Параметр SystemVerilog / Verilator WIDTH и индексирование структуры случая вне границ - PullRequest
0 голосов
/ 21 января 2020

В настоящее время я внедряю PRNG в SystemVerilog, используя LFSR, как описано здесь . Ширина должна быть переменной с использованием параметра. Я достигаю конструкции:

module PRNG
#(
    parameter WIDTH = 32,
    parameter SEED = 1
)
(
    input clk,
    input update,
    output reg [WIDTH-1:0] prng
);

reg [WIDTH-1:0] lastRng = WIDTH'(SEED);

always_comb begin
    var tap;

    case (WIDTH)
        default: tap = 0;
        3: tap = lastRng[2] ^~ lastRng[1];
        [...]
        168: tap = lastRng[167] ^~ lastRng[165] ^~ lastRng[152] ^~ lastRng[150];
    endcase

    if (update) begin
        prng = {lastRng[WIDTH-2:0], tap};
    end else begin
        prng = lastRng;
    end
end

always_ff @(posedge clk) begin
    lastRng <= prng;
end

endmodule

Теперь, моделируя этот модуль с помощью Verilator, он жалуется на то, что индексы выбора выходят за пределы диапазона для каждого случая > WIDTH-1, хотя (я думаю, что) эти случаи явно должны быть оптимизирован, поскольку WIDTH является константой:

Selection index out of range: 167:167 outside 31:0

Есть ли простой способ обойти эту ошибку, например, без. Логика сдвига битов c только для индексации n-го бита?

Ответы [ 2 ]

1 голос
/ 21 января 2020

Вам необходимо реструктурировать свой блок, чтобы у вас не было внешних ссылок. При моделировании компилятору не требуется оптимизировать процедурный код на основе постоянных значений, поэтому он должен быть законным. Перемещение оператора case за пределы блока always меняет его с процедурного на подробный (то же самое для операторов if и for -l oop.

logic tap;// same as var tap, but better to show the implicit data type

case (WIDTH)
    default: assign tap = 0;
    3: assign tap = lastRng[2] ^~ lastRng[1];
    [...]
    168: assign tap = lastRng[167] ^~ lastRng[165] ^~ lastRng[152] ^~ lastRng[150];
endcase

always_comb
if (update)
    prng = {lastRng[WIDTH-2:0], tap};
else 
    prng = lastRng;
1 голос
/ 21 января 2020

Для этого вам нужно использовать generate.

Попробуйте это

  1. Переместить блок оператора case за пределы always_comb (вы не можете использовать generate в блоке always, кто-то поправит меня, если это не означает always_comb
  2. Измените операторы tap = на assign tap =.
  3. (необязательно) Surround блок case с generate / endgenerate. Это не обязательно, но может показаться, что это улучшает читаемость.
...