olo_base_ram_tdp¶
Status Information¶
VHDL Source: olo_base_ram_tdp
Description¶
This component implements a true dual-port RAM. It offers two ports, which both allow reading and writing. The two ports run on separate clocks - although connecting the same clock to both ports is allowed.
The RAM is implemented in pure VHDL but in a way that allows tools to implement it in block-RAMs.
Warning
True dual port RAM with different clocks for teh two ports is NOT supported when compiling with Yosys for Gologne Chip FPGAs. Please use olo_base_ram_sdp instead or connect the same clock to both ports.
Generics¶
| Name | Type | Default | Description |
|---|---|---|---|
| Depth_g | positive | - | Number of addresses the RAM has |
| Width_g | positive | - | Number of bits stored per address (word-width) |
| UseByteEnable_g | boolean | false | By default, all bits of a memory cell are written. Enabling byte-enables allows to control which bytes are written individually. The setting is only allows for if Width_g is a multiple of eight (otherwise the word byte-enable does not make sense). Note that setting this setting to true can lead to increased resource usage. See Detailed Description |
| RdLatency_g | positive | 1 | Read latency. 1 is the behavior of a normal synchronous RAM Higher values can be desirable for timing-optimization in high-speed logic. |
| RamStyle_g | string | "auto" | Through this generic, the exact resource to use for implementation can be controlled. This generic is applied to the attributes ram_style and ramstyle which vendors offer to control RAM implementation. Commonly used values are given below. AMD: "auto", block", "distributed", "ultra" - see ug901 for details Intel: "M4K", "M9K", "M20K", "M144K", "MLAB" - see quartus-help for details Efinix: "block_ram", "registers" - see efinity-synthesis for details Synplify(Lattice/Microchip): "block_ram", "registers", "distributed" - see microchip-attributes-guide for details Gowin: "block_ram", "distributed_ram", "registers", "rw_check", "no_rw_check" - see GowinSynthesis User Guide for details. |
| RamBehavior_g | string | "RBW" | Controls the RAM behavior. Must match the behavior of RAM resources of the target technology for efficient implementation. "RBW": Read-before-write - more common common, hence the default "WBR": Write-before-read If you are unsure what behavior your target device offers, try both settings and check which one is correctly mapped to RAM resources using the synthesis report. |
| InitString_g | string | "" | Initialization data for the memory formatted as comma separated list of hex calues (e.g. "0x1234, 0x0ABC"). Each value MUST have the 0x prefix. The first value goes to address 0, the second one to address 1 and so on. |
| InitFormat_g | string | "NONE" | "NONE": RAM is not initialized "HEX": RAM is initialized with InitString_g interpreted as list of hex values. Note: Not all technologies support RAM initialization. Check the documentation of your technology/tools for details. |
Interfaces¶
Port A¶
| Name | In/Out | Length | Default | Description |
|---|---|---|---|---|
| A_Clk | in | 1 | - | Port A clock |
| A_Rst | in | 1 | '0' | Port A synchronous reset Optional, only resets internal state of A_RdValid Does NOT reset the content of memory cells! |
| A_Addr | in | ceil(log2(Depth_g)) | - | Port A address |
| A_Be | in | Width_g/8 | All '1' | Port A byte-enables Ignored if UseByteEnable_g = false |
| A_WrEna | in | 1 | '0' | Port A write enable. The memory cell at A_Addr is written only if A_WrEna='1'. |
| A_WrData | in | Width_g | 0 | Port A write data |
| A_RdEna | in | 1 | '1' | Port A read indicator. A_RdValid is asserted RdLatency_g cycles after A_RdEna was asserted. Important: The RAM is always read, independently of the value of A_RdEna. |
| A_RdData | out | Width_g | N/A | Port A read data |
| A_RdValid | out | 1 | N/A | Port A read valid. Asserted RdLatency_g cycles after A_RdEna was asserted. |
Port B¶
| Name | In/Out | Length | Default | Description |
|---|---|---|---|---|
| B_Clk | in | 1 | - | Port B clock |
| B_Rst | in | 1 | '0' | Port B synchronous reset Optional, only resets internal state of B_RdValid Does NOT reset the content of memory cells! |
| B_Addr | in | ceil(log2(Depth_g)) | - | Port B address |
| B_Be | in | Width_g*/8 | All '1' | Port B byte-enables Ignored if UseByteEnable_g = false |
| B_WrEna | in | 1 | '0' | Port B write enable. The memory cell at B_Addr is written only if B_WrEna='1'. |
| B_WrData | in | Width_g | 0 | Port B write data |
| B_RdEna | in | 1 | '1' | Port B read indicator. B_RdValid is asserted RdLatency_g cycles after B_RdEna was asserted. Important: The RAM is always read, independently of the value of B_RdEna. |
| B_RdData | out | Width_g | N/A | Port B read data |
| B_RdValid | out | 1 | N/A | Port B read valid. Asserted RdLatency_g cycles after B_RdEna was asserted. |
Detailed Description¶
Read Latency¶
Below figure explains the RdLatency_g generic in detail:

Byte Enables¶
Due to tool limitations regarding inference, the usage of byte enables (UseByteEnable_g=true) can lead to increased RAM usage.nTherefore, do not use byte enable signals unless this is strictly required.
Open Logic internally does not use byte enables, hence only users using the olo_base_ram_tdp component directly with byte-enables enabled are affected.
For applications where vendor/tool independence is important, this is to be regarded as a required trade-off. For applications that target only one specific technology, it is suggested to use vendor macros if RAM with byte enables if required.
RdEna and RdValid¶
For TDP RAM inference, not all tools do support read enable signals. Therefore olo_base_ram_tdp, in contrast to other RAM components, does read the RAM in every clock cycle, independently of the A_RdEna / B_RdEna signals.
The A_RdEna / B_RdEna signals are only used to control the A_RdValid / B_RdValid signals.
This means that if A_RdEna is asserted, A_RdValid is asserted after RdLatency_g cycles, indicating that the data on A_RdData is valid and can be used. This is very useful in pipelined design, especially with configurable RdLatency_g values because it allows to design logic around independently of the RAM read latency.

The figure nicely depicts that A_RdData is updated even if A_RdEna is de-asserted.