Search code examples
verilogvariable-assignmentdelayvivado

What is the subtle purpose for writing Verilog code this way instead of direct continuous assignment?


I saw the following Verilog code in the top-most simulation test-bench source file sim_tb_top.v generated automatically by Example Design of MIG memory controller in Xilinx Vivado:

localparam real TPROP_PCB_CTRL     = 0.00;
                   // Delay for Address and Ctrl signals
wire [0:0] ddr3_cs_n_fpga;
reg [0:0] ddr3_cs_n_sdram_tmp;
wire [0:0] ddr3_cs_n_sdram;

always @( * )
    ddr3_cs_n_sdram_tmp   <=  #(TPROP_PCB_CTRL) ddr3_cs_n_fpga;
assign ddr3_cs_n_sdram =  ddr3_cs_n_sdram_tmp;

I don't understand why the generated source code does not just use a direct continuous assignment:

assign ddr3_cs_n_sdram = #(TPROP_PCB_CTRL) ddr3_cs_n_fpga;

I cannot see the difference of the two. Does the generated code in sim_tb_top.v which uses a combinational always block have some special subtle purpose over a direct continuous assignment?


Solution

  • The always block with a nonblocking assignment performs transport delay, whereas the continuous assignment performs inertial delay.

    Transport delay means the signals RHS of the assignment can change faster than the assignment delay without any loss in intermediate values.

    Inertial delay means if the signals on the RHS of the assignment change faster than the assignment delay, those intermediate values will get suppressed; a new assignment cannot happen until the next scheduled assignment happens. A blocking assignment in the always block could have produce the same effect, but continuous assignments always have inertial delay.

    I'm assuming the delays are not always 0.0 and overwritten by SDF or some other mechanism.