成功生成verilog
This commit is contained in:
parent
6f02672358
commit
f7ee8c4c87
|
@ -44,7 +44,6 @@ class Core(implicit val config: CpuConfig) extends Module {
|
||||||
ctrl.memoryUnit <> memoryUnit.ctrl
|
ctrl.memoryUnit <> memoryUnit.ctrl
|
||||||
ctrl.writeBackUnit <> writeBackUnit.ctrl
|
ctrl.writeBackUnit <> writeBackUnit.ctrl
|
||||||
ctrl.cacheCtrl.iCache_stall := io.inst.icache_stall
|
ctrl.cacheCtrl.iCache_stall := io.inst.icache_stall
|
||||||
ctrl.cacheCtrl.dCache_stall := io.data.dcache_stall
|
|
||||||
|
|
||||||
fetchUnit.memory <> memoryUnit.fetchUnit
|
fetchUnit.memory <> memoryUnit.fetchUnit
|
||||||
fetchUnit.execute <> executeUnit.fetchUnit
|
fetchUnit.execute <> executeUnit.fetchUnit
|
||||||
|
@ -120,6 +119,7 @@ class Core(implicit val config: CpuConfig) extends Module {
|
||||||
|
|
||||||
memoryUnit.dataMemory.in.rdata := io.data.rdata
|
memoryUnit.dataMemory.in.rdata := io.data.rdata
|
||||||
memoryUnit.dataMemory.in.acc_err := io.data.acc_err
|
memoryUnit.dataMemory.in.acc_err := io.data.acc_err
|
||||||
|
memoryUnit.dataMemory.in.ready := !io.data.dcache_stall
|
||||||
io.data.en := memoryUnit.dataMemory.out.en
|
io.data.en := memoryUnit.dataMemory.out.en
|
||||||
io.data.size := memoryUnit.dataMemory.out.rlen
|
io.data.size := memoryUnit.dataMemory.out.rlen
|
||||||
io.data.wen := memoryUnit.dataMemory.out.wen
|
io.data.wen := memoryUnit.dataMemory.out.wen
|
||||||
|
|
|
@ -17,15 +17,16 @@ class Ctrl(implicit val config: CpuConfig) extends Module {
|
||||||
val writeBackUnit = Flipped(new WriteBackCtrl())
|
val writeBackUnit = Flipped(new WriteBackCtrl())
|
||||||
})
|
})
|
||||||
|
|
||||||
val inst0_lw_stall = (io.executeUnit.inst(0).mem_wreg) &&
|
val inst0_lw_stall = (io.executeUnit.inst(0).mem_wreg) && io.executeUnit.inst(0).reg_waddr.orR &&
|
||||||
(io.decoderUnit.inst0.src1.ren && io.decoderUnit.inst0.src1.raddr === io.executeUnit.inst(0).reg_waddr ||
|
(io.decoderUnit.inst0.src1.ren && io.decoderUnit.inst0.src1.raddr === io.executeUnit.inst(0).reg_waddr ||
|
||||||
io.decoderUnit.inst0.src2.ren && io.decoderUnit.inst0.src2.raddr === io.executeUnit.inst(0).reg_waddr)
|
io.decoderUnit.inst0.src2.ren && io.decoderUnit.inst0.src2.raddr === io.executeUnit.inst(0).reg_waddr)
|
||||||
val inst1_lw_stall = (io.executeUnit.inst(1).mem_wreg) &&
|
val inst1_lw_stall = (io.executeUnit.inst(1).mem_wreg) && io.executeUnit.inst(1).reg_waddr.orR &&
|
||||||
(io.decoderUnit.inst0.src1.ren && io.decoderUnit.inst0.src1.raddr === io.executeUnit.inst(1).reg_waddr ||
|
(io.decoderUnit.inst0.src1.ren && io.decoderUnit.inst0.src1.raddr === io.executeUnit.inst(1).reg_waddr ||
|
||||||
io.decoderUnit.inst0.src2.ren && io.decoderUnit.inst0.src2.raddr === io.executeUnit.inst(1).reg_waddr)
|
io.decoderUnit.inst0.src2.ren && io.decoderUnit.inst0.src2.raddr === io.executeUnit.inst(1).reg_waddr)
|
||||||
val lw_stall = inst0_lw_stall || inst1_lw_stall
|
val lw_stall = inst0_lw_stall || inst1_lw_stall
|
||||||
// TODO: 这里的stall信号可能不对
|
// TODO: 这里的stall信号可能不对
|
||||||
val longest_stall = io.executeUnit.fu_stall || io.cacheCtrl.iCache_stall || io.cacheCtrl.dCache_stall
|
val longest_stall =
|
||||||
|
io.executeUnit.fu_stall || io.cacheCtrl.iCache_stall || io.memoryUnit.mem_stall
|
||||||
|
|
||||||
io.fetchUnit.allow_to_go := !io.cacheCtrl.iCache_stall
|
io.fetchUnit.allow_to_go := !io.cacheCtrl.iCache_stall
|
||||||
io.decoderUnit.allow_to_go := !(lw_stall || longest_stall)
|
io.decoderUnit.allow_to_go := !(lw_stall || longest_stall)
|
||||||
|
|
|
@ -55,7 +55,6 @@ class SrcReadSignal extends Bundle {
|
||||||
|
|
||||||
class CacheCtrl extends Bundle {
|
class CacheCtrl extends Bundle {
|
||||||
val iCache_stall = Output(Bool())
|
val iCache_stall = Output(Bool())
|
||||||
val dCache_stall = Output(Bool())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class FetchUnitCtrl extends Bundle {
|
class FetchUnitCtrl extends Bundle {
|
||||||
|
@ -85,7 +84,7 @@ class ExecuteFuCtrl extends Bundle {
|
||||||
class ExecuteCtrl(implicit val config: CpuConfig) extends Bundle {
|
class ExecuteCtrl(implicit val config: CpuConfig) extends Bundle {
|
||||||
val inst = Output(Vec(config.fuNum, new MemRead()))
|
val inst = Output(Vec(config.fuNum, new MemRead()))
|
||||||
val fu_stall = Output(Bool())
|
val fu_stall = Output(Bool())
|
||||||
val flush = Output(Bool())
|
val flush = Output(Bool())
|
||||||
|
|
||||||
val allow_to_go = Input(Bool())
|
val allow_to_go = Input(Bool())
|
||||||
val do_flush = Input(Bool())
|
val do_flush = Input(Bool())
|
||||||
|
@ -94,7 +93,8 @@ class ExecuteCtrl(implicit val config: CpuConfig) extends Bundle {
|
||||||
}
|
}
|
||||||
|
|
||||||
class MemoryCtrl extends Bundle {
|
class MemoryCtrl extends Bundle {
|
||||||
val flush = Output(Bool())
|
val flush = Output(Bool())
|
||||||
|
val mem_stall = Output(Bool())
|
||||||
|
|
||||||
val allow_to_go = Input(Bool())
|
val allow_to_go = Input(Bool())
|
||||||
val do_flush = Input(Bool())
|
val do_flush = Input(Bool())
|
||||||
|
|
|
@ -17,10 +17,16 @@ class CsrMemoryUnit(implicit val config: CpuConfig) extends Bundle {
|
||||||
val info = new InstInfo()
|
val info = new InstInfo()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
val set_lr = Bool()
|
||||||
|
val set_lr_val = Bool()
|
||||||
|
val set_lr_addr = UInt(DATA_ADDR_WID.W)
|
||||||
})
|
})
|
||||||
val out = Output(new Bundle {
|
val out = Output(new Bundle {
|
||||||
val flush = Bool()
|
val flush = Bool()
|
||||||
val flush_pc = UInt(PC_WID.W)
|
val flush_pc = UInt(PC_WID.W)
|
||||||
|
|
||||||
|
val lr = Bool()
|
||||||
|
val lr_addr = UInt(DATA_ADDR_WID.W)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,20 +110,20 @@ class Csr(implicit val config: CpuConfig) extends Module with HasCSRConst {
|
||||||
val wdata = Wire(UInt(XLEN.W))
|
val wdata = Wire(UInt(XLEN.W))
|
||||||
|
|
||||||
// Atom LR/SC Control Bits
|
// Atom LR/SC Control Bits
|
||||||
val setLr = WireInit(Bool(), false.B)
|
val set_lr = WireInit(Bool(), false.B)
|
||||||
val setLrVal = WireInit(Bool(), false.B)
|
val set_lr_val = WireInit(Bool(), false.B)
|
||||||
val setLrAddr = WireInit(UInt(XLEN.W), DontCare) //TODO : need check
|
val set_lr_addr = WireInit(UInt(DATA_ADDR_WID.W), 0.U)
|
||||||
val lr = RegInit(Bool(), false.B)
|
val lr = RegInit(Bool(), false.B)
|
||||||
val lrAddr = RegInit(UInt(XLEN.W), 0.U)
|
val lr_addr = RegInit(UInt(DATA_ADDR_WID.W), 0.U)
|
||||||
BoringUtils.addSink(setLr, "set_lr")
|
set_lr := io.memoryUnit.in.set_lr
|
||||||
BoringUtils.addSink(setLrVal, "set_lr_val")
|
set_lr_val := io.memoryUnit.in.set_lr_val
|
||||||
BoringUtils.addSink(setLrAddr, "set_lr_addr")
|
set_lr_addr := io.memoryUnit.in.set_lr_addr
|
||||||
BoringUtils.addSource(lr, "lr")
|
io.memoryUnit.out.lr := lr
|
||||||
BoringUtils.addSource(lrAddr, "lr_addr")
|
io.memoryUnit.out.lr_addr := lr_addr
|
||||||
|
|
||||||
when(setLr) {
|
when(set_lr) {
|
||||||
lr := setLrVal
|
lr := set_lr_val
|
||||||
lrAddr := setLrAddr
|
lr_addr := set_lr_addr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Side Effect
|
// Side Effect
|
||||||
|
|
|
@ -113,6 +113,7 @@ class ExecuteUnit(implicit val config: CpuConfig) extends Module {
|
||||||
|
|
||||||
io.memoryStage.inst0.pc := io.executeStage.inst0.pc
|
io.memoryStage.inst0.pc := io.executeStage.inst0.pc
|
||||||
io.memoryStage.inst0.info := io.executeStage.inst0.info
|
io.memoryStage.inst0.info := io.executeStage.inst0.info
|
||||||
|
io.memoryStage.inst0.src_info := io.executeStage.inst0.src_info
|
||||||
io.memoryStage.inst0.rd_info.wdata(FuType.alu) := fu.inst(0).result.alu
|
io.memoryStage.inst0.rd_info.wdata(FuType.alu) := fu.inst(0).result.alu
|
||||||
io.memoryStage.inst0.rd_info.wdata(FuType.mdu) := fu.inst(0).result.mdu
|
io.memoryStage.inst0.rd_info.wdata(FuType.mdu) := fu.inst(0).result.mdu
|
||||||
io.memoryStage.inst0.rd_info.wdata(FuType.csr) := io.csr.out.rdata
|
io.memoryStage.inst0.rd_info.wdata(FuType.csr) := io.csr.out.rdata
|
||||||
|
@ -137,6 +138,7 @@ class ExecuteUnit(implicit val config: CpuConfig) extends Module {
|
||||||
|
|
||||||
io.memoryStage.inst1.pc := io.executeStage.inst1.pc
|
io.memoryStage.inst1.pc := io.executeStage.inst1.pc
|
||||||
io.memoryStage.inst1.info := io.executeStage.inst1.info
|
io.memoryStage.inst1.info := io.executeStage.inst1.info
|
||||||
|
io.memoryStage.inst1.src_info := io.executeStage.inst1.src_info
|
||||||
io.memoryStage.inst1.rd_info.wdata(FuType.alu) := fu.inst(1).result.alu
|
io.memoryStage.inst1.rd_info.wdata(FuType.alu) := fu.inst(1).result.alu
|
||||||
io.memoryStage.inst1.rd_info.wdata(FuType.mdu) := fu.inst(1).result.mdu
|
io.memoryStage.inst1.rd_info.wdata(FuType.mdu) := fu.inst(1).result.mdu
|
||||||
io.memoryStage.inst1.rd_info.wdata(FuType.csr) := io.csr.out.rdata
|
io.memoryStage.inst1.rd_info.wdata(FuType.csr) := io.csr.out.rdata
|
||||||
|
|
|
@ -5,10 +5,12 @@ import chisel3.util._
|
||||||
import cpu.defines._
|
import cpu.defines._
|
||||||
import cpu.defines.Const._
|
import cpu.defines.Const._
|
||||||
import cpu.CpuConfig
|
import cpu.CpuConfig
|
||||||
|
import chisel3.util.experimental.BoringUtils
|
||||||
|
|
||||||
class DataMemoryAccess_DataMemory extends Bundle {
|
class DataMemoryAccess_DataMemory extends Bundle {
|
||||||
val in = Input(new Bundle {
|
val in = Input(new Bundle {
|
||||||
val acc_err = Bool()
|
val acc_err = Bool()
|
||||||
|
val ready = Bool()
|
||||||
val rdata = UInt(DATA_WID.W)
|
val rdata = UInt(DATA_WID.W)
|
||||||
})
|
})
|
||||||
val out = Output(new Bundle {
|
val out = Output(new Bundle {
|
||||||
|
@ -21,85 +23,170 @@ class DataMemoryAccess_DataMemory extends Bundle {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DataMemoryAccess_MemoryUnit extends Bundle {
|
||||||
|
val in = Input(new Bundle {
|
||||||
|
val mem_en = Bool()
|
||||||
|
val info = new InstInfo()
|
||||||
|
val src_info = new SrcInfo()
|
||||||
|
val ex = new ExceptionInfo()
|
||||||
|
|
||||||
|
val lr = Bool()
|
||||||
|
val lr_addr = UInt(DATA_ADDR_WID.W)
|
||||||
|
})
|
||||||
|
val out = Output(new Bundle {
|
||||||
|
val ready = Bool()
|
||||||
|
val rdata = UInt(DATA_WID.W)
|
||||||
|
val ex = new ExceptionInfo()
|
||||||
|
|
||||||
|
val set_lr = Bool()
|
||||||
|
val set_lr_val = Bool()
|
||||||
|
val set_lr_addr = UInt(DATA_ADDR_WID.W)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
class DataMemoryAccess(implicit val config: CpuConfig) extends Module {
|
class DataMemoryAccess(implicit val config: CpuConfig) extends Module {
|
||||||
val io = IO(new Bundle {
|
val io = IO(new Bundle {
|
||||||
val memoryUnit = new Bundle {
|
val memoryUnit = new DataMemoryAccess_MemoryUnit()
|
||||||
val in = Input(new Bundle {
|
|
||||||
val mem_en = Bool()
|
|
||||||
val info = new InstInfo()
|
|
||||||
val mem_wdata = UInt(DATA_WID.W)
|
|
||||||
val mem_addr = UInt(DATA_ADDR_WID.W)
|
|
||||||
val mem_sel = Vec(config.fuNum, Bool())
|
|
||||||
val ex = Vec(config.fuNum, new ExceptionInfo())
|
|
||||||
})
|
|
||||||
val out = Output(new Bundle {
|
|
||||||
val acc_err = Bool()
|
|
||||||
val rdata = Output(UInt(DATA_WID.W))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
val dataMemory = new DataMemoryAccess_DataMemory()
|
val dataMemory = new DataMemoryAccess_DataMemory()
|
||||||
})
|
})
|
||||||
val mem_addr = io.memoryUnit.in.mem_addr
|
|
||||||
val mem_addr2 = mem_addr(1, 0)
|
val atomAlu = Module(new AtomAlu()).io
|
||||||
val mem_rdata = io.dataMemory.in.rdata
|
val lsExe = Module(new LSExe()).io
|
||||||
val mem_wdata = io.memoryUnit.in.mem_wdata
|
|
||||||
val op = io.memoryUnit.in.info.op
|
val valid = io.memoryUnit.in.mem_en
|
||||||
io.dataMemory.out.en := io.memoryUnit.in.mem_en &&
|
val src1 = io.memoryUnit.in.src_info.src1_data
|
||||||
(io.memoryUnit.in.mem_sel(0) &&
|
val src2 = io.memoryUnit.in.src_info.src2_data
|
||||||
!(HasExcInt(io.memoryUnit.in.ex(0))) ||
|
val func = io.memoryUnit.in.info.op
|
||||||
io.memoryUnit.in.mem_sel(1) &&
|
val inst = io.memoryUnit.in.info.inst
|
||||||
!(HasExcInt(io.memoryUnit.in.ex(0))) && !(HasExcInt(io.memoryUnit.in.ex(1))))
|
|
||||||
io.dataMemory.out.addr := mem_addr
|
val storeReq = valid & LSUOpType.isStore(func)
|
||||||
val rdata = LookupTree(
|
val loadReq = valid & LSUOpType.isLoad(func)
|
||||||
mem_addr(2, 0),
|
val atomReq = valid & LSUOpType.isAtom(func)
|
||||||
List(
|
val amoReq = valid & LSUOpType.isAMO(func)
|
||||||
"b000".U -> mem_rdata(63, 0),
|
val lrReq = valid & LSUOpType.isLR(func)
|
||||||
"b001".U -> mem_rdata(63, 8),
|
val scReq = valid & LSUOpType.isSC(func)
|
||||||
"b010".U -> mem_rdata(63, 16),
|
|
||||||
"b011".U -> mem_rdata(63, 24),
|
val aq = inst(26)
|
||||||
"b100".U -> mem_rdata(63, 32),
|
val rl = inst(25)
|
||||||
"b101".U -> mem_rdata(63, 40),
|
val funct3 = inst(14, 12)
|
||||||
"b110".U -> mem_rdata(63, 48),
|
|
||||||
"b111".U -> mem_rdata(63, 56)
|
val atomWidthW = !funct3(0)
|
||||||
)
|
val atomWidthD = funct3(0)
|
||||||
)
|
|
||||||
io.memoryUnit.out.acc_err := io.dataMemory.in.acc_err
|
// Atom LR/SC Control Bits
|
||||||
io.memoryUnit.out.rdata := MuxLookup(op, rdata(XLEN - 1, 0))(
|
val setLr = Wire(Bool())
|
||||||
List(
|
val setLrVal = Wire(Bool())
|
||||||
LSUOpType.lb -> SignedExtend(rdata(7, 0), XLEN),
|
val setLrAddr = Wire(UInt(DATA_ADDR_WID.W))
|
||||||
LSUOpType.lh -> SignedExtend(rdata(15, 0), XLEN),
|
val lr = WireInit(Bool(), false.B)
|
||||||
LSUOpType.lw -> SignedExtend(rdata(31, 0), XLEN),
|
val lrAddr = WireInit(UInt(DATA_ADDR_WID.W), DontCare)
|
||||||
LSUOpType.lbu -> ZeroExtend(rdata(7, 0), XLEN),
|
io.memoryUnit.out.set_lr := setLr
|
||||||
LSUOpType.lhu -> ZeroExtend(rdata(15, 0), XLEN),
|
io.memoryUnit.out.set_lr_val := setLrVal
|
||||||
LSUOpType.lwu -> ZeroExtend(rdata(31, 0), XLEN)
|
io.memoryUnit.out.set_lr_addr := setLrAddr
|
||||||
)
|
lr := io.memoryUnit.in.lr
|
||||||
)
|
lrAddr := io.memoryUnit.in.lr_addr
|
||||||
def genWdata(data: UInt, sizeEncode: UInt): UInt = {
|
|
||||||
LookupTree(
|
val s_idle :: s_lr :: s_sc :: s_amo_l :: s_amo_a :: s_amo_s :: Nil = Enum(6)
|
||||||
sizeEncode,
|
|
||||||
List(
|
val state = RegInit(s_idle)
|
||||||
"b00".U -> Fill(8, data(7, 0)),
|
val atomMemReg = Reg(UInt(XLEN.W))
|
||||||
"b01".U -> Fill(4, data(15, 0)),
|
val atomRegReg = Reg(UInt(XLEN.W))
|
||||||
"b10".U -> Fill(2, data(31, 0)),
|
atomAlu.in.rdata := atomMemReg
|
||||||
"b11".U -> data
|
atomAlu.in.wdata := io.dataMemory.out.wdata
|
||||||
)
|
atomAlu.in.info := io.memoryUnit.in.info
|
||||||
)
|
|
||||||
|
val scInvalid = (src1 =/= lrAddr || !lr) && scReq
|
||||||
|
|
||||||
|
lsExe.in.info := io.memoryUnit.in.info
|
||||||
|
lsExe.in.mem_addr := 0.U
|
||||||
|
lsExe.in.mem_en := false.B
|
||||||
|
lsExe.in.wdata := 0.U
|
||||||
|
io.memoryUnit.out.ready := false.B
|
||||||
|
|
||||||
|
switch(state) {
|
||||||
|
is(s_idle) { // calculate address
|
||||||
|
lsExe.in.mem_en := io.memoryUnit.in.mem_en && !atomReq
|
||||||
|
lsExe.in.mem_addr := src1 + src2
|
||||||
|
lsExe.in.info.op := func
|
||||||
|
lsExe.in.wdata := io.memoryUnit.in.src_info.src2_data
|
||||||
|
io.memoryUnit.out.ready := lsExe.dataMemory.in.ready || scInvalid
|
||||||
|
state := s_idle
|
||||||
|
|
||||||
|
when(amoReq) { state := s_amo_l }
|
||||||
|
when(lrReq) { state := s_lr }
|
||||||
|
when(scReq) { state := Mux(scInvalid, s_idle, s_sc) }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
is(s_amo_l) {
|
||||||
|
lsExe.in.mem_en := true.B
|
||||||
|
lsExe.in.mem_addr := src1
|
||||||
|
lsExe.in.info.op := Mux(atomWidthD, LSUOpType.ld, LSUOpType.lw)
|
||||||
|
lsExe.in.wdata := DontCare
|
||||||
|
io.memoryUnit.out.ready := false.B
|
||||||
|
when(lsExe.dataMemory.in.ready) {
|
||||||
|
state := s_amo_a;
|
||||||
|
}
|
||||||
|
atomMemReg := lsExe.out.rdata
|
||||||
|
atomRegReg := lsExe.out.rdata
|
||||||
|
}
|
||||||
|
|
||||||
|
is(s_amo_a) {
|
||||||
|
lsExe.in.mem_en := false.B
|
||||||
|
lsExe.in.mem_addr := DontCare
|
||||||
|
lsExe.in.info.op := DontCare
|
||||||
|
lsExe.in.wdata := DontCare
|
||||||
|
io.memoryUnit.out.ready := false.B
|
||||||
|
state := s_amo_s
|
||||||
|
atomMemReg := atomAlu.out.result
|
||||||
|
}
|
||||||
|
|
||||||
|
is(s_amo_s) {
|
||||||
|
lsExe.in.mem_en := true.B
|
||||||
|
lsExe.in.mem_addr := src1
|
||||||
|
lsExe.in.info.op := Mux(atomWidthD, LSUOpType.sd, LSUOpType.sw)
|
||||||
|
lsExe.in.wdata := atomMemReg
|
||||||
|
io.memoryUnit.out.ready := lsExe.dataMemory.in.ready
|
||||||
|
when(lsExe.dataMemory.in.ready) {
|
||||||
|
state := s_idle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is(s_lr) {
|
||||||
|
lsExe.in.mem_en := true.B
|
||||||
|
lsExe.in.mem_addr := src1
|
||||||
|
lsExe.in.info.op := Mux(atomWidthD, LSUOpType.ld, LSUOpType.lw)
|
||||||
|
lsExe.in.wdata := DontCare
|
||||||
|
io.memoryUnit.out.ready := lsExe.dataMemory.in.ready
|
||||||
|
when(lsExe.dataMemory.in.ready) {
|
||||||
|
state := s_idle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is(s_sc) {
|
||||||
|
lsExe.in.mem_en := true.B
|
||||||
|
lsExe.in.mem_addr := src1
|
||||||
|
lsExe.in.info.op := Mux(atomWidthD, LSUOpType.sd, LSUOpType.sw)
|
||||||
|
lsExe.in.wdata := io.memoryUnit.in.src_info.src2_data
|
||||||
|
io.memoryUnit.out.ready := lsExe.dataMemory.in.ready
|
||||||
|
when(lsExe.dataMemory.in.ready) {
|
||||||
|
state := s_idle;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
def genWmask(addr: UInt, sizeEncode: UInt): UInt = {
|
when(lsExe.out.loadAddrMisaligned || lsExe.out.storeAddrMisaligned) {
|
||||||
LookupTree(
|
state := s_idle
|
||||||
sizeEncode,
|
io.memoryUnit.out.ready := true.B
|
||||||
List(
|
io.memoryUnit.out.ready := true.B
|
||||||
"b00".U -> 0x1.U, //0001 << addr(2:0)
|
|
||||||
"b01".U -> 0x3.U, //0011
|
|
||||||
"b10".U -> 0xf.U, //1111
|
|
||||||
"b11".U -> 0xff.U //11111111
|
|
||||||
)
|
|
||||||
) << addr(2, 0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
io.dataMemory.out.wdata := genWdata(mem_wdata, op(1, 0))
|
setLr := io.memoryUnit.out.ready && (lrReq || scReq)
|
||||||
io.dataMemory.out.wen := LSUOpType.isStore(op) && io.memoryUnit.in.mem_en
|
setLrVal := lrReq
|
||||||
io.dataMemory.out.wstrb := genWmask(mem_addr, op(1, 0))
|
setLrAddr := src1
|
||||||
io.dataMemory.out.rlen := op(1, 0)
|
|
||||||
|
io.dataMemory <> lsExe.dataMemory
|
||||||
|
|
||||||
|
io.memoryUnit.out.ex := io.memoryUnit.in.ex
|
||||||
|
io.memoryUnit.out.ex.exception(loadAddrMisaligned) := lsExe.out.loadAddrMisaligned
|
||||||
|
io.memoryUnit.out.ex.exception(storeAddrMisaligned) := lsExe.out.storeAddrMisaligned
|
||||||
|
io.memoryUnit.out.ex.exception(loadAccessFault) := lsExe.out.loadAccessFault
|
||||||
|
io.memoryUnit.out.ex.exception(storeAccessFault) := lsExe.out.storeAccessFault
|
||||||
|
io.memoryUnit.out.rdata := lsExe.out.rdata
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@ class LSExe extends Module {
|
||||||
val out = Output(new Bundle {
|
val out = Output(new Bundle {
|
||||||
val loadAddrMisaligned = Bool()
|
val loadAddrMisaligned = Bool()
|
||||||
val storeAddrMisaligned = Bool()
|
val storeAddrMisaligned = Bool()
|
||||||
|
val loadAccessFault = Bool()
|
||||||
|
val storeAccessFault = Bool()
|
||||||
val rdata = UInt(DATA_WID.W)
|
val rdata = UInt(DATA_WID.W)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -136,5 +138,7 @@ class LSExe extends Module {
|
||||||
val is_amo = valid && LSUOpType.isAMO(op)
|
val is_amo = valid && LSUOpType.isAMO(op)
|
||||||
io.out.rdata := Mux(partialLoad, rdataPartialLoad, rdataSel)
|
io.out.rdata := Mux(partialLoad, rdataPartialLoad, rdataSel)
|
||||||
io.out.loadAddrMisaligned := valid && !isStore && !is_amo && !addrAligned
|
io.out.loadAddrMisaligned := valid && !isStore && !is_amo && !addrAligned
|
||||||
|
io.out.loadAccessFault := valid && !isStore && !is_amo && acc_err
|
||||||
io.out.storeAddrMisaligned := valid && (isStore || is_amo) && !addrAligned
|
io.out.storeAddrMisaligned := valid && (isStore || is_amo) && !addrAligned
|
||||||
|
io.out.storeAccessFault := valid && (isStore || is_amo) && acc_err
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,16 +24,37 @@ class MemoryUnit(implicit val config: CpuConfig) extends Module {
|
||||||
})
|
})
|
||||||
|
|
||||||
val dataMemoryAccess = Module(new DataMemoryAccess()).io
|
val dataMemoryAccess = Module(new DataMemoryAccess()).io
|
||||||
dataMemoryAccess.memoryUnit.in.mem_en := io.memoryStage.inst0.mem.en
|
val mem_sel = VecInit(
|
||||||
dataMemoryAccess.memoryUnit.in.info := io.memoryStage.inst0.mem.info
|
io.memoryStage.inst0.info.valid &&
|
||||||
dataMemoryAccess.memoryUnit.in.mem_wdata := io.memoryStage.inst0.mem.wdata
|
io.memoryStage.inst0.info.fusel === FuType.lsu &&
|
||||||
dataMemoryAccess.memoryUnit.in.mem_addr := io.memoryStage.inst0.mem.addr
|
!HasExcInt(io.memoryStage.inst0.ex),
|
||||||
dataMemoryAccess.memoryUnit.in.mem_sel := io.memoryStage.inst0.mem.sel
|
io.memoryStage.inst1.info.valid &&
|
||||||
dataMemoryAccess.memoryUnit.in.ex(0) := io.memoryStage.inst0.ex
|
io.memoryStage.inst1.info.fusel === FuType.lsu &&
|
||||||
dataMemoryAccess.memoryUnit.in.ex(1) := io.memoryStage.inst1.ex
|
!HasExcInt(io.memoryStage.inst1.ex) && !HasExcInt(io.memoryStage.inst0.ex)
|
||||||
dataMemoryAccess.dataMemory.in.acc_err := io.dataMemory.in.acc_err
|
)
|
||||||
dataMemoryAccess.dataMemory.in.rdata := io.dataMemory.in.rdata
|
dataMemoryAccess.memoryUnit.in.mem_en := mem_sel.reduce(_ || _)
|
||||||
io.dataMemory.out := dataMemoryAccess.dataMemory.out
|
dataMemoryAccess.memoryUnit.in.info := MuxCase(
|
||||||
|
0.U.asTypeOf(new InstInfo()),
|
||||||
|
Seq(
|
||||||
|
mem_sel(0) -> io.memoryStage.inst0.info,
|
||||||
|
mem_sel(1) -> io.memoryStage.inst1.info
|
||||||
|
)
|
||||||
|
)
|
||||||
|
dataMemoryAccess.memoryUnit.in.src_info := MuxCase(
|
||||||
|
0.U.asTypeOf(new SrcInfo()),
|
||||||
|
Seq(
|
||||||
|
mem_sel(0) -> io.memoryStage.inst0.src_info,
|
||||||
|
mem_sel(1) -> io.memoryStage.inst1.src_info
|
||||||
|
)
|
||||||
|
)
|
||||||
|
dataMemoryAccess.memoryUnit.in.ex := MuxCase(
|
||||||
|
0.U.asTypeOf(new ExceptionInfo()),
|
||||||
|
Seq(
|
||||||
|
mem_sel(0) -> io.memoryStage.inst0.ex,
|
||||||
|
mem_sel(1) -> io.memoryStage.inst1.ex
|
||||||
|
)
|
||||||
|
)
|
||||||
|
dataMemoryAccess.dataMemory <> io.dataMemory
|
||||||
|
|
||||||
io.decoderUnit(0).wen := io.writeBackStage.inst0.info.reg_wen
|
io.decoderUnit(0).wen := io.writeBackStage.inst0.info.reg_wen
|
||||||
io.decoderUnit(0).waddr := io.writeBackStage.inst0.info.reg_waddr
|
io.decoderUnit(0).waddr := io.writeBackStage.inst0.info.reg_waddr
|
||||||
|
@ -46,22 +67,22 @@ class MemoryUnit(implicit val config: CpuConfig) extends Module {
|
||||||
io.writeBackStage.inst0.info := io.memoryStage.inst0.info
|
io.writeBackStage.inst0.info := io.memoryStage.inst0.info
|
||||||
io.writeBackStage.inst0.rd_info.wdata := io.memoryStage.inst0.rd_info.wdata
|
io.writeBackStage.inst0.rd_info.wdata := io.memoryStage.inst0.rd_info.wdata
|
||||||
io.writeBackStage.inst0.rd_info.wdata(FuType.lsu) := dataMemoryAccess.memoryUnit.out.rdata
|
io.writeBackStage.inst0.rd_info.wdata(FuType.lsu) := dataMemoryAccess.memoryUnit.out.rdata
|
||||||
io.writeBackStage.inst0.ex := io.memoryStage.inst0.ex
|
io.writeBackStage.inst0.ex := Mux(
|
||||||
io.writeBackStage.inst0.ex.exception(loadAccessFault) := io.memoryStage.inst0.mem.sel(0) &&
|
mem_sel(0),
|
||||||
LSUOpType.isLoad(io.memoryStage.inst0.info.op) && dataMemoryAccess.memoryUnit.out.acc_err
|
dataMemoryAccess.memoryUnit.out.ex,
|
||||||
io.writeBackStage.inst0.ex.exception(storeAccessFault) := io.memoryStage.inst0.mem.sel(0) &&
|
io.memoryStage.inst0.ex
|
||||||
LSUOpType.isStore(io.memoryStage.inst0.info.op) && dataMemoryAccess.memoryUnit.out.acc_err
|
)
|
||||||
io.writeBackStage.inst0.commit := io.memoryStage.inst0.info.valid
|
io.writeBackStage.inst0.commit := io.memoryStage.inst0.info.valid
|
||||||
|
|
||||||
io.writeBackStage.inst1.pc := io.memoryStage.inst1.pc
|
io.writeBackStage.inst1.pc := io.memoryStage.inst1.pc
|
||||||
io.writeBackStage.inst1.info := io.memoryStage.inst1.info
|
io.writeBackStage.inst1.info := io.memoryStage.inst1.info
|
||||||
io.writeBackStage.inst1.rd_info.wdata := io.memoryStage.inst1.rd_info.wdata
|
io.writeBackStage.inst1.rd_info.wdata := io.memoryStage.inst1.rd_info.wdata
|
||||||
io.writeBackStage.inst1.rd_info.wdata(FuType.lsu) := dataMemoryAccess.memoryUnit.out.rdata
|
io.writeBackStage.inst1.rd_info.wdata(FuType.lsu) := dataMemoryAccess.memoryUnit.out.rdata
|
||||||
io.writeBackStage.inst1.ex := io.memoryStage.inst1.ex
|
io.writeBackStage.inst1.ex := Mux(
|
||||||
io.writeBackStage.inst1.ex.exception(loadAccessFault) := io.memoryStage.inst0.mem.sel(1) &&
|
mem_sel(1),
|
||||||
LSUOpType.isLoad(io.memoryStage.inst1.info.op) && dataMemoryAccess.memoryUnit.out.acc_err
|
dataMemoryAccess.memoryUnit.out.ex,
|
||||||
io.writeBackStage.inst1.ex.exception(storeAccessFault) := io.memoryStage.inst0.mem.sel(1) &&
|
io.memoryStage.inst1.ex
|
||||||
LSUOpType.isStore(io.memoryStage.inst1.info.op) && dataMemoryAccess.memoryUnit.out.acc_err
|
)
|
||||||
io.writeBackStage.inst1.commit := io.memoryStage.inst1.info.valid &&
|
io.writeBackStage.inst1.commit := io.memoryStage.inst1.info.valid &&
|
||||||
!(HasExcInt(io.writeBackStage.inst0.ex))
|
!(HasExcInt(io.writeBackStage.inst0.ex))
|
||||||
|
|
||||||
|
@ -80,8 +101,15 @@ class MemoryUnit(implicit val config: CpuConfig) extends Module {
|
||||||
0.U.asTypeOf(new InstInfo())
|
0.U.asTypeOf(new InstInfo())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
io.csr.in.set_lr := dataMemoryAccess.memoryUnit.out.set_lr && io.ctrl.allow_to_go
|
||||||
|
io.csr.in.set_lr_val := dataMemoryAccess.memoryUnit.out.set_lr_val
|
||||||
|
io.csr.in.set_lr_addr := dataMemoryAccess.memoryUnit.out.set_lr_addr
|
||||||
|
dataMemoryAccess.memoryUnit.in.lr := io.csr.out.lr
|
||||||
|
dataMemoryAccess.memoryUnit.in.lr_addr := io.csr.out.lr_addr
|
||||||
|
|
||||||
io.fetchUnit.flush := io.csr.out.flush && io.ctrl.allow_to_go
|
io.fetchUnit.flush := io.csr.out.flush && io.ctrl.allow_to_go
|
||||||
io.fetchUnit.target := Mux(io.csr.out.flush, io.csr.out.flush_pc, io.writeBackStage.inst0.pc + 4.U)
|
io.fetchUnit.target := Mux(io.csr.out.flush, io.csr.out.flush_pc, io.writeBackStage.inst0.pc + 4.U)
|
||||||
|
|
||||||
io.ctrl.flush := io.fetchUnit.flush
|
io.ctrl.flush := io.fetchUnit.flush
|
||||||
|
io.ctrl.mem_stall := !dataMemoryAccess.memoryUnit.out.ready && dataMemoryAccess.memoryUnit.in.mem_en
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue