tilelink2: explicitly check that fixed fields never change in multibeat
This commit is contained in:
parent
e652cd155b
commit
935b53f3bf
@ -126,11 +126,13 @@ class TLBundleA(params: TLBundleParameters)
|
||||
extends TLBundleBase(params)
|
||||
with HasTLData
|
||||
{
|
||||
// fixed fields during multibeat:
|
||||
val opcode = UInt(width = 3)
|
||||
val param = UInt(width = 3) // amo_opcode || 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)
|
||||
|
||||
@ -149,11 +151,13 @@ class TLBundleB(params: TLBundleParameters)
|
||||
extends TLBundleBase(params)
|
||||
with HasTLData
|
||||
{
|
||||
// fixed fields during multibeat:
|
||||
val opcode = UInt(width = 3)
|
||||
val param = UInt(width = 3)
|
||||
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)
|
||||
|
||||
@ -168,11 +172,13 @@ class TLBundleC(params: TLBundleParameters)
|
||||
extends TLBundleBase(params)
|
||||
with HasTLData
|
||||
{
|
||||
// fixed fields during multibeat:
|
||||
val opcode = UInt(width = 3)
|
||||
val param = UInt(width = 3)
|
||||
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]
|
||||
|
||||
@ -192,11 +198,13 @@ class TLBundleD(params: TLBundleParameters)
|
||||
extends TLBundleBase(params)
|
||||
with HasTLData
|
||||
{
|
||||
// fixed fields during multibeat:
|
||||
val opcode = UInt(width = 3)
|
||||
val param = UInt(width = 2)
|
||||
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]
|
||||
|
||||
|
@ -7,7 +7,7 @@ import chisel3.internal.sourceinfo.SourceInfo
|
||||
|
||||
object TLMonitor
|
||||
{
|
||||
def legalizeA(bundle: TLBundleA, edge: TLEdgeOut, sourceInfo: SourceInfo) = {
|
||||
def legalizeFormatA(bundle: TLBundleA, edge: TLEdgeOut, sourceInfo: SourceInfo) = {
|
||||
assert (TLMessages.isA(bundle.opcode), "'A' channel has invalid opcode")(sourceInfo)
|
||||
|
||||
// Reuse these subexpressions to save some firrtl lines
|
||||
@ -72,7 +72,7 @@ object TLMonitor
|
||||
}
|
||||
}
|
||||
|
||||
def legalizeB(bundle: TLBundleB, edge: TLEdgeIn, sourceInfo: SourceInfo) = {
|
||||
def legalizeFormatB(bundle: TLBundleB, edge: TLEdgeIn, sourceInfo: SourceInfo) = {
|
||||
assert (TLMessages.isB(bundle.opcode), "'B' channel has invalid opcode")(sourceInfo)
|
||||
|
||||
// Reuse these subexpressions to save some firrtl lines
|
||||
@ -137,7 +137,7 @@ object TLMonitor
|
||||
}
|
||||
}
|
||||
|
||||
def legalizeC(bundle: TLBundleC, edge: TLEdgeOut, sourceInfo: SourceInfo) = {
|
||||
def legalizeFormatC(bundle: TLBundleC, edge: TLEdgeOut, sourceInfo: SourceInfo) = {
|
||||
assert (TLMessages.isC(bundle.opcode), "'C' channel has invalid opcode")(sourceInfo)
|
||||
|
||||
val source_ok = edge.client.contains(bundle.source)
|
||||
@ -203,7 +203,7 @@ object TLMonitor
|
||||
}
|
||||
}
|
||||
|
||||
def legalizeD(bundle: TLBundleD, edge: TLEdgeIn, sourceInfo: SourceInfo) = {
|
||||
def legalizeFormatD(bundle: TLBundleD, edge: TLEdgeIn, sourceInfo: SourceInfo) = {
|
||||
assert (TLMessages.isD(bundle.opcode), "'D' channel has invalid opcode")(sourceInfo)
|
||||
|
||||
val source_ok = edge.client.contains(bundle.source)
|
||||
@ -254,15 +254,135 @@ object TLMonitor
|
||||
}
|
||||
}
|
||||
|
||||
def legalizeE(bundle: TLBundleE, edge: TLEdgeOut, sourceInfo: SourceInfo) = {
|
||||
def legalizeFormatE(bundle: TLBundleE, edge: TLEdgeOut, sourceInfo: SourceInfo) = {
|
||||
assert (edge.manager.containsById(bundle.sink), "'E' channels carries invalid sink ID")(sourceInfo)
|
||||
}
|
||||
|
||||
def legalizeFormat(bundleOut: TLBundle, edgeOut: TLEdgeOut, bundleIn: TLBundle, edgeIn: TLEdgeIn, sourceInfo: SourceInfo) = {
|
||||
when (bundleOut.a.valid) { legalizeFormatA(bundleOut.a.bits, edgeOut, sourceInfo) }
|
||||
when (bundleIn .b.valid) { legalizeFormatB(bundleIn .b.bits, edgeIn, sourceInfo) }
|
||||
when (bundleOut.c.valid) { legalizeFormatC(bundleOut.c.bits, edgeOut, sourceInfo) }
|
||||
when (bundleIn .d.valid) { legalizeFormatD(bundleIn .d.bits, edgeIn, sourceInfo) }
|
||||
when (bundleOut.e.valid) { legalizeFormatE(bundleOut.e.bits, edgeOut, sourceInfo) }
|
||||
}
|
||||
|
||||
def legalizeMultibeatA(a: DecoupledIO[TLBundleA], edge: TLEdgeOut, sourceInfo: SourceInfo) = {
|
||||
val counter = RegInit(UInt(0, width = log2Up(edge.maxTransfer)))
|
||||
val opcode = Reg(UInt())
|
||||
val param = Reg(UInt())
|
||||
val size = Reg(UInt())
|
||||
val source = Reg(UInt())
|
||||
val address = Reg(UInt())
|
||||
when (a.valid && counter =/= UInt(0)) {
|
||||
assert (a.bits.opcode === opcode, "'A' channel opcode changed within multibeat operation")(sourceInfo)
|
||||
assert (a.bits.param === param, "'A' channel param changed within multibeat operation")(sourceInfo)
|
||||
assert (a.bits.size === size, "'A' channel size changed within multibeat operation")(sourceInfo)
|
||||
assert (a.bits.source === source, "'A' channel source changed within multibeat operation")(sourceInfo)
|
||||
assert (a.bits.address=== address,"'A' channel address changed with multibeat operation")(sourceInfo)
|
||||
}
|
||||
when (a.fire()) {
|
||||
counter := counter - UInt(1)
|
||||
when (counter === UInt(0)) {
|
||||
counter := edge.numBeats(a.bits) - UInt(1)
|
||||
opcode := a.bits.opcode
|
||||
param := a.bits.param
|
||||
size := a.bits.size
|
||||
source := a.bits.source
|
||||
address := a.bits.address
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def legalizeMultibeatB(b: DecoupledIO[TLBundleB], edge: TLEdgeIn, sourceInfo: SourceInfo) = {
|
||||
val counter = RegInit(UInt(0, width = log2Up(edge.maxTransfer)))
|
||||
val opcode = Reg(UInt())
|
||||
val param = Reg(UInt())
|
||||
val size = Reg(UInt())
|
||||
val source = Reg(UInt())
|
||||
val address = Reg(UInt())
|
||||
when (b.valid && counter =/= UInt(0)) {
|
||||
assert (b.bits.opcode === opcode, "'B' channel opcode changed within multibeat operation")(sourceInfo)
|
||||
assert (b.bits.param === param, "'B' channel param changed within multibeat operation")(sourceInfo)
|
||||
assert (b.bits.size === size, "'B' channel size changed within multibeat operation")(sourceInfo)
|
||||
assert (b.bits.source === source, "'B' channel source changed within multibeat operation")(sourceInfo)
|
||||
assert (b.bits.address=== address,"'B' channel address changed with multibeat operation")(sourceInfo)
|
||||
}
|
||||
when (b.fire()) {
|
||||
counter := counter - UInt(1)
|
||||
when (counter === UInt(0)) {
|
||||
counter := edge.numBeats(b.bits) - UInt(1)
|
||||
opcode := b.bits.opcode
|
||||
param := b.bits.param
|
||||
size := b.bits.size
|
||||
source := b.bits.source
|
||||
address := b.bits.address
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def legalizeMultibeatC(c: DecoupledIO[TLBundleC], edge: TLEdgeOut, sourceInfo: SourceInfo) = {
|
||||
val counter = RegInit(UInt(0, width = log2Up(edge.maxTransfer)))
|
||||
val opcode = Reg(UInt())
|
||||
val param = Reg(UInt())
|
||||
val size = Reg(UInt())
|
||||
val source = Reg(UInt())
|
||||
val address = Reg(UInt())
|
||||
when (c.valid && counter =/= UInt(0)) {
|
||||
assert (c.bits.opcode === opcode, "'C' channel opcode changed within multibeat operation")(sourceInfo)
|
||||
assert (c.bits.param === param, "'C' channel param changed within multibeat operation")(sourceInfo)
|
||||
assert (c.bits.size === size, "'C' channel size changed within multibeat operation")(sourceInfo)
|
||||
assert (c.bits.source === source, "'C' channel source changed within multibeat operation")(sourceInfo)
|
||||
assert (c.bits.address=== address,"'C' channel address changed with multibeat operation")(sourceInfo)
|
||||
}
|
||||
when (c.fire()) {
|
||||
counter := counter - UInt(1)
|
||||
when (counter === UInt(0)) {
|
||||
counter := edge.numBeats(c.bits) - UInt(1)
|
||||
opcode := c.bits.opcode
|
||||
param := c.bits.param
|
||||
size := c.bits.size
|
||||
source := c.bits.source
|
||||
address := c.bits.address
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def legalizeMultibeatD(d: DecoupledIO[TLBundleD], edge: TLEdgeIn, sourceInfo: SourceInfo) = {
|
||||
val counter = RegInit(UInt(0, width = log2Up(edge.maxTransfer)))
|
||||
val opcode = Reg(UInt())
|
||||
val param = Reg(UInt())
|
||||
val size = Reg(UInt())
|
||||
val source = Reg(UInt())
|
||||
val sink = Reg(UInt())
|
||||
when (d.valid && counter =/= UInt(0)) {
|
||||
assert (d.bits.opcode === opcode, "'D' channel opcode changed within multibeat operation")(sourceInfo)
|
||||
assert (d.bits.param === param, "'D' channel param changed within multibeat operation")(sourceInfo)
|
||||
assert (d.bits.size === size, "'D' channel size changed within multibeat operation")(sourceInfo)
|
||||
assert (d.bits.source === source, "'D' channel source changed within multibeat operation")(sourceInfo)
|
||||
assert (d.bits.sink === sink, "'D' channel sink changed with multibeat operation")(sourceInfo)
|
||||
}
|
||||
when (d.fire()) {
|
||||
counter := counter - UInt(1)
|
||||
when (counter === UInt(0)) {
|
||||
counter := edge.numBeats(d.bits) - UInt(1)
|
||||
opcode := d.bits.opcode
|
||||
param := d.bits.param
|
||||
size := d.bits.size
|
||||
source := d.bits.source
|
||||
sink := d.bits.sink
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def legalizeMultibeat(bundleOut: TLBundle, edgeOut: TLEdgeOut, bundleIn: TLBundle, edgeIn: TLEdgeIn, sourceInfo: SourceInfo) = {
|
||||
legalizeMultibeatA(bundleOut.a, edgeOut, sourceInfo)
|
||||
legalizeMultibeatB(bundleOut.b, edgeIn, sourceInfo)
|
||||
legalizeMultibeatC(bundleOut.c, edgeOut, sourceInfo)
|
||||
legalizeMultibeatD(bundleOut.d, edgeIn, sourceInfo)
|
||||
}
|
||||
|
||||
def legalize(bundleOut: TLBundle, edgeOut: TLEdgeOut, bundleIn: TLBundle, edgeIn: TLEdgeIn, sourceInfo: SourceInfo) = {
|
||||
when (bundleOut.a.valid) { legalizeA(bundleOut.a.bits, edgeOut, sourceInfo) }
|
||||
when (bundleIn .b.valid) { legalizeB(bundleIn .b.bits, edgeIn, sourceInfo) }
|
||||
when (bundleOut.c.valid) { legalizeC(bundleOut.c.bits, edgeOut, sourceInfo) }
|
||||
when (bundleIn .d.valid) { legalizeD(bundleIn .d.bits, edgeIn, sourceInfo) }
|
||||
when (bundleOut.e.valid) { legalizeE(bundleOut.e.bits, edgeOut, sourceInfo) }
|
||||
legalizeFormat(bundleOut, edgeOut, bundleIn, edgeIn, sourceInfo)
|
||||
legalizeMultibeat(bundleOut, edgeOut, bundleIn, edgeIn, sourceInfo)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user