From 3dd10e6b9bb05664bcff33dc5b43aa6eb84854d3 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Thu, 28 Mar 2019 19:39:12 +0800 Subject: [PATCH] add simple test for UART --- heavycomps/heavycomps/test/__init__.py | 0 heavycomps/heavycomps/test/test_uart.py | 41 +++++++++++++++++++++++++ heavycomps/heavycomps/uart.py | 32 +++++++++---------- 3 files changed, 56 insertions(+), 17 deletions(-) create mode 100644 heavycomps/heavycomps/test/__init__.py create mode 100644 heavycomps/heavycomps/test/test_uart.py diff --git a/heavycomps/heavycomps/test/__init__.py b/heavycomps/heavycomps/test/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/heavycomps/heavycomps/test/test_uart.py b/heavycomps/heavycomps/test/test_uart.py new file mode 100644 index 0000000..0177fd2 --- /dev/null +++ b/heavycomps/heavycomps/test/test_uart.py @@ -0,0 +1,41 @@ +import unittest + +from nmigen import * +from nmigen.back.pysim import * + +from heavycomps import uart + + +class Loopback: + def __init__(self, tuning_word=2**31): + self.tx = uart.RS232TX(tuning_word) + self.rx = uart.RS232RX(tuning_word) + + def elaborate(self, platform): + m = Module() + m.submodules.tx = self.tx + m.submodules.rx = self.rx + m.d.comb += self.rx.rx.eq(self.tx.tx) + return m + + +class TestUART(unittest.TestCase): + def test_loopback(self): + dut = Loopback() + test_vector = [32, 129, 201, 39, 0, 255] + + with Simulator(Fragment.get(dut, None)) as sim: + sim.add_clock(1e-6) + + def send(): + for value in test_vector: + yield from dut.tx.write(value) + + def receive(): + for value in test_vector: + received = yield from dut.rx.read() + self.assertEqual(received, value) + + sim.add_sync_process(send) + sim.add_sync_process(receive) + sim.run() diff --git a/heavycomps/heavycomps/uart.py b/heavycomps/heavycomps/uart.py index b4195ba..522e3d5 100644 --- a/heavycomps/heavycomps/uart.py +++ b/heavycomps/heavycomps/uart.py @@ -1,6 +1,5 @@ from nmigen import * from nmigen.lib.cdc import MultiReg -from nmigen.cli import main class RS232RX: @@ -50,6 +49,14 @@ class RS232RX: return m + def read(self): + while not (yield self.stb): + yield + value = yield self.data + # clear stb, otherwise multiple calls to this generator keep returning the same value + yield + return value + class RS232TX: def __init__(self, tuning_word): @@ -92,19 +99,10 @@ class RS232TX: return m - -class Loopback: - def elaborate(self, platform): - m = Module() - tuning_word = 2**31 - tx = RS232TX(tuning_word) - rx = RS232RX(tuning_word) - m.submodules += tx, rx - m.d.comb += rx.rx.eq(tx.tx) - m.d.comb += tx.data.eq(42) - m.d.comb += tx.stb.eq(1) - return m - -if __name__ == "__main__": - uart = Loopback() - main(uart) + def write(self, data): + yield self.stb.eq(1) + yield self.data.eq(data) + yield + while not (yield self.ack): + yield + yield self.stb.eq(0)