From 6a46ea30521edd8e1bcb1b9d08ae280a3209e9c9 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Tue, 28 Aug 2018 11:50:11 +0200 Subject: [PATCH] test/test_bist: add generator test, remove async test --- test/common.py | 23 ------- test/test_axi.py | 4 +- test/test_bist.py | 143 ++++++++++++++++++++++++++++------------ test/test_bist_async.py | 100 ---------------------------- 4 files changed, 102 insertions(+), 168 deletions(-) delete mode 100755 test/test_bist_async.py diff --git a/test/common.py b/test/common.py index 57f19c2..7b25cc3 100644 --- a/test/common.py +++ b/test/common.py @@ -72,26 +72,3 @@ class DRAMMemory: yield yield dram_port.cmd.ready.eq(0) yield - - -class BISTDriver: - def __init__(self, module): - self.module = module - - def reset(self): - yield self.module.reset.eq(1) - yield - yield self.module.reset.eq(0) - yield - - def run(self, base, length): - yield self.module.base.eq(base) - yield self.module.length.eq(length) - yield self.module.start.eq(1) - yield - yield self.module.start.eq(0) - yield - while((yield self.module.done) == 0): - yield - if hasattr(self.module, "errors"): - self.errors = (yield self.module.errors) diff --git a/test/test_axi.py b/test/test_axi.py index 24ed252..5df7721 100755 --- a/test/test_axi.py +++ b/test/test_axi.py @@ -123,7 +123,7 @@ class TestAXI(unittest.TestCase): if ax_addr != beat.addr: self.errors += 1 yield - + # dut ax_burst = stream.Endpoint(ax_description(32, 32)) ax_beat = stream.Endpoint(ax_description(32, 32)) @@ -135,7 +135,7 @@ class TestAXI(unittest.TestCase): for i in range(32): bursts.append(Burst(burst_types["fixed"], prng.randrange(2**32), prng.randrange(256), log2_int(32//8))) bursts.append(Burst(burst_types["incr"], prng.randrange(2**32), prng.randrange(256), log2_int(32//8))) - + # generate expexted dut output (beats for reference) beats = [] for burst in bursts: diff --git a/test/test_bist.py b/test/test_bist.py index 932d0d8..2e1dfca 100755 --- a/test/test_bist.py +++ b/test/test_bist.py @@ -5,7 +5,8 @@ from migen import * from litex.soc.interconnect.stream import * -from litedram.common import LiteDRAMWritePort, LiteDRAMReadPort +from litedram.common import * +from litedram.frontend.bist import * from litedram.frontend.bist import _LiteDRAMBISTGenerator from litedram.frontend.bist import _LiteDRAMBISTChecker @@ -14,52 +15,108 @@ from test.common import * from litex.gen.sim import * -class DUT(Module): - def __init__(self): - self.write_port = LiteDRAMWritePort(aw=32, dw=32) - self.read_port = LiteDRAMReadPort(aw=32, dw=32) - self.submodules.generator = _LiteDRAMBISTGenerator(self.write_port, True) - self.submodules.checker = _LiteDRAMBISTChecker(self.read_port, True) +class GenCheckDriver: + def __init__(self, module): + self.module = module + def reset(self): + yield self.module.reset.eq(1) + yield + yield self.module.reset.eq(0) + yield -def main_generator(dut, mem): - generator = BISTDriver(dut.generator) - checker = BISTDriver(dut.checker) - - # write - yield from generator.reset() - yield from generator.run(16, 64) - - # read (no errors) - yield from checker.reset() - yield from checker.run(16, 64) - assert checker.errors == 0 - - # corrupt memory (using generator) - yield from generator.reset() - yield from generator.run(16 + 60, 64) - - # read (4 errors) - yield from checker.reset() - yield from checker.run(16, 64) - assert checker.errors != 0 - - # read (no errors) - yield from checker.reset() - yield from checker.run(16 + 60, 64) - assert checker.errors == 0 + def run(self, base, length): + yield self.module.base.eq(base) + yield self.module.length.eq(length) + yield self.module.start.eq(1) + yield + yield self.module.start.eq(0) + yield + while((yield self.module.done) == 0): + yield + if hasattr(self.module, "errors"): + self.errors = (yield self.module.errors) class TestBIST(unittest.TestCase): - def test(self): + def test_generator(self): + port = LiteDRAMNativeWritePort(address_width=32, data_width=32) + + def main_generator(dut): + self.errors = 0 + + # test incr + yield dut.ce.eq(1) + yield dut.random_enable.eq(0) + yield + for i in range(1024): + data = (yield dut.o) + if data != i: + self.errors += 1 + yield + + # test random + datas = [] + yield dut.ce.eq(1) + yield dut.random_enable.eq(1) + for i in range(1024): + data = (yield dut.o) + if data in datas: + self.errors += 1 + datas.append(data) + yield + + # dut + dut = Generator(23, n_state=23, taps=[17, 22]) + + # simulation + generators = [main_generator(dut)] + run_simulation(dut, main_generator(dut), vcd_name="generator.vcd") + self.assertEqual(self.errors, 0) + + def test_bist(self): + class DUT(Module): + def __init__(self): + self.write_port = LiteDRAMNativeWritePort(address_width=32, data_width=32) + self.read_port = LiteDRAMNativeReadPort(address_width=32, data_width=32) + self.submodules.generator = _LiteDRAMBISTGenerator(self.write_port) + self.submodules.checker = _LiteDRAMBISTChecker(self.read_port) + + def main_generator(dut, mem): + generator = GenCheckDriver(dut.generator) + checker = GenCheckDriver(dut.checker) + + # write + yield from generator.reset() + yield from generator.run(16, 64) + + # read (no errors) + yield from checker.reset() + yield from checker.run(16, 64) + assert checker.errors == 0 + + # corrupt memory (using generator) + yield from generator.reset() + yield from generator.run(16 + 60, 64) + + # read (4 errors) + yield from checker.reset() + yield from checker.run(16, 64) + assert checker.errors != 0 + + # read (no errors) + yield from checker.reset() + yield from checker.run(16 + 60, 64) + assert checker.errors == 0 + + # dut dut = DUT() mem = DRAMMemory(32, 128) - generators = { - "sys" : [ - main_generator(dut, mem), - mem.write_generator(dut.write_port), - mem.read_generator(dut.read_port) - ] - } - clocks = {"sys": 10} - run_simulation(dut, generators, clocks, vcd_name="sim.vcd") + + # simulation + generators = [ + main_generator(dut, mem), + mem.write_generator(dut.write_port), + mem.read_generator(dut.read_port) + ] + run_simulation(dut, generators, vcd_name="bist.vcd") diff --git a/test/test_bist_async.py b/test/test_bist_async.py deleted file mode 100755 index 3b1f63f..0000000 --- a/test/test_bist_async.py +++ /dev/null @@ -1,100 +0,0 @@ -import unittest - -from migen import * - -from litex.soc.interconnect.stream import * - -from litedram.common import PhySettings, LiteDRAMNativePort -from litedram.core import * -from litedram.modules import SDRAMModule -from litedram.frontend.crossbar import LiteDRAMCrossbar -from litedram.frontend.bist import _LiteDRAMBISTGenerator -from litedram.frontend.bist import _LiteDRAMBISTChecker -from litedram.frontend.adaptation import LiteDRAMNativePortCDC - -from litedram.phy.model import SDRAMPHYModel - -from test.common import * - -from litex.gen.sim import * - - -class SimModule(SDRAMModule): - # geometry - nbanks = 2 - nrows = 2048 - ncols = 2 - # timings - tRP = 1 - tRCD = 1 - tWR = 1 - tWTR = (1, None) - tREFI = 1 - tRFC = 1 - - -class TB(Module): - def __init__(self): - # phy - sdram_module = SimModule(1000, "1:1") - phy_settings = PhySettings( - memtype="SDR", - dfi_databits=1*16, - nphases=1, - rdphase=0, - wrphase=0, - rdcmdphase=0, - wrcmdphase=0, - cl=2, - read_latency=4, - write_latency=0 - ) - self.submodules.sdrphy = SDRAMPHYModel(sdram_module, - phy_settings, - we_granularity=0) - - # controller - self.submodules.controller = LiteDRAMController( - phy_settings, - sdram_module.geom_settings, - sdram_module.timing_settings, - ControllerSettings(with_refresh=False)) - self.comb += self.controller.dfi.connect(self.sdrphy.dfi) - self.submodules.crossbar = LiteDRAMCrossbar(self.controller.interface, - self.controller.nrowbits) - - # ports - write_user_port = self.crossbar.get_port("write", cd="write") - read_user_port = self.crossbar.get_port("read", cd="read") - - # generator / checker - self.submodules.generator = _LiteDRAMBISTGenerator(write_user_port, True) - self.submodules.checker = _LiteDRAMBISTChecker(read_user_port, True) - - -def main_generator(dut): - generator = BISTDriver(dut.generator) - checker = BISTDriver(dut.checker) - - for i in range(16): - yield - - # write - yield from generator.reset() - yield from generator.run(16, 16) - - # read (no errors) - yield from checker.reset() - yield from checker.run(16, 16) - assert checker.errors == 0 - - -class TestBISTAsync(unittest.TestCase): - def test(self): - tb = TB() - generators = {"sys" : [main_generator(tb)]} - clocks = {"sys": 10, - "write": 12, - "read": 8} - run_simulation(tb, generators, clocks, vcd_name="sim.vcd") - self.assertEqual(dut.checker.error_count.status, 0)