Использование параметров с циклом for в verilog для выбора бита

Я проектирую некоторое оборудование в Verilog, но, чтобы сохранить гибкость, я использую параметры для установки ширины, чтобы я мог изменять ширину по мере необходимости без изменения кода. Одна проблема, с которой я столкнулся, заключается в разделе кода, где я хочу иметь возможность выполнять параллельную запись в несколько ячеек.

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

Мне нужно сохранить r_data_buf как массив из-за способа чтения данных. Мне также непонятно, почему verilog не нравится этот код, поскольку все является константой во время компиляции, или как я могу это исправить и при этом получить желаемое поведение.


person ras2124    schedule 10.04.2012    source источник
comment
Вероятно, было бы полезно, если бы вы могли сказать, что не нравится verilog (сообщения об ошибках?, сбой синтеза?, сбой симуляции?), но, основываясь только на предположении, я думаю, что большинство синтезаторов реализовали бы такой массив как массив оперативной памяти или защелки. , и вы, как правило, не сможете написать несколько местоположений одновременно. (В ОЗУ идет только одна шина адреса/данных, поэтому вы не можете втиснуть в нее две записи в одном и том же цикле).   -  person Tim    schedule 10.04.2012


Ответы (1)


Компилятор Verilog недоволен, потому что он видит i_load_data[x:y], где и x, и y зависят от параметров, поэтому он обеспокоен тем, что это может привести к изменению ширины (хотя в вашем случае это невозможно).

Есть несколько простых способов это исправить:

  1. Используйте оператор +:, чтобы указать ширину. (Я также изменил BUFFER_SIZE на DATA_WIDTH, потому что это выглядело как опечатка.) В этой форме вы указываете индекс LSB и ширину данных, которые хотите выбрать.

    r_data_buf[i] <= i_load_data[i * DATA_WIDTH  +: DATA_WIDTH];
    
  2. Используйте дополнительный цикл for для установки каждого бита по отдельности

    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
    
person Peter de Rivaz    schedule 10.04.2012
comment
1 полностью решил мою проблему. Я никогда не видел такого синтаксиса, но он определенно полезен. Кроме того, да, это была опечатка. - person ras2124; 10.04.2012
comment
Рад помочь :) Вас также может заинтересовать аналогичный оператор -:, в котором вместо этого вы указываете индекс старшего бита и ширину данных. В этом случае это не так хорошо, потому что вы должны написать что-то вроде i_load_data[i * DATA_WIDTH + DATA_WIDTH-1 -: DATA_WIDTH] - person Peter de Rivaz; 11.04.2012