修改包名,修改各单元逻辑

This commit is contained in:
Liphen 2024-03-22 22:45:48 +08:00
parent 703cd0b41c
commit 6508b72858
25 changed files with 178 additions and 438 deletions

View File

@ -2,139 +2,72 @@ package cpu
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._
import chisel3.internal.DontCareBinding
import defines._ import defines._
import defines.Const._ import defines.Const._
import pipeline.fetch._ import pipeline._
import pipeline.decode._
import pipeline.execute._
import pipeline.memory._
import pipeline.writeback._
import ctrl._ import ctrl._
import icache.mmu.Tlb
class Core(implicit val cpuConfig: CpuConfig) extends Module { class Core extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val ext_int = Input(new ExtInterrupt()) val interrupt = Input(new ExtInterrupt())
val inst = new Cache_ICache() val instSram = new InstSram()
val data = new Cache_DCache() val dataSram = new DataSram()
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 decodeStage = Module(new DecodeStage()).io
val instFifo = Module(new InstFifo()).io
val decodeUnit = Module(new DecodeUnit()).io val decodeUnit = Module(new DecodeUnit()).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 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
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.decodeUnit <> decodeUnit.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.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.instSram <> io.instSram
fetchUnit.decode <> decodeUnit.fetchUnit fetchUnit.decodeStage <> decodeStage.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
}
// 译码级缓存
decodeStage.decodeUnit <> decodeUnit.decodeStage
// 译码单元
decodeUnit.regfile <> regfile.read decodeUnit.regfile <> regfile.read
for (i <- 0 until (cpuConfig.commitNum)) { decodeUnit.forward.exe := executeUnit.decodeUnit.forward.exe
decodeUnit.forward(i).exe := executeUnit.decodeUnit.forward(i).exe decodeUnit.forward.is_load := executeUnit.decodeUnit.forward.is_load // exe级是load指令
decodeUnit.forward(i).is_load := executeUnit.decodeUnit.forward(i).is_load // exe级是load指令 decodeUnit.forward.mem := memoryUnit.decodeUnit
decodeUnit.forward(i).mem := memoryUnit.decodeUnit(i)
}
decodeUnit.csr <> csr.decodeUnit
decodeUnit.executeStage <> executeStage.decodeUnit decodeUnit.executeStage <> executeStage.decodeUnit
for (i <- 0 until (cpuConfig.commitNum)) { // 执行级缓存
// 流水线清空或者暂停时需要清空缓存级的数据也就是插入气泡 executeStage.executeUnit <> executeUnit.executeStage
executeStage.ctrl.clear(i) := executeUnit.dataSram <> io.dataSram
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 executeUnit.memoryStage <> memoryStage.executeUnit
memoryStage.ctrl.allow_to_go := ctrl.memoryUnit.allow_to_go // 访存级缓存
memoryStage.ctrl.clear := ctrl.memoryUnit.do_flush memoryStage.memoryUnit <> memoryUnit.memoryStage
// 访存单元
memoryUnit.memoryStage <> memoryStage.memoryUnit
memoryUnit.csr <> csr.memoryUnit
memoryUnit.writeBackStage <> writeBackStage.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.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.writeBackStage <> writeBackStage.writeBackUnit
writeBackUnit.ctrl <> ctrl.writeBackUnit writeBackUnit.regfile <> regfile.write
regfile.write <> writeBackUnit.regfile 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
} }

View File

@ -1,23 +1,20 @@
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._
import cache._
import cpu._ import cpu._
import cpu.defines._ import cpu.defines._
class PuaCpu extends Module { class PuaCpu extends Module {
implicit val cpuConfig = new CpuConfig()
val io = IO(new Bundle { val io = IO(new Bundle {
val ext_int = Input(new ExtInterrupt()) val ext_int = Input(new ExtInterrupt())
val axi = new AXI() val inst_sram = new InstSram()
val data_sram = new DataSram()
val debug = new DEBUG() val debug = new DEBUG()
}) })
val core = Module(new Core()) val core = Module(new Core())
val cache = Module(new Cache())
core.io.inst <> cache.io.inst io.ext_int <> core.io.interrupt
core.io.data <> cache.io.data io.inst_sram <> core.io.instSram
io.data_sram <> core.io.dataSram
io.ext_int <> core.io.ext_int
io.debug <> core.io.debug io.debug <> core.io.debug
io.axi <> cache.io.axi
} }

