Tutorials

Learn More

In Verilog, a module is a basic building block that contains wires, tasks, function declaration, continuous and procedural statements, and hierarchies of other modules. The module construct behaves perfectly w.r.t. design implementation, while developing a testbench an engineer has to take care to avoid a race condition between design and testbench. The program block is sensitive to the design signals changes that are declared in the module block are scheduled in the reactive region of the time slot.

Syntax:

program <program_name> <port_list>;
  ...
endprogram

Program block purpose

  1. All elements within the program block are scheduled to execute in the reactive region. This helps to avoid race-around conditions between design and testbench.
  2. It provides an execution entry point for the testbench.
  3. It encapsulates testbench data in a single container.

Similarities between program and module block

  1. A program block can instantiate another program block in the way how the module is instantiated another module block.
  2. Both can have no or more inputs, inout, and output ports.
  3. Both can have tasks, functions, variable declaration.
  4. Both can have continuous assignments, initial blocks, concurrent assertions, generate blocks, etc.

Difference between program and module block

  1. A program block can not instantiate a module block. On the opposite side, a module block can instantiate another module or program block.
  2. A program block can not have an interface, user-defined primitives (UDP), always block or nested program.
  3. The initial block inside the program block is scheduled in the reactive region whereas the initial blocks inside the module lock are scheduled in the active region.

How program block avoid race around condition?

To understand it clearly, below two points need to be cleared.

  1. As per System Verilog scheduling semantic, System Verilog events are scheduled in the following order.
    Active region → Non-blocking region → Reactive region. 
  2. The non-blocking assignments (RHS) are evaluated in the active region and updates their LHS in the NBA region (Non-blocking region).

    When the design module assigns some value to a variable in the initial block and the testbench module tries to access the same variable (in the initial block) and perform some action, race around condition is expected to occur.

    Race around situation example

    Let’s understand with the below example, the design module has assigned out <= 2 and the testbench module wants to do some action based on design update (here, value is printed for simplicity). 

    Design Code:

    module dut_example (output bit [3:0] out);
      initial begin
        out <= 2;
      end
    endmodule

    In the active region of a time slot, the RHS value of non-blocking assignment out (<= 2;) is evaluated, LHS value is not yet updated. At the same time, testbench tries to access the variable that has an older value (default value in this case). Thus, the testbench operation will be affected.

    TB Code:

    module tb_mod_top;
      wire [3:0] out;
      
      dut_example DUT(out);
      initial begin
        if(out == 2)
          $display("Design assigned out is 2");
        else
          $display("Design assigned out = %0d", out);
      end
    endmodule

    Output:

    Design assigned out = 0

    Race around solution example using program block

    To resolve this race around the condition, a program block is used that executes in the reactive region. By the time the reactive region is scheduled, the out variable value would have updated to 2 in the NBA region.

    TB Code:

    program tb_pro(input [3:0] out);
      initial begin
        if(out == 2)
          $display("Design assigned out is 2");
        else
          $display("Design assigned out = %0d", out);
      end
    endprogram
    
    module tb_mod_top;
      wire [3:0] out;
      
      dut_example DUT(out);
      tb_pro tb(out);
    endmodule

    Output:

    Design assigned out is 2

    System Verilog Tutorials