I added waveform analysis for J-type and S-type in Homework 3.
contributed by < jeremy90307
>
The code for the Three-Stage processor is ca2023-lab3_3-Stage, and the reference source is YatCPU_Lab.
Before constructing the Three-Stage CPU, it is essential to understand the concept of interrupts. Without interrupts, a program will only run according to the pre-defined instructions without the ability to interrupt midway. However, a practical CPU must always be ready to handle external events, allowing it to promptly process interrupts.
Please refer to Lab2 of YatCPU for a detailed introduction.
Control and Status Registers (CSR) are utilized to control and store the current status of various features in the CPU.
mstatus register
The mstatus register is used to record the current state, such as whether interrupts are enabled.
mepc register
The mepc register saves the address of the instruction to be executed after the interrupt returns. When the CPU handles an interrupt, the mepc register is automatically set to the address of the current instruction.
mcause register
The mcause register stores the reason for the interrupt.
mtvec register
The mtvec
register stores the address of the interrupt handling routine. When the CPU encounters an interrupt, the program counter (pc
) register is automatically set to the address stored in the mtvec
register, pointing to the interrupt handling routine.
When an interrupt occurs, the CPU needs to flush and stall the pipeline, and write interrupt-related information into CSR registers.
ID : ID stage needs to identify CSR instructions and generate corresponding control signals and data for other modules.
EXE : For CSR instructions, writing into a register involves first fetching the value from the CSR register according to the instruction semantics. The value is then modified before being written back to the CSR register. At this moment, the ALU inside the EXE is idle, allowing for the reuse of the ALU to obtain the value from the CSR register.
WB : After supporting CSR-related operations, the source of data to be written back to the target register includes the value read from the target CSR register before modification.
The purpose of an interrupt controller is to detect external interrupts. Upon the arrival of an interrupt, it interrupts the current execution flow of the CPU. After setting the relevant CSR information, the processor then jumps to the interrupt handling routine to execute the interrupt service routine.
In the previous HW3 single-cycle CPU design, the critical path was too long, making it challenging to increase the clock frequency. Additionally, each clock cycle could only execute one instruction, resulting in a low instruction throughput. Therefore, a 3-stage CPU (IF, ID, EXE) was designed to address these issues. However, branch and jump instructions also introduced control hazards
Building a Three-Stage CPU following the tutorial from YatCPU, I will complete the assessment according to the instructions in the content.
Using the IF2ID
and ID2EX
pipeline registers, the single-cycle CPU is divided into three stages.
Pipeline registers act as buffers in a pipeline, helping to split combinational logic and shorten critical paths. Their function is straightforward – during each clock cycle, based on the reset (pipeline clear) or stall (pipeline pause) conditions, the register content is cleared, held, or set to a new value. The output of the register is the value stored in it. For versatility, we can define a PipelineRegister module with parameters to implement pipeline registers of varying data widths.
Task: Complete the PipelineRegister.scala
module with the provided template.
In all these scenarios, the EXE stage sends the jump signal, consisting of jump_flag and jump_address, to the IF stage. However, before writing the jump_address to the program counter (pc), there are unwanted instructions in the IF and ID stages that have not yet written to the registers. Therefore, it is only necessary to clear the corresponding pipeline registers to flush these two instructions.
Test: Fill in the missing code in the Control.scala
module.
Test: Complete the code for the flush part in the CPU.scala
module.
Result
hw2.S
) into the ca2023-lab3_3-stage/csrc
directory.ecall
and add _start:
Makefile
,and add hw2.asmbin
under BINS.$ make update
in the directory to generate hw2.asmbin
.ThreeStageCPUTest.scala
, add a Test for hw2.asmbin
.Test
Output
No CPI comparison and analysis.