Forum Discussion
Hi Dirk,
Could you provide the qar of your design if possible to replicate? Can send it via private message if it confidential.
- dsmr5 years ago
New Contributor
Hi,
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- sstrell5 years ago
Super Contributor
The 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]; endI'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.