Reading file into dynamic array failed

hello everyone! i tried to initialize dynamic array with data, read from file, but no data was loaded into it. My code looks like this:

int file_id;
bit [7:0] video_data [0:BYTES_PER_WORD*(IMAGE_SIZE_XIMAGE_SIZE_Y)-1];
bit [7:0] data_array [];
bit a;
file_id = $fopen(“$NAK_DIR/clouds/000000000.raw”, “rb”);
data_array = new[BYTES_PER_WORD
(IMAGE_SIZE_X*IMAGE_SIZE_Y)];
a = $fread(data_array, file_id);
a = $fread(video_data, file_id);
$fclose(file_id);

after executing these lines, “data_array” stores zeroes, and “video_data” (fixed-size array) stores valid data. Bit “a” stores zero both after first and second attempt to read data from file. Both arrays have the same size.
What am i doing wrong?

You need to call $rewind inbetween the two calls to $fread.

In reply to dave_59:

that could the answer, but “data_array” calls $fread first, and still, it is “data_array”, what stores zeroes, and “video_data” stores true values, read from file (still, it calls $fread second). However, i tried to do, what you recommended, now my code is:


$frewind(file_id);
a = $fread(data_array, file_id);
$frewind(file_id);
a = $fread(video_data, file_id);

but nothing changed. “data_array” still stores zeroes.

In reply to trogers:

You may want to contact your tool vendor directly for support. It looks like the $fread to a dynamic memory has no effect.

In reply to trogers:

Hi this is a description on how to read from binary files. I have posted, this in another thread but i think here makes also sense. I hope it helps.

Below the example for reading from a binary file with systemverilog.

As shown in IEEE SV Standard documentation, the “nchar_code” will return the number of bytes/chars read. In case EOF have been already reached on last read this number will be zero.

You can control the number of bytes to be read with the $fread function call (“nchar_code”). This is done with the type definition of the “data_write_temp”. If the “data_write_temp” variable is 16bits long then it will read 16bits each time the $fread is called. In case, “data_write_temp” is 32bits as in the example, the $fread will read nchar_code=4bytes(32bits). You can also define an array and the $fread function will try to fill that array.

Lets define a multidimensional array mem.

     logic [31:0] mem [0:2][0:4][5:8];

In the example word contents, wzyx,

    -w shows the start of the word
    -z corresponds to words of the [0:2] dimension (3 blocks).
    -y corresponds to words of the [0:4] dimension (5 rows).
    -x corresponds to words of the [5:8] dimension (4 columns).

The file will be structure as below (notice @z shows the z dimension blocks):

    @0 w005 w006 w007 w008
       w015 w016 w017 w018
       w025 w026 w027 w028
       w035 w036 w037 w038
       w045 w046 w047 w048
    @1 w105 w106 w107 w108
       w115 w116 w117 w118
       w125 w126 w127 w128
       w135 w136 w137 w138
       w145 w146 w147 w148
    @2 w205 w206 w207 w208
       w215 w216 w217 w218
       w225 w226 w227 w228
       w235 w236 w237 w238
       w245 w246 w247 w248

In the previous structure, the numbers shows the index of each dimension.
e.g. w048 means, the word w (32bits) value on index z =0, index y= 4 and index x= 8.

Now, you have many ways to read this.
You can read all in a single shot using the type “mem” declared above, or you can do a while loop until EOF reading pieces of 32bits using a “data_write_temp” variable of 32bits. The loop is interesting if you want to do something some checks for every word piece and you are not interested having a memory value.

In case multidimensional array / single shot read is chosen, then you can either use $fread or use an specific function $readmemh defined in SV standard.

$readmemh("mem.data", mem, 1, (3*5*4));

is equivalent to

$readmemh("mem.data", mem);

The $readmemh spare you the need to open/close the file.

If you use $fread for one shot read


logic [31:0]          mem [0:2][0:4][5:8];
      register_init_id      = $fopen("mem.data","rb");                 
      nchar_code = $fread(mem, register_init_id);   
      if (nchar_code!=(3*5*4)*4)) begin 
      `uvm_error("do_read_file", $sformatf("Was not possible to read the whole expected bytes")); 
      end    
      $fclose(register_init_id);

In case you wanted to do a loop using 32b word read. Then see the following example.

The example uses the data which is read from the file to write to AHB Bus using an AHB Verification Component.


        logic [31:0] data_write_temp;
        ...
        //DO REGISTER FILE
        register_init_id      = $fopen("../../software/binary.bin","rb");
        if (register_init_id==0) begin `uvm_error("do_read_file", $sformatf("Was not possible to open the register_init_id file")); end 
        count_32b_words=0;
        while(!$feof(register_init_id)) begin            
            nchar_code = $fread(data_write_temp, register_init_id);
            if ((nchar_code!=4)||(nchar_code==0)) begin
                if (nchar_code!=0) begin
                    `uvm_error("do_read_file", $sformatf("Was not possible to read from file a whole 4bytes word:%0d",nchar_code));
                end
            end else begin
                tmp_ahb_address = (pnio_pkg::conf_ahb_register_init_file_part1 + 4*count_32b_words);        
                data_write_temp = (data_write_temp << 8*( (tmp_ahb_address)%(DATAWIDTH/(8))));//bit shift if necessary not aligned to 4 bytes        
                `uvm_create_on(m_ahb_xfer,p_sequencer.ahb0_seqr);                         
                assert(m_ahb_xfer.randomize(* solvefaildebug *) with {                                       
                        write  == 1;//perform a write
                        HADDR  == tmp_ahb_address;
                        HSIZE  == SIZE_32_BIT;
                        HBURST == HBURST_SINGLE;
                        HXDATA.size() == 1; //only one data for single bust
                        HXDATA[0]  == data_write_temp;
                    }) else $fatal (0, "Randomization failed");                //end assert   
                `uvm_send(m_ahb_xfer);                  
                count_32b_words++;
            end //end if there is a word read
        end //end while    
        $fclose(register_init_id);