我目前正在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现在,在使用Verilator模拟这个模块时,它抱怨每个情况> WIDTH-1的选择索引都超出了范围,尽管(我认为)这些情况显然应该优化,因为宽度是一个常数:
Selection index out of range: 167:167 outside 31:0有什么简单的方法可以避免这个错误吗?位移位逻辑只是为了索引第n位?
发布于 2020-01-21 12:11:41
要做到这一点,您需要使用generate。
尝尝这个
always_comb (不能在always块中使用always,如果这不代表always_comb,则有人纠正我)tap =语句更改为assign tap =。generate/endgenerate包围generate块。这不是必需的,但您可能会发现它有助于可读性。发布于 2020-01-21 16:32:36
你需要重组你的块,这样你就不会有超出限制的引用。在模拟中,编译器不需要基于常量值来优化过程代码,因此它需要合法。将case语句移出always块将其从过程化更改为基于精化( if和for-loop语句也是如此)。
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;https://stackoverflow.com/questions/59839264
复制相似问题