Welcome ! This website will help YOU (recent graduates/professionals) learn verification languages like SystemVerilog and UVM. Register for free and access more content !

Verilog is a hardware description language and there is no requirement for designers to simulate their RTL designs to be able to convert them into logic gates. So why do we need to simulate?

Simulation is a technique of applying different input stimulus to the design at different times to check if the RTL code behaves the intended way. Essentially, simulation is a well-followed technique to verify the robustness of the design. It is also similar to how a fabricated chip will be used in the real world and how it reacts to different inputs. For example, the design above represents a positive edge detector with inputs clock and signal which are evaluated at periodic intervals to find the output pe as shown.

There are several EDA companies that develop simulators capable of figuring out the outputs for various inputs to the design. Verilog is defined in terms of a discrete event execution model and different simulators are free to use different algorithms to provide the user with a consistent set of results. The Verilog code is divided into multiple processes and threads and may be evaluated at different times in the course of a simulation.

module tb;
  reg clk;
  reg sig;
  always #5 clk = ~clk;   // Process loops after every 5ns
  initial begin        // Process starts at time 0ns
    sig = 0;
    #5 clk = 0;        // Assign clk to 0 at time 5ns
    #15  sig = 1;      // Assign sig to 1 at time 20ns (#5 + #15)
    #20  sig = 0;      // Assign sig to 0 at time 40ns (#5 + #15 + #20)
    #15  sig = 1;      // Assign sig to 1 at time 55ns (#5 + #15 + #20 + #15)
    #10  sig = 0;      // Assign sig to 0 at time 65ns (#5 + #15 + #20 + #15 + #10)
    #20 $finish;       // Finish simulation at time 85ns

Simulations allow us to dump design and testbench signals into a waveform that can be graphically represented to analyze and debug functionality of the RTL design. The waveform shown below is obtained from an EDA tool and shows the progress of each signal with respect to time and is same as the timing diagram shown before.

simulation example

Every change in the value of a variable or net is called an update event. And processes are sensitive to update events such that these processes are evaluated whenever the update event happens and is called an evaluation event. Because of the possibility of having multiple processes being evaluated arbitrarily, the order of changes has to be tracked in something called as an event queue. Naturally, they are ordered by the simulation time. Placement of a new event on the queue is called scheduling. Simulation time is used to refer to the time value maintained by the simulator to model the actual time it would take for the circuit being simulated. The time values for the example above are shown in nanoseconds ns in the timing diagram.

module des;
  wire abc;
  wire a, b, c;
  assign abc = a & b | c;  // abc is updated via the assign statement (process) whenever a, b or c change -> update event
simulation example

Refresh Verilog and see an example !

The Verilog event queue is logically divided into five regions, and events can be added to any of them. However, it can be removed only from the active region.

Events Description
Active Occur at the current simulation time, and can be processed in any order
Inactive Occur at the current simulation time, but is processed after all active events are done
Nonblocking Evaluated at some previous time, but assignment is done in the current simulation time after active and inactive events are done
Monitor Processed after all the active, inactive and non-blocking events are done
Future Occur at some future simulation time
simulation regions

A simulation cycle is where all active events are processed. The standard guarantees a certain scheduling order except for a few cases and. For example, statements inside a begin-end block will only be executed in the order in which they appear.

module tb;
  reg [3:0] a;
  reg [3:0] b;
  initial begin    // Statements are executed one after the other at appropriate simulation times
    a = 5;      // At time 0ns, a is assigned 5
    b = 2;      // In the same simulation step (time 0ns), b is assigned 2
    #10 a = 7;    // When simulation advances to 10ns, a is assigned 7

The event queue defines that assignment to b should happen after assignment to a.

Was this article helpful ?

We use cookies to personalize content and ads, to provide social media features and to analyze our traffic. You consent to our cookies if you continue to use our website. To find out more about the cookies we use and how to delete them, see our privacy policy.

  I accept cookies from this site.
EU Cookie Directive plugin by www.channeldigital.co.uk