riscv-lab/chisel/playground/src/Core.scala

141 lines
5.4 KiB
Scala

package cpu
import chisel3._
import chisel3.util._
import chisel3.internal.DontCareBinding
import defines._
import defines.Const._
import pipeline.fetch._
import pipeline.decode._
import pipeline.execute._
import pipeline.memory._
import pipeline.writeback._
import ctrl._
import icache.mmu.Tlb
class Core(implicit val cpuConfig: 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 decodeUnit = Module(new DecodeUnit()).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
val tlb = Module(new Tlb()).io
tlb.icache <> io.inst.tlb
tlb.dcache <> io.data.tlb
tlb.csr <> csr.tlb
tlb.sfence_vma <> memoryUnit.ctrl.sfence_vma
ctrl.decodeUnit <> decodeUnit.ctrl
ctrl.executeUnit <> executeUnit.ctrl
ctrl.memoryUnit <> memoryUnit.ctrl
ctrl.writeBackUnit <> writeBackUnit.ctrl
ctrl.cacheCtrl.iCache_stall := io.inst.icache_stall
fetchUnit.memory <> memoryUnit.fetchUnit
fetchUnit.execute <> executeUnit.fetchUnit
fetchUnit.decode <> decodeUnit.fetchUnit
fetchUnit.instFifo.full := instFifo.full
fetchUnit.iCache.inst_valid := io.inst.inst_valid
io.inst.addr(0) := fetchUnit.iCache.pc
io.inst.addr(1) := fetchUnit.iCache.pc_next
for (i <- 2 until cpuConfig.instFetchNum) {
io.inst.addr(i) := fetchUnit.iCache.pc_next + ((i - 1) * 4).U
}
bpu.decode <> decodeUnit.bpu
bpu.execute <> executeUnit.bpu
instFifo.do_flush := ctrl.decodeUnit.do_flush
instFifo.decoderUint <> decodeUnit.instFifo
for (i <- 0 until cpuConfig.instFetchNum) {
instFifo.write(i).pht_index := bpu.instBuffer.pht_index(i)
bpu.instBuffer.pc(i) := instFifo.write(i).pc
instFifo.wen(i) := io.inst.inst_valid(i)
instFifo.write(i).pc := io.inst.addr(0) + (i * 4).U
instFifo.write(i).inst := io.inst.inst(i)
instFifo.write(i).access_fault := io.inst.access_fault
instFifo.write(i).page_fault := io.inst.page_fault
instFifo.write(i).addr_misaligned := io.inst.addr_misaligned
}
decodeUnit.regfile <> regfile.read
for (i <- 0 until (cpuConfig.commitNum)) {
decodeUnit.forward(i).exe := executeUnit.decodeUnit.forward(i).exe
decodeUnit.forward(i).is_load := executeUnit.decodeUnit.forward(i).is_load // exe级是load指令
decodeUnit.forward(i).mem := memoryUnit.decodeUnit(i)
}
decodeUnit.csr <> csr.decodeUnit
decodeUnit.executeStage <> executeStage.decodeUnit
for (i <- 0 until (cpuConfig.commitNum)) {
// 流水线清空或者暂停时,需要清空缓存级的数据,也就是插入气泡
executeStage.ctrl.clear(i) :=
ctrl.memoryUnit.do_flush || ctrl.executeUnit.do_flush ||
!decodeUnit.instFifo.allow_to_go(i) && ctrl.executeUnit.allow_to_go
executeStage.ctrl.allow_to_go(i) := decodeUnit.instFifo.allow_to_go(i)
}
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.ext_int := io.ext_int
memoryUnit.dataMemory.in.rdata := io.data.rdata
memoryUnit.dataMemory.in.access_fault := io.data.access_fault
memoryUnit.dataMemory.in.page_fault := io.data.page_fault
memoryUnit.dataMemory.in.ready := io.data.dcache_ready
io.data.en := memoryUnit.dataMemory.out.en
io.data.rlen := memoryUnit.dataMemory.out.rlen
io.data.wen := memoryUnit.dataMemory.out.wen
io.data.wdata := memoryUnit.dataMemory.out.wdata
io.data.addr := memoryUnit.dataMemory.out.addr
io.data.wstrb := memoryUnit.dataMemory.out.wstrb
io.data.exe_addr := executeUnit.dataMemory.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
// 解决fence_i
io.inst.fence_i := memoryUnit.ctrl.fence_i
io.data.fence_i := memoryUnit.ctrl.fence_i
io.inst.dcache_stall := !io.data.dcache_ready
io.inst.req := !instFifo.full && !reset.asBool
io.inst.complete_single_request := ctrl.fetchUnit.allow_to_go
io.data.complete_single_request := ctrl.memoryUnit.allow_to_go || ctrl.memoryUnit.complete_single_request
}