litex-boards/litex_boards/targets/embedfire_rise_pro.py

205 lines
8.5 KiB
Python
Raw Normal View History

2024-11-01 22:09:06 -04:00
#!/usr/bin/env python3
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2024 Yu-Ti Kuo <bobgash2@gmail.com>
# SPDX-License-Identifier: BSD-2-Clause
# embedfire rise pro FPGA: https://detail.tmall.com/item.htm?id=645153441975
from migen import *
from litex.gen import *
from litex_boards.platforms import embedfire_rise_pro
from litex.soc.cores.clock import *
from litex.soc.integration.soc import SoCRegion
from litex.soc.integration.soc_core import *
from litex.soc.integration.builder import *
from litex.soc.cores.led import LedChaser
from litex.soc.cores.gpio import GPIOIn
from litex.soc.cores.xadc import XADC
from litex.soc.cores.dna import DNA
from litex.soc.cores.pwm import PWM
from litedram.modules import MT41K256M16
from litedram.phy import s7ddrphy
from liteeth.phy.mii import LiteEthPHYMII
# CRG ----------------------------------------------------------------------------------------------
class _CRG(LiteXModule):
def __init__(self, platform, sys_clk_freq, with_dram=True, with_rst=True):
self.rst = Signal()
self.cd_sys = ClockDomain()
if with_dram:
self.cd_sys4x = ClockDomain()
self.cd_sys4x_dqs = ClockDomain()
self.cd_idelay = ClockDomain()
# # #
# Clk/Rst.
clk50 = platform.request("clk50")
rst = ~platform.request("cpu_reset") if with_rst else 0
# PLL.
self.pll = pll = S7PLL(speedgrade=-1)
self.comb += pll.reset.eq(rst | self.rst)
pll.register_clkin(clk50, 50e6)
pll.create_clkout(self.cd_sys, sys_clk_freq)
platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin) # Ignore sys_clk to pll.clkin path created by SoC's rst.
if with_dram:
pll.create_clkout(self.cd_sys4x, 4*sys_clk_freq)
pll.create_clkout(self.cd_sys4x_dqs, 4*sys_clk_freq, phase=90)
pll.create_clkout(self.cd_idelay, 200e6)
# IdelayCtrl.
if with_dram:
self.idelayctrl = S7IDELAYCTRL(self.cd_idelay)
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self, variant="a7-35", toolchain="vivado", sys_clk_freq=50e6,
with_xadc = False,
with_dna = False,
with_ethernet = False,
with_etherbone = False,
eth_ip = "192.168.1.50",
remote_ip = None,
eth_dynamic_ip = False,
with_led_chaser = True,
with_buttons = False,
with_beeper = True,
**kwargs):
platform = embedfire_rise_pro.Platform(variant=variant, toolchain=toolchain)
# CRG --------------------------------------------------------------------------------------
with_dram = (kwargs.get("integrated_main_ram_size", 0) == 0)
self.crg = _CRG(platform, sys_clk_freq, with_dram)
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq, ident="LiteX SoC on embedfire", **kwargs)
# XADC -------------------------------------------------------------------------------------
if with_xadc:
self.xadc = XADC()
# DNA --------------------------------------------------------------------------------------
if with_dna:
self.dna = DNA()
self.dna.add_timing_constraints(platform, sys_clk_freq, self.crg.cd_sys.clk)
# DDR3 SDRAM -------------------------------------------------------------------------------
if not self.integrated_main_ram_size:
self.ddrphy = s7ddrphy.A7DDRPHY(platform.request("ddram"),
memtype = "DDR3",
nphases = 4,
sys_clk_freq = sys_clk_freq)
self.add_sdram("sdram",
phy = self.ddrphy,
module = MT41K256M16(sys_clk_freq, "1:4"),
l2_cache_size = kwargs.get("l2_size", 8192)
)
# Ethernet / Etherbone ---------------------------------------------------------------------
if with_ethernet or with_etherbone:
self.ethphy = LiteEthPHYMII(
clock_pads = self.platform.request("eth_clocks"),
pads = self.platform.request("eth"))
if with_etherbone:
self.add_etherbone(phy=self.ethphy, ip_address=eth_ip, with_ethmac=with_ethernet)
elif with_ethernet:
self.add_ethernet(phy=self.ethphy, dynamic_ip=eth_dynamic_ip, local_ip=eth_ip, remote_ip=remote_ip)
# Leds -------------------------------------------------------------------------------------
if with_led_chaser:
self.leds = LedChaser(
pads = platform.request_all("user_led"),
sys_clk_freq = sys_clk_freq,
)
self.leds.add_pwm()
# Buttons ----------------------------------------------------------------------------------
if with_buttons:
self.buttons = GPIOIn(
pads = platform.request_all("user_btn"),
with_irq = self.irq.enabled
)
# Beeper------------------------------------------------------------------------------------
self.beeper = PWM(
pwm=platform.request("beeper", 0),
with_csr = True,
default_enable = False,
default_width = 0x800,
default_period = 0xfff,
)
self.fan_pwm = PWM(
pwm=platform.request("fan", 0),
with_csr = True,
default_enable = False,
default_width = 0x800,
default_period = 0xfff,
)
# Build --------------------------------------------------------------------------------------------
def main():
from litex.build.parser import LiteXArgumentParser
parser = LiteXArgumentParser(platform=embedfire_rise_pro.Platform, description="LiteX SoC on embedfire rise pro.")
parser.add_target_argument("--flash", action="store_true", help="Flash bitstream.")
parser.add_target_argument("--variant", default="a7-35", help="Board variant (a7-35 or a7-100 or a7-200).")
parser.add_target_argument("--sys-clk-freq", default=50e6, type=float, help="System clock frequency.")
parser.add_target_argument("--with-xadc", action="store_true", help="Enable 7-Series XADC.")
parser.add_target_argument("--with-dna", action="store_true", help="Enable 7-Series DNA.")
parser.add_target_argument("--with-ethernet", action="store_true", help="Enable Ethernet support.")
parser.add_target_argument("--with-etherbone", action="store_true", help="Enable Etherbone support.")
parser.add_target_argument("--eth-ip", default="192.168.1.50", help="Ethernet/Etherbone IP address.")
parser.add_target_argument("--remote-ip", default="192.168.1.100", help="Remote IP address of TFTP server.")
parser.add_target_argument("--eth-dynamic-ip", action="store_true", help="Enable dynamic Ethernet IP addresses setting.")
sdopts = parser.target_group.add_mutually_exclusive_group()
sdopts.add_argument("--with-spi-sdcard", action="store_true", help="Enable SPI-mode SDCard support.")
sdopts.add_argument("--with-sdcard", action="store_true", help="Enable SDCard support.")
args = parser.parse_args()
assert not (args.with_etherbone and args.eth_dynamic_ip)
soc = BaseSoC(
variant = args.variant,
toolchain = args.toolchain,
sys_clk_freq = args.sys_clk_freq,
with_xadc = args.with_xadc,
with_dna = args.with_dna,
with_ethernet = args.with_ethernet,
with_etherbone = args.with_etherbone,
eth_ip = args.eth_ip,
remote_ip = args.remote_ip,
eth_dynamic_ip = args.eth_dynamic_ip,
**parser.soc_argdict
)
if args.with_spi_sdcard:
soc.add_spi_sdcard()
if args.with_sdcard:
soc.add_sdcard()
builder = Builder(soc, **parser.builder_argdict)
if args.build:
builder.build(**parser.toolchain_argdict)
if args.load:
prog = soc.platform.create_programmer()
prog.load_bitstream(builder.get_bitstream_filename(mode="sram"))
if args.flash:
prog = soc.platform.create_programmer()
prog.flash(0, builder.get_bitstream_filename(mode="flash"))
if __name__ == "__main__":
main()