from nmigen.build import ResourceError
from nmutil.sim_util import do_sim
import enum
+from fractions import Fraction
def get_all_resources(platform, name):
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())
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
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):
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