0

I'm trying to read 16384 values in from a .txt file and use them as values in my testbench. I'm using $fopen and trying to use $fscanf. The error I'm getting back is that 'A' is an unpacked array, I'm not sure if my method is correct even without this error. Thanks for any help!

module tb2_fir;
// Inputs
reg Clk,rst_n;
reg signed [7:0] Xin;

// Outputs
wire signed [15:0] Yout;
reg signed [15:0]A[0:16383];
integer file,fd,i,file1,file2;


// Instantiate the Unit Under Test (UUT)
fir uut (
    .Clk(Clk), 
    .Xin(Xin), 
    .Yout(Yout),
    .rst_n(rst_n)
);

//Generate a clock with 10 ns clock period.
initial Clk = 0;
always #5 Clk =~Clk;
always @(negedge Clk)
begin
if(rst_n)
Xin<='0;
end

//Initialize and apply the inputs.
initial begin 
file=$fopen("data_1.txt","r");
file2=$fscanf(file,"%d",A);

for(i=0;i<16383;i=i+1)
@(negedge Clk) Xin=A[i];
$finish;
end   
endmodule
Aaron Ryan
  • 97
  • 1
  • 10
  • 0, 0, -257, 4840, -9229, 4132, 4840, -4132, -4840, 4132, 4840, -4132, -4840, 9229, -9769, 11287,-10235, 9229, -9769, 11827,-12833, 12293,-10775, 11827,-12833, 12293, -5138, all values are between -12.5k and +12.5k, I've changed the width to represent this – Aaron Ryan Jul 16 '21 at 13:59

2 Answers2

2

No, you cannot read in your data in a single call to $fscanf to fill your array. In order to read in all the data from your file (which in the comment you specify as a CSV), you'll need to loop over the elements one at a time:

reg signed [15:0] A[0:16383];
integer fd, i, scanRet;
...
initial begin
  fd = $fopen("data_1.txt", "r");
  
  i = 0;
  do begin
    // Note that if you have data like '0, 0, -10, 23, 1000, ...' in your file, you need the comma in the format string
    scanRet = $fscanf(fd, "%d,", A[i]);
    i = i + 1;
  end while (i < $size(A) && scanRet > 0);
  
  for (i = 0; i < $size(A); i = i + 1) begin
    @(negedge Clk) Xin = A[i]; // Note that you declare Xin as reg signed [7:0], while A[i] is reg signed [15:0]; are you sure you only want to truncate A[i] to a byte?
  end
  $finish;
end

Be sure to account for how your data is actually formatted in the file in your format string.

Unn
  • 4,775
  • 18
  • 30
1
reg signed [15:0]A[0:16383];

You instantiate A to be an unpacked array with 16384 elements, each element is a 16-bit array. It is all good here. To use the $fscanf function, you have to loop 16384 times to fill each element.

reg [16384:0] cnt = 16384;
//Initialize and apply the inputs.
initial begin 
file=$fopen("data_1.txt","r");
while (cnt>0) begin
    file2=$fscanf(file,"%d",A[cnt]);
    cnt = cnt - 1;
end

Finally, you need to close the file to release the buffer.

$fclose(file);
Guan
  • 13
  • 2