144 lines
5.9 KiB
Scala
144 lines
5.9 KiB
Scala
package cpu
|
|
|
|
import chisel3._
|
|
import chisel3.util._
|
|
import chisel3.internal.DontCareBinding
|
|
|
|
import defines._
|
|
import defines.Const._
|
|
import pipeline.fetch._
|
|
import pipeline.decoder._
|
|
import pipeline.execute._
|
|
import pipeline.memory._
|
|
import pipeline.writeback._
|
|
import ctrl._
|
|
import mmu._
|
|
import chisel3.util.experimental.decode.decoder
|
|
import cpu.pipeline.fetch.InstFifo
|
|
|
|
class Core(implicit val config: CpuConfig) extends Module {
|
|
val io = IO(new Bundle {
|
|
val ext_int = Input(new ExtInterrupt())
|
|
val inst = new Cache_ICache()
|
|
val data = new Cache_DCache()
|
|
val debug = new DEBUG()
|
|
})
|
|
|
|
val ctrl = Module(new Ctrl()).io
|
|
val fetchUnit = Module(new FetchUnit()).io
|
|
val bpu = Module(new BranchPredictorUnit()).io
|
|
val instFifo = Module(new InstFifo()).io
|
|
val decoderUnit = Module(new DecoderUnit()).io
|
|
val regfile = Module(new ARegFile()).io
|
|
val executeStage = Module(new ExecuteStage()).io
|
|
val executeUnit = Module(new ExecuteUnit()).io
|
|
val csr = Module(new Csr()).io
|
|
val memoryStage = Module(new MemoryStage()).io
|
|
val memoryUnit = Module(new MemoryUnit()).io
|
|
val writeBackStage = Module(new WriteBackStage()).io
|
|
val writeBackUnit = Module(new WriteBackUnit()).io
|
|
|
|
ctrl.instFifo.has2insts := !(instFifo.empty || instFifo.almost_empty)
|
|
ctrl.decoderUnit <> decoderUnit.ctrl
|
|
ctrl.executeUnit <> executeUnit.ctrl
|
|
ctrl.memoryUnit <> memoryUnit.ctrl
|
|
ctrl.writeBackUnit <> writeBackUnit.ctrl
|
|
ctrl.cacheCtrl.iCache_stall := io.inst.stall
|
|
ctrl.cacheCtrl.dCache_stall := io.data.stall
|
|
|
|
fetchUnit.memory <> memoryUnit.fetchUnit
|
|
fetchUnit.execute <> executeUnit.fetchUnit
|
|
fetchUnit.decoder <> decoderUnit.fetchUnit
|
|
fetchUnit.instFifo.full := instFifo.full
|
|
fetchUnit.iCache.inst_valid := io.inst.valid
|
|
io.inst.addr(0) := fetchUnit.iCache.pc
|
|
io.inst.addr(1) := fetchUnit.iCache.pc_next
|
|
for (i <- 2 until config.instFetchNum) {
|
|
io.inst.addr(i) := fetchUnit.iCache.pc_next + ((i - 1) * 4).U
|
|
}
|
|
|
|
bpu.decoder.ena := ctrl.decoderUnit.allow_to_go
|
|
bpu.decoder.op := decoderUnit.bpu.decoded_inst0.op
|
|
bpu.decoder.inst := decoderUnit.bpu.decoded_inst0.inst
|
|
bpu.decoder.rs1 := decoderUnit.bpu.decoded_inst0.reg1_raddr
|
|
bpu.decoder.rs2 := decoderUnit.bpu.decoded_inst0.reg2_raddr
|
|
bpu.decoder.pc := decoderUnit.bpu.pc
|
|
bpu.decoder.pc_plus4 := decoderUnit.bpu.pc + 4.U
|
|
bpu.decoder.pht_index := decoderUnit.bpu.pht_index
|
|
decoderUnit.bpu.update_pht_index := bpu.decoder.update_pht_index
|
|
bpu.execute <> executeUnit.bpu
|
|
decoderUnit.bpu.branch_inst := bpu.decoder.branch_inst
|
|
decoderUnit.bpu.pred_branch := bpu.decoder.pred_branch
|
|
decoderUnit.bpu.branch_target := bpu.decoder.branch_target
|
|
|
|
instFifo.do_flush := ctrl.decoderUnit.do_flush
|
|
instFifo.icache_stall := io.inst.stall
|
|
instFifo.ren <> decoderUnit.instFifo.allow_to_go
|
|
decoderUnit.instFifo.inst <> instFifo.read
|
|
|
|
for (i <- 0 until config.instFetchNum) {
|
|
instFifo.write(i).pht_index := bpu.instBuffer.pht_index(i)
|
|
bpu.instBuffer.pc(i) := instFifo.write(i).pc
|
|
instFifo.wen(i) := io.inst.valid(i)
|
|
instFifo.write(i).pc := io.inst.addr(0) + (i * 4).U
|
|
instFifo.write(i).inst := io.inst.rdata(i)
|
|
}
|
|
|
|
decoderUnit.instFifo.info.empty := instFifo.empty
|
|
decoderUnit.instFifo.info.almost_empty := instFifo.almost_empty
|
|
decoderUnit.regfile <> regfile.read
|
|
for (i <- 0 until (config.fuNum)) {
|
|
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 := memoryUnit.decoderUnit(i)
|
|
}
|
|
decoderUnit.csr <> csr.decoderUnit
|
|
decoderUnit.executeStage <> executeStage.decoderUnit
|
|
|
|
executeStage.ctrl.clear(0) := ctrl.memoryUnit.flush_req ||
|
|
ctrl.executeUnit.do_flush && ctrl.executeUnit.allow_to_go ||
|
|
!ctrl.decoderUnit.allow_to_go && ctrl.executeUnit.allow_to_go
|
|
executeStage.ctrl.clear(1) := ctrl.memoryUnit.flush_req ||
|
|
(ctrl.executeUnit.do_flush && 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
|
|
|
|
executeUnit.executeStage <> executeStage.executeUnit
|
|
executeUnit.csr <> csr.executeUnit
|
|
executeUnit.memoryStage <> memoryStage.executeUnit
|
|
|
|
memoryStage.ctrl.allow_to_go := ctrl.memoryUnit.allow_to_go
|
|
memoryStage.ctrl.clear := ctrl.memoryUnit.do_flush
|
|
|
|
memoryUnit.memoryStage <> memoryStage.memoryUnit
|
|
memoryUnit.csr <> csr.memoryUnit
|
|
memoryUnit.writeBackStage <> writeBackStage.memoryUnit
|
|
|
|
csr.ctrl.exe_stall := !ctrl.executeUnit.allow_to_go
|
|
csr.ctrl.mem_stall := !ctrl.memoryUnit.allow_to_go
|
|
csr.ext_int := io.ext_int
|
|
|
|
memoryUnit.dataMemory.in.rdata := io.data.rdata
|
|
io.data.en := memoryUnit.dataMemory.out.en
|
|
io.data.size := memoryUnit.dataMemory.out.rlen
|
|
io.data.write := memoryUnit.dataMemory.out.wen
|
|
io.data.wdata := memoryUnit.dataMemory.out.wdata
|
|
io.data.addr := memoryUnit.dataMemory.out.addr
|
|
|
|
writeBackStage.memoryUnit <> memoryUnit.writeBackStage
|
|
writeBackStage.ctrl.allow_to_go := ctrl.writeBackUnit.allow_to_go
|
|
writeBackStage.ctrl.clear := ctrl.writeBackUnit.do_flush
|
|
|
|
writeBackUnit.writeBackStage <> writeBackStage.writeBackUnit
|
|
writeBackUnit.ctrl <> ctrl.writeBackUnit
|
|
regfile.write <> writeBackUnit.regfile
|
|
|
|
io.debug <> writeBackUnit.debug
|
|
|
|
// io.inst.fence_i := executeUnit.executeStage.inst0.inst_info.ifence
|
|
// io.data.fence_i := memoryUnit.memoryStage.inst0.inst_info.dfence
|
|
io.inst.en := !instFifo.full
|
|
io.inst.ready := !ctrl.fetchUnit.allow_to_go
|
|
io.data.ready := !ctrl.memoryUnit.allow_to_go
|
|
}
|