Compare commits
10 commits
4c684f1718
...
cfce1b6b54
Author | SHA1 | Date | |
---|---|---|---|
cfce1b6b54 | |||
23656db068 | |||
4cfd8268fd | |||
9192d576e7 | |||
42d77a0d85 | |||
6d6474530c | |||
1eefeca2d6 | |||
804e1ed2e6 | |||
800e7b6eb0 | |||
97b13a813f |
12 changed files with 211 additions and 309 deletions
|
@ -54,6 +54,25 @@ class CPU extends MultiIOModule {
|
||||||
/**
|
/**
|
||||||
TODO: Your code here
|
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.PCin := IF.io.PC
|
||||||
IFBarrier.instructionIn := IF.io.instruction
|
IFBarrier.instructionIn := IF.io.instruction
|
||||||
|
@ -61,74 +80,65 @@ class CPU extends MultiIOModule {
|
||||||
ID.io.instruction := IFBarrier.instructionOut
|
ID.io.instruction := IFBarrier.instructionOut
|
||||||
ID.io.pc := IFBarrier.PCout
|
ID.io.pc := IFBarrier.PCout
|
||||||
|
|
||||||
IDBarrier.op1in := ID.io.op1
|
IDBarrier.in.op1 := ID.io.op1
|
||||||
IDBarrier.op2in := ID.io.op2
|
IDBarrier.in.op2 := ID.io.op2
|
||||||
IDBarrier.isOp1RValue := ID.io.isOp1RValue
|
IDBarrier.in.isOp1RValue := ID.io.isOp1RValue
|
||||||
IDBarrier.isOp2RValue := ID.io.isOp2RValue
|
IDBarrier.in.isOp2RValue := ID.io.isOp2RValue
|
||||||
IDBarrier.r1ValueIn := ID.io.r1Value
|
IDBarrier.in.r1Value := ID.io.r1Value
|
||||||
IDBarrier.r2ValueIn := ID.io.r2Value
|
IDBarrier.in.r2Value := ID.io.r2Value
|
||||||
IDBarrier.r1AddressIn := ID.io.r1Address
|
IDBarrier.in.r1Address := ID.io.r1Address
|
||||||
IDBarrier.r2AddressIn := ID.io.r2Address
|
IDBarrier.in.r2Address := ID.io.r2Address
|
||||||
IDBarrier.ALUopIn := ID.io.ALUOp
|
IDBarrier.in.ALUop := ID.io.ALUOp
|
||||||
IDBarrier.returnAddrIn := ID.io.returnAddr
|
IDBarrier.in.returnAddr := ID.io.returnAddr
|
||||||
IDBarrier.jumpIn := ID.io.jump
|
IDBarrier.in.jump := ID.io.jump
|
||||||
IDBarrier.branchTypeIn := ID.io.branchType
|
IDBarrier.in.branchType := ID.io.branchType
|
||||||
IDBarrier.writeEnableIn := ID.io.writeEnableOut
|
IDBarrier.in.writeEnable := ID.io.writeEnableOut
|
||||||
IDBarrier.writeAddrIn := ID.io.writeAddrOut
|
IDBarrier.in.writeAddr := ID.io.writeAddrOut
|
||||||
IDBarrier.memWriteIn := ID.io.memWrite
|
IDBarrier.in.memWrite := ID.io.memWrite
|
||||||
IDBarrier.memReadIn := ID.io.memRead
|
IDBarrier.in.memRead := ID.io.memRead
|
||||||
|
|
||||||
EX.io.op1 := IDBarrier.op1out
|
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 := IDBarrier.op2out
|
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.ALUopOut
|
EX.io.ALUOp := IDBarrier.out.ALUop
|
||||||
EX.io.branchType := IDBarrier.branchTypeOut
|
EX.io.branchType := IDBarrier.out.branchType
|
||||||
EX.io.rs1ValueIn := IDBarrier.r1ValueOut.asSInt()
|
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 := IDBarrier.r2ValueOut.asSInt()
|
EX.io.rs2ValueIn := forward(IDBarrier.out.r2Value, IDBarrier.out.r2Address, true.B, mem = MEMBarrier.forwardMem, wb = MEMBarrier.forwardWb, id = MEMBarrier.forwardId).asSInt()
|
||||||
|
|
||||||
EXBarrier.r2ValueIn := EX.io.rs2ValueOut.asUInt()
|
EXBarrier.in.r2Value := EX.io.rs2ValueOut.asUInt()
|
||||||
EXBarrier.ALUResultIn := EX.io.ALUResult.asUInt()
|
EXBarrier.in.ALUResult := EX.io.ALUResult.asUInt()
|
||||||
EXBarrier.branchIn := EX.io.branch
|
EXBarrier.in.branch := EX.io.branch
|
||||||
EXBarrier.jumpIn := IDBarrier.jumpOut
|
EXBarrier.in.jump := IDBarrier.out.jump
|
||||||
EXBarrier.returnAddrIn := IDBarrier.returnAddrOut
|
EXBarrier.in.returnAddr := IDBarrier.out.returnAddr
|
||||||
EXBarrier.writeEnableIn := IDBarrier.writeEnableOut
|
EXBarrier.in.writeEnable := IDBarrier.out.writeEnable
|
||||||
EXBarrier.writeAddrIn := IDBarrier.writeAddrOut
|
EXBarrier.in.writeAddr := IDBarrier.out.writeAddr
|
||||||
EXBarrier.memWriteIn := IDBarrier.memWriteOut
|
EXBarrier.in.memWrite := IDBarrier.out.memWrite
|
||||||
EXBarrier.memReadIn := IDBarrier.memReadOut
|
EXBarrier.in.memRead := IDBarrier.out.memRead
|
||||||
|
|
||||||
MEM.io.ALUResult := EXBarrier.ALUResultOut
|
MEM.io.ALUResult := EXBarrier.out.ALUResult
|
||||||
MEM.io.jump := EXBarrier.jumpOut
|
MEM.io.jump := EXBarrier.out.jump
|
||||||
MEM.io.returnAddr := EXBarrier.returnAddrOut
|
MEM.io.returnAddr := EXBarrier.out.returnAddr
|
||||||
MEM.io.writeMem := EXBarrier.memWriteOut
|
MEM.io.writeMem := EXBarrier.out.memWrite
|
||||||
MEM.io.readMem := EXBarrier.memReadOut
|
MEM.io.readMem := EXBarrier.out.memRead
|
||||||
MEM.io.writeData := EXBarrier.r2ValueOut
|
MEM.io.writeData := EXBarrier.out.r2Value
|
||||||
|
|
||||||
MEMBarrier.memRead := EXBarrier.memReadOut
|
MEMBarrier.memRead := EXBarrier.out.memRead
|
||||||
MEMBarrier.dataIn := MEM.io.dataOut
|
MEMBarrier.in.data := MEM.io.dataOut
|
||||||
MEMBarrier.writeEnableIn := EXBarrier.writeEnableOut
|
MEMBarrier.in.writeEnable := EXBarrier.out.writeEnable
|
||||||
MEMBarrier.writeAddrIn := EXBarrier.writeAddrOut
|
MEMBarrier.in.writeAddr := EXBarrier.out.writeAddr
|
||||||
|
|
||||||
// Write back
|
// Write back
|
||||||
ID.io.writeData := MEMBarrier.dataOut
|
ID.io.writeData := MEMBarrier.out.data
|
||||||
ID.io.writeEnableIn := MEMBarrier.writeEnableOut
|
ID.io.writeEnableIn := MEMBarrier.out.writeEnable
|
||||||
ID.io.writeAddrIn := MEMBarrier.writeAddrOut
|
ID.io.writeAddrIn := MEMBarrier.out.writeAddr
|
||||||
|
|
||||||
// Branching
|
// Branching
|
||||||
IF.io.branch := EXBarrier.branchOut
|
IF.io.branch := EXBarrier.out.branch
|
||||||
IF.io.branchAddress := EXBarrier.ALUResultOut
|
IF.io.branchAddress := EXBarrier.out.ALUResult
|
||||||
|
|
||||||
// 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
|
|
||||||
|
|
||||||
IDBarrier.forwardWbData := MEMBarrier.forwardWbData
|
|
||||||
IDBarrier.forwardWb := MEMBarrier.forwardWb
|
|
||||||
IDBarrier.forwardWbAddr := MEMBarrier.forwardWbAddr
|
|
||||||
|
|
||||||
// Stall
|
// Stall
|
||||||
IF.io.stall := ID.io.stall
|
IF.io.stall := IDBarrier.stall
|
||||||
|
IFBarrier.stall := IDBarrier.stall
|
||||||
|
|
||||||
|
// Flush
|
||||||
|
IFBarrier.flush := EXBarrier.flush
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,69 +3,29 @@ package FiveStage
|
||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.experimental.MultiIOModule
|
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 {
|
class EXBarrier extends MultiIOModule {
|
||||||
val io = IO(
|
val io = IO(
|
||||||
new Bundle {
|
new Bundle {
|
||||||
val ALUResultIn = Input(UInt(32.W))
|
val in = Input(new EXBarrierIO)
|
||||||
val ALUResultOut = Output(UInt(32.W))
|
val out = Output(new EXBarrierIO)
|
||||||
val returnAddrIn = Input(UInt(32.W))
|
val flush = Output(Bool())
|
||||||
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 forwardEx = Output(Bool())
|
|
||||||
val forwardExAddr = Output(UInt(5.W))
|
|
||||||
val forwardExData = Output(UInt(32.W))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
val ALUResult = RegInit(UInt(32.W), 0.U)
|
val delay = Reg(new EXBarrierIO)
|
||||||
ALUResult := io.ALUResultIn
|
delay := io.in
|
||||||
io.ALUResultOut := ALUResult
|
io.out := delay
|
||||||
|
|
||||||
val returnAddr = RegInit(UInt(32.W), 0.U)
|
io.flush := io.in.branch
|
||||||
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
|
|
||||||
|
|
||||||
io.forwardEx := io.writeEnableIn && !io.memReadIn
|
|
||||||
io.forwardExAddr := io.writeAddrIn
|
|
||||||
io.forwardExData := io.ALUResultIn
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ class InstructionDecode extends MultiIOModule {
|
||||||
val branchType = Output(UInt(3.W))
|
val branchType = Output(UInt(3.W))
|
||||||
val jump = Output(Bool())
|
val jump = Output(Bool())
|
||||||
val returnAddr = Output(UInt(32.W))
|
val returnAddr = Output(UInt(32.W))
|
||||||
val stall = Output(Bool())
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -86,18 +85,13 @@ class InstructionDecode extends MultiIOModule {
|
||||||
io.r2Address := registers.io.readAddress2
|
io.r2Address := registers.io.readAddress2
|
||||||
|
|
||||||
io.ALUOp := decoder.ALUop
|
io.ALUOp := decoder.ALUop
|
||||||
io.branchType := decoder.branchType
|
|
||||||
io.writeAddrOut := decoder.instruction.registerRd
|
io.writeAddrOut := decoder.instruction.registerRd
|
||||||
|
|
||||||
val stallDelay = RegInit(Bool(), false.B)
|
io.jump := decoder.controlSignals.jump
|
||||||
val stall = Mux(stallDelay, false.B, decoder.controlSignals.memRead)
|
io.branchType := decoder.branchType
|
||||||
io.stall := stall
|
|
||||||
stallDelay := stall
|
|
||||||
|
|
||||||
io.jump := Mux(stallDelay, false.B, decoder.controlSignals.jump)
|
|
||||||
io.returnAddr := io.pc + 4.U
|
io.returnAddr := io.pc + 4.U
|
||||||
|
|
||||||
io.writeEnableOut := Mux(stallDelay, false.B, decoder.controlSignals.regWrite)
|
io.writeEnableOut := decoder.controlSignals.regWrite
|
||||||
io.memRead := Mux(stallDelay, false.B, decoder.controlSignals.memRead)
|
io.memRead := decoder.controlSignals.memRead
|
||||||
io.memWrite := Mux(stallDelay, false.B, decoder.controlSignals.memWrite)
|
io.memWrite := decoder.controlSignals.memWrite
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,157 +3,35 @@ package FiveStage
|
||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.experimental.MultiIOModule
|
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 {
|
class IDBarrier extends MultiIOModule {
|
||||||
val io = IO(
|
val io = IO(
|
||||||
new Bundle {
|
new Bundle {
|
||||||
val op1in = Input(SInt(32.W))
|
val in = Input(new IDBarrierIO)
|
||||||
val op1out = Output(SInt(32.W))
|
val out = Output(new IDBarrierIO)
|
||||||
val isOp1RValue = Input(Bool())
|
val stall = Output(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())
|
|
||||||
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 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 isOp1RValue = RegInit(Bool(), false.B)
|
val delay = Reg(new IDBarrierIO)
|
||||||
isOp1RValue := io.isOp1RValue
|
delay := io.in
|
||||||
val isOp2RValue = RegInit(Bool(), false.B)
|
io.out := delay
|
||||||
isOp2RValue := io.isOp2RValue
|
io.stall := io.out.memRead
|
||||||
|
|
||||||
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 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,
|
|
||||||
Mux(
|
|
||||||
io.forwardMem && io.r2AddressIn === io.forwardMemAddr,
|
|
||||||
io.forwardMemData,
|
|
||||||
Mux(
|
|
||||||
io.forwardWb && io.r2AddressIn === io.forwardWbAddr,
|
|
||||||
io.forwardWbData,
|
|
||||||
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
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ class InstructionFetch extends MultiIOModule {
|
||||||
*/
|
*/
|
||||||
io.PC := PC
|
io.PC := PC
|
||||||
IMEM.io.instructionAddress := 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)
|
val instruction = Wire(new Instruction)
|
||||||
instruction := IMEM.io.instruction.asTypeOf(new Instruction)
|
instruction := IMEM.io.instruction.asTypeOf(new Instruction)
|
||||||
|
|
|
@ -10,11 +10,37 @@ class IFBarrier extends MultiIOModule {
|
||||||
val PCout = Output(UInt(32.W))
|
val PCout = Output(UInt(32.W))
|
||||||
val instructionIn = Input(new Instruction)
|
val instructionIn = Input(new Instruction)
|
||||||
val instructionOut = Output(new Instruction)
|
val instructionOut = Output(new Instruction)
|
||||||
|
val stall = Input(Bool())
|
||||||
|
val flush = Input(Bool())
|
||||||
})
|
})
|
||||||
|
|
||||||
val PC = RegInit(UInt(32.W), 0.U)
|
val PC = RegInit(UInt(32.W), 0.U)
|
||||||
PC := io.PCin
|
PC := Mux(io.stall, PC, io.PCin)
|
||||||
io.PCout := PC
|
io.PCout := PC
|
||||||
|
|
||||||
io.instructionOut := io.instructionIn
|
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.flush || flushRemaining > 0.U,
|
||||||
|
Instruction.NOP,
|
||||||
|
Mux(
|
||||||
|
replay,
|
||||||
|
instruction,
|
||||||
|
io.instructionIn
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,44 +2,50 @@ package FiveStage
|
||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.experimental.MultiIOModule
|
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 {
|
class MEMBarrier extends MultiIOModule {
|
||||||
val io = IO(
|
val io = IO(
|
||||||
new Bundle {
|
new Bundle {
|
||||||
val dataIn = Input(UInt(32.W))
|
val in = Input(new MEMBarrierIO)
|
||||||
val dataOut = Output(UInt(32.W))
|
val out = Output(new MEMBarrierIO)
|
||||||
val writeAddrIn = Input(UInt(5.W))
|
|
||||||
val writeAddrOut = Output(UInt(5.W))
|
|
||||||
val writeEnableIn = Input(Bool())
|
|
||||||
val writeEnableOut = Output(Bool())
|
|
||||||
val memRead = Input(Bool())
|
val memRead = Input(Bool())
|
||||||
val forwardMem = Output(Bool())
|
val forwardMem = Output(new Forwarding)
|
||||||
val forwardMemAddr = Output(UInt(5.W))
|
val forwardWb = Output(new Forwarding)
|
||||||
val forwardMemData = Output(UInt(32.W))
|
val forwardId = Output(new Forwarding)
|
||||||
val forwardWb = Output(Bool())
|
|
||||||
val forwardWbAddr = Output(UInt(5.W))
|
|
||||||
val forwardWbData = Output(UInt(32.W))
|
|
||||||
})
|
})
|
||||||
|
|
||||||
val memRead = RegInit(Bool(), false.B)
|
val memRead = RegInit(Bool(), false.B)
|
||||||
memRead := io.memRead
|
memRead := io.memRead
|
||||||
|
|
||||||
val data = RegInit(UInt(32.W), 0.U)
|
val delay = Reg(new MEMBarrierIO)
|
||||||
data := io.dataIn
|
val delay2 = Reg(new MEMBarrierIO)
|
||||||
io.dataOut := Mux(memRead, io.dataIn, data)
|
|
||||||
|
|
||||||
val writeAddr = RegInit(UInt(5.W), 0.U)
|
delay := io.in
|
||||||
writeAddr := io.writeAddrIn
|
io.out := delay
|
||||||
io.writeAddrOut := writeAddr
|
io.out.data := Mux(memRead, io.in.data, delay.data)
|
||||||
|
delay2 := io.out
|
||||||
|
|
||||||
val writeEnable = RegInit(Bool(), false.B)
|
io.forwardMem.write := io.in.writeEnable && !io.memRead
|
||||||
writeEnable := io.writeEnableIn
|
io.forwardMem.writeAddr := io.in.writeAddr
|
||||||
io.writeEnableOut := writeEnable
|
io.forwardMem.writeData := io.in.data
|
||||||
|
|
||||||
io.forwardMem := io.writeEnableIn && !io.memRead
|
io.forwardWb.write := io.out.writeEnable
|
||||||
io.forwardMemAddr := io.writeAddrIn
|
io.forwardWb.writeAddr := io.out.writeAddr
|
||||||
io.forwardMemData := io.dataIn
|
io.forwardWb.writeData := io.out.data
|
||||||
|
|
||||||
io.forwardWb := writeEnable
|
io.forwardId.write := delay2.writeEnable
|
||||||
io.forwardWbAddr := writeAddr
|
io.forwardId.writeAddr := delay2.writeAddr
|
||||||
io.forwardWbData := Mux(memRead, io.dataIn, data)
|
io.forwardId.writeData := delay2.data
|
||||||
|
}
|
||||||
|
|
||||||
|
class Forwarding extends Bundle {
|
||||||
|
val writeAddr = UInt(5.W)
|
||||||
|
val writeData = UInt(32.W)
|
||||||
|
val write = Bool()
|
||||||
|
def valid = write && (writeAddr =/= 0.U)
|
||||||
}
|
}
|
||||||
|
|
5
src/test/resources/tests/addload.s
Normal file
5
src/test/resources/tests/addload.s
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
main:
|
||||||
|
addi a5,a5,2
|
||||||
|
lw a4,-36(s0)
|
||||||
|
add a5,a4,a5
|
||||||
|
done
|
|
@ -4,4 +4,7 @@ main:
|
||||||
loop:
|
loop:
|
||||||
addi x2, x2, 1
|
addi x2, x2, 1
|
||||||
blt x2, x1, loop
|
blt x2, x1, loop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
|
nop
|
||||||
done
|
done
|
18
src/test/resources/tests/fucked.s
Normal file
18
src/test/resources/tests/fucked.s
Normal file
|
@ -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
|
|
@ -1,6 +1,8 @@
|
||||||
main:
|
main:
|
||||||
jal x1, end
|
jal x1, end
|
||||||
addi x1, x1, 0
|
addi x1, x1, 0
|
||||||
|
nop
|
||||||
|
nop
|
||||||
done
|
done
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
|
|
@ -19,7 +19,7 @@ import LogParser._
|
||||||
|
|
||||||
object Manifest {
|
object Manifest {
|
||||||
|
|
||||||
val singleTest = "load3.s"
|
val singleTest = "branch.s"
|
||||||
|
|
||||||
val nopPadded = false
|
val nopPadded = false
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue