axi4: diplomacy capable AXI4
This commit is contained in:
		
							
								
								
									
										68
									
								
								src/main/scala/uncore/axi4/Bundles.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/main/scala/uncore/axi4/Bundles.scala
									
									
									
									
									
										Normal 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)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										47
									
								
								src/main/scala/uncore/axi4/Nodes.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/main/scala/uncore/axi4/Nodes.scala
									
									
									
									
									
										Normal 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)
 | 
				
			||||||
							
								
								
									
										109
									
								
								src/main/scala/uncore/axi4/Parameters.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								src/main/scala/uncore/axi4/Parameters.scala
									
									
									
									
									
										Normal 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)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										37
									
								
								src/main/scala/uncore/axi4/Protocol.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								src/main/scala/uncore/axi4/Protocol.scala
									
									
									
									
									
										Normal 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)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										9
									
								
								src/main/scala/uncore/axi4/package.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/main/scala/uncore/axi4/package.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					package uncore
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Chisel._
 | 
				
			||||||
 | 
					import diplomacy._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package object axi4
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  type AXI4OutwardNode = OutwardNode[AXI4MasterPortParameters, AXI4SlavePortParameters, AXI4Bundle]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user