tools/litex_gen: Rename to litex_periph_gen to make it more explicit (And also to prepare for litex_soc_gen).
This commit is contained in:
parent
36ea82546f
commit
e7cee80670
|
@ -1,215 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
#
|
||||
# This file is part of LiteX.
|
||||
#
|
||||
# Copyright (c) 2020 Antmicro <www.antmicro.com>
|
||||
# Copyright (c) 2020 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||
# 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()
|
|
@ -0,0 +1,126 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
#
|
||||
# This file is part of LiteX.
|
||||
#
|
||||
# Copyright (c) 2022 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||
# 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()
|
Loading…
Reference in New Issue