49 lines
1.2 KiB
Scala
49 lines
1.2 KiB
Scala
|
// See LICENSE.SiFive for license details.
|
||
|
// See LICENSE.Berkeley for license details.
|
||
|
|
||
|
package freechips.rocketchip.util
|
||
|
|
||
|
import Chisel._
|
||
|
|
||
|
/** Takes in data on one decoupled interface and broadcasts it
|
||
|
* to N decoupled output interfaces.
|
||
|
*/
|
||
|
class Broadcaster[T <: Data](typ: T, n: Int) extends Module {
|
||
|
val io = new Bundle {
|
||
|
val in = Decoupled(typ).flip
|
||
|
val out = Vec(n, Decoupled(typ))
|
||
|
}
|
||
|
|
||
|
require (n > 0)
|
||
|
|
||
|
if (n == 1) {
|
||
|
io.out.head <> io.in
|
||
|
} else {
|
||
|
val idx = Reg(init = UInt(0, log2Up(n)))
|
||
|
val save = Reg(typ)
|
||
|
|
||
|
io.out.head.valid := idx === UInt(0) && io.in.valid
|
||
|
io.out.head.bits := io.in.bits
|
||
|
for (i <- 1 until n) {
|
||
|
io.out(i).valid := idx === UInt(i)
|
||
|
io.out(i).bits := save
|
||
|
}
|
||
|
io.in.ready := io.out.head.ready && idx === UInt(0)
|
||
|
|
||
|
when (io.in.fire()) { save := io.in.bits }
|
||
|
|
||
|
when (io.out(idx).fire()) {
|
||
|
when (idx === UInt(n - 1)) { idx := UInt(0) }
|
||
|
.otherwise { idx := idx + UInt(1) }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
object Broadcaster {
|
||
|
def apply[T <: Data](in: DecoupledIO[T], n: Int): Vec[DecoupledIO[T]] = {
|
||
|
val split = Module(new Broadcaster(in.bits, n))
|
||
|
split.io.in <> in
|
||
|
split.io.out
|
||
|
}
|
||
|
}
|