refactor(exe): 重构部分跳转信号

This commit is contained in:
Liphen 2023-12-01 16:12:30 +08:00
parent a08eb20f88
commit 36840d6abe
7 changed files with 92 additions and 97 deletions

View File

@ -137,10 +137,9 @@ class Core(implicit val config: CpuConfig) extends Module {
io.debug <> writeBackUnit.debug io.debug <> writeBackUnit.debug
io.inst.fence_i := executeUnit.executeStage.inst0.info.fusel === FuType.mou && io.inst.fence := executeUnit.executeStage.inst0.info.fusel === FuType.mou &&
executeUnit.executeStage.inst0.info.op === MOUOpType.fencei executeUnit.executeStage.inst0.info.op === MOUOpType.fencei
io.data.fence_i := memoryUnit.memoryStage.inst0.info.fusel === FuType.mou && io.data.fence := false.B
memoryUnit.memoryStage.inst0.info.op === MOUOpType.fencei
io.inst.req := !instFifo.full && !reset.asBool io.inst.req := !instFifo.full && !reset.asBool
io.inst.cpu_ready := ctrl.fetchUnit.allow_to_go io.inst.cpu_ready := ctrl.fetchUnit.allow_to_go
io.data.cpu_ready := ctrl.memoryUnit.allow_to_go io.data.cpu_ready := ctrl.memoryUnit.allow_to_go

View File

@ -71,7 +71,7 @@ class DCache(implicit config: CpuConfig) extends Module {
val cached_stall = false.B val cached_stall = false.B
io.cpu.dcache_stall := Mux( io.cpu.dcache_stall := Mux(
status === s_idle && !acc_err, status === s_idle && !acc_err,
Mux(io.cpu.en, (cached_stall || mmio_read_stall || mmio_write_stall), io.cpu.fence_i), Mux(io.cpu.en, (cached_stall || mmio_read_stall || mmio_write_stall), io.cpu.fence),
status =/= s_save status =/= s_save
) )
io.cpu.rdata := saved_rdata io.cpu.rdata := saved_rdata

View File

@ -111,7 +111,7 @@ class Cache_ICache(implicit val config: CpuConfig) extends Bundle {
val req = Output(Bool()) val req = Output(Bool())
val cpu_ready = Output(Bool()) // !cpu_stall val cpu_ready = Output(Bool()) // !cpu_stall
val addr = Output(Vec(config.instFetchNum, UInt(INST_ADDR_WID.W))) // virtual address and next virtual address val addr = Output(Vec(config.instFetchNum, UInt(INST_ADDR_WID.W))) // virtual address and next virtual address
val fence_i = Output(Bool()) val fence = Output(Bool())
// read inst result // read inst result
val inst = Input(Vec(config.instFetchNum, UInt(INST_WID.W))) val inst = Input(Vec(config.instFetchNum, UInt(INST_WID.W)))
@ -128,7 +128,7 @@ class Cache_DCache extends Bundle {
val wen = Output(Bool()) val wen = Output(Bool())
val wdata = Output(UInt(XLEN.W)) val wdata = Output(UInt(XLEN.W))
val cpu_ready = Output(Bool()) val cpu_ready = Output(Bool())
val fence_i = Output(Bool()) val fence = Output(Bool())
val wstrb = Output(UInt(AXI_STRB_WID.W)) val wstrb = Output(UInt(AXI_STRB_WID.W))
val rdata = Input(UInt(XLEN.W)) val rdata = Input(UInt(XLEN.W))

View File

@ -8,13 +8,17 @@ import cpu.defines.Const._
class BranchCtrl extends Module { class BranchCtrl extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val in = new Bundle { val in = new Bundle {
val info = Input(new InstInfo()) val pc = Input(UInt(PC_WID.W))
val src_info = Input(new SrcInfo()) val info = Input(new InstInfo())
val pred_branch = Input(Bool()) val src_info = Input(new SrcInfo())
val pred_branch = Input(Bool())
val jump_regiser = Input(Bool())
val branch_target = Input(UInt(PC_WID.W))
} }
val out = new Bundle { val out = new Bundle {
val branch = Output(Bool()) val branch = Output(Bool())
val pred_fail = Output(Bool()) val pred_fail = Output(Bool())
val target = Output(UInt(PC_WID.W))
} }
}) })
val valid = val valid =
@ -35,4 +39,12 @@ class BranchCtrl extends Module {
io.out.pred_fail := io.in.pred_branch =/= io.out.branch io.out.pred_fail := io.in.pred_branch =/= io.out.branch
io.out.branch := (LookupTree(ALUOpType.getBranchType(op), table) ^ io.out.branch := (LookupTree(ALUOpType.getBranchType(op), table) ^
ALUOpType.isBranchInvert(op)) & valid ALUOpType.isBranchInvert(op)) & valid
io.out.target := MuxCase(
io.in.pc + 4.U, // 默认顺序运行吧
Seq(
(io.out.pred_fail && io.out.branch) -> io.in.branch_target,
(io.out.pred_fail && !io.out.branch) -> (io.in.pc + 4.U),
(io.in.jump_regiser) -> ((src1 + src2) & ~1.U(XLEN.W))
)
)
} }

