tilelink2: Filter adapter removes some of the address space
This commit is contained in:
		@@ -104,6 +104,17 @@ case class AddressSet(base: BigInt, mask: BigInt) extends Ordered[AddressSet]
 | 
				
			|||||||
  // Widen the match function to ignore all bits in imask
 | 
					  // Widen the match function to ignore all bits in imask
 | 
				
			||||||
  def widen(imask: BigInt) = AddressSet(base & ~imask, mask | imask)
 | 
					  def widen(imask: BigInt) = AddressSet(base & ~imask, mask | imask)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Return an AddressSet that only contains the addresses both sets contain
 | 
				
			||||||
 | 
					  def intersect(x: AddressSet): Option[AddressSet] = {
 | 
				
			||||||
 | 
					    if (!overlaps(x)) {
 | 
				
			||||||
 | 
					      None
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      val r_mask = mask & x.mask
 | 
				
			||||||
 | 
					      val r_base = base | x.base
 | 
				
			||||||
 | 
					      Some(AddressSet(r_base, r_mask))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // AddressSets have one natural Ordering (the containment order, if contiguous)
 | 
					  // AddressSets have one natural Ordering (the containment order, if contiguous)
 | 
				
			||||||
  def compare(x: AddressSet) = {
 | 
					  def compare(x: AddressSet) = {
 | 
				
			||||||
    val primary   = (this.base - x.base).signum // smallest address first
 | 
					    val primary   = (this.base - x.base).signum // smallest address first
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										49
									
								
								src/main/scala/uncore/tilelink2/Filter.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/main/scala/uncore/tilelink2/Filter.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,49 @@
 | 
				
			|||||||
 | 
					// See LICENSE for license details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package uncore.tilelink2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Chisel._
 | 
				
			||||||
 | 
					import chisel3.internal.sourceinfo.SourceInfo
 | 
				
			||||||
 | 
					import diplomacy._
 | 
				
			||||||
 | 
					import scala.math.{min,max}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TLFilter(select: AddressSet) extends LazyModule
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val node = TLAdapterNode(
 | 
				
			||||||
 | 
					    clientFn  = { case Seq(cp) => cp },
 | 
				
			||||||
 | 
					    managerFn = { case Seq(mp) =>
 | 
				
			||||||
 | 
					      mp.copy(managers = mp.managers.map { m =>
 | 
				
			||||||
 | 
					        val filtered = m.address.map(_.intersect(select)).flatten
 | 
				
			||||||
 | 
					        val cap = TransferSizes(1, select.alignment.toInt)
 | 
				
			||||||
 | 
					        if (filtered.isEmpty) { None } else {
 | 
				
			||||||
 | 
					          Some(m.copy(
 | 
				
			||||||
 | 
					            address            = filtered,
 | 
				
			||||||
 | 
					            supportsAcquire    = m.supportsAcquire   .intersect(cap),
 | 
				
			||||||
 | 
					            supportsArithmetic = m.supportsArithmetic.intersect(cap),
 | 
				
			||||||
 | 
					            supportsLogical    = m.supportsLogical   .intersect(cap),
 | 
				
			||||||
 | 
					            supportsGet        = m.supportsGet       .intersect(cap),
 | 
				
			||||||
 | 
					            supportsPutFull    = m.supportsPutFull   .intersect(cap),
 | 
				
			||||||
 | 
					            supportsPutPartial = m.supportsPutPartial.intersect(cap),
 | 
				
			||||||
 | 
					            supportsHint       = m.supportsHint      .intersect(cap)))
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }.flatten)
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  lazy val module = new LazyModuleImp(this) {
 | 
				
			||||||
 | 
					    val io = new Bundle {
 | 
				
			||||||
 | 
					      val in  = node.bundleIn
 | 
				
			||||||
 | 
					      val out = node.bundleOut
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    io.out <> io.in
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					object TLFilter
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  // applied to the TL source node; y.node := TLBuffer(x.node)
 | 
				
			||||||
 | 
					  def apply(select: AddressSet)(x: TLOutwardNode)(implicit sourceInfo: SourceInfo): TLOutwardNode = {
 | 
				
			||||||
 | 
					    val filter = LazyModule(new TLFilter(select))
 | 
				
			||||||
 | 
					    filter.node := x
 | 
				
			||||||
 | 
					    filter.node
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -23,7 +23,9 @@ case class TLManagerParameters(
 | 
				
			|||||||
  fifoId:             Option[Int]   = None,
 | 
					  fifoId:             Option[Int]   = None,
 | 
				
			||||||
  customDTS:          Option[String]= None)
 | 
					  customDTS:          Option[String]= None)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					  require (!address.isEmpty)
 | 
				
			||||||
  address.foreach { a => require (a.finite) }
 | 
					  address.foreach { a => require (a.finite) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  address.combinations(2).foreach { case Seq(x,y) => require (!x.overlaps(y)) }
 | 
					  address.combinations(2).foreach { case Seq(x,y) => require (!x.overlaps(y)) }
 | 
				
			||||||
  require (supportsPutFull.contains(supportsPutPartial))
 | 
					  require (supportsPutFull.contains(supportsPutPartial))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user