tilelink2: replace addr_hi with address (#397)
When faced with ambiguous routing of wmask=0, we decided to include all the address bits. Hopefully in most cases the low bits will be optimized away anyway.
This commit is contained in:
parent
9655621aa8
commit
a82cfb8306
@ -36,7 +36,7 @@ class TLROM(val base: BigInt, val size: Int, contentsDelayed: => Seq[Byte], exec
|
||||
in.d.valid := in.a.valid
|
||||
in.a.ready := in.d.ready
|
||||
|
||||
val index = in.a.bits.addr_hi(log2Ceil(size/beatBytes)-1,0)
|
||||
val index = in.a.bits.address(log2Ceil(size)-1,log2Ceil(beatBytes))
|
||||
in.d.bits := edge.AccessAck(in.a.bits, UInt(0), rom(index))
|
||||
|
||||
// Tie off unused channels
|
||||
|
@ -103,7 +103,7 @@ final class TLBundleA(params: TLBundleParameters)
|
||||
val param = UInt(width = 3) // amo_opcode || perms || hint
|
||||
val size = UInt(width = params.sizeBits)
|
||||
val source = UInt(width = params.sourceBits) // from
|
||||
val addr_hi = UInt(width = params.addrHiBits) // to
|
||||
val address = UInt(width = params.addressBits) // to
|
||||
// variable fields during multibeat:
|
||||
val mask = UInt(width = params.dataBits/8)
|
||||
val data = UInt(width = params.dataBits)
|
||||
@ -118,7 +118,7 @@ final class TLBundleB(params: TLBundleParameters)
|
||||
val param = UInt(width = 3)
|
||||
val size = UInt(width = params.sizeBits)
|
||||
val source = UInt(width = params.sourceBits) // to
|
||||
val addr_hi = UInt(width = params.addrHiBits) // from
|
||||
val address = UInt(width = params.addressBits) // from
|
||||
// variable fields during multibeat:
|
||||
val mask = UInt(width = params.dataBits/8)
|
||||
val data = UInt(width = params.dataBits)
|
||||
@ -133,8 +133,7 @@ final class TLBundleC(params: TLBundleParameters)
|
||||
val param = UInt(width = 3)
|
||||
val size = UInt(width = params.sizeBits)
|
||||
val source = UInt(width = params.sourceBits) // from
|
||||
val addr_hi = UInt(width = params.addrHiBits) // to
|
||||
val addr_lo = UInt(width = params.addrLoBits) // instead of mask
|
||||
val address = UInt(width = params.addressBits) // to
|
||||
// variable fields during multibeat:
|
||||
val data = UInt(width = params.dataBits)
|
||||
val error = Bool() // AccessAck[Data]
|
||||
|
@ -11,45 +11,15 @@ class TLEdge(
|
||||
manager: TLManagerPortParameters)
|
||||
extends TLEdgeParameters(client, manager)
|
||||
{
|
||||
def isHiAligned(addr_hi: UInt, lgSize: UInt): Bool = {
|
||||
if (maxLgSize == 0) Bool(true) else {
|
||||
val mask = UIntToOH1(lgSize, maxLgSize) >> log2Ceil(manager.beatBytes)
|
||||
(addr_hi & mask) === UInt(0)
|
||||
}
|
||||
}
|
||||
|
||||
def isLoAligned(addr_lo: UInt, lgSize: UInt): Bool = {
|
||||
def isAligned(address: UInt, lgSize: UInt): Bool = {
|
||||
if (maxLgSize == 0) Bool(true) else {
|
||||
val mask = UIntToOH1(lgSize, maxLgSize)
|
||||
(addr_lo & mask) === UInt(0)
|
||||
(address & mask) === UInt(0)
|
||||
}
|
||||
}
|
||||
|
||||
def mask(addr_lo: UInt, lgSize: UInt): UInt =
|
||||
maskGen(addr_lo, lgSize, manager.beatBytes)
|
||||
|
||||
// !!! make sure to align addr_lo for PutPartials with 0 masks
|
||||
def addr_lo(mask: UInt, lgSize: UInt): UInt = {
|
||||
val sizeOH1 = UIntToOH1(lgSize, log2Up(manager.beatBytes))
|
||||
// Almost OHToUInt, but bits set => bits not set
|
||||
def helper(mask: UInt, width: Int): UInt = {
|
||||
if (width <= 1) {
|
||||
UInt(0)
|
||||
} else if (width == 2) {
|
||||
~mask(0, 0)
|
||||
} else {
|
||||
val mid = 1 << (log2Up(width)-1)
|
||||
val hi = mask(width-1, mid)
|
||||
val lo = mask(mid-1, 0)
|
||||
Cat(!lo.orR, helper(hi | lo, mid))
|
||||
}
|
||||
}
|
||||
helper(mask, bundle.dataBits/8) & ~sizeOH1
|
||||
}
|
||||
|
||||
def full_mask(imask: UInt, lgSize: UInt): UInt = {
|
||||
mask(addr_lo(imask, lgSize), lgSize)
|
||||
}
|
||||
def mask(address: UInt, lgSize: UInt): UInt =
|
||||
maskGen(address, lgSize, manager.beatBytes)
|
||||
|
||||
def staticHasData(bundle: TLChannel): Option[Boolean] = {
|
||||
bundle match {
|
||||
@ -147,49 +117,35 @@ class TLEdge(
|
||||
x match {
|
||||
case a: TLBundleA => a.mask
|
||||
case b: TLBundleB => b.mask
|
||||
case c: TLBundleC => mask(c.addr_lo, c.size)
|
||||
case c: TLBundleC => mask(c.address, c.size)
|
||||
case d: TLBundleD => mask(d.addr_lo, d.size)
|
||||
}
|
||||
}
|
||||
|
||||
def full_mask(x: TLDataChannel): UInt = {
|
||||
x match {
|
||||
case a: TLBundleA => full_mask(a.mask, a.size)
|
||||
case b: TLBundleB => full_mask(b.mask, b.size)
|
||||
case c: TLBundleC => mask(c.addr_lo, c.size)
|
||||
case a: TLBundleA => mask(a.address, a.size)
|
||||
case b: TLBundleB => mask(b.address, b.size)
|
||||
case c: TLBundleC => mask(c.address, c.size)
|
||||
case d: TLBundleD => mask(d.addr_lo, d.size)
|
||||
}
|
||||
}
|
||||
|
||||
def addr_lo(x: TLDataChannel): UInt = {
|
||||
def address(x: TLDataChannel): UInt = {
|
||||
x match {
|
||||
case a: TLBundleA => addr_lo(a.mask, a.size)
|
||||
case b: TLBundleB => addr_lo(b.mask, b.size)
|
||||
case c: TLBundleC => c.addr_lo
|
||||
case a: TLBundleA => a.address
|
||||
case b: TLBundleB => b.address
|
||||
case c: TLBundleC => c.address
|
||||
case d: TLBundleD => d.addr_lo
|
||||
}
|
||||
}
|
||||
|
||||
def addr_hi(x: TLAddrChannel): UInt = {
|
||||
x match {
|
||||
case a: TLBundleA => a.addr_hi
|
||||
case b: TLBundleB => b.addr_hi
|
||||
case c: TLBundleC => c.addr_hi
|
||||
}
|
||||
}
|
||||
|
||||
def address(x: TLAddrChannel): UInt = {
|
||||
val hi = addr_hi(x)
|
||||
if (manager.beatBytes == 1) hi else Cat(hi, addr_lo(x))
|
||||
}
|
||||
|
||||
def addr_lo(x: UInt): UInt = {
|
||||
def addr_hi(x: UInt): UInt = x >> log2Ceil(manager.beatBytes)
|
||||
def addr_lo(x: UInt): UInt =
|
||||
if (manager.beatBytes == 1) UInt(0) else x(log2Ceil(manager.beatBytes)-1, 0)
|
||||
}
|
||||
|
||||
def addr_hi(x: UInt): UInt = {
|
||||
x >> log2Ceil(manager.beatBytes)
|
||||
}
|
||||
def addr_hi(x: TLAddrChannel): UInt = addr_hi(address(x))
|
||||
def addr_lo(x: TLDataChannel): UInt = addr_lo(address(x))
|
||||
|
||||
def numBeats(x: TLChannel): UInt = {
|
||||
x match {
|
||||
@ -228,7 +184,7 @@ class TLEdge(
|
||||
when (fire) {
|
||||
counter := Mux(first, beats1, counter1)
|
||||
}
|
||||
(first, last, beats1 & ~counter1)
|
||||
(first, last, (beats1 & ~counter1) << log2Ceil(manager.beatBytes))
|
||||
}
|
||||
|
||||
def firstlast(x: DecoupledIO[TLChannel]): (Bool, Bool, UInt) = firstlast(x.bits, x.fire())
|
||||
@ -248,7 +204,7 @@ class TLEdgeOut(
|
||||
a.param := growPermissions
|
||||
a.size := lgSize
|
||||
a.source := fromSource
|
||||
a.addr_hi := addr_hi(toAddress)
|
||||
a.address := toAddress
|
||||
a.mask := SInt(-1).asUInt
|
||||
a.data := UInt(0)
|
||||
(legal, a)
|
||||
@ -262,8 +218,7 @@ class TLEdgeOut(
|
||||
c.param := shrinkPermissions
|
||||
c.size := lgSize
|
||||
c.source := fromSource
|
||||
c.addr_hi := addr_hi(toAddress)
|
||||
c.addr_lo := addr_lo(toAddress)
|
||||
c.address := toAddress
|
||||
c.data := UInt(0)
|
||||
c.error := Bool(false)
|
||||
(legal, c)
|
||||
@ -277,8 +232,7 @@ class TLEdgeOut(
|
||||
c.param := shrinkPermissions
|
||||
c.size := lgSize
|
||||
c.source := fromSource
|
||||
c.addr_hi := addr_hi(toAddress)
|
||||
c.addr_lo := addr_lo(toAddress)
|
||||
c.address := toAddress
|
||||
c.data := data
|
||||
c.error := Bool(false)
|
||||
(legal, c)
|
||||
@ -290,8 +244,7 @@ class TLEdgeOut(
|
||||
c.param := reportPermissions
|
||||
c.size := lgSize
|
||||
c.source := fromSource
|
||||
c.addr_hi := addr_hi(toAddress)
|
||||
c.addr_lo := addr_lo(toAddress)
|
||||
c.address := toAddress
|
||||
c.data := UInt(0)
|
||||
c.error := Bool(false)
|
||||
c
|
||||
@ -303,8 +256,7 @@ class TLEdgeOut(
|
||||
c.param := reportPermissions
|
||||
c.size := lgSize
|
||||
c.source := fromSource
|
||||
c.addr_hi := addr_hi(toAddress)
|
||||
c.addr_lo := addr_lo(toAddress)
|
||||
c.address := toAddress
|
||||
c.data := data
|
||||
c.error := Bool(false)
|
||||
c
|
||||
@ -325,7 +277,7 @@ class TLEdgeOut(
|
||||
a.param := UInt(0)
|
||||
a.size := lgSize
|
||||
a.source := fromSource
|
||||
a.addr_hi := addr_hi(toAddress)
|
||||
a.address := toAddress
|
||||
a.mask := mask(toAddress, lgSize)
|
||||
a.data := UInt(0)
|
||||
(legal, a)
|
||||
@ -339,7 +291,7 @@ class TLEdgeOut(
|
||||
a.param := UInt(0)
|
||||
a.size := lgSize
|
||||
a.source := fromSource
|
||||
a.addr_hi := addr_hi(toAddress)
|
||||
a.address := toAddress
|
||||
a.mask := mask(toAddress, lgSize)
|
||||
a.data := data
|
||||
(legal, a)
|
||||
@ -353,7 +305,7 @@ class TLEdgeOut(
|
||||
a.param := UInt(0)
|
||||
a.size := lgSize
|
||||
a.source := fromSource
|
||||
a.addr_hi := addr_hi(toAddress)
|
||||
a.address := toAddress
|
||||
a.mask := mask
|
||||
a.data := data
|
||||
(legal, a)
|
||||
@ -367,7 +319,7 @@ class TLEdgeOut(
|
||||
a.param := atomic
|
||||
a.size := lgSize
|
||||
a.source := fromSource
|
||||
a.addr_hi := addr_hi(toAddress)
|
||||
a.address := toAddress
|
||||
a.mask := mask(toAddress, lgSize)
|
||||
a.data := data
|
||||
(legal, a)
|
||||
@ -381,7 +333,7 @@ class TLEdgeOut(
|
||||
a.param := atomic
|
||||
a.size := lgSize
|
||||
a.source := fromSource
|
||||
a.addr_hi := addr_hi(toAddress)
|
||||
a.address := toAddress
|
||||
a.mask := mask(toAddress, lgSize)
|
||||
a.data := data
|
||||
(legal, a)
|
||||
@ -395,7 +347,7 @@ class TLEdgeOut(
|
||||
a.param := param
|
||||
a.size := lgSize
|
||||
a.source := fromSource
|
||||
a.addr_hi := addr_hi(toAddress)
|
||||
a.address := toAddress
|
||||
a.mask := mask(toAddress, lgSize)
|
||||
a.data := UInt(0)
|
||||
(legal, a)
|
||||
@ -410,8 +362,7 @@ class TLEdgeOut(
|
||||
c.param := UInt(0)
|
||||
c.size := lgSize
|
||||
c.source := fromSource
|
||||
c.addr_hi := addr_hi(toAddress)
|
||||
c.addr_lo := addr_lo(toAddress)
|
||||
c.address := toAddress
|
||||
c.data := UInt(0)
|
||||
c.error := error
|
||||
c
|
||||
@ -426,8 +377,7 @@ class TLEdgeOut(
|
||||
c.param := UInt(0)
|
||||
c.size := lgSize
|
||||
c.source := fromSource
|
||||
c.addr_hi := addr_hi(toAddress)
|
||||
c.addr_lo := addr_lo(toAddress)
|
||||
c.address := toAddress
|
||||
c.data := data
|
||||
c.error := error
|
||||
c
|
||||
@ -440,8 +390,7 @@ class TLEdgeOut(
|
||||
c.param := UInt(0)
|
||||
c.size := lgSize
|
||||
c.source := fromSource
|
||||
c.addr_hi := addr_hi(toAddress)
|
||||
c.addr_lo := addr_lo(toAddress)
|
||||
c.address := toAddress
|
||||
c.data := UInt(0)
|
||||
c.error := Bool(false)
|
||||
c
|
||||
@ -462,7 +411,7 @@ class TLEdgeIn(
|
||||
b.param := capPermissions
|
||||
b.size := lgSize
|
||||
b.source := toSource
|
||||
b.addr_hi := addr_hi(fromAddress)
|
||||
b.address := fromAddress
|
||||
b.mask := SInt(-1).asUInt
|
||||
b.data := UInt(0)
|
||||
(legal, b)
|
||||
@ -518,7 +467,7 @@ class TLEdgeIn(
|
||||
b.param := UInt(0)
|
||||
b.size := lgSize
|
||||
b.source := toSource
|
||||
b.addr_hi := addr_hi(fromAddress)
|
||||
b.address := fromAddress
|
||||
b.mask := mask(fromAddress, lgSize)
|
||||
b.data := UInt(0)
|
||||
(legal, b)
|
||||
@ -532,7 +481,7 @@ class TLEdgeIn(
|
||||
b.param := UInt(0)
|
||||
b.size := lgSize
|
||||
b.source := toSource
|
||||
b.addr_hi := addr_hi(fromAddress)
|
||||
b.address := fromAddress
|
||||
b.mask := mask(fromAddress, lgSize)
|
||||
b.data := data
|
||||
(legal, b)
|
||||
@ -546,7 +495,7 @@ class TLEdgeIn(
|
||||
b.param := UInt(0)
|
||||
b.size := lgSize
|
||||
b.source := toSource
|
||||
b.addr_hi := addr_hi(fromAddress)
|
||||
b.address := fromAddress
|
||||
b.mask := mask
|
||||
b.data := data
|
||||
(legal, b)
|
||||
@ -560,7 +509,7 @@ class TLEdgeIn(
|
||||
b.param := atomic
|
||||
b.size := lgSize
|
||||
b.source := toSource
|
||||
b.addr_hi := addr_hi(fromAddress)
|
||||
b.address := fromAddress
|
||||
b.mask := mask(fromAddress, lgSize)
|
||||
b.data := data
|
||||
(legal, b)
|
||||
@ -574,7 +523,7 @@ class TLEdgeIn(
|
||||
b.param := atomic
|
||||
b.size := lgSize
|
||||
b.source := toSource
|
||||
b.addr_hi := addr_hi(fromAddress)
|
||||
b.address := fromAddress
|
||||
b.mask := mask(fromAddress, lgSize)
|
||||
b.data := data
|
||||
(legal, b)
|
||||
@ -588,7 +537,7 @@ class TLEdgeIn(
|
||||
b.param := param
|
||||
b.size := lgSize
|
||||
b.source := toSource
|
||||
b.addr_hi := addr_hi(fromAddress)
|
||||
b.address := fromAddress
|
||||
b.mask := mask(fromAddress, lgSize)
|
||||
b.data := UInt(0)
|
||||
(legal, b)
|
||||
|
@ -229,7 +229,7 @@ class TLFragmenter(minSize: Int, maxSize: Int, alwaysMin: Boolean = false) exten
|
||||
|
||||
repeater.io.repeat := !aHasData && aFragnum =/= UInt(0)
|
||||
out.a <> in_a
|
||||
out.a.bits.addr_hi := in_a.bits.addr_hi | (~aFragnum << log2Ceil(minSize/beatBytes) & aOrigOH1 >> log2Ceil(beatBytes))
|
||||
out.a.bits.address := in_a.bits.address | (~aFragnum << log2Ceil(minSize) & aOrigOH1)
|
||||
out.a.bits.source := Cat(in_a.bits.source, aFragnum)
|
||||
out.a.bits.size := aFrag
|
||||
|
||||
|
@ -30,12 +30,12 @@ class TLLegacy(implicit val p: Parameters) extends LazyModule with HasTileLinkPa
|
||||
edge.manager.managers.foreach { m =>
|
||||
// If a slave supports read at all, it must support all TL Legacy requires
|
||||
if (m.supportsGet) {
|
||||
require (m.supportsGet.contains(TransferSizes(tlDataBytes)))
|
||||
require (m.supportsGet.contains(TransferSizes(1, tlDataBytes)))
|
||||
require (m.supportsGet.contains(TransferSizes(tlDataBeats * tlDataBytes)))
|
||||
}
|
||||
// Likewise, any put support must mean full put support
|
||||
if (m.supportsPutPartial) {
|
||||
require (m.supportsPutPartial.contains(TransferSizes(tlDataBytes)))
|
||||
require (m.supportsPutPartial.contains(TransferSizes(1, tlDataBytes)))
|
||||
require (m.supportsPutPartial.contains(TransferSizes(tlDataBeats * tlDataBytes)))
|
||||
}
|
||||
// Any atomic support => must support 32-bit up to beat size of all types
|
||||
@ -66,24 +66,26 @@ class TLLegacy(implicit val p: Parameters) extends LazyModule with HasTileLinkPa
|
||||
val block = UInt(log2Ceil(tlDataBytes*tlDataBeats))
|
||||
val size = io.legacy.acquire.bits.op_size()
|
||||
|
||||
// Find the operation size from the wmask
|
||||
// Returns: (any_1, size)
|
||||
def mask_helper(range: UInt): (Bool, UInt) = {
|
||||
// Find the operation size and offset from the wmask
|
||||
// Returns: (any_1, size, offset)
|
||||
def mask_helper(range: UInt): (Bool, UInt, UInt) = {
|
||||
val len = range.getWidth
|
||||
if (len == 1) {
|
||||
(range === UInt(1), UInt(0))
|
||||
(range === UInt(1), UInt(0), UInt(0)) // ugh. offset has one useless bit.
|
||||
} else {
|
||||
val mid = len / 2
|
||||
val lo = range(mid-1, 0)
|
||||
val hi = range(len-1, mid)
|
||||
val (lo_1, lo_s) = mask_helper(lo)
|
||||
val (hi_1, hi_s) = mask_helper(hi)
|
||||
val (lo_1, lo_s, lo_a) = mask_helper(lo)
|
||||
val (hi_1, hi_s, hi_a) = mask_helper(hi)
|
||||
val out_1 = lo_1 || hi_1
|
||||
val out_s = Mux(lo_1, Mux(hi_1, UInt(log2Up(len)), lo_s), hi_s)
|
||||
(out_1, out_s)
|
||||
val out_a = Mux(lo_1, Mux(hi_1, UInt(0), lo_a), Cat(UInt(1), hi_a))
|
||||
(out_1, out_s, out_a)
|
||||
}
|
||||
}
|
||||
val wsize = mask_helper(wmask)._2
|
||||
val (_, wsize, wlow1) = mask_helper(wmask)
|
||||
val wlow = wlow1 >> 1
|
||||
|
||||
// Only create atomic messages if TL2 managers support them
|
||||
val atomics = if (edge.manager.anySupportLogical) {
|
||||
@ -103,30 +105,20 @@ class TLLegacy(implicit val p: Parameters) extends LazyModule with HasTileLinkPa
|
||||
Wire(new TLBundleA(edge.bundle))
|
||||
}
|
||||
|
||||
out.a.bits := MuxLookup(io.legacy.acquire.bits.a_type, Wire(new TLBundleA(edge.bundle)), Array(
|
||||
Acquire.getType -> edge.Get (source, address, size) ._2,
|
||||
Acquire.getBlockType -> edge.Get (source, address, block)._2,
|
||||
Acquire.putType -> edge.Put (source, address, wsize, data, wmask)._2,
|
||||
Acquire.putBlockType -> edge.Put (source, address, block, data, wmask)._2,
|
||||
Acquire.getPrefetchType -> edge.Hint(source, address, block, UInt(0))._2,
|
||||
Acquire.putPrefetchType -> edge.Hint(source, address, block, UInt(1))._2,
|
||||
Acquire.putAtomicType -> atomics))
|
||||
|
||||
val beatMask = UInt(tlDataBytes-1)
|
||||
val blockMask = UInt(tlDataBytes*tlDataBeats-1)
|
||||
val addressMask = MuxLookup(io.legacy.acquire.bits.a_type, beatMask, Array(
|
||||
Acquire.getType -> beatMask,
|
||||
Acquire.getBlockType -> blockMask,
|
||||
Acquire.putType -> beatMask,
|
||||
Acquire.putBlockType -> blockMask,
|
||||
Acquire.getPrefetchType -> blockMask,
|
||||
Acquire.putPrefetchType -> blockMask,
|
||||
Acquire.putAtomicType -> beatMask))
|
||||
out.a.bits := MuxLookup(io.legacy.acquire.bits.a_type, Wire(new TLBundleA(edge.bundle)), Array(
|
||||
Acquire.getType -> edge.Get (source, address, size)._2,
|
||||
Acquire.getBlockType -> edge.Get (source, ~(~address|blockMask), block)._2,
|
||||
Acquire.putType -> edge.Put (source, address|wlow, wsize, data, wmask)._2,
|
||||
Acquire.putBlockType -> edge.Put (source, ~(~address|blockMask), block, data, wmask)._2,
|
||||
Acquire.getPrefetchType -> edge.Hint(source, ~(~address|blockMask), block, UInt(0))._2,
|
||||
Acquire.putPrefetchType -> edge.Hint(source, ~(~address|blockMask), block, UInt(1))._2,
|
||||
Acquire.putAtomicType -> atomics))
|
||||
|
||||
// Get rid of some unneeded muxes
|
||||
out.a.bits.source := source
|
||||
out.a.bits.data := data
|
||||
out.a.bits.addr_hi := ~(~address | addressMask) >> log2Ceil(tlDataBytes)
|
||||
|
||||
// TL legacy does not support bus errors
|
||||
assert (!out.d.valid || !out.d.bits.error)
|
||||
|
@ -20,7 +20,7 @@ class TLMonitor(gen: () => TLBundleSnoop, edge: () => TLEdge, sourceInfo: Source
|
||||
|
||||
// Reuse these subexpressions to save some firrtl lines
|
||||
val source_ok = edge.client.contains(bundle.source)
|
||||
val is_aligned = edge.isHiAligned(bundle.addr_hi, bundle.size)
|
||||
val is_aligned = edge.isAligned(bundle.address, bundle.size)
|
||||
val mask = edge.full_mask(bundle)
|
||||
|
||||
when (bundle.opcode === TLMessages.Acquire) {
|
||||
@ -85,7 +85,7 @@ class TLMonitor(gen: () => TLBundleSnoop, edge: () => TLEdge, sourceInfo: Source
|
||||
|
||||
// Reuse these subexpressions to save some firrtl lines
|
||||
val address_ok = edge.manager.containsSafe(edge.address(bundle))
|
||||
val is_aligned = edge.isHiAligned(bundle.addr_hi, bundle.size)
|
||||
val is_aligned = edge.isAligned(bundle.address, bundle.size)
|
||||
val mask = edge.full_mask(bundle)
|
||||
|
||||
when (bundle.opcode === TLMessages.Probe) {
|
||||
@ -149,7 +149,7 @@ class TLMonitor(gen: () => TLBundleSnoop, edge: () => TLEdge, sourceInfo: Source
|
||||
assert (TLMessages.isC(bundle.opcode), "'C' channel has invalid opcode" + extra)
|
||||
|
||||
val source_ok = edge.client.contains(bundle.source)
|
||||
val is_aligned = edge.isHiAligned(bundle.addr_hi, bundle.size) && edge.isLoAligned(bundle.addr_lo, bundle.size)
|
||||
val is_aligned = edge.isAligned(bundle.address, bundle.size)
|
||||
val address_ok = edge.manager.containsSafe(edge.address(bundle))
|
||||
|
||||
when (bundle.opcode === TLMessages.ProbeAck) {
|
||||
@ -215,7 +215,7 @@ class TLMonitor(gen: () => TLBundleSnoop, edge: () => TLEdge, sourceInfo: Source
|
||||
assert (TLMessages.isD(bundle.opcode), "'D' channel has invalid opcode" + extra)
|
||||
|
||||
val source_ok = edge.client.contains(bundle.source)
|
||||
val is_aligned = edge.isLoAligned(bundle.addr_lo, bundle.size)
|
||||
val is_aligned = edge.isAligned(bundle.addr_lo, bundle.size)
|
||||
val sink_ok = edge.manager.containsById(bundle.sink)
|
||||
|
||||
when (bundle.opcode === TLMessages.ReleaseAck) {
|
||||
@ -287,20 +287,20 @@ class TLMonitor(gen: () => TLBundleSnoop, edge: () => TLEdge, sourceInfo: Source
|
||||
val param = Reg(UInt())
|
||||
val size = Reg(UInt())
|
||||
val source = Reg(UInt())
|
||||
val addr_hi = Reg(UInt())
|
||||
val address = Reg(UInt())
|
||||
when (a.valid && !a_first) {
|
||||
assert (a.bits.opcode === opcode, "'A' channel opcode changed within multibeat operation" + extra)
|
||||
assert (a.bits.param === param, "'A' channel param changed within multibeat operation" + extra)
|
||||
assert (a.bits.size === size, "'A' channel size changed within multibeat operation" + extra)
|
||||
assert (a.bits.source === source, "'A' channel source changed within multibeat operation" + extra)
|
||||
assert (a.bits.addr_hi=== addr_hi,"'A' channel addr_hi changed with multibeat operation" + extra)
|
||||
assert (a.bits.address=== address,"'A' channel address changed with multibeat operation" + extra)
|
||||
}
|
||||
when (a.fire() && a_first) {
|
||||
opcode := a.bits.opcode
|
||||
param := a.bits.param
|
||||
size := a.bits.size
|
||||
source := a.bits.source
|
||||
addr_hi := a.bits.addr_hi
|
||||
address := a.bits.address
|
||||
}
|
||||
}
|
||||
|
||||
@ -310,20 +310,20 @@ class TLMonitor(gen: () => TLBundleSnoop, edge: () => TLEdge, sourceInfo: Source
|
||||
val param = Reg(UInt())
|
||||
val size = Reg(UInt())
|
||||
val source = Reg(UInt())
|
||||
val addr_hi = Reg(UInt())
|
||||
val address = Reg(UInt())
|
||||
when (b.valid && !b_first) {
|
||||
assert (b.bits.opcode === opcode, "'B' channel opcode changed within multibeat operation" + extra)
|
||||
assert (b.bits.param === param, "'B' channel param changed within multibeat operation" + extra)
|
||||
assert (b.bits.size === size, "'B' channel size changed within multibeat operation" + extra)
|
||||
assert (b.bits.source === source, "'B' channel source changed within multibeat operation" + extra)
|
||||
assert (b.bits.addr_hi=== addr_hi,"'B' channel addr_hi changed with multibeat operation" + extra)
|
||||
assert (b.bits.address=== address,"'B' channel addresss changed with multibeat operation" + extra)
|
||||
}
|
||||
when (b.fire() && b_first) {
|
||||
opcode := b.bits.opcode
|
||||
param := b.bits.param
|
||||
size := b.bits.size
|
||||
source := b.bits.source
|
||||
addr_hi := b.bits.addr_hi
|
||||
address := b.bits.address
|
||||
}
|
||||
}
|
||||
|
||||
@ -333,23 +333,20 @@ class TLMonitor(gen: () => TLBundleSnoop, edge: () => TLEdge, sourceInfo: Source
|
||||
val param = Reg(UInt())
|
||||
val size = Reg(UInt())
|
||||
val source = Reg(UInt())
|
||||
val addr_hi = Reg(UInt())
|
||||
val addr_lo = Reg(UInt())
|
||||
val address = Reg(UInt())
|
||||
when (c.valid && !c_first) {
|
||||
assert (c.bits.opcode === opcode, "'C' channel opcode changed within multibeat operation" + extra)
|
||||
assert (c.bits.param === param, "'C' channel param changed within multibeat operation" + extra)
|
||||
assert (c.bits.size === size, "'C' channel size changed within multibeat operation" + extra)
|
||||
assert (c.bits.source === source, "'C' channel source changed within multibeat operation" + extra)
|
||||
assert (c.bits.addr_hi=== addr_hi,"'C' channel addr_hi changed with multibeat operation" + extra)
|
||||
assert (c.bits.addr_lo=== addr_lo,"'C' channel addr_lo changed with multibeat operation" + extra)
|
||||
assert (c.bits.address=== address,"'C' channel address changed with multibeat operation" + extra)
|
||||
}
|
||||
when (c.fire() && c_first) {
|
||||
opcode := c.bits.opcode
|
||||
param := c.bits.param
|
||||
size := c.bits.size
|
||||
source := c.bits.source
|
||||
addr_hi := c.bits.addr_hi
|
||||
addr_lo := c.bits.addr_lo
|
||||
address := c.bits.address
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,14 +243,14 @@ case class TLClientPortParameters(
|
||||
}
|
||||
|
||||
case class TLBundleParameters(
|
||||
addrHiBits: Int,
|
||||
addressBits: Int,
|
||||
dataBits: Int,
|
||||
sourceBits: Int,
|
||||
sinkBits: Int,
|
||||
sizeBits: Int)
|
||||
{
|
||||
// Chisel has issues with 0-width wires
|
||||
require (addrHiBits >= 1)
|
||||
require (addressBits >= 1)
|
||||
require (dataBits >= 8)
|
||||
require (sourceBits >= 1)
|
||||
require (sinkBits >= 1)
|
||||
@ -258,11 +258,10 @@ case class TLBundleParameters(
|
||||
require (isPow2(dataBits))
|
||||
|
||||
val addrLoBits = log2Up(dataBits/8)
|
||||
val addressBits = addrHiBits + log2Ceil(dataBits/8)
|
||||
|
||||
def union(x: TLBundleParameters) =
|
||||
TLBundleParameters(
|
||||
max(addrHiBits, x.addrHiBits),
|
||||
max(addressBits, x.addressBits),
|
||||
max(dataBits, x.dataBits),
|
||||
max(sourceBits, x.sourceBits),
|
||||
max(sinkBits, x.sinkBits),
|
||||
@ -273,7 +272,7 @@ object TLBundleParameters
|
||||
{
|
||||
def apply(client: TLClientPortParameters, manager: TLManagerPortParameters) =
|
||||
new TLBundleParameters(
|
||||
addrHiBits = log2Up(manager.maxAddress + 1) - log2Ceil(manager.beatBytes),
|
||||
addressBits = log2Up(manager.maxAddress + 1),
|
||||
dataBits = manager.beatBytes * 8,
|
||||
sourceBits = log2Up(client.endSourceId),
|
||||
sinkBits = log2Up(manager.endSinkId),
|
||||
|
@ -113,7 +113,8 @@ class TLRAMModel(log: String = "") extends LazyModule
|
||||
val (a_first, a_last, a_address_inc) = edge.firstlast(a, a_fire)
|
||||
val a_size = edge.size(a)
|
||||
val a_sizeOH = UIntToOH(a_size)
|
||||
val a_addr_hi = a.addr_hi | a_address_inc
|
||||
val a_address = a.address | a_address_inc
|
||||
val a_addr_hi = edge.addr_hi(a_address)
|
||||
val a_base = edge.address(a)
|
||||
val a_mask = edge.mask(a_base, a_size)
|
||||
val a_fifo = edge.manager.hasFifoIdFast(a_base)
|
||||
@ -199,7 +200,8 @@ class TLRAMModel(log: String = "") extends LazyModule
|
||||
val d_size = edge.size(d)
|
||||
val d_sizeOH = UIntToOH(d_size)
|
||||
val d_base = d_flight.base
|
||||
val d_addr_hi = d_base >> shift | d_address_inc
|
||||
val d_address = d_base | d_address_inc
|
||||
val d_addr_hi = edge.addr_hi(d_address)
|
||||
val d_mask = edge.mask(d_base, d_size)
|
||||
val d_fifo = edge.manager.hasFifoIdFast(d_flight.base)
|
||||
|
||||
|
@ -36,7 +36,7 @@ class TLRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int =
|
||||
val params = RegMapperParams(log2Up((address.mask+1)/beatBytes), beatBytes, addrLoEnd)
|
||||
val in = Wire(Decoupled(new RegMapperInput(params)))
|
||||
in.bits.read := a.bits.opcode === TLMessages.Get
|
||||
in.bits.index := a.bits.addr_hi
|
||||
in.bits.index := edge.addr_hi(a.bits)
|
||||
in.bits.data := a.bits.data
|
||||
in.bits.mask := a.bits.mask
|
||||
in.bits.extra := Cat(edge.addr_lo(a.bits), a.bits.source, a.bits.size)
|
||||
|
@ -32,7 +32,9 @@ class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)
|
||||
val mask = bigBits(address.mask >> log2Ceil(beatBytes))
|
||||
|
||||
val in = io.in(0)
|
||||
val addrBits = (mask zip in.a.bits.addr_hi.toBools).filter(_._1).map(_._2)
|
||||
val edge = node.edgesIn(0)
|
||||
|
||||
val addrBits = (mask zip edge.addr_hi(in.a.bits).toBools).filter(_._1).map(_._2)
|
||||
val memAddress = Cat(addrBits.reverse)
|
||||
val mem = SeqMem(1 << addrBits.size, Vec(beatBytes, Bits(width = 8)))
|
||||
|
||||
@ -49,7 +51,6 @@ class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4)
|
||||
in.d.valid := d_full
|
||||
in.a.ready := in.d.ready || !d_full
|
||||
|
||||
val edge = node.edgesIn(0)
|
||||
in.d.bits := edge.AccessAck(d_addr, UInt(0), d_source, d_size)
|
||||
// avoid data-bus Mux
|
||||
in.d.bits.data := d_data
|
||||
|
@ -29,14 +29,9 @@ class TLWidthWidget(innerBeatBytes: Int) extends LazyModule
|
||||
val rmask = Reg(UInt(width = (ratio-1)*inBytes))
|
||||
val data = Cat(edgeIn.data(in.bits), rdata)
|
||||
val mask = Cat(edgeIn.mask(in.bits), rmask)
|
||||
val address = edgeIn.address(in.bits)
|
||||
val size = edgeIn.size(in.bits)
|
||||
val hasData = edgeIn.hasData(in.bits)
|
||||
val addr_all = in.bits match {
|
||||
case x: TLAddrChannel => edgeIn.address(x)
|
||||
case _ => UInt(0)
|
||||
}
|
||||
val addr_hi = edgeOut.addr_hi(addr_all)
|
||||
val addr_lo = edgeOut.addr_lo(addr_all)
|
||||
|
||||
val count = RegInit(UInt(0, width = log2Ceil(ratio)))
|
||||
val first = count === UInt(0)
|
||||
@ -64,8 +59,8 @@ class TLWidthWidget(innerBeatBytes: Int) extends LazyModule
|
||||
}
|
||||
|
||||
val dataOut = if (edgeIn.staticHasData(in.bits) == Some(false)) UInt(0) else dataMux(size)
|
||||
val maskFull = edgeOut.mask(addr_lo, size)
|
||||
val maskOut = Mux(hasData, maskMux(size) & maskFull, maskFull)
|
||||
lazy val maskFull = edgeOut.mask(address, size)
|
||||
lazy val maskOut = Mux(hasData, maskMux(size) & maskFull, maskFull)
|
||||
|
||||
in.ready := out.ready || !last
|
||||
out.valid := in.valid && last
|
||||
@ -73,12 +68,12 @@ class TLWidthWidget(innerBeatBytes: Int) extends LazyModule
|
||||
edgeOut.data(out.bits) := dataOut
|
||||
|
||||
out.bits match {
|
||||
case a: TLBundleA => a.addr_hi := addr_hi; a.mask := maskOut
|
||||
case b: TLBundleB => b.addr_hi := addr_hi; b.mask := maskOut
|
||||
case c: TLBundleC => c.addr_hi := addr_hi; c.addr_lo := addr_lo
|
||||
case a: TLBundleA => a.mask := maskOut
|
||||
case b: TLBundleB => b.mask := maskOut
|
||||
case c: TLBundleC => ()
|
||||
case d: TLBundleD => ()
|
||||
// addr_lo gets padded with 0s on D channel, the only lossy transform in this core
|
||||
// this should be safe, because we only care about addr_log on D to determine which
|
||||
// this should be safe, because we only care about addr_lo on D to determine which
|
||||
// piece of data to extract when the D data bus is narrowed. Since we duplicated the
|
||||
// data to all locations, addr_lo still points at a valid copy.
|
||||
}
|
||||
@ -93,10 +88,6 @@ class TLWidthWidget(innerBeatBytes: Int) extends LazyModule
|
||||
val size = edgeIn.size(in.bits)
|
||||
val data = edgeIn.data(in.bits)
|
||||
val mask = edgeIn.mask(in.bits)
|
||||
val addr = in.bits match {
|
||||
case x: TLAddrChannel => edgeIn.address(x) >> log2Ceil(outBytes)
|
||||
case _ => UInt(0)
|
||||
}
|
||||
|
||||
val dataSlices = Vec.tabulate(ratio) { i => data((i+1)*outBytes*8-1, i*outBytes*8) }
|
||||
val maskSlices = Vec.tabulate(ratio) { i => mask((i+1)*outBytes -1, i*outBytes) }
|
||||
@ -123,14 +114,12 @@ class TLWidthWidget(innerBeatBytes: Int) extends LazyModule
|
||||
edgeOut.data(out.bits) := dataOut
|
||||
|
||||
out.bits match {
|
||||
case a: TLBundleA => a.addr_hi := addr; a.mask := maskOut
|
||||
case b: TLBundleB => b.addr_hi := addr; b.mask := maskOut
|
||||
case c: TLBundleC => c.addr_hi := addr
|
||||
case d: TLBundleD => ()
|
||||
case a: TLBundleA => a.mask := maskOut
|
||||
case b: TLBundleB => b.mask := maskOut
|
||||
case c: TLBundleC => ()
|
||||
case d: TLBundleD => () // addr_lo gets truncated automagically
|
||||
}
|
||||
|
||||
// addr_lo gets truncated automagically
|
||||
|
||||
// Repeat the input if we're not last
|
||||
!last
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user