0
\$\begingroup\$

I am using the code shown here Verilog: Writing to a Register Happens A Clock Cycle Late and that user posted a picture where output would change 2 cycles after asserting write enable. That post got an answer which seemed reasonably good to me. However, I decided to simulate the exact same code and create a testbench for it and in mine, output appears only 1 clock cycle after asserting write enable. Could somebody explain to me why is different if I'm doing the exact same thing?

enter image description here

The only difference I can spot is we're not using the same simulator but how could that be the reason?

This is testbench:

`timescale 1ns / 1ps
module test_regblock_tb;

parameter tclk = 10;

reg clk = 1'b1;
reg rst = 1'b1;

always
    #(tclk/2) clk =~clk;

initial begin
    #(tclk*10);
    rst = 1'b0;
end

reg [4:0] RegA_Name = 4'd5;
reg [4:0] RegB_Name = 4'd6;
reg [4:0] RegC_Name = 4'd7;
reg [31:0] RegA_In = 32'd0;
reg [31:0] RegC_In = 32'd0;
reg RegA_WrtEn = 1'b0;
reg RegC_WrtEn = 1'b0;

wire [31:0] RegA_Out;
wire [31:0] RegB_Out;

RegisterFile regblock(
.CLK(clk),
.RegA_Name(RegA_Name),
.RegB_Name(RegB_Name),
.RegC_Name(RegC_Name),
.RegA_In(RegA_In),
.RegC_In(RegC_In),
.RegA_WrtEn(RegA_WrtEn),
.RegC_WrtEn(RegC_WrtEn),
.RegA_Out(RegA_Out),
.RegB_Out(RegB_Out)
);

initial 
begin
#(11*tclk);
RegA_In = 32'd126;
RegA_WrtEn = 1'b1;
#(tclk);
RegA_WrtEn = 1'b0;
#(50*tclk);
$stop;

end 

endmodule
\$\endgroup\$
0
1
\$\begingroup\$

The problem is with your testbench's use of #(tclk*N) followed by the use of blocking assignments to your design's inputs—it's a race condition. Your testbench should be using non-blocking assignments to any signals synchronized to the rising edge of tclk. Or you can adjust your testbench initial block so that the signal changes do not coincide with the rising edge.

\$\endgroup\$
3
  • \$\begingroup\$ I think your last suggestion is the best one. Moving all input signal changes away from the clock edges makes it a lot easier to see what is going on. \$\endgroup\$ – Elliot Alderson Jul 29 '20 at 20:24
  • \$\begingroup\$ I see. Correct me if I'm wrong but this race condition is unlikely (if not impossible) to happen in real hardware since signals won't change at the exact same time as the rising edge of the clock, so what I was seeing in simulation (output at only 1 clock cycle) would not happen if I tested it on real hardware, right? It wouldn't be ready until 2 clock cycles. \$\endgroup\$ – simedro Jul 30 '20 at 6:43
  • \$\begingroup\$ Simulation testbenches do not exist in real hardware. Real hardware can have race conditions if the hardware logic is not placed and routed correctly, so not impossible. We tend to take that for granted. \$\endgroup\$ – dave_59 Aug 1 '20 at 0:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.