mirror of
https://github.com/enjoy-digital/litedram.git
synced 2025-01-04 09:52:25 -05:00
bist: Working on improving the names of things.
This commit is contained in:
parent
8ff2f8779b
commit
f1ad8991a4
3 changed files with 100 additions and 81 deletions
|
@ -60,13 +60,13 @@ class _LiteDRAMBISTGenerator(Module):
|
|||
else:
|
||||
self.submodules.gen = gen = Counter(dram_port.dw)
|
||||
|
||||
self.started = started = Signal()
|
||||
enable = Signal()
|
||||
self.running = running = Signal()
|
||||
not_finished = Signal()
|
||||
counter = Signal(dram_port.aw)
|
||||
self.comb += enable.eq(started & (counter != (self.length - 1)))
|
||||
self.comb += not_finished.eq(running & (counter != (self.length - 1)))
|
||||
self.sync += [
|
||||
If(self.start,
|
||||
started.eq(1),
|
||||
running.eq(1),
|
||||
counter.eq(0)
|
||||
).Elif(gen.ce,
|
||||
counter.eq(counter + 1)
|
||||
|
@ -74,12 +74,12 @@ class _LiteDRAMBISTGenerator(Module):
|
|||
]
|
||||
|
||||
self.comb += [
|
||||
dma.sink.valid.eq(enable),
|
||||
dma.sink.valid.eq(not_finished),
|
||||
dma.sink.address.eq(self.base + counter),
|
||||
dma.sink.data.eq(gen.o),
|
||||
gen.ce.eq(enable & dma.sink.ready),
|
||||
gen.ce.eq(not_finished & dma.sink.ready),
|
||||
|
||||
self.done.eq(~enable & started)
|
||||
self.done.eq(~not_finished & running)
|
||||
]
|
||||
|
||||
|
||||
|
@ -145,11 +145,11 @@ class _LiteDRAMBISTChecker(Module, AutoCSR):
|
|||
self.length = Signal(dram_port.aw)
|
||||
self.halt_on_error = Signal()
|
||||
|
||||
self.error_count = Signal(32)
|
||||
self.error_addr = Signal(dram_port.aw)
|
||||
self.err_count = Signal(32)
|
||||
self.err_addr = Signal(dram_port.aw)
|
||||
|
||||
self.error_wanted = Signal(dram_port.dw)
|
||||
self.error_actual = Signal(dram_port.dw)
|
||||
self.err_expect = Signal(dram_port.dw)
|
||||
self.err_actual = Signal(dram_port.dw)
|
||||
|
||||
self.done = Signal()
|
||||
|
||||
|
@ -164,24 +164,24 @@ class _LiteDRAMBISTChecker(Module, AutoCSR):
|
|||
|
||||
self._address_counter = address_counter = Signal(dram_port.aw)
|
||||
|
||||
self.started = started = Signal()
|
||||
self.running = running = Signal()
|
||||
self.sync += [
|
||||
If(self.start,
|
||||
started.eq(1),
|
||||
If(self.error_addr != 0,
|
||||
self.error_addr.eq(0),
|
||||
running.eq(1),
|
||||
If(self.err_addr != 0,
|
||||
self.err_addr.eq(0),
|
||||
address_counter.eq(address_counter+1),
|
||||
),
|
||||
),
|
||||
]
|
||||
|
||||
address_enable = Signal()
|
||||
address_not_finished = Signal()
|
||||
address_counter_ce = Signal()
|
||||
self.comb += [
|
||||
address_enable.eq(started & (address_counter != (self.length - 1))),
|
||||
address_counter_ce.eq(address_enable & dma.sink.ready),
|
||||
address_not_finished.eq(running & (address_counter != (self.length - 1))),
|
||||
address_counter_ce.eq(address_not_finished & dma.sink.ready),
|
||||
|
||||
dma.sink.valid.eq(address_enable),
|
||||
dma.sink.valid.eq(address_not_finished),
|
||||
dma.sink.address.eq(self.base + address_counter),
|
||||
]
|
||||
self.sync += [
|
||||
|
@ -191,11 +191,11 @@ class _LiteDRAMBISTChecker(Module, AutoCSR):
|
|||
]
|
||||
|
||||
self._data_counter = data_counter = Signal(dram_port.aw)
|
||||
data_enable = Signal()
|
||||
data_not_finished = Signal()
|
||||
data_counter_ce = Signal()
|
||||
self.comb += [
|
||||
data_enable.eq(started & (data_counter != address_counter)),
|
||||
data_counter_ce.eq(data_enable & dma.source.valid),
|
||||
data_not_finished.eq(running & (data_counter != address_counter)),
|
||||
data_counter_ce.eq(data_not_finished & dma.source.valid),
|
||||
|
||||
dma.source.ready.eq(data_counter_ce),
|
||||
gen.ce.eq(data_counter_ce),
|
||||
|
@ -204,12 +204,12 @@ class _LiteDRAMBISTChecker(Module, AutoCSR):
|
|||
If(data_counter_ce,
|
||||
data_counter.eq(data_counter + 1),
|
||||
If(dma.source.data != gen.o,
|
||||
self.error_count.eq(self.error_count + 1),
|
||||
self.error_addr.eq(self.base + data_counter),
|
||||
self.error_wanted.eq(gen.o),
|
||||
self.error_actual.eq(dma.source.data),
|
||||
self.err_count.eq(self.err_count + 1),
|
||||
self.err_addr.eq(self.base + data_counter),
|
||||
self.err_expect.eq(gen.o),
|
||||
self.err_actual.eq(dma.source.data),
|
||||
If(self.halt_on_error,
|
||||
started.eq(0),
|
||||
running.eq(0),
|
||||
),
|
||||
)
|
||||
),
|
||||
|
@ -217,10 +217,10 @@ class _LiteDRAMBISTChecker(Module, AutoCSR):
|
|||
|
||||
error = Signal()
|
||||
self.comb += [
|
||||
error.eq(self.halt_on_error & (self.error_addr != 0)),
|
||||
error.eq(self.halt_on_error & (self.err_addr != 0)),
|
||||
]
|
||||
|
||||
self.comb += self.done.eq((~data_enable & ~address_enable & started) | error)
|
||||
self.comb += self.done.eq((~data_not_finished & ~address_not_finished & running) | error)
|
||||
|
||||
|
||||
class LiteDRAMBISTChecker(Module, AutoCSR):
|
||||
|
@ -243,22 +243,31 @@ class LiteDRAMBISTChecker(Module, AutoCSR):
|
|||
done : out
|
||||
The module has completed checking
|
||||
|
||||
error_count : out
|
||||
err_count : out
|
||||
Number of DRAM words which don't match.
|
||||
error_addr : out
|
||||
|
||||
err_addr : out
|
||||
Address of the last error to occur.
|
||||
err_expect : out
|
||||
Expected data value on the last error.
|
||||
err_actual : out
|
||||
Actual data value on the last error.
|
||||
"""
|
||||
|
||||
def __init__(self, dram_port, random=True):
|
||||
self.reset = CSR()
|
||||
self.start = CSR()
|
||||
self.done = CSRStatus()
|
||||
|
||||
self.base = CSRStorage(dram_port.aw)
|
||||
self.length = CSRStorage(dram_port.aw)
|
||||
self.halt_on_error = CSRStorage()
|
||||
|
||||
self.error_count = CSRStatus(32)
|
||||
self.error_addr = CSRStatus(dram_port.aw)
|
||||
self.done = CSRStatus()
|
||||
|
||||
self.err_count = CSRStatus(32)
|
||||
self.err_addr = CSRStatus(dram_port.aw)
|
||||
self.err_expect = CSRStatus(dram_port.dw)
|
||||
self.err_actual = CSRStatus(dram_port.dw)
|
||||
|
||||
# # #
|
||||
|
||||
|
@ -301,13 +310,23 @@ class LiteDRAMBISTChecker(Module, AutoCSR):
|
|||
core.halt_on_error.eq(halt_on_error_sync.o),
|
||||
]
|
||||
|
||||
error_count_sync = BusSynchronizer(32, cd, "sys")
|
||||
error_addr_sync = BusSynchronizer(dram_port.aw, cd, "sys")
|
||||
self.submodules += error_addr_sync, error_count_sync
|
||||
self.comb += [
|
||||
error_count_sync.i.eq(core.error_count),
|
||||
self.error_count.status.eq(error_count_sync.o),
|
||||
err_count_sync = BusSynchronizer(32, cd, "sys")
|
||||
err_addr_sync = BusSynchronizer(dram_port.aw, cd, "sys")
|
||||
err_expect_sync = BusSynchronizer(dram_port.dw, cd, "sys")
|
||||
err_actual_sync = BusSynchronizer(dram_port.dw, cd, "sys")
|
||||
|
||||
error_addr_sync.i.eq(core.error_addr),
|
||||
self.error_addr.status.eq(error_addr_sync.o),
|
||||
self.submodules += err_addr_sync, err_count_sync, err_expect_sync, err_actual_sync
|
||||
|
||||
self.comb += [
|
||||
err_count_sync.i.eq(core.err_count),
|
||||
self.err_count.status.eq(err_count_sync.o),
|
||||
|
||||
err_addr_sync.i.eq(core.err_addr),
|
||||
self.err_addr.status.eq(err_addr_sync.o),
|
||||
|
||||
err_expect_sync.i.eq(core.err_expect),
|
||||
self.err_expect.status.eq(err_expect_sync.o),
|
||||
|
||||
err_actual_sync.i.eq(core.err_actual),
|
||||
self.err_actual.status.eq(err_actual_sync.o),
|
||||
]
|
||||
|
|
|
@ -55,7 +55,7 @@ def main_generator(dut, mem):
|
|||
|
||||
# read with no errors
|
||||
yield from reset_bist_module(dut.checker)
|
||||
errors = yield dut.checker.error_count.status
|
||||
errors = yield dut.checker.err_count.status
|
||||
assert errors == 0, errors
|
||||
|
||||
yield dut.checker.base.storage.eq(16)
|
||||
|
@ -69,7 +69,7 @@ def main_generator(dut, mem):
|
|||
yield
|
||||
done = yield dut.checker.done.status
|
||||
assert done, done
|
||||
errors = yield dut.checker.error_count.status
|
||||
errors = yield dut.checker.err_count.status
|
||||
assert errors == 0, errors
|
||||
|
||||
yield
|
||||
|
@ -77,7 +77,7 @@ def main_generator(dut, mem):
|
|||
|
||||
# read with one error
|
||||
yield from reset_bist_module(dut.checker)
|
||||
errors = yield dut.checker.error_count.status
|
||||
errors = yield dut.checker.err_count.status
|
||||
assert errors == 0, errors
|
||||
|
||||
print("mem.mem[20]", hex(mem.mem[20]))
|
||||
|
@ -95,18 +95,18 @@ def main_generator(dut, mem):
|
|||
yield
|
||||
done = yield dut.checker.done.status
|
||||
assert done, done
|
||||
errors = yield dut.checker.error_count.status
|
||||
errors = yield dut.checker.err_count.status
|
||||
assert errors == 1, errors
|
||||
|
||||
error_addr = yield dut.checker.error_addr.status
|
||||
assert error_addr == 20, error_addr
|
||||
err_addr = yield dut.checker.err_addr.status
|
||||
assert err_addr == 20, err_addr
|
||||
|
||||
yield
|
||||
yield
|
||||
|
||||
# read with two errors
|
||||
yield from reset_bist_module(dut.checker)
|
||||
errors = yield dut.checker.error_count.status
|
||||
errors = yield dut.checker.err_count.status
|
||||
assert errors == 0, errors
|
||||
|
||||
print("mem.mem[21]", hex(mem.mem[21]))
|
||||
|
@ -124,18 +124,18 @@ def main_generator(dut, mem):
|
|||
yield
|
||||
done = yield dut.checker.done.status
|
||||
assert done, done
|
||||
errors = yield dut.checker.error_count.status
|
||||
errors = yield dut.checker.err_count.status
|
||||
assert errors == 2, errors
|
||||
|
||||
error_addr = yield dut.checker.error_addr.status
|
||||
assert error_addr == 21, error_addr
|
||||
err_addr = yield dut.checker.err_addr.status
|
||||
assert err_addr == 21, err_addr
|
||||
|
||||
yield
|
||||
yield
|
||||
|
||||
# read with two errors but halting on the first one
|
||||
yield from reset_bist_module(dut.checker)
|
||||
errors = yield dut.checker.error_count.status
|
||||
errors = yield dut.checker.err_count.status
|
||||
assert errors == 0, errors
|
||||
|
||||
yield dut.checker.base.storage.eq(16)
|
||||
|
@ -150,19 +150,19 @@ def main_generator(dut, mem):
|
|||
yield
|
||||
done = yield dut.checker.done.status
|
||||
assert done, done
|
||||
started = yield dut.checker.core.started
|
||||
assert not started, started
|
||||
running = yield dut.checker.core.running
|
||||
assert not running, running
|
||||
for i in range(16):
|
||||
yield
|
||||
|
||||
errors = yield dut.checker.error_count.status
|
||||
errors = yield dut.checker.err_count.status
|
||||
assert errors == 1, errors
|
||||
error_addr = yield dut.checker.error_addr.status
|
||||
assert error_addr == 20, error_addr
|
||||
error_wanted = yield dut.checker.core.error_wanted
|
||||
assert error_wanted == 0xffff000f, error_wanted
|
||||
error_actual = yield dut.checker.core.error_actual
|
||||
assert error_actual == 0x200, error_actual
|
||||
err_addr = yield dut.checker.err_addr.status
|
||||
assert err_addr == 20, err_addr
|
||||
err_expect = yield dut.checker.core.err_expect
|
||||
assert err_expect == 0xffff000f, err_expect
|
||||
err_actual = yield dut.checker.core.err_actual
|
||||
assert err_actual == 0x200, err_actual
|
||||
|
||||
yield from toggle_re(dut.checker.start)
|
||||
for i in range(8):
|
||||
|
@ -171,19 +171,19 @@ def main_generator(dut, mem):
|
|||
yield
|
||||
done = yield dut.checker.done.status
|
||||
assert done, done
|
||||
started = yield dut.checker.core.started
|
||||
assert not started, started
|
||||
running = yield dut.checker.core.running
|
||||
assert not running, running
|
||||
for i in range(16):
|
||||
yield
|
||||
|
||||
errors = yield dut.checker.error_count.status
|
||||
errors = yield dut.checker.err_count.status
|
||||
assert errors == 2, errors
|
||||
error_addr = yield dut.checker.error_addr.status
|
||||
assert error_addr == 21, error_addr
|
||||
error_wanted = yield dut.checker.core.error_wanted
|
||||
assert error_wanted == 0xfff1ff1f, error_wanted
|
||||
error_actual = yield dut.checker.core.error_actual
|
||||
assert error_actual == 0x210, error_actual
|
||||
err_addr = yield dut.checker.err_addr.status
|
||||
assert err_addr == 21, err_addr
|
||||
err_expect = yield dut.checker.core.err_expect
|
||||
assert err_expect == 0xfff1ff1f, err_expect
|
||||
err_actual = yield dut.checker.core.err_actual
|
||||
assert err_actual == 0x210, err_actual
|
||||
|
||||
yield from toggle_re(dut.checker.start)
|
||||
for i in range(8):
|
||||
|
@ -192,18 +192,18 @@ def main_generator(dut, mem):
|
|||
yield
|
||||
done = yield dut.checker.done.status
|
||||
assert done, done
|
||||
started = yield dut.checker.core.started
|
||||
assert started, started
|
||||
running = yield dut.checker.core.running
|
||||
assert running, running
|
||||
for i in range(16):
|
||||
yield
|
||||
|
||||
error_addr = yield dut.checker.error_addr.status
|
||||
error_wanted = yield dut.checker.core.error_wanted
|
||||
error_actual = yield dut.checker.core.error_actual
|
||||
errors = yield dut.checker.error_count.status
|
||||
err_addr = yield dut.checker.err_addr.status
|
||||
err_expect = yield dut.checker.core.err_expect
|
||||
err_actual = yield dut.checker.core.err_actual
|
||||
errors = yield dut.checker.err_count.status
|
||||
assert errors == 2, errors
|
||||
error_addr = yield dut.checker.error_addr.status
|
||||
assert error_addr == 0, error_addr
|
||||
err_addr = yield dut.checker.err_addr.status
|
||||
assert err_addr == 0, err_addr
|
||||
|
||||
yield
|
||||
yield
|
||||
|
|
|
@ -19,8 +19,8 @@ def reset_bist_module(module):
|
|||
yield
|
||||
|
||||
# Check some initial conditions are correct after reset.
|
||||
started = yield module.core.started
|
||||
assert started == 0, started
|
||||
running = yield module.core.running
|
||||
assert running == 0, running
|
||||
|
||||
done = yield module.done.status
|
||||
assert not done, done
|
||||
|
|
Loading…
Reference in a new issue