如何在Verilog中初始化推断的块RAM(BRAM)的内容[英] How to initialize contents of inferred Block RAM (BRAM) in Verilog

本文是小编为大家收集整理的关于如何在Verilog中初始化推断的块RAM(BRAM)的内容的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我很难初始化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

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

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

我正在使用Vivado 2015.4编程Kintex XC7K70 FPGA.

推荐答案

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

parameter MEM_INIT_FILE = "";
...
initial begin
  if (MEM_INIT_FILE != "") begin
    $readmemh(MEM_INIT_FILE, ram);
  end
end

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

0001
1234
3FFF
1B34
...

请注意,没有" 0x"前缀,每行代表相邻的地址(或任何分离空格).在上面的示例中,$readmemh将14'h0001将14'h0001放入ram[0],14'h1234中ram[1],14'h3FFF中,ram[2]等等.您还可以使用//或/* */在十六进制文件中包含评论.最后,您可以使用@符号来指定以下数字位于的地址,例如:

@0002
0101
0A0A
...

在上面的文件中,ram[0]和ram[1]将是非初始化的,ram[2]将获得14'h0101.这些都是十六进制文件格式的主要结构,尽管您也可以像其他Verilog数字中一样使用_,x和z,并且在上面位置的部分中可以阅读一些规则.

其他推荐答案

除了 @unn的出色ANS外,我想补充一点,如果您只想用所有位以1'b1或1'b0初始化内存,那么您就可以列出以下代码,

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

对于您的情况,width = 14,mem_init_val可能为1'b1或1'b0.

其他推荐答案

由于您的问题引用了#xilinx和#vivado标签,因此我想建议您还可以使用xpm_memory xpm_memory原始人家族来实例化参数化的内存.这种方法的优点:

  1. 精确导出了FPGA上内存资源的硬件功能(即,让您清楚地考虑限制(例如内存端口).

  2. 保证在模拟和记忆原始台上正确的相同行为.

  3. 您可以根据您的设计约束,允许Vivado在合成时间选择最有效的内存实现(BRAM,Ultraram,分布式RAM,FLOPS).

  4. 易于微调(启用或禁用内部管道阶段等).

话虽如此,纯粹推断的记忆通常更容易编码.但是,仍然值得熟悉Xilinx提供的内存原始图,以便您对Vivado可以轻松合成以及不能更清楚地了解.

有关更多信息,请参见UG573,《 Vivado Memory Resources用户指南:

/support/documentation/user_guides/ug573-ultrascale-memory-resources.pdf

本文地址:https://www.itbaoku.cn/post/2090948.html

问题描述

I am having trouble initializing the contents of an inferred ram in Verilog. The code for the ram is as below:

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

I have run into the command $readmemh. However, documentation for it seems sparse. How should I format the file that contains the data? Also, how can I pass the file as argument when instantiating this module so that I can have different instances of this module load from different files?

I want the initialized content to be available for both simulation and actual implementation. So that the FPGA already boots with this content in RAM.

I am using Vivado 2015.4 to program a Kintex xc7k70 FPGA.

推荐答案

You are correct that you should use $readmemh inside an initial block. In order to make it so different instances of the module can have different initialization files, you should use a parameter like so:

parameter MEM_INIT_FILE = "";
...
initial begin
  if (MEM_INIT_FILE != "") begin
    $readmemh(MEM_INIT_FILE, ram);
  end
end

The format is described in Section 21.4 of the IEEE1800-2012 specification; typically the file is just a bunch of lines containing hex numbers of the correct bit-length, like so:

0001
1234
3FFF
1B34
...

Note that there is no "0x" prefix and each line represents an adjacent address (or any separating whitespace). In the example above, $readmemh would put 14'h0001 into ram[0], 14'h1234 into ram[1], 14'h3FFF into ram[2] and so on. You can also include comments in the hex file using // or /* */. Finally, you can use the @ symbol to designate an address for the following numbers to be located at, like so:

@0002
0101
0A0A
...

In the above file, ram[0] and ram[1] would be uninitialized and ram[2] would get 14'h0101. Those are all the major constructs of the hex file format, though you can also use _, x and z as you would in other Verilog numbers and theres a few more rules you can read in the section sited above.

其他推荐答案

Apart from @Unn's excellent ans, I want to add that, If you just want to initialize your memory with either all bits to 1'b1 or 1'b0, then you can just put following code,

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

For your case, WIDTH=14, and MEM_INIT_VAL may be 1'b1 or 1'b0.

其他推荐答案

Since your question cited the #xilinx and #vivado tags, I wanted to suggest that you can also use the xpm_memory family of primitives to instantiate a parameterized memory. The advantages of this approach:

  1. Exports exactly the hardware capabilities of the memory resources on the FPGA (ie, makes you think clearly about limitations such as memory ports).

  2. Guarantees correct identical behavior in simulation and benchtop for memory primitives.

  3. You can allow Vivado to choose the most efficient memory implementation (BRAM, UltraRAM, distributed RAM, flops) at synthesis time, according to your design constraints.

  4. Easy to fine tune (enable or disable internal pipeline stages, etc.).

With that said, purely inferred memories are often easier to code. But, it's still worth getting familiar with the Xilinx-provided memory primitives so that you'll have a clearer idea of what Vivado can easily synthesize, and what it can't.

For more information, see UG573, the Vivado Memory Resources User Guide:

https://www.xilinx.com/support/documentation/user_guides/ug573-ultrascale-memory-resources.pdf