1
0

axi4: diplomacy capable AXI4

This commit is contained in:
Wesley W. Terpstra 2016-10-04 17:52:15 -07:00
parent dcb9383568
commit b29d34038e
5 changed files with 270 additions and 0 deletions

View File

@ -0,0 +1,68 @@
// See LICENSE for license details.
package uncore.axi4
import Chisel._
import chisel3.util.Irrevocable
import util.GenericParameterizedBundle
abstract class AXI4BundleBase(params: AXI4BundleParameters) extends GenericParameterizedBundle(params)
abstract class AXI4BundleA(params: AXI4BundleParameters) extends AXI4BundleBase(params)
{
val id = UInt(width = params.idBits)
val addr = UInt(width = params.addrBits)
val len = UInt(width = params.lenBits) // number of beats - 1
val size = UInt(width = params.sizeBits) // bytes in beat = 2^size
val burst = UInt(width = params.burstBits)
val lock = UInt(width = params.lockBits)
val cache = UInt(width = params.cacheBits)
val prot = UInt(width = params.protBits)
val qos = UInt(width = params.qosBits) // 0=no QoS, bigger = higher priority
// val region = UInt(width = 4) // optional
}
// A non-standard bundle that can be both AR and AW
class AXI4BundleARW(params: AXI4BundleParameters) extends AXI4BundleA(params)
{
val wen = Bool()
}
class AXI4BundleAW(params: AXI4BundleParameters) extends AXI4BundleA(params)
class AXI4BundleAR(params: AXI4BundleParameters) extends AXI4BundleA(params)
class AXI4BundleW(params: AXI4BundleParameters) extends AXI4BundleBase(params)
{
// id ... removed in AXI4
val data = UInt(width = params.dataBits)
val strb = UInt(width = params.dataBits/8)
val last = Bool()
}
class AXI4BundleR(params: AXI4BundleParameters) extends AXI4BundleBase(params)
{
val id = UInt(width = params.idBits)
val data = UInt(width = params.dataBits)
val resp = UInt(width = params.respBits)
val last = Bool()
}
class AXI4BundleB(params: AXI4BundleParameters) extends AXI4BundleBase(params)
{
val id = UInt(width = params.idBits)
val resp = UInt(width = params.respBits)
}
class AXI4Bundle(params: AXI4BundleParameters) extends AXI4BundleBase(params)
{
val aw = Irrevocable(new AXI4BundleAW(params))
val w = Irrevocable(new AXI4BundleW (params))
val b = Irrevocable(new AXI4BundleB (params)).flip
val ar = Irrevocable(new AXI4BundleAR(params))
val r = Irrevocable(new AXI4BundleR (params)).flip
}
object AXI4Bundle
{
def apply(params: AXI4BundleParameters) = new AXI4Bundle(params)
}

View File

