Skip to content
Snippets Groups Projects
Unverified Commit a68c00e4 authored by enjoy-digital's avatar enjoy-digital Committed by GitHub
Browse files

Merge pull request #104 from DerFetzer/colorlight_5a_75e_v6_0

Add support for 5A-75E V6.0 board
parents 2eda9d02 8bd736bd
No related branches found
No related tags found
No related merge requests found
......@@ -4,8 +4,9 @@
# Copyright (c) 2020 Vadim Kaushan <admin@disasm.info>
# SPDX-License-Identifier: BSD-2-Clause
# The Colorlight 5A-75E PCB and IOs have been documented by @derekmulcahy:
# The Colorlight 5A-75E PCB and IOs have been documented by @derekmulcahy and @adamgreig:
# https://github.com/q3k/chubby75/issues/59
# https://github.com/q3k/chubby75/pull/67
from litex.build.generic_platform import *
from litex.build.lattice import LatticePlatform
......@@ -96,7 +97,88 @@ _io_v7_1 = [
),
]
# from https://github.com/q3k/chubby75/blob/master/5a-75b/hardware_V7.1.md
# Documented by @adamgreig
_io_v6_0 = [
# clock
("clk25", 0, Pins("P6"), IOStandard("LVCMOS33")),
# led
("user_led_n", 0, Pins("T6"), IOStandard("LVCMOS33")),
# btn
("user_btn_n", 0, Pins("R7"), IOStandard("LVCMOS33")),
# serial
("serial", 0,
Subsignal("tx", Pins("T6")), # led (J19 DATA_LED-)
Subsignal("rx", Pins("R7")), # btn (J19 KEY+)
IOStandard("LVCMOS33")
),
# spiflash (25Q32JVSIQ)
("spiflash", 0,
# clk
Subsignal("cs_n", Pins("N8")),
#Subsignal("clk", Pins("")), driven through USRMCLK
Subsignal("mosi", Pins("T8")),
Subsignal("miso", Pins("T7")),
IOStandard("LVCMOS33"),
),
# sdram (M12L64322A-5T)
("sdram_clock", 0, Pins("C8"), IOStandard("LVCMOS33")),
("sdram", 0,
Subsignal("a", Pins("A9 B9 B10 C10 D9 C9 E9 D8 E8 C7 B8")),
Subsignal("dq", Pins(
"D5 C5 E5 C6 D6 E6 D7 E7",
"D10 C11 D11 C12 E10 C13 D13 E11",
"A5 B4 A4 B3 A3 C3 A2 B2",
"D14 B14 A14 B13 A13 B12 B11 A11")),
Subsignal("we_n", Pins("B5")),
Subsignal("ras_n", Pins("B6")),
Subsignal("cas_n", Pins("A6")),
#Subsignal("cs_n", Pins("")), # gnd
#Subsignal("cke", Pins("")), # 3v3
Subsignal("ba", Pins("B7 A8")),
#Subsignal("dm", Pins("")), # gnd
Misc("SLEWRATE=FAST"),
IOStandard("LVCMOS33"),
),
# ethernet (RTL8211FD)
("eth_clocks", 0,
Subsignal("tx", Pins("L1")),
Subsignal("rx", Pins("J1")),
IOStandard("LVCMOS33")
),
("eth", 0,
Subsignal("rst_n", Pins("R6")),
Subsignal("mdio", Pins("T4")),
Subsignal("mdc", Pins("R5")),
Subsignal("rx_ctl", Pins("J2")),
Subsignal("rx_data", Pins("K2 J3 K1 K3")),
Subsignal("tx_ctl", Pins("L2")),
Subsignal("tx_data", Pins("M2 M1 P1 R1")),
IOStandard("LVCMOS33")
),
("eth_clocks", 1,
Subsignal("tx", Pins("J16")),
Subsignal("rx", Pins("M16")),
IOStandard("LVCMOS33")
),
("eth", 1,
Subsignal("rst_n", Pins("R6")),
Subsignal("mdio", Pins("T4")),
Subsignal("mdc", Pins("R5")),
Subsignal("rx_ctl", Pins("P16")),
Subsignal("rx_data", Pins("M15 R16 L15 L16")),
Subsignal("tx_ctl", Pins("K14")),
Subsignal("tx_data", Pins("K16 J15 J14 K15")),
IOStandard("LVCMOS33")
),
]
# from https://github.com/q3k/chubby75/blob/master/5a-75e/hardware_V7.1.md
_connectors_v7_1 = [
("j1", "F3 F1 G3 - G2 H3 H5 F15 L2 K1 J5 K2 B16 J14 F12 -"),
("j2", "G4 G5 J2 - H2 J1 J3 F15 L2 K1 J5 K2 B16 J14 F12 -"),
......@@ -116,6 +198,26 @@ _connectors_v7_1 = [
("j16", "G13 G12 E15 - F14 F13 C13 F15 L2 K1 J5 K2 B16 J14 F12 -"),
]
# from https://github.com/q3k/chubby75/blob/master/5a-75e/hardware_V6.0.md
_connectors_v6_0 = [
("j1", "C4 D4 E4 - D3 E3 F4 N4 N5 N3 P3 P4 M3 N1 M4 -"),
("j2", "F3 F5 G3 - G4 H3 H4 N4 N5 N3 P3 P4 M3 N1 M4 -"),
("j3", "G5 H5 J5 - J4 B1 C2 N4 N5 N3 P3 P4 M3 N1 M4 -"),
("j4", "C1 D1 E2 - E1 F2 F1 N4 N5 N3 P3 P4 M3 N1 M4 -"),
("j5", "G2 G1 H2 - K5 K4 L3 N4 N5 N3 P3 P4 M3 N1 M4 -"),
("j6", "L4 L5 P2 - R2 T2 R3 N4 N5 N3 P3 P4 M3 N1 M4 -"),
("j7", "T3 R4 M5 - P5 N6 N7 N4 N5 N3 P3 P4 M3 N1 M4 -"),
("j8", "P7 M7 P8 - R8 M8 M9 N4 N5 N3 P3 P4 M3 N1 M4 -"),
("j9", "P11 N11 M11 - T13 R12 R13 N4 N5 N3 P3 P4 M3 N1 M4 -"),
("j10", "R14 T14 D16 - C15 C16 B16 N4 N5 N3 P3 P4 M3 N1 M4 -"),
("j11", "B15 C14 T15 - P15 R15 P12 N4 N5 N3 P3 P4 M3 N1 M4 -"),
("j12", "P13 N12 N13 - M12 P14 N14 N4 N5 N3 P3 P4 M3 N1 M4 -"),
("j13", "H15 H14 G16 - F16 G15 F15 N4 N5 N3 P3 P4 M3 N1 M4 -"),
("j14", "E15 E16 L12 - L13 M14 L14 N4 N5 N3 P3 P4 M3 N1 M4 -"),
("j15", "J13 K13 J12 - H13 H12 G12 N4 N5 N3 P3 P4 M3 N1 M4 -"),
("j16", "F14 G13 F12 - F13 F14 E14 N4 N5 N3 P3 P4 M3 N1 M4 -"),
]
# Platform -----------------------------------------------------------------------------------------
......@@ -124,11 +226,11 @@ class Platform(LatticePlatform):
default_clk_period = 1e9/25e6
def __init__(self, revision="7.1"):
assert revision in ["7.1"]
assert revision in ["6.0", "7.1"]
self.revision = revision
device = {"7.1": "LFE5U-25F-6BG256C"}[revision]
io = {"7.1": _io_v7_1}[revision]
connectors = {"7.1": _connectors_v7_1}[revision]
device = {"6.0": "LFE5U-25F-6BG256C", "7.1": "LFE5U-25F-6BG256C"}[revision]
io = {"6.0": _io_v6_0, "7.1": _io_v7_1}[revision]
connectors = {"6.0": _connectors_v6_0, "7.1": _connectors_v7_1}[revision]
LatticePlatform.__init__(self, device, io, connectors=connectors, toolchain="trellis")
def create_programmer(self):
......
......@@ -34,7 +34,7 @@
# You should see the LiteX BIOS and be able to interact with it.
#
# Note that you can also use a 5A-75E board:
# ./colorlight_5a_75x.py --board=5a-75e --revision=7.1
# ./colorlight_5a_75x.py --board=5a-75e --revision=7.1 (or 6.0)
#
# Disclaimer: SoC 2) is still a Proof of Concept with large timings violations on the IP/UDP and
# Etherbone stack that need to be optimized. It was initially just used to validate the reversed
......@@ -57,7 +57,7 @@ from litex.soc.cores.clock import *
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *
from litedram.modules import M12L16161A
from litedram.modules import M12L16161A, M12L64322A
from litedram.phy import GENSDRPHY, HalfRateGENSDRPHY
from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII
......@@ -65,7 +65,7 @@ from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII
# CRG ----------------------------------------------------------------------------------------------
class _CRG(Module):
def __init__(self, platform, sys_clk_freq, with_usb_pll=False, with_rst=True, sdram_rate="1:1"):
def __init__(self, platform, sys_clk_freq, use_internal_osc=False, with_usb_pll=False, with_rst=True, sdram_rate="1:1"):
self.clock_domains.cd_sys = ClockDomain()
if sdram_rate == "1:2":
self.clock_domains.cd_sys2x = ClockDomain()
......@@ -76,13 +76,23 @@ class _CRG(Module):
# # #
# Clk / Rst
clk25 = platform.request("clk25")
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 = 1 if not with_rst else platform.request("user_btn_n", 0)
# PLL
self.submodules.pll = pll = ECP5PLL()
self.comb += pll.reset.eq(~rst_n)
pll.register_clkin(clk25, 25e6)
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)
......@@ -94,7 +104,7 @@ class _CRG(Module):
if with_usb_pll:
self.submodules.usb_pll = usb_pll = ECP5PLL()
self.comb += usb_pll.reset.eq(~rst_n)
usb_pll.register_clkin(clk25, 25e6)
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)
......@@ -107,7 +117,7 @@ class _CRG(Module):
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self, board, revision, with_ethernet=False, with_etherbone=False, sys_clk_freq=60e6, sdram_rate="1:1", **kwargs):
def __init__(self, board, revision, with_ethernet=False, with_etherbone=False, eth_phy=0, sys_clk_freq=60e6, use_internal_osc=False, sdram_rate="1:1", **kwargs):
board = board.lower()
assert board in ["5a-75b", "5a-75e"]
if board == "5a-75b":
......@@ -115,8 +125,11 @@ class BaseSoC(SoCCore):
elif board == "5a-75e":
platform = colorlight_5a_75e.Platform(revision=revision)
if board == "5a-75e" and revision == "6.0" and (with_etherbone or with_ethernet):
assert use_internal_osc, "You cannot use the 25MHz clock as system clock since it is provided by the Ethernet PHY and will stop during PHY reset."
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq,
SoCCore.__init__(self, platform, int(sys_clk_freq),
ident = "LiteX SoC on Colorlight " + board.upper(),
ident_version = True,
**kwargs)
......@@ -124,17 +137,23 @@ class BaseSoC(SoCCore):
# CRG --------------------------------------------------------------------------------------
with_rst = kwargs["uart_name"] not in ["serial", "bridge"] # serial_rx shared with user_btn_n.
with_usb_pll = kwargs.get("uart_name", None) == "usb_acm"
self.submodules.crg = _CRG(platform, sys_clk_freq, with_usb_pll=with_usb_pll,with_rst=with_rst, sdram_rate=sdram_rate)
self.submodules.crg = _CRG(platform, sys_clk_freq, use_internal_osc=use_internal_osc, with_usb_pll=with_usb_pll,with_rst=with_rst, sdram_rate=sdram_rate)
# 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 == "5a-75e" and revision == "6.0":
sdram_cls = M12L64322A
sdram_size = 0x80000000
else:
sdram_cls = M12L16161A
sdram_size = 0x40000000
self.add_sdram("sdram",
phy = self.sdrphy,
module = M12L16161A(sys_clk_freq, sdram_rate),
module = sdram_cls(sys_clk_freq, sdram_rate),
origin = self.mem_map["main_ram"],
size = kwargs.get("max_sdram_size", 0x40000000),
size = kwargs.get("max_sdram_size", sdram_size),
l2_cache_size = kwargs.get("l2_size", 8192),
l2_cache_min_data_width = kwargs.get("min_l2_data_width", 128),
l2_cache_reverse = True
......@@ -143,8 +162,8 @@ class BaseSoC(SoCCore):
# Ethernet / Etherbone ---------------------------------------------------------------------
if with_ethernet or with_etherbone:
self.submodules.ethphy = LiteEthPHYRGMII(
clock_pads = self.platform.request("eth_clocks"),
pads = self.platform.request("eth"))
clock_pads = self.platform.request("eth_clocks", eth_phy),
pads = self.platform.request("eth", eth_phy))
self.add_csr("ethphy")
if with_ethernet:
self.add_ethernet(phy=self.ethphy)
......@@ -158,22 +177,25 @@ def main():
builder_args(parser)
soc_core_args(parser)
trellis_args(parser)
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="5a-75b", help="Board type: 5a-75b (default) or 5a-75e")
parser.add_argument("--revision", default="7.0", type=str, help="Board revision 7.0 (default) or 6.1")
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("--eth-phy", default=0, type=int, help="Ethernet PHY 0 or 1 (default=0)")
parser.add_argument("--sys-clk-freq", default=60e6, help="System clock frequency (default=60MHz)")
parser.add_argument("--sdram-rate", default="1:1", help="SDRAM Rate 1:1 Full Rate (default), 1:2 Half Rate")
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="5a-75b", help="Board type: 5a-75b (default) or 5a-75e")
parser.add_argument("--revision", default="7.0", type=str, help="Board revision 7.0 (default), 6.0 or 6.1")
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("--eth-phy", default=0, type=int, help="Ethernet PHY 0 or 1 (default=0)")
parser.add_argument("--sys-clk-freq", default=60e6, type=float, help="System clock frequency (default=60MHz)")
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")
args = parser.parse_args()
assert not (args.with_ethernet and args.with_etherbone)
soc = BaseSoC(board=args.board, revision=args.revision,
with_ethernet = args.with_ethernet,
with_etherbone = args.with_etherbone,
sys_clk_freq = args.sys_clk_freq,
with_ethernet = args.with_ethernet,
with_etherbone = args.with_etherbone,
eth_phy = args.eth_phy,
sys_clk_freq = args.sys_clk_freq,
use_internal_osc = args.use_internal_osc,
sdram_rate = args.sdram_rate,
**soc_core_argdict(args))
builder = Builder(soc, **builder_argdict(args))
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment