diff --git a/litedram/frontend/bist.py b/litedram/frontend/bist.py index 89b8fdf..de00c0a 100644 --- a/litedram/frontend/bist.py +++ b/litedram/frontend/bist.py @@ -222,9 +222,6 @@ class _LiteDRAMBISTChecker(Module, AutoCSR): self.data_counter = data_counter = Signal(dram_port.aw) self.submodules.data_fsm = data_fsm = FSM(reset_state="IDLE") - self.data_error = Signal() - self.comb += self.data_error.eq(dma.source.data != gen.o) - data_fsm.act("IDLE", If(self.start, NextValue(data_counter, 0), @@ -237,7 +234,7 @@ class _LiteDRAMBISTChecker(Module, AutoCSR): If(dma.source.valid, gen.ce.eq(1), NextValue(data_counter, data_counter + 1), - If(self.data_error, + If(dma.source.data != gen.o, NextValue(self.err_count, self.err_count + 1), ), If(data_counter == (self.length-1), @@ -325,3 +322,30 @@ class LiteDRAMBISTChecker(Module, AutoCSR): err_count_sync.i.eq(core.err_count), self.err_count.status.eq(err_count_sync.o), ] + + +class LiteDRAMBISTCheckerScope(Module): + """Easy scope access to important signals of LiteDRAMBISTChecker.""" + + def __init__(self, checker): + core = checker.core + self.data_error = Signal() + self.data_address = Signal(core.data_counter.nbits) + self.data_expected = Signal(core.dma.source.data.nbits) + self.data_actual = Signal(core.dma.source.data.nbits) + + self.comb += [ + self.data_error.eq(core.dma.source.valid & + (self.data_actual != self.data_expected)), + self.data_address.eq(core.base + core.data_counter), + self.data_actual.eq(core.dma.source.data), + self.data_expected.eq(core.gen.o), + ] + + def signals(self): + return [ + self.data_error, + self.data_address, + self.data_expected, + self.data_actual, + ] diff --git a/test/bist_tb.py b/test/bist_tb.py index c53e4e2..e4d85f6 100755 --- a/test/bist_tb.py +++ b/test/bist_tb.py @@ -9,6 +9,7 @@ from litex.soc.interconnect.stream import * from litedram.common import LiteDRAMWritePort, LiteDRAMReadPort from litedram.frontend.bist import LiteDRAMBISTGenerator from litedram.frontend.bist import LiteDRAMBISTChecker +from litedram.frontend.bist import LiteDRAMBISTCheckerScope from test.common import * @@ -18,6 +19,7 @@ class TB(Module): self.read_port = LiteDRAMReadPort(aw=32, dw=32) self.submodules.generator = LiteDRAMBISTGenerator(self.write_port, random=True) self.submodules.checker = LiteDRAMBISTChecker(self.read_port, random=True) + self.submodules.checker_scope = LiteDRAMBISTCheckerScope(self.checker) def main_generator(dut, mem): @@ -117,7 +119,7 @@ def main_generator(dut, mem): yield yield - # read with two errors but halting on the first one + # check the scoped signals yield from reset_bist_module(dut.checker) errors = yield dut.checker.err_count.status assert errors == 0, errors @@ -129,27 +131,27 @@ def main_generator(dut, mem): yield from toggle_re(dut.checker.start) for i in range(8): yield - while((yield dut.checker.core.data_error) == 0): + while((yield dut.checker_scope.data_error) == 0): yield - err_addr = yield dut.checker.core.data_counter + dut.checker.core.base + err_addr = yield dut.checker_scope.data_address assert err_addr == 20, err_addr - err_expect = yield dut.checker.core.gen.o + err_expect = yield dut.checker_scope.data_expected assert err_expect == 0xffff000f, hex(err_expect) - err_actual = yield dut.checker.core.dma.source.data + err_actual = yield dut.checker_scope.data_actual assert err_actual == 0x200, err_actual yield errors = yield dut.checker.core.err_count assert errors == 1, errors - while((yield dut.checker.core.data_error) == 0): + while((yield dut.checker_scope.data_error) == 0): yield - err_addr = yield dut.checker.core.data_counter + dut.checker.core.base + err_addr = yield dut.checker_scope.data_address assert err_addr == 21, err_addr - err_expect = yield dut.checker.core.gen.o + err_expect = yield dut.checker_scope.data_expected assert err_expect == 0xfff1ff1f, hex(err_expect) - err_actual = yield dut.checker.core.dma.source.data + err_actual = yield dut.checker_scope.data_actual assert err_actual == 0x210, hex(err_actual) yield errors = yield dut.checker.core.err_count