From b747e6849a82b0388f1d70345c1422a34e61aa04 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Mon, 25 Apr 2022 22:16:08 -0700 Subject: [PATCH] fix test to work at 115200 baud --- uart_demo.py | 55 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/uart_demo.py b/uart_demo.py index 4054f9b..76a8b09 100755 --- a/uart_demo.py +++ b/uart_demo.py @@ -10,6 +10,7 @@ from nmigen.sim import Tick from nmigen.build import ResourceError from nmutil.sim_util import do_sim import enum +from fractions import Fraction def get_all_resources(platform, name): @@ -100,8 +101,8 @@ class SimpleUART(Elaboratable): class UartDemo(Elaboratable): - def __init__(self, text, baud=115200): - self.simple_uart = SimpleUART(baud_rate=baud) + def __init__(self, text, baud_rate=115200): + self.simple_uart = SimpleUART(baud_rate=baud_rate) self.text = str(text) self.text_bytes = list(self.text.encode()) @@ -152,7 +153,7 @@ class TestUartDemo(unittest.TestCase): STOP = enum.auto() m = Module() - dut = UartDemo("test text", baud=9600) + dut = UartDemo("test text") sample_event = Signal() expected_state = Signal(ExpectedState) m.submodules.dut = dut @@ -161,33 +162,53 @@ class TestUartDemo(unittest.TestCase): sample_event, expected_state, ]) as sim: - expected_bit_tick_count = round( - SIM_CLOCK_FREQ / dut.simple_uart.baud_rate) + current_tick = 0 + bit_center_tick = Fraction(0) + ticks_per_bit = (Fraction(SIM_CLOCK_FREQ) + / dut.simple_uart.baud_rate) + + def tick(): + nonlocal sim # make debugging easier + nonlocal current_tick + current_tick += 1 + yield Tick() def read_bit(is_initial=False): + nonlocal sim # make debugging easier + nonlocal bit_center_tick, current_tick yield sample_event.eq(1) start_value = yield dut.simple_uart.tx transition = None - for i in range(expected_bit_tick_count): - yield Tick() + bit_center_tick += ticks_per_bit + while current_tick < bit_center_tick: + yield from tick() yield sample_event.eq(0) value = yield dut.simple_uart.tx if value != start_value: - transition = i + transition = current_tick break if transition is not None: - delta = expected_bit_tick_count if is_initial else 1 - self.assertAlmostEqual( - transition, expected_bit_tick_count / 2, delta=delta) - for i in range(expected_bit_tick_count // 2): - yield Tick() + if not is_initial: + expected = bit_center_tick - ticks_per_bit / 2 + # stop exceptions from causing synchronization loss + with self.subTest(): + self.assertAlmostEqual(transition, + expected, + delta=1) + bit_center_tick = current_tick + ticks_per_bit / 2 + while current_tick < bit_center_tick: + yield from tick() yield sample_event.eq(0) value = yield dut.simple_uart.tx - self.assertNotEqual(value, start_value, - "two transitions in one bit time") + # stop exceptions from causing synchronization loss + with self.subTest(): + self.assertNotEqual( + value, start_value, + "two transitions in one bit time") return start_value def process(): + nonlocal sim # make debugging easier yield expected_state.eq(ExpectedState.START) start_bit = yield from read_bit(True) for i in range(3): @@ -218,10 +239,6 @@ class TestUartDemo(unittest.TestCase): sim.run() -def build(platform, do_program): - platform.build(UartDemo("Hello World!\r\n"), do_program=do_program) - - PLATFORMS = { "ArtyA7_100": ArtyA7_100Platform, # TODO: add more -- 2.30.2