Merge branch 'litex-hub:master' into master

This commit is contained in:
Sergiu Mosanu 2022-02-08 12:20:35 -05:00 committed by GitHub
commit 0d2336768d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 324 additions and 16 deletions

View File

@ -35,7 +35,7 @@ _io = [
("seven_seg", 2, Pins("AB23 AE29 AD29 AC28 AD30 AC29 AC30"), IOStandard("3.3-V LVTTL")),
("seven_seg", 3, Pins("AD26 AC27 AD25 AC25 AB28 AB25 AB22"), IOStandard("3.3-V LVTTL")),
("seven_seg", 4, Pins("AA24 Y23 Y24 W22 W24 V23 W25"), IOStandard("3.3-V LVTTL")),
("seven_seg", 5, Pins("V25 AA28 Y27 AB27 AB26 AA26 AA2"), IOStandard("3.3-V LVTTL")),
("seven_seg", 5, Pins("V25 AA28 Y27 AB27 AB26 AA26 AA25"), IOStandard("3.3-V LVTTL")),
# Button
("key", 0, Pins("AA14"), IOStandard("3.3-V LVTTL")),

View File

@ -200,14 +200,13 @@ _io = [
# HDMI
("hdmi", 0,
Subsignal("d", Pins(
"C11 A11 B11 A10 B10 C10 A8 B7",
"B8 A7 C8 C9 F11 E11 E10 D10",
"F10 F9 D9 D8 C7 F8 E8 D11")),
Subsignal("de", Pins("F14")),
Subsignal("clk", Pins("A9")),
Subsignal("vsync", Pins("E14")),
Subsignal("hsync", Pins("F13")),
Subsignal("r", Pins("F10 F9 D9 D8 C7 F8 E8 D11")),
Subsignal("g", Pins("B8 A7 C8 C9 F11 E11 E10 D10")),
Subsignal("b", Pins("C11 A11 B11 A10 B10 C10 A8 B7")),
Subsignal("de", Pins("F14")),
Subsignal("clk", Pins("A9")),
Subsignal("vsync_n", Pins("E14")),
Subsignal("hsync_n", Pins("F13")),
Subsignal("sda", Pins("D13")),
Subsignal("scl", Pins("C13")),
IOStandard("LVCMOS33")

View File

@ -0,0 +1,39 @@
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2022 Ilia Sergachev <ilia@sergachev.ch>
# SPDX-License-Identifier: BSD-2-Clause
from litex.build.generic_platform import *
from litex.build.xilinx import XilinxPlatform, VivadoProgrammer
# IOs ----------------------------------------------------------------------------------------------
_io = [
# Fan.
("fan", 0, Pins("A12"), IOStandard("LVCMOS33")),
# Seems like there are no on-board clock sources for PL when PS is not used so here a
# clock-capable PMOD connector pin is added as a possible clock input (not tested).
("pmod_hda16_cc", 0, Pins("B21"), IOStandard("LVCMOS33")),
]
# Platform -----------------------------------------------------------------------------------------
class Platform(XilinxPlatform):
default_clk_name = "pmod_hda16_cc"
default_clk_period = 1e9/100e6
def __init__(self):
XilinxPlatform.__init__(self, "xck26-sfvc784-2lv-c", _io, toolchain="vivado")
self.toolchain.bitstream_commands = \
["set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]", ]
self.default_clk_freq = 1e9 / self.default_clk_period
def create_programmer(self):
return VivadoProgrammer()
def do_finalize(self, fragment, *args, **kwargs):
XilinxPlatform.do_finalize(self, fragment, *args, **kwargs)
self.add_period_constraint(self.lookup_request("pmod_hda16_cc", loose=True), 1e9/100e6)

View File

@ -210,7 +210,7 @@ def main():
parser.add_argument("--toolchain", default="trellis", help="FPGA toolchain (trellis or diamond).")
parser.add_argument("--sys-clk-freq", default=48e6, help="System clock frequency.")
parser.add_argument("--revision", default="0.2", help="Board Revision (0.1 or 0.2).")
parser.add_argument("--device", default="25F", help="ECP5 device (25F or 45F).")
parser.add_argument("--device", default="25F", help="ECP5 device (25F, 45F or 85F).")
parser.add_argument("--sdram-device", default="MT41K64M16", help="SDRAM device (MT41K64M16, MT41K128M16, MT41K256M16 or MT41K512M16).")
parser.add_argument("--with-spi-sdcard", action="store_true", help="Enable SPI-mode SDCard support.")
builder_args(parser)

View File

@ -21,6 +21,8 @@ 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 GPIOTristate
from litex.soc.cores.video import VideoDVIPHY
from litex.soc.cores.bitbang import I2CMaster
from litedram.modules import MT41J256M16
from litedram.phy import ECP5DDRPHY
@ -112,8 +114,13 @@ class _CRGSDRAM(Module):
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
def __init__(self, sys_clk_freq=int(75e6), toolchain="trellis", with_ethernet=False,
with_led_chaser=True, with_pmod_gpio=False, **kwargs):
def __init__(self, sys_clk_freq=int(75e6), toolchain="trellis",
with_ethernet = False,
with_video_terminal = False,
with_video_framebuffer = False,
with_led_chaser = True,
with_pmod_gpio = False,
**kwargs):
platform = trellisboard.Platform(toolchain=toolchain)
# SoCCore ----------------------------------------------------------------------------------
@ -145,6 +152,22 @@ class BaseSoC(SoCCore):
pads = self.platform.request("eth"))
self.add_ethernet(phy=self.ethphy)
# HDMI -------------------------------------------------------------------------------------
if with_video_terminal or with_video_framebuffer:
# PHY + TP410 I2C initialization.
hdmi_pads = platform.request("hdmi")
self.submodules.videophy = VideoDVIPHY(hdmi_pads, clock_domain="init")
self.submodules.videoi2c = I2CMaster(hdmi_pads)
self.videoi2c.add_init(addr=0x38, init=[
(0x08, 0x35) # CTL_1_MODE: Normal operation, 24-bit, HSYNC/VSYNC.
])
# Video Terminal/Framebuffer.
if with_video_terminal:
self.add_video_terminal(phy=self.videophy, timings="640x480@75Hz", clock_domain="init")
if with_video_framebuffer:
self.add_video_framebuffer(phy=self.videophy, timings="640x480@75Hz", clock_domain="init")
# Leds -------------------------------------------------------------------------------------
if with_led_chaser:
self.submodules.leds = LedChaser(
@ -165,19 +188,24 @@ def main():
parser.add_argument("--toolchain", default="trellis", help="FPGA toolchain (trellis or diamond).")
parser.add_argument("--sys-clk-freq", default=75e6, help="System clock frequency.")
parser.add_argument("--with-ethernet", action="store_true", help="Enable Ethernet support.")
viopts = parser.add_mutually_exclusive_group()
viopts.add_argument("--with-video-terminal", action="store_true", help="Enable Video Terminal (HDMI).")
viopts.add_argument("--with-video-framebuffer", action="store_true", help="Enable Video Framebuffer (HDMI).")
sdopts = parser.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.")
parser.add_argument("--with-pmod-gpio", action="store_true", help="Enable GPIOs through PMOD.") # FIXME: Temporary test.
parser.add_argument("--with-pmod-gpio", action="store_true", help="Enable GPIOs through PMOD.") # FIXME: Temporary test.
builder_args(parser)
soc_core_args(parser)
trellis_args(parser)
args = parser.parse_args()
soc = BaseSoC(
sys_clk_freq = int(float(args.sys_clk_freq)),
with_ethernet = args.with_ethernet,
with_pmod_gpio = args.with_pmod_gpio,
sys_clk_freq = int(float(args.sys_clk_freq)),
with_ethernet = args.with_ethernet,
with_video_terminal = args.with_video_terminal,
with_video_framebuffer = args.with_video_framebuffer,
with_pmod_gpio = args.with_pmod_gpio,
**soc_core_argdict(args)
)
if args.with_spi_sdcard:

View File

@ -0,0 +1,242 @@
#!/usr/bin/env python3
#
# This file is part of LiteX-Boards.
#
# Copyright (c) 2022 Ilia Sergachev <ilia@sergachev.ch>
# SPDX-License-Identifier: BSD-2-Clause
# Build/Use:
# The current support is sufficient to run LiteX BIOS on Cortex-A53 core #0:
# ./xilinx_kv260.py --build --load
# LiteX BIOS can then be executed on hardware using JTAG with the following xsct script from:
# https://github.com/sergachev/litex-template/tree/kv260
# make -f Makefile.kv260 load will build everything and run xsct in the end.
#
# Relies on https://github.com/lucaceresoli/zynqmp-pmufw-builder to create a generic PMU firmware;
# first build will take a while because it includes a cross-toolchain.
import argparse
from migen import *
from litex_boards.platforms import xilinx_kv260
from litex.build.xilinx.vivado import vivado_build_args, vivado_build_argdict
from litex.build.tools import write_to_file
from litex.soc.interconnect import axi
from litex.soc.interconnect import wishbone
from litex.soc.cores.clock import *
from litex.soc.integration.soc_core import *
from litex.soc.integration.soc import SoCRegion
from litex.soc.integration.builder import *
# CRG ----------------------------------------------------------------------------------------------
class _CRG(Module):
def __init__(self, platform, sys_clk_freq, use_ps7_clk=False):
self.rst = Signal()
self.clock_domains.cd_sys = ClockDomain()
# # #
if use_ps7_clk:
self.comb += ClockSignal("sys").eq(ClockSignal("ps"))
self.comb += ResetSignal("sys").eq(ResetSignal("ps") | self.rst)
else:
self.submodules.pll = pll = S7PLL(speedgrade=-1)
self.comb += pll.reset.eq(self.rst)
pll.register_clkin(platform.request(platform.default_clk_name), platform.default_clk_freq)
pll.create_clkout(self.cd_sys, sys_clk_freq)
# Ignore sys_clk to pll.clkin path created by SoC's rst.
platform.add_false_path_constraints(self.cd_sys.clk, pll.clkin)
# BaseSoC ------------------------------------------------------------------------------------------
class BaseSoC(SoCCore):
mem_map = {"csr": 0xA000_0000} # default GP0 address on ZynqMP
def __init__(self, sys_clk_freq, **kwargs):
platform = xilinx_kv260.Platform()
if kwargs.get("cpu_type", None) == "zynqmp":
kwargs['integrated_sram_size'] = 0
# SoCCore ----------------------------------------------------------------------------------
SoCCore.__init__(self, platform, sys_clk_freq,
ident = "LiteX SoC on KV260",
**kwargs)
# ZynqMP Integration -----------------------------------------------------------------------
if kwargs.get("cpu_type", None) == "zynqmp":
self.cpu.config.update({
'PSU_MIO_36_DIRECTION': 'out',
'PSU_MIO_37_DIRECTION': 'in',
'PSU__UART1__BAUD_RATE': 115200,
'PSU__CRL_APB__UART1_REF_CTRL__DIVISOR0': 10,
})
# generated from board xml presets
self.cpu.config.update({
'PSU__CRF_APB__ACPU_CTRL__FREQMHZ': '1333.333',
'PSU__DDRC__BANK_ADDR_COUNT': '2',
'PSU__DDRC__BG_ADDR_COUNT': '1',
'PSU__DDRC__BRC_MAPPING': 'ROW_BANK_COL',
'PSU__DDRC__BUS_WIDTH': '64 Bit',
'PSU__DDRC__CL': '16',
'PSU__DDRC__CLOCK_STOP_EN': '0',
'PSU__DDRC__COL_ADDR_COUNT': '10',
'PSU__DDRC__COMPONENTS': 'Components',
'PSU__DDRC__CWL': '12',
'PSU__DDRC__DDR4_ADDR_MAPPING': '0',
'PSU__DDRC__DDR4_CAL_MODE_ENABLE': '0',
'PSU__DDRC__DDR4_CRC_CONTROL': '0',
'PSU__DDRC__DDR4_T_REF_MODE': '0',
'PSU__DDRC__DDR4_T_REF_RANGE': 'Normal (0-85)',
'PSU__DDRC__DEVICE_CAPACITY': '8192 MBits',
'PSU__DDRC__DIMM_ADDR_MIRROR': '0',
'PSU__DDRC__DM_DBI': 'DM_NO_DBI',
'PSU__DDRC__DRAM_WIDTH': '16 Bits',
'PSU__DDRC__ECC': 'Disabled',
'PSU__DDRC__FGRM': '1X',
'PSU__DDRC__LP_ASR': 'manual normal',
'PSU__DDRC__MEMORY_TYPE': 'DDR 4',
'PSU__DDRC__PARITY_ENABLE': '0',
'PSU__DDRC__PER_BANK_REFRESH': '0',
'PSU__DDRC__PHY_DBI_MODE': '0',
'PSU__DDRC__RANK_ADDR_COUNT': '0',
'PSU__DDRC__ROW_ADDR_COUNT': '16',
'PSU__DDRC__SELF_REF_ABORT': '0',
'PSU__DDRC__SPEED_BIN': 'DDR4_2400R',
'PSU__DDRC__STATIC_RD_MODE': '0',
'PSU__DDRC__TRAIN_DATA_EYE': '1',
'PSU__DDRC__TRAIN_READ_GATE': '1',
'PSU__DDRC__TRAIN_WRITE_LEVEL': '1',
'PSU__DDRC__T_FAW': '30.0',
'PSU__DDRC__T_RAS_MIN': '33',
'PSU__DDRC__T_RC': '47.06',
'PSU__DDRC__T_RCD': '16',
'PSU__DDRC__T_RP': '16',
'PSU__DDRC__VREF': '1',
'PSU__FPGA_PL0_ENABLE': '1',
'PSU__PMU__GPO4__ENABLE': '0', # these 2 are disabled for uart1
'PSU__PMU__GPO5__ENABLE': '0',
'PSU__UART1__PERIPHERAL__ENABLE': '1',
'PSU__UART1__PERIPHERAL__IO': 'MIO 36 .. 37',
})
# Connect Zynq AXI master to the SoC
wb_gp0 = wishbone.Interface()
self.submodules += axi.AXI2Wishbone(
axi = self.cpu.add_axi_gp_master(),
wishbone = wb_gp0,
base_address = self.mem_map["csr"])
self.add_wb_master(wb_gp0)
self.bus.add_region("sram", SoCRegion(
origin=self.cpu.mem_map["sram"],
size=2 * 1024 * 1024 * 1024) # DDR
)
self.bus.add_region("rom", SoCRegion(
origin=self.cpu.mem_map["rom"],
size=512 * 1024 * 1024 // 8,
linker=True)
)
self.constants['CONFIG_CLOCK_FREQUENCY'] = 1333333008
use_ps7_clk = True
else:
use_ps7_clk = False
# CRG --------------------------------------------------------------------------------------
self.submodules.crg = _CRG(platform, sys_clk_freq, use_ps7_clk)
def finalize(self, *args, **kwargs):
super(BaseSoC, self).finalize(*args, **kwargs)
if self.cpu_type != "zynqmp":
return
libxil_path = os.path.join(self.builder.software_dir, 'libxil')
os.makedirs(os.path.realpath(libxil_path), exist_ok=True)
lib = os.path.join(libxil_path, 'embeddedsw')
if not os.path.exists(lib):
os.system("git clone --depth 1 https://github.com/Xilinx/embeddedsw {}".format(lib))
os.makedirs(os.path.realpath(self.builder.include_dir), exist_ok=True)
for header in [
'XilinxProcessorIPLib/drivers/uartps/src/xuartps_hw.h',
'lib/bsp/standalone/src/common/xil_types.h',
'lib/bsp/standalone/src/common/xil_assert.h',
'lib/bsp/standalone/src/common/xil_io.h',
'lib/bsp/standalone/src/common/xil_printf.h',
'lib/bsp/standalone/src/common/xstatus.h',
'lib/bsp/standalone/src/common/xdebug.h',
'lib/bsp/standalone/src/arm/ARMv8/64bit/xpseudo_asm.h',
'lib/bsp/standalone/src/arm/ARMv8/64bit/xreg_cortexa53.h',
'lib/bsp/standalone/src/arm/ARMv8/64bit/xil_cache.h',
'lib/bsp/standalone/src/arm/ARMv8/64bit/xil_errata.h',
'lib/bsp/standalone/src/arm/ARMv8/64bit/platform/ZynqMP/xparameters_ps.h',
'lib/bsp/standalone/src/arm/common/xil_exception.h',
'lib/bsp/standalone/src/arm/common/gcc/xpseudo_asm_gcc.h',
]:
shutil.copy(os.path.join(lib, header), self.builder.include_dir)
write_to_file(os.path.join(self.builder.include_dir, 'bspconfig.h'), """
#ifndef BSPCONFIG_H
#define BSPCONFIG_H
#define EL3 1
#define EL1_NONSECURE 0
#endif
""")
write_to_file(os.path.join(self.builder.include_dir, 'xparameters.h'), '''
#ifndef XPARAMETERS_H
#define XPARAMETERS_H
#include "xparameters_ps.h"
#define STDIN_BASEADDRESS 0xFF010000
#define STDOUT_BASEADDRESS 0xFF010000
#define XPAR_PSU_DDR_0_S_AXI_BASEADDR 0x00000000
#define XPAR_PSU_DDR_0_S_AXI_HIGHADDR 0x7FFFFFFF
#define XPAR_PSU_DDR_1_S_AXI_BASEADDR 0x800000000
#define XPAR_PSU_DDR_1_S_AXI_HIGHADDR 0x87FFFFFFF
#define XPAR_CPU_CORTEXA53_0_TIMESTAMP_CLK_FREQ 99999001
#endif
''')
# Build --------------------------------------------------------------------------------------------
def main():
parser = argparse.ArgumentParser(description="LiteX SoC on KV260")
parser.add_argument("--build", action="store_true", help="Build bitstream.")
parser.add_argument("--load", action="store_true", help="Load bitstream.")
parser.add_argument("--sys-clk-freq", default=100e6, help="System clock frequency.")
builder_args(parser)
soc_core_args(parser)
vivado_build_args(parser)
parser.set_defaults(cpu_type="zynqmp")
parser.set_defaults(no_uart=True)
args = parser.parse_args()
soc = BaseSoC(
sys_clk_freq=int(float(args.sys_clk_freq)),
**soc_core_argdict(args)
)
builder = Builder(soc, **builder_argdict(args))
if args.cpu_type == "zynqmp":
soc.builder = builder
builder.add_software_package('libxil')
builder.add_software_library('libxil')
builder.build(**vivado_build_argdict(args), run=args.build)
if args.load:
prog = soc.platform.create_programmer()
prog.load_bitstream(os.path.join(builder.gateware_dir, soc.build_name + ".bit"))
if __name__ == "__main__":
main()