Overview
The Instruction Fetch Unit (IFU) is the front-end subsystem of a processor responsible for fetching instructions from the instruction cache and predicting the next Program Counter (PC) address, i.e., the address of the next instruction to fetch. The IFU is part of the broader RISC-V processor front end and is studied both in the context of high-performance superscalar out-of-order cores and in FPGA-targeted soft-processor implementations.
Role in the pipeline
In a two-way RISC-V superscalar out-of-order core, the front end fetches and decodes instructions before sending them to the back end for execution and retirement. The IFU supplies up to two fetched instructions per cycle to the Instruction Decode stage, which can also decode two instructions per cycle. This makes the IFU a throughput-critical front-end component: it must provide instruction bytes and next-PC predictions quickly enough to keep the downstream decode, rename, issue, and execution stages supplied.
In a five-stage pipelined RISC-V soft-processor context (RVCoreP), one of three effective optimization methods used to raise operating frequency is instruction fetch unit optimization that includes a pipelined branch-prediction mechanism, alongside ALU optimization and data-alignment/sign-extension optimization for data-memory output.
In FPGA-targeted soft processors supporting the RISC-V compressed-instruction extension (RVCoreP-32IC), the IFU must additionally handle 16-bit compressed instructions. Because the compressed extension reduces program size by about 25%, an efficient compressed-aware IFU is needed to avoid a significant performance penalty. RVCoreP-32IC reports DMIPS, CoreMark, and Embench values that are 42.5%, 41.1%, and 21.3% higher, respectively, than the related work, implemented in Verilog HDL and verified on a Xilinx Artix-7 FPGA.
Branch-prediction structures
The IFU's dynamic predictor includes three main structures:
- Branch History Table (BHT): maintains history for previous occurrences of branches and predicts branch direction, i.e., taken or not taken. The cited design uses a GShare indexing scheme.
- Branch Target Buffer (BTB): records target PC addresses for branch instructions, accelerating the determination of branch-taken addresses.
- Return Address Stack (RAS): stores return addresses for decoded function calls; when a function-return instruction is encountered, the popped RAS entry is used as the next predicted PC address.
Together, these structures allow the IFU to select likely next fetch addresses before branches are fully resolved later in the pipeline.
Interfaces used in verification
The cited UVM-based verification work models the IFU as connected to the rest of the processor through four separate interfaces. During simulation, each interface is driven by a distinct parameterized constrained-random test sequence that mimics how the IFU behaves when connected to the remaining processor subsystems while executing real programs.
The four interfaces and their parameters are:
- Predictor Update interface: updated by the execution stage with the resolved status of branches. Parameters include backward branch taken rate, forward branch taken rate, invalid instruction rate, and function return rate. The "backward branch" parameter can take values such as 5%, 40%, and 80%, representing low, medium, and high probability that a branch instruction has a backward direction (e.g., loops vs. forward branches in
ifstatements). - Decode interface: connects the IFU to the Decode stage, informs the IFU about validity and instruction type, including function calls and returns, and triggers branch-prediction restart events. Parameters include idle rate, invalid instruction rate, function call rate, and stall rate, where the first three must always sum to 1 because they cannot be activated simultaneously. Stall rate is the probability that the decode stage will backpressure the IFU by not accepting the two fetched instructions.
- Pipeline Flush interface: issues a flush when a branch is mispredicted. Parameters include branch misprediction rate and branch instruction rate (the probability that at least one of the fetched instructions is a branch).
- Instruction Cache interface: fetches two instructions from the instruction cache for a current PC address. Parameters include backward branch rate, partial access rate (probability of issuing partial accesses when issuing a cache hit), and miss rate (probability of issuing miss cycles when a new PC address is issued).
Verification coverpoints
A representative set of functional coverpoints used in IFU verification, with associated bin counts, includes:
- Both fetched instructions predicted as branch-taken [1 bin]
- Both fetched instructions predicted as branch-not-taken [1 bin]
- Branch 1 taken, Branch 2 not taken [1 bin]
- Branch 1 not taken, Branch 2 taken [1 bin]
- Write to every line of BHT array [256 bins]
- Write to every counter of BHT array [1024 bins]
- Overflow each counter of BHT array [1024 bins]
- Underflow each counter of BHT array [1024 bins]
- Read every line of the BHT array to predict branch outcome [256 * 2 ports]
- Read every counter of the BHT array [1024 * 2 ports]
- Read from every line of BTB array [256 * 2 ports]
- Write to every line of BTB array [256 bins]
- BTB is full [1 bin]
- BTB is empty [1 bin]
- RAS is full [1 bin]
- RAS is empty [1 bin]
- RAS overflow issued [1 bin]
- RAS underflow issued [1 bin]
- Restart-event FSM transitions [5 bins]
- Half-access FSM transitions [2 bins]
These coverpoints allow verification engineers both to find interesting bugs during simulation and to quantify the quality of the test sequences in covering the functional properties of the design.
Block-level verification with UVM
In a separate UVM-based verification project targeting a RISC-V core (RV32I), the IFU is treated as one of the major core blocks to be verified individually, alongside the Decode Unit, Execution Unit (ALU, MUL/DIV), Register File, Control and Status Registers (CSR), Load/Store Unit (LSU), Branch Prediction Unit, Pipeline and Hazard Unit, and Interrupt/Exception Unit. The environment uses constrained-random stimulus generation, SystemVerilog assertions (SVA), functional coverage closure, an architectural reference model (e.g., Spike or a custom ISA model), and a scoreboard that compares expected vs. actual outputs at transaction or instruction granularity. UVM components implemented for this work include sequence, sequencer, driver, monitor, scoreboard, and coverage collector. The reported result is that all targeted units including the IFU were verified against the RISC-V specification, functional and assertion coverage goals were achieved, and critical corner-case bugs were identified and resolved.
MAB-driven simulation flow
The cited UVM-based verification work applies a multi-armed-bandit (MAB) driven verification flow to the IFU. In that flow, virtual test sequences combine one sequence per IFU interface, and the UCB1 algorithm is used to balance exploration and exploitation when selecting sequences for simulation. A set of K = 40 virtual sequences is chosen so that each parameter level is used at least once; the verification engineer is free to choose a specific parameter set that targets a corner case. Coverage bins are considered fully covered when they are hit at least 100 times, and bins that reach the goal are removed from the set of active bins so they stop contributing to the reward of the applied test sequences.