Final score: 117/100
Contributors: 吴梦轩 12212006, 王韬杰 12210519, 吴思锐 12210122
This is the final project for the course CS214 Computer Organization at SUSTech. The project is to implement a simple 5-stage pipelined CPU in Verilog. The CPU is based on the RISC-V instruction set architecture (ISA). The CPU is capable of executing the RV32I base integer instruction set except sb
, sh
, ecall
and ebreak
instructions.
- 5-stage Pipeline: The CPU is implemented with a 5-stage pipeline, including Instruction Fetch (IF), Instruction Decode (ID), Execute (EX), Memory Access (MEM), and Write Back (WB).
- Forwarding Unit: The CPU is equipped with a forwarding unit to handle data hazards.
- Hazard Detection Unit: The CPU is equipped with a hazard detection unit to handle load-use hazards.
- Branch Prediction: The CPU is equipped with a simple branch prediction module to predict the program counter value.
lui
andauipc
Instructions: The CPU is capable of executinglui
andauipc
instructions.- Bug-free: During our testing, the CPU is bug-free for its hardware implementation. We are confident that any program that runs on the RARS simulator will run correctly on our CPU. If you find any bugs, please let us know.
- Well Documented: Each module is documented in detail, we hope this can help you understand the code
/Assembly
: Assembly code and tools./Assembly/Out
:.txt
files that can be used to directly load the program to the FPGA./Assembly/Testcase 1
: Assembly code for the first test case./Assembly/Testcase 2
: Assembly code for the second test case./Assembly/Init Screen
: Assembly code for a simple welcome page./Assembly/Hazard
: Assembly code that demonstrates the ability of the CPU to handle data hazards./Assembly/Branch Prediction
: Assembly code that loops forever, use with simulation to demonstrate the branch prediction module./Assembly/GenUBit_RISC_V.bat
: A batch file to convert the assembly code to.coe
file and.txt
file./Assembly/UartAssist.exe
: A tool to load the program to the FPGA via UART./Assembly/*
: Other required files for the conversion.
/Report
: Report for the project./Pipeline_CPU.ip_user_files
: IP user files generated by Vivado (do not modify)./Pipeline_CPU.srcs
: Source code for the project.Pipeline_CPU.xpr
: Vivado project file.Project Requirement.pdf
: Project requirement.RV32 Reference Card.pdf
: Reference card for the RV32 ISA.Top.bit
: A pre-built bitstream for the project.
Please refer to the report for detailed information about the project structure.
- Download the project to your local machine.
- Open Vivado and connect your FPGA board to your computer.
- Program the FPGA with the pre-built bitstream
Top.bit
.
Note: The Top.bit
file is built for Minisys board, not EGO-1 board. Please make sure you have the correct board before using it.
- Download the project to your local machine.
- Open
Pipeline_CPU.xpr
in Vivado. - Import design files
Pipeline_CPU.srcs/sources_1
to the project (please make sure you haveuart_bmpg_0
IP core, which is a custom IP core provided by the instructor and does not exist in Vivado by default). - Import constraints file
Pipeline_CPU.srcs/constrs_1/new/Constraint.xdc
to the project. - Run generate bitstream.
- Write your program in RARS.
- Set Memory Configuration to
Compact, Text at Address 0
underSettings/Memory Configuration
. - Assemble your program.
- Dump your instructions to
inst.txt
and data todmem.txt
using theFile/Dump Memory
function, set dump format toHexadecimal Text
.
- Copy and paste your
inst.txt
anddmem.txt
to the same directory asGenUBit_RISC_V.bat
,rars2coe.exe
andUARTCoe_v3.0.exe
(provided under/Assembly
). - Run
GenUBit_RISC_V.bat
to generateprgmip32.coe
anddmem32.coe
. - Set
prgmip32.coe
anddmem32.coe
as the initial memory content in theInstruction Memory
andData Memory
respectively. - Run generate bitstream.
- Copy and paste your
inst.txt
anddmem.txt
to the same directory asGenUBit_RISC_V.bat
,rars2coe.exe
andUARTCoe_v3.0.exe
(provided under/Assembly
). - Run
GenUBit_RISC_V.bat
to generateout.txt
. - Run
UartAssist.exe
(provided under/Assembly
), set the baud rate to 128000, and loadout.txt
. - Program the FPGA.
- Press P2 on the FPGA board to enter the UART communication mode.
- Send the program to the FPGA by clicking
Send
inUartAssist.exe
. - Wait until
Program Done
is displayed inUartAssist.exe
. - Press S6 (Reset) on the FPGA board to start the program.
For the sake of code quality, we have some regulations for the code:
- Naming:
- Variable: Use
snake_case
for variable names. Example:read_data
- value: No special requirements
- flag: Use _flag as the suffix. Example:
mem_read_flag
- data: For data from/to memory/register, use _data as the suffix. Example:
write_data
- constant: Use all uppercase with underscore for constants. Example:
HALF_PERIOD
(should be defined in a separate parameter file under/Parameters
)
- stage: If the variable is present in multiple stages, put stage name as the final suffix. Example:
instruction_IF
- Module: Use
snake_case
with uppercase for module names. Example:Decoder
- Instance: Use
<module_name> + _ + Instance
for instance names. Example:Decoder_Instance
- Ip Core: Use
snake_case
with suffix_ip
for IP core names. Example:CPU_Main_Clock_ip
- Variable: Use
- Constants: For all constants, please put them in the
Parameters.v
and reference them in the code. An example is shown inInstruction_Fetch.v
. - Instantiation: When instantiating a module, please use the following format:
For example:
<module_name> <module_name> + _ + Instance( .<port_name>(<port_name>) );
Controller Controller_Instance( .inst(inst), .branch_flag(branch_flag), .ALU_Operation(ALU_Operation), .ALU_src_flag(ALU_src_flag), .mem_read_flag(mem_read_flag), .mem_write_flag(mem_write_flag), .mem_to_reg_flag(mem_to_reg_flag), .reg_write_flag(reg_write_flag) );