1 // See LICENSE for license details.
2 package sifive.blocks.devices.uart
5 import chisel3.experimental.MultiIOModule
6 import freechips.rocketchip.config.Parameters
7 import freechips.rocketchip.regmapper._
8 import freechips.rocketchip.tilelink._
9 import freechips.rocketchip.util._
11 import sifive.blocks.util.{NonBlockingEnqueue, NonBlockingDequeue}
13 case class UARTParams(
18 divisorBits: Int = 16,
24 trait HasUARTParameters {
26 def uartDataBits = c.dataBits
27 def uartStopBits = c.stopBits
28 def uartDivisorInit = c.divisorInit
29 def uartDivisorBits = c.divisorBits
31 def uartOversample = c.oversample
32 def uartOversampleFactor = 1 << uartOversample
33 def uartNSamples = c.nSamples
35 def uartNTxEntries = c.nTxEntries
36 def uartNRxEntries = c.nRxEntries
38 require(uartDivisorInit != 0) // should have been initialized during instantiation
39 require(uartDivisorBits > uartOversample)
40 require(uartOversampleFactor > uartNSamples)
43 abstract class UARTModule(val c: UARTParams)(implicit val p: Parameters)
44 extends Module with HasUARTParameters
46 class UARTPortIO extends Bundle {
47 val txd = Bool(OUTPUT)
51 trait HasUARTTopBundleContents extends Bundle {
52 val port = new UARTPortIO
55 class UARTTx(c: UARTParams)(implicit p: Parameters) extends UARTModule(c)(p) {
58 val in = Decoupled(Bits(width = uartDataBits)).flip
59 val out = Bits(OUTPUT, 1)
60 val div = UInt(INPUT, uartDivisorBits)
61 val nstop = UInt(INPUT, log2Up(uartStopBits))
64 val prescaler = Reg(init = UInt(0, uartDivisorBits))
65 val pulse = (prescaler === UInt(0))
67 private val n = uartDataBits + 1
68 val counter = Reg(init = UInt(0, log2Floor(n + uartStopBits) + 1))
69 val shifter = Reg(Bits(width = n))
70 val out = Reg(init = Bits(1, 1))
73 val plusarg_tx = PlusArg("uart_tx", 1, "Enable/disable the TX to speed up simulation").orR
75 val busy = (counter =/= UInt(0))
76 io.in.ready := io.en && !busy
78 printf("UART TX (%x): %c\n", io.in.bits, io.in.bits)
80 when (io.in.fire() && plusarg_tx) {
81 shifter := Cat(io.in.bits, Bits(0, 1))
82 counter := Mux1H((0 until uartStopBits).map(i =>
83 (io.nstop === UInt(i)) -> UInt(n + i + 1)))
86 prescaler := Mux(pulse, io.div, prescaler - UInt(1))
88 when (pulse && busy) {
89 counter := counter - UInt(1)
90 shifter := Cat(Bits(1, 1), shifter >> 1)
95 class UARTRx(c: UARTParams)(implicit p: Parameters) extends UARTModule(c)(p) {
98 val in = Bits(INPUT, 1)
99 val out = Valid(Bits(width = uartDataBits))
100 val div = UInt(INPUT, uartDivisorBits)
103 val debounce = Reg(init = UInt(0, 2))
104 val debounce_max = (debounce === UInt(3))
105 val debounce_min = (debounce === UInt(0))
107 val prescaler = Reg(UInt(width = uartDivisorBits - uartOversample + 1))
108 val start = Wire(init = Bool(false))
109 val pulse = (prescaler === UInt(0))
111 private val dataCountBits = log2Floor(uartDataBits) + 1
113 val data_count = Reg(UInt(width = dataCountBits))
114 val data_last = (data_count === UInt(0))
115 val sample_count = Reg(UInt(width = uartOversample))
116 val sample_mid = (sample_count === UInt((uartOversampleFactor - uartNSamples + 1) >> 1))
117 val sample_last = (sample_count === UInt(0))
118 val countdown = Cat(data_count, sample_count) - UInt(1)
120 // Compensate for the divisor not being a multiple of the oversampling period.
121 // Let remainder k = (io.div % uartOversampleFactor).
122 // For the last k samples, extend the sampling delay by 1 cycle.
123 val remainder = io.div(uartOversample-1, 0)
124 val extend = (sample_count < remainder) // Pad head: (sample_count > ~remainder)
125 val restore = start || pulse
126 val prescaler_in = Mux(restore, io.div >> uartOversample, prescaler)
127 val prescaler_next = prescaler_in - Mux(restore && extend, UInt(0), UInt(1))
129 val sample = Reg(Bits(width = uartNSamples))
130 val voter = Majority(sample.toBools.toSet)
131 val shifter = Reg(Bits(width = uartDataBits))
133 val valid = Reg(init = Bool(false))
135 io.out.valid := valid
136 io.out.bits := shifter
138 val (s_idle :: s_data :: Nil) = Enum(UInt(), 2)
139 val state = Reg(init = s_idle)
143 when (!(!io.in) && !debounce_min) {
144 debounce := debounce - UInt(1)
147 debounce := debounce + UInt(1)
148 when (debounce_max) {
151 prescaler := prescaler_next
152 data_count := UInt(uartDataBits+1)
153 sample_count := UInt(uartOversampleFactor - 1)
159 prescaler := prescaler_next
161 sample := Cat(sample, io.in)
162 data_count := countdown >> uartOversample
163 sample_count := countdown(uartOversample-1, 0)
170 shifter := Cat(voter, shifter >> 1)
182 class UARTInterrupts extends Bundle {
187 trait HasUARTTopModuleContents extends MultiIOModule with HasUARTParameters with HasRegMap {
188 val io: HasUARTTopBundleContents
189 implicit val p: Parameters
190 def params: UARTParams
193 val txm = Module(new UARTTx(params))
194 val txq = Module(new Queue(txm.io.in.bits, uartNTxEntries))
196 val rxm = Module(new UARTRx(params))
197 val rxq = Module(new Queue(rxm.io.out.bits, uartNRxEntries))
199 val div = Reg(init = UInt(uartDivisorInit, uartDivisorBits))
201 private val stopCountBits = log2Up(uartStopBits)
202 private val txCountBits = log2Floor(uartNTxEntries) + 1
203 private val rxCountBits = log2Floor(uartNRxEntries) + 1
205 val txen = Reg(init = Bool(false))
206 val rxen = Reg(init = Bool(false))
207 val txwm = Reg(init = UInt(0, txCountBits))
208 val rxwm = Reg(init = UInt(0, rxCountBits))
209 val nstop = Reg(init = UInt(0, stopCountBits))
212 txm.io.in <> txq.io.deq
214 txm.io.nstop := nstop
215 io.port.txd := txm.io.out
218 rxm.io.in := io.port.rxd
219 rxq.io.enq <> rxm.io.out
222 val ie = Reg(init = new UARTInterrupts().fromBits(Bits(0)))
223 val ip = Wire(new UARTInterrupts)
225 ip.txwm := (txq.io.count < txwm)
226 ip.rxwm := (rxq.io.count > rxwm)
227 interrupts(0) := (ip.txwm && ie.txwm) || (ip.rxwm && ie.rxwm)
230 UARTCtrlRegs.txfifo -> NonBlockingEnqueue(txq.io.enq),
231 UARTCtrlRegs.rxfifo -> NonBlockingDequeue(rxq.io.deq),
233 UARTCtrlRegs.txctrl -> Seq(
235 RegField(stopCountBits, nstop)),
236 UARTCtrlRegs.rxctrl -> Seq(RegField(1, rxen)),
237 UARTCtrlRegs.txmark -> Seq(RegField(txCountBits, txwm)),
238 UARTCtrlRegs.rxmark -> Seq(RegField(rxCountBits, rxwm)),
240 UARTCtrlRegs.ie -> Seq(
241 RegField(1, ie.txwm),
242 RegField(1, ie.rxwm)),
244 UARTCtrlRegs.ip -> Seq(
245 RegField.r(1, ip.txwm),
246 RegField.r(1, ip.rxwm)),
248 UARTCtrlRegs.div -> Seq(
249 RegField(uartDivisorBits, div))
253 // Magic TL2 Incantation to create a TL2 UART
254 class TLUART(w: Int, c: UARTParams)(implicit p: Parameters)
255 extends TLRegisterRouter(c.address, "serial", Seq("sifive,uart0"), interrupts = 1, beatBytes = w)(
256 new TLRegBundle(c, _) with HasUARTTopBundleContents)(
257 new TLRegModule(c, _, _) with HasUARTTopModuleContents)