2016-11-28 01:16:37 +01:00
|
|
|
// See LICENSE.SiFive for license details.
|
2016-08-19 20:08:35 +02:00
|
|
|
|
|
|
|
package uncore.tilelink2
|
|
|
|
|
|
|
|
import Chisel._
|
2016-08-31 21:17:55 +02:00
|
|
|
import chisel3.internal.sourceinfo.SourceInfo
|
2016-10-04 00:17:36 +02:00
|
|
|
import diplomacy._
|
2016-08-19 20:08:35 +02:00
|
|
|
|
2016-08-24 01:23:35 +02:00
|
|
|
class TLEdge(
|
2016-08-19 20:08:35 +02:00
|
|
|
client: TLClientPortParameters,
|
|
|
|
manager: TLManagerPortParameters)
|
|
|
|
extends TLEdgeParameters(client, manager)
|
2016-08-24 01:23:35 +02:00
|
|
|
{
|
2016-10-14 23:09:39 +02:00
|
|
|
def isAligned(address: UInt, lgSize: UInt): Bool = {
|
2016-09-07 08:46:44 +02:00
|
|
|
if (maxLgSize == 0) Bool(true) else {
|
|
|
|
val mask = UIntToOH1(lgSize, maxLgSize)
|
2016-10-14 23:09:39 +02:00
|
|
|
(address & mask) === UInt(0)
|
2016-09-07 08:46:44 +02:00
|
|
|
}
|
|
|
|
}
|
2016-08-24 01:23:35 +02:00
|
|
|
|
2016-10-14 23:09:39 +02:00
|
|
|
def mask(address: UInt, lgSize: UInt): UInt =
|
|
|
|
maskGen(address, lgSize, manager.beatBytes)
|
2016-09-05 03:22:12 +02:00
|
|
|
|
2016-09-07 08:46:44 +02:00
|
|
|
def staticHasData(bundle: TLChannel): Option[Boolean] = {
|
|
|
|
bundle match {
|
|
|
|
case _:TLBundleA => {
|
2016-09-03 04:55:08 +02:00
|
|
|
// Do there exist A messages with Data?
|
|
|
|
val aDataYes = manager.anySupportArithmetic || manager.anySupportLogical || manager.anySupportPutFull || manager.anySupportPutPartial
|
|
|
|
// Do there exist A messages without Data?
|
2017-01-18 03:52:16 +01:00
|
|
|
val aDataNo = manager.anySupportAcquireB || manager.anySupportGet || manager.anySupportHint
|
2016-09-03 04:55:08 +02:00
|
|
|
// Statically optimize the case where hasData is a constant
|
|
|
|
if (!aDataYes) Some(false) else if (!aDataNo) Some(true) else None
|
|
|
|
}
|
2016-09-07 08:46:44 +02:00
|
|
|
case _:TLBundleB => {
|
2016-09-03 04:55:08 +02:00
|
|
|
// Do there exist B messages with Data?
|
|
|
|
val bDataYes = client.anySupportArithmetic || client.anySupportLogical || client.anySupportPutFull || client.anySupportPutPartial
|
|
|
|
// Do there exist B messages without Data?
|
|
|
|
val bDataNo = client.anySupportProbe || client.anySupportGet || client.anySupportHint
|
|
|
|
// Statically optimize the case where hasData is a constant
|
|
|
|
if (!bDataYes) Some(false) else if (!bDataNo) Some(true) else None
|
|
|
|
}
|
2016-09-07 08:46:44 +02:00
|
|
|
case _:TLBundleC => {
|
2016-09-03 04:55:08 +02:00
|
|
|
// Do there eixst C messages with Data?
|
|
|
|
val cDataYes = client.anySupportGet || client.anySupportArithmetic || client.anySupportLogical || client.anySupportProbe
|
|
|
|
// Do there exist C messages without Data?
|
|
|
|
val cDataNo = client.anySupportPutFull || client.anySupportPutPartial || client.anySupportHint || client.anySupportProbe
|
|
|
|
if (!cDataYes) Some(false) else if (!cDataNo) Some(true) else None
|
|
|
|
}
|
2016-09-07 08:46:44 +02:00
|
|
|
case _:TLBundleD => {
|
2016-09-03 04:55:08 +02:00
|
|
|
// Do there eixst D messages with Data?
|
2017-01-18 03:52:16 +01:00
|
|
|
val dDataYes = manager.anySupportGet || manager.anySupportArithmetic || manager.anySupportLogical || manager.anySupportAcquireB
|
2016-09-03 04:55:08 +02:00
|
|
|
// Do there exist D messages without Data?
|
2017-01-18 03:52:16 +01:00
|
|
|
val dDataNo = manager.anySupportPutFull || manager.anySupportPutPartial || manager.anySupportHint || manager.anySupportAcquireT
|
2016-09-03 04:55:08 +02:00
|
|
|
if (!dDataYes) Some(false) else if (!dDataNo) Some(true) else None
|
|
|
|
}
|
2016-09-07 08:46:44 +02:00
|
|
|
case _:TLBundleE => Some(false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
def hasFollowUp(x: TLChannel): Bool = {
|
|
|
|
x match {
|
|
|
|
case a: TLBundleA => Bool(true)
|
|
|
|
case b: TLBundleB => Bool(true)
|
|
|
|
case c: TLBundleC => c.opcode(2) && c.opcode(1)
|
|
|
|
// opcode === TLMessages.Release ||
|
|
|
|
// opcode === TLMessages.ReleaseData
|
|
|
|
case d: TLBundleD => d.opcode(2) && !d.opcode(1)
|
|
|
|
// opcode === TLMessages.Grant ||
|
|
|
|
// opcode === TLMessages.GrantData
|
|
|
|
case e: TLBundleE => Bool(false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
def hasData(x: TLChannel): Bool = {
|
|
|
|
val opdata = x match {
|
|
|
|
case a: TLBundleA => !a.opcode(2)
|
|
|
|
// opcode === TLMessages.PutFullData ||
|
|
|
|
// opcode === TLMessages.PutPartialData ||
|
|
|
|
// opcode === TLMessages.ArithmeticData ||
|
|
|
|
// opcode === TLMessages.LogicalData
|
|
|
|
case b: TLBundleB => !b.opcode(2)
|
|
|
|
// opcode === TLMessages.PutFullData ||
|
|
|
|
// opcode === TLMessages.PutPartialData ||
|
|
|
|
// opcode === TLMessages.ArithmeticData ||
|
|
|
|
// opcode === TLMessages.LogicalData
|
|
|
|
case c: TLBundleC => c.opcode(0)
|
|
|
|
// opcode === TLMessages.AccessAckData ||
|
|
|
|
// opcode === TLMessages.ProbeAckData ||
|
|
|
|
// opcode === TLMessages.ReleaseData
|
|
|
|
case d: TLBundleD => d.opcode(0)
|
|
|
|
// opcode === TLMessages.AccessAckData ||
|
|
|
|
// opcode === TLMessages.GrantData
|
|
|
|
case e: TLBundleE => Bool(false)
|
|
|
|
}
|
|
|
|
staticHasData(x).map(Bool(_)).getOrElse(opdata)
|
|
|
|
}
|
|
|
|
|
2016-12-01 23:55:25 +01:00
|
|
|
def opcode(x: TLDataChannel): UInt = {
|
|
|
|
x match {
|
|
|
|
case a: TLBundleA => a.opcode
|
|
|
|
case b: TLBundleB => b.opcode
|
|
|
|
case c: TLBundleC => c.opcode
|
|
|
|
case d: TLBundleD => d.opcode
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
def param(x: TLDataChannel): UInt = {
|
|
|
|
x match {
|
|
|
|
case a: TLBundleA => a.param
|
|
|
|
case b: TLBundleB => b.param
|
|
|
|
case c: TLBundleC => c.param
|
|
|
|
case d: TLBundleD => d.param
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-07 08:46:44 +02:00
|
|
|
def size(x: TLDataChannel): UInt = {
|
|
|
|
x match {
|
|
|
|
case a: TLBundleA => a.size
|
|
|
|
case b: TLBundleB => b.size
|
|
|
|
case c: TLBundleC => c.size
|
|
|
|
case d: TLBundleD => d.size
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
def data(x: TLDataChannel): UInt = {
|
|
|
|
x match {
|
|
|
|
case a: TLBundleA => a.data
|
|
|
|
case b: TLBundleB => b.data
|
|
|
|
case c: TLBundleC => c.data
|
|
|
|
case d: TLBundleD => d.data
|
2016-09-03 04:55:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-07 08:46:44 +02:00
|
|
|
def mask(x: TLDataChannel): UInt = {
|
|
|
|
x match {
|
|
|
|
case a: TLBundleA => a.mask
|
|
|
|
case b: TLBundleB => b.mask
|
2016-10-14 23:09:39 +02:00
|
|
|
case c: TLBundleC => mask(c.address, c.size)
|
2016-09-07 08:46:44 +02:00
|
|
|
case d: TLBundleD => mask(d.addr_lo, d.size)
|
|
|
|
}
|
|
|
|
}
|
2016-09-03 04:55:08 +02:00
|
|
|
|
2016-09-27 02:00:03 +02:00
|
|
|
def full_mask(x: TLDataChannel): UInt = {
|
|
|
|
x match {
|
2016-10-14 23:09:39 +02:00
|
|
|
case a: TLBundleA => mask(a.address, a.size)
|
|
|
|
case b: TLBundleB => mask(b.address, b.size)
|
|
|
|
case c: TLBundleC => mask(c.address, c.size)
|
2016-09-27 02:00:03 +02:00
|
|
|
case d: TLBundleD => mask(d.addr_lo, d.size)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-14 23:09:39 +02:00
|
|
|
def address(x: TLDataChannel): UInt = {
|
2016-09-07 08:46:44 +02:00
|
|
|
x match {
|
2016-10-14 23:09:39 +02:00
|
|
|
case a: TLBundleA => a.address
|
|
|
|
case b: TLBundleB => b.address
|
|
|
|
case c: TLBundleC => c.address
|
2016-09-07 08:46:44 +02:00
|
|
|
case d: TLBundleD => d.addr_lo
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-14 23:09:39 +02:00
|
|
|
def addr_hi(x: UInt): UInt = x >> log2Ceil(manager.beatBytes)
|
|
|
|
def addr_lo(x: UInt): UInt =
|
2016-09-27 02:00:03 +02:00
|
|
|
if (manager.beatBytes == 1) UInt(0) else x(log2Ceil(manager.beatBytes)-1, 0)
|
|
|
|
|
2016-10-14 23:09:39 +02:00
|
|
|
def addr_hi(x: TLAddrChannel): UInt = addr_hi(address(x))
|
|
|
|
def addr_lo(x: TLDataChannel): UInt = addr_lo(address(x))
|
2016-09-27 02:00:03 +02:00
|
|
|
|
2016-09-07 08:46:44 +02:00
|
|
|
def numBeats(x: TLChannel): UInt = {
|
|
|
|
x match {
|
|
|
|
case _: TLBundleE => UInt(1)
|
|
|
|
case bundle: TLDataChannel => {
|
|
|
|
val hasData = this.hasData(bundle)
|
|
|
|
val size = this.size(bundle)
|
|
|
|
val cutoff = log2Ceil(manager.beatBytes)
|
|
|
|
val small = if (manager.maxTransfer <= manager.beatBytes) Bool(true) else size <= UInt(cutoff)
|
|
|
|
val decode = UIntToOH(size, maxLgSize+1) >> cutoff
|
2016-09-10 05:55:56 +02:00
|
|
|
Mux(hasData, decode | small.asUInt, UInt(1))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
def numBeats1(x: TLChannel): UInt = {
|
|
|
|
x match {
|
|
|
|
case _: TLBundleE => UInt(0)
|
|
|
|
case bundle: TLDataChannel => {
|
2016-09-23 07:06:22 +02:00
|
|
|
if (maxLgSize == 0) {
|
|
|
|
UInt(0)
|
|
|
|
} else {
|
|
|
|
val decode = UIntToOH1(size(bundle), maxLgSize) >> log2Ceil(manager.beatBytes)
|
|
|
|
Mux(hasData(bundle), decode, UInt(0))
|
|
|
|
}
|
2016-09-07 08:46:44 +02:00
|
|
|
}
|
|
|
|
}
|
2016-08-24 01:23:35 +02:00
|
|
|
}
|
2016-10-08 05:15:31 +02:00
|
|
|
|
2016-11-14 20:56:48 +01:00
|
|
|
def firstlastHelper(bits: TLChannel, fire: Bool): (Bool, Bool, Bool, UInt) = {
|
2016-10-08 05:15:31 +02:00
|
|
|
val beats1 = numBeats1(bits)
|
|
|
|
val counter = RegInit(UInt(0, width = log2Up(maxTransfer / manager.beatBytes)))
|
|
|
|
val counter1 = counter - UInt(1)
|
|
|
|
val first = counter === UInt(0)
|
|
|
|
val last = counter === UInt(1) || beats1 === UInt(0)
|
2016-11-14 20:56:48 +01:00
|
|
|
val done = last && fire
|
|
|
|
val count = (beats1 & ~counter1)
|
2016-10-08 05:15:31 +02:00
|
|
|
when (fire) {
|
|
|
|
counter := Mux(first, beats1, counter1)
|
|
|
|
}
|
2016-11-14 20:56:48 +01:00
|
|
|
(first, last, done, count)
|
2016-10-08 05:15:31 +02:00
|
|
|
}
|
|
|
|
|
2016-11-14 20:56:48 +01:00
|
|
|
def first(bits: TLChannel, fire: Bool): Bool = firstlastHelper(bits, fire)._1
|
|
|
|
def first(x: DecoupledIO[TLChannel]): Bool = first(x.bits, x.fire())
|
2016-11-19 04:01:36 +01:00
|
|
|
def first(x: ValidIO[TLChannel]): Bool = first(x.bits, x.valid)
|
2016-11-14 20:56:48 +01:00
|
|
|
|
|
|
|
def last(bits: TLChannel, fire: Bool): Bool = firstlastHelper(bits, fire)._2
|
|
|
|
def last(x: DecoupledIO[TLChannel]): Bool = last(x.bits, x.fire())
|
2016-11-19 04:01:36 +01:00
|
|
|
def last(x: ValidIO[TLChannel]): Bool = last(x.bits, x.valid)
|
2016-11-14 20:56:48 +01:00
|
|
|
|
|
|
|
def firstlast(bits: TLChannel, fire: Bool): (Bool, Bool, Bool) = {
|
|
|
|
val r = firstlastHelper(bits, fire)
|
|
|
|
(r._1, r._2, r._3)
|
|
|
|
}
|
|
|
|
def firstlast(x: DecoupledIO[TLChannel]): (Bool, Bool, Bool) = firstlast(x.bits, x.fire())
|
2016-11-19 04:01:36 +01:00
|
|
|
def firstlast(x: ValidIO[TLChannel]): (Bool, Bool, Bool) = firstlast(x.bits, x.valid)
|
2016-11-14 20:56:48 +01:00
|
|
|
|
|
|
|
def count(bits: TLChannel, fire: Bool): (Bool, Bool, Bool, UInt) = {
|
|
|
|
val r = firstlastHelper(bits, fire)
|
|
|
|
(r._1, r._2, r._3, r._4)
|
|
|
|
}
|
|
|
|
def count(x: DecoupledIO[TLChannel]): (Bool, Bool, Bool, UInt) = count(x.bits, x.fire())
|
2016-11-19 04:01:36 +01:00
|
|
|
def count(x: ValidIO[TLChannel]): (Bool, Bool, Bool, UInt) = count(x.bits, x.valid)
|
2016-11-14 20:56:48 +01:00
|
|
|
|
|
|
|
def addr_inc(bits: TLChannel, fire: Bool): (Bool, Bool, Bool, UInt) = {
|
|
|
|
val r = firstlastHelper(bits, fire)
|
|
|
|
(r._1, r._2, r._3, r._4 << log2Ceil(manager.beatBytes))
|
|
|
|
}
|
|
|
|
def addr_inc(x: DecoupledIO[TLChannel]): (Bool, Bool, Bool, UInt) = addr_inc(x.bits, x.fire())
|
2016-11-19 04:01:36 +01:00
|
|
|
def addr_inc(x: ValidIO[TLChannel]): (Bool, Bool, Bool, UInt) = addr_inc(x.bits, x.valid)
|
2016-08-24 01:23:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
class TLEdgeOut(
|
|
|
|
client: TLClientPortParameters,
|
|
|
|
manager: TLManagerPortParameters)
|
|
|
|
extends TLEdge(client, manager)
|
2016-08-19 20:08:35 +02:00
|
|
|
{
|
|
|
|
// Transfers
|
2016-08-20 05:28:58 +02:00
|
|
|
def Acquire(fromSource: UInt, toAddress: UInt, lgSize: UInt, growPermissions: UInt) = {
|
2017-01-18 03:52:16 +01:00
|
|
|
require (manager.anySupportAcquireB)
|
|
|
|
val legal = manager.supportsAcquireBFast(toAddress, lgSize)
|
2016-08-27 00:32:20 +02:00
|
|
|
val a = Wire(new TLBundleA(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
a.opcode := TLMessages.Acquire
|
|
|
|
a.param := growPermissions
|
|
|
|
a.size := lgSize
|
|
|
|
a.source := fromSource
|
2016-10-14 23:09:39 +02:00
|
|
|
a.address := toAddress
|
2016-11-12 03:34:48 +01:00
|
|
|
a.mask := mask(toAddress, lgSize)
|
2016-08-20 05:28:58 +02:00
|
|
|
a.data := UInt(0)
|
|
|
|
(legal, a)
|
|
|
|
}
|
|
|
|
|
|
|
|
def Release(fromSource: UInt, toAddress: UInt, lgSize: UInt, shrinkPermissions: UInt) = {
|
2017-01-18 03:52:16 +01:00
|
|
|
require (manager.anySupportAcquireB)
|
|
|
|
val legal = manager.supportsAcquireBFast(toAddress, lgSize)
|
2016-08-27 00:32:20 +02:00
|
|
|
val c = Wire(new TLBundleC(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
c.opcode := TLMessages.Release
|
|
|
|
c.param := shrinkPermissions
|
|
|
|
c.size := lgSize
|
|
|
|
c.source := fromSource
|
2016-10-14 23:09:39 +02:00
|
|
|
c.address := toAddress
|
2016-08-20 05:28:58 +02:00
|
|
|
c.data := UInt(0)
|
2016-08-30 23:38:26 +02:00
|
|
|
c.error := Bool(false)
|
2016-08-20 05:28:58 +02:00
|
|
|
(legal, c)
|
|
|
|
}
|
|
|
|
|
|
|
|
def Release(fromSource: UInt, toAddress: UInt, lgSize: UInt, shrinkPermissions: UInt, data: UInt) = {
|
2017-01-18 03:52:16 +01:00
|
|
|
require (manager.anySupportAcquireB)
|
|
|
|
val legal = manager.supportsAcquireBFast(toAddress, lgSize)
|
2016-08-27 00:32:20 +02:00
|
|
|
val c = Wire(new TLBundleC(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
c.opcode := TLMessages.ReleaseData
|
|
|
|
c.param := shrinkPermissions
|
|
|
|
c.size := lgSize
|
|
|
|
c.source := fromSource
|
2016-10-14 23:09:39 +02:00
|
|
|
c.address := toAddress
|
2016-08-20 05:28:58 +02:00
|
|
|
c.data := data
|
2016-08-30 23:38:26 +02:00
|
|
|
c.error := Bool(false)
|
2016-08-20 05:28:58 +02:00
|
|
|
(legal, c)
|
|
|
|
}
|
|
|
|
|
2016-11-11 00:56:42 +01:00
|
|
|
def ProbeAck(b: TLBundleB, reportPermissions: UInt): TLBundleC =
|
|
|
|
ProbeAck(b.source, b.address, b.size, reportPermissions)
|
|
|
|
|
|
|
|
def ProbeAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, reportPermissions: UInt): TLBundleC = {
|
2016-08-27 00:32:20 +02:00
|
|
|
val c = Wire(new TLBundleC(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
c.opcode := TLMessages.ProbeAck
|
|
|
|
c.param := reportPermissions
|
|
|
|
c.size := lgSize
|
2016-09-07 08:46:44 +02:00
|
|
|
c.source := fromSource
|
2016-10-14 23:09:39 +02:00
|
|
|
c.address := toAddress
|
2016-08-20 05:28:58 +02:00
|
|
|
c.data := UInt(0)
|
2016-08-30 23:38:26 +02:00
|
|
|
c.error := Bool(false)
|
2016-08-20 05:28:58 +02:00
|
|
|
c
|
|
|
|
}
|
|
|
|
|
2016-11-11 00:56:42 +01:00
|
|
|
def ProbeAck(b: TLBundleB, reportPermissions: UInt, data: UInt): TLBundleC =
|
|
|
|
ProbeAck(b.source, b.address, b.size, reportPermissions, data)
|
|
|
|
|
|
|
|
def ProbeAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, reportPermissions: UInt, data: UInt): TLBundleC = {
|
2016-08-27 00:32:20 +02:00
|
|
|
val c = Wire(new TLBundleC(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
c.opcode := TLMessages.ProbeAckData
|
|
|
|
c.param := reportPermissions
|
|
|
|
c.size := lgSize
|
2016-09-07 08:46:44 +02:00
|
|
|
c.source := fromSource
|
2016-10-14 23:09:39 +02:00
|
|
|
c.address := toAddress
|
2016-08-20 05:28:58 +02:00
|
|
|
c.data := data
|
2016-08-30 23:38:26 +02:00
|
|
|
c.error := Bool(false)
|
2016-08-20 05:28:58 +02:00
|
|
|
c
|
|
|
|
}
|
|
|
|
|
2016-11-11 00:56:42 +01:00
|
|
|
def GrantAck(d: TLBundleD): TLBundleE = GrantAck(d.sink)
|
|
|
|
def GrantAck(toSink: UInt): TLBundleE = {
|
2016-08-27 00:32:20 +02:00
|
|
|
val e = Wire(new TLBundleE(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
e.sink := toSink
|
|
|
|
e
|
|
|
|
}
|
|
|
|
|
|
|
|
// Accesses
|
|
|
|
def Get(fromSource: UInt, toAddress: UInt, lgSize: UInt) = {
|
2016-08-22 22:28:52 +02:00
|
|
|
require (manager.anySupportGet)
|
2016-09-18 02:04:18 +02:00
|
|
|
val legal = manager.supportsGetFast(toAddress, lgSize)
|
2016-08-27 00:32:20 +02:00
|
|
|
val a = Wire(new TLBundleA(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
a.opcode := TLMessages.Get
|
|
|
|
a.param := UInt(0)
|
|
|
|
a.size := lgSize
|
|
|
|
a.source := fromSource
|
2016-10-14 23:09:39 +02:00
|
|
|
a.address := toAddress
|
2016-09-07 08:46:44 +02:00
|
|
|
a.mask := mask(toAddress, lgSize)
|
2016-08-20 05:28:58 +02:00
|
|
|
a.data := UInt(0)
|
|
|
|
(legal, a)
|
|
|
|
}
|
|
|
|
|
|
|
|
def Put(fromSource: UInt, toAddress: UInt, lgSize: UInt, data: UInt) = {
|
2016-08-22 22:28:52 +02:00
|
|
|
require (manager.anySupportPutFull)
|
2016-09-18 02:04:18 +02:00
|
|
|
val legal = manager.supportsPutFullFast(toAddress, lgSize)
|
2016-08-27 00:32:20 +02:00
|
|
|
val a = Wire(new TLBundleA(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
a.opcode := TLMessages.PutFullData
|
|
|
|
a.param := UInt(0)
|
|
|
|
a.size := lgSize
|
|
|
|
a.source := fromSource
|
2016-10-14 23:09:39 +02:00
|
|
|
a.address := toAddress
|
2016-09-07 08:46:44 +02:00
|
|
|
a.mask := mask(toAddress, lgSize)
|
2016-08-20 05:28:58 +02:00
|
|
|
a.data := data
|
|
|
|
(legal, a)
|
|
|
|
}
|
|
|
|
|
2016-08-31 00:06:37 +02:00
|
|
|
def Put(fromSource: UInt, toAddress: UInt, lgSize: UInt, data: UInt, mask : UInt) = {
|
2016-08-22 22:28:52 +02:00
|
|
|
require (manager.anySupportPutPartial)
|
2016-09-18 02:04:18 +02:00
|
|
|
val legal = manager.supportsPutPartialFast(toAddress, lgSize)
|
2016-08-27 00:32:20 +02:00
|
|
|
val a = Wire(new TLBundleA(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
a.opcode := TLMessages.PutPartialData
|
|
|
|
a.param := UInt(0)
|
|
|
|
a.size := lgSize
|
|
|
|
a.source := fromSource
|
2016-10-14 23:09:39 +02:00
|
|
|
a.address := toAddress
|
2016-08-31 00:06:37 +02:00
|
|
|
a.mask := mask
|
2016-08-20 05:28:58 +02:00
|
|
|
a.data := data
|
|
|
|
(legal, a)
|
|
|
|
}
|
|
|
|
|
|
|
|
def Arithmetic(fromSource: UInt, toAddress: UInt, lgSize: UInt, data: UInt, atomic: UInt) = {
|
2016-08-22 22:28:52 +02:00
|
|
|
require (manager.anySupportArithmetic)
|
2016-09-18 02:04:18 +02:00
|
|
|
val legal = manager.supportsArithmeticFast(toAddress, lgSize)
|
2016-08-27 00:32:20 +02:00
|
|
|
val a = Wire(new TLBundleA(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
a.opcode := TLMessages.ArithmeticData
|
|
|
|
a.param := atomic
|
|
|
|
a.size := lgSize
|
|
|
|
a.source := fromSource
|
2016-10-14 23:09:39 +02:00
|
|
|
a.address := toAddress
|
2016-09-07 08:46:44 +02:00
|
|
|
a.mask := mask(toAddress, lgSize)
|
2016-08-20 05:28:58 +02:00
|
|
|
a.data := data
|
|
|
|
(legal, a)
|
|
|
|
}
|
|
|
|
|
|
|
|
def Logical(fromSource: UInt, toAddress: UInt, lgSize: UInt, data: UInt, atomic: UInt) = {
|
2016-08-22 22:28:52 +02:00
|
|
|
require (manager.anySupportLogical)
|
2016-09-18 02:04:18 +02:00
|
|
|
val legal = manager.supportsLogicalFast(toAddress, lgSize)
|
2016-08-27 00:32:20 +02:00
|
|
|
val a = Wire(new TLBundleA(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
a.opcode := TLMessages.LogicalData
|
|
|
|
a.param := atomic
|
|
|
|
a.size := lgSize
|
|
|
|
a.source := fromSource
|
2016-10-14 23:09:39 +02:00
|
|
|
a.address := toAddress
|
2016-09-07 08:46:44 +02:00
|
|
|
a.mask := mask(toAddress, lgSize)
|
2016-08-20 05:28:58 +02:00
|
|
|
a.data := data
|
|
|
|
(legal, a)
|
|
|
|
}
|
|
|
|
|
|
|
|
def Hint(fromSource: UInt, toAddress: UInt, lgSize: UInt, param: UInt) = {
|
2016-08-22 22:28:52 +02:00
|
|
|
require (manager.anySupportHint)
|
2016-09-18 02:04:18 +02:00
|
|
|
val legal = manager.supportsHintFast(toAddress, lgSize)
|
2016-08-27 00:32:20 +02:00
|
|
|
val a = Wire(new TLBundleA(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
a.opcode := TLMessages.Hint
|
|
|
|
a.param := param
|
|
|
|
a.size := lgSize
|
|
|
|
a.source := fromSource
|
2016-10-14 23:09:39 +02:00
|
|
|
a.address := toAddress
|
2016-09-07 08:46:44 +02:00
|
|
|
a.mask := mask(toAddress, lgSize)
|
2016-08-20 05:28:58 +02:00
|
|
|
a.data := UInt(0)
|
|
|
|
(legal, a)
|
|
|
|
}
|
|
|
|
|
2016-09-07 08:46:44 +02:00
|
|
|
def AccessAck(b: TLBundleB): TLBundleC = AccessAck(b.source, address(b), b.size)
|
|
|
|
def AccessAck(b: TLBundleB, error: Bool): TLBundleC = AccessAck(b.source, address(b), b.size, error)
|
|
|
|
def AccessAck(fromSource: UInt, toAddress: UInt, lgSize: UInt): TLBundleC = AccessAck(fromSource, toAddress, lgSize, Bool(false))
|
|
|
|
def AccessAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, error: Bool) = {
|
2016-08-27 00:32:20 +02:00
|
|
|
val c = Wire(new TLBundleC(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
c.opcode := TLMessages.AccessAck
|
|
|
|
c.param := UInt(0)
|
|
|
|
c.size := lgSize
|
2016-09-07 08:46:44 +02:00
|
|
|
c.source := fromSource
|
2016-10-14 23:09:39 +02:00
|
|
|
c.address := toAddress
|
2016-08-20 05:28:58 +02:00
|
|
|
c.data := UInt(0)
|
2016-08-30 23:38:26 +02:00
|
|
|
c.error := error
|
2016-08-23 00:36:39 +02:00
|
|
|
c
|
|
|
|
}
|
|
|
|
|
2016-09-07 08:46:44 +02:00
|
|
|
def AccessAck(b: TLBundleB, data: UInt): TLBundleC = AccessAck(b.source, address(b), b.size, data)
|
|
|
|
def AccessAck(b: TLBundleB, data: UInt, error: Bool): TLBundleC = AccessAck(b.source, address(b), b.size, data, error)
|
|
|
|
def AccessAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, data: UInt): TLBundleC = AccessAck(fromSource, toAddress, lgSize, data, Bool(false))
|
|
|
|
def AccessAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, data: UInt, error: Bool) = {
|
2016-08-27 00:32:20 +02:00
|
|
|
val c = Wire(new TLBundleC(bundle))
|
2016-08-30 23:38:26 +02:00
|
|
|
c.opcode := TLMessages.AccessAckData
|
2016-08-23 00:36:39 +02:00
|
|
|
c.param := UInt(0)
|
|
|
|
c.size := lgSize
|
2016-09-07 08:46:44 +02:00
|
|
|
c.source := fromSource
|
2016-10-14 23:09:39 +02:00
|
|
|
c.address := toAddress
|
2016-08-30 23:38:26 +02:00
|
|
|
c.data := data
|
|
|
|
c.error := error
|
2016-08-20 05:28:58 +02:00
|
|
|
c
|
|
|
|
}
|
|
|
|
|
2016-09-07 08:46:44 +02:00
|
|
|
def HintAck(b: TLBundleB): TLBundleC = HintAck(b.source, address(b), b.size)
|
|
|
|
def HintAck(fromSource: UInt, toAddress: UInt, lgSize: UInt) = {
|
2016-08-27 00:32:20 +02:00
|
|
|
val c = Wire(new TLBundleC(bundle))
|
2016-08-30 23:38:26 +02:00
|
|
|
c.opcode := TLMessages.HintAck
|
2016-08-20 05:28:58 +02:00
|
|
|
c.param := UInt(0)
|
|
|
|
c.size := lgSize
|
2016-09-07 08:46:44 +02:00
|
|
|
c.source := fromSource
|
2016-10-14 23:09:39 +02:00
|
|
|
c.address := toAddress
|
2016-08-30 23:38:26 +02:00
|
|
|
c.data := UInt(0)
|
|
|
|
c.error := Bool(false)
|
2016-08-20 05:28:58 +02:00
|
|
|
c
|
|
|
|
}
|
2016-08-19 20:08:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
class TLEdgeIn(
|
|
|
|
client: TLClientPortParameters,
|
|
|
|
manager: TLManagerPortParameters)
|
2016-08-24 01:23:35 +02:00
|
|
|
extends TLEdge(client, manager)
|
2016-08-19 20:08:35 +02:00
|
|
|
{
|
|
|
|
// Transfers
|
2016-08-20 05:28:58 +02:00
|
|
|
def Probe(fromAddress: UInt, toSource: UInt, lgSize: UInt, capPermissions: UInt) = {
|
2016-08-22 22:28:52 +02:00
|
|
|
require (client.anySupportProbe)
|
2016-09-18 02:04:18 +02:00
|
|
|
val legal = client.supportsProbe(toSource, lgSize)
|
2016-08-27 00:32:20 +02:00
|
|
|
val b = Wire(new TLBundleB(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
b.opcode := TLMessages.Probe
|
|
|
|
b.param := capPermissions
|
|
|
|
b.size := lgSize
|
|
|
|
b.source := toSource
|
2016-10-14 23:09:39 +02:00
|
|
|
b.address := fromAddress
|
2016-11-12 03:34:48 +01:00
|
|
|
b.mask := mask(fromAddress, lgSize)
|
2016-08-20 05:28:58 +02:00
|
|
|
b.data := UInt(0)
|
|
|
|
(legal, b)
|
|
|
|
}
|
|
|
|
|
2016-09-07 08:46:44 +02:00
|
|
|
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) = {
|
2016-08-27 00:32:20 +02:00
|
|
|
val d = Wire(new TLBundleD(bundle))
|
2016-09-07 08:46:44 +02:00
|
|
|
d.opcode := TLMessages.Grant
|
|
|
|
d.param := capPermissions
|
|
|
|
d.size := lgSize
|
|
|
|
d.source := toSource
|
|
|
|
d.sink := fromSink
|
2016-09-27 02:00:03 +02:00
|
|
|
d.addr_lo := addr_lo(fromAddress)
|
2016-09-07 08:46:44 +02:00
|
|
|
d.data := UInt(0)
|
|
|
|
d.error := error
|
2016-08-20 05:28:58 +02:00
|
|
|
d
|
|
|
|
}
|
|
|
|
|
2016-09-07 08:46:44 +02:00
|
|
|
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) = {
|
2016-08-27 00:32:20 +02:00
|
|
|
val d = Wire(new TLBundleD(bundle))
|
2016-09-07 08:46:44 +02:00
|
|
|
d.opcode := TLMessages.GrantData
|
|
|
|
d.param := capPermissions
|
|
|
|
d.size := lgSize
|
|
|
|
d.source := toSource
|
|
|
|
d.sink := fromSink
|
2016-09-27 02:00:03 +02:00
|
|
|
d.addr_lo := addr_lo(fromAddress)
|
2016-09-07 08:46:44 +02:00
|
|
|
d.data := data
|
|
|
|
d.error := error
|
2016-08-20 05:28:58 +02:00
|
|
|
d
|
|
|
|
}
|
|
|
|
|
2016-09-07 08:46:44 +02:00
|
|
|
def ReleaseAck(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt) = {
|
2016-08-27 00:32:20 +02:00
|
|
|
val d = Wire(new TLBundleD(bundle))
|
2016-09-07 08:46:44 +02:00
|
|
|
d.opcode := TLMessages.ReleaseAck
|
|
|
|
d.param := UInt(0)
|
|
|
|
d.size := lgSize
|
|
|
|
d.source := toSource
|
|
|
|
d.sink := fromSink
|
2016-09-27 02:00:03 +02:00
|
|
|
d.addr_lo := addr_lo(fromAddress)
|
2016-09-07 08:46:44 +02:00
|
|
|
d.data := UInt(0)
|
|
|
|
d.error := Bool(false)
|
2016-08-20 05:28:58 +02:00
|
|
|
d
|
|
|
|
}
|
|
|
|
|
|
|
|
// Accesses
|
|
|
|
def Get(fromAddress: UInt, toSource: UInt, lgSize: UInt) = {
|
2016-08-22 22:28:52 +02:00
|
|
|
require (client.anySupportGet)
|
2016-08-20 05:28:58 +02:00
|
|
|
val legal = client.supportsGet(toSource, lgSize)
|
2016-08-27 00:32:20 +02:00
|
|
|
val b = Wire(new TLBundleB(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
b.opcode := TLMessages.Get
|
|
|
|
b.param := UInt(0)
|
|
|
|
b.size := lgSize
|
|
|
|
b.source := toSource
|
2016-10-14 23:09:39 +02:00
|
|
|
b.address := fromAddress
|
2016-09-07 08:46:44 +02:00
|
|
|
b.mask := mask(fromAddress, lgSize)
|
2016-08-20 05:28:58 +02:00
|
|
|
b.data := UInt(0)
|
|
|
|
(legal, b)
|
|
|
|
}
|
|
|
|
|
|
|
|
def Put(fromAddress: UInt, toSource: UInt, lgSize: UInt, data: UInt) = {
|
2016-08-22 22:28:52 +02:00
|
|
|
require (client.anySupportPutFull)
|
2016-08-20 05:28:58 +02:00
|
|
|
val legal = client.supportsPutFull(toSource, lgSize)
|
2016-08-27 00:32:20 +02:00
|
|
|
val b = Wire(new TLBundleB(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
b.opcode := TLMessages.PutFullData
|
|
|
|
b.param := UInt(0)
|
|
|
|
b.size := lgSize
|
|
|
|
b.source := toSource
|
2016-10-14 23:09:39 +02:00
|
|
|
b.address := fromAddress
|
2016-09-07 08:46:44 +02:00
|
|
|
b.mask := mask(fromAddress, lgSize)
|
2016-08-20 05:28:58 +02:00
|
|
|
b.data := data
|
|
|
|
(legal, b)
|
|
|
|
}
|
|
|
|
|
2016-08-31 00:06:37 +02:00
|
|
|
def Put(fromAddress: UInt, toSource: UInt, lgSize: UInt, data: UInt, mask : UInt) = {
|
2016-08-22 22:28:52 +02:00
|
|
|
require (client.anySupportPutPartial)
|
2016-08-20 05:28:58 +02:00
|
|
|
val legal = client.supportsPutPartial(toSource, lgSize)
|
2016-08-27 00:32:20 +02:00
|
|
|
val b = Wire(new TLBundleB(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
b.opcode := TLMessages.PutPartialData
|
|
|
|
b.param := UInt(0)
|
|
|
|
b.size := lgSize
|
|
|
|
b.source := toSource
|
2016-10-14 23:09:39 +02:00
|
|
|
b.address := fromAddress
|
2016-08-31 00:06:37 +02:00
|
|
|
b.mask := mask
|
2016-08-20 05:28:58 +02:00
|
|
|
b.data := data
|
|
|
|
(legal, b)
|
|
|
|
}
|
|
|
|
|
|
|
|
def Arithmetic(fromAddress: UInt, toSource: UInt, lgSize: UInt, data: UInt, atomic: UInt) = {
|
2016-08-22 22:28:52 +02:00
|
|
|
require (client.anySupportArithmetic)
|
2016-08-20 05:28:58 +02:00
|
|
|
val legal = client.supportsArithmetic(toSource, lgSize)
|
2016-08-27 00:32:20 +02:00
|
|
|
val b = Wire(new TLBundleB(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
b.opcode := TLMessages.ArithmeticData
|
|
|
|
b.param := atomic
|
|
|
|
b.size := lgSize
|
|
|
|
b.source := toSource
|
2016-10-14 23:09:39 +02:00
|
|
|
b.address := fromAddress
|
2016-09-07 08:46:44 +02:00
|
|
|
b.mask := mask(fromAddress, lgSize)
|
2016-08-20 05:28:58 +02:00
|
|
|
b.data := data
|
|
|
|
(legal, b)
|
|
|
|
}
|
|
|
|
|
|
|
|
def Logical(fromAddress: UInt, toSource: UInt, lgSize: UInt, data: UInt, atomic: UInt) = {
|
2016-08-22 22:28:52 +02:00
|
|
|
require (client.anySupportLogical)
|
2016-08-20 05:28:58 +02:00
|
|
|
val legal = client.supportsLogical(toSource, lgSize)
|
2016-08-27 00:32:20 +02:00
|
|
|
val b = Wire(new TLBundleB(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
b.opcode := TLMessages.LogicalData
|
|
|
|
b.param := atomic
|
|
|
|
b.size := lgSize
|
|
|
|
b.source := toSource
|
2016-10-14 23:09:39 +02:00
|
|
|
b.address := fromAddress
|
2016-09-07 08:46:44 +02:00
|
|
|
b.mask := mask(fromAddress, lgSize)
|
2016-08-20 05:28:58 +02:00
|
|
|
b.data := data
|
|
|
|
(legal, b)
|
|
|
|
}
|
|
|
|
|
|
|
|
def Hint(fromAddress: UInt, toSource: UInt, lgSize: UInt, param: UInt) = {
|
2016-08-22 22:28:52 +02:00
|
|
|
require (client.anySupportHint)
|
2016-09-13 02:15:28 +02:00
|
|
|
val legal = client.supportsHint(toSource, lgSize)
|
2016-08-27 00:32:20 +02:00
|
|
|
val b = Wire(new TLBundleB(bundle))
|
2016-08-20 05:28:58 +02:00
|
|
|
b.opcode := TLMessages.Hint
|
|
|
|
b.param := param
|
|
|
|
b.size := lgSize
|
|
|
|
b.source := toSource
|
2016-10-14 23:09:39 +02:00
|
|
|
b.address := fromAddress
|
2016-09-07 08:46:44 +02:00
|
|
|
b.mask := mask(fromAddress, lgSize)
|
2016-08-20 05:28:58 +02:00
|
|
|
b.data := UInt(0)
|
|
|
|
(legal, b)
|
|
|
|
}
|
|
|
|
|
2016-09-07 08:46:44 +02:00
|
|
|
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) = {
|
2016-08-27 00:32:20 +02:00
|
|
|
val d = Wire(new TLBundleD(bundle))
|
2016-09-07 08:46:44 +02:00
|
|
|
d.opcode := TLMessages.AccessAck
|
|
|
|
d.param := UInt(0)
|
|
|
|
d.size := lgSize
|
|
|
|
d.source := toSource
|
|
|
|
d.sink := fromSink
|
2016-09-27 02:00:03 +02:00
|
|
|
d.addr_lo := addr_lo(fromAddress)
|
2016-09-07 08:46:44 +02:00
|
|
|
d.data := UInt(0)
|
|
|
|
d.error := error
|
2016-08-23 00:36:39 +02:00
|
|
|
d
|
|
|
|
}
|
|
|
|
|
2016-09-07 08:46:44 +02:00
|
|
|
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) = {
|
2016-08-27 00:32:20 +02:00
|
|
|
val d = Wire(new TLBundleD(bundle))
|
2016-09-07 08:46:44 +02:00
|
|
|
d.opcode := TLMessages.AccessAckData
|
|
|
|
d.param := UInt(0)
|
|
|
|
d.size := lgSize
|
|
|
|
d.source := toSource
|
|
|
|
d.sink := fromSink
|
2016-09-27 02:00:03 +02:00
|
|
|
d.addr_lo := addr_lo(fromAddress)
|
2016-09-07 08:46:44 +02:00
|
|
|
d.data := data
|
|
|
|
d.error := error
|
2016-08-20 05:28:58 +02:00
|
|
|
d
|
|
|
|
}
|
|
|
|
|
2016-09-13 02:26:40 +02:00
|
|
|
def HintAck(a: TLBundleA, fromSink: UInt): TLBundleD = HintAck(address(a), fromSink, a.source, a.size)
|
2016-09-07 08:46:44 +02:00
|
|
|
def HintAck(fromAddress: UInt, fromSink: UInt, toSource: UInt, lgSize: UInt) = {
|
2016-08-27 00:32:20 +02:00
|
|
|
val d = Wire(new TLBundleD(bundle))
|
2016-09-07 08:46:44 +02:00
|
|
|
d.opcode := TLMessages.HintAck
|
|
|
|
d.param := UInt(0)
|
|
|
|
d.size := lgSize
|
|
|
|
d.source := toSource
|
|
|
|
d.sink := fromSink
|
2016-09-27 02:00:03 +02:00
|
|
|
d.addr_lo := addr_lo(fromAddress)
|
2016-09-07 08:46:44 +02:00
|
|
|
d.data := UInt(0)
|
|
|
|
d.error := Bool(false)
|
2016-08-20 05:28:58 +02:00
|
|
|
d
|
|
|
|
}
|
2016-08-19 20:08:35 +02:00
|
|
|
}
|