我需要做出一份延迟声明,延迟的数量随时间而变化,可能会增加或减少。当模拟时间等于某个变量(称为延迟)时,我需要一个语句发生,该变量延迟被其他并行进程不断改变,不需要综合。这是一个例子:
module test();
logic flag;
integer delay=10;
initial begin
flag=0;
#1;
delay=2;
flag=1;
#1
delay=20;
flag=0;
end
always @ (flag) begin
$display("Inside flag always block at time: %0t with delay of %d", $realtime,delay);
#delay
flag=~flag;
$display("Flag changed to %d at time: %0t", flag, $realtime);
end
endmodule
换句话说,即使在内部延迟完成之前,我也需要在标志发生任何变化时中断(重置)always @(flag)语句,并使用新的延迟值重新执行#delay语句。
我想到的想法:
1-通过使其对切换模拟器的每个时间步骤的虚拟时钟敏感来重新编写代码逻辑。但我认为这会消耗大量资源,特别是如果我的代码的目的是加速模拟的话。
2-使用Fork/Join语句创建多个线程,每个线程对应一个延迟值的变化(使用延迟变量的动态数组内存分配),但问题是如何在fork块中进行动态语句。
最后,我感觉这是无论如何都不可能的,有没有解决方法?
只是为了说明我在评论中所说的循环。这里有两个循环:一个控制延迟计数器(通过 $time),另一个控制延迟的 flag。总是块对标志做出反应。
module test;
int delay;
bit flag;
time start;
initial begin
forever begin
@(delay) begin
$display("%0t: delay for %d", $time, delay);
start = $time;
end
end
end
initial begin
forever begin
#1
if ($time - start == delay)
flag = 1;
end
end
initial begin
delay = 0;
#3 delay = 10;
#30 delay = 5;
#10 delay = 10;
#22 delay = 20;
#10 delay = 11;
#100 $finish;
end
always @(flag) begin
if (flag) begin
$display ("%0t, delayed", $time);
flag = ~flag;
end
end
endmodule
前 3 个延迟工作不间断。最后一个 (20) 被 (11) 打断。算法的其余部分取决于你。
注意:这是一个快速而肮脏的 v2k 风格的实现,只是为了说明这个概念。在 svtb 可以做得更好。