Verilog: Timing Controls

Verilog: Timing Controls

Timing Controls

Timing control statements are required in simulation to advance time. The time at which procedural statements will get executed shall be specified using timing controls. Delay based, event based and level sensitive timing controls are available in Verilog. Each of these are discussed below.

Delay Based Timing Control

In this, timing control is achieved by specifying waiting time to execution, when the statement is encountered. The sybmol "#" is used to specify the delay. There are 3 ways, delay based timing control can be specified.

  • Regular Delay Control

    In this delay will be specified on the left of the procedural assignment as a non-zero number. In the below code, execution of line 11 to 14 statements are controlled by some delays. The statement b = 1 will be executed at time 10 and others at time 30,35 and 45. Refer simulation result for more details.

  • Intra-assignment Delay Control

    In this case, delays will be specified on the right hand side of the assignment operation. The RHS expression will be evaluated at the current time and the assignment will be occurred only after the delay. The statement a = #5 (b + c) and rval = #20 L_DELAY + a - 4 are intra-assignment delay control statements. Value of b and c are evaluated at time 45, but assignment to 'a' will happen only at time 50. The same way L_DELAY + a - 4 will be calculated at time 50 and assignment to rval will happen at time 70.

    module delay_control_check; parameter L_DELAY = 10;

    reg a,b,c; reg[3:0] rval;

    initial begin a = 0; b=0; c=0; rval = L_DELAY - 5;

    //Regular Delay Control #10 b = 1; #20 c = a + b; #5 a = c; #10 rval = L_DELAY + a;

    b= 0; c = 0; //Intra assignment a = #5 (b + c); rval = #20 L_DELAY + a - 4; end

    initial begin $monitor($time,"Value a = %b, b= %b, c=%b rval=%d\n",a,b,c,rval); #500 $finish; end

    endmodule /* Simulation result ncsim> run 0Value a = 0, b= 0, c=0 rval= 5

    10Value a = 0, b= 1, c=0 rval= 5

    30Value a = 0, b= 1, c=1 rval= 5

    35Value a = 1, b= 1, c=1 rval= 5

    45Value a = 1, b= 0, c=0 rval=11

    50Value a = 0, b= 0, c=0 rval=11

    70Value a = 0, b= 0, c=0 rval= 6

    Simulation complete via $finish(1) at time 500 NS + 0 ./delay.v:25 #500 $finish; */

  • Zero Delay Control

    Zero delay control statement specifies zero delay value to LHS of procedural assignment. This is a method to ensure that the statement is executed at the end of that simulation time. That means, zero delay control statement is executed only after all other statements in that simulation time are executed. Here, a,b,c are executed different values in two initial block, one using normal assignment and other using zero delay. This example shows that how assignments will happen in the simulation.

    module zero_delay_check; reg a,b,c;

    //initial block with zero delay initial begin
    #0 a = 1; #0 b = 1; #0 c = 1; $display(" Zero delay control a= %b, b= %b, c=%b\n",a,b,c); end

    //initial block without zero delay initial c = 0;

    initial begin a = 0; b = 0; $display("Non-zero delay control a= %b, b= %b, c=%b\n",a,b,c); end

    endmodule

    /* Simulation Result ncsim> run Non-zero delay control a= 0, b= 0, c=0

    Zero delay control a= 1, b= 1, c=1 */

Event Based Timing Control

In this, execution of a statement or a block of a statement is controlled by an event. Regular, named and event OR control are different types of event based controls.

  • Regular event control

    Execution of statement will happen on changes in signal or at a positive or negative transitions of signals. For example posedge of clock, negedge of reset etc.

    eg: @(posedge clock) out = in; @(clock) z = n << 2;

  • Named Event Control

    Event will be declared using keyword 'event' and is triggered by using the symbol ' -> '. In the below example the event 'received' is declared and is triggered when pkt_done is high. Once event is triggered, always block at line 23 will get executed.

    module event_control(in,ctrl,clock,out);

    input [31:0] in; input [2:0] ctrl; input clock; output [31:0] out;

    reg [31:0] out; wire pkt_done;

    event received;

    assign pkt_done = ^ctrl;

    always @(posedge clock) begin if(pkt_done) begin $display("Event : Triggered"); ->received; end end

    always @(received) begin $display("Event : Received"); out = in + 100; end endmodule

    //for testing
    module test; reg [31:0] in; reg [2:0] ctrl; reg clock = 0;

    wire [31:0] out;

    event_control ec(in,ctrl,clock,out);

    always clock = #5 ~clock;

    initial begin in = 32'd25; ctrl = 3'b100;

    #10 in = 'd50; ctrl = 3'b101;

    #10 in = 'd30; ctrl = 3'b001;

    #10 in = 40; ctrl = 3'b010;

    #10 in = 0; ctrl = 3'b000; end

    initial begin $monitor($time,"clock=%b, in = %d, ctrl=%b out=%d\n",clock,in,ctrl,out); #50 $finish; end endmodule

    /* Simulation Result ncsim> run 0clock=0, in = 25, ctrl=100 out= x

    Event : Triggered Event : Received 5clock=1, in = 25, ctrl=100 out= 125

    10clock=0, in = 50, ctrl=101 out= 125

    15clock=1, in = 50, ctrl=101 out= 125

    20clock=0, in = 30, ctrl=001 out= 125

    Event : Triggered Event : Received 25clock=1, in = 30, ctrl=001 out= 130

    30clock=0, in = 40, ctrl=010 out= 130

    Event : Triggered Event : Received 35clock=1, in = 40, ctrl=010 out= 140

    40clock=0, in = 0, ctrl=000 out= 140

    45clock=1, in = 0, ctrl=000 out= 140

    Simulation complete via $finish(1) at time 50 NS + 0 ./event.v:61 #50 $finish; ncsim> exit */

  • Event OR control

    The transitions of signal or event can trigger the execution of statements as shown below.

    always @(clock or in) //Wait for clock or in to change

    OR

    always @(clock, in)

Level Sensitive Timing Control

This waits for a certain condition to be true. In the below example, it waits for xor-ctrl bits to be 1, and then do the assignment to out.

module level_control(in,ctrl,out);

input [31:0] in; input [2:0] ctrl; output [31:0] out;

reg [31:0] out;

always begin wait (^ctrl) #2 out = in + 100; end endmodule

module test_level_control; reg [31:0] in; reg [2:0] ctrl; wire [31:0] out;

level_control ec(in,ctrl,out);

initial begin in = 32'd25; ctrl = 3'b100;

#10 in = 'd50; ctrl = 3'b101;

#10 in = 'd30; ctrl = 3'b001;

#10 in = 40; ctrl = 3'b011;

#10 in = 0; ctrl = 3'b100; end

initial begin $monitor($time,"in=%0d, ctrl=%b out=%0d\n",in,ctrl,out); #50 $finish; end

endmodule

/*

Simulation Result ncsim> run 0in=25, ctrl=100 out=x

2in=25, ctrl=100 out=125

10in=50, ctrl=101 out=125

12in=50, ctrl=101 out=150

20in=30, ctrl=001 out=150

22in=30, ctrl=001 out=130

30in=40, ctrl=011 out=130

32in=40, ctrl=011 out=140

40in=0, ctrl=100 out=140

42in=0, ctrl=100 out=100

Simulation complete via $finish(1) at time 50 NS + 0 ./level_sensitive.v:43 #50 $finish;

*/