ยง 4.4.3. Execute¶
RV32ISingleCycleExecuteStage selects the ALU operands, computes the arithmetic/address result, evaluates a branch, and supplies the control-transfer target. In the core it is named EXECUTE. It is combinational: it neither stores operands nor updates architectural state.
| Component | Description | Structural | Behavioral |
|---|---|---|---|
RV32ISingleCycleExecuteStage |
Operand muxes, one shared ALU, branch condition, branch/jump target selection | Yes | Yes |
4.4.3.1. RV32ISingleCycleExecuteStage¶
IO pins¶
| Pin | Direction | Width | Description |
|---|---|---|---|
PC |
Input | 32 | Current instruction's old PC |
RS1_VALUE, RS2_VALUE, IMM |
Input | 32 each | Register operands and decoded immediate |
ALU_OP |
Input | 5 | ALU32 opcode |
ALU_A_SEL, ALU_B_SEL |
Input | 2 each | Operand selectors, defined below |
BRANCH_TYPE |
Input | 3 | Branch-condition selector |
JUMP_TYPE |
Input | 2 | Target selector: 0 branch, 1 JAL, 2 JALR, 3 zero |
ALU_RESULT |
Output | 32 | Shared ALU result |
CONTROL_TARGET |
Output | 32 | Candidate transfer target, before Next PC selection |
BRANCH_TAKEN |
Output | 1 | Selected ALU comparison condition |
Behavior¶
| Selector | 0 | 1 | 2 | 3 |
|---|---|---|---|---|
ALU_A_SEL |
RS1_VALUE | PC | Zero | Zero |
ALU_B_SEL |
RS2_VALUE | IMM | Zero | Zero |
JUMP_TYPE โ CONTROL_TARGET |
PC+IMM | ALU_RESULT | ALU_RESULT with bit 0 cleared | Zero |
All additions wrap to 32 bits. ALU operation codes 0โ12 and reserved 13โ31 retain ALU32's complete contract: reserved operations produce result zero. ALU_RESULT is not replaced by the branch target when branching, and a jump's link value is not computed here.
| BRANCH_TYPE | BRANCH_TAKEN |
|---|---|
| 0, 7 | False |
| 1 | EQ |
| 2 | NOT EQ |
| 3 | LT_SIGNED |
| 4 | NOT LT_SIGNED |
| 5 | LT_UNSIGNED |
| 6 | NOT LT_UNSIGNED |
These flags compare the selected ALU operands, not necessarily the original RS1/RS2 pins. EQ/LT flags are enabled only for SUB, SLT, and SLTU. Incoherent manually supplied controls still follow the table: for example, inverted comparison flags can be true when the underlying flags are disabled. The instruction decoder selects SUB and register operands for every legal branch.
Shared arithmetic¶
| Instruction group | Main ALU work | Other arithmetic needed at the same time |
|---|---|---|
| Register/immediate ALU, LUI, AUIPC | Selected operation | Fetch computes PC+4 |
| Load/store | RS1+IMM | Fetch computes PC+4 |
| Conditional branch | RS1โRS2, including signed/unsigned flags | Branch-target adder computes PC+IMM; Fetch computes PC+4 |
| JAL | PC+IMM | Fetch computes PC+4 for the link |
| JALR | RS1+IMM; target bit 0 is then cleared | Fetch computes PC+4 for the link |
The branch adder remains combinational hardware even during other instructions, but its result is selected only for JUMP_TYPE=0. There is no dedicated RS1+IMM adder. Next PC chooses target versus fallthrough and checks alignment; execution status decides whether to capture anything.
C++ example¶
Reuse the complete alu32_example::alu model from 4.3.3, including its comparison-flag qualifications. Each unsigned selector is supplied within its pin width. The single ALU call represents sharing, not six successive uses of a clocked ALU.
#include <cstdint>
namespace single_cycle_example {
struct ExecuteInputs {
uint32_t PC, RS1_VALUE, RS2_VALUE, IMM;
unsigned ALU_OP, ALU_A_SEL, ALU_B_SEL, BRANCH_TYPE, JUMP_TYPE;
};
struct ExecuteOutputs { uint32_t ALU_RESULT, CONTROL_TARGET; bool BRANCH_TAKEN; };
ExecuteOutputs execute(const ExecuteInputs& i) {
const uint32_t a=i.ALU_A_SEL==0 ? i.RS1_VALUE : i.ALU_A_SEL==1 ? i.PC : 0;
const uint32_t b=i.ALU_B_SEL==0 ? i.RS2_VALUE : i.ALU_B_SEL==1 ? i.IMM : 0;
const auto r=alu32_example::alu(a,b,i.ALU_OP);
const bool conditions[]{false,r.EQ,!r.EQ,r.LT_SIGNED,!r.LT_SIGNED,
r.LT_UNSIGNED,!r.LT_UNSIGNED,false};
const uint32_t branch_target=i.PC+i.IMM;
const uint32_t target=i.JUMP_TYPE==0 ? branch_target
: i.JUMP_TYPE==1 ? r.OUT : i.JUMP_TYPE==2 ? r.OUT&~uint32_t{1} : 0;
return {r.OUT,target,conditions[i.BRANCH_TYPE]};
}
}
Unknown inputs and timing¶
Structural muxes/gates may isolate unused unknown data. The behavioral stage instead sets all three outputs to X if any input bit is nonbinary, even an unused operand or selector. Equivalence therefore covers settled binary inputs only. There is no clock or stored state. The catalog-selected compact stage uses gate-derived delays, while its settled-value computation does not reproduce intermediate gate glitches.
Implementation¶
Structural implementation¶
OPERAND_A and OPERAND_B feed one ALU32Core child named ALU. Its EQ/LT outputs and three inversions feed BRANCH_CONDITION. The general ALU32 flag block is absent here, but the comparison network retains the internal arithmetic carry and overflow it needs. BRANCH_TARGET_ADD computes PC+IMM. JALR_MASK is a rewire clearing bit 0 of the ALU result; TARGET_SELECT chooses branch/JAL/JALR/zero. Constants supply zero words and low control inputs.
Behavioral implementation¶
BehavioralStage's Execute branch computes the selected operation, comparison qualification, branch mux, and target selection directly, without gate objects or an instruction oracle. The family is rv32i.single-cycle.execute.
Examples¶
The recorded run covers all 32 ALU opcodes for a fixed operand pair, all eight branch selectors, signed versus unsigned comparison, equality, wrapped targets, JAL sharing, and JALR masking. For JALR, 0x101+4 yields ALU result 0x105 but target 0x104.
All 46 recorded rows of RV32ISingleCycleExecuteStageTest, 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 (3c9d1b0ad1ffa503). Changing fidelity or the circuit can change these times.
| Checkpointzero-based number ยท timeline label | Timesimulator units | ALU_A_SELInput ยท 2 bit |
ALU_B_SELInput ยท 2 bit |
ALU_OPInput ยท 5 bit |
BRANCH_TYPEInput ยท 3 bit |
IMMInput ยท 32 bit |
JUMP_TYPEInput ยท 2 bit |
PCInput ยท 32 bit |
RS1_VALUEInput ยท 32 bit |
RS2_VALUEInput ยท 32 bit |
ALU_RESULTExpected output ยท 32 bit |
BRANCH_TAKENExpected output ยท 1 bit |
CONTROL_TARGETExpected output ยท 32 bit |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
#0inputs | 33 | 0x0 |
0x0 |
0x00 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
not checked | not checked | not checked |
#1alu-op-0 | 34 | 0x0 |
0x0 |
0x00 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x80000001 |
not checked | not checked |
#2alu-op-1 | 62 | 0x0 |
0x0 |
0x01 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x7FFFFFFF |
not checked | not checked |
#3alu-op-2 | 84 | 0x0 |
0x0 |
0x02 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#4alu-op-3 | 102 | 0x0 |
0x0 |
0x03 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x80000001 |
not checked | not checked |
#5alu-op-4 | 122 | 0x0 |
0x0 |
0x04 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x80000001 |
not checked | not checked |
#6alu-op-5 | 138 | 0x0 |
0x0 |
0x05 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#7alu-op-6 | 166 | 0x0 |
0x0 |
0x06 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x40000000 |
not checked | not checked |
#8alu-op-7 | 192 | 0x0 |
0x0 |
0x07 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0xC0000000 |
not checked | not checked |
#9alu-op-8 | 224 | 0x0 |
0x0 |
0x08 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000001 |
not checked | not checked |
#10alu-op-9 | 238 | 0x0 |
0x0 |
0x09 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#11alu-op-10 | 261 | 0x0 |
0x0 |
0x0A |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x80000000 |
not checked | not checked |
#12alu-op-11 | 279 | 0x0 |
0x0 |
0x0B |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000001 |
not checked | not checked |
#13alu-op-12 | 303 | 0x0 |
0x0 |
0x0C |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#14alu-op-13 | 309 | 0x0 |
0x0 |
0x0D |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#15alu-op-14 | 329 | 0x0 |
0x0 |
0x0E |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#16alu-op-15 | 347 | 0x0 |
0x0 |
0x0F |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#17alu-op-16 | 367 | 0x0 |
0x0 |
0x10 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#18alu-op-17 | 374 | 0x0 |
0x0 |
0x11 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#19alu-op-18 | 394 | 0x0 |
0x0 |
0x12 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#20alu-op-19 | 412 | 0x0 |
0x0 |
0x13 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#21alu-op-20 | 432 | 0x0 |
0x0 |
0x14 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#22alu-op-21 | 439 | 0x0 |
0x0 |
0x15 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#23alu-op-22 | 459 | 0x0 |
0x0 |
0x16 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#24alu-op-23 | 477 | 0x0 |
0x0 |
0x17 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#25alu-op-24 | 497 | 0x0 |
0x0 |
0x18 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#26alu-op-25 | 504 | 0x0 |
0x0 |
0x19 |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#27alu-op-26 | 524 | 0x0 |
0x0 |
0x1A |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#28alu-op-27 | 542 | 0x0 |
0x0 |
0x1B |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#29alu-op-28 | 562 | 0x0 |
0x0 |
0x1C |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#30alu-op-29 | 568 | 0x0 |
0x0 |
0x1D |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#31alu-op-30 | 588 | 0x0 |
0x0 |
0x1E |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#32alu-op-31 | 606 | 0x0 |
0x0 |
0x1F |
0x0 |
0x0000000C |
0x0 |
0x00000100 |
0x80000000 |
0x00000001 |
0x00000000 |
not checked | not checked |
#33address-and-jalr | 636 | 0x0 |
0x1 |
0x00 |
0x0 |
0x00000004 |
0x2 |
0x00000100 |
0x00000101 |
0x00000001 |
0x00000105 |
not checked | 0x00000104 |
#34jal-shares-alu | 660 | 0x1 |
0x1 |
0x00 |
0x0 |
0x00000004 |
0x1 |
0x00000100 |
0x00000101 |
0x00000001 |
0x00000104 |
not checked | 0x00000104 |
#35signed-unsigned-branch | 692 | 0x0 |
0x0 |
0x01 |
0x0 |
0xFFFFFFFC |
0x0 |
0x00000100 |
0xFFFFFFFF |
0x00000001 |
not checked | not checked | not checked |
#36branch-0 | 693 | 0x0 |
0x0 |
0x01 |
0x0 |
0xFFFFFFFC |
0x0 |
0x00000100 |
0xFFFFFFFF |
0x00000001 |
0xFFFFFFFE |
0 |
0x000000FC |
#37branch-1 | 699 | 0x0 |
0x0 |
0x01 |
0x1 |
0xFFFFFFFC |
0x0 |
0x00000100 |
0xFFFFFFFF |
0x00000001 |
0xFFFFFFFE |
0 |
0x000000FC |
#38branch-2 | 708 | 0x0 |
0x0 |
0x01 |
0x2 |
0xFFFFFFFC |
0x0 |
0x00000100 |
0xFFFFFFFF |
0x00000001 |
0xFFFFFFFE |
1 |
0x000000FC |
#39branch-3 | 716 | 0x0 |
0x0 |
0x01 |
0x3 |
0xFFFFFFFC |
0x0 |
0x00000100 |
0xFFFFFFFF |
0x00000001 |
0xFFFFFFFE |
1 |
0x000000FC |
#40branch-4 | 722 | 0x0 |
0x0 |
0x01 |
0x4 |
0xFFFFFFFC |
0x0 |
0x00000100 |
0xFFFFFFFF |
0x00000001 |
0xFFFFFFFE |
0 |
0x000000FC |
#41branch-5 | 728 | 0x0 |
0x0 |
0x01 |
0x5 |
0xFFFFFFFC |
0x0 |
0x00000100 |
0xFFFFFFFF |
0x00000001 |
0xFFFFFFFE |
0 |
0x000000FC |
#42branch-6 | 737 | 0x0 |
0x0 |
0x01 |
0x6 |
0xFFFFFFFC |
0x0 |
0x00000100 |
0xFFFFFFFF |
0x00000001 |
0xFFFFFFFE |
1 |
0x000000FC |
#43branch-7 | 746 | 0x0 |
0x0 |
0x01 |
0x7 |
0xFFFFFFFC |
0x0 |
0x00000100 |
0xFFFFFFFF |
0x00000001 |
0xFFFFFFFE |
0 |
0x000000FC |
#44equal-branch | 782 | 0x0 |
0x0 |
0x01 |
0x1 |
0xFFFFFFFC |
0x0 |
0x00000100 |
0x00000001 |
0x00000001 |
not checked | 1 |
not checked |
#45wrap-target | 807 | 0x0 |
0x0 |
0x01 |
0x1 |
0x00000008 |
0x0 |
0xFFFFFFFC |
0x00000001 |
0x00000001 |
not checked | not checked | 0x00000004 |
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¶
RV32ISingleCycleExecuteStageTest checks both implementations; these are representative operand values, not an exhaustive 64-bit operand space. RV32ISingleCycleStageIntegrationTest asserts one main ALU and one branch adder, and verifies JALR when its destination is also its source. RV32ISingleCycleDocumentationTest.py compiles/replays this example. Source: RV32ISingleCycleStages.cpp and RV32ISingleCycleStagesBehavioral.cpp; scenarios: src/tests/RV32ISingleCycleStageTests.cpp.