Working branching.

This commit is contained in:
Sebastian Bugge 2024-10-04 02:16:17 +02:00
parent 934593fb6f
commit 92d0dfd9eb
Signed by: kaholaz
GPG key ID: 2EFFEDEE03519691
9 changed files with 102 additions and 32 deletions

View file

@ -63,8 +63,10 @@ class CPU extends MultiIOModule {
IDBarrier.op1in := ID.io.op1 IDBarrier.op1in := ID.io.op1
IDBarrier.op2in := ID.io.op2 IDBarrier.op2in := ID.io.op2
IDBarrier.r1ValueIn := ID.io.r1Value
IDBarrier.r2ValueIn := ID.io.r2Value IDBarrier.r2ValueIn := ID.io.r2Value
IDBarrier.ALUopIn := ID.io.ALUOp IDBarrier.ALUopIn := ID.io.ALUOp
IDBarrier.branchTypeIn := ID.io.branchType
IDBarrier.writeEnableIn := ID.io.writeEnableOut IDBarrier.writeEnableIn := ID.io.writeEnableOut
IDBarrier.writeAddrIn := ID.io.writeAddrOut IDBarrier.writeAddrIn := ID.io.writeAddrOut
IDBarrier.memWriteIn := ID.io.memWrite IDBarrier.memWriteIn := ID.io.memWrite
@ -73,13 +75,17 @@ class CPU extends MultiIOModule {
EX.io.op1 := IDBarrier.op1out EX.io.op1 := IDBarrier.op1out
EX.io.op2 := IDBarrier.op2out EX.io.op2 := IDBarrier.op2out
EX.io.ALUOp := IDBarrier.ALUopOut EX.io.ALUOp := IDBarrier.ALUopOut
EX.io.branchType := IDBarrier.branchTypeOut
EX.io.rs1ValueIn := IDBarrier.r1ValueOut.asSInt()
EX.io.rs2ValueIn := IDBarrier.r2ValueOut.asSInt()
EXBarrier.r2ValueIn := EX.io.rs2ValueOut.asUInt()
EXBarrier.ALUResultIn := EX.io.ALUResult.asUInt()
EXBarrier.branchIn := EX.io.branch
EXBarrier.writeEnableIn := IDBarrier.writeEnableOut EXBarrier.writeEnableIn := IDBarrier.writeEnableOut
EXBarrier.writeAddrIn := IDBarrier.writeAddrOut EXBarrier.writeAddrIn := IDBarrier.writeAddrOut
EXBarrier.memWriteIn := IDBarrier.memWriteOut EXBarrier.memWriteIn := IDBarrier.memWriteOut
EXBarrier.memReadIn := IDBarrier.memReadOut EXBarrier.memReadIn := IDBarrier.memReadOut
EXBarrier.r2ValueIn := IDBarrier.r2ValueOut
EXBarrier.ALUResultIn := EX.io.ALUResult.asUInt()
MEM.io.ALUResult := EXBarrier.ALUResultOut MEM.io.ALUResult := EXBarrier.ALUResultOut
MEM.io.writeMem := EXBarrier.memWriteOut MEM.io.writeMem := EXBarrier.memWriteOut
@ -90,4 +96,8 @@ class CPU extends MultiIOModule {
ID.io.writeData := MEM.io.dataOut ID.io.writeData := MEM.io.dataOut
ID.io.writeEnableIn := EXBarrier.writeEnableOut ID.io.writeEnableIn := EXBarrier.writeEnableOut
ID.io.writeAddrIn := EXBarrier.writeAddrOut ID.io.writeAddrIn := EXBarrier.writeAddrOut
// Branching
IF.io.branch := EXBarrier.branchOut
IF.io.branchAddress := EXBarrier.branchAddress
} }

View file

@ -46,36 +46,44 @@ class Decoder() extends Module {
*/ */
val opcodeMap: Array[(BitPat, List[UInt])] = Array( val opcodeMap: Array[(BitPat, List[UInt])] = Array(
// signal regWrite, memRead, memWrite, branch, jump, branchType, Op1Select, Op2Select, ImmSelect, ALUOp // 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 ), 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 ), 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 ), 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 ), 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 ), 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 ), 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 ), 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 ), 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 ), 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 ), 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
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 // 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 ), BEQ -> List(N, N, N, Y, N, branchType.beq, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ),
ANDI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.AND ), BNE -> List(N, N, N, Y, N, branchType.neq, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ),
ORI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.OR ), BLT -> List(N, N, N, Y, N, branchType.lt, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ),
XORI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.XOR ), BGE -> List(N, N, N, Y, N, branchType.gte, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ),
SLTI -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.SLT ), BLTU -> List(N, N, N, Y, N, branchType.ltu, PC, imm, ImmFormat.BTYPE, ALUOps.ADD ),
SLTIU -> List(Y, N, N, N, N, branchType.DC, rs1, imm, ImmFormat.ITYPE, ALUOps.SLTU ), BGEU -> List(N, N, N, Y, N, branchType.gteu,PC, imm, ImmFormat.BTYPE, ALUOps.ADD ),
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
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 ),
) )

