完成实验大致框架

实现转移指令的理想流水线设计实验
This commit is contained in:
Liphen 2024-05-27 15:50:41 +08:00
parent 0797cd651e
commit ecddfd545b
13 changed files with 35 additions and 165 deletions

View File

@ -15,7 +15,6 @@ class Core extends Module {
val debug = new DEBUG() val debug = new DEBUG()
}) })
val ctrl = Module(new Ctrl()).io
val fetchUnit = Module(new FetchUnit()).io val fetchUnit = Module(new FetchUnit()).io
val decodeStage = Module(new DecodeStage()).io val decodeStage = Module(new DecodeStage()).io
val decodeUnit = Module(new DecodeUnit()).io val decodeUnit = Module(new DecodeUnit()).io
@ -27,17 +26,6 @@ class Core extends Module {
val writeBackStage = Module(new WriteBackStage()).io val writeBackStage = Module(new WriteBackStage()).io
val writeBackUnit = Module(new WriteBackUnit()).io val writeBackUnit = Module(new WriteBackUnit()).io
// 控制信号
ctrl.fetchUnit <> fetchUnit.ctrl
ctrl.decodeUnit <> decodeUnit.ctrl
ctrl.executeUnit <> executeUnit.ctrl
ctrl.memoryUnit <> memoryUnit.ctrl
ctrl.writeBackUnit <> writeBackUnit.ctrl
decodeStage.ctrl := ctrl.fetchUnit.ctrlSignal
executeStage.ctrl := ctrl.decodeUnit.ctrlSignal
memoryStage.ctrl := ctrl.executeUnit.ctrlSignal
writeBackStage.ctrl := ctrl.memoryUnit.ctrlSignal
// 取指单元 // 取指单元
fetchUnit.instSram <> io.instSram fetchUnit.instSram <> io.instSram
fetchUnit.decodeStage <> decodeStage.fetchUnit fetchUnit.decodeStage <> decodeStage.fetchUnit
@ -53,7 +41,7 @@ class Core extends Module {
executeUnit.dataSram <> io.dataSram executeUnit.dataSram <> io.dataSram
// 执行单元 // 执行单元
executeUnit.memoryStage <> memoryStage.executeUnit executeUnit.memoryStage <> memoryStage.executeUnit
executeUnit.fetchUnit <> fetchUnit.executeUnit
// 访存级缓存 // 访存级缓存
memoryStage.memoryUnit <> memoryUnit.memoryStage memoryStage.memoryUnit <> memoryUnit.memoryStage
// 访存单元 // 访存单元

View File

@ -1,52 +0,0 @@
package cpu.pipeline
import chisel3._
import chisel3.util._
import cpu.defines._
import cpu.defines.Const._
import cpu.CpuConfig
class Ctrl extends Module {
val io = IO(new Bundle {
val fetchUnit = Flipped(new FetchUnitCtrl())
val decodeUnit = Flipped(new DecodeUnitCtrl())
val executeUnit = Flipped(new ExecuteCtrl())
val memoryUnit = Flipped(new MemoryCtrl())
val writeBackUnit = Flipped(new WriteBackCtrl())
})
// 数据冲突的条件是
// 1. 对应单元的指令有效
// 2. 对应单元的指令写寄存器
// 3. 对应单元的指令写寄存器地址与当前单元的指令读寄存器地址冲突
val exe_conflict = io.executeUnit.info.valid &&
io.executeUnit.info.reg_wen &&
io.executeUnit.info.reg_waddr.orR &&
(io.decodeUnit.info.src1_ren && io.decodeUnit.info.src1_raddr === io.executeUnit.info.reg_waddr ||
io.decodeUnit.info.src2_ren && io.decodeUnit.info.src2_raddr === io.executeUnit.info.reg_waddr)
val mem_conflict = io.memoryUnit.info.valid &&
io.memoryUnit.info.reg_wen &&
io.memoryUnit.info.reg_waddr.orR &&
(io.decodeUnit.info.src1_ren && io.decodeUnit.info.src1_raddr === io.memoryUnit.info.reg_waddr ||
io.decodeUnit.info.src2_ren && io.decodeUnit.info.src2_raddr === io.memoryUnit.info.reg_waddr)
val wb_conflict = io.writeBackUnit.info.valid &&
io.writeBackUnit.info.reg_wen &&
io.writeBackUnit.info.reg_waddr.orR &&
(io.decodeUnit.info.src1_ren && io.decodeUnit.info.src1_raddr === io.writeBackUnit.info.reg_waddr ||
io.decodeUnit.info.src2_ren && io.decodeUnit.info.src2_raddr === io.writeBackUnit.info.reg_waddr)
io.fetchUnit.ctrlSignal.allow_to_go := !(exe_conflict || mem_conflict || wb_conflict)
io.decodeUnit.ctrlSignal.allow_to_go := !(exe_conflict || mem_conflict || wb_conflict)
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.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 := false.B
io.memoryUnit.ctrlSignal.do_flush := false.B
io.writeBackUnit.ctrlSignal.do_flush := false.B
io.fetchUnit.target := io.executeUnit.target
}

View File

@ -40,42 +40,6 @@ class SrcReadSignal extends Bundle {
val raddr = UInt(REG_ADDR_WID.W) val raddr = UInt(REG_ADDR_WID.W)
} }
class CtrlSignal extends Bundle {
val allow_to_go = Bool()
val do_flush = Bool()
}
class FetchUnitCtrl extends Bundle {
val target = Input(UInt(XLEN.W))
val ctrlSignal = Input(new CtrlSignal())
}
class DecodeUnitCtrl extends Bundle {
val info = Output(new Info())
val ctrlSignal = Input(new CtrlSignal())
}
class ExecuteCtrl extends Bundle {
val info = Output(new Info())
val flush = Output(Bool())
val target = Output(UInt(XLEN.W))
val ctrlSignal = Input(new CtrlSignal())
}
class MemoryCtrl extends Bundle {
val info = Output(new Info())
val ctrlSignal = Input(new CtrlSignal())
}
class WriteBackCtrl extends Bundle {
val info = Output(new Info())
val ctrlSignal = Input(new CtrlSignal())
}
class InstSram extends Bundle { class InstSram extends Bundle {
val en = Output(Bool()) val en = Output(Bool())
val addr = Output(UInt(SRAM_ADDR_WID.W)) val addr = Output(UInt(SRAM_ADDR_WID.W))

View File

@ -18,18 +18,13 @@ class FetchUnitDecodeUnit extends Bundle {
class DecodeStage extends Module { class DecodeStage extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val ctrl = Input(new CtrlSignal())
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.do_flush) {
data := 0.U.asTypeOf(new IfIdData())
}.elsewhen(io.ctrl.allow_to_go) {
data := io.fetchUnit.data data := io.fetchUnit.data
}
io.decodeUnit.data := data io.decodeUnit.data := data
} }

View File

@ -7,7 +7,6 @@ import cpu.defines.Const._
class DecodeUnit extends Module { class DecodeUnit extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val ctrl = new DecodeUnitCtrl()
// 输入 // 输入
val decodeStage = Flipped(new FetchUnitDecodeUnit()) val decodeStage = Flipped(new FetchUnitDecodeUnit())
val regfile = new Src12Read() val regfile = new Src12Read()
@ -27,8 +26,6 @@ class DecodeUnit extends Module {
io.regfile.src1.raddr := info.src1_raddr io.regfile.src1.raddr := info.src1_raddr
io.regfile.src2.raddr := info.src2_raddr io.regfile.src2.raddr := info.src2_raddr
io.ctrl.info := info
io.executeStage.data.pc := pc io.executeStage.data.pc := pc
io.executeStage.data.info := info io.executeStage.data.info := info
io.executeStage.data.src_info.src1_data := MuxCase( io.executeStage.data.src_info.src1_data := MuxCase(

View File

@ -18,18 +18,13 @@ class DecodeUnitExecuteUnit extends Bundle {
class ExecuteStage extends Module { class ExecuteStage extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val ctrl = Input(new CtrlSignal())
val decodeUnit = Input(new DecodeUnitExecuteUnit()) val decodeUnit = Input(new DecodeUnitExecuteUnit())
val executeUnit = Output(new DecodeUnitExecuteUnit()) val executeUnit = Output(new DecodeUnitExecuteUnit())
}) })
val data = RegInit(0.U.asTypeOf(new IdExeData())) val data = RegInit(0.U.asTypeOf(new IdExeData()))
when(io.ctrl.do_flush) {
data := 0.U.asTypeOf(new IdExeData())
}.elsewhen(io.ctrl.allow_to_go) {
data := io.decodeUnit.data data := io.decodeUnit.data
}
io.executeUnit.data := data io.executeUnit.data := data
} }

View File

@ -7,18 +7,21 @@ import cpu.defines._
import cpu.defines.Const._ import cpu.defines.Const._
import chisel3.util.experimental.BoringUtils import chisel3.util.experimental.BoringUtils
class BranchSignal extends Bundle {
val branch = Bool()
val target = UInt(XLEN.W)
}
class ExecuteUnit extends Module { class ExecuteUnit extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val ctrl = new ExecuteCtrl() val fetchUnit = Output(new BranchSignal())
val executeStage = Input(new DecodeUnitExecuteUnit()) val executeStage = Input(new DecodeUnitExecuteUnit())
val memoryStage = Output(new ExecuteUnitMemoryUnit()) val memoryStage = Output(new ExecuteUnitMemoryUnit())
val dataSram = new DataSram() val dataSram = new DataSram()
}) })
val allow_to_go = io.ctrl.ctrlSignal.allow_to_go
BoringUtils.addSource(allow_to_go, "exe_allow_to_go")
val valid = io.executeStage.data.info.valid && io.ctrl.ctrlSignal.allow_to_go val valid = io.executeStage.data.info.valid
val fusel = io.executeStage.data.info.fusel val fusel = io.executeStage.data.info.fusel
val fu = Module(new Fu()).io val fu = Module(new Fu()).io
@ -28,9 +31,8 @@ class ExecuteUnit extends Module {
io.dataSram <> fu.dataSram io.dataSram <> fu.dataSram
io.ctrl.flush := valid && fu.ctrl.flush io.fetchUnit.branch := valid && fu.ctrl.flush
io.ctrl.target := fu.ctrl.target io.fetchUnit.target := fu.ctrl.target
io.ctrl.info := io.executeStage.data.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

View File

@ -14,9 +14,6 @@ class Lsu extends Module {
val dataSram = new DataSram() val dataSram = new DataSram()
}) })
val allow_to_go = Wire(Bool())
BoringUtils.addSink(allow_to_go, "exe_allow_to_go")
def genWmask(addr: UInt, sizeEncode: UInt): UInt = { def genWmask(addr: UInt, sizeEncode: UInt): UInt = {
LookupTree( LookupTree(
sizeEncode, sizeEncode,
@ -61,7 +58,7 @@ class Lsu extends Module {
) )
} }
val valid = io.info.valid && io.info.fusel === FuType.lsu && allow_to_go // && 无异常 val valid = io.info.valid && io.info.fusel === FuType.lsu
val op = io.info.op val op = io.info.op
val is_load = valid && LSUOpType.isLoad(op) val is_load = valid && LSUOpType.isLoad(op)
val is_store = valid && LSUOpType.isStore(op) val is_store = valid && LSUOpType.isStore(op)
@ -120,11 +117,10 @@ class Lsu extends Module {
"b11".U -> (addr(2, 0) === 0.U) //d "b11".U -> (addr(2, 0) === 0.U) //d
) )
) )
val addr_last = RegEnable(addr, allow_to_go)
io.dataSram.en := valid && addr_aligned io.dataSram.en := valid && addr_aligned
io.dataSram.wen := req_wmask & Fill(8, is_store) io.dataSram.wen := req_wmask & Fill(8, is_store)
io.dataSram.addr := Mux(!allow_to_go, addr_last, req_addr) // 在mem被阻塞时保持原先的读地址不变 io.dataSram.addr := req_addr // 在mem被阻塞时保持原先的读地址不变
io.dataSram.wdata := req_wdata io.dataSram.wdata := req_wdata
val result = Wire(UInt(XLEN.W)) val result = Wire(UInt(XLEN.W))

