Using parameters with a for loop in verilog to select bits

I'm developing some hardware in Verilog, but in an attempt to keep flexibility, I use parameters to set the width so that I can change the width as needed without changing the code. One of the problems I ran into is in the section of the code where I want to be able to write in parallel to multiple cells.

parameter DATA_WIDTH = 16;
parameter BUFFER_SIZE = 16;
parameter LOAD_WIDTH = DATA_WIDTH*BUFFER_SIZE;

input [LOAD_WIDTH-1:0] i_load_data;

reg [DATA_WIDTH-1:0]    r_data_buf[BUFFER_SIZE-1:0];

...

always@(posedge clk) begin
....
    else if (i_load_flag) begin
        for(i = 0; i < BUFFER_SIZE; i = i + 1)
            r_data_buf[i] <= i_load_data[i * BUFFER_SIZE + BUFFER_SIZE - 1:i * BUFFER_SIZE];
    end
end

      

I need to store r_data_buf as an array because of the way the data is read. It is also not clear to me why verilog doesn't like this code, since everything is a constant at compile time or how I can fix it and still get the behavior I want.

+3


source to share


1 answer


The Verilog compiler is unhappy because it sees i_load_data [x: y] where both x and y depend on parameters, so it is concerned that this might cause the width to change (although this is not possible in your case).

There are several easy ways to fix this:



  • Use the +: operator to specify the width. (I also changed BUFFER_SIZE to DATA_WIDTH because it looked like a typo.) In this form, you specify the LSB index and the width of the data you want to select.

    r_data_buf[i] <= i_load_data[i * DATA_WIDTH  +: DATA_WIDTH];
    
          

  • Use an extra cycle for each separate set

    for(i = 0; i < BUFFER_SIZE; i = i + 1)
    begin
        for(j = 0; j < DATA_WIDTH; j = j + 1)
        begin
            r_data_buf[i][j] <= i_load_data[i * DATA_WIDTH  + j];
        end
    end
    
          

+7


source







All Articles