在英特尔 Quartus 中,我可以使用字符串参数初始化 RAM 吗?
In Intel Quartus, can I initialize RAM using a string parameter?
我需要用不同的数据文件初始化同一个 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
您看到的报告错误是针对 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, section 9.2.2.4 Sequential logic always_ff procedure:
Variables on the left-hand side of assignments within an always_ff
procedure, including variables from the contents of a called function,
shall not be written to by any other process.
错误消失:
always @(posedge clk) begin
除此之外,我没有看到使用传递给不同实例的不同 HEXFILE
值有任何问题。如果您继续看到问题,您可以尝试使用 parameter
而不是 string
:
module ram #(
parameter HEXFILE = "split1.mem"
)
我需要用不同的数据文件初始化同一个 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
您看到的报告错误是针对 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, section 9.2.2.4 Sequential logic always_ff procedure:
Variables on the left-hand side of assignments within an always_ff procedure, including variables from the contents of a called function, shall not be written to by any other process.
错误消失:
always @(posedge clk) begin
除此之外,我没有看到使用传递给不同实例的不同 HEXFILE
值有任何问题。如果您继续看到问题,您可以尝试使用 parameter
而不是 string
:
module ram #(
parameter HEXFILE = "split1.mem"
)