diff --git a/litex_boards/platforms/digilent_zedboard.py b/litex_boards/platforms/digilent_zedboard.py index 43d8c80..c2738ad 100644 --- a/litex_boards/platforms/digilent_zedboard.py +++ b/litex_boards/platforms/digilent_zedboard.py @@ -38,13 +38,6 @@ _io = [ ("user_btn_r", 0, Pins("R18"), IOStandard("LVCMOS25")), ("user_btn_u", 0, Pins("T18"), IOStandard("LVCMOS25")), - # Serial (ust to make CI pass) - # Unfortunately the only USB UART is hard-wired to the ARM CPU - ("serial", 0, - Subsignal("tx", Pins("-")), - Subsignal("rx", Pins("-")) - ), - # OLED (UG-2832HSWEG04/ssd1306) ("zed_oled", 0, Subsignal("clk", Pins("AB12")), @@ -213,6 +206,9 @@ class Platform(XilinxPlatform): def __init__(self): XilinxPlatform.__init__(self, "xc7z020clg484-1", _io, _connectors, 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 OpenOCD(config="board/digilent_zedboard.cfg") diff --git a/litex_boards/targets/digilent_zedboard.py b/litex_boards/targets/digilent_zedboard.py new file mode 100644 index 0000000..eba47c7 --- /dev/null +++ b/litex_boards/targets/digilent_zedboard.py @@ -0,0 +1,181 @@ +#!/usr/bin/env python3 + +# +# This file is part of LiteX-Boards. +# +# Copyright (c) 2021 Ilia Sergachev +# SPDX-License-Identifier: BSD-2-Clause + +import argparse + +from migen import * + +from litex_boards.platforms import digilent_zedboard +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 * +from litex.soc.cores.led import LedChaser + +# 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("ps7")) + self.comb += ResetSignal("sys").eq(ResetSignal("ps7") | 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): + def __init__(self, sys_clk_freq, with_led_chaser=True, **kwargs): + platform = digilent_zedboard.Platform() + + if kwargs.get("cpu_type", None) == "zynq7000": + kwargs['integrated_sram_size'] = 0 + + # SoCCore ---------------------------------------------------------------------------------- + SoCCore.__init__(self, platform, sys_clk_freq, + ident = "LiteX SoC on Zedboard", + ident_version = True, + **kwargs) + + # Zynq7000 Integration --------------------------------------------------------------------- + if kwargs.get("cpu_type", None) == "zynq7000": + self.cpu.set_ps7(name="Zynq", + preset="ZedBoard", + config={'PCW_FPGA0_PERIPHERAL_FREQMHZ': sys_clk_freq / 1e6}) + + # Connect AXI GP0 to the SoC + wb_gp0 = wishbone.Interface() + self.submodules += axi.AXI2Wishbone( + axi = self.cpu.add_axi_gp_master(), + wishbone = wb_gp0, + base_address = 0x43c0_0000) # default GP0 address on Zynq + self.add_wb_master(wb_gp0) + + # FIXME: collection of hacks to enable BIOS compilation + self.bus.add_region("sram", SoCRegion( + origin=128 * 1024 * 1024, + size=256 * 1024 * 1024) + ) + self.bus.add_region("rom", SoCRegion( + origin=256 * 1024 * 1024, + size=8 * 1024 * 1024, + linker=True) + ) + self.cpu.use_rom = True + self.constants['CONFIG_CLOCK_FREQUENCY'] = 666666687 + + use_ps7_clk = True + else: + use_ps7_clk = False + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = _CRG(platform, sys_clk_freq, use_ps7_clk) + + # Leds ------------------------------------------------------------------------------------- + if with_led_chaser: + self.submodules.leds = LedChaser( + pads = platform.request_all("user_led"), + sys_clk_freq = sys_clk_freq) + + def finalize(self, *args, **kwargs): + super(BaseSoC, self).finalize(*args, **kwargs) + if self.cpu_type != "zynq7000": + 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/cortexa9/xpseudo_asm.h', + 'lib/bsp/standalone/src/arm/cortexa9/xreg_cortexa9.h', + 'lib/bsp/standalone/src/arm/cortexa9/xil_cache.h', + 'lib/bsp/standalone/src/arm/cortexa9/xparameters_ps.h', + 'lib/bsp/standalone/src/arm/cortexa9/xil_errata.h', + 'lib/bsp/standalone/src/arm/cortexa9/xtime_l.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'), + '#define FPU_HARD_FLOAT_ABI_ENABLED 1') + write_to_file(os.path.join(self.builder.include_dir, 'xparameters.h'), ''' +#ifndef __XPARAMETERS_H +#define __XPARAMETERS_H + +#include "xparameters_ps.h" + +#define STDOUT_BASEADDRESS 0xE0001000 +#define XPAR_PS7_DDR_0_S_AXI_BASEADDR 0x00100000 +#define XPAR_PS7_DDR_0_S_AXI_HIGHADDR 0x3FFFFFFF + +#endif +''') + + +# Build -------------------------------------------------------------------------------------------- + + +def main(): + parser = argparse.ArgumentParser(description="LiteX SoC on Zedboard") + 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 (default: %(default)d)") + builder_args(parser) + soc_core_args(parser) + vivado_build_args(parser) + parser.set_defaults(cpu_type="zynq7000") + 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 == "zynq7000": + 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()