重构exe unit

This commit is contained in:
Liphen 2024-01-22 15:40:38 +08:00
parent b13ff2377c
commit 413a7e22d2
8 changed files with 45 additions and 88 deletions

View File

@ -80,9 +80,9 @@ class Core(implicit val cpuConfig: CpuConfig) extends Module {
decodeUnit.instFifo.info.almost_empty := instFifo.almost_empty
decodeUnit.regfile <> regfile.read
for (i <- 0 until (cpuConfig.commitNum)) {
decodeUnit.forward(i).exe := executeUnit.decodeUnit.forward(i).exe
decodeUnit.forward(i).mem_wreg := executeUnit.decodeUnit.forward(i).exe_mem_wreg
decodeUnit.forward(i).mem := memoryUnit.decodeUnit(i)
decodeUnit.forward(i).exe := executeUnit.decodeUnit.forward(i).exe
decodeUnit.forward(i).is_load := executeUnit.decodeUnit.forward(i).is_load // exe级是load指令
decodeUnit.forward(i).mem := memoryUnit.decodeUnit(i)
}
decodeUnit.csr <> csr.decodeUnit
decodeUnit.executeStage <> executeStage.decodeUnit

View File

@ -16,16 +16,16 @@ class Ctrl(implicit val cpuConfig: CpuConfig) extends Module {
val writeBackUnit = Flipped(new WriteBackCtrl())
})
val inst0_lw_stall = (io.executeUnit.inst(0).mem_wreg) && io.executeUnit.inst(0).reg_waddr.orR &&
val inst0_lw_stall = (io.executeUnit.inst(0).is_load) && io.executeUnit.inst(0).reg_waddr.orR &&
(io.decodeUnit.inst0.src1.ren && io.decodeUnit.inst0.src1.raddr === io.executeUnit.inst(0).reg_waddr ||
io.decodeUnit.inst0.src2.ren && io.decodeUnit.inst0.src2.raddr === io.executeUnit.inst(0).reg_waddr)
val inst1_lw_stall = (io.executeUnit.inst(1).mem_wreg) && io.executeUnit.inst(1).reg_waddr.orR &&
val inst1_lw_stall = (io.executeUnit.inst(1).is_load) && io.executeUnit.inst(1).reg_waddr.orR &&
(io.decodeUnit.inst0.src1.ren && io.decodeUnit.inst0.src1.raddr === io.executeUnit.inst(1).reg_waddr ||
io.decodeUnit.inst0.src2.ren && io.decodeUnit.inst0.src2.raddr === io.executeUnit.inst(1).reg_waddr)
val lw_stall = inst0_lw_stall || inst1_lw_stall
// TODO: 这里的stall信号可以改进尝试让前后端完全解耦
val longest_stall =
io.executeUnit.fu_stall || io.cacheCtrl.iCache_stall || io.memoryUnit.mem_stall
io.executeUnit.fu.stall || io.cacheCtrl.iCache_stall || io.memoryUnit.mem_stall
io.fetchUnit.allow_to_go := !io.cacheCtrl.iCache_stall
io.decodeUnit.allow_to_go := !(lw_stall || longest_stall)

View File

