mirror of
https://github.com/enjoy-digital/litedram.git
synced 2025-01-04 09:52:25 -05:00
8ff2f8779b
Also include ability to see address of error and expected verse actual data values. Extend the test bench to test this functionality.
99 lines
2.9 KiB
Python
99 lines
2.9 KiB
Python
from litex.gen import *
|
|
|
|
|
|
def toggle_re(reg):
|
|
resig = reg.re
|
|
# Check that reset isn't set
|
|
reval = yield resig
|
|
assert not reval, reval
|
|
yield resig.eq(1)
|
|
yield
|
|
yield resig.eq(0)
|
|
|
|
|
|
def reset_bist_module(module):
|
|
# Toggle the reset
|
|
yield from toggle_re(module.reset)
|
|
# Takes 8 more clock cycles for the reset to have an effect
|
|
for i in range(8):
|
|
yield
|
|
|
|
# Check some initial conditions are correct after reset.
|
|
started = yield module.core.started
|
|
assert started == 0, started
|
|
|
|
done = yield module.done.status
|
|
assert not done, done
|
|
|
|
|
|
def seed_to_data(seed, random=True, nbits=32):
|
|
if nbits == 32:
|
|
if random:
|
|
return (seed * 0x31415979 + 1) & 0xffffffff
|
|
else:
|
|
return seed
|
|
else:
|
|
assert nbits%32 == 0
|
|
data = 0
|
|
for i in range(nbits//32):
|
|
data = data << 32
|
|
data |= seed_to_data(seed*nbits//32 + i, random, 32)
|
|
return data
|
|
|
|
|
|
class DRAMMemory:
|
|
def __init__(self, width, depth, init=[]):
|
|
self.width = width
|
|
self.depth = depth
|
|
self.mem = []
|
|
for d in init:
|
|
self.mem.append(d)
|
|
for _ in range(depth-len(init)):
|
|
self.mem.append(0)
|
|
|
|
@passive
|
|
def read_generator(self, dram_port):
|
|
address = 0
|
|
pending = 0
|
|
yield dram_port.cmd.ready.eq(0)
|
|
while True:
|
|
yield dram_port.rdata.valid.eq(0)
|
|
if pending:
|
|
yield dram_port.rdata.valid.eq(1)
|
|
yield dram_port.rdata.data.eq(self.mem[address%self.depth])
|
|
yield
|
|
yield dram_port.rdata.valid.eq(0)
|
|
yield dram_port.rdata.data.eq(0)
|
|
pending = 0
|
|
elif (yield dram_port.cmd.valid):
|
|
pending = not (yield dram_port.cmd.we)
|
|
address = (yield dram_port.cmd.adr)
|
|
if pending:
|
|
yield dram_port.cmd.ready.eq(1)
|
|
yield
|
|
yield dram_port.cmd.ready.eq(0)
|
|
yield
|
|
|
|
@passive
|
|
def write_generator(self, dram_port):
|
|
address = 0
|
|
pending = 0
|
|
yield dram_port.cmd.ready.eq(0)
|
|
while True:
|
|
yield dram_port.wdata.ready.eq(0)
|
|
if pending:
|
|
yield dram_port.wdata.ready.eq(1)
|
|
yield
|
|
self.mem[address%self.depth] = (yield dram_port.wdata.data) # TODO manage we
|
|
yield dram_port.wdata.ready.eq(0)
|
|
yield
|
|
pending = 0
|
|
yield
|
|
elif (yield dram_port.cmd.valid):
|
|
pending = (yield dram_port.cmd.we)
|
|
address = (yield dram_port.cmd.adr)
|
|
if pending:
|
|
yield dram_port.cmd.ready.eq(1)
|
|
yield
|
|
yield dram_port.cmd.ready.eq(0)
|
|
yield
|