K
Kevin Neilson
Guest
I've discovered that Synplify no longer requires the use of $readmemh / $readmemb to initialize inferred blockRAMs or ROMs. I thought I'd post some examples of this for my own future reference. You can now use the SystemVerilog-style array initialization. You can do this directly, or by using a multimensional parameter set in a package file. (Don't forget to check the 'SystemVerilog' option box in Synplify.) You can also initialize a RAM/ROM using a function you define in a generate loop. (You have to use a generate loop because an 'initial' loop is ignored by Synplify.) You could use this, for example, to create a sine/cos lookup table. A few examples below.
/*****************************************************************
* Inferred ROM Initialization Using SysVerilog Array Init
*****************************************************************/
module rom0 (input clk, input [5:0] addr, output [9:0] dout);
reg [7:0] rom [0:63] = '{ 1, 3, 5, 7, 9,11,13,15, // init values
0, 2, 4, 6, 8,10,12,14,
3, 6, 9,12,15,18,21,24,
1, 3, 5, 7, 9,11,13,15,
0, 2, 4, 6, 8,10,12,14,
3, 6, 9,12,15,18,21,24,
1, 3, 5, 7, 9,11,13,15,
0, 2, 4, 6, 8,10,12,14};
reg [7:0] raddr;
always@(posedge clk) raddr <= addr; // blockROM must have reg. addr
assign dout = rom[raddr];
endmodule
/*****************************************************************
* Inferred ROM Initialization Using Array Init (Alternate Syntax)
*****************************************************************/
module rom1 (input clk, input [5:0] addr, output [9:0] dout);
reg [7:0] rom [0:63] = '{0:8'h55, 3:8'haa, 13:8'hab, default:0};
reg [7:0] raddr;
always@(posedge clk) raddr <= addr; // blockROM must have reg. addr
assign dout = rom[raddr];
endmodule
/*****************************************************************
* Inferred ROM Initialization Using Loop
*****************************************************************/
module rom2 (input clk, input [5:0] addr, output [9:0] dout);
// Create initialization array using a generate statement
// (You can't use an 'initial' loop because Synplify ingores those)
logic [7:0] init_array [0:63];
generate
for (genvar i=0; i<64; i++)
assign init_array = i**2; // arbitrary function
endgenerate
reg [7:0] rom [0:63] = init_array; // Infer ROM
reg [7:0] raddr;
always@(posedge clk) raddr <= addr; // blockROM must have reg. addr
assign dout = rom[raddr];
endmodule
/*****************************************************************
* Inferred ROM Initialization Using SysVerilog Array Init
*****************************************************************/
module rom0 (input clk, input [5:0] addr, output [9:0] dout);
reg [7:0] rom [0:63] = '{ 1, 3, 5, 7, 9,11,13,15, // init values
0, 2, 4, 6, 8,10,12,14,
3, 6, 9,12,15,18,21,24,
1, 3, 5, 7, 9,11,13,15,
0, 2, 4, 6, 8,10,12,14,
3, 6, 9,12,15,18,21,24,
1, 3, 5, 7, 9,11,13,15,
0, 2, 4, 6, 8,10,12,14};
reg [7:0] raddr;
always@(posedge clk) raddr <= addr; // blockROM must have reg. addr
assign dout = rom[raddr];
endmodule
/*****************************************************************
* Inferred ROM Initialization Using Array Init (Alternate Syntax)
*****************************************************************/
module rom1 (input clk, input [5:0] addr, output [9:0] dout);
reg [7:0] rom [0:63] = '{0:8'h55, 3:8'haa, 13:8'hab, default:0};
reg [7:0] raddr;
always@(posedge clk) raddr <= addr; // blockROM must have reg. addr
assign dout = rom[raddr];
endmodule
/*****************************************************************
* Inferred ROM Initialization Using Loop
*****************************************************************/
module rom2 (input clk, input [5:0] addr, output [9:0] dout);
// Create initialization array using a generate statement
// (You can't use an 'initial' loop because Synplify ingores those)
logic [7:0] init_array [0:63];
generate
for (genvar i=0; i<64; i++)
assign init_array = i**2; // arbitrary function
endgenerate
reg [7:0] rom [0:63] = init_array; // Infer ROM
reg [7:0] raddr;
always@(posedge clk) raddr <= addr; // blockROM must have reg. addr
assign dout = rom[raddr];
endmodule