tools: Add initial LiteX standalone SoC generator.
Allow generating standalone SoC with CPU/Peripherals that can be re-integrated in external design or top level LiteX SoCs. Example of of use: python3 litex_soc_gen.py --cpu-type=vexriscv --bus-standard=wishbone --build python3 litex_soc_gen.py --cpu-type=naxriscv --bus-standard=axi-lite --build
This commit is contained in:
parent
e7cee80670
commit
e8b6200225
|
@ -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