【问题标题】:In Intel Quartus, can I initialize RAM using a string parameter?在 Intel Quartus 中,我可以使用字符串参数初始化 RAM 吗?
【发布时间】:2022-01-10 07:50:14
【问题描述】:

我需要用不同的数据文件初始化同一个 ram 模块的几个实例,我想这样做如下:

module ram #(
  string HEXFILE = "split1.mem"
)
(
  input  logic        clk,
  input  logic [31:0] a,
  input  logic [7:0]  wd,
  input  logic        we,
  output logic [7:0]  rd
);

logic [7:0] mem [3071:0];
integer fd;


initial $readmemh(HEXFILE, mem);

always_ff @(posedge clk) begin
  if (we) mem[a] <= wd;
  rd <= mem[a];
end

endmodule

在我的顶级实体中,将它们初始化如下:

ram #(
  .HEXFILE("split1.mem")
) M0 (
  .clk(clk),
  .a(a0),
  .wd(wd0),
  .we(we),
  .rd(rd0)
);

ram #(
  .HEXFILE("split2.mem")
) M1 (
  .clk(clk),
  .a(a1),
  .wd(wd1),
  .we(we),
  .rd(rd1)
);

// And so on ...

但是当我尝试这样做时,我收到以下错误:

Error (10686): SystemVerilog error at ram.sv(18): HEXFILE has an aggregate value

如果我对文件名使用字符串文字,它可以正常工作:

initial $readmemh("split1.mem", mem)

关于如何在不创建相同文件的副本来更改输入文件的情况下实现这一点的任何想法?

编辑:我认为 Verilog 以不同的方式处理参数和字符串文字。它将string 视为logic 的扩展,这就是它说它需要扩展的原因。

我不知道如何将其定义为字符串文字。以下似乎有效,但在我看来这是一种可怕的可怕方式:

generate
if      (HEXFILE == "split1.mem") initial $readmemh("split1.mem", mem);
else if (HEXFILE == "split2.mem") initial $readmemh("split2.mem", mem);
else if (HEXFILE == "split3.mem") initial $readmemh("split3.mem", mem);
else if (HEXFILE == "split4.mem") initial $readmemh("split4.mem", mem);
endgenerate

【问题讨论】:

    标签: verilog system-verilog fpga quartus intel-fpga


    【解决方案1】:

    您看到的报告错误是ram 模块中的第18 行,也就是这一行:

    always_ff @(posedge clk) begin
    

    当我在不同的模拟器上运行时,我看不到确切的错误消息,但使用 Synopsys VCS,我看到了:

    Error-[ICPD] Illegal combination of drivers
    ram.sv, 12
      Illegal combination of procedural drivers
      Variable "mem" is driven by an invalid combination of procedural drivers. 
      Variables written on left-hand of "always_ff" cannot be written to by any 
      other processes, including other "always_ff" processes.
      This variable is declared at "ram.sv", 12: logic [7:0] mem[3071:0];
      The first driver is at "ram.sv", 16: $readmemh(HEXFILE, mem);
      The second driver is at "ram.sv", 18: always_ff @(posedge clk) begin
      if (we) begin
       ...
    

    请参阅 IEEE Std 1800-2017,第 9.2.2.4 节 S顺序逻辑 always_ff 过程

    always_ff 内赋值左侧的变量 过程,包括来自被调用函数内容的变量, 不应由任何其他进程写入。

    错误消失了:

    always @(posedge clk) begin
    

    除此之外,我认为使用传递给不同实例的不同 HEXFILE 值没有任何问题。如果您仍然看到问题,您可以尝试使用parameter 而不是string

    module ram #(
      parameter HEXFILE = "split1.mem"
    )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-02
      • 2010-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-10
      • 1970-01-01
      • 2012-03-19
      相关资源
      最近更新 更多