View File

@ -8,8 +8,8 @@ import cpu.defines._
class FetchUnit extends Module { class FetchUnit extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val ctrl = new FetchUnitCtrl()
val decodeStage = new FetchUnitDecodeUnit() val decodeStage = new FetchUnitDecodeUnit()
val executeUnit = Input(new BranchSignal())
val instSram = new InstSram() val instSram = new InstSram()
}) })
@ -31,8 +31,7 @@ class FetchUnit extends Module {
io.instSram.addr := MuxCase( io.instSram.addr := MuxCase(
pc + 4.U, pc + 4.U,
Seq( Seq(
io.ctrl.ctrlSignal.do_flush -> io.ctrl.target, io.executeUnit.branch -> io.executeUnit.target
!io.ctrl.ctrlSignal.allow_to_go -> pc
) )
) )

View File

@ -19,16 +19,13 @@ class ExecuteUnitMemoryUnit extends Bundle {
class MemoryStage extends Module { class MemoryStage extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val ctrl = Input(new CtrlSignal())
val executeUnit = Input(new ExecuteUnitMemoryUnit()) val executeUnit = Input(new ExecuteUnitMemoryUnit())
val memoryUnit = Output(new ExecuteUnitMemoryUnit()) val memoryUnit = Output(new ExecuteUnitMemoryUnit())
}) })
val data = RegInit(0.U.asTypeOf(new ExeMemData())) val data = RegInit(0.U.asTypeOf(new ExeMemData()))
when(io.ctrl.do_flush) {
data := 0.U.asTypeOf(new ExeMemData())
}.elsewhen(io.ctrl.allow_to_go) {
data := io.executeUnit.data data := io.executeUnit.data
}
io.memoryUnit.data := data io.memoryUnit.data := data
} }

