litex-boards/litex_boards/platforms/logicbone.py

209 lines
7.6 KiB
Python

#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2020 Owen Kirby <oskirby@gmail.com>
# SPDX-License-Identifier: BSD-2-Clause
#
# Logicbone ECP5:
# - Design files: https://github.com/oskirby/logicbone
# - Bootloader: https://github.com/oskirby/tinydfu-bootloader
#
from litex.build.generic_platform import *
from litex.build.lattice import LatticeECP5Platform
from litex.build.dfu import DFUProg
# IOs ----------------------------------------------------------------------------------------------
_io_rev0 = [
# Clk / Rst
("clk25", 0, Pins("M19"), IOStandard("LVCMOS18")),
("rst_n", 0, Pins("C17"), IOStandard("LVCMOS33")),
# Leds
("user_led", 0, Pins("D16"), IOStandard("LVCMOS33")),
("user_led", 1, Pins("C15"), IOStandard("LVCMOS33")),
("user_led", 2, Pins("C13"), IOStandard("LVCMOS33")),
("user_led", 3, Pins("B13"), IOStandard("LVCMOS33")),
# Buttons
("user_btn", 0, Pins("U2"), IOStandard("LVCMOS33")),
# DDR3 SDRAM
("ddram", 0,
Subsignal("a", Pins(
"D5 F4 B3 F3 E5 C3 C4 A5",
"A3 B5 G3 F5 D2 A4 D3 E3"),
IOStandard("SSTL135_I")),
Subsignal("ba", Pins("B4 H5 N2"), IOStandard("SSTL135_I")),
Subsignal("ras_n", Pins("L1"), IOStandard("SSTL135_I")),
Subsignal("cas_n", Pins("M1"), IOStandard("SSTL135_I")),
Subsignal("we_n", Pins("E4"), IOStandard("SSTL135_I")),
Subsignal("cs_n", Pins("M3"), IOStandard("SSTL135_I")),
#Subsignal("dm", Pins("L4 J5"), IOStandard("SSTL135_I")),
Subsignal("dm", Pins("L5 H3"), IOStandard("SSTL135_I")), # HACK: I broke the DM pins, so we'll use some NC pins instead.
Subsignal("dq", Pins(
"G2 K1 F1 K3 H2 J3 G1 H1",
"B1 E1 A2 F2 C1 E2 C2 D1"),
IOStandard("SSTL135_I"),
Misc("TERMINATION=75")),
Subsignal("dqs_p", Pins("K2 H4"), IOStandard("SSTL135D_I"),
Misc("TERMINATION=OFF"),
Misc("DIFFRESISTOR=100")),
Subsignal("clk_p", Pins("M4"), IOStandard("SSTL135D_I")),
Subsignal("cke", Pins("K4"), IOStandard("SSTL135_I")),
Subsignal("odt", Pins("C5"), IOStandard("SSTL135_I")),
Subsignal("reset_n", Pins("P1"), IOStandard("SSTL135_I")),
Misc("SLEWRATE=FAST"),
),
# USB
("usb", 0,
Subsignal("d_p", Pins("B12")),
Subsignal("d_n", Pins("C12")),
Subsignal("pullup", Pins("C16")),
IOStandard("LVCMOS33")
),
# Serial
("serial", 0,
Subsignal("rx", Pins("B6"), IOStandard("LVCMOS33")),
Subsignal("tx", Pins("A7"), IOStandard("LVCMOS33")),
),
# SPIFlash
("spiflash", 0,
Subsignal("cs_n", Pins("R2"), IOStandard("LVCMOS33")),
#Subsignal("clk", Pins("U3"), IOStandard("LVCMOS33")), # Note: CLK is bound using USRMCLK block
Subsignal("miso", Pins("V2"), IOStandard("LVCMOS33")),
Subsignal("mosi", Pins("W2"), IOStandard("LVCMOS33")),
Subsignal("wp", Pins("Y2"), IOStandard("LVCMOS33")),
Subsignal("hold", Pins("W1"), IOStandard("LVCMOS33")),
),
("spiflash4x", 0,
Subsignal("cs_n", Pins("R2"), IOStandard("LVCMOS33")),
#Subsignal("clk", Pins("U3"), IOStandard("LVCMOS33")), # Note: CLK is bound using USRMCLK block
Subsignal("dq", Pins("W2 V2 Y2 W1"), IOStandard("LVCMOS33")),
),
# SDCard
("spisdcard", 0,
Subsignal("clk", Pins("E11")),
Subsignal("mosi", Pins("D15"), Misc("PULLMODE=UP")),
Subsignal("cs_n", Pins("E14"), Misc("PULLMODE=UP")),
Subsignal("miso", Pins("D13"), Misc("PULLMODE=UP")),
Misc("SLEWRATE=FAST"),
IOStandard("LVCMOS33"),
),
("sdcard", 0,
Subsignal("clk", Pins("E11")),
Subsignal("cmd", Pins("D15"), Misc("PULLMODE=UP")),
Subsignal("data", Pins("D13 E13 E15 E14"), Misc("PULLMODE=UP")),
Subsignal("cd", Pins("D14"), Misc("PULLMODE=UP")),
IOStandard("LVCMOS33"), Misc("SLEWRATE=FAST")
),
# I2C
("i2c", 0,
Subsignal("sda", Pins("V1")),
Subsignal("scl", Pins("U1")),
IOStandard("LVCMOS33")
),
# RGMII Ethernet
("eth_clocks", 0,
Subsignal("tx", Pins("A15")),
Subsignal("rx", Pins("B18")),
Subsignal("ref", Pins("A19")),
IOStandard("LVCMOS33")
),
("eth", 0,
#Subsignal("rst_n", Pins("U17")), # Stolen for SYS_RESETn on prototypes.
Subsignal("int_n", Pins("B20"), Misc("PULLMODE=UP")), # HACK: Should have a pullup on the board.
Subsignal("mdio", Pins("B19"), Misc("PULLMODE=UP")), # HACK: Should have a pullup on the board.
Subsignal("mdc", Pins("D12")),
Subsignal("tx_ctl", Pins("B15")),
Subsignal("tx_data", Pins("A12 A13 C14 A14")),
Subsignal("rx_ctl", Pins("A18")),
Subsignal("rx_data", Pins("B17 A17 B16 A16")),
IOStandard("LVCMOS33")
),
]
# Connectors ---------------------------------------------------------------------------------------
_connectors_rev0 = [
("P8",
"None", # No pin 0
"None", "None", # GND
"C20", "D19", # P8_LVDS1
"D20", "E19", # P8_LVDS2
"E20", "F19", # P8_LVDS3
"F20", "G20", # P8_LVDS4
"None", "None",
"None", "None",
"None", "None",
"None", "None",
"None", "None",
"None", "None",
"G19", "H20", # P8_LVDS5
"J20", "K20", # P8_LVDS6
"C18", "D17", # P8_LVDS7
"D18", "E17", # P8_LVDS8
"E18", "F18", # P8_LVDS9
"F17", "G18", # P8_LVDS10
"E16", "F16", # P8_LVDS11
"G16", "H16", # P8_LVDS12
"J17", "J16", # P8_LVDS13
"H18", "H17", # P8_LVDS14
"J19", "K19", # P8_LVDS15
"J18", "K18"), # P8_LVDS16
("P9",
"None", # No pin 0
"None", "None", # GND
"None", "None", # VCC3V3
"None", "None", # CAPE_5V
"None", "None", # VBUS
"None", "None", # PWR_BUTTON, SYS_RESETn
"A11", "B11", # GPIO11, GPIO12
"A10", "C10", # GPIO13, GPIO14
"A9", "B9", # GPIO15, GPIO16
"C11", "A8", # GPIO17, GPIO18
"None", "None", # I2C Bus
"D9", "C8", # GPIO21, GPIO22
"B8", "A7", # GPIO23, GPIO24
"A6", "B6", # GPIO25, GPIO26
"D8", "C7", # GPIO27, P9_SPI_CSEL
"D7", "C6", # P9_SPI_D0, P9_SPI_D1
"D6", "None", # P9_SPI_SCLK, VADC
"None", "None", # AIN4, GNDA
"None", "None", # AIN6, AIN5
"None", "None", # AIN2, AIN3
"None", "None", # AIN0, AIN1
"B10", "E10", # CLKOUT, GPIO42
"None", "None", # GND
"None", "None") # GND
]
# Platform -----------------------------------------------------------------------------------------
class Platform(LatticeECP5Platform):
default_clk_name = "clk25"
default_clk_period = 1e9/25e6
def __init__(self, revision="rev0", device="45F", toolchain="trellis", **kwargs):
assert revision in ["rev0"]
self.revision = revision
io = {"rev0": _io_rev0 }[revision]
connectors = {"rev0": _connectors_rev0 }[revision]
LatticeECP5Platform.__init__(self, f"LFE5UM5G-{device}-8BG381C", io, connectors, toolchain=toolchain, **kwargs)
def create_programmer(self):
return DFUProg(vid="1d50", pid="6130")
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", loose=True), 1e9/125e6)