未命名语句块中的声明
命名块中的局部变量
Verilog允许在命名的begin…end或fork…join块中声明局部变量。局部变量声明的通常用法是声明一个临时变量进行循环控制。局部变量避免了对同名但用途不同的模块模块级变量的无意访问。下面的代码段声明了两个都叫i的变量,在命名的begin块中的for循环将使用命名块中声明的局部变量i,而不会影响模块级声明的变量i。
module chip (input clock);integer i; //模块级声明always@(posedge clock)
begin : loop //命名块integer i;//局部变量for(i = 0; i <= 127; i = i + 1)begin...end
end
endmodule
对局部变量的层次化引用
在命名块中声明的变量可以用包含块名的层次路径引用。一般情况下,只要测试和验证程序会使用层次路径方式引用变量。层次化引用是不可综合的,因为这并不代表硬件行为。VCD(Value Change Dump,一种标准的仿真波形记录格式)文件、所有波形显示或其他调试工具也可以使用层次路径方式引用命名块内的变量。
module test;reg clock;chip chip(.clock(clock));always #5 clock = ~clock;
initial
beginclock = 0;repeat(5)@(negedge clock)$display("chip.i = %0d",chip.i);$display("chip.loop.i = %0d",chip.loop.i);$finish;
end
endmodule
未命名块中的局部变量
module chip (input clock);integer i; //模块级声明always@(posedge clock)
begin //未命名块integer i;//局部变量for(i = 0; i <= 127; i = i + 1)begin...end
end
endmodule
未命名块中的局部变量没有层次路径
由于块没有名字,未命名块中的局部变量不能被层次化引用。测试程序或VCD文件也不能引用局部变量,因为变量没有层次路径。
在未命名块中声明变量可以作为一种方法,保护局部变量不被外部交叉模块引用。由于没哟层次路径,局部变量不能在局部范围以外的任何地方引用。
从调试过程推导层次路径
允许未命名域中声明变量的扩展不是SystemVerilog特有的。Verilog语言也有类似情况。用户自定义原语(UDP)可以在内部声明域中创建一个变量。在这种情况下,软件工具会推断出一个实例名,以便于UDP中的变量能在调试工具中引用。软件工具也可以给未命名块一个推断名,以便于波形显示或调试工具引用未命名中的局部变量。Verilog标准中既不要求也不禁止给未命名原语实例推断一个实例名。SystemVerilog标准中也既不要求也不禁止给未命名原语实例推断一个实例名。
仿真时间单位和精度
包含时间单位的时间值
将时间单位指定为时间值的一部分
SystemVerilog扩展了Verilog语言,可以给时间值指定时间单位。
forever #5ns clock = ~clock;
直接给时间值指定时间单位消除了延迟时间不明确的缺点。
s(秒)、ms(毫秒)、us(微秒)、ns(纳[诺]秒)、ps(皮[可]秒)、fs(飞[母托]秒)、step(软件工具使用的最小花四溅单位,(用于SystemVerilog测试时钟快))
注意:时间值和时间单位之间不允许有空格
#3.2ps //正确
#4.1 ps//不正确,不允许有空格
范围即(scope-level)时间单位和精度
时间单位和精度作为模块定义的一部分
SystemVerilog允许指定局部性的时间单位和精度,作为模块、接口或程序块的一部分,而不是作为软件工具的指令。
在SystemVerilog中通过使用关键字timeunit和timeprecision进一步增强了时间单位的说明。这些关键字作为模块定义的一部分,用来指定模块内的时间单位和精度信息。
moudle chip(...);timeunit 1ns;timeprecision 10ps;...
endmodule
关键字timeunit和timeprecision使模块、接口或程序块与时间单位和精度信息直接绑定,而不使用软件
工具的指令,
这解决了Verilog的`timescale指令中存才的不明确性和对文件顺序的依赖性。
除了特殊单位step外,关键字timeunit和precision可以使用单位和Verilog的 `timescale指令相同
注意:timeunit和timeprecision语句必须在其他任何声明或语句之前、紧随模块、接口或程序的声明之后指定。
编译单元的时间单位和精度
外部声明时间单位和精度
timeunit和timeprecision的声明库在编译单元域指定,但必须先于其他任何声明。在编译单元域内和接口–如果他们没有局部timeunit或timeprecision声明,并且编译时没有有效的Verilog`timescale指令
时间单位和精度搜索次序
使用SystemVerilog时,时间单位和精度值可以在很多地方指定。SystemVerilog定义了一个搜索法则来确定时间值的单位和精度
(1)如果时间值带时间单位,则使用指定的单位。
(2)否则,使用在模块、接口和程序内部指定的时间单位和精度
(3)否则,如果模块或接口声明嵌入到其他的模块和接口内,使用父模块或接口指定的时间单位和精度
(4)否则,使用模块编译时,有效的`timescale时间单位和精度
(5)否则,使用在编译单元域中定义的时间的单位和精度
(6)否则,使用仿真器默认的时间单位和精度
//时间单位和精度的混合声明(不可综合)
timeunit 1ns //外部声明的时间单位和精度
timeprecision 1ns;module my_chip(...)timeprecision 1ps;//局域精度(优于外部精度)always@(posedge data_request)begin#2.5 send_packet; //使用外部单位和局部精度#3.75 check_crc; //使用指定的单位endtask send_packet();
.....
endtasktask check_crc();
.....
endtask
endmodule`timescale 1ps/ps //`timescale指令指定的单位和精度,优于外部声明module FSM(...)timeunit 1ns; //局部声明优于`timescale的指定always@(State)begin#1.2 case(State) //使用局部声明的单位和`timescale指定的精度waite :#20ps ...; //使用此处指定的单位...end
endmoudle