From cb324ea47c1f19e06ad2d6c054584c6cc6b3cb6c Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 23 May 2016 14:17:22 +0200 Subject: [PATCH] frontend/bist: LiteDRAMBISTGenerator can now be asynchronous --- litedram/frontend/bist.py | 79 +++++++++++++++++++++++++++++---------- test/bist_tb.py | 12 ++++-- 2 files changed, 68 insertions(+), 23 deletions(-) diff --git a/litedram/frontend/bist.py b/litedram/frontend/bist.py index f0c7f77..d7ede79 100644 --- a/litedram/frontend/bist.py +++ b/litedram/frontend/bist.py @@ -2,6 +2,7 @@ from functools import reduce from operator import xor from litex.gen import * +from litex.gen.genlib.cdc import PulseSynchronizer, BusSynchronizer from litex.soc.interconnect.csr import * @@ -30,8 +31,44 @@ class LFSR(Module): ] -class LiteDRAMBISTGenerator(Module, AutoCSR): +class _LiteDRAMBISTGenerator(Module): def __init__(self, dram_port): + self.reset = Signal() + self.shoot = Signal() + self.done = Signal() + self.base = Signal(dram_port.aw) + self.length = Signal(dram_port.aw) + + # # # + + self.submodules.dma = dma = LiteDRAMDMAWriter(dram_port) + + self.submodules.lfsr = lfsr = LFSR(dram_port.dw) + self.comb += lfsr.reset.eq(self.reset) + + enable = Signal() + counter = Signal(dram_port.aw) + self.comb += enable.eq(counter != 0) + self.sync += [ + If(self.shoot, + counter.eq(self.length) + ).Elif(lfsr.ce, + counter.eq(counter - 1) + ) + ] + + self.comb += [ + dma.sink.valid.eq(enable), + dma.sink.address.eq(self.base + counter), + dma.sink.data.eq(lfsr.o), + lfsr.ce.eq(enable & dma.sink.ready), + + self.done.eq(~enable) + ] + + +class LiteDRAMBISTGenerator(Module, AutoCSR): + def __init__(self, dram_port, cd="sys"): self.reset = CSR() self.shoot = CSR() self.done = CSRStatus() @@ -40,29 +77,33 @@ class LiteDRAMBISTGenerator(Module, AutoCSR): # # # - self.submodules.dma = dma = LiteDRAMDMAWriter(dram_port) + generator = _LiteDRAMBISTGenerator(dram_port) + self.submodules += ClockDomainsRenamer(cd)(generator) - self.submodules.lfsr = lfsr = LFSR(dram_port.dw) - self.comb += lfsr.reset.eq(self.reset.re) + reset_sync = PulseSynchronizer("sys", cd) + shoot_sync = PulseSynchronizer("sys", cd) + done_sync = BusSynchronizer(1, cd, "sys") + self.submodules += reset_sync, shoot_sync, done_sync - enable = Signal() - counter = Signal(dram_port.aw) - self.comb += enable.eq(counter != 0) - self.sync += [ - If(self.shoot.re, - counter.eq(self.length.storage) - ).Elif(lfsr.ce, - counter.eq(counter - 1) - ) - ] + base_sync = BusSynchronizer(dram_port.aw, "sys", cd, 8) + length_sync = BusSynchronizer(dram_port.aw, "sys", cd, 8) + self.submodules += base_sync, length_sync self.comb += [ - dma.sink.valid.eq(enable), - dma.sink.address.eq(self.base.storage + counter), - dma.sink.data.eq(lfsr.o), - lfsr.ce.eq(enable & dma.sink.ready), + reset_sync.i.eq(self.reset.re), + generator.reset.eq(reset_sync.o), - self.done.status.eq(~enable) + shoot_sync.i.eq(self.shoot.re), + generator.shoot.eq(shoot_sync.o), + + done_sync.i.eq(generator.done), + self.done.status.eq(done_sync.o), + + base_sync.i.eq(self.base.storage), + generator.base.eq(base_sync.o), + + length_sync.i.eq(self.length.storage), + generator.length.eq(length_sync.o) ] diff --git a/test/bist_tb.py b/test/bist_tb.py index d081e4c..160d378 100644 --- a/test/bist_tb.py +++ b/test/bist_tb.py @@ -21,21 +21,25 @@ def main_generator(dut): # write yield dut.generator.base.storage.eq(16) yield dut.generator.length.storage.eq(64) - yield + for i in range(8): + yield yield dut.generator.shoot.re.eq(1) yield yield dut.generator.shoot.re.eq(0) - yield + for i in range(8): + yield while((yield dut.generator.done.status) == 0): yield # read yield dut.checker.base.storage.eq(16) yield dut.checker.length.storage.eq(64) - yield + for i in range(8): + yield yield dut.checker.shoot.re.eq(1) yield yield dut.checker.shoot.re.eq(0) - yield + for i in range(8): + yield while((yield dut.checker.done.status) == 0): yield # check