SystemVerilog Program Block

Program Block

The Program construct provides a race-free interaction between the design and the testbench, all elements declared within the program block will get executed in the Reactive region. Non-blocking assignments within the module are scheduled in the active region, initial blocks within program blocks are scheduled in the Reactive region.

Statements within a program block (scheduled in the Reactive region) that are sensitive to changes in design signals declared in modules (scheduled in the active region), an active region is scheduled before the reactive region this avoids the race condition between testbench and design.

Program block syntax

program test(input clk, input [7:0] addr, output [7:0] wdata);
    ...
endprogram
 
    or
 
program test (interface mem_intf);
    ...
endprogram

Program block,

  • can be instantiated and ports can be connected the same as a module
  • can contain one or more initial blocks
  • cannot contain always blocks, modules, interfaces, or other programs
  • In the program block, variables can only be assigned using blocking assignments. Using non-blocking assignments within the program shall be an error

difference between module and program

In the examples below, find the difference between writing testbench with module block and program block.
In example-1 writing testbench with module block, because of race condition testbench gets the dut signal addr value as 0.

In example-2 writing testbench with program block, testbench gets the dut signal addr value as 1.

Therefore writing testbench with program block provides race-free interaction between the design and the testbench.

example-1 with module block

//-------------------------------------------------------------------------
//design code
//-------------------------------------------------------------------------
module design_ex(output bit [7:0] addr);
  initial begin
    addr <= 10;
  end   
endmodule

//-------------------------------------------------------------------------
//testbench
//-------------------------------------------------------------------------
module testbench(input bit [7:0] addr);
  initial begin
    $display("\t Addr = %0d",addr);
  end
endmodule

//-------------------------------------------------------------------------
//testbench top
//-------------------------------------------------------------------------
module tbench_top;
  wire [7:0] addr;

  //design instance
  design_ex dut(addr);

  //testbench instance
  testbench test(addr);
endmodule

Simulator Output

Addr = 0

Click to execute on   

example-2 with a program block

//-------------------------------------------------------------------------
//design code
//-------------------------------------------------------------------------
module design_ex(output bit [7:0] addr);
  initial begin
    addr <= 10;
  end   
endmodule

//-------------------------------------------------------------------------
//testbench
//-------------------------------------------------------------------------

program testbench(input bit [7:0] addr);
  initial begin
    $display("\t Addr = %0d",addr);
  end
endprogram

//-------------------------------------------------------------------------
//testbench top
//-------------------------------------------------------------------------
module tbench_top;
  wire [7:0] addr;

  //design instance
  design_ex dut(addr);
  //testbench instance
  testbench test(addr);
endmodule

Simulator Output

Addr = 10

Click to execute on   

❮ Previous Next ❯