[init] added colorlight i9+ based on XC7A50 FPGA
This commit is contained in:
parent
1f6e7f36a5
commit
322cc5d45b
|
@ -0,0 +1,132 @@
|
|||
#
|
||||
# This file is part of LiteX-Boards.
|
||||
#
|
||||
# Copyright (c) 2023 Charles-Henri Mousset <ch.mousset@gmail.com>
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
from litex.build.generic_platform import *
|
||||
from litex.build.xilinx import Xilinx7SeriesPlatform
|
||||
from litex.build.openocd import OpenOCD
|
||||
|
||||
# IOs ----------------------------------------------------------------------------------------------
|
||||
|
||||
_io = [
|
||||
("clk25", 0, Pins("K4"), IOStandard("LVCMOS33")),
|
||||
("user_led", 0, Pins("A18"), IOStandard("LVCMOS33")),
|
||||
|
||||
# RGMII Ethernet (B50612D)
|
||||
("eth_clocks", 0, # U5 is SDIO phy #0
|
||||
Subsignal("tx", Pins("A1")),
|
||||
Subsignal("rx", Pins("H4")),
|
||||
IOStandard("LVCMOS33")
|
||||
),
|
||||
("eth", 0,
|
||||
Subsignal("rst_n", Pins("H2")),
|
||||
Subsignal("mdio", Pins("G2")),
|
||||
Subsignal("mdc", Pins("G1")),
|
||||
Subsignal("rx_ctl", Pins("F1")),
|
||||
Subsignal("rx_data", Pins("E3 E2 E1 F3")),
|
||||
Subsignal("tx_ctl", Pins("D1")),
|
||||
Subsignal("tx_data", Pins("B2 B1 C2 D2")),
|
||||
IOStandard("LVCMOS33")
|
||||
),
|
||||
("eth_clocks", 1, # U9 is SDIO phy #1
|
||||
Subsignal("tx", Pins("M6")),
|
||||
Subsignal("rx", Pins("L3")),
|
||||
IOStandard("LVCMOS33")
|
||||
),
|
||||
("eth", 1,
|
||||
Subsignal("rst_n", Pins("H2")),
|
||||
Subsignal("mdio", Pins("G2")),
|
||||
Subsignal("mdc", Pins("G1")),
|
||||
Subsignal("rx_ctl", Pins("R1")),
|
||||
Subsignal("rx_data", Pins("N2 N3 P1 P2")),
|
||||
Subsignal("tx_ctl", Pins("N5")),
|
||||
Subsignal("tx_data", Pins("M5 M2 N4 P4")),
|
||||
IOStandard("LVCMOS33")
|
||||
),
|
||||
# M12L64322A
|
||||
("sdram_clock", 0, Pins("E14"), IOStandard("LVCMOS33")),
|
||||
("sdram", 0,
|
||||
Subsignal("a", Pins(
|
||||
"C20 C19 C13 F13 G13 G15 "
|
||||
"F14 F18 E13 E18 C14 A13")), # address pin A11 routed but NC on M12L64322A
|
||||
Subsignal("dq", Pins(
|
||||
"F21 E22 F20 E21 F19 D22 E19 D21 "
|
||||
"K21 L21 K22 M21 L20 M22 N20 M20 "
|
||||
"B18 D20 A19 A21 A20 B21 C22 B22 "
|
||||
"G21 G22 H20 H22 J20 J22 G20 J21 "
|
||||
)),
|
||||
Subsignal("we_n", Pins("D17")),
|
||||
Subsignal("ras_n", Pins("A14")),
|
||||
Subsignal("cas_n", Pins("D14")),
|
||||
#Subsignal("cs_n", Pins("")), # gnd
|
||||
#Subsignal("cke", Pins("")), # 3v3
|
||||
Subsignal("ba", Pins("D19 B13")),
|
||||
#Subsignal("dm", Pins("")), # gnd
|
||||
IOStandard("LVCMOS33"),
|
||||
Misc("SLEWRATE=FAST")
|
||||
),
|
||||
]
|
||||
|
||||
# Connectors ---------------------------------------------------------------------------------------
|
||||
|
||||
_connectors = [
|
||||
("dimm",
|
||||
"- "
|
||||
"GND 5V GND 5V GND 5V GND 5V GND 5V " # 1-10
|
||||
"GND 5V NC NC ETH1_1P ETH2_1P ETH1_1N ETH2_1N NC NC " # 11-20
|
||||
"ETH1_2N ETH2_2N ETH1_2P ETH2_2P NC NC ETH1_3P ETH2_3P ETH1_3N ETH2_3N " # 21-30
|
||||
"NC NC ETH1_4N ETH2_4N ETH1_4P ETH2_4P NC NC GND GND " # 31-40
|
||||
"R2 P5 P6 T6 R6 U7 T1 U6 T3 U5 " # 41-50
|
||||
"T4 V5 T4 U1 GND GND U2 H3 U3 J1 " # 51-60
|
||||
"V2 K1 V3 L1 W1 M1 Y1 J2 AA1 K2 " # 61-70
|
||||
"AB1 K3 W2 G3 Y2 J4 AB2 G4 AA3 F4 " # 71-80
|
||||
"AB3 L4 Y3 R3 W4 M3 AA4 V4 Y4 R4 " # 81-90
|
||||
"AB5 T5 AA5 J5 Y6 J6 AB6 W5 AA6 L5 " # 91-100
|
||||
"Y7 L6 AB7 W6 GND GND GND GND AA8 V7 " # 101-110
|
||||
"AB8 N13 Y8 N14 W7 P15 Y9 P16 V8 R16 " # 111-120
|
||||
"W9 N17 V9 V17 R14 P17 P14 U17 W17 T18 " # 121-130
|
||||
"Y18 R17 AA18 U18 W19 R18 AB18 N18 Y19 R19 " # 131-140
|
||||
"AA19 N19 V18 N15 V19 M16 AB20 M15 AA20 L15 " # 141-150
|
||||
"AA21 L16 AB21 K14 Y21 N22 GND GND AB22 J14 " # 151-160
|
||||
"W20 J15 Y22 J19 W21 H13 W22 H14 V20 H17 " # 161-170
|
||||
"V22 H15 U21 G18 U20 G17 T20 G16 P19 F16 " # 171-180
|
||||
"P20 F15 M18 E17 L19 E16 J17 D16 K18 D15 " # 181-190
|
||||
"K19 C18 K16 C17 H18 B20 H19 B17 NC NC" # 191-200
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
def pmod_uart(port="P2"):
|
||||
if port == "P2":
|
||||
return [
|
||||
("serial", 0,
|
||||
Subsignal("tx", Pins("dimm:41")),
|
||||
Subsignal("rx", Pins("dimm:51")),
|
||||
IOStandard("LVCMOS33"))
|
||||
]
|
||||
else:
|
||||
raise ValueError(f"port {port} not in ['P2']")
|
||||
|
||||
# Platform -----------------------------------------------------------------------------------------
|
||||
|
||||
class Platform(Xilinx7SeriesPlatform):
|
||||
default_clk_name = "clk25"
|
||||
default_clk_period = 1e9/25e6
|
||||
|
||||
def __init__(self, toolchain="vivado"):
|
||||
Xilinx7SeriesPlatform.__init__(self, "xc7a50tfgg484-1", _io, _connectors, toolchain=toolchain)
|
||||
self.toolchain.bitstream_commands = \
|
||||
["set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]"]
|
||||
self.toolchain.additional_commands = \
|
||||
["write_cfgmem -force -format bin -interface spix4 -size 16 "
|
||||
"-loadbit \"up 0x0 {build_name}.bit\" -file {build_name}.bin"]
|
||||
|
||||
|
||||
def create_programmer(self, cfg="openocd_xc7_ft2232.cfg"):
|
||||
return OpenOCD(cfg, "bscan_spi_xc7a50t.bit")
|
||||
|
||||
def do_finalize(self, fragment):
|
||||
Xilinx7SeriesPlatform.do_finalize(self, fragment)
|
||||
self.add_period_constraint(self.lookup_request(self.default_clk_name, loose=True), self.default_clk_period)
|
|
@ -0,0 +1,186 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
#
|
||||
# This file is part of LiteX-Boards.
|
||||
#
|
||||
# Copyright (c) 2015-2019 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||
# Copyright (c) 2020 Antmicro <www.antmicro.com>
|
||||
# Copyright (c) 2022 Victor Suarez Rovere <suarezvictor@gmail.com>
|
||||
# Copyright (c) 2023 Charles-Henri Mousset <ch.mousset@gmail.com>
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
|
||||
from migen import *
|
||||
|
||||
from litex.gen import *
|
||||
|
||||
from litex.build.io import DDROutput
|
||||
|
||||
from litex_boards.platforms import colorlight_i9plus
|
||||
|
||||
from litex.soc.cores.clock import *
|
||||
from litex.soc.integration.soc import SoCRegion
|
||||
from litex.soc.integration.soc_core import *
|
||||
from litex.soc.integration.builder import *
|
||||
from litex.soc.cores.led import LedChaser
|
||||
from litex.soc.cores.dna import DNA
|
||||
|
||||
from litedram.modules import M12L64322A
|
||||
from litedram.phy import GENSDRPHY
|
||||
|
||||
from liteeth.phy.s7rgmii import LiteEthPHYRGMII
|
||||
|
||||
# CRG ----------------------------------------------------------------------------------------------
|
||||
|
||||
class _CRG(LiteXModule):
|
||||
def __init__(self, platform, sys_clk_freq, with_dram=True, with_ethernet=True):
|
||||
self.rst = Signal()
|
||||
self.cd_sys = ClockDomain()
|
||||
self.cd_idelay = ClockDomain()
|
||||
if with_dram:
|
||||
self.cd_sys_ps = ClockDomain()
|
||||
|
||||
# # #
|
||||
|
||||
# Clk/Rst.
|
||||
clk25 = platform.request("clk25")
|
||||
|
||||
# PLL.
|
||||
self.pll = pll = S7PLL(speedgrade=-1)
|
||||
self.comb += pll.reset.eq(self.rst)
|
||||
pll.register_clkin(clk25, 25e6)
|
||||
pll.create_clkout(self.cd_sys, 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.
|
||||
if with_dram:
|
||||
pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=90) # untested
|
||||
# SDRAM clock
|
||||
sdram_clk = ClockSignal("sys_ps")
|
||||
self.specials += DDROutput(1, 0, platform.request("sdram_clock"), sdram_clk)
|
||||
|
||||
self.idelayctrl = S7IDELAYCTRL(self.cd_idelay)
|
||||
|
||||
|
||||
# BaseSoC ------------------------------------------------------------------------------------------
|
||||
|
||||
class BaseSoC(SoCCore):
|
||||
def __init__(self, toolchain="vivado", sys_clk_freq=100e6,
|
||||
with_dna = False,
|
||||
with_pmod_uart = False,
|
||||
with_ethernet = False,
|
||||
with_etherbone = False,
|
||||
eth_port = 0,
|
||||
eth_ip = "192.168.1.50",
|
||||
eth_dynamic_ip = False,
|
||||
with_led_chaser = True,
|
||||
with_jtagbone = True,
|
||||
with_spi_flash = False,
|
||||
**kwargs):
|
||||
platform = colorlight_i9plus.Platform(toolchain=toolchain)
|
||||
|
||||
# PMOD: uart on P2 (top) -------------------------------------------------------------------
|
||||
if with_pmod_uart:
|
||||
platform.add_extension(colorlight_i9plus.pmod_uart())
|
||||
|
||||
# CRG --------------------------------------------------------------------------------------
|
||||
with_dram = (kwargs.get("integrated_main_ram_size", 0) == 0)
|
||||
self.crg = _CRG(platform, sys_clk_freq, with_dram)
|
||||
|
||||
# SoCCore ----------------------------------------------------------------------------------
|
||||
SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on Arty A7", **kwargs)
|
||||
|
||||
# DNA --------------------------------------------------------------------------------------
|
||||
if with_dna:
|
||||
self.dna = DNA()
|
||||
self.dna.add_timing_constraints(platform, sys_clk_freq, self.crg.cd_sys.clk)
|
||||
|
||||
# SDRAM ------------------------------------------------------------------------------------
|
||||
if not self.integrated_main_ram_size:
|
||||
sdrphy_cls = GENSDRPHY
|
||||
self.sdrphy = sdrphy_cls(platform.request("sdram"))
|
||||
self.add_sdram("sdram",
|
||||
phy = self.sdrphy,
|
||||
module = M12L64322A(sys_clk_freq, "1:1"),
|
||||
l2_cache_size = kwargs.get("l2_size", 8192)
|
||||
)
|
||||
|
||||
|
||||
# Ethernet / Etherbone ---------------------------------------------------------------------
|
||||
if with_ethernet or with_etherbone:
|
||||
self.ethphy = LiteEthPHYRGMII(
|
||||
clock_pads = self.platform.request("eth_clocks", eth_port),
|
||||
pads = self.platform.request("eth", eth_port),
|
||||
tx_delay = 0)
|
||||
if with_ethernet:
|
||||
self.add_ethernet(phy=self.ethphy, dynamic_ip=eth_dynamic_ip)
|
||||
if with_etherbone:
|
||||
self.add_etherbone(phy=self.ethphy, ip_address=eth_ip)
|
||||
|
||||
# Jtagbone ---------------------------------------------------------------------------------
|
||||
if with_jtagbone:
|
||||
self.add_jtagbone()
|
||||
|
||||
# SPI Flash --------------------------------------------------------------------------------
|
||||
if with_spi_flash:
|
||||
from litespi.modules import MX25L12833F
|
||||
from litespi.opcodes import SpiNorFlashOpCodes as Codes
|
||||
self.add_spi_flash(mode="4x", module=MX25L12833F(Codes.READ_1_1_4), rate="1:2", with_master=True)
|
||||
|
||||
# Leds -------------------------------------------------------------------------------------
|
||||
if with_led_chaser:
|
||||
self.leds = LedChaser(
|
||||
pads = platform.request_all("user_led"),
|
||||
sys_clk_freq = sys_clk_freq,
|
||||
)
|
||||
|
||||
|
||||
# Build --------------------------------------------------------------------------------------------
|
||||
|
||||
def main():
|
||||
from litex.build.parser import LiteXArgumentParser
|
||||
parser = LiteXArgumentParser(platform=colorlight_i9plus.Platform, description="LiteX SoC on Arty A7.")
|
||||
parser.add_target_argument("--flash", action="store_true", help="Flash bitstream.")
|
||||
parser.add_target_argument("--sys-clk-freq", default=100e6, type=float, help="System clock frequency.")
|
||||
parser.add_target_argument("--with-dna", action="store_true", help="Enable 7-Series DNA.")
|
||||
parser.add_target_argument("--with-pmod-uart", action="store_true", help="Enable uart on P2 (top) PMOD")
|
||||
ethopts = parser.target_group.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_target_argument("--eth-port", default=0, type=int, help="Ethernet port to use (0/1)")
|
||||
parser.add_target_argument("--eth-ip", default="192.168.1.50", help="Ethernet/Etherbone IP address.")
|
||||
parser.add_target_argument("--eth-dynamic-ip", action="store_true", help="Enable dynamic Ethernet IP addresses setting.")
|
||||
parser.add_target_argument("--with-jtagbone", action="store_true", help="Enable JTAGbone support.")
|
||||
parser.add_target_argument("--with-spi-flash", action="store_true", help="Enable SPI Flash (MMAPed).")
|
||||
args = parser.parse_args()
|
||||
|
||||
assert not (args.with_etherbone and args.eth_dynamic_ip)
|
||||
|
||||
soc = BaseSoC(
|
||||
toolchain = args.toolchain,
|
||||
sys_clk_freq = args.sys_clk_freq,
|
||||
with_dna = args.with_dna,
|
||||
with_pmod_uart = args.with_pmod_uart,
|
||||
with_ethernet = args.with_ethernet,
|
||||
with_etherbone = args.with_etherbone,
|
||||
eth_port = args.eth_port,
|
||||
eth_ip = args.eth_ip,
|
||||
eth_dynamic_ip = args.eth_dynamic_ip,
|
||||
with_jtagbone = args.with_jtagbone,
|
||||
with_spi_flash = args.with_spi_flash,
|
||||
**parser.soc_argdict
|
||||
)
|
||||
|
||||
builder = Builder(soc, **parser.builder_argdict)
|
||||
if args.build:
|
||||
builder.build(**parser.toolchain_argdict)
|
||||
|
||||
if args.load:
|
||||
prog = soc.platform.create_programmer(cfg="prog/openocd_xc7_ft2232.cfg")
|
||||
prog.load_bitstream(builder.get_bitstream_filename(mode="sram"))
|
||||
|
||||
if args.flash:
|
||||
prog = soc.platform.create_programmer(cfg="prog/openocd_xc7_ft2232.cfg")
|
||||
prog.flash(0, builder.get_bitstream_filename(mode="flash"))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in New Issue