AxiSlidingWindowSuite.scala 4.03 KB
Newer Older
1
package chisel.axiutils
Jens Korinth's avatar
Jens Korinth committed
2
3
4
5
6
import  chisel3._
import  chisel3.util._
import  chisel3.iotesters.{ChiselFlatSpec, Driver, PeekPokeTester}
import  chisel.axi._

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

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

/**
 * Tester class for AxiSlidingWindow:
 * 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.
 **/
Jens Korinth's avatar
Jens Korinth committed
39
class AxiSlidingWindowTester[T <: Data](m: AxiSlidingWindowTestModule[T]) extends PeekPokeTester(m) {
40
  // fill memory model
Jens Korinth's avatar
Jens Korinth committed
41
  AxiSlaveModel.fillWithLinearSeq(m.saxi, m.axi.dataWidth)(m.axi, this)
42
43
44
45
46
  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
47
  val totalSteps = (m.saxi.cfg.size * m.axi.dataWidth) / m.asw.cfg.width - m.asw.cfg.depth
48
49
  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
50
  while (peek(m.io.asw_data_valid) == 0) step(1)
51
52
53
  // 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
54
    val found = (0 until m.asw.cfg.depth) map (i => peek(m.io.asw_data_bits) & (1 << (m.asw.cfg.depth - i - 1)))
55
56
57
    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
58
    assert(noErrors, "sliding window #%d should match".format(i))
59
60
    start += 1
    // advance simulation with handshake
Jens Korinth's avatar
Jens Korinth committed
61
    poke(m.io.ready, true)
62
    step(1)
Jens Korinth's avatar
Jens Korinth committed
63
    poke(m.io.ready, false)
64
    // wait for next valid
Jens Korinth's avatar
Jens Korinth committed
65
    while (peek(m.io.asw_data_valid) == 0) step(1)
66
67
68
69
  }
}

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

  private def slidingWindow(width: Int, depth: Int)(implicit afa: AxiFifoAdapterConfiguration) = {
Jens Korinth's avatar
Jens Korinth committed
76
    val args = chiselArgs ++ Array("--target-dir", "test/slidingWindow/%dx%d".format(width, depth))
77
    val cfg = AxiSlidingWindowConfiguration(
Jens Korinth's avatar
Jens Korinth committed
78
        gen = UInt(width.W),
79
80
81
82
        depth = depth,
        width = width,
        afa = afa
      )
Jens Korinth's avatar
Jens Korinth committed
83
84
    Driver.execute(args, () => new AxiSlidingWindowTestModule(cfg))
      { m => new AxiSlidingWindowTester(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
}