Skip to content

§ 3.1.2. SRAM

This section specifies a single-port asynchronous SRAM, from a one-bit cell to an addressable device. It separates word storage, physical row/column organization, symbolic bitline behavior, and access circuitry. Shared decoding/selection construction and output-enable behavior are described in 3.1.0. Helper Components; the SRAM-specific bitline and access contracts remain distinct.

Component Description Structural Behavioral
SRAMCell Stores one bit using a feedback latch and symbolic write access Yes Yes
SRAMRow Groups C cells sharing one wordline Yes Yes
SRAMBitlinePair Digital primitive for one shared column's precharge, sensing, and write excitation Yes No
SRAMStorageBank<W> Assembles R rows and C shared bitline pairs Yes Yes
SRAMRowDecoder Decodes the row portion of a word address Yes No
SRAMPrecharge Distributes precharge control to the physical columns Yes No
SRAMWriteDriver Generates one bit's complementary write values and masked drive enable Yes No
SRAMSenseAmplifier Digital primitive that accepts a valid symbolic read differential Yes No
SRAMColumnSelector<W> Routes one word's read pairs and write enables among K column groups Yes No
SRAMAccessControl<W> Timed digital primitive sequencing an asynchronous access Yes No
SRAMOutputBuffer<W> Compatibility wrapper around the common output-enable primitive Yes No
SRAM<W> Complete word-addressed asynchronous SRAM device Yes Yes

“Structural” includes explicitly identified terminal digital primitives for bitlines, sensing, output enable, and timing. Those primitives have directly evaluated behavior, but no separate behavioral-fidelity replacement. Only cells, rows, banks, and devices currently have both registered implementations. Structural remains the default for supported small geometries.

Compile the C++ examples in page order. They describe settled binary-control behavior, including state and operation deadlines; empty data optionals represent unknown bits. Construction geometry is assumed valid. Gate propagation and X/Z control-input rules remain in each component's “Unknown inputs and timing” section. These references are not additional simulator components.

Geometry and interface conventions

  • W is the word width: 8, 16, or 32 bits, fixed by the template.
  • N = depth_words is the number of addressable words, supplied at construction.
  • K = words_per_row is a power of two from 1 through 64 that divides N. Non-power-of-two depths such as N=6, K=2 are supported.
  • There are R = N/K physical rows and C = W*K bit columns. Capacity is N*W/8 bytes. A word is not necessarily a whole row.
  • Word address a selects row a/K and slot a%K. Slot j occupies columns j*W through j*W+W−1 in this model.
  • SRAM<32> with N=1024, K=4 has 256 rows, 128 columns, 1024 four-byte words, and 4096 bytes. Use behavioral device fidelity for that capacity rather than expanding 32,768 cells.
  • The device configuration is SRAMDeviceConfig.
  • The 32-bit word-address port and separate write/read buses are simulator-facing conventions. They are not a pin-for-pin package model with bidirectional DQ. The engine's single-source wires and INPUT/OUTPUT pin types are unchanged.
  • CE_N, WE_N, and OE_N are active-low; internal enables and byte masks are active-high. X means unknown and Z means high impedance. Storage has no guaranteed initial binary value.

In the visualizer, rows run horizontally and are stacked in row-number order. Cells run left-to-right in column-number order; BITLINE_c sits beneath CELL_c in every row. The complete device places the row decoder to the left, precharge above the bank, and column selection, write drivers, and sensing below. This layout shows the organization of the digital model, not a transistor floorplan.

Conventional 6T SRAM uses wordlines, paired bitlines, precharge, write drivers, and sensing. Here the cell uses a latch-based digital representation, and a bitline pair carries a symbolic differential, not an electrical voltage. The block organization follows those roles without claiming transistor accuracy. See SRAM cells and row/column organization, slides 31–42.

Construction

Native Python factories return fully initialized components; the same registered contracts are used by WebAssembly scenarios:

import circuit_backend as simulator

small = simulator.create_sram("SMALL", data_width=16, depth_words=8,
                              words_per_row=2, fidelity="structural")
large = simulator.create_sram("LARGE", data_width=32, depth_words=1024,
                              words_per_row=4, fidelity="behavioral")
cell = simulator.create_sram_component("cell", "CELL")
row = simulator.create_sram_component("row", "ROW", {"columns": "16"})

The device contract is memory.sram.device.W; the bank is memory.sram.bank.W. Cell and row contracts are memory.sram.cell and memory.sram.row. The remaining contract suffixes are bitline-pair, row-decoder, precharge, write-driver, sense-amplifier, column-selector.W, access-control.W, and output-buffer.W. Replace W with 8, 16, or 32. Standalone row/bitline/precharge geometry uses columns/rows/columns respectively.

Factories reject unsupported widths, invalid geometry, unknown parameters, and unsupported requested fidelities. They do not silently expand a large device or substitute behavioral fidelity for an explicit structural request.

Access timing

The device is asynchronous: no external clock is required. A selected address/control change starts a finite internal event sequence. Let P be phase_ticks (default 32, permitted 32–10000 simulator ticks).

Time from a new request Phase Action
0 Quiet Disable old wordlines, write drive, sensing, and output; keep old staged buses stable
P Precharge Stage the new address/data/mask and precharge all bitline pairs
2P Release Release precharge; establish write drive if this is a write
3P Access Activate the selected wordline; cells write or develop a read differential
4P Ready Enable sensing and, for a read with OE active, the output buffer

Internal paths add propagation delays. Tests compare settled checkpoints, not equal transient waveforms between fidelities. A canceled request cannot be completed by a stale timer. A write canceled before row activation does not change storage; canceling after activation can leave a completed write and does not roll it back. Hold inputs stable for a complete access. These delays are deliberately conservative simulator units, not calibrated nanoseconds or a vendor setup/hold specification. No automatic cache-latency claim follows from them.

All component examples follow the same IO/behavior/implementation/test pattern as §3.1.1. The C++ references describe each component's binary-control contract, rather than only one selected operation. Example tables are generated from every recorded test checkpoint, include checkpoint number and absolute time, and scroll within the page.

3.1.2.1. SRAMCell

Stores one bit using a feedback latch and symbolic write access.

IO pins

Pin Direction Width Description
WL Input 1 Selects the cell's row
DRIVE Input 1 Strong write excitation; not asserted for reads or precharge
BL, BL_BAR Input 1 each Symbolic complementary write values
Q, Q_BAR Output 1 each Stored bit and its complement

Behavior

With WL = DRIVE = 1, a complementary binary pair writes Q = BL. If either enable is 0, the cell holds its previous state. Merely selecting the row does not write. The DRIVE signal is an explicit digital distinction between write excitation and read sensing; it is not an extra physical pin on a 6T cell.

C++ example

#include <optional>
struct SRAMCellReference {
    std::optional<bool> q; // Empty means unknown, including power-up.
    std::optional<bool> q_bar() const {
        return q ? std::optional(!*q) : std::nullopt;
    }
    void update(bool wl, bool drive, std::optional<bool> bl,
                std::optional<bool> bar) {
        if (wl && drive)
            q = bl && bar && *bl != *bar ? bl : std::nullopt;
    }
};

Unknown inputs and timing

Starts unknown. An enabled noncomplementary or X/Z write pair makes storage unknown; a later valid write restores a known bit. Unknown enables can poison state when a write is possible. The structural access primitive has one tick of delay, followed by NAND-latch propagation.

Implementation

Structural implementation

ACCESS converts symbolic write excitation into active-low set/reset controls. STATE is the existing SRLatch, containing two feedback NAND gates. This is a digital latch-based representation, not a six-transistor electrical circuit.

Behavioral implementation

A stored four-state value implements the same settled cell contract without the latch topology. SRAMContractTest compares both implementations.

The behavioral cell's visualizer displays recorded Q and Q_BAR values, with WL and DRIVE indicators. These follow timeline scrubbing; the structural view continues to show its access circuit and latch.

Examples

All 9 recorded rows of SRAMCellTest, in checkpoint order. Outputs are test expectations verified against the simulation. Time is the absolute settled checkpoint time in simulator units, not milliseconds or CPU cycles.

Default scenario profile: canonical-default-preview / structural (59857f039337ca4c). Changing fidelity or the circuit can change these times.

