devices: create periphery keys for all devices
[sifive-blocks.git] / src / main / scala / devices / spi / SPIArbiter.scala
1 // See LICENSE for license details.
2 package sifive.blocks.devices.spi
3
4 import Chisel._
5
6 class SPIInnerIO(c: SPIParamsBase) extends SPILinkIO(c) {
7 val lock = Bool(OUTPUT)
8 }
9
10 class SPIArbiter(c: SPIParamsBase, n: Int) extends Module {
11 val io = new Bundle {
12 val inner = Vec(n, new SPIInnerIO(c)).flip
13 val outer = new SPILinkIO(c)
14 val sel = UInt(INPUT, log2Up(n))
15 }
16
17 val sel = Reg(init = Vec(Bool(true) +: Seq.fill(n-1)(Bool(false))))
18
19 io.outer.tx.valid := Mux1H(sel, io.inner.map(_.tx.valid))
20 io.outer.tx.bits := Mux1H(sel, io.inner.map(_.tx.bits))
21 io.outer.cnt := Mux1H(sel, io.inner.map(_.cnt))
22 io.outer.fmt := Mux1H(sel, io.inner.map(_.fmt))
23 io.outer.cs := Mux1H(sel, io.inner.map(_.cs))
24
25 (io.inner zip sel).foreach { case (inner, s) =>
26 inner.tx.ready := io.outer.tx.ready && s
27 inner.rx.valid := io.outer.rx.valid && s
28 inner.rx.bits := io.outer.rx.bits
29 inner.active := io.outer.active && s
30 }
31
32 val nsel = Vec.tabulate(n)(io.sel === UInt(_))
33 val lock = Mux1H(sel, io.inner.map(_.lock))
34 when (!lock) {
35 sel := nsel
36 when (sel.asUInt =/= nsel.asUInt) {
37 io.outer.cs.clear := Bool(true)
38 }
39 }
40 }