完成对idu的修改

This commit is contained in:
Liphen 2023-11-19 15:24:10 +08:00
parent ec63ebc747
commit 8cc7e38b8b
5 changed files with 198 additions and 202 deletions

View File

@ -8,10 +8,8 @@ import cpu.CpuConfig
class ExceptionInfo extends Bundle {
val flush_req = Bool()
val eret = Bool()
val badvaddr = UInt(PC_WID.W)
val bd = Bool()
// val excode = UInt(EXCODE_WID.W)
val excode = Vec(EXCODE_WID, Bool())
val int = Vec(INT_WID, Bool())
}
class SrcInfo extends Bundle {
@ -36,7 +34,6 @@ class InstInfo extends Bundle {
val imm = UInt(XLEN.W)
val dual_issue = Bool()
val branch_link = Bool()
val mem_addr = UInt(DATA_ADDR_WID.W)
val inst = UInt(INST_WID.W)
}

View File

@ -17,6 +17,9 @@ trait Constants extends CoreParameter {
def SINGLE_ISSUE = false.B
def DUAL_ISSUE = true.B
def INT_WID = 12
def EXCODE_WID = 16
// div
def DIV_CTRL_WID = 2
def DIV_FREE = 0.U(DIV_CTRL_WID.W)
@ -94,7 +97,7 @@ trait AXIConst {
def RESP_SLVERR = 2
def RESP_DECERR = 3
}
object Const extends Constants with AXIConst
object Const extends Constants with AXIConst with HasExceptionNO
object Instructions extends HasInstrType with CoreParameter {
def NOP = 0x00000013.U

View File

@ -173,6 +173,40 @@ object CSROpType {
def clri = "b111".U
}
trait HasExceptionNO {
def instrAddrMisaligned = 0
def instrAccessFault = 1
def illegalInstr = 2
def breakPoint = 3
def loadAddrMisaligned = 4
def loadAccessFault = 5
def storeAddrMisaligned = 6
def storeAccessFault = 7
def ecallU = 8
def ecallS = 9
def ecallM = 11
def instrPageFault = 12
def loadPageFault = 13
def storePageFault = 15
val ExcPriority = Seq(
breakPoint, // TODO: different BP has different priority
instrPageFault,
instrAccessFault,
illegalInstr,
instrAddrMisaligned,
ecallM,
ecallS,
ecallU,
storeAddrMisaligned,
loadAddrMisaligned,
storePageFault,
loadPageFault,
storeAccessFault,
loadAccessFault
)
}
object Causes {
val misaligned_fetch = 0x0
val fetch_access = 0x1

View File

@ -13,7 +13,9 @@ class Decoder extends Module with HasInstrType {
val inst = UInt(INST_WID.W)
})
// outputs
val out = Output(new InstInfo())
val out = Output(new Bundle {
val inst_info = new InstInfo()
})
})
val inst = io.in.inst
@ -35,24 +37,24 @@ class Decoder extends Module with HasInstrType {
val (rs, rt, rd) = (inst(19, 15), inst(24, 20), inst(11, 7))
io.out.inst_valid := instrType === InstrN
io.out.reg1_ren := src1Type === SrcType.reg
io.out.reg1_raddr := rs
io.out.reg2_ren := src2Type === SrcType.reg
io.out.reg2_raddr := rt
io.out.fusel := fuType
io.out.op := fuOpType
io.out.inst_info.inst_valid := instrType === InstrN
io.out.inst_info.reg1_ren := src1Type === SrcType.reg
io.out.inst_info.reg1_raddr := Mux(src1Type === SrcType.reg, rs, 0.U)
io.out.inst_info.reg2_ren := src2Type === SrcType.reg
io.out.inst_info.reg2_raddr := Mux(src2Type === SrcType.reg, rt, 0.U)
io.out.inst_info.fusel := fuType
io.out.inst_info.op := fuOpType
when(fuType === FuType.bru) {
def isLink(reg: UInt) = (reg === 1.U || reg === 5.U)
when(isLink(rd) && fuOpType === ALUOpType.jal) { io.out.op := ALUOpType.call }
when(isLink(rd) && fuOpType === ALUOpType.jal) { io.out.inst_info.op := ALUOpType.call }
when(fuOpType === ALUOpType.jalr) {
when(isLink(rs)) { io.out.op := ALUOpType.ret }
when(isLink(rd)) { io.out.op := ALUOpType.call }
when(isLink(rs)) { io.out.inst_info.op := ALUOpType.ret }
when(isLink(rd)) { io.out.inst_info.op := ALUOpType.call }
}
}
io.out.reg_wen := isrfWen(instrType)
io.out.reg_waddr := Mux(isrfWen(instrType), rd, 0.U)
io.out.imm := LookupTree(
io.out.inst_info.reg_wen := isrfWen(instrType)
io.out.inst_info.reg_waddr := Mux(isrfWen(instrType), rd, 0.U)
io.out.inst_info.imm := LookupTree(
instrType,
Seq(
InstrI -> signedExtend(inst(31, 20), XLEN),
@ -63,9 +65,7 @@ class Decoder extends Module with HasInstrType {
InstrJ -> signedExtend(Cat(inst(31), inst(19, 12), inst(20), inst(30, 21), 0.U(1.W)), XLEN)
)
)
// io.out.csr_addr := Cat(inst(15, 11), inst(2, 0))
io.out.dual_issue := false.B
io.out.inst := inst
io.out.branch_link := VecInit(ALUOpType.jal, ALUOpType.jalr).contains(fuOpType)
io.out.mem_addr := DontCare
io.out.inst_info.dual_issue := false.B
io.out.inst_info.inst := inst
io.out.inst_info.branch_link := VecInit(ALUOpType.jal, ALUOpType.jalr).contains(fuOpType)
}

View File

@ -1,197 +1,159 @@
// package cpu.pipeline.decoder
package cpu.pipeline.decoder
// import chisel3._
// import chisel3.util._
// import cpu.defines._
// import cpu.defines.Const._
// import cpu.{BranchPredictorConfig, CpuConfig}
// import cpu.pipeline.execute.DecoderUnitExecuteUnit
// import cpu.pipeline.fetch.BufferUnit
import chisel3._
import chisel3.util._
import chisel3.util.experimental.BoringUtils
import cpu.defines._
import cpu.defines.Const._
import cpu.{BranchPredictorConfig, CpuConfig}
import cpu.pipeline.execute.DecoderUnitExecuteUnit
import cpu.pipeline.fetch.BufferUnit
// class InstFifoDecoderUnit(implicit val config: CpuConfig) extends Bundle {
// val allow_to_go = Output(Vec(config.decoderNum, Bool()))
// val inst = Input(Vec(config.decoderNum, new BufferUnit()))
// val info = Input(new Bundle {
// val empty = Bool()
// val almost_empty = Bool()
// })
// }
class InstFifoDecoderUnit(implicit val config: CpuConfig) extends Bundle {
val allow_to_go = Output(Vec(config.decoderNum, Bool()))
val inst = Input(Vec(config.decoderNum, new BufferUnit()))
val info = Input(new Bundle {
val empty = Bool()
val almost_empty = Bool()
})
}
// class DataForwardToDecoderUnit extends Bundle {
// val exe = new RegWrite()
// val mem_wreg = Bool()
// val mem = new RegWrite()
// }
class DataForwardToDecoderUnit extends Bundle {
val exe = new RegWrite()
val mem_wreg = Bool()
val mem = new RegWrite()
}
// class CsrDecoderUnit extends Bundle {
// val access_allowed = Bool()
// val kernel_mode = Bool()
// val intterupt_allowed = Bool()
// val cause_ip = UInt(8.W)
// val status_im = UInt(8.W)
// }
class CsrDecoderUnit extends Bundle {
val access_allowed = Bool()
val kernel_mode = Bool()
val intterupt_allowed = Bool()
val cause_ip = UInt(8.W)
val status_im = UInt(8.W)
}
// class DecoderUnit(implicit val config: CpuConfig) extends Module {
// val io = IO(new Bundle {
// // 输入
// val instFifo = new InstFifoDecoderUnit()
// val regfile = Vec(config.decoderNum, new Src12Read())
// val forward = Input(Vec(config.fuNum, new DataForwardToDecoderUnit()))
// val csr = Input(new CsrDecoderUnit())
// // 输出
// val fetchUnit = new Bundle {
// val branch = Output(Bool())
// val target = Output(UInt(PC_WID.W))
// }
// val bpu = new Bundle {
// val bpuConfig = new BranchPredictorConfig()
// val pc = Output(UInt(PC_WID.W))
// val decoded_inst0 = Output(new InstInfo())
// val id_allow_to_go = Output(Bool())
// val pht_index = Output(UInt(bpuConfig.phtDepth.W))
class DecoderUnit(implicit val config: CpuConfig) extends Module with HasExceptionNO {
val io = IO(new Bundle {
// 输入
val instFifo = new InstFifoDecoderUnit()
val regfile = Vec(config.decoderNum, new Src12Read())
val forward = Input(Vec(config.fuNum, new DataForwardToDecoderUnit()))
val csr = Input(new CsrDecoderUnit())
// 输出
val fetchUnit = new Bundle {
val branch = Output(Bool())
val target = Output(UInt(PC_WID.W))
}
val bpu = new Bundle {
val bpuConfig = new BranchPredictorConfig()
val pc = Output(UInt(PC_WID.W))
val decoded_inst0 = Output(new InstInfo())
val id_allow_to_go = Output(Bool())
val pht_index = Output(UInt(bpuConfig.phtDepth.W))
// val branch_inst = Input(Bool())
// val pred_branch = Input(Bool())
// val branch_target = Input(UInt(PC_WID.W))
// val update_pht_index = Input(UInt(bpuConfig.phtDepth.W))
// }
// val executeStage = Output(new DecoderUnitExecuteUnit())
// val ctrl = new DecoderUnitCtrl()
// })
val branch_inst = Input(Bool())
val pred_branch = Input(Bool())
val branch_target = Input(UInt(PC_WID.W))
val update_pht_index = Input(UInt(bpuConfig.phtDepth.W))
}
val executeStage = Output(new DecoderUnitExecuteUnit())
val ctrl = new DecoderUnitCtrl()
})
// val issue = Module(new Issue()).io
// val decoder = Seq.fill(config.decoderNum)(Module(new Decoder()))
// val jumpCtrl = Module(new JumpCtrl()).io
// val forwardCtrl = Module(new ForwardCtrl()).io
val issue = Module(new Issue()).io
val decoder = Seq.fill(config.decoderNum)(Module(new Decoder()))
val jumpCtrl = Module(new JumpCtrl()).io
val forwardCtrl = Module(new ForwardCtrl()).io
// io.regfile(0).src1.raddr := decoder(0).io.out.reg1_raddr
// io.regfile(0).src2.raddr := decoder(0).io.out.reg2_raddr
// io.regfile(1).src1.raddr := decoder(1).io.out.reg1_raddr
// io.regfile(1).src2.raddr := decoder(1).io.out.reg2_raddr
io.regfile(0).src1.raddr := decoder(0).io.out.inst_info.reg1_raddr
io.regfile(0).src2.raddr := decoder(0).io.out.inst_info.reg2_raddr
io.regfile(1).src1.raddr := decoder(1).io.out.inst_info.reg1_raddr
io.regfile(1).src2.raddr := decoder(1).io.out.inst_info.reg2_raddr
// forwardCtrl.in.forward := io.forward
// forwardCtrl.in.regfile := io.regfile // TODO:这里的连接可能有问题
forwardCtrl.in.forward := io.forward
forwardCtrl.in.regfile := io.regfile // TODO:这里的连接可能有问题
// issue.allow_to_go := io.ctrl.allow_to_go
// issue.instFifo := io.instFifo.info
issue.allow_to_go := io.ctrl.allow_to_go
issue.instFifo := io.instFifo.info
// jumpCtrl.in.allow_to_go := io.ctrl.allow_to_go
// jumpCtrl.in.decoded_inst0 := decoder(0).io.out
// jumpCtrl.in.forward := io.forward
// jumpCtrl.in.pc := io.instFifo.inst(0).pc
// jumpCtrl.in.reg1_data := io.regfile(0).src1.rdata
jumpCtrl.in.allow_to_go := io.ctrl.allow_to_go
jumpCtrl.in.decoded_inst0 := decoder(0).io.out
jumpCtrl.in.forward := io.forward
jumpCtrl.in.pc := io.instFifo.inst(0).pc
jumpCtrl.in.reg1_data := io.regfile(0).src1.rdata
// val inst0_branch = jumpCtrl.out.jump || io.bpu.pred_branch
val inst0_branch = jumpCtrl.out.jump || io.bpu.pred_branch
// io.fetchUnit.branch := inst0_branch
// io.fetchUnit.target := Mux(io.bpu.pred_branch, io.bpu.branch_target, jumpCtrl.out.jump_target)
io.fetchUnit.branch := inst0_branch
io.fetchUnit.target := Mux(io.bpu.pred_branch, io.bpu.branch_target, jumpCtrl.out.jump_target)
// io.instFifo.allow_to_go(0) := io.ctrl.allow_to_go
// io.instFifo.allow_to_go(1) := issue.inst1.allow_to_go
io.instFifo.allow_to_go(0) := io.ctrl.allow_to_go
io.instFifo.allow_to_go(1) := issue.inst1.allow_to_go
// io.bpu.id_allow_to_go := io.ctrl.allow_to_go
// io.bpu.pc := io.instFifo.inst(0).pc
// io.bpu.decoded_inst0 := decoder(0).io.out
// io.bpu.pht_index := io.instFifo.inst(0).pht_index
io.bpu.id_allow_to_go := io.ctrl.allow_to_go
io.bpu.pc := io.instFifo.inst(0).pc
io.bpu.decoded_inst0 := decoder(0).io.out
io.bpu.pht_index := io.instFifo.inst(0).pht_index
// io.ctrl.inst0.src1.ren := decoder(0).io.out.reg1_ren
// io.ctrl.inst0.src1.raddr := decoder(0).io.out.reg1_raddr
// io.ctrl.inst0.src2.ren := decoder(0).io.out.reg2_ren
// io.ctrl.inst0.src2.raddr := decoder(0).io.out.reg2_raddr
// io.ctrl.branch := inst0_branch
io.ctrl.inst0.src1.ren := decoder(0).io.out.inst_info.reg1_ren
io.ctrl.inst0.src1.raddr := decoder(0).io.out.inst_info.reg1_raddr
io.ctrl.inst0.src2.ren := decoder(0).io.out.inst_info.reg2_ren
io.ctrl.inst0.src2.raddr := decoder(0).io.out.inst_info.reg2_raddr
io.ctrl.branch := inst0_branch
// val pc = io.instFifo.inst.map(_.pc)
// val inst = io.instFifo.inst.map(_.inst)
// val inst_info = decoder.map(_.io.out)
// val interrupt = io.csr.intterupt_allowed && (io.csr.cause_ip & io.csr.status_im).orR && !io.instFifo.info.empty
val pc = io.instFifo.inst.map(_.pc)
val inst = io.instFifo.inst.map(_.inst)
val inst_info = decoder.map(_.io.out.inst_info)
// for (i <- 0 until (config.decoderNum)) {
// decoder(i).io.in.inst := inst(i)
// issue.decodeInst(i) := inst_info(i)
// issue.execute(i).mem_wreg := io.forward(i).mem_wreg
// issue.execute(i).reg_waddr := io.forward(i).exe.waddr
// }
for (i <- 0 until (config.decoderNum)) {
decoder(i).io.in.inst := inst(i)
issue.decodeInst(i) := inst_info(i)
issue.execute(i).mem_wreg := io.forward(i).mem_wreg
issue.execute(i).reg_waddr := io.forward(i).exe.waddr
}
// io.executeStage.inst0.pc := pc(0)
// io.executeStage.inst0.inst_info := inst_info(0)
// io.executeStage.inst0.inst_info.reg_wen := MuxLookup(inst_info(0).op, inst_info(0).reg_wen)(
// Seq(
// EXE_MOVN -> (io.executeStage.inst0.src_info.src2_data =/= 0.U),
// EXE_MOVZ -> (io.executeStage.inst0.src_info.src2_data === 0.U)
// )
// )
// io.executeStage.inst0.inst_info.mem_addr :=
// io.executeStage.inst0.src_info.src1_data + Util.signedExtend(io.executeStage.inst0.inst_info.inst(15, 0))
// io.executeStage.inst0.src_info.src1_data := Mux(
// inst_info(0).reg1_ren,
// forwardCtrl.out.inst(0).src1.rdata,
// decoder(0).io.out.imm
// )
// io.executeStage.inst0.src_info.src2_data := Mux(
// inst_info(0).reg2_ren,
// forwardCtrl.out.inst(0).src2.rdata,
// decoder(0).io.out.imm
// )
// io.executeStage.inst0.ex.flush_req :=
// io.executeStage.inst0.ex.excode =/= EX_NO ||
// io.executeStage.inst0.ex.eret
// io.executeStage.inst0.ex.eret := inst_info(0).op === EXE_ERET
// io.executeStage.inst0.ex.badvaddr := pc(0)
// val inst0_ex_cpu =
// !io.csr.access_allowed && VecInit(EXE_MFC0, EXE_MTC0, EXE_TLBR, EXE_TLBWI, EXE_TLBWR, EXE_TLBP, EXE_ERET, EXE_WAIT)
// .contains(inst_info(0).op)
// io.executeStage.inst0.ex.excode := MuxCase(
// EX_NO,
// Seq(
// interrupt -> EX_INT,
// (pc(0)(1, 0).orR || (pc(0)(31) && !io.csr.kernel_mode)) -> EX_ADEL,
// (inst_info(0).inst_valid === INST_INVALID) -> EX_RI,
// (inst_info(0).op === EXE_SYSCALL) -> EX_SYS,
// (inst_info(0).op === EXE_BREAK) -> EX_BP,
// (inst0_ex_cpu) -> EX_CPU
// )
// )
// io.executeStage.inst0.jb_info.jump_regiser := jumpCtrl.out.jump_register
// io.executeStage.inst0.jb_info.branch_inst := io.bpu.branch_inst
// io.executeStage.inst0.jb_info.pred_branch := io.bpu.pred_branch
// io.executeStage.inst0.jb_info.branch_target := io.bpu.branch_target
// io.executeStage.inst0.jb_info.update_pht_index := io.bpu.update_pht_index
val int = WireInit(0.U(INT_WID.W))
BoringUtils.addSink(int, "intDecoderUnit")
io.executeStage.inst0.ex.int.zip(int.asBools).map { case (x, y) => x := y }
val hasInt = int.orR
// io.executeStage.inst1.allow_to_go := issue.inst1.allow_to_go
// io.executeStage.inst1.pc := pc(1)
// io.executeStage.inst1.inst_info := inst_info(1)
// io.executeStage.inst1.inst_info.reg_wen := MuxLookup(inst_info(1).op, inst_info(1).reg_wen)(
// Seq(
// EXE_MOVN -> (io.executeStage.inst1.src_info.src2_data =/= 0.U),
// EXE_MOVZ -> (io.executeStage.inst1.src_info.src2_data === 0.U)
// )
// )
// io.executeStage.inst1.inst_info.mem_addr :=
// io.executeStage.inst1.src_info.src1_data + Util.signedExtend(io.executeStage.inst1.inst_info.inst(15, 0))
// io.executeStage.inst1.src_info.src1_data := Mux(
// inst_info(1).reg1_ren,
// forwardCtrl.out.inst(1).src1.rdata,
// decoder(1).io.out.imm
// )
// io.executeStage.inst1.src_info.src2_data := Mux(
// inst_info(1).reg2_ren,
// forwardCtrl.out.inst(1).src2.rdata,
// decoder(1).io.out.imm
// )
// io.executeStage.inst1.ex.flush_req := io.executeStage.inst1.ex.excode =/= EX_NO
// io.executeStage.inst1.ex.eret := inst_info(1).op === EXE_ERET
// io.executeStage.inst1.ex.badvaddr := pc(1)
// val inst1_ex_cpu =
// !io.csr.access_allowed && VecInit(EXE_MFC0, EXE_MTC0, EXE_TLBR, EXE_TLBWI, EXE_TLBWR, EXE_TLBP, EXE_ERET, EXE_WAIT)
// .contains(inst_info(1).op)
// io.executeStage.inst1.ex.excode := MuxCase(
// EX_NO,
// Seq(
// (pc(1)(1, 0).orR || (pc(1)(31) && !io.csr.kernel_mode)) -> EX_ADEL,
// (inst_info(1).inst_valid === INST_INVALID) -> EX_RI,
// (inst_info(1).op === EXE_SYSCALL) -> EX_SYS,
// (inst_info(1).op === EXE_BREAK) -> EX_BP,
// (inst1_ex_cpu) -> EX_CPU
// )
// )
// }
io.executeStage.inst0.pc := pc(0)
io.executeStage.inst0.inst_info := inst_info(0)
io.executeStage.inst0.src_info.src1_data := Mux(
inst_info(0).reg1_ren,
forwardCtrl.out.inst(0).src1.rdata,
Util.signedExtend(pc(0), INST_ADDR_WID)
)
io.executeStage.inst0.src_info.src2_data := Mux(
inst_info(0).reg2_ren,
forwardCtrl.out.inst(0).src2.rdata,
decoder(0).io.out.inst_info.imm
)
io.executeStage.inst0.ex.flush_req := io.executeStage.inst0.ex.excode.asUInt.orR
io.executeStage.inst0.ex.excode.map(_ := false.B)
io.executeStage.inst0.ex.excode(illegalInstr) := !decoder(0).io.out.inst_info.inst_valid &&
!hasInt && !io.instFifo.info.empty
io.executeStage.inst0.jb_info.jump_regiser := jumpCtrl.out.jump_register
io.executeStage.inst0.jb_info.branch_inst := io.bpu.branch_inst
io.executeStage.inst0.jb_info.pred_branch := io.bpu.pred_branch
io.executeStage.inst0.jb_info.branch_target := io.bpu.branch_target
io.executeStage.inst0.jb_info.update_pht_index := io.bpu.update_pht_index
io.executeStage.inst1.allow_to_go := issue.inst1.allow_to_go
io.executeStage.inst1.pc := pc(1)
io.executeStage.inst1.inst_info := inst_info(1)
io.executeStage.inst1.src_info.src1_data := Mux(
inst_info(1).reg1_ren,
forwardCtrl.out.inst(1).src1.rdata,
Util.signedExtend(pc(1), INST_ADDR_WID)
)
io.executeStage.inst1.src_info.src2_data := Mux(
inst_info(1).reg2_ren,
forwardCtrl.out.inst(1).src2.rdata,
decoder(1).io.out.inst_info.imm
)
io.executeStage.inst1.ex.excode.map(_ := false.B)
io.executeStage.inst1.ex.excode(illegalInstr) := !decoder(1).io.out.inst_info.inst_valid &&
!hasInt && !io.instFifo.info.almost_empty
}