Checkpointzero-based number · timeline label Timesimulator units BLInput · 1 bit BL_BARInput · 1 bit DRIVEInput · 1 bit WLInput · 1 bit QExpected output · 1 bit Q_BARExpected output · 1 bit
#0unknown-startup2 1 1 0 0 X X
#1write-zero7 0 1 1 1 0 1
#2hold10 0 1 0 0 0 not checked
#3read-is-not-write12 1 1 0 1 0 not checked
#4write-one17 1 0 1 1 1 0
#5deselect-before-drive-change20 1 0 0 0 1 not checked
#6unselected-write-drive22 0 1 1 0 1 not checked
#7unknown-write27 X X 1 1 X not checked
#8recover-zero32 0 1 1 1 0 not checked

Scroll within the table for all rows and pins. Buses use hexadecimal; values containing X/Z use MSB-first binary. Inputs show the declared values in effect at each checkpoint, including retained inputs. Sequential tests also replay preparation changes between checkpoints, such as lowering the clock. Use the matching checkpoint label in the simulation below.

The sequence establishes zero, holds it, selects the cell for a read without writing, writes one, rejects an unselected write, captures unknown data, and recovers with a valid write.

Embedded simulation

The standalone SRAMCellTest opens this component as SRAM_ROOT. Use the explorer to compare structural and behavioral fidelity.

Open SRAMCell in the simulator

Source and tests

Test Coverage
SRAMCellTest The complete standalone sequence shown above
SRAMContractTest Structural/behavioral equivalence; device and bank widths 8/16/32, multiple geometries and byte masks, mixed bank selection, and invalid configuration rejection

3.1.2.2. SRAMRow

Groups C cells sharing one wordline.

IO pins

Pin Direction Width Description
WL Input 1 Shared wordline
DRIVE_c Input 1 each Write excitation for column c
BL_c, BL_BAR_c Input 1 each Column write values
Q_c Output 1 each Each cell's stored value; feeds the column bitline model

Behavior

The construction parameter columns = C creates exactly C cells. Each cell receives the shared wordline and its own column excitation. There is no address decoder, clock, reset, or word read port inside a row. The row may contain several addressable words.

C++ example

#include <cstddef>
#include <vector>
struct SRAMRowReference {
    std::vector<SRAMCellReference> cells;
    explicit SRAMRowReference(std::size_t columns) : cells(columns) {}
    void update(bool wl, const std::vector<bool>& drive,
                const std::vector<std::optional<bool>>& bl,
                const std::vector<std::optional<bool>>& bar) {
        for (std::size_t c = 0; c < cells.size(); ++c)
            cells[c].update(wl, drive.at(c), bl.at(c), bar.at(c));
    }
    std::optional<bool> q(std::size_t c) const { return cells.at(c).q; }
};

Unknown inputs and timing

Startup and enabled unknown writes follow SRAMCell. columns accepts 1–4096; this is a simulator expansion limit, not a physical row-size claim. Inputs must settle before expecting the row's outputs to settle.

Implementation

Structural implementation

Contains CELL_0 through CELL_(C−1). Cells are registered families, so a structural row can contain behavioral cells.

Behavioral implementation

Stores C four-state values and applies the per-column write controls directly. It keeps the same expanded pin interface.

Examples

All 5 recorded rows of SRAMRowTest, in checkpoint order. Outputs are test expectations verified against the simulation. Time is the absolute settled checkpoint time in simulator units, not milliseconds or CPU cycles.

Default scenario profile: canonical-default-preview / structural (59857f039337ca4c). Changing fidelity or the circuit can change these times.

Checkpointzero-based number · timeline label Timesimulator units BL_0Input · 1 bit BL_1Input · 1 bit BL_BAR_0Input · 1 bit BL_BAR_1Input · 1 bit DRIVE_0Input · 1 bit DRIVE_1Input · 1 bit WLInput · 1 bit Q_0Expected output · 1 bit Q_1Expected output · 1 bit
#0unknown-startup2 1 0 0 1 0 0 0 X X
#1write-two-columns7 1 0 0 1 1 1 1 1 0
#2release10 1 0 0 1 0 0 0 1 0
#3prepare-masked-write12 0 1 1 0 0 1 0 1 0
#4write-only-column-one17 0 1 1 0 0 1 1 1 1

Scroll within the table for all rows and pins. Buses use hexadecimal; values containing X/Z use MSB-first binary. Inputs show the declared values in effect at each checkpoint, including retained inputs. Sequential tests also replay preparation changes between checkpoints, such as lowering the clock. Use the matching checkpoint label in the simulation below.

The two-column example writes different bits, deselects the row, then changes only column 1 while column 0's drive is disabled.

Embedded simulation

The standalone SRAMRowTest opens this component as SRAM_ROOT. Use the explorer to compare structural and behavioral fidelity.

Open SRAMRow in the simulator

Source and tests

Test Coverage
SRAMRowTest The complete standalone sequence shown above
SRAMContractTest Structural/behavioral equivalence; device and bank widths 8/16/32, multiple geometries and byte masks, mixed bank selection, and invalid configuration rejection

3.1.2.3. SRAMBitlinePair

Digital primitive for one shared column's precharge, sensing, and write excitation.

IO pins

Pin Direction Width Description
PRECHARGE Input 1 Charge/equalize the pair while all rows and write drivers are inactive
DRIVE Input 1 Enable strong write drive
WRITE_BL, WRITE_BL_BAR Input 1 each Write driver's complementary values
WL_r, Q_r Input 1 each Wordline and stored bit contribution from row r
BL, BL_BAR Output 1 each Symbolic bitline state, not measured voltage
VALID Output 1 Known read differential is available
CELL_DRIVE Output 1 Write excitation sent to the column's cells
CELL_BL, CELL_BL_BAR Output 1 each Write values delivered to cells

Behavior

The construction parameter rows = R supplies one contribution per row. Precharge sets the symbolic pair to (1,1) and prepares it for reading. Releasing precharge retains that state. Selecting one row develops (Q, !Q); VALID is high only for a known bit. Releasing a used row requires another precharge before the next read. During writes, the driver determines the pair and CELL_DRIVE is high. Cells still decide whether their wordline permits writing.

Multiple selected rows, an unknown wordline/drive/precharge, or precharge overlapping a selected row/write drive invalidate the pair and suppress cell drive. These are conservative digital rules, not a calculation of electrical contention.

C++ example

#include <optional>
#include <vector>
struct SRAMBitlineReference {
    std::optional<bool> bl, bar, cell_bl, cell_bar;
    bool valid = false, cell_drive = false;
    bool prepared = false;
    std::optional<std::size_t> reading_row;
    void update(bool precharge, bool drive, std::optional<bool> write_bl,
                std::optional<bool> write_bar, const std::vector<bool>& wl,
                const std::vector<std::optional<bool>>& cells) {
        valid = cell_drive = false; cell_bl.reset(); cell_bar.reset();
        std::size_t count = 0, row = 0;
        for (std::size_t r = 0; r < wl.size(); ++r)
            if (wl[r]) { ++count; row = r; }
        auto invalidate = [&] {
            bl.reset(); bar.reset(); prepared = false; reading_row.reset();
        };
        if (count > 1 || (precharge && (drive || count))) { invalidate(); return; }
        if (precharge) {
            bl = bar = true; prepared = true; reading_row.reset();
        } else if (drive) {
            bl = cell_bl = write_bl; bar = cell_bar = write_bar;
            cell_drive = true; prepared = false; reading_row.reset();
        } else if (count) {
            if (!prepared || (reading_row && *reading_row != row)) {
                invalidate(); return;
            }
            reading_row = row; bl = cells.at(row);
            bar = bl ? std::optional(!*bl) : std::nullopt;
            valid = bl.has_value();
        } else if (reading_row) {
            prepared = false; reading_row.reset(); // Pair retains its last value.
        }
    }
};

Unknown inputs and timing

The pair starts (X,X). The example covers all binary control combinations, including conflicts, and uses empty optionals for unknown data. X/Z control inputs additionally invalidate the pair. Outputs have a one-tick delay, omitted from the settled reference.

Implementation

Structural implementation

A registered terminal digital primitive. It is the explicit abstraction boundary for shared bitline behavior, with state recording through ordinary output wires. There is no multi-driver net resolver, capacitance, voltage, transistor strength, or leakage model. No separate compact implementation is registered because this primitive already performs direct evaluation.

Examples

All 13 recorded rows of SRAMBitlinePairTest, in checkpoint order. Outputs are test expectations verified against the simulation. Time is the absolute settled checkpoint time in simulator units, not milliseconds or CPU cycles.

Default scenario profile: canonical-default-preview / structural (59857f039337ca4c). Changing fidelity or the circuit can change these times.

