first cut at pending scoreboarding
This commit is contained in:
parent
4fd01d82b8
commit
b08dced37c
@ -446,17 +446,28 @@ abstract class L2XactTracker extends XactTracker with L2HellaCacheParameters {
|
|||||||
(Mux(!full_block, beat, multi_cnt), Mux(!full_block, inc, multi_done))
|
(Mux(!full_block, beat, multi_cnt), Mux(!full_block, inc, multi_done))
|
||||||
} else { (UInt(0), inc) }
|
} else { (UInt(0), inc) }
|
||||||
}
|
}
|
||||||
|
|
||||||
def connectInternalDataBeatCounter[T <: HasL2BeatAddr](
|
def connectInternalDataBeatCounter[T <: HasL2BeatAddr](
|
||||||
in: DecoupledIO[T],
|
in: DecoupledIO[T],
|
||||||
beat: UInt = UInt(0),
|
beat: UInt = UInt(0),
|
||||||
full_block: Bool = Bool(true)) = {
|
full_block: Bool = Bool(true)) = {
|
||||||
connectDataBeatCounter(in.fire(), in.bits, beat, full_block)
|
connectDataBeatCounter(in.fire(), in.bits, beat, full_block)
|
||||||
}
|
}
|
||||||
|
|
||||||
def connectInternalDataBeatCounter[T <: HasL2Data](
|
def connectInternalDataBeatCounter[T <: HasL2Data](
|
||||||
in: ValidIO[T],
|
in: ValidIO[T],
|
||||||
full_block: Bool = Bool(true)) = {
|
full_block: Bool = Bool(true)) = {
|
||||||
connectDataBeatCounter(in.valid, in.bits, UInt(0), full_block)._2
|
connectDataBeatCounter(in.valid, in.bits, UInt(0), full_block)._2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def addInternalPendingBit[T <: HasL2BeatAddr](in: DecoupledIO[T]) =
|
||||||
|
Fill(in.bits.refillCycles, in.fire()) & UIntToOH(in.bits.addr_beat)
|
||||||
|
|
||||||
|
def dropPendingBit[T <: HasL2BeatAddr] (in: DecoupledIO[T]) =
|
||||||
|
Fill(in.bits.refillCycles, in.fire()) & ~UIntToOH(in.bits.addr_beat)
|
||||||
|
|
||||||
|
def dropInternalPendingBit[T <: HasL2BeatAddr] (in: ValidIO[T]) =
|
||||||
|
Fill(in.bits.refillCycles, in.valid) & ~UIntToOH(in.bits.addr_beat)
|
||||||
}
|
}
|
||||||
|
|
||||||
class L2VoluntaryReleaseTracker(trackerId: Int, bankId: Int) extends L2XactTracker {
|
class L2VoluntaryReleaseTracker(trackerId: Int, bankId: Int) extends L2XactTracker {
|
||||||
@ -591,8 +602,6 @@ class L2AcquireTracker(trackerId: Int, bankId: Int) extends L2XactTracker {
|
|||||||
val xact_meta = Reg{ new L2Metadata }
|
val xact_meta = Reg{ new L2Metadata }
|
||||||
val xact_way_en = Reg{ Bits(width = nWays) }
|
val xact_way_en = Reg{ Bits(width = nWays) }
|
||||||
val pending_coh = Reg{ xact_meta.coh.clone }
|
val pending_coh = Reg{ xact_meta.coh.clone }
|
||||||
val pending_finish = Reg{ io.outer.finish.bits.clone }
|
|
||||||
val ignt_q = Module(new Queue(new L2SecondaryMissInfo, nSecondaryMisses))(innerTLParams)
|
|
||||||
|
|
||||||
val is_hit = xact_tag_match && xact_meta.coh.outer.isHit(xact.op_code())
|
val is_hit = xact_tag_match && xact_meta.coh.outer.isHit(xact.op_code())
|
||||||
val do_allocate = xact.allocate()
|
val do_allocate = xact.allocate()
|
||||||
@ -611,18 +620,38 @@ class L2AcquireTracker(trackerId: Int, bankId: Int) extends L2XactTracker {
|
|||||||
val mask_incoherent = mask_self & ~io.incoherent.toBits
|
val mask_incoherent = mask_self & ~io.incoherent.toBits
|
||||||
|
|
||||||
val irel_data_done = connectIncomingDataBeatCounter(io.inner.release)
|
val irel_data_done = connectIncomingDataBeatCounter(io.inner.release)
|
||||||
val ognt_data_done = connectIncomingDataBeatCounter(io.outer.grant)
|
|
||||||
val (oacq_data_cnt, oacq_data_done) = connectOutgoingDataBeatCounter(io.outer.acquire, xact.addr_beat)
|
val (oacq_data_cnt, oacq_data_done) = connectOutgoingDataBeatCounter(io.outer.acquire, xact.addr_beat)
|
||||||
|
val ognt_data_done = connectIncomingDataBeatCounter(io.outer.grant)
|
||||||
|
val pending_ofin = Reg{ io.outer.finish.bits.clone }
|
||||||
|
|
||||||
|
val ignt_q = Module(new Queue(new L2SecondaryMissInfo, nSecondaryMisses))(innerTLParams)
|
||||||
val (ignt_data_idx, ignt_data_done) = connectOutgoingDataBeatCounter(io.inner.grant, ignt_q.io.deq.bits.addr_beat)
|
val (ignt_data_idx, ignt_data_done) = connectOutgoingDataBeatCounter(io.inner.grant, ignt_q.io.deq.bits.addr_beat)
|
||||||
|
ignt_q.io.enq.valid := Bool(false)
|
||||||
|
ignt_q.io.enq.bits.client_xact_id := io.iacq().client_xact_id
|
||||||
|
ignt_q.io.enq.bits.addr_beat := io.iacq().addr_beat
|
||||||
|
ignt_q.io.deq.ready := ignt_data_done
|
||||||
|
|
||||||
val ifin_cnt = Reg(init = UInt(0, width = log2Up(nSecondaryMisses+1)))
|
val ifin_cnt = Reg(init = UInt(0, width = log2Up(nSecondaryMisses+1)))
|
||||||
when(ignt_data_done) { ifin_cnt := ifin_cnt + UInt(1) }
|
when(ignt_data_done) { ifin_cnt := ifin_cnt + UInt(1) }
|
||||||
|
|
||||||
val pending_reads = Reg(init=Bits(0, width = innerDataBeats))
|
val pending_reads = Reg(init=Bits(0, width = innerDataBeats))
|
||||||
val pending_writes = Reg(init=Bits(0, width = innerDataBeats))
|
pending_reads := pending_reads |
|
||||||
val pending_resps = Reg(init=Bits(0, width = innerDataBeats))
|
addPendingBit(io.inner.acquire) |
|
||||||
|
dropPendingBit(io.data.read)
|
||||||
val curr_read_beat = PriorityEncoder(pending_reads)
|
val curr_read_beat = PriorityEncoder(pending_reads)
|
||||||
|
|
||||||
|
val pending_writes = Reg(init=Bits(0, width = innerDataBeats))
|
||||||
|
pending_writes := pending_writes |
|
||||||
|
addPendingBit(io.inner.acquire) |
|
||||||
|
addPendingBit(io.inner.release) |
|
||||||
|
addPendingBit(io.outer.grant) &
|
||||||
|
dropPendingBit(io.data.write)
|
||||||
val curr_write_beat = PriorityEncoder(pending_writes)
|
val curr_write_beat = PriorityEncoder(pending_writes)
|
||||||
|
|
||||||
|
val pending_resps = Reg(init=Bits(0, width = innerDataBeats))
|
||||||
|
pending_resps := pending_resps |
|
||||||
|
addInternalPendingBit(io.data.read) &
|
||||||
|
dropInternalPendingBit(io.data.resp)
|
||||||
|
|
||||||
val pending_coh_on_hit = HierarchicalMetadata(
|
val pending_coh_on_hit = HierarchicalMetadata(
|
||||||
io.meta.resp.bits.meta.coh.inner,
|
io.meta.resp.bits.meta.coh.inner,
|
||||||
io.meta.resp.bits.meta.coh.outer.onHit(xact.op_code()))
|
io.meta.resp.bits.meta.coh.outer.onHit(xact.op_code()))
|
||||||
@ -720,8 +749,8 @@ class L2AcquireTracker(trackerId: Int, bankId: Int) extends L2XactTracker {
|
|||||||
io.outer.release.valid := Bool(false)
|
io.outer.release.valid := Bool(false)
|
||||||
io.outer.grant.ready := Bool(false)
|
io.outer.grant.ready := Bool(false)
|
||||||
io.outer.finish.valid := Bool(false)
|
io.outer.finish.valid := Bool(false)
|
||||||
io.outer.finish.bits := pending_finish
|
io.outer.finish.bits := pending_ofin
|
||||||
val pending_finish_on_ognt = io.ognt().makeFinish()
|
val pending_ofin_on_ognt = io.ognt().makeFinish()
|
||||||
|
|
||||||
io.inner.probe.valid := Bool(false)
|
io.inner.probe.valid := Bool(false)
|
||||||
io.inner.probe.bits.header.src := UInt(bankId)
|
io.inner.probe.bits.header.src := UInt(bankId)
|
||||||
@ -739,7 +768,6 @@ class L2AcquireTracker(trackerId: Int, bankId: Int) extends L2XactTracker {
|
|||||||
amo_result,
|
amo_result,
|
||||||
data_buffer(ignt_data_idx)))
|
data_buffer(ignt_data_idx)))
|
||||||
io.ignt().client_xact_id := ignt_q.io.deq.bits.client_xact_id
|
io.ignt().client_xact_id := ignt_q.io.deq.bits.client_xact_id
|
||||||
ignt_q.io.deq.ready := ignt_data_done
|
|
||||||
|
|
||||||
io.inner.acquire.ready := state === s_idle ||
|
io.inner.acquire.ready := state === s_idle ||
|
||||||
can_merge_iacq_put ||
|
can_merge_iacq_put ||
|
||||||
@ -789,6 +817,7 @@ class L2AcquireTracker(trackerId: Int, bankId: Int) extends L2XactTracker {
|
|||||||
pending_writes := UInt(0)
|
pending_writes := UInt(0)
|
||||||
pending_resps := UInt(0)
|
pending_resps := UInt(0)
|
||||||
ifin_cnt := UInt(0)
|
ifin_cnt := UInt(0)
|
||||||
|
ignt_q.io.enq.valid := Bool(true)
|
||||||
state := s_meta_read
|
state := s_meta_read
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -842,7 +871,6 @@ class L2AcquireTracker(trackerId: Int, bankId: Int) extends L2XactTracker {
|
|||||||
when(io.irel().hasData()) {
|
when(io.irel().hasData()) {
|
||||||
pending_coh.outer := pending_ocoh_on_irel
|
pending_coh.outer := pending_ocoh_on_irel
|
||||||
mergeDataInner(io.irel().addr_beat, io.irel().data)
|
mergeDataInner(io.irel().addr_beat, io.irel().data)
|
||||||
pending_writes := pending_writes | UIntToOH(io.irel().addr_beat)
|
|
||||||
}
|
}
|
||||||
// We don't decrement release_count until we've received all the data beats.
|
// We don't decrement release_count until we've received all the data beats.
|
||||||
when(!io.irel().hasMultibeatData() || irel_data_done) {
|
when(!io.irel().hasMultibeatData() || irel_data_done) {
|
||||||
@ -866,14 +894,13 @@ class L2AcquireTracker(trackerId: Int, bankId: Int) extends L2XactTracker {
|
|||||||
when(io.outer.grant.valid) {
|
when(io.outer.grant.valid) {
|
||||||
when(io.ognt().hasData()) {
|
when(io.ognt().hasData()) {
|
||||||
mergeDataOuter(io.ognt().addr_beat, io.ognt().data)
|
mergeDataOuter(io.ognt().addr_beat, io.ognt().data)
|
||||||
pending_writes := pending_writes | UIntToOH(io.ognt().addr_beat)
|
|
||||||
}
|
}
|
||||||
when(ognt_data_done) {
|
when(ognt_data_done) {
|
||||||
pending_coh := pending_coh_on_ognt
|
pending_coh := pending_coh_on_ognt
|
||||||
when(io.ognt().requiresAck()) {
|
when(io.ognt().requiresAck()) {
|
||||||
pending_finish.payload := pending_finish_on_ognt
|
pending_ofin.payload := pending_ofin_on_ognt
|
||||||
pending_finish.header.dst := io.outer.grant.bits.header.src
|
pending_ofin.header.dst := io.outer.grant.bits.header.src
|
||||||
pending_finish.header.src := UInt(bankId)
|
pending_ofin.header.src := UInt(bankId)
|
||||||
state := s_outer_finish
|
state := s_outer_finish
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
state := Mux(!do_allocate, s_inner_grant,
|
state := Mux(!do_allocate, s_inner_grant,
|
||||||
@ -892,18 +919,10 @@ class L2AcquireTracker(trackerId: Int, bankId: Int) extends L2XactTracker {
|
|||||||
is(s_data_read) {
|
is(s_data_read) {
|
||||||
io.data.read.valid := pending_reads.orR
|
io.data.read.valid := pending_reads.orR
|
||||||
when(io.data.read.ready) {
|
when(io.data.read.ready) {
|
||||||
pending_resps := pending_resps | UIntToOH(curr_read_beat)
|
|
||||||
pending_reads := pending_reads & ~UIntToOH(curr_read_beat)
|
|
||||||
when(PopCount(pending_reads) <= UInt(1)) { state := s_data_resp }
|
when(PopCount(pending_reads) <= UInt(1)) { state := s_data_resp }
|
||||||
}
|
}
|
||||||
when(io.data.resp.valid) {
|
when(io.data.resp.valid) {
|
||||||
mergeDataInternal(io.data.resp.bits.addr_beat, io.data.resp.bits.data)
|
mergeDataInternal(io.data.resp.bits.addr_beat, io.data.resp.bits.data)
|
||||||
pending_resps := pending_resps & ~UIntToOH(io.data.resp.bits.addr_beat)
|
|
||||||
}
|
|
||||||
when(io.data.read.ready && io.data.resp.valid) {
|
|
||||||
pending_resps := (pending_resps &
|
|
||||||
~UIntToOH(io.data.resp.bits.addr_beat)) |
|
|
||||||
UIntToOH(curr_read_beat)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is(s_data_resp) {
|
is(s_data_resp) {
|
||||||
@ -918,7 +937,6 @@ class L2AcquireTracker(trackerId: Int, bankId: Int) extends L2XactTracker {
|
|||||||
is(s_data_write) {
|
is(s_data_write) {
|
||||||
io.data.write.valid := pending_writes.orR //TODO make sure all acquire data is present
|
io.data.write.valid := pending_writes.orR //TODO make sure all acquire data is present
|
||||||
when(io.data.write.ready) {
|
when(io.data.write.ready) {
|
||||||
pending_writes := pending_writes & ~UIntToOH(curr_write_beat)
|
|
||||||
when(PopCount(pending_writes) <= UInt(1)) { state := s_inner_grant }
|
when(PopCount(pending_writes) <= UInt(1)) { state := s_inner_grant }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -950,20 +968,12 @@ class L2AcquireTracker(trackerId: Int, bankId: Int) extends L2XactTracker {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ignt_q.io.enq.valid := io.inner.acquire.fire() &&
|
|
||||||
(state === s_idle || !xact.hasMultibeatData())
|
|
||||||
ignt_q.io.enq.bits.client_xact_id := io.iacq().client_xact_id
|
|
||||||
ignt_q.io.enq.bits.addr_beat := io.iacq().addr_beat
|
|
||||||
|
|
||||||
// Handle Get and Put merging
|
// Handle Get and Put merging
|
||||||
when(io.inner.acquire.fire()) {
|
when(io.inner.acquire.fire() && io.iacq().hasData()) {
|
||||||
val beat = io.iacq().addr_beat
|
mergeDataPut(io.iacq().addr_beat, io.iacq().wmask(), io.iacq().data)
|
||||||
when(io.iacq().hasData()) {
|
when(!xact.hasMultibeatData()) { ignt_q.io.enq.valid := Bool(true) }
|
||||||
mergeDataPut(beat, io.iacq().wmask(), io.iacq().data)
|
//iacq_data_valid(beat) := Bool(true)
|
||||||
//iacq_data_valid(beat) := Bool(true)
|
|
||||||
pending_writes := pending_writes | UIntToOH(io.iacq().addr_beat)
|
|
||||||
}
|
|
||||||
when(state != s_idle) { pending_reads := pending_reads | UIntToOH(io.iacq().addr_beat) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(!(state != s_idle && io.inner.acquire.fire() &&
|
assert(!(state != s_idle && io.inner.acquire.fire() &&
|
||||||
@ -1007,7 +1017,7 @@ class L2WritebackUnit(trackerId: Int, bankId: Int) extends L2XactTracker {
|
|||||||
val xact_way_en = Reg{ Bits(width = nWays) }
|
val xact_way_en = Reg{ Bits(width = nWays) }
|
||||||
val data_buffer = Vec.fill(innerDataBeats){ Reg(io.irel().data.clone) }
|
val data_buffer = Vec.fill(innerDataBeats){ Reg(io.irel().data.clone) }
|
||||||
val xact_id = Reg{ UInt() }
|
val xact_id = Reg{ UInt() }
|
||||||
val pending_finish = Reg{ io.outer.finish.bits.clone }
|
val pending_ofin = Reg{ io.outer.finish.bits.clone }
|
||||||
|
|
||||||
val irel_had_data = Reg(init = Bool(false))
|
val irel_had_data = Reg(init = Bool(false))
|
||||||
val release_count = Reg(init = UInt(0, width = log2Up(nCoherentClients+1)))
|
val release_count = Reg(init = UInt(0, width = log2Up(nCoherentClients+1)))
|
||||||
@ -1043,8 +1053,8 @@ class L2WritebackUnit(trackerId: Int, bankId: Int) extends L2XactTracker {
|
|||||||
io.outer.release.bits.header.src := UInt(bankId)
|
io.outer.release.bits.header.src := UInt(bankId)
|
||||||
io.outer.grant.ready := Bool(false) // default
|
io.outer.grant.ready := Bool(false) // default
|
||||||
io.outer.finish.valid := Bool(false) // default
|
io.outer.finish.valid := Bool(false) // default
|
||||||
io.outer.finish.bits := pending_finish
|
io.outer.finish.bits := pending_ofin
|
||||||
val pending_finish_on_ognt = io.ognt().makeFinish()
|
val pending_ofin_on_ognt = io.ognt().makeFinish()
|
||||||
|
|
||||||
io.inner.probe.valid := Bool(false)
|
io.inner.probe.valid := Bool(false)
|
||||||
io.inner.probe.bits.header.src := UInt(bankId)
|
io.inner.probe.bits.header.src := UInt(bankId)
|
||||||
@ -1133,8 +1143,8 @@ class L2WritebackUnit(trackerId: Int, bankId: Int) extends L2XactTracker {
|
|||||||
io.outer.grant.ready := Bool(true)
|
io.outer.grant.ready := Bool(true)
|
||||||
when(io.outer.grant.valid) {
|
when(io.outer.grant.valid) {
|
||||||
when(io.ognt().requiresAck()) {
|
when(io.ognt().requiresAck()) {
|
||||||
pending_finish.payload := pending_finish_on_ognt
|
pending_ofin.payload := pending_ofin_on_ognt
|
||||||
pending_finish.header.dst := io.outer.grant.bits.header.src
|
pending_ofin.header.dst := io.outer.grant.bits.header.src
|
||||||
state := s_outer_finish
|
state := s_outer_finish
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
state := s_wb_resp
|
state := s_wb_resp
|
||||||
|
@ -139,12 +139,19 @@ abstract class XactTracker extends CoherenceAgentModule {
|
|||||||
val done = Mux(multi, multi_done, inc)
|
val done = Mux(multi, multi_done, inc)
|
||||||
(cnt, done)
|
(cnt, done)
|
||||||
}
|
}
|
||||||
|
|
||||||
def connectOutgoingDataBeatCounter[T <: HasTileLinkData : ClassTag](
|
def connectOutgoingDataBeatCounter[T <: HasTileLinkData : ClassTag](
|
||||||
in: DecoupledIO[LogicalNetworkIO[T]],
|
in: DecoupledIO[LogicalNetworkIO[T]],
|
||||||
beat: UInt = UInt(0)) = {
|
beat: UInt = UInt(0)) = {
|
||||||
connectDataBeatCounter(in.fire(), in.bits.payload, beat)
|
connectDataBeatCounter(in.fire(), in.bits.payload, beat)
|
||||||
}
|
}
|
||||||
|
|
||||||
def connectIncomingDataBeatCounter[T <: HasTileLinkData : ClassTag](in: DecoupledIO[LogicalNetworkIO[T]]) = {
|
def connectIncomingDataBeatCounter[T <: HasTileLinkData : ClassTag](in: DecoupledIO[LogicalNetworkIO[T]]) = {
|
||||||
connectDataBeatCounter(in.fire(), in.bits.payload, UInt(0))._2
|
connectDataBeatCounter(in.fire(), in.bits.payload, UInt(0))._2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def addPendingBit[T <: HasTileLinkData with HasTileLinkBeatId](in: DecoupledIO[LogicalNetworkIO[T]]) = {
|
||||||
|
(Fill(in.bits.payload.tlDataBeats, in.fire() && in.bits.payload.hasData()) &
|
||||||
|
UIntToOH(in.bits.payload.addr_beat))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user