add initial Siglent SDS1104X-E support (Ethernet & DDR3 validated).

Pinout from https://github.com/360nosc0pe project.
This commit is contained in:
Florent Kermarrec 2020-11-13 12:16:59 +01:00
parent d42af3ea19
commit 27f60b2e93
3 changed files with 247 additions and 0 deletions

View File

@ -104,6 +104,7 @@ Repurposed FPGA hardware that has been "documented" by enthusiasts :), allows yo
| Name | FPGA Family | FPGA device | Sys-Clk | TTY | DRAM | Ethernet | Flash | | Name | FPGA Family | FPGA device | Sys-Clk | TTY | DRAM | Ethernet | Flash |
|--------------|---------------------|---------------|----------|------|--------------------|--------------------|-------------| |--------------|---------------------|---------------|----------|------|--------------------|--------------------|-------------|
| SDS1104X-E | Xilinx Zynq | XC7Z020 | 100MHz | Eth | 32-bit 256MB DDR3 | 100Mbps MII | ? |
| Colorlight5A | Lattice ECP5 | LFE5U-25F | 60MHz | IOs | 32-bit 8MB SDR | 2x 1Gbps RGMII | 4MB QSPI | | Colorlight5A | Lattice ECP5 | LFE5U-25F | 60MHz | IOs | 32-bit 8MB SDR | 2x 1Gbps RGMII | 4MB QSPI |
| Linsn RV901 | Xilinx Spartan6 | XC6SLX16 | 75MHz | IOs | 32-bit 8MB SDR | 2x 1Gbps RGMII | 4MB QSPI | | Linsn RV901 | Xilinx Spartan6 | XC6SLX16 | 75MHz | IOs | 32-bit 8MB SDR | 2x 1Gbps RGMII | 4MB QSPI |
| PanoLogic G2 | Xilinx Spartan6 | XC6SLX100-150 | 50MHz | IOs | 32-bit 128MB DDR2 | 1Gbps GMII | 16MB QSPI | | PanoLogic G2 | Xilinx Spartan6 | XC6SLX100-150 | 50MHz | IOs | 32-bit 128MB DDR2 | 1Gbps GMII | 16MB QSPI |

View File

@ -0,0 +1,119 @@
#!/usr/bin/env python3
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
from litex.build.generic_platform import *
from litex.build.xilinx import XilinxPlatform, VivadoProgrammer
# IOs ----------------------------------------------------------------------------------------------
_io = [ # Documented by https://github.com/360nosc0pe project.
# Leds
("user_led", 0, Pins("G16"), IOStandard("LVCMOS33")),
# Beeper
("beeper", 0, Pins("W17"), IOStandard("LVCMOS33")),
# Led Frontpanel
("led_frontpanel", 0,
Subsignal("rclk", Pins("N22")),
Subsignal("clk", Pins("R20")),
Subsignal("mosi", Pins("P22")),
Subsignal("oe", Pins("R21")),
IOStandard("LVCMOS33"),
),
# Button Frontpanel
("btn_frontpanel", 0,
Subsignal("clk", Pins("H18")),
Subsignal("clr", Pins("G19")),
Subsignal("miso", Pins("G17")),
IOStandard("LVCMOS33")
),
# LCD
("lcd", 0,
Subsignal("clk", Pins("D20")),
Subsignal("vsync", Pins("A21")),
Subsignal("hsync", Pins("A22")),
Subsignal("r", Pins("G22 F22 F21 F19 F18 F17")),
Subsignal("g", Pins("F16 E21 E20 E19 E18 E16")),
Subsignal("b", Pins("D22 D21 C22 C20 B22 B21")),
IOStandard("LVCMOS33"),
),
# MII Ethernet
("eth_clocks", 0,
Subsignal("tx", Pins("B19")),
Subsignal("rx", Pins("C17")),
IOStandard("LVCMOS33"),
),
("eth", 0,
Subsignal("rst_n", Pins("R6")),
Subsignal("mdio", Pins("E15")),
Subsignal("mdc", Pins("D15")),
Subsignal("rx_dv", Pins("A16")),
Subsignal("rx_er", Pins("C15")),
Subsignal("rx_data", Pins("D16 A17 B17 D17")),
Subsignal("tx_en", Pins("A18")),
Subsignal("tx_data", Pins("C18 A19 C19 B20")),
Subsignal("col", Pins("B16")),
Subsignal("crs", Pins("B15")),
IOStandard("LVCMOS33"),
),
# DDR3 SDRAM
("ddram", 0,
Subsignal("a", Pins(
"J21 K18 J18 R16 P16 T18 R18 T19",
"R19 P18 P17 P15 N15"),
IOStandard("SSTL135")),
Subsignal("ba", Pins("K21 J20 J22"), IOStandard("SSTL135")),
Subsignal("ras_n", Pins("L21"), IOStandard("SSTL135")),
Subsignal("cas_n", Pins("L22"), IOStandard("SSTL135")),
Subsignal("we_n", Pins("K19"), IOStandard("SSTL135")),
#Subsignal("cs_n", Pins(""), IOStandard("SSTL135")), # Pulled low.
#Subsignal("dm", Pins(""), IOStandard("SSTL135")), # Pulled low.
Subsignal("dq", Pins(
" T21 U21 T22 U22 W20 W21 U20 V20",
"AA22 AB22 AA21 AB21 AB19 AB20 Y19 AA19",
" W16 Y16 U17 V17 AA17 AB17 AA16 AB16",
" V14 V13 W13 Y14 AA14 Y13 AA13 AB14"),
IOStandard("SSTL135"),
Misc("IN_TERM=UNTUNED_SPLIT_40")),
Subsignal("dqs_p", Pins("V22 Y20 U15 W15"),
IOStandard("DIFF_SSTL135"),
Misc("IN_TERM=UNTUNED_SPLIT_40")),
Subsignal("dqs_n", Pins("W22 Y21 U16 Y15"),
IOStandard("DIFF_SSTL135"),
Misc("IN_TERM=UNTUNED_SPLIT_40")),
Subsignal("clk_p", Pins("T16"), IOStandard("DIFF_SSTL135")),
Subsignal("clk_n", Pins("T17"), IOStandard("DIFF_SSTL135")),
Subsignal("cke", Pins("M21"), IOStandard("SSTL135")),
Subsignal("odt", Pins("M22"), IOStandard("SSTL135")),
Subsignal("reset_n", Pins("V18"), IOStandard("SSTL135")),
Misc("SLEW=FAST"),
),
]
# Connectors ---------------------------------------------------------------------------------------
_connectors = []
# Platform -----------------------------------------------------------------------------------------
class Platform(XilinxPlatform):
def __init__(self):
XilinxPlatform.__init__(self, "xc7z020-clg484-1", _io, _connectors, toolchain="vivado")
def create_programmer(self):
return VivadoProgrammer()
def do_finalize(self, fragment):
XilinxPlatform.do_finalize(self, fragment)
self.add_period_constraint(self.lookup_request("eth_clocks:rx", loose=True), 1e9/25e6)
self.add_period_constraint(self.lookup_request("eth_clocks:tx", loose=True), 1e9/25e6)

