Merge pull request from litex-hub/master

Merge with official repo
This commit is contained in:
Guillaume REMBERT 2021-01-28 11:56:46 +01:00 committed by GitHub
commit a2f54864e8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 701 additions and 14 deletions

View file

@ -0,0 +1,171 @@
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2020 Hans Baier <hansfbaier@gmail.com>
#
# SPDX-License-Identifier: BSD-2-Clause
from litex.build.altera import AlteraPlatform
from litex.build.altera.programmer import USBBlaster
from litex.build.generic_platform import Pins, IOStandard, Subsignal, Misc
# IOs ----------------------------------------------------------------------------------------------
_io = [
# Clk
("clk50", 0, Pins("AF14"), IOStandard("3.3-V LVTTL")),
# Leds
("user_led", 0, Pins("AF10"), IOStandard("3.3-V LVTTL")),
("user_led", 1, Pins("AD10"), IOStandard("3.3-V LVTTL")),
("user_led", 2, Pins("AE11"), IOStandard("3.3-V LVTTL")),
("user_led", 3, Pins("AD7"), IOStandard("3.3-V LVTTL")),
# Buttons
("user_btn", 0, Pins("AE9"), IOStandard("3.3-V LVTTL")),
("user_btn", 1, Pins("AE12"), IOStandard("3.3-V LVTTL")),
("user_btn", 2, Pins("AD9"), IOStandard("3.3-V LVTTL")),
("user_btn", 3, Pins("AD11"), IOStandard("3.3-V LVTTL")),
# Switches
("user_sw", 0, Pins("W25"), IOStandard("3.3-V LVTTL")),
("user_sw", 1, Pins("V25"), IOStandard("3.3-V LVTTL")),
("user_sw", 2, Pins("AC28"), IOStandard("3.3-V LVTTL")),
("user_sw", 3, Pins("AC29"), IOStandard("3.3-V LVTTL")),
# DDR3 SDRAM
("ddram", 0,
Subsignal("a", Pins(
"AJ14 AK14 AH12 AJ12 AG15 AH15 AK12 AK13",
"AH13 AH14 AJ9 AK9 AK7 AK8 AG12"),
IOStandard("SSTL15"),
),
Subsignal("ba", Pins("AH10 AJ11 AK11"), IOStandard("SSTL-15 CLASS I"), ),
Subsignal("ras_n", Pins("AH8"), IOStandard("SSTL-15 CLASS I")),
Subsignal("cas_n", Pins("AH7"), IOStandard("SSTL-15 CLASS I")),
Subsignal("we_n", Pins("AJ6"), IOStandard("SSTL-15 CLASS I")),
Subsignal("dm", Pins("AH17 AG23 AK23 AJ27"),
IOStandard("SSTL-15 CLASS I"),
Misc("OUTPUT_TERMINATION=SERIES 50 OHM WITH CALIBRATION")
),
Subsignal("dq", Pins(
"AF18 AE17 AG16 AF16 AH20 AG21 AJ16 AH18",
"AK18 AJ17 AG18 AK19 AG20 AF19 AJ20 AH24",
"AE19 AE18 AG22 AK22 AF21 AF20 AH23 AK24",
"AF24 AF23 AJ24 AK26 AE23 AE22 AG25 AK27"),
IOStandard("SSTL-15 CLASS I"),
Misc("INPUT_TERMINATION=PARALLEL 50 OHM WITH CALIBRATION"),
Misc("OUTPUT_TERMINATION=SERIES 50 OHM WITH CALIBRATION"),
),
Subsignal("dqs_p", Pins("V16 V17 Y17 AC20"),
IOStandard("DIFFERENTIAL 1.5-V SSTL CLASS I"),
Misc("INPUT_TERMINATION=PARALLEL 50 OHM WITH CALIBRATION"),
Misc("OUTPUT_TERMINATION=SERIES 50 OHM WITH CALIBRATION")
),
Subsignal("dqs_n", Pins("W16 W17 AA18 AD19"),
IOStandard("DIFFERENTIAL 1.5-V SSTL CLASS I"),
Misc("INPUT_TERMINATION=PARALLEL 50 OHM WITH CALIBRATION"),
Misc("OUTPUT_TERMINATION=SERIES 50 OHM WITH CALIBRATION")
),
Subsignal("clk_p", Pins("AA14"),
IOStandard("DIFFERENTIAL 1.5-V SSTL CLASS I"),
Misc("OUTPUT_TERMINATION=SERIES 50 OHM WITH CALIBRATION"),
Misc("D5_DELAY=2")
),
Subsignal("clk_n", Pins("AA15"),
IOStandard("DIFFERENTIAL 1.5-V SSTL CLASS I"),
Misc("OUTPUT_TERMINATION=SERIES 50 OHM WITH CALIBRATION"),
Misc("D5_DELAY=2")
),
Subsignal("cs_n", Pins("AB15"), IOStandard("SSTL-15 CLASS I")),
Subsignal("cke", Pins("AJ21"), IOStandard("SSTL-15 CLASS I")),
Subsignal("odt", Pins("AE16"), IOStandard("SSTL-15 CLASS I")),
Subsignal("reset_n", Pins("AK21"), IOStandard("SSTL-15 CLASS I")),
Subsignal("rzq", Pins("AG1"), IOStandard("SSTL-15")),
Misc("CURRENT_STRENGTH_NEW=MAXIMUM CURRENT")
),
# VGA
("vga", 0,
Subsignal("hsync_n", Pins("AD12")),
Subsignal("vsync_n", Pins("AC12")),
Subsignal("sync_n", Pins("AG2")),
Subsignal("blank_n", Pins("AH3")),
Subsignal("r", Pins("AG5 AA12 AB12 AF6 AG6 AJ2 AH5 AJ1")),
Subsignal("g", Pins("Y21 AA25 AB26 AB22 AB23 AA24 AB25 AE27")),
Subsignal("b", Pins("AE28 Y23 Y24 AG28 AF28 V23 W24 AF29")),
IOStandard("3.3-V LVTTL")
),
# IrDA
("irda", 0,
Subsignal("irda_rxd", Pins("AH2")),
IOStandard("3.3-V LVTTL")
),
# Temperatue
("temperature", 0,
Subsignal("temp_cs_n", Pins("AF8")),
Subsignal("temp_din", Pins("AG7")),
Subsignal("temp_dout", Pins("AG1")),
Subsignal("temp_sclk", Pins("AF9")),
IOStandard("3.3-V LVTTL")
),
# Audio
("audio", 0,
Subsignal("aud_adclrck", Pins("AG30")),
Subsignal("aud_adcdat", Pins("AC27")),
Subsignal("aud_daclrck", Pins("AH4")),
Subsignal("aud_dacdat", Pins("AG3")),
Subsignal("aud_xck", Pins("AC9")),
Subsignal("aud_bclk", Pins("AE7")),
Subsignal("aud_i2c_sclk", Pins("AH30")),
Subsignal("aud_i2c_sdat", Pins("AF30")),
Subsignal("aud_mute", Pins("AD26")),
IOStandard("3.3-V LVTTL")
)
]
# Connectors ---------------------------------------------------------------------------------------
_connectors_hsmc_gpio_daughterboard = [
("J2", "G15 F14 H15 F15 A13 G13 B13 H14 B11 E13 - - " +
"C12 F13 B8 B12 C8 C13 A10 D10 A11 D11 B7 D12 C7 E12 A5 D9 - - " +
"A6 E9 A3 B5 A4 B6 B1 C2 B2 D2"),
("J2p", "D1 E1 E11 F11"), # top to bottom, starting with 57
("J3", "AB27 F8 AA26 F9 B3 G8 C3 H8 D4 H7 - - " +
"E4 J7 E2 K8 E3 K7 E6 J9 E7 J10 C4 J12 D5 G10 C5 J12 - - " +
"D6 K12 F6 G11 G7 G12 D7 A8 E8 A9"),
("J3p", "C9 C10 H12 H13"), # top to bottom, starting with 117
("J4", "- - AD3 AE1 AD4 AE2 - - AB3 AC1 - - " +
"AB4 AC2 - - Y3 AA1 Y4 AA2 - - V3 W1 V4 W2 - - - -" +
"T3 U1 T4 R1 - R2 P3 U2 P4 -"),
("J4p", "M3 M4 - H3 H4 J14 AD29 - N1 N2 - J1 J2") # top to bottom, starting with 169
]
# Platform -----------------------------------------------------------------------------------------
_device_map = {
"revb" : "5CSXFC6D6F31C8ES",
"revc" : "5CSXFC6D6F31C8ES",
"revd" : "5CSXFC6D6F31C8",
}
class Platform(AlteraPlatform):
default_clk_name = "clk50"
default_clk_period = 1e9/50e6
def __init__(self, revision="revd"):
assert revision in _device_map.keys()
self.revision = revision
AlteraPlatform.__init__(self, _device_map[revision], _io, connectors=_connectors_hsmc_gpio_daughterboard)
def create_programmer(self):
return USBBlaster()
def do_finalize(self, fragment):
AlteraPlatform.do_finalize(self, fragment)
self.add_period_constraint(self.lookup_request("clk50", loose=True), 1e9/50e6)

