§ 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-256 | 6 | 0 |
0x00000100 |
0x0 |
0x00000004 |
0x00000004 |
0 |
#1select-0-0-258 | 9 | 0 |
0x00000102 |
0x0 |
0x00000004 |
0x00000004 |
0 |
#2select-0-0-4294967292 | 12 | 0 |
0xFFFFFFFC |
0x0 |
0x00000004 |
0x00000004 |
0 |
#3select-0-1-256 | 17 | 1 |
0x00000100 |
0x0 |
0x00000004 |
0x00000100 |
0 |
#4select-0-1-258 | 21 | 1 |
0x00000102 |
0x0 |
0x00000004 |
0x00000102 |
1 |
#5select-0-1-4294967292 | 25 | 1 |
0xFFFFFFFC |
0x0 |
0x00000004 |
0xFFFFFFFC |
0 |
#6select-1-0-256 | 32 | 0 |
0x00000100 |
0x1 |
0x00000004 |
0x00000100 |
0 |
#7select-1-0-258 | 36 | 0 |
0x00000102 |
0x1 |
0x00000004 |
0x00000102 |
1 |
#8select-1-0-4294967292 | 40 | 0 |
0xFFFFFFFC |
0x1 |
0x00000004 |
0xFFFFFFFC |
0 |
#9select-1-1-256 | 44 | 1 |
0x00000100 |
0x1 |
0x00000004 |
0x00000100 |
0 |
#10select-1-1-258 | 48 | 1 |
0x00000102 |
0x1 |
0x00000004 |
0x00000102 |
1 |
#11select-1-1-4294967292 | 52 | 1 |
0xFFFFFFFC |
0x1 |
0x00000004 |
0xFFFFFFFC |
0 |
#12select-2-0-256 | 56 | 0 |
0x00000100 |
0x2 |
0x00000004 |
0x00000100 |
0 |
#13select-2-0-258 | 60 | 0 |
0x00000102 |
0x2 |
0x00000004 |
0x00000102 |
1 |
#14select-2-0-4294967292 | 64 | 0 |
0xFFFFFFFC |
0x2 |
0x00000004 |
0xFFFFFFFC |
0 |
#15select-2-1-256 | 68 | 1 |
0x00000100 |
0x2 |
0x00000004 |
0x00000100 |
0 |
#16select-2-1-258 | 72 | 1 |
0x00000102 |
0x2 |
0x00000004 |
0x00000102 |
1 |
#17select-2-1-4294967292 | 76 | 1 |
0xFFFFFFFC |
0x2 |
0x00000004 |
0xFFFFFFFC |
0 |
#18select-3-0-256 | 80 | 0 |
0x00000100 |
0x3 |
0x00000004 |
0x00000100 |
0 |
#19select-3-0-258 | 84 | 0 |
0x00000102 |
0x3 |
0x00000004 |
0x00000102 |
1 |
#20select-3-0-4294967292 | 88 | 0 |
0xFFFFFFFC |
0x3 |
0x00000004 |
0xFFFFFFFC |
0 |
#21select-3-1-256 | 92 | 1 |
0x00000100 |
0x3 |
0x00000004 |
0x00000100 |
0 |
#22select-3-1-258 | 96 | 1 |
0x00000102 |
0x3 |
0x00000004 |
0x00000102 |
1 |
#23select-3-1-4294967292 | 100 | 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¶
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.