Commit 27f60b2e authored by Florent Kermarrec's avatar Florent Kermarrec

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

Pinout from https://github.com/360nosc0pe project.
parent d42af3ea
...@@ -104,6 +104,7 @@ Repurposed FPGA hardware that has been "documented" by enthusiasts :), allows yo ...@@ -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 |
......
#!/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)
#!/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()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment