From 97b13a813f8954fb23499cabd36faf833e91593d Mon Sep 17 00:00:00 2001 From: Sebastian Bugge Date: Fri, 1 Nov 2024 03:02:36 +0100 Subject: [PATCH 01/10] Actually fix forwarding. --- src/main/scala/CPU.scala | 8 +-- src/main/scala/EXBarrier.scala | 7 -- src/main/scala/IDBarrier.scala | 124 +++++++++++++++----------------- src/main/scala/MEMBarrier.scala | 16 ++++- src/test/scala/Manifest.scala | 2 +- 5 files changed, 78 insertions(+), 79 deletions(-) diff --git a/src/main/scala/CPU.scala b/src/main/scala/CPU.scala index bc6ffe1..dc57158 100644 --- a/src/main/scala/CPU.scala +++ b/src/main/scala/CPU.scala @@ -117,10 +117,6 @@ class CPU extends MultiIOModule { IF.io.branchAddress := EXBarrier.ALUResultOut // Forwarding - IDBarrier.forwardExData := EXBarrier.forwardExData - IDBarrier.forwardEx := EXBarrier.forwardEx - IDBarrier.forwardExAddr := EXBarrier.forwardExAddr - IDBarrier.forwardMemData := MEMBarrier.forwardMemData IDBarrier.forwardMem := MEMBarrier.forwardMem IDBarrier.forwardMemAddr := MEMBarrier.forwardMemAddr @@ -129,6 +125,10 @@ class CPU extends MultiIOModule { IDBarrier.forwardWb := MEMBarrier.forwardWb IDBarrier.forwardWbAddr := MEMBarrier.forwardWbAddr + IDBarrier.forwardIdData := MEMBarrier.forwardIdData + IDBarrier.forwardId := MEMBarrier.forwardId + IDBarrier.forwardIdAddr := MEMBarrier.forwardIdAddr + // Stall IF.io.stall := ID.io.stall } diff --git a/src/main/scala/EXBarrier.scala b/src/main/scala/EXBarrier.scala index 9ba6cfc..4d74cda 100644 --- a/src/main/scala/EXBarrier.scala +++ b/src/main/scala/EXBarrier.scala @@ -24,9 +24,6 @@ class EXBarrier extends MultiIOModule { val branchOut = Output(Bool()) val jumpIn = Input(Bool()) val jumpOut = Output(Bool()) - val forwardEx = Output(Bool()) - val forwardExAddr = Output(UInt(5.W)) - val forwardExData = Output(UInt(32.W)) }) val ALUResult = RegInit(UInt(32.W), 0.U) @@ -64,8 +61,4 @@ class EXBarrier extends MultiIOModule { val jump = RegInit(Bool(), false.B) jump := io.jumpIn io.jumpOut := jump - - io.forwardEx := io.writeEnableIn && !io.memReadIn - io.forwardExAddr := io.writeAddrIn - io.forwardExData := io.ALUResultIn } diff --git a/src/main/scala/IDBarrier.scala b/src/main/scala/IDBarrier.scala index c297af2..cb9c7e8 100644 --- a/src/main/scala/IDBarrier.scala +++ b/src/main/scala/IDBarrier.scala @@ -37,15 +37,15 @@ class IDBarrier extends MultiIOModule { val memWriteIn = Input(Bool()) val memWriteOut = Output(Bool()) - val forwardEx = Input(Bool()) - val forwardExAddr = Input(UInt(5.W)) - val forwardExData = Input(UInt(32.W)) val forwardMem = Input(Bool()) val forwardMemAddr = Input(UInt(5.W)) val forwardMemData = Input(UInt(32.W)) val forwardWb = Input(Bool()) val forwardWbAddr = Input(UInt(5.W)) val forwardWbData = Input(UInt(32.W)) + val forwardId = Input(Bool()) + val forwardIdAddr = Input(UInt(5.W)) + val forwardIdData = Input(UInt(32.W)) }) val isOp1RValue = RegInit(Bool(), false.B) @@ -53,77 +53,69 @@ class IDBarrier extends MultiIOModule { val isOp2RValue = RegInit(Bool(), false.B) isOp2RValue := io.isOp2RValue - val op1 = RegInit(SInt(32.W), 0.S) - op1 := Mux( - io.forwardEx && io.isOp1RValue && io.r1AddressIn === io.forwardExAddr, - io.forwardExData.asSInt(), - Mux( - io.forwardMem && io.isOp1RValue && io.r1AddressIn === io.forwardMemAddr, - io.forwardMemData.asSInt(), - Mux( - io.forwardWb && io.isOp1RValue && io.r1AddressIn === io.forwardWbAddr, - io.forwardWbData.asSInt(), - io.op1in.asSInt(), - ), - ), - ) - io.op1out := op1 - - val op2 = RegInit(SInt(32.W), 0.S) - op2 := Mux( - io.forwardEx && io.isOp2RValue && io.r2AddressIn === io.forwardExAddr, - io.forwardExData.asSInt(), - Mux( - io.forwardMem && io.isOp2RValue && io.r2AddressIn === io.forwardMemAddr, - io.forwardMemData.asSInt(), - Mux( - io.forwardWb && io.isOp2RValue && io.r2AddressIn === io.forwardWbAddr, - io.forwardWbData.asSInt(), - io.op2in, - ), - ), - ) - io.op2out := op2 - - val r1Value = RegInit(UInt(32.W), 0.U) - r1Value := Mux( - io.forwardEx && io.r1AddressIn === io.forwardExAddr, - io.forwardExData, - Mux( - io.forwardMem && io.isOp1RValue && io.r1AddressIn === io.forwardMemAddr, - io.forwardMemData, - Mux( - io.forwardWb && io.isOp1RValue && io.r1AddressIn === io.forwardWbAddr, - io.forwardWbData, - io.r1ValueIn, - ), - ), - ) - io.r1ValueOut := r1Value + val r2Address = RegInit(UInt(5.W), 0.U) + r2Address := io.r2AddressIn + io.r2AddressOut := r2Address val r1Address = RegInit(UInt(5.W), 0.U) r1Address := io.r1AddressIn io.r1AddressOut := r1Address - val r2Value = RegInit(UInt(32.W), 0.U) - r2Value := Mux( - io.forwardEx && io.r2AddressIn === io.forwardExAddr, - io.forwardExData, + val op1 = RegInit(SInt(32.W), 0.S) + op1 := io.op1in + io.op1out := Mux( + io.forwardMem && isOp1RValue && r1Address === io.forwardMemAddr, + io.forwardMemData.asSInt(), Mux( - io.forwardMem && io.r2AddressIn === io.forwardMemAddr, - io.forwardMemData, + io.forwardWb && isOp1RValue && r1Address === io.forwardWbAddr, + io.forwardWbData.asSInt(), Mux( - io.forwardWb && io.r2AddressIn === io.forwardWbAddr, - io.forwardWbData, - io.r2ValueIn, - ), - ), - ) - io.r2ValueOut := r2Value + io.forwardId && isOp1RValue && r1Address === io.forwardIdAddr, + io.forwardIdData.asSInt(), + op1.asSInt(), + ))) - val r2Address = RegInit(UInt(5.W), 0.U) - r2Address := io.r2AddressIn - io.r2AddressOut := r2Address + val op2 = RegInit(SInt(32.W), 0.S) + op2 := io.op2in + io.op2out := Mux( + io.forwardMem && isOp2RValue && r2Address === io.forwardMemAddr, + io.forwardMemData.asSInt(), + Mux( + io.forwardWb && isOp2RValue && r2Address === io.forwardWbAddr, + io.forwardWbData.asSInt(), + Mux( + io.forwardId && isOp2RValue && r2Address === io.forwardIdAddr, + io.forwardIdData.asSInt(), + op2.asSInt(), + ))) + + val r1Value = RegInit(UInt(32.W), 0.U) + r1Value := io.r1ValueIn + io.r1ValueOut := Mux( + io.forwardMem && r1Address === io.forwardMemAddr, + io.forwardMemData, + Mux( + io.forwardWb && r1Address === io.forwardWbAddr, + io.forwardWbData, + Mux( + io.forwardId && r1Address === io.forwardIdAddr, + io.forwardIdData, + r1Value, + ))) + + val r2Value = RegInit(UInt(32.W), 0.U) + r2Value := io.r2ValueIn + io.r2ValueOut := Mux( + io.forwardMem && r2Address === io.forwardMemAddr, + io.forwardMemData, + Mux( + io.forwardWb && r2Address === io.forwardWbAddr, + io.forwardWbData, + Mux( + io.forwardId && r2Address === io.forwardIdAddr, + io.forwardIdData, + r2Value, + ))) val returnAddr = RegInit(UInt(32.W), 0.U) returnAddr := io.returnAddrIn diff --git a/src/main/scala/MEMBarrier.scala b/src/main/scala/MEMBarrier.scala index ed36d1a..57e6fc1 100644 --- a/src/main/scala/MEMBarrier.scala +++ b/src/main/scala/MEMBarrier.scala @@ -18,6 +18,9 @@ class MEMBarrier extends MultiIOModule { val forwardWb = Output(Bool()) val forwardWbAddr = Output(UInt(5.W)) val forwardWbData = Output(UInt(32.W)) + val forwardId = Output(Bool()) + val forwardIdAddr = Output(UInt(5.W)) + val forwardIdData = Output(UInt(32.W)) }) val memRead = RegInit(Bool(), false.B) @@ -41,5 +44,16 @@ class MEMBarrier extends MultiIOModule { io.forwardWb := writeEnable io.forwardWbAddr := writeAddr - io.forwardWbData := Mux(memRead, io.dataIn, data) + io.forwardWbData := io.dataOut + + val forwardId = RegInit(Bool(), false.B) + forwardId := writeEnable + val forwardIdAddr = RegInit(UInt(5.W), 0.U) + forwardIdAddr := io.writeAddrOut + val forwardIdData = RegInit(UInt(32.W), 0.U) + forwardIdData := io.dataOut + + io.forwardId := forwardId + io.forwardIdAddr := forwardIdAddr + io.forwardIdData := forwardIdData } diff --git a/src/test/scala/Manifest.scala b/src/test/scala/Manifest.scala index eaf8823..bc851f7 100644 --- a/src/test/scala/Manifest.scala +++ b/src/test/scala/Manifest.scala @@ -19,7 +19,7 @@ import LogParser._ object Manifest { - val singleTest = "load3.s" + val singleTest = "forward1.s" val nopPadded = false From 800e7b6eb0cf2e434bbdcb104c2bb8b0a93d7825 Mon Sep 17 00:00:00 2001 From: Sebastian Bugge Date: Fri, 1 Nov 2024 03:13:00 +0100 Subject: [PATCH 02/10] Rewrite stall to be more modular. --- src/main/scala/ID.scala | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/main/scala/ID.scala b/src/main/scala/ID.scala index 8942aa8..a3adb11 100644 --- a/src/main/scala/ID.scala +++ b/src/main/scala/ID.scala @@ -89,10 +89,19 @@ class InstructionDecode extends MultiIOModule { io.branchType := decoder.branchType io.writeAddrOut := decoder.instruction.registerRd - val stallDelay = RegInit(Bool(), false.B) - val stall = Mux(stallDelay, false.B, decoder.controlSignals.memRead) + val stallsRemaining = RegInit(UInt(4.W), 0.U) + val stallDelay = stallsRemaining > 0.U + stallsRemaining := Mux( + stallDelay, + stallsRemaining - 1.U, + Mux( + decoder.controlSignals.memRead, + 1.U, + 0.U + )) + + val stall = stallsRemaining > 1.U || decoder.controlSignals.memRead && !stallDelay io.stall := stall - stallDelay := stall io.jump := Mux(stallDelay, false.B, decoder.controlSignals.jump) io.returnAddr := io.pc + 4.U From 804e1ed2e67bc156efea3cd9d70a1e216165722e Mon Sep 17 00:00:00 2001 From: Sebastian Bugge Date: Fri, 1 Nov 2024 03:32:59 +0100 Subject: [PATCH 03/10] It works! --- src/main/scala/ID.scala | 10 +++++++--- src/main/scala/IF.scala | 2 +- src/test/resources/tests/branch.s | 1 + src/test/scala/Manifest.scala | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/scala/ID.scala b/src/main/scala/ID.scala index a3adb11..7ea6e01 100644 --- a/src/main/scala/ID.scala +++ b/src/main/scala/ID.scala @@ -86,7 +86,6 @@ class InstructionDecode extends MultiIOModule { io.r2Address := registers.io.readAddress2 io.ALUOp := decoder.ALUop - io.branchType := decoder.branchType io.writeAddrOut := decoder.instruction.registerRd val stallsRemaining = RegInit(UInt(4.W), 0.U) @@ -97,13 +96,18 @@ class InstructionDecode extends MultiIOModule { Mux( decoder.controlSignals.memRead, 1.U, - 0.U + Mux( + decoder.controlSignals.branch, + 3.U, + 0.U + ) )) - val stall = stallsRemaining > 1.U || decoder.controlSignals.memRead && !stallDelay + val stall = stallsRemaining > 1.U || decoder.controlSignals.memRead && !stallDelay || decoder.controlSignals.branch && !stallDelay io.stall := stall io.jump := Mux(stallDelay, false.B, decoder.controlSignals.jump) + io.branchType := Mux(stallDelay, branchType.DC, decoder.branchType) io.returnAddr := io.pc + 4.U io.writeEnableOut := Mux(stallDelay, false.B, decoder.controlSignals.regWrite) diff --git a/src/main/scala/IF.scala b/src/main/scala/IF.scala index 35b0842..b4fd54a 100644 --- a/src/main/scala/IF.scala +++ b/src/main/scala/IF.scala @@ -48,7 +48,7 @@ class InstructionFetch extends MultiIOModule { */ io.PC := PC IMEM.io.instructionAddress := PC - PC := Mux(io.stall, PC, Mux(io.branch, io.branchAddress, PC + 4.U)) + PC := Mux(io.branch, io.branchAddress, Mux(io.stall, PC, PC + 4.U)) val instruction = Wire(new Instruction) instruction := IMEM.io.instruction.asTypeOf(new Instruction) diff --git a/src/test/resources/tests/branch.s b/src/test/resources/tests/branch.s index 0761396..64d56ef 100644 --- a/src/test/resources/tests/branch.s +++ b/src/test/resources/tests/branch.s @@ -4,4 +4,5 @@ main: loop: addi x2, x2, 1 blt x2, x1, loop + nop done \ No newline at end of file diff --git a/src/test/scala/Manifest.scala b/src/test/scala/Manifest.scala index bc851f7..d10ed8a 100644 --- a/src/test/scala/Manifest.scala +++ b/src/test/scala/Manifest.scala @@ -19,7 +19,7 @@ import LogParser._ object Manifest { - val singleTest = "forward1.s" + val singleTest = "branch.s" val nopPadded = false From 1eefeca2d6c2fd4617eb43d823e26007024a3a17 Mon Sep 17 00:00:00 2001 From: Sebastian Bugge Date: Tue, 5 Nov 2024 14:13:15 +0100 Subject: [PATCH 04/10] Simplify forwarding. --- src/main/scala/CPU.scala | 8 ---- src/main/scala/IDBarrier.scala | 60 ++++++++++++++---------------- src/main/scala/MEMBarrier.scala | 37 +++++++++--------- src/test/resources/tests/addload.s | 5 +++ src/test/resources/tests/branch.s | 1 - src/test/resources/tests/fucked.s | 18 +++++++++ src/test/scala/Manifest.scala | 2 +- 7 files changed, 70 insertions(+), 61 deletions(-) create mode 100644 src/test/resources/tests/addload.s create mode 100644 src/test/resources/tests/fucked.s diff --git a/src/main/scala/CPU.scala b/src/main/scala/CPU.scala index dc57158..a34dfc7 100644 --- a/src/main/scala/CPU.scala +++ b/src/main/scala/CPU.scala @@ -117,17 +117,9 @@ class CPU extends MultiIOModule { IF.io.branchAddress := EXBarrier.ALUResultOut // Forwarding - IDBarrier.forwardMemData := MEMBarrier.forwardMemData IDBarrier.forwardMem := MEMBarrier.forwardMem - IDBarrier.forwardMemAddr := MEMBarrier.forwardMemAddr - - IDBarrier.forwardWbData := MEMBarrier.forwardWbData IDBarrier.forwardWb := MEMBarrier.forwardWb - IDBarrier.forwardWbAddr := MEMBarrier.forwardWbAddr - - IDBarrier.forwardIdData := MEMBarrier.forwardIdData IDBarrier.forwardId := MEMBarrier.forwardId - IDBarrier.forwardIdAddr := MEMBarrier.forwardIdAddr // Stall IF.io.stall := ID.io.stall diff --git a/src/main/scala/IDBarrier.scala b/src/main/scala/IDBarrier.scala index cb9c7e8..fe0ee47 100644 --- a/src/main/scala/IDBarrier.scala +++ b/src/main/scala/IDBarrier.scala @@ -37,15 +37,9 @@ class IDBarrier extends MultiIOModule { val memWriteIn = Input(Bool()) val memWriteOut = Output(Bool()) - val forwardMem = Input(Bool()) - val forwardMemAddr = Input(UInt(5.W)) - val forwardMemData = Input(UInt(32.W)) - val forwardWb = Input(Bool()) - val forwardWbAddr = Input(UInt(5.W)) - val forwardWbData = Input(UInt(32.W)) - val forwardId = Input(Bool()) - val forwardIdAddr = Input(UInt(5.W)) - val forwardIdData = Input(UInt(32.W)) + val forwardMem = Input(new Forwarding) + val forwardWb = Input(new Forwarding) + val forwardId = Input(new Forwarding) }) val isOp1RValue = RegInit(Bool(), false.B) @@ -64,56 +58,56 @@ class IDBarrier extends MultiIOModule { val op1 = RegInit(SInt(32.W), 0.S) op1 := io.op1in io.op1out := Mux( - io.forwardMem && isOp1RValue && r1Address === io.forwardMemAddr, - io.forwardMemData.asSInt(), + isOp1RValue && io.forwardMem.valid && r1Address === io.forwardMem.writeAddr, + io.forwardMem.writeData.asSInt(), Mux( - io.forwardWb && isOp1RValue && r1Address === io.forwardWbAddr, - io.forwardWbData.asSInt(), + isOp1RValue && io.forwardWb.valid && r1Address === io.forwardWb.writeAddr, + io.forwardWb.writeData.asSInt(), Mux( - io.forwardId && isOp1RValue && r1Address === io.forwardIdAddr, - io.forwardIdData.asSInt(), + isOp1RValue && io.forwardId.valid && r1Address === io.forwardId.writeAddr, + io.forwardId.writeData.asSInt(), op1.asSInt(), ))) val op2 = RegInit(SInt(32.W), 0.S) op2 := io.op2in io.op2out := Mux( - io.forwardMem && isOp2RValue && r2Address === io.forwardMemAddr, - io.forwardMemData.asSInt(), + isOp2RValue && io.forwardMem.valid && r2Address === io.forwardMem.writeAddr, + io.forwardMem.writeData.asSInt(), Mux( - io.forwardWb && isOp2RValue && r2Address === io.forwardWbAddr, - io.forwardWbData.asSInt(), + isOp2RValue && io.forwardWb.valid && r2Address === io.forwardWb.writeAddr, + io.forwardWb.writeData.asSInt(), Mux( - io.forwardId && isOp2RValue && r2Address === io.forwardIdAddr, - io.forwardIdData.asSInt(), + isOp2RValue && io.forwardId.valid && r2Address === io.forwardId.writeAddr, + io.forwardId.writeData.asSInt(), op2.asSInt(), ))) val r1Value = RegInit(UInt(32.W), 0.U) r1Value := io.r1ValueIn io.r1ValueOut := Mux( - io.forwardMem && r1Address === io.forwardMemAddr, - io.forwardMemData, + io.forwardMem.valid && r1Address === io.forwardMem.writeAddr, + io.forwardMem.writeData, Mux( - io.forwardWb && r1Address === io.forwardWbAddr, - io.forwardWbData, + io.forwardWb.valid && r1Address === io.forwardWb.writeAddr, + io.forwardWb.writeData, Mux( - io.forwardId && r1Address === io.forwardIdAddr, - io.forwardIdData, + io.forwardId.valid && r1Address === io.forwardId.writeAddr, + io.forwardId.writeData, r1Value, ))) val r2Value = RegInit(UInt(32.W), 0.U) r2Value := io.r2ValueIn io.r2ValueOut := Mux( - io.forwardMem && r2Address === io.forwardMemAddr, - io.forwardMemData, + io.forwardMem.valid && r2Address === io.forwardMem.writeAddr, + io.forwardMem.writeData, Mux( - io.forwardWb && r2Address === io.forwardWbAddr, - io.forwardWbData, + io.forwardWb.valid && r2Address === io.forwardWb.writeAddr, + io.forwardWb.writeData, Mux( - io.forwardId && r2Address === io.forwardIdAddr, - io.forwardIdData, + io.forwardId.valid && r2Address === io.forwardId.writeAddr, + io.forwardId.writeData, r2Value, ))) diff --git a/src/main/scala/MEMBarrier.scala b/src/main/scala/MEMBarrier.scala index 57e6fc1..1187a9f 100644 --- a/src/main/scala/MEMBarrier.scala +++ b/src/main/scala/MEMBarrier.scala @@ -12,15 +12,9 @@ class MEMBarrier extends MultiIOModule { val writeEnableIn = Input(Bool()) val writeEnableOut = Output(Bool()) val memRead = Input(Bool()) - val forwardMem = Output(Bool()) - val forwardMemAddr = Output(UInt(5.W)) - val forwardMemData = Output(UInt(32.W)) - val forwardWb = Output(Bool()) - val forwardWbAddr = Output(UInt(5.W)) - val forwardWbData = Output(UInt(32.W)) - val forwardId = Output(Bool()) - val forwardIdAddr = Output(UInt(5.W)) - val forwardIdData = Output(UInt(32.W)) + val forwardMem = Output(new Forwarding) + val forwardWb = Output(new Forwarding) + val forwardId = Output(new Forwarding) }) val memRead = RegInit(Bool(), false.B) @@ -38,13 +32,13 @@ class MEMBarrier extends MultiIOModule { writeEnable := io.writeEnableIn io.writeEnableOut := writeEnable - io.forwardMem := io.writeEnableIn && !io.memRead - io.forwardMemAddr := io.writeAddrIn - io.forwardMemData := io.dataIn + io.forwardMem.write := io.writeEnableIn && !io.memRead + io.forwardMem.writeAddr := io.writeAddrIn + io.forwardMem.writeData := io.dataIn - io.forwardWb := writeEnable - io.forwardWbAddr := writeAddr - io.forwardWbData := io.dataOut + io.forwardWb.write := writeEnable + io.forwardWb.writeAddr := writeAddr + io.forwardWb.writeData := io.dataOut val forwardId = RegInit(Bool(), false.B) forwardId := writeEnable @@ -53,7 +47,14 @@ class MEMBarrier extends MultiIOModule { val forwardIdData = RegInit(UInt(32.W), 0.U) forwardIdData := io.dataOut - io.forwardId := forwardId - io.forwardIdAddr := forwardIdAddr - io.forwardIdData := forwardIdData + io.forwardId.write := forwardId + io.forwardId.writeAddr := forwardIdAddr + io.forwardId.writeData := forwardIdData +} + +class Forwarding extends Bundle { + val writeAddr = UInt(5.W) + val writeData = UInt(32.W) + val write = Bool() + def valid = write && (writeAddr =/= 0.U) } diff --git a/src/test/resources/tests/addload.s b/src/test/resources/tests/addload.s new file mode 100644 index 0000000..ea26489 --- /dev/null +++ b/src/test/resources/tests/addload.s @@ -0,0 +1,5 @@ +main: + addi a5,a5,2 + lw a4,-36(s0) + add a5,a4,a5 + done \ No newline at end of file diff --git a/src/test/resources/tests/branch.s b/src/test/resources/tests/branch.s index 64d56ef..0761396 100644 --- a/src/test/resources/tests/branch.s +++ b/src/test/resources/tests/branch.s @@ -4,5 +4,4 @@ main: loop: addi x2, x2, 1 blt x2, x1, loop - nop done \ No newline at end of file diff --git a/src/test/resources/tests/fucked.s b/src/test/resources/tests/fucked.s new file mode 100644 index 0000000..2661c5e --- /dev/null +++ b/src/test/resources/tests/fucked.s @@ -0,0 +1,18 @@ +main: + addi x2, x2, 0 + j loop + nop + nop + + +loop: + addi x1, x1, 32 + blt x1, x2, loop + nop + nop + nop + nop + j end + +end: + done diff --git a/src/test/scala/Manifest.scala b/src/test/scala/Manifest.scala index d10ed8a..01665d6 100644 --- a/src/test/scala/Manifest.scala +++ b/src/test/scala/Manifest.scala @@ -19,7 +19,7 @@ import LogParser._ object Manifest { - val singleTest = "branch.s" + val singleTest = "fucked.s" val nopPadded = false From 6d6474530ca0b92c69720fba840bb33c8a38f01a Mon Sep 17 00:00:00 2001 From: Sebastian Bugge Date: Thu, 7 Nov 2024 23:51:17 +0100 Subject: [PATCH 05/10] Simplify IDBarrier. --- src/main/scala/CPU.scala | 31 ++++++++++++---- src/main/scala/IDBarrier.scala | 65 +++++++--------------------------- 2 files changed, 38 insertions(+), 58 deletions(-) diff --git a/src/main/scala/CPU.scala b/src/main/scala/CPU.scala index a34dfc7..52738b2 100644 --- a/src/main/scala/CPU.scala +++ b/src/main/scala/CPU.scala @@ -54,6 +54,25 @@ class CPU extends MultiIOModule { /** TODO: Your code here */ + def forward(data: UInt, addr: UInt, useForward: Bool, mem: Forwarding, wb: Forwarding, id: Forwarding): UInt = { + Mux( + !useForward, + data, + Mux( + mem.valid && mem.writeAddr === addr, + mem.writeData, + Mux( + wb.valid && wb.writeAddr === addr, + wb.writeData, + Mux( + id.valid && id.writeAddr === addr, + id.writeData, + data, + ) + ) + ) + ) + } IFBarrier.PCin := IF.io.PC IFBarrier.instructionIn := IF.io.instruction @@ -63,8 +82,8 @@ class CPU extends MultiIOModule { IDBarrier.op1in := ID.io.op1 IDBarrier.op2in := ID.io.op2 - IDBarrier.isOp1RValue := ID.io.isOp1RValue - IDBarrier.isOp2RValue := ID.io.isOp2RValue + IDBarrier.isOp1RValueIn := ID.io.isOp1RValue + IDBarrier.isOp2RValueIn := ID.io.isOp2RValue IDBarrier.r1ValueIn := ID.io.r1Value IDBarrier.r2ValueIn := ID.io.r2Value IDBarrier.r1AddressIn := ID.io.r1Address @@ -78,12 +97,12 @@ class CPU extends MultiIOModule { IDBarrier.memWriteIn := ID.io.memWrite IDBarrier.memReadIn := ID.io.memRead - EX.io.op1 := IDBarrier.op1out - EX.io.op2 := IDBarrier.op2out + EX.io.op1 := forward(IDBarrier.op1out.asUInt(), IDBarrier.r1AddressOut, IDBarrier.isOp1RValueOut, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt() + EX.io.op2 := forward(IDBarrier.op2out.asUInt(), IDBarrier.r2AddressOut, IDBarrier.isOp2RValueOut, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt() EX.io.ALUOp := IDBarrier.ALUopOut EX.io.branchType := IDBarrier.branchTypeOut - EX.io.rs1ValueIn := IDBarrier.r1ValueOut.asSInt() - EX.io.rs2ValueIn := IDBarrier.r2ValueOut.asSInt() + EX.io.rs1ValueIn := forward(IDBarrier.r1ValueOut, IDBarrier.r1AddressOut, true.B, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt() + EX.io.rs2ValueIn := forward(IDBarrier.r2ValueOut, IDBarrier.r2AddressOut, true.B, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt() EXBarrier.r2ValueIn := EX.io.rs2ValueOut.asUInt() EXBarrier.ALUResultIn := EX.io.ALUResult.asUInt() diff --git a/src/main/scala/IDBarrier.scala b/src/main/scala/IDBarrier.scala index fe0ee47..26869d4 100644 --- a/src/main/scala/IDBarrier.scala +++ b/src/main/scala/IDBarrier.scala @@ -8,10 +8,12 @@ class IDBarrier extends MultiIOModule { new Bundle { val op1in = Input(SInt(32.W)) val op1out = Output(SInt(32.W)) - val isOp1RValue = Input(Bool()) + val isOp1RValueIn = Input(Bool()) + val isOp1RValueOut = Output(Bool()) val op2in = Input(SInt(32.W)) val op2out = Output(SInt(32.W)) - val isOp2RValue = Input(Bool()) + val isOp2RValueIn = Input(Bool()) + val isOp2RValueOut = Output(Bool()) val r1ValueIn = Input(UInt(32.W)) val r1ValueOut = Output(UInt(32.W)) val r1AddressIn = Input(UInt(5.W)) @@ -36,16 +38,15 @@ class IDBarrier extends MultiIOModule { val memReadOut = Output(Bool()) val memWriteIn = Input(Bool()) val memWriteOut = Output(Bool()) - - val forwardMem = Input(new Forwarding) - val forwardWb = Input(new Forwarding) - val forwardId = Input(new Forwarding) }) val isOp1RValue = RegInit(Bool(), false.B) - isOp1RValue := io.isOp1RValue + isOp1RValue := io.isOp1RValueIn + io.isOp1RValueOut := isOp1RValue + val isOp2RValue = RegInit(Bool(), false.B) - isOp2RValue := io.isOp2RValue + isOp2RValue := io.isOp2RValueIn + io.isOp2RValueOut := isOp2RValue val r2Address = RegInit(UInt(5.W), 0.U) r2Address := io.r2AddressIn @@ -57,59 +58,19 @@ class IDBarrier extends MultiIOModule { val op1 = RegInit(SInt(32.W), 0.S) op1 := io.op1in - io.op1out := Mux( - isOp1RValue && io.forwardMem.valid && r1Address === io.forwardMem.writeAddr, - io.forwardMem.writeData.asSInt(), - Mux( - isOp1RValue && io.forwardWb.valid && r1Address === io.forwardWb.writeAddr, - io.forwardWb.writeData.asSInt(), - Mux( - isOp1RValue && io.forwardId.valid && r1Address === io.forwardId.writeAddr, - io.forwardId.writeData.asSInt(), - op1.asSInt(), - ))) + io.op1out := op1 val op2 = RegInit(SInt(32.W), 0.S) op2 := io.op2in - io.op2out := Mux( - isOp2RValue && io.forwardMem.valid && r2Address === io.forwardMem.writeAddr, - io.forwardMem.writeData.asSInt(), - Mux( - isOp2RValue && io.forwardWb.valid && r2Address === io.forwardWb.writeAddr, - io.forwardWb.writeData.asSInt(), - Mux( - isOp2RValue && io.forwardId.valid && r2Address === io.forwardId.writeAddr, - io.forwardId.writeData.asSInt(), - op2.asSInt(), - ))) + io.op2out := op2 val r1Value = RegInit(UInt(32.W), 0.U) r1Value := io.r1ValueIn - io.r1ValueOut := Mux( - io.forwardMem.valid && r1Address === io.forwardMem.writeAddr, - io.forwardMem.writeData, - Mux( - io.forwardWb.valid && r1Address === io.forwardWb.writeAddr, - io.forwardWb.writeData, - Mux( - io.forwardId.valid && r1Address === io.forwardId.writeAddr, - io.forwardId.writeData, - r1Value, - ))) + io.r1ValueOut := r1Value val r2Value = RegInit(UInt(32.W), 0.U) r2Value := io.r2ValueIn - io.r2ValueOut := Mux( - io.forwardMem.valid && r2Address === io.forwardMem.writeAddr, - io.forwardMem.writeData, - Mux( - io.forwardWb.valid && r2Address === io.forwardWb.writeAddr, - io.forwardWb.writeData, - Mux( - io.forwardId.valid && r2Address === io.forwardId.writeAddr, - io.forwardId.writeData, - r2Value, - ))) + io.r2ValueOut := r2Value val returnAddr = RegInit(UInt(32.W), 0.U) returnAddr := io.returnAddrIn From 42d77a0d85aea745c444990a64bdca6c555a3949 Mon Sep 17 00:00:00 2001 From: Sebastian Bugge Date: Fri, 8 Nov 2024 01:06:07 +0100 Subject: [PATCH 06/10] Simplify EXBarrier. --- src/main/scala/CPU.scala | 45 ++++++++++------------ src/main/scala/EXBarrier.scala | 70 +++++++++------------------------- 2 files changed, 37 insertions(+), 78 deletions(-) diff --git a/src/main/scala/CPU.scala b/src/main/scala/CPU.scala index 52738b2..8804a34 100644 --- a/src/main/scala/CPU.scala +++ b/src/main/scala/CPU.scala @@ -104,27 +104,27 @@ class CPU extends MultiIOModule { EX.io.rs1ValueIn := forward(IDBarrier.r1ValueOut, IDBarrier.r1AddressOut, true.B, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt() EX.io.rs2ValueIn := forward(IDBarrier.r2ValueOut, IDBarrier.r2AddressOut, true.B, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt() - 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 + EXBarrier.in.r2Value := EX.io.rs2ValueOut.asUInt() + EXBarrier.in.ALUResult := EX.io.ALUResult.asUInt() + EXBarrier.in.branch := EX.io.branch + EXBarrier.in.jump := IDBarrier.jumpOut + EXBarrier.in.returnAddr := IDBarrier.returnAddrOut + EXBarrier.in.writeEnable := IDBarrier.writeEnableOut + EXBarrier.in.writeAddr := IDBarrier.writeAddrOut + EXBarrier.in.memWrite := IDBarrier.memWriteOut + EXBarrier.in.memRead := 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 + MEM.io.ALUResult := EXBarrier.out.ALUResult + MEM.io.jump := EXBarrier.out.jump + MEM.io.returnAddr := EXBarrier.out.returnAddr + MEM.io.writeMem := EXBarrier.out.memWrite + MEM.io.readMem := EXBarrier.out.memRead + MEM.io.writeData := EXBarrier.out.r2Value - MEMBarrier.memRead := EXBarrier.memReadOut + MEMBarrier.memRead := EXBarrier.out.memRead MEMBarrier.dataIn := MEM.io.dataOut - MEMBarrier.writeEnableIn := EXBarrier.writeEnableOut - MEMBarrier.writeAddrIn := EXBarrier.writeAddrOut + MEMBarrier.writeEnableIn := EXBarrier.out.writeEnable + MEMBarrier.writeAddrIn := EXBarrier.out.writeAddr // Write back ID.io.writeData := MEMBarrier.dataOut @@ -132,13 +132,8 @@ class CPU extends MultiIOModule { ID.io.writeAddrIn := MEMBarrier.writeAddrOut // Branching - IF.io.branch := EXBarrier.branchOut - IF.io.branchAddress := EXBarrier.ALUResultOut - - // Forwarding - IDBarrier.forwardMem := MEMBarrier.forwardMem - IDBarrier.forwardWb := MEMBarrier.forwardWb - IDBarrier.forwardId := MEMBarrier.forwardId + IF.io.branch := EXBarrier.out.branch + IF.io.branchAddress := EXBarrier.out.ALUResult // Stall IF.io.stall := ID.io.stall diff --git a/src/main/scala/EXBarrier.scala b/src/main/scala/EXBarrier.scala index 4d74cda..2c79a95 100644 --- a/src/main/scala/EXBarrier.scala +++ b/src/main/scala/EXBarrier.scala @@ -3,62 +3,26 @@ package FiveStage import chisel3._ import chisel3.experimental.MultiIOModule +class EXBarrierIO extends Bundle { + val ALUResult = UInt(32.W) + val returnAddr = UInt(32.W) + val r2Value = UInt(32.W) + val writeAddr = UInt(5.W) + val writeEnable = Bool() + val memRead = Bool() + val memWrite = Bool() + val branch = Bool() + val jump = Bool() +} + class EXBarrier extends MultiIOModule { val io = IO( new Bundle { - val ALUResultIn = Input(UInt(32.W)) - val ALUResultOut = 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)) - val writeAddrOut = Output(UInt(5.W)) - val writeEnableIn = Input(Bool()) - val writeEnableOut = Output(Bool()) - val memReadIn = Input(Bool()) - val memReadOut = Output(Bool()) - val memWriteIn = Input(Bool()) - val memWriteOut = Output(Bool()) - val branchIn = Input(Bool()) - val branchOut = Output(Bool()) - val jumpIn = Input(Bool()) - val jumpOut = Output(Bool()) + val in = Input(new EXBarrierIO) + val out = Output(new EXBarrierIO) }) - val ALUResult = RegInit(UInt(32.W), 0.U) - ALUResult := io.ALUResultIn - io.ALUResultOut := ALUResult - - 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 - - val writeAddr = RegInit(UInt(5.W), 0.U) - writeAddr := io.writeAddrIn - io.writeAddrOut := writeAddr - - val writeEnable = RegInit(Bool(), false.B) - writeEnable := io.writeEnableIn - io.writeEnableOut := writeEnable - - val memRead = RegInit(Bool(), false.B) - memRead := io.memReadIn - io.memReadOut := memRead - - val memWrite = RegInit(Bool(), false.B) - memWrite := io.memWriteIn - io.memWriteOut := memWrite - - val branch = RegInit(Bool(), false.B) - branch := io.branchIn - io.branchOut := branch - - val jump = RegInit(Bool(), false.B) - jump := io.jumpIn - io.jumpOut := jump + val delay = Reg(new EXBarrierIO) + delay := io.in + io.out := delay } From 9192d576e77da4f62ba93e457c20f7e73dcae569 Mon Sep 17 00:00:00 2001 From: Sebastian Bugge Date: Fri, 8 Nov 2024 01:30:51 +0100 Subject: [PATCH 07/10] Simplify IDBarrier. --- src/main/scala/CPU.scala | 56 ++++++++-------- src/main/scala/IDBarrier.scala | 119 +++++++-------------------------- 2 files changed, 52 insertions(+), 123 deletions(-) diff --git a/src/main/scala/CPU.scala b/src/main/scala/CPU.scala index 8804a34..2a32b65 100644 --- a/src/main/scala/CPU.scala +++ b/src/main/scala/CPU.scala @@ -80,39 +80,39 @@ class CPU extends MultiIOModule { ID.io.instruction := IFBarrier.instructionOut ID.io.pc := IFBarrier.PCout - IDBarrier.op1in := ID.io.op1 - IDBarrier.op2in := ID.io.op2 - IDBarrier.isOp1RValueIn := ID.io.isOp1RValue - IDBarrier.isOp2RValueIn := ID.io.isOp2RValue - IDBarrier.r1ValueIn := ID.io.r1Value - IDBarrier.r2ValueIn := ID.io.r2Value - IDBarrier.r1AddressIn := ID.io.r1Address - IDBarrier.r2AddressIn := ID.io.r2Address - 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 - IDBarrier.memWriteIn := ID.io.memWrite - IDBarrier.memReadIn := ID.io.memRead + IDBarrier.in.op1 := ID.io.op1 + IDBarrier.in.op2 := ID.io.op2 + IDBarrier.in.isOp1RValue := ID.io.isOp1RValue + IDBarrier.in.isOp2RValue := ID.io.isOp2RValue + IDBarrier.in.r1Value := ID.io.r1Value + IDBarrier.in.r2Value := ID.io.r2Value + IDBarrier.in.r1Address := ID.io.r1Address + IDBarrier.in.r2Address := ID.io.r2Address + IDBarrier.in.ALUop := ID.io.ALUOp + IDBarrier.in.returnAddr := ID.io.returnAddr + IDBarrier.in.jump := ID.io.jump + IDBarrier.in.branchType := ID.io.branchType + IDBarrier.in.writeEnable := ID.io.writeEnableOut + IDBarrier.in.writeAddr := ID.io.writeAddrOut + IDBarrier.in.memWrite := ID.io.memWrite + IDBarrier.in.memRead := ID.io.memRead - EX.io.op1 := forward(IDBarrier.op1out.asUInt(), IDBarrier.r1AddressOut, IDBarrier.isOp1RValueOut, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt() - EX.io.op2 := forward(IDBarrier.op2out.asUInt(), IDBarrier.r2AddressOut, IDBarrier.isOp2RValueOut, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt() - EX.io.ALUOp := IDBarrier.ALUopOut - EX.io.branchType := IDBarrier.branchTypeOut - EX.io.rs1ValueIn := forward(IDBarrier.r1ValueOut, IDBarrier.r1AddressOut, true.B, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt() - EX.io.rs2ValueIn := forward(IDBarrier.r2ValueOut, IDBarrier.r2AddressOut, true.B, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt() + EX.io.op1 := forward(IDBarrier.out.op1.asUInt(), IDBarrier.out.r1Address, IDBarrier.out.isOp1RValue, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt() + EX.io.op2 := forward(IDBarrier.out.op2.asUInt(), IDBarrier.out.r2Address, IDBarrier.out.isOp2RValue, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt() + EX.io.ALUOp := IDBarrier.out.ALUop + EX.io.branchType := IDBarrier.out.branchType + EX.io.rs1ValueIn := forward(IDBarrier.out.r1Value, IDBarrier.out.r1Address, true.B, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt() + EX.io.rs2ValueIn := forward(IDBarrier.out.r2Value, IDBarrier.out.r2Address, true.B, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt() EXBarrier.in.r2Value := EX.io.rs2ValueOut.asUInt() EXBarrier.in.ALUResult := EX.io.ALUResult.asUInt() EXBarrier.in.branch := EX.io.branch - EXBarrier.in.jump := IDBarrier.jumpOut - EXBarrier.in.returnAddr := IDBarrier.returnAddrOut - EXBarrier.in.writeEnable := IDBarrier.writeEnableOut - EXBarrier.in.writeAddr := IDBarrier.writeAddrOut - EXBarrier.in.memWrite := IDBarrier.memWriteOut - EXBarrier.in.memRead := IDBarrier.memReadOut + EXBarrier.in.jump := IDBarrier.out.jump + EXBarrier.in.returnAddr := IDBarrier.out.returnAddr + EXBarrier.in.writeEnable := IDBarrier.out.writeEnable + EXBarrier.in.writeAddr := IDBarrier.out.writeAddr + EXBarrier.in.memWrite := IDBarrier.out.memWrite + EXBarrier.in.memRead := IDBarrier.out.memRead MEM.io.ALUResult := EXBarrier.out.ALUResult MEM.io.jump := EXBarrier.out.jump diff --git a/src/main/scala/IDBarrier.scala b/src/main/scala/IDBarrier.scala index 26869d4..105ca34 100644 --- a/src/main/scala/IDBarrier.scala +++ b/src/main/scala/IDBarrier.scala @@ -3,104 +3,33 @@ package FiveStage import chisel3._ import chisel3.experimental.MultiIOModule +class IDBarrierIO extends Bundle { + val op1 = SInt(32.W) + val isOp1RValue = Bool() + val op2 = SInt(32.W) + val isOp2RValue = Bool() + val r1Value = UInt(32.W) + val r1Address = UInt(5.W) + val r2Value = UInt(32.W) + val r2Address = UInt(5.W) + val returnAddr = UInt(32.W) + val jump = Bool() + val ALUop = UInt(4.W) + val branchType = UInt(3.W) + val writeAddr = UInt(5.W) + val writeEnable = Bool() + val memRead = Bool() + val memWrite = Bool() +} + class IDBarrier extends MultiIOModule { val io = IO( new Bundle { - val op1in = Input(SInt(32.W)) - val op1out = Output(SInt(32.W)) - val isOp1RValueIn = Input(Bool()) - val isOp1RValueOut = Output(Bool()) - val op2in = Input(SInt(32.W)) - val op2out = Output(SInt(32.W)) - val isOp2RValueIn = Input(Bool()) - val isOp2RValueOut = Output(Bool()) - val r1ValueIn = Input(UInt(32.W)) - val r1ValueOut = Output(UInt(32.W)) - val r1AddressIn = Input(UInt(5.W)) - val r1AddressOut = Output(UInt(5.W)) - val r2ValueIn = Input(UInt(32.W)) - val r2ValueOut = Output(UInt(32.W)) - val r2AddressIn = Input(UInt(5.W)) - val r2AddressOut = Output(UInt(5.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)) - val branchTypeOut = Output(UInt(3.W)) - val writeAddrIn = Input(UInt(5.W)) - val writeAddrOut = Output(UInt(5.W)) - val writeEnableIn = Input(Bool()) - val writeEnableOut = Output(Bool()) - val memReadIn = Input(Bool()) - val memReadOut = Output(Bool()) - val memWriteIn = Input(Bool()) - val memWriteOut = Output(Bool()) + val in = Input(new IDBarrierIO) + val out = Output(new IDBarrierIO) }) - val isOp1RValue = RegInit(Bool(), false.B) - isOp1RValue := io.isOp1RValueIn - io.isOp1RValueOut := isOp1RValue - - val isOp2RValue = RegInit(Bool(), false.B) - isOp2RValue := io.isOp2RValueIn - io.isOp2RValueOut := isOp2RValue - - val r2Address = RegInit(UInt(5.W), 0.U) - r2Address := io.r2AddressIn - io.r2AddressOut := r2Address - - val r1Address = RegInit(UInt(5.W), 0.U) - r1Address := io.r1AddressIn - io.r1AddressOut := r1Address - - val op1 = RegInit(SInt(32.W), 0.S) - op1 := io.op1in - io.op1out := op1 - - val op2 = RegInit(SInt(32.W), 0.S) - op2 := io.op2in - io.op2out := op2 - - val r1Value = RegInit(UInt(32.W), 0.U) - r1Value := io.r1ValueIn - io.r1ValueOut := r1Value - - val r2Value = RegInit(UInt(32.W), 0.U) - 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 - - val branchType = RegInit(UInt(5.W), 0.U) - branchType := io.branchTypeIn - io.branchTypeOut := branchType - - val writeAddr = RegInit(UInt(5.W), 0.U) - writeAddr := io.writeAddrIn - io.writeAddrOut := writeAddr - - val writeEnable = RegInit(Bool(), false.B) - writeEnable := io.writeEnableIn - io.writeEnableOut := writeEnable - - val memRead = RegInit(Bool(), false.B) - memRead := io.memReadIn - io.memReadOut := memRead - - val memWrite = RegInit(Bool(), false.B) - memWrite := io.memWriteIn - io.memWriteOut := memWrite + val delay = Reg(new IDBarrierIO) + delay := io.in + io.out := delay } From 4cfd8268fd9b4e7f045b4a8b73664bb47da7e121 Mon Sep 17 00:00:00 2001 From: Sebastian Bugge Date: Fri, 8 Nov 2024 01:47:20 +0100 Subject: [PATCH 08/10] Simplify MEMBarrier. --- src/main/scala/CPU.scala | 12 +++---- src/main/scala/MEMBarrier.scala | 55 ++++++++++++++------------------- 2 files changed, 29 insertions(+), 38 deletions(-) diff --git a/src/main/scala/CPU.scala b/src/main/scala/CPU.scala index 2a32b65..51d1360 100644 --- a/src/main/scala/CPU.scala +++ b/src/main/scala/CPU.scala @@ -122,14 +122,14 @@ class CPU extends MultiIOModule { MEM.io.writeData := EXBarrier.out.r2Value MEMBarrier.memRead := EXBarrier.out.memRead - MEMBarrier.dataIn := MEM.io.dataOut - MEMBarrier.writeEnableIn := EXBarrier.out.writeEnable - MEMBarrier.writeAddrIn := EXBarrier.out.writeAddr + MEMBarrier.in.data := MEM.io.dataOut + MEMBarrier.in.writeEnable := EXBarrier.out.writeEnable + MEMBarrier.in.writeAddr := EXBarrier.out.writeAddr // Write back - ID.io.writeData := MEMBarrier.dataOut - ID.io.writeEnableIn := MEMBarrier.writeEnableOut - ID.io.writeAddrIn := MEMBarrier.writeAddrOut + ID.io.writeData := MEMBarrier.out.data + ID.io.writeEnableIn := MEMBarrier.out.writeEnable + ID.io.writeAddrIn := MEMBarrier.out.writeAddr // Branching IF.io.branch := EXBarrier.out.branch diff --git a/src/main/scala/MEMBarrier.scala b/src/main/scala/MEMBarrier.scala index 1187a9f..bef66ad 100644 --- a/src/main/scala/MEMBarrier.scala +++ b/src/main/scala/MEMBarrier.scala @@ -2,15 +2,17 @@ package FiveStage import chisel3._ import chisel3.experimental.MultiIOModule +class MEMBarrierIO extends Bundle { + val data = UInt(32.W) + val writeAddr = UInt(5.W) + val writeEnable = Bool() +} + class MEMBarrier extends MultiIOModule { val io = IO( new Bundle { - val dataIn = Input(UInt(32.W)) - val dataOut = Output(UInt(32.W)) - val writeAddrIn = Input(UInt(5.W)) - val writeAddrOut = Output(UInt(5.W)) - val writeEnableIn = Input(Bool()) - val writeEnableOut = Output(Bool()) + val in = Input(new MEMBarrierIO) + val out = Output(new MEMBarrierIO) val memRead = Input(Bool()) val forwardMem = Output(new Forwarding) val forwardWb = Output(new Forwarding) @@ -20,36 +22,25 @@ class MEMBarrier extends MultiIOModule { val memRead = RegInit(Bool(), false.B) memRead := io.memRead - val data = RegInit(UInt(32.W), 0.U) - data := io.dataIn - io.dataOut := Mux(memRead, io.dataIn, data) + val delay = Reg(new MEMBarrierIO) + val delay2 = Reg(new MEMBarrierIO) - val writeAddr = RegInit(UInt(5.W), 0.U) - writeAddr := io.writeAddrIn - io.writeAddrOut := writeAddr + delay := io.in + io.out := delay + io.out.data := Mux(memRead, io.in.data, delay.data) + delay2 := io.out - val writeEnable = RegInit(Bool(), false.B) - writeEnable := io.writeEnableIn - io.writeEnableOut := writeEnable + io.forwardMem.write := io.in.writeEnable && !io.memRead + io.forwardMem.writeAddr := io.in.writeAddr + io.forwardMem.writeData := io.in.data - io.forwardMem.write := io.writeEnableIn && !io.memRead - io.forwardMem.writeAddr := io.writeAddrIn - io.forwardMem.writeData := io.dataIn + io.forwardWb.write := io.out.writeEnable + io.forwardWb.writeAddr := io.out.writeAddr + io.forwardWb.writeData := io.out.data - io.forwardWb.write := writeEnable - io.forwardWb.writeAddr := writeAddr - io.forwardWb.writeData := io.dataOut - - val forwardId = RegInit(Bool(), false.B) - forwardId := writeEnable - val forwardIdAddr = RegInit(UInt(5.W), 0.U) - forwardIdAddr := io.writeAddrOut - val forwardIdData = RegInit(UInt(32.W), 0.U) - forwardIdData := io.dataOut - - io.forwardId.write := forwardId - io.forwardId.writeAddr := forwardIdAddr - io.forwardId.writeData := forwardIdData + io.forwardId.write := delay2.writeEnable + io.forwardId.writeAddr := delay2.writeAddr + io.forwardId.writeData := delay2.data } class Forwarding extends Bundle { From 23656db0689cb72299129f5c1a330e4b83a6d58b Mon Sep 17 00:00:00 2001 From: Sebastian Bugge Date: Mon, 11 Nov 2024 01:59:20 +0100 Subject: [PATCH 09/10] Do memread stalling correctly. --- src/main/scala/CPU.scala | 3 ++- src/main/scala/ID.scala | 12 ++++-------- src/main/scala/IDBarrier.scala | 2 ++ src/main/scala/IFBarrier.scala | 18 ++++++++++++++++-- src/test/scala/Manifest.scala | 2 +- 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/main/scala/CPU.scala b/src/main/scala/CPU.scala index 51d1360..551f62c 100644 --- a/src/main/scala/CPU.scala +++ b/src/main/scala/CPU.scala @@ -136,5 +136,6 @@ class CPU extends MultiIOModule { IF.io.branchAddress := EXBarrier.out.ALUResult // Stall - IF.io.stall := ID.io.stall + IF.io.stall := IDBarrier.stall || ID.io.stall + IFBarrier.stall := IDBarrier.stall } diff --git a/src/main/scala/ID.scala b/src/main/scala/ID.scala index 7ea6e01..5627fe4 100644 --- a/src/main/scala/ID.scala +++ b/src/main/scala/ID.scala @@ -94,16 +94,12 @@ class InstructionDecode extends MultiIOModule { stallDelay, stallsRemaining - 1.U, Mux( - decoder.controlSignals.memRead, - 1.U, - Mux( - decoder.controlSignals.branch, - 3.U, - 0.U - ) + decoder.controlSignals.branch, + 3.U, + 0.U )) - val stall = stallsRemaining > 1.U || decoder.controlSignals.memRead && !stallDelay || decoder.controlSignals.branch && !stallDelay + val stall = stallsRemaining > 1.U || decoder.controlSignals.branch && !stallDelay io.stall := stall io.jump := Mux(stallDelay, false.B, decoder.controlSignals.jump) diff --git a/src/main/scala/IDBarrier.scala b/src/main/scala/IDBarrier.scala index 105ca34..c924233 100644 --- a/src/main/scala/IDBarrier.scala +++ b/src/main/scala/IDBarrier.scala @@ -27,9 +27,11 @@ class IDBarrier extends MultiIOModule { new Bundle { val in = Input(new IDBarrierIO) val out = Output(new IDBarrierIO) + val stall = Output(Bool()) }) val delay = Reg(new IDBarrierIO) delay := io.in io.out := delay + io.stall := io.out.memRead } diff --git a/src/main/scala/IFBarrier.scala b/src/main/scala/IFBarrier.scala index 0523874..755410b 100644 --- a/src/main/scala/IFBarrier.scala +++ b/src/main/scala/IFBarrier.scala @@ -10,11 +10,25 @@ class IFBarrier extends MultiIOModule { val PCout = Output(UInt(32.W)) val instructionIn = Input(new Instruction) val instructionOut = Output(new Instruction) + val stall = Input(Bool()) }) val PC = RegInit(UInt(32.W), 0.U) - PC := io.PCin + PC := Mux(io.stall, PC, io.PCin) io.PCout := PC - io.instructionOut := io.instructionIn + val instruction = Reg(new Instruction) + val replay = RegInit(Bool(), false.B) + replay := io.stall + instruction := io.instructionIn + + io.instructionOut := Mux( + io.stall, + Instruction.NOP, + Mux( + replay, + instruction, + io.instructionIn + ) + ) } diff --git a/src/test/scala/Manifest.scala b/src/test/scala/Manifest.scala index 01665d6..79d6989 100644 --- a/src/test/scala/Manifest.scala +++ b/src/test/scala/Manifest.scala @@ -19,7 +19,7 @@ import LogParser._ object Manifest { - val singleTest = "fucked.s" + val singleTest = "simpleload.s" val nopPadded = false From cfce1b6b548447e426888298af1300ed5d6e5e68 Mon Sep 17 00:00:00 2001 From: Sebastian Bugge Date: Mon, 11 Nov 2024 17:49:10 +0100 Subject: [PATCH 10/10] Working branching. --- src/main/scala/CPU.scala | 5 ++++- src/main/scala/EXBarrier.scala | 3 +++ src/main/scala/ID.scala | 25 +++++-------------------- src/main/scala/IFBarrier.scala | 14 +++++++++++++- src/test/resources/tests/branch.s | 3 +++ src/test/resources/tests/jump.s | 2 ++ src/test/scala/Manifest.scala | 2 +- 7 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/main/scala/CPU.scala b/src/main/scala/CPU.scala index 551f62c..230c3af 100644 --- a/src/main/scala/CPU.scala +++ b/src/main/scala/CPU.scala @@ -136,6 +136,9 @@ class CPU extends MultiIOModule { IF.io.branchAddress := EXBarrier.out.ALUResult // Stall - IF.io.stall := IDBarrier.stall || ID.io.stall + IF.io.stall := IDBarrier.stall IFBarrier.stall := IDBarrier.stall + + // Flush + IFBarrier.flush := EXBarrier.flush } diff --git a/src/main/scala/EXBarrier.scala b/src/main/scala/EXBarrier.scala index 2c79a95..222f20c 100644 --- a/src/main/scala/EXBarrier.scala +++ b/src/main/scala/EXBarrier.scala @@ -20,9 +20,12 @@ class EXBarrier extends MultiIOModule { new Bundle { val in = Input(new EXBarrierIO) val out = Output(new EXBarrierIO) + val flush = Output(Bool()) }) val delay = Reg(new EXBarrierIO) delay := io.in io.out := delay + + io.flush := io.in.branch } diff --git a/src/main/scala/ID.scala b/src/main/scala/ID.scala index 5627fe4..1027e70 100644 --- a/src/main/scala/ID.scala +++ b/src/main/scala/ID.scala @@ -39,7 +39,6 @@ class InstructionDecode extends MultiIOModule { val branchType = Output(UInt(3.W)) val jump = Output(Bool()) val returnAddr = Output(UInt(32.W)) - val stall = Output(Bool()) } ) @@ -88,25 +87,11 @@ class InstructionDecode extends MultiIOModule { io.ALUOp := decoder.ALUop io.writeAddrOut := decoder.instruction.registerRd - val stallsRemaining = RegInit(UInt(4.W), 0.U) - val stallDelay = stallsRemaining > 0.U - stallsRemaining := Mux( - stallDelay, - stallsRemaining - 1.U, - Mux( - decoder.controlSignals.branch, - 3.U, - 0.U - )) - - val stall = stallsRemaining > 1.U || decoder.controlSignals.branch && !stallDelay - io.stall := stall - - io.jump := Mux(stallDelay, false.B, decoder.controlSignals.jump) - io.branchType := Mux(stallDelay, branchType.DC, decoder.branchType) + io.jump := decoder.controlSignals.jump + io.branchType := decoder.branchType io.returnAddr := io.pc + 4.U - io.writeEnableOut := Mux(stallDelay, false.B, decoder.controlSignals.regWrite) - io.memRead := Mux(stallDelay, false.B, decoder.controlSignals.memRead) - io.memWrite := Mux(stallDelay, false.B, decoder.controlSignals.memWrite) + io.writeEnableOut := decoder.controlSignals.regWrite + io.memRead := decoder.controlSignals.memRead + io.memWrite := decoder.controlSignals.memWrite } diff --git a/src/main/scala/IFBarrier.scala b/src/main/scala/IFBarrier.scala index 755410b..49555ea 100644 --- a/src/main/scala/IFBarrier.scala +++ b/src/main/scala/IFBarrier.scala @@ -11,6 +11,7 @@ class IFBarrier extends MultiIOModule { val instructionIn = Input(new Instruction) val instructionOut = Output(new Instruction) val stall = Input(Bool()) + val flush = Input(Bool()) }) val PC = RegInit(UInt(32.W), 0.U) @@ -19,11 +20,22 @@ class IFBarrier extends MultiIOModule { val instruction = Reg(new Instruction) val replay = RegInit(Bool(), false.B) + val flushRemaining = RegInit(UInt(2.W), 0.U) + flushRemaining := Mux( + io.flush, + 2.U, + Mux( + flushRemaining === 0.U, + 0.U, + flushRemaining - 1.U + ) + ) + replay := io.stall instruction := io.instructionIn io.instructionOut := Mux( - io.stall, + io.stall || io.flush || flushRemaining > 0.U, Instruction.NOP, Mux( replay, diff --git a/src/test/resources/tests/branch.s b/src/test/resources/tests/branch.s index 0761396..15f6937 100644 --- a/src/test/resources/tests/branch.s +++ b/src/test/resources/tests/branch.s @@ -4,4 +4,7 @@ main: loop: addi x2, x2, 1 blt x2, x1, loop + nop + nop + nop done \ No newline at end of file diff --git a/src/test/resources/tests/jump.s b/src/test/resources/tests/jump.s index cb18ee4..a72a9df 100644 --- a/src/test/resources/tests/jump.s +++ b/src/test/resources/tests/jump.s @@ -1,6 +1,8 @@ main: jal x1, end addi x1, x1, 0 + nop + nop done end: diff --git a/src/test/scala/Manifest.scala b/src/test/scala/Manifest.scala index 79d6989..d10ed8a 100644 --- a/src/test/scala/Manifest.scala +++ b/src/test/scala/Manifest.scala @@ -19,7 +19,7 @@ import LogParser._ object Manifest { - val singleTest = "simpleload.s" + val singleTest = "branch.s" val nopPadded = false