1
0

tilelink2: explicitly check that fixed fields never change in multibeat

This commit is contained in:
Wesley W. Terpstra 2016-09-01 11:34:56 -07:00
parent e652cd155b
commit 935b53f3bf
2 changed files with 138 additions and 10 deletions

View File

@ -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]

View File

@ -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) }
} }
} }