Verilog 使用延迟的自触发始终阻塞

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

我需要实现一个由

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'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看看答案。