§ 4.5.5. Memory Access¶
RV32IBaselineMemoryStage adapts the EX/MEM packet to stage-local word-addressed memory pins. The complete core's combinational DATA_PORT converts these pins to the universal interface of an external zero-wait FF endpoint. The stage contains neither storage nor a pending transaction. EX/MEM and MEM/WB are the only surrounding instruction buffers.
| Component | Description | Structural | Behavioral |
|---|---|---|---|
RV32IBaselineMemoryStage |
Direct load/store lanes, access qualification, MEM/WB packet | Yes | Yes |
IO pins¶
| Pin | Direction | Width | Description |
|---|---|---|---|
IN_VALID |
Input | 1 | EX/MEM validity |
IN_PC, IN_INSTRUCTION, IN_ALU_RESULT, IN_STORE_DATA, IN_PC_PLUS_4, IN_NEXT_PC, IN_CONTROL, IN_REGISTER_ADDRESSES, IN_FETCH_STATUS, IN_EXECUTION_STATUS |
Input | 32 each | EX/MEM payload |
MEMORY_ENABLE |
Input | 1 | Global execution and older-WB-terminal permission |
DMEM_READ_DATA, DMEM_FAULT |
Input | 32, 1 | Native word and combinational access fault |
DMEM_WORD_ADDR, DMEM_WRITE_DATA |
Output | 32 each | Word index and aligned write lanes |
DMEM_WRITE_MASK |
Output | 4 | Byte enables |
DMEM_READ_EN, DMEM_WE |
Output | 1 each | Direct read enable; authorize store at memory's next rising edge |
OUT_VALID |
Output | 1 | Forwarded validity |
OUT_<field> |
Output | 32 each | All EX/MEM fields above forwarded under the OUT prefix |
OUT_MEMORY_DATA, OUT_MEMORY_STATUS |
Output | 32 each | Extended load data; bit 0 misalignment, bit 1 access fault |
TERMINAL |
Output | 1 | Valid incoming terminal reason or eligible memory error |
Behavior¶
A memory operation is eligible only when IN_VALID is one, decode requests a load/store, and no earlier terminal reason accompanies that instruction. READ_EN is MEMORY_ENABLE && eligible. Stores also enable the read/access check so range faults are known before the write edge.
Byte addressing becomes WORD_ADDR=ALU_RESULT>>2. Byte offset selects and extends load lanes, shifts STORE_DATA, and forms WRITE_MASK. Loads support signed/unsigned bytes and halfwords, plus words. Misaligned halfword/word accesses and reserved size 3 are rejected. The original byte address remains in the packet for retirement.
WE additionally requires a store and valid alignment/size. It denotes the requested operation, not successful completion: the endpoint rejects an invalid store without modifying memory. Response faults affect terminal status but never feed back into WE or the request opcode. MEMORY_ENABLE=0 suppresses both read and write enables. Packet forwarding and lane calculation remain combinational; this input is not a request handshake or a packet register enable.
MEMORY_STATUS qualifies data errors by operation eligibility. A prior instruction fault takes precedence and suppresses the memory operation. The stage reports terminal status immediately to pipeline control; the fault becomes architectural only when this instruction reaches Writeback.
Memory compatibility¶
Use MemoryEndpoint<ff,32>, either fused behavioral or a visible FF controller plus native FF storage. The latter can use scalable MemoryContainer<ff,32> or a small cell-expanded FFMemory<32>. The complete-core memory table lists the supported assemblies and construction restrictions.
The surrounding EX/MEM and MEM/WB registers do not by themselves add memory-wait support. This baseline's control stalls for register dependencies and branches, not delayed REQ_READY/RSP_VALID. The current SRAM, DRAM, ROM, and NOR-flash endpoints are therefore unsuitable: a delayed load could reach MEM/WB with stale data if custom wiring bypassed the program root's non-FF guard. Use the transaction-capable RV32IFiveStageCore for those endpoints.
C++ example¶
early_terminal is the shared check for valid fetch/decode/target faults and halt. The returned packet forwards all incoming fields and adds loaded data/status. An endpoint stores bytes on its own rising edge only when we requests a valid, accepted store; an error response performs no write. This function itself stores nothing.
struct MemoryResult {
Packet packet; bool terminal;
uint32_t word_addr, write_data; unsigned write_mask;
bool read_en, we;
};
inline MemoryResult memory(Packet p,bool enable,uint32_t read_word,bool fault) {
const bool early=early_terminal(p);
const bool read=bits(p.control,2,1),write=bits(p.control,3,1),sign=bits(p.control,4,1);
const auto size=bits(p.control,11,3),offset=p.alu_result&3;
const bool eligible=p.valid&&!early&&(read||write);
const bool bad=size==3||(size==1&&(offset&1))||(size==2&&offset);
uint32_t value=read_word>>(8*offset);
if(size==0) {value&=255; if(sign&&(value&128)) value|=0xffffff00u;}
else if(size==1) {value&=65535; if(sign&&(value&32768)) value|=0xffff0000u;}
else if(size==3) value=0;
p.memory_data=value;
p.memory_status=eligible?(uint32_t(bad)|(uint32_t(fault)<<1)):0;
const unsigned mask=size==0?1u<<offset:size==1?(3u<<offset)&15:size==2?15:0;
return {p,early||(eligible&&(bad||fault)),p.alu_result>>2,p.store_data<<(8*offset),mask,
enable&&eligible,enable&&eligible&&write&&!bad};
}
Implementation¶
Structural implementation¶
ACCESS reuses RV32ISingleCycleMemoryStage, which groups RV32IMemoryLanes and alignment checking. PACKET_STATUS groups incoming terminal-reason checks. Packet/status rewires and eligibility/fault gates surround the combinational access path. There is no REQUEST, pending flag, or duplicate memory device.
Behavioral implementation¶
memoryPacket computes the same binary lane mappings, permission signals, and status. The registered family is rv32i.baseline.memory. The complete core connects to an external FF endpoint: an FF controller plus a native FF device, or their fused behavioral implementation. It shares the CPU clock and adds no wait cycle.
Examples¶
The test includes signed byte extraction, byte/word stores, alignment/access faults, an older terminal instruction disabling memory, and invalid packet suppression.
All 9 recorded rows of RV32IBaselineMemoryStageTest, 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: baseline-structural-stages / structural (f72af366c5dca6eb). Changing fidelity or the circuit can change these times.
| Checkpointzero-based number · timeline label | Timesimulator units | DMEM_FAULTInput · 1 bit |
DMEM_READ_DATAInput · 32 bit |
IN_ALU_RESULTInput · 32 bit |
IN_CONTROLInput · 32 bit |
IN_EXECUTION_STATUSInput · 32 bit |
IN_FETCH_STATUSInput · 32 bit |
IN_INSTRUCTIONInput · 32 bit |
IN_NEXT_PCInput · 32 bit |
IN_PCInput · 32 bit |
IN_PC_PLUS_4Input · 32 bit |
IN_REGISTER_ADDRESSESInput · 32 bit |
IN_STORE_DATAInput · 32 bit |
IN_VALIDInput · 1 bit |
MEMORY_ENABLEInput · 1 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 |
OUT_ALU_RESULTExpected output · 32 bit |
OUT_CONTROLExpected output · 32 bit |
OUT_EXECUTION_STATUSExpected output · 32 bit |
OUT_FETCH_STATUSExpected output · 32 bit |
OUT_INSTRUCTIONExpected output · 32 bit |
OUT_MEMORY_DATAExpected output · 32 bit |
OUT_MEMORY_STATUSExpected output · 32 bit |
OUT_NEXT_PCExpected output · 32 bit |
OUT_PCExpected output · 32 bit |
OUT_PC_PLUS_4Expected output · 32 bit |
OUT_REGISTER_ADDRESSESExpected output · 32 bit |
OUT_STORE_DATAExpected output · 32 bit |
OUT_VALIDExpected output · 1 bit |
TERMINALExpected output · 1 bit |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
#0initial-inputs | 9 | 0 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
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 |
#1lb | 20 | 0 |
0x00008000 |
0x00000101 |
0x20000497 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
1 |
1 |
1 |
0 |
0x00000040 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | 0xFFFFFF80 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | 0 |
#2sb | 26 | 0 |
0x00008000 |
0x00000101 |
0x20000189 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x000000A5 |
1 |
1 |
not checked | 1 |
not checked | 0x0000A500 |
0x2 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked |
#3endpoint-rejects-write | 29 | 1 |
0x00008000 |
0x00000101 |
0x20000189 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x000000A5 |
1 |
1 |
not checked | 1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | 0x00000002 |
not checked | not checked | not checked | not checked | not checked | not checked | 1 |
#4misaligned-sw | 37 | 0 |
0x00008000 |
0x00000101 |
0x20001189 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x000000A5 |
1 |
1 |
not checked | 0 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | 0x00000001 |
not checked | not checked | not checked | not checked | not checked | not checked | 1 |
#5aligned-sw | 48 | 0 |
0x00008000 |
0x00000100 |
0x20001189 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x000000A5 |
1 |
1 |
not checked | 1 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | 0x00000000 |
not checked | not checked | not checked | not checked | not checked | not checked | 0 |
#6older-terminal-blocks-store | 52 | 0 |
0x00008000 |
0x00000100 |
0x20001189 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x000000A5 |
1 |
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 |
#7fetch-fault-blocks-memory | 63 | 0 |
0x00008000 |
0x00000100 |
0x20001189 |
0x00000000 |
0x00000002 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x000000A5 |
1 |
1 |
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 | 1 |
#8bubble-has-no-effects | 67 | 0 |
0x00008000 |
0x00000100 |
0x20001189 |
0x00000000 |
0x00000002 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x000000A5 |
0 |
1 |
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 | 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.
Tests¶
RV32IBaselineMemoryStageTest compares both implementations. Program tests check retired memory effects against the instruction reference and independently verify the physical write history. Sources: RV32IBaselinePipeline.cpp, RV32IBaselinePipelineBehavioral.cpp.