View file

@ -10,6 +10,11 @@ class Execute extends MultiIOModule {
new Bundle { new Bundle {
val op1 = Input(SInt(32.W)) val op1 = Input(SInt(32.W))
val op2 = Input(SInt(32.W)) val op2 = Input(SInt(32.W))
val rs1ValueIn = Input(SInt(32.W))
val rs2ValueIn = Input(SInt(32.W))
val rs2ValueOut = Output(SInt(32.W))
val branchType = Input(UInt(3.W))
val branch = Output(Bool())
val ALUOp = Input(UInt(4.W)) val ALUOp = Input(UInt(4.W))
val ALUResult = Output(SInt(32.W)) val ALUResult = Output(SInt(32.W))
} }
@ -30,5 +35,17 @@ class Execute extends MultiIOModule {
ALUOps.COPY_B -> io.op2, ALUOps.COPY_B -> io.op2,
) )
val BranchALUOpsMap = Array (
branchType.beq -> (io.rs1ValueIn === io.rs2ValueIn),
branchType.neq -> !(io.rs1ValueIn === io.rs2ValueIn),
branchType.lt -> (io.rs1ValueIn < io.rs2ValueIn),
branchType.gte -> (io.rs1ValueIn >= io.rs2ValueIn),
branchType.ltu -> (io.rs1ValueIn.asUInt() < io.rs2ValueIn.asUInt()),
branchType.gteu -> (io.rs1ValueIn.asUInt() >= io.rs2ValueIn.asUInt()),
branchType.jump -> true.B,
)
io.rs2ValueOut := io.rs2ValueIn
io.branch := MuxLookup(io.branchType, false.B, BranchALUOpsMap)
io.ALUResult := MuxLookup(io.ALUOp, 0.S(32.W), ALUOpsMap) io.ALUResult := MuxLookup(io.ALUOp, 0.S(32.W), ALUOpsMap)
} }

View file

@ -8,6 +8,7 @@ class EXBarrier extends MultiIOModule {
new Bundle { new Bundle {
val ALUResultIn = Input(UInt(32.W)) val ALUResultIn = Input(UInt(32.W))
val ALUResultOut = Output(UInt(32.W)) val ALUResultOut = Output(UInt(32.W))
val branchAddress = Output(UInt(32.W))
val r2ValueIn = Input(UInt(32.W)) val r2ValueIn = Input(UInt(32.W))
val r2ValueOut = Output(UInt(32.W)) val r2ValueOut = Output(UInt(32.W))
val writeAddrIn = Input(UInt(5.W)) val writeAddrIn = Input(UInt(5.W))
@ -18,9 +19,14 @@ class EXBarrier extends MultiIOModule {
val memReadOut = Output(Bool()) val memReadOut = Output(Bool())
val memWriteIn = Input(Bool()) val memWriteIn = Input(Bool())
val memWriteOut = Output(Bool()) val memWriteOut = Output(Bool())
val branchIn = Input(Bool())
val branchOut = Output(Bool())
}) })
io.ALUResultOut := io.ALUResultIn io.ALUResultOut := io.ALUResultIn
val branchAddress = RegInit(UInt(32.W), 0.U)
branchAddress := io.ALUResultIn
io.branchAddress := branchAddress
val r2Value = RegInit(UInt(32.W), 0.U) val r2Value = RegInit(UInt(32.W), 0.U)
r2Value := io.r2ValueIn r2Value := io.r2ValueIn
@ -41,5 +47,9 @@ class EXBarrier extends MultiIOModule {
val memWrite = RegInit(Bool(), false.B) val memWrite = RegInit(Bool(), false.B)
memWrite := io.memWriteIn memWrite := io.memWriteIn
io.memWriteOut := memWrite io.memWriteOut := memWrite
val branch = RegInit(Bool(), false.B)
branch := io.branchIn
io.branchOut := branch
} }

View file

