From 323e373d0e4b42f1473345d979064d3565969bdd Mon Sep 17 00:00:00 2001 From: Sebastian Bugge Date: Fri, 4 Oct 2024 04:11:26 +0200 Subject: [PATCH] Almost working jump. --- src/main/scala/CPU.scala | 6 +++ src/main/scala/Decoder.scala | 72 +++++++++++++++------------- src/main/scala/EX.scala | 1 + src/main/scala/EXBarrier.scala | 12 +++++ src/main/scala/ID.scala | 5 ++ src/main/scala/IDBarrier.scala | 12 +++++ src/main/scala/MEM.scala | 4 +- src/main/scala/ToplevelSignals.scala | 1 + src/test/resources/tests/jump.s | 11 +++++ 9 files changed, 89 insertions(+), 35 deletions(-) create mode 100644 src/test/resources/tests/jump.s diff --git a/src/main/scala/CPU.scala b/src/main/scala/CPU.scala index 8fd4b3a..859838e 100644 --- a/src/main/scala/CPU.scala +++ b/src/main/scala/CPU.scala @@ -66,6 +66,8 @@ class CPU extends MultiIOModule { IDBarrier.r1ValueIn := ID.io.r1Value IDBarrier.r2ValueIn := ID.io.r2Value IDBarrier.ALUopIn := ID.io.ALUOp + IDBarrier.returnAddrIn := ID.io.returnAddr + IDBarrier.jumpIn := ID.io.jump IDBarrier.branchTypeIn := ID.io.branchType IDBarrier.writeEnableIn := ID.io.writeEnableOut IDBarrier.writeAddrIn := ID.io.writeAddrOut @@ -82,12 +84,16 @@ class CPU extends MultiIOModule { EXBarrier.r2ValueIn := EX.io.rs2ValueOut.asUInt() EXBarrier.ALUResultIn := EX.io.ALUResult.asUInt() EXBarrier.branchIn := EX.io.branch + EXBarrier.jumpIn := IDBarrier.jumpOut + EXBarrier.returnAddrIn := IDBarrier.returnAddrOut EXBarrier.writeEnableIn := IDBarrier.writeEnableOut EXBarrier.writeAddrIn := IDBarrier.writeAddrOut EXBarrier.memWriteIn := IDBarrier.memWriteOut EXBarrier.memReadIn := IDBarrier.memReadOut MEM.io.ALUResult := EXBarrier.ALUResultOut + MEM.io.jump := EXBarrier.jumpOut + MEM.io.returnAddr := EXBarrier.returnAddrOut MEM.io.writeMem := EXBarrier.memWriteOut MEM.io.readMem := EXBarrier.memReadOut MEM.io.writeData := EXBarrier.r2ValueOut diff --git a/src/main/scala/Decoder.scala b/src/main/scala/Decoder.scala index 5cd321d..f4ddd66 100644 --- a/src/main/scala/Decoder.scala +++ b/src/main/scala/Decoder.scala @@ -46,44 +46,48 @@ class Decoder() extends Module { */ val opcodeMap: Array[(BitPat, List[UInt])] = Array( - // signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp - ADD -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.ADD ), - SUB -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SUB ), - AND -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.AND ), - OR -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.OR ), - XOR -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.XOR ), - SLT -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SLT ), - SLTU -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SLTU ), - SRA -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SRA ), - SRL -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SRL ), - SLL -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SLL ), + // signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp + ADD -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.ADD ), + SUB -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SUB ), + AND -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.AND ), + OR -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.OR ), + XOR -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.XOR ), + SLT -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SLT ), + SLTU -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SLTU ), + SRA -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SRA ), + SRL -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SRL ), + SLL -> List(Y, N, N, N, N, branchType.DC, rs1, rs2, ImmFormat.DC, ALUOps.SLL ), - // signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp - ADDI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.ADD ), - ANDI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.AND ), - ORI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.OR ), - XORI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.XOR ), - SLTI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.SLT ), - SLTIU -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.SLTU ), - SRAI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.SRA ), - SRLI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.SRL ), - SLLI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.SLL ), + // signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp + ADDI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.ADD ), + ANDI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.AND ), + ORI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.OR ), + XORI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.XOR ), + SLTI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.SLT ), + SLTIU -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.SLTU ), + SRAI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.SRA ), + SRLI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.SRL ), + SLLI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.SLL ), - // signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp - LUI -> List(Y, N, N, N, N, branchType.DC, Op1Select.DC, imm, ImmFormat.UTYPE, ALUOps.COPY_B), - AUIPC -> List(Y, N, N, N, N, branchType.DC, Op1Select.PC, imm, ImmFormat.UTYPE, ALUOps.ADD ), + // signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp + LUI -> List(Y, N, N, N, N, branchType.DC, Op1Select.DC, imm, ImmFormat.UTYPE, ALUOps.COPY_B), + AUIPC -> List(Y, N, N, N, N, branchType.DC, Op1Select.PC, imm, ImmFormat.UTYPE, ALUOps.ADD ), - // signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp - LW -> List(Y, Y, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.ADD ), - SW -> List(N, N, Y, N, N, branchType.DC, rs1, imm, ImmFormat.STYPE, ALUOps.ADD ), + // signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp + LW -> List(Y, Y, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.ADD ), + SW -> List(N, N, Y, N, N, branchType.DC, rs1, imm, ImmFormat.STYPE, ALUOps.ADD ), - // signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp - BEQ -> List(N, N, N, Y, N, branchType.beq, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ), - BNE -> List(N, N, N, Y, N, branchType.neq, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ), - BLT -> List(N, N, N, Y, N, branchType.lt, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ), - BGE -> List(N, N, N, Y, N, branchType.gte, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ), - BLTU -> List(N, N, N, Y, N, branchType.ltu, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ), - BGEU -> List(N, N, N, Y, N, branchType.gteu,PC, imm, ImmFormat.BTYPE, ALUOps.ADD ), + // signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp + BEQ -> List(N, N, N, Y, N, branchType.beq, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ), + BNE -> List(N, N, N, Y, N, branchType.neq, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ), + BLT -> List(N, N, N, Y, N, branchType.lt, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ), + BGE -> List(N, N, N, Y, N, branchType.gte, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ), + BLTU -> List(N, N, N, Y, N, branchType.ltu, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ), + BGEU -> List(N, N, N, Y, N, branchType.gteu, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ), + + // signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp + JAL -> List(Y, N, N, Y, Y, branchType.jump, PC, imm, ImmFormat.JTYPE, ALUOps.ADD ), + JALR -> List(Y, N, N, Y, Y, branchType.jump, rs1, imm, ImmFormat.JTYPE, ALUOps.ADDR ), ) diff --git a/src/main/scala/EX.scala b/src/main/scala/EX.scala index 539ae2d..a65bb61 100644 --- a/src/main/scala/EX.scala +++ b/src/main/scala/EX.scala @@ -31,6 +31,7 @@ class Execute extends MultiIOModule { ALUOps.SRA -> (io.op1 >> io.op2(4, 0)), ALUOps.SRL -> (io.op1.asUInt() >> io.op2(4, 0)).asSInt(), ALUOps.SLL -> (io.op1.asUInt() << io.op2(4, 0)).asSInt(), + ALUOps.ADDR -> ((io.op1 + io.op2) & -2.S), ALUOps.COPY_A -> io.op1, ALUOps.COPY_B -> io.op2, ) diff --git a/src/main/scala/EXBarrier.scala b/src/main/scala/EXBarrier.scala index d61babe..2bbd918 100644 --- a/src/main/scala/EXBarrier.scala +++ b/src/main/scala/EXBarrier.scala @@ -9,6 +9,8 @@ class EXBarrier extends MultiIOModule { val ALUResultIn = Input(UInt(32.W)) val ALUResultOut = Output(UInt(32.W)) val branchAddress = Output(UInt(32.W)) + val returnAddrIn = Input(UInt(32.W)) + val returnAddrOut = Output(UInt(32.W)) val r2ValueIn = Input(UInt(32.W)) val r2ValueOut = Output(UInt(32.W)) val writeAddrIn = Input(UInt(5.W)) @@ -21,6 +23,8 @@ class EXBarrier extends MultiIOModule { val memWriteOut = Output(Bool()) val branchIn = Input(Bool()) val branchOut = Output(Bool()) + val jumpIn = Input(Bool()) + val jumpOut = Output(Bool()) }) io.ALUResultOut := io.ALUResultIn @@ -28,6 +32,10 @@ class EXBarrier extends MultiIOModule { branchAddress := io.ALUResultIn io.branchAddress := branchAddress + val returnAddr = RegInit(UInt(32.W), 0.U) + returnAddr := io.returnAddrIn + io.returnAddrOut := returnAddr + val r2Value = RegInit(UInt(32.W), 0.U) r2Value := io.r2ValueIn io.r2ValueOut := r2Value @@ -51,5 +59,9 @@ class EXBarrier extends MultiIOModule { val branch = RegInit(Bool(), false.B) branch := io.branchIn io.branchOut := branch + + val jump = RegInit(Bool(), false.B) + jump := io.jumpIn + io.jumpOut := jump } diff --git a/src/main/scala/ID.scala b/src/main/scala/ID.scala index cda89dc..9b5ebfb 100644 --- a/src/main/scala/ID.scala +++ b/src/main/scala/ID.scala @@ -33,6 +33,8 @@ class InstructionDecode extends MultiIOModule { val memWrite = Output(Bool()) val memRead = Output(Bool()) val branchType = Output(UInt(3.W)) + val jump = Output(Bool()) + val returnAddr = Output(UInt(32.W)) } ) @@ -73,6 +75,9 @@ class InstructionDecode extends MultiIOModule { io.r1Value := registers.io.readData1 io.r2Value := registers.io.readData2 + io.jump := decoder.controlSignals.jump + io.returnAddr := io.pc + 4.U + io.ALUOp := decoder.ALUop io.branchType := decoder.branchType io.writeAddrOut := decoder.instruction.registerRd diff --git a/src/main/scala/IDBarrier.scala b/src/main/scala/IDBarrier.scala index 749ae3c..e087a35 100644 --- a/src/main/scala/IDBarrier.scala +++ b/src/main/scala/IDBarrier.scala @@ -14,6 +14,10 @@ class IDBarrier extends MultiIOModule { val r1ValueOut = Output(UInt(32.W)) val r2ValueIn = Input(UInt(32.W)) val r2ValueOut = Output(UInt(32.W)) + val returnAddrIn = Input(UInt(32.W)) + val returnAddrOut = Output(UInt(32.W)) + val jumpIn = Input(Bool()) + val jumpOut = Output(Bool()) val ALUopIn = Input(UInt(4.W)) val ALUopOut = Output(UInt(4.W)) val branchTypeIn = Input(UInt(3.W)) @@ -44,6 +48,14 @@ class IDBarrier extends MultiIOModule { r2Value := io.r2ValueIn io.r2ValueOut := r2Value + val returnAddr = RegInit(UInt(32.W), 0.U) + returnAddr := io.returnAddrIn + io.returnAddrOut := returnAddr + + val jump = RegInit(UInt(32.W), 0.U) + jump := io.jumpIn + io.jumpOut := jump + val ALUop = RegInit(UInt(4.W), 0.U) ALUop := io.ALUopIn io.ALUopOut := ALUop diff --git a/src/main/scala/MEM.scala b/src/main/scala/MEM.scala index dd641c1..723b85b 100644 --- a/src/main/scala/MEM.scala +++ b/src/main/scala/MEM.scala @@ -23,6 +23,8 @@ class MemoryFetch() extends MultiIOModule { val readMem = Input(Bool()) val writeMem = Input(Bool()) val dataOut = Output(UInt(32.W)) + val jump = Input(Bool()) + val returnAddr = Input(UInt(32.W)) }) @@ -49,5 +51,5 @@ class MemoryFetch() extends MultiIOModule { DMEM.io.writeEnable := io.writeMem DMEM.io.dataAddress := Mux(io.writeMem, ALUResult, io.ALUResult) - io.dataOut := Mux(io.readMem, DMEM.io.dataOut, ALUResult) + io.dataOut := Mux(io.readMem, DMEM.io.dataOut, Mux(io.jump, io.returnAddr, ALUResult)) } diff --git a/src/main/scala/ToplevelSignals.scala b/src/main/scala/ToplevelSignals.scala index 7fe70f5..e56b572 100644 --- a/src/main/scala/ToplevelSignals.scala +++ b/src/main/scala/ToplevelSignals.scala @@ -119,6 +119,7 @@ object ALUOps { val SRA = 9.U(4.W) val COPY_A = 10.U(4.W) val COPY_B = 11.U(4.W) + val ADDR = 12.U(4.W) val DC = 15.U(4.W) } diff --git a/src/test/resources/tests/jump.s b/src/test/resources/tests/jump.s new file mode 100644 index 0000000..e9334e9 --- /dev/null +++ b/src/test/resources/tests/jump.s @@ -0,0 +1,11 @@ +main: + addi x2, x2, 4 + j loop + +end: + done + +loop: + bge x1, x2, end + addi x1, x1, 1 + j loop \ No newline at end of file