From 0671d5d637fbf3ca74ee842875a9c9b3ea1124ff Mon Sep 17 00:00:00 2001 From: Henry Cook Date: Fri, 9 Sep 2016 17:16:35 -0700 Subject: [PATCH] Initial version of fuzzer and simple ram fuzz test --- chisel3 | 2 +- .../scala/junctions/unittests/UnitTest.scala | 4 +- src/main/scala/uncore/tilelink2/Fuzzer.scala | 145 ++++++++++++++++++ src/main/scala/uncore/unittests/Tests.scala | 3 +- 4 files changed, 151 insertions(+), 3 deletions(-) create mode 100644 src/main/scala/uncore/tilelink2/Fuzzer.scala diff --git a/chisel3 b/chisel3 index 16426b3a..bb240453 160000 --- a/chisel3 +++ b/chisel3 @@ -1 +1 @@ -Subproject commit 16426b3a68d85ce7dd9655b0ce773431eb69fc74 +Subproject commit bb240453abf96b4c2d75ebb2cdc7e3159068431d diff --git a/src/main/scala/junctions/unittests/UnitTest.scala b/src/main/scala/junctions/unittests/UnitTest.scala index f206e945..b40be2af 100644 --- a/src/main/scala/junctions/unittests/UnitTest.scala +++ b/src/main/scala/junctions/unittests/UnitTest.scala @@ -4,12 +4,14 @@ import Chisel._ import junctions._ import cde.{Field, Parameters} -abstract class UnitTest extends Module { +trait HasUnitTestIO { val io = new Bundle { val finished = Bool(OUTPUT) val start = Bool(INPUT) } +} +abstract class UnitTest extends Module with HasUnitTestIO { when (io.start) { printf(s"Started UnitTest ${this.getClass.getSimpleName}\n") } diff --git a/src/main/scala/uncore/tilelink2/Fuzzer.scala b/src/main/scala/uncore/tilelink2/Fuzzer.scala new file mode 100644 index 00000000..f39ff722 --- /dev/null +++ b/src/main/scala/uncore/tilelink2/Fuzzer.scala @@ -0,0 +1,145 @@ +// See LICENSE for license details. +package uncore.tilelink2 + +import Chisel._ +import chisel3.util.LFSR16 +import junctions.unittests._ + +object LFSR64 +{ + private var counter = 0 + private def next: Int = { + counter += 1 + counter + } + + def apply(increment: Bool = Bool(true), seed: Int = next): UInt = + { + val wide = 64 + val lfsr = RegInit(UInt((seed * 0xDEADBEEFCAFEBAB1L) >>> 1, width = wide)) + val xor = lfsr(0) ^ lfsr(1) ^ lfsr(3) ^ lfsr(4) + when (increment) { lfsr := Cat(xor, lfsr(wide-1,1)) } + lfsr + } +} + +object NoiseMaker +{ + def apply(wide: Int, increment: Bool = Bool(true)): UInt = { + val lfsrs = Seq.fill((wide+63)/64) { LFSR64(increment) } + Cat(lfsrs)(wide-1,0) + } +} + +object MaskMaker +{ + def apply(wide: Int, bits: UInt): UInt = + Vec.tabulate(wide) {UInt(_) < bits} .asUInt +} + + +class TLFuzzer(nOperations: Int) extends LazyModule +{ + val node = TLClientNode(TLClientParameters()) + + lazy val module = new LazyModuleImp(this) { + val io = new Bundle { + val out = node.bundleOut + val finished = Bool() + } + + val out = io.out(0) + val edge = node.edgesOut(0) + + val idx = Reg(init = UInt(nOperations-1, log2Up(nOperations))) + val finished = RegInit(Bool(false)) + val valid = RegInit(Bool(false)) + valid := Bool(true) + io.finished := finished + + val counter = RegInit(UInt(0, width = log2Up(edge.maxTransfer))) + val inc = Wire(Bool()) + + val addrBits = log2Up(edge.manager.maxAddress + 1) + val amo_size = UInt(2) + NoiseMaker(1, inc) // word or dword + val size = NoiseMaker(edge.bundle.sizeBits, inc) + val addr_mask = MaskMaker(addrBits, size) + val addr = NoiseMaker(addrBits, inc) & ~addr_mask + val wmask = NoiseMaker(edge.manager.beatBytes, inc) + val data = NoiseMaker(edge.bundle.dataBits, inc) + val arth_op = NoiseMaker(3, inc) + val log_op = NoiseMaker(2, inc) + val src = UInt(0) + + val (glegal, gbits) = edge.Get(src, addr, size) + val (pflegal, pfbits) = if(edge.manager.anySupportPutFull) { + edge.Put(src, addr, size, data) + } else { (glegal, gbits) } + val (pplegal, ppbits) = if(edge.manager.anySupportPutPartial) { + edge.Put(src, addr, size, data, wmask) + } else { (glegal, gbits) } + val (alegal, abits) = if(edge.manager.anySupportArithmetic) { + edge.Arithmetic(src, addr, size, data, arth_op) + } else { (glegal, gbits) } + val (llegal, lbits) = if(edge.manager.anySupportLogical) { + edge.Logical(src, addr, size, data, log_op) + } else { (glegal, gbits) } + val (hlegal, hbits) = if(edge.manager.anySupportHint) { + edge.Hint(src, addr, size, UInt(0)) + } else { (glegal, gbits) } + + val a_type_sel = NoiseMaker(3, inc) + + val legal = MuxLookup(a_type_sel, glegal, Seq( + UInt("b000") -> glegal, + UInt("b001") -> pflegal, + UInt("b010") -> pplegal, + UInt("b011") -> alegal, + UInt("b100") -> llegal, + UInt("b101") -> hlegal)) + + val bits = MuxLookup(a_type_sel, gbits, Seq( + UInt("b000") -> gbits, + UInt("b001") -> pfbits, + UInt("b010") -> ppbits, + UInt("b011") -> abits, + UInt("b100") -> lbits, + UInt("b101") -> hbits)) + + out.a.valid := legal + out.a.bits := bits + out.b.ready := Bool(true) + out.c.valid := Bool(false) + out.d.ready := Bool(true) + out.e.valid := Bool(false) + + inc := !legal || (out.a.fire() && counter === UInt(0)) + when (out.a.fire()) { + counter := counter - UInt(1) + when (counter === UInt(0)) { + counter := edge.numBeats(out.a.bits) - UInt(1) + idx := idx - UInt(1) + } + when (idx === UInt(0)) { finished := Bool(true) } + } + } +} + +class TLFuzzRAM extends LazyModule +{ + val ram = LazyModule(new TLRAM(AddressSet(0, 0xfff))) + val xbar = LazyModule(new TLXbar) + val fuzz = LazyModule(new TLFuzzer(1000)) + + connect(TLWidthWidget(TLHintHandler(fuzz.node), 16) -> xbar.node) + connect(TLFragmenter(TLBuffer(xbar.node), 4, 256) -> ram.node) + + lazy val module = new LazyModuleImp(this) with HasUnitTestIO { + io.finished := fuzz.module.io.finished + } +} + +class TLFuzzRAMTest extends UnitTest { + val dut = LazyModule(new TLFuzzRAM).module + io.finished := dut.io.finished +} diff --git a/src/main/scala/uncore/unittests/Tests.scala b/src/main/scala/uncore/unittests/Tests.scala index bcd9de37..c59194b6 100644 --- a/src/main/scala/uncore/unittests/Tests.scala +++ b/src/main/scala/uncore/unittests/Tests.scala @@ -81,5 +81,6 @@ object UncoreUnitTests { Seq( Module(new SmiConverterTest), Module(new ROMSlaveTest), - Module(new TileLinkRAMTest)) + Module(new TileLinkRAMTest), + Module(new uncore.tilelink2.TLFuzzRAMTest)) }