提交 6886802e 编写于 作者: L LinJiawei

Merge remote-tracking branch 'origin/master' into ftq

......@@ -8,7 +8,7 @@ import freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp}
import freechips.rocketchip.tilelink.{BankBinder, TLBuffer, TLBundleParameters, TLCacheCork, TLClientNode, TLFilter, TLFuzzer, TLIdentityNode, TLToAXI4, TLWidthWidget, TLXbar}
import utils.{DebugIdentityNode, DataDontCareNode}
import utils.XSInfo
import xiangshan.{HasXSParameter, XSCore, HasXSLog}
import xiangshan.{HasXSParameter, XSCore, HasXSLog, DifftestBundle}
import sifive.blocks.inclusivecache.{CacheParameters, InclusiveCache, InclusiveCacheMicroParameters}
import freechips.rocketchip.diplomacy.{AddressSet, LazyModule, LazyModuleImp}
import freechips.rocketchip.devices.tilelink.{DevNullParams, TLError}
......@@ -162,7 +162,9 @@ class XSSoc()(implicit p: Parameters) extends LazyModule with HasSoCParameter {
// val meip = Input(Vec(NumCores, Bool()))
val ila = if(env.FPGAPlatform && EnableILA) Some(Output(new ILABundle)) else None
})
val difftestIO0 = IO(new DifftestBundle())
val difftestIO1 = IO(new DifftestBundle())
val difftestIO = Seq(difftestIO0, difftestIO1)
plic.module.io.extra.get.intrVec <> RegNext(RegNext(Cat(io.extIntrs)))
for (i <- 0 until NumCores) {
......@@ -172,6 +174,12 @@ class XSSoc()(implicit p: Parameters) extends LazyModule with HasSoCParameter {
xs_core(i).module.io.externalInterrupt.meip := plic.module.io.extra.get.meip(i)
xs_core(i).module.io.l2ToPrefetcher <> l2cache(i).module.io
}
difftestIO0 <> DontCare
difftestIO1 <> DontCare
if (env.DualCoreDifftest) {
difftestIO0 <> xs_core(0).module.difftestIO
difftestIO1 <> xs_core(1).module.difftestIO
}
// do not let dma AXI signals optimized out
chisel3.dontTouch(dma.out.head._1)
chisel3.dontTouch(extDev.out.head._1)
......
......@@ -24,7 +24,7 @@ object Parameters {
val simParameters = Parameters(envParameters = EnviromentParameters(FPGAPlatform = false)) // sim only, disable log
val debugParameters = Parameters(envParameters = simParameters.envParameters.copy(EnableDebug = true, EnablePerfDebug = true)) // open log
val simDualCoreParameters = Parameters(socParameters = SoCParameters(NumCores = 2), envParameters = EnviromentParameters(FPGAPlatform = false))
val simDualCoreParameters = Parameters(socParameters = SoCParameters(NumCores = 2), envParameters = EnviromentParameters(FPGAPlatform = true, DualCoreDifftest = true))
val debugDualCoreParameters = Parameters(socParameters = SoCParameters(NumCores = 2), envParameters = simParameters.envParameters.copy(EnableDebug = true))
private var parameters = Parameters() // a default parameter, can be updated before use
......
......@@ -449,3 +449,55 @@ class SfenceBundle extends XSBundle {
p"valid:0x${Hexadecimal(valid)} rs1:${bits.rs1} rs2:${bits.rs2} addr:${Hexadecimal(bits.addr)}"
}
}
class DifftestBundle extends XSBundle {
val fromSbuffer = new Bundle() {
val sbufferResp = Output(Bool())
val sbufferAddr = Output(UInt(64.W))
val sbufferData = Output(Vec(64, UInt(8.W)))
val sbufferMask = Output(UInt(64.W))
}
val fromSQ = new Bundle() {
val storeCommit = Output(UInt(2.W))
val storeAddr = Output(Vec(2, UInt(64.W)))
val storeData = Output(Vec(2, UInt(64.W)))
val storeMask = Output(Vec(2, UInt(8.W)))
}
val fromXSCore = new Bundle() {
val r = Output(Vec(64, UInt(XLEN.W)))
}
val fromCSR = new Bundle() {
val intrNO = Output(UInt(64.W))
val cause = Output(UInt(64.W))
val priviledgeMode = Output(UInt(2.W))
val mstatus = Output(UInt(64.W))
val sstatus = Output(UInt(64.W))
val mepc = Output(UInt(64.W))
val sepc = Output(UInt(64.W))
val mtval = Output(UInt(64.W))
val stval = Output(UInt(64.W))
val mtvec = Output(UInt(64.W))
val stvec = Output(UInt(64.W))
val mcause = Output(UInt(64.W))
val scause = Output(UInt(64.W))
val satp = Output(UInt(64.W))
val mip = Output(UInt(64.W))
val mie = Output(UInt(64.W))
val mscratch = Output(UInt(64.W))
val sscratch = Output(UInt(64.W))
val mideleg = Output(UInt(64.W))
val medeleg = Output(UInt(64.W))
}
val fromRoq = new Bundle() {
val commit = Output(UInt(32.W))
val thisPC = Output(UInt(XLEN.W))
val thisINST = Output(UInt(32.W))
val skip = Output(UInt(32.W))
val wen = Output(UInt(32.W))
val wdata = Output(Vec(CommitWidth, UInt(XLEN.W))) // set difftest width to 6
val wdst = Output(Vec(CommitWidth, UInt(32.W))) // set difftest width to 6
val wpc = Output(Vec(CommitWidth, UInt(XLEN.W))) // set difftest width to 6
val isRVC = Output(UInt(32.W))
val scFailed = Output(Bool())
}
}
\ No newline at end of file
......@@ -22,6 +22,14 @@ import freechips.rocketchip.tile.HasFPUParameters
import sifive.blocks.inclusivecache.PrefetcherIO
import utils._
object hartIdCore extends (() => Int) {
var x = 0
def apply(): Int = {
x = x + 1
x-1
}
}
case class XSCoreParameters
(
XLEN: Int = 64,
......@@ -295,7 +303,8 @@ case class EnviromentParameters
(
FPGAPlatform: Boolean = true,
EnableDebug: Boolean = false,
EnablePerfDebug: Boolean = false
EnablePerfDebug: Boolean = false,
DualCoreDifftest: Boolean = false
)
// object AddressSpace extends HasXSParameter {
......@@ -356,6 +365,8 @@ class XSCoreImp(outer: XSCore) extends LazyModuleImp(outer)
val externalInterrupt = new ExternalInterruptIO
val l2ToPrefetcher = Flipped(new PrefetcherIO(PAddrBits))
})
val difftestIO = IO(new DifftestBundle())
difftestIO <> DontCare
println(s"FPGAPlatform:${env.FPGAPlatform} EnableDebug:${env.EnableDebug}")
AddressSpace.printMemmap()
......@@ -488,4 +499,18 @@ class XSCoreImp(outer: XSCore) extends LazyModuleImp(outer)
ExcitingUtils.addSource(debugArchReg, "difftestRegs", ExcitingUtils.Debug)
}
if (env.DualCoreDifftest) {
val id = hartIdCore()
difftestIO.fromSbuffer <> memBlock.difftestIO.fromSbuffer
difftestIO.fromSQ <> memBlock.difftestIO.fromSQ
difftestIO.fromCSR <> integerBlock.difftestIO.fromCSR
difftestIO.fromRoq <> ctrlBlock.difftestIO.fromRoq
val debugIntReg, debugFpReg = WireInit(VecInit(Seq.fill(32)(0.U(XLEN.W))))
ExcitingUtils.addSink(debugIntReg, s"DEBUG_INT_ARCH_REG$id", ExcitingUtils.Debug)
ExcitingUtils.addSink(debugFpReg, s"DEBUG_FP_ARCH_REG$id", ExcitingUtils.Debug)
val debugArchReg = WireInit(VecInit(debugIntReg ++ debugFpReg))
difftestIO.fromXSCore.r := debugArchReg
}
}
......@@ -178,6 +178,22 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
}
})
val difftestIO = IO(new Bundle() {
val fromRoq = new Bundle() {
val commit = Output(UInt(32.W))
val thisPC = Output(UInt(XLEN.W))
val thisINST = Output(UInt(32.W))
val skip = Output(UInt(32.W))
val wen = Output(UInt(32.W))
val wdata = Output(Vec(CommitWidth, UInt(XLEN.W))) // set difftest width to 6
val wdst = Output(Vec(CommitWidth, UInt(32.W))) // set difftest width to 6
val wpc = Output(Vec(CommitWidth, UInt(XLEN.W))) // set difftest width to 6
val isRVC = Output(UInt(32.W))
val scFailed = Output(Bool())
}
})
difftestIO <> DontCare
val ftq = Module(new Ftq)
val decode = Module(new DecodeStage)
val rename = Module(new Rename)
......@@ -283,6 +299,10 @@ class CtrlBlock extends XSModule with HasCircularQueuePtrHelper {
io.toFpBlock.redirect <> backendRedirect
io.toLsBlock.redirect <> backendRedirect
if (env.DualCoreDifftest) {
difftestIO.fromRoq <> roq.difftestIO
}
dispatch.io.readPortIndex.intIndex <> io.toIntBlock.readPortIndex
dispatch.io.readPortIndex.fpIndex <> io.toFpBlock.readPortIndex
......
......@@ -92,6 +92,31 @@ class IntegerBlock
val sbuffer = new FenceToSbuffer // to mem
}
})
val difftestIO = IO(new Bundle() {
val fromCSR = new Bundle() {
val intrNO = Output(UInt(64.W))
val cause = Output(UInt(64.W))
val priviledgeMode = Output(UInt(2.W))
val mstatus = Output(UInt(64.W))
val sstatus = Output(UInt(64.W))
val mepc = Output(UInt(64.W))
val sepc = Output(UInt(64.W))
val mtval = Output(UInt(64.W))
val stval = Output(UInt(64.W))
val mtvec = Output(UInt(64.W))
val stvec = Output(UInt(64.W))
val mcause = Output(UInt(64.W))
val scause = Output(UInt(64.W))
val satp = Output(UInt(64.W))
val mip = Output(UInt(64.W))
val mie = Output(UInt(64.W))
val mscratch = Output(UInt(64.W))
val sscratch = Output(UInt(64.W))
val mideleg = Output(UInt(64.W))
val medeleg = Output(UInt(64.W))
}
})
difftestIO <> DontCare
val redirect = io.fromCtrlBlock.redirect
......@@ -219,6 +244,9 @@ class IntegerBlock
jmpExeUnit.csrio <> io.csrio
jmpExeUnit.fenceio <> io.fenceio
if (env.DualCoreDifftest) {
jmpExeUnit.difftestIO.fromCSR <> difftestIO.fromCSR
}
// read int rf from ctrl block
intRf.io.readPorts.zipWithIndex.map{ case(r, i) => r.addr := io.fromCtrlBlock.readRf(i) }
......
......@@ -83,6 +83,21 @@ class MemBlockImp
val toDCachePrefetch = DecoupledIO(new MissReq)
})
val difftestIO = IO(new Bundle() {
val fromSbuffer = new Bundle() {
val sbufferResp = Output(Bool())
val sbufferAddr = Output(UInt(64.W))
val sbufferData = Output(Vec(64, UInt(8.W)))
val sbufferMask = Output(UInt(64.W))
}
val fromSQ = new Bundle() {
val storeCommit = Output(UInt(2.W))
val storeAddr = Output(Vec(2, UInt(64.W)))
val storeData = Output(Vec(2, UInt(64.W)))
val storeMask = Output(Vec(2, UInt(8.W)))
}
})
difftestIO <> DontCare
val dcache = outer.dcache.module
val uncache = outer.uncache.module
......@@ -195,6 +210,10 @@ class MemBlockImp
io.ptw <> dtlb.io.ptw
dtlb.io.sfence <> io.sfence
dtlb.io.csr <> io.tlbCsr
if (env.DualCoreDifftest) {
difftestIO.fromSbuffer <> sbuffer.difftestIO
difftestIO.fromSQ <> lsq.difftestIO.fromSQ
}
// LoadUnit
for (i <- 0 until exuParameters.LduCnt) {
......@@ -212,6 +231,7 @@ class MemBlockImp
// passdown to lsq
lsq.io.loadIn(i) <> loadUnits(i).io.lsq.loadIn
lsq.io.ldout(i) <> loadUnits(i).io.lsq.ldout
lsq.io.loadDataForwarded(i) <> loadUnits(i).io.lsq.loadDataForwarded
}
// StoreUnit
......@@ -271,8 +291,8 @@ class MemBlockImp
val atomic_rs0 = exuParameters.LduCnt + 0
val atomic_rs1 = exuParameters.LduCnt + 1
val st0_atomics = reservationStations(atomic_rs0).io.deq.valid && reservationStations(atomic_rs0).io.deq.bits.uop.ctrl.fuType === FuType.mou
val st1_atomics = reservationStations(atomic_rs1).io.deq.valid && reservationStations(atomic_rs1).io.deq.bits.uop.ctrl.fuType === FuType.mou
val st0_atomics = reservationStations(atomic_rs0).io.deq.valid && FuType.storeIsAMO(reservationStations(atomic_rs0).io.deq.bits.uop.ctrl.fuType)
val st1_atomics = reservationStations(atomic_rs1).io.deq.valid && FuType.storeIsAMO(reservationStations(atomic_rs1).io.deq.bits.uop.ctrl.fuType)
when (st0_atomics) {
reservationStations(atomic_rs0).io.deq.ready := atomicsUnit.io.in.ready
......
......@@ -8,16 +8,12 @@ package xiangshan.backend.decode
import chisel3._
import chisel3.util._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.rocket.{RVCDecoder, ExpandedInstruction}
import freechips.rocketchip.rocket.{CSR,Causes}
import freechips.rocketchip.util.{uintToBitPat,UIntIsOneOf}
import xiangshan._
import utils._
import xiangshan.backend._
import xiangshan.backend.decode.Instructions._
import freechips.rocketchip.tile.RocketTile
/**
* Abstract trait giving defaults and other relevant values to different Decode constants/
......@@ -422,7 +418,7 @@ class DecodeUnit extends XSModule with DecodeUnitConstants {
cs.fpu := fpDecoder.io.fpCtrl
// read src1~3 location
cs.lsrc1 := Mux(ctrl_flow.instr === LUI || cs.src1Type === SrcType.pc, 0.U, ctrl_flow.instr(RS1_MSB,RS1_LSB))
cs.lsrc1 := Mux(ctrl_flow.instr === LUI, 0.U,ctrl_flow.instr(RS1_MSB,RS1_LSB))
cs.lsrc2 := ctrl_flow.instr(RS2_MSB,RS2_LSB)
cs.lsrc3 := ctrl_flow.instr(RS3_MSB,RS3_LSB)
// read dest location
......
......@@ -51,9 +51,10 @@ class Dispatch1 extends XSModule with HasExceptionNO {
!req.bits.cf.pd.notCFI || FuType.isJumpExu(req.bits.ctrl.fuType)
))
val isFp = VecInit(io.fromRename.map(req => FuType.isFpExu (req.bits.ctrl.fuType)))
val isLs = VecInit(io.fromRename.map(req => FuType.isMemExu(req.bits.ctrl.fuType)))
val isMem = VecInit(io.fromRename.map(req => FuType.isMemExu(req.bits.ctrl.fuType)))
val isLs = VecInit(io.fromRename.map(req => FuType.isLoadStore(req.bits.ctrl.fuType)))
val isStore = VecInit(io.fromRename.map(req => FuType.isStoreExu(req.bits.ctrl.fuType)))
val isAMO = VecInit(io.fromRename.map(req => req.bits.ctrl.fuType === FuType.mou))
val isAMO = VecInit(io.fromRename.map(req => FuType.isAMO(req.bits.ctrl.fuType)))
val isBlockBackward = VecInit(io.fromRename.map(_.bits.ctrl.blockBackward))
val isNoSpecExec = VecInit(io.fromRename.map(_.bits.ctrl.noSpecExec))
......@@ -69,7 +70,7 @@ class Dispatch1 extends XSModule with HasExceptionNO {
val updatedOldPdest = Wire(Vec(RenameWidth, UInt(PhyRegIdxWidth.W)))
for (i <- 0 until RenameWidth) {
updatedCommitType(i) := Cat(isLs(i) && !isAMO(i), isStore(i) | isBranch(i))
updatedCommitType(i) := Cat(isLs(i), (isStore(i) && !isAMO(i)) | isBranch(i))
updatedPsrc1(i) := io.fromRename.take(i).map(_.bits.pdest)
.zip(if (i == 0) Seq() else io.renameBypass.lsrc1_bypass(i-1).asBools)
.foldLeft(io.fromRename(i).bits.psrc1) {
......@@ -100,7 +101,8 @@ class Dispatch1 extends XSModule with HasExceptionNO {
// update commitType
updatedUop(i).ctrl.commitType := updatedCommitType(i)
// update roqIdx, lqIdx, sqIdx
updatedUop(i).roqIdx := io.enqRoq.resp(i)
// updatedUop(i).roqIdx := io.enqRoq.resp(i)
XSError(io.fromRename(i).valid && updatedUop(i).roqIdx.asUInt =/= io.enqRoq.resp(i).asUInt, "they should equal")
updatedUop(i).lqIdx := io.enqLsq.resp(i).lqIdx
updatedUop(i).sqIdx := io.enqLsq.resp(i).sqIdx
}
......@@ -145,9 +147,8 @@ class Dispatch1 extends XSModule with HasExceptionNO {
io.enqRoq.req(i).bits := updatedUop(i)
XSDebug(io.enqRoq.req(i).valid, p"pc 0x${Hexadecimal(io.fromRename(i).bits.cf.pc)} receives nroq ${io.enqRoq.resp(i)}\n")
val shouldEnqLsq = isLs(i) && !isAMO(i)
io.enqLsq.needAlloc(i) := io.fromRename(i).valid && shouldEnqLsq
io.enqLsq.req(i).valid := io.fromRename(i).valid && shouldEnqLsq && thisCanActualOut(i) && io.enqRoq.canAccept && io.toIntDq.canAccept && io.toFpDq.canAccept && io.toLsDq.canAccept
io.enqLsq.needAlloc(i) := io.fromRename(i).valid && isLs(i)
io.enqLsq.req(i).valid := io.fromRename(i).valid && isLs(i) && thisCanActualOut(i) && io.enqRoq.canAccept && io.toIntDq.canAccept && io.toFpDq.canAccept && io.toLsDq.canAccept
io.enqLsq.req(i).bits := updatedUop(i)
io.enqLsq.req(i).bits.roqIdx := io.enqRoq.resp(i)
XSDebug(io.enqLsq.req(i).valid,
......@@ -166,9 +167,9 @@ class Dispatch1 extends XSModule with HasExceptionNO {
io.toFpDq.req(i).valid := io.fromRename(i).valid && !hasException(i) && isFp(i) && thisCanActualOut(i) &&
io.enqLsq.canAccept && io.enqRoq.canAccept && io.toIntDq.canAccept && io.toLsDq.canAccept
io.toLsDq.needAlloc(i) := io.fromRename(i).valid && isLs(i)
io.toLsDq.needAlloc(i) := io.fromRename(i).valid && isMem(i)
io.toLsDq.req(i).bits := updatedUop(i)
io.toLsDq.req(i).valid := io.fromRename(i).valid && !hasException(i) && isLs(i) && thisCanActualOut(i) &&
io.toLsDq.req(i).valid := io.fromRename(i).valid && !hasException(i) && isMem(i) && thisCanActualOut(i) &&
io.enqLsq.canAccept && io.enqRoq.canAccept && io.toIntDq.canAccept && io.toFpDq.canAccept
XSDebug(io.toIntDq.req(i).valid, p"pc 0x${Hexadecimal(io.toIntDq.req(i).bits.cf.pc)} int index $i\n")
......
......@@ -22,13 +22,13 @@ class Dispatch2Fp extends XSModule {
* Part 1: generate indexes for reservation stations
*/
val fmacIndexGen = Module(new IndexMapping(dpParams.FpDqDeqWidth, exuParameters.FmacCnt, true))
val fmacCanAccept = VecInit(io.fromDq.map(deq => deq.valid && fmacExeUnitCfg.canAccept(deq.bits.ctrl.fuType)))
val fmacCanAccept = VecInit(io.fromDq.map(deq => deq.valid && FuType.fmacCanAccept(deq.bits.ctrl.fuType)))
val fmacPriority = PriorityGen((0 until exuParameters.FmacCnt).map(i => io.numExist(i)))
fmacIndexGen.io.validBits := fmacCanAccept
fmacIndexGen.io.priority := fmacPriority
val fmiscIndexGen = Module(new IndexMapping(dpParams.FpDqDeqWidth, exuParameters.FmiscCnt, true))
val fmiscCanAccept = VecInit(io.fromDq.map(deq => deq.valid && fmiscExeUnitCfg.canAccept(deq.bits.ctrl.fuType)))
val fmiscCanAccept = VecInit(io.fromDq.map(deq => deq.valid && FuType.fmiscCanAccept(deq.bits.ctrl.fuType)))
val fmiscPriority = PriorityGen((0 until exuParameters.FmiscCnt).map(i => io.numExist(i+exuParameters.FmacCnt)))
fmiscIndexGen.io.validBits := fmiscCanAccept
fmiscIndexGen.io.priority := fmiscPriority
......
......@@ -26,9 +26,9 @@ class Dispatch2Int extends XSModule {
* Part 1: generate indexes for reservation stations
*/
assert(jmpCnt == 1)
val jmpCanAccept = VecInit(io.fromDq.map(deq => deq.valid && jumpExeUnitCfg.canAccept(deq.bits.ctrl.fuType)))
val mduCanAccept = VecInit(io.fromDq.map(deq => deq.valid && mulDivExeUnitCfg.canAccept(deq.bits.ctrl.fuType)))
val aluCanAccept = VecInit(io.fromDq.map(deq => deq.valid && aluExeUnitCfg.canAccept(deq.bits.ctrl.fuType)))
val jmpCanAccept = VecInit(io.fromDq.map(deq => deq.valid && FuType.jmpCanAccept(deq.bits.ctrl.fuType)))
val mduCanAccept = VecInit(io.fromDq.map(deq => deq.valid && FuType.mduCanAccept(deq.bits.ctrl.fuType)))
val aluCanAccept = VecInit(io.fromDq.map(deq => deq.valid && FuType.aluCanAccept(deq.bits.ctrl.fuType)))
val jmpIndexGen = Module(new IndexMapping(dpParams.IntDqDeqWidth, jmpCnt, false))
val mduIndexGen = Module(new IndexMapping(dpParams.IntDqDeqWidth, mduCnt, true))
......
......@@ -13,8 +13,6 @@ class Dispatch2Ls extends XSModule {
val fromDq = Flipped(Vec(dpParams.LsDqDeqWidth, DecoupledIO(new MicroOp)))
val readIntRf = Vec(NRMemReadPorts, Output(UInt(PhyRegIdxWidth.W)))
val readFpRf = Vec(exuParameters.StuCnt, Output(UInt(PhyRegIdxWidth.W)))
// val intRegAddr = Vec(NRMemReadPorts, Output(UInt(PhyRegIdxWidth.W)))
// val fpRegAddr = Vec(exuParameters.StuCnt, Output(UInt(PhyRegIdxWidth.W)))
val readIntState = Vec(NRMemReadPorts, Flipped(new BusyTableReadIO))
val readFpState = Vec(exuParameters.StuCnt, Flipped(new BusyTableReadIO))
val numExist = Input(Vec(exuParameters.LsExuCnt, UInt(log2Ceil(IssQueSize).W)))
......@@ -25,13 +23,13 @@ class Dispatch2Ls extends XSModule {
* Part 1: generate indexes for reservation stations
*/
val loadIndexGen = Module(new IndexMapping(dpParams.LsDqDeqWidth, exuParameters.LduCnt, true))
val loadCanAccept = VecInit(io.fromDq.map(deq => deq.valid && ldExeUnitCfg.canAccept(deq.bits.ctrl.fuType)))
val loadCanAccept = VecInit(io.fromDq.map(deq => deq.valid && FuType.loadCanAccept(deq.bits.ctrl.fuType)))
val loadPriority = PriorityGen((0 until exuParameters.LduCnt).map(i => io.numExist(i)))
loadIndexGen.io.validBits := loadCanAccept
loadIndexGen.io.priority := loadPriority
val storeIndexGen = Module(new IndexMapping(dpParams.LsDqDeqWidth, exuParameters.StuCnt, true))
val storeCanAccept = VecInit(io.fromDq.map(deq => deq.valid && stExeUnitCfg.canAccept(deq.bits.ctrl.fuType)))
val storeCanAccept = VecInit(io.fromDq.map(deq => deq.valid && FuType.storeCanAccept(deq.bits.ctrl.fuType)))
val storePriority = PriorityGen((0 until exuParameters.StuCnt).map(i => io.numExist(i+exuParameters.LduCnt)))
storeIndexGen.io.validBits := storeCanAccept
storeIndexGen.io.priority := storePriority
......@@ -51,20 +49,26 @@ class Dispatch2Ls extends XSModule {
assert(exuParameters.LduCnt == 2)
assert(exuParameters.StuCnt == 2)
val readPort = Seq(0, 1, 2, 4)
val firstStorePsrc2 = PriorityMux(storeCanAccept, io.fromDq.map(_.bits.psrc2))
val secondStorePsrc2 = PriorityMux((1 until 4).map(i => Cat(storeCanAccept.take(i)).orR && storeCanAccept(i)), io.fromDq.drop(1).map(_.bits.psrc2))
for (i <- 0 until exuParameters.LsExuCnt) {
if (i < exuParameters.LduCnt) {
io.readIntRf(readPort(i)) := io.fromDq(indexVec(i)).bits.psrc1
io.readIntState(readPort(i)).req := io.fromDq(indexVec(i)).bits.psrc1
}
else {
io.readFpRf(i - exuParameters.LduCnt) := io.fromDq(indexVec(i)).bits.psrc2
io.readIntRf(readPort(i) ) := io.fromDq(indexVec(i)).bits.psrc1
io.readIntRf(readPort(i)+1) := io.fromDq(indexVec(i)).bits.psrc2
io.readFpState(i - exuParameters.LduCnt).req := io.fromDq(indexVec(i)).bits.psrc2
io.readIntState(readPort(i) ).req := io.fromDq(indexVec(i)).bits.psrc1
io.readIntState(readPort(i)+1).req := io.fromDq(indexVec(i)).bits.psrc2
}
}
// src1 always needs srcState but only store's src2 needs srcState
for (i <- 0 until 4) {
io.readIntState(i).req := io.fromDq(i).bits.psrc1
}
io.readIntState(4).req := firstStorePsrc2
io.readIntState(5).req := secondStorePsrc2
io.readFpState(0).req := firstStorePsrc2
io.readFpState(1).req := secondStorePsrc2
/**
* Part 3: dispatch to reservation stations
......@@ -80,13 +84,15 @@ class Dispatch2Ls extends XSModule {
enq.valid := storeIndexGen.io.mapping(i - exuParameters.LduCnt).valid && storeReady
}
enq.bits := io.fromDq(indexVec(i)).bits
enq.bits.src1State := io.readIntState(readPort(i)).resp
enq.bits.src1State := io.readIntState(indexVec(i)).resp
if (i < exuParameters.LduCnt) {
enq.bits.src2State := DontCare
}
else {
enq.bits.src2State := Mux(io.fromDq(indexVec(i)).bits.ctrl.src2Type === SrcType.fp,
io.readFpState(i - exuParameters.LduCnt).resp, io.readIntState(readPort(i) + 1).resp)
Mux(storePriority(i-2) === 0.U, io.readFpState(0).resp, io.readFpState(1).resp),
Mux(storePriority(i-2) === 0.U, io.readIntState(4).resp, io.readIntState(5).resp)
)
}
enq.bits.src3State := DontCare
......
......@@ -30,7 +30,7 @@ case class ExuParameters
def NRFuType = 9
def FuOpWidth = 7
def FuOpWidth = 6
}
case class ExuConfig
......
......@@ -30,6 +30,31 @@ class JumpExeUnit extends Exu(jumpExeUnitCfg)
val fencei = Output(Bool())
val sbuffer = new FenceToSbuffer
})
val difftestIO = IO(new Bundle() {
val fromCSR = new Bundle() {
val intrNO = Output(UInt(64.W))
val cause = Output(UInt(64.W))
val priviledgeMode = Output(UInt(2.W))
val mstatus = Output(UInt(64.W))
val sstatus = Output(UInt(64.W))
val mepc = Output(UInt(64.W))
val sepc = Output(UInt(64.W))
val mtval = Output(UInt(64.W))
val stval = Output(UInt(64.W))
val mtvec = Output(UInt(64.W))
val stvec = Output(UInt(64.W))
val mcause = Output(UInt(64.W))
val scause = Output(UInt(64.W))
val satp = Output(UInt(64.W))
val mip = Output(UInt(64.W))
val mie = Output(UInt(64.W))
val mscratch = Output(UInt(64.W))
val sscratch = Output(UInt(64.W))
val mideleg = Output(UInt(64.W))
val medeleg = Output(UInt(64.W))
}
})
difftestIO <> DontCare
val jmp = supportedFunctionUnits.collectFirst{
case j: Jump => j
......@@ -58,6 +83,10 @@ class JumpExeUnit extends Exu(jumpExeUnitCfg)
csr.csrio.externalInterrupt <> csrio.externalInterrupt
csr.csrio.tlb <> csrio.tlb
if (env.DualCoreDifftest) {
difftestIO.fromCSR <> csr.difftestIO
}
fenceio.sfence <> fence.sfence
fenceio.fencei <> fence.fencei
fenceio.sbuffer <> fence.toSbuffer
......
......@@ -145,6 +145,29 @@ class CSR extends FunctionUnit with HasCSRConst
// TLB
val tlb = Output(new TlbCsrBundle)
})
val difftestIO = IO(new Bundle() {
val intrNO = Output(UInt(64.W))
val cause = Output(UInt(64.W))
val priviledgeMode = Output(UInt(2.W))
val mstatus = Output(UInt(64.W))
val sstatus = Output(UInt(64.W))
val mepc = Output(UInt(64.W))
val sepc = Output(UInt(64.W))
val mtval = Output(UInt(64.W))
val stval = Output(UInt(64.W))
val mtvec = Output(UInt(64.W))
val stvec = Output(UInt(64.W))
val mcause = Output(UInt(64.W))
val scause = Output(UInt(64.W))
val satp = Output(UInt(64.W))
val mip = Output(UInt(64.W))
val mie = Output(UInt(64.W))
val mscratch = Output(UInt(64.W))
val sscratch = Output(UInt(64.W))
val mideleg = Output(UInt(64.W))
val medeleg = Output(UInt(64.W))
})
difftestIO <> DontCare
val cfIn = io.in.bits.uop.cf
val cfOut = Wire(new CtrlFlow)
......@@ -852,6 +875,8 @@ class CSR extends FunctionUnit with HasCSRConst
}
def readWithScala(addr: Int): UInt = mapping(addr)._1
val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U)
if (!env.FPGAPlatform) {
// display all perfcnt when nooptrap is executed
......@@ -862,7 +887,6 @@ class CSR extends FunctionUnit with HasCSRConst
}
}
val difftestIntrNO = Mux(raiseIntr, causeNO, 0.U)
ExcitingUtils.addSource(difftestIntrNO, "difftestIntrNOfromCSR")
ExcitingUtils.addSource(causeNO, "difftestCausefromCSR")
ExcitingUtils.addSource(priviledgeMode, "difftestMode", Debug)
......@@ -884,4 +908,27 @@ class CSR extends FunctionUnit with HasCSRConst
ExcitingUtils.addSource(mideleg, "difftestMideleg", Debug)
ExcitingUtils.addSource(medeleg, "difftestMedeleg", Debug)
}
if (env.DualCoreDifftest) {
difftestIO.intrNO := RegNext(difftestIntrNO)
difftestIO.cause := RegNext(causeNO)
difftestIO.priviledgeMode := priviledgeMode
difftestIO.mstatus := mstatus
difftestIO.sstatus := mstatus & sstatusRmask
difftestIO.mepc := mepc
difftestIO.sepc := sepc
difftestIO.mtval:= mtval
difftestIO.stval:= stval
difftestIO.mtvec := mtvec
difftestIO.stvec := stvec
difftestIO.mcause := mcause
difftestIO.scause := scause
difftestIO.satp := satp
difftestIO.mip := mipReg
difftestIO.mie := mie
difftestIO.mscratch := mscratch
difftestIO.sscratch := sscratch
difftestIO.mideleg := mideleg
difftestIO.medeleg := medeleg
}
}
......@@ -4,6 +4,22 @@ import chisel3._
import chisel3.util._
import xiangshan._
object hartIdRFInt extends (() => Int) {
var x = 0
def apply(): Int = {
x = x + 1
x-1
}
}
object hartIdRFFp extends (() => Int) {
var x = 0
def apply(): Int = {
x = x + 1
x-1
}
}
class RfReadPort(len: Int) extends XSBundle {
val addr = Input(UInt(PhyRegIdxWidth.W))
val data = Output(UInt(len.W))
......@@ -65,6 +81,29 @@ class Regfile
ExcitingUtils.Debug
)
}
if (env.DualCoreDifftest) {
val id = if (hasZero) hartIdRFInt() else hartIdRFFp()
val debugArchRat = WireInit(VecInit(Seq.fill(32)(0.U(PhyRegIdxWidth.W))))
ExcitingUtils.addSink(
debugArchRat,
if(hasZero) s"DEBUG_INI_ARCH_RAT$id" else s"DEBUG_FP_ARCH_RAT$id",
ExcitingUtils.Debug
)
val debugArchReg = WireInit(VecInit(debugArchRat.zipWithIndex.map(
x => if(hasZero){
if(x._2 == 0) 0.U else mem(x._1)
} else {
ieee(mem(x._1))
}
)))
ExcitingUtils.addSource(
debugArchReg,
if(hasZero) s"DEBUG_INT_ARCH_REG$id" else s"DEBUG_FP_ARCH_REG$id",
ExcitingUtils.Debug
)
}
} else {
val regfile = Module(new regfile_160x64_10w16r_sim)
......
......@@ -4,6 +4,7 @@ import chisel3._
import chisel3.util._
import xiangshan._
import utils._
import xiangshan.backend.roq.RoqPtr
class RenameBypassInfo extends XSBundle {
val lsrc1_bypass = MixedVec(List.tabulate(RenameWidth-1)(i => UInt((i+1).W)))
......@@ -12,7 +13,7 @@ class RenameBypassInfo extends XSBundle {
val ldest_bypass = MixedVec(List.tabulate(RenameWidth-1)(i => UInt((i+1).W)))
}
class Rename extends XSModule {
class Rename extends XSModule with HasCircularQueuePtrHelper {
val io = IO(new Bundle() {
val redirect = Flipped(ValidIO(new Redirect))
val roqCommits = Flipped(new RoqCommitIO)
......@@ -51,6 +52,7 @@ class Rename extends XSModule {
freelist.redirect := io.redirect
freelist.walk.valid := io.roqCommits.isWalk
}
val canOut = io.out(0).ready && fpFreeList.req.canAlloc && intFreeList.req.canAlloc && !io.roqCommits.isWalk
def needDestReg[T <: CfCtrl](fp: Boolean, x: T): Bool = {
{if(fp) x.ctrl.fpWen else x.ctrl.rfWen && (x.ctrl.ldest =/= 0.U)}
......@@ -64,6 +66,16 @@ class Rename extends XSModule {
fpFreeList.req.doAlloc := intFreeList.req.canAlloc && io.out(0).ready
intFreeList.req.doAlloc := fpFreeList.req.canAlloc && io.out(0).ready
// speculatively assign the instruction with an roqIdx
val validCount = PopCount(io.in.map(_.valid))
val roqIdxHead = RegInit(0.U.asTypeOf(new RoqPtr))
val lastCycleMisprediction = RegNext(io.redirect.valid && !io.redirect.bits.isUnconditional() && !io.redirect.bits.flushItself())
val roqIdxHeadNext = Mux(io.redirect.valid,
Mux(io.redirect.bits.isUnconditional(), 0.U.asTypeOf(new RoqPtr), io.redirect.bits.roqIdx),
Mux(lastCycleMisprediction, roqIdxHead + 1.U, Mux(canOut, roqIdxHead + validCount, roqIdxHead))
)
roqIdxHead := roqIdxHeadNext
/**
* Rename: allocate free physical register and update rename table
*/
......@@ -85,7 +97,6 @@ class Rename extends XSModule {
val needFpDest = Wire(Vec(RenameWidth, Bool()))
val needIntDest = Wire(Vec(RenameWidth, Bool()))
val hasValid = Cat(io.in.map(_.valid)).orR
val canOut = io.out(0).ready && fpFreeList.req.canAlloc && intFreeList.req.canAlloc && !io.roqCommits.isWalk
for (i <- 0 until RenameWidth) {
uops(i).cf := io.in(i).bits.cf
uops(i).ctrl := io.in(i).bits.ctrl
......@@ -114,6 +125,8 @@ class Rename extends XSModule {
)
)
uops(i).roqIdx := roqIdxHead + i.U
io.out(i).valid := io.in(i).valid && intFreeList.req.canAlloc && fpFreeList.req.canAlloc && !io.roqCommits.isWalk
io.out(i).bits := uops(i)
......
......@@ -15,6 +15,22 @@ class RatWritePort extends XSBundle {
val wdata = Input(UInt(PhyRegIdxWidth.W))
}
object hartIdRTInt extends (() => Int) {
var x = 0
def apply(): Int = {
x = x + 1
x-1
}
}
object hartIdRTFp extends (() => Int) {
var x = 0
def apply(): Int = {
x = x + 1
x-1
}
}
class RenameTable(float: Boolean) extends XSModule {
val io = IO(new Bundle() {
val redirect = Flipped(ValidIO(new Redirect))
......@@ -65,4 +81,13 @@ class RenameTable(float: Boolean) extends XSModule {
ExcitingUtils.Debug
)
}
if (env.DualCoreDifftest) {
val id = if (float) hartIdRTFp() else hartIdRTInt()
ExcitingUtils.addSource(
arch_table,
if(float) s"DEBUG_FP_ARCH_RAT$id" else s"DEBUG_INI_ARCH_RAT$id",
ExcitingUtils.Debug
)
}
}
......@@ -211,6 +211,20 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
val csr = new RoqCSRIO
})
val difftestIO = IO(new Bundle() {
val commit = Output(UInt(32.W))
val thisPC = Output(UInt(XLEN.W))
val thisINST = Output(UInt(32.W))
val skip = Output(UInt(32.W))
val wen = Output(UInt(32.W))
val wdata = Output(Vec(CommitWidth, UInt(XLEN.W))) // set difftest width to 6
val wdst = Output(Vec(CommitWidth, UInt(32.W))) // set difftest width to 6
val wpc = Output(Vec(CommitWidth, UInt(XLEN.W))) // set difftest width to 6
val isRVC = Output(UInt(32.W))
val scFailed = Output(Bool())
})
difftestIO <> DontCare
// instvalid field
// val valid = RegInit(VecInit(List.fill(RoqSize)(false.B)))
val valid = Mem(RoqSize, Bool())
......@@ -737,55 +751,55 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
instrCnt := instrCnt + retireCounter
io.csr.perfinfo.retiredInstr := RegNext(retireCounter)
if(!env.FPGAPlatform) {
//difftest signals
val firstValidCommit = (deqPtr + PriorityMux(io.commits.valid, VecInit(List.tabulate(CommitWidth)(_.U)))).value
val skip = Wire(Vec(CommitWidth, Bool()))
val wen = Wire(Vec(CommitWidth, Bool()))
val wdata = Wire(Vec(CommitWidth, UInt(XLEN.W)))
val wdst = Wire(Vec(CommitWidth, UInt(32.W)))
val diffTestDebugLrScValid = Wire(Vec(CommitWidth, Bool()))
val wpc = Wire(Vec(CommitWidth, UInt(XLEN.W)))
val trapVec = Wire(Vec(CommitWidth, Bool()))
val isRVC = Wire(Vec(CommitWidth, Bool()))
for(i <- 0 until CommitWidth){
// io.commits(i).valid
val idx = deqPtrVec(i).value
val uop = debug_microOp(idx)
val DifftestSkipSC = false
if(!DifftestSkipSC){
skip(i) := (debug_exuDebug(idx).isMMIO || debug_exuDebug(idx).isPerfCnt) && io.commits.valid(i)
}else{
skip(i) := (
debug_exuDebug(idx).isMMIO ||
debug_exuDebug(idx).isPerfCnt ||
uop.ctrl.fuType === FuType.mou && uop.ctrl.fuOpType === LSUOpType.sc_d ||
uop.ctrl.fuType === FuType.mou && uop.ctrl.fuOpType === LSUOpType.sc_w
) && io.commits.valid(i)
}
wen(i) := io.commits.valid(i) && uop.ctrl.rfWen && uop.ctrl.ldest =/= 0.U
wdata(i) := debug_exuData(idx)
wdst(i) := uop.ctrl.ldest
diffTestDebugLrScValid(i) := uop.diffTestDebugLrScValid
wpc(i) := SignExt(uop.cf.pc, XLEN)
trapVec(i) := io.commits.valid(i) && (state===s_idle) && uop.ctrl.isXSTrap
isRVC(i) := uop.cf.pd.isRVC
//difftest signals
val firstValidCommit = (deqPtr + PriorityMux(io.commits.valid, VecInit(List.tabulate(CommitWidth)(_.U)))).value
val skip = Wire(Vec(CommitWidth, Bool()))
val wen = Wire(Vec(CommitWidth, Bool()))
val wdata = Wire(Vec(CommitWidth, UInt(XLEN.W)))
val wdst = Wire(Vec(CommitWidth, UInt(32.W)))
val diffTestDebugLrScValid = Wire(Vec(CommitWidth, Bool()))
val wpc = Wire(Vec(CommitWidth, UInt(XLEN.W)))
val trapVec = Wire(Vec(CommitWidth, Bool()))
val isRVC = Wire(Vec(CommitWidth, Bool()))
for(i <- 0 until CommitWidth) {
// io.commits(i).valid
val idx = deqPtrVec(i).value
val uop = debug_microOp(idx)
val DifftestSkipSC = false
if(!DifftestSkipSC){
skip(i) := (debug_exuDebug(idx).isMMIO || debug_exuDebug(idx).isPerfCnt) && io.commits.valid(i)
}else{
skip(i) := (
debug_exuDebug(idx).isMMIO ||
debug_exuDebug(idx).isPerfCnt ||
uop.ctrl.fuType === FuType.mou && uop.ctrl.fuOpType === LSUOpType.sc_d ||
uop.ctrl.fuType === FuType.mou && uop.ctrl.fuOpType === LSUOpType.sc_w
) && io.commits.valid(i)
}
wen(i) := io.commits.valid(i) && uop.ctrl.rfWen && uop.ctrl.ldest =/= 0.U
wdata(i) := debug_exuData(idx)
wdst(i) := uop.ctrl.ldest
diffTestDebugLrScValid(i) := uop.diffTestDebugLrScValid
wpc(i) := SignExt(uop.cf.pc, XLEN)
trapVec(i) := io.commits.valid(i) && (state===s_idle) && uop.ctrl.isXSTrap
isRVC(i) := uop.cf.pd.isRVC
}
val retireCounterFix = Mux(io.redirectOut.valid, 1.U, retireCounter)
val retirePCFix = SignExt(Mux(io.redirectOut.valid, debug_deqUop.cf.pc, debug_microOp(firstValidCommit).cf.pc), XLEN)
val retireInstFix = Mux(io.redirectOut.valid, debug_deqUop.cf.instr, debug_microOp(firstValidCommit).cf.instr)
val scFailed = !diffTestDebugLrScValid(0) &&
debug_deqUop.ctrl.fuType === FuType.mou &&
(debug_deqUop.ctrl.fuOpType === LSUOpType.sc_d || debug_deqUop.ctrl.fuOpType === LSUOpType.sc_w)
val scFailed = !diffTestDebugLrScValid(0) &&
debug_deqUop.ctrl.fuType === FuType.mou &&
(debug_deqUop.ctrl.fuOpType === LSUOpType.sc_d || debug_deqUop.ctrl.fuOpType === LSUOpType.sc_w)
if (!env.FPGAPlatform) {
val difftestIntrNO = WireInit(0.U(XLEN.W))
val difftestCause = WireInit(0.U(XLEN.W))
ExcitingUtils.addSink(difftestIntrNO, "difftestIntrNOfromCSR")
ExcitingUtils.addSink(difftestCause, "difftestCausefromCSR")
XSDebug(difftestIntrNO =/= 0.U, "difftest intrNO set %x\n", difftestIntrNO)
val retireCounterFix = Mux(io.redirectOut.valid, 1.U, retireCounter)
val retirePCFix = SignExt(Mux(io.redirectOut.valid, debug_deqUop.cf.pc, debug_microOp(firstValidCommit).cf.pc), XLEN)
val retireInstFix = Mux(io.redirectOut.valid, debug_deqUop.cf.instr, debug_microOp(firstValidCommit).cf.instr)
ExcitingUtils.addSource(RegNext(retireCounterFix), "difftestCommit", ExcitingUtils.Debug)
ExcitingUtils.addSource(RegNext(retirePCFix), "difftestThisPC", ExcitingUtils.Debug)//first valid PC
......@@ -814,4 +828,17 @@ class Roq(numWbPorts: Int) extends XSModule with HasCircularQueuePtrHelper {
ExcitingUtils.addSource(hitTrap, "XSTRAP", ConnectionType.Debug)
}
}
if (env.DualCoreDifftest) {
difftestIO.commit := RegNext(retireCounterFix)
difftestIO.thisPC := RegNext(retirePCFix)
difftestIO.thisINST := RegNext(retireInstFix)
difftestIO.skip := RegNext(skip.asUInt)
difftestIO.wen := RegNext(wen.asUInt)
difftestIO.wdata := RegNext(wdata)
difftestIO.wdst := RegNext(wdst)
difftestIO.wpc := RegNext(wpc)
difftestIO.isRVC := RegNext(isRVC.asUInt)
difftestIO.scFailed := RegNext(scFailed)
}
}
......@@ -167,7 +167,7 @@ class RecentRequestTable(p: BOPParameters) extends PrefetchModule {
rrTable.io.r.req.bits.setIdx := idx(rAddr)
rData := rrTable.io.r.resp.data(0)
val rwConflict = io.w.fire() && io.r.req.fire() && idx(wAddr) === idx(rAddr)
val rwConflict = io.w.fire() && io.r.req.fire()// && idx(wAddr) === idx(rAddr)
// when (rwConflict) {
// rrTable.io.r.req.valid := false.B
// }
......@@ -295,7 +295,7 @@ class OffsetScoreTable(p: BOPParameters) extends PrefetchModule {
XSDebug(io.req.fire(), p"receive req from L1. io.req.bits=0x${Hexadecimal(io.req.bits)}\n")
}
class BestOffsetPrefetchEntry(p: BOPParameters) extends PrefetchModule {
class BestOffsetPrefetchEntry(p: BOPParameters) extends PrefetchModule with HasTlbConst {
val io = IO(new Bundle {
val id = Input(UInt(p.totalWidth.W))
val prefetchOffset = Input(UInt(p.offsetWidth.W))
......@@ -305,19 +305,27 @@ class BestOffsetPrefetchEntry(p: BOPParameters) extends PrefetchModule {
})
def blockBytes = p.blockBytes
def getBlockAddr(addr: UInt) = Cat(addr(PAddrBits - 1, log2Up(blockBytes)), 0.U(log2Up(blockBytes).W))
def getBlock(addr: UInt) = addr(PAddrBits - 1, log2Up(blockBytes))
def getBlockAddr(addr: UInt) = Cat(getBlock(addr), 0.U(log2Up(blockBytes).W))
def getPageNum(addr: UInt) = addr(PAddrBits - 1, offLen)
val s_idle :: s_req :: s_resp :: s_write_recent_req :: s_finish :: Nil = Enum(5)
val state = RegInit(s_idle)
val req = RegInit(0.U.asTypeOf(new PrefetchReq))
val baseAddr = RegInit(0.U(PAddrBits.W))
val baseBlock = getBlock(io.pft.train.bits.addr)
val nextBlock = baseBlock + io.prefetchOffset
val nextAddr = Cat(nextBlock, 0.U(log2Up(blockBytes).W))
val crossPage = getPageNum(nextAddr) =/= getPageNum(io.pft.train.bits.addr)
when (state === s_idle) {
when (io.pft.train.valid) {
state := s_req
req.addr := getBlockAddr(io.pft.train.bits.addr) + (io.prefetchOffset << log2Up(blockBytes))
// state := s_req
state := Mux(crossPage, s_idle, s_req)
req.addr := nextAddr
req.write := io.pft.train.bits.write
baseAddr := getBlockAddr(io.pft.train.bits.addr)
XSDebug(crossPage, p"prefetch addr 0x${nextAddr} cross page, ignore this!\n")
}
}
......@@ -357,7 +365,7 @@ class BestOffsetPrefetchEntry(p: BOPParameters) extends PrefetchModule {
io.writeRRTable.valid := state === s_write_recent_req
io.writeRRTable.bits := baseAddr // write this into recent request table
XSDebug(p"bopEntry ${io.id}: state=${state} prefetchOffset=${io.prefetchOffset} inflight=${io.inflight.valid} 0x${Hexadecimal(io.inflight.bits)} writeRRTable: ${io.writeRRTable.valid} 0x${Hexadecimal(io.writeRRTable.bits)} baseAddr=0x${Hexadecimal(baseAddr)} req: ${req}\n")
XSDebug(p"bopEntry ${io.id}: state=${state} prefetchOffset=${io.prefetchOffset} inflight=${io.inflight.valid} 0x${Hexadecimal(io.inflight.bits)} writeRRTable: ${io.writeRRTable.valid} 0x${Hexadecimal(io.writeRRTable.bits)} baseAddr=0x${Hexadecimal(baseAddr)} nextAddr=0x${Hexadecimal(nextAddr)} crossPage=${crossPage} req: ${req}\n")
XSDebug(p"bopEntry ${io.id}: io.pft: ${io.pft}\n")
}
......
......@@ -85,7 +85,7 @@ class StreamBufferAlloc(p: StreamPrefetchParameters) extends StreamPrefetchReq(p
}
class StreamBuffer(p: StreamPrefetchParameters) extends PrefetchModule {
class StreamBuffer(p: StreamPrefetchParameters) extends PrefetchModule with HasTlbConst {
val io = IO(new Bundle {
val streamBufId = Input(UInt(log2Up(streamCnt).W))
val addrs = Vec(p.streamSize, ValidIO(UInt(PAddrBits.W)))
......@@ -102,6 +102,7 @@ class StreamBuffer(p: StreamPrefetchParameters) extends PrefetchModule {
def blockBytes = p.blockBytes
// def getBlockAddr(addr: UInt) = addr & ~((blockBytes - 1).U(addr.getWidth.W))
def getBlockAddr(addr: UInt) = Cat(addr(PAddrBits - 1, log2Up(p.blockBytes)), 0.U(log2Up(p.blockBytes).W))
def getPageNum(addr: UInt) = addr(PAddrBits - 1, offLen)
val baseReq = RegInit(0.U.asTypeOf(Valid(new PrefetchReq)))
val nextReq = RegInit(0.U.asTypeOf(new PrefetchReq))
......@@ -163,11 +164,17 @@ class StreamBuffer(p: StreamPrefetchParameters) extends PrefetchModule {
}
// enqueue
val nextAddrCrossPage = getPageNum(baseReq.bits.addr) =/= getPageNum(nextReq.addr)
when (!full && baseReq.valid && !needRealloc) {
state(tail) := s_req
tail := tail + 1.U
buf(tail) := nextReq
nextReq.addr := nextReq.addr + blockBytes.U
when (!nextAddrCrossPage) {
state(tail) := s_req
tail := tail + 1.U
buf(tail) := nextReq
nextReq.addr := nextReq.addr + blockBytes.U
XSDebug(p"enqueue 0x${nextReq.addr}\n")
}.otherwise {
XSDebug(p"addr 0x${nextReq.addr} could not enqueue for crossing pages\n")
}
}
val reqs = Wire(Vec(streamSize, Decoupled(new StreamPrefetchReq(p))))
......@@ -259,7 +266,7 @@ class StreamBuffer(p: StreamPrefetchParameters) extends PrefetchModule {
p"deqLater: ${deqLater(i)} deqValid: ${deqValid(i)}\n")
}
XSDebug(s"${p.cacheName} " + p"StreamBuf ${io.streamBufId} head: ${head} tail: ${tail} full: ${full} empty: ${empty} nextHead: ${nextHead} blockBytes: ${blockBytes.U}\n")
XSDebug(s"${p.cacheName} " + p"StreamBuf ${io.streamBufId} baseReq: v=${baseReq.valid} ${baseReq.bits} nextReq: ${nextReq}\n")
XSDebug(s"${p.cacheName} " + p"StreamBuf ${io.streamBufId} baseReq: v=${baseReq.valid} ${baseReq.bits} nextReq: ${nextReq} crossPage: ${nextAddrCrossPage}\n")
XSDebug(needRealloc, s"${p.cacheName} " + p"StreamBuf ${io.streamBufId} needRealloc: ${needRealloc} reallocReq: ${reallocReq}\n")
XSDebug(s"${p.cacheName} " + p"StreamBuf ${io.streamBufId} prefetchPrior: ")
(0 until streamSize).foreach(i => XSDebug(false, true.B, p"${prefetchPrior(i)} "))
......@@ -312,38 +319,40 @@ class StreamPrefetch(p: StreamPrefetchParameters) extends PrefetchModule {
// 1. streamBufs hit while l1i miss
val hit = WireInit(false.B)
val hitVec = WireInit(VecInit(Seq.fill(streamCnt * streamSize)(false.B)))
for (i <- 0 until streamCnt) {
for (j <- 0 until streamSize) {
when (io.train.valid && addrValids(i)(j) && getBlockAddr(io.train.bits.addr) === streamBufs(i).io.addrs(j).bits) {
hit := true.B
// hit := true.B
hitVec(i*streamSize+j) := true.B
streamBufs(i).io.update.valid := true.B
streamBufs(i).io.update.bits.hitIdx := j.U
ages(i) := maxAge
}
}
}
hit := ParallelOR(hitVec)
// 2. streamBufs miss
val allocIdx = Wire(UInt(log2Up(streamCnt).W))
val ageCmp = Seq.fill(streamCnt)(Wire(new CompareBundle(ageWidth)))
(0 until streamCnt).foreach(i => ageCmp(i).bits := ages(i))
(0 until streamCnt).foreach(i => ageCmp(i).idx := i.U)
when ((~bufValids.asUInt).orR) {
allocIdx := PriorityMux(~bufValids.asUInt, VecInit(List.tabulate(streamCnt)(_.U)))
}.otherwise {
allocIdx := ParallelMin(ageCmp).idx
}
when (!hit && io.train.valid) {
(0 until streamCnt).foreach(i => ages(i) := Mux(ages(i) =/= 0.U, ages(i) - 1.U, 0.U))
// realloc an invalid or the eldest stream buffer with new one
val idx = Wire(UInt(log2Up(streamCnt).W))
when ((~bufValids.asUInt).orR) {
idx := PriorityMux(~bufValids.asUInt, VecInit(List.tabulate(streamCnt)(_.U)))
}.otherwise {
val ageCmp = Seq.fill(streamCnt)(Wire(new CompareBundle(ageWidth)))
(0 until streamCnt).foreach(i => ageCmp(i).bits := ages(i))
(0 until streamCnt).foreach(i => ageCmp(i).idx := i.U)
idx := ParallelMin(ageCmp).idx
}
for (i <- 0 until streamCnt) {
streamBufs(i).io.alloc.valid := idx === i.U
streamBufs(i).io.alloc.valid := allocIdx === i.U
streamBufs(i).io.alloc.bits := DontCare
streamBufs(i).io.alloc.bits.addr := io.train.bits.addr
streamBufs(i).io.alloc.bits.write := io.train.bits.write
when (idx === i.U) { ages(i) := maxAge }
when (allocIdx === i.U) { ages(i) := maxAge }
}
}
......
......@@ -41,6 +41,7 @@ class LsqWrappper extends XSModule with HasDCacheParameters {
val brqRedirect = Input(Valid(new Redirect))
val loadIn = Vec(LoadPipelineWidth, Flipped(Valid(new LsPipelineBundle)))
val storeIn = Vec(StorePipelineWidth, Flipped(Valid(new LsPipelineBundle)))
val loadDataForwarded = Vec(LoadPipelineWidth, Input(Bool()))
val sbuffer = Vec(StorePipelineWidth, Decoupled(new DCacheWordReq))
val ldout = Vec(2, DecoupledIO(new ExuOutput)) // writeback int load
val mmioStout = DecoupledIO(new ExuOutput) // writeback uncached store
......@@ -53,6 +54,15 @@ class LsqWrappper extends XSModule with HasDCacheParameters {
val exceptionAddr = new ExceptionAddrIO
val sqempty = Output(Bool())
})
val difftestIO = IO(new Bundle() {
val fromSQ = new Bundle() {
val storeCommit = Output(UInt(2.W))
val storeAddr = Output(Vec(2, UInt(64.W)))
val storeData = Output(Vec(2, UInt(64.W)))
val storeMask = Output(Vec(2, UInt(8.W)))
}
})
difftestIO <> DontCare
val loadQueue = Module(new LoadQueue)
val storeQueue = Module(new StoreQueue)
......@@ -82,6 +92,7 @@ class LsqWrappper extends XSModule with HasDCacheParameters {
loadQueue.io.brqRedirect <> io.brqRedirect
loadQueue.io.loadIn <> io.loadIn
loadQueue.io.storeIn <> io.storeIn
loadQueue.io.loadDataForwarded <> io.loadDataForwarded
loadQueue.io.ldout <> io.ldout
loadQueue.io.commits <> io.commits
loadQueue.io.rollback <> io.rollback
......@@ -106,6 +117,10 @@ class LsqWrappper extends XSModule with HasDCacheParameters {
storeQueue.io.sqempty <> io.sqempty
if (env.DualCoreDifftest) {
difftestIO.fromSQ <> storeQueue.difftestIO
}
io.exceptionAddr.vaddr := Mux(io.exceptionAddr.isStore, storeQueue.io.exceptionAddr.vaddr, loadQueue.io.exceptionAddr.vaddr)
// naive uncache arbiter
......
......@@ -66,6 +66,7 @@ class LoadQueue extends XSModule
val brqRedirect = Input(Valid(new Redirect))
val loadIn = Vec(LoadPipelineWidth, Flipped(Valid(new LsPipelineBundle)))
val storeIn = Vec(StorePipelineWidth, Flipped(Valid(new LsPipelineBundle)))
val loadDataForwarded = Vec(LoadPipelineWidth, Input(Bool()))
val ldout = Vec(2, DecoupledIO(new ExuOutput)) // writeback int load
val load_s1 = Vec(LoadPipelineWidth, Flipped(new LoadForwardQueryIO))
val commits = Flipped(new RoqCommitIO)
......@@ -85,7 +86,6 @@ class LoadQueue extends XSModule
val allocated = RegInit(VecInit(List.fill(LoadQueueSize)(false.B))) // lq entry has been allocated
val datavalid = RegInit(VecInit(List.fill(LoadQueueSize)(false.B))) // data is valid
val writebacked = RegInit(VecInit(List.fill(LoadQueueSize)(false.B))) // inst has been writebacked to CDB
val commited = Reg(Vec(LoadQueueSize, Bool())) // inst has been writebacked to CDB
val miss = Reg(Vec(LoadQueueSize, Bool())) // load inst missed, waiting for miss queue to accept miss request
// val listening = Reg(Vec(LoadQueueSize, Bool())) // waiting for refill result
val pending = Reg(Vec(LoadQueueSize, Bool())) // mmio pending: inst is an mmio inst, it will not be executed until it reachs the end of roq
......@@ -95,7 +95,6 @@ class LoadQueue extends XSModule
val enqPtrExt = RegInit(VecInit((0 until RenameWidth).map(_.U.asTypeOf(new LqPtr))))
val deqPtrExt = RegInit(0.U.asTypeOf(new LqPtr))
val deqPtrExtNext = Wire(new LqPtr)
val validCounter = RegInit(0.U(log2Ceil(LoadQueueSize + 1).W))
val allowEnqueue = RegInit(true.B)
val enqPtr = enqPtrExt(0).value
......@@ -127,7 +126,6 @@ class LoadQueue extends XSModule
allocated(index) := true.B
datavalid(index) := false.B
writebacked(index) := false.B
commited(index) := false.B
miss(index) := false.B
// listening(index) := false.B
pending(index) := false.B
......@@ -177,13 +175,13 @@ class LoadQueue extends XSModule
io.loadIn(i).bits.mmio
)}
val loadWbIndex = io.loadIn(i).bits.uop.lqIdx.value
datavalid(loadWbIndex) := !io.loadIn(i).bits.miss && !io.loadIn(i).bits.mmio
datavalid(loadWbIndex) := (!io.loadIn(i).bits.miss || io.loadDataForwarded(i)) && !io.loadIn(i).bits.mmio
writebacked(loadWbIndex) := !io.loadIn(i).bits.miss && !io.loadIn(i).bits.mmio
val loadWbData = Wire(new LQDataEntry)
loadWbData.paddr := io.loadIn(i).bits.paddr
loadWbData.mask := io.loadIn(i).bits.mask
loadWbData.data := io.loadIn(i).bits.data // fwd data
loadWbData.data := io.loadIn(i).bits.forwardData.asUInt // fwd data
loadWbData.fwdMask := io.loadIn(i).bits.forwardMask
dataModule.io.wbWrite(i, loadWbIndex, loadWbData)
dataModule.io.wb.wen(i) := true.B
......@@ -195,7 +193,7 @@ class LoadQueue extends XSModule
debug_mmio(loadWbIndex) := io.loadIn(i).bits.mmio
val dcacheMissed = io.loadIn(i).bits.miss && !io.loadIn(i).bits.mmio
miss(loadWbIndex) := dcacheMissed
miss(loadWbIndex) := dcacheMissed && !io.loadDataForwarded(i)
pending(loadWbIndex) := io.loadIn(i).bits.mmio
uop(loadWbIndex).debugInfo.issueTime := io.loadIn(i).bits.uop.debugInfo.issueTime
}
......@@ -554,7 +552,7 @@ class LoadQueue extends XSModule
// invalidate lq term using robIdx
val needCancel = Wire(Vec(LoadQueueSize, Bool()))
for (i <- 0 until LoadQueueSize) {
needCancel(i) := uop(i).roqIdx.needFlush(io.brqRedirect) && allocated(i) && !commited(i)
needCancel(i) := uop(i).roqIdx.needFlush(io.brqRedirect) && allocated(i)
when (needCancel(i)) {
allocated(i) := false.B
}
......@@ -578,19 +576,9 @@ class LoadQueue extends XSModule
deqPtrExt := deqPtrExtNext
val lastLastCycleRedirect = RegNext(lastCycleRedirect.valid)
val trueValidCounter = distanceBetween(enqPtrExt(0), deqPtrExt)
validCounter := Mux(lastLastCycleRedirect,
trueValidCounter,
validCounter + enqNumber - commitCount
)
allowEnqueue := Mux(io.brqRedirect.valid,
false.B,
Mux(lastLastCycleRedirect,
trueValidCounter <= (LoadQueueSize - RenameWidth).U,
validCounter + enqNumber <= (LoadQueueSize - RenameWidth).U
)
)
val validCount = distanceBetween(enqPtrExt(0), deqPtrExt)
allowEnqueue := validCount + enqNumber <= (LoadQueueSize - RenameWidth).U
// debug info
XSDebug("enqPtrExt %d:%d deqPtrExt %d:%d\n", enqPtrExt(0).flag, enqPtr, deqPtrExt.flag, deqPtr)
......@@ -609,7 +597,6 @@ class LoadQueue extends XSModule
PrintFlag(allocated(i), "a")
PrintFlag(allocated(i) && datavalid(i), "v")
PrintFlag(allocated(i) && writebacked(i), "w")
PrintFlag(allocated(i) && commited(i), "c")
PrintFlag(allocated(i) && miss(i), "m")
// PrintFlag(allocated(i) && listening(i), "l")
PrintFlag(allocated(i) && pending(i), "p")
......
......@@ -106,6 +106,51 @@ class MaskModule(numEntries: Int, numRead: Int, numWrite: Int) extends XSModule
}
}
class Data8Module(numEntries: Int, numRead: Int, numWrite: Int) extends XSModule with HasDCacheParameters {
val io = IO(new Bundle {
// read
val raddr = Input(Vec(numRead, UInt(log2Up(numEntries).W)))
val rdata = Output(Vec(numRead, UInt(8.W)))
// address indexed write
val wen = Input(Vec(numWrite, Bool()))
val waddr = Input(Vec(numWrite, UInt(log2Up(numEntries).W)))
val wdata = Input(Vec(numWrite, UInt(8.W)))
// masked write
val mwmask = Input(Vec(blockWords, Vec(numEntries, Bool())))
val mwdata = Input(Vec(blockWords, UInt(8.W)))
})
val data = Reg(Vec(numEntries, UInt(8.W)))
// read ports
for (i <- 0 until numRead) {
io.rdata(i) := data(RegNext(io.raddr(i)))
}
// below is the write ports (with priorities)
for (i <- 0 until numWrite) {
when (io.wen(i)) {
data(io.waddr(i)) := io.wdata(i)
}
}
// masked write
for (i <- 0 until blockWords) {
for (j <- 0 until numEntries) {
when (io.mwmask(i)(j)) {
data(j) := io.mwdata(i)
}
}
}
// DataModuleTemplate should not be used when there're any write conflicts
for (i <- 0 until numWrite) {
for (j <- i+1 until numWrite) {
assert(!(io.wen(i) && io.wen(j) && io.waddr(i) === io.waddr(j)))
}
}
}
class CoredataModule(numEntries: Int, numRead: Int, numWrite: Int) extends XSModule with HasDCacheParameters {
val io = IO(new Bundle {
// data io
......@@ -131,20 +176,28 @@ class CoredataModule(numEntries: Int, numRead: Int, numWrite: Int) extends XSMod
val paddrWen = Input(Vec(numWrite, Bool()))
})
val data = Reg(Vec(numEntries, UInt(XLEN.W)))
val data8 = Seq.fill(8)(Module(new Data8Module(numEntries, numRead, numWrite)))
val fwdMask = Reg(Vec(numEntries, UInt(8.W)))
val wordIndex = Reg(Vec(numEntries, UInt((blockOffBits - wordOffBits).W)))
// read ports
for (i <- 0 until numRead) {
io.rdata(i) := data(RegNext(io.raddr(i)))
for (j <- 0 until 8) {
data8(j).io.raddr(i) := io.raddr(i)
}
io.rdata(i) := VecInit((0 until 8).map(j => data8(j).io.rdata(i))).asUInt
}
// below is the write ports (with priorities)
for (i <- 0 until numWrite) {
when (io.wen(i)) {
data(io.waddr(i)) := io.wdata(i)
// write to data8
for (j <- 0 until 8) {
data8(j).io.waddr(i) := io.waddr(i)
data8(j).io.wdata(i) := io.wdata(i)(8*(j+1)-1, 8*j)
data8(j).io.wen(i) := io.wen(i)
}
// write ctrl info
when (io.fwdMaskWen(i)) {
fwdMask(io.waddr(i)) := io.fwdMaskWdata(i)
}
......@@ -153,25 +206,25 @@ class CoredataModule(numEntries: Int, numRead: Int, numWrite: Int) extends XSMod
}
}
// write refilled data to data8
// masked write
// refill missed load
def mergeRefillData(refill: UInt, fwd: UInt, fwdMask: UInt): UInt = {
val res = Wire(Vec(8, UInt(8.W)))
(0 until 8).foreach(i => {
res(i) := Mux(fwdMask(i), fwd(8 * (i + 1) - 1, 8 * i), refill(8 * (i + 1) - 1, 8 * i))
})
res.asUInt
}
// select refill data
// split dcache result into words
val words = VecInit((0 until blockWords) map { i => io.refillData(DataBits * (i + 1) - 1, DataBits * i)})
// select refill data according to wordIndex (paddr)
for (i <- 0 until 8) {
for (j <- 0 until blockWords) {
data8(i).io.mwdata(j) := words(j)(8*(i+1)-1, 8*i)
}
}
// refill data according to matchMask, refillMask and refill.vald
for (j <- 0 until numEntries) {
when (io.mwmask(j)) {
val refillData = words(wordIndex(j)) // TODO
data(j) := mergeRefillData(refillData, data(j), fwdMask(j))
// gen refill wmask
for (j <- 0 until blockWords) {
for (k <- 0 until numEntries) {
val wordMatch = wordIndex(k) === j.U
for (i <- 0 until 8) {
data8(i).io.mwmask(j)(k) := wordMatch && io.mwmask(k) && !fwdMask(k)(i)
}
}
}
......
......@@ -46,11 +46,21 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
val sqempty = Output(Bool())
})
val difftestIO = IO(new Bundle() {
val storeCommit = Output(UInt(2.W))
val storeAddr = Output(Vec(2, UInt(64.W)))
val storeData = Output(Vec(2, UInt(64.W)))
val storeMask = Output(Vec(2, UInt(8.W)))
})
difftestIO <> DontCare
// data modules
val uop = Reg(Vec(StoreQueueSize, new MicroOp))
// val data = Reg(Vec(StoreQueueSize, new LsqEntry))
val dataModule = Module(new StoreQueueData(StoreQueueSize, numRead = StorePipelineWidth, numWrite = StorePipelineWidth, numForward = StorePipelineWidth))
dataModule.io := DontCare
val paddrModule = Module(new SQPaddrModule(StoreQueueSize, numRead = StorePipelineWidth, numWrite = StorePipelineWidth, numForward = StorePipelineWidth))
paddrModule.io := DontCare
val vaddrModule = Module(new AsyncDataModuleTemplate(UInt(VAddrBits.W), StoreQueueSize, numRead = 1, numWrite = StorePipelineWidth))
vaddrModule.io := DontCare
......@@ -66,7 +76,6 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
require(StoreQueueSize > RenameWidth)
val enqPtrExt = RegInit(VecInit((0 until RenameWidth).map(_.U.asTypeOf(new SqPtr))))
val deqPtrExt = RegInit(VecInit((0 until StorePipelineWidth).map(_.U.asTypeOf(new SqPtr))))
val validCounter = RegInit(0.U(log2Ceil(LoadQueueSize + 1).W))
val allowEnqueue = RegInit(true.B)
val enqPtr = enqPtrExt(0).value
......@@ -86,9 +95,9 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
deqPtrExt
)
))
val dataModuleRead = dataModule.io.rdata
for (i <- 0 until StorePipelineWidth) {
dataModule.io.raddr(i) := deqPtrExtNext(i).value
paddrModule.io.raddr(i) := deqPtrExtNext(i).value
}
vaddrModule.io.raddr(0) := io.exceptionAddr.lsIdx.sqIdx.value
......@@ -129,6 +138,7 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
*/
for (i <- 0 until StorePipelineWidth) {
dataModule.io.wen(i) := false.B
paddrModule.io.wen(i) := false.B
vaddrModule.io.wen(i) := false.B
when (io.storeIn(i).fire()) {
val stWbIndex = io.storeIn(i).bits.uop.sqIdx.value
......@@ -138,13 +148,17 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
val storeWbData = Wire(new SQDataEntry)
storeWbData := DontCare
storeWbData.paddr := io.storeIn(i).bits.paddr
storeWbData.mask := io.storeIn(i).bits.mask
storeWbData.data := io.storeIn(i).bits.data
dataModule.io.waddr(i) := stWbIndex
dataModule.io.wdata(i) := storeWbData
dataModule.io.wen(i) := true.B
paddrModule.io.waddr(i) := stWbIndex
paddrModule.io.wdata(i) := io.storeIn(i).bits.paddr
paddrModule.io.wen(i) := true.B
vaddrModule.io.waddr(i) := stWbIndex
vaddrModule.io.wdata(i) := io.storeIn(i).bits.vaddr
vaddrModule.io.wen(i) := true.B
......@@ -193,15 +207,13 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
)
// do real fwd query
dataModule.io.forwardQuery(
numForward = i,
paddr = io.forward(i).paddr,
needForward1 = needForward1,
needForward2 = needForward2
)
dataModule.io.needForward(i)(0) := needForward1 & paddrModule.io.forwardMmask(i).asUInt
dataModule.io.needForward(i)(1) := needForward2 & paddrModule.io.forwardMmask(i).asUInt
paddrModule.io.forwardMdata(i) := io.forward(i).paddr
io.forward(i).forwardMask := dataModule.io.forward(i).forwardMask
io.forward(i).forwardData := dataModule.io.forward(i).forwardData
io.forward(i).forwardMask := dataModule.io.forwardMask(i)
io.forward(i).forwardData := dataModule.io.forwardData(i)
}
/**
......@@ -221,13 +233,13 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
!io.commits.isWalk
io.uncache.req.bits.cmd := MemoryOpConstants.M_XWR
io.uncache.req.bits.addr := dataModule.io.rdata(0).paddr // data(deqPtr) -> rdata(0)
io.uncache.req.bits.addr := paddrModule.io.rdata(0) // data(deqPtr) -> rdata(0)
io.uncache.req.bits.data := dataModule.io.rdata(0).data
io.uncache.req.bits.mask := dataModule.io.rdata(0).mask
io.uncache.req.bits.meta.id := DontCare
io.uncache.req.bits.meta.vaddr := DontCare
io.uncache.req.bits.meta.paddr := dataModule.io.rdata(0).paddr
io.uncache.req.bits.meta.paddr := paddrModule.io.rdata(0)
io.uncache.req.bits.meta.uop := uop(deqPtr)
io.uncache.req.bits.meta.mmio := true.B
io.uncache.req.bits.meta.tlb_miss := false.B
......@@ -256,7 +268,7 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
io.mmioStout.valid := allocated(deqPtr) && datavalid(deqPtr) && !writebacked(deqPtr)
io.mmioStout.bits.uop := uop(deqPtr)
io.mmioStout.bits.uop.sqIdx := deqPtrExt(0)
io.mmioStout.bits.data := dataModuleRead(0).data // dataModuleRead.read(deqPtr)
io.mmioStout.bits.data := dataModule.io.rdata(0).data // dataModule.io.rdata.read(deqPtr)
io.mmioStout.bits.redirectValid := false.B
io.mmioStout.bits.redirect := DontCare
io.mmioStout.bits.debug.isMMIO := true.B
......@@ -290,9 +302,9 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
// if sbuffer.fire(), read next
io.sbuffer(i).valid := allocated(ptr) && commited(ptr) && !mmio(ptr)
io.sbuffer(i).bits.cmd := MemoryOpConstants.M_XWR
io.sbuffer(i).bits.addr := dataModuleRead(i).paddr
io.sbuffer(i).bits.data := dataModuleRead(i).data
io.sbuffer(i).bits.mask := dataModuleRead(i).mask
io.sbuffer(i).bits.addr := paddrModule.io.rdata(i)
io.sbuffer(i).bits.data := dataModule.io.rdata(i).data
io.sbuffer(i).bits.mask := dataModule.io.rdata(i).mask
io.sbuffer(i).bits.meta := DontCare
io.sbuffer(i).bits.meta.tlb_miss := false.B
io.sbuffer(i).bits.meta.uop := DontCare
......@@ -308,17 +320,23 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
assert(io.sbuffer(0).fire())
}
if (!env.FPGAPlatform) {
val storeCommit = PopCount(io.sbuffer.map(_.fire()))
val waddr = VecInit(io.sbuffer.map(req => SignExt(req.bits.addr, 64)))
val wdata = VecInit(io.sbuffer.map(req => req.bits.data & MaskExpand(req.bits.mask)))
val wmask = VecInit(io.sbuffer.map(_.bits.mask))
val storeCommit = PopCount(io.sbuffer.map(_.fire()))
val waddr = VecInit(io.sbuffer.map(req => SignExt(req.bits.addr, 64)))
val wdata = VecInit(io.sbuffer.map(req => req.bits.data & MaskExpand(req.bits.mask)))
val wmask = VecInit(io.sbuffer.map(_.bits.mask))
if (!env.FPGAPlatform) {
ExcitingUtils.addSource(RegNext(storeCommit), "difftestStoreCommit", ExcitingUtils.Debug)
ExcitingUtils.addSource(RegNext(waddr), "difftestStoreAddr", ExcitingUtils.Debug)
ExcitingUtils.addSource(RegNext(wdata), "difftestStoreData", ExcitingUtils.Debug)
ExcitingUtils.addSource(RegNext(wmask), "difftestStoreMask", ExcitingUtils.Debug)
}
if (env.DualCoreDifftest) {
difftestIO.storeCommit := RegNext(storeCommit)
difftestIO.storeAddr := RegNext(waddr)
difftestIO.storeData := RegNext(wdata)
difftestIO.storeMask := RegNext(wmask)
}
// Read vaddr for mem exception
io.exceptionAddr.vaddr := vaddrModule.io.rdata(0)
......@@ -351,19 +369,9 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
val lastLastCycleRedirect = RegNext(lastCycleRedirect)
val dequeueCount = Mux(io.sbuffer(1).fire(), 2.U, Mux(io.sbuffer(0).fire() || io.mmioStout.fire(), 1.U, 0.U))
val trueValidCounter = distanceBetween(enqPtrExt(0), deqPtrExt(0))
validCounter := Mux(lastLastCycleRedirect,
trueValidCounter - dequeueCount,
validCounter + enqNumber - dequeueCount
)
allowEnqueue := Mux(io.brqRedirect.valid,
false.B,
Mux(lastLastCycleRedirect,
trueValidCounter <= (StoreQueueSize - RenameWidth).U,
validCounter + enqNumber <= (StoreQueueSize - RenameWidth).U
)
)
val validCount = distanceBetween(enqPtrExt(0), deqPtrExt(0))
allowEnqueue := validCount + enqNumber <= (StoreQueueSize - RenameWidth).U
// io.sqempty will be used by sbuffer
// We delay it for 1 cycle for better timing
......@@ -384,7 +392,7 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
for (i <- 0 until StoreQueueSize) {
if (i % 4 == 0) XSDebug("")
XSDebug(false, true.B, "%x [%x] ", uop(i).cf.pc, dataModule.io.debug(i).paddr)
XSDebug(false, true.B, "%x ", uop(i).cf.pc)
PrintFlag(allocated(i), "a")
PrintFlag(allocated(i) && datavalid(i), "v")
PrintFlag(allocated(i) && writebacked(i), "w")
......
......@@ -11,12 +11,52 @@ import xiangshan.mem._
import xiangshan.backend.roq.RoqPtr
// Data module define
// These data modules are like SyncDataModuleTemplate, but support cam-like ops
class SQPaddrModule(numEntries: Int, numRead: Int, numWrite: Int, numForward: Int) extends XSModule with HasDCacheParameters {
val io = IO(new Bundle {
val raddr = Input(Vec(numRead, UInt(log2Up(numEntries).W)))
val rdata = Output(Vec(numRead, UInt((PAddrBits).W)))
val wen = Input(Vec(numWrite, Bool()))
val waddr = Input(Vec(numWrite, UInt(log2Up(numEntries).W)))
val wdata = Input(Vec(numWrite, UInt((PAddrBits).W)))
val forwardMdata = Input(Vec(numForward, UInt((PAddrBits).W)))
val forwardMmask = Output(Vec(numForward, Vec(numEntries, Bool())))
})
val data = Reg(Vec(numEntries, UInt((PAddrBits).W)))
// read ports
for (i <- 0 until numRead) {
io.rdata(i) := data(RegNext(io.raddr(i)))
}
// below is the write ports (with priorities)
for (i <- 0 until numWrite) {
when (io.wen(i)) {
data(io.waddr(i)) := io.wdata(i)
}
}
// content addressed match
for (i <- 0 until numForward) {
for (j <- 0 until numEntries) {
io.forwardMmask(i)(j) := io.forwardMdata(i)(PAddrBits-1, 3) === data(j)(PAddrBits-1, 3)
}
}
// DataModuleTemplate should not be used when there're any write conflicts
for (i <- 0 until numWrite) {
for (j <- i+1 until numWrite) {
assert(!(io.wen(i) && io.wen(j) && io.waddr(i) === io.waddr(j)))
}
}
}
class SQDataEntry extends XSBundle {
// val vaddr = UInt(VAddrBits.W) // TODO: need opt
val paddr = UInt(PAddrBits.W)
// val paddr = UInt(PAddrBits.W)
val mask = UInt(8.W)
val data = UInt(XLEN.W)
// val exception = UInt(16.W) // TODO: opt size
}
class StoreQueueData(size: Int, numRead: Int, numWrite: Int, numForward: Int) extends XSModule with HasDCacheParameters with HasCircularQueuePtrHelper {
......@@ -29,13 +69,8 @@ class StoreQueueData(size: Int, numRead: Int, numWrite: Int, numForward: Int) ex
val debug = Vec(size, Output(new SQDataEntry))
val needForward = Input(Vec(numForward, Vec(2, UInt(size.W))))
val forward = Vec(numForward, Flipped(new LoadForwardQueryIO))
def forwardQuery(numForward: Int, paddr: UInt, needForward1: Data, needForward2: Data): Unit = {
this.needForward(numForward)(0) := needForward1
this.needForward(numForward)(1) := needForward2
this.forward(numForward).paddr := paddr
}
val forwardMask = Vec(numForward, Output(Vec(8, Bool())))
val forwardData = Vec(numForward, Output(Vec(8, UInt(8.W))))
})
io := DontCare
......@@ -72,32 +107,7 @@ class StoreQueueData(size: Int, numRead: Int, numWrite: Int, numForward: Int) ex
// entry with larger index should have higher priority since it's data is younger
(0 until numForward).map(i => {
val forwardMask1 = WireInit(VecInit(Seq.fill(8)(false.B)))
val forwardData1 = WireInit(VecInit(Seq.fill(8)(0.U(8.W))))
val forwardMask2 = WireInit(VecInit(Seq.fill(8)(false.B)))
val forwardData2 = WireInit(VecInit(Seq.fill(8)(0.U(8.W))))
for (j <- 0 until size) {
val needCheck = io.forward(i).paddr(PAddrBits - 1, 3) === data(j).paddr(PAddrBits - 1, 3)
(0 until XLEN / 8).foreach(k => {
when (needCheck && data(j).mask(k)) {
when (io.needForward(i)(0)(j)) {
forwardMask1(k) := true.B
forwardData1(k) := data(j).data(8 * (k + 1) - 1, 8 * k)
}
when (io.needForward(i)(1)(j)) {
forwardMask2(k) := true.B
forwardData2(k) := data(j).data(8 * (k + 1) - 1, 8 * k)
}
XSDebug(io.needForward(i)(0)(j) || io.needForward(i)(1)(j),
p"forwarding $k-th byte ${Hexadecimal(data(j).data(8 * (k + 1) - 1, 8 * k))} " +
p"from ptr $j\n")
}
})
}
// parallel fwd logic
val paddrMatch = Wire(Vec(size, Bool()))
val matchResultVec = Wire(Vec(size * 2, new FwdEntry))
def parallelFwd(xs: Seq[Data]): Data = {
......@@ -113,13 +123,14 @@ class StoreQueueData(size: Int, numRead: Int, numWrite: Int, numForward: Int) ex
})
}
for (j <- 0 until size) {
paddrMatch(j) := io.forward(i).paddr(PAddrBits - 1, 3) === data(j).paddr(PAddrBits - 1, 3)
}
// paddrMatch is now included in io.needForward
// for (j <- 0 until size) {
// paddrMatch(j) := io.forward(i).paddr(PAddrBits - 1, 3) === data(j).paddr(PAddrBits - 1, 3)
// }
for (j <- 0 until size) {
val needCheck0 = RegNext(paddrMatch(j) && io.needForward(i)(0)(j))
val needCheck1 = RegNext(paddrMatch(j) && io.needForward(i)(1)(j))
val needCheck0 = RegNext(io.needForward(i)(0)(j))
val needCheck1 = RegNext(io.needForward(i)(1)(j))
(0 until XLEN / 8).foreach(k => {
matchResultVec(j).mask(k) := needCheck0 && data(j).mask(k)
matchResultVec(j).data(k) := data(j).data(8 * (k + 1) - 1, 8 * k)
......@@ -130,8 +141,8 @@ class StoreQueueData(size: Int, numRead: Int, numWrite: Int, numForward: Int) ex
val parallelFwdResult = parallelFwd(matchResultVec).asTypeOf(new FwdEntry)
io.forward(i).forwardMask := parallelFwdResult.mask
io.forward(i).forwardData := parallelFwdResult.data
io.forwardMask(i) := parallelFwdResult.mask
io.forwardData(i) := parallelFwdResult.data
})
......
......@@ -12,6 +12,7 @@ import xiangshan.backend.LSUOpType
class LoadToLsqIO extends XSBundle {
val loadIn = ValidIO(new LsPipelineBundle)
val ldout = Flipped(DecoupledIO(new ExuOutput))
val loadDataForwarded = Output(Bool())
val forward = new LoadForwardQueryIO
}
......@@ -141,6 +142,7 @@ class LoadUnit_S2 extends XSModule with HasLoadHelper {
val dcacheResp = Flipped(DecoupledIO(new DCacheWordResp))
val lsq = new LoadForwardQueryIO
val sbuffer = new LoadForwardQueryIO
val dataForwarded = Output(Bool())
})
val s2_uop = io.in.bits.uop
......@@ -194,10 +196,17 @@ class LoadUnit_S2 extends XSModule with HasLoadHelper {
io.out.bits := io.in.bits
io.out.bits.data := rdataPartialLoad
// when exception occurs, set it to not miss and let it write back to roq (via int port)
io.out.bits.miss := s2_cache_miss && !fullForward && !s2_exception
io.out.bits.miss := s2_cache_miss && !s2_exception
io.out.bits.uop.ctrl.fpWen := io.in.bits.uop.ctrl.fpWen && !s2_exception
io.out.bits.mmio := s2_mmio
// For timing reasons, we can not let
// io.out.bits.miss := s2_cache_miss && !s2_exception && !fullForward
// We use io.dataForwarded instead. It means forward logic have prepared all data needed,
// and dcache query is no longer needed.
// Such inst will be writebacked from load queue.
io.dataForwarded := s2_cache_miss && fullForward && !s2_exception
io.in.ready := io.out.ready || !io.in.valid
// merge forward result
......@@ -259,6 +268,7 @@ class LoadUnit extends XSModule with HasLoadHelper {
load_s2.io.lsq.forwardMask <> io.lsq.forward.forwardMask
load_s2.io.sbuffer.forwardData <> io.sbuffer.forwardData
load_s2.io.sbuffer.forwardMask <> io.sbuffer.forwardMask
load_s2.io.dataForwarded <> io.lsq.loadDataForwarded
XSDebug(load_s0.io.out.valid,
p"S0: pc ${Hexadecimal(load_s0.io.out.bits.uop.cf.pc)}, lId ${Hexadecimal(load_s0.io.out.bits.uop.lqIdx.asUInt)}, " +
......
......@@ -114,6 +114,13 @@ class NewSbuffer extends XSModule with HasSbufferCst {
val empty = Output(Bool())
} // sbuffer flush
})
val difftestIO = IO(new Bundle() {
val sbufferResp = Output(Bool())
val sbufferAddr = Output(UInt(64.W))
val sbufferData = Output(Vec(64, UInt(8.W)))
val sbufferMask = Output(UInt(64.W))
})
difftestIO <> DontCare
val buffer = Mem(StoreBufferSize, new SbufferLine)
val stateVec = RegInit(VecInit(Seq.fill(StoreBufferSize)(s_invalid)))
......@@ -376,6 +383,13 @@ class NewSbuffer extends XSModule with HasSbufferCst {
XSDebug(p"recv cache resp: id=[$respId]\n")
}
if (env.DualCoreDifftest) {
difftestIO.sbufferResp := WireInit(io.dcache.resp.fire())
difftestIO.sbufferAddr := WireInit(getAddr(tagRead(respId)))
difftestIO.sbufferData := WireInit(bufferRead(respId).data.asTypeOf(Vec(CacheLineBytes, UInt(8.W))))
difftestIO.sbufferMask := WireInit(bufferRead(respId).mask)
}
val needSpace = (io.in(0).fire && !canMerge(0)) +& (io.in(1).fire && !canMerge(1) && !sameTag)
invalidCount := invalidCount - needSpace + io.dcache.resp.fire()
validCount := validCount + needSpace - prepareValid
......
......@@ -21,10 +21,10 @@ package object xiangshan {
}
object SrcState {
def busy = "b00".U
def rdy = "b01".U
def specRdy = "b10".U // speculative ready, for future use
def apply() = UInt(2.W)
def busy = "b0".U
def rdy = "b1".U
// def specRdy = "b10".U // speculative ready, for future use
def apply() = UInt(1.W)
}
object FuType extends HasXSParameter {
......@@ -33,18 +33,18 @@ package object xiangshan {
def jmp = "b0000".U
def i2f = "b0001".U
def csr = "b0010".U
def alu = "b0011".U
def alu = "b0110".U
def mul = "b0100".U
def div = "b0101".U
def fence = "b0110".U
def fence = "b0011".U
def fmac = "b1000".U
def fmisc = "b1001".U
def fmisc = "b1011".U
def fDivSqrt = "b1010".U
def ldu = "b1100".U
def stu = "b1101".U
def mou = "b1110".U // for amo, lr, sc, fence
def mou = "b1111".U // for amo, lr, sc, fence
def apply() = UInt(log2Up(num).W)
......@@ -52,8 +52,21 @@ package object xiangshan {
def isJumpExu(fuType: UInt) = fuType === jmp
def isFpExu(fuType: UInt) = fuType(3, 2) === "b10".U
def isMemExu(fuType: UInt) = fuType(3, 2) === "b11".U
def isLoadExu(fuType: UInt) = fuType === ldu || fuType === mou
def isStoreExu(fuType: UInt) = fuType === stu
def isLoadStore(fuType: UInt) = isMemExu(fuType) && !fuType(1)
def isStoreExu(fuType: UInt) = isMemExu(fuType) && fuType(0)
def isAMO(fuType: UInt) = fuType(1)
def jmpCanAccept(fuType: UInt) = !fuType(2)
def mduCanAccept(fuType: UInt) = fuType(2) && !fuType(1)
def aluCanAccept(fuType: UInt) = fuType(2) && fuType(1)
def fmacCanAccept(fuType: UInt) = !fuType(1)
def fmiscCanAccept(fuType: UInt) = fuType(1)
def loadCanAccept(fuType: UInt) = !fuType(0)
def storeCanAccept(fuType: UInt) = fuType(0)
def storeIsAMO(fuType: UInt) = fuType(1)
val functionNameMap = Map(
jmp.litValue() -> "jmp",
......
......@@ -21,5 +21,7 @@ extern "C" void xs_assert(long long line) {
}
void sig_handler(int signo) {
if (signal_num != 0)
exit(0);
signal_num = signo;
}
......@@ -12,19 +12,19 @@
#define DEBUG_RETIRE_TRACE_SIZE 16
#define DEBUG_WB_TRACE_SIZE 16
void (*ref_difftest_memcpy_from_dut)(paddr_t dest, void *src, size_t n) = NULL;
void (*ref_difftest_memcpy_from_ref)(void *dest, paddr_t src, size_t n) = NULL;
void (*ref_difftest_getregs)(void *c) = NULL;
void (*ref_difftest_setregs)(const void *c) = NULL;
void (*ref_difftest_get_mastatus)(void *s) = NULL;
void (*ref_difftest_set_mastatus)(const void *s) = NULL;
void (*ref_difftest_get_csr)(void *c) = NULL;
void (*ref_difftest_set_csr)(const void *c) = NULL;
vaddr_t (*ref_disambiguate_exec)(void *disambiguate_para) = NULL;
int (*ref_difftest_store_commit)(uint64_t *saddr, uint64_t *sdata, uint8_t *smask) = NULL;
static void (*ref_difftest_exec)(uint64_t n) = NULL;
static void (*ref_difftest_raise_intr)(uint64_t NO) = NULL;
static void (*ref_isa_reg_display)(void) = NULL;
void (*ref_difftest_memcpy_from_dut)(paddr_t dest, void *src, size_t n, int coreid) = NULL;
void (*ref_difftest_memcpy_from_ref)(void *dest, paddr_t src, size_t n, int coreid) = NULL;
void (*ref_difftest_getregs)(void *c, int coreid) = NULL;
void (*ref_difftest_setregs)(const void *c, int coreid) = NULL;
void (*ref_difftest_get_mastatus)(void *s, int coreid) = NULL;
void (*ref_difftest_set_mastatus)(const void *s, int coreid) = NULL;
void (*ref_difftest_get_csr)(void *c, int coreid) = NULL;
void (*ref_difftest_set_csr)(const void *c, int coreid) = NULL;
vaddr_t (*ref_disambiguate_exec)(void *disambiguate_para, int coreid) = NULL;
int (*ref_difftest_store_commit)(uint64_t *saddr, uint64_t *sdata, uint8_t *smask, int coreid) = NULL;
static void (*ref_difftest_exec)(uint64_t n, int coreid) = NULL;
static void (*ref_difftest_raise_intr)(uint64_t NO, int coreid) = NULL;
static void (*ref_isa_reg_display)(int coreid) = NULL;
static bool is_skip_ref;
static bool is_skip_dut;
......@@ -41,7 +41,7 @@ void difftest_skip_ref() {
void difftest_skip_dut() {
if (is_skip_dut) return;
ref_difftest_exec(1);
ref_difftest_exec(1, 0);
is_skip_dut = true;
}
......@@ -51,49 +51,49 @@ void init_difftest() {
puts("Using " REF_SO " for difftest");
assert(handle);
ref_difftest_memcpy_from_dut = (void (*)(paddr_t, void *, size_t))dlsym(handle, "difftest_memcpy_from_dut");
ref_difftest_memcpy_from_dut = (void (*)(paddr_t, void *, size_t, int))dlsym(handle, "difftest_memcpy_from_dut");
assert(ref_difftest_memcpy_from_dut);
ref_difftest_memcpy_from_ref = (void (*)(void *, paddr_t, size_t))dlsym(handle, "difftest_memcpy_from_ref");
ref_difftest_memcpy_from_ref = (void (*)(void *, paddr_t, size_t, int))dlsym(handle, "difftest_memcpy_from_ref");
assert(ref_difftest_memcpy_from_ref);
ref_difftest_getregs = (void (*)(void *))dlsym(handle, "difftest_getregs");
ref_difftest_getregs = (void (*)(void *, int))dlsym(handle, "difftest_getregs");
assert(ref_difftest_getregs);
ref_difftest_setregs = (void (*)(const void *))dlsym(handle, "difftest_setregs");
ref_difftest_setregs = (void (*)(const void *, int))dlsym(handle, "difftest_setregs");
assert(ref_difftest_setregs);
ref_difftest_get_mastatus = (void (*)(void *))dlsym(handle, "difftest_get_mastatus");
ref_difftest_get_mastatus = (void (*)(void *, int))dlsym(handle, "difftest_get_mastatus");
assert(ref_difftest_get_mastatus);
ref_difftest_set_mastatus = (void (*)(const void *))dlsym(handle, "difftest_set_mastatus");
ref_difftest_set_mastatus = (void (*)(const void *, int))dlsym(handle, "difftest_set_mastatus");
assert(ref_difftest_set_mastatus);
ref_difftest_get_csr = (void (*)(void *))dlsym(handle, "difftest_get_csr");
ref_difftest_get_csr = (void (*)(void *, int))dlsym(handle, "difftest_get_csr");
assert(ref_difftest_get_csr);
ref_difftest_set_csr = (void (*)(const void *))dlsym(handle, "difftest_set_csr");
ref_difftest_set_csr = (void (*)(const void *, int))dlsym(handle, "difftest_set_csr");
assert(ref_difftest_set_csr);
ref_disambiguate_exec = (vaddr_t (*)(void *))dlsym(handle, "disambiguate_exec");
ref_disambiguate_exec = (vaddr_t (*)(void *, int))dlsym(handle, "disambiguate_exec");
assert(ref_disambiguate_exec);
ref_difftest_store_commit = (int (*)(uint64_t*, uint64_t*, uint8_t*))dlsym(handle, "difftest_store_commit");
ref_difftest_store_commit = (int (*)(uint64_t*, uint64_t*, uint8_t*, int))dlsym(handle, "difftest_store_commit");
assert(ref_difftest_store_commit);
ref_difftest_exec = (void (*)(uint64_t))dlsym(handle, "difftest_exec");
ref_difftest_exec = (void (*)(uint64_t, int))dlsym(handle, "difftest_exec");
assert(ref_difftest_exec);
ref_difftest_raise_intr = (void (*)(uint64_t))dlsym(handle, "difftest_raise_intr");
ref_difftest_raise_intr = (void (*)(uint64_t, int))dlsym(handle, "difftest_raise_intr");
assert(ref_difftest_raise_intr);
ref_isa_reg_display = (void (*)(void))dlsym(handle, "isa_reg_display");
ref_isa_reg_display = (void (*)(int))dlsym(handle, "isa_reg_display");
assert(ref_isa_reg_display);
void (*ref_difftest_init)(void) = (void (*)(void))dlsym(handle, "difftest_init");
void (*ref_difftest_init)(int) = (void (*)(int))dlsym(handle, "difftest_init");
assert(ref_difftest_init);
ref_difftest_init();
ref_difftest_init(0);
}
static const char *reg_name[DIFFTEST_NR_REG] = {
......@@ -140,7 +140,7 @@ void difftest_display(uint8_t mode) {
j, pc_wb_queue[j], wen_wb_queue[j]!=0, wdst_wb_queue[j], wdata_wb_queue[j], (j==((wb_pointer-1)%DEBUG_WB_TRACE_SIZE))?"<--":"");
}
printf("\n============== Reg Diff ==============\n");
ref_isa_reg_display();
ref_isa_reg_display(0);
printf("priviledgeMode: %d\n", mode);
}
......@@ -171,12 +171,12 @@ int difftest_step(DiffState *s) {
struct SyncState sync;
sync.lrscValid = 0;
sync.lrscAddr = 0;
ref_difftest_set_mastatus((uint64_t*)&sync); // sync lr/sc microarchitectural regs
ref_difftest_set_mastatus((uint64_t*)&sync, 0); // sync lr/sc microarchitectural regs
}
// single step difftest
if (s->intrNO) {
ref_difftest_raise_intr(s->intrNO);
ref_difftest_raise_intr(s->intrNO, 0);
// ref_difftest_exec(1);//TODO
}
else {
......@@ -191,14 +191,14 @@ int difftest_step(DiffState *s) {
// MMIO accessing should not be a branch or jump, just +2/+4 to get the next pc
// printf("SKIP %d\n", i);
// to skip the checking of an instruction, just copy the reg state to reference design
ref_difftest_getregs(&ref_r);
ref_difftest_getregs(&ref_r, 0);
ref_r[DIFFTEST_THIS_PC] += selectBit(s->isRVC, i) ? 2 : 4;
if(selectBit(s->wen, i)){
if(s->wdst[i] != 0){
ref_r[s->wdst[i]] = s->wdata[i];
}
}
ref_difftest_setregs(ref_r);
ref_difftest_setregs(ref_r, 0);
}else{
// single step exec
// IPF, LPF, SPF
......@@ -208,14 +208,14 @@ int difftest_step(DiffState *s) {
ds.exceptionNo = s->cause;
ds.mtval = s->reg_scala[DIFFTEST_MTVAL];
ds.stval = s->reg_scala[DIFFTEST_STVAL];
ref_disambiguate_exec(&ds);
ref_disambiguate_exec(&ds, 0);
}else{
ref_difftest_exec(1);
ref_difftest_exec(1, 0);
}
}
}
}
ref_difftest_getregs(&ref_r);
ref_difftest_getregs(&ref_r, 0);
uint64_t next_pc = ref_r[DIFFTEST_THIS_PC];
pc_retire_pointer = (pc_retire_pointer+1) % DEBUG_RETIRE_TRACE_SIZE;
......@@ -255,5 +255,5 @@ int difftest_step(DiffState *s) {
}
int difftest_store_step(uint64_t *saddr, uint64_t *sdata, uint8_t *smask) {
return ref_difftest_store_commit(saddr, sdata, smask);
return ref_difftest_store_commit(saddr, sdata, smask, 0);
}
......@@ -82,16 +82,16 @@ struct DisambiguationState {
uint64_t stval;
};
extern void (*ref_difftest_memcpy_from_dut)(paddr_t dest, void *src, size_t n);
extern void (*ref_difftest_memcpy_from_ref)(void *dest, paddr_t src, size_t n);
extern void (*ref_difftest_getregs)(void *c);
extern void (*ref_difftest_setregs)(const void *c);
extern void (*ref_difftest_get_mastatus)(void *s);
extern void (*ref_difftest_set_mastatus)(const void *s);
extern void (*ref_difftest_get_csr)(void *c);
extern void (*ref_difftest_set_csr)(const void *c);
extern vaddr_t (*ref_disambiguate_exec)(void *disambiguate_para);
extern int (*ref_difftest_store_commit)(uint64_t *saddr, uint64_t *sdata, uint8_t *smask);
extern void (*ref_difftest_memcpy_from_dut)(paddr_t dest, void *src, size_t n, int coreid);
extern void (*ref_difftest_memcpy_from_ref)(void *dest, paddr_t src, size_t n, int coreid);
extern void (*ref_difftest_getregs)(void *c, int coreid);
extern void (*ref_difftest_setregs)(const void *c, int coreid);
extern void (*ref_difftest_get_mastatus)(void *s, int coreid);
extern void (*ref_difftest_set_mastatus)(const void *s, int coreid);
extern void (*ref_difftest_get_csr)(void *c, int coreid);
extern void (*ref_difftest_set_csr)(const void *c, int coreid);
extern vaddr_t (*ref_disambiguate_exec)(void *disambiguate_para, int coreid);
extern int (*ref_difftest_store_commit)(uint64_t *saddr, uint64_t *sdata, uint8_t *smask, int coreid);
void init_difftest();
int difftest_step(DiffState *s);
......
......@@ -276,19 +276,26 @@ uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
extern uint32_t uptime(void);
uint32_t lasttime_poll = 0;
uint32_t lasttime_snapshot = 0;
uint64_t lastcommit = max_cycle;
uint64_t instr_left_last_cycle = max_instr;
uint64_t lastcommit[NumCore];
uint64_t instr_left_last_cycle[NumCore];
const int stuck_limit = 2000;
uint64_t core_max_instr[NumCore];
uint32_t wdst[NumCore][DIFFTEST_WIDTH];
uint64_t wdata[NumCore][DIFFTEST_WIDTH];
uint64_t wpc[NumCore][DIFFTEST_WIDTH];
uint64_t reg[NumCore][DIFFTEST_NR_REG];
DiffState diff[NumCore];
for (int i = 0; i < NumCore; i++) {
diff[i].reg_scala = reg[i];
diff[i].wpc = wpc[i];
diff[i].wdata = wdata[i];
diff[i].wdst = wdst[i];
lastcommit[i] = max_cycle;
instr_left_last_cycle[i] = max_cycle;
core_max_instr[i] = max_instr;
}
uint32_t wdst[DIFFTEST_WIDTH];
uint64_t wdata[DIFFTEST_WIDTH];
uint64_t wpc[DIFFTEST_WIDTH];
uint64_t reg[DIFFTEST_NR_REG];
DiffState diff;
diff.reg_scala = reg;
diff.wpc = wpc;
diff.wdata = wdata;
diff.wdst = wdst;
#if VM_COVERAGE == 1
// we dump coverage into files at the end
......@@ -298,8 +305,10 @@ uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
#endif
while (!Verilated::gotFinish() && trapCode == STATE_RUNNING) {
if (!(max_cycle > 0 && max_instr > 0 && instr_left_last_cycle >= max_instr /* handle overflow */)) {
trapCode = STATE_LIMIT_EXCEEDED;
if (!(max_cycle > 0 &&
core_max_instr[0] > 0 &&
instr_left_last_cycle[0] >= core_max_instr[0])) {
trapCode = STATE_LIMIT_EXCEEDED; /* handle overflow */
break;
}
if (assert_count > 0) {
......@@ -319,7 +328,7 @@ uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
if (dut_ptr->io_trap_valid) trapCode = dut_ptr->io_trap_code;
if (trapCode != STATE_RUNNING) break;
if (lastcommit - max_cycle > stuck_limit && hascommit) {
if (lastcommit[0] - max_cycle > stuck_limit && hascommit) {
eprintf("No instruction commits for %d cycles, maybe get stuck\n"
"(please also check whether a fence.i instruction requires more than %d cycles to flush the icache)\n",
stuck_limit, stuck_limit);
......@@ -329,57 +338,66 @@ uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
if (!hascommit && dut_ptr->io_difftest_commit && dut_ptr->io_difftest_thisPC == 0x80000000u) {
hascommit = 1;
read_emu_regs(reg);
read_emu_regs(reg[0]);
void* get_img_start();
long get_img_size();
ref_difftest_memcpy_from_dut(0x80000000, get_img_start(), get_img_size());
ref_difftest_setregs(reg);
ref_difftest_memcpy_from_dut(0x80000000, get_img_start(), get_img_size(), 0);
ref_difftest_setregs(reg[0], 0);
printf("The first instruction has commited. Difftest enabled. \n");
}
// difftest
if (dut_ptr->io_difftest_commit && hascommit) {
read_emu_regs(reg);
read_wb_info(wpc, wdata, wdst);
diff.commit = dut_ptr->io_difftest_commit;
diff.this_inst = dut_ptr->io_difftest_thisINST;
diff.skip = dut_ptr->io_difftest_skip;
diff.isRVC = dut_ptr->io_difftest_isRVC;
diff.wen = dut_ptr->io_difftest_wen;
diff.intrNO = dut_ptr->io_difftest_intrNO;
diff.cause = dut_ptr->io_difftest_cause;
diff.priviledgeMode = dut_ptr->io_difftest_priviledgeMode;
diff.sync.scFailed = dut_ptr->io_difftest_scFailed;
if (difftest_step(&diff)) {
trapCode = STATE_ABORT;
}
lastcommit = max_cycle;
// update instr_cnt
instr_left_last_cycle = max_instr;
max_instr -= diff.commit;
}
for (int i = 0; i < NumCore; i++) {
if (dut_ptr->io_difftest_commit && hascommit) {
read_emu_regs(reg[i]);
read_wb_info(wpc[i], wdata[i], wdst[i]);
diff[i].commit = dut_ptr->io_difftest_commit;
diff[i].this_inst = dut_ptr->io_difftest_thisINST;
diff[i].skip = dut_ptr->io_difftest_skip;
diff[i].isRVC = dut_ptr->io_difftest_isRVC;
diff[i].wen = dut_ptr->io_difftest_wen;
diff[i].intrNO = dut_ptr->io_difftest_intrNO;
diff[i].cause = dut_ptr->io_difftest_cause;
diff[i].priviledgeMode = dut_ptr->io_difftest_priviledgeMode;
diff[i].sync.scFailed = dut_ptr->io_difftest_scFailed;
if (i == 0) {
if (difftest_step(&diff[i])) {
trapCode = STATE_ABORT;
}
}
lastcommit[i] = max_cycle;
if (dut_ptr->io_difftest_storeCommit) {
read_store_info(diff.store_addr, diff.store_data, diff.store_mask);
for (int i = 0; i < dut_ptr->io_difftest_storeCommit; i++) {
auto addr = diff.store_addr[i];
auto data = diff.store_data[i];
auto mask = diff.store_mask[i];
if (difftest_store_step(&addr, &data, &mask)) {
difftest_display(dut_ptr->io_difftest_priviledgeMode);
printf("Mismatch for store commits: \n");
printf("REF commits addr 0x%lx, data 0x%lx, mask 0x%x\n", addr, data, mask);
printf("DUT commits addr 0x%lx, data 0x%lx, mask 0x%x\n",
diff.store_addr[i], diff.store_data[i], diff.store_mask[i]);
trapCode = STATE_ABORT;
break;
// update instr_cnt
instr_left_last_cycle[i] = core_max_instr[i];
core_max_instr[i] -= diff[i].commit;
}
#ifdef DIFFTEST_STORE_COMMIT
for (int core = 0; core < NumCore; core++) {
if (dut_ptr->io_difftest_storeCommit) {
read_store_info(diff[core].store_addr, diff[core].store_data, diff[core].store_mask);
for (int i = 0; i < dut_ptr->io_difftest_storeCommit; i++) {
auto addr = diff[core].store_addr[i];
auto data = diff[core].store_data[i];
auto mask = diff[core].store_mask[i];
if (difftest_store_step(&addr, &data, &mask)) {
difftest_display(dut_ptr->io_difftest_priviledgeMode);
printf("Mismatch for store commits: \n");
printf("REF commits addr 0x%lx, data 0x%lx, mask 0x%x\n", addr, data, mask);
printf("DUT commits addr 0x%lx, data 0x%lx, mask 0x%x\n",
diff[core].store_addr[i], diff[core].store_data[i], diff[core].store_mask[i]);
trapCode = STATE_ABORT;
break;
}
}
}
}
#endif
}
uint32_t t = uptime();
......@@ -504,23 +522,23 @@ void Emulator::snapshot_save(const char *filename) {
stream.unbuf_write(get_ram_start(), size);
uint64_t ref_r[DIFFTEST_NR_REG];
ref_difftest_getregs(&ref_r);
ref_difftest_getregs(&ref_r, 0);
stream.unbuf_write(ref_r, sizeof(ref_r));
uint64_t nemu_this_pc = get_nemu_this_pc();
stream.unbuf_write(&nemu_this_pc, sizeof(nemu_this_pc));
char *buf = (char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
ref_difftest_memcpy_from_ref(buf, 0x80000000, size);
ref_difftest_memcpy_from_ref(buf, 0x80000000, size, 0);
stream.unbuf_write(buf, size);
munmap(buf, size);
struct SyncState sync_mastate;
ref_difftest_get_mastatus(&sync_mastate);
ref_difftest_get_mastatus(&sync_mastate, 0);
stream.unbuf_write(&sync_mastate, sizeof(struct SyncState));
uint64_t csr_buf[4096];
ref_difftest_get_csr(csr_buf);
ref_difftest_get_csr(csr_buf, 0);
stream.unbuf_write(&csr_buf, sizeof(csr_buf));
long sdcard_offset;
......@@ -553,7 +571,7 @@ void Emulator::snapshot_load(const char *filename) {
char *buf = (char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
stream.read(buf, size);
ref_difftest_memcpy_from_dut(0x80000000, buf, size);
ref_difftest_memcpy_from_dut(0x80000000, buf, size, 0);
munmap(buf, size);
struct SyncState sync_mastate;
......
......@@ -7,6 +7,8 @@
#include <verilated_vcd_c.h> // Trace file format header
#define SNAPSHOT_INTERVAL 60 // unit: second
#define DIFFTEST_STORE_COMMIT
#define NumCore 1
struct EmuArgs {
uint32_t seed;
......
......@@ -53,6 +53,11 @@ class DiffTestIO extends XSBundle {
val storeAddr = Output(Vec(2, UInt(64.W)))
val storeData = Output(Vec(2, UInt(64.W)))
val storeMask = Output(Vec(2, UInt(8.W)))
val sbufferResp = Output(Bool())
val sbufferAddr = Output(UInt(64.W))
val sbufferData = Output(Vec(64, UInt(8.W)))
val sbufferMask = Output(UInt(64.W))
}
class LogCtrlIO extends Bundle {
......@@ -112,11 +117,13 @@ class XSSimSoC(axiSim: Boolean)(implicit p: config.Parameters) extends LazyModul
lazy val module = new LazyModuleImp(this) {
val io = IO(new Bundle {
val difftest = new DiffTestIO
val difftest = new DiffTestIO
val difftest2 = new DiffTestIO
val logCtrl = new LogCtrlIO
val trap = new TrapIO
val uart = new UARTIO
})
io.difftest2 <> DontCare
dontTouch(io.difftest)
dontTouch(io.logCtrl)
......@@ -129,47 +136,97 @@ class XSSimSoC(axiSim: Boolean)(implicit p: config.Parameters) extends LazyModul
soc.module.io.extIntrs(i) := false.B
}
val difftest = WireInit(0.U.asTypeOf(new DiffTestIO))
val difftest = Seq(WireInit(0.U.asTypeOf(new DiffTestIO)), WireInit(0.U.asTypeOf(new DiffTestIO)))
if (!env.FPGAPlatform) {
ExcitingUtils.addSink(difftest.commit, "difftestCommit", Debug)
ExcitingUtils.addSink(difftest.thisPC, "difftestThisPC", Debug)
ExcitingUtils.addSink(difftest.thisINST, "difftestThisINST", Debug)
ExcitingUtils.addSink(difftest.skip, "difftestSkip", Debug)
ExcitingUtils.addSink(difftest.isRVC, "difftestIsRVC", Debug)
ExcitingUtils.addSink(difftest.wen, "difftestWen", Debug)
ExcitingUtils.addSink(difftest.wdata, "difftestWdata", Debug)
ExcitingUtils.addSink(difftest.wdst, "difftestWdst", Debug)
ExcitingUtils.addSink(difftest.wpc, "difftestWpc", Debug)
ExcitingUtils.addSink(difftest.intrNO, "difftestIntrNO", Debug)
ExcitingUtils.addSink(difftest.cause, "difftestCause", Debug)
ExcitingUtils.addSink(difftest.r, "difftestRegs", Debug)
ExcitingUtils.addSink(difftest.priviledgeMode, "difftestMode", Debug)
ExcitingUtils.addSink(difftest.mstatus, "difftestMstatus", Debug)
ExcitingUtils.addSink(difftest.sstatus, "difftestSstatus", Debug)
ExcitingUtils.addSink(difftest.mepc, "difftestMepc", Debug)
ExcitingUtils.addSink(difftest.sepc, "difftestSepc", Debug)
ExcitingUtils.addSink(difftest.mtval, "difftestMtval", Debug)
ExcitingUtils.addSink(difftest.stval, "difftestStval", Debug)
ExcitingUtils.addSink(difftest.mtvec, "difftestMtvec", Debug)
ExcitingUtils.addSink(difftest.stvec, "difftestStvec", Debug)
ExcitingUtils.addSink(difftest.mcause, "difftestMcause", Debug)
ExcitingUtils.addSink(difftest.scause, "difftestScause", Debug)
ExcitingUtils.addSink(difftest.satp, "difftestSatp", Debug)
ExcitingUtils.addSink(difftest.mip, "difftestMip", Debug)
ExcitingUtils.addSink(difftest.mie, "difftestMie", Debug)
ExcitingUtils.addSink(difftest.mscratch, "difftestMscratch", Debug)
ExcitingUtils.addSink(difftest.sscratch, "difftestSscratch", Debug)
ExcitingUtils.addSink(difftest.mideleg, "difftestMideleg", Debug)
ExcitingUtils.addSink(difftest.medeleg, "difftestMedeleg", Debug)
ExcitingUtils.addSink(difftest.scFailed, "difftestScFailed", Debug)
ExcitingUtils.addSink(difftest.storeCommit, "difftestStoreCommit", Debug)
ExcitingUtils.addSink(difftest.storeAddr, "difftestStoreAddr", Debug)
ExcitingUtils.addSink(difftest.storeData, "difftestStoreData", Debug)
ExcitingUtils.addSink(difftest.storeMask, "difftestStoreMask", Debug)
ExcitingUtils.addSink(difftest(0).commit, "difftestCommit", Debug)
ExcitingUtils.addSink(difftest(0).thisPC, "difftestThisPC", Debug)
ExcitingUtils.addSink(difftest(0).thisINST, "difftestThisINST", Debug)
ExcitingUtils.addSink(difftest(0).skip, "difftestSkip", Debug)
ExcitingUtils.addSink(difftest(0).isRVC, "difftestIsRVC", Debug)
ExcitingUtils.addSink(difftest(0).wen, "difftestWen", Debug)
ExcitingUtils.addSink(difftest(0).wdata, "difftestWdata", Debug)
ExcitingUtils.addSink(difftest(0).wdst, "difftestWdst", Debug)
ExcitingUtils.addSink(difftest(0).wpc, "difftestWpc", Debug)
ExcitingUtils.addSink(difftest(0).intrNO, "difftestIntrNO", Debug)
ExcitingUtils.addSink(difftest(0).cause, "difftestCause", Debug)
ExcitingUtils.addSink(difftest(0).r, "difftestRegs", Debug)
ExcitingUtils.addSink(difftest(0).priviledgeMode, "difftestMode", Debug)
ExcitingUtils.addSink(difftest(0).mstatus, "difftestMstatus", Debug)
ExcitingUtils.addSink(difftest(0).sstatus, "difftestSstatus", Debug)
ExcitingUtils.addSink(difftest(0).mepc, "difftestMepc", Debug)
ExcitingUtils.addSink(difftest(0).sepc, "difftestSepc", Debug)
ExcitingUtils.addSink(difftest(0).mtval, "difftestMtval", Debug)
ExcitingUtils.addSink(difftest(0).stval, "difftestStval", Debug)
ExcitingUtils.addSink(difftest(0).mtvec, "difftestMtvec", Debug)
ExcitingUtils.addSink(difftest(0).stvec, "difftestStvec", Debug)
ExcitingUtils.addSink(difftest(0).mcause, "difftestMcause", Debug)
ExcitingUtils.addSink(difftest(0).scause, "difftestScause", Debug)
ExcitingUtils.addSink(difftest(0).satp, "difftestSatp", Debug)
ExcitingUtils.addSink(difftest(0).mip, "difftestMip", Debug)
ExcitingUtils.addSink(difftest(0).mie, "difftestMie", Debug)
ExcitingUtils.addSink(difftest(0).mscratch, "difftestMscratch", Debug)
ExcitingUtils.addSink(difftest(0).sscratch, "difftestSscratch", Debug)
ExcitingUtils.addSink(difftest(0).mideleg, "difftestMideleg", Debug)
ExcitingUtils.addSink(difftest(0).medeleg, "difftestMedeleg", Debug)
ExcitingUtils.addSink(difftest(0).scFailed, "difftestScFailed", Debug)
ExcitingUtils.addSink(difftest(0).storeCommit, "difftestStoreCommit", Debug)
ExcitingUtils.addSink(difftest(0).storeAddr, "difftestStoreAddr", Debug)
ExcitingUtils.addSink(difftest(0).storeData, "difftestStoreData", Debug)
ExcitingUtils.addSink(difftest(0).storeMask, "difftestStoreMask", Debug)
}
if (env.DualCoreDifftest) {
for (i <- 0 until NumCores) {
difftest(i).commit := soc.module.difftestIO(i).fromRoq.commit
difftest(i).thisPC := soc.module.difftestIO(i).fromRoq.thisPC
difftest(i).thisINST := soc.module.difftestIO(i).fromRoq.thisINST
difftest(i).skip := soc.module.difftestIO(i).fromRoq.skip
difftest(i).isRVC := soc.module.difftestIO(i).fromRoq.isRVC
difftest(i).wen := soc.module.difftestIO(i).fromRoq.wen
difftest(i).wdata := soc.module.difftestIO(i).fromRoq.wdata
difftest(i).wdst := soc.module.difftestIO(i).fromRoq.wdst
difftest(i).wpc := soc.module.difftestIO(i).fromRoq.wpc
difftest(i).scFailed := soc.module.difftestIO(i).fromRoq.scFailed
difftest(i).r := soc.module.difftestIO(i).fromXSCore.r
difftest(i).intrNO := soc.module.difftestIO(i).fromCSR.intrNO
difftest(i).cause := soc.module.difftestIO(i).fromCSR.cause
difftest(i).priviledgeMode := soc.module.difftestIO(i).fromCSR.priviledgeMode
difftest(i).mstatus := soc.module.difftestIO(i).fromCSR.mstatus
difftest(i).sstatus := soc.module.difftestIO(i).fromCSR.sstatus
difftest(i).mepc := soc.module.difftestIO(i).fromCSR.mepc
difftest(i).sepc := soc.module.difftestIO(i).fromCSR.sepc
difftest(i).mtval := soc.module.difftestIO(i).fromCSR.mtval
difftest(i).stval := soc.module.difftestIO(i).fromCSR.stval
difftest(i).mtvec := soc.module.difftestIO(i).fromCSR.mtvec
difftest(i).stvec := soc.module.difftestIO(i).fromCSR.stvec
difftest(i).mcause := soc.module.difftestIO(i).fromCSR.mcause
difftest(i).scause := soc.module.difftestIO(i).fromCSR.scause
difftest(i).satp := soc.module.difftestIO(i).fromCSR.satp
difftest(i).mip := soc.module.difftestIO(i).fromCSR.mip
difftest(i).mie := soc.module.difftestIO(i).fromCSR.mie
difftest(i).mscratch := soc.module.difftestIO(i).fromCSR.mscratch
difftest(i).sscratch := soc.module.difftestIO(i).fromCSR.sscratch
difftest(i).mideleg := soc.module.difftestIO(i).fromCSR.mideleg
difftest(i).medeleg := soc.module.difftestIO(i).fromCSR.medeleg
difftest(i).storeCommit := soc.module.difftestIO(i).fromSQ.storeCommit
difftest(i).storeAddr := soc.module.difftestIO(i).fromSQ.storeAddr
difftest(i).storeData := soc.module.difftestIO(i).fromSQ.storeData
difftest(i).storeMask := soc.module.difftestIO(i).fromSQ.storeMask
difftest(i).sbufferResp := soc.module.difftestIO(i).fromSbuffer.sbufferResp
difftest(i).sbufferAddr := soc.module.difftestIO(i).fromSbuffer.sbufferAddr
difftest(i).sbufferData := soc.module.difftestIO(i).fromSbuffer.sbufferData
difftest(i).sbufferMask := soc.module.difftestIO(i).fromSbuffer.sbufferMask
}
io.difftest2 := difftest(1)
}
// BoringUtils.addSink(difftest.lrscAddr, "difftestLrscAddr")
io.difftest := difftest
io.difftest := difftest(0)
val trap = WireInit(0.U.asTypeOf(new TrapIO))
if (!env.FPGAPlatform) {
......@@ -213,14 +270,19 @@ class XSSimTop(axiSim: Boolean)(implicit p: config.Parameters) extends LazyModul
lazy val module = new LazyModuleImp(this) {
val io = IO(new Bundle {
val difftest = new DiffTestIO
val difftest = new DiffTestIO
val difftest2 = new DiffTestIO
val logCtrl = new LogCtrlIO
val trap = new TrapIO
val uart = new UARTIO
val memAXI = if (axiSim) chiselTypeOf(axiSimRam.module.io) else Input(Bool())
})
io.difftest2 <> DontCare
io.difftest <> dut.module.io.difftest
io.difftest <> dut.module.io.difftest
if (env.DualCoreDifftest) {
io.difftest2 <> dut.module.io.difftest2
}
io.logCtrl <> dut.module.io.logCtrl
io.trap <> dut.module.io.trap
io.uart <> dut.module.io.uart
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册