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

Inferring a True Dual Port RAM with Byte enable for MAX10 FPGA

jal_joshi
Beginner
1,361 Views

I'm trying to implement a True Dual Port RAM with byteenable for MAX10 FPGA. When I try synthesizing the code it gets inferred as an SYNC_RAM (RTL Viewer) but without byte enable as one of its ports. As a result, it utilizes more RAM blocks (M9K) compared to the RAM: 2-Port Mega function.

e.g. if I configure the Mega function for DEPTH = 512 DATA_WIDTH = 32 it infers 2 M9K blocks, while using the same configuration for my RTL it infers 4 M9K blocks.   

Attached is my RTL code. Let me know where I'm doing wrong. 

module u20_data_mem #
(

parameter MEM_DEPTH_32_I = 512,

parameter MEM_ADDR_WIDTH_32_I = 9
)
(

//Port A
input clock_a,
input [(MEM_ADDR_WIDTH_32_I-1):0] address_a,
input [31:0] data_a,
input [3:0] byteena_a,
output reg [31:0] q_a,
input wren_a,
input rden_a,

//Port B
input clock_b,
input [(MEM_ADDR_WIDTH_32_I-1):0] address_b,
input [31:0] data_b,
input [3:0] byteena_b,
output reg [31:0] q_b,
input wren_b,
input rden_b
);

reg [7:0] mem_byte0 [ (MEM_DEPTH_32_I-1)/4:0] /* synthesis ramstyle = "no_rw_check" */;
reg [15:8] mem_byte1 [ (MEM_DEPTH_32_I-1)/4:0] /* synthesis ramstyle = "no_rw_check" */;
reg [23:16] mem_byte2 [ (MEM_DEPTH_32_I-1)/4:0] /* synthesis ramstyle = "no_rw_check" */;
reg [31:24] mem_byte3 [ (MEM_DEPTH_32_I-1)/4:0] /* synthesis ramstyle = "no_rw_check" */;

reg [7:0] q_a0;
reg [7:0] q_a1;
reg [7:0] q_a2;
reg [7:0] q_a3;

reg [7:0] q_b0;
reg [7:0] q_b1;
reg [7:0] q_b2;
reg [7:0] q_b3;

//Port A read operation
always @ (posedge clock_a)
begin
if (rden_a)
begin
q_a <= {q_a3,q_a2,q_a1,q_a0};
end
end

//Port A write operation for 0th Byte
always @ (posedge clock_a)
begin
if ( (wren_a) & (byteena_a[0]))
begin
mem_byte0[address_a]<= data_a[7:0];
q_a0 <= data_a[7:0];
end
else
begin
q_a0 <= mem_byte0[address_a];
end
end

//Port A write operation for 1st Byte
always @ (posedge clock_a)
begin
if ( (wren_a) & (byteena_a[1]))
begin
mem_byte1[address_a]<= data_a[15:8];
q_a1 <= data_a[15:8];
end
else
begin
q_a1 <= mem_byte1[address_a];
end
end

//Port A write operation for 2nd Byte
always @ (posedge clock_a)
begin
if ( (wren_a) & (byteena_a[2]))
begin
mem_byte2[address_a]<= data_a[23:16];
q_a2 <= data_a[23:16];
end
else
begin
q_a2 <= mem_byte2[address_a];
end
end

//Port A write operation for 3rd Byte
always @ (posedge clock_a)
begin
if ( (wren_a) & (byteena_a[3]))
begin
mem_byte3[address_a]<= data_a[31:24];
q_a3 <= data_a[31:24];
end
else
begin
q_a3 <= mem_byte3[address_a];
end
end

//Port B read operation
always @ (posedge clock_b)
begin
if (rden_b)
begin
q_b = {q_b3,q_b2,q_b1,q_b0};
end
end

//Port B write operation for 0th Byte
always @ (posedge clock_b)
begin
if ( (wren_b) & (byteena_b[0]))
begin
mem_byte0[address_b]<= data_b[7:0];
q_b0 <= data_b[7:0];
end
else
begin
q_b0 <= mem_byte0[address_b];
end
end

//Port B write operation for 1st Byte
always @ (posedge clock_b)
begin
if ( (wren_b) & (byteena_b[1]))
begin
mem_byte1[address_b]<= data_b[15:8];
q_b1 <= data_b[15:8];
end
else
begin
q_b1 <= mem_byte1[address_b];
end
end

//Port B write operation for 2nd Byte
always @ (posedge clock_b)
begin
if ( (wren_b) & (byteena_b[2]))
begin
mem_byte2[address_b]<= data_b[23:16];
q_b2 <= data_b[23:16];
end
else
begin
q_b2 <= mem_byte2[address_b];
end
end

//Port B write operation for 3rd Byte
always @ (posedge clock_b)
begin
if ( (wren_b) & (byteena_b[3]))
begin
mem_byte3[address_b]<= data_b[31:24];
q_b3 <= data_b[31:24];
end
else
begin
q_b3 <= mem_byte3[address_b];
end
end

endmodule

0 Kudos
1 Solution
ShengN_Intel
Employee
1,324 Views

Hi,


The reason why there are 4 M9K blocks is because of mem_byte0, mem_byte1, mem_byte2 and mem_byte3 you declared.

May go to Edit -> Insert Template -> Verilog HDL -> Full Designs ->RAMs and ROMs and refer to True Dual Port RAM (dual clocks).

May also go to Edit -> Insert Template -> VHDL -> Full Designs ->RAMs and ROMs and refer to Byte-enabled True Dual Port RAM for byte enable. (VHDL)


Thanks,

Best regards,

Sheng

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


View solution in original post

2 Replies
ShengN_Intel
Employee
1,325 Views

Hi,


The reason why there are 4 M9K blocks is because of mem_byte0, mem_byte1, mem_byte2 and mem_byte3 you declared.

May go to Edit -> Insert Template -> Verilog HDL -> Full Designs ->RAMs and ROMs and refer to True Dual Port RAM (dual clocks).

May also go to Edit -> Insert Template -> VHDL -> Full Designs ->RAMs and ROMs and refer to Byte-enabled True Dual Port RAM for byte enable. (VHDL)


Thanks,

Best regards,

Sheng

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


jal_joshi
Beginner
1,274 Views

Hi Sheng,

 

Thanks for your remark. I was able to manage it with a single memory block after referring to the templates. 

 

Regards,

Jal

0 Kudos
Reply