mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
Merge branch 'master' into naxriscv-merge
This commit is contained in:
commit
8e7fd9bc1f
29 changed files with 587 additions and 242 deletions
48
CHANGES
48
CHANGES
|
@ -1,11 +1,33 @@
|
||||||
[> Changes since 2022.04
|
[> Changes since 2022.08
|
||||||
------------------------
|
------------------------
|
||||||
|
|
||||||
|
[> Issues resolved
|
||||||
|
------------------
|
||||||
|
|
||||||
|
[> Added Features
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
[> API changes/Deprecation
|
||||||
|
--------------------------
|
||||||
|
|
||||||
|
|
||||||
|
[> 2022.08, released on September 12th 2022
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
[> Issues resolved
|
[> Issues resolved
|
||||||
------------------
|
------------------
|
||||||
- cpu/vexriscv: Fix compilation with new binutils.
|
- cpu/vexriscv: Fix compilation with new binutils.
|
||||||
- soc/LiteXSocArgumentParser: Fix --cpu-type parsing.
|
- soc/LiteXSocArgumentParser: Fix --cpu-type parsing.
|
||||||
- litex_sim: Fix --with-ethernet.
|
- 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
|
||||||
-----------------
|
-----------------
|
||||||
|
@ -39,6 +61,29 @@
|
||||||
- soc: Add --bus-interconnect parameter to select interconect: shared/crossbar.
|
- soc: Add --bus-interconnect parameter to select interconect: shared/crossbar.
|
||||||
- valentyusb: Package and install it with LiteX.
|
- valentyusb: Package and install it with LiteX.
|
||||||
- bios/mem_list: Align Mem Regions.
|
- 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
|
||||||
--------------------------
|
--------------------------
|
||||||
|
@ -46,6 +91,7 @@
|
||||||
- tools: Rename litex_gen to litex_periph_gen.
|
- tools: Rename litex_gen to litex_periph_gen.
|
||||||
- LiteX-Boards: Only generate SoC/Software headers when --build is set
|
- LiteX-Boards: Only generate SoC/Software headers when --build is set
|
||||||
- Symbiflow: Rename to F4PGA.
|
- Symbiflow: Rename to F4PGA.
|
||||||
|
- mkmsscimg: Rename to crcfbigen.
|
||||||
|
|
||||||
[> 2022.04, released on May 3th 2022
|
[> 2022.04, released on May 3th 2022
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
59
CONTRIBUTORS
59
CONTRIBUTORS
|
@ -10,40 +10,46 @@ and we'll fix it!
|
||||||
|
|
||||||
Contributors:
|
Contributors:
|
||||||
Copyright (c) 2021 Acathla-fr <fabien@acathla.tk>
|
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) 2019 Ambroz Bizjak <ambrop7@gmail.com>
|
||||||
Copyright (c) 2021 Andreas Galauner <andreas@galauner.de>
|
Copyright (c) 2021 Andreas Galauner <andreas@galauner.de>
|
||||||
Copyright (c) 2021-2022 Andrew Dennison <andrew.dennison@motec.com.au>
|
Copyright (c) 2021-2022 Andrew Dennison <andrew.dennison@motec.com.au>
|
||||||
Copyright (c) 2021 Andwer E Wilson <lavatech.co@gmail.com>
|
Copyright (c) 2021 Andwer E Wilson <lavatech.co@gmail.com>
|
||||||
Copyright (c) 2021 Andy Kitchen <kitchen.andy+git@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 Antony Pavlov <antonynpavlov@gmail.com>
|
||||||
Copyright (c) 2019 Antti Lukats <Antti.Lukats@googlemail.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-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 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) 2021 Benjamin Henrion <zoobab@gmail.com>
|
||||||
Copyright (c) 2019-2020 Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
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) 2021 Blake Smith <blakesmith0@gmail.com>
|
||||||
Copyright (c) 2012-2013 Brandon Hamilton <brandon.hamilton@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) 2017-2021 bunnie <bunnie@kosagi.com>
|
||||||
Copyright (c) 2019 Caleb Jamison <cbjamo@gmail.com>
|
Copyright (c) 2019 Caleb Jamison <cbjamo@gmail.com>
|
||||||
Copyright (c) 2021 Camilo Andres Vera Ruiz <camilovera9811@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) 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) 2018 Chris Ballance <chris.ballance@physics.ox.ac.uk>
|
||||||
Copyright (c) 2021 Chris Osterwood <osterwood@capablerobot.com>
|
Copyright (c) 2021 Chris Osterwood <osterwood@capablerobot.com>
|
||||||
Copyright (c) 2020-2022 Christian Klarhorst <cklarhor@techfak.uni-bielefeld.de>
|
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) 2019 Daniel Kucera <daniel.kucera@gmail.com>
|
||||||
Copyright (c) 2020 Dave Marples <dave@marples.net>
|
Copyright (c) 2020 Dave Marples <dave@marples.net>
|
||||||
Copyright (c) 2013 David Carne <davidcarne@gmail.com>
|
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 Jablonski <dayjaby@gmail.com>
|
||||||
Copyright (c) 2020-2021 David Lattimore <dml@chromium.org>
|
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) 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) 2018 Deano Calver <me@deanoc.com>
|
||||||
Copyright (c) 2021-2022 developandplay <34752929+developandplay@users.noreply.github.com>
|
Copyright (c) 2021-2022 developandplay <34752929+developandplay@users.noreply.github.com>
|
||||||
Copyright (c) 2018-2022 Dolu1990 <charles.papon.90@gmail.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) 2021 Evan Lojewski <github@meklort.com>
|
||||||
Copyright (c) 2018 Ewen McNeill <ewen@naos.co.nz>
|
Copyright (c) 2018 Ewen McNeill <ewen@naos.co.nz>
|
||||||
Copyright (c) 2014 Fabien Marteau <fabien.marteau@armadeus.com>
|
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) 2020 Filipe Laíns <lains@archlinux.org>
|
||||||
Copyright (c) 2012-2022 Florent Kermarrec <florent@enjoy-digital.fr>
|
Copyright (c) 2012-2022 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
Copyright (c) 2019 Francis Lam <flam@alum.mit.edu>
|
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) 2019-2022 Gabriel L. Somlo <gsomlo@gmail.com>
|
||||||
Copyright (c) 2021 Gary Wong <gtw@gnu.org>
|
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) 2020-2021 Geert Uytterhoeven <geert@linux-m68k.org>
|
||||||
Copyright (c) 2021 George Hilliard <thirtythreeforty@gmail.com>
|
Copyright (c) 2021 George Hilliard <thirtythreeforty@gmail.com>
|
||||||
Copyright (c) 2019 Giammarco Zacheo <g.zacheo@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) 2017 Greg Darke <greg@tsukasa.net.au>
|
||||||
Copyright (c) 2020-2022 Greg Davill <greg.davill@gmail.com>
|
Copyright (c) 2020-2022 Greg Davill <greg.davill@gmail.com>
|
||||||
Copyright (c) 2021 Guillaume REMBERT <zguig52@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) 2020-2022 Gwenhael Goavec-Merou <gwenhael.goavec-merou@trabucayre.com>
|
||||||
Copyright (c) 2021 Hans Baier <hansfbaier@gmail.com>
|
Copyright (c) 2021 Hans Baier <hansfbaier@gmail.com>
|
||||||
Copyright (c) 2022 Icenowy Zheng <icenowy@aosc.io>
|
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) 2021 Jan Luebbe <jlu@pengutronix.de>
|
||||||
Copyright (c) 2014 Jannis Harder <jix@jixco.de>
|
Copyright (c) 2014 Jannis Harder <jix@jixco.de>
|
||||||
Copyright (c) 2018 Jean-François Nguyen <jf@lambdaconcept.com>
|
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) 2022 Jevin Sweval <jevinsweval@gmail.com>
|
||||||
Copyright (c) 2015 Joe Britton <joe.britton@gmail.com>
|
Copyright (c) 2015 Joe Britton <joe.britton@gmail.com>
|
||||||
Copyright (c) 2017 Joel Addison <joel@addison.net.au>
|
Copyright (c) 2017 Joel Addison <joel@addison.net.au>
|
||||||
Copyright (c) 2020-2022 Joel Stanley <joel@jms.id.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) 2019 Kees Jongenburger <kees.jongenburger@gmail.com>
|
||||||
Copyright (c) 2013 Kenneth Ryerson <kryerson@vermeer.com>
|
Copyright (c) 2013 Kenneth Ryerson <kryerson@vermeer.com>
|
||||||
Copyright (c) 2020 kessam <61152217+kessam@users.noreply.github.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 Kurt Kiefer <kekiefer@gmail.com>
|
||||||
Copyright (c) 2019 Larry Doolittle <ldoolitt@recycle.lbl.gov>
|
Copyright (c) 2019 Larry Doolittle <ldoolitt@recycle.lbl.gov>
|
||||||
Copyright (c) 2012-2013 Lars-Peter Clausen <lars@metafoo.de>
|
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 Czerski <m.czerski@ap-tech.pl>
|
||||||
Copyright (c) 2021 Marek Materzok <tilk@tilk.eu>
|
Copyright (c) 2021 Marek Materzok <tilk@tilk.eu>
|
||||||
Copyright (c) 2019 Martin Cornil <martin.cornil@railnova.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) 2021 Matt Johnston <matt@codeconstruct.com.au>
|
||||||
Copyright (c) 2017 Matt Kelly <Matthew.Joseph.Kelly@gmail.com>
|
Copyright (c) 2017 Matt Kelly <Matthew.Joseph.Kelly@gmail.com>
|
||||||
Copyright (c) 2019-2022 Michael Betz <michibetz@gmail.com>
|
Copyright (c) 2019-2022 Michael Betz <michibetz@gmail.com>
|
||||||
Copyright (c) 2012 Michael Walle <michael@walle.cc>
|
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) 2021-2022 Mikołaj Sowiński <msowinski@technosystem.com.pl>
|
||||||
Copyright (c) 2019-2021 Miodrag Milanovic <mmicko@gmail.com>
|
Copyright (c) 2019-2021 Miodrag Milanovic <mmicko@gmail.com>
|
||||||
Copyright (c) 2019 msloniewski <marcin.sloniewski@gmail.com>
|
Copyright (c) 2019 msloniewski <marcin.sloniewski@gmail.com>
|
||||||
Copyright (c) 2021 Nathaniel R. Lewis <linux.robotdude@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 Navaneeth Bhardwaj <navan93@gmail.com>
|
||||||
Copyright (c) 2021 Nick Østergaard <oe.nick@gmail.com>
|
Copyright (c) 2021 Nick Østergaard <oe.nick@gmail.com>
|
||||||
Copyright (c) 2013 Nina Engelhardt <nakengelhardt@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) 2021 Nick Østergaard <oe.nick@gmail.com>
|
||||||
Copyright (c) 2020 Owen Kirby <oskirby@gmail.com>
|
Copyright (c) 2020 Owen Kirby <oskirby@gmail.com>
|
||||||
Copyright (c) 2015 Olof Kindgren <olof.kindgren@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) 2020 Paul Sajna <sajattack@gmail.com>
|
||||||
Copyright (c) 2018 Paul Schulz <paul@mawsonlakes.org>
|
Copyright (c) 2018 Paul Schulz <paul@mawsonlakes.org>
|
||||||
Copyright (c) 2020 Pepijn de Vos <pepijndevos@gmail.com>
|
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) 2020 Piense <piense@gmail.com>
|
||||||
Copyright (c) 2017 Pierre-Olivier Vauboin <po@lambdaconcept>
|
Copyright (c) 2017 Pierre-Olivier Vauboin <po@lambdaconcept>
|
||||||
Copyright (c) 2020 Piotr Esden-Tempski <piotr@esden.net>
|
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) 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) 2020-2021 Raptor Engineering Development Team <support@raptorengineering.com>
|
||||||
Copyright (c) 2021 Ray Molenkamp <github@lazydodo.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-2016 Robert Jordens <jordens@gmail.com>
|
||||||
Copyright (c) 2013 Robert Jördens <jordens@gmail.com>
|
Copyright (c) 2013 Robert Jördens <jordens@gmail.com>
|
||||||
Copyright (c) 2021 Robert Wilbrandt <robert@stamm-wilbrandt.de>
|
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) 2015 Rohit Kumar Singh <rohit91.2008@gmail.com>
|
||||||
Copyright (c) 2021 Romain Dolbeau <romain@dolbeau.org>
|
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) 2020 rprinz08 <richard.prinz@min.at>
|
||||||
Copyright (c) 2015 Ryan Verner <ryan.verner@gmail.com>
|
Copyright (c) 2015 Ryan Verner <ryan.verner@gmail.com>
|
||||||
Copyright (c) 2020 Sadullah Canakci <sadullahcanakci@gmail.com>
|
Copyright (c) 2019-2020 Sadullah Canakci <sadullahcanakci@gmail.com>
|
||||||
Copyright (c) 2019-2021 sadullah <sadullahcanakci@gmail.com>
|
|
||||||
Copyright (c) 2020 Samuel Lindemer <samuel.lindemer@gmail.com>
|
Copyright (c) 2020 Samuel Lindemer <samuel.lindemer@gmail.com>
|
||||||
Copyright (c) 2018-2020 Sean Cross <sean@xobs.io>
|
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) 2021 Sergiu Mosanu <sm7ed@virginia.edu>
|
||||||
Copyright (c) 2017-2018 Sergiusz Bazanski <q3k@q3k.org>
|
Copyright (c) 2017-2018 Sergiusz Bazanski <q3k@q3k.org>
|
||||||
Copyright (c) 2020 Shawn Anastasio <shawn@anastas.io>
|
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) 2020 shuffle2 <godisgovernment@gmail.com>
|
||||||
Copyright (c) 2021 Simon Thornington <simon.thornington@gmail.com>
|
Copyright (c) 2021 Simon Thornington <simon.thornington@gmail.com>
|
||||||
Copyright (c) 2018-2022 Stafford Horne <shorne@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) 2020 Stéphane Gourichon <stephane.gourichon@fidergo.fr>
|
||||||
Copyright (c) 2022 Sylvain Lefebvre <sylvain.lefebvre@inria.fr>
|
Copyright (c) 2022 Sylvain Lefebvre <sylvain.lefebvre@inria.fr>
|
||||||
Copyright (c) 2021-2022 Sylvain Munaut <tnt@246tNt.com>
|
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) 2019 Tom Keddie <git@bronwenandtom.com>
|
||||||
Copyright (c) 2021-2022 tongchen126 <tongchen126@gmail.com>
|
Copyright (c) 2021-2022 tongchen126 <tongchen126@gmail.com>
|
||||||
Copyright (c) 2020 Vadim Kaushan <admin@disasm.info>
|
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) 2019 vytautasb <v.buitvydas@limemicro.com>
|
||||||
Copyright (c) 2013 Werner Almesberger <werner@almesberger.net>
|
Copyright (c) 2013 Werner Almesberger <werner@almesberger.net>
|
||||||
Copyright (c) 2015-2021 whitequark <whitequark@whitequark.org>
|
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) 2022 Wolfgang Nagele <mail@wnagele.com>
|
||||||
Copyright (c) 2013-2014 Yann Sionneau <yann.sionneau@gmail.com>
|
Copyright (c) 2021 wuhanstudio <wuhanstudio@qq.com>
|
||||||
Copyright (c) 2015 Yves Delley <hack@delley.net>
|
Copyright (c) 2022 xhe <xw897002528@gmail.com>
|
||||||
Copyright (c) 2020 Xiretza <xiretza@xiretza.xyz>
|
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) 2020 Yehowshua Immanuel <yimmanuel3@gatech.edu>
|
||||||
Copyright (c) 2021 Yoshimasa Niwa <niw@niw.at>
|
Copyright (c) 2021 Yoshimasa Niwa <niw@niw.at>
|
||||||
Copyright (c) 2015 Yves Delley <hack@delley.net>
|
Copyright (c) 2015 Yves Delley <hack@delley.net>
|
||||||
|
|
|
@ -132,6 +132,12 @@ def _resource_type(resource):
|
||||||
class ConnectorManager:
|
class ConnectorManager:
|
||||||
def __init__(self, connectors):
|
def __init__(self, connectors):
|
||||||
self.connector_table = dict()
|
self.connector_table = dict()
|
||||||
|
self.add_connector(connectors)
|
||||||
|
|
||||||
|
def add_connector(self, connectors):
|
||||||
|
if isinstance(connectors, tuple):
|
||||||
|
connectors = [connectors]
|
||||||
|
|
||||||
for connector in connectors:
|
for connector in connectors:
|
||||||
cit = iter(connector)
|
cit = iter(connector)
|
||||||
conn_name = next(cit)
|
conn_name = next(cit)
|
||||||
|
@ -162,7 +168,10 @@ class ConnectorManager:
|
||||||
if pn.isdigit():
|
if pn.isdigit():
|
||||||
pn = int(pn)
|
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:
|
else:
|
||||||
r.append(identifier)
|
r.append(identifier)
|
||||||
|
|
||||||
|
@ -193,6 +202,9 @@ class ConstraintManager:
|
||||||
def add_extension(self, io):
|
def add_extension(self, io):
|
||||||
self.available.extend(io)
|
self.available.extend(io)
|
||||||
|
|
||||||
|
def add_connector(self, connectors):
|
||||||
|
self.connector_manager.add_connector(connectors)
|
||||||
|
|
||||||
def request(self, name, number=None, loose=False):
|
def request(self, name, number=None, loose=False):
|
||||||
resource = _lookup(self.available, name, number, loose)
|
resource = _lookup(self.available, name, number, loose)
|
||||||
if resource is None:
|
if resource is None:
|
||||||
|
@ -356,6 +368,9 @@ class GenericPlatform:
|
||||||
def add_extension(self, *args, **kwargs):
|
def add_extension(self, *args, **kwargs):
|
||||||
return self.constraint_manager.add_extension(*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):
|
def finalize(self, fragment, *args, **kwargs):
|
||||||
if self.finalized:
|
if self.finalized:
|
||||||
raise ConstraintError("Already finalized")
|
raise ConstraintError("Already finalized")
|
||||||
|
|
|
@ -16,10 +16,11 @@ from litex.build.xilinx.vivado import _xdc_separator, _build_xdc
|
||||||
from litex.build import tools
|
from litex.build import tools
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from f4pga import Flow, make_flow_config
|
from f4pga.flows.flow import Flow
|
||||||
from f4pga.common import set_verbosity_level
|
from f4pga.flows.commands import make_flow_config
|
||||||
from f4pga.cache import F4Cache
|
from f4pga.flows.common import set_verbosity_level
|
||||||
from f4pga.flow_config import ProjectFlowConfig
|
from f4pga.flows.cache import F4Cache
|
||||||
|
from f4pga.flows.flow_config import ProjectFlowConfig
|
||||||
except ModuleNotFoundError as e:
|
except ModuleNotFoundError as e:
|
||||||
raise ModuleNotFoundError("Try getting/updating F4PGA tool (https://github.com/chipsalliance/f4pga/)") from 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
29
litex/soc/cores/cpu/naxriscv/core.py
Normal file → Executable file
|
@ -196,6 +196,7 @@ class NaxRiscv(CPU):
|
||||||
md5_hash.update(str(NaxRiscv.xlen).encode('utf-8'))
|
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_tap).encode('utf-8'))
|
||||||
md5_hash.update(str(NaxRiscv.jtag_instruction).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:
|
for args in NaxRiscv.scala_args:
|
||||||
md5_hash.update(args.encode('utf-8'))
|
md5_hash.update(args.encode('utf-8'))
|
||||||
for file in NaxRiscv.scala_paths:
|
for file in NaxRiscv.scala_paths:
|
||||||
|
@ -227,7 +228,7 @@ class NaxRiscv(CPU):
|
||||||
ndir = os.path.join(vdir, "ext", "NaxRiscv")
|
ndir = os.path.join(vdir, "ext", "NaxRiscv")
|
||||||
sdir = os.path.join(vdir, "ext", "SpinalHDL")
|
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")
|
NaxRiscv.git_setup("SpinalHDL", sdir, "https://github.com/SpinalHDL/SpinalHDL.git", "dev" , "a130f7b7")
|
||||||
|
|
||||||
gen_args = []
|
gen_args = []
|
||||||
|
@ -235,6 +236,8 @@ class NaxRiscv(CPU):
|
||||||
gen_args.append(f"--netlist-directory={vdir}")
|
gen_args.append(f"--netlist-directory={vdir}")
|
||||||
gen_args.append(f"--reset-vector={reset_address}")
|
gen_args.append(f"--reset-vector={reset_address}")
|
||||||
gen_args.append(f"--xlen={NaxRiscv.xlen}")
|
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:
|
for args in NaxRiscv.scala_args:
|
||||||
gen_args.append(f"--scala-args={args}")
|
gen_args.append(f"--scala-args={args}")
|
||||||
if(NaxRiscv.jtag_tap) :
|
if(NaxRiscv.jtag_tap) :
|
||||||
|
@ -395,6 +398,7 @@ class NaxRiscv(CPU):
|
||||||
o_peripheral_clint_rresp = clintbus.r.resp,
|
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))
|
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):
|
def add_memory_buses(self, address_width, data_width):
|
||||||
nax_data_width = 64
|
nax_data_width = 64
|
||||||
|
@ -463,8 +467,29 @@ class NaxRiscv(CPU):
|
||||||
|
|
||||||
def do_finalize(self):
|
def do_finalize(self):
|
||||||
assert hasattr(self, "reset_address")
|
assert hasattr(self, "reset_address")
|
||||||
|
|
||||||
self.find_scala_files()
|
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)
|
self.generate_netlist_name(self.reset_address)
|
||||||
|
|
||||||
# Do verilog instance.
|
# Do verilog instance.
|
||||||
|
|
|
@ -260,7 +260,7 @@ class VexRiscvSMP(CPU):
|
||||||
gen_args.append(f"--aes-instruction={VexRiscvSMP.aes_instruction}")
|
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"--out-of-order-decoder={VexRiscvSMP.out_of_order_decoder}")
|
||||||
gen_args.append(f"--wishbone-memory={VexRiscvSMP.wishbone_memory}")
|
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"--fpu={VexRiscvSMP.with_fpu}")
|
||||||
gen_args.append(f"--cpu-per-fpu={VexRiscvSMP.cpu_per_fpu}")
|
gen_args.append(f"--cpu-per-fpu={VexRiscvSMP.cpu_per_fpu}")
|
||||||
gen_args.append(f"--rvc={VexRiscvSMP.with_rvc}")
|
gen_args.append(f"--rvc={VexRiscvSMP.with_rvc}")
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
# This file is part of LiteX.
|
# This file is part of LiteX.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2014-2015 Robert Jordens <jordens@gmail.com>
|
# Copyright (c) 2014-2015 Robert Jordens <jordens@gmail.com>
|
||||||
|
# Copyright (c) 2022 Florent Kermarrec <florent@enjoy-digital.fr>
|
||||||
# SPDX-License-Identifier: BSD-2-Clause
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
from migen import *
|
from migen import *
|
||||||
|
@ -12,34 +13,36 @@ from litex.soc.interconnect.csr import *
|
||||||
# Xilinx DNA (Device Identifier) -------------------------------------------------------------------
|
# Xilinx DNA (Device Identifier) -------------------------------------------------------------------
|
||||||
|
|
||||||
class DNA(Module, AutoCSR):
|
class DNA(Module, AutoCSR):
|
||||||
|
nbits = 57
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
n = 57
|
self._id = CSRStatus(self.nbits)
|
||||||
self._id = CSRStatus(n)
|
|
||||||
|
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
self.do = do = Signal()
|
# Create slow DNA Clk (sys_clk/16).
|
||||||
self.count = count = Signal(max=2*n + 1)
|
self.clock_domains.cd_dna = ClockDomain()
|
||||||
self.clk = clk = Signal()
|
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",
|
self.specials += Instance("DNA_PORT",
|
||||||
i_DIN = self._id.status[-1],
|
i_CLK = ClockSignal("dna"),
|
||||||
o_DOUT = do,
|
i_READ = (count == 0),
|
||||||
i_CLK = clk,
|
i_SHIFT = 1,
|
||||||
i_READ = count < 2,
|
i_DIN = 0,
|
||||||
i_SHIFT = 1
|
o_DOUT = dout,
|
||||||
)
|
)
|
||||||
|
self.sync.dna += [
|
||||||
self.sync += [
|
If(count < (self.nbits + 1),
|
||||||
If(count < 2*n,
|
|
||||||
count.eq(count + 1),
|
count.eq(count + 1),
|
||||||
If(clk,
|
self._id.status.eq(Cat(dout, self._id.status))
|
||||||
self._id.status.eq(Cat(do, self._id.status))
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
|
|
||||||
def add_timing_constraints(self, platform, sys_clk_freq, sys_clk):
|
def add_timing_constraints(self, platform, sys_clk_freq, sys_clk):
|
||||||
platform.add_period_constraint(self.clk, 2*1e9/sys_clk_freq)
|
platform.add_period_constraint(self.cd_dna.clk, 16*1e9/sys_clk_freq)
|
||||||
platform.add_false_path_constraints(self.clk, sys_clk)
|
platform.add_false_path_constraints(self.cd_dna.clk, sys_clk)
|
||||||
|
|
|
@ -809,6 +809,52 @@ class VideoHDMIPHY(Module):
|
||||||
)
|
)
|
||||||
setattr(self.submodules, f"{color}_serializer", serializer)
|
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).
|
# HDMI (Xilinx Spartan6).
|
||||||
|
|
||||||
class VideoS6HDMIPHY(Module):
|
class VideoS6HDMIPHY(Module):
|
||||||
|
|
|
@ -69,11 +69,10 @@ class Builder:
|
||||||
include_dir = None,
|
include_dir = None,
|
||||||
generated_dir = None,
|
generated_dir = None,
|
||||||
|
|
||||||
# Compile Options.
|
# Compilation.
|
||||||
compile_software = True,
|
compile_software = True,
|
||||||
compile_gateware = True,
|
compile_gateware = True,
|
||||||
build_backend = "litex",
|
build_backend = "litex",
|
||||||
lto = False,
|
|
||||||
|
|
||||||
# Exports.
|
# Exports.
|
||||||
csr_json = None,
|
csr_json = None,
|
||||||
|
@ -81,8 +80,9 @@ class Builder:
|
||||||
csr_svd = None,
|
csr_svd = None,
|
||||||
memory_x = None,
|
memory_x = None,
|
||||||
|
|
||||||
# BIOS Options.
|
# BIOS.
|
||||||
bios_options = [],
|
bios_lto = False,
|
||||||
|
bios_console = "full",
|
||||||
|
|
||||||
# Documentation.
|
# Documentation.
|
||||||
generate_doc = False):
|
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.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"))
|
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_software = compile_software
|
||||||
self.compile_gateware = compile_gateware
|
self.compile_gateware = compile_gateware
|
||||||
self.build_backend = build_backend
|
self.build_backend = build_backend
|
||||||
self.lto = lto
|
|
||||||
|
|
||||||
# Exports.
|
# Exports.
|
||||||
self.csr_csv = csr_csv
|
self.csr_csv = csr_csv
|
||||||
|
@ -108,16 +107,16 @@ class Builder:
|
||||||
self.csr_svd = csr_svd
|
self.csr_svd = csr_svd
|
||||||
self.memory_x = memory_x
|
self.memory_x = memory_x
|
||||||
|
|
||||||
# BIOS Options.
|
# BIOS.
|
||||||
self.bios_options = bios_options
|
self.bios_lto = bios_lto
|
||||||
|
self.bios_console = bios_console
|
||||||
|
|
||||||
# Documentation
|
# Documentation.
|
||||||
self.generate_doc = generate_doc
|
self.generate_doc = generate_doc
|
||||||
|
|
||||||
# List software packages and libraries.
|
# Software packages and libraries.
|
||||||
self.software_packages = []
|
self.software_packages = []
|
||||||
self.software_libraries = []
|
self.software_libraries = []
|
||||||
|
|
||||||
for name in soc_software_packages:
|
for name in soc_software_packages:
|
||||||
self.add_software_package(name)
|
self.add_software_package(name)
|
||||||
self.add_software_library(name)
|
self.add_software_library(name)
|
||||||
|
@ -134,6 +133,7 @@ class Builder:
|
||||||
# Helper.
|
# Helper.
|
||||||
variables_contents = []
|
variables_contents = []
|
||||||
def define(k, v):
|
def define(k, v):
|
||||||
|
k = k.replace("-", "_")
|
||||||
try:
|
try:
|
||||||
variables_contents.append("{}={}".format(k, _makefile_escape(v)))
|
variables_contents.append("{}={}".format(k, _makefile_escape(v)))
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
|
@ -161,11 +161,10 @@ class Builder:
|
||||||
for name, src_dir in self.software_packages:
|
for name, src_dir in self.software_packages:
|
||||||
define(name.upper() + "_DIRECTORY", src_dir)
|
define(name.upper() + "_DIRECTORY", src_dir)
|
||||||
|
|
||||||
# Define Compile/BIOS Options.
|
# Define BIOS variables.
|
||||||
define("LTO", f"{self.lto:d}")
|
define("LTO", f"{self.bios_lto:d}")
|
||||||
for bios_option in self.bios_options:
|
assert self.bios_console in ["full", "no-history", "no-autocomplete", "lite", "disable"]
|
||||||
assert bios_option in ["TERM_NO_HIST", "TERM_MINI", "TERM_NO_COMPLETE"]
|
define(f"BIOS_CONSOLE_{self.bios_console.upper()}", "1")
|
||||||
define(bios_option, "1")
|
|
||||||
|
|
||||||
return "\n".join(variables_contents)
|
return "\n".join(variables_contents)
|
||||||
|
|
||||||
|
@ -257,10 +256,15 @@ class Builder:
|
||||||
meson_minor_min = 59
|
meson_minor_min = 59
|
||||||
if meson_present:
|
if meson_present:
|
||||||
meson_version = subprocess.check_output(["meson", "-v"]).decode("utf-8").split(".")
|
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 = "Unable to find valid Meson build system, please install it with:\n"
|
||||||
msg += "- pip3 install meson.\n"
|
msg += "- pip3 install meson.\n"
|
||||||
raise OSError(msg)
|
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):
|
def _prepare_rom_software(self):
|
||||||
# Create directories for all software packages.
|
# Create directories for all software packages.
|
||||||
|
@ -283,7 +287,10 @@ class Builder:
|
||||||
def _initialize_rom_software(self):
|
def _initialize_rom_software(self):
|
||||||
# Get BIOS data from compiled BIOS binary.
|
# Get BIOS data from compiled BIOS binary.
|
||||||
bios_file = os.path.join(self.software_dir, "bios", "bios.bin")
|
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.
|
# Initialize SoC with with BIOS data.
|
||||||
self.soc.initialize_rom(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", 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-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("--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-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-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("--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("--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.")
|
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):
|
def builder_argdict(args):
|
||||||
return {
|
return {
|
||||||
|
@ -409,10 +418,11 @@ def builder_argdict(args):
|
||||||
"build_backend" : args.build_backend,
|
"build_backend" : args.build_backend,
|
||||||
"compile_software" : (not args.no_compile) and (not args.no_compile_software),
|
"compile_software" : (not args.no_compile) and (not args.no_compile_software),
|
||||||
"compile_gateware" : (not args.no_compile) and (not args.no_compile_gateware),
|
"compile_gateware" : (not args.no_compile) and (not args.no_compile_gateware),
|
||||||
"lto" : args.lto,
|
|
||||||
"csr_csv" : args.csr_csv,
|
"csr_csv" : args.csr_csv,
|
||||||
"csr_json" : args.csr_json,
|
"csr_json" : args.csr_json,
|
||||||
"csr_svd" : args.csr_svd,
|
"csr_svd" : args.csr_svd,
|
||||||
"memory_x" : args.memory_x,
|
"memory_x" : args.memory_x,
|
||||||
"generate_doc" : args.doc,
|
"generate_doc" : args.doc,
|
||||||
|
"bios_lto" : args.bios_lto,
|
||||||
|
"bios_console" : args.bios_console,
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,8 @@ def get_mem_regions(filename_or_regions, offset):
|
||||||
regions = {filename: f"{offset:08x}"}
|
regions = {filename: f"{offset:08x}"}
|
||||||
return regions
|
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.
|
# Create memory regions.
|
||||||
regions = get_mem_regions(filename_or_regions, offset)
|
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))
|
data_size, mem_size))
|
||||||
|
|
||||||
# Fill data.
|
# 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():
|
for filename, base in regions.items():
|
||||||
base = int(base, 16)
|
base = int(base, 16)
|
||||||
with open(filename, "rb") as f:
|
with open(filename, "rb") as f:
|
||||||
i = 0
|
i = 0
|
||||||
while True:
|
while True:
|
||||||
w = f.read(4)
|
w = f.read(bytes_per_data)
|
||||||
if not w:
|
if not w:
|
||||||
break
|
break
|
||||||
if len(w) != 4:
|
if len(w) != bytes_per_data:
|
||||||
for _ in range(len(w), 4):
|
for _ in range(len(w), bytes_per_data):
|
||||||
w += b'\x00'
|
w += b'\x00'
|
||||||
unpack_order = {
|
unpack_order = {
|
||||||
"little": "<I",
|
"little": "<I",
|
||||||
"big": ">I"
|
"big": ">I"
|
||||||
}[endianness]
|
}[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
|
i += 1
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
36
litex/soc/integration/soc.py
Normal file → Executable file
36
litex/soc/integration/soc.py
Normal file → Executable file
|
@ -332,7 +332,10 @@ class SoCBusHandler(Module):
|
||||||
axi.AXILiteInterface : axi.AXILiteConverter,
|
axi.AXILiteInterface : axi.AXILiteConverter,
|
||||||
axi.AXIInterface : axi.AXIConverter,
|
axi.AXIInterface : axi.AXIConverter,
|
||||||
}[interface_cls]
|
}[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":
|
if direction == "m2s":
|
||||||
master, slave = interface, adapted_interface
|
master, slave = interface, adapted_interface
|
||||||
elif direction == "s2m":
|
elif direction == "s2m":
|
||||||
|
@ -353,7 +356,10 @@ class SoCBusHandler(Module):
|
||||||
return interface
|
return interface
|
||||||
# Different Bus-Standard: Return adapted interface.
|
# Different Bus-Standard: Return adapted interface.
|
||||||
else:
|
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":
|
if direction == "m2s":
|
||||||
master, slave = interface, adapted_interface
|
master, slave = interface, adapted_interface
|
||||||
elif direction == "s2m":
|
elif direction == "s2m":
|
||||||
|
@ -886,7 +892,7 @@ class SoC(Module):
|
||||||
colorer("added", color="green")))
|
colorer("added", color="green")))
|
||||||
setattr(self.submodules, name, SoCController(**kwargs))
|
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 = {
|
ram_cls = {
|
||||||
"wishbone": wishbone.SRAM,
|
"wishbone": wishbone.SRAM,
|
||||||
"axi-lite": axi.AXILiteSRAM,
|
"axi-lite": axi.AXILiteSRAM,
|
||||||
|
@ -897,8 +903,12 @@ class SoC(Module):
|
||||||
"axi-lite": axi.AXILiteInterface,
|
"axi-lite": axi.AXILiteInterface,
|
||||||
"axi" : axi.AXILiteInterface, # FIXME: Use AXI-Lite for now, create AXISRAM.
|
"axi" : axi.AXILiteInterface, # FIXME: Use AXI-Lite for now, create AXISRAM.
|
||||||
}[self.bus.standard]
|
}[self.bus.standard]
|
||||||
ram_bus = interface_cls(data_width=self.bus.data_width, bursting=self.bus.bursting)
|
ram_bus = interface_cls(
|
||||||
ram = ram_cls(size, bus=ram_bus, init=contents, read_only=(mode == "r"), name=name)
|
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.bus.add_slave(name, ram.bus, SoCRegion(origin=origin, size=size, mode=mode))
|
||||||
self.check_if_exists(name)
|
self.check_if_exists(name)
|
||||||
self.logger.info("RAM {} {} {}.".format(
|
self.logger.info("RAM {} {} {}.".format(
|
||||||
|
@ -909,7 +919,7 @@ class SoC(Module):
|
||||||
if contents != []:
|
if contents != []:
|
||||||
self.add_config(f"{name}_INIT", 1)
|
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)
|
self.add_ram(name, origin, size, contents, mode=mode)
|
||||||
|
|
||||||
def init_rom(self, name, contents=[], auto_size=True):
|
def init_rom(self, name, contents=[], auto_size=True):
|
||||||
|
@ -917,7 +927,7 @@ class SoC(Module):
|
||||||
colorer(name),
|
colorer(name),
|
||||||
colorer(f"0x{4*len(contents):x}")))
|
colorer(f"0x{4*len(contents):x}")))
|
||||||
getattr(self, name).mem.init = contents
|
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(
|
self.logger.info("Auto-Resizing ROM {} from {} to {}.".format(
|
||||||
colorer(name),
|
colorer(name),
|
||||||
colorer(f"0x{self.bus.regions[name].size:x}"),
|
colorer(f"0x{self.bus.regions[name].size:x}"),
|
||||||
|
@ -1475,7 +1485,11 @@ class LiteXSoC(SoC):
|
||||||
sdram_size = min(sdram_size, size)
|
sdram_size = min(sdram_size, size)
|
||||||
|
|
||||||
# Add SDRAM region.
|
# 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) ----------------------------------
|
# Add CPU's direct memory buses (if not already declared) ----------------------------------
|
||||||
if hasattr(self.cpu, "add_memory_buses"):
|
if hasattr(self.cpu, "add_memory_buses"):
|
||||||
|
@ -1906,7 +1920,7 @@ class LiteXSoC(SoC):
|
||||||
if "write" in mode:
|
if "write" in mode:
|
||||||
self.comb += self.sata_irq.mem2sector_dma.trigger.eq(self.sata_mem2sector.irq)
|
self.comb += self.sata_irq.mem2sector_dma.trigger.eq(self.sata_mem2sector.irq)
|
||||||
if self.irq.enabled:
|
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.
|
# Timing constraints.
|
||||||
self.platform.add_period_constraint(self.sata_phy.crg.cd_sata_tx.clk, 1e9/sata_clk_freq)
|
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,
|
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_buffering = True, dma_buffering_depth=1024,
|
||||||
with_dma_loopback = True,
|
with_dma_loopback = True,
|
||||||
with_msi = True):
|
with_msi = True,
|
||||||
|
with_synchronizer = False):
|
||||||
# Imports
|
# Imports
|
||||||
from litepcie.core import LitePCIeEndpoint, LitePCIeMSI
|
from litepcie.core import LitePCIeEndpoint, LitePCIeMSI
|
||||||
from litepcie.frontend.dma import LitePCIeDMA
|
from litepcie.frontend.dma import LitePCIeDMA
|
||||||
|
@ -1959,6 +1974,7 @@ class LiteXSoC(SoC):
|
||||||
dma = LitePCIeDMA(phy, endpoint,
|
dma = LitePCIeDMA(phy, endpoint,
|
||||||
with_buffering = with_dma_buffering, buffering_depth=dma_buffering_depth,
|
with_buffering = with_dma_buffering, buffering_depth=dma_buffering_depth,
|
||||||
with_loopback = with_dma_loopback,
|
with_loopback = with_dma_loopback,
|
||||||
|
with_synchronizer = with_synchronizer,
|
||||||
address_width = address_width
|
address_width = address_width
|
||||||
)
|
)
|
||||||
setattr(self.submodules, f"{name}_dma{i}", dma)
|
setattr(self.submodules, f"{name}_dma{i}", dma)
|
||||||
|
|
|
@ -78,7 +78,7 @@ class SoCCore(LiteXSoC):
|
||||||
|
|
||||||
# ROM parameters
|
# ROM parameters
|
||||||
integrated_rom_size = 0,
|
integrated_rom_size = 0,
|
||||||
integrated_rom_mode = "r",
|
integrated_rom_mode = "rx",
|
||||||
integrated_rom_init = [],
|
integrated_rom_init = [],
|
||||||
|
|
||||||
# SRAM parameters
|
# SRAM parameters
|
||||||
|
@ -156,7 +156,10 @@ class SoCCore(LiteXSoC):
|
||||||
# ROM.
|
# ROM.
|
||||||
# Initialize ROM from binary file when provided.
|
# Initialize ROM from binary file when provided.
|
||||||
if isinstance(integrated_rom_init, str):
|
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)
|
integrated_rom_size = 4*len(integrated_rom_init)
|
||||||
|
|
||||||
# Disable ROM when no CPU/hard-CPU.
|
# Disable ROM when no CPU/hard-CPU.
|
||||||
|
|
|
@ -18,53 +18,73 @@ from litex.soc.interconnect.axi.axi_common import *
|
||||||
|
|
||||||
# AXI Definition -----------------------------------------------------------------------------------
|
# AXI Definition -----------------------------------------------------------------------------------
|
||||||
|
|
||||||
def ax_description(address_width, id_width):
|
def ax_description(address_width, id_width=0, user_width=0):
|
||||||
return [
|
# * present for interconnect with others cores but not used by LiteX.
|
||||||
("addr", address_width),
|
ax = [
|
||||||
("burst", 2), # Burst type
|
("addr", address_width), # Address Width.
|
||||||
("len", 8), # Number of data (-1) transfers (up to 256)
|
("burst", 2), # Burst type.
|
||||||
("size", 4), # Number of bytes (-1) of each data transfer (up to 1024 bits)
|
("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), # *
|
("lock", 2), # *
|
||||||
("prot", 3), # *
|
("prot", 3), # *
|
||||||
("cache", 4), # *
|
("cache", 4), # *
|
||||||
("qos", 4), # *
|
("qos", 4), # *
|
||||||
("id", id_width)
|
("region", 4), # *
|
||||||
]
|
]
|
||||||
# * present for interconnect with others cores but not used by LiteX.
|
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):
|
def w_description(data_width, id_width=0, user_width=0):
|
||||||
return [
|
w = [
|
||||||
("data", data_width),
|
("data", data_width),
|
||||||
("strb", data_width//8),
|
("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):
|
def b_description(id_width=0, user_width=0):
|
||||||
return [
|
b = [("resp", 2)]
|
||||||
("resp", 2),
|
if id_width:
|
||||||
("id", id_width)
|
b += [("id", id_width)]
|
||||||
]
|
if user_width:
|
||||||
|
b += [("user", user_width)]
|
||||||
|
return b
|
||||||
|
|
||||||
def r_description(data_width, id_width):
|
def r_description(data_width, id_width=0, user_width=0):
|
||||||
return [
|
r = [
|
||||||
("resp", 2),
|
("resp", 2),
|
||||||
("data", data_width),
|
("data", data_width),
|
||||||
("id", id_width)
|
|
||||||
]
|
]
|
||||||
|
if id_width:
|
||||||
|
r += [("id", id_width)]
|
||||||
|
if user_width:
|
||||||
|
r += [("user", user_width)]
|
||||||
|
return r
|
||||||
|
|
||||||
class AXIInterface:
|
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.data_width = data_width
|
||||||
self.address_width = address_width
|
self.address_width = address_width
|
||||||
self.id_width = id_width
|
self.id_width = id_width
|
||||||
self.clock_domain = clock_domain
|
self.clock_domain = clock_domain
|
||||||
self.bursting = bursting # FIXME: Use or add check.
|
self.bursting = bursting # FIXME: Use or add check.
|
||||||
|
|
||||||
self.aw = stream.Endpoint(ax_description(address_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), 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), 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), 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), 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"):
|
def connect_to_pads(self, pads, mode="master"):
|
||||||
return connect_to_pads(self, pads, mode, axi_full=True)
|
return connect_to_pads(self, pads, mode, axi_full=True)
|
||||||
|
|
|
@ -19,7 +19,11 @@ from litex.soc.interconnect.axi.axi_common import *
|
||||||
# AXI-Lite Definition ------------------------------------------------------------------------------
|
# AXI-Lite Definition ------------------------------------------------------------------------------
|
||||||
|
|
||||||
def ax_lite_description(address_width):
|
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):
|
def w_lite_description(data_width):
|
||||||
return [
|
return [
|
||||||
|
|
|
@ -17,27 +17,48 @@ from litex.soc.interconnect.axi.axi_common import *
|
||||||
# AXI-Stream Definition ----------------------------------------------------------------------------
|
# AXI-Stream Definition ----------------------------------------------------------------------------
|
||||||
|
|
||||||
class AXIStreamInterface(stream.Endpoint):
|
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.data_width = data_width
|
||||||
self.keep_width = keep_width
|
self.keep_width = keep_width
|
||||||
|
self.id_width = id_width
|
||||||
|
self.dest_width = dest_width
|
||||||
self.user_width = user_width
|
self.user_width = user_width
|
||||||
|
|
||||||
|
# Define Payload Layout.
|
||||||
payload_layout = [("data", data_width)]
|
payload_layout = [("data", data_width)]
|
||||||
if self.keep_width:
|
if self.keep_width:
|
||||||
payload_layout += [("keep", keep_width)]
|
payload_layout += [("keep", keep_width)]
|
||||||
|
|
||||||
|
# Define Param Layout.
|
||||||
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:
|
if self.user_width:
|
||||||
param_layout += [("user", user_width)]
|
param_layout += [("user", user_width)]
|
||||||
|
|
||||||
|
# Create Endpoint.
|
||||||
stream.Endpoint.__init__(self, stream.EndpointDescription(payload_layout, param_layout))
|
stream.Endpoint.__init__(self, stream.EndpointDescription(payload_layout, param_layout))
|
||||||
|
|
||||||
def get_ios(self, bus_name="axi"):
|
def get_ios(self, bus_name="axi"):
|
||||||
|
# Control Signals.
|
||||||
subsignals = [
|
subsignals = [
|
||||||
Subsignal("tvalid", Pins(1)),
|
Subsignal("tvalid", Pins(1)),
|
||||||
Subsignal("tlast", Pins(1)),
|
Subsignal("tlast", Pins(1)),
|
||||||
Subsignal("tready", 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:
|
if self.keep_width:
|
||||||
subsignals += [Subsignal("tkeep", Pins(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:
|
if self.user_width:
|
||||||
subsignals += [Subsignal("tuser", Pins(self.user_width))]
|
subsignals += [Subsignal("tuser", Pins(self.user_width))]
|
||||||
ios = [(bus_name , 0) + tuple(subsignals)]
|
ios = [(bus_name , 0) + tuple(subsignals)]
|
||||||
|
@ -47,21 +68,35 @@ class AXIStreamInterface(stream.Endpoint):
|
||||||
assert mode in ["slave", "master"]
|
assert mode in ["slave", "master"]
|
||||||
r = []
|
r = []
|
||||||
if mode == "master":
|
if mode == "master":
|
||||||
|
# Control Signals.
|
||||||
r.append(pads.tvalid.eq(self.valid))
|
r.append(pads.tvalid.eq(self.valid))
|
||||||
r.append(self.ready.eq(pads.tready))
|
r.append(self.ready.eq(pads.tready))
|
||||||
r.append(pads.tlast.eq(self.last))
|
r.append(pads.tlast.eq(self.last))
|
||||||
|
# Payload Signals.
|
||||||
r.append(pads.tdata.eq(self.data))
|
r.append(pads.tdata.eq(self.data))
|
||||||
if self.keep_width:
|
if self.keep_width:
|
||||||
r.append(pads.tkeep.eq(self.keep))
|
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:
|
if self.user_width:
|
||||||
r.append(pads.tuser.eq(self.user))
|
r.append(pads.tuser.eq(self.user))
|
||||||
if mode == "slave":
|
if mode == "slave":
|
||||||
|
# Control Signals.
|
||||||
r.append(self.valid.eq(pads.tvalid))
|
r.append(self.valid.eq(pads.tvalid))
|
||||||
r.append(pads.tready.eq(self.ready))
|
r.append(pads.tready.eq(self.ready))
|
||||||
r.append(self.last.eq(pads.tlast))
|
r.append(self.last.eq(pads.tlast))
|
||||||
|
# Payload Signals.
|
||||||
r.append(self.data.eq(pads.tdata))
|
r.append(self.data.eq(pads.tdata))
|
||||||
if self.keep_width:
|
if self.keep_width:
|
||||||
r.append(self.keep.eq(pads.tkeep))
|
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:
|
if self.user_width:
|
||||||
r.append(self.user.eq(pads.tuser))
|
r.append(self.user.eq(pads.tuser))
|
||||||
return r
|
return r
|
||||||
|
|
|
@ -766,7 +766,32 @@ class PipeReady(Module):
|
||||||
|
|
||||||
# Buffer -------------------------------------------------------------------------------------------
|
# 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 ---------------------------------------------------------------------------------------------
|
# Cast ---------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -46,8 +46,11 @@ CTI_BURST_END = 0b111
|
||||||
|
|
||||||
|
|
||||||
class Interface(Record):
|
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.data_width = data_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.adr_width = adr_width
|
||||||
self.bursting = bursting
|
self.bursting = bursting
|
||||||
Record.__init__(self, set_layout_parameters(_layout,
|
Record.__init__(self, set_layout_parameters(_layout,
|
||||||
|
@ -258,41 +261,39 @@ class DownConverter(Module):
|
||||||
# # #
|
# # #
|
||||||
|
|
||||||
skip = Signal()
|
skip = Signal()
|
||||||
counter = Signal(max=ratio)
|
done = Signal()
|
||||||
|
count = Signal(max=ratio)
|
||||||
|
|
||||||
# Control Path
|
# Control Path.
|
||||||
fsm = FSM(reset_state="IDLE")
|
self.comb += [
|
||||||
fsm = ResetInserter()(fsm)
|
done.eq(count == (ratio - 1)),
|
||||||
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)}),
|
|
||||||
If(master.stb & master.cyc,
|
If(master.stb & master.cyc,
|
||||||
skip.eq(slave.sel == 0),
|
skip.eq(slave.sel == 0),
|
||||||
slave.we.eq(master.we),
|
|
||||||
slave.cyc.eq(~skip),
|
slave.cyc.eq(~skip),
|
||||||
slave.stb.eq(~skip),
|
slave.stb.eq(~skip),
|
||||||
|
slave.we.eq(master.we),
|
||||||
If(slave.ack | skip,
|
If(slave.ack | skip,
|
||||||
NextValue(counter, counter + 1),
|
master.ack.eq(done)
|
||||||
If(counter == (ratio - 1),
|
|
||||||
master.ack.eq(1),
|
|
||||||
NextState("IDLE")
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
]
|
||||||
|
self.sync += [
|
||||||
|
If((slave.stb & slave.cyc & slave.ack) | skip,
|
||||||
|
count.eq(count + 1)
|
||||||
|
),
|
||||||
|
If(master.ack | ~master.cyc,
|
||||||
|
count.eq(0)
|
||||||
)
|
)
|
||||||
|
]
|
||||||
|
|
||||||
# Write Datapath
|
# Address.
|
||||||
self.comb += Case(counter, {i: slave.dat_w.eq(master.dat_w[i*dw_to:]) for i in range(ratio)})
|
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)
|
dat_r = Signal(dw_from, reset_less=True)
|
||||||
self.comb += master.dat_r.eq(Cat(dat_r[dw_to:], slave.dat_r))
|
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))
|
self.sync += If(slave.ack | skip, dat_r.eq(master.dat_r))
|
||||||
|
|
|
@ -21,18 +21,22 @@ OBJECTS = boot-helper.o \
|
||||||
sim_debug.o \
|
sim_debug.o \
|
||||||
main.o
|
main.o
|
||||||
|
|
||||||
ifneq "$(or $(TERM_NO_COMPLETE),$(TERM_MINI))" ""
|
ifneq "$(or $(BIOS_CONSOLE_NO_AUTOCOMPLETE),$(BIOS_CONSOLE_LITE))" ""
|
||||||
CFLAGS += -DTERM_NO_COMPLETE
|
CFLAGS += -DBIOS_CONSOLE_NO_AUTOCOMPLETE
|
||||||
else
|
else
|
||||||
OBJECTS += complete.o
|
OBJECTS += complete.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef TERM_NO_HIST
|
ifdef BIOS_CONSOLE_NO_HISTORY
|
||||||
CFLAGS += -DTERM_NO_HIST
|
CFLAGS += -DBIOS_CONSOLE_NO_HISTORY
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef TERM_MINI
|
ifdef BIOS_CONSOLE_DISABLE
|
||||||
CFLAGS += -DTERM_MINI
|
CFLAGS += -DBIOS_CONSOLE_DISABLE
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifdef BIOS_CONSOLE_LITE
|
||||||
|
CFLAGS += -DBIOS_CONSOLE_LITE
|
||||||
OBJECTS += readline_simple.o
|
OBJECTS += readline_simple.o
|
||||||
else
|
else
|
||||||
OBJECTS += readline.o
|
OBJECTS += readline.o
|
||||||
|
|
|
@ -32,6 +32,9 @@ struct command_struct {
|
||||||
extern struct command_struct *const __bios_cmd_start[];
|
extern struct command_struct *const __bios_cmd_start[];
|
||||||
extern struct command_struct *const __bios_cmd_end[];
|
extern struct command_struct *const __bios_cmd_end[];
|
||||||
|
|
||||||
|
#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) \
|
#define define_command(cmd_name, handler, help_txt, group_id) \
|
||||||
struct command_struct s_##cmd_name = { \
|
struct command_struct s_##cmd_name = { \
|
||||||
.func = (cmd_handler)handler, \
|
.func = (cmd_handler)handler, \
|
||||||
|
@ -42,7 +45,7 @@ extern struct command_struct *const __bios_cmd_end[];
|
||||||
const struct command_struct *__bios_cmd_##cmd_name __attribute__((__used__)) \
|
const struct command_struct *__bios_cmd_##cmd_name __attribute__((__used__)) \
|
||||||
__attribute__((__section__(".bios_cmd"))) = &s_##cmd_name
|
__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
|
|
@ -80,11 +80,13 @@ static void boot_sequence(void)
|
||||||
|
|
||||||
__attribute__((__used__)) int main(int i, char **c)
|
__attribute__((__used__)) int main(int i, char **c)
|
||||||
{
|
{
|
||||||
|
#ifndef BIOS_CONSOLE_DISABLE
|
||||||
char buffer[CMD_LINE_BUFFER_SIZE];
|
char buffer[CMD_LINE_BUFFER_SIZE];
|
||||||
char *params[MAX_PARAM];
|
char *params[MAX_PARAM];
|
||||||
char *command;
|
char *command;
|
||||||
struct command_struct *cmd;
|
struct command_struct *cmd;
|
||||||
int nb_params;
|
int nb_params;
|
||||||
|
#endif
|
||||||
int sdr_ok;
|
int sdr_ok;
|
||||||
|
|
||||||
#ifdef CONFIG_CPU_HAS_INTERRUPT
|
#ifdef CONFIG_CPU_HAS_INTERRUPT
|
||||||
|
@ -207,8 +209,11 @@ __attribute__((__used__)) int main(int i, char **c)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Console */
|
/* Console */
|
||||||
|
#ifdef BIOS_CONSOLE_DISABLE
|
||||||
|
printf("--======= \e[1mDone (No Console) \e[0m ==========--\n");
|
||||||
|
#else
|
||||||
printf("--============= \e[1mConsole\e[0m ================--\n");
|
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();
|
hist_init();
|
||||||
#endif
|
#endif
|
||||||
printf("\n%s", PROMPT);
|
printf("\n%s", PROMPT);
|
||||||
|
@ -223,5 +228,6 @@ __attribute__((__used__)) int main(int i, char **c)
|
||||||
}
|
}
|
||||||
printf("\n%s", PROMPT);
|
printf("\n%s", PROMPT);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
#include "readline.h"
|
#include "readline.h"
|
||||||
#include "complete.h"
|
#include "complete.h"
|
||||||
|
|
||||||
#ifndef TERM_NO_HIST
|
#ifndef BIOS_CONSOLE_NO_HISTORY
|
||||||
static int hist_max = 0;
|
static int hist_max = 0;
|
||||||
static int hist_add_idx = 0;
|
static int hist_add_idx = 0;
|
||||||
static int hist_cur = 0;
|
static int hist_cur = 0;
|
||||||
|
@ -76,7 +76,7 @@ static int read_key(void)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TERM_NO_HIST
|
#ifndef BIOS_CONSOLE_NO_HISTORY
|
||||||
static void cread_add_to_hist(char *line)
|
static void cread_add_to_hist(char *line)
|
||||||
{
|
{
|
||||||
strcpy(&hist_lines[hist_add_idx][0], line);
|
strcpy(&hist_lines[hist_add_idx][0], line);
|
||||||
|
@ -189,7 +189,7 @@ int readline(char *buf, int len)
|
||||||
int insert = 1;
|
int insert = 1;
|
||||||
unsigned char ichar;
|
unsigned char ichar;
|
||||||
|
|
||||||
#ifndef TERM_NO_COMPLETE
|
#ifndef BIOS_CONSOLE_NO_AUTOCOMPLETE
|
||||||
char tmp;
|
char tmp;
|
||||||
int reprint, i;
|
int reprint, i;
|
||||||
char *completestr;
|
char *completestr;
|
||||||
|
@ -204,7 +204,7 @@ int readline(char *buf, int len)
|
||||||
|
|
||||||
switch (ichar) {
|
switch (ichar) {
|
||||||
case '\t':
|
case '\t':
|
||||||
#ifndef TERM_NO_COMPLETE
|
#ifndef BIOS_CONSOLE_NO_AUTOCOMPLETE
|
||||||
buf[eol_num] = 0;
|
buf[eol_num] = 0;
|
||||||
tmp = buf[num];
|
tmp = buf[num];
|
||||||
|
|
||||||
|
@ -306,7 +306,7 @@ int readline(char *buf, int len)
|
||||||
case KEY_UP:
|
case KEY_UP:
|
||||||
case KEY_DOWN:
|
case KEY_DOWN:
|
||||||
{
|
{
|
||||||
#ifndef TERM_NO_HIST
|
#ifndef BIOS_CONSOLE_NO_HISTORY
|
||||||
char * hline;
|
char * hline;
|
||||||
if (ichar == KEY_UP)
|
if (ichar == KEY_UP)
|
||||||
hline = hist_prev();
|
hline = hist_prev();
|
||||||
|
@ -343,7 +343,7 @@ int readline(char *buf, int len)
|
||||||
len = eol_num;
|
len = eol_num;
|
||||||
buf[eol_num] = '\0';
|
buf[eol_num] = '\0';
|
||||||
|
|
||||||
#ifndef TERM_NO_HIST
|
#ifndef BIOS_CONSOLE_NO_HISTORY
|
||||||
if (buf[0] && buf[0] != CREAD_HIST_CHAR)
|
if (buf[0] && buf[0] != CREAD_HIST_CHAR)
|
||||||
cread_add_to_hist(buf);
|
cread_add_to_hist(buf);
|
||||||
hist_cur = hist_add_idx;
|
hist_cur = hist_add_idx;
|
||||||
|
|
|
@ -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);
|
command_pwr(DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS|DFII_COMMAND_WRDATA);
|
||||||
cdelay(15);
|
cdelay(15);
|
||||||
|
|
||||||
#ifdef SDRAM_PHY_ECP5DDRPHY
|
#if defined(SDRAM_PHY_ECP5DDRPHY) || defined(SDRAM_PHY_GW2DDRPHY)
|
||||||
ddrphy_burstdet_clr_write(1);
|
ddrphy_burstdet_clr_write(1);
|
||||||
#endif
|
#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)
|
if (((ddrphy_burstdet_seen_read() >> module) & 0x1) != 1)
|
||||||
errors += 1;
|
errors += 1;
|
||||||
#endif
|
#endif
|
||||||
|
@ -894,7 +894,7 @@ static void sdram_read_leveling_rst_delay(int module) {
|
||||||
/* Un-select module */
|
/* Un-select module */
|
||||||
ddrphy_dly_sel_write(0);
|
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. */
|
/* Sync all DQSBUFM's, By toggling all dly_sel (DQSBUFM.PAUSE) lines. */
|
||||||
ddrphy_dly_sel_write(0xff);
|
ddrphy_dly_sel_write(0xff);
|
||||||
ddrphy_dly_sel_write(0);
|
ddrphy_dly_sel_write(0);
|
||||||
|
@ -911,7 +911,7 @@ static void sdram_read_leveling_inc_delay(int module) {
|
||||||
/* Un-select module */
|
/* Un-select module */
|
||||||
ddrphy_dly_sel_write(0);
|
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. */
|
/* Sync all DQSBUFM's, By toggling all dly_sel (DQSBUFM.PAUSE) lines. */
|
||||||
ddrphy_dly_sel_write(0xff);
|
ddrphy_dly_sel_write(0xff);
|
||||||
ddrphy_dly_sel_write(0);
|
ddrphy_dly_sel_write(0);
|
||||||
|
|
|
@ -36,11 +36,19 @@ class RemoteClient(EtherboneIPC, CSRBuilder):
|
||||||
self.debug = debug
|
self.debug = debug
|
||||||
self.base_address = base_address if base_address is not None else 0
|
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):
|
def open(self):
|
||||||
if hasattr(self, "socket"):
|
if hasattr(self, "socket"):
|
||||||
return
|
return
|
||||||
self.socket = socket.create_connection((self.host, self.port), 5.0)
|
self.socket = socket.create_connection((self.host, self.port), 5.0)
|
||||||
self.socket.settimeout(5.0)
|
self.socket.settimeout(5.0)
|
||||||
|
self._receive_server_info()
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
if not hasattr(self, "socket"):
|
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 = RemoteClient(host=host, csr_csv=csr_csv, port=port)
|
||||||
bus.open()
|
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 = ""
|
fpga_identifier = ""
|
||||||
|
|
||||||
for i in range(256):
|
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 = RemoteClient(host=host, csr_csv=csr_csv, port=port)
|
||||||
bus.open()
|
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():
|
for name, register in bus.regs.__dict__.items():
|
||||||
if (filter is None) or filter in name:
|
if (filter is None) or filter in name:
|
||||||
print("0x{:08x} : 0x{:08x} {}".format(register.addr, register.read(), name))
|
print("0x{:08x} : 0x{:08x} {}".format(register.addr, register.read(), name))
|
||||||
|
|
|
@ -27,12 +27,14 @@ class Author:
|
||||||
def add_year(self, year):
|
def add_year(self, year):
|
||||||
self.years.append(year)
|
self.years.append(year)
|
||||||
self.years = make_unique(self.years)
|
self.years = make_unique(self.years)
|
||||||
|
self.years.sort()
|
||||||
|
|
||||||
# Use Git Log + Processing to create the list of Contibutors ---------------------------------------
|
# Use Git Log + Processing to create the list of Contibutors ---------------------------------------
|
||||||
|
|
||||||
companies = {
|
companies = {
|
||||||
"Antmicro" : "Antmicro.com",
|
"Antmicro" : "Antmicro.com",
|
||||||
"Google" : "Google.com",
|
"Google" : "Google.com",
|
||||||
|
"RapidSilicon" : "RapidSilicon.com",
|
||||||
}
|
}
|
||||||
|
|
||||||
def list_contributors(path):
|
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")
|
os.system(f"git log --follow --pretty=format:\"%an,%ae,%aI\" {path} | sort | uniq > contribs.csv")
|
||||||
|
|
||||||
# Read .csv and process it.
|
# Read .csv and process it.
|
||||||
authors = {}
|
contributors = {}
|
||||||
with open("contribs.csv", newline='') as csvfile:
|
with open("contribs.csv", newline='') as csvfile:
|
||||||
reader = csv.reader(csvfile, delimiter=",")
|
reader = csv.reader(csvfile, delimiter=",")
|
||||||
for line in reader:
|
for line in reader:
|
||||||
|
@ -53,13 +55,14 @@ def list_contributors(path):
|
||||||
if companies_email.lower() in email:
|
if companies_email.lower() in email:
|
||||||
name = companies_name
|
name = companies_name
|
||||||
email = companies_email
|
email = companies_email
|
||||||
if name in authors.keys():
|
if name in contributors.keys():
|
||||||
authors[name].add_year(int(year))
|
contributors[name].add_year(int(year))
|
||||||
else:
|
else:
|
||||||
authors[name] = Author(email, int(year))
|
contributors[name] = Author(email, int(year))
|
||||||
|
|
||||||
# Export Contributors.
|
# 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) "
|
r = "Copyright (c) "
|
||||||
if len(info.years) > 1:
|
if len(info.years) > 1:
|
||||||
years = f"{info.years[0]}-{info.years[-1]}"
|
years = f"{info.years[0]}-{info.years[-1]}"
|
||||||
|
|
|
@ -96,35 +96,48 @@ class RemoteServer(EtherboneIPC):
|
||||||
self.socket.close()
|
self.socket.close()
|
||||||
del self.socket
|
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):
|
def _serve_thread(self):
|
||||||
while True:
|
while True:
|
||||||
client_socket, addr = self.socket.accept()
|
client_socket, addr = self.socket.accept()
|
||||||
|
self._send_server_info(client_socket)
|
||||||
print("Connected with " + addr[0] + ":" + str(addr[1]))
|
print("Connected with " + addr[0] + ":" + str(addr[1]))
|
||||||
try:
|
try:
|
||||||
|
# Serve Etherbone reads/writes.
|
||||||
while True:
|
while True:
|
||||||
|
# Receive packet.
|
||||||
try:
|
try:
|
||||||
packet = self.receive_packet(client_socket)
|
packet = self.receive_packet(client_socket)
|
||||||
if packet == 0:
|
if packet == 0:
|
||||||
break
|
break
|
||||||
except:
|
except:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# Decode Packet.
|
||||||
packet = EtherbonePacket(packet)
|
packet = EtherbonePacket(packet)
|
||||||
packet.decode()
|
packet.decode()
|
||||||
|
|
||||||
|
# Get Packet's Record.
|
||||||
record = packet.records.pop()
|
record = packet.records.pop()
|
||||||
|
|
||||||
# Wait for lock
|
# Hardware lock/reservation.
|
||||||
while self.lock:
|
while self.lock:
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
|
|
||||||
# Set lock
|
|
||||||
self.lock = True
|
self.lock = True
|
||||||
|
|
||||||
# Handle writes:
|
# Handle Etherbone writes.
|
||||||
if record.writes != None:
|
if record.writes != None:
|
||||||
self.comm.write(record.writes.base_addr, record.writes.get_datas())
|
self.comm.write(record.writes.base_addr, record.writes.get_datas())
|
||||||
|
|
||||||
# Handle reads
|
# Handle Etherbone reads.
|
||||||
if record.reads != None:
|
if record.reads != None:
|
||||||
max_length = {
|
max_length = {
|
||||||
"CommUART": 256,
|
"CommUART": 256,
|
||||||
|
@ -148,7 +161,7 @@ class RemoteServer(EtherboneIPC):
|
||||||
packet.encode()
|
packet.encode()
|
||||||
self.send_packet(client_socket, packet)
|
self.send_packet(client_socket, packet)
|
||||||
|
|
||||||
# release lock
|
# Release hardware lock.
|
||||||
self.lock = False
|
self.lock = False
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
|
|
@ -404,6 +404,7 @@ def main():
|
||||||
# Configuration --------------------------------------------------------------------------------
|
# 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.
|
# UART.
|
||||||
if soc_kwargs["uart_name"] == "serial":
|
if soc_kwargs["uart_name"] == "serial":
|
||||||
|
@ -412,7 +413,10 @@ def main():
|
||||||
|
|
||||||
# ROM.
|
# ROM.
|
||||||
if args.rom_init:
|
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 / SDRAM.
|
||||||
ram_boot_offset = 0x40000000 # FIXME
|
ram_boot_offset = 0x40000000 # FIXME
|
||||||
|
@ -420,7 +424,11 @@ def main():
|
||||||
soc_kwargs["integrated_main_ram_size"] = args.integrated_main_ram_size
|
soc_kwargs["integrated_main_ram_size"] = args.integrated_main_ram_size
|
||||||
if args.integrated_main_ram_size:
|
if args.integrated_main_ram_size:
|
||||||
if args.ram_init is not None:
|
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)
|
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)
|
ram_boot_address = get_boot_address(args.ram_init)
|
||||||
elif args.with_sdram:
|
elif args.with_sdram:
|
||||||
assert args.ram_init is None
|
assert args.ram_init is None
|
||||||
|
@ -430,7 +438,11 @@ def main():
|
||||||
if args.sdram_from_spd_dump:
|
if args.sdram_from_spd_dump:
|
||||||
soc_kwargs["sdram_spd_data"] = parse_spd_hexdump(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:
|
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)
|
ram_boot_address = get_boot_address(args.sdram_init)
|
||||||
|
|
||||||
# Ethernet.
|
# Ethernet.
|
||||||
|
|
|
@ -97,10 +97,6 @@ class CrossoverUART:
|
||||||
if not present:
|
if not present:
|
||||||
raise ValueError(f"CrossoverUART {name} not present in design.")
|
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):
|
def open(self):
|
||||||
self.bus.open()
|
self.bus.open()
|
||||||
self.file, self.name = pty.openpty()
|
self.file, self.name = pty.openpty()
|
||||||
|
|
23
test/test_axi_stream.py
Normal file
23
test/test_axi_stream.py
Normal 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()
|
|
@ -50,3 +50,15 @@ class TestStream(unittest.TestCase):
|
||||||
def test_pipe_ready(self):
|
def test_pipe_ready(self):
|
||||||
dut = PipeReady([("data", 8)])
|
dut = PipeReady([("data", 8)])
|
||||||
self.pipe_test(dut)
|
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)
|
||||||
|
|
Loading…
Reference in a new issue