提交 2e4b12ad 编写于 作者: Z zoujr

Merge branch 'master' of https://github.com/RISCVERS/XiangShan

......@@ -348,3 +348,4 @@ mill.rdiB
stale_outputs_checked
*.snapshot
......@@ -5,7 +5,7 @@ import chisel3.util._
import xiangshan._
import xiangshan.backend.regfile.Regfile
import xiangshan.backend.exu._
import xiangshan.backend.issue.ReservationStationNew
import xiangshan.backend.issue.{ReservationStationCtrl, ReservationStationData}
class FpBlockToCtrlIO extends XSBundle {
......@@ -78,28 +78,30 @@ class FloatBlock
s"delay:${certainLatency}"
)
val rs = Module(new ReservationStationNew(
cfg, wakeupCnt, extraListenPortsCnt, fixedDelay = certainLatency, feedback = false
))
val rsCtrl = Module(new ReservationStationCtrl(cfg, wakeupCnt, extraListenPortsCnt, fixedDelay = certainLatency, feedback = false))
val rsData = Module(new ReservationStationData(cfg, wakeupCnt, extraListenPortsCnt, fixedDelay = certainLatency, feedback = false))
rs.io.redirect <> redirect
rs.io.numExist <> io.toCtrlBlock.numExist(i)
rs.io.enqCtrl <> io.fromCtrlBlock.enqIqCtrl(i)
rs.io.enqData <> io.fromCtrlBlock.enqIqData(i)
rsCtrl.io.data <> rsData.io.ctrl
rsCtrl.io.redirect <> redirect // TODO: remove it
rsCtrl.io.numExist <> io.toCtrlBlock.numExist(i)
rsCtrl.io.enqCtrl <> io.fromCtrlBlock.enqIqCtrl(i)
rsData.io.enqData <> io.fromCtrlBlock.enqIqData(i)
rsData.io.redirect <> redirect
rs.io.writeBackedData <> writeBackData
for ((x, y) <- rs.io.extraListenPorts.zip(extraListenPorts)) {
rsData.io.writeBackedData <> writeBackData
for ((x, y) <- rsData.io.extraListenPorts.zip(extraListenPorts)) {
x.valid := y.fire()
x.bits := y.bits
}
exeUnits(i).io.redirect <> redirect
exeUnits(i).io.fromFp <> rs.io.deq
rs.io.tlbFeedback := DontCare
exeUnits(i).io.fromFp <> rsData.io.deq
rsData.io.feedback := DontCare
rs.suggestName(s"rs_${cfg.name}")
rsCtrl.suggestName(s"rsc_${cfg.name}")
rsData.suggestName(s"rsd_${cfg.name}")
rs
rsData
})
for(rs <- reservedStations){
......@@ -157,4 +159,4 @@ class FloatBlock
rf.data := wb.bits.data
}
}
}
\ No newline at end of file
......@@ -6,7 +6,7 @@ import xiangshan._
import xiangshan.backend.exu.Exu.{jumpExeUnitCfg, ldExeUnitCfg, stExeUnitCfg}
import xiangshan.backend.exu.{AluExeUnit, ExuConfig, JumpExeUnit, MulDivExeUnit, Wb}
import xiangshan.backend.fu.FenceToSbuffer
import xiangshan.backend.issue.ReservationStationNew
import xiangshan.backend.issue.{ReservationStationCtrl, ReservationStationData}
import xiangshan.backend.regfile.Regfile
import xiangshan.backend.fu.fpu.Fflags
......@@ -131,28 +131,33 @@ class IntegerBlock
println(s"${i}: exu:${cfg.name} wakeupCnt: ${wakeupCnt} extraListenPorts: ${extraListenPortsCnt} delay:${certainLatency} feedback:${feedback}")
val rs = Module(new ReservationStationNew(
cfg, wakeupCnt, extraListenPortsCnt, fixedDelay = certainLatency, feedback = feedback
))
rs.io.redirect <> redirect
rs.io.numExist <> io.toCtrlBlock.numExist(i)
rs.io.enqCtrl <> io.fromCtrlBlock.enqIqCtrl(i)
rs.io.enqData <> io.fromCtrlBlock.enqIqData(i)
rs.io.writeBackedData <> writeBackData
for ((x, y) <- rs.io.extraListenPorts.zip(extraListenPorts)) {
// val rs = Module(new ReservationStationNew(
// cfg, wakeupCnt, extraListenPortsCnt, fixedDelay = certainLatency, feedback = feedback
// ))
val rsCtrl = Module(new ReservationStationCtrl(cfg, wakeupCnt, extraListenPortsCnt, fixedDelay = certainLatency, feedback = feedback))
val rsData = Module(new ReservationStationData(cfg, wakeupCnt, extraListenPortsCnt, fixedDelay = certainLatency, feedback = feedback))
rsCtrl.io.data <> rsData.io.ctrl
rsCtrl.io.redirect <> redirect // TODO: remove it
rsCtrl.io.numExist <> io.toCtrlBlock.numExist(i)
rsCtrl.io.enqCtrl <> io.fromCtrlBlock.enqIqCtrl(i)
rsData.io.enqData <> io.fromCtrlBlock.enqIqData(i)
rsData.io.redirect <> redirect
rsData.io.writeBackedData <> writeBackData
for ((x, y) <- rsData.io.extraListenPorts.zip(extraListenPorts)) {
x.valid := y.fire()
x.bits := y.bits
}
exeUnits(i).io.redirect <> redirect
exeUnits(i).io.fromInt <> rs.io.deq
rs.io.tlbFeedback := DontCare
exeUnits(i).io.fromInt <> rsData.io.deq
rsData.io.feedback := DontCare
rs.suggestName(s"rs_${cfg.name}")
rsCtrl.suggestName(s"rsc_${cfg.name}")
rsData.suggestName(s"rsd_${cfg.name}")
rs
rsData
})
for(rs <- reservationStations){
......@@ -220,4 +225,4 @@ class IntegerBlock
rf.addr := wb.bits.uop.pdest
rf.data := wb.bits.data
}
}
}
\ No newline at end of file
......@@ -9,7 +9,7 @@ import xiangshan.backend.exu._
import xiangshan.cache._
import xiangshan.mem._
import xiangshan.backend.fu.FenceToSbuffer
import xiangshan.backend.issue.ReservationStationNew
import xiangshan.backend.issue.{ReservationStationCtrl, ReservationStationData}
import xiangshan.backend.fu.FunctionUnit.{lduCfg, mouCfg, stuCfg}
class LsBlockToCtrlIO extends XSBundle {
......@@ -105,26 +105,30 @@ class MemBlock
println(s"${i}: exu:${cfg.name} wakeupCnt: ${wakeupCnt} extraListenPorts: ${extraListenPortsCnt} delay:${certainLatency} feedback:${feedback}")
val rs = Module(new ReservationStationNew(
cfg, wakeupCnt, extraListenPortsCnt, fixedDelay = certainLatency, feedback = feedback
))
val rsCtrl = Module(new ReservationStationCtrl(cfg, wakeupCnt, extraListenPortsCnt, fixedDelay = certainLatency, feedback = feedback))
val rsData = Module(new ReservationStationData(cfg, wakeupCnt, extraListenPortsCnt, fixedDelay = certainLatency, feedback = feedback))
rs.io.redirect <> redirect
rs.io.numExist <> io.toCtrlBlock.numExist(i)
rs.io.enqCtrl <> io.fromCtrlBlock.enqIqCtrl(i)
rs.io.enqData <> io.fromCtrlBlock.enqIqData(i)
rsCtrl.io.data <> rsData.io.ctrl
rsCtrl.io.redirect <> redirect // TODO: remove it
rsCtrl.io.numExist <> io.toCtrlBlock.numExist(i)
rsCtrl.io.enqCtrl <> io.fromCtrlBlock.enqIqCtrl(i)
rsData.io.enqData <> io.fromCtrlBlock.enqIqData(i)
rsData.io.redirect <> redirect
rs.io.writeBackedData <> writeBackData
for ((x, y) <- rs.io.extraListenPorts.zip(extraListenPorts)) {
rsData.io.writeBackedData <> writeBackData
for ((x, y) <- rsData.io.extraListenPorts.zip(extraListenPorts)) {
x.valid := y.fire()
x.bits := y.bits
}
rs.io.tlbFeedback := DontCare
// exeUnits(i).io.redirect <> redirect
// exeUnits(i).io.fromInt <> rsData.io.deq
rsData.io.feedback := DontCare
rs.suggestName(s"rs_${cfg.name}")
rsCtrl.suggestName(s"rsc_${cfg.name}")
rsData.suggestName(s"rsd_${cfg.name}")
rs
rsData
})
for(rs <- reservationStations){
......@@ -166,7 +170,7 @@ class MemBlock
// LoadUnit
for (i <- 0 until exuParameters.LduCnt) {
loadUnits(i).io.redirect <> io.fromCtrlBlock.redirect
loadUnits(i).io.tlbFeedback <> reservationStations(i).io.tlbFeedback
loadUnits(i).io.tlbFeedback <> reservationStations(i).io.feedback
loadUnits(i).io.dtlb <> dtlb.io.requestor(i)
// get input form dispatch
loadUnits(i).io.ldin <> reservationStations(i).io.deq
......@@ -184,7 +188,7 @@ class MemBlock
// StoreUnit
for (i <- 0 until exuParameters.StuCnt) {
storeUnits(i).io.redirect <> io.fromCtrlBlock.redirect
storeUnits(i).io.tlbFeedback <> reservationStations(exuParameters.LduCnt + i).io.tlbFeedback
storeUnits(i).io.tlbFeedback <> reservationStations(exuParameters.LduCnt + i).io.feedback
storeUnits(i).io.dtlb <> dtlb.io.requestor(exuParameters.LduCnt + i)
// get input form dispatch
storeUnits(i).io.stin <> reservationStations(exuParameters.LduCnt + i).io.deq
......@@ -232,6 +236,7 @@ class MemBlock
atomicsUnit.io.dtlb.resp.valid := false.B
atomicsUnit.io.dtlb.resp.bits := DontCare
atomicsUnit.io.dtlb.req.ready := dtlb.io.requestor(0).req.ready
// dispatch 0 takes priority
atomicsUnit.io.in.valid := st0_atomics
......@@ -251,7 +256,7 @@ class MemBlock
when(atomicsUnit.io.tlbFeedback.valid) {
assert(!storeUnits(0).io.tlbFeedback.valid)
atomicsUnit.io.tlbFeedback <> reservationStations(exuParameters.LduCnt + 0).io.tlbFeedback
atomicsUnit.io.tlbFeedback <> reservationStations(exuParameters.LduCnt + 0).io.feedback
}
atomicsUnit.io.dcache <> io.dcache.atomics
......@@ -269,4 +274,4 @@ class MemBlock
lsq.io.exceptionAddr.isStore := io.lsqio.exceptionAddr.isStore
io.lsqio.exceptionAddr.vaddr := Mux(atomicsUnit.io.exceptionAddr.valid, atomicsUnit.io.exceptionAddr.bits, lsq.io.exceptionAddr.vaddr)
}
}
\ No newline at end of file
package xiangshan.backend.exu
import chisel3._
......@@ -15,4 +16,17 @@ class AluExeUnit extends Exu(aluExeUnitCfg)
io.toInt.bits.redirectValid := alu.redirectOutValid
io.toInt.bits.redirect := alu.redirectOut
io.toInt.bits.brUpdate := alu.brUpdate
}
XSDebug(io.fromInt.valid || io.redirect.valid,
p"fromInt(${io.fromInt.valid} ${io.fromInt.ready}) toInt(${io.toInt.valid} ${io.toInt.ready})" +
p"Redirect:(${io.redirect.valid} ${io.redirect.bits.isException}${io.redirect.bits.isFlushPipe}${io.redirect.bits.isMisPred}${io.redirect.bits.isReplay}) roqIdx:${io.redirect.bits.roqIdx}\n",
)
XSDebug(io.fromInt.valid,
p"src1:${Hexadecimal(io.fromInt.bits.src1)} src2:${Hexadecimal(io.fromInt.bits.src2)} " +
p"src3:${Hexadecimal(io.fromInt.bits.src3)} func:${Binary(io.fromInt.bits.uop.ctrl.fuOpType)} " +
p"pc:${Hexadecimal(io.fromInt.bits.uop.cf.pc)} roqIdx:${io.fromInt.bits.uop.roqIdx}\n"
)
XSDebug(io.toInt.valid,
p"res:${Hexadecimal(io.toInt.bits.data)}\n"
)
}
\ No newline at end of file
......@@ -100,7 +100,7 @@ abstract class Exu(val config: ExuConfig) extends XSModule {
val src2 = in.bits.src2
val src3 = in.bits.src3
fu.io.in.valid := in.valid && sel
fu.io.in.valid := in.valid && sel && !in.bits.uop.roqIdx.needFlush(io.redirect)
fu.io.in.bits.uop := in.bits.uop
fu.io.in.bits.src.foreach(_ <> DontCare)
if (fuCfg.srcCnt > 0) {
......
......@@ -11,7 +11,10 @@ class FenceToSbuffer extends XSBundle {
val sbIsEmpty = Input(Bool())
}
class Fence extends FunctionUnit{
// class Fence extends FunctionUnit(FuConfig(
// /*FuType.fence, 1, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false,*/ latency = UncertainLatency()
// )){
class Fence extends FunctionUnit{ // TODO: check it
val sfence = IO(Output(new SfenceBundle))
val fencei = IO(Output(Bool()))
......@@ -43,7 +46,7 @@ class Fence extends FunctionUnit{
when (state === s_sb && valid && func === FenceOpType.fencei && !sbEmpty) { state := s_icache }
when (state === s_sb && valid && func === FenceOpType.sfence && !sbEmpty) { state := s_tlb }
when (state === s_sb && valid && func === FenceOpType.fence && !sbEmpty) { state := s_none }
when (state =/= s_sb && sbEmpty) { state := s_sb }
when (state =/= s_sb && sbEmpty) { state := s_sb }
assert(!(io.out.valid && io.out.bits.uop.ctrl.rfWen))
io.in.ready := state === s_sb
......@@ -54,4 +57,4 @@ class Fence extends FunctionUnit{
assert(!(valid || state =/= s_sb) || io.out.ready) // NOTE: fence instr must be the first(only one) instr, so io.out.ready must be true
XSDebug(valid || state=/=s_sb || io.out.valid, p"In(${io.in.valid} ${io.in.ready}) Out(${io.out.valid} ${io.out.ready}) state:${state} sbuffer(flush:${sbuffer} empty:${sbEmpty}) fencei:${fencei} sfence:${sfence} Inpc:0x${Hexadecimal(io.in.bits.uop.cf.pc)} InroqIdx:${io.in.bits.uop.roqIdx} Outpc:0x${Hexadecimal(io.out.bits.uop.cf.pc)} OutroqIdx:${io.out.bits.uop.roqIdx}\n")
}
}
\ No newline at end of file
......@@ -175,7 +175,8 @@ object FunctionUnit extends HasXSParameter {
val fenceCfg = FuConfig(
fuGen = fence _,
fuSel = (x: FunctionUnit) => x.io.in.bits.uop.ctrl.fuType === FuType.fence,
FuType.fence, 1, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false
FuType.fence, 1, 0, writeIntRf = false, writeFpRf = false, hasRedirect = false,
UncertainLatency() // TODO: need rewrite latency structure, not just this value
)
val csrCfg = FuConfig(
......
......@@ -154,10 +154,8 @@ class TlbResp extends TlbBundle {
}
class TlbRequestIO() extends TlbBundle {
val req = Valid(new TlbReq)
val resp = Flipped(Valid(new TlbResp))
// override def cloneType: this.type = (new TlbRequestIO(Width)).asInstanceOf[this.type]
val req = DecoupledIO(new TlbReq)
val resp = Flipped(DecoupledIO(new TlbResp))
}
class BlockTlbRequestIO() extends TlbBundle {
......@@ -231,6 +229,7 @@ class TLB(Width: Int, isDtlb: Boolean) extends TlbModule with HasCSRConst{
2.U -> Cat(hitppn(i), reqAddr(i).off)
))
req(i).ready := resp(i).ready
resp(i).valid := valid(i)
resp(i).bits.paddr := Mux(vmEnable, paddr, SignExt(req(i).bits.vaddr, PAddrBits))
resp(i).bits.miss := miss(i)
......@@ -279,7 +278,7 @@ class TLB(Width: Int, isDtlb: Boolean) extends TlbModule with HasCSRConst{
}
// reset pf when pf hit
val pfHitReset = ParallelOR(widthMap{i => Mux(valid(i), VecInit(pfHitVec(i)).asUInt, 0.U) })
val pfHitReset = ParallelOR(widthMap{i => Mux(resp(i).fire(), VecInit(pfHitVec(i)).asUInt, 0.U) })
val pfHitRefill = ParallelOR(pfHitReset.asBools)
// refill
......@@ -356,8 +355,8 @@ class TLB(Width: Int, isDtlb: Boolean) extends TlbModule with HasCSRConst{
// Log
for(i <- 0 until Width) {
XSDebug(req(i).valid, p"req(${i.U}): ${req(i).bits}\n")
XSDebug(resp(i).valid, p"resp(${i.U}): ${resp(i).bits}\n")
XSDebug(req(i).valid, p"req(${i.U}): (${req(i).valid} ${req(i).ready}) ${req(i).bits}\n")
XSDebug(resp(i).valid, p"resp(${i.U}): (${resp(i).valid} ${resp(i).ready}) ${resp(i).bits}\n")
}
XSDebug(sfence.valid, p"Sfence: ${sfence}\n")
......@@ -412,27 +411,24 @@ object TLB {
if (!shouldBlock) { // dtlb
for (i <- 0 until width) {
tlb.io.requestor(i).req.valid := in(i).req.valid
tlb.io.requestor(i).req.bits := in(i).req.bits
in(i).req.ready := DontCare
in(i).resp.valid := tlb.io.requestor(i).resp.valid
in(i).resp.bits := tlb.io.requestor(i).resp.bits
tlb.io.requestor(i) <> in(i)
// tlb.io.requestor(i).req.valid := in(i).req.valid
// tlb.io.requestor(i).req.bits := in(i).req.bits
// in(i).req.ready := tlb.io.requestor(i).req.ready
// in(i).resp.valid := tlb.io.requestor(i).resp.valid
// in(i).resp.bits := tlb.io.requestor(i).resp.bits
// tlb.io.requestor(i).resp.ready := in(i).resp.ready
}
} else { // itlb
require(width == 1)
tlb.io.requestor(0).req.valid := in(0).req.valid
tlb.io.requestor(0).req.bits := in(0).req.bits
in(0).req.ready := !tlb.io.requestor(0).resp.bits.miss && in(0).resp.ready
// val pf = LookupTree(tlb.io.requestor(0).req.bits.cmd, List(
// TlbCmd.read -> tlb.io.requestor(0).resp.bits.excp.pf.ld,
// TlbCmd.write -> tlb.io.requestor(0).resp.bits.excp.pf.st,
// TlbCmd.exec -> tlb.io.requestor(0).resp.bits.excp.pf.instr
// ))
in(0).req.ready := !tlb.io.requestor(0).resp.bits.miss && in(0).resp.ready && tlb.io.requestor(0).req.ready
in(0).resp.valid := tlb.io.requestor(0).resp.valid && !tlb.io.requestor(0).resp.bits.miss
in(0).resp.bits := tlb.io.requestor(0).resp.bits
tlb.io.requestor(0).resp.ready := in(0).resp.ready
}
tlb.io.ptw
......
......@@ -459,4 +459,6 @@ class PTWImp(outer: PTW) extends PtwModule(outer){
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")
// TODO: add ptw perf cnt
}
......@@ -9,13 +9,17 @@ import scala.math.min
trait MicroBTBPatameter{
val nWays = 16
val offsetSize = 20
val lowerBitsSize = 20
val tagSize = 20
val extended_stat = false
}
class MicroBTB extends BasePredictor
with MicroBTBPatameter
{
val tagSize = VAddrBits - log2Ceil(PredictWidth) - 1
// val tagSize = VAddrBits - log2Ceil(PredictWidth) - 1
val untaggedBits = PredictWidth + 1
class MicroBTBResp extends Resp
{
......@@ -44,7 +48,7 @@ class MicroBTB extends BasePredictor
override val io = IO(new MicroBTBIO)
io.uBTBBranchInfo <> out_ubtb_br_info
def getTag(pc: UInt) = (pc >> (log2Ceil(PredictWidth) + 1)).asUInt()
def getTag(pc: UInt) = (pc >> untaggedBits)(tagSize-1, 0)
def getBank(pc: UInt) = pc(log2Ceil(PredictWidth) ,1)
class MicroBTBMeta extends XSBundle
......@@ -58,7 +62,7 @@ class MicroBTB extends BasePredictor
class MicroBTBEntry extends XSBundle
{
val offset = SInt(offsetSize.W)
val lower = UInt(lowerBitsSize.W)
}
// val uBTBMeta = RegInit((0.U).asTypeOf(Vec(nWays, Vec(PredictWidth, new MicroBTBMeta))))
......@@ -173,9 +177,9 @@ class MicroBTB extends BasePredictor
val read_resp = Wire(Vec(PredictWidth,new ReadRespEntry))
val read_bank_inOrder = VecInit((0 until PredictWidth).map(b => (read_req_basebank + b.U)(log2Up(PredictWidth)-1,0) ))
val isInNextRow = VecInit((0 until PredictWidth).map(_.U < read_req_basebank))
// val isInNextRow = VecInit((0 until PredictWidth).map(_.U < read_req_basebank))
(0 until PredictWidth).map{ b => metas(b).rtag := Mux(isInNextRow(b),read_req_tag + 1.U,read_req_tag) }
(0 until PredictWidth).map{ b => metas(b).rtag := read_req_tag }
val read_hit_ohs = read_bank_inOrder.map{ b => metas(b).hit_ohs }
val read_hit_vec = VecInit(read_hit_ohs.map{oh => ParallelOR(oh).asBool})
val read_hit_ways = VecInit(read_hit_ohs.map{oh => PriorityEncoder(oh)})
......@@ -193,7 +197,7 @@ class MicroBTB extends BasePredictor
read_resp(i).valid := read_hit_vec(i) && io.inMask(i)
read_resp(i).taken := read_resp(i).valid && uBTBMeta_resp(i).pred(1)
read_resp(i).is_Br := read_resp(i).valid && uBTBMeta_resp(i).is_Br
read_resp(i).target := ((io.pc.bits).asSInt + (i<<1).S + btb_resp(i).offset).asUInt
read_resp(i).target := Cat(io.pc.bits(VAddrBits-1, lowerBitsSize+1), btb_resp(i).asUInt, 0.U(1.W))
read_resp(i).is_RVC := read_resp(i).valid && uBTBMeta_resp(i).is_RVC
out_ubtb_br_info.hits(i) := read_hit_vec(i)
......@@ -250,7 +254,7 @@ class MicroBTB extends BasePredictor
val update_base_bank = getBank(update_fetch_pc)
val update_tag = getTag(update_br_pc)
val update_target = Mux(u.pd.isBr, u.brTarget, u.target)
val update_taget_offset = update_target.asSInt - update_br_pc.asSInt
val update_target_lower = update_target(lowerBitsSize, 1)
val update_is_BR_or_JAL = (u.pd.brType === BrType.branch) || (u.pd.brType === BrType.jal)
......@@ -260,12 +264,12 @@ class MicroBTB extends BasePredictor
//write btb target when miss prediction
// when(entry_write_valid)
// {
// uBTB(update_write_way)(update_bank).offset := update_taget_offset
// uBTB(update_write_way)(update_bank).offset := update_target_offset
// }
for (b <- 0 until PredictWidth) {
datas(b).wen := do_reset || (entry_write_valid && b.U === update_bank)
datas(b).wWay := Mux(do_reset, reset_way, update_write_way)
datas(b).wdata := Mux(do_reset, 0.U.asTypeOf(new MicroBTBEntry), update_taget_offset.asTypeOf(new MicroBTBEntry))
datas(b).wdata := Mux(do_reset, 0.U.asTypeOf(new MicroBTBEntry), update_target_lower.asTypeOf(new MicroBTBEntry))
}
......@@ -296,8 +300,8 @@ class MicroBTB extends BasePredictor
i.U,read_hit_vec(i),read_hit_ways(i),read_resp(i).valid,read_resp(i).is_RVC,read_resp(i).taken,read_resp(i).is_Br,read_resp(i).target,out_ubtb_br_info.writeWay(i))
}
XSDebug(meta_write_valid,"uBTB update: update | pc:0x%x | update hits:%b | | update_write_way:%d | update_bank: %d| update_br_index:%d | update_tag:%x | upadate_offset 0x%x\n "
,update_br_pc,update_hits,update_write_way,update_bank,update_br_idx,update_tag,update_taget_offset(offsetSize-1,0))
XSDebug(meta_write_valid,"uBTB update: update | pc:0x%x | update hits:%b | | update_write_way:%d | update_bank: %d| update_br_index:%d | update_tag:%x | update_lower 0x%x\n "
,update_br_pc,update_hits,update_write_way,update_bank,update_br_idx,update_tag,update_target_lower(lowerBitsSize-1,0))
XSDebug(meta_write_valid, "uBTB update: update_taken:%d | old_pred:%b | new_pred:%b\n",
update_taken, metas(update_bank).rpred,
Mux(!update_hits,
......@@ -306,6 +310,11 @@ class MicroBTB extends BasePredictor
))
}
if (extended_stat) {
val high_identical = update_target(VAddrBits-1, lowerBitsSize) =/= update_fetch_pc(VAddrBits-1, lowerBitsSize)
XSDebug(io.update.valid, "extended_stat: identical %d\n", high_identical)
}
//bypass:read-after-write
// for( b <- 0 until PredictWidth) {
......
......@@ -53,10 +53,10 @@ class LoadForwardQueryIO extends XSBundle {
val uop = Output(new MicroOp) // for replay
val pc = Output(UInt(VAddrBits.W)) //for debug
val valid = Output(Bool()) //for debug
val forwardMask = Input(Vec(8, Bool()))
val forwardData = Input(Vec(8, UInt(8.W)))
// val lqIdx = Output(UInt(LoadQueueIdxWidth.W))
val sqIdx = Output(new SqPtr)
}
}
\ No newline at end of file
......@@ -46,6 +46,7 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
io.dtlb.req.valid := false.B
io.dtlb.req.bits := DontCare
io.dtlb.resp.ready := false.B
io.flush_sbuffer.valid := false.B
......@@ -75,11 +76,12 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
io.dtlb.req.valid := true.B
io.dtlb.req.bits.vaddr := in.src1
io.dtlb.req.bits.roqIdx := in.uop.roqIdx
io.dtlb.resp.ready := true.B
val is_lr = in.uop.ctrl.fuOpType === LSUOpType.lr_w || in.uop.ctrl.fuOpType === LSUOpType.lr_d
io.dtlb.req.bits.cmd := Mux(is_lr, TlbCmd.read, TlbCmd.write)
io.dtlb.req.bits.debug.pc := in.uop.cf.pc
when(io.dtlb.resp.valid && !io.dtlb.resp.bits.miss){
when(io.dtlb.resp.fire && !io.dtlb.resp.bits.miss){
// exception handling
val addrAligned = LookupTree(in.uop.ctrl.fuOpType(1,0), List(
"b00".U -> true.B, //b
......@@ -143,7 +145,7 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
LSUOpType.amomaxu_d -> M_XA_MAXU
))
io.dcache.req.bits.addr := paddr
io.dcache.req.bits.addr := paddr
io.dcache.req.bits.data := genWdata(in.src2, in.uop.ctrl.fuOpType(1,0))
// TODO: atomics do need mask: fix mask
io.dcache.req.bits.mask := genWmask(paddr, in.uop.ctrl.fuOpType(1,0))
......@@ -221,4 +223,4 @@ class AtomicsUnit extends XSModule with MemoryOpConstants{
when(io.redirect.valid){
atom_override_xtval := false.B
}
}
}
\ No newline at end of file
......@@ -22,8 +22,8 @@ class LoadUnit_S0 extends XSModule {
val in = Flipped(Decoupled(new ExuInput))
val out = Decoupled(new LsPipelineBundle)
val redirect = Flipped(ValidIO(new Redirect))
val dtlbReq = Valid(new TlbReq)
val dtlbResp = Flipped(Valid(new TlbResp))
val dtlbReq = DecoupledIO(new TlbReq)
val dtlbResp = Flipped(DecoupledIO(new TlbResp))
val tlbFeedback = ValidIO(new TlbFeedback)
val dcacheReq = DecoupledIO(new DCacheLoadReq)
})
......@@ -40,6 +40,7 @@ class LoadUnit_S0 extends XSModule {
io.dtlbReq.bits.cmd := TlbCmd.read
io.dtlbReq.bits.roqIdx := s0_uop.roqIdx
io.dtlbReq.bits.debug.pc := s0_uop.cf.pc
io.dtlbResp.ready := io.out.ready // TODO: check it: io.out.fire()?
// feedback tlb result to RS
// Note: can be moved to s1
......@@ -293,4 +294,4 @@ class LoadUnit extends XSModule {
when(io.ldout.fire()){
XSDebug("ldout %x iw %x fw %x\n", io.ldout.bits.uop.cf.pc, io.ldout.bits.uop.ctrl.rfWen, io.ldout.bits.uop.ctrl.fpWen)
}
}
}
\ No newline at end of file
......@@ -58,6 +58,7 @@ class StoreUnit extends XSModule {
io.dtlb.req.bits.cmd := TlbCmd.write
io.dtlb.req.bits.roqIdx := io.stin.bits.uop.roqIdx
io.dtlb.req.bits.debug.pc := io.stin.bits.uop.cf.pc
io.dtlb.resp.ready := s2_out.ready
s2_out.bits := DontCare
s2_out.bits.vaddr := saddr
......@@ -134,4 +135,4 @@ class StoreUnit extends XSModule {
// update store buffer according to store fill buffer
}
}
\ No newline at end of file
......@@ -15,6 +15,7 @@ static inline void print_help(const char *file) {
printf("\n");
printf(" -s, --seed=NUM use this seed\n");
printf(" -C, --max-cycles=NUM execute at most NUM cycles\n");
printf(" -I, --max-instr=NUM execute at most NUM instructions\n");
printf(" -i, --image=FILE run with this image file\n");
printf(" -b, --log-begin=NUM display log from NUM th cycle\n");
printf(" -e, --log-end=NUM stop display log at NUM th cycle\n");
......@@ -32,6 +33,7 @@ inline EmuArgs parse_args(int argc, const char *argv[]) {
{ "dump-wave", 0, NULL, 0 },
{ "seed", 1, NULL, 's' },
{ "max-cycles", 1, NULL, 'C' },
{ "max-instr", 1, NULL, 'I' },
{ "image", 1, NULL, 'i' },
{ "log-begin", 1, NULL, 'b' },
{ "log-end", 1, NULL, 'e' },
......@@ -41,7 +43,7 @@ inline EmuArgs parse_args(int argc, const char *argv[]) {
int o;
while ( (o = getopt_long(argc, const_cast<char *const*>(argv),
"-s:C:hi:m:b:e:", long_options, &long_index)) != -1) {
"-s:C:I:hi:m:b:e:", long_options, &long_index)) != -1) {
switch (o) {
case 0:
switch (long_index) {
......@@ -59,6 +61,7 @@ inline EmuArgs parse_args(int argc, const char *argv[]) {
}
break;
case 'C': args.max_cycles = atoll(optarg); break;
case 'I': args.max_instr = atoll(optarg); break;
case 'i': args.image = optarg; break;
case 'b': args.log_begin = atoll(optarg); break;
case 'e': args.log_end = atoll(optarg); break;
......@@ -222,12 +225,13 @@ inline void Emulator::single_cycle() {
cycles ++;
}
uint64_t Emulator::execute(uint64_t n) {
uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
extern void poll_event(void);
extern uint32_t uptime(void);
uint32_t lasttime_poll = 0;
uint32_t lasttime_snapshot = 0;
uint64_t lastcommit = n;
uint64_t lastcommit = max_cycle;
uint64_t instr_left_last_cycle = max_instr;
const int stuck_limit = 2000;
uint32_t wdst[DIFFTEST_WIDTH];
......@@ -240,14 +244,19 @@ uint64_t Emulator::execute(uint64_t n) {
diff.wdata = wdata;
diff.wdst = wdst;
while (trapCode == STATE_RUNNING && n > 0) {
while (trapCode == STATE_RUNNING) {
if (!(max_cycle > 0 && max_instr > 0 && instr_left_last_cycle >= max_instr /* handle overflow */)) {
trapCode = STATE_LIMIT_EXCEEDED;
break;
}
single_cycle();
n --;
max_cycle --;
if (dut_ptr->io_trap_valid) trapCode = dut_ptr->io_trap_code;
if (trapCode != STATE_RUNNING) break;
if (lastcommit - n > stuck_limit && hascommit) {
if (lastcommit - 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);
......@@ -283,7 +292,11 @@ uint64_t Emulator::execute(uint64_t n) {
if (difftest_step(&diff)) {
trapCode = STATE_ABORT;
}
lastcommit = n;
lastcommit = max_cycle;
// update instr_cnt
instr_left_last_cycle = max_instr;
max_instr -= diff.commit;
}
uint32_t t = uptime();
......@@ -355,6 +368,9 @@ void Emulator::display_trapinfo() {
case STATE_ABORT:
eprintf(ANSI_COLOR_RED "ABORT at pc = 0x%" PRIx64 "\n" ANSI_COLOR_RESET, pc);
break;
case STATE_LIMIT_EXCEEDED:
eprintf(ANSI_COLOR_YELLOW "EXCEEDING CYCLE/INSTR LIMIT at pc = 0x%" PRIx64 "\n" ANSI_COLOR_RESET, pc);
break;
default:
eprintf(ANSI_COLOR_RED "Unknown trap code: %d\n", trapCode);
}
......
......@@ -9,6 +9,7 @@
struct EmuArgs {
uint32_t seed;
uint64_t max_cycles;
uint64_t max_instr;
uint64_t log_begin, log_end;
const char *image;
const char *snapshot_path;
......@@ -17,6 +18,7 @@ struct EmuArgs {
EmuArgs() {
seed = 0;
max_cycles = -1;
max_instr = -1;
log_begin = 1;
log_end = -1;
snapshot_path = NULL;
......@@ -38,6 +40,7 @@ class Emulator {
STATE_GOODTRAP = 0,
STATE_BADTRAP,
STATE_ABORT,
STATE_LIMIT_EXCEEDED,
STATE_RUNNING = -1
};
......@@ -60,7 +63,7 @@ class Emulator {
public:
Emulator(int argc, const char *argv[]);
~Emulator();
uint64_t execute(uint64_t n);
uint64_t execute(uint64_t max_cycle, uint64_t max_instr);
uint64_t get_cycles() const { return cycles; }
EmuArgs get_args() const { return args; }
bool is_good_trap() { return trapCode == STATE_GOODTRAP; };
......
......@@ -19,7 +19,7 @@ int main(int argc, const char** argv) {
};
auto args = emu->get_args();
uint64_t cycles = emu->execute(args.max_cycles);
uint64_t cycles = emu->execute(args.max_cycles, args.max_instr);
bool is_good_trap = emu->is_good_trap();
delete emu;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册