9

我在 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 进行编程。

4

4 回答 4

11

您应该$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将 put 14'h0001into ram[0], 14'h1234into ram[1], 14'h3FFFintoram[2]等等。您还可以使用//或在十六进制文件中包含注释/* */。最后,您可以使用该@符号为以下数字指定一个地址,如下所示:

@0002
0101
0A0A
...

在上面的文件中,ram[0]andram[1]将未初始化并ram[2]会得到14'h0101. 这些是 hex 文件格式的所有主要结构,尽管您也可以使用_,xz其他 Verilog 数字一样,您可以在上面的部分阅读更多规则。

于 2016-04-14T03:16:00.400 回答
5

除了@Unn 的优秀答案之外,我想补充一点,如果您只想将所有位初始化为1'b1or的内存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'b11'b0

于 2016-04-14T04:24:32.840 回答
0

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

  1. 准确导出 FPGA 上内存资源的硬件功能(即让您清楚地考虑内存端口等限制)。

  2. 保证内存原语在仿真和台式机中的正确相同行为。

  3. 您可以允许 Vivado 在综合时根据您的设计约束选择最高效的内存实现(BRAM、UltraRAM、分布式 RAM、触发器)。

  4. 易于微调(启用或禁用内部流水线阶段等)。

话虽如此,纯粹推断的记忆通常更容易编码。但是,熟悉 Xilinx 提供的内存原语仍然值得,这样您就可以更清楚地了解 Vivado 可以轻松合成什么,以及它不能合成什么。

如需更多信息,请参阅 UG573,Vivado 内存资源用户指南:

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

于 2020-09-13T23:44:06.237 回答
-3
integer j;
initial 
  for(j = 0; j < DEPTH; j = j+1) 
    ram[j] = j;

这在调试的情况下可能很容易,其中位置的值是它的位置编号。

另外,我建议您不要初始化 RAM。它将帮助您在模拟中捕获错误(如果有),因为如果 RAM 未初始化并且可以轻松捕获,则数据驱动将是 'x。

于 2016-04-14T16:30:01.607 回答