Verilog 使用延迟的自触发始终阻塞
我需要实现一个由 a) 外部事件eflag,或,b)取决于其状态,内部事件iflag,计划dt秒后,以先到者为准 我使用延迟(#)运算符进行的试验导致了阻塞行为,例如,长dt确实阻塞了下一个eflag。 如果可能,我将避免使用dtmax作为长dt的计数开销 工作和预期,但失败的代码:Verilog 使用延迟的自触发始终阻塞,verilog,Verilog,我需要实现一个由 a) 外部事件eflag,或,b)取决于其状态,内部事件iflag,计划dt秒后,以先到者为准 我使用延迟(#)运算符进行的试验导致了阻塞行为,例如,长dt确实阻塞了下一个eflag。 如果可能,我将避免使用dtmax作为长dt的计数开销 工作和预期,但失败的代码: `timescale 1ns/100fs `define tick 1.0e-9 parameter real dtmax = 1; initial iflag=1'b0; initial toggle=1
`timescale 1ns/100fs
`define tick 1.0e-9
parameter real dtmax = 1;
initial iflag=1'b0;
initial toggle=1'b0;
always @(eflag, iflag) begin
// time step control
dt = ...;
iticks = dt/`tick;
toggle = !toggle;
end
//------------------------------------------------------
/*
a) time step counter - working
always #1 begin
iticks = iticks - 1;
if (iticks < 1) begin
iflag = !iflag;
iticks=dtmax/`tick;
end
end
*/
// b) intended
always @(toggle) begin
#(iticks) iflag <= !iflag; // failing, not changing iflag
// #(iticks) iflag = !iflag; // failing, blocking simulation
end
`时标1ns/100fs
`定义勾号1.0e-9
参数real dtmax=1;
初始iflag=1'b0;
初始切换=1'b0;
始终@(eflag,iflag)开始
//时间步长控制
dt=。。。;
iticks=dt/`tick;
切换=!切换;
结束
//------------------------------------------------------
/*
a) 时间步长计数器工作
总是从一开始
iticks=iticks-1;
如果(iticks<1)开始
iflag=!iflag;
iticks=dtmax/`勾号;
结束
结束
*/
//b)预期的
始终@(切换)开始
#(iticks)iflag我更改了你的代码,这个新代码对我来说很好。如果您认为它不起作用,那么您对Verilog模拟的理解可能是错误的。非阻塞延迟在信号上调度事件。如果在分配该计划之前,计划了另一个具有不同值的事件,则会覆盖第一个事件。如果新事件具有相同的值,则保留第一个事件
// Verilog
// self-triggered always block
// block should take time steps <= dtmax
`define tick 1.0e-9
module dut(eflag);
input eflag;
reg iflag;
reg toggle;
integer iticks;
real last_time;
real now;
real dtlast;
real dtmax;
always @(eflag, iflag) begin
now = $time*`tick;
dtlast = now - last_time;
dtmax = iticks*`tick; // from last call
$display( "dtlast: %g",dtlast);
$display( "err: %d",dtlast > dtmax); // giving wrong value in sim?
$display("\nnow: %g",now);
$display( "dtmax: %g",dtmax);
// time step control dummy
iticks <= 7 + $random % 5; //changed because in previous one eflag and toggle always changed at the same time
toggle = !toggle;
last_time = now;
end
initial toggle = 0;
initial iflag = 0;
always @(toggle) begin
#(iticks) iflag <= !iflag;
end
endmodule
//Verilog
//自触发始终块
//块应采用时间步长(dtmax);//在sim卡中给出错误的值?
$display(“\n现在:%g”);
$display(“dtmax:%g”,dtmax);
//时间步控制假人
iticks我更改了你的代码,这个新代码对我来说很好。如果您认为它不起作用,那么您对Verilog模拟的理解可能是错误的。非阻塞延迟在信号上调度事件。如果在分配该计划之前,计划了另一个具有不同值的事件,则会覆盖第一个事件。如果新事件具有相同的值,则保留第一个事件
// Verilog
// self-triggered always block
// block should take time steps <= dtmax
`define tick 1.0e-9
module dut(eflag);
input eflag;
reg iflag;
reg toggle;
integer iticks;
real last_time;
real now;
real dtlast;
real dtmax;
always @(eflag, iflag) begin
now = $time*`tick;
dtlast = now - last_time;
dtmax = iticks*`tick; // from last call
$display( "dtlast: %g",dtlast);
$display( "err: %d",dtlast > dtmax); // giving wrong value in sim?
$display("\nnow: %g",now);
$display( "dtmax: %g",dtmax);
// time step control dummy
iticks <= 7 + $random % 5; //changed because in previous one eflag and toggle always changed at the same time
toggle = !toggle;
last_time = now;
end
initial toggle = 0;
initial iflag = 0;
always @(toggle) begin
#(iticks) iflag <= !iflag;
end
endmodule
//Verilog
//自触发始终块
//块应采用时间步长(dtmax);//在sim卡中给出错误的值?
$display(“\n现在:%g”);
$display(“dtmax:%g”,dtmax);
//时间步控制假人
谢谢你的回答,事实上我想摆脱步行式的递减。请在问题中查看我编辑的代码。如果您将其更改为iflag,您可以修改您的问题,使其更清晰,并发布您的全部代码,以便我可以调试它。嗨,Laleh,谢谢您的参与。我已经把它放在了操场上,以后会编辑这个问题。@bardo看到答案了。谢谢你的回答,实际上我想摆脱步行式的递减。请在问题中查看我编辑的代码。如果您将其更改为iflag,您可以修改您的问题,使其更清晰,并发布您的全部代码,以便我可以调试它。嗨,Laleh,谢谢您的参与。我已经把它放在了操场上,稍后会编辑这个问题。@bardo看看答案。