tilelink: add PatternPusher, a device to inject a fixed traffic pattern (#950)
This commit is contained in:
		
				
					committed by
					
						
						GitHub
					
				
			
			
				
	
			
			
			
						parent
						
							a3358f34a0
						
					
				
				
					commit
					baf769f924
				
			
							
								
								
									
										74
									
								
								src/main/scala/tilelink/PatternPusher.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								src/main/scala/tilelink/PatternPusher.scala
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
				
			|||||||
 | 
					// See LICENSE.SiFive for license details.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package freechips.rocketchip.tilelink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import Chisel._
 | 
				
			||||||
 | 
					import chisel3.internal.sourceinfo.SourceInfo
 | 
				
			||||||
 | 
					import freechips.rocketchip.config.Parameters
 | 
				
			||||||
 | 
					import freechips.rocketchip.diplomacy._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					sealed trait Pattern {
 | 
				
			||||||
 | 
					  def address: BigInt
 | 
				
			||||||
 | 
					  def size: Int
 | 
				
			||||||
 | 
					  def bits(edge: TLEdgeOut): (Bool, TLBundleA)
 | 
				
			||||||
 | 
					  require ((address & ((BigInt(1) << size) - 1)) == 0)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					case class WritePattern(address: BigInt, size: Int, data: BigInt) extends Pattern
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  require (log2Floor(data) < (BigInt(8) << size))
 | 
				
			||||||
 | 
					  def bits(edge: TLEdgeOut) = edge.Put(UInt(0), UInt(address), UInt(size), UInt(data))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					case class ReadPattern(address: BigInt, size: Int) extends Pattern
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  def bits(edge: TLEdgeOut) = edge.Get(UInt(0), UInt(address), UInt(size))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TLPatternPusher(name: String, pattern: Seq[Pattern])(implicit p: Parameters) extends LazyModule
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  val node = TLClientNode(Seq(TLClientPortParameters(Seq(TLClientParameters(name = name)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  lazy val module = new LazyModuleImp(this) {
 | 
				
			||||||
 | 
					    val io = new Bundle {
 | 
				
			||||||
 | 
					      val tl_out = node.bundleOut
 | 
				
			||||||
 | 
					      val run = Bool(INPUT)
 | 
				
			||||||
 | 
					      val done = Bool(OUTPUT)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    val edgeOut = node.edgesOut(0)
 | 
				
			||||||
 | 
					    pattern.foreach { p =>
 | 
				
			||||||
 | 
					      require (p.size <= log2Ceil(edgeOut.manager.beatBytes), "Patterns must fit in a single beat")
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    val step   = RegInit(UInt(0, width = log2Ceil(pattern.size+1)))
 | 
				
			||||||
 | 
					    val flight = RegInit(Bool(false))
 | 
				
			||||||
 | 
					    val ready  = RegNext(Bool(true), Bool(false))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    val end = step === UInt(pattern.size)
 | 
				
			||||||
 | 
					    io.done := end && !flight
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    val a = io.tl_out(0).a
 | 
				
			||||||
 | 
					    val d = io.tl_out(0).d
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    when (a.fire()) {
 | 
				
			||||||
 | 
					      flight := Bool(true)
 | 
				
			||||||
 | 
					      step := step + UInt(1)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    when (d.fire()) {
 | 
				
			||||||
 | 
					      flight := Bool(false)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    val (plegal, pbits) = pattern.map(_.bits(edgeOut)).unzip
 | 
				
			||||||
 | 
					    assert (end || Vec(plegal)(step), s"Pattern pusher ${name} tried to push an illegal request")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    a.valid := io.run && ready && !end && !flight
 | 
				
			||||||
 | 
					    a.bits  := Vec(pbits)(step)
 | 
				
			||||||
 | 
					    d.ready := Bool(true)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Tie off unused channels
 | 
				
			||||||
 | 
					    io.tl_out(0).b.ready := Bool(true)
 | 
				
			||||||
 | 
					    io.tl_out(0).c.valid := Bool(false)
 | 
				
			||||||
 | 
					    io.tl_out(0).e.valid := Bool(false)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user