[tilelink2] Fuzzer: Allow noise-making to be parameterized. Better comments.
This commit is contained in:
parent
05100c12a7
commit
e318c29d48
@ -50,15 +50,39 @@ object LFSR64
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object NoiseMaker
|
trait HasNoiseMakerIO
|
||||||
{
|
{
|
||||||
def apply(wide: Int, increment: Bool = Bool(true)): UInt = {
|
val io = new Bundle {
|
||||||
val lfsrs = Seq.fill((wide+63)/64) { LFSR64(increment) }
|
val inc = Bool(INPUT)
|
||||||
Cat(lfsrs)(wide-1,0)
|
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)))
|
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 out = io.out(0)
|
||||||
val edge = node.edgesOut(0)
|
val edge = node.edgesOut(0)
|
||||||
|
|
||||||
|
// Extract useful parameters from the TL edge
|
||||||
val endAddress = edge.manager.maxAddress + 1
|
val endAddress = edge.manager.maxAddress + 1
|
||||||
val maxTransfer = edge.manager.maxTransfer
|
val maxTransfer = edge.manager.maxTransfer
|
||||||
val beatBytes = edge.manager.beatBytes
|
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
|
// Increment random number generation for the following subfields
|
||||||
val inc = Wire(Bool())
|
val inc = Wire(Bool())
|
||||||
val inc_beat = Wire(Bool())
|
val inc_beat = Wire(Bool())
|
||||||
val arth_op = NoiseMaker(3, inc)
|
val arth_op = noiseMaker(3, inc)
|
||||||
val log_op = NoiseMaker(2, inc)
|
val log_op = noiseMaker(2, inc)
|
||||||
val amo_size = UInt(2) + NoiseMaker(1, inc) // word or dword
|
val amo_size = UInt(2) + noiseMaker(1, inc) // word or dword
|
||||||
val size = NoiseMaker(sizeBits, inc)
|
val size = noiseMaker(sizeBits, inc)
|
||||||
val addr = NoiseMaker(addressBits, inc) & ~UIntToOH1(size, addressBits)
|
val addr = noiseMaker(addressBits, inc) & ~UIntToOH1(size, addressBits)
|
||||||
val mask = NoiseMaker(beatBytes, inc_beat) & edge.mask(addr, size)
|
val mask = noiseMaker(beatBytes, inc_beat) & edge.mask(addr, size)
|
||||||
val data = NoiseMaker(dataBits, inc_beat)
|
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 (glegal, gbits) = edge.Get(src, addr, size)
|
||||||
val (pflegal, pfbits) = if(edge.manager.anySupportPutFull) {
|
val (pflegal, pfbits) = if(edge.manager.anySupportPutFull) {
|
||||||
edge.Put(src, addr, size, data)
|
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))
|
edge.Hint(src, addr, size, UInt(0))
|
||||||
} else { (glegal, gbits) }
|
} 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(
|
val legal = MuxLookup(a_type_sel, glegal, Seq(
|
||||||
UInt("b000") -> glegal,
|
UInt("b000") -> glegal,
|
||||||
@ -154,6 +182,7 @@ class TLFuzzer(nOperations: Int, inFlight: Int = 32) extends LazyModule
|
|||||||
UInt("b100") -> lbits,
|
UInt("b100") -> lbits,
|
||||||
UInt("b101") -> hbits))
|
UInt("b101") -> hbits))
|
||||||
|
|
||||||
|
// Wire both the used and un-used channel signals
|
||||||
out.a.valid := legal && alloc.valid && num_reqs =/= UInt(0)
|
out.a.valid := legal && alloc.valid && num_reqs =/= UInt(0)
|
||||||
out.a.bits := bits
|
out.a.bits := bits
|
||||||
out.b.ready := Bool(true)
|
out.b.ready := Bool(true)
|
||||||
@ -161,6 +190,7 @@ class TLFuzzer(nOperations: Int, inFlight: Int = 32) extends LazyModule
|
|||||||
out.d.ready := Bool(true)
|
out.d.ready := Bool(true)
|
||||||
out.e.valid := Bool(false)
|
out.e.valid := Bool(false)
|
||||||
|
|
||||||
|
// Increment the various progress-tracking states
|
||||||
inc := !legal || req_done
|
inc := !legal || req_done
|
||||||
inc_beat := !legal || out.a.fire()
|
inc_beat := !legal || out.a.fire()
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user