Add RCS Sparrowhawk and Arctic Tern platforms

Sparrowhawk is a single CPU POWER9 OpenVPX platform
Arctic Tern is a ModBMC-based platform for BMC development
parent cb1ea6c6
......@@ -33,6 +33,10 @@ Please see the [Quick Start Guide](https://gitlab.raptorengineering.com/kestrel-
cd kestrel/litex/litex-boards/litex_boards/targets
./kestrel_versa_ecp5.py --device=LFE5UM --cpu-type=microwatt --cpu-variant=standard+ghdl+irq --with-ethernet --build --nextpnr-seed 1
or
./sparrowhawk_bmc.py --device=LFE5UM5G --cpu-type=microwatt --cpu-variant=standard+ghdl+irq --with-ethernet --with-video --build --nextpnr-seed 1
or
./rcs_arctic_tern_bmc_card.py --device=LFE5UM --cpu-type=microwatt --cpu-variant=standard+ghdl+irq --with-ethernet --with-video --build --nextpnr-seed 1
# Updating the bitstream with new firmware
......
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2022 Raptor Engineering, LLC
# SPDX-License-Identifier: BSD-2-Clause
from litex.build.generic_platform import *
from litex.build.lattice import LatticePlatform
from litex.build.lattice.programmer import OpenOCDJTAGProgrammer
import os
# IOs ----------------------------------------------------------------------------------------------
_io = [
# Clk / Rst (module)
("clk125", 0, Pins("B6"), IOStandard("LVCMOS33")),
("rst_n", 0, Pins("T3"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
# BMC serial (module)
("serial", 0,
Subsignal("rx", Pins("B8"), IOStandard("LVCMOS33")),
Subsignal("tx", Pins("A7"), IOStandard("LVCMOS33")),
),
# Host serial (module)
("serial", 1,
Subsignal("rx", Pins("C1"), IOStandard("LVCMOS33")),
Subsignal("tx", Pins("C2"), IOStandard("LVCMOS33")),
Subsignal("rts", Pins("C8"), IOStandard("LVCMOS33")),
Subsignal("cts", Pins("D8"), IOStandard("LVCMOS33")),
),
# DDR3 SDRAM (module)
("ddram", 0,
Subsignal("a", Pins(
"J1 K1 G2 H2 F1 G1 J4 J3 J5 K3 K2 H1 M5 K4 L4"),
IOStandard("SSTL135_I")),
Subsignal("ba", Pins("K5 L5 M1"), IOStandard("SSTL135_I")),
Subsignal("ras_n", Pins("L2"), IOStandard("SSTL135_I")),
Subsignal("cas_n", Pins("N2"), IOStandard("SSTL135_I")),
Subsignal("we_n", Pins("N1"), IOStandard("SSTL135_I")),
Subsignal("cs_n", Pins("P5"), IOStandard("SSTL135_I")),
Subsignal("dm", Pins("R20 N18 F20 E18"), IOStandard("SSTL135_I")),
Subsignal("dq", Pins(
"T20 U17 T18 U16 U19 T17 U20 U18",
"L19 M18 L17 L16 L20 M19 L18 M20",
"J20 K18 F19 K19 J19 J18 G20 K20",
"G16 H18 H16 F18 J16 E17 J17 H17"),
IOStandard("SSTL135_I"),
Misc("TERMINATION=75")),
Subsignal("dqs_p", Pins("T19 N16 G19 F17"), IOStandard("SSTL135D_I"),
Misc("TERMINATION=OFF"),
Misc("DIFFRESISTOR=100")),
Subsignal("clk_p", Pins("P19 E16"), IOStandard("SSTL135D_I")),
Subsignal("cke", Pins("N5"), IOStandard("SSTL135_I")),
Subsignal("odt", Pins("M3"), IOStandard("SSTL135_I")),
Subsignal("reset_n", Pins("L1"), IOStandard("SSTL135_I")),
Misc("SLEWRATE=FAST"),
),
# PCIe (module)
("pcie_x1", 0,
Subsignal("clk_p", Pins("Y11")),
Subsignal("clk_n", Pins("Y12")),
Subsignal("rx_p", Pins("Y5")),
Subsignal("rx_n", Pins("Y6")),
Subsignal("tx_p", Pins("W4")),
Subsignal("tx_n", Pins("W5")),
Subsignal("perst", Pins("A6"), IOStandard("LVCMOS33")),
),
# Inter-module SERDES (module)
("serdes_x2", 0,
Subsignal("clk_p", Pins("Y19")),
Subsignal("clk_n", Pins("W20")),
Subsignal("rx_p", Pins("Y14 Y16")),
Subsignal("rx_n", Pins("Y15 Y17")),
Subsignal("tx_p", Pins("W13 W17")),
Subsignal("tx_n", Pins("W14 W18")),
Subsignal("perst", Pins("A6"), IOStandard("LVCMOS33")),
),
# Bitstream Flash device (module)
# Contains FPGA bistream, USRMCLK block required for clock output
("fpgaspiflash4x", 0,
Subsignal("cs_n", Pins("R2")),
Subsignal("dq", Pins("W2 V2 Y2 W1")),
IOStandard("LVCMOS33"),
Misc("SLEWRATE=SLOW"),
Misc("DRIVE=16"),
),
# BMC firmware Flash device (carrier card)
("bmcspiflash4x", 0,
Subsignal("cs_n", Pins("G5")),
Subsignal("clk", Pins("E5")),
Subsignal("dq", Pins("E3 F5 D2 H4")),
IOStandard("LVCMOS33"),
Misc("SLEWRATE=SLOW"),
Misc("DRIVE=16"),
),
# Host Flash device (carrier card)
("hostspiflash4x", 0,
Subsignal("cs_n", Pins("E2")),
Subsignal("clk", Pins("G3")),
Subsignal("dq", Pins("F2 F3 D1 A2")),
IOStandard("LVCMOS33"),
Misc("SLEWRATE=SLOW"),
Misc("DRIVE=16"),
),
# I2C bus 1
# 3-pin header (carrier card)
("i2c_master", 0,
Subsignal("sda", Pins("E4"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
Subsignal("scl", Pins("D5"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
),
# I2C bus 2
# 3-pin header (carrier card)
("i2c_master", 1,
Subsignal("sda", Pins("B1"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
Subsignal("scl", Pins("B2"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
),
# I2C bus 3
# 3-pin header (carrier card)
("i2c_master", 2,
Subsignal("sda", Pins("C7"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
Subsignal("scl", Pins("E8"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
),
# I2C bus 4
# GPIO expander 1 (module)
("i2c_master", 3,
Subsignal("sda", Pins("U1"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
Subsignal("scl", Pins("R1"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
),
# I2C bus 5
# GPIO expander 2 (module)
("i2c_master", 4,
Subsignal("sda", Pins("A12"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
Subsignal("scl", Pins("E12"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
),
# I2C bus 9
("i2c_master", 5,
Subsignal("sda", Pins("R3"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
Subsignal("scl", Pins("U2"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
),
# I2C bus 12
# RTC + digital video + temperature sensor (module)
# Clock generator + PMBus (carrier card)
("i2c_master", 6,
Subsignal("sda", Pins("V1"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
Subsignal("scl", Pins("T1"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
),
# Host LPC interface (module)
("hostlpcslave", 0,
Subsignal("frame_n", Pins("D3"), Misc("PULLMODE=UP")),
Subsignal("reset_n", Pins("C3"), Misc("PULLMODE=UP")),
Subsignal("addrdata", Pins("C4 A3 B4 B3"), Misc("PULLMODE=UP")),
Subsignal("serirq", Pins("F4"), Misc("PULLMODE=UP")),
Subsignal("clk", Pins("H5"), Misc("PULLMODE=NONE")),
IOStandard("LVCMOS33"),
Misc("SLEWRATE=SLOW"),
Misc("DRIVE=16"),
),
# FSI (carrier card)
("openfsi_master", 0,
Subsignal("clock", Pins("A18"), IOStandard("LVCMOS33")),
Subsignal("data", Pins("B18"), IOStandard("LVCMOS33")),
Subsignal("data_direction", Pins("T2"), IOStandard("LVCMOS33")),
),
# RGMII Ethernet (module)
("eth_clocks", 0,
Subsignal("tx", Pins("C11")),
Subsignal("rx", Pins("A9")),
IOStandard("LVCMOS33")
),
("eth", 0,
# Reset is available on GPIO expander 2
Subsignal("mdio", Pins("D9")),
Subsignal("mdc", Pins("E6")),
Subsignal("rx_ctl", Pins("A8")),
Subsignal("rx_data", Pins("E9 C9 D10 E10")),
Subsignal("tx_ctl", Pins("C10")),
Subsignal("tx_data", Pins("B10 A10 B11 A11")),
IOStandard("LVCMOS33")
),
# Digital video (module)
("dvo", 0,
Subsignal("r", Pins(
"C14 E14 D14 E13 D13 C13 E11 C12")),
Subsignal("g", Pins(
"B19 B20 C17 C16 C15 D16 D15 E15")),
Subsignal("b", Pins(
"A14 A15 B15 A16 B16 A17 A19 B17")),
Subsignal("de", Pins("A13")),
Subsignal("hsync_n", Pins("B13")),
Subsignal("vsync_n", Pins("B12")),
Subsignal("clk", Pins("D11")),
IOStandard("LVCMOS33")
),
# 4-pin fan headers (carrier card)
("pwm_tach_pads", 0,
Subsignal("pwm1", Pins("B5"), IOStandard("LVCMOS33")),
Subsignal("pwm2", Pins("C5"), IOStandard("LVCMOS33")),
Subsignal("pwm3", Pins("E1"), IOStandard("LVCMOS33")),
Subsignal("pwm4", Pins("H3"), IOStandard("LVCMOS33")),
Subsignal("tach1", Pins("D7"), IOStandard("LVCMOS33")),
Subsignal("tach2", Pins("C6"), IOStandard("LVCMOS33")),
Subsignal("tach3", Pins("E7"), IOStandard("LVCMOS33")),
Subsignal("tach4", Pins("D6"), IOStandard("LVCMOS33")),
),
]
# Platform -----------------------------------------------------------------------------------------
class Platform(LatticePlatform):
default_clk_name = "clk125"
default_clk_period = 1e9/125e6
def __init__(self, device="LFE5UM", speed_grade="7", toolchain="trellis", **kwargs):
assert device in ["LFE5UM5G", "LFE5UM"]
if device is "LFE5UM5G":
speed_grade = "8"
LatticePlatform.__init__(self, device + "-85F-" + speed_grade + "CABGA381", _io, toolchain=toolchain, **kwargs)
def request(self, *args, **kwargs):
return LatticePlatform.request(self, *args, **kwargs)
def create_programmer(self):
return OpenOCDJTAGProgrammer("openocd_evn_ecp5.cfg")
def do_finalize(self, fragment):
LatticePlatform.do_finalize(self, fragment)
self.add_period_constraint(self.lookup_request("clk125", loose=True), 1e9/125e6)
self.add_period_constraint(self.lookup_request("eth_clocks:rx", 0, loose=True), 1e9/125e6)
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2017 Sergiusz Bazanski <q3k@q3k.org>
# Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
# Copyright (c) 2020-2021 Raptor Engineering, LLC
# SPDX-License-Identifier: BSD-2-Clause
from litex.build.generic_platform import *
from litex.build.lattice import LatticePlatform
from litex.build.lattice.programmer import OpenOCDJTAGProgrammer
# IOs ----------------------------------------------------------------------------------------------
_io = [
# Clk / Rst
("clk24", 0, Pins("B6"), IOStandard("LVCMOS33")),
("rst_n", 0, Pins("T2"), IOStandard("LVCMOS33")), # Front panel power button, for easy debugging
# GPIO Bank 1
# BMC_POWER_UP | BMC_BOOT_PHASE | BP_SYSRESET_N | DBG_FSI0_EN | SYS_PWROK_BUF | BMC_INTRUDER_N | PM_CP0_ATTENTION_B | BMC_FP_ID_BTN
("gpio1", 0, Pins("T17 U16 C5 C6 T1 V1 R3 U2"), IOStandard("LVCMOS33")),
# Serial (BMC COM1)
("serial", 0,
Subsignal("rx", Pins("D10"), IOStandard("LVCMOS33")),
Subsignal("tx", Pins("E10"), IOStandard("LVCMOS33")),
),
# NCSI Ethernet
("eth_clocks", 0,
Subsignal("ref_clk", Pins("A9")),
IOStandard("LVCMOS33")
),
("eth", 0,
Subsignal("crs_dv", Pins("B9")),
Subsignal("rx_data", Pins("A10 B10")),
Subsignal("tx_en", Pins("B11")),
Subsignal("tx_data", Pins("C11 A11")),
IOStandard("LVCMOS33")
),
# PCIe
("pcie_x1", 0,
Subsignal("clk_p", Pins("Y11")),
Subsignal("clk_n", Pins("Y12")),
Subsignal("rx_p", Pins("Y5")),
Subsignal("rx_n", Pins("Y6")),
Subsignal("tx_p", Pins("W4")),
Subsignal("tx_n", Pins("W5")),
Subsignal("perst", Pins("A6"), IOStandard("LVCMOS33")),
),
# I2C
# Regulators
("i2c_master", 1,
Subsignal("sda", Pins("B8"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
Subsignal("scl", Pins("A7"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
),
# SEEPROM
("i2c_master", 2,
Subsignal("sda", Pins("D9"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
Subsignal("scl", Pins("A8"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
),
# CPU clock
("i2c_master", 3,
Subsignal("sda", Pins("U1"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
Subsignal("scl", Pins("R1"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
),
# Platform control FPGA / temperature sensors
("i2c_master", 4,
Subsignal("sda", Pins("C7"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
Subsignal("scl", Pins("E8"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
),
# RTC
("i2c_master", 5,
Subsignal("sda", Pins("C8"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
Subsignal("scl", Pins("D8"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
),
# Digital Video
("i2c_master", 6,
Subsignal("sda", Pins("L17"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
Subsignal("scl", Pins("L18"), IOStandard("LVCMOS33"), Misc("PULLMODE=UP")),
),
# FSI
("openfsi_master", 0,
Subsignal("clock", Pins("E7"), IOStandard("LVCMOS33")),
Subsignal("data", Pins("D6"), IOStandard("LVCMOS33")),
Subsignal("data_direction", Pins("D7"), IOStandard("LVCMOS33")),
),
# ECP5 Flash device
# Also contains FPGA bistream, USRMCLK block required for clock output
("bmcspiflash4x", 0,
Subsignal("cs_n", Pins("R2")),
Subsignal("dq", Pins("W2 V2 Y2 W1")),
IOStandard("LVCMOS33"),
Misc("SLEWRATE=SLOW"),
Misc("DRIVE=16"),
),
# Host Flash device
("hostspiflash4x", 0,
Subsignal("cs_n", Pins("E2")),
Subsignal("clk", Pins("G3")),
Subsignal("dq", Pins("F2 F3 B5 B2")),
IOStandard("LVCMOS33"),
Misc("SLEWRATE=SLOW"),
Misc("DRIVE=16"),
),
# Host LPC interface
("hostlpcslave", 0,
Subsignal("frame_n", Pins("D3"), Misc("PULLMODE=UP")),
Subsignal("reset_n", Pins("C3"), Misc("PULLMODE=UP")),
Subsignal("addrdata", Pins("C4 A3 B4 B3"), Misc("PULLMODE=UP")),
Subsignal("serirq", Pins("F4"), Misc("PULLMODE=UP")),
Subsignal("clk", Pins("H5"), Misc("PULLMODE=NONE")),
IOStandard("LVCMOS33"),
Misc("SLEWRATE=SLOW"),
Misc("DRIVE=16"),
),
("hostlpcsecureinterface", 0,
Subsignal("clk_out", Pins("H3"), Misc("PULLMODE=UP")),
IOStandard("LVCMOS33"),
Misc("SLEWRATE=FAST"),
Misc("DRIVE=16"),
),
# Digital video
("dvo", 0,
Subsignal("r", Pins(
"R16 P16 N17 P17 N18 M17 N16 M18")),
Subsignal("g", Pins(
"T20 R20 P20 P18 P19 N20 N19 R17")),
Subsignal("b", Pins(
"T16 R18 T19 U17 U18 T18 U19 U20")),
Subsignal("de", Pins("M19")),
Subsignal("hsync_n", Pins("L19")),
Subsignal("vsync_n", Pins("M20")),
Subsignal("clk", Pins("L20")),
IOStandard("LVCMOS33")
),
]
# Connectors ---------------------------------------------------------------------------------------
_connectors = [
]
# Platform -----------------------------------------------------------------------------------------
class Platform(LatticePlatform):
default_clk_name = "clk24"
default_clk_period = 1e9/24e6
def __init__(self, device="LFE5UM5G", toolchain="trellis", **kwargs):
assert device in ["LFE5UM5G", "LFE5UM"]
LatticePlatform.__init__(self, device + "-85F-8BG381C", _io, _connectors, toolchain=toolchain, **kwargs)
def create_programmer(self):
return OpenOCDJTAGProgrammer("openocd_sparrowhawk_bmc.cfg")
def do_finalize(self, fragment):
self.add_period_constraint(self.lookup_request("clk24", loose=True), 1e9/24e6)
self.add_period_constraint(self.lookup_request("eth_clocks:ref_clk", 0, loose=True), 1e9/50e6)
#!/usr/bin/env python3
#
# This file is part of Kestrel
#
# Copyright (c) 2018-2019 Florent Kermarrec <florent@enjoy-digital.fr>
# Copyright (c) 2018-2019 David Shah <dave@ds0.me>
# Copyright (c) 2020-2022 Raptor Engineering, LLC
# SPDX-License-Identifier: BSD-2-Clause
import os
import argparse
import subprocess
import tempfile
from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer
from litex_boards.platforms import rcs_arctic_tern_bmc_card
from litex.build.lattice.trellis import trellis_args, trellis_argdict
from litex.soc.cores.clock import *
from litex.soc.integration.soc import SoCRegion
from litex.soc.integration.soc_core import *
from litex.soc.integration.soc_sdram import *
from litex.soc.integration.builder import *
from litex.soc.interconnect.csr import AutoCSR
from litex.soc.interconnect.csr import CSRStorage
from litex.soc.interconnect.csr import CSRStatus
from litex.soc.cores.video import VideoDVOPHY
from litex.soc.cores.led import LedChaser
from litex.soc.cores.gpio import _GPIOIRQ
from litedram.modules import MT41J256M16
from litedram.phy import ECP5DDRPHY
from litedram.common import get_default_cl
from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII
# Kestrel-specific peripherals
from tercelspi.tercelspi import TercelSPI
from aquilalpc.aquilalpc import AquilaLPCSlave
from swiftfsi.swiftfsi import OpenFSIMaster
from simplertc.simplertc import SimpleRTCSlave
from simplepwm.simplepwm import SimplePWMSlave
from opencoresi2c.opencoresi2c import OpenCoresI2CMaster
from arcticterngpio.arcticterngpio import ArcticTernGPIOI2CExists
from arcticterngpio.arcticterngpio import ArcticTernSDRHexDriver
# Useful constants
kB = 1024
mB = 1024*kB
# Internal GPIO Output -----------------------------------------------------------------------------
class InternalGPIOOut(Module, AutoCSR):
def __init__(self, data_out, nbits):
self._out = CSRStorage(nbits, description="GPIO Ouptut(s) Control.")
# # #
for i in range(nbits):
self.comb += data_out[i].eq(self._out.storage[i])
# Internal GPIO Tristate ---------------------------------------------------------------------------
class InternalGPIOTristate(_GPIOIRQ, Module, AutoCSR):
def __init__(self, data_in, data_out, data_oe, nbits, with_irq=False):
self._oe = CSRStorage(nbits, description="GPIO Tristate(s) Control.")
self._in = CSRStatus(nbits, description="GPIO Input(s) Status.")
self._out = CSRStorage(nbits, description="GPIO Ouptut(s) Control.")
# # #
for i in range(nbits):
self.comb += data_oe[i].eq(self._oe.storage[i])
self.comb += data_out[i].eq(self._out.storage[i])
self.comb += self._in.status[i].eq(data_in[i])
if with_irq:
self.add_irq(self._in.status)
# CRG ----------------------------------------------------------------------------------------------
class _CRG(Module):
def __init__(self, platform, sys_clk_freq):
self.rst = Signal()
self.clock_domains.cd_init = ClockDomain()
self.clock_domains.cd_por = ClockDomain(reset_less=True)
self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_sys2x = ClockDomain()
self.clock_domains.cd_sys2x_i = ClockDomain(reset_less=True)
self.clock_domains.cd_dvo = ClockDomain(reset_less=True)
# # #
self.stop = Signal()
self.reset = Signal()
# Clk / Rst
clk125 = platform.request("clk125")
rst_n = platform.request("rst_n")
# Power on reset
por_count = Signal(16, reset=2**16-1)
por_done = Signal()
self.comb += por_done.eq(por_count == 0)
self.sync.por += If(~por_done, por_count.eq(por_count - 1))
# PLL
sys2x_clk_ecsout = Signal()
self.submodules.pll = pll = ECP5PLL()
self.comb += pll.reset.eq(~por_done | ~rst_n | self.rst)
pll.register_clkin(clk125, 125e6)
pll.create_clkout(self.cd_sys2x_i, 2*sys_clk_freq)
pll.create_clkout(self.cd_init, 25e6)
self.specials += [
Instance("OSCG",
p_DIV = 128, # 2.4MHz
o_OSC = self.cd_por.clk),
Instance("ECLKBRIDGECS",
i_CLK0 = self.cd_sys2x_i.clk,
i_SEL = 0,
o_ECSOUT = sys2x_clk_ecsout),
Instance("ECLKSYNCB",
i_ECLKI = sys2x_clk_ecsout,
i_STOP = self.stop,
o_ECLKO = self.cd_sys2x.clk),
Instance("CLKDIVF",
p_DIV = "2.0",
i_ALIGNWD = 0,
i_CLKI = self.cd_sys2x.clk,
i_RST = self.reset,
o_CDIVX = self.cd_sys.clk),
AsyncResetSynchronizer(self.cd_sys, ~pll.locked | self.reset),
AsyncResetSynchronizer(self.cd_sys2x, ~pll.locked | self.reset),
]
# Generate DVO clock
pll.create_clkout(self.cd_dvo, 40e6) # 800x600@60
#pll.create_clkout(self.cd_dvo, 148.35e6) # 1920x1080@60
#pll.create_clkout(self.cd_dvo, 148.2e6) # 1920x1200@60
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
mem_map = {
"hostxicsicp" : 0xc3000000,
"hostxicsics" : 0xc3001000,
"ethmac" : 0xc3002000,
"fpgaspiflashcfg" : 0xc3004000,
"bmcspiflashcfg" : 0xc3004100,
"hostspiflashcfg" : 0xc3004200,
"simplertc" : 0xc3005000,
"simplepwm" : 0xc3006800,
"openfsimaster" : 0xc3007000,
"i2cmaster0" : 0xc3008000,
"i2cmaster1" : 0xc3008020,
"i2cmaster2" : 0xc3008040,
"i2cmaster3" : 0xc3008060,
"i2cmaster4" : 0xc3008080,
"i2cmaster5" : 0xc30080a0,
"i2cmaster6" : 0xc30080c0,
"fpgaspiflash" : 0xc4000000,
"bmcspiflash" : 0xc6000000,
"hostspiflash" : 0xc8000000,
"hostlpcslave" : 0xcc000000,
}
mem_map.update(SoCCore.mem_map)
interrupt_map = {
"gpio1" : 1,
"ethmac" : 2,
"hostlpcslave" : 3,
"openfsimaster" : 4,
"i2cmaster0" : 5,
"i2cmaster1" : 6,
"i2cmaster2" : 7,
"i2cmaster3" : 8,
"i2cmaster4" : 9,
"i2cmaster5" : 10,
"i2cmaster6" : 11,
}
interrupt_map.update(SoCCore.interrupt_map)
def __init__(self, sys_clk_freq=int(64e6), device="LFE5UM5G", with_video=False, with_ethernet=False, with_etherbone=False, with_openfsi_master=True, with_fpgaspiflash=True, with_bmcspiflash=True, with_hostspiflash=True, with_hostlpcslave=True, with_i2c_masters=True, with_gpio=True, with_simple_pwm=True, with_simple_rtc=True, eth_ip="192.168.1.50", eth_phy=0, toolchain="trellis", **kwargs):
platform = rcs_arctic_tern_bmc_card.Platform(toolchain=toolchain, device=device)
## Reduce resource wastage on ECP5
kwargs["csr_address_width"] = 14
kwargs["csr_data_width"] = 8
kwargs["csr_paging"] = 0x800
# Disable timer peripheral
# Microwatt, or any other POWER-compliant CPU, already provides an
# architecturally-defined timer with interrupt (decrementer),
# so the LiteX one just wastes resources in Kestrel.
kwargs["with_timer"] = False
kwargs["timer_uptime"] = False
# FIXME: adapt integrated rom size for Microwatt
if kwargs.get("cpu_type", None) == "microwatt":
kwargs["integrated_rom_size"] = 0xd000 if with_ethernet else 0xb000
else:
# There are numerous PowerPC-isms scattered throughout the HDL and firmware.
# Even if you get a bistream out with a non-PowerPC CPU, it probably won't
# work, and the firmware almost certainly won't build, let alone function.
#
# If you are an end user or software developer, you probably forgot to pass
# "--cpu-type=microwatt" to the build script.
#
# If you are a developer and are trying to port the Kestrel HDL and firmware
# to a non-PowerPC CPU, you probably know what you're doing and can debug
# whatever you break on your own hardware. Remove this line and keep hacking!
raise OSError("Kestrel HDL and firmware currently require a PowerPC-compatible CPU to function. Did you forget '--cpu-type=microwatt'?")
# SoCCore -----------------------------------------_----------------------------------------
SoCCore.__init__(self, platform, irq_n_irqs=16, clk_freq=sys_clk_freq,
ident = "Kestrel SoC on Raptor Arctic Tern",
ident_version = True,
**kwargs)
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = _CRG(platform, sys_clk_freq)
# Video Output -----------------------------------------------------------------------------
if with_video:
dvo_pads = platform.request("dvo")
self.submodules.videophy = VideoDVOPHY(dvo_pads, clock_domain="dvo")
#self.add_video_colorbars(phy=self.videophy, timings="800x600@60Hz", clock_domain="dvo")
#self.add_video_colorbars(phy=self.videophy, timings="1920x1080@60Hz", clock_domain="dvo")
#self.add_video_colorbars(phy=self.videophy, timings="1920x1200@60Hz", clock_domain="dvo")
self.add_video_terminal(phy=self.videophy, timings="800x600@60Hz", clock_domain="dvo")
# DDR3 SDRAM --------------------------------------------------------------------------------
if not self.integrated_main_ram_size:
self.submodules.ddrphy = ECP5DDRPHY(
platform.request("ddram"),
cmd_delay=0 if sys_clk_freq > 64e6 else 100,
sys_clk_freq=sys_clk_freq)
self.add_csr("ddrphy")
self.comb += self.crg.stop.eq(self.ddrphy.init.stop)
self.comb += self.crg.reset.eq(self.ddrphy.init.reset)
self.add_sdram("sdram",
phy = self.ddrphy,
module = MT41J256M16(sys_clk_freq, "1:2"), # Not MT41J256M16, but the AS4C256M16D3C in use has similar specifications
origin = self.mem_map["main_ram"],
size = kwargs.get("max_sdram_size", 0x40000000),
l2_cache_size = kwargs.get("l2_size", 8192),