SlidingWindowSuite.scala 4.24 KB
Newer Older
Jens Korinth's avatar
Jens Korinth committed
1
2
3
4
package chisel.axiutils.axi4
import  chisel.axi._
import  chisel.axiutils._
import  chisel.miscutils.Logging
Jens Korinth's avatar
Jens Korinth committed
5
6
7
8
import  chisel3._
import  chisel3.util._
import  chisel3.iotesters.{ChiselFlatSpec, Driver, PeekPokeTester}

Jens Korinth's avatar
Jens Korinth committed
9
10
/** Test module for SlidingWindow:
 *  Connects SlidingWindow instance to AXI slave model.
11
 **/
Jens Korinth's avatar
Jens Korinth committed
12
13
14
class SlidingWindowTestModule[T <: Data](cfg: SlidingWindow.Configuration[T])
                                        (implicit val axi: Axi4.Configuration,
                                         logLevel: Logging.Level) extends Module {
Jens Korinth's avatar
Jens Korinth committed
15
16
17
18
19
  val io = IO(new Bundle {
    val ready          = Input(Bool())
    val asw_data_valid = Output(Bool())
    val asw_data_bits  = Output(UInt(axi.dataWidth))
  })
20
21

  /** AXI memory model **/
Jens Korinth's avatar
Jens Korinth committed
22
  val saxi = Module(new SlaveModel(SlaveModel.Configuration(size = Some(1024))))
23
  /** AxiSlidingWindow instance (DUT) **/
Jens Korinth's avatar
Jens Korinth committed
24
  val asw = Module(new SlidingWindow(cfg))
25
  asw.io.maxi <> saxi.io.saxi
Jens Korinth's avatar
Jens Korinth committed
26
27
  val ready = RegInit(false.B)
  ready := io.ready
28
  asw.io.data.ready := ready
Jens Korinth's avatar
Jens Korinth committed
29
  val base = RegInit(0.U(axi.addrWidth: chisel3.internal.firrtl.Width))
30
  asw.io.base := base
Jens Korinth's avatar
Jens Korinth committed
31
32
  io.asw_data_valid := asw.io.data.valid
  io.asw_data_bits  := asw.io.data.bits
33
34
}

Jens Korinth's avatar
Jens Korinth committed
35
36
37
38
/** Tester class for SlidingWindow:
 *  Fills memory model with increasing integers of configured element width,
 *  then checks sliding window against expected values at each step.
 *  Does not operate at full speed, each step has at least one cycle delay.
39
 **/
Jens Korinth's avatar
Jens Korinth committed
40
class SlidingWindowTester[T <: Data](m: SlidingWindowTestModule[T]) extends PeekPokeTester(m) {
41
  // fill memory model
Jens Korinth's avatar
Jens Korinth committed
42
  SlaveModel.fillWithLinearSeq(m.saxi, m.axi.dataWidth)(m.axi, this)
43
44
45
46
47
  reset(10) // reset
  
  var noErrors = true
  var start = 0
  val maxData = scala.math.pow(2, m.asw.cfg.width).toInt
Jens Korinth's avatar
Jens Korinth committed
48
  val totalSteps = (m.saxi.cfg.size * m.axi.dataWidth) / m.asw.cfg.width - m.asw.cfg.depth
49
50
  printf("mem size = %d bytes, total steps = %d".format(m.saxi.cfg.size, totalSteps))
  // wait for data to be valid
Jens Korinth's avatar
Jens Korinth committed
51
  while (peek(m.io.asw_data_valid) == 0) step(1)
52
53
54
  // check all sliding windows within size of memory slave (no border handling)
  for (i <- 0 until totalSteps if noErrors) {
    val expected = (0 until m.asw.cfg.depth) map (i => (i + start) % maxData)
Jens Korinth's avatar
Jens Korinth committed
55
    val found = (0 until m.asw.cfg.depth) map (i => peek(m.io.asw_data_bits) & (1 << (m.asw.cfg.depth - i - 1)))
56
57
58
    noErrors = expected.equals(found)
    if (!noErrors)
      println("Mismatch at step #%d: expected %s, found %s".format(start, expected.toString, found.toString))
Jens Korinth's avatar
Jens Korinth committed
59
    assert(noErrors, "sliding window #%d should match".format(i))
60
61
    start += 1
    // advance simulation with handshake
Jens Korinth's avatar
Jens Korinth committed
62
    poke(m.io.ready, true)
63
    step(1)
Jens Korinth's avatar
Jens Korinth committed
64
    poke(m.io.ready, false)
65
    // wait for next valid
Jens Korinth's avatar
Jens Korinth committed
66
    while (peek(m.io.asw_data_valid) == 0) step(1)
67
68
69
70
  }
}

/** Unit test suite for AxiSlidingWindow. **/
Jens Korinth's avatar
Jens Korinth committed
71
72
class SlidingWindowSuite extends ChiselFlatSpec {
  implicit val logLevel = Logging.Level.Info
Jens Korinth's avatar
Jens Korinth committed
73
74
  val chiselArgs = Array("--fint-write-vcd")
  implicit val axi: Axi4.Configuration = Axi4.Configuration(addrWidth = AddrWidth(32), dataWidth = DataWidth(64))
75
  implicit val afa: AxiFifoAdapter.Configuration = AxiFifoAdapter.Configuration(fifoDepth = 16)
76

77
  private def slidingWindow(width: Int, depth: Int)(implicit afa: AxiFifoAdapter.Configuration) = {
Jens Korinth's avatar
Jens Korinth committed
78
    val args = chiselArgs ++ Array("--target-dir", "test/slidingWindow/%dx%d".format(width, depth))
Jens Korinth's avatar
Jens Korinth committed
79
80
81
82
83
84
    val cfg = SlidingWindow.Configuration(gen = UInt(width.W),
                                          depth = depth,
                                          width = width,
                                          afa = afa)
    Driver.execute(args, () => new SlidingWindowTestModule(cfg))
      { m => new SlidingWindowTester(m) }
85
86
  }

Jens Korinth's avatar
Jens Korinth committed
87
88
89
90
91
92
93
94
95
  "slidingWindow_8_3" should "be ok" in    { slidingWindow(8, 3) }
  "slidingWindow_16_8" should "be ok" in   { slidingWindow(16, 3) }
  "slidingWindow_32_8" should "be ok" in   { slidingWindow(32, 3) }
  "slidingWindow_8_10" should "be ok" in   { slidingWindow(8, 10) }
  "slidingWindow_16_10" should "be ok" in  { slidingWindow(16, 10) }
  "slidingWindow_32_10" should "be ok" in  { slidingWindow(32, 10) }
  "slidingWindow_8_16" should "be ok" in   { slidingWindow(8, 16) }
  "slidingWindow_16_16" should "be ok" in  { slidingWindow(16, 16) }
  "slidingWindow_32_16" should "be ok" in  { slidingWindow(32, 16) }
96
}