tilelink2: RegisterRouter Unit Test
This commit is contained in:
		| @@ -39,7 +39,7 @@ class UnitTestSuite(implicit p: Parameters) extends Module { | |||||||
|     state := Mux(test_idx === UInt(tests.size - 1), s_done, s_start) |     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.start.valid := Bool(false) | ||||||
|   timer.io.stop.valid := Bool(false) |   timer.io.stop.valid := Bool(false) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -179,13 +179,15 @@ class TLFuzzer(nOperations: Int, inFlight: Int = 32) extends LazyModule | |||||||
| class TLFuzzRAM extends LazyModule | class TLFuzzRAM extends LazyModule | ||||||
| { | { | ||||||
|   val model = LazyModule(new TLRAMModel) |   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 xbar = LazyModule(new TLXbar) | ||||||
|   val fuzz = LazyModule(new TLFuzzer(1000)) |   val fuzz = LazyModule(new TLFuzzer(5000)) | ||||||
|  |  | ||||||
|   model.node := fuzz.node |   model.node := fuzz.node | ||||||
|   xbar.node := TLWidthWidget(TLHintHandler(model.node), 16) |   xbar.node := TLWidthWidget(TLHintHandler(model.node), 16) | ||||||
|   ram.node := TLFragmenter(TLBuffer(xbar.node), 4, 256) |   ram.node := TLFragmenter(TLBuffer(xbar.node), 4, 256) | ||||||
|  |   gpio.node := TLFragmenter(TLBuffer(xbar.node), 4, 32) | ||||||
|  |  | ||||||
|   lazy val module = new LazyModuleImp(this) with HasUnitTestIO { |   lazy val module = new LazyModuleImp(this) with HasUnitTestIO { | ||||||
|     io.finished := fuzz.module.io.finished |     io.finished := fuzz.module.io.finished | ||||||
|   | |||||||
| @@ -223,7 +223,7 @@ class TLRAMModel extends LazyModule | |||||||
|             when (!shadow.valid) { |             when (!shadow.valid) { | ||||||
|               printf("G 0x%x := undefined\n", d_addr_hi << shift | UInt(i)) |               printf("G 0x%x := undefined\n", d_addr_hi << shift | UInt(i)) | ||||||
|             } .otherwise { |             } .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) |               assert (shadow.value === got) | ||||||
|             } |             } | ||||||
|           } |           } | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ object LFSR16Seed | |||||||
|   def apply(seed: Int): UInt = |   def apply(seed: Int): UInt = | ||||||
|   { |   { | ||||||
|     val width = 16 |     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 := Cat(lfsr(0)^lfsr(2)^lfsr(3)^lfsr(5), lfsr(width-1,1)) | ||||||
|     lfsr |     lfsr | ||||||
|   } |   } | ||||||
| @@ -39,12 +39,11 @@ class RRTestCombinational(val bits: Int, rvalid: Bool => Bool, wready: Bool => B | |||||||
|  |  | ||||||
| object RRTestCombinational | object RRTestCombinational | ||||||
| { | { | ||||||
|   private var seed = 0 |   private var seed = 42 | ||||||
|   def always: Bool => Bool = _ => Bool(true) |   def always: Bool => Bool = _ => Bool(true) | ||||||
|   def random: Bool => Bool = { |   def random: Bool => Bool = { | ||||||
|     seed = seed + 1 |     seed = seed + 1 | ||||||
|     val lfsr = LFSR16Seed(seed) |     _ => LFSR16Seed(seed)(0) | ||||||
|     _ => lfsr(0) |  | ||||||
|   } |   } | ||||||
|   def delay(x: Int): Bool => Bool = { fire => |   def delay(x: Int): Bool => Bool = { fire => | ||||||
|     val reg = RegInit(UInt(0, width = log2Ceil(x+1))) |     val reg = RegInit(UInt(0, width = log2Ceil(x+1))) | ||||||
| @@ -96,32 +95,40 @@ class RRTestRequest(val bits: Int, | |||||||
|  |  | ||||||
| object RRTestRequest | object RRTestRequest | ||||||
| { | { | ||||||
|   private var seed = 0 |   private var seed = 1231 | ||||||
|   def pipe(x: Int): (Bool, Bool, UInt) => (Bool, Bool, UInt) = { (ivalid, oready, idata) => |   def pipe(x: Int): (Bool, Bool, UInt) => (Bool, Bool, UInt) = { (ivalid, oready, idata) => | ||||||
|     val full = RegInit(Vec.fill(x)(Bool(false))) |     val full = RegInit(Vec.fill(x)(Bool(false))) | ||||||
|     val ready = Wire(Vec.fill(x)(Bool())) |     val ready = Wire(Vec(x, Bool())) | ||||||
|     val data = Reg(Vec.fill(x)(UInt(width = idata.getWidth))) |     val data = Reg(Vec(x, UInt(width = idata.getWidth))) | ||||||
|     // Construct a classic bubble-filling pipeline |     // 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)) { data(0) := idata } | ||||||
|  |     when (ready(0)) { full(0) := ivalid } | ||||||
|     ((ready.init zip ready.tail) zip full.init) foreach { case ((self, next), full) => |     ((ready.init zip ready.tail) zip full.init) foreach { case ((self, next), full) => | ||||||
|       self := next || !full |       self := next || !full | ||||||
|     } |     } | ||||||
|     ((data.init zip data.tail) zip ready.tail) foreach { case ((prev, self), ready) => |     ((data.init zip data.tail) zip ready.tail) foreach { case ((prev, self), ready) => | ||||||
|       when (ready) { self := prev } |       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) = { |   def busy: (Bool, Bool, UInt) => (Bool, Bool, UInt) = { | ||||||
|     seed = seed + 1 |     seed = seed + 1 | ||||||
|     val lfsr = LFSR16Seed(seed) |  | ||||||
|     (ivalid, oready, idata) => { |     (ivalid, oready, idata) => { | ||||||
|  |       val lfsr = LFSR16Seed(seed) | ||||||
|       val busy = RegInit(Bool(false)) |       val busy = RegInit(Bool(false)) | ||||||
|  |       val data = Reg(UInt(width = idata.getWidth)) | ||||||
|       val progress = lfsr(0) |       val progress = lfsr(0) | ||||||
|       when (progress) { |       when (progress) { | ||||||
|         busy := Mux(busy, !oready, ivalid) |         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, |   def request(bits: Int, | ||||||
| @@ -140,3 +147,76 @@ object RRTestRequest | |||||||
|         (request.io.wiready, request.io.wovalid) }) |         (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) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user