Program Block

 Program Block 


The Program construct provides race-free interaction between the design and the testbench, all elements declared within the program will get executed in Reactive region.

Non-blocking assignments with in 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), as active region is scheduled before the reactive region this avoids the race condition between testbench and design.

The syntax for the program block is,

      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 same as module.
  • can contain one or more initial blocks. 
  • cannot contain always blocks, modules, interfaces, or other programs.
  • In program variables can only be assigned using blocking assignments. Using non-blocking assignments with in the program shall be an error.
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: 


//-------------------------------------------------------------------------
//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

Execute the above code on 

 Example-2: 



//-------------------------------------------------------------------------
//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

Execute the above code on