0
\$\begingroup\$

I am facing an issue with the post-synthesis implementation of a special Serial-In-Serial-Out kind of buffer. It receives inputs and stores them in registers and can later output the stored inputs.

  • When iReset is HIGH, the contents of the buffer are cleared.
  • When iValid is HIGH, the values of the registers in the buffer are shifted and buffer[0] receives iResidual.
  • When oEnable is HIGH, the buffer outputs the values of the last register to oResidual (in this case buffer[2]) and the values are shifted accordingly.
  • When oValid is HIGH, it means that oResidual is a valid output.

Here is the full code:

module ResidualBuffer (
 input iClock,
 input iValid,
 input iReset,
 input oEnable,
 input signed [15:0] iResidual,
 output signed [15:0] oResidual,
 output oValid,
 output signed [15:0] bufferReg0,
 output signed [15:0] bufferReg1,
 output signed [15:0] bufferReg2
 );
parameter blkSize = 3;
reg signed [15:0] buffer [0 : blkSize - 1];
integer i;
reg signed [15:0] oResidualReg;
assign oResidual = oResidualReg;
reg signed [blkSize : 0] oValidReg = -2; // for blkSize = 3, oValidReg = 4'b1110
assign oValid = oValidReg[0];
assign bufferReg0 = buffer[0];
assign bufferReg1 = buffer[1];
assign bufferReg2 = buffer[2];
always @(posedge iClock or posedge iReset) begin
 if (iReset) begin
 for (i = 0; i < blkSize; i = i + 1) begin
 buffer[i] <= 0;
 end
 oResidualReg <= 0;
 oValidReg <= -2;
 end else if (iValid) begin
 for (i = 1; i < blkSize; i = i + 1) begin
 buffer[i] <= buffer[i - 1];
 end
 buffer[0] <= iResidual;
 oResidualReg <= oResidualReg;
 oValidReg <= oValidReg;
 end else if (oEnable) begin
 oValidReg <= oValidReg>>1;
 oResidualReg <= buffer[blkSize - 1];
 for (i = 1; i < blkSize; i = i + 1) begin
 buffer[i] <= buffer[i - 1];
 end
 end
end
endmodule

The behavioural simulation is working as expected: Behavioural-simulation

The post-synthesis simulation is different and confusing: Post-synthesis-simulation

The problems I am facing are:

  1. When iValid is LOW, buffer[0] continues to receive iResidual and the values in the registers are shifted and I don't understand why.
  2. When oEnable is HIGH, it is reflected only in the next clock cycle. However this is not the case for iValid as explained in (1) and I don't understand why.

~Edit: For those who want to look at the testbench I used

`timescale 1ns / 100ps
module ResidualBufferTB;
 reg iClock;
 reg iValid;
 reg iReset;
 reg oEnable;
 reg signed [15:0] iResidual;
 wire signed [15:0] oResidual;
 wire oValid;
 wire signed [15:0] bufferReg0;
 wire signed [15:0] bufferReg1;
 wire signed [15:0] bufferReg2;
 ResidualBuffer #(.blkSize(3)) DUT (
 .iClock(iClock),
 .iValid(iValid),
 .iReset(iReset),
 .oEnable(oEnable),
 .iResidual(iResidual),
 .oResidual(oResidual),
 .oValid(oValid),
 .bufferReg0(bufferReg0),
 .bufferReg1(bufferReg1),
 .bufferReg2(bufferReg2)
 );
 always begin
 #0 iClock = 0;
 #125 iClock = 1;
 #125 iClock = 0;
 end
 initial begin
 iReset = 1; iValid = 0; oEnable = 0;
 #125 iReset = 0;
 #250 iValid = 1; iResidual = 20;
 #250 iResidual = -123;
 #250 iResidual = 31;
 #250 iValid = 0; iResidual = 0;
 #250
 #250 oEnable = 1;
 #1250
 $stop;
 end
endmodule
asked May 21, 2020 at 11:51
\$\endgroup\$
0

1 Answer 1

0
\$\begingroup\$

You didn't provide the testbench so I can't be certain but it looks like you are changing the values of the inputs at the same time the clock rises. That will often cause differences between behavioral and post-synthesis simulations.

You may be seeing the results of setup time violations in the logic. The behavioral simulation has no delays but the post-synthesis simulation does, so their behavior will be different. Try moving the changes in the inputs to be coincident with the falling edge of the clock rather than the rising edge.

answered May 21, 2020 at 12:20
\$\endgroup\$
2
  • \$\begingroup\$ Thanks for the answer. So it is possible that when iValid goes to HIGH and iResidual changes at the same time, that buffer[0] will receive the new value of iResidual, but when oEnable goes to HIGH that it will take a clock cycle for buffer[2]'s value to change? \$\endgroup\$ Commented May 21, 2020 at 12:25
  • \$\begingroup\$ Your design is synchronous...we only care about the values of the inputs when a rising clock edge occurs. So, all of the inputs should be stable (unchanging) for at least a short time before the clock edge and a short time after the clock edge. \$\endgroup\$ Commented May 21, 2020 at 12:50

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.