Verilog语法速成(二) 13.6 常量: 整数型 • 基数格式 – [size] ‘baseformat value – size:以位计的常数的位宽; – baseformat代表进制:八进制:o或O、二进制:b或B、十进制:d或D、十六进制:h或H – 其中十六进制数值a到f以及x和z不区分大小写 • 注意事项 – 为了增加数值的可读性,可以在数字之间增加下划线,例如“8’b1001_0011”表示位宽为8位的二进制数。下划线可以随意使用在整数或实数中,但是不能作为首字符。 – 在二进制表示中,x,z只表示相应位的逻辑状态;在八进制表示中,一位x或z代表3个二进制位都处于x或者z状态;在十六进制表示中,一位x或z代表4个二进制位都处于x或者z状态。 – 当没有说明位宽[size]时,整数的位宽为机器的字长(至少为32位);当位宽比数值的实际二进制位少时,高位部分会被舍去;当位宽比数值的实际二进制位多时,且最高位为0或1时,则高位由0填充;当位宽比数值的实际二进制位多时,且最高位为x或z时,则高位相应由x或z填充。 示例: • 3’b101:位宽为三位的二进制数:二进制101,十进制数值为:5,合法 • 5’o37:位宽为5位的八进制数,虽然一个八进制数的位宽为3,但是八进制3转换为2进制为011,故可以省去0位,即合法,十进制数值为:31. • 12’habc:位宽为12位的十六进制数,其中abc为三个十六进制数,每个十六进制数的位宽为4,故总和为12,合法,十进制数值为:2748 • -4d’10:非法,“ ‘ “符号位置错误 • 4’b1x0x:合法,其中从低位到高位的第一位和第三位为未知,故数值未知 • 12’h13x:合法,十二位位宽,十六进制,其中从低位到高位的第一位十六进制数为未知数,故数值未知 • 32’bz:合法,这是三十二位位宽,二进制数,其为高阻态。 • 23456:合法,默认为十进制,23456. • ‘hc3:合法,默认为至少32位(机器的字长),其十进制值为:195 • 4’d-8:不合法,数值其中有非法字符 • 3’[]b101:不合法,b前有非法字符 • (3+2)’b11010:不合法,位宽限制不可有算术符号。 实数型(少用) – 实数常量可以用十进制或科学表示法表示。 12 unsized decimal (zero-extended to 32 bits) ‘H83a unsized hexadecimal (zero- extended to 32 bits) 8’b1100_ 0001 8-bit binary 64’hff01 64-bit hexadecimal (zero- extended to 64 bits) 9’O17 9-bit octal 32’bz01x Z-extended to 32 bits 3’b1010_ 1101 3-bit number, truncated to 3’b101 6.3 decimal notation 32e- 4 scientific notation for 0.0032 4.1E3 scientific notation for 4100 字符串型 Verilog中,字符串大多用于显示信息的命令中($display and $monitor)。 • 8位ASCII值表示的字符可看作是无符号整数 • 字符串要在一行中用双引号括起来,也就是不能跨行。 • 字符串中可以使用一些C语言转义(escape)符,如\t \n • 可以使用一些C语言格式符(如%b)在仿真时产生格式化输出: ”This is a normal string” ”This string has a \t tab and ends with a new line\n” ”This string formats a value: val = %b” 如果字符串被用作Verilog HDL中表达式或者赋值语句中的操作数,则每个字符串(包括空格)被看做是8位的ASCII值序列,即一个字符对应8位的ASCII值。比如,为了储存字符串“hello world!”,就需要定义一个8*12位的变量: reg[1:8*12] message; initial begin message =“hello world!”; end 转义符及格式符将在验证支持部分讨论 格式符
转义符
格式符%0d表示没有前导0的十进制数 13.7 参数型 • 在Verilog HDL中,参数是一个非常重要的数据类型,属于常量,在仿真开始之前就被赋值,在仿真过程中保持不变。采用参数定义方法可以提高程序的可读性和维护性。参数常用来定义延迟时间和变量的位宽。 • 参数类型的定义格式: • parameter 参数名1=表达式1,参数名2=表达式2,………,参数名n=表达式n; • 其中,表达式既可以是常数,也可以是表达式。参数定义完以后,程序中出现的所有的参数名都将被替换为相对应的表达式。 • 如:parameter LENGTH=32,WEIGHT=16; • 用参数声明一个可变常量,常用于定义延时及宽度变量。 • 参数定义的语法:parameter <list_of_assignment>; • 可一次定义多个参数,用逗号隔开。 • 在使用文字(literal)的地方都可以使用参数。 • 参数的定义是局部的,只在当前模块中有效。 • 参数定义可使用以前定义的整数和实数参数。 注意:参数file不是string,而是一个整数,其值是所有字母的扩展ASCII值。若file=“AB”,则file值为8‘h4142。用法: $fopen(file); $display(“%s”, file); 13.8 变量型 Reg & Wire 1)Wire型:线网表示逻辑单的物理连接,可以对应为电路中的物理信号连线,这种变量类型不能保持电荷(除trireg之外)。连线型变量必须要有驱动源,一种是连接到一个们或者模块的输出端,另一种是用assign连续赋值语句对它进行赋值。若没有驱动源,将保持高阻态z (除trireg之外)。 2)定义语法: wire [msb:lsb] 变量名1,变量名2, …,变量名n; 其中,msb和lsb定义了范围,它们之间用冒号分隔,并且均为常数表达式。如果没有定义范围,则缺省值为1位变量。下面是一些wire型变量定义的一些例子: wire a,b; //定义了两个wire类型的变量 wire L; //定义了一个wire类型的变量 wire[7:0] databus; //定义了一组8位总线 wire[32:1]busA, busB, busC; //定义了三组32位总线 3)不同的wire类型 线网型数据类型 功能说明 wire,tri 标准连线(缺省为该类型) wor,trior 多重驱动时,具有线或特性的连线型 trireg 具有电荷保持特性的连线型数据 tri1 上拉电阻 tri0 下拉电阻 supply0 电源线,用于对“地”建模,为低电平0 supply1 电源线,用于对电源线建模,为高电平1 wand,trand 多重驱动时,具有线与特性的连线型 最常见的是wire(连线)和tri(三态线)两种,它们的语法和语义一致。不同之处在于:wire型变量通常用来表示单个门驱动或连续赋值语句驱动的连线型数据。tri型数据变量则用来表示多驱动器驱动的连线型数据,主要用于定义三态的线网。
wor和tiror代表多重驱动时,具有线或特性的线网类型。
wand和tirand代表多重驱动时,具有线与特性的线网类型。 wand/triand
• tri0的特征是,若无驱动源驱动,其值为0,用于下拉电阻建模。 • tri1的特征是,若无驱动源驱动,其值为1,用于上拉电阻建模。 trio/ tri1
• supply0用于对“地”建模,即低电平0; • supply1用于对电源建模,即高电平1; • 如supply0表示Gnd. Supply1表示Vcc。 • trireg线网能存储数值(类似于寄存器型数据类型),并且用于电容节点的建模。当三态寄存器(trireg)的所有驱动源都处于高阻态(z)时,三态寄存器线网将保持作用在线网上的最后一个逻辑值。三态寄存器线网的缺省初始值为x。 • 一个trireg网络型数据用于模拟电荷存储。电荷量强度可以下面的关键字来控制:small、medium、;large。默认的电荷强度为medium。一个trireg网络型数据能够模拟一个电荷存储节点,该节点的电荷量将随时间而逐渐衰减。对于一个trireg网络型数据,仿真时其电荷衰减时间应当制定为延迟时间。 4)关键点: • 线网被合并到连接,但这些可以被优化掉 • 除了wire 外,综合工具不支持其他线网类型 • 甚至在建立隐式声明时,也要在每个模块的顶部明确声明所有线网。这样通过明确意图,增加了Verilog 代码的可读性和可维护性 • 只用supply0 和supply1 声明地和电源线网 1)reg型:寄存器保存在initial always task 和function 内赋的值。 • reg是最常用的寄存器类型 • Reg型变量时最常见也是最重要的寄存器型数据类型,它是数据存储单的抽象类型,其对应的硬件电路件具有状态保持作用,能够存储数据,如触发器、锁存器等。reg型变量常用于行为级描述中,由过程赋值语句对其进行赋值。 • reg 型数据域wire型数据的区别在于,reg型数据类型保持最后一次的赋值,而wire型数据需要有持续的驱动。一般情况下,reg型数据的默认初始值为不定值x,缺省时的位宽为1位。 • 2)定义语法: – reg [ Range] RegisterOrMemory,…; – integer RegisterOrMemory,…; – time RegisterOrMemory,…; – real RegisterName,…; • 规则 – 寄存器只能用过程赋值来赋值 – 在给定的设备中,integer 有最大大小,但它至少有32 位。time 寄存器的长度也有相似的保证,但它至少有64 位 – 类型是integer 或time 的寄存器一般像有相同数量位数的reg 一样运转。Integer 和time 的个别位和部分选择可以和reg 一样建立。但在表达式中,integer 的值作为有符号数处理,而reg 或time的值作为无符号数处理 – 在同一时间只能访问(读或写)存储器数组的一个完整素。要访问存储器数组一个素的个别位,该素的内容首先要被复制到一个适当的寄存器 – 寄存器这个术语也表示一个硬件寄存器(即触发器),名字是假设表示一个软件寄存器(即一个变量)。Verilog 寄存器可以并用于描述和合并组合逻辑、锁存器、触发器和连接 – 用reg 描述逻辑,integer 描述循环变量和计算,real 在系统模型中使用,time 保存测试装。real、time 和integer 不可综合 • net声明 <net_type> [range] [delay] <net_name>[, net_name]; net_type: net类型 range: 矢量范围,以[MSB:LSB]格式 delay: 定义与net相关的延时 net_name: net名称,一次可定义多个net, 用逗号分开。 • 寄存器声明 <reg_type> [range] <reg_name>[, reg_name]; reg_type:寄存器类型 range: 矢量范围,以[MSB:LSB]格式。只对reg类型有效 reg_name :寄存器名称,一次可定义多个寄存器,用逗号分开 • 书写规范建议 – 对数值类型,按降序方式定义位宽
• 1)存储器型(memory):本质上还是寄存器型变量阵列,只是Verilog HDL语言中没有多维数组,所有就用reg型变量建立寄存器组来实现存储器的功能,也就是扩展的reg型数据地址范围。存储器型变量可以描述RAM型、ROM型存储器以及reg文件。数组中的每一个单通过一个数组索引进行寻址。 • 存储器型变量的一般声明格式: • reg<rangel1><name_of_register><range2>; • 其中,range1和range2都是可选项,缺省时都为1. • range1:表示存储器中寄存器的位宽,格式为[msb:lsb] • range2:表示寄存器的个数,格式为[msb:lsb],即有msb-lsb+1个 • name_of_register:变量名称列表,一次可以定义多个名称,之间用逗号分开。 存储器类型举例: • reg[7:0] mem1[255:0]; //定义了一个有256个8位寄存器的存储器mem1 地址范围是0到255. • reg[15:0]mem2[127:0],reg1,reg2;//定义了一个具有128个16位寄存器的存储器mem2和2个16位的寄存器reg1和reg2 • • 2)注意:memory型和reg型数据的差别。一个由n个1位寄存器构成的寄存器和一个n位寄存器的意义是不同的。 • reg[n-1:0]a; //表示一个n位的寄存器a • reg mem1[n-1:0]; //表示一个由n个1位寄存器构成的存储器mem1. • 一个n位的寄存器可以在一条赋值语句里进行赋值,而一个完整的存储器则不行。 • 如果想对存储器中的存储单进行读写操作,则必须指定该单在存储器中的地址。 • 如:mem1[2]=0;//给mem1存储器中的第三个存储单赋值为0 13.9 信号分类: 信号可以分为端口信号和内部信号。出现在端口列表中的信号是端口信号,其它的信号为内部信号。 对于端口信号,输入端口只能是net类型。输出端口可以是net类型,也可以是register类型。若输出端口在过程块中赋值则为register类型;若在过程块外赋值(包括实例化语句),则为net类型。 内部信号类型与输出端口相同,可以是net或register类型。判断方法也与输出端口相同。若在过程块中赋值,则为register类型;若在过程块外赋值,则为net类型。 若信号既需要在过程块中赋值,又需要在过程块外赋值。这种情况是有可能出现的,如决断信号。这时需要一个中间信号转换。 13.10 运算符: • 1)常用的算术运算符 – 加法+ – 减法- – 乘法* – 除法/ – 求模% • 应注意的问题 – 算术操作结果的位数长度 • 算术表达式结果的长度由最长的操作数决定 – 有符号数和无符号数 • 在设计中,请先按无符号数进行,无符号数的值一般存储在线网、reg(寄存器)变量及普通(没有符号标记s)的基数格式表示的整数型中,有符号数值一般存储在存储在整型变量、十进制形式的整数、有符号的reg(寄存器)变量及有符号的线网中 • 2)关系运算符 >(大于) <(小于) >=(不小于) <=(不大于) • 关系操作符的结果为真(1)或假(0)。如果操作数中有一位为x或z,那么结果为x • 3)相等关系运算符 ==(逻辑相等) ===(全等于) !=(逻辑不等) !==(不全等) • 相等关系运算符是对两个操作数进行比较,比较的结果有三种:真1,假0,和不定值(x). • Verilog HD语言中四种相等关系运算符:等于(==)、不等于(!=)、全等于(===)。 • 这四种运算符都是双目运算符,要求有两个操作数。他们的优先级是相同的。 • “==”和“!=”称为逻辑等式运算符,其结果有两个操作数的值决定,由于操作数中某些位可能是不定值x和高阻态值z,所以结果可能是不定值x。 • “===”和“!==”运算符则不同,他是对操作数按位比较,两个操作数必须完全一样,其结果才是1,否则都是0.但是,若两个操作数对应位出现不定值x和高阻值z,则可以认为是相同的。 • “===”和“!==”运算符常用于case表达式的判别,所以又称为“case”等式运算符。 • 4)逻辑运算符 • 逻辑与运算符“&&” • 逻辑或运算符“||” • 逻辑非运算符(!) 其中逻辑与和逻辑或,是双目运算符。 逻辑非为单目运算符。 在逻辑运算符的操作中,如果操作数是1位的,那么1就代表逻辑真,0就代表逻辑假。 如果是操作数是由多位的,则当操作数每一位都是0时才是逻辑0值,只要有一位1,这个操作数就是逻辑1值。 例如:寄存器变量a、b的初值分别是4’b1110和4’b0000,则 !a=0, !b=1; a&&b=0; a||b=1; 需要注意的是,若操作数中存在不定态x,则逻辑运算的结果也是不定态x。 • 5)数字逻辑电路中,信号与信号之间的运算称之位运算符。 Verilog HDL提供了一下五种类型的位运算符: • 按位取反(~) (相当于非门运算) • 按位与(&)(相当于与门运算) • 按位或(|)(相当于或门运算) • 按位异或(^)(相当于异或门运算) • 按位同或(^~)(相当于同或门运算) • 位逻辑运算对其自变量的每一位进行操作。 6)归约操作符 • 归纳运算符按位进行逻辑运算,属于单目运算符。由于这一类运算符操作的结果产生1位逻辑值,因而被形象地称为缩位运算符。 • 在Verilog HDL中,缩位运算符包括&(与)、|(或)、^(异或)以及相应的非操作~&、 ~|、 ~^、 ^~ .归纳运算符的操作数只有一个。这里需注意和位运算进行区别。 • 举例:a=4’b1101,则 &a= 1&1&0&1 =0 7)移位操作符 >> 逻辑右移 << 逻辑左移 移位操作符对其左边的操作数进行向左或向右的位移位操作。 第二个操作数(移位位数)是无符号数 若第二个操作数是x或z则结果为x << 将左边的操作数左移右边操作数指定的位数 >> 将左边的操作数右移右边操作数指定的位数 在赋值语句中,如果右边(RHS)的结果: 位宽大于左边,则把最高位截去 位宽小于左边,则零扩展 8)条件运算符 • 语法结构:cond_expr?expr1:expr2 • 如果cond_expr为真,选择expr1;如果cond_expr为假,选择expr2。如果cond_expr为x或z,结果将是按以下逻辑expr1和expr2按位操作的值:0与0得0,1与1得1,其余情况为x。 9)连接运算符 • 语法定义: – {expr1,expr2,…,exprN} • 例如: wire [7:0] Dbus; assign Dbus[7:4]={Dbus[0], Dbus[1], Dbus[2], Dbus[3]}; assign Dbus={Dbus[3:0],Dbus[7:4]}; 10)复制运算符 {Const_int{Var}} 复制一个变量或在{ }中的值 前两个{ 符号之间的正整数Const_in指定复制次数。 示例: module replicate (); reg [3: 0] rega; reg [1: 0] regb, regc; reg [7: 0] bus; initial begin rega = 4’b1001; regb = 2’b11; regc = 2’b00; end initial fork #10 bus <= {4{regb}}; // bus = // regb is replicated 4 times. #20 bus <= { {2{regb}}, {2{regc}} }; // bus = . regc and regb are each // replicated, and the resulting vectors // are concatenated together #30 bus <= { {4{rega[1]}}, rega }; // bus = 00001001. rega is sign-extended #40 $finish; 整理:SANGHUSUN 四川大学物理学院ASIC设计实验室 E-mail:SANGHUSUN @foxmail.com 2020.07.31
2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/59976.html