我在用verilog工作台模拟我的系统时遇到了问题。我有一个信号(clk_out),我想从中测量并自动检查周期以及高低时间。信号clk_out的周期为1秒,高时间和低时间均为500ms。
`timescale 1ms / 1ps
module tb;
parameter PASSED = 1;
parameter FAILED = 0;
wire clk_out;
reg reset_n;
reg result;
realtime time1;
realtime time2;
realtime time3;
initial begin
result = PASSED;
reset_n = 1'b0;
// stay in reset for 100ms
reset_n = #100 1'b1;
@(negedge clk_out);
time1 = $realtime;
@(posedge clk_out);
time2 = $realtime;
@(negedge clk_out);
time3 = $realtime;
$display("\n");
$display("period is %f, high time is %f, and low time is %f",time3-time1,time3-time2,time2-time1);
$display("\n");
if (time3-time1 <= 999 || time3-time1 >= 1001) begin
result = FAILED;
end
if (time2-time1 <= time3*0.998/2 || time2-time1 >= time3*1.002/2) begin
result = FAILED;
end
if (time3-time2 <= time3*0.998/2 || time3-time2 >= time3*1.002/2) begin
result = FAILED;
end
$display("\n");
$display("=================================================");
if (result) begin
$display("Test is PASSED");
end else begin
$display("Test is FAILED");
end
// create the 1Hz signal when not in reset
my_module my_module_under_test
(
.RESET_N (reset_n),
.CLK_OUT (clk_out)
);
modelsim输出如下:
期间为1000000000.000000,高时间为500000000.000000,低时间为500000000.000000
=============================================== ==
测试失败
===============结束模拟===============
似乎模拟器不会读取文件顶部的时间刻度。我希望有:
time3 - time1 = 1000.00000
time2 - time1 = 500.00000
time3 - time2 = 500.00000
我做错了什么?
由于
答案 0 :(得分:0)
两种可能性:
检查上面module my_module(...)
声明的时间刻度,模块将使用此时间刻度。如果未在文件中声明时间刻度,则它将使用最近声明的时间刻度;编制订单事宜。如果未声明先前编译的时间刻度,则它将使用模拟器默认时间刻度。
如果使用命令行选项-timescale timeunit/timeprecision
,则将忽略全局时间范围和verilog文件中的任何声明。
答案 1 :(得分:0)
我已将您的代码转换为EDA Playground上的自包含测试,而不是my_module。
按预期输出。
# time3-time1 : 1000.000000
# time3-time2 : 500.000000
# time2-time1 : 500.000000
如果您仍然遇到问题我会建议my_module中存在一个问题,即时钟没有以正确的频率运行。
提示:
1)我会改变您应用重置的方式:
// stay in reset for 100ms
reset_n = #100 1'b1;
到
// stay in reset for 100ms
#100ms reset_n = 1'b1;
最后一个版本将依次等待100ms然后释放重置,然后再转到测试程序的其余部分。
2)如果您的模拟器使用时间指示符支持它,有助于消除对时间刻度的依赖。 ps
微秒,ns
纳秒,ms
毫秒,s
秒。