1
0
Fork 0
sifive-blocks/src/main/scala/devices/spi/SPIArbiter.scala

41 lines
1.1 KiB
Scala

// See LICENSE for license details.
package sifive.blocks.devices.spi
import Chisel._
class SPIInnerIO(c: SPIConfigBase) extends SPILinkIO(c) {
val lock = Bool(OUTPUT)
}
class SPIArbiter(c: SPIConfigBase, n: Int) extends Module {
val io = new Bundle {
val inner = Vec(n, new SPIInnerIO(c)).flip
val outer = new SPILinkIO(c)
val sel = UInt(INPUT, log2Up(n))
}
val sel = Reg(init = Vec(Bool(true) +: Seq.fill(n-1)(Bool(false))))
io.outer.tx.valid := Mux1H(sel, io.inner.map(_.tx.valid))
io.outer.tx.bits := Mux1H(sel, io.inner.map(_.tx.bits))
io.outer.cnt := Mux1H(sel, io.inner.map(_.cnt))
io.outer.fmt := Mux1H(sel, io.inner.map(_.fmt))
io.outer.cs := Mux1H(sel, io.inner.map(_.cs))
(io.inner zip sel).foreach { case (inner, s) =>
inner.tx.ready := io.outer.tx.ready && s
inner.rx.valid := io.outer.rx.valid && s
inner.rx.bits := io.outer.rx.bits
inner.active := io.outer.active && s
}
val nsel = Vec.tabulate(n)(io.sel === UInt(_))
val lock = Mux1H(sel, io.inner.map(_.lock))
when (!lock) {
sel := nsel
when (sel.asUInt =/= nsel.asUInt) {
io.outer.cs.clear := Bool(true)
}
}
}