Skip to content

Instantly share code, notes, and snippets.

@lschuermann
Created July 23, 2021 09:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lschuermann/9a748ad2d8904d5a4bf9361f4b37485d to your computer and use it in GitHub Desktop.
Save lschuermann/9a748ad2d8904d5a4bf9361f4b37485d to your computer and use it in GitHub Desktop.
NetFPGA SUME DRAM issues
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2021 Leon Schuermann <leon@is.currently.online>
# SPDX-License-Identifier: BSD-2-Clause
from litex.build.generic_platform import *
from litex.build.xilinx import XilinxPlatform, VivadoProgrammer
# IOs ----------------------------------------------------------------------------------------------
_io = [
# System Clock / Rst
("clk200", 0,
Subsignal("p", Pins("H19"), IOStandard("LVDS")),
Subsignal("n", Pins("G18"), IOStandard("LVDS")),
),
# DDR3 SODIMM Clock Signal.
#
# Should not be used for other purposes in designs that use the
# DDR3 memory.
("ddrclk233", 0,
Subsignal("p", Pins("AU14"), IOStandard("LVDS")),
Subsignal("n", Pins("AU13"), IOStandard("LVDS")),
),
# PMOD A pmod_ja_2
("cpu_reset_n", 0, Pins("AW17"), IOStandard("LVCMOS15")),
# Leds
("user_led", 0, Pins("AR22"), IOStandard("LVCMOS18")),
("user_led", 1, Pins("AR23"), IOStandard("LVCMOS18")),
# Buttons
("user_btn", 0, Pins("AR13"), IOStandard("LVCMOS15")),
("user_btn", 1, Pins("BB12"), IOStandard("LVCMOS15")),
# PMOD A serial output
("serial", 0,
#Subsignal("tx", Pins("AV19")), # pmod_ja_4
#Subsignal("rx", Pins("AU19")), # pmod_ja_3
Subsignal("tx", Pins("AV16")), # pmod_ja_9
Subsignal("rx", Pins("AW16")), # pmod_ja_10
IOStandard("LVCMOS15")
),
("pmod_a_noe", 0, Pins("C40"), IOStandard("LVCMOS15")),
("pmod_a_dir", 1, Pins("AT16"), IOStandard("LVCMOS15")),
("pmod_a_dir", 2, Pins("AU16"), IOStandard("LVCMOS15")),
("pmod_a_dir", 3, Pins("BB19"), IOStandard("LVCMOS15")),
("pmod_a_dir", 4, Pins("AV20"), IOStandard("LVCMOS15")),
("pmod_a_dir", 7, Pins("AW20"), IOStandard("LVCMOS15")),
("pmod_a_dir", 8, Pins("BA17"), IOStandard("LVCMOS15")),
("pmod_a_dir", 9, Pins("BB17"), IOStandard("LVCMOS15")),
("pmod_a_dir", 10, Pins("AY20"), IOStandard("LVCMOS15")),
# DDR3 SDRAM
("ddram_a", 0,
Subsignal("a", Pins(
"G17 J20 H18 D21 D18 C21 J17 E17",
"B21 A19 E20 A17 K19 C20 F17 K17"),
IOStandard("SSTL15")),
Subsignal("ba", Pins("F20 D17 B19"), IOStandard("SSTL15")),
Subsignal("ras_n", Pins("B17"), IOStandard("SSTL15")),
Subsignal("cas_n", Pins("D20"), IOStandard("SSTL15")),
Subsignal("we_n", Pins("H20"), IOStandard("SSTL15")),
Subsignal("cs_n", Pins("C19"), IOStandard("SSTL15")),
Subsignal("dm", Pins(
"M13 J13 G14 A14 B23 D26 A31 F31"),
IOStandard("SSTL15")),
Subsignal("dq", Pins(
"M11 M12 N14 M14 N13 L12 L14 N15",
"K15 K14 H14 L16 K13 H13 H15 J15",
"E14 F15 F16 E15 G12 F12 E13 F14",
"D15 D16 B16 C16 E12 C13 B14 D13",
"C24 A25 B26 B27 B22 A22 C23 A24",
"D25 C25 E24 E23 D22 D23 E22 F22",
"A29 A30 A32 D28 C28 C29 D27 C31",
"D30 E30 C30 F30 F27 F26 F29 E29"),
IOStandard("SSTL15_T_DCI")),
Subsignal("dqs_p", Pins(
"N16 K12 H16 C15 A26 F25 B28 E27",
IOStandard("DIFF_SSTL15_T_DCI")),
Subsignal("dqs_n", Pins(
"M16 J12 G16 C14 A27 E25 B29 E28"),
IOStandard("DIFF_SSTL15_T_DCI")),
Subsignal("clk_p", Pins("G19"), IOStandard("DIFF_SSTL15")),
Subsignal("clk_n", Pins("F19"), IOStandard("DIFF_SSTL15")),
Subsignal("cke", Pins("M17"), IOStandard("SSTL15")),
Subsignal("odt", Pins("J18"), IOStandard("SSTL15")),
Subsignal("reset_n", Pins("A15"), IOStandard("LVCMOS15")),
# Misc("SLEW"), SLEW=""
Misc("VCCAUX_IO=HIGH"),
),
# TODO: 10G Ethernet
]
# Connectors ---------------------------------------------------------------------------------------
_connectors = []
# Platform -----------------------------------------------------------------------------------------
class Platform(XilinxPlatform):
default_clk_name = "clk200"
default_clk_period = 1e9/200e6
def __init__(self):
XilinxPlatform.__init__(self, "xc7vx690tffg1761-3", _io, _connectors, toolchain="vivado")
self.add_platform_command("set_property CFGBVS GND [current_design]")
self.add_platform_command("set_property CONFIG_VOLTAGE 1.8 [current_design]")
def do_finalize(self, fragment):
XilinxPlatform.do_finalize(self, fragment)
self.add_period_constraint(self.lookup_request("clk200", loose=True), 1e9/200e6)
__ _ __ _ __
/ / (_) /____ | |/_/
/ /__/ / __/ -_)> <
/____/_/\__/\__/_/|_|
Build your hardware, easily!
(c) Copyright 2012-2021 Enjoy-Digital
(c) Copyright 2007-2015 M-Labs
BIOS CRC passed (8d1506d5)
Migen git sha1: --------
LiteX git sha1: --------
--=============== SoC ==================--
CPU: VexRiscv_Secure @ 100MHz
BUS: WISHBONE 32-bit @ 4GiB
CSR: 32-bit data
ROM: 128KiB
SRAM: 8KiB
L2: 8KiB
SDRAM: 1048576KiB 64-bit @ 800MT/s (CL-6 CWL-5)
--========== Initialization ============--
Initializing SDRAM @0x40000000...
Switching SDRAM to software control.
Write leveling:
tCK equivalent taps: 32
Cmd/Clk scan (0-16)
|0001100000001111| best: 5
Setting Cmd/Clk delay to 5 taps.
Data scan:
m0: |110000000000000000111111| delay: 18
m1: |111000000000000000111111| delay: 18
m2: |111111111111111111111111| delay: 00
m3: |111100000000000000011111| delay: -
m4: |111111111111000000000000| delay: 00
m5: |111111111110000000000000| delay: 00
m6: |111111111111111000000000| delay: 00
m7: |111111111111110000000000| delay: 00
Write latency calibration:
m0:0 m1:0 m2:6 m3:6 m4:6 m5:6 m6:6 m7:6
Write DQ-DQS training:
m0: |00000000000011111111111110000000| delays: 18+-06
m1: |00000000000111111111111100000000| delays: 17+-06
m2: |000000000000000000000000000000000| delays: -
m3: |11111110000000000000000000000000| delays: 03+-03
m4: |11111100000000000000000000000000| delays: 03+-03
m5: |11111110000000000000000000000000| delays: 03+-03
m6: |11111100000000000000000000000000| delays: 03+-03
m7: |11111100000000000000000000000000| delays: 03+-03
Read leveling:
m0, b00: |00000000000000000000000000000000| delays: -
m0, b01: |00000000000000000000000000000000| delays: -
m0, b02: |11111111111100000000000000000000| delays: 06+-06
m0, b03: |00000000000000011111111111110000| delays: 21+-06
m0, b04: |00000000000000000000000000000001| delays: 31+-00
m0, b05: |00000000000000000000000000000000| delays: -
m0, b06: |00000000000000000000000000000000| delays: -
m0, b07: |00000000000000000000000000000000| delays: -
best: m0, b03 delays: 21+-06
m1, b00: |00000000000000000000000000000000| delays: -
m1, b01: |00000000000000000000000000000000| delays: -
m1, b02: |11111111111000000000000000000000| delays: 05+-05
m1, b03: |00000000000000111111111111100000| delays: 20+-06
m1, b04: |00000000000000000000000000000011| delays: 31+-01
m1, b05: |00000000000000000000000000000000| delays: -
m1, b06: |00000000000000000000000000000000| delays: -
m1, b07: |00000000000000000000000000000000| delays: -
best: m1, b03 delays: 21+-07
m2, b00: |00000000000000000000000000000000| delays: -
m2, b01: |00000000000000000000000000000000| delays: -
m2, b02: |00000000000000000000000000000000| delays: -
m2, b03: |00000000000000000000000000000000| delays: -
m2, b04: |00000000000000000000000000000000| delays: -
m2, b05: |00000000000000000000000000000000| delays: -
m2, b06: |00000000000000000000000000000000| delays: -
m2, b07: |00000000000000000000000000000000| delays: -
best: m2, b04 delays: -
m3, b00: |00000000000000000000000000000000| delays: -
m3, b01: |00000000000000000000000000000000| delays: -
m3, b02: |11111111100000000000000000000000| delays: 04+-04
m3, b03: |00000000000011111111111110000000| delays: 18+-06
m3, b04: |00000000000000000000000000011111| delays: 29+-02
m3, b05: |00000000000000000000000000000000| delays: -
m3, b06: |00000000000000000000000000000000| delays: -
m3, b07: |00000000000000000000000000000000| delays: -
best: m3, b03 delays: 18+-07
m4, b00: |00000000000000000000000000000000| delays: -
m4, b01: |00000000000000000000000000000000| delays: -
m4, b02: |11100000000000000000000000000000| delays: 01+-01
m4, b03: |00000011111111111111000000000000| delays: 13+-07
m4, b04: |00000000000000000000001111111111| delays: 27+-05
m4, b05: |00000000000000000000000000000000| delays: -
m4, b06: |00000000000000000000000000000000| delays: -
m4, b07: |00000000000000000000000000000000| delays: -
best: m4, b03 delays: 13+-07
m5, b00: |00000000000000000000000000000000| delays: -
m5, b01: |00000000000000000000000000000000| delays: -
m5, b02: |11000000000000000000000000000000| delays: 01+-01
m5, b03: |00000111111111111110000000000000| delays: 12+-07
m5, b04: |00000000000000000000011111111111| delays: 26+-05
m5, b05: |00000000000000000000000000000000| delays: -
m5, b06: |00000000000000000000000000000000| delays: -
m5, b07: |00000000000000000000000000000000| delays: -
best: m5, b03 delays: 12+-07
m6, b00: |00000000000000000000000000000000| delays: -
m6, b01: |00000000000000000000000000000000| delays: -
m6, b02: |10000000000000000000000000000000| delays: 00+-00
m6, b03: |00001111111111111100000000000000| delays: 11+-07
m6, b04: |00000000000000000000111111111111| delays: 26+-06
m6, b05: |00000000000000000000000000000000| delays: -
m6, b06: |00000000000000000000000000000000| delays: -
m6, b07: |00000000000000000000000000000000| delays: -
best: m6, b03 delays: 11+-07
m7, b00: |00000000000000000000000000000000| delays: -
m7, b01: |00000000000000000000000000000000| delays: -
m7, b02: |10000000000000000000000000000000| delays: 00+-00
m7, b03: |00000111111111111100000000000000| delays: 11+-06
m7, b04: |00000000000000000000011111111111| delays: 26+-05
m7, b05: |00000000000000000000000000000000| delays: -
m7, b06: |00000000000000000000000000000000| delays: -
m7, b07: |00000000000000000000000000000000| delays: -
best: m7, b03 delays: 11+-06
Switching SDRAM to hardware control.
Memtest at 0x40000000 (2.0MiB)...
Write: 0x40000000-0x40200000 2.0MiB
Read: 0x40000000-0x40200000 2.0MiB
bus errors: 64/256
addr errors: 0/8192
data errors: 147738/524288
Memtest KO
Memory initialization failed
--============= Console ================--
litex> mem_list
Available memory regions:
ROM 0x00000000 0x20000
SRAM 0x10000000 0x2000
MAIN_RAM 0x40000000 0x40000000
CSR 0xf0000000 0x10000
litex> mem_write 0x40000000 0xA55A1234 0x10000000
litex> mem_read 0x48001234 32
Memory dump:
0x48001234 34 12 5e a5 34 12 5a a5 34 12 5e a5 34 12 5a a5 4.^.4.Z.4.^.4.Z.
0x48001244 34 12 5e a5 34 12 5a a5 34 12 5e a5 34 12 5a a5 4.^.4.Z.4.^.4.Z.
litex> ident
Ident: LiteX SoC on NetFPGA-SUME
litex> uptime
Uptime: 179603294 sys_clk cycles / 1 seconds
litex>
#!/usr/bin/env python3
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2021 Leon Schuermann <leon@is.currently.online>
# SPDX-License-Identifier: BSD-2-Clause
import os
import argparse
import math
from migen import *
from litex.build.xilinx.vivado import vivado_build_args, vivado_build_argdict
from litedram.modules import MT8KTF51264
from litedram.phy import s7ddrphy
from litex.soc.cores.clock import *
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *
from litex.soc.cores.led import LedChaser
from litex_boards.platforms import netfpga_sume
# CRG ----------------------------------------------------------------------------------------------
class _CRG(Module):
def __init__(self, platform, sys_clk_freq):
self.rst = Signal()
self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
self.clock_domains.cd_idelay = ClockDomain()
# # #
self.submodules.pll = pll = S7MMCM(speedgrade=-2)
self.comb += pll.reset.eq(~platform.request("cpu_reset_n") | self.rst)
pll.register_clkin(platform.request("clk200"), 200e6)
pll.create_clkout(self.cd_sys, sys_clk_freq)
pll.create_clkout(self.cd_sys4x, 4*sys_clk_freq)
pll.create_clkout(self.cd_idelay, 200e6)
platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin) # Ignore sys_clk to pll.clkin path created by SoC's rst.
self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_idelay)
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self,
sys_clk_freq=int(100e6),
eth_ip="192.168.1.50",
eth_dynamic_ip=False,
with_ethernet=False,
with_etherbone=False,
ident_version=True,
**kwargs):
platform = netfpga_sume.Platform()
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq,
ident = "LiteX SoC on NetFPGA-SUME",
ident_version = ident_version,
**kwargs)
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = _CRG(platform, sys_clk_freq)
# DDR3 SDRAM -------------------------------------------------------------------------------
if not self.integrated_main_ram_size:
self.submodules.ddrphy = s7ddrphy.V7DDRPHY(platform.request("ddram_a"),
memtype = "DDR3",
nphases = 4,
sys_clk_freq = sys_clk_freq,
)
self.add_sdram("sdram",
phy = self.ddrphy,
module = MT8KTF51264(sys_clk_freq, "1:4"),
origin = self.mem_map["main_ram"],
size = kwargs.get("max_sdram_size", 0x40000000),
l2_cache_size = kwargs.get("l2_size", 8192),
)
# PMOD configuration -----------------------------------------------------------------------
self.comb += [
# Set pin directions on level shifter
platform.request("pmod_a_dir", 8).eq(0), # Input: CPU reset pin
platform.request("pmod_a_dir", 10).eq(0), # Input: Serial RX
platform.request("pmod_a_dir", 9).eq(1), # Output: Serial TX
# Enable outputs
platform.request("pmod_a_noe", 0).eq(0),
]
# Leds -------------------------------------------------------------------------------------
leds = platform.request_all("user_led")
self.submodules.leds = LedChaser(
pads = leds,
sys_clk_freq = sys_clk_freq)
# Build --------------------------------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser(description="LiteX SoC on NetFPGA-SUME")
parser.add_argument("--build", action="store_true", help="Build bitstream")
parser.add_argument("--load", action="store_true", help="Load bitstream")
parser.add_argument("--sys-clk-freq", default=100e6, help="System clock frequency (default: 100MHz)")
ethopts = parser.add_mutually_exclusive_group()
ethopts.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support")
ethopts.add_argument("--with-etherbone", action="store_true", help="Enable Etherbone support")
parser.add_argument("--eth-ip", default="192.168.1.50", type=str, help="Ethernet/Etherbone IP address")
parser.add_argument("--eth-dynamic-ip", action="store_true", help="Enable dynamic Ethernet IP addresses setting")
builder_args(parser)
soc_core_args(parser)
vivado_build_args(parser)
args = parser.parse_args()
assert not (args.with_etherbone and args.eth_dynamic_ip)
soc = BaseSoC(
sys_clk_freq = int(float(args.sys_clk_freq)),
with_ethernet = args.with_ethernet,
with_etherbone = args.with_etherbone,
eth_ip = args.eth_ip,
eth_dynamic_ip = args.eth_dynamic_ip,
ident_version = args.ident_version,
**soc_core_argdict(args)
)
builder = Builder(soc, **builder_argdict(args))
builder_kwargs = vivado_build_argdict(args)
builder.build(**builder_kwargs, run=args.build)
if args.load:
prog = soc.platform.create_programmer()
prog.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".bit"))
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment