-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuart_nmigen.py
82 lines (69 loc) · 2.76 KB
/
uart_nmigen.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# from: https://github.com/m-labs/nmigen/blob/master/examples/basic/uart.py
from nmigen import *
class UART_NMIGEN(Elaboratable):
def __init__(self, divisor, data_bits=8):
assert divisor >= 4
self.data_bits = data_bits
self.divisor = divisor
self.tx_o = Signal()
self.rx_i = Signal()
self.tx_data = Signal(data_bits)
self.tx_rdy = Signal()
self.tx_ack = Signal()
self.rx_data = Signal(data_bits)
self.rx_err = Signal()
self.rx_ovf = Signal()
self.rx_rdy = Signal()
self.rx_ack = Signal()
def elaborate(self, platform):
m = Module()
### m.domains.sync = ClockDomain()
tx_phase = Signal(len(Const(self.divisor)))
tx_shreg = Signal(1 + self.data_bits + 1, reset=-1)
tx_count = Signal(len(Const(len(tx_shreg) + 1)))
m.d.comb += self.tx_o.eq(tx_shreg[0])
with m.If(tx_count == 0):
m.d.comb += self.tx_ack.eq(1)
with m.If(self.tx_rdy):
m.d.sync += [
tx_shreg.eq(Cat(C(0, 1), self.tx_data, C(1, 1))),
tx_count.eq(len(tx_shreg)),
tx_phase.eq(self.divisor - 1),
]
with m.Else():
with m.If(tx_phase != 0):
m.d.sync += tx_phase.eq(tx_phase - 1)
with m.Else():
m.d.sync += [
tx_shreg.eq(Cat(tx_shreg[1:], C(1, 1))),
tx_count.eq(tx_count - 1),
tx_phase.eq(self.divisor - 1),
]
rx_phase = Signal(len(Const(self.divisor)))
rx_shreg = Signal(1 + self.data_bits + 1, reset=-1)
rx_count = Signal(len(Const(len(rx_shreg) + 1)))
m.d.comb += self.rx_data.eq(rx_shreg[1:-1])
with m.If(rx_count == 0):
m.d.comb += self.rx_err.eq(~(~rx_shreg[0] & rx_shreg[-1]))
with m.If(~self.rx_i):
with m.If(self.rx_ack | ~self.rx_rdy):
m.d.sync += [
self.rx_rdy.eq(0),
self.rx_ovf.eq(0),
rx_count.eq(len(rx_shreg)),
rx_phase.eq(self.divisor // 2),
]
with m.Else():
m.d.sync += self.rx_ovf.eq(1)
with m.Else():
with m.If(rx_phase != 0):
m.d.sync += rx_phase.eq(rx_phase - 1)
with m.Else():
m.d.sync += [
rx_shreg.eq(Cat(rx_shreg[1:], self.rx_i)),
rx_count.eq(rx_count - 1),
rx_phase.eq(self.divisor - 1),
]
with m.If(rx_count == 1):
m.d.sync += self.rx_rdy.eq(1)
return m