View File

@ -9,7 +9,6 @@ import cpu.CpuConfig
class MemoryUnit extends Module { class MemoryUnit extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val ctrl = new MemoryCtrl()
val memoryStage = Input(new ExecuteUnitMemoryUnit()) val memoryStage = Input(new ExecuteUnitMemoryUnit())
val writeBackStage = Output(new MemoryUnitWriteBackUnit()) val writeBackStage = Output(new MemoryUnitWriteBackUnit())
}) })
@ -23,8 +22,6 @@ class MemoryUnit extends Module {
BoringUtils.addSource(op, "mem_lsu_op") BoringUtils.addSource(op, "mem_lsu_op")
BoringUtils.addSource(addr, "mem_lsu_addr") BoringUtils.addSource(addr, "mem_lsu_addr")
io.ctrl.info := io.memoryStage.data.info
io.writeBackStage.data.pc := io.memoryStage.data.pc io.writeBackStage.data.pc := io.memoryStage.data.pc
io.writeBackStage.data.info := io.memoryStage.data.info io.writeBackStage.data.info := io.memoryStage.data.info
io.writeBackStage.data.rd_info.wdata := io.memoryStage.data.rd_info.wdata io.writeBackStage.data.rd_info.wdata := io.memoryStage.data.rd_info.wdata

View File

@ -17,16 +17,12 @@ class MemoryUnitWriteBackUnit extends Bundle {
} }
class WriteBackStage extends Module { class WriteBackStage extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val ctrl = Input(new CtrlSignal())
val memoryUnit = Input(new MemoryUnitWriteBackUnit()) val memoryUnit = Input(new MemoryUnitWriteBackUnit())
val writeBackUnit = Output(new MemoryUnitWriteBackUnit()) val writeBackUnit = Output(new MemoryUnitWriteBackUnit())
}) })
val data = RegInit(0.U.asTypeOf(new MemWbData())) val data = RegInit(0.U.asTypeOf(new MemWbData()))
when(io.ctrl.do_flush) {
data := 0.U.asTypeOf(new MemWbData())
}.elsewhen(io.ctrl.allow_to_go) {
data := io.memoryUnit.data data := io.memoryUnit.data
}
io.writeBackUnit.data := data io.writeBackUnit.data := data
} }

