1
0
rocket-chip/src/main/scala/tilelink/Bundles.scala
Wesley W. Terpstra 9804bdc34e tilelink: remove obsolete addr_lo signal (#895)
When we first implemented TL, we thought this was helpful, because
it made WidthWidgets stateless in all cases. However, it put too
much burden on all other masters and slaves, none of which benefitted
from this signal. Furthermore, even with addr_lo, WidthWidgets were
information lossy because when they widen, they have no information
about what to fill in the new high bits of addr_lo.
2017-07-26 16:01:21 -07:00

262 lines
8.6 KiB
Scala

// See LICENSE.SiFive for license details.
package freechips.rocketchip.tilelink
import Chisel._
import chisel3.util.{ReadyValidIO}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.util._
abstract class TLBundleBase(params: TLBundleParameters) extends GenericParameterizedBundle(params)
// common combos in lazy policy:
// Put + Acquire
// Release + AccessAck
object TLMessages
{
// A B C D E
def PutFullData = UInt(0) // . . => AccessAck
def PutPartialData = UInt(1) // . . => AccessAck
def ArithmeticData = UInt(2) // . . => AccessAckData
def LogicalData = UInt(3) // . . => AccessAckData
def Get = UInt(4) // . . => AccessAckData
def Hint = UInt(5) // . . => HintAck
def Acquire = UInt(6) // . => Grant[Data]
def Probe = UInt(6) // . => ProbeAck[Data]
def AccessAck = UInt(0) // . .
def AccessAckData = UInt(1) // . .
def HintAck = UInt(2) // . .
def ProbeAck = UInt(4) // .
def ProbeAckData = UInt(5) // .
def Release = UInt(6) // . => ReleaseAck
def ReleaseData = UInt(7) // . => ReleaseAck
def Grant = UInt(4) // . => GrantAck
def GrantData = UInt(5) // . => GrantAck
def ReleaseAck = UInt(6) // .
def GrantAck = UInt(0) // .
def isA(x: UInt) = x <= Acquire
def isB(x: UInt) = x <= Probe
def isC(x: UInt) = x <= ReleaseData
def isD(x: UInt) = x <= ReleaseAck
}
/**
* The three primary TileLink permissions are:
* (T)runk: the agent is (or is on inwards path to) the global point of serialization.
* (B)ranch: the agent is on an outwards path to
* (N)one:
* These permissions are permuted by transfer operations in various ways.
* Operations can cap permissions, request for them to be grown or shrunk,
* or for a report on their current status.
*/
object TLPermissions
{
val aWidth = 2
val bdWidth = 2
val cWidth = 3
// Cap types (Grant = new permissions, Probe = permisions <= target)
def toT = UInt(0, bdWidth)
def toB = UInt(1, bdWidth)
def toN = UInt(2, bdWidth)
def isCap(x: UInt) = x <= toN
// Grow types (Acquire = permissions >= target)
def NtoB = UInt(0, aWidth)
def NtoT = UInt(1, aWidth)
def BtoT = UInt(2, aWidth)
def isGrow(x: UInt) = x <= BtoT
// Shrink types (ProbeAck, Release)
def TtoB = UInt(0, cWidth)
def TtoN = UInt(1, cWidth)
def BtoN = UInt(2, cWidth)
def isShrink(x: UInt) = x <= BtoN
// Report types (ProbeAck)
def TtoT = UInt(3, cWidth)
def BtoB = UInt(4, cWidth)
def NtoN = UInt(5, cWidth)
def isReport(x: UInt) = x <= NtoN
}
object TLAtomics
{
val width = 3
// Arithmetic types
def MIN = UInt(0, width)
def MAX = UInt(1, width)
def MINU = UInt(2, width)
def MAXU = UInt(3, width)
def ADD = UInt(4, width)
def isArithmetic(x: UInt) = x <= ADD
// Logical types
def XOR = UInt(0, width)
def OR = UInt(1, width)
def AND = UInt(2, width)
def SWAP = UInt(3, width)
def isLogical(x: UInt) = x <= SWAP
}
object TLHints
{
val width = 1
def PREFETCH_READ = UInt(0, width)
def PREFETCH_WRITE = UInt(1, width)
}
sealed trait TLChannel extends TLBundleBase {
val channelName: String
}
sealed trait TLDataChannel extends TLChannel
sealed trait TLAddrChannel extends TLDataChannel
final class TLBundleA(params: TLBundleParameters)
extends TLBundleBase(params) with TLAddrChannel
{
val channelName = "'A' channel"
// fixed fields during multibeat:
val opcode = UInt(width = 3)
val param = UInt(width = List(TLAtomics.width, TLPermissions.aWidth, TLHints.width).max) // amo_opcode || grow perms || hint
val size = UInt(width = params.sizeBits)
val source = UInt(width = params.sourceBits) // from
val address = UInt(width = params.addressBits) // to
// variable fields during multibeat:
val mask = UInt(width = params.dataBits/8)
val data = UInt(width = params.dataBits)
}
final class TLBundleB(params: TLBundleParameters)
extends TLBundleBase(params) with TLAddrChannel
{
val channelName = "'B' channel"
// fixed fields during multibeat:
val opcode = UInt(width = 3)
val param = UInt(width = TLPermissions.bdWidth) // cap perms
val size = UInt(width = params.sizeBits)
val source = UInt(width = params.sourceBits) // to
val address = UInt(width = params.addressBits) // from
// variable fields during multibeat:
val mask = UInt(width = params.dataBits/8)
val data = UInt(width = params.dataBits)
}
final class TLBundleC(params: TLBundleParameters)
extends TLBundleBase(params) with TLAddrChannel
{
val channelName = "'C' channel"
// fixed fields during multibeat:
val opcode = UInt(width = 3)
val param = UInt(width = TLPermissions.cWidth) // shrink or report perms
val size = UInt(width = params.sizeBits)
val source = UInt(width = params.sourceBits) // from
val address = UInt(width = params.addressBits) // to
// variable fields during multibeat:
val data = UInt(width = params.dataBits)
val error = Bool() // AccessAck[Data]
}
final class TLBundleD(params: TLBundleParameters)
extends TLBundleBase(params) with TLDataChannel
{
val channelName = "'D' channel"
// fixed fields during multibeat:
val opcode = UInt(width = 3)
val param = UInt(width = TLPermissions.bdWidth) // cap perms
val size = UInt(width = params.sizeBits)
val source = UInt(width = params.sourceBits) // to
val sink = UInt(width = params.sinkBits) // from
// variable fields during multibeat:
val data = UInt(width = params.dataBits)
val error = Bool() // AccessAck[Data], Grant[Data]
}
final class TLBundleE(params: TLBundleParameters)
extends TLBundleBase(params) with TLChannel
{
val channelName = "'E' channel"
val sink = UInt(width = params.sinkBits) // to
}
class TLBundle(params: TLBundleParameters) extends TLBundleBase(params)
{
val a = Decoupled(new TLBundleA(params))
val b = Decoupled(new TLBundleB(params)).flip
val c = Decoupled(new TLBundleC(params))
val d = Decoupled(new TLBundleD(params)).flip
val e = Decoupled(new TLBundleE(params))
}
object TLBundle
{
def apply(params: TLBundleParameters) = new TLBundle(params)
}
final class DecoupledSnoop[+T <: Data](gen: T) extends Bundle
{
val ready = Bool()
val valid = Bool()
val bits = gen.asOutput
def fire(dummy: Int = 0) = ready && valid
override def cloneType: this.type = new DecoupledSnoop(gen).asInstanceOf[this.type]
}
object DecoupledSnoop
{
def apply[T <: Data](source: DecoupledIO[T], sink: DecoupledIO[T]) = {
val out = Wire(new DecoupledSnoop(sink.bits))
out.ready := sink.ready
out.valid := source.valid
out.bits := source.bits
out
}
}
class TLBundleSnoop(params: TLBundleParameters) extends TLBundleBase(params)
{
val a = new DecoupledSnoop(new TLBundleA(params))
val b = new DecoupledSnoop(new TLBundleB(params))
val c = new DecoupledSnoop(new TLBundleC(params))
val d = new DecoupledSnoop(new TLBundleD(params))
val e = new DecoupledSnoop(new TLBundleE(params))
}
object TLBundleSnoop
{
def apply(source: TLBundle, sink: TLBundle) = {
val out = Wire(new TLBundleSnoop(sink.params))
out.a := DecoupledSnoop(source.a, sink.a)
out.b := DecoupledSnoop(sink.b, source.b)
out.c := DecoupledSnoop(source.c, sink.c)
out.d := DecoupledSnoop(sink.d, source.d)
out.e := DecoupledSnoop(source.e, sink.e)
out
}
}
class TLAsyncBundleBase(params: TLAsyncBundleParameters) extends GenericParameterizedBundle(params)
class TLAsyncBundle(params: TLAsyncBundleParameters) extends TLAsyncBundleBase(params)
{
val a = new AsyncBundle(params.depth, new TLBundleA(params.base))
val b = new AsyncBundle(params.depth, new TLBundleB(params.base)).flip
val c = new AsyncBundle(params.depth, new TLBundleC(params.base))
val d = new AsyncBundle(params.depth, new TLBundleD(params.base)).flip
val e = new AsyncBundle(params.depth, new TLBundleE(params.base))
}
class TLRationalBundle(params: TLBundleParameters) extends TLBundleBase(params)
{
val a = RationalIO(new TLBundleA(params))
val b = RationalIO(new TLBundleB(params)).flip
val c = RationalIO(new TLBundleC(params))
val d = RationalIO(new TLBundleD(params)).flip
val e = RationalIO(new TLBundleE(params))
}