Skip to content

§ 4.5.1. Pipeline Registers

Pipeline registers hold instruction packets, not architectural registers. Baseline and advanced cores use the same four register families.

Component Description Structural Behavioral
RV32IIFIDPipelineRegister Fetch → Decode packet Yes Yes
RV32IIDEXPipelineRegister Decode → Execute packet Yes Yes
RV32IEXMEMPipelineRegister Execute → Memory packet Yes Yes
RV32IMEMWBPipelineRegister Memory → Writeback packet Yes Yes

IO pins

Pin Direction Width Description
CLK, RST Input 1 each Rising-edge capture; asynchronous active-high reset
WRITE_ENABLE Input 1 Capture when one; hold when zero
FLUSH Input 1 Capture a bubble when WRITE_ENABLE is one
D_VALID Input 1 Incoming instruction validity
D_<field> Input 32 each Incoming payload fields listed below
Q_VALID Output 1 Stored instruction validity
Q_<field> Output 32 each Stored payload fields
Register Payload fields
IF/ID PC, INSTRUCTION, FETCH_STATUS
ID/EX IF/ID fields plus RS1_VALUE, RS2_VALUE, IMMEDIATE, CONTROL, REGISTER_ADDRESSES
EX/MEM PC, INSTRUCTION, ALU_RESULT, STORE_DATA, PC_PLUS_4, NEXT_PC, CONTROL, REGISTER_ADDRESSES, FETCH_STATUS, EXECUTION_STATUS
MEM/WB EX/MEM fields plus MEMORY_DATA, MEMORY_STATUS

Behavior

Reset clears all fields and validity. A rising edge with WRITE_ENABLE=1 captures every payload field and sets Q_VALID to D_VALID && !FLUSH. With WRITE_ENABLE=0, FLUSH does not override the hold. A bubble's payload is not necessarily zero; downstream side effects must be gated by validity.

Advance, hold, and bubble

With reset inactive, the following actions occur at a rising edge:

WRITE_ENABLE FLUSH Action
0 0 or 1 Hold: retain both the current payload and its validity
1 0 Advance: capture the incoming payload and D_VALID; an invalid input remains a bubble
1 1 Bubble: capture the incoming payload but force Q_VALID=0

The clock continues running during a pipeline stall. The controller can hold one register while allowing others to advance. For example, a data hazard holds IF/ID so its instruction stays in Decode, while ID/EX receives a bubble and older instructions advance through EX/MEM and MEM/WB. See the cycle-by-cycle hazard and jump examples.

C++ example

N is the number of 32-bit payload fields in the table. This reference includes capture, hold, reset, and bubble behavior; reset before use.

#include <array>
#include <cstdint>
template<unsigned N> struct PipelineRegister {
    bool valid=false, previous_clock=false;
    std::array<uint32_t,N> payload{};
    void evaluate(bool clk, bool reset, bool enable, bool flush,
                  bool incoming_valid, const std::array<uint32_t,N>& incoming) {
        if(reset) { valid=false; payload.fill(0); }
        else if(!previous_clock && clk && enable) {
            payload=incoming;
            valid=incoming_valid && !flush;
        }
        previous_clock=clk;
    }
};

Packet encodings

The public pins are 32-bit wiring bundles, not additional ISA registers. Standalone packet components retain all 32 bits supplied at their inputs. Core instances use a compact internal schema because the stage producers define only the fields below.

CONTROL bits Meaning
0, 1, 2, 3, 4 LEGAL, REG_WRITE, MEM_READ, MEM_WRITE, LOAD_SIGN_EXTEND
5, 6, 7, 8 HALT_REQUEST, TRAP_REQUEST, USES_RS1, USES_RS2
10:9, 12:11 WRITEBACK_SEL, MEM_SIZE
15:13, 17:16 BRANCH_TYPE, JUMP_TYPE
21:18, 26:22 DECODE_TRAP_CAUSE, ALU_OP
28:27, 30:29 ALU_A_SEL, ALU_B_SEL
31 Reserved

Values of these fields are the decoder's encodings. REGISTER_ADDRESSES stores RS1 in bits 4:0, RS2 in 9:5, and RD in 14:10. The other bits are reserved.

Status word Defined bits
FETCH_STATUS 0: PC misaligned; 1: instruction access fault
EXECUTION_STATUS 0: selected branch/jump target misaligned
MEMORY_STATUS 0: data misaligned; 1: data access fault

Implementation

Structural implementation

