我正在尝试使用初始块将值分配给只读的推断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
,表明它应该是。 "user_data_file": "/root/packer_userdata.sh",
。但是编译该模块会产生相同的警告信息。
答案 0 :(得分:3)
我通过实验发现RAM在上电后的某个时钟周期之前没有得到正确的值。
不幸的是,你没有说你是怎么做到的。我假设您正在使用iCE40综合并在硬件中运行SRAM编程,因为这将与已知的iCE40硬件问题相匹配。
解决方法:不要使用SRAM编程或将设计重置几个周期,以便BRAM初始化一段时间才能完成。
使用莱迪思工具时也可以重现此问题。这是一个硬件错误。合成流程无法对此做任何事情。
您的HDL代码没问题,在使用支持初始化存储器的流程(例如iCE40综合或Xilinx 7系列合成)时,应该产生具有初始化存储器资源的网表。
编辑重新评论:您可以忽略初始块中的警告重新阻止与非阻止分配。在您的情况下,如果分配被解释为阻塞或非阻塞,则没有任何区别。但是像下面这样的代码会导致问题:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="10dp"
android:shape="rectangle" >
<solid android:color="#9294a3" />
<stroke
android:width="2dp"
android:color="#c2bbbb" />
<corners android:radius="2dp" />
我想表达初始化发生在时间步长0开始时(或之前!)的意图。
这是任何初始块的作用,无论是否使用了阻塞或非阻塞分配。