Skip to content

Commit 8aa3fb3

Browse files
committedMay 1, 2015
com/uart: add tx and rx fifos.
Since ressource usage is low with default depth of 16 (implemented in RAM LUTs) we don't keep old behaviour. Tested successfully with BIOS and flterm.
1 parent a6f290a commit 8aa3fb3

File tree

2 files changed

+41
-23
lines changed

2 files changed

+41
-23
lines changed
 

Diff for: ‎misoclib/com/uart/__init__.py

+32-17
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,45 @@
33
from migen.bank.eventmanager import *
44
from migen.genlib.record import Record
55
from migen.flow.actor import Sink, Source
6+
from migen.actorlib.fifo import SyncFIFO
67

78

89
class UART(Module, AutoCSR):
9-
def __init__(self, phy):
10+
def __init__(self, phy,
11+
tx_fifo_depth=16,
12+
rx_fifo_depth=16):
1013
self._rxtx = CSR(8)
14+
self._txfull = CSRStatus()
15+
self._rxempty = CSRStatus()
1116

1217
self.submodules.ev = EventManager()
13-
self.ev.tx = EventSourcePulse()
14-
self.ev.rx = EventSourcePulse()
18+
self.ev.tx = EventSourceProcess()
19+
self.ev.rx = EventSourceProcess()
1520
self.ev.finalize()
16-
###
17-
self.sync += [
18-
If(self._rxtx.re,
19-
phy.sink.stb.eq(1),
20-
phy.sink.data.eq(self._rxtx.r),
21-
).Elif(phy.sink.ack,
22-
phy.sink.stb.eq(0)
23-
),
24-
If(phy.source.stb,
25-
self._rxtx.w.eq(phy.source.data)
26-
)
21+
22+
# # #
23+
24+
tx_fifo = SyncFIFO([("data", 8)], tx_fifo_depth)
25+
self.submodules += tx_fifo
26+
self.comb += [
27+
tx_fifo.sink.stb.eq(self._rxtx.re),
28+
tx_fifo.sink.data.eq(self._rxtx.r),
29+
self._txfull.status.eq(~tx_fifo.sink.ack),
30+
Record.connect(tx_fifo.source, phy.sink)
2731
]
32+
33+
rx_fifo = SyncFIFO([("data", 8)], rx_fifo_depth)
34+
self.submodules += rx_fifo
35+
self.comb += [
36+
Record.connect(phy.source, rx_fifo.sink),
37+
self._rxempty.status.eq(~rx_fifo.source.stb),
38+
self._rxtx.w.eq(rx_fifo.source.data),
39+
rx_fifo.source.ack.eq(self.ev.rx.clear)
40+
]
41+
2842
self.comb += [
29-
self.ev.tx.trigger.eq(phy.sink.stb & phy.sink.ack),
30-
self.ev.rx.trigger.eq(phy.source.stb & phy.source.ack),
31-
phy.source.ack.eq(~self.ev.rx.pending)
43+
# Generate TX IRQ when tx_fifo becomes empty
44+
self.ev.tx.trigger.eq(tx_fifo.source.stb),
45+
# Generate RX IRQ when rx_fifo becomes non-empty
46+
self.ev.rx.trigger.eq(~rx_fifo.source.stb),
3247
]

Diff for: ‎software/libbase/uart.c

+9-6
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,22 @@ void uart_isr(void)
3131
stat = uart_ev_pending_read();
3232

3333
if(stat & UART_EV_RX) {
34-
rx_buf[rx_produce] = uart_rxtx_read();
35-
rx_produce = (rx_produce + 1) & UART_RINGBUFFER_MASK_RX;
36-
uart_ev_pending_write(UART_EV_RX);
34+
while(!uart_rxempty_read()) {
35+
rx_buf[rx_produce] = uart_rxtx_read();
36+
rx_produce = (rx_produce + 1) & UART_RINGBUFFER_MASK_RX;
37+
uart_ev_pending_write(UART_EV_RX);
38+
}
3739
}
3840

3941
if(stat & UART_EV_TX) {
4042
uart_ev_pending_write(UART_EV_TX);
41-
if(tx_level > 0) {
43+
if(tx_level == 0)
44+
tx_cts = 1;
45+
while(tx_level > 0 && !uart_txfull_read()) {
4246
uart_rxtx_write(tx_buf[tx_consume]);
4347
tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX;
4448
tx_level--;
45-
} else
46-
tx_cts = 1;
49+
}
4750
}
4851
}
4952

0 commit comments

Comments
 (0)
Please sign in to comment.