1
0

new tshrs, compiles but does not elaborate

This commit is contained in:
Henry Cook 2014-10-07 22:33:10 -07:00
parent 394eb38a96
commit 86bdbd6535
3 changed files with 293 additions and 190 deletions

View File

@ -353,10 +353,14 @@ abstract class L2XactTracker(innerId: String, outerId: String) extends L2HellaCa
val c_ack = io.inner.finish.bits
val m_gnt = io.outer.grant.bits
def mergeData(acq: Acquire, data: UInt): UInt = {
//TODO wite mask
Mux(co.messageHasData(acq), acq.data, data)
}
}
class L2VoluntaryReleaseTracker(trackerId: Int, bankId: Int, innerId: String, outerId: String) extends L2XactTracker(innerId, outerId) {
val s_idle :: s_meta_read :: s_meta_resp :: s_meta_write :: s_data_write :: s_ack :: s_busy :: Nil = Enum(UInt(), 6)
val s_idle :: s_meta_read :: s_meta_resp :: s_meta_write :: s_data_write :: s_grant :: s_busy :: Nil = Enum(UInt(), 6)
val state = Reg(init=s_idle)
val xact = Reg{ new Release }
val xact_internal = Reg{ new L2MetaResp }
@ -412,18 +416,26 @@ class L2VoluntaryReleaseTracker(trackerId: Int, bankId: Int, innerId: String, ou
}
is(s_meta_resp) {
when(io.meta_resp.valid) {
xact_internal := io.meta_resp.bits
state := s_meta_write
xact_internal := co.masterMetadataOnRelease(xact,
io.meta_resp.bits.meta.coh,
init_client_id)
state := Mux(io.meta_resp.bits.tag_match,
Mux(co.messageHasData(xact), s_data_write, s_meta_write),
s_grant)
}
}
is(s_data_write) {
io.data_write.valid := Bool(true)
when(io.data_write.ready) { state := s_meta_write }
}
is(s_meta_write) {
io.meta_write.valid := Bool(true)
when(io.outer.acquire.ready) { state := s_ack }
when(io.meta_write.ready) { state := s_grant }
}
is(s_ack) {
is(s_grant) {
io.inner.grant.valid := Bool(true)
when(io.inner.grant.ready) {
state := Mux(co.requiresAckForGrant(io.inner.grant.bits.payload.g_type),
state := Mux(co.requiresAckForGrant(c_gnt.payload.g_type),
s_busy, s_idle)
}
}
@ -434,61 +446,71 @@ class L2VoluntaryReleaseTracker(trackerId: Int, bankId: Int, innerId: String, ou
}
class L2AcquireTracker(trackerId: Int, bankId: Int, innerId: String, outerId: String) extends L2XactTracker(innerId, outerId) {
val s_idle :: s_probe :: s_mem_read :: s_mem_write :: s_make_grant :: s_busy :: Nil = Enum(UInt(), 6)
val s_idle :: s_meta_read :: s_meta_resp :: s_probe :: s_data_read_wb :: s_data_resp_wb :: s_outer_write_wb :: s_outer_read :: s_outer_resp :: s_data_read_hit :: s_data_resp_hit :: s_data_write :: s_outer_write_acq :: s_meta_write :: s_grant :: s_busy :: Nil = Enum(UInt(), 16)
val state = Reg(init=s_idle)
val xact = Reg{ new Acquire }
val xact_internal = Reg{ new L2MetaResp }
val init_client_id = Reg(init=UInt(0, width = log2Up(nClients)))
//TODO: Will need id reg for merged release xacts
val release_count = if (nClients == 1) UInt(0) else Reg(init=UInt(0, width = log2Up(nClients)))
val probe_flags = Reg(init=Bits(0, width = nClients))
val curr_p_id = PriorityEncoder(probe_flags)
val pending_outer_write = co.messageHasData(xact)
val pending_outer_read = co.requiresOuterRead(xact.a_type)
val release_count = Reg(init = UInt(0, width = log2Up(nClients)))
val pending_probes = Reg(init = co.dir())
val curr_p_id = pending_probes.next()
val is_uncached = co.messageIsUncached(xact)
val tag_match = xact_internal.tag_match
val needs_writeback = co.needsWriteback(xact_internal.meta.coh)
val is_hit = co.isHit(xact, xact_internal.meta.coh)
val needs_probes = co.requiresProbes(xact.a_type, xact_internal.meta.coh)
val c_rel_had_data = Reg{Bool()}
val c_rel_was_voluntary = Reg{Bool()}
val wb_buffer = Reg{xact.data.clone}
io.has_acquire_conflict := co.isCoherenceConflict(xact.addr, c_acq.payload.addr) &&
(state != s_idle) //TODO: Also indexes
io.has_release_conflict := co.isCoherenceConflict(xact.addr, c_rel.payload.addr) &&
(state != s_idle) //TODO: Also indexes?
val outer_write_acq = Bundle(Acquire(co.getUncachedWriteAcquireType,
xact.addr, UInt(trackerId), xact.data),
{ case TLId => outerId })
val outer_write_rel = Bundle(Acquire(co.getUncachedWriteAcquireType,
xact.addr, UInt(trackerId), c_rel.payload.data),
{ case TLId => outerId })
val outer_read = Bundle(Acquire(co.getUncachedReadAcquireType, xact.addr, UInt(trackerId)),
{ case TLId => outerId })
val probe_initial_flags = Bits(width = nClients)
probe_initial_flags := Bits(0)
if (nClients > 1) {
// issue self-probes for uncached read xacts to facilitate I$ coherence
val probe_self = Bool(true) //co.needsSelfProbe(io.inner.acquire.bits.payload)
val myflag = Mux(probe_self, Bits(0), UIntToOH(c_acq.header.src(log2Up(nClients)-1,0)))
probe_initial_flags := ~(io.tile_incoherent | myflag)
}
io.has_acquire_conflict := co.isCoherenceConflict(xact.addr, c_acq.payload.addr) && (state != s_idle)
io.has_release_conflict := co.isCoherenceConflict(xact.addr, c_rel.payload.addr) && (state != s_idle)
xact.addr,
UInt(trackerId),
xact.data), { case TLId => outerId })
val outer_write_wb = Bundle(Acquire(co.getUncachedWriteAcquireType,
Cat(xact_internal.meta.tag,
xact.addr(untagBits-1,blockOffBits)),
UInt(trackerId),
wb_buffer), { case TLId => outerId })
val outer_read = Bundle(Acquire(co.getUncachedReadAcquireType,
xact.addr,
UInt(trackerId)), { case TLId => outerId })
io.outer.acquire.valid := Bool(false)
io.outer.acquire.bits.payload := outer_read //default
io.outer.acquire.bits.header.src := UInt(bankId)
io.outer.acquire.bits.payload := outer_read
io.outer.grant.ready := io.inner.grant.ready
io.outer.grant.ready := Bool(true) //grant.data -> xact.data
val inner_probe_cacq = Probe(co.getProbeType(xact, xact_internal.meta.coh),
xact.addr,
UInt(trackerId))
val inner_probe_wb = Probe(co.getProbeTypeOnVoluntaryWriteback,
xact.addr,
UInt(trackerId))
//TODO inner_probe_mprb
io.inner.probe.valid := Bool(false)
io.inner.probe.bits.header.src := UInt(bankId)
io.inner.probe.bits.header.dst := curr_p_id
io.inner.probe.bits.payload := Probe(co.getProbeType(xact, /*xact_internal.meta), TODO*/
co.masterMetadataOnFlush),
xact.addr,
UInt(trackerId))
io.inner.probe.bits.payload := Mux(needs_writeback,
inner_probe_wb,
inner_probe_cacq)
val grant_type = co.getGrantType(xact, co.masterMetadataOnFlush)// TODO xact_internal.meta)
val grant_type = co.getGrantType(xact, xact_internal.meta.coh)
io.inner.grant.valid := Bool(false)
io.inner.grant.bits.header.src := UInt(bankId)
io.inner.grant.bits.header.dst := init_client_id
io.inner.grant.bits.payload := Grant(grant_type,
xact.client_xact_id,
UInt(trackerId),
m_gnt.payload.data)
xact.data)
io.inner.acquire.ready := Bool(false)
io.inner.release.ready := Bool(false)
@ -511,91 +533,154 @@ class L2AcquireTracker(trackerId: Int, bankId: Int, innerId: String, outerId: St
io.meta_write.bits.id := UInt(trackerId)
io.meta_write.bits.idx := xact.addr(untagBits-1,blockOffBits)
io.meta_write.bits.way_en := xact_internal.way_en
io.meta_write.bits.data := xact_internal.meta
when(io.meta_resp.valid && io.meta_resp.bits.id === UInt(trackerId)) { xact_internal := io.meta_resp.bits }
io.meta_write.bits.data.tag := xact.addr >> UInt(untagBits)
io.meta_write.bits.data.coh := xact_internal.meta.coh
switch (state) {
is(s_idle) {
io.inner.acquire.ready := Bool(true)
val needs_outer_write = co.messageHasData(c_acq.payload)
val needs_outer_read = co.requiresOuterRead(c_acq.payload.a_type)
when( io.inner.acquire.valid ) {
xact := c_acq.payload
init_client_id := c_acq.header.src
probe_flags := probe_initial_flags
if(nClients > 1) {
release_count := PopCount(probe_initial_flags)
state := Mux(probe_initial_flags.orR, s_probe,
Mux(needs_outer_write, s_mem_write,
Mux(needs_outer_read, s_mem_read, s_make_grant)))
} else state := Mux(needs_outer_write, s_mem_write,
Mux(needs_outer_read, s_mem_read, s_make_grant))
state := s_meta_read
}
}
// s_read_meta
// xact_internal := resp
is(s_probe) {
// Generate probes
io.inner.probe.valid := probe_flags.orR
when(io.inner.probe.ready) {
probe_flags := probe_flags & ~(UIntToOH(curr_p_id))
is(s_meta_read) {
io.meta_read.valid := Bool(true)
when(io.meta_read.ready) { state := s_meta_resp }
}
is(s_meta_resp) {
when(io.meta_resp.valid) {
val coh = io.meta_resp.bits.meta.coh
val _tag_match = io.meta_resp.bits.tag_match
val _needs_writeback = co.needsWriteback(coh)
val _is_hit = co.isHit(xact, coh)
val _needs_probes = co.requiresProbes(xact.a_type, coh)
xact_internal := io.meta_resp.bits
when(!_needs_writeback) {
xact_internal.meta.coh := co.masterMetadataOnFlush
}
when(_needs_probes) {
pending_probes := coh.sharers
release_count := coh.sharers.count()
c_rel_had_data := Bool(false)
c_rel_was_voluntary := Bool(false)
}
state := Mux(_tag_match,
Mux(_is_hit,
Mux(_needs_probes, s_probe, s_data_read_hit),
Mux(_needs_probes, s_probe, s_outer_read)),
Mux(_needs_writeback,
Mux(_needs_probes, s_probe, s_data_read_wb),
s_outer_read))
}
}
is(s_probe) {
val skip = io.tile_incoherent(curr_p_id) ||
((curr_p_id === init_client_id) &&
!co.requiresSelfProbe(xact.a_type))
io.inner.probe.valid := !(pending_probes.none() || skip)
when(io.inner.probe.ready || skip) {
pending_probes.pop(curr_p_id)
}
when(skip) { release_count := release_count - UInt(1) }
// Handle releases, which may have data to be written back
// Handle releases, which may have data being written back
io.inner.release.ready := Bool(true)
when(io.inner.release.valid) {
//xact_internal.meta.coh := tl.co.masterMetadataOnRelease(
// io.inner.release.bits.payload,
// xact_internal.meta.coh,
// init_client_id)
xact_internal.meta.coh := co.masterMetadataOnRelease(
c_rel.payload,
xact_internal.meta.coh,
c_rel.header.src)
when(co.messageHasData(c_rel.payload)) {
io.outer.acquire.valid := Bool(true)
io.outer.acquire.bits.payload := outer_write_rel
when(io.outer.acquire.ready) {
io.inner.release.ready := Bool(true)
if(nClients > 1) release_count := release_count - UInt(1)
when(release_count === UInt(1)) {
state := Mux(pending_outer_write, s_mem_write,
Mux(pending_outer_read, s_mem_read, s_make_grant))
}
c_rel_had_data := Bool(true)
when(tag_match) {
xact.data := mergeData(xact, io.inner.release.bits.payload.data)
} .otherwise {
wb_buffer := io.inner.release.bits.payload.data
}
} .otherwise {
io.inner.release.ready := Bool(true)
if(nClients > 1) release_count := release_count - UInt(1)
}
when(co.isVoluntary(c_rel.payload)) {
c_rel_was_voluntary := Bool(true)
}
when(!co.isVoluntary(c_rel.payload)) {
release_count := release_count - Mux(skip, UInt(2), UInt(1))
when(release_count === UInt(1)) {
state := Mux(pending_outer_write, s_mem_write,
Mux(pending_outer_read, s_mem_read, s_make_grant))
state := Mux(tag_match,
Mux(is_hit,
Mux(c_rel_had_data, s_meta_write, s_data_read_hit),
s_outer_read),
Mux(c_rel_had_data, s_outer_write_wb, s_data_read_wb))
}
}
}
}
is(s_mem_read) {
is(s_data_read_wb) {
io.data_read.valid := Bool(true)
when(io.data_read.ready) {
state := s_data_resp_wb
}
}
is(s_data_resp_wb) {
when(io.data_resp.valid) {
wb_buffer := io.data_resp.bits
state := s_outer_write_wb
}
}
is(s_outer_write_wb) {
io.outer.acquire.valid := Bool(true)
io.outer.acquire.bits.payload := outer_write_wb
when(io.outer.acquire.ready) {
state := s_outer_read
}
}
is(s_outer_read) {
io.outer.acquire.valid := Bool(true)
io.outer.acquire.bits.payload := outer_read
when(io.outer.acquire.ready) {
state := Mux(co.requiresAckForGrant(grant_type), s_busy, s_idle)
state := s_outer_resp
}
}
is(s_mem_write) {
io.outer.acquire.valid := Bool(true)
io.outer.acquire.bits.payload := outer_write_acq
when(io.outer.acquire.ready) {
state := Mux(pending_outer_read, s_mem_read, s_make_grant)
is(s_outer_resp) {
io.outer.grant.ready := Bool(true)
when(io.outer.grant.valid) {
xact.data := mergeData(xact, io.outer.grant.bits.payload.data)
//TODO: set pending client state in xact_internal.meta.coh
state := Mux(co.messageHasData(io.outer.grant.bits.payload),
s_data_write, s_data_read_hit)
}
}
is(s_make_grant) {
is(s_data_read_hit) {
io.data_read.valid := Bool(true)
when(io.data_read.ready) {
state := s_data_resp_hit
}
}
is(s_data_resp_hit) {
when(io.data_resp.valid) {
xact.data := mergeData(xact, io.data_resp.bits.data)
state := s_meta_write
}
}
is(s_data_write) {
io.data_write.valid := Bool(true)
when(io.data_write.ready) {
state := s_meta_write
}
}
is(s_meta_write) {
io.meta_write.valid := Bool(true)
when(io.meta_write.ready) { state := s_grant }
}
is(s_grant) {
io.inner.grant.valid := Bool(true)
when(io.inner.grant.ready) {
state := Mux(co.requiresAckForGrant(grant_type), s_busy, s_idle)
state := Mux(co.requiresAckForGrant(c_gnt.payload.g_type),
s_busy, s_idle)
}
}
is(s_busy) { // Nothing left to do but wait for transaction to complete
when(io.outer.grant.valid && m_gnt.payload.client_xact_id === UInt(trackerId)) {
io.inner.grant.valid := Bool(true)
}
when(io.inner.finish.valid && c_ack.payload.master_xact_id === UInt(trackerId)) {
state := s_idle
}
is(s_busy) {
when(io.inner.finish.valid) { state := s_idle }
}
}
}

View File

@ -51,7 +51,6 @@ class MixedMetadata(inner: CoherencePolicy, outer: CoherencePolicy) extends Cohe
*/
abstract class DirectoryRepresentation extends Bundle {
val internal: UInt
def pop(id: UInt): DirectoryRepresentation
def push(id: UInt): DirectoryRepresentation
def flush(dummy: Int = 0): DirectoryRepresentation
@ -106,6 +105,7 @@ abstract class CoherencePolicy(val dir: () => DirectoryRepresentation) {
def needsTransactionOnSecondaryMiss(cmd: UInt, outstanding: Acquire): Bool
def needsTransactionOnCacheControl(cmd: UInt, m: ClientMetadata): Bool
def needsWriteback(m: ClientMetadata): Bool
def needsWriteback(m: MasterMetadata): Bool
def clientMetadataOnHit(cmd: UInt, m: ClientMetadata): ClientMetadata
def clientMetadataOnCacheControl(cmd: UInt): ClientMetadata
@ -114,33 +114,33 @@ abstract class CoherencePolicy(val dir: () => DirectoryRepresentation) {
def clientMetadataOnProbe(incoming: Probe, m: ClientMetadata): ClientMetadata
def masterMetadataOnFlush: MasterMetadata
def masterMetadataOnRelease(incoming: Release, m: MasterMetadata, src: UInt): MasterMetadata
def masterMetadataOnGrant(outgoing: Grant, m: MasterMetadata, dst: UInt): MasterMetadata
def getAcquireTypeOnPrimaryMiss(cmd: UInt, m: ClientMetadata): UInt
def getAcquireTypeOnSecondaryMiss(cmd: UInt, m: ClientMetadata, outstanding: Acquire): UInt
def getProbeType(a: Acquire, m: MasterMetadata): UInt
def getProbeTypeOnVoluntaryWriteback: UInt
def getReleaseTypeOnCacheControl(cmd: UInt): UInt
def getReleaseTypeOnVoluntaryWriteback(): UInt
def getReleaseTypeOnProbe(p: Probe, m: ClientMetadata): UInt
def getGrantType(a: Acquire, m: MasterMetadata): UInt
def getGrantType(r: Release, m: MasterMetadata): UInt
//def getGrantType(a: Acquire) = getGrantType(a, new NullRepresentation) // TODO
//def getGrantType(r: Release) = getGrantType(r, new NullRepresentation)
def messageHasData (rel: SourcedMessage): Bool
def messageUpdatesDataArray (reply: Grant): Bool
def messageIsUncached(acq: Acquire): Bool
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool
def isVoluntary(rel: Release): Bool
def isVoluntary(gnt: Grant): Bool
def requiresOuterRead(a_type: UInt, m: MasterMetadata): Bool
def requiresOuterWrite(a_type: UInt, m: MasterMetadata): Bool
def requiresOuterRead(a_type: UInt): Bool
def requiresOuterWrite(a_type: UInt): Bool
def requiresSelfProbe(a_type: UInt): Bool
def requiresProbes(a_type: UInt, m: MasterMetadata): Bool
def requiresAckForGrant(g_type: UInt): Bool
def requiresAckForRelease(r_type: UInt): Bool
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool
def isCoherenceConflict(addr1: UInt, addr2: UInt): Bool
}
trait UncachedTransactions {
@ -191,6 +191,7 @@ class MICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWit
def needsWriteback (m: ClientMetadata): Bool = {
needsTransactionOnCacheControl(M_INV, m)
}
def needsWriteback(m: MasterMetadata) = isValid(m)
def clientMetadataOnHit(cmd: UInt, m: ClientMetadata) = m
def clientMetadataOnCacheControl(cmd: UInt) = ClientMetadata(
@ -214,16 +215,19 @@ class MICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWit
probeCopy -> m.state
)))(this)
def masterMetadataOnFlush = MasterMetadata(masterInvalid)(this)
def masterMetadataOnRelease(incoming: Release, m: MasterMetadata, src: UInt) = {
val popped = m.sharers.pop(src)
val next = MasterMetadata(Mux(popped.none(), masterInvalid, masterValid), popped)(this)
def is(r: UInt) = incoming.r_type === r
def masterMetadataOnRelease(r: Release, m: MasterMetadata, src: UInt) = {
val next = MasterMetadata(masterValid, m.sharers.pop(src))(this)
MuxBundle(m, Array(
is(releaseVoluntaryInvalidateData) -> next,
is(releaseInvalidateData) -> next,
is(releaseCopyData) -> m,
is(releaseInvalidateAck) -> next,
is(releaseCopyAck) -> m
r.is(releaseVoluntaryInvalidateData) -> next,
r.is(releaseInvalidateData) -> next,
r.is(releaseInvalidateAck) -> next
))
}
def masterMetadataOnGrant(g: Grant, m: MasterMetadata, dst: UInt) = {
val cached = MasterMetadata(masterValid, m.sharers.push(dst))(this)
val uncached = MasterMetadata(masterValid, m.sharers)(this)
MuxBundle(uncached, Array(
g.is(grantReadExclusive) -> cached
))
}
@ -292,6 +296,7 @@ class MICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWit
acquireAtomicUncached -> probeInvalidate
))
}
def getProbeTypeOnVoluntaryWriteback: UInt = probeInvalidate
def requiresOuterRead(a_type: UInt) = {
(a_type != acquireWriteUncached)
@ -299,11 +304,10 @@ class MICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWit
def requiresOuterWrite(a_type: UInt) = {
(a_type === acquireWriteUncached)
}
def requiresOuterRead(a_type: UInt, m: MasterMetadata) = requiresOuterRead(a_type)
def requiresOuterWrite(a_type: UInt, m: MasterMetadata) = requiresOuterWrite(a_type)
def requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck
def requiresAckForRelease(r_type: UInt) = Bool(false)
def requiresSelfProbe(a_type: UInt) = Bool(false)
def requiresSelfProbe(a_type: UInt) = a_type === acquireReadUncached
def requiresProbes(a_type: UInt, m: MasterMetadata) = !m.sharers.none()
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
}
@ -346,6 +350,7 @@ class MEICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWi
def needsWriteback (m: ClientMetadata): Bool = {
needsTransactionOnCacheControl(M_INV, m)
}
def needsWriteback(m: MasterMetadata) = isValid(m)
def clientMetadataOnHit(cmd: UInt, m: ClientMetadata) =
ClientMetadata(Mux(isWrite(cmd), clientExclusiveDirty, m.state))(this)
@ -374,18 +379,20 @@ class MEICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWi
probeCopy -> m.state
)))(this)
def masterMetadataOnFlush = MasterMetadata(masterInvalid)(this)
def masterMetadataOnRelease(incoming: Release, m: MasterMetadata, src: UInt) = {
val popped = m.sharers.pop(src)
val next = MasterMetadata(Mux(popped.none(), masterInvalid, masterValid), popped)(this)
def is(r: UInt) = incoming.r_type === r
def masterMetadataOnRelease(r: Release, m: MasterMetadata, src: UInt) = {
val next = MasterMetadata(masterValid, m.sharers.pop(src))(this)
MuxBundle(m, Array(
is(releaseVoluntaryInvalidateData) -> next,
is(releaseInvalidateData) -> next,
is(releaseDowngradeData) -> m,
is(releaseCopyData) -> m,
is(releaseInvalidateAck) -> next,
is(releaseDowngradeAck) -> m,
is(releaseCopyAck) -> m
r.is(releaseVoluntaryInvalidateData) -> next,
r.is(releaseInvalidateData) -> next,
r.is(releaseInvalidateAck) -> next
))
}
def masterMetadataOnGrant(g: Grant, m: MasterMetadata, dst: UInt) = {
val cached = MasterMetadata(masterValid, m.sharers.push(dst))(this)
val uncached = MasterMetadata(masterValid, m.sharers)(this)
MuxBundle(uncached, Array(
g.is(grantReadExclusive) -> cached,
g.is(grantReadExclusiveAck) -> cached
))
}
@ -462,6 +469,7 @@ class MEICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWi
acquireAtomicUncached -> probeInvalidate
))
}
def getProbeTypeOnVoluntaryWriteback: UInt = probeInvalidate
def requiresOuterRead(a_type: UInt) = {
(a_type != acquireWriteUncached)
@ -469,25 +477,25 @@ class MEICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWi
def requiresOuterWrite(a_type: UInt) = {
(a_type === acquireWriteUncached)
}
def requiresOuterRead(a_type: UInt, m: MasterMetadata) = requiresOuterRead(a_type)
def requiresOuterWrite(a_type: UInt, m: MasterMetadata) = requiresOuterWrite(a_type)
def requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck
def requiresAckForRelease(r_type: UInt) = Bool(false)
def requiresSelfProbe(a_type: UInt) = Bool(false)
def requiresSelfProbe(a_type: UInt) = a_type === acquireReadUncached
def requiresProbes(a_type: UInt, m: MasterMetadata) = !m.sharers.none()
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
}
class MSICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWithUncached(dir) {
def nClientStates = 3
def nMasterStates = 3
def nMasterStates = 2
def nAcquireTypes = 7
def nProbeTypes = 3
def nReleaseTypes = 7
def nGrantTypes = 9
val clientInvalid :: clientShared :: clientExclusiveDirty :: Nil = Enum(UInt(), nClientStates)
val masterInvalid :: masterShared :: masterExclusive :: Nil = Enum(UInt(), nMasterStates)
//val masterInvalid :: masterShared :: masterExclusive :: Nil = Enum(UInt(), nMasterStates)
val masterInvalid :: masterValid :: Nil = Enum(UInt(), nMasterStates)
val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(UInt(), nAcquireTypes)
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(UInt(), nProbeTypes)
@ -522,6 +530,7 @@ class MSICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWi
def needsWriteback (m: ClientMetadata): Bool = {
needsTransactionOnCacheControl(M_INV, m)
}
def needsWriteback(m: MasterMetadata) = isValid(m)
def clientMetadataOnHit(cmd: UInt, m: ClientMetadata) =
ClientMetadata(Mux(isWrite(cmd), clientExclusiveDirty, m.state))(this)
@ -549,20 +558,21 @@ class MSICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWi
probeCopy -> m.state
)))(this)
def masterMetadataOnFlush = MasterMetadata(masterInvalid)(this)
def masterMetadataOnRelease(incoming: Release, m: MasterMetadata, src: UInt) = {
val popped = m.sharers.pop(src)
val next = MasterMetadata(
Mux(popped.none(), masterInvalid,
Mux(popped.one(), masterExclusive, masterShared)), popped)(this)
def is(r: UInt) = incoming.r_type === r
def masterMetadataOnRelease(r: Release, m: MasterMetadata, src: UInt) = {
val next = MasterMetadata(masterValid, m.sharers.pop(src))(this)
MuxBundle(m, Array(
is(releaseVoluntaryInvalidateData) -> next,
is(releaseInvalidateData) -> next,
is(releaseDowngradeData) -> m,
is(releaseCopyData) -> m,
is(releaseInvalidateAck) -> next,
is(releaseDowngradeAck) -> m,
is(releaseCopyAck) -> m
r.is(releaseVoluntaryInvalidateData) -> next,
r.is(releaseInvalidateData) -> next,
r.is(releaseInvalidateAck) -> next
))
}
def masterMetadataOnGrant(g: Grant, m: MasterMetadata, dst: UInt) = {
val cached = MasterMetadata(masterValid, m.sharers.push(dst))(this)
val uncached = MasterMetadata(masterValid, m.sharers)(this)
MuxBundle(uncached, Array(
g.is(grantReadShared) -> cached,
g.is(grantReadExclusive) -> cached,
g.is(grantReadExclusiveAck) -> cached
))
}
@ -612,7 +622,7 @@ class MSICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWi
def getGrantType(a: Acquire, m: MasterMetadata): UInt = {
MuxLookup(a.a_type, grantReadUncached, Array(
acquireReadShared -> Mux(m.sharers.count() > UInt(0), grantReadShared, grantReadExclusive),
acquireReadShared -> Mux(!m.sharers.none(), grantReadShared, grantReadExclusive),
acquireReadExclusive -> grantReadExclusive,
acquireReadUncached -> grantReadUncached,
acquireWriteUncached -> grantWriteUncached,
@ -635,6 +645,7 @@ class MSICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWi
acquireWriteUncached -> probeInvalidate
))
}
def getProbeTypeOnVoluntaryWriteback: UInt = probeInvalidate
def requiresOuterRead(a_type: UInt) = {
(a_type != acquireWriteUncached)
@ -642,25 +653,25 @@ class MSICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWi
def requiresOuterWrite(a_type: UInt) = {
(a_type === acquireWriteUncached)
}
def requiresOuterRead(a_type: UInt, m: MasterMetadata) = requiresOuterRead(a_type)
def requiresOuterWrite(a_type: UInt, m: MasterMetadata) = requiresOuterWrite(a_type)
def requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck
def requiresAckForRelease(r_type: UInt) = Bool(false)
def requiresSelfProbe(a_type: UInt) = Bool(false)
def requiresSelfProbe(a_type: UInt) = a_type === acquireReadUncached
def requiresProbes(a_type: UInt, m: MasterMetadata) = !m.sharers.none()
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
}
class MESICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWithUncached(dir) {
def nClientStates = 4
def nMasterStates = 3
def nMasterStates = 2
def nAcquireTypes = 7
def nProbeTypes = 3
def nReleaseTypes = 7
def nGrantTypes = 9
val clientInvalid :: clientShared :: clientExclusiveClean :: clientExclusiveDirty :: Nil = Enum(UInt(), nClientStates)
val masterInvalid :: masterShared :: masterExclusive :: Nil = Enum(UInt(), nMasterStates)
//val masterInvalid :: masterShared :: masterExclusive :: Nil = Enum(UInt(), nMasterStates)
val masterInvalid :: masterValid :: Nil = Enum(UInt(), nMasterStates)
val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: Nil = Enum(UInt(), nAcquireTypes)
val probeInvalidate :: probeDowngrade :: probeCopy :: Nil = Enum(UInt(), nProbeTypes)
@ -695,6 +706,7 @@ class MESICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyW
def needsWriteback (m: ClientMetadata): Bool = {
needsTransactionOnCacheControl(M_INV, m)
}
def needsWriteback(m: MasterMetadata) = isValid(m)
def clientMetadataOnHit(cmd: UInt, m: ClientMetadata) =
ClientMetadata(Mux(isWrite(cmd), clientExclusiveDirty, m.state))(this)
@ -723,20 +735,21 @@ class MESICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyW
probeCopy -> m.state
)))(this)
def masterMetadataOnFlush = MasterMetadata(masterInvalid)(this)
def masterMetadataOnRelease(incoming: Release, m: MasterMetadata, src: UInt) = {
val popped = m.sharers.pop(src)
val next = MasterMetadata(
Mux(popped.none(), masterInvalid,
Mux(popped.one(), masterExclusive, masterShared)), popped)(this)
def is(r: UInt) = incoming.r_type === r
def masterMetadataOnRelease(r: Release, m: MasterMetadata, src: UInt) = {
val next = MasterMetadata(masterValid, m.sharers.pop(src))(this)
MuxBundle(m, Array(
is(releaseVoluntaryInvalidateData) -> next,
is(releaseInvalidateData) -> next,
is(releaseDowngradeData) -> m,
is(releaseCopyData) -> m,
is(releaseInvalidateAck) -> next,
is(releaseDowngradeAck) -> m,
is(releaseCopyAck) -> m
r.is(releaseVoluntaryInvalidateData) -> next,
r.is(releaseInvalidateData) -> next,
r.is(releaseInvalidateAck) -> next
))
}
def masterMetadataOnGrant(g: Grant, m: MasterMetadata, dst: UInt) = {
val cached = MasterMetadata(masterValid, m.sharers.push(dst))(this)
val uncached = MasterMetadata(masterValid, m.sharers)(this)
MuxBundle(uncached, Array(
g.is(grantReadShared) -> cached,
g.is(grantReadExclusive) -> cached,
g.is(grantReadExclusiveAck) -> cached
))
}
@ -786,7 +799,7 @@ class MESICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyW
def getGrantType(a: Acquire, m: MasterMetadata): UInt = {
MuxLookup(a.a_type, grantReadUncached, Array(
acquireReadShared -> Mux(m.sharers.count() > UInt(0), grantReadShared, grantReadExclusive),
acquireReadShared -> Mux(!m.sharers.none(), grantReadShared, grantReadExclusive),
acquireReadExclusive -> grantReadExclusive,
acquireReadUncached -> grantReadUncached,
acquireWriteUncached -> grantWriteUncached,
@ -813,6 +826,7 @@ class MESICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyW
acquireAtomicUncached -> probeInvalidate
))
}
def getProbeTypeOnVoluntaryWriteback: UInt = probeInvalidate
def requiresOuterRead(a_type: UInt) = {
(a_type != acquireWriteUncached)
@ -820,26 +834,26 @@ class MESICoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyW
def requiresOuterWrite(a_type: UInt) = {
(a_type === acquireWriteUncached)
}
def requiresOuterRead(a_type: UInt, m: MasterMetadata) = requiresOuterRead(a_type)
def requiresOuterWrite(a_type: UInt, m: MasterMetadata) = requiresOuterWrite(a_type)
def requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck
def requiresAckForRelease(r_type: UInt) = Bool(false)
def requiresSelfProbe(a_type: UInt) = Bool(false)
def requiresSelfProbe(a_type: UInt) = a_type === acquireReadUncached
def requiresProbes(a_type: UInt, m: MasterMetadata) = !m.sharers.none()
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
}
class MigratoryCoherence(dir: () => DirectoryRepresentation) extends CoherencePolicyWithUncached(dir) {
def nClientStates = 7
def nMasterStates = 3
def nMasterStates = 2
def nAcquireTypes = 8
def nProbeTypes = 4
def nReleaseTypes = 11
def nGrantTypes = 9
val clientInvalid :: clientShared :: clientExclusiveClean :: clientExclusiveDirty :: clientSharedByTwo :: clientMigratoryClean :: clientMigratoryDirty :: Nil = Enum(UInt(), nClientStates)
val masterInvalid :: masterShared :: masterExclusive :: Nil = Enum(UInt(), nMasterStates)
//val masterInvalid :: masterShared :: masterExclusive :: Nil = Enum(UInt(), nMasterStates)
val masterInvalid :: masterValid :: Nil = Enum(UInt(), nMasterStates)
val acquireReadShared :: acquireReadExclusive :: acquireReadUncached :: acquireWriteUncached :: acquireReadWordUncached :: acquireWriteWordUncached :: acquireAtomicUncached :: acquireInvalidateOthers :: Nil = Enum(UInt(), nAcquireTypes)
val probeInvalidate :: probeDowngrade :: probeCopy :: probeInvalidateOthers :: Nil = Enum(UInt(), nProbeTypes)
@ -873,6 +887,7 @@ class MigratoryCoherence(dir: () => DirectoryRepresentation) extends CoherencePo
def needsWriteback (m: ClientMetadata): Bool = {
needsTransactionOnCacheControl(M_INV, m)
}
def needsWriteback(m: MasterMetadata) = isValid(m)
def clientMetadataOnHit(cmd: UInt, m: ClientMetadata) = ClientMetadata(
Mux(isWrite(cmd), MuxLookup(m.state, clientExclusiveDirty, Array(
@ -914,25 +929,24 @@ class MigratoryCoherence(dir: () => DirectoryRepresentation) extends CoherencePo
clientMigratoryDirty -> clientInvalid))
)))(this)
def masterMetadataOnFlush = MasterMetadata(masterInvalid)(this)
def masterMetadataOnRelease(incoming: Release, m: MasterMetadata, src: UInt) = {
val popped = m.sharers.pop(src)
val next = MasterMetadata(
Mux(popped.none(), masterInvalid,
Mux(popped.one(), masterExclusive, masterShared)),
popped)(this)
def is(r: UInt) = incoming.r_type === r
def masterMetadataOnRelease(r: Release, m: MasterMetadata, src: UInt) = {
val next = MasterMetadata(masterValid, m.sharers.pop(src))(this)
MuxBundle(m, Array(
is(releaseVoluntaryInvalidateData) -> next,
is(releaseInvalidateData) -> next,
is(releaseDowngradeData) -> m,
is(releaseCopyData) -> m,
is(releaseInvalidateAck) -> next,
is(releaseDowngradeAck) -> m,
is(releaseCopyAck) -> m,
is(releaseDowngradeDataMigratory) -> m,
is(releaseDowngradeAckHasCopy) -> m,
is(releaseInvalidateDataMigratory) -> next,
is(releaseInvalidateAckMigratory) -> next
r.is(releaseVoluntaryInvalidateData) -> next,
r.is(releaseInvalidateData) -> next,
r.is(releaseInvalidateAck) -> next,
r.is(releaseInvalidateDataMigratory) -> next,
r.is(releaseInvalidateAckMigratory) -> next
))
}
def masterMetadataOnGrant(g: Grant, m: MasterMetadata, dst: UInt) = {
val cached = MasterMetadata(masterValid, m.sharers.push(dst))(this)
val uncached = MasterMetadata(masterValid, m.sharers)(this)
MuxBundle(uncached, Array(
g.is(grantReadShared) -> cached,
g.is(grantReadExclusive) -> cached,
g.is(grantReadExclusiveAck) -> cached,
g.is(grantReadMigratory) -> cached
))
}
@ -983,7 +997,7 @@ class MigratoryCoherence(dir: () => DirectoryRepresentation) extends CoherencePo
def getGrantType(a: Acquire, m: MasterMetadata): UInt = {
MuxLookup(a.a_type, grantReadUncached, Array(
acquireReadShared -> Mux(m.sharers.count() > UInt(0), grantReadShared, grantReadExclusive), //TODO: what is count? Depend on release.p_type???
acquireReadShared -> Mux(!m.sharers.none(), grantReadShared, grantReadExclusive), //TODO: what is count? Depend on release.p_type???
acquireReadExclusive -> grantReadExclusive,
acquireReadUncached -> grantReadUncached,
acquireWriteUncached -> grantWriteUncached,
@ -1012,6 +1026,7 @@ class MigratoryCoherence(dir: () => DirectoryRepresentation) extends CoherencePo
acquireInvalidateOthers -> probeInvalidateOthers
))
}
def getProbeTypeOnVoluntaryWriteback: UInt = probeInvalidate
def requiresOuterRead(a_type: UInt) = {
(a_type != acquireWriteUncached && a_type != acquireInvalidateOthers)
@ -1019,12 +1034,11 @@ class MigratoryCoherence(dir: () => DirectoryRepresentation) extends CoherencePo
def requiresOuterWrite(a_type: UInt) = {
(a_type === acquireWriteUncached || a_type === acquireWriteWordUncached || a_type === acquireAtomicUncached)
}
def requiresOuterRead(a_type: UInt, m: MasterMetadata) = requiresOuterRead(a_type)
def requiresOuterWrite(a_type: UInt, m: MasterMetadata) = requiresOuterWrite(a_type)
def requiresAckForGrant(g_type: UInt) = g_type != grantVoluntaryAck
def requiresAckForRelease(r_type: UInt) = Bool(false)
def requiresSelfProbe(a_type: UInt) = Bool(false)
def requiresSelfProbe(a_type: UInt) = a_type === acquireReadUncached
def requiresProbes(a_type: UInt, m: MasterMetadata) = !m.sharers.none()
def pendingVoluntaryReleaseIsSufficient(r_type: UInt, p_type: UInt): Bool = (r_type === releaseVoluntaryInvalidateData)
}

View File

@ -77,6 +77,7 @@ class Acquire extends ClientSourcedMessage
val write_mask = Bits(width = params(TLWriteMaskBits))
val subword_addr = Bits(width = params(TLWordAddrBits))
val atomic_opcode = Bits(width = params(TLAtomicOpBits))
def is(t: UInt) = a_type === t
}
object Probe
@ -94,6 +95,7 @@ class Probe extends MasterSourcedMessage
with HasPhysicalAddress
with HasMasterTransactionId {
val p_type = UInt(width = params(TLCoherence).probeTypeWidth)
def is(t: UInt) = p_type === t
}
object Release
@ -127,6 +129,7 @@ class Release extends ClientSourcedMessage
with HasMasterTransactionId
with HasTileLinkData {
val r_type = UInt(width = params(TLCoherence).releaseTypeWidth)
def is(t: UInt) = r_type === t
}
object Grant
@ -151,6 +154,7 @@ class Grant extends MasterSourcedMessage
with HasClientTransactionId
with HasMasterTransactionId {
val g_type = UInt(width = params(TLCoherence).grantTypeWidth)
def is(t: UInt) = g_type === t
}
class Finish extends ClientSourcedMessage with HasMasterTransactionId