View file

@ -0,0 +1,153 @@
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2021 Kazumoto Kojima <kkojima@rr.iij4u.or.jp>
# SPDX-License-Identifier: BSD-2-Clause
# The Colorlight i5 PCB and IOs have been documented by @wuxx
# https://github.com/wuxx/Colorlight-FPGA-Projects
from litex.build.generic_platform import *
from litex.build.lattice import LatticePlatform
from litex.build.lattice.programmer import EcpDapProgrammer
# IOs ----------------------------------------------------------------------------------------------
_io_v7_0 = [ # Documented by @smunaut
# Clk
("clk25", 0, Pins("P3"), IOStandard("LVCMOS33")),
# Led
("user_led_n", 0, Pins("U16"), IOStandard("LVCMOS33")),
# Reset button
("cpu_reset_n", 0, Pins("K18"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
# Serial
("serial", 0,
Subsignal("tx", Pins("J17")),
Subsignal("rx", Pins("H18")),
IOStandard("LVCMOS33")
),
# SPIFlash (GD25Q16CSIG)
("spiflash", 0,
Subsignal("cs_n", Pins("R2")),
# https://github.com/m-labs/nmigen-boards/pull/38
#Subsignal("clk", Pins("")), driven through USRMCLK
Subsignal("mosi", Pins("W2")),
Subsignal("miso", Pins("V2")),
IOStandard("LVCMOS33"),
),
# SDRAM SDRAM (EM638325-6H)
("sdram_clock", 0, Pins("B9"), IOStandard("LVCMOS33")),
("sdram", 0,
Subsignal("a", Pins(
"B13 C14 A16 A17 B16 B15 A14 A13",
"A12 A11 B12")),
Subsignal("dq", Pins(
"D15 E14 E13 D12 E12 D11 C10 B17",
"B8 A8 C7 A7 A6 B6 A5 B5",
"D5 C5 D6 C6 E7 D7 E8 D8",
"E9 D9 E11 C11 C12 D13 D14 C15")),
Subsignal("we_n", Pins("A10")),
Subsignal("ras_n", Pins("B10")),
Subsignal("cas_n", Pins("A9")),
#Subsignal("cs_n", Pins("")), # gnd
#Subsignal("cke", Pins("")), # 3v3
Subsignal("ba", Pins("B11 C8")), # sdram pin BA0 and BA1
#Subsignal("dm", Pins("")), # gnd
IOStandard("LVCMOS33"),
Misc("SLEWRATE=FAST")
),
# RGMII Ethernet (B50612D)
# The order of the two PHYs is swapped with the naming of the connectors
# on the board so to match with the configuration of their PHYA[0] pins.
("eth_clocks", 0,
Subsignal("tx", Pins("G1")),
Subsignal("rx", Pins("H2")),
IOStandard("LVCMOS33")
),
("eth", 0,
Subsignal("rst_n", Pins("P4")),
Subsignal("mdio", Pins("P5")),
Subsignal("mdc", Pins("N5")),
Subsignal("rx_ctl", Pins("P2")),
Subsignal("rx_data", Pins("K2 L1 N1 P1")),
Subsignal("tx_ctl", Pins("K1")),
Subsignal("tx_data", Pins("G2 H1 J1 J3")),
IOStandard("LVCMOS33")
),
("eth_clocks", 1,
Subsignal("tx", Pins("U19")),
Subsignal("rx", Pins("L19")),
IOStandard("LVCMOS33")
),
("eth", 1,
Subsignal("rst_n", Pins("P4")),
Subsignal("mdio", Pins("P5")),
Subsignal("mdc", Pins("N5")),
Subsignal("rx_ctl", Pins("M20")),
Subsignal("rx_data", Pins("P20 N19 N20 M19")),
Subsignal("tx_ctl", Pins("P19")),
Subsignal("tx_data", Pins("U20 T19 T20 R20")),
IOStandard("LVCMOS33")
),
]
# From https://github.com/wuxx/Colorlight-FPGA-Projects/blob/master/schematic/i5_v6.0-extboard.pdf and
# https://github.com/wuxx/Colorlight-FPGA-Projects/blob/master/doc/i5_extboard_v1.2_pinout.png
_connectors_v7_0 = [
("pmode", "C17 B18 B20 F20 A18 A19 B19 D20"),
("pmodf", "D1 C1 C2 E3 E2 D2 B1 A3"),
]
# PMODS --------------------------------------------------------------------------------------------
def sdcard_pmod_io(pmod):
return [
# SDCard PMOD:
# - https://store.digilentinc.com/pmod-microsd-microsd-card-slot/
("spisdcard", 0,
Subsignal("clk", Pins(f"{pmod}:3")),
Subsignal("mosi", Pins(f"{pmod}:1"), Misc("PULLMODE=UP")),
Subsignal("cs_n", Pins(f"{pmod}:0"), Misc("PULLMODE=UP")),
Subsignal("miso", Pins(f"{pmod}:2"), Misc("PULLMODE=UP")),
Misc("SLEWRATE=FAST"),
IOStandard("LVCMOS33"),
),
("sdcard", 0,
Subsignal("data", Pins(f"{pmod}:2 {pmod}:4 {pmod}:5 {pmod}:0"), Misc("PULLMODE=UP")),
Subsignal("cmd", Pins(f"{pmod}:1"), Misc("PULLMODE=UP")),
Subsignal("clk", Pins(f"{pmod}:3")),
Subsignal("cd", Pins(f"{pmod}:6")),
#Misc("SLEWRATE=FAST"),
IOStandard("LVCMOS33"),
),
]
_sdcard_pmod_io = sdcard_pmod_io("pmode") # SDCARD PMOD on P3.
# Platform -----------------------------------------------------------------------------------------
class Platform(LatticePlatform):
default_clk_name = "clk25"
default_clk_period = 1e9/25e6
def __init__(self, revision="7.0", toolchain="trellis"):
assert revision in ["7.0"]
self.revision = revision
device = {"7.0": "LFE5U-25F-6BG381C"}[revision]
io = {"7.0": _io_v7_0}[revision]
connectors = {"7.0": _connectors_v7_0}[revision]
LatticePlatform.__init__(self, device, io, connectors=connectors, toolchain=toolchain)
def create_programmer(self):
return EcpDapProgrammer()
def do_finalize(self, fragment):
LatticePlatform.do_finalize(self, fragment)
self.add_period_constraint(self.lookup_request("clk25", loose=True), 1e9/25e6)
self.add_period_constraint(self.lookup_request("eth_clocks:rx", 0, loose=True), 1e9/125e6)
self.add_period_constraint(self.lookup_request("eth_clocks:rx", 1, loose=True), 1e9/125e6)

View file

@ -117,6 +117,15 @@ _io = [
),
]
# Connectors ---------------------------------------------------------------------------------------
_connectors = [
# PIN 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
("JP1", "A8 D3 B8 C3 A2 A3 B3 B4 A4 B5 - - A5 D5 B6 A6 B7 D6 A7 C6 C8 E6 E7 D8 E8 F8 F9 E9 - - C9 D9 E11 E10 C11 B11 A12 D11 D12 B12"),
("JP2", "T9 F13 R9 T15 T14 T13 R13 T12 R12 T11 - - T10 R11 P11 R10 N12 P9 N9 N11 L16 K16 R16 L15 P15 P16 R14 N16 - - N15 P14 L14 N14 M10 L13 J16 K15 J13 J14"),
("JP3", "- E15 E16 M16 A14 B16 C14 C16 C15 D16 D15 D14 F15 F16 F14 G16 G15 - - - - - - - - -")
]
# Platform -----------------------------------------------------------------------------------------
class Platform(AlteraPlatform):
@ -124,7 +133,7 @@ class Platform(AlteraPlatform):
default_clk_period = 1e9/50e6
def __init__(self):
AlteraPlatform.__init__(self, "EP4CE22F17C6", _io)
AlteraPlatform.__init__(self, "EP4CE22F17C6", _io, _connectors)
def create_programmer(self):
return USBBlaster()

View file

@ -112,8 +112,9 @@ class Platform(LatticePlatform):
default_clk_name = "clk100"
default_clk_period = 1e9/100e6
def __init__(self, toolchain="trellis", **kwargs):
LatticePlatform.__init__(self, "LFE5UM5G-85F-8BG554I", _io, _connectors, toolchain=toolchain, **kwargs)
def __init__(self, device="85F", toolchain="trellis", **kwargs):
assert device in ["45F", "85F"]
LatticePlatform.__init__(self, f"LFE5UM5G-{device}-8BG554I", _io, _connectors, toolchain=toolchain, **kwargs)
def create_programmer(self):
return OpenOCDJTAGProgrammer("openocd_ecpix5.cfg")

View file

@ -81,6 +81,21 @@ _io_common = [
IOStandard("LVCMOS33")
),
# SPIFlash
("spiflash", 0,
Subsignal("cs_n", Pins("R2")),
Subsignal("miso", Pins("V2")),
Subsignal("mosi", Pins("W2")),
Subsignal("wp", Pins("Y2")),
Subsignal("hold", Pins("W1")),
IOStandard("LVCMOS33")
),
("spiflash4x", 0,
Subsignal("cs_n", Pins("R2")),
Subsignal("dq", Pins("W2", "V2", "Y2", "W1")),
IOStandard("LVCMOS33")
),
# OLED
("oled_spi", 0,
Subsignal("clk", Pins("P4")),

View file

@ -0,0 +1,92 @@
#!/usr/bin/env python3
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2020 Hans Baier <hansfbaier@gmail.com>
# SPDX-License-Identifier: BSD-2-Clause
import os
import argparse
from migen.fhdl.module import Module
from migen.fhdl.structure import Signal, ClockDomain
from migen.genlib.resetsync import AsyncResetSynchronizer
from litex.soc.cores.clock import CycloneVPLL
from litex.soc.integration.builder import Builder, builder_args, builder_argdict
from litex.soc.integration.soc_core import SoCCore
from litex.soc.integration.soc_sdram import soc_sdram_argdict, soc_sdram_args
from litex.soc.cores.led import LedChaser
from litex_boards.platforms import arrow_sockit
# CRG ----------------------------------------------------------------------------------------------
class _CRG(Module):
def __init__(self, platform, sys_clk_freq):
self.rst = Signal()
self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_sys_ps = ClockDomain(reset_less=True)
# Clk / Rst
clk50 = platform.request("clk50")
# PLL
self.submodules.pll = pll = CycloneVPLL(speedgrade="-C6")
self.comb += pll.reset.eq(self.rst)
pll.register_clkin(clk50, 50e6)
pll.create_clkout(self.cd_sys, sys_clk_freq)
pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=90)
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self, sys_clk_freq=int(50e6), revision="revd", **kwargs):
platform = arrow_sockit.Platform(revision)
# Defaults to Crossover UART because serial is attached to the HPS and cannot be used.
if kwargs["uart_name"] == "serial":
kwargs["uart_name"] = "crossover"
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq,
ident = "LiteX SoC on the Arrow SoCKit",
ident_version = True,
**kwargs)
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = _CRG(platform, sys_clk_freq)
# Leds -------------------------------------------------------------------------------------
self.submodules.leds = LedChaser(
pads = platform.request_all("user_led"),
sys_clk_freq = sys_clk_freq)
self.add_csr("leds")
# Build --------------------------------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser(description="LiteX SoC on SoCKit")
parser.add_argument("--build", action="store_true", help="Build bitstream")
parser.add_argument("--load", action="store_true", help="Load bitstream")
parser.add_argument("--revision", default="revd", help="Board revision: revb (default), revc or revd")
parser.add_argument("--sys-clk-freq", default=50e6, help="System clock frequency (default: 50MHz)")
builder_args(parser)
soc_sdram_args(parser)
args = parser.parse_args()
soc = BaseSoC(
sys_clk_freq = int(float(args.sys_clk_freq)),
revision = args.revision,
**soc_sdram_argdict(args)
)
builder = Builder(soc, **builder_argdict(args))
builder.build(run=args.build)
if args.load:
prog = soc.platform.create_programmer()
prog.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".sof"))
if __name__ == "__main__":
main()

