From bcbe07b601390fb6b3866492654462b727d87b4a Mon Sep 17 00:00:00 2001 From: Sebastian Bugge Date: Fri, 18 Oct 2024 07:37:50 +0200 Subject: [PATCH] Working forwarding (i think). --- src/main/scala/CPU.scala | 13 +++++++ src/main/scala/EXBarrier.scala | 8 ++++- src/main/scala/ID.scala | 9 +++++ src/main/scala/IDBarrier.scala | 66 +++++++++++++++++++++++++++++++--- src/main/scala/MEM.scala | 3 -- src/test/scala/Manifest.scala | 2 +- 6 files changed, 92 insertions(+), 9 deletions(-) diff --git a/src/main/scala/CPU.scala b/src/main/scala/CPU.scala index 859838e..39e430e 100644 --- a/src/main/scala/CPU.scala +++ b/src/main/scala/CPU.scala @@ -63,8 +63,12 @@ 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.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 @@ -106,4 +110,13 @@ class CPU extends MultiIOModule { // Branching IF.io.branch := EXBarrier.branchOut IF.io.branchAddress := EXBarrier.branchAddress + + // Forwarding + IDBarrier.forwardExData := EXBarrier.forwardExData + IDBarrier.forwardEx := EXBarrier.forwardEx + IDBarrier.forwardExAddr := EXBarrier.forwardExAddr + + IDBarrier.forwardMemData := MEM.io.dataOut + IDBarrier.forwardMem := EXBarrier.writeEnableOut + IDBarrier.forwardMemAddr := EXBarrier.writeAddrOut } diff --git a/src/main/scala/EXBarrier.scala b/src/main/scala/EXBarrier.scala index 2bbd918..16f9b1f 100644 --- a/src/main/scala/EXBarrier.scala +++ b/src/main/scala/EXBarrier.scala @@ -25,6 +25,9 @@ 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)) }) io.ALUResultOut := io.ALUResultIn @@ -63,5 +66,8 @@ 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/ID.scala b/src/main/scala/ID.scala index 9b5ebfb..f54660e 100644 --- a/src/main/scala/ID.scala +++ b/src/main/scala/ID.scala @@ -21,9 +21,13 @@ class InstructionDecode extends MultiIOModule { val instruction = Input(new Instruction) val pc = Input(UInt(32.W)) val op1 = Output(SInt(32.W)) + val isOp1RValue = Output(Bool()) val op2 = Output(SInt(32.W)) + val isOp2RValue = Output(Bool()) val r1Value = Output(UInt(32.W)) + val r1Address = Output(UInt(5.W)) val r2Value = Output(UInt(32.W)) + val r2Address = Output(UInt(5.W)) val ALUOp = Output(UInt(4.W)) val writeAddrIn = Input(UInt(5.W)) val writeAddrOut = Output(UInt(5.W)) @@ -72,8 +76,13 @@ class InstructionDecode extends MultiIOModule { Op2Select.rs2 -> registers.io.readData2.asSInt(), ) io.op2 := MuxLookup(decoder.op2Select, 0.S(32.W), select2Map) + + io.isOp1RValue := decoder.op1Select === Op1Select.rs1 io.r1Value := registers.io.readData1 + io.r1Address := registers.io.readAddress1 + io.isOp2RValue := decoder.op2Select === Op2Select.rs2 io.r2Value := registers.io.readData2 + io.r2Address := registers.io.readAddress2 io.jump := decoder.controlSignals.jump io.returnAddr := io.pc + 4.U diff --git a/src/main/scala/IDBarrier.scala b/src/main/scala/IDBarrier.scala index e087a35..07fc2f9 100644 --- a/src/main/scala/IDBarrier.scala +++ b/src/main/scala/IDBarrier.scala @@ -8,12 +8,18 @@ class IDBarrier extends MultiIOModule { new Bundle { val op1in = Input(SInt(32.W)) val op1out = Output(SInt(32.W)) + val isOp1RValue = Input(Bool()) val op2in = Input(SInt(32.W)) val op2out = Output(SInt(32.W)) + val isOp2RValue = Input(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()) @@ -30,24 +36,76 @@ class IDBarrier extends MultiIOModule { val memReadOut = Output(Bool()) 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 isOp1RValue = RegInit(Bool(), false.B) + isOp1RValue := io.isOp1RValue + val isOp2RValue = RegInit(Bool(), false.B) + isOp2RValue := io.isOp2RValue + val op1 = RegInit(SInt(32.W), 0.S) - op1 := io.op1in + 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(), + io.op1in.asSInt(), + ), + ) io.op1out := op1 val op2 = RegInit(SInt(32.W), 0.S) - op2 := io.op2in + 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(), + io.op2in, + ), + ) io.op2out := op2 val r1Value = RegInit(UInt(32.W), 0.U) - r1Value := io.r1ValueIn + r1Value := Mux( + io.forwardEx && io.r1AddressIn === io.forwardExAddr, + io.forwardExData, + Mux( + io.forwardMem && io.isOp1RValue && io.r1AddressIn === io.forwardMemAddr, + io.forwardMemData, + io.r1ValueIn, + ), + ) io.r1ValueOut := r1Value + val r1Address = RegInit(UInt(5.W), 0.U) + r1Address := io.r1AddressIn + io.r1AddressOut := r1Address + val r2Value = RegInit(UInt(32.W), 0.U) - r2Value := io.r2ValueIn + r2Value := Mux( + io.forwardEx && io.r2AddressIn === io.forwardExAddr, + io.forwardExData, + Mux( + io.forwardMem && io.r2AddressIn === io.forwardMemAddr, + io.forwardMemData, + io.r2ValueIn, + ), + ) io.r2ValueOut := r2Value + val r2Address = RegInit(UInt(5.W), 0.U) + r2Address := io.r2AddressIn + io.r2AddressOut := r2Address + val returnAddr = RegInit(UInt(32.W), 0.U) returnAddr := io.returnAddrIn io.returnAddrOut := returnAddr diff --git a/src/main/scala/MEM.scala b/src/main/scala/MEM.scala index 723b85b..669d53f 100644 --- a/src/main/scala/MEM.scala +++ b/src/main/scala/MEM.scala @@ -27,10 +27,8 @@ class MemoryFetch() extends MultiIOModule { val returnAddr = Input(UInt(32.W)) }) - val DMEM = Module(new DMEM) - /** * Setup. You should not change this code */ @@ -38,7 +36,6 @@ class MemoryFetch() extends MultiIOModule { testHarness.DMEMpeek := DMEM.io.dataOut testHarness.testUpdates := DMEM.testHarness.testUpdates - /** * Your code here. */ diff --git a/src/test/scala/Manifest.scala b/src/test/scala/Manifest.scala index 6246818..b021309 100644 --- a/src/test/scala/Manifest.scala +++ b/src/test/scala/Manifest.scala @@ -21,7 +21,7 @@ object Manifest { val singleTest = "addi.s" - val nopPadded = true + val nopPadded = false val singleTestOptions = TestOptions( printIfSuccessful = true,