1
0

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.
This commit is contained in:
Wesley W. Terpstra 2017-07-26 16:01:21 -07:00 committed by GitHub
parent 3cceb866cf
commit 9804bdc34e
19 changed files with 45 additions and 80 deletions

View File

@ -53,7 +53,6 @@ class TLError(params: ErrorParams, beatBytes: Int = 4)(implicit p: Parameters) e
d.bits.size := a.bits.size
d.bits.source := a.bits.source
d.bits.sink := UInt(0)
d.bits.addr_lo := a.bits.address
d.bits.data := UInt(0)
d.bits.error := a.bits.opcode =/= Hint // Hints may not error

View File

@ -42,7 +42,7 @@ class TLROM(val base: BigInt, val size: Int, contentsDelayed: => Seq[Byte], exec
val index = in.a.bits.address(log2Ceil(wrapSize)-1,log2Ceil(beatBytes))
val high = if (wrapSize == size) UInt(0) else in.a.bits.address(log2Ceil(size)-1, log2Ceil(wrapSize))
in.d.bits := edge.AccessAck(in.a.bits, UInt(0), Mux(high.orR, UInt(0), rom(index)))
in.d.bits := edge.AccessAck(in.a.bits, Mux(high.orR, UInt(0), rom(index)))
// Tie off unused channels
in.b.valid := Bool(false)

View File

@ -52,7 +52,7 @@ class TLTestRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int
val legal = address.contains(in.a.bits.address)
val wdata = Vec.tabulate(beatBytes) { i => in.a.bits.data(8*(i+1)-1, 8*i) }
in.d.bits := edge.AccessAck(in.a.bits, UInt(0), !legal)
in.d.bits := edge.AccessAck(in.a.bits, !legal)
in.d.bits.data := Cat(mem(memAddress).reverse)
in.d.bits.opcode := Mux(hasData, TLMessages.AccessAck, TLMessages.AccessAckData)
when (in.a.fire() && hasData && legal) { mem.write(memAddress, wdata, in.a.bits.mask.toBools) }

View File

@ -36,7 +36,7 @@ class TLZero(address: AddressSet, resources: Seq[Resource], executable: Boolean
a.ready := in.d.ready
in.d.valid := a.valid
in.d.bits := edge.AccessAck(a.bits, UInt(0))
in.d.bits := edge.AccessAck(a.bits)
in.d.bits.opcode := Mux(hasData, TLMessages.AccessAck, TLMessages.AccessAckData)
// Tie off unused channels

View File

@ -285,8 +285,8 @@ class ICacheModule(outer: ICache) extends LazyModuleImp(outer)
tl.d.valid := respValid
tl.d.bits := Mux(edge_in.get.hasData(s1_a),
edge_in.get.AccessAck(s1_a, UInt(0)),
edge_in.get.AccessAck(s1_a, UInt(0), UInt(0)))
edge_in.get.AccessAck(s1_a),
edge_in.get.AccessAck(s1_a, UInt(0)))
tl.d.bits.data := s1s3_slaveData
// Tie off unused channels

View File

@ -85,8 +85,8 @@ class ScratchpadSlavePort(address: AddressSet)(implicit p: Parameters) extends L
tl_in.d.valid := io.dmem.resp.valid || state === s_grant
tl_in.d.bits := Mux(acq.opcode.isOneOf(TLMessages.PutFullData, TLMessages.PutPartialData),
edge.AccessAck(acq, UInt(0)),
edge.AccessAck(acq, UInt(0), UInt(0)))
edge.AccessAck(acq),
edge.AccessAck(acq, UInt(0)))
tl_in.d.bits.data := Mux(io.dmem.resp.valid, io.dmem.resp.bits.data_raw, acq.data)
// Tie off unused channels

View File

