§ 4.5.4. Execute¶
RV32IBaselineExecuteStage uses the operands captured in ID/EX. It has no register-file access, forwarding path, or internal sequential state.
| Component | Description | Structural | Behavioral |
|---|---|---|---|
RV32IBaselineExecuteStage |
Shared-ALU computation, target resolution, EX/MEM packet | Yes | Yes |
IO pins¶
| Pin | Direction | Width | Description |
|---|---|---|---|
IN_VALID |
Input | 1 | ID/EX validity |
IN_PC, IN_INSTRUCTION, IN_FETCH_STATUS |
Input | 32 each | Instruction identity and fetch status |
IN_RS1_VALUE, IN_RS2_VALUE, IN_IMMEDIATE |
Input | 32 each | Captured operands and immediate |
IN_CONTROL, IN_REGISTER_ADDRESSES |
Input | 32 each | Decoded control and register addresses |
OUT_VALID |
Output | 1 | Forwarded validity |
OUT_PC, OUT_INSTRUCTION, OUT_FETCH_STATUS, OUT_CONTROL, OUT_REGISTER_ADDRESSES |
Output | 32 each | Forwarded packet fields |
OUT_ALU_RESULT, OUT_STORE_DATA |
Output | 32 each | ALU result and captured RS2 |
OUT_PC_PLUS_4, OUT_NEXT_PC |
Output | 32 each | Link/fallthrough value and resolved next PC |
OUT_EXECUTION_STATUS |
Output | 32 | Bit 0: selected target misaligned; other bits zero |
TERMINAL, CONTROL_FLOW |
Output | 1 each | Valid terminal instruction; valid branch/jump awaiting resolution |
Behavior¶
Operand selectors and ALU_OP follow the single-cycle Execute datapath. Arithmetic, logic, shifts, comparisons, and address calculations use the same ALU32. Branch comparisons use its comparison outputs. A separate PC+immediate adder works concurrently with branch comparison; JAL and JALR instead reuse the main ALU for their target addition. JALR clears target bit 0.
NEXT_PC is the selected target for a jump or taken branch, otherwise PC+4. Only a selected misaligned target sets EXECUTION_STATUS. An untaken branch with a numerically misaligned candidate target does not trap.
This packet contract does not carry PC+4 in ID/EX, so Execute recomputes it with one incrementer. It is not a second ALU. STORE_DATA always equals the old captured RS2, never a newly written register value.
TERMINAL combines incoming terminal reasons with selected-target misalignment, qualified by IN_VALID. CONTROL_FLOW is asserted for every valid branch/jump, including untaken branches. The controller resumes Fetch only after this resolution cycle.
C++ example¶
The shared Packet type carries instruction fields. early_terminal checks validity, the defined fetch/execution status bits, legality, halt, and trap. The arithmetic helper includes ALU32's reserved-opcode zero result.
inline uint32_t alu(unsigned op,uint32_t a,uint32_t b) {
const unsigned sh=b&31;
switch(op) {
case ALU32Op::ADD:return a+b; case ALU32Op::SUB:return a-b;
case ALU32Op::AND:return a&b; case ALU32Op::OR:return a|b; case ALU32Op::XOR:return a^b;
case ALU32Op::SLL:return a<<sh; case ALU32Op::SRL:return a>>sh;
case ALU32Op::SRA:return sh&&(a&0x80000000u)?(a>>sh)|(~uint32_t{0}<<(32-sh)):a>>sh;
case ALU32Op::SLT:return int32_t(a)<int32_t(b); case ALU32Op::SLTU:return a<b;
case ALU32Op::PASS_A:return a; case ALU32Op::PASS_B:return b; default:return 0;
}
}
inline StageResult execute(Packet p) {
const auto as=bits(p.control,27,3),bs=bits(p.control,29,3);
const auto op=bits(p.control,22,31),branch=bits(p.control,13,7),jump=bits(p.control,16,3);
const uint32_t a=as==0?p.rs1_value:as==1?p.pc:0;
const uint32_t b=bs==0?p.rs2_value:bs==1?p.immediate:0;
p.alu_result=alu(op,a,b); p.store_data=p.rs2_value; p.pc_plus_4=p.pc+4;
const bool compare=op==ALU32Op::SUB||op==ALU32Op::SLT||op==ALU32Op::SLTU;
const bool eq=compare&&a==b,lt=compare&&int32_t(a)<int32_t(b),ltu=compare&&a<b;
const bool conditions[]{false,eq,!eq,lt,!lt,ltu,!ltu,false};
const bool taken=jump||conditions[branch];
const auto target=jump==0?p.pc+p.immediate:jump==1?p.alu_result:jump==2?p.alu_result&~1u:0;
p.next_pc=taken?target:p.pc_plus_4;
p.execution_status=taken&&bool(target&3);
return {p,early_terminal(p),p.valid&&(branch||jump)};
}
Implementation¶
Structural implementation¶
DATAPATH reuses RV32ISingleCycleExecuteStage; NEXT_PC reuses RV32ISingleCycleNextPCStage. A structural IncrementBy4, field/status rewiring, and the shared PACKET_STATUS group complete the stage. There is exactly one CPU-specific ALU32 datapath and no separate RS1+immediate target adder.
Behavioral implementation¶
executePacket evaluates the same binary ALU, branch conditions, targets, and status without a simulator-owned register. The registered family is rv32i.baseline.execute. A catalog-selected behavioral stage uses gate-derived per-path delays and, where available, a delay twin for the current values. Compare values after settling; the checked equivalence scope is binary inputs.
Examples¶
The rows cover arithmetic, both branch outcomes, selected-target alignment, JAL/JALR target reuse, signed/unsigned comparison, and invalid-slot qualification.
All 11 recorded rows of RV32IBaselineExecuteStageTest, 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 | IN_CONTROLInput · 32 bit |
IN_FETCH_STATUSInput · 32 bit |
IN_IMMEDIATEInput · 32 bit |
IN_INSTRUCTIONInput · 32 bit |
IN_PCInput · 32 bit |
IN_REGISTER_ADDRESSESInput · 32 bit |
IN_RS1_VALUEInput · 32 bit |
IN_RS2_VALUEInput · 32 bit |
IN_VALIDInput · 1 bit |
CONTROL_FLOWExpected output · 1 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_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 | 33 | 0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000000 |
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 |
#1addi | 65 | 0x20001283 |
0x00000000 |
0x00000005 |
0x00000000 |
0x00000100 |
0x00000000 |
0x00000007 |
0xDEADBEEF |
1 |
0 |
0x0000000C |
not checked | not checked | not checked | not checked | 0x00000104 |
not checked | 0x00000104 |
not checked | 0xDEADBEEF |
not checked | 0 |
#2beq-not-taken | 103 | 0x00403181 |
0x00000000 |
0x00000008 |
0x00000000 |
0x00000100 |
0x00000000 |
0x00000007 |
0x00000008 |
1 |
1 |
not checked | not checked | 0x00000000 |
not checked | not checked | 0x00000104 |
not checked | not checked | not checked | not checked | not checked | not checked |
#3beq-taken | 145 | 0x00403181 |
0x00000000 |
0x00000008 |
0x00000000 |
0x00000100 |
0x00000000 |
0x00000007 |
0x00000007 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | 0x00000108 |
not checked | not checked | not checked | not checked | not checked | not checked |
#4taken-misaligned | 159 | 0x00403181 |
0x00000000 |
0x00000002 |
0x00000000 |
0x00000100 |
0x00000000 |
0x00000007 |
0x00000007 |
1 |
not checked | not checked | not checked | 0x00000001 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | 1 |
#5untaken-misaligned-target-is-harmless | 195 | 0x00403181 |
0x00000000 |
0x00000002 |
0x00000000 |
0x00000100 |
0x00000000 |
0x00000007 |
0x00000008 |
1 |
not checked | not checked | not checked | 0x00000000 |
not checked | not checked | not checked | not checked | not checked | not checked | not checked | not checked | 0 |
#6jal-shares-alu | 226 | 0x28011603 |
0x00000000 |
0x00000008 |
0x00000000 |
0x00000100 |
0x00000000 |
0x00000007 |
0x00000008 |
1 |
not checked | 0x00000108 |
not checked | not checked | not checked | not checked | 0x00000108 |
not checked | not checked | not checked | not checked | not checked | not checked |
#7jalr-clears-bit-zero | 260 | 0x20021683 |
0x00000000 |
0x00000000 |
0x00000000 |
0x00000100 |
0x00000000 |
0x00000109 |
0x00000008 |
1 |
not checked | 0x00000109 |
not checked | not checked | not checked | not checked | 0x00000108 |
not checked | not checked | not checked | not checked | not checked | not checked |
#8signed-branch | 294 | 0x00407181 |
0x00000000 |
0x00000008 |
0x00000000 |
0x00000100 |
0x00000000 |
0xFFFFFFFF |
0x00000001 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | 0x00000108 |
not checked | not checked | not checked | not checked | not checked | not checked |
#9unsigned-branch | 303 | 0x0040B181 |
0x00000000 |
0x00000008 |
0x00000000 |
0x00000100 |
0x00000000 |
0xFFFFFFFF |
0x00000001 |
1 |
not checked | not checked | not checked | not checked | not checked | not checked | 0x00000104 |
not checked | not checked | not checked | not checked | not checked | not checked |
#10invalid-slot | 308 | 0x0040B181 |
0x00000003 |
0x00000008 |
0x00000000 |
0x00000100 |
0x00000000 |
0xFFFFFFFF |
0x00000001 |
0 |
0 |
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¶
RV32IBaselineExecuteStageTest compares both implementations; program cases exercise the complete instruction set supported by the reference. Sources: RV32IBaselinePipeline.cpp, RV32IBaselinePipelineBehavioral.cpp.