完成气泡流水线大致代码框架

This commit is contained in:
Liphen 2024-05-27 09:54:58 +08:00
parent 3b2ba2e43c
commit d2bc851cf7
11 changed files with 44 additions and 137 deletions

View File

@ -46,9 +46,6 @@ class Core extends Module {
decodeStage.decodeUnit <> decodeUnit.decodeStage
// 译码单元
decodeUnit.regfile <> regfile.read
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
// 执行级缓存

View File

@ -15,12 +15,28 @@ class Ctrl extends Module {
val writeBackUnit = Flipped(new WriteBackCtrl())
})
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)
// 数据冲突的条件是
// 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 := !lw_stall
io.decodeUnit.ctrlSignal.allow_to_go := !lw_stall
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

View File

@ -23,7 +23,6 @@ class RdInfo extends Bundle {
class Info extends Bundle {
val valid = Bool()
val inst_legal = Bool()
val src1_ren = Bool()
val src1_raddr = UInt(REG_ADDR_WID.W)
val src2_ren = Bool()
@ -36,11 +35,6 @@ class Info extends Bundle {
val inst = UInt(XLEN.W)
}
class MemRead extends Bundle {
val is_load = Bool()
val reg_waddr = UInt(REG_ADDR_WID.W)
}
class SrcReadSignal extends Bundle {
val ren = Bool()
val raddr = UInt(REG_ADDR_WID.W)
@ -57,16 +51,13 @@ class FetchUnitCtrl extends Bundle {
}
class DecodeUnitCtrl extends Bundle {
val src_info = Output(new Bundle {
val src1 = new SrcReadSignal()
val src2 = new SrcReadSignal()
})
val info = Output(new Info())
val ctrlSignal = Input(new CtrlSignal())
}
class ExecuteCtrl extends Bundle {
val data = Output(new MemRead())
val info = Output(new Info())
val flush = Output(Bool())
val target = Output(UInt(XLEN.W))
@ -74,10 +65,14 @@ class ExecuteCtrl extends Bundle {
}
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())
}

View File

@ -77,7 +77,7 @@ object BRUOpType {
}
// load store unit
object LSUOpType { //TODO: refactor LSU fuop
object LSUOpType {
def lb = "b0000".U
def lh = "b0001".U
def lw = "b0010".U
@ -115,4 +115,3 @@ object MDUOpType {
def isDivSign(op: UInt) = isDiv(op) && !op(0)
def isWordOp(op: UInt) = op(3)
}

View File

@ -42,17 +42,11 @@ class ARegFile extends Module {
io.read.src1.rdata := 0.U
}.otherwise {
io.read.src1.rdata := regs(io.read.src1.raddr)
when(io.write.wen && io.read.src1.raddr === io.write.waddr) {
io.read.src1.rdata := io.write.wdata
}
}
// src2
when(io.read.src2.raddr === 0.U) {
io.read.src2.rdata := 0.U
}.otherwise {
io.read.src2.rdata := regs(io.read.src2.raddr)
when(io.write.wen && io.read.src2.raddr === io.write.waddr) {
io.read.src2.rdata := io.write.wdata
}
}
}

View File

@ -5,19 +5,12 @@ import chisel3.util._
import cpu.defines._
import cpu.defines.Const._
class DataForwardToDecodeUnit extends Bundle {
val exe = new RegWrite()
val is_load = Bool()
val mem = new RegWrite()
}
class DecodeUnit extends Module {
val io = IO(new Bundle {
val ctrl = new DecodeUnitCtrl()
val ctrl = new DecodeUnitCtrl()
// 输入
val decodeStage = Flipped(new FetchUnitDecodeUnit())
val regfile = new Src12Read()
val forward = Input(new DataForwardToDecodeUnit())
// 输出
val executeStage = Output(new DecodeUnitExecuteUnit())
})
@ -25,37 +18,29 @@ class DecodeUnit extends Module {
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.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.info := info
io.executeStage.data.pc := pc
io.executeStage.data.info := info
io.executeStage.data.src_info.src1_data := MuxCase(
SignedExtend(pc, XLEN),
Seq(
info.src1_ren -> forwardCtrl.out.data.src1.rdata,
info.src1_ren -> io.regfile.src1.rdata,
(info.inst(6, 0) === "b0110111".U) -> 0.U
)
)
io.executeStage.data.src_info.src2_data := Mux(
info.src2_ren,
forwardCtrl.out.data.src2.rdata,
io.regfile.src2.rdata,
info.imm
)
}

View File

@ -38,7 +38,6 @@ class Decoder extends Module with HasInstrType {
io.out.info.valid := false.B
io.out.info.inst := inst
io.out.info.inst_legal := instrType =/= InstrN
io.out.info.src1_ren := src1Type === SrcType.reg
io.out.info.src1_raddr := Mux(io.out.info.src1_ren, rs, 0.U)
io.out.info.src2_ren := src2Type === SrcType.reg

View File

@ -1,62 +0,0 @@
package cpu.pipeline
import chisel3._
import chisel3.util._
import cpu.defines._
import cpu.defines.Const._
import cpu.CpuConfig
class ForwardCtrl extends Module {
val io = IO(new Bundle {
val in = Input(new Bundle {
val forward = new DataForwardToDecodeUnit()
val regfile = new Src12Read()
})
val out = Output(new Bundle {
val data = new Src12Read()
})
})
// wb优先度最低
io.out.data.src1.raddr := DontCare
io.out.data.src2.raddr := DontCare
io.out.data.src1.rdata := io.in.regfile.src1.rdata
io.out.data.src2.rdata := io.in.regfile.src2.rdata
// mem优先度中
when(
io.in.forward.mem.wen &&
io.in.forward.mem.waddr === io.in.regfile.src1.raddr
) {
io.out.data.src1.rdata := io.in.forward.mem.wdata
}
when(
io.in.forward.mem.wen &&
io.in.forward.mem.waddr === io.in.regfile.src2.raddr
) {
io.out.data.src2.rdata := io.in.forward.mem.wdata
}
// exe优先度高
when(
io.in.forward.exe.wen && !io.in.forward.is_load &&
io.in.forward.exe.waddr === io.in.regfile.src1.raddr
) {
io.out.data.src1.rdata := io.in.forward.exe.wdata
}
when(
io.in.forward.exe.wen && !io.in.forward.is_load &&
io.in.forward.exe.waddr === io.in.regfile.src2.raddr
) {
io.out.data.src2.rdata := io.in.forward.exe.wdata
}
// 读零寄存器时数据为0
when(io.in.regfile.src1.raddr === 0.U) {
io.out.data.src1.rdata := 0.U
}
when(io.in.regfile.src2.raddr === 0.U) {
io.out.data.src2.rdata := 0.U
}
}

View File

@ -11,16 +11,8 @@ class ExecuteUnit extends Module {
val io = IO(new Bundle {
val ctrl = new ExecuteCtrl()
val executeStage = Input(new DecodeUnitExecuteUnit())
val decodeUnit = new Bundle {
val forward = Output(
new Bundle {
val exe = new RegWrite()
val is_load = Bool()
}
)
}
val memoryStage = Output(new ExecuteUnitMemoryUnit())
val dataSram = new DataSram()
val memoryStage = Output(new ExecuteUnitMemoryUnit())
val dataSram = new DataSram()
})
val allow_to_go = io.ctrl.ctrlSignal.allow_to_go
@ -36,19 +28,12 @@ class ExecuteUnit extends Module {
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
io.ctrl.flush := valid && fu.ctrl.flush
io.ctrl.target := fu.ctrl.target
io.ctrl.info := io.executeStage.data.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.decodeUnit.forward.exe.wen := io.memoryStage.data.info.reg_wen
io.decodeUnit.forward.exe.waddr := io.memoryStage.data.info.reg_waddr
io.decodeUnit.forward.exe.wdata := io.memoryStage.data.rd_info.wdata(io.memoryStage.data.info.fusel)
io.decodeUnit.forward.is_load := io.ctrl.data.is_load
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
}

View File

@ -11,7 +11,6 @@ class MemoryUnit extends Module {
val io = IO(new Bundle {
val ctrl = new MemoryCtrl()
val memoryStage = Input(new ExecuteUnitMemoryUnit())
val decodeUnit = Output(new RegWrite())
val writeBackStage = Output(new MemoryUnitWriteBackUnit())
})
@ -24,9 +23,7 @@ class MemoryUnit extends Module {
BoringUtils.addSource(op, "mem_lsu_op")
BoringUtils.addSource(addr, "mem_lsu_addr")
io.decodeUnit.wen := io.writeBackStage.data.info.reg_wen
io.decodeUnit.waddr := io.writeBackStage.data.info.reg_waddr
io.decodeUnit.wdata := io.writeBackStage.data.rd_info.wdata(io.writeBackStage.data.info.fusel)
io.ctrl.info := io.memoryStage.data.info
io.writeBackStage.data.pc := io.memoryStage.data.pc
io.writeBackStage.data.info := io.memoryStage.data.info

View File

@ -22,6 +22,8 @@ class WriteBackUnit extends Module {
io.regfile.waddr := io.writeBackStage.data.info.reg_waddr
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.commit := io.writeBackStage.data.info.valid && io.ctrl.ctrlSignal.allow_to_go
io.debug.rf_wnum := io.regfile.waddr