diff --git a/src/main/scala/funcunit/BranchControl.scala b/src/main/scala/funcunit/BranchControl.scala index b89af1b..52d9198 100644 --- a/src/main/scala/funcunit/BranchControl.scala +++ b/src/main/scala/funcunit/BranchControl.scala @@ -7,13 +7,6 @@ import pipeline._ 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{ diff --git a/src/main/scala/funcunit/ForwardPath.scala b/src/main/scala/funcunit/ForwardPath.scala new file mode 100644 index 0000000..b8a312f --- /dev/null +++ b/src/main/scala/funcunit/ForwardPath.scala @@ -0,0 +1,43 @@ +package funcunit + +import chisel3._ +import pipeline.{DsToFPBus, EsToFPBus, MsToFPBus} + +class ForwardPath extends Module{ + val es2fp_bus = IO(Flipped(new EsToFPBus)) + val ms2fp_bus = IO(Flipped(new MsToFPBus)) + val ds2fp_bus = IO(Flipped(new DsToFPBus)) + val rf_read = IO(Flipped(new RFRead)) + + val es_rel = Wire(Vec(2, Bool())) + val ms_rel = Wire(Vec(2, Bool())) + val es_hit = Wire(Vec(2, Bool())) + val ms_hit = Wire(Vec(2, Bool())) + + rf_read.raddr := ds2fp_bus.rf_read.raddr + + for (i <- 0 to 1) { + es_rel(i) := (ds2fp_bus.rf_read.raddr(i) === es2fp_bus.data.rf_wnum) && es2fp_bus.data.addr_valid && (ds2fp_bus.rf_read.raddr(i) =/= 0.U) + es_hit(i) := es2fp_bus.data.data_valid + + ms_rel(i) := (ds2fp_bus.rf_read.raddr(i) === ms2fp_bus.data.rf_wnum) && ms2fp_bus.data.addr_valid && (ds2fp_bus.rf_read.raddr(i) =/= 0.U) + ms_hit(i) := ms2fp_bus.data.data_valid + + when (es_rel(i) && es_hit(i)) { + ds2fp_bus.rf_read.rdata(i) := es2fp_bus.data.rf_wdata + }.elsewhen(ms_rel(i) && ms_hit(i)) { + ds2fp_bus.rf_read.rdata(i) := ms2fp_bus.data.rf_wdata + }.otherwise { + ds2fp_bus.rf_read.rdata(i) := rf_read.rdata(i) + } + + + } + + when (es_rel(0) && !es_hit(0) || es_rel(1) && !es_hit(1)) { + ds2fp_bus.stall := true.B + }.otherwise { + ds2fp_bus.stall := false.B + } + +} diff --git a/src/main/scala/mycpu_top.scala b/src/main/scala/mycpu_top.scala index b4f334f..b7db3c4 100644 --- a/src/main/scala/mycpu_top.scala +++ b/src/main/scala/mycpu_top.scala @@ -20,15 +20,16 @@ class mycpu_top extends Module { val es = Module(new Execute) val ms = Module(new Memory) val bc = Module(new BranchControl) + val fp = Module(new ForwardPath) val rf = Module(new RegFile) // Pipeline Interface fs.fs2ds_bus <> ds.fs2ds_bus ds.ds2es_bus <> es.ds2es_bus - es.es2ms_bus <> ms.es2msbus + es.es2ms_bus <> ms.es2ms_bus // RegFile Interface - ds.rf_read <> rf.read_channel + fp.rf_read <> rf.read_channel ms.rf_write <> rf.write_channel // Sram Interface @@ -47,5 +48,10 @@ class mycpu_top extends Module { bc.es2bc_bus <> es.es2bc_bus bc.bc2ds_bus <> ds.bc2ds_bus bc.bc2fs_bus <> fs.bc2fs_bus + + // Forward Path + fp.es2fp_bus <> es.es2fp_bus + fp.ms2fp_bus <> ms.ms2fp_bus + fp.ds2fp_bus <> ds.data_fetch } } diff --git a/src/main/scala/pipeline/Decode.scala b/src/main/scala/pipeline/Decode.scala index d68405e..c2fc520 100644 --- a/src/main/scala/pipeline/Decode.scala +++ b/src/main/scala/pipeline/Decode.scala @@ -14,7 +14,7 @@ class Decode extends Module { val ds2es_bus = IO(new DsToEsBus) val bc2ds_bus = IO(Flipped(new BcToDsBus)) val ds2bc_bus = IO(new DsToBcBus) - val rf_read = IO(Flipped(new RFRead)) + val data_fetch = IO(new DsToFPBus) // Stage Control val valid = RegInit(false.B) @@ -35,7 +35,7 @@ class Decode extends Module { // Operand Helper Methods def ITypeOp(aluop: Int): Unit = { ds2es_bus.data.aluop(aluop) := true.B - ds2es_bus.data.src(0) := rf_read.rdata(0) + ds2es_bus.data.src(0) := data_fetch.rf_read.rdata(0) ds2es_bus.data.src(1) := simm16 ds2es_bus.data.rf_wen := true.B ds2es_bus.data.rf_wnum := rt @@ -43,14 +43,14 @@ class Decode extends Module { 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) + ds2es_bus.data.src(0) := data_fetch.rf_read.rdata(0) + ds2es_bus.data.src(1) := data_fetch.rf_read.rdata(1) ds2es_bus.data.br_offset := simm18 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(0) := data_fetch.rf_read.rdata(0) ds2es_bus.data.src(1) := simm16 ds2es_bus.data.rf_wen := true.B ds2es_bus.data.rf_wnum := rt @@ -59,18 +59,18 @@ class Decode extends Module { } def ItypeOp_St(st_type: Int): Unit = { - ds2es_bus.data.src(0) := rf_read.rdata(0) + ds2es_bus.data.src(0) := data_fetch.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) + ds2es_bus.data.br_offset := data_fetch.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) - ds2es_bus.data.src(1) := rf_read.rdata(1) + ds2es_bus.data.src(0) := data_fetch.rf_read.rdata(0) + ds2es_bus.data.src(1) := data_fetch.rf_read.rdata(1) ds2es_bus.data.rf_wen := true.B ds2es_bus.data.rf_wnum := rd } @@ -78,14 +78,14 @@ class Decode extends Module { 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.src(1) := data_fetch.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) + ds2es_bus.data.br_offset := data_fetch.rf_read.rdata(0) } def JTypeOp_Jal(): Unit = { @@ -125,11 +125,11 @@ class Decode extends Module { ds2bc_bus.data.pc := data.pc - rf_read.raddr(0) := rs - rf_read.raddr(1) := rt + data_fetch.rf_read.raddr(0) := rs + data_fetch.rf_read.raddr(1) := rt /* Stage Control Implement */ - ds_ready_go := true.B + ds_ready_go := !data_fetch.stall when (bc2ds_bus.br_taken) { valid := false.B }.elsewhen(fs2ds_bus.ds_allowin) { diff --git a/src/main/scala/pipeline/Execute.scala b/src/main/scala/pipeline/Execute.scala index bfa7967..3aef946 100644 --- a/src/main/scala/pipeline/Execute.scala +++ b/src/main/scala/pipeline/Execute.scala @@ -9,6 +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 es2fp_bus = IO(new EsToFPBus) val data_sram_req = IO(new SramReq) // Stage Control @@ -37,6 +38,11 @@ class Execute extends Module{ es2bc_bus.data.br_type := data.br_type es2bc_bus.data.valid := valid + es2fp_bus.data.rf_wnum := data.rf_wnum + es2fp_bus.data.rf_wdata := alu.io.alu_result + es2fp_bus.data.addr_valid := valid && data.rf_wen + es2fp_bus.data.data_valid := valid && !(data.ld_st_type.asUInt.orR) && data.rf_wen + 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 diff --git a/src/main/scala/pipeline/Interface.scala b/src/main/scala/pipeline/Interface.scala index 2ebebab..6132504 100644 --- a/src/main/scala/pipeline/Interface.scala +++ b/src/main/scala/pipeline/Interface.scala @@ -85,7 +85,6 @@ class EsToMsBus extends Bundle { } class EsToBcData extends Bundle { -// val pc = Output(UInt(32.W)) val br_offset = Output(UInt(32.W)) val br_cond = new Bundle() { val result = Output(UInt(32.W)) @@ -101,6 +100,15 @@ class EsToBcBus extends Bundle { val data = new EsToBcData } +class EsToFPBus extends Bundle { + val data = new StageToFPData +} + +// memory and forward +class MsToFPBus extends Bundle { + val data = new StageToFPData +} + // Debug Interface class DebugInterface extends Bundle { val pc = Output(UInt(32.W)) @@ -120,3 +128,16 @@ class BcToFsBus extends Bundle { val br_taken = Output(Bool()) val br_target = Output(UInt(32.W)) } + +// Forward Path Interface +class StageToFPData extends Bundle { + val rf_wnum = Output(UInt(5.W)) + val rf_wdata = Output(UInt(32.W)) + val data_valid = Output(Bool()) + val addr_valid = Output(Bool()) +} + +class DsToFPBus extends Bundle { + val rf_read = Flipped(new RFRead) + val stall = Input(Bool()) +} diff --git a/src/main/scala/pipeline/Memory.scala b/src/main/scala/pipeline/Memory.scala index 4fd2b86..608db1f 100644 --- a/src/main/scala/pipeline/Memory.scala +++ b/src/main/scala/pipeline/Memory.scala @@ -7,7 +7,8 @@ import funcunit._ class Memory extends Module{ // Interface val data_sram_res = IO(new SramRes) - val es2msbus = IO(Flipped(new EsToMsBus)) + val es2ms_bus = IO(Flipped(new EsToMsBus)) + val ms2fp_bus = IO(new MsToFPBus) val rf_write = IO(Flipped(new RFWrite)) val debug = IO(new DebugInterface) @@ -17,22 +18,29 @@ class Memory extends Module{ val data = Reg(new EsToMsData) /* Interface Implement */ - es2msbus.ms_allowin := !valid || ms_ready_go + es2ms_bus.ms_allowin := !valid || ms_ready_go + + ms2fp_bus.data.rf_wnum := rf_write.wnum + ms2fp_bus.data.rf_wdata := rf_write.wdata + ms2fp_bus.data.addr_valid := valid && data.rf.wen(0) + ms2fp_bus.data.data_valid := valid && data.rf.wen(0) + 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 := rf_write /* Stage Control Implement */ ms_ready_go := true.B - when (es2msbus.ms_allowin) { - valid := es2msbus.es_valid + when (es2ms_bus.ms_allowin) { + valid := es2ms_bus.es_valid } - when (es2msbus.es_valid && es2msbus.ms_allowin) { - data := es2msbus.data + when (es2ms_bus.es_valid && es2ms_bus.ms_allowin) { + data := es2ms_bus.data } }