View File

@ -7,11 +7,11 @@ import cpu.defines.Const._
import cpu.{BranchPredictorConfig, CpuConfig} import cpu.{BranchPredictorConfig, CpuConfig}
class IdExeInst0 extends Bundle { class IdExeInst0 extends Bundle {
val config = new BranchPredictorConfig() val config = new BranchPredictorConfig()
val pc = UInt(PC_WID.W) val pc = UInt(PC_WID.W)
val info = new InstInfo() val info = new InstInfo()
val src_info = new SrcInfo() val src_info = new SrcInfo()
val ex = new ExceptionInfo() val ex = new ExceptionInfo()
val jb_info = new Bundle { val jb_info = new Bundle {
// jump ctrl // jump ctrl
val jump_regiser = Bool() val jump_regiser = Bool()
@ -26,7 +26,7 @@ class IdExeInst0 extends Bundle {
class IdExeInst1 extends Bundle { class IdExeInst1 extends Bundle {
val allow_to_go = Bool() val allow_to_go = Bool()
val pc = UInt(PC_WID.W) val pc = UInt(PC_WID.W)
val info = new InstInfo() val info = new InstInfo()
val src_info = new SrcInfo() val src_info = new SrcInfo()
val ex = new ExceptionInfo() val ex = new ExceptionInfo()
} }

View File

@ -41,68 +41,75 @@ class ExecuteUnit(implicit val config: CpuConfig) extends Module {
io.executeStage.inst1.info.valid && io.ctrl.allow_to_go io.executeStage.inst1.info.valid && io.ctrl.allow_to_go
) )
val fusel = VecInit(
io.executeStage.inst0.info.fusel,
io.executeStage.inst1.info.fusel
)
val is_csr = VecInit(
fusel(0) === FuType.csr && valid(0) &&
!(io.executeStage.inst0.ex.exception.asUInt.orR || io.executeStage.inst0.ex.interrupt.asUInt.orR),
fusel(1) === FuType.csr && valid(1) &&
!(io.executeStage.inst1.ex.exception.asUInt.orR || io.executeStage.inst1.ex.interrupt.asUInt.orR)
)
io.ctrl.inst(0).mem_wreg := io.executeStage.inst0.info.mem_wreg io.ctrl.inst(0).mem_wreg := io.executeStage.inst0.info.mem_wreg
io.ctrl.inst(0).reg_waddr := io.executeStage.inst0.info.reg_waddr io.ctrl.inst(0).reg_waddr := io.executeStage.inst0.info.reg_waddr
io.ctrl.inst(1).mem_wreg := io.executeStage.inst1.info.mem_wreg io.ctrl.inst(1).mem_wreg := io.executeStage.inst1.info.mem_wreg
io.ctrl.inst(1).reg_waddr := io.executeStage.inst1.info.reg_waddr io.ctrl.inst(1).reg_waddr := io.executeStage.inst1.info.reg_waddr
io.ctrl.branch := valid(0) && io.ctrl.allow_to_go && io.ctrl.branch := valid(0) && io.ctrl.allow_to_go &&
(io.executeStage.inst0.jb_info.jump_regiser || fu.branch.pred_fail) (fu.branch.jump_regiser || fu.branch.pred_fail)
val csr_sel0 = valid(0) && io.executeStage.inst0.info.fusel === FuType.csr && io.csr.in.valid := is_csr.asUInt.orR
!(io.executeStage.inst0.ex.exception.asUInt.orR || io.executeStage.inst0.ex.interrupt.asUInt.orR)
val csr_sel1 = valid(1) && io.executeStage.inst1.info.fusel === FuType.csr &&
!(io.executeStage.inst1.ex.exception.asUInt.orR || io.executeStage.inst1.ex.interrupt.asUInt.orR)
io.csr.in.valid := (csr_sel0 || csr_sel1)
io.csr.in.info := MuxCase( io.csr.in.info := MuxCase(
0.U.asTypeOf(new InstInfo()), 0.U.asTypeOf(new InstInfo()),
Seq( Seq(
csr_sel0 -> io.executeStage.inst0.info, is_csr(0) -> io.executeStage.inst0.info,
csr_sel1 -> io.executeStage.inst1.info is_csr(1) -> io.executeStage.inst1.info
) )
) )
io.csr.in.src_info := MuxCase( io.csr.in.src_info := MuxCase(
0.U.asTypeOf(new SrcInfo()), 0.U.asTypeOf(new SrcInfo()),
Seq( Seq(
csr_sel0 -> io.executeStage.inst0.src_info, is_csr(0) -> io.executeStage.inst0.src_info,
csr_sel1 -> io.executeStage.inst1.src_info is_csr(1) -> io.executeStage.inst1.src_info
) )
) )
io.csr.in.ex := MuxCase( io.csr.in.ex := MuxCase(
0.U.asTypeOf(new ExceptionInfo()), 0.U.asTypeOf(new ExceptionInfo()),
Seq( Seq(
csr_sel0 -> io.executeStage.inst0.ex, is_csr(0) -> io.executeStage.inst0.ex,
csr_sel1 -> io.executeStage.inst1.ex is_csr(1) -> io.executeStage.inst1.ex
) )
) )
val is_lsu = VecInit(
fusel(0) === FuType.lsu && valid(0) &&
!(io.executeStage.inst0.ex.exception.asUInt.orR || io.executeStage.inst0.ex.interrupt.asUInt.orR),
fusel(1) === FuType.lsu && valid(1) &&
!(io.executeStage.inst1.ex.exception.asUInt.orR || io.executeStage.inst1.ex.interrupt.asUInt.orR)
)
// input accessMemCtrl // input accessMemCtrl
accessMemCtrl.inst(0).info := io.executeStage.inst0.info accessMemCtrl.inst(0).info := Mux(is_lsu(0), io.executeStage.inst0.info, 0.U.asTypeOf(new InstInfo()))
accessMemCtrl.inst(0).src_info := io.executeStage.inst0.src_info accessMemCtrl.inst(0).src_info := Mux(is_lsu(0), io.executeStage.inst0.src_info, 0.U.asTypeOf(new SrcInfo()))
accessMemCtrl.inst(0).ex.in := io.executeStage.inst0.ex accessMemCtrl.inst(0).ex.in := Mux(is_lsu(0), io.executeStage.inst0.ex, 0.U.asTypeOf(new ExceptionInfo()))
accessMemCtrl.inst(1).info := io.executeStage.inst1.info accessMemCtrl.inst(1).info := Mux(is_lsu(1), io.executeStage.inst1.info, 0.U.asTypeOf(new InstInfo()))
accessMemCtrl.inst(1).src_info := io.executeStage.inst1.src_info accessMemCtrl.inst(1).src_info := Mux(is_lsu(1), io.executeStage.inst1.src_info, 0.U.asTypeOf(new SrcInfo()))
accessMemCtrl.inst(1).ex.in := io.executeStage.inst1.ex accessMemCtrl.inst(1).ex.in := Mux(is_lsu(1), io.executeStage.inst1.ex, 0.U.asTypeOf(new ExceptionInfo()))
// input fu // input fu
fu.ctrl <> io.ctrl.fu fu.ctrl <> io.ctrl.fu
fu.inst(0).pc := io.executeStage.inst0.pc fu.inst(0).pc := io.executeStage.inst0.pc
fu.inst(0).mul_en := io.executeStage.inst0.info.fusel === FuType.mdu && fu.inst(0).info := io.executeStage.inst0.info
!MDUOpType.isDiv(io.executeStage.inst0.info.op) fu.inst(0).src_info := io.executeStage.inst0.src_info
fu.inst(0).div_en := io.executeStage.inst0.info.fusel === FuType.mdu && fu.inst(0).ex.in := io.executeStage.inst0.ex
MDUOpType.isDiv(io.executeStage.inst0.info.op) fu.inst(1).pc := io.executeStage.inst1.pc
fu.inst(0).info := io.executeStage.inst0.info fu.inst(1).info := io.executeStage.inst1.info
fu.inst(0).src_info := io.executeStage.inst0.src_info fu.inst(1).src_info := io.executeStage.inst1.src_info
fu.inst(0).ex.in := fu.inst(1).ex.in := io.executeStage.inst1.ex
Mux(io.executeStage.inst0.info.fusel === FuType.lsu, accessMemCtrl.inst(0).ex.out, io.executeStage.inst0.ex) fu.branch.pred_branch := io.executeStage.inst0.jb_info.pred_branch
fu.inst(1).pc := io.executeStage.inst1.pc fu.branch.jump_regiser := io.executeStage.inst0.jb_info.jump_regiser
fu.inst(1).mul_en := io.executeStage.inst1.info.fusel === FuType.mdu && fu.branch.branch_target := io.executeStage.inst0.jb_info.branch_target
!MDUOpType.isDiv(io.executeStage.inst1.info.op)
fu.inst(1).div_en := io.executeStage.inst1.info.fusel === FuType.mdu &&
MDUOpType.isDiv(io.executeStage.inst1.info.op)
fu.inst(1).info := io.executeStage.inst1.info
fu.inst(1).src_info := io.executeStage.inst1.src_info
fu.inst(1).ex.in := io.executeStage.inst1.ex
fu.branch.pred_branch := io.executeStage.inst0.jb_info.pred_branch
io.bpu.pc := io.executeStage.inst0.pc io.bpu.pc := io.executeStage.inst0.pc
io.bpu.update_pht_index := io.executeStage.inst0.jb_info.update_pht_index io.bpu.update_pht_index := io.executeStage.inst0.jb_info.update_pht_index
@ -110,15 +117,7 @@ class ExecuteUnit(implicit val config: CpuConfig) extends Module {
io.bpu.branch_inst := io.executeStage.inst0.jb_info.branch_inst io.bpu.branch_inst := io.executeStage.inst0.jb_info.branch_inst
io.fetchUnit.branch := io.ctrl.branch io.fetchUnit.branch := io.ctrl.branch
io.fetchUnit.target := MuxCase( io.fetchUnit.target := fu.branch.target
io.executeStage.inst0.pc + 4.U, // 默认顺序运行吧
Seq(
(fu.branch.pred_fail && fu.branch.branch) -> io.executeStage.inst0.jb_info.branch_target,
(fu.branch.pred_fail && !fu.branch.branch) -> (io.executeStage.inst0.pc + 4.U),
(io.executeStage.inst0.jb_info.jump_regiser) -> ((io.executeStage.inst0.src_info.src1_data + io.executeStage.inst0.src_info.src2_data) & ~1
.U(XLEN.W))
)
)
io.ctrl.fu_stall := fu.stall_req io.ctrl.fu_stall := fu.stall_req

View File

@ -12,11 +12,9 @@ class Fu(implicit val config: CpuConfig) extends Module {
val inst = Vec( val inst = Vec(
config.decoderNum, config.decoderNum,
new Bundle { new Bundle {
val pc = Input(UInt(PC_WID.W)) val pc = Input(UInt(PC_WID.W))
val mul_en = Input(Bool()) val info = Input(new InstInfo())
val div_en = Input(Bool()) val src_info = Input(new SrcInfo())
val info = Input(new InstInfo())
val src_info = Input(new SrcInfo())
val ex = new Bundle { val ex = new Bundle {
val in = Input(new ExceptionInfo()) val in = Input(new ExceptionInfo())
val out = Output(new ExceptionInfo()) val out = Output(new ExceptionInfo())
@ -29,48 +27,35 @@ class Fu(implicit val config: CpuConfig) extends Module {
) )
val stall_req = Output(Bool()) val stall_req = Output(Bool())
val branch = new Bundle { val branch = new Bundle {
val pred_branch = Input(Bool()) val pred_branch = Input(Bool())
val branch = Output(Bool()) val jump_regiser = Input(Bool())
val pred_fail = Output(Bool()) val branch_target = Input(UInt(PC_WID.W))
val branch = Output(Bool())
val pred_fail = Output(Bool())
val target = Output(UInt(PC_WID.W))
} }
}) })
val alu = Seq.fill(config.decoderNum)(Module(new Alu())) val alu = Seq.fill(config.decoderNum)(Module(new Alu()))
// val mul = Module(new Mul()).io
// val div = Module(new Div()).io
val branchCtrl = Module(new BranchCtrl()).io val branchCtrl = Module(new BranchCtrl()).io
branchCtrl.in.info := io.inst(0).info branchCtrl.in.pc := io.inst(0).pc
branchCtrl.in.src_info := io.inst(0).src_info branchCtrl.in.info := io.inst(0).info
branchCtrl.in.pred_branch := io.branch.pred_branch branchCtrl.in.src_info := io.inst(0).src_info
io.branch.branch := branchCtrl.out.branch branchCtrl.in.pred_branch := io.branch.pred_branch
io.branch.pred_fail := branchCtrl.out.pred_fail branchCtrl.in.jump_regiser := io.branch.jump_regiser
branchCtrl.in.branch_target := io.branch.branch_target
io.branch.branch := branchCtrl.out.branch
io.branch.pred_fail := branchCtrl.out.pred_fail
io.branch.target := branchCtrl.out.target
for (i <- 0 until (config.fuNum)) { for (i <- 0 until (config.fuNum)) {
alu(i).io.info := io.inst(i).info alu(i).io.info := io.inst(i).info
alu(i).io.src_info := io.inst(i).src_info alu(i).io.src_info := io.inst(i).src_info
// alu(i).io.mul.result := mul.result io.inst(i).ex.out := io.inst(i).ex.in
// alu(i).io.mul.ready := mul.ready
// alu(i).io.div.ready := div.ready
// alu(i).io.div.result := div.result
io.inst(i).ex.out := io.inst(i).ex.in
io.inst(i).ex.out.exception := io.inst(i).ex.in.exception io.inst(i).ex.out.exception := io.inst(i).ex.in.exception
} }
// mul.src1 := Mux(io.inst(0).mul_en, io.inst(0).src_info.src1_data, io.inst(1).src_info.src1_data)
// mul.src2 := Mux(io.inst(0).mul_en, io.inst(0).src_info.src2_data, io.inst(1).src_info.src2_data)
// mul.signed := Mux(io.inst(0).mul_en, alu(0).io.mul.signed, alu(1).io.mul.signed)
// mul.start := Mux(io.inst(0).mul_en, alu(0).io.mul.en, alu(1).io.mul.en)
// mul.allow_to_go := io.ctrl.allow_to_go
// div.src1 := Mux(io.inst(0).div_en, io.inst(0).src_info.src1_data, io.inst(1).src_info.src1_data)
// div.src2 := Mux(io.inst(0).div_en, io.inst(0).src_info.src2_data, io.inst(1).src_info.src2_data)
// div.signed := Mux(io.inst(0).div_en, alu(0).io.div.signed, alu(1).io.div.signed)
// div.start := Mux(io.inst(0).div_en, alu(0).io.div.en, alu(1).io.div.en)
// div.allow_to_go := io.ctrl.allow_to_go
// io.stall_req := (io.inst.map(_.div_en).reduce(_ || _) && !div.ready) ||
// (io.inst.map(_.mul_en).reduce(_ || _) && !mul.ready)
io.stall_req := false.B io.stall_req := false.B
io.inst(0).result.alu := Mux( io.inst(0).result.alu := Mux(