完成气泡流水线大致代码框架
This commit is contained in:
parent
3b2ba2e43c
commit
d2bc851cf7
|
@ -46,9 +46,6 @@ class Core extends Module {
|
||||||
decodeStage.decodeUnit <> decodeUnit.decodeStage
|
decodeStage.decodeUnit <> decodeUnit.decodeStage
|
||||||
// 译码单元
|
// 译码单元
|
||||||
decodeUnit.regfile <> regfile.read
|
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
|
decodeUnit.executeStage <> executeStage.decodeUnit
|
||||||
|
|
||||||
// 执行级缓存
|
// 执行级缓存
|
||||||
|
|
|
@ -15,12 +15,28 @@ class Ctrl extends Module {
|
||||||
val writeBackUnit = Flipped(new WriteBackCtrl())
|
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 ||
|
// 1. 对应单元的指令有效
|
||||||
io.decodeUnit.src_info.src2.ren && io.decodeUnit.src_info.src2.raddr === io.executeUnit.data.reg_waddr)
|
// 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.fetchUnit.ctrlSignal.allow_to_go := !(exe_conflict || mem_conflict || wb_conflict)
|
||||||
io.decodeUnit.ctrlSignal.allow_to_go := !lw_stall
|
io.decodeUnit.ctrlSignal.allow_to_go := !(exe_conflict || mem_conflict || wb_conflict)
|
||||||
io.executeUnit.ctrlSignal.allow_to_go := true.B
|
io.executeUnit.ctrlSignal.allow_to_go := true.B
|
||||||
io.memoryUnit.ctrlSignal.allow_to_go := true.B
|
io.memoryUnit.ctrlSignal.allow_to_go := true.B
|
||||||
io.writeBackUnit.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 {
|
class Info extends Bundle {
|
||||||
val valid = Bool()
|
val valid = Bool()
|
||||||
val inst_legal = Bool()
|
|
||||||
val src1_ren = Bool()
|
val src1_ren = Bool()
|
||||||
val src1_raddr = UInt(REG_ADDR_WID.W)
|
val src1_raddr = UInt(REG_ADDR_WID.W)
|
||||||
val src2_ren = Bool()
|
val src2_ren = Bool()
|
||||||
|
@ -36,11 +35,6 @@ class Info extends Bundle {
|
||||||
val inst = UInt(XLEN.W)
|
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 {
|
class SrcReadSignal extends Bundle {
|
||||||
val ren = Bool()
|
val ren = Bool()
|
||||||
val raddr = UInt(REG_ADDR_WID.W)
|
val raddr = UInt(REG_ADDR_WID.W)
|
||||||
|
@ -57,16 +51,13 @@ class FetchUnitCtrl extends Bundle {
|
||||||
}
|
}
|
||||||
|
|
||||||
class DecodeUnitCtrl extends Bundle {
|
class DecodeUnitCtrl extends Bundle {
|
||||||
val src_info = Output(new Bundle {
|
val info = Output(new Info())
|
||||||
val src1 = new SrcReadSignal()
|
|
||||||
val src2 = new SrcReadSignal()
|
|
||||||
})
|
|
||||||
|
|
||||||
val ctrlSignal = Input(new CtrlSignal())
|
val ctrlSignal = Input(new CtrlSignal())
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExecuteCtrl extends Bundle {
|
class ExecuteCtrl extends Bundle {
|
||||||
val data = Output(new MemRead())
|
val info = Output(new Info())
|
||||||
val flush = Output(Bool())
|
val flush = Output(Bool())
|
||||||
val target = Output(UInt(XLEN.W))
|
val target = Output(UInt(XLEN.W))
|
||||||
|
|
||||||
|
@ -74,10 +65,14 @@ class ExecuteCtrl extends Bundle {
|
||||||
}
|
}
|
||||||
|
|
||||||
class MemoryCtrl extends Bundle {
|
class MemoryCtrl extends Bundle {
|
||||||
|
val info = Output(new Info())
|
||||||
|
|
||||||
val ctrlSignal = Input(new CtrlSignal())
|
val ctrlSignal = Input(new CtrlSignal())
|
||||||
}
|
}
|
||||||
|
|
||||||
class WriteBackCtrl extends Bundle {
|
class WriteBackCtrl extends Bundle {
|
||||||
|
val info = Output(new Info())
|
||||||
|
|
||||||
val ctrlSignal = Input(new CtrlSignal())
|
val ctrlSignal = Input(new CtrlSignal())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ object BRUOpType {
|
||||||
}
|
}
|
||||||
|
|
||||||
// load store unit
|
// load store unit
|
||||||
object LSUOpType { //TODO: refactor LSU fuop
|
object LSUOpType {
|
||||||
def lb = "b0000".U
|
def lb = "b0000".U
|
||||||
def lh = "b0001".U
|
def lh = "b0001".U
|
||||||
def lw = "b0010".U
|
def lw = "b0010".U
|
||||||
|
@ -115,4 +115,3 @@ object MDUOpType {
|
||||||
def isDivSign(op: UInt) = isDiv(op) && !op(0)
|
def isDivSign(op: UInt) = isDiv(op) && !op(0)
|
||||||
def isWordOp(op: UInt) = op(3)
|
def isWordOp(op: UInt) = op(3)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,17 +42,11 @@ class ARegFile extends Module {
|
||||||
io.read.src1.rdata := 0.U
|
io.read.src1.rdata := 0.U
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
io.read.src1.rdata := regs(io.read.src1.raddr)
|
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
|
// src2
|
||||||
when(io.read.src2.raddr === 0.U) {
|
when(io.read.src2.raddr === 0.U) {
|
||||||
io.read.src2.rdata := 0.U
|
io.read.src2.rdata := 0.U
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
io.read.src2.rdata := regs(io.read.src2.raddr)
|
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._
|
||||||
import cpu.defines.Const._
|
import cpu.defines.Const._
|
||||||
|
|
||||||
class DataForwardToDecodeUnit extends Bundle {
|
|
||||||
val exe = new RegWrite()
|
|
||||||
val is_load = Bool()
|
|
||||||
val mem = new RegWrite()
|
|
||||||
}
|
|
||||||
|
|
||||||
class DecodeUnit extends Module {
|
class DecodeUnit extends Module {
|
||||||
val io = IO(new Bundle {
|
val io = IO(new Bundle {
|
||||||
val ctrl = new DecodeUnitCtrl()
|
val ctrl = new DecodeUnitCtrl()
|
||||||
// 输入
|
// 输入
|
||||||
val decodeStage = Flipped(new FetchUnitDecodeUnit())
|
val decodeStage = Flipped(new FetchUnitDecodeUnit())
|
||||||
val regfile = new Src12Read()
|
val regfile = new Src12Read()
|
||||||
val forward = Input(new DataForwardToDecodeUnit())
|
|
||||||
// 输出
|
// 输出
|
||||||
val executeStage = Output(new DecodeUnitExecuteUnit())
|
val executeStage = Output(new DecodeUnitExecuteUnit())
|
||||||
})
|
})
|
||||||
|
@ -25,37 +18,29 @@ class DecodeUnit extends Module {
|
||||||
val decoder = Module(new Decoder()).io
|
val decoder = Module(new Decoder()).io
|
||||||
decoder.in.inst := io.decodeStage.data.inst
|
decoder.in.inst := io.decodeStage.data.inst
|
||||||
|
|
||||||
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.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.regfile := io.regfile
|
|
||||||
|
|
||||||
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.src_info.src1.ren := info.src1_ren
|
io.ctrl.info := info
|
||||||
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.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(
|
||||||
SignedExtend(pc, XLEN),
|
SignedExtend(pc, XLEN),
|
||||||
Seq(
|
Seq(
|
||||||
info.src1_ren -> forwardCtrl.out.data.src1.rdata,
|
info.src1_ren -> io.regfile.src1.rdata,
|
||||||
(info.inst(6, 0) === "b0110111".U) -> 0.U
|
(info.inst(6, 0) === "b0110111".U) -> 0.U
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
io.executeStage.data.src_info.src2_data := Mux(
|
io.executeStage.data.src_info.src2_data := Mux(
|
||||||
info.src2_ren,
|
info.src2_ren,
|
||||||
forwardCtrl.out.data.src2.rdata,
|
io.regfile.src2.rdata,
|
||||||
info.imm
|
info.imm
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,6 @@ class Decoder extends Module with HasInstrType {
|
||||||
|
|
||||||
io.out.info.valid := false.B
|
io.out.info.valid := false.B
|
||||||
io.out.info.inst := inst
|
io.out.info.inst := inst
|
||||||
io.out.info.inst_legal := instrType =/= InstrN
|
|
||||||
io.out.info.src1_ren := src1Type === SrcType.reg
|
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.src1_raddr := Mux(io.out.info.src1_ren, rs, 0.U)
|
||||||
io.out.info.src2_ren := src2Type === SrcType.reg
|
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 io = IO(new Bundle {
|
||||||
val ctrl = new ExecuteCtrl()
|
val ctrl = new ExecuteCtrl()
|
||||||
val executeStage = Input(new DecodeUnitExecuteUnit())
|
val executeStage = Input(new DecodeUnitExecuteUnit())
|
||||||
val decodeUnit = new Bundle {
|
val memoryStage = Output(new ExecuteUnitMemoryUnit())
|
||||||
val forward = Output(
|
val dataSram = new DataSram()
|
||||||
new Bundle {
|
|
||||||
val exe = new RegWrite()
|
|
||||||
val is_load = Bool()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
val memoryStage = Output(new ExecuteUnitMemoryUnit())
|
|
||||||
val dataSram = new DataSram()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
val allow_to_go = io.ctrl.ctrlSignal.allow_to_go
|
val allow_to_go = io.ctrl.ctrlSignal.allow_to_go
|
||||||
|
@ -36,19 +28,12 @@ class ExecuteUnit extends Module {
|
||||||
|
|
||||||
io.dataSram <> fu.dataSram
|
io.dataSram <> fu.dataSram
|
||||||
|
|
||||||
io.ctrl.data.is_load := fusel === FuType.lsu && LSUOpType.isLoad(io.executeStage.data.info.op)
|
io.ctrl.flush := valid && fu.ctrl.flush
|
||||||
io.ctrl.data.reg_waddr := io.executeStage.data.info.reg_waddr
|
io.ctrl.target := fu.ctrl.target
|
||||||
io.ctrl.flush := valid && fu.ctrl.flush
|
io.ctrl.info := io.executeStage.data.info
|
||||||
io.ctrl.target := fu.ctrl.target
|
|
||||||
|
|
||||||
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.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
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ 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 decodeUnit = Output(new RegWrite())
|
|
||||||
val writeBackStage = Output(new MemoryUnitWriteBackUnit())
|
val writeBackStage = Output(new MemoryUnitWriteBackUnit())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -24,9 +23,7 @@ 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.decodeUnit.wen := io.writeBackStage.data.info.reg_wen
|
io.ctrl.info := io.memoryStage.data.info
|
||||||
io.decodeUnit.waddr := io.writeBackStage.data.info.reg_waddr
|
|
||||||
io.decodeUnit.wdata := io.writeBackStage.data.rd_info.wdata(io.writeBackStage.data.info.fusel)
|
|
||||||
|
|
||||||
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
|
||||||
|
|
|
@ -22,6 +22,8 @@ class WriteBackUnit extends Module {
|
||||||
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.ctrl.ctrlSignal.allow_to_go
|
||||||
io.debug.rf_wnum := io.regfile.waddr
|
io.debug.rf_wnum := io.regfile.waddr
|
||||||
|
|
Loading…
Reference in New Issue