- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Sheng,
Thanks for your remark. I was able to manage it with a single memory block after referring to the templates.
Regards,
Jal

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page