Skip to content

olo_ft_ram_tdp

Back to Entity List

Status Information

VHDL Source: olo_ft_ram_tdp

Description

This component implements an ECC-protected true dual-port RAM using SECDED (Single Error Correction, Double Error Detection) Hamming code. It wraps olo_base_ram_tdp internally with a wider word to store parity bits alongside data.

The ECC is transparent to the user: data is automatically encoded on write and decoded/corrected on read. Error status flags indicate whether a single-bit error was corrected or a double-bit error was detected.

The true dual-port topology has two fully independent ports (A and B). Each port can read and write, each runs on its own clock (A_Clk / B_Clk), and each has its own ECC encoder and decoder so the two ports are protected independently.

This is useful in radiation-hardened designs where single-event upsets (SEUs) can flip bits in memory cells, e.g. in space or high-energy physics environments.

For background on the SECDED scheme, the codeword layout, error injection semantics and the constraints that apply across the ft area, see Open Logic Fault-Tolerance Principles.

Warning

True dual port RAM is NOT supported when compiling with Yosys for Cologne Chip FPGAs. Please use olo_base_ram_sdp instead.

Generics

Name Type Default Description
Depth_g positive - Number of addresses the RAM has
Width_g positive - Number of data bits stored per address (word-width). The internal RAM is wider to accommodate ECC parity bits.
RamRdLatency_g positive 1 Read latency of the wrapped RAM, excluding ECC pipeline stages. Higher values can help close timing on the RAM read path.
RamStyle_g string "auto" Controls the RAM implementation resource. Passed through to olo_base_ram_tdp.
RamBehavior_g string "RBW" Controls the RAM behavior.
"RBW": Read-before-write
"WBR": Write-before-read
EccPipeline_g natural 0 Number of pipeline register stages within each ECC decoder (range 0..2).
0 = combinational decode (default).
1 = single register at the decoder output - breaks the path from the RAM read port to the user's logic.
2 = distributed pipeline: register between syndrome compute and correction, plus a register at the output - use this when both halves of the SECDED logic need their own clock cycle to close timing.
See ECC Pipeline for details. Total read latency is RamRdLatency_g + EccPipeline_g cycles.

Interfaces

The two ports are symmetric. Port A and Port B carry the same set of signals with the A_ / B_ prefix respectively. The descriptions below are written for Port A; Port B behaves identically on its own clock.

Port A

Name In/Out Length Default Description
A_Clk in 1 - Port A clock
A_Rst in 1 '0' Port A reset (high-active, synchronous to A_Clk). Clears the port's error-injection latch and read-valid pipeline. RAM contents are unaffected (block RAMs cannot be reset).
A_Addr in ceil(log2(Depth_g)) - Port A address
A_WrEna in 1 '0' Port A write enable
A_WrData in Width_g 0 Port A write data
A_RdEna in 1 '1' Port A read enable. A_RdValid pulses '1' exactly RamRdLatency_g+EccPipeline_g cycles after each A_RdEna = '1' cycle. The RAM always reads; A_RdEna only gates the valid flag. Leave at the default '1' for continuous reads.
A_RdData out Width_g N/A Port A read data (corrected if a single-bit error was detected)
A_RdValid out 1 N/A Port A read-data valid. Pulses '1' when A_RdData / A_RdEccSec / A_RdEccDed correspond to a read (= A_RdEna delayed by RamRdLatency_g+EccPipeline_g cycles).
A_RdEccSec out 1 N/A Port A single error corrected flag. '1' when a single-bit error was detected and corrected.
A_RdEccDed out 1 N/A Port A double error detected flag. '1' when an uncorrectable double-bit error was detected. Read data is unreliable in this case.
A_ErrInj_BitFlip in eccCodewordWidth(Width_g) all 0 Port A error injection. Codeword-wide flip pattern XORed into the stored codeword. Popcount 1 = SEC-correctable, popcount 2 = DED-detectable. Leave unconnected for normal operation. See Error Injection.
A_ErrInj_Valid in 1 '0' Port A injection strobe. Latches A_ErrInj_BitFlip into the encoder's pending-injection register; the pattern is applied to the next write.

Port B

Name In/Out Length Default Description
B_Clk in 1 - Port B clock
B_Rst in 1 '0' Port B reset. Same behavior as A_Rst on B_Clk.
B_Addr in ceil(log2(Depth_g)) - Port B address
B_WrEna in 1 '0' Port B write enable
B_WrData in Width_g 0 Port B write data
B_RdEna in 1 '1' Port B read enable. Same behavior as A_RdEna.
B_RdData out Width_g N/A Port B read data (corrected if a single-bit error was detected)
B_RdValid out 1 N/A Port B read-data valid. Same behavior as A_RdValid.
B_RdEccSec out 1 N/A Port B single error corrected flag. Same behavior as A_RdEccSec.
B_RdEccDed out 1 N/A Port B double error detected flag. Same behavior as A_RdEccDed.
B_ErrInj_BitFlip in eccCodewordWidth(Width_g) all 0 Port B error injection. Same behavior as A_ErrInj_BitFlip.
B_ErrInj_Valid in 1 '0' Port B injection strobe. Same behavior as A_ErrInj_Valid.

Detailed Description

Architecture

olo_ft_ram_tdp architecture

Each port has its own ECC encoder and decoder, so the two ports are protected independently and can run on independent clocks. The ECC encoding is combinational on each write path. The internal RAM (an instance of olo_base_ram_tdp with a codeword-wide word) provides the configurable read pipeline (RamRdLatency_g) and forwards a per-port RdValid to the matching decoder. The ECC decoding happens in the per-port olo_ft_ecc_decode instances and the error flags are time-aligned with the read data regardless of EccPipeline_g.

Unlike the single- and simple-dual-port RAMs, olo_base_ram_tdp always reads on both ports; the A_RdEna / B_RdEna inputs only gate the corresponding RdValid output, they do not gate the RAM read itself.

ECC Pipeline

EccPipeline_g is forwarded one-to-one to both internal olo_ft_ecc_decode instances and inserts register stages on the decode datapath. The range is 0..2:

EccPipeline_g Structure
0 Combinational decode after the RAM read port. A_RdData / A_RdEccSec / A_RdEccDed appear RamRdLatency_g cycles after A_Addr.
1 Combinational syndrome + correction + SEC/DED → register near the output. Breaks the path from the RAM read port to the user's logic.
2 Combinational syndrome → register → combinational correction + SEC/DED → register. Breaks both the syndrome path and the correction path - use this when both halves of the SECDED logic need their own clock cycle to close timing at high clock frequencies.

Total read latency from address-presented to data-valid is RamRdLatency_g + EccPipeline_g clock cycles.

ECC Overhead, Error Injection and Status Flags

See the corresponding sections in Open Logic Fault-Tolerance Principles:

Constraints

See Open Logic Fault-Tolerance Principles - Constraints That Apply Across the Area for the no-byte-enables and no-initialization constraints. In addition, the following olo_ft_ram_tdp-specific constraint applies:

  • True dual-port RAM is NOT supported when compiling with Yosys for Cologne Chip FPGAs (inherited from olo_base_ram_tdp).