View File

@ -8,7 +8,6 @@ import cpu.CpuConfig
class WriteBackUnit extends Module { class WriteBackUnit extends Module {
val io = IO(new Bundle { val io = IO(new Bundle {
val ctrl = new WriteBackCtrl()
val writeBackStage = Input(new MemoryUnitWriteBackUnit()) val writeBackStage = Input(new MemoryUnitWriteBackUnit())
val regfile = Output(new RegWrite()) val regfile = Output(new RegWrite())
val debug = new DEBUG() val debug = new DEBUG()
@ -16,16 +15,13 @@ class WriteBackUnit extends Module {
io.regfile.wen := io.regfile.wen :=
io.writeBackStage.data.info.valid && io.writeBackStage.data.info.valid &&
io.ctrl.ctrlSignal.allow_to_go &&
io.writeBackStage.data.info.reg_wen io.writeBackStage.data.info.reg_wen
io.regfile.waddr := io.writeBackStage.data.info.reg_waddr io.regfile.waddr := io.writeBackStage.data.info.reg_waddr
io.regfile.wdata := io.writeBackStage.data.rd_info.wdata(io.writeBackStage.data.info.fusel) io.regfile.wdata := io.writeBackStage.data.rd_info.wdata(io.writeBackStage.data.info.fusel)
io.ctrl.info := io.writeBackStage.data.info
io.debug.pc := io.writeBackStage.data.pc io.debug.pc := io.writeBackStage.data.pc
io.debug.commit := io.writeBackStage.data.info.valid && io.ctrl.ctrlSignal.allow_to_go io.debug.commit := io.writeBackStage.data.info.valid
io.debug.rf_wnum := io.regfile.waddr io.debug.rf_wnum := io.regfile.waddr
io.debug.rf_wdata := io.regfile.wdata io.debug.rf_wdata := io.regfile.wdata
} }