@ -133,7 +133,7 @@ class TLBroadcast(lineBytes: Int, numTrackers: Int = 4, bufferless: Boolean = fa
in.c.ready := c_probeack || Mux(c_release, releaseack.ready, putfull.ready)
releaseack.valid := in.c.valid && c_release
releaseack.bits := edgeIn.ReleaseAck(in.c.bits.address, UInt(0), in.c.bits.source, in.c.bits.size)
releaseack.bits := edgeIn.ReleaseAck(in.c.bits)
val put_what = Mux(c_releasedata, TRANSFORM_B, DROP)
val put_who = Mux(c_releasedata, in.c.bits.source, c_trackerSrc)

View File

@ -171,7 +171,6 @@ final class TLBundleD(params: TLBundleParameters)
val size = UInt(width = params.sizeBits)
val source = UInt(width = params.sourceBits) // to
val sink = UInt(width = params.sinkBits) // from
val addr_lo = UInt(width = params.addrLoBits) // instead of mask
// variable fields during multibeat:
val data = UInt(width = params.dataBits)
val error = Bool() // AccessAck[Data], Grant[Data]

View File

@ -79,7 +79,6 @@ class TLCacheCork(unsafe: Boolean = false)(implicit p: Parameters) extends LazyM
c_d.bits.size := in.c.bits.size
c_d.bits.source := in.c.bits.source
c_d.bits.sink := UInt(0)
c_d.bits.addr_lo := in.c.bits.address
c_d.bits.data := UInt(0)
c_d.bits.error := Bool(false)

View File

@ -61,7 +61,6 @@ class TLDelayer(q: Double)(implicit p: Parameters) extends LazyModule
dnoise.size := LFSRNoiseMaker(dnoise.params.sizeBits)
dnoise.source := LFSRNoiseMaker(dnoise.params.sourceBits)
dnoise.sink := LFSRNoiseMaker(dnoise.params.sinkBits)
dnoise.addr_lo := LFSRNoiseMaker(dnoise.params.addrLoBits)
dnoise.data := LFSRNoiseMaker(dnoise.params.dataBits)
dnoise.error := LFSRNoiseMaker(1)(0)

View File

@ -144,30 +144,27 @@ class TLEdge(
}
}
def mask(x: TLDataChannel): UInt = {
def mask(x: TLAddrChannel): UInt = {
x match {
case a: TLBundleA => a.mask
case b: TLBundleB => b.mask
case c: TLBundleC => mask(c.address, c.size)
case d: TLBundleD => mask(d.addr_lo, d.size)
}
}
def full_mask(x: TLDataChannel): UInt = {
def full_mask(x: TLAddrChannel): UInt = {
x match {
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 address(x: TLDataChannel): UInt = {
def address(x: TLAddrChannel): UInt = {
x match {
case a: TLBundleA => a.address
case b: TLBundleB => b.address
case c: TLBundleC => c.address
case d: TLBundleD => d.addr_lo
}
}
@ -185,7 +182,7 @@ class TLEdge(
if (manager.beatBytes == 1) UInt(0) else x(log2Ceil(manager.beatBytes)-1, 0)
def addr_hi(x: TLAddrChannel): UInt = addr_hi(address(x))
def addr_lo(x: TLDataChannel): UInt = addr_lo(address(x))
def addr_lo(x: TLAddrChannel): UInt = addr_lo(address(x))
def numBeats(x: TLChannel): UInt = {
x match {
@ -497,42 +494,40 @@ class TLEdgeIn(
(legal, b)
}
def Grant(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt): TLBundleD = Grant(fromAddress, fromSink, toSource, lgSize, capPermissions, Bool(false))
def Grant(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt, error: Bool) = {
def Grant(fromSink: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt): TLBundleD = Grant(fromSink, toSource, lgSize, capPermissions, Bool(false))
def Grant(fromSink: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt, error: Bool) = {
val d = Wire(new TLBundleD(bundle))
d.opcode := TLMessages.Grant
d.param := capPermissions
d.size := lgSize
d.source := toSource
d.sink := fromSink
d.addr_lo := addr_lo(fromAddress)
d.data := UInt(0)
d.error := error
d
}
def Grant(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt, data: UInt): TLBundleD = Grant(fromAddress, fromSink, toSource, lgSize, capPermissions, data, Bool(false))
def Grant(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt, data: UInt, error: Bool) = {
def Grant(fromSink: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt, data: UInt): TLBundleD = Grant(fromSink, toSource, lgSize, capPermissions, data, Bool(false))
def Grant(fromSink: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt, data: UInt, error: Bool) = {
val d = Wire(new TLBundleD(bundle))
d.opcode := TLMessages.GrantData
d.param := capPermissions
d.size := lgSize
d.source := toSource
d.sink := fromSink
d.addr_lo := addr_lo(fromAddress)
d.data := data
d.error := error
d
}
def ReleaseAck(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt) = {
def ReleaseAck(c: TLBundleC): TLBundleD = ReleaseAck(c.source, c.size)
def ReleaseAck(toSource: UInt, lgSize: UInt): TLBundleD = {
val d = Wire(new TLBundleD(bundle))
d.opcode := TLMessages.ReleaseAck
d.param := UInt(0)
d.size := lgSize
d.source := toSource
d.sink := fromSink
d.addr_lo := addr_lo(fromAddress)
d.sink := UInt(0)
d.data := UInt(0)
d.error := Bool(false)
d
@ -623,47 +618,44 @@ class TLEdgeIn(
(legal, b)
}
def AccessAck(a: TLBundleA, fromSink: UInt): TLBundleD = AccessAck(address(a), fromSink, a.source, a.size)
def AccessAck(a: TLBundleA, fromSink: UInt, error: Bool): TLBundleD = AccessAck(address(a), fromSink, a.source, a.size, error)
def AccessAck(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt): TLBundleD = AccessAck(fromAddress, fromSink, toSource, lgSize, Bool(false))
def AccessAck(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt, error: Bool) = {
def AccessAck(a: TLBundleA): TLBundleD = AccessAck(a.source, a.size)
def AccessAck(a: TLBundleA, error: Bool): TLBundleD = AccessAck(a.source, a.size, error)
def AccessAck(toSource: UInt, lgSize: UInt): TLBundleD = AccessAck(toSource, lgSize, Bool(false))
def AccessAck(toSource: UInt, lgSize: UInt, error: Bool) = {
val d = Wire(new TLBundleD(bundle))
d.opcode := TLMessages.AccessAck
d.param := UInt(0)
d.size := lgSize
d.source := toSource
d.sink := fromSink
d.addr_lo := addr_lo(fromAddress)
d.sink := UInt(0)
d.data := UInt(0)
d.error := error
d
}
def AccessAck(a: TLBundleA, fromSink: UInt, data: UInt): TLBundleD = AccessAck(address(a), fromSink, a.source, a.size, data)
def AccessAck(a: TLBundleA, fromSink: UInt, data: UInt, error: Bool): TLBundleD = AccessAck(address(a), fromSink, a.source, a.size, data, error)
def AccessAck(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt, data: UInt): TLBundleD = AccessAck(fromAddress, fromSink, toSource, lgSize, data, Bool(false))
def AccessAck(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt, data: UInt, error: Bool) = {
def AccessAck(a: TLBundleA, data: UInt): TLBundleD = AccessAck(a.source, a.size, data)
def AccessAck(a: TLBundleA, data: UInt, error: Bool): TLBundleD = AccessAck(a.source, a.size, data, error)
def AccessAck(toSource: UInt, lgSize: UInt, data: UInt): TLBundleD = AccessAck(toSource, lgSize, data, Bool(false))
def AccessAck(toSource: UInt, lgSize: UInt, data: UInt, error: Bool) = {
val d = Wire(new TLBundleD(bundle))
d.opcode := TLMessages.AccessAckData
d.param := UInt(0)
d.size := lgSize
d.source := toSource
d.sink := fromSink
d.addr_lo := addr_lo(fromAddress)
d.sink := UInt(0)
d.data := data
d.error := error
d
}
def HintAck(a: TLBundleA, fromSink: UInt): TLBundleD = HintAck(address(a), fromSink, a.source, a.size)
def HintAck(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt) = {
def HintAck(a: TLBundleA): TLBundleD = HintAck(a.source, a.size)
def HintAck(toSource: UInt, lgSize: UInt) = {
val d = Wire(new TLBundleD(bundle))
d.opcode := TLMessages.HintAck
d.param := UInt(0)
d.size := lgSize
d.source := toSource
d.sink := fromSink
d.addr_lo := addr_lo(fromAddress)
d.sink := UInt(0)
d.data := UInt(0)
d.error := Bool(false)
d

View File

@ -190,7 +190,6 @@ class TLFragmenter(val minSize: Int, val maxSize: Int, val alwaysMin: Boolean =
out.d.ready := in.d.ready || drop
in.d.valid := out.d.valid && !drop
in.d.bits := out.d.bits // pass most stuff unchanged
in.d.bits.addr_lo := out.d.bits.addr_lo & ~dsizeOH1
in.d.bits.source := out.d.bits.source >> addedBits
in.d.bits.size := Mux(dFirst, dFirst_size, dOrig)

View File

@ -40,7 +40,7 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f
out.a.valid := in.a.valid && !hintBitsAtA
in.a.ready := Mux(hintBitsAtA, hint.ready, out.a.ready)
hint.bits := edgeIn.HintAck(in.a.bits, UInt(0))
hint.bits := edgeIn.HintAck(in.a.bits)
out.a.bits := in.a.bits
TLArbiter(TLArbiter.lowestIndexFirst)(in.d, (edgeOut.numBeats1(out.d.bits), out.d), (UInt(0), Queue(hint, 1)))

View File

@ -232,12 +232,10 @@ class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args)
assert (TLMessages.isD(bundle.opcode), "'D' channel has invalid opcode" + extra)
val source_ok = edge.client.contains(bundle.source)
val is_aligned = edge.isAligned(bundle.addr_lo, bundle.size)
val sink_ok = Bool(edge.manager.endSinkId == 0) || bundle.sink < UInt(edge.manager.endSinkId)
when (bundle.opcode === TLMessages.ReleaseAck) {
assert (source_ok, "'D' channel ReleaseAck carries invalid source ID" + extra)
assert (is_aligned, "'D' channel ReleaseAck address not aligned to size" + extra)
assert (sink_ok, "'D' channel ReleaseAck carries invalid sink ID" + extra)
assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'D' channel ReleaseAck smaller than a beat" + extra)
assert (bundle.param === UInt(0), "'D' channel ReleaseeAck carries invalid param" + extra)
@ -245,7 +243,6 @@ class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args)
when (bundle.opcode === TLMessages.Grant) {
assert (source_ok, "'D' channel Grant carries invalid source ID" + extra)
assert (is_aligned, "'D' channel Grant address not aligned to size" + extra)
assert (sink_ok, "'D' channel Grant carries invalid sink ID" + extra)
assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'D' channel Grant smaller than a beat" + extra)
assert (TLPermissions.isCap(bundle.param), "'D' channel Grant carries invalid cap param" + extra)
@ -253,7 +250,6 @@ class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args)
when (bundle.opcode === TLMessages.GrantData) {
assert (source_ok, "'D' channel GrantData carries invalid source ID" + extra)
assert (is_aligned, "'D' channel GrantData address not aligned to size" + extra)
assert (sink_ok, "'D' channel GrantData carries invalid sink ID" + extra)
assert (bundle.size >= UInt(log2Ceil(edge.manager.beatBytes)), "'D' channel GrantData smaller than a beat" + extra)
assert (TLPermissions.isCap(bundle.param), "'D' channel GrantData carries invalid cap param" + extra)
@ -261,7 +257,6 @@ class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args)
when (bundle.opcode === TLMessages.AccessAck) {
assert (source_ok, "'D' channel AccessAck carries invalid source ID" + extra)
assert (is_aligned, "'D' channel AccessAck address not aligned to size" + extra)
assert (sink_ok, "'D' channel AccessAck carries invalid sink ID" + extra)
// size is ignored
assert (bundle.param === UInt(0), "'D' channel AccessAck carries invalid param" + extra)
@ -269,7 +264,6 @@ class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args)
when (bundle.opcode === TLMessages.AccessAckData) {
assert (source_ok, "'D' channel AccessAckData carries invalid source ID" + extra)
assert (is_aligned, "'D' channel AccessAckData address not aligned to size" + extra)
assert (sink_ok, "'D' channel AccessAckData carries invalid sink ID" + extra)
// size is ignored
assert (bundle.param === UInt(0), "'D' channel AccessAckData carries invalid param" + extra)
@ -277,7 +271,6 @@ class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args)
when (bundle.opcode === TLMessages.HintAck) {
assert (source_ok, "'D' channel HintAck carries invalid source ID" + extra)
assert (is_aligned, "'D' channel HintAck address not aligned to size" + extra)
assert (sink_ok, "'D' channel HintAck carries invalid sink ID" + extra)
// size is ignored
assert (bundle.param === UInt(0), "'D' channel HintAck carries invalid param" + extra)
@ -379,14 +372,12 @@ class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args)
val size = Reg(UInt())
val source = Reg(UInt())
val sink = Reg(UInt())
val addr_lo = Reg(UInt())
when (d.valid && !d_first) {
assert (d.bits.opcode === opcode, "'D' channel opcode changed within multibeat operation" + extra)
assert (d.bits.param === param, "'D' channel param changed within multibeat operation" + extra)
assert (d.bits.size === size, "'D' channel size changed within multibeat operation" + extra)
assert (d.bits.source === source, "'D' channel source changed within multibeat operation" + extra)
assert (d.bits.sink === sink, "'D' channel sink changed with multibeat operation" + extra)
assert (d.bits.addr_lo=== addr_lo,"'D' channel addr_lo changed with multibeat operation" + extra)
}
when (d.fire() && d_first) {
opcode := d.bits.opcode
@ -394,7 +385,6 @@ class TLMonitor(args: TLMonitorArgs) extends TLMonitorBase(args)
size := d.bits.size
source := d.bits.source
sink := d.bits.sink
addr_lo := d.bits.addr_lo
}
}

View File

@ -47,15 +47,14 @@ class TLRegisterNode(
val baseEnd = 0
val (sizeEnd, sizeOff) = (edge.bundle.sizeBits + baseEnd, baseEnd)
val (sourceEnd, sourceOff) = (edge.bundle.sourceBits + sizeEnd, sizeEnd)
val (addrLoEnd, addrLoOff) = (log2Up(beatBytes) + sourceEnd, sourceEnd)
val params = RegMapperParams(log2Up(size/beatBytes), beatBytes, addrLoEnd)
val params = RegMapperParams(log2Up(size/beatBytes), beatBytes, sourceEnd)
val in = Wire(Decoupled(new RegMapperInput(params)))
in.bits.read := a.bits.opcode === TLMessages.Get
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)
in.bits.extra := Cat(a.bits.source, a.bits.size)
// Invoke the register map builder
val out = RegMapper(beatBytes, concurrency, undefZero, in, mapping:_*)
@ -66,10 +65,8 @@ class TLRegisterNode(
d.valid := out.valid
out.ready := d.ready
// We must restore the size and addr_lo to enable width adapters to work
// We must restore the size to enable width adapters to work
d.bits := edge.AccessAck(
fromAddress = out.bits.extra(addrLoEnd-1, addrLoOff),
fromSink = UInt(0), // our unique sink id
toSource = out.bits.extra(sourceEnd-1, sourceOff),
lgSize = out.bits.extra(sizeEnd-1, sizeOff))

View File

@ -51,7 +51,6 @@ class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4,
val d_read = Reg(Bool())
val d_size = Reg(UInt())
val d_source = Reg(UInt())
val d_addr = Reg(UInt())
val d_data = Wire(UInt())
val d_legal = Reg(Bool())
@ -61,7 +60,7 @@ class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4,
in.d.valid := d_full
in.a.ready := in.d.ready || !d_full
in.d.bits := edge.AccessAck(d_addr, UInt(0), d_source, d_size, !d_legal)
in.d.bits := edge.AccessAck(d_source, d_size, !d_legal)
// avoid data-bus Mux
in.d.bits.data := d_data
in.d.bits.opcode := Mux(d_read, TLMessages.AccessAckData, TLMessages.AccessAck)
@ -74,7 +73,6 @@ class TLRAM(address: AddressSet, executable: Boolean = true, beatBytes: Int = 4,
d_read := read
d_size := in.a.bits.size
d_source := in.a.bits.source
d_addr := edge.addr_lo(in.a.bits)
d_legal := a_legal
}

View File

@ -170,7 +170,6 @@ class TLToAHB(val aFlow: Boolean = false)(implicit p: Parameters) extends LazyMo
val d_error = Reg(Bool())
val d_write = RegEnable(send.write, out.hreadyout)
val d_source = RegEnable(send.source, out.hreadyout)
val d_addr = RegEnable(send.addr, out.hreadyout)
val d_size = RegEnable(send.size, out.hreadyout)
when (out.hreadyout) {
@ -180,7 +179,7 @@ class TLToAHB(val aFlow: Boolean = false)(implicit p: Parameters) extends LazyMo
}
d.valid := d_valid && out.hreadyout
d.bits := edgeIn.AccessAck(d_addr, UInt(0), d_source, d_size, out.hrdata, out.hresp || d_error)
d.bits := edgeIn.AccessAck(d_source, d_size, out.hrdata, out.hresp || d_error)
d.bits.opcode := Mux(d_write, TLMessages.AccessAck, TLMessages.AccessAckData)
// AHB has no cache coherence

View File

@ -83,7 +83,7 @@ class TLToAPB(val aFlow: Boolean = true)(implicit p: Parameters) extends LazyMod
d.valid := a_enable && out.pready
assert (!d.valid || d.ready)
d.bits := edgeIn.AccessAck(a.bits, UInt(0), out.prdata, out.pslverr)
d.bits := edgeIn.AccessAck(a.bits, out.prdata, out.pslverr)
d.bits.opcode := Mux(a_write, TLMessages.AccessAck, TLMessages.AccessAckData)
}
}

View File

@ -93,18 +93,16 @@ class TLToAXI4(beatBytes: Int, combinational: Boolean = true, adapterName: Optio
ElaborationArtefacts.add(s"${n}.axi4.json", s"""{"mapping":[${maps.mkString(",")}]}""")
}
// We need to keep the following state from A => D: (addr_lo, size, source)
// We need to keep the following state from A => D: (size, source)
// All of those fields could potentially require 0 bits (argh. Chisel.)
// We will pack all of that extra information into the user bits.
val sourceBits = log2Ceil(edgeIn.client.endSourceId)
val sizeBits = log2Ceil(edgeIn.maxLgSize+1)
val addrBits = log2Ceil(edgeIn.manager.beatBytes)
val stateBits = addrBits + sizeBits + sourceBits // could be 0
val stateBits = sizeBits + sourceBits // could be 0
require (stateBits <= out.aw.bits.params.userBits)
val a_address = edgeIn.address(in.a.bits)
val a_addr_lo = edgeIn.addr_lo(a_address)
val a_source = in.a.bits.source
val a_size = edgeIn.size(in.a.bits)
val a_isPut = edgeIn.hasData(in.a.bits)
@ -113,26 +111,22 @@ class TLToAXI4(beatBytes: Int, combinational: Boolean = true, adapterName: Optio
// Make sure the fields are within the bounds we assumed
assert (a_source < UInt(BigInt(1) << sourceBits))
assert (a_size < UInt(BigInt(1) << sizeBits))
assert (a_addr_lo < UInt(BigInt(1) << addrBits))
// Carefully pack/unpack fields into the state we send
val baseEnd = 0
val (sourceEnd, sourceOff) = (sourceBits + baseEnd, baseEnd)
val (sizeEnd, sizeOff) = (sizeBits + sourceEnd, sourceEnd)
val (addrEnd, addrOff) = (addrBits + sizeEnd, sizeEnd)
require (addrEnd == stateBits)
require (sizeEnd == stateBits)
val a_state = (a_source << sourceOff) | (a_size << sizeOff) | (a_addr_lo << addrOff)
val a_state = (a_source << sourceOff) | (a_size << sizeOff)
val r_state = out.r.bits.user.getOrElse(UInt(0))
val r_source = if (sourceBits > 0) r_state(sourceEnd-1, sourceOff) else UInt(0)
val r_size = if (sizeBits > 0) r_state(sizeEnd -1, sizeOff) else UInt(0)
val r_addr_lo = if (addrBits > 0) r_state(addrEnd -1, addrOff) else UInt(0)
val b_state = out.b.bits.user.getOrElse(UInt(0))
val b_source = if (sourceBits > 0) b_state(sourceEnd-1, sourceOff) else UInt(0)
val b_size = if (sizeBits > 0) b_state(sizeEnd -1, sizeOff) else UInt(0)
val b_addr_lo = if (addrBits > 0) b_state(addrEnd -1, addrOff) else UInt(0)
// We need these Queues because AXI4 queues are irrevocable
val depth = if (combinational) 1 else 2
@ -188,8 +182,8 @@ class TLToAXI4(beatBytes: Int, combinational: Boolean = true, adapterName: Optio
val r_error = out.r.bits.resp =/= AXI4Parameters.RESP_OKAY
val b_error = out.b.bits.resp =/= AXI4Parameters.RESP_OKAY
val r_d = edgeIn.AccessAck(r_addr_lo, UInt(0), r_source, r_size, UInt(0), r_error)
val b_d = edgeIn.AccessAck(b_addr_lo, UInt(0), b_source, b_size, b_error)
val r_d = edgeIn.AccessAck(r_source, r_size, UInt(0), r_error)
val b_d = edgeIn.AccessAck(b_source, b_size, b_error)
in.d.bits := Mux(r_wins, r_d, b_d)
in.d.bits.data := out.r.bits.data // avoid a costly Mux