View file

@ -104,10 +104,11 @@ class BaseSoC(SoCCore):
)
# Leds -------------------------------------------------------------------------------------
self.submodules.leds = LedChaser(
pads = platform.request_all("user_led"),
sys_clk_freq = sys_clk_freq)
self.add_csr("leds")
if platform.lookup_request("serial", loose=True) is None: # Disable leds when serial is used.
self.submodules.leds = LedChaser(
pads = platform.request_all("user_led"),
sys_clk_freq = sys_clk_freq)
self.add_csr("leds")
# Build --------------------------------------------------------------------------------------------

View file

@ -0,0 +1,234 @@
#!/usr/bin/env python3
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2021 Kazumoto Kojima <kkojima@rr.iij4u.or.jp>
# SPDX-License-Identifier: BSD-2-Clause
import os
import argparse
import sys
from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer
from litex.build.io import DDROutput
from litex_boards.platforms import colorlight_i5
from litex.build.tools import write_to_file
from litex.build.lattice.trellis import trellis_args, trellis_argdict
from litex.soc.cores.clock import *
from litex.soc.cores.spi_flash import SpiFlash
from litex.soc.cores.spi import SPIMaster
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *
from litex.soc.cores.led import LedChaser
from litex.soc.interconnect.csr import *
from litex.soc.cores.prbs import *
from litedram.modules import M12L64322A
from litedram.phy import GENSDRPHY, HalfRateGENSDRPHY
from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII
# PRBS -------------------------------------------------------------------------------------------
class _PRBSSource(Module, AutoCSR):
def __init__(self):
self.submodules.prbs = prbs = PRBS31Generator(32)
self.data = CSRStatus(32)
self.comb += [
self.data.status.eq(prbs.o)
]
# CRG ----------------------------------------------------------------------------------------------
class _CRG(Module):
def __init__(self, platform, sys_clk_freq, use_internal_osc=False, with_usb_pll=False, sdram_rate="1:1"):
self.rst = Signal()
self.clock_domains.cd_sys = ClockDomain()
if sdram_rate == "1:2":
self.clock_domains.cd_sys2x = ClockDomain()
self.clock_domains.cd_sys2x_ps = ClockDomain(reset_less=True)
else:
self.clock_domains.cd_sys_ps = ClockDomain(reset_less=True)
# # #
# Clk / Rst
if not use_internal_osc:
clk = platform.request("clk25")
clk_freq = 25e6
else:
clk = Signal()
div = 5
self.specials += Instance("OSCG",
p_DIV = div,
o_OSC = clk)
clk_freq = 310e6/div
rst_n = platform.request("cpu_reset_n")
# PLL
self.submodules.pll = pll = ECP5PLL()
self.comb += pll.reset.eq(~rst_n | self.rst)
pll.register_clkin(clk, clk_freq)
pll.create_clkout(self.cd_sys, sys_clk_freq)
if sdram_rate == "1:2":
pll.create_clkout(self.cd_sys2x, 2*sys_clk_freq)
pll.create_clkout(self.cd_sys2x_ps, 2*sys_clk_freq, phase=180) # Idealy 90° but needs to be increased.
else:
pll.create_clkout(self.cd_sys_ps, sys_clk_freq, phase=180) # Idealy 90° but needs to be increased.
# USB PLL
if with_usb_pll:
self.submodules.usb_pll = usb_pll = ECP5PLL()
self.comb += usb_pll.reset.eq(~rst_n | self.rst)
usb_pll.register_clkin(clk, clk_freq)
self.clock_domains.cd_usb_12 = ClockDomain()
self.clock_domains.cd_usb_48 = ClockDomain()
usb_pll.create_clkout(self.cd_usb_12, 12e6, margin=0)
usb_pll.create_clkout(self.cd_usb_48, 48e6, margin=0)
# SDRAM clock
sdram_clk = ClockSignal("sys2x_ps" if sdram_rate == "1:2" else "sys_ps")
self.specials += DDROutput(1, 0, platform.request("sdram_clock"), sdram_clk)
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
mem_map = {**SoCCore.mem_map, **{"spiflash": 0xd0000000}}
def __init__(self, board="i5", revision="7.0", sys_clk_freq=60e6, with_ethernet=False, with_etherbone=False, local_ip="", remote_ip="", eth_phy=0, use_internal_osc=False, sdram_rate="1:1", with_prbs=False, **kwargs):
board = board.lower()
assert board in ["i5"]
if board == "i5":
platform = colorlight_i5.Platform(revision=revision)
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, int(sys_clk_freq),
ident = "LiteX SoC on Colorlight " + board.upper(),
ident_version = True,
**kwargs)
# CRG --------------------------------------------------------------------------------------
with_usb_pll = kwargs.get("uart_name", None) == "usb_acm"
self.submodules.crg = _CRG(platform, sys_clk_freq, use_internal_osc=use_internal_osc, with_usb_pll=with_usb_pll, sdram_rate=sdram_rate)
# Leds -------------------------------------------------------------------------------------
ledn = platform.request_all("user_led_n")
self.submodules.leds = LedChaser(pads=ledn, sys_clk_freq=sys_clk_freq)
self.add_csr("leds")
# SPI Flash --------------------------------------------------------------------------------
self.add_spi_flash(mode="1x", dummy_cycles=8)
self.add_constant("SPIFLASH_PAGE_SIZE", 256)
self.add_constant("SPIFLASH_SECTOR_SIZE", 4096)
# SDR SDRAM --------------------------------------------------------------------------------
if not self.integrated_main_ram_size:
sdrphy_cls = HalfRateGENSDRPHY if sdram_rate == "1:2" else GENSDRPHY
self.submodules.sdrphy = sdrphy_cls(platform.request("sdram"))
# if board == "i5" and revision == "7.0":
sdram_cls = M12L64322A # compat with EM638325-6H
self.add_sdram("sdram",
phy = self.sdrphy,
module = sdram_cls(sys_clk_freq, sdram_rate),
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
)
# Ethernet / Etherbone ---------------------------------------------------------------------
if with_ethernet or with_etherbone:
self.submodules.ethphy = LiteEthPHYRGMII(
clock_pads = self.platform.request("eth_clocks", eth_phy),
pads = self.platform.request("eth", eth_phy),
tx_delay = 0)
self.add_csr("ethphy")
if with_ethernet:
self.add_ethernet(phy=self.ethphy)
if with_etherbone:
self.add_etherbone(phy=self.ethphy)
if local_ip:
local_ip = local_ip.split(".")
self.add_constant("LOCALIP1", int(local_ip[0]))
self.add_constant("LOCALIP2", int(local_ip[1]))
self.add_constant("LOCALIP3", int(local_ip[2]))
self.add_constant("LOCALIP4", int(local_ip[3]))
if remote_ip:
remote_ip = remote_ip.split(".")
self.add_constant("REMOTEIP1", int(remote_ip[0]))
self.add_constant("REMOTEIP2", int(remote_ip[1]))
self.add_constant("REMOTEIP3", int(remote_ip[2]))
self.add_constant("REMOTEIP4", int(remote_ip[3]))
# PRBS -------------------------------------------------------------------------------------
if with_prbs:
self.submodules.prbs = _PRBSSource()
self.add_csr("prbs")
# Build --------------------------------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser(description="LiteX SoC on Colorlight i5")
parser.add_argument("--build", action="store_true", help="Build bitstream")
parser.add_argument("--load", action="store_true", help="Load bitstream")
parser.add_argument("--board", default="i5", help="Board type: i5 (default)")
parser.add_argument("--revision", default="7.0", type=str, help="Board revision: 7.0 (default)")
parser.add_argument("--sys-clk-freq", default=60e6, help="System clock frequency (default: 60MHz)")
parser.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support")
parser.add_argument("--with-etherbone", action="store_true", help="Enable Etherbone support")
parser.add_argument("--remote-ip", default="192.168.1.100", help="Remote IP address of TFTP server")
parser.add_argument("--local-ip", default="192.168.1.50", help="Local IP address")
parser.add_argument("--with-spi-sdcard", action="store_true", help="Enable SPI-mode SDCard support")
parser.add_argument("--with-sdcard", action="store_true", help="Enable SDCard support")
parser.add_argument("--eth-phy", default=0, type=int, help="Ethernet PHY: 0 (default) or 1")
parser.add_argument("--use-internal-osc", action="store_true", help="Use internal oscillator")
parser.add_argument("--sdram-rate", default="1:1", help="SDRAM Rate: 1:1 Full Rate (default), 1:2 Half Rate")
parser.add_argument("--l2-size", default=8192, type=int, help="L2 cache size")
parser.add_argument("--with-prbs", action="store_true", help="Enable PRBS support")
builder_args(parser)
soc_core_args(parser)
trellis_args(parser)
args = parser.parse_args()
assert not (args.with_ethernet and args.with_etherbone)
soc = BaseSoC(board=args.board, revision=args.revision,
sys_clk_freq = int(float(args.sys_clk_freq)),
with_ethernet = args.with_ethernet,
with_etherbone = args.with_etherbone,
local_ip = args.local_ip,
remote_ip = args.remote_ip,
eth_phy = args.eth_phy,
use_internal_osc = args.use_internal_osc,
sdram_rate = args.sdram_rate,
l2_size = args.l2_size,
with_prbs = args.with_prbs,
**soc_core_argdict(args)
)
assert not (args.with_spi_sdcard and args.with_sdcard)
soc.platform.add_extension(colorlight_i5._sdcard_pmod_io)
if args.with_spi_sdcard:
soc.add_spi_sdcard()
if args.with_sdcard:
soc.add_sdcard()
builder = Builder(soc, **builder_argdict(args))
builder.build(**trellis_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 + ".svf"))
if __name__ == "__main__":
main()

