blob: 6e6e3fbd208052a109d1d376be1940bd353b2160 [file] [log] [blame]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright (C) 2017-2020 The Project X-Ray Authors.
#
# Use of this source code is governed by a ISC-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/ISC
#
# SPDX-License-Identifier: ISC
import sys
import time
import argparse
from litex import RemoteClient
from sdram_init import *
def identify_fpga(wb):
""" Gets the FPGA identifier and prints it on terminal."""
fpga_id = ""
for i in range(256):
c = chr(wb.read(wb.bases.identifier_mem + 4 * i) & 0xff)
fpga_id += c
if c == "\0":
break
print(fpga_id)
def seed_to_data(seed, random=True):
if random:
return (1664525 * seed + 1013904223) & 0xffffffff
else:
return seed
def write_pattern(wb, length):
for i in range(length):
wb.write(wb.mems.main_ram.base + 4 * i, seed_to_data(i))
def check_pattern(wb, length, debug=False):
errors = 0
for i in range(length):
error = 0
if wb.read(wb.mems.main_ram.base + 4 * i) != seed_to_data(i):
error = 1
if debug:
print(
"{}: 0x{:08x}, 0x{:08x} KO".format(
i, wb.read(wb.mems.main_ram.base + 4 * i),
seed_to_data(i)))
else:
if debug:
print(
"{}: 0x{:08x}, 0x{:08x} OK".format(
i, wb.read(wb.mems.main_ram.base + 4 * i),
seed_to_data(i)))
errors += error
return errors
def find_bitslips_delays(wb):
""" Finds bitslip and delay values that can be used with the implemented DDR design."""
nbitslips = 8
ndelays = 32
nmodules = 2
nwords = 16
final_bitslip = None
final_delay = None
for bitslip in range(nbitslips):
print("bitslip {:d}: |".format(bitslip), end="")
for delay in range(ndelays):
for module in range(nmodules):
wb.regs.ddrphy_dly_sel.write(1 << module)
wb.regs.ddrphy_rdly_dq_rst.write(1)
wb.regs.ddrphy_rdly_dq_bitslip_rst.write(1)
for i in range(bitslip):
wb.regs.ddrphy_rdly_dq_bitslip.write(1)
for i in range(delay):
wb.regs.ddrphy_rdly_dq_inc.write(1)
write_pattern(wb, nwords)
errors = check_pattern(wb, nwords)
if errors:
print("..|", end="")
else:
print("{:02d}|".format(delay), end="")
final_bitslip = bitslip if final_bitslip is None else final_bitslip
final_delay = delay if final_delay is None else final_delay
sys.stdout.flush()
print("")
assert final_bitslip is not None and final_delay is not None, "bitslip/delay values not found"
return final_bitslip, final_delay
def set_bitslip_delay(wb, bitslip, delay):
""" Sets bitslip and delay values."""
nmodules = 2
for module in range(nmodules):
wb.regs.ddrphy_dly_sel.write(1 << module)
wb.regs.ddrphy_rdly_dq_rst.write(1)
wb.regs.ddrphy_rdly_dq_bitslip_rst.write(1)
for i in range(bitslip):
wb.regs.ddrphy_rdly_dq_bitslip.write(1)
for i in range(delay):
wb.regs.ddrphy_rdly_dq_inc.write(1)
def read_word_offset(read_only=False):
word = None
if not read_only:
print("\n==================================================\n")
print(
"Set a byte long word to write to memory (e.g. 0xdeadbeef): ",
end="")
word = int(input(), 16) & 0xffffffff
print("\n==================================================\n")
print("Set offset from base memory address: ", end="")
offset = int(input())
print("\n==================================================\n")
print("Set number of words to read or write: ", end="")
length = int(input())
return word, offset, length
def write_user_pattern(wb, offset, length, pattern):
for i in range(length):
wb.write(wb.mems.main_ram.base + 4 * (offset + i), pattern)
def read_user_pattern(wb, offset, length, pattern=None):
for i in range(length):
read_value = wb.read(wb.mems.main_ram.base + 4 * (offset + i))
if pattern is None:
print("0x{:08x}".format(read_value))
else:
if read_value == pattern:
outcome = "CORRECT"
else:
outcome = "INCORRECT"
print(
"{} --> 0x{:08x}, 0x{:08x}".format(
outcome, read_value, pattern))
def start_command_interface(wb):
cmd_list = """
Commands list:
0 --> Write memory
1 --> Read memory
2 --> Write/Read memory
3 --> Print commands list
4 --> Exit
"""
print(cmd_list)
while True:
print("\nWaiting for command: ", end="")
cmd = int(input())
if cmd == 0:
word, offset, length = read_word_offset()
write_user_pattern(wb, offset, length, word)
elif cmd == 1:
word, offset, length = read_word_offset(True)
read_user_pattern(wb, offset, length)
elif cmd == 2:
word, offset, length = read_word_offset()
write_user_pattern(wb, offset, length, word)
read_user_pattern(wb, offset, length, word)
elif cmd == 3:
print(cmd_list)
elif cmd == 4:
break
else:
print("Command not recognized, try again...")
def main():
parser = argparse.ArgumentParser(
description="Script to test correct DDR behaviour.")
parser.add_argument(
'--bitslip', default=None, help="Defines a bitslip value.")
parser.add_argument('--delay', default=None, help="Defines a delay value.")
args = parser.parse_args()
wb = RemoteClient(debug=False)
wb.open()
# software control
wb.regs.sdram_dfii_control.write(0)
# sdram initialization
for i, (comment, a, ba, cmd, delay) in enumerate(init_sequence):
print(comment)
wb.regs.sdram_dfii_pi0_address.write(a)
wb.regs.sdram_dfii_pi0_baddress.write(ba)
if i < 2:
wb.regs.sdram_dfii_control.write(cmd)
else:
wb.regs.sdram_dfii_pi0_command.write(cmd)
wb.regs.sdram_dfii_pi0_command_issue.write(1)
# hardware control
wb.regs.sdram_dfii_control.write(dfii_control_sel)
if args.bitslip is None or args.delay is None:
bitslip, delay = find_bitslips_delays(wb)
else:
bitslip = int(args.bitslip)
delay = int(args.delay)
set_bitslip_delay(wb, bitslip, delay)
start_command_interface(wb)
wb.close()
if __name__ == "__main__":
main()