Checkpointzero-based number · timeline label Timesimulator units DRIVEInput · 1 bit PRECHARGEInput · 1 bit Q_0Input · 1 bit Q_1Input · 1 bit WL_0Input · 1 bit WL_1Input · 1 bit WRITE_BLInput · 1 bit WRITE_BL_BARInput · 1 bit BLExpected output · 1 bit BL_BARExpected output · 1 bit CELL_BLExpected output · 1 bit CELL_BL_BARExpected output · 1 bit CELL_DRIVEExpected output · 1 bit VALIDExpected output · 1 bit
#0unknown-startup1 0 0 0 1 0 0 0 1 X X not checked not checked not checked 0
#1precharge3 0 1 0 1 0 0 0 1 1 1 not checked not checked 0 not checked
#2retain-charge5 0 0 0 1 0 0 0 1 1 1 not checked not checked not checked not checked
#3read-row-zero7 0 0 0 1 1 0 0 1 0 1 not checked not checked 0 1
#4release-row9 0 0 0 1 0 0 0 1 not checked not checked not checked not checked not checked 0
#5missing-precharge11 0 0 0 1 0 1 0 1 X not checked not checked not checked not checked 0
#6deselect13 0 0 0 1 0 0 0 1 not checked not checked not checked not checked not checked 0
#7precharge-again15 0 1 0 1 0 0 0 1 1 1 not checked not checked not checked not checked
#8release-precharge17 0 0 0 1 0 0 0 1 1 not checked not checked not checked not checked not checked
#9read-row-one19 0 0 0 1 0 1 0 1 1 0 not checked not checked not checked 1
#10two-row-conflict21 0 0 0 1 1 1 0 1 X not checked not checked not checked 0 0
#11write-drive23 1 0 0 1 0 0 0 1 0 1 0 not checked 1 not checked
#12precharge-write-conflict25 1 1 0 1 0 0 0 1 X not checked not checked not checked 0 not checked

Scroll within the table for all rows and pins. Buses use hexadecimal; values containing X/Z use MSB-first binary. Inputs show the declared values in effect at each checkpoint, including retained inputs. Sequential tests also replay preparation changes between checkpoints, such as lowering the clock. Use the matching checkpoint label in the simulation below.

The sequence includes precharge, retained charge, reads from both rows, a missing-precharge failure, two-row contention, write drive, and a precharge/write conflict.

Embedded simulation

The standalone SRAMBitlinePairTest opens this component as SRAM_ROOT. Expand the component where it has structural children; a terminal digital primitive is intentionally a leaf.

Open SRAMBitlinePair in the simulator

Source and tests

Test Coverage
SRAMBitlinePairTest The complete standalone sequence shown above

3.1.2.4. SRAMStorageBank<W>

Assembles R rows and C shared bitline pairs.

IO pins

Pin Direction Width Description
WL_r Input 1 each Row selections supplied by the decoder
PRECHARGE_c Input 1 each Precharge enable per bit column
DRIVE_c Input 1 each Column write drive
WRITE_BL_c, WRITE_BL_BAR_c Input 1 each Column write values
BL_c, BL_BAR_c, VALID_c Output 1 each Symbolic pair and read-valid result per column

Behavior

For W-bit words, N words, and K words per row, the bank has R = N/K rows and C = W*K columns. It contains exactly N*W cells. There is no complete word-address interface: row decoding, column selection, sensing, and access sequencing remain outside the bank. It does not expose every stored word as WORD_n, unlike FFStorageBank.

C++ example

#include <cstddef>
#include <vector>
struct SRAMBankReference {
    std::vector<SRAMRowReference> rows;
    std::vector<SRAMBitlineReference> columns;
    SRAMBankReference(std::size_t r, std::size_t c)
        : rows(r, SRAMRowReference(c)), columns(c) {}
    void update(const std::vector<bool>& wl, const std::vector<bool>& precharge,
                const std::vector<bool>& drive,
                const std::vector<std::optional<bool>>& bl,
                const std::vector<std::optional<bool>>& bar) {
        for (std::size_t c = 0; c < columns.size(); ++c) {
            std::vector<std::optional<bool>> q;
            for (const auto& row : rows) q.push_back(row.q(c));
            auto& pair = columns[c];
            pair.update(precharge.at(c), drive.at(c), bl.at(c), bar.at(c), wl, q);
            for (std::size_t r = 0; r < rows.size(); ++r)
                rows[r].cells[c].update(wl.at(r), pair.cell_drive, pair.cell_bl, pair.cell_bar);
        }
    }
    // BL_c / BL_BAR_c / VALID_c are columns[c].bl / bar / valid.
};

Unknown inputs and timing

The example composes the cell and bitline references, including unknown startup, precharge, reads, writes, and binary control conflicts. It assumes controls are settled and binary; X/Z controls follow the rules above. Both bank implementations are limited to 4096 cells because their interface exposes every row and column. A large compact device uses the word-address port instead.

Implementation

Structural implementation

ROW_r owns C SRAMCell instances. BITLINE_c receives that column's cell values from every row and distributes write excitation back to those cells. Rows own cells; bitline components do not duplicate storage.

Behavioral implementation

A flat four-state cell array plus per-column bitline state replaces the rows and cells. The same digital bitline primitive rules are reused. This proves equivalence to the documented abstraction, not independently to analog SRAM physics. Bank replacement leaves the surrounding decoder, precharge, drivers, selector, and sense amplifiers visible.

Examples

All 16 recorded rows of SRAMStorageBankTest, in checkpoint order. Outputs are test expectations verified against the simulation. Time is the absolute settled checkpoint time in simulator units, not milliseconds or CPU cycles.

Default scenario profile: canonical-default-preview / structural (59857f039337ca4c). Changing fidelity or the circuit can change these times.

