1

I am trying to read a set of values for my simulation from the input.csv file and writing the results to the output.csv file. I see some inconsistency when I dump the results to the output.csv file.

My module bypass just registers the data to two stages and sends the input to the output.

module bypass (clk, rst, a,b,c,d,w,x,y,z);

input clk, rst;
input [31:0] a, b, c,d;
output reg [31:0] w,x,y,z;

reg [31:0] stg1_a, stg1_b, stg1_c, stg1_d;
reg [31:0] stg2_a, stg2_b, stg2_c, stg2_d;


always @(posedge clk) begin
    if (rst) begin
        stg1_a <= 0; 
        stg1_b <= 0; 
        stg1_c <= 0; 
        stg1_d <= 0;
        stg2_a <= 0; 
        stg2_b <= 0; 
        stg2_c <= 0; 
        stg2_d <= 0;
        w <= 0;
        x <= 0;
        y <= 0;
        z <= 0;
     end else begin    
        stg1_a <= a; 
        stg1_b <= b; 
        stg1_c <= c; 
        stg1_d <= d;
        stg2_a <= stg1_a; 
        stg2_b <= stg1_b; 
        stg2_c <= stg1_c; 
        stg2_d <= stg1_d;
        w <= stg2_a;
        x <= stg2_b;
        y <= stg2_c;
        z <= stg2_d;
     end 
end
     
endmodule

Below is my testbench:

