when I intialize block RAM and I want to use block RAM in a FOR I faced with this invalid memory name?

Status
Not open for further replies.

stackprogramer

Full Member level 3
Joined
Jul 22, 2015
Messages
181
Helped
0
Reputation
0
Reaction score
1
Trophy points
1,298
Activity points
2,669
when I initialize block RAM and I want to use block RAM in a FOR I am faced with this invalid memory name.
When I don't use RAM block array in For loop I have not any warning and readmemh works correctly...
WARNING: [Synth 8-2898] ignoring malformed $readmem task: invalid memory name [file.sv:50]
WARNING: [Synth 8-2898] ignoring malformed $readmem task: invalid memory name [file.sv:51]

Code:
module multiplier_core
  #(parameter WIDTH=64)
   (input clk, input reset,input [31:0] reg_user,
    input [32-1:0] config_tdata, input config_tlast, input config_tvalid, output config_tready,
    output [63:0] o_tdata, output o_tlast, output o_tvalid, input o_tready);

     reg signed [15:0] data_samples_i_buffer [1024:0];
     reg signed [15:0] data_samples_q_buffer [1024:0];

     reg [31:0] edgei_tbl_rom[0:1024];
     reg [31:0] edgeq_tbl_rom[0:1024];



     initial begin
          //Initial 

            $readmemh("/home/sp/rfnoc-test/rfnoc/fpga/rfnoc_block_multiplier/1.hex",edgei_tbl_rom,0,1024);
            $readmemh("/home/sp/rfnoc-test/rfnoc/fpga/rfnoc_block_multiplier/1.hex",edgeq_tbl_rom,0,1024);
    ebd


     always @(posedge config_tvalid ) begin
        if(state==1)
        begin
           $display("-------Clock is triggerted...%0d ----",m);

            //Save samples in samples buffer 
            data_samples_i_buffer[m]=config_tdata[15:0];
            data_samples_q_buffer[m]=config_tdata[31:16];

            $display("Sample %0d = %0d +i %0d",m,data_samples_i_buffer[m],data_samples_q_buffer[m]);


            if(m==1024) begin

              m=0;

            end else begin

              m=m+1;

            end
              // temp_i_mult_result_sum= edge_tbl_rom[j];
            for(j=0; j<1000; j=j+1)
                begin

              temp_i_mult_result_sum= edgei_tbl_rom[j];//(temp_i_mult_result_sum+data_samples_i_buffer[j]*edgei_tbl_rom[j]+data_samples_q_buffer[j]*edgeq_tbl_rom[j]);



                end



               // energy_factor=reg_user;//65536*20;
                multiplier_tdata=temp_i_mult_result_sum;
          temp_i_mult_result_sum=0;

        end
        else begin


        end


  end
        assign o_tdata = { 32'h00000000, multiplier_tdata};
        assign o_tlast = config_tlast;
        assign o_tvalid = config_tvalid;
        assign config_tready = o_tready;
endmodule
 

Please review the explanation about "malformed $readmemh task" in your previous thread.

O.K., "ignoring malformed" seems to refer to a different problem https://support.xilinx.com/s/article/62935?language=en_US
In my words, you are using the memory in a way, that no block ram can be inferred.

Block ram can be only accessed one memory address per clock cycle. In your code you are reading the whole ram in one cycle, this prevents generation ("inference") of block ram and makes $readmemh fail.
 

When I remove the for and I write this section instead for now it works...I don't think in the Reg array I have a limit in a clock......but
when I used even for i=1 or 2 I was faced with previous errors.
my question why when I used for with readmemh it doesn't work correctly? can any one guide me?
Code:
temp_i_mult_result_sum= edge_tbl_rom[j]+edge_tbl_rom[j+100];
           temp_i_mult_result_sum= edge_tbl_rom[j+1]+edge_tbl_rom[j+5]+edge_tbl_rom[j+7]+edge_tbl_rom[j+8];
Code:
module multiplier_core
  #(parameter WIDTH=64)
   (input clk, input reset,input [31:0] reg_user,
    input [32-1:0] config_tdata, input config_tlast, input config_tvalid, output config_tready,
    output [63:0] o_tdata, output o_tlast, output o_tvalid, input o_tready);

     reg signed [15:0] data_samples_i_buffer [1024:0];
     reg signed [15:0] data_samples_q_buffer [1024:0];

     reg [31:0] edgei_tbl_rom[0:1024];
     reg [31:0] edgeq_tbl_rom[0:1024];



     initial begin
          //Initial 

            $readmemh("/home/sp/rfnoc-test/rfnoc/fpga/rfnoc_block_multiplier/1.hex",edgei_tbl_rom,0,1024);
            $readmemh("/home/sp/rfnoc-test/rfnoc/fpga/rfnoc_block_multiplier/1.hex",edgeq_tbl_rom,0,1024);
    ebd


     always @(posedge config_tvalid ) begin
        if(state==1)
        begin
           $display("-------Clock is triggerted...%0d ----",m);

            //Save samples in samples buffer 
            data_samples_i_buffer[m]=config_tdata[15:0];
            data_samples_q_buffer[m]=config_tdata[31:16];

            $display("Sample %0d = %0d +i %0d",m,data_samples_i_buffer[m],data_samples_q_buffer[m]);


            if(m==1024) begin

              m=0;

            end else begin

              m=m+1;

            end
            
temp_i_mult_result_sum= edge_tbl_rom[j]+edge_tbl_rom[j+100];
           temp_i_mult_result_sum= edge_tbl_rom[j+1]+edge_tbl_rom[j+5]+edge_tbl_rom[j+7]+edge_tbl_rom[j+8];



               // energy_factor=reg_user;//65536*20;
                multiplier_tdata=temp_i_mult_result_sum;
          temp_i_mult_result_sum=0;

        end
        else begin


        end


  end
        assign o_tdata = { 32'h00000000, multiplier_tdata};
        assign o_tlast = config_tlast;
        assign o_tvalid = config_tvalid;
        assign config_tready = o_tready;
endmodule
 

Read about RAM inference capabilities and coding template in Vivado Design Suite User Guide https://docs.xilinx.com/r/en-US/ug901-vivado-synthesis/RAM-HDL-Coding-Techniques

A code as quoted above
Code:
reg [31:0] edge_tbl_rom[0:1024];
  temp_i_mult_result_sum= edge_tbl_rom[j+1]+edge_tbl_rom[j+5]+edge_tbl_rom[j+7]+edge_tbl_rom[j+8];
blocks RAM inference. edge_tbl_rom can be only implemented in core logic. Besides large resource requirements (30k registers respectively large amount of combinational logic) this also seems to prevent usage of $readmemh system task, thus your table isn't initialized as expected. Unfortunately Xilinx doesn't manage to give clearly understandable warning about it, but the quoted support article suggests that the "malformed" warning comes in this cases.

The RAM/ROM can be still initialized in HDL code (generated constants, case construct, whatsoever). If the table is representing a mathematical function, e.g. trigonometric, you can calculate it in HDL without using external tools.
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…