System verilog SystemVerilog/Verilator宽度参数和大小写结构索引超出范围

System verilog SystemVerilog/Verilator宽度参数和大小写结构索引超出范围,system-verilog,verilator,System Verilog,Verilator,我目前正在SystemVerilog中使用LFSR实现PRNG,如前所述。宽度应使用参数进行更改。我得出以下结论: 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 be

我目前正在SystemVerilog中使用LFSR实现PRNG,如前所述。宽度应使用参数进行更改。我得出以下结论:

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

是否有一种简单的方法来解决此错误,而不使用位移位逻辑来索引第n位?

要做到这一点,您需要使用
生成

试试这个

  • 将case语句块移到
    始终梳
    之外(您不能在
    始终梳
    块中使用
    生成
    ,如果这不代表
    始终梳
  • tap=
    语句更改为
    assign tap=
  • (可选)用
    generate
    /
    endgenerate
    环绕
    案例
    块。这不是必需的,但您可能会发现它有助于可读性

  • 为此,您需要使用
    生成

    试试这个

  • 将case语句块移到
    始终梳
    之外(您不能在
    始终梳
    块中使用
    生成
    ,如果这不代表
    始终梳
  • tap=
    语句更改为
    assign tap=
  • (可选)用
    generate
    /
    endgenerate
    环绕
    案例
    块。这不是必需的,但您可能会发现它有助于可读性

  • 您需要重新构造块,这样就不会有越界引用。在模拟中,编译器不需要基于常量值优化程序代码,因此它必须是合法的。将case语句移出
    始终
    块会将其从程序更改为基于细化的(与
    if
    for
    循环语句相同

    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;
    

    您需要重新构造块,这样就不会有越界引用。在模拟中,编译器不需要基于常量值优化程序代码,因此它必须是合法的。将case语句移出
    始终
    块会将其从程序更改为基于细化的(与
    if
    for
    循环语句相同

    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;