Creating the top.sv file
First, Nik and I designed the overall architecture of the CPU, including the registers, the control unit, the instruction and data memory, and the ALU.
Using the schematic drawn by Nik I wired all the components and added the required multiplexers to create the top.sv file.(Commit)
-
A multiplexer with
JAL
as the selector bit. When high it will store our current instruction address into regfile.sv . This allows us to return to that instruction when aJALR
instruction is called. (Commit) -
Another multiplexer with
JALR
as the selector bit. When high it will load the ALU result value into the PC. This is because we will have the instruction address from the regfile.sv come out ofrd2
-->srcB
-->AluResult
. (Commit) -
A third and final multiplexer with
BranchSrc
as the selector bit was added for the branch instructions.BranchSrc
would be high if a branch instruction was called and the comparison ofSrcA
andSrcB
was done in the ALU and outputted from the ALUBranch
Port. For example, if we had aBEQ rd1, rd2, label
instruction.BranchSrc
Would be1'b1
and the boolean output ofrd1==rd2
would be outputted from the ALUbranch
port. -
addrselect
was a control signal created for all the load and store instructions.
Making sure the single-cycle CPU was fully working was a top priority as we intended to do the pipelining and cache extension tasks which will be built on top of this CPU. Although each component was tested individually we needed to make sure that the components together worked
I designed an ALU test program (commit) and created a truth table for it (commit). It worked on the first try (commit)
Once again I designed a branch test program and ran it. (Commit) Test all branches by setting a flag in a3
logic:
a3 == 0 all branches work
a3 == 1 beq doesn't work (test stopped and bne,blt,bge,bltu,bgeu not tested)
a3 == 2 beq works bne doesn't work (test stopped and blt,bge,bltu,bgeu not tested)
a3 == 3 beq works bne works blt doesn't work (test stopped and bge,bltu,bgeu not tested)
a3 == 4 beq works bne works blt works bge doesn't work (test stopped and bltu,bgeu not tested)
a3 == 5 beq works bne works blt works bge works bltu doesn't work (test stopped and bgeu not tested)
a3 == 6 beq works bne works blt works bge works bltu works and bgeu doesn't work
When running the test the branch instructions were not working this was expected as branch instructions depend on several components such as the extend.sv, alu.sv, and the control.sv. The issue was with the signextend logic as it was only extending to 25 bits. I fixed this error (commit). The other error was with the ALU logic for func3 which produced the branch output. This was fixed (commit) and the branches were now all fully working (commit).
To test JAL and JALR we used the [f1assembly.txt]https://github.com/EIE2-IAC-Labs/iac-riscv-cw-14/blob/VERSION-2-SINGLE-CYCLE/test/f1.txt). The program, however, didn't work so Nik and I looked at the GTKWave and saw that the signextention wasn't working properly. After looking at the RISC-V ISA we noticed that for JALR we need to add Imm12
not Imm20
to the PC (Commit)
After all this testing we ran a working F1 Program! (Commit)
Contribution:
-
Overlooking the top.sv file rewiring that Ben and Nik worked on with the addition of the registers for each block.
-
Testing the pipelined CPU using the previous single cycle assembly code but added noops for register dependencies that would have caused data hazards and noops for the start of subroutines that would have caused control hazards as we need to flush the code before the jump instruction (Commit)
-
Rewriting the f1 program with noops. (Commit)
-
Extra: Created a python script that took the initial instruction memory and detected all register dependency data hazards and produced a new instruction memory with noops added (commit)
I learned a lot by completing the RISC-V processor coursework. By working on the top.sv file I gained a deeper understanding of computer architecture and how processors operate at the fundamental level. I learned about the different components of a processor, such as the registers, the control unit, and the arithmetic logic unit, and how they work together to execute instructions. Additionally, I gained practical experience in designing and implementing a processor using Verilog. Alongside this, I learned about several useful features of GitHub that helped me to manage and collaborate on my code effectively which was essential for keeping my code up to date and ensuring that I was working with the latest version.
If I had more time I would further optimize the python script that I wrote for it to add noops to flush instructions for when branches happen. I could have integrated the program in the shell script so that every time we simulate the CPU the script would run and noops would be added and the CPU would use the new instruction memory. Alternatively, I could have tried to use hardware methods such as forwading.