From 1202c387bf4af2a0757f6ad690218f775bc9028f Mon Sep 17 00:00:00 2001 From: Charles-Henri Mousset Date: Tue, 28 Feb 2023 10:16:23 +0100 Subject: [PATCH 1/3] [init] added colorlight i5a-907 support --- litex_boards/platforms/colorlight_i5a_907.py | 136 +++++++++++++++++++ litex_boards/targets/colorlight_5a_75x.py | 6 +- 2 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 litex_boards/platforms/colorlight_i5a_907.py diff --git a/litex_boards/platforms/colorlight_i5a_907.py b/litex_boards/platforms/colorlight_i5a_907.py new file mode 100644 index 0000000..37eee63 --- /dev/null +++ b/litex_boards/platforms/colorlight_i5a_907.py @@ -0,0 +1,136 @@ +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2020 Florent Kermarrec +# SPDX-License-Identifier: BSD-2-Clause + +# The Colorlight 5A-75B PCB and IOs have been documented by @miek and @smunaut: +# https://github.com/q3k/chubby75/tree/master/5a-75b + +from litex.build.generic_platform import * +from litex.build.lattice import LatticeECP5Platform +from litex.build.lattice.programmer import OpenOCDJTAGProgrammer + +# IOs ---------------------------------------------------------------------------------------------- + +_io_v7_0 = [ # Documented by @miek + # Clk + ("clk25", 0, Pins("P6"), IOStandard("LVCMOS33")), + + # Led + ("user_led_n", 0, Pins("P11"), IOStandard("LVCMOS33")), + + # Button + ("user_btn_n", 0, Pins("M13"), IOStandard("LVCMOS33")), + + # Serial + ("serial", 0, + Subsignal("tx", Pins("P11")), # led (J19 DATA_LED-) + Subsignal("rx", Pins("M13")), # btn (J19 KEY+) + IOStandard("LVCMOS33") + ), + + # SPIFlash (W25Q32JV) + ("spiflash", 0, + # clk + Subsignal("cs_n", Pins("N8")), + #Subsignal("clk", Pins("")), driven through USRMCLK + Subsignal("mosi", Pins("T8")), + Subsignal("miso", Pins("T7")), + IOStandard("LVCMOS33"), + ), + + # SDR SDRAM (M126L6161A) + ("sdram_clock", 0, Pins("C6"), IOStandard("LVCMOS33")), + ("sdram", 0, + Subsignal("a", Pins( + "A9 E10 B12 D13 C12 D11 D10 E9", + "D9 B7 C8")), + Subsignal("dq", Pins( + "B13 C11 C10 A11 C9 E8 B6 B9", + "A6 B5 A5 B4 B3 C3 A2 B2", + "E2 D3 A4 E4 D4 C4 E5 D5", + "E6 D6 D8 A8 B8 B10 B11 E11")), + Subsignal("we_n", Pins("C7")), + Subsignal("ras_n", Pins("D7")), + Subsignal("cas_n", Pins("E7")), + #Subsignal("cs_n", Pins("")), # gnd + #Subsignal("cke", Pins("")), # 3v3 + Subsignal("ba", Pins("A7")), + #Subsignal("dm", Pins("")), # gnd + IOStandard("LVCMOS33"), + Misc("SLEWRATE=FAST") + ), + + # RGMII Ethernet (B50612D) + ("eth_clocks", 0, + Subsignal("tx", Pins("M2")), + Subsignal("rx", Pins("M1")), + IOStandard("LVCMOS33") + ), + ("eth", 0, + #Subsignal("rst_n", Pins("P5")), + Subsignal("mdio", Pins("T2")), + Subsignal("mdc", Pins("P3")), + Subsignal("rx_ctl", Pins("N6")), + Subsignal("rx_data", Pins("N1 M5 N5 M6")), + Subsignal("tx_ctl", Pins("M3")), + Subsignal("tx_data", Pins("L1 L3 P2 L4")), + IOStandard("LVCMOS33") + ), + ("eth_clocks", 1, + Subsignal("tx", Pins("M12")), + Subsignal("rx", Pins("M16")), + IOStandard("LVCMOS33") + ), + ("eth", 1, + #Subsignal("rst_n", Pins("P5")), + Subsignal("mdio", Pins("T2")), + Subsignal("mdc", Pins("P3")), + Subsignal("rx_ctl", Pins("L15")), + Subsignal("rx_data", Pins("P13 N13 P14 M15")), + Subsignal("tx_ctl", Pins("R15")), + Subsignal("tx_data", Pins("T14 R12 R13 R14")), + IOStandard("LVCMOS33") + ), + + # USB + ("usb", 0, + Subsignal("d_p", Pins("M8")), + Subsignal("d_n", Pins("R2")), + Subsignal("pullup", Pins("P4")), + IOStandard("LVCMOS33") + ), +] + +# From https://github.com/q3k/chubby75/blob/master/5a-75b/hardware_V7.0.md +_connectors_v7_0 = [ + ("j1", "- "), + ("j2", "- "), + ("j3", "- "), + ("j4", "- "), +] + + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(LatticeECP5Platform): + default_clk_name = "clk25" + default_clk_period = 1e9/25e6 + + def __init__(self, revision="7.0", toolchain="trellis"): + assert revision in ["6.1", "7.0", "8.0"] + self.revision = revision + device = {"7.0": "LFE5U-25F-6BG256C"}[revision] + io = {"7.0": _io_v7_0 }[revision] + connectors = {"7.0": _connectors_v7_0 }[revision] + LatticeECP5Platform.__init__(self, device, io, connectors=connectors, toolchain=toolchain) + + def create_programmer(self): + return OpenOCDJTAGProgrammer("openocd_colorlight_5a_75b.cfg") + + def do_finalize(self, fragment): + LatticeECP5Platform.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) diff --git a/litex_boards/targets/colorlight_5a_75x.py b/litex_boards/targets/colorlight_5a_75x.py index 5119780..8b4c900 100755 --- a/litex_boards/targets/colorlight_5a_75x.py +++ b/litex_boards/targets/colorlight_5a_75x.py @@ -47,7 +47,7 @@ from litex.gen import * from litex.build.io import DDROutput -from litex_boards.platforms import colorlight_5a_75b, colorlight_5a_75e +from litex_boards.platforms import colorlight_5a_75b, colorlight_5a_75e, colorlight_i5a_907 from litex.soc.cores.clock import * from litex.soc.integration.soc_core import * @@ -125,11 +125,13 @@ class BaseSoC(SoCCore): sdram_rate = "1:1", **kwargs): board = board.lower() - assert board in ["5a-75b", "5a-75e"] + assert board in ["5a-75b", "5a-75e", "i5a-907"] if board == "5a-75b": platform = colorlight_5a_75b.Platform(revision=revision, toolchain=toolchain) elif board == "5a-75e": platform = colorlight_5a_75e.Platform(revision=revision, toolchain=toolchain) + elif board == "i5a-907": + platform = colorlight_i5a_907.Platform(revision=revision, toolchain=toolchain) 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." From 874532871f04abc585d5d6662e04e07fc49b1b22 Mon Sep 17 00:00:00 2001 From: Charles-Henri Mousset Date: Sat, 29 Apr 2023 18:28:56 +0200 Subject: [PATCH 2/3] [enh] taking advantage of pins directly connected --- litex_boards/platforms/colorlight_i5a_907.py | 41 ++++++++++++++------ litex_boards/targets/colorlight_5a_75x.py | 8 +++- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/litex_boards/platforms/colorlight_i5a_907.py b/litex_boards/platforms/colorlight_i5a_907.py index 37eee63..7d93f3a 100644 --- a/litex_boards/platforms/colorlight_i5a_907.py +++ b/litex_boards/platforms/colorlight_i5a_907.py @@ -2,10 +2,14 @@ # This file is part of LiteX-Boards. # # Copyright (c) 2020 Florent Kermarrec +# Copyright (c) 2023 Charles-Henri Mousset # SPDX-License-Identifier: BSD-2-Clause # The Colorlight 5A-75B PCB and IOs have been documented by @miek and @smunaut: # https://github.com/q3k/chubby75/tree/master/5a-75b +# The Colorlight 5A-907 PCB, which is heavily based on the 5A-75B has been documented by @chmouss: +# https://github.com/chmousset/colorlight_reverse + from litex.build.generic_platform import * from litex.build.lattice import LatticeECP5Platform @@ -13,7 +17,7 @@ from litex.build.lattice.programmer import OpenOCDJTAGProgrammer # IOs ---------------------------------------------------------------------------------------------- -_io_v7_0 = [ # Documented by @miek +_io_v7_0 = [ # Documented by @miek and @chmouss # Clk ("clk25", 0, Pins("P6"), IOStandard("LVCMOS33")), @@ -25,8 +29,14 @@ _io_v7_0 = [ # Documented by @miek # Serial ("serial", 0, - Subsignal("tx", Pins("P11")), # led (J19 DATA_LED-) - Subsignal("rx", Pins("M13")), # btn (J19 KEY+) + Subsignal("tx", Pins("P15")), # FAN pin 1 + Subsignal("rx", Pins("L14")), # FAN pin 2 + IOStandard("LVCMOS33") + ), + + ("uartbone", 0, + Subsignal("tx", Pins("F15")), # EXT_VOL pin 1 + Subsignal("rx", Pins("E16")), # EXT_VOL pin 2 IOStandard("LVCMOS33") ), @@ -95,20 +105,29 @@ _io_v7_0 = [ # Documented by @miek ), # USB + # To use the USB: + # shunt R124 and R134 + # remove R107 + # connect on R107's pad towards FPGA to R124 shunt through a 1.5k resistor ("usb", 0, - Subsignal("d_p", Pins("M8")), - Subsignal("d_n", Pins("R2")), - Subsignal("pullup", Pins("P4")), + Subsignal("d_p", Pins("F15")), # EXT_VOL pin 1 + Subsignal("d_n", Pins("E16")), # EXT_VOL pin 2 + Subsignal("pullup", Pins("A12")), # R107's pad towards FPGA IOStandard("LVCMOS33") ), ] -# From https://github.com/q3k/chubby75/blob/master/5a-75b/hardware_V7.0.md +# Documented by @chmouss _connectors_v7_0 = [ - ("j1", "- "), - ("j2", "- "), - ("j3", "- "), - ("j4", "- "), + ("door", "- - P16"), + ("smoke", "- - M14 -"), + ("fan", "- P15 L14"), + ("ext_vol", "- F15 E16"), + # pinout: 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 + ("j1", "- L2 K1 F12 J14 B16 - J5 K2 F3 F1 T4 G3 - G2 H3 R5 H5 J4 K3 - R8 G1 K4 C2 P8 E3"), + ("j2", "- L2 K1 F12 J14 B16 - J2 J1 H4 K5 R7 P1 - R1 L5 P7 F2 P4 R2 - N7 M8 M9 T6 M7 R6"), + ("j3", "- L2 K1 F12 J14 B16 - G4 G5 M11 N11 L13 P12 - K15 N12 G13 L16 K16 J15 - G12 J16 J12 H15 F13 G16"), + ("j4", "- L2 K1 F12 J14 B16 - F5 F4 H13 J13 E15 H12 - G14 H14 D16 G15 A15 F16 - F14 A14 E13 B14 E14 A13"), ] diff --git a/litex_boards/targets/colorlight_5a_75x.py b/litex_boards/targets/colorlight_5a_75x.py index 8b4c900..1a95470 100755 --- a/litex_boards/targets/colorlight_5a_75x.py +++ b/litex_boards/targets/colorlight_5a_75x.py @@ -138,6 +138,8 @@ class BaseSoC(SoCCore): # CRG -------------------------------------------------------------------------------------- with_rst = kwargs["uart_name"] not in ["serial", "crossover"] # serial_rx shared with user_btn_n. + if board == "i5a-907": + with_rst = True with_usb_pll = kwargs.get("uart_name", None) == "usb_acm" self.crg = _CRG(platform, sys_clk_freq, use_internal_osc = use_internal_osc, @@ -178,17 +180,19 @@ class BaseSoC(SoCCore): # Leds ------------------------------------------------------------------------------------- # Disable leds when serial is used. - if platform.lookup_request("serial", loose=True) is None and with_led_chaser: + if platform.lookup_request("serial", loose=True) is None and with_led_chaser or board == "i5a-907": self.leds = LedChaser( pads = platform.request_all("user_led_n"), sys_clk_freq = sys_clk_freq) + self.add_uartbone(name="uartbone") + # Build -------------------------------------------------------------------------------------------- def main(): from litex.build.parser import LiteXArgumentParser parser = LiteXArgumentParser(platform=colorlight_5a_75b.Platform, description="LiteX SoC on Colorlight 5A-75X.") - parser.add_target_argument("--board", default="5a-75b", help="Board type (5a-75b or 5a-75e).") + parser.add_target_argument("--board", default="5a-75b", help="Board type (5a-75b, 5a-75e or i5a-907).") parser.add_target_argument("--revision", default="7.0", help="Board revision (6.0, 6.1, 7.0 or 8.0).") parser.add_target_argument("--sys-clk-freq", default=60e6, type=float, help="System clock frequency.") ethopts = parser.target_group.add_mutually_exclusive_group() From 31c680abf8a9201e01d23c2e55ba794ebea2f6b6 Mon Sep 17 00:00:00 2001 From: Charles-Henri Mousset Date: Sun, 30 Apr 2023 09:42:31 +0200 Subject: [PATCH 3/3] [enh] added option for uartbone --- litex_boards/platforms/colorlight_i5a_907.py | 7 ++++--- litex_boards/targets/colorlight_5a_75x.py | 17 +++++++++++++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/litex_boards/platforms/colorlight_i5a_907.py b/litex_boards/platforms/colorlight_i5a_907.py index 7d93f3a..8c7d08c 100644 --- a/litex_boards/platforms/colorlight_i5a_907.py +++ b/litex_boards/platforms/colorlight_i5a_907.py @@ -7,7 +7,7 @@ # The Colorlight 5A-75B PCB and IOs have been documented by @miek and @smunaut: # https://github.com/q3k/chubby75/tree/master/5a-75b -# The Colorlight 5A-907 PCB, which is heavily based on the 5A-75B has been documented by @chmouss: +# The Colorlight 5A-907 PCB, which is heavily based on the 5A-75B, has been documented by @chmouss: # https://github.com/chmousset/colorlight_reverse @@ -108,7 +108,8 @@ _io_v7_0 = [ # Documented by @miek and @chmouss # To use the USB: # shunt R124 and R134 # remove R107 - # connect on R107's pad towards FPGA to R124 shunt through a 1.5k resistor + # connect R107's pad towards FPGA to R124 shunt through a 1.5k resistor + # note: it conflicts with uartbone ("usb", 0, Subsignal("d_p", Pins("F15")), # EXT_VOL pin 1 Subsignal("d_n", Pins("E16")), # EXT_VOL pin 2 @@ -138,7 +139,7 @@ class Platform(LatticeECP5Platform): default_clk_period = 1e9/25e6 def __init__(self, revision="7.0", toolchain="trellis"): - assert revision in ["6.1", "7.0", "8.0"] + assert revision in ["7.0"] self.revision = revision device = {"7.0": "LFE5U-25F-6BG256C"}[revision] io = {"7.0": _io_v7_0 }[revision] diff --git a/litex_boards/targets/colorlight_5a_75x.py b/litex_boards/targets/colorlight_5a_75x.py index 1a95470..d2dc769 100755 --- a/litex_boards/targets/colorlight_5a_75x.py +++ b/litex_boards/targets/colorlight_5a_75x.py @@ -39,6 +39,10 @@ # 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 # pinout but happens to work on hardware... +# +# Note you can also use the i5a-907 board: +# ./colorlight_5a_75x.py --board=i5a-907 --revision=7.0 --build + from migen import * from migen.genlib.resetsync import AsyncResetSynchronizer @@ -118,6 +122,7 @@ class BaseSoC(SoCCore): def __init__(self, board, revision, sys_clk_freq=60e6, toolchain="trellis", with_ethernet = False, with_etherbone = False, + with_uartbone = False, eth_ip = "192.168.1.50", eth_phy = 0, with_led_chaser = True, @@ -180,12 +185,18 @@ class BaseSoC(SoCCore): # Leds ------------------------------------------------------------------------------------- # Disable leds when serial is used. - if platform.lookup_request("serial", loose=True) is None and with_led_chaser or board == "i5a-907": + if (platform.lookup_request("serial", loose=True) is None and with_led_chaser + or board == "i5a-907"): self.leds = LedChaser( pads = platform.request_all("user_led_n"), sys_clk_freq = sys_clk_freq) - self.add_uartbone(name="uartbone") + # Uartbone --------------------------------------------------------------------------------- + if with_uartbone: + if board != "i5a-907": + raise ValueError("uartbone only supported on i5a-907") + self.add_uartbone(name="uartbone") + # Build -------------------------------------------------------------------------------------------- @@ -198,6 +209,7 @@ def main(): 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("--with-uartbone", action="store_true", help="Add uartbone on 'FAN OUT' connector.") parser.add_target_argument("--eth-ip", default="192.168.1.50", help="Ethernet/Etherbone IP address.") parser.add_target_argument("--eth-phy", default=0, type=int, help="Ethernet PHY (0 or 1).") parser.add_target_argument("--use-internal-osc", action="store_true", help="Use internal oscillator.") @@ -209,6 +221,7 @@ def main(): toolchain = args.toolchain, with_ethernet = args.with_ethernet, with_etherbone = args.with_etherbone, + with_uartbone = args.with_uartbone, eth_ip = args.eth_ip, eth_phy = args.eth_phy, use_internal_osc = args.use_internal_osc,