我设计了一个 RAM 模块,我需要该模块的多个实例,每个实例都有不同的内存初始化文件。
Quartus手册说Quartus支持
$readmemh()
函数来初始化RAM。所以我在这个模块中添加了两个参数,并将不同的参数传递给每个实例,以指定每个实例将读取哪些文件。
我的下面的代码可以在 Modelsim 中运行,但是在合成时失败。 Quartus崩溃了,我把它去掉后,Quartus合成成功了。
module cell_module
#(
parameter X_ID = "1",
parameter Y_ID = "1",
parameter DIR_ID = {X_ID, "_", Y_ID}
)
...
reg [15:0] Mem_1 [0:31];
reg [15:0] Mem_2 [0:31];
`ifdef SIM_MEM_INIT
initial begin
$readmemh ({"../data", DIR_ID, "/file1.txt"},Mem_1);
$readmemh ({"../data", DIR_ID, "/file2.txt"},Mem_2);
end
`endif
上面的模块在顶层实例化如下:
cell_module #(.X_ID("1"), .Y_ID("1")) cell_module1 (...)
cell_module #(.X_ID("1"), .Y_ID("2")) cell_module2 (...)
cell_module #(.X_ID("2"), .Y_ID("1")) cell_module3 (...)
cell_module #(.X_ID("2"), .Y_ID("2")) cell_module4 (...)
参数指定哪个文件夹包含该单元的初始内存。 该代码在Modelsim中运行,并在Quartus中分析和阐述成功完成。
但是会导致quartus_map在合成时崩溃。我找不到有关此错误消息的任何信息。
如果这是不可能的,是否有任何好的方法可以用不同的内容初始化多个实例的RAM? 谢谢
编辑:
我构建了一个小型 Quartus 项目来测试这是否可以完成。我按照Quartus手册编写了一个标准RAM模块,其中有两个额外的参数来定义初始化内存文件的文件夹。 这是ram的代码,
module mem_init
#(parameter DATA_WIDTH=8, parameter ADDR_WIDTH=6, parameter X_ID = "1", Y_ID = "1", DIR_ID = {X_ID,"_", Y_ID})
(input [(DATA_WIDTH-1):0] data,
input [(ADDR_WIDTH-1):0] addr,
input we, clk,
output [(DATA_WIDTH-1):0] q);
reg [DATA_WIDTH-1:0] ram[2**ADDR_WIDTH-1:0];
reg [ADDR_WIDTH-1:0] addr_reg;
initial
begin : INIT
$readmemh ("../data", DIR_ID, "/file.txt", ram);
end
always @ (posedge clk)
begin
if (we)
ram[addr] <= data;
addr_reg <= addr;
end
assign q = ram[addr_reg];
endmodule
及其初始化:
mem_init #(.DATA_WIDTH(DATA_WIDTH), .ADDR_WIDTH(ADDR_WIDTH), .X_ID("1"), .Y_ID("1"))
mem1 (.data(data1), .addr(add1), .we(we), .clk(clk), .q(q1));
mem_init #(.DATA_WIDTH(DATA_WIDTH), .ADDR_WIDTH(ADDR_WIDTH), .X_ID("1"), .Y_ID("2"))
mem2 ( .data(data2),.addr(add2),.we(we), .clk(clk), .q(q2));
这在仿真中有效,Quartus 成功综合了该设计。
IEEE-1800 综合标准不支持“初始块”。
如果 Altera/Intel 让您摆脱这一点,那么就分层引用而言,这个问题也可能对您有所帮助:
这个问题似乎仍然悬而未决。您是否尝试使用文件名作为参数?以你为例:
module cell_module
#(
parameter INIT_FILE_NAME = "blah"
)
...
reg [15:0] mem [0:31];
`ifdef SIM_MEM_INIT
initial begin
$readmemh (INIT_FILE_NAME,mem);
end
`endif
并实例化记忆:
cell_module #(.INIT_FILE_NAME("../data_1_1_file.txt")) cell_module1 (...)
cell_module #(.INIT_FILE_NAME("../data_1_2_file.txt")) cell_module2 (...)
cell_module #(.INIT_FILE_NAME("../data_2_1_file.txt")) cell_module3 (...)
cell_module #(.INIT_FILE_NAME("../data_2_2_file.txt")) cell_module4 (...)
我认为你的代码的问题在于你如何连接参数来创建
DIR_ID
。
您可以实现重置信号:
always (posedge clock or posedge reset)
begin
if(reset==0)
begin
$readmemh ("../data", DIR_ID, "/file.txt", ram);
end
end
它会对你有帮助;我认为。 再次检查 Verilog 中可综合的内容。