完成气泡流水线大致代码框架
This commit is contained in:
parent
3b2ba2e43c
commit
d2bc851cf7
|
@ -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
|
||||
|
||||
// 执行级缓存
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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())
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue