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

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.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 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
}

View File

@ -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 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
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
}

View File

@ -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
}

View File

@ -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(implicit val cpuConfig: CpuConfig) extends Bundle {
val inst = Output(Vec(cpuConfig.commitNum, new MemRead()))
class ExecuteCtrl extends Bundle {
val data = Output(new MemRead())
val flush = Output(Bool())
val target = Output(UInt(XLEN.W))
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()
}
// 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))
class InstSram extends Bundle {
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 complete_single_request = Output(Bool())
val fence_i = Output(Bool())
val wstrb = Output(UInt(AXI_STRB_WID.W))
val wen = 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 DEBUG extends Bundle {

View File

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

View File

@ -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

View File

@ -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: 未实现
}

View File

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

View File

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

View File

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

View File

@ -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

View File

@ -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 data = 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 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 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 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()))
}
val mdu_sel = VecInit(
io.inst(0).info.fusel === FuType.mdu,
io.inst(1).info.fusel === FuType.mdu
)
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.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))
)
mdu.info := io.data.info
mdu.src_info := io.data.src_info
lsu.info := io.data.info
lsu.src_info := io.data.src_info
lsu.dataSram <> io.dataSram
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.flush := bru.out.branch
io.ctrl.target := bru.out.target
}

View File

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

View File

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

View File

@ -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 {

View File

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

View File

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

View File

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

View File

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

View File

@ -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
)
)

View File

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

View File

@ -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 decodeUnit = Output(new RegWrite())
val writeBackStage = Output(new MemoryUnitWriteBackUnit())
val dataSram = new DataSram()
})
val rdata = Wire(UInt(XLEN.W))

View File

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

View File

@ -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 {

View File

@ -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)
// }
// }