View file

@ -77,8 +77,8 @@ class _CRG(Module):
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self, sys_clk_freq=int(75e6), with_ethernet=False, **kwargs):
platform = ecpix5.Platform(toolchain="trellis")
def __init__(self, device="85F", sys_clk_freq=int(75e6), with_ethernet=False, **kwargs):
platform = ecpix5.Platform(device=device, toolchain="trellis")
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq,
@ -128,6 +128,7 @@ def main():
parser = argparse.ArgumentParser(description="LiteX SoC on ECPIX-5")
parser.add_argument("--build", action="store_true", help="Build bitstream")
parser.add_argument("--load", action="store_true", help="Load bitstream")
parser.add_argument("--device", default="85F", help="ECP5 device (default: 85F)")
parser.add_argument("--sys-clk-freq", default=75e6, help="System clock frequency (default: 75MHz)")
parser.add_argument("--with-sdcard", action="store_true", help="Enable SDCard support")
parser.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support")
@ -137,6 +138,7 @@ def main():
args = parser.parse_args()
soc = BaseSoC(
device = args.device,
sys_clk_freq = int(float(args.sys_clk_freq)),
with_ethernet = args.with_ethernet,
**soc_core_argdict(args)

View file

@ -105,7 +105,7 @@ class BaseSoC(SoCCore):
data_width = 128,
bar0_size = 0x20000)
self.add_csr("pcie_phy")
self.add_pcie(phy=self.pcie_phy, ndmas=1)
self.add_pcie(phy=self.pcie_phy, ndmas=1, max_pending_requests=2)
# Leds -------------------------------------------------------------------------------------
self.submodules.leds = LedChaser(

View file

@ -76,6 +76,7 @@ class _CRG(Module):
class _CRGSDRAM(Module):
def __init__(self, platform, sys_clk_freq, with_usb_pll=False):
self.rst = Signal()
self.clock_domains.cd_init = ClockDomain()
self.clock_domains.cd_por = ClockDomain(reset_less=True)
self.clock_domains.cd_sys = ClockDomain()
@ -102,7 +103,7 @@ class _CRGSDRAM(Module):
# PLL
sys2x_clk_ecsout = Signal()
self.submodules.pll = pll = ECP5PLL()
self.comb += pll.reset.eq(~por_done | ~rst_n)
self.comb += pll.reset.eq(~por_done | ~rst_n | self.rst)
pll.register_clkin(clk48, 48e6)
pll.create_clkout(self.cd_sys2x_i, 2*sys_clk_freq)
pll.create_clkout(self.cd_init, 24e6)
@ -182,8 +183,7 @@ class BaseSoC(SoCCore):
self.submodules.ddrphy = ECP5DDRPHY(
pads = ddram_pads,
sys_clk_freq = sys_clk_freq,
cmd_delay = 0 if sys_clk_freq > 64e6 else 100,
dm_remapping = {0:1, 1:0})
cmd_delay = 0 if sys_clk_freq > 64e6 else 100)
self.ddrphy.settings.rtt_nom = "disabled"
self.add_csr("ddrphy")
if hasattr(ddram_pads, "vccio"):

