DecoupledDataSource.scala 1.34 KB
Newer Older
1
package chisel.miscutils
Jens Korinth's avatar
Jens Korinth committed
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import Chisel._

/**
 * 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.
 **/
class DecoupledDataSource[T <: Data](gen: T, val size : Int, data: (Int) => T, val repeat: Boolean = true) extends Module {
  val ds  = for (i <- 0 until size) yield data(i) // evaluate data to array
  val io  = new DecoupledDataSourceIO(gen) // interface
  val i   = Reg(UInt(width = log2Up(if (repeat) size else size + 1))) // index
  val rom = Vec.tabulate(size)(n => ds(n)) // ROM with data
  io.out.bits  := rom(i) // current index data
  io.out.valid := i < UInt(size) // valid until exceeded
  when (reset) {
    i := UInt(0)
  }
  .otherwise {
    if (repeat)
      when (io.out.ready && io.out.valid) { i := Mux(i < UInt(size - 1), i + UInt(1), UInt(0)) }
    else
      when (io.out.ready && io.out.valid && i < UInt(size)) { i := i + UInt(1) }
  }
}