Merge branch 'master' into naxriscv-merge

This commit is contained in:
Dolu1990 2022-09-12 19:18:12 +02:00
commit 8e7fd9bc1f
29 changed files with 587 additions and 242 deletions

112
CHANGES
View file

@ -1,51 +1,97 @@
[> Changes since 2022.04
[> Changes since 2022.08
------------------------
[> Issues resolved
------------------
[> Added Features
-----------------
[> API changes/Deprecation
--------------------------
[> 2022.08, released on September 12th 2022
-------------------------------------------
[> Issues resolved
------------------
- cpu/vexriscv: Fix compilation with new binutils.
- soc/LiteXSocArgumentParser: Fix --cpu-type parsing.
- litex_sim: Fix --with-ethernet.
- liblitesdcard: Fix SDCard initialization corner cases.
- liblitedram: Enable sdram_init/mr_write for SDRAM.
- export/get_memory_x: Replace SPIFlash with ROM.
- soc/cores/video: Fix operation with some monitors (set data to 0 during blanking).
- tools/remote/comm_usb: Fix multi-word reads/writes.
- build/lattice/oxide: Fix ES posfix on device name.
- interconnect/axi: Fix AXIArbiter corner case.
- litex_server/client: Fix remapping over CommPCIe.
- LitePCIe: Fix LiteUART support with multi-boards.
[> Added Features
[> Added Features
-----------------
- litex_setup: Add -tag support for install/update.
- tools: Add initial LiteX standalone SoC generator.
- cores/ram: Add Xilinx's FIFO_SYNC_MACRO equivalent.
- LitePCIe: Always use 24-bit depth fields on LitePCIeBuffering to simplify software.
- gen/fhdl: Integrate Migen namer to give us more flexibility.
- fhdl/memory: Prefix memory files with build name to simplify reuse/integration.
- cpu/rocket: Add more variants.
- cores/video: Enable driving both + and - diff outs to compensate hardware issues.
- build: Add intial OSFPGA Foedag/Raptor build backend.
- cpu/cva5: Add initial CVA5 CPU support (ex Taiga).
- LiteSATA: Add IRQ and Identify support.
- clock/intel: Improve to find the best PLL config.
- cpu/cva6: Add initial CVA6 CPU support (ex Ariane).
- bios: Improve config flags.
- tools: Add I2s/MMCM support to litex_json2dts_zephyr.
- clock/gowin: Add GW2A support.
- bios: Disable LTO (does not work in all cases, needs to be investigated).
- CI: Test more RISC-V CPUs and OpenRisc CPUs in CI.
- bios: Add CONFIG_NO_BOOT to allow disabling boot sequence.
- export: Allow disabling CSR_BASE define in csr.h.
- build/openocd: Update for compatibility with upstream OpenOCD.
- cpu/openc906: Add initial OpenC906 support (open version of the Allwinner's D1 chip).
- soc: Add automatic bridging between AXI <-> AXI-Lite <-> Wishbone.
- soc: Add AXI-Full bus support.
- interconnect: Add AXI DownConverted and Interconnect/Crossbar.
- interconnect: Create axi directory and split code.
- soc: Modify SoC finalization order for more flexibility.
- soc: Add --bus-interconnect parameter to select interconect: shared/crossbar.
- valentyusb: Package and install it with LiteX.
- bios/mem_list: Align Mem Regions.
- litex_setup: Add -tag support for install/update.
- tools: Add initial LiteX standalone SoC generator.
- cores/ram: Add Xilinx's FIFO_SYNC_MACRO equivalent.
- LitePCIe: Always use 24-bit depth fields on LitePCIeBuffering to simplify software.
- gen/fhdl: Integrate Migen namer to give us more flexibility.
- fhdl/memory: Prefix memory files with build name to simplify reuse/integration.
- cpu/rocket: Add more variants.
- cores/video: Enable driving both + and - diff outs to compensate hardware issues.
- build: Add intial OSFPGA Foedag/Raptor build backend.
- cpu/cva5: Add initial CVA5 CPU support (ex Taiga).
- LiteSATA: Add IRQ and Identify support.
- clock/intel: Improve to find the best PLL config.
- cpu/cva6: Add initial CVA6 CPU support (ex Ariane).
- bios: Improve config flags.
- tools: Add I2s/MMCM support to litex_json2dts_zephyr.
- clock/gowin: Add GW2A support.
- bios: Disable LTO (does not work in all cases, needs to be investigated).
- CI: Test more RISC-V CPUs and OpenRisc CPUs in CI.
- bios: Add CONFIG_NO_BOOT to allow disabling boot sequence.
- export: Allow disabling CSR_BASE define in csr.h.
- build/openocd: Update for compatibility with upstream OpenOCD.
- cpu/openc906: Add initial OpenC906 support (open version of the Allwinner's D1 chip).
- soc: Add automatic bridging between AXI <-> AXI-Lite <-> Wishbone.
- soc: Add AXI-Full bus support.
- interconnect: Add AXI DownConverted and Interconnect/Crossbar.
- interconnect: Create axi directory and split code.
- soc: Modify SoC finalization order for more flexibility.
- soc: Add --bus-interconnect parameter to select interconect: shared/crossbar.
- valentyusb: Package and install it with LiteX.
- bios/mem_list: Align Mem Regions.
- build: Introduce GenericToolchain to cleanup/simplify build backends.
- soc/etherbone: Expose broadcast capability.
- build/lattice: Add MCLK frequency support.
- cpu/cva6: Add IRQ support.
- cores/clock: Add manual placement support to ECP5PLL.
- cores/leds: Add polarity support.
- cpu/neorv32: Switch to new NeoRV32 LiteX Core Complex and add variants support.
- cores/gpio: Add optional reset value.
- litex_client: Add --host support for remote operation.
- sim/verilator: Add jobs number support (to limit RAM usage with large SoCs/CPUs).
- soc/SocBusHandler Add get_address_width method to simplify peripheral integration.
- bios: Expose BIOS console parameters (to enable/disable history/autocomplete).
- bios: Expose BIOS LTO configuration.
- litex_json2renode: Update.
- build: Introduce YosysNextPNRToolchain to cleanup/simplify Yosys support.
- bios: Add buttons support/command.
- litex_client: Add XADC/Identifier/Leds/Buttons support to GUI.
- cpu/NaxRiscv: Update.
- build/generic_platofrm: Add add_connector methode to allow extending connectors.
- litex_server/client: Add initial information exchange between server/client.
- LitePCIe: Improve 64-bit support.
- interconnect/axi: Add missing optional signals.
- interconnect/wishbone: Improve DownConverter efficiency.
[> API changes/Deprecation
[> API changes/Deprecation
--------------------------
- LiteX-Boards : Remove short import support on platforms/targets.
- tools: Rename litex_gen to litex_periph_gen.
- LiteX-Boards: Only generate SoC/Software headers when --build is set
- Symbiflow: Rename to F4PGA.
- mkmsscimg: Rename to crcfbigen.
[> 2022.04, released on May 3th 2022
------------------------------------

View file

@ -10,40 +10,46 @@ and we'll fix it!
Contributors:
Copyright (c) 2021 Acathla-fr <fabien@acathla.tk>
Copyright (c) 2011-2012 Alain Péteut <alain.peteut@yahoo.com>
Copyright (c) 2011-2015 Alain Péteut <alain.peteut@yahoo.com>
Copyright (c) 2019 Ambroz Bizjak <ambrop7@gmail.com>
Copyright (c) 2021 Andreas Galauner <andreas@galauner.de>
Copyright (c) 2021-2022 Andrew Dennison <andrew.dennison@motec.com.au>
Copyright (c) 2021 Andwer E Wilson <lavatech.co@gmail.com>
Copyright (c) 2021 Andy Kitchen <kitchen.andy+git@gmail.com>
Copyright (c) 2018-2022 Antmicro <Antmicro.com>
Copyright (c) 2019 Antony Pavlov <antonynpavlov@gmail.com>
Copyright (c) 2019 Antti Lukats <Antti.Lukats@googlemail.com>
Copyright (c) 2018-2021 Antmicro <www.antmicro.com>
Copyright (c) 2019-2020 Arnaud Durand <arnaud.durand@unifr.ch>
Copyright (c) 2019 atommann <atommann@gmail.com>
Copyright (c) 2022 Bastian Löher <b.loeher@gsi.de>
Copyright (c) 2022 Ben Stobbs <ben@stobbs.com>
Copyright (c) 2021 Benjamin Henrion <zoobab@gmail.com>
Copyright (c) 2019-2020 Benjamin Herrenschmidt <benh@kernel.crashing.org>
Copyright (c) 2022 Ben Stobbs <ben@stobbs.com>
Copyright (c) 2021 Blake Smith <blakesmith0@gmail.com>
Copyright (c) 2012-2013 Brandon Hamilton <brandon.hamilton@gmail.com>
Copyright (c) 2022 Brian Swetland <swetland@frotz.net>
Copyright (c) 2017-2021 bunnie <bunnie@kosagi.com>
Copyright (c) 2019 Caleb Jamison <cbjamo@gmail.com>
Copyright (c) 2021 Camilo Andres Vera Ruiz <camilovera9811@gmail.com>
Copyright (c) 2021-2022 Charles-Henri Mousset <ch.mousset@gmail.com>
Copyright (c) 2019 chmousset <ch.mousset@gmail.com>
Copyright (c) 2018 Chris Ballance <chris.ballance@physics.ox.ac.uk>
Copyright (c) 2021 Chris Osterwood <osterwood@capablerobot.com>
Copyright (c) 2020-2022 Christian Klarhorst <cklarhor@techfak.uni-bielefeld.de>
Copyright (c) 2021 Dan Callaghan <dcallagh@google.com>
Copyright (c) 2022 curliph <curliph@gmail.com>
Copyright (c) 2019 Daniel Kucera <daniel.kucera@gmail.com>
Copyright (c) 2020 Dave Marples <dave@marples.net>
Copyright (c) 2013 David Carne <davidcarne@gmail.com>
Copyright (c) 2020 davidcorrigan714 <davidcorrigan714@gmail.com>
Copyright (c) 2020-2021 David Jablonski <dayjaby@gmail.com>
Copyright (c) 2020-2021 David Lattimore <dml@chromium.org>
Copyright (c) 2022 David Lobato <dav.lobato@gmail.com>
Copyright (c) 2020-2022 David Sawatzke <d-git@sawatzke.dev>
Copyright (c) 2018-2020 David Shah <dave@ds0.me>
Copyright (c) 2020 davidcorrigan714 <davidcorrigan714@gmail.com>
Copyright (c) 2018 Deano Calver <me@deanoc.com>
Copyright (c) 2021-2022 developandplay <34752929+developandplay@users.noreply.github.com>
Copyright (c) 2018-2022 Dolu1990 <charles.papon.90@gmail.com>
Copyright (c) 2022 Eric Matthews <ematthew@sfu.ca>
Copyright (c) 2021 Evan Lojewski <github@meklort.com>
Copyright (c) 2018 Ewen McNeill <ewen@naos.co.nz>
Copyright (c) 2014 Fabien Marteau <fabien.marteau@armadeus.com>
@ -53,10 +59,10 @@ Copyright (c) 2017-2018 Felix Held <felix-github@felixheld.de>
Copyright (c) 2020 Filipe Laíns <lains@archlinux.org>
Copyright (c) 2012-2022 Florent Kermarrec <florent@enjoy-digital.fr>
Copyright (c) 2019 Francis Lam <flam@alum.mit.edu>
Copyright (c) 2022-2021 Franck Jullien <franck.jullien@collshade.fr>
Copyright (c) 2020-2022 Franck Jullien <franck.jullien@collshade.fr>
Copyright (c) 2019-2022 Gabriel L. Somlo <gsomlo@gmail.com>
Copyright (c) 2021 Gary Wong <gtw@gnu.org>
Copyright (c) 2018-2021 Gatecat <gatecat@ds0.me>
Copyright (c) 2018-2022 gatecat <gatecat@ds0.me>
Copyright (c) 2020-2021 Geert Uytterhoeven <geert@linux-m68k.org>
Copyright (c) 2021 George Hilliard <thirtythreeforty@gmail.com>
Copyright (c) 2019 Giammarco Zacheo <g.zacheo@gmail.com>
@ -64,7 +70,7 @@ Copyright (c) 2021-2022 Google <Google.com>
Copyright (c) 2017 Greg Darke <greg@tsukasa.net.au>
Copyright (c) 2020-2022 Greg Davill <greg.davill@gmail.com>
Copyright (c) 2021 Guillaume REMBERT <zguig52@gmail.com>
Copyright (c) 2015-2014 Guy Hutchison <ghutchis@gmail.com>
Copyright (c) 2014-2015 Guy Hutchison <ghutchis@gmail.com>
Copyright (c) 2020-2022 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
Copyright (c) 2021 Hans Baier <hansfbaier@gmail.com>
Copyright (c) 2022 Icenowy Zheng <icenowy@aosc.io>
@ -74,11 +80,12 @@ Copyright (c) 2021 Jakub Piecuch <j.piecuch96@gmail.com>
Copyright (c) 2021 Jan Luebbe <jlu@pengutronix.de>
Copyright (c) 2014 Jannis Harder <jix@jixco.de>
Copyright (c) 2018 Jean-François Nguyen <jf@lambdaconcept.com>
Copyright (c) 2020 Jędrzej Boczar <yendreij@gmail.com>
Copyright (c) 2022 Jevin Sweval <jevinsweval@gmail.com>
Copyright (c) 2015 Joe Britton <joe.britton@gmail.com>
Copyright (c) 2017 Joel Addison <joel@addison.net.au>
Copyright (c) 2020-2022 Joel Stanley <joel@jms.id.au>
Copyright (c) 2022 Johannes Rudolph <johannes.rudolph@gmail.com>
Copyright (c) 2020 Jędrzej Boczar <yendreij@gmail.com>
Copyright (c) 2019 Kees Jongenburger <kees.jongenburger@gmail.com>
Copyright (c) 2013 Kenneth Ryerson <kryerson@vermeer.com>
Copyright (c) 2020 kessam <61152217+kessam@users.noreply.github.com>
@ -87,22 +94,26 @@ Copyright (c) 2021 Konstantin <buecheko@protonmail.com>
Copyright (c) 2019 Kurt Kiefer <kekiefer@gmail.com>
Copyright (c) 2019 Larry Doolittle <ldoolitt@recycle.lbl.gov>
Copyright (c) 2012-2013 Lars-Peter Clausen <lars@metafoo.de>
Copyright (c) 2020-2021 Leon Schuermann <leon@is.currently.online>
Copyright (c) 2020-2022 Leon Schuermann <leon@is.currently.online>
Copyright (c) 2022 Marcus Comstedt <marcus@mc.pp.se>
Copyright (c) 2021 Marek Czerski <m.czerski@ap-tech.pl>
Copyright (c) 2021 Marek Materzok <tilk@tilk.eu>
Copyright (c) 2019 Martin Cornil <martin.cornil@railnova.eu>
Copyright (c) 2022 Massimiliano Giacometti <massimiliano.giacometti@planv.tech>
Copyright (c) 2021 Matt Johnston <matt@codeconstruct.com.au>
Copyright (c) 2017 Matt Kelly <Matthew.Joseph.Kelly@gmail.com>
Copyright (c) 2019-2022 Michael Betz <michibetz@gmail.com>
Copyright (c) 2012 Michael Walle <michael@walle.cc>
Copyright (c) 2022 Mikolaj Sowinski <mikolaj.sowinski@gmail.com>
Copyright (c) 2021-2022 Mikołaj Sowiński <msowinski@technosystem.com.pl>
Copyright (c) 2019-2021 Miodrag Milanovic <mmicko@gmail.com>
Copyright (c) 2019 msloniewski <marcin.sloniewski@gmail.com>
Copyright (c) 2021 Nathaniel R. Lewis <linux.robotdude@gmail.com>
Copyright (c) 2021 Navaneeth <navan93@gmail.com>
Copyright (c) 2021 Navaneeth Bhardwaj <navan93@gmail.com>
Copyright (c) 2021 Nick Østergaard <oe.nick@gmail.com>
Copyright (c) 2013 Nina Engelhardt <nakengelhardt@gmail.com>
Copyright (c) 2015 Numato <sales@numato.com>
Copyright (c) 2015 numato <sales@numato.com>
Copyright (c) 2021 Nick Østergaard <oe.nick@gmail.com>
Copyright (c) 2020 Owen Kirby <oskirby@gmail.com>
Copyright (c) 2015 Olof Kindgren <olof.kindgren@gmail.com>
@ -111,27 +122,28 @@ Copyright (c) 2021 Paul Mackerras <paulus@ozlabs.org>
Copyright (c) 2020 Paul Sajna <sajattack@gmail.com>
Copyright (c) 2018 Paul Schulz <paul@mawsonlakes.org>
Copyright (c) 2020 Pepijn de Vos <pepijndevos@gmail.com>
Copyright (c) 2018 Phlipped <phlipped@gmail.com>
Copyright (c) 2018 phlipped <phlipped@gmail.com>
Copyright (c) 2020 Piense <piense@gmail.com>
Copyright (c) 2017 Pierre-Olivier Vauboin <po@lambdaconcept>
Copyright (c) 2020 Piotr Esden-Tempski <piotr@esden.net>
Copyright (c) 2015 Psmears <patrick@smears.org>
Copyright (c) 2015 psmears <patrick@smears.org>
Copyright (c) 2020 Rangel Ivanov <rangelivanov88@gmail.com>
Copyright (c) 2021-2022 RapidSilicon <RapidSilicon.com>
Copyright (c) 2020-2021 Raptor Engineering Development Team <support@raptorengineering.com>
Copyright (c) 2021 Ray Molenkamp <github@lazydodo.com>
Copyright (c) 2020 rob-ng15 <58272847+rob-ng15@users.noreply.github.com>
Copyright (c) 2013-2016 Robert Jordens <jordens@gmail.com>
Copyright (c) 2013 Robert Jördens <jordens@gmail.com>
Copyright (c) 2021 Robert Wilbrandt <robert@stamm-wilbrandt.de>
Copyright (c) 2020 rob-ng15 <58272847+rob-ng15@users.noreply.github.com>
Copyright (c) 2015 Rohit Kumar Singh <rohit91.2008@gmail.com>
Copyright (c) 2021 Romain Dolbeau <romain@dolbeau.org>
Copyright (c) 2022 Rouven Broszeit <roubro1991@gmx.de>
Copyright (c) 2020 rprinz08 <richard.prinz@min.at>
Copyright (c) 2015 Ryan Verner <ryan.verner@gmail.com>
Copyright (c) 2020 Sadullah Canakci <sadullahcanakci@gmail.com>
Copyright (c) 2019-2021 sadullah <sadullahcanakci@gmail.com>
Copyright (c) 2019-2020 Sadullah Canakci <sadullahcanakci@gmail.com>
Copyright (c) 2020 Samuel Lindemer <samuel.lindemer@gmail.com>
Copyright (c) 2018-2020 Sean Cross <sean@xobs.io>
Copyright (c) 2013-2016 Sebastien Bourdeauducq <sb@m-labs.hk>
Copyright (c) 2011-2016 Sebastien Bourdeauducq <sb@m-labs.hk>
Copyright (c) 2021 Sergiu Mosanu <sm7ed@virginia.edu>
Copyright (c) 2017-2018 Sergiusz Bazanski <q3k@q3k.org>
Copyright (c) 2020 Shawn Anastasio <shawn@anastas.io>
@ -139,10 +151,13 @@ Copyright (c) 2020-2021 Shawn Hoffman <godisgovernment@gmail.com>
Copyright (c) 2020 shuffle2 <godisgovernment@gmail.com>
Copyright (c) 2021 Simon Thornington <simon.thornington@gmail.com>
Copyright (c) 2018-2022 Stafford Horne <shorne@gmail.com>
Copyright (c) 2020 Stephane Gourichon <stephane.gourichon@fidergo.fr>
Copyright (c) 2022 stnolting <stnolting@gmail.com>
Copyright (c) 2020 Stéphane Gourichon <stephane.gourichon@fidergo.fr>
Copyright (c) 2022 Sylvain Lefebvre <sylvain.lefebvre@inria.fr>
Copyright (c) 2021-2022 Sylvain Munaut <tnt@246tNt.com>
Copyright (c) 2017-2018 Tim 'mithro' Ansell <me@mith.ro>
Copyright (c) 2022 Thomas Watson <twatson52@icloud.com>
Copyright (c) 2017-2021 Tim 'mithro' Ansell <me@mith.ro>
Copyright (c) 2019 Tom Keddie <git@bronwenandtom.com>
Copyright (c) 2021-2022 tongchen126 <tongchen126@gmail.com>
Copyright (c) 2020 Vadim Kaushan <admin@disasm.info>
@ -154,11 +169,13 @@ Copyright (c) 2022 Victor Suarez Rovere <suarezvictor@gmail.com>
Copyright (c) 2019 vytautasb <v.buitvydas@limemicro.com>
Copyright (c) 2013 Werner Almesberger <werner@almesberger.net>
Copyright (c) 2015-2021 whitequark <whitequark@whitequark.org>
Copyright (c) 2015-2021 William D. Jones <thor0505@comcast.net>
Copyright (c) 2015-2022 William D. Jones <thor0505@comcast.net>
Copyright (c) 2022 Wolfgang Nagele <mail@wnagele.com>
Copyright (c) 2013-2014 Yann Sionneau <yann.sionneau@gmail.com>
Copyright (c) 2015 Yves Delley <hack@delley.net>
Copyright (c) 2021 wuhanstudio <wuhanstudio@qq.com>
Copyright (c) 2022 xhe <xw897002528@gmail.com>
Copyright (c) 2020 Xiretza <xiretza@xiretza.xyz>
Copyright (c) 2013-2015 Yann Sionneau <yann.sionneau@gmail.com>
Copyright (c) 2015 Yves Delley <hack@delley.net>
Copyright (c) 2020 Yehowshua Immanuel <yimmanuel3@gatech.edu>
Copyright (c) 2021 Yoshimasa Niwa <niw@niw.at>
Copyright (c) 2015 Yves Delley <hack@delley.net>

View file

@ -132,6 +132,12 @@ def _resource_type(resource):
class ConnectorManager:
def __init__(self, connectors):
self.connector_table = dict()
self.add_connector(connectors)
def add_connector(self, connectors):
if isinstance(connectors, tuple):
connectors = [connectors]
for connector in connectors:
cit = iter(connector)
conn_name = next(cit)
@ -162,7 +168,10 @@ class ConnectorManager:
if pn.isdigit():
pn = int(pn)
r.append(self.connector_table[conn][pn])
conn_pn = self.connector_table[conn][pn]
if ":" in conn_pn:
conn_pn = self.resolve_identifiers([conn_pn])[0]
r.append(conn_pn)
else:
r.append(identifier)
@ -193,6 +202,9 @@ class ConstraintManager:
def add_extension(self, io):
self.available.extend(io)
def add_connector(self, connectors):
self.connector_manager.add_connector(connectors)
def request(self, name, number=None, loose=False):
resource = _lookup(self.available, name, number, loose)
if resource is None:
@ -356,6 +368,9 @@ class GenericPlatform:
def add_extension(self, *args, **kwargs):
return self.constraint_manager.add_extension(*args, **kwargs)
def add_connector(self, *args, **kwargs):
self.constraint_manager.add_connector(*args, **kwargs)
def finalize(self, fragment, *args, **kwargs):
if self.finalized:
raise ConstraintError("Already finalized")

View file

@ -16,10 +16,11 @@ from litex.build.xilinx.vivado import _xdc_separator, _build_xdc
from litex.build import tools
try:
from f4pga import Flow, make_flow_config
from f4pga.common import set_verbosity_level
from f4pga.cache import F4Cache
from f4pga.flow_config import ProjectFlowConfig
from f4pga.flows.flow import Flow
from f4pga.flows.commands import make_flow_config
from f4pga.flows.common import set_verbosity_level
from f4pga.flows.cache import F4Cache
from f4pga.flows.flow_config import ProjectFlowConfig
except ModuleNotFoundError as e:
raise ModuleNotFoundError("Try getting/updating F4PGA tool (https://github.com/chipsalliance/f4pga/)") from e

29
litex/soc/cores/cpu/naxriscv/core.py Normal file → Executable file
View file

@ -196,6 +196,7 @@ class NaxRiscv(CPU):
md5_hash.update(str(NaxRiscv.xlen).encode('utf-8'))
md5_hash.update(str(NaxRiscv.jtag_tap).encode('utf-8'))
md5_hash.update(str(NaxRiscv.jtag_instruction).encode('utf-8'))
md5_hash.update(str(NaxRiscv.memory_regions).encode('utf-8'))
for args in NaxRiscv.scala_args:
md5_hash.update(args.encode('utf-8'))
for file in NaxRiscv.scala_paths:
@ -227,7 +228,7 @@ class NaxRiscv(CPU):
ndir = os.path.join(vdir, "ext", "NaxRiscv")
sdir = os.path.join(vdir, "ext", "SpinalHDL")
NaxRiscv.git_setup("NaxRiscv", ndir, "https://github.com/SpinalHDL/NaxRiscv.git" , "main", "b13c0aad")
NaxRiscv.git_setup("NaxRiscv", ndir, "https://github.com/SpinalHDL/NaxRiscv.git" , "main", "cb2a598a")
NaxRiscv.git_setup("SpinalHDL", sdir, "https://github.com/SpinalHDL/SpinalHDL.git", "dev" , "a130f7b7")
gen_args = []
@ -235,6 +236,8 @@ class NaxRiscv(CPU):
gen_args.append(f"--netlist-directory={vdir}")
gen_args.append(f"--reset-vector={reset_address}")
gen_args.append(f"--xlen={NaxRiscv.xlen}")
for region in NaxRiscv.memory_regions:
gen_args.append(f"--memory-region={region[0]},{region[1]},{region[2]},{region[3]}")
for args in NaxRiscv.scala_args:
gen_args.append(f"--scala-args={args}")
if(NaxRiscv.jtag_tap) :
@ -395,6 +398,7 @@ class NaxRiscv(CPU):
o_peripheral_clint_rresp = clintbus.r.resp,
)
soc.bus.add_slave("clint", clintbus, region=soc_region_cls(origin=soc.mem_map.get("clint"), size=0x1_0000, cached=False))
self.soc = soc # FIXME: Save SoC instance to retrieve the final mem layout on finalization.
def add_memory_buses(self, address_width, data_width):
nax_data_width = 64
@ -463,8 +467,29 @@ class NaxRiscv(CPU):
def do_finalize(self):
assert hasattr(self, "reset_address")
self.find_scala_files()
# Generate memory map from CPU perspective
# naxriscv modes:
# r,w,x,c : readable, writeable, executable, caching allowed
# io : IO region (Implies P bus, preserve memory order, no dcache)
# naxriscv bus:
# p : peripheral
# m : memory
NaxRiscv.memory_regions = []
for name, region in self.soc.bus.io_regions.items():
NaxRiscv.memory_regions.append( (region.origin, region.size, "io", "p") ) # IO is only allowed on the p bus
for name, region in self.soc.bus.regions.items():
if region.linker: # remove virtual regions
continue
if len(self.memory_buses) and name == 'main_ram': # m bus
bus = "m"
else:
bus = "p"
mode = region.mode
mode += "c" if region.cached else ""
NaxRiscv.memory_regions.append( (region.origin, region.size, mode, bus) )
self.generate_netlist_name(self.reset_address)
# Do verilog instance.

View file

@ -260,7 +260,7 @@ class VexRiscvSMP(CPU):
gen_args.append(f"--aes-instruction={VexRiscvSMP.aes_instruction}")
gen_args.append(f"--out-of-order-decoder={VexRiscvSMP.out_of_order_decoder}")
gen_args.append(f"--wishbone-memory={VexRiscvSMP.wishbone_memory}")
gen_args.append(f"--wishbone-force-32b={VexRiscvSMP.wishbone_force_32b}")
if(VexRiscvSMP.wishbone_force_32b): gen_args.append(f"--wishbone-force-32b={VexRiscvSMP.wishbone_force_32b}")
gen_args.append(f"--fpu={VexRiscvSMP.with_fpu}")
gen_args.append(f"--cpu-per-fpu={VexRiscvSMP.cpu_per_fpu}")
gen_args.append(f"--rvc={VexRiscvSMP.with_rvc}")

View file

@ -2,6 +2,7 @@
# This file is part of LiteX.
#
# Copyright (c) 2014-2015 Robert Jordens <jordens@gmail.com>
# Copyright (c) 2022 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
from migen import *
@ -12,34 +13,36 @@ from litex.soc.interconnect.csr import *
# Xilinx DNA (Device Identifier) -------------------------------------------------------------------
class DNA(Module, AutoCSR):
nbits = 57
def __init__(self):
n = 57
self._id = CSRStatus(n)
self._id = CSRStatus(self.nbits)
# # #
self.do = do = Signal()
self.count = count = Signal(max=2*n + 1)
self.clk = clk = Signal()
# Create slow DNA Clk (sys_clk/16).
self.clock_domains.cd_dna = ClockDomain()
dna_clk_count = Signal(4)
self.sync += dna_clk_count.eq(dna_clk_count + 1)
self.sync += self.cd_dna.clk.eq(dna_clk_count[3])
self.comb += clk.eq(count[0])
# Shift-Out DNA Identifier.
count = Signal(8)
dout = Signal()
self.specials += Instance("DNA_PORT",
i_DIN = self._id.status[-1],
o_DOUT = do,
i_CLK = clk,
i_READ = count < 2,
i_SHIFT = 1
i_CLK = ClockSignal("dna"),
i_READ = (count == 0),
i_SHIFT = 1,
i_DIN = 0,
o_DOUT = dout,
)
self.sync += [
If(count < 2*n,
self.sync.dna += [
If(count < (self.nbits + 1),
count.eq(count + 1),
If(clk,
self._id.status.eq(Cat(do, self._id.status))
)
self._id.status.eq(Cat(dout, self._id.status))
)
]
def add_timing_constraints(self, platform, sys_clk_freq, sys_clk):
platform.add_period_constraint(self.clk, 2*1e9/sys_clk_freq)
platform.add_false_path_constraints(self.clk, sys_clk)
platform.add_period_constraint(self.cd_dna.clk, 16*1e9/sys_clk_freq)
platform.add_false_path_constraints(self.cd_dna.clk, sys_clk)

View file

@ -809,6 +809,52 @@ class VideoHDMIPHY(Module):
)
setattr(self.submodules, f"{color}_serializer", serializer)
# HDMI (Gowin).
class VideoGowinHDMIPHY(Module):
def __init__(self, pads, clock_domain="sys", pn_swap=[]):
self.sink = sink = stream.Endpoint(video_data_layout)
# # #
# Always ack Sink, no backpressure.
self.comb += sink.ready.eq(1)
# Clocking + Differential Signaling.
pix_clk = ClockSignal(clock_domain)
self.specials += Instance("ELVDS_OBUF",
i_I = pix_clk if "clk" not in pn_swap else ~pix_clk,
o_O = pads.clk_p,
o_OB = pads.clk_n,
)
for color in ["r", "g", "b"]:
# TMDS Encoding.
encoder = ClockDomainsRenamer(clock_domain)(TMDSEncoder())
setattr(self.submodules, f"{color}_encoder", encoder)
self.comb += encoder.d.eq(getattr(sink, color))
self.comb += encoder.c.eq(Cat(sink.hsync, sink.vsync) if color == "r" else 0)
self.comb += encoder.de.eq(sink.de)
# 10:1 Serialization + Differential Signaling.
data_i = encoder.out if color not in pn_swap else ~encoder.out
pad_o = Signal()
self.specials += Instance("OSER10",
i_PCLK = pix_clk,
i_FCLK = ClockSignal(clock_domain + "5x"),
i_RESET = ResetSignal(clock_domain),
**{f"i_D{i}" : data_i[i] for i in range(10)},
o_Q = pad_o,
)
c2d = {"r": 0, "g": 1, "b": 2}
self.specials += Instance("ELVDS_OBUF",
i_I = pad_o,
o_O = getattr(pads, f"data{c2d[color]}_p"),
o_OB = getattr(pads, f"data{c2d[color]}_n"),
)
# HDMI (Xilinx Spartan6).
class VideoS6HDMIPHY(Module):

View file

@ -69,11 +69,10 @@ class Builder:
include_dir = None,
generated_dir = None,
# Compile Options.
# Compilation.
compile_software = True,
compile_gateware = True,
build_backend = "litex",
lto = False,
# Exports.
csr_json = None,
@ -81,8 +80,9 @@ class Builder:
csr_svd = None,
memory_x = None,
# BIOS Options.
bios_options = [],
# BIOS.
bios_lto = False,
bios_console = "full",
# Documentation.
generate_doc = False):
@ -96,11 +96,10 @@ class Builder:
self.include_dir = os.path.abspath(include_dir or os.path.join(self.software_dir, "include"))
self.generated_dir = os.path.abspath(generated_dir or os.path.join(self.include_dir, "generated"))
# Compile Options.
# Compilation.
self.compile_software = compile_software
self.compile_gateware = compile_gateware
self.build_backend = build_backend
self.lto = lto
# Exports.
self.csr_csv = csr_csv
@ -108,16 +107,16 @@ class Builder:
self.csr_svd = csr_svd
self.memory_x = memory_x
# BIOS Options.
self.bios_options = bios_options
# BIOS.
self.bios_lto = bios_lto
self.bios_console = bios_console
# Documentation
# Documentation.
self.generate_doc = generate_doc
# List software packages and libraries.
# Software packages and libraries.
self.software_packages = []
self.software_libraries = []
for name in soc_software_packages:
self.add_software_package(name)
self.add_software_library(name)
@ -134,6 +133,7 @@ class Builder:
# Helper.
variables_contents = []
def define(k, v):
k = k.replace("-", "_")
try:
variables_contents.append("{}={}".format(k, _makefile_escape(v)))
except AttributeError as e:
@ -161,11 +161,10 @@ class Builder:
for name, src_dir in self.software_packages:
define(name.upper() + "_DIRECTORY", src_dir)
# Define Compile/BIOS Options.
define("LTO", f"{self.lto:d}")
for bios_option in self.bios_options:
assert bios_option in ["TERM_NO_HIST", "TERM_MINI", "TERM_NO_COMPLETE"]
define(bios_option, "1")
# Define BIOS variables.
define("LTO", f"{self.bios_lto:d}")
assert self.bios_console in ["full", "no-history", "no-autocomplete", "lite", "disable"]
define(f"BIOS_CONSOLE_{self.bios_console.upper()}", "1")
return "\n".join(variables_contents)
@ -257,10 +256,15 @@ class Builder:
meson_minor_min = 59
if meson_present:
meson_version = subprocess.check_output(["meson", "-v"]).decode("utf-8").split(".")
if (not meson_present) or (int(meson_version[0]) < meson_major_min) or (int(meson_version[1]) < meson_minor_min):
if (not meson_present):
msg = "Unable to find valid Meson build system, please install it with:\n"
msg += "- pip3 install meson.\n"
raise OSError(msg)
if (int(meson_version[0]) < meson_major_min) or (int(meson_version[1]) < meson_minor_min):
msg = f"Meson version to old. Found: {meson_version[0]}.{meson_version[1]}. Required: {meson_major_min}.{meson_minor_min}.\n"
msg += "Try updating with:\n"
msg += "- pip3 install -U meson.\n"
raise OSError(msg)
def _prepare_rom_software(self):
# Create directories for all software packages.
@ -283,7 +287,10 @@ class Builder:
def _initialize_rom_software(self):
# Get BIOS data from compiled BIOS binary.
bios_file = os.path.join(self.software_dir, "bios", "bios.bin")
bios_data = soc_core.get_mem_data(bios_file, self.soc.cpu.endianness)
bios_data = soc_core.get_mem_data(bios_file,
data_width = self.soc.bus.data_width,
endianness = self.soc.cpu.endianness,
)
# Initialize SoC with with BIOS data.
self.soc.initialize_rom(bios_data)
@ -392,12 +399,14 @@ def builder_args(parser):
builder_group.add_argument("--no-compile", action="store_true", help="Disable Software and Gateware compilation.")
builder_group.add_argument("--no-compile-software", action="store_true", help="Disable Software compilation only.")
builder_group.add_argument("--no-compile-gateware", action="store_true", help="Disable Gateware compilation only.")
builder_group.add_argument("--lto", action="store_true", help="Enable LTO (Link Time Optimization) for Software compilation.")
builder_group.add_argument("--csr-csv", default=None, help="Write SoC mapping to the specified CSV file.")
builder_group.add_argument("--csr-json", default=None, help="Write SoC mapping to the specified JSON file.")
builder_group.add_argument("--csr-svd", default=None, help="Write SoC mapping to the specified SVD file.")
builder_group.add_argument("--memory-x", default=None, help="Write SoC Memory Regions to the specified Memory-X file.")
builder_group.add_argument("--doc", action="store_true", help="Generate SoC Documentation.")
bios_group = parser.add_argument_group(title="BIOS options") # FIXME: Move?
bios_group.add_argument("--bios-lto", action="store_true", help="Enable BIOS LTO (Link Time Optimization) compilation.")
bios_group.add_argument("--bios-console", default="full" , help="Select BIOS console config.", choices=["full", "no-history", "no-autocomplete", "lite", "disable"])
def builder_argdict(args):
return {
@ -409,10 +418,11 @@ def builder_argdict(args):
"build_backend" : args.build_backend,
"compile_software" : (not args.no_compile) and (not args.no_compile_software),
"compile_gateware" : (not args.no_compile) and (not args.no_compile_gateware),
"lto" : args.lto,
"csr_csv" : args.csr_csv,
"csr_json" : args.csr_json,
"csr_svd" : args.csr_svd,
"memory_x" : args.memory_x,
"generate_doc" : args.doc,
"bios_lto" : args.bios_lto,
"bios_console" : args.bios_console,
}

View file

@ -39,7 +39,8 @@ def get_mem_regions(filename_or_regions, offset):
regions = {filename: f"{offset:08x}"}
return regions
def get_mem_data(filename_or_regions, endianness="big", mem_size=None, offset=0):
def get_mem_data(filename_or_regions, data_width=32, endianness="big", mem_size=None, offset=0):
assert data_width in [32, 64]
# Create memory regions.
regions = get_mem_regions(filename_or_regions, offset)
@ -56,23 +57,28 @@ def get_mem_data(filename_or_regions, endianness="big", mem_size=None, offset=0)
data_size, mem_size))
# Fill data.
data = [0]*math.ceil(data_size/4)
bytes_per_data = data_width//8
data = [0]*math.ceil(data_size/bytes_per_data)
for filename, base in regions.items():
base = int(base, 16)
with open(filename, "rb") as f:
i = 0
while True:
w = f.read(4)
w = f.read(bytes_per_data)
if not w:
break
if len(w) != 4:
for _ in range(len(w), 4):
if len(w) != bytes_per_data:
for _ in range(len(w), bytes_per_data):
w += b'\x00'
unpack_order = {
"little": "<I",
"big": ">I"
}[endianness]
data[(base - offset)//4 + i] = struct.unpack(unpack_order, w)[0]
if data_width == 32:
data[(base - offset)//bytes_per_data + i] = struct.unpack(unpack_order, w)[0]
if data_width == 64:
data[(base - offset)//bytes_per_data + i] = (struct.unpack(unpack_order, w[0:4])[0] << 0)
data[(base - offset)//bytes_per_data + i] |= (struct.unpack(unpack_order, w[4:8])[0] << 32)
i += 1
return data

42
litex/soc/integration/soc.py Normal file → Executable file
View file

@ -332,7 +332,10 @@ class SoCBusHandler(Module):
axi.AXILiteInterface : axi.AXILiteConverter,
axi.AXIInterface : axi.AXIConverter,
}[interface_cls]
adapted_interface = interface_cls(data_width=self.data_width)
adapted_interface = interface_cls(
data_width = self.data_width,
address_width = self.address_width
)
if direction == "m2s":
master, slave = interface, adapted_interface
elif direction == "s2m":
@ -353,7 +356,10 @@ class SoCBusHandler(Module):
return interface
# Different Bus-Standard: Return adapted interface.
else:
adapted_interface = main_bus_cls(data_width=self.data_width)
adapted_interface = main_bus_cls(
data_width = self.data_width,
address_width = self.address_width
)
if direction == "m2s":
master, slave = interface, adapted_interface
elif direction == "s2m":
@ -886,7 +892,7 @@ class SoC(Module):
colorer("added", color="green")))
setattr(self.submodules, name, SoCController(**kwargs))
def add_ram(self, name, origin, size, contents=[], mode="rw"):
def add_ram(self, name, origin, size, contents=[], mode="rwx"):
ram_cls = {
"wishbone": wishbone.SRAM,
"axi-lite": axi.AXILiteSRAM,
@ -897,8 +903,12 @@ class SoC(Module):
"axi-lite": axi.AXILiteInterface,
"axi" : axi.AXILiteInterface, # FIXME: Use AXI-Lite for now, create AXISRAM.
}[self.bus.standard]
ram_bus = interface_cls(data_width=self.bus.data_width, bursting=self.bus.bursting)
ram = ram_cls(size, bus=ram_bus, init=contents, read_only=(mode == "r"), name=name)
ram_bus = interface_cls(
data_width = self.bus.data_width,
address_width = self.bus.address_width,
bursting = self.bus.bursting
)
ram = ram_cls(size, bus=ram_bus, init=contents, read_only=("w" not in mode), name=name)
self.bus.add_slave(name, ram.bus, SoCRegion(origin=origin, size=size, mode=mode))
self.check_if_exists(name)
self.logger.info("RAM {} {} {}.".format(
@ -909,7 +919,7 @@ class SoC(Module):
if contents != []:
self.add_config(f"{name}_INIT", 1)
def add_rom(self, name, origin, size, contents=[], mode="r"):
def add_rom(self, name, origin, size, contents=[], mode="rx"):
self.add_ram(name, origin, size, contents, mode=mode)
def init_rom(self, name, contents=[], auto_size=True):
@ -917,7 +927,7 @@ class SoC(Module):
colorer(name),
colorer(f"0x{4*len(contents):x}")))
getattr(self, name).mem.init = contents
if auto_size and self.bus.regions[name].mode == "r":
if auto_size and "w" not in self.bus.regions[name].mode:
self.logger.info("Auto-Resizing ROM {} from {} to {}.".format(
colorer(name),
colorer(f"0x{self.bus.regions[name].size:x}"),
@ -1475,7 +1485,11 @@ class LiteXSoC(SoC):
sdram_size = min(sdram_size, size)
# Add SDRAM region.
self.bus.add_region("main_ram", SoCRegion(origin=self.mem_map.get("main_ram", origin), size=sdram_size))
main_ram_region = SoCRegion(
origin = self.mem_map.get("main_ram", origin),
size = sdram_size,
mode = "rwx")
self.bus.add_region("main_ram", main_ram_region)
# Add CPU's direct memory buses (if not already declared) ----------------------------------
if hasattr(self.cpu, "add_memory_buses"):
@ -1906,7 +1920,7 @@ class LiteXSoC(SoC):
if "write" in mode:
self.comb += self.sata_irq.mem2sector_dma.trigger.eq(self.sata_mem2sector.irq)
if self.irq.enabled:
self.irq.add("sata", use_loc_if_exists=True)
self.irq.add("sata_irq", use_loc_if_exists=True)
# Timing constraints.
self.platform.add_period_constraint(self.sata_phy.crg.cd_sata_tx.clk, 1e9/sata_clk_freq)
@ -1920,7 +1934,8 @@ class LiteXSoC(SoC):
def add_pcie(self, name="pcie", phy=None, ndmas=0, max_pending_requests=8, address_width=32,
with_dma_buffering = True, dma_buffering_depth=1024,
with_dma_loopback = True,
with_msi = True):
with_msi = True,
with_synchronizer = False):
# Imports
from litepcie.core import LitePCIeEndpoint, LitePCIeMSI
from litepcie.frontend.dma import LitePCIeDMA
@ -1957,9 +1972,10 @@ class LiteXSoC(SoC):
assert with_msi
self.check_if_exists(f"{name}_dma{i}")
dma = LitePCIeDMA(phy, endpoint,
with_buffering = with_dma_buffering, buffering_depth=dma_buffering_depth,
with_loopback = with_dma_loopback,
address_width = address_width
with_buffering = with_dma_buffering, buffering_depth=dma_buffering_depth,
with_loopback = with_dma_loopback,
with_synchronizer = with_synchronizer,
address_width = address_width
)
setattr(self.submodules, f"{name}_dma{i}", dma)
self.msis[f"{name.upper()}_DMA{i}_WRITER"] = dma.writer.irq

View file

@ -78,7 +78,7 @@ class SoCCore(LiteXSoC):
# ROM parameters
integrated_rom_size = 0,
integrated_rom_mode = "r",
integrated_rom_mode = "rx",
integrated_rom_init = [],
# SRAM parameters
@ -156,7 +156,10 @@ class SoCCore(LiteXSoC):
# ROM.
# Initialize ROM from binary file when provided.
if isinstance(integrated_rom_init, str):
integrated_rom_init = get_mem_data(integrated_rom_init, "little") # FIXME: Endianness.
integrated_rom_init = get_mem_data(integrated_rom_init,
endianness = "little", # FIXME: Depends on CPU.
data_width = bus_data_width
)
integrated_rom_size = 4*len(integrated_rom_init)
# Disable ROM when no CPU/hard-CPU.

View file

@ -18,53 +18,73 @@ from litex.soc.interconnect.axi.axi_common import *
# AXI Definition -----------------------------------------------------------------------------------
def ax_description(address_width, id_width):
return [
("addr", address_width),
("burst", 2), # Burst type
("len", 8), # Number of data (-1) transfers (up to 256)
("size", 4), # Number of bytes (-1) of each data transfer (up to 1024 bits)
("lock", 2), # *
("prot", 3), # *
("cache", 4), # *
("qos", 4), # *
("id", id_width)
]
def ax_description(address_width, id_width=0, user_width=0):
# * present for interconnect with others cores but not used by LiteX.
ax = [
("addr", address_width), # Address Width.
("burst", 2), # Burst type.
("len", 8), # Number of data (-1) transfers (up to 256).
("size", 4), # Number of bytes (-1) of each data transfer (up to 1024 bits).
("lock", 2), # *
("prot", 3), # *
("cache", 4), # *
("qos", 4), # *
("region", 4), # *
]
if id_width:
ax += [("id", id_width)] # ID Width.
if user_width:
ax += [("user", user_width)] # *
return ax
def w_description(data_width, id_width):
return [
def w_description(data_width, id_width=0, user_width=0):
w = [
("data", data_width),
("strb", data_width//8),
("id", id_width)
]
if id_width:
w += [("id", id_width)]
if user_width:
w += [("user", user_width)]
return w
def b_description(id_width):
return [
("resp", 2),
("id", id_width)
]
def b_description(id_width=0, user_width=0):
b = [("resp", 2)]
if id_width:
b += [("id", id_width)]
if user_width:
b += [("user", user_width)]
return b
def r_description(data_width, id_width):
return [
def r_description(data_width, id_width=0, user_width=0):
r = [
("resp", 2),
("data", data_width),
("id", id_width)
]
if id_width:
r += [("id", id_width)]
if user_width:
r += [("user", user_width)]
return r
class AXIInterface:
def __init__(self, data_width=32, address_width=32, id_width=1, clock_domain="sys", name=None, bursting=False):
def __init__(self, data_width=32, address_width=32, id_width=1, clock_domain="sys", name=None, bursting=False,
aw_user_width = 0,
w_user_width = 0,
b_user_width = 0,
ar_user_width = 0,
r_user_width = 0):
self.data_width = data_width
self.address_width = address_width
self.id_width = id_width
self.clock_domain = clock_domain
self.bursting = bursting # FIXME: Use or add check.
self.aw = stream.Endpoint(ax_description(address_width, id_width), name=name)
self.w = stream.Endpoint(w_description(data_width, id_width), name=name)
self.b = stream.Endpoint(b_description(id_width), name=name)
self.ar = stream.Endpoint(ax_description(address_width, id_width), name=name)
self.r = stream.Endpoint(r_description(data_width, id_width), name=name)
self.aw = stream.Endpoint(ax_description(address_width, id_width, aw_user_width), name=name)
self.w = stream.Endpoint(w_description(data_width, id_width, w_user_width), name=name)
self.b = stream.Endpoint(b_description(id_width, b_user_width), name=name)
self.ar = stream.Endpoint(ax_description(address_width, id_width, ar_user_width), name=name)
self.r = stream.Endpoint(r_description(data_width, id_width, r_user_width), name=name)
def connect_to_pads(self, pads, mode="master"):
return connect_to_pads(self, pads, mode, axi_full=True)

View file

@ -19,7 +19,11 @@ from litex.soc.interconnect.axi.axi_common import *
# AXI-Lite Definition ------------------------------------------------------------------------------
def ax_lite_description(address_width):
return [("addr", address_width)]
return [
("addr", address_width),
("prot", 3), # *
]
# * present for interconnect with others cores but not used by LiteX.
def w_lite_description(data_width):
return [

View file

@ -17,27 +17,48 @@ from litex.soc.interconnect.axi.axi_common import *
# AXI-Stream Definition ----------------------------------------------------------------------------
class AXIStreamInterface(stream.Endpoint):
def __init__(self, data_width=32, keep_width=0, user_width=0):
def __init__(self, data_width=32, keep_width=0, id_width=0, dest_width=0, user_width=0):
self.data_width = data_width
self.keep_width = keep_width
self.id_width = id_width
self.dest_width = dest_width
self.user_width = user_width
# Define Payload Layout.
payload_layout = [("data", data_width)]
if self.keep_width:
payload_layout += [("keep", keep_width)]
# Define Param Layout.
param_layout = []
if self.id_width:
param_layout += [("id", id_width)]
if self.dest_width:
param_layout += [("dest", dest_width)]
if self.user_width:
param_layout += [("user", user_width)]
# Create Endpoint.
stream.Endpoint.__init__(self, stream.EndpointDescription(payload_layout, param_layout))
def get_ios(self, bus_name="axi"):
# Control Signals.
subsignals = [
Subsignal("tvalid", Pins(1)),
Subsignal("tlast", Pins(1)),
Subsignal("tready", Pins(1)),
Subsignal("tdata", Pins(self.data_width)),
]
# Payload Signals.
subsignals += [Subsignal("tdata", Pins(self.data_width))]
if self.keep_width:
subsignals += [Subsignal("tkeep", Pins(self.keep_width))]
# Param Signals.
if self.id_width:
subsignals += [Subsignal("tid", Pins(self.id_width))]
if self.dest_width:
subsignals += [Subsignal("tdest", Pins(self.dest_width))]
if self.user_width:
subsignals += [Subsignal("tuser", Pins(self.user_width))]
ios = [(bus_name , 0) + tuple(subsignals)]
@ -47,21 +68,35 @@ class AXIStreamInterface(stream.Endpoint):
assert mode in ["slave", "master"]
r = []
if mode == "master":
# Control Signals.
r.append(pads.tvalid.eq(self.valid))
r.append(self.ready.eq(pads.tready))
r.append(pads.tlast.eq(self.last))
# Payload Signals.
r.append(pads.tdata.eq(self.data))
if self.keep_width:
r.append(pads.tkeep.eq(self.keep))
# Param Signals.
if self.id_width:
r.append(pads.tid.eq(self.id))
if self.dest_width:
r.append(pads.tdest.eq(self.dest))
if self.user_width:
r.append(pads.tuser.eq(self.user))
if mode == "slave":
# Control Signals.
r.append(self.valid.eq(pads.tvalid))
r.append(pads.tready.eq(self.ready))
r.append(self.last.eq(pads.tlast))
# Payload Signals.
r.append(self.data.eq(pads.tdata))
if self.keep_width:
r.append(self.keep.eq(pads.tkeep))
# Param Signals.
if self.id_width:
r.append(self.id.eq(pads.tid))
if self.dest_width:
r.append(self.dest.eq(pads.tdest))
if self.user_width:
r.append(self.user.eq(pads.tuser))
return r

View file

@ -766,7 +766,32 @@ class PipeReady(Module):
# Buffer -------------------------------------------------------------------------------------------
class Buffer(PipeValid): pass # FIXME: Replace Buffer with PipeValid in codebase?
class Buffer(Module):
"""Pipe valid/payload and/or ready to cut timing path"""
def __init__(self, layout, pipe_valid=True, pipe_ready=False):
self.sink = sink = Endpoint(layout)
self.source = source = Endpoint(layout)
# # #
pipeline = []
# Pipe Valid (Optional).
if pipe_valid:
self.submodules.pipe_valid = PipeValid(layout)
pipeline.append(self.pipe_valid)
# Pipe Ready (Optional).
if pipe_ready:
self.submodules.pipe_ready = PipeReady(layout)
pipeline.append(self.pipe_ready)
# Buffer Pipeline.
self.submodules.pipeline = Pipeline(
sink,
*pipeline,
source
)
# Cast ---------------------------------------------------------------------------------------------

View file

@ -46,9 +46,12 @@ CTI_BURST_END = 0b111
class Interface(Record):
def __init__(self, data_width=32, adr_width=30, bursting=False):
def __init__(self, data_width=32, adr_width=30, bursting=False, **kwargs):
self.data_width = data_width
self.adr_width = adr_width
if kwargs.get("address_width", False):
# FIXME: Improve or switch Wishbone to byte addressing instead of word addressing.
adr_width = kwargs["address_width"] - int(log2(data_width//8))
self.adr_width = adr_width
self.bursting = bursting
Record.__init__(self, set_layout_parameters(_layout,
adr_width = adr_width,
@ -257,42 +260,40 @@ class DownConverter(Module):
# # #
skip = Signal()
counter = Signal(max=ratio)
skip = Signal()
done = Signal()
count = Signal(max=ratio)
# Control Path
fsm = FSM(reset_state="IDLE")
fsm = ResetInserter()(fsm)
self.submodules.fsm = fsm
self.comb += fsm.reset.eq(~master.cyc)
fsm.act("IDLE",
NextValue(counter, 0),
If(master.stb & master.cyc,
NextState("CONVERT"),
)
)
fsm.act("CONVERT",
slave.adr.eq(Cat(counter, master.adr)),
Case(counter, {i: slave.sel.eq(master.sel[i*dw_to//8:]) for i in range(ratio)}),
# Control Path.
self.comb += [
done.eq(count == (ratio - 1)),
If(master.stb & master.cyc,
skip.eq(slave.sel == 0),
slave.we.eq(master.we),
slave.cyc.eq(~skip),
slave.stb.eq(~skip),
slave.we.eq(master.we),
If(slave.ack | skip,
NextValue(counter, counter + 1),
If(counter == (ratio - 1),
master.ack.eq(1),
NextState("IDLE")
)
master.ack.eq(done)
)
)
)
]
self.sync += [
If((slave.stb & slave.cyc & slave.ack) | skip,
count.eq(count + 1)
),
If(master.ack | ~master.cyc,
count.eq(0)
)
]
# Write Datapath
self.comb += Case(counter, {i: slave.dat_w.eq(master.dat_w[i*dw_to:]) for i in range(ratio)})
# Address.
self.comb += slave.adr.eq(Cat(count, master.adr))
# Read Datapath
# Write Datapath.
self.comb += Case(count, {i: slave.dat_w.eq(master.dat_w[i*dw_to:]) for i in range(ratio)})
self.comb += Case(count, {i: slave.sel.eq(master.sel[i*dw_to//8:]) for i in range(ratio)}),
# Read Datapath.
dat_r = Signal(dw_from, reset_less=True)
self.comb += master.dat_r.eq(Cat(dat_r[dw_to:], slave.dat_r))
self.sync += If(slave.ack | skip, dat_r.eq(master.dat_r))

View file

@ -21,18 +21,22 @@ OBJECTS = boot-helper.o \
sim_debug.o \
main.o
ifneq "$(or $(TERM_NO_COMPLETE),$(TERM_MINI))" ""
CFLAGS += -DTERM_NO_COMPLETE
ifneq "$(or $(BIOS_CONSOLE_NO_AUTOCOMPLETE),$(BIOS_CONSOLE_LITE))" ""
CFLAGS += -DBIOS_CONSOLE_NO_AUTOCOMPLETE
else
OBJECTS += complete.o
endif
ifdef TERM_NO_HIST
CFLAGS += -DTERM_NO_HIST
ifdef BIOS_CONSOLE_NO_HISTORY
CFLAGS += -DBIOS_CONSOLE_NO_HISTORY
endif
ifdef TERM_MINI
CFLAGS += -DTERM_MINI
ifdef BIOS_CONSOLE_DISABLE
CFLAGS += -DBIOS_CONSOLE_DISABLE
endif
ifdef BIOS_CONSOLE_LITE
CFLAGS += -DBIOS_CONSOLE_LITE
OBJECTS += readline_simple.o
else
OBJECTS += readline.o

View file

@ -32,17 +32,20 @@ struct command_struct {
extern struct command_struct *const __bios_cmd_start[];
extern struct command_struct *const __bios_cmd_end[];
#define define_command(cmd_name, handler, help_txt, group_id) \
struct command_struct s_##cmd_name = { \
.func = (cmd_handler)handler, \
.name = #cmd_name, \
.help = help_txt, \
.group = group_id, \
}; \
const struct command_struct *__bios_cmd_##cmd_name __attribute__((__used__)) \
__attribute__((__section__(".bios_cmd"))) = &s_##cmd_name
#ifdef BIOS_CONSOLE_BIOS_CONSOLE_DISABLE
#define define_command(cmd_name, handler, help_txt, group_id)
#else
#define define_command(cmd_name, handler, help_txt, group_id) \
struct command_struct s_##cmd_name = { \
.func = (cmd_handler)handler, \
.name = #cmd_name, \
.help = help_txt, \
.group = group_id, \
}; \
const struct command_struct *__bios_cmd_##cmd_name __attribute__((__used__)) \
__attribute__((__section__(".bios_cmd"))) = &s_##cmd_name
struct command_struct *command_dispatcher(char *command, int nb_params, char **params);
struct command_struct *command_dispatcher(char *command, int nb_params, char **params);
#endif
#endif
#endif

View file

@ -80,11 +80,13 @@ static void boot_sequence(void)
__attribute__((__used__)) int main(int i, char **c)
{
#ifndef BIOS_CONSOLE_DISABLE
char buffer[CMD_LINE_BUFFER_SIZE];
char *params[MAX_PARAM];
char *command;
struct command_struct *cmd;
int nb_params;
#endif
int sdr_ok;
#ifdef CONFIG_CPU_HAS_INTERRUPT
@ -207,8 +209,11 @@ __attribute__((__used__)) int main(int i, char **c)
#endif
/* Console */
#ifdef BIOS_CONSOLE_DISABLE
printf("--======= \e[1mDone (No Console) \e[0m ==========--\n");
#else
printf("--============= \e[1mConsole\e[0m ================--\n");
#if !defined(TERM_MINI) && !defined(TERM_NO_HIST)
#if !defined(BIOS_CONSOLE_LITE) && !defined(BIOS_CONSOLE_NO_HISTORY)
hist_init();
#endif
printf("\n%s", PROMPT);
@ -223,5 +228,6 @@ __attribute__((__used__)) int main(int i, char **c)
}
printf("\n%s", PROMPT);
}
#endif
return 0;
}

View file

@ -16,7 +16,7 @@
#include "readline.h"
#include "complete.h"
#ifndef TERM_NO_HIST
#ifndef BIOS_CONSOLE_NO_HISTORY
static int hist_max = 0;
static int hist_add_idx = 0;
static int hist_cur = 0;
@ -76,7 +76,7 @@ static int read_key(void)
return c;
}
#ifndef TERM_NO_HIST
#ifndef BIOS_CONSOLE_NO_HISTORY
static void cread_add_to_hist(char *line)
{
strcpy(&hist_lines[hist_add_idx][0], line);
@ -189,7 +189,7 @@ int readline(char *buf, int len)
int insert = 1;
unsigned char ichar;
#ifndef TERM_NO_COMPLETE
#ifndef BIOS_CONSOLE_NO_AUTOCOMPLETE
char tmp;
int reprint, i;
char *completestr;
@ -204,7 +204,7 @@ int readline(char *buf, int len)
switch (ichar) {
case '\t':
#ifndef TERM_NO_COMPLETE
#ifndef BIOS_CONSOLE_NO_AUTOCOMPLETE
buf[eol_num] = 0;
tmp = buf[num];
@ -306,7 +306,7 @@ int readline(char *buf, int len)
case KEY_UP:
case KEY_DOWN:
{
#ifndef TERM_NO_HIST
#ifndef BIOS_CONSOLE_NO_HISTORY
char * hline;
if (ichar == KEY_UP)
hline = hist_prev();
@ -343,7 +343,7 @@ int readline(char *buf, int len)
len = eol_num;
buf[eol_num] = '\0';
#ifndef TERM_NO_HIST
#ifndef BIOS_CONSOLE_NO_HISTORY
if (buf[0] && buf[0] != CREAD_HIST_CHAR)
cread_add_to_hist(buf);
hist_cur = hist_add_idx;

View file

@ -326,7 +326,7 @@ static unsigned int sdram_write_read_check_test_pattern(int module, unsigned int
command_pwr(DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS|DFII_COMMAND_WRDATA);
cdelay(15);
#ifdef SDRAM_PHY_ECP5DDRPHY
#if defined(SDRAM_PHY_ECP5DDRPHY) || defined(SDRAM_PHY_GW2DDRPHY)
ddrphy_burstdet_clr_write(1);
#endif
@ -362,7 +362,7 @@ static unsigned int sdram_write_read_check_test_pattern(int module, unsigned int
}
}
#ifdef SDRAM_PHY_ECP5DDRPHY
#if defined(SDRAM_PHY_ECP5DDRPHY) || defined(SDRAM_PHY_GW2DDRPHY)
if (((ddrphy_burstdet_seen_read() >> module) & 0x1) != 1)
errors += 1;
#endif
@ -894,7 +894,7 @@ static void sdram_read_leveling_rst_delay(int module) {
/* Un-select module */
ddrphy_dly_sel_write(0);
#ifdef SDRAM_PHY_ECP5DDRPHY
#if defined(SDRAM_PHY_ECP5DDRPHY) || defined(SDRAM_PHY_GW2DDRPHY)
/* Sync all DQSBUFM's, By toggling all dly_sel (DQSBUFM.PAUSE) lines. */
ddrphy_dly_sel_write(0xff);
ddrphy_dly_sel_write(0);
@ -911,7 +911,7 @@ static void sdram_read_leveling_inc_delay(int module) {
/* Un-select module */
ddrphy_dly_sel_write(0);
#ifdef SDRAM_PHY_ECP5DDRPHY
#if defined(SDRAM_PHY_ECP5DDRPHY) || defined(SDRAM_PHY_GW2DDRPHY)
/* Sync all DQSBUFM's, By toggling all dly_sel (DQSBUFM.PAUSE) lines. */
ddrphy_dly_sel_write(0xff);
ddrphy_dly_sel_write(0);

View file

@ -36,11 +36,19 @@ class RemoteClient(EtherboneIPC, CSRBuilder):
self.debug = debug
self.base_address = base_address if base_address is not None else 0
def _receive_server_info(self):
info = str(self.socket.recv(128))
# With LitePCIe, CSRs are translated to 0 to limit BAR0 size, so also translate base address.
if "CommPCIe" in info:
self.base_address = -self.mems.csr.base
def open(self):
if hasattr(self, "socket"):
return
self.socket = socket.create_connection((self.host, self.port), 5.0)
self.socket.settimeout(5.0)
self._receive_server_info()
def close(self):
if not hasattr(self, "socket"):
@ -99,10 +107,6 @@ def dump_identifier(host, csr_csv, port):
bus = RemoteClient(host=host, csr_csv=csr_csv, port=port)
bus.open()
# On PCIe designs, CSR is remapped to 0 to limit BAR0 size.
if hasattr(bus.bases, "pcie_phy"):
bus.base_address = -bus.mems.csr.base
fpga_identifier = ""
for i in range(256):
@ -119,10 +123,6 @@ def dump_registers(host, csr_csv, port, filter=None):
bus = RemoteClient(host=host, csr_csv=csr_csv, port=port)
bus.open()
# On PCIe designs, CSR is remapped to 0 to limit BAR0 size.
if hasattr(bus.bases, "pcie_phy"):
bus.base_address = -bus.mems.csr.base
for name, register in bus.regs.__dict__.items():
if (filter is None) or filter in name:
print("0x{:08x} : 0x{:08x} {}".format(register.addr, register.read(), name))

View file

@ -27,12 +27,14 @@ class Author:
def add_year(self, year):
self.years.append(year)
self.years = make_unique(self.years)
self.years.sort()
# Use Git Log + Processing to create the list of Contibutors ---------------------------------------
companies = {
"Antmicro" : "Antmicro.com",
"Google" : "Google.com",
"Antmicro" : "Antmicro.com",
"Google" : "Google.com",
"RapidSilicon" : "RapidSilicon.com",
}
def list_contributors(path):
@ -41,7 +43,7 @@ def list_contributors(path):
os.system(f"git log --follow --pretty=format:\"%an,%ae,%aI\" {path} | sort | uniq > contribs.csv")
# Read .csv and process it.
authors = {}
contributors = {}
with open("contribs.csv", newline='') as csvfile:
reader = csv.reader(csvfile, delimiter=",")
for line in reader:
@ -53,13 +55,14 @@ def list_contributors(path):
if companies_email.lower() in email:
name = companies_name
email = companies_email
if name in authors.keys():
authors[name].add_year(int(year))
if name in contributors.keys():
contributors[name].add_year(int(year))
else:
authors[name] = Author(email, int(year))
contributors[name] = Author(email, int(year))
# Export Contributors.
for name, info in authors.items():
for name in sorted(contributors.keys(), key=lambda x:x.upper()):
info = contributors[name]
r = "Copyright (c) "
if len(info.years) > 1:
years = f"{info.years[0]}-{info.years[-1]}"

View file

@ -96,35 +96,48 @@ class RemoteServer(EtherboneIPC):
self.socket.close()
del self.socket
def _send_server_info(self, client_socket):
# FIXME: Formalize info/improve.
info = []
info.append(f"{self.comm.__class__.__name__}")
info.append(f"{self.bind_ip}")
info.append(f"{self.bind_port}")
info = ":".join(info)
client_socket.sendall(bytes(info, "UTF-8"))
def _serve_thread(self):
while True:
client_socket, addr = self.socket.accept()
self._send_server_info(client_socket)
print("Connected with " + addr[0] + ":" + str(addr[1]))
try:
# Serve Etherbone reads/writes.
while True:
# Receive packet.
try:
packet = self.receive_packet(client_socket)
if packet == 0:
break
except:
break
# Decode Packet.
packet = EtherbonePacket(packet)
packet.decode()
# Get Packet's Record.
record = packet.records.pop()
# Wait for lock
# Hardware lock/reservation.
while self.lock:
time.sleep(0.01)
# Set lock
self.lock = True
# Handle writes:
# Handle Etherbone writes.
if record.writes != None:
self.comm.write(record.writes.base_addr, record.writes.get_datas())
# Handle reads
# Handle Etherbone reads.
if record.reads != None:
max_length = {
"CommUART": 256,
@ -148,7 +161,7 @@ class RemoteServer(EtherboneIPC):
packet.encode()
self.send_packet(client_socket, packet)
# release lock
# Release hardware lock.
self.lock = False
finally:

View file

@ -403,7 +403,8 @@ def main():
# Configuration --------------------------------------------------------------------------------
cpu = CPUS.get(soc_kwargs.get("cpu_type", "vexriscv"))
cpu = CPUS.get(soc_kwargs.get("cpu_type", "vexriscv"))
bus_data_width = int(soc_kwargs["bus_data_width"])
# UART.
if soc_kwargs["uart_name"] == "serial":
@ -412,7 +413,10 @@ def main():
# ROM.
if args.rom_init:
soc_kwargs["integrated_rom_init"] = get_mem_data(args.rom_init, endianness=cpu.endianness)
soc_kwargs["integrated_rom_init"] = get_mem_data(args.rom_init,
data_width = bus_data_width,
endianness = cpu.endianness
)
# RAM / SDRAM.
ram_boot_offset = 0x40000000 # FIXME
@ -420,8 +424,12 @@ def main():
soc_kwargs["integrated_main_ram_size"] = args.integrated_main_ram_size
if args.integrated_main_ram_size:
if args.ram_init is not None:
soc_kwargs["integrated_main_ram_init"] = get_mem_data(args.ram_init, endianness=cpu.endianness, offset=ram_boot_offset)
ram_boot_address = get_boot_address(args.ram_init)
soc_kwargs["integrated_main_ram_init"] = get_mem_data(args.ram_init,
data_width = bus_data_width,
endianness = cpu.endianness,
offset = ram_boot_offset
)
ram_boot_address = get_boot_address(args.ram_init)
elif args.with_sdram:
assert args.ram_init is None
soc_kwargs["sdram_module"] = args.sdram_module
@ -430,7 +438,11 @@ def main():
if args.sdram_from_spd_dump:
soc_kwargs["sdram_spd_data"] = parse_spd_hexdump(args.sdram_from_spd_dump)
if args.sdram_init is not None:
soc_kwargs["sdram_init"] = get_mem_data(args.sdram_init, endianness=cpu.endianness, offset=ram_boot_offset)
soc_kwargs["sdram_init"] = get_mem_data(args.sdram_init,
data_width = bus_data_width,
endianness = cpu.endianness,
offset = ram_boot_offset
)
ram_boot_address = get_boot_address(args.sdram_init)
# Ethernet.

View file

@ -97,10 +97,6 @@ class CrossoverUART:
if not present:
raise ValueError(f"CrossoverUART {name} not present in design.")
# FIXME: On PCIe designs, CSR is remapped to 0 to limit BAR0 size.
if base_address is None and hasattr(self.bus.bases, "pcie_phy"):
self.bus.base_address = -self.bus.mems.csr.base
def open(self):
self.bus.open()
self.file, self.name = pty.openpty()

23
test/test_axi_stream.py Normal file
View file

@ -0,0 +1,23 @@
#
# This file is part of LiteX.
#
# Copyright (c) 2020-2022 Florent Kermarrec <florent@enjoy-digital.fr>
# SPDX-License-Identifier: BSD-2-Clause
import unittest
from migen import *
from litex.soc.interconnect.axi import AXIStreamInterface
class TestAXIStream(unittest.TestCase):
def test_axi_stream_syntax(self):
axis = AXIStreamInterface(data_width=32)
axis = AXIStreamInterface(data_width=32, keep_width=4)
axis = AXIStreamInterface(data_width=32, keep_width=4, id_width=4)
axis = AXIStreamInterface(data_width=32, keep_width=4, id_width=4, dest_width=4)
axis = AXIStreamInterface(data_width=32, keep_width=4, id_width=4, dest_width=4, user_width=4)
def test_axi_stream_get_ios(self):
axis = AXIStreamInterface(data_width=32, keep_width=4, id_width=4, dest_width=4, user_width=4)
pads = axis.get_ios()

View file

@ -50,3 +50,15 @@ class TestStream(unittest.TestCase):
def test_pipe_ready(self):
dut = PipeReady([("data", 8)])
self.pipe_test(dut)
def test_buffer_valid(self):
dut = Buffer([("data", 8)], pipe_valid=True, pipe_ready=False)
self.pipe_test(dut)
def test_buffer_ready(self):
dut = Buffer([("data", 8)], pipe_valid=False, pipe_ready=True)
self.pipe_test(dut)
def test_buffer_valid_ready(self):
dut = Buffer([("data", 8)], pipe_valid=True, pipe_ready=True)
self.pipe_test(dut)