修改包名,修改各单元逻辑
This commit is contained in:
parent
703cd0b41c
commit
6508b72858
|
@ -2,139 +2,72 @@ 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 pipeline._
|
||||
import ctrl._
|
||||
import icache.mmu.Tlb
|
||||
|
||||
class Core(implicit val cpuConfig: CpuConfig) extends Module {
|
||||
class Core 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 interrupt = Input(new ExtInterrupt())
|
||||
val instSram = new InstSram()
|
||||
val dataSram = new DataSram()
|
||||
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 decodeStage = Module(new DecodeStage()).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.fetchUnit <> fetchUnit.ctrl
|
||||
ctrl.decodeUnit <> decodeUnit.ctrl
|
||||
ctrl.executeUnit <> executeUnit.ctrl
|
||||
ctrl.memoryUnit <> memoryUnit.ctrl
|
||||
ctrl.writeBackUnit <> writeBackUnit.ctrl
|
||||
ctrl.cacheCtrl.iCache_stall := io.inst.icache_stall
|
||||
decodeStage.ctrl := ctrl.fetchUnit.ctrlSignal
|
||||
executeStage.ctrl := ctrl.decodeUnit.ctrlSignal
|
||||
memoryStage.ctrl := ctrl.executeUnit.ctrlSignal
|
||||
writeBackStage.ctrl := ctrl.memoryUnit.ctrlSignal
|
||||
|
||||
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
|
||||
}
|
||||
// 取指单元
|
||||
fetchUnit.instSram <> io.instSram
|
||||
fetchUnit.decodeStage <> decodeStage.fetchUnit
|
||||
|
||||
// 译码级缓存
|
||||
decodeStage.decodeUnit <> decodeUnit.decodeStage
|
||||
// 译码单元
|
||||
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.forward.exe := executeUnit.decodeUnit.forward.exe
|
||||
decodeUnit.forward.is_load := executeUnit.decodeUnit.forward.is_load // exe级是load指令
|
||||
decodeUnit.forward.mem := memoryUnit.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
|
||||
// 执行级缓存
|
||||
executeStage.executeUnit <> executeUnit.executeStage
|
||||
executeUnit.dataSram <> io.dataSram
|
||||
// 执行单元
|
||||
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
|
||||
// 访存级缓存
|
||||
memoryStage.memoryUnit <> memoryUnit.memoryStage
|
||||
// 访存单元
|
||||
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
|
||||
writeBackUnit.regfile <> regfile.write
|
||||
writeBackUnit.debug <> io.debug
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -1,23 +1,20 @@
|
|||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cache._
|
||||
import cpu._
|
||||
import cpu.defines._
|
||||
|
||||
class PuaCpu extends Module {
|
||||
implicit val cpuConfig = new CpuConfig()
|
||||
val io = IO(new Bundle {
|
||||
val ext_int = Input(new ExtInterrupt())
|
||||
val axi = new AXI()
|
||||
val debug = new DEBUG()
|
||||
val ext_int = Input(new ExtInterrupt())
|
||||
val inst_sram = new InstSram()
|
||||
val data_sram = new DataSram()
|
||||
val debug = new DEBUG()
|
||||
})
|
||||
val core = Module(new Core())
|
||||
val cache = Module(new Cache())
|
||||
|
||||
core.io.inst <> cache.io.inst
|
||||
core.io.data <> cache.io.data
|
||||
val core = Module(new Core())
|
||||
|
||||
io.ext_int <> core.io.ext_int
|
||||
io.ext_int <> core.io.interrupt
|
||||
io.inst_sram <> core.io.instSram
|
||||
io.data_sram <> core.io.dataSram
|
||||
io.debug <> core.io.debug
|
||||
io.axi <> cache.io.axi
|
||||
}
|
||||
|
|
|
@ -6,9 +6,8 @@ import cpu.defines._
|
|||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
|
||||
class Ctrl(implicit val cpuConfig: CpuConfig) extends Module {
|
||||
class Ctrl extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val cacheCtrl = Flipped(new CacheCtrl())
|
||||
val fetchUnit = Flipped(new FetchUnitCtrl())
|
||||
val decodeUnit = Flipped(new DecodeUnitCtrl())
|
||||
val executeUnit = Flipped(new ExecuteCtrl())
|
||||
|
@ -16,27 +15,22 @@ class Ctrl(implicit val cpuConfig: CpuConfig) extends Module {
|
|||
val writeBackUnit = Flipped(new WriteBackCtrl())
|
||||
})
|
||||
|
||||
val inst0_lw_stall = (io.executeUnit.inst(0).is_load) && io.executeUnit.inst(0).reg_waddr.orR &&
|
||||
(io.decodeUnit.inst0.src1.ren && io.decodeUnit.inst0.src1.raddr === io.executeUnit.inst(0).reg_waddr ||
|
||||
io.decodeUnit.inst0.src2.ren && io.decodeUnit.inst0.src2.raddr === io.executeUnit.inst(0).reg_waddr)
|
||||
val inst1_lw_stall = (io.executeUnit.inst(1).is_load) && io.executeUnit.inst(1).reg_waddr.orR &&
|
||||
(io.decodeUnit.inst0.src1.ren && io.decodeUnit.inst0.src1.raddr === io.executeUnit.inst(1).reg_waddr ||
|
||||
io.decodeUnit.inst0.src2.ren && io.decodeUnit.inst0.src2.raddr === io.executeUnit.inst(1).reg_waddr)
|
||||
val lw_stall = inst0_lw_stall || inst1_lw_stall
|
||||
val longest_stall =
|
||||
io.executeUnit.fu.stall || io.cacheCtrl.iCache_stall || io.memoryUnit.mem_stall
|
||||
val lw_stall = (io.executeUnit.data.is_load) && io.executeUnit.data.reg_waddr.orR &&
|
||||
(io.decodeUnit.src_info.src1.ren && io.decodeUnit.src_info.src1.raddr === io.executeUnit.data.reg_waddr ||
|
||||
io.decodeUnit.src_info.src2.ren && io.decodeUnit.src_info.src2.raddr === io.executeUnit.data.reg_waddr)
|
||||
|
||||
io.fetchUnit.allow_to_go := !io.cacheCtrl.iCache_stall
|
||||
io.decodeUnit.allow_to_go := !(lw_stall || longest_stall)
|
||||
io.executeUnit.allow_to_go := !longest_stall
|
||||
io.memoryUnit.allow_to_go := !longest_stall
|
||||
io.writeBackUnit.allow_to_go := !longest_stall
|
||||
io.fetchUnit.ctrlSignal.allow_to_go := !lw_stall
|
||||
io.decodeUnit.ctrlSignal.allow_to_go := !lw_stall
|
||||
io.executeUnit.ctrlSignal.allow_to_go := true.B
|
||||
io.memoryUnit.ctrlSignal.allow_to_go := true.B
|
||||
io.writeBackUnit.ctrlSignal.allow_to_go := true.B
|
||||
|
||||
io.fetchUnit.do_flush := false.B
|
||||
io.decodeUnit.do_flush := io.memoryUnit.flush || io.executeUnit.flush || io.decodeUnit.branch
|
||||
io.executeUnit.do_flush := io.memoryUnit.flush || io.executeUnit.flush
|
||||
io.memoryUnit.do_flush := io.memoryUnit.flush
|
||||
io.writeBackUnit.do_flush := false.B
|
||||
io.fetchUnit.ctrlSignal.do_flush := io.executeUnit.flush
|
||||
io.decodeUnit.ctrlSignal.do_flush := io.executeUnit.flush ||
|
||||
!io.decodeUnit.ctrlSignal.allow_to_go && io.executeUnit.ctrlSignal.allow_to_go
|
||||
io.executeUnit.ctrlSignal.do_flush := io.executeUnit.flush
|
||||
io.memoryUnit.ctrlSignal.do_flush := false.B
|
||||
io.writeBackUnit.ctrlSignal.do_flush := false.B
|
||||
|
||||
io.executeUnit.fu.allow_to_go := io.memoryUnit.allow_to_go
|
||||
io.fetchUnit.target := io.executeUnit.target
|
||||
}
|
||||
|
|
|
@ -5,8 +5,6 @@ import chisel3.util._
|
|||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
import icache.mmu.{Tlb_DCache, Tlb_ICache}
|
||||
import cpu.pipeline.memory.Mou
|
||||
|
||||
class ExceptionInfo extends Bundle {
|
||||
val exception = Vec(EXC_WID, Bool())
|
||||
|
@ -54,174 +52,55 @@ class SrcReadSignal extends Bundle {
|
|||
val raddr = UInt(REG_ADDR_WID.W)
|
||||
}
|
||||
|
||||
class CacheCtrl extends Bundle {
|
||||
val iCache_stall = Output(Bool())
|
||||
class CtrlSignal extends Bundle {
|
||||
val allow_to_go = Bool()
|
||||
val do_flush = Bool()
|
||||
}
|
||||
|
||||
class FetchUnitCtrl extends Bundle {
|
||||
val allow_to_go = Input(Bool())
|
||||
val do_flush = Input(Bool())
|
||||
val target = Input(UInt(XLEN.W))
|
||||
val ctrlSignal = Input(new CtrlSignal())
|
||||
}
|
||||
|
||||
class DecodeUnitCtrl extends Bundle {
|
||||
val inst0 = Output(new Bundle {
|
||||
val src_info = Output(new Bundle {
|
||||
val src1 = new SrcReadSignal()
|
||||
val src2 = new SrcReadSignal()
|
||||
})
|
||||
val branch = Output(Bool())
|
||||
|
||||
val allow_to_go = Input(Bool())
|
||||
val do_flush = Input(Bool())
|
||||
val ctrlSignal = Input(new CtrlSignal())
|
||||
}
|
||||
|
||||
class ExecuteFuCtrl extends Bundle {
|
||||
val allow_to_go = Input(Bool())
|
||||
val stall = Output(Bool())
|
||||
}
|
||||
class ExecuteCtrl extends Bundle {
|
||||
val data = Output(new MemRead())
|
||||
val flush = Output(Bool())
|
||||
val target = Output(UInt(XLEN.W))
|
||||
|
||||
class ExecuteCtrl(implicit val cpuConfig: CpuConfig) extends Bundle {
|
||||
val inst = Output(Vec(cpuConfig.commitNum, new MemRead()))
|
||||
val flush = Output(Bool())
|
||||
|
||||
val allow_to_go = Input(Bool())
|
||||
val do_flush = Input(Bool())
|
||||
|
||||
val fu = new ExecuteFuCtrl()
|
||||
}
|
||||
|
||||
class MouTlb extends Bundle {
|
||||
val valid = Bool()
|
||||
val src_info = new SrcInfo()
|
||||
val ctrlSignal = Input(new CtrlSignal())
|
||||
}
|
||||
|
||||
class MemoryCtrl extends Bundle {
|
||||
val flush = Output(Bool())
|
||||
val mem_stall = Output(Bool())
|
||||
|
||||
val allow_to_go = Input(Bool())
|
||||
val do_flush = Input(Bool())
|
||||
|
||||
// to cache
|
||||
val fence_i = Output(Bool())
|
||||
val complete_single_request = Output(Bool()) // to dcache
|
||||
// to tlb
|
||||
val sfence_vma = Output(new MouTlb())
|
||||
val ctrlSignal = Input(new CtrlSignal())
|
||||
}
|
||||
|
||||
class WriteBackCtrl extends Bundle {
|
||||
val allow_to_go = Input(Bool())
|
||||
val do_flush = Input(Bool())
|
||||
val ctrlSignal = Input(new CtrlSignal())
|
||||
}
|
||||
|
||||
// cpu to icache
|
||||
class Cache_ICache(implicit val cpuConfig: CpuConfig) extends Bundle {
|
||||
// read inst request from cpu
|
||||
val req = Output(Bool())
|
||||
val complete_single_request = Output(Bool())
|
||||
val addr = Output(Vec(cpuConfig.instFetchNum, UInt(XLEN.W))) // virtual address and next virtual address
|
||||
val fence_i = Output(Bool())
|
||||
val dcache_stall = Output(Bool())
|
||||
|
||||
// read inst result
|
||||
val inst = Input(Vec(cpuConfig.instFetchNum, UInt(XLEN.W)))
|
||||
val inst_valid = Input(Vec(cpuConfig.instFetchNum, Bool()))
|
||||
val access_fault = Input(Bool())
|
||||
val page_fault = Input(Bool())
|
||||
val addr_misaligned = Input(Bool())
|
||||
val icache_stall = Input(Bool()) // icache_stall
|
||||
|
||||
// tlb
|
||||
val tlb = new Tlb_ICache()
|
||||
class InstSram extends Bundle {
|
||||
val en = Output(Bool())
|
||||
val addr = Output(UInt(AXI_ADDR_WID.W))
|
||||
val wdata = Output(UInt(INST_WID.W))
|
||||
val wen = Output(UInt((INST_WID / 8).W))
|
||||
val rdata = Input(UInt(INST_WID.W))
|
||||
}
|
||||
|
||||
// cpu to dcache
|
||||
class Cache_DCache extends Bundle {
|
||||
val exe_addr = Output(UInt(XLEN.W))
|
||||
val addr = Output(UInt(XLEN.W))
|
||||
val rlen = Output(UInt(AXI_LEN_WID.W))
|
||||
val en = Output(Bool())
|
||||
val wen = Output(Bool())
|
||||
val wdata = Output(UInt(XLEN.W))
|
||||
val complete_single_request = Output(Bool())
|
||||
val fence_i = Output(Bool())
|
||||
val wstrb = Output(UInt(AXI_STRB_WID.W))
|
||||
|
||||
val rdata = Input(UInt(XLEN.W))
|
||||
val access_fault = Input(Bool())
|
||||
val page_fault = Input(Bool())
|
||||
val dcache_ready = Input(Bool())
|
||||
|
||||
val tlb = new Tlb_DCache()
|
||||
}
|
||||
|
||||
// axi
|
||||
// master -> slave
|
||||
|
||||
class AR extends Bundle {
|
||||
val id = UInt(AXI_ID_WID.W)
|
||||
val addr = UInt(AXI_ADDR_WID.W)
|
||||
val len = UInt(AXI_LEN_WID.W)
|
||||
val size = UInt(AXI_SIZE_WID.W)
|
||||
val burst = UInt(AXI_BURST_WID.W)
|
||||
val lock = UInt(AXI_LOCK_WID.W)
|
||||
val cache = UInt(AXI_CACHE_WID.W)
|
||||
val prot = UInt(AXI_PROT_WID.W)
|
||||
}
|
||||
|
||||
class R extends Bundle {
|
||||
val id = UInt(AXI_ID_WID.W)
|
||||
val data = UInt(AXI_DATA_WID.W)
|
||||
val resp = UInt(AXI_RESP_WID.W)
|
||||
val last = Bool()
|
||||
}
|
||||
|
||||
class AW extends Bundle {
|
||||
val id = UInt(AXI_ID_WID.W)
|
||||
val addr = UInt(AXI_ADDR_WID.W)
|
||||
val len = UInt(AXI_LEN_WID.W)
|
||||
val size = UInt(AXI_SIZE_WID.W)
|
||||
val burst = UInt(AXI_BURST_WID.W)
|
||||
val lock = UInt(AXI_LOCK_WID.W)
|
||||
val cache = UInt(AXI_CACHE_WID.W)
|
||||
val prot = UInt(AXI_PROT_WID.W)
|
||||
}
|
||||
|
||||
class W extends Bundle {
|
||||
val id = UInt(AXI_ID_WID.W)
|
||||
val data = UInt(AXI_DATA_WID.W)
|
||||
val strb = UInt(AXI_STRB_WID.W)
|
||||
val last = Bool()
|
||||
}
|
||||
|
||||
class B extends Bundle {
|
||||
val id = UInt(AXI_ID_WID.W)
|
||||
val resp = UInt(AXI_RESP_WID.W)
|
||||
}
|
||||
|
||||
class ICache_AXIInterface extends Bundle {
|
||||
val ar = Decoupled(new AR())
|
||||
val r = Flipped(Decoupled(new R()))
|
||||
}
|
||||
|
||||
class DCache_AXIInterface extends ICache_AXIInterface {
|
||||
val aw = Decoupled(new AW())
|
||||
val w = Decoupled(new W())
|
||||
val b = Flipped(Decoupled(new B()))
|
||||
}
|
||||
|
||||
class Cache_AXIInterface extends Bundle {
|
||||
// axi read channel
|
||||
val icache = new ICache_AXIInterface()
|
||||
val dcache = new DCache_AXIInterface()
|
||||
}
|
||||
|
||||
// AXI interface
|
||||
class AXI extends Bundle {
|
||||
val ar = Decoupled(new AR()) // read address channel
|
||||
val r = Flipped(Decoupled(new R())) // read data channel
|
||||
val aw = Decoupled(new AW()) // write address channel
|
||||
val w = Decoupled(new W()) // write data channel
|
||||
val b = Flipped(Decoupled(new B())) // write response channel
|
||||
class DataSram extends Bundle {
|
||||
val en = Output(Bool())
|
||||
val addr = Output(UInt(AXI_ADDR_WID.W))
|
||||
val wdata = Output(UInt(XLEN.W))
|
||||
val wen = Output(UInt(AXI_STRB_WID.W))
|
||||
val rdata = Input(UInt(XLEN.W))
|
||||
}
|
||||
|
||||
class DEBUG extends Bundle {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package cpu.pipeline.decode
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package cpu.pipeline.decode
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
@ -13,25 +13,23 @@ class IfIdData extends Bundle {
|
|||
val addr_misaligned = Bool()
|
||||
}
|
||||
|
||||
class FetchUnitDecodeUnit extends IfIdData {
|
||||
class FetchUnitDecodeUnit extends Bundle {
|
||||
val data = Output(new IfIdData())
|
||||
}
|
||||
|
||||
class DecodeStage extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val ctrl = Input(new Bundle {
|
||||
val allow_to_go = Bool()
|
||||
val clear = Bool()
|
||||
})
|
||||
val ctrl = Input(new CtrlSignal())
|
||||
val fetchUnit = Flipped(new FetchUnitDecodeUnit())
|
||||
val decodeUnit = new FetchUnitDecodeUnit()
|
||||
})
|
||||
|
||||
val data = RegInit(0.U.asTypeOf(new IfIdData()))
|
||||
|
||||
when(io.ctrl.clear) {
|
||||
when(io.ctrl.do_flush) {
|
||||
data := 0.U.asTypeOf(new IfIdData())
|
||||
}.elsewhen(io.ctrl.allow_to_go) {
|
||||
data := io.fetchUnit
|
||||
data := io.fetchUnit.data
|
||||
}
|
||||
|
||||
io.decodeUnit.data := data
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
package cpu.pipeline.decode
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import chisel3.util.experimental.BoringUtils
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.pipeline.execute.DecodeUnitExecuteUnit
|
||||
import cpu.pipeline.execute
|
||||
|
||||
class DataForwardToDecodeUnit extends Bundle {
|
||||
val exe = new RegWrite()
|
||||
|
@ -21,31 +18,31 @@ class DecodeUnit extends Module with HasExceptionNO with HasCSRConst {
|
|||
val regfile = new Src12Read()
|
||||
val forward = Input(new DataForwardToDecodeUnit())
|
||||
// 输出
|
||||
val fetchUnit = new Bundle {
|
||||
val branch = Output(Bool())
|
||||
val target = Output(UInt(XLEN.W))
|
||||
}
|
||||
val executeStage = Output(new DecodeUnitExecuteUnit())
|
||||
val ctrl = new DecodeUnitCtrl()
|
||||
})
|
||||
|
||||
val decoder = Module(new Decoder())
|
||||
val decoder = Module(new Decoder()).io
|
||||
decoder.in.inst := io.decodeStage.data.inst
|
||||
|
||||
val forwardCtrl = Module(new ForwardCtrl()).io
|
||||
|
||||
val pc = io.decodeStage.data.pc
|
||||
val info = Wire(new Info())
|
||||
|
||||
info := decoder.io.out.info
|
||||
info := decoder.out.info
|
||||
info.valid := io.decodeStage.data.valid
|
||||
|
||||
forwardCtrl.in.forward := io.forward
|
||||
forwardCtrl.in.regfile := io.regfile
|
||||
|
||||
io.regfile.src1.raddr := info.src1_raddr
|
||||
io.regfile.src2.raddr := info.src2_raddr
|
||||
|
||||
io.ctrl.src_info.src1.ren := info.src1_ren
|
||||
io.ctrl.src_info.src1.raddr := info.src1_raddr
|
||||
io.ctrl.src_info.src2.ren := info.src2_ren
|
||||
io.ctrl.src_info.src2.raddr := info.src2_raddr
|
||||
io.ctrl.branch := io.fetchUnit.branch
|
||||
|
||||
io.executeStage.data.pc := pc
|
||||
io.executeStage.data.info := info
|
||||
|
@ -61,4 +58,5 @@ class DecodeUnit extends Module with HasExceptionNO with HasCSRConst {
|
|||
forwardCtrl.out.data.src2.rdata,
|
||||
info.imm
|
||||
)
|
||||
io.executeStage.data.ex := DontCare // TODO: 未实现
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package cpu.pipeline.decode
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package cpu.pipeline.decode
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package cpu.pipeline.execute
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
package cpu.pipeline.execute
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.CpuConfig
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.pipeline.decode.RegWrite
|
||||
import cpu.pipeline.memory.ExecuteUnitMemoryUnit
|
||||
|
||||
class ExecuteUnit extends Module {
|
||||
val io = IO(new Bundle {
|
||||
|
@ -27,20 +25,24 @@ class ExecuteUnit extends Module {
|
|||
val valid = io.executeStage.data.info.valid && io.ctrl.ctrlSignal.allow_to_go
|
||||
val fusel = io.executeStage.data.info.fusel
|
||||
|
||||
val fu = Module(new Fu()).io
|
||||
fu.data.pc := io.executeStage.data.pc
|
||||
fu.data.info := io.executeStage.data.info
|
||||
fu.data.src_info := io.executeStage.data.src_info
|
||||
fu.data.ex.in := io.executeStage.data.ex
|
||||
|
||||
io.dataSram <> fu.dataSram
|
||||
|
||||
io.ctrl.data.is_load := fusel === FuType.lsu && LSUOpType.isLoad(io.executeStage.data.info.op)
|
||||
io.ctrl.data.reg_waddr := io.executeStage.data.info.reg_waddr
|
||||
io.ctrl.flush := valid && fu.ctrl.flush
|
||||
io.ctrl.target := fu.ctrl.target
|
||||
|
||||
val fu = Module(new Fu()).io
|
||||
fu.data.pc := io.executeStage.data.pc
|
||||
fu.data.info := io.executeStage.data.info
|
||||
fu.data.src_info := io.executeStage.data.src_info
|
||||
|
||||
io.memoryStage.data.pc := io.executeStage.data.pc
|
||||
io.memoryStage.data.info := io.executeStage.data.info
|
||||
io.memoryStage.data.src_info := io.executeStage.data.src_info
|
||||
io.memoryStage.data.rd_info := fu.data.rd_info
|
||||
io.memoryStage.data.ex := fu.data.ex.out
|
||||
|
||||
// 数据前递
|
||||
io.decodeUnit.forward.exe.wen := io.memoryStage.data.info.reg_wen
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package cpu.pipeline.execute
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
@ -6,90 +6,51 @@ import cpu.defines._
|
|||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
|
||||
class Fu(implicit val cpuConfig: CpuConfig) extends Module {
|
||||
class Fu extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val ctrl = new ExecuteFuCtrl()
|
||||
val inst = Vec(
|
||||
cpuConfig.decoderNum,
|
||||
new Bundle {
|
||||
val pc = Input(UInt(XLEN.W))
|
||||
val info = Input(new Info())
|
||||
val src_info = Input(new SrcInfo())
|
||||
val result = Output(new Bundle {
|
||||
val mdu = UInt(XLEN.W)
|
||||
val alu = UInt(XLEN.W)
|
||||
})
|
||||
val data = new Bundle {
|
||||
val pc = Input(UInt(XLEN.W))
|
||||
val info = Input(new Info())
|
||||
val src_info = Input(new SrcInfo())
|
||||
val rd_info = Output(new RdInfo())
|
||||
val ex = new Bundle {
|
||||
val in = Input(new ExceptionInfo())
|
||||
val out = Output(new ExceptionInfo())
|
||||
}
|
||||
)
|
||||
val dataMemory = new Bundle {
|
||||
val addr = Output(UInt(XLEN.W))
|
||||
}
|
||||
val branch = new Bundle {
|
||||
val pred_branch = Input(Bool())
|
||||
val jump_regiser = Input(Bool())
|
||||
val branch_target = Input(UInt(XLEN.W))
|
||||
val branch = Output(Bool())
|
||||
val flush = Output(Bool())
|
||||
val target = Output(UInt(XLEN.W))
|
||||
|
||||
val dataSram = new DataSram()
|
||||
val ctrl = new Bundle {
|
||||
val flush = Output(Bool())
|
||||
val target = Output(UInt(XLEN.W))
|
||||
}
|
||||
})
|
||||
|
||||
val alu = Seq.fill(cpuConfig.decoderNum)(Module(new Alu()))
|
||||
val branchCtrl = Module(new BranchCtrl()).io
|
||||
val mdu = Module(new Mdu()).io
|
||||
val alu = Module(new Alu()).io
|
||||
val bru = Module(new Bru()).io
|
||||
val mdu = Module(new Mdu()).io
|
||||
val lsu = Module(new Lsu()).io
|
||||
|
||||
branchCtrl.in.pc := io.inst(0).pc
|
||||
branchCtrl.in.info := io.inst(0).info
|
||||
branchCtrl.in.src_info := io.inst(0).src_info
|
||||
branchCtrl.in.pred_branch := io.branch.pred_branch
|
||||
branchCtrl.in.jump_regiser := io.branch.jump_regiser
|
||||
branchCtrl.in.branch_target := io.branch.branch_target
|
||||
io.branch.branch := branchCtrl.out.branch
|
||||
bru.in.pc := io.data.pc
|
||||
bru.in.info := io.data.info
|
||||
bru.in.src_info := io.data.src_info
|
||||
|
||||
val branchCtrl_flush = (branchCtrl.out.pred_fail || io.branch.jump_regiser)
|
||||
io.branch.flush := branchCtrl_flush
|
||||
io.branch.target := branchCtrl.out.target
|
||||
alu.info := io.data.info
|
||||
alu.src_info := io.data.src_info
|
||||
|
||||
for (i <- 0 until (cpuConfig.commitNum)) {
|
||||
alu(i).io.info := Mux(io.inst(i).info.fusel === FuType.alu, io.inst(i).info, 0.U.asTypeOf(new Info()))
|
||||
alu(i).io.src_info := Mux(io.inst(i).info.fusel === FuType.alu, io.inst(i).src_info, 0.U.asTypeOf(new SrcInfo()))
|
||||
}
|
||||
mdu.info := io.data.info
|
||||
mdu.src_info := io.data.src_info
|
||||
|
||||
val mdu_sel = VecInit(
|
||||
io.inst(0).info.fusel === FuType.mdu,
|
||||
io.inst(1).info.fusel === FuType.mdu
|
||||
)
|
||||
lsu.info := io.data.info
|
||||
lsu.src_info := io.data.src_info
|
||||
lsu.dataSram <> io.dataSram
|
||||
|
||||
mdu.info := MuxCase(
|
||||
0.U.asTypeOf(new Info()),
|
||||
Seq(mdu_sel(0) -> io.inst(0).info, mdu_sel(1) -> io.inst(1).info)
|
||||
)
|
||||
mdu.src_info := MuxCase(
|
||||
0.U.asTypeOf(new SrcInfo()),
|
||||
Seq(mdu_sel(0) -> io.inst(0).src_info, mdu_sel(1) -> io.inst(1).src_info)
|
||||
)
|
||||
mdu.allow_to_go := io.ctrl.allow_to_go
|
||||
io.data.rd_info.wdata := DontCare
|
||||
io.data.rd_info.wdata(FuType.alu) := alu.result
|
||||
io.data.rd_info.wdata(FuType.bru) := io.data.pc + 4.U
|
||||
io.data.rd_info.wdata(FuType.mdu) := mdu.result
|
||||
io.data.ex.out := io.data.ex.in // TODO: add exception handling
|
||||
|
||||
io.ctrl.stall := io.inst.map(_.info.fusel === FuType.mdu).reduce(_ || _) && !mdu.ready
|
||||
|
||||
io.inst(0).result.alu := alu(0).io.result
|
||||
io.inst(0).result.mdu := mdu.result
|
||||
|
||||
io.inst(1).result.alu := alu(1).io.result
|
||||
io.inst(1).result.mdu := mdu.result
|
||||
|
||||
val mem_addr = Seq.tabulate(cpuConfig.commitNum)(i =>
|
||||
Mux(
|
||||
LSUOpType.isAtom(io.inst(i).info.op),
|
||||
io.inst(i).src_info.src1_data,
|
||||
io.inst(i).src_info.src1_data + io.inst(i).info.imm
|
||||
)
|
||||
)
|
||||
// 当mem级访存发生stall时,mem_addr_last不变
|
||||
val mem_addr_last = RegEnable(io.dataMemory.addr, io.ctrl.allow_to_go)
|
||||
io.dataMemory.addr := Mux(
|
||||
!io.ctrl.allow_to_go,
|
||||
mem_addr_last,
|
||||
Mux(io.inst(0).info.fusel === FuType.lsu, mem_addr(0), mem_addr(1))
|
||||
)
|
||||
io.ctrl.flush := bru.out.branch
|
||||
io.ctrl.target := bru.out.target
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package cpu.pipeline.execute
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package cpu.pipeline.execute
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
package cpu.pipeline.execute
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
import chisel3.util.experimental.BoringUtils
|
||||
|
||||
class CsrMemoryUnit(implicit val cpuConfig: CpuConfig) extends Bundle {
|
||||
val in = Input(new Bundle {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package cpu.pipeline.execute
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package cpu.pipeline.execute
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package cpu.pipeline.execute
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package cpu.pipeline.execute
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
|
|
@ -1,22 +1,15 @@
|
|||
package cpu.pipeline.fetch
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
import cpu.defines._
|
||||
import cpu.pipeline.decode.FetchUnitDecodeUnit
|
||||
|
||||
class ExecuteUnitFetchUnit extends Bundle {
|
||||
val flush = Output(Bool())
|
||||
val target = Output(UInt(XLEN.W))
|
||||
}
|
||||
|
||||
class FetchUnit extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val ctrl = new FetchUnitCtrl()
|
||||
val execute = Flipped(new ExecuteUnitFetchUnit())
|
||||
val decodeStage = Output(new FetchUnitDecodeUnit())
|
||||
val decodeStage = new FetchUnitDecodeUnit()
|
||||
val instSram = new InstSram()
|
||||
})
|
||||
val pc = RegNext(io.instSram.addr, PC_INIT)
|
||||
|
@ -28,7 +21,7 @@ class FetchUnit extends Module {
|
|||
io.instSram.addr := MuxCase(
|
||||
pc + 4.U,
|
||||
Seq(
|
||||
io.execute.flush -> io.execute.target,
|
||||
io.ctrl.ctrlSignal.do_flush -> io.ctrl.target,
|
||||
!io.ctrl.ctrlSignal.allow_to_go -> pc
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package cpu.pipeline.memory
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
|
|
@ -1,26 +1,18 @@
|
|||
package cpu.pipeline.memory
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import chisel3.util.experimental.BoringUtils
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.CpuConfig
|
||||
import cpu.pipeline.decode.RegWrite
|
||||
import cpu.pipeline.execute.CsrMemoryUnit
|
||||
import cpu.pipeline.writeback.MemoryUnitWriteBackUnit
|
||||
import chisel3.util.experimental.BoringUtils
|
||||
|
||||
class MemoryUnit extends Module {
|
||||
val io = IO(new Bundle {
|
||||
val ctrl = new MemoryCtrl()
|
||||
val memoryStage = Input(new ExecuteUnitMemoryUnit())
|
||||
val fetchUnit = Output(new Bundle {
|
||||
val flush = Bool()
|
||||
val target = UInt(XLEN.W)
|
||||
})
|
||||
val ctrl = new MemoryCtrl()
|
||||
val memoryStage = Input(new ExecuteUnitMemoryUnit())
|
||||
val decodeUnit = Output(new RegWrite())
|
||||
val writeBackStage = Output(new MemoryUnitWriteBackUnit())
|
||||
val dataSram = new DataSram()
|
||||
})
|
||||
|
||||
val rdata = Wire(UInt(XLEN.W))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package cpu.pipeline.writeback
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
package cpu.pipeline.writeback
|
||||
package cpu.pipeline
|
||||
|
||||
import chisel3._
|
||||
import chisel3.util._
|
||||
import cpu.defines._
|
||||
import cpu.defines.Const._
|
||||
import cpu.pipeline.decode.RegWrite
|
||||
import cpu.CpuConfig
|
||||
|
||||
class WriteBackUnit extends Module {
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
import cpu._
|
||||
import circt.stage._
|
||||
// import cpu._
|
||||
// import circt.stage._
|
||||
|
||||
import cpu.pipeline.execute.Csr
|
||||
import cache.DCache
|
||||
import icache.mmu.Tlb
|
||||
|
||||
object TestMain extends App {
|
||||
implicit val cpuConfig = new CpuConfig()
|
||||
implicit val dCacheConfig = CacheConfig(cacheType = "dcache")
|
||||
def top = new DCache(dCacheConfig)
|
||||
val useMFC = false // use MLIR-based firrtl compiler
|
||||
val generator = Seq(chisel3.stage.ChiselGeneratorAnnotation(() => top))
|
||||
if (useMFC) {
|
||||
(new ChiselStage).execute(args, generator :+ CIRCTTargetAnnotation(CIRCTTarget.Verilog))
|
||||
} else {
|
||||
(new chisel3.stage.ChiselStage).execute(args, generator)
|
||||
}
|
||||
}
|
||||
// object TestMain extends App {
|
||||
// implicit val cpuConfig = new CpuConfig()
|
||||
// def top = new Top()
|
||||
// val useMFC = false // use MLIR-based firrtl compiler
|
||||
// val generator = Seq(chisel3.stage.ChiselGeneratorAnnotation(() => top))
|
||||
// if (useMFC) {
|
||||
// (new ChiselStage).execute(args, generator :+ CIRCTTargetAnnotation(CIRCTTarget.Verilog))
|
||||
// } else {
|
||||
// (new chisel3.stage.ChiselStage).execute(args, generator)
|
||||
// }
|
||||
// }
|
||||
|
|
Loading…
Reference in New Issue