View File

@ -6,9 +6,8 @@ import cpu.defines._
import cpu.defines.Const._ import cpu.defines.Const._
import cpu.CpuConfig import cpu.CpuConfig
class Ctrl(implicit val cpuConfig: CpuConfig) extends Module { class Ctrl extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val cacheCtrl = Flipped(new CacheCtrl())
val fetchUnit = Flipped(new FetchUnitCtrl()) val fetchUnit = Flipped(new FetchUnitCtrl())
val decodeUnit = Flipped(new DecodeUnitCtrl()) val decodeUnit = Flipped(new DecodeUnitCtrl())
val executeUnit = Flipped(new ExecuteCtrl()) val executeUnit = Flipped(new ExecuteCtrl())
@ -16,27 +15,22 @@ class Ctrl(implicit val cpuConfig: CpuConfig) extends Module {
val writeBackUnit = Flipped(new WriteBackCtrl()) val writeBackUnit = Flipped(new WriteBackCtrl())
}) })
val inst0_lw_stall = (io.executeUnit.inst(0).is_load) && io.executeUnit.inst(0).reg_waddr.orR && val lw_stall = (io.executeUnit.data.is_load) && io.executeUnit.data.reg_waddr.orR &&
(io.decodeUnit.inst0.src1.ren && io.decodeUnit.inst0.src1.raddr === io.executeUnit.inst(0).reg_waddr || (io.decodeUnit.src_info.src1.ren && io.decodeUnit.src_info.src1.raddr === io.executeUnit.data.reg_waddr ||
io.decodeUnit.inst0.src2.ren && io.decodeUnit.inst0.src2.raddr === io.executeUnit.inst(0).reg_waddr) io.decodeUnit.src_info.src2.ren && io.decodeUnit.src_info.src2.raddr === io.executeUnit.data.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
io.fetchUnit.allow_to_go := !io.cacheCtrl.iCache_stall io.fetchUnit.ctrlSignal.allow_to_go := !lw_stall
io.decodeUnit.allow_to_go := !(lw_stall || longest_stall) io.decodeUnit.ctrlSignal.allow_to_go := !lw_stall
io.executeUnit.allow_to_go := !longest_stall io.executeUnit.ctrlSignal.allow_to_go := true.B
io.memoryUnit.allow_to_go := !longest_stall io.memoryUnit.ctrlSignal.allow_to_go := true.B
io.writeBackUnit.allow_to_go := !longest_stall io.writeBackUnit.ctrlSignal.allow_to_go := true.B
io.fetchUnit.do_flush := false.B io.fetchUnit.ctrlSignal.do_flush := io.executeUnit.flush
io.decodeUnit.do_flush := io.memoryUnit.flush || io.executeUnit.flush || io.decodeUnit.branch io.decodeUnit.ctrlSignal.do_flush := io.executeUnit.flush ||
io.executeUnit.do_flush := io.memoryUnit.flush || io.executeUnit.flush !io.decodeUnit.ctrlSignal.allow_to_go && io.executeUnit.ctrlSignal.allow_to_go
io.memoryUnit.do_flush := io.memoryUnit.flush io.executeUnit.ctrlSignal.do_flush := io.executeUnit.flush
io.writeBackUnit.do_flush := false.B 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
} }

View File

