1
\$\begingroup\$

I have a set of test vectors saved in a csv file and formatted as follows:

0010,1000,1010
1110,0101,0001
1001,0001,0000

These are randomly generated and can be of any arbitrary length or number. Here the number is 3 (3 vectors per row) and length is 4 (4 bits for each vector).

I wanted to read these vectors in Verilog and apply them to an array of instantiated modules. In other words, 0010 will be applied to the first instance, 1010 to the third instance. Next apply 1110 to first instance, 0001 to the third and so on.

We have three latches (Lat module) and we are generating 3 instances of it in Lat_array module. I want the operation be like: first indexed instance gets the first 4 bits, second instance gets the second set of four bits and the final instance gets the last four bits in the row. All of them get the 4 bits at the same time and output at the same. After that, the data in the next row is applied in the same order as another input test vector. Below the waveforms are posted.

desired waveform actual waveform

I tried the following code. I could test a single module, but I don't know how to test several instances using the test vectors above. Could you please guide me where I doing wrong and how to implement this?

Top level module:

module Lat_array #(parameter number =3, parameter length = 4)(ins, clks, resets,outs);

input [length- 1:0] ins;

input clks, resets;

output [length-1:0] outs;

generate
 genvar i;
 for (i=0; i<number; i=i+1) begin
   Lat lat(
     .clk(clks)
    ,.reset(resets)
    ,.in(ins)
    ,.out(outs)
    );
 end
endgenerate

endmodule

The Lat module:

module Lat #(parameter length = 4)(in, clk, reset,out);

input [length- 1:0] in;
input clk, reset;

output [length-1:0] out;

reg [length-1:0] res;

always @ (posedge clk) begin
if (!reset)
    res <= 0;
else
    res <= in;
end
assign out = res;

endmodule  

Testbench:

`timescale 1ns/1ps

module tb;

parameter number = 3;
parameter length = 4;

reg [length-1:0] in;

reg clk, reset;

wire [length-1:0] out;

Lat_array #(.number(number), .length(length)) lat_insts (.ins(in), .clks(clk), .resets(reset), .outs(out));

initial begin
reset <=0;
clk <=0;
end

always @(clk) #100 clk <= ~clk;


reg [length-1:0] temp;
reg [length- 1:0] test_in [(3*number)-1:0];

integer f, k;

initial begin

#500 reset <= 1;
     in <= 0;

f = $fopen("test.csv", "r");
 
  for (integer i = 0; i < 3; i = i + 1)
  //while(! $feof(f))
  begin
        for(integer j = 0; j < number; j = j + 1)
        begin
        
            k = $fscanf(f,"%b,",temp);
            $display("%b", temp);

            test_in[j] = temp;
        end
        #10; in = test_in[i-1];
  end
  #200 reset <=0;
  $monitor("in=%b, out=%b", in, out);
#1000 $finish;
end
endmodule
\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

The problem is that you are driving the same 4-bit input value to each instance of your Lat module inside the Lat_array module.

One way to fix this is to get rid of the Lat_array module and just place the instance array directly into the testbench:

module tb;
    parameter number = 3; // number of test vectors per input
    parameter length = 4; // width of in/out busses

    reg clk, reset;
    reg  [length-1:0] in  [number];
    wire [length-1:0] out [number];
    reg  [length-1:0] temp;
    integer f, k;

    genvar i;
    for (i=0; i<number; i=i+1) begin
        Lat lat (
             .clk(clk)
            ,.reset(reset)
            ,.in(in[i])
            ,.out(out[i])
        );
    end

    always #100 clk <= ~clk;

    initial begin
        reset <= 0;
        clk   <= 0;

        repeat (3) @(posedge clk); 
        reset <= 1;
        for (integer i = 0; i < number; i = i + 1) in[i] <= 0;
    
        f = $fopen("test.csv", "r");
        for (integer i = 0; i < 3; i = i + 1) begin
            for (integer j = 0; j < number; j = j + 1) begin
                k = $fscanf(f,"%b,",temp);
                $display($time, , "%b", temp);
                in[j] <= temp;
            end
            repeat (3) @(posedge clk); 
        end

        #200 reset <= 0;
        #1000 $finish;
    end
endmodule

Waves:

enter image description here

\$\endgroup\$
4
  • \$\begingroup\$ Thank you very much for your answer. Just one other question, how to have a delayed outputs as I showed in the waveforms. I tried to add a counter in Lat module but that delayed output for each input differently. Also tried adding an idle time before out <=in; with repeat (20) @(posedge clk) in Lat module, but has the same problem. \$\endgroup\$ Aug 9 at 13:36
  • \$\begingroup\$ @engineer1155: You're welcome. I updated the answer so that the input value is held for 3 cycles. \$\endgroup\$
    – toolic
    Aug 9 at 14:09
  • \$\begingroup\$ thanks but that only delayed the first outputs \$\endgroup\$ Aug 9 at 14:50
  • \$\begingroup\$ @engineer1155: Works for me on 2 simulators. I added waves to my answer. \$\endgroup\$
    – toolic
    Aug 9 at 14:55

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.