Vec considered harmful; use isOneOf instead (#64)
Vec is heavyweight and really should only be used for I/O and dynamic indexing. A recurring pattern in uncore is Vec(const1, const2, const3) contains x which is nice but has a deleterious effect on simulation copilation and execution time. This patch proposes an alternative: x isOneOf (const1, const2, const3) x isOneOf seqOfThings I think it's also more idiomatic. This is just a prototype; I'm not wed to the name or implementation.
This commit is contained in:
parent
16a6b11081
commit
70b677ecda
11
uncore/src/main/scala/Util.scala
Normal file
11
uncore/src/main/scala/Util.scala
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
package uncore
|
||||||
|
|
||||||
|
import Chisel._
|
||||||
|
|
||||||
|
package object Util {
|
||||||
|
implicit class UIntIsOneOf(val x: UInt) extends AnyVal {
|
||||||
|
def isOneOf(s: Seq[UInt]): Bool = s.map(x === _).reduce(_||_)
|
||||||
|
|
||||||
|
def isOneOf(u1: UInt, u2: UInt*): Bool = isOneOf(u1 +: u2.toSeq)
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ import Chisel._
|
|||||||
import uncore.coherence._
|
import uncore.coherence._
|
||||||
import uncore.tilelink._
|
import uncore.tilelink._
|
||||||
import uncore.constants._
|
import uncore.constants._
|
||||||
|
import uncore.Util._
|
||||||
import cde.Parameters
|
import cde.Parameters
|
||||||
|
|
||||||
class L2BroadcastHub(implicit p: Parameters) extends HierarchicalCoherenceAgent()(p) {
|
class L2BroadcastHub(implicit p: Parameters) extends HierarchicalCoherenceAgent()(p) {
|
||||||
@ -155,7 +156,7 @@ class BufferedBroadcastAcquireTracker(trackerId: Int)(implicit p: Parameters)
|
|||||||
// and/or write back dirty data, and may be unexpected voluntary releases
|
// and/or write back dirty data, and may be unexpected voluntary releases
|
||||||
def irel_can_merge = io.irel().conflicts(xact_addr_block) &&
|
def irel_can_merge = io.irel().conflicts(xact_addr_block) &&
|
||||||
io.irel().isVoluntary() &&
|
io.irel().isVoluntary() &&
|
||||||
!Vec(s_idle, s_meta_write).contains(state) &&
|
!state.isOneOf(s_idle, s_meta_write) &&
|
||||||
!all_pending_done &&
|
!all_pending_done &&
|
||||||
!io.outer.grant.fire() &&
|
!io.outer.grant.fire() &&
|
||||||
!io.inner.grant.fire() &&
|
!io.inner.grant.fire() &&
|
||||||
|
@ -9,6 +9,7 @@ import uncore.util.AMOALU
|
|||||||
import uncore.coherence._
|
import uncore.coherence._
|
||||||
import uncore.tilelink._
|
import uncore.tilelink._
|
||||||
import uncore.constants._
|
import uncore.constants._
|
||||||
|
import uncore.Util._
|
||||||
import cde.{Parameters, Field}
|
import cde.{Parameters, Field}
|
||||||
|
|
||||||
case object CacheName extends Field[String]
|
case object CacheName extends Field[String]
|
||||||
@ -807,7 +808,7 @@ class CacheAcquireTracker(trackerId: Int)(implicit p: Parameters)
|
|||||||
|
|
||||||
|
|
||||||
// Setup IOs used for routing in the parent
|
// Setup IOs used for routing in the parent
|
||||||
val before_wb_alloc = Vec(s_meta_read, s_meta_resp, s_wb_req).contains(state)
|
val before_wb_alloc = state isOneOf (s_meta_read, s_meta_resp, s_wb_req)
|
||||||
|
|
||||||
routeInParent(
|
routeInParent(
|
||||||
iacqMatches = inSameSet(_, xact_addr_block),
|
iacqMatches = inSameSet(_, xact_addr_block),
|
||||||
@ -899,7 +900,7 @@ class CacheAcquireTracker(trackerId: Int)(implicit p: Parameters)
|
|||||||
|
|
||||||
def irel_can_merge = io.irel().conflicts(xact_addr_block) &&
|
def irel_can_merge = io.irel().conflicts(xact_addr_block) &&
|
||||||
io.irel().isVoluntary() &&
|
io.irel().isVoluntary() &&
|
||||||
!Vec(s_idle, s_meta_read, s_meta_resp, s_meta_write).contains(state) &&
|
!state.isOneOf(s_idle, s_meta_read, s_meta_resp, s_meta_write) &&
|
||||||
!all_pending_done &&
|
!all_pending_done &&
|
||||||
!io.outer.grant.fire() &&
|
!io.outer.grant.fire() &&
|
||||||
!io.inner.grant.fire() &&
|
!io.inner.grant.fire() &&
|
||||||
|
@ -6,6 +6,7 @@ import Chisel._
|
|||||||
import uncore.coherence._
|
import uncore.coherence._
|
||||||
import uncore.tilelink._
|
import uncore.tilelink._
|
||||||
import uncore.util._
|
import uncore.util._
|
||||||
|
import uncore.Util._
|
||||||
import cde.{Field, Parameters}
|
import cde.{Field, Parameters}
|
||||||
import scala.math.max
|
import scala.math.max
|
||||||
|
|
||||||
@ -275,7 +276,7 @@ trait AcceptsVoluntaryReleases extends HasVoluntaryReleaseMetadataBuffer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
io.inner.grant.valid := Vec(s_wb_req, s_wb_resp, s_inner_probe, s_busy).contains(state) &&
|
io.inner.grant.valid := state.isOneOf(s_wb_req, s_wb_resp, s_inner_probe, s_busy) &&
|
||||||
vol_ignt_counter.pending &&
|
vol_ignt_counter.pending &&
|
||||||
!(pending_irel_data.orR || block_vol_ignt)
|
!(pending_irel_data.orR || block_vol_ignt)
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ package uncore.coherence
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import uncore.tilelink._
|
import uncore.tilelink._
|
||||||
import uncore.constants._
|
import uncore.constants._
|
||||||
|
import uncore.Util._
|
||||||
|
|
||||||
/** The entire CoherencePolicy API consists of the following three traits:
|
/** The entire CoherencePolicy API consists of the following three traits:
|
||||||
* HasCustomTileLinkMessageTypes, used to define custom messages
|
* HasCustomTileLinkMessageTypes, used to define custom messages
|
||||||
@ -32,8 +33,8 @@ trait HasCustomTileLinkMessageTypes {
|
|||||||
def grantTypeWidth = log2Up(nGrantTypes)
|
def grantTypeWidth = log2Up(nGrantTypes)
|
||||||
|
|
||||||
val acquireTypesWithData = Nil // Only built-in Acquire types have data for now
|
val acquireTypesWithData = Nil // Only built-in Acquire types have data for now
|
||||||
def releaseTypesWithData: Vec[UInt]
|
def releaseTypesWithData: Seq[UInt]
|
||||||
def grantTypesWithData: Vec[UInt]
|
def grantTypesWithData: Seq[UInt]
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This API contains all functions required for client coherence agents.
|
/** This API contains all functions required for client coherence agents.
|
||||||
@ -47,16 +48,16 @@ trait HasClientSideCoherencePolicy {
|
|||||||
// Client coherence states and their permissions
|
// Client coherence states and their permissions
|
||||||
val nClientStates: Int
|
val nClientStates: Int
|
||||||
def clientStateWidth = log2Ceil(nClientStates)
|
def clientStateWidth = log2Ceil(nClientStates)
|
||||||
def clientStatesWithReadPermission: Vec[UInt]
|
def clientStatesWithReadPermission: Seq[UInt]
|
||||||
def clientStatesWithWritePermission: Vec[UInt]
|
def clientStatesWithWritePermission: Seq[UInt]
|
||||||
def clientStatesWithDirtyData: Vec[UInt]
|
def clientStatesWithDirtyData: Seq[UInt]
|
||||||
|
|
||||||
// Transaction initiation logic
|
// Transaction initiation logic
|
||||||
def isValid(meta: ClientMetadata): Bool
|
def isValid(meta: ClientMetadata): Bool
|
||||||
def isHit(cmd: UInt, meta: ClientMetadata): Bool = {
|
def isHit(cmd: UInt, meta: ClientMetadata): Bool = {
|
||||||
Mux(isWriteIntent(cmd),
|
Mux(isWriteIntent(cmd),
|
||||||
clientStatesWithWritePermission.contains(meta.state),
|
meta.state isOneOf clientStatesWithWritePermission,
|
||||||
clientStatesWithReadPermission.contains(meta.state))
|
meta.state isOneOf clientStatesWithReadPermission)
|
||||||
}
|
}
|
||||||
//TODO: Assumes all states with write permissions also have read permissions
|
//TODO: Assumes all states with write permissions also have read permissions
|
||||||
def requiresAcquireOnSecondaryMiss(
|
def requiresAcquireOnSecondaryMiss(
|
||||||
@ -68,7 +69,7 @@ trait HasClientSideCoherencePolicy {
|
|||||||
//TODO: Assumes all cache ctrl ops writeback dirty data, and
|
//TODO: Assumes all cache ctrl ops writeback dirty data, and
|
||||||
// doesn't issue transaction when e.g. downgrading Exclusive to Shared:
|
// doesn't issue transaction when e.g. downgrading Exclusive to Shared:
|
||||||
def requiresReleaseOnCacheControl(cmd: UInt, meta: ClientMetadata): Bool =
|
def requiresReleaseOnCacheControl(cmd: UInt, meta: ClientMetadata): Bool =
|
||||||
clientStatesWithDirtyData.contains(meta.state)
|
meta.state isOneOf clientStatesWithDirtyData
|
||||||
|
|
||||||
// Determine which custom message type to use
|
// Determine which custom message type to use
|
||||||
def getAcquireType(cmd: UInt, meta: ClientMetadata): UInt
|
def getAcquireType(cmd: UInt, meta: ClientMetadata): UInt
|
||||||
@ -131,23 +132,23 @@ class MICoherence(dir: DirectoryRepresentation) extends CoherencePolicy(dir) {
|
|||||||
val releaseInvalidateData :: releaseCopyData :: releaseInvalidateAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes)
|
val releaseInvalidateData :: releaseCopyData :: releaseInvalidateAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes)
|
||||||
val grantExclusive :: Nil = Enum(UInt(), nGrantTypes)
|
val grantExclusive :: Nil = Enum(UInt(), nGrantTypes)
|
||||||
|
|
||||||
def releaseTypesWithData = Vec(releaseInvalidateData, releaseCopyData)
|
def releaseTypesWithData = Seq(releaseInvalidateData, releaseCopyData)
|
||||||
def grantTypesWithData = Vec(grantExclusive)
|
def grantTypesWithData = Seq(grantExclusive)
|
||||||
|
|
||||||
// Client states and functions
|
// Client states and functions
|
||||||
val nClientStates = 2
|
val nClientStates = 2
|
||||||
val clientInvalid :: clientValid :: Nil = Enum(UInt(), nClientStates)
|
val clientInvalid :: clientValid :: Nil = Enum(UInt(), nClientStates)
|
||||||
|
|
||||||
def clientStatesWithReadPermission = Vec(clientValid)
|
def clientStatesWithReadPermission = Seq(clientValid)
|
||||||
def clientStatesWithWritePermission = Vec(clientValid)
|
def clientStatesWithWritePermission = Seq(clientValid)
|
||||||
def clientStatesWithDirtyData = Vec(clientValid)
|
def clientStatesWithDirtyData = Seq(clientValid)
|
||||||
|
|
||||||
def isValid (meta: ClientMetadata): Bool = meta.state =/= clientInvalid
|
def isValid (meta: ClientMetadata): Bool = meta.state =/= clientInvalid
|
||||||
|
|
||||||
def getAcquireType(cmd: UInt, meta: ClientMetadata): UInt = acquireExclusive
|
def getAcquireType(cmd: UInt, meta: ClientMetadata): UInt = acquireExclusive
|
||||||
|
|
||||||
def getReleaseType(cmd: UInt, meta: ClientMetadata): UInt = {
|
def getReleaseType(cmd: UInt, meta: ClientMetadata): UInt = {
|
||||||
val dirty = clientStatesWithDirtyData.contains(meta.state)
|
val dirty = meta.state isOneOf clientStatesWithDirtyData
|
||||||
MuxLookup(cmd, releaseCopyAck, Array(
|
MuxLookup(cmd, releaseCopyAck, Array(
|
||||||
M_FLUSH -> Mux(dirty, releaseInvalidateData, releaseInvalidateAck),
|
M_FLUSH -> Mux(dirty, releaseInvalidateData, releaseInvalidateAck),
|
||||||
M_PRODUCE -> Mux(dirty, releaseCopyData, releaseCopyAck),
|
M_PRODUCE -> Mux(dirty, releaseCopyData, releaseCopyAck),
|
||||||
@ -222,16 +223,16 @@ class MEICoherence(dir: DirectoryRepresentation) extends CoherencePolicy(dir) {
|
|||||||
val releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes)
|
val releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes)
|
||||||
val grantExclusive :: Nil = Enum(UInt(), nGrantTypes)
|
val grantExclusive :: Nil = Enum(UInt(), nGrantTypes)
|
||||||
|
|
||||||
def releaseTypesWithData = Vec(releaseInvalidateData, releaseDowngradeData, releaseCopyData)
|
def releaseTypesWithData = Seq(releaseInvalidateData, releaseDowngradeData, releaseCopyData)
|
||||||
def grantTypesWithData = Vec(grantExclusive)
|
def grantTypesWithData = Seq(grantExclusive)
|
||||||
|
|
||||||
// Client states and functions
|
// Client states and functions
|
||||||
val nClientStates = 3
|
val nClientStates = 3
|
||||||
val clientInvalid :: clientExclusiveClean :: clientExclusiveDirty :: Nil = Enum(UInt(), nClientStates)
|
val clientInvalid :: clientExclusiveClean :: clientExclusiveDirty :: Nil = Enum(UInt(), nClientStates)
|
||||||
|
|
||||||
def clientStatesWithReadPermission = Vec(clientExclusiveClean, clientExclusiveDirty)
|
def clientStatesWithReadPermission = Seq(clientExclusiveClean, clientExclusiveDirty)
|
||||||
def clientStatesWithWritePermission = Vec(clientExclusiveClean, clientExclusiveDirty)
|
def clientStatesWithWritePermission = Seq(clientExclusiveClean, clientExclusiveDirty)
|
||||||
def clientStatesWithDirtyData = Vec(clientExclusiveDirty)
|
def clientStatesWithDirtyData = Seq(clientExclusiveDirty)
|
||||||
|
|
||||||
def isValid (meta: ClientMetadata) = meta.state =/= clientInvalid
|
def isValid (meta: ClientMetadata) = meta.state =/= clientInvalid
|
||||||
|
|
||||||
@ -239,7 +240,7 @@ class MEICoherence(dir: DirectoryRepresentation) extends CoherencePolicy(dir) {
|
|||||||
Mux(isWriteIntent(cmd), acquireExclusiveDirty, acquireExclusiveClean)
|
Mux(isWriteIntent(cmd), acquireExclusiveDirty, acquireExclusiveClean)
|
||||||
|
|
||||||
def getReleaseType(cmd: UInt, meta: ClientMetadata): UInt = {
|
def getReleaseType(cmd: UInt, meta: ClientMetadata): UInt = {
|
||||||
val dirty = clientStatesWithDirtyData.contains(meta.state)
|
val dirty = meta.state isOneOf clientStatesWithDirtyData
|
||||||
MuxLookup(cmd, releaseCopyAck, Array(
|
MuxLookup(cmd, releaseCopyAck, Array(
|
||||||
M_FLUSH -> Mux(dirty, releaseInvalidateData, releaseInvalidateAck),
|
M_FLUSH -> Mux(dirty, releaseInvalidateData, releaseInvalidateAck),
|
||||||
M_PRODUCE -> Mux(dirty, releaseDowngradeData, releaseDowngradeAck),
|
M_PRODUCE -> Mux(dirty, releaseDowngradeData, releaseDowngradeAck),
|
||||||
@ -324,16 +325,16 @@ class MSICoherence(dir: DirectoryRepresentation) extends CoherencePolicy(dir) {
|
|||||||
val releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes)
|
val releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes)
|
||||||
val grantShared :: grantExclusive :: grantExclusiveAck :: Nil = Enum(UInt(), nGrantTypes)
|
val grantShared :: grantExclusive :: grantExclusiveAck :: Nil = Enum(UInt(), nGrantTypes)
|
||||||
|
|
||||||
def releaseTypesWithData = Vec(releaseInvalidateData, releaseDowngradeData, releaseCopyData)
|
def releaseTypesWithData = Seq(releaseInvalidateData, releaseDowngradeData, releaseCopyData)
|
||||||
def grantTypesWithData = Vec(grantShared, grantExclusive)
|
def grantTypesWithData = Seq(grantShared, grantExclusive)
|
||||||
|
|
||||||
// Client states and functions
|
// Client states and functions
|
||||||
val nClientStates = 3
|
val nClientStates = 3
|
||||||
val clientInvalid :: clientShared :: clientExclusiveDirty :: Nil = Enum(UInt(), nClientStates)
|
val clientInvalid :: clientShared :: clientExclusiveDirty :: Nil = Enum(UInt(), nClientStates)
|
||||||
|
|
||||||
def clientStatesWithReadPermission = Vec(clientShared, clientExclusiveDirty)
|
def clientStatesWithReadPermission = Seq(clientShared, clientExclusiveDirty)
|
||||||
def clientStatesWithWritePermission = Vec(clientExclusiveDirty)
|
def clientStatesWithWritePermission = Seq(clientExclusiveDirty)
|
||||||
def clientStatesWithDirtyData = Vec(clientExclusiveDirty)
|
def clientStatesWithDirtyData = Seq(clientExclusiveDirty)
|
||||||
|
|
||||||
def isValid(meta: ClientMetadata): Bool = meta.state =/= clientInvalid
|
def isValid(meta: ClientMetadata): Bool = meta.state =/= clientInvalid
|
||||||
|
|
||||||
@ -341,7 +342,7 @@ class MSICoherence(dir: DirectoryRepresentation) extends CoherencePolicy(dir) {
|
|||||||
Mux(isWriteIntent(cmd), acquireExclusive, acquireShared)
|
Mux(isWriteIntent(cmd), acquireExclusive, acquireShared)
|
||||||
|
|
||||||
def getReleaseType(cmd: UInt, meta: ClientMetadata): UInt = {
|
def getReleaseType(cmd: UInt, meta: ClientMetadata): UInt = {
|
||||||
val dirty = clientStatesWithDirtyData.contains(meta.state)
|
val dirty = meta.state isOneOf clientStatesWithDirtyData
|
||||||
MuxLookup(cmd, releaseCopyAck, Array(
|
MuxLookup(cmd, releaseCopyAck, Array(
|
||||||
M_FLUSH -> Mux(dirty, releaseInvalidateData, releaseInvalidateAck),
|
M_FLUSH -> Mux(dirty, releaseInvalidateData, releaseInvalidateAck),
|
||||||
M_PRODUCE -> Mux(dirty, releaseDowngradeData, releaseDowngradeAck),
|
M_PRODUCE -> Mux(dirty, releaseDowngradeData, releaseDowngradeAck),
|
||||||
@ -361,7 +362,7 @@ class MSICoherence(dir: DirectoryRepresentation) extends CoherencePolicy(dir) {
|
|||||||
ClientMetadata(
|
ClientMetadata(
|
||||||
MuxLookup(cmd, meta.state, Array(
|
MuxLookup(cmd, meta.state, Array(
|
||||||
M_FLUSH -> clientInvalid,
|
M_FLUSH -> clientInvalid,
|
||||||
M_PRODUCE -> Mux(clientStatesWithWritePermission.contains(meta.state),
|
M_PRODUCE -> Mux(meta.state isOneOf clientStatesWithWritePermission,
|
||||||
clientShared, meta.state))))(meta.p)
|
clientShared, meta.state))))(meta.p)
|
||||||
|
|
||||||
def clientMetadataOnGrant(incoming: HasGrantType, cmd: UInt, meta: ClientMetadata) =
|
def clientMetadataOnGrant(incoming: HasGrantType, cmd: UInt, meta: ClientMetadata) =
|
||||||
@ -442,16 +443,16 @@ class MESICoherence(dir: DirectoryRepresentation) extends CoherencePolicy(dir) {
|
|||||||
val releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes)
|
val releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: Nil = Enum(UInt(), nReleaseTypes)
|
||||||
val grantShared :: grantExclusive :: grantExclusiveAck :: Nil = Enum(UInt(), nGrantTypes)
|
val grantShared :: grantExclusive :: grantExclusiveAck :: Nil = Enum(UInt(), nGrantTypes)
|
||||||
|
|
||||||
def releaseTypesWithData = Vec(releaseInvalidateData, releaseDowngradeData, releaseCopyData)
|
def releaseTypesWithData = Seq(releaseInvalidateData, releaseDowngradeData, releaseCopyData)
|
||||||
def grantTypesWithData = Vec(grantShared, grantExclusive)
|
def grantTypesWithData = Seq(grantShared, grantExclusive)
|
||||||
|
|
||||||
// Client states and functions
|
// Client states and functions
|
||||||
val nClientStates = 4
|
val nClientStates = 4
|
||||||
val clientInvalid :: clientShared :: clientExclusiveClean :: clientExclusiveDirty :: Nil = Enum(UInt(), nClientStates)
|
val clientInvalid :: clientShared :: clientExclusiveClean :: clientExclusiveDirty :: Nil = Enum(UInt(), nClientStates)
|
||||||
|
|
||||||
def clientStatesWithReadPermission = Vec(clientShared, clientExclusiveClean, clientExclusiveDirty)
|
def clientStatesWithReadPermission = Seq(clientShared, clientExclusiveClean, clientExclusiveDirty)
|
||||||
def clientStatesWithWritePermission = Vec(clientExclusiveClean, clientExclusiveDirty)
|
def clientStatesWithWritePermission = Seq(clientExclusiveClean, clientExclusiveDirty)
|
||||||
def clientStatesWithDirtyData = Vec(clientExclusiveDirty)
|
def clientStatesWithDirtyData = Seq(clientExclusiveDirty)
|
||||||
|
|
||||||
def isValid(meta: ClientMetadata): Bool = meta.state =/= clientInvalid
|
def isValid(meta: ClientMetadata): Bool = meta.state =/= clientInvalid
|
||||||
|
|
||||||
@ -459,7 +460,7 @@ class MESICoherence(dir: DirectoryRepresentation) extends CoherencePolicy(dir) {
|
|||||||
Mux(isWriteIntent(cmd), acquireExclusive, acquireShared)
|
Mux(isWriteIntent(cmd), acquireExclusive, acquireShared)
|
||||||
|
|
||||||
def getReleaseType(cmd: UInt, meta: ClientMetadata): UInt = {
|
def getReleaseType(cmd: UInt, meta: ClientMetadata): UInt = {
|
||||||
val dirty = clientStatesWithDirtyData.contains(meta.state)
|
val dirty = meta.state isOneOf clientStatesWithDirtyData
|
||||||
MuxLookup(cmd, releaseCopyAck, Array(
|
MuxLookup(cmd, releaseCopyAck, Array(
|
||||||
M_FLUSH -> Mux(dirty, releaseInvalidateData, releaseInvalidateAck),
|
M_FLUSH -> Mux(dirty, releaseInvalidateData, releaseInvalidateAck),
|
||||||
M_PRODUCE -> Mux(dirty, releaseDowngradeData, releaseDowngradeAck),
|
M_PRODUCE -> Mux(dirty, releaseDowngradeData, releaseDowngradeAck),
|
||||||
@ -479,7 +480,7 @@ class MESICoherence(dir: DirectoryRepresentation) extends CoherencePolicy(dir) {
|
|||||||
ClientMetadata(
|
ClientMetadata(
|
||||||
MuxLookup(cmd, meta.state, Array(
|
MuxLookup(cmd, meta.state, Array(
|
||||||
M_FLUSH -> clientInvalid,
|
M_FLUSH -> clientInvalid,
|
||||||
M_PRODUCE -> Mux(clientStatesWithWritePermission.contains(meta.state),
|
M_PRODUCE -> Mux(meta.state isOneOf clientStatesWithWritePermission,
|
||||||
clientShared, meta.state),
|
clientShared, meta.state),
|
||||||
M_CLEAN -> Mux(meta.state === clientExclusiveDirty,
|
M_CLEAN -> Mux(meta.state === clientExclusiveDirty,
|
||||||
clientExclusiveClean, meta.state))))(meta.p)
|
clientExclusiveClean, meta.state))))(meta.p)
|
||||||
@ -558,16 +559,16 @@ class MigratoryCoherence(dir: DirectoryRepresentation) extends CoherencePolicy(d
|
|||||||
val releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: releaseDowngradeDataMigratory :: releaseDowngradeAckHasCopy :: releaseInvalidateDataMigratory :: releaseInvalidateAckMigratory :: Nil = Enum(UInt(), nReleaseTypes)
|
val releaseInvalidateData :: releaseDowngradeData :: releaseCopyData :: releaseInvalidateAck :: releaseDowngradeAck :: releaseCopyAck :: releaseDowngradeDataMigratory :: releaseDowngradeAckHasCopy :: releaseInvalidateDataMigratory :: releaseInvalidateAckMigratory :: Nil = Enum(UInt(), nReleaseTypes)
|
||||||
val grantShared :: grantExclusive :: grantExclusiveAck :: grantReadMigratory :: Nil = Enum(UInt(), nGrantTypes)
|
val grantShared :: grantExclusive :: grantExclusiveAck :: grantReadMigratory :: Nil = Enum(UInt(), nGrantTypes)
|
||||||
|
|
||||||
def releaseTypesWithData = Vec(releaseInvalidateData, releaseDowngradeData, releaseCopyData, releaseInvalidateDataMigratory, releaseDowngradeDataMigratory)
|
def releaseTypesWithData = Seq(releaseInvalidateData, releaseDowngradeData, releaseCopyData, releaseInvalidateDataMigratory, releaseDowngradeDataMigratory)
|
||||||
def grantTypesWithData = Vec(grantShared, grantExclusive, grantReadMigratory)
|
def grantTypesWithData = Seq(grantShared, grantExclusive, grantReadMigratory)
|
||||||
|
|
||||||
// Client states and functions
|
// Client states and functions
|
||||||
val nClientStates = 7
|
val nClientStates = 7
|
||||||
val clientInvalid :: clientShared :: clientExclusiveClean :: clientExclusiveDirty :: clientSharedByTwo :: clientMigratoryClean :: clientMigratoryDirty :: Nil = Enum(UInt(), nClientStates)
|
val clientInvalid :: clientShared :: clientExclusiveClean :: clientExclusiveDirty :: clientSharedByTwo :: clientMigratoryClean :: clientMigratoryDirty :: Nil = Enum(UInt(), nClientStates)
|
||||||
|
|
||||||
def clientStatesWithReadPermission = Vec(clientShared, clientExclusiveClean, clientExclusiveDirty, clientSharedByTwo, clientMigratoryClean, clientMigratoryDirty)
|
def clientStatesWithReadPermission = Seq(clientShared, clientExclusiveClean, clientExclusiveDirty, clientSharedByTwo, clientMigratoryClean, clientMigratoryDirty)
|
||||||
def clientStatesWithWritePermission = Vec(clientExclusiveClean, clientExclusiveDirty, clientMigratoryClean, clientMigratoryDirty)
|
def clientStatesWithWritePermission = Seq(clientExclusiveClean, clientExclusiveDirty, clientMigratoryClean, clientMigratoryDirty)
|
||||||
def clientStatesWithDirtyData = Vec(clientExclusiveDirty, clientMigratoryDirty)
|
def clientStatesWithDirtyData = Seq(clientExclusiveDirty, clientMigratoryDirty)
|
||||||
|
|
||||||
def isValid (meta: ClientMetadata): Bool = meta.state =/= clientInvalid
|
def isValid (meta: ClientMetadata): Bool = meta.state =/= clientInvalid
|
||||||
|
|
||||||
@ -577,7 +578,7 @@ class MigratoryCoherence(dir: DirectoryRepresentation) extends CoherencePolicy(d
|
|||||||
acquireShared)
|
acquireShared)
|
||||||
|
|
||||||
def getReleaseType(cmd: UInt, meta: ClientMetadata): UInt = {
|
def getReleaseType(cmd: UInt, meta: ClientMetadata): UInt = {
|
||||||
val dirty = clientStatesWithDirtyData.contains(meta.state)
|
val dirty = meta.state isOneOf clientStatesWithDirtyData
|
||||||
MuxLookup(cmd, releaseCopyAck, Array(
|
MuxLookup(cmd, releaseCopyAck, Array(
|
||||||
M_FLUSH -> Mux(dirty, releaseInvalidateData, releaseInvalidateAck),
|
M_FLUSH -> Mux(dirty, releaseInvalidateData, releaseInvalidateAck),
|
||||||
M_PRODUCE -> Mux(dirty, releaseDowngradeData, releaseDowngradeAck),
|
M_PRODUCE -> Mux(dirty, releaseDowngradeData, releaseDowngradeAck),
|
||||||
@ -585,9 +586,9 @@ class MigratoryCoherence(dir: DirectoryRepresentation) extends CoherencePolicy(d
|
|||||||
}
|
}
|
||||||
|
|
||||||
def getReleaseType(incoming: HasProbeType, meta: ClientMetadata): UInt = {
|
def getReleaseType(incoming: HasProbeType, meta: ClientMetadata): UInt = {
|
||||||
val dirty = clientStatesWithDirtyData.contains(meta.state)
|
val dirty = meta.state isOneOf clientStatesWithDirtyData
|
||||||
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
|
val with_data = MuxLookup(incoming.p_type, releaseInvalidateData, Array(
|
||||||
probeInvalidate -> Mux(Vec(clientExclusiveDirty, clientMigratoryDirty).contains(meta.state),
|
probeInvalidate -> Mux(meta.state isOneOf (clientExclusiveDirty, clientMigratoryDirty),
|
||||||
releaseInvalidateDataMigratory, releaseInvalidateData),
|
releaseInvalidateDataMigratory, releaseInvalidateData),
|
||||||
probeDowngrade -> Mux(meta.state === clientMigratoryDirty,
|
probeDowngrade -> Mux(meta.state === clientMigratoryDirty,
|
||||||
releaseDowngradeDataMigratory, releaseDowngradeData),
|
releaseDowngradeDataMigratory, releaseDowngradeData),
|
||||||
@ -614,7 +615,7 @@ class MigratoryCoherence(dir: DirectoryRepresentation) extends CoherencePolicy(d
|
|||||||
ClientMetadata(
|
ClientMetadata(
|
||||||
MuxLookup(cmd, meta.state, Array(
|
MuxLookup(cmd, meta.state, Array(
|
||||||
M_FLUSH -> clientInvalid,
|
M_FLUSH -> clientInvalid,
|
||||||
M_PRODUCE -> Mux(clientStatesWithWritePermission.contains(meta.state),
|
M_PRODUCE -> Mux(meta.state isOneOf clientStatesWithWritePermission,
|
||||||
clientShared, meta.state),
|
clientShared, meta.state),
|
||||||
M_CLEAN -> MuxLookup(meta.state, meta.state, Array(
|
M_CLEAN -> MuxLookup(meta.state, meta.state, Array(
|
||||||
clientExclusiveDirty -> clientExclusiveClean,
|
clientExclusiveDirty -> clientExclusiveClean,
|
||||||
|
@ -4,6 +4,7 @@ package uncore.tilelink
|
|||||||
import Chisel._
|
import Chisel._
|
||||||
import junctions._
|
import junctions._
|
||||||
import uncore.coherence.CoherencePolicy
|
import uncore.coherence.CoherencePolicy
|
||||||
|
import uncore.Util._
|
||||||
import scala.math.max
|
import scala.math.max
|
||||||
import uncore.constants._
|
import uncore.constants._
|
||||||
import cde.{Parameters, Field}
|
import cde.{Parameters, Field}
|
||||||
@ -211,7 +212,7 @@ trait HasAcquireType extends HasTileLinkParameters {
|
|||||||
def isBuiltInType(t: UInt): Bool = is_builtin_type && a_type === t
|
def isBuiltInType(t: UInt): Bool = is_builtin_type && a_type === t
|
||||||
|
|
||||||
/** Does this message refer to subblock operands using info in the Acquire.union subbundle */
|
/** Does this message refer to subblock operands using info in the Acquire.union subbundle */
|
||||||
def isSubBlockType(dummy: Int = 0): Bool = isBuiltInType() && Acquire.typesOnSubBlocks.contains(a_type)
|
def isSubBlockType(dummy: Int = 0): Bool = isBuiltInType() && a_type.isOneOf(Acquire.typesOnSubBlocks)
|
||||||
|
|
||||||
/** Is this message a built-in prefetch message */
|
/** Is this message a built-in prefetch message */
|
||||||
def isPrefetch(dummy: Int = 0): Bool = isBuiltInType() &&
|
def isPrefetch(dummy: Int = 0): Bool = isBuiltInType() &&
|
||||||
@ -224,11 +225,11 @@ trait HasAcquireType extends HasTileLinkParameters {
|
|||||||
def isGet(dummy: Int = 0): Bool = isBuiltInType() && (is(Acquire.getType) || is(Acquire.getBlockType))
|
def isGet(dummy: Int = 0): Bool = isBuiltInType() && (is(Acquire.getType) || is(Acquire.getBlockType))
|
||||||
|
|
||||||
/** Does this message contain data? Assumes that no custom message types have data. */
|
/** Does this message contain data? Assumes that no custom message types have data. */
|
||||||
def hasData(dummy: Int = 0): Bool = isBuiltInType() && Acquire.typesWithData.contains(a_type)
|
def hasData(dummy: Int = 0): Bool = isBuiltInType() && a_type.isOneOf(Acquire.typesWithData)
|
||||||
|
|
||||||
/** Does this message contain multiple beats of data? Assumes that no custom message types have data. */
|
/** Does this message contain multiple beats of data? Assumes that no custom message types have data. */
|
||||||
def hasMultibeatData(dummy: Int = 0): Bool = Bool(tlDataBeats > 1) && isBuiltInType() &&
|
def hasMultibeatData(dummy: Int = 0): Bool = Bool(tlDataBeats > 1) && isBuiltInType() &&
|
||||||
Acquire.typesWithMultibeatData.contains(a_type)
|
a_type.isOneOf(Acquire.typesWithMultibeatData)
|
||||||
|
|
||||||
/** Mapping between each built-in Acquire type and a built-in Grant type. */
|
/** Mapping between each built-in Acquire type and a built-in Grant type. */
|
||||||
def getBuiltInGrantType(dummy: Int = 0): UInt = Acquire.getBuiltInGrantType(this.a_type)
|
def getBuiltInGrantType(dummy: Int = 0): UInt = Acquire.getBuiltInGrantType(this.a_type)
|
||||||
@ -251,9 +252,9 @@ trait HasReleaseType extends HasTileLinkParameters with MightBeVoluntary {
|
|||||||
val r_type = UInt(width = tlCoh.releaseTypeWidth)
|
val r_type = UInt(width = tlCoh.releaseTypeWidth)
|
||||||
|
|
||||||
def is(t: UInt) = r_type === t
|
def is(t: UInt) = r_type === t
|
||||||
def hasData(dummy: Int = 0) = tlCoh.releaseTypesWithData.contains(r_type)
|
def hasData(dummy: Int = 0) = r_type.isOneOf(tlCoh.releaseTypesWithData)
|
||||||
def hasMultibeatData(dummy: Int = 0) = Bool(tlDataBeats > 1) &&
|
def hasMultibeatData(dummy: Int = 0) = Bool(tlDataBeats > 1) &&
|
||||||
tlCoh.releaseTypesWithData.contains(r_type)
|
r_type.isOneOf(tlCoh.releaseTypesWithData)
|
||||||
def isVoluntary(dummy: Int = 0) = voluntary
|
def isVoluntary(dummy: Int = 0) = voluntary
|
||||||
def requiresAck(dummy: Int = 0) = !Bool(tlNetworkPreservesPointToPointOrdering)
|
def requiresAck(dummy: Int = 0) = !Bool(tlNetworkPreservesPointToPointOrdering)
|
||||||
}
|
}
|
||||||
@ -267,12 +268,12 @@ trait HasGrantType extends HasTileLinkParameters with MightBeVoluntary {
|
|||||||
def isBuiltInType(t: UInt): Bool = is_builtin_type && g_type === t
|
def isBuiltInType(t: UInt): Bool = is_builtin_type && g_type === t
|
||||||
def is(t: UInt):Bool = g_type === t
|
def is(t: UInt):Bool = g_type === t
|
||||||
def hasData(dummy: Int = 0): Bool = Mux(isBuiltInType(),
|
def hasData(dummy: Int = 0): Bool = Mux(isBuiltInType(),
|
||||||
Grant.typesWithData.contains(g_type),
|
g_type.isOneOf(Grant.typesWithData),
|
||||||
tlCoh.grantTypesWithData.contains(g_type))
|
g_type.isOneOf(tlCoh.grantTypesWithData))
|
||||||
def hasMultibeatData(dummy: Int = 0): Bool =
|
def hasMultibeatData(dummy: Int = 0): Bool =
|
||||||
Bool(tlDataBeats > 1) && Mux(isBuiltInType(),
|
Bool(tlDataBeats > 1) && Mux(isBuiltInType(),
|
||||||
Grant.typesWithMultibeatData.contains(g_type),
|
g_type.isOneOf(Grant.typesWithMultibeatData),
|
||||||
tlCoh.grantTypesWithData.contains(g_type))
|
g_type.isOneOf(tlCoh.grantTypesWithData))
|
||||||
def isVoluntary(dummy: Int = 0): Bool = isBuiltInType() && (g_type === Grant.voluntaryAckType)
|
def isVoluntary(dummy: Int = 0): Bool = isBuiltInType() && (g_type === Grant.voluntaryAckType)
|
||||||
def requiresAck(dummy: Int = 0): Bool = !Bool(tlNetworkPreservesPointToPointOrdering) && !isVoluntary()
|
def requiresAck(dummy: Int = 0): Bool = !Bool(tlNetworkPreservesPointToPointOrdering) && !isVoluntary()
|
||||||
}
|
}
|
||||||
@ -296,7 +297,7 @@ class AcquireMetadata(implicit p: Parameters) extends ClientToManagerChannel
|
|||||||
/** Complete physical address for block, beat or operand */
|
/** Complete physical address for block, beat or operand */
|
||||||
def full_addr(dummy: Int = 0) =
|
def full_addr(dummy: Int = 0) =
|
||||||
Cat(this.addr_block, this.addr_beat,
|
Cat(this.addr_block, this.addr_beat,
|
||||||
Mux(isBuiltInType() && Acquire.typesWithAddrByte.contains(this.a_type),
|
Mux(isBuiltInType() && this.a_type.isOneOf(Acquire.typesWithAddrByte),
|
||||||
this.addr_byte(), UInt(0, tlByteAddrBits)))
|
this.addr_byte(), UInt(0, tlByteAddrBits)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user