From e7cee80670217ea2f220f89df36cd15f8a0ec444 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Thu, 5 May 2022 17:36:22 +0200 Subject: [PATCH] tools/litex_gen: Rename to litex_periph_gen to make it more explicit (And also to prepare for litex_soc_gen). --- litex/tools/litex_gen.py | 215 -------------------------------- litex/tools/litex_periph_gen.py | 126 +++++++++++++++++++ 2 files changed, 126 insertions(+), 215 deletions(-) delete mode 100755 litex/tools/litex_gen.py create mode 100755 litex/tools/litex_periph_gen.py diff --git a/litex/tools/litex_gen.py b/litex/tools/litex_gen.py deleted file mode 100755 index 0ebb855e1..000000000 --- a/litex/tools/litex_gen.py +++ /dev/null @@ -1,215 +0,0 @@ -#!/usr/bin/env python3 - -# -# This file is part of LiteX. -# -# Copyright (c) 2020 Antmicro -# Copyright (c) 2020 Florent Kermarrec -# SPDX-License-Identifier: BSD-2-Clause - -import argparse - -from migen import * - -from litex.build.generic_platform import * - -from litex.soc.integration.soc_core import * -from litex.soc.integration.builder import * -from litex.soc.interconnect import wishbone -from litex.soc.interconnect import axi - -from litex.soc.cores.pwm import PWM -from litex.soc.cores.gpio import GPIOTristate -from litex.soc.cores.spi import SPIMaster, SPISlave -from litex.soc.cores.clock import S7MMCM - -# Platform ----------------------------------------------------------------------------------------- - -_io = [ - ("sys_clk", 0, Pins(1)), - ("sys_rst", 0, Pins(1)), -] - -# Platform ----------------------------------------------------------------------------------------- - -class Platform(GenericPlatform): - def __init__(self, io): - GenericPlatform.__init__(self, "", io) - - def build(self, fragment, build_dir, **kwargs): - os.makedirs(build_dir, exist_ok=True) - os.chdir(build_dir) - top_output = self.get_verilog(fragment) - top_output.write("litex_core.v") - -# LiteXCore ---------------------------------------------------------------------------------------- - -class LiteXCore(SoCMini): - SoCMini.mem_map["csr"] = 0x00000000 - def __init__(self, sys_clk_freq=int(100e6), - with_pwm = False, - with_mmcm = False, - with_gpio = False, gpio_width=32, - with_spi_master = False, spi_master_data_width=8, spi_master_clk_freq=8e6, - **kwargs): - - platform = Platform(_io) - - # UART - if kwargs["with_uart"]: - platform.add_extension([ - ("serial", 0, - Subsignal("tx", Pins(1)), - Subsignal("rx", Pins(1)), - ) - ]) - - # CRG -------------------------------------------------------------------------------------- - self.submodules.crg = CRG(platform.request("sys_clk"), rst=platform.request("sys_rst")) - - # SoCMini ---------------------------------------------------------------------------------- - print(kwargs) - SoCMini.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) - - # MMCM - if with_mmcm: - platform.add_extension([ - ("clkgen", 0, - Subsignal("ref", Pins(1)), - Subsignal("out0", Pins(1)), - Subsignal("out1", Pins(1)), - Subsignal("locked", Pins(1)), - ) - ]) - - self.clock_domains.cd_out0 = ClockDomain(reset_less=True) - self.clock_domains.cd_out1 = ClockDomain(reset_less=True) - self.submodules.mmcm = mmcm = S7MMCM() - mmcm.expose_drp() - self.add_csr("mmcm") - - clkgen = platform.request("clkgen") - - mmcm.register_clkin(clkgen.ref, 100e6) - mmcm.create_clkout(self.cd_out0, 148.5e6, with_reset=False) - mmcm.create_clkout(self.cd_out1, 742.5e6, with_reset=False) - - self.comb += [ - clkgen.out0.eq(self.cd_out0.clk), - clkgen.out1.eq(self.cd_out1.clk), - clkgen.locked.eq(mmcm.locked), - ] - - # SPI Master - if with_spi_master: - platform.add_extension([ - ("spi_master", 0, - Subsignal("clk", Pins(1)), - Subsignal("cs_n", Pins(1)), - Subsignal("mosi", Pins(1)), - Subsignal("miso", Pins(1)), - ) - ]) - self.submodules.spi_master = SPIMaster( - pads = platform.request("spi_master"), - data_width = spi_master_data_width, - sys_clk_freq = sys_clk_freq, - spi_clk_freq = spi_master_clk_freq, - ) - self.add_csr("spi_master") - - # PWM - if with_pwm: - platform.add_extension([("pwm", 0, Pins(1))]) - self.submodules.pwm = PWM(platform.request("pwm")) - self.add_csr("pwm") - - # GPIO - if with_gpio: - platform.add_extension([("gpio", 0, Pins(gpio_width))]) - self.submodules.gpio = GPIOTristate(platform.request("gpio")) - self.add_csr("gpio") - - # Wishbone Master - if kwargs["bus"] in ["wishbone"]: - wb_bus = wishbone.Interface() - self.bus.add_master(master=wb_bus) - platform.add_extension(wb_bus.get_ios("wb")) - wb_pads = platform.request("wb") - self.comb += wb_bus.connect_to_pads(wb_pads, mode="slave") - - # AXI-Lite Master - if kwargs["bus"] in ["axi", "axi_lite"]: - axi_bus = axi.AXILiteInterface(data_width=32, address_width=32) - wb_bus = wishbone.Interface() - axi2wb = axi.AXILite2Wishbone(axi_bus, wb_bus) - self.submodules += axi2wb - self.bus.add_master(master=wb_bus) - platform.add_extension(axi_bus.get_ios("axi")) - axi_pads = platform.request("axi") - self.comb += axi_bus.connect_to_pads(axi_pads, mode="slave") - - # IRQs - for name, loc in sorted(self.irq.locs.items()): - module = getattr(self, name) - platform.add_extension([("irq_"+name, 0, Pins(1))]) - irq_pin = platform.request("irq_"+name) - self.comb += irq_pin.eq(module.ev.irq) - -# Build ------------------------------------------------------------------------------------------- - -def soc_argdict(args): - ret = {} - for arg in [ - "bus", - "with_pwm", - "with_mmcm", - "with_uart", - "uart_fifo_depth", - "with_ctrl", - "with_timer", - "with_gpio", - "gpio_width", - "with_spi_master", - "spi_master_data_width", - "spi_master_clk_freq", - "csr_data_width", - "csr_address_width", - "csr_paging"]: - ret[arg] = getattr(args, arg) - return ret - -def main(): - parser = argparse.ArgumentParser(description="LiteX standalone core generator", formatter_class=argparse.ArgumentDefaultsHelpFormatter) - builder_args(parser) - - # Bus - parser.add_argument("--bus", default="wishbone", type=str, help="Bus Standard (wishbone, or axi-lite).") - - # Cores - parser.add_argument("--with-pwm", action="store_true", help="Add PWM core.") - parser.add_argument("--with-mmcm", action="store_true", help="Add MMCM (Xilinx 7-series) core.") - parser.add_argument("--with-uart", action="store_true", help="Add UART core.") - parser.add_argument("--uart-fifo-depth", default=16, type=int, help="UART FIFO depth.") - parser.add_argument("--with-ctrl", action="store_true", help="Add bus controller core.") - parser.add_argument("--with-timer", action="store_true", help="Add timer core.") - parser.add_argument("--with-spi-master", action="store_true", help="Add SPI master core.") - parser.add_argument("--spi-master-data-width", default=8, type=int, help="SPI master data width.") - parser.add_argument("--spi-master-clk-freq", default=8e6, type=int, help="SPI master output clock frequency.") - parser.add_argument("--with-gpio", action="store_true", help="Add GPIO core.") - parser.add_argument("--gpio-width", default=32, type=int, help="GPIO signals width.") - - # CSR settings - parser.add_argument("--csr-data-width", default=8, type=int, help="CSR bus data-width (8 or 32).") - parser.add_argument("--csr-address-width", default=14, type=int, help="CSR bus address-width.") - parser.add_argument("--csr-paging", default=0x800, type=int, help="CSR bus paging.") - - args = parser.parse_args() - - soc = LiteXCore(**soc_argdict(args)) - builder = Builder(soc, **builder_argdict(args)) - builder.build() - - -if __name__ == "__main__": - main() diff --git a/litex/tools/litex_periph_gen.py b/litex/tools/litex_periph_gen.py new file mode 100755 index 000000000..5e235ad21 --- /dev/null +++ b/litex/tools/litex_periph_gen.py @@ -0,0 +1,126 @@ +#!/usr/bin/env python3 + +# +# This file is part of LiteX. +# +# Copyright (c) 2022 Florent Kermarrec +# SPDX-License-Identifier: BSD-2-Clause + +""" +LiteX standalone SoC generator. + +This generator reduces the scope of LiteX to CPU/Peripherals selection/integration and to the creation +of SoC with MMAP/Streaming DMA interfaces that can be reintegrated in external designs (or LiteX SoC). +Think of it as a mini Nios SOPC Builder/ Zynq or Microblaze Subsystem generator that offers you the +possibility to reuse any of CPU supported by LiteX :) +""" + +import argparse + +from migen import * + +from litex.build.generic_platform import * + +from litex.soc.integration.soc_core import * +from litex.soc.integration.soc import SoCRegion +from litex.soc.integration.builder import * +from litex.soc.interconnect import wishbone +from litex.soc.interconnect import axi + +# IOs/Interfaces ----------------------------------------------------------------------------------- + +def get_common_ios(): + return [ + # Clk/Rst. + ("clk", 0, Pins(1)), + ("rst", 0, Pins(1)), + ] + +def get_uart_ios(): + return [ + # Serial + ("uart", 0, + Subsignal("tx", Pins(1)), + Subsignal("rx", Pins(1)), + ) + ] + +# Platform ----------------------------------------------------------------------------------------- + +class Platform(GenericPlatform): + def build(self, fragment, build_dir, build_name, **kwargs): + os.makedirs(build_dir, exist_ok=True) + os.chdir(build_dir) + conv_output = self.get_verilog(fragment, name=build_name) + conv_output.write(f"{build_name}.v") + +# LiteX SoC Generator ------------------------------------------------------------------------------ + +class LiteXSoCGenerator(SoCMini): + def __init__(self, name="litex_soc", sys_clk_freq=int(50e6), **kwargs): + # Platform --------------------------------------------------------------------------------- + platform = Platform(device="", io=get_common_ios()) + platform.name = name + platform.add_extension(get_uart_ios()) + + # CRG -------------------------------------------------------------------------------------- + self.submodules.crg = CRG( + clk = platform.request("clk"), + rst = platform.request("rst"), + ) + + # SoC -------------------------------------------------------------------------------------- + if kwargs["uart_name"] == "serial": + kwargs["uart_name"] = "uart" + SoCCore.__init__(self, platform, clk_freq=sys_clk_freq, **kwargs) + + # MMAP Slave Interface --------------------------------------------------------------------- + s_bus = { + "wishbone" : wishbone.Interface(), + "axi-lite" : axi.AXILiteInterface(), + + }[kwargs["bus_standard"]] + self.bus.add_master(name="mmap_s", master=s_bus) + platform.add_extension(s_bus.get_ios("mmap_s")) + wb_pads = platform.request("mmap_s") + self.comb += s_bus.connect_to_pads(wb_pads, mode="slave") + + # MMAP Master Interface -------------------------------------------------------------------- + # FIXME: Allow Region configuration. + m_bus = { + "wishbone" : wishbone.Interface(), + "axi-lite" : axi.AXILiteInterface(), + + }[kwargs["bus_standard"]] + wb_region = SoCRegion(origin=0x2000_0000, size=0x1000_0000, cached=True) # FIXME. + self.bus.add_slave(name="mmap_m", slave=m_bus, region=wb_region) + platform.add_extension(m_bus.get_ios("mmap_m")) + wb_pads = platform.request("mmap_m") + self.comb += m_bus.connect_to_pads(wb_pads, mode="master") + +# Build -------------------------------------------------------------------------------------------- +def main(): + # Arguments. + from litex.soc.integration.soc import LiteXSoCArgumentParser + parser = LiteXSoCArgumentParser(description="LiteX standalone SoC generator") + target_group = parser.add_argument_group(title="Generator options") + target_group.add_argument("--name", default="litex_soc", help="SoC Name.") + target_group.add_argument("--build", action="store_true", help="Build SoC.") + target_group.add_argument("--sys-clk-freq", default=int(50e6), help="System clock frequency.") + builder_args(parser) + soc_core_args(parser) + args = parser.parse_args() + + # SoC. + soc = LiteXSoCGenerator( + name = args.name, + sys_clk_freq = int(float(args.sys_clk_freq)), + **soc_core_argdict(args) + ) + + # Build. + builder = Builder(soc, **builder_argdict(args)) + builder.build(build_name=args.name, run=args.build) + +if __name__ == "__main__": + main()