Skip to content

Commit

Permalink
Merge branch 'main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
longfangsong authored Apr 2, 2024
2 parents e1e862d + b01fb22 commit 02e6b9f
Show file tree
Hide file tree
Showing 7 changed files with 310 additions and 192 deletions.
36 changes: 11 additions & 25 deletions src/main/scala/ALU.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,58 +3,44 @@ import chisel3.util._

class ALU extends Module {

import ALUOperation._

val io = IO(new Bundle {
val A = Input(Bits(32.W))
val B = Input(Bits(32.W))
val op = Input(Bits(4.W))
val op = Input(UOp())
val result = Output(Bits(32.W))
})
io.result := 0xdead.U
switch(io.op) {
is(ADD) {
is(UOp.ADD) {
io.result := io.A.asUInt + io.B.asUInt
}
is(SUB) {
is(UOp.SUB) {
io.result := io.A.asUInt - io.B.asUInt
}
is(SLL) {
is(UOp.SLL) {
io.result := io.A << io.B(4, 0).asUInt
}
is(SLT) {
is(UOp.SLT) {
io.result := io.A.asSInt < io.B.asSInt
}
is(SLTU) {
is(UOp.SLTU) {
io.result := io.A.asUInt < io.B.asUInt
}
is(XOR) {
is(UOp.XOR) {
io.result := io.A ^ io.B
}
is(SRL) {
is(UOp.SRL) {
io.result := io.A >> io.B(4, 0).asUInt
}
is(SRA) {
is(UOp.SRA) {
io.result := (io.A.asSInt >> io.B(4, 0)).asUInt()
}
is(OR) {
is(UOp.OR) {
io.result := io.A | io.B
}
is(AND) {
is(UOp.AND) {
io.result := io.A & io.B
}
}
}

object ALUOperation extends Enumeration {
val ADD = "b0000".U
val SUB = "b1000".U
val SLL = "b0001".U
val SLT = "b0010".U
val SLTU = "b0011".U
val XOR = "b0100".U
val SRL = "b0101".U
val SRA = "b1101".U
val OR = "b0110".U
val AND = "b0111".U
}
24 changes: 7 additions & 17 deletions src/main/scala/BranchCondition.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,32 @@ import chisel3.util._

class BranchCondition extends Module {

import BranchType._

val io = IO(new Bundle {
val A = Input(Bits(32.W))
val B = Input(Bits(32.W))
val op = Input(Bits(3.W))
val op = Input(UOp())
val take = Output(Bool())
})
io.take := false.B
switch(io.op) {
is(EQ) {
is(UOp.BEQ) {
io.take := io.A.asSInt() === io.B.asSInt()
}
is(NE) {
is(UOp.BNE) {
io.take := io.A.asSInt() =/= io.B.asSInt()
}
is(LT) {
is(UOp.BLT) {
io.take := io.A.asSInt() < io.B.asSInt()
}
is(GE) {
is(UOp.BGE) {
io.take := io.A.asSInt() >= io.B.asSInt()
}
is(LTU) {
is(UOp.BLTU) {
io.take := io.A.asUInt() < io.B.asUInt()
}
is(GEU) {
is(UOp.BGEU) {
io.take := io.A.asUInt() >= io.B.asUInt()
}
}
}

object BranchType extends Enumeration {
val EQ = "b000".U
val NE = "b001".U
val LT = "b100".U
val GE = "b101".U
val LTU = "b110".U
val GEU = "b111".U
}
122 changes: 43 additions & 79 deletions src/main/scala/CPU.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ class CPUBundle extends Bundle {

class CPU extends Module {

import CommandType._

val io = IO(new CPUBundle)

Expand All @@ -21,6 +20,9 @@ class CPU extends Module {
val instruction = Wire(UInt(32.W))
instruction := io.programROMBundle.value

val decoder = Wire(new Decoder())
decoder.decode(instruction)

io.dataBusBundle.readMode := true.B
io.dataBusBundle.maskLevel := Mask.WORD
io.dataBusBundle.address := 0.U
Expand All @@ -34,52 +36,44 @@ class CPU extends Module {
csr.io.timerInterruptPending := io.timerInterruptPending

val regFile = Module(new RegFile)
regFile.io.addressInput := instruction(11, 7)
regFile.io.addressA := instruction(19, 15)
regFile.io.addressB := instruction(24, 20)
regFile.io.addressInput := decoder.rdAddr
regFile.io.addressA := decoder.rs1Addr
regFile.io.addressB := decoder.rs2Addr
regFile.io.input := 0xdead.U
regFile.io.writeEnable := false.B

val immGen = Module(new Imm)
immGen.io.instruction := instruction

val branchCondition = Module(new BranchCondition)
branchCondition.io.A := regFile.io.outputA
branchCondition.io.B := regFile.io.outputB
branchCondition.io.op := instruction(14, 12)
branchCondition.io.op := decoder.uOp

val alu = Module(new ALU)
alu.io.A := 0xdead.U
alu.io.B := 0xdead.U
alu.io.op := 0xdead.U
alu.io.op := UOp.NOP

val stall = RegInit(false.B)

when(stall) {
stall := false.B
regFile.io.writeEnable := true.B
io.dataBusBundle.address := (regFile.io.outputA.asSInt() + immGen.io.result).asUInt()
io.dataBusBundle.maskLevel := instruction(13, 12)
io.dataBusBundle.address := (regFile.io.outputA.asSInt() + decoder.immData.asSInt()).asUInt()
io.dataBusBundle.maskLevel := decoder.maskLevel
// second part of load
switch(instruction(14, 12)) {
// LB
is("b000".U) {
switch(decoder.uOp) {
is(UOp.LB) {
regFile.io.input := io.dataBusBundle.dataOut(7, 0)
}
// LH
is("b001".U) {
is(UOp.LH) {
regFile.io.input := io.dataBusBundle.dataOut(15, 0)
}
// LW
is("b010".U) {
is(UOp.LW) {
regFile.io.input := io.dataBusBundle.dataOut
}
// LBU
is("b100".U) {
is(UOp.LBU) {
regFile.io.input := io.dataBusBundle.dataOut(7, 0).asUInt()
}
// LHU
is("b101".U) {
is(UOp.LHU) {
regFile.io.input := io.dataBusBundle.dataOut(15, 0).asUInt()
}
}
Expand All @@ -90,80 +84,69 @@ class CPU extends Module {
csr.io.inputValue := pc + 4.U
pc := csr.io.pcOnInterrupt
}.otherwise {
switch(instruction(6, 2)) {
is(LUI) {
regFile.io.input := immGen.io.result.asUInt()
switch(decoder.instType) {
is(InstType.LUI) {
regFile.io.input := decoder.immData
regFile.io.writeEnable := true.B
}
is(AUIPC) {
alu.io.A := immGen.io.result.asUInt()
is(InstType.AUIPC) {
alu.io.A := decoder.immData
alu.io.B := pc
alu.io.op := ALUOperation.ADD
alu.io.op := UOp.ADD

regFile.io.input := alu.io.result
regFile.io.writeEnable := true.B
}
is(JAL) {
is(InstType.JAL) {
alu.io.A := 4.U
alu.io.B := pc
alu.io.op := ALUOperation.ADD
alu.io.op := UOp.ADD

regFile.io.input := alu.io.result
regFile.io.writeEnable := true.B
pc := (pc.asSInt() + immGen.io.result).asUInt()
pc := (pc.asSInt() + decoder.immData.asSInt()).asUInt()
}
is(JALR) {
is(InstType.JALR) {
alu.io.A := regFile.io.outputA
alu.io.B := immGen.io.result.asUInt()
alu.io.op := ALUOperation.ADD
alu.io.B := decoder.immData
alu.io.op := UOp.ADD

regFile.io.input := pc + 4.U
regFile.io.writeEnable := true.B
pc := alu.io.result & "hfffffffe".U
}
is(BRANCH) {
is(InstType.BRANCH) {
when(branchCondition.io.take) {
pc := (pc.asSInt() + immGen.io.result).asUInt()
pc := (pc.asSInt() + decoder.immData.asSInt()).asUInt()
}
}
is(LOAD) {
is(InstType.LOAD) {
// first part of load: send a load command to addressSpace
io.dataBusBundle.address := (regFile.io.outputA.asSInt() + immGen.io.result).asUInt()
io.dataBusBundle.maskLevel := instruction(13, 12)
io.dataBusBundle.address := (regFile.io.outputA.asSInt() + decoder.immData.asSInt()).asUInt()
io.dataBusBundle.maskLevel := decoder.maskLevel
// stall once for waiting for the load result come out
pc := pc
stall := true.B
}
is(STORE) {
io.dataBusBundle.address := (regFile.io.outputA.asSInt() + immGen.io.result).asUInt()
is(InstType.STORE) {
io.dataBusBundle.address := (regFile.io.outputA.asSInt() + decoder.immData.asSInt()).asUInt()
io.dataBusBundle.readMode := false.B
io.dataBusBundle.maskLevel := instruction(13, 12)
io.dataBusBundle.maskLevel := decoder.maskLevel
io.dataBusBundle.dataIn := regFile.io.outputB
}
is(CALCULATE_IMM) {
regFile.io.writeEnable := true.B
alu.io.A := regFile.io.outputA
alu.io.B := immGen.io.result.asUInt()
when(instruction(14, 12) === "b001".U || instruction(14, 12) === "b101".U) {
alu.io.op := Cat(instruction(30), instruction(14, 12))
}.otherwise {
alu.io.op := Cat(0.U(1.W), instruction(14, 12))
}
regFile.io.input := alu.io.result
}
is(CALCULATE_REG) {
is(InstType.CALCULATE) {
regFile.io.writeEnable := true.B
alu.io.A := regFile.io.outputA
alu.io.B := regFile.io.outputB
alu.io.op := Cat(instruction(30), instruction(14, 12))
alu.io.B := Mux(decoder.needImm,decoder.immData,regFile.io.outputB)
alu.io.op := decoder.uOp
regFile.io.input := alu.io.result
}
is(FENCE) {
is(InstType.FENCE) {
// we don't have multicore, pipeline, etc. now, so we don't need this command
}
is(SYSTEM) {
switch(instruction(31, 20)) {
is(SystemCommand.MRET) {
is(InstType.SYSTEM) {
switch(decoder.uOp) {
is(UOp.MRET) {
csr.io.flipStatusMIE := true.B
csr.io.address := CSRAddress.mepc
pc := csr.io.outputValue
Expand All @@ -174,22 +157,3 @@ class CPU extends Module {
}
}

object CommandType extends Enumeration {
val LUI = "b01101".U
val AUIPC = "b00101".U
val JAL = "b11011".U
val JALR = "b11001".U
val BRANCH = "b11000".U
val LOAD = "b00000".U
val STORE = "b01000".U
val CALCULATE_IMM = "b00100".U
val CALCULATE_REG = "b01100".U
val FENCE = "b00011".U
val SYSTEM = "b11100".U
}

object SystemCommand extends Enumeration {
val MRET = "h302".U
val ECALL = "b000".U
val EBREAK = "b001".U
}
Loading

0 comments on commit 02e6b9f

Please sign in to comment.