@ -46,7 +46,7 @@ class InstInfo extends Bundle {
}
class MemRead extends Bundle {
val mem_wreg = Bool()
val is_load = Bool()
val reg_waddr = UInt(REG_ADDR_WID.W)
}
@ -77,12 +77,12 @@ class DecodeUnitCtrl extends Bundle {
class ExecuteFuCtrl extends Bundle {
val allow_to_go = Input(Bool())
val stall = Output(Bool())
}
class ExecuteCtrl(implicit val cpuConfig: CpuConfig) extends Bundle {
val inst = Output(Vec(cpuConfig.commitNum, new MemRead()))
val fu_stall = Output(Bool())
val flush = Output(Bool())
val inst = Output(Vec(cpuConfig.commitNum, new MemRead()))
val flush = Output(Bool())
val allow_to_go = Input(Bool())
val do_flush = Input(Bool())

View File

@ -21,7 +21,7 @@ class DecodeUnitInstFifo(implicit val cpuConfig: CpuConfig) extends Bundle {
class DataForwardToDecodeUnit extends Bundle {
val exe = new RegWrite()
val mem_wreg = Bool()
val is_load = Bool()
val mem = new RegWrite()
}
@ -74,7 +74,7 @@ class DecodeUnit(implicit val cpuConfig: CpuConfig) extends Module with HasExcep
for (i <- 0 until (cpuConfig.decoderNum)) {
decoder(i).io.in.inst := inst(i)
issue.decodeInst(i) := info(i)
issue.execute(i).mem_wreg := io.forward(i).mem_wreg
issue.execute(i).is_load := io.forward(i).is_load
issue.execute(i).reg_waddr := io.forward(i).exe.waddr
io.regfile(i).src1.raddr := info(i).src1_raddr
io.regfile(i).src2.raddr := info(i).src2_raddr

View File

@ -48,13 +48,13 @@ class ForwardCtrl(implicit val cpuConfig: CpuConfig) extends Module {
for (i <- 0 until (cpuConfig.decoderNum)) {
for (j <- 0 until (cpuConfig.commitNum)) {
when(
io.in.forward(j).exe.wen && !io.in.forward(j).mem_wreg &&
io.in.forward(j).exe.wen && !io.in.forward(j).is_load &&
io.in.forward(j).exe.waddr === io.in.regfile(i).src1.raddr
) {
io.out.inst(i).src1.rdata := io.in.forward(j).exe.wdata
}
when(
io.in.forward(j).exe.wen && !io.in.forward(j).mem_wreg &&
io.in.forward(j).exe.wen && !io.in.forward(j).is_load &&
io.in.forward(j).exe.waddr === io.in.regfile(i).src2.raddr
) {
io.out.inst(i).src2.rdata := io.in.forward(j).exe.wdata

View File

@ -38,10 +38,10 @@ class Issue(implicit val cpuConfig: CpuConfig) extends Module with HasCSRConst {
// 写后读冲突
val load_stall =
io.execute(0).mem_wreg && io.execute(0).reg_waddr.orR &&
io.execute(0).is_load && io.execute(0).reg_waddr.orR &&
(inst1.src1_ren && inst1.src1_raddr === io.execute(0).reg_waddr ||
inst1.src2_ren && inst1.src2_raddr === io.execute(0).reg_waddr) ||
io.execute(1).mem_wreg && io.execute(1).reg_waddr.orR &&
io.execute(1).is_load && io.execute(1).reg_waddr.orR &&
(inst1.src1_ren && inst1.src1_raddr === io.execute(1).reg_waddr ||
inst1.src2_ren && inst1.src2_raddr === io.execute(1).reg_waddr)
val raw_reg = // inst1的源操作数是inst0的目的操作数

View File

@ -24,8 +24,8 @@ class ExecuteUnit(implicit val cpuConfig: CpuConfig) extends Module {
Vec(
cpuConfig.commitNum,
new Bundle {
val exe = new RegWrite()
val exe_mem_wreg = Bool()
val exe = new RegWrite()
val is_load = Bool()
}
)
)
@ -36,74 +36,35 @@ class ExecuteUnit(implicit val cpuConfig: CpuConfig) extends Module {
}
})
val fu = Module(new Fu()).io
val valid = io.executeStage.inst.map(_.info.valid && io.ctrl.allow_to_go)
val fusel = io.executeStage.inst.map(_.info.fusel)
val valid = VecInit(
io.executeStage.inst(0).info.valid && io.ctrl.allow_to_go,
io.executeStage.inst(1).info.valid && io.ctrl.allow_to_go
)
val fusel = VecInit(
io.executeStage.inst(0).info.fusel,
io.executeStage.inst(1).info.fusel
)
io.ctrl.flush := io.fetchUnit.flush
for (i <- 0 until (cpuConfig.commitNum)) {
io.ctrl.inst(i).is_load :=
io.executeStage.inst(i).info.fusel === FuType.lsu && io.executeStage.inst(i).info.reg_wen
io.ctrl.inst(i).reg_waddr := io.executeStage.inst(i).info.reg_waddr
}
val is_csr = VecInit(
fusel(0) === FuType.csr && valid(0) &&
!(HasExcInt(io.executeStage.inst(0).ex)),
fusel(1) === FuType.csr && valid(1) &&
!(HasExcInt(io.executeStage.inst(1).ex))
Seq.tabulate(cpuConfig.commitNum)(i =>
fusel(i) === FuType.csr && valid(i) && !(HasExcInt(io.executeStage.inst(i).ex))
)
)
val mem_wreg = VecInit(
io.executeStage.inst(0).info.fusel === FuType.lsu && io.executeStage.inst(0).info.reg_wen,
io.executeStage.inst(1).info.fusel === FuType.lsu && io.executeStage.inst(1).info.reg_wen
)
io.ctrl.inst(0).mem_wreg := mem_wreg(0)
io.ctrl.inst(0).reg_waddr := io.executeStage.inst(0).info.reg_waddr
io.ctrl.inst(1).mem_wreg := mem_wreg(1)
io.ctrl.inst(1).reg_waddr := io.executeStage.inst(1).info.reg_waddr
io.ctrl.flush := io.fetchUnit.flush
io.csr.in.valid := is_csr.asUInt.orR
io.csr.in.pc := MuxCase(
0.U,
Seq(
is_csr(0) -> io.executeStage.inst(0).pc,
is_csr(1) -> io.executeStage.inst(1).pc
)
)
io.csr.in.info := MuxCase(
0.U.asTypeOf(new InstInfo()),
Seq(
is_csr(0) -> io.executeStage.inst(0).info,
is_csr(1) -> io.executeStage.inst(1).info
)
)
io.csr.in.src_info := MuxCase(
0.U.asTypeOf(new SrcInfo()),
Seq(
is_csr(0) -> io.executeStage.inst(0).src_info,
is_csr(1) -> io.executeStage.inst(1).src_info
)
)
io.csr.in.ex := MuxCase(
0.U.asTypeOf(new ExceptionInfo()),
Seq(
is_csr(0) -> io.executeStage.inst(0).ex,
is_csr(1) -> io.executeStage.inst(1).ex
)
)
val is_lsu = VecInit(
fusel(0) === FuType.lsu && valid(0) &&
!(HasExcInt(io.executeStage.inst(0).ex)),
fusel(1) === FuType.lsu && valid(1) &&
!(HasExcInt(io.executeStage.inst(1).ex))
)
def selectInstField[T <: Data](select: Vec[Bool], fields: Seq[T]): T = {
require(select.length == fields.length)
Mux1H(select.zip(fields))
}
// input fu
io.csr.in.pc := selectInstField(is_csr, io.executeStage.inst.map(_.pc))
io.csr.in.info := selectInstField(is_csr, io.executeStage.inst.map(_.info))
io.csr.in.src_info := selectInstField(is_csr, io.executeStage.inst.map(_.src_info))
io.csr.in.ex := selectInstField(is_csr, io.executeStage.inst.map(_.ex))
val fu = Module(new Fu()).io
fu.ctrl <> io.ctrl.fu
for (i <- 0 until (cpuConfig.commitNum)) {
fu.inst(i).pc := io.executeStage.inst(i).pc
@ -121,12 +82,9 @@ class ExecuteUnit(implicit val cpuConfig: CpuConfig) extends Module {
io.bpu.branch := fu.branch.branch
io.bpu.branch_inst := io.executeStage.jump_branch_info.branch_inst
io.fetchUnit.flush := valid(0) && io.ctrl.allow_to_go &&
(fu.branch.flush || io.csr.out.flush)
io.fetchUnit.flush := valid(0) && io.ctrl.allow_to_go && (fu.branch.flush || io.csr.out.flush)
io.fetchUnit.target := Mux(io.csr.out.flush, io.csr.out.target, fu.branch.target)
io.ctrl.fu_stall := fu.stall_req
for (i <- 0 until (cpuConfig.commitNum)) {
io.memoryStage.inst(i).pc := io.executeStage.inst(i).pc
io.memoryStage.inst(i).info := io.executeStage.inst(i).info
@ -154,9 +112,9 @@ class ExecuteUnit(implicit val cpuConfig: CpuConfig) extends Module {
io.fetchUnit.target
)
io.decodeUnit.forward(i).exe.wen := io.memoryStage.inst(i).info.reg_wen
io.decodeUnit.forward(i).exe.waddr := io.memoryStage.inst(i).info.reg_waddr
io.decodeUnit.forward(i).exe.wdata := io.memoryStage.inst(i).rd_info.wdata(io.memoryStage.inst(i).info.fusel)
io.decodeUnit.forward(i).exe_mem_wreg := io.ctrl.inst(i).mem_wreg
io.decodeUnit.forward(i).exe.wen := io.memoryStage.inst(i).info.reg_wen
io.decodeUnit.forward(i).exe.waddr := io.memoryStage.inst(i).info.reg_waddr
io.decodeUnit.forward(i).exe.wdata := io.memoryStage.inst(i).rd_info.wdata(io.memoryStage.inst(i).info.fusel)
io.decodeUnit.forward(i).is_load := io.ctrl.inst(i).is_load
}
}

View File

@ -21,7 +21,6 @@ class Fu(implicit val cpuConfig: CpuConfig) extends Module {
})
}
)
val stall_req = Output(Bool())
val dataMemory = new Bundle {
val addr = Output(UInt(XLEN.W))
}
@ -71,7 +70,7 @@ class Fu(implicit val cpuConfig: CpuConfig) extends Module {
)
mdu.allow_to_go := io.ctrl.allow_to_go
io.stall_req := io.inst.map(_.info.fusel === FuType.mdu).reduce(_ || _) && !mdu.ready
io.ctrl.stall := io.inst.map(_.info.fusel === FuType.mdu).reduce(_ || _) && !mdu.ready
io.inst(0).result.alu := alu(0).io.result
io.inst(0).result.mdu := mdu.result