2016-08-19 20:08:35 +02:00
|
|
|
// See LICENSE for license details.
|
|
|
|
|
|
|
|
package uncore.tilelink2
|
|
|
|
|
2016-09-27 23:44:26 +02:00
|
|
|
import Chisel._
|
2016-10-13 03:09:01 +02:00
|
|
|
import chisel3.util.{ReadyValidIO}
|
2016-10-04 00:17:36 +02:00
|
|
|
import diplomacy._
|
|
|
|
import util.{AsyncQueueSource, AsyncQueueSink, GenericParameterizedBundle}
|
2016-08-19 20:08:35 +02:00
|
|
|
|
2016-08-30 02:02:04 +02:00
|
|
|
abstract class TLBundleBase(params: TLBundleParameters) extends GenericParameterizedBundle(params)
|
|
|
|
|
2016-08-24 01:23:35 +02:00
|
|
|
// common combos in lazy policy:
|
|
|
|
// Put + Acquire
|
|
|
|
// Release + AccessAck
|
|
|
|
|
2016-08-20 00:25:51 +02:00
|
|
|
object TLMessages
|
|
|
|
{
|
|
|
|
// A B C D E
|
2016-08-30 23:43:07 +02:00
|
|
|
val PutFullData = UInt(0) // . . => AccessAck
|
|
|
|
val PutPartialData = UInt(1) // . . => AccessAck
|
|
|
|
val ArithmeticData = UInt(2) // . . => AccessAckData
|
|
|
|
val LogicalData = UInt(3) // . . => AccessAckData
|
|
|
|
val Get = UInt(4) // . . => AccessAckData
|
|
|
|
val Hint = UInt(5) // . . => HintAck
|
|
|
|
val Acquire = UInt(6) // . => Grant[Data]
|
|
|
|
val Probe = UInt(6) // . => ProbeAck[Data]
|
2016-08-30 23:38:26 +02:00
|
|
|
val AccessAck = UInt(0) // . .
|
|
|
|
val AccessAckData = UInt(1) // . .
|
|
|
|
val HintAck = UInt(2) // . .
|
|
|
|
//val PutThroughData = UInt(3) // . // future extension ?
|
|
|
|
val ProbeAck = UInt(4) // .
|
|
|
|
val ProbeAckData = UInt(5) // .
|
2016-08-30 23:43:07 +02:00
|
|
|
val Release = UInt(6) // . => ReleaseAck
|
|
|
|
val ReleaseData = UInt(7) // . => ReleaseAck
|
|
|
|
val Grant = UInt(4) // . => GrantAck
|
|
|
|
val GrantData = UInt(5) // . => GrantAck
|
2016-08-30 23:38:26 +02:00
|
|
|
val ReleaseAck = UInt(6) // .
|
2016-08-20 00:25:51 +02:00
|
|
|
val GrantAck = UInt(0) // .
|
2016-08-23 00:36:39 +02:00
|
|
|
|
|
|
|
def isA(x: UInt) = x <= Acquire
|
|
|
|
def isB(x: UInt) = x <= Probe
|
|
|
|
def isC(x: UInt) = x <= ReleaseData
|
2016-08-30 23:38:26 +02:00
|
|
|
def isD(x: UInt) = x <= ReleaseAck
|
2016-08-20 00:25:51 +02:00
|
|
|
}
|
|
|
|
|
2016-11-11 00:56:42 +01:00
|
|
|
/**
|
|
|
|
* The three primary TileLink permissions are:
|
|
|
|
* (T)runk: the agent is (or is on the path to) the global point of serialization.
|
|
|
|
* (B)ranch: the agent
|
|
|
|
* (N)one:
|
|
|
|
* These permissions are permuted by transfer operations in various ways.
|
|
|
|
* Messages for
|
|
|
|
*/
|
2016-08-20 00:25:51 +02:00
|
|
|
object TLPermissions
|
|
|
|
{
|
|
|
|
// Cap types (Grant = new permissions, Probe = permisions <= target)
|
|
|
|
val toT = UInt(0)
|
|
|
|
val toB = UInt(1)
|
|
|
|
val toN = UInt(2)
|
2016-08-23 00:36:39 +02:00
|
|
|
def isCap(x: UInt) = x <= toN
|
2016-08-20 00:25:51 +02:00
|
|
|
|
|
|
|
// Grow types (Acquire = permissions >= target)
|
|
|
|
val NtoB = UInt(0)
|
|
|
|
val NtoT = UInt(1)
|
|
|
|
val BtoT = UInt(2)
|
2016-08-23 00:36:39 +02:00
|
|
|
def isGrow(x: UInt) = x <= BtoT
|
2016-08-20 00:25:51 +02:00
|
|
|
|
|
|
|
// Shrink types (ProbeAck, Release)
|
|
|
|
val TtoB = UInt(0)
|
|
|
|
val TtoN = UInt(1)
|
|
|
|
val BtoN = UInt(2)
|
2016-08-23 00:36:39 +02:00
|
|
|
def isShrink(x: UInt) = x <= BtoN
|
2016-08-20 00:25:51 +02:00
|
|
|
|
|
|
|
// Report types (ProbeAck)
|
|
|
|
val TtoT = UInt(3)
|
|
|
|
val BtoB = UInt(4)
|
|
|
|
val NtoN = UInt(5)
|
2016-08-23 00:36:39 +02:00
|
|
|
def isReport(x: UInt) = x <= NtoN
|
2016-08-20 00:25:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
object TLAtomics
|
|
|
|
{
|
2016-08-23 00:36:39 +02:00
|
|
|
// Arithmetic types
|
2016-08-30 19:40:14 +02:00
|
|
|
val MIN = UInt(0)
|
|
|
|
val MAX = UInt(1)
|
|
|
|
val MINU = UInt(2)
|
|
|
|
val MAXU = UInt(3)
|
|
|
|
val ADD = UInt(4)
|
|
|
|
def isArithmetic(x: UInt) = x <= ADD
|
2016-08-23 00:36:39 +02:00
|
|
|
|
|
|
|
// Logical types
|
2016-08-30 19:40:14 +02:00
|
|
|
val XOR = UInt(0)
|
|
|
|
val OR = UInt(1)
|
|
|
|
val AND = UInt(2)
|
|
|
|
val SWAP = UInt(3)
|
|
|
|
def isLogical(x: UInt) = x <= SWAP
|
2016-08-20 00:25:51 +02:00
|
|
|
}
|
|
|
|
|
2016-11-03 05:37:30 +01:00
|
|
|
object TLHints
|
|
|
|
{
|
|
|
|
val PREFETCH_READ = UInt(0)
|
|
|
|
val PREFETCH_WRITE = UInt(1)
|
|
|
|
}
|
|
|
|
|
2016-09-15 02:43:07 +02:00
|
|
|
sealed trait TLChannel extends TLBundleBase {
|
|
|
|
val channelName: String
|
|
|
|
}
|
2016-09-07 08:46:44 +02:00
|
|
|
sealed trait TLDataChannel extends TLChannel
|
|
|
|
sealed trait TLAddrChannel extends TLDataChannel
|
2016-08-24 01:23:35 +02:00
|
|
|
|
2016-09-07 08:46:44 +02:00
|
|
|
final class TLBundleA(params: TLBundleParameters)
|
|
|
|
extends TLBundleBase(params) with TLAddrChannel
|
2016-08-19 20:08:35 +02:00
|
|
|
{
|
2016-09-15 02:43:07 +02:00
|
|
|
val channelName = "'A' channel"
|
2016-09-01 20:34:56 +02:00
|
|
|
// fixed fields during multibeat:
|
2016-08-19 20:08:35 +02:00
|
|
|
val opcode = UInt(width = 3)
|
2016-08-20 03:39:21 +02:00
|
|
|
val param = UInt(width = 3) // amo_opcode || perms || hint
|
2016-08-19 20:08:35 +02:00
|
|
|
val size = UInt(width = params.sizeBits)
|
2016-09-07 08:46:44 +02:00
|
|
|
val source = UInt(width = params.sourceBits) // from
|
2016-10-14 23:09:39 +02:00
|
|
|
val address = UInt(width = params.addressBits) // to
|
2016-09-01 20:34:56 +02:00
|
|
|
// variable fields during multibeat:
|
2016-08-31 00:06:37 +02:00
|
|
|
val mask = UInt(width = params.dataBits/8)
|
2016-08-19 20:08:35 +02:00
|
|
|
val data = UInt(width = params.dataBits)
|
|
|
|
}
|
|
|
|
|
2016-09-07 08:46:44 +02:00
|
|
|
final class TLBundleB(params: TLBundleParameters)
|
|
|
|
extends TLBundleBase(params) with TLAddrChannel
|
2016-08-19 20:08:35 +02:00
|
|
|
{
|
2016-09-15 02:43:07 +02:00
|
|
|
val channelName = "'B' channel"
|
2016-09-01 20:34:56 +02:00
|
|
|
// fixed fields during multibeat:
|
2016-08-19 20:08:35 +02:00
|
|
|
val opcode = UInt(width = 3)
|
2016-08-20 03:39:21 +02:00
|
|
|
val param = UInt(width = 3)
|
2016-08-19 20:08:35 +02:00
|
|
|
val size = UInt(width = params.sizeBits)
|
2016-09-07 08:46:44 +02:00
|
|
|
val source = UInt(width = params.sourceBits) // to
|
2016-10-14 23:09:39 +02:00
|
|
|
val address = UInt(width = params.addressBits) // from
|
2016-09-01 20:34:56 +02:00
|
|
|
// variable fields during multibeat:
|
2016-08-31 00:06:37 +02:00
|
|
|
val mask = UInt(width = params.dataBits/8)
|
2016-08-19 20:08:35 +02:00
|
|
|
val data = UInt(width = params.dataBits)
|
|
|
|
}
|
|
|
|
|
2016-09-07 08:46:44 +02:00
|
|
|
final class TLBundleC(params: TLBundleParameters)
|
|
|
|
extends TLBundleBase(params) with TLAddrChannel
|
2016-08-19 20:08:35 +02:00
|
|
|
{
|
2016-09-15 02:43:07 +02:00
|
|
|
val channelName = "'C' channel"
|
2016-09-01 20:34:56 +02:00
|
|
|
// fixed fields during multibeat:
|
2016-08-19 20:08:35 +02:00
|
|
|
val opcode = UInt(width = 3)
|
2016-08-20 00:25:51 +02:00
|
|
|
val param = UInt(width = 3)
|
2016-08-19 20:08:35 +02:00
|
|
|
val size = UInt(width = params.sizeBits)
|
2016-09-07 08:46:44 +02:00
|
|
|
val source = UInt(width = params.sourceBits) // from
|
2016-10-14 23:09:39 +02:00
|
|
|
val address = UInt(width = params.addressBits) // to
|
2016-09-01 20:34:56 +02:00
|
|
|
// variable fields during multibeat:
|
2016-08-19 20:08:35 +02:00
|
|
|
val data = UInt(width = params.dataBits)
|
2016-08-30 23:38:26 +02:00
|
|
|
val error = Bool() // AccessAck[Data]
|
2016-08-19 20:08:35 +02:00
|
|
|
}
|
|
|
|
|
2016-09-07 08:46:44 +02:00
|
|
|
final class TLBundleD(params: TLBundleParameters)
|
|
|
|
extends TLBundleBase(params) with TLDataChannel
|
2016-08-19 20:08:35 +02:00
|
|
|
{
|
2016-09-15 02:43:07 +02:00
|
|
|
val channelName = "'D' channel"
|
2016-09-01 20:34:56 +02:00
|
|
|
// fixed fields during multibeat:
|
2016-09-07 08:46:44 +02:00
|
|
|
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
|
|
|
|
val addr_lo = UInt(width = params.addrLoBits) // instead of mask
|
2016-09-01 20:34:56 +02:00
|
|
|
// variable fields during multibeat:
|
2016-09-07 08:46:44 +02:00
|
|
|
val data = UInt(width = params.dataBits)
|
|
|
|
val error = Bool() // AccessAck[Data], Grant[Data]
|
2016-08-19 20:08:35 +02:00
|
|
|
}
|
|
|
|
|
2016-09-07 08:46:44 +02:00
|
|
|
final class TLBundleE(params: TLBundleParameters)
|
|
|
|
extends TLBundleBase(params) with TLChannel
|
2016-08-19 20:08:35 +02:00
|
|
|
{
|
2016-09-15 02:43:07 +02:00
|
|
|
val channelName = "'E' channel"
|
2016-09-08 21:14:55 +02:00
|
|
|
val sink = UInt(width = params.sinkBits) // to
|
2016-08-19 20:08:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
class TLBundle(params: TLBundleParameters) extends TLBundleBase(params)
|
|
|
|
{
|
2016-10-13 03:09:01 +02:00
|
|
|
val a = Decoupled(new TLBundleA(params))
|
|
|
|
val b = Decoupled(new TLBundleB(params)).flip
|
|
|
|
val c = Decoupled(new TLBundleC(params))
|
|
|
|
val d = Decoupled(new TLBundleD(params)).flip
|
|
|
|
val e = Decoupled(new TLBundleE(params))
|
2016-08-19 20:08:35 +02:00
|
|
|
}
|
2016-08-24 22:50:11 +02:00
|
|
|
|
|
|
|
object TLBundle
|
|
|
|
{
|
|
|
|
def apply(params: TLBundleParameters) = new TLBundle(params)
|
|
|
|
}
|
2016-09-21 21:04:52 +02:00
|
|
|
|
2016-10-13 03:09:01 +02:00
|
|
|
final class DecoupledSnoop[+T <: Data](gen: T) extends Bundle
|
2016-09-21 21:04:52 +02:00
|
|
|
{
|
|
|
|
val ready = Bool()
|
|
|
|
val valid = Bool()
|
|
|
|
val bits = gen.asOutput
|
|
|
|
|
|
|
|
def fire(dummy: Int = 0) = ready && valid
|
2016-10-13 03:09:01 +02:00
|
|
|
override def cloneType: this.type = new DecoupledSnoop(gen).asInstanceOf[this.type]
|
2016-09-21 21:04:52 +02:00
|
|
|
}
|
|
|
|
|
2016-10-13 03:09:01 +02:00
|
|
|
object DecoupledSnoop
|
2016-09-21 21:04:52 +02:00
|
|
|
{
|
2016-10-13 03:09:01 +02:00
|
|
|
def apply[T <: Data](i: DecoupledIO[T]) = {
|
|
|
|
val out = Wire(new DecoupledSnoop(i.bits))
|
2016-09-21 21:04:52 +02:00
|
|
|
out.ready := i.ready
|
|
|
|
out.valid := i.valid
|
|
|
|
out.bits := i.bits
|
|
|
|
out
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
class TLBundleSnoop(params: TLBundleParameters) extends TLBundleBase(params)
|
|
|
|
{
|
2016-10-13 03:09:01 +02:00
|
|
|
val a = new DecoupledSnoop(new TLBundleA(params))
|
|
|
|
val b = new DecoupledSnoop(new TLBundleB(params))
|
|
|
|
val c = new DecoupledSnoop(new TLBundleC(params))
|
|
|
|
val d = new DecoupledSnoop(new TLBundleD(params))
|
|
|
|
val e = new DecoupledSnoop(new TLBundleE(params))
|
2016-09-21 21:04:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
object TLBundleSnoop
|
|
|
|
{
|
|
|
|
def apply(x: TLBundle) = {
|
|
|
|
val out = Wire(new TLBundleSnoop(x.params))
|
2016-10-13 03:09:01 +02:00
|
|
|
out.a <> DecoupledSnoop(x.a)
|
|
|
|
out.b <> DecoupledSnoop(x.b)
|
|
|
|
out.c <> DecoupledSnoop(x.c)
|
|
|
|
out.d <> DecoupledSnoop(x.d)
|
|
|
|
out.e <> DecoupledSnoop(x.e)
|
2016-09-21 21:04:52 +02:00
|
|
|
out
|
|
|
|
}
|
|
|
|
}
|
2016-09-30 00:34:21 +02:00
|
|
|
|
2016-09-30 02:12:13 +02:00
|
|
|
final class AsyncBundle[T <: Data](val depth: Int, gen: T) extends Bundle
|
2016-09-30 00:34:21 +02:00
|
|
|
{
|
|
|
|
require (isPow2(depth))
|
2016-10-15 03:05:35 +02:00
|
|
|
val mem = Vec(depth, gen)
|
2016-09-30 00:34:21 +02:00
|
|
|
val ridx = UInt(width = log2Up(depth)+1).flip
|
|
|
|
val widx = UInt(width = log2Up(depth)+1)
|
2016-10-15 03:05:35 +02:00
|
|
|
val ridx_valid = Bool().flip
|
|
|
|
val widx_valid = Bool()
|
2016-10-07 05:27:34 +02:00
|
|
|
val source_reset_n = Bool()
|
|
|
|
val sink_reset_n = Bool().flip
|
|
|
|
|
2016-09-30 00:34:21 +02:00
|
|
|
override def cloneType: this.type = new AsyncBundle(depth, gen).asInstanceOf[this.type]
|
|
|
|
}
|
|
|
|
|
2016-09-30 02:12:13 +02:00
|
|
|
object FromAsyncBundle
|
|
|
|
{
|
2016-10-13 03:09:01 +02:00
|
|
|
def apply[T <: Data](x: AsyncBundle[T], sync: Int = 3): DecoupledIO[T] = {
|
2016-09-30 02:12:13 +02:00
|
|
|
val sink = Module(new AsyncQueueSink(x.mem(0), x.depth, sync))
|
|
|
|
x.ridx := sink.io.ridx
|
2016-10-15 03:05:35 +02:00
|
|
|
x.ridx_valid := sink.io.ridx_valid
|
2016-09-30 02:12:13 +02:00
|
|
|
sink.io.widx := x.widx
|
2016-10-15 03:05:35 +02:00
|
|
|
sink.io.widx_valid := x.widx_valid
|
2016-09-30 02:12:13 +02:00
|
|
|
sink.io.mem := x.mem
|
2016-10-07 05:27:34 +02:00
|
|
|
sink.io.source_reset_n := x.source_reset_n
|
|
|
|
x.sink_reset_n := !sink.reset
|
2016-10-13 03:09:01 +02:00
|
|
|
val out = Wire(Decoupled(x.mem(0)))
|
2016-09-30 02:12:13 +02:00
|
|
|
out.valid := sink.io.deq.valid
|
|
|
|
out.bits := sink.io.deq.bits
|
|
|
|
sink.io.deq.ready := out.ready
|
|
|
|
out
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
object ToAsyncBundle
|
|
|
|
{
|
|
|
|
def apply[T <: Data](x: ReadyValidIO[T], depth: Int = 8, sync: Int = 3): AsyncBundle[T] = {
|
|
|
|
val source = Module(new AsyncQueueSource(x.bits, depth, sync))
|
|
|
|
source.io.enq.valid := x.valid
|
|
|
|
source.io.enq.bits := x.bits
|
|
|
|
x.ready := source.io.enq.ready
|
|
|
|
val out = Wire(new AsyncBundle(depth, x.bits))
|
|
|
|
source.io.ridx := out.ridx
|
2016-10-15 03:05:35 +02:00
|
|
|
source.io.ridx_valid := out.ridx_valid
|
2016-09-30 02:12:13 +02:00
|
|
|
out.mem := source.io.mem
|
|
|
|
out.widx := source.io.widx
|
2016-10-15 03:05:35 +02:00
|
|
|
out.widx_valid := source.io.widx_valid
|
2016-10-07 05:27:34 +02:00
|
|
|
source.io.sink_reset_n := out.sink_reset_n
|
|
|
|
out.source_reset_n := !source.reset
|
2016-09-30 02:12:13 +02:00
|
|
|
out
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-30 00:34:21 +02:00
|
|
|
class TLAsyncBundleBase(params: TLAsyncBundleParameters) extends GenericParameterizedBundle(params)
|
|
|
|
|
|
|
|
class TLAsyncBundle(params: TLAsyncBundleParameters) extends TLAsyncBundleBase(params)
|
|
|
|
{
|
|
|
|
val a = new AsyncBundle(params.depth, new TLBundleA(params.base))
|
|
|
|
val b = new AsyncBundle(params.depth, new TLBundleB(params.base)).flip
|
|
|
|
val c = new AsyncBundle(params.depth, new TLBundleC(params.base))
|
|
|
|
val d = new AsyncBundle(params.depth, new TLBundleD(params.base)).flip
|
|
|
|
val e = new AsyncBundle(params.depth, new TLBundleE(params.base))
|
|
|
|
}
|