Checkpointzero-based number · timeline label Timesimulator units DRIVE_0Input · 1 bit DRIVE_1Input · 1 bit DRIVE_10Input · 1 bit DRIVE_11Input · 1 bit DRIVE_12Input · 1 bit DRIVE_13Input · 1 bit DRIVE_14Input · 1 bit DRIVE_15Input · 1 bit DRIVE_2Input · 1 bit DRIVE_3Input · 1 bit DRIVE_4Input · 1 bit DRIVE_5Input · 1 bit DRIVE_6Input · 1 bit DRIVE_7Input · 1 bit DRIVE_8Input · 1 bit DRIVE_9Input · 1 bit PRECHARGE_0Input · 1 bit PRECHARGE_1Input · 1 bit PRECHARGE_10Input · 1 bit PRECHARGE_11Input · 1 bit PRECHARGE_12Input · 1 bit PRECHARGE_13Input · 1 bit PRECHARGE_14Input · 1 bit PRECHARGE_15Input · 1 bit PRECHARGE_2Input · 1 bit PRECHARGE_3Input · 1 bit PRECHARGE_4Input · 1 bit PRECHARGE_5Input · 1 bit PRECHARGE_6Input · 1 bit PRECHARGE_7Input · 1 bit PRECHARGE_8Input · 1 bit PRECHARGE_9Input · 1 bit WL_0Input · 1 bit WL_1Input · 1 bit WRITE_BL_0Input · 1 bit WRITE_BL_1Input · 1 bit WRITE_BL_10Input · 1 bit WRITE_BL_11Input · 1 bit WRITE_BL_12Input · 1 bit WRITE_BL_13Input · 1 bit WRITE_BL_14Input · 1 bit WRITE_BL_15Input · 1 bit WRITE_BL_2Input · 1 bit WRITE_BL_3Input · 1 bit WRITE_BL_4Input · 1 bit WRITE_BL_5Input · 1 bit WRITE_BL_6Input · 1 bit WRITE_BL_7Input · 1 bit WRITE_BL_8Input · 1 bit WRITE_BL_9Input · 1 bit WRITE_BL_BAR_0Input · 1 bit WRITE_BL_BAR_1Input · 1 bit WRITE_BL_BAR_10Input · 1 bit WRITE_BL_BAR_11Input · 1 bit WRITE_BL_BAR_12Input · 1 bit WRITE_BL_BAR_13Input · 1 bit WRITE_BL_BAR_14Input · 1 bit WRITE_BL_BAR_15Input · 1 bit WRITE_BL_BAR_2Input · 1 bit WRITE_BL_BAR_3Input · 1 bit WRITE_BL_BAR_4Input · 1 bit WRITE_BL_BAR_5Input · 1 bit WRITE_BL_BAR_6Input · 1 bit WRITE_BL_BAR_7Input · 1 bit WRITE_BL_BAR_8Input · 1 bit WRITE_BL_BAR_9Input · 1 bit BL_0Expected output · 1 bit BL_1Expected output · 1 bit BL_10Expected output · 1 bit BL_11Expected output · 1 bit BL_12Expected output · 1 bit BL_13Expected output · 1 bit BL_14Expected output · 1 bit BL_15Expected output · 1 bit BL_2Expected output · 1 bit BL_3Expected output · 1 bit BL_4Expected output · 1 bit BL_5Expected output · 1 bit BL_6Expected output · 1 bit BL_7Expected output · 1 bit BL_8Expected output · 1 bit BL_9Expected output · 1 bit BL_BAR_0Expected output · 1 bit BL_BAR_1Expected output · 1 bit BL_BAR_10Expected output · 1 bit BL_BAR_11Expected output · 1 bit BL_BAR_12Expected output · 1 bit BL_BAR_13Expected output · 1 bit BL_BAR_14Expected output · 1 bit BL_BAR_15Expected output · 1 bit BL_BAR_2Expected output · 1 bit BL_BAR_3Expected output · 1 bit BL_BAR_4Expected output · 1 bit BL_BAR_5Expected output · 1 bit BL_BAR_6Expected output · 1 bit BL_BAR_7Expected output · 1 bit BL_BAR_8Expected output · 1 bit BL_BAR_9Expected output · 1 bit VALID_0Expected output · 1 bit VALID_1Expected output · 1 bit VALID_10Expected output · 1 bit VALID_11Expected output · 1 bit VALID_12Expected output · 1 bit VALID_13Expected output · 1 bit VALID_14Expected output · 1 bit VALID_15Expected output · 1 bit VALID_2Expected output · 1 bit VALID_3Expected output · 1 bit VALID_4Expected output · 1 bit VALID_5Expected output · 1 bit VALID_6Expected output · 1 bit VALID_7Expected output · 1 bit VALID_8Expected output · 1 bit VALID_9Expected output · 1 bit
#0idle2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked 0 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked
#1prepare-write-row-05 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked 0 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked
#2write-row-010 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked 0 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked
#3release-row-013 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked 0 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked
#4prepare-write-row-116 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked 0 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked
#5write-row-121 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked 0 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked
#6release-row-124 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked 0 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked
#7release-drivers27 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked 0 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked
#8precharge-row-029 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked 1 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked
#9release-precharge-031 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked 0 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked
#10read-row-033 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
#11end-read-035 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked 0 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked
#12precharge-row-137 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked 1 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked
#13release-precharge-139 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked 0 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked
#14read-row-141 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
#15end-read-143 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked 0 not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked not checked

Scroll within the table for all rows and pins. Buses use hexadecimal; values containing X/Z use MSB-first binary. Inputs show the declared values in effect at each checkpoint, including retained inputs. Sequential tests also replay preparation changes between checkpoints, such as lowering the clock. Use the matching checkpoint label in the simulation below.

The 4×8 bank is arranged as two rows of 16 cells. Every cell is written in a row-dependent alternating pattern, then both rows are read through explicit precharge/release/select sequences.

Embedded simulation

The standalone SRAMStorageBankTest opens this component as SRAM_ROOT. Use the explorer to compare structural and behavioral fidelity.

Open SRAMStorageBank<W> in the simulator

Source and tests

Test Coverage
SRAMStorageBankTest The complete standalone sequence shown above
SRAMContractTest Structural/behavioral equivalence; device and bank widths 8/16/32, multiple geometries and byte masks, mixed bank selection, and invalid configuration rejection

3.1.2.5. SRAMRowDecoder

Decodes the row portion of a word address.

IO pins

Pin Direction Width Description
WORD_ADDR Input 32 Complete word index
ENABLE Input 1 Permit row activation
WL_r Output 1 each One-hot row selection

Behavior

For K words per row, the row number is WORD_ADDR / K. The low log2(K) bits select a word within the row and are ignored here. A known address outside N words selects no row. This decoder is not a DRAM ACTIVATE command or an externally retained open-row protocol.

C++ example

#include <cstddef>
#include <cstdint>
#include <vector>
std::vector<bool> sram_rows_ref(std::uint32_t address, bool enable,
                                std::size_t words, std::size_t words_per_row) {
    std::vector<bool> result(words / words_per_row, false);
    if (enable && address < words) result[address / words_per_row] = true;
    return result;
}

Unknown inputs and timing

Unknown address bits propagate through the gates and may produce unknown wordlines; the bitline model then suppresses writes. A known low ENABLE deselects all rows even with an unknown address. The structural decoder accepts up to 512 words; complete structural devices apply the stricter W-dependent cell limit.

Implementation

Structural implementation

An address splitter, complemented address bits, and balanced AND trees implement the row matches. The shared decodeMatch construction routine builds those trees after this wrapper extracts the row-address bits. No storage or direct host indexing is used; gate names and hierarchy remain unchanged. See helper reuse boundaries.

Examples

All 9 recorded rows of SRAMRowDecoderTest, in checkpoint order. Outputs are test expectations verified against the simulation. Time is the absolute settled checkpoint time in simulator units, not milliseconds or CPU cycles.

Default scenario profile: canonical-default-preview / structural (59857f039337ca4c). Changing fidelity or the circuit can change these times.

Checkpointzero-based number · timeline label Timesimulator units ENABLEInput · 1 bit WORD_ADDRInput · 32 bit WL_0Expected output · 1 bit WL_1Expected output · 1 bit WL_2Expected output · 1 bit
#0disabled8 0 0x00000000 0 0 0
#1address-012 1 0x00000000 1 0 0
#2address-114 1 0x00000001 1 0 0
#3address-219 1 0x00000002 0 1 0
#4address-321 1 0x00000003 0 1 0
#5address-426 1 0x00000004 0 0 1
#6address-528 1 0x00000005 0 0 1
#7address-633 1 0x00000006 0 0 0
#8address-429496729542 1 0xFFFFFFFF 0 0 0

Scroll within the table for all rows and pins. Buses use hexadecimal; values containing X/Z use MSB-first binary. Inputs show the declared values in effect at each checkpoint, including retained inputs. Sequential tests also replay preparation changes between checkpoints, such as lowering the clock. Use the matching checkpoint label in the simulation below.

Six words arranged two per row demonstrate both word slots in each of three rows, an out-of-range address, and an address with high bits set.

Embedded simulation

The standalone SRAMRowDecoderTest opens this component as SRAM_ROOT. Expand the component where it has structural children; a terminal digital primitive is intentionally a leaf.

Open SRAMRowDecoder in the simulator

Source and tests

Test Coverage
SRAMRowDecoderTest The complete standalone sequence shown above

3.1.2.6. SRAMPrecharge

Distributes precharge control to the physical columns.

IO pins

Pin Direction Width Description
ENABLE Input 1 Request precharge
PRECHARGE_c Output 1 each Buffered request for column c

Behavior

The construction parameter columns = C creates C buffered precharge controls. This block distributes control; the corresponding SRAMBitlinePair owns the symbolic charged state. Precharge must occur with wordlines and write drivers inactive.

C++ example

#include <cstddef>
#include <vector>
std::vector<bool> sram_precharge_ref(bool enable, std::size_t columns) {
    return std::vector<bool>(columns, enable);
}

Unknown inputs and timing

Each buffer propagates X/Z as unknown logic. Outputs settle one gate tick after the input. Precharge completion in the complete device includes the downstream bitline delay.

Implementation

Structural implementation

One AND buffer with a constant-high input per column. These outputs actually drive the bitline primitives; the block is not a visual-only grouping.

Examples

All 4 recorded rows of SRAMPrechargeTest, in checkpoint order. Outputs are test expectations verified against the simulation. Time is the absolute settled checkpoint time in simulator units, not milliseconds or CPU cycles.

Default scenario profile: canonical-default-preview / structural (59857f039337ca4c). Changing fidelity or the circuit can change these times.

Checkpointzero-based number · timeline label Timesimulator units ENABLEInput · 1 bit PRECHARGE_0Expected output · 1 bit PRECHARGE_1Expected output · 1 bit
#0disabled1 0 0 0
#1enabled3 1 1 1
#2released5 0 0 0
#3unknown-enable7 X X X