`timescale 1ns / 1ps
module tb_bypass();

`define CSV_FILE "input.csv"
`define CSV_OUT_FILE "output.csv"
    integer outfile1; //file descriptors
    integer i;  //index used in "for" loop

reg CLK, RST;

parameter REG_WIDTH = 32;
parameter CSV_COL_DEPTH = 32;

reg [REG_WIDTH-1 : 0] col1[0 : CSV_COL_DEPTH-1]; 
reg [REG_WIDTH-1 : 0] col2[0 : CSV_COL_DEPTH-1];
reg [REG_WIDTH-1 : 0] col3[0 : CSV_COL_DEPTH-1]; 
reg [REG_WIDTH-1 : 0] col4[0 : CSV_COL_DEPTH-1];

reg [REG_WIDTH-1 : 0] A, B, C, D;
wire [REG_WIDTH-1 : 0] W, X, Y, Z;
reg [REG_WIDTH-1 : 0] file1, r, scanRet, file2, start;

bypass dut (.clk(CLK), 
                     .rst(RST), 
                     .a(A),.b(B),.c(C),.d(D),
                     .w(W),.x(X),.y(Y),.z(Z));

always #5 CLK = !CLK;
                     
                     
initial begin
    start = 0;
    CLK = 0;
    RST = 1;
    #10 RST = 0;
    end

initial begin
    file1=$fopen(`CSV_FILE,"r");
    file2=$fopen(`CSV_OUT_FILE,"w");

    i = 0;
    while (i < CSV_COL_DEPTH)
        begin 
            scanRet = $fscanf(file1, "%h, %h, %h, %h", col1[i], col2[i], col3[i], col4[i]);
            i = i + 1;
        end     
    
    for (i = 0; i < CSV_COL_DEPTH; i = i + 1) begin 
        @(posedge CLK) A = col1[i]; 
                   B = col2[i];
                   C = col3[i];
                   D = col4[i]; 
                   start = 1;
      $display("%h, %h, %h, %h",W, X, Y, Z);
      $fwrite(file2,"%h, %h, %h, %h\n",W, X, Y, Z);
    end
    start = 0;
   
          
    //once writing is finished, close all the files.
    $fclose(file1);
    $fclose(file2);  
    
    //wait and then stop the simulation.
    #10000;
    $stop;
end 
  
endmodule
                 

The following is the input.csv that I use for my test:

00000000,00000001,00000002,00000003
00000004,00000005,00000006,00000007
00000008,00000009,0000000A,0000000B
0000000C,0000000D,0000000E,0000000F
00000010,00000011,00000012,00000013
00000014,00000015,00000016,00000017
00000018,00000019,0000001A,0000001B
0000001C,0000001D,0000001E,0000001F
00000020,00000021,00000022,00000023
00000024,00000025,00000026,00000027
00000028,00000029,0000002A,0000002B
0000002C,0000002D,0000002E,0000002F
00000030,00000031,00000032,00000033
00000034,00000035,00000036,00000037
00000038,00000039,0000003A,0000003B
0000003C,0000003D,0000003E,0000003F
00000040,00000041,00000042,00000043
00000044,00000045,00000046,00000047
00000048,00000049,0000004A,0000004B
0000004C,0000004D,0000004E,0000004F
00000050,00000051,00000052,00000053
00000054,00000055,00000056,00000057
00000058,00000059,0000005A,0000005B
0000005C,0000005D,0000005E,0000005F
00000060,00000061,00000062,00000063
00000064,00000065,00000066,00000067
00000068,00000069,0000006A,0000006B
0000006C,0000006D,0000006E,0000006F
00000070,00000071,00000072,00000073
00000074,00000075,00000076,00000077
00000078,00000079,0000007A,0000007B
0000007C,0000007D,0000007E,0000007F

The following is my output.csv. I expect the output.csv to be similar to the input.csv, but I see some inconsistency. I am missing the last few lines and a line in the start as shown below.

xxxxxxxx, xxxxxxxx, xxxxxxxx, xxxxxxxx
00000000, 00000000, 00000000, 00000000
00000000, 00000000, 00000000, 00000000
00000000, 00000000, 00000000, 00000000
00000004, 00000005, 00000006, 00000007
00000008, 00000009, 0000000a, 0000000b
0000000c, 0000000d, 0000000e, 0000000f
00000010, 00000011, 00000012, 00000013
00000014, 00000015, 00000016, 00000017
00000018, 00000019, 0000001a, 0000001b
0000001c, 0000001d, 0000001e, 0000001f
00000020, 00000021, 00000022, 00000023
00000024, 00000025, 00000026, 00000027
00000028, 00000029, 0000002a, 0000002b
0000002c, 0000002d, 0000002e, 0000002f
00000030, 00000031, 00000032, 00000033
00000034, 00000035, 00000036, 00000037
00000038, 00000039, 0000003a, 0000003b
0000003c, 0000003d, 0000003e, 0000003f
00000040, 00000041, 00000042, 00000043
00000044, 00000045, 00000046, 00000047
00000048, 00000049, 0000004a, 0000004b
0000004c, 0000004d, 0000004e, 0000004f
00000050, 00000051, 00000052, 00000053
00000054, 00000055, 00000056, 00000057
00000058, 00000059, 0000005a, 0000005b
0000005c, 0000005d, 0000005e, 0000005f
00000060, 00000061, 00000062, 00000063
00000064, 00000065, 00000066, 00000067
00000068, 00000069, 0000006a, 0000006b
0000006c, 0000006d, 0000006e, 0000006f
00000070, 00000071, 00000072, 00000073

I am trying to understand where I am going wrong.

toolic
  • 57,801
  • 17
  • 75
  • 117
user2532296
  • 828
  • 1
  • 10
  • 27

2 Answers2

1

There is a simulation race condition in your testbench. You need to drive the inputs to the dut using nonblocking assignments (<=) instead of blocking assignments (=). For example:

    @(posedge CLK) A <= col1[i]; 

This fixes the missing 0, 1, 2, 3 in your output.

Since your design adds cycles of latency between your input and output, you need to extend the time that you look at your outputs (after you stop driving your inputs).

Here is how the testbench can be changed to get your expected output:

    for (i = 0; i < CSV_COL_DEPTH; i = i + 1) begin 
        @(posedge CLK) A <= col1[i]; 
                   B <= col2[i];
                   C <= col3[i];
                   D <= col4[i]; 
                   start = 1;
        @(negedge CLK);
      $display("%h, %h, %h, %h",W, X, Y, Z);
      $fwrite(file2,"%h, %h, %h, %h\n",W, X, Y, Z);
    end
    for (i = 0; i < 3; i = i + 1) begin 
        @(negedge CLK);
      $display("%h, %h, %h, %h",W, X, Y, Z);
      $fwrite(file2,"%h, %h, %h, %h\n",W, X, Y, Z);
    end
    start = 0;

Note the 2nd for loop, which only displays and writes to your file.

For the display/fwrites, I changed posedge to negedge to avoid races.

toolic
  • 57,801
  • 17
  • 75
  • 117
-1

When RST is set, all of the registers in your design are set to 0.

Your bench is sending the first set of values while RST is set.

Additionally, you need to run at least 3 more clocks to sample the remaining values.

The strategy previously posted of separating the driving and monitoring loops is worth considering, although potential problems with blocking assignments is a red herring in this instance.

Matt
  • 1
  • 2