我试图使用初始块为只读推断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];
endmoduleYosys给出了这个警告信息:
$ 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回购中对问题50的讨论提供了一个示例模块mem2reg_with_two_always_blocks,它建议它应该是。但编译该模块会发出相同的警告消息。
发布于 2017-06-14 10:39:56
我在实验中发现,在断电后的某些时钟周期内,RAM无法得到正确的值。
不幸的是,你没有说你是怎么做到的。我假设您使用的是iCE40综合,并使用SRAM编程在硬件中运行它,因为这将与已知的iCE40硬件问题相匹配。
有关更多信息,请参见这里和这里。
解决办法:不要使用SRAM编程,也不要让您的设计重新设置几个周期,以便给BRAM初始化一些时间来完成。
在使用格子工具时也可以再现这个问题。这是个硬件缺陷。合成流程对此无能为力。
您的HDL代码是可以的,当使用支持初始化内存的流(如iCE40合成或Xilinx 7系列合成)时,应该生成具有初始化内存资源的netlists。
编辑重新注释:您可以忽略警告、重新阻塞和初始块中的非阻塞分配。在您的情况下,如果任务被解释为阻塞或非阻塞,则没有任何区别。但是,像下面这样的代码会导致问题:
initial begin
mem[0] = 1;
mem[1] = mem[0];
end我想表达一下初始化发生在(或之前)的意图!时间步骤0的开始。
这是任何初始块所做的事情,不管是否在其中使用阻塞或非阻塞赋值。
https://stackoverflow.com/questions/44540359
复制相似问题