Scroll within the table for all rows and pins. Buses use hexadecimal; values containing X/Z use MSB-first binary. Inputs show the declared values in effect at each checkpoint, including retained inputs. Sequential tests also replay preparation changes between checkpoints, such as lowering the clock. Use the matching checkpoint label in the simulation below.

The two-column example asserts and releases precharge and shows an unknown control propagating to both outputs.

Embedded simulation

The standalone SRAMPrechargeTest opens this component as SRAM_ROOT. Expand the component where it has structural children; a terminal digital primitive is intentionally a leaf.

Open SRAMPrecharge in the simulator

Source and tests

Test Coverage
SRAMPrechargeTest The complete standalone sequence shown above

3.1.2.7. SRAMWriteDriver

Generates one bit's complementary write values and masked drive enable.

IO pins

Pin Direction Width Description
D Input 1 Data bit
ENABLE Input 1 Write phase active
MASK Input 1 Enable this bit's byte lane
BL, BL_BAR Output 1 each Data and complementary data
DRIVE Output 1 ENABLE AND MASK

Behavior

BL = D, BL_BAR = !D, and DRIVE = ENABLE && MASK. The values may remain present while DRIVE = 0; that does not write storage. There is one driver per external data bit. All eight drivers in a byte receive the same byte-mask input.

C++ example

struct SRAMDriveReference { bool bl, bar, drive; };
SRAMDriveReference sram_drive_ref(bool data, bool enable, bool mask) {
    return {data, !data, enable && mask};
}

Unknown inputs and timing

Unknown data produces an unknown pair. Unknown drive control is rejected by the bitline primitive and does not authorize a write. Complement generation includes its own gate delay; the access sequencer establishes write drive before activating the row.

Implementation

Structural implementation

ENABLED_BYTE is an AND gate, DATA is a buffer, and COMPLEMENT is a NOT gate. No electrical drive strength is calculated.

Examples

All 8 recorded rows of SRAMWriteDriverTest, in checkpoint order. Outputs are test expectations verified against the simulation. Time is the absolute settled checkpoint time in simulator units, not milliseconds or CPU cycles.

Default scenario profile: canonical-default-preview / structural (59857f039337ca4c). Changing fidelity or the circuit can change these times.

Checkpointzero-based number · timeline label Timesimulator units DInput · 1 bit ENABLEInput · 1 bit MASKInput · 1 bit BLExpected output · 1 bit BL_BARExpected output · 1 bit DRIVEExpected output · 1 bit
#0data-0-enable-0-mask-02 0 0 0 0 1 0
#1data-0-enable-0-mask-14 0 0 1 0 1 0
#2data-0-enable-1-mask-06 0 1 0 0 1 0
#3data-0-enable-1-mask-18 0 1 1 0 1 1
#4data-1-enable-0-mask-011 1 0 0 1 0 0
#5data-1-enable-0-mask-113 1 0 1 1 0 0
#6data-1-enable-1-mask-015 1 1 0 1 0 0
#7data-1-enable-1-mask-117 1 1 1 1 0 1

Scroll within the table for all rows and pins. Buses use hexadecimal; values containing X/Z use MSB-first binary. Inputs show the declared values in effect at each checkpoint, including retained inputs. Sequential tests also replay preparation changes between checkpoints, such as lowering the clock. Use the matching checkpoint label in the simulation below.

All eight binary combinations of data, enable, and byte mask are included.

Embedded simulation

The standalone SRAMWriteDriverTest opens this component as SRAM_ROOT. Expand the component where it has structural children; a terminal digital primitive is intentionally a leaf.

Open SRAMWriteDriver in the simulator

Source and tests

Test Coverage
SRAMWriteDriverTest The complete standalone sequence shown above

3.1.2.8. SRAMSenseAmplifier

Digital primitive that accepts a valid symbolic read differential.

IO pins

Pin Direction Width Description
BL, BL_BAR Input 1 each Selected symbolic bitline pair
VALID Input 1 The bitline model has a known read differential
ENABLE Input 1 Sensing phase active
Q Output 1 Resolved read bit, or X

Behavior

A known complementary pair produces Q = BL only when VALID = ENABLE = 1. Equal pairs, disabled sensing, and invalid input produce X. In particular, (1,1) from precharge must not be mistaken for a stored one.

C++ example

#include <optional>
std::optional<bool> sram_sense_ref(bool bl, bool bar, bool valid, bool enable) {
    if (enable && valid && bl != bar) return bl;
    return std::nullopt;
}

Unknown inputs and timing

X/Z or a noncomplementary pair cannot produce a known bit. Output delay is one tick. This model does not calculate differential voltage, gain, noise, or sense-amplifier offset.

Implementation

Structural implementation

A registered terminal digital primitive. It provides the sensing boundary used by the structural device; there is no separate behavioral replacement.

Examples

All 5 recorded rows of SRAMSenseAmplifierTest, in checkpoint order. Outputs are test expectations verified against the simulation. Time is the absolute settled checkpoint time in simulator units, not milliseconds or CPU cycles.

Default scenario profile: canonical-default-preview / structural (59857f039337ca4c). Changing fidelity or the circuit can change these times.

Checkpointzero-based number · timeline label Timesimulator units BLInput · 1 bit BL_BARInput · 1 bit ENABLEInput · 1 bit VALIDInput · 1 bit QExpected output · 1 bit
#0disabled1 1 1 0 0 X
#1equal-pair-is-not-data3 1 1 1 0 X
#2sense-zero5 0 1 1 1 0
#3sense-one7 1 0 1 1 1
#4invalid-pair9 1 1 1 1 X

Scroll within the table for all rows and pins. Buses use hexadecimal; values containing X/Z use MSB-first binary. Inputs show the declared values in effect at each checkpoint, including retained inputs. Sequential tests also replay preparation changes between checkpoints, such as lowering the clock. Use the matching checkpoint label in the simulation below.

Disabled sensing, the equalized pair, both valid bit values, and an invalid pair are tested.

Embedded simulation

The standalone SRAMSenseAmplifierTest opens this component as SRAM_ROOT. Expand the component where it has structural children; a terminal digital primitive is intentionally a leaf.

Open SRAMSenseAmplifier in the simulator

Source and tests

Test Coverage
SRAMSenseAmplifierTest The complete standalone sequence shown above

3.1.2.9. SRAMColumnSelector<W>

Routes one word's read pairs and write enables among K column groups.

IO pins

Pin Direction Width Description
WORD_ADDR Input 32 Low address bits select the word slot
WRITE_BL_b, WRITE_BL_BAR_b, WRITE_DRIVE_b Input 1 each W write-driver lanes
BL_c, BL_BAR_c, VALID_c Input 1 each Read state from all C = W*K columns
DRIVE_c, DRIVE_BL_c, DRIVE_BL_BAR_c Output 1 each Write route to each column
READ_BL_b, READ_BL_BAR_b, READ_VALID_b Output 1 each W selected read pairs

Behavior

The slot is WORD_ADDR % K. For lane b, the selected column is slot*W + b; this implementation uses contiguous word groups. The selector routes W read pairs and enables only that slot's write drivers. A real layout may interleave columns differently; that placement detail is not modeled here.

C++ example

#include <cstddef>
#include <cstdint>
#include <vector>
struct SRAMColumnReference {
    std::vector<std::optional<bool>> read_bl, read_bar, drive_bl, drive_bar;
    std::vector<bool> read_valid, drive;
};
SRAMColumnReference sram_select_ref(std::uint32_t address, std::size_t width,
    std::size_t slots, const std::vector<SRAMBitlineReference>& columns,
    const std::vector<bool>& write_bl, const std::vector<bool>& write_bar,
    const std::vector<bool>& write_drive) {
    SRAMColumnReference out;
    const auto slot = address % slots;
    for (std::size_t c = 0; c < width * slots; ++c) {
        auto b = c % width;
        out.drive_bl.push_back(write_bl.at(b)); // Data broadcast, drive decoded.
        out.drive_bar.push_back(write_bar.at(b));
        out.drive.push_back(c / width == slot && write_drive.at(b));
    }
    for (std::size_t b = 0; b < width; ++b) {
        const auto& col = columns.at(slot * width + b);
        out.read_bl.push_back(col.bl); out.read_bar.push_back(col.bar);
        out.read_valid.push_back(col.valid);
    }
    return out;
}

Unknown inputs and timing

Unknown slot bits follow the gate/multiplexer rules. Full-address range checking belongs to the row decoder, not this selector. K = 1 uses buffered pass-through paths rather than a multiplexer tree.

Implementation

Structural implementation

