Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.
15463 Discussions

Infer dual port RAM without read during write bypass logic


I am attempting to infer a single clock, dual port RAM without any bypass logic. I am having problems with synthesis, it seems to add a lot of bypass logic that wasn't there when I used the megawizard.

// // Dual-Port RAM with different read/write addresses and single read/write clock // and with a control for writing single bytes into the memory word; byte enable // Note - bytes are VERY often not even close to 8 bits. 16 for colors, 18 for floats, etc. module byte_enabled_dual_port_ram #(parameter int RADDR_WIDTH = 8, WADDR_WIDTH = 6, BYTE_WIDTH = 8, BYTES = 4, WIDTH = BYTES * BYTE_WIDTH ) ( input [WADDR_WIDTH-1:0] waddr, input [RADDR_WIDTH-1:0] raddr, input [BYTES-1:0] be, input [WIDTH-1:0] wdata, input we, clk, output reg [WIDTH/(1<<(RADDR_WIDTH - WADDR_WIDTH))-1:0] q ); localparam int WORDS = 1 << WADDR_WIDTH; localparam int RATIO = 1 << (RADDR_WIDTH - WADDR_WIDTH); // use a multi-dimensional packed array to model individual bytes within the word logic [BYTES-1:0][BYTE_WIDTH-1:0] ram[0:WORDS-1];   logic [WADDR_WIDTH-1:0] waddr_reg; logic [RADDR_WIDTH-1:0] raddr_reg; logic [BYTES-1:0] be_reg; logic [WIDTH-1:0] wdata_reg; logic we_reg; wire [WIDTH-1:0]word = ram[raddr_reg/RATIO]; always_ff@(posedge clk) begin waddr_reg <= waddr; raddr_reg <= raddr; be_reg <= be; wdata_reg <= wdata; we_reg <= we; for(int i = 0; i < BYTES; i++) begin if(be_reg[i] && we_reg) begin ram[waddr_reg][i] <= wdata_reg[i*BYTE_WIDTH +: BYTE_WIDTH]; end end //q <= ram[raddr / RATIO][(raddr % RATIO) * (BYTES/RATIO) +: (BYTES/RATIO)]; q <= word[(raddr_reg % RATIO) * (WIDTH/RATIO) +: (WIDTH/RATIO)]; end endmodule : byte_enabled_dual_port_ram  

I'm not sure what's going on exactly - when I look at the RTL viewer, I can see that raddr is passed directly to the altsyncram module, instead of going through the raddr_reg: rtl_dual_port.png

Any ideas what's gone wrong? How to fix?

0 Kudos
2 Replies

Hi Evan,

Apologize for idle for awhile. Do you able to solve the issue? Do you need further help?

I ended up just using an altsyncram definition. I dont think quartus is able to infer such a complicated ram.