Full-width payloads use Register<32>. In core instances, FETCH_STATUS and MEMORY_STATUS use two storage bits, EXECUTION_STATUS uses one, and CONTROL uses 31. REGISTER_ADDRESSES stores three 5-bit fields through ID/EX and only the RD field in EX/MEM and MEM/WB. Split/join rewires maintain the public 32-bit pins and fill unused output bits with zero. A FlipFlopCell stores validity, with reset/enable/flush qualification. Standalone packet instances use full-width registers for every payload field, including inputs with reserved bits set.

Behavioral implementation

RV32IPipelineRegisterBehavioral models known clock edges, hold, flush, reset, and four-state capture. When a write control is uncertain, a stored bit stays zero only if both its held and incoming values are zero; every other pair becomes X, including two ones. With the compact core schema, it zeros unstored bits at capture and preserves the same 32-bit observable packet as the structural implementation. Standalone instances retain arbitrary input bits.

Examples

Each register has its own complete checkpoint table and simulation.

All 7 recorded rows of RV32IIFIDPipelineRegisterTest, 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: rv32i-component-preview-preview / structural (08cc3e83d3dde828). Changing fidelity or the circuit can change these times.

Checkpointzero-based number · timeline label Timesimulator units CLKInput · 1 bit D_FETCH_STATUSInput · 32 bit D_INSTRUCTIONInput · 32 bit D_PCInput · 32 bit D_VALIDInput · 1 bit FLUSHInput · 1 bit RSTInput · 1 bit WRITE_ENABLEInput · 1 bit Q_FETCH_STATUSExpected output · 32 bit Q_INSTRUCTIONExpected output · 32 bit Q_PCExpected output · 32 bit Q_VALIDExpected output · 1 bit
#0reset4 0 0x00000012 0x00000011 0x00000010 0 0 1 0 0x00000000 0x00000000 0x00000000 0
#1prepare-first-payload6 0 0x00000102 0x00000101 0x00000100 1 0 0 1 0x00000000 0x00000000 0x00000000 0
#2capture-first-payload11 1 0x00000102 0x00000101 0x00000100 1 0 0 1 0x00000102 0x00000101 0x00000100 1
#3hold-with-write-disabled18 1 0x00000202 0x00000201 0x00000200 0 0 0 0 0x00000102 0x00000101 0x00000100 1
#4flush-invalidates-entry26 1 0x00000302 0x00000301 0x00000300 1 1 0 1 0x00000302 0x00000301 0x00000300 0
#5capture-after-flush34 1 0x00000402 0x00000401 0x00000400 1 0 0 1 0x00000402 0x00000401 0x00000400 1
#6asynchronous-reset-recovery39 1 0x00000402 0x00000401 0x00000400 1 0 1 1 0x00000000 0x00000000 0x00000000 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.

All 7 recorded rows of RV32IIDEXPipelineRegisterTest, 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: rv32i-component-preview-preview / structural (08cc3e83d3dde828). Changing fidelity or the circuit can change these times.

Checkpointzero-based number · timeline label Timesimulator units CLKInput · 1 bit D_CONTROLInput · 32 bit D_FETCH_STATUSInput · 32 bit D_IMMEDIATEInput · 32 bit D_INSTRUCTIONInput · 32 bit D_PCInput · 32 bit D_REGISTER_ADDRESSESInput · 32 bit D_RS1_VALUEInput · 32 bit D_RS2_VALUEInput · 32 bit D_VALIDInput · 1 bit FLUSHInput · 1 bit RSTInput · 1 bit WRITE_ENABLEInput · 1 bit Q_CONTROLExpected output · 32 bit Q_FETCH_STATUSExpected output · 32 bit Q_IMMEDIATEExpected output · 32 bit Q_INSTRUCTIONExpected output · 32 bit Q_PCExpected output · 32 bit Q_REGISTER_ADDRESSESExpected output · 32 bit Q_RS1_VALUEExpected output · 32 bit Q_RS2_VALUEExpected output · 32 bit Q_VALIDExpected output · 1 bit
#0reset4 0 0x00000015 0x00000017 0x00000014 0x00000011 0x00000010 0x00000016 0x00000012 0x00000013 0 0 1 0 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0
#1prepare-first-payload6 0 0x00000105 0x00000107 0x00000104 0x00000101 0x00000100 0x00000106 0x00000102 0x00000103 1 0 0 1 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0
#2capture-first-payload11 1 0x00000105 0x00000107 0x00000104 0x00000101 0x00000100 0x00000106 0x00000102 0x00000103 1 0 0 1 0x00000105 0x00000107 0x00000104 0x00000101 0x00000100 0x00000106 0x00000102 0x00000103 1
#3hold-with-write-disabled18 1 0x00000205 0x00000207 0x00000204 0x00000201 0x00000200 0x00000206 0x00000202 0x00000203 0 0 0 0 0x00000105 0x00000107 0x00000104 0x00000101 0x00000100 0x00000106 0x00000102 0x00000103 1
#4flush-invalidates-entry26 1 0x00000305 0x00000307 0x00000304 0x00000301 0x00000300 0x00000306 0x00000302 0x00000303 1 1 0 1 0x00000305 0x00000307 0x00000304 0x00000301 0x00000300 0x00000306 0x00000302 0x00000303 0
#5capture-after-flush34 1 0x00000405 0x00000407 0x00000404 0x00000401 0x00000400 0x00000406 0x00000402 0x00000403 1 0 0 1 0x00000405 0x00000407 0x00000404 0x00000401 0x00000400 0x00000406 0x00000402 0x00000403 1
#6asynchronous-reset-recovery39 1 0x00000405 0x00000407 0x00000404 0x00000401 0x00000400 0x00000406 0x00000402 0x00000403 1 0 1 1 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 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.

