提交 49cdb253 编写于 作者: Y Yinan Xu

Merge remote-tracking branch 'origin/master' into perf-debug

......@@ -171,6 +171,7 @@ class Backend extends XSModule
})
io.mem.commits <> roq.io.commits
io.mem.roqDeqPtr := roq.io.roqDeqPtr
io.mem.ldin <> issueQueues.filter(_.exuCfg == Exu.ldExeUnitCfg).map(_.io.deq)
io.mem.stin <> issueQueues.filter(_.exuCfg == Exu.stExeUnitCfg).map(_.io.deq)
jmpExeUnit.io.exception.valid := roq.io.redirect.valid && roq.io.redirect.bits.isException
......
......@@ -66,7 +66,6 @@ class Dispatch1 extends XSModule {
io.toRoq(i).valid := io.fromRename(i).valid && !roqIndexRegValid(i)
io.toRoq(i).bits := io.fromRename(i).bits
io.toRoq(i).bits.ctrl.commitType := Cat(isLs(i), isStore(i) | isFp(i)) // TODO: add it to decode
io.toRoq(i).bits.lsroqIdx := Mux(lsroqIndexRegValid(i), lsroqIndexReg(i), io.lsroqIdx(i))
io.toLsroq(i).valid := io.fromRename(i).valid && !lsroqIndexRegValid(i) && isLs(i) && io.fromRename(i).bits.ctrl.fuType =/= FuType.mou && roqIndexAcquired(i) && !cancelled(i)
io.toLsroq(i).bits := io.fromRename(i).bits
......
......@@ -94,7 +94,7 @@ class IssueQueue
def writeBackHit(src: UInt, srcType: UInt, wbUop: (Bool, MicroOp)): Bool = {
val (v, uop) = wbUop
val isSameType =
(SrcType.isReg(srcType) && uop.ctrl.rfWen) || (SrcType.isFp(srcType) && uop.ctrl.fpWen)
(SrcType.isReg(srcType) && uop.ctrl.rfWen && src =/= 0.U) || (SrcType.isFp(srcType) && uop.ctrl.fpWen)
v && isSameType && (src===uop.pdest)
}
......
......@@ -284,7 +284,7 @@ class ReservationStation
for(i <- idQue.indices) { // Should be IssQue.indices but Mem() does not support
for(j <- 0 until srcListenNum) {
val hitVec = cdbValid.indices.map(k => psrc(i)(j) === cdbPdest(k) && cdbValid(k) && (srcType(i)(j)===SrcType.reg && cdbrfWen(k) || srcType(i)(j)===SrcType.fp && cdbfpWen(k)))
val hitVec = cdbValid.indices.map(k => psrc(i)(j) === cdbPdest(k) && cdbValid(k) && (srcType(i)(j)===SrcType.reg && cdbrfWen(k) && cdbPdest(k) =/= 0.U || srcType(i)(j)===SrcType.fp && cdbfpWen(k)))
val hit = ParallelOR(hitVec).asBool
val data = ParallelMux(hitVec zip cdbData)
when (validQue(i) && !srcRdyVec(i)(j) && hit) {
......@@ -306,7 +306,7 @@ class ReservationStation
for (i <- idQue.indices) { // Should be IssQue.indices but Mem() does not support
for (j <- 0 until srcListenNum) {
val hitVec = bpValid.indices.map(k => psrc(i)(j) === bpPdest(k) && bpValid(k) && (srcType(i)(j)===SrcType.reg && bprfWen(k) || srcType(i)(j)===SrcType.fp && bpfpWen(k)))
val hitVec = bpValid.indices.map(k => psrc(i)(j) === bpPdest(k) && bpValid(k) && (srcType(i)(j)===SrcType.reg && bprfWen(k) && bpPdest(k) =/= 0.U || srcType(i)(j)===SrcType.fp && bpfpWen(k)))
val hitVecNext = hitVec.map(RegNext(_))
val hit = ParallelOR(hitVec).asBool
when (validQue(i) && !srcRdyVec(i)(j) && hit) {
......@@ -333,7 +333,7 @@ class ReservationStation
val enqPsrc = List(enqCtrl.bits.psrc1, enqCtrl.bits.psrc2, enqCtrl.bits.psrc3)
val enqSrcType = List(enqCtrl.bits.ctrl.src1Type, enqCtrl.bits.ctrl.src2Type, enqCtrl.bits.ctrl.src3Type)
for (i <- 0 until srcListenNum) {
val hitVec = bpValid.indices.map(j => enqPsrc(i)===bpPdest(j) && bpValid(j) && (enqSrcType(i)===SrcType.reg && bprfWen(j) || enqSrcType(i)===SrcType.fp && bpfpWen(j)))
val hitVec = bpValid.indices.map(j => enqPsrc(i)===bpPdest(j) && bpValid(j) && (enqSrcType(i)===SrcType.reg && bprfWen(j) && bpPdest(j) =/= 0.U || enqSrcType(i)===SrcType.fp && bpfpWen(j)))
val hitVecNext = hitVec.map(RegNext(_))
val hit = ParallelOR(hitVec).asBool
when (enqFire && hit && !enqSrcRdy(i)) {
......
......@@ -22,6 +22,7 @@ class Roq extends XSModule {
val exeWbResults = Vec(exuParameters.ExuCnt + 1, Flipped(ValidIO(new ExuOutput)))
val commits = Vec(CommitWidth, Valid(new RoqCommit))
val bcommit = Output(UInt(BrTagWidth.W))
val roqDeqPtr = Output(UInt(RoqIdxWidth.W))
})
val numWbPorts = io.exeWbResults.length
......@@ -48,6 +49,8 @@ class Roq extends XSModule {
val s_idle :: s_walk :: s_extrawalk :: Nil = Enum(3)
val state = RegInit(s_idle)
io.roqDeqPtr := deqPtrExt
// Dispatch
val noSpecEnq = io.dp1Req.map(i => i.bits.ctrl.noSpecExec)
val hasNoSpec = RegInit(false.B)
......@@ -90,6 +93,7 @@ class Roq extends XSModule {
val wbIdx = wbIdxExt.tail(1)
writebacked(wbIdx) := true.B
microOp(wbIdx).cf.exceptionVec := io.exeWbResults(i).bits.uop.cf.exceptionVec
microOp(wbIdx).lsroqIdx := io.exeWbResults(i).bits.uop.lsroqIdx
microOp(wbIdx).ctrl.flushPipe := io.exeWbResults(i).bits.uop.ctrl.flushPipe
microOp(wbIdx).diffTestDebugLrScValid := io.exeWbResults(i).bits.uop.diffTestDebugLrScValid
exuData(wbIdx) := io.exeWbResults(i).bits.data
......@@ -116,7 +120,8 @@ class Roq extends XSModule {
val deqUop = microOp(deqPtr)
val deqPtrWritebacked = writebacked(deqPtr) && valid(deqPtr)
val intrEnable = intrBitSet && !isEmpty && !hasNoSpec // TODO: wanna check why has hasCsr(hasNoSpec)
val intrEnable = intrBitSet && !isEmpty && !hasNoSpec &&
deqUop.ctrl.commitType =/= CommitType.STORE && deqUop.ctrl.commitType =/= CommitType.LOAD// TODO: wanna check why has hasCsr(hasNoSpec)
val exceptionEnable = deqPtrWritebacked && Cat(deqUop.cf.exceptionVec).orR()
val isFlushPipe = deqPtrWritebacked && deqUop.ctrl.flushPipe
io.redirect := DontCare
......
......@@ -393,6 +393,11 @@ class DCacheImp(outer: DCache) extends LazyModuleImp(outer) with HasDCacheParame
}
// sync with prober
missQueue.io.probe_wb_req.valid := prober.io.wb_req.fire()
missQueue.io.probe_wb_req.bits := prober.io.wb_req.bits
missQueue.io.probe_active := prober.io.probe_active
//----------------------------------------
// prober
prober.io.block := block_probe(prober.io.inflight_req_block_addr.bits)
......@@ -410,9 +415,6 @@ class DCacheImp(outer: DCache) extends LazyModuleImp(outer) with HasDCacheParame
prober.io.wb_resp := wb.io.resp
wb.io.mem_grant := bus.d.fire() && bus.d.bits.source === cfg.nMissEntries.U
missQueue.io.probe_wb_req.valid := prober.io.wb_req.fire()
missQueue.io.probe_wb_req.bits := prober.io.wb_req.bits
TLArbiter.lowestFromSeq(edge, bus.c, Seq(prober.io.rep, wb.io.release))
// synchronization stuff
......
......@@ -252,7 +252,7 @@ class TLB(Width: Int, isDtlb: Boolean) extends TlbModule with HasCSRConst{
val state = RegInit(state_idle)
ptw <> DontCare // TODO: need check it
ptw.req.valid := ParallelOR(miss).asBool && state===state_idle
ptw.req.valid := ParallelOR(miss).asBool && state===state_idle && !sfence.valid
ptw.resp.ready := state===state_wait
// val ptwReqSeq = Wire(Seq.fill(Width)(new comBundle()))
......@@ -314,6 +314,8 @@ class TLB(Width: Int, isDtlb: Boolean) extends TlbModule with HasCSRConst{
// sfence (flush)
when (sfence.valid) {
state := state_idle
ptw.req.valid := false.B
when (sfence.bits.rs1) { // virtual address *.rs1 <- (rs1===0.U)
when (sfence.bits.rs2) { // asid, but i do not want to support asid, *.rs2 <- (rs2===0.U)
// all addr and all asid
......
......@@ -224,7 +224,7 @@ class ICacheImp(outer: ICache) extends ICacheModule(outer)
val metas = metaArray.io.r.resp.asTypeOf(Vec(nWays,new ICacheMetaBundle))
val datas =dataArray.map(b => RegEnable(next=b.io.r.resp.asTypeOf(Vec(nWays,new ICacheDataBundle)), enable=s2_fire))
val validMeta = Cat((0 until nWays).map{w => validArray(Cat(s2_idx, w.U))}.reverse).asUInt
val validMeta = Cat((0 until nWays).map{w => validArray(Cat(s2_idx, w.U(2.W)))}.reverse).asUInt
// hit check and generate victim cacheline mask
val hitVec = VecInit((0 until nWays).map{w => metas(w).tag === s2_tag && validMeta(w) === 1.U})
......
......@@ -60,6 +60,8 @@ class MissEntry(edge: TLEdgeOut) extends DCacheModule
// watch prober's write back requests
val probe_wb_req = Flipped(ValidIO(new WritebackReq(edge.bundle.sourceBits)))
val probe_active = Flipped(ValidIO(UInt()))
})
// MSHR:
......@@ -70,7 +72,7 @@ class MissEntry(edge: TLEdgeOut) extends DCacheModule
// 5. wait for client's finish
// 6. update meta data
// 7. done
val s_invalid :: s_meta_read_req :: s_meta_read_resp :: s_decide_next_state :: s_wb_req :: s_wb_resp :: s_refill_req :: s_refill_resp :: s_data_write_req :: s_mem_finish :: s_send_resp :: s_client_finish :: s_meta_write_req :: Nil = Enum(13)
val s_invalid :: s_meta_read_req :: s_meta_read_resp :: s_decide_next_state :: s_refill_req :: s_refill_resp :: s_mem_finish :: s_wait_probe_exit :: s_send_resp :: s_wb_req :: s_wb_resp :: s_data_write_req :: s_meta_write_req :: s_client_finish :: Nil = Enum(14)
val state = RegInit(s_invalid)
......@@ -332,7 +334,14 @@ class MissEntry(edge: TLEdgeOut) extends DCacheModule
when (io.mem_finish.fire()) {
grantack.valid := false.B
state := s_wait_probe_exit
}
}
when (state === s_wait_probe_exit) {
// we only wait for probe, when prober is manipulating our set
val should_wait_for_probe_exit = io.probe_active.valid && io.probe_active.bits === req_idx
when (!should_wait_for_probe_exit) {
// no data
when (early_response) {
// load miss respond right after finishing tilelink transactions
......@@ -359,10 +368,12 @@ class MissEntry(edge: TLEdgeOut) extends DCacheModule
}
}
// during refill, probe may step in, it may release our blocks
// if it releases the block we are trying to acquire, we don't care, since we will get it back eventually
// but we need to know whether it releases the block we are trying to evict
val prober_writeback_our_block = (state === s_refill_req || state === s_refill_resp) &&
val prober_writeback_our_block = (state === s_refill_req || state === s_refill_resp ||
state === s_mem_finish || state === s_wait_probe_exit || state === s_send_resp || state === s_wb_req) &&
io.probe_wb_req.valid && !io.probe_wb_req.bits.voluntary &&
io.probe_wb_req.bits.tag === req_old_meta.tag &&
io.probe_wb_req.bits.idx === req_idx &&
......@@ -475,6 +486,7 @@ class MissQueue(edge: TLEdgeOut) extends DCacheModule with HasTLDump
val wb_resp = Input(Bool())
val probe_wb_req = Flipped(ValidIO(new WritebackReq(edge.bundle.sourceBits)))
val probe_active = Flipped(ValidIO(UInt()))
val inflight_req_idxes = Output(Vec(cfg.nMissEntries, Valid(UInt())))
val inflight_req_block_addrs = Output(Vec(cfg.nMissEntries, Valid(UInt())))
......@@ -527,6 +539,7 @@ class MissQueue(edge: TLEdgeOut) extends DCacheModule with HasTLDump
wb_req_arb.io.in(i) <> entry.io.wb_req
entry.io.wb_resp := io.wb_resp
entry.io.probe_wb_req <> io.probe_wb_req
entry.io.probe_active <> io.probe_active
entry.io.mem_grant.valid := false.B
entry.io.mem_grant.bits := DontCare
......
......@@ -19,6 +19,7 @@ class ProbeUnit(edge: TLEdgeOut) extends DCacheModule with HasTLDump {
val block = Input(Bool())
val inflight_req_idx = Output(Valid(UInt()))
val inflight_req_block_addr = Output(Valid(UInt()))
val probe_active = Output(Valid(UInt()))
})
val s_invalid :: s_wait_sync :: s_meta_read_req :: s_meta_read_resp :: s_decide_next_state :: s_release :: s_wb_req :: s_wb_resp :: s_meta_write_req :: Nil = Enum(9)
......@@ -54,6 +55,11 @@ class ProbeUnit(edge: TLEdgeOut) extends DCacheModule with HasTLDump {
io.inflight_req_block_addr.valid := state =/= s_invalid
io.inflight_req_block_addr.bits := req_block_addr
// active means nobody is blocking it anymore
// it will run free
io.probe_active.valid := state =/= s_invalid && state =/= s_wait_sync
io.probe_active.bits := req_idx
XSDebug("state: %d\n", state)
when (state === s_invalid) {
......
......@@ -189,6 +189,7 @@ class PTWImp(outer: PTW) extends PtwModule(outer){
val memRdata = Wire(UInt(XLEN.W))
val memPte = memRdata.asTypeOf(new PteBundle)
val memValid = mem.d.valid
val memRespReady = mem.d.ready
val memRespFire = mem.d.fire()
val memReqReady = mem.a.ready
val memReqFire = mem.a.fire()
......@@ -199,7 +200,7 @@ class PTWImp(outer: PTW) extends PtwModule(outer){
val level = RegInit(0.U(2.W)) // 0/1/2
val levelNext = level + 1.U
val latch = Reg(new PtwResp)
val sfenceLatch = RegEnable(false.B, init = false.B, memRespFire) // NOTE: store sfence to disable mem.resp.fire(), but not stall other ptw req
val sfenceLatch = RegEnable(false.B, init = false.B, memValid) // NOTE: store sfence to disable mem.resp.fire(), but not stall other ptw req
/*
* tlbl2
......@@ -325,8 +326,8 @@ class PTWImp(outer: PTW) extends PtwModule(outer){
mem.a.valid := state === state_req &&
((level===0.U && !tlbHit && !l1Hit) ||
(level===1.U && !l2Hit) ||
(level===2.U)) && !sfenceLatch
mem.d.ready := state === state_wait_resp
(level===2.U)) && !sfenceLatch && !sfence.valid
mem.d.ready := state === state_wait_resp || sfenceLatch
val memAddrLatch = RegEnable(memAddr, mem.a.valid)
memRdata := (mem.d.bits.data >> (memAddrLatch(log2Up(l1BusDataWidth/8) - 1, log2Up(XLEN/8)) << log2Up(XLEN)))(XLEN - 1, 0)
......@@ -334,7 +335,7 @@ class PTWImp(outer: PTW) extends PtwModule(outer){
/*
* resp
*/
val ptwFinish = (state===state_req && tlbHit && level===0.U) || ((memPte.isLeaf() || memPte.isPf() || (!memPte.isLeaf() && level===2.U)) && memRespFire) || state===state_wait_ready
val ptwFinish = (state===state_req && tlbHit && level===0.U) || ((memPte.isLeaf() || memPte.isPf() || (!memPte.isLeaf() && level===2.U)) && memRespFire && !sfenceLatch) || state===state_wait_ready
for(i <- 0 until PtwWidth) {
resp(i).valid := valid && arbChosen===i.U && ptwFinish // TODO: add resp valid logic
resp(i).bits.entry := Mux(tlbHit, tlbHitData,
......@@ -346,8 +347,8 @@ class PTWImp(outer: PTW) extends PtwModule(outer){
/*
* refill
*/
assert(!memRespFire || state===state_wait_resp)
when (memRespFire && !memPte.isPf()) {
assert(!memRespFire || (state===state_wait_resp || sfenceLatch))
when (memRespFire && !memPte.isPf() && !sfenceLatch) {
when (level===0.U && !memPte.isLeaf) {
val refillIdx = LFSR64()(log2Up(PtwL1EntrySize)-1,0) // TODO: may be LRU
ptwl1(refillIdx).refill(l1addr, memRdata)
......@@ -436,4 +437,6 @@ class PTWImp(outer: PTW) extends PtwModule(outer){
XSDebug(memReqFire, p"mem req fire addr:0x${Hexadecimal(memAddr)}\n")
XSDebug(memRespFire, p"mem resp fire rdata:0x${Hexadecimal(mem.d.bits.data)} Pte:${memPte}\n")
XSDebug(sfenceLatch, p"ptw has a flushed req waiting for resp... state:${state} mem.a(${mem.a.valid} ${mem.a.ready}) d($memValid} ${memRespReady})\n")
}
......@@ -166,7 +166,9 @@ class WritebackUnit(edge: TLEdgeOut) extends DCacheModule {
when (io.release.fire()) {
data_req_cnt := data_req_cnt + 1.U
when (data_req_cnt === (refillCycles-1).U) {
val last_beat = Mux(should_writeback_data, data_req_cnt === (refillCycles-1).U, true.B)
when (last_beat) {
state := Mux(req.voluntary, s_grant, s_resp)
}
}
......
......@@ -157,7 +157,7 @@ abstract class BPUStage extends XSModule with HasBPUParameter{
val target = Mux(taken, targetSrc(jmpIdx), npc(inLatch.pc, PopCount(inLatch.mask)))
io.pred.bits <> DontCare
io.pred.bits.redirect := target =/= inLatch.target
io.pred.bits.redirect := target =/= inLatch.target || inLatch.saveHalfRVI && !saveHalfRVI
io.pred.bits.taken := taken
io.pred.bits.jmpIdx := jmpIdx
io.pred.bits.hasNotTakenBrs := hasNTBr
......@@ -564,6 +564,7 @@ class BPU extends BaseBPU {
s1.io.in.bits.target := npc(io.in.bits.pc, PopCount(io.in.bits.inMask)) // Deault target npc
s1.io.in.bits.resp <> s1_resp_in
s1.io.in.bits.brInfo <> s1_brInfo_in
s1.io.in.bits.saveHalfRVI := false.B
val s1_hist = RegEnable(io.in.bits.hist, enable=s1_fire)
val s2_hist = RegEnable(s1_hist, enable=s2.io.in.fire())
......
......@@ -169,8 +169,8 @@ class IFU extends XSModule with HasIFUConst
// the previous half of RVI instruction waits until it meets its last half
val if3_hasPrevHalfInstr = prevHalfInstr.valid && (prevHalfInstr.pc + 2.U) === if3_pc
// set to invalid once consumed
val prevHalfConsumed = if3_hasPrevHalfInstr && if3_fire
// set to invalid once consumed or redirect from backend
val prevHalfConsumed = if3_hasPrevHalfInstr && if3_fire || if4_flush
when (prevHalfConsumed) {
if3_prevHalfInstr.valid := false.B
}
......
......@@ -24,8 +24,6 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
val s_invalid :: s_tlb :: s_flush_sbuffer_req :: s_flush_sbuffer_resp :: s_cache_req :: s_cache_resp :: s_finish :: Nil = Enum(7)
val state = RegInit(s_invalid)
val in = Reg(new ExuInput())
// vaddr for stored for exception
val vaddr = Reg(UInt())
val atom_override_xtval = RegInit(false.B)
// paddr after translation
val paddr = Reg(UInt())
......@@ -33,7 +31,7 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
val resp_data = Reg(UInt())
val is_lrsc_valid = Reg(Bool())
ExcitingUtils.addSource(vaddr, "ATOM_EXECPTION_VADDR")
ExcitingUtils.addSource(in.src1, "ATOM_EXECPTION_VADDR")
ExcitingUtils.addSource(atom_override_xtval, "ATOM_OVERRIDE_XTVAL")
// assign default value to output signals
......@@ -58,7 +56,6 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
when (io.in.fire()) {
in := io.in.bits
state := s_tlb
vaddr := in.src1
}
}
......@@ -179,7 +176,7 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
resp_data := LookupTree(in.uop.ctrl.fuOpType, List(
LSUOpType.lr_w -> SignExt(rdataSel(31, 0), XLEN),
LSUOpType.sc_w -> SignExt(rdataSel(31, 0), XLEN),
LSUOpType.sc_w -> rdata,
LSUOpType.amoswap_w -> SignExt(rdataSel(31, 0), XLEN),
LSUOpType.amoadd_w -> SignExt(rdataSel(31, 0), XLEN),
LSUOpType.amoxor_w -> SignExt(rdataSel(31, 0), XLEN),
......@@ -191,7 +188,7 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
LSUOpType.amomaxu_w -> SignExt(rdataSel(31, 0), XLEN),
LSUOpType.lr_d -> SignExt(rdataSel(63, 0), XLEN),
LSUOpType.sc_d -> SignExt(rdataSel(63, 0), XLEN),
LSUOpType.sc_d -> rdata,
LSUOpType.amoswap_d -> SignExt(rdataSel(63, 0), XLEN),
LSUOpType.amoadd_d -> SignExt(rdataSel(63, 0), XLEN),
LSUOpType.amoxor_d -> SignExt(rdataSel(63, 0), XLEN),
......
......@@ -43,6 +43,7 @@ class Lsroq extends XSModule with HasDCacheParameters {
val rollback = Output(Valid(new Redirect))
val dcache = new DCacheLineIO
val uncache = new DCacheWordIO
val roqDeqPtr = Input(UInt(RoqIdxWidth.W))
// val refill = Flipped(Valid(new DCacheLineReq ))
})
......@@ -282,12 +283,12 @@ class Lsroq extends XSModule with HasDCacheParameters {
val loadWbSelVec = VecInit((0 until LsroqSize).map(i => {
allocated(i) && valid(i) && !writebacked(i) && !store(i)
})).asUInt() // use uint instead vec to reduce verilog lines
val loadWbSel = Wire(Vec(StorePipelineWidth, UInt(log2Up(LsroqSize).W)))
val loadWbSel = Wire(Vec(LoadPipelineWidth, UInt(log2Up(LsroqSize).W)))
val lselvec0 = PriorityEncoderOH(loadWbSelVec)
val lselvec1 = PriorityEncoderOH(loadWbSelVec & (~lselvec0).asUInt)
loadWbSel(0) := OHToUInt(lselvec0)
loadWbSel(1) := OHToUInt(lselvec1)
(0 until StorePipelineWidth).map(i => {
(0 until LoadPipelineWidth).map(i => {
// data select
val rdata = data(loadWbSel(i)).data
val func = uop(loadWbSel(i)).ctrl.fuOpType
......@@ -313,6 +314,7 @@ class Lsroq extends XSModule with HasDCacheParameters {
))
io.ldout(i).bits.uop := uop(loadWbSel(i))
io.ldout(i).bits.uop.cf.exceptionVec := data(loadWbSel(i)).exception.asBools
io.ldout(i).bits.uop.lsroqIdx := loadWbSel(i)
io.ldout(i).bits.data := rdataPartialLoad
io.ldout(i).bits.redirectValid := false.B
io.ldout(i).bits.redirect := DontCare
......@@ -348,6 +350,7 @@ class Lsroq extends XSModule with HasDCacheParameters {
(0 until StorePipelineWidth).map(i => {
io.stout(i).bits.uop := uop(storeWbSel(i))
io.stout(i).bits.uop.lsroqIdx := storeWbSel(i)
io.stout(i).bits.uop.cf.exceptionVec := data(storeWbSel(i)).exception.asBools
io.stout(i).bits.data := data(storeWbSel(i)).data
io.stout(i).bits.redirectValid := false.B
......@@ -633,7 +636,7 @@ class Lsroq extends XSModule with HasDCacheParameters {
val commitType = io.commits(0).bits.uop.ctrl.commitType
io.uncache.req.valid := pending(ringBufferTail) && allocated(ringBufferTail) &&
(commitType === CommitType.STORE || commitType === CommitType.LOAD) &&
io.commits(0).bits.uop.lsroqIdx === ringBufferTailExtended &&
io.roqDeqPtr === uop(ringBufferTail).roqIdx &&
!io.commits(0).bits.isWalk
io.uncache.req.bits.cmd := Mux(store(ringBufferTail), MemoryOpConstants.M_XWR, MemoryOpConstants.M_XRD)
......
......@@ -73,6 +73,7 @@ class MemToBackendIO extends XSBundle {
val commits = Flipped(Vec(CommitWidth, Valid(new RoqCommit)))
val dp1Req = Vec(RenameWidth, Flipped(DecoupledIO(new MicroOp)))
val lsroqIdxs = Output(Vec(RenameWidth, UInt(LsroqIdxWidth.W)))
val roqDeqPtr = Input(UInt(RoqIdxWidth.W))
}
class Memend extends XSModule {
......@@ -139,6 +140,7 @@ class Memend extends XSModule {
lsroq.io.dp1Req <> io.backend.dp1Req
lsroq.io.lsroqIdxs <> io.backend.lsroqIdxs
lsroq.io.brqRedirect := io.backend.redirect
lsroq.io.roqDeqPtr := io.backend.roqDeqPtr
io.backend.replayAll <> lsroq.io.rollback
lsroq.io.dcache <> io.loadMiss
......
......@@ -349,7 +349,7 @@ class Sbuffer extends XSModule with HasSBufferConst {
}
}
XSDebug(flush.valid, p"Reveive flush. f_state:${f_state} state:${state}\n")
XSDebug(flush.valid, p"Reveive flush. f_state:${f_state}\n")
XSDebug(f_state =/= f_idle || flush.valid, p"f_state:${f_state} idx:${wb_arb.io.in(FlushPort).bits} In(${wb_arb.io.in(FlushPort).valid} ${wb_arb.io.in(FlushPort).ready}) wb_resp:${wb_resp}\n")
// write back unit
......
......@@ -18,6 +18,8 @@ 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;
static void (*ref_difftest_exec)(uint64_t n) = NULL;
static void (*ref_difftest_raise_intr)(uint64_t NO) = NULL;
......@@ -66,6 +68,12 @@ void init_difftest() {
ref_difftest_set_mastatus = (void (*)(const void *))dlsym(handle, "difftest_set_mastatus");
assert(ref_difftest_set_mastatus);
ref_difftest_get_csr = (void (*)(void *))dlsym(handle, "difftest_get_csr");
assert(ref_difftest_get_csr);
ref_difftest_set_csr = (void (*)(const void *))dlsym(handle, "difftest_set_csr");
assert(ref_difftest_set_csr);
ref_disambiguate_exec = (vaddr_t (*)(void *))dlsym(handle, "disambiguate_exec");
assert(ref_disambiguate_exec);
......@@ -158,6 +166,7 @@ int difftest_step(DiffState *s) {
if(s->sync.scFailed){
struct SyncState sync;
sync.lrscValid = 0;
sync.lrscAddr = 0;
ref_difftest_set_mastatus((uint64_t*)&sync); // sync lr/sc microarchitectural regs
}
......@@ -190,7 +199,7 @@ int difftest_step(DiffState *s) {
// single step exec
// IPF, LPF, SPF
if(s->cause == 12 || s->cause == 13 || s->cause == 15){
printf("s->cause %ld\n", s->cause);
// printf("s->cause %ld\n", s->cause);
ref_disambiguate_exec(&s->cause);
}else{
ref_difftest_exec(1);
......
......@@ -44,6 +44,7 @@ struct SyncChannel {
struct SyncState {
uint64_t lrscValid;
uint64_t lrscAddr;
};
struct DiffState {
......@@ -72,10 +73,10 @@ 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_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);
void init_difftest();
......
#include "emu.h"
#include "sdcard.h"
#include "difftest.h"
#include <getopt.h>
......@@ -274,11 +275,18 @@ uint64_t Emulator::execute(uint64_t n) {
poll_event();
lasttime_poll = t;
}
static int snapshot_count = 0;
if (t - lasttime_snapshot > 1000 * SNAPSHOT_INTERVAL) {
// save snapshot every 10s
time_t now = time(NULL);
snapshot_save(snapshot_filename(now));
lasttime_snapshot = t;
// dump snapshot to file every 10 minutes
snapshot_count++;
if (snapshot_count == 60) {
snapshot_slot[0].save();
snapshot_count = 0;
}
}
}
......@@ -366,6 +374,17 @@ void Emulator::snapshot_save(const char *filename) {
ref_difftest_get_mastatus(&sync_mastate);
stream.unbuf_write(&sync_mastate, sizeof(struct SyncState));
uint64_t csr_buf[4096];
ref_difftest_get_csr(csr_buf);
stream.unbuf_write(&csr_buf, sizeof(csr_buf));
long sdcard_offset;
if(fp)
sdcard_offset = ftell(fp);
else
sdcard_offset = 0;
stream.unbuf_write(&sdcard_offset, sizeof(sdcard_offset));
// actually write to file in snapshot_finalize()
}
......@@ -395,4 +414,13 @@ void Emulator::snapshot_load(const char *filename) {
struct SyncState sync_mastate;
stream.read(&sync_mastate, sizeof(struct SyncState));
ref_difftest_set_mastatus(&sync_mastate);
uint64_t csr_buf[4096];
stream.read(&csr_buf, sizeof(csr_buf));
ref_difftest_set_csr(csr_buf);
long sdcard_offset = 0;
stream.read(&sdcard_offset, sizeof(sdcard_offset));
if(fp)
fseek(fp, sdcard_offset, SEEK_SET);
}
#include "common.h"
#include "sdcard.h"
extern "C" {
FILE *fp = NULL;
static FILE *fp = NULL;
extern "C" {
void sd_setaddr(uint32_t addr) {
fseek(fp, addr, SEEK_SET);
......@@ -17,7 +18,7 @@ void sd_read(uint32_t *data) {
}
void init_sd(void) {
fp = fopen("/home/yzh/projectn/debian.img", "r");
fp = fopen("/home/xyn/debian/debian.img", "r");
if(!fp)
{
eprintf(ANSI_COLOR_MAGENTA "[warning] sdcard img not found\n");
......
#ifndef __SDCARD_H
#define __SDCARD_H
#include "common.h"
extern FILE *fp;
#endif // __SDCARD_H
......@@ -40,9 +40,9 @@ uint8_t uart_getc() {
eprintf(ANSI_COLOR_RED "now = %ds\n" ANSI_COLOR_RESET, now / 1000);
lasttime = now;
}
if (now > 4 * 3600 * 1000) { // 4 hours
ch = uart_dequeue();
}
// if (now > 4 * 3600 * 1000) { // 4 hours
// ch = uart_dequeue();
// }
return ch;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册