评估事件调度Verilog分层事件Queu

2024-09-28 21:22:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用Python实现一个简单的基于事件的Verilog模拟器,但实际上我很难在规范中找到一些细节(ieee1364-2005第11节)。在

假设我刚刚对clk执行了一个更新事件,它现在获得了新值1(之前是0)。根据规范,这要求我为敏感进程安排“评估事件”。在

是否必须将always @(posedge clk)块的求值安排为活动事件还是非活动事件?我猜后者是对的?在

或者说,更笼统地说。基本上所有事件都被安排为非活动事件,但以下情况除外:

  • 非阻塞分配更新为非阻塞分配事件
  • 作为活动事件的连续分配

非常感谢!在


Tags: 规范进程事件情况模拟器alwaysverilog细节
1条回答
网友
1楼 · 发布于 2024-09-28 21:22:59

默认情况下,所有操作都在活动的区域中运行。例外情况包括:

  • #0个块分配位于非活动区域
  • 非阻塞性任务在NBA地区
  • $monitor、$strobe和PLI/VPI位于监视器区域

通过在任何现有模拟器中运行以下命令,我们可以证明@发生在活动区域:

int x; 
initial begin 
   $monitor("From    $monitor: x is %0d",x); 
   #0 x = 5; // inactive event 
   x = 3; // active event (after inactive event)
   #1; // go to next time stamp
   fork
     #0 x = 7; // inactive event 
     x = 11; // active event 
   join
   #0 fork // inactive region
     #0 x = 2; // inactive event 
     x = 5; // active event 
     x <= 4; // NBA event 
   join
end 
// active event region
always @* $display("From @* $display: x is %0d",x); 

输出:

^{pr2}$

显示报告的次数多于监视器的次数。这就排除了@在监视器或未来区域中累积的可能性。Display is正在报告每个事件区域。每个事件区域只能循环回活动区域。因此,必须在活动区域中处理@,并且更新变量{}的每个区域都将触发一个新的活动区域事件。在

这也可以通过了解Verilog的历史来证明。不幸的是,这并没有很好的记录。我是从80年代末90年代初使用/开发verilog的人那里学来的,总的解释是:在IEEE Std 1364-1995之前,@早于这两个区域,才将非活动区域和NBA区域添加到verilog中。添加这些区域是为了向非确定性模拟器添加确定性。在

always @(posedge clk) pipe0 = in;
always @(posedge clk) pipe1 = pipe0; // unpredictable, non-deterministic order
always @(posedge clk) #0 pipe0 = in; // Inactive region added some determinism
always @(posedge clk) pipe1 = pipe0; 
always @(posedge clk) #0 pipe0 = in; // But was fragile
always @(posedge clk) #0 pipe1 = pipe0; // unpredictable order again
always @(posedge clk) pipe2 = pipe1; 
always @(posedge clk) pipe0 <= in; 
always @(posedge clk) pipe1 <= pipe0; 
always @(posedge clk) pipe2 <= pipe1; // NBA region fixed it 
 ...
always @(posedge clk) pipeN <= pipeM; //             and made it scalable




根据评论的反馈进行澄清

事件被激活,而不是被移动。激活的NBA事件进入if (E is an update event)、修改对象和调度新的评估事件的真实条件(在下次输入活动区域时处理)。一旦所有的激活的事件都完成了,调度将返回while循环的顶部。NBA区域只分配值,评估实际上是在早期的活跃区域阶段进行的。
根据您的例子:
module TEST;
   reg test = 0;
   reg test2 = 0;
   reg clk = 0;

   initial begin
      clk <= 1;
      test <= 1;
   end

   always @(posedge clk) begin
      test2 <= test;
   end
endmodule

while循环的每次迭代都将如下所示:

Iteration:0
  Active: <  - This is region is executing
      clk$tmp = eval(1)
      test$tmp = eval(1)
  Inactive:NBA:
      clk = clk$tmp
      test = test$tmp
Iteration:1
  Active:Inactive:NBA: <  - This is region is executing
      clk = clk$tmp
      test = test$tmp
      Active.schedule( eval( "@(posedge clk)" )
Iteration:2
  Active: <  - This is region is executing
      eval( "@(posedge clk)" )
      Active.schedule( "test2$tmp = eval(test)" )
      NBA.schedule( "test2 = test2$tmp" )
  Inactive:NBA:
Iteration:3
  Active: <  - This is region is executing
      test2$tmp = eval(test)
  Inactive:NBA:
      test2 = test2$tmp
Iteration:4
  Active:Inactive:NBA: <  - This is region is executing
      test2 = test2$tmp
Iteration:5  > next simulation cycle

相关问题 更多 >