A low-bit slot decoder gates write excitation. Separate mux trees select BL, BL_BAR, and VALID for each read lane. The shared selectMuxTree construction routine creates those existing trees; it does not replace them with host indexing or a post-sense word mux. Buffers carry write values to the column groups.

Examples

All 2 recorded rows of SRAMColumnSelectorTest, in checkpoint order. Outputs are test expectations verified against the simulation. Time is the absolute settled checkpoint time in simulator units, not milliseconds or CPU cycles.

Default scenario profile: canonical-default-preview / structural (59857f039337ca4c). Changing fidelity or the circuit can change these times.

Checkpointzero-based number · timeline label Timesimulator units BL_0Input · 1 bit BL_1Input · 1 bit BL_10Input · 1 bit BL_11Input · 1 bit BL_12Input · 1 bit BL_13Input · 1 bit BL_14Input · 1 bit BL_15Input · 1 bit BL_2Input · 1 bit BL_3Input · 1 bit BL_4Input · 1 bit BL_5Input · 1 bit BL_6Input · 1 bit BL_7Input · 1 bit BL_8Input · 1 bit BL_9Input · 1 bit BL_BAR_0Input · 1 bit BL_BAR_1Input · 1 bit BL_BAR_10Input · 1 bit BL_BAR_11Input · 1 bit BL_BAR_12Input · 1 bit BL_BAR_13Input · 1 bit BL_BAR_14Input · 1 bit BL_BAR_15Input · 1 bit BL_BAR_2Input · 1 bit BL_BAR_3Input · 1 bit BL_BAR_4Input · 1 bit BL_BAR_5Input · 1 bit BL_BAR_6Input · 1 bit BL_BAR_7Input · 1 bit BL_BAR_8Input · 1 bit BL_BAR_9Input · 1 bit VALID_0Input · 1 bit VALID_1Input · 1 bit VALID_10Input · 1 bit VALID_11Input · 1 bit VALID_12Input · 1 bit VALID_13Input · 1 bit VALID_14Input · 1 bit VALID_15Input · 1 bit VALID_2Input · 1 bit VALID_3Input · 1 bit VALID_4Input · 1 bit VALID_5Input · 1 bit VALID_6Input · 1 bit VALID_7Input · 1 bit VALID_8Input · 1 bit VALID_9Input · 1 bit WORD_ADDRInput · 32 bit WRITE_BL_0Input · 1 bit WRITE_BL_1Input · 1 bit WRITE_BL_2Input · 1 bit WRITE_BL_3Input · 1 bit WRITE_BL_4Input · 1 bit WRITE_BL_5Input · 1 bit WRITE_BL_6Input · 1 bit WRITE_BL_7Input · 1 bit WRITE_BL_BAR_0Input · 1 bit WRITE_BL_BAR_1Input · 1 bit WRITE_BL_BAR_2Input · 1 bit WRITE_BL_BAR_3Input · 1 bit WRITE_BL_BAR_4Input · 1 bit WRITE_BL_BAR_5Input · 1 bit WRITE_BL_BAR_6Input · 1 bit WRITE_BL_BAR_7Input · 1 bit WRITE_DRIVE_0Input · 1 bit WRITE_DRIVE_1Input · 1 bit WRITE_DRIVE_2Input · 1 bit WRITE_DRIVE_3Input · 1 bit WRITE_DRIVE_4Input · 1 bit WRITE_DRIVE_5Input · 1 bit WRITE_DRIVE_6Input · 1 bit WRITE_DRIVE_7Input · 1 bit DRIVE_0Expected output · 1 bit DRIVE_1Expected output · 1 bit DRIVE_10Expected output · 1 bit DRIVE_11Expected output · 1 bit DRIVE_12Expected output · 1 bit DRIVE_13Expected output · 1 bit DRIVE_14Expected output · 1 bit DRIVE_15Expected output · 1 bit DRIVE_2Expected output · 1 bit DRIVE_3Expected output · 1 bit DRIVE_4Expected output · 1 bit DRIVE_5Expected output · 1 bit DRIVE_6Expected output · 1 bit DRIVE_7Expected output · 1 bit DRIVE_8Expected output · 1 bit DRIVE_9Expected output · 1 bit DRIVE_BL_0Expected output · 1 bit DRIVE_BL_1Expected output · 1 bit DRIVE_BL_10Expected output · 1 bit DRIVE_BL_11Expected output · 1 bit DRIVE_BL_12Expected output · 1 bit DRIVE_BL_13Expected output · 1 bit DRIVE_BL_14Expected output · 1 bit DRIVE_BL_15Expected output · 1 bit DRIVE_BL_2Expected output · 1 bit DRIVE_BL_3Expected output · 1 bit DRIVE_BL_4Expected output · 1 bit DRIVE_BL_5Expected output · 1 bit DRIVE_BL_6Expected output · 1 bit DRIVE_BL_7Expected output · 1 bit DRIVE_BL_8Expected output · 1 bit DRIVE_BL_9Expected output · 1 bit DRIVE_BL_BAR_0Expected output · 1 bit DRIVE_BL_BAR_1Expected output · 1 bit DRIVE_BL_BAR_10Expected output · 1 bit DRIVE_BL_BAR_11Expected output · 1 bit DRIVE_BL_BAR_12Expected output · 1 bit DRIVE_BL_BAR_13Expected output · 1 bit DRIVE_BL_BAR_14Expected output · 1 bit DRIVE_BL_BAR_15Expected output · 1 bit DRIVE_BL_BAR_2Expected output · 1 bit DRIVE_BL_BAR_3Expected output · 1 bit DRIVE_BL_BAR_4Expected output · 1 bit DRIVE_BL_BAR_5Expected output · 1 bit DRIVE_BL_BAR_6Expected output · 1 bit DRIVE_BL_BAR_7Expected output · 1 bit DRIVE_BL_BAR_8Expected output · 1 bit DRIVE_BL_BAR_9Expected output · 1 bit READ_BL_0Expected output · 1 bit READ_BL_1Expected output · 1 bit READ_BL_2Expected output · 1 bit READ_BL_3Expected output · 1 bit READ_BL_4Expected output · 1 bit READ_BL_5Expected output · 1 bit READ_BL_6Expected output · 1 bit READ_BL_7Expected output · 1 bit READ_BL_BAR_0Expected output · 1 bit READ_BL_BAR_1Expected output · 1 bit READ_BL_BAR_2Expected output · 1 bit READ_BL_BAR_3Expected output · 1 bit READ_BL_BAR_4Expected output · 1 bit READ_BL_BAR_5Expected output · 1 bit READ_BL_BAR_6Expected output · 1 bit READ_BL_BAR_7Expected output · 1 bit READ_VALID_0Expected output · 1 bit READ_VALID_1Expected output · 1 bit READ_VALID_2Expected output · 1 bit READ_VALID_3Expected output · 1 bit READ_VALID_4Expected output · 1 bit READ_VALID_5Expected output · 1 bit READ_VALID_6Expected output · 1 bit READ_VALID_7Expected output · 1 bit
#0slot-04 0 0 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x00000000 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
#1slot-19 0 0 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0x00000001 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 1 1 1 1 1 1 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1

Scroll within the table for all rows and pins. Buses use hexadecimal; values containing X/Z use MSB-first binary. Inputs show the declared values in effect at each checkpoint, including retained inputs. Sequential tests also replay preparation changes between checkpoints, such as lowering the clock. Use the matching checkpoint label in the simulation below.

Two word slots contain opposite bit patterns. The example verifies every selected read lane, every write-enable route, and the complementary write values.

Embedded simulation

The standalone SRAMColumnSelectorTest opens this component as SRAM_ROOT. Expand the component where it has structural children; a terminal digital primitive is intentionally a leaf.

Open SRAMColumnSelector<W> in the simulator

Source and tests

Test Coverage
SRAMColumnSelectorTest The complete standalone sequence shown above

3.1.2.10. SRAMAccessControl<W>

Timed digital primitive sequencing an asynchronous access.

IO pins

Pin Direction Width Description
WORD_ADDR Input 32 Requested word index
WRITE_DATA Input W Write data
WRITE_MASK Input W/8 Byte write enables
CE_N, WE_N, OE_N Input 1 each Active-low chip, write, and output enables
ADDRESS, DATA, MASK Output 32, W, W/8 Staged address and write signals
PRECHARGE, ROW_ENABLE, WRITE_ENABLE, SENSE_ENABLE, OUTPUT_ENABLE Output 1 each Internal phase controls

