1 // See LICENSE for license details.
2 package sifive.blocks.devices.uart
7 import uncore.tilelink2._
10 import rocketchip.PeripheryBusConfig
11 import sifive.blocks.util.{NonBlockingEnqueue, NonBlockingDequeue}
13 case class UARTConfig(
17 divisorBits: Int = 16,
23 trait HasUARTParameters {
25 val uartDataBits = c.dataBits
26 val uartStopBits = c.stopBits
27 val uartDivisorBits = c.divisorBits
29 val uartOversample = c.oversample
30 val uartOversampleFactor = 1 << uartOversample
31 val uartNSamples = c.nSamples
33 val uartNTxEntries = c.nTxEntries
34 val uartNRxEntries = c.nRxEntries
36 require(uartDivisorBits > uartOversample)
37 require(uartOversampleFactor > uartNSamples)
40 abstract class UARTModule(val c: UARTConfig)(implicit val p: Parameters)
41 extends Module with HasUARTParameters
43 class UARTPortIO extends Bundle {
44 val txd = Bool(OUTPUT)
48 trait MixUARTParameters {
49 implicit val p: Parameters
50 val params: UARTConfig
54 trait UARTTopBundle extends Bundle with MixUARTParameters with HasUARTParameters {
55 val port = new UARTPortIO
58 class UARTTx(c: UARTConfig)(implicit p: Parameters) extends UARTModule(c)(p) {
61 val in = Decoupled(Bits(width = uartDataBits)).flip
62 val out = Bits(OUTPUT, 1)
63 val div = UInt(INPUT, uartDivisorBits)
64 val nstop = UInt(INPUT, log2Up(uartStopBits))
67 val prescaler = Reg(init = UInt(0, uartDivisorBits))
68 val pulse = (prescaler === UInt(0))
70 private val n = uartDataBits + 1
71 val counter = Reg(init = UInt(0, log2Floor(n + uartStopBits) + 1))
72 val shifter = Reg(Bits(width = n))
73 val out = Reg(init = Bits(1, 1))
76 val busy = (counter =/= UInt(0))
77 io.in.ready := io.en && !busy
79 printf("%c", io.in.bits)
80 shifter := Cat(io.in.bits, Bits(0, 1))
81 counter := Mux1H((0 until uartStopBits).map(i =>
82 (io.nstop === UInt(i)) -> UInt(n + i + 1)))
85 prescaler := Mux(pulse, io.div, prescaler - UInt(1))
87 when (pulse && busy) {
88 counter := counter - UInt(1)
89 shifter := Cat(Bits(1, 1), shifter >> 1)
94 class UARTRx(c: UARTConfig)(implicit p: Parameters) extends UARTModule(c)(p) {
97 val in = Bits(INPUT, 1)
98 val out = Valid(Bits(width = uartDataBits))
99 val div = UInt(INPUT, uartDivisorBits)
102 val debounce = Reg(init = UInt(0, 2))
103 val debounce_max = (debounce === UInt(3))
104 val debounce_min = (debounce === UInt(0))
106 val prescaler = Reg(init = UInt(0, uartDivisorBits - uartOversample))
107 val start = Wire(init = Bool(false))
108 val busy = Wire(init = Bool(false))
109 val pulse = (prescaler === UInt(0)) && busy
112 prescaler := prescaler - UInt(1)
114 when (start || pulse) {
115 prescaler := io.div >> uartOversample
118 val sample = Reg(Bits(width = uartNSamples))
119 val voter = new Majority(sample.toBools.toSet)
121 sample := Cat(sample, io.in)
124 private val delay0 = (uartOversampleFactor + uartNSamples) >> 1
125 private val delay1 = uartOversampleFactor
127 val timer = Reg(UInt(width = uartOversample + 1))
128 val counter = Reg(UInt(width = log2Floor(uartDataBits) + 1))
129 val shifter = Reg(Bits(width = uartDataBits))
130 val expire = (timer === UInt(0)) && pulse
132 val sched = Wire(init = Bool(false))
134 timer := timer - UInt(1)
137 timer := UInt(delay1-1)
140 val valid = Reg(init = Bool(false))
142 io.out.valid := valid
143 io.out.bits := shifter
145 val (s_idle :: s_start :: s_data :: Nil) = Enum(UInt(), 3)
146 val state = Reg(init = s_idle)
150 when (!(!io.in) && !debounce_min) {
151 debounce := debounce - UInt(1)
154 debounce := debounce + UInt(1)
155 when (debounce_max) {
158 timer := UInt(delay0-1)
171 counter := UInt(uartDataBits)
179 counter := counter - UInt(1)
180 when (counter === UInt(0)) {
184 shifter := Cat(voter.out, shifter >> 1)
196 class UARTInterrupts extends Bundle {
201 trait UARTTopModule extends Module with MixUARTParameters with HasUARTParameters with HasRegMap {
202 val io: UARTTopBundle
204 val txm = Module(new UARTTx(c))
205 val txq = Module(new Queue(txm.io.in.bits, uartNTxEntries))
207 val rxm = Module(new UARTRx(c))
208 val rxq = Module(new Queue(rxm.io.out.bits, uartNRxEntries))
210 val divinit = 542 // (62.5MHz / 115200)
211 val div = Reg(init = UInt(divinit, uartDivisorBits))
213 private val stopCountBits = log2Up(uartStopBits)
214 private val txCountBits = log2Floor(uartNTxEntries) + 1
215 private val rxCountBits = log2Floor(uartNRxEntries) + 1
217 val txen = Reg(init = Bool(false))
218 val rxen = Reg(init = Bool(false))
219 val txwm = Reg(init = UInt(0, txCountBits))
220 val rxwm = Reg(init = UInt(0, rxCountBits))
221 val nstop = Reg(init = UInt(0, stopCountBits))
224 txm.io.in <> txq.io.deq
226 txm.io.nstop := nstop
227 io.port.txd := txm.io.out
230 rxm.io.in := io.port.rxd
231 rxq.io.enq <> rxm.io.out
234 val ie = Reg(init = new UARTInterrupts().fromBits(Bits(0)))
235 val ip = Wire(new UARTInterrupts)
237 ip.txwm := (txq.io.count < txwm)
238 ip.rxwm := (rxq.io.count > rxwm)
239 interrupts(0) := (ip.txwm && ie.txwm) || (ip.rxwm && ie.rxwm)
242 UARTCtrlRegs.txfifo -> NonBlockingEnqueue(txq.io.enq),
243 UARTCtrlRegs.rxfifo -> NonBlockingDequeue(rxq.io.deq),
245 UARTCtrlRegs.txctrl -> Seq(
247 RegField(stopCountBits, nstop)),
248 UARTCtrlRegs.rxctrl -> Seq(RegField(1, rxen)),
249 UARTCtrlRegs.txmark -> Seq(RegField(txCountBits, txwm)),
250 UARTCtrlRegs.rxmark -> Seq(RegField(rxCountBits, rxwm)),
252 UARTCtrlRegs.ie -> Seq(
253 RegField(1, ie.txwm),
254 RegField(1, ie.rxwm)),
256 UARTCtrlRegs.ip -> Seq(
257 RegField.r(1, ip.txwm),
258 RegField.r(1, ip.rxwm)),
260 UARTCtrlRegs.div -> Seq(
261 RegField(uartDivisorBits, div))
265 class Majority(in: Set[Bool]) {
266 private val n = (in.size >> 1) + 1
267 private val clauses = in.subsets(n).map(_.reduce(_ && _))
268 val out = clauses.reduce(_ || _)
271 // Magic TL2 Incantation to create a TL2 Slave
272 class UART(c: UARTConfig)(implicit p: Parameters)
273 extends TLRegisterRouter(c.address, interrupts = 1, beatBytes = p(PeripheryBusConfig).beatBytes)(
274 new TLRegBundle(c, _) with UARTTopBundle)(
275 new TLRegModule(c, _, _) with UARTTopModule)