如何在 Yosys 的初始块中分配 RAM 值?
How to assign RAM values in an initial block in Yosys?
我正在尝试使用初始块将值分配给只读推断 RAM:
module rom (
input clk,
input [5:0] addr,
output reg [15:0] data);
reg [15:0] mem [0:63];
initial begin
mem[0] = 1;
mem[1] = 2;
end
always @(posedge clk)
data <= mem[addr];
endmodule
Yosys 发出此警告消息:
$ yosys -q -p "synth_ice40 -blif rom.blif" rom.v
Warning: Blocking assignment to memory in line rom.v:9 is handled like a non-blocking assignment.
Warning: Blocking assignment to memory in line rom.v:10 is handled like a non-blocking assignment.
如果我忽略警告(或将初始分配更改为非阻塞),我通过实验发现 RAM 在加电后的某些时钟周期之前不会获得正确的值。
难道不能这样使用初始块吗? yosys github repo 中对问题 #50 的讨论提供了一个示例模块 mem2reg_with_two_always_blocks
,这表明它应该是。但是编译该模块会绘制相同的警告消息。
I find experimentally that the RAM doesn't get its correct values until some clock cycles after power-up.
不幸的是你没有说你是怎么做到的。我假设您正在使用 iCE40 综合,并且 运行 它在硬件中使用 SRAM 编程,因为这将匹配已知的 iCE40 硬件问题。
解决方法:不要使用 SRAM 编程或让您的设计再复位几个周期,以便给 BRAM 初始化一些时间来完成。
使用 Lattice 工具时也可以重现该问题。这是一个硬件错误。综合流程对此无能为力。
您的 HDL 代码没问题,当使用支持初始化存储器的流程(例如 iCE40 综合或 Xilinx 7 系列综合)时,应该会生成具有初始化存储器资源的网表。
编辑评论:您可以忽略初始块中的警告 re blocking vs nonblocking assignments。在您的情况下,如果分配被解释为阻塞或非阻塞,则没有任何区别。但是像下面这样的代码会导致问题:
initial begin
mem[0] = 1;
mem[1] = mem[0];
end
I want to express the intention that the initialization happens at (or before!) the beginning of timestep 0.
这就是任何初始块所做的,无论其中使用的是阻塞赋值还是非阻塞赋值。
我正在尝试使用初始块将值分配给只读推断 RAM:
module rom (
input clk,
input [5:0] addr,
output reg [15:0] data);
reg [15:0] mem [0:63];
initial begin
mem[0] = 1;
mem[1] = 2;
end
always @(posedge clk)
data <= mem[addr];
endmodule
Yosys 发出此警告消息:
$ yosys -q -p "synth_ice40 -blif rom.blif" rom.v
Warning: Blocking assignment to memory in line rom.v:9 is handled like a non-blocking assignment.
Warning: Blocking assignment to memory in line rom.v:10 is handled like a non-blocking assignment.
如果我忽略警告(或将初始分配更改为非阻塞),我通过实验发现 RAM 在加电后的某些时钟周期之前不会获得正确的值。
难道不能这样使用初始块吗? yosys github repo 中对问题 #50 的讨论提供了一个示例模块 mem2reg_with_two_always_blocks
,这表明它应该是。但是编译该模块会绘制相同的警告消息。
I find experimentally that the RAM doesn't get its correct values until some clock cycles after power-up.
不幸的是你没有说你是怎么做到的。我假设您正在使用 iCE40 综合,并且 运行 它在硬件中使用 SRAM 编程,因为这将匹配已知的 iCE40 硬件问题。
解决方法:不要使用 SRAM 编程或让您的设计再复位几个周期,以便给 BRAM 初始化一些时间来完成。
使用 Lattice 工具时也可以重现该问题。这是一个硬件错误。综合流程对此无能为力。
您的 HDL 代码没问题,当使用支持初始化存储器的流程(例如 iCE40 综合或 Xilinx 7 系列综合)时,应该会生成具有初始化存储器资源的网表。
编辑评论:您可以忽略初始块中的警告 re blocking vs nonblocking assignments。在您的情况下,如果分配被解释为阻塞或非阻塞,则没有任何区别。但是像下面这样的代码会导致问题:
initial begin
mem[0] = 1;
mem[1] = mem[0];
end
I want to express the intention that the initialization happens at (or before!) the beginning of timestep 0.
这就是任何初始块所做的,无论其中使用的是阻塞赋值还是非阻塞赋值。