2017-06-14 89 views
0

我试图用一个初始块赋值给一个只读推断RAM:如何在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回购中讨论问题#50提供了一个示例模块mem2reg_with_two_always_blocks,这表明它应该是。但编译该模块会引发相同的警告消息。

回答

2

我在实验中发现,RAM在上电后的某些时钟周期之前没有得到正确的值。

不幸的是,你不说你是如何做到这一点。我假设你正在使用iCE40综合,并在SRAM编程的硬件中运行它,因为这会匹配已知的iCE40硬件问题。

又见herehere以获取更多信息。

解决办法:不要使用SRAM编程或让你的设计复位几个周期给BRAM初始化一些时间来完成。

的问题,也可以使用莱迪思工具时再现。这是一个硬件错误。合成流程对此无能为力。

你的HDL代码行并使用支持初始化存储器(如iCE40合成或赛灵思7系列合成)的流量时应该产生与初始化内存资源网表。


编辑评论:您可以忽略初始块中的警告阻止与非阻止赋值。在你的情况下,如果分配被解释为阻塞或非阻塞,则没有任何区别。但是,像下面的代码会导致问题:

initial begin 
    mem[0] = 1; 
    mem[1] = mem[0]; 
end 

我想表达的意图是初始化发生在(!或之前)时间步长的开始0

这是任何无论是否使用阻塞或非阻塞赋值,初始块都会执行此操作。

+0

是的,上下文是使用SPI从编程的ICE40(在myStorm板上,这是唯一的选择)。我将通过使用计数器来解决配置后延迟启动的问题。但我仍然不理解关于在非时钟初始块内处理阻塞分配的警告消息。我想表示初始化发生在时间步0开始时(或之前!)。 –

+0

@ R.Miller请参阅编辑。 – CliffordVienna