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)
|
extends TLBundleBase(params)
|
||||||
with HasTLData
|
with HasTLData
|
||||||
{
|
{
|
||||||
|
// fixed fields during multibeat:
|
||||||
val opcode = UInt(width = 3)
|
val opcode = UInt(width = 3)
|
||||||
val param = UInt(width = 3) // amo_opcode || perms || hint
|
val param = UInt(width = 3) // amo_opcode || perms || hint
|
||||||
val size = UInt(width = params.sizeBits)
|
val size = UInt(width = params.sizeBits)
|
||||||
val source = UInt(width = params.sourceBits) // from
|
val source = UInt(width = params.sourceBits) // from
|
||||||
val address = UInt(width = params.addressBits) // to
|
val address = UInt(width = params.addressBits) // to
|
||||||
|
// variable fields during multibeat:
|
||||||
val mask = UInt(width = params.dataBits/8)
|
val mask = UInt(width = params.dataBits/8)
|
||||||
val data = UInt(width = params.dataBits)
|
val data = UInt(width = params.dataBits)
|
||||||
|
|
||||||
@ -149,11 +151,13 @@ class TLBundleB(params: TLBundleParameters)
|
|||||||
extends TLBundleBase(params)
|
extends TLBundleBase(params)
|
||||||
with HasTLData
|
with HasTLData
|
||||||
{
|
{
|
||||||
|
// fixed fields during multibeat:
|
||||||
val opcode = UInt(width = 3)
|
val opcode = UInt(width = 3)
|
||||||
val param = UInt(width = 3)
|
val param = UInt(width = 3)
|
||||||
val size = UInt(width = params.sizeBits)
|
val size = UInt(width = params.sizeBits)
|
||||||
val source = UInt(width = params.sourceBits) // to
|
val source = UInt(width = params.sourceBits) // to
|
||||||
val address = UInt(width = params.addressBits) // from
|
val address = UInt(width = params.addressBits) // from
|
||||||
|
// variable fields during multibeat:
|
||||||
val mask = UInt(width = params.dataBits/8)
|
val mask = UInt(width = params.dataBits/8)
|
||||||
val data = UInt(width = params.dataBits)
|
val data = UInt(width = params.dataBits)
|
||||||
|
|
||||||
@ -168,11 +172,13 @@ class TLBundleC(params: TLBundleParameters)
|
|||||||
extends TLBundleBase(params)
|
extends TLBundleBase(params)
|
||||||
with HasTLData
|
with HasTLData
|
||||||
{
|
{
|
||||||
|
// fixed fields during multibeat:
|
||||||
val opcode = UInt(width = 3)
|
val opcode = UInt(width = 3)
|
||||||
val param = UInt(width = 3)
|
val param = UInt(width = 3)
|
||||||
val size = UInt(width = params.sizeBits)
|
val size = UInt(width = params.sizeBits)
|
||||||
val source = UInt(width = params.sourceBits) // from
|
val source = UInt(width = params.sourceBits) // from
|
||||||
val address = UInt(width = params.addressBits) // to
|
val address = UInt(width = params.addressBits) // to
|
||||||
|
// variable fields during multibeat:
|
||||||
val data = UInt(width = params.dataBits)
|
val data = UInt(width = params.dataBits)
|
||||||
val error = Bool() // AccessAck[Data]
|
val error = Bool() // AccessAck[Data]
|
||||||
|
|
||||||
@ -192,11 +198,13 @@ class TLBundleD(params: TLBundleParameters)
|
|||||||
extends TLBundleBase(params)
|
extends TLBundleBase(params)
|
||||||
with HasTLData
|
with HasTLData
|
||||||
{
|
{
|
||||||
|
// fixed fields during multibeat:
|
||||||
val opcode = UInt(width = 3)
|
val opcode = UInt(width = 3)
|
||||||
val param = UInt(width = 2)
|
val param = UInt(width = 2)
|
||||||
val size = UInt(width = params.sizeBits)
|
val size = UInt(width = params.sizeBits)
|
||||||
val source = UInt(width = params.sourceBits) // to
|
val source = UInt(width = params.sourceBits) // to
|
||||||
val sink = UInt(width = params.sinkBits) // from
|
val sink = UInt(width = params.sinkBits) // from
|
||||||
|
// variable fields during multibeat:
|
||||||
val data = UInt(width = params.dataBits)
|
val data = UInt(width = params.dataBits)
|
||||||
val error = Bool() // AccessAck[Data], Grant[Data]
|
val error = Bool() // AccessAck[Data], Grant[Data]
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import chisel3.internal.sourceinfo.SourceInfo
|
|||||||
|
|
||||||
object TLMonitor
|
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)
|
assert (TLMessages.isA(bundle.opcode), "'A' channel has invalid opcode")(sourceInfo)
|
||||||
|
|
||||||
// Reuse these subexpressions to save some firrtl lines
|
// 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)
|
assert (TLMessages.isB(bundle.opcode), "'B' channel has invalid opcode")(sourceInfo)
|
||||||
|
|
||||||
// Reuse these subexpressions to save some firrtl lines
|
// 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)
|
assert (TLMessages.isC(bundle.opcode), "'C' channel has invalid opcode")(sourceInfo)
|
||||||
|
|
||||||
val source_ok = edge.client.contains(bundle.source)
|
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)
|
assert (TLMessages.isD(bundle.opcode), "'D' channel has invalid opcode")(sourceInfo)
|
||||||
|
|
||||||
val source_ok = edge.client.contains(bundle.source)
|
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)
|
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) = {
|
def legalize(bundleOut: TLBundle, edgeOut: TLEdgeOut, bundleIn: TLBundle, edgeIn: TLEdgeIn, sourceInfo: SourceInfo) = {
|
||||||
when (bundleOut.a.valid) { legalizeA(bundleOut.a.bits, edgeOut, sourceInfo) }
|
legalizeFormat(bundleOut, edgeOut, bundleIn, edgeIn, sourceInfo)
|
||||||
when (bundleIn .b.valid) { legalizeB(bundleIn .b.bits, edgeIn, sourceInfo) }
|
legalizeMultibeat(bundleOut, edgeOut, bundleIn, 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) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user