Skip to content

ยง 4.4.4. Memory Access

RV32ISingleCycleMemoryStage formats direct load/store pins and load results. In the core it is named MEMORY. It contains no storage, request registers, clock, or reset state.

These are stage-local pins. The complete core's combinational DATA_PORT converts them to universal REQ/RSP pins for the external zero-wait FF endpoint; it adds no buffering or cycle. The endpoint's controller and native device are outside this stage.

Component Description Structural Behavioral
RV32ISingleCycleMemoryStage Combinational address/lane formatting, alignment check, and commit-gated store enable Yes Yes

4.4.4.1. RV32ISingleCycleMemoryStage

IO pins

Pin Direction Width Description
ISSUE, COMMIT Input 1 each Active memory intent; final permission to commit
MEM_WRITE, SIGN_EXTEND Input 1 each Store direction; signed byte/halfword load
ADDR, WRITE_DATA Input 32 each Effective byte address; unshifted source
SIZE Input 2 0 byte, 1 halfword, 2 word, 3 invalid
DMEM_READ_DATA Input 32 Native word before load-lane selection
DMEM_FAULT Input 1 Native access fault
READ_DATA Output 32 Narrowed and sign/zero-extended load value
DONE, FAULT, MISALIGNED Output 1 each Constant one; native fault; bad alignment or invalid size
DMEM_WORD_ADDR Output 32 ADDR/4 native word index
DMEM_WRITE_DATA Output 32 Source shifted to selected little-endian lanes
DMEM_WRITE_MASK Output 4 Enabled byte lanes
DMEM_READ_EN, DMEM_WE Output 1 each Active access/read check; authorized store enable

Behavior

ADDR[1:0] selects the little-endian byte lane. RV32IMemoryLanes shifts store data, forms the byte mask, and extracts/sign-extends loads. Invalid SIZE=3 gives mask/result zero. Misaligned halfwords/words are reported; there are no split accesses.

DMEM_READ_EN follows ISSUE for both reads and stores. DMEM_WE is ISSUE && MEM_WRITE && COMMIT && !MISALIGNED. In the complete core, ISSUE excludes earlier fetch/decode faults and terminal state, and COMMIT is tied high: the endpoint validates the request and never writes on a fault. Its response must not feed COMMIT, because that would change a rejected write's REQ_OP to read and create a feedback loop. Standalone native-device callers may use COMMIT as an independent store authorization, provided the device rejects invalid writes.

The native memory owns the write clock and captures DMEM_WORD_ADDR/WRITE_DATA/WRITE_MASK on the same rising edge as PC and the register file. Changing this stage's input immediately changes its output after settling: there is no payload capture or response buffer. No store needs its new contents read back to finish.

DONE is constant one because this port has no handshake; it does not detect settling. FAULT follows DMEM_FAULT without ISSUE qualification. The core uses it only for an active memory instruction.

Memory compatibility

The connected core requires MemoryEndpoint<ff,32>: either the fused behavioral form or an FF controller with native FF storage. MemoryContainer<ff,32> supplies scalable storage behind that controller; FFMemory<32> supplies a small expanded circuit. Native devices are not wired directly to the core's universal pins. See the complete-core memory table.

This stage cannot wait for a delayed response: DONE stays one and there is no pending-request state. The current SRAM, DRAM, ROM, and NOR-flash endpoints therefore require a wait-capable core, not just a controller attached to this stage. Construction guards reject them for the single-cycle system; bypassing those guards can produce incorrect execution rather than additional wait cycles.

C++ example

This binary reference reuses only the combinational lane and alignment examples from 4.3.5.