127
litex_boards/targets/sds1104xe.py Executable file
View File

@ -0,0 +1,127 @@
#!/usr/bin/env python3
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
# Build/Use ----------------------------------------------------------------------------------------
# Build/Load bitstream:
# ./sds1104xe.py --with-etherbone --uart-name=crossover --csr-csv=csr.csv --build --load
#
# Test Ethernet:
# ping 192.168.1.50
#
# Test Console:
# litex_server --udp
# litex_crossover_uart (will create /dev/pts/X)
# litex_term /dev/pts/X
# --------------------------------------------------------------------------------------------------
import os
import argparse
from migen import *
from litex_boards.platforms import sds1104xe
from litex.build.xilinx.vivado import vivado_build_args, vivado_build_argdict
from litex.soc.cores.clock import *
from litex.soc.integration.soc_core import *
from litex.soc.integration.soc_sdram import *
from litex.soc.integration.builder import *
from litedram.modules import MT41K64M16
from litedram.phy import s7ddrphy
from liteeth.phy.mii import LiteEthPHYMII
# 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_sys4x_dqs = ClockDomain(reset_less=True)
self.clock_domains.cd_idelay = ClockDomain()
# # #
self.submodules.pll = pll = S7PLL(speedgrade=-1)
pll.register_clkin(ClockSignal("eth_tx"), 25e6)
pll.create_clkout(self.cd_sys, sys_clk_freq)
pll.create_clkout(self.cd_sys4x, 4*sys_clk_freq)
pll.create_clkout(self.cd_sys4x_dqs, 4*sys_clk_freq, phase=90)
pll.create_clkout(self.cd_idelay, 200e6)
self.submodules.idelayctrl = S7IDELAYCTRL(self.cd_idelay)
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self, sys_clk_freq=int(100e6), with_etherbone=False, **kwargs):
platform = sds1104xe.Platform()
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq,
ident = "LiteX SoC on Siglent SDS1104X-E",
ident_version = True,
**kwargs)
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = _CRG(platform, sys_clk_freq)
# DDR3 SDRAM -------------------------------------------------------------------------------
if not self.integrated_main_ram_size:
self.submodules.ddrphy = s7ddrphy.A7DDRPHY(platform.request("ddram"),
memtype = "DDR3",
nphases = 4,
sys_clk_freq = sys_clk_freq)
self.add_csr("ddrphy")
self.add_sdram("sdram",
phy = self.ddrphy,
module = MT41K64M16(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),
l2_cache_min_data_width = kwargs.get("min_l2_data_width", 128),
l2_cache_reverse = True
)
# Etherbone --------------------------------------------------------------------------------
if with_etherbone:
self.submodules.ethphy = LiteEthPHYMII(
clock_pads = self.platform.request("eth_clocks"),
pads = self.platform.request("eth"))
self.add_csr("ethphy")
self.add_etherbone(phy=self.ethphy)
# Build --------------------------------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser(description="LiteX SoC on SDS1104X-E")
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)")
parser.add_argument("--with-etherbone", action="store_true", help="Enable Etherbone support")
builder_args(parser)
soc_sdram_args(parser)
vivado_build_args(parser)
args = parser.parse_args()
soc = BaseSoC(
sys_clk_freq = int(float(args.sys_clk_freq)),
with_etherbone = args.with_etherbone,
**soc_sdram_argdict(args)
)
builder = Builder(soc, **builder_argdict(args))
builder.build(**vivado_build_argdict(args), run=args.build)
if args.load:
prog = soc.platform.create_programmer()
prog.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".bit"), device=1)
if __name__ == "__main__":
main()