@ -22,6 +22,7 @@ class InstructionDecode extends MultiIOModule {
val pc = Input(UInt(32.W)) val pc = Input(UInt(32.W))
val op1 = Output(SInt(32.W)) val op1 = Output(SInt(32.W))
val op2 = Output(SInt(32.W)) val op2 = Output(SInt(32.W))
val r1Value = Output(UInt(32.W))
val r2Value = Output(UInt(32.W)) val r2Value = Output(UInt(32.W))
val ALUOp = Output(UInt(4.W)) val ALUOp = Output(UInt(4.W))
val writeAddrIn = Input(UInt(5.W)) val writeAddrIn = Input(UInt(5.W))
@ -31,6 +32,7 @@ class InstructionDecode extends MultiIOModule {
val writeData = Input(UInt(32.W)) val writeData = Input(UInt(32.W))
val memWrite = Output(Bool()) val memWrite = Output(Bool())
val memRead = Output(Bool()) val memRead = Output(Bool())
val branchType = Output(UInt(3.W))
} }
) )
@ -68,9 +70,11 @@ class InstructionDecode extends MultiIOModule {
Op2Select.rs2 -> registers.io.readData2.asSInt(), Op2Select.rs2 -> registers.io.readData2.asSInt(),
) )
io.op2 := MuxLookup(decoder.op2Select, 0.S(32.W), select2Map) io.op2 := MuxLookup(decoder.op2Select, 0.S(32.W), select2Map)
io.r1Value := registers.io.readData1
io.r2Value := registers.io.readData2 io.r2Value := registers.io.readData2
io.ALUOp := decoder.ALUop io.ALUOp := decoder.ALUop
io.branchType := decoder.branchType
io.writeAddrOut := decoder.instruction.registerRd io.writeAddrOut := decoder.instruction.registerRd
io.writeEnableOut := decoder.controlSignals.regWrite io.writeEnableOut := decoder.controlSignals.regWrite
io.memRead := decoder.controlSignals.memRead io.memRead := decoder.controlSignals.memRead

View file

@ -10,10 +10,14 @@ class IDBarrier extends MultiIOModule {
val op1out = Output(SInt(32.W)) val op1out = Output(SInt(32.W))
val op2in = Input(SInt(32.W)) val op2in = Input(SInt(32.W))
val op2out = Output(SInt(32.W)) val op2out = Output(SInt(32.W))
val r1ValueIn = Input(UInt(32.W))
val r1ValueOut = Output(UInt(32.W))
val r2ValueIn = Input(UInt(32.W)) val r2ValueIn = Input(UInt(32.W))
val r2ValueOut = Output(UInt(32.W)) val r2ValueOut = Output(UInt(32.W))
val ALUopIn = Input(UInt(4.W)) val ALUopIn = Input(UInt(4.W))
val ALUopOut = Output(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 writeAddrIn = Input(UInt(5.W))
val writeAddrOut = Output(UInt(5.W)) val writeAddrOut = Output(UInt(5.W))
val writeEnableIn = Input(Bool()) val writeEnableIn = Input(Bool())
@ -32,6 +36,10 @@ class IDBarrier extends MultiIOModule {
op2 := io.op2in op2 := io.op2in
io.op2out := op2 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) val r2Value = RegInit(UInt(32.W), 0.U)
r2Value := io.r2ValueIn r2Value := io.r2ValueIn
io.r2ValueOut := r2Value io.r2ValueOut := r2Value
@ -40,6 +48,10 @@ class IDBarrier extends MultiIOModule {
ALUop := io.ALUopIn ALUop := io.ALUopIn
io.ALUopOut := ALUop 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) val writeAddr = RegInit(UInt(5.W), 0.U)
writeAddr := io.writeAddrIn writeAddr := io.writeAddrIn
io.writeAddrOut := writeAddr io.writeAddrOut := writeAddr

View file

@ -25,6 +25,8 @@ class InstructionFetch extends MultiIOModule {
new Bundle { new Bundle {
val PC = Output(UInt(32.W)) val PC = Output(UInt(32.W))
val instruction = Output(new Instruction) val instruction = Output(new Instruction)
val branch = Input(Bool())
val branchAddress = Input(UInt(32.W))
}) })
val IMEM = Module(new IMEM) val IMEM = Module(new IMEM)
@ -45,7 +47,7 @@ class InstructionFetch extends MultiIOModule {
*/ */
io.PC := PC io.PC := PC
IMEM.io.instructionAddress := PC IMEM.io.instructionAddress := PC
PC := PC + 4.U PC := Mux(io.branch, io.branchAddress, 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)

View file

@ -0,0 +1,7 @@
main:
addi x1, x1, 12
lui x2, 0
loop:
addi x2, x2, 1
blt x2, x1, loop
done

View file

@ -19,7 +19,7 @@ import LogParser._
object Manifest { object Manifest {
val singleTest = "constants.s" val singleTest = "branch.s"
val nopPadded = true val nopPadded = true