gateware: test out UART, had to fix SR flags

This commit is contained in:
David Lenfesty 2023-02-04 14:40:05 -07:00
parent c3f62c271c
commit 0bf4fb5c1b
4 changed files with 75 additions and 33 deletions

View File

@ -1,5 +1,6 @@
from amaranth import * from amaranth import *
from i2c import * from i2c import *
from amlib.io.i2c import *
from amaranth.lib.io import pin_layout from amaranth.lib.io import pin_layout
from tests import BaseTestClass, provide_testcase_name from tests import BaseTestClass, provide_testcase_name
@ -45,33 +46,6 @@ class TestCSROperation(BaseTestClass):
self.harness = TestHarness() self.harness = TestHarness()
def _write_csr(self, bus, index, data):
yield bus.addr.eq(index)
yield bus.w_stb.eq(1)
yield bus.w_data.eq(data)
yield Tick()
yield bus.w_stb.eq(0)
yield Tick()
def _wait_for_signal(self, signal, polarity=False, require_edge=True, timeout=1000):
ready_for_edge = not require_edge # If we don't require edge, we can just ignore
while True:
timeout -= 1
if timeout == 0:
self.fail(f"_wait_for_signal({signal}, {polarity}, {require_edge}, {timeout}, timed out!")
read = yield signal
if read == polarity:
if ready_for_edge:
break
else:
ready_for_edge = True
yield Tick()
# NOTE So ideally there are more test cases... but the initiator itself is well tested, # NOTE So ideally there are more test cases... but the initiator itself is well tested,
# and we only really need it to work for a limited set of use cases, so exhaustive testing # and we only really need it to work for a limited set of use cases, so exhaustive testing
# isn't a huge deal. As well, we can cover all valid uses of the signals with one test. # isn't a huge deal. As well, we can cover all valid uses of the signals with one test.

View File

@ -1,17 +1,57 @@
from amaranth import * from amaranth import *
from amaranth.sim import * from amaranth.sim import *
from amlib.io.serial import *
from uart import * from uart import *
from tests import BaseTestClass, provide_testcase_name from tests import BaseTestClass, provide_testcase_name
__all__ = ["TestHarness", "TestUART"]
class TestHarness(Elaboratable): class TestHarness(Elaboratable):
def __init__(self): def __init__(self):
self.uut = UART(10e6) self.uut = UART(10e6, fifo_depth=16)
self.uart = AsyncSerial(divisor=int(10e6 // 115200), divisor_bits=16, data_bits=8, parity="none")
def elaborate(self, platform): def elaborate(self, platform):
assert platform is None assert platform is None
m = Module() m = Module()
m.submodules.uut = self.uut
m.submodules.uart = self.uart
return m # Connect UART lines
m.d.comb += [
self.uut.rx.eq(self.uart.tx.o),
self.uart.rx.i.eq(self.uut.tx),
]
# Connect the data lines so we are always pulling data out... for now
m.d.comb += [
self.uart.rx.ack.eq(1),
]
return m
class TestUART(BaseTestClass):
def setUp(self):
self.harness = TestHarness()
@provide_testcase_name
def test_operation(self, test_name):
def test():
for i in range(20):
yield from self._write_csr(self.harness.uut.bus, 2, i)
for _ in range(2000):
yield Tick()
yield from self._write_csr(self.harness.uut.bus, 0, 1000)
for _ in range(20000):
yield Tick()
self._run_test(test, test_name)

View File

@ -37,6 +37,34 @@ class BaseTestClass(unittest.TestCase):
del sim del sim
######### Random Utilities ########
def _write_csr(self, bus, index, data):
yield bus.addr.eq(index)
yield bus.w_stb.eq(1)
yield bus.w_data.eq(data)
yield Tick()
yield bus.w_stb.eq(0)
yield Tick()
def _wait_for_signal(self, signal, polarity=False, require_edge=True, timeout=1000):
ready_for_edge = not require_edge # If we don't require edge, we can just ignore
while True:
timeout -= 1
if timeout == 0:
self.fail(f"_wait_for_signal({signal}, {polarity}, {require_edge}, {timeout}, timed out!")
read = yield signal
if read == polarity:
if ready_for_edge:
break
else:
ready_for_edge = True
yield Tick()
def provide_testcase_name(fn): def provide_testcase_name(fn):
"""Decorator that provides a function with access to its own class and name.""" """Decorator that provides a function with access to its own class and name."""
def wrapper(self): def wrapper(self):

View File

@ -100,10 +100,10 @@ class UART(Elaboratable):
# SR Hookups # SR Hookups
m.d.comb += [ m.d.comb += [
self.SR.r_data[0].eq(self._tx_fifo.level < self.fifo_depth), # txfifo_full self.SR.r_data[0].eq(self._tx_fifo.level == self.fifo_depth), # txfifo_full
self.SR.r_data[1].eq(self._tx_fifo.level > 0), # txfifo_empty self.SR.r_data[1].eq(self._tx_fifo.level == 0), # txfifo_empty
self.SR.r_data[2].eq(self._rx_fifo.level < self.fifo_depth), # rxfifo_full self.SR.r_data[2].eq(self._rx_fifo.level == self.fifo_depth), # rxfifo_full
self.SR.r_data[3].eq(self._rx_fifo.level > 0), # rxfifo_empty self.SR.r_data[3].eq(self._rx_fifo.level == 0), # rxfifo_empty
] ]
# DR hookups # DR hookups