Verilog Event Regions

Hi All,

Today we'll see about something important about Verilog language. We'll see the event regions of the Verilog and how does it affect the simulation process.


Verilog Event Regions

Please note that this is a conceptual model as per IEEE standard and how each vendor implemets this model, is completely proprietary.

Verilog is divided in the 4 event regions. And for any given time stamp, it is necessary to execute events of all region, before moving to the next time stamp (So if timescale is 1ns/10ps, then at every 10ps, events in all of the regions are evaluated, before moving to next simulation time)
  • Active Region - 
    • The active event region is the event region, where most of the Verilog events are scheduled including Blocking Assignment, Evaluation of RHS side of Nonblocking Assignments, Continuous Assignments, $display command execution and evaluation of i/p & o/p of primitives. 
    • However all of the sub events of the active region, can be executed in any order and is strictly vendor specific or proprietary.
    • Events are added in any of the event queue, but are removed from only active event queue. So all events scheduled in other event queues are eventually promoted to active event queue in a given time stamp.
  • Inactive Region - 
    • Events with #0 delays are scheduled in this event region.
  • Nonblocking Region - 
    • Update of LHS side of a nonblocking assignment is scheduled in this event region.
  • Monitor Region 
    • $monitor,  $strobe function execution are scheduled in this event region.
This event regions are very useful in solving the race condition in the Verilog Design. 

Now you may think what is "Race Condition" in a design.

A verilog race condition is the condition, when multiple events, which are scheduled in the same simulation time stamp, will give different results depending upon the order of execution.

Now let's look at a small design to get idea of the race condition.



Now here is the Verilog code havign race condition. (only always block is showed)

always @ (posedge clk, negedge rst)
begin
  if (rst != 0)
    q1 = 1'b0;
  else
    q1 = q2;
end

always @ (posedge clk, negedge rst)
begin
  if (rst != 0)
    q2 = 1'b0;
  else
    q2 = q1;
end

This code is having the inbuilt race condition, because on the positive edge of clock, we don't know which always block will be executed first. And depending upon that result can be different than the expectations. Also due to blocking assignment, instead of swapping of values, both flipflops will have the same data.

Now check the below code for same design but without race condition.
always @ (posedge clk, negedge rst)
begin
  if (rst != 0)
    q1 <= 1'b0;
  else
    q1 <= q2;
end


always @ (posedge clk, negedge rst)
begin
  if (rst != 0)
    q2 <= 1'b0;
  else
    q2 <= q1;
end

Only difference between 2 codes is that the later one is having nonblocking assignment.

Now irrespective of which always block is executed first, this code will always give proper results. Because of nonblocking assignment, the update of q1 & q2 is scheduled in the nonblocking region, whereas their RHS side gets calculated in the active region. (So it will take the previous value of q1 & q2).

Hope that this post will help you to better understand the verilog design and better code it.

Feel free to comment and ask questions. :)

Comments

Post a Comment

Popular posts from this blog

SystemVerilog Event Regions

Standard Cell Based ASIC Design Flow