1

Is there a way in SystemVerilog to create a dynamic array that allocates its memory contiguously? I'm trying to read in data from a file into a dynamic array. The problem appears to be that the dynamic array is not in contiguous memory locations, so the file is not read properly into the array.

When I declare the variable reading the file as a non-dynamic array it works fine, so I assume the problem is contiguous memory. Here's the code:

This works fine, but does not use a dynamic array:

// Reads frame from a binary file
task t_Read_File(input string i_File_Name);
  int n_Temp[10][10];
  int n_File_ID;

  n_File_ID = $fopen(i_File_Name, "rb");
  $fread(n_Temp, n_File_ID);
  $fclose(n_File_ID);
  r_Frame = n_Temp;
endtask : t_Read_File

This uses a dynamic array (r_Frame) but does not work

// Reads frame from a binary file
task t_Read_File(input string i_File_Name);
  int n_File_ID;

  n_File_ID = $fopen(i_File_Name, "rb");
  $fread(r_Frame, n_File_ID);
  $fclose(n_File_ID);
endtask : t_Read_File

FYI, r_Frame is declared previously as a local variable to my class as follows:

int r_Frame[][];
Russell
  • 3,384
  • 4
  • 31
  • 45

2 Answers2

1

Using $fread on a dynamic array is an open issue in the standard. It's even more problematic for multi-dimensional dynamic arrays as there is no way to know how to shape the array. To make matters more complicated, SystemVerilog does not really have multi-dimensional array; instead it has arrays of arrays. This means each indexed dimension could have a different size.

You could try allocating the array first, then calling $fread.

r_Frame = new[10];
foreach (r_Frame[i]) r_Frame[i] = new[10];
dave_59
  • 39,096
  • 3
  • 24
  • 63
  • I actually did allocate the array first using new. So r_Frame is properly allocated for the size of the input file specified by fread. – Russell Jan 29 '16 at 15:44
  • You need to clarify what you mean by "does not work". Are you getting an error, or not the results you expect. I know recent versions of Recent versions of Modelsim support $fread as long as you pre-allocate the dynamic array. You may need to contact your tool vendor if you are having problems. Otherwise you will have to do the read on fixed sized chunks and push them into a queue or dynamic array. – dave_59 Jan 29 '16 at 21:19
  • I posted the solution to my question. There was definitely a problem reading into r_Frame, even if I specified the dimensions using `new` prior to using `$fread`. Might be a Modelsim thing. Using a temporary variable fixed it though. Thanks for the help. – Russell Feb 03 '16 at 18:06
0

Here's the solution that I had to end up implementing. Basically I read the text file one line at a time into n_Temp, which was just a large temporary array structure. Then I put it into the multidimensional dynamic array r_Frame one value at a time. Despite previously calling new for r_Frame and setting the dimensions, $fread was not writing the values into r_Frame. I had to go through this extra step using a temporary variable to get it to work. Also I did have to write an endian swap function to convert the little-endian data file to big-endian format.

task t_Read_File(input string i_File_Name);
  int n_Temp[5000]; // arbitrary, large
  int n_File_ID;
  n_File_ID = $fopen(i_File_Name, "rb");
  for (int i=0; i<n_Active_Rows; i++)
    begin
      void'($fread(n_Temp, n_File_ID, , n_Active_Cols));
      for (int j=0; j<n_Active_Cols; j++)
        r_Frame[i][j] = Sim_Support_Pkg::f_Endian_Swap(n_Temp[j]);
    end
  $fclose(n_File_ID);
endtask : t_Read_File
Russell
  • 3,384
  • 4
  • 31
  • 45