diff --git a/test/test_bist.py b/test/test_bist.py index 958a487..afdcdbe 100644 --- a/test/test_bist.py +++ b/test/test_bist.py @@ -108,6 +108,35 @@ class DMAWriterDriver: yield +class DMAReaderDriver: + def __init__(self, dma): + self.dma = dma + self.data = [] + + def read(self, address_list): + n_last = len(self.data) + yield self.dma.sink.valid.eq(1) + for adr in address_list: + yield self.dma.sink.address.eq(adr) + while not (yield self.dma.sink.ready): + yield + while (yield self.dma.sink.ready): + yield + yield self.dma.sink.valid.eq(0) + while len(self.data) < n_last + len(address_list): + yield + + @passive + def read_handler(self): + yield self.dma.source.ready.eq(1) + while True: + while not (yield self.dma.source.valid): + yield + data = (yield self.dma.source.data) + self.data.append(data) + yield + + class TestBIST(unittest.TestCase): def setUp(self): # define common test data used for both generator and checker tests @@ -299,8 +328,8 @@ class TestBIST(unittest.TestCase): } for i in range(32): data = self.pattern_test_data["32bit_long_sequential"] - data['pattern'].append((i, 64 + i)) - data['expected'][i] = 64 + i + data["pattern"].append((i, 64 + i)) + data["expected"][i] = 64 + i def test_generator(self): def main_generator(dut): @@ -405,7 +434,7 @@ class TestBIST(unittest.TestCase): self.assertEqual(len(set(mem)), len(mem), msg="Duplicate values in memory") self.assertNotEqual(mem, list(range(len(mem))), msg="Values are a sequence") - def test_bist_generator_random_addr(self): # write whole memory and check if there are no repetitions? + def test_bist_generator_random_addr(self): data = self.bist_test_data["32bit"] data["random_addr"] = True dut = self.generator_test(data.pop("expected"), data_width=32, config_args=data, check_mem=False) @@ -621,7 +650,7 @@ class TestBIST(unittest.TestCase): } run_simulation(dut, generators, clocks) - def dma_writer_test_pattern(self, pattern, mem_expected, data_width, **kwargs): + def dma_writer_test(self, pattern, mem_expected, data_width, **kwargs): class DUT(Module): def __init__(self): self.port = LiteDRAMNativeWritePort(address_width=32, data_width=data_width) @@ -643,30 +672,76 @@ class TestBIST(unittest.TestCase): pattern = [(0x04, 0xdeadc0de)] mem_expected = [0] * 32 mem_expected[0x04] = 0xdeadc0de - self.dma_writer_test_pattern(pattern, mem_expected, data_width=32) + self.dma_writer_test(pattern, mem_expected, data_width=32) def test_dma_writer_multiple(self): data = self.pattern_test_data["32bit"] - self.dma_writer_test_pattern(data["pattern"], data["expected"], data_width=32) + self.dma_writer_test(data["pattern"], data["expected"], data_width=32) def test_dma_writer_sequential(self): data = self.pattern_test_data["32bit_sequential"] - self.dma_writer_test_pattern(data["pattern"], data["expected"], data_width=32) + self.dma_writer_test(data["pattern"], data["expected"], data_width=32) def test_dma_writer_long_sequential(self): data = self.pattern_test_data["32bit_long_sequential"] - self.dma_writer_test_pattern(data["pattern"], data["expected"], data_width=32) + self.dma_writer_test(data["pattern"], data["expected"], data_width=32) def test_dma_writer_no_fifo(self): data = self.pattern_test_data["32bit_long_sequential"] - self.dma_writer_test_pattern(data["pattern"], data["expected"], data_width=32, - fifo_depth=1) + self.dma_writer_test(data["pattern"], data["expected"], data_width=32, + fifo_depth=1) def test_dma_writer_fifo_buffered(self): data = self.pattern_test_data["32bit_long_sequential"] - self.dma_writer_test_pattern(data["pattern"], data["expected"], data_width=32, - fifo_buffered=True) + self.dma_writer_test(data["pattern"], data["expected"], data_width=32, + fifo_buffered=True) def test_dma_writer_duplicates(self): data = self.pattern_test_data["32bit_duplicates"] - self.dma_writer_test_pattern(data["pattern"], data["expected"], data_width=32) + self.dma_writer_test(data["pattern"], data["expected"], data_width=32) + + def dma_reader_test(self, pattern, mem_expected, data_width, **kwargs): + class DUT(Module): + def __init__(self): + self.port = LiteDRAMNativeReadPort(address_width=32, data_width=data_width) + self.submodules.dma = LiteDRAMDMAReader(self.port, **kwargs) + + dut = DUT() + driver = DMAReaderDriver(dut.dma) + mem = DRAMMemory(data_width, len(mem_expected), init=mem_expected) + + generators = [ + driver.read([adr for adr, data in pattern]), + driver.read_handler(), + mem.read_handler(dut.port), + ] + run_simulation(dut, generators) + self.assertEqual(driver.data, [data for adr, data in pattern]) + + def test_dma_reader_single(self): + pattern = [(0x04, 0xdeadc0de)] + mem_expected = [0] * 32 + mem_expected[0x04] = 0xdeadc0de + self.dma_reader_test(pattern, mem_expected, data_width=32) + + def test_dma_reader_multiple(self): + data = self.pattern_test_data["32bit"] + self.dma_reader_test(data["pattern"], data["expected"], data_width=32) + + def test_dma_reader_sequential(self): + data = self.pattern_test_data["32bit_sequential"] + self.dma_reader_test(data["pattern"], data["expected"], data_width=32) + + def test_dma_reader_long_sequential(self): + data = self.pattern_test_data["32bit_long_sequential"] + self.dma_reader_test(data["pattern"], data["expected"], data_width=32) + + def test_dma_reader_no_fifo(self): + data = self.pattern_test_data["32bit_long_sequential"] + self.dma_reader_test(data["pattern"], data["expected"], data_width=32, + fifo_depth=1) + + def test_dma_reader_fifo_buffered(self): + data = self.pattern_test_data["32bit_long_sequential"] + self.dma_reader_test(data["pattern"], data["expected"], data_width=32, + fifo_buffered=True)