验证语言系列:timeunit和timeprecision

前面曾写过《Verilog系列:timescale去哪儿了》,其中讲述了timescale的用法,在使用时如果timescale顺序设置不合适,往往导致指定的延迟与期望不一致.随着搭建平台时对于验证平台要求的提高,有时需要使模块、接口或程序块与时间单位和精度信息直接绑定,有时需要指定class中的时间单位等,面对这样的问题,SystemVerilog中增加了两个新的特性: timeunit和timeprecision,本文将示例两者的用法和注意事项.
timeunit和timeprecision可以使用在module、program、package、interface等结构中,但是不能使用在class中,而timescale可以使用在任何地方,这也导致了其独立性不够,容易因为文件编译顺序等原因导致期望的时间延迟不对的情况出现。timeunit和timeprecision的含义主要如下:
timeunit:用于指定时间单位,也可以同时指定时间精度;
timeprecision:用于指定时间精度;
【示例】
`timescale 1 ns / 1 ns
module dut_time(clk);
timeunit 1ns;
timeprecision 10ps;
`timescale 10 ns / 1 ns
output clk;
reg    clk;
initial begin
    clk = 1'b0;
    forever #1.125 clk = ~clk;
end
endmodule

`timescale 10 ns / 1 ns
module top_tb;
reg clk;
wire clkt;
dut_time dut_t(clkt);
initial begin
    $printtimescale(top_tb);
    $printtimescale(top_tb.dut_t);
    clk = 1'b0;
    forever #1.55 clk = ~clk;
end
endmodule
【仿真结果】
# Time scale of (top_tb) is  10ns /  1ns
# Time scale of (top_tb.dut_t) is  1ns /  10ps


在不指定timescale的情况下,可以通过timeunit和timeprecision指定当前模块的时间单位和时间精度,此时模块外部和内部指定的timescale不起任何作用,即timeunit和timeprecision有更高的优先级;
【示例】
module dut_time(clk);
timeunit 1ns / 1ps;
// timeprecision 10ps; illegal format!
timeprecision 1ps;
output clk;
reg    clk;
initial begin
    clk = 1'b0;
    forever #1.125 clk = ~clk;
end
endmodule

`timescale 10 ns / 1 ns
module top_tb;
reg clk;
wire clkt;
dut_time dut_t(clkt);
initial begin
    $printtimescale(top_tb);
    $printtimescale(top_tb.dut_t);
    clk = 1'b0;
    forever #1.55 clk = ~clk;
end
endmodule
【仿真结果】
# Time scale of (top_tb) is  10ns /  1ns
# Time scale of (top_tb.dut_t) is  1ns /  1ps


指定timeunit时可以像timescale那样,同时指定时间单位和时间精度,其后仍然可以继续使用timeprecision,但是timeprecision指定的时间精度必须与timeunit中指定的时间精度一致.但是需要注意的是,这种方式指定时间单位和精度后,其后是不能再次使用timeunit;
【示例】
module dut_time(clk);
timeunit 10ns;
output clk;
reg    clk;
initial begin
    clk = 1'b0;
    forever #1.125 clk = ~clk;
end
endmodule

module top_tb;
reg clk;
wire clkt;
dut_time dut_t(clkt);
initial begin
    $printtimescale(top_tb);
    $printtimescale(top_tb.dut_t);
    clk = 1'b0;
    forever #1.55 clk = ~clk;
end
endmodule
【仿真结果】
# Time scale of (top_tb) is  1ns /  1ns
# Time scale of (top_tb.dut_t) is  10ns /  1ns
如果仅使用timeunit,且timeunit中仅指定了时间单位,那么当其他模块没有指定时间精度时,编译可以通过,但是此时精度由仿真器默认值决定(此处为1ns),模块内时间单位由timeunit决定;这里注意,timeprecision不能单独使用,但是timeunit可以;
综上所述,timeunit和timeprecision摆脱了timescale对于编译顺序的束缚,对于任何模块、程序、包或接口,或者在任意编译单元作用域内,都可以定义一个时间单位和一个时间精度,此时就会定义一个时间作用域.并且timeunit和timeprecision相对于timescale有更高的优先级和灵活性.但是在具体使用时,还是应该明确显式的制定确定的时间单位和时间精度,以免影响代码的可读性.



全部评论
感谢大佬的分享
点赞 回复 分享
发布于 2022-09-18 18:24 陕西

相关推荐

Natrium_:这时间我以为飞机票
点赞 评论 收藏
分享
过往烟沉:我说什么来着,java就业面就是广!
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务