AxiMuxSuite.scala 2.91 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
11
12
/**
 * Read test module for AxiMux:
 * Checks parallel reads from multiple AXI-MM masters.
 * @param n Number of parallel masters.
 * @param axi Implicit AXI interface configuration.
 **/
Jens Korinth's avatar
Jens Korinth committed
13
14
15
16
class AxiMuxReadTestModule(val n: Int)(implicit axi: Axi4.Configuration) extends Module {
  val io = IO(new Bundle {
    val afa_deq_ready = Output(UInt(n.W))
    val afa_deq_valid = Output(UInt(n.W))
Jens Korinth's avatar
Jens Korinth committed
17
    val afa_deq_bits  = Input(Vec(n, UInt(axi.dataWidth)))
Jens Korinth's avatar
Jens Korinth committed
18
  })
19
  val mux = Module(new AxiMux(n))
Jens Korinth's avatar
Jens Korinth committed
20
  private val asmcfg = AxiSlaveModelConfiguration(size = Some(n * 128))
21
  val saxi = Module(new AxiSlaveModel(asmcfg))
Jens Korinth's avatar
Jens Korinth committed
22
  private val afacfg = AxiFifoAdapterConfiguration(fifoDepth = 8, burstSize = Some(4))
23
24
25
26
27
  val afa = for (i <- 0 until n) yield Module(new AxiFifoAdapter(afacfg))
  val bases = (0 until n) map (_ * 128 * (axi.dataWidth / 8))

  mux.io.maxi <> saxi.io.saxi
  ((afa zip mux.io.saxi) zip bases) map { case ((a, s), b) => {
Jens Korinth's avatar
Jens Korinth committed
28
29
30
    a.io.maxi      <> s
    a.io.base      := b.U
    a.io.deq.ready := true.B
31
  }}
Jens Korinth's avatar
Jens Korinth committed
32
33
34
35
36
  afa.zipWithIndex map { case (a, i) =>
    io.afa_deq_ready(i) := a.io.deq.ready
    io.afa_deq_valid(i) := a.io.deq.valid
    io.afa_deq_bits(i)  <> a.io.deq.bits
  }
37
38
39
40
41
42
43
44
}

/**
 * Unit test for reading across an AxiMux module:
 * Connects multiple AxiFifoAdapters with increasing base addresses 
 * to single AxiSlaveModel and checks the data for correctness.
 * No performance measurement!
 * @param m Test module.
Jens Korinth's avatar
Jens Korinth committed
45
 * @param isTrace if true, will enable tracing in Chisel PeekPokeTester.
46
 **/
Jens Korinth's avatar
Jens Korinth committed
47
48
class AxiMuxReadTester(m: AxiMuxReadTestModule)
                      (implicit axi: Axi4.Configuration) extends PeekPokeTester(m) {
49
  implicit val tester = this
Jens Korinth's avatar
Jens Korinth committed
50
  AxiSlaveModel.fillWithLinearSeq(m.saxi, axi.dataWidth)
51
52
53
54
  reset(10)

  var counter: Array[Int] = Array.fill[Int](m.n)(0)
  def finished: Boolean = counter map (_ >= 128) reduce (_&&_)
Jens Korinth's avatar
Jens Korinth committed
55
  def handshake(i: Int) = peek(m.io.afa_deq_ready) != 0 && peek(m.io.afa_deq_valid) != 0
56
57
58
  
  while (! finished) {
    for (i <- 0 until m.n if handshake(i)) {
Jens Korinth's avatar
Jens Korinth committed
59
      val ok = peek(m.io.afa_deq_bits(i)) == counter(i) + i * 128
60
61
62
63
64
65
66
67
68
69
      assert(ok)
      if (ok) counter(i) += 1
    }
    step(1)
  }
}

/**
 * Unit test suit for AxiMux.
 **/
Jens Korinth's avatar
Jens Korinth committed
70
71
72
class AxiMuxSuite extends ChiselFlatSpec {
  val chiselArgs = Array("--fint-write-vcd")
  implicit val axi = Axi4.Configuration(addrWidth = AddrWidth(32), dataWidth = DataWidth(64))
73
74

  private def testMuxRead(n: Int) = {
Jens Korinth's avatar
Jens Korinth committed
75
76
77
    val args = chiselArgs ++ Array("--target-dir", "test/AxiMuxSuite/%02d".format(n))
    Driver.execute(args, () => new AxiMuxReadTestModule(n))
      { m => new AxiMuxReadTester(m) }
78
79
  }

Jens Korinth's avatar
Jens Korinth committed
80
81
82
83
  "testMuxRead1" should "be ok" in  { testMuxRead( 1) }
  "testMuxRead2" should "be ok" in  { testMuxRead( 2) }
  "testMuxRead3" should "be ok" in  { testMuxRead( 3) }
  "testMuxRead10" should "be ok" in { testMuxRead(10) }
84
}