misoclib/com/uart: cleanup and add irq condition parameters

- reintroduce RX/TX split (ease comprehension)
- use FIFO wrapper function from Migen.
- add tx_irq_condition and rx_irq_condition
This commit is contained in:
Florent Kermarrec 2015-07-24 11:03:40 +02:00
parent b1ea3340f3
commit d73d75007e
1 changed files with 26 additions and 19 deletions

View File

@ -2,13 +2,13 @@ from migen.fhdl.std import *
from migen.bank.description import * from migen.bank.description import *
from migen.bank.eventmanager import * from migen.bank.eventmanager import *
from migen.genlib.record import Record from migen.genlib.record import Record
from migen.actorlib.fifo import SyncFIFO, AsyncFIFO from migen.actorlib.fifo import FIFO
class UART(Module, AutoCSR): class UART(Module, AutoCSR):
def __init__(self, phy, def __init__(self, phy,
tx_fifo_depth=16, tx_fifo_depth=16, tx_irq_condition="empty",
rx_fifo_depth=16, rx_fifo_depth=16, rx_irq_condition="non-empty",
phy_cd="sys"): phy_cd="sys"):
self._rxtx = CSR(8) self._rxtx = CSR(8)
self._txfull = CSRStatus() self._txfull = CSRStatus()
@ -21,30 +21,37 @@ class UART(Module, AutoCSR):
# # # # # #
if phy_cd == "sys": # TX
tx_fifo = SyncFIFO([("data", 8)], tx_fifo_depth) tx_fifo = FIFO([("data", 8)], tx_fifo_depth, source_cd=phy_cd)
rx_fifo = SyncFIFO([("data", 8)], rx_fifo_depth) self.submodules += tx_fifo
# Generate TX IRQ when tx_fifo becomes empty
tx_irq = tx_fifo.source.stb tx_irqs = {
else: "empty": tx_fifo.source.stb,
tx_fifo = ClockDomainsRenamer({"write": "sys", "read": phy_cd})( "non-full": ~tx_fifo.sink.ack
AsyncFIFO([("data", 8)], tx_fifo_depth)) }
rx_fifo = ClockDomainsRenamer({"write": phy_cd, "read": "sys"})(
AsyncFIFO([("data", 8)], rx_fifo_depth))
# Generate TX IRQ when tx_fifo becomes non-full
tx_irq = ~tx_fifo.sink.ack
self.submodules += tx_fifo, rx_fifo
self.comb += [ self.comb += [
tx_fifo.sink.stb.eq(self._rxtx.re), tx_fifo.sink.stb.eq(self._rxtx.re),
tx_fifo.sink.data.eq(self._rxtx.r), tx_fifo.sink.data.eq(self._rxtx.r),
self._txfull.status.eq(~tx_fifo.sink.ack), self._txfull.status.eq(~tx_fifo.sink.ack),
Record.connect(tx_fifo.source, phy.sink), Record.connect(tx_fifo.source, phy.sink),
self.ev.tx.trigger.eq(tx_irq), self.ev.tx.trigger.eq(tx_irqs[tx_irq_condition])
]
# RX
rx_fifo = FIFO([("data", 8)], rx_fifo_depth, sink_cd=phy_cd)
self.submodules += rx_fifo
rx_irqs = {
"non-empty": ~rx_fifo.source.stb,
"full": rx_fifo.sink.ack
}
self.comb += [
Record.connect(phy.source, rx_fifo.sink), Record.connect(phy.source, rx_fifo.sink),
self._rxempty.status.eq(~rx_fifo.source.stb), self._rxempty.status.eq(~rx_fifo.source.stb),
self._rxtx.w.eq(rx_fifo.source.data), self._rxtx.w.eq(rx_fifo.source.data),
rx_fifo.source.ack.eq(self.ev.rx.clear), rx_fifo.source.ack.eq(self.ev.rx.clear),
# Generate RX IRQ when rx_fifo becomes non-empty self.ev.rx.trigger.eq(rx_irqs[rx_irq_condition])
self.ev.rx.trigger.eq(~rx_fifo.source.stb),
] ]