mirror of
https://github.com/enjoy-digital/litedram.git
synced 2025-01-04 09:52:25 -05:00
test/test_bist: add generator test, remove async test
This commit is contained in:
parent
7677a853f1
commit
6a46ea3052
4 changed files with 102 additions and 168 deletions
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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)
|
Loading…
Reference in a new issue