修改id级逻辑
This commit is contained in:
parent
2c7af2ce4b
commit
7e13a02cb4
|
@ -24,43 +24,35 @@ class RegWrite extends Bundle {
|
|||
|
||||
class ARegFile(implicit val cpuConfig: CpuConfig) extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val read = Flipped(Vec(cpuConfig.decoderNum, new Src12Read()))
|
||||
val write = Flipped(Vec(cpuConfig.commitNum, new RegWrite()))
|
||||
val read = Flipped(new Src12Read())
|
||||
val write = Flipped(new RegWrite())
|
||||
})
|
||||
|
||||
// 定义32个32位寄存器
|
||||
val regs = RegInit(VecInit(Seq.fill(AREG_NUM)(0.U(XLEN.W))))
|
||||
|
||||
// 写寄存器堆
|
||||
for (i <- 0 until (cpuConfig.commitNum)) {
|
||||
when(io.write(i).wen && io.write(i).waddr =/= 0.U) {
|
||||
regs(io.write(i).waddr) := io.write(i).wdata
|
||||
}
|
||||
when(io.write.wen && io.write.waddr =/= 0.U) {
|
||||
regs(io.write.waddr) := io.write.wdata
|
||||
}
|
||||
|
||||
// 读寄存器堆
|
||||
for (i <- 0 until (cpuConfig.decoderNum)) {
|
||||
// src1
|
||||
when(io.read(i).src1.raddr === 0.U) {
|
||||
io.read(i).src1.rdata := 0.U
|
||||
}.otherwise {
|
||||
io.read(i).src1.rdata := regs(io.read(i).src1.raddr)
|
||||
for (j <- 0 until (cpuConfig.commitNum)) {
|
||||
when(io.write(j).wen && io.read(i).src1.raddr === io.write(j).waddr) {
|
||||
io.read(i).src1.rdata := io.write(j).wdata
|
||||
}
|
||||
}
|
||||
// src1
|
||||
when(io.read.src1.raddr === 0.U) {
|
||||
io.read.src1.rdata := 0.U
|
||||
}.otherwise {
|
||||
io.read.src1.rdata := regs(io.read.src1.raddr)
|
||||
when(io.write.wen && io.read.src1.raddr === io.write.waddr) {
|
||||
io.read.src1.rdata := io.write.wdata
|
||||
}
|
||||
// src2
|
||||
when(io.read(i).src2.raddr === 0.U) {
|
||||
io.read(i).src2.rdata := 0.U
|
||||
}.otherwise {
|
||||
io.read(i).src2.rdata := regs(io.read(i).src2.raddr)
|
||||
for (j <- 0 until (cpuConfig.commitNum)) {
|
||||
when(io.write(j).wen && io.read(i).src2.raddr === io.write(j).waddr) {
|
||||
io.read(i).src2.rdata := io.write(j).wdata
|
||||
}
|
||||
}
|
||||
}
|
||||
// src2
|
||||
when(io.read.src2.raddr === 0.U) {
|
||||
io.read.src2.rdata := 0.U
|
||||
}.otherwise {
|
||||
io.read.src2.rdata := regs(io.read.src2.raddr)
|
||||
when(io.write.wen && io.read.src2.raddr === io.write.waddr) {
|
||||
io.read.src2.rdata := io.write.wdata
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package cpu.pipeline.decode
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
|
||||
class IfIdData extends Bundle {
|
||||
val inst = UInt(XLEN.W)
|
||||
val valid = Bool()
|
||||
val pc = UInt(XLEN.W)
|
||||
val addr_misaligned = Bool()
|
||||
}
|
||||
|
||||
class FetchUnitDecodeUnit extends IfIdData {
|
||||
val data = Output(new IfIdData())
|
||||
}
|
||||
|
||||
class DecodeStage(implicit val cpuConfig: CpuConfig) extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val ctrl = Input(new Bundle {
|
||||
val allow_to_go = Bool()
|
||||
val clear = Bool()
|
||||
})
|
||||
val fetchUnit = Flipped(new FetchUnitDecodeUnit())
|
||||
val decodeUnit = new FetchUnitDecodeUnit()
|
||||
})
|
||||
val data = RegInit(0.U.asTypeOf(new IfIdData()))
|
||||
|
||||
when(io.ctrl.clear) {
|
||||
data := 0.U.asTypeOf(new IfIdData())
|
||||
}.elsewhen(io.ctrl.allow_to_go) {
|
||||
data := io.fetchUnit
|
||||
}
|
||||
|
||||
io.decodeUnit.data := data
|
||||
}
|
|
@ -5,148 +5,60 @@ import chisel3.util._
|
|||
import chisel3.util.experimental.BoringUtils
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.{BranchPredictorConfig, CpuConfig}
|
||||
import cpu.pipeline.execute.DecodeUnitExecuteUnit
|
||||
import cpu.pipeline.fetch.IfIdData
|
||||
import cpu.pipeline.execute
|
||||
|
||||
class DecodeUnitInstFifo(implicit val cpuConfig: CpuConfig) extends Bundle {
|
||||
val allow_to_go = Output(Vec(cpuConfig.decoderNum, Bool()))
|
||||
val inst = Input(Vec(cpuConfig.decoderNum, new IfIdData()))
|
||||
val info = Input(new Bundle {
|
||||
val empty = Bool()
|
||||
val almost_empty = Bool()
|
||||
})
|
||||
}
|
||||
|
||||
class DataForwardToDecodeUnit extends Bundle {
|
||||
val exe = new RegWrite()
|
||||
val is_load = Bool()
|
||||
val mem = new RegWrite()
|
||||
}
|
||||
|
||||
class DecoderBranchPredictorUnit extends Bundle {
|
||||
val bpuConfig = new BranchPredictorConfig()
|
||||
val pc = Output(UInt(XLEN.W))
|
||||
val info = Output(new Info())
|
||||
val pht_index = Output(UInt(bpuConfig.phtDepth.W))
|
||||
|
||||
val branch_inst = Input(Bool())
|
||||
val branch = Input(Bool())
|
||||
val target = Input(UInt(XLEN.W))
|
||||
val update_pht_index = Input(UInt(bpuConfig.phtDepth.W))
|
||||
}
|
||||
|
||||
class DecodeUnit(implicit val cpuConfig: CpuConfig) extends Module with HasExceptionNO with HasCSRConst {
|
||||
class DecodeUnit extends Module with HasExceptionNO with HasCSRConst {
|
||||
val io = IO(new Bundle {
|
||||
// 输入
|
||||
val instFifo = new DecodeUnitInstFifo()
|
||||
val regfile = Vec(cpuConfig.decoderNum, new Src12Read())
|
||||
val forward = Input(Vec(cpuConfig.commitNum, new DataForwardToDecodeUnit()))
|
||||
val csr = Input(new execute.CsrDecodeUnit())
|
||||
val decodeStage = Flipped(new FetchUnitDecodeUnit())
|
||||
val regfile = new Src12Read()
|
||||
val forward = Input(new DataForwardToDecodeUnit())
|
||||
// 输出
|
||||
val fetchUnit = new Bundle {
|
||||
val branch = Output(Bool())
|
||||
val target = Output(UInt(XLEN.W))
|
||||
}
|
||||
val bpu = new DecoderBranchPredictorUnit()
|
||||
val executeStage = Output(new DecodeUnitExecuteUnit())
|
||||
val ctrl = new DecodeUnitCtrl()
|
||||
})
|
||||
|
||||
val decoder = Seq.fill(cpuConfig.decoderNum)(Module(new Decoder()))
|
||||
val jumpCtrl = Module(new JumpCtrl()).io
|
||||
val decoder = Module(new Decoder())
|
||||
val forwardCtrl = Module(new ForwardCtrl()).io
|
||||
val issue = Module(new Issue()).io
|
||||
|
||||
val pc = io.instFifo.inst.map(_.pc)
|
||||
val inst = io.instFifo.inst.map(_.inst)
|
||||
val info = Wire(Vec(cpuConfig.decoderNum, new Info()))
|
||||
val mode = io.csr.mode
|
||||
val pc = io.decodeStage.data.pc
|
||||
val info = Wire(new Info())
|
||||
|
||||
info := decoder.map(_.io.out.info)
|
||||
info(0).valid := !io.instFifo.info.empty
|
||||
info(1).valid := !io.instFifo.info.almost_empty && !io.instFifo.info.empty
|
||||
|
||||
issue.allow_to_go := io.ctrl.allow_to_go
|
||||
issue.instFifo := io.instFifo.info
|
||||
io.instFifo.allow_to_go(1) := issue.inst1.allow_to_go
|
||||
for (i <- 0 until (cpuConfig.decoderNum)) {
|
||||
decoder(i).io.in.inst := inst(i)
|
||||
issue.decodeInst(i) := info(i)
|
||||
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
|
||||
}
|
||||
info := decoder.io.out.info
|
||||
info.valid := io.decodeStage.data.valid
|
||||
|
||||
forwardCtrl.in.forward := io.forward
|
||||
forwardCtrl.in.regfile := io.regfile
|
||||
jumpCtrl.in.info := info(0)
|
||||
jumpCtrl.in.forward := io.forward
|
||||
jumpCtrl.in.pc := pc(0)
|
||||
jumpCtrl.in.src_info := io.executeStage.inst(0).src_info
|
||||
|
||||
val inst0_branch = jumpCtrl.out.jump || io.bpu.branch
|
||||
io.ctrl.src_info.src1.ren := info.src1_ren
|
||||
io.ctrl.src_info.src1.raddr := info.src1_raddr
|
||||
io.ctrl.src_info.src2.ren := info.src2_ren
|
||||
io.ctrl.src_info.src2.raddr := info.src2_raddr
|
||||
io.ctrl.branch := io.fetchUnit.branch
|
||||
|
||||
io.fetchUnit.branch := inst0_branch && io.ctrl.allow_to_go
|
||||
io.fetchUnit.target := Mux(io.bpu.branch, io.bpu.target, jumpCtrl.out.jump_target)
|
||||
|
||||
io.instFifo.allow_to_go(0) := io.ctrl.allow_to_go
|
||||
io.bpu.pc := pc(0)
|
||||
io.bpu.info := info(0)
|
||||
io.bpu.pht_index := io.instFifo.inst(0).pht_index
|
||||
|
||||
io.ctrl.inst0.src1.ren := info(0).src1_ren
|
||||
io.ctrl.inst0.src1.raddr := info(0).src1_raddr
|
||||
io.ctrl.inst0.src2.ren := info(0).src2_ren
|
||||
io.ctrl.inst0.src2.raddr := info(0).src2_raddr
|
||||
io.ctrl.branch := io.fetchUnit.branch
|
||||
|
||||
io.executeStage.jump_branch_info.jump_regiser := jumpCtrl.out.jump_register
|
||||
io.executeStage.jump_branch_info.branch_inst := io.bpu.branch_inst
|
||||
io.executeStage.jump_branch_info.pred_branch := io.bpu.branch
|
||||
io.executeStage.jump_branch_info.branch_target := io.bpu.target
|
||||
io.executeStage.jump_branch_info.update_pht_index := io.bpu.update_pht_index
|
||||
|
||||
for (i <- 0 until (cpuConfig.commitNum)) {
|
||||
io.executeStage.inst(i).pc := pc(i)
|
||||
io.executeStage.inst(i).info := info(i)
|
||||
io.executeStage.inst(i).src_info.src1_data := MuxCase(
|
||||
SignedExtend(pc(i), XLEN),
|
||||
Seq(
|
||||
info(i).src1_ren -> forwardCtrl.out.inst(i).src1.rdata,
|
||||
(info(i).inst(6, 0) === "b0110111".U) -> 0.U
|
||||
)
|
||||
io.executeStage.data.pc := pc
|
||||
io.executeStage.data.info := info
|
||||
io.executeStage.data.src_info.src1_data := MuxCase(
|
||||
SignedExtend(pc, XLEN),
|
||||
Seq(
|
||||
info.src1_ren -> forwardCtrl.out.data.src1.rdata,
|
||||
(info.inst(6, 0) === "b0110111".U) -> 0.U
|
||||
)
|
||||
io.executeStage.inst(i).src_info.src2_data := Mux(
|
||||
info(i).src2_ren,
|
||||
forwardCtrl.out.inst(i).src2.rdata,
|
||||
info(i).imm
|
||||
)
|
||||
(0 until (INT_WID)).foreach(j => io.executeStage.inst(i).ex.interrupt(j) := io.csr.interrupt(j))
|
||||
io.executeStage.inst(i).ex.exception.map(_ := false.B)
|
||||
io.executeStage.inst(i).ex.exception(illegalInst) := !info(i).inst_legal
|
||||
io.executeStage.inst(i).ex.exception(instAccessFault) := io.instFifo.inst(i).access_fault
|
||||
io.executeStage.inst(i).ex.exception(instPageFault) := io.instFifo.inst(i).page_fault
|
||||
io.executeStage.inst(i).ex.exception(instAddrMisaligned) := io.instFifo.inst(i).addr_misaligned ||
|
||||
io.fetchUnit.target(log2Ceil(INST_WID / 8) - 1, 0).orR && io.fetchUnit.branch
|
||||
io.executeStage.inst(i).ex.exception(breakPoint) :=
|
||||
info(i).op === CSROpType.ebreak && info(i).fusel === FuType.csr
|
||||
io.executeStage.inst(i).ex.exception(ecallM) :=
|
||||
info(i).op === CSROpType.ecall && mode === ModeM && info(i).fusel === FuType.csr
|
||||
io.executeStage.inst(i).ex.exception(ecallS) :=
|
||||
info(i).op === CSROpType.ecall && mode === ModeS && info(i).fusel === FuType.csr
|
||||
io.executeStage.inst(i).ex.exception(ecallU) :=
|
||||
info(i).op === CSROpType.ecall && mode === ModeU && info(i).fusel === FuType.csr
|
||||
io.executeStage.inst(i).ex.tval.map(_ := DontCare)
|
||||
io.executeStage.inst(i).ex.tval(instPageFault) := pc(i)
|
||||
io.executeStage.inst(i).ex.tval(instAccessFault) := pc(i)
|
||||
io.executeStage.inst(i).ex.tval(illegalInst) := info(i).inst
|
||||
io.executeStage.inst(i).ex.tval(instAddrMisaligned) := Mux(
|
||||
io.fetchUnit.target(log2Ceil(INST_WID / 8) - 1, 0).orR && io.fetchUnit.branch,
|
||||
io.fetchUnit.target,
|
||||
pc(i)
|
||||
)
|
||||
}
|
||||
)
|
||||
io.executeStage.data.src_info.src2_data := Mux(
|
||||
info.src2_ren,
|
||||
forwardCtrl.out.data.src2.rdata,
|
||||
info.imm
|
||||
)
|
||||
}
|
||||
|
|
|
@ -7,68 +7,56 @@ import cpu.defines._
|
|||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
|
||||
class ForwardCtrl(implicit val cpuConfig: CpuConfig) extends Module {
|
||||
class ForwardCtrl extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val in = Input(new Bundle {
|
||||
val forward = Vec(cpuConfig.commitNum, new DataForwardToDecodeUnit())
|
||||
val regfile = Vec(cpuConfig.decoderNum, new Src12Read())
|
||||
val forward = new DataForwardToDecodeUnit()
|
||||
val regfile = new Src12Read()
|
||||
})
|
||||
val out = Output(new Bundle {
|
||||
val inst = Vec(cpuConfig.decoderNum, new Src12Read())
|
||||
val data = new Src12Read()
|
||||
})
|
||||
})
|
||||
|
||||
// wb优先度最低
|
||||
for (i <- 0 until (cpuConfig.decoderNum)) {
|
||||
io.out.inst(i).src1.raddr := DontCare
|
||||
io.out.inst(i).src2.raddr := DontCare
|
||||
io.out.inst(i).src1.rdata := io.in.regfile(i).src1.rdata
|
||||
io.out.inst(i).src2.rdata := io.in.regfile(i).src2.rdata
|
||||
}
|
||||
io.out.data.src1.raddr := DontCare
|
||||
io.out.data.src2.raddr := DontCare
|
||||
io.out.data.src1.rdata := io.in.regfile.src1.rdata
|
||||
io.out.data.src2.rdata := io.in.regfile.src2.rdata
|
||||
|
||||
// mem优先度中
|
||||
for (i <- 0 until (cpuConfig.decoderNum)) {
|
||||
for (j <- 0 until (cpuConfig.commitNum)) {
|
||||
when(
|
||||
io.in.forward(j).mem.wen &&
|
||||
io.in.forward(j).mem.waddr === io.in.regfile(i).src1.raddr
|
||||
) {
|
||||
io.out.inst(i).src1.rdata := io.in.forward(j).mem.wdata
|
||||
}
|
||||
when(
|
||||
io.in.forward(j).mem.wen &&
|
||||
io.in.forward(j).mem.waddr === io.in.regfile(i).src2.raddr
|
||||
) {
|
||||
io.out.inst(i).src2.rdata := io.in.forward(j).mem.wdata
|
||||
}
|
||||
}
|
||||
when(
|
||||
io.in.forward.mem.wen &&
|
||||
io.in.forward.mem.waddr === io.in.regfile.src1.raddr
|
||||
) {
|
||||
io.out.data.src1.rdata := io.in.forward.mem.wdata
|
||||
}
|
||||
when(
|
||||
io.in.forward.mem.wen &&
|
||||
io.in.forward.mem.waddr === io.in.regfile.src2.raddr
|
||||
) {
|
||||
io.out.data.src2.rdata := io.in.forward.mem.wdata
|
||||
}
|
||||
|
||||
// exe优先度高
|
||||
for (i <- 0 until (cpuConfig.decoderNum)) {
|
||||
for (j <- 0 until (cpuConfig.commitNum)) {
|
||||
when(
|
||||
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).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
|
||||
}
|
||||
}
|
||||
when(
|
||||
io.in.forward.exe.wen && !io.in.forward.is_load &&
|
||||
io.in.forward.exe.waddr === io.in.regfile.src1.raddr
|
||||
) {
|
||||
io.out.data.src1.rdata := io.in.forward.exe.wdata
|
||||
}
|
||||
when(
|
||||
io.in.forward.exe.wen && !io.in.forward.is_load &&
|
||||
io.in.forward.exe.waddr === io.in.regfile.src2.raddr
|
||||
) {
|
||||
io.out.data.src2.rdata := io.in.forward.exe.wdata
|
||||
}
|
||||
|
||||
// 读零寄存器时,数据为0
|
||||
(0 until (cpuConfig.decoderNum)).foreach(i => {
|
||||
when(io.in.regfile(i).src1.raddr === 0.U) {
|
||||
io.out.inst(i).src1.rdata := 0.U
|
||||
}
|
||||
when(io.in.regfile(i).src2.raddr === 0.U) {
|
||||
io.out.inst(i).src2.rdata := 0.U
|
||||
}
|
||||
})
|
||||
when(io.in.regfile.src1.raddr === 0.U) {
|
||||
io.out.data.src1.rdata := 0.U
|
||||
}
|
||||
when(io.in.regfile.src2.raddr === 0.U) {
|
||||
io.out.data.src2.rdata := 0.U
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue