Skip to content

Commit b1386c1

Browse files
committed
uart-demo: add reference implementation.
1 parent 55f550a commit b1386c1

File tree

2 files changed

+74
-2
lines changed

2 files changed

+74
-2
lines changed

uart-demo/tests/test_uart.py

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,52 @@
88
from uart_demo.ports import PortGroup
99

1010

11-
# TODO
11+
class LoopbackUARTTestCase(unittest.TestCase):
12+
def test_hello(self):
13+
ports = PortGroup()
14+
ports.rx = io.SimulationPort("i", 1)
15+
ports.tx = io.SimulationPort("o", 1)
16+
17+
dut = LoopbackUART(ports, clk_freq=48e6, baudrate=115200)
18+
19+
# send "hello" to the UART receiver
20+
async def rx_testbench(ctx):
21+
ctx.set(ports.rx.i, 1)
22+
await ctx.delay(1 / dut.baudrate)
23+
24+
for rx_chr in "hello":
25+
# send the start bit
26+
ctx.set(ports.rx.i, 0)
27+
await ctx.delay(1 / dut.baudrate)
28+
29+
# send data bits
30+
for rx_bit in reversed(f"{ord(rx_chr):08b}"):
31+
ctx.set(ports.rx.i, int(rx_bit))
32+
await ctx.delay(1 / dut.baudrate)
33+
34+
# send the stop bit
35+
ctx.set(ports.rx.i, 1)
36+
await ctx.delay(1 / dut.baudrate)
37+
38+
# check that "hello" is transmitted back
39+
async def tx_testbench(ctx):
40+
for tx_chr in "hello":
41+
# wait for the start bit
42+
await ctx.negedge(ports.tx.o)
43+
await ctx.delay(1 / dut.baudrate)
44+
45+
# check data bits
46+
for tx_bit in reversed(f"{ord(tx_chr):08b}"):
47+
self.assertEqual(ctx.get(ports.tx.o), int(tx_bit))
48+
await ctx.delay(1 / dut.baudrate)
49+
50+
# check the stop bit
51+
self.assertEqual(ctx.get(ports.tx.o), 1)
52+
53+
sim = Simulator(dut)
54+
sim.add_clock(period=1 / 48e6)
55+
sim.add_testbench(rx_testbench)
56+
sim.add_testbench(tx_testbench)
57+
58+
with sim.write_vcd(vcd_file="test.vcd"):
59+
sim.run()

uart-demo/uart_demo/uart.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,28 @@
77
__all__ = ["LoopbackUART"]
88

99

10-
# TODO
10+
class LoopbackUART(wiring.Component):
11+
def __init__(self, ports, clk_freq, baudrate=115200):
12+
super().__init__({})
13+
self.ports = ports
14+
self.clk_freq = clk_freq
15+
self.baudrate = baudrate
16+
17+
def elaborate(self, platform):
18+
m = Module()
19+
20+
m.submodules.rx_buffer = rx_buffer = io.Buffer("i", self.ports.rx)
21+
m.submodules.tx_buffer = tx_buffer = io.Buffer("o", self.ports.tx)
22+
23+
m.submodules.uart = uart = AsyncSerial(divisor=int(self.clk_freq // self.baudrate))
24+
25+
m.d.comb += [
26+
uart.rx.i.eq(rx_buffer.i),
27+
tx_buffer.o.eq(uart.tx.o),
28+
29+
uart.rx.ack .eq(uart.tx.rdy),
30+
uart.tx.data.eq(uart.rx.data),
31+
uart.tx.ack .eq(uart.rx.rdy),
32+
]
33+
34+
return m

0 commit comments

Comments
 (0)