//规定了上升及下降时延值。
`timescale 10ns/1ns 那么5.22对应52ns, 6.17对应62ns。
直至遇到另一个`timescale指令或`resetall指令。当一个设计中的多个模块带有自身的`timescale编译指令时将发生什么?在这种情况下,模拟器总是定位在所有模块的最小时延精度上,并且所有时延都相应地换算为最小时延精度。例如,
`timescale 1ns/ 100ps module AndFunc (Z, A, B); output Z; input A, B;
and # (5.22, 6.17 ) Al (Z, A, B); endmodule
`timescale 10ns/ 1ns module TB; reg PutA, PutB; wire GetO;
initial begin PutA = 0; PutB = 0; #5.21 PutB = 1; #10.4 PutA = 1; #15 PutB = 0; end
AndFunc AF1(GetO, PutA, PutB); endmodule
在这个例子中,每个模块都有自身的`timescale编译器指令。`timescale编译器指令第一次应用于时延。因此,在第一个模块中,5.22对应5.2 ns, 6.17对应6.2 ns;
在第二个模块中5.21对应52 ns, 10.4对应104 ns, 15对应150 ns。
如果仿真模块TB,设计中的所有模块最小时间精度为100 ps。因此,所有延迟(特别是模块TB中的延迟)将换算成精度为100 ps。
延迟52 ns现在对应520*100 ps,104对应1040*100 ps,150对应1500*100 ps。
更重要的是,仿真使用100 ps为时间精度。如果仿真模块AndFunc,由于模块TB不是模块AddFunc的子模块,模块TB中的`timescale程序指令将不再有效。
`unconnected_drive pull1 . . .
/*在这两个程序指令间的所有未连接的输入端口为正偏电路状态(连接到高电平)*/ `nounconnected_drive
`unconnected_drive pull0 . . .
/*在这两个程序指令间的所有未连接的输入端口为反偏电路状态(连接到低电平)*/ `nounconnected_drive Verilog HDL有下列四种基本的值:
1) 0:逻辑0或“假” 2) 1:逻辑1或“真” 3) x:未知 4) z:高阻
z的值总是意味着高阻抗,一个为0的值通常是指逻辑0。
在门的输入或一个表达式中的为“z”的值通常解释成“x”。此外,x值和z值都是不分大小写的,也就是说, 值0x1z与值0X1Z相同
Verilog HDL中有三类常量: 1) 整型 2) 实数型
3) 字符串型
下划线符号(_)可以随意用在整数或实数中,它们就数量本身没有意义。它们能用来提高易读性;
整型数可以按如下两种方式书写:
1) 简单的十进制数格式 整数值代表一个有符号的数
2) 基数格式 以基数格式计数的数通常为无符号数。
[size ] 'base value
size 定义以位计的常量的位长;base为o或O(表示八进制),b或B(表示二进制),d或D(表示十进制),h或H(表示十六进制)之一;value是基于base的值的数字序列。值x和z以及十六进制中的a到f不区分大小写。
注意,x(或z)在十六进制值中代表4位x(或z),在八进制中代表3位x(或z),在二进制中代表1位x(或z)。 4'D2 4位十进制数 4'B1x_01 4位二进制数
7'Hx 7位x(扩展的x), 即xxxxxxx 4'hZ 4位z(扩展的z) , 即zzzz
4'd-4 非法:数值不能为负
8'h 2 A 在位长和字符之间, 以及基数和数值之间 允许出现空格 3' b001 非法: ` 和基数b之间不允许出现空格 (2+3)'b10 非法: 位长不能够为表达式
实数可以用下列两种形式定义: 1) 十进制计数法;例如2.0 5.678
2) 科学计数法; 这种形式的实数举例如下:23_5.1e2 其值为23510.0; 忽略下划线
实数如何隐式地转换为整数。实数通过四舍五入被转换为最相近的整数。
42.446, 42.45 转换为整数42 92.5, 92.699 转换为整数93
-15.62 转换为整数-16
字符串是双引号内的字符序列。字符串不能分成多行书写。例如:
用8位ASCII值表示的字符可看作是无符号整数。因此字符串是8位ASCII值的序列。为存储字符串“INTERNAL ERROR”,变量需要8*14位。
reg [1 : 8*14] Message; . . .
Message = \
3.7 数据类型
Verilog HDL 有两大类数据类型。 1) 线网类型。net type 表示Verilog结构化元件间的物理连线。它的值由驱动元件的值决定, 例如 连续赋值或门的输出。如果没有驱动元件连接到线网,线网的缺省值为z。
2) 寄存器类型。register type表示一个抽象的数据存储单元,它只能在always语句和initial语句中被赋值,并且它的值从一个赋值到另一个赋值被保存下来。寄存器类型的变量 具有x 的缺省值。
线网类型主要有wire 和tri 两种。线网类型用于对结构化器件之间的物理连线的建模。如器件 的管脚,内部器件如与门的输出等。以上面的与门为例,输入信号A,B是由外部器件所驱动。 由于线网类型代表的是物理连接线,因此它不存贮逻辑值。必须由器件所驱动。通常由assign 进行赋值。如 assign A = B ^ C;
当一个wire 类型的信号没有被驱动时,缺省值为Z (高阻)。 信号没有定义数据类型时,缺省为 wire 类型。
tri 主要用于定义三态的线网。
net_kind [msb:lsb] net1, net2, . . . , netN;
* wire * wor * wand * trior * triand * trireg * tri * tri1 * tri0 * supply0 * supply1
net_kind 是上述线网类型的一种。msb和lsb 是用于定义线网范围的常量表达式;如果没有定义范围,缺省的线网类型为1位。
wand [2:0] Addr; Addr是3位线与。
supply0用于对“地”建模,即低电平0;supply1网用于对电源建模,即高电平1;例如: supply0 Gnd, ClkGnd; supply1 [2:0] Vcc;
3.7.3 向量和标量线网
在定义向量线网时可选用关键词scalared 或vectored。如果一个线网定义时使用了关键词vectored, 那么就不允许位选择和部分选择该线网。换句话说,必须对线网整体赋值:
wire vectored [3:1] Grb;
//不允许位选择Grb[2]和部分选择Grb [3:2]
wor scalared [4:0] Best; //与wor [4:0] Best相同,如果没有定义关键词,缺省值为标量。 允许位选择Best [2]和部分选择Best [3:1]。
3.7.4 寄存器类型
有5种不同的寄存器类型。
* reg * integer * real * time * realtime 1. reg寄存器类型
reg [msb: lsb] reg1, reg2, . . . regN;
如果没有定义范围,缺省值为1位寄存器。例如: reg [3:0] Sat; //Sat为4 位寄存器。
reg Cnt; //1位寄存器。
寄存器可以取任意长度。寄存器中的值通常被解释为无符号数, 例如: reg [1:4] Comb; . . .
Comb = -2; //Comb 的值为14(1110),1110是2的补码。
Comb = 5; //Comb的值为15(0101)。
3. 书写规范建议 对数组类型,请按降序方式,如[7:0] ;
2. 存储器
存储器是一个寄存器数组。数组的维数不能大于2。
Reg [msb: lsb] memory1 [ upper1: lower1], memory2 [upper2: lower2],. . . ; 例如:
reg [0:3] MyMem [0:63] //MyMem为64个4位寄存器的数组。 reg Bog [1:5] 在后面 //Bog为5个1位寄存器的数组。
parameter ADDR_SIZE = 16 , WORD_SIZE = 8;
reg [1: WORD_SIZE] RamPar [ ADDR_SIZE-1 : 0], DataReg;
RamPar是存储器,是16个8位寄存器数组,而DataReg是8位寄存器。
存储器赋值不能在一条赋值语句中完成,但是寄存器可以。因此在存储器被赋值时,需要定义一个索引。
reg [1:5] Dig; //Dig为5位寄存器。 Dig = 5'b11011; 正确的, reg BOg[1:5]; //Bog为5个1位寄存器的存储器。 Bog = 5'b11011; 不正确:
有一种存储器赋值的方法是分别对存储器中的每个字赋值。例如: reg [0:3] Xrom [1:4]
Xrom[1] = 4'hA; Xrom[2] = 4'h8; Xrom[3] = 4'hF; Xrom[4] = 4'h2;
1) $readmemb (加载二进制值) 2) $readmemb (加载十六进制值)
这些系统任务从指定的文本文件中读取数据并加载到存储器。文本文件必须包含相应的二进制或者十六进制数。例如:
reg [1:4] RomB [7:1] ;
$ readmemb (\
$readmemb (\从地址6开始,并且持续到1。 $readmemb ( \从地址6读到地址4。
3. Integer寄存器类型
整数寄存器包含整数值。作为普通寄存器使用
integer integer1, integer2,. . . intergerN [msb:1sb] ;
msb和lsb是定义整数 数组界限 的常量表达式,一个整数最少容纳32位。 integer A, B, C; //三个整数型寄存器。 integer Hist [3:6]; //一组四个寄存器。
可存储有符号数,并且算术操作符提供2的补码运算结果。
整数不能作为位向量访问。例如,对于上面的整数B的说明,B[6]和B[20:10]是非法的。 将整数赋值给一般的reg类型变量,然后从中选取相应的位,如下所示:
reg [31:0] Breg;
integer Bint; //Bint[6]和Bint[20:10]是不允许的。
Breg = Bint; /*现在,Breg[6]和Breg[20:10]是允许的,并且从整数Bint获取相应的位值。*/
通过简单的赋值将整数转换为位向量。类型转换自动完成,不必使用特定的函数。从位向量 到 整数的转换也可以通过赋值完成。例如: integer J;
reg [3:0] Bcq;
J = 6; //J的值为32'b0000...00110。 Bcq = J; // Bcq的值为4'b0110。
Bcq = 4'b0101.
J = Bcq; //J的值为32'b0000...00101。
J = -6; //J 的值为 32'b1111...11010。 Bcq = J; //Bcq的值为4'b1010。
注意赋值总是从最右端的位向最左边的位进行;任何多余的位被截断。
4. time类型 寄存器用于存储和处理时间
time time_id1, time_id2, . . . ,time_idN [ msb:1sb];
未定义界限,每个标识符存储一个至少64位的时间值。时间类型的寄存器只存储无符号数 time Events [0:31]; //时间值数组。
time CurrTime; //CurrTime 存储一个时间值
5. real和realtime类型 实数寄存器(或实数时间寄存器)
real real_reg1, real_reg2, . . ., real_regN;
realtime realtime_reg1, realtime_reg2, . . . ,realtime_regN;
real说明的变量的缺省值为0。不允许对real声明 值域、位界限 或 字节界限。 当将值x和z赋予real类型寄存器时,这些值作0处理。
real RamCnt; . . .
RamCnt = 'b01x1Z; RamCnt在赋值后的值为'b01010。
3.8 参数
参数是一个常量。用于定义时延和变量的宽度。
parameter param1 = const_expr1, param2 = const_expr2, . . . , paramN = const_exprN;
parameter BIT = 1, BYTE = 8, PI = 3.14;
第四节 Verilog中的表达式
4.1 操作数
操作数可以是以下类型中的一种:
1) 常数 2) 参数 3) 线网 4) 寄存器 5) 位选择 6) 部分选择 7) 存储器单元 8) 函数调用
表达式中的整数值可被解释为有符号数或无符号数。如果表达式中是十进制整数,例如,12被解释为有符号数。如果整数是基数型整数(定长或非定长),那么该整数作为无符号数对待。下面举例说明。