Parameterized Macro: Dual Port Distributed RAM
- MACRO_GROUP: XPM
- MACRO_SUBGROUP: XPM_MEMORY
Introduction
This macro instantiates Dual Port Distributed RAM. Port A performs both read and write operations and simultaneously port B performs read operations from the memory. Port B does not enable write operations.
The following describes the basic read and write port usage of an XPM_MEMORY instance. It does not distinguish between ports A and B.
- All synchronous signals are sensitive to the rising edge of clk[a|b], assumed to be a buffered and toggling clock signal behaving according to target device and memory primitive requirements.
- A read operation is performed implicitly on address addr[a|b] combinatorially. The data output registers on each clk[a|b] cycle when en[a|b] is asserted.
- Read data appears on the dout[a|b] port READ_LATENCY_[A|B] clk[a|b] cycles after the associated read operation.
- A write operation is explicitly performed, writing dina to address addra, when both ena and wea are asserted on each clka cycle.
- The value of en[a|b] gates all read and write operations on the initiating clk[a|b] cycle, regardless of input or output latencies. The addra and wea inputs have no effect when ena is deasserted on the coincident clka cycle.
- When rst[a|b] is asserted on a clk[a|b] cycle, the final output register resets immediately but synchronously to READ_RESET_VALUE_[A|B], irrespective of READ_LATENCY_[A|B].
- When regce[a|b] is asserted and rst[a|b] is deasserted on a clk[a|b] cycle, the final output register captures and outputs the value from the previous pipeline register.
- Undriven or unknown values provided on module inputs produce undefined memory array and output port behavior.
- Using MEMORY INIT PARAM limits the maximum supported memory size to 4K bits.
- When the attribute “CLOCKING_MODE” is set to “common_clock”, all
read/write operations to memory through port A and port B are performed on clka. If this
attribute is set to “independent_clock”, then read/write operations through port A are
performed based on clka, and read/write operations through port B are performed based on
clkb. - Writing to an out-of-range address location may overwrite a valid address location when effective address bits match to a physical memory address location.
- Specify set_false_path constraint for
the independent clock distributed RAM based memory if the design takes
care of avoiding address collision (write address != read address
at any given point of time). Set USE_EMBEDDED_CONSTRAINT = 1 if XPM_MEMORY
needs to take care of necessary constraints. If USE_EMBEDDED_CONSTRAINT
= 0, Vivado may trigger Timing-6 or Timing-7 or both. Alternatively,
you can also add the constraint when USE_EMBEDDED_CONSTRAINT = 0.
An example of adding this constraint is provided below. If Port-B
also has write permissions for an Independent clock configuration,
then a similar constraint needs to be added for clkb as well.
set_false_path -from [filter [all_fanout -from [get_ports clka] -flat -endpoints_only] {IS_LEAF}] -through [get_pins -of_objects [get_cells -hier * -filter {PRIMITIVE_SUBGROUP==LUTRAM || PRIMITIVE_SUBGROUP==dram || PRIMITIVE_SUBGROUP==drom}] -filter {DIRECTION==OUT}] - If "CLOCKING_MODE" is set to "independent_clock", Vivado can trigger a false positive CDC-1 warning and can be ignored.
Port Descriptions
| Port | Direction | Width | Domain | Sense | Handling if Unused | Function |
|---|---|---|---|---|---|---|
| addra | Input | ADDR_WIDTH_A | clka | NA | Active | Address for port A write and read operations. |
| addrb | Input | ADDR_WIDTH_B | clkb | NA | Active | Address for port B write and read operations. |
| clka | Input | 1 | NA | EDGE_RISING | Active | Clock signal for port A. Also clocks port B when parameter CLOCKING_MODE is "common_clock". |
| clkb | Input | 1 | NA | EDGE_RISING | Active | Clock signal for port B when parameter CLOCKING_MODE is "independent_clock". Unused when parameter CLOCKING_MODE is "common_clock". |
| dina | Input | WRITE_DATA_WIDTH_A | clka | NA | Active | Data input for port A write operations. |
| douta | Output | READ_DATA_WIDTH_A | clka | NA | Active | Data output for port A read operations. |
| doutb | Output | READ_DATA_WIDTH_B | clkb | NA | Active | Data output for port B read operations. |
| ena | Input | 1 | clka | LEVEL_HIGH | Active |
Memory enable signal for port A. Must be high on clock cycles when you initiate read or write operations. Pipelined internally. |
| enb | Input | 1 | clkb | LEVEL_HIGH | Active |
Memory enable signal for port B. Must be high on the clock cycles when you initiate read or write operations. Pipelined internally. |
| regcea | Input | 1 | clka | LEVEL_HIGH | 1 | Clock Enable for the last register stage on the output data path. |
| regceb | Input | 1 | clkb | LEVEL_HIGH | Active | Do not change from the provided value. |
| rsta | Input | 1 | clka | LEVEL_HIGH | Active |
Reset signal for the final port A output register stage. Synchronously resets output port douta to the value specified by parameter READ_RESET_VALUE_A. |
| rstb | Input | 1 | clkb | LEVEL_HIGH | Active | Reset signal for the final port B output register stage. Synchronously resets output port doutb to the value specified by parameter READ_RESET_VALUE_B. |
| wea | Input | WRITE_DATA_WIDTH_A / BYTE_WRITE_WIDTH_A | clka | LEVEL_HIGH | Active |
Write enable vector for port A input data port dina. 1 bit wide for word-wide writes. In byte-wide write configurations, each bit controls the writing one byte of dina to address addra. For example, to synchronously write only bits [15-8] of dina when WRITE_DATA_WIDTH_A is 32, wea is 4'b0010. |
Design Entry Method
| Instantiation | Yes |
| Inference | No |
| IP and IP Integrator Catalog | No |
Available Attributes
| Attribute | Type | Allowed Values | Default | Description |
|---|---|---|---|---|
| ADDR_WIDTH_A | DECIMAL | 1 to 20 | 6 |
Specify the width of the port A address port addra, in bits. Must be large enough to access the entire memory from port A, that is, >= $clog2(MEMORY_SIZE/[WRITE|READ]_DATA_WIDTH_A). |
| ADDR_WIDTH_B | DECIMAL | 1 to 20 | 6 |
Specify the width of the port B address port addrb, in bits. Must be large enough to access the entire memory from port B, that is, >= $clog2(MEMORY_SIZE/[WRITE|READ]_DATA_WIDTH_B). |
| BYTE_WRITE_WIDTH_A | DECIMAL | 1 to 4608 | 32 |
To enable byte-wide writes on port A, specify the byte width, in bits.
Or to enable word-wide writes on port A, specify the same value as for WRITE_DATA_WIDTH_A. |
| CLOCKING_MODE | STRING | "common_clock", "independent_clock" | "common_clock" | Specifies whether port A and port B use a common clock or independent clocks.
|
| IGNORE_INIT_SYNTH | DECIMAL | 0 to 1 | 0 |
0: Initiazation file if specified applies for both simulation and synthesis 1: Initiazation file if specified applies for only simulation and ignored for synthesis |
| MEMORY_INIT_FILE | STRING | String | "none" |
Specify "none" (including quotes) for no memory initialization, or specify the name of a memory initialization file. Enter only the name of the file with .mem extension, including quotes but without path (for example, "my_file.mem"). File format must be ASCII and consist of only hexadecimal values organized into the specified depth by narrowest data width generic value of the memory. Initialization of memory happens through the file name specified only when parameter MEMORY_INIT_PARAM value is equal to "". When using XPM_MEMORY in a project, add the specified file to the Vivado project as a design source. |
| MEMORY_INIT_PARAM | STRING | String | "0" |
Specify "" or "0" (including quotes) for no memory initialization through parameter, or specify the string containing the hex characters. Enter only hex characters with each location separated by delimiter (,). Parameter format must be ASCII and consist of only hexadecimal values organized into the specified depth by narrowest data width generic value of the memory. For example, if the narrowest data width is 8, and the depth of memory is 8 locations, then pass the parameter value as follows. parameter MEMORY_INIT_PARAM = "AB,CD,EF,1,2,34,56,78" Where "AB" is the 0th location and "78" is the 7th location. |
| MEMORY_OPTIMIZATION | STRING | "true", "false" | "true" | Specify "true" to enable the optimization of unused memory or bits in the memory structure. Specify "false" to disable the optimization of unused memory or bits in the memory structure |
| MEMORY_SIZE | DECIMAL | 2 to 150994944 | 2048 | Specify the total memory array size, in bits. For example, enter 65536 for a 2kx32 RAM. |
| MESSAGE_CONTROL | DECIMAL | 0 to 1 | 0 | Specify 1 to enable the dynamic message reporting such as collision warnings, and 0 to disable the message reporting |
| READ_DATA_WIDTH_A | DECIMAL | 1 to 4608 | 32 |
Specify the width of the port A read data output port douta, in bits. The values of READ_DATA_WIDTH_A and WRITE_DATA_WIDTH_A must be equal. |
| READ_DATA_WIDTH_B | DECIMAL | 1 to 4608 | 32 |
Specify the width of the port B read data output port doutb, in bits. The values of READ_DATA_WIDTH_B and WRITE_DATA_WIDTH_B must be equal. |
| READ_LATENCY_A | DECIMAL | 0 to 100 | 2 |
Specify the number of register stages in the port A read data pipeline. Read data output to port douta takes this number of clka cycles. Targeting block memory requires a value of 1 or larger; 1 causes use of memory latch only; 2 causes use of output register. Targeting distributed memory requires a value of 0 or larger; 0 indicates combinatorial output. Values larger than 2 synthesize additional flip-flops that are not retimed into memory primitives. |
| READ_LATENCY_B | DECIMAL | 0 to 100 | 2 |
Specify the number of register stages in the port B read data pipeline. Read data output to port doutb takes this number of clkb cycles (clka when CLOCKING_MODE is "common_clock"). Targeting block memory requires a value of 1 or larger. 1 causes use of memory latch only; 2 causes use of output register. Targeting distributed memory requires a value of 0 or larger. 0 indicates combinatorial output. Values larger than 2 synthesize additional flip-flops that are not retimed into memory primitives. |
| READ_RESET_VALUE_A | STRING | String | "0" |
Specify the reset value of the port A final output register stage in response to rsta input port assertion. The specified value must fit within the READ_DATA_WIDTH_A bit width. |
| READ_RESET_VALUE_B | STRING | String | "0" |
Specify the reset value of the port B final output register stage in response to rstb input port assertion. The specified value must fit within the READ_DATA_WIDTH_B bit width. |
| RST_MODE_A | STRING | "SYNC", "ASYNC" | "SYNC" |
Describes the behavior of the reset
|
| RST_MODE_B | STRING | "SYNC", "ASYNC" | "SYNC" |
Describes the behavior of the reset
|
| SIM_ASSERT_CHK | DECIMAL | 0 to 1 | 0 |
0: Disable simulation message reporting. This does not report messages related to potential misuse. 1: Enable simulation message reporting. This reports messages related to potential misuse. |
| USE_EMBEDDED_CONSTRAINT | DECIMAL | 0 to 1 | 0 | Specify 1 to enable the set_false_path constraint addition between clka of Distributed RAM and doutb_reg on clkb |
| USE_MEM_INIT | DECIMAL | 0 to 1 | 1 |
Specify 1 to enable the generation of the following message and 0 to disable generation of the following message completely. "INFO - MEMORY_INIT_FILE and MEMORY_INIT_PARAM together specifies no memory initialization. Initial memory contents will be all 0s." NOTE: The message generates only when there is no Memory Initialization specified either through file or Parameter. |
| USE_MEM_INIT_MMI | DECIMAL | 0 to 1 | 0 |
Specify 1 to expose this memory information for writing to the MMI file. |
| WRITE_DATA_WIDTH_A | DECIMAL | 1 to 4608 | 32 |
Specify the width of the port A write data input port dina, in bits. The values of WRITE_DATA_WIDTH_A and READ_DATA_WIDTH_A must be equal. |
VHDL Instantiation Template
Library xpm;
use xpm.vcomponents.all;
-- xpm_memory_dpdistram: Dual Port Distributed RAM
-- Xilinx Parameterized Macro, version 2026.1
xpm_memory_dpdistram_inst : xpm_memory_dpdistram
generic map (
ADDR_WIDTH_A => 6, -- DECIMAL
ADDR_WIDTH_B => 6, -- DECIMAL
BYTE_WRITE_WIDTH_A => 32, -- DECIMAL
CLOCKING_MODE => "common_clock", -- String
IGNORE_INIT_SYNTH => 0, -- DECIMAL
MEMORY_INIT_FILE => "none", -- String
MEMORY_INIT_PARAM => "0", -- String
MEMORY_OPTIMIZATION => "true", -- String
MEMORY_SIZE => 2048, -- DECIMAL
MESSAGE_CONTROL => 0, -- DECIMAL
READ_DATA_WIDTH_A => 32, -- DECIMAL
READ_DATA_WIDTH_B => 32, -- DECIMAL
READ_LATENCY_A => 2, -- DECIMAL
READ_LATENCY_B => 2, -- DECIMAL
READ_RESET_VALUE_A => "0", -- String
READ_RESET_VALUE_B => "0", -- String
RST_MODE_A => "SYNC", -- String
RST_MODE_B => "SYNC", -- String
SIM_ASSERT_CHK => 0, -- DECIMAL; 0=disable simulation messages, 1=enable simulation messages
USE_EMBEDDED_CONSTRAINT => 0, -- DECIMAL
USE_MEM_INIT => 1, -- DECIMAL
USE_MEM_INIT_MMI => 0, -- DECIMAL
WRITE_DATA_WIDTH_A => 32 -- DECIMAL
)
port map (
clka => clka, -- 1-bit input: Clock signal for port A. Also clocks port B when parameter CLOCKING_MODE is "common_clock".
rsta => rsta, -- 1-bit input: Reset signal for the final port A output register stage. Synchronously resets output port douta to the value
-- specified by parameter READ_RESET_VALUE_A.
ena => ena, -- 1-bit input: Memory enable signal for port A. Must be high on clock cycles when you initiate read or write operations.
-- Pipelined internally.
regcea => regcea, -- 1-bit input: Clock Enable for the last register stage on the output data path.
wea => wea, -- WRITE_DATA_WIDTH_A/BYTE_WRITE_WIDTH_A-bit input: Write enable vector for port A input data port dina. 1 bit wide for
-- word-wide writes. In byte-wide write configurations, each bit controls the writing one byte of dina to address addra. For
-- example, to synchronously write only bits [15-8] of dina when WRITE_DATA_WIDTH_A is 32, wea is 4'b0010.
addra => addra, -- ADDR_WIDTH_A-bit input: Address for port A write and read operations.
dina => dina, -- WRITE_DATA_WIDTH_A-bit input: Data input for port A write operations.
douta => douta, -- READ_DATA_WIDTH_A-bit output: Data output for port A read operations.
clkb => clkb, -- 1-bit input: Clock signal for port B when parameter CLOCKING_MODE is "independent_clock". Unused when parameter
-- CLOCKING_MODE is "common_clock".
rstb => rstb, -- 1-bit input: Reset signal for the final port B output register stage. Synchronously resets output port doutb to the value
-- specified by parameter READ_RESET_VALUE_B.
enb => enb, -- 1-bit input: Memory enable signal for port B. Must be high on the clock cycles when you initiate read or write operations.
-- Pipelined internally.
regceb => regceb, -- 1-bit input: Do not change from the provided value.
addrb => addrb, -- ADDR_WIDTH_B-bit input: Address for port B write and read operations.
doutb => doutb -- READ_DATA_WIDTH_B-bit output: Data output for port B read operations.
);
-- End of xpm_memory_dpdistram_inst instantiation
Verilog Instantiation Template
// xpm_memory_dpdistram: Dual Port Distributed RAM
// Xilinx Parameterized Macro, version 2026.1
xpm_memory_dpdistram #(
.ADDR_WIDTH_A(6), // DECIMAL
.ADDR_WIDTH_B(6), // DECIMAL
.BYTE_WRITE_WIDTH_A(32), // DECIMAL
.CLOCKING_MODE("common_clock"), // String
.IGNORE_INIT_SYNTH(0), // DECIMAL
.MEMORY_INIT_FILE("none"), // String
.MEMORY_INIT_PARAM("0"), // String
.MEMORY_OPTIMIZATION("true"), // String
.MEMORY_SIZE(2048), // DECIMAL
.MESSAGE_CONTROL(0), // DECIMAL
.READ_DATA_WIDTH_A(32), // DECIMAL
.READ_DATA_WIDTH_B(32), // DECIMAL
.READ_LATENCY_A(2), // DECIMAL
.READ_LATENCY_B(2), // DECIMAL
.READ_RESET_VALUE_A("0"), // String
.READ_RESET_VALUE_B("0"), // String
.RST_MODE_A("SYNC"), // String
.RST_MODE_B("SYNC"), // String
.SIM_ASSERT_CHK(0), // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
.USE_EMBEDDED_CONSTRAINT(0), // DECIMAL
.USE_MEM_INIT(1), // DECIMAL
.USE_MEM_INIT_MMI(0), // DECIMAL
.WRITE_DATA_WIDTH_A(32) // DECIMAL
)
xpm_memory_dpdistram_inst (
.clka(clka), // 1-bit input: Clock signal for port A. Also clocks port B when parameter CLOCKING_MODE is "common_clock".
.rsta(rsta), // 1-bit input: Reset signal for the final port A output register stage. Synchronously resets output port douta to the value
// specified by parameter READ_RESET_VALUE_A.
.ena(ena), // 1-bit input: Memory enable signal for port A. Must be high on clock cycles when you initiate read or write operations.
// Pipelined internally.
.regcea(regcea), // 1-bit input: Clock Enable for the last register stage on the output data path.
.wea(wea), // WRITE_DATA_WIDTH_A/BYTE_WRITE_WIDTH_A-bit input: Write enable vector for port A input data port dina. 1 bit wide for
// word-wide writes. In byte-wide write configurations, each bit controls the writing one byte of dina to address addra. For
// example, to synchronously write only bits [15-8] of dina when WRITE_DATA_WIDTH_A is 32, wea is 4'b0010.
.addra(addra), // ADDR_WIDTH_A-bit input: Address for port A write and read operations.
.dina(dina), // WRITE_DATA_WIDTH_A-bit input: Data input for port A write operations.
.douta(douta), // READ_DATA_WIDTH_A-bit output: Data output for port A read operations.
.clkb(clkb), // 1-bit input: Clock signal for port B when parameter CLOCKING_MODE is "independent_clock". Unused when parameter
// CLOCKING_MODE is "common_clock".
.rstb(rstb), // 1-bit input: Reset signal for the final port B output register stage. Synchronously resets output port doutb to the value
// specified by parameter READ_RESET_VALUE_B.
.enb(enb), // 1-bit input: Memory enable signal for port B. Must be high on the clock cycles when you initiate read or write operations.
// Pipelined internally.
.regceb(regceb), // 1-bit input: Do not change from the provided value.
.addrb(addrb), // ADDR_WIDTH_B-bit input: Address for port B write and read operations.
.doutb(doutb) // READ_DATA_WIDTH_B-bit output: Data output for port B read operations.
);
// End of xpm_memory_dpdistram_inst instantiation