diff --git a/src/main/scala/funcunit/BranchControl.scala b/src/main/scala/funcunit/BranchControl.scala index a8aa8c1..b89af1b 100644 --- a/src/main/scala/funcunit/BranchControl.scala +++ b/src/main/scala/funcunit/BranchControl.scala @@ -1,10 +1,19 @@ package funcunit import chisel3._ +import chisel3.util._ +import funcunit.BranchControl.{TYPE_BEQ, TYPE_BNE, TYPE_JAL, TYPE_JR, NR_BR_INST} import pipeline._ -object BranchControl { - val TYPE_BEQ = 0 +object BranchControl extends Enumeration { + val TYPE_BEQ, TYPE_BNE, TYPE_JAL, TYPE_JR, NR_BR_INST = Value +// val TYPE_BEQ = 0 +// val TYPE_BNE = 1 + +// val TYPE_JAL = 2 +// val TYPE_JR = 3 + +// val NR_BR_INST = 4 } class BranchControl extends RawModule{ @@ -21,9 +30,25 @@ class BranchControl extends RawModule{ bc2fs_bus.br_target := br_target br_taken := false.B - br_target := ds2bc_bus.data.pc + es2bc_bus.data.offset + br_target := 0.U + + when (es2bc_bus.data.br_type(TYPE_BEQ.id) && es2bc_bus.data.br_cond.zero) { + br_taken := true.B + br_target := ds2bc_bus.data.pc + es2bc_bus.data.br_offset + } + + when (es2bc_bus.data.br_type(TYPE_BNE.id) && !es2bc_bus.data.br_cond.zero) { + br_taken := true.B + br_target := ds2bc_bus.data.pc + es2bc_bus.data.br_offset + } + + when (es2bc_bus.data.br_type(TYPE_JAL.id)) { + br_taken := true.B + br_target := Cat(ds2bc_bus.data.pc(31, 28), es2bc_bus.data.br_offset(27, 0)) + } - when (es2bc_bus.data.br_type(0) && es2bc_bus.data.cond.zero) { + when (es2bc_bus.data.br_type(TYPE_JR.id)) { br_taken := true.B + br_target := es2bc_bus.data.br_offset } } diff --git a/src/main/scala/funcunit/LdStControl.scala b/src/main/scala/funcunit/LdStControl.scala new file mode 100644 index 0000000..1e5e81f --- /dev/null +++ b/src/main/scala/funcunit/LdStControl.scala @@ -0,0 +1,5 @@ +package funcunit + +object LdStControl extends Enumeration { + val TYPE_LW, TYPE_SW, NR_LD_ST_INST = Value +} diff --git a/src/main/scala/mycpu_top.scala b/src/main/scala/mycpu_top.scala index 31636ee..b4f334f 100644 --- a/src/main/scala/mycpu_top.scala +++ b/src/main/scala/mycpu_top.scala @@ -32,7 +32,11 @@ class mycpu_top extends Module { ms.rf_write <> rf.write_channel // Sram Interface - es.data_sram <> data_sram + data_sram.en := es.data_sram_req.en + data_sram.wen := es.data_sram_req.wen + data_sram.addr := es.data_sram_req.addr + data_sram.wdata := es.data_sram_req.wdata + ms.data_sram_res.rdata := data_sram.rdata fs.inst_sram <> inst_sram // Debug Interface diff --git a/src/main/scala/pipeline/Decode.scala b/src/main/scala/pipeline/Decode.scala index 98f548d..d68405e 100644 --- a/src/main/scala/pipeline/Decode.scala +++ b/src/main/scala/pipeline/Decode.scala @@ -5,6 +5,7 @@ import chisel3.util._ import funcunit._ import funcunit.Alu._ import funcunit.BranchControl._ +import funcunit.LdStControl._ import Instructions._ class Decode extends Module { @@ -25,9 +26,11 @@ class Decode extends Module { val rs = inst(25, 21) val rt = inst(20, 16) val rd = inst(15, 11) + val sa = inst(10, 6) val uimm16 = Cat(Fill(16, false.B), inst(15, 0)) val simm16 = Cat(Fill(16, inst(15)), inst(15, 0)) val simm18 = Cat(Fill(14, inst(15)), inst(15, 0), Fill(2, false.B)) + val imm28 = Cat(Fill(4, false.B), inst(25, 0), Fill(2, false.B)) // Operand Helper Methods def ITypeOp(aluop: Int): Unit = { @@ -38,7 +41,7 @@ class Decode extends Module { ds2es_bus.data.rf_wnum := rt } - def ITypeOp(aluop: Int, br_type: Int): Unit = { + def ITypeOp_Br(aluop: Int, br_type: Int): Unit = { ds2es_bus.data.aluop(aluop) := true.B ds2es_bus.data.src(0) := rf_read.rdata(0) ds2es_bus.data.src(1) := rf_read.rdata(1) @@ -46,6 +49,24 @@ class Decode extends Module { ds2es_bus.data.br_type(br_type) := true.B } + def ItypeOp_Ld(ld_type: Int): Unit = { + ds2es_bus.data.src(0) := rf_read.rdata(0) + ds2es_bus.data.src(1) := simm16 + ds2es_bus.data.rf_wen := true.B + ds2es_bus.data.rf_wnum := rt + ds2es_bus.data.req_mem := true.B + ds2es_bus.data.ld_st_type(ld_type) := true.B + } + + def ItypeOp_St(st_type: Int): Unit = { + ds2es_bus.data.src(0) := rf_read.rdata(0) + ds2es_bus.data.src(1) := simm16 + ds2es_bus.data.req_mem := true.B + ds2es_bus.data.ld_st_type(st_type) := true.B + // now br_offset is store data + ds2es_bus.data.br_offset := rf_read.rdata(1) + } + def RTypeOp(aluop: Int): Unit = { ds2es_bus.data.aluop(aluop) := true.B ds2es_bus.data.src(0) := rf_read.rdata(0) @@ -54,6 +75,29 @@ class Decode extends Module { ds2es_bus.data.rf_wnum := rd } + def RTypeOp_ShiftSa(aluop: Int): Unit = { + ds2es_bus.data.aluop(aluop) := true.B + ds2es_bus.data.src(0) := sa + ds2es_bus.data.src(1) := rf_read.rdata(1) + ds2es_bus.data.rf_wen := true.B + ds2es_bus.data.rf_wnum := rd + } + + def RTypeOp_Jr(): Unit = { + ds2es_bus.data.br_type(TYPE_JR.id) := true.B + ds2es_bus.data.br_offset := rf_read.rdata(0) + } + + def JTypeOp_Jal(): Unit = { + ds2es_bus.data.aluop(OP_ADD) := true.B + ds2es_bus.data.src(0) := data.pc + ds2es_bus.data.src(1) := 8.U + ds2es_bus.data.rf_wen := true.B + ds2es_bus.data.rf_wnum := 31.U + ds2es_bus.data.br_type(TYPE_JAL.id) := true.B + ds2es_bus.data.br_offset := imm28 + } + def DsToEsBusDataInit(): Unit = { ds2es_bus.data.pc := data.pc ds2es_bus.data.rf_wnum := 0.U @@ -64,9 +108,12 @@ class Decode extends Module { for (i <- 0 to 11) { ds2es_bus.data.aluop(i) := false.B } - for (i <- 0 to 0) { + for (i <- 0 until NR_BR_INST.id) { ds2es_bus.data.br_type(i) := false.B } + for (i <- 0 until NR_LD_ST_INST.id) { + ds2es_bus.data.ld_st_type(i) := false.B + } ds2es_bus.data.br_offset := 0.U } @@ -100,9 +147,61 @@ class Decode extends Module { RTypeOp(OP_ADD) } + when (inst === ADDU) { + RTypeOp(OP_ADD) + } + + when (inst === SUBU) { + RTypeOp(OP_SUB) + } + + when (inst === AND) { + RTypeOp(OP_AND) + } + + when (inst === OR) { + RTypeOp(OP_OR) + } + + when (inst === XOR) { + RTypeOp(OP_XOR) + } + + when (inst === NOR) { + RTypeOp(OP_NOR) + } + + when (inst === SLT) { + RTypeOp(OP_SLT) + } + + when (inst === SLTU) { + RTypeOp(OP_SLTU) + } + + when (inst === SLL) { + RTypeOp_ShiftSa(OP_SLL) + } + + when (inst === SRL) { + RTypeOp_ShiftSa(OP_SRL) + } + + when (inst === SRA) { + RTypeOp_ShiftSa(OP_SRA) + } + + when (inst === JR) { + RTypeOp_Jr() + } + // I-type when (inst === BEQ) { - ITypeOp(OP_SUB, TYPE_BEQ) + ITypeOp_Br(OP_SUB, TYPE_BEQ.id) + } + + when (inst === BNE) { + ITypeOp_Br(OP_SUB, TYPE_BNE.id) } when (inst === ADDI) { @@ -121,4 +220,16 @@ class Decode extends Module { ITypeOp(OP_LUI) } + when (inst === LW) { + ItypeOp_Ld(TYPE_LW.id) + } + + when (inst === SW) { + ItypeOp_St(TYPE_SW.id) + } + + // J-type + when (inst === JAL) { + JTypeOp_Jal() + } } diff --git a/src/main/scala/pipeline/Execute.scala b/src/main/scala/pipeline/Execute.scala index fa9db72..bfa7967 100644 --- a/src/main/scala/pipeline/Execute.scala +++ b/src/main/scala/pipeline/Execute.scala @@ -9,7 +9,7 @@ class Execute extends Module{ val ds2es_bus = IO(Flipped(new DsToEsBus)) val es2ms_bus = IO(new EsToMsBus) val es2bc_bus = IO(new EsToBcBus) - val data_sram = IO(new SramInterface) + val data_sram_req = IO(new SramReq) // Stage Control val valid = RegInit(false.B) @@ -26,20 +26,21 @@ class Execute extends Module{ es2ms_bus.data.pc := data.pc es2ms_bus.data.rf.wen := Fill(4, data.rf_wen) es2ms_bus.data.rf.wnum := data.rf_wnum - es2ms_bus.data.rf.wdata := Mux(data.req_mem, data_sram.rdata, alu.io.alu_result) - - es2bc_bus.data.offset := data.br_offset - es2bc_bus.data.cond.result := alu.io.alu_result - es2bc_bus.data.cond.carryout := alu.io.alu_carryout - es2bc_bus.data.cond.overflow := alu.io.alu_overflow - es2bc_bus.data.cond.zero := alu.io.alu_zero + es2ms_bus.data.rf.wdata := alu.io.alu_result + es2ms_bus.data.req_mem := data.req_mem + + es2bc_bus.data.br_offset := data.br_offset + es2bc_bus.data.br_cond.result := alu.io.alu_result + es2bc_bus.data.br_cond.carryout := alu.io.alu_carryout + es2bc_bus.data.br_cond.overflow := alu.io.alu_overflow + es2bc_bus.data.br_cond.zero := alu.io.alu_zero es2bc_bus.data.br_type := data.br_type es2bc_bus.data.valid := valid - data_sram.en := data.req_mem - data_sram.wen := 0.U - data_sram.addr := alu.io.mem_addr_result - data_sram.wdata := 0.U + data_sram_req.en := data.req_mem && valid + data_sram_req.wen := Mux(data.ld_st_type(1), "b1111".U, 0.U) + data_sram_req.addr := alu.io.mem_addr_result + data_sram_req.wdata := data.br_offset /* Stage Control Implement */ es_ready_go := true.B diff --git a/src/main/scala/pipeline/Instructions.scala b/src/main/scala/pipeline/Instructions.scala index 760f77d..64e56d0 100644 --- a/src/main/scala/pipeline/Instructions.scala +++ b/src/main/scala/pipeline/Instructions.scala @@ -6,12 +6,34 @@ import chisel3.util._ object Instructions { // R-type def ADD = BitPat("b000000 ????? ????? ????? 00000 100000") + def ADDU = BitPat("b000000 ????? ????? ????? 00000 100001") + def SUBU = BitPat("b000000 ????? ????? ????? 00000 100011") + def AND = BitPat("b000000 ????? ????? ????? 00000 100100") + def OR = BitPat("b000000 ????? ????? ????? 00000 100101") + def XOR = BitPat("b000000 ????? ????? ????? 00000 100110") + def NOR = BitPat("b000000 ????? ????? ????? 00000 100111") + def SLT = BitPat("b000000 ????? ????? ????? 00000 101010") + def SLTU = BitPat("b000000 ????? ????? ????? 00000 101011") + + def SLL = BitPat("b000000 00000 ????? ????? ????? 000000") + def SRL = BitPat("b000000 00000 ????? ????? ????? 000010") + def SRA = BitPat("b000000 00000 ????? ????? ????? 000011") + + def JR = BitPat("b000000 ????? 00000 00000 00000 001000") // I-type def BEQ = BitPat("b000100 ????? ????? ????? ????? ??????") + def BNE = BitPat("b000101 ????? ????? ????? ????? ??????") + def ADDI = BitPat("b001000 ????? ????? ????? ????? ??????") def ADDIU = BitPat("b001001 ????? ????? ????? ????? ??????") def ORI = BitPat("b001101 ????? ????? ????? ????? ??????") def LUI = BitPat("b001111 ????? ????? ????? ????? ??????") + def LW = BitPat("b100011 ????? ????? ????? ????? ??????") + def SW = BitPat("b101011 ????? ????? ????? ????? ??????") + + // J-type + def JAL = BitPat("b000011 ????? ????? ????? ????? ??????") + } diff --git a/src/main/scala/pipeline/Interface.scala b/src/main/scala/pipeline/Interface.scala index 754e149..2ebebab 100644 --- a/src/main/scala/pipeline/Interface.scala +++ b/src/main/scala/pipeline/Interface.scala @@ -2,21 +2,28 @@ package pipeline import chisel3._ import funcunit._ +import funcunit.BranchControl._ +import funcunit.LdStControl._ // sram insterface -trait SramReq extends Bundle { +class SramReq extends Bundle { val en = Output(Bool()) val wen = Output(UInt(4.W)) val addr = Output(UInt(32.W)) val wdata = Output(UInt(32.W)) } -trait SramRes extends Bundle { +class SramRes extends Bundle { val rdata = Input(UInt(32.W)) } -class SramInterface extends Bundle with SramReq with SramRes - +class SramInterface extends Bundle { + val en = Output(Bool()) + val wen = Output(UInt(4.W)) + val addr = Output(UInt(32.W)) + val wdata = Output(UInt(32.W)) + val rdata = Input(UInt(32.W)) +} // inst-fetch and decode class FsToDsData extends Bundle { val pc = Output(UInt(32.W)) @@ -41,9 +48,11 @@ class DsToEsData extends Bundle { val aluop = Output(Vec(12, Bool())) // inst-type - val br_type = Output(Vec(1, Bool())) + val br_type = Output(Vec(NR_BR_INST.id, Bool())) val br_offset = Output(UInt(32.W)) + val ld_st_type = Output(Vec(NR_LD_ST_INST.id, Bool())) + // Sram Interface val req_mem = Output(Bool()) } @@ -65,9 +74,8 @@ class DsToBcBus extends Bundle { // execute and memory class EsToMsData extends Bundle { val pc = Output(UInt(32.W)) - - // RF Interface val rf = new FlippedRFWrite + val req_mem = Output(Bool()) } class EsToMsBus extends Bundle { @@ -78,14 +86,14 @@ class EsToMsBus extends Bundle { class EsToBcData extends Bundle { // val pc = Output(UInt(32.W)) - val offset = Output(UInt(32.W)) - val cond = new Bundle() { + val br_offset = Output(UInt(32.W)) + val br_cond = new Bundle() { val result = Output(UInt(32.W)) val carryout = Output(Bool()) val overflow = Output(Bool()) val zero = Output(Bool()) } - val br_type = Output(Vec(1, Bool())) + val br_type = Output(Vec(NR_BR_INST.id, Bool())) val valid = Output(Bool()) } diff --git a/src/main/scala/pipeline/Memory.scala b/src/main/scala/pipeline/Memory.scala index 6bcefa1..4fd2b86 100644 --- a/src/main/scala/pipeline/Memory.scala +++ b/src/main/scala/pipeline/Memory.scala @@ -1,10 +1,12 @@ package pipeline +import Chisel.Fill import chisel3._ import funcunit._ class Memory extends Module{ // Interface + val data_sram_res = IO(new SramRes) val es2msbus = IO(Flipped(new EsToMsBus)) val rf_write = IO(Flipped(new RFWrite)) val debug = IO(new DebugInterface) @@ -16,9 +18,12 @@ class Memory extends Module{ /* Interface Implement */ es2msbus.ms_allowin := !valid || ms_ready_go - rf_write := data.rf + rf_write.wen := data.rf.wen & Fill(4, valid) + rf_write.wdata := Mux(data.req_mem, data_sram_res.rdata, data.rf.wdata) + rf_write.wnum := data.rf.wnum debug.pc := data.pc - debug.rf := data.rf + debug.rf := rf_write + /* Stage Control Implement */ ms_ready_go := true.B