Skip to content

§ 4.4.6. Next PC

RV32ISingleCycleNextPCStage chooses fallthrough or a control-transfer target and reports a selected target's alignment. In the core it is named NEXT_PC. The PC register itself belongs to Fetch.

Component Description Structural Behavioral
RV32ISingleCycleNextPCStage Next-address selection and qualified target-alignment check Yes Yes

4.4.6.1. RV32ISingleCycleNextPCStage

IO pins

Pin Direction Width Description
PC_PLUS_4 Input 32 Fallthrough address from Fetch
CONTROL_TARGET Input 32 Branch/JAL/JALR candidate from Execute
BRANCH_TAKEN Input 1 Selected branch condition
JUMP_TYPE Input 2 Any nonzero code requests a transfer
NEXT_PC Output 32 Transfer target if taken, otherwise PC_PLUS_4
TARGET_MISALIGNED Output 1 Selected transfer target has either low address bit set

Behavior

taken = BRANCH_TAKEN OR (JUMP_TYPE != 0). NEXT_PC selects CONTROL_TARGET when taken and PC_PLUS_4 otherwise. TARGET_MISALIGNED is taken AND ((CONTROL_TARGET & 3) != 0).

A misaligned candidate does not trap when a branch is not taken. This stage does not check the current PC, recalculate a target, or mask JALR bit 0: Fetch checks the current PC and Execute masks the JALR target. Clearing JALR bit 0 can still leave bit 1 set, which is misaligned for the project's four-byte instructions.

The two-bit code 3 also selects a transfer, although the decoder never emits it and Execute supplies target zero for it. No instruction legality or PC-write authorization is inferred here. Even a misaligned selected target appears on NEXT_PC; execution status suppresses PC capture and records the fault.

C++ example

#include <cstdint>
namespace single_cycle_example {
struct NextPCInputs {
    uint32_t PC_PLUS_4, CONTROL_TARGET;
    bool BRANCH_TAKEN;
    unsigned JUMP_TYPE;
};
struct NextPCOutputs { uint32_t NEXT_PC; bool TARGET_MISALIGNED; };
NextPCOutputs next_pc(const NextPCInputs& i) {
    const bool taken=i.BRANCH_TAKEN || i.JUMP_TYPE!=0;
    return {taken ? i.CONTROL_TARGET : i.PC_PLUS_4,
            taken && (i.CONTROL_TARGET&3)!=0};
}
}

Unknown inputs and timing

The structural implementation follows its OR/AND gates, mux, and alignment checker. The behavioral implementation emits X on both outputs if JUMP_TYPE or BRANCH_TAKEN is nonbinary. With known controls it forwards the selected data vector; TARGET_MISALIGNED is zero for an unselected transfer, or X if the selected target word contains any nonbinary bit. Structural alignment only depends on the low two target bits. Equivalence is binary settled behavior, not identical X/Z resolution or path timing. There is no stored state.

Implementation

Structural implementation

JUMP_BITS splits the jump code, JUMPING ORs its bits, and TAKEN includes the branch condition. NEXT_PC_SELECT selects the word. TARGET_LOW_BITS extracts target bits 0 and 1; TARGET_UNALIGNED ORs them and TAKEN_MISALIGNED qualifies the check. Instruction alignment is fixed at four bytes, so no general data-size decoder is needed. These seven children contain no PC register or adder.

Behavioral implementation

BehavioralStage's NextPC branch computes selection and qualified alignment directly. Catalog selection attaches output delays characterized from the structural selection and alignment circuit. The family is rv32i.single-cycle.next-pc.

Examples

All four jump codes, both branch values, and three targets are combined into 24 rows. In particular, target 0x102 faults only when selected; 0x100 and 0xFFFFFFFC are aligned.

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

Checkpointzero-based number · timeline label Timesimulator units BRANCH_TAKENInput · 1 bit CONTROL_TARGETInput · 32 bit JUMP_TYPEInput · 2 bit PC_PLUS_4Input · 32 bit NEXT_PCExpected output · 32 bit TARGET_MISALIGNEDExpected output · 1 bit
#0select-0-0-2566 0 0x00000100 0x0 0x00000004 0x00000004 0
#1select-0-0-2589 0 0x00000102 0x0 0x00000004 0x00000004 0
#2select-0-0-429496729212 0 0xFFFFFFFC 0x0 0x00000004 0x00000004 0
#3select-0-1-25617 1 0x00000100 0x0 0x00000004 0x00000100 0
#4select-0-1-25821 1 0x00000102 0x0 0x00000004 0x00000102 1
#5select-0-1-429496729225 1 0xFFFFFFFC 0x0 0x00000004 0xFFFFFFFC 0
#6select-1-0-25632 0 0x00000100 0x1 0x00000004 0x00000100 0
#7select-1-0-25836 0 0x00000102 0x1 0x00000004 0x00000102 1
#8select-1-0-429496729240 0 0xFFFFFFFC 0x1 0x00000004 0xFFFFFFFC 0
#9select-1-1-25644 1 0x00000100 0x1 0x00000004 0x00000100 0
#10select-1-1-25848 1 0x00000102 0x1 0x00000004 0x00000102 1
#11select-1-1-429496729252 1 0xFFFFFFFC 0x1 0x00000004 0xFFFFFFFC 0
#12select-2-0-25656 0 0x00000100 0x2 0x00000004 0x00000100 0
#13select-2-0-25860 0 0x00000102 0x2 0x00000004 0x00000102 1
#14select-2-0-429496729264 0 0xFFFFFFFC 0x2 0x00000004 0xFFFFFFFC 0
#15select-2-1-25668 1 0x00000100 0x2 0x00000004 0x00000100 0
#16select-2-1-25872 1 0x00000102 0x2 0x00000004 0x00000102 1
#17select-2-1-429496729276 1 0xFFFFFFFC 0x2 0x00000004 0xFFFFFFFC 0
#18select-3-0-25680 0 0x00000100 0x3 0x00000004 0x00000100 0
#19select-3-0-25884 0 0x00000102 0x3 0x00000004 0x00000102 1
#20select-3-0-429496729288 0 0xFFFFFFFC 0x3 0x00000004 0xFFFFFFFC 0
#21select-3-1-25692 1 0x00000100 0x3 0x00000004 0x00000100 0
#22select-3-1-25896 1 0x00000102 0x3 0x00000004 0x00000102 1
#23select-3-1-4294967292100 1 0xFFFFFFFC 0x3 0x00000004 0xFFFFFFFC 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.

Embedded simulation

Open Next PC stage

Tests

RV32ISingleCycleNextPCStageTest compares all 24 rows in both implementations. Program 15 checks that a misaligned jump prevents link/PC updates and causes a precise terminal trap. RV32ISingleCycleDocumentationTest.py verifies this pin table and the exact C++ example. Source: RV32ISingleCycleStages.cpp and RV32ISingleCycleStagesBehavioral.cpp; scenarios: src/tests/RV32ISingleCycleStageTests.cpp.