All 7 recorded rows of RV32IEXMEMPipelineRegisterTest, 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: rv32i-component-preview-preview / structural (08cc3e83d3dde828). Changing fidelity or the circuit can change these times.

Checkpointzero-based number · timeline label Timesimulator units CLKInput · 1 bit D_ALU_RESULTInput · 32 bit D_CONTROLInput · 32 bit D_EXECUTION_STATUSInput · 32 bit D_FETCH_STATUSInput · 32 bit D_INSTRUCTIONInput · 32 bit D_NEXT_PCInput · 32 bit D_PCInput · 32 bit D_PC_PLUS_4Input · 32 bit D_REGISTER_ADDRESSESInput · 32 bit D_STORE_DATAInput · 32 bit D_VALIDInput · 1 bit FLUSHInput · 1 bit RSTInput · 1 bit WRITE_ENABLEInput · 1 bit Q_ALU_RESULTExpected output · 32 bit Q_CONTROLExpected output · 32 bit Q_EXECUTION_STATUSExpected output · 32 bit Q_FETCH_STATUSExpected output · 32 bit Q_INSTRUCTIONExpected output · 32 bit Q_NEXT_PCExpected output · 32 bit Q_PCExpected output · 32 bit Q_PC_PLUS_4Expected output · 32 bit Q_REGISTER_ADDRESSESExpected output · 32 bit Q_STORE_DATAExpected output · 32 bit Q_VALIDExpected output · 1 bit
#0reset4 0 0x00000012 0x00000016 0x00000019 0x00000018 0x00000011 0x00000015 0x00000010 0x00000014 0x00000017 0x00000013 0 0 1 0 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0
#1prepare-first-payload6 0 0x00000102 0x00000106 0x00000109 0x00000108 0x00000101 0x00000105 0x00000100 0x00000104 0x00000107 0x00000103 1 0 0 1 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0
#2capture-first-payload11 1 0x00000102 0x00000106 0x00000109 0x00000108 0x00000101 0x00000105 0x00000100 0x00000104 0x00000107 0x00000103 1 0 0 1 0x00000102 0x00000106 0x00000109 0x00000108 0x00000101 0x00000105 0x00000100 0x00000104 0x00000107 0x00000103 1
#3hold-with-write-disabled18 1 0x00000202 0x00000206 0x00000209 0x00000208 0x00000201 0x00000205 0x00000200 0x00000204 0x00000207 0x00000203 0 0 0 0 0x00000102 0x00000106 0x00000109 0x00000108 0x00000101 0x00000105 0x00000100 0x00000104 0x00000107 0x00000103 1
#4flush-invalidates-entry26 1 0x00000302 0x00000306 0x00000309 0x00000308 0x00000301 0x00000305 0x00000300 0x00000304 0x00000307 0x00000303 1 1 0 1 0x00000302 0x00000306 0x00000309 0x00000308 0x00000301 0x00000305 0x00000300 0x00000304 0x00000307 0x00000303 0
#5capture-after-flush34 1 0x00000402 0x00000406 0x00000409 0x00000408 0x00000401 0x00000405 0x00000400 0x00000404 0x00000407 0x00000403 1 0 0 1 0x00000402 0x00000406 0x00000409 0x00000408 0x00000401 0x00000405 0x00000400 0x00000404 0x00000407 0x00000403 1
#6asynchronous-reset-recovery39 1 0x00000402 0x00000406 0x00000409 0x00000408 0x00000401 0x00000405 0x00000400 0x00000404 0x00000407 0x00000403 1 0 1 1 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 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.