View file

@ -81,8 +81,10 @@ class _CRG(Module):
class BaseSoC(SoCCore):
def __init__(self, device="LFE5U-45F", revision="2.0", toolchain="trellis",
sys_clk_freq=int(50e6), sdram_module_cls="MT48LC16M16", sdram_rate="1:1", **kwargs):
sys_clk_freq=int(50e6), sdram_module_cls="MT48LC16M16", sdram_rate="1:1", spiflash=False, **kwargs):
platform = ulx3s.Platform(device=device, revision=revision, toolchain=toolchain)
if spiflash:
self.mem_map = {**SoCCore.mem_map, **{"spiflash": 0x80000000}}
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq,
@ -135,6 +137,8 @@ def main():
parser.add_argument("--revision", default="2.0", help="Board revision: 2.0 (default) or 1.7")
parser.add_argument("--sys-clk-freq", default=50e6, help="System clock frequency (default: 50MHz)")
parser.add_argument("--sdram-module", default="MT48LC16M16", help="SDRAM module: MT48LC16M16 (default), AS4C32M16 or AS4C16M16")
parser.add_argument("--with-spiflash", action="store_true", help="Make the SPI Flash accessible from the SoC")
parser.add_argument("--flash-boot-adr", type=lambda x: int(x,0), default=None, help="Flash boot address")
parser.add_argument("--with-spi-sdcard", action="store_true", help="Enable SPI-mode SDCard support")
parser.add_argument("--with-sdcard", action="store_true", help="Enable SDCard support")
parser.add_argument("--with-oled", action="store_true", help="Enable SDD1331 OLED support")
@ -151,6 +155,7 @@ def main():
sys_clk_freq = int(float(args.sys_clk_freq)),
sdram_module_cls = args.sdram_module,
sdram_rate = args.sdram_rate,
spiflash = args.with_spiflash,
**soc_sdram_argdict(args))
assert not (args.with_spi_sdcard and args.with_sdcard)
if args.with_spi_sdcard:
@ -159,6 +164,10 @@ def main():
soc.add_sdcard()
if args.with_oled:
soc.add_oled()
if args.with_spiflash:
soc.add_spi_flash(mode="1x", dummy_cycles=8)
if args.flash_boot_adr:
soc.add_constant("FLASH_BOOT_ADDRESS", args.flash_boot_adr)
builder = Builder(soc, **builder_argdict(args))
builder_kargs = trellis_argdict(args) if args.toolchain == "trellis" else {}