Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)

Dual port RAM Cyclone 5

AEsqu
Novice
979 Views

Hello,

I'm used to use this RTL code in Synplify to instantiate dual port ram for other FPGA's than the cyclone 5:

module dp_block
(
// memory port 1
p1_clk,
p1_addr,
p1_din,
p1_dout,
p1_we,
p1_re,
p1_ena,
// memory port 2
p2_clk,
p2_addr,
p2_din,
p2_dout,
p2_we,
p2_re,
p2_ena
)/*synthesis syn_ramstyle="no_rw_check"*/;

// memory parameter
parameter ADDR_BIT_WIDTH = 8;
parameter DATA_BIT_WIDTH = 16;

// memory port 1
input p1_clk;
input [ADDR_BIT_WIDTH-1:0] p1_addr;
input [DATA_BIT_WIDTH-1:0] p1_din;
input p1_we;
input p1_re;
input p1_ena;
output [DATA_BIT_WIDTH-1:0] p1_dout;
reg [DATA_BIT_WIDTH-1:0] p1_dout;

// memory port 2
input p2_clk;
input [ADDR_BIT_WIDTH-1:0] p2_addr;
input [DATA_BIT_WIDTH-1:0] p2_din;
input p2_we;
input p2_re;
input p2_ena;
output [DATA_BIT_WIDTH-1:0] p2_dout;
reg [DATA_BIT_WIDTH-1:0] p2_dout;

// memory
reg [DATA_BIT_WIDTH-1:0] mem [0:(2**ADDR_BIT_WIDTH)-1];

 

always @(posedge p1_clk) begin
if (p1_ena)
begin
if (p1_we)
mem[p1_addr] <= p1_din;
p1_dout <= mem[p1_addr];
end
end

always @(posedge p2_clk) begin
if (p2_ena)
begin
if (p2_we)
mem[p2_addr] <= p2_din;
p2_dout <= mem[p2_addr];
end
end

endmodule

 

This is not working for the cyclone 5 apparently (write conflict),

Synplify team told me that Cyclone 5 M10K block only supports new data instead of old data at the read port.

In the Intel coding style reference for the Cyclone 5 document,

I do not see the verilog code example for dual port ram with 2 clocks, like above.

What would be the RTL code to make it work with the cyclone 5?

I have attached a ip configuration picture that would match the RTL code (unfortunately I couldn't find a way in Quartus 21.1 to create verilog/vhdl code for the dual port,

only netlist generation, which is not for me as I use it for different ram sizes and want to keep it generic with only one RTL code for Synplify.

Kind Regards,

Alexandre. 

0 Kudos
7 Replies
sstrell
Honored Contributor III
970 Views

In the Quartus text editor true dual port RAM (dual clock) template (Text Editor Edit menu -> Insert Template), it's a bit different from what you have.  New data would imply that on write, you should have, along with writing to the RAM:

 

p1_dout <= p1_din; //similar for p2

 

You're also missing in your if statements an else check for if p1_we (or p2_we) are low:

p1_dout <= mem[p1_addr]; //again similar for p2

 

I'm also not sure if there are separate RAM enable signals like what you have (p1_ena and p2_ena).  They are not in the template.

Any of these could affect how the RAM gets inferred and whether extra external logic gets added to match your behavioral description.

0 Kudos
AEsqu
Novice
955 Views

Thank you,

I couldn't reach the edit/insert template as it only popups when a file is open with the Quartus editor.

I think the template generator should always be available.

I will create one from it and try, thanks again sstrell.

0 Kudos
AEsqu
Novice
951 Views

Synplify still errors out when using the RAM close to the Quartus template (on a ram bigger than 32 bits, using 7 8 bits blocks of dp_block):

@E:MF212 : dp_block.v(30) | Cannot map ....mem.I_dp_block_6.ram_1[7:0] due to multiple write clocks.

Looks like a synplify bug.

I have attached the file where both your remarks are in.

0 Kudos
sstrell
Honored Contributor III
944 Views

Again, I don't think p1_ena or p2_ena are valid signals for the RAM.  They're still in your code.

0 Kudos
AEsqu
Novice
908 Views

Thank You, Synplify is indeed able to map the RAM in the cyclone 5 when the enables are removed.

 

0 Kudos
ShengN_Intel
Employee
889 Views

Hi,

 

Looks like the issue addressed had been resolved.
I'll now transition this thread to community support.
If you have a new question, feel free to open a new thread to get the support from Intel experts.

 

Thank you.

 

Best regards,
Sheng
p/s: If any answer from the community or Intel support are helpful, please feel free to give Kudos.

0 Kudos
AEsqu
Novice
807 Views

Synopsys provided me an updated m_altera file for Synplify, that supports the enable in the dual port ram RTL code,

(that was supported for the xilinx mapper).

 

The code below is now compiling well for the cyclone V.

module dp_block
#(parameter DATA_BIT_WIDTH=16, parameter ADDR_BIT_WIDTH=8)
(
  input [(DATA_BIT_WIDTH-1):0] p1_din, p2_din,
  input [(ADDR_BIT_WIDTH-1):0] p1_addr, p2_addr,
  input p1_we, p2_we, p1_clk, p1_re, p1_ena, p2_clk, p2_re, p2_ena,
  output reg [(DATA_BIT_WIDTH-1):0] p1_dout, p2_dout
)/*synthesis syn_ramstyle="no_rw_check"*/;

  // Declare the RAM variable
  reg [DATA_BIT_WIDTH-1:0] ram[2**ADDR_BIT_WIDTH-1:0];

  always @ (posedge p1_clk)
    begin
      if (p1_ena)
        begin
          if (p1_we) 
            begin
              ram[p1_addr] <= p1_din;
              p1_dout <= p1_din;
            end
          else 
            begin
              p1_dout <= ram[p1_addr];
            end 
        end
    end

  always @ (posedge p2_clk)
    begin
      if (p2_ena)
        begin 
          if (p2_we) 
            begin
              ram[p2_addr] <= p2_din;
              p2_dout <= p2_din;
            end
          else 
            begin
              p2_dout <= ram[p2_addr];
            end 
        end
    end

endmodule

AEsqu_0-1648726388192.png

 

0 Kudos
Reply