All 7 recorded rows of RV32IMEMWBPipelineRegisterTest, 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: rv32i-component-preview-preview / structural (08cc3e83d3dde828). Changing fidelity or the circuit can change these times.

Checkpointzero-based number · timeline label Timesimulator units CLKInput · 1 bit D_ALU_RESULTInput · 32 bit D_CONTROLInput · 32 bit D_EXECUTION_STATUSInput · 32 bit D_FETCH_STATUSInput · 32 bit D_INSTRUCTIONInput · 32 bit D_MEMORY_DATAInput · 32 bit D_MEMORY_STATUSInput · 32 bit D_NEXT_PCInput · 32 bit D_PCInput · 32 bit D_PC_PLUS_4Input · 32 bit D_REGISTER_ADDRESSESInput · 32 bit D_STORE_DATAInput · 32 bit D_VALIDInput · 1 bit FLUSHInput · 1 bit RSTInput · 1 bit WRITE_ENABLEInput · 1 bit Q_ALU_RESULTExpected output · 32 bit Q_CONTROLExpected output · 32 bit Q_EXECUTION_STATUSExpected output · 32 bit Q_FETCH_STATUSExpected output · 32 bit Q_INSTRUCTIONExpected output · 32 bit Q_MEMORY_DATAExpected output · 32 bit Q_MEMORY_STATUSExpected output · 32 bit Q_NEXT_PCExpected output · 32 bit Q_PCExpected output · 32 bit Q_PC_PLUS_4Expected output · 32 bit Q_REGISTER_ADDRESSESExpected output · 32 bit Q_STORE_DATAExpected output · 32 bit Q_VALIDExpected output · 1 bit
#0reset4 0 0x00000012 0x00000017 0x0000001A 0x00000019 0x00000011 0x00000013 0x0000001B 0x00000016 0x00000010 0x00000015 0x00000018 0x00000014 0 0 1 0 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0
#1prepare-first-payload6 0 0x00000102 0x00000107 0x0000010A 0x00000109 0x00000101 0x00000103 0x0000010B 0x00000106 0x00000100 0x00000105 0x00000108 0x00000104 1 0 0 1 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0
#2capture-first-payload11 1 0x00000102 0x00000107 0x0000010A 0x00000109 0x00000101 0x00000103 0x0000010B 0x00000106 0x00000100 0x00000105 0x00000108 0x00000104 1 0 0 1 0x00000102 0x00000107 0x0000010A 0x00000109 0x00000101 0x00000103 0x0000010B 0x00000106 0x00000100 0x00000105 0x00000108 0x00000104 1
#3hold-with-write-disabled18 1 0x00000202 0x00000207 0x0000020A 0x00000209 0x00000201 0x00000203 0x0000020B 0x00000206 0x00000200 0x00000205 0x00000208 0x00000204 0 0 0 0 0x00000102 0x00000107 0x0000010A 0x00000109 0x00000101 0x00000103 0x0000010B 0x00000106 0x00000100 0x00000105 0x00000108 0x00000104 1
#4flush-invalidates-entry26 1 0x00000302 0x00000307 0x0000030A 0x00000309 0x00000301 0x00000303 0x0000030B 0x00000306 0x00000300 0x00000305 0x00000308 0x00000304 1 1 0 1 0x00000302 0x00000307 0x0000030A 0x00000309 0x00000301 0x00000303 0x0000030B 0x00000306 0x00000300 0x00000305 0x00000308 0x00000304 0
#5capture-after-flush34 1 0x00000402 0x00000407 0x0000040A 0x00000409 0x00000401 0x00000403 0x0000040B 0x00000406 0x00000400 0x00000405 0x00000408 0x00000404 1 0 0 1 0x00000402 0x00000407 0x0000040A 0x00000409 0x00000401 0x00000403 0x0000040B 0x00000406 0x00000400 0x00000405 0x00000408 0x00000404 1
#6asynchronous-reset-recovery39 1 0x00000402 0x00000407 0x0000040A 0x00000409 0x00000401 0x00000403 0x0000040B 0x00000406 0x00000400 0x00000405 0x00000408 0x00000404 1 0 1 1 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 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

RV32IIFIDPipelineRegisterTest, RV32IIDEXPipelineRegisterTest, RV32IEXMEMPipelineRegisterTest, and RV32IMEMWBPipelineRegisterTest compare both implementations. RV32IBaselinePipelineCoreTest checks overlap, global pause, drain, and reset with these registers connected. Sources: RV32IPipelineRegisters.hpp/.cpp.