[tilelink2] Fuzzer: Allow noise-making to be parameterized. Better comments.
This commit is contained in:
		@@ -50,15 +50,39 @@ object LFSR64
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
object NoiseMaker
 | 
			
		||||
trait HasNoiseMakerIO
 | 
			
		||||
{
 | 
			
		||||
  def apply(wide: Int, increment: Bool = Bool(true)): UInt = {
 | 
			
		||||
    val lfsrs = Seq.fill((wide+63)/64) { LFSR64(increment) }
 | 
			
		||||
    Cat(lfsrs)(wide-1,0)
 | 
			
		||||
  val io = new Bundle {
 | 
			
		||||
    val inc = Bool(INPUT)
 | 
			
		||||
    val random = UInt(OUTPUT)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class TLFuzzer(nOperations: Int, inFlight: Int = 32) extends LazyModule
 | 
			
		||||
class LFSRNoiseMaker(wide: Int) extends Module with HasNoiseMakerIO
 | 
			
		||||
{
 | 
			
		||||
  val lfsrs = Seq.fill((wide+63)/64) { LFSR64(io.inc) }
 | 
			
		||||
  io.random := Cat(lfsrs)(wide-1,0)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
object LFSRNoiseMaker {
 | 
			
		||||
  def apply(wide: Int, increment: Bool = Bool(true)): UInt = {
 | 
			
		||||
    val nm = Module(new LFSRNoiseMaker(wide))
 | 
			
		||||
    nm.io.inc := increment
 | 
			
		||||
    nm.io.random
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** TLFuzzer drives test traffic over TL2 links. It generates a sequence of randomized
 | 
			
		||||
  * requests, and issues legal ones into the DUT. TODO: Currently the fuzzer only generates
 | 
			
		||||
  * memory operations, not permissions transfers.
 | 
			
		||||
  * @param nOperations is the total number of operations that the fuzzer must complete for the test to pass
 | 
			
		||||
  * @param inFlight is the number of operations that can be in-flight to the DUT concurrently
 | 
			
		||||
  * @param noiseMaker is a function that supplies a random UInt of a given width every time inc is true
 | 
			
		||||
  */
 | 
			
		||||
class TLFuzzer(
 | 
			
		||||
    nOperations: Int,
 | 
			
		||||
    inFlight: Int = 32,
 | 
			
		||||
    noiseMaker: (Int, Bool) => UInt = LFSRNoiseMaker.apply _) extends LazyModule
 | 
			
		||||
{
 | 
			
		||||
  val node = TLClientNode(TLClientParameters(sourceId = IdRange(0,inFlight)))
 | 
			
		||||
 | 
			
		||||
@@ -70,6 +94,8 @@ class TLFuzzer(nOperations: Int, inFlight: Int = 32) extends LazyModule
 | 
			
		||||
 | 
			
		||||
    val out = io.out(0)
 | 
			
		||||
    val edge = node.edgesOut(0)
 | 
			
		||||
 | 
			
		||||
    // Extract useful parameters from the TL edge
 | 
			
		||||
    val endAddress   = edge.manager.maxAddress + 1
 | 
			
		||||
    val maxTransfer  = edge.manager.maxTransfer
 | 
			
		||||
    val beatBytes    = edge.manager.beatBytes
 | 
			
		||||
@@ -111,14 +137,15 @@ class TLFuzzer(nOperations: Int, inFlight: Int = 32) extends LazyModule
 | 
			
		||||
    // Increment random number generation for the following subfields
 | 
			
		||||
    val inc = Wire(Bool())
 | 
			
		||||
    val inc_beat = Wire(Bool())
 | 
			
		||||
    val arth_op   = NoiseMaker(3, inc)
 | 
			
		||||
    val log_op    = NoiseMaker(2, inc) 
 | 
			
		||||
    val amo_size  = UInt(2) + NoiseMaker(1, inc) // word or dword
 | 
			
		||||
    val size      = NoiseMaker(sizeBits, inc)
 | 
			
		||||
    val addr      = NoiseMaker(addressBits, inc) & ~UIntToOH1(size, addressBits)
 | 
			
		||||
    val mask      = NoiseMaker(beatBytes, inc_beat) & edge.mask(addr, size)
 | 
			
		||||
    val data      = NoiseMaker(dataBits, inc_beat)
 | 
			
		||||
    val arth_op   = noiseMaker(3, inc)
 | 
			
		||||
    val log_op    = noiseMaker(2, inc)
 | 
			
		||||
    val amo_size  = UInt(2) + noiseMaker(1, inc) // word or dword
 | 
			
		||||
    val size      = noiseMaker(sizeBits, inc)
 | 
			
		||||
    val addr      = noiseMaker(addressBits, inc) & ~UIntToOH1(size, addressBits)
 | 
			
		||||
    val mask      = noiseMaker(beatBytes, inc_beat) & edge.mask(addr, size)
 | 
			
		||||
    val data      = noiseMaker(dataBits, inc_beat)
 | 
			
		||||
 | 
			
		||||
    // Actually generate specific TL messages when it is legal to do so
 | 
			
		||||
    val (glegal,  gbits)  = edge.Get(src, addr, size)
 | 
			
		||||
    val (pflegal, pfbits) = if(edge.manager.anySupportPutFull) { 
 | 
			
		||||
                              edge.Put(src, addr, size, data)
 | 
			
		||||
@@ -136,7 +163,8 @@ class TLFuzzer(nOperations: Int, inFlight: Int = 32) extends LazyModule
 | 
			
		||||
                              edge.Hint(src, addr, size, UInt(0))
 | 
			
		||||
                            } else { (glegal, gbits) }
 | 
			
		||||
 | 
			
		||||
    val a_type_sel  = NoiseMaker(3, inc)
 | 
			
		||||
    // Pick a specific message to try to send
 | 
			
		||||
    val a_type_sel  = noiseMaker(3, inc)
 | 
			
		||||
 | 
			
		||||
    val legal = MuxLookup(a_type_sel, glegal, Seq(
 | 
			
		||||
      UInt("b000") -> glegal,
 | 
			
		||||
@@ -154,6 +182,7 @@ class TLFuzzer(nOperations: Int, inFlight: Int = 32) extends LazyModule
 | 
			
		||||
      UInt("b100") -> lbits,
 | 
			
		||||
      UInt("b101") -> hbits))
 | 
			
		||||
 | 
			
		||||
    // Wire both the used and un-used channel signals
 | 
			
		||||
    out.a.valid := legal && alloc.valid && num_reqs =/= UInt(0)
 | 
			
		||||
    out.a.bits  := bits
 | 
			
		||||
    out.b.ready := Bool(true)
 | 
			
		||||
@@ -161,6 +190,7 @@ class TLFuzzer(nOperations: Int, inFlight: Int = 32) extends LazyModule
 | 
			
		||||
    out.d.ready := Bool(true)
 | 
			
		||||
    out.e.valid := Bool(false)
 | 
			
		||||
 | 
			
		||||
    // Increment the various progress-tracking states
 | 
			
		||||
    inc := !legal || req_done
 | 
			
		||||
    inc_beat := !legal || out.a.fire()
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user