Still unclear what exactly this fixes, I think mostly bugs in migen/LiteX. Not sure if it's synthesizing the memory elements for the sampler modules either.
260 lines
9.2 KiB
Python
260 lines
9.2 KiB
Python
"""
|
|
LiteX Platform for sonar board using Colorlight i9 module
|
|
"""
|
|
|
|
# This file used to belong to LiteX Boards
|
|
#
|
|
# Copyright (c) 2021 Kazumoto Kojima <kkojima@rr.iij4u.or.jp>
|
|
# Copyright (c) 2023 David Lenfesty <lenfesty@ualberta.ca>
|
|
# SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
# The Colorlight i5 PCB and IOs have been documented by @wuxx
|
|
# https://github.com/wuxx/Colorlight-FPGA-Projects
|
|
|
|
import copy
|
|
|
|
from litex.build.generic_platform import *
|
|
from litex.build.lattice import LatticePlatform
|
|
from litex.build.lattice.programmer import EcpDapProgrammer
|
|
|
|
# IOs ----------------------------------------------------------------------------------------------
|
|
|
|
_io_v7_0 = [ # Colorlight i9 documented by @smunaut
|
|
# Clk
|
|
("clk25", 0, Pins("P3"), IOStandard("LVCMOS33")),
|
|
|
|
# Led
|
|
("user_led_n", 0, Pins("U16"), IOStandard("LVCMOS33")),
|
|
|
|
# Serial
|
|
("serial", 0,
|
|
Subsignal("tx", Pins("P16")),
|
|
Subsignal("rx", Pins("L5")),
|
|
IOStandard("LVCMOS33")
|
|
),
|
|
|
|
# TODO the other serial ports
|
|
|
|
# TODO I2C
|
|
|
|
# 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")
|
|
),
|
|
|
|
# GPDI
|
|
("gpdi", 0,
|
|
Subsignal("clk_p", Pins("J19"), IOStandard("LVCMOS33D"), Misc("DRIVE=4")),
|
|
#Subsignal("clk_n", Pins("K19"), IOStandard("LVCMOS33D"), Misc("DRIVE=4")),
|
|
Subsignal("data0_p", Pins("G19"), IOStandard("LVCMOS33D"), Misc("DRIVE=4")),
|
|
#Subsignal("data0_n", Pins("H20"), IOStandard("LVCMOS33D"), Misc("DRIVE=4")),
|
|
Subsignal("data1_p", Pins("E20"), IOStandard("LVCMOS33D"), Misc("DRIVE=4")),
|
|
#Subsignal("data1_n", Pins("F19"), IOStandard("LVCMOS33D"), Misc("DRIVE=4")),
|
|
Subsignal("data2_p", Pins("C20"), IOStandard("LVCMOS33D"), Misc("DRIVE=4")),
|
|
#Subsignal("data2_n", Pins("D19"), IOStandard("LVCMOS33D"), Misc("DRIVE=4")),
|
|
),
|
|
|
|
# High speed parallel ADCs
|
|
("adc", 0,
|
|
# Rev A pins
|
|
#Subsignal("data", Pins("M18 N18 N17 P18 U17 U18 T17 M17 P17 R17")),
|
|
# Rev B pins
|
|
Subsignal("data", Pins("L20 M18 N18 N17 P18 U17 U18 T17 M17 P17")),
|
|
Subsignal("refclk", Pins("K18")),
|
|
Subsignal("oen_b", Pins("C18")),
|
|
Subsignal("standby", Pins("T18")),
|
|
Subsignal("dfs", Pins("R18")),
|
|
Subsignal("otr", Pins("R17")),
|
|
IOStandard("LVCMOS33")
|
|
),
|
|
("adc", 1,
|
|
Subsignal("data", Pins("R1 T1 U1 Y2 W1 V1 M1 N2 N3 T2")),
|
|
Subsignal("refclk", Pins("M4")),
|
|
Subsignal("oen_b", Pins("N4")),
|
|
Subsignal("standby", Pins("R3")),
|
|
Subsignal("dfs", Pins("T3")),
|
|
Subsignal("otr", Pins("M3")),
|
|
IOStandard("LVCMOS33")
|
|
),
|
|
("adc", 2,
|
|
Subsignal("data", Pins("A18 C17 A19 B18 B19 B20 C20 D19 D20 E19")),
|
|
Subsignal("refclk", Pins("J19")),
|
|
Subsignal("oen_b", Pins("H20")),
|
|
Subsignal("standby", Pins("G20")),
|
|
Subsignal("dfs", Pins("G19")),
|
|
Subsignal("otr", Pins("F20")),
|
|
IOStandard("LVCMOS33")
|
|
),
|
|
("adc", 3,
|
|
Subsignal("data", Pins("E4 F1 F3 G3 H3 H4 H5 J4 J5 K3")),
|
|
Subsignal("refclk", Pins("M4")),
|
|
Subsignal("oen_b", Pins("N4")),
|
|
Subsignal("standby", Pins("B3")),
|
|
Subsignal("dfs", Pins("K5")),
|
|
Subsignal("otr", Pins("K4")),
|
|
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"),
|
|
]
|
|
|
|
# ColorLight i9 V 7.2 hardware
|
|
# See https://github.com/wuxx/Colorlight-FPGA-Projects/blob/master/colorlight_i9_v7.2.md
|
|
|
|
# SPIFlash (W25Q64JVSIQ)
|
|
|
|
_io_v7_2 = copy.deepcopy(_io_v7_0)
|
|
|
|
# Change the LED pin to "L2"
|
|
|
|
for i, x in enumerate(_io_v7_2):
|
|
if x[:2] == ("user_led_n", 0):
|
|
_io_v7_2[i] = ("user_led_n", 0, Pins("L2"), IOStandard("LVCMOS33"))
|
|
break
|
|
|
|
# optional, alternative uart location
|
|
# requires "--uart-name serialx"
|
|
_io_v7_2 += [
|
|
("serialx", 0, Subsignal("tx", Pins("E5")), Subsignal("rx", Pins("F4")), IOStandard("LVCMOS33"))
|
|
]
|
|
|
|
_connectors_v7_2 = copy.deepcopy(_connectors_v7_0)
|
|
|
|
# Append the rest of the pmod interfaces
|
|
|
|
_connectors_v7_2 += [
|
|
# P2
|
|
("pmodc", "P17 R18 C18 L2 M17 R17 T18 K18"),
|
|
("pmodd", "J20 L18 M18 N17 G20 K20 L20 N18"),
|
|
# P4
|
|
("pmodg", "H4 G3 F1 F2 H3 F3 E4 E1"),
|
|
("pmodh", "- E19 B3 K5 - B2 K4 A2"),
|
|
# P5
|
|
("pmodi", "D18 G5 F5 E5 D17 D16 E6 F4"),
|
|
("pmodj", "J17 H17 H16 G16 H18 G18 F18 E18"),
|
|
# P6
|
|
("pmodk", "R3 M4 L5 J16 N4 L4 P16 J18"),
|
|
("pmodl", "R1 U1 W1 M1 T1 Y2 V1 N2"),
|
|
]
|
|
|
|
# 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, board="i5", revision="7.0", toolchain="trellis"):
|
|
if board == "i5":
|
|
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]
|
|
if board == "i9":
|
|
assert revision in ["7.2"]
|
|
self.revision = revision
|
|
device = {"7.2": "LFE5U-45F-6BG381C"}[revision]
|
|
io = {"7.2": _io_v7_2}[revision]
|
|
connectors = {"7.2": _connectors_v7_2}[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) |