Behavior

A selected operation follows the timing sequence described above. Address changes, CE/WE changes, and write data/mask changes during a write restart it safely. Old address/data remain staged while the previous row is being disabled. OE only gates the completed read output; it does not restart the access. Write data/mask changes during a read are ignored.

Queued timer events recheck the current deadline and phase. Canceling or replacing a request prevents an old timer from completing that previous request.

C++ example

#include <cstddef>
#include <cstdint>
#include <optional>
#include <tuple>
struct SRAMControlReference {
    enum class Phase { Idle, Quiet, Precharge, Release, Access, Ready };
    Phase phase = Phase::Idle;
    struct Inputs {
        std::uint32_t address = 0, data = 0;
        unsigned mask = 0;
        bool ce_n = true, we_n = true, oe_n = true;
    };
    using Signature = std::tuple<std::uint32_t, bool, bool, std::uint32_t, unsigned>;
    std::optional<Signature> signature;
    Inputs pending;
    std::size_t due = 0;
    std::uint32_t address = 0, data = 0;
    unsigned mask = 0;
    bool precharge = false, row_enable = false, write_enable = false;
    bool sense_enable = false, output_enable = false;
    void update(std::size_t now, std::size_t ticks, const Inputs& in) {
        Signature next{in.address, in.ce_n, in.we_n,
                       in.we_n ? 0 : in.data, in.we_n ? 0 : in.mask};
        if (signature != next) { // OE and read-mode write buses do not restart.
            signature = next; pending = in;
            precharge = row_enable = write_enable = sense_enable = false;
            phase = in.ce_n ? Phase::Idle : Phase::Quiet;
            due = in.ce_n ? 0 : now + ticks;
        } else if (due && now >= due) {
            switch (phase) {
            case Phase::Quiet:
                address = pending.address; data = pending.data; mask = pending.mask;
                precharge = true; phase = Phase::Precharge; break;
            case Phase::Precharge:
                precharge = false; write_enable = !pending.we_n;
                phase = Phase::Release; break;
            case Phase::Release: row_enable = true; phase = Phase::Access; break;
            case Phase::Access: sense_enable = pending.we_n; phase = Phase::Ready; break;
            default: break;
            }
            due = phase == Phase::Ready ? 0 : now + ticks;
        }
        output_enable = phase == Phase::Ready && !in.ce_n && in.we_n && !in.oe_n;
    }
};

Unknown inputs and timing

Call update on input changes and at every nonzero due; a superseded deadline is harmless because the current request owns due. Inputs changing exactly at a deadline restart the access before that old phase can advance. Unknown CE/WE suppress operation; unknown OE disables output. Unknown addresses are passed through and handled by the row/bitline circuitry. The example assumes binary inputs and valid positive ticks. This is a conservative digital timing contract, not a specific vendor's timing model.

Implementation

Structural implementation

A registered terminal timing primitive implemented by AccessSequence. It schedules future evaluations in the existing simulator. No global clock, wire change, or new engine event type is required.

Examples

All 5 recorded rows of SRAMAccessControlTest, in checkpoint order. Outputs are test expectations verified against the simulation. Time is the absolute settled checkpoint time in simulator units, not milliseconds or CPU cycles.

Default scenario profile: canonical-default-preview / structural (59857f039337ca4c). Changing fidelity or the circuit can change these times.

Checkpointzero-based number · timeline label Timesimulator units CE_NInput · 1 bit OE_NInput · 1 bit WE_NInput · 1 bit WORD_ADDRInput · 32 bit WRITE_DATAInput · 8 bit WRITE_MASKInput · 1 bit ADDRESSExpected output · 32 bit DATAExpected output · 8 bit MASKExpected output · 1 bit OUTPUT_ENABLEExpected output · 1 bit PRECHARGEExpected output · 1 bit ROW_ENABLEExpected output · 1 bit SENSE_ENABLEExpected output · 1 bit WRITE_ENABLEExpected output · 1 bit
#0deselected0 1 0 1 0x00000001 0xA5 1 not checked not checked not checked 0 not checked 0 not checked not checked
#1read-complete129 0 0 1 0x00000001 0xA5 1 0x00000001 not checked not checked 1 0 1 1 0
#2output-disabled130 0 1 1 0x00000001 0xA5 1 not checked not checked not checked 0 not checked 1 not checked not checked
#3write-complete259 0 1 0 0x00000001 0xA5 1 not checked 0xA5 1 0 not checked not checked 0 1
#4deselect260 1 1 0 0x00000001 0xA5 1 not checked not checked not checked not checked 0 0 not checked 0

Scroll within the table for all rows and pins. Buses use hexadecimal; values containing X/Z use MSB-first binary. Inputs show the declared values in effect at each checkpoint, including retained inputs. Sequential tests also replay preparation changes between checkpoints, such as lowering the clock. Use the matching checkpoint label in the simulation below.

The standalone checkpoints show deselection, completed read, OE-only disable, completed write, and deselection. Intermediate precharge/release/access phases remain visible on the timeline. SRAMTimingTest additionally checks partial accesses and stale timers.

Embedded simulation

The standalone SRAMAccessControlTest opens this component as SRAM_ROOT. Expand the component where it has structural children; a terminal digital primitive is intentionally a leaf.

Open SRAMAccessControl<W> in the simulator

Source and tests

Test Coverage
SRAMAccessControlTest The complete standalone sequence shown above
SRAMTimingTest Canceled short writes, incomplete reads, superseded address requests, and eventual event-queue quiescence

3.1.2.11. SRAMOutputBuffer<W>

Digital output-enable primitive with high-impedance disabled output.

IO pins

Pin Direction Width Description
DATA Input W Read word from sense amplifiers
ENABLE Input 1 Present read data
OUT Output W Data when enabled, Z when disabled

Behavior

A high enable forwards the input word. A low enable produces Z on every output bit. This models an output driver being disabled; it does not make the simulator wire bidirectional or resolve other drivers.

C++ example

#include <cstdint>
#include <optional>
std::optional<std::uint32_t> sram_output_ref(std::uint32_t data, bool enable) {
    if (enable) return data;
    return std::nullopt; // Disabled output, not a stored zero.
}

Unknown inputs and timing

An unknown/Z enable produces X rather than choosing between driving and disconnecting. Enabled data preserves its four-state values. Output delay is one tick.

Implementation

Structural implementation

A compatibility wrapper inheriting the common MemoryOutputBuffer implementation. It retains the SRAM catalog ID, display name, pins, and one-tick delay without adding a child component. The implementation is a terminal digital primitive because ordinary Boolean gates cannot produce the required Z output. There is no separate behavioral replacement.

Examples

All 4 recorded rows of SRAMOutputBufferTest, in checkpoint order. Outputs are test expectations verified against the simulation. Time is the absolute settled checkpoint time in simulator units, not milliseconds or CPU cycles.

Default scenario profile: canonical-default-preview / structural (59857f039337ca4c). Changing fidelity or the circuit can change these times.

Checkpointzero-based number · timeline label Timesimulator units DATAInput · 8 bit ENABLEInput · 1 bit OUTExpected output · 8 bit
#0disabled1 0xA5 0 0bZZZZZZZZ
#1enabled3 0xA5 1 0xA5
#2unknown-enable5 0xA5 X 0bXXXXXXXX
#3disable-again7 0xA5 0 0bZZZZZZZZ

Scroll within the table for all rows and pins. Buses use hexadecimal; values containing X/Z use MSB-first binary. Inputs show the declared values in effect at each checkpoint, including retained inputs. Sequential tests also replay preparation changes between checkpoints, such as lowering the clock. Use the matching checkpoint label in the simulation below.

The example checks disabled Z, enabled data, unknown enable, and returning to disabled Z.

Embedded simulation

The standalone SRAMOutputBufferTest opens this component as SRAM_ROOT. Expand the component where it has structural children; a terminal digital primitive is intentionally a leaf.

Open SRAMOutputBuffer<W> in the simulator

Source and tests

Test Coverage
SRAMOutputBufferTest The complete standalone sequence shown above

3.1.2.12. SRAM<W>

Complete word-addressed asynchronous SRAM device.

IO pins

Pin Direction Width Description
WORD_ADDR Input 32 Word index, not byte address
WRITE_DATA Input W Data for the selected word
WRITE_MASK Input W/8 Bit b enables byte b; bit 0 is the least-significant byte
CE_N Input 1 Low selects the device
WE_N Input 1 Low requests writing; high requests reading
OE_N Input 1 Low enables a completed read output
READ_DATA Output W Read result, or Z while disabled/writing/accessing

