WIP uncore and rocket changes compile
This commit is contained in:
@ -43,6 +43,14 @@ object TLMessages
|
||||
def isD(x: UInt) = x <= ReleaseAck
|
||||
}
|
||||
|
||||
/**
|
||||
* The three primary TileLink permissions are:
|
||||
* (T)runk: the agent is (or is on the path to) the global point of serialization.
|
||||
* (B)ranch: the agent
|
||||
* (N)one:
|
||||
* These permissions are permuted by transfer operations in various ways.
|
||||
* Messages for
|
||||
*/
|
||||
object TLPermissions
|
||||
{
|
||||
// Cap types (Grant = new permissions, Probe = permisions <= target)
|
||||
|
@ -238,7 +238,10 @@ class TLEdgeOut(
|
||||
(legal, c)
|
||||
}
|
||||
|
||||
def ProbeAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, reportPermissions: UInt) = {
|
||||
def ProbeAck(b: TLBundleB, reportPermissions: UInt): TLBundleC =
|
||||
ProbeAck(b.source, b.address, b.size, reportPermissions)
|
||||
|
||||
def ProbeAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, reportPermissions: UInt): TLBundleC = {
|
||||
val c = Wire(new TLBundleC(bundle))
|
||||
c.opcode := TLMessages.ProbeAck
|
||||
c.param := reportPermissions
|
||||
@ -250,7 +253,10 @@ class TLEdgeOut(
|
||||
c
|
||||
}
|
||||
|
||||
def ProbeAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, reportPermissions: UInt, data: UInt) = {
|
||||
def ProbeAck(b: TLBundleB, reportPermissions: UInt, data: UInt): TLBundleC =
|
||||
ProbeAck(b.source, b.address, b.size, reportPermissions, data)
|
||||
|
||||
def ProbeAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, reportPermissions: UInt, data: UInt): TLBundleC = {
|
||||
val c = Wire(new TLBundleC(bundle))
|
||||
c.opcode := TLMessages.ProbeAckData
|
||||
c.param := reportPermissions
|
||||
@ -262,7 +268,8 @@ class TLEdgeOut(
|
||||
c
|
||||
}
|
||||
|
||||
def GrantAck(toSink: UInt) = {
|
||||
def GrantAck(d: TLBundleD): TLBundleE = GrantAck(d.sink)
|
||||
def GrantAck(toSink: UInt): TLBundleE = {
|
||||
val e = Wire(new TLBundleE(bundle))
|
||||
e.sink := toSink
|
||||
e
|
||||
|
149
src/main/scala/uncore/tilelink2/Metadata.scala
Normal file
149
src/main/scala/uncore/tilelink2/Metadata.scala
Normal file
@ -0,0 +1,149 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
package uncore.tilelink2
|
||||
|
||||
import Chisel._
|
||||
import chisel3.internal.sourceinfo.SourceInfo
|
||||
import util._
|
||||
import uncore.constants.MemoryOpConstants
|
||||
|
||||
object ClientStates {
|
||||
val width = 2
|
||||
|
||||
val Nothing = UInt(0)
|
||||
val Branch = UInt(1)
|
||||
val Trunk = UInt(2)
|
||||
val Dirty = UInt(3)
|
||||
|
||||
def hasReadPermission(state: UInt): Bool = state > Nothing
|
||||
def hasWritePermission(state: UInt): Bool = state > Branch
|
||||
}
|
||||
|
||||
object MemoryOpCategories extends MemoryOpConstants {
|
||||
val wr = Cat(Bool(true), Bool(true)) // Op actually writes
|
||||
val wi = Cat(Bool(false), Bool(true)) // Future op will write
|
||||
val rd = Cat(Bool(false), Bool(false)) // Op only reads
|
||||
|
||||
def categorize(cmd: UInt): UInt = Cat(isWrite(cmd), isWriteIntent(cmd))
|
||||
}
|
||||
|
||||
/** Stores the client-side coherence information,
|
||||
* such as permissions on the data and whether the data is dirty.
|
||||
* Its API can be used to make TileLink messages in response to
|
||||
* memory operations, cache control oeprations, or Probe messages.
|
||||
*/
|
||||
class ClientMetadata extends Bundle {
|
||||
/** Actual state information stored in this bundle */
|
||||
val state = UInt(width = ClientStates.width)
|
||||
|
||||
/** Metadata equality */
|
||||
def ===(rhs: UInt): Bool = state === rhs
|
||||
def ===(rhs: ClientMetadata): Bool = state === rhs.state
|
||||
def =/=(rhs: ClientMetadata): Bool = !this.===(rhs)
|
||||
|
||||
/** Is the block's data present in this cache */
|
||||
def isValid(dummy: Int = 0): Bool = state > ClientStates.Nothing
|
||||
|
||||
/** Determine whether this cmd misses, and the new state (on hit) or param to be sent (on miss) */
|
||||
private def growStarter(cmd: UInt): (Bool, UInt) = {
|
||||
import MemoryOpCategories._
|
||||
import TLPermissions._
|
||||
import ClientStates._
|
||||
MuxTLookup(Cat(categorize(cmd), state), (Bool(false), UInt(0)), Seq(
|
||||
//(effect, am now) -> (was a hit, next)
|
||||
Cat(rd, Dirty) -> (Bool(true), Dirty),
|
||||
Cat(rd, Trunk) -> (Bool(true), Trunk),
|
||||
Cat(rd, Branch) -> (Bool(true), Branch),
|
||||
Cat(wi, Dirty) -> (Bool(true), Dirty),
|
||||
Cat(wi, Trunk) -> (Bool(true), Trunk),
|
||||
Cat(wr, Dirty) -> (Bool(true), Dirty),
|
||||
Cat(wr, Trunk) -> (Bool(true), Dirty),
|
||||
//(effect, am now) -> (was a miss, param)
|
||||
Cat(rd, Nothing) -> (Bool(false), NtoB),
|
||||
Cat(wi, Branch) -> (Bool(false), BtoT),
|
||||
Cat(wi, Nothing) -> (Bool(false), NtoT),
|
||||
Cat(wr, Branch) -> (Bool(false), BtoT),
|
||||
Cat(wr, Nothing) -> (Bool(false), NtoT)))
|
||||
}
|
||||
|
||||
/** Determine what state to go to after miss based on Grant param */
|
||||
private def growFinisher(cmd: UInt, param: UInt): UInt = {
|
||||
import MemoryOpCategories._
|
||||
import TLPermissions._
|
||||
import ClientStates._
|
||||
MuxLookup(Cat(categorize(cmd), param), UInt(0), Seq(
|
||||
//(effect param) -> (next)
|
||||
Cat(rd, toB) -> Branch,
|
||||
Cat(rd, toT) -> Trunk,
|
||||
Cat(wi, toT) -> Trunk,
|
||||
Cat(wr, toT) -> Dirty))
|
||||
}
|
||||
|
||||
|
||||
/** Does a secondary miss on the block require another Acquire message */
|
||||
def requiresAcquireOnSecondaryMiss(first_cmd: UInt, second_cmd: UInt): Bool = {
|
||||
import MemoryOpCategories._
|
||||
isWriteIntent(second_cmd) && !isWriteIntent(first_cmd)
|
||||
}
|
||||
|
||||
/** Does this cache have permissions on this block sufficient to perform op,
|
||||
* and what to do next (Acquire message param or updated metadata). */
|
||||
def onAccess(cmd: UInt): (Bool, UInt, ClientMetadata) = {
|
||||
val r = growStarter(cmd)
|
||||
(r._1, r._2, ClientMetadata(r._2))
|
||||
}
|
||||
|
||||
/** Metadata change on a returned Grant */
|
||||
def onGrant(cmd: UInt, param: UInt): ClientMetadata = ClientMetadata(growFinisher(cmd, param))
|
||||
|
||||
/** Determine what state to go to based on Probe param */
|
||||
private def shrinkHelper(param: UInt): (Bool, UInt, UInt) = {
|
||||
import ClientStates._
|
||||
import TLPermissions._
|
||||
MuxTLookup(Cat(param, state), (Bool(false), UInt(0), UInt(0)), Seq(
|
||||
//(wanted, am now) -> (dirtyWB resp, next)
|
||||
Cat(toT, Dirty) -> (Bool(true), TtoT, Trunk),
|
||||
Cat(toT, Trunk) -> (Bool(false), TtoT, Trunk),
|
||||
Cat(toT, Branch) -> (Bool(false), BtoB, Branch),
|
||||
Cat(toT, Nothing) -> (Bool(false), NtoN, Nothing),
|
||||
Cat(toB, Dirty) -> (Bool(true), TtoB, Branch),
|
||||
Cat(toB, Trunk) -> (Bool(false), TtoB, Branch), // Policy: Don't notify on clean downgrade
|
||||
Cat(toB, Branch) -> (Bool(false), BtoB, Branch),
|
||||
Cat(toB, Nothing) -> (Bool(false), BtoN, Nothing),
|
||||
Cat(toN, Dirty) -> (Bool(true), TtoN, Nothing),
|
||||
Cat(toN, Trunk) -> (Bool(false), TtoN, Nothing), // Policy: Don't notify on clean downgrade
|
||||
Cat(toN, Branch) -> (Bool(false), BtoN, Nothing), // Policy: Don't notify on clean downgrade
|
||||
Cat(toN, Nothing) -> (Bool(false), NtoN, Nothing)))
|
||||
}
|
||||
|
||||
/** Translate cache control cmds into Probe param */
|
||||
private def cmdToPermCap(cmd: UInt): UInt = {
|
||||
import MemoryOpCategories._
|
||||
import TLPermissions._
|
||||
MuxLookup(cmd, toN, Seq(
|
||||
M_FLUSH -> toN,
|
||||
M_PRODUCE -> toB,
|
||||
M_CLEAN -> toT))
|
||||
}
|
||||
|
||||
def onCacheControl(cmd: UInt): (Bool, UInt, ClientMetadata) = {
|
||||
val r = shrinkHelper(cmdToPermCap(cmd))
|
||||
(r._1, r._2, ClientMetadata(r._3))
|
||||
}
|
||||
|
||||
def onProbe(param: UInt): (Bool, UInt, ClientMetadata) = {
|
||||
val r = shrinkHelper(param)
|
||||
(Bool(true), r._2, ClientMetadata(r._3))
|
||||
}
|
||||
}
|
||||
|
||||
/** Factories for ClientMetadata, including on reset */
|
||||
object ClientMetadata {
|
||||
def apply(perm: UInt) = {
|
||||
val meta = Wire(new ClientMetadata)
|
||||
meta.state := perm
|
||||
meta
|
||||
}
|
||||
def onReset = ClientMetadata(ClientStates.Nothing)
|
||||
def maximum = ClientMetadata(ClientStates.Dirty)
|
||||
}
|
Reference in New Issue
Block a user