-
Single Cycle
-
Pipelining
-
Data Cache
From the project, we have produced three variants of a RISCV32I CPU. Each can be found within their own branch in this repository:
- Single cycle (
baseRISCV32I
branch) - Pipelined (
pipelinedRISCV32I
branch) - Pipelined with data cache (
datacacheRISCV32I
branch)
Each variant has all instructions in the below table implemented:
Source: Harris & Harris (2022), Digital Design and Computer Architecture: Risc-V Edition
Documentation is provided in the main
branch (that's this one). There is also a reducedRISCV
branch which was used for Lab 4 and has been kept for reference.
To help maintain an organised workspace, the CPU has been broken down in a hierarchical manner:
You will find a similar hierachy in this documentation. You can access the relevant documentation files from the table of contents above. With the exception of personal statements, all documentation in this branch form a joint statement by Team 21.
Name | GitHub | Link to Personal Statement |
---|---|---|
Danial Dehghan | daniald1 | Danial's Statement |
Mohammed Tayyab Khalid | MohammedTK22 | Tayyab's Statement |
Ronit Ravi | r0n1tr | Ronit's Statement |
Ziean Ahmed Sheikh | za722-ic | Ziean's Statement |
The following table indicates who contributed to what parts of the CPU.
0
= Main Contributor, 1
= Co-Contributor
Task | Files | Ziean | Ronit | Danial | Tayyab |
---|---|---|---|---|---|
General | - | - | - | - | - |
F1 Program | f1_fsm.mem | 1 | 0 | 1 | |
Mem files | *.mem, *.asm | 1 | 1 | 1 | 1 |
Testbenches | *_tb.cpp | 0 | 1 | 1 | 1 |
Generics | 1 | 1 | 1 | 1 | |
Single-cycle | - | - | - | - | - |
ALU | top_alu.sv, alu.sv | 1 | 0 | ||
Control Unit | top_control.sv, main_decoder.sv, alu_decoder.sv, branch_decoder.sv, pcsrc_logic.sv | 0 | 1 | 1 | |
Data Memory | data_mem.sv | 0 | 1 | ||
Instruction Memory | instr_mem.sv | 0 | |||
Program Counter | top_pc.sv, pcmux.sv, pcreg.sv | 1 | 1 | 0 | 1 |
Register file | reg_file.sv | 0 | |||
Sign extend | sign_extend.sv | 0 | |||
Pipelining | - | - | - | - | - |
Decode Stage Register | pipeline_reg_decode.sv | 1 | 0 | ||
Execute Stage Register | pipeline_reg_execute.sv | 1 | 0 | ||
Memory Stage Register | pipeline_reg_memory.sv | 0 | |||
Writeback Stage Register | pipeline_reg_writeback.sv | 0 | |||
Hazard unit | hazard_unit.sv | 1 | 0 | ||
Data Cache | - | - | - | - | - |
Data Cache (1-way) | cache_1w.mem, cache_1w.sv | 1 | 0 | ||
Data Cache (2-way) | cache_2w.mem, cache_2w.sv | 0 | 1 |
To begin viewing the CPUs, clone this repository and switch to the corresponding branch to test the different CPU Versions.
Pasting the following command in the terminal in the baseRISCV32I
branch and it should run the Gaussian PDF on your Vbuddy.
$ ./base.sh
Additionally if you go to instr_mem/instr_mem.sv/
and change line 18's "pdf" to "f1_test" and then run:
$ ./f1_base.sh
This will plot the F1 Lights onto your Vbuddy.
Pasting the following command in pipelinedRISCV32I
branch it should plot the Noisy PDF onto the Vbuddy.
$ ./pipeline.sh
Additionally if you go to instr_mem/instr_mem.sv/
and change line 18's "pdf" to "f1_test" and then run:
$ ./f1_pipeline.sh
This will plot the F1 Lights onto your Vbuddy.
Pasting the following command in branch datacacheRISCV32I
will plot the Triangle PDF on your Vbuddy.
$ ./cache.sh
Additionally if you go to instr_mem/instr_mem.sv/
and change line 18's "pdf" to "f1_test" and then run:
$ ./f1_cache.sh
This will plot the F1 Lights onto your Vbuddy.
Information: We have other testbenches under each submodule folder that when run evaluates all possbile use cases for the corresponding module and prints out the states and output into the terminal.
DISCLAIMER: Do not test other .mem files for validity as they are not in little-endian form, there were used purely for testing in the past and are now all deprecated apart from the files used in the shell scripts.
Here is a waveform showing you the instructions for the F1 Lights program read in from the .mem file in the instruction memory, and the following instructions executed evidenced by registers a0, a1 and t1.
cpu_f1.mp4
cpu_gauss.mp4
cpu_sine.mp4
cpu_noise.mp4
traingle_cpu.mp4
We wrote a program call pdf_expected_output.cpp that you can find in mem_files that should perform the same operation as the pdf assembly. We took the results and plotted them in excel (see below) which matches the plots on vbuddy, giving us reason to believe our cpu works.
Here's a screenshot of the pdf program working in the base CPU. This is during the build loop, since the instruction memory address is cycling between addresses 52 thorugh 80. To see the entire simulation, follow the above build instrctions andopen the resulting .vcd file in GTKWave.
For both versions of our CPU with Pipeline with Hazard Unit as well as our separate added Data Cache version, both successfully compile the PDF and F1 programs and output the corresponding waveforms above.
When din = 0x000000C8 , the cache checks set 2 if the tags match and the V flag is high, i.e if it's a hit or miss. The hit signal being low indicates a miss, resulting in din propogating to the input of the data memory, a . The data memory returns 0x0 , which is written back, resulting in cache_memory[2] = 0x800000600000000. The 8 at the end is a result of the V flag being set to high, and the tag matches with the tag you'd retrieve from din after neglecting the least significant 5 bits of the word. Therefore, The cache works.
For more information on the implementation of cache specifically please refer to