diff --git a/src/main/scala/junctions/unittests/UnitTest.scala b/src/main/scala/junctions/unittests/UnitTest.scala index 723ac164..77dd146b 100644 --- a/src/main/scala/junctions/unittests/UnitTest.scala +++ b/src/main/scala/junctions/unittests/UnitTest.scala @@ -39,7 +39,7 @@ class UnitTestSuite(implicit p: Parameters) extends Module { state := Mux(test_idx === UInt(tests.size - 1), s_done, s_start) } - val timer = Module(new Timer(50000, tests.size)) + val timer = Module(new Timer(100000, tests.size)) timer.io.start.valid := Bool(false) timer.io.stop.valid := Bool(false) diff --git a/src/main/scala/uncore/tilelink2/Fuzzer.scala b/src/main/scala/uncore/tilelink2/Fuzzer.scala index 7c9b2625..42469fb4 100644 --- a/src/main/scala/uncore/tilelink2/Fuzzer.scala +++ b/src/main/scala/uncore/tilelink2/Fuzzer.scala @@ -179,13 +179,15 @@ class TLFuzzer(nOperations: Int, inFlight: Int = 32) extends LazyModule class TLFuzzRAM extends LazyModule { val model = LazyModule(new TLRAMModel) - val ram = LazyModule(new TLRAM(AddressSet(0, 0xfff))) + val ram = LazyModule(new TLRAM(AddressSet(0, 0x3ff))) + val gpio = LazyModule(new RRTest1(0x400)) val xbar = LazyModule(new TLXbar) - val fuzz = LazyModule(new TLFuzzer(1000)) + val fuzz = LazyModule(new TLFuzzer(5000)) model.node := fuzz.node xbar.node := TLWidthWidget(TLHintHandler(model.node), 16) ram.node := TLFragmenter(TLBuffer(xbar.node), 4, 256) + gpio.node := TLFragmenter(TLBuffer(xbar.node), 4, 32) lazy val module = new LazyModuleImp(this) with HasUnitTestIO { io.finished := fuzz.module.io.finished diff --git a/src/main/scala/uncore/tilelink2/RAMModel.scala b/src/main/scala/uncore/tilelink2/RAMModel.scala index 45172b3a..ce3ddb70 100644 --- a/src/main/scala/uncore/tilelink2/RAMModel.scala +++ b/src/main/scala/uncore/tilelink2/RAMModel.scala @@ -223,7 +223,7 @@ class TLRAMModel extends LazyModule when (!shadow.valid) { printf("G 0x%x := undefined\n", d_addr_hi << shift | UInt(i)) } .otherwise { - printf("G 0x%x := 0x%x\n", d_addr_hi << shift | UInt(i), shadow.value) + printf("G 0x%x := 0x%x\n", d_addr_hi << shift | UInt(i), got) assert (shadow.value === got) } } diff --git a/src/main/scala/uncore/tilelink2/RegisterRouterTest.scala b/src/main/scala/uncore/tilelink2/RegisterRouterTest.scala index a93112f5..65dde1d3 100644 --- a/src/main/scala/uncore/tilelink2/RegisterRouterTest.scala +++ b/src/main/scala/uncore/tilelink2/RegisterRouterTest.scala @@ -9,7 +9,7 @@ object LFSR16Seed def apply(seed: Int): UInt = { val width = 16 - val lfsr = Reg(init=UInt(seed, width)) + val lfsr = Reg(init=UInt((seed*0x7231) % 65536, width)) lfsr := Cat(lfsr(0)^lfsr(2)^lfsr(3)^lfsr(5), lfsr(width-1,1)) lfsr } @@ -39,12 +39,11 @@ class RRTestCombinational(val bits: Int, rvalid: Bool => Bool, wready: Bool => B object RRTestCombinational { - private var seed = 0 + private var seed = 42 def always: Bool => Bool = _ => Bool(true) def random: Bool => Bool = { seed = seed + 1 - val lfsr = LFSR16Seed(seed) - _ => lfsr(0) + _ => LFSR16Seed(seed)(0) } def delay(x: Int): Bool => Bool = { fire => val reg = RegInit(UInt(0, width = log2Ceil(x+1))) @@ -96,32 +95,40 @@ class RRTestRequest(val bits: Int, object RRTestRequest { - private var seed = 0 + private var seed = 1231 def pipe(x: Int): (Bool, Bool, UInt) => (Bool, Bool, UInt) = { (ivalid, oready, idata) => val full = RegInit(Vec.fill(x)(Bool(false))) - val ready = Wire(Vec.fill(x)(Bool())) - val data = Reg(Vec.fill(x)(UInt(width = idata.getWidth))) + val ready = Wire(Vec(x, Bool())) + val data = Reg(Vec(x, UInt(width = idata.getWidth))) // Construct a classic bubble-filling pipeline - ready(x) := oready || !full(x) + ready(x-1) := oready || !full(x-1) when (ready(0)) { data(0) := idata } + when (ready(0)) { full(0) := ivalid } ((ready.init zip ready.tail) zip full.init) foreach { case ((self, next), full) => self := next || !full } ((data.init zip data.tail) zip ready.tail) foreach { case ((prev, self), ready) => when (ready) { self := prev } } - (ready(0), full(x), Mux(full(x) && oready, data(x), UInt(0))) + ((full.init zip full.tail) zip ready.tail) foreach { case ((prev, self), ready) => + when (ready) { self := prev } + } + (ready(0), full(x-1), data(x-1)) } def busy: (Bool, Bool, UInt) => (Bool, Bool, UInt) = { seed = seed + 1 - val lfsr = LFSR16Seed(seed) (ivalid, oready, idata) => { + val lfsr = LFSR16Seed(seed) val busy = RegInit(Bool(false)) + val data = Reg(UInt(width = idata.getWidth)) val progress = lfsr(0) when (progress) { busy := Mux(busy, !oready, ivalid) } - (progress && !busy, progress && busy, idata) + val iready = progress && !busy + val ovalid = progress && busy + when (ivalid && iready) { data := idata } + (iready, ovalid, data) } } def request(bits: Int, @@ -140,3 +147,76 @@ object RRTestRequest (request.io.wiready, request.io.wovalid) }) } } + +object RRTest0Map +{ + import RRTestCombinational._ + + def aa(bits: Int) = combo(bits, always, always) + def ar(bits: Int) = combo(bits, always, random) + def ad(bits: Int) = combo(bits, always, delay(11)) + def ae(bits: Int) = combo(bits, always, delay(5)) + def ra(bits: Int) = combo(bits, random, always) + def rr(bits: Int) = combo(bits, random, random) + def rd(bits: Int) = combo(bits, random, delay(11)) + def re(bits: Int) = combo(bits, random, delay(5)) + def da(bits: Int) = combo(bits, delay(5), always) + def dr(bits: Int) = combo(bits, delay(5), random) + def dd(bits: Int) = combo(bits, delay(5), delay(5)) + def de(bits: Int) = combo(bits, delay(5), delay(11)) + def ea(bits: Int) = combo(bits, delay(11), always) + def er(bits: Int) = combo(bits, delay(11), random) + def ed(bits: Int) = combo(bits, delay(11), delay(5)) + def ee(bits: Int) = combo(bits, delay(11), delay(11)) + + // All fields must respect byte alignment, or else it won't behave like an SRAM + val map = Seq( + 0 -> Seq(aa(8), ar(8), ad(8), ae(8)), + 1 -> Seq(ra(8), rr(8), rd(8), re(8)), + 2 -> Seq(da(8), dr(8), dd(8), de(8)), + 3 -> Seq(ea(8), er(8), ed(8), ee(8)), + 4 -> Seq(aa(3), ar(5), ad(1), ae(7), ra(2), rr(6), rd(4), re(4)), + 5 -> Seq(da(3), dr(5), dd(1), de(7), ea(2), er(6), ed(4), ee(4)), + 6 -> Seq(aa(8), rr(8), dd(8), ee(8)), + 7 -> Seq(ar(8), rd(8), de(8), ea(8))) +} + +object RRTest1Map +{ + import RRTestRequest._ + + def pp(bits: Int) = request(bits, pipe(3), pipe(3)) + def pb(bits: Int) = request(bits, pipe(3), busy) + def bp(bits: Int) = request(bits, busy, pipe(3)) + def bb(bits: Int) = request(bits, busy, busy) + + val map = RRTest0Map.map.take(6) ++ Seq( + 6 -> Seq(pp(8), pb(8), bp(8), bb(8)), + 7 -> Seq(pp(3), pb(5), bp(1), bb(7), pb(5), bp(3), pp(4), bb(4))) +} + +trait RRTest0Bundle +{ +} + +trait RRTest0Module extends HasRegMap +{ + regmap(RRTest0Map.map:_*) +} + +class RRTest0(address: BigInt) extends TLRegisterRouter(address, 0, 32, Some(0), 4)( + new TLRegBundle((), _) with RRTest0Bundle)( + new TLRegModule((), _, _) with RRTest0Module) + +trait RRTest1Bundle +{ +} + +trait RRTest1Module extends HasRegMap +{ + regmap(RRTest1Map.map:_*) +} + +class RRTest1(address: BigInt) extends TLRegisterRouter(address, 0, 32, Some(6), 4)( + new TLRegBundle((), _) with RRTest1Bundle)( + new TLRegModule((), _, _) with RRTest1Module)