如何在Verilog中初始化推断的Block RAM(BRAM)的内容

Pau*_*ulo 8 verilog fpga xilinx vivado

我无法在Verilog中初始化推断的ram的内容.ram的代码如下:

module ram(
        input clock, // System clock
        input we, // When high RAM sets data in input lines to given address
        input [13:0] data_in, // Data lines to write to memory
        input [10:0] addr_in, // Address lines for saving data to memory
        input [10:0] addr_out, // Address for reading from ram
        output reg data_out // Data out
);

reg [13:0] ram[2047:0];

// Initialize RAM from file
// WHAT SHOULD GO HERE?

always @(posedge clock) begin
    // Save data to RAM
    if (we) begin
        ram[addr_in] <= data_in;
    end

    // Place data from RAM
    data_out <= ram[addr_out];
end        
endmodule
Run Code Online (Sandbox Code Playgroud)

我遇到了命令$ readmemh.但是,它的文档似乎很少.我应该如何格式化包含数据的文件?另外,如何在实例化此模块时将文件作为参数传递,以便我可以从不同的文件中加载此模块的不同实例?

我希望初始化的内容可用于模拟和实际实现.因此FPGA已经在RAM中使用此内容启动了.

我正在使用Vivado 2015.4来编写Kintex xc7k70 FPGA.

Unn*_*Unn 8

你应该$readmemh在初始块内使用是正确的.为了使模块的不同实例具有不同的初始化文件,您应该使用如下参数:

parameter MEM_INIT_FILE = "";
...
initial begin
  if (MEM_INIT_FILE != "") begin
    $readmemh(MEM_INIT_FILE, ram);
  end
end
Run Code Online (Sandbox Code Playgroud)

该格式在IEEE1800-2012规范的第21.4节中描述; 通常文件只是一串包含正确位长的十六进制数的行,如下所示:

0001
1234
3FFF
1B34
...
Run Code Online (Sandbox Code Playgroud)

请注意,没有"0x"前缀,每行代表一个相邻的地址(或任何分隔的空格).在上面的例子中,$readmemh会放14'h0001ram[0],14'h1234ram[1],14'h3FFFram[2]等.您还可以使用//或在hex文件中包含注释/* */.最后,您可以使用该@符号来指定以下数字的地址,如下所示:

@0002
0101
0A0A
...
Run Code Online (Sandbox Code Playgroud)

在上面的文件中,ram[0]并且ram[1]将是未初始化的并且ram[2]会得到14'h0101.这些都是十六进制文件格式的所有主要结构,虽然你也可以使用_,x而且z,你会在其他的Verilog数量和那里有你可以在上面选址的部分读了几多个规则.


Pra*_*rji 6

除了@Unn 的出色回答之外,我想补充一点,如果您只想使用所有位 to1'b1或来初始化内存1'b0,那么您可以输入以下代码,

integer j;
initial 
  for(j = 0; j < DEPTH; j = j+1) 
    ram[j] = {WIDTH{MEM_INIT_VAL}};
Run Code Online (Sandbox Code Playgroud)

对于您的情况,WIDTH=14,并且 MEM_INIT_VAL 可能是1'b11'b0