Forum Discussion
dsmr
New Contributor
5 years agoHi,
meanwhile I found the problem. About 15 years ago, I modeled a simple RAM after an Altera-Megafunction using registered inputs. I remember finding this a bit weird, but that way Quartus managed to infer RAM instead of logic - at least until 2019.
It seems as of 2020 Quartus refuses to infer RAM for the code below. Is there any way to get the old behavior back? I have tried changing the RAM model to use registered outputs, but that changes the behavior in some rare cases.
Kind regards
Dirk
module spRam1(q, d, adr, we, clk);
// define parameters
parameter m = 10; // Address width
parameter n = 1024; // Number of elements
parameter w = 8; // Data width
// define inputs and outputs
output [w-1:0] q; // Data output
input [w-1:0] d; // Data input
input [m-1:0] adr; // Read/write address
input we; // Write enable
input clk; // Clock
// define internal states
reg [w-1:0] mem[n-1:0]; // Memory
reg weD; // Delayed read enable
reg [m-1:0] adrD; // Delayed address
reg [w-1:0] dD; // Delayed data
// synchronous memory operation - input is registered (as in Altera Megafunction)
always @(posedge clk) begin
weD <= we;
adrD <= adr;
dD <= d;
if (weD)
mem[adrD] <= dD;
end
// assign output
assign q = mem[adrD]; // Output if read enable in
// the previous cycle
endmodule
sstrell
Super Contributor
5 years agoThe Quartus template for an inferred RAM is:
always @ (posedge clk) begin if (we) ram[addr] = data; // Read returns OLD data. To return // NEW data, use = (blocking write) rather than <= (non-blocking write) // in the write assignment. NOTE: NEW data requires extra bypass // logic around the RAM on Stratix10. q <= ram[addr]; end
I'm not sure what behavior change you are referring to, but the read side of the RAM should be in the same process. It's been like this for as long as I can remember.