@ -5,8 +5,6 @@ import chisel3.util._
import cpu.defines._ import cpu.defines._
import cpu.defines.Const._ import cpu.defines.Const._
import cpu.CpuConfig import cpu.CpuConfig
import icache.mmu.{Tlb_DCache, Tlb_ICache}
import cpu.pipeline.memory.Mou
class ExceptionInfo extends Bundle { class ExceptionInfo extends Bundle {
val exception = Vec(EXC_WID, Bool()) val exception = Vec(EXC_WID, Bool())
@ -54,174 +52,55 @@ class SrcReadSignal extends Bundle {
val raddr = UInt(REG_ADDR_WID.W) val raddr = UInt(REG_ADDR_WID.W)
} }
class CacheCtrl extends Bundle { class CtrlSignal extends Bundle {
val iCache_stall = Output(Bool()) val allow_to_go = Bool()
val do_flush = Bool()
} }
class FetchUnitCtrl extends Bundle { class FetchUnitCtrl extends Bundle {
val allow_to_go = Input(Bool()) val target = Input(UInt(XLEN.W))
val do_flush = Input(Bool()) val ctrlSignal = Input(new CtrlSignal())
} }
class DecodeUnitCtrl extends Bundle { class DecodeUnitCtrl extends Bundle {
val inst0 = Output(new Bundle { val src_info = Output(new Bundle {
val src1 = new SrcReadSignal() val src1 = new SrcReadSignal()
val src2 = new SrcReadSignal() val src2 = new SrcReadSignal()
}) })
val branch = Output(Bool())
val allow_to_go = Input(Bool()) val ctrlSignal = Input(new CtrlSignal())
val do_flush = Input(Bool())
} }
class ExecuteFuCtrl extends Bundle { class ExecuteCtrl extends Bundle {
val allow_to_go = Input(Bool()) val data = Output(new MemRead())
val stall = Output(Bool())
}
class ExecuteCtrl(implicit val cpuConfig: CpuConfig) extends Bundle {
val inst = Output(Vec(cpuConfig.commitNum, new MemRead()))
val flush = Output(Bool()) val flush = Output(Bool())
val target = Output(UInt(XLEN.W))
val allow_to_go = Input(Bool()) val ctrlSignal = Input(new CtrlSignal())
val do_flush = Input(Bool())
val fu = new ExecuteFuCtrl()
}
class MouTlb extends Bundle {
val valid = Bool()
val src_info = new SrcInfo()
} }
class MemoryCtrl extends Bundle { class MemoryCtrl extends Bundle {
val flush = Output(Bool()) val ctrlSignal = Input(new CtrlSignal())
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())
} }
class WriteBackCtrl extends Bundle { class WriteBackCtrl extends Bundle {
val allow_to_go = Input(Bool()) val ctrlSignal = Input(new CtrlSignal())
val do_flush = Input(Bool())
} }
// cpu to icache class InstSram extends Bundle {
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()
}
// 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 en = Output(Bool())
val wen = 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))
}
class DataSram extends Bundle {
val en = Output(Bool())
val addr = Output(UInt(AXI_ADDR_WID.W))
val wdata = Output(UInt(XLEN.W)) val wdata = Output(UInt(XLEN.W))
val complete_single_request = Output(Bool()) val wen = Output(UInt(AXI_STRB_WID.W))
val fence_i = Output(Bool())
val wstrb = Output(UInt(AXI_STRB_WID.W))
val rdata = Input(UInt(XLEN.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 DEBUG extends Bundle { class DEBUG extends Bundle {

View File

@ -1,4 +1,4 @@
package cpu.pipeline.decode package cpu.pipeline
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._

View File

@ -1,4 +1,4 @@
package cpu.pipeline.decode package cpu.pipeline
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._
@ -13,25 +13,23 @@ class IfIdData extends Bundle {
val addr_misaligned = Bool() val addr_misaligned = Bool()
} }
class FetchUnitDecodeUnit extends IfIdData { class FetchUnitDecodeUnit extends Bundle {
val data = Output(new IfIdData()) val data = Output(new IfIdData())
} }
class DecodeStage extends Module { class DecodeStage extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val ctrl = Input(new Bundle { val ctrl = Input(new CtrlSignal())
val allow_to_go = Bool()
val clear = Bool()
})
val fetchUnit = Flipped(new FetchUnitDecodeUnit()) val fetchUnit = Flipped(new FetchUnitDecodeUnit())
val decodeUnit = new FetchUnitDecodeUnit() val decodeUnit = new FetchUnitDecodeUnit()
}) })
val data = RegInit(0.U.asTypeOf(new IfIdData())) val data = RegInit(0.U.asTypeOf(new IfIdData()))
when(io.ctrl.clear) { when(io.ctrl.do_flush) {
data := 0.U.asTypeOf(new IfIdData()) data := 0.U.asTypeOf(new IfIdData())
}.elsewhen(io.ctrl.allow_to_go) { }.elsewhen(io.ctrl.allow_to_go) {
data := io.fetchUnit data := io.fetchUnit.data
} }
io.decodeUnit.data := data io.decodeUnit.data := data

View File

@ -1,12 +1,9 @@
package cpu.pipeline.decode package cpu.pipeline
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._
import chisel3.util.experimental.BoringUtils
import cpu.defines._ import cpu.defines._
import cpu.defines.Const._ import cpu.defines.Const._
import cpu.pipeline.execute.DecodeUnitExecuteUnit
import cpu.pipeline.execute
class DataForwardToDecodeUnit extends Bundle { class DataForwardToDecodeUnit extends Bundle {
val exe = new RegWrite() val exe = new RegWrite()
@ -21,31 +18,31 @@ class DecodeUnit extends Module with HasExceptionNO with HasCSRConst {
val regfile = new Src12Read() val regfile = new Src12Read()
val forward = Input(new DataForwardToDecodeUnit()) 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 executeStage = Output(new DecodeUnitExecuteUnit())
val ctrl = new DecodeUnitCtrl() 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 forwardCtrl = Module(new ForwardCtrl()).io
val pc = io.decodeStage.data.pc val pc = io.decodeStage.data.pc
val info = Wire(new Info()) val info = Wire(new Info())
info := decoder.io.out.info info := decoder.out.info
info.valid := io.decodeStage.data.valid info.valid := io.decodeStage.data.valid
forwardCtrl.in.forward := io.forward forwardCtrl.in.forward := io.forward
forwardCtrl.in.regfile := io.regfile 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.ren := info.src1_ren
io.ctrl.src_info.src1.raddr := info.src1_raddr io.ctrl.src_info.src1.raddr := info.src1_raddr
io.ctrl.src_info.src2.ren := info.src2_ren io.ctrl.src_info.src2.ren := info.src2_ren
io.ctrl.src_info.src2.raddr := info.src2_raddr io.ctrl.src_info.src2.raddr := info.src2_raddr
io.ctrl.branch := io.fetchUnit.branch
io.executeStage.data.pc := pc io.executeStage.data.pc := pc
io.executeStage.data.info := info io.executeStage.data.info := info
@ -61,4 +58,5 @@ class DecodeUnit extends Module with HasExceptionNO with HasCSRConst {
forwardCtrl.out.data.src2.rdata, forwardCtrl.out.data.src2.rdata,
info.imm info.imm
) )
io.executeStage.data.ex := DontCare // TODO: 未实现
} }

View File

@ -1,4 +1,4 @@
package cpu.pipeline.decode package cpu.pipeline
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._

View File

@ -1,4 +1,4 @@
package cpu.pipeline.decode package cpu.pipeline
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._

View File

@ -1,4 +1,4 @@
package cpu.pipeline.execute package cpu.pipeline
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._

View File

@ -1,12 +1,10 @@
package cpu.pipeline.execute package cpu.pipeline
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.decode.RegWrite
import cpu.pipeline.memory.ExecuteUnitMemoryUnit
class ExecuteUnit extends Module { class ExecuteUnit extends Module {
val io = IO(new Bundle { 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 valid = io.executeStage.data.info.valid && io.ctrl.ctrlSignal.allow_to_go
val fusel = io.executeStage.data.info.fusel 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.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.data.reg_waddr := io.executeStage.data.info.reg_waddr
io.ctrl.flush := valid && fu.ctrl.flush io.ctrl.flush := valid && fu.ctrl.flush
io.ctrl.target := fu.ctrl.target 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.pc := io.executeStage.data.pc
io.memoryStage.data.info := io.executeStage.data.info io.memoryStage.data.info := io.executeStage.data.info
io.memoryStage.data.src_info := io.executeStage.data.src_info io.memoryStage.data.src_info := io.executeStage.data.src_info
io.memoryStage.data.rd_info := fu.data.rd_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 io.decodeUnit.forward.exe.wen := io.memoryStage.data.info.reg_wen

View File

@ -1,4 +1,4 @@
package cpu.pipeline.execute package cpu.pipeline
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._
@ -6,90 +6,51 @@ import cpu.defines._
import cpu.defines.Const._ import cpu.defines.Const._
import cpu.CpuConfig import cpu.CpuConfig
class Fu(implicit val cpuConfig: CpuConfig) extends Module { class Fu extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val ctrl = new ExecuteFuCtrl() val data = new Bundle {
val inst = Vec(
cpuConfig.decoderNum,
new Bundle {
val pc = Input(UInt(XLEN.W)) val pc = Input(UInt(XLEN.W))
val info = Input(new Info()) val info = Input(new Info())
val src_info = Input(new SrcInfo()) val src_info = Input(new SrcInfo())
val result = Output(new Bundle { val rd_info = Output(new RdInfo())
val mdu = UInt(XLEN.W) val ex = new Bundle {
val alu = UInt(XLEN.W) 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 dataSram = new DataSram()
val jump_regiser = Input(Bool()) val ctrl = new Bundle {
val branch_target = Input(UInt(XLEN.W))
val branch = Output(Bool())
val flush = Output(Bool()) val flush = Output(Bool())
val target = Output(UInt(XLEN.W)) val target = Output(UInt(XLEN.W))
} }
}) })
val alu = Seq.fill(cpuConfig.decoderNum)(Module(new Alu())) val alu = Module(new Alu()).io
val branchCtrl = Module(new BranchCtrl()).io val bru = Module(new Bru()).io
val mdu = Module(new Mdu()).io val mdu = Module(new Mdu()).io
val lsu = Module(new Lsu()).io
branchCtrl.in.pc := io.inst(0).pc bru.in.pc := io.data.pc
branchCtrl.in.info := io.inst(0).info bru.in.info := io.data.info
branchCtrl.in.src_info := io.inst(0).src_info bru.in.src_info := io.data.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
val branchCtrl_flush = (branchCtrl.out.pred_fail || io.branch.jump_regiser) alu.info := io.data.info
io.branch.flush := branchCtrl_flush alu.src_info := io.data.src_info
io.branch.target := branchCtrl.out.target
for (i <- 0 until (cpuConfig.commitNum)) { mdu.info := io.data.info
alu(i).io.info := Mux(io.inst(i).info.fusel === FuType.alu, io.inst(i).info, 0.U.asTypeOf(new Info())) mdu.src_info := io.data.src_info
alu(i).io.src_info := Mux(io.inst(i).info.fusel === FuType.alu, io.inst(i).src_info, 0.U.asTypeOf(new SrcInfo()))
}
val mdu_sel = VecInit( lsu.info := io.data.info
io.inst(0).info.fusel === FuType.mdu, lsu.src_info := io.data.src_info
io.inst(1).info.fusel === FuType.mdu lsu.dataSram <> io.dataSram
)
mdu.info := MuxCase( io.data.rd_info.wdata := DontCare
0.U.asTypeOf(new Info()), io.data.rd_info.wdata(FuType.alu) := alu.result
Seq(mdu_sel(0) -> io.inst(0).info, mdu_sel(1) -> io.inst(1).info) io.data.rd_info.wdata(FuType.bru) := io.data.pc + 4.U
) io.data.rd_info.wdata(FuType.mdu) := mdu.result
mdu.src_info := MuxCase( io.data.ex.out := io.data.ex.in // TODO: add exception handling
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.ctrl.stall := io.inst.map(_.info.fusel === FuType.mdu).reduce(_ || _) && !mdu.ready io.ctrl.flush := bru.out.branch
io.ctrl.target := bru.out.target
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))
)
} }

View File

@ -1,4 +1,4 @@
package cpu.pipeline.execute package cpu.pipeline
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._

View File

@ -1,4 +1,4 @@
package cpu.pipeline.execute package cpu.pipeline
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._

View File

@ -1,11 +1,10 @@
package cpu.pipeline.execute package cpu.pipeline
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 chisel3.util.experimental.BoringUtils
class CsrMemoryUnit(implicit val cpuConfig: CpuConfig) extends Bundle { class CsrMemoryUnit(implicit val cpuConfig: CpuConfig) extends Bundle {
val in = Input(new Bundle { val in = Input(new Bundle {

View File

@ -1,4 +1,4 @@
package cpu.pipeline.execute package cpu.pipeline
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._

View File

@ -1,4 +1,4 @@
package cpu.pipeline.execute package cpu.pipeline
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._

View File

@ -1,4 +1,4 @@
package cpu.pipeline.execute package cpu.pipeline
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._

View File

@ -1,4 +1,4 @@
package cpu.pipeline.execute package cpu.pipeline
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._

View File

@ -1,22 +1,15 @@
package cpu.pipeline.fetch package cpu.pipeline
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._
import cpu.defines.Const._ import cpu.defines.Const._
import cpu.CpuConfig import cpu.CpuConfig
import cpu.defines._ 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 { class FetchUnit extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val ctrl = new FetchUnitCtrl() val ctrl = new FetchUnitCtrl()
val execute = Flipped(new ExecuteUnitFetchUnit()) val decodeStage = new FetchUnitDecodeUnit()
val decodeStage = Output(new FetchUnitDecodeUnit())
val instSram = new InstSram() val instSram = new InstSram()
}) })
val pc = RegNext(io.instSram.addr, PC_INIT) val pc = RegNext(io.instSram.addr, PC_INIT)
@ -28,7 +21,7 @@ class FetchUnit extends Module {
io.instSram.addr := MuxCase( io.instSram.addr := MuxCase(
pc + 4.U, pc + 4.U,
Seq( Seq(
io.execute.flush -> io.execute.target, io.ctrl.ctrlSignal.do_flush -> io.ctrl.target,
!io.ctrl.ctrlSignal.allow_to_go -> pc !io.ctrl.ctrlSignal.allow_to_go -> pc
) )
) )

View File

@ -1,4 +1,4 @@
package cpu.pipeline.memory package cpu.pipeline
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._

View File

@ -1,26 +1,18 @@
package cpu.pipeline.memory package cpu.pipeline
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._
import chisel3.util.experimental.BoringUtils
import cpu.defines._ import cpu.defines._
import cpu.defines.Const._ import cpu.defines.Const._
import cpu.CpuConfig 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 { class MemoryUnit 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 flush = Bool()
val target = UInt(XLEN.W)
})
val decodeUnit = Output(new RegWrite()) val decodeUnit = Output(new RegWrite())
val writeBackStage = Output(new MemoryUnitWriteBackUnit()) val writeBackStage = Output(new MemoryUnitWriteBackUnit())
val dataSram = new DataSram()
}) })
val rdata = Wire(UInt(XLEN.W)) val rdata = Wire(UInt(XLEN.W))

View File

@ -1,4 +1,4 @@
package cpu.pipeline.writeback package cpu.pipeline
import chisel3._ import chisel3._
import chisel3.util._ import chisel3.util._

View File

@ -1,10 +1,9 @@
package cpu.pipeline.writeback package cpu.pipeline
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.decode.RegWrite
import cpu.CpuConfig import cpu.CpuConfig
class WriteBackUnit extends Module { class WriteBackUnit extends Module {

View File

@ -1,19 +1,14 @@
import cpu._ // import cpu._
import circt.stage._ // import circt.stage._
import cpu.pipeline.execute.Csr // object TestMain extends App {
import cache.DCache // implicit val cpuConfig = new CpuConfig()
import icache.mmu.Tlb // def top = new Top()
// val useMFC = false // use MLIR-based firrtl compiler
object TestMain extends App { // val generator = Seq(chisel3.stage.ChiselGeneratorAnnotation(() => top))
implicit val cpuConfig = new CpuConfig() // if (useMFC) {
implicit val dCacheConfig = CacheConfig(cacheType = "dcache") // (new ChiselStage).execute(args, generator :+ CIRCTTargetAnnotation(CIRCTTarget.Verilog))
def top = new DCache(dCacheConfig) // } else {
val useMFC = false // use MLIR-based firrtl compiler // (new chisel3.stage.ChiselStage).execute(args, generator)
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)
}
}