@ -0,0 +1,47 @@
// See LICENSE for license details.
package uncore.axi4
import Chisel._
import chisel3.internal.sourceinfo.SourceInfo
import diplomacy._
object AXI4Imp extends NodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4EdgeParameters, AXI4EdgeParameters, AXI4Bundle]
{
def edgeO(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu)
def edgeI(pd: AXI4MasterPortParameters, pu: AXI4SlavePortParameters): AXI4EdgeParameters = AXI4EdgeParameters(pd, pu)
def bundleO(eo: Seq[AXI4EdgeParameters]): Vec[AXI4Bundle] = {
require (!eo.isEmpty)
Vec(eo.size, AXI4Bundle(eo.map(_.bundle).reduce(_.union(_))))
}
def bundleI(ei: Seq[AXI4EdgeParameters]): Vec[AXI4Bundle] = {
require (!ei.isEmpty)
Vec(ei.size, AXI4Bundle(ei.map(_.bundle).reduce(_.union(_)))).flip
}
def colour = "#00ccff" // bluish
def connect(bo: => AXI4Bundle, bi: => AXI4Bundle, ei: => AXI4EdgeParameters)(implicit sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = {
(None, () => { bi <> bo })
}
override def mixO(pd: AXI4MasterPortParameters, node: OutwardNode[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4Bundle]): AXI4MasterPortParameters =
pd.copy(masters = pd.masters.map { c => c.copy (nodePath = node +: c.nodePath) })
override def mixI(pu: AXI4SlavePortParameters, node: InwardNode[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4Bundle]): AXI4SlavePortParameters =
pu.copy(slaves = pu.slaves.map { m => m.copy (nodePath = node +: m.nodePath) })
}
case class AXI4IdentityNode() extends IdentityNode(AXI4Imp)
case class AXI4OutputNode() extends OutputNode(AXI4Imp)
case class AXI4InputNode() extends InputNode(AXI4Imp)
case class AXI4MasterNode(portParams: AXI4MasterPortParameters, numPorts: Range.Inclusive = 1 to 1)
extends SourceNode(AXI4Imp)(portParams, numPorts)
case class AXI4SlaveNode(portParams: AXI4SlavePortParameters, numPorts: Range.Inclusive = 1 to 1)
extends SinkNode(AXI4Imp)(portParams, numPorts)
case class AXI4AdapterNode(
clientFn: Seq[AXI4MasterPortParameters] => AXI4MasterPortParameters,
managerFn: Seq[AXI4SlavePortParameters] => AXI4SlavePortParameters,
numMasterPorts: Range.Inclusive = 1 to 1,
numSlavePorts: Range.Inclusive = 1 to 1)
extends InteriorNode(AXI4Imp)(clientFn, managerFn, numMasterPorts, numSlavePorts)

View File

@ -0,0 +1,109 @@
// See LICENSE for license details.
package uncore.axi4
import Chisel._
import diplomacy._
import scala.math.max
case class AXI4SlaveParameters(
address: Seq[AddressSet],
regionType: RegionType.T = RegionType.GET_EFFECTS,
executable: Boolean = false, // processor can execute from this memory
nodePath: Seq[BaseNode] = Seq(),
supportsWrite: TransferSizes = TransferSizes.none,
supportsRead: TransferSizes = TransferSizes.none,
interleavedId: Option[Int] = None) // The device will not interleave read responses
{
address.foreach { a => require (a.finite) }
address.combinations(2).foreach { case Seq(x,y) => require (!x.overlaps(y)) }
val name = nodePath.lastOption.map(_.lazyModule.name).getOrElse("disconnected")
val maxTransfer = max(supportsWrite.max, supportsRead.max)
val maxAddress = address.map(_.max).max
// The device had better not support a transfer larger than it's alignment
address.foreach { case a => require (a.alignment >= maxTransfer) }
}
case class AXI4SlavePortParameters(
slaves: Seq[AXI4SlaveParameters],
beatBytes: Int)
{
require (!slaves.isEmpty)
require (isPow2(beatBytes))
val maxTransfer = slaves.map(_.maxTransfer).max
val maxAddress = slaves.map(_.maxAddress).max
// Check the link is not pointlessly wide
require (maxTransfer >= beatBytes)
// Check that the link can be implemented in AXI4
require (maxTransfer <= beatBytes * (1 << AXI4Parameters.lenBits))
// Require disjoint ranges for addresses
slaves.combinations(2).foreach { case Seq(x,y) =>
x.address.foreach { a => y.address.foreach { b =>
require (!a.overlaps(b))
} }
}
}
case class AXI4MasterParameters(
id: IdRange = IdRange(0, 1),
nodePath: Seq[BaseNode] = Seq())
{
val name = nodePath.lastOption.map(_.lazyModule.name).getOrElse("disconnected")
}
case class AXI4MasterPortParameters(
masters: Seq[AXI4MasterParameters])
{
val endId = masters.map(_.id.end).max
// Require disjoint ranges for ids
masters.combinations(2).foreach { case Seq(x,y) => require (!x.id.overlaps(y.id)) }
}
case class AXI4BundleParameters(
addrBits: Int,
dataBits: Int,
idBits: Int)
{
require (dataBits >= 8)
require (addrBits >= 1)
require (idBits >= 1)
require (isPow2(dataBits))
// Bring the globals into scope
val lenBits = AXI4Parameters.lenBits
val sizeBits = AXI4Parameters.sizeBits
val burstBits = AXI4Parameters.burstBits
val lockBits = AXI4Parameters.lockBits
val cacheBits = AXI4Parameters.cacheBits
val protBits = AXI4Parameters.protBits
val qosBits = AXI4Parameters.qosBits
val respBits = AXI4Parameters.respBits
def union(x: AXI4BundleParameters) =
AXI4BundleParameters(
max(addrBits, x.addrBits),
max(dataBits, x.dataBits),
max(idBits, x.idBits))
}
object AXI4BundleParameters
{
def apply(master: AXI4MasterPortParameters, slave: AXI4SlavePortParameters) =
new AXI4BundleParameters(
addrBits = log2Up(slave.maxAddress+1),
dataBits = slave.beatBytes * 8,
idBits = log2Up(master.endId))
}
case class AXI4EdgeParameters(
master: AXI4MasterPortParameters,
slave: AXI4SlavePortParameters)
{
val bundle = AXI4BundleParameters(master, slave)
}

View File

@ -0,0 +1,37 @@
// See LICENSE for license details.
package uncore.axi4
import Chisel._
import chisel3.util.{Irrevocable, IrrevocableIO}
object AXI4Parameters
{
// These are all fixed by the AXI4 standard:
val lenBits = 8
val sizeBits = 3
val burstBits = 2
val lockBits = 1
val cacheBits = 4
val protBits = 3
val qosBits = 4
val respBits = 2
val CACHE_RALLOCATE = UInt(8, width = cacheBits)
val CACHE_WALLOCATE = UInt(4, width = cacheBits)
val CACHE_MODIFIABLE = UInt(2, width = cacheBits)
val CACHE_BUFFERABLE = UInt(1, width = cacheBits)
val PROT_PRIVILEDGED = UInt(1, width = protBits)
val PROT_INSECURE = UInt(2, width = protBits)
val PROT_INSTRUCTION = UInt(4, width = protBits)
val BURST_FIXED = UInt(0, width = burstBits)
val BURST_INCR = UInt(1, width = burstBits)
val BURST_WRAP = UInt(2, width = burstBits)
val RESP_OKAY = UInt(0, width = respBits)
val RESP_EXOKAY = UInt(1, width = respBits)
val RESP_SLVERR = UInt(2, width = respBits)
val RESP_DECERR = UInt(3, width = respBits)
}

View File

@ -0,0 +1,9 @@
package uncore
import Chisel._
import diplomacy._
package object axi4
{
type AXI4OutwardNode = OutwardNode[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4Bundle]
}