We developed 5 distinct CPUs: a single-cycle processor, pipelined RV32IM, pipelined with cache, pipelined with branch prediction and a pipelined CPU that combines all cache multiply & branch prediction capabilities.
mainbranch: Final Pipelined CPU with multiply, data cache and branch prediction capabilites combined.SingleCyclebranch: Verified single-cycle CPUPipeline-MULbranch: Pipelined RV32IM perofrming complex maths instructionsCache-finalbranch: Pipelined with CacheBranch Predictionbranch: Pipelined with branch prediction- some branches left for other utiilties and referencing, but all inherit from their main function name eg Cache, Mul, Pipelined etc
| Name | Personal Statement |
|---|---|
| Samuel Amos-Osebeyo | Statement |
| Louis Canning | Statement |
| Archie Kendall | Statement |
| Adil Shah | Statement |
We used lucid-chart throughout the project, a digital 'drawing board' where we could collaborate and evolve designs in real time. It enabled us to visually and functionally keep up with what we were doing on git, with different pages and schematics for our differenct branches. This also enabled us to switch to different branches and help eachother debug as we could look up the relevant schematic on the shared notes.
.
├── .gitignore
├── ReadMe.md
├── rtl
│ ├── adder.sv
│ ├── branch_prediction
│ │ ├── branch_history_table.sv
│ │ ├── branch_predictor.sv
│ │ └── branch_target_buffer.sv
│ ├── decode
│ │ ├── D_E_reg.sv
│ │ ├── alu_decoder.sv
│ │ ├── control_unit.sv
│ │ ├── decode.sv
│ │ ├── regfile.sv
│ │ └── sign_extend.sv
│ ├── execute
│ │ ├── E_M_reg.sv
│ │ ├── alu.sv
│ │ ├── branch_comparator.sv
│ │ ├── div.sv
│ │ └── execute.sv
│ ├── fetch
│ │ ├── F_D_reg.sv
│ │ ├── fetch.sv
│ │ ├── instrMem.sv
│ │ └── pc_reg.sv
│ ├── hazard_unit
│ │ ├── control_hazard.sv
│ │ └── hazard_unit.sv
│ ├── memory
│ │ ├── M_W_reg.sv
│ │ ├── cache.sv
│ │ ├── cache_L1.sv
│ │ ├── cache_controller.sv
│ │ ├── cache_data_parser.sv
│ │ ├── datamem.sv
│ │ └── memory.sv
│ ├── mux.sv
│ ├── mux4.sv
│ ├── top.sv
│ └── writeback
│ └── writeback.sv
└── tb
├── Units
│ ├── Testing_Guide.md
│ ├── [testbench headers]
│ ├── [verify implementations]
│ └── doitunit.sh
├── asm
│ ├── 1_addi_bne.s
│ ├── 2_li_add.s
│ ├── 3_lbu_sb.s
│ ├── 4_jal_ret.s
│ ├── 5_pdf.s
│ ├── f1.s
│ └── predictor.s
├── cache_testing
│ └── [cache test assemblies]
├── hazards_test_asm
│ ├── [data hazard tests]
│ ├── div.s
│ └── mul.s
├── custom_tests
│ ├── custom_cpu_testbench.h
│ └── custom_verify.cpp
├── reference
│ └── [PDF reference materials]
├── assemble.sh
├── cacheit.sh
├── custom_doit.sh
└── doit.sh
All commands should be executed from the /tb directory or the subsequent test folder
use +chmod +x *<scriptname> to give yourself access
| Command | Purpose |
|---|---|
./doit.sh |
Execute standard test suite |
./doitunit.sh [unit name] |
Run module tests in Units folder |
./custom_doit.sh |
Run our directory of our own tests |
./pdf.sh [distribution name] |
Run PDF distribution visualization |
./f1.sh |
Run F1 starting lights simulation |
./cacheit.sh |
Run Cache Test suite and performance tests |
Our single-cycle CPU implements all RV32I instructions (except fence, ecall & ebreak) , enabling single-cycle execution of arithmetic, logical, memory, and control flow operations. This satisfies the requirements of stretch goal 3 from the brief.
| Component | Samuel | Louis | Archie | Adil |
|---|---|---|---|---|
| Program Counter | x | |||
| ALU | x | |||
| Register File | x | |||
| Instruction Memory | x | x | ||
| Control Unit | x | |||
| Sign Extension | x | |||
| Data Path Integration | x | x | ||
| Data Memory | x | x | ||
| Top-Level Assembly | x | x | ||
| Unit Testing | x | |||
| Integration Testing | x | x | ||
| F1 Program | x | |||
| Vbuddy integration | x |
The testing script validated the CPU functionality through the given tests, modular tests were completed before integration as well.
Our F1 implementation demonstrates correct timing and state machine behavior:
F1_normal.mp4
F1_random.mp4
Gaussian.mp4
Noisy.mp4
Successfully visualizes probability distributions with proper data handling:
Gaussian Distribution: Smooth bell curve with correct statistical properties
Noisy Distribution: Demonstrates proper random number generation
Triangle Distribution: Linear probability distribution correctly implemented
Implementation Detail: To achieve smooth visualization, we display values every 3 clock cycles:
bool is_paused = vbdFlag();
top->trigger = is_paused;
if (!is_paused) {
j++;
if (j % 3 == 0) {
vbdCycle(j);
vbdPlot(top->a0, 0, 255);
}
}
Our pipelined processor achieves higher throughput through instruction-level parallelism across 5 pipeline stages: fetch, decode, execute, memory & writeback. An additional hazard unit was created to detect and mitigate any data, control and structural hazards that arose. This design processes multiple instructions concurrently, with each stage handling a different instruction simultaneously. As well as continuing to pass key fundamental tests. This satisfies the requirements for stretch goal 2 from the brief.
Key Features:
- Full RV32IM instruction set support
- Data and Control Hazard Detection with forwarding and stalling
We developed custom testing scripts to test our specialised assembly files to ensure the design behaved as desired.
The specialised assembly programs were needed to either evaluate extension performance or for debugging purposes. The test prints from the script can be seen below.
Our extensions: These were all done on a fully pipelined cpu and all worked correctly
- RV32IM extension
- Branch Prediction
- 2 way set associative Cache
These are all explored in more depth in our individual statements, all exentions had a quantifiable improvement over the standard pipelined version while still maintaining correctness across the board giving us the same test prints as the image seen just above. They were developed parallely on the base pipeline CPU and once extensive testing was completed, all these improvements were compiled into the one CPU.
With the completion of the cache all recommended stretch goals menmtioned in the brief have been achieved.
| Component | Samuel | Louis | Archie | Adil |
|---|---|---|---|---|
| Pipelining | x | x | x | x |
| Forwarding | x | |||
| Load stalls | x | |||
| Control Hazards | x | |||
| Branch Predictions | x | |||
| Pipeline debug | x | x | ||
| RV32IM extension | x | |||
| Cache | x |
-
Hazard Coordination: Synchronizing data forwarding, load-use stalls, and cache stalls while handling simultaneous conditions from cache misses and division operations without corrupting the pipeline.
-
Clock Synchronization: Standardizing all modules to
posedge clkafter early race conditions from mixed edge triggers in the BTB and register file caused unpredictable behavior. -
Metadata Propagation: Ensuring branch prediction flags and opcode validity bits propagate correctly through stages and clear during flushes to prevent spurious stalls and incorrect forwarding.
-
Multi-Cycle Stalls: Coordinating 32-cycle division and cache miss stalls with selective pipeline freezing strategies while preventing instruction loss or state corruption.
-
Interface Consistency: Resolving signal naming ambiguities and polarity mismatches between modules (e.g.,
memUnsignedcontrol signal) that caused instruction-specific bugs requiring GTKWave debugging.
Our strategy of isolating and thoroughly testing individual modules before integration proved essential to the project's success. Each team member developed and verified their components independently using comprehensive unit tests, ensuring correct functionality before system-level assembly. This modular approach enabled parallel development across multiple extensions simultaneously - with in person code reviews of modules to ensure each member gained insight into each feature.
This collaborative workflow demonstrated our team coordination, with clear interfaces and regular communication ensuring smooth integration of complex features into a fully functional enhanced, pipelined CPU.
- Verilator for simulation
- GTest for C++ testbenches
- GTKWave for waveform analysis
- RISC-V GNU toolchain for assembly
- VBuddy for hardware visualization
- Harris & Harris: Digital Design and Computer Architecture: RISC-V Edition



