DecoupledDataSource.scala 1.88 KB
Newer Older
1
package chisel.miscutils
Jens Korinth's avatar
Jens Korinth committed
2
3
import  chisel3._
import  chisel3.util._
Jens Korinth's avatar
Jens Korinth committed
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

/**
 * Interface for DecoupledDataSource.
 **/
class DecoupledDataSourceIO[T <: Data](gen: T) extends Bundle {
  val out = Decoupled(gen.cloneType)
}

/**
 * Data source providing fixed data via Decoupled interface.
 * Provides the data given via Decoupled handshakes; if repeat
 * is true, data is wrapped around.
 * @param gen Type.
 * @param size Total number of elements.
 * @param data Function providing data for each index
 * @param repeat If true, will always have data via wrap-around,
                 otherwise valid will go low after data was
		 consumed.
 **/
Jens Korinth's avatar
Jens Korinth committed
23
24
25
26
27
28
29
30
class DecoupledDataSource[T <: Data](gen: T,
                                     val size : Int,
                                     val data: (Int) => T,
                                     val repeat: Boolean = true)
                                    (implicit l: Logging.Level)
    extends Module with Logging {
  cinfo("size = %d, repeat = %s, addrWidth = %d".format(size,
    if (repeat) "true" else "false", log2Ceil(if (repeat) size else size + 1)))
31

Jens Korinth's avatar
Jens Korinth committed
32
  val ds  = for (i <- 0 until size) yield data(i) // evaluate data to array
Jens Korinth's avatar
Jens Korinth committed
33
34
  val io  = IO(new DecoupledDataSourceIO(gen)) // interface
  val i   = Reg(UInt(log2Ceil(if (repeat) size else size + 1).W)) // index
Jens Korinth's avatar
Jens Korinth committed
35
36
  val rom = Vec.tabulate(size)(n => ds(n)) // ROM with data
  io.out.bits  := rom(i) // current index data
Jens Korinth's avatar
Jens Korinth committed
37
  io.out.valid := !reset && i < size.U // valid until exceeded
Jens Korinth's avatar
Jens Korinth committed
38
  when (reset) {
Jens Korinth's avatar
Jens Korinth committed
39
    i := 0.U
Jens Korinth's avatar
Jens Korinth committed
40
41
  }
  .otherwise {
42
43
44
45
46
47
48
49
50
51
52
53
54
    when (io.out.ready && io.out.valid) {
      val next = if (repeat) {
        if (math.pow(2, log2Ceil(size)).toInt == size) {
          i + 1.U
        } else {
          Mux((i + 1.U) < size.U, i + 1.U, 0.U)
        }
      } else {
        Mux(i < size.U, i + 1.U, i)
      }
      info(p"i = $i -> $next, bits = 0x${Hexadecimal(io.out.bits.asUInt())}")
      i := next
    }
Jens Korinth's avatar
Jens Korinth committed
55
56
  }
}