feat: 修改Decode模块
This commit is contained in:
parent
77aca76b74
commit
ec63ebc747
|
@ -1,147 +1,147 @@
|
||||||
package cpu
|
// package cpu
|
||||||
|
|
||||||
import chisel3._
|
// import chisel3._
|
||||||
import chisel3.util._
|
// import chisel3.util._
|
||||||
import chisel3.internal.DontCareBinding
|
// import chisel3.internal.DontCareBinding
|
||||||
|
|
||||||
import defines._
|
// import defines._
|
||||||
import defines.Const._
|
// import defines.Const._
|
||||||
import pipeline.fetch._
|
// import pipeline.fetch._
|
||||||
import pipeline.decoder._
|
// import pipeline.decoder._
|
||||||
import pipeline.execute._
|
// import pipeline.execute._
|
||||||
import pipeline.memory._
|
// import pipeline.memory._
|
||||||
import pipeline.writeback._
|
// import pipeline.writeback._
|
||||||
import ctrl._
|
// import ctrl._
|
||||||
import mmu._
|
// import mmu._
|
||||||
import chisel3.util.experimental.decode.decoder
|
// import chisel3.util.experimental.decode.decoder
|
||||||
import cpu.pipeline.fetch.InstFifo
|
// import cpu.pipeline.fetch.InstFifo
|
||||||
|
|
||||||
class Core(implicit val config: CpuConfig) extends Module {
|
// class Core(implicit val config: CpuConfig) extends Module {
|
||||||
val io = IO(new Bundle {
|
// val io = IO(new Bundle {
|
||||||
val ext_int = Input(UInt(6.W))
|
// val ext_int = Input(UInt(6.W))
|
||||||
val inst = new Cache_ICache()
|
// val inst = new Cache_ICache()
|
||||||
val data = new Cache_DCache()
|
// val data = new Cache_DCache()
|
||||||
val debug = new DEBUG()
|
// val debug = new DEBUG()
|
||||||
})
|
// })
|
||||||
|
|
||||||
val ctrl = Module(new Ctrl()).io
|
// val ctrl = Module(new Ctrl()).io
|
||||||
val fetchUnit = Module(new FetchUnit()).io
|
// val fetchUnit = Module(new FetchUnit()).io
|
||||||
val bpu = Module(new BranchPredictorUnit()).io
|
// val bpu = Module(new BranchPredictorUnit()).io
|
||||||
val instFifo = Module(new InstFifo()).io
|
// val instFifo = Module(new InstFifo()).io
|
||||||
val decoderUnit = Module(new DecoderUnit()).io
|
// val decoderUnit = Module(new DecoderUnit()).io
|
||||||
val regfile = Module(new ARegFile()).io
|
// val regfile = Module(new ARegFile()).io
|
||||||
val executeStage = Module(new ExecuteStage()).io
|
// val executeStage = Module(new ExecuteStage()).io
|
||||||
val executeUnit = Module(new ExecuteUnit()).io
|
// val executeUnit = Module(new ExecuteUnit()).io
|
||||||
val csr = Module(new Csr()).io
|
// val csr = Module(new Csr()).io
|
||||||
val memoryStage = Module(new MemoryStage()).io
|
// val memoryStage = Module(new MemoryStage()).io
|
||||||
val memoryUnit = Module(new MemoryUnit()).io
|
// val memoryUnit = Module(new MemoryUnit()).io
|
||||||
val writeBackStage = Module(new WriteBackStage()).io
|
// val writeBackStage = Module(new WriteBackStage()).io
|
||||||
val writeBackUnit = Module(new WriteBackUnit()).io
|
// val writeBackUnit = Module(new WriteBackUnit()).io
|
||||||
|
|
||||||
ctrl.instFifo.has2insts := !(instFifo.empty || instFifo.almost_empty)
|
// ctrl.instFifo.has2insts := !(instFifo.empty || instFifo.almost_empty)
|
||||||
ctrl.decoderUnit <> decoderUnit.ctrl
|
// ctrl.decoderUnit <> decoderUnit.ctrl
|
||||||
ctrl.executeUnit <> executeUnit.ctrl
|
// ctrl.executeUnit <> executeUnit.ctrl
|
||||||
ctrl.memoryUnit <> memoryUnit.ctrl
|
// ctrl.memoryUnit <> memoryUnit.ctrl
|
||||||
ctrl.writeBackUnit <> writeBackUnit.ctrl
|
// ctrl.writeBackUnit <> writeBackUnit.ctrl
|
||||||
ctrl.cacheCtrl.iCache_stall := io.inst.stall
|
// ctrl.cacheCtrl.iCache_stall := io.inst.stall
|
||||||
ctrl.cacheCtrl.dCache_stall := io.data.stall
|
// ctrl.cacheCtrl.dCache_stall := io.data.stall
|
||||||
|
|
||||||
fetchUnit.memory <> memoryUnit.fetchUnit
|
// fetchUnit.memory <> memoryUnit.fetchUnit
|
||||||
fetchUnit.execute <> executeUnit.fetchUnit
|
// fetchUnit.execute <> executeUnit.fetchUnit
|
||||||
fetchUnit.decoder <> decoderUnit.fetchUnit
|
// fetchUnit.decoder <> decoderUnit.fetchUnit
|
||||||
fetchUnit.instFifo.full := instFifo.full
|
// fetchUnit.instFifo.full := instFifo.full
|
||||||
fetchUnit.iCache.inst_valid := io.inst.valid
|
// fetchUnit.iCache.inst_valid := io.inst.valid
|
||||||
io.inst.addr(0) := fetchUnit.iCache.pc
|
// io.inst.addr(0) := fetchUnit.iCache.pc
|
||||||
io.inst.addr(1) := fetchUnit.iCache.pc_next
|
// io.inst.addr(1) := fetchUnit.iCache.pc_next
|
||||||
for (i <- 2 until config.instFetchNum) {
|
// for (i <- 2 until config.instFetchNum) {
|
||||||
io.inst.addr(i) := fetchUnit.iCache.pc_next + ((i - 1) * 4).U
|
// io.inst.addr(i) := fetchUnit.iCache.pc_next + ((i - 1) * 4).U
|
||||||
}
|
// }
|
||||||
|
|
||||||
bpu.decoder.ena := ctrl.decoderUnit.allow_to_go
|
// bpu.decoder.ena := ctrl.decoderUnit.allow_to_go
|
||||||
bpu.decoder.op := decoderUnit.bpu.decoded_inst0.op
|
// bpu.decoder.op := decoderUnit.bpu.decoded_inst0.op
|
||||||
bpu.decoder.inst := decoderUnit.bpu.decoded_inst0.inst
|
// bpu.decoder.inst := decoderUnit.bpu.decoded_inst0.inst
|
||||||
bpu.decoder.rs1 := decoderUnit.bpu.decoded_inst0.reg1_raddr
|
// bpu.decoder.rs1 := decoderUnit.bpu.decoded_inst0.reg1_raddr
|
||||||
bpu.decoder.rs2 := decoderUnit.bpu.decoded_inst0.reg2_raddr
|
// bpu.decoder.rs2 := decoderUnit.bpu.decoded_inst0.reg2_raddr
|
||||||
bpu.decoder.pc := decoderUnit.bpu.pc
|
// bpu.decoder.pc := decoderUnit.bpu.pc
|
||||||
bpu.decoder.pc_plus4 := decoderUnit.bpu.pc + 4.U
|
// bpu.decoder.pc_plus4 := decoderUnit.bpu.pc + 4.U
|
||||||
bpu.decoder.pht_index := decoderUnit.bpu.pht_index
|
// bpu.decoder.pht_index := decoderUnit.bpu.pht_index
|
||||||
decoderUnit.bpu.update_pht_index := bpu.decoder.update_pht_index
|
// decoderUnit.bpu.update_pht_index := bpu.decoder.update_pht_index
|
||||||
bpu.execute <> executeUnit.bpu
|
// bpu.execute <> executeUnit.bpu
|
||||||
if (config.branchPredictor == "pesudo") {
|
// if (config.branchPredictor == "pesudo") {
|
||||||
bpu.regfile.get <> regfile.bpu.get
|
// bpu.regfile.get <> regfile.bpu.get
|
||||||
}
|
// }
|
||||||
decoderUnit.bpu.branch_inst := bpu.decoder.branch_inst
|
// decoderUnit.bpu.branch_inst := bpu.decoder.branch_inst
|
||||||
decoderUnit.bpu.pred_branch := bpu.decoder.pred_branch
|
// decoderUnit.bpu.pred_branch := bpu.decoder.pred_branch
|
||||||
decoderUnit.bpu.branch_target := bpu.decoder.branch_target
|
// decoderUnit.bpu.branch_target := bpu.decoder.branch_target
|
||||||
|
|
||||||
instFifo.do_flush := ctrl.decoderUnit.do_flush
|
// instFifo.do_flush := ctrl.decoderUnit.do_flush
|
||||||
instFifo.icache_stall := io.inst.stall
|
// instFifo.icache_stall := io.inst.stall
|
||||||
instFifo.ren <> decoderUnit.instFifo.allow_to_go
|
// instFifo.ren <> decoderUnit.instFifo.allow_to_go
|
||||||
decoderUnit.instFifo.inst <> instFifo.read
|
// decoderUnit.instFifo.inst <> instFifo.read
|
||||||
|
|
||||||
for (i <- 0 until config.instFetchNum) {
|
// for (i <- 0 until config.instFetchNum) {
|
||||||
instFifo.write(i).pht_index := bpu.instBuffer.pht_index(i)
|
// instFifo.write(i).pht_index := bpu.instBuffer.pht_index(i)
|
||||||
bpu.instBuffer.pc(i) := instFifo.write(i).pc
|
// bpu.instBuffer.pc(i) := instFifo.write(i).pc
|
||||||
instFifo.wen(i) := io.inst.valid(i)
|
// instFifo.wen(i) := io.inst.valid(i)
|
||||||
instFifo.write(i).pc := io.inst.addr(0) + (i * 4).U
|
// instFifo.write(i).pc := io.inst.addr(0) + (i * 4).U
|
||||||
instFifo.write(i).inst := io.inst.rdata
|
// instFifo.write(i).inst := io.inst.rdata
|
||||||
}
|
// }
|
||||||
|
|
||||||
decoderUnit.instFifo.info.empty := instFifo.empty
|
// decoderUnit.instFifo.info.empty := instFifo.empty
|
||||||
decoderUnit.instFifo.info.almost_empty := instFifo.almost_empty
|
// decoderUnit.instFifo.info.almost_empty := instFifo.almost_empty
|
||||||
decoderUnit.regfile <> regfile.read
|
// decoderUnit.regfile <> regfile.read
|
||||||
for (i <- 0 until (config.fuNum)) {
|
// for (i <- 0 until (config.fuNum)) {
|
||||||
decoderUnit.forward(i).exe := executeUnit.decoderUnit.forward(i).exe
|
// decoderUnit.forward(i).exe := executeUnit.decoderUnit.forward(i).exe
|
||||||
decoderUnit.forward(i).mem_wreg := executeUnit.decoderUnit.forward(i).exe_mem_wreg
|
// decoderUnit.forward(i).mem_wreg := executeUnit.decoderUnit.forward(i).exe_mem_wreg
|
||||||
decoderUnit.forward(i).mem := memoryUnit.decoderUnit(i)
|
// decoderUnit.forward(i).mem := memoryUnit.decoderUnit(i)
|
||||||
}
|
// }
|
||||||
decoderUnit.csr <> csr.decoderUnit
|
// decoderUnit.csr <> csr.decoderUnit
|
||||||
decoderUnit.executeStage <> executeStage.decoderUnit
|
// decoderUnit.executeStage <> executeStage.decoderUnit
|
||||||
|
|
||||||
executeStage.ctrl.clear(0) := ctrl.memoryUnit.flush_req ||
|
// executeStage.ctrl.clear(0) := ctrl.memoryUnit.flush_req ||
|
||||||
!decoderUnit.executeStage.inst0.ex.bd && ctrl.executeUnit.do_flush && ctrl.executeUnit.allow_to_go ||
|
// !decoderUnit.executeStage.inst0.ex.bd && ctrl.executeUnit.do_flush && ctrl.executeUnit.allow_to_go ||
|
||||||
!ctrl.decoderUnit.allow_to_go && ctrl.executeUnit.allow_to_go
|
// !ctrl.decoderUnit.allow_to_go && ctrl.executeUnit.allow_to_go
|
||||||
executeStage.ctrl.clear(1) := ctrl.memoryUnit.flush_req ||
|
// executeStage.ctrl.clear(1) := ctrl.memoryUnit.flush_req ||
|
||||||
(ctrl.executeUnit.do_flush && decoderUnit.executeStage.inst1.allow_to_go) ||
|
// (ctrl.executeUnit.do_flush && decoderUnit.executeStage.inst1.allow_to_go) ||
|
||||||
(ctrl.executeUnit.allow_to_go && !decoderUnit.executeStage.inst1.allow_to_go)
|
// (ctrl.executeUnit.allow_to_go && !decoderUnit.executeStage.inst1.allow_to_go)
|
||||||
executeStage.ctrl.inst0_allow_to_go := ctrl.executeUnit.allow_to_go
|
// executeStage.ctrl.inst0_allow_to_go := ctrl.executeUnit.allow_to_go
|
||||||
|
|
||||||
executeUnit.decoderUnit.inst0_bd := decoderUnit.executeStage.inst0.ex.bd
|
// executeUnit.decoderUnit.inst0_bd := decoderUnit.executeStage.inst0.ex.bd
|
||||||
executeUnit.executeStage <> executeStage.executeUnit
|
// executeUnit.executeStage <> executeStage.executeUnit
|
||||||
executeUnit.csr <> csr.executeUnit
|
// executeUnit.csr <> csr.executeUnit
|
||||||
executeUnit.memoryStage <> memoryStage.executeUnit
|
// executeUnit.memoryStage <> memoryStage.executeUnit
|
||||||
|
|
||||||
memoryStage.ctrl.allow_to_go := ctrl.memoryUnit.allow_to_go
|
// memoryStage.ctrl.allow_to_go := ctrl.memoryUnit.allow_to_go
|
||||||
memoryStage.ctrl.clear := ctrl.memoryUnit.do_flush
|
// memoryStage.ctrl.clear := ctrl.memoryUnit.do_flush
|
||||||
|
|
||||||
memoryUnit.memoryStage <> memoryStage.memoryUnit
|
// memoryUnit.memoryStage <> memoryStage.memoryUnit
|
||||||
memoryUnit.csr <> csr.memoryUnit
|
// memoryUnit.csr <> csr.memoryUnit
|
||||||
memoryUnit.writeBackStage <> writeBackStage.memoryUnit
|
// memoryUnit.writeBackStage <> writeBackStage.memoryUnit
|
||||||
|
|
||||||
csr.ctrl.exe_stall := !ctrl.executeUnit.allow_to_go
|
// csr.ctrl.exe_stall := !ctrl.executeUnit.allow_to_go
|
||||||
csr.ctrl.mem_stall := !ctrl.memoryUnit.allow_to_go
|
// csr.ctrl.mem_stall := !ctrl.memoryUnit.allow_to_go
|
||||||
csr.ext_int := io.ext_int
|
// csr.ext_int := io.ext_int
|
||||||
|
|
||||||
memoryUnit.dataMemory.in.rdata := io.data.rdata
|
// memoryUnit.dataMemory.in.rdata := io.data.rdata
|
||||||
io.data.en := memoryUnit.dataMemory.out.en
|
// io.data.en := memoryUnit.dataMemory.out.en
|
||||||
io.data.size := memoryUnit.dataMemory.out.rlen
|
// io.data.size := memoryUnit.dataMemory.out.rlen
|
||||||
io.data.write := memoryUnit.dataMemory.out.wen
|
// io.data.write := memoryUnit.dataMemory.out.wen
|
||||||
io.data.wdata := memoryUnit.dataMemory.out.wdata
|
// io.data.wdata := memoryUnit.dataMemory.out.wdata
|
||||||
io.data.addr := memoryUnit.dataMemory.out.addr
|
// io.data.addr := memoryUnit.dataMemory.out.addr
|
||||||
|
|
||||||
writeBackStage.memoryUnit <> memoryUnit.writeBackStage
|
// writeBackStage.memoryUnit <> memoryUnit.writeBackStage
|
||||||
writeBackStage.ctrl.allow_to_go := ctrl.writeBackUnit.allow_to_go
|
// writeBackStage.ctrl.allow_to_go := ctrl.writeBackUnit.allow_to_go
|
||||||
writeBackStage.ctrl.clear := ctrl.writeBackUnit.do_flush
|
// writeBackStage.ctrl.clear := ctrl.writeBackUnit.do_flush
|
||||||
|
|
||||||
writeBackUnit.writeBackStage <> writeBackStage.writeBackUnit
|
// writeBackUnit.writeBackStage <> writeBackStage.writeBackUnit
|
||||||
writeBackUnit.ctrl <> ctrl.writeBackUnit
|
// writeBackUnit.ctrl <> ctrl.writeBackUnit
|
||||||
regfile.write <> writeBackUnit.regfile
|
// regfile.write <> writeBackUnit.regfile
|
||||||
|
|
||||||
io.debug <> writeBackUnit.debug
|
// io.debug <> writeBackUnit.debug
|
||||||
|
|
||||||
// io.inst.fence_i := executeUnit.executeStage.inst0.inst_info.ifence
|
// // io.inst.fence_i := executeUnit.executeStage.inst0.inst_info.ifence
|
||||||
// io.data.fence_i := memoryUnit.memoryStage.inst0.inst_info.dfence
|
// // io.data.fence_i := memoryUnit.memoryStage.inst0.inst_info.dfence
|
||||||
io.inst.en := !instFifo.full
|
// io.inst.en := !instFifo.full
|
||||||
io.inst.ready := !ctrl.fetchUnit.allow_to_go
|
// io.inst.ready := !ctrl.fetchUnit.allow_to_go
|
||||||
io.data.ready := !ctrl.memoryUnit.allow_to_go
|
// io.data.ready := !ctrl.memoryUnit.allow_to_go
|
||||||
}
|
// }
|
||||||
|
|
|
@ -2,6 +2,7 @@ package cpu.defines
|
||||||
|
|
||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.util._
|
import chisel3.util._
|
||||||
|
import cpu.defines._
|
||||||
import cpu.defines.Const._
|
import cpu.defines.Const._
|
||||||
import cpu.CpuConfig
|
import cpu.CpuConfig
|
||||||
|
|
||||||
|
@ -10,16 +11,16 @@ class ExceptionInfo extends Bundle {
|
||||||
val eret = Bool()
|
val eret = Bool()
|
||||||
val badvaddr = UInt(PC_WID.W)
|
val badvaddr = UInt(PC_WID.W)
|
||||||
val bd = Bool()
|
val bd = Bool()
|
||||||
val excode = UInt(EXCODE_WID.W)
|
// val excode = UInt(EXCODE_WID.W)
|
||||||
}
|
}
|
||||||
|
|
||||||
class SrcInfo extends Bundle {
|
class SrcInfo extends Bundle {
|
||||||
val src1_data = UInt(DATA_WID.W)
|
val src1_data = UInt(XLEN.W)
|
||||||
val src2_data = UInt(DATA_WID.W)
|
val src2_data = UInt(XLEN.W)
|
||||||
}
|
}
|
||||||
|
|
||||||
class RdInfo extends Bundle {
|
class RdInfo extends Bundle {
|
||||||
val wdata = UInt(DATA_WID.W)
|
val wdata = UInt(XLEN.W)
|
||||||
}
|
}
|
||||||
|
|
||||||
class InstInfo extends Bundle {
|
class InstInfo extends Bundle {
|
||||||
|
@ -28,23 +29,14 @@ class InstInfo extends Bundle {
|
||||||
val reg1_raddr = UInt(REG_ADDR_WID.W)
|
val reg1_raddr = UInt(REG_ADDR_WID.W)
|
||||||
val reg2_ren = Bool()
|
val reg2_ren = Bool()
|
||||||
val reg2_raddr = UInt(REG_ADDR_WID.W)
|
val reg2_raddr = UInt(REG_ADDR_WID.W)
|
||||||
val fusel = UInt(FU_SEL_WID.W)
|
val fusel = FuType()
|
||||||
val op = UInt(OP_WID.W)
|
val op = FuOpType()
|
||||||
val reg_wen = Bool()
|
val reg_wen = Bool()
|
||||||
val reg_waddr = UInt(REG_ADDR_WID.W)
|
val reg_waddr = UInt(REG_ADDR_WID.W)
|
||||||
val imm32 = UInt(DATA_WID.W)
|
val imm = UInt(XLEN.W)
|
||||||
val csr_addr = UInt(CSR_ADDR_WID.W)
|
|
||||||
val dual_issue = Bool()
|
val dual_issue = Bool()
|
||||||
val whilo = Bool()
|
|
||||||
val rmem = Bool()
|
|
||||||
val wmem = Bool()
|
|
||||||
val mul = Bool()
|
|
||||||
val div = Bool()
|
|
||||||
val branch_link = Bool()
|
val branch_link = Bool()
|
||||||
val ifence = Bool()
|
|
||||||
val dfence = Bool()
|
|
||||||
val mem_addr = UInt(DATA_ADDR_WID.W)
|
val mem_addr = UInt(DATA_ADDR_WID.W)
|
||||||
val mem_wreg = Bool()
|
|
||||||
val inst = UInt(INST_WID.W)
|
val inst = UInt(INST_WID.W)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,11 +126,11 @@ class Cache_DCache extends Bundle {
|
||||||
val size = Output(UInt(2.W))
|
val size = Output(UInt(2.W))
|
||||||
val en = Output(Bool())
|
val en = Output(Bool())
|
||||||
val write = Output(Bool())
|
val write = Output(Bool())
|
||||||
val wdata = Output(UInt(DATA_WID.W))
|
val wdata = Output(UInt(XLEN.W))
|
||||||
val ready = Output(Bool())
|
val ready = Output(Bool())
|
||||||
val fence_i = Output(Bool())
|
val fence_i = Output(Bool())
|
||||||
|
|
||||||
val rdata = Input(UInt(DATA_WID.W))
|
val rdata = Input(UInt(XLEN.W))
|
||||||
val valid = Input(Bool())
|
val valid = Input(Bool())
|
||||||
val acc_err = Input(Bool())
|
val acc_err = Input(Bool())
|
||||||
val stall = Input(Bool())
|
val stall = Input(Bool())
|
||||||
|
@ -165,7 +157,7 @@ class R extends Bundle {
|
||||||
val ready = Output(Bool())
|
val ready = Output(Bool())
|
||||||
|
|
||||||
val id = Input(UInt(4.W))
|
val id = Input(UInt(4.W))
|
||||||
val data = Input(UInt(DATA_WID.W))
|
val data = Input(UInt(XLEN.W))
|
||||||
val resp = Input(UInt(2.W))
|
val resp = Input(UInt(2.W))
|
||||||
val last = Input(Bool())
|
val last = Input(Bool())
|
||||||
val valid = Input(Bool())
|
val valid = Input(Bool())
|
||||||
|
@ -187,7 +179,7 @@ class AW extends Bundle {
|
||||||
|
|
||||||
class W extends Bundle {
|
class W extends Bundle {
|
||||||
val id = Output(UInt(4.W))
|
val id = Output(UInt(4.W))
|
||||||
val data = Output(UInt(DATA_WID.W))
|
val data = Output(UInt(XLEN.W))
|
||||||
val strb = Output(UInt(4.W))
|
val strb = Output(UInt(4.W))
|
||||||
val last = Output(Bool())
|
val last = Output(Bool())
|
||||||
val valid = Output(Bool())
|
val valid = Output(Bool())
|
||||||
|
|
|
@ -10,13 +10,12 @@ trait CoreParameter {
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Constants extends CoreParameter {
|
trait Constants extends CoreParameter {
|
||||||
def config = new CpuConfig
|
|
||||||
// 全局
|
// 全局
|
||||||
def PC_WID = XLEN
|
def PC_WID = XLEN
|
||||||
def PC_INIT = "h60000000".U(PC_WID.W)
|
def PC_INIT = "h60000000".U(PC_WID.W)
|
||||||
|
|
||||||
def SINGLE_ISSUE = false.B
|
def SINGLE_ISSUE = false.B
|
||||||
def DUAL_ISSUE = true.B
|
def DUAL_ISSUE = true.B
|
||||||
|
|
||||||
// div
|
// div
|
||||||
def DIV_CTRL_WID = 2
|
def DIV_CTRL_WID = 2
|
||||||
|
|
|
@ -1,128 +1,128 @@
|
||||||
package cpu.defines
|
// package cpu.defines
|
||||||
|
|
||||||
import chisel3._
|
// import chisel3._
|
||||||
import chisel3.util._
|
// import chisel3.util._
|
||||||
import cpu.defines.Const._
|
// import cpu.defines.Const._
|
||||||
|
|
||||||
class CsrIndex extends Bundle {
|
// class CsrIndex extends Bundle {
|
||||||
val p = Bool()
|
// val p = Bool()
|
||||||
val blank = UInt((32 - 1 - log2Ceil(TLB_NUM)).W)
|
// val blank = UInt((32 - 1 - log2Ceil(TLB_NUM)).W)
|
||||||
val index = UInt(log2Ceil(TLB_NUM).W)
|
// val index = UInt(log2Ceil(TLB_NUM).W)
|
||||||
}
|
// }
|
||||||
|
|
||||||
class CsrRandom extends Bundle {
|
// class CsrRandom extends Bundle {
|
||||||
val blank = UInt((32 - log2Ceil(TLB_NUM)).W)
|
// val blank = UInt((32 - log2Ceil(TLB_NUM)).W)
|
||||||
val random = UInt(log2Ceil(TLB_NUM).W)
|
// val random = UInt(log2Ceil(TLB_NUM).W)
|
||||||
}
|
// }
|
||||||
|
|
||||||
class CsrEntryLo extends Bundle {
|
// class CsrEntryLo extends Bundle {
|
||||||
val fill = UInt((32 - PFN_WID - C_WID - 3).W)
|
// val fill = UInt((32 - PFN_WID - C_WID - 3).W)
|
||||||
val pfn = UInt(PFN_WID.W)
|
// val pfn = UInt(PFN_WID.W)
|
||||||
val c = UInt(C_WID.W)
|
// val c = UInt(C_WID.W)
|
||||||
val d = Bool()
|
// val d = Bool()
|
||||||
val v = Bool()
|
// val v = Bool()
|
||||||
val g = Bool()
|
// val g = Bool()
|
||||||
}
|
// }
|
||||||
|
|
||||||
class CsrContext extends Bundle {
|
// class CsrContext extends Bundle {
|
||||||
val ptebase = UInt(PTEBASE_WID.W)
|
// val ptebase = UInt(PTEBASE_WID.W)
|
||||||
val badvpn2 = UInt(VPN2_WID.W)
|
// val badvpn2 = UInt(VPN2_WID.W)
|
||||||
val blank = UInt((32 - PTEBASE_WID - VPN2_WID).W)
|
// val blank = UInt((32 - PTEBASE_WID - VPN2_WID).W)
|
||||||
}
|
// }
|
||||||
|
|
||||||
class CsrWired extends Bundle {
|
// class CsrWired extends Bundle {
|
||||||
val blank = UInt((31 - log2Ceil(TLB_NUM)).W)
|
// val blank = UInt((31 - log2Ceil(TLB_NUM)).W)
|
||||||
val wired = UInt(log2Ceil(TLB_NUM).W)
|
// val wired = UInt(log2Ceil(TLB_NUM).W)
|
||||||
}
|
// }
|
||||||
|
|
||||||
class CsrBadVAddr extends Bundle {
|
// class CsrBadVAddr extends Bundle {
|
||||||
val badvaddr = UInt(PC_WID.W)
|
// val badvaddr = UInt(PC_WID.W)
|
||||||
}
|
// }
|
||||||
|
|
||||||
class CsrCount extends Bundle {
|
// class CsrCount extends Bundle {
|
||||||
val count = UInt(DATA_WID.W)
|
// val count = UInt(DATA_WID.W)
|
||||||
}
|
// }
|
||||||
|
|
||||||
class CsrEntryHi extends Bundle {
|
// class CsrEntryHi extends Bundle {
|
||||||
val vpn2 = UInt(VPN2_WID.W)
|
// val vpn2 = UInt(VPN2_WID.W)
|
||||||
val blank = UInt((32 - VPN2_WID - ASID_WID).W)
|
// val blank = UInt((32 - VPN2_WID - ASID_WID).W)
|
||||||
val asid = UInt(ASID_WID.W)
|
// val asid = UInt(ASID_WID.W)
|
||||||
}
|
// }
|
||||||
|
|
||||||
class CsrCompare extends Bundle {
|
// class CsrCompare extends Bundle {
|
||||||
val compare = UInt(DATA_WID.W)
|
// val compare = UInt(DATA_WID.W)
|
||||||
}
|
// }
|
||||||
|
|
||||||
class CsrStatus extends Bundle {
|
// class CsrStatus extends Bundle {
|
||||||
val blank3 = UInt(3.W)
|
// val blank3 = UInt(3.W)
|
||||||
val cu0 = Bool()
|
// val cu0 = Bool()
|
||||||
val blank2 = UInt(5.W)
|
// val blank2 = UInt(5.W)
|
||||||
val bev = Bool()
|
// val bev = Bool()
|
||||||
val blank1 = UInt(6.W)
|
// val blank1 = UInt(6.W)
|
||||||
val im = UInt(8.W)
|
// val im = UInt(8.W)
|
||||||
val blank0 = UInt(3.W)
|
// val blank0 = UInt(3.W)
|
||||||
val um = Bool()
|
// val um = Bool()
|
||||||
val r0 = Bool()
|
// val r0 = Bool()
|
||||||
val erl = Bool()
|
// val erl = Bool()
|
||||||
val exl = Bool()
|
// val exl = Bool()
|
||||||
val ie = Bool()
|
// val ie = Bool()
|
||||||
}
|
// }
|
||||||
|
|
||||||
class CsrCause extends Bundle {
|
// class CsrCause extends Bundle {
|
||||||
val bd = Bool()
|
// val bd = Bool()
|
||||||
val blank3 = UInt(7.W)
|
// val blank3 = UInt(7.W)
|
||||||
val iv = Bool()
|
// val iv = Bool()
|
||||||
val blank2 = UInt(7.W)
|
// val blank2 = UInt(7.W)
|
||||||
val ip = UInt(8.W)
|
// val ip = UInt(8.W)
|
||||||
val blank1 = Bool()
|
// val blank1 = Bool()
|
||||||
val excode = UInt(5.W)
|
// val excode = UInt(5.W)
|
||||||
val blank0 = UInt(2.W)
|
// val blank0 = UInt(2.W)
|
||||||
}
|
// }
|
||||||
|
|
||||||
class CsrEpc extends Bundle {
|
// class CsrEpc extends Bundle {
|
||||||
val epc = UInt(PC_WID.W)
|
// val epc = UInt(PC_WID.W)
|
||||||
}
|
// }
|
||||||
|
|
||||||
class CsrEbase extends Bundle {
|
// class CsrEbase extends Bundle {
|
||||||
val fill = Bool()
|
// val fill = Bool()
|
||||||
val blank1 = Bool()
|
// val blank1 = Bool()
|
||||||
val ebase = UInt(18.W)
|
// val ebase = UInt(18.W)
|
||||||
val blank0 = UInt(2.W)
|
// val blank0 = UInt(2.W)
|
||||||
val cpuNum = UInt(10.W)
|
// val cpuNum = UInt(10.W)
|
||||||
}
|
// }
|
||||||
|
|
||||||
class CsrConfig extends Bundle {
|
// class CsrConfig extends Bundle {
|
||||||
val m = Bool()
|
// val m = Bool()
|
||||||
val k23 = UInt(3.W)
|
// val k23 = UInt(3.W)
|
||||||
val ku = UInt(3.W)
|
// val ku = UInt(3.W)
|
||||||
val impl = UInt(9.W)
|
// val impl = UInt(9.W)
|
||||||
val be = Bool()
|
// val be = Bool()
|
||||||
val at = UInt(2.W)
|
// val at = UInt(2.W)
|
||||||
val ar = UInt(3.W)
|
// val ar = UInt(3.W)
|
||||||
val mt = UInt(3.W)
|
// val mt = UInt(3.W)
|
||||||
val blank = UInt(3.W)
|
// val blank = UInt(3.W)
|
||||||
val vi = Bool()
|
// val vi = Bool()
|
||||||
val k0 = UInt(3.W)
|
// val k0 = UInt(3.W)
|
||||||
}
|
// }
|
||||||
|
|
||||||
class CsrConfig1 extends Bundle {
|
// class CsrConfig1 extends Bundle {
|
||||||
val m = Bool()
|
// val m = Bool()
|
||||||
val ms = UInt(6.W)
|
// val ms = UInt(6.W)
|
||||||
val is = UInt(3.W)
|
// val is = UInt(3.W)
|
||||||
val il = UInt(3.W)
|
// val il = UInt(3.W)
|
||||||
val ia = UInt(3.W)
|
// val ia = UInt(3.W)
|
||||||
val ds = UInt(3.W)
|
// val ds = UInt(3.W)
|
||||||
val dl = UInt(3.W)
|
// val dl = UInt(3.W)
|
||||||
val da = UInt(3.W)
|
// val da = UInt(3.W)
|
||||||
val c2 = Bool()
|
// val c2 = Bool()
|
||||||
val md = Bool()
|
// val md = Bool()
|
||||||
val pc = Bool()
|
// val pc = Bool()
|
||||||
val wr = Bool()
|
// val wr = Bool()
|
||||||
val ca = Bool()
|
// val ca = Bool()
|
||||||
val ep = Bool()
|
// val ep = Bool()
|
||||||
val fp = Bool()
|
// val fp = Bool()
|
||||||
}
|
// }
|
||||||
|
|
||||||
class CsrErrorEpc extends Bundle {
|
// class CsrErrorEpc extends Bundle {
|
||||||
val errorEpc = UInt(PC_WID.W)
|
// val errorEpc = UInt(PC_WID.W)
|
||||||
}
|
// }
|
||||||
|
|
|
@ -3,9 +3,10 @@ package cpu.pipeline.decoder
|
||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.util._
|
import chisel3.util._
|
||||||
import cpu.defines._
|
import cpu.defines._
|
||||||
|
import cpu.defines.Util._
|
||||||
import cpu.defines.Const._
|
import cpu.defines.Const._
|
||||||
|
|
||||||
class Decoder extends Module {
|
class Decoder extends Module with HasInstrType {
|
||||||
val io = IO(new Bundle {
|
val io = IO(new Bundle {
|
||||||
// inputs
|
// inputs
|
||||||
val in = Input(new Bundle {
|
val in = Input(new Bundle {
|
||||||
|
@ -16,49 +17,55 @@ class Decoder extends Module {
|
||||||
})
|
})
|
||||||
|
|
||||||
val inst = io.in.inst
|
val inst = io.in.inst
|
||||||
|
val instrType :: fuType :: fuOpType :: Nil =
|
||||||
|
ListLookup(inst, Instructions.DecodeDefault, Instructions.DecodeTable)
|
||||||
|
|
||||||
val instrType :: fuType :: fuOpType :: Nil = // insert Instructions.DecodeDefault when interrupt comes
|
val SrcTypeTable = Seq(
|
||||||
Instructions.DecodeDefault.zip(decodeList).map{case (inst, dec) => Mux(hasIntr || io.in.bits.exceptionVec(instrPageFault) || io.out.bits.cf.exceptionVec(instrAccessFault), inst, dec)}
|
InstrI -> (SrcType.reg, SrcType.imm),
|
||||||
|
InstrR -> (SrcType.reg, SrcType.reg),
|
||||||
|
InstrS -> (SrcType.reg, SrcType.reg),
|
||||||
|
InstrSA -> (SrcType.reg, SrcType.reg),
|
||||||
|
InstrB -> (SrcType.reg, SrcType.reg),
|
||||||
|
InstrU -> (SrcType.pc, SrcType.imm),
|
||||||
|
InstrJ -> (SrcType.pc, SrcType.imm),
|
||||||
|
InstrN -> (SrcType.pc, SrcType.imm)
|
||||||
|
)
|
||||||
|
val src1Type = LookupTree(instrType, SrcTypeTable.map(p => (p._1, p._2._1)))
|
||||||
|
val src2Type = LookupTree(instrType, SrcTypeTable.map(p => (p._1, p._2._2)))
|
||||||
|
|
||||||
|
val (rs, rt, rd) = (inst(19, 15), inst(24, 20), inst(11, 7))
|
||||||
|
|
||||||
val rt = inst(20, 16)
|
io.out.inst_valid := instrType === InstrN
|
||||||
val rd = inst(15, 11)
|
io.out.reg1_ren := src1Type === SrcType.reg
|
||||||
val sa = inst(10, 6)
|
|
||||||
val rs = inst(25, 21)
|
|
||||||
val imm16 = inst(15, 0)
|
|
||||||
|
|
||||||
io.out.inst_valid := inst_valid
|
|
||||||
io.out.reg1_ren := reg1_ren
|
|
||||||
io.out.reg1_raddr := rs
|
io.out.reg1_raddr := rs
|
||||||
io.out.reg2_ren := reg2_ren
|
io.out.reg2_ren := src2Type === SrcType.reg
|
||||||
io.out.reg2_raddr := rt
|
io.out.reg2_raddr := rt
|
||||||
io.out.fusel := fusel
|
io.out.fusel := fuType
|
||||||
io.out.op := op
|
io.out.op := fuOpType
|
||||||
io.out.reg_wen := reg_wen
|
when(fuType === FuType.bru) {
|
||||||
io.out.reg_waddr := MuxLookup(reg_waddr_type, AREG_31)( // 取"b11111", 即31号寄存器
|
def isLink(reg: UInt) = (reg === 1.U || reg === 5.U)
|
||||||
|
when(isLink(rd) && fuOpType === ALUOpType.jal) { io.out.op := ALUOpType.call }
|
||||||
|
when(fuOpType === ALUOpType.jalr) {
|
||||||
|
when(isLink(rs)) { io.out.op := ALUOpType.ret }
|
||||||
|
when(isLink(rd)) { io.out.op := ALUOpType.call }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
io.out.reg_wen := isrfWen(instrType)
|
||||||
|
io.out.reg_waddr := Mux(isrfWen(instrType), rd, 0.U)
|
||||||
|
io.out.imm := LookupTree(
|
||||||
|
instrType,
|
||||||
Seq(
|
Seq(
|
||||||
WRA_T1 -> rd, // 取inst(15,11)
|
InstrI -> signedExtend(inst(31, 20), XLEN),
|
||||||
WRA_T2 -> rt // 取inst(20,16)
|
InstrS -> signedExtend(Cat(inst(31, 25), inst(11, 7)), XLEN),
|
||||||
|
InstrSA -> signedExtend(Cat(inst(31, 25), inst(11, 7)), XLEN),
|
||||||
|
InstrB -> signedExtend(Cat(inst(31), inst(7), inst(30, 25), inst(11, 8), 0.U(1.W)), XLEN),
|
||||||
|
InstrU -> signedExtend(Cat(inst(31, 12), 0.U(12.W)), XLEN),
|
||||||
|
InstrJ -> signedExtend(Cat(inst(31), inst(19, 12), inst(20), inst(30, 21), 0.U(1.W)), XLEN)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
io.out.imm32 := MuxLookup(imm_type, Util.zeroExtend(sa))( // default IMM_SHT
|
// io.out.csr_addr := Cat(inst(15, 11), inst(2, 0))
|
||||||
Seq(
|
io.out.dual_issue := false.B
|
||||||
IMM_LSE -> Util.signedExtend(imm16),
|
|
||||||
IMM_LZE -> Util.zeroExtend(imm16),
|
|
||||||
IMM_HZE -> Cat(imm16, Fill(16, 0.U))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
io.out.csr_addr := Cat(inst(15, 11), inst(2, 0))
|
|
||||||
io.out.dual_issue := dual_issue
|
|
||||||
io.out.whilo := VecInit(FU_MUL, FU_DIV, FU_MTHILO).contains(fusel) && op =/= EXE_MUL // MUL不写HILO
|
|
||||||
io.out.inst := inst
|
io.out.inst := inst
|
||||||
io.out.wmem := fusel === FU_MEM && (!reg_wen.orR || op === EXE_SC)
|
io.out.branch_link := VecInit(ALUOpType.jal, ALUOpType.jalr).contains(fuOpType)
|
||||||
io.out.rmem := fusel === FU_MEM && reg_wen.orR
|
|
||||||
io.out.mul := fusel === FU_MUL
|
|
||||||
io.out.div := fusel === FU_DIV
|
|
||||||
io.out.ifence := inst(16) === 0.U && op === EXE_CACHE
|
|
||||||
io.out.dfence := inst(16) === 1.U && op === EXE_CACHE
|
|
||||||
io.out.branch_link := VecInit(EXE_JAL, EXE_JALR, EXE_BGEZAL, EXE_BLTZAL).contains(op)
|
|
||||||
io.out.mem_addr := DontCare
|
io.out.mem_addr := DontCare
|
||||||
io.out.mem_wreg := VecInit(EXE_LB, EXE_LBU, EXE_LH, EXE_LHU, EXE_LW, EXE_LL, EXE_LWL, EXE_LWR).contains(op)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,197 +1,197 @@
|
||||||
package cpu.pipeline.decoder
|
// package cpu.pipeline.decoder
|
||||||
|
|
||||||
import chisel3._
|
// import chisel3._
|
||||||
import chisel3.util._
|
// import chisel3.util._
|
||||||
import cpu.defines._
|
// import cpu.defines._
|
||||||
import cpu.defines.Const._
|
// import cpu.defines.Const._
|
||||||
import cpu.{BranchPredictorConfig, CpuConfig}
|
// import cpu.{BranchPredictorConfig, CpuConfig}
|
||||||
import cpu.pipeline.execute.DecoderUnitExecuteUnit
|
// import cpu.pipeline.execute.DecoderUnitExecuteUnit
|
||||||
import cpu.pipeline.fetch.BufferUnit
|
// import cpu.pipeline.fetch.BufferUnit
|
||||||
|
|
||||||
class InstFifoDecoderUnit(implicit val config: CpuConfig) extends Bundle {
|
// class InstFifoDecoderUnit(implicit val config: CpuConfig) extends Bundle {
|
||||||
val allow_to_go = Output(Vec(config.decoderNum, Bool()))
|
// val allow_to_go = Output(Vec(config.decoderNum, Bool()))
|
||||||
val inst = Input(Vec(config.decoderNum, new BufferUnit()))
|
// val inst = Input(Vec(config.decoderNum, new BufferUnit()))
|
||||||
val info = Input(new Bundle {
|
// val info = Input(new Bundle {
|
||||||
val empty = Bool()
|
// val empty = Bool()
|
||||||
val almost_empty = Bool()
|
// val almost_empty = Bool()
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
class DataForwardToDecoderUnit extends Bundle {
|
// class DataForwardToDecoderUnit extends Bundle {
|
||||||
val exe = new RegWrite()
|
// val exe = new RegWrite()
|
||||||
val mem_wreg = Bool()
|
// val mem_wreg = Bool()
|
||||||
val mem = new RegWrite()
|
// val mem = new RegWrite()
|
||||||
}
|
// }
|
||||||
|
|
||||||
class CsrDecoderUnit extends Bundle {
|
// class CsrDecoderUnit extends Bundle {
|
||||||
val access_allowed = Bool()
|
// val access_allowed = Bool()
|
||||||
val kernel_mode = Bool()
|
// val kernel_mode = Bool()
|
||||||
val intterupt_allowed = Bool()
|
// val intterupt_allowed = Bool()
|
||||||
val cause_ip = UInt(8.W)
|
// val cause_ip = UInt(8.W)
|
||||||
val status_im = UInt(8.W)
|
// val status_im = UInt(8.W)
|
||||||
}
|
// }
|
||||||
|
|
||||||
class DecoderUnit(implicit val config: CpuConfig) extends Module {
|
// class DecoderUnit(implicit val config: CpuConfig) extends Module {
|
||||||
val io = IO(new Bundle {
|
// val io = IO(new Bundle {
|
||||||
// 输入
|
// // 输入
|
||||||
val instFifo = new InstFifoDecoderUnit()
|
// val instFifo = new InstFifoDecoderUnit()
|
||||||
val regfile = Vec(config.decoderNum, new Src12Read())
|
// val regfile = Vec(config.decoderNum, new Src12Read())
|
||||||
val forward = Input(Vec(config.fuNum, new DataForwardToDecoderUnit()))
|
// val forward = Input(Vec(config.fuNum, new DataForwardToDecoderUnit()))
|
||||||
val csr = Input(new CsrDecoderUnit())
|
// val csr = Input(new CsrDecoderUnit())
|
||||||
// 输出
|
// // 输出
|
||||||
val fetchUnit = new Bundle {
|
// val fetchUnit = new Bundle {
|
||||||
val branch = Output(Bool())
|
// val branch = Output(Bool())
|
||||||
val target = Output(UInt(PC_WID.W))
|
// val target = Output(UInt(PC_WID.W))
|
||||||
}
|
// }
|
||||||
val bpu = new Bundle {
|
// val bpu = new Bundle {
|
||||||
val bpuConfig = new BranchPredictorConfig()
|
// val bpuConfig = new BranchPredictorConfig()
|
||||||
val pc = Output(UInt(PC_WID.W))
|
// val pc = Output(UInt(PC_WID.W))
|
||||||
val decoded_inst0 = Output(new InstInfo())
|
// val decoded_inst0 = Output(new InstInfo())
|
||||||
val id_allow_to_go = Output(Bool())
|
// val id_allow_to_go = Output(Bool())
|
||||||
val pht_index = Output(UInt(bpuConfig.phtDepth.W))
|
// val pht_index = Output(UInt(bpuConfig.phtDepth.W))
|
||||||
|
|
||||||
val branch_inst = Input(Bool())
|
// val branch_inst = Input(Bool())
|
||||||
val pred_branch = Input(Bool())
|
// val pred_branch = Input(Bool())
|
||||||
val branch_target = Input(UInt(PC_WID.W))
|
// val branch_target = Input(UInt(PC_WID.W))
|
||||||
val update_pht_index = Input(UInt(bpuConfig.phtDepth.W))
|
// val update_pht_index = Input(UInt(bpuConfig.phtDepth.W))
|
||||||
}
|
// }
|
||||||
val executeStage = Output(new DecoderUnitExecuteUnit())
|
// val executeStage = Output(new DecoderUnitExecuteUnit())
|
||||||
val ctrl = new DecoderUnitCtrl()
|
// val ctrl = new DecoderUnitCtrl()
|
||||||
})
|
// })
|
||||||
|
|
||||||
val issue = Module(new Issue()).io
|
// val issue = Module(new Issue()).io
|
||||||
val decoder = Seq.fill(config.decoderNum)(Module(new Decoder()))
|
// val decoder = Seq.fill(config.decoderNum)(Module(new Decoder()))
|
||||||
val jumpCtrl = Module(new JumpCtrl()).io
|
// val jumpCtrl = Module(new JumpCtrl()).io
|
||||||
val forwardCtrl = Module(new ForwardCtrl()).io
|
// val forwardCtrl = Module(new ForwardCtrl()).io
|
||||||
|
|
||||||
io.regfile(0).src1.raddr := decoder(0).io.out.reg1_raddr
|
// io.regfile(0).src1.raddr := decoder(0).io.out.reg1_raddr
|
||||||
io.regfile(0).src2.raddr := decoder(0).io.out.reg2_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).src1.raddr := decoder(1).io.out.reg1_raddr
|
||||||
io.regfile(1).src2.raddr := decoder(1).io.out.reg2_raddr
|
// io.regfile(1).src2.raddr := decoder(1).io.out.reg2_raddr
|
||||||
|
|
||||||
forwardCtrl.in.forward := io.forward
|
// forwardCtrl.in.forward := io.forward
|
||||||
forwardCtrl.in.regfile := io.regfile // TODO:这里的连接可能有问题
|
// forwardCtrl.in.regfile := io.regfile // TODO:这里的连接可能有问题
|
||||||
|
|
||||||
issue.allow_to_go := io.ctrl.allow_to_go
|
// issue.allow_to_go := io.ctrl.allow_to_go
|
||||||
issue.instFifo := io.instFifo.info
|
// issue.instFifo := io.instFifo.info
|
||||||
|
|
||||||
jumpCtrl.in.allow_to_go := io.ctrl.allow_to_go
|
// jumpCtrl.in.allow_to_go := io.ctrl.allow_to_go
|
||||||
jumpCtrl.in.decoded_inst0 := decoder(0).io.out
|
// jumpCtrl.in.decoded_inst0 := decoder(0).io.out
|
||||||
jumpCtrl.in.forward := io.forward
|
// jumpCtrl.in.forward := io.forward
|
||||||
jumpCtrl.in.pc := io.instFifo.inst(0).pc
|
// jumpCtrl.in.pc := io.instFifo.inst(0).pc
|
||||||
jumpCtrl.in.reg1_data := io.regfile(0).src1.rdata
|
// 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.branch := inst0_branch
|
||||||
io.fetchUnit.target := Mux(io.bpu.pred_branch, io.bpu.branch_target, jumpCtrl.out.jump_target)
|
// 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(0) := io.ctrl.allow_to_go
|
||||||
io.instFifo.allow_to_go(1) := issue.inst1.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.id_allow_to_go := io.ctrl.allow_to_go
|
||||||
io.bpu.pc := io.instFifo.inst(0).pc
|
// io.bpu.pc := io.instFifo.inst(0).pc
|
||||||
io.bpu.decoded_inst0 := decoder(0).io.out
|
// io.bpu.decoded_inst0 := decoder(0).io.out
|
||||||
io.bpu.pht_index := io.instFifo.inst(0).pht_index
|
// 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.ren := decoder(0).io.out.reg1_ren
|
||||||
io.ctrl.inst0.src1.raddr := decoder(0).io.out.reg1_raddr
|
// 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.ren := decoder(0).io.out.reg2_ren
|
||||||
io.ctrl.inst0.src2.raddr := decoder(0).io.out.reg2_raddr
|
// io.ctrl.inst0.src2.raddr := decoder(0).io.out.reg2_raddr
|
||||||
io.ctrl.branch := inst0_branch
|
// io.ctrl.branch := inst0_branch
|
||||||
|
|
||||||
val pc = io.instFifo.inst.map(_.pc)
|
// val pc = io.instFifo.inst.map(_.pc)
|
||||||
val inst = io.instFifo.inst.map(_.inst)
|
// val inst = io.instFifo.inst.map(_.inst)
|
||||||
val inst_info = decoder.map(_.io.out)
|
// 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 interrupt = io.csr.intterupt_allowed && (io.csr.cause_ip & io.csr.status_im).orR && !io.instFifo.info.empty
|
||||||
|
|
||||||
for (i <- 0 until (config.decoderNum)) {
|
// for (i <- 0 until (config.decoderNum)) {
|
||||||
decoder(i).io.in.inst := inst(i)
|
// decoder(i).io.in.inst := inst(i)
|
||||||
issue.decodeInst(i) := inst_info(i)
|
// issue.decodeInst(i) := inst_info(i)
|
||||||
issue.execute(i).mem_wreg := io.forward(i).mem_wreg
|
// issue.execute(i).mem_wreg := io.forward(i).mem_wreg
|
||||||
issue.execute(i).reg_waddr := io.forward(i).exe.waddr
|
// issue.execute(i).reg_waddr := io.forward(i).exe.waddr
|
||||||
}
|
// }
|
||||||
|
|
||||||
io.executeStage.inst0.pc := pc(0)
|
// io.executeStage.inst0.pc := pc(0)
|
||||||
io.executeStage.inst0.inst_info := inst_info(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)(
|
// io.executeStage.inst0.inst_info.reg_wen := MuxLookup(inst_info(0).op, inst_info(0).reg_wen)(
|
||||||
Seq(
|
// Seq(
|
||||||
EXE_MOVN -> (io.executeStage.inst0.src_info.src2_data =/= 0.U),
|
// EXE_MOVN -> (io.executeStage.inst0.src_info.src2_data =/= 0.U),
|
||||||
EXE_MOVZ -> (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.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 + Util.signedExtend(io.executeStage.inst0.inst_info.inst(15, 0))
|
||||||
io.executeStage.inst0.src_info.src1_data := Mux(
|
// io.executeStage.inst0.src_info.src1_data := Mux(
|
||||||
inst_info(0).reg1_ren,
|
// inst_info(0).reg1_ren,
|
||||||
forwardCtrl.out.inst(0).src1.rdata,
|
// forwardCtrl.out.inst(0).src1.rdata,
|
||||||
decoder(0).io.out.imm32
|
// decoder(0).io.out.imm
|
||||||
)
|
// )
|
||||||
io.executeStage.inst0.src_info.src2_data := Mux(
|
// io.executeStage.inst0.src_info.src2_data := Mux(
|
||||||
inst_info(0).reg2_ren,
|
// inst_info(0).reg2_ren,
|
||||||
forwardCtrl.out.inst(0).src2.rdata,
|
// forwardCtrl.out.inst(0).src2.rdata,
|
||||||
decoder(0).io.out.imm32
|
// decoder(0).io.out.imm
|
||||||
)
|
// )
|
||||||
io.executeStage.inst0.ex.flush_req :=
|
// io.executeStage.inst0.ex.flush_req :=
|
||||||
io.executeStage.inst0.ex.excode =/= EX_NO ||
|
// io.executeStage.inst0.ex.excode =/= EX_NO ||
|
||||||
io.executeStage.inst0.ex.eret
|
// io.executeStage.inst0.ex.eret
|
||||||
io.executeStage.inst0.ex.eret := inst_info(0).op === EXE_ERET
|
// io.executeStage.inst0.ex.eret := inst_info(0).op === EXE_ERET
|
||||||
io.executeStage.inst0.ex.badvaddr := pc(0)
|
// io.executeStage.inst0.ex.badvaddr := pc(0)
|
||||||
val inst0_ex_cpu =
|
// 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)
|
// !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)
|
// .contains(inst_info(0).op)
|
||||||
io.executeStage.inst0.ex.excode := MuxCase(
|
// io.executeStage.inst0.ex.excode := MuxCase(
|
||||||
EX_NO,
|
// EX_NO,
|
||||||
Seq(
|
// Seq(
|
||||||
interrupt -> EX_INT,
|
// interrupt -> EX_INT,
|
||||||
(pc(0)(1, 0).orR || (pc(0)(31) && !io.csr.kernel_mode)) -> EX_ADEL,
|
// (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).inst_valid === INST_INVALID) -> EX_RI,
|
||||||
(inst_info(0).op === EXE_SYSCALL) -> EX_SYS,
|
// (inst_info(0).op === EXE_SYSCALL) -> EX_SYS,
|
||||||
(inst_info(0).op === EXE_BREAK) -> EX_BP,
|
// (inst_info(0).op === EXE_BREAK) -> EX_BP,
|
||||||
(inst0_ex_cpu) -> EX_CPU
|
// (inst0_ex_cpu) -> EX_CPU
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
io.executeStage.inst0.jb_info.jump_regiser := jumpCtrl.out.jump_register
|
// 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.branch_inst := io.bpu.branch_inst
|
||||||
io.executeStage.inst0.jb_info.pred_branch := io.bpu.pred_branch
|
// 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.branch_target := io.bpu.branch_target
|
||||||
io.executeStage.inst0.jb_info.update_pht_index := io.bpu.update_pht_index
|
// 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.allow_to_go := issue.inst1.allow_to_go
|
||||||
io.executeStage.inst1.pc := pc(1)
|
// io.executeStage.inst1.pc := pc(1)
|
||||||
io.executeStage.inst1.inst_info := inst_info(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)(
|
// io.executeStage.inst1.inst_info.reg_wen := MuxLookup(inst_info(1).op, inst_info(1).reg_wen)(
|
||||||
Seq(
|
// Seq(
|
||||||
EXE_MOVN -> (io.executeStage.inst1.src_info.src2_data =/= 0.U),
|
// EXE_MOVN -> (io.executeStage.inst1.src_info.src2_data =/= 0.U),
|
||||||
EXE_MOVZ -> (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.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 + Util.signedExtend(io.executeStage.inst1.inst_info.inst(15, 0))
|
||||||
io.executeStage.inst1.src_info.src1_data := Mux(
|
// io.executeStage.inst1.src_info.src1_data := Mux(
|
||||||
inst_info(1).reg1_ren,
|
// inst_info(1).reg1_ren,
|
||||||
forwardCtrl.out.inst(1).src1.rdata,
|
// forwardCtrl.out.inst(1).src1.rdata,
|
||||||
decoder(1).io.out.imm32
|
// decoder(1).io.out.imm
|
||||||
)
|
// )
|
||||||
io.executeStage.inst1.src_info.src2_data := Mux(
|
// io.executeStage.inst1.src_info.src2_data := Mux(
|
||||||
inst_info(1).reg2_ren,
|
// inst_info(1).reg2_ren,
|
||||||
forwardCtrl.out.inst(1).src2.rdata,
|
// forwardCtrl.out.inst(1).src2.rdata,
|
||||||
decoder(1).io.out.imm32
|
// decoder(1).io.out.imm
|
||||||
)
|
// )
|
||||||
io.executeStage.inst1.ex.flush_req := io.executeStage.inst1.ex.excode =/= EX_NO
|
// 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.eret := inst_info(1).op === EXE_ERET
|
||||||
io.executeStage.inst1.ex.badvaddr := pc(1)
|
// io.executeStage.inst1.ex.badvaddr := pc(1)
|
||||||
val inst1_ex_cpu =
|
// 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)
|
// !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)
|
// .contains(inst_info(1).op)
|
||||||
io.executeStage.inst1.ex.excode := MuxCase(
|
// io.executeStage.inst1.ex.excode := MuxCase(
|
||||||
EX_NO,
|
// EX_NO,
|
||||||
Seq(
|
// Seq(
|
||||||
(pc(1)(1, 0).orR || (pc(1)(31) && !io.csr.kernel_mode)) -> EX_ADEL,
|
// (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).inst_valid === INST_INVALID) -> EX_RI,
|
||||||
(inst_info(1).op === EXE_SYSCALL) -> EX_SYS,
|
// (inst_info(1).op === EXE_SYSCALL) -> EX_SYS,
|
||||||
(inst_info(1).op === EXE_BREAK) -> EX_BP,
|
// (inst_info(1).op === EXE_BREAK) -> EX_BP,
|
||||||
(inst1_ex_cpu) -> EX_CPU
|
// (inst1_ex_cpu) -> EX_CPU
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
|
|
@ -1,64 +1,64 @@
|
||||||
package cpu.pipeline.decoder
|
// package cpu.pipeline.decoder
|
||||||
|
|
||||||
import chisel3._
|
// import chisel3._
|
||||||
import chisel3.util._
|
// import chisel3.util._
|
||||||
|
|
||||||
import cpu.defines._
|
// import cpu.defines._
|
||||||
import cpu.defines.Const._
|
// import cpu.defines.Const._
|
||||||
import cpu.CpuConfig
|
// import cpu.CpuConfig
|
||||||
|
|
||||||
class ForwardCtrl(implicit val config: CpuConfig) extends Module {
|
// class ForwardCtrl(implicit val config: CpuConfig) extends Module {
|
||||||
val io = IO(new Bundle {
|
// val io = IO(new Bundle {
|
||||||
val in = Input(new Bundle {
|
// val in = Input(new Bundle {
|
||||||
val forward = Vec(config.fuNum, new DataForwardToDecoderUnit())
|
// val forward = Vec(config.fuNum, new DataForwardToDecoderUnit())
|
||||||
val regfile = Vec(config.decoderNum, new Src12Read())
|
// val regfile = Vec(config.decoderNum, new Src12Read())
|
||||||
})
|
// })
|
||||||
val out = Output(new Bundle {
|
// val out = Output(new Bundle {
|
||||||
val inst = Vec(config.decoderNum, new Src12Read())
|
// val inst = Vec(config.decoderNum, new Src12Read())
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
|
|
||||||
// wb优先度最低
|
// // wb优先度最低
|
||||||
for (i <- 0 until (config.decoderNum)) {
|
// for (i <- 0 until (config.decoderNum)) {
|
||||||
io.out.inst(i).src1.raddr := DontCare
|
// io.out.inst(i).src1.raddr := DontCare
|
||||||
io.out.inst(i).src2.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).src1.rdata := io.in.regfile(i).src1.rdata
|
||||||
io.out.inst(i).src2.rdata := io.in.regfile(i).src2.rdata
|
// io.out.inst(i).src2.rdata := io.in.regfile(i).src2.rdata
|
||||||
}
|
// }
|
||||||
|
|
||||||
// mem优先度中
|
// // mem优先度中
|
||||||
for (i <- 0 until (config.decoderNum)) {
|
// for (i <- 0 until (config.decoderNum)) {
|
||||||
for (j <- 0 until (config.fuNum)) {
|
// for (j <- 0 until (config.fuNum)) {
|
||||||
when(
|
// when(
|
||||||
io.in.forward(j).mem.wen &&
|
// io.in.forward(j).mem.wen &&
|
||||||
io.in.forward(j).mem.waddr === io.in.regfile(i).src1.raddr,
|
// io.in.forward(j).mem.waddr === io.in.regfile(i).src1.raddr,
|
||||||
) {
|
// ) {
|
||||||
io.out.inst(i).src1.rdata := io.in.forward(j).mem.wdata
|
// io.out.inst(i).src1.rdata := io.in.forward(j).mem.wdata
|
||||||
}
|
// }
|
||||||
when(
|
// when(
|
||||||
io.in.forward(j).mem.wen &&
|
// io.in.forward(j).mem.wen &&
|
||||||
io.in.forward(j).mem.waddr === io.in.regfile(i).src2.raddr,
|
// io.in.forward(j).mem.waddr === io.in.regfile(i).src2.raddr,
|
||||||
) {
|
// ) {
|
||||||
io.out.inst(i).src2.rdata := io.in.forward(j).mem.wdata
|
// io.out.inst(i).src2.rdata := io.in.forward(j).mem.wdata
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// exe优先度高
|
// // exe优先度高
|
||||||
for (i <- 0 until (config.decoderNum)) {
|
// for (i <- 0 until (config.decoderNum)) {
|
||||||
for (j <- 0 until (config.fuNum)) {
|
// for (j <- 0 until (config.fuNum)) {
|
||||||
when(
|
// when(
|
||||||
io.in.forward(j).exe.wen && !io.in.forward(j).mem_wreg &&
|
// io.in.forward(j).exe.wen && !io.in.forward(j).mem_wreg &&
|
||||||
io.in.forward(j).exe.waddr === io.in.regfile(i).src1.raddr,
|
// io.in.forward(j).exe.waddr === io.in.regfile(i).src1.raddr,
|
||||||
) {
|
// ) {
|
||||||
io.out.inst(i).src1.rdata := io.in.forward(j).exe.wdata
|
// io.out.inst(i).src1.rdata := io.in.forward(j).exe.wdata
|
||||||
}
|
// }
|
||||||
when(
|
// when(
|
||||||
io.in.forward(j).exe.wen && !io.in.forward(j).mem_wreg &&
|
// io.in.forward(j).exe.wen && !io.in.forward(j).mem_wreg &&
|
||||||
io.in.forward(j).exe.waddr === io.in.regfile(i).src2.raddr,
|
// io.in.forward(j).exe.waddr === io.in.regfile(i).src2.raddr,
|
||||||
) {
|
// ) {
|
||||||
io.out.inst(i).src2.rdata := io.in.forward(j).exe.wdata
|
// io.out.inst(i).src2.rdata := io.in.forward(j).exe.wdata
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
|
@ -1,59 +1,59 @@
|
||||||
package cpu.pipeline.decoder
|
// package cpu.pipeline.decoder
|
||||||
|
|
||||||
import chisel3._
|
// import chisel3._
|
||||||
import chisel3.util._
|
// import chisel3.util._
|
||||||
import cpu.defines._
|
// import cpu.defines._
|
||||||
import cpu.defines.Const._
|
// import cpu.defines.Const._
|
||||||
import cpu.CpuConfig
|
// import cpu.CpuConfig
|
||||||
|
|
||||||
class Issue(implicit val config: CpuConfig) extends Module {
|
// class Issue(implicit val config: CpuConfig) extends Module {
|
||||||
val io = IO(new Bundle {
|
// val io = IO(new Bundle {
|
||||||
// 输入
|
// // 输入
|
||||||
val allow_to_go = Input(Bool())
|
// val allow_to_go = Input(Bool())
|
||||||
val instFifo = Input(new Bundle {
|
// val instFifo = Input(new Bundle {
|
||||||
val empty = Bool()
|
// val empty = Bool()
|
||||||
val almost_empty = Bool()
|
// val almost_empty = Bool()
|
||||||
})
|
// })
|
||||||
val decodeInst = Input(Vec(config.decoderNum, new InstInfo()))
|
// val decodeInst = Input(Vec(config.decoderNum, new InstInfo()))
|
||||||
val execute = Input(Vec(config.fuNum, new MemRead()))
|
// val execute = Input(Vec(config.fuNum, new MemRead()))
|
||||||
// 输出
|
// // 输出
|
||||||
val inst1 = Output(new Bundle {
|
// val inst1 = Output(new Bundle {
|
||||||
val allow_to_go = Bool()
|
// val allow_to_go = Bool()
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
|
|
||||||
val inst0 = io.decodeInst(0)
|
// val inst0 = io.decodeInst(0)
|
||||||
val inst1 = io.decodeInst(1)
|
// val inst1 = io.decodeInst(1)
|
||||||
|
|
||||||
// inst buffer是否存有至少2条指令
|
// // inst buffer是否存有至少2条指令
|
||||||
val instFifo_invalid = io.instFifo.empty || io.instFifo.almost_empty
|
// val instFifo_invalid = io.instFifo.empty || io.instFifo.almost_empty
|
||||||
|
|
||||||
// 结构冲突
|
// // 结构冲突
|
||||||
val mem_conflict = inst0.fusel === FU_MEM && inst1.fusel === FU_MEM
|
// val mem_conflict = inst0.fusel === FU_MEM && inst1.fusel === FU_MEM
|
||||||
val mul_conflict = inst0.fusel === FU_MUL && inst1.fusel === FU_MUL
|
// val mul_conflict = inst0.fusel === FU_MUL && inst1.fusel === FU_MUL
|
||||||
val div_conflict = inst0.fusel === FU_DIV && inst1.fusel === FU_DIV
|
// val div_conflict = inst0.fusel === FU_DIV && inst1.fusel === FU_DIV
|
||||||
val struct_conflict = mem_conflict || mul_conflict || div_conflict
|
// val struct_conflict = mem_conflict || mul_conflict || div_conflict
|
||||||
|
|
||||||
// 写后读冲突
|
// // 写后读冲突
|
||||||
val load_stall =
|
// val load_stall =
|
||||||
io.execute(0).mem_wreg && (inst1.reg1_ren && inst1.reg1_raddr === io.execute(0).reg_waddr ||
|
// io.execute(0).mem_wreg && (inst1.reg1_ren && inst1.reg1_raddr === io.execute(0).reg_waddr ||
|
||||||
inst1.reg2_ren && inst1.reg2_raddr === io.execute(0).reg_waddr) ||
|
// inst1.reg2_ren && inst1.reg2_raddr === io.execute(0).reg_waddr) ||
|
||||||
io.execute(1).mem_wreg && (inst1.reg1_ren && inst1.reg1_raddr === io.execute(1).reg_waddr ||
|
// io.execute(1).mem_wreg && (inst1.reg1_ren && inst1.reg1_raddr === io.execute(1).reg_waddr ||
|
||||||
inst1.reg2_ren && inst1.reg2_raddr === io.execute(1).reg_waddr)
|
// inst1.reg2_ren && inst1.reg2_raddr === io.execute(1).reg_waddr)
|
||||||
val raw_reg =
|
// val raw_reg =
|
||||||
inst0.reg_wen && (inst0.reg_waddr === inst1.reg1_raddr && inst1.reg1_ren || inst0.reg_waddr === inst1.reg2_raddr && inst1.reg2_ren)
|
// inst0.reg_wen && (inst0.reg_waddr === inst1.reg1_raddr && inst1.reg1_ren || inst0.reg_waddr === inst1.reg2_raddr && inst1.reg2_ren)
|
||||||
val raw_hilo = VecInit(FU_DIV, FU_MUL, FU_MTHILO).contains(inst0.fusel) &&
|
// val raw_hilo = VecInit(FU_DIV, FU_MUL, FU_MTHILO).contains(inst0.fusel) &&
|
||||||
VecInit(FU_DIV, FU_MUL, FU_MFHILO, FU_MTHILO).contains(inst1.fusel)
|
// VecInit(FU_DIV, FU_MUL, FU_MFHILO, FU_MTHILO).contains(inst1.fusel)
|
||||||
val raw_csr =
|
// val raw_csr =
|
||||||
inst0.op === EXE_MTC0 && inst1.op === EXE_MFC0 && inst0.csr_addr === inst1.csr_addr
|
// inst0.op === EXE_MTC0 && inst1.op === EXE_MFC0 && inst0.csr_addr === inst1.csr_addr
|
||||||
val data_conflict = raw_reg || raw_hilo || raw_csr || load_stall
|
// val data_conflict = raw_reg || raw_hilo || raw_csr || load_stall
|
||||||
|
|
||||||
// 指令1是否允许执行
|
// // 指令1是否允许执行
|
||||||
io.inst1.allow_to_go := io.allow_to_go &&
|
// io.inst1.allow_to_go := io.allow_to_go &&
|
||||||
!instFifo_invalid &&
|
// !instFifo_invalid &&
|
||||||
inst0.dual_issue &&
|
// inst0.dual_issue &&
|
||||||
inst1.dual_issue &&
|
// inst1.dual_issue &&
|
||||||
!struct_conflict &&
|
// !struct_conflict &&
|
||||||
!data_conflict &&
|
// !data_conflict &&
|
||||||
!VecInit(FU_BR, FU_EX).contains(io.decodeInst(1).fusel)
|
// !VecInit(FU_BR, FU_EX).contains(io.decodeInst(1).fusel)
|
||||||
}
|
// }
|
||||||
|
|
|
@ -1,43 +1,43 @@
|
||||||
package cpu.pipeline.decoder
|
// package cpu.pipeline.decoder
|
||||||
|
|
||||||
import chisel3._
|
// import chisel3._
|
||||||
import chisel3.util._
|
// import chisel3.util._
|
||||||
|
|
||||||
import cpu.defines._
|
// import cpu.defines._
|
||||||
import cpu.defines.Const._
|
// import cpu.defines.Const._
|
||||||
import cpu.CpuConfig
|
// import cpu.CpuConfig
|
||||||
|
|
||||||
class JumpCtrl(implicit val config: CpuConfig) extends Module {
|
// class JumpCtrl(implicit val config: CpuConfig) extends Module {
|
||||||
val io = IO(new Bundle {
|
// val io = IO(new Bundle {
|
||||||
val in = Input(new Bundle {
|
// val in = Input(new Bundle {
|
||||||
val allow_to_go = Bool()
|
// val allow_to_go = Bool()
|
||||||
val pc = UInt(PC_WID.W)
|
// val pc = UInt(PC_WID.W)
|
||||||
val decoded_inst0 = new InstInfo()
|
// val decoded_inst0 = new InstInfo()
|
||||||
val reg1_data = UInt(DATA_WID.W)
|
// val reg1_data = UInt(DATA_WID.W)
|
||||||
val forward = Vec(config.fuNum, new DataForwardToDecoderUnit())
|
// val forward = Vec(config.fuNum, new DataForwardToDecoderUnit())
|
||||||
})
|
// })
|
||||||
val out = Output(new Bundle {
|
// val out = Output(new Bundle {
|
||||||
val jump_inst = Bool()
|
// val jump_inst = Bool()
|
||||||
val jump_register = Bool()
|
// val jump_register = Bool()
|
||||||
val jump = Bool()
|
// val jump = Bool()
|
||||||
val jump_target = UInt(PC_WID.W)
|
// val jump_target = UInt(PC_WID.W)
|
||||||
})
|
// })
|
||||||
})
|
// })
|
||||||
|
|
||||||
val op = io.in.decoded_inst0.op
|
// val op = io.in.decoded_inst0.op
|
||||||
val jump_inst = VecInit(EXE_J, EXE_JAL).contains(op)
|
// val jump_inst = VecInit(EXE_J, EXE_JAL).contains(op)
|
||||||
val jump_register_inst = VecInit(EXE_JR, EXE_JALR).contains(op)
|
// val jump_register_inst = VecInit(EXE_JR, EXE_JALR).contains(op)
|
||||||
io.out.jump_inst := jump_inst || jump_register_inst
|
// io.out.jump_inst := jump_inst || jump_register_inst
|
||||||
io.out.jump := io.in.allow_to_go && (jump_inst || jump_register_inst && !io.out.jump_register)
|
// io.out.jump := io.in.allow_to_go && (jump_inst || jump_register_inst && !io.out.jump_register)
|
||||||
io.out.jump_register := jump_register_inst &&
|
// io.out.jump_register := jump_register_inst &&
|
||||||
((io.in.forward(0).exe.wen && io.in.decoded_inst0.reg1_raddr === io.in.forward(0).exe.waddr) ||
|
// ((io.in.forward(0).exe.wen && io.in.decoded_inst0.reg1_raddr === io.in.forward(0).exe.waddr) ||
|
||||||
(io.in.forward(1).exe.wen && io.in.decoded_inst0.reg1_raddr === io.in.forward(1).exe.waddr) ||
|
// (io.in.forward(1).exe.wen && io.in.decoded_inst0.reg1_raddr === io.in.forward(1).exe.waddr) ||
|
||||||
(io.in.forward(0).mem.wen && io.in.decoded_inst0.reg1_raddr === io.in.forward(0).mem.waddr) ||
|
// (io.in.forward(0).mem.wen && io.in.decoded_inst0.reg1_raddr === io.in.forward(0).mem.waddr) ||
|
||||||
(io.in.forward(1).mem.wen && io.in.decoded_inst0.reg1_raddr === io.in.forward(1).mem.waddr))
|
// (io.in.forward(1).mem.wen && io.in.decoded_inst0.reg1_raddr === io.in.forward(1).mem.waddr))
|
||||||
val pc_plus_4 = io.in.pc + 4.U(PC_WID.W)
|
// val pc_plus_4 = io.in.pc + 4.U(PC_WID.W)
|
||||||
io.out.jump_target := Mux(
|
// io.out.jump_target := Mux(
|
||||||
jump_inst,
|
// jump_inst,
|
||||||
Cat(pc_plus_4(31, 28), io.in.decoded_inst0.inst(25, 0), 0.U(2.W)),
|
// Cat(pc_plus_4(31, 28), io.in.decoded_inst0.inst(25, 0), 0.U(2.W)),
|
||||||
io.in.reg1_data,
|
// io.in.reg1_data,
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
|
|
@ -1,135 +1,135 @@
|
||||||
package cpu.pipeline.execute
|
// package cpu.pipeline.execute
|
||||||
|
|
||||||
import chisel3._
|
// import chisel3._
|
||||||
import chisel3.util._
|
// import chisel3.util._
|
||||||
import cpu.defines._
|
// import cpu.defines._
|
||||||
import cpu.defines.Const._
|
// import cpu.defines.Const._
|
||||||
|
|
||||||
class DivSignal extends Bundle {
|
// class DivSignal extends Bundle {
|
||||||
val ready = Input(Bool())
|
// val ready = Input(Bool())
|
||||||
val result = Input(UInt(HILO_WID.W))
|
// val result = Input(UInt(HILO_WID.W))
|
||||||
|
|
||||||
val en = Output(Bool())
|
// val en = Output(Bool())
|
||||||
val signed = Output(Bool())
|
// val signed = Output(Bool())
|
||||||
}
|
// }
|
||||||
class MultSignal extends Bundle {
|
// class MultSignal extends Bundle {
|
||||||
val ready = Input(Bool())
|
// val ready = Input(Bool())
|
||||||
val result = Input(UInt(HILO_WID.W))
|
// val result = Input(UInt(HILO_WID.W))
|
||||||
|
|
||||||
val en = Output(Bool())
|
// val en = Output(Bool())
|
||||||
val signed = Output(Bool())
|
// val signed = Output(Bool())
|
||||||
}
|
// }
|
||||||
class Alu extends Module {
|
// class Alu extends Module {
|
||||||
val io = IO(new Bundle {
|
// val io = IO(new Bundle {
|
||||||
val inst_info = Input(new InstInfo())
|
// val inst_info = Input(new InstInfo())
|
||||||
val src_info = Input(new SrcInfo())
|
// val src_info = Input(new SrcInfo())
|
||||||
val csr_rdata = Input(UInt(DATA_WID.W))
|
// val csr_rdata = Input(UInt(DATA_WID.W))
|
||||||
val llbit = Input(Bool())
|
// val llbit = Input(Bool())
|
||||||
val hilo = new Bundle {
|
// val hilo = new Bundle {
|
||||||
val rdata = Input(UInt(HILO_WID.W))
|
// val rdata = Input(UInt(HILO_WID.W))
|
||||||
val wdata = Output(UInt(HILO_WID.W))
|
// val wdata = Output(UInt(HILO_WID.W))
|
||||||
}
|
// }
|
||||||
val mul = new MultSignal()
|
// val mul = new MultSignal()
|
||||||
val div = new DivSignal()
|
// val div = new DivSignal()
|
||||||
val result = Output(UInt(DATA_WID.W))
|
// val result = Output(UInt(DATA_WID.W))
|
||||||
val overflow = Output(Bool())
|
// val overflow = Output(Bool())
|
||||||
val trap = Output(Bool())
|
// val trap = Output(Bool())
|
||||||
})
|
// })
|
||||||
val op = io.inst_info.op
|
// val op = io.inst_info.op
|
||||||
val src1 = io.src_info.src1_data
|
// val src1 = io.src_info.src1_data
|
||||||
val src2 = io.src_info.src2_data
|
// val src2 = io.src_info.src2_data
|
||||||
|
|
||||||
val sum = src1 + src2
|
// val sum = src1 + src2
|
||||||
val diff = src1 - src2
|
// val diff = src1 - src2
|
||||||
val slt = src1.asSInt < src2.asSInt
|
// val slt = src1.asSInt < src2.asSInt
|
||||||
val sltu = src1 < src2
|
// val sltu = src1 < src2
|
||||||
val clo = WireInit(32.U)
|
// val clo = WireInit(32.U)
|
||||||
val clz = WireInit(32.U)
|
// val clz = WireInit(32.U)
|
||||||
for (i <- 0 until 32) {
|
// for (i <- 0 until 32) {
|
||||||
when(!src1(i)) {
|
// when(!src1(i)) {
|
||||||
clo := (31 - i).U
|
// clo := (31 - i).U
|
||||||
}.otherwise {
|
// }.otherwise {
|
||||||
clz := (31 - i).U
|
// clz := (31 - i).U
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
val hilo = io.hilo.rdata
|
// val hilo = io.hilo.rdata
|
||||||
|
|
||||||
io.hilo.wdata := MuxLookup(op, 0.U)(
|
// io.hilo.wdata := MuxLookup(op, 0.U)(
|
||||||
Seq(
|
// Seq(
|
||||||
EXE_MTHI -> Cat(src1, hilo(31, 0)),
|
// EXE_MTHI -> Cat(src1, hilo(31, 0)),
|
||||||
EXE_MTLO -> Cat(hilo(63, 32), src1),
|
// EXE_MTLO -> Cat(hilo(63, 32), src1),
|
||||||
EXE_MULT -> Mux(io.mul.ready, io.mul.result, 0.U),
|
// EXE_MULT -> Mux(io.mul.ready, io.mul.result, 0.U),
|
||||||
EXE_MULTU -> Mux(io.mul.ready, io.mul.result, 0.U),
|
// EXE_MULTU -> Mux(io.mul.ready, io.mul.result, 0.U),
|
||||||
EXE_MADD -> Mux(io.mul.ready, hilo + io.mul.result, 0.U),
|
// EXE_MADD -> Mux(io.mul.ready, hilo + io.mul.result, 0.U),
|
||||||
EXE_MADDU -> Mux(io.mul.ready, hilo + io.mul.result, 0.U),
|
// EXE_MADDU -> Mux(io.mul.ready, hilo + io.mul.result, 0.U),
|
||||||
EXE_MSUB -> Mux(io.mul.ready, hilo - io.mul.result, 0.U),
|
// EXE_MSUB -> Mux(io.mul.ready, hilo - io.mul.result, 0.U),
|
||||||
EXE_MSUBU -> Mux(io.mul.ready, hilo - io.mul.result, 0.U),
|
// EXE_MSUBU -> Mux(io.mul.ready, hilo - io.mul.result, 0.U),
|
||||||
EXE_DIV -> Mux(io.div.ready, io.div.result, 0.U),
|
// EXE_DIV -> Mux(io.div.ready, io.div.result, 0.U),
|
||||||
EXE_DIVU -> Mux(io.div.ready, io.div.result, 0.U)
|
// EXE_DIVU -> Mux(io.div.ready, io.div.result, 0.U)
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
|
|
||||||
io.mul.signed := VecInit(EXE_MULT, EXE_MUL, EXE_MADD, EXE_MSUB).contains(op)
|
// io.mul.signed := VecInit(EXE_MULT, EXE_MUL, EXE_MADD, EXE_MSUB).contains(op)
|
||||||
io.mul.en := Mux(
|
// io.mul.en := Mux(
|
||||||
VecInit(EXE_MUL, EXE_MULT, EXE_MULTU, EXE_MADD, EXE_MSUB, EXE_MADDU, EXE_MSUBU).contains(op),
|
// VecInit(EXE_MUL, EXE_MULT, EXE_MULTU, EXE_MADD, EXE_MSUB, EXE_MADDU, EXE_MSUBU).contains(op),
|
||||||
!io.mul.ready,
|
// !io.mul.ready,
|
||||||
false.B
|
// false.B
|
||||||
)
|
// )
|
||||||
io.div.signed := VecInit(EXE_DIV).contains(op)
|
// io.div.signed := VecInit(EXE_DIV).contains(op)
|
||||||
io.div.en := Mux(VecInit(EXE_DIV, EXE_DIVU).contains(op), !io.div.ready, false.B)
|
// io.div.en := Mux(VecInit(EXE_DIV, EXE_DIVU).contains(op), !io.div.ready, false.B)
|
||||||
|
|
||||||
io.result := MuxLookup(op, 0.U)(
|
// io.result := MuxLookup(op, 0.U)(
|
||||||
Seq(
|
// Seq(
|
||||||
// 算数指令
|
// // 算数指令
|
||||||
EXE_ADD -> sum,
|
// EXE_ADD -> sum,
|
||||||
EXE_ADDU -> sum,
|
// EXE_ADDU -> sum,
|
||||||
EXE_SUB -> diff,
|
// EXE_SUB -> diff,
|
||||||
EXE_SUBU -> diff,
|
// EXE_SUBU -> diff,
|
||||||
EXE_SLT -> slt,
|
// EXE_SLT -> slt,
|
||||||
EXE_SLTU -> sltu,
|
// EXE_SLTU -> sltu,
|
||||||
// 逻辑指令
|
// // 逻辑指令
|
||||||
EXE_AND -> (src1 & src2),
|
// EXE_AND -> (src1 & src2),
|
||||||
EXE_OR -> (src1 | src2),
|
// EXE_OR -> (src1 | src2),
|
||||||
EXE_NOR -> (~(src1 | src2)),
|
// EXE_NOR -> (~(src1 | src2)),
|
||||||
EXE_XOR -> (src1 ^ src2),
|
// EXE_XOR -> (src1 ^ src2),
|
||||||
// 移位指令
|
// // 移位指令
|
||||||
EXE_SLL -> (src2 << src1(4, 0)),
|
// EXE_SLL -> (src2 << src1(4, 0)),
|
||||||
EXE_SRL -> (src2 >> src1(4, 0)),
|
// EXE_SRL -> (src2 >> src1(4, 0)),
|
||||||
EXE_SRA -> ((src2.asSInt >> src1(4, 0)).asUInt),
|
// EXE_SRA -> ((src2.asSInt >> src1(4, 0)).asUInt),
|
||||||
// 数据移动指令
|
// // 数据移动指令
|
||||||
EXE_MFHI -> io.hilo.rdata(63, 32),
|
// EXE_MFHI -> io.hilo.rdata(63, 32),
|
||||||
EXE_MFLO -> io.hilo.rdata(31, 0),
|
// EXE_MFLO -> io.hilo.rdata(31, 0),
|
||||||
EXE_MFC0 -> io.csr_rdata,
|
// EXE_MFC0 -> io.csr_rdata,
|
||||||
EXE_MOVN -> src1,
|
// EXE_MOVN -> src1,
|
||||||
EXE_MOVZ -> src1,
|
// EXE_MOVZ -> src1,
|
||||||
// 前导记数指令
|
// // 前导记数指令
|
||||||
EXE_CLZ -> clz,
|
// EXE_CLZ -> clz,
|
||||||
EXE_CLO -> clo,
|
// EXE_CLO -> clo,
|
||||||
// 特殊指令
|
// // 特殊指令
|
||||||
EXE_SC -> io.llbit,
|
// EXE_SC -> io.llbit,
|
||||||
// 乘除法
|
// // 乘除法
|
||||||
EXE_MUL -> Mux(io.mul.ready, io.mul.result(31, 0), 0.U),
|
// EXE_MUL -> Mux(io.mul.ready, io.mul.result(31, 0), 0.U),
|
||||||
EXE_MULT -> Mux(io.mul.ready, io.mul.result(31, 0), 0.U),
|
// EXE_MULT -> Mux(io.mul.ready, io.mul.result(31, 0), 0.U),
|
||||||
EXE_MULTU -> Mux(io.mul.ready, io.mul.result(31, 0), 0.U)
|
// EXE_MULTU -> Mux(io.mul.ready, io.mul.result(31, 0), 0.U)
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
|
|
||||||
io.overflow := MuxLookup(op, false.B)(
|
// io.overflow := MuxLookup(op, false.B)(
|
||||||
Seq(
|
// Seq(
|
||||||
EXE_ADD -> ((src1(31) === src2(31)) & (src1(31) =/= sum(31))),
|
// EXE_ADD -> ((src1(31) === src2(31)) & (src1(31) =/= sum(31))),
|
||||||
EXE_SUB -> ((src1(31) =/= src2(31)) & (src1(31) =/= diff(31)))
|
// EXE_SUB -> ((src1(31) =/= src2(31)) & (src1(31) =/= diff(31)))
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
|
|
||||||
io.trap := MuxLookup(op, false.B)(
|
// io.trap := MuxLookup(op, false.B)(
|
||||||
Seq(
|
// Seq(
|
||||||
EXE_TEQ -> (src1 === src2),
|
// EXE_TEQ -> (src1 === src2),
|
||||||
EXE_TNE -> (src1 =/= src2),
|
// EXE_TNE -> (src1 =/= src2),
|
||||||
EXE_TGE -> !slt,
|
// EXE_TGE -> !slt,
|
||||||
EXE_TGEU -> !sltu,
|
// EXE_TGEU -> !sltu,
|
||||||
EXE_TLT -> slt,
|
// EXE_TLT -> slt,
|
||||||
EXE_TLTU -> sltu
|
// EXE_TLTU -> sltu
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
|
|
@ -1,35 +1,35 @@
|
||||||
package cpu.pipeline.execute
|
// package cpu.pipeline.execute
|
||||||
|
|
||||||
import chisel3._
|
// import chisel3._
|
||||||
import chisel3.util._
|
// import chisel3.util._
|
||||||
import cpu.defines._
|
// import cpu.defines._
|
||||||
import cpu.defines.Const._
|
// 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 inst_info = Input(new InstInfo())
|
// val inst_info = Input(new InstInfo())
|
||||||
val src_info = Input(new SrcInfo())
|
// val src_info = Input(new SrcInfo())
|
||||||
val pred_branch = Input(Bool())
|
// val pred_branch = Input(Bool())
|
||||||
}
|
// }
|
||||||
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 src1 = io.in.src_info.src1_data
|
// val src1 = io.in.src_info.src1_data
|
||||||
val src2 = io.in.src_info.src2_data
|
// val src2 = io.in.src_info.src2_data
|
||||||
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 := MuxLookup(io.in.inst_info.op, false.B)(
|
// io.out.branch := MuxLookup(io.in.inst_info.op, false.B)(
|
||||||
Seq(
|
// Seq(
|
||||||
EXE_BEQ -> (src1 === src2),
|
// EXE_BEQ -> (src1 === src2),
|
||||||
EXE_BNE -> (src1 =/= src2),
|
// EXE_BNE -> (src1 =/= src2),
|
||||||
EXE_BGTZ -> (!src1(31) && (src1 =/= 0.U)),
|
// EXE_BGTZ -> (!src1(31) && (src1 =/= 0.U)),
|
||||||
EXE_BLEZ -> (src1(31) || src1 === 0.U),
|
// EXE_BLEZ -> (src1(31) || src1 === 0.U),
|
||||||
EXE_BGEZ -> (!src1(31)),
|
// EXE_BGEZ -> (!src1(31)),
|
||||||
EXE_BGEZAL -> (!src1(31)),
|
// EXE_BGEZAL -> (!src1(31)),
|
||||||
EXE_BLTZ -> (src1(31)),
|
// EXE_BLTZ -> (src1(31)),
|
||||||
EXE_BLTZAL -> (src1(31))
|
// EXE_BLTZAL -> (src1(31))
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
|
|
@ -1,368 +1,368 @@
|
||||||
package cpu.pipeline.execute
|
// package cpu.pipeline.execute
|
||||||
|
|
||||||
import chisel3._
|
// import chisel3._
|
||||||
import chisel3.util._
|
// import chisel3.util._
|
||||||
import cpu.defines._
|
// import cpu.defines._
|
||||||
import cpu.defines.Const._
|
// import cpu.defines.Const._
|
||||||
import cpu.pipeline.memory.CsrInfo
|
// import cpu.pipeline.memory.CsrInfo
|
||||||
import cpu.CpuConfig
|
// import cpu.CpuConfig
|
||||||
import cpu.pipeline.decoder.CsrDecoderUnit
|
// import cpu.pipeline.decoder.CsrDecoderUnit
|
||||||
|
|
||||||
class CsrMemoryUnit(implicit val config: CpuConfig) extends Bundle {
|
// class CsrMemoryUnit(implicit val config: CpuConfig) extends Bundle {
|
||||||
val in = Input(new Bundle {
|
// val in = Input(new Bundle {
|
||||||
val inst = Vec(
|
// val inst = Vec(
|
||||||
config.fuNum,
|
// config.fuNum,
|
||||||
new Bundle {
|
// new Bundle {
|
||||||
val pc = UInt(PC_WID.W)
|
// val pc = UInt(PC_WID.W)
|
||||||
val ex = new ExceptionInfo()
|
// val ex = new ExceptionInfo()
|
||||||
}
|
// }
|
||||||
)
|
// )
|
||||||
})
|
// })
|
||||||
val out = Output(new Bundle {
|
// val out = Output(new Bundle {
|
||||||
val flush = Bool()
|
// val flush = Bool()
|
||||||
val flush_pc = UInt(PC_WID.W)
|
// val flush_pc = UInt(PC_WID.W)
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
class CsrExecuteUnit(implicit val config: CpuConfig) extends Bundle {
|
// class CsrExecuteUnit(implicit val config: CpuConfig) extends Bundle {
|
||||||
val in = Input(new Bundle {
|
// val in = Input(new Bundle {
|
||||||
val inst_info = Vec(config.fuNum, new InstInfo())
|
// val inst_info = Vec(config.fuNum, new InstInfo())
|
||||||
val mtc0_wdata = UInt(DATA_WID.W)
|
// val mtc0_wdata = UInt(DATA_WID.W)
|
||||||
})
|
// })
|
||||||
val out = Output(new Bundle {
|
// val out = Output(new Bundle {
|
||||||
val csr_rdata = Vec(config.fuNum, UInt(DATA_WID.W))
|
// val csr_rdata = Vec(config.fuNum, UInt(DATA_WID.W))
|
||||||
val debug = Output(new CsrInfo())
|
// val debug = Output(new CsrInfo())
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
class Csr(implicit val config: CpuConfig) extends Module {
|
// class Csr(implicit val config: CpuConfig) extends Module {
|
||||||
val io = IO(new Bundle {
|
// val io = IO(new Bundle {
|
||||||
val ext_int = Input(UInt(EXT_INT_WID.W))
|
// val ext_int = Input(UInt(EXT_INT_WID.W))
|
||||||
val ctrl = Input(new Bundle {
|
// val ctrl = Input(new Bundle {
|
||||||
val exe_stall = Bool()
|
// val exe_stall = Bool()
|
||||||
val mem_stall = Bool()
|
// val mem_stall = Bool()
|
||||||
})
|
// })
|
||||||
val decoderUnit = Output(new CsrDecoderUnit())
|
// val decoderUnit = Output(new CsrDecoderUnit())
|
||||||
val executeUnit = new CsrExecuteUnit()
|
// val executeUnit = new CsrExecuteUnit()
|
||||||
val memoryUnit = new CsrMemoryUnit()
|
// val memoryUnit = new CsrMemoryUnit()
|
||||||
})
|
// })
|
||||||
// 优先使用inst0的信息
|
// // 优先使用inst0的信息
|
||||||
val ex_sel = io.memoryUnit.in.inst(0).ex.flush_req || !io.memoryUnit.in.inst(1).ex.flush_req
|
// val ex_sel = io.memoryUnit.in.inst(0).ex.flush_req || !io.memoryUnit.in.inst(1).ex.flush_req
|
||||||
val pc = Mux(ex_sel, io.memoryUnit.in.inst(0).pc, io.memoryUnit.in.inst(1).pc)
|
// val pc = Mux(ex_sel, io.memoryUnit.in.inst(0).pc, io.memoryUnit.in.inst(1).pc)
|
||||||
val ex = Mux(ex_sel, io.memoryUnit.in.inst(0).ex, io.memoryUnit.in.inst(1).ex)
|
// val ex = Mux(ex_sel, io.memoryUnit.in.inst(0).ex, io.memoryUnit.in.inst(1).ex)
|
||||||
val mtc0_wen = io.executeUnit.in.inst_info(0).op === EXE_MTC0
|
// val mtc0_wen = io.executeUnit.in.inst_info(0).op === EXE_MTC0
|
||||||
val mtc0_wdata = io.executeUnit.in.mtc0_wdata
|
// val mtc0_wdata = io.executeUnit.in.mtc0_wdata
|
||||||
val mtc0_addr = io.executeUnit.in.inst_info(0).csr_addr
|
// val mtc0_addr = io.executeUnit.in.inst_info(0).csr_addr
|
||||||
val exe_op = io.executeUnit.in.inst_info(0).op
|
// val exe_op = io.executeUnit.in.inst_info(0).op
|
||||||
val exe_stall = io.ctrl.exe_stall
|
// val exe_stall = io.ctrl.exe_stall
|
||||||
val mem_stall = io.ctrl.mem_stall
|
// val mem_stall = io.ctrl.mem_stall
|
||||||
|
|
||||||
// ---------------csr-defines-----------------
|
// // ---------------csr-defines-----------------
|
||||||
|
|
||||||
// index register (0,0)
|
// // index register (0,0)
|
||||||
val csr_index = RegInit(0.U.asTypeOf(new CsrIndex()))
|
// val csr_index = RegInit(0.U.asTypeOf(new CsrIndex()))
|
||||||
|
|
||||||
// random register (1,0)
|
// // random register (1,0)
|
||||||
val random_init = Wire(new CsrRandom())
|
// val random_init = Wire(new CsrRandom())
|
||||||
random_init := 0.U.asTypeOf(new CsrRandom())
|
// random_init := 0.U.asTypeOf(new CsrRandom())
|
||||||
random_init.random := (TLB_NUM - 1).U
|
// random_init.random := (TLB_NUM - 1).U
|
||||||
val csr_random = RegInit(random_init)
|
// val csr_random = RegInit(random_init)
|
||||||
|
|
||||||
// entrylo0 register (2,0)
|
// // entrylo0 register (2,0)
|
||||||
val csr_entrylo0 = RegInit(0.U.asTypeOf(new CsrEntryLo()))
|
// val csr_entrylo0 = RegInit(0.U.asTypeOf(new CsrEntryLo()))
|
||||||
|
|
||||||
// entrylo1 register (3,0)
|
// // entrylo1 register (3,0)
|
||||||
val csr_entrylo1 = RegInit(0.U.asTypeOf(new CsrEntryLo()))
|
// val csr_entrylo1 = RegInit(0.U.asTypeOf(new CsrEntryLo()))
|
||||||
|
|
||||||
// context register (4,0)
|
// // context register (4,0)
|
||||||
val csr_context = RegInit(0.U.asTypeOf(new CsrContext()))
|
// val csr_context = RegInit(0.U.asTypeOf(new CsrContext()))
|
||||||
|
|
||||||
// page mask register (5,0)
|
// // page mask register (5,0)
|
||||||
val csr_pagemask = 0.U
|
// val csr_pagemask = 0.U
|
||||||
|
|
||||||
// wired register (6,0)
|
// // wired register (6,0)
|
||||||
val csr_wired = RegInit(0.U.asTypeOf(new CsrWired()))
|
// val csr_wired = RegInit(0.U.asTypeOf(new CsrWired()))
|
||||||
|
|
||||||
// badvaddr register (8,0)
|
// // badvaddr register (8,0)
|
||||||
val csr_badvaddr = RegInit(0.U.asTypeOf(new CsrBadVAddr()))
|
// val csr_badvaddr = RegInit(0.U.asTypeOf(new CsrBadVAddr()))
|
||||||
|
|
||||||
// count register (9,0)
|
// // count register (9,0)
|
||||||
val count_init = Wire(new CsrCount())
|
// val count_init = Wire(new CsrCount())
|
||||||
count_init := 0.U.asTypeOf(new CsrCount())
|
// count_init := 0.U.asTypeOf(new CsrCount())
|
||||||
count_init.count := 1.U
|
// count_init.count := 1.U
|
||||||
val csr_count = RegInit(count_init)
|
// val csr_count = RegInit(count_init)
|
||||||
|
|
||||||
// entryhi register (10,0)
|
// // entryhi register (10,0)
|
||||||
val csr_entryhi = RegInit(0.U.asTypeOf(new CsrEntryHi()))
|
// val csr_entryhi = RegInit(0.U.asTypeOf(new CsrEntryHi()))
|
||||||
|
|
||||||
// compare register (11,0)
|
// // compare register (11,0)
|
||||||
val csr_compare = RegInit(0.U.asTypeOf(new CsrCompare()))
|
// val csr_compare = RegInit(0.U.asTypeOf(new CsrCompare()))
|
||||||
|
|
||||||
// status register (12,0)
|
// // status register (12,0)
|
||||||
val status_init = Wire(new CsrStatus())
|
// val status_init = Wire(new CsrStatus())
|
||||||
status_init := 0.U.asTypeOf(new CsrStatus())
|
// status_init := 0.U.asTypeOf(new CsrStatus())
|
||||||
status_init.bev := true.B
|
// status_init.bev := true.B
|
||||||
val csr_status = RegInit(status_init)
|
// val csr_status = RegInit(status_init)
|
||||||
|
|
||||||
// cause register (13,0)
|
// // cause register (13,0)
|
||||||
val csr_cause = RegInit(0.U.asTypeOf(new CsrCause()))
|
// val csr_cause = RegInit(0.U.asTypeOf(new CsrCause()))
|
||||||
|
|
||||||
// epc register (14,0)
|
// // epc register (14,0)
|
||||||
val csr_epc = RegInit(0.U.asTypeOf(new CsrEpc()))
|
// val csr_epc = RegInit(0.U.asTypeOf(new CsrEpc()))
|
||||||
|
|
||||||
// prid register (15,0)
|
// // prid register (15,0)
|
||||||
val prid = "h_0001_8003".U
|
// val prid = "h_0001_8003".U
|
||||||
|
|
||||||
// ebase register (15,1)
|
// // ebase register (15,1)
|
||||||
val ebase_init = Wire(new CsrEbase())
|
// val ebase_init = Wire(new CsrEbase())
|
||||||
ebase_init := 0.U.asTypeOf(new CsrEbase())
|
// ebase_init := 0.U.asTypeOf(new CsrEbase())
|
||||||
ebase_init.fill := true.B
|
// ebase_init.fill := true.B
|
||||||
val csr_ebase = RegInit(ebase_init)
|
// val csr_ebase = RegInit(ebase_init)
|
||||||
|
|
||||||
// config register (16,0)
|
// // config register (16,0)
|
||||||
val csr_config = Wire(new CsrConfig())
|
// val csr_config = Wire(new CsrConfig())
|
||||||
csr_config := 0.U.asTypeOf(new CsrConfig())
|
// csr_config := 0.U.asTypeOf(new CsrConfig())
|
||||||
csr_config.k0 := 3.U
|
// csr_config.k0 := 3.U
|
||||||
csr_config.mt := 1.U
|
// csr_config.mt := 1.U
|
||||||
csr_config.m := true.B
|
// csr_config.m := true.B
|
||||||
|
|
||||||
// config1 register (16,1)
|
// // config1 register (16,1)
|
||||||
val csr_config1 = Wire(new CsrConfig1())
|
// val csr_config1 = Wire(new CsrConfig1())
|
||||||
csr_config1 := 0.U.asTypeOf(new CsrConfig1())
|
// csr_config1 := 0.U.asTypeOf(new CsrConfig1())
|
||||||
csr_config1.il := 5.U
|
// csr_config1.il := 5.U
|
||||||
csr_config1.ia := 1.U
|
// csr_config1.ia := 1.U
|
||||||
csr_config1.dl := 5.U
|
// csr_config1.dl := 5.U
|
||||||
csr_config1.da := 1.U
|
// csr_config1.da := 1.U
|
||||||
csr_config1.ms := (TLB_NUM - 1).U
|
// csr_config1.ms := (TLB_NUM - 1).U
|
||||||
|
|
||||||
// taglo register (28,0)
|
// // taglo register (28,0)
|
||||||
val csr_taglo = RegInit(0.U(DATA_WID.W))
|
// val csr_taglo = RegInit(0.U(DATA_WID.W))
|
||||||
|
|
||||||
// taghi register (29,0)
|
// // taghi register (29,0)
|
||||||
val csr_taghi = RegInit(0.U(DATA_WID.W))
|
// val csr_taghi = RegInit(0.U(DATA_WID.W))
|
||||||
|
|
||||||
// error epc register (30,0)
|
// // error epc register (30,0)
|
||||||
val csr_error_epc = RegInit(0.U.asTypeOf(new CsrEpc()))
|
// val csr_error_epc = RegInit(0.U.asTypeOf(new CsrEpc()))
|
||||||
|
|
||||||
// random register (1,0)
|
// // random register (1,0)
|
||||||
csr_random.random := Mux(csr_random.random === csr_wired.wired, (TLB_NUM - 1).U, (csr_random.random - 1.U))
|
// csr_random.random := Mux(csr_random.random === csr_wired.wired, (TLB_NUM - 1).U, (csr_random.random - 1.U))
|
||||||
|
|
||||||
// context register (4,0)
|
// // context register (4,0)
|
||||||
when(!mem_stall && ex.flush_req) {
|
// when(!mem_stall && ex.flush_req) {
|
||||||
when(VecInit(EX_TLBL, EX_TLBS, EX_MOD).contains(ex.excode)) {
|
// when(VecInit(EX_TLBL, EX_TLBS, EX_MOD).contains(ex.excode)) {
|
||||||
csr_context.badvpn2 := ex.badvaddr(31, 13)
|
// csr_context.badvpn2 := ex.badvaddr(31, 13)
|
||||||
}
|
// }
|
||||||
}.elsewhen(!exe_stall) {
|
// }.elsewhen(!exe_stall) {
|
||||||
when(mtc0_wen && mtc0_addr === CSR_CONTEXT_ADDR) {
|
// when(mtc0_wen && mtc0_addr === CSR_CONTEXT_ADDR) {
|
||||||
csr_context.ptebase := mtc0_wdata.asTypeOf(new CsrContext()).ptebase
|
// csr_context.ptebase := mtc0_wdata.asTypeOf(new CsrContext()).ptebase
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// wired register (6,0)
|
// // wired register (6,0)
|
||||||
when(!exe_stall) {
|
// when(!exe_stall) {
|
||||||
when(mtc0_wen && mtc0_addr === CSR_WIRED_ADDR) {
|
// when(mtc0_wen && mtc0_addr === CSR_WIRED_ADDR) {
|
||||||
csr_wired.wired := mtc0_wdata.asTypeOf(new CsrWired()).wired
|
// csr_wired.wired := mtc0_wdata.asTypeOf(new CsrWired()).wired
|
||||||
csr_random.random := (TLB_NUM - 1).U
|
// csr_random.random := (TLB_NUM - 1).U
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// badvaddr register (8,0)
|
// // badvaddr register (8,0)
|
||||||
when(!mem_stall && ex.flush_req) {
|
// when(!mem_stall && ex.flush_req) {
|
||||||
when(VecInit(EX_ADEL, EX_TLBL, EX_ADES, EX_TLBS, EX_MOD).contains(ex.excode)) {
|
// when(VecInit(EX_ADEL, EX_TLBL, EX_ADES, EX_TLBS, EX_MOD).contains(ex.excode)) {
|
||||||
csr_badvaddr.badvaddr := ex.badvaddr
|
// csr_badvaddr.badvaddr := ex.badvaddr
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// count register (9,0)
|
// // count register (9,0)
|
||||||
val tick = RegInit(false.B)
|
// val tick = RegInit(false.B)
|
||||||
tick := !tick
|
// tick := !tick
|
||||||
when(tick) {
|
// when(tick) {
|
||||||
csr_count.count := csr_count.count + 1.U
|
// csr_count.count := csr_count.count + 1.U
|
||||||
}
|
// }
|
||||||
when(!exe_stall) {
|
// when(!exe_stall) {
|
||||||
when(mtc0_wen && mtc0_addr === CSR_COUNT_ADDR) {
|
// when(mtc0_wen && mtc0_addr === CSR_COUNT_ADDR) {
|
||||||
csr_count.count := mtc0_wdata.asTypeOf(new CsrCount()).count
|
// csr_count.count := mtc0_wdata.asTypeOf(new CsrCount()).count
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// entryhi register (10,0)
|
// // entryhi register (10,0)
|
||||||
when(!mem_stall && ex.flush_req) {
|
// when(!mem_stall && ex.flush_req) {
|
||||||
when(VecInit(EX_TLBL, EX_TLBS, EX_MOD).contains(ex.excode)) {
|
// when(VecInit(EX_TLBL, EX_TLBS, EX_MOD).contains(ex.excode)) {
|
||||||
csr_entryhi.vpn2 := ex.badvaddr(31, 13)
|
// csr_entryhi.vpn2 := ex.badvaddr(31, 13)
|
||||||
}
|
// }
|
||||||
}.elsewhen(!exe_stall) {
|
// }.elsewhen(!exe_stall) {
|
||||||
when(mtc0_wen && mtc0_addr === CSR_ENTRYHI_ADDR) {
|
// when(mtc0_wen && mtc0_addr === CSR_ENTRYHI_ADDR) {
|
||||||
val wdata = mtc0_wdata.asTypeOf(new CsrEntryHi())
|
// val wdata = mtc0_wdata.asTypeOf(new CsrEntryHi())
|
||||||
csr_entryhi.asid := wdata.asid
|
// csr_entryhi.asid := wdata.asid
|
||||||
csr_entryhi.vpn2 := wdata.vpn2
|
// csr_entryhi.vpn2 := wdata.vpn2
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// compare register (11,0)
|
// // compare register (11,0)
|
||||||
when(!exe_stall) {
|
// when(!exe_stall) {
|
||||||
when(mtc0_wen && mtc0_addr === CSR_COMPARE_ADDR) {
|
// when(mtc0_wen && mtc0_addr === CSR_COMPARE_ADDR) {
|
||||||
csr_compare.compare := mtc0_wdata.asTypeOf(new CsrCompare()).compare
|
// csr_compare.compare := mtc0_wdata.asTypeOf(new CsrCompare()).compare
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// status register (12,0)
|
// // status register (12,0)
|
||||||
when(!mem_stall && ex.eret) {
|
// when(!mem_stall && ex.eret) {
|
||||||
when(csr_status.erl) {
|
// when(csr_status.erl) {
|
||||||
csr_status.erl := false.B
|
// csr_status.erl := false.B
|
||||||
}.otherwise {
|
// }.otherwise {
|
||||||
csr_status.exl := false.B
|
// csr_status.exl := false.B
|
||||||
}
|
// }
|
||||||
}.elsewhen(!mem_stall && ex.flush_req) {
|
// }.elsewhen(!mem_stall && ex.flush_req) {
|
||||||
csr_status.exl := true.B
|
// csr_status.exl := true.B
|
||||||
}.elsewhen(!exe_stall) {
|
// }.elsewhen(!exe_stall) {
|
||||||
when(mtc0_wen && mtc0_addr === CSR_STATUS_ADDR) {
|
// when(mtc0_wen && mtc0_addr === CSR_STATUS_ADDR) {
|
||||||
val wdata = mtc0_wdata.asTypeOf(new CsrStatus())
|
// val wdata = mtc0_wdata.asTypeOf(new CsrStatus())
|
||||||
csr_status.cu0 := wdata.cu0
|
// csr_status.cu0 := wdata.cu0
|
||||||
csr_status.ie := wdata.ie
|
// csr_status.ie := wdata.ie
|
||||||
csr_status.exl := wdata.exl
|
// csr_status.exl := wdata.exl
|
||||||
csr_status.erl := wdata.erl
|
// csr_status.erl := wdata.erl
|
||||||
csr_status.um := wdata.um
|
// csr_status.um := wdata.um
|
||||||
csr_status.im := wdata.im
|
// csr_status.im := wdata.im
|
||||||
csr_status.bev := wdata.bev
|
// csr_status.bev := wdata.bev
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// cause register (13,0)
|
// // cause register (13,0)
|
||||||
csr_cause.ip := Cat(
|
// csr_cause.ip := Cat(
|
||||||
csr_cause.ip(7) || csr_compare.compare === csr_count.count || io.ext_int(5), // TODO:此处的ext_int可能不对
|
// csr_cause.ip(7) || csr_compare.compare === csr_count.count || io.ext_int(5), // TODO:此处的ext_int可能不对
|
||||||
io.ext_int(4, 0),
|
// io.ext_int(4, 0),
|
||||||
csr_cause.ip(1, 0)
|
// csr_cause.ip(1, 0)
|
||||||
)
|
// )
|
||||||
when(!mem_stall && ex.flush_req && !ex.eret) {
|
// when(!mem_stall && ex.flush_req && !ex.eret) {
|
||||||
when(!csr_status.exl) {
|
// when(!csr_status.exl) {
|
||||||
csr_cause.bd := ex.bd
|
// csr_cause.bd := ex.bd
|
||||||
}
|
// }
|
||||||
csr_cause.excode := MuxLookup(ex.excode, csr_cause.excode)(
|
// csr_cause.excode := MuxLookup(ex.excode, csr_cause.excode)(
|
||||||
Seq(
|
// Seq(
|
||||||
EX_NO -> EXC_NO,
|
// EX_NO -> EXC_NO,
|
||||||
EX_INT -> EXC_INT,
|
// EX_INT -> EXC_INT,
|
||||||
EX_MOD -> EXC_MOD,
|
// EX_MOD -> EXC_MOD,
|
||||||
EX_TLBL -> EXC_TLBL,
|
// EX_TLBL -> EXC_TLBL,
|
||||||
EX_TLBS -> EXC_TLBS,
|
// EX_TLBS -> EXC_TLBS,
|
||||||
EX_ADEL -> EXC_ADEL,
|
// EX_ADEL -> EXC_ADEL,
|
||||||
EX_ADES -> EXC_ADES,
|
// EX_ADES -> EXC_ADES,
|
||||||
EX_SYS -> EXC_SYS,
|
// EX_SYS -> EXC_SYS,
|
||||||
EX_BP -> EXC_BP,
|
// EX_BP -> EXC_BP,
|
||||||
EX_RI -> EXC_RI,
|
// EX_RI -> EXC_RI,
|
||||||
EX_CPU -> EXC_CPU,
|
// EX_CPU -> EXC_CPU,
|
||||||
EX_OV -> EXC_OV
|
// EX_OV -> EXC_OV
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
}.elsewhen(!exe_stall) {
|
// }.elsewhen(!exe_stall) {
|
||||||
when(mtc0_wen) {
|
// when(mtc0_wen) {
|
||||||
when(mtc0_addr === CSR_COMPARE_ADDR) {
|
// when(mtc0_addr === CSR_COMPARE_ADDR) {
|
||||||
csr_cause.ip := Cat(false.B, csr_cause.ip(6, 0))
|
// csr_cause.ip := Cat(false.B, csr_cause.ip(6, 0))
|
||||||
}.elsewhen(mtc0_addr === CSR_CAUSE_ADDR) {
|
// }.elsewhen(mtc0_addr === CSR_CAUSE_ADDR) {
|
||||||
val wdata = mtc0_wdata.asTypeOf(new CsrCause())
|
// val wdata = mtc0_wdata.asTypeOf(new CsrCause())
|
||||||
csr_cause.ip := Cat(
|
// csr_cause.ip := Cat(
|
||||||
csr_cause.ip(7, 2),
|
// csr_cause.ip(7, 2),
|
||||||
wdata.ip(1, 0)
|
// wdata.ip(1, 0)
|
||||||
)
|
// )
|
||||||
csr_cause.iv := wdata.iv
|
// csr_cause.iv := wdata.iv
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// epc register (14,0)
|
// // epc register (14,0)
|
||||||
when(!mem_stall && ex.flush_req) {
|
// when(!mem_stall && ex.flush_req) {
|
||||||
when(!csr_status.exl) {
|
// when(!csr_status.exl) {
|
||||||
csr_epc.epc := Mux(ex.bd, pc - 4.U, pc)
|
// csr_epc.epc := Mux(ex.bd, pc - 4.U, pc)
|
||||||
}
|
// }
|
||||||
}.elsewhen(!exe_stall) {
|
// }.elsewhen(!exe_stall) {
|
||||||
when(mtc0_wen && mtc0_addr === CSR_EPC_ADDR) {
|
// when(mtc0_wen && mtc0_addr === CSR_EPC_ADDR) {
|
||||||
csr_epc.epc := mtc0_wdata.asTypeOf(new CsrEpc()).epc
|
// csr_epc.epc := mtc0_wdata.asTypeOf(new CsrEpc()).epc
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// ebase register (15,1)
|
// // ebase register (15,1)
|
||||||
when(!exe_stall) {
|
// when(!exe_stall) {
|
||||||
when(mtc0_wen && mtc0_addr === CSR_EBASE_ADDR) {
|
// when(mtc0_wen && mtc0_addr === CSR_EBASE_ADDR) {
|
||||||
csr_ebase.ebase := mtc0_wdata.asTypeOf(new CsrEbase()).ebase
|
// csr_ebase.ebase := mtc0_wdata.asTypeOf(new CsrEbase()).ebase
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// taglo register (28,0)
|
// // taglo register (28,0)
|
||||||
when(!exe_stall) {
|
// when(!exe_stall) {
|
||||||
when(mtc0_wen && mtc0_addr === CSR_TAGLO_ADDR) {
|
// when(mtc0_wen && mtc0_addr === CSR_TAGLO_ADDR) {
|
||||||
csr_taglo := mtc0_wdata
|
// csr_taglo := mtc0_wdata
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// taghi register (29,0)
|
// // taghi register (29,0)
|
||||||
when(!exe_stall) {
|
// when(!exe_stall) {
|
||||||
when(mtc0_wen && mtc0_addr === CSR_TAGHI_ADDR) {
|
// when(mtc0_wen && mtc0_addr === CSR_TAGHI_ADDR) {
|
||||||
csr_taghi := mtc0_wdata
|
// csr_taghi := mtc0_wdata
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// error epc register (30,0)
|
// // error epc register (30,0)
|
||||||
when(!exe_stall) {
|
// when(!exe_stall) {
|
||||||
when(mtc0_wen && mtc0_addr === CSR_ERROR_EPC_ADDR) {
|
// when(mtc0_wen && mtc0_addr === CSR_ERROR_EPC_ADDR) {
|
||||||
csr_error_epc.epc := mtc0_wdata.asTypeOf(new CsrEpc()).epc
|
// csr_error_epc.epc := mtc0_wdata.asTypeOf(new CsrEpc()).epc
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
for (i <- 0 until config.fuNum) {
|
// for (i <- 0 until config.fuNum) {
|
||||||
io.executeUnit.out.csr_rdata(i) := MuxLookup(io.executeUnit.in.inst_info(i).csr_addr, 0.U)(
|
// io.executeUnit.out.csr_rdata(i) := MuxLookup(io.executeUnit.in.inst_info(i).csr_addr, 0.U)(
|
||||||
Seq(
|
// Seq(
|
||||||
CSR_INDEX_ADDR -> csr_index.asUInt,
|
// CSR_INDEX_ADDR -> csr_index.asUInt,
|
||||||
CSR_RANDOM_ADDR -> csr_random.asUInt,
|
// CSR_RANDOM_ADDR -> csr_random.asUInt,
|
||||||
CSR_ENTRYLO0_ADDR -> csr_entrylo0.asUInt,
|
// CSR_ENTRYLO0_ADDR -> csr_entrylo0.asUInt,
|
||||||
CSR_ENTRYLO1_ADDR -> csr_entrylo1.asUInt,
|
// CSR_ENTRYLO1_ADDR -> csr_entrylo1.asUInt,
|
||||||
CSR_CONTEXT_ADDR -> csr_context.asUInt,
|
// CSR_CONTEXT_ADDR -> csr_context.asUInt,
|
||||||
CSR_PAGE_MASK_ADDR -> csr_pagemask,
|
// CSR_PAGE_MASK_ADDR -> csr_pagemask,
|
||||||
CSR_WIRED_ADDR -> csr_wired.asUInt,
|
// CSR_WIRED_ADDR -> csr_wired.asUInt,
|
||||||
CSR_BADV_ADDR -> csr_badvaddr.asUInt,
|
// CSR_BADV_ADDR -> csr_badvaddr.asUInt,
|
||||||
CSR_COUNT_ADDR -> csr_count.asUInt,
|
// CSR_COUNT_ADDR -> csr_count.asUInt,
|
||||||
CSR_ENTRYHI_ADDR -> csr_entryhi.asUInt,
|
// CSR_ENTRYHI_ADDR -> csr_entryhi.asUInt,
|
||||||
CSR_COMPARE_ADDR -> csr_compare.asUInt,
|
// CSR_COMPARE_ADDR -> csr_compare.asUInt,
|
||||||
CSR_STATUS_ADDR -> csr_status.asUInt,
|
// CSR_STATUS_ADDR -> csr_status.asUInt,
|
||||||
CSR_CAUSE_ADDR -> csr_cause.asUInt,
|
// CSR_CAUSE_ADDR -> csr_cause.asUInt,
|
||||||
CSR_EPC_ADDR -> csr_epc.asUInt,
|
// CSR_EPC_ADDR -> csr_epc.asUInt,
|
||||||
CSR_PRID_ADDR -> prid,
|
// CSR_PRID_ADDR -> prid,
|
||||||
CSR_EBASE_ADDR -> csr_ebase.asUInt,
|
// CSR_EBASE_ADDR -> csr_ebase.asUInt,
|
||||||
CSR_CONFIG_ADDR -> csr_config.asUInt,
|
// CSR_CONFIG_ADDR -> csr_config.asUInt,
|
||||||
CSR_CONFIG1_ADDR -> csr_config1.asUInt,
|
// CSR_CONFIG1_ADDR -> csr_config1.asUInt,
|
||||||
CSR_TAGLO_ADDR -> csr_taglo,
|
// CSR_TAGLO_ADDR -> csr_taglo,
|
||||||
CSR_TAGHI_ADDR -> csr_taghi,
|
// CSR_TAGHI_ADDR -> csr_taghi,
|
||||||
CSR_ERROR_EPC_ADDR -> csr_error_epc.asUInt
|
// CSR_ERROR_EPC_ADDR -> csr_error_epc.asUInt
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
io.decoderUnit.cause_ip := csr_cause.ip
|
// io.decoderUnit.cause_ip := csr_cause.ip
|
||||||
io.decoderUnit.status_im := csr_status.im
|
// io.decoderUnit.status_im := csr_status.im
|
||||||
io.decoderUnit.kernel_mode := (csr_status.exl && !(ex.eret && csr_status.erl)) ||
|
// io.decoderUnit.kernel_mode := (csr_status.exl && !(ex.eret && csr_status.erl)) ||
|
||||||
(csr_status.erl && !ex.eret) ||
|
// (csr_status.erl && !ex.eret) ||
|
||||||
!csr_status.um ||
|
// !csr_status.um ||
|
||||||
(ex.flush_req && !ex.eret)
|
// (ex.flush_req && !ex.eret)
|
||||||
io.decoderUnit.access_allowed := io.decoderUnit.kernel_mode || csr_status.cu0
|
// io.decoderUnit.access_allowed := io.decoderUnit.kernel_mode || csr_status.cu0
|
||||||
io.decoderUnit.intterupt_allowed := csr_status.ie && !csr_status.exl && !csr_status.erl
|
// io.decoderUnit.intterupt_allowed := csr_status.ie && !csr_status.exl && !csr_status.erl
|
||||||
|
|
||||||
io.executeUnit.out.debug.csr_cause := csr_cause.asUInt
|
// io.executeUnit.out.debug.csr_cause := csr_cause.asUInt
|
||||||
io.executeUnit.out.debug.csr_count := csr_count.asUInt
|
// io.executeUnit.out.debug.csr_count := csr_count.asUInt
|
||||||
io.executeUnit.out.debug.csr_random := csr_random.asUInt
|
// io.executeUnit.out.debug.csr_random := csr_random.asUInt
|
||||||
|
|
||||||
val trap_base = Mux(
|
// val trap_base = Mux(
|
||||||
csr_status.bev,
|
// csr_status.bev,
|
||||||
"hbfc00200".U(PC_WID.W),
|
// "hbfc00200".U(PC_WID.W),
|
||||||
csr_ebase.asUInt
|
// csr_ebase.asUInt
|
||||||
)
|
// )
|
||||||
io.memoryUnit.out.flush := false.B
|
// io.memoryUnit.out.flush := false.B
|
||||||
io.memoryUnit.out.flush_pc := 0.U
|
// io.memoryUnit.out.flush_pc := 0.U
|
||||||
when(ex.eret) {
|
// when(ex.eret) {
|
||||||
io.memoryUnit.out.flush := true.B && !io.ctrl.mem_stall
|
// io.memoryUnit.out.flush := true.B && !io.ctrl.mem_stall
|
||||||
io.memoryUnit.out.flush_pc := Mux(csr_status.erl, csr_error_epc.epc, csr_epc.epc)
|
// io.memoryUnit.out.flush_pc := Mux(csr_status.erl, csr_error_epc.epc, csr_epc.epc)
|
||||||
}.elsewhen(ex.flush_req) {
|
// }.elsewhen(ex.flush_req) {
|
||||||
io.memoryUnit.out.flush := true.B && !io.ctrl.mem_stall
|
// io.memoryUnit.out.flush := true.B && !io.ctrl.mem_stall
|
||||||
io.memoryUnit.out.flush_pc := Mux(
|
// io.memoryUnit.out.flush_pc := Mux(
|
||||||
csr_status.exl,
|
// csr_status.exl,
|
||||||
trap_base + "h180".U,
|
// trap_base + "h180".U,
|
||||||
trap_base + "h200".U
|
// trap_base + "h200".U
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
|
@ -1,160 +1,160 @@
|
||||||
package cpu.pipeline.execute
|
// package cpu.pipeline.execute
|
||||||
|
|
||||||
import chisel3._
|
// import chisel3._
|
||||||
import chisel3.util._
|
// import chisel3.util._
|
||||||
import cpu.defines._
|
// import cpu.defines._
|
||||||
import cpu.defines.Const._
|
// import cpu.defines.Const._
|
||||||
import cpu.CpuConfig
|
// import cpu.CpuConfig
|
||||||
|
|
||||||
class SignedDiv extends BlackBox with HasBlackBoxResource {
|
// class SignedDiv extends BlackBox with HasBlackBoxResource {
|
||||||
val io = IO(new Bundle {
|
// val io = IO(new Bundle {
|
||||||
val aclk = Input(Clock())
|
// val aclk = Input(Clock())
|
||||||
// 除数
|
// // 除数
|
||||||
val s_axis_divisor_tvalid = Input(Bool())
|
// val s_axis_divisor_tvalid = Input(Bool())
|
||||||
val s_axis_divisor_tready = Output(Bool())
|
// val s_axis_divisor_tready = Output(Bool())
|
||||||
val s_axis_divisor_tdata = Input(UInt(DATA_WID.W))
|
// val s_axis_divisor_tdata = Input(UInt(DATA_WID.W))
|
||||||
// 被除数
|
// // 被除数
|
||||||
val s_axis_dividend_tvalid = Input(Bool())
|
// val s_axis_dividend_tvalid = Input(Bool())
|
||||||
val s_axis_dividend_tready = Output(Bool())
|
// val s_axis_dividend_tready = Output(Bool())
|
||||||
val s_axis_dividend_tdata = Input(UInt(DATA_WID.W))
|
// val s_axis_dividend_tdata = Input(UInt(DATA_WID.W))
|
||||||
// 结果
|
// // 结果
|
||||||
val m_axis_dout_tvalid = Output(Bool())
|
// val m_axis_dout_tvalid = Output(Bool())
|
||||||
val m_axis_dout_tdata = Output(UInt(HILO_WID.W))
|
// val m_axis_dout_tdata = Output(UInt(HILO_WID.W))
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
class UnsignedDiv extends BlackBox with HasBlackBoxResource {
|
// class UnsignedDiv extends BlackBox with HasBlackBoxResource {
|
||||||
val io = IO(new Bundle {
|
// val io = IO(new Bundle {
|
||||||
val aclk = Input(Clock())
|
// val aclk = Input(Clock())
|
||||||
// 除数
|
// // 除数
|
||||||
val s_axis_divisor_tvalid = Input(Bool())
|
// val s_axis_divisor_tvalid = Input(Bool())
|
||||||
val s_axis_divisor_tready = Output(Bool())
|
// val s_axis_divisor_tready = Output(Bool())
|
||||||
val s_axis_divisor_tdata = Input(UInt(DATA_WID.W))
|
// val s_axis_divisor_tdata = Input(UInt(DATA_WID.W))
|
||||||
// 被除数
|
// // 被除数
|
||||||
val s_axis_dividend_tvalid = Input(Bool())
|
// val s_axis_dividend_tvalid = Input(Bool())
|
||||||
val s_axis_dividend_tready = Output(Bool())
|
// val s_axis_dividend_tready = Output(Bool())
|
||||||
val s_axis_dividend_tdata = Input(UInt(DATA_WID.W))
|
// val s_axis_dividend_tdata = Input(UInt(DATA_WID.W))
|
||||||
// 结果
|
// // 结果
|
||||||
val m_axis_dout_tvalid = Output(Bool())
|
// val m_axis_dout_tvalid = Output(Bool())
|
||||||
val m_axis_dout_tdata = Output(UInt(HILO_WID.W))
|
// val m_axis_dout_tdata = Output(UInt(HILO_WID.W))
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
class Div(implicit config: CpuConfig) extends Module {
|
// class Div(implicit config: CpuConfig) extends Module {
|
||||||
val io = IO(new Bundle {
|
// val io = IO(new Bundle {
|
||||||
val src1 = Input(UInt(DATA_WID.W))
|
// val src1 = Input(UInt(DATA_WID.W))
|
||||||
val src2 = Input(UInt(DATA_WID.W))
|
// val src2 = Input(UInt(DATA_WID.W))
|
||||||
val signed = Input(Bool())
|
// val signed = Input(Bool())
|
||||||
val start = Input(Bool())
|
// val start = Input(Bool())
|
||||||
val allow_to_go = Input(Bool())
|
// val allow_to_go = Input(Bool())
|
||||||
|
|
||||||
val ready = Output(Bool())
|
// val ready = Output(Bool())
|
||||||
val result = Output(UInt(HILO_WID.W))
|
// val result = Output(UInt(HILO_WID.W))
|
||||||
})
|
// })
|
||||||
|
|
||||||
if (config.build) {
|
// if (config.build) {
|
||||||
val signedDiv = Module(new SignedDiv()).io
|
// val signedDiv = Module(new SignedDiv()).io
|
||||||
val unsignedDiv = Module(new UnsignedDiv()).io
|
// val unsignedDiv = Module(new UnsignedDiv()).io
|
||||||
|
|
||||||
signedDiv.aclk := clock
|
// signedDiv.aclk := clock
|
||||||
unsignedDiv.aclk := clock
|
// unsignedDiv.aclk := clock
|
||||||
|
|
||||||
// 0为被除数,1为除数
|
// // 0为被除数,1为除数
|
||||||
val unsignedDiv_sent = Seq.fill(2)(RegInit(false.B))
|
// val unsignedDiv_sent = Seq.fill(2)(RegInit(false.B))
|
||||||
val unsignedDiv_done = RegInit(false.B)
|
// val unsignedDiv_done = RegInit(false.B)
|
||||||
val signedDiv_sent = Seq.fill(2)(RegInit(false.B))
|
// val signedDiv_sent = Seq.fill(2)(RegInit(false.B))
|
||||||
val signedDiv_done = RegInit(false.B)
|
// val signedDiv_done = RegInit(false.B)
|
||||||
|
|
||||||
when(unsignedDiv.s_axis_dividend_tready && unsignedDiv.s_axis_dividend_tvalid) {
|
// when(unsignedDiv.s_axis_dividend_tready && unsignedDiv.s_axis_dividend_tvalid) {
|
||||||
unsignedDiv_sent(0) := true.B
|
// unsignedDiv_sent(0) := true.B
|
||||||
}.elsewhen(io.ready && io.allow_to_go) {
|
// }.elsewhen(io.ready && io.allow_to_go) {
|
||||||
unsignedDiv_sent(0) := false.B
|
// unsignedDiv_sent(0) := false.B
|
||||||
}
|
// }
|
||||||
when(unsignedDiv.s_axis_divisor_tready && unsignedDiv.s_axis_divisor_tvalid) {
|
// when(unsignedDiv.s_axis_divisor_tready && unsignedDiv.s_axis_divisor_tvalid) {
|
||||||
unsignedDiv_sent(1) := true.B
|
// unsignedDiv_sent(1) := true.B
|
||||||
}.elsewhen(io.ready && io.allow_to_go) {
|
// }.elsewhen(io.ready && io.allow_to_go) {
|
||||||
unsignedDiv_sent(1) := false.B
|
// unsignedDiv_sent(1) := false.B
|
||||||
}
|
// }
|
||||||
|
|
||||||
when(signedDiv.s_axis_dividend_tready && signedDiv.s_axis_dividend_tvalid) {
|
// when(signedDiv.s_axis_dividend_tready && signedDiv.s_axis_dividend_tvalid) {
|
||||||
signedDiv_sent(0) := true.B
|
// signedDiv_sent(0) := true.B
|
||||||
}.elsewhen(io.ready && io.allow_to_go) {
|
// }.elsewhen(io.ready && io.allow_to_go) {
|
||||||
signedDiv_sent(0) := false.B
|
// signedDiv_sent(0) := false.B
|
||||||
}
|
// }
|
||||||
when(signedDiv.s_axis_divisor_tready && signedDiv.s_axis_divisor_tvalid) {
|
// when(signedDiv.s_axis_divisor_tready && signedDiv.s_axis_divisor_tvalid) {
|
||||||
signedDiv_sent(1) := true.B
|
// signedDiv_sent(1) := true.B
|
||||||
}.elsewhen(io.ready && io.allow_to_go) {
|
// }.elsewhen(io.ready && io.allow_to_go) {
|
||||||
signedDiv_sent(1) := false.B
|
// signedDiv_sent(1) := false.B
|
||||||
}
|
// }
|
||||||
|
|
||||||
when(signedDiv.m_axis_dout_tvalid && !io.allow_to_go) {
|
// when(signedDiv.m_axis_dout_tvalid && !io.allow_to_go) {
|
||||||
signedDiv_done := true.B
|
// signedDiv_done := true.B
|
||||||
}.elsewhen(io.allow_to_go) {
|
// }.elsewhen(io.allow_to_go) {
|
||||||
signedDiv_done := false.B
|
// signedDiv_done := false.B
|
||||||
}
|
// }
|
||||||
|
|
||||||
when(unsignedDiv.m_axis_dout_tvalid && !io.allow_to_go) {
|
// when(unsignedDiv.m_axis_dout_tvalid && !io.allow_to_go) {
|
||||||
unsignedDiv_done := true.B
|
// unsignedDiv_done := true.B
|
||||||
}.elsewhen(io.allow_to_go) {
|
// }.elsewhen(io.allow_to_go) {
|
||||||
unsignedDiv_done := false.B
|
// unsignedDiv_done := false.B
|
||||||
}
|
// }
|
||||||
// 被除数和除数的valid信号
|
// // 被除数和除数的valid信号
|
||||||
signedDiv.s_axis_dividend_tvalid := io.start && !signedDiv_sent(0) && io.signed
|
// signedDiv.s_axis_dividend_tvalid := io.start && !signedDiv_sent(0) && io.signed
|
||||||
signedDiv.s_axis_divisor_tvalid := io.start && !signedDiv_sent(1) && io.signed
|
// signedDiv.s_axis_divisor_tvalid := io.start && !signedDiv_sent(1) && io.signed
|
||||||
|
|
||||||
unsignedDiv.s_axis_dividend_tvalid := io.start && !unsignedDiv_sent(0) && !io.signed
|
// unsignedDiv.s_axis_dividend_tvalid := io.start && !unsignedDiv_sent(0) && !io.signed
|
||||||
unsignedDiv.s_axis_divisor_tvalid := io.start && !unsignedDiv_sent(1) && !io.signed
|
// unsignedDiv.s_axis_divisor_tvalid := io.start && !unsignedDiv_sent(1) && !io.signed
|
||||||
|
|
||||||
// 被除数和除数的值
|
// // 被除数和除数的值
|
||||||
signedDiv.s_axis_dividend_tdata := io.src1
|
// signedDiv.s_axis_dividend_tdata := io.src1
|
||||||
signedDiv.s_axis_divisor_tdata := io.src2
|
// signedDiv.s_axis_divisor_tdata := io.src2
|
||||||
|
|
||||||
unsignedDiv.s_axis_dividend_tdata := io.src1
|
// unsignedDiv.s_axis_dividend_tdata := io.src1
|
||||||
unsignedDiv.s_axis_divisor_tdata := io.src2
|
// unsignedDiv.s_axis_divisor_tdata := io.src2
|
||||||
|
|
||||||
io.ready := Mux(
|
// io.ready := Mux(
|
||||||
io.signed,
|
// io.signed,
|
||||||
signedDiv.m_axis_dout_tvalid || signedDiv_done,
|
// signedDiv.m_axis_dout_tvalid || signedDiv_done,
|
||||||
unsignedDiv.m_axis_dout_tvalid || unsignedDiv_done,
|
// unsignedDiv.m_axis_dout_tvalid || unsignedDiv_done,
|
||||||
)
|
// )
|
||||||
val signedRes =
|
// val signedRes =
|
||||||
Cat(signedDiv.m_axis_dout_tdata(DATA_WID - 1, 0), signedDiv.m_axis_dout_tdata(HILO_WID - 1, DATA_WID))
|
// Cat(signedDiv.m_axis_dout_tdata(DATA_WID - 1, 0), signedDiv.m_axis_dout_tdata(HILO_WID - 1, DATA_WID))
|
||||||
val unsignedRes =
|
// val unsignedRes =
|
||||||
Cat(unsignedDiv.m_axis_dout_tdata(DATA_WID - 1, 0), unsignedDiv.m_axis_dout_tdata(HILO_WID - 1, DATA_WID))
|
// Cat(unsignedDiv.m_axis_dout_tdata(DATA_WID - 1, 0), unsignedDiv.m_axis_dout_tdata(HILO_WID - 1, DATA_WID))
|
||||||
io.result := Mux(io.signed, signedRes, unsignedRes)
|
// io.result := Mux(io.signed, signedRes, unsignedRes)
|
||||||
} else {
|
// } else {
|
||||||
val cnt = RegInit(0.U(log2Ceil(config.divClockNum + 1).W))
|
// val cnt = RegInit(0.U(log2Ceil(config.divClockNum + 1).W))
|
||||||
cnt := MuxCase(
|
// cnt := MuxCase(
|
||||||
cnt,
|
// cnt,
|
||||||
Seq(
|
// Seq(
|
||||||
(io.start && !io.ready) -> (cnt + 1.U),
|
// (io.start && !io.ready) -> (cnt + 1.U),
|
||||||
io.allow_to_go -> 0.U,
|
// io.allow_to_go -> 0.U,
|
||||||
),
|
// ),
|
||||||
)
|
// )
|
||||||
|
|
||||||
val div_signed = io.signed
|
// val div_signed = io.signed
|
||||||
|
|
||||||
val dividend_signed = io.src1(31) & div_signed
|
// val dividend_signed = io.src1(31) & div_signed
|
||||||
val divisor_signed = io.src2(31) & div_signed
|
// val divisor_signed = io.src2(31) & div_signed
|
||||||
|
|
||||||
val dividend_abs = Mux(dividend_signed, (-io.src1).asUInt, io.src1.asUInt)
|
// val dividend_abs = Mux(dividend_signed, (-io.src1).asUInt, io.src1.asUInt)
|
||||||
val divisor_abs = Mux(divisor_signed, (-io.src2).asUInt, io.src2.asUInt)
|
// val divisor_abs = Mux(divisor_signed, (-io.src2).asUInt, io.src2.asUInt)
|
||||||
|
|
||||||
val quotient_signed = (io.src1(31) ^ io.src2(31)) & div_signed
|
// val quotient_signed = (io.src1(31) ^ io.src2(31)) & div_signed
|
||||||
val remainder_signed = io.src1(31) & div_signed
|
// val remainder_signed = io.src1(31) & div_signed
|
||||||
|
|
||||||
val quotient_abs = dividend_abs / divisor_abs
|
// val quotient_abs = dividend_abs / divisor_abs
|
||||||
val remainder_abs = dividend_abs - quotient_abs * divisor_abs
|
// val remainder_abs = dividend_abs - quotient_abs * divisor_abs
|
||||||
|
|
||||||
val quotient = RegInit(0.S(32.W))
|
// val quotient = RegInit(0.S(32.W))
|
||||||
val remainder = RegInit(0.S(32.W))
|
// val remainder = RegInit(0.S(32.W))
|
||||||
|
|
||||||
when(io.start) {
|
// when(io.start) {
|
||||||
quotient := Mux(quotient_signed, (-quotient_abs).asSInt, quotient_abs.asSInt)
|
// quotient := Mux(quotient_signed, (-quotient_abs).asSInt, quotient_abs.asSInt)
|
||||||
remainder := Mux(remainder_signed, (-remainder_abs).asSInt, remainder_abs.asSInt)
|
// remainder := Mux(remainder_signed, (-remainder_abs).asSInt, remainder_abs.asSInt)
|
||||||
}
|
// }
|
||||||
|
|
||||||
io.ready := cnt >= config.divClockNum.U
|
// io.ready := cnt >= config.divClockNum.U
|
||||||
io.result := Cat(remainder, quotient)
|
// io.result := Cat(remainder, quotient)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
|
@ -1,99 +1,99 @@
|
||||||
package cpu.pipeline.execute
|
// package cpu.pipeline.execute
|
||||||
|
|
||||||
import chisel3._
|
// import chisel3._
|
||||||
import chisel3.util._
|
// import chisel3.util._
|
||||||
import cpu.CpuConfig
|
// import cpu.CpuConfig
|
||||||
import cpu.defines._
|
// import cpu.defines._
|
||||||
import cpu.defines.Const._
|
// import cpu.defines.Const._
|
||||||
|
|
||||||
class ExeAccessMemCtrl(implicit val config: CpuConfig) extends Module {
|
// class ExeAccessMemCtrl(implicit val config: CpuConfig) extends Module {
|
||||||
val io = IO(new Bundle {
|
// val io = IO(new Bundle {
|
||||||
val mem = new Bundle {
|
// val mem = new Bundle {
|
||||||
val out = Output(new Bundle {
|
// val out = Output(new Bundle {
|
||||||
val en = Bool()
|
// val en = Bool()
|
||||||
val ren = Bool()
|
// val ren = Bool()
|
||||||
val wen = Bool()
|
// val wen = Bool()
|
||||||
val inst_info = new InstInfo()
|
// val inst_info = new InstInfo()
|
||||||
val addr = UInt(DATA_ADDR_WID.W)
|
// val addr = UInt(DATA_ADDR_WID.W)
|
||||||
val wdata = UInt(DATA_WID.W)
|
// val wdata = UInt(DATA_WID.W)
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
val inst = Vec(
|
// val inst = Vec(
|
||||||
config.fuNum,
|
// config.fuNum,
|
||||||
new Bundle {
|
// new Bundle {
|
||||||
val inst_info = Input(new InstInfo())
|
// val inst_info = Input(new InstInfo())
|
||||||
val src_info = Input(new SrcInfo())
|
// 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())
|
||||||
}
|
// }
|
||||||
val mem_sel = Output(Bool())
|
// val mem_sel = Output(Bool())
|
||||||
},
|
// },
|
||||||
)
|
// )
|
||||||
})
|
// })
|
||||||
io.mem.out.en := io.inst.map(_.mem_sel).reduce(_ || _)
|
// io.mem.out.en := io.inst.map(_.mem_sel).reduce(_ || _)
|
||||||
io.mem.out.ren := io.inst(0).mem_sel && io.inst(0).inst_info.rmem ||
|
// io.mem.out.ren := io.inst(0).mem_sel && io.inst(0).inst_info.rmem ||
|
||||||
io.inst(1).mem_sel && io.inst(1).inst_info.rmem
|
// io.inst(1).mem_sel && io.inst(1).inst_info.rmem
|
||||||
io.mem.out.wen := io.inst(0).mem_sel && io.inst(0).inst_info.wmem ||
|
// io.mem.out.wen := io.inst(0).mem_sel && io.inst(0).inst_info.wmem ||
|
||||||
io.inst(1).mem_sel && io.inst(1).inst_info.wmem
|
// io.inst(1).mem_sel && io.inst(1).inst_info.wmem
|
||||||
io.mem.out.inst_info := MuxCase(
|
// io.mem.out.inst_info := MuxCase(
|
||||||
DontCare,
|
// DontCare,
|
||||||
Seq(
|
// Seq(
|
||||||
(io.inst(0).inst_info.fusel === FU_MEM) -> io.inst(0).inst_info,
|
// (io.inst(0).inst_info.fusel === FU_MEM) -> io.inst(0).inst_info,
|
||||||
(io.inst(1).inst_info.fusel === FU_MEM) -> io.inst(1).inst_info,
|
// (io.inst(1).inst_info.fusel === FU_MEM) -> io.inst(1).inst_info,
|
||||||
),
|
// ),
|
||||||
)
|
// )
|
||||||
val mem_addr = Wire(Vec(config.fuNum, UInt(DATA_ADDR_WID.W)))
|
// val mem_addr = Wire(Vec(config.fuNum, UInt(DATA_ADDR_WID.W)))
|
||||||
mem_addr(0) := io.inst(0).inst_info.mem_addr
|
// mem_addr(0) := io.inst(0).inst_info.mem_addr
|
||||||
mem_addr(1) := io.inst(1).inst_info.mem_addr
|
// mem_addr(1) := io.inst(1).inst_info.mem_addr
|
||||||
io.mem.out.addr := MuxCase(
|
// io.mem.out.addr := MuxCase(
|
||||||
0.U,
|
// 0.U,
|
||||||
Seq(
|
// Seq(
|
||||||
(io.inst(0).inst_info.fusel === FU_MEM) -> mem_addr(0),
|
// (io.inst(0).inst_info.fusel === FU_MEM) -> mem_addr(0),
|
||||||
(io.inst(1).inst_info.fusel === FU_MEM) -> mem_addr(1),
|
// (io.inst(1).inst_info.fusel === FU_MEM) -> mem_addr(1),
|
||||||
),
|
// ),
|
||||||
)
|
// )
|
||||||
io.mem.out.wdata := MuxCase(
|
// io.mem.out.wdata := MuxCase(
|
||||||
0.U,
|
// 0.U,
|
||||||
Seq(
|
// Seq(
|
||||||
(io.inst(0).inst_info.fusel === FU_MEM) ->
|
// (io.inst(0).inst_info.fusel === FU_MEM) ->
|
||||||
io.inst(0).src_info.src2_data,
|
// io.inst(0).src_info.src2_data,
|
||||||
(io.inst(1).inst_info.fusel === FU_MEM) ->
|
// (io.inst(1).inst_info.fusel === FU_MEM) ->
|
||||||
io.inst(1).src_info.src2_data,
|
// io.inst(1).src_info.src2_data,
|
||||||
),
|
// ),
|
||||||
)
|
// )
|
||||||
val mem_adel = Wire(Vec(config.fuNum, Bool()))
|
// val mem_adel = Wire(Vec(config.fuNum, Bool()))
|
||||||
for (i <- 0 until config.fuNum) {
|
// for (i <- 0 until config.fuNum) {
|
||||||
mem_adel(i) := VecInit(EXE_LW, EXE_LL).contains(io.inst(i).inst_info.op) && mem_addr(i)(1, 0) =/= 0.U ||
|
// mem_adel(i) := VecInit(EXE_LW, EXE_LL).contains(io.inst(i).inst_info.op) && mem_addr(i)(1, 0) =/= 0.U ||
|
||||||
VecInit(EXE_LH, EXE_LHU).contains(io.inst(i).inst_info.op) && mem_addr(i)(0) =/= 0.U
|
// VecInit(EXE_LH, EXE_LHU).contains(io.inst(i).inst_info.op) && mem_addr(i)(0) =/= 0.U
|
||||||
}
|
// }
|
||||||
val mem_ades = Wire(Vec(config.fuNum, Bool()))
|
// val mem_ades = Wire(Vec(config.fuNum, Bool()))
|
||||||
for (i <- 0 until config.fuNum) {
|
// for (i <- 0 until config.fuNum) {
|
||||||
mem_ades(i) := VecInit(EXE_SW, EXE_SC).contains(io.inst(i).inst_info.op) && mem_addr(i)(1, 0) =/= 0.U ||
|
// mem_ades(i) := VecInit(EXE_SW, EXE_SC).contains(io.inst(i).inst_info.op) && mem_addr(i)(1, 0) =/= 0.U ||
|
||||||
io.inst(i).inst_info.op === EXE_SH && mem_addr(i)(0) =/= 0.U
|
// io.inst(i).inst_info.op === EXE_SH && mem_addr(i)(0) =/= 0.U
|
||||||
}
|
// }
|
||||||
|
|
||||||
for (i <- 0 until config.fuNum) {
|
// for (i <- 0 until config.fuNum) {
|
||||||
io.inst(i).ex.out := io.inst(i).ex.in
|
// io.inst(i).ex.out := io.inst(i).ex.in
|
||||||
io.inst(i).ex.out.excode := MuxCase(
|
// io.inst(i).ex.out.excode := MuxCase(
|
||||||
io.inst(i).ex.in.excode,
|
// io.inst(i).ex.in.excode,
|
||||||
Seq(
|
// Seq(
|
||||||
(io.inst(i).ex.in.excode =/= EX_NO) -> io.inst(i).ex.in.excode,
|
// (io.inst(i).ex.in.excode =/= EX_NO) -> io.inst(i).ex.in.excode,
|
||||||
mem_adel(i) -> EX_ADEL,
|
// mem_adel(i) -> EX_ADEL,
|
||||||
mem_ades(i) -> EX_ADES,
|
// mem_ades(i) -> EX_ADES,
|
||||||
),
|
// ),
|
||||||
)
|
// )
|
||||||
io.inst(i).ex.out.badvaddr := Mux(
|
// io.inst(i).ex.out.badvaddr := Mux(
|
||||||
VecInit(EX_ADEL, EX_ADES).contains(io.inst(i).ex.in.excode),
|
// VecInit(EX_ADEL, EX_ADES).contains(io.inst(i).ex.in.excode),
|
||||||
io.inst(i).ex.in.badvaddr,
|
// io.inst(i).ex.in.badvaddr,
|
||||||
mem_addr(i),
|
// mem_addr(i),
|
||||||
)
|
// )
|
||||||
io.inst(i).ex.out.flush_req := io.inst(i).ex.in.flush_req || io.inst(i).ex.out.excode =/= EX_NO
|
// io.inst(i).ex.out.flush_req := io.inst(i).ex.in.flush_req || io.inst(i).ex.out.excode =/= EX_NO
|
||||||
}
|
// }
|
||||||
io.inst(0).mem_sel := (io.inst(0).inst_info.wmem || io.inst(0).inst_info.rmem) &&
|
// io.inst(0).mem_sel := (io.inst(0).inst_info.wmem || io.inst(0).inst_info.rmem) &&
|
||||||
!io.inst(0).ex.out.flush_req
|
// !io.inst(0).ex.out.flush_req
|
||||||
io.inst(1).mem_sel := (io.inst(1).inst_info.wmem || io.inst(1).inst_info.rmem) &&
|
// io.inst(1).mem_sel := (io.inst(1).inst_info.wmem || io.inst(1).inst_info.rmem) &&
|
||||||
!io.inst(0).ex.out.flush_req && !io.inst(1).ex.out.flush_req
|
// !io.inst(0).ex.out.flush_req && !io.inst(1).ex.out.flush_req
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
|
@ -1,151 +1,151 @@
|
||||||
package cpu.pipeline.execute
|
// package cpu.pipeline.execute
|
||||||
|
|
||||||
import chisel3._
|
// import chisel3._
|
||||||
import chisel3.util._
|
// import chisel3.util._
|
||||||
import cpu.CpuConfig
|
// import cpu.CpuConfig
|
||||||
import cpu.defines._
|
// import cpu.defines._
|
||||||
import cpu.defines.Const._
|
// import cpu.defines.Const._
|
||||||
import cpu.pipeline.decoder.RegWrite
|
// import cpu.pipeline.decoder.RegWrite
|
||||||
import cpu.pipeline.memory.{ExecuteUnitMemoryUnit, CsrInfo}
|
// import cpu.pipeline.memory.{ExecuteUnitMemoryUnit, CsrInfo}
|
||||||
import cpu.pipeline.fetch.ExecuteUnitBranchPredictor
|
// import cpu.pipeline.fetch.ExecuteUnitBranchPredictor
|
||||||
|
|
||||||
class ExecuteUnit(implicit val config: CpuConfig) extends Module {
|
// class ExecuteUnit(implicit val config: CpuConfig) extends Module {
|
||||||
val io = IO(new Bundle {
|
// val io = IO(new Bundle {
|
||||||
val ctrl = new ExecuteCtrl()
|
// val ctrl = new ExecuteCtrl()
|
||||||
val executeStage = Input(new DecoderUnitExecuteUnit())
|
// val executeStage = Input(new DecoderUnitExecuteUnit())
|
||||||
val csr = Flipped(new CsrExecuteUnit())
|
// val csr = Flipped(new CsrExecuteUnit())
|
||||||
val bpu = new ExecuteUnitBranchPredictor()
|
// val bpu = new ExecuteUnitBranchPredictor()
|
||||||
val fetchUnit = Output(new Bundle {
|
// val fetchUnit = Output(new Bundle {
|
||||||
val branch = Bool()
|
// val branch = Bool()
|
||||||
val target = UInt(PC_WID.W)
|
// val target = UInt(PC_WID.W)
|
||||||
})
|
// })
|
||||||
val decoderUnit = new Bundle {
|
// val decoderUnit = new Bundle {
|
||||||
val forward = Output(
|
// val forward = Output(
|
||||||
Vec(
|
// Vec(
|
||||||
config.fuNum,
|
// config.fuNum,
|
||||||
new Bundle {
|
// new Bundle {
|
||||||
val exe = new RegWrite()
|
// val exe = new RegWrite()
|
||||||
val exe_mem_wreg = Bool()
|
// val exe_mem_wreg = Bool()
|
||||||
},
|
// },
|
||||||
),
|
// ),
|
||||||
)
|
// )
|
||||||
val inst0_bd = Input(Bool())
|
// val inst0_bd = Input(Bool())
|
||||||
}
|
// }
|
||||||
val memoryStage = Output(new ExecuteUnitMemoryUnit())
|
// val memoryStage = Output(new ExecuteUnitMemoryUnit())
|
||||||
|
|
||||||
val statistic = if (!config.build) Some(new BranchPredictorUnitStatistic()) else None
|
// val statistic = if (!config.build) Some(new BranchPredictorUnitStatistic()) else None
|
||||||
})
|
// })
|
||||||
|
|
||||||
val fu = Module(new Fu()).io
|
// val fu = Module(new Fu()).io
|
||||||
val accessMemCtrl = Module(new ExeAccessMemCtrl()).io
|
// val accessMemCtrl = Module(new ExeAccessMemCtrl()).io
|
||||||
|
|
||||||
io.ctrl.inst(0).mem_wreg := io.executeStage.inst0.inst_info.mem_wreg
|
// io.ctrl.inst(0).mem_wreg := io.executeStage.inst0.inst_info.mem_wreg
|
||||||
io.ctrl.inst(0).reg_waddr := io.executeStage.inst0.inst_info.reg_waddr
|
// io.ctrl.inst(0).reg_waddr := io.executeStage.inst0.inst_info.reg_waddr
|
||||||
io.ctrl.inst(1).mem_wreg := io.executeStage.inst1.inst_info.mem_wreg
|
// io.ctrl.inst(1).mem_wreg := io.executeStage.inst1.inst_info.mem_wreg
|
||||||
io.ctrl.inst(1).reg_waddr := io.executeStage.inst1.inst_info.reg_waddr
|
// io.ctrl.inst(1).reg_waddr := io.executeStage.inst1.inst_info.reg_waddr
|
||||||
io.ctrl.branch := io.ctrl.allow_to_go &&
|
// io.ctrl.branch := io.ctrl.allow_to_go &&
|
||||||
(io.executeStage.inst0.jb_info.jump_regiser || fu.branch.pred_fail)
|
// (io.executeStage.inst0.jb_info.jump_regiser || fu.branch.pred_fail)
|
||||||
|
|
||||||
io.csr.in.mtc0_wdata := io.executeStage.inst0.src_info.src2_data
|
// io.csr.in.mtc0_wdata := io.executeStage.inst0.src_info.src2_data
|
||||||
io.csr.in.inst_info(0) := Mux(
|
// io.csr.in.inst_info(0) := Mux(
|
||||||
!io.executeStage.inst0.ex.flush_req,
|
// !io.executeStage.inst0.ex.flush_req,
|
||||||
io.executeStage.inst0.inst_info,
|
// io.executeStage.inst0.inst_info,
|
||||||
0.U.asTypeOf(new InstInfo()),
|
// 0.U.asTypeOf(new InstInfo()),
|
||||||
)
|
// )
|
||||||
io.csr.in.inst_info(1) := io.executeStage.inst1.inst_info
|
// io.csr.in.inst_info(1) := io.executeStage.inst1.inst_info
|
||||||
|
|
||||||
// input accessMemCtrl
|
// // input accessMemCtrl
|
||||||
accessMemCtrl.inst(0).inst_info := io.executeStage.inst0.inst_info
|
// accessMemCtrl.inst(0).inst_info := io.executeStage.inst0.inst_info
|
||||||
accessMemCtrl.inst(0).src_info := io.executeStage.inst0.src_info
|
// accessMemCtrl.inst(0).src_info := io.executeStage.inst0.src_info
|
||||||
accessMemCtrl.inst(0).ex.in := io.executeStage.inst0.ex
|
// accessMemCtrl.inst(0).ex.in := io.executeStage.inst0.ex
|
||||||
accessMemCtrl.inst(1).inst_info := io.executeStage.inst1.inst_info
|
// accessMemCtrl.inst(1).inst_info := io.executeStage.inst1.inst_info
|
||||||
accessMemCtrl.inst(1).src_info := io.executeStage.inst1.src_info
|
// accessMemCtrl.inst(1).src_info := io.executeStage.inst1.src_info
|
||||||
accessMemCtrl.inst(1).ex.in := io.executeStage.inst1.ex
|
// accessMemCtrl.inst(1).ex.in := io.executeStage.inst1.ex
|
||||||
|
|
||||||
// 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).hilo_wen := io.executeStage.inst0.inst_info.whilo
|
// fu.inst(0).hilo_wen := io.executeStage.inst0.inst_info.whilo
|
||||||
fu.inst(0).mul_en := io.executeStage.inst0.inst_info.mul
|
// fu.inst(0).mul_en := io.executeStage.inst0.inst_info.mul
|
||||||
fu.inst(0).div_en := io.executeStage.inst0.inst_info.div
|
// fu.inst(0).div_en := io.executeStage.inst0.inst_info.div
|
||||||
fu.inst(0).inst_info := io.executeStage.inst0.inst_info
|
// fu.inst(0).inst_info := io.executeStage.inst0.inst_info
|
||||||
fu.inst(0).src_info := io.executeStage.inst0.src_info
|
// fu.inst(0).src_info := io.executeStage.inst0.src_info
|
||||||
fu.inst(0).ex.in :=
|
// fu.inst(0).ex.in :=
|
||||||
Mux(io.executeStage.inst0.inst_info.fusel === FU_MEM, accessMemCtrl.inst(0).ex.out, io.executeStage.inst0.ex)
|
// Mux(io.executeStage.inst0.inst_info.fusel === FU_MEM, accessMemCtrl.inst(0).ex.out, io.executeStage.inst0.ex)
|
||||||
fu.inst(1).pc := io.executeStage.inst1.pc
|
// fu.inst(1).pc := io.executeStage.inst1.pc
|
||||||
fu.inst(1).hilo_wen := io.executeStage.inst1.inst_info.whilo
|
// fu.inst(1).hilo_wen := io.executeStage.inst1.inst_info.whilo
|
||||||
fu.inst(1).mul_en := io.executeStage.inst1.inst_info.mul
|
// fu.inst(1).mul_en := io.executeStage.inst1.inst_info.mul
|
||||||
fu.inst(1).div_en := io.executeStage.inst1.inst_info.div
|
// fu.inst(1).div_en := io.executeStage.inst1.inst_info.div
|
||||||
fu.inst(1).inst_info := io.executeStage.inst1.inst_info
|
// fu.inst(1).inst_info := io.executeStage.inst1.inst_info
|
||||||
fu.inst(1).src_info := io.executeStage.inst1.src_info
|
// fu.inst(1).src_info := io.executeStage.inst1.src_info
|
||||||
fu.inst(1).ex.in := io.executeStage.inst1.ex
|
// fu.inst(1).ex.in := io.executeStage.inst1.ex
|
||||||
fu.csr_rdata := io.csr.out.csr_rdata
|
// fu.csr_rdata := io.csr.out.csr_rdata
|
||||||
fu.branch.pred_branch := io.executeStage.inst0.jb_info.pred_branch
|
// 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
|
||||||
io.bpu.branch := fu.branch.branch
|
// io.bpu.branch := fu.branch.branch
|
||||||
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.allow_to_go &&
|
// io.fetchUnit.branch := io.ctrl.allow_to_go &&
|
||||||
(io.executeStage.inst0.jb_info.jump_regiser || fu.branch.pred_fail)
|
// (io.executeStage.inst0.jb_info.jump_regiser || fu.branch.pred_fail)
|
||||||
io.fetchUnit.target := MuxCase(
|
// io.fetchUnit.target := MuxCase(
|
||||||
io.executeStage.inst0.pc + 4.U, // 默认顺序运行吧
|
// io.executeStage.inst0.pc + 4.U, // 默认顺序运行吧
|
||||||
Seq(
|
// 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.jb_info.branch_target,
|
||||||
(fu.branch.pred_fail && !fu.branch.branch) -> Mux(
|
// (fu.branch.pred_fail && !fu.branch.branch) -> Mux(
|
||||||
io.decoderUnit.inst0_bd || io.executeStage.inst1.ex.bd,
|
// io.decoderUnit.inst0_bd || io.executeStage.inst1.ex.bd,
|
||||||
io.executeStage.inst0.pc + 8.U,
|
// io.executeStage.inst0.pc + 8.U,
|
||||||
io.executeStage.inst0.pc + 4.U,
|
// io.executeStage.inst0.pc + 4.U,
|
||||||
),
|
// ),
|
||||||
(io.executeStage.inst0.jb_info.jump_regiser) -> io.executeStage.inst0.src_info.src1_data,
|
// (io.executeStage.inst0.jb_info.jump_regiser) -> io.executeStage.inst0.src_info.src1_data,
|
||||||
),
|
// ),
|
||||||
)
|
// )
|
||||||
|
|
||||||
io.ctrl.fu_stall := fu.stall_req
|
// io.ctrl.fu_stall := fu.stall_req
|
||||||
|
|
||||||
io.memoryStage.inst0.mem.en := accessMemCtrl.mem.out.en
|
// io.memoryStage.inst0.mem.en := accessMemCtrl.mem.out.en
|
||||||
io.memoryStage.inst0.mem.ren := accessMemCtrl.mem.out.ren
|
// io.memoryStage.inst0.mem.ren := accessMemCtrl.mem.out.ren
|
||||||
io.memoryStage.inst0.mem.wen := accessMemCtrl.mem.out.wen
|
// io.memoryStage.inst0.mem.wen := accessMemCtrl.mem.out.wen
|
||||||
io.memoryStage.inst0.mem.addr := accessMemCtrl.mem.out.addr
|
// io.memoryStage.inst0.mem.addr := accessMemCtrl.mem.out.addr
|
||||||
io.memoryStage.inst0.mem.wdata := accessMemCtrl.mem.out.wdata
|
// io.memoryStage.inst0.mem.wdata := accessMemCtrl.mem.out.wdata
|
||||||
io.memoryStage.inst0.mem.sel := accessMemCtrl.inst.map(_.mem_sel)
|
// io.memoryStage.inst0.mem.sel := accessMemCtrl.inst.map(_.mem_sel)
|
||||||
io.memoryStage.inst0.mem.inst_info := accessMemCtrl.mem.out.inst_info
|
// io.memoryStage.inst0.mem.inst_info := accessMemCtrl.mem.out.inst_info
|
||||||
io.memoryStage.inst0.mem.llbit := fu.llbit
|
// io.memoryStage.inst0.mem.llbit := fu.llbit
|
||||||
|
|
||||||
io.memoryStage.inst0.pc := io.executeStage.inst0.pc
|
// io.memoryStage.inst0.pc := io.executeStage.inst0.pc
|
||||||
io.memoryStage.inst0.inst_info := io.executeStage.inst0.inst_info
|
// io.memoryStage.inst0.inst_info := io.executeStage.inst0.inst_info
|
||||||
io.memoryStage.inst0.rd_info.wdata := fu.inst(0).result
|
// io.memoryStage.inst0.rd_info.wdata := fu.inst(0).result
|
||||||
io.memoryStage.inst0.ex := Mux(
|
// io.memoryStage.inst0.ex := Mux(
|
||||||
io.executeStage.inst0.inst_info.fusel === FU_MEM,
|
// io.executeStage.inst0.inst_info.fusel === FU_MEM,
|
||||||
accessMemCtrl.inst(0).ex.out,
|
// accessMemCtrl.inst(0).ex.out,
|
||||||
fu.inst(0).ex.out,
|
// fu.inst(0).ex.out,
|
||||||
)
|
// )
|
||||||
io.memoryStage.inst0.csr := io.csr.out.debug
|
// io.memoryStage.inst0.csr := io.csr.out.debug
|
||||||
|
|
||||||
io.memoryStage.inst1.pc := io.executeStage.inst1.pc
|
// io.memoryStage.inst1.pc := io.executeStage.inst1.pc
|
||||||
io.memoryStage.inst1.inst_info := io.executeStage.inst1.inst_info
|
// io.memoryStage.inst1.inst_info := io.executeStage.inst1.inst_info
|
||||||
io.memoryStage.inst1.rd_info.wdata := fu.inst(1).result
|
// io.memoryStage.inst1.rd_info.wdata := fu.inst(1).result
|
||||||
io.memoryStage.inst1.ex := Mux(
|
// io.memoryStage.inst1.ex := Mux(
|
||||||
io.executeStage.inst1.inst_info.fusel === FU_MEM,
|
// io.executeStage.inst1.inst_info.fusel === FU_MEM,
|
||||||
accessMemCtrl.inst(1).ex.out,
|
// accessMemCtrl.inst(1).ex.out,
|
||||||
fu.inst(1).ex.out,
|
// fu.inst(1).ex.out,
|
||||||
)
|
// )
|
||||||
|
|
||||||
io.decoderUnit.forward(0).exe.wen := io.memoryStage.inst0.inst_info.reg_wen
|
// io.decoderUnit.forward(0).exe.wen := io.memoryStage.inst0.inst_info.reg_wen
|
||||||
io.decoderUnit.forward(0).exe.waddr := io.memoryStage.inst0.inst_info.reg_waddr
|
// io.decoderUnit.forward(0).exe.waddr := io.memoryStage.inst0.inst_info.reg_waddr
|
||||||
io.decoderUnit.forward(0).exe.wdata := io.memoryStage.inst0.rd_info.wdata
|
// io.decoderUnit.forward(0).exe.wdata := io.memoryStage.inst0.rd_info.wdata
|
||||||
io.decoderUnit.forward(0).exe_mem_wreg := io.memoryStage.inst0.inst_info.mem_wreg
|
// io.decoderUnit.forward(0).exe_mem_wreg := io.memoryStage.inst0.inst_info.mem_wreg
|
||||||
|
|
||||||
io.decoderUnit.forward(1).exe.wen := io.memoryStage.inst1.inst_info.reg_wen
|
// io.decoderUnit.forward(1).exe.wen := io.memoryStage.inst1.inst_info.reg_wen
|
||||||
io.decoderUnit.forward(1).exe.waddr := io.memoryStage.inst1.inst_info.reg_waddr
|
// io.decoderUnit.forward(1).exe.waddr := io.memoryStage.inst1.inst_info.reg_waddr
|
||||||
io.decoderUnit.forward(1).exe.wdata := io.memoryStage.inst1.rd_info.wdata
|
// io.decoderUnit.forward(1).exe.wdata := io.memoryStage.inst1.rd_info.wdata
|
||||||
io.decoderUnit.forward(1).exe_mem_wreg := io.memoryStage.inst1.inst_info.mem_wreg
|
// io.decoderUnit.forward(1).exe_mem_wreg := io.memoryStage.inst1.inst_info.mem_wreg
|
||||||
|
|
||||||
// ===----------------------------------------------------------------===
|
// // ===----------------------------------------------------------------===
|
||||||
// statistic
|
// // statistic
|
||||||
// ===----------------------------------------------------------------===
|
// // ===----------------------------------------------------------------===
|
||||||
if (!config.build) {
|
// if (!config.build) {
|
||||||
io.statistic.get <> fu.statistic.get
|
// io.statistic.get <> fu.statistic.get
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
|
@ -1,199 +1,199 @@
|
||||||
package cpu.pipeline.fetch
|
// package cpu.pipeline.fetch
|
||||||
|
|
||||||
import chisel3._
|
// import chisel3._
|
||||||
import chisel3.util._
|
// import chisel3.util._
|
||||||
import cpu.defines.Const._
|
// import cpu.defines.Const._
|
||||||
import cpu._
|
// import cpu._
|
||||||
import cpu.pipeline.decoder.Src12Read
|
// import cpu.pipeline.decoder.Src12Read
|
||||||
|
|
||||||
class ExecuteUnitBranchPredictor extends Bundle {
|
// class ExecuteUnitBranchPredictor extends Bundle {
|
||||||
val bpuConfig = new BranchPredictorConfig()
|
// val bpuConfig = new BranchPredictorConfig()
|
||||||
val pc = Output(UInt(PC_WID.W))
|
// val pc = Output(UInt(PC_WID.W))
|
||||||
val update_pht_index = Output(UInt(bpuConfig.phtDepth.W))
|
// val update_pht_index = Output(UInt(bpuConfig.phtDepth.W))
|
||||||
val branch_inst = Output(Bool())
|
// val branch_inst = Output(Bool())
|
||||||
val branch = Output(Bool())
|
// val branch = Output(Bool())
|
||||||
}
|
// }
|
||||||
|
|
||||||
class BranchPredictorIO(implicit config: CpuConfig) extends Bundle {
|
// class BranchPredictorIO(implicit config: CpuConfig) extends Bundle {
|
||||||
val bpuConfig = new BranchPredictorConfig()
|
// val bpuConfig = new BranchPredictorConfig()
|
||||||
val decoder = new Bundle {
|
// val decoder = new Bundle {
|
||||||
val inst = Input(UInt(INST_WID.W))
|
// val inst = Input(UInt(INST_WID.W))
|
||||||
val op = Input(UInt(OP_WID.W))
|
// val op = Input(UInt(OP_WID.W))
|
||||||
val ena = Input(Bool())
|
// val ena = Input(Bool())
|
||||||
val pc = Input(UInt(PC_WID.W))
|
// val pc = Input(UInt(PC_WID.W))
|
||||||
val pc_plus4 = Input(UInt(PC_WID.W))
|
// val pc_plus4 = Input(UInt(PC_WID.W))
|
||||||
val pht_index = Input(UInt(bpuConfig.phtDepth.W))
|
// val pht_index = Input(UInt(bpuConfig.phtDepth.W))
|
||||||
|
|
||||||
val rs1 = Input(UInt(REG_ADDR_WID.W))
|
// val rs1 = Input(UInt(REG_ADDR_WID.W))
|
||||||
val rs2 = Input(UInt(REG_ADDR_WID.W))
|
// val rs2 = Input(UInt(REG_ADDR_WID.W))
|
||||||
|
|
||||||
val branch_inst = Output(Bool())
|
// val branch_inst = Output(Bool())
|
||||||
val pred_branch = Output(Bool())
|
// val pred_branch = Output(Bool())
|
||||||
val branch_target = Output(UInt(PC_WID.W))
|
// val branch_target = Output(UInt(PC_WID.W))
|
||||||
val update_pht_index = Output(UInt(bpuConfig.phtDepth.W))
|
// val update_pht_index = Output(UInt(bpuConfig.phtDepth.W))
|
||||||
}
|
// }
|
||||||
|
|
||||||
val instBuffer = new Bundle {
|
// val instBuffer = new Bundle {
|
||||||
val pc = Input(Vec(config.instFetchNum, UInt(PC_WID.W)))
|
// val pc = Input(Vec(config.instFetchNum, UInt(PC_WID.W)))
|
||||||
val pht_index = Output(Vec(config.instFetchNum, UInt(bpuConfig.phtDepth.W)))
|
// val pht_index = Output(Vec(config.instFetchNum, UInt(bpuConfig.phtDepth.W)))
|
||||||
}
|
// }
|
||||||
|
|
||||||
val execute = Flipped(new ExecuteUnitBranchPredictor())
|
// val execute = Flipped(new ExecuteUnitBranchPredictor())
|
||||||
|
|
||||||
val regfile = if (config.branchPredictor == "pesudo") Some(new Src12Read()) else None
|
// val regfile = if (config.branchPredictor == "pesudo") Some(new Src12Read()) else None
|
||||||
}
|
// }
|
||||||
|
|
||||||
class BranchPredictorUnit(implicit config: CpuConfig) extends Module {
|
// class BranchPredictorUnit(implicit config: CpuConfig) extends Module {
|
||||||
val io = IO(new BranchPredictorIO())
|
// val io = IO(new BranchPredictorIO())
|
||||||
|
|
||||||
if (config.branchPredictor == "adaptive") {
|
// if (config.branchPredictor == "adaptive") {
|
||||||
val adaptive_predictor = Module(new AdaptiveTwoLevelPredictor())
|
// val adaptive_predictor = Module(new AdaptiveTwoLevelPredictor())
|
||||||
io <> adaptive_predictor.io
|
// io <> adaptive_predictor.io
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (config.branchPredictor == "pesudo") {
|
// if (config.branchPredictor == "pesudo") {
|
||||||
val pesudo_predictor = Module(new PesudoBranchPredictor())
|
// val pesudo_predictor = Module(new PesudoBranchPredictor())
|
||||||
io <> pesudo_predictor.io
|
// io <> pesudo_predictor.io
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (config.branchPredictor == "global") {
|
// if (config.branchPredictor == "global") {
|
||||||
val global_predictor = Module(new GlobalBranchPredictor())
|
// val global_predictor = Module(new GlobalBranchPredictor())
|
||||||
io <> global_predictor.io
|
// io <> global_predictor.io
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
class PesudoBranchPredictor(implicit config: CpuConfig) extends Module {
|
// class PesudoBranchPredictor(implicit config: CpuConfig) extends Module {
|
||||||
val io = IO(new BranchPredictorIO())
|
// val io = IO(new BranchPredictorIO())
|
||||||
io.decoder.branch_inst := VecInit(EXE_BEQ, EXE_BNE, EXE_BGTZ, EXE_BLEZ, EXE_BGEZ, EXE_BGEZAL, EXE_BLTZ, EXE_BLTZAL)
|
// io.decoder.branch_inst := VecInit(EXE_BEQ, EXE_BNE, EXE_BGTZ, EXE_BLEZ, EXE_BGEZ, EXE_BGEZAL, EXE_BLTZ, EXE_BLTZAL)
|
||||||
.contains(io.decoder.op)
|
// .contains(io.decoder.op)
|
||||||
io.decoder.branch_target := io.decoder.pc_plus4 + Cat(
|
// io.decoder.branch_target := io.decoder.pc_plus4 + Cat(
|
||||||
Fill(14, io.decoder.inst(15)),
|
// Fill(14, io.decoder.inst(15)),
|
||||||
io.decoder.inst(15, 0),
|
// io.decoder.inst(15, 0),
|
||||||
0.U(2.W)
|
// 0.U(2.W)
|
||||||
)
|
// )
|
||||||
|
|
||||||
io.regfile.get.src1.raddr := io.decoder.rs1
|
// io.regfile.get.src1.raddr := io.decoder.rs1
|
||||||
io.regfile.get.src2.raddr := io.decoder.rs2
|
// io.regfile.get.src2.raddr := io.decoder.rs2
|
||||||
val (src1, src2) = (io.regfile.get.src1.rdata, io.regfile.get.src2.rdata)
|
// val (src1, src2) = (io.regfile.get.src1.rdata, io.regfile.get.src2.rdata)
|
||||||
val pred_branch = MuxLookup(io.decoder.op, false.B)(
|
// val pred_branch = MuxLookup(io.decoder.op, false.B)(
|
||||||
Seq(
|
// Seq(
|
||||||
EXE_BEQ -> (src1 === src2),
|
// EXE_BEQ -> (src1 === src2),
|
||||||
EXE_BNE -> (src1 =/= src2),
|
// EXE_BNE -> (src1 =/= src2),
|
||||||
EXE_BGTZ -> (!src1(31) && (src1 =/= 0.U)),
|
// EXE_BGTZ -> (!src1(31) && (src1 =/= 0.U)),
|
||||||
EXE_BLEZ -> (src1(31) || src1 === 0.U),
|
// EXE_BLEZ -> (src1(31) || src1 === 0.U),
|
||||||
EXE_BGEZ -> (!src1(31)),
|
// EXE_BGEZ -> (!src1(31)),
|
||||||
EXE_BGEZAL -> (!src1(31)),
|
// EXE_BGEZAL -> (!src1(31)),
|
||||||
EXE_BLTZ -> (src1(31)),
|
// EXE_BLTZ -> (src1(31)),
|
||||||
EXE_BLTZAL -> (src1(31))
|
// EXE_BLTZAL -> (src1(31))
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
|
|
||||||
io.decoder.pred_branch := io.decoder.ena && io.decoder.branch_inst && pred_branch
|
// io.decoder.pred_branch := io.decoder.ena && io.decoder.branch_inst && pred_branch
|
||||||
}
|
// }
|
||||||
|
|
||||||
class GlobalBranchPredictor(
|
// class GlobalBranchPredictor(
|
||||||
GHR_DEPTH: Int = 4, // 可以记录的历史记录个数
|
// GHR_DEPTH: Int = 4, // 可以记录的历史记录个数
|
||||||
PC_HASH_WID: Int = 4, // 取得PC的宽度
|
// PC_HASH_WID: Int = 4, // 取得PC的宽度
|
||||||
PHT_DEPTH: Int = 6, // 可以记录的历史个数
|
// PHT_DEPTH: Int = 6, // 可以记录的历史个数
|
||||||
BHT_DEPTH: Int = 4 // 取得PC的宽度
|
// BHT_DEPTH: Int = 4 // 取得PC的宽度
|
||||||
)(
|
// )(
|
||||||
implicit
|
// implicit
|
||||||
config: CpuConfig)
|
// config: CpuConfig)
|
||||||
extends Module {
|
// extends Module {
|
||||||
val io = IO(new BranchPredictorIO())
|
// val io = IO(new BranchPredictorIO())
|
||||||
|
|
||||||
val strongly_not_taken :: weakly_not_taken :: weakly_taken :: strongly_taken :: Nil = Enum(4)
|
// val strongly_not_taken :: weakly_not_taken :: weakly_taken :: strongly_taken :: Nil = Enum(4)
|
||||||
|
|
||||||
io.decoder.branch_inst := VecInit(EXE_BEQ, EXE_BNE, EXE_BGTZ, EXE_BLEZ, EXE_BGEZ, EXE_BGEZAL, EXE_BLTZ, EXE_BLTZAL)
|
// io.decoder.branch_inst := VecInit(EXE_BEQ, EXE_BNE, EXE_BGTZ, EXE_BLEZ, EXE_BGEZ, EXE_BGEZAL, EXE_BLTZ, EXE_BLTZAL)
|
||||||
.contains(io.decoder.op)
|
// .contains(io.decoder.op)
|
||||||
io.decoder.branch_target := io.decoder.pc_plus4 + Cat(
|
// io.decoder.branch_target := io.decoder.pc_plus4 + Cat(
|
||||||
Fill(14, io.decoder.inst(15)),
|
// Fill(14, io.decoder.inst(15)),
|
||||||
io.decoder.inst(15, 0),
|
// io.decoder.inst(15, 0),
|
||||||
0.U(2.W)
|
// 0.U(2.W)
|
||||||
)
|
// )
|
||||||
// 局部预测模式
|
// // 局部预测模式
|
||||||
|
|
||||||
val bht = RegInit(VecInit(Seq.fill(1 << BHT_DEPTH)(0.U(PHT_DEPTH.W))))
|
// val bht = RegInit(VecInit(Seq.fill(1 << BHT_DEPTH)(0.U(PHT_DEPTH.W))))
|
||||||
val pht = RegInit(VecInit(Seq.fill(1 << PHT_DEPTH)(strongly_taken)))
|
// val pht = RegInit(VecInit(Seq.fill(1 << PHT_DEPTH)(strongly_taken)))
|
||||||
val bht_index = io.decoder.pc(1 + BHT_DEPTH, 2)
|
// val bht_index = io.decoder.pc(1 + BHT_DEPTH, 2)
|
||||||
val pht_index = bht(bht_index)
|
// val pht_index = bht(bht_index)
|
||||||
|
|
||||||
io.decoder.pred_branch :=
|
// io.decoder.pred_branch :=
|
||||||
io.decoder.ena && io.decoder.branch_inst && (pht(pht_index) === weakly_taken || pht(pht_index) === strongly_taken)
|
// io.decoder.ena && io.decoder.branch_inst && (pht(pht_index) === weakly_taken || pht(pht_index) === strongly_taken)
|
||||||
val update_bht_index = io.execute.pc(1 + BHT_DEPTH, 2)
|
// val update_bht_index = io.execute.pc(1 + BHT_DEPTH, 2)
|
||||||
val update_pht_index = bht(update_bht_index)
|
// val update_pht_index = bht(update_bht_index)
|
||||||
|
|
||||||
when(io.execute.branch_inst) {
|
// when(io.execute.branch_inst) {
|
||||||
bht(update_bht_index) := Cat(bht(update_bht_index)(PHT_DEPTH - 2, 0), io.execute.branch)
|
// bht(update_bht_index) := Cat(bht(update_bht_index)(PHT_DEPTH - 2, 0), io.execute.branch)
|
||||||
switch(pht(update_pht_index)) {
|
// switch(pht(update_pht_index)) {
|
||||||
is(strongly_not_taken) {
|
// is(strongly_not_taken) {
|
||||||
pht(update_pht_index) := Mux(io.execute.branch, weakly_not_taken, strongly_not_taken)
|
// pht(update_pht_index) := Mux(io.execute.branch, weakly_not_taken, strongly_not_taken)
|
||||||
}
|
// }
|
||||||
is(weakly_not_taken) {
|
// is(weakly_not_taken) {
|
||||||
pht(update_pht_index) := Mux(io.execute.branch, weakly_taken, strongly_not_taken)
|
// pht(update_pht_index) := Mux(io.execute.branch, weakly_taken, strongly_not_taken)
|
||||||
}
|
// }
|
||||||
is(weakly_taken) {
|
// is(weakly_taken) {
|
||||||
pht(update_pht_index) := Mux(io.execute.branch, strongly_taken, weakly_not_taken)
|
// pht(update_pht_index) := Mux(io.execute.branch, strongly_taken, weakly_not_taken)
|
||||||
}
|
// }
|
||||||
is(strongly_taken) {
|
// is(strongly_taken) {
|
||||||
pht(update_pht_index) := Mux(io.execute.branch, strongly_taken, weakly_taken)
|
// pht(update_pht_index) := Mux(io.execute.branch, strongly_taken, weakly_taken)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
class AdaptiveTwoLevelPredictor(
|
// class AdaptiveTwoLevelPredictor(
|
||||||
)(
|
// )(
|
||||||
implicit
|
// implicit
|
||||||
config: CpuConfig)
|
// config: CpuConfig)
|
||||||
extends Module {
|
// extends Module {
|
||||||
val bpuConfig = new BranchPredictorConfig()
|
// val bpuConfig = new BranchPredictorConfig()
|
||||||
val PHT_DEPTH = bpuConfig.phtDepth
|
// val PHT_DEPTH = bpuConfig.phtDepth
|
||||||
val BHT_DEPTH = bpuConfig.bhtDepth
|
// val BHT_DEPTH = bpuConfig.bhtDepth
|
||||||
val io = IO(new BranchPredictorIO())
|
// val io = IO(new BranchPredictorIO())
|
||||||
|
|
||||||
val strongly_not_taken :: weakly_not_taken :: weakly_taken :: strongly_taken :: Nil = Enum(4)
|
// val strongly_not_taken :: weakly_not_taken :: weakly_taken :: strongly_taken :: Nil = Enum(4)
|
||||||
|
|
||||||
io.decoder.branch_inst :=
|
// io.decoder.branch_inst :=
|
||||||
VecInit(EXE_BEQ, EXE_BNE, EXE_BGTZ, EXE_BLEZ, EXE_BGEZ, EXE_BGEZAL, EXE_BLTZ, EXE_BLTZAL).contains(io.decoder.op)
|
// VecInit(EXE_BEQ, EXE_BNE, EXE_BGTZ, EXE_BLEZ, EXE_BGEZ, EXE_BGEZAL, EXE_BLTZ, EXE_BLTZAL).contains(io.decoder.op)
|
||||||
io.decoder.branch_target := io.decoder.pc_plus4 + Cat(
|
// io.decoder.branch_target := io.decoder.pc_plus4 + Cat(
|
||||||
Fill(14, io.decoder.inst(15)),
|
// Fill(14, io.decoder.inst(15)),
|
||||||
io.decoder.inst(15, 0),
|
// io.decoder.inst(15, 0),
|
||||||
0.U(2.W)
|
// 0.U(2.W)
|
||||||
)
|
// )
|
||||||
|
|
||||||
val bht = RegInit(VecInit(Seq.fill(1 << BHT_DEPTH)(0.U(PHT_DEPTH.W))))
|
// val bht = RegInit(VecInit(Seq.fill(1 << BHT_DEPTH)(0.U(PHT_DEPTH.W))))
|
||||||
val pht = RegInit(VecInit(Seq.fill(1 << PHT_DEPTH)(strongly_taken)))
|
// val pht = RegInit(VecInit(Seq.fill(1 << PHT_DEPTH)(strongly_taken)))
|
||||||
val pht_index = io.decoder.pht_index
|
// val pht_index = io.decoder.pht_index
|
||||||
|
|
||||||
for (i <- 0 until config.instFetchNum) {
|
// for (i <- 0 until config.instFetchNum) {
|
||||||
io.instBuffer.pht_index(i) := bht(io.instBuffer.pc(i)(1 + BHT_DEPTH, 2))
|
// io.instBuffer.pht_index(i) := bht(io.instBuffer.pc(i)(1 + BHT_DEPTH, 2))
|
||||||
}
|
// }
|
||||||
|
|
||||||
io.decoder.pred_branch :=
|
// io.decoder.pred_branch :=
|
||||||
io.decoder.ena && io.decoder.branch_inst && (pht(pht_index) === weakly_taken || pht(pht_index) === strongly_taken)
|
// io.decoder.ena && io.decoder.branch_inst && (pht(pht_index) === weakly_taken || pht(pht_index) === strongly_taken)
|
||||||
io.decoder.update_pht_index := bht(io.decoder.pc(1 + BHT_DEPTH, 2))
|
// io.decoder.update_pht_index := bht(io.decoder.pc(1 + BHT_DEPTH, 2))
|
||||||
|
|
||||||
val update_bht_index = io.execute.pc(1 + BHT_DEPTH, 2)
|
// val update_bht_index = io.execute.pc(1 + BHT_DEPTH, 2)
|
||||||
val update_pht_index = io.execute.update_pht_index
|
// val update_pht_index = io.execute.update_pht_index
|
||||||
|
|
||||||
when(io.execute.branch_inst) {
|
// when(io.execute.branch_inst) {
|
||||||
bht(update_bht_index) := Cat(bht(update_bht_index)(PHT_DEPTH - 2, 0), io.execute.branch)
|
// bht(update_bht_index) := Cat(bht(update_bht_index)(PHT_DEPTH - 2, 0), io.execute.branch)
|
||||||
switch(pht(update_pht_index)) {
|
// switch(pht(update_pht_index)) {
|
||||||
is(strongly_not_taken) {
|
// is(strongly_not_taken) {
|
||||||
pht(update_pht_index) := Mux(io.execute.branch, weakly_not_taken, strongly_not_taken)
|
// pht(update_pht_index) := Mux(io.execute.branch, weakly_not_taken, strongly_not_taken)
|
||||||
}
|
// }
|
||||||
is(weakly_not_taken) {
|
// is(weakly_not_taken) {
|
||||||
pht(update_pht_index) := Mux(io.execute.branch, weakly_taken, strongly_not_taken)
|
// pht(update_pht_index) := Mux(io.execute.branch, weakly_taken, strongly_not_taken)
|
||||||
}
|
// }
|
||||||
is(weakly_taken) {
|
// is(weakly_taken) {
|
||||||
pht(update_pht_index) := Mux(io.execute.branch, strongly_taken, weakly_not_taken)
|
// pht(update_pht_index) := Mux(io.execute.branch, strongly_taken, weakly_not_taken)
|
||||||
}
|
// }
|
||||||
is(strongly_taken) {
|
// is(strongly_taken) {
|
||||||
pht(update_pht_index) := Mux(io.execute.branch, strongly_taken, weakly_taken)
|
// pht(update_pht_index) := Mux(io.execute.branch, strongly_taken, weakly_taken)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
|
@ -1,168 +1,168 @@
|
||||||
package cpu.pipeline.memory
|
// package cpu.pipeline.memory
|
||||||
|
|
||||||
import chisel3._
|
// import chisel3._
|
||||||
import chisel3.util._
|
// import chisel3.util._
|
||||||
import cpu.defines._
|
// import cpu.defines._
|
||||||
import cpu.defines.Const._
|
// import cpu.defines.Const._
|
||||||
import cpu.CpuConfig
|
// import cpu.CpuConfig
|
||||||
|
|
||||||
class DataMemoryAccess(implicit val config: CpuConfig) extends Module {
|
// class DataMemoryAccess(implicit val config: CpuConfig) extends Module {
|
||||||
val io = IO(new Bundle {
|
// val io = IO(new Bundle {
|
||||||
val memoryUnit = new Bundle {
|
// val memoryUnit = new Bundle {
|
||||||
val in = Input(new Bundle {
|
// val in = Input(new Bundle {
|
||||||
val mem_en = Bool()
|
// val mem_en = Bool()
|
||||||
val inst_info = new InstInfo()
|
// val inst_info = new InstInfo()
|
||||||
val mem_wdata = UInt(DATA_WID.W)
|
// val mem_wdata = UInt(DATA_WID.W)
|
||||||
val mem_addr = UInt(DATA_ADDR_WID.W)
|
// val mem_addr = UInt(DATA_ADDR_WID.W)
|
||||||
val mem_sel = Vec(config.fuNum, Bool())
|
// val mem_sel = Vec(config.fuNum, Bool())
|
||||||
val ex = Vec(config.fuNum, new ExceptionInfo())
|
// val ex = Vec(config.fuNum, new ExceptionInfo())
|
||||||
val llbit = Bool()
|
// val llbit = Bool()
|
||||||
})
|
// })
|
||||||
val out = Output(new Bundle {
|
// val out = Output(new Bundle {
|
||||||
val rdata = Output(UInt(DATA_WID.W))
|
// val rdata = Output(UInt(DATA_WID.W))
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
val dataMemory = new Bundle {
|
// val dataMemory = new Bundle {
|
||||||
val in = Input(new Bundle {
|
// val in = Input(new Bundle {
|
||||||
val rdata = UInt(DATA_WID.W)
|
// val rdata = UInt(DATA_WID.W)
|
||||||
})
|
// })
|
||||||
val out = Output(new Bundle {
|
// val out = Output(new Bundle {
|
||||||
val en = Bool()
|
// val en = Bool()
|
||||||
val rlen = UInt(2.W)
|
// val rlen = UInt(2.W)
|
||||||
val wen = UInt(4.W)
|
// val wen = UInt(4.W)
|
||||||
val addr = UInt(DATA_ADDR_WID.W)
|
// val addr = UInt(DATA_ADDR_WID.W)
|
||||||
val wdata = UInt(DATA_WID.W)
|
// val wdata = UInt(DATA_WID.W)
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
val mem_addr = io.memoryUnit.in.mem_addr
|
// val mem_addr = io.memoryUnit.in.mem_addr
|
||||||
val mem_addr2 = mem_addr(1, 0)
|
// val mem_addr2 = mem_addr(1, 0)
|
||||||
val mem_rdata = io.dataMemory.in.rdata
|
// val mem_rdata = io.dataMemory.in.rdata
|
||||||
val mem_wdata = io.memoryUnit.in.mem_wdata
|
// val mem_wdata = io.memoryUnit.in.mem_wdata
|
||||||
val op = io.memoryUnit.in.inst_info.op
|
// val op = io.memoryUnit.in.inst_info.op
|
||||||
io.dataMemory.out.en := io.memoryUnit.in.mem_en &&
|
// io.dataMemory.out.en := io.memoryUnit.in.mem_en &&
|
||||||
(io.memoryUnit.in.mem_sel(0) && !io.memoryUnit.in.ex(0).flush_req ||
|
// (io.memoryUnit.in.mem_sel(0) && !io.memoryUnit.in.ex(0).flush_req ||
|
||||||
io.memoryUnit.in.mem_sel(1) && !io.memoryUnit.in.ex(0).flush_req && !io.memoryUnit.in.ex(1).flush_req)
|
// io.memoryUnit.in.mem_sel(1) && !io.memoryUnit.in.ex(0).flush_req && !io.memoryUnit.in.ex(1).flush_req)
|
||||||
io.dataMemory.out.addr := mem_addr
|
// io.dataMemory.out.addr := mem_addr
|
||||||
|
|
||||||
io.memoryUnit.out.rdata := MuxLookup(op, 0.U)(
|
// io.memoryUnit.out.rdata := MuxLookup(op, 0.U)(
|
||||||
Seq(
|
// Seq(
|
||||||
EXE_LB -> MuxLookup(mem_addr2, 0.U)(
|
// EXE_LB -> MuxLookup(mem_addr2, 0.U)(
|
||||||
Seq(
|
// Seq(
|
||||||
"b11".U -> Util.signedExtend(mem_rdata(31, 24)),
|
// "b11".U -> Util.signedExtend(mem_rdata(31, 24)),
|
||||||
"b10".U -> Util.signedExtend(mem_rdata(23, 16)),
|
// "b10".U -> Util.signedExtend(mem_rdata(23, 16)),
|
||||||
"b01".U -> Util.signedExtend(mem_rdata(15, 8)),
|
// "b01".U -> Util.signedExtend(mem_rdata(15, 8)),
|
||||||
"b00".U -> Util.signedExtend(mem_rdata(7, 0))
|
// "b00".U -> Util.signedExtend(mem_rdata(7, 0))
|
||||||
)
|
// )
|
||||||
),
|
// ),
|
||||||
EXE_LBU -> MuxLookup(mem_addr2, 0.U)(
|
// EXE_LBU -> MuxLookup(mem_addr2, 0.U)(
|
||||||
Seq(
|
// Seq(
|
||||||
"b11".U -> Util.zeroExtend(mem_rdata(31, 24)),
|
// "b11".U -> Util.zeroExtend(mem_rdata(31, 24)),
|
||||||
"b10".U -> Util.zeroExtend(mem_rdata(23, 16)),
|
// "b10".U -> Util.zeroExtend(mem_rdata(23, 16)),
|
||||||
"b01".U -> Util.zeroExtend(mem_rdata(15, 8)),
|
// "b01".U -> Util.zeroExtend(mem_rdata(15, 8)),
|
||||||
"b00".U -> Util.zeroExtend(mem_rdata(7, 0))
|
// "b00".U -> Util.zeroExtend(mem_rdata(7, 0))
|
||||||
)
|
// )
|
||||||
),
|
// ),
|
||||||
EXE_LH -> Mux(
|
// EXE_LH -> Mux(
|
||||||
mem_addr2(1),
|
// mem_addr2(1),
|
||||||
Util.signedExtend(mem_rdata(31, 16)),
|
// Util.signedExtend(mem_rdata(31, 16)),
|
||||||
Util.signedExtend(mem_rdata(15, 0))
|
// Util.signedExtend(mem_rdata(15, 0))
|
||||||
),
|
// ),
|
||||||
EXE_LHU -> Mux(
|
// EXE_LHU -> Mux(
|
||||||
mem_addr2(1),
|
// mem_addr2(1),
|
||||||
Util.zeroExtend(mem_rdata(31, 16)),
|
// Util.zeroExtend(mem_rdata(31, 16)),
|
||||||
Util.zeroExtend(mem_rdata(15, 0))
|
// Util.zeroExtend(mem_rdata(15, 0))
|
||||||
),
|
// ),
|
||||||
EXE_LW -> mem_rdata,
|
// EXE_LW -> mem_rdata,
|
||||||
EXE_LL -> mem_rdata,
|
// EXE_LL -> mem_rdata,
|
||||||
EXE_LWL -> MuxLookup(mem_addr2, 0.U)(
|
// EXE_LWL -> MuxLookup(mem_addr2, 0.U)(
|
||||||
Seq(
|
// Seq(
|
||||||
"b11".U -> mem_rdata,
|
// "b11".U -> mem_rdata,
|
||||||
"b10".U -> Cat(mem_rdata(23, 0), mem_wdata(7, 0)),
|
// "b10".U -> Cat(mem_rdata(23, 0), mem_wdata(7, 0)),
|
||||||
"b01".U -> Cat(mem_rdata(15, 0), mem_wdata(15, 0)),
|
// "b01".U -> Cat(mem_rdata(15, 0), mem_wdata(15, 0)),
|
||||||
"b00".U -> Cat(mem_rdata(7, 0), mem_wdata(23, 0))
|
// "b00".U -> Cat(mem_rdata(7, 0), mem_wdata(23, 0))
|
||||||
)
|
// )
|
||||||
),
|
// ),
|
||||||
EXE_LWR -> MuxLookup(mem_addr2, 0.U)(
|
// EXE_LWR -> MuxLookup(mem_addr2, 0.U)(
|
||||||
Seq(
|
// Seq(
|
||||||
"b11".U -> Cat(mem_wdata(31, 8), mem_rdata(31, 24)),
|
// "b11".U -> Cat(mem_wdata(31, 8), mem_rdata(31, 24)),
|
||||||
"b10".U -> Cat(mem_wdata(31, 16), mem_rdata(31, 16)),
|
// "b10".U -> Cat(mem_wdata(31, 16), mem_rdata(31, 16)),
|
||||||
"b01".U -> Cat(mem_wdata(31, 24), mem_rdata(31, 8)),
|
// "b01".U -> Cat(mem_wdata(31, 24), mem_rdata(31, 8)),
|
||||||
"b00".U -> mem_rdata
|
// "b00".U -> mem_rdata
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
io.dataMemory.out.wdata := MuxLookup(op, mem_wdata)( // default SW, SC
|
// io.dataMemory.out.wdata := MuxLookup(op, mem_wdata)( // default SW, SC
|
||||||
Seq(
|
// Seq(
|
||||||
EXE_SB -> Fill(4, mem_wdata(7, 0)),
|
// EXE_SB -> Fill(4, mem_wdata(7, 0)),
|
||||||
EXE_SH -> Fill(2, mem_wdata(15, 0)),
|
// EXE_SH -> Fill(2, mem_wdata(15, 0)),
|
||||||
EXE_SWL -> MuxLookup(mem_addr2, 0.U)(
|
// EXE_SWL -> MuxLookup(mem_addr2, 0.U)(
|
||||||
Seq(
|
// Seq(
|
||||||
"b11".U -> mem_wdata,
|
// "b11".U -> mem_wdata,
|
||||||
"b10".U -> Cat(0.U(8.W), mem_wdata(31, 8)),
|
// "b10".U -> Cat(0.U(8.W), mem_wdata(31, 8)),
|
||||||
"b01".U -> Cat(0.U(16.W), mem_wdata(31, 16)),
|
// "b01".U -> Cat(0.U(16.W), mem_wdata(31, 16)),
|
||||||
"b00".U -> Cat(0.U(24.W), mem_wdata(31, 24))
|
// "b00".U -> Cat(0.U(24.W), mem_wdata(31, 24))
|
||||||
)
|
// )
|
||||||
),
|
// ),
|
||||||
EXE_SWR -> MuxLookup(mem_addr2, 0.U)(
|
// EXE_SWR -> MuxLookup(mem_addr2, 0.U)(
|
||||||
Seq(
|
// Seq(
|
||||||
"b11".U -> Cat(mem_wdata(7, 0), 0.U(24.W)),
|
// "b11".U -> Cat(mem_wdata(7, 0), 0.U(24.W)),
|
||||||
"b10".U -> Cat(mem_wdata(15, 0), 0.U(16.W)),
|
// "b10".U -> Cat(mem_wdata(15, 0), 0.U(16.W)),
|
||||||
"b01".U -> Cat(mem_wdata(23, 0), 0.U(8.W)),
|
// "b01".U -> Cat(mem_wdata(23, 0), 0.U(8.W)),
|
||||||
"b00".U -> mem_wdata
|
// "b00".U -> mem_wdata
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
io.dataMemory.out.wen := MuxLookup(op, 0.U)(
|
// io.dataMemory.out.wen := MuxLookup(op, 0.U)(
|
||||||
Seq(
|
// Seq(
|
||||||
EXE_SB -> MuxLookup(mem_addr2, 0.U)(
|
// EXE_SB -> MuxLookup(mem_addr2, 0.U)(
|
||||||
Seq(
|
// Seq(
|
||||||
"b11".U -> "b1000".U,
|
// "b11".U -> "b1000".U,
|
||||||
"b10".U -> "b0100".U,
|
// "b10".U -> "b0100".U,
|
||||||
"b01".U -> "b0010".U,
|
// "b01".U -> "b0010".U,
|
||||||
"b00".U -> "b0001".U
|
// "b00".U -> "b0001".U
|
||||||
)
|
// )
|
||||||
),
|
// ),
|
||||||
EXE_SH -> Mux(mem_addr2(1), "b1100".U, "b0011".U),
|
// EXE_SH -> Mux(mem_addr2(1), "b1100".U, "b0011".U),
|
||||||
EXE_SW -> "b1111".U,
|
// EXE_SW -> "b1111".U,
|
||||||
EXE_SC -> Fill(4, io.memoryUnit.in.llbit),
|
// EXE_SC -> Fill(4, io.memoryUnit.in.llbit),
|
||||||
EXE_SWL -> MuxLookup(mem_addr2, 0.U)(
|
// EXE_SWL -> MuxLookup(mem_addr2, 0.U)(
|
||||||
Seq(
|
// Seq(
|
||||||
"b11".U -> "b1111".U,
|
// "b11".U -> "b1111".U,
|
||||||
"b10".U -> "b0111".U,
|
// "b10".U -> "b0111".U,
|
||||||
"b01".U -> "b0011".U,
|
// "b01".U -> "b0011".U,
|
||||||
"b00".U -> "b0001".U
|
// "b00".U -> "b0001".U
|
||||||
)
|
// )
|
||||||
),
|
// ),
|
||||||
EXE_SWR -> MuxLookup(mem_addr2, 0.U)(
|
// EXE_SWR -> MuxLookup(mem_addr2, 0.U)(
|
||||||
Seq(
|
// Seq(
|
||||||
"b11".U -> "b1000".U,
|
// "b11".U -> "b1000".U,
|
||||||
"b10".U -> "b1100".U,
|
// "b10".U -> "b1100".U,
|
||||||
"b01".U -> "b1110".U,
|
// "b01".U -> "b1110".U,
|
||||||
"b00".U -> "b1111".U
|
// "b00".U -> "b1111".U
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
io.dataMemory.out.rlen := MuxLookup(op, 0.U)(
|
// io.dataMemory.out.rlen := MuxLookup(op, 0.U)(
|
||||||
Seq(
|
// Seq(
|
||||||
EXE_LW -> 2.U,
|
// EXE_LW -> 2.U,
|
||||||
EXE_LL -> 2.U,
|
// EXE_LL -> 2.U,
|
||||||
EXE_LH -> 1.U,
|
// EXE_LH -> 1.U,
|
||||||
EXE_LHU -> 1.U,
|
// EXE_LHU -> 1.U,
|
||||||
EXE_LB -> 0.U,
|
// EXE_LB -> 0.U,
|
||||||
EXE_LBU -> 0.U,
|
// EXE_LBU -> 0.U,
|
||||||
EXE_LWL -> 2.U,
|
// EXE_LWL -> 2.U,
|
||||||
EXE_LWR -> 2.U,
|
// EXE_LWR -> 2.U,
|
||||||
EXE_SW -> 2.U,
|
// EXE_SW -> 2.U,
|
||||||
EXE_SWL -> 2.U,
|
// EXE_SWL -> 2.U,
|
||||||
EXE_SWR -> 2.U,
|
// EXE_SWR -> 2.U,
|
||||||
EXE_SC -> 2.U,
|
// EXE_SC -> 2.U,
|
||||||
EXE_SH -> 1.U,
|
// EXE_SH -> 1.U,
|
||||||
EXE_SB -> 0.U
|
// EXE_SB -> 0.U
|
||||||
)
|
// )
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
|
|
|
@ -1,103 +1,103 @@
|
||||||
package cpu.pipeline.memory
|
// package cpu.pipeline.memory
|
||||||
|
|
||||||
import chisel3._
|
// import chisel3._
|
||||||
import chisel3.util._
|
// import chisel3.util._
|
||||||
import cpu.defines._
|
// import cpu.defines._
|
||||||
import cpu.defines.Const._
|
// import cpu.defines.Const._
|
||||||
import cpu.CpuConfig
|
// import cpu.CpuConfig
|
||||||
import cpu.pipeline.decoder.RegWrite
|
// import cpu.pipeline.decoder.RegWrite
|
||||||
import cpu.pipeline.execute.CsrMemoryUnit
|
// import cpu.pipeline.execute.CsrMemoryUnit
|
||||||
import cpu.pipeline.writeback.MemoryUnitWriteBackUnit
|
// import cpu.pipeline.writeback.MemoryUnitWriteBackUnit
|
||||||
|
|
||||||
class MemoryUnit(implicit val config: CpuConfig) extends Module {
|
// class MemoryUnit(implicit val config: CpuConfig) extends Module {
|
||||||
val io = IO(new Bundle {
|
// val io = IO(new Bundle {
|
||||||
val ctrl = new MemoryCtrl()
|
// val ctrl = new MemoryCtrl()
|
||||||
val memoryStage = Input(new ExecuteUnitMemoryUnit())
|
// val memoryStage = Input(new ExecuteUnitMemoryUnit())
|
||||||
val fetchUnit = Output(new Bundle {
|
// val fetchUnit = Output(new Bundle {
|
||||||
val flush = Bool()
|
// val flush = Bool()
|
||||||
val flush_pc = UInt(PC_WID.W)
|
// val flush_pc = UInt(PC_WID.W)
|
||||||
})
|
// })
|
||||||
val decoderUnit = Output(Vec(config.fuNum, new RegWrite()))
|
// val decoderUnit = Output(Vec(config.fuNum, new RegWrite()))
|
||||||
val csr = Flipped(new CsrMemoryUnit())
|
// val csr = Flipped(new CsrMemoryUnit())
|
||||||
val writeBackStage = Output(new MemoryUnitWriteBackUnit())
|
// val writeBackStage = Output(new MemoryUnitWriteBackUnit())
|
||||||
val dataMemory = new Bundle {
|
// val dataMemory = new Bundle {
|
||||||
val in = Input(new Bundle {
|
// val in = Input(new Bundle {
|
||||||
val rdata = UInt(DATA_WID.W)
|
// val rdata = UInt(DATA_WID.W)
|
||||||
})
|
// })
|
||||||
val out = Output(new Bundle {
|
// val out = Output(new Bundle {
|
||||||
val en = Bool()
|
// val en = Bool()
|
||||||
val rlen = UInt(2.W)
|
// val rlen = UInt(2.W)
|
||||||
val wen = UInt(4.W)
|
// val wen = UInt(4.W)
|
||||||
val addr = UInt(DATA_ADDR_WID.W)
|
// val addr = UInt(DATA_ADDR_WID.W)
|
||||||
val wdata = UInt(DATA_WID.W)
|
// val wdata = UInt(DATA_WID.W)
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
|
|
||||||
val dataMemoryAccess = Module(new DataMemoryAccess()).io
|
// val dataMemoryAccess = Module(new DataMemoryAccess()).io
|
||||||
dataMemoryAccess.memoryUnit.in.mem_en := io.memoryStage.inst0.mem.en
|
// dataMemoryAccess.memoryUnit.in.mem_en := io.memoryStage.inst0.mem.en
|
||||||
dataMemoryAccess.memoryUnit.in.inst_info := io.memoryStage.inst0.mem.inst_info
|
// dataMemoryAccess.memoryUnit.in.inst_info := io.memoryStage.inst0.mem.inst_info
|
||||||
dataMemoryAccess.memoryUnit.in.mem_wdata := io.memoryStage.inst0.mem.wdata
|
// dataMemoryAccess.memoryUnit.in.mem_wdata := io.memoryStage.inst0.mem.wdata
|
||||||
dataMemoryAccess.memoryUnit.in.mem_addr := io.memoryStage.inst0.mem.addr
|
// dataMemoryAccess.memoryUnit.in.mem_addr := io.memoryStage.inst0.mem.addr
|
||||||
dataMemoryAccess.memoryUnit.in.mem_sel := io.memoryStage.inst0.mem.sel
|
// dataMemoryAccess.memoryUnit.in.mem_sel := io.memoryStage.inst0.mem.sel
|
||||||
dataMemoryAccess.memoryUnit.in.ex(0) := io.memoryStage.inst0.ex
|
// dataMemoryAccess.memoryUnit.in.ex(0) := io.memoryStage.inst0.ex
|
||||||
dataMemoryAccess.memoryUnit.in.ex(1) := io.memoryStage.inst1.ex
|
// dataMemoryAccess.memoryUnit.in.ex(1) := io.memoryStage.inst1.ex
|
||||||
dataMemoryAccess.dataMemory.in.rdata := io.dataMemory.in.rdata
|
// dataMemoryAccess.dataMemory.in.rdata := io.dataMemory.in.rdata
|
||||||
dataMemoryAccess.memoryUnit.in.llbit := io.memoryStage.inst0.mem.llbit
|
// dataMemoryAccess.memoryUnit.in.llbit := io.memoryStage.inst0.mem.llbit
|
||||||
io.dataMemory.out := dataMemoryAccess.dataMemory.out
|
// io.dataMemory.out := dataMemoryAccess.dataMemory.out
|
||||||
|
|
||||||
io.decoderUnit(0).wen := io.writeBackStage.inst0.inst_info.reg_wen
|
// io.decoderUnit(0).wen := io.writeBackStage.inst0.inst_info.reg_wen
|
||||||
io.decoderUnit(0).waddr := io.writeBackStage.inst0.inst_info.reg_waddr
|
// io.decoderUnit(0).waddr := io.writeBackStage.inst0.inst_info.reg_waddr
|
||||||
io.decoderUnit(0).wdata := io.writeBackStage.inst0.rd_info.wdata
|
// io.decoderUnit(0).wdata := io.writeBackStage.inst0.rd_info.wdata
|
||||||
io.decoderUnit(1).wen := io.writeBackStage.inst1.inst_info.reg_wen
|
// io.decoderUnit(1).wen := io.writeBackStage.inst1.inst_info.reg_wen
|
||||||
io.decoderUnit(1).waddr := io.writeBackStage.inst1.inst_info.reg_waddr
|
// io.decoderUnit(1).waddr := io.writeBackStage.inst1.inst_info.reg_waddr
|
||||||
io.decoderUnit(1).wdata := io.writeBackStage.inst1.rd_info.wdata
|
// io.decoderUnit(1).wdata := io.writeBackStage.inst1.rd_info.wdata
|
||||||
|
|
||||||
io.writeBackStage.inst0.pc := io.memoryStage.inst0.pc
|
// io.writeBackStage.inst0.pc := io.memoryStage.inst0.pc
|
||||||
io.writeBackStage.inst0.inst_info := io.memoryStage.inst0.inst_info
|
// io.writeBackStage.inst0.inst_info := io.memoryStage.inst0.inst_info
|
||||||
io.writeBackStage.inst0.rd_info.wdata := Mux(
|
// io.writeBackStage.inst0.rd_info.wdata := Mux(
|
||||||
io.writeBackStage.inst0.inst_info.mem_wreg,
|
// io.writeBackStage.inst0.inst_info.mem_wreg,
|
||||||
dataMemoryAccess.memoryUnit.out.rdata,
|
// dataMemoryAccess.memoryUnit.out.rdata,
|
||||||
io.memoryStage.inst0.rd_info.wdata,
|
// io.memoryStage.inst0.rd_info.wdata,
|
||||||
)
|
// )
|
||||||
io.writeBackStage.inst0.ex := io.memoryStage.inst0.ex
|
// io.writeBackStage.inst0.ex := io.memoryStage.inst0.ex
|
||||||
io.writeBackStage.inst0.ex.excode := MuxCase(
|
// io.writeBackStage.inst0.ex.excode := MuxCase(
|
||||||
io.memoryStage.inst0.ex.excode,
|
// io.memoryStage.inst0.ex.excode,
|
||||||
Seq(
|
// Seq(
|
||||||
(io.memoryStage.inst0.ex.excode =/= EX_NO) -> io.memoryStage.inst0.ex.excode,
|
// (io.memoryStage.inst0.ex.excode =/= EX_NO) -> io.memoryStage.inst0.ex.excode,
|
||||||
),
|
// ),
|
||||||
)
|
// )
|
||||||
io.writeBackStage.inst0.ex.flush_req := io.memoryStage.inst0.ex.flush_req || io.writeBackStage.inst0.ex.excode =/= EX_NO
|
// io.writeBackStage.inst0.ex.flush_req := io.memoryStage.inst0.ex.flush_req || io.writeBackStage.inst0.ex.excode =/= EX_NO
|
||||||
io.writeBackStage.inst0.csr := io.memoryStage.inst0.csr
|
// io.writeBackStage.inst0.csr := io.memoryStage.inst0.csr
|
||||||
|
|
||||||
io.writeBackStage.inst1.pc := io.memoryStage.inst1.pc
|
// io.writeBackStage.inst1.pc := io.memoryStage.inst1.pc
|
||||||
io.writeBackStage.inst1.inst_info := io.memoryStage.inst1.inst_info
|
// io.writeBackStage.inst1.inst_info := io.memoryStage.inst1.inst_info
|
||||||
io.writeBackStage.inst1.rd_info.wdata := Mux(
|
// io.writeBackStage.inst1.rd_info.wdata := Mux(
|
||||||
io.writeBackStage.inst1.inst_info.mem_wreg,
|
// io.writeBackStage.inst1.inst_info.mem_wreg,
|
||||||
dataMemoryAccess.memoryUnit.out.rdata,
|
// dataMemoryAccess.memoryUnit.out.rdata,
|
||||||
io.memoryStage.inst1.rd_info.wdata,
|
// io.memoryStage.inst1.rd_info.wdata,
|
||||||
)
|
// )
|
||||||
io.writeBackStage.inst1.ex := io.memoryStage.inst1.ex
|
// io.writeBackStage.inst1.ex := io.memoryStage.inst1.ex
|
||||||
io.writeBackStage.inst1.ex.excode := MuxCase(
|
// io.writeBackStage.inst1.ex.excode := MuxCase(
|
||||||
io.memoryStage.inst1.ex.excode,
|
// io.memoryStage.inst1.ex.excode,
|
||||||
Seq(
|
// Seq(
|
||||||
(io.memoryStage.inst1.ex.excode =/= EX_NO) -> io.memoryStage.inst1.ex.excode,
|
// (io.memoryStage.inst1.ex.excode =/= EX_NO) -> io.memoryStage.inst1.ex.excode,
|
||||||
),
|
// ),
|
||||||
)
|
// )
|
||||||
io.writeBackStage.inst1.ex.flush_req := io.memoryStage.inst1.ex.flush_req || io.writeBackStage.inst1.ex.excode =/= EX_NO
|
// io.writeBackStage.inst1.ex.flush_req := io.memoryStage.inst1.ex.flush_req || io.writeBackStage.inst1.ex.excode =/= EX_NO
|
||||||
|
|
||||||
io.csr.in.inst(0).pc := io.writeBackStage.inst0.pc
|
// io.csr.in.inst(0).pc := io.writeBackStage.inst0.pc
|
||||||
io.csr.in.inst(0).ex := io.writeBackStage.inst0.ex
|
// io.csr.in.inst(0).ex := io.writeBackStage.inst0.ex
|
||||||
io.csr.in.inst(1).pc := io.writeBackStage.inst1.pc
|
// io.csr.in.inst(1).pc := io.writeBackStage.inst1.pc
|
||||||
io.csr.in.inst(1).ex := io.writeBackStage.inst1.ex
|
// io.csr.in.inst(1).ex := io.writeBackStage.inst1.ex
|
||||||
|
|
||||||
io.fetchUnit.flush := Mux(
|
// io.fetchUnit.flush := Mux(
|
||||||
io.csr.out.flush,
|
// io.csr.out.flush,
|
||||||
io.csr.out.flush,
|
// io.csr.out.flush,
|
||||||
io.writeBackStage.inst0.inst_info.op === EXE_MTC0 && io.ctrl.allow_to_go,
|
// io.writeBackStage.inst0.inst_info.op === EXE_MTC0 && io.ctrl.allow_to_go,
|
||||||
)
|
// )
|
||||||
io.fetchUnit.flush_pc := Mux(io.csr.out.flush, io.csr.out.flush_pc, io.writeBackStage.inst0.pc + 4.U)
|
// io.fetchUnit.flush_pc := Mux(io.csr.out.flush, io.csr.out.flush_pc, io.writeBackStage.inst0.pc + 4.U)
|
||||||
|
|
||||||
io.ctrl.flush_req := io.fetchUnit.flush
|
// io.ctrl.flush_req := io.fetchUnit.flush
|
||||||
io.ctrl.eret := io.writeBackStage.inst0.ex.eret
|
// io.ctrl.eret := io.writeBackStage.inst0.ex.eret
|
||||||
}
|
// }
|
||||||
|
|
|
@ -13,7 +13,6 @@ class WriteBackUnit(implicit val config: CpuConfig) extends Module {
|
||||||
val writeBackStage = Input(new MemoryUnitWriteBackUnit())
|
val writeBackStage = Input(new MemoryUnitWriteBackUnit())
|
||||||
val regfile = Output(Vec(config.commitNum, new RegWrite()))
|
val regfile = Output(Vec(config.commitNum, new RegWrite()))
|
||||||
val debug = new DEBUG()
|
val debug = new DEBUG()
|
||||||
val statistic = if (!config.build) Some(new SocStatistic()) else None
|
|
||||||
})
|
})
|
||||||
|
|
||||||
io.regfile(0)
|
io.regfile(0)
|
||||||
|
@ -64,15 +63,4 @@ class WriteBackUnit(implicit val config: CpuConfig) extends Module {
|
||||||
io.regfile(1).wdata,
|
io.regfile(1).wdata,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ===----------------------------------------------------------------===
|
|
||||||
// statistic
|
|
||||||
// ===----------------------------------------------------------------===
|
|
||||||
if (!config.build) {
|
|
||||||
io.statistic.get.csr_cause := io.writeBackStage.inst0.csr.csr_cause
|
|
||||||
io.statistic.get.csr_count := io.writeBackStage.inst0.csr.csr_count
|
|
||||||
io.statistic.get.csr_random := io.writeBackStage.inst0.csr.csr_random
|
|
||||||
io.statistic.get.int := io.writeBackStage.inst0.ex.excode === EX_INT
|
|
||||||
io.statistic.get.commit := io.ctrl.allow_to_go
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import cpu._
|
import cpu._
|
||||||
import circt.stage._
|
import circt.stage._
|
||||||
import cache.Cache
|
import cache.Cache
|
||||||
|
import cpu.pipeline.decoder.Decoder
|
||||||
|
|
||||||
object TestMain extends App {
|
object TestMain extends App {
|
||||||
implicit val config = new CpuConfig()
|
implicit val config = new CpuConfig()
|
||||||
def top = new Cache()
|
def top = new Decoder()
|
||||||
val useMFC = false // use MLIR-based firrtl compiler
|
val useMFC = false // use MLIR-based firrtl compiler
|
||||||
val generator = Seq(chisel3.stage.ChiselGeneratorAnnotation(() => top))
|
val generator = Seq(chisel3.stage.ChiselGeneratorAnnotation(() => top))
|
||||||
if (useMFC) {
|
if (useMFC) {
|
||||||
|
|
Loading…
Reference in New Issue