#include <cstdint>
namespace single_cycle_example {
struct MemoryInputs {
    bool ISSUE, COMMIT, MEM_WRITE, SIGN_EXTEND;
    uint32_t ADDR, WRITE_DATA;
    unsigned SIZE;
    uint32_t DMEM_READ_DATA;
    bool DMEM_FAULT;
};
struct MemoryOutputs {
    uint32_t READ_DATA;
    bool DONE, FAULT, MISALIGNED;
    uint32_t DMEM_WORD_ADDR, DMEM_WRITE_DATA;
    unsigned DMEM_WRITE_MASK;
    bool DMEM_READ_EN, DMEM_WE;
};
class Memory {
public:
    MemoryOutputs observe(const MemoryInputs& i) const {
        const auto l=memory_access_example::lanes(i.ADDR,i.WRITE_DATA,i.DMEM_READ_DATA,i.SIZE,i.SIGN_EXTEND);
        const bool bad=i.SIZE==3||memory_access_example::misaligned(i.ADDR,i.SIZE);
        return {l.READ_DATA,true,i.DMEM_FAULT,bad,i.ADDR>>2,l.WORD_WRITE_DATA,l.WRITE_MASK,
                i.ISSUE,i.ISSUE&&i.MEM_WRITE&&i.COMMIT&&!bad};
    }
    MemoryOutputs evaluate(const MemoryInputs& i) { return observe(i); }
};
}

Unknown inputs and timing

The behavioral model preserves each selected load bit and its sign extension, including unknown bits. Unknown neighboring bytes do not invalidate a known byte load. Address, size, and store-data integer conversions are binary abstractions; nonbinary controls/store operands are outside equivalence. Fault bits are forwarded. The catalog-selected stage uses gate-derived output delays; eligible paths can use a delay twin for current values. Neither fidelity adds a clock to this path. Allow the entire load-to-writeback path to settle.

Implementation

Structural implementation

LANES performs byte-lane formatting without constructing an unused guarded word-address output. ALIGNMENT plus SIZE_BITS/INVALID_SIZE rejects bad accesses; MEMORY_PORT forms the word index directly. WRITE_INTENT, ALIGNED, WRITE_ALLOWED, and COMMIT_STORE gate stores, so a bad address cannot write a rounded-down word. Constants drive DONE. There is no REQUEST child.

Behavioral implementation

BehavioralStage's Memory branch evaluates the same combinational logic without MemoryRequestState or owned contents. Both implementations are registered as rv32i.single-cycle.memory.

Examples

Eleven accesses cover signed/unsigned loads, every store width, invalid size, misalignment, and native faults. Each checks direct outputs, commit permission, changed store data without any edge, and disabled access.

All 44 recorded rows of RV32ISingleCycleMemoryStageTest, 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 (7ecc45acd04324df). Changing fidelity or the circuit can change these times.

