I need to initialize several instances of the same ram module with different data files which I would like to do as follows:
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
And in my top level entity, initialize these as follows:
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 ...
But when I try to do this, I get the following error:
Error (10686): SystemVerilog error at ram.sv(18): HEXFILE has an aggregate value
It works fine if I use a string literal for the file name:
initial $readmemh("split1.mem", mem)
Any ideas on how I can achieve this without creating copies of the same file just to change the input file?
EDIT: I think Verilog treats parameters and string literals differently. It's treating string
as an extension of logic
which is why it's saying it needs to be extended.
I don't know how to define it as a string literal. The following seems to be working but it's a terrible terrible way in my opinion:
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