评估事件调度-Verilog分层事件队列[英] Evaluation Event Scheduling - Verilog Stratified Event Queue

本文是小编为大家收集整理的关于评估事件调度-Verilog分层事件队列的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我正在尝试在Python中实现一个简单的基于事件的Verilog模拟器,但是我实际上很难在规范中找到一些细节(IEEE 1364-2005的第11节).

假设我只是在clk上完善了一个更新事件,该事件现在获得了新值1(前0).根据规范,这要求我安排敏感过程的"评估事件".

我是否必须安排对always @(posedge clk)块作为活动或不活动事件的评估?我猜后者是正确的吗?

或实际上说更一般.基本上所有事件都安排为无效事件,但有以下例外:

  • 非阻止分配更新作为非阻滞作业事件
  • 连续分配为活动事件

非常感谢!

推荐答案

默认情况下,一切都在活动区域中运行.例外是:

  • #0阻止分配在非活动区域
  • 非阻滞作业在 nba 区域
  • $ MONITOR,$ Strobe和PLI/VPI在 Monitor region

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

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); 

输出:

 From @* $display: x is 3
 From $monitor: x is 3
 From @* $display: x is 11
 From @* $display: x is 7
 From @* $display: x is 5
 From @* $display: x is 2
 From @* $display: x is 4
 From $monitor: x is 4

显示报告更多次,然后监视.这排除了在监视器或将来的区域中累积的@.显示正在报告每个事件区域.每个事件区域只能循环回到活动区域.因此,必须在活动区域​​中处理@,每个更新变量x的区域都触发了新的活动区域事件.

这也可以通过了解Verilog的历史来证明这一点.不幸的是,这还没有得到充分记录.我通过在90年代初在80年代末使用/开发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),修改对象的真实条件,并安排新的评估事件(下次输入 Active 输入的区域).一旦所有激活的事件都完成后,时间表将返回到While-Loop的顶部. 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

本文地址:https://www.itbaoku.cn/post/2090995.html

问题描述

I am trying to implement a simple event based Verilog simulator in Python, but I actually struggle to find some details in the specification (section 11 of IEEE 1364-2005).

Let's say I just perfomed an update event on clk which now obtained the new value 1 (0 before). According to the specification this requires me to schedule 'evaluation events' for sensitive processes.

Do I have to schedule the evaluation of an always @(posedge clk) block as active or inactive event? I'm guessing that the latter is correct?

Or actually, to speak more general. Are basically all events scheduled as inactive events with the following exceptions:

  • Non blocking assignment updates as non-blocking assignment events
  • continuous assignments as active events

Thanks a lot!

推荐答案

By default everything runs in the Active region. The exceptions being:

  • #0 blocking assignments are in the Inactive region
  • Non-blocking assignments are in the NBA region
  • $monitor, $strobe, and PLI/VPI are in the Monitor region

We can prove that @ happens in the Active region, by running the following in any existing simulator:

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); 

Outputs:

 From @* $display: x is 3
 From $monitor: x is 3
 From @* $display: x is 11
 From @* $display: x is 7
 From @* $display: x is 5
 From @* $display: x is 2
 From @* $display: x is 4
 From $monitor: x is 4

Display reports more times then monitor. This rules out @ accruing in the Monitor or Future region. Display is is reporting on every event region. Each event region can only loop back to the Active region. Therefor, the @ must be handled in the Active region and each region that updates the variable x is triggering a new Active region event.

This can also be proved by knowing looking at the history of Verilog. Unfortunately, this is not well documented. I leaned learned about it through people that were using/developing verilog in the late '80s early '90s. The over all explanation is: The Inactive and NBA regions were added to Verilog before IEEE Std 1364-1995, @ predates these two region. The regions were added to add determinism to a non-deterministic simulator.

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



clarification based on feedback from comments

Events are activated, not moved. Activated NBA events enter the true condition of if (E is an update event), modified object and schedule new evaluation events (handled the next time Active region entered). Once all the activated events are completed, the schedule goes back to the top of the while-loop. The NBA region only assigns values, the evaluation was actually done in an earlier Active region stage.
From your example:

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

Each iteration of the while loop would look something like this:

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