Search code examples
verilog

Missing data while shuffling


I'm working on shuffling input Datas using multiplexers and D flipflops. While simulating it, I'm getting one delay in between which makes the next data to disappear.

Here is the Verilog code (for checking the wires I have given them as outputs in the port list):

module shuffle (in0,in1,s,clk,out0,out1,c1,c2,d1,d2,y1,y2);
input [4:0] in0,in1;
input clk,s;
output [4:0]out0,out1;
output [4:0] c1,c2,d1,d2,y1,y2;

dflip D1(in1,clk,y1);
dflip D2(y1,clk,c1);
dflip D3(c1,clk,c2);
mux2_1 m2(in0,c2,s,out1);
mux2_1 m1(c2,in0,s,y2);
dflip D4(y2,clk,d1);
dflip D5(d1,clk,d2);
dflip D6(d2,clk,out0);
endmodule

module dflip (d,clk,q);
input [4:0]d;
input clk;
output reg [4:0]q;
always @(posedge clk)
begin
   q <= d;
end
endmodule

module mux2_1 (d0, d1, s, y);
output [4:0]y;
input [4:0]d0, d1;
input s;
assign y = (s)? d1:d0;
endmodule

Here's the Testbench:-

module shuffle_test;
reg [4:0] in0,in1;
reg clk,s;
wire [4:0] y1,c1,c2,y2,d1,d2;
wire [4:0] out0,out1;

shuffle s1 (.in0(in0),.in1(in1),.s(s),.clk(clk),.out0(out0),.out1(out1),.c1(c1),.c2(c2),.d1(d1),.d2(d2),.y1(y1),.y2(y2));

always #50 clk = ~clk;
always #200 s = ~s;

initial 
    begin
           clk = 1; s = 1;
           in0 = 5'b00000; //0
           in1 = 5'b00100; //4
      #100 in0 = 5'b00001; //1
           in1 = 5'b00101; //5
      #100 in0 = 5'b00010; //2
           in1 = 5'b00110; //6
      #100 in0 = 5'b00011; //3
           in1 = 5'b00111; //7
          #300 $stop;
    end
endmodule

simulation output

These are the inputs:

clock cycle 0 1 2 3 4 5 6
in0 0 1 2 3
in1 4 5 6 7

Here's my expected output:

clock cycle 0 1 2 3 4 5 6
out0 - - 0 1 4 5
out1 - - 2 3 6 7

This is my output: -

clock cylce 0 1 2 3 4 5 6
out0 - - 0 1 - 4 3
out1 - - 2 3 6 7

Solution

  • The problem is that you have a Verilog simulation race condition in your testbench. You need to drive the design inputs the same way as you drive the design data internally, namely using:

    • @(posedge clk)
    • Nonblocking assignments (<=)

    always #50 clk = ~clk;
    
    initial begin
        clk = 1; s = 1;
        in0 = 5'b00000; //0
        in1 = 5'b00100; //4
        @(posedge clk);
        in0 <= 5'b00001; //1
        in1 <= 5'b00101; //5
        @(posedge clk);
        s   <= ~s;
        in0 <= 5'b00010; //2
        in1 <= 5'b00110; //6
        @(posedge clk);
        in0 <= 5'b00011; //3
        in1 <= 5'b00111; //7
        @(posedge clk);
        s   <= ~s;
        #300 $finish;
    end