63 lines
1.8 KiB
Scala
63 lines
1.8 KiB
Scala
// See LICENSE for license details.
|
|
package sifive.blocks.devices.spi
|
|
|
|
import Chisel._
|
|
|
|
class SPIFIFOControl(c: SPIConfigBase) extends SPIBundle(c) {
|
|
val fmt = new SPIFormat(c) with HasSPILength
|
|
val cs = new Bundle with HasSPICSMode
|
|
val wm = new SPIWatermark(c)
|
|
}
|
|
|
|
class SPIFIFO(c: SPIConfigBase) extends Module {
|
|
val io = new Bundle {
|
|
val ctrl = new SPIFIFOControl(c).asInput
|
|
val link = new SPIInnerIO(c)
|
|
val tx = Decoupled(Bits(width = c.frameBits)).flip
|
|
val rx = Decoupled(Bits(width = c.frameBits))
|
|
val ip = new SPIInterrupts().asOutput
|
|
}
|
|
|
|
val txq = Module(new Queue(io.tx.bits, c.txDepth))
|
|
val rxq = Module(new Queue(io.rx.bits, c.rxDepth))
|
|
|
|
txq.io.enq <> io.tx
|
|
io.link.tx <> txq.io.deq
|
|
|
|
val fire_tx = io.link.tx.fire()
|
|
val fire_rx = io.link.rx.fire()
|
|
val rxen = Reg(init = Bool(false))
|
|
|
|
rxq.io.enq.valid := io.link.rx.valid && rxen
|
|
rxq.io.enq.bits := io.link.rx.bits
|
|
io.rx <> rxq.io.deq
|
|
|
|
when (fire_rx) {
|
|
rxen := Bool(false)
|
|
}
|
|
when (fire_tx) {
|
|
rxen := (io.link.fmt.iodir === SPIDirection.Rx)
|
|
}
|
|
|
|
val proto = SPIProtocol.decode(io.link.fmt.proto).zipWithIndex
|
|
val cnt_quot = Mux1H(proto.map { case (s, i) => s -> (io.ctrl.fmt.len >> i) })
|
|
val cnt_rmdr = Mux1H(proto.map { case (s, i) => s -> (io.ctrl.fmt.len(i, 0).orR) })
|
|
io.link.fmt <> io.ctrl.fmt
|
|
io.link.cnt := cnt_quot + cnt_rmdr
|
|
|
|
val cs_mode = RegNext(io.ctrl.cs.mode, SPICSMode.Auto)
|
|
val cs_mode_hold = (cs_mode === SPICSMode.Hold)
|
|
val cs_mode_off = (cs_mode === SPICSMode.Off)
|
|
val cs_update = (cs_mode =/= io.ctrl.cs.mode)
|
|
val cs_clear = !(cs_mode_hold || cs_mode_off)
|
|
|
|
io.link.cs.set := !cs_mode_off
|
|
io.link.cs.clear := cs_update || (fire_tx && cs_clear)
|
|
io.link.cs.hold := Bool(false)
|
|
|
|
io.link.lock := io.link.tx.valid || rxen
|
|
|
|
io.ip.txwm := (txq.io.count < io.ctrl.wm.tx)
|
|
io.ip.rxwm := (rxq.io.count > io.ctrl.wm.rx)
|
|
}
|