Branch History Table (BHT)
Overview
The Branch History Table (BHT) is a memory structure used by a processor's branch predictor to record and exploit the historical outcomes of branch instructions. It is one of the key sub-components of a dynamic branch predictor, alongside the Branch Target Buffer (BTB) and the Return Address Stack (RAS) [1].
Role within the Branch Predictor
In the RISC-V superscalar design considered in the evidence, the branch predictor is part of the Instruction Fetch (IF) unit and is responsible for predicting the next Program Counter (PC) address. The dynamic predictor inside the IF unit is composed of three parts [1]:
- Branch History Table (BHT) — maintains a history of the outcomes of previous occurrences of each branch in order to predict the direction (taken or not-taken) of the current branch, using a GShare indexing scheme.
- Branch Target Buffer (BTB) — records the target PC address of each branch instruction so that branch-taken target addresses can be resolved quickly.
- Return Address Stack (RAS) — stores the return addresses of decoded function calls; on a return instruction, the popped RAS entry supplies the next predicted PC.
The BHT therefore supplies the direction prediction, while the BTB supplies the target address and the RAS supplies return addresses.
Internal Organization (per the cited RISC-V superscalar study)
The functional verification study of the RISC-V superscalar IF unit enumerates the BHT's structure via the coverpoints used to verify it [2]:
| Property | Value | Coverpoint reference |
|---|---|---|
| Number of entries (lines) in the BHT array | 256 | Coverpoint 5 ("Write to every line of BHT array" = 256 bins) |
| Number of counters per BHT entry | 4 (1024 total counters) | Coverpoints 6, 7, 8, 10 (each with 1024 bins) |
| Read ports on the BHT array | 2 (one per fetched instruction) | Coverpoints 9 ("Read every line of the BHT array to predict the outcome of a branch" = 256×2 bins), 10 (1024×2 bins) |
These numbers reflect a dual-issue fetch path that retrieves one BHT direction prediction per instruction fetched per cycle.
Verification Coverpoints for the BHT
The BHT is exercised by a specific set of functional coverpoints in the cited UVM-based verification work [2]:
- Write to every line of BHT array — 256 bins (one per BHT entry).
- Write to every counter of BHT array — 1024 bins.
- Overflow each counter of BHT array — 1024 bins (testing the saturation upper bound of each saturating counter).
- Underflow each counter of BHT array — 1024 bins (testing the saturation lower bound of each saturating counter).
- Read every line of the BHT array to predict the outcome of a branch — 256×2 bins (256 lines × 2 read ports).
- Read every counter of the BHT array — 1024×2 bins (1024 counters × 2 read ports).
In that work, each coverpoint bin is considered "covered" once it has been hit at least 100 times [3].
Use as a Microarchitectural Configuration Knob
In parameterized RISC-V RTL implementations, the BHT is exposed as a tunable microarchitectural parameter. Designers can configure BHT vs. BTB sizes as part of the core's RTL parameters, in addition to other knobs such as pipeline depth, cache associativity, and bus interface selection [4]. This makes BHT sizing a deliberate performance/power/area (PPA) trade-off.
Prediction Flow within the IF Unit
The IF unit fetches up to two instructions per cycle. For each fetched instruction, the dynamic predictor issues:
- a BTB lookup to obtain a candidate target PC,
- a BHT lookup to obtain a taken/not-taken direction prediction,
- a RAS check for function return addresses.
A selection logic block then chooses between PC+4, BTB target, or RAS-supplied PC to produce the next predicted PCs (NextPC1, NextPC2) that drive the instruction cache [1].
Predictor Update
Once a branch is resolved at the execution stage, the predictor update interface notifies the IF unit of the branch's actual outcome. The Flush Controller, which holds the original BHT-sourced direction prediction in a FIFO, compares the predicted outcome with the actual outcome and, on a mismatch, triggers a pipeline flush and redirect [1]. The BHT counter corresponding to the branch PC is then updated (incrementing on taken, decrementing on not-taken, within saturation bounds), as enforced by coverpoints 6–8.