Behavior

CE_N = 1 disables access without clearing memory. With CE_N = 0, WE_N = 0 writes the enabled bytes after the access phases; WE_N = 1 reads. OE controls only read output. A zero write mask changes no bits. Reads are nondestructive. There is no clock, reset, refresh command, READY handshake, or hardware FAULT pin.

A known out-of-range read returns X after access; an out-of-range write changes no cells. Unknown address/control handling is a simulator rule, not a hardware exception mechanism. Use the SRAM-specific memory controller to connect this native port to the shared transaction protocol.

C++ example

#include <cstddef>
#include <cstdint>
#include <optional>
#include <vector>
template<std::size_t W> struct SRAMReference {
    static_assert(W == 8 || W == 16 || W == 32);
    using Word = std::vector<std::optional<bool>>;
    std::vector<Word> words;
    SRAMControlReference control;
    Word read_data = Word(W);
    bool high_z = true;
    explicit SRAMReference(std::size_t count) : words(count, Word(W)) {}
    void update(std::size_t now, std::size_t ticks, const SRAMControlReference::Inputs& in) {
        const auto previous = control.phase;
        control.update(now, ticks, in);
        const bool valid = control.address < words.size();
        if (previous == SRAMControlReference::Phase::Release &&
            control.phase == SRAMControlReference::Phase::Access && control.write_enable && valid) {
            for (unsigned b = 0; b < W; ++b)
                if (control.mask & (1u << (b / 8)))
                    words[control.address][b] = bool((control.data >> b) & 1u);
        }
        high_z = !control.output_enable;
        read_data = !high_z && valid ? words[control.address] : Word(W);
    }
};

Unknown inputs and timing

The example includes unknown startup, partial initialization, byte masks, output disable, invalid addresses, request cancellation, and access deadlines. high_z distinguishes a disabled output from an enabled unknown word. Its inputs are binary and geometry is prevalidated; unknown write data additionally makes only enabled bits unknown, and unknown byte enables suppress writes to those lanes. Call at input changes and every control.due. Gate propagation is omitted; use at least 4*phase_ticks + 32 ticks for a conservative simulator settling budget.

Implementation

Structural implementation

Combines ACCESS_CONTROL, ROW_DECODE, PRECHARGE, STORAGE, COLUMN_SELECT, W WRITE_DRIVER_b and SENSE_b instances, bus wiring, and OUTPUT. Each SRAMWriteDriver retains its own write-enable/mask gate and complementary data pair: the drive and bitline paths must keep their tested relative timing. Precharge control and repeated column-select complements are shared, while each bitline pair and sense amplifier remains visible. The device expands at most 4096 cells. The default 4×8 example has two rows, 16 bitline pairs, and 32 cells.

Behavioral implementation

The same access sequencer controls a packed, optionally paged MemoryStorage. It preserves native pins and unknown startup without expanding rows/cells. Capacity is bounded by 32-bit byte addressing and explicit allocation/history budgets. Setup image loading is allowed only before simulation starts. Selecting behavioral fidelity at STORAGE instead retains the complete device's visible peripheral circuitry and its small-bank geometry limit.

Examples

All 35 recorded rows of SRAMTest, in checkpoint order. Outputs are test expectations verified against the simulation. Time is the absolute settled checkpoint time in simulator units, not milliseconds or CPU cycles.

Default scenario profile: canonical-default-preview / structural (59857f039337ca4c). Changing fidelity or the circuit can change these times.

Checkpointzero-based number · timeline label Timesimulator units CE_NInput · 1 bit OE_NInput · 1 bit WE_NInput · 1 bit WORD_ADDRInput · 32 bit WRITE_DATAInput · 8 bit WRITE_MASKInput · 1 bit READ_DATAExpected output · 8 bit
#0deselected-startup5 1 0 1 0x00000000 0x00 1 0bZZZZZZZZ
#1unwritten-read135 0 0 1 0x00000000 0x00 1 0bXXXXXXXX
#2setup-word-0139 1 0 1 0x00000000 0x81 1 0bZZZZZZZZ
#3write-word-0268 0 0 0 0x00000000 0x81 1 0bZZZZZZZZ
#4read-word-0399 0 0 1 0x00000000 0x81 1 0x81
#5setup-word-1406 1 0 1 0x00000001 0xE6 1 0bZZZZZZZZ
#6write-word-1535 0 0 0 0x00000001 0xE6 1 0bZZZZZZZZ
#7read-word-1666 0 0 1 0x00000001 0xE6 1 0xE6
#8setup-word-2673 1 0 1 0x00000002 0x4F 1 0bZZZZZZZZ
#9write-word-2802 0 0 0 0x00000002 0x4F 1 0bZZZZZZZZ
#10read-word-2933 0 0 1 0x00000002 0x4F 1 0x4F
#11setup-word-3940 1 0 1 0x00000003 0xB4 1 0bZZZZZZZZ
#12write-word-31069 0 0 0 0x00000003 0xB4 1 0bZZZZZZZZ
#13read-word-31200 0 0 1 0x00000003 0xB4 1 0xB4
#14mask-setup-01207 1 0 1 0x00000000 0x10 0 0bZZZZZZZZ
#15masked-write-01336 0 0 0 0x00000000 0x10 0 0bZZZZZZZZ
#16masked-read-01467 0 0 1 0x00000000 0x10 0 0x81
#17mask-setup-11474 1 0 1 0x00000001 0x55 1 0bZZZZZZZZ
#18masked-write-11603 0 0 0 0x00000001 0x55 1 0bZZZZZZZZ
#19masked-read-11734 0 0 1 0x00000001 0x55 1 0x55
#20disable-output1736 0 1 1 0x00000001 0x55 1 0bZZZZZZZZ
#21read-last-word1867 0 0 1 0x00000003 0x55 1 0xB4
#22ignored-write-inputs-during-read1868 0 0 1 0x00000003 0bXXXXXXXX X 0xB4
#23invalid-read1998 0 0 1 0x00000004 0bXXXXXXXX X 0bXXXXXXXX
#24invalid-write2127 0 0 0 0x00000004 0x00 1 0bZZZZZZZZ
#25end-invalid-write2132 1 0 1 0x00000004 0x00 1 0bZZZZZZZZ
#26readback-02263 0 0 1 0x00000000 0x00 1 0x81
#27readback-12394 0 0 1 0x00000001 0x00 1 0x55
#28readback-22525 0 0 1 0x00000002 0x00 1 0x4F
#29readback-32656 0 0 1 0x00000003 0x00 1 0xB4
#30prepare-unknown-write2663 1 0 1 0x00000000 0bXXXXXXXX 1 0bZZZZZZZZ
#31write-unknown2792 0 0 0 0x00000000 0bXXXXXXXX 1 0bZZZZZZZZ
#32read-unknown2922 0 0 1 0x00000000 0bXXXXXXXX 1 0bXXXXXXXX
#33unknown-address3052 0 0 1 0bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 0bXXXXXXXX 1 0bXXXXXXXX
#34deselect-retains3056 1 0 1 0bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 0bXXXXXXXX 1 0bZZZZZZZZ

Scroll within the table for all rows and pins. Buses use hexadecimal; values containing X/Z use MSB-first binary. Inputs show the declared values in effect at each checkpoint, including retained inputs. Sequential tests also replay preparation changes between checkpoints, such as lowering the clock. Use the matching checkpoint label in the simulation below.

Every recorded row is included: unknown startup, all four addresses, both 8-bit masks, OE disable, ignored read-mode write inputs, invalid accesses, retention readback, unknown writes, and unknown addressing. Wider 16/32-bit masks and other geometries are covered by the contract test.

Embedded simulation

The standalone SRAMTest opens this component as SRAM_ROOT. Use the explorer to compare structural and behavioral fidelity.

Open SRAM<W> in the simulator

Source and tests

Test Coverage
SRAMTest The complete standalone sequence shown above
SRAMContractTest Structural/behavioral equivalence; device and bank widths 8/16/32, multiple geometries and byte masks, mixed bank selection, and invalid configuration rejection
SRAMTimingTest Canceled short writes, incomplete reads, superseded address requests, and eventual event-queue quiescence
DocumentationExamplesTest Compile the exact page snippets; exercise cell/bitline conflicts, bank reads/writes, column routing, masks, cancellation, and deadlines; replay the device scenario's uninterrupted binary-input prefix against recorded outputs