重构exe unit
This commit is contained in:
parent
b13ff2377c
commit
413a7e22d2
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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的目的操作数
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue