2013-05-22 11:10:13 -04:00
|
|
|
from migen.fhdl.std import *
|
2011-12-17 18:29:37 -05:00
|
|
|
from migen.bank.description import *
|
2012-02-06 11:45:31 -05:00
|
|
|
from migen.bank.eventmanager import *
|
2014-07-30 22:23:59 -04:00
|
|
|
from migen.genlib.record import Record
|
2015-07-24 07:57:57 -04:00
|
|
|
from migen.actorlib.fifo import SyncFIFO, AsyncFIFO
|
|
|
|
|
|
|
|
|
|
|
|
def _get_uart_fifo(depth, sink_cd="sys", source_cd="sys"):
|
|
|
|
if sink_cd != source_cd:
|
|
|
|
fifo = AsyncFIFO([("data", 8)], depth)
|
|
|
|
return ClockDomainsRenamer({"write": sink_cd, "read": source_cd})(fifo)
|
|
|
|
else:
|
|
|
|
return SyncFIFO([("data", 8)], depth)
|
2011-12-13 11:33:12 -05:00
|
|
|
|
2015-04-13 10:47:22 -04:00
|
|
|
|
2014-09-24 15:30:25 -04:00
|
|
|
class UART(Module, AutoCSR):
|
2015-05-01 09:58:10 -04:00
|
|
|
def __init__(self, phy,
|
2015-07-24 18:21:59 -04:00
|
|
|
tx_fifo_depth=16,
|
|
|
|
rx_fifo_depth=16,
|
2015-07-19 03:23:35 -04:00
|
|
|
phy_cd="sys"):
|
2015-04-13 10:19:55 -04:00
|
|
|
self._rxtx = CSR(8)
|
2015-05-01 09:58:10 -04:00
|
|
|
self._txfull = CSRStatus()
|
|
|
|
self._rxempty = CSRStatus()
|
2014-09-24 15:30:25 -04:00
|
|
|
|
2015-04-13 10:19:55 -04:00
|
|
|
self.submodules.ev = EventManager()
|
2015-05-01 09:58:10 -04:00
|
|
|
self.ev.tx = EventSourceProcess()
|
|
|
|
self.ev.rx = EventSourceProcess()
|
2015-04-13 10:19:55 -04:00
|
|
|
self.ev.finalize()
|
2015-05-01 09:58:10 -04:00
|
|
|
|
|
|
|
# # #
|
|
|
|
|
2015-07-24 05:03:40 -04:00
|
|
|
# TX
|
2015-07-24 07:57:57 -04:00
|
|
|
tx_fifo = _get_uart_fifo(tx_fifo_depth, source_cd=phy_cd)
|
2015-07-24 05:03:40 -04:00
|
|
|
self.submodules += tx_fifo
|
|
|
|
|
2015-05-01 09:58:10 -04:00
|
|
|
self.comb += [
|
|
|
|
tx_fifo.sink.stb.eq(self._rxtx.re),
|
|
|
|
tx_fifo.sink.data.eq(self._rxtx.r),
|
|
|
|
self._txfull.status.eq(~tx_fifo.sink.ack),
|
2015-07-19 03:23:35 -04:00
|
|
|
Record.connect(tx_fifo.source, phy.sink),
|
2015-07-24 18:21:59 -04:00
|
|
|
# Generate TX IRQ when tx_fifo becomes non-full
|
|
|
|
self.ev.tx.trigger.eq(~tx_fifo.sink.ack)
|
2015-07-24 05:03:40 -04:00
|
|
|
]
|
|
|
|
|
2015-05-01 09:58:10 -04:00
|
|
|
|
2015-07-24 05:03:40 -04:00
|
|
|
# RX
|
2015-07-24 07:57:57 -04:00
|
|
|
rx_fifo = _get_uart_fifo(rx_fifo_depth, sink_cd=phy_cd)
|
2015-07-24 05:03:40 -04:00
|
|
|
self.submodules += rx_fifo
|
|
|
|
|
|
|
|
|
|
|
|
self.comb += [
|
2015-05-01 09:58:10 -04:00
|
|
|
Record.connect(phy.source, rx_fifo.sink),
|
|
|
|
self._rxempty.status.eq(~rx_fifo.source.stb),
|
|
|
|
self._rxtx.w.eq(rx_fifo.source.data),
|
2015-07-19 03:23:35 -04:00
|
|
|
rx_fifo.source.ack.eq(self.ev.rx.clear),
|
2015-07-24 18:21:59 -04:00
|
|
|
# Generate RX IRQ when tx_fifo becomes non-empty
|
|
|
|
self.ev.rx.trigger.eq(~rx_fifo.source.stb)
|
2015-04-13 10:19:55 -04:00
|
|
|
]
|