Checkpointzero-based number ยท timeline label Timesimulator units ADDRInput ยท 32 bit COMMITInput ยท 1 bit DMEM_FAULTInput ยท 1 bit DMEM_READ_DATAInput ยท 32 bit ISSUEInput ยท 1 bit MEM_WRITEInput ยท 1 bit SIGN_EXTENDInput ยท 1 bit SIZEInput ยท 2 bit WRITE_DATAInput ยท 32 bit DMEM_READ_ENExpected output ยท 1 bit DMEM_WEExpected output ยท 1 bit DMEM_WORD_ADDRExpected output ยท 32 bit DMEM_WRITE_DATAExpected output ยท 32 bit DMEM_WRITE_MASKExpected output ยท 4 bit DONEExpected output ยท 1 bit FAULTExpected output ยท 1 bit MISALIGNEDExpected output ยท 1 bit READ_DATAExpected output ยท 32 bit
#0direct-access-010 0x00000101 0 0 0x00008000 1 0 1 0x0 0xDEADBEEF not checked 0 0x00000040 0xADBEEF00 0x2 1 0 0 0xFFFFFF80
#1authorize-013 0x00000101 1 0 0x00008000 1 0 1 0x0 0xDEADBEEF not checked 0 not checked not checked not checked not checked not checked not checked not checked
#2payload-is-not-buffered-019 0x00000101 1 0 0x00008000 1 0 1 0x0 0x00000000 not checked not checked not checked 0x00000000 not checked not checked not checked not checked not checked
#3disabled-021 0x00000101 1 0 0x00008000 0 0 1 0x0 0x00000000 0 0 not checked not checked not checked not checked not checked not checked not checked
#4direct-access-129 0x00000103 0 0 0x80000000 1 0 0 0x0 0xDEADBEEF not checked 0 0x00000040 0xEF000000 0x8 1 0 0 0x00000080
#5authorize-132 0x00000103 1 0 0x80000000 1 0 0 0x0 0xDEADBEEF not checked 0 not checked not checked not checked not checked not checked not checked not checked
#6payload-is-not-buffered-138 0x00000103 1 0 0x80000000 1 0 0 0x0 0x00000000 not checked not checked not checked 0x00000000 not checked not checked not checked not checked not checked
#7disabled-140 0x00000103 1 0 0x80000000 0 0 0 0x0 0x00000000 0 0 not checked not checked not checked not checked not checked not checked not checked
#8direct-access-252 0x00000102 0 0 0x80010000 1 0 1 0x1 0xDEADBEEF not checked 0 0x00000040 0xBEEF0000 0xC 1 0 0 0xFFFF8001
#9authorize-255 0x00000102 1 0 0x80010000 1 0 1 0x1 0xDEADBEEF not checked 0 not checked not checked not checked not checked not checked not checked not checked
#10payload-is-not-buffered-261 0x00000102 1 0 0x80010000 1 0 1 0x1 0x00000000 not checked not checked not checked 0x00000000 not checked not checked not checked not checked not checked
#11disabled-263 0x00000102 1 0 0x80010000 0 0 1 0x1 0x00000000 0 0 not checked not checked not checked not checked not checked not checked not checked
#12direct-access-373 0x00000100 0 0 0x0000FFFE 1 0 0 0x1 0xDEADBEEF not checked 0 0x00000040 0xDEADBEEF 0x3 1 0 0 0x0000FFFE
#13authorize-376 0x00000100 1 0 0x0000FFFE 1 0 0 0x1 0xDEADBEEF not checked 0 not checked not checked not checked not checked not checked not checked not checked
#14payload-is-not-buffered-382 0x00000100 1 0 0x0000FFFE 1 0 0 0x1 0x00000000 not checked not checked not checked 0x00000000 not checked not checked not checked not checked not checked
#15disabled-384 0x00000100 1 0 0x0000FFFE 0 0 0 0x1 0x00000000 0 0 not checked not checked not checked not checked not checked not checked not checked
#16direct-access-493 0x00000100 0 0 0x12345678 1 0 0 0x2 0xDEADBEEF not checked 0 0x00000040 0xDEADBEEF 0xF 1 0 0 0x12345678
#17authorize-496 0x00000100 1 0 0x12345678 1 0 0 0x2 0xDEADBEEF not checked 0 not checked not checked not checked not checked not checked not checked not checked
#18payload-is-not-buffered-4102 0x00000100 1 0 0x12345678 1 0 0 0x2 0x00000000 not checked not checked not checked 0x00000000 not checked not checked not checked not checked not checked
#19disabled-4104 0x00000100 1 0 0x12345678 0 0 0 0x2 0x00000000 0 0 not checked not checked not checked not checked not checked not checked not checked
#20direct-access-5114 0x00000102 0 0 0x00000000 1 1 0 0x0 0xDEADBEEF not checked 0 0x00000040 0xBEEF0000 0x4 1 0 0 0x00000000
#21authorize-5117 0x00000102 1 0 0x00000000 1 1 0 0x0 0xDEADBEEF not checked 1 not checked not checked not checked not checked not checked not checked not checked
#22payload-is-not-buffered-5123 0x00000102 1 0 0x00000000 1 1 0 0x0 0x00000000 not checked not checked not checked 0x00000000 not checked not checked not checked not checked not checked
#23disabled-5126 0x00000102 1 0 0x00000000 0 1 0 0x0 0x00000000 0 0 not checked not checked not checked not checked not checked not checked not checked
#24direct-access-6132 0x00000102 0 0 0x00000000 1 1 0 0x1 0xDEADBEEF not checked 0 0x00000040 0xBEEF0000 0xC 1 0 0 0x00000000
#25authorize-6135 0x00000102 1 0 0x00000000 1 1 0 0x1 0xDEADBEEF not checked 1 not checked not checked not checked not checked not checked not checked not checked
#26payload-is-not-buffered-6141 0x00000102 1 0 0x00000000 1 1 0 0x1 0x00000000 not checked not checked not checked 0x00000000 not checked not checked not checked not checked not checked
#27disabled-6144 0x00000102 1 0 0x00000000 0 1 0 0x1 0x00000000 0 0 not checked not checked not checked not checked not checked not checked not checked
#28direct-access-7152 0x00000100 0 0 0x00000000 1 1 0 0x2 0xDEADBEEF not checked 0 0x00000040 0xDEADBEEF 0xF 1 0 0 0x00000000
#29authorize-7155 0x00000100 1 0 0x00000000 1 1 0 0x2 0xDEADBEEF not checked 1 not checked not checked not checked not checked not checked not checked not checked
#30payload-is-not-buffered-7161 0x00000100 1 0 0x00000000 1 1 0 0x2 0x00000000 not checked not checked not checked 0x00000000 not checked not checked not checked not checked not checked
#31disabled-7164 0x00000100 1 0 0x00000000 0 1 0 0x2 0x00000000 0 0 not checked not checked not checked not checked not checked not checked not checked
#32direct-access-8172 0x00000102 0 1 0x00000000 1 1 0 0x2 0xDEADBEEF not checked 0 0x00000040 0xBEEF0000 0xF 1 1 1 0x00000000
#33authorize-8173 0x00000102 0 1 0x00000000 1 1 0 0x2 0xDEADBEEF not checked 0 not checked not checked not checked not checked not checked not checked not checked
#34payload-is-not-buffered-8179 0x00000102 0 1 0x00000000 1 1 0 0x2 0x00000000 not checked not checked not checked 0x00000000 not checked not checked not checked not checked not checked
#35disabled-8182 0x00000102 0 1 0x00000000 0 1 0 0x2 0x00000000 0 0 not checked not checked not checked not checked not checked not checked not checked
#36direct-access-9188 0x00000100 0 1 0x00000000 1 0 0 0x3 0xDEADBEEF not checked 0 0x00000040 0xDEADBEEF 0x0 1 1 1 0x00000000
#37authorize-9189 0x00000100 0 1 0x00000000 1 0 0 0x3 0xDEADBEEF not checked 0 not checked not checked not checked not checked not checked not checked not checked
#38payload-is-not-buffered-9195 0x00000100 0 1 0x00000000 1 0 0 0x3 0x00000000 not checked not checked not checked 0x00000000 not checked not checked not checked not checked not checked
#39disabled-9197 0x00000100 0 1 0x00000000 0 0 0 0x3 0x00000000 0 0 not checked not checked not checked not checked not checked not checked not checked
#40direct-access-10203 0x00000100 0 1 0x00000000 1 0 0 0x2 0xDEADBEEF not checked 0 0x00000040 0xDEADBEEF 0xF 1 1 0 0x00000000
#41authorize-10204 0x00000100 0 1 0x00000000 1 0 0 0x2 0xDEADBEEF not checked 0 not checked not checked not checked not checked not checked not checked not checked
#42payload-is-not-buffered-10210 0x00000100 0 1 0x00000000 1 0 0 0x2 0x00000000 not checked not checked not checked 0x00000000 not checked not checked not checked not checked not checked
#43disabled-10212 0x00000100 0 1 0x00000000 0 0 0 0x2 0x00000000 0 0 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.

Embedded simulation

Open Memory stage

Tests

RV32ISingleCycleMemoryStageTest compares both implementations. RV32ISingleCycleStageIntegrationTest checks old-source loads/stores with at most one cycle per instruction. RV32ISingleCycleDocumentationTest.py executes the exact C++ example. Sources: RV32ISingleCycleStages.cpp, RV32ISingleCycleStagesBehavioral.cpp, and RV32ISingleCycleStageTests.cpp.