提交 67ef08a8 编写于 作者: Z zoujr

Merge branch 'master' into bpu-timing

......@@ -40,6 +40,8 @@ RELEASE_ARGS = --disable-all --remove-assert --fpga-platform
DEBUG_ARGS = --enable-difftest
ifeq ($(RELEASE),1)
override SIM_ARGS += $(RELEASE_ARGS)
else
override SIM_ARGS += $(DEBUG_ARGS)
endif
TIMELOG = $(BUILD_DIR)/time.log
......@@ -52,9 +54,9 @@ help:
$(TOP_V): $(SCALA_FILE)
mkdir -p $(@D)
mill -i XiangShan.runMain $(FPGATOP) -td $(@D) \
mill -i XiangShan.runMain $(FPGATOP) -td $(@D) \
--config $(CONFIG) --full-stacktrace --output-file $(@F) \
--repl-seq-mem -c:$(FPGATOP):-o:$(@D)/$(@F).conf --infer-rw \
--infer-rw --repl-seq-mem -c:$(FPGATOP):-o:$(@D)/$(@F).conf \
--gen-mem-verilog full --num-cores $(NUM_CORES) \
$(RELEASE_ARGS)
sed -i -e 's/_\(aw\|ar\|w\|r\|b\)_\(\|bits_\)/_\1/g' $@
......@@ -74,11 +76,11 @@ $(SIM_TOP_V): $(SCALA_FILE) $(TEST_FILE)
mkdir -p $(@D)
@echo "\n[mill] Generating Verilog files..." > $(TIMELOG)
@date -R | tee -a $(TIMELOG)
$(TIME_CMD) mill -i XiangShan.test.runMain $(SIMTOP) -td $(@D) \
$(TIME_CMD) mill -i XiangShan.test.runMain $(SIMTOP) -td $(@D) \
--config $(CONFIG) --full-stacktrace --output-file $(@F) \
--repl-seq-mem -c:$(SIMTOP):-o:$(@D)/$(@F).conf --infer-rw \
--infer-rw --repl-seq-mem -c:$(SIMTOP):-o:$(@D)/$(@F).conf \
--gen-mem-verilog full --num-cores $(NUM_CORES) \
$(DEBUG_ARGS) $(SIM_ARGS)
$(SIM_ARGS)
@git log -n 1 >> .__head__
@git diff >> .__diff__
@sed -i 's/^/\/\// ' .__head__
......
Subproject commit fb00a5a7b020a1d66f854322c862c8cdaf2fb5a9
Subproject commit 9fc1180b77738dac273418a8177c6d9469ddc620
Subproject commit dff8392b1f9eced37e8ee8eade69d0bf25542cce
Subproject commit db5c2b43c2f48e896d449ce825c4870dcf2fa314
Subproject commit cb97f940276cbaf713856d1cfcf2b808d824ac22
Subproject commit 81f87ad06eabdadf7a598cda8a4b26b403947067
......@@ -83,7 +83,7 @@ class XSTop()(implicit p: Parameters) extends BaseXSSoc() with HasSoCParameter
for (i <- 0 until NumCores) {
core_with_l2(i).clint_int_sink := misc.clint.intnode
core_with_l2(i).plic_int_sink := misc.plic.intnode
core_with_l2(i).plic_int_sink :*= misc.plic.intnode
core_with_l2(i).debug_int_sink := misc.debugModule.debug.dmOuter.dmOuter.intnode
misc.plic.intnode := core_with_l2(i).beu_int_source
misc.peripheral_ports(i) := core_with_l2(i).uncache
......
......@@ -54,4 +54,4 @@ object PipelineConnect {
pipelineConnect.io.isFlush := isFlush
right <> pipelineConnect.io.out
}
}
}
\ No newline at end of file
......@@ -28,7 +28,7 @@ class ResetGen extends Module {
}
object ResetGen {
def apply(resetChain: Seq[Seq[Module]], reset: Bool, sim: Boolean): Seq[Bool] = {
def apply(resetChain: Seq[Seq[MultiIOModule]], reset: Bool, sim: Boolean): Seq[Bool] = {
val resetReg = Wire(Vec(resetChain.length + 1, Bool()))
resetReg.foreach(_ := reset)
for ((resetLevel, i) <- resetChain.zipWithIndex) {
......
......@@ -307,6 +307,7 @@ class ExternalInterruptIO(implicit p: Parameters) extends XSBundle {
val mtip = Input(Bool())
val msip = Input(Bool())
val meip = Input(Bool())
val seip = Input(Bool())
val debug = Input(Bool())
}
......@@ -330,7 +331,6 @@ class RobCommitInfo(implicit p: Parameters) extends XSBundle {
val fpWen = Bool()
val wflags = Bool()
val commitType = CommitType()
val eliminatedMove = Bool()
val pdest = UInt(PhyRegIdxWidth.W)
val old_pdest = UInt(PhyRegIdxWidth.W)
val ftqIdx = new FtqPtr
......
......@@ -252,6 +252,7 @@ case class DebugOptions
(
FPGAPlatform: Boolean = false,
EnableDifftest: Boolean = false,
AlwaysBasicDiff: Boolean = true,
EnableDebug: Boolean = false,
EnablePerfDebug: Boolean = true,
UseDRAMSim: Boolean = false
......
......@@ -58,7 +58,7 @@ abstract class XSCoreBase()(implicit p: config.Parameters) extends LazyModule
// interrupt sinks
val clint_int_sink = IntSinkNode(IntSinkPortSimple(1, 2))
val debug_int_sink = IntSinkNode(IntSinkPortSimple(1, 1))
val plic_int_sink = IntSinkNode(IntSinkPortSimple(1, 1))
val plic_int_sink = IntSinkNode(IntSinkPortSimple(2, 1))
// outer facing nodes
val frontend = LazyModule(new Frontend())
val ptw = LazyModule(new PTWWrapper())
......@@ -278,6 +278,7 @@ class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer)
csrioIn.externalInterrupt.msip := outer.clint_int_sink.in.head._1(0)
csrioIn.externalInterrupt.mtip := outer.clint_int_sink.in.head._1(1)
csrioIn.externalInterrupt.meip := outer.plic_int_sink.in.head._1(0)
csrioIn.externalInterrupt.seip := outer.plic_int_sink.in.last._1(0)
csrioIn.externalInterrupt.debug := outer.debug_int_sink.in.head._1(0)
csrioIn.distributedUpdate <> memBlock.io.csrUpdate // TODO
......@@ -296,7 +297,8 @@ class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer)
val itlbRepeater1 = PTWRepeater(frontend.io.ptw, fenceio.sfence, csrioIn.tlb)
val itlbRepeater2 = PTWRepeater(itlbRepeater1.io.ptw, ptw.io.tlb(0), fenceio.sfence, csrioIn.tlb)
val dtlbRepeater = PTWFilter(memBlock.io.ptw, ptw.io.tlb(1), fenceio.sfence, csrioIn.tlb, l2tlbParams.filterSize)
val dtlbRepeater1 = PTWFilter(memBlock.io.ptw, fenceio.sfence, csrioIn.tlb, l2tlbParams.filterSize)
val dtlbRepeater2 = PTWRepeaterNB(passReady = false, dtlbRepeater1.io.ptw, ptw.io.tlb(1), fenceio.sfence, csrioIn.tlb)
ptw.io.sfence <> fenceio.sfence
ptw.io.csr.tlb <> csrioIn.tlb
ptw.io.csr.distribute_csr <> csrioIn.customCtrl.distribute_csr
......@@ -310,7 +312,7 @@ class XSCoreImp(outer: XSCoreBase) extends LazyModuleImp(outer)
// v v v v v
// PTW {MemBlock, dtlb} ExuBlocks CtrlBlock {Frontend, itlb}
val resetChain = Seq(
Seq(memBlock, dtlbRepeater),
Seq(memBlock, dtlbRepeater1, dtlbRepeater2),
Seq(exuBlocks.head),
// Note: arbiters don't actually have reset ports
exuBlocks.tail ++ Seq(outer.wbArbiter.module),
......
......@@ -448,13 +448,13 @@ class SchedulerImp(outer: Scheduler) extends LazyModuleImp(outer) with HasXSPara
}
}
if (env.EnableDifftest && intRfConfig._1) {
if ((env.AlwaysBasicDiff || env.EnableDifftest) && intRfConfig._1) {
val difftest = Module(new DifftestArchIntRegState)
difftest.io.clock := clock
difftest.io.coreid := hardId.U
difftest.io.gpr := intRfReadData.takeRight(32)
}
if (env.EnableDifftest && fpRfConfig._1) {
if ((env.AlwaysBasicDiff || env.EnableDifftest) && fpRfConfig._1) {
val difftest = Module(new DifftestArchFpRegState)
difftest.io.clock := clock
difftest.io.coreid := hardId.U
......
......@@ -19,6 +19,7 @@ package xiangshan.backend.exu
import chipsalliance.rocketchip.config.Parameters
import chisel3._
import chisel3.util._
import difftest.{DifftestFpWriteback, DifftestIntWriteback}
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp}
import utils.{XSPerfAccumulate, XSPerfHistogram}
import xiangshan._
......@@ -204,7 +205,7 @@ class WbArbiterWrapper(
val numOutPorts = intArbiter.numOutPorts + fpArbiter.numOutPorts
lazy val module = new LazyModuleImp(this) {
lazy val module = new LazyModuleImp(this) with HasXSParameter {
val io = IO(new Bundle() {
val in = Vec(numInPorts, Flipped(DecoupledIO(new ExuOutput)))
val out = Vec(numOutPorts, ValidIO(new ExuOutput))
......@@ -222,6 +223,14 @@ class WbArbiterWrapper(
wb.ready := arb.ready
}
}
intArbiter.module.io.out.foreach(out => {
val difftest = Module(new DifftestIntWriteback)
difftest.io.clock := clock
difftest.io.coreid := hardId.U
difftest.io.valid := out.valid
difftest.io.dest := out.bits.uop.pdest
difftest.io.data := out.bits.data
})
val fpWriteback = io.in.zip(exuConfigs).filter(_._2.writeFpRf)
fpArbiter.module.io.in.zip(fpWriteback).foreach{ case (arb, (wb, cfg)) =>
......@@ -232,6 +241,14 @@ class WbArbiterWrapper(
wb.ready := arb.ready
}
}
fpArbiter.module.io.out.foreach(out => {
val difftest = Module(new DifftestFpWriteback)
difftest.io.clock := clock
difftest.io.coreid := hardId.U
difftest.io.valid := out.valid
difftest.io.dest := out.bits.uop.pdest
difftest.io.data := out.bits.data
})
io.out <> intArbiter.module.io.out ++ fpArbiter.module.io.out
}
......
......@@ -925,7 +925,7 @@ class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMP
mipWire.t.m := csrio.externalInterrupt.mtip
mipWire.s.m := csrio.externalInterrupt.msip
mipWire.e.m := csrio.externalInterrupt.meip
mipWire.e.s := csrio.externalInterrupt.meip
mipWire.e.s := csrio.externalInterrupt.seip
// interrupts
val intrNO = IntPriority.foldRight(0.U)((i: Int, sum: UInt) => Mux(intrVec(i), i.U, sum))
......@@ -1079,7 +1079,8 @@ class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMP
val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U)
if (env.EnableDifftest) {
// Always instantiate basic difftest modules.
if (env.AlwaysBasicDiff || env.EnableDifftest) {
val difftest = Module(new DifftestArchEvent)
difftest.io.clock := clock
difftest.io.coreid := hardId.U
......@@ -1088,7 +1089,8 @@ class CSR(implicit p: Parameters) extends FunctionUnit with HasCSRConst with PMP
difftest.io.exceptionPC := RegNext(SignExt(csrio.exception.bits.uop.cf.pc, XLEN))
}
if (env.EnableDifftest) {
// Always instantiate basic difftest modules.
if (env.AlwaysBasicDiff || env.EnableDifftest) {
val difftest = Module(new DifftestCSRState)
difftest.io.clock := clock
difftest.io.coreid := hardId.U
......
......@@ -20,8 +20,7 @@ import chipsalliance.rocketchip.config.Parameters
import chisel3._
import chisel3.util._
import freechips.rocketchip.tile.FType
import fudian.FPUpConverter
import hardfloat.{DivSqrtRecFNToRaw_small, DivSqrtRecFNToRaw_srt4, RoundAnyRawFNToRecFN}
import fudian.{FPUpConverter,FDIV}
class FDivSqrtDataModule(implicit p: Parameters) extends FPUDataModule {
val in_valid, out_ready = IO(Input(Bool()))
......@@ -32,101 +31,34 @@ class FDivSqrtDataModule(implicit p: Parameters) extends FPUDataModule {
val in_fire = in_valid && in_ready
val out_fire = out_valid && out_ready
val s_idle :: s_div :: s_finish :: Nil = Enum(3)
val state = RegInit(s_idle)
val divSqrt = Module(new DivSqrtRecFNToRaw_srt4(FType.D.exp, FType.D.sig))
val divSqrtRawValid = divSqrt.io.rawOutValid_sqrt || divSqrt.io.rawOutValid_div
val fpCtrl = io.in.fpCtrl
val tag = fpCtrl.typeTagIn
val single = RegEnable(tag === S, in_fire)
val rmReg = RegEnable(rm, in_fire)
switch(state){
is(s_idle){
when(in_fire && !kill_w){ state := s_div }
}
is(s_div){
when(divSqrtRawValid){
state := s_finish
}
}
is(s_finish){
when(out_fire){
state := s_idle
}
}
}
when(kill_r){ state := s_idle }
val in1_unboxed = FPU.unbox(io.in.src(0), tag)
val in2_unboxed = FPU.unbox(io.in.src(1), tag)
def up_convert_s_d(in: UInt): UInt = {
val converter = Module(new FPUpConverter(
FPU.f32.expWidth, FPU.f32.precision,
FPU.f64.expWidth, FPU.f64.precision
))
converter.io.in := in
converter.io.rm := DontCare
converter.io.result
}
val src1 = hardfloat.recFNFromFN(FType.D.exp, FType.D.sig,
Mux(tag === FPU.S,
up_convert_s_d(in1_unboxed),
in1_unboxed
)
)
val src2 = hardfloat.recFNFromFN(FType.D.exp, FType.D.sig,
Mux(tag === FPU.S,
up_convert_s_d(in2_unboxed),
in2_unboxed
)
)
divSqrt.io.inValid := in_fire && !kill_w
divSqrt.io.sqrtOp := fpCtrl.sqrt
divSqrt.io.kill := kill_r
divSqrt.io.sigBits := Mux(tag === S, FType.S.sig.U, FType.D.sig.U)
divSqrt.io.a := src1
divSqrt.io.b := src2
divSqrt.io.roundingMode := rm
val round32 = Module(new RoundAnyRawFNToRecFN(
FType.D.exp, FType.D.sig+2, FType.S.exp, FType.S.sig, 0
))
val round64 = Module(new RoundAnyRawFNToRecFN(
FType.D.exp, FType.D.sig+2, FType.D.exp, FType.D.sig, 0
))
for(rounder <- Seq(round32, round64)){
rounder.io.invalidExc := divSqrt.io.invalidExc
rounder.io.infiniteExc := divSqrt.io.infiniteExc
rounder.io.in := divSqrt.io.rawOut
rounder.io.roundingMode := rmReg
rounder.io.detectTininess := hardfloat.consts.tininess_afterRounding
val src1 = FPU.unbox(io.in.src(0), tag)
val src2 = FPU.unbox(io.in.src(1), tag)
val typeSel = VecInit(FPU.ftypes.zipWithIndex.map(_._2.U === tag))
val outSel = RegEnable(typeSel, VecInit(Seq.fill(typeSel.length)(true.B)), in_fire) // inelegant
val divSqrt = FPU.ftypes.map{ t =>
val fdiv = Module(new FDIV(t.expWidth, t.precision))
fdiv.io.a := src1
fdiv.io.b := src2
fdiv.io.rm := rm
fdiv.io.specialIO.in_valid := in_fire && !kill_w
fdiv.io.specialIO.out_ready := out_ready
fdiv.io.specialIO.isSqrt := fpCtrl.sqrt
fdiv.io.specialIO.kill := kill_r
fdiv
}
val data = Mux(single,
FPU.box(
Cat(0.U(32.W), hardfloat.fNFromRecFN(FType.S.exp, FType.S.sig, round32.io.out)),
FPU.S
),
FPU.box(hardfloat.fNFromRecFN(FType.D.exp, FType.D.sig, round64.io.out), FPU.D)
)
val flags = Mux(single, round32.io.exceptionFlags, round64.io.exceptionFlags)
assert(!(state === s_idle && !divSqrt.io.inReady))
in_ready := state===s_idle
out_valid := state===s_finish
io.out.data := RegNext(data, divSqrtRawValid)
fflags := RegNext(flags, divSqrtRawValid)
in_ready := Mux1H(outSel, divSqrt.map(_.io.specialIO.in_ready))
out_valid := Mux1H(outSel, divSqrt.map(_.io.specialIO.out_valid))
io.out.data := Mux1H(outSel, divSqrt.zip(FPU.ftypes).map{
case (mod, t) => FPU.box(mod.io.result, t)
})
fflags := Mux1H(outSel, divSqrt.map(_.io.fflags))
}
class FDivSqrt(implicit p: Parameters) extends FPUSubModule {
val uopReg = RegEnable(io.in.bits.uop, io.in.fire())
......
......@@ -270,7 +270,7 @@ class Rename(implicit p: Parameters) extends XSModule {
for (i <- 0 until CommitWidth) {
val info = io.robCommits.info(i)
XSDebug(io.robCommits.isWalk && io.robCommits.valid(i), p"[#$i walk info] pc:${Hexadecimal(info.pc)} " +
p"ldest:${info.ldest} rfWen:${info.rfWen} fpWen:${info.fpWen} " + p"eliminatedMove:${info.eliminatedMove} " +
p"ldest:${info.ldest} rfWen:${info.rfWen} fpWen:${info.fpWen} " +
p"pdest:${info.pdest} old_pdest:${info.old_pdest}\n")
}
......
......@@ -277,8 +277,6 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
// data for redirect, exception, etc.
// val flagBkup = RegInit(VecInit(List.fill(RobSize)(false.B)))
val flagBkup = Mem(RobSize, Bool())
// record move elimination info for each instruction
val eliminatedMove = Mem(RobSize, Bool())
// data for debug
// Warn: debug_* prefix should not exist in generated verilog.
......@@ -687,7 +685,6 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
// enqueue logic set 6 writebacked to false
for (i <- 0 until RenameWidth) {
when (canEnqueue(i)) {
eliminatedMove(enqPtrVec(i).value) := io.enq.req(i).bits.eliminatedMove
writebacked(enqPtrVec(i).value) := io.enq.req(i).bits.eliminatedMove && !io.enq.req(i).bits.cf.exceptionVec.asUInt.orR
val isStu = io.enq.req(i).bits.ctrl.fuType === FuType.stu
store_data_writebacked(enqPtrVec(i).value) := !isStu
......@@ -740,7 +737,6 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
wdata.fpWen := req.ctrl.fpWen
wdata.wflags := req.ctrl.fpu.wflags
wdata.commitType := req.ctrl.commitType
wdata.eliminatedMove := req.eliminatedMove
wdata.pdest := req.pdest
wdata.old_pdest := req.old_pdest
wdata.ftqIdx := req.cf.ftqPtr
......@@ -770,7 +766,7 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
def load_wb_idxes = Seq(exuParameters.AluCnt + 1) // second port for load
def store_wb_idxes = io.exeWbResults.indices.takeRight(2)
val all_exception_possibilities = Seq(csr_wb_idx, atomic_wb_idx) ++ load_wb_idxes ++ store_wb_idxes
all_exception_possibilities.zipWithIndex.map{ case (p, i) => connect_exception(i, p) }
all_exception_possibilities.zipWithIndex.foreach{ case (p, i) => connect_exception(i, p) }
def connect_exception(index: Int, wb_index: Int) = {
exceptionGen.io.wb(index).valid := io.exeWbResults(wb_index).valid
// A temporary fix for float load writeback
......@@ -911,21 +907,16 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
val wdata = Wire(Vec(CommitWidth, UInt(XLEN.W)))
val wpc = Wire(Vec(CommitWidth, UInt(XLEN.W)))
val trapVec = Wire(Vec(CommitWidth, Bool()))
for(i <- 0 until CommitWidth) {
val idx = deqPtrVec(i).value
wdata(i) := debug_exuData(idx)
wpc(i) := SignExt(commitDebugUop(i).cf.pc, XLEN)
trapVec(i) := io.commits.valid(i) && (state===s_idle) && commitDebugUop(i).ctrl.isXSTrap
}
val retireCounterFix = Mux(io.exception.valid, 1.U, retireCounter)
val retirePCFix = SignExt(Mux(io.exception.valid, io.exception.bits.uop.cf.pc, debug_microOp(firstValidCommit).cf.pc), XLEN)
val retireInstFix = Mux(io.exception.valid, io.exception.bits.uop.cf.instr, debug_microOp(firstValidCommit).cf.instr)
val hitTrap = trapVec.reduce(_||_)
val trapCode = PriorityMux(wdata.zip(trapVec).map(x => x._2 -> x._1))
val trapPC = SignExt(PriorityMux(wpc.zip(trapVec).map(x => x._2 ->x._1)), XLEN)
if (env.EnableDifftest) {
for (i <- 0 until CommitWidth) {
val difftest = Module(new DifftestInstrCommit)
......@@ -940,7 +931,7 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
difftest.io.valid := RegNext(io.commits.valid(i) && !io.commits.isWalk)
difftest.io.pc := RegNext(SignExt(uop.cf.pc, XLEN))
difftest.io.instr := RegNext(uop.cf.instr)
difftest.io.special := RegNext(CommitType.isFused(uop.ctrl.commitType))
difftest.io.special := RegNext(CommitType.isFused(io.commits.info(i).commitType))
// when committing an eliminated move instruction,
// we must make sure that skip is properly set to false (output from EXU is random value)
difftest.io.skip := RegNext(Mux(uop.eliminatedMove, false.B, exuOut.isMMIO || exuOut.isPerfCnt))
......@@ -948,9 +939,9 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
difftest.io.scFailed := RegNext(!uop.diffTestDebugLrScValid &&
uop.ctrl.fuType === FuType.mou &&
(uop.ctrl.fuOpType === LSUOpType.sc_d || uop.ctrl.fuOpType === LSUOpType.sc_w))
difftest.io.wen := RegNext(io.commits.valid(i) && uop.ctrl.rfWen && uop.ctrl.ldest =/= 0.U)
difftest.io.wdata := RegNext(exuData)
difftest.io.wdest := RegNext(uop.ctrl.ldest)
difftest.io.wen := RegNext(io.commits.valid(i) && io.commits.info(i).rfWen && io.commits.info(i).ldest =/= 0.U)
difftest.io.wpdest := RegNext(io.commits.info(i).pdest)
difftest.io.wdest := RegNext(io.commits.info(i)ldest)
// runahead commit hint
val runahead_commit = Module(new DifftestRunaheadCommitEvent)
......@@ -963,6 +954,44 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
runahead_commit.io.pc := difftest.io.pc
}
}
else if (env.AlwaysBasicDiff) {
// These are the structures used by difftest only and should be optimized after synthesis.
val dt_eliminatedMove = Mem(RobSize, Bool())
val dt_isRVC = Mem(RobSize, Bool())
val dt_exuDebug = Reg(Vec(RobSize, new DebugBundle))
for (i <- 0 until RenameWidth) {
when (canEnqueue(i)) {
dt_eliminatedMove(enqPtrVec(i).value) := io.enq.req(i).bits.eliminatedMove
dt_isRVC(enqPtrVec(i).value) := io.enq.req(i).bits.cf.pd.isRVC
}
}
for (i <- 0 until numWbPorts) {
when (io.exeWbResults(i).valid) {
val wbIdx = io.exeWbResults(i).bits.uop.robIdx.value
dt_exuDebug(wbIdx) := io.exeWbResults(i).bits.debug
}
}
// Always instantiate basic difftest modules.
for (i <- 0 until CommitWidth) {
val commitInfo = io.commits.info(i)
val ptr = deqPtrVec(i).value
val exuOut = dt_exuDebug(ptr)
val eliminatedMove = dt_eliminatedMove(ptr)
val isRVC = dt_isRVC(ptr)
val difftest = Module(new DifftestBasicInstrCommit)
difftest.io.clock := clock
difftest.io.coreid := hardId.U
difftest.io.index := i.U
difftest.io.valid := RegNext(io.commits.valid(i) && !io.commits.isWalk)
difftest.io.special := RegNext(CommitType.isFused(commitInfo.commitType))
difftest.io.skip := RegNext(Mux(eliminatedMove, false.B, exuOut.isMMIO || exuOut.isPerfCnt))
difftest.io.isRVC := RegNext(isRVC)
difftest.io.wen := RegNext(io.commits.valid(i) && commitInfo.rfWen && commitInfo.ldest =/= 0.U)
difftest.io.wpdest := RegNext(commitInfo.pdest)
difftest.io.wdest := RegNext(commitInfo.ldest)
}
}
if (env.EnableDifftest) {
for (i <- 0 until CommitWidth) {
......@@ -981,7 +1010,18 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
}
}
// Always instantiate basic difftest modules.
if (env.EnableDifftest) {
val dt_isXSTrap = Mem(RobSize, Bool())
for (i <- 0 until RenameWidth) {
when (canEnqueue(i)) {
dt_isXSTrap(enqPtrVec(i).value) := io.enq.req(i).bits.ctrl.isXSTrap
}
}
val trapVec = io.commits.valid.zip(deqPtrVec).map{ case (v, d) => state === s_idle && v && dt_isXSTrap(d.value) }
val hitTrap = trapVec.reduce(_||_)
val trapCode = PriorityMux(wdata.zip(trapVec).map(x => x._2 -> x._1))
val trapPC = SignExt(PriorityMux(wpc.zip(trapVec).map(x => x._2 ->x._1)), XLEN)
val difftest = Module(new DifftestTrapEvent)
difftest.io.clock := clock
difftest.io.coreid := hardId.U
......@@ -991,6 +1031,22 @@ class Rob(numWbPorts: Int)(implicit p: Parameters) extends XSModule with HasCirc
difftest.io.cycleCnt := timer
difftest.io.instrCnt := instrCnt
}
else if (env.AlwaysBasicDiff) {
val dt_isXSTrap = Mem(RobSize, Bool())
for (i <- 0 until RenameWidth) {
when (canEnqueue(i)) {
dt_isXSTrap(enqPtrVec(i).value) := io.enq.req(i).bits.ctrl.isXSTrap
}
}
val trapVec = io.commits.valid.zip(deqPtrVec).map{ case (v, d) => state === s_idle && v && dt_isXSTrap(d.value) }
val hitTrap = trapVec.reduce(_||_)
val difftest = Module(new DifftestBasicTrapEvent)
difftest.io.clock := clock
difftest.io.coreid := hardId.U
difftest.io.valid := hitTrap
difftest.io.cycleCnt := timer
difftest.io.instrCnt := instrCnt
}
val perfinfo = IO(new Bundle(){
val perfEvents = Output(new PerfEventsBundle(18))
......
......@@ -98,6 +98,7 @@ class PTWImp(outer: PTW)(implicit p: Parameters) extends PtwModule(outer) with H
val source = UInt(bSourceWidth.W)
}, if (l2tlbParams.enablePrefetch) 3 else 2))
val outArb = (0 until PtwWidth).map(i => Module(new Arbiter(new PtwResp, 3)).io)
val outArbCachePort = 0
val outArbFsmPort = 1
val outArbMqPort = 2
......@@ -130,7 +131,9 @@ class PTWImp(outer: PTW)(implicit p: Parameters) extends PtwModule(outer) with H
cache.io.req.bits.isFirst := arb2.io.chosen =/= InArbMissQueuePort.U
cache.io.sfence := sfence
cache.io.csr := csr
cache.io.resp.ready := Mux(cache.io.resp.bits.hit, true.B, missQueue.io.in.ready || (!cache.io.resp.bits.toFsm.l2Hit && fsm.io.req.ready))
cache.io.resp.ready := Mux(cache.io.resp.bits.hit,
outReady(cache.io.resp.bits.req_info.source, outArbCachePort),
missQueue.io.in.ready || (!cache.io.resp.bits.toFsm.l2Hit && fsm.io.req.ready))
val mq_in_arb = Module(new Arbiter(new L2TlbMQInBundle, 2))
mq_in_arb.io.in(0).valid := cache.io.resp.valid && !cache.io.resp.bits.hit && (cache.io.resp.bits.toFsm.l2Hit || !fsm.io.req.ready)
......@@ -150,8 +153,7 @@ class PTWImp(outer: PTW)(implicit p: Parameters) extends PtwModule(outer) with H
fsm.io.req.bits.ppn := cache.io.resp.bits.toFsm.ppn
fsm.io.csr := csr
fsm.io.sfence := sfence
fsm.io.resp.ready := MuxLookup(fsm.io.resp.bits.source, true.B,
(0 until PtwWidth).map(i => i.U -> outArb(i).in(outArbFsmPort).ready))
fsm.io.resp.ready := outReady(fsm.io.resp.bits.source, outArbFsmPort)
// mem req
def blockBytes_align(addr: UInt) = {
......@@ -239,13 +241,12 @@ class PTWImp(outer: PTW)(implicit p: Parameters) extends PtwModule(outer) with H
pmp_check(1).req <> missQueue.io.pmp.req
missQueue.io.pmp.resp <> pmp_check(1).resp
mq_out.ready := MuxLookup(missQueue.io.out.bits.req_info.source, true.B,
(0 until PtwWidth).map(i => i.U -> outArb(i).in(outArbMqPort).ready))
mq_out.ready := outReady(mq_out.bits.req_info.source, outArbMqPort)
for (i <- 0 until PtwWidth) {
outArb(i).in(0).valid := cache.io.resp.valid && cache.io.resp.bits.hit && cache.io.resp.bits.req_info.source===i.U
outArb(i).in(0).bits.entry := cache.io.resp.bits.toTlb
outArb(i).in(0).bits.pf := false.B
outArb(i).in(0).bits.af := false.B
outArb(i).in(outArbCachePort).valid := cache.io.resp.valid && cache.io.resp.bits.hit && cache.io.resp.bits.req_info.source===i.U
outArb(i).in(outArbCachePort).bits.entry := cache.io.resp.bits.toTlb
outArb(i).in(outArbCachePort).bits.pf := false.B
outArb(i).in(outArbCachePort).bits.af := false.B
outArb(i).in(outArbFsmPort).valid := fsm.io.resp.valid && fsm.io.resp.bits.source===i.U
outArb(i).in(outArbFsmPort).bits := fsm.io.resp.bits.resp
outArb(i).in(outArbMqPort).valid := mq_out.valid && mq_out.bits.req_info.source===i.U
......@@ -297,6 +298,11 @@ class PTWImp(outer: PTW)(implicit p: Parameters) extends PtwModule(outer) with H
ptw_resp
}
def outReady(source: UInt, port: Int): Bool = {
MuxLookup(source, true.B,
(0 until PtwWidth).map(i => i.U -> outArb(i).in(port).ready))
}
// debug info
for (i <- 0 until PtwWidth) {
XSDebug(p"[io.tlb(${i.U})] ${io.tlb(i)}\n")
......
......@@ -103,13 +103,18 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
val rwHarzad = if (sramSinglePort) io.refill.valid else false.B
// handle hand signal and req_info
val stage1 = Wire(Decoupled(new PtwCacheReq()))
val stage2 = Wire(Decoupled(new PtwCacheReq()))
val stage3 = Wire(Decoupled(new PtwCacheReq()))
val stage1 = Wire(Decoupled(new PtwCacheReq())) // enq stage & read page cache valid
val stage2 = Wire(Vec(2, Decoupled(new PtwCacheReq()))) // page cache resp & check hit & check ecc
val stage3 = Wire(Decoupled(new PtwCacheReq())) // deq stage
/* stage1.valid && stage2(0).ready : stage1 (in) -> stage2
* stage2(1).valid && stage3.ready : stage2 -> stage3
* stage3.valid && io.resp.ready : stage3 (out) -> outside
*/
stage1 <> io.req
PipelineConnect(stage1, stage2, stage3.ready, flush, rwHarzad)
PipelineConnect(stage2, stage3, io.resp.ready, flush)
stage3.ready := io.resp.ready
PipelineConnect(stage1, stage2(0), stage2(1).ready, flush, rwHarzad)
InsideStageConnect(stage2(0), stage2(1))
PipelineConnect(stage2(1), stage3, io.resp.ready, flush)
stage3.ready := !stage3.valid || io.resp.ready
// l1: level 0 non-leaf pte
val l1 = Reg(Vec(l2tlbParams.l1Size, new PtwEntry(tagLen = PtwL1TagLen)))
......@@ -200,7 +205,7 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
XSDebug(stage1.fire, p"[l1] l1(${i.U}) ${l1(i)} hit:${l1(i).hit(stage1.bits.req_info.vpn, io.csr.satp.asid)}\n")
}
XSDebug(stage1.fire, p"[l1] l1v:${Binary(l1v)} hitVecT:${Binary(VecInit(hitVecT).asUInt)}\n")
XSDebug(stage2.valid, p"[l1] l1Hit:${hit} l1HitPPN:0x${Hexadecimal(hitPPN)} hitVec:${VecInit(hitVec).asUInt}\n")
XSDebug(stage2(0).valid, p"[l1] l1Hit:${hit} l1HitPPN:0x${Hexadecimal(hitPPN)} hitVec:${VecInit(hitVec).asUInt}\n")
VecInit(hitVecT).suggestName(s"l1_hitVecT")
VecInit(hitVec).suggestName(s"l1_hitVec")
......@@ -217,7 +222,7 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
l2.io.r.req.valid := stage1.fire
l2.io.r.req.bits.apply(setIdx = ridx)
val ramDatas = l2.io.r.resp.data
val hitVec = VecInit(ramDatas.zip(vidx).map { case (wayData, v) => wayData.entries.hit(stage2.bits.req_info.vpn, io.csr.satp.asid) && v })
val hitVec = VecInit(ramDatas.zip(vidx).map { case (wayData, v) => wayData.entries.hit(stage2(0).bits.req_info.vpn, io.csr.satp.asid) && v })
val hitWayEntry = ParallelPriorityMux(hitVec zip ramDatas)
val hitWayData = hitWayEntry.entries
val hit = ParallelOR(hitVec) && cache_read_valid && RegNext(l2.io.r.req.ready, init = false.B)
......@@ -231,16 +236,16 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
hitWayData.suggestName(s"l2_hitWayData")
hitWay.suggestName(s"l2_hitWay")
when (hit) { ptwl2replace.access(genPtwL2SetIdx(stage2.bits.req_info.vpn), hitWay) }
when (hit) { ptwl2replace.access(genPtwL2SetIdx(stage2(0).bits.req_info.vpn), hitWay) }
l2AccessPerf.zip(hitVec).map{ case (l, h) => l := h && RegNext(stage1.fire) }
XSDebug(stage1.fire, p"[l2] ridx:0x${Hexadecimal(ridx)}\n")
for (i <- 0 until l2tlbParams.l2nWays) {
XSDebug(RegNext(stage1.fire), p"[l2] ramDatas(${i.U}) ${ramDatas(i)} l2v:${vidx(i)} hit:${ramDatas(i).entries.hit(stage2.bits.req_info.vpn, io.csr.satp.asid)}\n")
XSDebug(RegNext(stage1.fire), p"[l2] ramDatas(${i.U}) ${ramDatas(i)} l2v:${vidx(i)} hit:${ramDatas(i).entries.hit(stage2(0).bits.req_info.vpn, io.csr.satp.asid)}\n")
}
XSDebug(stage2.valid, p"[l2] l2Hit:${hit} l2HitPPN:0x${Hexadecimal(hitWayData.ppns(genPtwL2SectorIdx(stage2.bits.req_info.vpn)))} hitVec:${Binary(hitVec.asUInt)} hitWay:${hitWay} vidx:${Binary(vidx.asUInt)}\n")
XSDebug(stage2(0).valid, p"[l2] l2Hit:${hit} l2HitPPN:0x${Hexadecimal(hitWayData.ppns(genPtwL2SectorIdx(stage2(0).bits.req_info.vpn)))} hitVec:${Binary(hitVec.asUInt)} hitWay:${hitWay} vidx:${Binary(vidx.asUInt)}\n")
(hit, hitWayData.ppns(genPtwL2SectorIdx(stage2.bits.req_info.vpn)), hitWayData.prefetch, eccError)
(hit, hitWayData.ppns(genPtwL2SectorIdx(stage2(0).bits.req_info.vpn)), hitWayData.prefetch, eccError)
}
// l3
......@@ -252,7 +257,7 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
l3.io.r.req.valid := stage1.fire
l3.io.r.req.bits.apply(setIdx = ridx)
val ramDatas = l3.io.r.resp.data
val hitVec = VecInit(ramDatas.zip(vidx).map{ case (wayData, v) => wayData.entries.hit(stage2.bits.req_info.vpn, io.csr.satp.asid) && v })
val hitVec = VecInit(ramDatas.zip(vidx).map{ case (wayData, v) => wayData.entries.hit(stage2(0).bits.req_info.vpn, io.csr.satp.asid) && v })
val hitWayEntry = ParallelPriorityMux(hitVec zip ramDatas)
val hitWayData = hitWayEntry.entries
val hitWayEcc = hitWayEntry.ecc
......@@ -260,14 +265,14 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
val hitWay = ParallelPriorityMux(hitVec zip (0 until l2tlbParams.l3nWays).map(_.U))
val eccError = hitWayEntry.decode()
when (hit) { ptwl3replace.access(genPtwL3SetIdx(stage2.bits.req_info.vpn), hitWay) }
when (hit) { ptwl3replace.access(genPtwL3SetIdx(stage2(0).bits.req_info.vpn), hitWay) }
l3AccessPerf.zip(hitVec).map{ case (l, h) => l := h && RegNext(stage1.fire) }
XSDebug(stage1.fire, p"[l3] ridx:0x${Hexadecimal(ridx)}\n")
for (i <- 0 until l2tlbParams.l3nWays) {
XSDebug(RegNext(stage1.fire), p"[l3] ramDatas(${i.U}) ${ramDatas(i)} l3v:${vidx(i)} hit:${ramDatas(i).entries.hit(stage2.bits.req_info.vpn, io.csr.satp.asid)}\n")
XSDebug(RegNext(stage1.fire), p"[l3] ramDatas(${i.U}) ${ramDatas(i)} l3v:${vidx(i)} hit:${ramDatas(i).entries.hit(stage2(0).bits.req_info.vpn, io.csr.satp.asid)}\n")
}
XSDebug(stage2.valid, p"[l3] l3Hit:${hit} l3HitData:${hitWayData} hitVec:${Binary(hitVec.asUInt)} hitWay:${hitWay} vidx:${Binary(vidx.asUInt)}\n")
XSDebug(stage2(0).valid, p"[l3] l3Hit:${hit} l3HitData:${hitWayData} hitVec:${Binary(hitVec.asUInt)} hitWay:${hitWay} vidx:${Binary(vidx.asUInt)}\n")
ridx.suggestName(s"l3_ridx")
vidx.suggestName(s"l3_vidx")
......@@ -277,8 +282,8 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
(hit, hitWayData, hitWayData.prefetch, eccError)
}
val l3HitPPN = l3HitData.ppns(genPtwL3SectorIdx(stage2.bits.req_info.vpn))
val l3HitPerm = l3HitData.perms.getOrElse(0.U.asTypeOf(Vec(PtwL3SectorSize, new PtePermBundle)))(genPtwL3SectorIdx(stage2.bits.req_info.vpn))
val l3HitPPN = l3HitData.ppns(genPtwL3SectorIdx(stage2(0).bits.req_info.vpn))
val l3HitPerm = l3HitData.perms.getOrElse(0.U.asTypeOf(Vec(PtwL3SectorSize, new PtePermBundle)))(genPtwL3SectorIdx(stage2(0).bits.req_info.vpn))
// super page
val spreplace = ReplacementPolicy.fromString(l2tlbParams.spReplacer, l2tlbParams.spSize)
......@@ -294,7 +299,7 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
for (i <- 0 until l2tlbParams.spSize) {
XSDebug(stage1.fire, p"[sp] sp(${i.U}) ${sp(i)} hit:${sp(i).hit(stage1.bits.req_info.vpn, io.csr.satp.asid)} spv:${spv(i)}\n")
}
XSDebug(stage2.valid, p"[sp] spHit:${hit} spHitData:${hitData} hitVec:${Binary(VecInit(hitVec).asUInt)}\n")
XSDebug(stage2(0).valid, p"[sp] spHit:${hit} spHitData:${hitData} hitVec:${Binary(VecInit(hitVec).asUInt)}\n")
VecInit(hitVecT).suggestName(s"sp_hitVecT")
VecInit(hitVec).suggestName(s"sp_hitVec")
......@@ -313,7 +318,7 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
// stage3, add stage 3 for ecc check...
val s3_res = Reg(new PageCacheRespBundle)
when (stage2.fire()) {
when (stage2(1).fire()) {
s3_res := s2_res_reg
}
......@@ -551,6 +556,12 @@ class PtwCache()(implicit p: Parameters) extends XSModule with HasPtwConst {
}
}
def InsideStageConnect[T <:Data](in: DecoupledIO[T], out: DecoupledIO[T], block: Bool = false.B): Unit = {
in.ready := !in.valid || out.ready
out.valid := in.valid
out.bits := in.bits
}
// Perf Count
val resp_l3 = s3_res.l3.hit
val resp_sp = s3_res.sp.hit
......
......@@ -117,21 +117,21 @@ class PtwFsm()(implicit p: Parameters) extends XSModule with HasPtwConst {
}
is (s_check_pte) {
when (io.resp.valid) {
when (io.resp.valid) { // find pte already or accessFault (mentioned below)
when (io.resp.fire()) {
state := s_idle
}
finish := true.B
}.otherwise {
when (io.pmp.resp.ld) {
// do nothing
}.elsewhen (io.mq.valid) {
when (io.mq.fire()) {
state := s_idle
}
finish := true.B
}.otherwise { // when level is 1.U, finish
assert(level =/= 2.U)
}.elsewhen(io.mq.valid) { // the next level is pte, go to miss queue
when (io.mq.fire()) {
state := s_idle
}
finish := true.B
} otherwise { // go to next level, access the memory, need pmp check first
when (io.pmp.resp.ld) { // pmp check failed, raise access-fault
// do nothing, RegNext the pmp check result and do it later (mentioned above)
}.otherwise { // go to next level.
assert(level === 0.U)
level := levelNext
state := s_mem_req
}
......
......@@ -29,6 +29,19 @@ class PTWReapterIO(Width: Int)(implicit p: Parameters) extends MMUIOBaseBundle {
val tlb = Flipped(new TlbPtwIO(Width))
val ptw = new TlbPtwIO
def apply(tlb: TlbPtwIO, ptw: TlbPtwIO, sfence: SfenceBundle, csr: TlbCsrBundle): Unit = {
this.tlb <> tlb
this.ptw <> ptw
this.sfence <> sfence
this.csr <> csr
}
def apply(tlb: TlbPtwIO, sfence: SfenceBundle, csr: TlbCsrBundle): Unit = {
this.tlb <> tlb
this.sfence <> sfence
this.csr <> csr
}
override def cloneType: this.type = (new PTWReapterIO(Width)).asInstanceOf[this.type]
}
......@@ -71,10 +84,66 @@ class PTWRepeater(Width: Int = 1)(implicit p: Parameters) extends XSModule with
/* dtlb
*
*/
class PTWRepeaterNB(Width: Int = 1, passReady: Boolean = false)(implicit p: Parameters) extends XSModule with HasPtwConst {
val io = IO(new PTWReapterIO(Width))
val req_in = if (Width == 1) {
io.tlb.req(0)
} else {
val arb = Module(new RRArbiter(io.tlb.req(0).bits.cloneType, Width))
arb.io.in <> io.tlb.req
arb.io.out
}
val (tlb, ptw, flush) = (io.tlb, io.ptw, RegNext(io.sfence.valid || io.csr.satp.changed))
/* sent: tlb -> repeater -> ptw
* recv: ptw -> repeater -> tlb
* different from PTWRepeater
*/
// tlb -> repeater -> ptw
val req = RegEnable(req_in.bits, req_in.fire())
val sent = BoolStopWatch(req_in.fire(), ptw.req(0).fire() || flush)
req_in.ready := !sent || { if (passReady) ptw.req(0).ready else false.B }
ptw.req(0).valid := sent
ptw.req(0).bits := req
// ptw -> repeater -> tlb
val resp = RegEnable(ptw.resp.bits, ptw.resp.fire())
val recv = BoolStopWatch(ptw.resp.fire(), tlb.resp.fire() || flush)
ptw.resp.ready := !recv || { if (passReady) tlb.resp.ready else false.B }
tlb.resp.valid := recv
tlb.resp.bits := resp
XSPerfAccumulate("req", req_in.fire())
XSPerfAccumulate("resp", tlb.resp.fire())
if (!passReady) {
XSPerfAccumulate("req_blank", req_in.valid && sent && ptw.req(0).ready)
XSPerfAccumulate("resp_blank", ptw.resp.valid && recv && tlb.resp.ready)
XSPerfAccumulate("req_blank_ignore_ready", req_in.valid && sent)
XSPerfAccumulate("resp_blank_ignore_ready", ptw.resp.valid && recv)
}
XSDebug(req_in.valid || io.tlb.resp.valid, p"tlb: ${tlb}\n")
XSDebug(io.ptw.req(0).valid || io.ptw.resp.valid, p"ptw: ${ptw}\n")
}
class PTWFilterIO(Width: Int)(implicit p: Parameters) extends MMUIOBaseBundle {
val tlb = Flipped(new BTlbPtwIO(Width))
val ptw = new TlbPtwIO()
def apply(tlb: BTlbPtwIO, ptw: TlbPtwIO, sfence: SfenceBundle, csr: TlbCsrBundle): Unit = {
this.tlb <> tlb
this.ptw <> ptw
this.sfence <> sfence
this.csr <> csr
}
def apply(tlb: BTlbPtwIO, sfence: SfenceBundle, csr: TlbCsrBundle): Unit = {
this.tlb <> tlb
this.sfence <> sfence
this.csr <> csr
}
override def cloneType: this.type = (new PTWFilterIO(Width)).asInstanceOf[this.type]
}
......@@ -233,10 +302,7 @@ object PTWRepeater {
)(implicit p: Parameters) = {
val width = tlb.req.size
val repeater = Module(new PTWRepeater(width))
repeater.io.tlb <> tlb
repeater.io.sfence <> sfence
repeater.io.csr <> csr
repeater.io.apply(tlb, sfence, csr)
repeater
}
......@@ -248,11 +314,32 @@ object PTWRepeater {
)(implicit p: Parameters) = {
val width = tlb.req.size
val repeater = Module(new PTWRepeater(width))
repeater.io.tlb <> tlb
repeater.io.ptw <> ptw
repeater.io.sfence <> sfence
repeater.io.csr <> csr
repeater.io.apply(tlb, ptw, sfence, csr)
repeater
}
}
object PTWRepeaterNB {
def apply(passReady: Boolean,
tlb: TlbPtwIO,
sfence: SfenceBundle,
csr: TlbCsrBundle
)(implicit p: Parameters) = {
val width = tlb.req.size
val repeater = Module(new PTWRepeaterNB(width, passReady))
repeater.io.apply(tlb, sfence, csr)
repeater
}
def apply(passReady: Boolean,
tlb: TlbPtwIO,
ptw: TlbPtwIO,
sfence: SfenceBundle,
csr: TlbCsrBundle
)(implicit p: Parameters) = {
val width = tlb.req.size
val repeater = Module(new PTWRepeaterNB(width, passReady))
repeater.io.apply(tlb, ptw, sfence, csr)
repeater
}
}
......@@ -267,11 +354,20 @@ object PTWFilter {
)(implicit p: Parameters) = {
val width = tlb.req.size
val filter = Module(new PTWFilter(width, size))
filter.io.tlb <> tlb
filter.io.ptw <> ptw
filter.io.sfence <> sfence
filter.io.csr <> csr
filter.io.apply(tlb, ptw, sfence, csr)
filter
}
def apply(
tlb: BTlbPtwIO,
sfence: SfenceBundle,
csr: TlbCsrBundle,
size: Int
)(implicit p: Parameters) = {
val width = tlb.req.size
val filter = Module(new PTWFilter(width, size))
filter.io.apply(tlb, sfence, csr)
filter
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册