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

查看:165
本文介绍了评估事件计划-Verilog分层事件队列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

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

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

非常感谢!

解决方案

默认情况下,所有内容都在 Active 区域中运行.例外是:

  • #0阻止分配位于无效区域
  • 无阻碍的任务位于 NBA 地区
  • $ monitor,$ strobe和PLI/VPI在 Monitor 区域

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

 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的历史来证明.不幸的是,这没有很好的记录.我通过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),修改对象的真实条件并安排新的评估事件(在下次进入活动区域时处理).一旦所有 activated 事件都完成,该计划将返回while循环的顶部. NBA 地区仅分配值,评估实际上是在更早的 Active 地区阶段进行的.
根据您的示例:

 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

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

这篇关于评估事件计划-Verilog分层事件队列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