Electronic – Relation between delta cycle and event scheduling in verilog simulation

simulationverilog

I understand that in Verilog/SystemVerilog standards there are different regions for event scheduling, thus mimicking the behavior of concurrent hardware. But how does this relate to the delta cycles I see in simulators(like expanding at a specific time point to see signals updating at different cycles)?

I can only find delta cycle concepts defined in VHDL simulations, not Verilog. Can anyone explain these two concepts?

Best Answer

"Delta cycles are an HDL concept used to order events that occur in zero physical time." sigasi.com

Taking the definition for Sigasi, what VHDL calls delay cycles, Verilog calls a scheduler. How VHDL and Verilog determine the order of zero time events is very different.

VHDL is a determinate simulator where it orders zero time events by updating everything (values from the previous cycle) before evaluating anything in each time step.

Verilog is an indeterminate simulator where it orders zero time events by using prioritized scheduler with five regions (Note: SystemVerilog has 17 regions). Each region is executed in a prioritized order. The events within each region can be executed in any order. Event can schedule (not execute) new events to any region. When a region finishes executing its events, the scheduler moves to the highest priority region that has scheduled events. The final region does not schedule events in the current cycle, it schedules events future time steps. The regions are:

  1. Active Region (before any #0):
    • Evaluate and assign all procedural blocking(=) assignments (always block)
    • Evaluate and assign all continuous assignments (assign statements)
    • Evaluate non-blocking assignments
    • Evaluate inputs and change outputs of all primitives
    • Evaluate and output $display and $write calls
  2. Inactive Region :
    • Add additional events to the scheduler from each procedural block until the next #0
    • Callback procedures scheduled with PLI routines such as tf_synchronize()(deprecated in IEEE 1364-2005) and vpi_register_cb(cbReadWriteSynch)
  3. NBA Region :
    • Assign the non-blocking(<=) assignments
  4. Monitor region
    • Evaluate and write $monitor and $strobe calls
    • Call PLI with reason_rosynchronize(deprecated in IEEE 1364-2005)
  5. Future Region :
    • Schedule events to happen #N (where N>0) in the time steps in the future

In Verilog, one "delta cycle" may follow the order:

Active⇒Inactive⇒Active⇒NBA⇒Active⇒NBA⇒Inactive⇒NBA⇒Active⇒Monitor⇒Future
OR
Active⇒Inactive⇒NBA⇒Active⇒Monitor⇒Future

It can look very confusing and it is possible to get into an infinite loop. It is something that several VHDL blogs and paper declare a major flaw in Verilog. In reality, when following the basic coding style of only using blocking assignments in combinational blocks and only using non-blocking assignments in sequential blocks, a typical Verilog RTL simulation's "delta cycle" will look like:

Active(init & clk)⇒NBA(flop update)⇒Active(comb logic)⇒Future(schedule clk)

The first Active region is for initializing and updating the clock. Most of the design is NBA(update) then Active(evaluate), same execution as VHDL. The other regions (including SystemVerilog's additional regions) exist for intend non-synthesizable behavioral modeling, linking to external languages (ex. C/C++), and verification test benches.

I will add that historically the Inactive region was created design. It was a failed attempt to determine what value a flop should be assigned to. NBA was created after and has been the recommend solution since. Any design still using the Inactive region (#0 delays) is following an practice that has been obsolete for roughly 20 year or more.