Forum Discussion
Altera_Forum
Honored Contributor
9 years agoPut the desired verilog ram template inside a module, and instantiate the module where you need a ram inferred. Parameterizze the module definition to select the desired width and depth. By doing this you should always be able to get Quartus to generate actual SRAM blocks vs separate LABs.
For example, I use the following for a dualport memory implementation, and then just instantiate a new instance of dualport () when needed.module dualport
# (
// external parameters
parameter TPD = 0, // simulation delay
parameter DATA = 32, // data bit width
parameter ADDRESS = 5, // number of address bits
parameter MODE = "NEW" // on read/write collision, data output
)
(
// port definitions
input wire clk, // master clock
input wire addr_a, // port A address input
input wire wren_a, // port A write enable input
input wire din_a, // port A data input
output reg dout_a, // port A data output
input wire addr_b, // port B address input
input wire wren_b, // port B write enable input
input wire din_b, // port B data input
output reg dout_b // port B data output
);
// internal parameters
localparam
SIZE = (1<<ADDRESS); // memory size based on address size
// internal signals
reg r_addr_a; // a side address register
reg r_wren_a; // a side write enable register
reg r_din_a; // a side data in register
reg r_addr_b; // b side address register
reg r_wren_b; // b side write enable register
reg r_din_b; // b side data in register
reg mem /* synthesis ramstyle = "no_rw_check" */;
`ifdef SIMULATION
// init memory contents
initial
begin : init_mem
integer i;
for (i = 0; i < SIZE; i = i+1) mem = 0;
end
reg d_addr_a;
reg d_addr_b;
reg d_wren_a;
reg d_wren_b;
always @(posedge clk)
begin
// output write data
if (r_wren_a) $write("%m wren:a addr=%h data=%h\n",r_addr_a,r_din_a);
if (r_wren_b) $write("%m wren:b addr=%h data=%h\n",r_addr_b,r_din_b);
// output read data
if (d_addr_a != r_addr_a && !d_wren_a) $write("%m read:a addr=%h data=%h\n",d_addr_a,dout_a);
if (d_addr_b != r_addr_b && !d_wren_b) $write("%m read:b addr=%h data=%h\n",d_addr_b,dout_b);
// delay address/wren for reads
d_addr_a <=# TPD r_addr_a;
d_addr_b <=# TPD r_addr_b;
d_wren_a <=# TPD r_wren_a;
d_wren_b <=# TPD r_wren_b;
end
`endif // SIMULATION
// port A access
always @(posedge clk)
begin
r_addr_a <=# TPD addr_a;
r_wren_a <=# TPD wren_a;
r_din_a <=# TPD din_a;
end
always @(posedge clk)
begin
// write data
if (r_wren_a) mem <=# TPD r_din_a;
// read data
if (r_wren_a && MODE == "NEW")
dout_a <=# TPD r_din_a;
else
dout_a <=# TPD mem;
end
// port B access
always @(posedge clk)
begin
r_addr_b <=# TPD addr_b;
r_wren_b <=# TPD wren_b;
r_din_b <=# TPD din_b;
end
always @(posedge clk)
begin
// write data
if (r_wren_b) mem <=# TPD r_din_b;
// read data
if (r_wren_b && MODE == "NEW")
dout_b <=# TPD r_din_b;
else
dout_b <=# TPD mem;
end
endmodule // dualport