__pycache__
*.pyc
-*.egg-info/
-vpi/*.o
-vpi/migensim.vpi
-examples/*.vcd
-doc/_build
+*.egg-info
+*.vcd
+outgoing
--- /dev/null
+[submodule "litex/soc/cores/cpu/lm32/verilog/submodule"]
+ path = litex/soc/cores/cpu/lm32/verilog/submodule
+ url = https://github.com/m-labs/lm32.git
+[submodule "litex/soc/cores/cpu/mor1kx/verilog"]
+ path = litex/soc/cores/cpu/mor1kx/verilog
+ url = https://github.com/openrisc/mor1kx.git
+[submodule "litex/soc/software/compiler_rt"]
+ path = litex/soc/software/compiler_rt
+ url = http://llvm.org/git/compiler-rt.git
+[submodule "litex/soc/software/unwinder"]
+ path = litex/soc/software/unwinder
+ url = https://github.com/whitequark/libunwind
+++ /dev/null
-language: python
-python:
- - "3.5"
-
-env:
- global:
- - PATH=$HOME/miniconda/bin:$PATH
-
-before_install:
- # Install Miniconda
- - wget https://raw.githubusercontent.com/m-labs/artiq/master/.travis/get-anaconda.sh
- - chmod +x get-anaconda.sh
- - ./get-anaconda.sh
- - source $HOME/miniconda/bin/activate py35
- - conda install anaconda-client numpydoc
-install:
- # Install iverilog package.
- # - "sudo add-apt-repository -y ppa:mithro/iverilog-backport"
- # - "sudo apt-get update"
- # - "sudo apt-get install iverilog"
- # - "iverilog -v; true"
- # Build the vpi module.
- # - "(cd vpi; make; sudo make install)"
- # Install verilator package
- - "sudo apt-get install verilator"
- - "verilator --version; true"
- # Build and install Migen conda package
- # workaround for https://github.com/conda/conda-build/issues/466
- - "mkdir -p /home/travis/miniconda/conda-bld/linux-64"
- - "conda index /home/travis/miniconda/conda-bld/linux-64"
- - "conda build --python 3.5 conda/migen"
- - "conda install $(conda build --output --python 3.5 conda/migen)"
-
-script:
- # Run tests
- - "python setup.py test"
- # Generate HTML documentation
- - "make -C doc html"
-
-after_success:
- # Upload Migen conda package to binstar
- - if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then anaconda login --hostname $(hostname) --username $binstar_login --password $binstar_password; fi
- - if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then anaconda upload --user $binstar_login --channel dev --force $HOME/miniconda/conda-bld/noarch/migen-*.tar.bz2; fi
-
-notifications:
- email: false
- irc:
- channels:
- - chat.freenode.net#m-labs
- template:
- - "%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message}"
- - "Build details : %{build_url}"
+++ /dev/null
-Unless otherwise noted, Migen is copyright (C) 2011-2013 Sebastien Bourdeauducq.
-The simulation extension (as mentioned in the comments at the beginning of the
-corresponding source files) is copyright (C) 2012 Vermeer Manufacturing Co. All
-rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-Other authors retain ownership of their contributions. If a submission can
-reasonably be considered independently copyrightable, it's yours and we
-encourage you to claim it with appropriate copyright notices. This submission
-then falls under the "otherwise noted" category. All submissions are strongly
-encouraged to use the two-clause BSD license reproduced above.
--- /dev/null
+graft litex/soc/software
+graft litex/soc/cores/cpu/lm32/verilog
+graft litex/soc/cores/cpu/mor1kx/verilog
--- /dev/null
+ __ _ __ _ __
+ / / (_) /____ | |/_/
+ / /__/ / __/ -_)> <
+ /____/_/\__/\__/_/|_|
+
+ Build your hardware, easily!
+ Copyright 2015 Enjoy-Digital
+ (based on Migen/MiSoC technologies)
+
+[> Intro
+---------
+LiteX is a fork of Migen/MiSoC for our own needs at Enjoy-Digital. It provides
+a single python package and add some specific features to design our FPGA cores,
+build a SoC with or or load/flash it to the hardware.
+
+The structure of LiteX is kept close to Migen/MiSoC to enable collaboration
+between projects.
+
+[> License
+-----------
+LiteX is copyright (c) 2015 Enjoy-Digital.
+Since it is based on Migen/MiSoC, see gen/MIGEN_LICENSE and soc/MISOC_LICENSE or
+git history to get correct ownership of files.
+
+[> Sub-packages
+-----------
+gen:
+ Provides tools and simple modules to generate HDL.
+
+build:
+ Provides tools to build FPGA bitstreams (interface to vendor toolchains) and to
+ simulate HDL code or full SoCs.
+
+soc:
+ Provides definitions/modules to build cores (bus, bank, flow), cores and tools
+ to build a SoC from such cores.
+
+boards:
+ Provides platforms and targets for the supported boards.
+
+[> Contact
+E-mail: florent [AT] enjoy-digital.fr
\ No newline at end of file
+++ /dev/null
-### Migen (Milkymist generator)
-
-[![Build Status](https://travis-ci.org/m-labs/migen.svg)](
-https://travis-ci.org/m-labs/migen)
-
-#### A Python toolbox for building complex digital hardware
-
-Despite being faster than schematics entry, hardware design with Verilog and
-VHDL remains tedious and inefficient for several reasons. The event-driven
-model introduces issues and manual coding that are unnecessary for synchronous
-circuits, which represent the lion's share of today's logic designs. Counter-
-intuitive arithmetic rules result in steeper learning curves and provide a
-fertile ground for subtle bugs in designs. Finally, support for procedural
-generation of logic (metaprogramming) through "generate" statements is very
-limited and restricts the ways code can be made generic, reused and organized.
-
-To address those issues, we have developed the **Migen FHDL** library that
-replaces the event-driven paradigm with the notions of combinatorial and
-synchronous statements, has arithmetic rules that make integers always behave
-like mathematical integers, and most importantly allows the design's logic to
-be constructed by a Python program. This last point enables hardware designers
-to take advantage of the richness of the Python language - object oriented
-programming, function parameters, generators, operator overloading, libraries,
-etc. - to build well organized, reusable and elegant designs.
-
-Other Migen libraries are built on FHDL and provide various tools such as a
-system-on-chip interconnect infrastructure, a dataflow programming system, a
-more traditional high-level synthesizer that compiles Python routines into
-state machines with datapaths, and a simulator that allows test benches to be
-written in Python.
-
-See the doc/ folder for more technical information.
-
-Migen is designed for Python 3.3. Note that Migen is **not** spelled MiGen.
-
-#### Quick Links
-
-Code repository:
-https://github.com/m-labs/migen
-
-System-on-chip design based on Migen:
-https://github.com/m-labs/misoc
-
-Online documentation:
-http://m-labs.hk/gateware.html
-
-#### Quick intro
-
-```python
-from migen import *
-from migen.build.platforms import m1
-plat = m1.Platform()
-led = plat.request("user_led")
-m = Module()
-counter = Signal(26)
-m.comb += led.eq(counter[25])
-m.sync += counter.eq(counter + 1)
-plat.build_cmdline(m)
-```
-
-#### License
-
-Migen is released under the very permissive two-clause BSD license. Under the
-terms of this license, you are authorized to use Migen for closed-source
-proprietary designs.
-Even though we do not require you to do so, those things are awesome, so please
-do them if possible:
-* tell us that you are using Migen
-* put the Migen logo (doc/migen_logo.svg) on the page of a product using it,
- with a link to http://m-labs.hk
-* cite Migen in publications related to research it has helped
-* send us feedback and suggestions for improvements
-* send us bug reports when something goes wrong
-* send us the modifications and improvements you have done to Migen. The use
- of "git format-patch" is recommended. If your submission is large and
- complex and/or you are not sure how to proceed, feel free to discuss it on
- the mailing list or IRC (#m-labs on Freenode) beforehand.
-
-See LICENSE file for full copyright and license info. You can contact us on the
-public mailing list devel [AT] lists.m-labs.hk.
-
- "Electricity! It's like magic!"
+++ /dev/null
-%PYTHON% setup.py install
+++ /dev/null
-package:
- name: migen
- version: {{ environ.get("GIT_DESCRIBE_TAG", "") }}
-
-source:
- git_url: https://github.com/m-labs/migen
- git_tag: master
-
-build:
- noarch_python: true
- number: {{ environ.get("GIT_DESCRIBE_NUMBER", 0) }}
- string: py_{{ environ.get("GIT_DESCRIBE_NUMBER", 0) }}+git{{ environ.get("GIT_DESCRIBE_HASH", "")[1:] }}
- script: $PYTHON setup.py install
-
-requirements:
- build:
- - python 3.5.*
- run:
- - python 3.5.*
-
-test:
- imports:
- - migen
-
-about:
- home: http://m-labs.hk/gateware.html
- license: 3-clause BSD
- summary: 'A Python toolbox for building complex digital hardware'
+++ /dev/null
-# Makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS =
-SPHINXBUILD = sphinx-build
-PAPER =
-BUILDDIR = _build
-
-# Internal variables.
-PAPEROPT_a4 = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-
-.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
-
-help:
- @echo "Please use \`make <target>' where <target> is one of"
- @echo " html to make standalone HTML files"
- @echo " dirhtml to make HTML files named index.html in directories"
- @echo " singlehtml to make a single large HTML file"
- @echo " pickle to make pickle files"
- @echo " json to make JSON files"
- @echo " htmlhelp to make HTML files and a HTML help project"
- @echo " qthelp to make HTML files and a qthelp project"
- @echo " devhelp to make HTML files and a Devhelp project"
- @echo " epub to make an epub"
- @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
- @echo " latexpdf to make LaTeX files and run them through pdflatex"
- @echo " text to make text files"
- @echo " man to make manual pages"
- @echo " changes to make an overview of all changed/added/deprecated items"
- @echo " linkcheck to check all external links for integrity"
- @echo " doctest to run all doctests embedded in the documentation (if enabled)"
-
-clean:
- -rm -rf $(BUILDDIR)/*
-
-html:
- $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-dirhtml:
- $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-singlehtml:
- $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
- @echo
- @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
-
-pickle:
- $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
- @echo
- @echo "Build finished; now you can process the pickle files."
-
-json:
- $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
- @echo
- @echo "Build finished; now you can process the JSON files."
-
-htmlhelp:
- $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
- @echo
- @echo "Build finished; now you can run HTML Help Workshop with the" \
- ".hhp project file in $(BUILDDIR)/htmlhelp."
-
-qthelp:
- $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
- @echo
- @echo "Build finished; now you can run "qcollectiongenerator" with the" \
- ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
- @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Migen.qhcp"
- @echo "To view the help file:"
- @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Migen.qhc"
-
-devhelp:
- $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
- @echo
- @echo "Build finished."
- @echo "To view the help file:"
- @echo "# mkdir -p $$HOME/.local/share/devhelp/Migen"
- @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Migen"
- @echo "# devhelp"
-
-epub:
- $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
- @echo
- @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
-
-latex:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo
- @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
- @echo "Run \`make' in that directory to run these through (pdf)latex" \
- "(use \`make latexpdf' here to do that automatically)."
-
-latexpdf:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo "Running LaTeX files through pdflatex..."
- make -C $(BUILDDIR)/latex all-pdf
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-text:
- $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
- @echo
- @echo "Build finished. The text files are in $(BUILDDIR)/text."
-
-man:
- $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
- @echo
- @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
-
-changes:
- $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
- @echo
- @echo "The overview file is in $(BUILDDIR)/changes."
-
-linkcheck:
- $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
- @echo
- @echo "Link check complete; look for any errors in the above output " \
- "or in $(BUILDDIR)/linkcheck/output.txt."
-
-doctest:
- $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
- @echo "Testing of doctests in the sources finished, look at the " \
- "results in $(BUILDDIR)/doctest/output.txt."
+++ /dev/null
-# -*- coding: utf-8 -*-
-#
-# Migen documentation build configuration file, created by
-# sphinx-quickstart on Fri Mar 9 14:11:54 2012.
-#
-# This file is execfile()d with the current directory set to its containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.insert(0, os.path.abspath('.'))
-
-# -- General configuration -----------------------------------------------------
-
-# If your documentation needs a minimal Sphinx version, state it here.
-#needs_sphinx = '1.0'
-
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = [
- 'sphinx.ext.pngmath',
- 'sphinx.ext.autodoc',
- 'sphinx.ext.doctest',
- 'sphinx.ext.autosummary',
- 'numpydoc', # to preprocess docstrings
- ]
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-#source_encoding = 'utf-8-sig'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General information about the project.
-project = u'Migen'
-copyright = u'2011-2015, M-Labs Limited'
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = '1.0'
-# The full version, including alpha/beta/rc tags.
-release = '1.0'
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-exclude_patterns = ['_build']
-
-# The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-modindex_common_prefix = ['migen.']
-
-numpydoc_show_class_members = False
-
-# -- Options for HTML output ---------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages. See the documentation for
-# a list of builtin themes.
-html_theme = 'alabaster'
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further. For a list of options available for each theme, see the
-# documentation.
-#html_theme_options = {}
-
-# Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
-
-# The name for this set of Sphinx documents. If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar. Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_domain_indices = True
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
-
-# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
-
-# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it. The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'Migendoc'
-
-html_use_modindex = False
-
-# -- Options for LaTeX output --------------------------------------------------
-
-# The paper size ('letter' or 'a4').
-#latex_paper_size = 'letter'
-
-# The font size ('10pt', '11pt' or '12pt').
-#latex_font_size = '10pt'
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass [howto/manual]).
-latex_documents = [
- ('index', 'Migen.tex', u'Migen manual',
- u'Sebastien Bourdeauducq', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-latex_logo = "migen_logo.png"
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# If true, show page references after internal links.
-#latex_show_pagerefs = False
-
-# If true, show URL addresses after external links.
-#latex_show_urls = False
-
-# Additional stuff for the LaTeX preamble.
-latex_preamble = '\setcounter{tocdepth}{3}'
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_domain_indices = True
-
-latex_use_modindex = False
-
-# -- Options for manual page output --------------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
- ('index', 'migen', u'Migen manual',
- [u'Sebastien Bourdeauducq'], 1)
-]
+++ /dev/null
-The FHDL domain-specific language
-#################################
-
-The Fragmented Hardware Description Language (FHDL) is the basis of Migen. It consists of a formal system to describe signals, and combinatorial and synchronous statements operating on them. The formal system itself is low level and close to the synthesizable subset of Verilog, and we then rely on Python algorithms to build complex structures by combining FHDL elements.
-The FHDL module also contains a back-end to produce synthesizable Verilog, and some structure analysis and manipulation functionality.
-
-FHDL differs from MyHDL [myhdl]_ in fundamental ways. MyHDL follows the event-driven paradigm of traditional HDLs (see :ref:`background`) while FHDL separates the code into combinatorial statements, synchronous statements, and reset values. In MyHDL, the logic is described directly in the Python AST. The converter to Verilog or VHDL then examines the Python AST and recognizes a subset of Python that it translates into V*HDL statements. This seriously impedes the capability of MyHDL to generate logic procedurally. With FHDL, you manipulate a custom AST from Python, and you can more easily design algorithms that operate on it.
-
-.. [myhdl] http://www.myhdl.org
-
-FHDL is made of several elements, which are briefly explained below. They all can be imported directly from the ``migen`` module.
-
-Expressions
-***********
-
-Constants
-=========
-
-The ``Constant`` object represents a constant, HDL-literal integer. It behaves like specifying integers and booleans but also supports slicing and can have a bit width or signedness different from what is implied by the value it represents.
-
-``True`` and ``False`` are interpreted as 1 and 0, respectively.
-
-Negative integers are explicitly supported. As with MyHDL [countin]_, arithmetic operations return the natural results.
-
-To lighten the syntax, assignments and operators automatically wrap Python integers and booleans into ``Constant``. Additionally, ``Constant`` is aliased to ``C``. The following are valid Migen statements: ``a.eq(0)``, ``a.eq(a + 1)``, ``a.eq(C(42)[0:1])``.
-
-.. [countin] http://www.jandecaluwe.com/hdldesign/counting.html
-
-Signal
-======
-
-The signal object represents a value that is expected to change in the circuit. It does exactly what Verilog's "wire" and "reg" and VHDL's "signal" do.
-
-The main point of the signal object is that it is identified by its Python ID (as returned by the :py:func:`id` function), and nothing else. It is the responsibility of the V*HDL back-end to establish an injective mapping between Python IDs and the V*HDL namespace. It should perform name mangling to ensure this. The consequence of this is that signal objects can safely become members of arbitrary Python classes, or be passed as parameters to functions or methods that generate logic involving them.
-
-The properties of a signal object are:
-
-* An integer or a (integer, boolean) pair that defines the number of bits and whether the bit of higher index of the signal is a sign bit (i.e. the signal is signed). The defaults are one bit and unsigned. Alternatively, the ``min`` and ``max`` parameters can be specified to define the range of the signal and determine its bit width and signedness. As with Python ranges, ``min`` is inclusive and defaults to 0, ``max`` is exclusive and defaults to 2.
-* A name, used as a hint for the V*HDL back-end name mangler.
-* The signal's reset value. It must be an integer, and defaults to 0. When the signal's value is modified with a synchronous statement, the reset value is the initialization value of the associated register. When the signal is assigned to in a conditional combinatorial statement (``If`` or ``Case``), the reset value is the value that the signal has when no condition that causes the signal to be driven is verified. This enforces the absence of latches in designs. If the signal is permanently driven using a combinatorial statement, the reset value has no effect.
-
-The sole purpose of the name property is to make the generated V*HDL code easier to understand and debug. From a purely functional point of view, it is perfectly OK to have several signals with the same name property. The back-end will generate a unique name for each object. If no name property is specified, Migen will analyze the code that created the signal object, and try to extract the variable or member name from there. For example, the following statements will create one or several signals named "bar": ::
-
- bar = Signal()
- self.bar = Signal()
- self.baz.bar = Signal()
- bar = [Signal() for x in range(42)]
-
-In case of conflicts, Migen tries first to resolve the situation by prefixing the identifiers with names from the class and module hierarchy that created them. If the conflict persists (which can be the case if two signal objects are created with the same name in the same context), it will ultimately add number suffixes.
-
-Operators
-=========
-
-Operators are represented by the ``_Operator`` object, which generally should not be used directly. Instead, most FHDL objects overload the usual Python logic and arithmetic operators, which allows a much lighter syntax to be used. For example, the expression: ::
-
- a * b + c
-
-is equivalent to::
-
- _Operator("+", [_Operator("*", [a, b]), c])
-
-Slices
-======
-
-Likewise, slices are represented by the ``_Slice`` object, which often should not be used in favor of the Python slice operation [x:y]. Implicit indices using the forms [x], [x:] and [:y] are supported. Beware! Slices work like Python slices, not like VHDL or Verilog slices. The first bound is the index of the LSB and is inclusive. The second bound is the index of MSB and is exclusive. In V*HDL, bounds are MSB:LSB and both are inclusive.
-
-Concatenations
-==============
-
-Concatenations are done using the ``Cat`` object. To make the syntax lighter, its constructor takes a variable number of arguments, which are the signals to be concatenated together (you can use the Python "*" operator to pass a list instead).
-To be consistent with slices, the first signal is connected to the bits with the lowest indices in the result. This is the opposite of the way the "{}" construct works in Verilog.
-
-Replications
-============
-
-The ``Replicate`` object represents the equivalent of {count{expression}} in Verilog.
-
-Statements
-**********
-
-Assignment
-==========
-
-Assignments are represented with the ``_Assign`` object. Since using it directly would result in a cluttered syntax, the preferred technique for assignments is to use the ``eq()`` method provided by objects that can have a value assigned to them. They are signals, and their combinations with the slice and concatenation operators.
-As an example, the statement: ::
-
- a[0].eq(b)
-
-is equivalent to: ::
-
- _Assign(_Slice(a, 0, 1), b)
-
-If
-==
-
-The ``If`` object takes a first parameter which must be an expression (combination of the ``Constant``, ``Signal``, ``_Operator``, ``_Slice``, etc. objects) representing the condition, then a variable number of parameters representing the statements (``_Assign``, ``If``, ``Case``, etc. objects) to be executed when the condition is verified.
-
-The ``If`` object defines a ``Else()`` method, which when called defines the statements to be executed when the condition is not true. Those statements are passed as parameters to the variadic method.
-
-For convenience, there is also a ``Elif()`` method.
-
-Example: ::
-
- If(tx_count16 == 0,
- tx_bitcount.eq(tx_bitcount + 1),
- If(tx_bitcount == 8,
- self.tx.eq(1)
- ).Elif(tx_bitcount == 9,
- self.tx.eq(1),
- tx_busy.eq(0)
- ).Else(
- self.tx.eq(tx_reg[0]),
- tx_reg.eq(Cat(tx_reg[1:], 0))
- )
- )
-
-Case
-====
-
-The ``Case`` object constructor takes as first parameter the expression to be tested, and a dictionary whose keys are the values to be matched, and values the statements to be executed in the case of a match. The special value ``"default"`` can be used as match value, which means the statements should be executed whenever there is no other match.
-
-Arrays
-======
-
-The ``Array`` object represents lists of other objects that can be indexed by FHDL expressions. It is explicitly possible to:
-
-* nest ``Array`` objects to create multidimensional tables.
-* list any Python object in a ``Array`` as long as every expression appearing in a module ultimately evaluates to a ``Signal`` for all possible values of the indices. This allows the creation of lists of structured data.
-* use expressions involving ``Array`` objects in both directions (assignment and reading).
-
-For example, this creates a 4x4 matrix of 1-bit signals: ::
-
- my_2d_array = Array(Array(Signal() for a in range(4)) for b in range(4))
-
-You can then read the matrix with (``x`` and ``y`` being 2-bit signals): ::
-
- out.eq(my_2d_array[x][y])
-
-and write it with: ::
-
- my_2d_array[x][y].eq(inp)
-
-Since they have no direct equivalent in Verilog, ``Array`` objects are lowered into multiplexers and conditional statements before the actual conversion takes place. Such lowering happens automatically without any user intervention.
-
-Specials
-********
-
-Tri-state I/O
-=============
-
-A triplet (O, OE, I) of one-way signals defining a tri-state I/O port is represented by the ``TSTriple`` object. Such objects are only containers for signals that are intended to be later connected to a tri-state I/O buffer, and cannot be used as module specials. Such objects, however, should be kept in the design as long as possible as they allow the individual one-way signals to be manipulated in a non-ambiguous way.
-
-The object that can be used in as a module special is ``Tristate``, and it behaves exactly like an instance of a tri-state I/O buffer that would be defined as follows: ::
-
- Instance("Tristate",
- io_target=target,
- i_o=o,
- i_oe=oe,
- o_i=i
- )
-
-Signals ``target``, ``o`` and ``i`` can have any width, while ``oe`` is 1-bit wide. The ``target`` signal should go to a port and not be used elsewhere in the design. Like modern FPGA architectures, Migen does not support internal tri-states.
-
-A ``Tristate`` object can be created from a ``TSTriple`` object by calling the ``get_tristate`` method.
-
-By default, Migen emits technology-independent behavioral code for a tri-state buffer. If a specific code is needed, the tristate handler can be overriden using the appropriate parameter of the V*HDL conversion function.
-
-Instances
-=========
-
-Instance objects represent the parametrized instantiation of a V*HDL module, and the connection of its ports to FHDL signals. They are useful in a number of cases:
-
-* Reusing legacy or third-party V*HDL code.
-* Using special FPGA features (DCM, ICAP, ...).
-* Implementing logic that cannot be expressed with FHDL (e.g. latches).
-* Breaking down a Migen system into multiple sub-systems.
-
-The instance object constructor takes the type (i.e. name of the instantiated module) of the instance, then multiple parameters describing how to connect and parametrize the instance.
-
-These parameters can be:
-
-* ``Instance.Input``, ``Instance.Output`` or ``Instance.InOut`` to describe signal connections with the instance. The parameters are the name of the port at the instance, and the FHDL expression it should be connected to.
-* ``Instance.Parameter`` sets a parameter (with a name and value) of the instance.
-* ``Instance.ClockPort`` and ``Instance.ResetPort`` are used to connect clock and reset signals to the instance. The only mandatory parameter is the name of the port at the instance. Optionally, a clock domain name can be specified, and the ``invert`` option can be used to interface to those modules that require a 180-degree clock or a active-low reset.
-
-Memories
-========
-
-Memories (on-chip SRAM) are supported using a mechanism similar to instances.
-
-A memory object has the following parameters:
-
-* The width, which is the number of bits in each word.
-* The depth, which represents the number of words in the memory.
-* An optional list of integers used to initialize the memory.
-
-To access the memory in hardware, ports can be obtained by calling the ``get_port`` method. A port always has an address signal ``a`` and a data read signal ``dat_r``. Other signals may be available depending on the port's configuration.
-
-Options to ``get_port`` are:
-
-* ``write_capable`` (default: ``False``): if the port can be used to write to the memory. This creates an additional ``we`` signal.
-* ``async_read`` (default: ``False``): whether reads are asychronous (combinatorial) or synchronous (registered).
-* ``has_re`` (default: ``False``): adds a read clock-enable signal ``re`` (ignored for asychronous ports).
-* ``we_granularity`` (default: ``0``): if non-zero, writes of less than a memory word can occur. The width of the ``we`` signal is increased to act as a selection signal for the sub-words.
-* ``mode`` (default: ``WRITE_FIRST``, ignored for aynchronous ports). It can be:
-
- * ``READ_FIRST``: during a write, the previous value is read.
- * ``WRITE_FIRST``: the written value is returned.
- * ``NO_CHANGE``: the data read signal keeps its previous value on a write.
-
-* ``clock_domain`` (default: ``"sys"``): the clock domain used for reading and writing from this port.
-
-Migen generates behavioural V*HDL code that should be compatible with all simulators and, if the number of ports is <= 2, most FPGA synthesizers. If a specific code is needed, the memory handler can be overriden using the appropriate parameter of the V*HDL conversion function.
-
-Inline synthesis directives
-===========================
-
-Inline synthesis directives (pseudo-comments such as ``// synthesis attribute keep of clock_signal_name is true``) are supported using the ``SynthesisDirective`` object. Its constructor takes as parameters a string containing the body of the directive, and optional keyword parameters that are used to replace signal names similarly to the Python string method ``format``. The above example could be represented as follows: ::
-
- SynthesisDirective("attribute keep of {clksig} is true", clksig=clock_domain.clk)
-
-Modules
-*******
-
-Modules play the same role as Verilog modules and VHDL entities. Similarly, they are organized in a tree structure. A FHDL module is a Python object that derives from the ``Module`` class. This class defines special attributes to be used by derived classes to describe their logic. They are explained below.
-
-Combinatorial statements
-========================
-
-A combinatorial statement is a statement that is executed whenever one of its inputs changes.
-
-Combinatorial statements are added to a module by using the ``comb`` special attribute. Like most module special attributes, it must be accessed using the ``+=`` incrementation operator, and either a single statement, a tuple of statements or a list of statements can appear on the right hand side.
-
-For example, the module below implements a OR gate: ::
-
- class ORGate(Module):
- def __init__(self):
- self.a = Signal()
- self.b = Signal()
- self.x = Signal()
-
- ###
-
- self.comb += x.eq(a | b)
-
-To improve code readability, it is recommended to place the interface of the module at the beginning of the ``__init__`` function, and separate it from the implementation using three hash signs.
-
-Synchronous statements
-======================
-
-A synchronous statements is a statement that is executed at each edge of some clock signal.
-
-They are added to a module by using the ``sync`` special attribute, which has the same properties as the ``comb`` attribute.
-
-The ``sync`` special attribute also has sub-attributes that correspond to abstract clock domains. For example, to add a statement to the clock domain named ``foo``, one would write ``self.sync.foo += statement``. The default clock domain is ``sys`` and writing ``self.sync += statement`` is equivalent to writing ``self.sync.sys += statement``.
-
-Submodules and specials
-=======================
-
-Submodules and specials can be added by using the ``submodules`` and ``specials`` attributes respectively. This can be done in two ways:
-
-#. anonymously, by using the ``+=`` operator on the special attribute directly, e.g. ``self.submodules += some_other_module``. Like with the ``comb`` and ``sync`` attributes, a single module/special or a tuple or list can be specified.
-#. by naming the submodule/special using a subattribute of the ``submodules`` or ``specials`` attribute, e.g. ``self.submodules.foo = module_foo``. The submodule/special is then accessible as an attribute of the object, e.g. ``self.foo`` (and not ``self.submodules.foo``). Only one submodule/special can be added at a time using this form.
-
-Clock domains
-=============
-
-Specifying the implementation of a clock domain is done using the ``ClockDomain`` object. It contains the name of the clock domain, a clock signal that can be driven like any other signal in the design (for example, using a PLL instance), and optionally a reset signal. Clock domains without a reset signal are reset using e.g. ``initial`` statements in Verilog, which in many FPGA families initalize the registers during configuration.
-
-The name can be omitted if it can be extracted from the variable name. When using this automatic naming feature, prefixes ``_``, ``cd_`` and ``_cd_`` are removed.
-
-Clock domains are then added to a module using the ``clock_domains`` special attribute, which behaves exactly like ``submodules`` and ``specials``.
-
-Summary of special attributes
-=============================
-
-.. table::
-
- +--------------------------------------------+--------------------------------------------------------------+
- | Syntax | Action |
- +============================================+==============================================================+
- | self.comb += stmt | Add combinatorial statement to current module. |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.comb += stmtA, stmtB | Add combinatorial statements A and B to current module. |
- | | |
- | self.comb += [stmtA, stmtB] | |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.sync += stmt | Add synchronous statement to current module, in default |
- | | clock domain sys. |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.sync.foo += stmt | Add synchronous statement to current module, in clock domain |
- | | foo. |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.sync.foo += stmtA, stmtB | Add synchronous statements A and B to current module, in |
- | | clock domain foo. |
- | self.sync.foo += [stmtA, stmtB] | |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.submodules += mod | Add anonymous submodule to current module. |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.submodules += modA, modB | Add anonymous submodules A and B to current module. |
- | | |
- | self.submodules += [modA, modB] | |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.submodules.bar = mod | Add submodule named bar to current module. The submodule can |
- | | then be accessed using self.bar. |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.specials += spe | Add anonymous special to current module. |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.specials += speA, speB | Add anonymous specials A and B to current module. |
- | | |
- | self.specials += [speA, speB] | |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.specials.bar = spe | Add special named bar to current module. The special can |
- | | then be accessed using self.bar. |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.clock_domains += cd | Add clock domain to current module. |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.clock_domains += cdA, cdB | Add clock domains A and B to current module. |
- | | |
- | self.clock_domains += [cdA, cdB] | |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.clock_domains.pix = ClockDomain() | Create and add clock domain pix to current module. The clock |
- | | domain name is pix in all cases. It can be accessed using |
- | self.clock_domains._pix = ClockDomain() | self.pix, self._pix, self.cd_pix and self._cd_pix, |
- | | respectively. |
- | self.clock_domains.cd_pix = ClockDomain() | |
- | | |
- | self.clock_domains._cd_pix = ClockDomain() | |
- +--------------------------------------------+--------------------------------------------------------------+
-
-Clock domain management
-=======================
-
-When a module has named submodules that define one or several clock domains with the same name, those clock domain names are prefixed with the name of each submodule plus an underscore.
-
-An example use case of this feature is a system with two independent video outputs. Each video output module is made of a clock generator module that defines a clock domain ``pix`` and drives the clock signal, plus a driver module that has synchronous statements and other elements in clock domain ``pix``. The designer of the video output module can simply use the clock domain name ``pix`` in that module. In the top-level system module, the video output submodules are named ``video0`` and ``video1``. Migen then automatically renames the ``pix`` clock domain of each module to ``video0_pix`` and ``video1_pix``. Note that happens only because the clock domain is defined (using ClockDomain objects), not simply referenced (using e.g. synchronous statements) in the video output modules.
-
-Clock domain name overlap is an error condition when any of the submodules that defines the clock domains is anonymous.
-
-Finalization mechanism
-======================
-
-Sometimes, it is desirable that some of a module logic be created only after the user has finished manipulating that module. For example, the FSM module supports that states be defined dynamically, and the width of the state signal can be known only after all states have been added. One solution is to declare the final number of states in the FSM constructor, but this is not user-friendly. A better solution is to automatically create the state signal just before the FSM module is converted to V*HDL. Migen supports this using the so-called finalization mechanism.
-
-Modules can overload a ``do_finalize`` method that can create logic and is called using the algorithm below:
-
-#. Finalization of the current module begins.
-#. If the module has already been finalized (e.g. manually), the procedure stops here.
-#. Submodules of the current module are recursively finalized.
-#. ``do_finalize`` is called for the current module.
-#. Any new submodules created by the current module's ``do_finalize`` are recursively finalized.
-
-Finalization is automatically invoked at V*HDL conversion and at simulation. It can be manually invoked for any module by calling its ``finalize`` method.
-
-The clock domain management mechanism explained above happens during finalization.
-
-Conversion for synthesis
-************************
-
-Any FHDL module can be converted into synthesizable Verilog HDL. This is accomplished by using the ``convert`` function in the ``verilog`` module.
-
-The ``migen.build`` component provides scripts to interface third-party FPGA tools (from Xilinx, Altera and Lattice) to Migen, and a database of boards for the easy deployment of designs.
+++ /dev/null
-Migen manual
-############
-
-.. toctree::
- :maxdepth: 2
-
- introduction
- fhdl
- simulation
- synthesis
- reference
+++ /dev/null
-Introduction
-############
-
-Migen is a Python-based tool that aims at automating further the VLSI design process.
-
-Migen makes it possible to apply modern software concepts such as object-oriented programming and metaprogramming to design hardware. This results in more elegant and easily maintained designs and reduces the incidence of human errors.
-
-.. _background:
-
-Background
-**********
-
-Even though the Milkymist system-on-chip [mm]_ had many successes, it suffers from several limitations stemming from its implementation in manually written Verilog HDL:
-
-.. [mm] http://m-labs.hk
-
-#. The "event-driven" paradigm of today's dominant hardware descriptions languages (Verilog and VHDL, collectively referred to as "V*HDL" in the rest of this document) is often too general. Today's FPGA architectures are optimized for the implementation of fully synchronous circuits. This means that the bulk of the code for an efficient FPGA design falls into three categories:
-
- #. Combinatorial statements
- #. Synchronous statements
- #. Initialization of registers at reset
-
- V*HDL do not follow this organization. This means that a lot of repetitive manual coding is needed, which brings sources of human errors, petty issues, and confusion for beginners:
-
- #. wire vs. reg in Verilog
- #. forgetting to initialize a register at reset
- #. deciding whether a combinatorial statement must go into a process/always block or not
- #. simulation mismatches with combinatorial processes/always blocks
- #. and more...
-
- A little-known fact about FPGAs is that many of them have the ability to initialize their registers from the bitstream contents. This can be done in a portable and standard way using an "initial" block in Verilog, and by affecting a value at the signal declaration in VHDL. This renders an explicit reset signal unnecessary in practice in some cases, which opens the way for further design optimization. However, this form of initialization is entirely not synthesizable for ASIC targets, and it is not easy to switch between the two forms of reset using V*HDL.
-
-#. V*HDL support for composite types is very limited. Signals having a record type in VHDL are unidirectional, which makes them clumsy to use e.g. in bus interfaces. There is no record type support in Verilog, which means that a lot of copy-and-paste has to be done when forwarding grouped signals.
-
-#. V*HDL support for procedurally generated logic is extremely limited. The most advanced forms of procedural generation of synthesizable logic that V*HDL offers are CPP-style directives in Verilog, combinatorial functions, and ``generate`` statements. Nothing really fancy, and it shows. To give a few examples:
-
- #. Building highly flexible bus interconnect is not possible. Even arbitrating any given number of bus masters for commonplace protocols such as Wishbone is difficult with the tools that V*HDL puts at our disposal.
- #. Building a memory infrastructure (including bus interconnect, bridges and caches) that can automatically adapt itself at compile-time to any word size of the SDRAM is clumsy and tedious.
- #. Building register banks for control, status and interrupt management of cores can also largely benefit from automation.
- #. Many hardware acceleration problems can fit into the dataflow programming model. Manual dataflow implementation in V*HDL has, again, a lot of redundancy and potential for human errors. See the Milkymist texture mapping unit [mthesis]_ [mxcell]_ for an example of this. The amount of detail to deal with manually also makes the design space exploration difficult, and therefore hinders the design of efficient architectures.
- #. Pre-computation of values, such as filter coefficients for DSP or even simply trigonometric tables, must often be done using external tools whose results are copy-and-pasted (in the best case, automatically) into the V*HDL source.
-
-.. [mthesis] http://m-labs.hk/thesis/thesis.pdf
-.. [mxcell] http://www.xilinx.com/publications/archives/xcell/Xcell77.pdf p30-35
-
-Enter Migen, a Python toolbox for building complex digital hardware. We could have designed a brand new programming language, but that would have been reinventing the wheel instead of being able to benefit from Python's rich features and immense library. The price to pay is a slightly cluttered syntax at times when writing descriptions in FHDL, but we believe this is totally acceptable, particularly when compared to VHDL ;-)
-
-Migen is made up of several related components:
-
-#. the base language, FHDL
-#. a library of small generic cores
-#. a simulator
-#. a build system
-
-Installing Migen
-****************
-
-Either run the ``setup.py`` installation script or simply set ``PYTHONPATH`` to the root of the source directory.
-
-If you wish to contribute patches, the suggest way to install is;
- #. Clone from the git repository at http://github.com/m-labs/migen
- #. Install using ``python3 ./setup.py develop --user``
- #. Edit the code in your git checkout.
-
-Alternative install methods
-===========================
-
- * Migen is available for the Anaconda Python distribution. The package can be found at at https://anaconda.org/m-labs/migen
- * Migen can be referenced in a requirements.txt file (used for ``pip install -r requirements.txt``) via ``-e git+http://github.com/m-labs/migen.git#egg=migen``. See the pip documentation for more information.
-
-Feedback
-********
-Feedback concerning Migen or this manual should be sent to the M-Labs developers' mailing list ``devel`` on lists.m-labs.hk.
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="159.05869"
- height="106.55"
- id="svg3245"
- version="1.1"
- inkscape:version="0.48.1 r9760"
- sodipodi:docname="migen.svg"
- inkscape:export-filename="/home/lekernel/migen.png"
- inkscape:export-xdpi="184.10001"
- inkscape:export-ydpi="184.10001">
- <defs
- id="defs3247">
- <linearGradient
- id="linearGradient6093">
- <stop
- style="stop-color:#2ca22c;stop-opacity:0;"
- offset="0"
- id="stop6095" />
- <stop
- style="stop-color:#2ca22c;stop-opacity:1;"
- offset="1"
- id="stop6097" />
- </linearGradient>
- <linearGradient
- id="linearGradient6047">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop6049" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop6051" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#a"
- id="linearGradient6176"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.24477,0,0,0.24477,203.271,213.559)"
- x1="150.95"
- y1="-22.384001"
- x2="252.2"
- y2="204.03999" />
- <linearGradient
- id="a"
- y2="150.32001"
- gradientUnits="userSpaceOnUse"
- y1="13.899"
- x2="200.5"
- x1="200.5">
- <stop
- style="stop-color:#fff"
- offset=".1374"
- id="stop7" />
- <stop
- style="stop-color:#509e10;stop-opacity:1;"
- offset="1"
- id="stop9" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#a"
- id="linearGradient3345"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.24477,0,0,0.24477,203.271,213.559)"
- x1="150.95"
- y1="-22.384001"
- x2="252.2"
- y2="204.03999" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#a"
- id="linearGradient3349"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.24477,0,0,0.24477,280.71427,440.33237)"
- x1="150.95"
- y1="-22.384001"
- x2="252.2"
- y2="204.03999" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6047"
- id="linearGradient6053"
- x1="178.04323"
- y1="474.42865"
- x2="235.87062"
- y2="474.42865"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.78422775,0,0,1,105.91918,-2.4999996)" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6093"
- id="linearGradient6099"
- x1="242.87946"
- y1="471.54514"
- x2="289.73526"
- y2="471.54514"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1,0,0,1.1424088,0,-67.150429)" />
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="2.8"
- inkscape:cx="134.13698"
- inkscape:cy="59.325232"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="false"
- inkscape:window-width="1916"
- inkscape:window-height="1117"
- inkscape:window-x="0"
- inkscape:window-y="0"
- inkscape:window-maximized="1"
- showguides="true"
- inkscape:guide-bbox="true"
- fit-margin-top="0"
- fit-margin-left="0"
- fit-margin-right="0"
- fit-margin-bottom="0" />
- <metadata
- id="metadata3250">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(-242.87946,-440.32929)">
- <rect
- style="fill:url(#linearGradient6099);fill-opacity:1;stroke:none"
- id="rect6043"
- width="66.843575"
- height="23.704336"
- x="242.87946"
- y="459.6947" />
- <path
- inkscape:connector-curvature="0"
- id="path29"
- d="m 366.02427,471.24237 c -22.519,36.716 -73.921,29.454 -73.921,29.454 32.229,-32.229 0.16326,-57.929 0.16326,-57.929 0,0 51.973,-7.996 73.758,28.475"
- style="font-size:18px;fill:#00ad00;fill-opacity:1;font-family:'DejaVu Sans, Arial, Sans'" />
- <path
- inkscape:connector-curvature="0"
- id="path31"
- d="m 366.02427,471.24237 c -22.519,36.716 -73.921,29.454 -73.921,29.454 32.229,-32.229 0.16326,-57.929 0.16326,-57.929 0,0 51.973,-7.996 73.758,28.475"
- style="font-size:18px;fill:none;font-family:'DejaVu Sans, Arial, Sans'" />
- <path
- style="font-size:18px;font-family:'DejaVu Sans, Arial, Sans'"
- inkscape:connector-curvature="0"
- id="path33"
- d="m 364.64427,470.43237 c -5.3108,8.6038 -12.825,15.435 -21.719,20.199 -7.7214,4.1357 -16.268,6.5868 -24.897,7.9228 -6.0011,0.92916 -12.11,1.2491 -18.178,1.0907 -1.8804,-0.0489 -3.76,-0.15102 -5.6339,-0.31747 -0.51696,-0.046 -1.0334,-0.0977 -1.5489,-0.15739 -0.29226,-0.0338 -0.85842,-0.11431 -0.14808,-0.0144 0.234,0.88632 0.468,1.7726 0.702,2.6592 8.3771,-8.431 15.128,-19.206 14.819,-31.472 -0.20072,-7.9507 -3.4638,-15.551 -8.2374,-21.816 -1.8852,-2.4739 -3.9815,-4.9329 -6.418,-6.8911 -0.234,0.88633 -0.46801,1.7729 -0.70201,2.6592 0.61487,-0.0942 -0.31747,0.0377 0.24551,-0.0343 0.60361,-0.0769 1.2087,-0.14221 1.814,-0.20194 2.1765,-0.21442 4.3616,-0.33925 6.5477,-0.40461 7.0088,-0.20928 14.057,0.24796 20.959,1.4953 7.9781,1.442 15.783,3.9756 22.86,7.9654 8.0388,4.532 14.777,11.012 19.535,18.924 1.0557,1.756 3.8079,0.15739 2.7476,-1.606 -5.1914,-8.6336 -12.6,-15.613 -21.408,-20.474 -7.7483,-4.275 -16.361,-6.8644 -25.074,-8.2486 -9.4825,-1.5066 -19.54,-1.944 -29.073,-0.48367 -1.1345,0.17379 -1.5874,1.9477 -0.70201,2.6592 3.0624,2.4612 5.6283,5.6205 7.7454,8.8104 4.5202,6.8118 6.9303,14.977 5.6423,23.154 -1.4588,9.2607 -7.0781,17.201 -13.551,23.715 -0.75977,0.76492 -0.53067,2.4859 0.70201,2.6592 9.9738,1.4023 20.482,0.7025 30.334,-1.1362 8.4689,-1.5805 16.759,-4.3922 24.256,-8.6664 8.6297,-4.9199 15.91,-11.93 21.128,-20.383 1.0812,-1.7514 -1.6723,-3.3482 -2.7473,-1.606 z" />
- <path
- inkscape:connector-curvature="0"
- id="path35"
- d="m 295.19427,443.74237 c 0,0 12.67,11.257 12.67,27.475 0,0 9.8236,-9.7551 23.069,0 0,0 15.098,13.305 33.229,0 0,0 -15.539,-32.087 -68.968,-27.475 z"
- style="font-size:18px;fill:url(#linearGradient3349);fill-opacity:1;font-family:'DejaVu Sans, Arial, Sans'" />
- <line
- id="line39"
- y2="471.03238"
- x2="400.71429"
- y1="471.03238"
- x1="366.79425"
- style="font-size:18px;fill:none;stroke:#000000;stroke-width:2.44770002;font-family:'DejaVu Sans, Arial, Sans'" />
- <path
- inkscape:connector-curvature="0"
- id="path59"
- d="m 344.15733,461.16448 4.84652,0"
- style="font-size:18px;fill:none;stroke:#000000;stroke-width:2.44799995;stroke-miterlimit:4;stroke-dasharray:none;font-family:'DejaVu Sans, Arial, Sans'"
- sodipodi:nodetypes="cc" />
- <path
- sodipodi:nodetypes="cc"
- style="font-size:18px;fill:none;stroke:#000000;stroke-width:2.44799995;stroke-miterlimit:4;stroke-dasharray:none;font-family:'DejaVu Sans, Arial, Sans'"
- d="m 344.15733,481.90109 4.84652,0"
- id="path6037"
- inkscape:connector-curvature="0" />
- <text
- xml:space="preserve"
- style="font-size:40px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Orbitron;-inkscape-font-specification:Orbitron Light"
- x="257.14285"
- y="537.7193"
- id="text6055"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan6057"
- x="257.14285"
- y="537.7193">migen</tspan></text>
- <path
- sodipodi:nodetypes="cc"
- style="font-size:18px;fill:none;stroke:#000000;stroke-width:2.61650872;stroke-miterlimit:4;stroke-dasharray:none;font-family:'DejaVu Sans, Arial, Sans'"
- d="m 289.42519,459.68794 14.57866,0"
- id="path6105"
- inkscape:connector-curvature="0" />
- <path
- inkscape:connector-curvature="0"
- id="path6107"
- d="m 289.42519,483.37763 14.57866,0"
- style="font-size:18px;fill:none;stroke:#000000;stroke-width:2.61650872;stroke-miterlimit:4;stroke-dasharray:none;font-family:'DejaVu Sans, Arial, Sans'"
- sodipodi:nodetypes="cc" />
- </g>
-</svg>
+++ /dev/null
-API reference
-=============
-
-:mod:`fhdl.structure` module
-----------------------------
-
-.. automodule:: migen.fhdl.structure
- :members:
- :show-inheritance:
-
-:mod:`fhdl.bitcontainer` module
--------------------------------
-
-.. automodule:: migen.fhdl.bitcontainer
- :members:
- :show-inheritance:
-
-:mod:`genlib.fifo` module
--------------------------
-
-.. automodule:: migen.genlib.fifo
- :members:
- :show-inheritance:
-
-:mod:`genlib.coding` module
----------------------------
-
-.. automodule:: migen.genlib.coding
- :members:
- :show-inheritance:
-
-:mod:`genlib.sort` module
--------------------------
-
-.. automodule:: migen.genlib.sort
- :members:
- :show-inheritance:
+++ /dev/null
-Simulating a Migen design
-#########################
-
-Migen allows you to easily simulate your FHDL design and interface it with arbitrary Python code. The simulator is written in pure Python and interprets the FHDL structure directly without using an external Verilog simulator.
-
-[To be rewritten]
+++ /dev/null
-Synthesizing a Migen design
-###########################
-
-[To be written]
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-
-
-class Example(Module):
- def __init__(self):
- dx = 2
- dy = 2
-
- x = Signal(max=dx)
- y = Signal(max=dy)
- out = Signal()
-
- my_2d_array = Array(Array(Signal() for a in range(dx)) for b in range(dy))
- self.comb += out.eq(my_2d_array[x][y])
-
- we = Signal()
- inp = Signal()
- self.sync += If(we,
- my_2d_array[x][y].eq(inp)
- )
-
- ina = Array(Signal() for a in range(dx))
- outa = Array(Signal() for a in range(dy))
- self.specials += Instance("test", o_O=outa[y], i_I=ina[x])
-
-if __name__ == "__main__":
- print(verilog.convert(Example()))
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-
-class Example(Module):
- def __init__(self):
- self.s = Signal()
- self.counter = Signal(8)
- x = Array(Signal(name="a") for i in range(7))
-
- myfsm = FSM()
- self.submodules += myfsm
-
- myfsm.act("FOO",
- self.s.eq(1),
- NextState("BAR")
- )
- myfsm.act("BAR",
- self.s.eq(0),
- NextValue(self.counter, self.counter + 1),
- NextValue(x[self.counter], 89),
- NextState("FOO")
- )
-
- self.be = myfsm.before_entering("FOO")
- self.ae = myfsm.after_entering("FOO")
- self.bl = myfsm.before_leaving("FOO")
- self.al = myfsm.after_leaving("FOO")
-
-if __name__ == "__main__":
- example = Example()
- print(verilog.convert(example, {example.s, example.counter, example.be, example.ae, example.bl, example.al}))
+++ /dev/null
-from random import Random
-
-from migen import *
-from migen.genlib.cdc import GrayCounter
-
-
-def tb(dut):
- prng = Random(7345)
- for i in range(35):
- print("{0:0{1}b} CE={2} bin={3}".format((yield dut.q),
- len(dut.q), (yield dut.ce), (yield dut.q_binary)))
- yield dut.ce.eq(prng.getrandbits(1))
- yield
-
-
-if __name__ == "__main__":
- dut = GrayCounter(3)
- run_simulation(dut, tb(dut), vcd_name="graycounter.vcd")
+++ /dev/null
-import subprocess
-
-from migen import *
-from migen.fhdl.verilog import convert
-
-
-# Create a parent module with two instances of a child module.
-# Bind input ports to first module and output ports to second,
-# and create internal signals to connect the first module to the
-# second.
-class ParentModule(Module):
- def __init__(self):
- self.inputs = [Signal(x+1, name="input{}".format(x)) for x in range(4)]
- self.trans = [Signal(x+1) for x in range(4)]
- self.outputs = [Signal(x+1, name="output{}".format(x)) for x in range(4)]
- self.io = set(self.inputs) | set(self.outputs)
- i = Instance("ChildModule",
- i_master_clk=ClockSignal(),
- i_master_rst=ResetSignal(),
- i_input0=self.inputs[0],
- i_input1=self.inputs[1],
- i_input2=self.inputs[2],
- i_input3=self.inputs[3],
- o_output0=self.trans[0],
- o_output1=self.trans[1],
- o_output2=self.trans[2],
- o_output3=self.trans[3]
- )
- j = Instance("ChildModule",
- i_master_clk=ClockSignal(),
- i_master_rst=ResetSignal(),
- i_input0=self.trans[0],
- i_input1=self.trans[1],
- i_input2=self.trans[2],
- i_input3=self.trans[3],
- o_output0=self.outputs[0],
- o_output1=self.outputs[1],
- o_output2=self.outputs[2],
- o_output3=self.outputs[3]
- )
- self.specials += i, j
-
-
-class ChildModule(Module):
- def __init__(self):
- self.inputs = [Signal(x+1, name_override="input{}".format(x)) for x in range(4)]
- self.outputs = [Signal(x+1, name_override="output{}".format(x)) for x in range(4)]
- self.io = set()
- for x in range(4):
- self.sync.master += self.outputs[x].eq(self.inputs[x])
- self.io = self.io.union(self.inputs)
- self.io = self.io.union(self.outputs)
-
-
-# Generate RTL for the parent module and the submodule, run through
-# icarus for a syntax check
-def test_instance_module():
- sub = ChildModule()
- convert(sub, sub.io, name="ChildModule").write("ChildModule.v")
-
- im = ParentModule()
- convert(im, im.io, name="ParentModule").write("ParentModule.v")
-
- subprocess.check_call(["iverilog", "-W", "all",
- "ParentModule.v", "ChildModule.v"])
-
-if __name__ == "__main__":
- test_instance_module()
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-from migen.genlib.divider import Divider
-
-
-class CDM(Module):
- def __init__(self):
- self.submodules.divider = Divider(5)
- self.clock_domains.cd_sys = ClockDomain(reset_less=True)
-
-
-class MultiMod(Module):
- def __init__(self):
- self.submodules.foo = CDM()
- self.submodules.bar = CDM()
-
-if __name__ == "__main__":
- mm = MultiMod()
- print(verilog.convert(mm, {mm.foo.cd_sys.clk, mm.bar.cd_sys.clk}))
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-
-
-class Example(Module):
- def __init__(self):
- self.specials.mem = Memory(32, 100, init=[5, 18, 32])
- p1 = self.mem.get_port(write_capable=True, we_granularity=8)
- p2 = self.mem.get_port(has_re=True, clock_domain="rd")
- self.specials += p1, p2
- self.ios = {p1.adr, p1.dat_r, p1.we, p1.dat_w,
- p2.adr, p2.dat_r, p2.re}
-
-
-if __name__ == "__main__":
- example = Example()
- print(verilog.convert(example, example.ios))
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-
-from functools import reduce
-from operator import or_
-
-
-def gen_list(n):
- s = [Signal() for i in range(n)]
- return s
-
-
-def gen_2list(n):
- s = [Signal(2) for i in range(n)]
- return s
-
-
-class Foo:
- def __init__(self):
- la = gen_list(3)
- lb = gen_2list(2)
- self.sigs = la + lb
-
-
-class Bar:
- def __init__(self):
- self.sigs = gen_list(2)
-
-
-class Example(Module):
- def __init__(self):
- a = [Bar() for x in range(3)]
- b = [Foo() for x in range(3)]
- c = b
- b = [Bar() for x in range(2)]
-
- output = Signal()
- allsigs = []
- for lst in [a, b, c]:
- for obj in lst:
- allsigs.extend(obj.sigs)
- self.comb += output.eq(reduce(or_, allsigs))
-
-print(verilog.convert(Example()))
+++ /dev/null
-from migen import *
-from migen.fhdl.specials import SynthesisDirective
-from migen.fhdl import verilog
-from migen.genlib.cdc import *
-
-
-class XilinxMultiRegImpl(MultiRegImpl):
- def __init__(self, *args, **kwargs):
- MultiRegImpl.__init__(self, *args, **kwargs)
- self.specials += set(SynthesisDirective("attribute shreg_extract of {r} is no", r=r)
- for r in self.regs)
-
-
-class XilinxMultiReg:
- @staticmethod
- def lower(dr):
- return XilinxMultiRegImpl(dr.i, dr.o, dr.odomain, dr.n)
-
-
-if __name__ == "__main__":
- ps = PulseSynchronizer("from", "to")
- v = verilog.convert(ps, {ps.i, ps.o}, special_overrides={MultiReg: XilinxMultiReg})
- print(v)
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-
-
-L = [
- ("position", [
- ("x", 10, DIR_M_TO_S),
- ("y", 10, DIR_M_TO_S),
- ]),
- ("color", 32, DIR_M_TO_S),
- ("stb", 1, DIR_M_TO_S),
- ("ack", 1, DIR_S_TO_M)
-]
-
-
-class Test(Module):
- def __init__(self):
- master = Record(L)
- slave = Record(L)
- self.comb += master.connect(slave)
-
-
-if __name__ == "__main__":
- print(verilog.convert(Test()))
- print(layout_len(L))
- print(layout_partial(L, "position/x", "color"))
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-
-
-class Example(Module):
- def __init__(self):
- a = Signal(3)
- b = Signal(4)
- c = Signal(5)
- d = Signal(7)
- s1 = c[:3][:2]
- s2 = Cat(a, b)[:6]
- s3 = Cat(s1, s2)[-5:]
- self.comb += s3.eq(0)
- self.comb += d.eq(Cat(d[::-1], Cat(s1[:1], s3[-4:])[:3]))
-
-
-if __name__ == "__main__":
- print(verilog.convert(Example()))
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-
-
-class Example(Module):
- def __init__(self, n=6):
- self.pad = Signal(n)
- self.t = TSTriple(n)
- self.specials += self.t.get_tristate(self.pad)
-
-if __name__ == "__main__":
- e = Example()
- print(verilog.convert(e, ios={e.pad, e.t.o, e.t.oe, e.t.i}))
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-from migen.genlib import divider
-
-
-@ResetInserter()
-@CEInserter()
-class Example(Module):
- def __init__(self, width):
- d1 = divider.Divider(width)
- d2 = divider.Divider(width)
- self.submodules += d1, d2
- self.ios = {
- d1.ready_o, d1.quotient_o, d1.remainder_o, d1.start_i, d1.dividend_i, d1.divisor_i,
- d2.ready_o, d2.quotient_o, d2.remainder_o, d2.start_i, d2.dividend_i, d2.divisor_i}
-
-if __name__ == "__main__":
- example = Example(16)
- print(verilog.convert(example, example.ios | {example.ce, example.reset}))
+++ /dev/null
-from migen import *
-
-
-# Our simple counter, which increments at every cycle.
-class Counter(Module):
- def __init__(self):
- self.count = Signal(4)
-
- # At each cycle, increase the value of the count signal.
- # We do it with convertible/synthesizable FHDL code.
- self.sync += self.count.eq(self.count + 1)
-
-
-# Simply read the count signal and print it.
-# The output is:
-# Count: 0
-# Count: 1
-# Count: 2
-# ...
-def counter_test(dut):
- for i in range(20):
- print((yield dut.count)) # read and print
- yield # next clock cycle
- # simulation ends with this generator
-
-
-if __name__ == "__main__":
- dut = Counter()
- run_simulation(dut, counter_test(dut), vcd_name="basic1.vcd")
+++ /dev/null
-from migen import *
-
-
-# A slightly more elaborate counter.
-# Has a clock enable (CE) signal, counts on more bits
-# and resets with a negative number.
-class Counter(Module):
- def __init__(self):
- self.ce = Signal()
- # Demonstrate negative numbers and signals larger than 32 bits.
- self.count = Signal((37, True), reset=-5)
-
- self.sync += If(self.ce, self.count.eq(self.count + 1))
-
-
-def counter_test(dut):
- for cycle in range(20):
- # Only assert CE every second cycle.
- # => each counter value is held for two cycles.
- if cycle % 2:
- yield dut.ce.eq(0) # This is how you write to a signal.
- else:
- yield dut.ce.eq(1)
- print("Cycle: {} Count: {}".format(cycle, (yield dut.count)))
- yield
-
-# Output is:
-# Cycle: 0 Count: -5
-# Cycle: 1 Count: -5
-# Cycle: 2 Count: -4
-# Cycle: 3 Count: -4
-# Cycle: 4 Count: -3
-# ...
-
-if __name__ == "__main__":
- dut = Counter()
- run_simulation(dut, counter_test(dut), vcd_name="basic2.vcd")
+++ /dev/null
-from functools import reduce
-from operator import add
-
-from math import cos, pi
-from scipy import signal
-import matplotlib.pyplot as plt
-
-from migen import *
-from migen.fhdl import verilog
-
-
-# A synthesizable FIR filter.
-class FIR(Module):
- def __init__(self, coef, wsize=16):
- self.coef = coef
- self.wsize = wsize
- self.i = Signal((self.wsize, True))
- self.o = Signal((self.wsize, True))
-
- ###
-
- muls = []
- src = self.i
- for c in self.coef:
- sreg = Signal((self.wsize, True))
- self.sync += sreg.eq(src)
- src = sreg
- c_fp = int(c*2**(self.wsize - 1))
- muls.append(c_fp*sreg)
- sum_full = Signal((2*self.wsize-1, True))
- self.sync += sum_full.eq(reduce(add, muls))
- self.comb += self.o.eq(sum_full >> self.wsize-1)
-
-
-# A test bench for our FIR filter.
-# Generates a sine wave at the input and records the output.
-def fir_tb(dut, frequency, inputs, outputs):
- f = 2**(dut.wsize - 1)
- for cycle in range(200):
- v = 0.1*cos(2*pi*frequency*cycle)
- yield dut.i.eq(int(f*v))
- inputs.append(v)
- outputs.append((yield dut.o)/f)
- yield
-
-
-if __name__ == "__main__":
- # Compute filter coefficients with SciPy.
- coef = signal.remez(30, [0, 0.1, 0.2, 0.4, 0.45, 0.5], [0, 1, 0])
-
- # Simulate for different frequencies and concatenate
- # the results.
- in_signals = []
- out_signals = []
- for frequency in [0.05, 0.1, 0.25]:
- dut = FIR(coef)
- tb = fir_tb(dut, frequency, in_signals, out_signals)
- run_simulation(dut, tb)
-
- # Plot data from the input and output waveforms.
- plt.plot(in_signals)
- plt.plot(out_signals)
- plt.show()
-
- # Print the Verilog source for the filter.
- fir = FIR(coef)
- print(verilog.convert(fir, ios={fir.i, fir.o}))
+++ /dev/null
-from migen import *
-
-
-class Mem(Module):
- def __init__(self):
- # Initialize the beginning of the memory with integers
- # from 0 to 19.
- self.specials.mem = Memory(16, 2**12, init=list(range(20)))
-
-
-def memory_test(dut):
- # write (only first 5 values)
- for i in range(5):
- yield dut.mem[i].eq(42 + i)
- # remember: values are written after the tick, and read before the tick.
- # wait one tick for the memory to update.
- yield
- # read what we have written, plus some initialization data
- for i in range(10):
- value = yield dut.mem[i]
- print(value)
-
-
-if __name__ == "__main__":
- dut = Mem()
- run_simulation(dut, memory_test(dut))
--- /dev/null
+# This file is Copyright (c) 2013 Florent Kermarrec <florent@enjoy-digital.fr>
+# License: BSD
+
+from litex.build.generic_platform import *
+from litex.build.altera import AlteraPlatform
+from litex.build.altera.programmer import USBBlaster
+
+
+_io = [
+ ("clk50", 0, Pins("R8"), IOStandard("3.3-V LVTTL")),
+
+ ("user_led", 0, Pins("A15"), IOStandard("3.3-V LVTTL")),
+ ("user_led", 1, Pins("A13"), IOStandard("3.3-V LVTTL")),
+ ("user_led", 2, Pins("B13"), IOStandard("3.3-V LVTTL")),
+ ("user_led", 3, Pins("A11"), IOStandard("3.3-V LVTTL")),
+ ("user_led", 4, Pins("D1"), IOStandard("3.3-V LVTTL")),
+ ("user_led", 5, Pins("F3"), IOStandard("3.3-V LVTTL")),
+ ("user_led", 6, Pins("B1"), IOStandard("3.3-V LVTTL")),
+ ("user_led", 7, Pins("L3"), IOStandard("3.3-V LVTTL")),
+
+ ("key", 0, Pins("J15"), IOStandard("3.3-V LVTTL")),
+ ("key", 1, Pins("E1"), IOStandard("3.3-V LVTTL")),
+
+ ("sw", 0, Pins("M1"), IOStandard("3.3-V LVTTL")),
+ ("sw", 1, Pins("T9"), IOStandard("3.3-V LVTTL")),
+ ("sw", 2, Pins("B9"), IOStandard("3.3-V LVTTL")),
+ ("sw", 3, Pins("M15"), IOStandard("3.3-V LVTTL")),
+
+ ("serial", 0,
+ Subsignal("tx", Pins("D3"), IOStandard("3.3-V LVTTL")),
+ Subsignal("rx", Pins("C3"), IOStandard("3.3-V LVTTL"))
+ ),
+
+ ("sdram_clock", 0, Pins("R4"), IOStandard("3.3-V LVTTL")),
+ ("sdram", 0,
+ Subsignal("a", Pins("P2 N5 N6 M8 P8 T7 N8 T6 R1 P1 N2 N1 L4")),
+ Subsignal("ba", Pins("M7 M6")),
+ Subsignal("cs_n", Pins("P6")),
+ Subsignal("cke", Pins("L7")),
+ Subsignal("ras_n", Pins("L2")),
+ Subsignal("cas_n", Pins("L1")),
+ Subsignal("we_n", Pins("C2")),
+ Subsignal("dq", Pins("G2 G1 L8 K5 K2 J2 J1 R7 T4 T2 T3 R3 R5 P3 N3 K1")),
+ Subsignal("dm", Pins("R6 T5")),
+ IOStandard("3.3-V LVTTL")
+ ),
+
+ ("epcs", 0,
+ Subsignal("data0", Pins("H2")),
+ Subsignal("dclk", Pins("H1")),
+ Subsignal("ncs0", Pins("D2")),
+ Subsignal("asd0", Pins("C1")),
+ IOStandard("3.3-V LVTTL")
+ ),
+
+ ("i2c", 0,
+ Subsignal("sclk", Pins("F2")),
+ Subsignal("sdat", Pins("F1")),
+ IOStandard("3.3-V LVTTL")
+ ),
+
+ ("g_sensor", 0,
+ Subsignal("cs_n", Pins("G5")),
+ Subsignal("int", Pins("M2")),
+ IOStandard("3.3-V LVTTL")
+ ),
+
+ ("adc", 0,
+ Subsignal("cs_n", Pins("A10")),
+ Subsignal("saddr", Pins("B10")),
+ Subsignal("sclk", Pins("B14")),
+ Subsignal("sdat", Pins("A9")),
+ IOStandard("3.3-V LVTTL")
+ ),
+
+ ("gpio_0", 0,
+ Pins("D3 C3 A2 A3 B3 B4 A4 B5 A5 D5 B6 A6 B7 D6 A7 C6",
+ "C8 E6 E7 D8 E8 F8 F9 E9 C9 D9 E11 E10 C11 B11 A12 D11",
+ "D12 B12"),
+ IOStandard("3.3-V LVTTL")
+ ),
+ ("gpio_1", 0,
+ Pins("F13 T15 T14 T13 R13 T12 R12 T11 T10 R11 P11 R10 N12 P9 N9 N11",
+ "L16 K16 R16 L15 P15 P16 R14 N16 N15 P14 L14 N14 M10 L13 J16 K15",
+ "J13 J14"),
+ IOStandard("3.3-V LVTTL")
+ ),
+ ("gpio_2", 0,
+ Pins("A14 B16 C14 C16 C15 D16 D15 D14 F15 F16 F14 G16 G15"),
+ IOStandard("3.3-V LVTTL")
+ ),
+]
+
+
+class Platform(AlteraPlatform):
+ default_clk_name = "clk50"
+ default_clk_period = 20
+
+ def __init__(self):
+ AlteraPlatform.__init__(self, "EP4CE22F17C6", _io)
+
+ def create_programmer(self):
+ return USBBlaster()
--- /dev/null
+from litex.build.generic_platform import *
+from litex.build.xilinx import XilinxPlatform, XC3SProg, VivadoProgrammer, iMPACT
+from litex.build.xilinx.ise import XilinxISEToolchain
+
+
+_io = [
+ ("user_led", 0, Pins("AB8"), IOStandard("LVCMOS15")),
+ ("user_led", 1, Pins("AA8"), IOStandard("LVCMOS15")),
+ ("user_led", 2, Pins("AC9"), IOStandard("LVCMOS15")),
+ ("user_led", 3, Pins("AB9"), IOStandard("LVCMOS15")),
+ ("user_led", 4, Pins("AE26"), IOStandard("LVCMOS25")),
+ ("user_led", 5, Pins("G19"), IOStandard("LVCMOS25")),
+ ("user_led", 6, Pins("E18"), IOStandard("LVCMOS25")),
+ ("user_led", 7, Pins("F16"), IOStandard("LVCMOS25")),
+
+ ("cpu_reset", 0, Pins("AB7"), IOStandard("LVCMOS15")),
+
+ ("user_btn_c", 0, Pins("G12"), IOStandard("LVCMOS25")),
+ ("user_btn_n", 0, Pins("AA12"), IOStandard("LVCMOS15")),
+ ("user_btn_s", 0, Pins("AB12"), IOStandard("LVCMOS15")),
+ ("user_btn_w", 0, Pins("AC6"), IOStandard("LVCMOS15")),
+ ("user_btn_e", 0, Pins("AG5"), IOStandard("LVCMOS15")),
+
+ ("user_dip_btn", 0, Pins("Y29"), IOStandard("LVCMOS25")),
+ ("user_dip_btn", 1, Pins("W29"), IOStandard("LVCMOS25")),
+ ("user_dip_btn", 2, Pins("AA28"), IOStandard("LVCMOS25")),
+ ("user_dip_btn", 3, Pins("Y28"), IOStandard("LVCMOS25")),
+
+ ("user_sma_clock", 0,
+ Subsignal("p", Pins("L25"), IOStandard("LVDS_25")),
+ Subsignal("n", Pins("K25"), IOStandard("LVDS_25"))
+ ),
+ ("user_sma_clock_p", 0, Pins("L25"), IOStandard("LVCMOS25")),
+ ("user_sma_clock_n", 0, Pins("K25"), IOStandard("LVCMOS25")),
+
+ ("user_sma_gpio_p", 0, Pins("Y23"), IOStandard("LVCMOS33")),
+ ("user_sma_gpio_n", 0, Pins("Y24"), IOStandard("LVCMOS33")),
+
+ ("clk200", 0,
+ Subsignal("p", Pins("AD12"), IOStandard("LVDS")),
+ Subsignal("n", Pins("AD11"), IOStandard("LVDS"))
+ ),
+
+ ("clk156", 0,
+ Subsignal("p", Pins("K28"), IOStandard("LVDS_25")),
+ Subsignal("n", Pins("K29"), IOStandard("LVDS_25"))
+ ),
+
+ ("i2c", 0,
+ Subsignal("scl", Pins("K21")),
+ Subsignal("sda", Pins("L21")),
+ IOStandard("LVCMOS25")),
+
+ ("serial", 0,
+ Subsignal("cts", Pins("L27")),
+ Subsignal("rts", Pins("K23")),
+ Subsignal("tx", Pins("K24")),
+ Subsignal("rx", Pins("M19")),
+ IOStandard("LVCMOS25")),
+
+ ("spiflash", 0, # clock needs to be accessed through STARTUPE2
+ Subsignal("cs_n", Pins("U19")),
+ Subsignal("dq", Pins("P24", "R25", "R20", "R21")),
+ IOStandard("LVCMOS25")
+ ),
+
+ ("mmc", 0,
+ Subsignal("wp", Pins("Y21")),
+ Subsignal("det", Pins("AA21")),
+ Subsignal("cmd", Pins("AB22")),
+ Subsignal("clk", Pins("AB23")),
+ Subsignal("dat", Pins("AC20 AA23 AA22 AC21")),
+ IOStandard("LVCMOS25")),
+
+ ("lcd", 0,
+ Subsignal("db", Pins("AA13 AA10 AA11 Y10")),
+ Subsignal("e", Pins("AB10")),
+ Subsignal("rs", Pins("Y11")),
+ Subsignal("rw", Pins("AB13")),
+ IOStandard("LVCMOS15")),
+
+ ("rotary", 0,
+ Subsignal("a", Pins("Y26")),
+ Subsignal("b", Pins("Y25")),
+ Subsignal("push", Pins("AA26")),
+ IOStandard("LVCMOS25")),
+
+ ("hdmi", 0,
+ Subsignal("d", Pins("B23 A23 E23 D23 F25 E25 E24 D24 F26 E26 G23 G24 J19 H19 L17 L18 K19 K20")),
+ Subsignal("de", Pins("H17")),
+ Subsignal("clk", Pins("K18")),
+ Subsignal("vsync", Pins("H20")),
+ Subsignal("hsync", Pins("J18")),
+ Subsignal("int", Pins("AH24")),
+ Subsignal("spdif", Pins("J17")),
+ Subsignal("spdif_out", Pins("G20")),
+ IOStandard("LVCMOS25")),
+
+ ("ddram", 0,
+ Subsignal("a", Pins(
+ "AH12 AG13 AG12 AF12 AJ12 AJ13 AJ14 AH14",
+ "AK13 AK14 AF13 AE13 AJ11 AH11 AK10 AK11"),
+ IOStandard("SSTL15")),
+ Subsignal("ba", Pins("AH9 AG9 AK9"), IOStandard("SSTL15")),
+ Subsignal("ras_n", Pins("AD9"), IOStandard("SSTL15")),
+ Subsignal("cas_n", Pins("AC11"), IOStandard("SSTL15")),
+ Subsignal("we_n", Pins("AE9"), IOStandard("SSTL15")),
+ Subsignal("cs_n", Pins("AC12"), IOStandard("SSTL15")),
+ Subsignal("dm", Pins("Y16 AB17 AF17 AE16 AK5 AJ3 AF6 AC7"),
+ IOStandard("SSTL15")),
+ Subsignal("dq", Pins(
+ "AA15 AA16 AC14 AD14 AA17 AB15 AE15 Y15",
+ "AB19 AD16 AC19 AD17 AA18 AB18 AE18 AD18",
+ "AG19 AK19 AG18 AF18 AH19 AJ19 AE19 AD19",
+ "AK16 AJ17 AG15 AF15 AH17 AG14 AH15 AK15",
+ "AK8 AK6 AG7 AF7 AF8 AK4 AJ8 AJ6",
+ "AH5 AH6 AJ2 AH2 AH4 AJ4 AK1 AJ1",
+ "AF1 AF2 AE4 AE3 AF3 AF5 AE1 AE5",
+ "AC1 AD3 AC4 AC5 AE6 AD6 AC2 AD4"),
+ IOStandard("SSTL15_T_DCI")),
+ Subsignal("dqs_p", Pins("AC16 Y19 AJ18 AH16 AH7 AG2 AG4 AD2"),
+ IOStandard("DIFF_SSTL15")),
+ Subsignal("dqs_n", Pins("AC15 Y18 AK18 AJ16 AJ7 AH1 AG3 AD1"),
+ IOStandard("DIFF_SSTL15")),
+ Subsignal("clk_p", Pins("AG10"), IOStandard("DIFF_SSTL15")),
+ Subsignal("clk_n", Pins("AH10"), IOStandard("DIFF_SSTL15")),
+ Subsignal("cke", Pins("AF10"), IOStandard("SSTL15")),
+ Subsignal("odt", Pins("AD8"), IOStandard("SSTL15")),
+ Subsignal("reset_n", Pins("AK3"), IOStandard("LVCMOS15")),
+ Misc("SLEW=FAST"),
+ Misc("VCCAUX_IO=HIGH")
+ ),
+
+ ("eth_clocks", 0,
+ Subsignal("tx", Pins("M28")),
+ Subsignal("gtx", Pins("K30")),
+ Subsignal("rx", Pins("U27")),
+ IOStandard("LVCMOS25")
+ ),
+ ("eth", 0,
+ Subsignal("rst_n", Pins("L20")),
+ Subsignal("int_n", Pins("N30")),
+ Subsignal("mdio", Pins("J21")),
+ Subsignal("mdc", Pins("R23")),
+ Subsignal("dv", Pins("R28")),
+ Subsignal("rx_er", Pins("V26")),
+ Subsignal("rx_data", Pins("U30 U25 T25 U28 R19 T27 T26 T28")),
+ Subsignal("tx_en", Pins("M27")),
+ Subsignal("tx_er", Pins("N29")),
+ Subsignal("tx_data", Pins("N27 N25 M29 L28 J26 K26 L30 J28")),
+ Subsignal("col", Pins("W19")),
+ Subsignal("crs", Pins("R30")),
+ IOStandard("LVCMOS25")
+ ),
+
+ ("pcie_x1", 0,
+ Subsignal("rst_n", Pins("G25"), IOStandard("LVCMOS25")),
+ Subsignal("clk_p", Pins("U8")),
+ Subsignal("clk_n", Pins("U7")),
+ Subsignal("rx_p", Pins("M6")),
+ Subsignal("rx_n", Pins("M5")),
+ Subsignal("tx_p", Pins("L4")),
+ Subsignal("tx_n", Pins("L3"))
+ ),
+ ("pcie_x2", 0,
+ Subsignal("rst_n", Pins("G25"), IOStandard("LVCMOS25")),
+ Subsignal("clk_p", Pins("U8")),
+ Subsignal("clk_n", Pins("U7")),
+ Subsignal("rx_p", Pins("M6 P6")),
+ Subsignal("rx_n", Pins("M5 P5")),
+ Subsignal("tx_p", Pins("L4 M2")),
+ Subsignal("tx_n", Pins("L3 M1"))
+ ),
+ ("pcie_x4", 0,
+ Subsignal("rst_n", Pins("G25"), IOStandard("LVCMOS25")),
+ Subsignal("clk_p", Pins("U8")),
+ Subsignal("clk_n", Pins("U7")),
+ Subsignal("rx_p", Pins("M6 P6 R4 T6")),
+ Subsignal("rx_n", Pins("M5 P5 R3 T5")),
+ Subsignal("tx_p", Pins("L4 M2 N4 P2")),
+ Subsignal("tx_n", Pins("L3 M1 N3 P1"))
+ ),
+ ("pcie_x8", 0,
+ Subsignal("rst_n", Pins("G25"), IOStandard("LVCMOS25")),
+ Subsignal("clk_p", Pins("U8")),
+ Subsignal("clk_n", Pins("U7")),
+ Subsignal("rx_p", Pins("M6 P6 R4 T6 V6 W4 Y6 AA4")),
+ Subsignal("rx_n", Pins("M5 P5 R3 T5 V5 W3 Y5 AA3")),
+ Subsignal("tx_p", Pins("L4 M2 N4 P2 T2 U4 V2 Y2")),
+ Subsignal("tx_n", Pins("L3 M1 N3 P1 T1 U3 V1 Y1"))
+ )
+]
+
+_connectors = [
+ ("HPC", {
+ "DP1_M2C_P": "D6",
+ "DP1_M2C_N": "D5",
+ "DP2_M2C_P": "B6",
+ "DP2_M2C_N": "B5",
+ "DP3_M2C_P": "A8",
+ "DP3_M2C_N": "A7",
+ "DP1_C2M_P": "C4",
+ "DP1_C2M_N": "C3",
+ "DP2_C2M_P": "B2",
+ "DP2_C2M_N": "B1",
+ "DP3_C2M_P": "A4",
+ "DP3_C2M_N": "A3",
+ "DP0_C2M_P": "D2",
+ "DP0_C2M_N": "D1",
+ "DP0_M2C_P": "E4",
+ "DP0_M2C_N": "E3",
+ "LA06_P": "H30",
+ "LA06_N": "G30",
+ "LA10_P": "D29",
+ "LA10_N": "C30",
+ "LA14_P": "B28",
+ "LA14_N": "A28",
+ "LA18_CC_P": "F21",
+ "LA18_CC_N": "E21",
+ "LA27_P": "C19",
+ "LA27_N": "B19",
+ "HA01_CC_P": "H14",
+ "HA01_CC_N": "G14",
+ "HA05_P": "F15",
+ "HA05_N": "E16",
+ "HA09_P": "F12",
+ "HA09_N": "E13",
+ "HA13_P": "L16",
+ "HA13_N": "K16",
+ "HA16_P": "L15",
+ "HA16_N": "K15",
+ "HA20_P": "K13",
+ "HA20_N": "J13",
+ "CLK1_M2C_P": "D17",
+ "CLK1_M2C_N": "D18",
+ "LA00_CC_P": "C25",
+ "LA00_CC_N": "B25",
+ "LA03_P": "H26",
+ "LA03_N": "H27",
+ "LA08_P": "E29",
+ "LA08_N": "E30",
+ "LA12_P": "C29",
+ "LA12_N": "B29",
+ "LA16_P": "B27",
+ "LA16_N": "A27",
+ "LA20_P": "E19",
+ "LA20_N": "D19",
+ "LA22_P": "C20",
+ "LA22_N": "B20",
+ "LA25_P": "G17",
+ "LA25_N": "F17",
+ "LA29_P": "C17",
+ "LA29_N": "B17",
+ "LA31_P": "G22",
+ "LA31_N": "F22",
+ "LA33_P": "H21",
+ "LA33_N": "H22",
+ "HA03_P": "C12",
+ "HA03_N": "B12",
+ "HA07_P": "B14",
+ "HA07_N": "A15",
+ "HA11_P": "B13",
+ "HA11_N": "A13",
+ "HA14_P": "J16",
+ "HA14_N": "H16",
+ "HA18_P": "K14",
+ "HA18_N": "J14",
+ "HA22_P": "L11",
+ "HA22_N": "K11",
+ "GBTCLK1_M2C_P": "E8",
+ "GBTCLK1_M2C_N": "E7",
+ "GBTCLK0_M2C_P": "C8",
+ "GBTCLK0_M2C_N": "C7",
+ "LA01_CC_P": "D26",
+ "LA01_CC_N": "C26",
+ "LA05_P": "G29",
+ "LA05_N": "F30",
+ "LA09_P": "B30",
+ "LA09_N": "A30",
+ "LA13_P": "A25",
+ "LA13_N": "A26",
+ "LA17_CC_P": "F20",
+ "LA17_CC_N": "E20",
+ "LA23_P": "B22",
+ "LA23_N": "A22",
+ "LA26_P": "B18",
+ "LA26_N": "A18",
+ "PG_M2C": "J29",
+ "HA00_CC_P": "D12",
+ "HA00_CC_N": "D13",
+ "HA04_P": "F11",
+ "HA04_N": "E11",
+ "HA08_P": "E14",
+ "HA08_N": "E15",
+ "HA12_P": "C15",
+ "HA12_N": "B15",
+ "HA15_P": "H15",
+ "HA15_N": "G15",
+ "HA19_P": "H11",
+ "HA19_N": "H12",
+ "PRSNT_M2C_B": "M20",
+ "CLK0_M2C_P": "D27",
+ "CLK0_M2C_N": "C27",
+ "LA02_P": "H24",
+ "LA02_N": "H25",
+ "LA04_P": "G28",
+ "LA04_N": "F28",
+ "LA07_P": "E28",
+ "LA07_N": "D28",
+ "LA11_P": "G27",
+ "LA11_N": "F27",
+ "LA15_P": "C24",
+ "LA15_N": "B24",
+ "LA19_P": "G18",
+ "LA19_N": "F18",
+ "LA21_P": "A20",
+ "LA21_N": "A21",
+ "LA24_P": "A16",
+ "LA24_N": "A17",
+ "LA28_P": "D16",
+ "LA28_N": "C16",
+ "LA30_P": "D22",
+ "LA30_N": "C22",
+ "LA32_P": "D21",
+ "LA32_N": "C21",
+ "HA02_P": "D11",
+ "HA02_N": "C11",
+ "HA06_P": "D14",
+ "HA06_N": "C14",
+ "HA10_P": "A11",
+ "HA10_N": "A12",
+ "HA17_CC_P": "G13",
+ "HA17_CC_N": "F13",
+ "HA21_P": "J11",
+ "HA21_N": "J12",
+ "HA23_P": "L12",
+ "HA23_N": "L13",
+ }
+ ),
+ ("LPC", {
+ "GBTCLK0_M2C_P": "N8",
+ "GBTCLK0_M2C_N": "N7",
+ "LA01_CC_P": "AE23",
+ "LA01_CC_N": "AF23",
+ "LA05_P": "AG22",
+ "LA05_N": "AH22",
+ "LA09_P": "AK23",
+ "LA09_N": "AK24",
+ "LA13_P": "AB24",
+ "LA13_N": "AC25",
+ "LA17_CC_P": "AB27",
+ "LA17_CC_N": "AC27",
+ "LA23_P": "AH26",
+ "LA23_N": "AH27",
+ "LA26_P": "AK29",
+ "LA26_N": "AK30",
+ "CLK0_M2C_P": "AF22",
+ "CLK0_M2C_N": "AG23",
+ "LA02_P": "AF20",
+ "LA02_N": "AF21",
+ "LA04_P": "AH21",
+ "LA04_N": "AJ21",
+ "LA07_P": "AG25",
+ "LA07_N": "AH25",
+ "LA11_P": "AE25",
+ "LA11_N": "AF25",
+ "LA15_P": "AC24",
+ "LA15_N": "AD24",
+ "LA19_P": "AJ26",
+ "LA19_N": "AK26",
+ "LA21_P": "AG27",
+ "LA21_N": "AG28",
+ "LA24_P": "AG30",
+ "LA24_N": "AH30",
+ "LA28_P": "AE30",
+ "LA28_N": "AF30",
+ "LA30_P": "AB29",
+ "LA30_N": "AB30",
+ "LA32_P": "Y30",
+ "LA32_N": "AA30",
+ "LA06_P": "AK20",
+ "LA06_N": "AK21",
+ "LA10_P": "AJ24",
+ "LA10_N": "AK25",
+ "LA14_P": "AD21",
+ "LA14_N": "AE21",
+ "LA18_CC_P": "AD27",
+ "LA18_CC_N": "AD28",
+ "LA27_P": "AJ28",
+ "LA27_N": "AJ29",
+ "CLK1_M2C_P": "AG29",
+ "CLK1_M2C_N": "AH29",
+ "LA00_CC_P": "AD23",
+ "LA00_CC_N": "AE24",
+ "LA03_P": "AG20",
+ "LA03_N": "AH20",
+ "LA08_P": "AJ22",
+ "LA08_N": "AJ23",
+ "LA12_P": "AA20",
+ "LA12_N": "AB20",
+ "LA16_P": "AC22",
+ "LA16_N": "AD22",
+ "LA20_P": "AF26",
+ "LA20_N": "AF27",
+ "LA22_P": "AJ27",
+ "LA22_N": "AK28",
+ "LA25_P": "AC26",
+ "LA25_N": "AD26",
+ "LA29_P": "AE28",
+ "LA29_N": "AF28",
+ "LA31_P": "AD29",
+ "LA31_N": "AE29",
+ "LA33_P": "AC29",
+ "LA33_N": "AC30",
+ }
+ )
+]
+
+
+class Platform(XilinxPlatform):
+ identifier = 0x4B37
+ default_clk_name = "clk156"
+ default_clk_period = 6.4
+
+ def __init__(self, toolchain="vivado", programmer="xc3sprog"):
+ XilinxPlatform.__init__(self, "xc7k325t-ffg900-2", _io, _connectors,
+ toolchain=toolchain)
+ if toolchain == "ise":
+ self.toolchain.bitgen_opt = "-g LCK_cycle:6 -g Binary:Yes -w -g ConfigRate:12 -g SPI_buswidth:4"
+ elif toolchain == "vivado":
+ self.toolchain.bitstream_commands = ["set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]"]
+ self.toolchain.additional_commands = ["write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit \"up 0x0 {build_name}.bit\" -file {build_name}.bin"]
+ self.programmer = programmer
+
+ def create_programmer(self):
+ if self.programmer == "xc3sprog":
+ return XC3SProg("jtaghs1_fast", "bscan_spi_kc705.bit")
+ elif self.programmer == "vivado":
+ return VivadoProgrammer()
+ elif self.programmer == "impact":
+ return iMPACT()
+ else:
+ raise ValueError("{} programmer is not supported".format(programmer))
+
+ def do_finalize(self, fragment):
+ XilinxPlatform.do_finalize(self, fragment)
+ try:
+ self.add_period_constraint(self.lookup_request("clk200").p, 5.0)
+ except ConstraintError:
+ pass
+ try:
+ self.add_period_constraint(self.lookup_request("eth_clocks").rx, 8.0)
+ except ConstraintError:
+ pass
+ if isinstance(self.toolchain, XilinxISEToolchain):
+ self.add_platform_command("CONFIG DCI_CASCADE = \"33 32 34\";")
+ else:
+ self.add_platform_command("set_property DCI_CASCADE {{32 34}} [get_iobanks 33]")
--- /dev/null
+# This file is Copyright (c) 2015 Matt O'Gorman <mog@rldn.net>
+# License: BSD
+
+from litex.build.generic_platform import *
+from litex.build.xilinx import XilinxPlatform
+from litex.build.xilinx.programmer import XC3SProg, FpgaProg
+
+
+_io = [
+ ("user_led", 0, Pins("P11"), IOStandard("LVCMOS33")),
+ ("user_led", 1, Pins("N9"), IOStandard("LVCMOS33")),
+ ("user_led", 2, Pins("M9"), IOStandard("LVCMOS33")),
+ ("user_led", 3, Pins("P9"), IOStandard("LVCMOS33")),
+ ("user_led", 4, Pins("T8"), IOStandard("LVCMOS33")),
+ ("user_led", 5, Pins("N8"), IOStandard("LVCMOS33")),
+ ("user_led", 6, Pins("P8"), IOStandard("LVCMOS33")),
+ ("user_led", 7, Pins("P7"), IOStandard("LVCMOS33")),
+
+ ("user_sw", 0, Pins("L1"), IOStandard("LVCMOS33"), Misc("PULLUP")),
+ ("user_sw", 1, Pins("L3"), IOStandard("LVCMOS33"), Misc("PULLUP")),
+ ("user_sw", 2, Pins("L4"), IOStandard("LVCMOS33"), Misc("PULLUP")),
+ ("user_sw", 3, Pins("L5"), IOStandard("LVCMOS33"), Misc("PULLUP")),
+
+ ("clk32", 0, Pins("J4"), IOStandard("LVCMOS33")),
+ ("clk50", 0, Pins("K3"), IOStandard("LVCMOS33")),
+
+ ("spiflash", 0,
+ Subsignal("cs_n", Pins("T3"), IOStandard("LVCMOS33")),
+ Subsignal("clk", Pins("R11"), IOStandard("LVCMOS33")),
+ Subsignal("mosi", Pins("T10"), IOStandard("LVCMOS33")),
+ Subsignal("miso", Pins("P10"), IOStandard("LVCMOS33"))
+ ),
+
+ ("adc", 0,
+ Subsignal("cs_n", Pins("F6"), IOStandard("LVCMOS33")),
+ Subsignal("clk", Pins("G6"), IOStandard("LVCMOS33")),
+ Subsignal("mosi", Pins("H4"), IOStandard("LVCMOS33")),
+ Subsignal("miso", Pins("H5"), IOStandard("LVCMOS33"))
+ ),
+
+ ("serial", 0,
+ Subsignal("tx", Pins("N6"), IOStandard("LVCMOS33")), # FTDI D1
+ Subsignal("rx", Pins("M7"), IOStandard("LVCMOS33")) # FTDI D0
+ ),
+
+ ("audio", 0,
+ Subsignal("a0", Pins("B8"), IOStandard("LVCMOS33")),
+ Subsignal("a1", Pins("A8"), IOStandard("LVCMOS33"))
+ ),
+
+ ("sdram_clock", 0, Pins("G16"), IOStandard("LVCMOS33"), Misc("SLEW=FAST")),
+ ("sdram", 0,
+ Subsignal("a", Pins("T15 R16 P15 P16 N16 M15 M16 L16 K15 K16 R15 J16 H15")),
+ Subsignal("dq", Pins("T13 T12 R12 T9 R9 T7 R7 T6 F16 E15 E16 D16 B16 B15 C16 C15")),
+ Subsignal("we_n", Pins("R5")),
+ Subsignal("ras_n", Pins("R2")),
+ Subsignal("cas_n", Pins("T4")),
+ Subsignal("cs_n", Pins("R1")),
+ Subsignal("cke", Pins("H16")),
+ Subsignal("ba", Pins("R14 T14")),
+ Subsignal("dm", Pins("T5 F15")),
+ IOStandard("LVCMOS33"), Misc("SLEW=FAST")
+ ),
+
+ ("usb_fifo", 0,
+ Subsignal("data", Pins("M7 N6 M6 P5 N5 P4 P2 P1")),
+ Subsignal("rxf_n", Pins("N3")),
+ Subsignal("txe_n", Pins("N1")),
+ Subsignal("rd_n", Pins("M1")),
+ Subsignal("wr_n", Pins("M2")),
+ Subsignal("siwua", Pins("M3")),
+ IOStandard("LVCMOS33"), Drive(8), Misc("SLEW=FAST")
+ ),
+
+ ("sd", 0,
+ Subsignal("sck", Pins("L12")),
+ Subsignal("d3", Pins("K12")),
+ Subsignal("d", Pins("M10")),
+ Subsignal("d1", Pins("L10")),
+ Subsignal("d2", Pins("J11")),
+ Subsignal("cmd", Pins("K11")),
+ IOStandard("LVCMOS33")
+ ),
+
+ ("dvi_in", 0,
+ Subsignal("clk_p", Pins("C9"), IOStandard("TMDS_33")),
+ Subsignal("clk_n", Pins("A9"), IOStandard("TMDS_33")),
+ Subsignal("data_p", Pins("C7 B6 B5"), IOStandard("TMDS_33")),
+ Subsignal("data_n", Pins("A7 A6 A5"), IOStandard("TMDS_33")),
+ Subsignal("scl", Pins("C1"), IOStandard("LVCMOS33")),
+ Subsignal("sda", Pins("B1"), IOStandard("LVCMOS33"))
+ ),
+
+ ("dvi_out", 0,
+ Subsignal("clk_p", Pins("B14"), IOStandard("TMDS_33")),
+ Subsignal("clk_n", Pins("A14"), IOStandard("TMDS_33")),
+ Subsignal("data_p", Pins("C13 B12 C11"), IOStandard("TMDS_33")),
+ Subsignal("data_n", Pins("A13 A12 A11"), IOStandard("TMDS_33")),
+ )
+]
+
+_connectors = [
+ ("A", "E7 C8 D8 E8 D9 A10 B10 C10 E10 F9 F10 D11"),
+ ("B", "E11 D14 D12 E12 E13 F13 F12 F14 G12 H14 J14"),
+ ("C", "J13 J12 K14 L14 L13 M14 M13 N14 M12 N12 P12 M11"),
+ ("D", "D6 C6 E6 C5"),
+ ("E", "D5 A4 G5 A3 B3 A2 B2 C3 C2 D3 D1 E3"),
+ ("F", "E2 E1 E4 F4 F5 G3 F3 G1 H3 H1 H2 J1")
+]
+
+
+class Platform(XilinxPlatform):
+ default_clk_name = "clk32"
+ default_clk_period = 31.25
+
+ def __init__(self, device="xc6slx9", programmer="xc3sprog"):
+ self.programmer = programmer
+ XilinxPlatform.__init__(self, device+"-3-ftg256", _io, _connectors)
+
+ def create_programmer(self):
+ if self.programmer == "xc3sprog":
+ return XC3SProg("minispartan6", "bscan_spi_minispartan6.bit")
+ elif self.programmer == "fpgaprog":
+ return FpgaProg()
+ else:
+ raise ValueError("{} programmer is not supported".format(programmer))
--- /dev/null
+from litex.build.generic_platform import *
+from litex.build.sim import SimPlatform
+
+
+class SimPins(Pins):
+ def __init__(self, n):
+ Pins.__init__(self, "s "*n)
+
+_io = [
+ ("sys_clk", 0, SimPins(1)),
+ ("sys_rst", 0, SimPins(1)),
+ ("serial", 0,
+ Subsignal("source_stb", SimPins(1)),
+ Subsignal("source_ack", SimPins(1)),
+ Subsignal("source_data", SimPins(8)),
+
+ Subsignal("sink_stb", SimPins(1)),
+ Subsignal("sink_ack", SimPins(1)),
+ Subsignal("sink_data", SimPins(8)),
+ ),
+ ("eth_clocks", 0,
+ Subsignal("none", SimPins(1)),
+ ),
+ ("eth", 0,
+ Subsignal("source_stb", SimPins(1)),
+ Subsignal("source_ack", SimPins(1)),
+ Subsignal("source_data", SimPins(8)),
+
+ Subsignal("sink_stb", SimPins(1)),
+ Subsignal("sink_ack", SimPins(1)),
+ Subsignal("sink_data", SimPins(8)),
+ ),
+]
+
+
+class Platform(SimPlatform):
+ is_sim = True
+ default_clk_name = "sys_clk"
+ default_clk_period = 1000 # on modern computers simulate at ~ 1MHz
+
+ def __init__(self):
+ SimPlatform.__init__(self, "SIM", _io)
+
+ def do_finalize(self, fragment):
+ pass
--- /dev/null
+# This file is Copyright (c) 2013 Florent Kermarrec <florent@enjoy-digital.fr>
+# License: BSD
+
+from litex.build.generic_platform import *
+from litex.build.lattice import LatticePlatform
+from litex.build.lattice.programmer import LatticeProgrammer
+
+
+_io = [
+ ("clk100", 0, Pins("L5"), IOStandard("LVDS25")),
+ ("rst_n", 0, Pins("A21"), IOStandard("LVCMOS33")),
+
+ ("user_led", 0, Pins("Y20"), IOStandard("LVCMOS33")),
+ ("user_led", 1, Pins("AA21"), IOStandard("LVCMOS33")),
+ ("user_led", 2, Pins("U18"), IOStandard("LVCMOS33")),
+ ("user_led", 3, Pins("U19"), IOStandard("LVCMOS33")),
+ ("user_led", 4, Pins("W19"), IOStandard("LVCMOS33")),
+ ("user_led", 5, Pins("V19"), IOStandard("LVCMOS33")),
+ ("user_led", 6, Pins("AB20"), IOStandard("LVCMOS33")),
+ ("user_led", 7, Pins("AA20"), IOStandard("LVCMOS33")),
+
+ ("user_dip_btn", 0, Pins("J7"), IOStandard("LVCMOS15")),
+ ("user_dip_btn", 1, Pins("J6"), IOStandard("LVCMOS15")),
+ ("user_dip_btn", 2, Pins("H2"), IOStandard("LVCMOS15")),
+ ("user_dip_btn", 3, Pins("H3"), IOStandard("LVCMOS15")),
+ ("user_dip_btn", 4, Pins("J3"), IOStandard("LVCMOS15")),
+ ("user_dip_btn", 5, Pins("K3"), IOStandard("LVCMOS15")),
+ ("user_dip_btn", 6, Pins("J2"), IOStandard("LVCMOS15")),
+ ("user_dip_btn", 7, Pins("J1"), IOStandard("LVCMOS15")),
+
+ ("serial", 0,
+ Subsignal("tx", Pins("B11"), IOStandard("LVCMOS33")), # X4 IO0
+ Subsignal("rx", Pins("B12"), IOStandard("LVCMOS33")), # X4 IO1
+ ),
+
+ ("eth_clocks", 0,
+ Subsignal("tx", Pins("C12")),
+ Subsignal("gtx", Pins("M2")),
+ Subsignal("rx", Pins("L4")),
+ IOStandard("LVCMOS33")
+ ),
+ ("eth", 0,
+ Subsignal("rst_n", Pins("L3")),
+ Subsignal("mdio", Pins("L2")),
+ Subsignal("mdc", Pins("V4")),
+ Subsignal("dv", Pins("M1")),
+ Subsignal("rx_er", Pins("M4")),
+ Subsignal("rx_data", Pins("M5 N1 N6 P6 T2 R2 P5 P3")),
+ Subsignal("tx_en", Pins("V3")),
+ Subsignal("tx_data", Pins("V1 U1 R3 P1 N5 N3 N4 N2")),
+ Subsignal("col", Pins("R1")),
+ Subsignal("crs", Pins("P4")),
+ IOStandard("LVCMOS33")
+ ),
+
+ ("eth_clocks", 1,
+ Subsignal("tx", Pins("M21")),
+ Subsignal("gtx", Pins("M19")),
+ Subsignal("rx", Pins("N19")),
+ IOStandard("LVCMOS33")
+ ),
+ ("eth", 1,
+ Subsignal("rst_n", Pins("R21")),
+ Subsignal("mdio", Pins("U16")),
+ Subsignal("mdc", Pins("Y18")),
+ Subsignal("dv", Pins("U15")),
+ Subsignal("rx_er", Pins("V20")),
+ Subsignal("rx_data", Pins("AB17 AA17 R19 V21 T17 R18 W21 Y21")),
+ Subsignal("tx_en", Pins("V22")),
+ Subsignal("tx_data", Pins("W22 R16 P17 Y22 T21 U22 P20 U20")),
+ Subsignal("col", Pins("N18")),
+ Subsignal("crs", Pins("P19")),
+ IOStandard("LVCMOS33")
+ ),
+]
+
+
+class Platform(LatticePlatform):
+ default_clk_name = "clk100"
+ default_clk_period = 10
+
+ def __init__(self):
+ LatticePlatform.__init__(self, "LFE3-35EA-6FN484C", _io)
+
+ def do_finalize(self, fragment):
+ LatticePlatform.do_finalize(self, fragment)
+ try:
+ self.add_period_constraint(self.lookup_request("eth_clocks", 0).rx, 8.0)
+ except ConstraintError:
+ pass
+ try:
+ self.add_period_constraint(self.lookup_request("eth_clocks", 1).rx, 8.0)
+ except ConstraintError:
+ pass
+ def create_programmer(self):
+ return LatticeProgrammer()
--- /dev/null
+#!/usr/bin/env python3
+
+import argparse
+
+from litex.gen import *
+from litex.boards.platforms import de0nano
+
+from litex.soc.cores.sdram.settings import IS42S16160
+from litex.soc.cores.sdram.phy import GENSDRPHY
+from litex.soc.integration.soc_sdram import *
+from litex.soc.integration.builder import *
+
+
+class _PLL(Module):
+ def __init__(self, period_in, name, phase_shift, operation_mode):
+ self.clk_in = Signal()
+ self.clk_out = Signal()
+
+ self.specials += Instance("ALTPLL",
+ p_bandwidth_type = "AUTO",
+ p_clk0_divide_by = 1,
+ p_clk0_duty_cycle = 50,
+ p_clk0_multiply_by = 2,
+ p_clk0_phase_shift = "{}".format(str(phase_shift)),
+ p_compensate_clock = "CLK0",
+ p_inclk0_input_frequency = int(period_in*1000),
+ p_intended_device_family = "Cyclone IV E",
+ p_lpm_hint = "CBX_MODULE_PREFIX={}_pll".format(name),
+ p_lpm_type = "altpll",
+ p_operation_mode = operation_mode,
+ i_inclk=self.clk_in,
+ o_clk=self.clk_out,
+ i_areset=0,
+ i_clkena=0x3f,
+ i_clkswitch=0,
+ i_configupdate=0,
+ i_extclkena=0xf,
+ i_fbin=1,
+ i_pfdena=1,
+ i_phasecounterselect=0xf,
+ i_phasestep=1,
+ i_phaseupdown=1,
+ i_pllena=1,
+ i_scanaclr=0,
+ i_scanclk=0,
+ i_scanclkena=1,
+ i_scandata=0,
+ i_scanread=0,
+ i_scanwrite=0
+ )
+
+
+class _CRG(Module):
+ def __init__(self, platform):
+ self.clock_domains.cd_sys = ClockDomain()
+ self.clock_domains.cd_sys_ps = ClockDomain()
+ self.clock_domains.cd_por = ClockDomain(reset_less=True)
+
+ clk50 = platform.request("clk50")
+
+ sys_pll = _PLL(20, "sys", 0, "NORMAL")
+ self.submodules += sys_pll
+ self.comb += [
+ sys_pll.clk_in.eq(clk50),
+ self.cd_sys.clk.eq(sys_pll.clk_out)
+ ]
+
+ sdram_pll = _PLL(20, "sdram", -3000, "ZERO_DELAY_BUFFER")
+ self.submodules += sdram_pll
+ self.comb += [
+ sdram_pll.clk_in.eq(clk50),
+ self.cd_sys_ps.clk.eq(sdram_pll.clk_out)
+ ]
+
+ # Power on Reset (vendor agnostic)
+ rst_n = Signal()
+ self.sync.por += rst_n.eq(1)
+ self.comb += [
+ self.cd_por.clk.eq(self.cd_sys.clk),
+ self.cd_sys.rst.eq(~rst_n),
+ self.cd_sys_ps.rst.eq(~rst_n)
+ ]
+
+ self.comb += platform.request("sdram_clock").eq(self.cd_sys_ps.clk)
+
+
+class BaseSoC(SoCSDRAM):
+ def __init__(self, **kwargs):
+ platform = de0nano.Platform()
+ SoCSDRAM.__init__(self, platform,
+ clk_freq=100*1000000,
+ integrated_rom_size=0x8000,
+ **kwargs)
+
+ self.submodules.crg = _CRG(platform)
+
+ if not self.integrated_main_ram_size:
+ self.submodules.sdrphy = GENSDRPHY(platform.request("sdram"))
+ sdram_module = IS42S16160(self.clk_freq)
+ self.register_sdram(self.sdrphy, "minicon",
+ sdram_module.geom_settings, sdram_module.timing_settings)
+
+def main():
+ parser = argparse.ArgumentParser(description="LiteX SoC port to the Altera DE0 Nano")
+ builder_args(parser)
+ soc_sdram_args(parser)
+ args = parser.parse_args()
+
+ soc = BaseSoC(**soc_sdram_argdict(args))
+ builder = Builder(soc, **builder_argdict(args))
+ builder.build()
+
+
+if __name__ == "__main__":
+ main()
--- /dev/null
+#!/usr/bin/env python3
+
+import argparse
+
+from litex.gen import *
+from litex.gen.genlib.resetsync import AsyncResetSynchronizer
+from litex.boards.platforms import kc705
+
+from litex.soc.cores.sdram.settings import MT8JTF12864
+from litex.soc.cores.sdram.phy import k7ddrphy
+from litex.soc.cores.flash import spi_flash
+from litex.soc.integration.soc_core import mem_decoder
+from litex.soc.integration.soc_sdram import *
+from litex.soc.integration.builder import *
+
+from liteeth.phy import LiteEthPHY
+from liteeth.core.mac import LiteEthMAC
+
+
+class _CRG(Module):
+ def __init__(self, platform):
+ self.clock_domains.cd_sys = ClockDomain()
+ self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
+ self.clock_domains.cd_clk200 = ClockDomain()
+
+ clk200 = platform.request("clk200")
+ clk200_se = Signal()
+ self.specials += Instance("IBUFDS", i_I=clk200.p, i_IB=clk200.n, o_O=clk200_se)
+
+ rst = platform.request("cpu_reset")
+
+ pll_locked = Signal()
+ pll_fb = Signal()
+ self.pll_sys = Signal()
+ pll_sys4x = Signal()
+ pll_clk200 = Signal()
+ self.specials += [
+ Instance("PLLE2_BASE",
+ p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked,
+
+ # VCO @ 1GHz
+ p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=5.0,
+ p_CLKFBOUT_MULT=5, p_DIVCLK_DIVIDE=1,
+ i_CLKIN1=clk200_se, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb,
+
+ # 125MHz
+ p_CLKOUT0_DIVIDE=8, p_CLKOUT0_PHASE=0.0, o_CLKOUT0=self.pll_sys,
+
+ # 500MHz
+ p_CLKOUT1_DIVIDE=2, p_CLKOUT1_PHASE=0.0, o_CLKOUT1=pll_sys4x,
+
+ # 200MHz
+ p_CLKOUT2_DIVIDE=5, p_CLKOUT2_PHASE=0.0, o_CLKOUT2=pll_clk200,
+
+ p_CLKOUT3_DIVIDE=2, p_CLKOUT3_PHASE=0.0, #o_CLKOUT3=,
+
+ p_CLKOUT4_DIVIDE=4, p_CLKOUT4_PHASE=0.0, #o_CLKOUT4=
+ ),
+ Instance("BUFG", i_I=self.pll_sys, o_O=self.cd_sys.clk),
+ Instance("BUFG", i_I=pll_sys4x, o_O=self.cd_sys4x.clk),
+ Instance("BUFG", i_I=pll_clk200, o_O=self.cd_clk200.clk),
+ AsyncResetSynchronizer(self.cd_sys, ~pll_locked | rst),
+ AsyncResetSynchronizer(self.cd_clk200, ~pll_locked | rst),
+ ]
+
+ reset_counter = Signal(4, reset=15)
+ ic_reset = Signal(reset=1)
+ self.sync.clk200 += \
+ If(reset_counter != 0,
+ reset_counter.eq(reset_counter - 1)
+ ).Else(
+ ic_reset.eq(0)
+ )
+ self.specials += Instance("IDELAYCTRL", i_REFCLK=ClockSignal("clk200"), i_RST=ic_reset)
+
+
+class BaseSoC(SoCSDRAM):
+ default_platform = "kc705"
+
+ csr_map = {
+ "spiflash": 16,
+ "ddrphy": 17,
+ }
+ csr_map.update(SoCSDRAM.csr_map)
+
+ def __init__(self, toolchain="ise", sdram_controller_type="minicon", **kwargs):
+ platform = kc705.Platform(toolchain=toolchain)
+ SoCSDRAM.__init__(self, platform,
+ clk_freq=125*1000000, cpu_reset_address=0xaf0000,
+ **kwargs)
+
+ self.submodules.crg = _CRG(platform)
+
+ if not self.integrated_main_ram_size:
+ self.submodules.ddrphy = k7ddrphy.K7DDRPHY(platform.request("ddram"))
+ sdram_module = MT8JTF12864(self.clk_freq)
+ self.register_sdram(self.ddrphy, sdram_controller_type,
+ sdram_module.geom_settings, sdram_module.timing_settings)
+
+ if not self.integrated_rom_size:
+ spiflash_pads = platform.request("spiflash")
+ spiflash_pads.clk = Signal()
+ self.specials += Instance("STARTUPE2",
+ i_CLK=0, i_GSR=0, i_GTS=0, i_KEYCLEARB=0, i_PACK=0,
+ i_USRCCLKO=spiflash_pads.clk, i_USRCCLKTS=0, i_USRDONEO=1, i_USRDONETS=1)
+ self.submodules.spiflash = spi_flash.SpiFlash(spiflash_pads, dummy=11, div=2)
+ self.add_constant("SPIFLASH_PAGE_SIZE", 256)
+ self.add_constant("SPIFLASH_SECTOR_SIZE", 0x10000)
+ self.flash_boot_address = 0xb00000
+ self.register_rom(self.spiflash.bus)
+
+
+class MiniSoC(BaseSoC):
+ csr_map = {
+ "ethphy": 18,
+ "ethmac": 19,
+ }
+ csr_map.update(BaseSoC.csr_map)
+
+ interrupt_map = {
+ "ethmac": 2,
+ }
+ interrupt_map.update(BaseSoC.interrupt_map)
+
+ mem_map = {
+ "ethmac": 0x30000000, # (shadow @0xb0000000)
+ }
+ mem_map.update(BaseSoC.mem_map)
+
+ def __init__(self, *args, **kwargs):
+ BaseSoC.__init__(self, *args, **kwargs)
+
+ self.submodules.ethphy = LiteEthPHY(self.platform.request("eth_clocks"),
+ self.platform.request("eth"), clk_freq=self.clk_freq)
+ self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, interface="wishbone")
+ self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus)
+ self.add_memory_region("ethmac", self.mem_map["ethmac"] | self.shadow_base, 0x2000)
+
+
+def soc_kc705_args(parser):
+ soc_sdram_args(parser)
+ parser.add_argument("--toolchain", default="ise",
+ help="FPGA toolchain to use: ise, vivado")
+
+
+def soc_kc705_argdict(args):
+ r = soc_sdram_argdict(args)
+ r["toolchain"] = args.toolchain
+ return r
+
+
+def main():
+ parser = argparse.ArgumentParser(description="LiteX SoC port to the KC705")
+ builder_args(parser)
+ soc_kc705_args(parser)
+ parser.add_argument("--with-ethernet", action="store_true",
+ help="enable Ethernet support")
+ args = parser.parse_args()
+
+ cls = MiniSoC if args.with_ethernet else BaseSoC
+ soc = cls(**soc_kc705_argdict(args))
+ builder = Builder(soc, **builder_argdict(args))
+ builder.build()
+
+
+if __name__ == "__main__":
+ main()
--- /dev/null
+#!/usr/bin/env python3
+
+import argparse
+from fractions import Fraction
+
+from litex.gen import *
+from litex.gen.genlib.resetsync import AsyncResetSynchronizer
+from litex.boards.platforms import minispartan6
+
+from litex.soc.cores.sdram.settings import AS4C16M16
+from litex.soc.cores.sdram.phy import GENSDRPHY
+from litex.soc.integration.soc_sdram import *
+from litex.soc.integration.builder import *
+
+
+class _CRG(Module):
+ def __init__(self, platform, clk_freq):
+ self.clock_domains.cd_sys = ClockDomain()
+ self.clock_domains.cd_sys_ps = ClockDomain()
+
+ f0 = 32*1000000
+ clk32 = platform.request("clk32")
+ clk32a = Signal()
+ self.specials += Instance("IBUFG", i_I=clk32, o_O=clk32a)
+ clk32b = Signal()
+ self.specials += Instance("BUFIO2", p_DIVIDE=1,
+ p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE",
+ i_I=clk32a, o_DIVCLK=clk32b)
+ f = Fraction(int(clk_freq), int(f0))
+ n, m, p = f.denominator, f.numerator, 8
+ assert f0/n*m == clk_freq
+ pll_lckd = Signal()
+ pll_fb = Signal()
+ pll = Signal(6)
+ self.specials.pll = Instance("PLL_ADV", p_SIM_DEVICE="SPARTAN6",
+ p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL",
+ p_REF_JITTER=.01, p_CLK_FEEDBACK="CLKFBOUT",
+ i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0,
+ p_DIVCLK_DIVIDE=1, p_CLKFBOUT_MULT=m*p//n, p_CLKFBOUT_PHASE=0.,
+ i_CLKIN1=clk32b, i_CLKIN2=0, i_CLKINSEL=1,
+ p_CLKIN1_PERIOD=1000000000/f0, p_CLKIN2_PERIOD=0.,
+ i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd,
+ o_CLKOUT0=pll[0], p_CLKOUT0_DUTY_CYCLE=.5,
+ o_CLKOUT1=pll[1], p_CLKOUT1_DUTY_CYCLE=.5,
+ o_CLKOUT2=pll[2], p_CLKOUT2_DUTY_CYCLE=.5,
+ o_CLKOUT3=pll[3], p_CLKOUT3_DUTY_CYCLE=.5,
+ o_CLKOUT4=pll[4], p_CLKOUT4_DUTY_CYCLE=.5,
+ o_CLKOUT5=pll[5], p_CLKOUT5_DUTY_CYCLE=.5,
+ p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p//1,
+ p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=p//1,
+ p_CLKOUT2_PHASE=0., p_CLKOUT2_DIVIDE=p//1,
+ p_CLKOUT3_PHASE=0., p_CLKOUT3_DIVIDE=p//1,
+ p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=p//1, # sys
+ p_CLKOUT5_PHASE=270., p_CLKOUT5_DIVIDE=p//1, # sys_ps
+ )
+ self.specials += Instance("BUFG", i_I=pll[4], o_O=self.cd_sys.clk)
+ self.specials += Instance("BUFG", i_I=pll[5], o_O=self.cd_sys_ps.clk)
+ self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd)
+
+ self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE",
+ p_INIT=0, p_SRTYPE="SYNC",
+ i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1,
+ i_C0=self.cd_sys.clk, i_C1=~self.cd_sys.clk,
+ o_Q=platform.request("sdram_clock"))
+
+
+class BaseSoC(SoCSDRAM):
+ def __init__(self, **kwargs):
+ clk_freq = 80*1000000
+ platform = minispartan6.Platform()
+ SoCSDRAM.__init__(self, platform, clk_freq,
+ integrated_rom_size=0x8000,
+ **kwargs)
+
+ self.submodules.crg = _CRG(platform, clk_freq)
+
+ if not self.integrated_main_ram_size:
+ self.submodules.sdrphy = GENSDRPHY(platform.request("sdram"))
+ sdram_module = AS4C16M16(clk_freq)
+ self.register_sdram(self.sdrphy, "minicon",
+ sdram_module.geom_settings, sdram_module.timing_settings)
+
+
+def main():
+ parser = argparse.ArgumentParser(description="LiteX SoC port to the MiniSpartan6")
+ builder_args(parser)
+ soc_sdram_args(parser)
+ args = parser.parse_args()
+
+ soc = BaseSoC(**soc_sdram_argdict(args))
+ builder = Builder(soc, **builder_argdict(args))
+ builder.build()
+
+
+if __name__ == "__main__":
+ main()
--- /dev/null
+#!/usr/bin/env python3
+
+import argparse
+from fractions import Fraction
+
+from litex.gen import *
+from litex.gen.genlib.resetsync import AsyncResetSynchronizer
+from litex.boards.platforms import papilio_pro
+
+from litex.soc.cores.sdram.settings import MT48LC4M16
+from litex.soc.cores.sdram.phy import GENSDRPHY
+from litex.soc.cores.flash import spi_flash
+from litex.soc.integration.soc_sdram import *
+from litex.soc.integration.builder import *
+
+
+class _CRG(Module):
+ def __init__(self, platform, clk_freq):
+ self.clock_domains.cd_sys = ClockDomain()
+ self.clock_domains.cd_sys_ps = ClockDomain()
+
+ f0 = 32*1000000
+ clk32 = platform.request("clk32")
+ clk32a = Signal()
+ self.specials += Instance("IBUFG", i_I=clk32, o_O=clk32a)
+ clk32b = Signal()
+ self.specials += Instance("BUFIO2", p_DIVIDE=1,
+ p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE",
+ i_I=clk32a, o_DIVCLK=clk32b)
+ f = Fraction(int(clk_freq), int(f0))
+ n, m, p = f.denominator, f.numerator, 8
+ assert f0/n*m == clk_freq
+ pll_lckd = Signal()
+ pll_fb = Signal()
+ pll = Signal(6)
+ self.specials.pll = Instance("PLL_ADV", p_SIM_DEVICE="SPARTAN6",
+ p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL",
+ p_REF_JITTER=.01, p_CLK_FEEDBACK="CLKFBOUT",
+ i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0,
+ p_DIVCLK_DIVIDE=1, p_CLKFBOUT_MULT=m*p//n, p_CLKFBOUT_PHASE=0.,
+ i_CLKIN1=clk32b, i_CLKIN2=0, i_CLKINSEL=1,
+ p_CLKIN1_PERIOD=1000000000/f0, p_CLKIN2_PERIOD=0.,
+ i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd,
+ o_CLKOUT0=pll[0], p_CLKOUT0_DUTY_CYCLE=.5,
+ o_CLKOUT1=pll[1], p_CLKOUT1_DUTY_CYCLE=.5,
+ o_CLKOUT2=pll[2], p_CLKOUT2_DUTY_CYCLE=.5,
+ o_CLKOUT3=pll[3], p_CLKOUT3_DUTY_CYCLE=.5,
+ o_CLKOUT4=pll[4], p_CLKOUT4_DUTY_CYCLE=.5,
+ o_CLKOUT5=pll[5], p_CLKOUT5_DUTY_CYCLE=.5,
+ p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p//1,
+ p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=p//1,
+ p_CLKOUT2_PHASE=0., p_CLKOUT2_DIVIDE=p//1,
+ p_CLKOUT3_PHASE=0., p_CLKOUT3_DIVIDE=p//1,
+ p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=p//1, # sys
+ p_CLKOUT5_PHASE=270., p_CLKOUT5_DIVIDE=p//1, # sys_ps
+ )
+ self.specials += Instance("BUFG", i_I=pll[4], o_O=self.cd_sys.clk)
+ self.specials += Instance("BUFG", i_I=pll[5], o_O=self.cd_sys_ps.clk)
+ self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd)
+
+ self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE",
+ p_INIT=0, p_SRTYPE="SYNC",
+ i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1,
+ i_C0=self.cd_sys.clk, i_C1=~self.cd_sys.clk,
+ o_Q=platform.request("sdram_clock"))
+
+
+class BaseSoC(SoCSDRAM):
+ csr_map = {
+ "spiflash": 16,
+ }
+ csr_map.update(SoCSDRAM.csr_map)
+
+ def __init__(self, **kwargs):
+ platform = papilio_pro.Platform()
+ clk_freq = 80*1000000
+ SoCSDRAM.__init__(self, platform, clk_freq,
+ cpu_reset_address=0x60000,
+ **kwargs)
+
+ self.submodules.crg = _CRG(platform, clk_freq)
+
+ if not self.integrated_main_ram_size:
+ self.submodules.sdrphy = GENSDRPHY(platform.request("sdram"))
+ sdram_module = MT48LC4M16(clk_freq)
+ self.register_sdram(self.sdrphy, "minicon",
+ sdram_module.geom_settings, sdram_module.timing_settings)
+
+ if not self.integrated_rom_size:
+ self.submodules.spiflash = spi_flash.SpiFlash(platform.request("spiflash2x"),
+ dummy=4, div=6)
+ self.flash_boot_address = 0x70000
+ self.register_rom(self.spiflash.bus)
+
+
+def main():
+ parser = argparse.ArgumentParser(description="LiteX SoC port to the Papilio Pro")
+ builder_args(parser)
+ soc_sdram_args(parser)
+ args = parser.parse_args()
+
+ soc = BaseSoC(**soc_sdram_argdict(args))
+ builder = Builder(soc, **builder_argdict(args))
+ builder.build()
+
+
+if __name__ == "__main__":
+ main()
--- /dev/null
+#!/usr/bin/env python3
+
+import argparse
+from fractions import Fraction
+
+from litex.gen import *
+from litex.gen.genlib.resetsync import AsyncResetSynchronizer
+from litex.boards.platforms import pipistrello
+
+from litex.soc.cores.sdram_settings import MT46H32M16
+from litex.soc.cores.sdram_phy import S6HalfRateDDRPHY
+from litex.soc.cores.flash import spi_flash
+from litex.soc.integration.soc_sdram import *
+from litex.soc.integration.builder import *
+
+
+class _CRG(Module):
+ def __init__(self, platform, clk_freq):
+ self.clock_domains.cd_sys = ClockDomain()
+ self.clock_domains.cd_sdram_half = ClockDomain()
+ self.clock_domains.cd_sdram_full_wr = ClockDomain()
+ self.clock_domains.cd_sdram_full_rd = ClockDomain()
+
+ self.clk4x_wr_strb = Signal()
+ self.clk4x_rd_strb = Signal()
+
+ f0 = Fraction(50, 1)*1000000
+ p = 12
+ f = Fraction(clk_freq*p, f0)
+ n, d = f.numerator, f.denominator
+ assert 19e6 <= f0/d <= 500e6 # pfd
+ assert 400e6 <= f0*n/d <= 1080e6 # vco
+
+ clk50 = platform.request("clk50")
+ clk50a = Signal()
+ self.specials += Instance("IBUFG", i_I=clk50, o_O=clk50a)
+ clk50b = Signal()
+ self.specials += Instance("BUFIO2", p_DIVIDE=1,
+ p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE",
+ i_I=clk50a, o_DIVCLK=clk50b)
+ pll_lckd = Signal()
+ pll_fb = Signal()
+ pll = Signal(6)
+ self.specials.pll = Instance("PLL_ADV", p_SIM_DEVICE="SPARTAN6",
+ p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL",
+ p_REF_JITTER=.01, p_CLK_FEEDBACK="CLKFBOUT",
+ i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0,
+ p_DIVCLK_DIVIDE=d, p_CLKFBOUT_MULT=n, p_CLKFBOUT_PHASE=0.,
+ i_CLKIN1=clk50b, i_CLKIN2=0, i_CLKINSEL=1,
+ p_CLKIN1_PERIOD=1e9/f0, p_CLKIN2_PERIOD=0.,
+ i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd,
+ o_CLKOUT0=pll[0], p_CLKOUT0_DUTY_CYCLE=.5,
+ o_CLKOUT1=pll[1], p_CLKOUT1_DUTY_CYCLE=.5,
+ o_CLKOUT2=pll[2], p_CLKOUT2_DUTY_CYCLE=.5,
+ o_CLKOUT3=pll[3], p_CLKOUT3_DUTY_CYCLE=.5,
+ o_CLKOUT4=pll[4], p_CLKOUT4_DUTY_CYCLE=.5,
+ o_CLKOUT5=pll[5], p_CLKOUT5_DUTY_CYCLE=.5,
+ p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p//4, # sdram wr rd
+ p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=p//4,
+ p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=p//2, # sdram dqs adr ctrl
+ p_CLKOUT3_PHASE=250., p_CLKOUT3_DIVIDE=p//2, # off-chip ddr
+ p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=p//1,
+ p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=p//1, # sys
+ )
+ self.specials += Instance("BUFG", i_I=pll[5], o_O=self.cd_sys.clk)
+ reset = platform.request("user_btn")
+ self.clock_domains.cd_por = ClockDomain()
+ por = Signal(max=1 << 11, reset=(1 << 11) - 1)
+ self.sync.por += If(por != 0, por.eq(por - 1))
+ self.comb += self.cd_por.clk.eq(self.cd_sys.clk)
+ self.specials += AsyncResetSynchronizer(self.cd_por, reset)
+ self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0))
+ self.specials += Instance("BUFG", i_I=pll[2], o_O=self.cd_sdram_half.clk)
+ self.specials += Instance("BUFPLL", p_DIVIDE=4,
+ i_PLLIN=pll[0], i_GCLK=self.cd_sys.clk,
+ i_LOCKED=pll_lckd, o_IOCLK=self.cd_sdram_full_wr.clk,
+ o_SERDESSTROBE=self.clk4x_wr_strb)
+ self.comb += [
+ self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk),
+ self.clk4x_rd_strb.eq(self.clk4x_wr_strb),
+ ]
+ clk_sdram_half_shifted = Signal()
+ self.specials += Instance("BUFG", i_I=pll[3], o_O=clk_sdram_half_shifted)
+ clk = platform.request("ddram_clock")
+ self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE",
+ p_INIT=0, p_SRTYPE="SYNC",
+ i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1,
+ i_C0=clk_sdram_half_shifted, i_C1=~clk_sdram_half_shifted,
+ o_Q=clk.p)
+ self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE",
+ p_INIT=0, p_SRTYPE="SYNC",
+ i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1,
+ i_C0=clk_sdram_half_shifted, i_C1=~clk_sdram_half_shifted,
+ o_Q=clk.n)
+
+
+class BaseSoC(SoCSDRAM):
+ csr_map = {
+ "spiflash": 16,
+ }
+ csr_map.update(SoCSDRAM.csr_map)
+
+ def __init__(self, clk_freq=(83 + Fraction(1, 3))*1000*1000, **kwargs):
+ platform = pipistrello.Platform()
+ SoCSDRAM.__init__(self, platform, clk_freq,
+ cpu_reset_address=0x170000, # 1.5 MB
+ **kwargs)
+
+ self.submodules.crg = _CRG(platform, clk_freq)
+
+ if not self.integrated_main_ram_size:
+ sdram_module = MT46H32M16(self.clk_freq)
+ self.submodules.ddrphy = S6HalfRateDDRPHY(platform.request("ddram"),
+ sdram_module.memtype,
+ rd_bitslip=1,
+ wr_bitslip=3,
+ dqs_ddr_alignment="C1")
+ self.comb += [
+ self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb),
+ self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb),
+ ]
+ self.register_sdram(self.ddrphy, "minicon",
+ sdram_module.geom_settings, sdram_module.timing_settings)
+
+ if not self.integrated_rom_size:
+ self.submodules.spiflash = spi_flash.SpiFlash(platform.request("spiflash4x"),
+ dummy=10, div=4)
+ self.add_constant("SPIFLASH_PAGE_SIZE", 256)
+ self.add_constant("SPIFLASH_SECTOR_SIZE", 0x10000)
+ self.flash_boot_address = 0x180000
+ self.register_rom(self.spiflash.bus, 0x1000000)
+
+
+soc_pipistrello_args = soc_sdram_args
+soc_pipistrello_argdict = soc_sdram_argdict
+
+
+def main():
+ parser = argparse.ArgumentParser(description="LiteX SoC port to the Pipistrello")
+ builder_args(parser)
+ soc_pipistrello_args(parser)
+ args = parser.parse_args()
+
+ soc = BaseSoC(**soc_pipistrello_argdict(args))
+ builder = Builder(soc, **builder_argdict(args))
+ builder.build()
+
+
+if __name__ == "__main__":
+ main()
+
--- /dev/null
+#!/usr/bin/env python3
+
+import argparse
+import importlib
+
+from litex.gen import *
+from litex.gen.genlib.io import CRG
+
+from litex.soc.integration.soc_core import *
+from litex.soc.integration.builder import *
+
+from liteeth.phy import LiteEthPHY
+from liteeth.core.mac import LiteEthMAC
+
+
+class BaseSoC(SoCCore):
+ def __init__(self, platform, **kwargs):
+ SoCCore.__init__(self, platform,
+ clk_freq=int((1/(platform.default_clk_period))*1000000000),
+ integrated_rom_size=0x8000,
+ integrated_main_ram_size=16*1024,
+ **kwargs)
+ self.submodules.crg = CRG(platform.request(platform.default_clk_name))
+
+
+class MiniSoC(BaseSoC):
+ csr_map = {
+ "ethphy": 20,
+ "ethmac": 21
+ }
+ csr_map.update(BaseSoC.csr_map)
+
+ interrupt_map = {
+ "ethmac": 2,
+ }
+ interrupt_map.update(BaseSoC.interrupt_map)
+
+ mem_map = {
+ "ethmac": 0x30000000, # (shadow @0xb0000000)
+ }
+ mem_map.update(BaseSoC.mem_map)
+
+ def __init__(self, platform, **kwargs):
+ BaseSoC.__init__(self, platform, **kwargs)
+
+ self.submodules.ethphy = LiteEthPHY(platform.request("eth_clocks"),
+ platform.request("eth"))
+ self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32,
+ interface="wishbone",
+ with_preamble_crc=False)
+ self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus)
+ self.add_memory_region("ethmac", self.mem_map["ethmac"] | self.shadow_base, 0x2000)
+
+
+def main():
+ parser = argparse.ArgumentParser(description="Generic LiteX SoC")
+ builder_args(parser)
+ soc_core_args(parser)
+ parser.add_argument("--with-ethernet", action="store_true",
+ help="enable Ethernet support")
+ parser.add_argument("platform",
+ help="module name of the platform to build for")
+ args = parser.parse_args()
+
+ platform_module = importlib.import_module(args.platform)
+ platform = platform_module.Platform()
+ cls = MiniSoC if args.with_ethernet else BaseSoC
+ soc = cls(platform, **soc_core_argdict(args))
+ builder = Builder(soc, **builder_argdict(args))
+ builder.build()
+
+
+if __name__ == "__main__":
+ main()
--- /dev/null
+from litex.build.altera.platform import AlteraPlatform
+from litex.build.altera.programmer import USBBlaster
--- /dev/null
+from litex.gen.fhdl.module import Module
+from litex.gen.fhdl.specials import Instance
+from litex.gen.genlib.io import DifferentialInput, DifferentialOutput
+
+
+class AlteraDifferentialInputImpl(Module):
+ def __init__(self, i_p, i_n, o):
+ self.specials += Instance("ALT_INBUF_DIFF",
+ name="ibuf_diff",
+ i_i=i_p,
+ i_ibar=i_n,
+ o_o=o)
+
+
+class AlteraDifferentialInput:
+ @staticmethod
+ def lower(dr):
+ return AlteraDifferentialInputImpl(dr.i_p, dr.i_n, dr.o)
+
+
+class AlteraDifferentialOutputImpl(Module):
+ def __init__(self, i, o_p, o_n):
+ self.specials += Instance("ALT_OUTBUF_DIFF",
+ name="obuf_diff",
+ i_i=i,
+ o_o=o_p,
+ o_obar=o_n)
+
+
+class AlteraDifferentialOutput:
+ @staticmethod
+ def lower(dr):
+ return AlteraDifferentialOutputImpl(dr.i, dr.o_p, dr.o_n)
+
+
+altera_special_overrides = {
+ DifferentialInput: AlteraDifferentialInput,
+ DifferentialOutput: AlteraDifferentialOutput
+}
--- /dev/null
+from litex.build.generic_platform import GenericPlatform
+from litex.build.altera import common, quartus
+
+
+class AlteraPlatform(GenericPlatform):
+ bitstream_ext = ".sof"
+
+ def __init__(self, *args, toolchain="quartus", **kwargs):
+ GenericPlatform.__init__(self, *args, **kwargs)
+ if toolchain == "quartus":
+ self.toolchain = quartus.AlteraQuartusToolchain()
+ else:
+ raise ValueError("Unknown toolchain")
+
+ def get_verilog(self, *args, special_overrides=dict(), **kwargs):
+ so = dict(common.altera_special_overrides)
+ so.update(special_overrides)
+ return GenericPlatform.get_verilog(self, *args, special_overrides=so,
+ **kwargs)
+
+ def build(self, *args, **kwargs):
+ return self.toolchain.build(self, *args, **kwargs)
+
+ def add_period_constraint(self, clk, period):
+ if hasattr(clk, "p"):
+ clk = clk.p
+ self.toolchain.add_period_constraint(self, clk, period)
--- /dev/null
+import subprocess
+
+from litex.build.generic_programmer import GenericProgrammer
+
+
+class USBBlaster(GenericProgrammer):
+ needs_bitreverse = False
+
+ def load_bitstream(self, bitstream_file, port=0):
+ usb_port = "[USB-{}]".format(port)
+ subprocess.call(["quartus_pgm", "-m", "jtag", "-c",
+ "USB-Blaster{}".format(usb_port), "-o",
+ "p;{}".format(bitstream_file)])
--- /dev/null
+# This file is Copyright (c) 2013 Florent Kermarrec <florent@enjoy-digital.fr>
+# License: BSD
+
+import os
+import subprocess
+
+from litex.gen.fhdl.structure import _Fragment
+
+from litex.build.generic_platform import Pins, IOStandard, Misc
+from litex.build import tools
+
+
+def _format_constraint(c, signame, fmt_r):
+ if isinstance(c, Pins):
+ return "set_location_assignment -comment \"{name}\" " \
+ "-to {signame} Pin_{pin}".format(
+ signame=signame,
+ name=fmt_r,
+ pin=c.identifiers[0])
+ elif isinstance(c, IOStandard):
+ return "set_instance_assignment -name io_standard " \
+ "-comment \"{name}\" \"{std}\" -to {signame}".format(
+ signame=signame,
+ name=fmt_r,
+ std=c.name)
+ elif isinstance(c, Misc):
+ if not isinstance(c.misc, str) and len(c.misc) == 2:
+ return "set_instance_assignment -comment \"{name}\" " \
+ "-name {misc[0]} \"{misc[1]}\" -to {signame}".format(
+ signame=signame,
+ name=fmt_r,
+ misc=c.misc)
+ else:
+ return "set_instance_assignment -comment \"{name}\" " \
+ "-name {misc} " \
+ "-to {signame}".format(
+ signame=signame,
+ name=fmt_r,
+ misc=c.misc)
+
+
+def _format_qsf(signame, pin, others, resname):
+ fmt_r = "{}:{}".format(*resname[:2])
+ if resname[2] is not None:
+ fmt_r += "." + resname[2]
+
+ fmt_c = [_format_constraint(c, signame, fmt_r) for c in
+ ([Pins(pin)] + others)]
+
+ return '\n'.join(fmt_c)
+
+
+def _build_qsf(named_sc, named_pc):
+ lines = []
+ for sig, pins, others, resname in named_sc:
+ if len(pins) > 1:
+ for i, p in enumerate(pins):
+ lines.append(
+ _format_qsf("{}[{}]".format(sig, i), p, others, resname))
+ else:
+ lines.append(_format_qsf(sig, pins[0], others, resname))
+
+ if named_pc:
+ lines.append("")
+ lines.append("\n\n".join(named_pc))
+
+ lines.append("set_global_assignment -name top_level_entity top")
+ return "\n".join(lines)
+
+
+def _build_files(device, sources, vincpaths, named_sc, named_pc, build_name):
+ lines = []
+ for filename, language, library in sources:
+ # Enforce use of SystemVerilog
+ # (Quartus does not support global parameters in Verilog)
+ if language == "verilog":
+ language = "systemverilog"
+ lines.append(
+ "set_global_assignment -name {lang}_FILE {path} "
+ "-library {lib}".format(
+ lang=language.upper(),
+ path=filename.replace("\\", "/"),
+ lib=library))
+
+ for path in vincpaths:
+ lines.append("set_global_assignment -name SEARCH_PATH {}".format(
+ path.replace("\\", "/")))
+
+ lines.append(_build_qsf(named_sc, named_pc))
+ lines.append("set_global_assignment -name DEVICE {}".format(device))
+ tools.write_to_file("{}.qsf".format(build_name), "\n".join(lines))
+
+
+def _run_quartus(build_name, quartus_path):
+ build_script_contents = """# Autogenerated by LiteX
+
+set -e
+
+quartus_map --read_settings_files=on --write_settings_files=off {build_name} -c {build_name}
+quartus_fit --read_settings_files=off --write_settings_files=off {build_name} -c {build_name}
+quartus_asm --read_settings_files=off --write_settings_files=off {build_name} -c {build_name}
+quartus_sta {build_name} -c {build_name}
+
+""".format(build_name=build_name) # noqa
+ build_script_file = "build_" + build_name + ".sh"
+ tools.write_to_file(build_script_file,
+ build_script_contents,
+ force_unix=True)
+
+ if subprocess.call(["bash", build_script_file]):
+ raise OSError("Subprocess failed")
+
+
+class AlteraQuartusToolchain:
+ def build(self, platform, fragment, build_dir="build", build_name="top",
+ toolchain_path="/opt/Altera", run=True):
+ tools.mkdir_noerror(build_dir)
+ os.chdir(build_dir)
+
+ if not isinstance(fragment, _Fragment):
+ fragment = fragment.get_fragment()
+ platform.finalize(fragment)
+
+ v_output = platform.get_verilog(fragment)
+ named_sc, named_pc = platform.resolve_signals(v_output.ns)
+ v_file = build_name + ".v"
+ v_output.write(v_file)
+ sources = platform.sources | {(v_file, "verilog", "work")}
+ _build_files(platform.device,
+ sources,
+ platform.verilog_include_paths,
+ named_sc,
+ named_pc,
+ build_name)
+ if run:
+ _run_quartus(build_name, toolchain_path)
+
+ os.chdir("..")
+
+ return v_output.ns
+
+ def add_period_constraint(self, platform, clk, period):
+ # TODO: handle differential clk
+ platform.add_platform_command(
+ "set_global_assignment -name duty_cycle 50 -section_id {clk}",
+ clk=clk)
+ platform.add_platform_command(
+ "set_global_assignment -name fmax_requirement \"{freq} MHz\" "
+ "-section_id {clk}".format(freq=(1. / period) * 1000,
+ clk="{clk}"),
+ clk=clk)
--- /dev/null
+import os
+
+from litex.gen.fhdl.structure import Signal
+from litex.gen.genlib.record import Record
+from litex.gen.genlib.io import CRG
+from litex.gen.fhdl import verilog, edif
+from litex.build import tools
+
+
+class ConstraintError(Exception):
+ pass
+
+
+class Pins:
+ def __init__(self, *identifiers):
+ self.identifiers = []
+ for i in identifiers:
+ self.identifiers += i.split()
+
+ def __repr__(self):
+ return "{}('{}')".format(self.__class__.__name__,
+ " ".join(self.identifiers))
+
+
+class IOStandard:
+ def __init__(self, name):
+ self.name = name
+
+ def __repr__(self):
+ return "{}('{}')".format(self.__class__.__name__, self.name)
+
+
+class Drive:
+ def __init__(self, strength):
+ self.strength = strength
+
+ def __repr__(self):
+ return "{}('{}')".format(self.__class__.__name__, self.strength)
+
+
+class Misc:
+ def __init__(self, misc):
+ self.misc = misc
+
+ def __repr__(self):
+ return "{}({})".format(self.__class__.__name__, repr(self.misc))
+
+
+class Subsignal:
+ def __init__(self, name, *constraints):
+ self.name = name
+ self.constraints = list(constraints)
+
+ def __repr__(self):
+ return "{}('{}', {})".format(
+ self.__class__.__name__,
+ self.name,
+ ", ".join([repr(constr) for constr in self.constraints]))
+
+
+class PlatformInfo:
+ def __init__(self, info):
+ self.info = info
+
+ def __repr__(self):
+ return "{}({})".format(self.__class__.__name__, repr(self.info))
+
+
+def _lookup(description, name, number):
+ for resource in description:
+ if resource[0] == name and (number is None or resource[1] == number):
+ return resource
+ raise ConstraintError("Resource not found: {}:{}".format(name, number))
+
+
+def _resource_type(resource):
+ t = None
+ for element in resource[2:]:
+ if isinstance(element, Pins):
+ assert(t is None)
+ t = len(element.identifiers)
+ elif isinstance(element, Subsignal):
+ if t is None:
+ t = []
+
+ assert(isinstance(t, list))
+ n_bits = None
+ for c in element.constraints:
+ if isinstance(c, Pins):
+ assert(n_bits is None)
+ n_bits = len(c.identifiers)
+
+ t.append((element.name, n_bits))
+
+ return t
+
+
+class ConnectorManager:
+ def __init__(self, connectors):
+ self.connector_table = dict()
+ for connector in connectors:
+ cit = iter(connector)
+ conn_name = next(cit)
+ if isinstance(connector[1], str):
+ pin_list = []
+ for pins in cit:
+ pin_list += pins.split()
+ pin_list = [None if pin == "None" else pin for pin in pin_list]
+ elif isinstance(connector[1], dict):
+ pin_list = connector[1]
+ else:
+ raise ValueError("Unsupported pin list type {} for connector"
+ " {}".format(type(connector[1]), conn_name))
+ if conn_name in self.connector_table:
+ raise ValueError(
+ "Connector specified more than once: {}".format(conn_name))
+
+ self.connector_table[conn_name] = pin_list
+
+ def resolve_identifiers(self, identifiers):
+ r = []
+ for identifier in identifiers:
+ if ":" in identifier:
+ conn, pn = identifier.split(":")
+ if pn.isdigit():
+ pn = int(pn)
+
+ r.append(self.connector_table[conn][pn])
+ else:
+ r.append(identifier)
+
+ return r
+
+
+def _separate_pins(constraints):
+ pins = None
+ others = []
+ for c in constraints:
+ if isinstance(c, Pins):
+ assert(pins is None)
+ pins = c.identifiers
+ else:
+ others.append(c)
+
+ return pins, others
+
+
+class ConstraintManager:
+ def __init__(self, io, connectors):
+ self.available = list(io)
+ self.matched = []
+ self.platform_commands = []
+ self.connector_manager = ConnectorManager(connectors)
+
+ def add_extension(self, io):
+ self.available.extend(io)
+
+ def request(self, name, number=None):
+ resource = _lookup(self.available, name, number)
+ rt = _resource_type(resource)
+ if isinstance(rt, int):
+ obj = Signal(rt, name_override=resource[0])
+ else:
+ obj = Record(rt, name=resource[0])
+
+ for element in resource[2:]:
+ if isinstance(element, PlatformInfo):
+ obj.platform_info = element.info
+ break
+
+ self.available.remove(resource)
+ self.matched.append((resource, obj))
+ return obj
+
+ def lookup_request(self, name, number=None):
+ for resource, obj in self.matched:
+ if resource[0] == name and (number is None or
+ resource[1] == number):
+ return obj
+
+ raise ConstraintError("Resource not found: {}:{}".format(name, number))
+
+ def add_platform_command(self, command, **signals):
+ self.platform_commands.append((command, signals))
+
+ def get_io_signals(self):
+ r = set()
+ for resource, obj in self.matched:
+ if isinstance(obj, Signal):
+ r.add(obj)
+ else:
+ r.update(obj.flatten())
+
+ return r
+
+ def get_sig_constraints(self):
+ r = []
+ for resource, obj in self.matched:
+ name = resource[0]
+ number = resource[1]
+ has_subsignals = False
+ top_constraints = []
+ for element in resource[2:]:
+ if isinstance(element, Subsignal):
+ has_subsignals = True
+ else:
+ top_constraints.append(element)
+
+ if has_subsignals:
+ for element in resource[2:]:
+ if isinstance(element, Subsignal):
+ sig = getattr(obj, element.name)
+ pins, others = _separate_pins(top_constraints +
+ element.constraints)
+ pins = self.connector_manager.resolve_identifiers(pins)
+ r.append((sig, pins, others,
+ (name, number, element.name)))
+ else:
+ pins, others = _separate_pins(top_constraints)
+ pins = self.connector_manager.resolve_identifiers(pins)
+ r.append((obj, pins, others, (name, number, None)))
+
+ return r
+
+ def get_platform_commands(self):
+ return self.platform_commands
+
+
+class GenericPlatform:
+ def __init__(self, device, io, connectors=[], name=None):
+ self.device = device
+ self.constraint_manager = ConstraintManager(io, connectors)
+ if name is None:
+ name = self.__module__.split(".")[-1]
+ self.name = name
+ self.sources = set()
+ self.verilog_include_paths = set()
+ self.finalized = False
+
+ def request(self, *args, **kwargs):
+ return self.constraint_manager.request(*args, **kwargs)
+
+ def lookup_request(self, *args, **kwargs):
+ return self.constraint_manager.lookup_request(*args, **kwargs)
+
+ def add_period_constraint(self, clk, period):
+ raise NotImplementedError
+
+ def add_platform_command(self, *args, **kwargs):
+ return self.constraint_manager.add_platform_command(*args, **kwargs)
+
+ def add_extension(self, *args, **kwargs):
+ return self.constraint_manager.add_extension(*args, **kwargs)
+
+ def finalize(self, fragment, *args, **kwargs):
+ if self.finalized:
+ raise ConstraintError("Already finalized")
+ # if none exists, create a default clock domain and drive it
+ if not fragment.clock_domains:
+ if not hasattr(self, "default_clk_name"):
+ raise NotImplementedError(
+ "No default clock and no clock domain defined")
+ crg = CRG(self.request(self.default_clk_name))
+ fragment += crg.get_fragment()
+
+ self.do_finalize(fragment, *args, **kwargs)
+ self.finalized = True
+
+ def do_finalize(self, fragment, *args, **kwargs):
+ """overload this and e.g. add_platform_command()'s after the modules
+ had their say"""
+ if hasattr(self, "default_clk_period"):
+ try:
+ self.add_period_constraint(
+ self.lookup_request(self.default_clk_name),
+ self.default_clk_period)
+ except ConstraintError:
+ pass
+
+ def add_source(self, filename, language=None, library=None):
+ if language is None:
+ language = tools.language_by_filename(filename)
+ if language is None:
+ language = "verilog"
+
+ if library is None:
+ library = "work"
+
+ self.sources.add((os.path.abspath(filename), language, library))
+
+ def add_sources(self, path, *filenames, language=None, library=None):
+ for f in filenames:
+ self.add_source(os.path.join(path, f), language, library)
+
+ def add_source_dir(self, path, recursive=True, library=None):
+ dir_files = []
+ if recursive:
+ for root, dirs, files in os.walk(path):
+ for filename in files:
+ dir_files.append(os.path.join(root, filename))
+ else:
+ for item in os.listdir(path):
+ if os.path.isfile(os.path.join(path, item)):
+ dir_files.append(os.path.join(path, item))
+ for filename in dir_files:
+ language = tools.language_by_filename(filename)
+ if language is not None:
+ self.add_source(filename, language, library)
+
+ def add_verilog_include_path(self, path):
+ self.verilog_include_paths.add(os.path.abspath(path))
+
+ def resolve_signals(self, vns):
+ # resolve signal names in constraints
+ sc = self.constraint_manager.get_sig_constraints()
+ named_sc = [(vns.get_name(sig), pins, others, resource)
+ for sig, pins, others, resource in sc]
+ # resolve signal names in platform commands
+ pc = self.constraint_manager.get_platform_commands()
+ named_pc = []
+ for template, args in pc:
+ name_dict = dict((k, vns.get_name(sig)) for k, sig in args.items())
+ named_pc.append(template.format(**name_dict))
+
+ return named_sc, named_pc
+
+ def get_verilog(self, fragment, **kwargs):
+ return verilog.convert(
+ fragment,
+ self.constraint_manager.get_io_signals(),
+ create_clock_domains=False, **kwargs)
+
+ def get_edif(self, fragment, cell_library, vendor, device, **kwargs):
+ return edif.convert(
+ fragment,
+ self.constraint_manager.get_io_signals(),
+ cell_library, vendor, device, **kwargs)
+
+ def build(self, fragment):
+ raise NotImplementedError("GenericPlatform.build must be overloaded")
+
+ def create_programmer(self):
+ raise NotImplementedError
--- /dev/null
+import os
+
+
+class GenericProgrammer:
+ def __init__(self, flash_proxy_basename=None):
+ self.flash_proxy_basename = flash_proxy_basename
+ self.flash_proxy_dirs = [
+ "~/.litex", "/usr/local/share/litex", "/usr/share/litex"]
+
+ def set_flash_proxy_dir(self, flash_proxy_dir):
+ if flash_proxy_dir is not None:
+ self.flash_proxy_dirs = [flash_proxy_dir]
+
+ def find_flash_proxy(self):
+ for d in self.flash_proxy_dirs:
+ fulldir = os.path.abspath(os.path.expanduser(d))
+ fullname = os.path.join(fulldir, self.flash_proxy_basename)
+ if os.path.exists(fullname):
+ return fullname
+ raise OSError("Failed to find flash proxy bitstream")
+
+ # must be overloaded by specific programmer
+ def load_bitstream(self, bitstream_file):
+ raise NotImplementedError
+
+ # must be overloaded by specific programmer
+ def flash(self, address, data_file):
+ raise NotImplementedError
+
+
--- /dev/null
+from litex.build.lattice.platform import LatticePlatform
+from litex.build.lattice.programmer import LatticeProgrammer
--- /dev/null
+from litex.gen.fhdl.module import Module
+from litex.gen.fhdl.specials import Instance
+from litex.gen.genlib.io import *
+from litex.gen.genlib.resetsync import AsyncResetSynchronizer
+
+
+class LatticeAsyncResetSynchronizerImpl(Module):
+ def __init__(self, cd, async_reset):
+ rst1 = Signal()
+ self.specials += [
+ Instance("FD1S3BX", i_D=0, i_PD=async_reset,
+ i_CK=cd.clk, o_Q=rst1),
+ Instance("FD1S3BX", i_D=rst1, i_PD=async_reset,
+ i_CK=cd.clk, o_Q=cd.rst)
+ ]
+
+
+class LatticeAsyncResetSynchronizer:
+ @staticmethod
+ def lower(dr):
+ return LatticeAsyncResetSynchronizerImpl(dr.cd, dr.async_reset)
+
+
+class LatticeDDROutputImpl(Module):
+ def __init__(self, i1, i2, o, clk):
+ self.specials += Instance("ODDRXD1",
+ synthesis_directive="ODDRAPPS=\"SCLK_ALIGNED\"",
+ i_SCLK=clk,
+ i_DA=i1, i_DB=i2, o_Q=o,
+ )
+
+
+class LatticeDDROutput:
+ @staticmethod
+ def lower(dr):
+ return LatticeDDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk)
+
+lattice_special_overrides = {
+ AsyncResetSynchronizer: LatticeAsyncResetSynchronizer,
+ DDROutput: LatticeDDROutput
+}
--- /dev/null
+# This file is Copyright (c) 2015 Florent Kermarrec <florent@enjoy-digital.fr>
+# License: BSD
+
+import os
+import sys
+import subprocess
+import shutil
+
+from litex.gen.fhdl.structure import _Fragment
+
+from litex.build.generic_platform import *
+from litex.build import tools
+from litex.build.lattice import common
+
+
+def _format_constraint(c):
+ if isinstance(c, Pins):
+ return ("LOCATE COMP ", " SITE " + "\"" + c.identifiers[0] + "\"")
+ elif isinstance(c, IOStandard):
+ return ("IOBUF PORT ", " IO_TYPE=" + c.name)
+ elif isinstance(c, Misc):
+ return c.misc
+
+
+def _format_lpf(signame, pin, others, resname):
+ fmt_c = [_format_constraint(c) for c in ([Pins(pin)] + others)]
+ r = ""
+ for pre, suf in fmt_c:
+ r += pre + "\"" + signame + "\"" + suf + ";\n"
+ return r
+
+
+def _build_lpf(named_sc, named_pc):
+ r = "BLOCK RESETPATHS;\n"
+ r += "BLOCK ASYNCPATHS;\n"
+ for sig, pins, others, resname in named_sc:
+ if len(pins) > 1:
+ for i, p in enumerate(pins):
+ r += _format_lpf(sig + "[" + str(i) + "]", p, others, resname)
+ else:
+ r += _format_lpf(sig, pins[0], others, resname)
+ if named_pc:
+ r += "\n" + "\n\n".join(named_pc)
+ return r
+
+
+def _build_files(device, sources, vincpaths, build_name):
+ tcl = []
+ tcl.append("prj_project new -name \"{}\" -impl \"implementation\" -dev {} -synthesis \"synplify\"".format(build_name, device))
+ for path in vincpaths:
+ tcl.append("prj_impl option {include path} {\"" + path + "\"}")
+ for filename, language, library in sources:
+ tcl.append("prj_src add \"" + filename + "\" -work " + library)
+ tcl.append("prj_run Synthesis -impl implementation -forceOne")
+ tcl.append("prj_run Translate -impl implementation")
+ tcl.append("prj_run Map -impl implementation")
+ tcl.append("prj_run PAR -impl implementation")
+ tcl.append("prj_run Export -impl implementation -task Bitgen")
+ tools.write_to_file(build_name + ".tcl", "\n".join(tcl))
+
+
+def _run_diamond(build_name, source, ver=None):
+ if sys.platform == "win32" or sys.platform == "cygwin":
+ build_script_contents = "REM Autogenerated by LiteX\n"
+ build_script_contents = "pnmainc " + build_name + ".tcl\n"
+ build_script_file = "build_" + build_name + ".bat"
+ tools.write_to_file(build_script_file, build_script_contents)
+ r = subprocess.call([build_script_file])
+ shutil.copy(os.path.join("implementation", build_name + "_implementation.bit"), build_name + ".bit")
+ else:
+ raise NotImplementedError
+
+ if r != 0:
+ raise OSError("Subprocess failed")
+
+
+class LatticeDiamondToolchain:
+ def build(self, platform, fragment, build_dir="build", build_name="top",
+ toolchain_path="/opt/Diamond", run=True):
+ tools.mkdir_noerror(build_dir)
+ os.chdir(build_dir)
+
+ if not isinstance(fragment, _Fragment):
+ fragment = fragment.get_fragment()
+ platform.finalize(fragment)
+
+ v_output = platform.get_verilog(fragment)
+ named_sc, named_pc = platform.resolve_signals(v_output.ns)
+ v_file = build_name + ".v"
+ v_output.write(v_file)
+ sources = platform.sources | {(v_file, "verilog", "work")}
+ _build_files(platform.device, sources, platform.verilog_include_paths, build_name)
+
+ tools.write_to_file(build_name + ".lpf", _build_lpf(named_sc, named_pc))
+
+ if run:
+ _run_diamond(build_name, toolchain_path)
+
+ os.chdir("..")
+
+ return v_output.ns
+
+ def add_period_constraint(self, platform, clk, period):
+ # TODO: handle differential clk
+ platform.add_platform_command("""FREQUENCY PORT "{clk}" {freq} MHz;""".format(freq=str(float(1/period)*1000), clk="{clk}"), clk=clk)
--- /dev/null
+from litex.build.generic_platform import GenericPlatform
+from litex.build.lattice import common, diamond
+
+
+class LatticePlatform(GenericPlatform):
+ bitstream_ext = ".bit"
+
+ def __init__(self, *args, toolchain="diamond", **kwargs):
+ GenericPlatform.__init__(self, *args, **kwargs)
+ if toolchain == "diamond":
+ self.toolchain = diamond.LatticeDiamondToolchain()
+ else:
+ raise ValueError("Unknown toolchain")
+
+ def get_verilog(self, *args, special_overrides=dict(), **kwargs):
+ so = dict(common.lattice_special_overrides)
+ so.update(special_overrides)
+ return GenericPlatform.get_verilog(self, *args, special_overrides=so, **kwargs)
+
+ def build(self, *args, **kwargs):
+ return self.toolchain.build(self, *args, **kwargs)
+
+ def add_period_constraint(self, clk, period):
+ if hasattr(clk, "p"):
+ clk = clk.p
+ self.toolchain.add_period_constraint(self, clk, period)
--- /dev/null
+import os
+import subprocess
+
+from litex.build.generic_programmer import GenericProgrammer
+from litex.build import tools
+
+
+# XXX Lattice programmer need an .xcf file, will need clean up and support for more parameters
+_xcf_template = """
+<?xml version='1.0' encoding='utf-8' ?>
+<!DOCTYPE ispXCF SYSTEM "IspXCF.dtd" >
+<ispXCF version="3.4.1">
+ <Comment></Comment>
+ <Chain>
+ <Comm>JTAG</Comm>
+ <Device>
+ <SelectedProg value="TRUE"/>
+ <Pos>1</Pos>
+ <Vendor>Lattice</Vendor>
+ <Family>LatticeECP3</Family>
+ <Name>LFE3-35EA</Name>
+ <File>{bitstream_file}</File>
+ <Operation>Fast Program</Operation>
+ </Device>
+ </Chain>
+ <ProjectOptions>
+ <Program>SEQUENTIAL</Program>
+ <Process>ENTIRED CHAIN</Process>
+ <OperationOverride>No Override</OperationOverride>
+ <StartTAP>TLR</StartTAP>
+ <EndTAP>TLR</EndTAP>
+ <VerifyUsercode value="FALSE"/>
+ </ProjectOptions>
+ <CableOptions>
+ <CableName>USB2</CableName>
+ <PortAdd>FTUSB-0</PortAdd>
+ <USBID>Dual RS232-HS A Location 0000 Serial A</USBID>
+ <JTAGPinSetting>
+ TRST ABSENT;
+ ISPEN ABSENT;
+ </JTAGPinSetting>
+ </CableOptions>
+</ispXCF>
+"""
+
+
+class LatticeProgrammer(GenericProgrammer):
+ needs_bitreverse = False
+
+ def load_bitstream(self, bitstream_file):
+ xcf_file = bitstream_file.replace(".bit", ".xcf")
+ xcf_content = _xcf_template.format(bitstream_file=bitstream_file)
+ tools.write_to_file(xcf_file, xcf_content)
+ subprocess.call(["pgrcmd", "-infile", xcf_file])
--- /dev/null
+import subprocess
+
+from litex.build.generic_programmer import GenericProgrammer
+
+
+class OpenOCD(GenericProgrammer):
+ needs_bitreverse = False
+
+ def __init__(self, config, flash_proxy_basename=None):
+ GenericProgrammer.__init__(self, flash_proxy_basename)
+ self.config = config
+
+ def load_bitstream(self, bitstream):
+ script = "; ".join([
+ "init",
+ "pld load 0 {}".format(bitstream),
+ "exit",
+ ])
+ subprocess.call(["openocd", "-f", self.config, "-c", script])
+
+ def flash(self, address, data):
+ flash_proxy = self.find_flash_proxy()
+ script = "; ".join([
+ "init",
+ "jtagspi_init 0 {}".format(flash_proxy),
+ "jtagspi_program {} 0x{:x}".format(data, address),
+ "fpga_program",
+ "exit"
+ ])
+ subprocess.call(["openocd", "-f", self.config, "-c", script])
--- /dev/null
+from litex.build.sim.platform import SimPlatform
--- /dev/null
+sim_special_overrides = {}
--- /dev/null
+// This file is Copyright (c) 2015 Florent Kermarrec <florent@enjoy-digital.fr>
+// License: BSD
+#include "Vdut.h"
+#include "verilated.h"
+#include "verilated_vcd_c.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <termios.h>
+#include <sys/poll.h>
+
+#include <linux/if.h>
+#include <linux/if_tun.h>
+
+/* ios */
+
+#ifdef SERIAL_SOURCE_STB
+#define WITH_SERIAL
+#endif
+
+#ifdef ETH_SOURCE_STB
+#define WITH_ETH
+#endif
+
+#define MAX(a,b) (((a)>(b))?(a):(b))
+#define MIN(a,b) (((a)<(b))?(a):(b))
+
+int trace = 0;
+
+vluint64_t main_time = 0;
+double sc_time_stamp()
+{
+ return main_time;
+}
+
+/* Sim struct */
+struct sim {
+ bool run;
+
+ unsigned int tick;
+ clock_t start;
+ clock_t end;
+ float speed;
+
+#ifdef WITH_SERIAL_PTY
+ char serial_dev[64];
+ int serial_fd;
+ unsigned char serial_rx_data;
+ unsigned char serial_tx_data;
+#endif
+#ifdef WITH_ETH
+ const char *eth_dev;
+ const char *eth_tap;
+ int eth_fd;
+ unsigned char eth_txbuffer[2048];
+ unsigned char eth_rxbuffer[2048];
+ int eth_txbuffer_len;
+ int eth_rxbuffer_len;
+ int eth_rxbuffer_pos;
+ int eth_last_source_stb;
+#endif
+};
+
+/* Serial functions */
+#ifndef WITH_SERIAL_PTY
+struct termios orig_termios;
+
+void reset_terminal_mode(void)
+{
+ tcsetattr(0, TCSANOW, &orig_termios);
+}
+
+void set_conio_terminal_mode(void)
+{
+ struct termios new_termios;
+
+ /* take two copies - one for now, one for later */
+ tcgetattr(0, &orig_termios);
+ memcpy(&new_termios, &orig_termios, sizeof(new_termios));
+
+ /* register cleanup handler, and set the new terminal mode */
+ atexit(reset_terminal_mode);
+ cfmakeraw(&new_termios);
+ tcsetattr(0, TCSANOW, &new_termios);
+}
+
+int kbhit(void)
+{
+ struct timeval tv = { 0L, 0L };
+ fd_set fds;
+ FD_ZERO(&fds);
+ FD_SET(0, &fds);
+ return select(1, &fds, NULL, NULL, &tv);
+}
+
+int getch(void)
+{
+ int r;
+ unsigned char c;
+ if((r = read(0, &c, sizeof(c))) < 0) {
+ return r;
+ } else {
+ return c;
+ }
+}
+#endif
+
+/* Ethernet functions */
+/* create tap:
+ openvpn --mktun --dev tap0
+ ifconfig tap0 192.168.0.14 up
+ mknod /dev/net/tap0 c 10 200
+ delete tap:
+ openvpn --rmtun --dev tap0 */
+#ifdef WITH_ETH
+void eth_init(struct sim *s, const char *dev, const char*tap)
+{
+ s->eth_txbuffer_len = 0;
+ s->eth_rxbuffer_len = 0;
+ s->eth_rxbuffer_pos = 0;
+ s->eth_last_source_stb = 0;
+ s->eth_dev = dev;
+ s->eth_tap = tap;
+}
+
+void eth_open(struct sim *s)
+{
+
+ struct ifreq ifr;
+ s->eth_fd = open (s->eth_dev, O_RDWR);
+ if(s->eth_fd < 0) {
+ fprintf(stderr, " Could not open dev %s\n", s->eth_dev);
+ return;
+ }
+
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+ strncpy(ifr.ifr_name, s->eth_tap, IFNAMSIZ);
+
+ if(ioctl(s->eth_fd, TUNSETIFF, (void *) &ifr) < 0) {
+ fprintf(stderr, " Could not set %s\n", s->eth_tap);
+ close(s->eth_fd);
+ }
+ return;
+}
+
+int eth_close(struct sim *s)
+{
+ if(s->eth_fd < 0)
+ close(s->eth_fd);
+}
+
+void eth_write(struct sim *s, unsigned char *buf, int len)
+{
+ write(s->eth_fd, buf, len);
+}
+
+int eth_read(struct sim *s, unsigned char *buf)
+{
+
+ struct pollfd fds[1];
+ int n;
+ int len;
+
+ fds[0].fd = s->eth_fd;
+ fds[0].events = POLLIN;
+
+ n = poll(fds, 1, 0);
+ if((n > 0) && ((fds[0].revents & POLLIN) == POLLIN)) {
+ len = read(s->eth_fd, buf, 1532);
+ } else {
+ len = 0;
+ }
+ return len;
+}
+#endif
+
+Vdut* dut;
+VerilatedVcdC* tfp;
+
+#ifndef WITH_SERIAL_PTY
+int console_service(struct sim *s)
+{
+ /* fpga --> console */
+ SERIAL_SOURCE_ACK = 1;
+ if(SERIAL_SOURCE_STB == 1) {
+ if(SERIAL_SOURCE_DATA == '\n')
+ putchar('\r');
+ putchar(SERIAL_SOURCE_DATA);
+ fflush(stdout);
+ }
+
+ /* console --> fpga */
+ SERIAL_SINK_STB = 0;
+ if(s->tick%(1000) == 0) {
+ if(kbhit()) {
+ char c = getch();
+ if(c == 27 && !kbhit()) {
+ printf("\r\n");
+ return -1;
+ } else {
+ SERIAL_SINK_STB = 1;
+ SERIAL_SINK_DATA = c;
+ }
+ }
+ }
+ return 0;
+}
+#else
+void console_init(struct sim *s)
+{
+ FILE *f;
+ f = fopen("/tmp/simserial","r");
+ fscanf(f, "%[^\n]", s->serial_dev);
+ fclose(f);
+ return;
+}
+
+void console_open(struct sim *s)
+{
+ s->serial_fd = open(s->serial_dev, O_RDWR);
+ if(s->serial_fd < 0) {
+ fprintf(stderr, " Could not open dev %s\n", s->serial_dev);
+ return;
+ }
+ return;
+}
+
+int console_close(struct sim *s)
+{
+ if(s->serial_fd < 0)
+ close(s->serial_fd);
+}
+
+void console_write(struct sim *s, unsigned char *buf, int len)
+{
+ write(s->serial_fd, buf, len);
+}
+
+int console_read(struct sim *s, unsigned char *buf)
+{
+ struct pollfd fds[1];
+ int n;
+ int len;
+
+ fds[0].fd = s->serial_fd;
+ fds[0].events = POLLIN;
+
+ n = poll(fds, 1, 0);
+ if((n > 0) && ((fds[0].revents & POLLIN) == POLLIN)) {
+ len = read(s->serial_fd, buf, 1);
+ } else {
+ len = 0;
+ }
+ return len;
+}
+
+int console_service(struct sim *s)
+{
+ /* fpga --> console */
+ SERIAL_SOURCE_ACK = 1;
+ if(SERIAL_SOURCE_STB == 1) {
+ s->serial_tx_data = SERIAL_SOURCE_DATA;
+ console_write(s, &(s->serial_tx_data), 1);
+ }
+
+ /* console --> fpga */
+ SERIAL_SINK_STB = 0;
+ if(console_read(s, &(s->serial_rx_data)))
+ {
+ SERIAL_SINK_STB = 1;
+ SERIAL_SINK_DATA = s->serial_rx_data;
+ }
+ return 0;
+}
+#endif
+
+#ifdef WITH_ETH
+int ethernet_service(struct sim *s) {
+ /* fpga --> tap */
+ ETH_SOURCE_ACK = 1;
+ if(ETH_SOURCE_STB == 1) {
+ s->eth_txbuffer[s->eth_txbuffer_len] = ETH_SOURCE_DATA;
+ s->eth_txbuffer_len++;
+ } else {
+ if(s->eth_last_source_stb) {
+ eth_write(s, s->eth_txbuffer, s->eth_txbuffer_len);
+ s->eth_txbuffer_len = 0;
+ }
+ }
+ s->eth_last_source_stb = ETH_SOURCE_STB;
+
+ /* tap --> fpga */
+ if(s->eth_rxbuffer_len == 0) {
+ ETH_SINK_STB = 0;
+ s->eth_rxbuffer_pos = 0;
+ s->eth_rxbuffer_len = eth_read(s, s->eth_rxbuffer);
+ } else {
+ if(s->eth_rxbuffer_pos < MAX(s->eth_rxbuffer_len, 60)) {
+ ETH_SINK_STB = 1;
+ ETH_SINK_DATA = s->eth_rxbuffer[s->eth_rxbuffer_pos];
+ s->eth_rxbuffer_pos++;
+ } else {
+ ETH_SINK_STB = 0;
+ s->eth_rxbuffer_len = 0;
+ memset(s->eth_rxbuffer, 0, 1532);
+ }
+ }
+}
+#endif
+
+void sim_tick(struct sim *s)
+{
+ SYS_CLK = s->tick%2;
+ dut->eval();
+ if(trace)
+ tfp->dump(s->tick);
+ s->tick++;
+}
+
+void sim_init(struct sim *s)
+{
+ int i;
+ s->tick = 0;
+#ifdef SYS_RST
+ SYS_RST = 1;
+ SYS_CLK = 0;
+ for (i=0; i<8; i++)
+ sim_tick(s);
+ SYS_RST = 0;
+#endif
+ s->start = clock();
+}
+
+int main(int argc, char **argv, char **env)
+{
+ float speed;
+
+#ifndef WITH_SERIAL_PTY
+ set_conio_terminal_mode();
+#endif
+
+ Verilated::commandArgs(argc, argv);
+ dut = new Vdut;
+
+ Verilated::traceEverOn(true);
+ tfp = new VerilatedVcdC;
+ dut->trace(tfp, 99);
+ tfp->open("dut.vcd");
+
+ struct sim s;
+ sim_init(&s);
+
+#ifdef WITH_SERIAL_PTY
+ console_init(&s);
+ console_open(&s);
+#endif
+
+#ifdef WITH_ETH
+ eth_init(&s, "/dev/net/tap0", "tap0"); // XXX get this from /tmp/simethernet
+ eth_open(&s);
+#endif
+
+ s.run = true;
+ while(s.run) {
+ sim_tick(&s);
+ if(SYS_CLK) {
+#ifdef WITH_SERIAL
+ if(console_service(&s) != 0)
+ s.run = false;
+#endif
+#ifdef WITH_ETH
+ ethernet_service(&s);
+#endif
+ }
+ }
+ s.end = clock();
+
+ speed = (s.tick/2)/((s.end-s.start)/CLOCKS_PER_SEC);
+
+ printf("average speed: %3.3f MHz\n\r", speed/1000000);
+
+ tfp->close();
+
+
+#ifdef WITH_SERIAL_PTY
+ console_close(&s);
+#endif
+#ifdef WITH_ETH
+ eth_close(&s);
+#endif
+
+ exit(0);
+}
--- /dev/null
+from litex.build.generic_platform import GenericPlatform
+from litex.build.sim import common, verilator
+
+
+class SimPlatform(GenericPlatform):
+ def __init__(self, *args, toolchain="verilator", **kwargs):
+ GenericPlatform.__init__(self, *args, **kwargs)
+ if toolchain == "verilator":
+ self.toolchain = verilator.SimVerilatorToolchain()
+ else:
+ raise ValueError("Unknown toolchain")
+
+ def get_verilog(self, *args, special_overrides=dict(), **kwargs):
+ so = dict(common.sim_special_overrides)
+ so.update(special_overrides)
+ return GenericPlatform.get_verilog(self, *args, special_overrides=so, **kwargs)
+
+ def build(self, *args, **kwargs):
+ return self.toolchain.build(self, *args, **kwargs)
+
--- /dev/null
+# This file is Copyright (c) 2015 Florent Kermarrec <florent@enjoy-digital.fr>
+# License: BSD
+
+import os
+import subprocess
+
+from litex.gen.fhdl.structure import _Fragment
+from litex.build import tools
+from litex.build.generic_platform import *
+
+
+def _build_tb(platform, vns, serial, template):
+ def io_name(resource, subsignal=None):
+ res = platform.lookup_request(resource)
+ if subsignal is not None:
+ res = getattr(res, subsignal)
+ return vns.get_name(res)
+
+ ios = """
+#define SYS_CLK dut->{sys_clk}
+""".format(sys_clk=io_name("sys_clk"))
+
+ if serial == "pty":
+ ios += "#define WITH_SERIAL_PTY"
+ elif serial == "console":
+ pass
+ else:
+ raise ValueError
+ try:
+ ios += """
+#define SERIAL_SOURCE_STB dut->{serial_source_stb}
+#define SERIAL_SOURCE_ACK dut->{serial_source_ack}
+#define SERIAL_SOURCE_DATA dut->{serial_source_data}
+
+#define SERIAL_SINK_STB dut->{serial_sink_stb}
+#define SERIAL_SINK_ACK dut->{serial_sink_ack}
+#define SERIAL_SINK_DATA dut->{serial_sink_data}
+""".format(
+ serial_source_stb=io_name("serial", "source_stb"),
+ serial_source_ack=io_name("serial", "source_ack"),
+ serial_source_data=io_name("serial", "source_data"),
+
+ serial_sink_stb=io_name("serial", "sink_stb"),
+ serial_sink_ack=io_name("serial", "sink_ack"),
+ serial_sink_data=io_name("serial", "sink_data"),
+ )
+ except:
+ pass
+
+ try:
+ ios += """
+#define ETH_SOURCE_STB dut->{eth_source_stb}
+#define ETH_SOURCE_ACK dut->{eth_source_ack}
+#define ETH_SOURCE_DATA dut->{eth_source_data}
+
+#define ETH_SINK_STB dut->{eth_sink_stb}
+#define ETH_SINK_ACK dut->{eth_sink_ack}
+#define ETH_SINK_DATA dut->{eth_sink_data}
+""".format(
+ eth_source_stb=io_name("eth", "source_stb"),
+ eth_source_ack=io_name("eth", "source_ack"),
+ eth_source_data=io_name("eth", "source_data"),
+
+ eth_sink_stb=io_name("eth", "sink_stb"),
+ eth_sink_ack=io_name("eth", "sink_ack"),
+ eth_sink_data=io_name("eth", "sink_data"),
+ )
+ except:
+ pass
+
+ content = ""
+ f = open(template, "r")
+ done = False
+ for l in f:
+ content += l
+ if "/* ios */" in l and not done:
+ content += ios
+ done = True
+
+ f.close()
+ tools.write_to_file("dut_tb.cpp", content)
+
+
+def _build_sim(platform, vns, build_name, include_paths, sim_path, serial, verbose):
+ include = ""
+ for path in include_paths:
+ include += "-I"+path+" "
+
+ build_script_contents = """# Autogenerated by LiteX
+ rm -rf obj_dir/
+verilator {disable_warnings} -O3 --cc dut.v --exe dut_tb.cpp -LDFLAGS "-lpthread" -trace {include}
+make -j -C obj_dir/ -f Vdut.mk Vdut
+
+""".format(
+ disable_warnings="-Wno-fatal",
+ include=include)
+ build_script_file = "build_" + build_name + ".sh"
+ tools.write_to_file(build_script_file, build_script_contents, force_unix=True)
+
+ _build_tb(platform, vns, serial, os.path.join("..", sim_path, "dut_tb.cpp"))
+ if verbose:
+ r = subprocess.call(["bash", build_script_file])
+ else:
+ r = subprocess.call(["bash", build_script_file], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
+ if r != 0:
+ raise OSError("Subprocess failed")
+
+
+def _run_sim(build_name):
+ run_script_contents = """obj_dir/Vdut
+"""
+ run_script_file = "run_" + build_name + ".sh"
+ tools.write_to_file(run_script_file, run_script_contents, force_unix=True)
+ r = subprocess.call(["bash", run_script_file])
+ if r != 0:
+ raise OSError("Subprocess failed")
+
+
+class SimVerilatorToolchain:
+ # XXX fir sim_path
+ def build(self, platform, fragment, build_dir="build", build_name="top",
+ sim_path="../migen/migen/build/sim/", serial="console",
+ run=True, verbose=False):
+ tools.mkdir_noerror(build_dir)
+ os.chdir(build_dir)
+
+ if not isinstance(fragment, _Fragment):
+ fragment = fragment.get_fragment()
+ platform.finalize(fragment)
+
+ v_output = platform.get_verilog(fragment)
+ named_sc, named_pc = platform.resolve_signals(v_output.ns)
+ v_output.write("dut.v")
+
+ include_paths = []
+ for source in platform.sources:
+ path = os.path.dirname(source[0]).replace("\\", "\/")
+ if path not in include_paths:
+ include_paths.append(path)
+ include_paths += platform.verilog_include_paths
+ _build_sim(platform, v_output.ns, build_name, include_paths, sim_path, serial, verbose)
+
+ if run:
+ _run_sim(build_name)
+
+ os.chdir("..")
+
+ return v_output.ns
--- /dev/null
+import os
+import struct
+from distutils.version import StrictVersion
+
+
+def mkdir_noerror(d):
+ try:
+ os.mkdir(d)
+ except OSError:
+ pass
+
+
+def language_by_filename(name):
+ extension = name.rsplit(".")[-1]
+ if extension in ["v", "vh", "vo"]:
+ return "verilog"
+ if extension in ["vhd", "vhdl", "vho"]:
+ return "vhdl"
+ return None
+
+
+def write_to_file(filename, contents, force_unix=False):
+ newline = None
+ if force_unix:
+ newline = "\n"
+ with open(filename, "w", newline=newline) as f:
+ f.write(contents)
+
+
+def arch_bits():
+ return struct.calcsize("P")*8
+
+
+def versions(path):
+ for n in os.listdir(path):
+ full = os.path.join(path, n)
+ if not os.path.isdir(full):
+ continue
+ try:
+ yield StrictVersion(n)
+ except ValueError:
+ continue
--- /dev/null
+from litex.build.xilinx.platform import XilinxPlatform
+from litex.build.xilinx.programmer import UrJTAG, XC3SProg, FpgaProg, VivadoProgrammer, iMPACT, Adept
--- /dev/null
+import os
+import sys
+from distutils.version import StrictVersion
+
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.specials import Instance
+from litex.gen.fhdl.module import Module
+from litex.gen.fhdl.specials import SynthesisDirective
+from litex.gen.genlib.cdc import *
+from litex.gen.genlib.resetsync import AsyncResetSynchronizer
+from litex.gen.genlib.io import *
+
+from litex.build import tools
+
+
+def settings(path, ver=None, sub=None):
+ vers = list(tools.versions(path))
+ if ver is None:
+ ver = max(vers)
+ else:
+ ver = StrictVersion(ver)
+ assert ver in vers
+
+ full = os.path.join(path, str(ver))
+ if sub:
+ full = os.path.join(full, sub)
+
+ search = [64, 32]
+ if tools.arch_bits() == 32:
+ search.reverse()
+
+ if sys.platform == "win32" or sys.platform == "cygwin":
+ script_ext = "bat"
+ else:
+ script_ext = "sh"
+
+ for b in search:
+ settings = os.path.join(full, "settings{0}.{1}".format(b, script_ext))
+ if os.path.exists(settings):
+ return settings
+
+ raise OSError("no settings file found")
+
+
+class XilinxNoRetimingImpl(Module):
+ def __init__(self, reg):
+ self.specials += SynthesisDirective("attribute register_balancing of {r} is no", r=reg)
+
+
+class XilinxNoRetiming:
+ @staticmethod
+ def lower(dr):
+ return XilinxNoRetimingImpl(dr.reg)
+
+
+class XilinxMultiRegImpl(MultiRegImpl):
+ def __init__(self, *args, **kwargs):
+ MultiRegImpl.__init__(self, *args, **kwargs)
+ self.specials += [SynthesisDirective("attribute shreg_extract of {r} is no", r=r)
+ for r in self.regs]
+
+
+class XilinxMultiReg:
+ @staticmethod
+ def lower(dr):
+ return XilinxMultiRegImpl(dr.i, dr.o, dr.odomain, dr.n)
+
+
+class XilinxAsyncResetSynchronizerImpl(Module):
+ def __init__(self, cd, async_reset):
+ rst1 = Signal()
+ self.specials += [
+ Instance("FDPE", p_INIT=1, i_D=0, i_PRE=async_reset,
+ i_CE=1, i_C=cd.clk, o_Q=rst1),
+ Instance("FDPE", p_INIT=1, i_D=rst1, i_PRE=async_reset,
+ i_CE=1, i_C=cd.clk, o_Q=cd.rst)
+ ]
+
+
+class XilinxAsyncResetSynchronizer:
+ @staticmethod
+ def lower(dr):
+ return XilinxAsyncResetSynchronizerImpl(dr.cd, dr.async_reset)
+
+
+class XilinxDifferentialInputImpl(Module):
+ def __init__(self, i_p, i_n, o):
+ self.specials += Instance("IBUFDS", i_I=i_p, i_IB=i_n, o_O=o)
+
+
+class XilinxDifferentialInput:
+ @staticmethod
+ def lower(dr):
+ return XilinxDifferentialInputImpl(dr.i_p, dr.i_n, dr.o)
+
+
+class XilinxDifferentialOutputImpl(Module):
+ def __init__(self, i, o_p, o_n):
+ self.specials += Instance("OBUFDS", i_I=i, o_O=o_p, o_OB=o_n)
+
+
+class XilinxDifferentialOutput:
+ @staticmethod
+ def lower(dr):
+ return XilinxDifferentialOutputImpl(dr.i, dr.o_p, dr.o_n)
+
+
+class XilinxDDROutputImpl(Module):
+ def __init__(self, i1, i2, o, clk):
+ self.specials += Instance("ODDR2",
+ p_DDR_ALIGNMENT="NONE", p_INIT=0, p_SRTYPE="SYNC",
+ i_C0=clk, i_C1=~clk, i_CE=1, i_S=0, i_R=0,
+ i_D0=i1, i_D1=i2, o_Q=o,
+ )
+
+
+class XilinxDDROutput:
+ @staticmethod
+ def lower(dr):
+ return XilinxDDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk)
+
+
+xilinx_special_overrides = {
+ NoRetiming: XilinxNoRetiming,
+ MultiReg: XilinxMultiReg,
+ AsyncResetSynchronizer: XilinxAsyncResetSynchronizer,
+ DifferentialInput: XilinxDifferentialInput,
+ DifferentialOutput: XilinxDifferentialOutput,
+ DDROutput: XilinxDDROutput
+}
+
+
+class XilinxDDROutputImplS7(Module):
+ def __init__(self, i1, i2, o, clk):
+ self.specials += Instance("ODDR",
+ p_DDR_CLK_EDGE="SAME_EDGE",
+ i_C=clk, i_CE=1, i_S=0, i_R=0,
+ i_D1=i1, i_D2=i2, o_Q=o,
+ )
+
+
+class XilinxDDROutputS7:
+ @staticmethod
+ def lower(dr):
+ return XilinxDDROutputImplS7(dr.i1, dr.i2, dr.o, dr.clk)
+
+
+xilinx_s7_special_overrides = {
+ DDROutput: XilinxDDROutputS7
+}
--- /dev/null
+import os
+import subprocess
+import sys
+
+from litex.gen.fhdl.structure import _Fragment
+from litex.build.generic_platform import *
+from litex.build import tools
+from litex.build.xilinx import common
+
+
+def _format_constraint(c):
+ if isinstance(c, Pins):
+ return "LOC=" + c.identifiers[0]
+ elif isinstance(c, IOStandard):
+ return "IOSTANDARD=" + c.name
+ elif isinstance(c, Drive):
+ return "DRIVE=" + str(c.strength)
+ elif isinstance(c, Misc):
+ return c.misc
+
+
+def _format_ucf(signame, pin, others, resname):
+ fmt_c = []
+ for c in [Pins(pin)] + others:
+ fc = _format_constraint(c)
+ if fc is not None:
+ fmt_c.append(fc)
+ fmt_r = resname[0] + ":" + str(resname[1])
+ if resname[2] is not None:
+ fmt_r += "." + resname[2]
+ return "NET \"" + signame + "\" " + " | ".join(fmt_c) + "; # " + fmt_r + "\n"
+
+
+def _build_ucf(named_sc, named_pc):
+ r = ""
+ for sig, pins, others, resname in named_sc:
+ if len(pins) > 1:
+ for i, p in enumerate(pins):
+ r += _format_ucf(sig + "(" + str(i) + ")", p, others, resname)
+ else:
+ r += _format_ucf(sig, pins[0], others, resname)
+ if named_pc:
+ r += "\n" + "\n\n".join(named_pc)
+ return r
+
+
+def _build_xst_files(device, sources, vincpaths, build_name, xst_opt):
+ prj_contents = ""
+ for filename, language, library in sources:
+ prj_contents += language + " " + library + " " + filename + "\n"
+ tools.write_to_file(build_name + ".prj", prj_contents)
+
+ xst_contents = """run
+-ifn {build_name}.prj
+-top top
+{xst_opt}
+-ofn {build_name}.ngc
+-p {device}
+""".format(build_name=build_name, xst_opt=xst_opt, device=device)
+ for path in vincpaths:
+ xst_contents += "-vlgincdir " + path + "\n"
+ tools.write_to_file(build_name + ".xst", xst_contents)
+
+
+def _run_yosys(device, sources, vincpaths, build_name):
+ ys_contents = ""
+ incflags = ""
+ for path in vincpaths:
+ incflags += " -I" + path
+ for filename, language, library in sources:
+ ys_contents += "read_{}{} {}\n".format(language, incflags, filename)
+
+ ys_contents += """hierarchy -check -top top
+proc; memory; opt; fsm; opt
+synth_xilinx -top top -edif {build_name}.edif""".format(build_name=build_name)
+
+ ys_name = build_name + ".ys"
+ tools.write_to_file(ys_name, ys_contents)
+ r = subprocess.call(["yosys", ys_name])
+ if r != 0:
+ raise OSError("Subprocess failed")
+
+
+def _run_ise(build_name, ise_path, source, mode, ngdbuild_opt,
+ bitgen_opt, ise_commands, map_opt, par_opt, ver=None):
+ if sys.platform == "win32" or sys.platform == "cygwin":
+ source_cmd = "call "
+ script_ext = ".bat"
+ shell = ["cmd", "/c"]
+ build_script_contents = "@echo off\nrem Autogenerated by LiteX\n"
+ else:
+ source_cmd = "source "
+ script_ext = ".sh"
+ shell = ["bash"]
+ build_script_contents = "# Autogenerated by LiteX\nset -e\n"
+ if source:
+ settings = common.settings(ise_path, ver, "ISE_DS")
+ build_script_contents += source_cmd + settings + "\n"
+ if mode == "edif":
+ ext = "edif"
+ else:
+ ext = "ngc"
+ build_script_contents += """
+xst -ifn {build_name}.xst
+"""
+
+ build_script_contents += """
+ngdbuild {ngdbuild_opt} -uc {build_name}.ucf {build_name}.{ext} {build_name}.ngd
+map {map_opt} -o {build_name}_map.ncd {build_name}.ngd {build_name}.pcf
+par {par_opt} {build_name}_map.ncd {build_name}.ncd {build_name}.pcf
+bitgen {bitgen_opt} {build_name}.ncd {build_name}.bit
+"""
+ build_script_contents = build_script_contents.format(build_name=build_name,
+ ngdbuild_opt=ngdbuild_opt, bitgen_opt=bitgen_opt, ext=ext,
+ par_opt=par_opt, map_opt=map_opt)
+ build_script_contents += ise_commands.format(build_name=build_name)
+ build_script_file = "build_" + build_name + script_ext
+ tools.write_to_file(build_script_file, build_script_contents, force_unix=False)
+ command = shell + [build_script_file]
+ r = subprocess.call(command)
+ if r != 0:
+ raise OSError("Subprocess failed")
+
+
+class XilinxISEToolchain:
+ def __init__(self):
+ self.xst_opt = """-ifmt MIXED
+-use_new_parser yes
+-opt_mode SPEED
+-register_balancing yes"""
+ self.map_opt = "-ol high -w"
+ self.par_opt = "-ol high -w"
+ self.ngdbuild_opt = ""
+ self.bitgen_opt = "-g Binary:Yes -w"
+ self.ise_commands = ""
+
+ def build(self, platform, fragment, build_dir="build", build_name="top",
+ toolchain_path=None, source=None, run=True, mode="xst"):
+ if not isinstance(fragment, _Fragment):
+ fragment = fragment.get_fragment()
+ if toolchain_path is None:
+ if sys.platform == "win32":
+ toolchain_path = "C:\\Xilinx"
+ elif sys.platform == "cygwin":
+ toolchain_path = "/cygdrive/c/Xilinx"
+ else:
+ toolchain_path = "/opt/Xilinx"
+ if source is None:
+ source = sys.platform != "win32"
+
+ platform.finalize(fragment)
+ ngdbuild_opt = self.ngdbuild_opt
+ vns = None
+
+ tools.mkdir_noerror(build_dir)
+ cwd = os.getcwd()
+ os.chdir(build_dir)
+ try:
+ if mode == "xst" or mode == "yosys":
+ v_output = platform.get_verilog(fragment)
+ vns = v_output.ns
+ named_sc, named_pc = platform.resolve_signals(vns)
+ v_file = build_name + ".v"
+ v_output.write(v_file)
+ sources = platform.sources | {(v_file, "verilog", "work")}
+ if mode == "xst":
+ _build_xst_files(platform.device, sources, platform.verilog_include_paths, build_name, self.xst_opt)
+ isemode = "xst"
+ else:
+ _run_yosys(platform.device, sources, platform.verilog_include_paths, build_name)
+ isemode = "edif"
+ ngdbuild_opt += "-p " + platform.device
+
+ if mode == "mist":
+ from mist import synthesize
+ synthesize(fragment, platform.constraint_manager.get_io_signals())
+
+ if mode == "edif" or mode == "mist":
+ e_output = platform.get_edif(fragment)
+ vns = e_output.ns
+ named_sc, named_pc = platform.resolve_signals(vns)
+ e_file = build_name + ".edif"
+ e_output.write(e_file)
+ isemode = "edif"
+
+ tools.write_to_file(build_name + ".ucf", _build_ucf(named_sc, named_pc))
+ if run:
+ _run_ise(build_name, toolchain_path, source, isemode,
+ ngdbuild_opt, self.bitgen_opt, self.ise_commands,
+ self.map_opt, self.par_opt)
+ finally:
+ os.chdir(cwd)
+
+ return vns
+
+ def add_period_constraint(self, platform, clk, period):
+ platform.add_platform_command("""NET "{clk}" TNM_NET = "GRP{clk}";
+TIMESPEC "TS{clk}" = PERIOD "GRP{clk}" """+str(period)+""" ns HIGH 50%;""", clk=clk)
--- /dev/null
+from litex.build.generic_platform import GenericPlatform
+from litex.build.xilinx import common, vivado, ise
+
+
+class XilinxPlatform(GenericPlatform):
+ bitstream_ext = ".bit"
+
+ def __init__(self, *args, toolchain="ise", **kwargs):
+ GenericPlatform.__init__(self, *args, **kwargs)
+ if toolchain == "ise":
+ self.toolchain = ise.XilinxISEToolchain()
+ elif toolchain == "vivado":
+ self.toolchain = vivado.XilinxVivadoToolchain()
+ else:
+ raise ValueError("Unknown toolchain")
+
+ def get_verilog(self, *args, special_overrides=dict(), **kwargs):
+ so = dict(common.xilinx_special_overrides)
+ if self.device[:3] == "xc7":
+ so.update(common.xilinx_s7_special_overrides)
+ so.update(special_overrides)
+ return GenericPlatform.get_verilog(self, *args, special_overrides=so, **kwargs)
+
+ def get_edif(self, fragment, **kwargs):
+ return GenericPlatform.get_edif(self, fragment, "UNISIMS", "Xilinx", self.device, **kwargs)
+
+ def build(self, *args, **kwargs):
+ return self.toolchain.build(self, *args, **kwargs)
+
+ def add_period_constraint(self, clk, period):
+ if hasattr(clk, "p"):
+ clk = clk.p
+ self.toolchain.add_period_constraint(self, clk, period)
--- /dev/null
+import os
+import sys
+import subprocess
+
+from litex.build.generic_programmer import GenericProgrammer
+from litex.build.xilinx import common
+
+
+def _run_urjtag(cmds):
+ with subprocess.Popen("jtag", stdin=subprocess.PIPE) as process:
+ process.stdin.write(cmds.encode("ASCII"))
+ process.communicate()
+
+
+class UrJTAG(GenericProgrammer):
+ needs_bitreverse = True
+
+ def __init__(self, cable, flash_proxy_basename=None):
+ GenericProgrammer.__init__(self, flash_proxy_basename)
+ self.cable = cable
+
+ def load_bitstream(self, bitstream_file):
+ cmds = """cable {cable}
+detect
+pld load {bitstream}
+quit
+""".format(bitstream=bitstream_file, cable=self.cable)
+ _run_urjtag(cmds)
+
+ def flash(self, address, data_file):
+ flash_proxy = self.find_flash_proxy()
+ cmds = """cable {cable}
+detect
+pld load "{flash_proxy}"
+initbus fjmem opcode=000010
+frequency 6000000
+detectflash 0
+endian big
+flashmem "{address}" "{data_file}" noverify
+""".format(flash_proxy=flash_proxy, address=address, data_file=data_file,
+ cable=self.cable)
+ _run_urjtag(cmds)
+
+
+class XC3SProg(GenericProgrammer):
+ needs_bitreverse = False
+
+ def __init__(self, cable, flash_proxy_basename=None):
+ GenericProgrammer.__init__(self, flash_proxy_basename)
+ self.cable = cable
+
+ def load_bitstream(self, bitstream_file):
+ subprocess.call(["xc3sprog", "-v", "-c", self.cable, bitstream_file])
+
+ def flash(self, address, data_file):
+ flash_proxy = self.find_flash_proxy()
+ subprocess.call(["xc3sprog", "-v", "-c", self.cable, "-I"+flash_proxy, "{}:w:0x{:x}:BIN".format(data_file, address)])
+
+
+
+class FpgaProg(GenericProgrammer):
+ needs_bitreverse = False
+
+ def __init__(self, flash_proxy_basename=None):
+ GenericProgrammer.__init__(self, flash_proxy_basename)
+
+ def load_bitstream(self, bitstream_file):
+ subprocess.call(["fpgaprog", "-v", "-f", bitstream_file])
+
+ def flash(self, address, data_file):
+ if address != 0:
+ raise ValueError("fpga prog needs a main bitstream at address 0")
+ flash_proxy = self.find_flash_proxy()
+ subprocess.call(["fpgaprog", "-v", "-sa", "-r", "-b", flash_proxy,
+ "-f", data_file])
+
+
+def _run_impact(cmds):
+ with subprocess.Popen("impact -batch", stdin=subprocess.PIPE, shell=True) as process:
+ process.stdin.write(cmds.encode("ASCII"))
+ process.communicate()
+ return process.returncode
+
+
+def _create_xsvf(bitstream_file, xsvf_file):
+ assert os.path.exists(bitstream_file), bitstream_file
+ assert not os.path.exists(xsvf_file), xsvf_file
+ assert 0 == _run_impact("""
+setPreference -pref KeepSVF:True
+setMode -bs
+setCable -port xsvf -file {xsvf}
+addDevice -p 1 -file {bitstream}
+program -p 1
+quit
+""".format(bitstream=bitstream_file, xsvf=xsvf_file))
+
+
+class iMPACT(GenericProgrammer):
+ needs_bitreverse = False
+
+ def load_bitstream(self, bitstream_file):
+ cmds = """setMode -bs
+setCable -p auto
+addDevice -p 1 -file {bitstream}
+program -p 1
+quit
+""".format(bitstream=bitstream_file)
+ _run_impact(cmds)
+
+
+def _run_vivado(path, ver, cmds):
+ if sys.platform == "win32" or sys.platform == "cygwin":
+ vivado_cmd = "vivado -mode tcl"
+ else:
+ settings = common.settings(path, ver)
+ vivado_cmd = "bash -c \"source " + settings + "&& vivado -mode tcl\""
+ with subprocess.Popen(vivado_cmd, stdin=subprocess.PIPE, shell=True) as process:
+ process.stdin.write(cmds.encode("ASCII"))
+ process.communicate()
+
+
+class VivadoProgrammer(GenericProgrammer):
+ needs_bitreverse = False
+ def __init__(self, vivado_path="/opt/Xilinx/Vivado", vivado_ver=None,
+ flash_part="n25q256-3.3v-spi-x1_x2_x4"):
+ GenericProgrammer.__init__(self)
+ self.vivado_path = vivado_path
+ self.vivado_ver = vivado_ver
+ self.flash_part = flash_part
+
+ def load_bitstream(self, bitstream_file):
+ cmds = """open_hw
+connect_hw_server
+open_hw_target [lindex [get_hw_targets -of_objects [get_hw_servers localhost]] 0]
+
+set_property PROBES.FILE {{}} [lindex [get_hw_devices] 0]
+set_property PROGRAM.FILE {{{bitstream}}} [lindex [get_hw_devices] 0]
+
+program_hw_devices [lindex [get_hw_devices] 0]
+refresh_hw_device [lindex [get_hw_devices] 0]
+
+quit
+""".format(bitstream=bitstream_file)
+ _run_vivado(self.vivado_path, self.vivado_ver, cmds)
+
+ # XXX works to flash bitstream, adapt it to flash bios
+ def flash(self, address, data_file):
+ cmds = """open_hw
+connect_hw_server
+open_hw_target [lindex [get_hw_targets -of_objects [get_hw_servers localhost]] 0]
+create_hw_cfgmem -hw_device [lindex [get_hw_devices] 0] -mem_dev [lindex [get_cfgmem_parts {{{flash_part}}}] 0]
+
+set_property PROGRAM.BLANK_CHECK 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
+set_property PROGRAM.ERASE 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
+set_property PROGRAM.CFG_PROGRAM 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
+set_property PROGRAM.VERIFY 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
+refresh_hw_device [lindex [get_hw_devices] 0]
+
+set_property PROGRAM.ADDRESS_RANGE {{use_file}} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
+set_property PROGRAM.FILES [list "{data}" ] [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0]]
+set_property PROGRAM.UNUSED_PIN_TERMINATION {{pull-none}} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
+set_property PROGRAM.BLANK_CHECK 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
+set_property PROGRAM.ERASE 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
+set_property PROGRAM.CFG_PROGRAM 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
+set_property PROGRAM.VERIFY 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
+
+startgroup
+if {{![string equal [get_property PROGRAM.HW_CFGMEM_TYPE [lindex [get_hw_devices] 0]] [get_property MEM_TYPE [get_property CFGMEM_PART [get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]]]] }} {{ create_hw_bitstream -hw_device [lindex [get_hw_devices] 0] [get_property PROGRAM.HW_CFGMEM_BITFILE [ lindex [get_hw_devices] 0]]; program_hw_devices [lindex [get_hw_devices] 0]; }};
+program_hw_cfgmem -hw_cfgmem [get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
+endgroup
+
+quit
+""".format(data=data_file, flash_part=self.flash_part)
+ _run_vivado(self.vivado_path, self.vivado_ver, cmds)
+
+
+class Adept(GenericProgrammer):
+ """Using the Adept tool with an onboard Digilent "USB JTAG" cable.
+
+ You need to install Adept Utilities V2 from
+ http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,66,828&Prod=ADEPT2
+ """
+
+ needs_bitreverse = False
+
+ def __init__(self, board, index, flash_proxy_basename=None):
+ GenericProgrammer.__init__(self, flash_proxy_basename)
+ self.board = board
+ self.index = index
+
+ def load_bitstream(self, bitstream_file):
+ subprocess.call([
+ "djtgcfg",
+ "--verbose",
+ "prog", "-d", self.board,
+ "-i", str(self.index),
+ "-f", bitstream_file,
+ ])
+
+ def flash(self, address, data_file):
+ raise ValueError("Flashing unsupported with DigilentAdept tools")
--- /dev/null
+# This file is Copyright (c) 2014 Florent Kermarrec <florent@enjoy-digital.fr>
+# License: BSD
+
+import os
+import subprocess
+import sys
+
+from litex.gen.fhdl.structure import _Fragment
+from litex.build.generic_platform import *
+from litex.build import tools
+from litex.build.xilinx import common
+
+
+def _format_constraint(c):
+ if isinstance(c, Pins):
+ return "set_property LOC " + c.identifiers[0]
+ elif isinstance(c, IOStandard):
+ return "set_property IOSTANDARD " + c.name
+ elif isinstance(c, Drive):
+ return "set_property DRIVE " + str(c.strength)
+ elif isinstance(c, Misc):
+ return "set_property " + c.misc.replace("=", " ")
+ else:
+ raise ValueError("unknown constraint {}".format(c))
+
+
+def _format_xdc(signame, resname, *constraints):
+ fmt_c = [_format_constraint(c) for c in constraints]
+ fmt_r = resname[0] + ":" + str(resname[1])
+ if resname[2] is not None:
+ fmt_r += "." + resname[2]
+ r = " ## {}\n".format(fmt_r)
+ for c in fmt_c:
+ r += c + " [get_ports " + signame + "]\n"
+ return r
+
+
+def _build_xdc(named_sc, named_pc):
+ r = ""
+ for sig, pins, others, resname in named_sc:
+ if len(pins) > 1:
+ for i, p in enumerate(pins):
+ r += _format_xdc(sig + "[" + str(i) + "]", resname, Pins(p), *others)
+ elif pins:
+ r += _format_xdc(sig, resname, Pins(pins[0]), *others)
+ else:
+ r += _format_xdc(sig, resname, *others)
+ if named_pc:
+ r += "\n" + "\n\n".join(named_pc)
+ return r
+
+
+def _run_vivado(build_name, vivado_path, source, ver=None):
+ if sys.platform == "win32" or sys.platform == "cygwin":
+ build_script_contents = "REM Autogenerated by LiteX\n"
+ build_script_contents += "vivado -mode batch -source " + build_name + ".tcl\n"
+ build_script_file = "build_" + build_name + ".bat"
+ tools.write_to_file(build_script_file, build_script_contents)
+ r = subprocess.call([build_script_file])
+ else:
+ build_script_contents = "# Autogenerated by LiteX\nset -e\n"
+ settings = common.settings(vivado_path, ver)
+ build_script_contents += "source " + settings + "\n"
+ build_script_contents += "vivado -mode batch -source " + build_name + ".tcl\n"
+ build_script_file = "build_" + build_name + ".sh"
+ tools.write_to_file(build_script_file, build_script_contents)
+ r = subprocess.call(["bash", build_script_file])
+
+ if r != 0:
+ raise OSError("Subprocess failed")
+
+
+class XilinxVivadoToolchain:
+ def __init__(self):
+ self.bitstream_commands = []
+ self.additional_commands = []
+ self.pre_synthesis_commands = []
+ self.with_phys_opt = False
+
+ def _build_batch(self, platform, sources, build_name):
+ tcl = []
+ for filename, language, library in sources:
+ filename_tcl = "{" + filename + "}"
+ tcl.append("add_files " + filename_tcl)
+ tcl.append("set_property library {} [get_files {}]"
+ .format(library, filename_tcl))
+
+ tcl.append("read_xdc {}.xdc".format(build_name))
+ tcl.extend(c.format(build_name=build_name) for c in self.pre_synthesis_commands)
+ tcl.append("synth_design -top top -part {} -include_dirs {{{}}}".format(platform.device, " ".join(platform.verilog_include_paths)))
+ tcl.append("report_utilization -hierarchical -file {}_utilization_hierarchical_synth.rpt".format(build_name))
+ tcl.append("report_utilization -file {}_utilization_synth.rpt".format(build_name))
+ tcl.append("place_design")
+ if self.with_phys_opt:
+ tcl.append("phys_opt_design -directive AddRetime")
+ tcl.append("report_utilization -hierarchical -file {}_utilization_hierarchical_place.rpt".format(build_name))
+ tcl.append("report_utilization -file {}_utilization_place.rpt".format(build_name))
+ tcl.append("report_io -file {}_io.rpt".format(build_name))
+ tcl.append("report_control_sets -verbose -file {}_control_sets.rpt".format(build_name))
+ tcl.append("report_clock_utilization -file {}_clock_utilization.rpt".format(build_name))
+ tcl.append("route_design")
+ tcl.append("report_route_status -file {}_route_status.rpt".format(build_name))
+ tcl.append("report_drc -file {}_drc.rpt".format(build_name))
+ tcl.append("report_timing_summary -max_paths 10 -file {}_timing.rpt".format(build_name))
+ tcl.append("report_power -file {}_power.rpt".format(build_name))
+ for bitstream_command in self.bitstream_commands:
+ tcl.append(bitstream_command.format(build_name=build_name))
+ tcl.append("write_bitstream -force {}.bit ".format(build_name))
+ for additional_command in self.additional_commands:
+ tcl.append(additional_command.format(build_name=build_name))
+ tcl.append("quit")
+ tools.write_to_file(build_name + ".tcl", "\n".join(tcl))
+
+ def build(self, platform, fragment, build_dir="build", build_name="top",
+ toolchain_path="/opt/Xilinx/Vivado", source=True, run=True):
+ tools.mkdir_noerror(build_dir)
+ os.chdir(build_dir)
+
+ if not isinstance(fragment, _Fragment):
+ fragment = fragment.get_fragment()
+ platform.finalize(fragment)
+ v_output = platform.get_verilog(fragment)
+ named_sc, named_pc = platform.resolve_signals(v_output.ns)
+ v_file = build_name + ".v"
+ v_output.write(v_file)
+ sources = platform.sources | {(v_file, "verilog", "work")}
+ self._build_batch(platform, sources, build_name)
+ tools.write_to_file(build_name + ".xdc", _build_xdc(named_sc, named_pc))
+ if run:
+ _run_vivado(build_name, toolchain_path, source)
+
+ os.chdir("..")
+
+ return v_output.ns
+
+ def add_period_constraint(self, platform, clk, period):
+ platform.add_platform_command("""create_clock -name {clk} -period """ + \
+ str(period) + """ [get_ports {clk}]""", clk=clk)
+++ /dev/null
-__pycache__
-*.pyc
-*.egg-info/
-vpi/*.o
-vpi/migensim.vpi
-examples/*.vcd
-doc/_build
+++ /dev/null
-language: python
-python:
- - "3.5"
-
-env:
- global:
- - PATH=$HOME/miniconda/bin:$PATH
-
-before_install:
- # Install Miniconda
- - wget https://raw.githubusercontent.com/m-labs/artiq/master/.travis/get-anaconda.sh
- - chmod +x get-anaconda.sh
- - ./get-anaconda.sh
- - source $HOME/miniconda/bin/activate py35
- - conda install anaconda-client numpydoc
-install:
- # Install iverilog package.
- # - "sudo add-apt-repository -y ppa:mithro/iverilog-backport"
- # - "sudo apt-get update"
- # - "sudo apt-get install iverilog"
- # - "iverilog -v; true"
- # Build the vpi module.
- # - "(cd vpi; make; sudo make install)"
- # Install verilator package
- - "sudo apt-get install verilator"
- - "verilator --version; true"
- # Build and install Migen conda package
- # workaround for https://github.com/conda/conda-build/issues/466
- - "mkdir -p /home/travis/miniconda/conda-bld/linux-64"
- - "conda index /home/travis/miniconda/conda-bld/linux-64"
- - "conda build --python 3.5 conda/migen"
- - "conda install $(conda build --output --python 3.5 conda/migen)"
-
-script:
- # Run tests
- - "python setup.py test"
- # Generate HTML documentation
- - "make -C doc html"
-
-after_success:
- # Upload Migen conda package to binstar
- - if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then anaconda login --hostname $(hostname) --username $binstar_login --password $binstar_password; fi
- - if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then anaconda upload --user $binstar_login --channel dev --force $HOME/miniconda/conda-bld/noarch/migen-*.tar.bz2; fi
-
-notifications:
- email: false
- irc:
- channels:
- - chat.freenode.net#m-labs
- template:
- - "%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message}"
- - "Build details : %{build_url}"
+++ /dev/null
-Unless otherwise noted, Migen is copyright (C) 2011-2013 Sebastien Bourdeauducq.
-The simulation extension (as mentioned in the comments at the beginning of the
-corresponding source files) is copyright (C) 2012 Vermeer Manufacturing Co. All
-rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-Other authors retain ownership of their contributions. If a submission can
-reasonably be considered independently copyrightable, it's yours and we
-encourage you to claim it with appropriate copyright notices. This submission
-then falls under the "otherwise noted" category. All submissions are strongly
-encouraged to use the two-clause BSD license reproduced above.
--- /dev/null
+Unless otherwise noted, Migen is copyright (C) 2011-2013 Sebastien Bourdeauducq.
+The simulation extension (as mentioned in the comments at the beginning of the
+corresponding source files) is copyright (C) 2012 Vermeer Manufacturing Co. All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+Other authors retain ownership of their contributions. If a submission can
+reasonably be considered independently copyrightable, it's yours and we
+encourage you to claim it with appropriate copyright notices. This submission
+then falls under the "otherwise noted" category. All submissions are strongly
+encouraged to use the two-clause BSD license reproduced above.
+++ /dev/null
-### Migen (Milkymist generator)
-
-[![Build Status](https://travis-ci.org/m-labs/migen.svg)](
-https://travis-ci.org/m-labs/migen)
-
-#### A Python toolbox for building complex digital hardware
-
-Despite being faster than schematics entry, hardware design with Verilog and
-VHDL remains tedious and inefficient for several reasons. The event-driven
-model introduces issues and manual coding that are unnecessary for synchronous
-circuits, which represent the lion's share of today's logic designs. Counter-
-intuitive arithmetic rules result in steeper learning curves and provide a
-fertile ground for subtle bugs in designs. Finally, support for procedural
-generation of logic (metaprogramming) through "generate" statements is very
-limited and restricts the ways code can be made generic, reused and organized.
-
-To address those issues, we have developed the **Migen FHDL** library that
-replaces the event-driven paradigm with the notions of combinatorial and
-synchronous statements, has arithmetic rules that make integers always behave
-like mathematical integers, and most importantly allows the design's logic to
-be constructed by a Python program. This last point enables hardware designers
-to take advantage of the richness of the Python language - object oriented
-programming, function parameters, generators, operator overloading, libraries,
-etc. - to build well organized, reusable and elegant designs.
-
-Other Migen libraries are built on FHDL and provide various tools such as a
-system-on-chip interconnect infrastructure, a dataflow programming system, a
-more traditional high-level synthesizer that compiles Python routines into
-state machines with datapaths, and a simulator that allows test benches to be
-written in Python.
-
-See the doc/ folder for more technical information.
-
-Migen is designed for Python 3.3. Note that Migen is **not** spelled MiGen.
-
-#### Quick Links
-
-Code repository:
-https://github.com/m-labs/migen
-
-System-on-chip design based on Migen:
-https://github.com/m-labs/misoc
-
-Online documentation:
-http://m-labs.hk/gateware.html
-
-#### Quick intro
-
-```python
-from migen import *
-from migen.build.platforms import m1
-plat = m1.Platform()
-led = plat.request("user_led")
-m = Module()
-counter = Signal(26)
-m.comb += led.eq(counter[25])
-m.sync += counter.eq(counter + 1)
-plat.build_cmdline(m)
-```
-
-#### License
-
-Migen is released under the very permissive two-clause BSD license. Under the
-terms of this license, you are authorized to use Migen for closed-source
-proprietary designs.
-Even though we do not require you to do so, those things are awesome, so please
-do them if possible:
-* tell us that you are using Migen
-* put the Migen logo (doc/migen_logo.svg) on the page of a product using it,
- with a link to http://m-labs.hk
-* cite Migen in publications related to research it has helped
-* send us feedback and suggestions for improvements
-* send us bug reports when something goes wrong
-* send us the modifications and improvements you have done to Migen. The use
- of "git format-patch" is recommended. If your submission is large and
- complex and/or you are not sure how to proceed, feel free to discuss it on
- the mailing list or IRC (#m-labs on Freenode) beforehand.
-
-See LICENSE file for full copyright and license info. You can contact us on the
-public mailing list devel [AT] lists.m-labs.hk.
-
- "Electricity! It's like magic!"
--- /dev/null
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.module import *
+from litex.gen.fhdl.specials import *
+from litex.gen.fhdl.bitcontainer import *
+from litex.gen.fhdl.decorators import *
+
+from litex.gen.sim import *
+
+from litex.gen.genlib.record import *
+from litex.gen.genlib.fsm import *
+++ /dev/null
-%PYTHON% setup.py install
+++ /dev/null
-package:
- name: migen
- version: {{ environ.get("GIT_DESCRIBE_TAG", "") }}
-
-source:
- git_url: https://github.com/m-labs/migen
- git_tag: master
-
-build:
- noarch_python: true
- number: {{ environ.get("GIT_DESCRIBE_NUMBER", 0) }}
- string: py_{{ environ.get("GIT_DESCRIBE_NUMBER", 0) }}+git{{ environ.get("GIT_DESCRIBE_HASH", "")[1:] }}
- script: $PYTHON setup.py install
-
-requirements:
- build:
- - python 3.5.*
- run:
- - python 3.5.*
-
-test:
- imports:
- - migen
-
-about:
- home: http://m-labs.hk/gateware.html
- license: 3-clause BSD
- summary: 'A Python toolbox for building complex digital hardware'
+++ /dev/null
-# Makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS =
-SPHINXBUILD = sphinx-build
-PAPER =
-BUILDDIR = _build
-
-# Internal variables.
-PAPEROPT_a4 = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-
-.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
-
-help:
- @echo "Please use \`make <target>' where <target> is one of"
- @echo " html to make standalone HTML files"
- @echo " dirhtml to make HTML files named index.html in directories"
- @echo " singlehtml to make a single large HTML file"
- @echo " pickle to make pickle files"
- @echo " json to make JSON files"
- @echo " htmlhelp to make HTML files and a HTML help project"
- @echo " qthelp to make HTML files and a qthelp project"
- @echo " devhelp to make HTML files and a Devhelp project"
- @echo " epub to make an epub"
- @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
- @echo " latexpdf to make LaTeX files and run them through pdflatex"
- @echo " text to make text files"
- @echo " man to make manual pages"
- @echo " changes to make an overview of all changed/added/deprecated items"
- @echo " linkcheck to check all external links for integrity"
- @echo " doctest to run all doctests embedded in the documentation (if enabled)"
-
-clean:
- -rm -rf $(BUILDDIR)/*
-
-html:
- $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-dirhtml:
- $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-singlehtml:
- $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
- @echo
- @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
-
-pickle:
- $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
- @echo
- @echo "Build finished; now you can process the pickle files."
-
-json:
- $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
- @echo
- @echo "Build finished; now you can process the JSON files."
-
-htmlhelp:
- $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
- @echo
- @echo "Build finished; now you can run HTML Help Workshop with the" \
- ".hhp project file in $(BUILDDIR)/htmlhelp."
-
-qthelp:
- $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
- @echo
- @echo "Build finished; now you can run "qcollectiongenerator" with the" \
- ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
- @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Migen.qhcp"
- @echo "To view the help file:"
- @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Migen.qhc"
-
-devhelp:
- $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
- @echo
- @echo "Build finished."
- @echo "To view the help file:"
- @echo "# mkdir -p $$HOME/.local/share/devhelp/Migen"
- @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Migen"
- @echo "# devhelp"
-
-epub:
- $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
- @echo
- @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
-
-latex:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo
- @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
- @echo "Run \`make' in that directory to run these through (pdf)latex" \
- "(use \`make latexpdf' here to do that automatically)."
-
-latexpdf:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo "Running LaTeX files through pdflatex..."
- make -C $(BUILDDIR)/latex all-pdf
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-text:
- $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
- @echo
- @echo "Build finished. The text files are in $(BUILDDIR)/text."
-
-man:
- $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
- @echo
- @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
-
-changes:
- $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
- @echo
- @echo "The overview file is in $(BUILDDIR)/changes."
-
-linkcheck:
- $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
- @echo
- @echo "Link check complete; look for any errors in the above output " \
- "or in $(BUILDDIR)/linkcheck/output.txt."
-
-doctest:
- $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
- @echo "Testing of doctests in the sources finished, look at the " \
- "results in $(BUILDDIR)/doctest/output.txt."
+++ /dev/null
-# -*- coding: utf-8 -*-
-#
-# Migen documentation build configuration file, created by
-# sphinx-quickstart on Fri Mar 9 14:11:54 2012.
-#
-# This file is execfile()d with the current directory set to its containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.insert(0, os.path.abspath('.'))
-
-# -- General configuration -----------------------------------------------------
-
-# If your documentation needs a minimal Sphinx version, state it here.
-#needs_sphinx = '1.0'
-
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = [
- 'sphinx.ext.pngmath',
- 'sphinx.ext.autodoc',
- 'sphinx.ext.doctest',
- 'sphinx.ext.autosummary',
- 'numpydoc', # to preprocess docstrings
- ]
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-#source_encoding = 'utf-8-sig'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General information about the project.
-project = u'Migen'
-copyright = u'2011-2015, M-Labs Limited'
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = '1.0'
-# The full version, including alpha/beta/rc tags.
-release = '1.0'
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-exclude_patterns = ['_build']
-
-# The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-modindex_common_prefix = ['migen.']
-
-numpydoc_show_class_members = False
-
-# -- Options for HTML output ---------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages. See the documentation for
-# a list of builtin themes.
-html_theme = 'alabaster'
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further. For a list of options available for each theme, see the
-# documentation.
-#html_theme_options = {}
-
-# Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
-
-# The name for this set of Sphinx documents. If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar. Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_domain_indices = True
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
-
-# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
-
-# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it. The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'Migendoc'
-
-html_use_modindex = False
-
-# -- Options for LaTeX output --------------------------------------------------
-
-# The paper size ('letter' or 'a4').
-#latex_paper_size = 'letter'
-
-# The font size ('10pt', '11pt' or '12pt').
-#latex_font_size = '10pt'
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass [howto/manual]).
-latex_documents = [
- ('index', 'Migen.tex', u'Migen manual',
- u'Sebastien Bourdeauducq', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-latex_logo = "migen_logo.png"
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# If true, show page references after internal links.
-#latex_show_pagerefs = False
-
-# If true, show URL addresses after external links.
-#latex_show_urls = False
-
-# Additional stuff for the LaTeX preamble.
-latex_preamble = '\setcounter{tocdepth}{3}'
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_domain_indices = True
-
-latex_use_modindex = False
-
-# -- Options for manual page output --------------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
- ('index', 'migen', u'Migen manual',
- [u'Sebastien Bourdeauducq'], 1)
-]
+++ /dev/null
-The FHDL domain-specific language
-#################################
-
-The Fragmented Hardware Description Language (FHDL) is the basis of Migen. It consists of a formal system to describe signals, and combinatorial and synchronous statements operating on them. The formal system itself is low level and close to the synthesizable subset of Verilog, and we then rely on Python algorithms to build complex structures by combining FHDL elements.
-The FHDL module also contains a back-end to produce synthesizable Verilog, and some structure analysis and manipulation functionality.
-
-FHDL differs from MyHDL [myhdl]_ in fundamental ways. MyHDL follows the event-driven paradigm of traditional HDLs (see :ref:`background`) while FHDL separates the code into combinatorial statements, synchronous statements, and reset values. In MyHDL, the logic is described directly in the Python AST. The converter to Verilog or VHDL then examines the Python AST and recognizes a subset of Python that it translates into V*HDL statements. This seriously impedes the capability of MyHDL to generate logic procedurally. With FHDL, you manipulate a custom AST from Python, and you can more easily design algorithms that operate on it.
-
-.. [myhdl] http://www.myhdl.org
-
-FHDL is made of several elements, which are briefly explained below. They all can be imported directly from the ``migen`` module.
-
-Expressions
-***********
-
-Constants
-=========
-
-The ``Constant`` object represents a constant, HDL-literal integer. It behaves like specifying integers and booleans but also supports slicing and can have a bit width or signedness different from what is implied by the value it represents.
-
-``True`` and ``False`` are interpreted as 1 and 0, respectively.
-
-Negative integers are explicitly supported. As with MyHDL [countin]_, arithmetic operations return the natural results.
-
-To lighten the syntax, assignments and operators automatically wrap Python integers and booleans into ``Constant``. Additionally, ``Constant`` is aliased to ``C``. The following are valid Migen statements: ``a.eq(0)``, ``a.eq(a + 1)``, ``a.eq(C(42)[0:1])``.
-
-.. [countin] http://www.jandecaluwe.com/hdldesign/counting.html
-
-Signal
-======
-
-The signal object represents a value that is expected to change in the circuit. It does exactly what Verilog's "wire" and "reg" and VHDL's "signal" do.
-
-The main point of the signal object is that it is identified by its Python ID (as returned by the :py:func:`id` function), and nothing else. It is the responsibility of the V*HDL back-end to establish an injective mapping between Python IDs and the V*HDL namespace. It should perform name mangling to ensure this. The consequence of this is that signal objects can safely become members of arbitrary Python classes, or be passed as parameters to functions or methods that generate logic involving them.
-
-The properties of a signal object are:
-
-* An integer or a (integer, boolean) pair that defines the number of bits and whether the bit of higher index of the signal is a sign bit (i.e. the signal is signed). The defaults are one bit and unsigned. Alternatively, the ``min`` and ``max`` parameters can be specified to define the range of the signal and determine its bit width and signedness. As with Python ranges, ``min`` is inclusive and defaults to 0, ``max`` is exclusive and defaults to 2.
-* A name, used as a hint for the V*HDL back-end name mangler.
-* The signal's reset value. It must be an integer, and defaults to 0. When the signal's value is modified with a synchronous statement, the reset value is the initialization value of the associated register. When the signal is assigned to in a conditional combinatorial statement (``If`` or ``Case``), the reset value is the value that the signal has when no condition that causes the signal to be driven is verified. This enforces the absence of latches in designs. If the signal is permanently driven using a combinatorial statement, the reset value has no effect.
-
-The sole purpose of the name property is to make the generated V*HDL code easier to understand and debug. From a purely functional point of view, it is perfectly OK to have several signals with the same name property. The back-end will generate a unique name for each object. If no name property is specified, Migen will analyze the code that created the signal object, and try to extract the variable or member name from there. For example, the following statements will create one or several signals named "bar": ::
-
- bar = Signal()
- self.bar = Signal()
- self.baz.bar = Signal()
- bar = [Signal() for x in range(42)]
-
-In case of conflicts, Migen tries first to resolve the situation by prefixing the identifiers with names from the class and module hierarchy that created them. If the conflict persists (which can be the case if two signal objects are created with the same name in the same context), it will ultimately add number suffixes.
-
-Operators
-=========
-
-Operators are represented by the ``_Operator`` object, which generally should not be used directly. Instead, most FHDL objects overload the usual Python logic and arithmetic operators, which allows a much lighter syntax to be used. For example, the expression: ::
-
- a * b + c
-
-is equivalent to::
-
- _Operator("+", [_Operator("*", [a, b]), c])
-
-Slices
-======
-
-Likewise, slices are represented by the ``_Slice`` object, which often should not be used in favor of the Python slice operation [x:y]. Implicit indices using the forms [x], [x:] and [:y] are supported. Beware! Slices work like Python slices, not like VHDL or Verilog slices. The first bound is the index of the LSB and is inclusive. The second bound is the index of MSB and is exclusive. In V*HDL, bounds are MSB:LSB and both are inclusive.
-
-Concatenations
-==============
-
-Concatenations are done using the ``Cat`` object. To make the syntax lighter, its constructor takes a variable number of arguments, which are the signals to be concatenated together (you can use the Python "*" operator to pass a list instead).
-To be consistent with slices, the first signal is connected to the bits with the lowest indices in the result. This is the opposite of the way the "{}" construct works in Verilog.
-
-Replications
-============
-
-The ``Replicate`` object represents the equivalent of {count{expression}} in Verilog.
-
-Statements
-**********
-
-Assignment
-==========
-
-Assignments are represented with the ``_Assign`` object. Since using it directly would result in a cluttered syntax, the preferred technique for assignments is to use the ``eq()`` method provided by objects that can have a value assigned to them. They are signals, and their combinations with the slice and concatenation operators.
-As an example, the statement: ::
-
- a[0].eq(b)
-
-is equivalent to: ::
-
- _Assign(_Slice(a, 0, 1), b)
-
-If
-==
-
-The ``If`` object takes a first parameter which must be an expression (combination of the ``Constant``, ``Signal``, ``_Operator``, ``_Slice``, etc. objects) representing the condition, then a variable number of parameters representing the statements (``_Assign``, ``If``, ``Case``, etc. objects) to be executed when the condition is verified.
-
-The ``If`` object defines a ``Else()`` method, which when called defines the statements to be executed when the condition is not true. Those statements are passed as parameters to the variadic method.
-
-For convenience, there is also a ``Elif()`` method.
-
-Example: ::
-
- If(tx_count16 == 0,
- tx_bitcount.eq(tx_bitcount + 1),
- If(tx_bitcount == 8,
- self.tx.eq(1)
- ).Elif(tx_bitcount == 9,
- self.tx.eq(1),
- tx_busy.eq(0)
- ).Else(
- self.tx.eq(tx_reg[0]),
- tx_reg.eq(Cat(tx_reg[1:], 0))
- )
- )
-
-Case
-====
-
-The ``Case`` object constructor takes as first parameter the expression to be tested, and a dictionary whose keys are the values to be matched, and values the statements to be executed in the case of a match. The special value ``"default"`` can be used as match value, which means the statements should be executed whenever there is no other match.
-
-Arrays
-======
-
-The ``Array`` object represents lists of other objects that can be indexed by FHDL expressions. It is explicitly possible to:
-
-* nest ``Array`` objects to create multidimensional tables.
-* list any Python object in a ``Array`` as long as every expression appearing in a module ultimately evaluates to a ``Signal`` for all possible values of the indices. This allows the creation of lists of structured data.
-* use expressions involving ``Array`` objects in both directions (assignment and reading).
-
-For example, this creates a 4x4 matrix of 1-bit signals: ::
-
- my_2d_array = Array(Array(Signal() for a in range(4)) for b in range(4))
-
-You can then read the matrix with (``x`` and ``y`` being 2-bit signals): ::
-
- out.eq(my_2d_array[x][y])
-
-and write it with: ::
-
- my_2d_array[x][y].eq(inp)
-
-Since they have no direct equivalent in Verilog, ``Array`` objects are lowered into multiplexers and conditional statements before the actual conversion takes place. Such lowering happens automatically without any user intervention.
-
-Specials
-********
-
-Tri-state I/O
-=============
-
-A triplet (O, OE, I) of one-way signals defining a tri-state I/O port is represented by the ``TSTriple`` object. Such objects are only containers for signals that are intended to be later connected to a tri-state I/O buffer, and cannot be used as module specials. Such objects, however, should be kept in the design as long as possible as they allow the individual one-way signals to be manipulated in a non-ambiguous way.
-
-The object that can be used in as a module special is ``Tristate``, and it behaves exactly like an instance of a tri-state I/O buffer that would be defined as follows: ::
-
- Instance("Tristate",
- io_target=target,
- i_o=o,
- i_oe=oe,
- o_i=i
- )
-
-Signals ``target``, ``o`` and ``i`` can have any width, while ``oe`` is 1-bit wide. The ``target`` signal should go to a port and not be used elsewhere in the design. Like modern FPGA architectures, Migen does not support internal tri-states.
-
-A ``Tristate`` object can be created from a ``TSTriple`` object by calling the ``get_tristate`` method.
-
-By default, Migen emits technology-independent behavioral code for a tri-state buffer. If a specific code is needed, the tristate handler can be overriden using the appropriate parameter of the V*HDL conversion function.
-
-Instances
-=========
-
-Instance objects represent the parametrized instantiation of a V*HDL module, and the connection of its ports to FHDL signals. They are useful in a number of cases:
-
-* Reusing legacy or third-party V*HDL code.
-* Using special FPGA features (DCM, ICAP, ...).
-* Implementing logic that cannot be expressed with FHDL (e.g. latches).
-* Breaking down a Migen system into multiple sub-systems.
-
-The instance object constructor takes the type (i.e. name of the instantiated module) of the instance, then multiple parameters describing how to connect and parametrize the instance.
-
-These parameters can be:
-
-* ``Instance.Input``, ``Instance.Output`` or ``Instance.InOut`` to describe signal connections with the instance. The parameters are the name of the port at the instance, and the FHDL expression it should be connected to.
-* ``Instance.Parameter`` sets a parameter (with a name and value) of the instance.
-* ``Instance.ClockPort`` and ``Instance.ResetPort`` are used to connect clock and reset signals to the instance. The only mandatory parameter is the name of the port at the instance. Optionally, a clock domain name can be specified, and the ``invert`` option can be used to interface to those modules that require a 180-degree clock or a active-low reset.
-
-Memories
-========
-
-Memories (on-chip SRAM) are supported using a mechanism similar to instances.
-
-A memory object has the following parameters:
-
-* The width, which is the number of bits in each word.
-* The depth, which represents the number of words in the memory.
-* An optional list of integers used to initialize the memory.
-
-To access the memory in hardware, ports can be obtained by calling the ``get_port`` method. A port always has an address signal ``a`` and a data read signal ``dat_r``. Other signals may be available depending on the port's configuration.
-
-Options to ``get_port`` are:
-
-* ``write_capable`` (default: ``False``): if the port can be used to write to the memory. This creates an additional ``we`` signal.
-* ``async_read`` (default: ``False``): whether reads are asychronous (combinatorial) or synchronous (registered).
-* ``has_re`` (default: ``False``): adds a read clock-enable signal ``re`` (ignored for asychronous ports).
-* ``we_granularity`` (default: ``0``): if non-zero, writes of less than a memory word can occur. The width of the ``we`` signal is increased to act as a selection signal for the sub-words.
-* ``mode`` (default: ``WRITE_FIRST``, ignored for aynchronous ports). It can be:
-
- * ``READ_FIRST``: during a write, the previous value is read.
- * ``WRITE_FIRST``: the written value is returned.
- * ``NO_CHANGE``: the data read signal keeps its previous value on a write.
-
-* ``clock_domain`` (default: ``"sys"``): the clock domain used for reading and writing from this port.
-
-Migen generates behavioural V*HDL code that should be compatible with all simulators and, if the number of ports is <= 2, most FPGA synthesizers. If a specific code is needed, the memory handler can be overriden using the appropriate parameter of the V*HDL conversion function.
-
-Inline synthesis directives
-===========================
-
-Inline synthesis directives (pseudo-comments such as ``// synthesis attribute keep of clock_signal_name is true``) are supported using the ``SynthesisDirective`` object. Its constructor takes as parameters a string containing the body of the directive, and optional keyword parameters that are used to replace signal names similarly to the Python string method ``format``. The above example could be represented as follows: ::
-
- SynthesisDirective("attribute keep of {clksig} is true", clksig=clock_domain.clk)
-
-Modules
-*******
-
-Modules play the same role as Verilog modules and VHDL entities. Similarly, they are organized in a tree structure. A FHDL module is a Python object that derives from the ``Module`` class. This class defines special attributes to be used by derived classes to describe their logic. They are explained below.
-
-Combinatorial statements
-========================
-
-A combinatorial statement is a statement that is executed whenever one of its inputs changes.
-
-Combinatorial statements are added to a module by using the ``comb`` special attribute. Like most module special attributes, it must be accessed using the ``+=`` incrementation operator, and either a single statement, a tuple of statements or a list of statements can appear on the right hand side.
-
-For example, the module below implements a OR gate: ::
-
- class ORGate(Module):
- def __init__(self):
- self.a = Signal()
- self.b = Signal()
- self.x = Signal()
-
- ###
-
- self.comb += x.eq(a | b)
-
-To improve code readability, it is recommended to place the interface of the module at the beginning of the ``__init__`` function, and separate it from the implementation using three hash signs.
-
-Synchronous statements
-======================
-
-A synchronous statements is a statement that is executed at each edge of some clock signal.
-
-They are added to a module by using the ``sync`` special attribute, which has the same properties as the ``comb`` attribute.
-
-The ``sync`` special attribute also has sub-attributes that correspond to abstract clock domains. For example, to add a statement to the clock domain named ``foo``, one would write ``self.sync.foo += statement``. The default clock domain is ``sys`` and writing ``self.sync += statement`` is equivalent to writing ``self.sync.sys += statement``.
-
-Submodules and specials
-=======================
-
-Submodules and specials can be added by using the ``submodules`` and ``specials`` attributes respectively. This can be done in two ways:
-
-#. anonymously, by using the ``+=`` operator on the special attribute directly, e.g. ``self.submodules += some_other_module``. Like with the ``comb`` and ``sync`` attributes, a single module/special or a tuple or list can be specified.
-#. by naming the submodule/special using a subattribute of the ``submodules`` or ``specials`` attribute, e.g. ``self.submodules.foo = module_foo``. The submodule/special is then accessible as an attribute of the object, e.g. ``self.foo`` (and not ``self.submodules.foo``). Only one submodule/special can be added at a time using this form.
-
-Clock domains
-=============
-
-Specifying the implementation of a clock domain is done using the ``ClockDomain`` object. It contains the name of the clock domain, a clock signal that can be driven like any other signal in the design (for example, using a PLL instance), and optionally a reset signal. Clock domains without a reset signal are reset using e.g. ``initial`` statements in Verilog, which in many FPGA families initalize the registers during configuration.
-
-The name can be omitted if it can be extracted from the variable name. When using this automatic naming feature, prefixes ``_``, ``cd_`` and ``_cd_`` are removed.
-
-Clock domains are then added to a module using the ``clock_domains`` special attribute, which behaves exactly like ``submodules`` and ``specials``.
-
-Summary of special attributes
-=============================
-
-.. table::
-
- +--------------------------------------------+--------------------------------------------------------------+
- | Syntax | Action |
- +============================================+==============================================================+
- | self.comb += stmt | Add combinatorial statement to current module. |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.comb += stmtA, stmtB | Add combinatorial statements A and B to current module. |
- | | |
- | self.comb += [stmtA, stmtB] | |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.sync += stmt | Add synchronous statement to current module, in default |
- | | clock domain sys. |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.sync.foo += stmt | Add synchronous statement to current module, in clock domain |
- | | foo. |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.sync.foo += stmtA, stmtB | Add synchronous statements A and B to current module, in |
- | | clock domain foo. |
- | self.sync.foo += [stmtA, stmtB] | |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.submodules += mod | Add anonymous submodule to current module. |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.submodules += modA, modB | Add anonymous submodules A and B to current module. |
- | | |
- | self.submodules += [modA, modB] | |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.submodules.bar = mod | Add submodule named bar to current module. The submodule can |
- | | then be accessed using self.bar. |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.specials += spe | Add anonymous special to current module. |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.specials += speA, speB | Add anonymous specials A and B to current module. |
- | | |
- | self.specials += [speA, speB] | |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.specials.bar = spe | Add special named bar to current module. The special can |
- | | then be accessed using self.bar. |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.clock_domains += cd | Add clock domain to current module. |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.clock_domains += cdA, cdB | Add clock domains A and B to current module. |
- | | |
- | self.clock_domains += [cdA, cdB] | |
- +--------------------------------------------+--------------------------------------------------------------+
- | self.clock_domains.pix = ClockDomain() | Create and add clock domain pix to current module. The clock |
- | | domain name is pix in all cases. It can be accessed using |
- | self.clock_domains._pix = ClockDomain() | self.pix, self._pix, self.cd_pix and self._cd_pix, |
- | | respectively. |
- | self.clock_domains.cd_pix = ClockDomain() | |
- | | |
- | self.clock_domains._cd_pix = ClockDomain() | |
- +--------------------------------------------+--------------------------------------------------------------+
-
-Clock domain management
-=======================
-
-When a module has named submodules that define one or several clock domains with the same name, those clock domain names are prefixed with the name of each submodule plus an underscore.
-
-An example use case of this feature is a system with two independent video outputs. Each video output module is made of a clock generator module that defines a clock domain ``pix`` and drives the clock signal, plus a driver module that has synchronous statements and other elements in clock domain ``pix``. The designer of the video output module can simply use the clock domain name ``pix`` in that module. In the top-level system module, the video output submodules are named ``video0`` and ``video1``. Migen then automatically renames the ``pix`` clock domain of each module to ``video0_pix`` and ``video1_pix``. Note that happens only because the clock domain is defined (using ClockDomain objects), not simply referenced (using e.g. synchronous statements) in the video output modules.
-
-Clock domain name overlap is an error condition when any of the submodules that defines the clock domains is anonymous.
-
-Finalization mechanism
-======================
-
-Sometimes, it is desirable that some of a module logic be created only after the user has finished manipulating that module. For example, the FSM module supports that states be defined dynamically, and the width of the state signal can be known only after all states have been added. One solution is to declare the final number of states in the FSM constructor, but this is not user-friendly. A better solution is to automatically create the state signal just before the FSM module is converted to V*HDL. Migen supports this using the so-called finalization mechanism.
-
-Modules can overload a ``do_finalize`` method that can create logic and is called using the algorithm below:
-
-#. Finalization of the current module begins.
-#. If the module has already been finalized (e.g. manually), the procedure stops here.
-#. Submodules of the current module are recursively finalized.
-#. ``do_finalize`` is called for the current module.
-#. Any new submodules created by the current module's ``do_finalize`` are recursively finalized.
-
-Finalization is automatically invoked at V*HDL conversion and at simulation. It can be manually invoked for any module by calling its ``finalize`` method.
-
-The clock domain management mechanism explained above happens during finalization.
-
-Conversion for synthesis
-************************
-
-Any FHDL module can be converted into synthesizable Verilog HDL. This is accomplished by using the ``convert`` function in the ``verilog`` module.
-
-The ``migen.build`` component provides scripts to interface third-party FPGA tools (from Xilinx, Altera and Lattice) to Migen, and a database of boards for the easy deployment of designs.
+++ /dev/null
-Migen manual
-############
-
-.. toctree::
- :maxdepth: 2
-
- introduction
- fhdl
- simulation
- synthesis
- reference
+++ /dev/null
-Introduction
-############
-
-Migen is a Python-based tool that aims at automating further the VLSI design process.
-
-Migen makes it possible to apply modern software concepts such as object-oriented programming and metaprogramming to design hardware. This results in more elegant and easily maintained designs and reduces the incidence of human errors.
-
-.. _background:
-
-Background
-**********
-
-Even though the Milkymist system-on-chip [mm]_ had many successes, it suffers from several limitations stemming from its implementation in manually written Verilog HDL:
-
-.. [mm] http://m-labs.hk
-
-#. The "event-driven" paradigm of today's dominant hardware descriptions languages (Verilog and VHDL, collectively referred to as "V*HDL" in the rest of this document) is often too general. Today's FPGA architectures are optimized for the implementation of fully synchronous circuits. This means that the bulk of the code for an efficient FPGA design falls into three categories:
-
- #. Combinatorial statements
- #. Synchronous statements
- #. Initialization of registers at reset
-
- V*HDL do not follow this organization. This means that a lot of repetitive manual coding is needed, which brings sources of human errors, petty issues, and confusion for beginners:
-
- #. wire vs. reg in Verilog
- #. forgetting to initialize a register at reset
- #. deciding whether a combinatorial statement must go into a process/always block or not
- #. simulation mismatches with combinatorial processes/always blocks
- #. and more...
-
- A little-known fact about FPGAs is that many of them have the ability to initialize their registers from the bitstream contents. This can be done in a portable and standard way using an "initial" block in Verilog, and by affecting a value at the signal declaration in VHDL. This renders an explicit reset signal unnecessary in practice in some cases, which opens the way for further design optimization. However, this form of initialization is entirely not synthesizable for ASIC targets, and it is not easy to switch between the two forms of reset using V*HDL.
-
-#. V*HDL support for composite types is very limited. Signals having a record type in VHDL are unidirectional, which makes them clumsy to use e.g. in bus interfaces. There is no record type support in Verilog, which means that a lot of copy-and-paste has to be done when forwarding grouped signals.
-
-#. V*HDL support for procedurally generated logic is extremely limited. The most advanced forms of procedural generation of synthesizable logic that V*HDL offers are CPP-style directives in Verilog, combinatorial functions, and ``generate`` statements. Nothing really fancy, and it shows. To give a few examples:
-
- #. Building highly flexible bus interconnect is not possible. Even arbitrating any given number of bus masters for commonplace protocols such as Wishbone is difficult with the tools that V*HDL puts at our disposal.
- #. Building a memory infrastructure (including bus interconnect, bridges and caches) that can automatically adapt itself at compile-time to any word size of the SDRAM is clumsy and tedious.
- #. Building register banks for control, status and interrupt management of cores can also largely benefit from automation.
- #. Many hardware acceleration problems can fit into the dataflow programming model. Manual dataflow implementation in V*HDL has, again, a lot of redundancy and potential for human errors. See the Milkymist texture mapping unit [mthesis]_ [mxcell]_ for an example of this. The amount of detail to deal with manually also makes the design space exploration difficult, and therefore hinders the design of efficient architectures.
- #. Pre-computation of values, such as filter coefficients for DSP or even simply trigonometric tables, must often be done using external tools whose results are copy-and-pasted (in the best case, automatically) into the V*HDL source.
-
-.. [mthesis] http://m-labs.hk/thesis/thesis.pdf
-.. [mxcell] http://www.xilinx.com/publications/archives/xcell/Xcell77.pdf p30-35
-
-Enter Migen, a Python toolbox for building complex digital hardware. We could have designed a brand new programming language, but that would have been reinventing the wheel instead of being able to benefit from Python's rich features and immense library. The price to pay is a slightly cluttered syntax at times when writing descriptions in FHDL, but we believe this is totally acceptable, particularly when compared to VHDL ;-)
-
-Migen is made up of several related components:
-
-#. the base language, FHDL
-#. a library of small generic cores
-#. a simulator
-#. a build system
-
-Installing Migen
-****************
-
-Either run the ``setup.py`` installation script or simply set ``PYTHONPATH`` to the root of the source directory.
-
-If you wish to contribute patches, the suggest way to install is;
- #. Clone from the git repository at http://github.com/m-labs/migen
- #. Install using ``python3 ./setup.py develop --user``
- #. Edit the code in your git checkout.
-
-Alternative install methods
-===========================
-
- * Migen is available for the Anaconda Python distribution. The package can be found at at https://anaconda.org/m-labs/migen
- * Migen can be referenced in a requirements.txt file (used for ``pip install -r requirements.txt``) via ``-e git+http://github.com/m-labs/migen.git#egg=migen``. See the pip documentation for more information.
-
-Feedback
-********
-Feedback concerning Migen or this manual should be sent to the M-Labs developers' mailing list ``devel`` on lists.m-labs.hk.
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="159.05869"
- height="106.55"
- id="svg3245"
- version="1.1"
- inkscape:version="0.48.1 r9760"
- sodipodi:docname="migen.svg"
- inkscape:export-filename="/home/lekernel/migen.png"
- inkscape:export-xdpi="184.10001"
- inkscape:export-ydpi="184.10001">
- <defs
- id="defs3247">
- <linearGradient
- id="linearGradient6093">
- <stop
- style="stop-color:#2ca22c;stop-opacity:0;"
- offset="0"
- id="stop6095" />
- <stop
- style="stop-color:#2ca22c;stop-opacity:1;"
- offset="1"
- id="stop6097" />
- </linearGradient>
- <linearGradient
- id="linearGradient6047">
- <stop
- style="stop-color:#ffffff;stop-opacity:1;"
- offset="0"
- id="stop6049" />
- <stop
- style="stop-color:#ffffff;stop-opacity:0;"
- offset="1"
- id="stop6051" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#a"
- id="linearGradient6176"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.24477,0,0,0.24477,203.271,213.559)"
- x1="150.95"
- y1="-22.384001"
- x2="252.2"
- y2="204.03999" />
- <linearGradient
- id="a"
- y2="150.32001"
- gradientUnits="userSpaceOnUse"
- y1="13.899"
- x2="200.5"
- x1="200.5">
- <stop
- style="stop-color:#fff"
- offset=".1374"
- id="stop7" />
- <stop
- style="stop-color:#509e10;stop-opacity:1;"
- offset="1"
- id="stop9" />
- </linearGradient>
- <linearGradient
- inkscape:collect="always"
- xlink:href="#a"
- id="linearGradient3345"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.24477,0,0,0.24477,203.271,213.559)"
- x1="150.95"
- y1="-22.384001"
- x2="252.2"
- y2="204.03999" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#a"
- id="linearGradient3349"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.24477,0,0,0.24477,280.71427,440.33237)"
- x1="150.95"
- y1="-22.384001"
- x2="252.2"
- y2="204.03999" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6047"
- id="linearGradient6053"
- x1="178.04323"
- y1="474.42865"
- x2="235.87062"
- y2="474.42865"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(0.78422775,0,0,1,105.91918,-2.4999996)" />
- <linearGradient
- inkscape:collect="always"
- xlink:href="#linearGradient6093"
- id="linearGradient6099"
- x1="242.87946"
- y1="471.54514"
- x2="289.73526"
- y2="471.54514"
- gradientUnits="userSpaceOnUse"
- gradientTransform="matrix(1,0,0,1.1424088,0,-67.150429)" />
- </defs>
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="2.8"
- inkscape:cx="134.13698"
- inkscape:cy="59.325232"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="false"
- inkscape:window-width="1916"
- inkscape:window-height="1117"
- inkscape:window-x="0"
- inkscape:window-y="0"
- inkscape:window-maximized="1"
- showguides="true"
- inkscape:guide-bbox="true"
- fit-margin-top="0"
- fit-margin-left="0"
- fit-margin-right="0"
- fit-margin-bottom="0" />
- <metadata
- id="metadata3250">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(-242.87946,-440.32929)">
- <rect
- style="fill:url(#linearGradient6099);fill-opacity:1;stroke:none"
- id="rect6043"
- width="66.843575"
- height="23.704336"
- x="242.87946"
- y="459.6947" />
- <path
- inkscape:connector-curvature="0"
- id="path29"
- d="m 366.02427,471.24237 c -22.519,36.716 -73.921,29.454 -73.921,29.454 32.229,-32.229 0.16326,-57.929 0.16326,-57.929 0,0 51.973,-7.996 73.758,28.475"
- style="font-size:18px;fill:#00ad00;fill-opacity:1;font-family:'DejaVu Sans, Arial, Sans'" />
- <path
- inkscape:connector-curvature="0"
- id="path31"
- d="m 366.02427,471.24237 c -22.519,36.716 -73.921,29.454 -73.921,29.454 32.229,-32.229 0.16326,-57.929 0.16326,-57.929 0,0 51.973,-7.996 73.758,28.475"
- style="font-size:18px;fill:none;font-family:'DejaVu Sans, Arial, Sans'" />
- <path
- style="font-size:18px;font-family:'DejaVu Sans, Arial, Sans'"
- inkscape:connector-curvature="0"
- id="path33"
- d="m 364.64427,470.43237 c -5.3108,8.6038 -12.825,15.435 -21.719,20.199 -7.7214,4.1357 -16.268,6.5868 -24.897,7.9228 -6.0011,0.92916 -12.11,1.2491 -18.178,1.0907 -1.8804,-0.0489 -3.76,-0.15102 -5.6339,-0.31747 -0.51696,-0.046 -1.0334,-0.0977 -1.5489,-0.15739 -0.29226,-0.0338 -0.85842,-0.11431 -0.14808,-0.0144 0.234,0.88632 0.468,1.7726 0.702,2.6592 8.3771,-8.431 15.128,-19.206 14.819,-31.472 -0.20072,-7.9507 -3.4638,-15.551 -8.2374,-21.816 -1.8852,-2.4739 -3.9815,-4.9329 -6.418,-6.8911 -0.234,0.88633 -0.46801,1.7729 -0.70201,2.6592 0.61487,-0.0942 -0.31747,0.0377 0.24551,-0.0343 0.60361,-0.0769 1.2087,-0.14221 1.814,-0.20194 2.1765,-0.21442 4.3616,-0.33925 6.5477,-0.40461 7.0088,-0.20928 14.057,0.24796 20.959,1.4953 7.9781,1.442 15.783,3.9756 22.86,7.9654 8.0388,4.532 14.777,11.012 19.535,18.924 1.0557,1.756 3.8079,0.15739 2.7476,-1.606 -5.1914,-8.6336 -12.6,-15.613 -21.408,-20.474 -7.7483,-4.275 -16.361,-6.8644 -25.074,-8.2486 -9.4825,-1.5066 -19.54,-1.944 -29.073,-0.48367 -1.1345,0.17379 -1.5874,1.9477 -0.70201,2.6592 3.0624,2.4612 5.6283,5.6205 7.7454,8.8104 4.5202,6.8118 6.9303,14.977 5.6423,23.154 -1.4588,9.2607 -7.0781,17.201 -13.551,23.715 -0.75977,0.76492 -0.53067,2.4859 0.70201,2.6592 9.9738,1.4023 20.482,0.7025 30.334,-1.1362 8.4689,-1.5805 16.759,-4.3922 24.256,-8.6664 8.6297,-4.9199 15.91,-11.93 21.128,-20.383 1.0812,-1.7514 -1.6723,-3.3482 -2.7473,-1.606 z" />
- <path
- inkscape:connector-curvature="0"
- id="path35"
- d="m 295.19427,443.74237 c 0,0 12.67,11.257 12.67,27.475 0,0 9.8236,-9.7551 23.069,0 0,0 15.098,13.305 33.229,0 0,0 -15.539,-32.087 -68.968,-27.475 z"
- style="font-size:18px;fill:url(#linearGradient3349);fill-opacity:1;font-family:'DejaVu Sans, Arial, Sans'" />
- <line
- id="line39"
- y2="471.03238"
- x2="400.71429"
- y1="471.03238"
- x1="366.79425"
- style="font-size:18px;fill:none;stroke:#000000;stroke-width:2.44770002;font-family:'DejaVu Sans, Arial, Sans'" />
- <path
- inkscape:connector-curvature="0"
- id="path59"
- d="m 344.15733,461.16448 4.84652,0"
- style="font-size:18px;fill:none;stroke:#000000;stroke-width:2.44799995;stroke-miterlimit:4;stroke-dasharray:none;font-family:'DejaVu Sans, Arial, Sans'"
- sodipodi:nodetypes="cc" />
- <path
- sodipodi:nodetypes="cc"
- style="font-size:18px;fill:none;stroke:#000000;stroke-width:2.44799995;stroke-miterlimit:4;stroke-dasharray:none;font-family:'DejaVu Sans, Arial, Sans'"
- d="m 344.15733,481.90109 4.84652,0"
- id="path6037"
- inkscape:connector-curvature="0" />
- <text
- xml:space="preserve"
- style="font-size:40px;font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Orbitron;-inkscape-font-specification:Orbitron Light"
- x="257.14285"
- y="537.7193"
- id="text6055"
- sodipodi:linespacing="125%"><tspan
- sodipodi:role="line"
- id="tspan6057"
- x="257.14285"
- y="537.7193">migen</tspan></text>
- <path
- sodipodi:nodetypes="cc"
- style="font-size:18px;fill:none;stroke:#000000;stroke-width:2.61650872;stroke-miterlimit:4;stroke-dasharray:none;font-family:'DejaVu Sans, Arial, Sans'"
- d="m 289.42519,459.68794 14.57866,0"
- id="path6105"
- inkscape:connector-curvature="0" />
- <path
- inkscape:connector-curvature="0"
- id="path6107"
- d="m 289.42519,483.37763 14.57866,0"
- style="font-size:18px;fill:none;stroke:#000000;stroke-width:2.61650872;stroke-miterlimit:4;stroke-dasharray:none;font-family:'DejaVu Sans, Arial, Sans'"
- sodipodi:nodetypes="cc" />
- </g>
-</svg>
+++ /dev/null
-API reference
-=============
-
-:mod:`fhdl.structure` module
-----------------------------
-
-.. automodule:: migen.fhdl.structure
- :members:
- :show-inheritance:
-
-:mod:`fhdl.bitcontainer` module
--------------------------------
-
-.. automodule:: migen.fhdl.bitcontainer
- :members:
- :show-inheritance:
-
-:mod:`genlib.fifo` module
--------------------------
-
-.. automodule:: migen.genlib.fifo
- :members:
- :show-inheritance:
-
-:mod:`genlib.coding` module
----------------------------
-
-.. automodule:: migen.genlib.coding
- :members:
- :show-inheritance:
-
-:mod:`genlib.sort` module
--------------------------
-
-.. automodule:: migen.genlib.sort
- :members:
- :show-inheritance:
+++ /dev/null
-Simulating a Migen design
-#########################
-
-Migen allows you to easily simulate your FHDL design and interface it with arbitrary Python code. The simulator is written in pure Python and interprets the FHDL structure directly without using an external Verilog simulator.
-
-[To be rewritten]
+++ /dev/null
-Synthesizing a Migen design
-###########################
-
-[To be written]
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-
-
-class Example(Module):
- def __init__(self):
- dx = 2
- dy = 2
-
- x = Signal(max=dx)
- y = Signal(max=dy)
- out = Signal()
-
- my_2d_array = Array(Array(Signal() for a in range(dx)) for b in range(dy))
- self.comb += out.eq(my_2d_array[x][y])
-
- we = Signal()
- inp = Signal()
- self.sync += If(we,
- my_2d_array[x][y].eq(inp)
- )
-
- ina = Array(Signal() for a in range(dx))
- outa = Array(Signal() for a in range(dy))
- self.specials += Instance("test", o_O=outa[y], i_I=ina[x])
-
-if __name__ == "__main__":
- print(verilog.convert(Example()))
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-
-class Example(Module):
- def __init__(self):
- self.s = Signal()
- self.counter = Signal(8)
- x = Array(Signal(name="a") for i in range(7))
-
- myfsm = FSM()
- self.submodules += myfsm
-
- myfsm.act("FOO",
- self.s.eq(1),
- NextState("BAR")
- )
- myfsm.act("BAR",
- self.s.eq(0),
- NextValue(self.counter, self.counter + 1),
- NextValue(x[self.counter], 89),
- NextState("FOO")
- )
-
- self.be = myfsm.before_entering("FOO")
- self.ae = myfsm.after_entering("FOO")
- self.bl = myfsm.before_leaving("FOO")
- self.al = myfsm.after_leaving("FOO")
-
-if __name__ == "__main__":
- example = Example()
- print(verilog.convert(example, {example.s, example.counter, example.be, example.ae, example.bl, example.al}))
+++ /dev/null
-from random import Random
-
-from migen import *
-from migen.genlib.cdc import GrayCounter
-
-
-def tb(dut):
- prng = Random(7345)
- for i in range(35):
- print("{0:0{1}b} CE={2} bin={3}".format((yield dut.q),
- len(dut.q), (yield dut.ce), (yield dut.q_binary)))
- yield dut.ce.eq(prng.getrandbits(1))
- yield
-
-
-if __name__ == "__main__":
- dut = GrayCounter(3)
- run_simulation(dut, tb(dut), vcd_name="graycounter.vcd")
+++ /dev/null
-import subprocess
-
-from migen import *
-from migen.fhdl.verilog import convert
-
-
-# Create a parent module with two instances of a child module.
-# Bind input ports to first module and output ports to second,
-# and create internal signals to connect the first module to the
-# second.
-class ParentModule(Module):
- def __init__(self):
- self.inputs = [Signal(x+1, name="input{}".format(x)) for x in range(4)]
- self.trans = [Signal(x+1) for x in range(4)]
- self.outputs = [Signal(x+1, name="output{}".format(x)) for x in range(4)]
- self.io = set(self.inputs) | set(self.outputs)
- i = Instance("ChildModule",
- i_master_clk=ClockSignal(),
- i_master_rst=ResetSignal(),
- i_input0=self.inputs[0],
- i_input1=self.inputs[1],
- i_input2=self.inputs[2],
- i_input3=self.inputs[3],
- o_output0=self.trans[0],
- o_output1=self.trans[1],
- o_output2=self.trans[2],
- o_output3=self.trans[3]
- )
- j = Instance("ChildModule",
- i_master_clk=ClockSignal(),
- i_master_rst=ResetSignal(),
- i_input0=self.trans[0],
- i_input1=self.trans[1],
- i_input2=self.trans[2],
- i_input3=self.trans[3],
- o_output0=self.outputs[0],
- o_output1=self.outputs[1],
- o_output2=self.outputs[2],
- o_output3=self.outputs[3]
- )
- self.specials += i, j
-
-
-class ChildModule(Module):
- def __init__(self):
- self.inputs = [Signal(x+1, name_override="input{}".format(x)) for x in range(4)]
- self.outputs = [Signal(x+1, name_override="output{}".format(x)) for x in range(4)]
- self.io = set()
- for x in range(4):
- self.sync.master += self.outputs[x].eq(self.inputs[x])
- self.io = self.io.union(self.inputs)
- self.io = self.io.union(self.outputs)
-
-
-# Generate RTL for the parent module and the submodule, run through
-# icarus for a syntax check
-def test_instance_module():
- sub = ChildModule()
- convert(sub, sub.io, name="ChildModule").write("ChildModule.v")
-
- im = ParentModule()
- convert(im, im.io, name="ParentModule").write("ParentModule.v")
-
- subprocess.check_call(["iverilog", "-W", "all",
- "ParentModule.v", "ChildModule.v"])
-
-if __name__ == "__main__":
- test_instance_module()
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-from migen.genlib.divider import Divider
-
-
-class CDM(Module):
- def __init__(self):
- self.submodules.divider = Divider(5)
- self.clock_domains.cd_sys = ClockDomain(reset_less=True)
-
-
-class MultiMod(Module):
- def __init__(self):
- self.submodules.foo = CDM()
- self.submodules.bar = CDM()
-
-if __name__ == "__main__":
- mm = MultiMod()
- print(verilog.convert(mm, {mm.foo.cd_sys.clk, mm.bar.cd_sys.clk}))
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-
-
-class Example(Module):
- def __init__(self):
- self.specials.mem = Memory(32, 100, init=[5, 18, 32])
- p1 = self.mem.get_port(write_capable=True, we_granularity=8)
- p2 = self.mem.get_port(has_re=True, clock_domain="rd")
- self.specials += p1, p2
- self.ios = {p1.adr, p1.dat_r, p1.we, p1.dat_w,
- p2.adr, p2.dat_r, p2.re}
-
-
-if __name__ == "__main__":
- example = Example()
- print(verilog.convert(example, example.ios))
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-
-from functools import reduce
-from operator import or_
-
-
-def gen_list(n):
- s = [Signal() for i in range(n)]
- return s
-
-
-def gen_2list(n):
- s = [Signal(2) for i in range(n)]
- return s
-
-
-class Foo:
- def __init__(self):
- la = gen_list(3)
- lb = gen_2list(2)
- self.sigs = la + lb
-
-
-class Bar:
- def __init__(self):
- self.sigs = gen_list(2)
-
-
-class Example(Module):
- def __init__(self):
- a = [Bar() for x in range(3)]
- b = [Foo() for x in range(3)]
- c = b
- b = [Bar() for x in range(2)]
-
- output = Signal()
- allsigs = []
- for lst in [a, b, c]:
- for obj in lst:
- allsigs.extend(obj.sigs)
- self.comb += output.eq(reduce(or_, allsigs))
-
-print(verilog.convert(Example()))
+++ /dev/null
-from migen import *
-from migen.fhdl.specials import SynthesisDirective
-from migen.fhdl import verilog
-from migen.genlib.cdc import *
-
-
-class XilinxMultiRegImpl(MultiRegImpl):
- def __init__(self, *args, **kwargs):
- MultiRegImpl.__init__(self, *args, **kwargs)
- self.specials += set(SynthesisDirective("attribute shreg_extract of {r} is no", r=r)
- for r in self.regs)
-
-
-class XilinxMultiReg:
- @staticmethod
- def lower(dr):
- return XilinxMultiRegImpl(dr.i, dr.o, dr.odomain, dr.n)
-
-
-if __name__ == "__main__":
- ps = PulseSynchronizer("from", "to")
- v = verilog.convert(ps, {ps.i, ps.o}, special_overrides={MultiReg: XilinxMultiReg})
- print(v)
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-
-
-L = [
- ("position", [
- ("x", 10, DIR_M_TO_S),
- ("y", 10, DIR_M_TO_S),
- ]),
- ("color", 32, DIR_M_TO_S),
- ("stb", 1, DIR_M_TO_S),
- ("ack", 1, DIR_S_TO_M)
-]
-
-
-class Test(Module):
- def __init__(self):
- master = Record(L)
- slave = Record(L)
- self.comb += master.connect(slave)
-
-
-if __name__ == "__main__":
- print(verilog.convert(Test()))
- print(layout_len(L))
- print(layout_partial(L, "position/x", "color"))
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-
-
-class Example(Module):
- def __init__(self):
- a = Signal(3)
- b = Signal(4)
- c = Signal(5)
- d = Signal(7)
- s1 = c[:3][:2]
- s2 = Cat(a, b)[:6]
- s3 = Cat(s1, s2)[-5:]
- self.comb += s3.eq(0)
- self.comb += d.eq(Cat(d[::-1], Cat(s1[:1], s3[-4:])[:3]))
-
-
-if __name__ == "__main__":
- print(verilog.convert(Example()))
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-
-
-class Example(Module):
- def __init__(self, n=6):
- self.pad = Signal(n)
- self.t = TSTriple(n)
- self.specials += self.t.get_tristate(self.pad)
-
-if __name__ == "__main__":
- e = Example()
- print(verilog.convert(e, ios={e.pad, e.t.o, e.t.oe, e.t.i}))
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-from migen.genlib import divider
-
-
-@ResetInserter()
-@CEInserter()
-class Example(Module):
- def __init__(self, width):
- d1 = divider.Divider(width)
- d2 = divider.Divider(width)
- self.submodules += d1, d2
- self.ios = {
- d1.ready_o, d1.quotient_o, d1.remainder_o, d1.start_i, d1.dividend_i, d1.divisor_i,
- d2.ready_o, d2.quotient_o, d2.remainder_o, d2.start_i, d2.dividend_i, d2.divisor_i}
-
-if __name__ == "__main__":
- example = Example(16)
- print(verilog.convert(example, example.ios | {example.ce, example.reset}))
+++ /dev/null
-from migen import *
-
-
-# Our simple counter, which increments at every cycle.
-class Counter(Module):
- def __init__(self):
- self.count = Signal(4)
-
- # At each cycle, increase the value of the count signal.
- # We do it with convertible/synthesizable FHDL code.
- self.sync += self.count.eq(self.count + 1)
-
-
-# Simply read the count signal and print it.
-# The output is:
-# Count: 0
-# Count: 1
-# Count: 2
-# ...
-def counter_test(dut):
- for i in range(20):
- print((yield dut.count)) # read and print
- yield # next clock cycle
- # simulation ends with this generator
-
-
-if __name__ == "__main__":
- dut = Counter()
- run_simulation(dut, counter_test(dut), vcd_name="basic1.vcd")
+++ /dev/null
-from migen import *
-
-
-# A slightly more elaborate counter.
-# Has a clock enable (CE) signal, counts on more bits
-# and resets with a negative number.
-class Counter(Module):
- def __init__(self):
- self.ce = Signal()
- # Demonstrate negative numbers and signals larger than 32 bits.
- self.count = Signal((37, True), reset=-5)
-
- self.sync += If(self.ce, self.count.eq(self.count + 1))
-
-
-def counter_test(dut):
- for cycle in range(20):
- # Only assert CE every second cycle.
- # => each counter value is held for two cycles.
- if cycle % 2:
- yield dut.ce.eq(0) # This is how you write to a signal.
- else:
- yield dut.ce.eq(1)
- print("Cycle: {} Count: {}".format(cycle, (yield dut.count)))
- yield
-
-# Output is:
-# Cycle: 0 Count: -5
-# Cycle: 1 Count: -5
-# Cycle: 2 Count: -4
-# Cycle: 3 Count: -4
-# Cycle: 4 Count: -3
-# ...
-
-if __name__ == "__main__":
- dut = Counter()
- run_simulation(dut, counter_test(dut), vcd_name="basic2.vcd")
+++ /dev/null
-from functools import reduce
-from operator import add
-
-from math import cos, pi
-from scipy import signal
-import matplotlib.pyplot as plt
-
-from migen import *
-from migen.fhdl import verilog
-
-
-# A synthesizable FIR filter.
-class FIR(Module):
- def __init__(self, coef, wsize=16):
- self.coef = coef
- self.wsize = wsize
- self.i = Signal((self.wsize, True))
- self.o = Signal((self.wsize, True))
-
- ###
-
- muls = []
- src = self.i
- for c in self.coef:
- sreg = Signal((self.wsize, True))
- self.sync += sreg.eq(src)
- src = sreg
- c_fp = int(c*2**(self.wsize - 1))
- muls.append(c_fp*sreg)
- sum_full = Signal((2*self.wsize-1, True))
- self.sync += sum_full.eq(reduce(add, muls))
- self.comb += self.o.eq(sum_full >> self.wsize-1)
-
-
-# A test bench for our FIR filter.
-# Generates a sine wave at the input and records the output.
-def fir_tb(dut, frequency, inputs, outputs):
- f = 2**(dut.wsize - 1)
- for cycle in range(200):
- v = 0.1*cos(2*pi*frequency*cycle)
- yield dut.i.eq(int(f*v))
- inputs.append(v)
- outputs.append((yield dut.o)/f)
- yield
-
-
-if __name__ == "__main__":
- # Compute filter coefficients with SciPy.
- coef = signal.remez(30, [0, 0.1, 0.2, 0.4, 0.45, 0.5], [0, 1, 0])
-
- # Simulate for different frequencies and concatenate
- # the results.
- in_signals = []
- out_signals = []
- for frequency in [0.05, 0.1, 0.25]:
- dut = FIR(coef)
- tb = fir_tb(dut, frequency, in_signals, out_signals)
- run_simulation(dut, tb)
-
- # Plot data from the input and output waveforms.
- plt.plot(in_signals)
- plt.plot(out_signals)
- plt.show()
-
- # Print the Verilog source for the filter.
- fir = FIR(coef)
- print(verilog.convert(fir, ios={fir.i, fir.o}))
+++ /dev/null
-from migen import *
-
-
-class Mem(Module):
- def __init__(self):
- # Initialize the beginning of the memory with integers
- # from 0 to 19.
- self.specials.mem = Memory(16, 2**12, init=list(range(20)))
-
-
-def memory_test(dut):
- # write (only first 5 values)
- for i in range(5):
- yield dut.mem[i].eq(42 + i)
- # remember: values are written after the tick, and read before the tick.
- # wait one tick for the memory to update.
- yield
- # read what we have written, plus some initialization data
- for i in range(10):
- value = yield dut.mem[i]
- print(value)
-
-
-if __name__ == "__main__":
- dut = Mem()
- run_simulation(dut, memory_test(dut))
--- /dev/null
+from litex.gen.fhdl import structure as f
+
+
+__all__ = ["log2_int", "bits_for", "value_bits_sign"]
+
+
+def log2_int(n, need_pow2=True):
+ l = 1
+ r = 0
+ while l < n:
+ l *= 2
+ r += 1
+ if need_pow2 and l != n:
+ raise ValueError("Not a power of 2")
+ return r
+
+
+def bits_for(n, require_sign_bit=False):
+ if n > 0:
+ r = log2_int(n + 1, False)
+ else:
+ require_sign_bit = True
+ r = log2_int(-n, False)
+ if require_sign_bit:
+ r += 1
+ return r
+
+
+def value_bits_sign(v):
+ """Bit length and signedness of a value.
+
+ Parameters
+ ----------
+ v : Value
+
+ Returns
+ -------
+ int, bool
+ Number of bits required to store `v` or available in `v`, followed by
+ whether `v` has a sign bit (included in the bit count).
+
+ Examples
+ --------
+ >>> value_bits_sign(f.Signal(8))
+ 8, False
+ >>> value_bits_sign(C(0xaa))
+ 8, False
+ """
+ if isinstance(v, (f.Constant, f.Signal)):
+ return v.nbits, v.signed
+ elif isinstance(v, (f.ClockSignal, f.ResetSignal)):
+ return 1, False
+ elif isinstance(v, f._Operator):
+ obs = list(map(value_bits_sign, v.operands))
+ if v.op == "+" or v.op == "-":
+ if not obs[0][1] and not obs[1][1]:
+ # both operands unsigned
+ return max(obs[0][0], obs[1][0]) + 1, False
+ elif obs[0][1] and obs[1][1]:
+ # both operands signed
+ return max(obs[0][0], obs[1][0]) + 1, True
+ elif not obs[0][1] and obs[1][1]:
+ # first operand unsigned (add sign bit), second operand signed
+ return max(obs[0][0] + 1, obs[1][0]) + 1, True
+ else:
+ # first signed, second operand unsigned (add sign bit)
+ return max(obs[0][0], obs[1][0] + 1) + 1, True
+ elif v.op == "*":
+ if not obs[0][1] and not obs[1][1]:
+ # both operands unsigned
+ return obs[0][0] + obs[1][0], False
+ elif obs[0][1] and obs[1][1]:
+ # both operands signed
+ return obs[0][0] + obs[1][0] - 1, True
+ else:
+ # one operand signed, the other unsigned (add sign bit)
+ return obs[0][0] + obs[1][0] + 1 - 1, True
+ elif v.op == "<<<":
+ if obs[1][1]:
+ extra = 2**(obs[1][0] - 1) - 1
+ else:
+ extra = 2**obs[1][0] - 1
+ return obs[0][0] + extra, obs[0][1]
+ elif v.op == ">>>":
+ if obs[1][1]:
+ extra = 2**(obs[1][0] - 1)
+ else:
+ extra = 0
+ return obs[0][0] + extra, obs[0][1]
+ elif v.op == "&" or v.op == "^" or v.op == "|":
+ if not obs[0][1] and not obs[1][1]:
+ # both operands unsigned
+ return max(obs[0][0], obs[1][0]), False
+ elif obs[0][1] and obs[1][1]:
+ # both operands signed
+ return max(obs[0][0], obs[1][0]), True
+ elif not obs[0][1] and obs[1][1]:
+ # first operand unsigned (add sign bit), second operand signed
+ return max(obs[0][0] + 1, obs[1][0]), True
+ else:
+ # first signed, second operand unsigned (add sign bit)
+ return max(obs[0][0], obs[1][0] + 1), True
+ elif v.op == "<" or v.op == "<=" or v.op == "==" or v.op == "!=" \
+ or v.op == ">" or v.op == ">=":
+ return 1, False
+ elif v.op == "~":
+ return obs[0]
+ else:
+ raise TypeError
+ elif isinstance(v, f._Slice):
+ return v.stop - v.start, value_bits_sign(v.value)[1]
+ elif isinstance(v, f.Cat):
+ return sum(value_bits_sign(sv)[0] for sv in v.l), False
+ elif isinstance(v, f.Replicate):
+ return (value_bits_sign(v.v)[0])*v.n, False
+ elif isinstance(v, f._ArrayProxy):
+ bsc = list(map(value_bits_sign, v.choices))
+ return max(bs[0] for bs in bsc), any(bs[1] for bs in bsc)
+ else:
+ raise TypeError("Can not calculate bit length of {} {}".format(
+ type(v), v))
--- /dev/null
+from operator import itemgetter
+
+
+class ConvOutput:
+ def __init__(self):
+ self.main_source = ""
+ self.data_files = dict()
+
+ def set_main_source(self, src):
+ self.main_source = src
+
+ def add_data_file(self, filename_base, content):
+ filename = filename_base
+ i = 1
+ while filename in self.data_files:
+ parts = filename_base.split(".", maxsplit=1)
+ parts[0] += "_" + str(i)
+ filename = ".".join(parts)
+ i += 1
+ self.data_files[filename] = content
+ return filename
+
+ def __str__(self):
+ r = self.main_source + "\n"
+ for filename, content in sorted(self.data_files.items(),
+ key=itemgetter(0)):
+ r += filename + ":\n" + content
+ return r
+
+ def write(self, main_filename):
+ with open(main_filename, "w") as f:
+ f.write(self.main_source)
+ for filename, content in self.data_files.items():
+ with open(filename, "w") as f:
+ f.write(content)
--- /dev/null
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.module import Module
+from litex.gen.fhdl.tools import insert_reset, rename_clock_domain
+
+
+__all__ = ["CEInserter", "ResetInserter", "ClockDomainsRenamer",
+ "ModuleTransformer"]
+
+
+class ModuleTransformer:
+ # overload this in derived classes
+ def transform_instance(self, i):
+ pass
+
+ # overload this in derived classes
+ def transform_fragment(self, i, f):
+ pass
+
+ def wrap_class(self, victim):
+ class Wrapped(victim):
+ def __init__(i, *args, **kwargs):
+ victim.__init__(i, *args, **kwargs)
+ self.transform_instance(i)
+
+ def get_fragment(i):
+ f = victim.get_fragment(i)
+ self.transform_fragment(i, f)
+ return f
+
+ Wrapped.__name__ = victim.__name__
+ # "{}_{}".format(self.__class__.__name__, victim.__name__)
+ return Wrapped
+
+ def wrap_instance(self, victim):
+ self.transform_instance(victim)
+ orig_get_fragment = victim.get_fragment
+
+ def get_fragment():
+ f = orig_get_fragment()
+ self.transform_fragment(victim, f)
+ return f
+
+ victim.get_fragment = get_fragment
+ return victim
+
+ def __call__(self, victim):
+ if isinstance(victim, Module):
+ return self.wrap_instance(victim)
+ else:
+ return self.wrap_class(victim)
+
+
+class ControlInserter(ModuleTransformer):
+ control_name = None # override this
+
+ def __init__(self, clock_domains=None):
+ self.clock_domains = clock_domains
+
+ def transform_instance(self, i):
+ if self.clock_domains is None:
+ ctl = Signal(name=self.control_name)
+ assert not hasattr(i, self.control_name)
+ setattr(i, self.control_name, ctl)
+ else:
+ for cd in self.clock_domains:
+ name = self.control_name + "_" + cd
+ ctl = Signal(name=name)
+ assert not hasattr(i, name)
+ setattr(i, name, ctl)
+
+ def transform_fragment(self, i, f):
+ if self.clock_domains is None:
+ if len(f.sync) != 1:
+ raise ValueError("Control signal clock domains must be specified when module has more than one domain")
+ cdn = list(f.sync.keys())[0]
+ to_insert = [(getattr(i, self.control_name), cdn)]
+ else:
+ to_insert = [(getattr(i, self.control_name + "_" + cdn), cdn)
+ for cdn in self.clock_domains]
+ self.transform_fragment_insert(i, f, to_insert)
+
+
+class CEInserter(ControlInserter):
+ control_name = "ce"
+
+ def transform_fragment_insert(self, i, f, to_insert):
+ for ce, cdn in to_insert:
+ f.sync[cdn] = [If(ce, *f.sync[cdn])]
+
+
+class ResetInserter(ControlInserter):
+ control_name = "reset"
+
+ def transform_fragment_insert(self, i, f, to_insert):
+ for reset, cdn in to_insert:
+ f.sync[cdn] = insert_reset(reset, f.sync[cdn])
+
+
+class ClockDomainsRenamer(ModuleTransformer):
+ def __init__(self, cd_remapping):
+ if isinstance(cd_remapping, str):
+ cd_remapping = {"sys": cd_remapping}
+ self.cd_remapping = cd_remapping
+
+ def transform_fragment(self, i, f):
+ for old, new in self.cd_remapping.items():
+ rename_clock_domain(f, old, new)
--- /dev/null
+from collections import OrderedDict, namedtuple
+
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.namer import build_namespace
+from litex.gen.fhdl.tools import list_special_ios
+from litex.gen.fhdl.structure import _Fragment
+from litex.gen.fhdl.conv_output import ConvOutput
+
+
+_Port = namedtuple("_Port", "name direction")
+_Cell = namedtuple("_Cell", "name ports")
+_Property = namedtuple("_Property", "name value")
+_Instance = namedtuple("_Instance", "name cell properties")
+_NetBranch = namedtuple("_NetBranch", "portname instancename")
+
+
+def _write_cells(cells):
+ r = ""
+ for cell in cells:
+ r += """
+ (cell {0.name}
+ (cellType GENERIC)
+ (view view_1
+ (viewType NETLIST)
+ (interface""".format(cell)
+ for port in cell.ports:
+ r += """
+ (port {0.name} (direction {0.direction}))""".format(port)
+ r += """
+ )
+ )
+ )"""
+ return r
+
+
+def _write_io(ios):
+ r = ""
+ for s in ios:
+ r += """
+ (port {0.name} (direction {0.direction}))""".format(s)
+ return r
+
+
+def _write_instantiations(instances, cell_library):
+ instantiations = ""
+ for instance in instances:
+ instantiations += """
+ (instance {0.name}
+ (viewRef view_1 (cellRef {0.cell} (libraryRef {1})))""".format(instance, cell_library)
+ for prop in instance.properties:
+ instantiations += """
+ (property {0} (string "{1}"))""".format(prop.name, prop.value)
+ instantiations += """
+ )"""
+ return instantiations
+
+
+def _write_connections(connections):
+ r = ""
+ for netname, branches in connections.items():
+ r += """
+ (net {0}
+ (joined""".format(netname)
+ for branch in branches:
+ r += """
+ (portRef {0}{1})""".format(branch.portname, "" if branch.instancename == "" else " (instanceRef {})".format(branch.instancename))
+ r += """
+ )
+ )"""
+ return r
+
+
+def _write_edif(cells, ios, instances, connections, cell_library, design_name, part, vendor):
+ r = """(edif {0}
+ (edifVersion 2 0 0)
+ (edifLevel 0)
+ (keywordMap (keywordLevel 0))
+ (external {1}
+ (edifLevel 0)
+ (technology (numberDefinition))""".format(design_name, cell_library)
+ r += _write_cells(cells)
+ r += """
+ )
+ (library {0}_lib
+ (edifLevel 0)
+ (technology (numberDefinition))
+ (cell {0}
+ (cellType GENERIC)
+ (view view_1
+ (viewType NETLIST)
+ (interface""".format(design_name)
+ r += _write_io(ios)
+ r += """
+ (designator "{0}")
+ )
+ (contents""".format(part)
+ r += _write_instantiations(instances, cell_library)
+ r += _write_connections(connections)
+ r += """
+ )
+ )
+ )
+ )
+ (design {0}
+ (cellRef {0} (libraryRef {0}_lib))
+ (property PART (string "{1}") (owner "{2}"))
+ )
+)""".format(design_name, part, vendor)
+
+ return r
+
+
+def _generate_cells(f):
+ cell_dict = OrderedDict()
+ for special in f.specials:
+ if isinstance(special, Instance):
+ port_list = []
+ for port in special.items:
+ if isinstance(port, Instance.Input):
+ port_list.append(_Port(port.name, "INPUT"))
+ elif isinstance(port, Instance.Output):
+ port_list.append(_Port(port.name, "OUTPUT"))
+ elif isinstance(port, Instance.InOut):
+ port_list.append(_Port(port.name, "INOUT"))
+ elif isinstance(port, Instance.Parameter):
+ pass
+ else:
+ raise NotImplementedError("Unsupported instance item")
+ if special.of in cell_dict:
+ if set(port_list) != set(cell_dict[special.of]):
+ raise ValueError("All instances must have the same ports for EDIF conversion")
+ else:
+ cell_dict[special.of] = port_list
+ else:
+ raise ValueError("EDIF conversion can only handle synthesized fragments")
+ return [_Cell(k, v) for k, v in cell_dict.items()]
+
+
+def _generate_instances(f, ns):
+ instances = []
+ for special in f.specials:
+ if isinstance(special, Instance):
+ props = []
+ for prop in special.items:
+ if isinstance(prop, Instance.Input):
+ pass
+ elif isinstance(prop, Instance.Output):
+ pass
+ elif isinstance(prop, Instance.InOut):
+ pass
+ elif isinstance(prop, Instance.Parameter):
+ props.append(_Property(name=prop.name, value=prop.value))
+ else:
+ raise NotImplementedError("Unsupported instance item")
+ instances.append(_Instance(name=ns.get_name(special), cell=special.of, properties=props))
+ else:
+ raise ValueError("EDIF conversion can only handle synthesized fragments")
+ return instances
+
+
+def _generate_ios(f, ios, ns):
+ outs = list_special_ios(f, False, True, False)
+ inouts = list_special_ios(f, False, False, True)
+ r = []
+ for io in ios:
+ direction = "OUTPUT" if io in outs else "INOUT" if io in inouts else "INPUT"
+ r.append(_Port(name=ns.get_name(io), direction=direction))
+ return r
+
+
+def _generate_connections(f, ios, ns):
+ r = OrderedDict()
+ for special in f.specials:
+ if isinstance(special, Instance):
+ instname = ns.get_name(special)
+ for port in special.items:
+ if isinstance(port, Instance._IO):
+ s = ns.get_name(port.expr)
+ if s not in r:
+ r[s] = []
+ r[s].append(_NetBranch(portname=port.name, instancename=instname))
+ elif isinstance(port, Instance.Parameter):
+ pass
+ else:
+ raise NotImplementedError("Unsupported instance item")
+ else:
+ raise ValueError("EDIF conversion can only handle synthesized fragments")
+ for s in ios:
+ io = ns.get_name(s)
+ if io not in r:
+ r[io] = []
+ r[io].append(_NetBranch(portname=io, instancename=""))
+ return r
+
+
+def convert(f, ios, cell_library, vendor, device, name="top"):
+ if not isinstance(f, _Fragment):
+ f = f.get_fragment()
+ if f.comb != [] or f.sync != {}:
+ raise ValueError("EDIF conversion can only handle synthesized fragments")
+ if ios is None:
+ ios = set()
+ cells = _generate_cells(f)
+ ns = build_namespace(list_special_ios(f, True, True, True))
+ instances = _generate_instances(f, ns)
+ inouts = _generate_ios(f, ios, ns)
+ connections = _generate_connections(f, ios, ns)
+ src = _write_edif(cells, inouts, instances, connections, cell_library, name, device, vendor)
+
+ r = ConvOutput()
+ r.set_main_source(src)
+ r.ns = ns
+ return r
--- /dev/null
+import collections
+from itertools import combinations
+
+from litex.gen.util.misc import flat_iteration
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.structure import _Fragment
+from litex.gen.fhdl.tools import rename_clock_domain
+
+
+__all__ = ["Module", "FinalizeError"]
+
+
+class FinalizeError(Exception):
+ pass
+
+
+def _flat_list(e):
+ if isinstance(e, collections.Iterable):
+ return flat_iteration(e)
+ else:
+ return [e]
+
+
+class _ModuleProxy:
+ def __init__(self, fm):
+ object.__setattr__(self, "_fm", fm)
+
+
+class _ModuleComb(_ModuleProxy):
+ def __iadd__(self, other):
+ self._fm._fragment.comb += _flat_list(other)
+ return self
+
+
+def _cd_append(d, key, statements):
+ try:
+ l = d[key]
+ except KeyError:
+ l = []
+ d[key] = l
+ l += _flat_list(statements)
+
+
+class _ModuleSyncCD:
+ def __init__(self, fm, cd):
+ self._fm = fm
+ self._cd = cd
+
+ def __iadd__(self, other):
+ _cd_append(self._fm._fragment.sync, self._cd, other)
+ return self
+
+
+class _ModuleSync(_ModuleProxy):
+ def __iadd__(self, other):
+ _cd_append(self._fm._fragment.sync, "sys", other)
+ return self
+
+ def __getattr__(self, name):
+ return _ModuleSyncCD(self._fm, name)
+
+ def __setattr__(self, name, value):
+ if not isinstance(value, _ModuleSyncCD):
+ raise AttributeError("Attempted to assign sync property - use += instead")
+
+
+# _ModuleForwardAttr enables user classes to do e.g.:
+# self.subm.foobar = SomeModule()
+# and then access the submodule with self.foobar.
+class _ModuleForwardAttr:
+ def __setattr__(self, name, value):
+ self.__iadd__(value)
+ setattr(self._fm, name, value)
+
+
+class _ModuleSpecials(_ModuleProxy, _ModuleForwardAttr):
+ def __iadd__(self, other):
+ self._fm._fragment.specials |= set(_flat_list(other))
+ return self
+
+
+class _ModuleSubmodules(_ModuleProxy):
+ def __setattr__(self, name, value):
+ self._fm._submodules += [(name, e) for e in _flat_list(value)]
+ setattr(self._fm, name, value)
+
+ def __iadd__(self, other):
+ self._fm._submodules += [(None, e) for e in _flat_list(other)]
+ return self
+
+
+class _ModuleClockDomains(_ModuleProxy, _ModuleForwardAttr):
+ def __iadd__(self, other):
+ self._fm._fragment.clock_domains += _flat_list(other)
+ return self
+
+
+class Module:
+ def get_fragment(self):
+ assert(not self.get_fragment_called)
+ self.get_fragment_called = True
+ self.finalize()
+ return self._fragment
+
+ def __getattr__(self, name):
+ if name == "comb":
+ return _ModuleComb(self)
+ elif name == "sync":
+ return _ModuleSync(self)
+ elif name == "specials":
+ return _ModuleSpecials(self)
+ elif name == "submodules":
+ return _ModuleSubmodules(self)
+ elif name == "clock_domains":
+ return _ModuleClockDomains(self)
+
+ # hack to have initialized regular attributes without using __init__
+ # (which would require derived classes to call it)
+ elif name == "finalized":
+ self.finalized = False
+ return self.finalized
+ elif name == "_fragment":
+ self._fragment = _Fragment()
+ return self._fragment
+ elif name == "_submodules":
+ self._submodules = []
+ return self._submodules
+ elif name == "_clock_domains":
+ self._clock_domains = []
+ return self._clock_domains
+ elif name == "get_fragment_called":
+ self.get_fragment_called = False
+ return self.get_fragment_called
+
+ else:
+ raise AttributeError("'"+self.__class__.__name__+"' object has no attribute '"+name+"'")
+
+ def __setattr__(self, name, value):
+ if name in ["comb", "sync", "specials", "submodules", "clock_domains"]:
+ if not isinstance(value, _ModuleProxy):
+ raise AttributeError("Attempted to assign special Module property - use += instead")
+ else:
+ object.__setattr__(self, name, value)
+
+ def _collect_submodules(self):
+ r = []
+ for name, submodule in self._submodules:
+ if not submodule.get_fragment_called:
+ r.append((name, submodule.get_fragment()))
+ return r
+
+ def finalize(self, *args, **kwargs):
+ if not self.finalized:
+ self.finalized = True
+ # finalize existing submodules before finalizing us
+ subfragments = self._collect_submodules()
+ self.do_finalize(*args, **kwargs)
+ # finalize submodules created by do_finalize
+ subfragments += self._collect_submodules()
+ # resolve clock domain name conflicts
+ needs_renaming = set()
+ for (mod_name1, f1), (mod_name2, f2) in combinations(subfragments, 2):
+ f1_names = set(cd.name for cd in f1.clock_domains)
+ f2_names = set(cd.name for cd in f2.clock_domains)
+ common_names = f1_names & f2_names
+ if common_names:
+ if mod_name1 is None or mod_name2 is None:
+ raise ValueError("Multiple submodules with local clock domains cannot be anonymous")
+ if mod_name1 == mod_name2:
+ raise ValueError("Multiple submodules with local clock domains cannot have the same name")
+ needs_renaming |= common_names
+ for mod_name, f in subfragments:
+ for cd in f.clock_domains:
+ if cd.name in needs_renaming:
+ rename_clock_domain(f, cd.name, mod_name + "_" + cd.name)
+ # sum subfragments
+ for mod_name, f in subfragments:
+ self._fragment += f
+
+ def do_finalize(self):
+ pass
+
+ def do_exit(self, *args, **kwargs):
+ for name, submodule in self._submodules:
+ submodule.do_exit(*args, **kwargs)
--- /dev/null
+from collections import OrderedDict
+from itertools import combinations
+
+from litex.gen.fhdl.structure import *
+
+
+class _Node:
+ def __init__(self):
+ self.signal_count = 0
+ self.numbers = set()
+ self.use_name = False
+ self.use_number = False
+ self.children = OrderedDict()
+
+
+def _display_tree(filename, tree):
+ from litex.gen.util.treeviz import RenderNode
+
+ def _to_render_node(name, node):
+ children = [_to_render_node(k, v) for k, v in node.children.items()]
+ if node.use_name:
+ if node.use_number:
+ color = (0.5, 0.9, 0.8)
+ else:
+ color = (0.8, 0.5, 0.9)
+ else:
+ if node.use_number:
+ color = (0.9, 0.8, 0.5)
+ else:
+ color = (0.8, 0.8, 0.8)
+ label = "{0}\n{1} signals\n{2}".format(name, node.signal_count, node.numbers)
+ return RenderNode(label, children, color=color)
+
+ top = _to_render_node("top", tree)
+ top.to_svg(filename)
+
+
+def _build_tree(signals, basic_tree=None):
+ root = _Node()
+ for signal in signals:
+ current_b = basic_tree
+ current = root
+ current.signal_count += 1
+ for name, number in signal.backtrace:
+ if basic_tree is None:
+ use_number = False
+ else:
+ current_b = current_b.children[name]
+ use_number = current_b.use_number
+ if use_number:
+ key = (name, number)
+ else:
+ key = name
+ try:
+ current = current.children[key]
+ except KeyError:
+ new = _Node()
+ current.children[key] = new
+ current = new
+ current.numbers.add(number)
+ if use_number:
+ current.all_numbers = sorted(current_b.numbers)
+ current.signal_count += 1
+ return root
+
+
+def _set_use_name(node, node_name=""):
+ cnames = [(k, _set_use_name(v, k)) for k, v in node.children.items()]
+ for (c1_prefix, c1_names), (c2_prefix, c2_names) in combinations(cnames, 2):
+ if not c1_names.isdisjoint(c2_names):
+ node.children[c1_prefix].use_name = True
+ node.children[c2_prefix].use_name = True
+ r = set()
+ for c_prefix, c_names in cnames:
+ if node.children[c_prefix].use_name:
+ for c_name in c_names:
+ r.add((c_prefix, ) + c_name)
+ else:
+ r |= c_names
+
+ if node.signal_count > sum(c.signal_count for c in node.children.values()):
+ node.use_name = True
+ r.add((node_name, ))
+
+ return r
+
+
+def _name_signal(tree, signal):
+ elements = []
+ treepos = tree
+ for step_name, step_n in signal.backtrace:
+ try:
+ treepos = treepos.children[(step_name, step_n)]
+ use_number = True
+ except KeyError:
+ treepos = treepos.children[step_name]
+ use_number = False
+ if treepos.use_name:
+ elname = step_name
+ if use_number:
+ elname += str(treepos.all_numbers.index(step_n))
+ elements.append(elname)
+ return "_".join(elements)
+
+
+def _build_pnd_from_tree(tree, signals):
+ return dict((signal, _name_signal(tree, signal)) for signal in signals)
+
+
+def _invert_pnd(pnd):
+ inv_pnd = dict()
+ for k, v in pnd.items():
+ inv_pnd[v] = inv_pnd.get(v, [])
+ inv_pnd[v].append(k)
+ return inv_pnd
+
+
+def _list_conflicting_signals(pnd):
+ inv_pnd = _invert_pnd(pnd)
+ r = set()
+ for k, v in inv_pnd.items():
+ if len(v) > 1:
+ r.update(v)
+ return r
+
+
+def _set_use_number(tree, signals):
+ for signal in signals:
+ current = tree
+ for step_name, step_n in signal.backtrace:
+ current = current.children[step_name]
+ current.use_number = current.signal_count > len(current.numbers) and len(current.numbers) > 1
+
+_debug = False
+
+
+def _build_pnd_for_group(group_n, signals):
+ basic_tree = _build_tree(signals)
+ _set_use_name(basic_tree)
+ if _debug:
+ _display_tree("tree{0}_basic.svg".format(group_n), basic_tree)
+ pnd = _build_pnd_from_tree(basic_tree, signals)
+
+ # If there are conflicts, try splitting the tree by numbers
+ # on paths taken by conflicting signals.
+ conflicting_signals = _list_conflicting_signals(pnd)
+ if conflicting_signals:
+ _set_use_number(basic_tree, conflicting_signals)
+ if _debug:
+ print("namer: using split-by-number strategy (group {0})".format(group_n))
+ _display_tree("tree{0}_marked.svg".format(group_n), basic_tree)
+ numbered_tree = _build_tree(signals, basic_tree)
+ _set_use_name(numbered_tree)
+ if _debug:
+ _display_tree("tree{0}_numbered.svg".format(group_n), numbered_tree)
+ pnd = _build_pnd_from_tree(numbered_tree, signals)
+ else:
+ if _debug:
+ print("namer: using basic strategy (group {0})".format(group_n))
+
+ # ...then add number suffixes by DUID
+ inv_pnd = _invert_pnd(pnd)
+ duid_suffixed = False
+ for name, signals in inv_pnd.items():
+ if len(signals) > 1:
+ duid_suffixed = True
+ for n, signal in enumerate(sorted(signals, key=lambda x: x.duid)):
+ pnd[signal] += str(n)
+ if _debug and duid_suffixed:
+ print("namer: using DUID suffixes (group {0})".format(group_n))
+
+ return pnd
+
+
+def _build_signal_groups(signals):
+ r = []
+ for signal in signals:
+ # build chain of related signals
+ related_list = []
+ cur_signal = signal
+ while cur_signal is not None:
+ related_list.insert(0, cur_signal)
+ cur_signal = cur_signal.related
+ # add to groups
+ for _ in range(len(related_list) - len(r)):
+ r.append(set())
+ for target_set, source_signal in zip(r, related_list):
+ target_set.add(source_signal)
+ # with the algorithm above and a list of all signals,
+ # a signal appears in all groups of a lower number than its.
+ # make signals appear only in their group of highest number.
+ for s1, s2 in zip(r, r[1:]):
+ s1 -= s2
+ return r
+
+
+def _build_pnd(signals):
+ groups = _build_signal_groups(signals)
+ gpnds = [_build_pnd_for_group(n, gsignals) for n, gsignals in enumerate(groups)]
+
+ pnd = dict()
+ for gn, gpnd in enumerate(gpnds):
+ for signal, name in gpnd.items():
+ result = name
+ cur_gn = gn
+ cur_signal = signal
+ while cur_signal.related is not None:
+ cur_signal = cur_signal.related
+ cur_gn -= 1
+ result = gpnds[cur_gn][cur_signal] + "_" + result
+ pnd[signal] = result
+
+ return pnd
+
+
+def build_namespace(signals, reserved_keywords=set()):
+ pnd = _build_pnd(signals)
+ ns = Namespace(pnd, reserved_keywords)
+ # register signals with name_override
+ for signal in signals:
+ if signal.name_override is not None:
+ ns.get_name(signal)
+ return ns
+
+
+class Namespace:
+ def __init__(self, pnd, reserved_keywords=set()):
+ self.counts = {k: 1 for k in reserved_keywords}
+ self.sigs = {}
+ self.pnd = pnd
+ self.clock_domains = dict()
+
+ def get_name(self, sig):
+ if isinstance(sig, ClockSignal):
+ sig = self.clock_domains[sig.cd].clk
+ if isinstance(sig, ResetSignal):
+ sig = self.clock_domains[sig.cd].rst
+ if sig is None:
+ raise ValueError("Attempted to obtain name of non-existent "
+ "reset signal of domain "+sig.cd)
+
+ if sig.name_override is not None:
+ sig_name = sig.name_override
+ else:
+ sig_name = self.pnd[sig]
+ try:
+ n = self.sigs[sig]
+ except KeyError:
+ try:
+ n = self.counts[sig_name]
+ except KeyError:
+ n = 0
+ self.sigs[sig] = n
+ self.counts[sig_name] = n + 1
+ if n:
+ return sig_name + "_" + str(n)
+ else:
+ return sig_name
--- /dev/null
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.specials import Memory, _MemoryPort, WRITE_FIRST, NO_CHANGE
+from litex.gen.fhdl.decorators import ModuleTransformer
+from litex.gen.util.misc import gcd_multiple
+
+
+class FullMemoryWE(ModuleTransformer):
+ def __init__(self):
+ self.replacments = dict()
+
+ def transform_fragment(self, i, f):
+ newspecials = set()
+
+ for orig in f.specials:
+ if not isinstance(orig, Memory):
+ newspecials.add(orig)
+ continue
+ global_granularity = gcd_multiple([p.we_granularity if p.we_granularity else orig.width for p in orig.ports])
+ if global_granularity == orig.width:
+ newspecials.add(orig) # nothing to do
+ else:
+ newmems = []
+ for i in range(orig.width//global_granularity):
+ if orig.init is None:
+ newinit = None
+ else:
+ newinit = [(v >> i*global_granularity) & (2**global_granularity - 1) for v in orig.init]
+ newmem = Memory(global_granularity, orig.depth, newinit, orig.name_override + "_grain" + str(i))
+ newspecials.add(newmem)
+ newmems.append(newmem)
+ for port in orig.ports:
+ port_granularity = port.we_granularity if port.we_granularity else orig.width
+ newport = _MemoryPort(
+ adr=port.adr,
+
+ dat_r=port.dat_r[i*global_granularity:(i+1)*global_granularity] if port.dat_r is not None else None,
+ we=port.we[i*global_granularity//port_granularity] if port.we is not None else None,
+ dat_w=port.dat_w[i*global_granularity:(i+1)*global_granularity] if port.dat_w is not None else None,
+
+ async_read=port.async_read,
+ re=port.re,
+ we_granularity=0,
+ mode=port.mode,
+ clock_domain=port.clock.cd)
+ newmem.ports.append(newport)
+ newspecials.add(newport)
+ self.replacments[orig] = newmems
+
+ f.specials = newspecials
+
+
+class MemoryToArray(ModuleTransformer):
+ def __init__(self):
+ self.replacements = dict()
+
+ def transform_fragment(self, i, f):
+ newspecials = set()
+
+ for mem in f.specials:
+ if not isinstance(mem, Memory):
+ newspecials.add(mem)
+ continue
+
+ storage = Array()
+ self.replacements[mem] = storage
+ init = []
+ if mem.init is not None:
+ init = mem.init
+ for d in init:
+ mem_storage = Signal(mem.width, reset=d)
+ storage.append(mem_storage)
+ for _ in range(mem.depth-len(init)):
+ mem_storage = Signal(mem.width)
+ storage.append(mem_storage)
+
+ for port in mem.ports:
+ if port.we_granularity:
+ raise NotImplementedError
+ try:
+ sync = f.sync[port.clock.cd]
+ except KeyError:
+ sync = f.sync[port.clock.cd] = []
+
+ # read
+ if port.async_read:
+ f.comb.append(port.dat_r.eq(storage[port.adr]))
+ else:
+ if port.mode == WRITE_FIRST and port.we is not None:
+ adr_reg = Signal.like(port.adr)
+ rd_stmt = adr_reg.eq(port.adr)
+ f.comb.append(port.dat_r.eq(storage[adr_reg]))
+ elif port.mode == NO_CHANGE and port.we is not None:
+ rd_stmt = If(~port.we, port.dat_r.eq(storage[port.adr]))
+ else: # READ_FIRST or port.we is None, simplest case
+ rd_stmt = port.dat_r.eq(storage[port.adr])
+ if port.re is None:
+ sync.append(rd_stmt)
+ else:
+ sync.append(If(port.re, rd_stmt))
+
+ # write
+ if port.we is not None:
+ if port.we_granularity:
+ n = mem.width//port.we_granularity
+ for i in range(n):
+ m = i*port.we_granularity
+ M = (i+1)*port.we_granularity
+ sync.append(If(port.we[i],
+ storage[port.adr][m:M].eq(port.dat_w)))
+ else:
+ sync.append(If(port.we,
+ storage[port.adr].eq(port.dat_w)))
+
+ f.specials = newspecials
--- /dev/null
+from operator import itemgetter
+
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.structure import _Value
+from litex.gen.fhdl.bitcontainer import bits_for, value_bits_sign
+from litex.gen.fhdl.tools import *
+from litex.gen.fhdl.tracer import get_obj_var_name
+from litex.gen.fhdl.verilog import _printexpr as verilog_printexpr
+
+
+__all__ = ["TSTriple", "Instance", "Memory",
+ "READ_FIRST", "WRITE_FIRST", "NO_CHANGE"]
+
+
+class Special(DUID):
+ def iter_expressions(self):
+ for x in []:
+ yield x
+
+ def rename_clock_domain(self, old, new):
+ for obj, attr, direction in self.iter_expressions():
+ rename_clock_domain_expr(getattr(obj, attr), old, new)
+
+ def list_clock_domains(self):
+ r = set()
+ for obj, attr, direction in self.iter_expressions():
+ r |= list_clock_domains_expr(getattr(obj, attr))
+ return r
+
+ def list_ios(self, ins, outs, inouts):
+ r = set()
+ for obj, attr, direction in self.iter_expressions():
+ if (direction == SPECIAL_INPUT and ins) \
+ or (direction == SPECIAL_OUTPUT and outs) \
+ or (direction == SPECIAL_INOUT and inouts):
+ signals = list_signals(getattr(obj, attr))
+ r.update(signals)
+ return r
+
+
+class Tristate(Special):
+ def __init__(self, target, o, oe, i=None):
+ Special.__init__(self)
+ self.target = wrap(target)
+ self.o = wrap(o)
+ self.oe = wrap(oe)
+ self.i = wrap(i) if i is not None else None
+
+ def iter_expressions(self):
+ for attr, target_context in [
+ ("target", SPECIAL_INOUT),
+ ("o", SPECIAL_INPUT),
+ ("oe", SPECIAL_INPUT),
+ ("i", SPECIAL_OUTPUT)]:
+ if getattr(self, attr) is not None:
+ yield self, attr, target_context
+
+ @staticmethod
+ def emit_verilog(tristate, ns, add_data_file):
+ def pe(e):
+ return verilog_printexpr(ns, e)[0]
+ w, s = value_bits_sign(tristate.target)
+ r = "assign " + pe(tristate.target) + " = " \
+ + pe(tristate.oe) + " ? " + pe(tristate.o) \
+ + " : " + str(w) + "'bz;\n"
+ if tristate.i is not None:
+ r += "assign " + pe(tristate.i) + " = " + pe(tristate.target) + ";\n"
+ r += "\n"
+ return r
+
+
+class TSTriple:
+ def __init__(self, bits_sign=None, min=None, max=None, reset_o=0, reset_oe=0):
+ self.o = Signal(bits_sign, min=min, max=max, reset=reset_o)
+ self.oe = Signal(reset=reset_oe)
+ self.i = Signal(bits_sign, min=min, max=max)
+
+ def get_tristate(self, target):
+ return Tristate(target, self.o, self.oe, self.i)
+
+
+class Instance(Special):
+ class _IO:
+ def __init__(self, name, expr=None):
+ self.name = name
+ if expr is None:
+ expr = Signal()
+ self.expr = wrap(expr)
+ class Input(_IO):
+ pass
+ class Output(_IO):
+ pass
+ class InOut(_IO):
+ pass
+ class Parameter:
+ def __init__(self, name, value):
+ self.name = name
+ if isinstance(value, (int, bool)):
+ value = Constant(value)
+ self.value = value
+ class PreformattedParam(str):
+ pass
+
+ def __init__(self, of, *items, name="", synthesis_directive=None, **kwargs):
+ Special.__init__(self)
+ self.of = of
+ if name:
+ self.name_override = name
+ else:
+ self.name_override = of
+ self.items = list(items)
+ self.synthesis_directive = synthesis_directive
+ for k, v in sorted(kwargs.items(), key=itemgetter(0)):
+ item_type, item_name = k.split("_", maxsplit=1)
+ item_class = {
+ "i": Instance.Input,
+ "o": Instance.Output,
+ "io": Instance.InOut,
+ "p": Instance.Parameter
+ }[item_type]
+ self.items.append(item_class(item_name, v))
+
+ def get_io(self, name):
+ for item in self.items:
+ if isinstance(item, Instance._IO) and item.name == name:
+ return item.expr
+
+ def iter_expressions(self):
+ for item in self.items:
+ if isinstance(item, Instance.Input):
+ yield item, "expr", SPECIAL_INPUT
+ elif isinstance(item, Instance.Output):
+ yield item, "expr", SPECIAL_OUTPUT
+ elif isinstance(item, Instance.InOut):
+ yield item, "expr", SPECIAL_INOUT
+
+ @staticmethod
+ def emit_verilog(instance, ns, add_data_file):
+ r = instance.of + " "
+ parameters = list(filter(lambda i: isinstance(i, Instance.Parameter), instance.items))
+ if parameters:
+ r += "#(\n"
+ firstp = True
+ for p in parameters:
+ if not firstp:
+ r += ",\n"
+ firstp = False
+ r += "\t." + p.name + "("
+ if isinstance(p.value, Constant):
+ r += verilog_printexpr(ns, p.value)[0]
+ elif isinstance(p.value, float):
+ r += str(p.value)
+ elif isinstance(p.value, Instance.PreformattedParam):
+ r += p.value
+ elif isinstance(p.value, str):
+ r += "\"" + p.value + "\""
+ else:
+ raise TypeError
+ r += ")"
+ r += "\n) "
+ r += ns.get_name(instance)
+ if parameters: r += " "
+ r += "(\n"
+ firstp = True
+ for p in instance.items:
+ if isinstance(p, Instance._IO):
+ name_inst = p.name
+ name_design = verilog_printexpr(ns, p.expr)[0]
+ if not firstp:
+ r += ",\n"
+ firstp = False
+ r += "\t." + name_inst + "(" + name_design + ")"
+ if not firstp:
+ r += "\n"
+ if instance.synthesis_directive is not None:
+ synthesis_directive = "/* synthesis {} */".format(instance.synthesis_directive)
+ r += ")" + synthesis_directive + ";\n\n"
+ else:
+ r += ");\n\n"
+ return r
+
+
+(READ_FIRST, WRITE_FIRST, NO_CHANGE) = range(3)
+
+
+class _MemoryPort(Special):
+ def __init__(self, adr, dat_r, we=None, dat_w=None,
+ async_read=False, re=None, we_granularity=0, mode=WRITE_FIRST,
+ clock_domain="sys"):
+ Special.__init__(self)
+ self.adr = adr
+ self.dat_r = dat_r
+ self.we = we
+ self.dat_w = dat_w
+ self.async_read = async_read
+ self.re = re
+ self.we_granularity = we_granularity
+ self.mode = mode
+ self.clock = ClockSignal(clock_domain)
+
+ def iter_expressions(self):
+ for attr, target_context in [
+ ("adr", SPECIAL_INPUT),
+ ("we", SPECIAL_INPUT),
+ ("dat_w", SPECIAL_INPUT),
+ ("re", SPECIAL_INPUT),
+ ("dat_r", SPECIAL_OUTPUT),
+ ("clock", SPECIAL_INPUT)]:
+ yield self, attr, target_context
+
+ @staticmethod
+ def emit_verilog(port, ns, add_data_file):
+ return "" # done by parent Memory object
+
+
+class _MemoryLocation(_Value):
+ def __init__(self, memory, index):
+ _Value.__init__(self)
+ self.memory = memory
+ self.index = wrap(index)
+
+
+class Memory(Special):
+ def __init__(self, width, depth, init=None, name=None):
+ Special.__init__(self)
+ self.width = width
+ self.depth = depth
+ self.ports = []
+ self.init = init
+ self.name_override = get_obj_var_name(name, "mem")
+
+ def __getitem__(self, index):
+ # simulation only
+ return _MemoryLocation(self, index)
+
+ def get_port(self, write_capable=False, async_read=False,
+ has_re=False, we_granularity=0, mode=WRITE_FIRST,
+ clock_domain="sys"):
+ if we_granularity >= self.width:
+ we_granularity = 0
+ adr = Signal(max=self.depth)
+ dat_r = Signal(self.width)
+ if write_capable:
+ if we_granularity:
+ we = Signal(self.width//we_granularity)
+ else:
+ we = Signal()
+ dat_w = Signal(self.width)
+ else:
+ we = None
+ dat_w = None
+ if has_re:
+ re = Signal()
+ else:
+ re = None
+ mp = _MemoryPort(adr, dat_r, we, dat_w,
+ async_read, re, we_granularity, mode,
+ clock_domain)
+ self.ports.append(mp)
+ return mp
+
+ @staticmethod
+ def emit_verilog(memory, ns, add_data_file):
+ r = ""
+ def gn(e):
+ if isinstance(e, Memory):
+ return ns.get_name(e)
+ else:
+ return verilog_printexpr(ns, e)[0]
+ adrbits = bits_for(memory.depth-1)
+
+ r += "reg [" + str(memory.width-1) + ":0] " \
+ + gn(memory) \
+ + "[0:" + str(memory.depth-1) + "];\n"
+
+ adr_regs = {}
+ data_regs = {}
+ for port in memory.ports:
+ if not port.async_read:
+ if port.mode == WRITE_FIRST and port.we is not None:
+ adr_reg = Signal(name_override="memadr")
+ r += "reg [" + str(adrbits-1) + ":0] " \
+ + gn(adr_reg) + ";\n"
+ adr_regs[id(port)] = adr_reg
+ else:
+ data_reg = Signal(name_override="memdat")
+ r += "reg [" + str(memory.width-1) + ":0] " \
+ + gn(data_reg) + ";\n"
+ data_regs[id(port)] = data_reg
+
+ for port in memory.ports:
+ r += "always @(posedge " + gn(port.clock) + ") begin\n"
+ if port.we is not None:
+ if port.we_granularity:
+ n = memory.width//port.we_granularity
+ for i in range(n):
+ m = i*port.we_granularity
+ M = (i+1)*port.we_granularity-1
+ sl = "[" + str(M) + ":" + str(m) + "]"
+ r += "\tif (" + gn(port.we) + "[" + str(i) + "])\n"
+ r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "]" + sl + " <= " + gn(port.dat_w) + sl + ";\n"
+ else:
+ r += "\tif (" + gn(port.we) + ")\n"
+ r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "] <= " + gn(port.dat_w) + ";\n"
+ if not port.async_read:
+ if port.mode == WRITE_FIRST and port.we is not None:
+ rd = "\t" + gn(adr_regs[id(port)]) + " <= " + gn(port.adr) + ";\n"
+ else:
+ bassign = gn(data_regs[id(port)]) + " <= " + gn(memory) + "[" + gn(port.adr) + "];\n"
+ if port.mode == READ_FIRST or port.we is None:
+ rd = "\t" + bassign
+ elif port.mode == NO_CHANGE:
+ rd = "\tif (!" + gn(port.we) + ")\n" \
+ + "\t\t" + bassign
+ if port.re is None:
+ r += rd
+ else:
+ r += "\tif (" + gn(port.re) + ")\n"
+ r += "\t" + rd.replace("\n\t", "\n\t\t")
+ r += "end\n\n"
+
+ for port in memory.ports:
+ if port.async_read:
+ r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(port.adr) + "];\n"
+ else:
+ if port.mode == WRITE_FIRST and port.we is not None:
+ r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(adr_regs[id(port)]) + "];\n"
+ else:
+ r += "assign " + gn(port.dat_r) + " = " + gn(data_regs[id(port)]) + ";\n"
+ r += "\n"
+
+ if memory.init is not None:
+ content = ""
+ for d in memory.init:
+ content += "{:x}\n".format(d)
+ memory_filename = add_data_file(gn(memory) + ".init", content)
+
+ r += "initial begin\n"
+ r += "\t$readmemh(\"" + memory_filename + "\", " + gn(memory) + ");\n"
+ r += "end\n\n"
+
+ return r
+
+
+class SynthesisDirective(Special):
+ def __init__(self, template, **signals):
+ Special.__init__(self)
+ self.template = template
+ self.signals = signals
+
+ @staticmethod
+ def emit_verilog(directive, ns, add_data_file):
+ name_dict = dict((k, ns.get_name(sig)) for k, sig in directive.signals.items())
+ formatted = directive.template.format(**name_dict)
+ return "// synthesis " + formatted + "\n"
+
+
+class Keep(SynthesisDirective):
+ def __init__(self, signal):
+ SynthesisDirective.__init__(self, "attribute keep of {s} is true", s=signal)
--- /dev/null
+import builtins as _builtins
+import collections as _collections
+
+from litex.gen.fhdl import tracer as _tracer
+from litex.gen.util.misc import flat_iteration as _flat_iteration
+
+
+class DUID:
+ """Deterministic Unique IDentifier"""
+ __next_uid = 0
+ def __init__(self):
+ self.duid = DUID.__next_uid
+ DUID.__next_uid += 1
+
+
+class _Value(DUID):
+ """Base class for operands
+
+ Instances of `_Value` or its subclasses can be operands to
+ arithmetic, comparison, bitwise, and logic operators.
+ They can be assigned (:meth:`eq`) or indexed/sliced (using the usual
+ Python indexing and slicing notation).
+
+ Values created from integers have the minimum bit width to necessary to
+ represent the integer.
+ """
+ def __bool__(self):
+ # Special case: Constants and Signals are part of a set or used as
+ # dictionary keys, and Python needs to check for equality.
+ if isinstance(self, _Operator) and self.op == "==":
+ a, b = self.operands
+ if isinstance(a, Constant) and isinstance(b, Constant):
+ return a.value == b.value
+ if isinstance(a, Signal) and isinstance(b, Signal):
+ return a is b
+ if (isinstance(a, Constant) and isinstance(b, Signal)
+ or isinstance(a, Signal) and isinstance(a, Constant)):
+ return False
+ raise TypeError("Attempted to convert Migen value to boolean")
+
+ def __invert__(self):
+ return _Operator("~", [self])
+ def __neg__(self):
+ return _Operator("-", [self])
+
+ def __add__(self, other):
+ return _Operator("+", [self, other])
+ def __radd__(self, other):
+ return _Operator("+", [other, self])
+ def __sub__(self, other):
+ return _Operator("-", [self, other])
+ def __rsub__(self, other):
+ return _Operator("-", [other, self])
+ def __mul__(self, other):
+ return _Operator("*", [self, other])
+ def __rmul__(self, other):
+ return _Operator("*", [other, self])
+ def __lshift__(self, other):
+ return _Operator("<<<", [self, other])
+ def __rlshift__(self, other):
+ return _Operator("<<<", [other, self])
+ def __rshift__(self, other):
+ return _Operator(">>>", [self, other])
+ def __rrshift__(self, other):
+ return _Operator(">>>", [other, self])
+ def __and__(self, other):
+ return _Operator("&", [self, other])
+ def __rand__(self, other):
+ return _Operator("&", [other, self])
+ def __xor__(self, other):
+ return _Operator("^", [self, other])
+ def __rxor__(self, other):
+ return _Operator("^", [other, self])
+ def __or__(self, other):
+ return _Operator("|", [self, other])
+ def __ror__(self, other):
+ return _Operator("|", [other, self])
+
+ def __lt__(self, other):
+ return _Operator("<", [self, other])
+ def __le__(self, other):
+ return _Operator("<=", [self, other])
+ def __eq__(self, other):
+ return _Operator("==", [self, other])
+ def __ne__(self, other):
+ return _Operator("!=", [self, other])
+ def __gt__(self, other):
+ return _Operator(">", [self, other])
+ def __ge__(self, other):
+ return _Operator(">=", [self, other])
+
+ def __len__(self):
+ from litex.gen.fhdl.bitcontainer import value_bits_sign
+ return value_bits_sign(self)[0]
+
+ def __getitem__(self, key):
+ n = len(self)
+ if isinstance(key, int):
+ if key >= n:
+ raise IndexError
+ if key < 0:
+ key += n
+ return _Slice(self, key, key+1)
+ elif isinstance(key, slice):
+ start, stop, step = key.indices(n)
+ if step != 1:
+ return Cat(self[i] for i in range(start, stop, step))
+ return _Slice(self, start, stop)
+ else:
+ raise TypeError
+
+ def eq(self, r):
+ """Assignment
+
+ Parameters
+ ----------
+ r : _Value, in
+ Value to be assigned.
+
+ Returns
+ -------
+ _Assign
+ Assignment statement that can be used in combinatorial or
+ synchronous context.
+ """
+ return _Assign(self, r)
+
+ def __hash__(self):
+ raise TypeError("unhashable type: '{}'".format(type(self).__name__))
+
+
+def wrap(value):
+ """Ensures that the passed object is a Migen value. Booleans and integers
+ are automatically wrapped into ``Constant``."""
+ if isinstance(value, (bool, int)):
+ value = Constant(value)
+ if not isinstance(value, _Value):
+ raise TypeError("Object is not a Migen value")
+ return value
+
+
+class _Operator(_Value):
+ def __init__(self, op, operands):
+ _Value.__init__(self)
+ self.op = op
+ self.operands = [wrap(o) for o in operands]
+
+
+def Mux(sel, val1, val0):
+ """Multiplex between two values
+
+ Parameters
+ ----------
+ sel : _Value(1), in
+ Selector.
+ val1 : _Value(N), in
+ val0 : _Value(N), in
+ Input values.
+
+ Returns
+ -------
+ _Value(N), out
+ Output `_Value`. If `sel` is asserted, the Mux returns
+ `val1`, else `val0`.
+ """
+ return _Operator("m", [sel, val1, val0])
+
+
+class _Slice(_Value):
+ def __init__(self, value, start, stop):
+ _Value.__init__(self)
+ if not isinstance(start, int) or not isinstance(stop, int):
+ raise TypeError("Slice boundaries must be integers")
+ self.value = wrap(value)
+ self.start = start
+ self.stop = stop
+
+
+class Cat(_Value):
+ """Concatenate values
+
+ Form a compound `_Value` from several smaller ones by concatenation.
+ The first argument occupies the lower bits of the result.
+ The return value can be used on either side of an assignment, that
+ is, the concatenated value can be used as an argument on the RHS or
+ as a target on the LHS. If it is used on the LHS, it must solely
+ consist of `Signal` s, slices of `Signal` s, and other concatenations
+ meeting these properties. The bit length of the return value is the sum of
+ the bit lengths of the arguments::
+
+ len(Cat(args)) == sum(len(arg) for arg in args)
+
+ Parameters
+ ----------
+ *args : _Values or iterables of _Values, inout
+ `_Value` s to be concatenated.
+
+ Returns
+ -------
+ Cat, inout
+ Resulting `_Value` obtained by concatentation.
+ """
+ def __init__(self, *args):
+ _Value.__init__(self)
+ self.l = [wrap(v) for v in _flat_iteration(args)]
+
+
+class Replicate(_Value):
+ """Replicate a value
+
+ An input value is replicated (repeated) several times
+ to be used on the RHS of assignments::
+
+ len(Replicate(s, n)) == len(s)*n
+
+ Parameters
+ ----------
+ v : _Value, in
+ Input value to be replicated.
+ n : int
+ Number of replications.
+
+ Returns
+ -------
+ Replicate, out
+ Replicated value.
+ """
+ def __init__(self, v, n):
+ _Value.__init__(self)
+ if not isinstance(n, int) or n < 0:
+ raise TypeError("Replication count must be a positive integer")
+ self.v = wrap(v)
+ self.n = n
+
+
+class Constant(_Value):
+ """A constant, HDL-literal integer `_Value`
+
+ Parameters
+ ----------
+ value : int
+ bits_sign : int or tuple or None
+ Either an integer `bits` or a tuple `(bits, signed)`
+ specifying the number of bits in this `Constant` and whether it is
+ signed (can represent negative values). `bits_sign` defaults
+ to the minimum width and signedness of `value`.
+ """
+ def __init__(self, value, bits_sign=None):
+ from litex.gen.fhdl.bitcontainer import bits_for
+
+ _Value.__init__(self)
+
+ self.value = int(value)
+ if bits_sign is None:
+ bits_sign = bits_for(self.value), self.value < 0
+ elif isinstance(bits_sign, int):
+ bits_sign = bits_sign, self.value < 0
+ self.nbits, self.signed = bits_sign
+ if not isinstance(self.nbits, int) or self.nbits <= 0:
+ raise TypeError("Width must be a strictly positive integer")
+
+ def __hash__(self):
+ return self.value
+
+
+C = Constant # shorthand
+
+
+class Signal(_Value):
+ """A `_Value` that can change
+
+ The `Signal` object represents a value that is expected to change
+ in the circuit. It does exactly what Verilog's `wire` and
+ `reg` and VHDL's `signal` do.
+
+ A `Signal` can be indexed to access a subset of its bits. Negative
+ indices (`signal[-1]`) and the extended Python slicing notation
+ (`signal[start:stop:step]`) are supported.
+ The indices 0 and -1 are the least and most significant bits
+ respectively.
+
+ Parameters
+ ----------
+ bits_sign : int or tuple
+ Either an integer `bits` or a tuple `(bits, signed)`
+ specifying the number of bits in this `Signal` and whether it is
+ signed (can represent negative values). `signed` defaults to
+ `False`.
+ name : str or None
+ Name hint for this signal. If `None` (default) the name is
+ inferred from the variable name this `Signal` is assigned to.
+ Name collisions are automatically resolved by prepending
+ names of objects that contain this `Signal` and by
+ appending integer sequences.
+ variable : bool
+ Deprecated.
+ reset : int
+ Reset (synchronous) or default (combinatorial) value.
+ When this `Signal` is assigned to in synchronous context and the
+ corresponding clock domain is reset, the `Signal` assumes the
+ given value. When this `Signal` is unassigned in combinatorial
+ context (due to conditional assignments not being taken),
+ the `Signal` assumes its `reset` value. Defaults to 0.
+ name_override : str or None
+ Do not use the inferred name but the given one.
+ min : int or None
+ max : int or None
+ If `bits_sign` is `None`, the signal bit width and signedness are
+ determined by the integer range given by `min` (inclusive,
+ defaults to 0) and `max` (exclusive, defaults to 2).
+ related : Signal or None
+ """
+ def __init__(self, bits_sign=None, name=None, variable=False, reset=0, name_override=None, min=None, max=None, related=None):
+ from litex.gen.fhdl.bitcontainer import bits_for
+
+ _Value.__init__(self)
+
+ # determine number of bits and signedness
+ if bits_sign is None:
+ if min is None:
+ min = 0
+ if max is None:
+ max = 2
+ max -= 1 # make both bounds inclusive
+ assert(min < max)
+ self.signed = min < 0 or max < 0
+ self.nbits = _builtins.max(bits_for(min, self.signed), bits_for(max, self.signed))
+ else:
+ assert(min is None and max is None)
+ if isinstance(bits_sign, tuple):
+ self.nbits, self.signed = bits_sign
+ else:
+ self.nbits, self.signed = bits_sign, False
+ if not isinstance(self.nbits, int) or self.nbits <= 0:
+ raise ValueError("Signal width must be a strictly positive integer")
+
+ self.variable = variable # deprecated
+ self.reset = reset
+ self.name_override = name_override
+ self.backtrace = _tracer.trace_back(name)
+ self.related = related
+
+ def __setattr__(self, k, v):
+ if k == "reset":
+ v = wrap(v)
+ _Value.__setattr__(self, k, v)
+
+ def __repr__(self):
+ return "<Signal " + (self.backtrace[-1][0] or "anonymous") + " at " + hex(id(self)) + ">"
+
+ @classmethod
+ def like(cls, other, **kwargs):
+ """Create Signal based on another.
+
+ Parameters
+ ----------
+ other : _Value
+ Object to base this Signal on.
+
+ See `migen.fhdl.bitcontainer.value_bits_sign` for details.
+ """
+ from litex.gen.fhdl.bitcontainer import value_bits_sign
+ return cls(bits_sign=value_bits_sign(other), **kwargs)
+
+ def __hash__(self):
+ return self.duid
+
+
+class ClockSignal(_Value):
+ """Clock signal for a given clock domain
+
+ `ClockSignal` s for a given clock domain can be retrieved multiple
+ times. They all ultimately refer to the same signal.
+
+ Parameters
+ ----------
+ cd : str
+ Clock domain to obtain a clock signal for. Defaults to `"sys"`.
+ """
+ def __init__(self, cd="sys"):
+ _Value.__init__(self)
+ if not isinstance(cd, str):
+ raise TypeError("Argument of ClockSignal must be a string")
+ self.cd = cd
+
+
+class ResetSignal(_Value):
+ """Reset signal for a given clock domain
+
+ `ResetSignal` s for a given clock domain can be retrieved multiple
+ times. They all ultimately refer to the same signal.
+
+ Parameters
+ ----------
+ cd : str
+ Clock domain to obtain a reset signal for. Defaults to `"sys"`.
+ allow_reset_less : bool
+ If the clock domain is resetless, return 0 instead of reporting an
+ error.
+ """
+ def __init__(self, cd="sys", allow_reset_less=False):
+ _Value.__init__(self)
+ if not isinstance(cd, str):
+ raise TypeError("Argument of ResetSignal must be a string")
+ self.cd = cd
+ self.allow_reset_less = allow_reset_less
+
+
+# statements
+
+
+class _Statement:
+ pass
+
+
+class _Assign(_Statement):
+ def __init__(self, l, r):
+ self.l = wrap(l)
+ self.r = wrap(r)
+
+
+def _check_statement(s):
+ if isinstance(s, _collections.Iterable):
+ return all(_check_statement(ss) for ss in s)
+ else:
+ return isinstance(s, _Statement)
+
+
+class If(_Statement):
+ """Conditional execution of statements
+
+ Parameters
+ ----------
+ cond : _Value(1), in
+ Condition
+ *t : Statements
+ Statements to execute if `cond` is asserted.
+
+ Examples
+ --------
+ >>> a = Signal()
+ >>> b = Signal()
+ >>> c = Signal()
+ >>> d = Signal()
+ >>> If(a,
+ ... b.eq(1)
+ ... ).Elif(c,
+ ... b.eq(0)
+ ... ).Else(
+ ... b.eq(d)
+ ... )
+ """
+ def __init__(self, cond, *t):
+ if not _check_statement(t):
+ raise TypeError("Not all test body objects are Migen statements")
+ self.cond = wrap(cond)
+ self.t = list(t)
+ self.f = []
+
+ def Else(self, *f):
+ """Add an `else` conditional block
+
+ Parameters
+ ----------
+ *f : Statements
+ Statements to execute if all previous conditions fail.
+ """
+ if not _check_statement(f):
+ raise TypeError("Not all test body objects are Migen statements")
+ _insert_else(self, list(f))
+ return self
+
+ def Elif(self, cond, *t):
+ """Add an `else if` conditional block
+
+ Parameters
+ ----------
+ cond : _Value(1), in
+ Condition
+ *t : Statements
+ Statements to execute if previous conditions fail and `cond`
+ is asserted.
+ """
+ _insert_else(self, [If(cond, *t)])
+ return self
+
+
+def _insert_else(obj, clause):
+ o = obj
+ while o.f:
+ assert(len(o.f) == 1)
+ assert(isinstance(o.f[0], If))
+ o = o.f[0]
+ o.f = clause
+
+
+class Case(_Statement):
+ """Case/Switch statement
+
+ Parameters
+ ----------
+ test : _Value, in
+ Selector value used to decide which block to execute
+ cases : dict
+ Dictionary of cases. The keys are numeric constants to compare
+ with `test`. The values are statements to be executed the
+ corresponding key matches `test`. The dictionary may contain a
+ string key `"default"` to mark a fall-through case that is
+ executed if no other key matches.
+
+ Examples
+ --------
+ >>> a = Signal()
+ >>> b = Signal()
+ >>> Case(a, {
+ ... 0: b.eq(1),
+ ... 1: b.eq(0),
+ ... "default": b.eq(0),
+ ... })
+ """
+ def __init__(self, test, cases):
+ self.test = wrap(test)
+ self.cases = dict()
+ for k, v in cases.items():
+ if isinstance(k, (bool, int)):
+ k = Constant(k)
+ if (not isinstance(k, Constant)
+ and not (isinstance(k, str) and k == "default")):
+ raise TypeError("Case object is not a Migen constant")
+ if not isinstance(v, _collections.Iterable):
+ v = [v]
+ if not _check_statement(v):
+ raise TypeError("Not all objects for case {} "
+ "are Migen statements".format(k))
+ self.cases[k] = v
+
+ def makedefault(self, key=None):
+ """Mark a key as the default case
+
+ Deletes/substitutes any previously existing default case.
+
+ Parameters
+ ----------
+ key : int or None
+ Key to use as default case if no other key matches.
+ By default, the largest key is the default key.
+ """
+ if key is None:
+ for choice in self.cases.keys():
+ if key is None or choice.value > key.value:
+ key = choice
+ self.cases["default"] = self.cases[key]
+ del self.cases[key]
+ return self
+
+
+# arrays
+
+
+class _ArrayProxy(_Value):
+ def __init__(self, choices, key):
+ _Value.__init__(self)
+ self.choices = []
+ for c in choices:
+ if isinstance(c, (bool, int)):
+ c = Constant(c)
+ self.choices.append(c)
+ self.key = key
+
+ def __getattr__(self, attr):
+ return _ArrayProxy([getattr(choice, attr) for choice in self.choices],
+ self.key)
+
+ def __getitem__(self, key):
+ return _ArrayProxy([choice.__getitem__(key) for choice in self.choices],
+ self.key)
+
+
+class Array(list):
+ """Addressable multiplexer
+
+ An array is created from an iterable of values and indexed using the
+ usual Python simple indexing notation (no negative indices or
+ slices). It can be indexed by numeric constants, `_Value` s, or
+ `Signal` s.
+
+ The result of indexing the array is a proxy for the entry at the
+ given index that can be used on either RHS or LHS of assignments.
+
+ An array can be indexed multiple times.
+
+ Multidimensional arrays are supported by packing inner arrays into
+ outer arrays.
+
+ Parameters
+ ----------
+ values : iterable of ints, _Values, Signals
+ Entries of the array. Each entry can be a numeric constant, a
+ `Signal` or a `Record`.
+
+ Examples
+ --------
+ >>> a = Array(range(10))
+ >>> b = Signal(max=10)
+ >>> c = Signal(max=10)
+ >>> b.eq(a[9 - c])
+ """
+ def __getitem__(self, key):
+ if isinstance(key, Constant):
+ return list.__getitem__(self, key.value)
+ elif isinstance(key, _Value):
+ return _ArrayProxy(self, key)
+ else:
+ return list.__getitem__(self, key)
+
+
+class ClockDomain:
+ """Synchronous domain
+
+ Parameters
+ ----------
+ name : str or None
+ Domain name. If None (the default) the name is inferred from the
+ variable name this `ClockDomain` is assigned to (stripping any
+ `"cd_"` prefix).
+ reset_less : bool
+ The domain does not use a reset signal. Registers within this
+ domain are still all initialized to their reset state once, e.g.
+ through Verilog `"initial"` statements.
+
+ Attributes
+ ----------
+ clk : Signal, inout
+ The clock for this domain. Can be driven or used to drive other
+ signals (preferably in combinatorial context).
+ rst : Signal or None, inout
+ Reset signal for this domain. Can be driven or used to drive.
+ """
+ def __init__(self, name=None, reset_less=False):
+ self.name = _tracer.get_obj_var_name(name)
+ if self.name is None:
+ raise ValueError("Cannot extract clock domain name from code, need to specify.")
+ if self.name.startswith("cd_"):
+ self.name = self.name[3:]
+ if self.name[0].isdigit():
+ raise ValueError("Clock domain name cannot start with a number.")
+ self.clk = Signal(name_override=self.name + "_clk")
+ if reset_less:
+ self.rst = None
+ else:
+ self.rst = Signal(name_override=self.name + "_rst")
+
+ def rename(self, new_name):
+ """Rename the clock domain
+
+ Parameters
+ ----------
+ new_name : str
+ New name
+ """
+ self.name = new_name
+ self.clk.name_override = new_name + "_clk"
+ if self.rst is not None:
+ self.rst.name_override = new_name + "_rst"
+
+
+class _ClockDomainList(list):
+ def __getitem__(self, key):
+ if isinstance(key, str):
+ for cd in self:
+ if cd.name == key:
+ return cd
+ raise KeyError(key)
+ else:
+ return list.__getitem__(self, key)
+
+
+(SPECIAL_INPUT, SPECIAL_OUTPUT, SPECIAL_INOUT) = range(3)
+
+
+class _Fragment:
+ def __init__(self, comb=None, sync=None, specials=None, clock_domains=None):
+ if comb is None: comb = []
+ if sync is None: sync = dict()
+ if specials is None: specials = set()
+ if clock_domains is None: clock_domains = _ClockDomainList()
+
+ self.comb = comb
+ self.sync = sync
+ self.specials = specials
+ self.clock_domains = _ClockDomainList(clock_domains)
+
+ def __add__(self, other):
+ newsync = _collections.defaultdict(list)
+ for k, v in self.sync.items():
+ newsync[k] = v[:]
+ for k, v in other.sync.items():
+ newsync[k].extend(v)
+ return _Fragment(self.comb + other.comb, newsync,
+ self.specials | other.specials,
+ self.clock_domains + other.clock_domains)
+
+ def __iadd__(self, other):
+ newsync = _collections.defaultdict(list)
+ for k, v in self.sync.items():
+ newsync[k] = v[:]
+ for k, v in other.sync.items():
+ newsync[k].extend(v)
+ self.comb += other.comb
+ self.sync = newsync
+ self.specials |= other.specials
+ self.clock_domains += other.clock_domains
+ return self
--- /dev/null
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.structure import _Slice, _Assign
+from litex.gen.fhdl.visit import NodeVisitor, NodeTransformer
+from litex.gen.fhdl.bitcontainer import value_bits_sign
+from litex.gen.util.misc import flat_iteration
+
+
+class _SignalLister(NodeVisitor):
+ def __init__(self):
+ self.output_list = set()
+
+ def visit_Signal(self, node):
+ self.output_list.add(node)
+
+
+class _TargetLister(NodeVisitor):
+ def __init__(self):
+ self.output_list = set()
+ self.target_context = False
+
+ def visit_Signal(self, node):
+ if self.target_context:
+ self.output_list.add(node)
+
+ def visit_Assign(self, node):
+ self.target_context = True
+ self.visit(node.l)
+ self.target_context = False
+
+ def visit_ArrayProxy(self, node):
+ for choice in node.choices:
+ self.visit(choice)
+
+
+class _InputLister(NodeVisitor):
+ def __init__(self):
+ self.output_list = set()
+
+ def visit_Signal(self, node):
+ self.output_list.add(node)
+
+ def visit_Assign(self, node):
+ self.visit(node.r)
+
+
+def list_signals(node):
+ lister = _SignalLister()
+ lister.visit(node)
+ return lister.output_list
+
+
+def list_targets(node):
+ lister = _TargetLister()
+ lister.visit(node)
+ return lister.output_list
+
+
+def list_inputs(node):
+ lister = _InputLister()
+ lister.visit(node)
+ return lister.output_list
+
+
+def _resort_statements(ol):
+ return [statement for i, statement in
+ sorted(ol, key=lambda x: x[0])]
+
+
+def group_by_targets(sl):
+ groups = []
+ seen = set()
+ for order, stmt in enumerate(flat_iteration(sl)):
+ targets = set(list_targets(stmt))
+ group = [(order, stmt)]
+ disjoint = targets.isdisjoint(seen)
+ seen |= targets
+ if not disjoint:
+ groups, old_groups = [], groups
+ for old_targets, old_group in old_groups:
+ if targets.isdisjoint(old_targets):
+ groups.append((old_targets, old_group))
+ else:
+ targets |= old_targets
+ group += old_group
+ groups.append((targets, group))
+ return [(targets, _resort_statements(stmts))
+ for targets, stmts in groups]
+
+
+def list_special_ios(f, ins, outs, inouts):
+ r = set()
+ for special in f.specials:
+ r |= special.list_ios(ins, outs, inouts)
+ return r
+
+
+class _ClockDomainLister(NodeVisitor):
+ def __init__(self):
+ self.clock_domains = set()
+
+ def visit_ClockSignal(self, node):
+ self.clock_domains.add(node.cd)
+
+ def visit_ResetSignal(self, node):
+ self.clock_domains.add(node.cd)
+
+ def visit_clock_domains(self, node):
+ for clockname, statements in node.items():
+ self.clock_domains.add(clockname)
+ self.visit(statements)
+
+
+def list_clock_domains_expr(f):
+ cdl = _ClockDomainLister()
+ cdl.visit(f)
+ return cdl.clock_domains
+
+
+def list_clock_domains(f):
+ r = list_clock_domains_expr(f)
+ for special in f.specials:
+ r |= special.list_clock_domains()
+ for cd in f.clock_domains:
+ r.add(cd.name)
+ return r
+
+
+def is_variable(node):
+ if isinstance(node, Signal):
+ return node.variable
+ elif isinstance(node, _Slice):
+ return is_variable(node.value)
+ elif isinstance(node, Cat):
+ arevars = list(map(is_variable, node.l))
+ r = arevars[0]
+ for x in arevars:
+ if x != r:
+ raise TypeError
+ return r
+ else:
+ raise TypeError
+
+
+def generate_reset(rst, sl):
+ targets = list_targets(sl)
+ return [t.eq(t.reset) for t in sorted(targets, key=lambda x: x.duid)]
+
+
+def insert_reset(rst, sl):
+ return [If(rst, *generate_reset(rst, sl)).Else(*sl)]
+
+
+def insert_resets(f):
+ newsync = dict()
+ for k, v in f.sync.items():
+ if f.clock_domains[k].rst is not None:
+ newsync[k] = insert_reset(ResetSignal(k), v)
+ else:
+ newsync[k] = v
+ f.sync = newsync
+
+
+class _Lowerer(NodeTransformer):
+ def __init__(self):
+ self.target_context = False
+ self.extra_stmts = []
+ self.comb = []
+
+ def visit_Assign(self, node):
+ old_target_context, old_extra_stmts = self.target_context, self.extra_stmts
+ self.extra_stmts = []
+
+ self.target_context = True
+ lhs = self.visit(node.l)
+ self.target_context = False
+ rhs = self.visit(node.r)
+ r = _Assign(lhs, rhs)
+ if self.extra_stmts:
+ r = [r] + self.extra_stmts
+
+ self.target_context, self.extra_stmts = old_target_context, old_extra_stmts
+ return r
+
+
+# Basics are FHDL structure elements that back-ends are not required to support
+# but can be expressed in terms of other elements (lowered) before conversion.
+class _BasicLowerer(_Lowerer):
+ def __init__(self, clock_domains):
+ self.clock_domains = clock_domains
+ _Lowerer.__init__(self)
+
+ def visit_ArrayProxy(self, node):
+ # TODO: rewrite without variables
+ array_muxed = Signal(value_bits_sign(node), variable=True)
+ if self.target_context:
+ k = self.visit(node.key)
+ cases = {}
+ for n, choice in enumerate(node.choices):
+ cases[n] = [self.visit_Assign(_Assign(choice, array_muxed))]
+ self.extra_stmts.append(Case(k, cases).makedefault())
+ else:
+ cases = dict((n, _Assign(array_muxed, self.visit(choice)))
+ for n, choice in enumerate(node.choices))
+ self.comb.append(Case(self.visit(node.key), cases).makedefault())
+ return array_muxed
+
+ def visit_ClockSignal(self, node):
+ return self.clock_domains[node.cd].clk
+
+ def visit_ResetSignal(self, node):
+ rst = self.clock_domains[node.cd].rst
+ if rst is None:
+ if node.allow_reset_less:
+ return 0
+ else:
+ raise ValueError("Attempted to get reset signal of resetless"
+ " domain '{}'".format(node.cd))
+ else:
+ return rst
+
+
+class _ComplexSliceLowerer(_Lowerer):
+ def visit_Slice(self, node):
+ if not isinstance(node.value, Signal):
+ slice_proxy = Signal(value_bits_sign(node.value))
+ if self.target_context:
+ a = _Assign(node.value, slice_proxy)
+ else:
+ a = _Assign(slice_proxy, node.value)
+ self.comb.append(self.visit_Assign(a))
+ node = _Slice(slice_proxy, node.start, node.stop)
+ return NodeTransformer.visit_Slice(self, node)
+
+
+def _apply_lowerer(l, f):
+ f = l.visit(f)
+ f.comb += l.comb
+
+ for special in f.specials:
+ for obj, attr, direction in special.iter_expressions():
+ if direction != SPECIAL_INOUT:
+ # inouts are only supported by Migen when connected directly to top-level
+ # in this case, they are Signal and never need lowering
+ l.comb = []
+ l.target_context = direction != SPECIAL_INPUT
+ l.extra_stmts = []
+ expr = getattr(obj, attr)
+ expr = l.visit(expr)
+ setattr(obj, attr, expr)
+ f.comb += l.comb + l.extra_stmts
+
+ return f
+
+
+def lower_basics(f):
+ return _apply_lowerer(_BasicLowerer(f.clock_domains), f)
+
+
+def lower_complex_slices(f):
+ return _apply_lowerer(_ComplexSliceLowerer(), f)
+
+
+class _ClockDomainRenamer(NodeVisitor):
+ def __init__(self, old, new):
+ self.old = old
+ self.new = new
+
+ def visit_ClockSignal(self, node):
+ if node.cd == self.old:
+ node.cd = self.new
+
+ def visit_ResetSignal(self, node):
+ if node.cd == self.old:
+ node.cd = self.new
+
+
+def rename_clock_domain_expr(f, old, new):
+ cdr = _ClockDomainRenamer(old, new)
+ cdr.visit(f)
+
+
+def rename_clock_domain(f, old, new):
+ rename_clock_domain_expr(f, old, new)
+ if new != old:
+ if old in f.sync:
+ if new in f.sync:
+ f.sync[new].extend(f.sync[old])
+ else:
+ f.sync[new] = f.sync[old]
+ del f.sync[old]
+ for special in f.specials:
+ special.rename_clock_domain(old, new)
+ try:
+ cd = f.clock_domains[old]
+ except KeyError:
+ pass
+ else:
+ cd.rename(new)
--- /dev/null
+import inspect
+from opcode import opname
+from collections import defaultdict
+
+
+def get_var_name(frame):
+ code = frame.f_code
+ call_index = frame.f_lasti
+ call_opc = opname[code.co_code[call_index]]
+ if call_opc != "CALL_FUNCTION" and call_opc != "CALL_FUNCTION_VAR":
+ return None
+ index = call_index+3
+ while True:
+ opc = opname[code.co_code[index]]
+ if opc == "STORE_NAME" or opc == "STORE_ATTR":
+ name_index = int(code.co_code[index+1])
+ return code.co_names[name_index]
+ elif opc == "STORE_FAST":
+ name_index = int(code.co_code[index+1])
+ return code.co_varnames[name_index]
+ elif opc == "STORE_DEREF":
+ name_index = int(code.co_code[index+1])
+ return code.co_cellvars[name_index]
+ elif opc == "LOAD_GLOBAL" or opc == "LOAD_ATTR" or opc == "LOAD_FAST" or opc == "LOAD_DEREF":
+ index += 3
+ elif opc == "DUP_TOP":
+ index += 1
+ elif opc == "BUILD_LIST":
+ index += 3
+ else:
+ return None
+
+
+def remove_underscore(s):
+ if len(s) > 2 and s[0] == "_" and s[1] != "_":
+ s = s[1:]
+ return s
+
+
+def get_obj_var_name(override=None, default=None):
+ if override:
+ return override
+
+ frame = inspect.currentframe().f_back
+ # We can be called via derived classes. Go back the stack frames
+ # until we reach the first class that does not inherit from us.
+ ourclass = frame.f_locals["self"].__class__
+ while "self" in frame.f_locals and isinstance(frame.f_locals["self"], ourclass):
+ frame = frame.f_back
+
+ vn = get_var_name(frame)
+ if vn is None:
+ vn = default
+ else:
+ vn = remove_underscore(vn)
+ return vn
+
+name_to_idx = defaultdict(int)
+classname_to_objs = dict()
+
+
+def index_id(l, obj):
+ for n, e in enumerate(l):
+ if id(e) == id(obj):
+ return n
+ raise ValueError
+
+
+def trace_back(varname=None):
+ l = []
+ frame = inspect.currentframe().f_back.f_back
+ while frame is not None:
+ if varname is None:
+ varname = get_var_name(frame)
+ if varname is not None:
+ varname = remove_underscore(varname)
+ l.insert(0, (varname, name_to_idx[varname]))
+ name_to_idx[varname] += 1
+
+ try:
+ obj = frame.f_locals["self"]
+ except KeyError:
+ obj = None
+ if hasattr(obj, "__del__"):
+ obj = None
+
+ if obj is None:
+ if varname is not None:
+ coname = frame.f_code.co_name
+ if coname == "<module>":
+ modules = frame.f_globals["__name__"]
+ modules = modules.split(".")
+ coname = modules[len(modules)-1]
+ coname = remove_underscore(coname)
+ l.insert(0, (coname, name_to_idx[coname]))
+ name_to_idx[coname] += 1
+ else:
+ classname = obj.__class__.__name__.lower()
+ try:
+ objs = classname_to_objs[classname]
+ except KeyError:
+ classname_to_objs[classname] = [obj]
+ idx = 0
+ else:
+ try:
+ idx = index_id(objs, obj)
+ except ValueError:
+ idx = len(objs)
+ objs.append(obj)
+ classname = remove_underscore(classname)
+ l.insert(0, (classname, idx))
+
+ varname = None
+ frame = frame.f_back
+ return l
--- /dev/null
+from functools import partial
+from operator import itemgetter
+import collections
+
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.structure import _Operator, _Slice, _Assign, _Fragment
+from litex.gen.fhdl.tools import *
+from litex.gen.fhdl.bitcontainer import bits_for
+from litex.gen.fhdl.namer import build_namespace
+from litex.gen.fhdl.conv_output import ConvOutput
+
+
+_reserved_keywords = {
+ "always", "and", "assign", "automatic", "begin", "buf", "bufif0", "bufif1",
+ "case", "casex", "casez", "cell", "cmos", "config", "deassign", "default",
+ "defparam", "design", "disable", "edge", "else", "end", "endcase",
+ "endconfig", "endfunction", "endgenerate", "endmodule", "endprimitive",
+ "endspecify", "endtable", "endtask", "event", "for", "force", "forever",
+ "fork", "function", "generate", "genvar", "highz0", "highz1", "if",
+ "ifnone", "incdir", "include", "initial", "inout", "input",
+ "instance", "integer", "join", "large", "liblist", "library", "localparam",
+ "macromodule", "medium", "module", "nand", "negedge", "nmos", "nor",
+ "noshowcancelled", "not", "notif0", "notif1", "or", "output", "parameter",
+ "pmos", "posedge", "primitive", "pull0", "pull1" "pulldown",
+ "pullup", "pulsestyle_onevent", "pulsestyle_ondetect", "remos", "real",
+ "realtime", "reg", "release", "repeat", "rnmos", "rpmos", "rtran",
+ "rtranif0", "rtranif1", "scalared", "showcancelled", "signed", "small",
+ "specify", "specparam", "strong0", "strong1", "supply0", "supply1",
+ "table", "task", "time", "tran", "tranif0", "tranif1", "tri", "tri0",
+ "tri1", "triand", "trior", "trireg", "unsigned", "use", "vectored", "wait",
+ "wand", "weak0", "weak1", "while", "wire", "wor","xnor", "xor"
+}
+
+
+def _printsig(ns, s):
+ if s.signed:
+ n = "signed "
+ else:
+ n = ""
+ if len(s) > 1:
+ n += "[" + str(len(s)-1) + ":0] "
+ n += ns.get_name(s)
+ return n
+
+
+def _printconstant(node):
+ if node.signed:
+ return (str(node.nbits) + "'sd" + str(2**node.nbits + node.value),
+ True)
+ else:
+ return str(node.nbits) + "'d" + str(node.value), False
+
+
+def _printexpr(ns, node):
+ if isinstance(node, Constant):
+ return _printconstant(node)
+ elif isinstance(node, Signal):
+ return ns.get_name(node), node.signed
+ elif isinstance(node, _Operator):
+ arity = len(node.operands)
+ r1, s1 = _printexpr(ns, node.operands[0])
+ if arity == 1:
+ if node.op == "-":
+ if s1:
+ r = node.op + r1
+ else:
+ r = "-$signed({1'd0, " + r1 + "})"
+ s = True
+ else:
+ r = node.op + r1
+ s = s1
+ elif arity == 2:
+ r2, s2 = _printexpr(ns, node.operands[1])
+ if node.op not in ["<<<", ">>>"]:
+ if s2 and not s1:
+ r1 = "$signed({1'd0, " + r1 + "})"
+ if s1 and not s2:
+ r2 = "$signed({1'd0, " + r2 + "})"
+ r = r1 + " " + node.op + " " + r2
+ s = s1 or s2
+ elif arity == 3:
+ assert node.op == "m"
+ r2, s2 = _printexpr(ns, node.operands[1])
+ r3, s3 = _printexpr(ns, node.operands[2])
+ if s2 and not s3:
+ r3 = "$signed({1'd0, " + r3 + "})"
+ if s3 and not s2:
+ r2 = "$signed({1'd0, " + r2 + "})"
+ r = r1 + " ? " + r2 + " : " + r3
+ s = s2 or s3
+ else:
+ raise TypeError
+ return "(" + r + ")", s
+ elif isinstance(node, _Slice):
+ # Verilog does not like us slicing non-array signals...
+ if isinstance(node.value, Signal) \
+ and len(node.value) == 1 \
+ and node.start == 0 and node.stop == 1:
+ return _printexpr(ns, node.value)
+
+ if node.start + 1 == node.stop:
+ sr = "[" + str(node.start) + "]"
+ else:
+ sr = "[" + str(node.stop-1) + ":" + str(node.start) + "]"
+ r, s = _printexpr(ns, node.value)
+ return r + sr, s
+ elif isinstance(node, Cat):
+ l = [_printexpr(ns, v)[0] for v in reversed(node.l)]
+ return "{" + ", ".join(l) + "}", False
+ elif isinstance(node, Replicate):
+ return "{" + str(node.n) + "{" + _printexpr(ns, node.v)[0] + "}}", False
+ else:
+ raise TypeError("Expression of unrecognized type: '{}'".format(type(node).__name__))
+
+
+(_AT_BLOCKING, _AT_NONBLOCKING, _AT_SIGNAL) = range(3)
+
+
+def _printnode(ns, at, level, node):
+ if node is None:
+ return ""
+ elif isinstance(node, _Assign):
+ if at == _AT_BLOCKING:
+ assignment = " = "
+ elif at == _AT_NONBLOCKING:
+ assignment = " <= "
+ elif is_variable(node.l):
+ assignment = " = "
+ else:
+ assignment = " <= "
+ return "\t"*level + _printexpr(ns, node.l)[0] + assignment + _printexpr(ns, node.r)[0] + ";\n"
+ elif isinstance(node, collections.Iterable):
+ return "".join(list(map(partial(_printnode, ns, at, level), node)))
+ elif isinstance(node, If):
+ r = "\t"*level + "if (" + _printexpr(ns, node.cond)[0] + ") begin\n"
+ r += _printnode(ns, at, level + 1, node.t)
+ if node.f:
+ r += "\t"*level + "end else begin\n"
+ r += _printnode(ns, at, level + 1, node.f)
+ r += "\t"*level + "end\n"
+ return r
+ elif isinstance(node, Case):
+ if node.cases:
+ r = "\t"*level + "case (" + _printexpr(ns, node.test)[0] + ")\n"
+ css = [(k, v) for k, v in node.cases.items() if isinstance(k, Constant)]
+ css = sorted(css, key=lambda x: x[0].value)
+ for choice, statements in css:
+ r += "\t"*(level + 1) + _printexpr(ns, choice)[0] + ": begin\n"
+ r += _printnode(ns, at, level + 2, statements)
+ r += "\t"*(level + 1) + "end\n"
+ if "default" in node.cases:
+ r += "\t"*(level + 1) + "default: begin\n"
+ r += _printnode(ns, at, level + 2, node.cases["default"])
+ r += "\t"*(level + 1) + "end\n"
+ r += "\t"*level + "endcase\n"
+ return r
+ else:
+ return ""
+ else:
+ raise TypeError("Node of unrecognized type: "+str(type(node)))
+
+
+def _list_comb_wires(f):
+ r = set()
+ groups = group_by_targets(f.comb)
+ for g in groups:
+ if len(g[1]) == 1 and isinstance(g[1][0], _Assign):
+ r |= g[0]
+ return r
+
+
+def _printheader(f, ios, name, ns,
+ reg_initialization):
+ sigs = list_signals(f) | list_special_ios(f, True, True, True)
+ special_outs = list_special_ios(f, False, True, True)
+ inouts = list_special_ios(f, False, False, True)
+ targets = list_targets(f) | special_outs
+ wires = _list_comb_wires(f) | special_outs
+ r = "module " + name + "(\n"
+ firstp = True
+ for sig in sorted(ios, key=lambda x: x.duid):
+ if not firstp:
+ r += ",\n"
+ firstp = False
+ if sig in inouts:
+ r += "\tinout " + _printsig(ns, sig)
+ elif sig in targets:
+ if sig in wires:
+ r += "\toutput " + _printsig(ns, sig)
+ else:
+ r += "\toutput reg " + _printsig(ns, sig)
+ else:
+ r += "\tinput " + _printsig(ns, sig)
+ r += "\n);\n\n"
+ for sig in sorted(sigs - ios, key=lambda x: x.duid):
+ if sig in wires:
+ r += "wire " + _printsig(ns, sig) + ";\n"
+ else:
+ if reg_initialization:
+ r += "reg " + _printsig(ns, sig) + " = " + _printexpr(ns, sig.reset)[0] + ";\n"
+ else:
+ r += "reg " + _printsig(ns, sig) + ";\n"
+ r += "\n"
+ return r
+
+
+def _printcomb(f, ns,
+ display_run,
+ dummy_signal,
+ blocking_assign):
+ r = ""
+ if f.comb:
+ if dummy_signal:
+ # Generate a dummy event to get the simulator
+ # to run the combinatorial process once at the beginning.
+ syn_off = "// synthesis translate_off\n"
+ syn_on = "// synthesis translate_on\n"
+ dummy_s = Signal(name_override="dummy_s")
+ r += syn_off
+ r += "reg " + _printsig(ns, dummy_s) + ";\n"
+ r += "initial " + ns.get_name(dummy_s) + " <= 1'd0;\n"
+ r += syn_on
+
+ groups = group_by_targets(f.comb)
+
+ for n, g in enumerate(groups):
+ if len(g[1]) == 1 and isinstance(g[1][0], _Assign):
+ r += "assign " + _printnode(ns, _AT_BLOCKING, 0, g[1][0])
+ else:
+ if dummy_signal:
+ dummy_d = Signal(name_override="dummy_d")
+ r += "\n" + syn_off
+ r += "reg " + _printsig(ns, dummy_d) + ";\n"
+ r += syn_on
+
+ r += "always @(*) begin\n"
+ if display_run:
+ r += "\t$display(\"Running comb block #" + str(n) + "\");\n"
+ if blocking_assign:
+ for t in g[0]:
+ r += "\t" + ns.get_name(t) + " = " + _printexpr(ns, t.reset)[0] + ";\n"
+ r += _printnode(ns, _AT_BLOCKING, 1, g[1])
+ else:
+ for t in g[0]:
+ r += "\t" + ns.get_name(t) + " <= " + _printexpr(ns, t.reset)[0] + ";\n"
+ r += _printnode(ns, _AT_NONBLOCKING, 1, g[1])
+ if dummy_signal:
+ r += syn_off
+ r += "\t" + ns.get_name(dummy_d) + " <= " + ns.get_name(dummy_s) + ";\n"
+ r += syn_on
+ r += "end\n"
+ r += "\n"
+ return r
+
+
+def _printsync(f, ns):
+ r = ""
+ for k, v in sorted(f.sync.items(), key=itemgetter(0)):
+ r += "always @(posedge " + ns.get_name(f.clock_domains[k].clk) + ") begin\n"
+ r += _printnode(ns, _AT_SIGNAL, 1, v)
+ r += "end\n\n"
+ return r
+
+
+def _call_special_classmethod(overrides, obj, method, *args, **kwargs):
+ cl = obj.__class__
+ if cl in overrides:
+ cl = overrides[cl]
+ if hasattr(cl, method):
+ return getattr(cl, method)(obj, *args, **kwargs)
+ else:
+ return None
+
+
+def _lower_specials_step(overrides, specials):
+ f = _Fragment()
+ lowered_specials = set()
+ for special in sorted(specials, key=lambda x: x.duid):
+ impl = _call_special_classmethod(overrides, special, "lower")
+ if impl is not None:
+ f += impl.get_fragment()
+ lowered_specials.add(special)
+ return f, lowered_specials
+
+
+def _can_lower(overrides, specials):
+ for special in specials:
+ cl = special.__class__
+ if cl in overrides:
+ cl = overrides[cl]
+ if hasattr(cl, "lower"):
+ return True
+ return False
+
+
+def _lower_specials(overrides, specials):
+ f, lowered_specials = _lower_specials_step(overrides, specials)
+ while _can_lower(overrides, f.specials):
+ f2, lowered_specials2 = _lower_specials_step(overrides, f.specials)
+ f += f2
+ lowered_specials |= lowered_specials2
+ f.specials -= lowered_specials2
+ return f, lowered_specials
+
+
+def _printspecials(overrides, specials, ns, add_data_file):
+ r = ""
+ for special in sorted(specials, key=lambda x: x.duid):
+ pr = _call_special_classmethod(overrides, special, "emit_verilog", ns, add_data_file)
+ if pr is None:
+ raise NotImplementedError("Special " + str(special) + " failed to implement emit_verilog")
+ r += pr
+ return r
+
+
+def convert(f, ios=None, name="top",
+ special_overrides=dict(),
+ create_clock_domains=True,
+ display_run=False, asic_syntax=False):
+ r = ConvOutput()
+ if not isinstance(f, _Fragment):
+ f = f.get_fragment()
+ if ios is None:
+ ios = set()
+
+ for cd_name in sorted(list_clock_domains(f)):
+ try:
+ f.clock_domains[cd_name]
+ except KeyError:
+ if create_clock_domains:
+ cd = ClockDomain(cd_name)
+ f.clock_domains.append(cd)
+ ios |= {cd.clk, cd.rst}
+ else:
+ raise KeyError("Unresolved clock domain: '"+cd_name+"'")
+
+ f = lower_complex_slices(f)
+ insert_resets(f)
+ f = lower_basics(f)
+ fs, lowered_specials = _lower_specials(special_overrides, f.specials)
+ f += lower_basics(fs)
+
+ ns = build_namespace(list_signals(f) \
+ | list_special_ios(f, True, True, True) \
+ | ios, _reserved_keywords)
+ ns.clock_domains = f.clock_domains
+ r.ns = ns
+
+ src = "/* Machine-generated using LiteX */\n"
+ src += _printheader(f, ios, name, ns,
+ reg_initialization=not asic_syntax)
+ src += _printcomb(f, ns,
+ display_run=display_run,
+ dummy_signal=not asic_syntax,
+ blocking_assign=asic_syntax)
+ src += _printsync(f, ns)
+ src += _printspecials(special_overrides, f.specials - lowered_specials, ns, r.add_data_file)
+ src += "endmodule\n"
+ r.set_main_source(src)
+
+ return r
--- /dev/null
+from copy import copy
+
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.structure import (_Operator, _Slice, _Assign, _ArrayProxy,
+ _Fragment)
+
+
+class NodeVisitor:
+ def visit(self, node):
+ if isinstance(node, Constant):
+ self.visit_Constant(node)
+ elif isinstance(node, Signal):
+ self.visit_Signal(node)
+ elif isinstance(node, ClockSignal):
+ self.visit_ClockSignal(node)
+ elif isinstance(node, ResetSignal):
+ self.visit_ResetSignal(node)
+ elif isinstance(node, _Operator):
+ self.visit_Operator(node)
+ elif isinstance(node, _Slice):
+ self.visit_Slice(node)
+ elif isinstance(node, Cat):
+ self.visit_Cat(node)
+ elif isinstance(node, Replicate):
+ self.visit_Replicate(node)
+ elif isinstance(node, _Assign):
+ self.visit_Assign(node)
+ elif isinstance(node, If):
+ self.visit_If(node)
+ elif isinstance(node, Case):
+ self.visit_Case(node)
+ elif isinstance(node, _Fragment):
+ self.visit_Fragment(node)
+ elif isinstance(node, (list, tuple)):
+ self.visit_statements(node)
+ elif isinstance(node, dict):
+ self.visit_clock_domains(node)
+ elif isinstance(node, _ArrayProxy):
+ self.visit_ArrayProxy(node)
+ elif node is not None:
+ self.visit_unknown(node)
+
+ def visit_Constant(self, node):
+ pass
+
+ def visit_Signal(self, node):
+ pass
+
+ def visit_ClockSignal(self, node):
+ pass
+
+ def visit_ResetSignal(self, node):
+ pass
+
+ def visit_Operator(self, node):
+ for o in node.operands:
+ self.visit(o)
+
+ def visit_Slice(self, node):
+ self.visit(node.value)
+
+ def visit_Cat(self, node):
+ for e in node.l:
+ self.visit(e)
+
+ def visit_Replicate(self, node):
+ self.visit(node.v)
+
+ def visit_Assign(self, node):
+ self.visit(node.l)
+ self.visit(node.r)
+
+ def visit_If(self, node):
+ self.visit(node.cond)
+ self.visit(node.t)
+ self.visit(node.f)
+
+ def visit_Case(self, node):
+ self.visit(node.test)
+ for v, statements in node.cases.items():
+ self.visit(statements)
+
+ def visit_Fragment(self, node):
+ self.visit(node.comb)
+ self.visit(node.sync)
+
+ def visit_statements(self, node):
+ for statement in node:
+ self.visit(statement)
+
+ def visit_clock_domains(self, node):
+ for clockname, statements in node.items():
+ self.visit(statements)
+
+ def visit_ArrayProxy(self, node):
+ for choice in node.choices:
+ self.visit(choice)
+ self.visit(node.key)
+
+ def visit_unknown(self, node):
+ pass
+
+
+# Default methods always copy the node, except for:
+# - Signals, ClockSignals and ResetSignals
+# - Unknown objects
+# - All fragment fields except comb and sync
+# In those cases, the original node is returned unchanged.
+class NodeTransformer:
+ def visit(self, node):
+ if isinstance(node, Constant):
+ return self.visit_Constant(node)
+ elif isinstance(node, Signal):
+ return self.visit_Signal(node)
+ elif isinstance(node, ClockSignal):
+ return self.visit_ClockSignal(node)
+ elif isinstance(node, ResetSignal):
+ return self.visit_ResetSignal(node)
+ elif isinstance(node, _Operator):
+ return self.visit_Operator(node)
+ elif isinstance(node, _Slice):
+ return self.visit_Slice(node)
+ elif isinstance(node, Cat):
+ return self.visit_Cat(node)
+ elif isinstance(node, Replicate):
+ return self.visit_Replicate(node)
+ elif isinstance(node, _Assign):
+ return self.visit_Assign(node)
+ elif isinstance(node, If):
+ return self.visit_If(node)
+ elif isinstance(node, Case):
+ return self.visit_Case(node)
+ elif isinstance(node, _Fragment):
+ return self.visit_Fragment(node)
+ elif isinstance(node, (list, tuple)):
+ return self.visit_statements(node)
+ elif isinstance(node, dict):
+ return self.visit_clock_domains(node)
+ elif isinstance(node, _ArrayProxy):
+ return self.visit_ArrayProxy(node)
+ elif node is not None:
+ return self.visit_unknown(node)
+ else:
+ return None
+
+ def visit_Constant(self, node):
+ return node
+
+ def visit_Signal(self, node):
+ return node
+
+ def visit_ClockSignal(self, node):
+ return node
+
+ def visit_ResetSignal(self, node):
+ return node
+
+ def visit_Operator(self, node):
+ return _Operator(node.op, [self.visit(o) for o in node.operands])
+
+ def visit_Slice(self, node):
+ return _Slice(self.visit(node.value), node.start, node.stop)
+
+ def visit_Cat(self, node):
+ return Cat(*[self.visit(e) for e in node.l])
+
+ def visit_Replicate(self, node):
+ return Replicate(self.visit(node.v), node.n)
+
+ def visit_Assign(self, node):
+ return _Assign(self.visit(node.l), self.visit(node.r))
+
+ def visit_If(self, node):
+ r = If(self.visit(node.cond))
+ r.t = self.visit(node.t)
+ r.f = self.visit(node.f)
+ return r
+
+ def visit_Case(self, node):
+ cases = dict((v, self.visit(statements)) for v, statements in node.cases.items())
+ r = Case(self.visit(node.test), cases)
+ return r
+
+ def visit_Fragment(self, node):
+ r = copy(node)
+ r.comb = self.visit(node.comb)
+ r.sync = self.visit(node.sync)
+ return r
+
+ # NOTE: this will always return a list, even if node is a tuple
+ def visit_statements(self, node):
+ return [self.visit(statement) for statement in node]
+
+ def visit_clock_domains(self, node):
+ return dict((clockname, self.visit(statements)) for clockname, statements in node.items())
+
+ def visit_ArrayProxy(self, node):
+ return _ArrayProxy([self.visit(choice) for choice in node.choices],
+ self.visit(node.key))
+
+ def visit_unknown(self, node):
+ return node
--- /dev/null
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.module import Module
+from litex.gen.fhdl.specials import Special
+from litex.gen.fhdl.bitcontainer import value_bits_sign
+from litex.gen.genlib.misc import WaitTimer
+
+
+class NoRetiming(Special):
+ def __init__(self, reg):
+ Special.__init__(self)
+ self.reg = reg
+
+ # do nothing
+ @staticmethod
+ def lower(dr):
+ return Module()
+
+
+class MultiRegImpl(Module):
+ def __init__(self, i, o, odomain, n):
+ self.i = i
+ self.o = o
+ self.odomain = odomain
+
+ w, signed = value_bits_sign(self.i)
+ self.regs = [Signal((w, signed)) for i in range(n)]
+
+ ###
+
+ src = self.i
+ for reg in self.regs:
+ sd = getattr(self.sync, self.odomain)
+ sd += reg.eq(src)
+ src = reg
+ self.comb += self.o.eq(src)
+ self.specials += [NoRetiming(reg) for reg in self.regs]
+
+
+class MultiReg(Special):
+ def __init__(self, i, o, odomain="sys", n=2):
+ Special.__init__(self)
+ self.i = wrap(i)
+ self.o = wrap(o)
+ self.odomain = odomain
+ self.n = n
+
+ def iter_expressions(self):
+ yield self, "i", SPECIAL_INPUT
+ yield self, "o", SPECIAL_OUTPUT
+
+ def rename_clock_domain(self, old, new):
+ Special.rename_clock_domain(self, old, new)
+ if self.odomain == old:
+ self.odomain = new
+
+ def list_clock_domains(self):
+ r = Special.list_clock_domains(self)
+ r.add(self.odomain)
+ return r
+
+ @staticmethod
+ def lower(dr):
+ return MultiRegImpl(dr.i, dr.o, dr.odomain, dr.n)
+
+
+class PulseSynchronizer(Module):
+ def __init__(self, idomain, odomain):
+ self.i = Signal()
+ self.o = Signal()
+
+ ###
+
+ toggle_i = Signal()
+ toggle_o = Signal()
+ toggle_o_r = Signal()
+
+ sync_i = getattr(self.sync, idomain)
+ sync_o = getattr(self.sync, odomain)
+
+ sync_i += If(self.i, toggle_i.eq(~toggle_i))
+ self.specials += MultiReg(toggle_i, toggle_o, odomain)
+ sync_o += toggle_o_r.eq(toggle_o)
+ self.comb += self.o.eq(toggle_o ^ toggle_o_r)
+
+
+class BusSynchronizer(Module):
+ """Clock domain transfer of several bits at once.
+
+ Ensures that all the bits form a single word that was present
+ synchronously in the input clock domain (unlike direct use of
+ ``MultiReg``)."""
+ def __init__(self, width, idomain, odomain, timeout=128):
+ self.i = Signal(width)
+ self.o = Signal(width)
+
+ if width == 1:
+ self.specials += MultiReg(self.i, self.o, odomain)
+ else:
+ sync_i = getattr(self.sync, idomain)
+ sync_o = getattr(self.sync, odomain)
+
+ starter = Signal(reset=1)
+ sync_i += starter.eq(0)
+ self.submodules._ping = PulseSynchronizer(idomain, odomain)
+ self.submodules._pong = PulseSynchronizer(odomain, idomain)
+ self.submodules._timeout = WaitTimer(timeout)
+ self.comb += [
+ self._timeout.wait.eq(~self._ping.i),
+ self._ping.i.eq(starter | self._pong.o | self._timeout.done),
+ self._pong.i.eq(self._ping.i)
+ ]
+
+ ibuffer = Signal(width)
+ obuffer = Signal(width)
+ sync_i += If(self._pong.o, ibuffer.eq(self.i))
+ self.specials += MultiReg(ibuffer, obuffer, odomain)
+ sync_o += If(self._ping.o, self.o.eq(obuffer))
+
+
+class GrayCounter(Module):
+ def __init__(self, width):
+ self.ce = Signal()
+ self.q = Signal(width)
+ self.q_next = Signal(width)
+ self.q_binary = Signal(width)
+ self.q_next_binary = Signal(width)
+
+ ###
+
+ self.comb += [
+ If(self.ce,
+ self.q_next_binary.eq(self.q_binary + 1)
+ ).Else(
+ self.q_next_binary.eq(self.q_binary)
+ ),
+ self.q_next.eq(self.q_next_binary ^ self.q_next_binary[1:])
+ ]
+ self.sync += [
+ self.q_binary.eq(self.q_next_binary),
+ self.q.eq(self.q_next)
+ ]
--- /dev/null
+"""
+Encoders and decoders between binary and one-hot representation
+"""
+
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.module import Module
+
+
+class Encoder(Module):
+ """Encode one-hot to binary
+
+ If `n` is low, the `o` th bit in `i` is asserted, else none or
+ multiple bits are asserted.
+
+ Parameters
+ ----------
+ width : int
+ Bit width of the input
+
+ Attributes
+ ----------
+ i : Signal(width), in
+ One-hot input
+ o : Signal(max=width), out
+ Encoded binary
+ n : Signal(1), out
+ Invalid, either none or multiple input bits are asserted
+ """
+ def __init__(self, width):
+ self.i = Signal(width) # one-hot
+ self.o = Signal(max=max(2, width)) # binary
+ self.n = Signal() # invalid: none or multiple
+ act = dict((1<<j, self.o.eq(j)) for j in range(width))
+ act["default"] = self.n.eq(1)
+ self.comb += Case(self.i, act)
+
+
+class PriorityEncoder(Module):
+ """Priority encode requests to binary
+
+ If `n` is low, the `o` th bit in `i` is asserted and the bits below
+ `o` are unasserted, else `o == 0`. The LSB has priority.
+
+ Parameters
+ ----------
+ width : int
+ Bit width of the input
+
+ Attributes
+ ----------
+ i : Signal(width), in
+ Input requests
+ o : Signal(max=width), out
+ Encoded binary
+ n : Signal(1), out
+ Invalid, no input bits are asserted
+ """
+ def __init__(self, width):
+ self.i = Signal(width) # one-hot, lsb has priority
+ self.o = Signal(max=max(2, width)) # binary
+ self.n = Signal() # none
+ for j in range(width)[::-1]: # last has priority
+ self.comb += If(self.i[j], self.o.eq(j))
+ self.comb += self.n.eq(self.i == 0)
+
+
+class Decoder(Module):
+ """Decode binary to one-hot
+
+ If `n` is low, the `i` th bit in `o` is asserted, the others are
+ not, else `o == 0`.
+
+ Parameters
+ ----------
+ width : int
+ Bit width of the output
+
+ Attributes
+ ----------
+ i : Signal(max=width), in
+ Input binary
+ o : Signal(width), out
+ Decoded one-hot
+ n : Signal(1), in
+ Invalid, no output bits are to be asserted
+ """
+
+ def __init__(self, width):
+ self.i = Signal(max=max(2, width)) # binary
+ self.n = Signal() # none/invalid
+ self.o = Signal(width) # one-hot
+ act = dict((j, self.o.eq(1<<j)) for j in range(width))
+ self.comb += Case(self.i, act)
+ self.comb += If(self.n, self.o.eq(0))
+
+
+class PriorityDecoder(Decoder):
+ pass # same
--- /dev/null
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.module import Module
+
+
+class Divider(Module):
+ def __init__(self, w):
+ self.start_i = Signal()
+ self.dividend_i = Signal(w)
+ self.divisor_i = Signal(w)
+ self.ready_o = Signal()
+ self.quotient_o = Signal(w)
+ self.remainder_o = Signal(w)
+
+ ###
+
+ qr = Signal(2*w)
+ counter = Signal(max=w+1)
+ divisor_r = Signal(w)
+ diff = Signal(w+1)
+
+ self.comb += [
+ self.quotient_o.eq(qr[:w]),
+ self.remainder_o.eq(qr[w:]),
+ self.ready_o.eq(counter == 0),
+ diff.eq(qr[w-1:] - divisor_r)
+ ]
+ self.sync += [
+ If(self.start_i,
+ counter.eq(w),
+ qr.eq(self.dividend_i),
+ divisor_r.eq(self.divisor_i)
+ ).Elif(~self.ready_o,
+ If(diff[w],
+ qr.eq(Cat(0, qr[:2*w-1]))
+ ).Else(
+ qr.eq(Cat(1, qr[:w-1], diff[:w]))
+ ),
+ counter.eq(counter - 1)
+ )
+ ]
--- /dev/null
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.module import Module
+from litex.gen.fhdl.specials import Memory
+from litex.gen.fhdl.bitcontainer import log2_int
+from litex.gen.fhdl.decorators import ClockDomainsRenamer
+from litex.gen.genlib.cdc import NoRetiming, MultiReg, GrayCounter
+
+
+def _inc(signal, modulo):
+ if modulo == 2**len(signal):
+ return signal.eq(signal + 1)
+ else:
+ return If(signal == (modulo - 1),
+ signal.eq(0)
+ ).Else(
+ signal.eq(signal + 1)
+ )
+
+
+class _FIFOInterface:
+ """
+ Data written to the input interface (`din`, `we`, `writable`) is
+ buffered and can be read at the output interface (`dout`, `re`,
+ `readable`). The data entry written first to the input
+ also appears first on the output.
+
+ Parameters
+ ----------
+ width : int
+ Bit width for the data.
+ depth : int
+ Depth of the FIFO.
+
+ Attributes
+ ----------
+ din : in, width
+ Input data
+ writable : out
+ There is space in the FIFO and `we` can be asserted to load new data.
+ we : in
+ Write enable signal to latch `din` into the FIFO. Does nothing if
+ `writable` is not asserted.
+ dout : out, width
+ Output data. Only valid if `readable` is asserted.
+ readable : out
+ Output data `dout` valid, FIFO not empty.
+ re : in
+ Acknowledge `dout`. If asserted, the next entry will be
+ available on the next cycle (if `readable` is high then).
+ """
+ def __init__(self, width, depth):
+ self.we = Signal()
+ self.writable = Signal() # not full
+ self.re = Signal()
+ self.readable = Signal() # not empty
+
+ self.din = Signal(width)
+ self.dout = Signal(width)
+ self.width = width
+
+
+class SyncFIFO(Module, _FIFOInterface):
+ """Synchronous FIFO (first in, first out)
+
+ Read and write interfaces are accessed from the same clock domain.
+ If different clock domains are needed, use :class:`AsyncFIFO`.
+
+ {interface}
+ level : out
+ Number of unread entries.
+ replace : in
+ Replaces the last entry written into the FIFO with `din`. Does nothing
+ if that entry has already been read (i.e. the FIFO is empty).
+ Assert in conjunction with `we`.
+ """
+ __doc__ = __doc__.format(interface=_FIFOInterface.__doc__)
+
+ def __init__(self, width, depth, fwft=True):
+ _FIFOInterface.__init__(self, width, depth)
+
+ self.level = Signal(max=depth+1)
+ self.replace = Signal()
+
+ ###
+
+ produce = Signal(max=depth)
+ consume = Signal(max=depth)
+ storage = Memory(self.width, depth)
+ self.specials += storage
+
+ wrport = storage.get_port(write_capable=True)
+ self.specials += wrport
+ self.comb += [
+ If(self.replace,
+ wrport.adr.eq(produce-1)
+ ).Else(
+ wrport.adr.eq(produce)
+ ),
+ wrport.dat_w.eq(self.din),
+ wrport.we.eq(self.we & (self.writable | self.replace))
+ ]
+ self.sync += If(self.we & self.writable & ~self.replace,
+ _inc(produce, depth))
+
+ do_read = Signal()
+ self.comb += do_read.eq(self.readable & self.re)
+
+ rdport = storage.get_port(async_read=fwft, has_re=not fwft)
+ self.specials += rdport
+ self.comb += [
+ rdport.adr.eq(consume),
+ self.dout.eq(rdport.dat_r)
+ ]
+ if not fwft:
+ self.comb += rdport.re.eq(do_read)
+ self.sync += If(do_read, _inc(consume, depth))
+
+ self.sync += \
+ If(self.we & self.writable & ~self.replace,
+ If(~do_read, self.level.eq(self.level + 1))
+ ).Elif(do_read,
+ self.level.eq(self.level - 1)
+ )
+ self.comb += [
+ self.writable.eq(self.level != depth),
+ self.readable.eq(self.level != 0)
+ ]
+
+
+class SyncFIFOBuffered(Module, _FIFOInterface):
+ def __init__(self, width, depth):
+ _FIFOInterface.__init__(self, width, depth)
+ self.submodules.fifo = fifo = SyncFIFO(width, depth, False)
+
+ self.writable = fifo.writable
+ self.din = fifo.din
+ self.we = fifo.we
+ self.dout = fifo.dout
+ self.level = Signal(max=depth+2)
+
+ ###
+
+ self.comb += fifo.re.eq(fifo.readable & (~self.readable | self.re))
+ self.sync += \
+ If(fifo.re,
+ self.readable.eq(1),
+ ).Elif(self.re,
+ self.readable.eq(0),
+ )
+ self.comb += self.level.eq(fifo.level + self.readable)
+
+
+class AsyncFIFO(Module, _FIFOInterface):
+ """Asynchronous FIFO (first in, first out)
+
+ Read and write interfaces are accessed from different clock domains,
+ named `read` and `write`. Use `ClockDomainsRenamer` to rename to
+ other names.
+
+ {interface}
+ """
+ __doc__ = __doc__.format(interface=_FIFOInterface.__doc__)
+
+ def __init__(self, width, depth):
+ _FIFOInterface.__init__(self, width, depth)
+
+ ###
+
+ depth_bits = log2_int(depth, True)
+
+ produce = ClockDomainsRenamer("write")(GrayCounter(depth_bits+1))
+ consume = ClockDomainsRenamer("read")(GrayCounter(depth_bits+1))
+ self.submodules += produce, consume
+ self.comb += [
+ produce.ce.eq(self.writable & self.we),
+ consume.ce.eq(self.readable & self.re)
+ ]
+
+ produce_rdomain = Signal(depth_bits+1)
+ self.specials += [
+ NoRetiming(produce.q),
+ MultiReg(produce.q, produce_rdomain, "read")
+ ]
+ consume_wdomain = Signal(depth_bits+1)
+ self.specials += [
+ NoRetiming(consume.q),
+ MultiReg(consume.q, consume_wdomain, "write")
+ ]
+ if depth_bits == 1:
+ self.comb += self.writable.eq((produce.q[-1] == consume_wdomain[-1])
+ | (produce.q[-2] == consume_wdomain[-2]))
+ else:
+ self.comb += [
+ self.writable.eq((produce.q[-1] == consume_wdomain[-1])
+ | (produce.q[-2] == consume_wdomain[-2])
+ | (produce.q[:-2] != consume_wdomain[:-2]))
+ ]
+ self.comb += self.readable.eq(consume.q != produce_rdomain)
+
+ storage = Memory(self.width, depth)
+ self.specials += storage
+ wrport = storage.get_port(write_capable=True, clock_domain="write")
+ self.specials += wrport
+ self.comb += [
+ wrport.adr.eq(produce.q_binary[:-1]),
+ wrport.dat_w.eq(self.din),
+ wrport.we.eq(produce.ce)
+ ]
+ rdport = storage.get_port(clock_domain="read")
+ self.specials += rdport
+ self.comb += [
+ rdport.adr.eq(consume.q_next_binary[:-1]),
+ self.dout.eq(rdport.dat_r)
+ ]
--- /dev/null
+from collections import OrderedDict
+
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.structure import _Statement, _Slice, _ArrayProxy
+from litex.gen.fhdl.module import Module, FinalizeError
+from litex.gen.fhdl.visit import NodeTransformer
+from litex.gen.fhdl.bitcontainer import value_bits_sign
+
+
+__all__ = ["AnonymousState", "NextState", "NextValue", "FSM"]
+
+
+class AnonymousState:
+ pass
+
+
+# do not use namedtuple here as it inherits tuple
+# and the latter is used elsewhere in FHDL
+class NextState(_Statement):
+ def __init__(self, state):
+ self.state = state
+
+
+class NextValue(_Statement):
+ def __init__(self, target, value):
+ self.target = target
+ self.value = value
+
+
+def _target_eq(a, b):
+ if type(a) != type(b):
+ return False
+ ty = type(a)
+ if ty == Constant:
+ return a.value == b.value
+ elif ty == Signal:
+ return a is b
+ elif ty == Cat:
+ return all(_target_eq(x, y) for x, y in zip(a.l, b.l))
+ elif ty == _Slice:
+ return (_target_eq(a.value, b.value)
+ and a.start == b.start
+ and a.end == b.end)
+ elif ty == _ArrayProxy:
+ return (all(_target_eq(x, y) for x, y in zip(a.choices, b.choices))
+ and _target_eq(a.key, b.key))
+ else:
+ raise ValueError("NextValue cannot be used with target type '{}'"
+ .format(ty))
+
+
+class _LowerNext(NodeTransformer):
+ def __init__(self, next_state_signal, encoding, aliases):
+ self.next_state_signal = next_state_signal
+ self.encoding = encoding
+ self.aliases = aliases
+ # (target, next_value_ce, next_value)
+ self.registers = []
+
+ def _get_register_control(self, target):
+ for x in self.registers:
+ if _target_eq(target, x[0]):
+ return x[1], x[2]
+ raise KeyError
+
+ def visit_unknown(self, node):
+ if isinstance(node, NextState):
+ try:
+ actual_state = self.aliases[node.state]
+ except KeyError:
+ actual_state = node.state
+ return self.next_state_signal.eq(self.encoding[actual_state])
+ elif isinstance(node, NextValue):
+ try:
+ next_value_ce, next_value = self._get_register_control(node.target)
+ except KeyError:
+ related = node.target if isinstance(node.target, Signal) else None
+ next_value = Signal(bits_sign=value_bits_sign(node.target), related=related)
+ next_value_ce = Signal(related=related)
+ self.registers.append((node.target, next_value_ce, next_value))
+ return next_value.eq(node.value), next_value_ce.eq(1)
+ else:
+ return node
+
+
+class FSM(Module):
+ def __init__(self, reset_state=None):
+ self.actions = OrderedDict()
+ self.state_aliases = dict()
+ self.reset_state = reset_state
+
+ self.before_entering_signals = OrderedDict()
+ self.before_leaving_signals = OrderedDict()
+ self.after_entering_signals = OrderedDict()
+ self.after_leaving_signals = OrderedDict()
+
+ def act(self, state, *statements):
+ if self.finalized:
+ raise FinalizeError
+ if self.reset_state is None:
+ self.reset_state = state
+ if state not in self.actions:
+ self.actions[state] = []
+ self.actions[state] += statements
+
+ def delayed_enter(self, name, target, delay):
+ if self.finalized:
+ raise FinalizeError
+ if delay > 0:
+ state = name
+ for i in range(delay):
+ if i == delay - 1:
+ next_state = target
+ else:
+ next_state = AnonymousState()
+ self.act(state, NextState(next_state))
+ state = next_state
+ else:
+ self.state_aliases[name] = target
+
+ def ongoing(self, state):
+ is_ongoing = Signal()
+ self.act(state, is_ongoing.eq(1))
+ return is_ongoing
+
+ def _get_signal(self, d, state):
+ if state not in self.actions:
+ self.actions[state] = []
+ try:
+ return d[state]
+ except KeyError:
+ is_el = Signal()
+ d[state] = is_el
+ return is_el
+
+ def before_entering(self, state):
+ return self._get_signal(self.before_entering_signals, state)
+
+ def before_leaving(self, state):
+ return self._get_signal(self.before_leaving_signals, state)
+
+ def after_entering(self, state):
+ signal = self._get_signal(self.after_entering_signals, state)
+ self.sync += signal.eq(self.before_entering(state))
+ return signal
+
+ def after_leaving(self, state):
+ signal = self._get_signal(self.after_leaving_signals, state)
+ self.sync += signal.eq(self.before_leaving(state))
+ return signal
+
+ def do_finalize(self):
+ nstates = len(self.actions)
+ self.encoding = dict((s, n) for n, s in enumerate(self.actions.keys()))
+ self.state = Signal(max=nstates, reset=self.encoding[self.reset_state])
+ self.next_state = Signal(max=nstates)
+
+ ln = _LowerNext(self.next_state, self.encoding, self.state_aliases)
+ cases = dict((self.encoding[k], ln.visit(v)) for k, v in self.actions.items() if v)
+ self.comb += [
+ self.next_state.eq(self.state),
+ Case(self.state, cases).makedefault(self.encoding[self.reset_state])
+ ]
+ self.sync += self.state.eq(self.next_state)
+ for register, next_value_ce, next_value in ln.registers:
+ self.sync += If(next_value_ce, register.eq(next_value))
+
+ # drive entering/leaving signals
+ for state, signal in self.before_leaving_signals.items():
+ encoded = self.encoding[state]
+ self.comb += signal.eq((self.state == encoded) & ~(self.next_state == encoded))
+ if self.reset_state in self.after_entering_signals:
+ self.after_entering_signals[self.reset_state].reset = 1
+ for state, signal in self.before_entering_signals.items():
+ encoded = self.encoding[state]
+ self.comb += signal.eq(~(self.state == encoded) & (self.next_state == encoded))
--- /dev/null
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.module import Module
+from litex.gen.fhdl.specials import Special
+
+
+class DifferentialInput(Special):
+ def __init__(self, i_p, i_n, o):
+ Special.__init__(self)
+ self.i_p = wrap(i_p)
+ self.i_n = wrap(i_n)
+ self.o = wrap(o)
+
+ def iter_expressions(self):
+ yield self, "i_p", SPECIAL_INPUT
+ yield self, "i_n", SPECIAL_INPUT
+ yield self, "o", SPECIAL_OUTPUT
+
+ @staticmethod
+ def lower(dr):
+ raise NotImplementedError("Attempted to use a differential input, but platform does not support them")
+
+
+class DifferentialOutput(Special):
+ def __init__(self, i, o_p, o_n):
+ Special.__init__(self)
+ self.i = wrap(i)
+ self.o_p = wrap(o_p)
+ self.o_n = wrap(o_n)
+
+ def iter_expressions(self):
+ yield self, "i", SPECIAL_INPUT
+ yield self, "o_p", SPECIAL_OUTPUT
+ yield self, "o_n", SPECIAL_OUTPUT
+
+ @staticmethod
+ def lower(dr):
+ raise NotImplementedError("Attempted to use a differential output, but platform does not support them")
+
+
+class CRG(Module):
+ def __init__(self, clk, rst=0):
+ self.clock_domains.cd_sys = ClockDomain()
+ self.clock_domains.cd_por = ClockDomain(reset_less=True)
+
+ if hasattr(clk, "p"):
+ clk_se = Signal()
+ self.specials += DifferentialInput(clk.p, clk.n, clk_se)
+ clk = clk_se
+
+ # Power on Reset (vendor agnostic)
+ int_rst = Signal(reset=1)
+ self.sync.por += int_rst.eq(rst)
+ self.comb += [
+ self.cd_sys.clk.eq(clk),
+ self.cd_por.clk.eq(clk),
+ self.cd_sys.rst.eq(int_rst)
+ ]
+
+
+class DDRInput(Special):
+ def __init__(self, i, o1, o2, clk=ClockSignal()):
+ Special.__init__(self)
+ self.i = wrap(i)
+ self.o1 = wrap(o1)
+ self.o2 = wrap(o2)
+ self.clk = wrap(clk)
+
+ def iter_expressions(self):
+ yield self, "i", SPECIAL_INPUT
+ yield self, "o1", SPECIAL_OUTPUT
+ yield self, "o2", SPECIAL_OUTPUT
+ yield self, "clk", SPECIAL_INPUT
+
+ @staticmethod
+ def lower(dr):
+ raise NotImplementedError("Attempted to use a DDR input, but platform does not support them")
+
+
+class DDROutput(Special):
+ def __init__(self, i1, i2, o, clk=ClockSignal()):
+ Special.__init__(self)
+ self.i1 = i1
+ self.i2 = i2
+ self.o = o
+ self.clk = clk
+
+ def iter_expressions(self):
+ yield self, "i1", SPECIAL_INPUT
+ yield self, "i2", SPECIAL_INPUT
+ yield self, "o", SPECIAL_OUTPUT
+ yield self, "clk", SPECIAL_INPUT
+
+ @staticmethod
+ def lower(dr):
+ raise NotImplementedError("Attempted to use a DDR output, but platform does not support them")
+
--- /dev/null
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.module import Module
+from litex.gen.fhdl.bitcontainer import bits_for
+
+
+def split(v, *counts):
+ r = []
+ offset = 0
+ for n in counts:
+ if n != 0:
+ r.append(v[offset:offset+n])
+ else:
+ r.append(None)
+ offset += n
+ return tuple(r)
+
+
+def displacer(signal, shift, output, n=None, reverse=False):
+ if shift is None:
+ return output.eq(signal)
+ if n is None:
+ n = 2**len(shift)
+ w = len(signal)
+ if reverse:
+ r = reversed(range(n))
+ else:
+ r = range(n)
+ l = [Replicate(shift == i, w) & signal for i in r]
+ return output.eq(Cat(*l))
+
+
+def chooser(signal, shift, output, n=None, reverse=False):
+ if shift is None:
+ return output.eq(signal)
+ if n is None:
+ n = 2**len(shift)
+ w = len(output)
+ cases = {}
+ for i in range(n):
+ if reverse:
+ s = n - i - 1
+ else:
+ s = i
+ cases[i] = [output.eq(signal[s*w:(s+1)*w])]
+ return Case(shift, cases).makedefault()
+
+
+def timeline(trigger, events):
+ lastevent = max([e[0] for e in events])
+ counter = Signal(max=lastevent+1)
+
+ counterlogic = If(counter != 0,
+ counter.eq(counter + 1)
+ ).Elif(trigger,
+ counter.eq(1)
+ )
+ # insert counter reset if it doesn't naturally overflow
+ # (test if lastevent+1 is a power of 2)
+ if (lastevent & (lastevent + 1)) != 0:
+ counterlogic = If(counter == lastevent,
+ counter.eq(0)
+ ).Else(
+ counterlogic
+ )
+
+ def get_cond(e):
+ if e[0] == 0:
+ return trigger & (counter == 0)
+ else:
+ return counter == e[0]
+ sync = [If(get_cond(e), *e[1]) for e in events]
+ sync.append(counterlogic)
+ return sync
+
+
+class WaitTimer(Module):
+ def __init__(self, t):
+ self.wait = Signal()
+ self.done = Signal()
+
+ # # #
+
+ count = Signal(bits_for(t), reset=t)
+ self.comb += self.done.eq(count == 0)
+ self.sync += \
+ If(self.wait,
+ If(~self.done, count.eq(count - 1))
+ ).Else(count.eq(count.reset))
--- /dev/null
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.tracer import get_obj_var_name
+
+from functools import reduce
+from operator import or_
+
+
+(DIR_NONE, DIR_S_TO_M, DIR_M_TO_S) = range(3)
+
+# Possible layout elements:
+# 1. (name, size)
+# 2. (name, size, direction)
+# 3. (name, sublayout)
+# size can be an int, or a (int, bool) tuple for signed numbers
+# sublayout must be a list
+
+
+def set_layout_parameters(layout, **layout_dict):
+ def resolve(p):
+ if isinstance(p, str):
+ try:
+ return layout_dict[p]
+ except KeyError:
+ return p
+ else:
+ return p
+
+ r = []
+ for f in layout:
+ if isinstance(f[1], (int, tuple, str)): # cases 1/2
+ if len(f) == 3:
+ r.append((f[0], resolve(f[1]), f[2]))
+ else:
+ r.append((f[0], resolve(f[1])))
+ elif isinstance(f[1], list): # case 3
+ r.append((f[0], set_layout_parameters(f[1], **layout_dict)))
+ else:
+ raise TypeError
+ return r
+
+
+def layout_len(layout):
+ r = 0
+ for f in layout:
+ if isinstance(f[1], (int, tuple)): # cases 1/2
+ if len(f) == 3:
+ fname, fsize, fdirection = f
+ else:
+ fname, fsize = f
+ elif isinstance(f[1], list): # case 3
+ fname, fsublayout = f
+ fsize = layout_len(fsublayout)
+ else:
+ raise TypeError
+ if isinstance(fsize, tuple):
+ r += fsize[0]
+ else:
+ r += fsize
+ return r
+
+
+def layout_get(layout, name):
+ for f in layout:
+ if f[0] == name:
+ return f
+ raise KeyError(name)
+
+
+def layout_partial(layout, *elements):
+ r = []
+ for path in elements:
+ path_s = path.split("/")
+ last = path_s.pop()
+ copy_ref = layout
+ insert_ref = r
+ for hop in path_s:
+ name, copy_ref = layout_get(copy_ref, hop)
+ try:
+ name, insert_ref = layout_get(insert_ref, hop)
+ except KeyError:
+ new_insert_ref = []
+ insert_ref.append((hop, new_insert_ref))
+ insert_ref = new_insert_ref
+ insert_ref.append(layout_get(copy_ref, last))
+ return r
+
+
+class Record:
+ def __init__(self, layout, name=None):
+ self.name = get_obj_var_name(name, "")
+ self.layout = layout
+
+ if self.name:
+ prefix = self.name + "_"
+ else:
+ prefix = ""
+ for f in self.layout:
+ if isinstance(f[1], (int, tuple)): # cases 1/2
+ if(len(f) == 3):
+ fname, fsize, fdirection = f
+ else:
+ fname, fsize = f
+ finst = Signal(fsize, name=prefix + fname)
+ elif isinstance(f[1], list): # case 3
+ fname, fsublayout = f
+ finst = Record(fsublayout, prefix + fname)
+ else:
+ raise TypeError
+ setattr(self, fname, finst)
+
+ def eq(self, other):
+ return [getattr(self, f[0]).eq(getattr(other, f[0]))
+ for f in self.layout if hasattr(other, f[0])]
+
+ def iter_flat(self):
+ for f in self.layout:
+ e = getattr(self, f[0])
+ if isinstance(e, Signal):
+ if len(f) == 3:
+ yield e, f[2]
+ else:
+ yield e, DIR_NONE
+ elif isinstance(e, Record):
+ yield from e.iter_flat()
+ else:
+ raise TypeError
+
+ def flatten(self):
+ return [signal for signal, direction in self.iter_flat()]
+
+ def raw_bits(self):
+ return Cat(*self.flatten())
+
+ def connect(self, *slaves, leave_out=set()):
+ if isinstance(leave_out, str):
+ leave_out = {leave_out}
+ r = []
+ for f in self.layout:
+ field = f[0]
+ if field not in leave_out:
+ self_e = getattr(self, field)
+ if isinstance(self_e, Signal):
+ direction = f[2]
+ if direction == DIR_M_TO_S:
+ r += [getattr(slave, field).eq(self_e) for slave in slaves]
+ elif direction == DIR_S_TO_M:
+ r.append(self_e.eq(reduce(or_, [getattr(slave, field) for slave in slaves])))
+ else:
+ raise TypeError
+ else:
+ for slave in slaves:
+ r += self_e.connect(getattr(slave, field), leave_out=leave_out)
+ return r
+
+ def connect_flat(self, *slaves):
+ r = []
+ iter_slaves = [slave.iter_flat() for slave in slaves]
+ for m_signal, m_direction in self.iter_flat():
+ if m_direction == DIR_M_TO_S:
+ for iter_slave in iter_slaves:
+ s_signal, s_direction = next(iter_slave)
+ assert(s_direction == DIR_M_TO_S)
+ r.append(s_signal.eq(m_signal))
+ elif m_direction == DIR_S_TO_M:
+ s_signals = []
+ for iter_slave in iter_slaves:
+ s_signal, s_direction = next(iter_slave)
+ assert(s_direction == DIR_S_TO_M)
+ s_signals.append(s_signal)
+ r.append(m_signal.eq(reduce(or_, s_signals)))
+ else:
+ raise TypeError
+ return r
+
+ def __len__(self):
+ return layout_len(self.layout)
+
+ def __repr__(self):
+ return "<Record " + ":".join(f[0] for f in self.layout) + " at " + hex(id(self)) + ">"
--- /dev/null
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.specials import Special
+
+
+class AsyncResetSynchronizer(Special):
+ def __init__(self, cd, async_reset):
+ Special.__init__(self)
+ self.cd = cd
+ self.async_reset = wrap(async_reset)
+
+ def iter_expressions(self):
+ yield self.cd, "clk", SPECIAL_INPUT
+ yield self.cd, "rst", SPECIAL_OUTPUT
+ yield self, "async_reset", SPECIAL_INPUT
+
+ @staticmethod
+ def lower(dr):
+ raise NotImplementedError("Attempted to use a reset synchronizer, but platform does not support them")
--- /dev/null
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.module import Module
+
+
+(SP_WITHDRAW, SP_CE) = range(2)
+
+
+class RoundRobin(Module):
+ def __init__(self, n, switch_policy=SP_WITHDRAW):
+ self.request = Signal(n)
+ self.grant = Signal(max=max(2, n))
+ self.switch_policy = switch_policy
+ if self.switch_policy == SP_CE:
+ self.ce = Signal()
+
+ ###
+
+ if n > 1:
+ cases = {}
+ for i in range(n):
+ switch = []
+ for j in reversed(range(i+1, i+n)):
+ t = j % n
+ switch = [
+ If(self.request[t],
+ self.grant.eq(t)
+ ).Else(
+ *switch
+ )
+ ]
+ if self.switch_policy == SP_WITHDRAW:
+ case = [If(~self.request[i], *switch)]
+ else:
+ case = switch
+ cases[i] = case
+ statement = Case(self.grant, cases)
+ if self.switch_policy == SP_CE:
+ statement = If(self.ce, statement)
+ self.sync += statement
+ else:
+ self.comb += self.grant.eq(0)
--- /dev/null
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.module import Module
+
+
+class BitonicSort(Module):
+ """Combinatorial sorting network
+
+ The Bitonic sort is implemented as a combinatorial sort using
+ comparators and multiplexers. Its asymptotic complexity (in terms of
+ number of comparators/muxes) is O(n log(n)**2), like mergesort or
+ shellsort.
+
+ http://www.dps.uibk.ac.at/~cosenza/teaching/gpu/sort-batcher.pdf
+
+ http://www.inf.fh-flensburg.de/lang/algorithmen/sortieren/bitonic/bitonicen.htm
+
+ http://www.myhdl.org/doku.php/cookbook:bitonic
+
+ Parameters
+ ----------
+ n : int
+ Number of inputs and output signals.
+ m : int
+ Bit width of inputs and outputs. Or a tuple of `(m, signed)`.
+ ascending : bool
+ Sort direction. `True` if input is to be sorted ascending,
+ `False` for descending. Defaults to ascending.
+
+ Attributes
+ ----------
+ i : list of Signals, in
+ Input values, each `m` wide.
+ o : list of Signals, out
+ Output values, sorted, each `m` bits wide.
+ """
+ def __init__(self, n, m, ascending=True):
+ self.i = [Signal(m) for i in range(n)]
+ self.o = [Signal(m) for i in range(n)]
+ self._sort(self.i, self.o, int(ascending), m)
+
+ def _sort_two(self, i0, i1, o0, o1, dir):
+ self.comb += [
+ o0.eq(i0),
+ o1.eq(i1),
+ If(dir == (i0 > i1),
+ o0.eq(i1),
+ o1.eq(i0),
+ )]
+
+ def _merge(self, i, o, dir, m):
+ n = len(i)
+ k = n//2
+ if n > 1:
+ t = [Signal(m) for j in range(n)]
+ for j in range(k):
+ self._sort_two(i[j], i[j + k], t[j], t[j + k], dir)
+ self._merge(t[:k], o[:k], dir, m)
+ self._merge(t[k:], o[k:], dir, m)
+ else:
+ self.comb += o[0].eq(i[0])
+
+ def _sort(self, i, o, dir, m):
+ n = len(i)
+ k = n//2
+ if n > 1:
+ t = [Signal(m) for j in range(n)]
+ self._sort(i[:k], t[:k], 1, m) # ascending
+ self._sort(i[k:], t[k:], 0, m) # descending
+ self._merge(t, o, dir, m)
+ else:
+ self.comb += o[0].eq(i[0])
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import *
-from migen.fhdl.specials import *
-from migen.fhdl.bitcontainer import *
-from migen.fhdl.decorators import *
-
-from migen.sim import *
-
-from migen.genlib.record import *
-from migen.genlib.fsm import *
+++ /dev/null
-from migen.build.altera.platform import AlteraPlatform
-from migen.build.altera.programmer import USBBlaster
+++ /dev/null
-from migen.fhdl.module import Module
-from migen.fhdl.specials import Instance
-from migen.genlib.io import DifferentialInput, DifferentialOutput
-
-
-class AlteraDifferentialInputImpl(Module):
- def __init__(self, i_p, i_n, o):
- self.specials += Instance("ALT_INBUF_DIFF",
- name="ibuf_diff",
- i_i=i_p,
- i_ibar=i_n,
- o_o=o)
-
-
-class AlteraDifferentialInput:
- @staticmethod
- def lower(dr):
- return AlteraDifferentialInputImpl(dr.i_p, dr.i_n, dr.o)
-
-
-class AlteraDifferentialOutputImpl(Module):
- def __init__(self, i, o_p, o_n):
- self.specials += Instance("ALT_OUTBUF_DIFF",
- name="obuf_diff",
- i_i=i,
- o_o=o_p,
- o_obar=o_n)
-
-
-class AlteraDifferentialOutput:
- @staticmethod
- def lower(dr):
- return AlteraDifferentialOutputImpl(dr.i, dr.o_p, dr.o_n)
-
-
-altera_special_overrides = {
- DifferentialInput: AlteraDifferentialInput,
- DifferentialOutput: AlteraDifferentialOutput
-}
+++ /dev/null
-from migen.build.generic_platform import GenericPlatform
-from migen.build.altera import common, quartus
-
-
-class AlteraPlatform(GenericPlatform):
- bitstream_ext = ".sof"
-
- def __init__(self, *args, toolchain="quartus", **kwargs):
- GenericPlatform.__init__(self, *args, **kwargs)
- if toolchain == "quartus":
- self.toolchain = quartus.AlteraQuartusToolchain()
- else:
- raise ValueError("Unknown toolchain")
-
- def get_verilog(self, *args, special_overrides=dict(), **kwargs):
- so = dict(common.altera_special_overrides)
- so.update(special_overrides)
- return GenericPlatform.get_verilog(self, *args, special_overrides=so,
- **kwargs)
-
- def build(self, *args, **kwargs):
- return self.toolchain.build(self, *args, **kwargs)
-
- def add_period_constraint(self, clk, period):
- if hasattr(clk, "p"):
- clk = clk.p
- self.toolchain.add_period_constraint(self, clk, period)
+++ /dev/null
-import subprocess
-
-from migen.build.generic_programmer import GenericProgrammer
-
-
-class USBBlaster(GenericProgrammer):
- needs_bitreverse = False
-
- def load_bitstream(self, bitstream_file, port=0):
- usb_port = "[USB-{}]".format(port)
- subprocess.call(["quartus_pgm", "-m", "jtag", "-c",
- "USB-Blaster{}".format(usb_port), "-o",
- "p;{}".format(bitstream_file)])
+++ /dev/null
-# This file is Copyright (c) 2013 Florent Kermarrec <florent@enjoy-digital.fr>
-# License: BSD
-
-import os
-import subprocess
-
-from migen.fhdl.structure import _Fragment
-
-from migen.build.generic_platform import Pins, IOStandard, Misc
-from migen.build import tools
-
-
-def _format_constraint(c, signame, fmt_r):
- if isinstance(c, Pins):
- return "set_location_assignment -comment \"{name}\" " \
- "-to {signame} Pin_{pin}".format(
- signame=signame,
- name=fmt_r,
- pin=c.identifiers[0])
- elif isinstance(c, IOStandard):
- return "set_instance_assignment -name io_standard " \
- "-comment \"{name}\" \"{std}\" -to {signame}".format(
- signame=signame,
- name=fmt_r,
- std=c.name)
- elif isinstance(c, Misc):
- if not isinstance(c.misc, str) and len(c.misc) == 2:
- return "set_instance_assignment -comment \"{name}\" " \
- "-name {misc[0]} \"{misc[1]}\" -to {signame}".format(
- signame=signame,
- name=fmt_r,
- misc=c.misc)
- else:
- return "set_instance_assignment -comment \"{name}\" " \
- "-name {misc} " \
- "-to {signame}".format(
- signame=signame,
- name=fmt_r,
- misc=c.misc)
-
-
-def _format_qsf(signame, pin, others, resname):
- fmt_r = "{}:{}".format(*resname[:2])
- if resname[2] is not None:
- fmt_r += "." + resname[2]
-
- fmt_c = [_format_constraint(c, signame, fmt_r) for c in
- ([Pins(pin)] + others)]
-
- return '\n'.join(fmt_c)
-
-
-def _build_qsf(named_sc, named_pc):
- lines = []
- for sig, pins, others, resname in named_sc:
- if len(pins) > 1:
- for i, p in enumerate(pins):
- lines.append(
- _format_qsf("{}[{}]".format(sig, i), p, others, resname))
- else:
- lines.append(_format_qsf(sig, pins[0], others, resname))
-
- if named_pc:
- lines.append("")
- lines.append("\n\n".join(named_pc))
-
- lines.append("set_global_assignment -name top_level_entity top")
- return "\n".join(lines)
-
-
-def _build_files(device, sources, vincpaths, named_sc, named_pc, build_name):
- lines = []
- for filename, language, library in sources:
- # Enforce use of SystemVerilog
- # (Quartus does not support global parameters in Verilog)
- if language == "verilog":
- language = "systemverilog"
- lines.append(
- "set_global_assignment -name {lang}_FILE {path} "
- "-library {lib}".format(
- lang=language.upper(),
- path=filename.replace("\\", "/"),
- lib=library))
-
- for path in vincpaths:
- lines.append("set_global_assignment -name SEARCH_PATH {}".format(
- path.replace("\\", "/")))
-
- lines.append(_build_qsf(named_sc, named_pc))
- lines.append("set_global_assignment -name DEVICE {}".format(device))
- tools.write_to_file("{}.qsf".format(build_name), "\n".join(lines))
-
-
-def _run_quartus(build_name, quartus_path):
- build_script_contents = """# Autogenerated by Migen
-
-set -e
-
-quartus_map --read_settings_files=on --write_settings_files=off {build_name} -c {build_name}
-quartus_fit --read_settings_files=off --write_settings_files=off {build_name} -c {build_name}
-quartus_asm --read_settings_files=off --write_settings_files=off {build_name} -c {build_name}
-quartus_sta {build_name} -c {build_name}
-
-""".format(build_name=build_name) # noqa
- build_script_file = "build_" + build_name + ".sh"
- tools.write_to_file(build_script_file,
- build_script_contents,
- force_unix=True)
-
- if subprocess.call(["bash", build_script_file]):
- raise OSError("Subprocess failed")
-
-
-class AlteraQuartusToolchain:
- def build(self, platform, fragment, build_dir="build", build_name="top",
- toolchain_path="/opt/Altera", run=True):
- tools.mkdir_noerror(build_dir)
- os.chdir(build_dir)
-
- if not isinstance(fragment, _Fragment):
- fragment = fragment.get_fragment()
- platform.finalize(fragment)
-
- v_output = platform.get_verilog(fragment)
- named_sc, named_pc = platform.resolve_signals(v_output.ns)
- v_file = build_name + ".v"
- v_output.write(v_file)
- sources = platform.sources | {(v_file, "verilog", "work")}
- _build_files(platform.device,
- sources,
- platform.verilog_include_paths,
- named_sc,
- named_pc,
- build_name)
- if run:
- _run_quartus(build_name, toolchain_path)
-
- os.chdir("..")
-
- return v_output.ns
-
- def add_period_constraint(self, platform, clk, period):
- # TODO: handle differential clk
- platform.add_platform_command(
- "set_global_assignment -name duty_cycle 50 -section_id {clk}",
- clk=clk)
- platform.add_platform_command(
- "set_global_assignment -name fmax_requirement \"{freq} MHz\" "
- "-section_id {clk}".format(freq=(1. / period) * 1000,
- clk="{clk}"),
- clk=clk)
+++ /dev/null
-import os
-
-from migen.build.generic_programmer import GenericProgrammer
-from migen.build.xilinx.programmer import _create_xsvf
-
-try:
- import fl
-except ImportError:
- import fpgalink3 as fl
-
-fl.flInitialise(0)
-
-
-class FPGALink(GenericProgrammer):
- """Using the fpgalink library from makestuff
-
- You will need fpgalink library installed from
- https://github.com/makestuff/libfpgalink
- """
-
- needs_bitreverse = False
-
- def __init__(self, initial_vidpid=None, pin_cfg="D0D2D3D4",
- fpgalink_vidpid="1D50:602B:0002", flash_proxy_basename=None):
- """
- Parameters
- ----------
- initial_vidpid : string
- The USB vendor and product id of the device before fpgalink
- firmware is loaded onto the device.
-
- Format is vid:pid as 4 digit hex numbers.
-
- pin_cfg : string
- FPGALink pin configuration string describing how the JTAG interface
- is hooked up to the programmer.
-
- fpgalink_vidpid : string
- The USB vendor, product and device id of the device after the
- fpgalink firmware is loaded onto the device.
-
- Format is vid:pid:did as 4 digit hex numbers.
- Defaults to 1D50:602B:0002 which is the makestuff FPGALink device.
- """
- GenericProgrammer.__init__(self, flash_proxy_basename)
- self.initial_vidpid = initial_vidpid
- self.fpgalink_vidpid = fpgalink_vidpid
- self.pin_cfg = pin_cfg
-
- def open_device(self):
- ivp = self.initial_vidpid
- vp = self.fpgalink_vidpid
-
- print("Attempting to open connection to FPGALink device", vp, "...")
- try:
- handle = fl.flOpen(self.fpgalink_vidpid)
- except fl.FLException as ex:
- if not ivp:
- raise FLException(
- "Could not open FPGALink device at {0} and"
- " no initial VID:PID was supplied".format(vp))
-
- print("Loading firmware into %s..." % ivp)
- fl.flLoadStandardFirmware(ivp, vp)
-
- print("Awaiting renumeration...")
- if not fl.flAwaitDevice(vp, 600):
- raise fl.FLException(
- "FPGALink device did not renumerate properly"
- " as {0}".format(vp))
-
- print("Attempting to open connection to FPGALink device", vp,
- "again...")
- handle = fl.flOpen(vp)
-
- # Only Nero capable hardware support doing programming.
- assert fl.flIsNeroCapable(handle)
- print("Cable connection opened.")
- return handle
-
- def load_bitstream(self, bitstream_file):
- n = 27
-
- xsvf_file = os.path.splitext(bitstream_file)[0]+'.xsvf'
- print("\nGenerating xsvf formatted bitstream")
- print("="*n)
- if os.path.exists(xsvf_file):
- os.unlink(xsvf_file)
- _create_xsvf(bitstream_file, xsvf_file)
- print("\n"+"="*n+"\n")
-
- print("Programming %s to device." % xsvf_file)
- print("="*n)
- handle = self.open_device()
- print("Programming device...")
- fl.flProgram(handle, "J:"+self.pin_cfg, progFile=xsvf_file)
- print("Programming successful!")
- print("="*n+"\n")
- fl.flClose(handle)
-
- def flash(self, address, data_file):
- raise NotImplementedError("Not supported yet.")
+++ /dev/null
-import os
-
-from migen.fhdl.structure import Signal
-from migen.genlib.record import Record
-from migen.genlib.io import CRG
-from migen.fhdl import verilog, edif
-from migen.build import tools
-
-
-class ConstraintError(Exception):
- pass
-
-
-class Pins:
- def __init__(self, *identifiers):
- self.identifiers = []
- for i in identifiers:
- self.identifiers += i.split()
-
- def __repr__(self):
- return "{}('{}')".format(self.__class__.__name__,
- " ".join(self.identifiers))
-
-
-class IOStandard:
- def __init__(self, name):
- self.name = name
-
- def __repr__(self):
- return "{}('{}')".format(self.__class__.__name__, self.name)
-
-
-class Drive:
- def __init__(self, strength):
- self.strength = strength
-
- def __repr__(self):
- return "{}('{}')".format(self.__class__.__name__, self.strength)
-
-
-class Misc:
- def __init__(self, misc):
- self.misc = misc
-
- def __repr__(self):
- return "{}({})".format(self.__class__.__name__, repr(self.misc))
-
-
-class Subsignal:
- def __init__(self, name, *constraints):
- self.name = name
- self.constraints = list(constraints)
-
- def __repr__(self):
- return "{}('{}', {})".format(
- self.__class__.__name__,
- self.name,
- ", ".join([repr(constr) for constr in self.constraints]))
-
-
-class PlatformInfo:
- def __init__(self, info):
- self.info = info
-
- def __repr__(self):
- return "{}({})".format(self.__class__.__name__, repr(self.info))
-
-
-def _lookup(description, name, number):
- for resource in description:
- if resource[0] == name and (number is None or resource[1] == number):
- return resource
- raise ConstraintError("Resource not found: {}:{}".format(name, number))
-
-
-def _resource_type(resource):
- t = None
- for element in resource[2:]:
- if isinstance(element, Pins):
- assert(t is None)
- t = len(element.identifiers)
- elif isinstance(element, Subsignal):
- if t is None:
- t = []
-
- assert(isinstance(t, list))
- n_bits = None
- for c in element.constraints:
- if isinstance(c, Pins):
- assert(n_bits is None)
- n_bits = len(c.identifiers)
-
- t.append((element.name, n_bits))
-
- return t
-
-
-class ConnectorManager:
- def __init__(self, connectors):
- self.connector_table = dict()
- for connector in connectors:
- cit = iter(connector)
- conn_name = next(cit)
- if isinstance(connector[1], str):
- pin_list = []
- for pins in cit:
- pin_list += pins.split()
- pin_list = [None if pin == "None" else pin for pin in pin_list]
- elif isinstance(connector[1], dict):
- pin_list = connector[1]
- else:
- raise ValueError("Unsupported pin list type {} for connector"
- " {}".format(type(connector[1]), conn_name))
- if conn_name in self.connector_table:
- raise ValueError(
- "Connector specified more than once: {}".format(conn_name))
-
- self.connector_table[conn_name] = pin_list
-
- def resolve_identifiers(self, identifiers):
- r = []
- for identifier in identifiers:
- if ":" in identifier:
- conn, pn = identifier.split(":")
- if pn.isdigit():
- pn = int(pn)
-
- r.append(self.connector_table[conn][pn])
- else:
- r.append(identifier)
-
- return r
-
-
-def _separate_pins(constraints):
- pins = None
- others = []
- for c in constraints:
- if isinstance(c, Pins):
- assert(pins is None)
- pins = c.identifiers
- else:
- others.append(c)
-
- return pins, others
-
-
-class ConstraintManager:
- def __init__(self, io, connectors):
- self.available = list(io)
- self.matched = []
- self.platform_commands = []
- self.connector_manager = ConnectorManager(connectors)
-
- def add_extension(self, io):
- self.available.extend(io)
-
- def request(self, name, number=None):
- resource = _lookup(self.available, name, number)
- rt = _resource_type(resource)
- if isinstance(rt, int):
- obj = Signal(rt, name_override=resource[0])
- else:
- obj = Record(rt, name=resource[0])
-
- for element in resource[2:]:
- if isinstance(element, PlatformInfo):
- obj.platform_info = element.info
- break
-
- self.available.remove(resource)
- self.matched.append((resource, obj))
- return obj
-
- def lookup_request(self, name, number=None):
- for resource, obj in self.matched:
- if resource[0] == name and (number is None or
- resource[1] == number):
- return obj
-
- raise ConstraintError("Resource not found: {}:{}".format(name, number))
-
- def add_platform_command(self, command, **signals):
- self.platform_commands.append((command, signals))
-
- def get_io_signals(self):
- r = set()
- for resource, obj in self.matched:
- if isinstance(obj, Signal):
- r.add(obj)
- else:
- r.update(obj.flatten())
-
- return r
-
- def get_sig_constraints(self):
- r = []
- for resource, obj in self.matched:
- name = resource[0]
- number = resource[1]
- has_subsignals = False
- top_constraints = []
- for element in resource[2:]:
- if isinstance(element, Subsignal):
- has_subsignals = True
- else:
- top_constraints.append(element)
-
- if has_subsignals:
- for element in resource[2:]:
- if isinstance(element, Subsignal):
- sig = getattr(obj, element.name)
- pins, others = _separate_pins(top_constraints +
- element.constraints)
- pins = self.connector_manager.resolve_identifiers(pins)
- r.append((sig, pins, others,
- (name, number, element.name)))
- else:
- pins, others = _separate_pins(top_constraints)
- pins = self.connector_manager.resolve_identifiers(pins)
- r.append((obj, pins, others, (name, number, None)))
-
- return r
-
- def get_platform_commands(self):
- return self.platform_commands
-
-
-class GenericPlatform:
- def __init__(self, device, io, connectors=[], name=None):
- self.device = device
- self.constraint_manager = ConstraintManager(io, connectors)
- if name is None:
- name = self.__module__.split(".")[-1]
- self.name = name
- self.sources = set()
- self.verilog_include_paths = set()
- self.finalized = False
-
- def request(self, *args, **kwargs):
- return self.constraint_manager.request(*args, **kwargs)
-
- def lookup_request(self, *args, **kwargs):
- return self.constraint_manager.lookup_request(*args, **kwargs)
-
- def add_period_constraint(self, clk, period):
- raise NotImplementedError
-
- def add_platform_command(self, *args, **kwargs):
- return self.constraint_manager.add_platform_command(*args, **kwargs)
-
- def add_extension(self, *args, **kwargs):
- return self.constraint_manager.add_extension(*args, **kwargs)
-
- def finalize(self, fragment, *args, **kwargs):
- if self.finalized:
- raise ConstraintError("Already finalized")
- # if none exists, create a default clock domain and drive it
- if not fragment.clock_domains:
- if not hasattr(self, "default_clk_name"):
- raise NotImplementedError(
- "No default clock and no clock domain defined")
- crg = CRG(self.request(self.default_clk_name))
- fragment += crg.get_fragment()
-
- self.do_finalize(fragment, *args, **kwargs)
- self.finalized = True
-
- def do_finalize(self, fragment, *args, **kwargs):
- """overload this and e.g. add_platform_command()'s after the modules
- had their say"""
- if hasattr(self, "default_clk_period"):
- try:
- self.add_period_constraint(
- self.lookup_request(self.default_clk_name),
- self.default_clk_period)
- except ConstraintError:
- pass
-
- def add_source(self, filename, language=None, library=None):
- if language is None:
- language = tools.language_by_filename(filename)
- if language is None:
- language = "verilog"
-
- if library is None:
- library = "work"
-
- self.sources.add((os.path.abspath(filename), language, library))
-
- def add_sources(self, path, *filenames, language=None, library=None):
- for f in filenames:
- self.add_source(os.path.join(path, f), language, library)
-
- def add_source_dir(self, path, recursive=True, library=None):
- dir_files = []
- if recursive:
- for root, dirs, files in os.walk(path):
- for filename in files:
- dir_files.append(os.path.join(root, filename))
- else:
- for item in os.listdir(path):
- if os.path.isfile(os.path.join(path, item)):
- dir_files.append(os.path.join(path, item))
- for filename in dir_files:
- language = tools.language_by_filename(filename)
- if language is not None:
- self.add_source(filename, language, library)
-
- def add_verilog_include_path(self, path):
- self.verilog_include_paths.add(os.path.abspath(path))
-
- def resolve_signals(self, vns):
- # resolve signal names in constraints
- sc = self.constraint_manager.get_sig_constraints()
- named_sc = [(vns.get_name(sig), pins, others, resource)
- for sig, pins, others, resource in sc]
- # resolve signal names in platform commands
- pc = self.constraint_manager.get_platform_commands()
- named_pc = []
- for template, args in pc:
- name_dict = dict((k, vns.get_name(sig)) for k, sig in args.items())
- named_pc.append(template.format(**name_dict))
-
- return named_sc, named_pc
-
- def get_verilog(self, fragment, **kwargs):
- return verilog.convert(
- fragment,
- self.constraint_manager.get_io_signals(),
- create_clock_domains=False, **kwargs)
-
- def get_edif(self, fragment, cell_library, vendor, device, **kwargs):
- return edif.convert(
- fragment,
- self.constraint_manager.get_io_signals(),
- cell_library, vendor, device, **kwargs)
-
- def build(self, fragment):
- raise NotImplementedError("GenericPlatform.build must be overloaded")
-
- def create_programmer(self):
- raise NotImplementedError
+++ /dev/null
-import os
-
-
-class GenericProgrammer:
- def __init__(self, flash_proxy_basename=None):
- self.flash_proxy_basename = flash_proxy_basename
- self.flash_proxy_dirs = [
- "~/.migen", "/usr/local/share/migen", "/usr/share/migen",
- "~/.mlabs", "/usr/local/share/mlabs", "/usr/share/mlabs"]
-
- def set_flash_proxy_dir(self, flash_proxy_dir):
- if flash_proxy_dir is not None:
- self.flash_proxy_dirs = [flash_proxy_dir]
-
- def find_flash_proxy(self):
- for d in self.flash_proxy_dirs:
- fulldir = os.path.abspath(os.path.expanduser(d))
- fullname = os.path.join(fulldir, self.flash_proxy_basename)
- if os.path.exists(fullname):
- return fullname
- raise OSError("Failed to find flash proxy bitstream")
-
- # must be overloaded by specific programmer
- def load_bitstream(self, bitstream_file):
- raise NotImplementedError
-
- # must be overloaded by specific programmer
- def flash(self, address, data_file):
- raise NotImplementedError
-
-
+++ /dev/null
-from migen.build.lattice.platform import LatticePlatform
-from migen.build.lattice.programmer import LatticeProgrammer
+++ /dev/null
-from migen.fhdl.module import Module
-from migen.fhdl.specials import Instance
-from migen.genlib.io import *
-from migen.genlib.resetsync import AsyncResetSynchronizer
-
-
-class LatticeAsyncResetSynchronizerImpl(Module):
- def __init__(self, cd, async_reset):
- rst1 = Signal()
- self.specials += [
- Instance("FD1S3BX", i_D=0, i_PD=async_reset,
- i_CK=cd.clk, o_Q=rst1),
- Instance("FD1S3BX", i_D=rst1, i_PD=async_reset,
- i_CK=cd.clk, o_Q=cd.rst)
- ]
-
-
-class LatticeAsyncResetSynchronizer:
- @staticmethod
- def lower(dr):
- return LatticeAsyncResetSynchronizerImpl(dr.cd, dr.async_reset)
-
-
-class LatticeDDROutputImpl(Module):
- def __init__(self, i1, i2, o, clk):
- self.specials += Instance("ODDRXD1",
- synthesis_directive="ODDRAPPS=\"SCLK_ALIGNED\"",
- i_SCLK=clk,
- i_DA=i1, i_DB=i2, o_Q=o,
- )
-
-
-class LatticeDDROutput:
- @staticmethod
- def lower(dr):
- return LatticeDDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk)
-
-lattice_special_overrides = {
- AsyncResetSynchronizer: LatticeAsyncResetSynchronizer,
- DDROutput: LatticeDDROutput
-}
+++ /dev/null
-# This file is Copyright (c) 2015 Florent Kermarrec <florent@enjoy-digital.fr>
-# License: BSD
-
-import os
-import sys
-import subprocess
-import shutil
-
-from migen.fhdl.structure import _Fragment
-
-from migen.build.generic_platform import *
-from migen.build import tools
-from migen.build.lattice import common
-
-
-def _format_constraint(c):
- if isinstance(c, Pins):
- return ("LOCATE COMP ", " SITE " + "\"" + c.identifiers[0] + "\"")
- elif isinstance(c, IOStandard):
- return ("IOBUF PORT ", " IO_TYPE=" + c.name)
- elif isinstance(c, Misc):
- return c.misc
-
-
-def _format_lpf(signame, pin, others, resname):
- fmt_c = [_format_constraint(c) for c in ([Pins(pin)] + others)]
- r = ""
- for pre, suf in fmt_c:
- r += pre + "\"" + signame + "\"" + suf + ";\n"
- return r
-
-
-def _build_lpf(named_sc, named_pc):
- r = "BLOCK RESETPATHS;\n"
- r += "BLOCK ASYNCPATHS;\n"
- for sig, pins, others, resname in named_sc:
- if len(pins) > 1:
- for i, p in enumerate(pins):
- r += _format_lpf(sig + "[" + str(i) + "]", p, others, resname)
- else:
- r += _format_lpf(sig, pins[0], others, resname)
- if named_pc:
- r += "\n" + "\n\n".join(named_pc)
- return r
-
-
-def _build_files(device, sources, vincpaths, build_name):
- tcl = []
- tcl.append("prj_project new -name \"{}\" -impl \"implementation\" -dev {} -synthesis \"synplify\"".format(build_name, device))
- for path in vincpaths:
- tcl.append("prj_impl option {include path} {\"" + path + "\"}")
- for filename, language, library in sources:
- tcl.append("prj_src add \"" + filename + "\" -work " + library)
- tcl.append("prj_run Synthesis -impl implementation -forceOne")
- tcl.append("prj_run Translate -impl implementation")
- tcl.append("prj_run Map -impl implementation")
- tcl.append("prj_run PAR -impl implementation")
- tcl.append("prj_run Export -impl implementation -task Bitgen")
- tools.write_to_file(build_name + ".tcl", "\n".join(tcl))
-
-
-def _run_diamond(build_name, source, ver=None):
- if sys.platform == "win32" or sys.platform == "cygwin":
- build_script_contents = "REM Autogenerated by Migen\n"
- build_script_contents = "pnmainc " + build_name + ".tcl\n"
- build_script_file = "build_" + build_name + ".bat"
- tools.write_to_file(build_script_file, build_script_contents)
- r = subprocess.call([build_script_file])
- shutil.copy(os.path.join("implementation", build_name + "_implementation.bit"), build_name + ".bit")
- else:
- raise NotImplementedError
-
- if r != 0:
- raise OSError("Subprocess failed")
-
-
-class LatticeDiamondToolchain:
- def build(self, platform, fragment, build_dir="build", build_name="top",
- toolchain_path="/opt/Diamond", run=True):
- tools.mkdir_noerror(build_dir)
- os.chdir(build_dir)
-
- if not isinstance(fragment, _Fragment):
- fragment = fragment.get_fragment()
- platform.finalize(fragment)
-
- v_output = platform.get_verilog(fragment)
- named_sc, named_pc = platform.resolve_signals(v_output.ns)
- v_file = build_name + ".v"
- v_output.write(v_file)
- sources = platform.sources | {(v_file, "verilog", "work")}
- _build_files(platform.device, sources, platform.verilog_include_paths, build_name)
-
- tools.write_to_file(build_name + ".lpf", _build_lpf(named_sc, named_pc))
-
- if run:
- _run_diamond(build_name, toolchain_path)
-
- os.chdir("..")
-
- return v_output.ns
-
- def add_period_constraint(self, platform, clk, period):
- # TODO: handle differential clk
- platform.add_platform_command("""FREQUENCY PORT "{clk}" {freq} MHz;""".format(freq=str(float(1/period)*1000), clk="{clk}"), clk=clk)
+++ /dev/null
-from migen.build.generic_platform import GenericPlatform
-from migen.build.lattice import common, diamond
-
-
-class LatticePlatform(GenericPlatform):
- bitstream_ext = ".bit"
-
- def __init__(self, *args, toolchain="diamond", **kwargs):
- GenericPlatform.__init__(self, *args, **kwargs)
- if toolchain == "diamond":
- self.toolchain = diamond.LatticeDiamondToolchain()
- else:
- raise ValueError("Unknown toolchain")
-
- def get_verilog(self, *args, special_overrides=dict(), **kwargs):
- so = dict(common.lattice_special_overrides)
- so.update(special_overrides)
- return GenericPlatform.get_verilog(self, *args, special_overrides=so, **kwargs)
-
- def build(self, *args, **kwargs):
- return self.toolchain.build(self, *args, **kwargs)
-
- def add_period_constraint(self, clk, period):
- if hasattr(clk, "p"):
- clk = clk.p
- self.toolchain.add_period_constraint(self, clk, period)
+++ /dev/null
-import os
-import subprocess
-
-from migen.build.generic_programmer import GenericProgrammer
-from migen.build import tools
-
-
-# XXX Lattice programmer need an .xcf file, will need clean up and support for more parameters
-_xcf_template = """
-<?xml version='1.0' encoding='utf-8' ?>
-<!DOCTYPE ispXCF SYSTEM "IspXCF.dtd" >
-<ispXCF version="3.4.1">
- <Comment></Comment>
- <Chain>
- <Comm>JTAG</Comm>
- <Device>
- <SelectedProg value="TRUE"/>
- <Pos>1</Pos>
- <Vendor>Lattice</Vendor>
- <Family>LatticeECP3</Family>
- <Name>LFE3-35EA</Name>
- <File>{bitstream_file}</File>
- <Operation>Fast Program</Operation>
- </Device>
- </Chain>
- <ProjectOptions>
- <Program>SEQUENTIAL</Program>
- <Process>ENTIRED CHAIN</Process>
- <OperationOverride>No Override</OperationOverride>
- <StartTAP>TLR</StartTAP>
- <EndTAP>TLR</EndTAP>
- <VerifyUsercode value="FALSE"/>
- </ProjectOptions>
- <CableOptions>
- <CableName>USB2</CableName>
- <PortAdd>FTUSB-0</PortAdd>
- <USBID>Dual RS232-HS A Location 0000 Serial A</USBID>
- <JTAGPinSetting>
- TRST ABSENT;
- ISPEN ABSENT;
- </JTAGPinSetting>
- </CableOptions>
-</ispXCF>
-"""
-
-
-class LatticeProgrammer(GenericProgrammer):
- needs_bitreverse = False
-
- def load_bitstream(self, bitstream_file):
- xcf_file = bitstream_file.replace(".bit", ".xcf")
- xcf_content = _xcf_template.format(bitstream_file=bitstream_file)
- tools.write_to_file(xcf_file, xcf_content)
- subprocess.call(["pgrcmd", "-infile", xcf_file])
+++ /dev/null
-import subprocess
-
-from migen.build.generic_programmer import GenericProgrammer
-
-
-class OpenOCD(GenericProgrammer):
- needs_bitreverse = False
-
- def __init__(self, config, flash_proxy_basename=None):
- GenericProgrammer.__init__(self, flash_proxy_basename)
- self.config = config
-
- def load_bitstream(self, bitstream):
- script = "; ".join([
- "init",
- "pld load 0 {}".format(bitstream),
- "exit",
- ])
- subprocess.call(["openocd", "-f", self.config, "-c", script])
-
- def flash(self, address, data):
- flash_proxy = self.find_flash_proxy()
- script = "; ".join([
- "init",
- "jtagspi_init 0 {}".format(flash_proxy),
- "jtagspi_program {} 0x{:x}".format(data, address),
- "fpga_program",
- "exit"
- ])
- subprocess.call(["openocd", "-f", self.config, "-c", script])
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-_ios = [
- ("clk0", 0, Pins("N9"), IOStandard("LVCMOS18")),
- ("fpga_reset", 0, Pins("T9"), IOStandard("LVCMOS18"), Drive("8")),
- ("fpga_initb", 0, Pins("T12"), IOStandard("LVCMOS18"), Drive("8")),
- ("weim", 0,
- Subsignal("cs4_dtack", Pins("R3"), IOStandard("LVCMOS18"), Drive("8")),
- Subsignal("cs5n", Pins("P10"), IOStandard("LVCMOS18")),
- Subsignal("eb0n", Pins("P9"), IOStandard("LVCMOS18")),
- Subsignal("oen", Pins("R9"), IOStandard("LVCMOS18")),
- Subsignal("data",
- Pins("T5 T6 P7 N8 P12 T13 R13 T14 P5 N6 T3 T11 T4 R5 M10 T10"),
- IOStandard("LVCMOS18"), Drive("8")),
- Subsignal("addr",
- Pins("N5 L7 M7 M8 L8 L9 L10 M11 P11 N11 N12 P13"),
- IOStandard("LVCMOS18"))
- )
-]
-
-_connectors = [
- ("J2",
- "None", # no 0 pin
- "None", # 1 +3v3
- "None", # 2 +3v3
- "None", # 3 GND
- "None", # 4 GND
- "None", # 5 DP USB_OTG_PHY +3V3
- "None", # 6 DM USB_OTG_PHY +3V3
- "None", # 7 VBUS USB_OTG_ PHY +3V3
- "None", # 8 PSW_N USB_OTG_PHY +3V3
- "None", # 9 ID USB_OTG_PHY +3V3
- "None", # 10 FAULT USB_OTG_PHY +3V3
- "None", # 11 RXP Ethernet_PHY +3V3
- "None", # 12 RXN Ethernet_PHY +3V3
- "None", # 13 ETH_LINK Ethernet_PHY +2V8
- "None", # 14 PC_VS2 PC +2V8 PF13
- "None", # 15 PC_VS1 PC +2V8 PF14
- "None", # 16 PC_PWRON PC +2V8 PF16
- "None", # 17 PC_READY PC +2V8 PF17
- "None", # 18 PWM0 PWM0 +2V8 PE5
- "None", # 19 TOUT GPT +2V8 PC14
- "None", # 20 GND POWER
- "None", # 21 VCC01 (IN) BANK1 SUPPLY VCCO1
- "C16", # 22 IO_L24P_1 FPGA_BANK1 VCC01
- "C15", # 23 IO_L24N_1 FPGA_BANK1 VCC01
- "D16", # 24 IO_L22_P1 FPGA_BANK1 VCC01
- "None", # 25 GND POWER
- "B14", # 26 IO_L02N_0 FPGA_BANK0 VCCO0
- "B15", # 27 IO_L02P_0 FPGA_BANK0
- "A13", # 28 IO_L04N_0 FPGA_BANK0
- "A14", # 29 IO_L04P_0 FPGA_BANK0 VCCO0
- "D11", # 30 IO_L03N_0 FPGA_BANK0 VCCO0
- "C12", # 31 IO_L03P_0 FPGA_BANK0 VCCO0
- "A10", # 32 IO_L08N_0 FPGA_BANK0 VCCO0
- "B10", # 33 IO_L08P_0 FPGA_BANK0 VCCO0
- "A9", # 34 IO_L10N_0 / GLCK7 FPGA_BANK0 VCCO0
- "C9", # 35 IO_L10P_0 / GCLK6 FPGA_BANK0 VCCO0
- "B8", # 36 IO_L12N_0 / GCLK11 FPGA_BANK0 VCCO0
- "A8", # 37 IO_L12P_0 / GCLK10 FPGA_BANK0 VCCO0
- "B6", # 38 IO_L15N_0 FPGA_BANK0 VCCO0
- "A6", # 39 IO_L15P_0 FPGA_BANK0 VCCO0
- "B4", # 40 IO_L18N_0 FPGA_BANK0 VCCO0
- "A4", # 41 IO_L18P_0 FPGA_BANK0 VCCO0
- "None", # 42 GND POWER
- "N3", # 43 IO_L24P_3 FPGA_BANK3 VCCO3
- "R1", # 44 IO_L23P_3 FPGA_BANK3 VCCO3
- "P1", # 45 IO_L22N_3 FPGA_BANK3 VCCO3
- "N1", # 46 IO_L20N_3 FPGA_BANK3 VCCO3
- "M1", # 47 IO_L20P_3 FPGA_BANK3 VCCO3
- "H3", # 48 IO_L12P_3 FPGA_BANK3 VCCO3
- "K1", # 49 IO_L15N_3 FPGA_BANK3 VCCO3
- "J1", # 50 IO_L14N_3 FPGA_BANK3 VCCO3
- "H1", # 51 IO_L11N_3 FPGA_BANK3 VCCO3
- "G1", # 52 IO_L08N_3 FPGA_BANK3 VCCO3
- "F1", # 53 IO_L08P_3 FPGA_BANK3 VCCO3
- "E1", # 54 IO_L03N_3 FPGA_BANK3 VCCO3
- "D1", # 55 IO_LO3P_3 FPGA_BANK3 VCCO3
- "C1", # 56 IO_L01N_3 FPGA_BANK3 VCCO3
- "None", # 57 GND POWER
- "None", # 58 TRSTN JTAG +2V8
- "None", # 59 TDI JTAG +2V8
- "None", # 60 TCK JTAG +2V8
- "None", # 61 TDO JTAG +2V8
- "None", # 62 TMS JTAG +2V8
- "None", # 63 GND POWER
- "C2", # 64 IO_L01P_3 FPGA_BANK3 VCCO3
- "D3", # 65 IO_L02N_3 FPGA_BANK3 VCCO3
- "D4", # 66 IO_L02P_3 FPGA_BANK3 VCCO3
- "F4", # 67 IP_LO4N_3 FPGA_BANK3 VCCO3
- "G2", # 68 IO_L11P_3 FPGA_BANK3 VCCO3
- "J2", # 69 IO_L14P_3 FPGA_BANK3 VCCO3
- "K3", # 70 IO_L15P_3 FPGA_BANK3 VCCO3
- "J3", # 71 IO_L12N_3 FPGA_BANK3 VCCO3
- "N2", # 72 IO_L22P_3 FPGA_BANK3 VCCO3
- "P2", # 73 IO_L23N_3 FPGA_BANK3 VCCO3
- "M4", # 74 IO_L24N_3 FPGA_BANK3 VCCO3
- "L6", # 75 IP_L25N_3 FPGA_BANK3 VCCO3
- "None", # 76 VCCO3 (IN) BANK3 SUPPLY VCCO3 (3.3Vmax)
- "None", # 77 VCCO3 (IN) BANK3 SUPPLY VCCO3 (3.3Vmax)
- "A3", # 78 IO_L19P_0 FPGA_BANK0 VCCO0
- "B3", # 79 IO_L19N_0 FPGA_BANK0 VCCO0
- "A5", # 80 IO_L17P_0 FPGA_BANK0 VCCO0
- "C5", # 81 IO_L17N_0 FPGA_BANK0 VCCO0
- "D7", # 82 IO_L16P_0 FPGA_BANK0 VCCO0
- "C6", # 83 IO_L16N_0 FPGA_BANK0 VCCO0
- "C8", # 84 IO_L11P_0 / GCLK8 FPGA_BANK0 VCCO0
- "D8", # 85 IO_L11N_0 / GCLK9 FPGA_BANK0 VCCO0
- "C10", # 86 IO_L09P_0 / GCLK4 FPGA_BANK0 VCCO0
- "D9", # 87 IO_L09N_0 / GCLK5 FPGA_BANK0 VCCO0
- "C11", # 88 IO_L07P_0 FPGA_BANK0 VCCO0
- "A11", # 89 IO_L07N_0 FPGA_BANK0 VCCO0
- "D13", # 90 IO_L01P_0 FPGA_BANK0 VCCO0
- "C13", # 91 IO_L01N_0 FPGA_BANK0 VCCO0
- "None", # 92 VCCO0 (IN) BANK0 SUPPLY VCCO0 (3.3Vmax)
- "None", # 93 VCCO0 (IN) BANK0 SUPPLY VCCO0 (3.3Vmax)
- "None", # 94 GND POWER VCCO0 A13
- "D15", # 95 IO_L22N_1 FPGA_BANK1 VCC01
- "E13", # 96 IO_L23P_1 FPGA_BANK1 VCC01
- "D14", # 97 IO_L23N_1 FPGA_BANK1 VCC01
- "E14", # 98 IO_L20P_1 FPGA_BANK1 VCC01
- "F13", # 99 IO_L20N_1 FPGA_BANK1 VCC01
- "None", # 100 GND POWER (3.3Vmax)
- "None", # 101 USR_RESETN (open CONFIG Pos PC15 +2V8 drain with pullup)
- "None", # 102 TIN GPT +2V8
- "None", # 103 EXTAL_26M CONFIG +2V5
- "None", # 104 RX3 RS232_3 RS232
- "None", # 105 TX3 RS232_3 RS232
- "None", # 106 RX1 RS232_1 RS232
- "None", # 107 TX1 RS232_1 RS232
- "None", # 108 BOOT CONFIG +2V8
- "None", # 109 TXN Ethernet_PHY +3V3
- "None", # 110 TXP Ethernet_PHY +3V3
- "None", # 111 ETH_ACTIVITY Ethernet_PHY +2V8
- "None", # 112 USBH2_NXT USB_HOST2 +2V5 PA3
- "None", # 113 USBH2_DIR USB_HOST2 +2V5 PA1
- "None", # 114 USBH2_DATA7 USB_HOST2 +2V5 PA2
- "None", # 115 USBH2_STP USB_HOST2 +2V5 PA4
- "None") # 116 USBH2_CLK USB_HOST2 +2V5 PA0
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk0"
- default_clk_period = 10
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc3s200a-ft256-4", _ios, _connectors)
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-_ios = [
- ("clk3", 0, Pins("N8"), IOStandard("LVCMOS33")),
- ("clko", 0, Pins("N7"), IOStandard("LVCMOS33")),
- ("fpga_initb", 0, Pins("P3"), IOStandard("LVCMOS33")),
- ("fpga_program", 0, Pins("R2"), IOStandard("LVCMOS33")),
- ("eim", 0,
- Subsignal("bclk", Pins("N12")),
- Subsignal("eb1", Pins("P13")),
- Subsignal("cs1", Pins("R11")),
- Subsignal("cs2", Pins("N9")),
- Subsignal("lba", Pins("R9")),
- Subsignal("eb0", Pins("P7")),
- Subsignal("oe", Pins("R7")),
- Subsignal("rw", Pins("R6")),
- Subsignal("dtack", Pins("N4")),
- Subsignal("wait", Pins("R4")),
- Subsignal("da", Pins("N6 L5 L6 R5 P5 N11 M11 P11 L8 K8 M8 M10 L9 R10 N5 M5")),
- IOStandard("LVCMOS33")
- )
-]
-
-_connectors = [
- ("J2",
- "None", # No 0 pin
- "None", # 1 FPGA Bank1 power
- "None", # 2 FPGA Bank1 power
- "None", # 3 GND
- "B14", # 4 IO_L1P_A25_1
- "B15", # 5 IO_L1N_A24_VREF_1
- "C14", # 6 IO_L33P_A15_M1A10_1
- "C15", # 7 IO_L33N_A14_M1A4_1
- "D13", # 8 IO_L35P_A11_M1A7_1
- "D15", # 9 IO_L35N_A10_M1A2_1
- "E14", # 10 IO_L37P_A7_M1A0_1
- "E15", # 11 IO_L37N_A6_M1A1_1
- "None", # 12 GND
- "F13", # 13 IO_L39P_M1A3_1
- "F15", # 14 IO_L39N_M1ODT_1
- "G14", # 15 IO_L41P_GCLK9_IRDY1_M1RASN_1
- "G15", # 16 IO_L41N_GCLK8_M1CASN_1
- "H13", # 17 IO_L42P_GCLK7_M1UDM_1
- "H15", # 18 IO_L42N_GCLK6_TRDY1_M1LDM
- "J14", # 19 IO_L43P_GCLK5_M1DQ4_1
- "J15", # 20 IO_L43N_GCLK4_M1DQ5_1
- "K13", # 21 IO_L44P_A3_M1DQ6_1
- "K15", # 22 IO_L44N_A2_M1DQ7_1
- "L14", # 23 IO_L45P_A1_M1LDQS_1
- "L15", # 24 IO_L45N_A0_M1LDQSN_1
- "None", # 25 GND
- "E2", # 26 IO_L52P_M3A8_3
- "E1", # 27 IO_L52N_M3A9_3
- "D3", # 28 IO_L54P_M3RESET_3
- "D1", # 29 IO_L54N_M3A11_3
- "F3", # 30 IO_L46P_M3CLK_3
- "F1", # 31 IO_L46N_M3CLKN_3
- "G2", # 32 IO_L44P_GCLK21_M3A5_3
- "G1", # 33 IO_L44N_GCLK20_M3A6_3
- "H3", # 34 IO_L42P_GCLK25_TRDY2_M3UDM_3
- "H1", # 35 IO_L42N_GCLK24_M3LDM_3
- "K3", # 36 IO_L40P_M3DQ6_3
- "K1", # 37 IO_L40N_M3DQ7_3
- "None", # 38 GND
- "None", # 39 GPIO4_16
- "None", # 40 GPIO4_17
- "None", # 41 BOOT_MODE0
- "None", # 42 AUD5_RXFS
- "None", # 43 AUD5_RXC
- "None", # 44 GND
- "None", # 45 AUD5_RXD
- "None", # 46 AUD5_TXC
- "None", # 47 AUD5_TXFS
- "None", # 48 GND
- "None", # 49 SPI2_SCLK_GPT_CMPOUT3
- "None", # 50 SPI2_MISO
- "None", # 51 SPI2_MOSI
- "None", # 52 SPI2_SS1
- "None", # 53 SPI2_SS2
- "None", # 54 SPI2_SS3
- "None", # 55 SPI2_RDY
- "None", # 56 OWIRE
- "None", # 57 GND
- "None", # 58 SPI1_SCLK
- "None", # 59 SPI1_MISO
- "None", # 60 SPI1_MOSI
- "None", # 61 SPI1_SS0
- "None", # 62 SPI1_SS1
- "None", # 63 SPI1_RDY
- "None", # 64 RESET#
- "None", # 65 VIO_H2
- "None", # 66 PMIC_GPIO6
- "None", # 67 TOUCH_X+
- "None", # 68 TOUCH_X-
- "None", # 69 TOUCH_Y+
- "None", # 70 TOUCH_Y-
- "None", # 71 AUXADCIN4
- "None", # 72 AUXADCIN3
- "None", # 73 AUXADCIN2
- "None", # 74 AUXADCIN1
- "None", # 75 PMIC_GPIO7
- "None", # 76 +1v8
- "None", # 77 RESERVED
- "None", # 78 UART3_TXD
- "None", # 79 UART_3_RXD
- "None", # 80 UART2_TXD
- "None", # 81 UART2_RXD
- "None", # 82 UART2_RTS_KEY_COL7
- "None", # 83 UART2_CTS_KEY_COL6
- "None", # 84 UART1_TXD
- "None", # 85 UART1_RXD
- "None", # 86 UART1_RTS
- "None", # 87 UART1_CTS
- "None", # 88 GND
- "None", # 89 AUD3_TXD
- "None", # 90 AUD3_RXD
- "None", # 91 AUD3_FS
- "None", # 92 AUD3_CK
- "None", # 93 GND
- "None", # 94 AUD6_TXFS_KEY_ROW7
- "None", # 95 AUD6_TXC_KEY_ROW6
- "None", # 96 AUD6_RXD_KEY_ROW5
- "None", # 97 AUD6_TXD_KEY_ROW4
- "None", # 98 I2C2_SDA_UART3_CTS
- "None", # 99 I2C2_SCL_UART3_RTS
- "None", # 100 BOOT_MODE1
- "None", # 101 PWM2
- "None", # 102 PWM1
- "None", # 103 GND
- "L1", # 104 IO_L39N_M3LDQSN_3
- "L2", # 105 IO_L39P_M3LDQS_3
- "J1", # 106 IO_L41N_GCLK26_M3DQ5_3
- "J2", # 107 IO_L41P_GCLK27_M3DQ4_3
- "J3", # 108 IO_L43N_GCLK22_IRDY2_M3CASN_3
- "K4", # 109 IO_L43P_GCLK23_M3RASN_3
- "J4", # 110 IO_L45N_M3ODT_3
- "K5", # 111 IO_L45P_M3A3_3
- "C1", # 112 IO_L83N_VREF_3
- "C2", # 113 IO_L83P_3
- "E3", # 114 IO_L53N_M3A12_3
- "D4", # 115 IO_L53P_M3CKE_3
- "None", # 116 GND
- "P15", # 117 IO_L74N_DOUT_BUSY_1
- "P14", # 118 IO_L74P_AWAKE_1
- "N15", # 119 IO_L47N_LDC_M1DQ1_1
- "N14", # 120 IO_L47P_FWE_B_M1DQ0_1
- "M15", # 121 IO_L46N_FOE_B_M1DQ3_1
- "M13", # 122 IO_L46P_FCS_B_M1DQS2_1
- "L12", # 123 IO_L40N_GCLK10_M1A6_1
- "K12", # 124 IO_L40P_GCLK11_M1A5_1
- "K11", # 125 IO_L38N_A4_M1CLKN_1
- "K10", # 126 IO_L38P_A5_M1CLK_1
- "J13", # 127 IO_L36N_A8_M1BA1_1
- "J11", # 128 IO_L36P_A9_M1BA0_1
- "None", # 129 GND
- "G13", # 130 IO_L34N_A12_M1BA2_1_NOTLX4
- "H12", # 131 IO_L34P_A13_M1WE_1_NOTLX4
- "H11", # 132 IO_L32N_A16_M1A9_1_NOTLX4
- "H10", # 133 IO_L32P_A17_M1A8_1_NOTLX4
- "F12", # 134 IO_L31N_A18_M1A12_1_NOTLX4
- "F11", # 135 IO_L31P_A19_M1CKE_1_NOTLX4
- "G12", # 136 IO_L30N_A20_M1A11_1_NOTLX4
- "G11", # 137 IO_L30P_A21_M1RESET_1_NOTLX4
- "None", # 138 GND
- "None", # 139 FPGA_BANK3_POWER
- "None") # 140 FPGA_BANK3_POWER
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk3"
- default_clk_period = 10.526
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6slx9-2csg225", _ios, _connectors)
+++ /dev/null
-# This file is Copyright (c) 2013 Florent Kermarrec <florent@enjoy-digital.fr>
-# License: BSD
-
-from migen.build.generic_platform import *
-from migen.build.altera import AlteraPlatform
-from migen.build.altera.programmer import USBBlaster
-
-
-_io = [
- ("clk50", 0, Pins("R8"), IOStandard("3.3-V LVTTL")),
-
- ("user_led", 0, Pins("A15"), IOStandard("3.3-V LVTTL")),
- ("user_led", 1, Pins("A13"), IOStandard("3.3-V LVTTL")),
- ("user_led", 2, Pins("B13"), IOStandard("3.3-V LVTTL")),
- ("user_led", 3, Pins("A11"), IOStandard("3.3-V LVTTL")),
- ("user_led", 4, Pins("D1"), IOStandard("3.3-V LVTTL")),
- ("user_led", 5, Pins("F3"), IOStandard("3.3-V LVTTL")),
- ("user_led", 6, Pins("B1"), IOStandard("3.3-V LVTTL")),
- ("user_led", 7, Pins("L3"), IOStandard("3.3-V LVTTL")),
-
- ("key", 0, Pins("J15"), IOStandard("3.3-V LVTTL")),
- ("key", 1, Pins("E1"), IOStandard("3.3-V LVTTL")),
-
- ("sw", 0, Pins("M1"), IOStandard("3.3-V LVTTL")),
- ("sw", 1, Pins("T9"), IOStandard("3.3-V LVTTL")),
- ("sw", 2, Pins("B9"), IOStandard("3.3-V LVTTL")),
- ("sw", 3, Pins("M15"), IOStandard("3.3-V LVTTL")),
-
- ("serial", 0,
- Subsignal("tx", Pins("D3"), IOStandard("3.3-V LVTTL")),
- Subsignal("rx", Pins("C3"), IOStandard("3.3-V LVTTL"))
- ),
-
- ("sdram_clock", 0, Pins("R4"), IOStandard("3.3-V LVTTL")),
- ("sdram", 0,
- Subsignal("a", Pins("P2 N5 N6 M8 P8 T7 N8 T6 R1 P1 N2 N1 L4")),
- Subsignal("ba", Pins("M7 M6")),
- Subsignal("cs_n", Pins("P6")),
- Subsignal("cke", Pins("L7")),
- Subsignal("ras_n", Pins("L2")),
- Subsignal("cas_n", Pins("L1")),
- Subsignal("we_n", Pins("C2")),
- Subsignal("dq", Pins("G2 G1 L8 K5 K2 J2 J1 R7 T4 T2 T3 R3 R5 P3 N3 K1")),
- Subsignal("dm", Pins("R6 T5")),
- IOStandard("3.3-V LVTTL")
- ),
-
- ("epcs", 0,
- Subsignal("data0", Pins("H2")),
- Subsignal("dclk", Pins("H1")),
- Subsignal("ncs0", Pins("D2")),
- Subsignal("asd0", Pins("C1")),
- IOStandard("3.3-V LVTTL")
- ),
-
- ("i2c", 0,
- Subsignal("sclk", Pins("F2")),
- Subsignal("sdat", Pins("F1")),
- IOStandard("3.3-V LVTTL")
- ),
-
- ("g_sensor", 0,
- Subsignal("cs_n", Pins("G5")),
- Subsignal("int", Pins("M2")),
- IOStandard("3.3-V LVTTL")
- ),
-
- ("adc", 0,
- Subsignal("cs_n", Pins("A10")),
- Subsignal("saddr", Pins("B10")),
- Subsignal("sclk", Pins("B14")),
- Subsignal("sdat", Pins("A9")),
- IOStandard("3.3-V LVTTL")
- ),
-
- ("gpio_0", 0,
- Pins("D3 C3 A2 A3 B3 B4 A4 B5 A5 D5 B6 A6 B7 D6 A7 C6",
- "C8 E6 E7 D8 E8 F8 F9 E9 C9 D9 E11 E10 C11 B11 A12 D11",
- "D12 B12"),
- IOStandard("3.3-V LVTTL")
- ),
- ("gpio_1", 0,
- Pins("F13 T15 T14 T13 R13 T12 R12 T11 T10 R11 P11 R10 N12 P9 N9 N11",
- "L16 K16 R16 L15 P15 P16 R14 N16 N15 P14 L14 N14 M10 L13 J16 K15",
- "J13 J14"),
- IOStandard("3.3-V LVTTL")
- ),
- ("gpio_2", 0,
- Pins("A14 B16 C14 C16 C15 D16 D15 D14 F15 F16 F14 G16 G15"),
- IOStandard("3.3-V LVTTL")
- ),
-]
-
-
-class Platform(AlteraPlatform):
- default_clk_name = "clk50"
- default_clk_period = 20
-
- def __init__(self):
- AlteraPlatform.__init__(self, "EP4CE22F17C6", _io)
-
- def create_programmer(self):
- return USBBlaster()
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform, XC3SProg, VivadoProgrammer, iMPACT
-from migen.build.xilinx.ise import XilinxISEToolchain
-
-
-_io = [
- ("user_led", 0, Pins("AB8"), IOStandard("LVCMOS15")),
- ("user_led", 1, Pins("AA8"), IOStandard("LVCMOS15")),
- ("user_led", 2, Pins("AC9"), IOStandard("LVCMOS15")),
- ("user_led", 3, Pins("AB9"), IOStandard("LVCMOS15")),
- ("user_led", 4, Pins("AE26"), IOStandard("LVCMOS25")),
- ("user_led", 5, Pins("G19"), IOStandard("LVCMOS25")),
- ("user_led", 6, Pins("E18"), IOStandard("LVCMOS25")),
- ("user_led", 7, Pins("F16"), IOStandard("LVCMOS25")),
-
- ("cpu_reset", 0, Pins("AB7"), IOStandard("LVCMOS15")),
-
- ("user_btn_c", 0, Pins("G12"), IOStandard("LVCMOS25")),
- ("user_btn_n", 0, Pins("AA12"), IOStandard("LVCMOS15")),
- ("user_btn_s", 0, Pins("AB12"), IOStandard("LVCMOS15")),
- ("user_btn_w", 0, Pins("AC6"), IOStandard("LVCMOS15")),
- ("user_btn_e", 0, Pins("AG5"), IOStandard("LVCMOS15")),
-
- ("user_dip_btn", 0, Pins("Y29"), IOStandard("LVCMOS25")),
- ("user_dip_btn", 1, Pins("W29"), IOStandard("LVCMOS25")),
- ("user_dip_btn", 2, Pins("AA28"), IOStandard("LVCMOS25")),
- ("user_dip_btn", 3, Pins("Y28"), IOStandard("LVCMOS25")),
-
- ("user_sma_clock", 0,
- Subsignal("p", Pins("L25"), IOStandard("LVDS_25")),
- Subsignal("n", Pins("K25"), IOStandard("LVDS_25"))
- ),
- ("user_sma_clock_p", 0, Pins("L25"), IOStandard("LVCMOS25")),
- ("user_sma_clock_n", 0, Pins("K25"), IOStandard("LVCMOS25")),
-
- ("user_sma_gpio_p", 0, Pins("Y23"), IOStandard("LVCMOS33")),
- ("user_sma_gpio_n", 0, Pins("Y24"), IOStandard("LVCMOS33")),
-
- ("clk200", 0,
- Subsignal("p", Pins("AD12"), IOStandard("LVDS")),
- Subsignal("n", Pins("AD11"), IOStandard("LVDS"))
- ),
-
- ("clk156", 0,
- Subsignal("p", Pins("K28"), IOStandard("LVDS_25")),
- Subsignal("n", Pins("K29"), IOStandard("LVDS_25"))
- ),
-
- ("i2c", 0,
- Subsignal("scl", Pins("K21")),
- Subsignal("sda", Pins("L21")),
- IOStandard("LVCMOS25")),
-
- ("serial", 0,
- Subsignal("cts", Pins("L27")),
- Subsignal("rts", Pins("K23")),
- Subsignal("tx", Pins("K24")),
- Subsignal("rx", Pins("M19")),
- IOStandard("LVCMOS25")),
-
- ("spiflash", 0, # clock needs to be accessed through STARTUPE2
- Subsignal("cs_n", Pins("U19")),
- Subsignal("dq", Pins("P24", "R25", "R20", "R21")),
- IOStandard("LVCMOS25")
- ),
-
- ("mmc", 0,
- Subsignal("wp", Pins("Y21")),
- Subsignal("det", Pins("AA21")),
- Subsignal("cmd", Pins("AB22")),
- Subsignal("clk", Pins("AB23")),
- Subsignal("dat", Pins("AC20 AA23 AA22 AC21")),
- IOStandard("LVCMOS25")),
-
- ("lcd", 0,
- Subsignal("db", Pins("AA13 AA10 AA11 Y10")),
- Subsignal("e", Pins("AB10")),
- Subsignal("rs", Pins("Y11")),
- Subsignal("rw", Pins("AB13")),
- IOStandard("LVCMOS15")),
-
- ("rotary", 0,
- Subsignal("a", Pins("Y26")),
- Subsignal("b", Pins("Y25")),
- Subsignal("push", Pins("AA26")),
- IOStandard("LVCMOS25")),
-
- ("hdmi", 0,
- Subsignal("d", Pins("B23 A23 E23 D23 F25 E25 E24 D24 F26 E26 G23 G24 J19 H19 L17 L18 K19 K20")),
- Subsignal("de", Pins("H17")),
- Subsignal("clk", Pins("K18")),
- Subsignal("vsync", Pins("H20")),
- Subsignal("hsync", Pins("J18")),
- Subsignal("int", Pins("AH24")),
- Subsignal("spdif", Pins("J17")),
- Subsignal("spdif_out", Pins("G20")),
- IOStandard("LVCMOS25")),
-
- ("ddram", 0,
- Subsignal("a", Pins(
- "AH12 AG13 AG12 AF12 AJ12 AJ13 AJ14 AH14",
- "AK13 AK14 AF13 AE13 AJ11 AH11 AK10 AK11"),
- IOStandard("SSTL15")),
- Subsignal("ba", Pins("AH9 AG9 AK9"), IOStandard("SSTL15")),
- Subsignal("ras_n", Pins("AD9"), IOStandard("SSTL15")),
- Subsignal("cas_n", Pins("AC11"), IOStandard("SSTL15")),
- Subsignal("we_n", Pins("AE9"), IOStandard("SSTL15")),
- Subsignal("cs_n", Pins("AC12"), IOStandard("SSTL15")),
- Subsignal("dm", Pins("Y16 AB17 AF17 AE16 AK5 AJ3 AF6 AC7"),
- IOStandard("SSTL15")),
- Subsignal("dq", Pins(
- "AA15 AA16 AC14 AD14 AA17 AB15 AE15 Y15",
- "AB19 AD16 AC19 AD17 AA18 AB18 AE18 AD18",
- "AG19 AK19 AG18 AF18 AH19 AJ19 AE19 AD19",
- "AK16 AJ17 AG15 AF15 AH17 AG14 AH15 AK15",
- "AK8 AK6 AG7 AF7 AF8 AK4 AJ8 AJ6",
- "AH5 AH6 AJ2 AH2 AH4 AJ4 AK1 AJ1",
- "AF1 AF2 AE4 AE3 AF3 AF5 AE1 AE5",
- "AC1 AD3 AC4 AC5 AE6 AD6 AC2 AD4"),
- IOStandard("SSTL15_T_DCI")),
- Subsignal("dqs_p", Pins("AC16 Y19 AJ18 AH16 AH7 AG2 AG4 AD2"),
- IOStandard("DIFF_SSTL15")),
- Subsignal("dqs_n", Pins("AC15 Y18 AK18 AJ16 AJ7 AH1 AG3 AD1"),
- IOStandard("DIFF_SSTL15")),
- Subsignal("clk_p", Pins("AG10"), IOStandard("DIFF_SSTL15")),
- Subsignal("clk_n", Pins("AH10"), IOStandard("DIFF_SSTL15")),
- Subsignal("cke", Pins("AF10"), IOStandard("SSTL15")),
- Subsignal("odt", Pins("AD8"), IOStandard("SSTL15")),
- Subsignal("reset_n", Pins("AK3"), IOStandard("LVCMOS15")),
- Misc("SLEW=FAST"),
- Misc("VCCAUX_IO=HIGH")
- ),
-
- ("eth_clocks", 0,
- Subsignal("tx", Pins("M28")),
- Subsignal("gtx", Pins("K30")),
- Subsignal("rx", Pins("U27")),
- IOStandard("LVCMOS25")
- ),
- ("eth", 0,
- Subsignal("rst_n", Pins("L20")),
- Subsignal("int_n", Pins("N30")),
- Subsignal("mdio", Pins("J21")),
- Subsignal("mdc", Pins("R23")),
- Subsignal("dv", Pins("R28")),
- Subsignal("rx_er", Pins("V26")),
- Subsignal("rx_data", Pins("U30 U25 T25 U28 R19 T27 T26 T28")),
- Subsignal("tx_en", Pins("M27")),
- Subsignal("tx_er", Pins("N29")),
- Subsignal("tx_data", Pins("N27 N25 M29 L28 J26 K26 L30 J28")),
- Subsignal("col", Pins("W19")),
- Subsignal("crs", Pins("R30")),
- IOStandard("LVCMOS25")
- ),
-
- ("pcie_x1", 0,
- Subsignal("rst_n", Pins("G25"), IOStandard("LVCMOS25")),
- Subsignal("clk_p", Pins("U8")),
- Subsignal("clk_n", Pins("U7")),
- Subsignal("rx_p", Pins("M6")),
- Subsignal("rx_n", Pins("M5")),
- Subsignal("tx_p", Pins("L4")),
- Subsignal("tx_n", Pins("L3"))
- ),
- ("pcie_x2", 0,
- Subsignal("rst_n", Pins("G25"), IOStandard("LVCMOS25")),
- Subsignal("clk_p", Pins("U8")),
- Subsignal("clk_n", Pins("U7")),
- Subsignal("rx_p", Pins("M6 P6")),
- Subsignal("rx_n", Pins("M5 P5")),
- Subsignal("tx_p", Pins("L4 M2")),
- Subsignal("tx_n", Pins("L3 M1"))
- ),
- ("pcie_x4", 0,
- Subsignal("rst_n", Pins("G25"), IOStandard("LVCMOS25")),
- Subsignal("clk_p", Pins("U8")),
- Subsignal("clk_n", Pins("U7")),
- Subsignal("rx_p", Pins("M6 P6 R4 T6")),
- Subsignal("rx_n", Pins("M5 P5 R3 T5")),
- Subsignal("tx_p", Pins("L4 M2 N4 P2")),
- Subsignal("tx_n", Pins("L3 M1 N3 P1"))
- ),
- ("pcie_x8", 0,
- Subsignal("rst_n", Pins("G25"), IOStandard("LVCMOS25")),
- Subsignal("clk_p", Pins("U8")),
- Subsignal("clk_n", Pins("U7")),
- Subsignal("rx_p", Pins("M6 P6 R4 T6 V6 W4 Y6 AA4")),
- Subsignal("rx_n", Pins("M5 P5 R3 T5 V5 W3 Y5 AA3")),
- Subsignal("tx_p", Pins("L4 M2 N4 P2 T2 U4 V2 Y2")),
- Subsignal("tx_n", Pins("L3 M1 N3 P1 T1 U3 V1 Y1"))
- )
-]
-
-_connectors = [
- ("HPC", {
- "DP1_M2C_P": "D6",
- "DP1_M2C_N": "D5",
- "DP2_M2C_P": "B6",
- "DP2_M2C_N": "B5",
- "DP3_M2C_P": "A8",
- "DP3_M2C_N": "A7",
- "DP1_C2M_P": "C4",
- "DP1_C2M_N": "C3",
- "DP2_C2M_P": "B2",
- "DP2_C2M_N": "B1",
- "DP3_C2M_P": "A4",
- "DP3_C2M_N": "A3",
- "DP0_C2M_P": "D2",
- "DP0_C2M_N": "D1",
- "DP0_M2C_P": "E4",
- "DP0_M2C_N": "E3",
- "LA06_P": "H30",
- "LA06_N": "G30",
- "LA10_P": "D29",
- "LA10_N": "C30",
- "LA14_P": "B28",
- "LA14_N": "A28",
- "LA18_CC_P": "F21",
- "LA18_CC_N": "E21",
- "LA27_P": "C19",
- "LA27_N": "B19",
- "HA01_CC_P": "H14",
- "HA01_CC_N": "G14",
- "HA05_P": "F15",
- "HA05_N": "E16",
- "HA09_P": "F12",
- "HA09_N": "E13",
- "HA13_P": "L16",
- "HA13_N": "K16",
- "HA16_P": "L15",
- "HA16_N": "K15",
- "HA20_P": "K13",
- "HA20_N": "J13",
- "CLK1_M2C_P": "D17",
- "CLK1_M2C_N": "D18",
- "LA00_CC_P": "C25",
- "LA00_CC_N": "B25",
- "LA03_P": "H26",
- "LA03_N": "H27",
- "LA08_P": "E29",
- "LA08_N": "E30",
- "LA12_P": "C29",
- "LA12_N": "B29",
- "LA16_P": "B27",
- "LA16_N": "A27",
- "LA20_P": "E19",
- "LA20_N": "D19",
- "LA22_P": "C20",
- "LA22_N": "B20",
- "LA25_P": "G17",
- "LA25_N": "F17",
- "LA29_P": "C17",
- "LA29_N": "B17",
- "LA31_P": "G22",
- "LA31_N": "F22",
- "LA33_P": "H21",
- "LA33_N": "H22",
- "HA03_P": "C12",
- "HA03_N": "B12",
- "HA07_P": "B14",
- "HA07_N": "A15",
- "HA11_P": "B13",
- "HA11_N": "A13",
- "HA14_P": "J16",
- "HA14_N": "H16",
- "HA18_P": "K14",
- "HA18_N": "J14",
- "HA22_P": "L11",
- "HA22_N": "K11",
- "GBTCLK1_M2C_P": "E8",
- "GBTCLK1_M2C_N": "E7",
- "GBTCLK0_M2C_P": "C8",
- "GBTCLK0_M2C_N": "C7",
- "LA01_CC_P": "D26",
- "LA01_CC_N": "C26",
- "LA05_P": "G29",
- "LA05_N": "F30",
- "LA09_P": "B30",
- "LA09_N": "A30",
- "LA13_P": "A25",
- "LA13_N": "A26",
- "LA17_CC_P": "F20",
- "LA17_CC_N": "E20",
- "LA23_P": "B22",
- "LA23_N": "A22",
- "LA26_P": "B18",
- "LA26_N": "A18",
- "PG_M2C": "J29",
- "HA00_CC_P": "D12",
- "HA00_CC_N": "D13",
- "HA04_P": "F11",
- "HA04_N": "E11",
- "HA08_P": "E14",
- "HA08_N": "E15",
- "HA12_P": "C15",
- "HA12_N": "B15",
- "HA15_P": "H15",
- "HA15_N": "G15",
- "HA19_P": "H11",
- "HA19_N": "H12",
- "PRSNT_M2C_B": "M20",
- "CLK0_M2C_P": "D27",
- "CLK0_M2C_N": "C27",
- "LA02_P": "H24",
- "LA02_N": "H25",
- "LA04_P": "G28",
- "LA04_N": "F28",
- "LA07_P": "E28",
- "LA07_N": "D28",
- "LA11_P": "G27",
- "LA11_N": "F27",
- "LA15_P": "C24",
- "LA15_N": "B24",
- "LA19_P": "G18",
- "LA19_N": "F18",
- "LA21_P": "A20",
- "LA21_N": "A21",
- "LA24_P": "A16",
- "LA24_N": "A17",
- "LA28_P": "D16",
- "LA28_N": "C16",
- "LA30_P": "D22",
- "LA30_N": "C22",
- "LA32_P": "D21",
- "LA32_N": "C21",
- "HA02_P": "D11",
- "HA02_N": "C11",
- "HA06_P": "D14",
- "HA06_N": "C14",
- "HA10_P": "A11",
- "HA10_N": "A12",
- "HA17_CC_P": "G13",
- "HA17_CC_N": "F13",
- "HA21_P": "J11",
- "HA21_N": "J12",
- "HA23_P": "L12",
- "HA23_N": "L13",
- }
- ),
- ("LPC", {
- "GBTCLK0_M2C_P": "N8",
- "GBTCLK0_M2C_N": "N7",
- "LA01_CC_P": "AE23",
- "LA01_CC_N": "AF23",
- "LA05_P": "AG22",
- "LA05_N": "AH22",
- "LA09_P": "AK23",
- "LA09_N": "AK24",
- "LA13_P": "AB24",
- "LA13_N": "AC25",
- "LA17_CC_P": "AB27",
- "LA17_CC_N": "AC27",
- "LA23_P": "AH26",
- "LA23_N": "AH27",
- "LA26_P": "AK29",
- "LA26_N": "AK30",
- "CLK0_M2C_P": "AF22",
- "CLK0_M2C_N": "AG23",
- "LA02_P": "AF20",
- "LA02_N": "AF21",
- "LA04_P": "AH21",
- "LA04_N": "AJ21",
- "LA07_P": "AG25",
- "LA07_N": "AH25",
- "LA11_P": "AE25",
- "LA11_N": "AF25",
- "LA15_P": "AC24",
- "LA15_N": "AD24",
- "LA19_P": "AJ26",
- "LA19_N": "AK26",
- "LA21_P": "AG27",
- "LA21_N": "AG28",
- "LA24_P": "AG30",
- "LA24_N": "AH30",
- "LA28_P": "AE30",
- "LA28_N": "AF30",
- "LA30_P": "AB29",
- "LA30_N": "AB30",
- "LA32_P": "Y30",
- "LA32_N": "AA30",
- "LA06_P": "AK20",
- "LA06_N": "AK21",
- "LA10_P": "AJ24",
- "LA10_N": "AK25",
- "LA14_P": "AD21",
- "LA14_N": "AE21",
- "LA18_CC_P": "AD27",
- "LA18_CC_N": "AD28",
- "LA27_P": "AJ28",
- "LA27_N": "AJ29",
- "CLK1_M2C_P": "AG29",
- "CLK1_M2C_N": "AH29",
- "LA00_CC_P": "AD23",
- "LA00_CC_N": "AE24",
- "LA03_P": "AG20",
- "LA03_N": "AH20",
- "LA08_P": "AJ22",
- "LA08_N": "AJ23",
- "LA12_P": "AA20",
- "LA12_N": "AB20",
- "LA16_P": "AC22",
- "LA16_N": "AD22",
- "LA20_P": "AF26",
- "LA20_N": "AF27",
- "LA22_P": "AJ27",
- "LA22_N": "AK28",
- "LA25_P": "AC26",
- "LA25_N": "AD26",
- "LA29_P": "AE28",
- "LA29_N": "AF28",
- "LA31_P": "AD29",
- "LA31_N": "AE29",
- "LA33_P": "AC29",
- "LA33_N": "AC30",
- }
- )
-]
-
-
-class Platform(XilinxPlatform):
- identifier = 0x4B37
- default_clk_name = "clk156"
- default_clk_period = 6.4
-
- def __init__(self, toolchain="vivado", programmer="xc3sprog"):
- XilinxPlatform.__init__(self, "xc7k325t-ffg900-2", _io, _connectors,
- toolchain=toolchain)
- if toolchain == "ise":
- self.toolchain.bitgen_opt = "-g LCK_cycle:6 -g Binary:Yes -w -g ConfigRate:12 -g SPI_buswidth:4"
- elif toolchain == "vivado":
- self.toolchain.bitstream_commands = ["set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]"]
- self.toolchain.additional_commands = ["write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit \"up 0x0 {build_name}.bit\" -file {build_name}.bin"]
- self.programmer = programmer
-
- def create_programmer(self):
- if self.programmer == "xc3sprog":
- return XC3SProg("jtaghs1_fast", "bscan_spi_kc705.bit")
- elif self.programmer == "vivado":
- return VivadoProgrammer()
- elif self.programmer == "impact":
- return iMPACT()
- else:
- raise ValueError("{} programmer is not supported".format(programmer))
-
- def do_finalize(self, fragment):
- XilinxPlatform.do_finalize(self, fragment)
- try:
- self.add_period_constraint(self.lookup_request("clk200").p, 5.0)
- except ConstraintError:
- pass
- try:
- self.add_period_constraint(self.lookup_request("eth_clocks").rx, 8.0)
- except ConstraintError:
- pass
- if isinstance(self.toolchain, XilinxISEToolchain):
- self.add_platform_command("CONFIG DCI_CASCADE = \"33 32 34\";")
- else:
- self.add_platform_command("set_property DCI_CASCADE {{32 34}} [get_iobanks 33]")
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-_io = [
- ("user_btn", 0, Pins("V4"), IOStandard("LVCMOS33"),
- Misc("PULLDOWN"), Misc("TIG")),
-
- ("user_led", 0, Pins("P4"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")),
- ("user_led", 1, Pins("L6"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")),
- ("user_led", 2, Pins("F5"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")),
- ("user_led", 3, Pins("C2"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")),
-
- ("user_dip", 0, Pins("B3"), Misc("PULLDOWN"), IOStandard("LVCMOS33")),
- ("user_dip", 1, Pins("A3"), Misc("PULLDOWN"), IOStandard("LVCMOS33")),
- ("user_dip", 2, Pins("B4"), Misc("PULLDOWN"), IOStandard("LVCMOS33")),
- ("user_dip", 3, Pins("A4"), Misc("PULLDOWN"), IOStandard("LVCMOS33")),
-
- # TI CDCE913 programmable triple-output PLL
- ("clk_y1", 0, Pins("V10"), IOStandard("LVCMOS33")), # default: 40 MHz
- ("clk_y2", 0, Pins("K15"), IOStandard("LVCMOS33")), # default: 66 2/3 MHz
- ("clk_y3", 0, Pins("C10"), IOStandard("LVCMOS33")), # default: 100 MHz
-
- # Maxim DS1088LU oscillator, not populated
- ("clk_backup", 0, Pins("R8"), IOStandard("LVCMOS33")),
-
- # TI CDCE913 PLL I2C control
- ("pll", 0,
- Subsignal("scl", Pins("P12")),
- Subsignal("sda", Pins("U13")),
- Misc("PULLUP"),
- IOStandard("LVCMOS33")),
-
- # Micron N25Q128 SPI Flash
- ("spiflash", 0,
- Subsignal("clk", Pins("R15")),
- Subsignal("cs_n", Pins("V3")),
- Subsignal("dq", Pins("T13 R13 T14 V14")),
- IOStandard("LVCMOS33")),
-
- # PMOD extension connectors
- ("pmod", 0,
- Subsignal("d", Pins("F15 F16 C17 C18 F14 G14 D17 D18")),
- IOStandard("LVCMOS33")),
- ("pmod", 1,
- Subsignal("d", Pins("H12 G13 E16 E18 K12 K13 F17 F18")),
- IOStandard("LVCMOS33")),
-
- ("pmod_diff", 0,
- Subsignal("io", Pins("F15 C17 F14 D17 H12 E16 K12 F17")),
- Subsignal("iob", Pins("F16 C18 G14 D18 G13 E18 K13 F18")),
- IOStandard("LVCMOS33")),
-
- ("serial", 0,
- Subsignal("tx", Pins("T7"), Misc("SLEW=SLOW")),
- Subsignal("rx", Pins("R7"), Misc("PULLUP")),
- IOStandard("LVCMOS33")),
-
- ("ddram_clock", 0,
- Subsignal("p", Pins("G3")),
- Subsignal("n", Pins("G1")),
- IOStandard("MOBILE_DDR")), # actually DIFF_
-
- # Micron MT46H32M16LFBF-5 LPDDR
- ("ddram", 0,
- Subsignal("a", Pins("J7 J6 H5 L7 F3 H4 H3 H6 "
- "D2 D1 F4 D3 G6")),
- Subsignal("ba", Pins("F2 F1")),
- Subsignal("dq", Pins("L2 L1 K2 K1 H2 H1 J3 J1 "
- "M3 M1 N2 N1 T2 T1 U2 U1")),
- Subsignal("cke", Pins("H7")),
- Subsignal("we_n", Pins("E3")),
- Subsignal("cs_n", Pins("K6")), # NC!
- Subsignal("cas_n", Pins("K5")),
- Subsignal("ras_n", Pins("L5")),
- Subsignal("dm", Pins("K3", "K4")),
- Subsignal("dqs", Pins("L4", "P2")),
- Subsignal("rzq", Pins("N4")),
- IOStandard("MOBILE_DDR")),
-
- # Nat Semi DP83848J 10/100 Ethernet PHY
- # pull-ups on col and rx_data set phy addr to 11111b
- # and prevent isolate mode (addr 00000b)
- ("eth_clocks", 0,
- Subsignal("rx", Pins("L15")),
- Subsignal("tx", Pins("H17")),
- IOStandard("LVCMOS33")),
-
- ("eth", 0,
- Subsignal("col", Pins("M18"), Misc("PULLUP")),
- Subsignal("crs", Pins("N17"), Misc("PULLDOWN")),
- Subsignal("mdc", Pins("M16"), Misc("PULLDOWN")),
- Subsignal("mdio", Pins("L18"), Misc("PULLUP")), # 1k5 ext PULLUP
- Subsignal("rst_n", Pins("T18"), Misc("TIG")),
- Subsignal("rx_data", Pins("T17 N16 N15 P18"), Misc("PULLUP")),
- Subsignal("dv", Pins("P17"), Misc("PULLDOWN")), # MII
- Subsignal("rx_er", Pins("N18"), Misc("PULLUP")), # auto MDIX
- Subsignal("tx_data", Pins("K18 K17 J18 J16")),
- Subsignal("tx_en", Pins("L17")),
- Subsignal("tx_er", Pins("L16")), # NC!
- IOStandard("LVCMOS33")),
- ]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk_y3"
- default_clk_period = 10
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6slx9-2csg324", _io)
- self.add_platform_command("""
-CONFIG VCCAUX = "3.3";
-""")
- self.toolchain.bitgen_opt = "-g LCK_cycle:6 -g Binary:Yes -w -g SPI_buswidth:4"
- self.toolchain.ise_commands = """
-promgen -w -spi -c FF -p mcs -o {build_name}.mcs -u 0 {build_name}.bit
-"""
-
- def do_finalize(self, fragment):
- XilinxPlatform.do_finalize(self, fragment)
-
- try:
- eth_clocks = self.lookup_request("eth_clocks")
- self.add_period_constraint(eth_clocks.rx, 40)
- self.add_period_constraint(eth_clocks.tx, 40)
- self.add_platform_command("""
-TIMESPEC "TS{phy_tx_clk}_io" = FROM "GRP{phy_tx_clk}" TO "PADS" 10 ns;
-TIMESPEC "TS{phy_rx_clk}_io" = FROM "PADS" TO "GRP{phy_rx_clk}" 10 ns;
-""", phy_rx_clk=eth_clocks.rx, phy_tx_clk=eth_clocks.tx)
- except ConstraintError:
- pass
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-from migen.build.xilinx.programmer import UrJTAG
-
-
-_io = [
- ("user_led", 0, Pins("B16"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")),
- ("user_led", 1, Pins("A16"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")),
-
- ("user_btn", 0, Pins("AB4"), IOStandard("LVCMOS33")),
- ("user_btn", 1, Pins("AA4"), IOStandard("LVCMOS33")),
- ("user_btn", 2, Pins("AB5"), IOStandard("LVCMOS33")),
-
- ("clk50", 0, Pins("AB11"), IOStandard("LVCMOS33")),
-
- # When executing softcore code in-place from the flash, we want
- # the flash reset to be released before the system reset.
- ("norflash_rst_n", 0, Pins("P22"), IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8)),
- ("norflash", 0,
- Subsignal("adr", Pins("L22 L20 K22 K21 J19 H20 F22",
- "F21 K17 J17 E22 E20 H18 H19 F20",
- "G19 C22 C20 D22 D21 F19 F18 D20 D19")),
- Subsignal("d", Pins("AA20 U14 U13 AA6 AB6 W4 Y4 Y7",
- "AA2 AB2 V15 AA18 AB18 Y13 AA12 AB12"), Misc("PULLDOWN")),
- Subsignal("oe_n", Pins("M22")),
- Subsignal("we_n", Pins("N20")),
- Subsignal("ce_n", Pins("M21")),
- IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8)
- ),
-
- ("serial", 0,
- Subsignal("tx", Pins("L17"), IOStandard("LVCMOS33"), Misc("SLEW=SLOW")),
- Subsignal("rx", Pins("K18"), IOStandard("LVCMOS33"), Misc("PULLUP"))
- ),
-
- ("ddram_clock", 0,
- Subsignal("p", Pins("M3")),
- Subsignal("n", Pins("L4")),
- IOStandard("SSTL2_I")
- ),
- ("ddram", 0,
- Subsignal("a", Pins("B1 B2 H8 J7 E4 D5 K7 F5 G6 C1 C3 D1 D2")),
- Subsignal("ba", Pins("A2 E6")),
- Subsignal("cs_n", Pins("F7")),
- Subsignal("cke", Pins("G7")),
- Subsignal("ras_n", Pins("E5")),
- Subsignal("cas_n", Pins("C4")),
- Subsignal("we_n", Pins("D3")),
- Subsignal("dq", Pins("Y2 W3 W1 P8 P7 P6 P5 T4 T3",
- "U4 V3 N6 N7 M7 M8 R4 P4 M6 L6 P3 N4",
- "M5 V2 V1 U3 U1 T2 T1 R3 R1 P2 P1")),
- Subsignal("dm", Pins("E1 E3 F3 G4")),
- Subsignal("dqs", Pins("F1 F2 H5 H6")),
- IOStandard("SSTL2_I")
- ),
-
- ("eth_clocks", 0,
- Subsignal("phy", Pins("M20")),
- Subsignal("rx", Pins("H22")),
- Subsignal("tx", Pins("H21")),
- IOStandard("LVCMOS33")
- ),
- ("eth", 0,
- Subsignal("rst_n", Pins("R22")),
- Subsignal("dv", Pins("V21")),
- Subsignal("rx_er", Pins("V22")),
- Subsignal("rx_data", Pins("U22 U20 T22 T21")),
- Subsignal("tx_en", Pins("N19")),
- Subsignal("tx_er", Pins("M19")),
- Subsignal("tx_data", Pins("M16 L15 P19 P20")),
- Subsignal("col", Pins("W20")),
- Subsignal("crs", Pins("W22")),
- IOStandard("LVCMOS33")
- ),
-
- ("vga_out", 0,
- Subsignal("clk", Pins("A11")),
- Subsignal("r", Pins("C6 B6 A6 C7 A7 B8 A8 D9")),
- Subsignal("g", Pins("C8 C9 A9 D7 D8 D10 C10 B10")),
- Subsignal("b", Pins("D11 C12 B12 A12 C13 A13 D14 C14")),
- Subsignal("hsync_n", Pins("A14")),
- Subsignal("vsync_n", Pins("C15")),
- Subsignal("psave_n", Pins("B14")),
- IOStandard("LVCMOS33")
- ),
-
- ("mmc", 0,
- Subsignal("clk", Pins("A10")),
- Subsignal("cmd", Pins("B18")),
- Subsignal("dat", Pins("A18 E16 C17 A17")),
- IOStandard("LVCMOS33")
- ),
-
- # Digital video mixer extension board
- ("dvi_in", 0,
- Subsignal("clk", Pins("A20")),
- Subsignal("data0_n", Pins("A21")),
- Subsignal("data1", Pins("B21")),
- Subsignal("data2_n", Pins("B22")),
- Subsignal("scl", Pins("G16")),
- Subsignal("sda", Pins("G17")),
- IOStandard("LVCMOS33")
- ),
- ("dvi_in", 1,
- Subsignal("clk", Pins("H17")),
- Subsignal("data0_n", Pins("H16")),
- Subsignal("data1", Pins("F17")),
- Subsignal("data2_n", Pins("F16")),
- Subsignal("scl", Pins("J16")),
- Subsignal("sda", Pins("K16")),
- IOStandard("LVCMOS33")
- ),
- ("dvi_pots", 0,
- Subsignal("charge", Pins("A18")), # SD_DAT0
- Subsignal("blackout", Pins("C17")), # SD_DAT2
- Subsignal("crossfade", Pins("A17")), # SD_DAT3
- IOStandard("LVCMOS33")
- )
-]
-
-
-class Platform(XilinxPlatform):
- identifier = 0x4D31
- default_clk_name = "clk50"
- default_clk_period = 20
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6slx45-fgg484-2", _io)
-
- def create_programmer(self):
- return UrJTAG(cable="milkymist", flash_proxy_basename="fjmem-m1.bit")
-
- def do_finalize(self, fragment):
- XilinxPlatform.do_finalize(self, fragment)
-
- try:
- eth_clocks = self.lookup_request("eth_clocks")
- self.add_period_constraint(eth_clocks.rx, 40)
- self.add_period_constraint(eth_clocks.tx, 40)
- self.add_platform_command("""
-TIMESPEC "TS{phy_tx_clk}_io" = FROM "GRP{phy_tx_clk}" TO "PADS" 10 ns;
-TIMESPEC "TS{phy_rx_clk}_io" = FROM "PADS" TO "GRP{phy_rx_clk}" 10 ns;
-""", phy_rx_clk=eth_clocks.rx, phy_tx_clk=eth_clocks.tx)
- except ConstraintError:
- pass
-
- for i in range(2):
- si = "dviclk"+str(i)
- try:
- self.add_period_constraint(self.lookup_request("dvi_in", i).clk, 26.7)
- except ConstraintError:
- pass
+++ /dev/null
-# This file is Copyright (c) 2015 William D. Jones <thor0505@comcast.net>
-# License: BSD
-
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-from migen.build.xilinx.programmer import XC3SProg
-
-
-_io = [
- ("clk50", 0, Pins("P43"), IOStandard("LVCMOS33")),
-
- ("user_btn", 0, Pins("P41"), IOStandard("LVTTL")),
-
- # The serial interface and flash memory have a shared SPI bus.
- # FPGA is secondary
- ("spiserial", 0,
- Subsignal("cs_n", Pins("P39"), IOStandard("LVTTL")),
- Subsignal("clk", Pins("P53"), IOStandard("LVTTL")),
- Subsignal("mosi", Pins("P46"), IOStandard("LVTTL")),
- Subsignal("miso", Pins("P51"), IOStandard("LVTTL"))
- ),
-
- # FPGA is primary
- ("spiflash", 0,
- Subsignal("cs_n", Pins("P27"), IOStandard("LVTTL")),
- Subsignal("clk", Pins("P53"), IOStandard("LVTTL")),
- Subsignal("mosi", Pins("P46"), IOStandard("LVTTL")),
- Subsignal("miso", Pins("P51"), IOStandard("LVTTL"))
- ),
-
- ("spiflash2x", 0,
- Subsignal("cs_n", Pins("P27")),
- Subsignal("clk", Pins("P53")),
- Subsignal("dq", Pins("P46", "P51")),
- IOStandard("LVTTL"), Misc("SLEW=FAST")
- ),
-
- # ADC over SPI- FPGA is primary
- ("adc", 0,
- Subsignal("cs_n", Pins("P12"), IOStandard("LVTTL")),
- Subsignal("clk", Pins("P9"), IOStandard("LVTTL")),
- Subsignal("mosi", Pins("P10"), IOStandard("LVTTL")),
- Subsignal("miso", Pins("P21"), IOStandard("LVTTL"))
- ),
-
- # GPIO control- SRAM and connectors are shared: these pins control how
- # to access each. Recommended to combine with gpio_sram_bus extension,
- # since these pins are related but not exposed on connectors.
- ("gpio_ctl", 0,
- Subsignal("ce_n", Pins("P3")), # Memory chip-enable. Called MEM_CEN
- # in schematic.
- Subsignal("bussw_oe_n", Pins("P30")), # 5V tolerant GPIO is shared
- # w/ memory using this pin.
- IOStandard("LVTTL"), Misc("SLEW=FAST")
- )
-]
-
-# Perhaps define some connectors as having a specific purpose- i.e. a 5V GPIO
-# bus with data, peripheral-select, and control signals?
-_connectors = [
- ("GPIO", """P59 P60 P61 P62 P64 P57
- P56 P52 P50 P49 P85 P84
- P83 P78 P77 P65 P70 P71
- P72 P73 P5 P4 P6 P98
- P94 P93 P90 P89 P88 P86"""), # 5V I/O- LVTTL
- ("DIO", "P20 P32 P33 P34 P35 P36 P37"), # Fast 3.3V IO (Directly attached
- # to FPGA)- LVCMOS33
- ("CLKIO", "P40 P44"), # Clock IO (Can be used as GPIO)- LVCMOS33
- ("INPUT", "P68 P97 P7 P82"), # Input-only pins- LVCMOS33
- ("LED", "P13 P15 P16 P19") # LEDs can be used as pins as well- LVTTL.
-]
-
-# Some default useful extensions- use platform.add_extension() to use, e.g.
-# from migen.build.platforms import mercury
-# plat = mercury.Platform()
-# plat.add_extension(mercury.gpio_sram)
-
-# SRAM and 5V-tolerant I/O share a parallel bus on 200k gate version. The SRAM
-# controller needs to take care of switching the bus between the two. Meant to
-# be Cat() into one GPIO bus, and combined with gpio_ctl.
-gpio_sram = [
- ("gpio_sram_bus", 0,
- Subsignal("a", Pins("""GPIO:0 GPIO:1 GPIO:2 GPIO:3
- GPIO:4 GPIO:5 GPIO:6 GPIO:7
- GPIO:8 GPIO:9 GPIO:10 GPIO:11
- GPIO:12 GPIO:13 GPIO:14 GPIO:15
- GPIO:16 GPIO:17 GPIO:18 GPIO:19""")),
- # A19 is actually unused- free for GPIO
- # 8-bit data bus
- Subsignal("d", Pins("""GPIO:20 GPIO:21 GPIO:22 GPIO:23
- GPIO:24 GPIO:25 GPIO:26 GPIO:27""")),
- Subsignal("we_n", Pins("GPIO:28")),
- Subsignal("unused", Pins("GPIO:29")), # Only used by GPIO.
- # Subsignal("oe_n", Pins()), # If OE wasn't tied to ground on Mercury,
- # this pin would be here.
- IOStandard("LVTTL"), Misc("SLEW=FAST")
- )
-]
-
-# The "serial port" is in fact over SPI. The creators of the board provide a
-# VHDL file for talking over this interface. In light of space constraints and
-# the fact that both the FT245RL and FPGA can BOTH be SPI primaries, however,
-# it may be necessary to sacrifice two "high-speed" (DIO, INPUT) pins instead.
-serial = [
- ("serial", 0,
- Subsignal("tx", Pins("DIO:0"), IOStandard("LVCMOS33")), # FTDI D1
- Subsignal("rx", Pins("INPUT:0"), IOStandard("LVCMOS33"))
- ) # FTDI D0
-]
-
-leds = [
- ("user_led", 0, Pins("LED:0"), IOStandard("LVTTL")),
- ("user_led", 1, Pins("LED:1"), IOStandard("LVTTL")),
- ("user_led", 2, Pins("LED:2"), IOStandard("LVTTL")),
- ("user_led", 3, Pins("LED:3"), IOStandard("LVTTL"))
-]
-
-# See: http://www.micro-nova.com/mercury-baseboard/
-# Not implemented yet.
-baseboard = [
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk50"
- default_clk_period = 20
-
- def __init__(self, device="xc3s200a-4-vq100"):
- XilinxPlatform.__init__(self, device, _io, _connectors)
- # Small device- optimize for AREA instead of SPEED (LM32 runs at about
- # 60-65MHz in AREA configuration).
- self.toolchain.xst_opt = """-ifmt MIXED
--use_new_parser yes
--opt_mode AREA
--register_balancing yes"""
-
- def create_programmer(self):
- raise NotImplementedError
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-_io = [
- ("clk100", 0, Pins("V10"), IOStandard("LVCMOS33")),
- ("clk12", 0, Pins("D9"), IOStandard("LVCMOS33")),
-
- ("serial", 0,
- Subsignal("tx", Pins("A8"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST")),
- Subsignal("rx", Pins("B8"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST"))),
-
- ("spiflash", 0,
- Subsignal("cs_n", Pins("V3")),
- Subsignal("clk", Pins("R15")),
- Subsignal("mosi", Pins("T13")),
- Subsignal("miso", Pins("R13"), Misc("PULLUP")),
- IOStandard("LVCMOS33"), Misc("SLEW=FAST")),
-
- ("ddram_clock", 0,
- Subsignal("p", Pins("G3")),
- Subsignal("n", Pins("G1")),
- IOStandard("MOBILE_DDR")),
-
- ("ddram", 0,
- Subsignal("a", Pins("J7 J6 H5 L7 F3 H4 H3 H6 D2 D1 F4 D3 G6")),
- Subsignal("ba", Pins("F2 F1")),
- Subsignal("cke", Pins("H7")),
- Subsignal("ras_n", Pins("L5")),
- Subsignal("cas_n", Pins("K5")),
- Subsignal("we_n", Pins("E3")),
- Subsignal(
- "dq", Pins("L2 L1 K2 K1 H2 H1 J3 J1 M3 M1 N2 N1 T2 T1 U2 U1")
- ),
- Subsignal("dqs", Pins("L4 P2")),
- Subsignal("dm", Pins("K3 K4")),
- IOStandard("MOBILE_DDR")),
-
- ("dipswitch", 0, Pins("C17"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("dipswitch", 1, Pins("C18"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("dipswitch", 2, Pins("D17"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("dipswitch", 3, Pins("D18"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("dipswitch", 4, Pins("E18"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("dipswitch", 5, Pins("E16"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("dipswitch", 6, Pins("F18"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("dipswitch", 7, Pins("F17"), IOStandard("LVCMOS33"), Misc("PULLUP")),
-
- ("buttonswitch", 0, Pins("K18"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("buttonswitch", 1, Pins("K17"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("buttonswitch", 2, Pins("L17"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("buttonswitch", 3, Pins("M16"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("buttonswitch", 4, Pins("L18"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("buttonswitch", 5, Pins("M18"), IOStandard("LVCMOS33"), Misc("PULLUP")),
-
- ("user_led", 0, Pins("T18"), IOStandard("LVCMOS33"), Drive(8)),
- ("user_led", 1, Pins("T17"), IOStandard("LVCMOS33"), Drive(8)),
- ("user_led", 2, Pins("U18"), IOStandard("LVCMOS33"), Drive(8)),
- ("user_led", 3, Pins("U17"), IOStandard("LVCMOS33"), Drive(8)),
- ("user_led", 4, Pins("N16"), IOStandard("LVCMOS33"), Drive(8)),
- ("user_led", 5, Pins("N15"), IOStandard("LVCMOS33"), Drive(8)),
- ("user_led", 6, Pins("P16"), IOStandard("LVCMOS33"), Drive(8)),
- ("user_led", 7, Pins("P15"), IOStandard("LVCMOS33"), Drive(8)),
-
- ("mmc", 0,
- Subsignal("dat", Pins("K14 G18 J13 L13"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST")),
-
- Subsignal("cmd", Pins("G16"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST")),
-
- Subsignal("clk", Pins("L12"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST"))),
-
- ("sevenseg", 0,
- Subsignal("segment7", Pins("A3"), IOStandard("LVCMOS33")), # A
- Subsignal("segment6", Pins("B4"), IOStandard("LVCMOS33")), # B
- Subsignal("segment5", Pins("A4"), IOStandard("LVCMOS33")), # C
- Subsignal("segment4", Pins("C4"), IOStandard("LVCMOS33")), # D
- Subsignal("segment3", Pins("C5"), IOStandard("LVCMOS33")), # E
- Subsignal("segment2", Pins("D6"), IOStandard("LVCMOS33")), # F
- Subsignal("segment1", Pins("C6"), IOStandard("LVCMOS33")), # G
- Subsignal("segment0", Pins("A5"), IOStandard("LVCMOS33")), # Dot
- Subsignal("enable0", Pins("B2"), IOStandard("LVCMOS33")), # EN0
- Subsignal("enable1", Pins("A2"), IOStandard("LVCMOS33")), # EN1
- Subsignal("enable2", Pins("B3"), IOStandard("LVCMOS33"))), # EN2
-
-
- ("audio", 0,
- Subsignal("channel1", Pins("B16"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST")),
- Subsignal("channel2", Pins("A16"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST"))),
-
- ("vga_out", 0,
- Subsignal("hsync_n", Pins("B12"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST")),
- Subsignal("vsync_n", Pins("A12"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST")),
- Subsignal("r", Pins("A9 B9 C9"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST")),
- Subsignal("g", Pins("C10 A10 C11"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST")),
- Subsignal("b", Pins("B11 A11"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST")))
-]
-
-_connectors = [
- ("P6", "T3 R3 V5 U5 V4 T4 V7 U7"),
- ("P7", "V11 U11 V13 U13 T10 R10 T11 R11"),
- ("P8", "L16 L15 K16 K15 J18 J16 H18 H17")
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk100"
- default_clk_period = 10
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6slx9-csg324-2", _io, _connectors)
-
- def create_programmer(self):
- raise NotImplementedError
+++ /dev/null
-# This file is Copyright (c) 2015 Matt O'Gorman <mog@rldn.net>
-# License: BSD
-
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-from migen.build.xilinx.programmer import XC3SProg, FpgaProg
-
-
-_io = [
- ("user_led", 0, Pins("P11"), IOStandard("LVCMOS33")),
- ("user_led", 1, Pins("N9"), IOStandard("LVCMOS33")),
- ("user_led", 2, Pins("M9"), IOStandard("LVCMOS33")),
- ("user_led", 3, Pins("P9"), IOStandard("LVCMOS33")),
- ("user_led", 4, Pins("T8"), IOStandard("LVCMOS33")),
- ("user_led", 5, Pins("N8"), IOStandard("LVCMOS33")),
- ("user_led", 6, Pins("P8"), IOStandard("LVCMOS33")),
- ("user_led", 7, Pins("P7"), IOStandard("LVCMOS33")),
-
- ("user_sw", 0, Pins("L1"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("user_sw", 1, Pins("L3"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("user_sw", 2, Pins("L4"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("user_sw", 3, Pins("L5"), IOStandard("LVCMOS33"), Misc("PULLUP")),
-
- ("clk32", 0, Pins("J4"), IOStandard("LVCMOS33")),
- ("clk50", 0, Pins("K3"), IOStandard("LVCMOS33")),
-
- ("spiflash", 0,
- Subsignal("cs_n", Pins("T3"), IOStandard("LVCMOS33")),
- Subsignal("clk", Pins("R11"), IOStandard("LVCMOS33")),
- Subsignal("mosi", Pins("T10"), IOStandard("LVCMOS33")),
- Subsignal("miso", Pins("P10"), IOStandard("LVCMOS33"))
- ),
-
- ("adc", 0,
- Subsignal("cs_n", Pins("F6"), IOStandard("LVCMOS33")),
- Subsignal("clk", Pins("G6"), IOStandard("LVCMOS33")),
- Subsignal("mosi", Pins("H4"), IOStandard("LVCMOS33")),
- Subsignal("miso", Pins("H5"), IOStandard("LVCMOS33"))
- ),
-
- ("serial", 0,
- Subsignal("tx", Pins("N6"), IOStandard("LVCMOS33")), # FTDI D1
- Subsignal("rx", Pins("M7"), IOStandard("LVCMOS33")) # FTDI D0
- ),
-
- ("audio", 0,
- Subsignal("a0", Pins("B8"), IOStandard("LVCMOS33")),
- Subsignal("a1", Pins("A8"), IOStandard("LVCMOS33"))
- ),
-
- ("sdram_clock", 0, Pins("G16"), IOStandard("LVCMOS33"), Misc("SLEW=FAST")),
- ("sdram", 0,
- Subsignal("a", Pins("T15 R16 P15 P16 N16 M15 M16 L16 K15 K16 R15 J16 H15")),
- Subsignal("dq", Pins("T13 T12 R12 T9 R9 T7 R7 T6 F16 E15 E16 D16 B16 B15 C16 C15")),
- Subsignal("we_n", Pins("R5")),
- Subsignal("ras_n", Pins("R2")),
- Subsignal("cas_n", Pins("T4")),
- Subsignal("cs_n", Pins("R1")),
- Subsignal("cke", Pins("H16")),
- Subsignal("ba", Pins("R14 T14")),
- Subsignal("dm", Pins("T5 F15")),
- IOStandard("LVCMOS33"), Misc("SLEW=FAST")
- ),
-
- ("usb_fifo", 0,
- Subsignal("data", Pins("M7 N6 M6 P5 N5 P4 P2 P1")),
- Subsignal("rxf_n", Pins("N3")),
- Subsignal("txe_n", Pins("N1")),
- Subsignal("rd_n", Pins("M1")),
- Subsignal("wr_n", Pins("M2")),
- Subsignal("siwua", Pins("M3")),
- IOStandard("LVCMOS33"), Drive(8), Misc("SLEW=FAST")
- ),
-
- ("sd", 0,
- Subsignal("sck", Pins("L12")),
- Subsignal("d3", Pins("K12")),
- Subsignal("d", Pins("M10")),
- Subsignal("d1", Pins("L10")),
- Subsignal("d2", Pins("J11")),
- Subsignal("cmd", Pins("K11")),
- IOStandard("LVCMOS33")
- ),
-
- ("dvi_in", 0,
- Subsignal("clk_p", Pins("C9"), IOStandard("TMDS_33")),
- Subsignal("clk_n", Pins("A9"), IOStandard("TMDS_33")),
- Subsignal("data_p", Pins("C7 B6 B5"), IOStandard("TMDS_33")),
- Subsignal("data_n", Pins("A7 A6 A5"), IOStandard("TMDS_33")),
- Subsignal("scl", Pins("C1"), IOStandard("LVCMOS33")),
- Subsignal("sda", Pins("B1"), IOStandard("LVCMOS33"))
- ),
-
- ("dvi_out", 0,
- Subsignal("clk_p", Pins("B14"), IOStandard("TMDS_33")),
- Subsignal("clk_n", Pins("A14"), IOStandard("TMDS_33")),
- Subsignal("data_p", Pins("C13 B12 C11"), IOStandard("TMDS_33")),
- Subsignal("data_n", Pins("A13 A12 A11"), IOStandard("TMDS_33")),
- )
-]
-
-_connectors = [
- ("A", "E7 C8 D8 E8 D9 A10 B10 C10 E10 F9 F10 D11"),
- ("B", "E11 D14 D12 E12 E13 F13 F12 F14 G12 H14 J14"),
- ("C", "J13 J12 K14 L14 L13 M14 M13 N14 M12 N12 P12 M11"),
- ("D", "D6 C6 E6 C5"),
- ("E", "D5 A4 G5 A3 B3 A2 B2 C3 C2 D3 D1 E3"),
- ("F", "E2 E1 E4 F4 F5 G3 F3 G1 H3 H1 H2 J1")
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk32"
- default_clk_period = 31.25
-
- def __init__(self, device="xc6slx9", programmer="xc3sprog"):
- self.programmer = programmer
- XilinxPlatform.__init__(self, device+"-3-ftg256", _io, _connectors)
-
- def create_programmer(self):
- if self.programmer == "xc3sprog":
- return XC3SProg("minispartan6", "bscan_spi_minispartan6.bit")
- elif self.programmer == "fpgaprog":
- return FpgaProg()
- else:
- raise ValueError("{} programmer is not supported".format(programmer))
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-from migen.build.xilinx.programmer import UrJTAG
-
-
-_io = [
- ("user_led", 0, Pins("V5"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")),
-
- ("clk50", 0, Pins("AB13"), IOStandard("LVCMOS33")),
-
- # When executing softcore code in-place from the flash, we want
- # the flash reset to be released before the system reset.
- ("norflash_rst_n", 0, Pins("P22"), IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8)),
- ("norflash", 0,
- Subsignal("adr", Pins("L22 L20 K22 K21 J19 H20 F22",
- "F21 K17 J17 E22 E20 H18 H19 F20",
- "G19 C22 C20 D22 D21 F19 F18 D20 D19")),
- Subsignal("d", Pins("AA20 U14 U13 AA6 AB6 W4 Y4 Y7",
- "AA2 AB2 V15 AA18 AB18 Y13 AA12 AB12"), Misc("PULLDOWN")),
- Subsignal("oe_n", Pins("M22")),
- Subsignal("we_n", Pins("N20")),
- Subsignal("ce_n", Pins("M21")),
- IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8)
- ),
-
- ("serial", 0,
- Subsignal("tx", Pins("L17"), IOStandard("LVCMOS33"), Misc("SLEW=SLOW")),
- Subsignal("rx", Pins("K18"), IOStandard("LVCMOS33"), Misc("PULLUP"))
- ),
-
- ("ddram_clock", 0,
- Subsignal("p", Pins("M3")),
- Subsignal("n", Pins("L4")),
- IOStandard("SSTL2_I")
- ),
- ("ddram", 0,
- Subsignal("a", Pins("B1 B2 H8 J7 E4 D5 K7 F5 G6 C1 C3 D1 D2")),
- Subsignal("ba", Pins("A2 E6")),
- Subsignal("cs_n", Pins("F7")),
- Subsignal("cke", Pins("G7")),
- Subsignal("ras_n", Pins("E5")),
- Subsignal("cas_n", Pins("C4")),
- Subsignal("we_n", Pins("D3")),
- Subsignal("dq", Pins("Y2 W3 W1 P8 P7 P6 P5 T4 T3",
- "U4 V3 N6 N7 M7 M8 R4 P4 M6 L6 P3 N4",
- "M5 V2 V1 U3 U1 T2 T1 R3 R1 P2 P1")),
- Subsignal("dm", Pins("E1 E3 F3 G4")),
- Subsignal("dqs", Pins("F1 F2 H5 H6")),
- IOStandard("SSTL2_I")
- ),
-
- ("eth_clocks", 0,
- Subsignal("phy", Pins("M20")),
- Subsignal("rx", Pins("H22")),
- Subsignal("tx", Pins("H21")),
- IOStandard("LVCMOS33")
- ),
- ("eth", 0,
- Subsignal("rst_n", Pins("R22")),
- Subsignal("dv", Pins("V21")),
- Subsignal("rx_er", Pins("V22")),
- Subsignal("rx_data", Pins("U22 U20 T22 T21")),
- Subsignal("tx_en", Pins("N19")),
- Subsignal("tx_er", Pins("M19")),
- Subsignal("tx_data", Pins("M16 L15 P19 P20")),
- Subsignal("col", Pins("W20")),
- Subsignal("crs", Pins("W22")),
- IOStandard("LVCMOS33")
- ),
-
- ("vga_out", 0,
- Subsignal("clk", Pins("A10")),
- Subsignal("r", Pins("C6 B6 A6 C7 A7 B8 A8 D9")),
- Subsignal("g", Pins("C8 C9 A9 D7 D8 D10 C10 B10")),
- Subsignal("b", Pins("D11 C12 B12 A12 C13 A13 D14 C14")),
- Subsignal("hsync_n", Pins("A14")),
- Subsignal("vsync_n", Pins("C15")),
- Subsignal("psave_n", Pins("B14")),
- IOStandard("LVCMOS33")
- ),
- ("dvi_out", 0,
- Subsignal("clk_p", Pins("W12"), IOStandard("TMDS_33")),
- Subsignal("clk_n", Pins("Y12"), IOStandard("TMDS_33")),
- Subsignal("data0_p", Pins("Y16"), IOStandard("TMDS_33")),
- Subsignal("data0_n", Pins("W15"), IOStandard("TMDS_33")),
- Subsignal("data1_p", Pins("AA16"), IOStandard("TMDS_33")),
- Subsignal("data1_n", Pins("AB16"), IOStandard("TMDS_33")),
- Subsignal("data2_p", Pins("Y15"), IOStandard("TMDS_33")),
- Subsignal("data2_n", Pins("AB15"), IOStandard("TMDS_33")),
- ),
-
- ("mmc", 0,
- Subsignal("clk", Pins("J3")),
- Subsignal("cmd", Pins("K1")),
- Subsignal("dat", Pins("J6 K6 N1 K5")),
- IOStandard("LVCMOS33")
- ),
-
- ("dvi_in", 0,
- Subsignal("clk_p", Pins("K20"), IOStandard("TMDS_33")),
- Subsignal("clk_n", Pins("K19"), IOStandard("TMDS_33")),
- Subsignal("data0_p", Pins("B21"), IOStandard("TMDS_33")),
- Subsignal("data0_n", Pins("B22"), IOStandard("TMDS_33")),
- Subsignal("data1_p", Pins("A20"), IOStandard("TMDS_33")),
- Subsignal("data1_n", Pins("A21"), IOStandard("TMDS_33")),
- Subsignal("data2_p", Pins("K16"), IOStandard("TMDS_33")),
- Subsignal("data2_n", Pins("J16"), IOStandard("TMDS_33")),
- Subsignal("scl", Pins("G20"), IOStandard("LVCMOS33")),
- Subsignal("sda", Pins("H16"), IOStandard("LVCMOS33")),
- Subsignal("hpd_notif", Pins("G22"), IOStandard("LVCMOS33")),
- Subsignal("hpd_en", Pins("G17"), IOStandard("LVCMOS33"))
- ),
- ("dvi_in", 1,
- Subsignal("clk_p", Pins("C11"), IOStandard("TMDS_33")),
- Subsignal("clk_n", Pins("A11"), IOStandard("TMDS_33")),
- Subsignal("data0_p", Pins("B18"), IOStandard("TMDS_33")),
- Subsignal("data0_n", Pins("A18"), IOStandard("TMDS_33")),
- Subsignal("data1_p", Pins("C17"), IOStandard("TMDS_33")),
- Subsignal("data1_n", Pins("A17"), IOStandard("TMDS_33")),
- Subsignal("data2_p", Pins("E16"), IOStandard("TMDS_33")),
- Subsignal("data2_n", Pins("D17"), IOStandard("TMDS_33")),
- Subsignal("scl", Pins("F17"), IOStandard("LVCMOS33")),
- Subsignal("sda", Pins("F16"), IOStandard("LVCMOS33")),
- Subsignal("hpd_notif", Pins("G16"), IOStandard("LVCMOS33")),
- Subsignal("hpd_en", Pins("B20"), IOStandard("LVCMOS33"))
- ),
- ("dvi_in", 2,
- Subsignal("clk_p", Pins("Y11"), IOStandard("TMDS_33")),
- Subsignal("clk_n", Pins("AB11"), IOStandard("TMDS_33")),
- Subsignal("data0_p", Pins("V11"), IOStandard("TMDS_33")),
- Subsignal("data0_n", Pins("W11"), IOStandard("TMDS_33")),
- Subsignal("data1_p", Pins("AA10"), IOStandard("TMDS_33")),
- Subsignal("data1_n", Pins("AB10"), IOStandard("TMDS_33")),
- Subsignal("data2_p", Pins("R11"), IOStandard("TMDS_33")),
- Subsignal("data2_n", Pins("T11"), IOStandard("TMDS_33")),
- Subsignal("scl", Pins("C16"), IOStandard("LVCMOS33")),
- Subsignal("sda", Pins("B16"), IOStandard("LVCMOS33")),
- Subsignal("hpd_notif", Pins("D6"), IOStandard("LVCMOS33")),
- Subsignal("hpd_en", Pins("A4"), IOStandard("LVCMOS33"))
- ),
- ("dvi_in", 3,
- Subsignal("clk_p", Pins("J20"), IOStandard("TMDS_33")),
- Subsignal("clk_n", Pins("J22"), IOStandard("TMDS_33")),
- Subsignal("data0_p", Pins("P18"), IOStandard("TMDS_33")),
- Subsignal("data0_n", Pins("R19"), IOStandard("TMDS_33")),
- Subsignal("data1_p", Pins("P17"), IOStandard("TMDS_33")),
- Subsignal("data1_n", Pins("N16"), IOStandard("TMDS_33")),
- Subsignal("data2_p", Pins("M17"), IOStandard("TMDS_33")),
- Subsignal("data2_n", Pins("M18"), IOStandard("TMDS_33")),
- Subsignal("scl", Pins("P21"), IOStandard("LVCMOS33")),
- Subsignal("sda", Pins("N22"), IOStandard("LVCMOS33")),
- Subsignal("hpd_notif", Pins("H17"), IOStandard("LVCMOS33")),
- Subsignal("hpd_en", Pins("C19"), IOStandard("LVCMOS33"))
- ),
-]
-
-
-class Platform(XilinxPlatform):
- identifier = 0x4D58
- default_clk_name = "clk50"
- default_clk_period = 20
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6slx45-fgg484-2", _io)
- self.add_platform_command("CONFIG VCCAUX=\"3.3\";\n")
-
- def create_programmer(self):
- return UrJTAG("fjmem-mixxeo.bit")
-
- def do_finalize(self, fragment):
- XilinxPlatform.do_finalize(self, fragment)
-
- try:
- eth_clocks = self.lookup_request("eth_clocks")
- self.add_period_constraint(eth_clocks.rx, 40)
- self.add_period_constraint(eth_clocks.tx, 40)
- self.add_platform_command("""
-TIMESPEC "TS{phy_tx_clk}_io" = FROM "GRP{phy_tx_clk}" TO "PADS" 10 ns;
-TIMESPEC "TS{phy_rx_clk}_io" = FROM "PADS" TO "GRP{phy_rx_clk}" 10 ns;
-""", phy_rx_clk=eth_clocks.rx, phy_tx_clk=eth_clocks.tx)
- except ConstraintError:
- pass
-
- for i in range(4):
- try:
- self.add_period_constraint(self.lookup_request("dvi_in", i).clk_p, 12)
- except ConstraintError:
- pass
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-_io = [
- # System clock (Differential 200MHz)
- ("clk200", 0,
- Subsignal("p", Pins("J9"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")),
- Subsignal("n", Pins("H9"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE"))
- ),
-
- # User clock (66MHz)
- ("clk66", 0, Pins("U23"), IOStandard("LVCMOS25")),
-
- # CPU reset switch
- ("cpu_reset", 0, Pins("H10"), IOStandard("SSTL15")),
-
- # LEDs
- ("user_led", 0, Pins("AC22"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")),
- ("user_led", 1, Pins("AC24"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")),
- ("user_led", 2, Pins("AE22"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")),
- ("user_led", 3, Pins("AE23"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")),
- ("user_led", 4, Pins("AB23"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")),
- ("user_led", 5, Pins("AG23"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")),
- ("user_led", 6, Pins("AE24"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")),
- ("user_led", 7, Pins("AD24"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")),
-
- # USB-to-UART
- ("serial", 0,
- Subsignal("tx", Pins("J25"), IOStandard("LVCMOS25")),
- Subsignal("rx", Pins("J24"), IOStandard("LVCMOS25"))
- ),
-
- # 10/100/1000 Tri-Speed Ethernet PHY
- ("eth_clocks", 0,
- Subsignal("rx", Pins("AP11")),
- Subsignal("tx", Pins("AD12")),
- IOStandard("LVCMOS25")
- ),
- ("eth", 0,
- Subsignal("rst_n", Pins("AH13")),
- Subsignal("dv", Pins("AM13")),
- Subsignal("rx_er", Pins("AG12")),
- Subsignal("rx_data", Pins("AN13 AF14 AE14 AN12 AM12 AD11 AC12 AC13")),
- Subsignal("tx_en", Pins("AJ10")),
- Subsignal("tx_er", Pins("AH10")),
- Subsignal("tx_data", Pins("AM11 AL11 AG10 AG11 AL10 AM10 AE11 AF11")),
- Subsignal("col", Pins("AK13")),
- Subsignal("crs", Pins("AL13")),
- IOStandard("LVCMOS25")
- )
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk200"
- default_clk_period = 5
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6vlx240t-ff1156-1", _io)
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-from migen.build.xilinx.programmer import XC3SProg
-
-
-_io = [
- ("user_led", 0, Pins("P112"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")),
-
- ("clk32", 0, Pins("P94"), IOStandard("LVCMOS33")),
-
- ("serial", 0,
- Subsignal("tx", Pins("P105"), IOStandard("LVCMOS33"), Misc("SLEW=SLOW")),
- Subsignal("rx", Pins("P101"), IOStandard("LVCMOS33"), Misc("PULLUP"))
- ),
-
- ("spiflash", 0,
- Subsignal("cs_n", Pins("P38")),
- Subsignal("clk", Pins("P70")),
- Subsignal("mosi", Pins("P64")),
- Subsignal("miso", Pins("P65"), Misc("PULLUP")),
- IOStandard("LVCMOS33"), Misc("SLEW=FAST")
- ),
- ("spiflash2x", 0,
- Subsignal("cs_n", Pins("P38")),
- Subsignal("clk", Pins("P70")),
- Subsignal("dq", Pins("P64", "P65")),
- IOStandard("LVCMOS33"), Misc("SLEW=FAST")
- ),
-
- ("sdram_clock", 0, Pins("P32"), IOStandard("LVCMOS33"), Misc("SLEW=FAST")),
- ("sdram", 0,
- Subsignal("a", Pins("P140 P139 P138 P137 P46 P45 P44",
- "P43 P41 P40 P141 P35 P34")),
- Subsignal("ba", Pins("P143 P142")),
- Subsignal("cs_n", Pins("P1")),
- Subsignal("cke", Pins("P33")),
- Subsignal("ras_n", Pins("P2")),
- Subsignal("cas_n", Pins("P5")),
- Subsignal("we_n", Pins("P6")),
- Subsignal("dq", Pins("P9 P10 P11 P12 P14 P15 P16 P8 P21 P22 P23 P24 P26 P27 P29 P30")),
- Subsignal("dm", Pins("P7 P17")),
- IOStandard("LVCMOS33"), Misc("SLEW=FAST")
- )
-]
-
-_connectors = [
- ("A", "P48 P51 P56 P58 P61 P66 P67 P75 P79 P81 P83 P85 P88 P93 P98 P100"),
- ("B", "P99 P97 P92 P87 P84 P82 P80 P78 P74 P95 P62 P59 P57 P55 P50 P47"),
- ("C", "P114 P115 P116 P117 P118 P119 P120 P121 P123 P124 P126 P127 P131 P132 P133 P134")
-]
-
-
-class Platform(XilinxPlatform):
- identifier = 0x5050
- default_clk_name = "clk32"
- default_clk_period = 31.25
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6slx9-tqg144-2", _io, _connectors)
-
- def create_programmer(self):
- return XC3SProg("papilio", "bscan_spi_lx9_papilio.bit")
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-from migen.build.xilinx.programmer import XC3SProg
-
-
-_io = [
- ("user_led", 0, Pins("V16"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # green at hdmi
- ("user_led", 1, Pins("U16"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # red at hdmi
- ("user_led", 2, Pins("A16"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # green at msd
- ("user_led", 3, Pins("A15"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # red at msd
- ("user_led", 4, Pins("A12"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # red at usb
-
- ("user_btn", 0, Pins("N14"), IOStandard("LVTTL"), Misc("PULLDOWN")),
-
- ("clk50", 0, Pins("H17"), IOStandard("LVTTL")),
-
- ("serial", 0,
- Subsignal("tx", Pins("A10")),
- Subsignal("rx", Pins("A11"), Misc("PULLUP")),
- Subsignal("cts", Pins("C10"), Misc("PULLUP")),
- Subsignal("rts", Pins("A9"), Misc("PULLUP")),
- IOStandard("LVTTL"),
- ),
-
- ("usb_fifo", 0,
- Subsignal("data", Pins("A11 A10 C10 A9 B9 A8 B8 A7")),
- Subsignal("rxf_n", Pins("C7")),
- Subsignal("txe_n", Pins("A6")),
- Subsignal("rd_n", Pins("B6")),
- Subsignal("wr_n", Pins("A5")),
- Subsignal("siwua", Pins("C5")),
- IOStandard("LVTTL"),
- ),
-
- ("hdmi", 0,
- Subsignal("clk_p", Pins("U5"), IOStandard("TMDS_33")),
- Subsignal("clk_n", Pins("V5"), IOStandard("TMDS_33")),
- Subsignal("data0_p", Pins("T6"), IOStandard("TMDS_33")),
- Subsignal("data0_n", Pins("V6"), IOStandard("TMDS_33")),
- Subsignal("data1_p", Pins("U7"), IOStandard("TMDS_33")),
- Subsignal("data1_n", Pins("V7"), IOStandard("TMDS_33")),
- Subsignal("data2_p", Pins("U8"), IOStandard("TMDS_33")),
- Subsignal("data2_n", Pins("V8"), IOStandard("TMDS_33")),
- Subsignal("scl", Pins("V9"), IOStandard("I2C")),
- Subsignal("sda", Pins("T9"), IOStandard("I2C")),
- Subsignal("hpd_notif", Pins("R8"), IOStandard("LVTTL")),
- ),
-
- ("spiflash", 0,
- Subsignal("cs_n", Pins("V3")),
- Subsignal("clk", Pins("R15")),
- Subsignal("mosi", Pins("T13")),
- Subsignal("miso", Pins("R13"), Misc("PULLUP")),
- Subsignal("wp", Pins("T14")),
- Subsignal("hold", Pins("V14")),
- IOStandard("LVTTL"), Misc("SLEW=FAST")
- ),
-
- ("spiflash2x", 0,
- Subsignal("cs_n", Pins("V3")),
- Subsignal("clk", Pins("R15")),
- Subsignal("dq", Pins("T13 R13"), Misc("PULLUP")),
- Subsignal("wp", Pins("T14")),
- Subsignal("hold", Pins("V14")),
- IOStandard("LVTTL"), Misc("SLEW=FAST")
- ),
-
- ("spiflash4x", 0,
- Subsignal("cs_n", Pins("V3")),
- Subsignal("clk", Pins("R15")),
- Subsignal("dq", Pins("T13 R13 T14 V14"), Misc("PULLUP")),
- IOStandard("LVTTL"), Misc("SLEW=FAST")
- ),
-
- ("mmc", 0,
- Subsignal("clk", Pins("A3")),
- Subsignal("cmd", Pins("B3"), Misc("PULLUP")),
- Subsignal("dat", Pins("B4 A4 B2 A2"), Misc("PULLUP")),
- IOStandard("SDIO")
- ),
-
- ("mmc_spi", 0,
- Subsignal("cs_n", Pins("A2"), Misc("PULLUP")),
- Subsignal("clk", Pins("A3")),
- Subsignal("mosi", Pins("B3")),
- Subsignal("miso", Pins("B4"), Misc("PULLUP")),
- IOStandard("SDIO")
- ),
-
- ("audio", 0,
- Subsignal("l", Pins("R7"), Misc("SLEW=SLOW")),
- Subsignal("r", Pins("T7"), Misc("SLEW=SLOW")),
- IOStandard("LVTTL"),
- ),
-
- ("pmod", 0,
- Subsignal("d", Pins("D9 C8 D6 C4 B11 C9 D8 C6")),
- IOStandard("LVTTL")
- ),
-
- ("ddram_clock", 0,
- Subsignal("p", Pins("G3")),
- Subsignal("n", Pins("G1")),
- IOStandard("MOBILE_DDR")
- ),
-
- ("ddram", 0,
- Subsignal("a", Pins("J7 J6 H5 L7 F3 H4 H3 H6 D2 D1 F4 D3 G6")),
- Subsignal("ba", Pins("F2 F1")),
- Subsignal("cke", Pins("H7")),
- Subsignal("ras_n", Pins("L5")),
- Subsignal("cas_n", Pins("K5")),
- Subsignal("we_n", Pins("E3")),
- Subsignal("dq", Pins("L2 L1 K2 K1 H2 H1 J3 J1 M3 M1 N2 N1 T2 T1 U2 U1")),
- Subsignal("dqs", Pins("L4 P2")),
- Subsignal("dm", Pins("K3 K4")),
- IOStandard("MOBILE_DDR")
- )
-]
-
-_connectors = [
- ("A", "U18 T17 P17 P16 N16 N17 M16 L15 L17 K15 K17 J16 H15 H18 F18 D18"),
- ("B", "C18 E18 G18 H16 J18 K18 K16 L18 L16 M18 N18 N15 P15 P18 T18 U17"),
- ("C", "F17 F16 E16 G16 F15 G14 F14 H14 H13 J13 G13 H12 K14 K13 K12 L12"),
-]
-
-
-class Platform(XilinxPlatform):
- identifier = 0x5049
- default_clk_name = "clk50"
- default_clk_period = 20
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6slx45-csg324-3", _io, _connectors)
- self.toolchain.bitgen_opt += " -g Compress -g ConfigRate:6"
-
- def create_programmer(self):
- return XC3SProg("papilio", "bscan_spi_lx45_csg324.bit")
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-_io = [
- ("user_led", 0, Pins("Y3")),
- ("user_led", 1, Pins("Y1")),
- ("user_led", 2, Pins("W2")),
- ("user_led", 3, Pins("W1")),
- ("user_led", 4, Pins("V3")),
- ("user_led", 5, Pins("V1")),
- ("user_led", 6, Pins("U2")),
- ("user_led", 7, Pins("U1")),
-
- ("clk100", 0,
- Subsignal("p", Pins("B14"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")),
- Subsignal("n", Pins("A14"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE"))
- ),
-
- ("gpio", 0, Pins("R8")),
-
- ("gpmc", 0,
- Subsignal("clk", Pins("R26")),
- Subsignal("a", Pins("N17 N18 L23 L24 N19 N20 N21 N22 P17 P19")),
- Subsignal("d", Pins("N23 N24 R18 R19 P21 P22 R20 R21 P24 P26 R23 R24 T22 T23 U23 R25")),
- Subsignal("we_n", Pins("W26")),
- Subsignal("oe_n", Pins("AA25")),
- Subsignal("ale_n", Pins("AA26")),
- Subsignal("wait", Pins("AD26")), # WAIT1/BUSY0
- IOStandard("LVCMOS33")),
- # Warning: CS are numbered 1-7 on ARM side and 0-6 on FPGA side.
- # Numbers here are given on the FPGA side.
- ("gpmc_ce_n", 0, Pins("V23"), IOStandard("LVCMOS33")), # nCS0
- ("gpmc_ce_n", 1, Pins("U25"), IOStandard("LVCMOS33")), # nCS1
- ("gpmc_ce_n", 2, Pins("W25"), IOStandard("LVCMOS33")), # nCS6
- ("gpmc_dmareq_n", 0, Pins("T24"), IOStandard("LVCMOS33")), # nCS2
- ("gpmc_dmareq_n", 1, Pins("T26"), IOStandard("LVCMOS33")), # nCS3
- ("gpmc_dmareq_n", 2, Pins("V24"), IOStandard("LVCMOS33")), # nCS4
- ("gpmc_dmareq_n", 3, Pins("V26"), IOStandard("LVCMOS33")), # nCS5
-
- # FMC150
- ("fmc150_ctrl", 0,
- Subsignal("spi_sclk", Pins("AE5")),
- Subsignal("spi_data", Pins("AF5")),
-
- Subsignal("adc_sdo", Pins("U13")),
- Subsignal("adc_en_n", Pins("AA15")),
- Subsignal("adc_reset", Pins("V13")),
-
- Subsignal("cdce_sdo", Pins("AA8")),
- Subsignal("cdce_en_n", Pins("Y9")),
- Subsignal("cdce_reset_n", Pins("AB7")),
- Subsignal("cdce_pd_n", Pins("AC6")),
- Subsignal("cdce_pll_status", Pins("W7")),
- Subsignal("cdce_ref_en", Pins("W8")),
-
- Subsignal("dac_sdo", Pins("W9")),
- Subsignal("dac_en_n", Pins("W10")),
-
- Subsignal("mon_sdo", Pins("AC5")),
- Subsignal("mon_en_n", Pins("AD6")),
- Subsignal("mon_reset_n", Pins("AF6")),
- Subsignal("mon_int_n", Pins("AD5")),
-
- Subsignal("pg_c2m", Pins("AA23"), IOStandard("LVCMOS33"))
- ),
- ("ti_dac", 0, # DAC3283
- Subsignal("dat_p", Pins("AA10 AA9 V11 Y11 W14 Y12 AD14 AE13"), IOStandard("LVDS_25")),
- Subsignal("dat_n", Pins("AB11 AB9 V10 AA11 Y13 AA12 AF14 AF13"), IOStandard("LVDS_25")),
- Subsignal("frame_p", Pins("AB13"), IOStandard("LVDS_25")),
- Subsignal("frame_n", Pins("AA13"), IOStandard("LVDS_25")),
- Subsignal("txenable", Pins("AB15"), IOStandard("LVCMOS25"))
- ),
- ("ti_adc", 0, # ADS62P49
- Subsignal("dat_a_p", Pins("AB14 Y21 W20 AB22 V18 W17 AA21")),
- Subsignal("dat_a_n", Pins("AC14 AA22 Y20 AC22 W19 W18 AB21")),
- Subsignal("dat_b_p", Pins("Y17 U15 AA19 W16 AA18 Y15 V14")),
- Subsignal("dat_b_n", Pins("AA17 V16 AB19 Y16 AB17 AA16 V15")),
- IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")
- ),
- ("fmc150_clocks", 0,
- Subsignal("dac_clk_p", Pins("V12"), IOStandard("LVDS_25")),
- Subsignal("dac_clk_n", Pins("W12"), IOStandard("LVDS_25")),
- Subsignal("adc_clk_p", Pins("AE15"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")),
- Subsignal("adc_clk_n", Pins("AF15"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")),
- Subsignal("clk_to_fpga", Pins("W24"), IOStandard("LVCMOS25"))
- ),
-
- ("fmc150_ext_trigger", 0, Pins("U26")),
-
- # Vermeer radar testbed
- # Switch controller
- ("pca9555", 0,
- Subsignal("sda", Pins("C13")),
- Subsignal("scl", Pins("G8")),
- IOStandard("LVCMOS33")
- ),
- # TX path
- ("pe43602", 0,
- Subsignal("d", Pins("H8")),
- Subsignal("clk", Pins("B3")),
- Subsignal("le", Pins("F7")),
- IOStandard("LVCMOS33")
- ),
- ("rfmd2081", 0,
- Subsignal("enx", Pins("E5")),
- Subsignal("sclk", Pins("G6")),
- Subsignal("sdata", Pins("F5")),
- Subsignal("locked", Pins("E6")),
- IOStandard("LVCMOS33")
- ),
- # RX path
- ("lmh6521", 0,
- Subsignal("scsb", Pins("C5")),
- Subsignal("sclk", Pins("G10")),
- Subsignal("sdi", Pins("D5")),
- Subsignal("sdo", Pins("F9")),
- IOStandard("LVCMOS33")
- ),
- ("lmh6521", 1,
- Subsignal("scsb", Pins("E10")),
- Subsignal("sclk", Pins("A4")),
- Subsignal("sdi", Pins("B4")),
- Subsignal("sdo", Pins("H10")),
- IOStandard("LVCMOS33")
- ),
- ("rffc5071", 0,
- Subsignal("enx", Pins("A2")),
- Subsignal("sclk", Pins("G9")),
- Subsignal("sdata", Pins("H9")),
- Subsignal("locked", Pins("A3")),
- IOStandard("LVCMOS33")
- )
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk100"
- default_clk_period = 10
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6slx150t-fgg676-3", _io)
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-_io = [
- ("epb", 0,
- Subsignal("cs_n", Pins("K13")),
- Subsignal("r_w_n", Pins("AF20")),
- Subsignal("be_n", Pins("AF14 AF18")),
- Subsignal("oe_n", Pins("AF21")),
- Subsignal("addr", Pins("AE23 AE22 AG18 AG12 AG15 AG23 AF19 AE12 AG16 AF13 AG20 AF23",
- "AH17 AH15 L20 J22 H22 L15 L16 K22 K21 K16 J15")),
- Subsignal("addr_gp", Pins("L21 G22 K23 K14 L14 J12")),
- Subsignal("data", Pins("AF15 AE16 AE21 AD20 AF16 AE17 AE19 AD19 AG22 AH22 AH12 AG13",
- "AH20 AH19 AH14 AH13")),
- Subsignal("rdy", Pins("K12")),
- IOStandard("LVCMOS33")
- ),
- ("roach_clocks", 0,
- Subsignal("epb_clk", Pins("AH18"), IOStandard("LVCMOS33")),
- Subsignal("sys_clk_n", Pins("H13")),
- Subsignal("sys_clk_p", Pins("J14")),
- Subsignal("aux0_clk_p", Pins("G15")),
- Subsignal("aux0_clk_n", Pins("G16")),
- Subsignal("aux1_clk_p", Pins("H14")),
- Subsignal("aux1_clk_n", Pins("H15")),
- Subsignal("dly_clk_n", Pins("J17")),
- Subsignal("dly_clk_p", Pins("J16")),
- ),
-]
-
-
-class Platform(XilinxPlatform):
- def __init__(self):
- XilinxPlatform.__init__(self, "xc5vsx95t-ff1136-1", _io)
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.sim import SimPlatform
-
-
-class SimPins(Pins):
- def __init__(self, n):
- Pins.__init__(self, "s "*n)
-
-_io = [
- ("sys_clk", 0, SimPins(1)),
- ("sys_rst", 0, SimPins(1)),
- ("serial", 0,
- Subsignal("source_stb", SimPins(1)),
- Subsignal("source_ack", SimPins(1)),
- Subsignal("source_data", SimPins(8)),
-
- Subsignal("sink_stb", SimPins(1)),
- Subsignal("sink_ack", SimPins(1)),
- Subsignal("sink_data", SimPins(8)),
- ),
- ("eth_clocks", 0,
- Subsignal("none", SimPins(1)),
- ),
- ("eth", 0,
- Subsignal("source_stb", SimPins(1)),
- Subsignal("source_ack", SimPins(1)),
- Subsignal("source_data", SimPins(8)),
-
- Subsignal("sink_stb", SimPins(1)),
- Subsignal("sink_ack", SimPins(1)),
- Subsignal("sink_data", SimPins(8)),
- ),
-]
-
-
-class Platform(SimPlatform):
- is_sim = True
- default_clk_name = "sys_clk"
- default_clk_period = 1000 # on modern computers simulate at ~ 1MHz
-
- def __init__(self):
- SimPlatform.__init__(self, "SIM", _io)
-
- def do_finalize(self, fragment):
- pass
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-_io = [
- ("clk64", 0,
- Subsignal("p", Pins("R7")),
- Subsignal("n", Pins("T7")),
- IOStandard("LVDS_33"),
- Misc("DIFF_TERM=TRUE"),
- ),
-
- ("pps", 0, Pins("M14"), Misc("TIG")),
- ("reset_n", 0, Pins("D5"), Misc("TIG")),
- ("codec_reset", 0, Pins("B14")),
- # recycles fpga_cfg_cclk for reset from fw
- ("ext_reset", 0, Pins("R14")),
-
- ("i2c", 0,
- Subsignal("sda", Pins("T13")),
- Subsignal("scl", Pins("R13")),
- ),
-
- ("cgen", 0,
- Subsignal("st_ld", Pins("M13")),
- Subsignal("st_refmon", Pins("J14")),
- Subsignal("st_status", Pins("P6")),
- Subsignal("ref_sel", Pins("T2")),
- Subsignal("sync_b", Pins("H15")),
- ),
-
- ("fx2_ifclk", 0, Pins("T8")),
- ("fx2_gpif", 0,
- Subsignal("d", Pins("P8 P9 N9 T9 R9 P11 P13 N12 "
- "T3 R3 P5 N6 T6 T5 N8 P7")),
- Subsignal("ctl", Pins("M7 M9 M11 P12")),
- Subsignal("slwr", Pins("T4")), # rdy0
- Subsignal("slrd", Pins("R5")), # rdy1
- # Subsignal("rdy2", Pins("T10")),
- # Subsignal("rdy3", Pins("N11")),
- # Subsignal("cs", Pins("P12")),
- Subsignal("sloe", Pins("R11")),
- Subsignal("pktend", Pins("P10")),
- Subsignal("adr", Pins("T11 H16")),
- ),
-
- ("user_led", 0, Pins("P4"), Misc("TIG")),
- ("user_led", 1, Pins("N4"), Misc("TIG")),
- ("user_led", 2, Pins("R2"), Misc("TIG")),
-
- ("debug_clk", 0, Pins("K15 K14")),
- ("debug", 0, Pins(
- "K16 J16 C16 C15 E13 D14 D16 D15 "
- "E14 F13 G13 F14 E16 F15 H13 G14 "
- "G16 F16 J12 J13 L14 L16 M15 M16 "
- "L13 K13 P16 N16 R15 P15 N13 N14")),
-
- ("adc", 0,
- Subsignal("sync", Pins("D10")),
- Subsignal("d", Pins("A4 B3 A3 D9 C10 A9 C9 D8 "
- "C8 B8 A8 B15")),
- ),
- ("dac", 0,
- Subsignal("blank", Pins("K1")),
- Subsignal("sync", Pins("J2")),
- Subsignal("d", Pins("J1 H3 J3 G2 H1 N3 M4 R1 "
- "P2 P1 M1 N1 M3 L4")),
- ),
- ("codec_spi", 0,
- Subsignal("sclk", Pins("K3")),
- Subsignal("sen", Pins("D13")),
- Subsignal("mosi", Pins("C13")),
- Subsignal("miso", Pins("G4")),
- ),
-
- ("aux_spi", 0,
- Subsignal("sen", Pins("C12")),
- Subsignal("sclk", Pins("D12")),
- Subsignal("miso", Pins("J5")),
- ),
- ("rx_io", 0, Pins("D7 C6 A6 B6 E9 A7 C7 B10 "
- "A10 C11 A11 D11 B12 A12 A14 A13")),
- ("tx_io", 0, Pins("K4 L3 L2 F1 F3 G3 E3 E2 "
- "E4 F4 D1 E1 D4 D3 C2 C1")),
- ("rx_spi", 0,
- Subsignal("miso", Pins("E6")),
- Subsignal("sen", Pins("B4")),
- Subsignal("mosi", Pins("A5")),
- Subsignal("sclk", Pins("C5")),
- ),
- ("tx_spi", 0,
- Subsignal("miso", Pins("J4")),
- Subsignal("sen", Pins("N2")),
- Subsignal("mosi", Pins("L1")),
- Subsignal("sclk", Pins("G1")),
- ),
-
- # these are just for information. do not request.
- ("mystery_bus", 0, Pins("C4 E7")),
- ("fpga_cfg",
- Subsignal("din", Pins("T14")),
- Subsignal("cclk", Pins("R14")),
- Subsignal("init_b", Pins("T12")),
- Subsignal("prog_b", Pins("A2")),
- Subsignal("done", Pins("T15")),
- ),
- ("jtag",
- Subsignal("tms", Pins("B2")),
- Subsignal("tdo", Pins("B16")),
- Subsignal("tdi", Pins("B1")),
- Subsignal("tck", Pins("A15")),
- ),
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk64"
- default_clk_period = 15.625
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc3s1400a-ft256-4", _io)
- self.toolchain.bitgen_opt = "-g LCK_cycle:6 -g Binary:Yes -w -g UnusedPin:PullUp"
-
- def do_finalize(self, fragment):
- XilinxPlatform.do_finalize(self, fragment)
-
- self.add_platform_command("""
-TIMESPEC TS_Pad2Pad = FROM PADS TO PADS 7 ns;
-""")
-
- try:
- ifclk = self.lookup_request("fx2_ifclk")
- gpif = self.lookup_request("fx2_gpif")
- for i, d in [(gpif.d, "in"), (gpif.d, "out"),
- (gpif.ctl, "in"), (gpif.adr, "out"),
- (gpif.slwr, "out"), (gpif.sloe, "out"),
- (gpif.slrd, "out"), (gpif.pktend, "out")]:
- if len(i) > 1:
- q = "(*)"
- else:
- q = ""
- self.add_platform_command("""
-INST "{i}%s" TNM = gpif_net_%s;
-""" % (q, d), i=i)
- self.add_platform_command("""
-NET "{ifclk}" TNM_NET = "GRPifclk";
-TIMESPEC "TSifclk" = PERIOD "GRPifclk" 20833 ps HIGH 50%;
-TIMEGRP "gpif_net_in" OFFSET = IN 5 ns VALID 10 ns BEFORE "{ifclk}" RISING;
-TIMEGRP "gpif_net_out" OFFSET = OUT 7 ns AFTER "{ifclk}" RISING;
-""", ifclk=ifclk)
- except ConstraintError:
- pass
+++ /dev/null
-# This file is Copyright (c) 2013 Florent Kermarrec <florent@enjoy-digital.fr>
-# License: BSD
-
-from migen.build.generic_platform import *
-from migen.build.lattice import LatticePlatform
-from migen.build.lattice.programmer import LatticeProgrammer
-
-
-_io = [
- ("clk100", 0, Pins("L5"), IOStandard("LVDS25")),
- ("rst_n", 0, Pins("A21"), IOStandard("LVCMOS33")),
-
- ("user_led", 0, Pins("Y20"), IOStandard("LVCMOS33")),
- ("user_led", 1, Pins("AA21"), IOStandard("LVCMOS33")),
- ("user_led", 2, Pins("U18"), IOStandard("LVCMOS33")),
- ("user_led", 3, Pins("U19"), IOStandard("LVCMOS33")),
- ("user_led", 4, Pins("W19"), IOStandard("LVCMOS33")),
- ("user_led", 5, Pins("V19"), IOStandard("LVCMOS33")),
- ("user_led", 6, Pins("AB20"), IOStandard("LVCMOS33")),
- ("user_led", 7, Pins("AA20"), IOStandard("LVCMOS33")),
-
- ("user_dip_btn", 0, Pins("J7"), IOStandard("LVCMOS15")),
- ("user_dip_btn", 1, Pins("J6"), IOStandard("LVCMOS15")),
- ("user_dip_btn", 2, Pins("H2"), IOStandard("LVCMOS15")),
- ("user_dip_btn", 3, Pins("H3"), IOStandard("LVCMOS15")),
- ("user_dip_btn", 4, Pins("J3"), IOStandard("LVCMOS15")),
- ("user_dip_btn", 5, Pins("K3"), IOStandard("LVCMOS15")),
- ("user_dip_btn", 6, Pins("J2"), IOStandard("LVCMOS15")),
- ("user_dip_btn", 7, Pins("J1"), IOStandard("LVCMOS15")),
-
- ("serial", 0,
- Subsignal("tx", Pins("B11"), IOStandard("LVCMOS33")), # X4 IO0
- Subsignal("rx", Pins("B12"), IOStandard("LVCMOS33")), # X4 IO1
- ),
-
- ("eth_clocks", 0,
- Subsignal("tx", Pins("C12")),
- Subsignal("gtx", Pins("M2")),
- Subsignal("rx", Pins("L4")),
- IOStandard("LVCMOS33")
- ),
- ("eth", 0,
- Subsignal("rst_n", Pins("L3")),
- Subsignal("mdio", Pins("L2")),
- Subsignal("mdc", Pins("V4")),
- Subsignal("dv", Pins("M1")),
- Subsignal("rx_er", Pins("M4")),
- Subsignal("rx_data", Pins("M5 N1 N6 P6 T2 R2 P5 P3")),
- Subsignal("tx_en", Pins("V3")),
- Subsignal("tx_data", Pins("V1 U1 R3 P1 N5 N3 N4 N2")),
- Subsignal("col", Pins("R1")),
- Subsignal("crs", Pins("P4")),
- IOStandard("LVCMOS33")
- ),
-
- ("eth_clocks", 1,
- Subsignal("tx", Pins("M21")),
- Subsignal("gtx", Pins("M19")),
- Subsignal("rx", Pins("N19")),
- IOStandard("LVCMOS33")
- ),
- ("eth", 1,
- Subsignal("rst_n", Pins("R21")),
- Subsignal("mdio", Pins("U16")),
- Subsignal("mdc", Pins("Y18")),
- Subsignal("dv", Pins("U15")),
- Subsignal("rx_er", Pins("V20")),
- Subsignal("rx_data", Pins("AB17 AA17 R19 V21 T17 R18 W21 Y21")),
- Subsignal("tx_en", Pins("V22")),
- Subsignal("tx_data", Pins("W22 R16 P17 Y22 T21 U22 P20 U20")),
- Subsignal("col", Pins("N18")),
- Subsignal("crs", Pins("P19")),
- IOStandard("LVCMOS33")
- ),
-]
-
-
-class Platform(LatticePlatform):
- default_clk_name = "clk100"
- default_clk_period = 10
-
- def __init__(self):
- LatticePlatform.__init__(self, "LFE3-35EA-6FN484C", _io)
-
- def do_finalize(self, fragment):
- LatticePlatform.do_finalize(self, fragment)
- try:
- self.add_period_constraint(self.lookup_request("eth_clocks", 0).rx, 8.0)
- except ConstraintError:
- pass
- try:
- self.add_period_constraint(self.lookup_request("eth_clocks", 1).rx, 8.0)
- except ConstraintError:
- pass
- def create_programmer(self):
- return LatticeProgrammer()
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-# Bank 34 and 35 voltage depend on J18 jumper setting
-_io = [
- ("clk100", 0, Pins("Y9"), IOStandard("LVCMOS33")),
-
- ("user_btn", 0, Pins("P16"), IOStandard("LVCMOS18")), # center
- ("user_btn", 1, Pins("R16"), IOStandard("LVCMOS18")), # down
- ("user_btn", 2, Pins("N15"), IOStandard("LVCMOS18")), # left
- ("user_btn", 3, Pins("R18"), IOStandard("LVCMOS18")), # right
- ("user_btn", 4, Pins("T18"), IOStandard("LVCMOS18")), # up
-
- ("user_sw", 0, Pins("F22"), IOStandard("LVCMOS18")),
- ("user_sw", 1, Pins("G22"), IOStandard("LVCMOS18")),
- ("user_sw", 2, Pins("H22"), IOStandard("LVCMOS18")),
- ("user_sw", 3, Pins("F21"), IOStandard("LVCMOS18")),
- ("user_sw", 4, Pins("H19"), IOStandard("LVCMOS18")),
- ("user_sw", 5, Pins("H18"), IOStandard("LVCMOS18")),
- ("user_sw", 6, Pins("H17"), IOStandard("LVCMOS18")),
- ("user_sw", 7, Pins("M15"), IOStandard("LVCMOS18")),
-
- ("user_led", 0, Pins("T22"), IOStandard("LVCMOS33")),
- ("user_led", 1, Pins("T21"), IOStandard("LVCMOS33")),
- ("user_led", 2, Pins("U22"), IOStandard("LVCMOS33")),
- ("user_led", 3, Pins("U21"), IOStandard("LVCMOS33")),
- ("user_led", 4, Pins("V22"), IOStandard("LVCMOS33")),
- ("user_led", 5, Pins("W22"), IOStandard("LVCMOS33")),
- ("user_led", 6, Pins("U19"), IOStandard("LVCMOS33")),
- ("user_led", 7, Pins("U14"), IOStandard("LVCMOS33")),
-
- # A
- ("pmod", 0, Pins("Y11 AA11 Y10 AA9 AB11 AB10 AB9 AA8"),
- IOStandard("LVCMOS33")),
- # B
- ("pmod", 1, Pins("W12 W11 V10 W8 V12 W10 V9 V8"),
- IOStandard("LVCMOS33")),
- # C
- ("pmod", 2,
- Subsignal("n", Pins("AB6 AA4 T6 U4")),
- Subsignal("p", Pins("AB7 Y4 R6 T4")),
- IOStandard("LVCMOS33")),
- # D
- ("pmod", 3,
- Subsignal("n", Pins("W7 V4 W5 U5")),
- Subsignal("p", Pins("V7 V5 W6 U6")),
- IOStandard("LVCMOS33")),
-
- ("audio", 0,
- Subsignal("adr", Pins("AB1 Y5")),
- Subsignal("gpio", Pins("Y8 AA7 AA6 Y6")),
- Subsignal("mclk", Pins("AB2")),
- Subsignal("sck", Pins("AB4")),
- Subsignal("sda", Pins("AB5")),
- IOStandard("LVCMOS33")),
-
- ("oled", 0,
- Subsignal("dc", Pins("U10")),
- Subsignal("res", Pins("U9")),
- Subsignal("sclk", Pins("AB12")),
- Subsignal("sdin", Pins("AA12")),
- Subsignal("vbat", Pins("U11")),
- Subsignal("vdd", Pins("U12")),
- IOStandard("LVCMOS33")),
-
- ("hdmi", 0,
- Subsignal("clk", Pins("W18")),
- Subsignal("d", Pins(
- "Y13 AA13 AA14 Y14 AB15 AB16 AA16 AB17 "
- "AA17 Y15 W13 W15 V15 U17 V14 V13")),
- Subsignal("de", Pins("U16")),
- Subsignal("hsync", Pins("V17")),
- Subsignal("vsync", Pins("W17")),
- Subsignal("int", Pins("W16")),
- Subsignal("scl", Pins("AA18")),
- Subsignal("sda", Pins("Y16")),
- Subsignal("spdif", Pins("U15")),
- Subsignal("spdifo", Pins("Y18")),
- IOStandard("LVCMOS33")),
-
- ("netic16", 0,
- Subsignal("w20", Pins("W20")),
- Subsignal("w21", Pins("W21")),
- IOStandard("LVCMOS33")),
-
- ("vga", 0,
- Subsignal("r", Pins("V20 U20 V19 V18")),
- Subsignal("g", Pins("AB22 AA22 AB21 AA21")),
- Subsignal("b", Pins("Y21 Y20 AB20 AB19")),
- Subsignal("hsync_n", Pins("AA19")),
- Subsignal("vsync_n", Pins("Y19")),
- IOStandard("LVCMOS33")),
-
- ("usb_otg", 0,
- Subsignal("vbusoc", Pins("L16")),
- Subsignal("reset_n", Pins("G17")),
- IOStandard("LVCMOS18")),
-
- ("pudc_b", 0, Pins("K16"), IOStandard("LVCMOS18")),
-
- ("xadc", 0,
- Subsignal("gio", Pins("H15 R15 K15 J15")),
- Subsignal("ad0_n", Pins("E16")),
- Subsignal("ad0_p", Pins("F16")),
- Subsignal("ad8_n", Pins("D17")),
- Subsignal("ad8_p", Pins("D16")),
- IOStandard("LVCMOS18")),
-
- ("fmc_clocks", 0,
- Subsignal("clk0_n", Pins("L19")),
- Subsignal("clk0_p", Pins("L18")),
- Subsignal("clk1_n", Pins("C19")),
- Subsignal("clk1_p", Pins("D18")),
- IOStandard("LVCMOS18")),
-
- ("fmc", 0,
- Subsignal("scl", Pins("R7")),
- Subsignal("sda", Pins("U7")),
-
- Subsignal("prsnt", Pins("AB14")),
-
- # 0, 1, 17, 18 can be clock signals
- Subsignal("la_n", Pins(
- "M20 N20 P18 P22 M22 K18 L22 T17 "
- "J22 R21 T19 N18 P21 M17 K20 J17 "
- "K21 B20 C20 G16 G21 E20 F19 D15 "
- "A19 C22 E18 D21 A17 C18 B15 B17 "
- "A22 B22")),
- Subsignal("la_p", Pins(
- "M19 N19 P17 N22 M21 J18 L21 T16 "
- "J21 R20 R19 N17 P20 L17 K19 J16 "
- "J20 B19 D20 G15 G20 E19 G19 E15 "
- "A18 D22 F18 E21 A16 C17 C15 B16 "
- "A21 B21")),
- IOStandard("LVCMOS18")),
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk100"
- default_clk_period = 10
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc7z020-clg484-1", _io)
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-_io = [
- ("clk_fx", 0, Pins("L22"), IOStandard("LVCMOS33")),
- ("clk_if", 0, Pins("K20"), IOStandard("LVCMOS33")),
- ("rst", 0, Pins("A18")),
- # PROG_B and DONE: AA1 U16
-
- ("fx2", 0,
- Subsignal("sloe", Pins("U15"), Drive(12)), # M1
- Subsignal("slrd", Pins("N22"), Drive(12)),
- Subsignal("slwr", Pins("M22"), Drive(12)),
- Subsignal("pktend", Pins("AB5"), Drive(12)), # CSO
- Subsignal("fifoadr", Pins("W17 Y18"), Drive(12)), # CCLK M0
- Subsignal("cont", Pins("G20")),
- Subsignal("fd", Pins("Y17 V13 W13 AA8 AB8 W6 Y6 Y9 "
- "V21 V22 U20 U22 R20 R22 P18 P19")),
- Subsignal("flag", Pins("F20 F19 F18 AB17")), # - - - CSI/MOSI
- Subsignal("rdy25", Pins("M21 K21 K22 J21")),
- Subsignal("ctl35", Pins("D19 E20 N20")),
- Subsignal("int45", Pins("C18 V17")),
- Subsignal("pc", Pins("G20 T10 V5 AB9 G19 H20 H19 H18")),
- # - DOUT/BUSY INIT_B RDWR_B DO CS CLK DI
- IOStandard("LVCMOS33")),
-
- ("mm", 0,
- Subsignal("a", Pins("M20 M19 M18 N19 T19 T21 T22 R19 ",
- "P20 P21 P22 J22 H21 H22 G22 F21")),
- Subsignal("d", Pins("D20 C20 C19 B21 B20 J19 K19 L19"), Drive(2)),
- Subsignal("wr_n", Pins("C22")),
- Subsignal("rd_n", Pins("D21")),
- Subsignal("psen_n", Pins("D22")),
- IOStandard("LVCMOS33")),
-
- ("serial", 0,
- Subsignal("tx", Pins("B22"), Misc("SLEW=QUIETIO")),
- Subsignal("rx", Pins("A21"), Misc("PULLDOWN")),
- IOStandard("LVCMOS33")),
-
- ("ddram_clock", 0,
- Subsignal("p", Pins("F2"), Misc("OUT_TERM=UNTUNED_50")),
- Subsignal("n", Pins("F1"), Misc("OUT_TERM=UNTUNED_50")),
- IOStandard("SSTL18_II")),
-
- ("ddram", 0,
- Subsignal("dqs", Pins("L3 T2"), IOStandard("SSTL18_II"), # DIFF_
- Misc("IN_TERM=NONE")),
- Subsignal("dqs_n", Pins("L1 T1"), IOStandard("SSTL18_II"), # DIFF_
- Misc("IN_TERM=NONE")),
- Subsignal("dm", Pins("H1 H2"), Misc("OUT_TERM=UNTUNED_50")),
- Subsignal("dq", Pins("M1 M2 J1 K2 J3 K1 N3 N1 "
- "U1 U3 P1 R3 P2 R1 V2 V1"), Misc("IN_TERM=NONE")),
- Subsignal("ras_n", Pins("N4"), Misc("OUT_TERM=UNTUNED_50")),
- Subsignal("cas_n", Pins("P3"), Misc("OUT_TERM=UNTUNED_50")),
- Subsignal("a", Pins("M5 K6 B1 J4 L4 K3 M4 K5 G3 G1 K4 C3 C1"),
- Misc("OUT_TERM=UNTUNED_50")),
- Subsignal("ba", Pins("E3 E1 D1"), Misc("OUT_TERM=UNTUNED_50")),
- Subsignal("cke", Pins("J6"), Misc("OUT_TERM=UNTUNED_50")),
- Subsignal("cs_n", Pins("H6")), # NC!
- Subsignal("odt", Pins("M3"), Misc("OUT_TERM=UNTUNED_50")),
- Subsignal("we_n", Pins("D2")),
- Subsignal("rzq", Pins("AA2")),
- Subsignal("zio", Pins("Y2")),
- IOStandard("SSTL18_II")),
-
- ("i2c", 0,
- Subsignal("scl", Pins("F22")),
- Subsignal("sda", Pins("E22")),
- IOStandard("LVCMOS33")),
-
- ("sd", 0,
- Subsignal("sck", Pins("H11")),
- Subsignal("d3", Pins("H14")),
- Subsignal("d", Pins("P10")),
- Subsignal("d1", Pins("T18")),
- Subsignal("d2", Pins("R17")),
- Subsignal("cmd", Pins("H13")),
- IOStandard("LVCMOS33")),
-
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk_if"
- default_clk_period = 20
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6slx150-3csg484", _io)
- self.add_platform_command("""
-CONFIG VCCAUX = "2.5";
-""")
-
- def do_finalize(self, fragment):
- XilinxPlatform.do_finalize(self, fragment)
-
- try:
- clk_if = self.lookup_request("clk_if")
- clk_fx = self.lookup_request("clk_fx")
- self.add_platform_command("""
-NET "{clk_if}" TNM_NET = "GRPclk_if";
-NET "{clk_fx}" TNM_NET = "GRPclk_fx";
-TIMESPEC "TSclk_fx" = PERIOD "GRPclk_fx" 20.83333 ns HIGH 50%;
-TIMESPEC "TSclk_if" = PERIOD "GRPclk_if" 20 ns HIGH 50%;
-TIMESPEC "TSclk_fx2if" = FROM "GRPclk_fx" TO "GRPclk_if" 3 ns DATAPATHONLY;
-TIMESPEC "TSclk_if2fx" = FROM "GRPclk_if" TO "GRPclk_fx" 3 ns DATAPATHONLY;
-""", clk_if=clk_if, clk_fx=clk_fx)
- except ConstraintError:
- pass
+++ /dev/null
-from migen.build.sim.platform import SimPlatform
+++ /dev/null
-sim_special_overrides = {}
+++ /dev/null
-// This file is Copyright (c) 2015 Florent Kermarrec <florent@enjoy-digital.fr>
-// License: BSD
-#include "Vdut.h"
-#include "verilated.h"
-#include "verilated_vcd_c.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <termios.h>
-#include <sys/poll.h>
-
-#include <linux/if.h>
-#include <linux/if_tun.h>
-
-/* ios */
-
-#ifdef SERIAL_SOURCE_STB
-#define WITH_SERIAL
-#endif
-
-#ifdef ETH_SOURCE_STB
-#define WITH_ETH
-#endif
-
-#define MAX(a,b) (((a)>(b))?(a):(b))
-#define MIN(a,b) (((a)<(b))?(a):(b))
-
-int trace = 0;
-
-vluint64_t main_time = 0;
-double sc_time_stamp()
-{
- return main_time;
-}
-
-/* Sim struct */
-struct sim {
- bool run;
-
- unsigned int tick;
- clock_t start;
- clock_t end;
- float speed;
-
-#ifdef WITH_SERIAL_PTY
- char serial_dev[64];
- int serial_fd;
- unsigned char serial_rx_data;
- unsigned char serial_tx_data;
-#endif
-#ifdef WITH_ETH
- const char *eth_dev;
- const char *eth_tap;
- int eth_fd;
- unsigned char eth_txbuffer[2048];
- unsigned char eth_rxbuffer[2048];
- int eth_txbuffer_len;
- int eth_rxbuffer_len;
- int eth_rxbuffer_pos;
- int eth_last_source_stb;
-#endif
-};
-
-/* Serial functions */
-#ifndef WITH_SERIAL_PTY
-struct termios orig_termios;
-
-void reset_terminal_mode(void)
-{
- tcsetattr(0, TCSANOW, &orig_termios);
-}
-
-void set_conio_terminal_mode(void)
-{
- struct termios new_termios;
-
- /* take two copies - one for now, one for later */
- tcgetattr(0, &orig_termios);
- memcpy(&new_termios, &orig_termios, sizeof(new_termios));
-
- /* register cleanup handler, and set the new terminal mode */
- atexit(reset_terminal_mode);
- cfmakeraw(&new_termios);
- tcsetattr(0, TCSANOW, &new_termios);
-}
-
-int kbhit(void)
-{
- struct timeval tv = { 0L, 0L };
- fd_set fds;
- FD_ZERO(&fds);
- FD_SET(0, &fds);
- return select(1, &fds, NULL, NULL, &tv);
-}
-
-int getch(void)
-{
- int r;
- unsigned char c;
- if((r = read(0, &c, sizeof(c))) < 0) {
- return r;
- } else {
- return c;
- }
-}
-#endif
-
-/* Ethernet functions */
-/* create tap:
- openvpn --mktun --dev tap0
- ifconfig tap0 192.168.0.14 up
- mknod /dev/net/tap0 c 10 200
- delete tap:
- openvpn --rmtun --dev tap0 */
-#ifdef WITH_ETH
-void eth_init(struct sim *s, const char *dev, const char*tap)
-{
- s->eth_txbuffer_len = 0;
- s->eth_rxbuffer_len = 0;
- s->eth_rxbuffer_pos = 0;
- s->eth_last_source_stb = 0;
- s->eth_dev = dev;
- s->eth_tap = tap;
-}
-
-void eth_open(struct sim *s)
-{
-
- struct ifreq ifr;
- s->eth_fd = open (s->eth_dev, O_RDWR);
- if(s->eth_fd < 0) {
- fprintf(stderr, " Could not open dev %s\n", s->eth_dev);
- return;
- }
-
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
- strncpy(ifr.ifr_name, s->eth_tap, IFNAMSIZ);
-
- if(ioctl(s->eth_fd, TUNSETIFF, (void *) &ifr) < 0) {
- fprintf(stderr, " Could not set %s\n", s->eth_tap);
- close(s->eth_fd);
- }
- return;
-}
-
-int eth_close(struct sim *s)
-{
- if(s->eth_fd < 0)
- close(s->eth_fd);
-}
-
-void eth_write(struct sim *s, unsigned char *buf, int len)
-{
- write(s->eth_fd, buf, len);
-}
-
-int eth_read(struct sim *s, unsigned char *buf)
-{
-
- struct pollfd fds[1];
- int n;
- int len;
-
- fds[0].fd = s->eth_fd;
- fds[0].events = POLLIN;
-
- n = poll(fds, 1, 0);
- if((n > 0) && ((fds[0].revents & POLLIN) == POLLIN)) {
- len = read(s->eth_fd, buf, 1532);
- } else {
- len = 0;
- }
- return len;
-}
-#endif
-
-Vdut* dut;
-VerilatedVcdC* tfp;
-
-#ifndef WITH_SERIAL_PTY
-int console_service(struct sim *s)
-{
- /* fpga --> console */
- SERIAL_SOURCE_ACK = 1;
- if(SERIAL_SOURCE_STB == 1) {
- if(SERIAL_SOURCE_DATA == '\n')
- putchar('\r');
- putchar(SERIAL_SOURCE_DATA);
- fflush(stdout);
- }
-
- /* console --> fpga */
- SERIAL_SINK_STB = 0;
- if(s->tick%(1000) == 0) {
- if(kbhit()) {
- char c = getch();
- if(c == 27 && !kbhit()) {
- printf("\r\n");
- return -1;
- } else {
- SERIAL_SINK_STB = 1;
- SERIAL_SINK_DATA = c;
- }
- }
- }
- return 0;
-}
-#else
-void console_init(struct sim *s)
-{
- FILE *f;
- f = fopen("/tmp/simserial","r");
- fscanf(f, "%[^\n]", s->serial_dev);
- fclose(f);
- return;
-}
-
-void console_open(struct sim *s)
-{
- s->serial_fd = open(s->serial_dev, O_RDWR);
- if(s->serial_fd < 0) {
- fprintf(stderr, " Could not open dev %s\n", s->serial_dev);
- return;
- }
- return;
-}
-
-int console_close(struct sim *s)
-{
- if(s->serial_fd < 0)
- close(s->serial_fd);
-}
-
-void console_write(struct sim *s, unsigned char *buf, int len)
-{
- write(s->serial_fd, buf, len);
-}
-
-int console_read(struct sim *s, unsigned char *buf)
-{
- struct pollfd fds[1];
- int n;
- int len;
-
- fds[0].fd = s->serial_fd;
- fds[0].events = POLLIN;
-
- n = poll(fds, 1, 0);
- if((n > 0) && ((fds[0].revents & POLLIN) == POLLIN)) {
- len = read(s->serial_fd, buf, 1);
- } else {
- len = 0;
- }
- return len;
-}
-
-int console_service(struct sim *s)
-{
- /* fpga --> console */
- SERIAL_SOURCE_ACK = 1;
- if(SERIAL_SOURCE_STB == 1) {
- s->serial_tx_data = SERIAL_SOURCE_DATA;
- console_write(s, &(s->serial_tx_data), 1);
- }
-
- /* console --> fpga */
- SERIAL_SINK_STB = 0;
- if(console_read(s, &(s->serial_rx_data)))
- {
- SERIAL_SINK_STB = 1;
- SERIAL_SINK_DATA = s->serial_rx_data;
- }
- return 0;
-}
-#endif
-
-#ifdef WITH_ETH
-int ethernet_service(struct sim *s) {
- /* fpga --> tap */
- ETH_SOURCE_ACK = 1;
- if(ETH_SOURCE_STB == 1) {
- s->eth_txbuffer[s->eth_txbuffer_len] = ETH_SOURCE_DATA;
- s->eth_txbuffer_len++;
- } else {
- if(s->eth_last_source_stb) {
- eth_write(s, s->eth_txbuffer, s->eth_txbuffer_len);
- s->eth_txbuffer_len = 0;
- }
- }
- s->eth_last_source_stb = ETH_SOURCE_STB;
-
- /* tap --> fpga */
- if(s->eth_rxbuffer_len == 0) {
- ETH_SINK_STB = 0;
- s->eth_rxbuffer_pos = 0;
- s->eth_rxbuffer_len = eth_read(s, s->eth_rxbuffer);
- } else {
- if(s->eth_rxbuffer_pos < MAX(s->eth_rxbuffer_len, 60)) {
- ETH_SINK_STB = 1;
- ETH_SINK_DATA = s->eth_rxbuffer[s->eth_rxbuffer_pos];
- s->eth_rxbuffer_pos++;
- } else {
- ETH_SINK_STB = 0;
- s->eth_rxbuffer_len = 0;
- memset(s->eth_rxbuffer, 0, 1532);
- }
- }
-}
-#endif
-
-void sim_tick(struct sim *s)
-{
- SYS_CLK = s->tick%2;
- dut->eval();
- if(trace)
- tfp->dump(s->tick);
- s->tick++;
-}
-
-void sim_init(struct sim *s)
-{
- int i;
- s->tick = 0;
-#ifdef SYS_RST
- SYS_RST = 1;
- SYS_CLK = 0;
- for (i=0; i<8; i++)
- sim_tick(s);
- SYS_RST = 0;
-#endif
- s->start = clock();
-}
-
-int main(int argc, char **argv, char **env)
-{
- float speed;
-
-#ifndef WITH_SERIAL_PTY
- set_conio_terminal_mode();
-#endif
-
- Verilated::commandArgs(argc, argv);
- dut = new Vdut;
-
- Verilated::traceEverOn(true);
- tfp = new VerilatedVcdC;
- dut->trace(tfp, 99);
- tfp->open("dut.vcd");
-
- struct sim s;
- sim_init(&s);
-
-#ifdef WITH_SERIAL_PTY
- console_init(&s);
- console_open(&s);
-#endif
-
-#ifdef WITH_ETH
- eth_init(&s, "/dev/net/tap0", "tap0"); // XXX get this from /tmp/simethernet
- eth_open(&s);
-#endif
-
- s.run = true;
- while(s.run) {
- sim_tick(&s);
- if(SYS_CLK) {
-#ifdef WITH_SERIAL
- if(console_service(&s) != 0)
- s.run = false;
-#endif
-#ifdef WITH_ETH
- ethernet_service(&s);
-#endif
- }
- }
- s.end = clock();
-
- speed = (s.tick/2)/((s.end-s.start)/CLOCKS_PER_SEC);
-
- printf("average speed: %3.3f MHz\n\r", speed/1000000);
-
- tfp->close();
-
-
-#ifdef WITH_SERIAL_PTY
- console_close(&s);
-#endif
-#ifdef WITH_ETH
- eth_close(&s);
-#endif
-
- exit(0);
-}
+++ /dev/null
-from migen.build.generic_platform import GenericPlatform
-from migen.build.sim import common, verilator
-
-
-class SimPlatform(GenericPlatform):
- def __init__(self, *args, toolchain="verilator", **kwargs):
- GenericPlatform.__init__(self, *args, **kwargs)
- if toolchain == "verilator":
- self.toolchain = verilator.SimVerilatorToolchain()
- else:
- raise ValueError("Unknown toolchain")
-
- def get_verilog(self, *args, special_overrides=dict(), **kwargs):
- so = dict(common.sim_special_overrides)
- so.update(special_overrides)
- return GenericPlatform.get_verilog(self, *args, special_overrides=so, **kwargs)
-
- def build(self, *args, **kwargs):
- return self.toolchain.build(self, *args, **kwargs)
-
+++ /dev/null
-# This file is Copyright (c) 2015 Florent Kermarrec <florent@enjoy-digital.fr>
-# License: BSD
-
-import os
-import subprocess
-
-from migen.fhdl.structure import _Fragment
-from migen.build import tools
-from migen.build.generic_platform import *
-
-
-def _build_tb(platform, vns, serial, template):
- def io_name(resource, subsignal=None):
- res = platform.lookup_request(resource)
- if subsignal is not None:
- res = getattr(res, subsignal)
- return vns.get_name(res)
-
- ios = """
-#define SYS_CLK dut->{sys_clk}
-""".format(sys_clk=io_name("sys_clk"))
-
- if serial == "pty":
- ios += "#define WITH_SERIAL_PTY"
- elif serial == "console":
- pass
- else:
- raise ValueError
- try:
- ios += """
-#define SERIAL_SOURCE_STB dut->{serial_source_stb}
-#define SERIAL_SOURCE_ACK dut->{serial_source_ack}
-#define SERIAL_SOURCE_DATA dut->{serial_source_data}
-
-#define SERIAL_SINK_STB dut->{serial_sink_stb}
-#define SERIAL_SINK_ACK dut->{serial_sink_ack}
-#define SERIAL_SINK_DATA dut->{serial_sink_data}
-""".format(
- serial_source_stb=io_name("serial", "source_stb"),
- serial_source_ack=io_name("serial", "source_ack"),
- serial_source_data=io_name("serial", "source_data"),
-
- serial_sink_stb=io_name("serial", "sink_stb"),
- serial_sink_ack=io_name("serial", "sink_ack"),
- serial_sink_data=io_name("serial", "sink_data"),
- )
- except:
- pass
-
- try:
- ios += """
-#define ETH_SOURCE_STB dut->{eth_source_stb}
-#define ETH_SOURCE_ACK dut->{eth_source_ack}
-#define ETH_SOURCE_DATA dut->{eth_source_data}
-
-#define ETH_SINK_STB dut->{eth_sink_stb}
-#define ETH_SINK_ACK dut->{eth_sink_ack}
-#define ETH_SINK_DATA dut->{eth_sink_data}
-""".format(
- eth_source_stb=io_name("eth", "source_stb"),
- eth_source_ack=io_name("eth", "source_ack"),
- eth_source_data=io_name("eth", "source_data"),
-
- eth_sink_stb=io_name("eth", "sink_stb"),
- eth_sink_ack=io_name("eth", "sink_ack"),
- eth_sink_data=io_name("eth", "sink_data"),
- )
- except:
- pass
-
- content = ""
- f = open(template, "r")
- done = False
- for l in f:
- content += l
- if "/* ios */" in l and not done:
- content += ios
- done = True
-
- f.close()
- tools.write_to_file("dut_tb.cpp", content)
-
-
-def _build_sim(platform, vns, build_name, include_paths, sim_path, serial, verbose):
- include = ""
- for path in include_paths:
- include += "-I"+path+" "
-
- build_script_contents = """# Autogenerated by Migen
- rm -rf obj_dir/
-verilator {disable_warnings} -O3 --cc dut.v --exe dut_tb.cpp -LDFLAGS "-lpthread" -trace {include}
-make -j -C obj_dir/ -f Vdut.mk Vdut
-
-""".format(
- disable_warnings="-Wno-fatal",
- include=include)
- build_script_file = "build_" + build_name + ".sh"
- tools.write_to_file(build_script_file, build_script_contents, force_unix=True)
-
- _build_tb(platform, vns, serial, os.path.join("..", sim_path, "dut_tb.cpp"))
- if verbose:
- r = subprocess.call(["bash", build_script_file])
- else:
- r = subprocess.call(["bash", build_script_file], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
- if r != 0:
- raise OSError("Subprocess failed")
-
-
-def _run_sim(build_name):
- run_script_contents = """obj_dir/Vdut
-"""
- run_script_file = "run_" + build_name + ".sh"
- tools.write_to_file(run_script_file, run_script_contents, force_unix=True)
- r = subprocess.call(["bash", run_script_file])
- if r != 0:
- raise OSError("Subprocess failed")
-
-
-class SimVerilatorToolchain:
- # XXX fir sim_path
- def build(self, platform, fragment, build_dir="build", build_name="top",
- sim_path="../migen/migen/build/sim/", serial="console",
- run=True, verbose=False):
- tools.mkdir_noerror(build_dir)
- os.chdir(build_dir)
-
- if not isinstance(fragment, _Fragment):
- fragment = fragment.get_fragment()
- platform.finalize(fragment)
-
- v_output = platform.get_verilog(fragment)
- named_sc, named_pc = platform.resolve_signals(v_output.ns)
- v_output.write("dut.v")
-
- include_paths = []
- for source in platform.sources:
- path = os.path.dirname(source[0]).replace("\\", "\/")
- if path not in include_paths:
- include_paths.append(path)
- include_paths += platform.verilog_include_paths
- _build_sim(platform, v_output.ns, build_name, include_paths, sim_path, serial, verbose)
-
- if run:
- _run_sim(build_name)
-
- os.chdir("..")
-
- return v_output.ns
+++ /dev/null
-import os
-import struct
-from distutils.version import StrictVersion
-
-
-def mkdir_noerror(d):
- try:
- os.mkdir(d)
- except OSError:
- pass
-
-
-def language_by_filename(name):
- extension = name.rsplit(".")[-1]
- if extension in ["v", "vh", "vo"]:
- return "verilog"
- if extension in ["vhd", "vhdl", "vho"]:
- return "vhdl"
- return None
-
-
-def write_to_file(filename, contents, force_unix=False):
- newline = None
- if force_unix:
- newline = "\n"
- with open(filename, "w", newline=newline) as f:
- f.write(contents)
-
-
-def arch_bits():
- return struct.calcsize("P")*8
-
-
-def versions(path):
- for n in os.listdir(path):
- full = os.path.join(path, n)
- if not os.path.isdir(full):
- continue
- try:
- yield StrictVersion(n)
- except ValueError:
- continue
+++ /dev/null
-from migen.build.xilinx.platform import XilinxPlatform
-from migen.build.xilinx.programmer import UrJTAG, XC3SProg, FpgaProg, VivadoProgrammer, iMPACT, Adept
+++ /dev/null
-import os
-import sys
-from distutils.version import StrictVersion
-
-from migen.fhdl.structure import *
-from migen.fhdl.specials import Instance
-from migen.fhdl.module import Module
-from migen.fhdl.specials import SynthesisDirective
-from migen.genlib.cdc import *
-from migen.genlib.resetsync import AsyncResetSynchronizer
-from migen.genlib.io import *
-
-from migen.build import tools
-
-
-def settings(path, ver=None, sub=None):
- vers = list(tools.versions(path))
- if ver is None:
- ver = max(vers)
- else:
- ver = StrictVersion(ver)
- assert ver in vers
-
- full = os.path.join(path, str(ver))
- if sub:
- full = os.path.join(full, sub)
-
- search = [64, 32]
- if tools.arch_bits() == 32:
- search.reverse()
-
- if sys.platform == "win32" or sys.platform == "cygwin":
- script_ext = "bat"
- else:
- script_ext = "sh"
-
- for b in search:
- settings = os.path.join(full, "settings{0}.{1}".format(b, script_ext))
- if os.path.exists(settings):
- return settings
-
- raise OSError("no settings file found")
-
-
-class XilinxNoRetimingImpl(Module):
- def __init__(self, reg):
- self.specials += SynthesisDirective("attribute register_balancing of {r} is no", r=reg)
-
-
-class XilinxNoRetiming:
- @staticmethod
- def lower(dr):
- return XilinxNoRetimingImpl(dr.reg)
-
-
-class XilinxMultiRegImpl(MultiRegImpl):
- def __init__(self, *args, **kwargs):
- MultiRegImpl.__init__(self, *args, **kwargs)
- self.specials += [SynthesisDirective("attribute shreg_extract of {r} is no", r=r)
- for r in self.regs]
-
-
-class XilinxMultiReg:
- @staticmethod
- def lower(dr):
- return XilinxMultiRegImpl(dr.i, dr.o, dr.odomain, dr.n)
-
-
-class XilinxAsyncResetSynchronizerImpl(Module):
- def __init__(self, cd, async_reset):
- rst1 = Signal()
- self.specials += [
- Instance("FDPE", p_INIT=1, i_D=0, i_PRE=async_reset,
- i_CE=1, i_C=cd.clk, o_Q=rst1),
- Instance("FDPE", p_INIT=1, i_D=rst1, i_PRE=async_reset,
- i_CE=1, i_C=cd.clk, o_Q=cd.rst)
- ]
-
-
-class XilinxAsyncResetSynchronizer:
- @staticmethod
- def lower(dr):
- return XilinxAsyncResetSynchronizerImpl(dr.cd, dr.async_reset)
-
-
-class XilinxDifferentialInputImpl(Module):
- def __init__(self, i_p, i_n, o):
- self.specials += Instance("IBUFDS", i_I=i_p, i_IB=i_n, o_O=o)
-
-
-class XilinxDifferentialInput:
- @staticmethod
- def lower(dr):
- return XilinxDifferentialInputImpl(dr.i_p, dr.i_n, dr.o)
-
-
-class XilinxDifferentialOutputImpl(Module):
- def __init__(self, i, o_p, o_n):
- self.specials += Instance("OBUFDS", i_I=i, o_O=o_p, o_OB=o_n)
-
-
-class XilinxDifferentialOutput:
- @staticmethod
- def lower(dr):
- return XilinxDifferentialOutputImpl(dr.i, dr.o_p, dr.o_n)
-
-
-class XilinxDDROutputImpl(Module):
- def __init__(self, i1, i2, o, clk):
- self.specials += Instance("ODDR2",
- p_DDR_ALIGNMENT="NONE", p_INIT=0, p_SRTYPE="SYNC",
- i_C0=clk, i_C1=~clk, i_CE=1, i_S=0, i_R=0,
- i_D0=i1, i_D1=i2, o_Q=o,
- )
-
-
-class XilinxDDROutput:
- @staticmethod
- def lower(dr):
- return XilinxDDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk)
-
-
-xilinx_special_overrides = {
- NoRetiming: XilinxNoRetiming,
- MultiReg: XilinxMultiReg,
- AsyncResetSynchronizer: XilinxAsyncResetSynchronizer,
- DifferentialInput: XilinxDifferentialInput,
- DifferentialOutput: XilinxDifferentialOutput,
- DDROutput: XilinxDDROutput
-}
-
-
-class XilinxDDROutputImplS7(Module):
- def __init__(self, i1, i2, o, clk):
- self.specials += Instance("ODDR",
- p_DDR_CLK_EDGE="SAME_EDGE",
- i_C=clk, i_CE=1, i_S=0, i_R=0,
- i_D1=i1, i_D2=i2, o_Q=o,
- )
-
-
-class XilinxDDROutputS7:
- @staticmethod
- def lower(dr):
- return XilinxDDROutputImplS7(dr.i1, dr.i2, dr.o, dr.clk)
-
-
-xilinx_s7_special_overrides = {
- DDROutput: XilinxDDROutputS7
-}
+++ /dev/null
-import os
-import subprocess
-import sys
-
-from migen.fhdl.structure import _Fragment
-from migen.build.generic_platform import *
-from migen.build import tools
-from migen.build.xilinx import common
-
-
-def _format_constraint(c):
- if isinstance(c, Pins):
- return "LOC=" + c.identifiers[0]
- elif isinstance(c, IOStandard):
- return "IOSTANDARD=" + c.name
- elif isinstance(c, Drive):
- return "DRIVE=" + str(c.strength)
- elif isinstance(c, Misc):
- return c.misc
-
-
-def _format_ucf(signame, pin, others, resname):
- fmt_c = []
- for c in [Pins(pin)] + others:
- fc = _format_constraint(c)
- if fc is not None:
- fmt_c.append(fc)
- fmt_r = resname[0] + ":" + str(resname[1])
- if resname[2] is not None:
- fmt_r += "." + resname[2]
- return "NET \"" + signame + "\" " + " | ".join(fmt_c) + "; # " + fmt_r + "\n"
-
-
-def _build_ucf(named_sc, named_pc):
- r = ""
- for sig, pins, others, resname in named_sc:
- if len(pins) > 1:
- for i, p in enumerate(pins):
- r += _format_ucf(sig + "(" + str(i) + ")", p, others, resname)
- else:
- r += _format_ucf(sig, pins[0], others, resname)
- if named_pc:
- r += "\n" + "\n\n".join(named_pc)
- return r
-
-
-def _build_xst_files(device, sources, vincpaths, build_name, xst_opt):
- prj_contents = ""
- for filename, language, library in sources:
- prj_contents += language + " " + library + " " + filename + "\n"
- tools.write_to_file(build_name + ".prj", prj_contents)
-
- xst_contents = """run
--ifn {build_name}.prj
--top top
-{xst_opt}
--ofn {build_name}.ngc
--p {device}
-""".format(build_name=build_name, xst_opt=xst_opt, device=device)
- for path in vincpaths:
- xst_contents += "-vlgincdir " + path + "\n"
- tools.write_to_file(build_name + ".xst", xst_contents)
-
-
-def _run_yosys(device, sources, vincpaths, build_name):
- ys_contents = ""
- incflags = ""
- for path in vincpaths:
- incflags += " -I" + path
- for filename, language, library in sources:
- ys_contents += "read_{}{} {}\n".format(language, incflags, filename)
-
- ys_contents += """hierarchy -check -top top
-proc; memory; opt; fsm; opt
-synth_xilinx -top top -edif {build_name}.edif""".format(build_name=build_name)
-
- ys_name = build_name + ".ys"
- tools.write_to_file(ys_name, ys_contents)
- r = subprocess.call(["yosys", ys_name])
- if r != 0:
- raise OSError("Subprocess failed")
-
-
-def _run_ise(build_name, ise_path, source, mode, ngdbuild_opt,
- bitgen_opt, ise_commands, map_opt, par_opt, ver=None):
- if sys.platform == "win32" or sys.platform == "cygwin":
- source_cmd = "call "
- script_ext = ".bat"
- shell = ["cmd", "/c"]
- build_script_contents = "@echo off\nrem Autogenerated by Migen\n"
- else:
- source_cmd = "source "
- script_ext = ".sh"
- shell = ["bash"]
- build_script_contents = "# Autogenerated by Migen\nset -e\n"
- if source:
- settings = common.settings(ise_path, ver, "ISE_DS")
- build_script_contents += source_cmd + settings + "\n"
- if mode == "edif":
- ext = "edif"
- else:
- ext = "ngc"
- build_script_contents += """
-xst -ifn {build_name}.xst
-"""
-
- build_script_contents += """
-ngdbuild {ngdbuild_opt} -uc {build_name}.ucf {build_name}.{ext} {build_name}.ngd
-map {map_opt} -o {build_name}_map.ncd {build_name}.ngd {build_name}.pcf
-par {par_opt} {build_name}_map.ncd {build_name}.ncd {build_name}.pcf
-bitgen {bitgen_opt} {build_name}.ncd {build_name}.bit
-"""
- build_script_contents = build_script_contents.format(build_name=build_name,
- ngdbuild_opt=ngdbuild_opt, bitgen_opt=bitgen_opt, ext=ext,
- par_opt=par_opt, map_opt=map_opt)
- build_script_contents += ise_commands.format(build_name=build_name)
- build_script_file = "build_" + build_name + script_ext
- tools.write_to_file(build_script_file, build_script_contents, force_unix=False)
- command = shell + [build_script_file]
- r = subprocess.call(command)
- if r != 0:
- raise OSError("Subprocess failed")
-
-
-class XilinxISEToolchain:
- def __init__(self):
- self.xst_opt = """-ifmt MIXED
--use_new_parser yes
--opt_mode SPEED
--register_balancing yes"""
- self.map_opt = "-ol high -w"
- self.par_opt = "-ol high -w"
- self.ngdbuild_opt = ""
- self.bitgen_opt = "-g Binary:Yes -w"
- self.ise_commands = ""
-
- def build(self, platform, fragment, build_dir="build", build_name="top",
- toolchain_path=None, source=None, run=True, mode="xst"):
- if not isinstance(fragment, _Fragment):
- fragment = fragment.get_fragment()
- if toolchain_path is None:
- if sys.platform == "win32":
- toolchain_path = "C:\\Xilinx"
- elif sys.platform == "cygwin":
- toolchain_path = "/cygdrive/c/Xilinx"
- else:
- toolchain_path = "/opt/Xilinx"
- if source is None:
- source = sys.platform != "win32"
-
- platform.finalize(fragment)
- ngdbuild_opt = self.ngdbuild_opt
- vns = None
-
- tools.mkdir_noerror(build_dir)
- cwd = os.getcwd()
- os.chdir(build_dir)
- try:
- if mode == "xst" or mode == "yosys":
- v_output = platform.get_verilog(fragment)
- vns = v_output.ns
- named_sc, named_pc = platform.resolve_signals(vns)
- v_file = build_name + ".v"
- v_output.write(v_file)
- sources = platform.sources | {(v_file, "verilog", "work")}
- if mode == "xst":
- _build_xst_files(platform.device, sources, platform.verilog_include_paths, build_name, self.xst_opt)
- isemode = "xst"
- else:
- _run_yosys(platform.device, sources, platform.verilog_include_paths, build_name)
- isemode = "edif"
- ngdbuild_opt += "-p " + platform.device
-
- if mode == "mist":
- from mist import synthesize
- synthesize(fragment, platform.constraint_manager.get_io_signals())
-
- if mode == "edif" or mode == "mist":
- e_output = platform.get_edif(fragment)
- vns = e_output.ns
- named_sc, named_pc = platform.resolve_signals(vns)
- e_file = build_name + ".edif"
- e_output.write(e_file)
- isemode = "edif"
-
- tools.write_to_file(build_name + ".ucf", _build_ucf(named_sc, named_pc))
- if run:
- _run_ise(build_name, toolchain_path, source, isemode,
- ngdbuild_opt, self.bitgen_opt, self.ise_commands,
- self.map_opt, self.par_opt)
- finally:
- os.chdir(cwd)
-
- return vns
-
- def add_period_constraint(self, platform, clk, period):
- platform.add_platform_command("""NET "{clk}" TNM_NET = "GRP{clk}";
-TIMESPEC "TS{clk}" = PERIOD "GRP{clk}" """+str(period)+""" ns HIGH 50%;""", clk=clk)
+++ /dev/null
-from migen.build.generic_platform import GenericPlatform
-from migen.build.xilinx import common, vivado, ise
-
-
-class XilinxPlatform(GenericPlatform):
- bitstream_ext = ".bit"
-
- def __init__(self, *args, toolchain="ise", **kwargs):
- GenericPlatform.__init__(self, *args, **kwargs)
- if toolchain == "ise":
- self.toolchain = ise.XilinxISEToolchain()
- elif toolchain == "vivado":
- self.toolchain = vivado.XilinxVivadoToolchain()
- else:
- raise ValueError("Unknown toolchain")
-
- def get_verilog(self, *args, special_overrides=dict(), **kwargs):
- so = dict(common.xilinx_special_overrides)
- if self.device[:3] == "xc7":
- so.update(common.xilinx_s7_special_overrides)
- so.update(special_overrides)
- return GenericPlatform.get_verilog(self, *args, special_overrides=so, **kwargs)
-
- def get_edif(self, fragment, **kwargs):
- return GenericPlatform.get_edif(self, fragment, "UNISIMS", "Xilinx", self.device, **kwargs)
-
- def build(self, *args, **kwargs):
- return self.toolchain.build(self, *args, **kwargs)
-
- def add_period_constraint(self, clk, period):
- if hasattr(clk, "p"):
- clk = clk.p
- self.toolchain.add_period_constraint(self, clk, period)
+++ /dev/null
-import os
-import sys
-import subprocess
-
-from migen.build.generic_programmer import GenericProgrammer
-from migen.build.xilinx import common
-
-
-def _run_urjtag(cmds):
- with subprocess.Popen("jtag", stdin=subprocess.PIPE) as process:
- process.stdin.write(cmds.encode("ASCII"))
- process.communicate()
-
-
-class UrJTAG(GenericProgrammer):
- needs_bitreverse = True
-
- def __init__(self, cable, flash_proxy_basename=None):
- GenericProgrammer.__init__(self, flash_proxy_basename)
- self.cable = cable
-
- def load_bitstream(self, bitstream_file):
- cmds = """cable {cable}
-detect
-pld load {bitstream}
-quit
-""".format(bitstream=bitstream_file, cable=self.cable)
- _run_urjtag(cmds)
-
- def flash(self, address, data_file):
- flash_proxy = self.find_flash_proxy()
- cmds = """cable {cable}
-detect
-pld load "{flash_proxy}"
-initbus fjmem opcode=000010
-frequency 6000000
-detectflash 0
-endian big
-flashmem "{address}" "{data_file}" noverify
-""".format(flash_proxy=flash_proxy, address=address, data_file=data_file,
- cable=self.cable)
- _run_urjtag(cmds)
-
-
-class XC3SProg(GenericProgrammer):
- needs_bitreverse = False
-
- def __init__(self, cable, flash_proxy_basename=None):
- GenericProgrammer.__init__(self, flash_proxy_basename)
- self.cable = cable
-
- def load_bitstream(self, bitstream_file):
- subprocess.call(["xc3sprog", "-v", "-c", self.cable, bitstream_file])
-
- def flash(self, address, data_file):
- flash_proxy = self.find_flash_proxy()
- subprocess.call(["xc3sprog", "-v", "-c", self.cable, "-I"+flash_proxy, "{}:w:0x{:x}:BIN".format(data_file, address)])
-
-
-
-class FpgaProg(GenericProgrammer):
- needs_bitreverse = False
-
- def __init__(self, flash_proxy_basename=None):
- GenericProgrammer.__init__(self, flash_proxy_basename)
-
- def load_bitstream(self, bitstream_file):
- subprocess.call(["fpgaprog", "-v", "-f", bitstream_file])
-
- def flash(self, address, data_file):
- if address != 0:
- raise ValueError("fpga prog needs a main bitstream at address 0")
- flash_proxy = self.find_flash_proxy()
- subprocess.call(["fpgaprog", "-v", "-sa", "-r", "-b", flash_proxy,
- "-f", data_file])
-
-
-def _run_impact(cmds):
- with subprocess.Popen("impact -batch", stdin=subprocess.PIPE, shell=True) as process:
- process.stdin.write(cmds.encode("ASCII"))
- process.communicate()
- return process.returncode
-
-
-def _create_xsvf(bitstream_file, xsvf_file):
- assert os.path.exists(bitstream_file), bitstream_file
- assert not os.path.exists(xsvf_file), xsvf_file
- assert 0 == _run_impact("""
-setPreference -pref KeepSVF:True
-setMode -bs
-setCable -port xsvf -file {xsvf}
-addDevice -p 1 -file {bitstream}
-program -p 1
-quit
-""".format(bitstream=bitstream_file, xsvf=xsvf_file))
-
-
-class iMPACT(GenericProgrammer):
- needs_bitreverse = False
-
- def load_bitstream(self, bitstream_file):
- cmds = """setMode -bs
-setCable -p auto
-addDevice -p 1 -file {bitstream}
-program -p 1
-quit
-""".format(bitstream=bitstream_file)
- _run_impact(cmds)
-
-
-def _run_vivado(path, ver, cmds):
- if sys.platform == "win32" or sys.platform == "cygwin":
- vivado_cmd = "vivado -mode tcl"
- else:
- settings = common.settings(path, ver)
- vivado_cmd = "bash -c \"source " + settings + "&& vivado -mode tcl\""
- with subprocess.Popen(vivado_cmd, stdin=subprocess.PIPE, shell=True) as process:
- process.stdin.write(cmds.encode("ASCII"))
- process.communicate()
-
-
-class VivadoProgrammer(GenericProgrammer):
- needs_bitreverse = False
- def __init__(self, vivado_path="/opt/Xilinx/Vivado", vivado_ver=None,
- flash_part="n25q256-3.3v-spi-x1_x2_x4"):
- GenericProgrammer.__init__(self)
- self.vivado_path = vivado_path
- self.vivado_ver = vivado_ver
- self.flash_part = flash_part
-
- def load_bitstream(self, bitstream_file):
- cmds = """open_hw
-connect_hw_server
-open_hw_target [lindex [get_hw_targets -of_objects [get_hw_servers localhost]] 0]
-
-set_property PROBES.FILE {{}} [lindex [get_hw_devices] 0]
-set_property PROGRAM.FILE {{{bitstream}}} [lindex [get_hw_devices] 0]
-
-program_hw_devices [lindex [get_hw_devices] 0]
-refresh_hw_device [lindex [get_hw_devices] 0]
-
-quit
-""".format(bitstream=bitstream_file)
- _run_vivado(self.vivado_path, self.vivado_ver, cmds)
-
- # XXX works to flash bitstream, adapt it to flash bios
- def flash(self, address, data_file):
- cmds = """open_hw
-connect_hw_server
-open_hw_target [lindex [get_hw_targets -of_objects [get_hw_servers localhost]] 0]
-create_hw_cfgmem -hw_device [lindex [get_hw_devices] 0] -mem_dev [lindex [get_cfgmem_parts {{{flash_part}}}] 0]
-
-set_property PROGRAM.BLANK_CHECK 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-set_property PROGRAM.ERASE 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-set_property PROGRAM.CFG_PROGRAM 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-set_property PROGRAM.VERIFY 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-refresh_hw_device [lindex [get_hw_devices] 0]
-
-set_property PROGRAM.ADDRESS_RANGE {{use_file}} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-set_property PROGRAM.FILES [list "{data}" ] [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0]]
-set_property PROGRAM.UNUSED_PIN_TERMINATION {{pull-none}} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-set_property PROGRAM.BLANK_CHECK 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-set_property PROGRAM.ERASE 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-set_property PROGRAM.CFG_PROGRAM 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-set_property PROGRAM.VERIFY 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-
-startgroup
-if {{![string equal [get_property PROGRAM.HW_CFGMEM_TYPE [lindex [get_hw_devices] 0]] [get_property MEM_TYPE [get_property CFGMEM_PART [get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]]]] }} {{ create_hw_bitstream -hw_device [lindex [get_hw_devices] 0] [get_property PROGRAM.HW_CFGMEM_BITFILE [ lindex [get_hw_devices] 0]]; program_hw_devices [lindex [get_hw_devices] 0]; }};
-program_hw_cfgmem -hw_cfgmem [get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-endgroup
-
-quit
-""".format(data=data_file, flash_part=self.flash_part)
- _run_vivado(self.vivado_path, self.vivado_ver, cmds)
-
-
-class Adept(GenericProgrammer):
- """Using the Adept tool with an onboard Digilent "USB JTAG" cable.
-
- You need to install Adept Utilities V2 from
- http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,66,828&Prod=ADEPT2
- """
-
- needs_bitreverse = False
-
- def __init__(self, board, index, flash_proxy_basename=None):
- GenericProgrammer.__init__(self, flash_proxy_basename)
- self.board = board
- self.index = index
-
- def load_bitstream(self, bitstream_file):
- subprocess.call([
- "djtgcfg",
- "--verbose",
- "prog", "-d", self.board,
- "-i", str(self.index),
- "-f", bitstream_file,
- ])
-
- def flash(self, address, data_file):
- raise ValueError("Flashing unsupported with DigilentAdept tools")
+++ /dev/null
-# This file is Copyright (c) 2014 Florent Kermarrec <florent@enjoy-digital.fr>
-# License: BSD
-
-import os
-import subprocess
-import sys
-
-from migen.fhdl.structure import _Fragment
-from migen.build.generic_platform import *
-from migen.build import tools
-from migen.build.xilinx import common
-
-
-def _format_constraint(c):
- if isinstance(c, Pins):
- return "set_property LOC " + c.identifiers[0]
- elif isinstance(c, IOStandard):
- return "set_property IOSTANDARD " + c.name
- elif isinstance(c, Drive):
- return "set_property DRIVE " + str(c.strength)
- elif isinstance(c, Misc):
- return "set_property " + c.misc.replace("=", " ")
- else:
- raise ValueError("unknown constraint {}".format(c))
-
-
-def _format_xdc(signame, resname, *constraints):
- fmt_c = [_format_constraint(c) for c in constraints]
- fmt_r = resname[0] + ":" + str(resname[1])
- if resname[2] is not None:
- fmt_r += "." + resname[2]
- r = " ## {}\n".format(fmt_r)
- for c in fmt_c:
- r += c + " [get_ports " + signame + "]\n"
- return r
-
-
-def _build_xdc(named_sc, named_pc):
- r = ""
- for sig, pins, others, resname in named_sc:
- if len(pins) > 1:
- for i, p in enumerate(pins):
- r += _format_xdc(sig + "[" + str(i) + "]", resname, Pins(p), *others)
- elif pins:
- r += _format_xdc(sig, resname, Pins(pins[0]), *others)
- else:
- r += _format_xdc(sig, resname, *others)
- if named_pc:
- r += "\n" + "\n\n".join(named_pc)
- return r
-
-
-def _run_vivado(build_name, vivado_path, source, ver=None):
- if sys.platform == "win32" or sys.platform == "cygwin":
- build_script_contents = "REM Autogenerated by Migen\n"
- build_script_contents += "vivado -mode batch -source " + build_name + ".tcl\n"
- build_script_file = "build_" + build_name + ".bat"
- tools.write_to_file(build_script_file, build_script_contents)
- r = subprocess.call([build_script_file])
- else:
- build_script_contents = "# Autogenerated by Migen\nset -e\n"
- settings = common.settings(vivado_path, ver)
- build_script_contents += "source " + settings + "\n"
- build_script_contents += "vivado -mode batch -source " + build_name + ".tcl\n"
- build_script_file = "build_" + build_name + ".sh"
- tools.write_to_file(build_script_file, build_script_contents)
- r = subprocess.call(["bash", build_script_file])
-
- if r != 0:
- raise OSError("Subprocess failed")
-
-
-class XilinxVivadoToolchain:
- def __init__(self):
- self.bitstream_commands = []
- self.additional_commands = []
- self.pre_synthesis_commands = []
- self.with_phys_opt = False
-
- def _build_batch(self, platform, sources, build_name):
- tcl = []
- for filename, language, library in sources:
- filename_tcl = "{" + filename + "}"
- tcl.append("add_files " + filename_tcl)
- tcl.append("set_property library {} [get_files {}]"
- .format(library, filename_tcl))
-
- tcl.append("read_xdc {}.xdc".format(build_name))
- tcl.extend(c.format(build_name=build_name) for c in self.pre_synthesis_commands)
- tcl.append("synth_design -top top -part {} -include_dirs {{{}}}".format(platform.device, " ".join(platform.verilog_include_paths)))
- tcl.append("report_utilization -hierarchical -file {}_utilization_hierarchical_synth.rpt".format(build_name))
- tcl.append("report_utilization -file {}_utilization_synth.rpt".format(build_name))
- tcl.append("place_design")
- if self.with_phys_opt:
- tcl.append("phys_opt_design -directive AddRetime")
- tcl.append("report_utilization -hierarchical -file {}_utilization_hierarchical_place.rpt".format(build_name))
- tcl.append("report_utilization -file {}_utilization_place.rpt".format(build_name))
- tcl.append("report_io -file {}_io.rpt".format(build_name))
- tcl.append("report_control_sets -verbose -file {}_control_sets.rpt".format(build_name))
- tcl.append("report_clock_utilization -file {}_clock_utilization.rpt".format(build_name))
- tcl.append("route_design")
- tcl.append("report_route_status -file {}_route_status.rpt".format(build_name))
- tcl.append("report_drc -file {}_drc.rpt".format(build_name))
- tcl.append("report_timing_summary -max_paths 10 -file {}_timing.rpt".format(build_name))
- tcl.append("report_power -file {}_power.rpt".format(build_name))
- for bitstream_command in self.bitstream_commands:
- tcl.append(bitstream_command.format(build_name=build_name))
- tcl.append("write_bitstream -force {}.bit ".format(build_name))
- for additional_command in self.additional_commands:
- tcl.append(additional_command.format(build_name=build_name))
- tcl.append("quit")
- tools.write_to_file(build_name + ".tcl", "\n".join(tcl))
-
- def build(self, platform, fragment, build_dir="build", build_name="top",
- toolchain_path="/opt/Xilinx/Vivado", source=True, run=True):
- tools.mkdir_noerror(build_dir)
- os.chdir(build_dir)
-
- if not isinstance(fragment, _Fragment):
- fragment = fragment.get_fragment()
- platform.finalize(fragment)
- v_output = platform.get_verilog(fragment)
- named_sc, named_pc = platform.resolve_signals(v_output.ns)
- v_file = build_name + ".v"
- v_output.write(v_file)
- sources = platform.sources | {(v_file, "verilog", "work")}
- self._build_batch(platform, sources, build_name)
- tools.write_to_file(build_name + ".xdc", _build_xdc(named_sc, named_pc))
- if run:
- _run_vivado(build_name, toolchain_path, source)
-
- os.chdir("..")
-
- return v_output.ns
-
- def add_period_constraint(self, platform, clk, period):
- platform.add_platform_command("""create_clock -name {clk} -period """ + \
- str(period) + """ [get_ports {clk}]""", clk=clk)
+++ /dev/null
-from migen.fhdl import structure as f
-
-
-__all__ = ["log2_int", "bits_for", "value_bits_sign"]
-
-
-def log2_int(n, need_pow2=True):
- l = 1
- r = 0
- while l < n:
- l *= 2
- r += 1
- if need_pow2 and l != n:
- raise ValueError("Not a power of 2")
- return r
-
-
-def bits_for(n, require_sign_bit=False):
- if n > 0:
- r = log2_int(n + 1, False)
- else:
- require_sign_bit = True
- r = log2_int(-n, False)
- if require_sign_bit:
- r += 1
- return r
-
-
-def value_bits_sign(v):
- """Bit length and signedness of a value.
-
- Parameters
- ----------
- v : Value
-
- Returns
- -------
- int, bool
- Number of bits required to store `v` or available in `v`, followed by
- whether `v` has a sign bit (included in the bit count).
-
- Examples
- --------
- >>> value_bits_sign(f.Signal(8))
- 8, False
- >>> value_bits_sign(C(0xaa))
- 8, False
- """
- if isinstance(v, (f.Constant, f.Signal)):
- return v.nbits, v.signed
- elif isinstance(v, (f.ClockSignal, f.ResetSignal)):
- return 1, False
- elif isinstance(v, f._Operator):
- obs = list(map(value_bits_sign, v.operands))
- if v.op == "+" or v.op == "-":
- if not obs[0][1] and not obs[1][1]:
- # both operands unsigned
- return max(obs[0][0], obs[1][0]) + 1, False
- elif obs[0][1] and obs[1][1]:
- # both operands signed
- return max(obs[0][0], obs[1][0]) + 1, True
- elif not obs[0][1] and obs[1][1]:
- # first operand unsigned (add sign bit), second operand signed
- return max(obs[0][0] + 1, obs[1][0]) + 1, True
- else:
- # first signed, second operand unsigned (add sign bit)
- return max(obs[0][0], obs[1][0] + 1) + 1, True
- elif v.op == "*":
- if not obs[0][1] and not obs[1][1]:
- # both operands unsigned
- return obs[0][0] + obs[1][0], False
- elif obs[0][1] and obs[1][1]:
- # both operands signed
- return obs[0][0] + obs[1][0] - 1, True
- else:
- # one operand signed, the other unsigned (add sign bit)
- return obs[0][0] + obs[1][0] + 1 - 1, True
- elif v.op == "<<<":
- if obs[1][1]:
- extra = 2**(obs[1][0] - 1) - 1
- else:
- extra = 2**obs[1][0] - 1
- return obs[0][0] + extra, obs[0][1]
- elif v.op == ">>>":
- if obs[1][1]:
- extra = 2**(obs[1][0] - 1)
- else:
- extra = 0
- return obs[0][0] + extra, obs[0][1]
- elif v.op == "&" or v.op == "^" or v.op == "|":
- if not obs[0][1] and not obs[1][1]:
- # both operands unsigned
- return max(obs[0][0], obs[1][0]), False
- elif obs[0][1] and obs[1][1]:
- # both operands signed
- return max(obs[0][0], obs[1][0]), True
- elif not obs[0][1] and obs[1][1]:
- # first operand unsigned (add sign bit), second operand signed
- return max(obs[0][0] + 1, obs[1][0]), True
- else:
- # first signed, second operand unsigned (add sign bit)
- return max(obs[0][0], obs[1][0] + 1), True
- elif v.op == "<" or v.op == "<=" or v.op == "==" or v.op == "!=" \
- or v.op == ">" or v.op == ">=":
- return 1, False
- elif v.op == "~":
- return obs[0]
- else:
- raise TypeError
- elif isinstance(v, f._Slice):
- return v.stop - v.start, value_bits_sign(v.value)[1]
- elif isinstance(v, f.Cat):
- return sum(value_bits_sign(sv)[0] for sv in v.l), False
- elif isinstance(v, f.Replicate):
- return (value_bits_sign(v.v)[0])*v.n, False
- elif isinstance(v, f._ArrayProxy):
- bsc = list(map(value_bits_sign, v.choices))
- return max(bs[0] for bs in bsc), any(bs[1] for bs in bsc)
- else:
- raise TypeError("Can not calculate bit length of {} {}".format(
- type(v), v))
+++ /dev/null
-from operator import itemgetter
-
-
-class ConvOutput:
- def __init__(self):
- self.main_source = ""
- self.data_files = dict()
-
- def set_main_source(self, src):
- self.main_source = src
-
- def add_data_file(self, filename_base, content):
- filename = filename_base
- i = 1
- while filename in self.data_files:
- parts = filename_base.split(".", maxsplit=1)
- parts[0] += "_" + str(i)
- filename = ".".join(parts)
- i += 1
- self.data_files[filename] = content
- return filename
-
- def __str__(self):
- r = self.main_source + "\n"
- for filename, content in sorted(self.data_files.items(),
- key=itemgetter(0)):
- r += filename + ":\n" + content
- return r
-
- def write(self, main_filename):
- with open(main_filename, "w") as f:
- f.write(self.main_source)
- for filename, content in self.data_files.items():
- with open(filename, "w") as f:
- f.write(content)
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-from migen.fhdl.tools import insert_reset, rename_clock_domain
-
-
-__all__ = ["CEInserter", "ResetInserter", "ClockDomainsRenamer",
- "ModuleTransformer"]
-
-
-class ModuleTransformer:
- # overload this in derived classes
- def transform_instance(self, i):
- pass
-
- # overload this in derived classes
- def transform_fragment(self, i, f):
- pass
-
- def wrap_class(self, victim):
- class Wrapped(victim):
- def __init__(i, *args, **kwargs):
- victim.__init__(i, *args, **kwargs)
- self.transform_instance(i)
-
- def get_fragment(i):
- f = victim.get_fragment(i)
- self.transform_fragment(i, f)
- return f
-
- Wrapped.__name__ = victim.__name__
- # "{}_{}".format(self.__class__.__name__, victim.__name__)
- return Wrapped
-
- def wrap_instance(self, victim):
- self.transform_instance(victim)
- orig_get_fragment = victim.get_fragment
-
- def get_fragment():
- f = orig_get_fragment()
- self.transform_fragment(victim, f)
- return f
-
- victim.get_fragment = get_fragment
- return victim
-
- def __call__(self, victim):
- if isinstance(victim, Module):
- return self.wrap_instance(victim)
- else:
- return self.wrap_class(victim)
-
-
-class ControlInserter(ModuleTransformer):
- control_name = None # override this
-
- def __init__(self, clock_domains=None):
- self.clock_domains = clock_domains
-
- def transform_instance(self, i):
- if self.clock_domains is None:
- ctl = Signal(name=self.control_name)
- assert not hasattr(i, self.control_name)
- setattr(i, self.control_name, ctl)
- else:
- for cd in self.clock_domains:
- name = self.control_name + "_" + cd
- ctl = Signal(name=name)
- assert not hasattr(i, name)
- setattr(i, name, ctl)
-
- def transform_fragment(self, i, f):
- if self.clock_domains is None:
- if len(f.sync) != 1:
- raise ValueError("Control signal clock domains must be specified when module has more than one domain")
- cdn = list(f.sync.keys())[0]
- to_insert = [(getattr(i, self.control_name), cdn)]
- else:
- to_insert = [(getattr(i, self.control_name + "_" + cdn), cdn)
- for cdn in self.clock_domains]
- self.transform_fragment_insert(i, f, to_insert)
-
-
-class CEInserter(ControlInserter):
- control_name = "ce"
-
- def transform_fragment_insert(self, i, f, to_insert):
- for ce, cdn in to_insert:
- f.sync[cdn] = [If(ce, *f.sync[cdn])]
-
-
-class ResetInserter(ControlInserter):
- control_name = "reset"
-
- def transform_fragment_insert(self, i, f, to_insert):
- for reset, cdn in to_insert:
- f.sync[cdn] = insert_reset(reset, f.sync[cdn])
-
-
-class ClockDomainsRenamer(ModuleTransformer):
- def __init__(self, cd_remapping):
- if isinstance(cd_remapping, str):
- cd_remapping = {"sys": cd_remapping}
- self.cd_remapping = cd_remapping
-
- def transform_fragment(self, i, f):
- for old, new in self.cd_remapping.items():
- rename_clock_domain(f, old, new)
+++ /dev/null
-from collections import OrderedDict, namedtuple
-
-from migen.fhdl.structure import *
-from migen.fhdl.namer import build_namespace
-from migen.fhdl.tools import list_special_ios
-from migen.fhdl.structure import _Fragment
-from migen.fhdl.conv_output import ConvOutput
-
-
-_Port = namedtuple("_Port", "name direction")
-_Cell = namedtuple("_Cell", "name ports")
-_Property = namedtuple("_Property", "name value")
-_Instance = namedtuple("_Instance", "name cell properties")
-_NetBranch = namedtuple("_NetBranch", "portname instancename")
-
-
-def _write_cells(cells):
- r = ""
- for cell in cells:
- r += """
- (cell {0.name}
- (cellType GENERIC)
- (view view_1
- (viewType NETLIST)
- (interface""".format(cell)
- for port in cell.ports:
- r += """
- (port {0.name} (direction {0.direction}))""".format(port)
- r += """
- )
- )
- )"""
- return r
-
-
-def _write_io(ios):
- r = ""
- for s in ios:
- r += """
- (port {0.name} (direction {0.direction}))""".format(s)
- return r
-
-
-def _write_instantiations(instances, cell_library):
- instantiations = ""
- for instance in instances:
- instantiations += """
- (instance {0.name}
- (viewRef view_1 (cellRef {0.cell} (libraryRef {1})))""".format(instance, cell_library)
- for prop in instance.properties:
- instantiations += """
- (property {0} (string "{1}"))""".format(prop.name, prop.value)
- instantiations += """
- )"""
- return instantiations
-
-
-def _write_connections(connections):
- r = ""
- for netname, branches in connections.items():
- r += """
- (net {0}
- (joined""".format(netname)
- for branch in branches:
- r += """
- (portRef {0}{1})""".format(branch.portname, "" if branch.instancename == "" else " (instanceRef {})".format(branch.instancename))
- r += """
- )
- )"""
- return r
-
-
-def _write_edif(cells, ios, instances, connections, cell_library, design_name, part, vendor):
- r = """(edif {0}
- (edifVersion 2 0 0)
- (edifLevel 0)
- (keywordMap (keywordLevel 0))
- (external {1}
- (edifLevel 0)
- (technology (numberDefinition))""".format(design_name, cell_library)
- r += _write_cells(cells)
- r += """
- )
- (library {0}_lib
- (edifLevel 0)
- (technology (numberDefinition))
- (cell {0}
- (cellType GENERIC)
- (view view_1
- (viewType NETLIST)
- (interface""".format(design_name)
- r += _write_io(ios)
- r += """
- (designator "{0}")
- )
- (contents""".format(part)
- r += _write_instantiations(instances, cell_library)
- r += _write_connections(connections)
- r += """
- )
- )
- )
- )
- (design {0}
- (cellRef {0} (libraryRef {0}_lib))
- (property PART (string "{1}") (owner "{2}"))
- )
-)""".format(design_name, part, vendor)
-
- return r
-
-
-def _generate_cells(f):
- cell_dict = OrderedDict()
- for special in f.specials:
- if isinstance(special, Instance):
- port_list = []
- for port in special.items:
- if isinstance(port, Instance.Input):
- port_list.append(_Port(port.name, "INPUT"))
- elif isinstance(port, Instance.Output):
- port_list.append(_Port(port.name, "OUTPUT"))
- elif isinstance(port, Instance.InOut):
- port_list.append(_Port(port.name, "INOUT"))
- elif isinstance(port, Instance.Parameter):
- pass
- else:
- raise NotImplementedError("Unsupported instance item")
- if special.of in cell_dict:
- if set(port_list) != set(cell_dict[special.of]):
- raise ValueError("All instances must have the same ports for EDIF conversion")
- else:
- cell_dict[special.of] = port_list
- else:
- raise ValueError("EDIF conversion can only handle synthesized fragments")
- return [_Cell(k, v) for k, v in cell_dict.items()]
-
-
-def _generate_instances(f, ns):
- instances = []
- for special in f.specials:
- if isinstance(special, Instance):
- props = []
- for prop in special.items:
- if isinstance(prop, Instance.Input):
- pass
- elif isinstance(prop, Instance.Output):
- pass
- elif isinstance(prop, Instance.InOut):
- pass
- elif isinstance(prop, Instance.Parameter):
- props.append(_Property(name=prop.name, value=prop.value))
- else:
- raise NotImplementedError("Unsupported instance item")
- instances.append(_Instance(name=ns.get_name(special), cell=special.of, properties=props))
- else:
- raise ValueError("EDIF conversion can only handle synthesized fragments")
- return instances
-
-
-def _generate_ios(f, ios, ns):
- outs = list_special_ios(f, False, True, False)
- inouts = list_special_ios(f, False, False, True)
- r = []
- for io in ios:
- direction = "OUTPUT" if io in outs else "INOUT" if io in inouts else "INPUT"
- r.append(_Port(name=ns.get_name(io), direction=direction))
- return r
-
-
-def _generate_connections(f, ios, ns):
- r = OrderedDict()
- for special in f.specials:
- if isinstance(special, Instance):
- instname = ns.get_name(special)
- for port in special.items:
- if isinstance(port, Instance._IO):
- s = ns.get_name(port.expr)
- if s not in r:
- r[s] = []
- r[s].append(_NetBranch(portname=port.name, instancename=instname))
- elif isinstance(port, Instance.Parameter):
- pass
- else:
- raise NotImplementedError("Unsupported instance item")
- else:
- raise ValueError("EDIF conversion can only handle synthesized fragments")
- for s in ios:
- io = ns.get_name(s)
- if io not in r:
- r[io] = []
- r[io].append(_NetBranch(portname=io, instancename=""))
- return r
-
-
-def convert(f, ios, cell_library, vendor, device, name="top"):
- if not isinstance(f, _Fragment):
- f = f.get_fragment()
- if f.comb != [] or f.sync != {}:
- raise ValueError("EDIF conversion can only handle synthesized fragments")
- if ios is None:
- ios = set()
- cells = _generate_cells(f)
- ns = build_namespace(list_special_ios(f, True, True, True))
- instances = _generate_instances(f, ns)
- inouts = _generate_ios(f, ios, ns)
- connections = _generate_connections(f, ios, ns)
- src = _write_edif(cells, inouts, instances, connections, cell_library, name, device, vendor)
-
- r = ConvOutput()
- r.set_main_source(src)
- r.ns = ns
- return r
+++ /dev/null
-import collections
-from itertools import combinations
-
-from migen.util.misc import flat_iteration
-from migen.fhdl.structure import *
-from migen.fhdl.structure import _Fragment
-from migen.fhdl.tools import rename_clock_domain
-
-
-__all__ = ["Module", "FinalizeError"]
-
-
-class FinalizeError(Exception):
- pass
-
-
-def _flat_list(e):
- if isinstance(e, collections.Iterable):
- return flat_iteration(e)
- else:
- return [e]
-
-
-class _ModuleProxy:
- def __init__(self, fm):
- object.__setattr__(self, "_fm", fm)
-
-
-class _ModuleComb(_ModuleProxy):
- def __iadd__(self, other):
- self._fm._fragment.comb += _flat_list(other)
- return self
-
-
-def _cd_append(d, key, statements):
- try:
- l = d[key]
- except KeyError:
- l = []
- d[key] = l
- l += _flat_list(statements)
-
-
-class _ModuleSyncCD:
- def __init__(self, fm, cd):
- self._fm = fm
- self._cd = cd
-
- def __iadd__(self, other):
- _cd_append(self._fm._fragment.sync, self._cd, other)
- return self
-
-
-class _ModuleSync(_ModuleProxy):
- def __iadd__(self, other):
- _cd_append(self._fm._fragment.sync, "sys", other)
- return self
-
- def __getattr__(self, name):
- return _ModuleSyncCD(self._fm, name)
-
- def __setattr__(self, name, value):
- if not isinstance(value, _ModuleSyncCD):
- raise AttributeError("Attempted to assign sync property - use += instead")
-
-
-# _ModuleForwardAttr enables user classes to do e.g.:
-# self.subm.foobar = SomeModule()
-# and then access the submodule with self.foobar.
-class _ModuleForwardAttr:
- def __setattr__(self, name, value):
- self.__iadd__(value)
- setattr(self._fm, name, value)
-
-
-class _ModuleSpecials(_ModuleProxy, _ModuleForwardAttr):
- def __iadd__(self, other):
- self._fm._fragment.specials |= set(_flat_list(other))
- return self
-
-
-class _ModuleSubmodules(_ModuleProxy):
- def __setattr__(self, name, value):
- self._fm._submodules += [(name, e) for e in _flat_list(value)]
- setattr(self._fm, name, value)
-
- def __iadd__(self, other):
- self._fm._submodules += [(None, e) for e in _flat_list(other)]
- return self
-
-
-class _ModuleClockDomains(_ModuleProxy, _ModuleForwardAttr):
- def __iadd__(self, other):
- self._fm._fragment.clock_domains += _flat_list(other)
- return self
-
-
-class Module:
- def get_fragment(self):
- assert(not self.get_fragment_called)
- self.get_fragment_called = True
- self.finalize()
- return self._fragment
-
- def __getattr__(self, name):
- if name == "comb":
- return _ModuleComb(self)
- elif name == "sync":
- return _ModuleSync(self)
- elif name == "specials":
- return _ModuleSpecials(self)
- elif name == "submodules":
- return _ModuleSubmodules(self)
- elif name == "clock_domains":
- return _ModuleClockDomains(self)
-
- # hack to have initialized regular attributes without using __init__
- # (which would require derived classes to call it)
- elif name == "finalized":
- self.finalized = False
- return self.finalized
- elif name == "_fragment":
- self._fragment = _Fragment()
- return self._fragment
- elif name == "_submodules":
- self._submodules = []
- return self._submodules
- elif name == "_clock_domains":
- self._clock_domains = []
- return self._clock_domains
- elif name == "get_fragment_called":
- self.get_fragment_called = False
- return self.get_fragment_called
-
- else:
- raise AttributeError("'"+self.__class__.__name__+"' object has no attribute '"+name+"'")
-
- def __setattr__(self, name, value):
- if name in ["comb", "sync", "specials", "submodules", "clock_domains"]:
- if not isinstance(value, _ModuleProxy):
- raise AttributeError("Attempted to assign special Module property - use += instead")
- else:
- object.__setattr__(self, name, value)
-
- def _collect_submodules(self):
- r = []
- for name, submodule in self._submodules:
- if not submodule.get_fragment_called:
- r.append((name, submodule.get_fragment()))
- return r
-
- def finalize(self, *args, **kwargs):
- if not self.finalized:
- self.finalized = True
- # finalize existing submodules before finalizing us
- subfragments = self._collect_submodules()
- self.do_finalize(*args, **kwargs)
- # finalize submodules created by do_finalize
- subfragments += self._collect_submodules()
- # resolve clock domain name conflicts
- needs_renaming = set()
- for (mod_name1, f1), (mod_name2, f2) in combinations(subfragments, 2):
- f1_names = set(cd.name for cd in f1.clock_domains)
- f2_names = set(cd.name for cd in f2.clock_domains)
- common_names = f1_names & f2_names
- if common_names:
- if mod_name1 is None or mod_name2 is None:
- raise ValueError("Multiple submodules with local clock domains cannot be anonymous")
- if mod_name1 == mod_name2:
- raise ValueError("Multiple submodules with local clock domains cannot have the same name")
- needs_renaming |= common_names
- for mod_name, f in subfragments:
- for cd in f.clock_domains:
- if cd.name in needs_renaming:
- rename_clock_domain(f, cd.name, mod_name + "_" + cd.name)
- # sum subfragments
- for mod_name, f in subfragments:
- self._fragment += f
-
- def do_finalize(self):
- pass
-
- def do_exit(self, *args, **kwargs):
- for name, submodule in self._submodules:
- submodule.do_exit(*args, **kwargs)
+++ /dev/null
-from collections import OrderedDict
-from itertools import combinations
-
-from migen.fhdl.structure import *
-
-
-class _Node:
- def __init__(self):
- self.signal_count = 0
- self.numbers = set()
- self.use_name = False
- self.use_number = False
- self.children = OrderedDict()
-
-
-def _display_tree(filename, tree):
- from migen.util.treeviz import RenderNode
-
- def _to_render_node(name, node):
- children = [_to_render_node(k, v) for k, v in node.children.items()]
- if node.use_name:
- if node.use_number:
- color = (0.5, 0.9, 0.8)
- else:
- color = (0.8, 0.5, 0.9)
- else:
- if node.use_number:
- color = (0.9, 0.8, 0.5)
- else:
- color = (0.8, 0.8, 0.8)
- label = "{0}\n{1} signals\n{2}".format(name, node.signal_count, node.numbers)
- return RenderNode(label, children, color=color)
-
- top = _to_render_node("top", tree)
- top.to_svg(filename)
-
-
-def _build_tree(signals, basic_tree=None):
- root = _Node()
- for signal in signals:
- current_b = basic_tree
- current = root
- current.signal_count += 1
- for name, number in signal.backtrace:
- if basic_tree is None:
- use_number = False
- else:
- current_b = current_b.children[name]
- use_number = current_b.use_number
- if use_number:
- key = (name, number)
- else:
- key = name
- try:
- current = current.children[key]
- except KeyError:
- new = _Node()
- current.children[key] = new
- current = new
- current.numbers.add(number)
- if use_number:
- current.all_numbers = sorted(current_b.numbers)
- current.signal_count += 1
- return root
-
-
-def _set_use_name(node, node_name=""):
- cnames = [(k, _set_use_name(v, k)) for k, v in node.children.items()]
- for (c1_prefix, c1_names), (c2_prefix, c2_names) in combinations(cnames, 2):
- if not c1_names.isdisjoint(c2_names):
- node.children[c1_prefix].use_name = True
- node.children[c2_prefix].use_name = True
- r = set()
- for c_prefix, c_names in cnames:
- if node.children[c_prefix].use_name:
- for c_name in c_names:
- r.add((c_prefix, ) + c_name)
- else:
- r |= c_names
-
- if node.signal_count > sum(c.signal_count for c in node.children.values()):
- node.use_name = True
- r.add((node_name, ))
-
- return r
-
-
-def _name_signal(tree, signal):
- elements = []
- treepos = tree
- for step_name, step_n in signal.backtrace:
- try:
- treepos = treepos.children[(step_name, step_n)]
- use_number = True
- except KeyError:
- treepos = treepos.children[step_name]
- use_number = False
- if treepos.use_name:
- elname = step_name
- if use_number:
- elname += str(treepos.all_numbers.index(step_n))
- elements.append(elname)
- return "_".join(elements)
-
-
-def _build_pnd_from_tree(tree, signals):
- return dict((signal, _name_signal(tree, signal)) for signal in signals)
-
-
-def _invert_pnd(pnd):
- inv_pnd = dict()
- for k, v in pnd.items():
- inv_pnd[v] = inv_pnd.get(v, [])
- inv_pnd[v].append(k)
- return inv_pnd
-
-
-def _list_conflicting_signals(pnd):
- inv_pnd = _invert_pnd(pnd)
- r = set()
- for k, v in inv_pnd.items():
- if len(v) > 1:
- r.update(v)
- return r
-
-
-def _set_use_number(tree, signals):
- for signal in signals:
- current = tree
- for step_name, step_n in signal.backtrace:
- current = current.children[step_name]
- current.use_number = current.signal_count > len(current.numbers) and len(current.numbers) > 1
-
-_debug = False
-
-
-def _build_pnd_for_group(group_n, signals):
- basic_tree = _build_tree(signals)
- _set_use_name(basic_tree)
- if _debug:
- _display_tree("tree{0}_basic.svg".format(group_n), basic_tree)
- pnd = _build_pnd_from_tree(basic_tree, signals)
-
- # If there are conflicts, try splitting the tree by numbers
- # on paths taken by conflicting signals.
- conflicting_signals = _list_conflicting_signals(pnd)
- if conflicting_signals:
- _set_use_number(basic_tree, conflicting_signals)
- if _debug:
- print("namer: using split-by-number strategy (group {0})".format(group_n))
- _display_tree("tree{0}_marked.svg".format(group_n), basic_tree)
- numbered_tree = _build_tree(signals, basic_tree)
- _set_use_name(numbered_tree)
- if _debug:
- _display_tree("tree{0}_numbered.svg".format(group_n), numbered_tree)
- pnd = _build_pnd_from_tree(numbered_tree, signals)
- else:
- if _debug:
- print("namer: using basic strategy (group {0})".format(group_n))
-
- # ...then add number suffixes by DUID
- inv_pnd = _invert_pnd(pnd)
- duid_suffixed = False
- for name, signals in inv_pnd.items():
- if len(signals) > 1:
- duid_suffixed = True
- for n, signal in enumerate(sorted(signals, key=lambda x: x.duid)):
- pnd[signal] += str(n)
- if _debug and duid_suffixed:
- print("namer: using DUID suffixes (group {0})".format(group_n))
-
- return pnd
-
-
-def _build_signal_groups(signals):
- r = []
- for signal in signals:
- # build chain of related signals
- related_list = []
- cur_signal = signal
- while cur_signal is not None:
- related_list.insert(0, cur_signal)
- cur_signal = cur_signal.related
- # add to groups
- for _ in range(len(related_list) - len(r)):
- r.append(set())
- for target_set, source_signal in zip(r, related_list):
- target_set.add(source_signal)
- # with the algorithm above and a list of all signals,
- # a signal appears in all groups of a lower number than its.
- # make signals appear only in their group of highest number.
- for s1, s2 in zip(r, r[1:]):
- s1 -= s2
- return r
-
-
-def _build_pnd(signals):
- groups = _build_signal_groups(signals)
- gpnds = [_build_pnd_for_group(n, gsignals) for n, gsignals in enumerate(groups)]
-
- pnd = dict()
- for gn, gpnd in enumerate(gpnds):
- for signal, name in gpnd.items():
- result = name
- cur_gn = gn
- cur_signal = signal
- while cur_signal.related is not None:
- cur_signal = cur_signal.related
- cur_gn -= 1
- result = gpnds[cur_gn][cur_signal] + "_" + result
- pnd[signal] = result
-
- return pnd
-
-
-def build_namespace(signals, reserved_keywords=set()):
- pnd = _build_pnd(signals)
- ns = Namespace(pnd, reserved_keywords)
- # register signals with name_override
- for signal in signals:
- if signal.name_override is not None:
- ns.get_name(signal)
- return ns
-
-
-class Namespace:
- def __init__(self, pnd, reserved_keywords=set()):
- self.counts = {k: 1 for k in reserved_keywords}
- self.sigs = {}
- self.pnd = pnd
- self.clock_domains = dict()
-
- def get_name(self, sig):
- if isinstance(sig, ClockSignal):
- sig = self.clock_domains[sig.cd].clk
- if isinstance(sig, ResetSignal):
- sig = self.clock_domains[sig.cd].rst
- if sig is None:
- raise ValueError("Attempted to obtain name of non-existent "
- "reset signal of domain "+sig.cd)
-
- if sig.name_override is not None:
- sig_name = sig.name_override
- else:
- sig_name = self.pnd[sig]
- try:
- n = self.sigs[sig]
- except KeyError:
- try:
- n = self.counts[sig_name]
- except KeyError:
- n = 0
- self.sigs[sig] = n
- self.counts[sig_name] = n + 1
- if n:
- return sig_name + "_" + str(n)
- else:
- return sig_name
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.specials import Memory, _MemoryPort, WRITE_FIRST, NO_CHANGE
-from migen.fhdl.decorators import ModuleTransformer
-from migen.util.misc import gcd_multiple
-
-
-class FullMemoryWE(ModuleTransformer):
- def __init__(self):
- self.replacments = dict()
-
- def transform_fragment(self, i, f):
- newspecials = set()
-
- for orig in f.specials:
- if not isinstance(orig, Memory):
- newspecials.add(orig)
- continue
- global_granularity = gcd_multiple([p.we_granularity if p.we_granularity else orig.width for p in orig.ports])
- if global_granularity == orig.width:
- newspecials.add(orig) # nothing to do
- else:
- newmems = []
- for i in range(orig.width//global_granularity):
- if orig.init is None:
- newinit = None
- else:
- newinit = [(v >> i*global_granularity) & (2**global_granularity - 1) for v in orig.init]
- newmem = Memory(global_granularity, orig.depth, newinit, orig.name_override + "_grain" + str(i))
- newspecials.add(newmem)
- newmems.append(newmem)
- for port in orig.ports:
- port_granularity = port.we_granularity if port.we_granularity else orig.width
- newport = _MemoryPort(
- adr=port.adr,
-
- dat_r=port.dat_r[i*global_granularity:(i+1)*global_granularity] if port.dat_r is not None else None,
- we=port.we[i*global_granularity//port_granularity] if port.we is not None else None,
- dat_w=port.dat_w[i*global_granularity:(i+1)*global_granularity] if port.dat_w is not None else None,
-
- async_read=port.async_read,
- re=port.re,
- we_granularity=0,
- mode=port.mode,
- clock_domain=port.clock.cd)
- newmem.ports.append(newport)
- newspecials.add(newport)
- self.replacments[orig] = newmems
-
- f.specials = newspecials
-
-
-class MemoryToArray(ModuleTransformer):
- def __init__(self):
- self.replacements = dict()
-
- def transform_fragment(self, i, f):
- newspecials = set()
-
- for mem in f.specials:
- if not isinstance(mem, Memory):
- newspecials.add(mem)
- continue
-
- storage = Array()
- self.replacements[mem] = storage
- init = []
- if mem.init is not None:
- init = mem.init
- for d in init:
- mem_storage = Signal(mem.width, reset=d)
- storage.append(mem_storage)
- for _ in range(mem.depth-len(init)):
- mem_storage = Signal(mem.width)
- storage.append(mem_storage)
-
- for port in mem.ports:
- if port.we_granularity:
- raise NotImplementedError
- try:
- sync = f.sync[port.clock.cd]
- except KeyError:
- sync = f.sync[port.clock.cd] = []
-
- # read
- if port.async_read:
- f.comb.append(port.dat_r.eq(storage[port.adr]))
- else:
- if port.mode == WRITE_FIRST and port.we is not None:
- adr_reg = Signal.like(port.adr)
- rd_stmt = adr_reg.eq(port.adr)
- f.comb.append(port.dat_r.eq(storage[adr_reg]))
- elif port.mode == NO_CHANGE and port.we is not None:
- rd_stmt = If(~port.we, port.dat_r.eq(storage[port.adr]))
- else: # READ_FIRST or port.we is None, simplest case
- rd_stmt = port.dat_r.eq(storage[port.adr])
- if port.re is None:
- sync.append(rd_stmt)
- else:
- sync.append(If(port.re, rd_stmt))
-
- # write
- if port.we is not None:
- if port.we_granularity:
- n = mem.width//port.we_granularity
- for i in range(n):
- m = i*port.we_granularity
- M = (i+1)*port.we_granularity
- sync.append(If(port.we[i],
- storage[port.adr][m:M].eq(port.dat_w)))
- else:
- sync.append(If(port.we,
- storage[port.adr].eq(port.dat_w)))
-
- f.specials = newspecials
+++ /dev/null
-from operator import itemgetter
-
-from migen.fhdl.structure import *
-from migen.fhdl.structure import _Value
-from migen.fhdl.bitcontainer import bits_for, value_bits_sign
-from migen.fhdl.tools import *
-from migen.fhdl.tracer import get_obj_var_name
-from migen.fhdl.verilog import _printexpr as verilog_printexpr
-
-
-__all__ = ["TSTriple", "Instance", "Memory",
- "READ_FIRST", "WRITE_FIRST", "NO_CHANGE"]
-
-
-class Special(DUID):
- def iter_expressions(self):
- for x in []:
- yield x
-
- def rename_clock_domain(self, old, new):
- for obj, attr, direction in self.iter_expressions():
- rename_clock_domain_expr(getattr(obj, attr), old, new)
-
- def list_clock_domains(self):
- r = set()
- for obj, attr, direction in self.iter_expressions():
- r |= list_clock_domains_expr(getattr(obj, attr))
- return r
-
- def list_ios(self, ins, outs, inouts):
- r = set()
- for obj, attr, direction in self.iter_expressions():
- if (direction == SPECIAL_INPUT and ins) \
- or (direction == SPECIAL_OUTPUT and outs) \
- or (direction == SPECIAL_INOUT and inouts):
- signals = list_signals(getattr(obj, attr))
- r.update(signals)
- return r
-
-
-class Tristate(Special):
- def __init__(self, target, o, oe, i=None):
- Special.__init__(self)
- self.target = wrap(target)
- self.o = wrap(o)
- self.oe = wrap(oe)
- self.i = wrap(i) if i is not None else None
-
- def iter_expressions(self):
- for attr, target_context in [
- ("target", SPECIAL_INOUT),
- ("o", SPECIAL_INPUT),
- ("oe", SPECIAL_INPUT),
- ("i", SPECIAL_OUTPUT)]:
- if getattr(self, attr) is not None:
- yield self, attr, target_context
-
- @staticmethod
- def emit_verilog(tristate, ns, add_data_file):
- def pe(e):
- return verilog_printexpr(ns, e)[0]
- w, s = value_bits_sign(tristate.target)
- r = "assign " + pe(tristate.target) + " = " \
- + pe(tristate.oe) + " ? " + pe(tristate.o) \
- + " : " + str(w) + "'bz;\n"
- if tristate.i is not None:
- r += "assign " + pe(tristate.i) + " = " + pe(tristate.target) + ";\n"
- r += "\n"
- return r
-
-
-class TSTriple:
- def __init__(self, bits_sign=None, min=None, max=None, reset_o=0, reset_oe=0):
- self.o = Signal(bits_sign, min=min, max=max, reset=reset_o)
- self.oe = Signal(reset=reset_oe)
- self.i = Signal(bits_sign, min=min, max=max)
-
- def get_tristate(self, target):
- return Tristate(target, self.o, self.oe, self.i)
-
-
-class Instance(Special):
- class _IO:
- def __init__(self, name, expr=None):
- self.name = name
- if expr is None:
- expr = Signal()
- self.expr = wrap(expr)
- class Input(_IO):
- pass
- class Output(_IO):
- pass
- class InOut(_IO):
- pass
- class Parameter:
- def __init__(self, name, value):
- self.name = name
- if isinstance(value, (int, bool)):
- value = Constant(value)
- self.value = value
- class PreformattedParam(str):
- pass
-
- def __init__(self, of, *items, name="", synthesis_directive=None, **kwargs):
- Special.__init__(self)
- self.of = of
- if name:
- self.name_override = name
- else:
- self.name_override = of
- self.items = list(items)
- self.synthesis_directive = synthesis_directive
- for k, v in sorted(kwargs.items(), key=itemgetter(0)):
- item_type, item_name = k.split("_", maxsplit=1)
- item_class = {
- "i": Instance.Input,
- "o": Instance.Output,
- "io": Instance.InOut,
- "p": Instance.Parameter
- }[item_type]
- self.items.append(item_class(item_name, v))
-
- def get_io(self, name):
- for item in self.items:
- if isinstance(item, Instance._IO) and item.name == name:
- return item.expr
-
- def iter_expressions(self):
- for item in self.items:
- if isinstance(item, Instance.Input):
- yield item, "expr", SPECIAL_INPUT
- elif isinstance(item, Instance.Output):
- yield item, "expr", SPECIAL_OUTPUT
- elif isinstance(item, Instance.InOut):
- yield item, "expr", SPECIAL_INOUT
-
- @staticmethod
- def emit_verilog(instance, ns, add_data_file):
- r = instance.of + " "
- parameters = list(filter(lambda i: isinstance(i, Instance.Parameter), instance.items))
- if parameters:
- r += "#(\n"
- firstp = True
- for p in parameters:
- if not firstp:
- r += ",\n"
- firstp = False
- r += "\t." + p.name + "("
- if isinstance(p.value, Constant):
- r += verilog_printexpr(ns, p.value)[0]
- elif isinstance(p.value, float):
- r += str(p.value)
- elif isinstance(p.value, Instance.PreformattedParam):
- r += p.value
- elif isinstance(p.value, str):
- r += "\"" + p.value + "\""
- else:
- raise TypeError
- r += ")"
- r += "\n) "
- r += ns.get_name(instance)
- if parameters: r += " "
- r += "(\n"
- firstp = True
- for p in instance.items:
- if isinstance(p, Instance._IO):
- name_inst = p.name
- name_design = verilog_printexpr(ns, p.expr)[0]
- if not firstp:
- r += ",\n"
- firstp = False
- r += "\t." + name_inst + "(" + name_design + ")"
- if not firstp:
- r += "\n"
- if instance.synthesis_directive is not None:
- synthesis_directive = "/* synthesis {} */".format(instance.synthesis_directive)
- r += ")" + synthesis_directive + ";\n\n"
- else:
- r += ");\n\n"
- return r
-
-
-(READ_FIRST, WRITE_FIRST, NO_CHANGE) = range(3)
-
-
-class _MemoryPort(Special):
- def __init__(self, adr, dat_r, we=None, dat_w=None,
- async_read=False, re=None, we_granularity=0, mode=WRITE_FIRST,
- clock_domain="sys"):
- Special.__init__(self)
- self.adr = adr
- self.dat_r = dat_r
- self.we = we
- self.dat_w = dat_w
- self.async_read = async_read
- self.re = re
- self.we_granularity = we_granularity
- self.mode = mode
- self.clock = ClockSignal(clock_domain)
-
- def iter_expressions(self):
- for attr, target_context in [
- ("adr", SPECIAL_INPUT),
- ("we", SPECIAL_INPUT),
- ("dat_w", SPECIAL_INPUT),
- ("re", SPECIAL_INPUT),
- ("dat_r", SPECIAL_OUTPUT),
- ("clock", SPECIAL_INPUT)]:
- yield self, attr, target_context
-
- @staticmethod
- def emit_verilog(port, ns, add_data_file):
- return "" # done by parent Memory object
-
-
-class _MemoryLocation(_Value):
- def __init__(self, memory, index):
- _Value.__init__(self)
- self.memory = memory
- self.index = wrap(index)
-
-
-class Memory(Special):
- def __init__(self, width, depth, init=None, name=None):
- Special.__init__(self)
- self.width = width
- self.depth = depth
- self.ports = []
- self.init = init
- self.name_override = get_obj_var_name(name, "mem")
-
- def __getitem__(self, index):
- # simulation only
- return _MemoryLocation(self, index)
-
- def get_port(self, write_capable=False, async_read=False,
- has_re=False, we_granularity=0, mode=WRITE_FIRST,
- clock_domain="sys"):
- if we_granularity >= self.width:
- we_granularity = 0
- adr = Signal(max=self.depth)
- dat_r = Signal(self.width)
- if write_capable:
- if we_granularity:
- we = Signal(self.width//we_granularity)
- else:
- we = Signal()
- dat_w = Signal(self.width)
- else:
- we = None
- dat_w = None
- if has_re:
- re = Signal()
- else:
- re = None
- mp = _MemoryPort(adr, dat_r, we, dat_w,
- async_read, re, we_granularity, mode,
- clock_domain)
- self.ports.append(mp)
- return mp
-
- @staticmethod
- def emit_verilog(memory, ns, add_data_file):
- r = ""
- def gn(e):
- if isinstance(e, Memory):
- return ns.get_name(e)
- else:
- return verilog_printexpr(ns, e)[0]
- adrbits = bits_for(memory.depth-1)
-
- r += "reg [" + str(memory.width-1) + ":0] " \
- + gn(memory) \
- + "[0:" + str(memory.depth-1) + "];\n"
-
- adr_regs = {}
- data_regs = {}
- for port in memory.ports:
- if not port.async_read:
- if port.mode == WRITE_FIRST and port.we is not None:
- adr_reg = Signal(name_override="memadr")
- r += "reg [" + str(adrbits-1) + ":0] " \
- + gn(adr_reg) + ";\n"
- adr_regs[id(port)] = adr_reg
- else:
- data_reg = Signal(name_override="memdat")
- r += "reg [" + str(memory.width-1) + ":0] " \
- + gn(data_reg) + ";\n"
- data_regs[id(port)] = data_reg
-
- for port in memory.ports:
- r += "always @(posedge " + gn(port.clock) + ") begin\n"
- if port.we is not None:
- if port.we_granularity:
- n = memory.width//port.we_granularity
- for i in range(n):
- m = i*port.we_granularity
- M = (i+1)*port.we_granularity-1
- sl = "[" + str(M) + ":" + str(m) + "]"
- r += "\tif (" + gn(port.we) + "[" + str(i) + "])\n"
- r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "]" + sl + " <= " + gn(port.dat_w) + sl + ";\n"
- else:
- r += "\tif (" + gn(port.we) + ")\n"
- r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "] <= " + gn(port.dat_w) + ";\n"
- if not port.async_read:
- if port.mode == WRITE_FIRST and port.we is not None:
- rd = "\t" + gn(adr_regs[id(port)]) + " <= " + gn(port.adr) + ";\n"
- else:
- bassign = gn(data_regs[id(port)]) + " <= " + gn(memory) + "[" + gn(port.adr) + "];\n"
- if port.mode == READ_FIRST or port.we is None:
- rd = "\t" + bassign
- elif port.mode == NO_CHANGE:
- rd = "\tif (!" + gn(port.we) + ")\n" \
- + "\t\t" + bassign
- if port.re is None:
- r += rd
- else:
- r += "\tif (" + gn(port.re) + ")\n"
- r += "\t" + rd.replace("\n\t", "\n\t\t")
- r += "end\n\n"
-
- for port in memory.ports:
- if port.async_read:
- r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(port.adr) + "];\n"
- else:
- if port.mode == WRITE_FIRST and port.we is not None:
- r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(adr_regs[id(port)]) + "];\n"
- else:
- r += "assign " + gn(port.dat_r) + " = " + gn(data_regs[id(port)]) + ";\n"
- r += "\n"
-
- if memory.init is not None:
- content = ""
- for d in memory.init:
- content += "{:x}\n".format(d)
- memory_filename = add_data_file(gn(memory) + ".init", content)
-
- r += "initial begin\n"
- r += "\t$readmemh(\"" + memory_filename + "\", " + gn(memory) + ");\n"
- r += "end\n\n"
-
- return r
-
-
-class SynthesisDirective(Special):
- def __init__(self, template, **signals):
- Special.__init__(self)
- self.template = template
- self.signals = signals
-
- @staticmethod
- def emit_verilog(directive, ns, add_data_file):
- name_dict = dict((k, ns.get_name(sig)) for k, sig in directive.signals.items())
- formatted = directive.template.format(**name_dict)
- return "// synthesis " + formatted + "\n"
-
-
-class Keep(SynthesisDirective):
- def __init__(self, signal):
- SynthesisDirective.__init__(self, "attribute keep of {s} is true", s=signal)
+++ /dev/null
-import builtins as _builtins
-import collections as _collections
-
-from migen.fhdl import tracer as _tracer
-from migen.util.misc import flat_iteration as _flat_iteration
-
-
-class DUID:
- """Deterministic Unique IDentifier"""
- __next_uid = 0
- def __init__(self):
- self.duid = DUID.__next_uid
- DUID.__next_uid += 1
-
-
-class _Value(DUID):
- """Base class for operands
-
- Instances of `_Value` or its subclasses can be operands to
- arithmetic, comparison, bitwise, and logic operators.
- They can be assigned (:meth:`eq`) or indexed/sliced (using the usual
- Python indexing and slicing notation).
-
- Values created from integers have the minimum bit width to necessary to
- represent the integer.
- """
- def __bool__(self):
- # Special case: Constants and Signals are part of a set or used as
- # dictionary keys, and Python needs to check for equality.
- if isinstance(self, _Operator) and self.op == "==":
- a, b = self.operands
- if isinstance(a, Constant) and isinstance(b, Constant):
- return a.value == b.value
- if isinstance(a, Signal) and isinstance(b, Signal):
- return a is b
- if (isinstance(a, Constant) and isinstance(b, Signal)
- or isinstance(a, Signal) and isinstance(a, Constant)):
- return False
- raise TypeError("Attempted to convert Migen value to boolean")
-
- def __invert__(self):
- return _Operator("~", [self])
- def __neg__(self):
- return _Operator("-", [self])
-
- def __add__(self, other):
- return _Operator("+", [self, other])
- def __radd__(self, other):
- return _Operator("+", [other, self])
- def __sub__(self, other):
- return _Operator("-", [self, other])
- def __rsub__(self, other):
- return _Operator("-", [other, self])
- def __mul__(self, other):
- return _Operator("*", [self, other])
- def __rmul__(self, other):
- return _Operator("*", [other, self])
- def __lshift__(self, other):
- return _Operator("<<<", [self, other])
- def __rlshift__(self, other):
- return _Operator("<<<", [other, self])
- def __rshift__(self, other):
- return _Operator(">>>", [self, other])
- def __rrshift__(self, other):
- return _Operator(">>>", [other, self])
- def __and__(self, other):
- return _Operator("&", [self, other])
- def __rand__(self, other):
- return _Operator("&", [other, self])
- def __xor__(self, other):
- return _Operator("^", [self, other])
- def __rxor__(self, other):
- return _Operator("^", [other, self])
- def __or__(self, other):
- return _Operator("|", [self, other])
- def __ror__(self, other):
- return _Operator("|", [other, self])
-
- def __lt__(self, other):
- return _Operator("<", [self, other])
- def __le__(self, other):
- return _Operator("<=", [self, other])
- def __eq__(self, other):
- return _Operator("==", [self, other])
- def __ne__(self, other):
- return _Operator("!=", [self, other])
- def __gt__(self, other):
- return _Operator(">", [self, other])
- def __ge__(self, other):
- return _Operator(">=", [self, other])
-
- def __len__(self):
- from migen.fhdl.bitcontainer import value_bits_sign
- return value_bits_sign(self)[0]
-
- def __getitem__(self, key):
- n = len(self)
- if isinstance(key, int):
- if key >= n:
- raise IndexError
- if key < 0:
- key += n
- return _Slice(self, key, key+1)
- elif isinstance(key, slice):
- start, stop, step = key.indices(n)
- if step != 1:
- return Cat(self[i] for i in range(start, stop, step))
- return _Slice(self, start, stop)
- else:
- raise TypeError
-
- def eq(self, r):
- """Assignment
-
- Parameters
- ----------
- r : _Value, in
- Value to be assigned.
-
- Returns
- -------
- _Assign
- Assignment statement that can be used in combinatorial or
- synchronous context.
- """
- return _Assign(self, r)
-
- def __hash__(self):
- raise TypeError("unhashable type: '{}'".format(type(self).__name__))
-
-
-def wrap(value):
- """Ensures that the passed object is a Migen value. Booleans and integers
- are automatically wrapped into ``Constant``."""
- if isinstance(value, (bool, int)):
- value = Constant(value)
- if not isinstance(value, _Value):
- raise TypeError("Object is not a Migen value")
- return value
-
-
-class _Operator(_Value):
- def __init__(self, op, operands):
- _Value.__init__(self)
- self.op = op
- self.operands = [wrap(o) for o in operands]
-
-
-def Mux(sel, val1, val0):
- """Multiplex between two values
-
- Parameters
- ----------
- sel : _Value(1), in
- Selector.
- val1 : _Value(N), in
- val0 : _Value(N), in
- Input values.
-
- Returns
- -------
- _Value(N), out
- Output `_Value`. If `sel` is asserted, the Mux returns
- `val1`, else `val0`.
- """
- return _Operator("m", [sel, val1, val0])
-
-
-class _Slice(_Value):
- def __init__(self, value, start, stop):
- _Value.__init__(self)
- if not isinstance(start, int) or not isinstance(stop, int):
- raise TypeError("Slice boundaries must be integers")
- self.value = wrap(value)
- self.start = start
- self.stop = stop
-
-
-class Cat(_Value):
- """Concatenate values
-
- Form a compound `_Value` from several smaller ones by concatenation.
- The first argument occupies the lower bits of the result.
- The return value can be used on either side of an assignment, that
- is, the concatenated value can be used as an argument on the RHS or
- as a target on the LHS. If it is used on the LHS, it must solely
- consist of `Signal` s, slices of `Signal` s, and other concatenations
- meeting these properties. The bit length of the return value is the sum of
- the bit lengths of the arguments::
-
- len(Cat(args)) == sum(len(arg) for arg in args)
-
- Parameters
- ----------
- *args : _Values or iterables of _Values, inout
- `_Value` s to be concatenated.
-
- Returns
- -------
- Cat, inout
- Resulting `_Value` obtained by concatentation.
- """
- def __init__(self, *args):
- _Value.__init__(self)
- self.l = [wrap(v) for v in _flat_iteration(args)]
-
-
-class Replicate(_Value):
- """Replicate a value
-
- An input value is replicated (repeated) several times
- to be used on the RHS of assignments::
-
- len(Replicate(s, n)) == len(s)*n
-
- Parameters
- ----------
- v : _Value, in
- Input value to be replicated.
- n : int
- Number of replications.
-
- Returns
- -------
- Replicate, out
- Replicated value.
- """
- def __init__(self, v, n):
- _Value.__init__(self)
- if not isinstance(n, int) or n < 0:
- raise TypeError("Replication count must be a positive integer")
- self.v = wrap(v)
- self.n = n
-
-
-class Constant(_Value):
- """A constant, HDL-literal integer `_Value`
-
- Parameters
- ----------
- value : int
- bits_sign : int or tuple or None
- Either an integer `bits` or a tuple `(bits, signed)`
- specifying the number of bits in this `Constant` and whether it is
- signed (can represent negative values). `bits_sign` defaults
- to the minimum width and signedness of `value`.
- """
- def __init__(self, value, bits_sign=None):
- from migen.fhdl.bitcontainer import bits_for
-
- _Value.__init__(self)
-
- self.value = int(value)
- if bits_sign is None:
- bits_sign = bits_for(self.value), self.value < 0
- elif isinstance(bits_sign, int):
- bits_sign = bits_sign, self.value < 0
- self.nbits, self.signed = bits_sign
- if not isinstance(self.nbits, int) or self.nbits <= 0:
- raise TypeError("Width must be a strictly positive integer")
-
- def __hash__(self):
- return self.value
-
-
-C = Constant # shorthand
-
-
-class Signal(_Value):
- """A `_Value` that can change
-
- The `Signal` object represents a value that is expected to change
- in the circuit. It does exactly what Verilog's `wire` and
- `reg` and VHDL's `signal` do.
-
- A `Signal` can be indexed to access a subset of its bits. Negative
- indices (`signal[-1]`) and the extended Python slicing notation
- (`signal[start:stop:step]`) are supported.
- The indices 0 and -1 are the least and most significant bits
- respectively.
-
- Parameters
- ----------
- bits_sign : int or tuple
- Either an integer `bits` or a tuple `(bits, signed)`
- specifying the number of bits in this `Signal` and whether it is
- signed (can represent negative values). `signed` defaults to
- `False`.
- name : str or None
- Name hint for this signal. If `None` (default) the name is
- inferred from the variable name this `Signal` is assigned to.
- Name collisions are automatically resolved by prepending
- names of objects that contain this `Signal` and by
- appending integer sequences.
- variable : bool
- Deprecated.
- reset : int
- Reset (synchronous) or default (combinatorial) value.
- When this `Signal` is assigned to in synchronous context and the
- corresponding clock domain is reset, the `Signal` assumes the
- given value. When this `Signal` is unassigned in combinatorial
- context (due to conditional assignments not being taken),
- the `Signal` assumes its `reset` value. Defaults to 0.
- name_override : str or None
- Do not use the inferred name but the given one.
- min : int or None
- max : int or None
- If `bits_sign` is `None`, the signal bit width and signedness are
- determined by the integer range given by `min` (inclusive,
- defaults to 0) and `max` (exclusive, defaults to 2).
- related : Signal or None
- """
- def __init__(self, bits_sign=None, name=None, variable=False, reset=0, name_override=None, min=None, max=None, related=None):
- from migen.fhdl.bitcontainer import bits_for
-
- _Value.__init__(self)
-
- # determine number of bits and signedness
- if bits_sign is None:
- if min is None:
- min = 0
- if max is None:
- max = 2
- max -= 1 # make both bounds inclusive
- assert(min < max)
- self.signed = min < 0 or max < 0
- self.nbits = _builtins.max(bits_for(min, self.signed), bits_for(max, self.signed))
- else:
- assert(min is None and max is None)
- if isinstance(bits_sign, tuple):
- self.nbits, self.signed = bits_sign
- else:
- self.nbits, self.signed = bits_sign, False
- if not isinstance(self.nbits, int) or self.nbits <= 0:
- raise ValueError("Signal width must be a strictly positive integer")
-
- self.variable = variable # deprecated
- self.reset = reset
- self.name_override = name_override
- self.backtrace = _tracer.trace_back(name)
- self.related = related
-
- def __setattr__(self, k, v):
- if k == "reset":
- v = wrap(v)
- _Value.__setattr__(self, k, v)
-
- def __repr__(self):
- return "<Signal " + (self.backtrace[-1][0] or "anonymous") + " at " + hex(id(self)) + ">"
-
- @classmethod
- def like(cls, other, **kwargs):
- """Create Signal based on another.
-
- Parameters
- ----------
- other : _Value
- Object to base this Signal on.
-
- See `migen.fhdl.bitcontainer.value_bits_sign` for details.
- """
- from migen.fhdl.bitcontainer import value_bits_sign
- return cls(bits_sign=value_bits_sign(other), **kwargs)
-
- def __hash__(self):
- return self.duid
-
-
-class ClockSignal(_Value):
- """Clock signal for a given clock domain
-
- `ClockSignal` s for a given clock domain can be retrieved multiple
- times. They all ultimately refer to the same signal.
-
- Parameters
- ----------
- cd : str
- Clock domain to obtain a clock signal for. Defaults to `"sys"`.
- """
- def __init__(self, cd="sys"):
- _Value.__init__(self)
- if not isinstance(cd, str):
- raise TypeError("Argument of ClockSignal must be a string")
- self.cd = cd
-
-
-class ResetSignal(_Value):
- """Reset signal for a given clock domain
-
- `ResetSignal` s for a given clock domain can be retrieved multiple
- times. They all ultimately refer to the same signal.
-
- Parameters
- ----------
- cd : str
- Clock domain to obtain a reset signal for. Defaults to `"sys"`.
- allow_reset_less : bool
- If the clock domain is resetless, return 0 instead of reporting an
- error.
- """
- def __init__(self, cd="sys", allow_reset_less=False):
- _Value.__init__(self)
- if not isinstance(cd, str):
- raise TypeError("Argument of ResetSignal must be a string")
- self.cd = cd
- self.allow_reset_less = allow_reset_less
-
-
-# statements
-
-
-class _Statement:
- pass
-
-
-class _Assign(_Statement):
- def __init__(self, l, r):
- self.l = wrap(l)
- self.r = wrap(r)
-
-
-def _check_statement(s):
- if isinstance(s, _collections.Iterable):
- return all(_check_statement(ss) for ss in s)
- else:
- return isinstance(s, _Statement)
-
-
-class If(_Statement):
- """Conditional execution of statements
-
- Parameters
- ----------
- cond : _Value(1), in
- Condition
- *t : Statements
- Statements to execute if `cond` is asserted.
-
- Examples
- --------
- >>> a = Signal()
- >>> b = Signal()
- >>> c = Signal()
- >>> d = Signal()
- >>> If(a,
- ... b.eq(1)
- ... ).Elif(c,
- ... b.eq(0)
- ... ).Else(
- ... b.eq(d)
- ... )
- """
- def __init__(self, cond, *t):
- if not _check_statement(t):
- raise TypeError("Not all test body objects are Migen statements")
- self.cond = wrap(cond)
- self.t = list(t)
- self.f = []
-
- def Else(self, *f):
- """Add an `else` conditional block
-
- Parameters
- ----------
- *f : Statements
- Statements to execute if all previous conditions fail.
- """
- if not _check_statement(f):
- raise TypeError("Not all test body objects are Migen statements")
- _insert_else(self, list(f))
- return self
-
- def Elif(self, cond, *t):
- """Add an `else if` conditional block
-
- Parameters
- ----------
- cond : _Value(1), in
- Condition
- *t : Statements
- Statements to execute if previous conditions fail and `cond`
- is asserted.
- """
- _insert_else(self, [If(cond, *t)])
- return self
-
-
-def _insert_else(obj, clause):
- o = obj
- while o.f:
- assert(len(o.f) == 1)
- assert(isinstance(o.f[0], If))
- o = o.f[0]
- o.f = clause
-
-
-class Case(_Statement):
- """Case/Switch statement
-
- Parameters
- ----------
- test : _Value, in
- Selector value used to decide which block to execute
- cases : dict
- Dictionary of cases. The keys are numeric constants to compare
- with `test`. The values are statements to be executed the
- corresponding key matches `test`. The dictionary may contain a
- string key `"default"` to mark a fall-through case that is
- executed if no other key matches.
-
- Examples
- --------
- >>> a = Signal()
- >>> b = Signal()
- >>> Case(a, {
- ... 0: b.eq(1),
- ... 1: b.eq(0),
- ... "default": b.eq(0),
- ... })
- """
- def __init__(self, test, cases):
- self.test = wrap(test)
- self.cases = dict()
- for k, v in cases.items():
- if isinstance(k, (bool, int)):
- k = Constant(k)
- if (not isinstance(k, Constant)
- and not (isinstance(k, str) and k == "default")):
- raise TypeError("Case object is not a Migen constant")
- if not isinstance(v, _collections.Iterable):
- v = [v]
- if not _check_statement(v):
- raise TypeError("Not all objects for case {} "
- "are Migen statements".format(k))
- self.cases[k] = v
-
- def makedefault(self, key=None):
- """Mark a key as the default case
-
- Deletes/substitutes any previously existing default case.
-
- Parameters
- ----------
- key : int or None
- Key to use as default case if no other key matches.
- By default, the largest key is the default key.
- """
- if key is None:
- for choice in self.cases.keys():
- if key is None or choice.value > key.value:
- key = choice
- self.cases["default"] = self.cases[key]
- del self.cases[key]
- return self
-
-
-# arrays
-
-
-class _ArrayProxy(_Value):
- def __init__(self, choices, key):
- _Value.__init__(self)
- self.choices = []
- for c in choices:
- if isinstance(c, (bool, int)):
- c = Constant(c)
- self.choices.append(c)
- self.key = key
-
- def __getattr__(self, attr):
- return _ArrayProxy([getattr(choice, attr) for choice in self.choices],
- self.key)
-
- def __getitem__(self, key):
- return _ArrayProxy([choice.__getitem__(key) for choice in self.choices],
- self.key)
-
-
-class Array(list):
- """Addressable multiplexer
-
- An array is created from an iterable of values and indexed using the
- usual Python simple indexing notation (no negative indices or
- slices). It can be indexed by numeric constants, `_Value` s, or
- `Signal` s.
-
- The result of indexing the array is a proxy for the entry at the
- given index that can be used on either RHS or LHS of assignments.
-
- An array can be indexed multiple times.
-
- Multidimensional arrays are supported by packing inner arrays into
- outer arrays.
-
- Parameters
- ----------
- values : iterable of ints, _Values, Signals
- Entries of the array. Each entry can be a numeric constant, a
- `Signal` or a `Record`.
-
- Examples
- --------
- >>> a = Array(range(10))
- >>> b = Signal(max=10)
- >>> c = Signal(max=10)
- >>> b.eq(a[9 - c])
- """
- def __getitem__(self, key):
- if isinstance(key, Constant):
- return list.__getitem__(self, key.value)
- elif isinstance(key, _Value):
- return _ArrayProxy(self, key)
- else:
- return list.__getitem__(self, key)
-
-
-class ClockDomain:
- """Synchronous domain
-
- Parameters
- ----------
- name : str or None
- Domain name. If None (the default) the name is inferred from the
- variable name this `ClockDomain` is assigned to (stripping any
- `"cd_"` prefix).
- reset_less : bool
- The domain does not use a reset signal. Registers within this
- domain are still all initialized to their reset state once, e.g.
- through Verilog `"initial"` statements.
-
- Attributes
- ----------
- clk : Signal, inout
- The clock for this domain. Can be driven or used to drive other
- signals (preferably in combinatorial context).
- rst : Signal or None, inout
- Reset signal for this domain. Can be driven or used to drive.
- """
- def __init__(self, name=None, reset_less=False):
- self.name = _tracer.get_obj_var_name(name)
- if self.name is None:
- raise ValueError("Cannot extract clock domain name from code, need to specify.")
- if self.name.startswith("cd_"):
- self.name = self.name[3:]
- if self.name[0].isdigit():
- raise ValueError("Clock domain name cannot start with a number.")
- self.clk = Signal(name_override=self.name + "_clk")
- if reset_less:
- self.rst = None
- else:
- self.rst = Signal(name_override=self.name + "_rst")
-
- def rename(self, new_name):
- """Rename the clock domain
-
- Parameters
- ----------
- new_name : str
- New name
- """
- self.name = new_name
- self.clk.name_override = new_name + "_clk"
- if self.rst is not None:
- self.rst.name_override = new_name + "_rst"
-
-
-class _ClockDomainList(list):
- def __getitem__(self, key):
- if isinstance(key, str):
- for cd in self:
- if cd.name == key:
- return cd
- raise KeyError(key)
- else:
- return list.__getitem__(self, key)
-
-
-(SPECIAL_INPUT, SPECIAL_OUTPUT, SPECIAL_INOUT) = range(3)
-
-
-class _Fragment:
- def __init__(self, comb=None, sync=None, specials=None, clock_domains=None):
- if comb is None: comb = []
- if sync is None: sync = dict()
- if specials is None: specials = set()
- if clock_domains is None: clock_domains = _ClockDomainList()
-
- self.comb = comb
- self.sync = sync
- self.specials = specials
- self.clock_domains = _ClockDomainList(clock_domains)
-
- def __add__(self, other):
- newsync = _collections.defaultdict(list)
- for k, v in self.sync.items():
- newsync[k] = v[:]
- for k, v in other.sync.items():
- newsync[k].extend(v)
- return _Fragment(self.comb + other.comb, newsync,
- self.specials | other.specials,
- self.clock_domains + other.clock_domains)
-
- def __iadd__(self, other):
- newsync = _collections.defaultdict(list)
- for k, v in self.sync.items():
- newsync[k] = v[:]
- for k, v in other.sync.items():
- newsync[k].extend(v)
- self.comb += other.comb
- self.sync = newsync
- self.specials |= other.specials
- self.clock_domains += other.clock_domains
- return self
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.structure import _Slice, _Assign
-from migen.fhdl.visit import NodeVisitor, NodeTransformer
-from migen.fhdl.bitcontainer import value_bits_sign
-from migen.util.misc import flat_iteration
-
-
-class _SignalLister(NodeVisitor):
- def __init__(self):
- self.output_list = set()
-
- def visit_Signal(self, node):
- self.output_list.add(node)
-
-
-class _TargetLister(NodeVisitor):
- def __init__(self):
- self.output_list = set()
- self.target_context = False
-
- def visit_Signal(self, node):
- if self.target_context:
- self.output_list.add(node)
-
- def visit_Assign(self, node):
- self.target_context = True
- self.visit(node.l)
- self.target_context = False
-
- def visit_ArrayProxy(self, node):
- for choice in node.choices:
- self.visit(choice)
-
-
-class _InputLister(NodeVisitor):
- def __init__(self):
- self.output_list = set()
-
- def visit_Signal(self, node):
- self.output_list.add(node)
-
- def visit_Assign(self, node):
- self.visit(node.r)
-
-
-def list_signals(node):
- lister = _SignalLister()
- lister.visit(node)
- return lister.output_list
-
-
-def list_targets(node):
- lister = _TargetLister()
- lister.visit(node)
- return lister.output_list
-
-
-def list_inputs(node):
- lister = _InputLister()
- lister.visit(node)
- return lister.output_list
-
-
-def _resort_statements(ol):
- return [statement for i, statement in
- sorted(ol, key=lambda x: x[0])]
-
-
-def group_by_targets(sl):
- groups = []
- seen = set()
- for order, stmt in enumerate(flat_iteration(sl)):
- targets = set(list_targets(stmt))
- group = [(order, stmt)]
- disjoint = targets.isdisjoint(seen)
- seen |= targets
- if not disjoint:
- groups, old_groups = [], groups
- for old_targets, old_group in old_groups:
- if targets.isdisjoint(old_targets):
- groups.append((old_targets, old_group))
- else:
- targets |= old_targets
- group += old_group
- groups.append((targets, group))
- return [(targets, _resort_statements(stmts))
- for targets, stmts in groups]
-
-
-def list_special_ios(f, ins, outs, inouts):
- r = set()
- for special in f.specials:
- r |= special.list_ios(ins, outs, inouts)
- return r
-
-
-class _ClockDomainLister(NodeVisitor):
- def __init__(self):
- self.clock_domains = set()
-
- def visit_ClockSignal(self, node):
- self.clock_domains.add(node.cd)
-
- def visit_ResetSignal(self, node):
- self.clock_domains.add(node.cd)
-
- def visit_clock_domains(self, node):
- for clockname, statements in node.items():
- self.clock_domains.add(clockname)
- self.visit(statements)
-
-
-def list_clock_domains_expr(f):
- cdl = _ClockDomainLister()
- cdl.visit(f)
- return cdl.clock_domains
-
-
-def list_clock_domains(f):
- r = list_clock_domains_expr(f)
- for special in f.specials:
- r |= special.list_clock_domains()
- for cd in f.clock_domains:
- r.add(cd.name)
- return r
-
-
-def is_variable(node):
- if isinstance(node, Signal):
- return node.variable
- elif isinstance(node, _Slice):
- return is_variable(node.value)
- elif isinstance(node, Cat):
- arevars = list(map(is_variable, node.l))
- r = arevars[0]
- for x in arevars:
- if x != r:
- raise TypeError
- return r
- else:
- raise TypeError
-
-
-def generate_reset(rst, sl):
- targets = list_targets(sl)
- return [t.eq(t.reset) for t in sorted(targets, key=lambda x: x.duid)]
-
-
-def insert_reset(rst, sl):
- return [If(rst, *generate_reset(rst, sl)).Else(*sl)]
-
-
-def insert_resets(f):
- newsync = dict()
- for k, v in f.sync.items():
- if f.clock_domains[k].rst is not None:
- newsync[k] = insert_reset(ResetSignal(k), v)
- else:
- newsync[k] = v
- f.sync = newsync
-
-
-class _Lowerer(NodeTransformer):
- def __init__(self):
- self.target_context = False
- self.extra_stmts = []
- self.comb = []
-
- def visit_Assign(self, node):
- old_target_context, old_extra_stmts = self.target_context, self.extra_stmts
- self.extra_stmts = []
-
- self.target_context = True
- lhs = self.visit(node.l)
- self.target_context = False
- rhs = self.visit(node.r)
- r = _Assign(lhs, rhs)
- if self.extra_stmts:
- r = [r] + self.extra_stmts
-
- self.target_context, self.extra_stmts = old_target_context, old_extra_stmts
- return r
-
-
-# Basics are FHDL structure elements that back-ends are not required to support
-# but can be expressed in terms of other elements (lowered) before conversion.
-class _BasicLowerer(_Lowerer):
- def __init__(self, clock_domains):
- self.clock_domains = clock_domains
- _Lowerer.__init__(self)
-
- def visit_ArrayProxy(self, node):
- # TODO: rewrite without variables
- array_muxed = Signal(value_bits_sign(node), variable=True)
- if self.target_context:
- k = self.visit(node.key)
- cases = {}
- for n, choice in enumerate(node.choices):
- cases[n] = [self.visit_Assign(_Assign(choice, array_muxed))]
- self.extra_stmts.append(Case(k, cases).makedefault())
- else:
- cases = dict((n, _Assign(array_muxed, self.visit(choice)))
- for n, choice in enumerate(node.choices))
- self.comb.append(Case(self.visit(node.key), cases).makedefault())
- return array_muxed
-
- def visit_ClockSignal(self, node):
- return self.clock_domains[node.cd].clk
-
- def visit_ResetSignal(self, node):
- rst = self.clock_domains[node.cd].rst
- if rst is None:
- if node.allow_reset_less:
- return 0
- else:
- raise ValueError("Attempted to get reset signal of resetless"
- " domain '{}'".format(node.cd))
- else:
- return rst
-
-
-class _ComplexSliceLowerer(_Lowerer):
- def visit_Slice(self, node):
- if not isinstance(node.value, Signal):
- slice_proxy = Signal(value_bits_sign(node.value))
- if self.target_context:
- a = _Assign(node.value, slice_proxy)
- else:
- a = _Assign(slice_proxy, node.value)
- self.comb.append(self.visit_Assign(a))
- node = _Slice(slice_proxy, node.start, node.stop)
- return NodeTransformer.visit_Slice(self, node)
-
-
-def _apply_lowerer(l, f):
- f = l.visit(f)
- f.comb += l.comb
-
- for special in f.specials:
- for obj, attr, direction in special.iter_expressions():
- if direction != SPECIAL_INOUT:
- # inouts are only supported by Migen when connected directly to top-level
- # in this case, they are Signal and never need lowering
- l.comb = []
- l.target_context = direction != SPECIAL_INPUT
- l.extra_stmts = []
- expr = getattr(obj, attr)
- expr = l.visit(expr)
- setattr(obj, attr, expr)
- f.comb += l.comb + l.extra_stmts
-
- return f
-
-
-def lower_basics(f):
- return _apply_lowerer(_BasicLowerer(f.clock_domains), f)
-
-
-def lower_complex_slices(f):
- return _apply_lowerer(_ComplexSliceLowerer(), f)
-
-
-class _ClockDomainRenamer(NodeVisitor):
- def __init__(self, old, new):
- self.old = old
- self.new = new
-
- def visit_ClockSignal(self, node):
- if node.cd == self.old:
- node.cd = self.new
-
- def visit_ResetSignal(self, node):
- if node.cd == self.old:
- node.cd = self.new
-
-
-def rename_clock_domain_expr(f, old, new):
- cdr = _ClockDomainRenamer(old, new)
- cdr.visit(f)
-
-
-def rename_clock_domain(f, old, new):
- rename_clock_domain_expr(f, old, new)
- if new != old:
- if old in f.sync:
- if new in f.sync:
- f.sync[new].extend(f.sync[old])
- else:
- f.sync[new] = f.sync[old]
- del f.sync[old]
- for special in f.specials:
- special.rename_clock_domain(old, new)
- try:
- cd = f.clock_domains[old]
- except KeyError:
- pass
- else:
- cd.rename(new)
+++ /dev/null
-import inspect
-from opcode import opname
-from collections import defaultdict
-
-
-def get_var_name(frame):
- code = frame.f_code
- call_index = frame.f_lasti
- call_opc = opname[code.co_code[call_index]]
- if call_opc != "CALL_FUNCTION" and call_opc != "CALL_FUNCTION_VAR":
- return None
- index = call_index+3
- while True:
- opc = opname[code.co_code[index]]
- if opc == "STORE_NAME" or opc == "STORE_ATTR":
- name_index = int(code.co_code[index+1])
- return code.co_names[name_index]
- elif opc == "STORE_FAST":
- name_index = int(code.co_code[index+1])
- return code.co_varnames[name_index]
- elif opc == "STORE_DEREF":
- name_index = int(code.co_code[index+1])
- return code.co_cellvars[name_index]
- elif opc == "LOAD_GLOBAL" or opc == "LOAD_ATTR" or opc == "LOAD_FAST" or opc == "LOAD_DEREF":
- index += 3
- elif opc == "DUP_TOP":
- index += 1
- elif opc == "BUILD_LIST":
- index += 3
- else:
- return None
-
-
-def remove_underscore(s):
- if len(s) > 2 and s[0] == "_" and s[1] != "_":
- s = s[1:]
- return s
-
-
-def get_obj_var_name(override=None, default=None):
- if override:
- return override
-
- frame = inspect.currentframe().f_back
- # We can be called via derived classes. Go back the stack frames
- # until we reach the first class that does not inherit from us.
- ourclass = frame.f_locals["self"].__class__
- while "self" in frame.f_locals and isinstance(frame.f_locals["self"], ourclass):
- frame = frame.f_back
-
- vn = get_var_name(frame)
- if vn is None:
- vn = default
- else:
- vn = remove_underscore(vn)
- return vn
-
-name_to_idx = defaultdict(int)
-classname_to_objs = dict()
-
-
-def index_id(l, obj):
- for n, e in enumerate(l):
- if id(e) == id(obj):
- return n
- raise ValueError
-
-
-def trace_back(varname=None):
- l = []
- frame = inspect.currentframe().f_back.f_back
- while frame is not None:
- if varname is None:
- varname = get_var_name(frame)
- if varname is not None:
- varname = remove_underscore(varname)
- l.insert(0, (varname, name_to_idx[varname]))
- name_to_idx[varname] += 1
-
- try:
- obj = frame.f_locals["self"]
- except KeyError:
- obj = None
- if hasattr(obj, "__del__"):
- obj = None
-
- if obj is None:
- if varname is not None:
- coname = frame.f_code.co_name
- if coname == "<module>":
- modules = frame.f_globals["__name__"]
- modules = modules.split(".")
- coname = modules[len(modules)-1]
- coname = remove_underscore(coname)
- l.insert(0, (coname, name_to_idx[coname]))
- name_to_idx[coname] += 1
- else:
- classname = obj.__class__.__name__.lower()
- try:
- objs = classname_to_objs[classname]
- except KeyError:
- classname_to_objs[classname] = [obj]
- idx = 0
- else:
- try:
- idx = index_id(objs, obj)
- except ValueError:
- idx = len(objs)
- objs.append(obj)
- classname = remove_underscore(classname)
- l.insert(0, (classname, idx))
-
- varname = None
- frame = frame.f_back
- return l
+++ /dev/null
-from functools import partial
-from operator import itemgetter
-import collections
-
-from migen.fhdl.structure import *
-from migen.fhdl.structure import _Operator, _Slice, _Assign, _Fragment
-from migen.fhdl.tools import *
-from migen.fhdl.bitcontainer import bits_for
-from migen.fhdl.namer import build_namespace
-from migen.fhdl.conv_output import ConvOutput
-
-
-_reserved_keywords = {
- "always", "and", "assign", "automatic", "begin", "buf", "bufif0", "bufif1",
- "case", "casex", "casez", "cell", "cmos", "config", "deassign", "default",
- "defparam", "design", "disable", "edge", "else", "end", "endcase",
- "endconfig", "endfunction", "endgenerate", "endmodule", "endprimitive",
- "endspecify", "endtable", "endtask", "event", "for", "force", "forever",
- "fork", "function", "generate", "genvar", "highz0", "highz1", "if",
- "ifnone", "incdir", "include", "initial", "inout", "input",
- "instance", "integer", "join", "large", "liblist", "library", "localparam",
- "macromodule", "medium", "module", "nand", "negedge", "nmos", "nor",
- "noshowcancelled", "not", "notif0", "notif1", "or", "output", "parameter",
- "pmos", "posedge", "primitive", "pull0", "pull1" "pulldown",
- "pullup", "pulsestyle_onevent", "pulsestyle_ondetect", "remos", "real",
- "realtime", "reg", "release", "repeat", "rnmos", "rpmos", "rtran",
- "rtranif0", "rtranif1", "scalared", "showcancelled", "signed", "small",
- "specify", "specparam", "strong0", "strong1", "supply0", "supply1",
- "table", "task", "time", "tran", "tranif0", "tranif1", "tri", "tri0",
- "tri1", "triand", "trior", "trireg", "unsigned", "use", "vectored", "wait",
- "wand", "weak0", "weak1", "while", "wire", "wor","xnor", "xor"
-}
-
-
-def _printsig(ns, s):
- if s.signed:
- n = "signed "
- else:
- n = ""
- if len(s) > 1:
- n += "[" + str(len(s)-1) + ":0] "
- n += ns.get_name(s)
- return n
-
-
-def _printconstant(node):
- if node.signed:
- return (str(node.nbits) + "'sd" + str(2**node.nbits + node.value),
- True)
- else:
- return str(node.nbits) + "'d" + str(node.value), False
-
-
-def _printexpr(ns, node):
- if isinstance(node, Constant):
- return _printconstant(node)
- elif isinstance(node, Signal):
- return ns.get_name(node), node.signed
- elif isinstance(node, _Operator):
- arity = len(node.operands)
- r1, s1 = _printexpr(ns, node.operands[0])
- if arity == 1:
- if node.op == "-":
- if s1:
- r = node.op + r1
- else:
- r = "-$signed({1'd0, " + r1 + "})"
- s = True
- else:
- r = node.op + r1
- s = s1
- elif arity == 2:
- r2, s2 = _printexpr(ns, node.operands[1])
- if node.op not in ["<<<", ">>>"]:
- if s2 and not s1:
- r1 = "$signed({1'd0, " + r1 + "})"
- if s1 and not s2:
- r2 = "$signed({1'd0, " + r2 + "})"
- r = r1 + " " + node.op + " " + r2
- s = s1 or s2
- elif arity == 3:
- assert node.op == "m"
- r2, s2 = _printexpr(ns, node.operands[1])
- r3, s3 = _printexpr(ns, node.operands[2])
- if s2 and not s3:
- r3 = "$signed({1'd0, " + r3 + "})"
- if s3 and not s2:
- r2 = "$signed({1'd0, " + r2 + "})"
- r = r1 + " ? " + r2 + " : " + r3
- s = s2 or s3
- else:
- raise TypeError
- return "(" + r + ")", s
- elif isinstance(node, _Slice):
- # Verilog does not like us slicing non-array signals...
- if isinstance(node.value, Signal) \
- and len(node.value) == 1 \
- and node.start == 0 and node.stop == 1:
- return _printexpr(ns, node.value)
-
- if node.start + 1 == node.stop:
- sr = "[" + str(node.start) + "]"
- else:
- sr = "[" + str(node.stop-1) + ":" + str(node.start) + "]"
- r, s = _printexpr(ns, node.value)
- return r + sr, s
- elif isinstance(node, Cat):
- l = [_printexpr(ns, v)[0] for v in reversed(node.l)]
- return "{" + ", ".join(l) + "}", False
- elif isinstance(node, Replicate):
- return "{" + str(node.n) + "{" + _printexpr(ns, node.v)[0] + "}}", False
- else:
- raise TypeError("Expression of unrecognized type: '{}'".format(type(node).__name__))
-
-
-(_AT_BLOCKING, _AT_NONBLOCKING, _AT_SIGNAL) = range(3)
-
-
-def _printnode(ns, at, level, node):
- if node is None:
- return ""
- elif isinstance(node, _Assign):
- if at == _AT_BLOCKING:
- assignment = " = "
- elif at == _AT_NONBLOCKING:
- assignment = " <= "
- elif is_variable(node.l):
- assignment = " = "
- else:
- assignment = " <= "
- return "\t"*level + _printexpr(ns, node.l)[0] + assignment + _printexpr(ns, node.r)[0] + ";\n"
- elif isinstance(node, collections.Iterable):
- return "".join(list(map(partial(_printnode, ns, at, level), node)))
- elif isinstance(node, If):
- r = "\t"*level + "if (" + _printexpr(ns, node.cond)[0] + ") begin\n"
- r += _printnode(ns, at, level + 1, node.t)
- if node.f:
- r += "\t"*level + "end else begin\n"
- r += _printnode(ns, at, level + 1, node.f)
- r += "\t"*level + "end\n"
- return r
- elif isinstance(node, Case):
- if node.cases:
- r = "\t"*level + "case (" + _printexpr(ns, node.test)[0] + ")\n"
- css = [(k, v) for k, v in node.cases.items() if isinstance(k, Constant)]
- css = sorted(css, key=lambda x: x[0].value)
- for choice, statements in css:
- r += "\t"*(level + 1) + _printexpr(ns, choice)[0] + ": begin\n"
- r += _printnode(ns, at, level + 2, statements)
- r += "\t"*(level + 1) + "end\n"
- if "default" in node.cases:
- r += "\t"*(level + 1) + "default: begin\n"
- r += _printnode(ns, at, level + 2, node.cases["default"])
- r += "\t"*(level + 1) + "end\n"
- r += "\t"*level + "endcase\n"
- return r
- else:
- return ""
- else:
- raise TypeError("Node of unrecognized type: "+str(type(node)))
-
-
-def _list_comb_wires(f):
- r = set()
- groups = group_by_targets(f.comb)
- for g in groups:
- if len(g[1]) == 1 and isinstance(g[1][0], _Assign):
- r |= g[0]
- return r
-
-
-def _printheader(f, ios, name, ns,
- reg_initialization):
- sigs = list_signals(f) | list_special_ios(f, True, True, True)
- special_outs = list_special_ios(f, False, True, True)
- inouts = list_special_ios(f, False, False, True)
- targets = list_targets(f) | special_outs
- wires = _list_comb_wires(f) | special_outs
- r = "module " + name + "(\n"
- firstp = True
- for sig in sorted(ios, key=lambda x: x.duid):
- if not firstp:
- r += ",\n"
- firstp = False
- if sig in inouts:
- r += "\tinout " + _printsig(ns, sig)
- elif sig in targets:
- if sig in wires:
- r += "\toutput " + _printsig(ns, sig)
- else:
- r += "\toutput reg " + _printsig(ns, sig)
- else:
- r += "\tinput " + _printsig(ns, sig)
- r += "\n);\n\n"
- for sig in sorted(sigs - ios, key=lambda x: x.duid):
- if sig in wires:
- r += "wire " + _printsig(ns, sig) + ";\n"
- else:
- if reg_initialization:
- r += "reg " + _printsig(ns, sig) + " = " + _printexpr(ns, sig.reset)[0] + ";\n"
- else:
- r += "reg " + _printsig(ns, sig) + ";\n"
- r += "\n"
- return r
-
-
-def _printcomb(f, ns,
- display_run,
- dummy_signal,
- blocking_assign):
- r = ""
- if f.comb:
- if dummy_signal:
- # Generate a dummy event to get the simulator
- # to run the combinatorial process once at the beginning.
- syn_off = "// synthesis translate_off\n"
- syn_on = "// synthesis translate_on\n"
- dummy_s = Signal(name_override="dummy_s")
- r += syn_off
- r += "reg " + _printsig(ns, dummy_s) + ";\n"
- r += "initial " + ns.get_name(dummy_s) + " <= 1'd0;\n"
- r += syn_on
-
- groups = group_by_targets(f.comb)
-
- for n, g in enumerate(groups):
- if len(g[1]) == 1 and isinstance(g[1][0], _Assign):
- r += "assign " + _printnode(ns, _AT_BLOCKING, 0, g[1][0])
- else:
- if dummy_signal:
- dummy_d = Signal(name_override="dummy_d")
- r += "\n" + syn_off
- r += "reg " + _printsig(ns, dummy_d) + ";\n"
- r += syn_on
-
- r += "always @(*) begin\n"
- if display_run:
- r += "\t$display(\"Running comb block #" + str(n) + "\");\n"
- if blocking_assign:
- for t in g[0]:
- r += "\t" + ns.get_name(t) + " = " + _printexpr(ns, t.reset)[0] + ";\n"
- r += _printnode(ns, _AT_BLOCKING, 1, g[1])
- else:
- for t in g[0]:
- r += "\t" + ns.get_name(t) + " <= " + _printexpr(ns, t.reset)[0] + ";\n"
- r += _printnode(ns, _AT_NONBLOCKING, 1, g[1])
- if dummy_signal:
- r += syn_off
- r += "\t" + ns.get_name(dummy_d) + " <= " + ns.get_name(dummy_s) + ";\n"
- r += syn_on
- r += "end\n"
- r += "\n"
- return r
-
-
-def _printsync(f, ns):
- r = ""
- for k, v in sorted(f.sync.items(), key=itemgetter(0)):
- r += "always @(posedge " + ns.get_name(f.clock_domains[k].clk) + ") begin\n"
- r += _printnode(ns, _AT_SIGNAL, 1, v)
- r += "end\n\n"
- return r
-
-
-def _call_special_classmethod(overrides, obj, method, *args, **kwargs):
- cl = obj.__class__
- if cl in overrides:
- cl = overrides[cl]
- if hasattr(cl, method):
- return getattr(cl, method)(obj, *args, **kwargs)
- else:
- return None
-
-
-def _lower_specials_step(overrides, specials):
- f = _Fragment()
- lowered_specials = set()
- for special in sorted(specials, key=lambda x: x.duid):
- impl = _call_special_classmethod(overrides, special, "lower")
- if impl is not None:
- f += impl.get_fragment()
- lowered_specials.add(special)
- return f, lowered_specials
-
-
-def _can_lower(overrides, specials):
- for special in specials:
- cl = special.__class__
- if cl in overrides:
- cl = overrides[cl]
- if hasattr(cl, "lower"):
- return True
- return False
-
-
-def _lower_specials(overrides, specials):
- f, lowered_specials = _lower_specials_step(overrides, specials)
- while _can_lower(overrides, f.specials):
- f2, lowered_specials2 = _lower_specials_step(overrides, f.specials)
- f += f2
- lowered_specials |= lowered_specials2
- f.specials -= lowered_specials2
- return f, lowered_specials
-
-
-def _printspecials(overrides, specials, ns, add_data_file):
- r = ""
- for special in sorted(specials, key=lambda x: x.duid):
- pr = _call_special_classmethod(overrides, special, "emit_verilog", ns, add_data_file)
- if pr is None:
- raise NotImplementedError("Special " + str(special) + " failed to implement emit_verilog")
- r += pr
- return r
-
-
-def convert(f, ios=None, name="top",
- special_overrides=dict(),
- create_clock_domains=True,
- display_run=False, asic_syntax=False):
- r = ConvOutput()
- if not isinstance(f, _Fragment):
- f = f.get_fragment()
- if ios is None:
- ios = set()
-
- for cd_name in sorted(list_clock_domains(f)):
- try:
- f.clock_domains[cd_name]
- except KeyError:
- if create_clock_domains:
- cd = ClockDomain(cd_name)
- f.clock_domains.append(cd)
- ios |= {cd.clk, cd.rst}
- else:
- raise KeyError("Unresolved clock domain: '"+cd_name+"'")
-
- f = lower_complex_slices(f)
- insert_resets(f)
- f = lower_basics(f)
- fs, lowered_specials = _lower_specials(special_overrides, f.specials)
- f += lower_basics(fs)
-
- ns = build_namespace(list_signals(f) \
- | list_special_ios(f, True, True, True) \
- | ios, _reserved_keywords)
- ns.clock_domains = f.clock_domains
- r.ns = ns
-
- src = "/* Machine-generated using Migen */\n"
- src += _printheader(f, ios, name, ns,
- reg_initialization=not asic_syntax)
- src += _printcomb(f, ns,
- display_run=display_run,
- dummy_signal=not asic_syntax,
- blocking_assign=asic_syntax)
- src += _printsync(f, ns)
- src += _printspecials(special_overrides, f.specials - lowered_specials, ns, r.add_data_file)
- src += "endmodule\n"
- r.set_main_source(src)
-
- return r
+++ /dev/null
-from copy import copy
-
-from migen.fhdl.structure import *
-from migen.fhdl.structure import (_Operator, _Slice, _Assign, _ArrayProxy,
- _Fragment)
-
-
-class NodeVisitor:
- def visit(self, node):
- if isinstance(node, Constant):
- self.visit_Constant(node)
- elif isinstance(node, Signal):
- self.visit_Signal(node)
- elif isinstance(node, ClockSignal):
- self.visit_ClockSignal(node)
- elif isinstance(node, ResetSignal):
- self.visit_ResetSignal(node)
- elif isinstance(node, _Operator):
- self.visit_Operator(node)
- elif isinstance(node, _Slice):
- self.visit_Slice(node)
- elif isinstance(node, Cat):
- self.visit_Cat(node)
- elif isinstance(node, Replicate):
- self.visit_Replicate(node)
- elif isinstance(node, _Assign):
- self.visit_Assign(node)
- elif isinstance(node, If):
- self.visit_If(node)
- elif isinstance(node, Case):
- self.visit_Case(node)
- elif isinstance(node, _Fragment):
- self.visit_Fragment(node)
- elif isinstance(node, (list, tuple)):
- self.visit_statements(node)
- elif isinstance(node, dict):
- self.visit_clock_domains(node)
- elif isinstance(node, _ArrayProxy):
- self.visit_ArrayProxy(node)
- elif node is not None:
- self.visit_unknown(node)
-
- def visit_Constant(self, node):
- pass
-
- def visit_Signal(self, node):
- pass
-
- def visit_ClockSignal(self, node):
- pass
-
- def visit_ResetSignal(self, node):
- pass
-
- def visit_Operator(self, node):
- for o in node.operands:
- self.visit(o)
-
- def visit_Slice(self, node):
- self.visit(node.value)
-
- def visit_Cat(self, node):
- for e in node.l:
- self.visit(e)
-
- def visit_Replicate(self, node):
- self.visit(node.v)
-
- def visit_Assign(self, node):
- self.visit(node.l)
- self.visit(node.r)
-
- def visit_If(self, node):
- self.visit(node.cond)
- self.visit(node.t)
- self.visit(node.f)
-
- def visit_Case(self, node):
- self.visit(node.test)
- for v, statements in node.cases.items():
- self.visit(statements)
-
- def visit_Fragment(self, node):
- self.visit(node.comb)
- self.visit(node.sync)
-
- def visit_statements(self, node):
- for statement in node:
- self.visit(statement)
-
- def visit_clock_domains(self, node):
- for clockname, statements in node.items():
- self.visit(statements)
-
- def visit_ArrayProxy(self, node):
- for choice in node.choices:
- self.visit(choice)
- self.visit(node.key)
-
- def visit_unknown(self, node):
- pass
-
-
-# Default methods always copy the node, except for:
-# - Signals, ClockSignals and ResetSignals
-# - Unknown objects
-# - All fragment fields except comb and sync
-# In those cases, the original node is returned unchanged.
-class NodeTransformer:
- def visit(self, node):
- if isinstance(node, Constant):
- return self.visit_Constant(node)
- elif isinstance(node, Signal):
- return self.visit_Signal(node)
- elif isinstance(node, ClockSignal):
- return self.visit_ClockSignal(node)
- elif isinstance(node, ResetSignal):
- return self.visit_ResetSignal(node)
- elif isinstance(node, _Operator):
- return self.visit_Operator(node)
- elif isinstance(node, _Slice):
- return self.visit_Slice(node)
- elif isinstance(node, Cat):
- return self.visit_Cat(node)
- elif isinstance(node, Replicate):
- return self.visit_Replicate(node)
- elif isinstance(node, _Assign):
- return self.visit_Assign(node)
- elif isinstance(node, If):
- return self.visit_If(node)
- elif isinstance(node, Case):
- return self.visit_Case(node)
- elif isinstance(node, _Fragment):
- return self.visit_Fragment(node)
- elif isinstance(node, (list, tuple)):
- return self.visit_statements(node)
- elif isinstance(node, dict):
- return self.visit_clock_domains(node)
- elif isinstance(node, _ArrayProxy):
- return self.visit_ArrayProxy(node)
- elif node is not None:
- return self.visit_unknown(node)
- else:
- return None
-
- def visit_Constant(self, node):
- return node
-
- def visit_Signal(self, node):
- return node
-
- def visit_ClockSignal(self, node):
- return node
-
- def visit_ResetSignal(self, node):
- return node
-
- def visit_Operator(self, node):
- return _Operator(node.op, [self.visit(o) for o in node.operands])
-
- def visit_Slice(self, node):
- return _Slice(self.visit(node.value), node.start, node.stop)
-
- def visit_Cat(self, node):
- return Cat(*[self.visit(e) for e in node.l])
-
- def visit_Replicate(self, node):
- return Replicate(self.visit(node.v), node.n)
-
- def visit_Assign(self, node):
- return _Assign(self.visit(node.l), self.visit(node.r))
-
- def visit_If(self, node):
- r = If(self.visit(node.cond))
- r.t = self.visit(node.t)
- r.f = self.visit(node.f)
- return r
-
- def visit_Case(self, node):
- cases = dict((v, self.visit(statements)) for v, statements in node.cases.items())
- r = Case(self.visit(node.test), cases)
- return r
-
- def visit_Fragment(self, node):
- r = copy(node)
- r.comb = self.visit(node.comb)
- r.sync = self.visit(node.sync)
- return r
-
- # NOTE: this will always return a list, even if node is a tuple
- def visit_statements(self, node):
- return [self.visit(statement) for statement in node]
-
- def visit_clock_domains(self, node):
- return dict((clockname, self.visit(statements)) for clockname, statements in node.items())
-
- def visit_ArrayProxy(self, node):
- return _ArrayProxy([self.visit(choice) for choice in node.choices],
- self.visit(node.key))
-
- def visit_unknown(self, node):
- return node
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-from migen.fhdl.specials import Special
-from migen.fhdl.bitcontainer import value_bits_sign
-from migen.genlib.misc import WaitTimer
-
-
-class NoRetiming(Special):
- def __init__(self, reg):
- Special.__init__(self)
- self.reg = reg
-
- # do nothing
- @staticmethod
- def lower(dr):
- return Module()
-
-
-class MultiRegImpl(Module):
- def __init__(self, i, o, odomain, n):
- self.i = i
- self.o = o
- self.odomain = odomain
-
- w, signed = value_bits_sign(self.i)
- self.regs = [Signal((w, signed)) for i in range(n)]
-
- ###
-
- src = self.i
- for reg in self.regs:
- sd = getattr(self.sync, self.odomain)
- sd += reg.eq(src)
- src = reg
- self.comb += self.o.eq(src)
- self.specials += [NoRetiming(reg) for reg in self.regs]
-
-
-class MultiReg(Special):
- def __init__(self, i, o, odomain="sys", n=2):
- Special.__init__(self)
- self.i = wrap(i)
- self.o = wrap(o)
- self.odomain = odomain
- self.n = n
-
- def iter_expressions(self):
- yield self, "i", SPECIAL_INPUT
- yield self, "o", SPECIAL_OUTPUT
-
- def rename_clock_domain(self, old, new):
- Special.rename_clock_domain(self, old, new)
- if self.odomain == old:
- self.odomain = new
-
- def list_clock_domains(self):
- r = Special.list_clock_domains(self)
- r.add(self.odomain)
- return r
-
- @staticmethod
- def lower(dr):
- return MultiRegImpl(dr.i, dr.o, dr.odomain, dr.n)
-
-
-class PulseSynchronizer(Module):
- def __init__(self, idomain, odomain):
- self.i = Signal()
- self.o = Signal()
-
- ###
-
- toggle_i = Signal()
- toggle_o = Signal()
- toggle_o_r = Signal()
-
- sync_i = getattr(self.sync, idomain)
- sync_o = getattr(self.sync, odomain)
-
- sync_i += If(self.i, toggle_i.eq(~toggle_i))
- self.specials += MultiReg(toggle_i, toggle_o, odomain)
- sync_o += toggle_o_r.eq(toggle_o)
- self.comb += self.o.eq(toggle_o ^ toggle_o_r)
-
-
-class BusSynchronizer(Module):
- """Clock domain transfer of several bits at once.
-
- Ensures that all the bits form a single word that was present
- synchronously in the input clock domain (unlike direct use of
- ``MultiReg``)."""
- def __init__(self, width, idomain, odomain, timeout=128):
- self.i = Signal(width)
- self.o = Signal(width)
-
- if width == 1:
- self.specials += MultiReg(self.i, self.o, odomain)
- else:
- sync_i = getattr(self.sync, idomain)
- sync_o = getattr(self.sync, odomain)
-
- starter = Signal(reset=1)
- sync_i += starter.eq(0)
- self.submodules._ping = PulseSynchronizer(idomain, odomain)
- self.submodules._pong = PulseSynchronizer(odomain, idomain)
- self.submodules._timeout = WaitTimer(timeout)
- self.comb += [
- self._timeout.wait.eq(~self._ping.i),
- self._ping.i.eq(starter | self._pong.o | self._timeout.done),
- self._pong.i.eq(self._ping.i)
- ]
-
- ibuffer = Signal(width)
- obuffer = Signal(width)
- sync_i += If(self._pong.o, ibuffer.eq(self.i))
- self.specials += MultiReg(ibuffer, obuffer, odomain)
- sync_o += If(self._ping.o, self.o.eq(obuffer))
-
-
-class GrayCounter(Module):
- def __init__(self, width):
- self.ce = Signal()
- self.q = Signal(width)
- self.q_next = Signal(width)
- self.q_binary = Signal(width)
- self.q_next_binary = Signal(width)
-
- ###
-
- self.comb += [
- If(self.ce,
- self.q_next_binary.eq(self.q_binary + 1)
- ).Else(
- self.q_next_binary.eq(self.q_binary)
- ),
- self.q_next.eq(self.q_next_binary ^ self.q_next_binary[1:])
- ]
- self.sync += [
- self.q_binary.eq(self.q_next_binary),
- self.q.eq(self.q_next)
- ]
+++ /dev/null
-"""
-Encoders and decoders between binary and one-hot representation
-"""
-
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-
-
-class Encoder(Module):
- """Encode one-hot to binary
-
- If `n` is low, the `o` th bit in `i` is asserted, else none or
- multiple bits are asserted.
-
- Parameters
- ----------
- width : int
- Bit width of the input
-
- Attributes
- ----------
- i : Signal(width), in
- One-hot input
- o : Signal(max=width), out
- Encoded binary
- n : Signal(1), out
- Invalid, either none or multiple input bits are asserted
- """
- def __init__(self, width):
- self.i = Signal(width) # one-hot
- self.o = Signal(max=max(2, width)) # binary
- self.n = Signal() # invalid: none or multiple
- act = dict((1<<j, self.o.eq(j)) for j in range(width))
- act["default"] = self.n.eq(1)
- self.comb += Case(self.i, act)
-
-
-class PriorityEncoder(Module):
- """Priority encode requests to binary
-
- If `n` is low, the `o` th bit in `i` is asserted and the bits below
- `o` are unasserted, else `o == 0`. The LSB has priority.
-
- Parameters
- ----------
- width : int
- Bit width of the input
-
- Attributes
- ----------
- i : Signal(width), in
- Input requests
- o : Signal(max=width), out
- Encoded binary
- n : Signal(1), out
- Invalid, no input bits are asserted
- """
- def __init__(self, width):
- self.i = Signal(width) # one-hot, lsb has priority
- self.o = Signal(max=max(2, width)) # binary
- self.n = Signal() # none
- for j in range(width)[::-1]: # last has priority
- self.comb += If(self.i[j], self.o.eq(j))
- self.comb += self.n.eq(self.i == 0)
-
-
-class Decoder(Module):
- """Decode binary to one-hot
-
- If `n` is low, the `i` th bit in `o` is asserted, the others are
- not, else `o == 0`.
-
- Parameters
- ----------
- width : int
- Bit width of the output
-
- Attributes
- ----------
- i : Signal(max=width), in
- Input binary
- o : Signal(width), out
- Decoded one-hot
- n : Signal(1), in
- Invalid, no output bits are to be asserted
- """
-
- def __init__(self, width):
- self.i = Signal(max=max(2, width)) # binary
- self.n = Signal() # none/invalid
- self.o = Signal(width) # one-hot
- act = dict((j, self.o.eq(1<<j)) for j in range(width))
- self.comb += Case(self.i, act)
- self.comb += If(self.n, self.o.eq(0))
-
-
-class PriorityDecoder(Decoder):
- pass # same
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-
-
-class Divider(Module):
- def __init__(self, w):
- self.start_i = Signal()
- self.dividend_i = Signal(w)
- self.divisor_i = Signal(w)
- self.ready_o = Signal()
- self.quotient_o = Signal(w)
- self.remainder_o = Signal(w)
-
- ###
-
- qr = Signal(2*w)
- counter = Signal(max=w+1)
- divisor_r = Signal(w)
- diff = Signal(w+1)
-
- self.comb += [
- self.quotient_o.eq(qr[:w]),
- self.remainder_o.eq(qr[w:]),
- self.ready_o.eq(counter == 0),
- diff.eq(qr[w-1:] - divisor_r)
- ]
- self.sync += [
- If(self.start_i,
- counter.eq(w),
- qr.eq(self.dividend_i),
- divisor_r.eq(self.divisor_i)
- ).Elif(~self.ready_o,
- If(diff[w],
- qr.eq(Cat(0, qr[:2*w-1]))
- ).Else(
- qr.eq(Cat(1, qr[:w-1], diff[:w]))
- ),
- counter.eq(counter - 1)
- )
- ]
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-from migen.fhdl.specials import Memory
-from migen.fhdl.bitcontainer import log2_int
-from migen.fhdl.decorators import ClockDomainsRenamer
-from migen.genlib.cdc import NoRetiming, MultiReg, GrayCounter
-
-
-def _inc(signal, modulo):
- if modulo == 2**len(signal):
- return signal.eq(signal + 1)
- else:
- return If(signal == (modulo - 1),
- signal.eq(0)
- ).Else(
- signal.eq(signal + 1)
- )
-
-
-class _FIFOInterface:
- """
- Data written to the input interface (`din`, `we`, `writable`) is
- buffered and can be read at the output interface (`dout`, `re`,
- `readable`). The data entry written first to the input
- also appears first on the output.
-
- Parameters
- ----------
- width : int
- Bit width for the data.
- depth : int
- Depth of the FIFO.
-
- Attributes
- ----------
- din : in, width
- Input data
- writable : out
- There is space in the FIFO and `we` can be asserted to load new data.
- we : in
- Write enable signal to latch `din` into the FIFO. Does nothing if
- `writable` is not asserted.
- dout : out, width
- Output data. Only valid if `readable` is asserted.
- readable : out
- Output data `dout` valid, FIFO not empty.
- re : in
- Acknowledge `dout`. If asserted, the next entry will be
- available on the next cycle (if `readable` is high then).
- """
- def __init__(self, width, depth):
- self.we = Signal()
- self.writable = Signal() # not full
- self.re = Signal()
- self.readable = Signal() # not empty
-
- self.din = Signal(width)
- self.dout = Signal(width)
- self.width = width
-
-
-class SyncFIFO(Module, _FIFOInterface):
- """Synchronous FIFO (first in, first out)
-
- Read and write interfaces are accessed from the same clock domain.
- If different clock domains are needed, use :class:`AsyncFIFO`.
-
- {interface}
- level : out
- Number of unread entries.
- replace : in
- Replaces the last entry written into the FIFO with `din`. Does nothing
- if that entry has already been read (i.e. the FIFO is empty).
- Assert in conjunction with `we`.
- """
- __doc__ = __doc__.format(interface=_FIFOInterface.__doc__)
-
- def __init__(self, width, depth, fwft=True):
- _FIFOInterface.__init__(self, width, depth)
-
- self.level = Signal(max=depth+1)
- self.replace = Signal()
-
- ###
-
- produce = Signal(max=depth)
- consume = Signal(max=depth)
- storage = Memory(self.width, depth)
- self.specials += storage
-
- wrport = storage.get_port(write_capable=True)
- self.specials += wrport
- self.comb += [
- If(self.replace,
- wrport.adr.eq(produce-1)
- ).Else(
- wrport.adr.eq(produce)
- ),
- wrport.dat_w.eq(self.din),
- wrport.we.eq(self.we & (self.writable | self.replace))
- ]
- self.sync += If(self.we & self.writable & ~self.replace,
- _inc(produce, depth))
-
- do_read = Signal()
- self.comb += do_read.eq(self.readable & self.re)
-
- rdport = storage.get_port(async_read=fwft, has_re=not fwft)
- self.specials += rdport
- self.comb += [
- rdport.adr.eq(consume),
- self.dout.eq(rdport.dat_r)
- ]
- if not fwft:
- self.comb += rdport.re.eq(do_read)
- self.sync += If(do_read, _inc(consume, depth))
-
- self.sync += \
- If(self.we & self.writable & ~self.replace,
- If(~do_read, self.level.eq(self.level + 1))
- ).Elif(do_read,
- self.level.eq(self.level - 1)
- )
- self.comb += [
- self.writable.eq(self.level != depth),
- self.readable.eq(self.level != 0)
- ]
-
-
-class SyncFIFOBuffered(Module, _FIFOInterface):
- def __init__(self, width, depth):
- _FIFOInterface.__init__(self, width, depth)
- self.submodules.fifo = fifo = SyncFIFO(width, depth, False)
-
- self.writable = fifo.writable
- self.din = fifo.din
- self.we = fifo.we
- self.dout = fifo.dout
- self.level = Signal(max=depth+2)
-
- ###
-
- self.comb += fifo.re.eq(fifo.readable & (~self.readable | self.re))
- self.sync += \
- If(fifo.re,
- self.readable.eq(1),
- ).Elif(self.re,
- self.readable.eq(0),
- )
- self.comb += self.level.eq(fifo.level + self.readable)
-
-
-class AsyncFIFO(Module, _FIFOInterface):
- """Asynchronous FIFO (first in, first out)
-
- Read and write interfaces are accessed from different clock domains,
- named `read` and `write`. Use `ClockDomainsRenamer` to rename to
- other names.
-
- {interface}
- """
- __doc__ = __doc__.format(interface=_FIFOInterface.__doc__)
-
- def __init__(self, width, depth):
- _FIFOInterface.__init__(self, width, depth)
-
- ###
-
- depth_bits = log2_int(depth, True)
-
- produce = ClockDomainsRenamer("write")(GrayCounter(depth_bits+1))
- consume = ClockDomainsRenamer("read")(GrayCounter(depth_bits+1))
- self.submodules += produce, consume
- self.comb += [
- produce.ce.eq(self.writable & self.we),
- consume.ce.eq(self.readable & self.re)
- ]
-
- produce_rdomain = Signal(depth_bits+1)
- self.specials += [
- NoRetiming(produce.q),
- MultiReg(produce.q, produce_rdomain, "read")
- ]
- consume_wdomain = Signal(depth_bits+1)
- self.specials += [
- NoRetiming(consume.q),
- MultiReg(consume.q, consume_wdomain, "write")
- ]
- if depth_bits == 1:
- self.comb += self.writable.eq((produce.q[-1] == consume_wdomain[-1])
- | (produce.q[-2] == consume_wdomain[-2]))
- else:
- self.comb += [
- self.writable.eq((produce.q[-1] == consume_wdomain[-1])
- | (produce.q[-2] == consume_wdomain[-2])
- | (produce.q[:-2] != consume_wdomain[:-2]))
- ]
- self.comb += self.readable.eq(consume.q != produce_rdomain)
-
- storage = Memory(self.width, depth)
- self.specials += storage
- wrport = storage.get_port(write_capable=True, clock_domain="write")
- self.specials += wrport
- self.comb += [
- wrport.adr.eq(produce.q_binary[:-1]),
- wrport.dat_w.eq(self.din),
- wrport.we.eq(produce.ce)
- ]
- rdport = storage.get_port(clock_domain="read")
- self.specials += rdport
- self.comb += [
- rdport.adr.eq(consume.q_next_binary[:-1]),
- self.dout.eq(rdport.dat_r)
- ]
+++ /dev/null
-from collections import OrderedDict
-
-from migen.fhdl.structure import *
-from migen.fhdl.structure import _Statement, _Slice, _ArrayProxy
-from migen.fhdl.module import Module, FinalizeError
-from migen.fhdl.visit import NodeTransformer
-from migen.fhdl.bitcontainer import value_bits_sign
-
-
-__all__ = ["AnonymousState", "NextState", "NextValue", "FSM"]
-
-
-class AnonymousState:
- pass
-
-
-# do not use namedtuple here as it inherits tuple
-# and the latter is used elsewhere in FHDL
-class NextState(_Statement):
- def __init__(self, state):
- self.state = state
-
-
-class NextValue(_Statement):
- def __init__(self, target, value):
- self.target = target
- self.value = value
-
-
-def _target_eq(a, b):
- if type(a) != type(b):
- return False
- ty = type(a)
- if ty == Constant:
- return a.value == b.value
- elif ty == Signal:
- return a is b
- elif ty == Cat:
- return all(_target_eq(x, y) for x, y in zip(a.l, b.l))
- elif ty == _Slice:
- return (_target_eq(a.value, b.value)
- and a.start == b.start
- and a.end == b.end)
- elif ty == _ArrayProxy:
- return (all(_target_eq(x, y) for x, y in zip(a.choices, b.choices))
- and _target_eq(a.key, b.key))
- else:
- raise ValueError("NextValue cannot be used with target type '{}'"
- .format(ty))
-
-
-class _LowerNext(NodeTransformer):
- def __init__(self, next_state_signal, encoding, aliases):
- self.next_state_signal = next_state_signal
- self.encoding = encoding
- self.aliases = aliases
- # (target, next_value_ce, next_value)
- self.registers = []
-
- def _get_register_control(self, target):
- for x in self.registers:
- if _target_eq(target, x[0]):
- return x[1], x[2]
- raise KeyError
-
- def visit_unknown(self, node):
- if isinstance(node, NextState):
- try:
- actual_state = self.aliases[node.state]
- except KeyError:
- actual_state = node.state
- return self.next_state_signal.eq(self.encoding[actual_state])
- elif isinstance(node, NextValue):
- try:
- next_value_ce, next_value = self._get_register_control(node.target)
- except KeyError:
- related = node.target if isinstance(node.target, Signal) else None
- next_value = Signal(bits_sign=value_bits_sign(node.target), related=related)
- next_value_ce = Signal(related=related)
- self.registers.append((node.target, next_value_ce, next_value))
- return next_value.eq(node.value), next_value_ce.eq(1)
- else:
- return node
-
-
-class FSM(Module):
- def __init__(self, reset_state=None):
- self.actions = OrderedDict()
- self.state_aliases = dict()
- self.reset_state = reset_state
-
- self.before_entering_signals = OrderedDict()
- self.before_leaving_signals = OrderedDict()
- self.after_entering_signals = OrderedDict()
- self.after_leaving_signals = OrderedDict()
-
- def act(self, state, *statements):
- if self.finalized:
- raise FinalizeError
- if self.reset_state is None:
- self.reset_state = state
- if state not in self.actions:
- self.actions[state] = []
- self.actions[state] += statements
-
- def delayed_enter(self, name, target, delay):
- if self.finalized:
- raise FinalizeError
- if delay > 0:
- state = name
- for i in range(delay):
- if i == delay - 1:
- next_state = target
- else:
- next_state = AnonymousState()
- self.act(state, NextState(next_state))
- state = next_state
- else:
- self.state_aliases[name] = target
-
- def ongoing(self, state):
- is_ongoing = Signal()
- self.act(state, is_ongoing.eq(1))
- return is_ongoing
-
- def _get_signal(self, d, state):
- if state not in self.actions:
- self.actions[state] = []
- try:
- return d[state]
- except KeyError:
- is_el = Signal()
- d[state] = is_el
- return is_el
-
- def before_entering(self, state):
- return self._get_signal(self.before_entering_signals, state)
-
- def before_leaving(self, state):
- return self._get_signal(self.before_leaving_signals, state)
-
- def after_entering(self, state):
- signal = self._get_signal(self.after_entering_signals, state)
- self.sync += signal.eq(self.before_entering(state))
- return signal
-
- def after_leaving(self, state):
- signal = self._get_signal(self.after_leaving_signals, state)
- self.sync += signal.eq(self.before_leaving(state))
- return signal
-
- def do_finalize(self):
- nstates = len(self.actions)
- self.encoding = dict((s, n) for n, s in enumerate(self.actions.keys()))
- self.state = Signal(max=nstates, reset=self.encoding[self.reset_state])
- self.next_state = Signal(max=nstates)
-
- ln = _LowerNext(self.next_state, self.encoding, self.state_aliases)
- cases = dict((self.encoding[k], ln.visit(v)) for k, v in self.actions.items() if v)
- self.comb += [
- self.next_state.eq(self.state),
- Case(self.state, cases).makedefault(self.encoding[self.reset_state])
- ]
- self.sync += self.state.eq(self.next_state)
- for register, next_value_ce, next_value in ln.registers:
- self.sync += If(next_value_ce, register.eq(next_value))
-
- # drive entering/leaving signals
- for state, signal in self.before_leaving_signals.items():
- encoded = self.encoding[state]
- self.comb += signal.eq((self.state == encoded) & ~(self.next_state == encoded))
- if self.reset_state in self.after_entering_signals:
- self.after_entering_signals[self.reset_state].reset = 1
- for state, signal in self.before_entering_signals.items():
- encoded = self.encoding[state]
- self.comb += signal.eq(~(self.state == encoded) & (self.next_state == encoded))
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-from migen.fhdl.specials import Special
-
-
-class DifferentialInput(Special):
- def __init__(self, i_p, i_n, o):
- Special.__init__(self)
- self.i_p = wrap(i_p)
- self.i_n = wrap(i_n)
- self.o = wrap(o)
-
- def iter_expressions(self):
- yield self, "i_p", SPECIAL_INPUT
- yield self, "i_n", SPECIAL_INPUT
- yield self, "o", SPECIAL_OUTPUT
-
- @staticmethod
- def lower(dr):
- raise NotImplementedError("Attempted to use a differential input, but platform does not support them")
-
-
-class DifferentialOutput(Special):
- def __init__(self, i, o_p, o_n):
- Special.__init__(self)
- self.i = wrap(i)
- self.o_p = wrap(o_p)
- self.o_n = wrap(o_n)
-
- def iter_expressions(self):
- yield self, "i", SPECIAL_INPUT
- yield self, "o_p", SPECIAL_OUTPUT
- yield self, "o_n", SPECIAL_OUTPUT
-
- @staticmethod
- def lower(dr):
- raise NotImplementedError("Attempted to use a differential output, but platform does not support them")
-
-
-class CRG(Module):
- def __init__(self, clk, rst=0):
- self.clock_domains.cd_sys = ClockDomain()
- self.clock_domains.cd_por = ClockDomain(reset_less=True)
-
- if hasattr(clk, "p"):
- clk_se = Signal()
- self.specials += DifferentialInput(clk.p, clk.n, clk_se)
- clk = clk_se
-
- # Power on Reset (vendor agnostic)
- int_rst = Signal(reset=1)
- self.sync.por += int_rst.eq(rst)
- self.comb += [
- self.cd_sys.clk.eq(clk),
- self.cd_por.clk.eq(clk),
- self.cd_sys.rst.eq(int_rst)
- ]
-
-
-class DDRInput(Special):
- def __init__(self, i, o1, o2, clk=ClockSignal()):
- Special.__init__(self)
- self.i = wrap(i)
- self.o1 = wrap(o1)
- self.o2 = wrap(o2)
- self.clk = wrap(clk)
-
- def iter_expressions(self):
- yield self, "i", SPECIAL_INPUT
- yield self, "o1", SPECIAL_OUTPUT
- yield self, "o2", SPECIAL_OUTPUT
- yield self, "clk", SPECIAL_INPUT
-
- @staticmethod
- def lower(dr):
- raise NotImplementedError("Attempted to use a DDR input, but platform does not support them")
-
-
-class DDROutput(Special):
- def __init__(self, i1, i2, o, clk=ClockSignal()):
- Special.__init__(self)
- self.i1 = i1
- self.i2 = i2
- self.o = o
- self.clk = clk
-
- def iter_expressions(self):
- yield self, "i1", SPECIAL_INPUT
- yield self, "i2", SPECIAL_INPUT
- yield self, "o", SPECIAL_OUTPUT
- yield self, "clk", SPECIAL_INPUT
-
- @staticmethod
- def lower(dr):
- raise NotImplementedError("Attempted to use a DDR output, but platform does not support them")
-
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-from migen.fhdl.bitcontainer import bits_for
-
-
-def split(v, *counts):
- r = []
- offset = 0
- for n in counts:
- if n != 0:
- r.append(v[offset:offset+n])
- else:
- r.append(None)
- offset += n
- return tuple(r)
-
-
-def displacer(signal, shift, output, n=None, reverse=False):
- if shift is None:
- return output.eq(signal)
- if n is None:
- n = 2**len(shift)
- w = len(signal)
- if reverse:
- r = reversed(range(n))
- else:
- r = range(n)
- l = [Replicate(shift == i, w) & signal for i in r]
- return output.eq(Cat(*l))
-
-
-def chooser(signal, shift, output, n=None, reverse=False):
- if shift is None:
- return output.eq(signal)
- if n is None:
- n = 2**len(shift)
- w = len(output)
- cases = {}
- for i in range(n):
- if reverse:
- s = n - i - 1
- else:
- s = i
- cases[i] = [output.eq(signal[s*w:(s+1)*w])]
- return Case(shift, cases).makedefault()
-
-
-def timeline(trigger, events):
- lastevent = max([e[0] for e in events])
- counter = Signal(max=lastevent+1)
-
- counterlogic = If(counter != 0,
- counter.eq(counter + 1)
- ).Elif(trigger,
- counter.eq(1)
- )
- # insert counter reset if it doesn't naturally overflow
- # (test if lastevent+1 is a power of 2)
- if (lastevent & (lastevent + 1)) != 0:
- counterlogic = If(counter == lastevent,
- counter.eq(0)
- ).Else(
- counterlogic
- )
-
- def get_cond(e):
- if e[0] == 0:
- return trigger & (counter == 0)
- else:
- return counter == e[0]
- sync = [If(get_cond(e), *e[1]) for e in events]
- sync.append(counterlogic)
- return sync
-
-
-class WaitTimer(Module):
- def __init__(self, t):
- self.wait = Signal()
- self.done = Signal()
-
- # # #
-
- count = Signal(bits_for(t), reset=t)
- self.comb += self.done.eq(count == 0)
- self.sync += \
- If(self.wait,
- If(~self.done, count.eq(count - 1))
- ).Else(count.eq(count.reset))
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.tracer import get_obj_var_name
-
-from functools import reduce
-from operator import or_
-
-
-(DIR_NONE, DIR_S_TO_M, DIR_M_TO_S) = range(3)
-
-# Possible layout elements:
-# 1. (name, size)
-# 2. (name, size, direction)
-# 3. (name, sublayout)
-# size can be an int, or a (int, bool) tuple for signed numbers
-# sublayout must be a list
-
-
-def set_layout_parameters(layout, **layout_dict):
- def resolve(p):
- if isinstance(p, str):
- try:
- return layout_dict[p]
- except KeyError:
- return p
- else:
- return p
-
- r = []
- for f in layout:
- if isinstance(f[1], (int, tuple, str)): # cases 1/2
- if len(f) == 3:
- r.append((f[0], resolve(f[1]), f[2]))
- else:
- r.append((f[0], resolve(f[1])))
- elif isinstance(f[1], list): # case 3
- r.append((f[0], set_layout_parameters(f[1], **layout_dict)))
- else:
- raise TypeError
- return r
-
-
-def layout_len(layout):
- r = 0
- for f in layout:
- if isinstance(f[1], (int, tuple)): # cases 1/2
- if len(f) == 3:
- fname, fsize, fdirection = f
- else:
- fname, fsize = f
- elif isinstance(f[1], list): # case 3
- fname, fsublayout = f
- fsize = layout_len(fsublayout)
- else:
- raise TypeError
- if isinstance(fsize, tuple):
- r += fsize[0]
- else:
- r += fsize
- return r
-
-
-def layout_get(layout, name):
- for f in layout:
- if f[0] == name:
- return f
- raise KeyError(name)
-
-
-def layout_partial(layout, *elements):
- r = []
- for path in elements:
- path_s = path.split("/")
- last = path_s.pop()
- copy_ref = layout
- insert_ref = r
- for hop in path_s:
- name, copy_ref = layout_get(copy_ref, hop)
- try:
- name, insert_ref = layout_get(insert_ref, hop)
- except KeyError:
- new_insert_ref = []
- insert_ref.append((hop, new_insert_ref))
- insert_ref = new_insert_ref
- insert_ref.append(layout_get(copy_ref, last))
- return r
-
-
-class Record:
- def __init__(self, layout, name=None):
- self.name = get_obj_var_name(name, "")
- self.layout = layout
-
- if self.name:
- prefix = self.name + "_"
- else:
- prefix = ""
- for f in self.layout:
- if isinstance(f[1], (int, tuple)): # cases 1/2
- if(len(f) == 3):
- fname, fsize, fdirection = f
- else:
- fname, fsize = f
- finst = Signal(fsize, name=prefix + fname)
- elif isinstance(f[1], list): # case 3
- fname, fsublayout = f
- finst = Record(fsublayout, prefix + fname)
- else:
- raise TypeError
- setattr(self, fname, finst)
-
- def eq(self, other):
- return [getattr(self, f[0]).eq(getattr(other, f[0]))
- for f in self.layout if hasattr(other, f[0])]
-
- def iter_flat(self):
- for f in self.layout:
- e = getattr(self, f[0])
- if isinstance(e, Signal):
- if len(f) == 3:
- yield e, f[2]
- else:
- yield e, DIR_NONE
- elif isinstance(e, Record):
- yield from e.iter_flat()
- else:
- raise TypeError
-
- def flatten(self):
- return [signal for signal, direction in self.iter_flat()]
-
- def raw_bits(self):
- return Cat(*self.flatten())
-
- def connect(self, *slaves, leave_out=set()):
- if isinstance(leave_out, str):
- leave_out = {leave_out}
- r = []
- for f in self.layout:
- field = f[0]
- if field not in leave_out:
- self_e = getattr(self, field)
- if isinstance(self_e, Signal):
- direction = f[2]
- if direction == DIR_M_TO_S:
- r += [getattr(slave, field).eq(self_e) for slave in slaves]
- elif direction == DIR_S_TO_M:
- r.append(self_e.eq(reduce(or_, [getattr(slave, field) for slave in slaves])))
- else:
- raise TypeError
- else:
- for slave in slaves:
- r += self_e.connect(getattr(slave, field), leave_out=leave_out)
- return r
-
- def connect_flat(self, *slaves):
- r = []
- iter_slaves = [slave.iter_flat() for slave in slaves]
- for m_signal, m_direction in self.iter_flat():
- if m_direction == DIR_M_TO_S:
- for iter_slave in iter_slaves:
- s_signal, s_direction = next(iter_slave)
- assert(s_direction == DIR_M_TO_S)
- r.append(s_signal.eq(m_signal))
- elif m_direction == DIR_S_TO_M:
- s_signals = []
- for iter_slave in iter_slaves:
- s_signal, s_direction = next(iter_slave)
- assert(s_direction == DIR_S_TO_M)
- s_signals.append(s_signal)
- r.append(m_signal.eq(reduce(or_, s_signals)))
- else:
- raise TypeError
- return r
-
- def __len__(self):
- return layout_len(self.layout)
-
- def __repr__(self):
- return "<Record " + ":".join(f[0] for f in self.layout) + " at " + hex(id(self)) + ">"
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.specials import Special
-
-
-class AsyncResetSynchronizer(Special):
- def __init__(self, cd, async_reset):
- Special.__init__(self)
- self.cd = cd
- self.async_reset = wrap(async_reset)
-
- def iter_expressions(self):
- yield self.cd, "clk", SPECIAL_INPUT
- yield self.cd, "rst", SPECIAL_OUTPUT
- yield self, "async_reset", SPECIAL_INPUT
-
- @staticmethod
- def lower(dr):
- raise NotImplementedError("Attempted to use a reset synchronizer, but platform does not support them")
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-
-
-(SP_WITHDRAW, SP_CE) = range(2)
-
-
-class RoundRobin(Module):
- def __init__(self, n, switch_policy=SP_WITHDRAW):
- self.request = Signal(n)
- self.grant = Signal(max=max(2, n))
- self.switch_policy = switch_policy
- if self.switch_policy == SP_CE:
- self.ce = Signal()
-
- ###
-
- if n > 1:
- cases = {}
- for i in range(n):
- switch = []
- for j in reversed(range(i+1, i+n)):
- t = j % n
- switch = [
- If(self.request[t],
- self.grant.eq(t)
- ).Else(
- *switch
- )
- ]
- if self.switch_policy == SP_WITHDRAW:
- case = [If(~self.request[i], *switch)]
- else:
- case = switch
- cases[i] = case
- statement = Case(self.grant, cases)
- if self.switch_policy == SP_CE:
- statement = If(self.ce, statement)
- self.sync += statement
- else:
- self.comb += self.grant.eq(0)
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-
-
-class BitonicSort(Module):
- """Combinatorial sorting network
-
- The Bitonic sort is implemented as a combinatorial sort using
- comparators and multiplexers. Its asymptotic complexity (in terms of
- number of comparators/muxes) is O(n log(n)**2), like mergesort or
- shellsort.
-
- http://www.dps.uibk.ac.at/~cosenza/teaching/gpu/sort-batcher.pdf
-
- http://www.inf.fh-flensburg.de/lang/algorithmen/sortieren/bitonic/bitonicen.htm
-
- http://www.myhdl.org/doku.php/cookbook:bitonic
-
- Parameters
- ----------
- n : int
- Number of inputs and output signals.
- m : int
- Bit width of inputs and outputs. Or a tuple of `(m, signed)`.
- ascending : bool
- Sort direction. `True` if input is to be sorted ascending,
- `False` for descending. Defaults to ascending.
-
- Attributes
- ----------
- i : list of Signals, in
- Input values, each `m` wide.
- o : list of Signals, out
- Output values, sorted, each `m` bits wide.
- """
- def __init__(self, n, m, ascending=True):
- self.i = [Signal(m) for i in range(n)]
- self.o = [Signal(m) for i in range(n)]
- self._sort(self.i, self.o, int(ascending), m)
-
- def _sort_two(self, i0, i1, o0, o1, dir):
- self.comb += [
- o0.eq(i0),
- o1.eq(i1),
- If(dir == (i0 > i1),
- o0.eq(i1),
- o1.eq(i0),
- )]
-
- def _merge(self, i, o, dir, m):
- n = len(i)
- k = n//2
- if n > 1:
- t = [Signal(m) for j in range(n)]
- for j in range(k):
- self._sort_two(i[j], i[j + k], t[j], t[j + k], dir)
- self._merge(t[:k], o[:k], dir, m)
- self._merge(t[k:], o[k:], dir, m)
- else:
- self.comb += o[0].eq(i[0])
-
- def _sort(self, i, o, dir, m):
- n = len(i)
- k = n//2
- if n > 1:
- t = [Signal(m) for j in range(n)]
- self._sort(i[:k], t[:k], 1, m) # ascending
- self._sort(i[k:], t[k:], 0, m) # descending
- self._merge(t, o, dir, m)
- else:
- self.comb += o[0].eq(i[0])
+++ /dev/null
-from migen.sim.core import Simulator, run_simulation
+++ /dev/null
-import operator
-import collections
-import inspect
-
-from migen.fhdl.structure import *
-from migen.fhdl.structure import (_Value, _Statement,
- _Operator, _Slice, _ArrayProxy,
- _Assign, _Fragment)
-from migen.fhdl.bitcontainer import value_bits_sign
-from migen.fhdl.tools import list_signals, list_targets, insert_resets
-from migen.fhdl.simplify import MemoryToArray
-from migen.fhdl.specials import _MemoryLocation
-from migen.sim.vcd import VCDWriter, DummyVCDWriter
-
-
-class ClockState:
- def __init__(self, high, half_period, time_before_trans):
- self.high = high
- self.half_period = half_period
- self.time_before_trans = time_before_trans
-
-
-class TimeManager:
- def __init__(self, description):
- self.clocks = dict()
-
- for k, period_phase in description.items():
- if isinstance(period_phase, tuple):
- period, phase = period_phase
- else:
- period = period_phase
- phase = 0
- half_period = period//2
- if phase >= half_period:
- phase -= half_period
- high = True
- else:
- high = False
- self.clocks[k] = ClockState(high, half_period, half_period - phase)
-
- def tick(self):
- rising = set()
- falling = set()
- dt = min(cs.time_before_trans for cs in self.clocks.values())
- for k, cs in self.clocks.items():
- if cs.time_before_trans == dt:
- cs.high = not cs.high
- if cs.high:
- rising.add(k)
- else:
- falling.add(k)
- cs.time_before_trans -= dt
- if not cs.time_before_trans:
- cs.time_before_trans += cs.half_period
- return dt, rising, falling
-
-
-str2op = {
- "~": operator.invert,
- "+": operator.add,
- "-": operator.sub,
- "*": operator.mul,
-
- ">>>": operator.rshift,
- "<<<": operator.lshift,
-
- "&": operator.and_,
- "^": operator.xor,
- "|": operator.or_,
-
- "<": operator.lt,
- "<=": operator.le,
- "==": operator.eq,
- "!=": operator.ne,
- ">": operator.gt,
- ">=": operator.ge,
-}
-
-
-def _truncate(value, nbits, signed):
- value = value & (2**nbits - 1)
- if signed and (value & 2**(nbits - 1)):
- value -= 2**nbits
- return value
-
-
-class Evaluator:
- def __init__(self, clock_domains, replaced_memories):
- self.clock_domains = clock_domains
- self.replaced_memories = replaced_memories
- self.signal_values = dict()
- self.modifications = dict()
-
- def commit(self):
- r = set()
- for k, v in self.modifications.items():
- if k not in self.signal_values or self.signal_values[k] != v:
- self.signal_values[k] = v
- r.add(k)
- self.modifications.clear()
- return r
-
- def eval(self, node, postcommit=False):
- if isinstance(node, Constant):
- return node.value
- elif isinstance(node, Signal):
- if postcommit:
- try:
- return self.modifications[node]
- except KeyError:
- pass
- try:
- return self.signal_values[node]
- except KeyError:
- return node.reset.value
- elif isinstance(node, _Operator):
- operands = [self.eval(o, postcommit) for o in node.operands]
- if node.op == "-":
- if len(operands) == 1:
- return -operands[0]
- else:
- return operands[0] - operands[1]
- elif node.op == "m":
- return operands[1] if operands[0] else operands[2]
- else:
- return str2op[node.op](*operands)
- elif isinstance(node, _Slice):
- v = self.eval(node.value, postcommit)
- idx = range(node.start, node.stop)
- return sum(((v >> i) & 1) << j for j, i in enumerate(idx))
- elif isinstance(node, Cat):
- shift = 0
- r = 0
- for element in node.l:
- nbits = len(element)
- # make value always positive
- r |= (self.eval(element, postcommit) & (2**nbits-1)) << shift
- shift += nbits
- return r
- elif isinstance(node, _ArrayProxy):
- return self.eval(node.choices[self.eval(node.key, postcommit)],
- postcommit)
- elif isinstance(node, _MemoryLocation):
- array = self.replaced_memories[node.memory]
- return self.eval(array[self.eval(node.index, postcommit)], postcommit)
- elif isinstance(node, ClockSignal):
- return self.eval(self.clock_domains[node.cd].clk, postcommit)
- elif isinstance(node, ResetSignal):
- rst = self.clock_domains[node.cd].rst
- if rst is None:
- if node.allow_reset_less:
- return 0
- else:
- raise ValueError("Attempted to get reset signal of resetless"
- " domain '{}'".format(node.cd))
- else:
- return self.eval(rst, postcommit)
- else:
- raise NotImplementedError
-
- def assign(self, node, value):
- if isinstance(node, Signal):
- assert not node.variable
- self.modifications[node] = _truncate(value,
- node.nbits, node.signed)
- elif isinstance(node, Cat):
- for element in node.l:
- nbits = len(element)
- self.assign(element, value & (2**nbits-1))
- value >>= nbits
- elif isinstance(node, _Slice):
- full_value = self.eval(node.value, True)
- # clear bits assigned to by the slice
- full_value &= ~((2**node.stop-1) - (2**node.start-1))
- # set them to the new value
- value &= 2**(node.stop - node.start)-1
- full_value |= value << node.start
- self.assign(node.value, full_value)
- elif isinstance(node, _ArrayProxy):
- self.assign(node.choices[self.eval(node.key)], value)
- elif isinstance(node, _MemoryLocation):
- array = self.replaced_memories[node.memory]
- self.assign(array[self.eval(node.index)], value)
- else:
- raise NotImplementedError
-
- def execute(self, statements):
- for s in statements:
- if isinstance(s, _Assign):
- self.assign(s.l, self.eval(s.r))
- elif isinstance(s, If):
- if self.eval(s.cond) & (2**len(s.cond) - 1):
- self.execute(s.t)
- else:
- self.execute(s.f)
- elif isinstance(s, Case):
- nbits, signed = value_bits_sign(s.test)
- test = _truncate(self.eval(s.test), nbits, signed)
- found = False
- for k, v in s.cases.items():
- if isinstance(k, Constant) and k.value == test:
- self.execute(v)
- found = True
- break
- if not found and "default" in s.cases:
- self.execute(s.cases["default"])
- elif isinstance(s, collections.Iterable):
- self.execute(s)
- else:
- raise NotImplementedError
-
-
-# TODO: instances via Iverilog/VPI
-class Simulator:
- def __init__(self, fragment_or_module, generators, clocks={"sys": 10}, vcd_name=None):
- if isinstance(fragment_or_module, _Fragment):
- self.fragment = fragment_or_module
- else:
- self.fragment = fragment_or_module.get_fragment()
- if not isinstance(generators, dict):
- generators = {"sys": generators}
- self.generators = dict()
- for k, v in generators.items():
- if (isinstance(v, collections.Iterable)
- and not inspect.isgenerator(v)):
- self.generators[k] = list(v)
- else:
- self.generators[k] = [v]
-
- self.time = TimeManager(clocks)
- for clock in clocks.keys():
- if clock not in self.fragment.clock_domains:
- cd = ClockDomain(name=clock, reset_less=True)
- cd.clk.reset = C(self.time.clocks[clock].high)
- self.fragment.clock_domains.append(cd)
-
- mta = MemoryToArray()
- mta.transform_fragment(None, self.fragment)
- insert_resets(self.fragment)
- # comb signals return to their reset value if nothing assigns them
- self.fragment.comb[0:0] = [s.eq(s.reset)
- for s in list_targets(self.fragment.comb)]
- self.evaluator = Evaluator(self.fragment.clock_domains,
- mta.replacements)
-
- if vcd_name is None:
- self.vcd = DummyVCDWriter()
- else:
- signals = list_signals(self.fragment)
- for cd in self.fragment.clock_domains:
- signals.add(cd.clk)
- if cd.rst is not None:
- signals.add(cd.rst)
- for memory_array in mta.replacements.values():
- signals |= set(memory_array)
- signals = sorted(signals, key=lambda x: x.duid)
- self.vcd = VCDWriter(vcd_name, signals)
-
- def __enter__(self):
- return self
-
- def __exit__(self, type, value, traceback):
- self.close()
-
- def close(self):
- self.vcd.close()
-
- def _commit_and_comb_propagate(self):
- # TODO: optimize
- all_modified = set()
- modified = self.evaluator.commit()
- all_modified |= modified
- while modified:
- self.evaluator.execute(self.fragment.comb)
- modified = self.evaluator.commit()
- all_modified |= modified
- for signal in all_modified:
- self.vcd.set(signal, self.evaluator.signal_values[signal])
-
- def _evalexec_nested_lists(self, x):
- if isinstance(x, list):
- return [self._evalexec_nested_lists(e) for e in x]
- elif isinstance(x, _Value):
- return self.evaluator.eval(x)
- elif isinstance(x, _Statement):
- self.evaluator.execute([x])
- return None
- else:
- raise ValueError
-
- def _process_generators(self, cd):
- exhausted = []
- for generator in self.generators[cd]:
- reply = None
- while True:
- try:
- request = generator.send(reply)
- if request is None:
- break # next cycle
- else:
- reply = self._evalexec_nested_lists(request)
- except StopIteration:
- exhausted.append(generator)
- break
- for generator in exhausted:
- self.generators[cd].remove(generator)
-
- def _continue_simulation(self):
- # TODO: passive generators
- return any(self.generators.values())
-
- def run(self):
- self.evaluator.execute(self.fragment.comb)
- self._commit_and_comb_propagate()
-
- while True:
- dt, rising, falling = self.time.tick()
- self.vcd.delay(dt)
- for cd in rising:
- self.evaluator.assign(self.fragment.clock_domains[cd].clk, 1)
- if cd in self.fragment.sync:
- self.evaluator.execute(self.fragment.sync[cd])
- if cd in self.generators:
- self._process_generators(cd)
- for cd in falling:
- self.evaluator.assign(self.fragment.clock_domains[cd].clk, 0)
- self._commit_and_comb_propagate()
-
- if not self._continue_simulation():
- break
-
-
-def run_simulation(*args, **kwargs):
- with Simulator(*args, **kwargs) as s:
- s.run()
+++ /dev/null
-from itertools import count
-
-from migen.fhdl.namer import build_namespace
-
-
-def vcd_codes():
- codechars = [chr(i) for i in range(33, 127)]
- for n in count():
- q, r = divmod(n, len(codechars))
- code = codechars[r]
- while q > 0:
- q, r = divmod(q, len(codechars))
- code = codechars[r] + code
- yield code
-
-
-class VCDWriter:
- def __init__(self, filename, signals):
- self.fo = open(filename, "w")
- self.codes = dict()
- self.signal_values = dict()
- self.t = 0
-
- try:
- ns = build_namespace(signals)
- codes = vcd_codes()
- for signal in signals:
- name = ns.get_name(signal)
- code = next(codes)
- self.codes[signal] = code
- self.fo.write("$var wire {len} {code} {name} $end\n"
- .format(name=name, code=code, len=len(signal)))
- self.fo.write("$dumpvars\n")
- for signal in signals:
- value = signal.reset.value
- self._write_value(signal, value)
- self.signal_values[signal] = value
- self.fo.write("$end\n")
- self.fo.write("#0\n")
- except:
- self.close()
- raise
-
- def _write_value(self, signal, value):
- l = len(signal)
- if value < 0:
- value += 2**l
- if l > 1:
- fmtstr = "b{:0" + str(l) + "b} {}\n"
- else:
- fmtstr = "{}{}\n"
- self.fo.write(fmtstr.format(value, self.codes[signal]))
-
- def set(self, signal, value):
- if self.signal_values[signal] != value:
- self._write_value(signal, value)
- self.signal_values[signal] = value
-
- def delay(self, delay):
- self.t += delay
- self.fo.write("#{}\n".format(self.t))
-
- def close(self):
- self.fo.close()
-
-
-class DummyVCDWriter:
- def set(self, signal, value):
- pass
-
- def delay(self, delay):
- pass
-
- def close(self):
- pass
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-
-
-class SimCase:
- def setUp(self, *args, **kwargs):
- self.tb = self.TestBench(*args, **kwargs)
-
- def test_to_verilog(self):
- verilog.convert(self.tb)
-
- def run_with(self, generator):
- run_simulation(self.tb, generator)
+++ /dev/null
-import unittest
-
-from migen import *
-from migen.genlib.coding import *
-
-from migen.test.support import SimCase
-
-
-class EncCase(SimCase, unittest.TestCase):
- class TestBench(Module):
- def __init__(self):
- self.submodules.dut = Encoder(8)
-
- def test_sizes(self):
- self.assertEqual(len(self.tb.dut.i), 8)
- self.assertEqual(len(self.tb.dut.o), 3)
- self.assertEqual(len(self.tb.dut.n), 1)
-
- def test_run_sequence(self):
- seq = list(range(1<<8))
- def gen():
- for _ in range(256):
- if seq:
- yield self.tb.dut.i.eq(seq.pop(0))
- if (yield self.tb.dut.n):
- self.assertNotIn((yield self.tb.dut.i), [1<<i for i in range(8)])
- else:
- self.assertEqual((yield self.tb.dut.i), 1<<(yield self.tb.dut.o))
- yield
- self.run_with(gen())
-
-
-class PrioEncCase(SimCase, unittest.TestCase):
- class TestBench(Module):
- def __init__(self):
- self.submodules.dut = PriorityEncoder(8)
-
- def test_sizes(self):
- self.assertEqual(len(self.tb.dut.i), 8)
- self.assertEqual(len(self.tb.dut.o), 3)
- self.assertEqual(len(self.tb.dut.n), 1)
-
- def test_run_sequence(self):
- seq = list(range(1<<8))
- def gen():
- for _ in range(256):
- if seq:
- yield self.tb.dut.i.eq(seq.pop(0))
- i = yield self.tb.dut.i
- if (yield self.tb.dut.n):
- self.assertEqual(i, 0)
- else:
- o = yield self.tb.dut.o
- if o > 0:
- self.assertEqual(i & 1<<(o - 1), 0)
- self.assertGreaterEqual(i, 1<<o)
- yield
- self.run_with(gen())
-
-
-class DecCase(SimCase, unittest.TestCase):
- class TestBench(Module):
- def __init__(self):
- self.submodules.dut = Decoder(8)
-
- def test_sizes(self):
- self.assertEqual(len(self.tb.dut.i), 3)
- self.assertEqual(len(self.tb.dut.o), 8)
- self.assertEqual(len(self.tb.dut.n), 1)
-
- def test_run_sequence(self):
- seq = list(range(8*2))
- def gen():
- for _ in range(256):
- if seq:
- i = seq.pop()
- yield self.tb.dut.i.eq(i//2)
- yield self.tb.dut.n.eq(i%2)
- i = yield self.tb.dut.i
- o = yield self.tb.dut.o
- if (yield self.tb.dut.n):
- self.assertEqual(o, 0)
- else:
- self.assertEqual(o, 1<<i)
- self.run_with(gen())
-
-
-class SmallPrioEncCase(SimCase, unittest.TestCase):
- class TestBench(Module):
- def __init__(self):
- self.submodules.dut = PriorityEncoder(1)
-
- def test_sizes(self):
- self.assertEqual(len(self.tb.dut.i), 1)
- self.assertEqual(len(self.tb.dut.o), 1)
- self.assertEqual(len(self.tb.dut.n), 1)
-
- def test_run_sequence(self):
- seq = list(range(1))
- def gen():
- for _ in range(5):
- if seq:
- yield self.tb.dut.i.eq(seq.pop(0))
- i = yield self.tb.dut.i
- if (yield self.tb.dut.n):
- self.assertEqual(i, 0)
- else:
- o = yield self.tb.dut.o
- if o > 0:
- self.assertEqual(i & 1<<(o - 1), 0)
- self.assertGreaterEqual(i, 1<<o)
- yield
- self.run_with(gen())
+++ /dev/null
-import unittest
-
-from migen import *
-from migen.test.support import SimCase
-
-
-class ConstantCase(SimCase, unittest.TestCase):
- class TestBench(Module):
- def __init__(self):
- self.sigs = [
- (Signal(3), Constant(0), 0),
- (Signal(3), Constant(5), 5),
- (Signal(3), Constant(1, 2), 1),
- (Signal(3), Constant(-1, 7), 7),
- (Signal(3), Constant(0b10101)[:3], 0b101),
- (Signal(3), Constant(0b10101)[1:4], 0b10),
- (Signal(4), Constant(0b1100)[::-1], 0b0011),
- ]
- self.comb += [a.eq(b) for a, b, c in self.sigs]
-
- def test_comparisons(self):
- def gen():
- for s, l, v in self.tb.sigs:
- s = yield s
- self.assertEqual(
- s, int(v),
- "got {}, want {} from literal {}".format(
- s, v, l))
- self.run_with(gen())
+++ /dev/null
-import unittest
-
-from migen import *
-from migen.genlib.divider import Divider
-from migen.test.support import SimCase
-
-
-class DivisionCase(SimCase, unittest.TestCase):
- class TestBench(Module):
- def __init__(self):
- self.submodules.dut = Divider(4)
-
- def test_division(self):
- def gen():
- for dividend in range(16):
- for divisor in range(1, 16):
- with self.subTest(dividend=dividend, divisor=divisor):
- yield self.tb.dut.dividend_i.eq(dividend)
- yield self.tb.dut.divisor_i.eq(divisor)
- yield self.tb.dut.start_i.eq(1)
- yield
- yield self.tb.dut.start_i.eq(0)
- yield
- while not (yield self.tb.dut.ready_o):
- yield
- self.assertEqual((yield self.tb.dut.quotient_o), dividend//divisor)
- self.assertEqual((yield self.tb.dut.remainder_o), dividend%divisor)
- self.run_with(gen())
+++ /dev/null
-import unittest
-import os.path
-import sys
-import subprocess
-
-
-def _make_test_method(name, foldername):
- def test_method(self):
- filename = name + ".py"
- example_path = os.path.abspath(
- os.path.join(os.path.dirname(__file__), "..", "..", "examples"))
- filepath = os.path.join(example_path, foldername, filename)
- subprocess.check_call(
- [sys.executable, filepath],
- stdout=subprocess.DEVNULL
- )
-
- return test_method
-
-
-class TestExamplesSim(unittest.TestCase):
- pass
-
-for name in ("basic1",
- "basic2",
- # skip "fir" as it depends on SciPy
- # "fir",
- "memory"):
- setattr(TestExamplesSim, "test_" + name,
- _make_test_method(name, "sim"))
-
-
-class TestExamplesBasic(unittest.TestCase):
- pass
-
-for name in ("arrays",
- "fsm",
- "graycounter",
- "local_cd",
- "memory",
- "namer",
- "psync",
- "record",
- "reslice",
- "tristate",
- "two_dividers"):
- setattr(TestExamplesBasic, "test_" + name,
- _make_test_method(name, "basic"))
-
+++ /dev/null
-import unittest
-from itertools import count
-
-from migen import *
-from migen.genlib.fifo import SyncFIFO
-
-from migen.test.support import SimCase
-
-
-class SyncFIFOCase(SimCase, unittest.TestCase):
- class TestBench(Module):
- def __init__(self):
- self.submodules.dut = SyncFIFO(64, 2)
-
- self.sync += [
- If(self.dut.we & self.dut.writable,
- self.dut.din[:32].eq(self.dut.din[:32] + 1),
- self.dut.din[32:].eq(self.dut.din[32:] + 2)
- )
- ]
-
- def test_run_sequence(self):
- seq = list(range(20))
- def gen():
- for cycle in count():
- # fire re and we at "random"
- yield self.tb.dut.we.eq(cycle % 2 == 0)
- yield self.tb.dut.re.eq(cycle % 3 == 0)
- # the output if valid must be correct
- if (yield self.tb.dut.readable) and (yield self.tb.dut.re):
- try:
- i = seq.pop(0)
- except IndexError:
- break
- self.assertEqual((yield self.tb.dut.dout[:32]), i)
- self.assertEqual((yield self.tb.dut.dout[32:]), i*2)
- yield
- self.run_with(gen())
-
- def test_replace(self):
- seq = [x for x in range(20) if x % 5]
- def gen():
- for cycle in count():
- yield self.tb.dut.we.eq(cycle % 2 == 0)
- yield self.tb.dut.re.eq(cycle % 7 == 0)
- yield self.tb.dut.replace.eq(
- (yield self.tb.dut.din[:32]) % 5 == 1)
- if (yield self.tb.dut.readable) and (yield self.tb.dut.re):
- try:
- i = seq.pop(0)
- except IndexError:
- break
- self.assertEqual((yield self.tb.dut.dout[:32]), i)
- self.assertEqual((yield self.tb.dut.dout[32:]), i*2)
- yield
- self.run_with(gen())
+++ /dev/null
-import unittest
-
-from migen import *
-from migen.test.support import SimCase
-
-
-class SignedCase(SimCase, unittest.TestCase):
- class TestBench(Module):
- def __init__(self):
- self.a = Signal((3, True))
- self.b = Signal((4, True))
- comps = [
- lambda p, q: p > q,
- lambda p, q: p >= q,
- lambda p, q: p < q,
- lambda p, q: p <= q,
- lambda p, q: p == q,
- lambda p, q: p != q,
- ]
- self.vals = []
- for asign in 1, -1:
- for bsign in 1, -1:
- for f in comps:
- r = Signal()
- r0 = f(asign*self.a, bsign*self.b)
- self.comb += r.eq(r0)
- self.vals.append((asign, bsign, f, r, r0.op))
-
- def test_comparisons(self):
- def gen():
- for i in range(-4, 4):
- yield self.tb.a.eq(i)
- yield self.tb.b.eq(i)
- a = yield self.tb.a
- b = yield self.tb.b
- for asign, bsign, f, r, op in self.tb.vals:
- r, r0 = (yield r), f(asign*a, bsign*b)
- self.assertEqual(r, int(r0),
- "got {}, want {}*{} {} {}*{} = {}".format(
- r, asign, a, op, bsign, b, r0))
- yield
- self.run_with(gen())
+++ /dev/null
-import unittest
-
-from migen import *
-
-
-def _same_slices(a, b):
- return a.value is b.value and a.start == b.start and a.stop == b.stop
-
-
-class SignalSizeCase(unittest.TestCase):
- def setUp(self):
- self.i = C(0xaa)
- self.j = C(-127)
- self.s = Signal((13, True))
-
- def test_len(self):
- self.assertEqual(len(self.s), 13)
- self.assertEqual(len(self.i), 8)
- self.assertEqual(len(self.j), 8)
+++ /dev/null
-import unittest
-from random import randrange
-
-from migen import *
-from migen.genlib.sort import *
-
-from migen.test.support import SimCase
-
-
-class BitonicCase(SimCase, unittest.TestCase):
- class TestBench(Module):
- def __init__(self):
- self.submodules.dut = BitonicSort(8, 4, ascending=True)
-
- def test_sizes(self):
- self.assertEqual(len(self.tb.dut.i), 8)
- self.assertEqual(len(self.tb.dut.o), 8)
- for i in range(8):
- self.assertEqual(len(self.tb.dut.i[i]), 4)
- self.assertEqual(len(self.tb.dut.o[i]), 4)
-
- def test_sort(self):
- def gen():
- for repeat in range(20):
- for i in self.tb.dut.i:
- yield i.eq(randrange(1<<len(i)))
- yield
- self.assertEqual(sorted((yield self.tb.dut.i)),
- (yield self.tb.dut.o))
- self.run_with(gen())
+++ /dev/null
-import unittest
-import subprocess
-import os
-
-from migen import *
-from migen.fhdl.verilog import convert
-
-
-# Create a module with some combinatorial, some sequential, and some simple
-# assigns
-class SyntaxModule(Module):
- def __init__(self):
- x = [Signal(8) for y in range(10)]
- y = [Signal(8) for z in range(10)]
- en = Signal()
- a = Signal()
- b = Signal()
- z = Signal()
- as_src = Signal(16);
- as_tgt1 = Signal(16);
- as_tgt2 = Signal(16);
- self.io = {a, b, z, en, as_src, as_tgt1, as_tgt2}
-
- self.comb += If(a, z.eq(b))
- self.comb += as_tgt1.eq(as_src)
- self.comb += as_tgt2.eq(100)
- for xi in x:
- self.io.add(xi)
- for xi in range(1, len(x)):
- self.comb += If(en, y[xi].eq(x[xi-1])).Else(y[xi].eq(x[xi]))
- self.sync += x[xi].eq(y[xi])
-
-
-# Create unit test to build module, run Verilator and check for errors
-class SyntaxCase(unittest.TestCase):
- def base_test(self, name, asic_syntax, options=[]):
- filename = "test_module_{}.v".format(name)
- t = SyntaxModule()
- c = convert(t, t.io, name="test_module", asic_syntax=asic_syntax)
- f = open(filename, "w")
- f.write(str(c))
- f.close()
- subprocess.check_call("verilator --lint-only " + " ".join(options) + " " + filename,
- stdout=subprocess.DEVNULL,
- stderr=subprocess.DEVNULL, shell=True)
- os.unlink(filename)
-
- # XXX for now desactivate, travis-ci's Verilator seems to behave differently
- # XXX upgrade travis-ci's Verilator?
- #def test_generic_syntax(self):
- # options = [
- # "-Wno-WIDTH",
- # "-Wno-COMBDLY",
- # "-Wno-INITIALDLY"
- # ]
- # self.base_test("generic", False, options)
-
- def test_asic_syntax(self):
- options = [
- "-Wno-WIDTH", # XXX should we improve ASIC backend to remove this?
- ]
- self.base_test("asic", True, options)
+++ /dev/null
-from fractions import gcd
-import collections
-
-
-def flat_iteration(l):
- for element in l:
- if isinstance(element, collections.Iterable):
- for element2 in flat_iteration(element):
- yield element2
- else:
- yield element
-
-
-def xdir(obj, return_values=False):
- for attr in dir(obj):
- if attr[:2] != "__" and attr[-2:] != "__":
- if return_values:
- yield attr, getattr(obj, attr)
- else:
- yield attr
-
-
-def gcd_multiple(numbers):
- l = len(numbers)
- if l == 1:
- return numbers[0]
- else:
- s = l//2
- return gcd(gcd_multiple(numbers[:s]), gcd_multiple(numbers[s:]))
+++ /dev/null
-import cairo
-import math
-
-
-def _cairo_draw_node(ctx, dx, radius, color, outer_color, s):
- ctx.save()
-
- ctx.translate(dx, 0)
-
- ctx.set_line_width(0.0)
- gradient_color = cairo.RadialGradient(0, 0, 0, 0, 0, radius)
- gradient_color.add_color_stop_rgb(0, *color)
- gradient_color.add_color_stop_rgb(1, *outer_color)
- ctx.set_source(gradient_color)
- ctx.arc(0, 0, radius, 0, 2*math.pi)
- ctx.fill()
-
- lines = s.split("\n")
- textws = []
- texths = []
- for line in lines:
- x_bearing, y_bearing, w, h, x_advance, y_advance = ctx.text_extents(line)
- textws.append(w)
- texths.append(h + 2)
- ctx.translate(0, -sum(texths[1:])/2)
- for line, w, h in zip(lines, textws, texths):
- ctx.translate(-w/2, h/2)
- ctx.move_to(0, 0)
- ctx.set_source_rgb(0, 0, 0)
- ctx.show_text(line)
- ctx.translate(w/2, h/2)
-
- ctx.restore()
-
-
-def _cairo_draw_connection(ctx, x0, y0, color0, x1, y1, color1):
- ctx.move_to(x0, y0)
- ctx.curve_to(x0, y0+20, x1, y1-20, x1, y1)
- ctx.set_line_width(1.2)
- gradient_color = cairo.LinearGradient(x0, y0, x1, y1)
- gradient_color.add_color_stop_rgb(0, *color0)
- gradient_color.add_color_stop_rgb(1, *color1)
- ctx.set_source(gradient_color)
- ctx.stroke()
-
-
-class RenderNode:
- def __init__(self, label, children=None, color=(0.8, 0.8, 0.8), radius=40):
- self.label = label
- if children is None:
- children = []
- self.children = children
- self.color = color
- self.outer_color = (color[0]*3/5, color[1]*3/5, color[2]*3/5)
- self.radius = radius
- self.pitch = self.radius*3
-
- def get_dimensions(self):
- if self.children:
- cws, chs, cdxs = zip(*[c.get_dimensions() for c in self.children])
- w = sum(cws)
- h = self.pitch + max(chs)
- dx = cws[0]/4 - cws[-1]/4
- else:
- w = h = self.pitch
- dx = 0
- return w, h, dx
-
- def render(self, ctx):
- if self.children:
- cws, chs, cdxs = zip(*[c.get_dimensions() for c in self.children])
- first_child_x = -sum(cws)/2
-
- ctx.save()
- ctx.translate(first_child_x, self.pitch)
- for c, w in zip(self.children, cws):
- ctx.translate(w/2, 0)
- c.render(ctx)
- ctx.translate(w/2, 0)
- ctx.restore()
-
- dx = cws[0]/4 - cws[-1]/4
-
- current_x = first_child_x
- for c, w, cdx in zip(self.children, cws, cdxs):
- current_y = self.pitch - c.radius
- current_x += w/2
- _cairo_draw_connection(ctx, dx, self.radius, self.outer_color, current_x+cdx, current_y, c.outer_color)
- current_x += w/2
- else:
- dx = 0
- _cairo_draw_node(ctx, dx, self.radius, self.color, self.outer_color, self.label)
-
- def to_svg(self, name):
- w, h, dx = self.get_dimensions()
- surface = cairo.SVGSurface(name, w, h)
- ctx = cairo.Context(surface)
- ctx.translate(w/2, self.pitch/2)
- self.render(ctx)
- surface.finish()
-
-
-def _test():
- xns = [RenderNode("X"+str(n)) for n in range(5)]
- yns = [RenderNode("Y"+str(n), [RenderNode("foo", color=(0.1*n, 0.5+0.2*n, 1.0-0.3*n))]) for n in range(3)]
- n1 = RenderNode("n1", yns)
- n2 = RenderNode("n2", xns, color=(0.8, 0.5, 0.9))
- top = RenderNode("top", [n1, n2])
- top.to_svg("test.svg")
-
-if __name__ == "__main__":
- _test()
+++ /dev/null
-#!/usr/bin/env python3
-
-import sys
-from setuptools import setup
-from setuptools import find_packages
-
-
-if sys.version_info[:3] < (3, 3):
- raise SystemExit("You need Python 3.3+")
-
-
-setup(
- name="migen",
- version="0.2",
- description="Python toolbox for building complex digital hardware",
- long_description=open("README.rst").read(),
- author="Sebastien Bourdeauducq",
- author_email="sb@m-labs.hk",
- url="http://m-labs.hk",
- download_url="https://github.com/m-labs/migen",
- packages=find_packages(),
- test_suite="migen.test",
- license="BSD",
- platforms=["Any"],
- keywords="HDL ASIC FPGA hardware design",
- classifiers=[
- "Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
- "Environment :: Console",
- "Development Status :: Beta",
- "Intended Audience :: Developers",
- "License :: OSI Approved :: BSD License",
- "Operating System :: OS Independent",
- "Programming Language :: Python",
- ],
-)
--- /dev/null
+from litex.gen.sim.core import Simulator, run_simulation
--- /dev/null
+import operator
+import collections
+import inspect
+
+from litex.gen.fhdl.structure import *
+from litex.gen.fhdl.structure import (_Value, _Statement,
+ _Operator, _Slice, _ArrayProxy,
+ _Assign, _Fragment)
+from litex.gen.fhdl.bitcontainer import value_bits_sign
+from litex.gen.fhdl.tools import list_signals, list_targets, insert_resets
+from litex.gen.fhdl.simplify import MemoryToArray
+from litex.gen.fhdl.specials import _MemoryLocation
+from litex.gen.sim.vcd import VCDWriter, DummyVCDWriter
+
+
+class ClockState:
+ def __init__(self, high, half_period, time_before_trans):
+ self.high = high
+ self.half_period = half_period
+ self.time_before_trans = time_before_trans
+
+
+class TimeManager:
+ def __init__(self, description):
+ self.clocks = dict()
+
+ for k, period_phase in description.items():
+ if isinstance(period_phase, tuple):
+ period, phase = period_phase
+ else:
+ period = period_phase
+ phase = 0
+ half_period = period//2
+ if phase >= half_period:
+ phase -= half_period
+ high = True
+ else:
+ high = False
+ self.clocks[k] = ClockState(high, half_period, half_period - phase)
+
+ def tick(self):
+ rising = set()
+ falling = set()
+ dt = min(cs.time_before_trans for cs in self.clocks.values())
+ for k, cs in self.clocks.items():
+ if cs.time_before_trans == dt:
+ cs.high = not cs.high
+ if cs.high:
+ rising.add(k)
+ else:
+ falling.add(k)
+ cs.time_before_trans -= dt
+ if not cs.time_before_trans:
+ cs.time_before_trans += cs.half_period
+ return dt, rising, falling
+
+
+str2op = {
+ "~": operator.invert,
+ "+": operator.add,
+ "-": operator.sub,
+ "*": operator.mul,
+
+ ">>>": operator.rshift,
+ "<<<": operator.lshift,
+
+ "&": operator.and_,
+ "^": operator.xor,
+ "|": operator.or_,
+
+ "<": operator.lt,
+ "<=": operator.le,
+ "==": operator.eq,
+ "!=": operator.ne,
+ ">": operator.gt,
+ ">=": operator.ge,
+}
+
+
+def _truncate(value, nbits, signed):
+ value = value & (2**nbits - 1)
+ if signed and (value & 2**(nbits - 1)):
+ value -= 2**nbits
+ return value
+
+
+class Evaluator:
+ def __init__(self, clock_domains, replaced_memories):
+ self.clock_domains = clock_domains
+ self.replaced_memories = replaced_memories
+ self.signal_values = dict()
+ self.modifications = dict()
+
+ def commit(self):
+ r = set()
+ for k, v in self.modifications.items():
+ if k not in self.signal_values or self.signal_values[k] != v:
+ self.signal_values[k] = v
+ r.add(k)
+ self.modifications.clear()
+ return r
+
+ def eval(self, node, postcommit=False):
+ if isinstance(node, Constant):
+ return node.value
+ elif isinstance(node, Signal):
+ if postcommit:
+ try:
+ return self.modifications[node]
+ except KeyError:
+ pass
+ try:
+ return self.signal_values[node]
+ except KeyError:
+ return node.reset.value
+ elif isinstance(node, _Operator):
+ operands = [self.eval(o, postcommit) for o in node.operands]
+ if node.op == "-":
+ if len(operands) == 1:
+ return -operands[0]
+ else:
+ return operands[0] - operands[1]
+ elif node.op == "m":
+ return operands[1] if operands[0] else operands[2]
+ else:
+ return str2op[node.op](*operands)
+ elif isinstance(node, _Slice):
+ v = self.eval(node.value, postcommit)
+ idx = range(node.start, node.stop)
+ return sum(((v >> i) & 1) << j for j, i in enumerate(idx))
+ elif isinstance(node, Cat):
+ shift = 0
+ r = 0
+ for element in node.l:
+ nbits = len(element)
+ # make value always positive
+ r |= (self.eval(element, postcommit) & (2**nbits-1)) << shift
+ shift += nbits
+ return r
+ elif isinstance(node, _ArrayProxy):
+ return self.eval(node.choices[self.eval(node.key, postcommit)],
+ postcommit)
+ elif isinstance(node, _MemoryLocation):
+ array = self.replaced_memories[node.memory]
+ return self.eval(array[self.eval(node.index, postcommit)], postcommit)
+ elif isinstance(node, ClockSignal):
+ return self.eval(self.clock_domains[node.cd].clk, postcommit)
+ elif isinstance(node, ResetSignal):
+ rst = self.clock_domains[node.cd].rst
+ if rst is None:
+ if node.allow_reset_less:
+ return 0
+ else:
+ raise ValueError("Attempted to get reset signal of resetless"
+ " domain '{}'".format(node.cd))
+ else:
+ return self.eval(rst, postcommit)
+ else:
+ raise NotImplementedError
+
+ def assign(self, node, value):
+ if isinstance(node, Signal):
+ assert not node.variable
+ self.modifications[node] = _truncate(value,
+ node.nbits, node.signed)
+ elif isinstance(node, Cat):
+ for element in node.l:
+ nbits = len(element)
+ self.assign(element, value & (2**nbits-1))
+ value >>= nbits
+ elif isinstance(node, _Slice):
+ full_value = self.eval(node.value, True)
+ # clear bits assigned to by the slice
+ full_value &= ~((2**node.stop-1) - (2**node.start-1))
+ # set them to the new value
+ value &= 2**(node.stop - node.start)-1
+ full_value |= value << node.start
+ self.assign(node.value, full_value)
+ elif isinstance(node, _ArrayProxy):
+ self.assign(node.choices[self.eval(node.key)], value)
+ elif isinstance(node, _MemoryLocation):
+ array = self.replaced_memories[node.memory]
+ self.assign(array[self.eval(node.index)], value)
+ else:
+ raise NotImplementedError
+
+ def execute(self, statements):
+ for s in statements:
+ if isinstance(s, _Assign):
+ self.assign(s.l, self.eval(s.r))
+ elif isinstance(s, If):
+ if self.eval(s.cond) & (2**len(s.cond) - 1):
+ self.execute(s.t)
+ else:
+ self.execute(s.f)
+ elif isinstance(s, Case):
+ nbits, signed = value_bits_sign(s.test)
+ test = _truncate(self.eval(s.test), nbits, signed)
+ found = False
+ for k, v in s.cases.items():
+ if isinstance(k, Constant) and k.value == test:
+ self.execute(v)
+ found = True
+ break
+ if not found and "default" in s.cases:
+ self.execute(s.cases["default"])
+ elif isinstance(s, collections.Iterable):
+ self.execute(s)
+ else:
+ raise NotImplementedError
+
+
+# TODO: instances via Iverilog/VPI
+class Simulator:
+ def __init__(self, fragment_or_module, generators, clocks={"sys": 10}, vcd_name=None):
+ if isinstance(fragment_or_module, _Fragment):
+ self.fragment = fragment_or_module
+ else:
+ self.fragment = fragment_or_module.get_fragment()
+ if not isinstance(generators, dict):
+ generators = {"sys": generators}
+ self.generators = dict()
+ for k, v in generators.items():
+ if (isinstance(v, collections.Iterable)
+ and not inspect.isgenerator(v)):
+ self.generators[k] = list(v)
+ else:
+ self.generators[k] = [v]
+
+ self.time = TimeManager(clocks)
+ for clock in clocks.keys():
+ if clock not in self.fragment.clock_domains:
+ cd = ClockDomain(name=clock, reset_less=True)
+ cd.clk.reset = C(self.time.clocks[clock].high)
+ self.fragment.clock_domains.append(cd)
+
+ mta = MemoryToArray()
+ mta.transform_fragment(None, self.fragment)
+ insert_resets(self.fragment)
+ # comb signals return to their reset value if nothing assigns them
+ self.fragment.comb[0:0] = [s.eq(s.reset)
+ for s in list_targets(self.fragment.comb)]
+ self.evaluator = Evaluator(self.fragment.clock_domains,
+ mta.replacements)
+
+ if vcd_name is None:
+ self.vcd = DummyVCDWriter()
+ else:
+ signals = list_signals(self.fragment)
+ for cd in self.fragment.clock_domains:
+ signals.add(cd.clk)
+ if cd.rst is not None:
+ signals.add(cd.rst)
+ for memory_array in mta.replacements.values():
+ signals |= set(memory_array)
+ signals = sorted(signals, key=lambda x: x.duid)
+ self.vcd = VCDWriter(vcd_name, signals)
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, type, value, traceback):
+ self.close()
+
+ def close(self):
+ self.vcd.close()
+
+ def _commit_and_comb_propagate(self):
+ # TODO: optimize
+ all_modified = set()
+ modified = self.evaluator.commit()
+ all_modified |= modified
+ while modified:
+ self.evaluator.execute(self.fragment.comb)
+ modified = self.evaluator.commit()
+ all_modified |= modified
+ for signal in all_modified:
+ self.vcd.set(signal, self.evaluator.signal_values[signal])
+
+ def _evalexec_nested_lists(self, x):
+ if isinstance(x, list):
+ return [self._evalexec_nested_lists(e) for e in x]
+ elif isinstance(x, _Value):
+ return self.evaluator.eval(x)
+ elif isinstance(x, _Statement):
+ self.evaluator.execute([x])
+ return None
+ else:
+ raise ValueError
+
+ def _process_generators(self, cd):
+ exhausted = []
+ for generator in self.generators[cd]:
+ reply = None
+ while True:
+ try:
+ request = generator.send(reply)
+ if request is None:
+ break # next cycle
+ else:
+ reply = self._evalexec_nested_lists(request)
+ except StopIteration:
+ exhausted.append(generator)
+ break
+ for generator in exhausted:
+ self.generators[cd].remove(generator)
+
+ def _continue_simulation(self):
+ # TODO: passive generators
+ return any(self.generators.values())
+
+ def run(self):
+ self.evaluator.execute(self.fragment.comb)
+ self._commit_and_comb_propagate()
+
+ while True:
+ dt, rising, falling = self.time.tick()
+ self.vcd.delay(dt)
+ for cd in rising:
+ self.evaluator.assign(self.fragment.clock_domains[cd].clk, 1)
+ if cd in self.fragment.sync:
+ self.evaluator.execute(self.fragment.sync[cd])
+ if cd in self.generators:
+ self._process_generators(cd)
+ for cd in falling:
+ self.evaluator.assign(self.fragment.clock_domains[cd].clk, 0)
+ self._commit_and_comb_propagate()
+
+ if not self._continue_simulation():
+ break
+
+
+def run_simulation(*args, **kwargs):
+ with Simulator(*args, **kwargs) as s:
+ s.run()
--- /dev/null
+from itertools import count
+
+from litex.gen.fhdl.namer import build_namespace
+
+
+def vcd_codes():
+ codechars = [chr(i) for i in range(33, 127)]
+ for n in count():
+ q, r = divmod(n, len(codechars))
+ code = codechars[r]
+ while q > 0:
+ q, r = divmod(q, len(codechars))
+ code = codechars[r] + code
+ yield code
+
+
+class VCDWriter:
+ def __init__(self, filename, signals):
+ self.fo = open(filename, "w")
+ self.codes = dict()
+ self.signal_values = dict()
+ self.t = 0
+
+ try:
+ ns = build_namespace(signals)
+ codes = vcd_codes()
+ for signal in signals:
+ name = ns.get_name(signal)
+ code = next(codes)
+ self.codes[signal] = code
+ self.fo.write("$var wire {len} {code} {name} $end\n"
+ .format(name=name, code=code, len=len(signal)))
+ self.fo.write("$dumpvars\n")
+ for signal in signals:
+ value = signal.reset.value
+ self._write_value(signal, value)
+ self.signal_values[signal] = value
+ self.fo.write("$end\n")
+ self.fo.write("#0\n")
+ except:
+ self.close()
+ raise
+
+ def _write_value(self, signal, value):
+ l = len(signal)
+ if value < 0:
+ value += 2**l
+ if l > 1:
+ fmtstr = "b{:0" + str(l) + "b} {}\n"
+ else:
+ fmtstr = "{}{}\n"
+ self.fo.write(fmtstr.format(value, self.codes[signal]))
+
+ def set(self, signal, value):
+ if self.signal_values[signal] != value:
+ self._write_value(signal, value)
+ self.signal_values[signal] = value
+
+ def delay(self, delay):
+ self.t += delay
+ self.fo.write("#{}\n".format(self.t))
+
+ def close(self):
+ self.fo.close()
+
+
+class DummyVCDWriter:
+ def set(self, signal, value):
+ pass
+
+ def delay(self, delay):
+ pass
+
+ def close(self):
+ pass
+++ /dev/null
-#!/bin/sh
-# Copyright Robert Jordens <robert@joerdens.org> 2014,2015
-
-# assuming your xilinx toolchain lives in /opt/Xilinx,
-# run `strace_tailor.sh /opt/Xilinx/ [synthesis script] [options]`,
-# e.g. for the pipistrello target of misoc:
-# strace_tailor.sh /opt/Xilinx/ ./make.py -t pipistrello build-bitstream
-# then in your current directory, `opt/Xilinx/*` is the
-# minimal toolchain required for this synthesis script run.
-
-PREFIX=$1
-shift
-strace -e trace=file,process -f -o strace.log $@
-sed -n 's|^.*"\('"$PREFIX"'[^"]*\)".*$|\1|p' strace.log \
- | sort | uniq | xargs -d '\n' \
- cp --parent --no-dereference --preserve=all -t .
--- /dev/null
+from fractions import gcd
+import collections
+
+
+def flat_iteration(l):
+ for element in l:
+ if isinstance(element, collections.Iterable):
+ for element2 in flat_iteration(element):
+ yield element2
+ else:
+ yield element
+
+
+def xdir(obj, return_values=False):
+ for attr in dir(obj):
+ if attr[:2] != "__" and attr[-2:] != "__":
+ if return_values:
+ yield attr, getattr(obj, attr)
+ else:
+ yield attr
+
+
+def gcd_multiple(numbers):
+ l = len(numbers)
+ if l == 1:
+ return numbers[0]
+ else:
+ s = l//2
+ return gcd(gcd_multiple(numbers[:s]), gcd_multiple(numbers[s:]))
+++ /dev/null
-__pycache__
-*.pyc
-*.egg-info
-*.vcd
-outgoing
+++ /dev/null
-[submodule "misoc/cores/lm32/verilog/submodule"]
- path = misoc/cores/lm32/verilog/submodule
- url = https://github.com/m-labs/lm32.git
-[submodule "misoc/cores/mor1kx/verilog"]
- path = misoc/cores/mor1kx/verilog
- url = https://github.com/openrisc/mor1kx.git
-[submodule "misoc/software/compiler_rt"]
- path = misoc/software/compiler_rt
- url = http://llvm.org/git/compiler-rt.git
-[submodule "misoc/software/unwinder"]
- path = misoc/software/unwinder
- url = https://github.com/whitequark/libunwind
+++ /dev/null
-language: python
-python:
- - "3.5"
-
-env:
- global:
- - PATH=$HOME/miniconda/bin:$PATH
-
-before_install:
- # Install Miniconda
- - wget https://raw.githubusercontent.com/m-labs/artiq/master/.travis/get-anaconda.sh
- - chmod +x get-anaconda.sh
- - ./get-anaconda.sh
- - source $HOME/miniconda/bin/activate py35
- - conda install anaconda-client
-install:
- # workaround for https://github.com/conda/conda-build/issues/466
- - "mkdir -p /home/travis/miniconda/conda-bld/linux-64"
- - "conda index /home/travis/miniconda/conda-bld/linux-64"
- - "conda build --python 3.5 conda/misoc"
- - "conda install $(conda build --output --python 3.5 conda/misoc)"
-script:
- - true
-
-after_success:
- - if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then anaconda login --hostname $(hostname) --username $binstar_login --password $binstar_password; fi
- - if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then anaconda upload --user $binstar_login --channel dev --force $HOME/miniconda/conda-bld/noarch/misoc-*.tar.bz2; fi
-
-notifications:
- email: false
- irc:
- channels:
- - chat.freenode.net#m-labs
- template:
- - "%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message}"
- - "Build details : %{build_url}"
+++ /dev/null
-
-# Sending Patches
-
-MiSoC does **not** use GitHub pull requests. Instead you must send patches to
-the public mailing list <devel@lists.m-labs.hk>.
-
-Before sending patches, please read the rest of this guide and make sure your
-patch meets the following criteria;
-
- - [ ] Meets style guide requirements listed below.
- - [ ] Includes a suitable commit message.
-
-Sending mail to the mailing list can be done via the `git send-email` tool.
-The `git send-email` tool is not included by default on many Linux
-distributions, on Ubuntu / Debian systems you may need to install the
-`git-email` package. Documentation on using this tool can be found at
-http://git-scm.com/docs/git-send-email
-
-To send patches to the mailing list you must first be subscribed to the list.
-You can subscribe at https://ssl.serverraum.org/lists/listinfo/devel
-
-An example session would be;
-```
-# Set up [sendemail] as described at http://git-scm.com/docs/git-send-email in
-# the EXAMPLE section.
-
-# Download, make changes to misoc and commit them
-git clone https://github.com/m-labs/misoc
-cd misoc
-edit xxx.py
-git commit -a
-
-# Send patch to mailing list
-# --------------------------
-# 1) Remove any previous outgoing patch
-rm -rf outgoing
-
-# 2) Put the patches to be sent into the outgoing directory
-git format-patch --cover-letter -M origin/master -o outgoing/
-
-# 3) Edit the cover letter with information about the patch
-edit outgoing/0000-*
-
-# 4) Actually send the email.
-git send-email --to=devel@lists.m-labs.hk outgoing/*
-```
-
-# Help
-
-If your submission is large and complex and/or you are not sure how to proceed,
-feel free to discuss it on the mailing list or IRC (#m-labs on Freenode)
-beforehand.
-
-# Style Guide
-
-All code should be compliant with the
-[PEP8 style guide](https://www.python.org/dev/peps/pep-0008/).
-
-You can use the [pep8 tool](https://www.python.org/dev/peps/pep-0008/) to check
-compliance with `pep8 myfile.py`
-
-When modifying existing code **be consistent** with any existing code style.
-
-# License
-
-All new contributions should be under the same license as MiSoC. This is a very
-permissive two-clause BSD license. Full license text can be found at
-https://github.com/m-labs/misoc/blob/master/LICENSE
+++ /dev/null
-Unless otherwise noted, MiSoC is copyright (C) 2011-2014 Sebastien Bourdeauducq.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-Other authors retain ownership of their contributions. If a submission can
-reasonably be considered independently copyrightable, it's yours and we
-encourage you to claim it with appropriate copyright notices. This submission
-then falls under the "otherwise noted" category. All submissions are strongly
-encouraged to use the two-clause BSD license reproduced above.
+++ /dev/null
-graft misoc/software
-graft misoc/cores/lm32/verilog
-graft misoc/cores/mor1kx/verilog
-include misoc/cores/mxcrg.v
--- /dev/null
+Unless otherwise noted, MiSoC is copyright (C) 2011-2014 Sebastien Bourdeauducq.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+Other authors retain ownership of their contributions. If a submission can
+reasonably be considered independently copyrightable, it's yours and we
+encourage you to claim it with appropriate copyright notices. This submission
+then falls under the "otherwise noted" category. All submissions are strongly
+encouraged to use the two-clause BSD license reproduced above.
+++ /dev/null
- __ ___ _ ____ _____
- / |/ / (_) / __/__ / ___/
- / /|_/ / / / _\ \/ _ \/ /__
- /_/ /_/ /_/ /___/\___/\___/
-
- Copyright 2007-2015 / M-Labs Ltd
- Copyright 2012-2015 / Enjoy-Digital
-
- a high performance and small footprint SoC based on Migen
-
-[> Features
------------
- * LatticeMico32 CPU, modified to include an optional MMU (experimental).
- * mor1kx (a better OpenRISC implementation) as alternative CPU option.
- * High performance memory controller capable of issuing several SDRAM commands
- per FPGA cycle.
- * Supports SDR, DDR, LPDDR, DDR2 and DDR3.
- * Provided peripherals: UART, GPIO, timer, GPIO, NOR flash controller, SPI
- flash controller, Ethernet MAC, and more.
- * High performance:
- - on Spartan-6, 83MHz system clock frequencies, 10+Gbps DDR
- SDRAM bandwidth, 1080p 32bpp framebuffer, etc.
- - on Kintex-7, 125MHz system clock frequencies (up to 200MHz without DDR3),
- 64Gbps DDR3 SDRAM bandwidth.
- * Low resource usage: basic implementation fits easily in Spartan-6 LX9.
- * Portable and easy to customize thanks to Python- and Migen-based
- architecture.
- * Design new peripherals using Migen and benefit from automatic CSR maps
- and logic, etc.
- * Possibility to encapsulate legacy Verilog/VHDL code.
- * Complex FPGA cores that can be used integrated in MiSoC or standalone:
- - LiteEth: a small footprint and configurable Ethernet core
-
-MiSoC comes with built-in support for the following boards:
- * Mixxeo, the digital video mixer from M-Labs [XC6SLX45]
- * Milkymist One, the original M-Labs video synthesizer [XC6SLX45]
- * Papilio Pro, a simple and low-cost development board [XC6SLX9]
- * Pipistrello, a simple board with USB and HDMI [XC6SLX45]
- * De0 Nano, a simple and low-cost development board [CYCLONEIV]
- * KC705, a Kintex-7 devboard from Xilinx [XC7K325T]
- * Versa, a low-cost Lattice development board [ECP3-35]
-MiSoC is portable and support for other boards can easily be added as external
-modules.
-
-[> Quick start guide
---------------------
-0. If cloned from Git without the --recursive option, get the submodules:
- git submodule update --init
-
-1. Install Python 3.3+, Migen and FPGA vendor's development tools.
- Get Migen from: https://github.com/m-labs/migen
-
-2. Install JTAG tools.
- For Mixxeo and M1: http://urjtag.org
- For Papilio Pro and KC705: http://xc3sprog.sourceforge.net
- For De0 Nano: USBBlaster from Altera
- We recommend using xc3sprog for Xilinx devices, but Vivado programmer
- is also supported for Xilinx 7-series.
-
-3. (Optional, only needed if you want to flash the bistream/software)
- Obtain and build any required flash proxy bitstreams. Flash proxy bitstreams
- give JTAG access to a flash chip through the FPGA.
- For Mixxeo and M1: https://github.com/m-labs/fjmem-m1
- For Papilio Pro: https://github.com/GadgetFactory/Papilio-Loader
- (xc3sprog/trunk/bscan_spi/bscan_spi_lx9_papilio.bit)
- For KC705: https://github.com/m-labs/bscan_spi_kc705
-
-4. Compile and install binutils. Take the latest version from GNU.
- mkdir build && cd build
- ../configure --target=lm32-elf
- make
- make install
-
-5. Compile and install GCC. Take gcc-core and gcc-g++ from GNU
- (version 4.5 or >=4.9).
- rm -rf libstdc++-v3
- mkdir build && cd build
- ../configure --target=lm32-elf --enable-languages="c,c++" --disable-libgcc \
- --disable-libssp
- make
- make install
-
-6. Build and flash the BIOS and bitstream. Run from MiSoC:
- For Mixxeo: ./make.py all
- For M1: ./make.py -p m1 all
- For Papilio Pro: ./make.py -t ppro all
- For Pipistrello: ./make.py -t pipistrello all
- For De0 Nano: ./make.py -t de0nano all load-bitstream
- For KC705: ./make.py -t kc705 all
-
- If just want to load the bitstream in volatile SRAM use:
- all load-bitstream
-
-7. Run a terminal program on the board's serial port at 115200 8-N-1.
- You should get the BIOS prompt.
-
-8. Read and experiment with the source!
- Come to our IRC channel and mailing list!
- A simple target is provided to test MiSoC easily with your board:
- Create your target with a clock and serial pins.
- Build and test it: ./make.py -t simple -p your_platform all load-bitstream
- If you don't have access to a FPGA board, you can also try MiSoC
- with Verilator:
- Download and install Verilator: http://www.veripool.org/
- Test it: ./make.py -t simple -p sim build-bitstream
-
-9. Contribute a patch!
- Once you have experimented with stuff, please send your results back.
- For more details on how to do so, you can see the CONTRIBUTING.rst file.
-
-[> License
-----------
-MiSoC is released under the very permissive two-clause BSD license. Under
-the terms of this license, you are authorized to use MiSoC for
-closed-source proprietary designs.
-Even though we do not require you to do so, those things are awesome, so please
-do them if possible:
- * tell us that you are using MiSoC
- * cite MiSoC in publications related to research it has helped
- * send us feedback and suggestions for improvements
- * send us bug reports when something goes wrong
- * send us the modifications and improvements you have done to MiSoC.
- The use of "git format-patch" is recommended. If your submission is large
- and complex and/or you are not sure how to proceed, feel free to discuss it
- on the mailing list or IRC (#m-labs on Freenode) beforehand.
-
-See LICENSE file for full copyright and license info.
-
-[> Links
---------
-Web:
- http://m-labs.hk
- http://enjoy-digital.fr
-
-Code repository:
- https://github.com/m-labs/misoc
-
-You can contact us on the public mailing list devel [AT] lists.m-labs.hk.
+++ /dev/null
-%PYTHON% setup.py install
+++ /dev/null
-package:
- name: misoc
- version: {{ environ.get("GIT_DESCRIBE_TAG", "") }}
-
-source:
- git_url: https://github.com/m-labs/misoc
- git_tag: master
-
-build:
- noarch_python: true
- number: {{ environ.get("GIT_DESCRIBE_NUMBER", 0) }}
- string: py_{{ environ.get("GIT_DESCRIBE_NUMBER", 0) }}+git{{ environ.get("GIT_DESCRIBE_HASH", "")[1:] }}
- script: $PYTHON setup.py install
-
-requirements:
- build:
- - migen
- - python
- run:
- - migen
- - python
-
-about:
- home: http://m-labs.hk/gateware.html
- license: 3-clause BSD
- summary: 'A high performance and small footprint SoC based on Migen'
--- /dev/null
+from litex.soc.cores.cpu.lm32.core import LM32
--- /dev/null
+import os
+
+from litex.gen import *
+
+from litex.soc.interconnect import wishbone
+
+
+class LM32(Module):
+ def __init__(self, platform, eba_reset):
+ self.ibus = i = wishbone.Interface()
+ self.dbus = d = wishbone.Interface()
+ self.interrupt = Signal(32)
+
+ ###
+
+ i_adr_o = Signal(32)
+ d_adr_o = Signal(32)
+ self.specials += Instance("lm32_cpu",
+ p_eba_reset=Instance.PreformattedParam("32'h{:08x}".format(eba_reset)),
+
+ i_clk_i=ClockSignal(),
+ i_rst_i=ResetSignal(),
+
+ i_interrupt=self.interrupt,
+
+ o_I_ADR_O=i_adr_o,
+ o_I_DAT_O=i.dat_w,
+ o_I_SEL_O=i.sel,
+ o_I_CYC_O=i.cyc,
+ o_I_STB_O=i.stb,
+ o_I_WE_O=i.we,
+ o_I_CTI_O=i.cti,
+ o_I_BTE_O=i.bte,
+ i_I_DAT_I=i.dat_r,
+ i_I_ACK_I=i.ack,
+ i_I_ERR_I=i.err,
+ i_I_RTY_I=0,
+
+ o_D_ADR_O=d_adr_o,
+ o_D_DAT_O=d.dat_w,
+ o_D_SEL_O=d.sel,
+ o_D_CYC_O=d.cyc,
+ o_D_STB_O=d.stb,
+ o_D_WE_O=d.we,
+ o_D_CTI_O=d.cti,
+ o_D_BTE_O=d.bte,
+ i_D_DAT_I=d.dat_r,
+ i_D_ACK_I=d.ack,
+ i_D_ERR_I=d.err,
+ i_D_RTY_I=0)
+
+ self.comb += [
+ self.ibus.adr.eq(i_adr_o[2:]),
+ self.dbus.adr.eq(d_adr_o[2:])
+ ]
+
+ # add Verilog sources
+ vdir = os.path.join(
+ os.path.abspath(os.path.dirname(__file__)), "verilog")
+ platform.add_sources(os.path.join(vdir, "submodule", "rtl"),
+ "lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v",
+ "lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v",
+ "lm32_shifter.v", "lm32_multiplier.v", "lm32_mc_arithmetic.v",
+ "lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v",
+ "lm32_dcache.v", "lm32_debug.v", "lm32_itlb.v", "lm32_dtlb.v")
+ platform.add_verilog_include_path(vdir)
--- /dev/null
+`ifdef LM32_CONFIG_V
+`else
+`define LM32_CONFIG_V
+
+//
+// EXCEPTION VECTORS BASE ADDRESS
+//
+
+// Base address for exception vectors
+`define CFG_EBA_RESET 32'h00000000
+
+// Base address for the debug exception vectors. If the DC_RE flag is
+// set or the at_debug signal is asserted (see CFG_ALTERNATE_EBA) this
+// will also be used for normal exception vectors.
+`define CFG_DEBA_RESET 32'h10000000
+
+// Enable exception vector remapping by external signal
+//`define CFG_ALTERNATE_EBA
+
+
+//
+// ALU OPTIONS
+//
+
+// Enable sign-extension instructions
+`define CFG_SIGN_EXTEND_ENABLED
+
+// Shifter
+// You may either enable the piplined or the multi-cycle barrel
+// shifter. The multi-cycle shifter will stall the pipeline until
+// the result is available after 32 cycles.
+// If both options are disabled, only "right shift by one bit" is
+// available.
+//`define CFG_MC_BARREL_SHIFT_ENABLED
+`define CFG_PL_BARREL_SHIFT_ENABLED
+
+// Multiplier
+// The multiplier is available either in a multi-cycle version or
+// in a pipelined one. The multi-cycle multiplier stalls the pipe
+// for 32 cycles. If both options are disabled, multiply operations
+// are not supported.
+//`define CFG_MC_MULTIPLY_ENABLED
+`define CFG_PL_MULTIPLY_ENABLED
+
+// Enable the multi-cycle divider. Stalls the pipe until the result
+// is ready after 32 cycles. If disabled, the divide operation is not
+// supported.
+`define CFG_MC_DIVIDE_ENABLED
+
+
+//
+// INTERRUPTS
+//
+
+// Enable support for 32 hardware interrupts
+`define CFG_INTERRUPTS_ENABLED
+
+// Enable level-sensitive interrupts. The interrupt line status is
+// reflected in the IP register, which is then read-only.
+`define CFG_LEVEL_SENSITIVE_INTERRUPTS
+
+
+//
+// USER INSTRUCTION
+//
+
+// Enable support for the user opcode.
+//`define CFG_USER_ENABLED
+
+
+//
+// MEMORY MANAGEMENT UNIT
+//
+
+// Enable instruction and data translation lookaside buffers and
+// restricted user mode.
+//`define CFG_MMU_ENABLED
+
+
+//
+// CACHE
+//
+
+// Instruction cache
+`define CFG_ICACHE_ENABLED
+`define CFG_ICACHE_ASSOCIATIVITY 1
+`define CFG_ICACHE_SETS 256
+`define CFG_ICACHE_BYTES_PER_LINE 16
+`define CFG_ICACHE_BASE_ADDRESS 32'h00000000
+`define CFG_ICACHE_LIMIT 32'h7fffffff
+
+// Data cache
+`define CFG_DCACHE_ENABLED
+`define CFG_DCACHE_ASSOCIATIVITY 1
+`define CFG_DCACHE_SETS 256
+`define CFG_DCACHE_BYTES_PER_LINE 16
+`define CFG_DCACHE_BASE_ADDRESS 32'h00000000
+`define CFG_DCACHE_LIMIT 32'h7fffffff
+
+
+//
+// DEBUG OPTION
+//
+
+// Globally enable debugging
+//`define CFG_DEBUG_ENABLED
+
+// Enable the hardware JTAG debugging interface.
+// Note: to use this, there must be a special JTAG module for your
+// device. At the moment, there is only support for the
+// Spartan-6.
+//`define CFG_JTAG_ENABLED
+
+// JTAG UART is a communication channel which uses JTAG to transmit
+// and receive bytes to and from the host computer.
+//`define CFG_JTAG_UART_ENABLED
+
+// Enable reading and writing to the memory and writing CSRs using
+// the JTAG interface.
+//`define CFG_HW_DEBUG_ENABLED
+
+// Number of hardware watchpoints, max. 4
+//`define CFG_WATCHPOINTS 32'h4
+
+// Enable hardware breakpoints
+//`define CFG_ROM_DEBUG_ENABLED
+
+// Number of hardware breakpoints, max. 4
+//`define CFG_BREAKPOINTS 32'h4
+
+// Put the processor into debug mode by an external signal. That is,
+// raise a breakpoint exception. This is useful if you have a debug
+// monitor and a serial line and you want to trap into the monitor on a
+// BREAK symbol on the serial line.
+//`define CFG_EXTERNAL_BREAK_ENABLED
+
+
+//
+// REGISTER FILE
+//
+
+// The following option explicitly infers block RAM for the register
+// file. There is extra logic to avoid parallel writes and reads.
+// Normally, if your synthesizer is smart enough, this should not be
+// necessary because it will automatically infer block RAM for you.
+//`define CFG_EBR_POSEDGE_REGISTER_FILE
+
+// Explicitly infers block RAM, too. But it uses two different clocks,
+// one being shifted by 180deg, for the read and write port. Therefore,
+// no additional logic to avoid the parallel write/reads.
+//`define CFG_EBR_NEGEDGE_REGISTER_FILE
+
+
+//
+// MISCELLANEOUS
+//
+
+// Exceptions on wishbone bus errors
+//`define CFG_BUS_ERRORS_ENABLED
+
+// Enable the cycle counter
+`define CFG_CYCLE_COUNTER_ENABLED
+
+// Embedded instruction ROM using on-chip block RAM
+//`define CFG_IROM_ENABLED
+//`define CFG_IROM_INIT_FILE "NONE"
+//`define CFG_IROM_BASE_ADDRESS 32'h10000000
+//`define CFG_IROM_LIMIT 32'h10000fff
+
+// Embedded data RAM using on-chip block RAM
+//`define CFG_DRAM_ENABLED
+//`define CFG_DRAM_INIT_FILE "NONE"
+//`define CFG_DRAM_BASE_ADDRESS 32'h20000000
+//`define CFG_DRAM_LIMIT 32'h20000fff
+
+// Trace unit
+//`define CFG_TRACE_ENABLED
+
+// Resolve unconditional branches already in the X stage (UNTESTED!)
+//`define CFG_FAST_UNCONDITIONAL_BRANCH
+
+// log2 function
+// If your simulator/synthesizer does not support the $clog2 system
+// function you can use a constant function instead.
+
+function integer clog2;
+ input integer value;
+ begin
+ value = value - 1;
+ for (clog2 = 0; value > 0; clog2 = clog2 + 1)
+ value = value >> 1;
+ end
+endfunction
+
+`define CLOG2 clog2
+
+//`define CLOG2 $clog2
+
+`endif
--- /dev/null
+Subproject commit 84b3e3ca0ad9535acaef201c1482342871358b08
--- /dev/null
+from litex.soc.cores.cpu.mor1kx.core import MOR1KX
--- /dev/null
+import os
+
+from litex.gen import *
+
+from litex.soc.interconnect import wishbone
+
+
+class MOR1KX(Module):
+ def __init__(self, platform, reset_pc):
+ self.ibus = i = wishbone.Interface()
+ self.dbus = d = wishbone.Interface()
+ self.interrupt = Signal(32)
+
+ ###
+
+ i_adr_o = Signal(32)
+ d_adr_o = Signal(32)
+ self.specials += Instance("mor1kx",
+ p_FEATURE_INSTRUCTIONCACHE="ENABLED",
+ p_OPTION_ICACHE_BLOCK_WIDTH=4,
+ p_OPTION_ICACHE_SET_WIDTH=8,
+ p_OPTION_ICACHE_WAYS=1,
+ p_OPTION_ICACHE_LIMIT_WIDTH=31,
+ p_FEATURE_DATACACHE="ENABLED",
+ p_OPTION_DCACHE_BLOCK_WIDTH=4,
+ p_OPTION_DCACHE_SET_WIDTH=8,
+ p_OPTION_DCACHE_WAYS=1,
+ p_OPTION_DCACHE_LIMIT_WIDTH=31,
+ p_FEATURE_TIMER="NONE",
+ p_OPTION_PIC_TRIGGER="LEVEL",
+ p_FEATURE_SYSCALL="NONE",
+ p_FEATURE_TRAP="NONE",
+ p_FEATURE_RANGE="NONE",
+ p_FEATURE_OVERFLOW="NONE",
+ p_FEATURE_ADDC="ENABLED",
+ p_FEATURE_CMOV="ENABLED",
+ p_FEATURE_FFL1="ENABLED",
+ p_OPTION_CPU0="CAPPUCCINO",
+ p_OPTION_RESET_PC=reset_pc,
+ p_IBUS_WB_TYPE="B3_REGISTERED_FEEDBACK",
+ p_DBUS_WB_TYPE="B3_REGISTERED_FEEDBACK",
+
+ i_clk=ClockSignal(),
+ i_rst=ResetSignal(),
+
+ i_irq_i=self.interrupt,
+
+ o_iwbm_adr_o=i_adr_o,
+ o_iwbm_dat_o=i.dat_w,
+ o_iwbm_sel_o=i.sel,
+ o_iwbm_cyc_o=i.cyc,
+ o_iwbm_stb_o=i.stb,
+ o_iwbm_we_o=i.we,
+ o_iwbm_cti_o=i.cti,
+ o_iwbm_bte_o=i.bte,
+ i_iwbm_dat_i=i.dat_r,
+ i_iwbm_ack_i=i.ack,
+ i_iwbm_err_i=i.err,
+ i_iwbm_rty_i=0,
+
+ o_dwbm_adr_o=d_adr_o,
+ o_dwbm_dat_o=d.dat_w,
+ o_dwbm_sel_o=d.sel,
+ o_dwbm_cyc_o=d.cyc,
+ o_dwbm_stb_o=d.stb,
+ o_dwbm_we_o=d.we,
+ o_dwbm_cti_o=d.cti,
+ o_dwbm_bte_o=d.bte,
+ i_dwbm_dat_i=d.dat_r,
+ i_dwbm_ack_i=d.ack,
+ i_dwbm_err_i=d.err,
+ i_dwbm_rty_i=0)
+
+ self.comb += [
+ self.ibus.adr.eq(i_adr_o[2:]),
+ self.dbus.adr.eq(d_adr_o[2:])
+ ]
+
+ # add Verilog sources
+ vdir = os.path.join(
+ os.path.abspath(os.path.dirname(__file__)),
+ "verilog", "rtl", "verilog")
+ platform.add_source_dir(vdir)
--- /dev/null
+Subproject commit 69b97fcb43b35d6c6639ecc68e63d912c09ee8da
--- /dev/null
+from litex.gen import *
+from litex.gen.genlib.fsm import FSM, NextState
+
+from litex.soc.interconnect import wishbone
+
+
+class NorFlash16(Module):
+ def __init__(self, pads, rd_timing, wr_timing):
+ self.bus = wishbone.Interface()
+
+ ###
+
+ data = TSTriple(16)
+ lsb = Signal()
+
+ self.specials += data.get_tristate(pads.d)
+ self.comb += [
+ data.oe.eq(pads.oe_n),
+ pads.ce_n.eq(0)
+ ]
+
+ load_lo = Signal()
+ load_hi = Signal()
+ store = Signal()
+
+ pads.oe_n.reset, pads.we_n.reset = 1, 1
+ self.sync += [
+ pads.oe_n.eq(1),
+ pads.we_n.eq(1),
+
+ # Register data/address to avoid off-chip glitches
+ If(self.bus.cyc & self.bus.stb,
+ pads.adr.eq(Cat(lsb, self.bus.adr)),
+ If(self.bus.we,
+ # Only 16-bit writes are supported. Assume sel=0011 or 1100.
+ If(self.bus.sel[0],
+ data.o.eq(self.bus.dat_w[:16])
+ ).Else(
+ data.o.eq(self.bus.dat_w[16:])
+ )
+ ).Else(
+ pads.oe_n.eq(0)
+ )
+ ),
+
+ If(load_lo, self.bus.dat_r[:16].eq(data.i)),
+ If(load_hi, self.bus.dat_r[16:].eq(data.i)),
+ If(store, pads.we_n.eq(0))
+ ]
+
+ # Typical timing of the flash chips:
+ # - 110ns address to output
+ # - 50ns write pulse width
+ counter = Signal(max=max(rd_timing, wr_timing)+1)
+ counter_en = Signal()
+ counter_wr_mode = Signal()
+ counter_done = Signal()
+ self.comb += counter_done.eq(counter == Mux(counter_wr_mode, wr_timing, rd_timing))
+ self.sync += If(counter_en & ~counter_done,
+ counter.eq(counter + 1)
+ ).Else(
+ counter.eq(0)
+ )
+
+ fsm = FSM()
+ self.submodules += fsm
+
+ fsm.act("IDLE",
+ If(self.bus.cyc & self.bus.stb,
+ If(self.bus.we,
+ NextState("WR")
+ ).Else(
+ NextState("RD_HI")
+ )
+ )
+ )
+ fsm.act("RD_HI",
+ lsb.eq(0),
+ counter_en.eq(1),
+ If(counter_done,
+ load_hi.eq(1),
+ NextState("RD_LO")
+ )
+ )
+ fsm.act("RD_LO",
+ lsb.eq(1),
+ counter_en.eq(1),
+ If(counter_done,
+ load_lo.eq(1),
+ NextState("ACK")
+ )
+ )
+ fsm.act("WR",
+ # supported cases: sel=0011 [lsb=1] and sel=1100 [lsb=0]
+ lsb.eq(self.bus.sel[0]),
+ counter_wr_mode.eq(1),
+ counter_en.eq(1),
+ store.eq(1),
+ If(counter_done, NextState("ACK"))
+ )
+ fsm.act("ACK",
+ self.bus.ack.eq(1),
+ NextState("IDLE")
+ )
--- /dev/null
+from litex.gen import *
+from litex.gen.genlib.misc import timeline
+
+from litex.soc.interconnect import wishbone
+from litex.soc.interconnect.csr import AutoCSR, CSRStorage, CSRStatus
+
+
+_FAST_READ = 0x0b
+_DIOFR = 0xbb
+_QIOFR = 0xeb
+
+
+def _format_cmd(cmd, spi_width):
+ """
+ `cmd` is the read instruction. Since everything is transmitted on all
+ dq lines (cmd, adr and data), extend/interleave cmd to full pads.dq
+ width even if dq1-dq3 are don't care during the command phase:
+ For example, for N25Q128, 0xeb is the quad i/o fast read, and
+ extended to 4 bits (dq1,dq2,dq3 high) is: 0xfffefeff
+ """
+ c = 2**(8*spi_width)-1
+ for b in range(8):
+ if not (cmd>>b)%2:
+ c &= ~(1<<(b*spi_width))
+ return c
+
+
+class SpiFlash(Module, AutoCSR):
+ def __init__(self, pads, dummy=15, div=2, with_bitbang=True):
+ """
+ Simple SPI flash, e.g. N25Q128 on the LX9 Microboard.
+
+ Supports multi-bit pseudo-parallel reads (aka Dual or Quad I/O Fast
+ Read). Only supports mode0 (cpol=0, cpha=0).
+ Optionally supports software bitbanging (for write, erase, or other commands).
+ """
+ self.bus = bus = wishbone.Interface()
+ spi_width = len(pads.dq)
+ if with_bitbang:
+ self.bitbang = CSRStorage(4)
+ self.miso = CSRStatus()
+ self.bitbang_en = CSRStorage()
+
+ ###
+
+ cs_n = Signal(reset=1)
+ clk = Signal()
+ dq_oe = Signal()
+ wbone_width = len(bus.dat_r)
+
+
+ read_cmd_params = {
+ 4: (_format_cmd(_QIOFR, 4), 4*8),
+ 2: (_format_cmd(_DIOFR, 2), 2*8),
+ 1: (_format_cmd(_FAST_READ, 1), 1*8)
+ }
+ read_cmd, cmd_width = read_cmd_params[spi_width]
+ addr_width = 24
+
+ pads.cs_n.reset = 1
+
+ dq = TSTriple(spi_width)
+ self.specials.dq = dq.get_tristate(pads.dq)
+
+ sr = Signal(max(cmd_width, addr_width, wbone_width))
+ dqs = Replicate(1, spi_width-1)
+
+ self.comb += bus.dat_r.eq(sr)
+
+ hw_read_logic = [
+ pads.clk.eq(clk),
+ pads.cs_n.eq(cs_n),
+ dq.o.eq(sr[-spi_width:]),
+ dq.oe.eq(dq_oe)
+ ]
+
+ if with_bitbang:
+ bitbang_logic = [
+ pads.clk.eq(self.bitbang.storage[1]),
+ pads.cs_n.eq(self.bitbang.storage[2]),
+ dq.o.eq(Cat(self.bitbang.storage[0], dqs)),
+ If(self.bitbang.storage[3],
+ dq.oe.eq(0)
+ ).Else(
+ dq.oe.eq(1)
+ ),
+ If(self.bitbang.storage[1],
+ self.miso.status.eq(dq.i[1])
+ )
+ ]
+
+ self.comb += \
+ If(self.bitbang_en.storage,
+ bitbang_logic
+ ).Else(
+ hw_read_logic
+ )
+ else:
+ self.comb += hw_read_logic
+
+ if div < 2:
+ raise ValueError("Unsupported value \'{}\' for div parameter for SpiFlash core".format(div))
+ else:
+ i = Signal(max=div)
+ dqi = Signal(spi_width)
+ self.sync += [
+ If(i == div//2 - 1,
+ clk.eq(1),
+ dqi.eq(dq.i),
+ ),
+ If(i == div - 1,
+ i.eq(0),
+ clk.eq(0),
+ sr.eq(Cat(dqi, sr[:-spi_width]))
+ ).Else(
+ i.eq(i + 1),
+ ),
+ ]
+
+ # spi is byte-addressed, prefix by zeros
+ z = Replicate(0, log2_int(wbone_width//8))
+
+ seq = [
+ (cmd_width//spi_width*div,
+ [dq_oe.eq(1), cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]),
+ (addr_width//spi_width*div,
+ [sr[-addr_width:].eq(Cat(z, bus.adr))]),
+ ((dummy + wbone_width//spi_width)*div,
+ [dq_oe.eq(0)]),
+ (1,
+ [bus.ack.eq(1), cs_n.eq(1)]),
+ (div, # tSHSL!
+ [bus.ack.eq(0)]),
+ (0,
+ []),
+ ]
+
+ # accumulate timeline deltas
+ t, tseq = 0, []
+ for dt, a in seq:
+ tseq.append((t, a))
+ t += dt
+
+ self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq)
--- /dev/null
+from litex.gen import *
+from litex.gen.genlib.cdc import MultiReg
+
+from litex.soc.interconnect.csr import *
+
+
+class GPIOIn(Module, AutoCSR):
+ def __init__(self, signal):
+ self._in = CSRStatus(len(signal))
+ self.specials += MultiReg(signal, self._in.status)
+
+
+class GPIOOut(Module, AutoCSR):
+ def __init__(self, signal):
+ self._out = CSRStorage(len(signal))
+ self.comb += signal.eq(self._out.storage)
+
+
+class GPIOInOut(Module):
+ def __init__(self, in_signal, out_signal):
+ self.submodules.gpio_in = GPIOIn(in_signal)
+ self.submodules.gpio_out = GPIOOut(out_signal)
+
+ def get_csrs(self):
+ return self.gpio_in.get_csrs() + self.gpio_out.get_csrs()
+
+
+class Blinker(Module):
+ def __init__(self, signal, divbits=26):
+ counter = Signal(divbits)
+ self.comb += signal.eq(counter[divbits-1])
+ self.sync += counter.eq(counter + 1)
--- /dev/null
+from litex.gen import *
+
+from litex.soc.interconnect.csr import *
+
+
+class Identifier(Module, AutoCSR):
+ def __init__(self, sysid, frequency, revision=None):
+ self._sysid = CSRStatus(16)
+ self._frequency = CSRStatus(32)
+
+ ###
+
+ self.comb += [
+ self._sysid.status.eq(sysid),
+ self._frequency.status.eq(frequency)
+ ]
--- /dev/null
+from migen import *
+
+from litex.soc.interconnect import dfi
+from litex.soc.interconnect.csr import *
+
+
+class PhaseInjector(Module, AutoCSR):
+ def __init__(self, phase):
+ self._command = CSRStorage(6) # cs, we, cas, ras, wren, rden
+ self._command_issue = CSR()
+ self._address = CSRStorage(len(phase.address))
+ self._baddress = CSRStorage(len(phase.bank))
+ self._wrdata = CSRStorage(len(phase.wrdata))
+ self._rddata = CSRStatus(len(phase.rddata))
+
+ ###
+
+ self.comb += [
+ If(self._command_issue.re,
+ phase.cs_n.eq(~self._command.storage[0]),
+ phase.we_n.eq(~self._command.storage[1]),
+ phase.cas_n.eq(~self._command.storage[2]),
+ phase.ras_n.eq(~self._command.storage[3])
+ ).Else(
+ phase.cs_n.eq(1),
+ phase.we_n.eq(1),
+ phase.cas_n.eq(1),
+ phase.ras_n.eq(1)
+ ),
+ phase.address.eq(self._address.storage),
+ phase.bank.eq(self._baddress.storage),
+ phase.wrdata_en.eq(self._command_issue.re & self._command.storage[4]),
+ phase.rddata_en.eq(self._command_issue.re & self._command.storage[5]),
+ phase.wrdata.eq(self._wrdata.storage),
+ phase.wrdata_mask.eq(0)
+ ]
+ self.sync += If(phase.rddata_valid, self._rddata.status.eq(phase.rddata))
+
+
+class DFIInjector(Module, AutoCSR):
+ def __init__(self, addressbits, bankbits, databits, nphases=1):
+ inti = dfi.Interface(addressbits, bankbits, databits, nphases)
+ self.slave = dfi.Interface(addressbits, bankbits, databits, nphases)
+ self.master = dfi.Interface(addressbits, bankbits, databits, nphases)
+
+ self._control = CSRStorage(4) # sel, cke, odt, reset_n
+
+ for n, phase in enumerate(inti.phases):
+ setattr(self.submodules, "pi" + str(n), PhaseInjector(phase))
+
+ ###
+
+ self.comb += If(self._control.storage[0],
+ self.slave.connect(self.master)
+ ).Else(
+ inti.connect(self.master)
+ )
+ self.comb += [phase.cke.eq(self._control.storage[1]) for phase in inti.phases]
+ self.comb += [phase.odt.eq(self._control.storage[2]) for phase in inti.phases if hasattr(phase, "odt")]
+ self.comb += [phase.reset_n.eq(self._control.storage[3]) for phase in inti.phases if hasattr(phase, "reset_n")]
--- /dev/null
+from litex.soc.cores.sdram.lasmicon.core import ControllerSettings, LASMIcon
--- /dev/null
+from litex.gen import *
+from litex.gen.genlib.roundrobin import *
+from litex.gen.genlib.fsm import FSM, NextState
+from litex.gen.genlib.fifo import SyncFIFO
+
+from litex.soc.cores.sdram.lasmicon.multiplexer import *
+
+
+class _AddressSlicer:
+ def __init__(self, colbits, address_align):
+ self.colbits = colbits
+ self.address_align = address_align
+
+ def row(self, address):
+ split = self.colbits - self.address_align
+ if isinstance(address, int):
+ return address >> split
+ else:
+ return address[split:]
+
+ def col(self, address):
+ split = self.colbits - self.address_align
+ if isinstance(address, int):
+ return (address & (2**split - 1)) << self.address_align
+ else:
+ return Cat(Replicate(0, self.address_align), address[:split])
+
+
+class BankMachine(Module):
+ def __init__(self, geom_settings, timing_settings, controller_settings, address_align, bankn, req):
+ self.refresh_req = Signal()
+ self.refresh_gnt = Signal()
+ self.cmd = CommandRequestRW(geom_settings.addressbits, geom_settings.bankbits)
+
+ ###
+
+ # Request FIFO
+ layout = [("we", 1), ("adr", len(req.adr))]
+ req_in = Record(layout)
+ reqf = Record(layout)
+ self.submodules.req_fifo = SyncFIFO(layout_len(layout),
+ controller_settings.req_queue_size)
+ self.comb += [
+ self.req_fifo.din.eq(req_in.raw_bits()),
+ reqf.raw_bits().eq(self.req_fifo.dout)
+ ]
+ self.comb += [
+ req_in.we.eq(req.we),
+ req_in.adr.eq(req.adr),
+ self.req_fifo.we.eq(req.stb),
+ req.req_ack.eq(self.req_fifo.writable),
+
+ self.req_fifo.re.eq(req.dat_w_ack | req.dat_r_ack),
+ req.lock.eq(self.req_fifo.readable)
+ ]
+
+ slicer = _AddressSlicer(geom_settings.colbits, address_align)
+
+ # Row tracking
+ has_openrow = Signal()
+ openrow = Signal(geom_settings.rowbits)
+ hit = Signal()
+ self.comb += hit.eq(openrow == slicer.row(reqf.adr))
+ track_open = Signal()
+ track_close = Signal()
+ self.sync += [
+ If(track_open,
+ has_openrow.eq(1),
+ openrow.eq(slicer.row(reqf.adr))
+ ),
+ If(track_close,
+ has_openrow.eq(0)
+ )
+ ]
+
+ # Address generation
+ s_row_adr = Signal()
+ self.comb += [
+ self.cmd.ba.eq(bankn),
+ If(s_row_adr,
+ self.cmd.a.eq(slicer.row(reqf.adr))
+ ).Else(
+ self.cmd.a.eq(slicer.col(reqf.adr))
+ )
+ ]
+
+ # Respect write-to-precharge specification
+ precharge_ok = Signal()
+ t_unsafe_precharge = 2 + timing_settings.tWR - 1
+ unsafe_precharge_count = Signal(max=t_unsafe_precharge+1)
+ self.comb += precharge_ok.eq(unsafe_precharge_count == 0)
+ self.sync += [
+ If(self.cmd.stb & self.cmd.ack & self.cmd.is_write,
+ unsafe_precharge_count.eq(t_unsafe_precharge)
+ ).Elif(~precharge_ok,
+ unsafe_precharge_count.eq(unsafe_precharge_count-1)
+ )
+ ]
+
+ # Control and command generation FSM
+ fsm = FSM()
+ self.submodules += fsm
+ fsm.act("REGULAR",
+ If(self.refresh_req,
+ NextState("REFRESH")
+ ).Elif(self.req_fifo.readable,
+ If(has_openrow,
+ If(hit,
+ # NB: write-to-read specification is enforced by multiplexer
+ self.cmd.stb.eq(1),
+ req.dat_w_ack.eq(self.cmd.ack & reqf.we),
+ req.dat_r_ack.eq(self.cmd.ack & ~reqf.we),
+ self.cmd.is_read.eq(~reqf.we),
+ self.cmd.is_write.eq(reqf.we),
+ self.cmd.cas_n.eq(0),
+ self.cmd.we_n.eq(~reqf.we)
+ ).Else(
+ NextState("PRECHARGE")
+ )
+ ).Else(
+ NextState("ACTIVATE")
+ )
+ )
+ )
+ fsm.act("PRECHARGE",
+ # Notes:
+ # 1. we are presenting the column address, A10 is always low
+ # 2. since we always go to the ACTIVATE state, we do not need
+ # to assert track_close.
+ If(precharge_ok,
+ self.cmd.stb.eq(1),
+ If(self.cmd.ack, NextState("TRP")),
+ self.cmd.ras_n.eq(0),
+ self.cmd.we_n.eq(0),
+ self.cmd.is_cmd.eq(1)
+ )
+ )
+ fsm.act("ACTIVATE",
+ s_row_adr.eq(1),
+ track_open.eq(1),
+ self.cmd.stb.eq(1),
+ self.cmd.is_cmd.eq(1),
+ If(self.cmd.ack, NextState("TRCD")),
+ self.cmd.ras_n.eq(0)
+ )
+ fsm.act("REFRESH",
+ self.refresh_gnt.eq(precharge_ok),
+ track_close.eq(1),
+ self.cmd.is_cmd.eq(1),
+ If(~self.refresh_req, NextState("REGULAR"))
+ )
+ fsm.delayed_enter("TRP", "ACTIVATE", timing_settings.tRP-1)
+ fsm.delayed_enter("TRCD", "REGULAR", timing_settings.tRCD-1)
--- /dev/null
+from litex.gen import *
+
+from litex.soc.interconnect import dfi, lasmi_bus
+from litex.soc.cores.sdram.lasmicon.refresher import *
+from litex.soc.cores.sdram.lasmicon.bankmachine import *
+from litex.soc.cores.sdram.lasmicon.multiplexer import *
+
+
+class ControllerSettings:
+ def __init__(self, req_queue_size=8, read_time=32, write_time=16, with_bandwidth=False):
+ self.req_queue_size = req_queue_size
+ self.read_time = read_time
+ self.write_time = write_time
+ self.with_bandwidth = with_bandwidth
+
+
+class LASMIcon(Module):
+ def __init__(self, phy_settings, geom_settings, timing_settings,
+ controller_settings=None):
+ if controller_settings is None:
+ controller_settings = ControllerSettings()
+ if phy_settings.memtype in ["SDR"]:
+ burst_length = phy_settings.nphases*1 # command multiplication*SDR
+ elif phy_settings.memtype in ["DDR", "LPDDR", "DDR2", "DDR3"]:
+ burst_length = phy_settings.nphases*2 # command multiplication*DDR
+ address_align = log2_int(burst_length)
+
+ self.dfi = dfi.Interface(geom_settings.addressbits,
+ geom_settings.bankbits,
+ phy_settings.dfi_databits,
+ phy_settings.nphases)
+ self.lasmic = lasmi_bus.Interface(
+ aw=geom_settings.rowbits + geom_settings.colbits - address_align,
+ dw=phy_settings.dfi_databits*phy_settings.nphases,
+ nbanks=2**geom_settings.bankbits,
+ req_queue_size=controller_settings.req_queue_size,
+ read_latency=phy_settings.read_latency+1,
+ write_latency=phy_settings.write_latency+1)
+ self.nrowbits = geom_settings.colbits - address_align
+
+ ###
+
+ self.submodules.refresher = Refresher(geom_settings.addressbits, geom_settings.bankbits,
+ timing_settings.tRP, timing_settings.tREFI, timing_settings.tRFC)
+ self.submodules.bank_machines = [BankMachine(geom_settings, timing_settings, controller_settings, address_align, i,
+ getattr(self.lasmic, "bank"+str(i)))
+ for i in range(2**geom_settings.bankbits)]
+ self.submodules.multiplexer = Multiplexer(phy_settings, geom_settings, timing_settings, controller_settings,
+ self.bank_machines, self.refresher,
+ self.dfi, self.lasmic)
+
+ def get_csrs(self):
+ return self.multiplexer.get_csrs()
--- /dev/null
+from functools import reduce
+from operator import or_, and_
+
+from litex.gen import *
+from litex.gen.genlib.roundrobin import *
+from litex.gen.genlib.fsm import FSM, NextState
+
+from litex.soc.cores.sdram.lasmicon.perf import Bandwidth
+from litex.soc.interconnect.csr import AutoCSR
+
+
+class CommandRequest:
+ def __init__(self, a, ba):
+ self.a = Signal(a)
+ self.ba = Signal(ba)
+ self.cas_n = Signal(reset=1)
+ self.ras_n = Signal(reset=1)
+ self.we_n = Signal(reset=1)
+
+
+class CommandRequestRW(CommandRequest):
+ def __init__(self, a, ba):
+ CommandRequest.__init__(self, a, ba)
+ self.stb = Signal()
+ self.ack = Signal()
+ self.is_cmd = Signal()
+ self.is_read = Signal()
+ self.is_write = Signal()
+
+
+class _CommandChooser(Module):
+ def __init__(self, requests):
+ self.want_reads = Signal()
+ self.want_writes = Signal()
+ self.want_cmds = Signal()
+ # NB: cas_n/ras_n/we_n are 1 when stb is inactive
+ self.cmd = CommandRequestRW(len(requests[0].a), len(requests[0].ba))
+
+ ###
+
+ rr = RoundRobin(len(requests), SP_CE)
+ self.submodules += rr
+
+ self.comb += [rr.request[i].eq(req.stb & ((req.is_cmd & self.want_cmds) | ((req.is_read == self.want_reads) | (req.is_write == self.want_writes))))
+ for i, req in enumerate(requests)]
+
+ stb = Signal()
+ self.comb += stb.eq(Array(req.stb for req in requests)[rr.grant])
+ for name in ["a", "ba", "is_read", "is_write", "is_cmd"]:
+ choices = Array(getattr(req, name) for req in requests)
+ self.comb += getattr(self.cmd, name).eq(choices[rr.grant])
+ for name in ["cas_n", "ras_n", "we_n"]:
+ # we should only assert those signals when stb is 1
+ choices = Array(getattr(req, name) for req in requests)
+ self.comb += If(self.cmd.stb, getattr(self.cmd, name).eq(choices[rr.grant]))
+ self.comb += self.cmd.stb.eq(stb \
+ & ((self.cmd.is_cmd & self.want_cmds) | ((self.cmd.is_read == self.want_reads) \
+ & (self.cmd.is_write == self.want_writes))))
+
+ self.comb += [If(self.cmd.stb & self.cmd.ack & (rr.grant == i), req.ack.eq(1))
+ for i, req in enumerate(requests)]
+ self.comb += rr.ce.eq(self.cmd.ack)
+
+
+class _Steerer(Module):
+ def __init__(self, commands, dfi):
+ ncmd = len(commands)
+ nph = len(dfi.phases)
+ self.sel = [Signal(max=ncmd) for i in range(nph)]
+
+ ###
+
+ def stb_and(cmd, attr):
+ if not hasattr(cmd, "stb"):
+ return 0
+ else:
+ return cmd.stb & getattr(cmd, attr)
+ for phase, sel in zip(dfi.phases, self.sel):
+ self.comb += [
+ phase.cke.eq(1),
+ phase.cs_n.eq(0)
+ ]
+ if hasattr(phase, "odt"):
+ self.comb += phase.odt.eq(1)
+ if hasattr(phase, "reset_n"):
+ self.comb += phase.reset_n.eq(1)
+ self.sync += [
+ phase.address.eq(Array(cmd.a for cmd in commands)[sel]),
+ phase.bank.eq(Array(cmd.ba for cmd in commands)[sel]),
+ phase.cas_n.eq(Array(cmd.cas_n for cmd in commands)[sel]),
+ phase.ras_n.eq(Array(cmd.ras_n for cmd in commands)[sel]),
+ phase.we_n.eq(Array(cmd.we_n for cmd in commands)[sel]),
+ phase.rddata_en.eq(Array(stb_and(cmd, "is_read") for cmd in commands)[sel]),
+ phase.wrdata_en.eq(Array(stb_and(cmd, "is_write") for cmd in commands)[sel])
+ ]
+
+
+class Multiplexer(Module, AutoCSR):
+ def __init__(self, phy_settings, geom_settings, timing_settings, controller_settings, bank_machines, refresher, dfi, lasmic,
+ with_bandwidth=False):
+ assert(phy_settings.nphases == len(dfi.phases))
+ self.phy_settings = phy_settings
+
+ # Command choosing
+ requests = [bm.cmd for bm in bank_machines]
+ self.submodules.choose_cmd = choose_cmd = _CommandChooser(requests)
+ self.submodules.choose_req = choose_req = _CommandChooser(requests)
+ self.comb += [
+ choose_cmd.want_reads.eq(0),
+ choose_cmd.want_writes.eq(0)
+ ]
+ if phy_settings.nphases == 1:
+ self.comb += [
+ choose_cmd.want_cmds.eq(1),
+ choose_req.want_cmds.eq(1)
+ ]
+
+ # Command steering
+ nop = CommandRequest(geom_settings.addressbits, geom_settings.bankbits)
+ commands = [nop, choose_cmd.cmd, choose_req.cmd, refresher.cmd] # nop must be 1st
+ (STEER_NOP, STEER_CMD, STEER_REQ, STEER_REFRESH) = range(4)
+ steerer = _Steerer(commands, dfi)
+ self.submodules += steerer
+
+ # Read/write turnaround
+ read_available = Signal()
+ write_available = Signal()
+ self.comb += [
+ read_available.eq(reduce(or_, [req.stb & req.is_read for req in requests])),
+ write_available.eq(reduce(or_, [req.stb & req.is_write for req in requests]))
+ ]
+
+ def anti_starvation(timeout):
+ en = Signal()
+ max_time = Signal()
+ if timeout:
+ t = timeout - 1
+ time = Signal(max=t+1)
+ self.comb += max_time.eq(time == 0)
+ self.sync += If(~en,
+ time.eq(t)
+ ).Elif(~max_time,
+ time.eq(time - 1)
+ )
+ else:
+ self.comb += max_time.eq(0)
+ return en, max_time
+ read_time_en, max_read_time = anti_starvation(controller_settings.read_time)
+ write_time_en, max_write_time = anti_starvation(controller_settings.write_time)
+
+ # Refresh
+ self.comb += [bm.refresh_req.eq(refresher.req) for bm in bank_machines]
+ go_to_refresh = Signal()
+ self.comb += go_to_refresh.eq(reduce(and_, [bm.refresh_gnt for bm in bank_machines]))
+
+ # Datapath
+ all_rddata = [p.rddata for p in dfi.phases]
+ all_wrdata = [p.wrdata for p in dfi.phases]
+ all_wrdata_mask = [p.wrdata_mask for p in dfi.phases]
+ self.comb += [
+ lasmic.dat_r.eq(Cat(*all_rddata)),
+ Cat(*all_wrdata).eq(lasmic.dat_w),
+ Cat(*all_wrdata_mask).eq(~lasmic.dat_we)
+ ]
+
+ # Control FSM
+ fsm = FSM()
+ self.submodules += fsm
+
+ def steerer_sel(steerer, phy_settings, r_w_n):
+ r = []
+ for i in range(phy_settings.nphases):
+ s = steerer.sel[i].eq(STEER_NOP)
+ if r_w_n == "read":
+ if i == phy_settings.rdphase:
+ s = steerer.sel[i].eq(STEER_REQ)
+ elif i == phy_settings.rdcmdphase:
+ s = steerer.sel[i].eq(STEER_CMD)
+ elif r_w_n == "write":
+ if i == phy_settings.wrphase:
+ s = steerer.sel[i].eq(STEER_REQ)
+ elif i == phy_settings.wrcmdphase:
+ s = steerer.sel[i].eq(STEER_CMD)
+ else:
+ raise ValueError
+ r.append(s)
+ return r
+
+ fsm.act("READ",
+ read_time_en.eq(1),
+ choose_req.want_reads.eq(1),
+ choose_cmd.cmd.ack.eq(1),
+ choose_req.cmd.ack.eq(1),
+ steerer_sel(steerer, phy_settings, "read"),
+ If(write_available,
+ # TODO: switch only after several cycles of ~read_available?
+ If(~read_available | max_read_time, NextState("RTW"))
+ ),
+ If(go_to_refresh, NextState("REFRESH"))
+ )
+ fsm.act("WRITE",
+ write_time_en.eq(1),
+ choose_req.want_writes.eq(1),
+ choose_cmd.cmd.ack.eq(1),
+ choose_req.cmd.ack.eq(1),
+ steerer_sel(steerer, phy_settings, "write"),
+ If(read_available,
+ If(~write_available | max_write_time, NextState("WTR"))
+ ),
+ If(go_to_refresh, NextState("REFRESH"))
+ )
+ fsm.act("REFRESH",
+ steerer.sel[0].eq(STEER_REFRESH),
+ refresher.ack.eq(1),
+ If(~refresher.req, NextState("READ"))
+ )
+ fsm.delayed_enter("RTW", "WRITE", phy_settings.read_latency-1) # FIXME: reduce this, actual limit is around (cl+1)/nphases
+ fsm.delayed_enter("WTR", "READ", timing_settings.tWTR-1)
+
+ if controller_settings.with_bandwidth:
+ data_width = phy_settings.dfi_databits*phy_settings.nphases
+ self.submodules.bandwidth = Bandwidth(self.choose_req.cmd, data_width)
--- /dev/null
+from litex.gen import *
+
+from litex.soc.interconnect.csr import *
+
+
+class Bandwidth(Module, AutoCSR):
+ def __init__(self, cmd, data_width, period_bits=24):
+ self._update = CSR()
+ self._nreads = CSRStatus(period_bits)
+ self._nwrites = CSRStatus(period_bits)
+ self._data_width = CSRStatus(bits_for(data_width), reset=data_width)
+
+ ###
+
+ cmd_stb = Signal()
+ cmd_ack = Signal()
+ cmd_is_read = Signal()
+ cmd_is_write = Signal()
+ self.sync += [
+ cmd_stb.eq(cmd.stb),
+ cmd_ack.eq(cmd.ack),
+ cmd_is_read.eq(cmd.is_read),
+ cmd_is_write.eq(cmd.is_write)
+ ]
+
+ counter = Signal(period_bits)
+ period = Signal()
+ nreads = Signal(period_bits)
+ nwrites = Signal(period_bits)
+ nreads_r = Signal(period_bits)
+ nwrites_r = Signal(period_bits)
+ self.sync += [
+ Cat(counter, period).eq(counter + 1),
+ If(period,
+ nreads_r.eq(nreads),
+ nwrites_r.eq(nwrites),
+ nreads.eq(0),
+ nwrites.eq(0)
+ ).Elif(cmd_stb & cmd_ack,
+ If(cmd_is_read, nreads.eq(nreads + 1)),
+ If(cmd_is_write, nwrites.eq(nwrites + 1)),
+ ),
+ If(self._update.re,
+ self._nreads.status.eq(nreads_r),
+ self._nwrites.status.eq(nwrites_r)
+ )
+ ]
--- /dev/null
+from litex.gen import *
+from litex.gen.genlib.misc import timeline
+from litex.gen.genlib.fsm import FSM
+
+from litex.soc.cores.sdram.lasmicon.multiplexer import *
+
+
+class Refresher(Module):
+ def __init__(self, a, ba, tRP, tREFI, tRFC):
+ self.req = Signal()
+ self.ack = Signal() # 1st command 1 cycle after assertion of ack
+ self.cmd = CommandRequest(a, ba)
+
+ ###
+
+ # Refresh sequence generator:
+ # PRECHARGE ALL --(tRP)--> AUTO REFRESH --(tRFC)--> done
+ seq_start = Signal()
+ seq_done = Signal()
+ self.sync += [
+ self.cmd.a.eq(2**10),
+ self.cmd.ba.eq(0),
+ self.cmd.cas_n.eq(1),
+ self.cmd.ras_n.eq(1),
+ self.cmd.we_n.eq(1),
+ seq_done.eq(0)
+ ]
+ self.sync += timeline(seq_start, [
+ (1, [
+ self.cmd.ras_n.eq(0),
+ self.cmd.we_n.eq(0)
+ ]),
+ (1+tRP, [
+ self.cmd.cas_n.eq(0),
+ self.cmd.ras_n.eq(0)
+ ]),
+ (1+tRP+tRFC, [
+ seq_done.eq(1)
+ ])
+ ])
+
+ # Periodic refresh counter
+ counter = Signal(max=tREFI)
+ start = Signal()
+ self.sync += [
+ start.eq(0),
+ If(counter == 0,
+ start.eq(1),
+ counter.eq(tREFI - 1)
+ ).Else(
+ counter.eq(counter - 1)
+ )
+ ]
+
+ # Control FSM
+ fsm = FSM()
+ self.submodules += fsm
+ fsm.act("IDLE", If(start, NextState("WAIT_GRANT")))
+ fsm.act("WAIT_GRANT",
+ self.req.eq(1),
+ If(self.ack,
+ seq_start.eq(1),
+ NextState("WAIT_SEQ")
+ )
+ )
+ fsm.act("WAIT_SEQ",
+ self.req.eq(1),
+ If(seq_done, NextState("IDLE"))
+ )
--- /dev/null
+from litex.soc.cores.sdram.minicon.core import Minicon
--- /dev/null
+from functools import reduce
+from operator import or_
+
+from litex.gen import *
+from litex.gen.genlib.fsm import FSM, NextState
+from litex.gen.genlib.misc import WaitTimer
+
+from litex.soc.interconnect import dfi as dfibus
+from litex.soc.interconnect import wishbone
+
+
+class _AddressSlicer:
+ def __init__(self, colbits, bankbits, rowbits, address_align):
+ self.colbits = colbits
+ self.bankbits = bankbits
+ self.rowbits = rowbits
+ self.address_align = address_align
+ self.addressbits = colbits - address_align + bankbits + rowbits
+
+ def row(self, address):
+ split = self.bankbits + self.colbits - self.address_align
+ if isinstance(address, int):
+ return address >> split
+ else:
+ return address[split:self.addressbits]
+
+ def bank(self, address):
+ split = self.colbits - self.address_align
+ if isinstance(address, int):
+ return (address & (2**(split + self.bankbits) - 1)) >> split
+ else:
+ return address[split:split+self.bankbits]
+
+ def col(self, address):
+ split = self.colbits - self.address_align
+ if isinstance(address, int):
+ return (address & (2**split - 1)) << self.address_align
+ else:
+ return Cat(Replicate(0, self.address_align), address[:split])
+
+
+@ResetInserter()
+@CEInserter()
+class _Bank(Module):
+ def __init__(self, geom_settings):
+ self.open = Signal()
+ self.row = Signal(geom_settings.rowbits)
+
+ self.idle = Signal(reset=1)
+ self.hit = Signal()
+
+ # # #
+
+ row = Signal(geom_settings.rowbits)
+ self.sync += \
+ If(self.open,
+ self.idle.eq(0),
+ row.eq(self.row)
+ )
+ self.comb += self.hit.eq(~self.idle & (self.row == row))
+
+
+class Minicon(Module):
+ def __init__(self, phy_settings, geom_settings, timing_settings):
+ if phy_settings.memtype in ["SDR"]:
+ burst_length = phy_settings.nphases*1 # command multiplication*SDR
+ elif phy_settings.memtype in ["DDR", "LPDDR", "DDR2", "DDR3"]:
+ burst_length = phy_settings.nphases*2 # command multiplication*DDR
+ burst_width = phy_settings.dfi_databits*phy_settings.nphases
+ address_align = log2_int(burst_length)
+
+ # # #
+
+ self.dfi = dfi = dfibus.Interface(geom_settings.addressbits,
+ geom_settings.bankbits,
+ phy_settings.dfi_databits,
+ phy_settings.nphases)
+
+ self.bus = bus = wishbone.Interface(burst_width)
+
+ rdphase = phy_settings.rdphase
+ wrphase = phy_settings.wrphase
+
+ precharge_all = Signal()
+ activate = Signal()
+ refresh = Signal()
+ write = Signal()
+ read = Signal()
+
+ # Compute current column, bank and row from wishbone address
+ slicer = _AddressSlicer(geom_settings.colbits,
+ geom_settings.bankbits,
+ geom_settings.rowbits,
+ address_align)
+
+ # Manage banks
+ bank_idle = Signal()
+ bank_hit = Signal()
+
+ banks = []
+ for i in range(2**geom_settings.bankbits):
+ bank = _Bank(geom_settings)
+ self.comb += [
+ bank.open.eq(activate),
+ bank.reset.eq(precharge_all),
+ bank.row.eq(slicer.row(bus.adr))
+ ]
+ banks.append(bank)
+ self.submodules += banks
+
+ cases = {}
+ for i, bank in enumerate(banks):
+ cases[i] = [bank.ce.eq(1)]
+ self.comb += Case(slicer.bank(bus.adr), cases)
+
+ self.comb += [
+ bank_hit.eq(reduce(or_, [bank.hit & bank.ce for bank in banks])),
+ bank_idle.eq(reduce(or_, [bank.idle & bank.ce for bank in banks])),
+ ]
+
+ # Timings
+ write2precharge_timer = WaitTimer(2 + timing_settings.tWR - 1)
+ self.submodules += write2precharge_timer
+ self.comb += write2precharge_timer.wait.eq(~write)
+
+ refresh_timer = WaitTimer(timing_settings.tREFI)
+ self.submodules += refresh_timer
+ self.comb += refresh_timer.wait.eq(~refresh)
+
+ # Main FSM
+ self.submodules.fsm = fsm = FSM()
+ fsm.act("IDLE",
+ If(refresh_timer.done,
+ NextState("PRECHARGE-ALL")
+ ).Elif(bus.stb & bus.cyc,
+ If(bank_hit,
+ If(bus.we,
+ NextState("WRITE")
+ ).Else(
+ NextState("READ")
+ )
+ ).Elif(~bank_idle,
+ If(write2precharge_timer.done,
+ NextState("PRECHARGE")
+ )
+ ).Else(
+ NextState("ACTIVATE")
+ )
+ )
+ )
+ fsm.act("READ",
+ read.eq(1),
+ dfi.phases[rdphase].ras_n.eq(1),
+ dfi.phases[rdphase].cas_n.eq(0),
+ dfi.phases[rdphase].we_n.eq(1),
+ dfi.phases[rdphase].rddata_en.eq(1),
+ NextState("WAIT-READ-DONE"),
+ )
+ fsm.act("WAIT-READ-DONE",
+ If(dfi.phases[rdphase].rddata_valid,
+ bus.ack.eq(1),
+ NextState("IDLE")
+ )
+ )
+ fsm.act("WRITE",
+ write.eq(1),
+ dfi.phases[wrphase].ras_n.eq(1),
+ dfi.phases[wrphase].cas_n.eq(0),
+ dfi.phases[wrphase].we_n.eq(0),
+ dfi.phases[wrphase].wrdata_en.eq(1),
+ NextState("WRITE-LATENCY")
+ )
+ fsm.act("WRITE-ACK",
+ bus.ack.eq(1),
+ NextState("IDLE")
+ )
+ fsm.act("PRECHARGE-ALL",
+ precharge_all.eq(1),
+ dfi.phases[rdphase].ras_n.eq(0),
+ dfi.phases[rdphase].cas_n.eq(1),
+ dfi.phases[rdphase].we_n.eq(0),
+ NextState("PRE-REFRESH")
+ )
+ fsm.act("PRECHARGE",
+ # do no reset bank since we are going to re-open it
+ dfi.phases[0].ras_n.eq(0),
+ dfi.phases[0].cas_n.eq(1),
+ dfi.phases[0].we_n.eq(0),
+ NextState("TRP")
+ )
+ fsm.act("ACTIVATE",
+ activate.eq(1),
+ dfi.phases[0].ras_n.eq(0),
+ dfi.phases[0].cas_n.eq(1),
+ dfi.phases[0].we_n.eq(1),
+ NextState("TRCD"),
+ )
+ fsm.act("REFRESH",
+ refresh.eq(1),
+ dfi.phases[rdphase].ras_n.eq(0),
+ dfi.phases[rdphase].cas_n.eq(0),
+ dfi.phases[rdphase].we_n.eq(1),
+ NextState("POST-REFRESH")
+ )
+ fsm.delayed_enter("WRITE-LATENCY", "WRITE-ACK", phy_settings.write_latency-1)
+ fsm.delayed_enter("TRP", "ACTIVATE", timing_settings.tRP-1)
+ fsm.delayed_enter("TRCD", "IDLE", timing_settings.tRCD-1)
+ fsm.delayed_enter("PRE-REFRESH", "REFRESH", timing_settings.tRP-1)
+ fsm.delayed_enter("POST-REFRESH", "IDLE", timing_settings.tRFC-1)
+
+ # DFI commands
+ for phase in dfi.phases:
+ if hasattr(phase, "reset_n"):
+ self.comb += phase.reset_n.eq(1)
+ if hasattr(phase, "odt"):
+ self.comb += phase.odt.eq(1)
+ self.comb += [
+ phase.cke.eq(1),
+ phase.cs_n.eq(0),
+ phase.bank.eq(slicer.bank(bus.adr)),
+ If(precharge_all,
+ phase.address.eq(2**10)
+ ).Elif(activate,
+ phase.address.eq(slicer.row(bus.adr))
+ ).Elif(write | read,
+ phase.address.eq(slicer.col(bus.adr))
+ )
+ ]
+
+ # DFI datapath
+ self.comb += [
+ bus.dat_r.eq(Cat(phase.rddata for phase in dfi.phases)),
+ Cat(phase.wrdata for phase in dfi.phases).eq(bus.dat_w),
+ Cat(phase.wrdata_mask for phase in dfi.phases).eq(~bus.sel),
+ ]
--- /dev/null
+# This file is Copyright (c) 2015 Florent Kermarrec <florent@enjoy-digital.fr>
+# License: BSD
+
+# SDRAM simulation PHY at DFI level
+# tested with SDR/DDR/DDR2/LPDDR/DDR3
+# TODO:
+# - add $display support to LiteX gen and manage timing violations?
+
+from litex.gen import *
+from litex.gen.fhdl.specials import *
+from litex.soc.mem.sdram.phy.dfi import *
+from litex.soc.mem import sdram
+
+
+class Bank(Module):
+ def __init__(self, data_width, nrows, ncols, burst_length):
+ self.activate = Signal()
+ self.activate_row = Signal(max=nrows)
+ self.precharge = Signal()
+
+ self.write = Signal()
+ self.write_col = Signal(max=ncols)
+ self.write_data = Signal(data_width)
+ self.write_mask = Signal(data_width//8)
+
+ self.read = Signal()
+ self.read_col = Signal(max=ncols)
+ self.read_data = Signal(data_width)
+
+ ###
+ active = Signal()
+ row = Signal(max=nrows)
+
+ self.sync += \
+ If(self.precharge,
+ active.eq(0),
+ ).Elif(self.activate,
+ active.eq(1),
+ row.eq(self.activate_row)
+ )
+
+ self.specials.mem = mem = Memory(data_width, nrows*ncols//burst_length)
+ self.specials.write_port = write_port = mem.get_port(write_capable=True,
+ we_granularity=8)
+ self.specials.read_port = read_port = mem.get_port(async_read=True)
+ self.comb += [
+ If(active,
+ write_port.adr.eq(row*ncols | self.write_col),
+ write_port.dat_w.eq(self.write_data),
+ write_port.we.eq(Replicate(self.write, data_width//8) & ~self.write_mask),
+ If(self.read,
+ read_port.adr.eq(row*ncols | self.read_col),
+ self.read_data.eq(read_port.dat_r)
+ )
+ )
+ ]
+
+
+class DFIPhase(Module):
+ def __init__(self, dfi, n):
+ phase = getattr(dfi, "p"+str(n))
+
+ self.bank = phase.bank
+ self.address = phase.address
+
+ self.wrdata = phase.wrdata
+ self.wrdata_mask = phase.wrdata_mask
+
+ self.rddata = phase.rddata
+ self.rddata_valid = phase.rddata_valid
+
+ self.activate = Signal()
+ self.precharge = Signal()
+ self.write = Signal()
+ self.read = Signal()
+
+ ###
+ self.comb += [
+ If(~phase.cs_n & ~phase.ras_n & phase.cas_n,
+ self.activate.eq(phase.we_n),
+ self.precharge.eq(~phase.we_n)
+ ),
+ If(~phase.cs_n & phase.ras_n & ~phase.cas_n,
+ self.write.eq(~phase.we_n),
+ self.read.eq(phase.we_n)
+ )
+ ]
+
+
+class SDRAMPHYSim(Module):
+ def __init__(self, module, settings):
+ if settings.memtype in ["SDR"]:
+ burst_length = settings.nphases*1 # command multiplication*SDR
+ elif settings.memtype in ["DDR", "LPDDR", "DDR2", "DDR3"]:
+ burst_length = settings.nphases*2 # command multiplication*DDR
+
+ addressbits = module.geom_settings.addressbits
+ bankbits = module.geom_settings.bankbits
+ rowbits = module.geom_settings.rowbits
+ colbits = module.geom_settings.colbits
+
+ self.settings = settings
+ self.module = module
+
+ self.dfi = Interface(addressbits, bankbits, self.settings.dfi_databits, self.settings.nphases)
+
+ ###
+ nbanks = 2**bankbits
+ nrows = 2**rowbits
+ ncols = 2**colbits
+ data_width = self.settings.dfi_databits*self.settings.nphases
+
+ # DFI phases
+ phases = [DFIPhase(self.dfi, n) for n in range(self.settings.nphases)]
+ self.submodules += phases
+
+ # banks
+ banks = [Bank(data_width, nrows, ncols, burst_length) for i in range(nbanks)]
+ self.submodules += banks
+
+ # connect DFI phases to banks (cmds, write datapath)
+ for nb, bank in enumerate(banks):
+ # bank activate
+ activates = Signal(len(phases))
+ cases = {}
+ for np, phase in enumerate(phases):
+ self.comb += activates[np].eq(phase.activate)
+ cases[2**np] = [
+ bank.activate.eq(phase.bank == nb),
+ bank.activate_row.eq(phase.address)
+ ]
+ self.comb += Case(activates, cases)
+
+ # bank precharge
+ precharges = Signal(len(phases))
+ cases = {}
+ for np, phase in enumerate(phases):
+ self.comb += precharges[np].eq(phase.precharge)
+ cases[2**np] = [
+ bank.precharge.eq((phase.bank == nb) | phase.address[10])
+ ]
+ self.comb += Case(precharges, cases)
+
+ # bank writes
+ writes = Signal(len(phases))
+ cases = {}
+ for np, phase in enumerate(phases):
+ self.comb += writes[np].eq(phase.write)
+ cases[2**np] = [
+ bank.write.eq(phase.bank == nb),
+ bank.write_col.eq(phase.address)
+ ]
+ self.comb += Case(writes, cases)
+ self.comb += [
+ bank.write_data.eq(Cat(*[phase.wrdata for phase in phases])),
+ bank.write_mask.eq(Cat(*[phase.wrdata_mask for phase in phases]))
+ ]
+
+ # bank reads
+ reads = Signal(len(phases))
+ cases = {}
+ for np, phase in enumerate(phases):
+ self.comb += reads[np].eq(phase.read)
+ cases[2**np] = [
+ bank.read.eq(phase.bank == nb),
+ bank.read_col.eq(phase.address)
+ ]
+ self.comb += Case(reads, cases)
+
+ # connect banks to DFI phases (cmds, read datapath)
+ banks_read = Signal()
+ banks_read_data = Signal(data_width)
+ self.comb += [
+ banks_read.eq(optree("|", [bank.read for bank in banks])),
+ banks_read_data.eq(optree("|", [bank.read_data for bank in banks]))
+ ]
+ # simulate read latency
+ for i in range(self.settings.read_latency):
+ new_banks_read = Signal()
+ new_banks_read_data = Signal(data_width)
+ self.sync += [
+ new_banks_read.eq(banks_read),
+ new_banks_read_data.eq(banks_read_data)
+ ]
+ banks_read = new_banks_read
+ banks_read_data = new_banks_read_data
+
+ self.comb += [
+ Cat(*[phase.rddata_valid for phase in phases]).eq(banks_read),
+ Cat(*[phase.rddata for phase in phases]).eq(banks_read_data)
+ ]
--- /dev/null
+from litex.soc.cores.sdram.phy.gensdrphy import GENSDRPHY
+from litex.soc.cores.sdram.phy.s6ddrphy import S6HalfRateDDRPHY, S6QuarterRateDDRPHY
+from litex.soc.cores.sdram.phy.k7ddrphy import K7DDRPHY
--- /dev/null
+#
+# 1:1 frequency-ratio Generic SDR PHY
+#
+# The GENSDRPHY is validated on CycloneIV (Altera) but since it does
+# not use vendor-dependent code, it can also be used on other architectures.
+#
+# The PHY needs 2 Clock domains:
+# - sys_clk : The System Clock domain
+# - sys_clk_ps : The System Clock domain with its phase shifted
+# (-3ns on C4@100MHz)
+#
+# Assert dfi_wrdata_en and present the data
+# on dfi_wrdata_mask/dfi_wrdata in the same
+# cycle as the write command.
+#
+# Assert dfi_rddata_en in the same cycle as the read
+# command. The data will come back on dfi_rddata
+# 4 cycles later, along with the assertion of
+# dfi_rddata_valid.
+#
+# This PHY only supports CAS Latency 2.
+#
+
+from litex.gen import *
+from litex.gen.genlib.record import *
+from litex.gen.fhdl.specials import Tristate
+
+from litex.soc.interconnect.dfi import *
+from litex.soc.cores.sdram import settings as sdram_settings
+
+
+class GENSDRPHY(Module):
+ def __init__(self, pads):
+ addressbits = len(pads.a)
+ bankbits = len(pads.ba)
+ databits = len(pads.dq)
+
+ self.settings = sdram_settings.PhySettings(
+ memtype="SDR",
+ dfi_databits=databits,
+ nphases=1,
+ rdphase=0,
+ wrphase=0,
+ rdcmdphase=0,
+ wrcmdphase=0,
+ cl=2,
+ read_latency=4,
+ write_latency=0
+ )
+
+ self.dfi = Interface(addressbits, bankbits, databits)
+
+ ###
+
+ #
+ # Command/address
+ #
+ self.sync += [
+ pads.a.eq(self.dfi.p0.address),
+ pads.ba.eq(self.dfi.p0.bank),
+ pads.cke.eq(self.dfi.p0.cke),
+ pads.cas_n.eq(self.dfi.p0.cas_n),
+ pads.ras_n.eq(self.dfi.p0.ras_n),
+ pads.we_n.eq(self.dfi.p0.we_n)
+ ]
+ if hasattr(pads, "cs_n"):
+ self.sync += pads.cs_n.eq(self.dfi.p0.cs_n)
+
+ #
+ # DQ/DQS/DM data
+ #
+ sd_dq_out = Signal(databits)
+ drive_dq = Signal()
+ self.sync += sd_dq_out.eq(self.dfi.p0.wrdata)
+ self.specials += Tristate(pads.dq, sd_dq_out, drive_dq)
+ self.sync += \
+ If(self.dfi.p0.wrdata_en,
+ pads.dm.eq(self.dfi.p0.wrdata_mask)
+ ).Else(
+ pads.dm.eq(0)
+ )
+ sd_dq_in_ps = Signal(databits)
+ self.sync.sys_ps += sd_dq_in_ps.eq(pads.dq)
+ self.sync += self.dfi.p0.rddata.eq(sd_dq_in_ps)
+
+ #
+ # DQ/DM control
+ #
+ d_dfi_wrdata_en = Signal()
+ self.sync += d_dfi_wrdata_en.eq(self.dfi.p0.wrdata_en)
+ self.comb += drive_dq.eq(d_dfi_wrdata_en)
+
+ rddata_sr = Signal(4)
+ self.comb += self.dfi.p0.rddata_valid.eq(rddata_sr[3])
+ self.sync += rddata_sr.eq(Cat(self.dfi.p0.rddata_en, rddata_sr[:3]))
--- /dev/null
+# tCK=5ns CL=7 CWL=6
+
+from litex.gen import *
+
+from litex.soc.interconnect.dfi import *
+from litex.soc.interconnect.csr import *
+from litex.soc.cores.sdram import settings as sdram_settings
+
+
+class K7DDRPHY(Module, AutoCSR):
+ def __init__(self, pads):
+ addressbits = len(pads.a)
+ bankbits = len(pads.ba)
+ databits = len(pads.dq)
+ nphases = 4
+
+ self._wlevel_en = CSRStorage()
+ self._wlevel_strobe = CSR()
+ self._dly_sel = CSRStorage(databits//8)
+ self._rdly_dq_rst = CSR()
+ self._rdly_dq_inc = CSR()
+ self._rdly_dq_bitslip = CSR()
+ self._wdly_dq_rst = CSR()
+ self._wdly_dq_inc = CSR()
+ self._wdly_dqs_rst = CSR()
+ self._wdly_dqs_inc = CSR()
+
+ self.settings = sdram_settings.PhySettings(
+ memtype="DDR3",
+ dfi_databits=2*databits,
+ nphases=nphases,
+ rdphase=0,
+ wrphase=2,
+ rdcmdphase=1,
+ wrcmdphase=0,
+ cl=7,
+ cwl=6,
+ read_latency=6,
+ write_latency=2
+ )
+
+ self.dfi = Interface(addressbits, bankbits, 2*databits, nphases)
+
+ ###
+
+ # Clock
+ sd_clk_se = Signal()
+ self.specials += [
+ Instance("OSERDESE2",
+ p_DATA_WIDTH=8, p_TRISTATE_WIDTH=1,
+ p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF",
+ p_SERDES_MODE="MASTER",
+
+ o_OQ=sd_clk_se,
+ i_OCE=1,
+ i_RST=ResetSignal(),
+ i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal(),
+ i_D1=0, i_D2=1, i_D3=0, i_D4=1,
+ i_D5=0, i_D6=1, i_D7=0, i_D8=1
+ ),
+ Instance("OBUFDS",
+ i_I=sd_clk_se,
+ o_O=pads.clk_p,
+ o_OB=pads.clk_n
+ )
+ ]
+
+ # Addresses and commands
+ for i in range(addressbits):
+ self.specials += \
+ Instance("OSERDESE2",
+ p_DATA_WIDTH=8, p_TRISTATE_WIDTH=1,
+ p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF",
+ p_SERDES_MODE="MASTER",
+
+ o_OQ=pads.a[i],
+ i_OCE=1,
+ i_RST=ResetSignal(),
+ i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal(),
+ i_D1=self.dfi.phases[0].address[i], i_D2=self.dfi.phases[0].address[i],
+ i_D3=self.dfi.phases[1].address[i], i_D4=self.dfi.phases[1].address[i],
+ i_D5=self.dfi.phases[2].address[i], i_D6=self.dfi.phases[2].address[i],
+ i_D7=self.dfi.phases[3].address[i], i_D8=self.dfi.phases[3].address[i]
+ )
+ for i in range(bankbits):
+ self.specials += \
+ Instance("OSERDESE2",
+ p_DATA_WIDTH=8, p_TRISTATE_WIDTH=1,
+ p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF",
+ p_SERDES_MODE="MASTER",
+
+ o_OQ=pads.ba[i],
+ i_OCE=1,
+ i_RST=ResetSignal(),
+ i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal(),
+ i_D1=self.dfi.phases[0].bank[i], i_D2=self.dfi.phases[0].bank[i],
+ i_D3=self.dfi.phases[1].bank[i], i_D4=self.dfi.phases[1].bank[i],
+ i_D5=self.dfi.phases[2].bank[i], i_D6=self.dfi.phases[2].bank[i],
+ i_D7=self.dfi.phases[3].bank[i], i_D8=self.dfi.phases[3].bank[i]
+ )
+ for name in "ras_n", "cas_n", "we_n", "cs_n", "cke", "odt", "reset_n":
+ self.specials += \
+ Instance("OSERDESE2",
+ p_DATA_WIDTH=8, p_TRISTATE_WIDTH=1,
+ p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF",
+ p_SERDES_MODE="MASTER",
+
+ o_OQ=getattr(pads, name),
+ i_OCE=1,
+ i_RST=ResetSignal(),
+ i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal(),
+ i_D1=getattr(self.dfi.phases[0], name), i_D2=getattr(self.dfi.phases[0], name),
+ i_D3=getattr(self.dfi.phases[1], name), i_D4=getattr(self.dfi.phases[1], name),
+ i_D5=getattr(self.dfi.phases[2], name), i_D6=getattr(self.dfi.phases[2], name),
+ i_D7=getattr(self.dfi.phases[3], name), i_D8=getattr(self.dfi.phases[3], name)
+ )
+
+ # DQS and DM
+ oe_dqs = Signal()
+ dqs_serdes_pattern = Signal(8)
+ self.comb += \
+ If(self._wlevel_en.storage,
+ If(self._wlevel_strobe.re,
+ dqs_serdes_pattern.eq(0b00000001)
+ ).Else(
+ dqs_serdes_pattern.eq(0b00000000)
+ )
+ ).Else(
+ dqs_serdes_pattern.eq(0b01010101)
+ )
+ for i in range(databits//8):
+ dm_o_nodelay = Signal()
+ self.specials += \
+ Instance("OSERDESE2",
+ p_DATA_WIDTH=8, p_TRISTATE_WIDTH=1,
+ p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF",
+ p_SERDES_MODE="MASTER",
+
+ o_OQ=dm_o_nodelay,
+ i_OCE=1,
+ i_RST=ResetSignal(),
+ i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal(),
+ i_D1=self.dfi.phases[0].wrdata_mask[i], i_D2=self.dfi.phases[0].wrdata_mask[databits//8+i],
+ i_D3=self.dfi.phases[1].wrdata_mask[i], i_D4=self.dfi.phases[1].wrdata_mask[databits//8+i],
+ i_D5=self.dfi.phases[2].wrdata_mask[i], i_D6=self.dfi.phases[2].wrdata_mask[databits//8+i],
+ i_D7=self.dfi.phases[3].wrdata_mask[i], i_D8=self.dfi.phases[3].wrdata_mask[databits//8+i]
+ )
+ self.specials += \
+ Instance("ODELAYE2",
+ p_DELAY_SRC="ODATAIN", p_SIGNAL_PATTERN="DATA",
+ p_CINVCTRL_SEL="FALSE", p_HIGH_PERFORMANCE_MODE="TRUE", p_REFCLK_FREQUENCY=200.0,
+ p_PIPE_SEL="FALSE", p_ODELAY_TYPE="VARIABLE", p_ODELAY_VALUE=0,
+
+ i_C=ClockSignal(),
+ i_LD=self._dly_sel.storage[i] & self._wdly_dq_rst.re,
+ i_CE=self._dly_sel.storage[i] & self._wdly_dq_inc.re,
+ i_LDPIPEEN=0, i_INC=1,
+
+ o_ODATAIN=dm_o_nodelay, o_DATAOUT=pads.dm[i]
+ )
+
+ dqs_nodelay = Signal()
+ dqs_delayed = Signal()
+ dqs_t = Signal()
+ self.specials += [
+ Instance("OSERDESE2",
+ p_DATA_WIDTH=8, p_TRISTATE_WIDTH=1,
+ p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF",
+ p_SERDES_MODE="MASTER",
+
+ o_OFB=dqs_nodelay, o_TQ=dqs_t,
+ i_OCE=1, i_TCE=1,
+ i_RST=ResetSignal(),
+ i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal(),
+ i_D1=dqs_serdes_pattern[0], i_D2=dqs_serdes_pattern[1],
+ i_D3=dqs_serdes_pattern[2], i_D4=dqs_serdes_pattern[3],
+ i_D5=dqs_serdes_pattern[4], i_D6=dqs_serdes_pattern[5],
+ i_D7=dqs_serdes_pattern[6], i_D8=dqs_serdes_pattern[7],
+ i_T1=~oe_dqs
+ ),
+ Instance("ODELAYE2",
+ p_DELAY_SRC="ODATAIN", p_SIGNAL_PATTERN="DATA",
+ p_CINVCTRL_SEL="FALSE", p_HIGH_PERFORMANCE_MODE="TRUE", p_REFCLK_FREQUENCY=200.0,
+ p_PIPE_SEL="FALSE", p_ODELAY_TYPE="VARIABLE", p_ODELAY_VALUE=6,
+
+ i_C=ClockSignal(),
+ i_LD=self._dly_sel.storage[i] & self._wdly_dqs_rst.re,
+ i_CE=self._dly_sel.storage[i] & self._wdly_dqs_inc.re,
+ i_LDPIPEEN=0, i_INC=1,
+
+ o_ODATAIN=dqs_nodelay, o_DATAOUT=dqs_delayed
+ ),
+ Instance("OBUFTDS",
+ i_I=dqs_delayed, i_T=dqs_t,
+ o_O=pads.dqs_p[i], o_OB=pads.dqs_n[i]
+ )
+ ]
+
+ # DQ
+ oe_dq = Signal()
+ for i in range(databits):
+ dq_o_nodelay = Signal()
+ dq_o_delayed = Signal()
+ dq_i_nodelay = Signal()
+ dq_i_delayed = Signal()
+ dq_t = Signal()
+ self.specials += [
+ Instance("OSERDESE2",
+ p_DATA_WIDTH=8, p_TRISTATE_WIDTH=1,
+ p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF",
+ p_SERDES_MODE="MASTER",
+
+ o_OQ=dq_o_nodelay, o_TQ=dq_t,
+ i_OCE=1, i_TCE=1,
+ i_RST=ResetSignal(),
+ i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal(),
+ i_D1=self.dfi.phases[0].wrdata[i], i_D2=self.dfi.phases[0].wrdata[databits+i],
+ i_D3=self.dfi.phases[1].wrdata[i], i_D4=self.dfi.phases[1].wrdata[databits+i],
+ i_D5=self.dfi.phases[2].wrdata[i], i_D6=self.dfi.phases[2].wrdata[databits+i],
+ i_D7=self.dfi.phases[3].wrdata[i], i_D8=self.dfi.phases[3].wrdata[databits+i],
+ i_T1=~oe_dq
+ ),
+ Instance("ISERDESE2",
+ p_DATA_WIDTH=8, p_DATA_RATE="DDR",
+ p_SERDES_MODE="MASTER", p_INTERFACE_TYPE="NETWORKING",
+ p_NUM_CE=1, p_IOBDELAY="IFD",
+
+ i_DDLY=dq_i_delayed,
+ i_CE1=1,
+ i_RST=ResetSignal() | (self._dly_sel.storage[i//8] & self._wdly_dq_rst.re),
+ i_CLK=ClockSignal("sys4x"), i_CLKB=~ClockSignal("sys4x"), i_CLKDIV=ClockSignal(),
+ i_BITSLIP=self._dly_sel.storage[i//8] & self._rdly_dq_bitslip.re,
+ o_Q8=self.dfi.phases[0].rddata[i], o_Q7=self.dfi.phases[0].rddata[databits+i],
+ o_Q6=self.dfi.phases[1].rddata[i], o_Q5=self.dfi.phases[1].rddata[databits+i],
+ o_Q4=self.dfi.phases[2].rddata[i], o_Q3=self.dfi.phases[2].rddata[databits+i],
+ o_Q2=self.dfi.phases[3].rddata[i], o_Q1=self.dfi.phases[3].rddata[databits+i]
+ ),
+ Instance("ODELAYE2",
+ p_DELAY_SRC="ODATAIN", p_SIGNAL_PATTERN="DATA",
+ p_CINVCTRL_SEL="FALSE", p_HIGH_PERFORMANCE_MODE="TRUE", p_REFCLK_FREQUENCY=200.0,
+ p_PIPE_SEL="FALSE", p_ODELAY_TYPE="VARIABLE", p_ODELAY_VALUE=0,
+
+ i_C=ClockSignal(),
+ i_LD=self._dly_sel.storage[i//8] & self._wdly_dq_rst.re,
+ i_CE=self._dly_sel.storage[i//8] & self._wdly_dq_inc.re,
+ i_LDPIPEEN=0, i_INC=1,
+
+ o_ODATAIN=dq_o_nodelay, o_DATAOUT=dq_o_delayed
+ ),
+ Instance("IDELAYE2",
+ p_DELAY_SRC="IDATAIN", p_SIGNAL_PATTERN="DATA",
+ p_CINVCTRL_SEL="FALSE", p_HIGH_PERFORMANCE_MODE="TRUE", p_REFCLK_FREQUENCY=200.0,
+ p_PIPE_SEL="FALSE", p_IDELAY_TYPE="VARIABLE", p_IDELAY_VALUE=6,
+
+ i_C=ClockSignal(),
+ i_LD=self._dly_sel.storage[i//8] & self._rdly_dq_rst.re,
+ i_CE=self._dly_sel.storage[i//8] & self._rdly_dq_inc.re,
+ i_LDPIPEEN=0, i_INC=1,
+
+ i_IDATAIN=dq_i_nodelay, o_DATAOUT=dq_i_delayed
+ ),
+ Instance("IOBUF",
+ i_I=dq_o_delayed, o_O=dq_i_nodelay, i_T=dq_t,
+ io_IO=pads.dq[i]
+ )
+ ]
+
+ # Flow control
+ #
+ # total read latency = 6:
+ # 2 cycles through OSERDESE2
+ # 2 cycles CAS
+ # 2 cycles through ISERDESE2
+ rddata_en = self.dfi.phases[self.settings.rdphase].rddata_en
+ for i in range(5):
+ n_rddata_en = Signal()
+ self.sync += n_rddata_en.eq(rddata_en)
+ rddata_en = n_rddata_en
+ self.sync += [phase.rddata_valid.eq(rddata_en | self._wlevel_en.storage)
+ for phase in self.dfi.phases]
+
+ oe = Signal()
+ last_wrdata_en = Signal(4)
+ wrphase = self.dfi.phases[self.settings.wrphase]
+ self.sync += last_wrdata_en.eq(Cat(wrphase.wrdata_en, last_wrdata_en[:3]))
+ self.comb += oe.eq(last_wrdata_en[1] | last_wrdata_en[2] | last_wrdata_en[3])
+ self.sync += \
+ If(self._wlevel_en.storage,
+ oe_dqs.eq(1), oe_dq.eq(0)
+ ).Else(
+ oe_dqs.eq(oe), oe_dq.eq(oe)
+ )
--- /dev/null
+# 1:2 and 1:4 frequency-ratio DDR / LPDDR / DDR2 / DDR3 PHYs for Spartan-6
+#
+# Assert dfi_wrdata_en and present the data
+# on dfi_wrdata_mask/dfi_wrdata in the same
+# cycle as the write command.
+#
+# Assert dfi_rddata_en in the same cycle as the read
+# command. The data will come back on dfi_rddata
+# 5 cycles later, along with the assertion
+# of dfi_rddata_valid.
+#
+# This PHY only supports CAS latency 3 for DDR, LPDDR, DDR2
+# and CAS latency 5/CAS write latency 6 for DDR3.
+#
+# Read commands must be sent on phase 0.
+# Write commands must be sent on phase 1.
+#
+
+from functools import reduce
+from operator import or_
+
+from litex.gen import *
+from litex.gen.genlib.record import *
+
+from litex.soc.interconnect.dfi import *
+from litex.soc.cores.sdram import settings as sdram_settings
+
+
+class S6HalfRateDDRPHY(Module):
+ def __init__(self, pads, memtype, rd_bitslip, wr_bitslip, dqs_ddr_alignment):
+ if memtype not in ["DDR", "LPDDR", "DDR2", "DDR3"]:
+ raise NotImplementedError("S6HalfRateDDRPHY only supports DDR, LPDDR, DDR2 and DDR3")
+ addressbits = len(pads.a)
+ bankbits = len(pads.ba)
+ databits = len(pads.dq)
+ nphases = 2
+
+ if memtype == "DDR3":
+ self.settings = sdram_settings.PhySettings(
+ memtype="DDR3",
+ dfi_databits=2*databits,
+ nphases=nphases,
+ rdphase=0,
+ wrphase=1,
+ rdcmdphase=1,
+ wrcmdphase=0,
+ cl=5,
+ cwl=6,
+ read_latency=6,
+ write_latency=2
+ )
+ else:
+ self.settings = sdram_settings.PhySettings(
+ memtype=memtype,
+ dfi_databits=2*databits,
+ nphases=nphases,
+ rdphase=0,
+ wrphase=1,
+ rdcmdphase=1,
+ wrcmdphase=0,
+ cl=3,
+ read_latency=5,
+ write_latency=0
+ )
+
+ self.dfi = Interface(addressbits, bankbits, 2*databits, nphases)
+ self.clk4x_wr_strb = Signal()
+ self.clk4x_rd_strb = Signal()
+
+ ###
+
+ # sys_clk : system clk, used for dfi interface
+ # sdram_half_clk : half rate sdram clk
+ # sdram_full_wr_clk : full rate sdram write clk
+ # sdram_full_rd_clk : full rate sdram read clk
+ sd_sys = getattr(self.sync, "sys")
+ sd_sdram_half = getattr(self.sync, "sdram_half")
+
+ sys_clk = ClockSignal("sys")
+ sdram_half_clk = ClockSignal("sdram_half")
+ sdram_full_wr_clk = ClockSignal("sdram_full_wr")
+ sdram_full_rd_clk = ClockSignal("sdram_full_rd")
+
+ #
+ # Command/address
+ #
+
+ # select active phase
+ # sys_clk ----____----____
+ # phase_sel(nphases=2) 0 1 0 1 Half Rate
+ phase_sel = Signal(log2_int(nphases))
+ phase_half = Signal.like(phase_sel)
+ phase_sys = Signal.like(phase_half)
+
+ sd_sys += phase_sys.eq(phase_half)
+
+ sd_sdram_half += [
+ If(phase_half == phase_sys,
+ phase_sel.eq(0),
+ ).Else(
+ phase_sel.eq(phase_sel+1)
+ ),
+ phase_half.eq(phase_half+1),
+ ]
+
+ # register dfi cmds on half_rate clk
+ r_dfi = Array(Record(phase_cmd_description(addressbits, bankbits)) for i in range(nphases))
+ for n, phase in enumerate(self.dfi.phases):
+ sd_sdram_half += [
+ r_dfi[n].reset_n.eq(phase.reset_n),
+ r_dfi[n].odt.eq(phase.odt),
+ r_dfi[n].address.eq(phase.address),
+ r_dfi[n].bank.eq(phase.bank),
+ r_dfi[n].cs_n.eq(phase.cs_n),
+ r_dfi[n].cke.eq(phase.cke),
+ r_dfi[n].cas_n.eq(phase.cas_n),
+ r_dfi[n].ras_n.eq(phase.ras_n),
+ r_dfi[n].we_n.eq(phase.we_n)
+ ]
+
+ # output cmds
+ sd_sdram_half += [
+ pads.a.eq(r_dfi[phase_sel].address),
+ pads.ba.eq(r_dfi[phase_sel].bank),
+ pads.cke.eq(r_dfi[phase_sel].cke),
+ pads.ras_n.eq(r_dfi[phase_sel].ras_n),
+ pads.cas_n.eq(r_dfi[phase_sel].cas_n),
+ pads.we_n.eq(r_dfi[phase_sel].we_n)
+ ]
+ # optional pads
+ for name in "reset_n", "cs_n", "odt":
+ if hasattr(pads, name):
+ sd_sdram_half += getattr(pads, name).eq(getattr(r_dfi[phase_sel], name))
+
+ #
+ # Bitslip
+ #
+ bitslip_cnt = Signal(4)
+ bitslip_inc = Signal()
+
+ sd_sys += [
+ If(bitslip_cnt == rd_bitslip,
+ bitslip_inc.eq(0)
+ ).Else(
+ bitslip_cnt.eq(bitslip_cnt+1),
+ bitslip_inc.eq(1)
+ )
+ ]
+
+ #
+ # DQ/DQS/DM data
+ #
+ sdram_half_clk_n = Signal()
+ self.comb += sdram_half_clk_n.eq(~sdram_half_clk)
+
+ postamble = Signal()
+ drive_dqs = Signal()
+ dqs_t_d0 = Signal()
+ dqs_t_d1 = Signal()
+
+ dqs_o = Signal(databits//8)
+ dqs_t = Signal(databits//8)
+
+ self.comb += [
+ dqs_t_d0.eq(~(drive_dqs | postamble)),
+ dqs_t_d1.eq(~drive_dqs),
+ ]
+
+ for i in range(databits//8):
+ # DQS output
+ self.specials += Instance("ODDR2",
+ p_DDR_ALIGNMENT=dqs_ddr_alignment,
+ p_INIT=0,
+ p_SRTYPE="ASYNC",
+
+ i_C0=sdram_half_clk,
+ i_C1=sdram_half_clk_n,
+
+ i_CE=1,
+ i_D0=0,
+ i_D1=1,
+ i_R=0,
+ i_S=0,
+
+ o_Q=dqs_o[i]
+ )
+
+ # DQS tristate cmd
+ self.specials += Instance("ODDR2",
+ p_DDR_ALIGNMENT=dqs_ddr_alignment,
+ p_INIT=0,
+ p_SRTYPE="ASYNC",
+
+ i_C0=sdram_half_clk,
+ i_C1=sdram_half_clk_n,
+
+ i_CE=1,
+ i_D0=dqs_t_d0,
+ i_D1=dqs_t_d1,
+ i_R=0,
+ i_S=0,
+
+ o_Q=dqs_t[i]
+ )
+
+ # DQS tristate buffer
+ if hasattr(pads, "dqs_n"):
+ self.specials += Instance("OBUFTDS",
+ i_I=dqs_o[i],
+ i_T=dqs_t[i],
+
+ o_O=pads.dqs[i],
+ o_OB=pads.dqs_n[i],
+ )
+ else:
+ self.specials += Instance("OBUFT",
+ i_I=dqs_o[i],
+ i_T=dqs_t[i],
+
+ o_O=pads.dqs[i]
+ )
+
+ sd_sdram_half += postamble.eq(drive_dqs)
+
+ d_dfi = [Record(phase_wrdata_description(nphases*databits)+phase_rddata_description(nphases*databits))
+ for i in range(2*nphases)]
+
+ for n, phase in enumerate(self.dfi.phases):
+ self.comb += [
+ d_dfi[n].wrdata.eq(phase.wrdata),
+ d_dfi[n].wrdata_mask.eq(phase.wrdata_mask),
+ d_dfi[n].wrdata_en.eq(phase.wrdata_en),
+ d_dfi[n].rddata_en.eq(phase.rddata_en),
+ ]
+ sd_sys += [
+ d_dfi[nphases+n].wrdata.eq(phase.wrdata),
+ d_dfi[nphases+n].wrdata_mask.eq(phase.wrdata_mask)
+ ]
+
+
+ drive_dq = Signal()
+ drive_dq_n = [Signal() for i in range(2)]
+ self.comb += drive_dq_n[0].eq(~drive_dq)
+ sd_sys += drive_dq_n[1].eq(drive_dq_n[0])
+
+ dq_t = Signal(databits)
+ dq_o = Signal(databits)
+ dq_i = Signal(databits)
+
+ dq_wrdata = []
+ for i in range(2):
+ for j in reversed(range(nphases)):
+ dq_wrdata.append(d_dfi[i*nphases+j].wrdata[:databits])
+ dq_wrdata.append(d_dfi[i*nphases+j].wrdata[databits:])
+
+ for i in range(databits):
+ # Data serializer
+ self.specials += Instance("OSERDES2",
+ p_DATA_WIDTH=4,
+ p_DATA_RATE_OQ="SDR",
+ p_DATA_RATE_OT="SDR",
+ p_SERDES_MODE="NONE",
+ p_OUTPUT_MODE="SINGLE_ENDED",
+
+ o_OQ=dq_o[i],
+ i_OCE=1,
+ i_CLK0=sdram_full_wr_clk,
+ i_CLK1=0,
+ i_IOCE=self.clk4x_wr_strb,
+ i_RST=0,
+ i_CLKDIV=sys_clk,
+
+ i_D1=dq_wrdata[wr_bitslip+3][i],
+ i_D2=dq_wrdata[wr_bitslip+2][i],
+ i_D3=dq_wrdata[wr_bitslip+1][i],
+ i_D4=dq_wrdata[wr_bitslip+0][i],
+
+ o_TQ=dq_t[i],
+ i_T1=drive_dq_n[(wr_bitslip+3)//4],
+ i_T2=drive_dq_n[(wr_bitslip+2)//4],
+ i_T3=drive_dq_n[(wr_bitslip+1)//4],
+ i_T4=drive_dq_n[(wr_bitslip+0)//4],
+ i_TRAIN=0,
+ i_TCE=1,
+ i_SHIFTIN1=0,
+ i_SHIFTIN2=0,
+ i_SHIFTIN3=0,
+ i_SHIFTIN4=0,
+ )
+
+ # Data deserializer
+ self.specials += Instance("ISERDES2",
+ p_DATA_WIDTH=4,
+ p_DATA_RATE="SDR",
+ p_BITSLIP_ENABLE="TRUE",
+ p_SERDES_MODE="NONE",
+ p_INTERFACE_TYPE="RETIMED",
+
+ i_D=dq_i[i],
+ i_CE0=1,
+ i_CLK0=sdram_full_rd_clk,
+ i_CLK1=0,
+ i_IOCE=self.clk4x_rd_strb,
+ i_RST=ResetSignal(),
+ i_CLKDIV=sys_clk,
+ i_BITSLIP=bitslip_inc,
+
+ o_Q1=d_dfi[0*nphases+0].rddata[i+databits],
+ o_Q2=d_dfi[0*nphases+0].rddata[i],
+ o_Q3=d_dfi[0*nphases+1].rddata[i+databits],
+ o_Q4=d_dfi[0*nphases+1].rddata[i],
+ )
+
+ # Data buffer
+ self.specials += Instance("IOBUF",
+ i_I=dq_o[i],
+ o_O=dq_i[i],
+ i_T=dq_t[i],
+ io_IO=pads.dq[i]
+ )
+
+ dq_wrdata_mask = []
+ for i in range(2):
+ for j in reversed(range(nphases)):
+ dq_wrdata_mask.append(d_dfi[i*nphases+j].wrdata_mask[:databits//8])
+ dq_wrdata_mask.append(d_dfi[i*nphases+j].wrdata_mask[databits//8:])
+
+ for i in range(databits//8):
+ # Mask serializer
+ self.specials += Instance("OSERDES2",
+ p_DATA_WIDTH=4,
+ p_DATA_RATE_OQ="SDR",
+ p_DATA_RATE_OT="SDR",
+ p_SERDES_MODE="NONE",
+ p_OUTPUT_MODE="SINGLE_ENDED",
+
+ o_OQ=pads.dm[i],
+ i_OCE=1,
+ i_CLK0=sdram_full_wr_clk,
+ i_CLK1=0,
+ i_IOCE=self.clk4x_wr_strb,
+ i_RST=0,
+ i_CLKDIV=sys_clk,
+
+ i_D1=dq_wrdata_mask[wr_bitslip+3][i],
+ i_D2=dq_wrdata_mask[wr_bitslip+2][i],
+ i_D3=dq_wrdata_mask[wr_bitslip+1][i],
+ i_D4=dq_wrdata_mask[wr_bitslip+0][i],
+
+ i_TRAIN=0,
+ i_TCE=0,
+ i_SHIFTIN1=0,
+ i_SHIFTIN2=0,
+ i_SHIFTIN3=0,
+ i_SHIFTIN4=0,
+ )
+
+
+ #
+ # DQ/DQS/DM control
+ #
+
+ # write
+ wrdata_en = Signal()
+ self.comb += wrdata_en.eq(reduce(or_, [d_dfi[p].wrdata_en for p in range(nphases)]))
+
+ if memtype == "DDR3":
+ r_drive_dq = Signal(self.settings.cwl-1)
+ sd_sdram_half += r_drive_dq.eq(Cat(wrdata_en, r_drive_dq))
+ self.comb += drive_dq.eq(r_drive_dq[self.settings.cwl-2])
+ else:
+ self.comb += drive_dq.eq(wrdata_en)
+
+ wrdata_en_d = Signal()
+ sd_sys += wrdata_en_d.eq(wrdata_en)
+
+ r_dfi_wrdata_en = Signal(max(self.settings.cwl, self.settings.cl))
+ sd_sdram_half += r_dfi_wrdata_en.eq(Cat(wrdata_en_d, r_dfi_wrdata_en))
+
+ if memtype == "DDR3":
+ self.comb += drive_dqs.eq(r_dfi_wrdata_en[self.settings.cwl-1])
+ else:
+ self.comb += drive_dqs.eq(r_dfi_wrdata_en[1])
+
+ # read
+ rddata_en = Signal()
+ self.comb += rddata_en.eq(reduce(or_, [d_dfi[p].rddata_en for p in range(nphases)]))
+
+ rddata_sr = Signal(self.settings.read_latency)
+ sd_sys += rddata_sr.eq(Cat(rddata_sr[1:self.settings.read_latency], rddata_en))
+
+ for n, phase in enumerate(self.dfi.phases):
+ self.comb += [
+ phase.rddata.eq(d_dfi[n].rddata),
+ phase.rddata_valid.eq(rddata_sr[0]),
+ ]
+
+
+class S6QuarterRateDDRPHY(Module):
+ def __init__(self, pads, rd_bitslip, wr_bitslip, dqs_ddr_alignment):
+ half_rate_phy = S6HalfRateDDRPHY(pads, "DDR3", rd_bitslip, wr_bitslip, dqs_ddr_alignment)
+ self.submodules += RenameClockDomains(half_rate_phy, {"sys" : "sys2x"})
+
+ addressbits = len(pads.a)
+ bankbits = len(pads.ba)
+ databits = len(pads.dq)
+ nphases = 4
+
+ self.settings = sdram_settings.PhySettings(
+ memtype="DDR3",
+ dfi_databits=2*databits,
+ nphases=nphases,
+ rdphase=0,
+ wrphase=1,
+ rdcmdphase=1,
+ wrcmdphase=0,
+ cl=5,
+ cwl=6,
+ read_latency=6//2+1,
+ write_latency=2//2
+ )
+
+ self.dfi = Interface(addressbits, bankbits, 2*databits, nphases)
+ self.clk8x_wr_strb = half_rate_phy.clk4x_wr_strb
+ self.clk8x_rd_strb = half_rate_phy.clk4x_rd_strb
+
+ # sys_clk : system clk, used for dfi interface
+ # sys2x_clk : 2x system clk
+ sd_sys = getattr(self.sync, "sys")
+ sd_sys2x = getattr(self.sync, "sys2x")
+
+ # select active sys2x phase
+ # sys_clk ----____----____
+ # phase_sel 0 1 0 1
+ phase_sel = Signal()
+ phase_sys2x = Signal.like(phase_sel)
+ phase_sys = Signal.like(phase_sys2x)
+
+ sd_sys += phase_sys.eq(phase_sys2x)
+
+ sd_sys2x += [
+ If(phase_sys2x == phase_sys,
+ phase_sel.eq(0),
+ ).Else(
+ phase_sel.eq(~phase_sel)
+ ),
+ phase_sys2x.eq(~phase_sel)
+ ]
+
+ # DFI adaptation
+
+ # Commands and writes
+ dfi_leave_out = set(["rddata", "rddata_valid", "wrdata_en"])
+ self.comb += [
+ If(~phase_sel,
+ Record.connect(self.dfi.phases[0], half_rate_phy.dfi.phases[0], leave_out=dfi_leave_out),
+ Record.connect(self.dfi.phases[1], half_rate_phy.dfi.phases[1], leave_out=dfi_leave_out),
+ ).Else(
+ Record.connect(self.dfi.phases[2], half_rate_phy.dfi.phases[0], leave_out=dfi_leave_out),
+ Record.connect(self.dfi.phases[3], half_rate_phy.dfi.phases[1], leave_out=dfi_leave_out),
+ ),
+ ]
+ wr_data_en = self.dfi.phases[self.settings.wrphase].wrdata_en & ~phase_sel
+ wr_data_en_d = Signal()
+ sd_sys2x += wr_data_en_d.eq(wr_data_en)
+ self.comb += half_rate_phy.dfi.phases[half_rate_phy.settings.wrphase].wrdata_en.eq(wr_data_en | wr_data_en_d)
+
+ # Reads
+ rddata = Array(Signal(2*databits) for i in range(2))
+ rddata_valid = Signal(2)
+
+ for i in range(2):
+ sd_sys2x += [
+ rddata_valid[i].eq(half_rate_phy.dfi.phases[i].rddata_valid),
+ rddata[i].eq(half_rate_phy.dfi.phases[i].rddata)
+ ]
+
+ sd_sys += [
+ self.dfi.phases[0].rddata.eq(rddata[0]),
+ self.dfi.phases[0].rddata_valid.eq(rddata_valid[0]),
+ self.dfi.phases[1].rddata.eq(rddata[1]),
+ self.dfi.phases[1].rddata_valid.eq(rddata_valid[1]),
+ self.dfi.phases[2].rddata.eq(half_rate_phy.dfi.phases[0].rddata),
+ self.dfi.phases[2].rddata_valid.eq(half_rate_phy.dfi.phases[0].rddata_valid),
+ self.dfi.phases[3].rddata.eq(half_rate_phy.dfi.phases[1].rddata),
+ self.dfi.phases[3].rddata_valid.eq(half_rate_phy.dfi.phases[1].rddata_valid)
+ ]
--- /dev/null
+from math import ceil
+from collections import namedtuple
+
+from litex.gen import *
+
+
+PhySettingsT = namedtuple("PhySettings", "memtype dfi_databits nphases rdphase wrphase rdcmdphase wrcmdphase cl cwl read_latency write_latency")
+def PhySettings(memtype, dfi_databits, nphases, rdphase, wrphase, rdcmdphase, wrcmdphase, cl, read_latency, write_latency, cwl=0):
+ return PhySettingsT(memtype, dfi_databits, nphases, rdphase, wrphase, rdcmdphase, wrcmdphase, cl, cwl, read_latency, write_latency)
+
+GeomSettingsT = namedtuple("_GeomSettings", "bankbits rowbits colbits addressbits")
+def GeomSettings(bankbits, rowbits, colbits):
+ return GeomSettingsT(bankbits, rowbits, colbits, max(rowbits, colbits))
+
+TimingSettings = namedtuple("TimingSettings", "tRP tRCD tWR tWTR tREFI tRFC")
+
+
+# TODO:
+# Try to share the maximum information we can between modules:
+# - ex: MT46V32M16 and MT46H32M16 are almost identical (V=DDR, H=LPDDR)
+# - Modules can have different configuration:
+# MT8JTF12864 (1GB), MT8JTF25664 (2GB)
+# but share all others informations, try to create an unique module for all
+# configurations.
+# - Modules can have different speedgrades, add support for it (and also add
+# a check to verify clk_freq is in the supported range)
+
+
+class SDRAMModule:
+ def __init__(self, clk_freq, memtype, geom_settings, timing_settings):
+ self.clk_freq = clk_freq
+ self.memtype = memtype
+ self.geom_settings = GeomSettings(
+ bankbits=log2_int(geom_settings["nbanks"]),
+ rowbits=log2_int(geom_settings["nrows"]),
+ colbits=log2_int(geom_settings["ncols"]),
+ )
+ self.timing_settings = TimingSettings(
+ tRP=self.ns(timing_settings["tRP"]),
+ tRCD=self.ns(timing_settings["tRCD"]),
+ tWR=self.ns(timing_settings["tWR"]),
+ tWTR=timing_settings["tWTR"],
+ tREFI=self.ns(timing_settings["tREFI"], False),
+ tRFC=self.ns(timing_settings["tRFC"])
+ )
+
+ def ns(self, t, margin=True):
+ clk_period_ns = 1000000000/self.clk_freq
+ if margin:
+ t += clk_period_ns/2
+ return ceil(t/clk_period_ns)
+
+
+# SDR
+class IS42S16160(SDRAMModule):
+ geom_settings = {
+ "nbanks": 4,
+ "nrows": 8192,
+ "ncols": 512
+ }
+ # Timings for -7 speedgrade
+ timing_settings = {
+ "tRP": 20,
+ "tRCD": 20,
+ "tWR": 20,
+ "tWTR": 2,
+ "tREFI": 64*1000*1000/8192,
+ "tRFC": 70
+ }
+ def __init__(self, clk_freq):
+ SDRAMModule.__init__(self, clk_freq, "SDR", self.geom_settings,
+ self.timing_settings)
+
+
+class MT48LC4M16(SDRAMModule):
+ geom_settings = {
+ "nbanks": 4,
+ "nrows": 4096,
+ "ncols": 256
+ }
+ timing_settings = {
+ "tRP": 15,
+ "tRCD": 15,
+ "tWR": 14,
+ "tWTR": 2,
+ "tREFI": 64*1000*1000/4096,
+ "tRFC": 66
+ }
+ def __init__(self, clk_freq):
+ SDRAMModule.__init__(self, clk_freq, "SDR", self.geom_settings,
+ self.timing_settings)
+
+
+class AS4C16M16(SDRAMModule):
+ geom_settings = {
+ "nbanks": 4,
+ "nrows": 8192,
+ "ncols": 512
+ }
+ # Timings for -6 speedgrade
+ timing_settings = {
+ "tRP": 18,
+ "tRCD": 18,
+ "tWR": 12,
+ "tWTR": 2,
+ "tREFI": 64*1000*1000/8192,
+ "tRFC": 60
+ }
+ def __init__(self, clk_freq):
+ SDRAMModule.__init__(self, clk_freq, "SDR", self.geom_settings,
+ self.timing_settings)
+
+
+# DDR
+class MT46V32M16(SDRAMModule):
+ geom_settings = {
+ "nbanks": 4,
+ "nrows": 8192,
+ "ncols": 1024
+ }
+ timing_settings = {
+ "tRP": 15,
+ "tRCD": 15,
+ "tWR": 15,
+ "tWTR": 2,
+ "tREFI": 64*1000*1000/8192,
+ "tRFC": 70
+ }
+ def __init__(self, clk_freq):
+ SDRAMModule.__init__(self, clk_freq, "DDR", self.geom_settings,
+ self.timing_settings)
+
+
+# LPDDR
+class MT46H32M16(SDRAMModule):
+ geom_settings = {
+ "nbanks": 4,
+ "nrows": 8192,
+ "ncols": 1024
+ }
+ timing_settings = {
+ "tRP": 15,
+ "tRCD": 15,
+ "tWR": 15,
+ "tWTR": 2,
+ "tREFI": 64*1000*1000/8192,
+ "tRFC": 72
+ }
+ def __init__(self, clk_freq):
+ SDRAMModule.__init__(self, clk_freq, "LPDDR", self.geom_settings,
+ self.timing_settings)
+
+
+# DDR2
+class MT47H128M8(SDRAMModule):
+ geom_settings = {
+ "nbanks": 8,
+ "nrows": 16384,
+ "ncols": 1024
+ }
+ timing_settings = {
+ "tRP": 15,
+ "tRCD": 15,
+ "tWR": 15,
+ "tWTR": 2,
+ "tREFI": 7800,
+ "tRFC": 127.5
+ }
+ def __init__(self, clk_freq):
+ SDRAMModule.__init__(self, clk_freq, "DDR2", self.geom_settings,
+ self.timing_settings)
+
+
+class P3R1GE4JGF(SDRAMModule):
+ geom_settings = {
+ "nbanks": 8,
+ "nrows": 8192,
+ "ncols": 1024
+ }
+ timing_settings = {
+ "tRP": 12.5,
+ "tRCD": 12.5,
+ "tWR": 15,
+ "tWTR": 3,
+ "tREFI": 7800,
+ "tRFC": 127.5,
+ }
+
+ def __init__(self, clk_freq):
+ SDRAMModule.__init__(self, clk_freq, "DDR2", self.geom_settings,
+ self.timing_settings)
+
+
+# DDR3
+class MT8JTF12864(SDRAMModule):
+ geom_settings = {
+ "nbanks": 8,
+ "nrows": 16384,
+ "ncols": 1024
+ }
+ timing_settings = {
+ "tRP": 15,
+ "tRCD": 15,
+ "tWR": 15,
+ "tWTR": 2,
+ "tREFI": 7800,
+ "tRFC": 70
+ }
+ def __init__(self, clk_freq):
+ SDRAMModule.__init__(self, clk_freq, "DDR3", self.geom_settings,
+ self.timing_settings)
+
+
+class MT41J128M16(SDRAMModule):
+ geom_settings = {
+ "nbanks": 8,
+ "nrows": 16384,
+ "ncols": 1024,
+ }
+ timing_settings = {
+ "tRP": 15,
+ "tRCD": 15,
+ "tWR": 15,
+ "tWTR": 3,
+ "tREFI": 64*1000*1000/16384,
+ "tRFC": 260,
+ }
+ def __init__(self, clk_freq):
+ SDRAMModule.__init__(self, clk_freq, "DDR3", self.geom_settings,
+ self.timing_settings)
--- /dev/null
+from functools import reduce
+from operator import xor
+
+from litex.gen import *
+
+from litex.soc.interconnect.csr import *
+from litex.soc.interconnect import dma_lasmi
+
+# TODO: implement or replace DMAControllers in MiSoC
+
+
+@ResetInserter()
+@CEInserter()
+class LFSR(Module):
+ def __init__(self, n_out, n_state=31, taps=[27, 30]):
+ self.o = Signal(n_out)
+
+ ###
+
+ state = Signal(n_state)
+ curval = [state[i] for i in range(n_state)]
+ curval += [0]*(n_out - n_state)
+ for i in range(n_out):
+ nv = ~reduce(xor, [curval[tap] for tap in taps])
+ curval.insert(0, nv)
+ curval.pop()
+
+ self.sync += [
+ state.eq(Cat(*curval[:n_state])),
+ self.o.eq(Cat(*curval))
+ ]
+
+
+memtest_magic = 0x361f
+
+
+class Writer(Module):
+ def __init__(self, lasmim):
+ self._magic = CSRStatus(16)
+ self._reset = CSR()
+ self._shoot = CSR()
+ self.submodules._dma = DMAWriteController(dma_lasmi.Writer(lasmim),
+ MODE_EXTERNAL)
+
+ ###
+
+ self.comb += self._magic.status.eq(memtest_magic)
+
+ lfsr = LFSR(lasmim.dw)
+ self.submodules += lfsr
+ self.comb += lfsr.reset.eq(self._reset.re)
+
+ en = Signal()
+ en_counter = Signal(lasmim.aw)
+ self.comb += en.eq(en_counter != 0)
+ self.sync += [
+ If(self._shoot.re,
+ en_counter.eq(self._dma.length)
+ ).Elif(lfsr.ce,
+ en_counter.eq(en_counter - 1)
+ )
+ ]
+
+ self.comb += [
+ self._dma.trigger.eq(self._shoot.re),
+ self._dma.data.stb.eq(en),
+ lfsr.ce.eq(en & self._dma.data.ack),
+ self._dma.data.d.eq(lfsr.o)
+ ]
+
+ def get_csrs(self):
+ return [self._magic, self._reset, self._shoot] + self._dma.get_csrs()
+
+
+class Reader(Module):
+ def __init__(self, lasmim):
+ self._magic = CSRStatus(16)
+ self._reset = CSR()
+ self._error_count = CSRStatus(lasmim.aw)
+ self.submodules._dma = DMAReadController(dma_lasmi.Reader(lasmim),
+ MODE_SINGLE_SHOT)
+
+ ###
+
+ self.comb += self._magic.status.eq(memtest_magic)
+
+ lfsr = LFSR(lasmim.dw)
+ self.submodules += lfsr
+ self.comb += lfsr.reset.eq(self._reset.re)
+
+ self.comb += [
+ lfsr.ce.eq(self._dma.data.stb),
+ self._dma.data.ack.eq(1)
+ ]
+ err_cnt = self._error_count.status
+ self.sync += [
+ If(self._reset.re,
+ err_cnt.eq(0)
+ ).Elif(self._dma.data.stb,
+ If(self._dma.data.d != lfsr.o, err_cnt.eq(err_cnt + 1))
+ )
+ ]
+
+ def get_csrs(self):
+ return [self._magic, self._reset, self._error_count] + self._dma.get_csrs()
+
+
+class _LFSRTB(Module):
+ def __init__(self, *args, **kwargs):
+ self.submodules.dut = LFSR(*args, **kwargs)
+ self.comb += self.dut.ce.eq(1)
+
+ def do_simulation(self, selfp):
+ print("{0:032x}".format(selfp.dut.o))
+
+if __name__ == "__main__":
+ from litex.gen.fhdl import verilog
+ from litex.gen.sim.generic import run_simulation
+
+ lfsr = LFSR(3, 4, [3, 2])
+ print(verilog.convert(lfsr, ios={lfsr.ce, lfsr.reset, lfsr.o}))
+
+ run_simulation(_LFSRTB(128), ncycles=20)
--- /dev/null
+from litex.soc.spi.core import SPIMaster
--- /dev/null
+from litex.gen import *
+from litex.gen.bank.description import *
+from litex.gen.genlib.fsm import FSM, NextState
+
+
+class SPIMaster(Module, AutoCSR):
+ def __init__(self, pads, width=24, div=2, cpha=1):
+ self.pads = pads
+
+ self._ctrl = CSR()
+ self._length = CSRStorage(8)
+ self._status = CSRStatus()
+ if hasattr(pads, "mosi"):
+ self._mosi = CSRStorage(width)
+ if hasattr(pads, "miso"):
+ self._miso = CSRStatus(width)
+
+ self.irq = Signal()
+
+ ###
+
+ # ctrl
+ start = Signal()
+ length = self._length.storage
+ enable_cs = Signal()
+ enable_shift = Signal()
+ done = Signal()
+
+ self.comb += [
+ start.eq(self._ctrl.re & self._ctrl.r[0]),
+ self._status.status.eq(done)
+ ]
+
+ # clk
+ i = Signal(max=div)
+ set_clk = Signal()
+ clr_clk = Signal()
+ self.sync += [
+ If(set_clk,
+ pads.clk.eq(enable_cs)
+ ),
+ If(clr_clk,
+ pads.clk.eq(0),
+ i.eq(0)
+ ).Else(
+ i.eq(i + 1),
+ )
+ ]
+
+ self.comb += [
+ set_clk.eq(i == (div//2-1)),
+ clr_clk.eq(i == (div-1))
+ ]
+
+ # fsm
+ cnt = Signal(8)
+ clr_cnt = Signal()
+ inc_cnt = Signal()
+ self.sync += \
+ If(clr_cnt,
+ cnt.eq(0)
+ ).Elif(inc_cnt,
+ cnt.eq(cnt+1)
+ )
+
+ fsm = FSM(reset_state="IDLE")
+ self.submodules += fsm
+ fsm.act("IDLE",
+ If(start,
+ NextState("WAIT_CLK")
+ ),
+ done.eq(1),
+ clr_cnt.eq(1)
+ )
+ fsm.act("WAIT_CLK",
+ If(clr_clk,
+ NextState("SHIFT")
+ ),
+ )
+ fsm.act("SHIFT",
+ If(cnt == length,
+ NextState("END")
+ ).Else(
+ inc_cnt.eq(clr_clk),
+ ),
+ enable_cs.eq(1),
+ enable_shift.eq(1),
+ )
+ fsm.act("END",
+ If(set_clk,
+ NextState("IDLE")
+ ),
+ enable_shift.eq(1),
+ self.irq.eq(1)
+ )
+
+ # miso
+ if hasattr(pads, "miso"):
+ miso = Signal()
+ sr_miso = Signal(width)
+
+ # (cpha = 1: capture on clk falling edge)
+ if cpha:
+ self.sync += \
+ If(enable_shift,
+ If(clr_clk,
+ miso.eq(pads.miso),
+ ).Elif(set_clk,
+ sr_miso.eq(Cat(miso, sr_miso[:-1]))
+ )
+ )
+ # (cpha = 0: capture on clk rising edge)
+ else:
+ self.sync += \
+ If(enable_shift,
+ If(set_clk,
+ miso.eq(pads.miso),
+ ).Elif(clr_clk,
+ sr_miso.eq(Cat(miso, sr_miso[:-1]))
+ )
+ )
+ self.comb += self._miso.status.eq(sr_miso)
+
+ # mosi
+ if hasattr(pads, "mosi"):
+ sr_mosi = Signal(width)
+
+ # (cpha = 1: propagated on clk rising edge)
+ if cpha:
+ self.sync += \
+ If(start,
+ sr_mosi.eq(self._mosi.storage)
+ ).Elif(clr_clk & enable_shift,
+ sr_mosi.eq(Cat(Signal(), sr_mosi[:-1]))
+ ).Elif(set_clk,
+ pads.mosi.eq(sr_mosi[-1])
+ )
+
+ # (cpha = 0: propagated on clk falling edge)
+ else:
+ self.sync += [
+ If(start,
+ sr_mosi.eq(self._mosi.storage)
+ ).Elif(set_clk & enable_shift,
+ sr_mosi.eq(Cat(Signal(), sr_mosi[:-1]))
+ ).Elif(clr_clk,
+ pads.mosi.eq(sr_mosi[-1])
+ )
+ ]
+
+ # cs_n
+ self.comb += pads.cs_n.eq(~enable_cs)
--- /dev/null
+from litex.gen import *
+from litex.gen.genlib.record import *
+from litex.gen.sim.generic import run_simulation
+
+from litex.soc.com.spi import SPIMaster
+
+
+class SPISlave(Module):
+ def __init__(self, pads, width):
+ self.pads = pads
+ self.width = width
+
+ ###
+
+ self.mosi = 0
+ self.miso = 0
+
+ self.last_cs_n = 1
+ self.last_clk = 0
+
+
+ def get_mosi(self):
+ return self.mosi
+
+ def set_miso(self, value):
+ self.miso = value
+
+ def do_simulation(self, selfp):
+ # detect edges
+ cs_n_rising = 0
+ cs_n_falling = 0
+ clk_rising = 0
+ clk_falling = 0
+ if selfp.pads.cs_n and not self.last_cs_n:
+ cs_n_rising = 1
+ if not selfp.pads.cs_n and self.last_cs_n:
+ cs_n_falling = 1
+ if selfp.pads.clk and not self.last_clk:
+ clk_rising = 1
+ if not selfp.pads.clk and self.last_clk:
+ clk_falling = 1
+
+ # input mosi
+ if clk_falling and not selfp.pads.cs_n:
+ self.mosi = self.mosi << 1
+ self.mosi |= selfp.pads.mosi
+
+ # output miso
+ if (clk_rising and not selfp.pads.cs_n):
+ selfp.pads.miso = (self.miso >> (self.width-1)) & 0x1
+ self.miso = self.miso << 1
+
+ # save signal states
+ self.last_cs_n = selfp.pads.cs_n
+ self.last_clk = selfp.pads.clk
+
+
+def spi_access(selfp, length, mosi):
+ selfp.spi_master._mosi.storage = mosi
+ yield
+ selfp.spi_master._ctrl.r = (length << 8) | 1
+ selfp.spi_master._ctrl.re = 1
+ yield
+ selfp.spi_master._ctrl.r = 0
+ selfp.spi_master._ctrl.re = 0
+ yield
+ while not (selfp.spi_master._status.status & 0x1):
+ yield
+
+
+class TB(Module):
+ def __init__(self):
+ pads = Record([("cs_n", 1), ("clk", 1), ("mosi", 1), ("miso", 1)])
+ self.submodules.spi_master = SPIMaster(pads, 24, 4)
+ self.submodules.spi_slave = SPISlave(pads, 24)
+
+ def gen_simulation(self, selfp):
+ for i in range(16):
+ yield
+ self.spi_slave.set_miso(0x123457)
+ yield from spi_access(selfp, 8, 0x123457)
+ print("{:08x}".format(self.spi_slave.get_mosi()))
+ print("{:08x}".format(selfp.spi_master._miso.status))
+
+if __name__ == "__main__":
+ run_simulation(TB(), ncycles=1000, vcd_name="my.vcd", keep_files=True)
--- /dev/null
+from litex.gen import *
+
+from litex.soc.interconnect.csr import *
+from litex.soc.interconnect.csr_eventmanager import *
+
+
+class Timer(Module, AutoCSR):
+ def __init__(self, width=32):
+ self._load = CSRStorage(width)
+ self._reload = CSRStorage(width)
+ self._en = CSRStorage()
+ self._update_value = CSR()
+ self._value = CSRStatus(width)
+
+ self.submodules.ev = EventManager()
+ self.ev.zero = EventSourceProcess()
+ self.ev.finalize()
+
+ ###
+
+ value = Signal(width)
+ self.sync += [
+ If(self._en.storage,
+ If(value == 0,
+ # set reload to 0 to disable reloading
+ value.eq(self._reload.storage)
+ ).Else(
+ value.eq(value - 1)
+ )
+ ).Else(
+ value.eq(self._load.storage)
+ ),
+ If(self._update_value.re, self._value.status.eq(value))
+ ]
+ self.comb += self.ev.zero.trigger.eq(value != 0)
--- /dev/null
+from litex.soc.cores.uart.core import UART, RS232PHY
--- /dev/null
+from litex.gen import *
+from litex.gen.genlib.record import Record
+from litex.gen.genlib.cdc import MultiReg
+
+from litex.soc.interconnect.csr import *
+from litex.soc.interconnect.csr_eventmanager import *
+from litex.soc.interconnect.stream import Source, Sink, SyncFIFO, AsyncFIFO
+
+
+class RS232PHYRX(Module):
+ def __init__(self, pads, tuning_word):
+ self.source = Source([("data", 8)])
+
+ # # #
+
+ uart_clk_rxen = Signal()
+ phase_accumulator_rx = Signal(32)
+
+ rx = Signal()
+ self.specials += MultiReg(pads.rx, rx)
+ rx_r = Signal()
+ rx_reg = Signal(8)
+ rx_bitcount = Signal(4)
+ rx_busy = Signal()
+ rx_done = self.source.stb
+ rx_data = self.source.data
+ self.sync += [
+ rx_done.eq(0),
+ rx_r.eq(rx),
+ If(~rx_busy,
+ If(~rx & rx_r, # look for start bit
+ rx_busy.eq(1),
+ rx_bitcount.eq(0),
+ )
+ ).Else(
+ If(uart_clk_rxen,
+ rx_bitcount.eq(rx_bitcount + 1),
+ If(rx_bitcount == 0,
+ If(rx, # verify start bit
+ rx_busy.eq(0)
+ )
+ ).Elif(rx_bitcount == 9,
+ rx_busy.eq(0),
+ If(rx, # verify stop bit
+ rx_data.eq(rx_reg),
+ rx_done.eq(1)
+ )
+ ).Else(
+ rx_reg.eq(Cat(rx_reg[1:], rx))
+ )
+ )
+ )
+ ]
+ self.sync += \
+ If(rx_busy,
+ Cat(phase_accumulator_rx, uart_clk_rxen).eq(phase_accumulator_rx + tuning_word)
+ ).Else(
+ Cat(phase_accumulator_rx, uart_clk_rxen).eq(2**31)
+ )
+
+
+class RS232PHYTX(Module):
+ def __init__(self, pads, tuning_word):
+ self.sink = Sink([("data", 8)])
+
+ # # #
+
+ uart_clk_txen = Signal()
+ phase_accumulator_tx = Signal(32)
+
+ pads.tx.reset = 1
+
+ tx_reg = Signal(8)
+ tx_bitcount = Signal(4)
+ tx_busy = Signal()
+ self.sync += [
+ self.sink.ack.eq(0),
+ If(self.sink.stb & ~tx_busy & ~self.sink.ack,
+ tx_reg.eq(self.sink.data),
+ tx_bitcount.eq(0),
+ tx_busy.eq(1),
+ pads.tx.eq(0)
+ ).Elif(uart_clk_txen & tx_busy,
+ tx_bitcount.eq(tx_bitcount + 1),
+ If(tx_bitcount == 8,
+ pads.tx.eq(1)
+ ).Elif(tx_bitcount == 9,
+ pads.tx.eq(1),
+ tx_busy.eq(0),
+ self.sink.ack.eq(1),
+ ).Else(
+ pads.tx.eq(tx_reg[0]),
+ tx_reg.eq(Cat(tx_reg[1:], 0))
+ )
+ )
+ ]
+ self.sync += [
+ If(tx_busy,
+ Cat(phase_accumulator_tx, uart_clk_txen).eq(phase_accumulator_tx + tuning_word)
+ ).Else(
+ Cat(phase_accumulator_tx, uart_clk_txen).eq(0)
+ )
+ ]
+
+
+class RS232PHY(Module, AutoCSR):
+ def __init__(self, pads, clk_freq, baudrate=115200):
+ self._tuning_word = CSRStorage(32, reset=int((baudrate/clk_freq)*2**32))
+ self.submodules.tx = RS232PHYTX(pads, self._tuning_word.storage)
+ self.submodules.rx = RS232PHYRX(pads, self._tuning_word.storage)
+ self.sink, self.source = self.tx.sink, self.rx.source
+
+
+def _get_uart_fifo(depth, sink_cd="sys", source_cd="sys"):
+ if sink_cd != source_cd:
+ fifo = AsyncFIFO([("data", 8)], depth)
+ return ClockDomainsRenamer({"write": sink_cd, "read": source_cd})(fifo)
+ else:
+ return SyncFIFO([("data", 8)], depth)
+
+
+class UART(Module, AutoCSR):
+ def __init__(self, phy,
+ tx_fifo_depth=16,
+ rx_fifo_depth=16,
+ phy_cd="sys"):
+ self._rxtx = CSR(8)
+ self._txfull = CSRStatus()
+ self._rxempty = CSRStatus()
+
+ self.submodules.ev = EventManager()
+ self.ev.tx = EventSourceProcess()
+ self.ev.rx = EventSourceProcess()
+ self.ev.finalize()
+
+ # # #
+
+ # TX
+ tx_fifo = _get_uart_fifo(tx_fifo_depth, source_cd=phy_cd)
+ self.submodules += tx_fifo
+
+ self.comb += [
+ tx_fifo.sink.stb.eq(self._rxtx.re),
+ tx_fifo.sink.data.eq(self._rxtx.r),
+ self._txfull.status.eq(~tx_fifo.sink.ack),
+ Record.connect(tx_fifo.source, phy.sink),
+ # Generate TX IRQ when tx_fifo becomes non-full
+ self.ev.tx.trigger.eq(~tx_fifo.sink.ack)
+ ]
+
+ # RX
+ rx_fifo = _get_uart_fifo(rx_fifo_depth, sink_cd=phy_cd)
+ self.submodules += rx_fifo
+
+ self.comb += [
+ Record.connect(phy.source, rx_fifo.sink),
+ self._rxempty.status.eq(~rx_fifo.source.stb),
+ self._rxtx.w.eq(rx_fifo.source.data),
+ rx_fifo.source.ack.eq(self.ev.rx.clear),
+ # Generate RX IRQ when tx_fifo becomes non-empty
+ self.ev.rx.trigger.eq(~rx_fifo.source.stb)
+ ]
--- /dev/null
+from litex.soc.integration.soc_core import SoCCore
+from litex.soc.integration.soc_sdram import SoCSDRAM
--- /dev/null
+import os
+import subprocess
+import struct
+
+from litex.soc.integration import cpu_interface, soc_sdram, sdram_init
+
+
+__all__ = ["soc_software_packages", "soc_directory",
+ "Builder", "builder_args", "builder_argdict"]
+
+
+# in build order (for dependencies)
+soc_software_packages = [
+ "libbase",
+ "libcompiler_rt",
+ "libdyld",
+ "libnet",
+ "libunwind",
+ "bios"
+]
+
+
+soc_directory = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
+
+
+def _makefile_escape(s):
+ return s.replace("\\", "\\\\")
+
+
+class Builder:
+ def __init__(self, soc, output_dir=None,
+ compile_software=True, compile_gateware=True,
+ gateware_toolchain_path=None,
+ csr_csv=None):
+ self.soc = soc
+ if output_dir is None:
+ output_dir = "soc_{}_{}".format(
+ soc.__class__.__name__.lower(),
+ soc.platform.name)
+ # From Python doc: makedirs() will become confused if the path
+ # elements to create include '..'
+ self.output_dir = os.path.abspath(output_dir)
+ self.compile_software = compile_software
+ self.compile_gateware = compile_gateware
+ self.gateware_toolchain_path = gateware_toolchain_path
+ self.csr_csv = csr_csv
+
+ self.software_packages = []
+ for name in soc_software_packages:
+ self.add_software_package(
+ name, os.path.join(soc_directory, "software", name))
+
+ def add_software_package(self, name, src_dir):
+ self.software_packages.append((name, src_dir))
+
+ def _generate_includes(self):
+ cpu_type = self.soc.cpu_type
+ memory_regions = self.soc.get_memory_regions()
+ flash_boot_address = getattr(self.soc, "flash_boot_address", None)
+ csr_regions = self.soc.get_csr_regions()
+ constants = self.soc.get_constants()
+ if isinstance(self.soc, soc_sdram.SoCSDRAM) and self.soc._sdram_phy:
+ sdram_phy_settings = self.soc._sdram_phy[0].settings
+ else:
+ sdram_phy_settings = None
+
+ buildinc_dir = os.path.join(self.output_dir, "software", "include")
+ generated_dir = os.path.join(buildinc_dir, "generated")
+ os.makedirs(generated_dir, exist_ok=True)
+ with open(os.path.join(generated_dir, "variables.mak"), "w") as f:
+ def define(k, v):
+ f.write("{}={}\n".format(k, _makefile_escape(v)))
+ for k, v in cpu_interface.get_cpu_mak(cpu_type):
+ define(k, v)
+ define("SOC_DIRECTORY", soc_directory)
+ define("BUILDINC_DIRECTORY", buildinc_dir)
+ for name, src_dir in self.software_packages:
+ define(name.upper() + "_DIRECTORY", src_dir)
+
+ with open(os.path.join(generated_dir, "output_format.ld"), "w") as f:
+ f.write(cpu_interface.get_linker_output_format(cpu_type))
+ with open(os.path.join(generated_dir, "regions.ld"), "w") as f:
+ f.write(cpu_interface.get_linker_regions(memory_regions))
+
+ with open(os.path.join(generated_dir, "mem.h"), "w") as f:
+ f.write(cpu_interface.get_mem_header(memory_regions, flash_boot_address))
+ with open(os.path.join(generated_dir, "csr.h"), "w") as f:
+ f.write(cpu_interface.get_csr_header(csr_regions, constants))
+
+ if sdram_phy_settings is not None:
+ with open(os.path.join(generated_dir, "sdram_phy.h"), "w") as f:
+ f.write(sdram_init.get_sdram_phy_header(sdram_phy_settings))
+
+ if self.csr_csv is not None:
+ with open(self.csr_csv, "w") as f:
+ f.write(cpu_interface.get_csr_csv(csr_regions))
+
+ def _generate_software(self):
+ for name, src_dir in self.software_packages:
+ dst_dir = os.path.join(self.output_dir, "software", name)
+ os.makedirs(dst_dir, exist_ok=True)
+ src = os.path.join(src_dir, "Makefile")
+ dst = os.path.join(dst_dir, "Makefile")
+ try:
+ os.remove(dst)
+ except FileNotFoundError:
+ pass
+ os.symlink(src, dst)
+ if self.compile_software:
+ subprocess.check_call(["make", "-C", dst_dir])
+
+ def _initialize_rom(self):
+ bios_file = os.path.join(self.output_dir, "software", "bios",
+ "bios.bin")
+ if self.soc.integrated_rom_size:
+ with open(bios_file, "rb") as boot_file:
+ boot_data = []
+ while True:
+ w = boot_file.read(4)
+ if not w:
+ break
+ boot_data.append(struct.unpack(">I", w)[0])
+ self.soc.initialize_rom(boot_data)
+
+ def build(self):
+ self.soc.finalize()
+
+ if self.soc.integrated_rom_size and not self.compile_software:
+ raise ValueError("Software must be compiled in order to "
+ "intitialize integrated ROM")
+
+ self._generate_includes()
+ self._generate_software()
+ self._initialize_rom()
+ if self.gateware_toolchain_path is None:
+ kwargs = dict()
+ else:
+ kwargs = {"toolchain_path": self.gateware_toolchain_path}
+ self.soc.build(build_dir=os.path.join(self.output_dir, "gateware"),
+ run=self.compile_gateware, **kwargs)
+
+
+def builder_args(parser):
+ parser.add_argument("--output-dir", default=None,
+ help="output directory for generated "
+ "source files and binaries")
+ parser.add_argument("--no-compile-software", action="store_true",
+ help="do not compile the software, only generate "
+ "build infrastructure")
+ parser.add_argument("--no-compile-gateware", action="store_true",
+ help="do not compile the gateware, only generate "
+ "HDL source files and build scripts")
+ parser.add_argument("--gateware-toolchain-path", default=None,
+ help="set gateware toolchain (ISE, Quartus, etc.) "
+ "installation path")
+ parser.add_argument("--csr-csv", default=None,
+ help="store CSR map in CSV format into the "
+ "specified file")
+
+
+def builder_argdict(args):
+ return {
+ "output_dir": args.output_dir,
+ "compile_software": not args.no_compile_software,
+ "compile_gateware": not args.no_compile_gateware,
+ "gateware_toolchain_path": args.gateware_toolchain_path,
+ "csr_csv": args.csr_csv
+ }
--- /dev/null
+from litex.gen import *
+
+from litex.soc.interconnect.csr import CSRStatus
+
+
+def get_cpu_mak(cpu):
+ if cpu == "lm32":
+ triple = "lm32-elf"
+ cpuflags = "-mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled"
+ clang = ""
+ elif cpu == "or1k":
+ triple = "or1k-linux"
+ cpuflags = "-mhard-mul -mhard-div -mror -mffl1 -maddc"
+ clang = "1"
+ else:
+ raise ValueError("Unsupported CPU type: "+cpu)
+ return [
+ ("TRIPLE", triple),
+ ("CPU", cpu),
+ ("CPUFLAGS", cpuflags),
+ ("CLANG", clang)
+ ]
+
+
+def get_linker_output_format(cpu_type):
+ return "OUTPUT_FORMAT(\"elf32-{}\")\n".format(cpu_type)
+
+
+def get_linker_regions(regions):
+ r = "MEMORY {\n"
+ for name, origin, length in regions:
+ r += "\t{} : ORIGIN = 0x{:08x}, LENGTH = 0x{:08x}\n".format(name, origin, length)
+ r += "}\n"
+ return r
+
+
+def get_mem_header(regions, flash_boot_address):
+ r = "#ifndef __GENERATED_MEM_H\n#define __GENERATED_MEM_H\n\n"
+ for name, base, size in regions:
+ r += "#define {name}_BASE 0x{base:08x}\n#define {name}_SIZE 0x{size:08x}\n\n".format(name=name.upper(), base=base, size=size)
+ if flash_boot_address is not None:
+ r += "#define FLASH_BOOT_ADDRESS 0x{:08x}\n\n".format(flash_boot_address)
+ r += "#endif\n"
+ return r
+
+
+def _get_rw_functions(reg_name, reg_base, nwords, busword, read_only, with_access_functions):
+ r = ""
+
+ r += "#define CSR_"+reg_name.upper()+"_ADDR "+hex(reg_base)+"\n"
+ r += "#define CSR_"+reg_name.upper()+"_SIZE "+str(nwords)+"\n"
+
+ size = nwords*busword
+ if size > 64:
+ return r
+ elif size > 32:
+ ctype = "unsigned long long int"
+ elif size > 16:
+ ctype = "unsigned int"
+ elif size > 8:
+ ctype = "unsigned short int"
+ else:
+ ctype = "unsigned char"
+
+ if with_access_functions:
+ r += "static inline "+ctype+" "+reg_name+"_read(void) {\n"
+ if size > 1:
+ r += "\t"+ctype+" r = MMPTR("+hex(reg_base)+");\n"
+ for byte in range(1, nwords):
+ r += "\tr <<= "+str(busword)+";\n\tr |= MMPTR("+hex(reg_base+4*byte)+");\n"
+ r += "\treturn r;\n}\n"
+ else:
+ r += "\treturn MMPTR("+hex(reg_base)+");\n}\n"
+
+ if not read_only:
+ r += "static inline void "+reg_name+"_write("+ctype+" value) {\n"
+ for word in range(nwords):
+ shift = (nwords-word-1)*busword
+ if shift:
+ value_shifted = "value >> "+str(shift)
+ else:
+ value_shifted = "value"
+ r += "\tMMPTR("+hex(reg_base+4*word)+") = "+value_shifted+";\n"
+ r += "}\n"
+ return r
+
+
+def get_csr_header(regions, constants, with_access_functions=True):
+ r = "#ifndef __GENERATED_CSR_H\n#define __GENERATED_CSR_H\n"
+ if with_access_functions:
+ r += "#include <hw/common.h>\n"
+ for name, origin, busword, obj in regions:
+ if isinstance(obj, Memory):
+ r += "#define CSR_"+name.upper()+"_BASE "+hex(origin)+"\n"
+ else:
+ r += "\n/* "+name+" */\n"
+ r += "#define CSR_"+name.upper()+"_BASE "+hex(origin)+"\n"
+ for csr in obj:
+ nr = (csr.size + busword - 1)//busword
+ r += _get_rw_functions(name + "_" + csr.name, origin, nr, busword, isinstance(csr, CSRStatus), with_access_functions)
+ origin += 4*nr
+
+ r += "\n/* constants */\n"
+ for name, value in constants:
+ r += "#define " + name
+ if value is not None:
+ if isinstance(value, str):
+ r += " \"" + value + "\""
+ else:
+ r += " " + str(value)
+ r += "\n"
+
+ r += "\n#endif\n"
+ return r
+
+
+def get_csr_csv(regions):
+ r = ""
+ for name, origin, busword, obj in regions:
+ if not isinstance(obj, Memory):
+ for csr in obj:
+ nr = (csr.size + busword - 1)//busword
+ r += "{}_{},0x{:08x},{},{}\n".format(name, csr.name, origin, nr, "ro" if isinstance(csr, CSRStatus) else "rw")
+ origin += 4*nr
+ return r
--- /dev/null
+from litex.gen import log2_int
+
+
+def get_sdram_phy_header(sdram_phy_settings):
+ r = "#ifndef __GENERATED_SDRAM_PHY_H\n#define __GENERATED_SDRAM_PHY_H\n"
+ r += "#include <hw/common.h>\n#include <generated/csr.h>\n#include <hw/flags.h>\n\n"
+
+ nphases = sdram_phy_settings.nphases
+ r += "#define DFII_NPHASES "+str(nphases)+"\n\n"
+
+ r += "static void cdelay(int i);\n"
+
+ # commands_px functions
+ for n in range(nphases):
+ r += """
+static void command_p{n}(int cmd)
+{{
+ sdram_dfii_pi{n}_command_write(cmd);
+ sdram_dfii_pi{n}_command_issue_write(1);
+}}""".format(n=str(n))
+ r += "\n\n"
+
+ # rd/wr access macros
+ r += """
+#define sdram_dfii_pird_address_write(X) sdram_dfii_pi{rdphase}_address_write(X)
+#define sdram_dfii_piwr_address_write(X) sdram_dfii_pi{wrphase}_address_write(X)
+
+#define sdram_dfii_pird_baddress_write(X) sdram_dfii_pi{rdphase}_baddress_write(X)
+#define sdram_dfii_piwr_baddress_write(X) sdram_dfii_pi{wrphase}_baddress_write(X)
+
+#define command_prd(X) command_p{rdphase}(X)
+#define command_pwr(X) command_p{wrphase}(X)
+""".format(rdphase=str(sdram_phy_settings.rdphase), wrphase=str(sdram_phy_settings.wrphase))
+ r += "\n"
+
+ #
+ # sdrrd/sdrwr functions utilities
+ #
+ r += "#define DFII_PIX_DATA_SIZE CSR_SDRAM_DFII_PI0_WRDATA_SIZE\n"
+ sdram_dfii_pix_wrdata_addr = []
+ for n in range(nphases):
+ sdram_dfii_pix_wrdata_addr.append("CSR_SDRAM_DFII_PI{n}_WRDATA_ADDR".format(n=n))
+ r += """
+const unsigned int sdram_dfii_pix_wrdata_addr[{n}] = {{
+ {sdram_dfii_pix_wrdata_addr}
+}};
+""".format(n=nphases, sdram_dfii_pix_wrdata_addr=",\n\t".join(sdram_dfii_pix_wrdata_addr))
+
+ sdram_dfii_pix_rddata_addr = []
+ for n in range(nphases):
+ sdram_dfii_pix_rddata_addr.append("CSR_SDRAM_DFII_PI{n}_RDDATA_ADDR".format(n=n))
+ r += """
+const unsigned int sdram_dfii_pix_rddata_addr[{n}] = {{
+ {sdram_dfii_pix_rddata_addr}
+}};
+""".format(n=nphases, sdram_dfii_pix_rddata_addr=",\n\t".join(sdram_dfii_pix_rddata_addr))
+ r += "\n"
+
+ # init sequence
+ cmds = {
+ "PRECHARGE_ALL": "DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
+ "MODE_REGISTER": "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
+ "AUTO_REFRESH": "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS",
+ "UNRESET": "DFII_CONTROL_ODT|DFII_CONTROL_RESET_N",
+ "CKE": "DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N"
+ }
+
+ cl = sdram_phy_settings.cl
+
+ if sdram_phy_settings.memtype == "SDR":
+ bl = sdram_phy_settings.nphases
+ mr = log2_int(bl) + (cl << 4)
+ reset_dll = 1 << 8
+
+ init_sequence = [
+ ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
+ ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
+ ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
+ ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
+ ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
+ ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
+ ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
+ ]
+
+ elif sdram_phy_settings.memtype == "DDR":
+ bl = 2*sdram_phy_settings.nphases
+ mr = log2_int(bl) + (cl << 4)
+ emr = 0
+ reset_dll = 1 << 8
+
+ init_sequence = [
+ ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
+ ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
+ ("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
+ ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
+ ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
+ ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
+ ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
+ ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
+ ]
+
+ elif sdram_phy_settings.memtype == "LPDDR":
+ bl = 2*sdram_phy_settings.nphases
+ mr = log2_int(bl) + (cl << 4)
+ emr = 0
+ reset_dll = 1 << 8
+
+ init_sequence = [
+ ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
+ ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
+ ("Load Extended Mode Register", emr, 2, cmds["MODE_REGISTER"], 0),
+ ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
+ ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
+ ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
+ ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
+ ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
+ ]
+
+ elif sdram_phy_settings.memtype == "DDR2":
+ bl = 2*sdram_phy_settings.nphases
+ wr = 2
+ mr = log2_int(bl) + (cl << 4) + (wr << 9)
+ emr = 0
+ emr2 = 0
+ emr3 = 0
+ reset_dll = 1 << 8
+ ocd = 7 << 7
+
+ init_sequence = [
+ ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
+ ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
+ ("Load Extended Mode Register 3", emr3, 3, cmds["MODE_REGISTER"], 0),
+ ("Load Extended Mode Register 2", emr2, 2, cmds["MODE_REGISTER"], 0),
+ ("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
+ ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
+ ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
+ ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
+ ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
+ ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200),
+ ("Load Extended Mode Register / OCD Default", emr+ocd, 1, cmds["MODE_REGISTER"], 0),
+ ("Load Extended Mode Register / OCD Exit", emr, 1, cmds["MODE_REGISTER"], 0),
+ ]
+ elif sdram_phy_settings.memtype == "DDR3":
+ bl = 2*sdram_phy_settings.nphases
+
+ def format_mr0(bl, cl, wr, dll_reset):
+ bl_to_mr0 = {
+ 4: 0b10,
+ 8: 0b00
+ }
+ cl_to_mr0 = {
+ 5: 0b0010,
+ 6: 0b0100,
+ 7: 0b0110,
+ 8: 0b1000,
+ 9: 0b1010,
+ 10: 0b1100,
+ 11: 0b1110,
+ 12: 0b0001,
+ 13: 0b0011,
+ 14: 0b0101
+ }
+ wr_to_mr0 = {
+ 16: 0b000,
+ 5: 0b001,
+ 6: 0b010,
+ 7: 0b011,
+ 8: 0b100,
+ 10: 0b101,
+ 12: 0b110,
+ 14: 0b111
+ }
+ mr0 = bl_to_mr0[bl]
+ mr0 |= (cl_to_mr0[cl] & 1) << 2
+ mr0 |= ((cl_to_mr0[cl] >> 1) & 0b111) << 4
+ mr0 |= dll_reset << 8
+ mr0 |= wr_to_mr0[wr] << 9
+ return mr0
+
+ def format_mr1(output_drive_strength, rtt_nom):
+ mr1 = ((output_drive_strength >> 0) & 1) << 1
+ mr1 |= ((output_drive_strength >> 1) & 1) << 5
+ mr1 |= ((rtt_nom >> 0) & 1) << 2
+ mr1 |= ((rtt_nom >> 1) & 1) << 6
+ mr1 |= ((rtt_nom >> 2) & 1) << 9
+ return mr1
+
+ def format_mr2(cwl, rtt_wr):
+ mr2 = (cwl-5) << 3
+ mr2 |= rtt_wr << 9
+ return mr2
+
+ mr0 = format_mr0(bl, cl, 8, 1) # wr=8 FIXME: this should be ceiling(tWR/tCK)
+ mr1 = format_mr1(1, 1) # Output Drive Strength RZQ/7 (34 ohm) / Rtt RZQ/4 (60 ohm)
+ mr2 = format_mr2(sdram_phy_settings.cwl, 2) # Rtt(WR) RZQ/4
+ mr3 = 0
+
+ init_sequence = [
+ ("Release reset", 0x0000, 0, cmds["UNRESET"], 50000),
+ ("Bring CKE high", 0x0000, 0, cmds["CKE"], 10000),
+ ("Load Mode Register 2", mr2, 2, cmds["MODE_REGISTER"], 0),
+ ("Load Mode Register 3", mr3, 3, cmds["MODE_REGISTER"], 0),
+ ("Load Mode Register 1", mr1, 1, cmds["MODE_REGISTER"], 0),
+ ("Load Mode Register 0, CL={0:d}, BL={1:d}".format(cl, bl), mr0, 0, cmds["MODE_REGISTER"], 200),
+ ("ZQ Calibration", 0x0400, 0, "DFII_COMMAND_WE|DFII_COMMAND_CS", 200),
+ ]
+
+ # the value of MR1 needs to be modified during write leveling
+ r += "#define DDR3_MR1 {}\n\n".format(mr1)
+ else:
+ raise NotImplementedError("Unsupported memory type: "+sdram_phy_settings.memtype)
+
+ r += "static void init_sequence(void)\n{\n"
+ for comment, a, ba, cmd, delay in init_sequence:
+ r += "\t/* {0} */\n".format(comment)
+ r += "\tsdram_dfii_pi0_address_write({0:#x});\n".format(a)
+ r += "\tsdram_dfii_pi0_baddress_write({0:d});\n".format(ba)
+ if cmd[:12] == "DFII_CONTROL":
+ r += "\tsdram_dfii_control_write({0});\n".format(cmd)
+ else:
+ r += "\tcommand_p0({0});\n".format(cmd)
+ if delay:
+ r += "\tcdelay({0:d});\n".format(delay)
+ r += "\n"
+ r += "}\n"
+
+ r += "#endif\n"
+
+ return r
--- /dev/null
+from operator import itemgetter
+
+from litex.gen import *
+
+from litex.soc.cores import identifier, timer, uart
+from litex.soc.cores.cpu import lm32, mor1kx
+from litex.soc.interconnect import wishbone, csr_bus, wishbone2csr
+
+
+__all__ = ["mem_decoder", "SoCCore", "soc_core_args", "soc_core_argdict"]
+
+
+def mem_decoder(address, start=26, end=29):
+ return lambda a: a[start:end] == ((address >> (start+2)) & (2**(end-start))-1)
+
+
+class SoCCore(Module):
+ csr_map = {
+ "crg": 0, # user
+ "uart_phy": 1, # provided by default (optional)
+ "uart": 2, # provided by default (optional)
+ "identifier": 3, # provided by default (optional)
+ "timer0": 4, # provided by default (optional)
+ "buttons": 5, # user
+ "leds": 6, # user
+ }
+ interrupt_map = {
+ "uart": 0,
+ "timer0": 1,
+ }
+ mem_map = {
+ "rom": 0x00000000, # (default shadow @0x80000000)
+ "sram": 0x10000000, # (default shadow @0x90000000)
+ "main_ram": 0x40000000, # (default shadow @0xc0000000)
+ "csr": 0x60000000, # (default shadow @0xe0000000)
+ }
+ def __init__(self, platform, clk_freq,
+ cpu_type="lm32", cpu_reset_address=0x00000000,
+ integrated_rom_size=0,
+ integrated_sram_size=4096,
+ integrated_main_ram_size=0,
+ shadow_base=0x80000000,
+ csr_data_width=8, csr_address_width=14,
+ with_uart=True, uart_baudrate=115200,
+ with_identifier=True,
+ with_timer=True):
+ self.platform = platform
+ self.clk_freq = clk_freq
+
+ self.cpu_type = cpu_type
+ if integrated_rom_size:
+ cpu_reset_address = 0
+ self.cpu_reset_address = cpu_reset_address
+
+ self.integrated_rom_size = integrated_rom_size
+ self.integrated_sram_size = integrated_sram_size
+ self.integrated_main_ram_size = integrated_main_ram_size
+
+ self.with_uart = with_uart
+ self.uart_baudrate = uart_baudrate
+
+ self.with_identifier = with_identifier
+
+ self.shadow_base = shadow_base
+
+ self.csr_data_width = csr_data_width
+ self.csr_address_width = csr_address_width
+
+ self._memory_regions = [] # list of (name, origin, length)
+ self._csr_regions = [] # list of (name, origin, busword, csr_list/Memory)
+ self._constants = [] # list of (name, value)
+
+ self._wb_masters = []
+ self._wb_slaves = []
+
+ if cpu_type == "lm32":
+ self.submodules.cpu = lm32.LM32(platform, self.cpu_reset_address)
+ elif cpu_type == "or1k":
+ self.submodules.cpu = mor1kx.MOR1KX(platform, self.cpu_reset_address)
+ else:
+ raise ValueError("Unsupported CPU type: {}".format(cpu_type))
+ self.add_wb_master(self.cpu.ibus)
+ self.add_wb_master(self.cpu.dbus)
+
+ if integrated_rom_size:
+ self.submodules.rom = wishbone.SRAM(integrated_rom_size, read_only=True)
+ self.register_rom(self.rom.bus, integrated_rom_size)
+
+ if integrated_sram_size:
+ self.submodules.sram = wishbone.SRAM(integrated_sram_size)
+ self.register_mem("sram", self.mem_map["sram"], self.sram.bus, integrated_sram_size)
+
+ # Note: Main Ram can be used when no external SDRAM is available and use SDRAM mapping.
+ if integrated_main_ram_size:
+ self.submodules.main_ram = wishbone.SRAM(integrated_main_ram_size)
+ self.register_mem("main_ram", self.mem_map["main_ram"], self.main_ram.bus, integrated_main_ram_size)
+
+ self.submodules.wishbone2csr = wishbone2csr.WB2CSR(
+ bus_csr=csr_bus.Interface(csr_data_width, csr_address_width))
+ self.register_mem("csr", self.mem_map["csr"], self.wishbone2csr.wishbone)
+
+ if with_uart:
+ self.submodules.uart_phy = uart.RS232PHY(platform.request("serial"), clk_freq, uart_baudrate)
+ self.submodules.uart = uart.UART(self.uart_phy)
+
+ if with_identifier:
+ platform_id = 0x554E if not hasattr(platform, "identifier") else platform.identifier
+ self.submodules.identifier = identifier.Identifier(platform_id, int(clk_freq))
+
+ if with_timer:
+ self.submodules.timer0 = timer.Timer()
+
+ def initialize_rom(self, data):
+ self.rom.mem.init = data
+
+ def add_wb_master(self, wbm):
+ if self.finalized:
+ raise FinalizeError
+ self._wb_masters.append(wbm)
+
+ def add_wb_slave(self, address_decoder, interface):
+ if self.finalized:
+ raise FinalizeError
+ self._wb_slaves.append((address_decoder, interface))
+
+ def add_memory_region(self, name, origin, length):
+ def in_this_region(addr):
+ return addr >= origin and addr < origin + length
+ for n, o, l in self._memory_regions:
+ if n == name or in_this_region(o) or in_this_region(o+l-1):
+ raise ValueError("Memory region conflict between {} and {}".format(n, name))
+
+ self._memory_regions.append((name, origin, length))
+
+ def register_mem(self, name, address, interface, size=None):
+ self.add_wb_slave(mem_decoder(address), interface)
+ if size is not None:
+ self.add_memory_region(name, address, size)
+
+ def register_rom(self, interface, rom_size=0xa000):
+ self.add_wb_slave(mem_decoder(self.mem_map["rom"]), interface)
+ self.add_memory_region("rom", self.cpu_reset_address, rom_size)
+
+ def get_memory_regions(self):
+ return self._memory_regions
+
+ def check_csr_region(self, name, origin):
+ for n, o, l, obj in self._csr_regions:
+ if n == name or o == origin:
+ raise ValueError("CSR region conflict between {} and {}".format(n, name))
+
+ def add_csr_region(self, name, origin, busword, obj):
+ self.check_csr_region(name, origin)
+ self._csr_regions.append((name, origin, busword, obj))
+
+ def get_csr_regions(self):
+ return self._csr_regions
+
+ def add_constant(self, name, value=None):
+ self._constants.append((name, value))
+
+ def get_constants(self):
+ r = []
+ for name, interrupt in sorted(self.interrupt_map.items(), key=itemgetter(1)):
+ r.append((name.upper() + "_INTERRUPT", interrupt))
+ r += self._constants
+ return r
+
+ def do_finalize(self):
+ registered_mems = {regions[0] for regions in self._memory_regions}
+ for mem in "rom", "sram":
+ if mem not in registered_mems:
+ raise FinalizeError("CPU needs a {} to be registered with register_mem()".format(mem))
+
+ # Wishbone
+ self.submodules.wishbonecon = wishbone.InterconnectShared(self._wb_masters,
+ self._wb_slaves, register=True)
+
+ # CSR
+ self.submodules.csrbankarray = csr_bus.CSRBankArray(self,
+ lambda name, memory: self.csr_map[name if memory is None else name + "_" + memory.name_override],
+ data_width=self.csr_data_width, address_width=self.csr_address_width)
+ self.submodules.csrcon = csr_bus.Interconnect(
+ self.wishbone2csr.csr, self.csrbankarray.get_buses())
+ for name, csrs, mapaddr, rmap in self.csrbankarray.banks:
+ self.add_csr_region(name, (self.mem_map["csr"] + 0x800*mapaddr) | self.shadow_base, self.csr_data_width, csrs)
+ for name, memory, mapaddr, mmap in self.csrbankarray.srams:
+ self.add_csr_region(name + "_" + memory.name_override, (self.mem_map["csr"] + 0x800*mapaddr) | self.shadow_base, self.csr_data_width, memory)
+
+ # Interrupts
+ for k, v in sorted(self.interrupt_map.items(), key=itemgetter(1)):
+ if hasattr(self, k):
+ self.comb += self.cpu.interrupt[v].eq(getattr(self, k).ev.irq)
+
+ def build(self, *args, **kwargs):
+ self.platform.build(self, *args, **kwargs)
+
+
+def soc_core_args(parser):
+ parser.add_argument("--cpu-type", default=None,
+ help="select CPU: lm32, or1k")
+ parser.add_argument("--integrated-rom-size", default=None, type=int,
+ help="size/enable the integrated (BIOS) ROM")
+ parser.add_argument("--integrated-main-ram-size", default=None, type=int,
+ help="size/enable the integrated main RAM")
+
+
+def soc_core_argdict(args):
+ r = dict()
+ for a in "cpu_type", "integrated_rom_size", "integrated_main_ram_size":
+ arg = getattr(args, a)
+ if arg is not None:
+ r[a] = arg
+ return r
--- /dev/null
+from litex.gen import *
+from litex.gen.genlib.record import *
+
+from litex.soc.interconnect import wishbone, wishbone2lasmi, lasmi_bus
+from litex.soc.interconnect.csr import AutoCSR
+from litex.soc.cores.sdram import dfii, minicon, lasmicon
+from litex.soc.integration.soc_core import *
+
+
+__all__ = ["SoCSDRAM", "soc_sdram_args", "soc_sdram_argdict"]
+
+
+class ControllerInjector(Module, AutoCSR):
+ def __init__(self, phy, controller_type, geom_settings, timing_settings):
+ self.submodules.dfii = dfii.DFIInjector(geom_settings.addressbits, geom_settings.bankbits,
+ phy.settings.dfi_databits, phy.settings.nphases)
+ self.comb += Record.connect(self.dfii.master, phy.dfi)
+
+ if controller_type == "lasmicon":
+ self.submodules.controller = controller = lasmicon.LASMIcon(phy.settings,
+ geom_settings,
+ timing_settings)
+ self.comb += Record.connect(controller.dfi, self.dfii.slave)
+
+ self.submodules.crossbar = lasmi_bus.LASMIxbar([controller.lasmic],
+ controller.nrowbits)
+ elif controller_type == "minicon":
+ self.submodules.controller = controller = minicon.Minicon(phy.settings,
+ geom_settings,
+ timing_settings)
+ self.comb += Record.connect(controller.dfi, self.dfii.slave)
+ else:
+ raise ValueError("Unsupported SDRAM controller type")
+
+
+class SoCSDRAM(SoCCore):
+ csr_map = {
+ "sdram": 8,
+ "l2_cache": 9
+ }
+ csr_map.update(SoCCore.csr_map)
+
+ def __init__(self, platform, clk_freq, l2_size=8192, **kwargs):
+ SoCCore.__init__(self, platform, clk_freq, **kwargs)
+ self.l2_size = l2_size
+
+ self._sdram_phy = []
+ self._wb_sdram_ifs = []
+ self._wb_sdram = wishbone.Interface()
+
+ def add_wb_sdram_if(self, interface):
+ if self.finalized:
+ raise FinalizeError
+ self._wb_sdram_ifs.append(interface)
+
+ def register_sdram(self, phy, sdram_controller_type, geom_settings, timing_settings):
+ assert not self._sdram_phy
+ self._sdram_phy.append(phy) # encapsulate in list to prevent CSR scanning
+
+ self.submodules.sdram = ControllerInjector(
+ phy, sdram_controller_type, geom_settings, timing_settings)
+
+ dfi_databits_divisor = 1 if phy.settings.memtype == "SDR" else 2
+ sdram_width = phy.settings.dfi_databits//dfi_databits_divisor
+ main_ram_size = 2**(geom_settings.bankbits +
+ geom_settings.rowbits +
+ geom_settings.colbits)*sdram_width//8
+ # XXX: Limit main_ram_size to 256MB, we should modify mem_map to allow larger memories.
+ main_ram_size = min(main_ram_size, 256*1024*1024)
+ if self.l2_size:
+ self.add_constant("L2_SIZE", self.l2_size)
+
+ # add a Wishbone interface to the DRAM
+ wb_sdram = wishbone.Interface()
+ self.add_wb_sdram_if(wb_sdram)
+ self.register_mem("main_ram", self.mem_map["main_ram"], wb_sdram, main_ram_size)
+
+ if sdram_controller_type == "lasmicon":
+ if self.l2_size:
+ lasmim = self.sdram.crossbar.get_master()
+ l2_cache = wishbone.Cache(self.l2_size//4, self._wb_sdram, wishbone.Interface(lasmim.dw))
+ # XXX Vivado ->2015.1 workaround, Vivado is not able to map correctly our L2 cache.
+ # Issue is reported to Xilinx and should be fixed in next releases (2015.2?).
+ # Remove this workaround when fixed by Xilinx.
+ from litex.build.xilinx.vivado import XilinxVivadoToolchain
+ if isinstance(self.platform.toolchain, XilinxVivadoToolchain):
+ from litex.gen.fhdl.simplify import FullMemoryWE
+ self.submodules.l2_cache = FullMemoryWE()(l2_cache)
+ else:
+ self.submodules.l2_cache = l2_cache
+ self.submodules.wishbone2lasmi = wishbone2lasmi.WB2LASMI(self.l2_cache.slave, lasmim)
+ elif sdram_controller_type == "minicon":
+ if self.l2_size:
+ l2_cache = wishbone.Cache(self.l2_size//4, self._wb_sdram, self.sdram.controller.bus)
+ # XXX Vivado ->2015.1 workaround, Vivado is not able to map correctly our L2 cache.
+ # Issue is reported to Xilinx and should be fixed in next releases (2015.2?).
+ # Remove this workaround when fixed by Xilinx.
+ from litex.build.xilinx.vivado import XilinxVivadoToolchain
+ if isinstance(self.platform.toolchain, XilinxVivadoToolchain):
+ from litex.gen.fhdl.simplify import FullMemoryWE
+ self.submodules.l2_cache = FullMemoryWE()(l2_cache)
+ else:
+ self.submodules.l2_cache = l2_cache
+ else:
+ self.submodules.converter = wishbone.Converter(self._wb_sdram, self.sdram.controller.bus)
+ else:
+ raise ValueError
+
+ def do_finalize(self):
+ if not self.integrated_main_ram_size:
+ if not self._sdram_phy:
+ raise FinalizeError("Need to call SDRAMSoC.register_sdram()")
+
+ # arbitrate wishbone interfaces to the DRAM
+ self.submodules.wb_sdram_con = wishbone.Arbiter(self._wb_sdram_ifs,
+ self._wb_sdram)
+ SoCCore.do_finalize(self)
+
+
+soc_sdram_args = soc_core_args
+soc_sdram_argdict = soc_core_argdict
--- /dev/null
+from litex.gen import *
+from litex.gen.util.misc import xdir
+from litex.gen.fhdl.tracer import get_obj_var_name
+
+
+class _CSRBase(DUID):
+ def __init__(self, size, name):
+ DUID.__init__(self)
+ self.name = get_obj_var_name(name)
+ if self.name is None:
+ raise ValueError("Cannot extract CSR name from code, need to specify.")
+ self.size = size
+
+
+class CSR(_CSRBase):
+ def __init__(self, size=1, name=None):
+ _CSRBase.__init__(self, size, name)
+ self.re = Signal(name=self.name + "_re")
+ self.r = Signal(self.size, name=self.name + "_r")
+ self.w = Signal(self.size, name=self.name + "_w")
+
+
+class _CompoundCSR(_CSRBase, Module):
+ def __init__(self, size, name):
+ _CSRBase.__init__(self, size, name)
+ self.simple_csrs = []
+
+ def get_simple_csrs(self):
+ if not self.finalized:
+ raise FinalizeError
+ return self.simple_csrs
+
+ def do_finalize(self, busword):
+ raise NotImplementedError
+
+
+class CSRStatus(_CompoundCSR):
+ def __init__(self, size=1, reset=0, name=None):
+ _CompoundCSR.__init__(self, size, name)
+ self.status = Signal(self.size, reset=reset)
+
+ def do_finalize(self, busword):
+ nwords = (self.size + busword - 1)//busword
+ for i in reversed(range(nwords)):
+ nbits = min(self.size - i*busword, busword)
+ sc = CSR(nbits, self.name + str(i) if nwords > 1 else self.name)
+ self.comb += sc.w.eq(self.status[i*busword:i*busword+nbits])
+ self.simple_csrs.append(sc)
+
+
+class CSRStorage(_CompoundCSR):
+ def __init__(self, size=1, reset=0, atomic_write=False, write_from_dev=False, alignment_bits=0, name=None):
+ _CompoundCSR.__init__(self, size, name)
+ self.alignment_bits = alignment_bits
+ self.storage_full = Signal(self.size, reset=reset)
+ self.storage = Signal(self.size - self.alignment_bits, reset=reset >> alignment_bits)
+ self.comb += self.storage.eq(self.storage_full[self.alignment_bits:])
+ self.atomic_write = atomic_write
+ self.re = Signal()
+ if write_from_dev:
+ self.we = Signal()
+ self.dat_w = Signal(self.size - self.alignment_bits)
+ self.sync += If(self.we, self.storage_full.eq(self.dat_w << self.alignment_bits))
+
+ def do_finalize(self, busword):
+ nwords = (self.size + busword - 1)//busword
+ if nwords > 1 and self.atomic_write:
+ backstore = Signal(self.size - busword, name=self.name + "_backstore")
+ for i in reversed(range(nwords)):
+ nbits = min(self.size - i*busword, busword)
+ sc = CSR(nbits, self.name + str(i) if nwords else self.name)
+ self.simple_csrs.append(sc)
+ lo = i*busword
+ hi = lo+nbits
+ # read
+ if lo >= self.alignment_bits:
+ self.comb += sc.w.eq(self.storage_full[lo:hi])
+ elif hi > self.alignment_bits:
+ self.comb += sc.w.eq(Cat(Replicate(0, hi - self.alignment_bits),
+ self.storage_full[self.alignment_bits:hi]))
+ else:
+ self.comb += sc.w.eq(0)
+ # write
+ if nwords > 1 and self.atomic_write:
+ if i:
+ self.sync += If(sc.re, backstore[lo-busword:hi-busword].eq(sc.r))
+ else:
+ self.sync += If(sc.re, self.storage_full.eq(Cat(sc.r, backstore)))
+ else:
+ self.sync += If(sc.re, self.storage_full[lo:hi].eq(sc.r))
+ self.sync += self.re.eq(sc.re)
+
+
+def csrprefix(prefix, csrs, done):
+ for csr in csrs:
+ if csr.duid not in done:
+ csr.name = prefix + csr.name
+ done.add(csr.duid)
+
+
+def memprefix(prefix, memories, done):
+ for memory in memories:
+ if memory.duid not in done:
+ memory.name_override = prefix + memory.name_override
+ done.add(memory.duid)
+
+
+def _make_gatherer(method, cls, prefix_cb):
+ def gatherer(self):
+ try:
+ exclude = self.autocsr_exclude
+ except AttributeError:
+ exclude = {}
+ try:
+ prefixed = self.__prefixed
+ except AttributeError:
+ prefixed = self.__prefixed = set()
+ r = []
+ for k, v in xdir(self, True):
+ if k not in exclude:
+ if isinstance(v, cls):
+ r.append(v)
+ elif hasattr(v, method) and callable(getattr(v, method)):
+ items = getattr(v, method)()
+ prefix_cb(k + "_", items, prefixed)
+ r += items
+ return sorted(r, key=lambda x: x.duid)
+ return gatherer
+
+
+class AutoCSR:
+ get_memories = _make_gatherer("get_memories", Memory, memprefix)
+ get_csrs = _make_gatherer("get_csrs", _CSRBase, csrprefix)
+
+
+class GenericBank(Module):
+ def __init__(self, description, busword):
+ # Turn description into simple CSRs and claim ownership of compound CSR modules
+ self.simple_csrs = []
+ for c in description:
+ if isinstance(c, CSR):
+ self.simple_csrs.append(c)
+ else:
+ c.finalize(busword)
+ self.simple_csrs += c.get_simple_csrs()
+ self.submodules += c
+ self.decode_bits = bits_for(len(self.simple_csrs)-1)
--- /dev/null
+from litex.gen import *
+from litex.gen.genlib.record import *
+from litex.gen.genlib.misc import chooser
+from litex.gen.util.misc import xdir
+
+from litex.soc.interconnect import csr
+from litex.soc.interconnect.csr import CSRStorage
+
+
+_layout = [
+ ("adr", "address_width", DIR_M_TO_S),
+ ("we", 1, DIR_M_TO_S),
+ ("dat_w", "data_width", DIR_M_TO_S),
+ ("dat_r", "data_width", DIR_S_TO_M)
+]
+
+
+class Interface(Record):
+ def __init__(self, data_width=8, address_width=14):
+ Record.__init__(self, set_layout_parameters(_layout,
+ data_width=data_width, address_width=address_width))
+
+
+class Interconnect(Module):
+ def __init__(self, master, slaves):
+ self.comb += master.connect(*slaves)
+
+
+class SRAM(Module):
+ def __init__(self, mem_or_size, address, read_only=None, init=None, bus=None):
+ if bus is None:
+ bus = Interface()
+ self.bus = bus
+ data_width = len(self.bus.dat_w)
+ if isinstance(mem_or_size, Memory):
+ mem = mem_or_size
+ else:
+ mem = Memory(data_width, mem_or_size//(data_width//8), init=init)
+ csrw_per_memw = (mem.width + data_width - 1)//data_width
+ word_bits = log2_int(csrw_per_memw)
+ page_bits = log2_int((mem.depth*csrw_per_memw + 511)//512, False)
+ if page_bits:
+ self._page = CSRStorage(page_bits, name=mem.name_override + "_page")
+ else:
+ self._page = None
+ if read_only is None:
+ if hasattr(mem, "bus_read_only"):
+ read_only = mem.bus_read_only
+ else:
+ read_only = False
+
+ ###
+
+ port = mem.get_port(write_capable=not read_only)
+ self.specials += mem, port
+
+ sel = Signal()
+ sel_r = Signal()
+ self.sync += sel_r.eq(sel)
+ self.comb += sel.eq(self.bus.adr[9:] == address)
+
+ if word_bits:
+ word_index = Signal(word_bits)
+ word_expanded = Signal(csrw_per_memw*data_width)
+ self.sync += word_index.eq(self.bus.adr[:word_bits])
+ self.comb += [
+ word_expanded.eq(port.dat_r),
+ If(sel_r,
+ chooser(word_expanded, word_index, self.bus.dat_r, n=csrw_per_memw, reverse=True)
+ )
+ ]
+ if not read_only:
+ wregs = []
+ for i in range(csrw_per_memw-1):
+ wreg = Signal(data_width)
+ self.sync += If(sel & self.bus.we & (self.bus.adr[:word_bits] == i), wreg.eq(self.bus.dat_w))
+ wregs.append(wreg)
+ memword_chunks = [self.bus.dat_w] + list(reversed(wregs))
+ self.comb += [
+ port.we.eq(sel & self.bus.we & (self.bus.adr[:word_bits] == csrw_per_memw - 1)),
+ port.dat_w.eq(Cat(*memword_chunks))
+ ]
+ else:
+ self.comb += If(sel_r, self.bus.dat_r.eq(port.dat_r))
+ if not read_only:
+ self.comb += [
+ port.we.eq(sel & self.bus.we),
+ port.dat_w.eq(self.bus.dat_w)
+ ]
+
+ if self._page is None:
+ self.comb += port.adr.eq(self.bus.adr[word_bits:word_bits+len(port.adr)])
+ else:
+ pv = self._page.storage
+ self.comb += port.adr.eq(Cat(self.bus.adr[word_bits:word_bits+len(port.adr)-len(pv)], pv))
+
+ def get_csrs(self):
+ if self._page is None:
+ return []
+ else:
+ return [self._page]
+
+
+class CSRBank(csr.GenericBank):
+ def __init__(self, description, address=0, bus=None):
+ if bus is None:
+ bus = Interface()
+ self.bus = bus
+
+ ###
+
+ csr.GenericBank.__init__(self, description, len(self.bus.dat_w))
+
+ sel = Signal()
+ self.comb += sel.eq(self.bus.adr[9:] == address)
+
+ for i, c in enumerate(self.simple_csrs):
+ self.comb += [
+ c.r.eq(self.bus.dat_w[:c.size]),
+ c.re.eq(sel & \
+ self.bus.we & \
+ (self.bus.adr[:self.decode_bits] == i))
+ ]
+
+ brcases = dict((i, self.bus.dat_r.eq(c.w)) for i, c in enumerate(self.simple_csrs))
+ self.sync += [
+ self.bus.dat_r.eq(0),
+ If(sel, Case(self.bus.adr[:self.decode_bits], brcases))
+ ]
+
+
+# address_map(name, memory) returns the CSR offset at which to map
+# the CSR object (register bank or memory).
+# If memory=None, the object is the register bank of object source.name.
+# Otherwise, it is a memory object belonging to source.name.
+# address_map is called exactly once for each object at each call to
+# scan(), so it can have side effects.
+class CSRBankArray(Module):
+ def __init__(self, source, address_map, *ifargs, **ifkwargs):
+ self.source = source
+ self.address_map = address_map
+ self.scan(ifargs, ifkwargs)
+
+ def scan(self, ifargs, ifkwargs):
+ self.banks = []
+ self.srams = []
+ for name, obj in xdir(self.source, True):
+ if hasattr(obj, "get_csrs"):
+ csrs = obj.get_csrs()
+ else:
+ csrs = []
+ if hasattr(obj, "get_memories"):
+ memories = obj.get_memories()
+ for memory in memories:
+ mapaddr = self.address_map(name, memory)
+ if mapaddr is None:
+ continue
+ sram_bus = Interface(*ifargs, **ifkwargs)
+ mmap = csr.SRAM(memory, mapaddr, bus=sram_bus)
+ self.submodules += mmap
+ csrs += mmap.get_csrs()
+ self.srams.append((name, memory, mapaddr, mmap))
+ if csrs:
+ mapaddr = self.address_map(name, None)
+ if mapaddr is None:
+ continue
+ bank_bus = Interface(*ifargs, **ifkwargs)
+ rmap = CSRBank(csrs, mapaddr, bus=bank_bus)
+ self.submodules += rmap
+ self.banks.append((name, csrs, mapaddr, rmap))
+
+ def get_rmaps(self):
+ return [rmap for name, csrs, mapaddr, rmap in self.banks]
+
+ def get_mmaps(self):
+ return [mmap for name, memory, mapaddr, mmap in self.srams]
+
+ def get_buses(self):
+ return [i.bus for i in self.get_rmaps() + self.get_mmaps()]
--- /dev/null
+from functools import reduce
+from operator import or_
+
+from litex.gen import *
+from litex.gen.util.misc import xdir
+
+from litex.soc.interconnect.csr import *
+
+
+class _EventSource(DUID):
+ def __init__(self):
+ DUID.__init__(self)
+ self.status = Signal() # value in the status register
+ self.pending = Signal() # value in the pending register + assert irq if unmasked
+ self.trigger = Signal() # trigger signal interface to the user design
+ self.clear = Signal() # clearing attempt by W1C to pending register, ignored by some event sources
+
+
+# set on a positive trigger pulse
+class EventSourcePulse(Module, _EventSource):
+ def __init__(self):
+ _EventSource.__init__(self)
+ self.comb += self.status.eq(0)
+ self.sync += [
+ If(self.clear, self.pending.eq(0)),
+ If(self.trigger, self.pending.eq(1))
+ ]
+
+
+# set on the falling edge of the trigger, status = trigger
+class EventSourceProcess(Module, _EventSource):
+ def __init__(self):
+ _EventSource.__init__(self)
+ self.comb += self.status.eq(self.trigger)
+ old_trigger = Signal()
+ self.sync += [
+ If(self.clear, self.pending.eq(0)),
+ old_trigger.eq(self.trigger),
+ If(~self.trigger & old_trigger, self.pending.eq(1))
+ ]
+
+
+# all status set by external trigger
+class EventSourceLevel(Module, _EventSource):
+ def __init__(self):
+ _EventSource.__init__(self)
+ self.comb += [
+ self.status.eq(self.trigger),
+ self.pending.eq(self.trigger)
+ ]
+
+
+class EventManager(Module, AutoCSR):
+ def __init__(self):
+ self.irq = Signal()
+
+ def do_finalize(self):
+ sources_u = [v for k, v in xdir(self, True) if isinstance(v, _EventSource)]
+ sources = sorted(sources_u, key=lambda x: x.duid)
+ n = len(sources)
+ self.status = CSR(n)
+ self.pending = CSR(n)
+ self.enable = CSRStorage(n)
+
+ for i, source in enumerate(sources):
+ self.comb += [
+ self.status.w[i].eq(source.status),
+ If(self.pending.re & self.pending.r[i], source.clear.eq(1)),
+ self.pending.w[i].eq(source.pending)
+ ]
+
+ irqs = [self.pending.w[i] & self.enable.storage[i] for i in range(n)]
+ self.comb += self.irq.eq(reduce(or_, irqs))
+
+ def __setattr__(self, name, value):
+ object.__setattr__(self, name, value)
+ if isinstance(value, _EventSource):
+ if self.finalized:
+ raise FinalizeError
+ self.submodules += value
+
+
+class SharedIRQ(Module):
+ def __init__(self, *event_managers):
+ self.irq = Signal()
+ self.comb += self.irq.eq(reduce(or_, [ev.irq for ev in event_managers]))
--- /dev/null
+from litex.gen import *
+from litex.gen.genlib.record import *
+
+
+def phase_cmd_description(addressbits, bankbits):
+ return [
+ ("address", addressbits, DIR_M_TO_S),
+ ("bank", bankbits, DIR_M_TO_S),
+ ("cas_n", 1, DIR_M_TO_S),
+ ("cs_n", 1, DIR_M_TO_S),
+ ("ras_n", 1, DIR_M_TO_S),
+ ("we_n", 1, DIR_M_TO_S),
+ ("cke", 1, DIR_M_TO_S),
+ ("odt", 1, DIR_M_TO_S),
+ ("reset_n", 1, DIR_M_TO_S)
+ ]
+
+
+def phase_wrdata_description(databits):
+ return [
+ ("wrdata", databits, DIR_M_TO_S),
+ ("wrdata_en", 1, DIR_M_TO_S),
+ ("wrdata_mask", databits//8, DIR_M_TO_S)
+ ]
+
+
+def phase_rddata_description(databits):
+ return [
+ ("rddata_en", 1, DIR_M_TO_S),
+ ("rddata", databits, DIR_S_TO_M),
+ ("rddata_valid", 1, DIR_S_TO_M)
+ ]
+
+
+def phase_description(addressbits, bankbits, databits):
+ r = phase_cmd_description(addressbits, bankbits)
+ r += phase_wrdata_description(databits)
+ r += phase_rddata_description(databits)
+ return r
+
+
+class Interface(Record):
+ def __init__(self, addressbits, bankbits, databits, nphases=1):
+ layout = [("p"+str(i), phase_description(addressbits, bankbits, databits)) for i in range(nphases)]
+ Record.__init__(self, layout)
+ self.phases = [getattr(self, "p"+str(i)) for i in range(nphases)]
+ for p in self.phases:
+ p.cas_n.reset = 1
+ p.cs_n.reset = 1
+ p.ras_n.reset = 1
+ p.we_n.reset = 1
+
+ # Returns pairs (DFI-mandated signal name, Migen signal object)
+ def get_standard_names(self, m2s=True, s2m=True):
+ r = []
+ add_suffix = len(self.phases) > 1
+ for n, phase in enumerate(self.phases):
+ for field, size, direction in phase.layout:
+ if (m2s and direction == DIR_M_TO_S) or (s2m and direction == DIR_S_TO_M):
+ if add_suffix:
+ if direction == DIR_M_TO_S:
+ suffix = "_p" + str(n)
+ else:
+ suffix = "_w" + str(n)
+ else:
+ suffix = ""
+ r.append(("dfi_" + field + suffix, getattr(phase, field)))
+ return r
+
+
+class Interconnect(Module):
+ def __init__(self, master, slave):
+ self.comb += master.connect(slave)
--- /dev/null
+from litex.gen import *
+from litex.gen.genlib.fifo import SyncFIFO
+
+
+class Reader(Module):
+ def __init__(self, lasmim, fifo_depth=None):
+ self.address = Sink([("a", lasmim.aw)])
+ self.data = Source([("d", lasmim.dw)])
+ self.busy = Signal()
+
+ ###
+
+ if fifo_depth is None:
+ fifo_depth = lasmim.req_queue_size + lasmim.read_latency + 2
+
+ # request issuance
+ request_enable = Signal()
+ request_issued = Signal()
+
+ self.comb += [
+ lasmim.we.eq(0),
+ lasmim.stb.eq(self.address.stb & request_enable),
+ lasmim.adr.eq(self.address.a),
+ self.address.ack.eq(lasmim.req_ack & request_enable),
+ request_issued.eq(lasmim.stb & lasmim.req_ack)
+ ]
+
+ # FIFO reservation level counter
+ # incremented when data is planned to be queued
+ # decremented when data is dequeued
+ data_dequeued = Signal()
+ rsv_level = Signal(max=fifo_depth+1)
+ self.sync += [
+ If(request_issued,
+ If(~data_dequeued, rsv_level.eq(rsv_level + 1))
+ ).Elif(data_dequeued,
+ rsv_level.eq(rsv_level - 1)
+ )
+ ]
+ self.comb += [
+ self.busy.eq(rsv_level != 0),
+ request_enable.eq(rsv_level != fifo_depth)
+ ]
+
+ # FIFO
+ fifo = SyncFIFO(lasmim.dw, fifo_depth)
+ self.submodules += fifo
+
+ self.comb += [
+ fifo.din.eq(lasmim.dat_r),
+ fifo.we.eq(lasmim.dat_r_ack),
+
+ self.data.stb.eq(fifo.readable),
+ fifo.re.eq(self.data.ack),
+ self.data.d.eq(fifo.dout),
+ data_dequeued.eq(self.data.stb & self.data.ack)
+ ]
+
+
+class Writer(Module):
+ def __init__(self, lasmim, fifo_depth=None):
+ self.address_data = Sink([("a", lasmim.aw), ("d", lasmim.dw)])
+ self.busy = Signal()
+
+ ###
+
+ if fifo_depth is None:
+ fifo_depth = lasmim.req_queue_size + lasmim.write_latency + 2
+
+ fifo = SyncFIFO(lasmim.dw, fifo_depth)
+ self.submodules += fifo
+
+ self.comb += [
+ lasmim.we.eq(1),
+ lasmim.stb.eq(fifo.writable & self.address_data.stb),
+ lasmim.adr.eq(self.address_data.a),
+ self.address_data.ack.eq(fifo.writable & lasmim.req_ack),
+ fifo.we.eq(self.address_data.stb & lasmim.req_ack),
+ fifo.din.eq(self.address_data.d)
+ ]
+
+ self.comb += [
+ If(lasmim.dat_w_ack,
+ fifo.re.eq(1),
+ lasmim.dat_we.eq(2**(lasmim.dw//8)-1),
+ lasmim.dat_w.eq(fifo.dout)
+ ),
+ self.busy.eq(fifo.readable)
+ ]
--- /dev/null
+from functools import reduce
+from operator import or_
+
+from litex.gen import *
+from litex.gen.genlib import roundrobin
+from litex.gen.genlib.record import *
+
+
+class Interface(Record):
+ def __init__(self, aw, dw, nbanks, req_queue_size, read_latency, write_latency):
+ self.aw = aw
+ self.dw = dw
+ self.nbanks = nbanks
+ self.req_queue_size = req_queue_size
+ self.read_latency = read_latency
+ self.write_latency = write_latency
+
+ bank_layout = [
+ ("adr", aw, DIR_M_TO_S),
+ ("we", 1, DIR_M_TO_S),
+ ("stb", 1, DIR_M_TO_S),
+ ("req_ack", 1, DIR_S_TO_M),
+ ("dat_w_ack", 1, DIR_S_TO_M),
+ ("dat_r_ack", 1, DIR_S_TO_M),
+ ("lock", 1, DIR_S_TO_M)
+ ]
+ if nbanks > 1:
+ layout = [("bank"+str(i), bank_layout) for i in range(nbanks)]
+ else:
+ layout = bank_layout
+ layout += [
+ ("dat_w", dw, DIR_M_TO_S),
+ ("dat_we", dw//8, DIR_M_TO_S),
+ ("dat_r", dw, DIR_S_TO_M)
+ ]
+ Record.__init__(self, layout)
+
+
+def _getattr_all(l, attr):
+ it = iter(l)
+ r = getattr(next(it), attr)
+ for e in it:
+ if getattr(e, attr) != r:
+ raise ValueError
+ return r
+
+
+class LASMIxbar(Module):
+ def __init__(self, controllers, cba_shift):
+ self._controllers = controllers
+ self._cba_shift = cba_shift
+
+ self._rca_bits = _getattr_all(controllers, "aw")
+ self._dw = _getattr_all(controllers, "dw")
+ self._nbanks = _getattr_all(controllers, "nbanks")
+ self._req_queue_size = _getattr_all(controllers, "req_queue_size")
+ self._read_latency = _getattr_all(controllers, "read_latency")
+ self._write_latency = _getattr_all(controllers, "write_latency")
+
+ self._bank_bits = log2_int(self._nbanks, False)
+ self._controller_bits = log2_int(len(self._controllers), False)
+
+ self._masters = []
+
+ def get_master(self):
+ if self.finalized:
+ raise FinalizeError
+ lasmi_master = Interface(self._rca_bits + self._bank_bits + self._controller_bits,
+ self._dw, 1, self._req_queue_size, self._read_latency, self._write_latency)
+ self._masters.append(lasmi_master)
+ return lasmi_master
+
+ def do_finalize(self):
+ nmasters = len(self._masters)
+
+ m_ca, m_ba, m_rca = self._split_master_addresses(self._controller_bits,
+ self._bank_bits, self._rca_bits, self._cba_shift)
+
+ for nc, controller in enumerate(self._controllers):
+ if self._controller_bits:
+ controller_selected = [ca == nc for ca in m_ca]
+ else:
+ controller_selected = [1]*nmasters
+ master_req_acks = [0]*nmasters
+ master_dat_w_acks = [0]*nmasters
+ master_dat_r_acks = [0]*nmasters
+
+ rrs = [roundrobin.RoundRobin(nmasters, roundrobin.SP_CE) for n in range(self._nbanks)]
+ self.submodules += rrs
+ for nb, rr in enumerate(rrs):
+ bank = getattr(controller, "bank"+str(nb))
+
+ # for each master, determine if another bank locks it
+ master_locked = []
+ for nm, master in enumerate(self._masters):
+ locked = 0
+ for other_nb, other_rr in enumerate(rrs):
+ if other_nb != nb:
+ other_bank = getattr(controller, "bank"+str(other_nb))
+ locked = locked | (other_bank.lock & (other_rr.grant == nm))
+ master_locked.append(locked)
+
+ # arbitrate
+ bank_selected = [cs & (ba == nb) & ~locked for cs, ba, locked in zip(controller_selected, m_ba, master_locked)]
+ bank_requested = [bs & master.stb for bs, master in zip(bank_selected, self._masters)]
+ self.comb += [
+ rr.request.eq(Cat(*bank_requested)),
+ rr.ce.eq(~bank.stb & ~bank.lock)
+ ]
+
+ # route requests
+ self.comb += [
+ bank.adr.eq(Array(m_rca)[rr.grant]),
+ bank.we.eq(Array(self._masters)[rr.grant].we),
+ bank.stb.eq(Array(bank_requested)[rr.grant])
+ ]
+ master_req_acks = [master_req_ack | ((rr.grant == nm) & bank_selected[nm] & bank.req_ack)
+ for nm, master_req_ack in enumerate(master_req_acks)]
+ master_dat_w_acks = [master_dat_w_ack | ((rr.grant == nm) & bank.dat_w_ack)
+ for nm, master_dat_w_ack in enumerate(master_dat_w_acks)]
+ master_dat_r_acks = [master_dat_r_ack | ((rr.grant == nm) & bank.dat_r_ack)
+ for nm, master_dat_r_ack in enumerate(master_dat_r_acks)]
+
+ for nm, master_dat_w_ack in enumerate(master_dat_w_acks):
+ for i in range(self._write_latency):
+ new_master_dat_w_ack = Signal()
+ self.sync += new_master_dat_w_ack.eq(master_dat_w_ack)
+ master_dat_w_ack = new_master_dat_w_ack
+ master_dat_w_acks[nm] = master_dat_w_ack
+
+ for nm, master_dat_r_ack in enumerate(master_dat_r_acks):
+ for i in range(self._read_latency):
+ new_master_dat_r_ack = Signal()
+ self.sync += new_master_dat_r_ack.eq(master_dat_r_ack)
+ master_dat_r_ack = new_master_dat_r_ack
+ master_dat_r_acks[nm] = master_dat_r_ack
+
+ self.comb += [master.req_ack.eq(master_req_ack) for master, master_req_ack in zip(self._masters, master_req_acks)]
+ self.comb += [master.dat_w_ack.eq(master_dat_w_ack) for master, master_dat_w_ack in zip(self._masters, master_dat_w_acks)]
+ self.comb += [master.dat_r_ack.eq(master_dat_r_ack) for master, master_dat_r_ack in zip(self._masters, master_dat_r_acks)]
+
+ # route data writes
+ controller_selected_wl = controller_selected
+ for i in range(self._write_latency):
+ n_controller_selected_wl = [Signal() for i in range(nmasters)]
+ self.sync += [n.eq(o) for n, o in zip(n_controller_selected_wl, controller_selected_wl)]
+ controller_selected_wl = n_controller_selected_wl
+ dat_w_maskselect = []
+ dat_we_maskselect = []
+ for master, selected in zip(self._masters, controller_selected_wl):
+ o_dat_w = Signal(self._dw)
+ o_dat_we = Signal(self._dw//8)
+ self.comb += If(selected,
+ o_dat_w.eq(master.dat_w),
+ o_dat_we.eq(master.dat_we)
+ )
+ dat_w_maskselect.append(o_dat_w)
+ dat_we_maskselect.append(o_dat_we)
+ self.comb += [
+ controller.dat_w.eq(reduce(or_, dat_w_maskselect)),
+ controller.dat_we.eq(reduce(or_, dat_we_maskselect))
+ ]
+
+ # route data reads
+ if self._controller_bits:
+ for master in self._masters:
+ controller_sel = Signal(self._controller_bits)
+ for nc, controller in enumerate(self._controllers):
+ for nb in range(nbanks):
+ bank = getattr(controller, "bank"+str(nb))
+ self.comb += If(bank.stb & bank.ack, controller_sel.eq(nc))
+ for i in range(self._read_latency):
+ n_controller_sel = Signal(self._controller_bits)
+ self.sync += n_controller_sel.eq(controller_sel)
+ controller_sel = n_controller_sel
+ self.comb += master.dat_r.eq(Array(self._controllers)[controller_sel].dat_r)
+ else:
+ self.comb += [master.dat_r.eq(self._controllers[0].dat_r) for master in self._masters]
+
+ def _split_master_addresses(self, controller_bits, bank_bits, rca_bits, cba_shift):
+ m_ca = [] # controller address
+ m_ba = [] # bank address
+ m_rca = [] # row and column address
+ for master in self._masters:
+ cba = Signal(self._controller_bits + self._bank_bits)
+ rca = Signal(self._rca_bits)
+ cba_upper = cba_shift + controller_bits + bank_bits
+ self.comb += cba.eq(master.adr[cba_shift:cba_upper])
+ if cba_shift < self._rca_bits:
+ if cba_shift:
+ self.comb += rca.eq(Cat(master.adr[:cba_shift], master.adr[cba_upper:]))
+ else:
+ self.comb += rca.eq(master.adr[cba_upper:])
+ else:
+ self.comb += rca.eq(master.adr[:cba_shift])
+
+ if self._controller_bits:
+ ca = Signal(self._controller_bits)
+ ba = Signal(self._bank_bits)
+ self.comb += Cat(ba, ca).eq(cba)
+ else:
+ ca = None
+ ba = cba
+
+ m_ca.append(ca)
+ m_ba.append(ba)
+ m_rca.append(rca)
+ return m_ca, m_ba, m_rca
--- /dev/null
+from litex.gen import *
+from litex.gen.genlib.record import *
+from litex.gen.genlib import fifo
+
+
+def _make_m2s(layout):
+ r = []
+ for f in layout:
+ if isinstance(f[1], (int, tuple)):
+ r.append((f[0], f[1], DIR_M_TO_S))
+ else:
+ r.append((f[0], _make_m2s(f[1])))
+ return r
+
+
+class EndpointDescription:
+ def __init__(self, payload_layout, packetized=False):
+ self.payload_layout = payload_layout
+ self.packetized = packetized
+
+ def get_full_layout(self):
+ reserved = {"stb", "ack", "payload", "sop", "eop", "description"}
+ attributed = set()
+ for f in self.payload_layout:
+ if f[0] in attributed:
+ raise ValueError(f[0] + " already attributed in payload layout")
+ if f[0] in reserved:
+ raise ValueError(f[0] + " cannot be used in endpoint layout")
+ attributed.add(f[0])
+
+ full_layout = [
+ ("payload", _make_m2s(self.payload_layout)),
+ ("stb", 1, DIR_M_TO_S),
+ ("ack", 1, DIR_S_TO_M)
+ ]
+ if self.packetized:
+ full_layout += [
+ ("sop", 1, DIR_M_TO_S),
+ ("eop", 1, DIR_M_TO_S)
+ ]
+ return full_layout
+
+
+class _Endpoint(Record):
+ def __init__(self, description_or_layout):
+ if isinstance(description_or_layout, EndpointDescription):
+ self.description = description_or_layout
+ else:
+ self.description = EndpointDescription(description_or_layout)
+ Record.__init__(self, self.description.get_full_layout())
+
+ def __getattr__(self, name):
+ return getattr(object.__getattribute__(self, "payload"), name)
+
+
+class Source(_Endpoint):
+ def connect(self, sink):
+ return Record.connect(self, sink)
+
+
+class Sink(_Endpoint):
+ def connect(self, source):
+ return source.connect(self)
+
+
+class _FIFOWrapper(Module):
+ def __init__(self, fifo_class, layout, depth):
+ self.sink = Sink(layout)
+ self.source = Source(layout)
+ self.busy = Signal()
+
+ ###
+
+ description = self.sink.description
+ fifo_layout = [("payload", description.payload_layout)]
+ if description.packetized:
+ fifo_layout += [("sop", 1), ("eop", 1)]
+
+ self.submodules.fifo = fifo_class(layout_len(fifo_layout), depth)
+ fifo_in = Record(fifo_layout)
+ fifo_out = Record(fifo_layout)
+ self.comb += [
+ self.fifo.din.eq(fifo_in.raw_bits()),
+ fifo_out.raw_bits().eq(self.fifo.dout)
+ ]
+
+ self.comb += [
+ self.sink.ack.eq(self.fifo.writable),
+ self.fifo.we.eq(self.sink.stb),
+ fifo_in.payload.eq(self.sink.payload),
+
+ self.source.stb.eq(self.fifo.readable),
+ self.source.payload.eq(fifo_out.payload),
+ self.fifo.re.eq(self.source.ack)
+ ]
+ if description.packetized:
+ self.comb += [
+ fifo_in.sop.eq(self.sink.sop),
+ fifo_in.eop.eq(self.sink.eop),
+ self.source.sop.eq(fifo_out.sop),
+ self.source.eop.eq(fifo_out.eop)
+ ]
+
+
+class SyncFIFO(_FIFOWrapper):
+ def __init__(self, layout, depth, buffered=False):
+ _FIFOWrapper.__init__(
+ self,
+ fifo.SyncFIFOBuffered if buffered else fifo.SyncFIFO,
+ layout, depth)
+
+
+class AsyncFIFO(_FIFOWrapper):
+ def __init__(self, layout, depth):
+ _FIFOWrapper.__init__(self, fifo.AsyncFIFO, layout, depth)
+
+
+class Multiplexer(Module):
+ def __init__(self, layout, n):
+ self.source = Source(layout)
+ sinks = []
+ for i in range(n):
+ sink = Sink(layout)
+ setattr(self, "sink"+str(i), sink)
+ sinks.append(sink)
+ self.sel = Signal(max=n)
+
+ # # #
+
+ cases = {}
+ for i, sink in enumerate(sinks):
+ cases[i] = Record.connect(sink, self.source)
+ self.comb += Case(self.sel, cases)
+
+
+class Demultiplexer(Module):
+ def __init__(self, layout, n):
+ self.sink = Sink(layout)
+ sources = []
+ for i in range(n):
+ source = Source(layout)
+ setattr(self, "source"+str(i), source)
+ sources.append(source)
+ self.sel = Signal(max=n)
+
+ # # #
+
+ cases = {}
+ for i, source in enumerate(sources):
+ cases[i] = Record.connect(self.sink, source)
+ self.comb += Case(self.sel, cases)
+
+# TODO: clean up code below
+# XXX
+
+from copy import copy
+from litex.gen.util.misc import xdir
+
+def pack_layout(l, n):
+ return [("chunk"+str(i), l) for i in range(n)]
+
+def get_endpoints(obj, filt=_Endpoint):
+ if hasattr(obj, "get_endpoints") and callable(obj.get_endpoints):
+ return obj.get_endpoints(filt)
+ r = dict()
+ for k, v in xdir(obj, True):
+ if isinstance(v, filt):
+ r[k] = v
+ return r
+
+def get_single_ep(obj, filt):
+ eps = get_endpoints(obj, filt)
+ if len(eps) != 1:
+ raise ValueError("More than one endpoint")
+ return list(eps.items())[0]
+
+
+class BinaryActor(Module):
+ def __init__(self, *args, **kwargs):
+ self.busy = Signal()
+ sink = get_single_ep(self, Sink)[1]
+ source = get_single_ep(self, Source)[1]
+ self.build_binary_control(sink, source, *args, **kwargs)
+
+ def build_binary_control(self, sink, source):
+ raise NotImplementedError("Binary actor classes must overload build_binary_control_fragment")
+
+
+class CombinatorialActor(BinaryActor):
+ def build_binary_control(self, sink, source):
+ self.comb += [
+ source.stb.eq(sink.stb),
+ sink.ack.eq(source.ack),
+ self.busy.eq(0)
+ ]
+ if sink.description.packetized:
+ self.comb += [
+ source.sop.eq(sink.sop),
+ source.eop.eq(sink.eop)
+ ]
+
+
+class Unpack(Module):
+ def __init__(self, n, layout_to, reverse=False):
+ self.source = source = Source(layout_to)
+ description_from = copy(source.description)
+ description_from.payload_layout = pack_layout(description_from.payload_layout, n)
+ self.sink = sink = Sink(description_from)
+
+ self.busy = Signal()
+
+ ###
+
+ mux = Signal(max=n)
+ first = Signal()
+ last = Signal()
+ self.comb += [
+ first.eq(mux == 0),
+ last.eq(mux == (n-1)),
+ source.stb.eq(sink.stb),
+ sink.ack.eq(last & source.ack)
+ ]
+ self.sync += [
+ If(source.stb & source.ack,
+ If(last,
+ mux.eq(0)
+ ).Else(
+ mux.eq(mux + 1)
+ )
+ )
+ ]
+ cases = {}
+ for i in range(n):
+ chunk = n-i-1 if reverse else i
+ cases[i] = [source.payload.raw_bits().eq(getattr(sink.payload, "chunk"+str(chunk)).raw_bits())]
+ self.comb += Case(mux, cases).makedefault()
+
+ if description_from.packetized:
+ self.comb += [
+ source.sop.eq(sink.sop & first),
+ source.eop.eq(sink.eop & last)
+ ]
+
+
+class Pack(Module):
+ def __init__(self, layout_from, n, reverse=False):
+ self.sink = sink = Sink(layout_from)
+ description_to = copy(sink.description)
+ description_to.payload_layout = pack_layout(description_to.payload_layout, n)
+ self.source = source = Source(description_to)
+ self.busy = Signal()
+
+ ###
+
+ demux = Signal(max=n)
+
+ load_part = Signal()
+ strobe_all = Signal()
+ cases = {}
+ for i in range(n):
+ chunk = n-i-1 if reverse else i
+ cases[i] = [getattr(source.payload, "chunk"+str(chunk)).raw_bits().eq(sink.payload.raw_bits())]
+ self.comb += [
+ self.busy.eq(strobe_all),
+ sink.ack.eq(~strobe_all | source.ack),
+ source.stb.eq(strobe_all),
+ load_part.eq(sink.stb & sink.ack)
+ ]
+
+ if description_to.packetized:
+ demux_last = ((demux == (n - 1)) | sink.eop)
+ else:
+ demux_last = (demux == (n - 1))
+
+ self.sync += [
+ If(source.ack, strobe_all.eq(0)),
+ If(load_part,
+ Case(demux, cases),
+ If(demux_last,
+ demux.eq(0),
+ strobe_all.eq(1)
+ ).Else(
+ demux.eq(demux + 1)
+ )
+ )
+ ]
+
+ if description_to.packetized:
+ self.sync += [
+ If(source.stb & source.ack,
+ source.sop.eq(sink.sop),
+ source.eop.eq(sink.eop),
+ ).Elif(sink.stb & sink.ack,
+ source.sop.eq(sink.sop | source.sop),
+ source.eop.eq(sink.eop | source.eop)
+ )
+ ]
+
+
+class Chunkerize(CombinatorialActor):
+ def __init__(self, layout_from, layout_to, n, reverse=False):
+ self.sink = Sink(layout_from)
+ if isinstance(layout_to, EndpointDescription):
+ layout_to = copy(layout_to)
+ layout_to.payload_layout = pack_layout(layout_to.payload_layout, n)
+ else:
+ layout_to = pack_layout(layout_to, n)
+ self.source = Source(layout_to)
+ CombinatorialActor.__init__(self)
+
+ ###
+
+ for i in range(n):
+ chunk = n-i-1 if reverse else i
+ for f in self.sink.description.payload_layout:
+ src = getattr(self.sink, f[0])
+ dst = getattr(getattr(self.source, "chunk"+str(chunk)), f[0])
+ self.comb += dst.eq(src[i*len(src)//n:(i+1)*len(src)//n])
+
+
+class Unchunkerize(CombinatorialActor):
+ def __init__(self, layout_from, n, layout_to, reverse=False):
+ if isinstance(layout_from, EndpointDescription):
+ fields = layout_from.payload_layout
+ layout_from = copy(layout_from)
+ layout_from.payload_layout = pack_layout(layout_from.payload_layout, n)
+ else:
+ fields = layout_from
+ layout_from = pack_layout(layout_from, n)
+ self.sink = Sink(layout_from)
+ self.source = Source(layout_to)
+ CombinatorialActor.__init__(self)
+
+ ###
+
+ for i in range(n):
+ chunk = n-i-1 if reverse else i
+ for f in fields:
+ src = getattr(getattr(self.sink, "chunk"+str(chunk)), f[0])
+ dst = getattr(self.source, f[0])
+ self.comb += dst[i*len(dst)//n:(i+1)*len(dst)//n].eq(src)
+
+
+class Converter(Module):
+ def __init__(self, layout_from, layout_to, reverse=False):
+ self.sink = Sink(layout_from)
+ self.source = Source(layout_to)
+ self.busy = Signal()
+
+ ###
+
+ width_from = len(self.sink.payload.raw_bits())
+ width_to = len(self.source.payload.raw_bits())
+
+ # downconverter
+ if width_from > width_to:
+ if width_from % width_to:
+ raise ValueError
+ ratio = width_from//width_to
+ self.submodules.chunkerize = Chunkerize(layout_from, layout_to, ratio, reverse)
+ self.submodules.unpack = Unpack(ratio, layout_to)
+
+ self.comb += [
+ Record.connect(self.sink, self.chunkerize.sink),
+ Record.connect(self.chunkerize.source, self.unpack.sink),
+ Record.connect(self.unpack.source, self.source),
+ self.busy.eq(self.unpack.busy)
+ ]
+ # upconverter
+ elif width_to > width_from:
+ if width_to % width_from:
+ raise ValueError
+ ratio = width_to//width_from
+ self.submodules.pack = Pack(layout_from, ratio)
+ self.submodules.unchunkerize = Unchunkerize(layout_from, ratio, layout_to, reverse)
+
+ self.comb += [
+ Record.connect(self.sink, self.pack.sink),
+ Record.connect(self.pack.source, self.unchunkerize.sink),
+ Record.connect(self.unchunkerize.source, self.source),
+ self.busy.eq(self.pack.busy)
+ ]
+ # direct connection
+ else:
+ self.comb += Record.connect(self.sink, self.source)
+
+# XXX
--- /dev/null
+from functools import reduce
+from operator import or_
+
+from litex.gen import *
+from litex.gen.genlib import roundrobin
+from litex.gen.genlib.record import *
+from litex.gen.genlib.misc import split, displacer, chooser
+from litex.gen.genlib.fsm import FSM, NextState
+
+from litex.soc.interconnect import csr
+
+# TODO: rewrite without FlipFlop and Counter
+
+
+_layout = [
+ ("adr", 30, DIR_M_TO_S),
+ ("dat_w", "data_width", DIR_M_TO_S),
+ ("dat_r", "data_width", DIR_S_TO_M),
+ ("sel", "sel_width", DIR_M_TO_S),
+ ("cyc", 1, DIR_M_TO_S),
+ ("stb", 1, DIR_M_TO_S),
+ ("ack", 1, DIR_S_TO_M),
+ ("we", 1, DIR_M_TO_S),
+ ("cti", 3, DIR_M_TO_S),
+ ("bte", 2, DIR_M_TO_S),
+ ("err", 1, DIR_S_TO_M)
+]
+
+
+class Interface(Record):
+ def __init__(self, data_width=32):
+ Record.__init__(self, set_layout_parameters(_layout,
+ data_width=data_width,
+ sel_width=data_width//8))
+
+ def _do_transaction(self):
+ yield self.cyc.eq(1)
+ yield self.stb.eq(1)
+ yield
+ while not (yield self.ack):
+ yield
+ yield self.cyc.eq(0)
+ yield self.stb.eq(0)
+
+ def write(self, adr, dat, sel=None):
+ if sel is None:
+ sel = 2**len(self.sel) - 1
+ yield self.adr.eq(adr)
+ yield self.dat_w.eq(dat)
+ yield self.sel.eq(sel)
+ yield self.we.eq(1)
+ yield from self._do_transaction()
+
+ def read(self, adr):
+ yield self.adr.eq(adr)
+ yield self.we.eq(0)
+ yield from self._do_transaction()
+ return (yield self.dat_r)
+
+
+class InterconnectPointToPoint(Module):
+ def __init__(self, master, slave):
+ self.comb += master.connect(slave)
+
+
+class Arbiter(Module):
+ def __init__(self, masters, target):
+ self.submodules.rr = roundrobin.RoundRobin(len(masters))
+
+ # mux master->slave signals
+ for name, size, direction in _layout:
+ if direction == DIR_M_TO_S:
+ choices = Array(getattr(m, name) for m in masters)
+ self.comb += getattr(target, name).eq(choices[self.rr.grant])
+
+ # connect slave->master signals
+ for name, size, direction in _layout:
+ if direction == DIR_S_TO_M:
+ source = getattr(target, name)
+ for i, m in enumerate(masters):
+ dest = getattr(m, name)
+ if name == "ack" or name == "err":
+ self.comb += dest.eq(source & (self.rr.grant == i))
+ else:
+ self.comb += dest.eq(source)
+
+ # connect bus requests to round-robin selector
+ reqs = [m.cyc for m in masters]
+ self.comb += self.rr.request.eq(Cat(*reqs))
+
+
+class Decoder(Module):
+ # slaves is a list of pairs:
+ # 0) function that takes the address signal and returns a FHDL expression
+ # that evaluates to 1 when the slave is selected and 0 otherwise.
+ # 1) wishbone.Slave reference.
+ # register adds flip-flops after the address comparators. Improves timing,
+ # but breaks Wishbone combinatorial feedback.
+ def __init__(self, master, slaves, register=False):
+ ns = len(slaves)
+ slave_sel = Signal(ns)
+ slave_sel_r = Signal(ns)
+
+ # decode slave addresses
+ self.comb += [slave_sel[i].eq(fun(master.adr))
+ for i, (fun, bus) in enumerate(slaves)]
+ if register:
+ self.sync += slave_sel_r.eq(slave_sel)
+ else:
+ self.comb += slave_sel_r.eq(slave_sel)
+
+ # connect master->slaves signals except cyc
+ for slave in slaves:
+ for name, size, direction in _layout:
+ if direction == DIR_M_TO_S and name != "cyc":
+ self.comb += getattr(slave[1], name).eq(getattr(master, name))
+
+ # combine cyc with slave selection signals
+ self.comb += [slave[1].cyc.eq(master.cyc & slave_sel[i])
+ for i, slave in enumerate(slaves)]
+
+ # generate master ack (resp. err) by ORing all slave acks (resp. errs)
+ self.comb += [
+ master.ack.eq(reduce(or_, [slave[1].ack for slave in slaves])),
+ master.err.eq(reduce(or_, [slave[1].err for slave in slaves]))
+ ]
+
+ # mux (1-hot) slave data return
+ masked = [Replicate(slave_sel_r[i], len(master.dat_r)) & slaves[i][1].dat_r for i in range(ns)]
+ self.comb += master.dat_r.eq(reduce(or_, masked))
+
+
+class InterconnectShared(Module):
+ def __init__(self, masters, slaves, register=False):
+ shared = Interface()
+ self.submodules += Arbiter(masters, shared)
+ self.submodules += Decoder(shared, slaves, register)
+
+
+class Crossbar(Module):
+ def __init__(self, masters, slaves, register=False):
+ matches, busses = zip(*slaves)
+ access = [[Interface() for j in slaves] for i in masters]
+ # decode each master into its access row
+ for row, master in zip(access, masters):
+ row = list(zip(matches, row))
+ self.submodules += Decoder(master, row, register)
+ # arbitrate each access column onto its slave
+ for column, bus in zip(zip(*access), busses):
+ self.submodules += Arbiter(column, bus)
+
+
+class DownConverter(Module):
+ """DownConverter
+
+ This module splits Wishbone accesses from a master interface to a smaller
+ slave interface.
+
+ Writes:
+ Writes from master are splitted N writes to the slave. Access is acked when the last
+ access is acked by the slave.
+
+ Reads:
+ Read from master are splitted in N reads to the the slave. Read datas from
+ the slave are cached before being presented concatenated on the last access.
+
+ """
+ def __init__(self, master, slave):
+ dw_from = len(master.dat_r)
+ dw_to = len(slave.dat_w)
+ ratio = dw_from//dw_to
+
+ # # #
+
+ read = Signal()
+ write = Signal()
+
+ counter = Counter(max=ratio)
+ self.submodules += counter
+ counter_done = Signal()
+ self.comb += counter_done.eq(counter.value == ratio-1)
+
+ # Main FSM
+ self.submodules.fsm = fsm = FSM(reset_state="IDLE")
+ fsm.act("IDLE",
+ counter.reset.eq(1),
+ If(master.stb & master.cyc,
+ If(master.we,
+ NextState("WRITE")
+ ).Else(
+ NextState("READ")
+ )
+ )
+ )
+ fsm.act("WRITE",
+ write.eq(1),
+ slave.we.eq(1),
+ slave.cyc.eq(1),
+ If(master.stb & master.cyc,
+ slave.stb.eq(1),
+ If(slave.ack,
+ counter.ce.eq(1),
+ If(counter_done,
+ master.ack.eq(1),
+ NextState("IDLE")
+ )
+ )
+ ).Elif(~master.cyc,
+ NextState("IDLE")
+ )
+ )
+ fsm.act("READ",
+ read.eq(1),
+ slave.cyc.eq(1),
+ If(master.stb & master.cyc,
+ slave.stb.eq(1),
+ If(slave.ack,
+ counter.ce.eq(1),
+ If(counter_done,
+ master.ack.eq(1),
+ NextState("IDLE")
+ )
+ )
+ ).Elif(~master.cyc,
+ NextState("IDLE")
+ )
+ )
+
+ # Address
+ self.comb += [
+ If(counter_done,
+ slave.cti.eq(7) # indicate end of burst
+ ).Else(
+ slave.cti.eq(2)
+ ),
+ slave.adr.eq(Cat(counter.value, master.adr))
+ ]
+
+ # Datapath
+ cases = {}
+ for i in range(ratio):
+ cases[i] = [
+ slave.sel.eq(master.sel[i*dw_to//8:(i+1)*dw_to]),
+ slave.dat_w.eq(master.dat_w[i*dw_to:(i+1)*dw_to])
+ ]
+ self.comb += Case(counter.value, cases)
+
+
+ cached_data = Signal(dw_from)
+ self.comb += master.dat_r.eq(Cat(cached_data[dw_to:], slave.dat_r))
+ self.sync += \
+ If(read & counter.ce,
+ cached_data.eq(master.dat_r)
+ )
+
+
+class UpConverter(Module):
+ """UpConverter
+
+ This module up-converts wishbone accesses and bursts from a master interface
+ to a wider slave interface. This allows efficient use wishbone bursts.
+
+ Writes:
+ Wishbone writes are cached before being written to the slave. Access to
+ the slave is done at the end of a burst or when address reach end of burst
+ addressing.
+
+ Reads:
+ Cache is refilled only at the beginning of each burst, the subsequent
+ reads of a burst use the cached data.
+
+ """
+ def __init__(self, master, slave):
+ dw_from = len(master.dat_r)
+ dw_to = len(slave.dat_w)
+ ratio = dw_to//dw_from
+ ratiobits = log2_int(ratio)
+
+ # # #
+
+ write = Signal()
+ evict = Signal()
+ refill = Signal()
+ read = Signal()
+
+ address = FlipFlop(30)
+ self.submodules += address
+ self.comb += address.d.eq(master.adr)
+
+ counter = Counter(max=ratio)
+ self.submodules += counter
+ counter_offset = Signal(max=ratio)
+ counter_done = Signal()
+ self.comb += [
+ counter_offset.eq(address.q),
+ counter_done.eq((counter.value + counter_offset) == ratio-1)
+ ]
+
+ cached_data = Signal(dw_to)
+ cached_sel = Signal(dw_to//8)
+
+ end_of_burst = Signal()
+ self.comb += end_of_burst.eq(~master.cyc |
+ (master.stb & master.cyc & master.ack & ((master.cti == 7) | counter_done)))
+
+
+ need_refill = FlipFlop(reset=1)
+ self.submodules += need_refill
+ self.comb += [
+ need_refill.reset.eq(end_of_burst),
+ need_refill.d.eq(0)
+ ]
+
+ # Main FSM
+ self.submodules.fsm = fsm = FSM()
+ fsm.act("IDLE",
+ counter.reset.eq(1),
+ If(master.stb & master.cyc,
+ address.ce.eq(1),
+ If(master.we,
+ NextState("WRITE")
+ ).Else(
+ If(need_refill.q,
+ NextState("REFILL")
+ ).Else(
+ NextState("READ")
+ )
+ )
+ )
+ )
+ fsm.act("WRITE",
+ If(master.stb & master.cyc,
+ write.eq(1),
+ counter.ce.eq(1),
+ master.ack.eq(1),
+ If(counter_done,
+ NextState("EVICT")
+ )
+ ).Elif(~master.cyc,
+ NextState("EVICT")
+ )
+ )
+ fsm.act("EVICT",
+ evict.eq(1),
+ slave.stb.eq(1),
+ slave.we.eq(1),
+ slave.cyc.eq(1),
+ slave.dat_w.eq(cached_data),
+ slave.sel.eq(cached_sel),
+ If(slave.ack,
+ NextState("IDLE")
+ )
+ )
+ fsm.act("REFILL",
+ refill.eq(1),
+ slave.stb.eq(1),
+ slave.cyc.eq(1),
+ If(slave.ack,
+ need_refill.ce.eq(1),
+ NextState("READ")
+ )
+ )
+ fsm.act("READ",
+ read.eq(1),
+ If(master.stb & master.cyc,
+ master.ack.eq(1)
+ ),
+ NextState("IDLE")
+ )
+
+ # Address
+ self.comb += [
+ slave.cti.eq(7), # we are not able to generate bursts since up-converting
+ slave.adr.eq(address.q[ratiobits:])
+ ]
+
+ # Datapath
+ cached_datas = [FlipFlop(dw_from) for i in range(ratio)]
+ cached_sels = [FlipFlop(dw_from//8) for i in range(ratio)]
+ self.submodules += cached_datas, cached_sels
+
+ cases = {}
+ for i in range(ratio):
+ write_sel = Signal()
+ cases[i] = write_sel.eq(1)
+ self.comb += [
+ cached_sels[i].reset.eq(counter.reset),
+ If(write,
+ cached_datas[i].d.eq(master.dat_w),
+ ).Else(
+ cached_datas[i].d.eq(slave.dat_r[dw_from*i:dw_from*(i+1)])
+ ),
+ cached_sels[i].d.eq(master.sel),
+ If((write & write_sel) | refill,
+ cached_datas[i].ce.eq(1),
+ cached_sels[i].ce.eq(1)
+ )
+ ]
+ self.comb += Case(counter.value + counter_offset, cases)
+
+ cases = {}
+ for i in range(ratio):
+ cases[i] = master.dat_r.eq(cached_datas[i].q)
+ self.comb += Case(address.q[:ratiobits], cases)
+
+ self.comb += [
+ cached_data.eq(Cat([cached_data.q for cached_data in cached_datas])),
+ cached_sel.eq(Cat([cached_sel.q for cached_sel in cached_sels]))
+ ]
+
+
+class Converter(Module):
+ """Converter
+
+ This module is a wrapper for DownConverter and UpConverter.
+ It should preferably be used rather than direct instantiations
+ of specific converters.
+ """
+ def __init__(self, master, slave):
+ self.master = master
+ self.slave = slave
+
+ # # #
+
+ dw_from = len(master.dat_r)
+ dw_to = len(slave.dat_r)
+ if dw_from > dw_to:
+ downconverter = DownConverter(master, slave)
+ self.submodules += downconverter
+ elif dw_from < dw_to:
+ upconverter = UpConverter(master, slave)
+ self.submodules += upconverter
+ else:
+ Record.connect(master, slave)
+
+
+class Cache(Module):
+ """Cache
+
+ This module is a write-back wishbone cache that can be used as a L2 cache.
+ Cachesize (in 32-bit words) is the size of the data store and must be a power of 2
+ """
+ def __init__(self, cachesize, master, slave):
+ self.master = master
+ self.slave = slave
+
+ ###
+
+ dw_from = len(master.dat_r)
+ dw_to = len(slave.dat_r)
+ if dw_to > dw_from and (dw_to % dw_from) != 0:
+ raise ValueError("Slave data width must be a multiple of {dw}".format(dw=dw_from))
+ if dw_to < dw_from and (dw_from % dw_to) != 0:
+ raise ValueError("Master data width must be a multiple of {dw}".format(dw=dw_to))
+
+ # Split address:
+ # TAG | LINE NUMBER | LINE OFFSET
+ offsetbits = log2_int(max(dw_to//dw_from, 1))
+ addressbits = len(slave.adr) + offsetbits
+ linebits = log2_int(cachesize) - offsetbits
+ tagbits = addressbits - linebits
+ wordbits = log2_int(max(dw_from//dw_to, 1))
+ adr_offset, adr_line, adr_tag = split(master.adr, offsetbits, linebits, tagbits)
+ word = Signal(wordbits) if wordbits else None
+
+ # Data memory
+ data_mem = Memory(dw_to*2**wordbits, 2**linebits)
+ data_port = data_mem.get_port(write_capable=True, we_granularity=8)
+ self.specials += data_mem, data_port
+
+ write_from_slave = Signal()
+ if adr_offset is None:
+ adr_offset_r = None
+ else:
+ adr_offset_r = Signal(offsetbits)
+ self.sync += adr_offset_r.eq(adr_offset)
+
+ self.comb += [
+ data_port.adr.eq(adr_line),
+ If(write_from_slave,
+ displacer(slave.dat_r, word, data_port.dat_w),
+ displacer(Replicate(1, dw_to//8), word, data_port.we)
+ ).Else(
+ data_port.dat_w.eq(Replicate(master.dat_w, max(dw_to//dw_from, 1))),
+ If(master.cyc & master.stb & master.we & master.ack,
+ displacer(master.sel, adr_offset, data_port.we, 2**offsetbits, reverse=True)
+ )
+ ),
+ chooser(data_port.dat_r, word, slave.dat_w),
+ slave.sel.eq(2**(dw_to//8)-1),
+ chooser(data_port.dat_r, adr_offset_r, master.dat_r, reverse=True)
+ ]
+
+
+ # Tag memory
+ tag_layout = [("tag", tagbits), ("dirty", 1)]
+ tag_mem = Memory(layout_len(tag_layout), 2**linebits)
+ tag_port = tag_mem.get_port(write_capable=True)
+ self.specials += tag_mem, tag_port
+ tag_do = Record(tag_layout)
+ tag_di = Record(tag_layout)
+ self.comb += [
+ tag_do.raw_bits().eq(tag_port.dat_r),
+ tag_port.dat_w.eq(tag_di.raw_bits())
+ ]
+
+ self.comb += [
+ tag_port.adr.eq(adr_line),
+ tag_di.tag.eq(adr_tag)
+ ]
+ if word is not None:
+ self.comb += slave.adr.eq(Cat(word, adr_line, tag_do.tag))
+ else:
+ self.comb += slave.adr.eq(Cat(adr_line, tag_do.tag))
+
+ # slave word computation, word_clr and word_inc will be simplified
+ # at synthesis when wordbits=0
+ word_clr = Signal()
+ word_inc = Signal()
+ if word is not None:
+ self.sync += \
+ If(word_clr,
+ word.eq(0),
+ ).Elif(word_inc,
+ word.eq(word+1)
+ )
+
+ def word_is_last(word):
+ if word is not None:
+ return word == 2**wordbits-1
+ else:
+ return 1
+
+ # Control FSM
+ self.submodules.fsm = fsm = FSM(reset_state="IDLE")
+ fsm.act("IDLE",
+ If(master.cyc & master.stb,
+ NextState("TEST_HIT")
+ )
+ )
+ fsm.act("TEST_HIT",
+ word_clr.eq(1),
+ If(tag_do.tag == adr_tag,
+ master.ack.eq(1),
+ If(master.we,
+ tag_di.dirty.eq(1),
+ tag_port.we.eq(1)
+ ),
+ NextState("IDLE")
+ ).Else(
+ If(tag_do.dirty,
+ NextState("EVICT")
+ ).Else(
+ NextState("REFILL_WRTAG")
+ )
+ )
+ )
+
+ fsm.act("EVICT",
+ slave.stb.eq(1),
+ slave.cyc.eq(1),
+ slave.we.eq(1),
+ If(slave.ack,
+ word_inc.eq(1),
+ If(word_is_last(word),
+ NextState("REFILL_WRTAG")
+ )
+ )
+ )
+ fsm.act("REFILL_WRTAG",
+ # Write the tag first to set the slave address
+ tag_port.we.eq(1),
+ word_clr.eq(1),
+ NextState("REFILL")
+ )
+ fsm.act("REFILL",
+ slave.stb.eq(1),
+ slave.cyc.eq(1),
+ slave.we.eq(0),
+ If(slave.ack,
+ write_from_slave.eq(1),
+ word_inc.eq(1),
+ If(word_is_last(word),
+ NextState("TEST_HIT"),
+ ).Else(
+ NextState("REFILL")
+ )
+ )
+ )
+
+
+class SRAM(Module):
+ def __init__(self, mem_or_size, read_only=None, init=None, bus=None):
+ if bus is None:
+ bus = Interface()
+ self.bus = bus
+ bus_data_width = len(self.bus.dat_r)
+ if isinstance(mem_or_size, Memory):
+ assert(mem_or_size.width <= bus_data_width)
+ self.mem = mem_or_size
+ else:
+ self.mem = Memory(bus_data_width, mem_or_size//(bus_data_width//8), init=init)
+ if read_only is None:
+ if hasattr(self.mem, "bus_read_only"):
+ read_only = self.mem.bus_read_only
+ else:
+ read_only = False
+
+ ###
+
+ # memory
+ port = self.mem.get_port(write_capable=not read_only, we_granularity=8)
+ self.specials += self.mem, port
+ # generate write enable signal
+ if not read_only:
+ self.comb += [port.we[i].eq(self.bus.cyc & self.bus.stb & self.bus.we & self.bus.sel[i])
+ for i in range(4)]
+ # address and data
+ self.comb += [
+ port.adr.eq(self.bus.adr[:len(port.adr)]),
+ self.bus.dat_r.eq(port.dat_r)
+ ]
+ if not read_only:
+ self.comb += port.dat_w.eq(self.bus.dat_w),
+ # generate ack
+ self.sync += [
+ self.bus.ack.eq(0),
+ If(self.bus.cyc & self.bus.stb & ~self.bus.ack, self.bus.ack.eq(1))
+ ]
+
+
+class CSRBank(csr.GenericBank):
+ def __init__(self, description, bus=None):
+ if bus is None:
+ bus = Interface()
+ self.bus = bus
+
+ ###
+
+ csr.GenericBank.__init__(self, description, len(self.bus.dat_w))
+
+ for i, c in enumerate(self.simple_csrs):
+ self.comb += [
+ c.r.eq(self.bus.dat_w[:c.size]),
+ c.re.eq(self.bus.cyc & self.bus.stb & ~self.bus.ack & self.bus.we & \
+ (self.bus.adr[:self.decode_bits] == i))
+ ]
+
+ brcases = dict((i, self.bus.dat_r.eq(c.w)) for i, c in enumerate(self.simple_csrs))
+ self.sync += [
+ Case(self.bus.adr[:self.decode_bits], brcases),
+ If(bus.ack, bus.ack.eq(0)).Elif(bus.cyc & bus.stb, bus.ack.eq(1))
+ ]
--- /dev/null
+from litex.gen import *
+from litex.gen.genlib.misc import timeline
+
+from litex.soc.interconnect import csr_bus, wishbone
+
+
+class WB2CSR(Module):
+ def __init__(self, bus_wishbone=None, bus_csr=None):
+ if bus_wishbone is None:
+ bus_wishbone = wishbone.Interface()
+ self.wishbone = bus_wishbone
+ if bus_csr is None:
+ bus_csr = csr_bus.Interface()
+ self.csr = bus_csr
+
+ ###
+
+ self.sync += [
+ self.csr.we.eq(0),
+ self.csr.dat_w.eq(self.wishbone.dat_w),
+ self.csr.adr.eq(self.wishbone.adr),
+ self.wishbone.dat_r.eq(self.csr.dat_r)
+ ]
+ self.sync += timeline(self.wishbone.cyc & self.wishbone.stb, [
+ (1, [self.csr.we.eq(self.wishbone.we)]),
+ (2, [self.wishbone.ack.eq(1)]),
+ (3, [self.wishbone.ack.eq(0)])
+ ])
--- /dev/null
+from litex.gen import *
+from litex.gen.genlib.fsm import FSM, NextState
+
+
+class WB2LASMI(Module):
+ def __init__(self, wishbone, lasmim):
+
+ ###
+
+ # Control FSM
+ self.submodules.fsm = fsm = FSM(reset_state="IDLE")
+ fsm.act("IDLE",
+ If(wishbone.cyc & wishbone.stb,
+ NextState("REQUEST")
+ )
+ )
+ fsm.act("REQUEST",
+ lasmim.stb.eq(1),
+ lasmim.we.eq(wishbone.we),
+ If(lasmim.req_ack,
+ If(wishbone.we,
+ NextState("WRITE_DATA")
+ ).Else(
+ NextState("READ_DATA")
+ )
+ )
+ )
+ fsm.act("WRITE_DATA",
+ If(lasmim.dat_w_ack,
+ lasmim.dat_we.eq(wishbone.sel),
+ wishbone.ack.eq(1),
+ NextState("IDLE")
+ )
+ )
+ fsm.act("READ_DATA",
+ If(lasmim.dat_r_ack,
+ wishbone.ack.eq(1),
+ NextState("IDLE")
+ )
+ )
+
+ # Address / Datapath
+ self.comb += [
+ lasmim.adr.eq(wishbone.adr),
+ If(lasmim.dat_w_ack,
+ lasmim.dat_w.eq(wishbone.dat_w),
+ ),
+ wishbone.dat_r.eq(lasmim.dat_r)
+ ]
+++ /dev/null
-from migen import *
-
-from misoc.interconnect import dfi
-from misoc.interconnect.csr import *
-
-
-class PhaseInjector(Module, AutoCSR):
- def __init__(self, phase):
- self._command = CSRStorage(6) # cs, we, cas, ras, wren, rden
- self._command_issue = CSR()
- self._address = CSRStorage(len(phase.address))
- self._baddress = CSRStorage(len(phase.bank))
- self._wrdata = CSRStorage(len(phase.wrdata))
- self._rddata = CSRStatus(len(phase.rddata))
-
- ###
-
- self.comb += [
- If(self._command_issue.re,
- phase.cs_n.eq(~self._command.storage[0]),
- phase.we_n.eq(~self._command.storage[1]),
- phase.cas_n.eq(~self._command.storage[2]),
- phase.ras_n.eq(~self._command.storage[3])
- ).Else(
- phase.cs_n.eq(1),
- phase.we_n.eq(1),
- phase.cas_n.eq(1),
- phase.ras_n.eq(1)
- ),
- phase.address.eq(self._address.storage),
- phase.bank.eq(self._baddress.storage),
- phase.wrdata_en.eq(self._command_issue.re & self._command.storage[4]),
- phase.rddata_en.eq(self._command_issue.re & self._command.storage[5]),
- phase.wrdata.eq(self._wrdata.storage),
- phase.wrdata_mask.eq(0)
- ]
- self.sync += If(phase.rddata_valid, self._rddata.status.eq(phase.rddata))
-
-
-class DFIInjector(Module, AutoCSR):
- def __init__(self, addressbits, bankbits, databits, nphases=1):
- inti = dfi.Interface(addressbits, bankbits, databits, nphases)
- self.slave = dfi.Interface(addressbits, bankbits, databits, nphases)
- self.master = dfi.Interface(addressbits, bankbits, databits, nphases)
-
- self._control = CSRStorage(4) # sel, cke, odt, reset_n
-
- for n, phase in enumerate(inti.phases):
- setattr(self.submodules, "pi" + str(n), PhaseInjector(phase))
-
- ###
-
- self.comb += If(self._control.storage[0],
- self.slave.connect(self.master)
- ).Else(
- inti.connect(self.master)
- )
- self.comb += [phase.cke.eq(self._control.storage[1]) for phase in inti.phases]
- self.comb += [phase.odt.eq(self._control.storage[2]) for phase in inti.phases if hasattr(phase, "odt")]
- self.comb += [phase.reset_n.eq(self._control.storage[3]) for phase in inti.phases if hasattr(phase, "reset_n")]
+++ /dev/null
-from misoc.cores.dvi_sampler.core import DVISampler
+++ /dev/null
-from migen import *
-from migen.genlib.cdc import MultiReg, PulseSynchronizer
-from migen.genlib.fifo import AsyncFIFO
-from migen.genlib.record import Record
-
-from misoc.interconnect.csr import *
-from misoc.cores.dvi_sampler.common import channel_layout
-
-
-class SyncPolarity(Module):
- def __init__(self):
- self.valid_i = Signal()
- self.data_in0 = Record(channel_layout)
- self.data_in1 = Record(channel_layout)
- self.data_in2 = Record(channel_layout)
-
- self.valid_o = Signal()
- self.de = Signal()
- self.hsync = Signal()
- self.vsync = Signal()
- self.r = Signal(8)
- self.g = Signal(8)
- self.b = Signal(8)
-
- ###
-
- de = self.data_in0.de
- de_r = Signal()
- c = self.data_in0.c
- c_polarity = Signal(2)
- c_out = Signal(2)
-
- self.comb += [
- self.de.eq(de_r),
- self.hsync.eq(c_out[0]),
- self.vsync.eq(c_out[1])
- ]
-
- self.sync.pix += [
- self.valid_o.eq(self.valid_i),
- self.r.eq(self.data_in2.d),
- self.g.eq(self.data_in1.d),
- self.b.eq(self.data_in0.d),
-
- de_r.eq(de),
- If(de_r & ~de,
- c_polarity.eq(c),
- c_out.eq(0)
- ).Else(
- c_out.eq(c ^ c_polarity)
- )
- ]
-
-
-class ResolutionDetection(Module, AutoCSR):
- def __init__(self, nbits=11):
- self.valid_i = Signal()
- self.vsync = Signal()
- self.de = Signal()
-
- self._hres = CSRStatus(nbits)
- self._vres = CSRStatus(nbits)
-
- ###
-
- # Detect DE transitions
- de_r = Signal()
- pn_de = Signal()
- self.sync.pix += de_r.eq(self.de)
- self.comb += pn_de.eq(~self.de & de_r)
-
- # HRES
- hcounter = Signal(nbits)
- self.sync.pix += If(self.valid_i & self.de,
- hcounter.eq(hcounter + 1)
- ).Else(
- hcounter.eq(0)
- )
-
- hcounter_st = Signal(nbits)
- self.sync.pix += If(self.valid_i,
- If(pn_de, hcounter_st.eq(hcounter))
- ).Else(
- hcounter_st.eq(0)
- )
- self.specials += MultiReg(hcounter_st, self._hres.status)
-
- # VRES
- vsync_r = Signal()
- p_vsync = Signal()
- self.sync.pix += vsync_r.eq(self.vsync),
- self.comb += p_vsync.eq(self.vsync & ~vsync_r)
-
- vcounter = Signal(nbits)
- self.sync.pix += If(self.valid_i & p_vsync,
- vcounter.eq(0)
- ).Elif(pn_de,
- vcounter.eq(vcounter + 1)
- )
-
- vcounter_st = Signal(nbits)
- self.sync.pix += If(self.valid_i,
- If(p_vsync, vcounter_st.eq(vcounter))
- ).Else(
- vcounter_st.eq(0)
- )
- self.specials += MultiReg(vcounter_st, self._vres.status)
-
-
-class FrameExtraction(Module, AutoCSR):
- def __init__(self, word_width, fifo_depth):
- # in pix clock domain
- self.valid_i = Signal()
- self.vsync = Signal()
- self.de = Signal()
- self.r = Signal(8)
- self.g = Signal(8)
- self.b = Signal(8)
-
- # in sys clock domain
- word_layout = [("sof", 1), ("pixels", word_width)]
- self.frame = Source(word_layout)
- self.busy = Signal()
-
- self._overflow = CSR()
-
- ###
-
- # start of frame detection
- vsync_r = Signal()
- new_frame = Signal()
- self.comb += new_frame.eq(self.vsync & ~vsync_r)
- self.sync.pix += vsync_r.eq(self.vsync)
-
- # pack pixels into words
- cur_word = Signal(word_width)
- cur_word_valid = Signal()
- encoded_pixel = Signal(24)
- self.comb += encoded_pixel.eq(Cat(self.b, self.g, self.r))
- pack_factor = word_width//24
- assert(pack_factor & (pack_factor - 1) == 0) # only support powers of 2
- pack_counter = Signal(max=pack_factor)
- self.sync.pix += [
- cur_word_valid.eq(0),
- If(new_frame,
- cur_word_valid.eq(pack_counter == (pack_factor - 1)),
- pack_counter.eq(0),
- ).Elif(self.valid_i & self.de,
- [If(pack_counter == (pack_factor-i-1),
- cur_word[24*i:24*(i+1)].eq(encoded_pixel)) for i in range(pack_factor)],
- cur_word_valid.eq(pack_counter == (pack_factor - 1)),
- pack_counter.eq(pack_counter + 1)
- )
- ]
-
- # FIFO
- fifo = RenameClockDomains(AsyncFIFO(word_layout, fifo_depth),
- {"write": "pix", "read": "sys"})
- self.submodules += fifo
- self.comb += [
- fifo.din.pixels.eq(cur_word),
- fifo.we.eq(cur_word_valid)
- ]
- self.sync.pix += \
- If(new_frame,
- fifo.din.sof.eq(1)
- ).Elif(cur_word_valid,
- fifo.din.sof.eq(0)
- )
- self.comb += [
- self.frame.stb.eq(fifo.readable),
- self.frame.payload.eq(fifo.dout),
- fifo.re.eq(self.frame.ack),
- self.busy.eq(0)
- ]
-
- # overflow detection
- pix_overflow = Signal()
- pix_overflow_reset = Signal()
- self.sync.pix += [
- If(fifo.we & ~fifo.writable,
- pix_overflow.eq(1)
- ).Elif(pix_overflow_reset,
- pix_overflow.eq(0)
- )
- ]
-
- sys_overflow = Signal()
- self.specials += MultiReg(pix_overflow, sys_overflow)
- self.submodules.overflow_reset = PulseSynchronizer("sys", "pix")
- self.submodules.overflow_reset_ack = PulseSynchronizer("pix", "sys")
- self.comb += [
- pix_overflow_reset.eq(self.overflow_reset.o),
- self.overflow_reset_ack.i.eq(pix_overflow_reset)
- ]
-
- overflow_mask = Signal()
- self.comb += [
- self._overflow.w.eq(sys_overflow & ~overflow_mask),
- self.overflow_reset.i.eq(self._overflow.re)
- ]
- self.sync += \
- If(self._overflow.re,
- overflow_mask.eq(1)
- ).Elif(self.overflow_reset_ack.o,
- overflow_mask.eq(0)
- )
+++ /dev/null
-from functools import reduce
-from operator import or_, and_
-
-from migen import *
-from migen.genlib.cdc import MultiReg
-from migen.genlib.fifo import _inc
-from migen.genlib.record import Record, layout_len
-
-from misoc.interconnect.csr import *
-from misoc.cores.dvi_sampler.common import channel_layout
-
-
-class _SyncBuffer(Module):
- def __init__(self, width, depth):
- self.din = Signal(width)
- self.dout = Signal(width)
- self.re = Signal()
-
- ###
-
- produce = Signal(max=depth)
- consume = Signal(max=depth)
- storage = Memory(width, depth)
- self.specials += storage
-
- wrport = storage.get_port(write_capable=True)
- self.specials += wrport
- self.comb += [
- wrport.adr.eq(produce),
- wrport.dat_w.eq(self.din),
- wrport.we.eq(1)
- ]
- self.sync += _inc(produce, depth)
-
- rdport = storage.get_port(async_read=True)
- self.specials += rdport
- self.comb += [
- rdport.adr.eq(consume),
- self.dout.eq(rdport.dat_r)
- ]
- self.sync += If(self.re, _inc(consume, depth))
-
-
-class ChanSync(Module, AutoCSR):
- def __init__(self, nchan=3, depth=8):
- self.valid_i = Signal()
- self.chan_synced = Signal()
-
- self._channels_synced = CSRStatus()
-
- lst_control = []
- all_control = Signal()
- for i in range(nchan):
- name = "data_in" + str(i)
- data_in = Record(channel_layout, name=name)
- setattr(self, name, data_in)
- name = "data_out" + str(i)
- data_out = Record(channel_layout, name=name)
- setattr(self, name, data_out)
-
- ###
-
- syncbuffer = RenameClockDomains(_SyncBuffer(layout_len(channel_layout), depth), "pix")
- self.submodules += syncbuffer
- self.comb += [
- syncbuffer.din.eq(data_in.raw_bits()),
- data_out.raw_bits().eq(syncbuffer.dout)
- ]
- is_control = Signal()
- self.comb += [
- is_control.eq(~data_out.de),
- syncbuffer.re.eq(~is_control | all_control)
- ]
- lst_control.append(is_control)
-
- some_control = Signal()
- self.comb += [
- all_control.eq(reduce(and_, lst_control)),
- some_control.eq(reduce(or_, lst_control))
- ]
- self.sync.pix += If(~self.valid_i,
- self.chan_synced.eq(0)
- ).Else(
- If(some_control,
- If(all_control,
- self.chan_synced.eq(1)
- ).Else(
- self.chan_synced.eq(0)
- )
- )
- )
- self.specials += MultiReg(self.chan_synced, self._channels_synced.status)
-
-
-class _TB(Module):
- def __init__(self, test_seq_it):
- self.test_seq_it = test_seq_it
-
- self.submodules.chansync = RenameClockDomains(ChanSync(), {"pix": "sys"})
- self.comb += self.chansync.valid_i.eq(1)
-
- def do_simulation(self, selfp):
- try:
- de0, de1, de2 = next(self.test_seq_it)
- except StopIteration:
- raise StopSimulation
-
- selfp.chansync.data_in0.de = de0
- selfp.chansync.data_in1.de = de1
- selfp.chansync.data_in2.de = de2
- selfp.chansync.data_in0.d = selfp.simulator.cycle_counter
- selfp.chansync.data_in1.d = selfp.simulator.cycle_counter
- selfp.chansync.data_in2.d = selfp.simulator.cycle_counter
-
- out0 = selfp.chansync.data_out0.d
- out1 = selfp.chansync.data_out1.d
- out2 = selfp.chansync.data_out2.d
-
- print("{0:5} {1:5} {2:5}".format(out0, out1, out2))
-
-if __name__ == "__main__":
- from migen.sim.generic import run_simulation
-
- test_seq = [
- (1, 1, 1),
- (1, 1, 0),
- (0, 0, 0),
- (0, 0, 0),
- (0, 0, 1),
- (1, 1, 1),
- (1, 1, 1),
- ]
- tb = _TB(iter(test_seq*2))
- run_simulation(tb)
+++ /dev/null
-from functools import reduce
-from operator import or_
-
-from migen import *
-from migen.genlib.cdc import MultiReg
-
-from misoc.interconnect.csr import *
-from misoc.cores.dvi_sampler.common import control_tokens
-
-
-class CharSync(Module, AutoCSR):
- def __init__(self, required_controls=8):
- self.raw_data = Signal(10)
- self.synced = Signal()
- self.data = Signal(10)
-
- self._char_synced = CSRStatus()
- self._ctl_pos = CSRStatus(bits_for(9))
-
- ###
-
- raw_data1 = Signal(10)
- self.sync.pix += raw_data1.eq(self.raw_data)
- raw = Signal(20)
- self.comb += raw.eq(Cat(raw_data1, self.raw_data))
-
- found_control = Signal()
- control_position = Signal(max=10)
- self.sync.pix += found_control.eq(0)
- for i in range(10):
- self.sync.pix += If(reduce(or_, [raw[i:i+10] == t for t in control_tokens]),
- found_control.eq(1),
- control_position.eq(i)
- )
-
- control_counter = Signal(max=required_controls)
- previous_control_position = Signal(max=10)
- word_sel = Signal(max=10)
- self.sync.pix += [
- If(found_control & (control_position == previous_control_position),
- If(control_counter == (required_controls - 1),
- control_counter.eq(0),
- self.synced.eq(1),
- word_sel.eq(control_position)
- ).Else(
- control_counter.eq(control_counter + 1)
- )
- ).Else(
- control_counter.eq(0)
- ),
- previous_control_position.eq(control_position)
- ]
- self.specials += MultiReg(self.synced, self._char_synced.status)
- self.specials += MultiReg(word_sel, self._ctl_pos.status)
-
- self.sync.pix += self.data.eq(raw >> word_sel)
+++ /dev/null
-from migen import *
-from migen.genlib.cdc import MultiReg
-
-from misoc.interconnect.csr import *
-
-
-class Clocking(Module, AutoCSR):
- def __init__(self, pads):
- self._pll_reset = CSRStorage(reset=1)
- self._locked = CSRStatus()
-
- # DRP
- self._pll_adr = CSRStorage(5)
- self._pll_dat_r = CSRStatus(16)
- self._pll_dat_w = CSRStorage(16)
- self._pll_read = CSR()
- self._pll_write = CSR()
- self._pll_drdy = CSRStatus()
-
- self.locked = Signal()
- self.serdesstrobe = Signal()
- self.clock_domains._cd_pix = ClockDomain()
- self.clock_domains._cd_pix2x = ClockDomain()
- self.clock_domains._cd_pix10x = ClockDomain(reset_less=True)
-
- ###
-
- clk_se = Signal()
- self.specials += Instance("IBUFDS", i_I=pads.clk_p, i_IB=pads.clk_n, o_O=clk_se)
-
- clkfbout = Signal()
- pll_locked = Signal()
- pll_clk0 = Signal()
- pll_clk1 = Signal()
- pll_clk2 = Signal()
- pll_drdy = Signal()
- self.sync += If(self._pll_read.re | self._pll_write.re,
- self._pll_drdy.status.eq(0)
- ).Elif(pll_drdy,
- self._pll_drdy.status.eq(1)
- )
- self.specials += Instance("PLL_ADV",
- p_CLKFBOUT_MULT=10,
- p_CLKOUT0_DIVIDE=1, # pix10x
- p_CLKOUT1_DIVIDE=5, # pix2x
- p_CLKOUT2_DIVIDE=10, # pix
- p_COMPENSATION="INTERNAL",
-
- i_CLKINSEL=1,
- i_CLKIN1=clk_se,
- o_CLKOUT0=pll_clk0, o_CLKOUT1=pll_clk1, o_CLKOUT2=pll_clk2,
- o_CLKFBOUT=clkfbout, i_CLKFBIN=clkfbout,
- o_LOCKED=pll_locked, i_RST=self._pll_reset.storage,
-
- i_DADDR=self._pll_adr.storage,
- o_DO=self._pll_dat_r.status,
- i_DI=self._pll_dat_w.storage,
- i_DEN=self._pll_read.re | self._pll_write.re,
- i_DWE=self._pll_write.re,
- o_DRDY=pll_drdy,
- i_DCLK=ClockSignal())
-
- locked_async = Signal()
- self.specials += [
- Instance("BUFPLL", p_DIVIDE=5,
- i_PLLIN=pll_clk0, i_GCLK=ClockSignal("pix2x"), i_LOCKED=pll_locked,
- o_IOCLK=self._cd_pix10x.clk, o_LOCK=locked_async, o_SERDESSTROBE=self.serdesstrobe),
- Instance("BUFG", i_I=pll_clk1, o_O=self._cd_pix2x.clk),
- Instance("BUFG", i_I=pll_clk2, o_O=self._cd_pix.clk),
- MultiReg(locked_async, self.locked, "sys")
- ]
- self.comb += self._locked.status.eq(self.locked)
-
- # sychronize pix+pix2x reset
- pix_rst_n = 1
- for i in range(2):
- new_pix_rst_n = Signal()
- self.specials += Instance("FDCE", i_D=pix_rst_n, i_CE=1, i_C=ClockSignal("pix"),
- i_CLR=~locked_async, o_Q=new_pix_rst_n)
- pix_rst_n = new_pix_rst_n
- self.comb += self._cd_pix.rst.eq(~pix_rst_n), self._cd_pix2x.rst.eq(~pix_rst_n)
+++ /dev/null
-control_tokens = [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011]
-channel_layout = [("d", 8), ("c", 2), ("de", 1)]
+++ /dev/null
-from migen import *
-
-from misoc.interconnect.csr import AutoCSR
-from misoc.cores.dvi_sampler.edid import EDID
-from misoc.cores.dvi_sampler.clocking import Clocking
-from misoc.cores.dvi_sampler.datacapture import DataCapture
-from misoc.cores.dvi_sampler.charsync import CharSync
-from misoc.cores.dvi_sampler.wer import WER
-from misoc.cores.dvi_sampler.decoding import Decoding
-from misoc.cores.dvi_sampler.chansync import ChanSync
-from misoc.cores.dvi_sampler.analysis import SyncPolarity, ResolutionDetection, FrameExtraction
-from misoc.cores.dvi_sampler.dma import DMA
-
-
-class DVISampler(Module, AutoCSR):
- def __init__(self, pads, lasmim, n_dma_slots=2, fifo_depth=512):
- self.submodules.edid = EDID(pads)
- self.submodules.clocking = Clocking(pads)
-
- for datan in range(3):
- name = "data" + str(datan)
-
- cap = DataCapture(getattr(pads, name + "_p"), getattr(pads, name + "_n"), 8)
- setattr(self.submodules, name + "_cap", cap)
- self.comb += cap.serdesstrobe.eq(self.clocking.serdesstrobe)
-
- charsync = CharSync()
- setattr(self.submodules, name + "_charsync", charsync)
- self.comb += charsync.raw_data.eq(cap.d)
-
- wer = WER()
- setattr(self.submodules, name + "_wer", wer)
- self.comb += wer.data.eq(charsync.data)
-
- decoding = Decoding()
- setattr(self.submodules, name + "_decod", decoding)
- self.comb += [
- decoding.valid_i.eq(charsync.synced),
- decoding.input.eq(charsync.data)
- ]
-
- self.submodules.chansync = ChanSync()
- self.comb += [
- self.chansync.valid_i.eq(self.data0_decod.valid_o & \
- self.data1_decod.valid_o & self.data2_decod.valid_o),
- self.chansync.data_in0.eq(self.data0_decod.output),
- self.chansync.data_in1.eq(self.data1_decod.output),
- self.chansync.data_in2.eq(self.data2_decod.output),
- ]
-
- self.submodules.syncpol = SyncPolarity()
- self.comb += [
- self.syncpol.valid_i.eq(self.chansync.chan_synced),
- self.syncpol.data_in0.eq(self.chansync.data_out0),
- self.syncpol.data_in1.eq(self.chansync.data_out1),
- self.syncpol.data_in2.eq(self.chansync.data_out2)
- ]
-
- self.submodules.resdetection = ResolutionDetection()
- self.comb += [
- self.resdetection.valid_i.eq(self.syncpol.valid_o),
- self.resdetection.de.eq(self.syncpol.de),
- self.resdetection.vsync.eq(self.syncpol.vsync)
- ]
-
- self.submodules.frame = FrameExtraction(24*lasmim.dw//32, fifo_depth)
- self.comb += [
- self.frame.valid_i.eq(self.syncpol.valid_o),
- self.frame.de.eq(self.syncpol.de),
- self.frame.vsync.eq(self.syncpol.vsync),
- self.frame.r.eq(self.syncpol.r),
- self.frame.g.eq(self.syncpol.g),
- self.frame.b.eq(self.syncpol.b)
- ]
-
- self.submodules.dma = DMA(lasmim, n_dma_slots)
- self.comb += self.frame.frame.connect(self.dma.frame)
- self.ev = self.dma.ev
-
- autocsr_exclude = {"ev"}
+++ /dev/null
-from migen import *
-from migen.genlib.cdc import MultiReg, PulseSynchronizer
-
-from misoc.interconnect.csr import *
-
-
-class DataCapture(Module, AutoCSR):
- def __init__(self, pad_p, pad_n, ntbits):
- self.serdesstrobe = Signal()
- self.d = Signal(10)
-
- self._dly_ctl = CSR(6)
- self._dly_busy = CSRStatus(2)
- self._phase = CSRStatus(2)
- self._phase_reset = CSR()
-
- ###
-
- # IO
- pad_se = Signal()
- self.specials += Instance("IBUFDS", i_I=pad_p, i_IB=pad_n, o_O=pad_se)
-
- pad_delayed_master = Signal()
- pad_delayed_slave = Signal()
- delay_inc = Signal()
- delay_ce = Signal()
- delay_master_cal = Signal()
- delay_master_rst = Signal()
- delay_master_busy = Signal()
- delay_slave_cal = Signal()
- delay_slave_rst = Signal()
- delay_slave_busy = Signal()
- self.specials += Instance("IODELAY2",
- p_SERDES_MODE="MASTER",
- p_DELAY_SRC="IDATAIN", p_IDELAY_TYPE="DIFF_PHASE_DETECTOR",
- p_COUNTER_WRAPAROUND="STAY_AT_LIMIT", p_DATA_RATE="SDR",
-
- i_IDATAIN=pad_se, o_DATAOUT=pad_delayed_master,
- i_CLK=ClockSignal("pix2x"), i_IOCLK0=ClockSignal("pix10x"),
-
- i_INC=delay_inc, i_CE=delay_ce,
- i_CAL=delay_master_cal, i_RST=delay_master_rst, o_BUSY=delay_master_busy,
- i_T=1)
- self.specials += Instance("IODELAY2",
- p_SERDES_MODE="SLAVE",
- p_DELAY_SRC="IDATAIN", p_IDELAY_TYPE="DIFF_PHASE_DETECTOR",
- p_COUNTER_WRAPAROUND="WRAPAROUND", p_DATA_RATE="SDR",
-
- i_IDATAIN=pad_se, o_DATAOUT=pad_delayed_slave,
- i_CLK=ClockSignal("pix2x"), i_IOCLK0=ClockSignal("pix10x"),
-
- i_INC=delay_inc, i_CE=delay_ce,
- i_CAL=delay_slave_cal, i_RST=delay_slave_rst, o_BUSY=delay_slave_busy,
- i_T=1)
-
- dsr2 = Signal(5)
- pd_valid = Signal()
- pd_incdec = Signal()
- pd_edge = Signal()
- pd_cascade = Signal()
- self.specials += Instance("ISERDES2",
- p_SERDES_MODE="MASTER",
- p_BITSLIP_ENABLE="FALSE", p_DATA_RATE="SDR", p_DATA_WIDTH=5,
- p_INTERFACE_TYPE="RETIMED",
-
- i_D=pad_delayed_master,
- o_Q4=dsr2[4], o_Q3=dsr2[3], o_Q2=dsr2[2], o_Q1=dsr2[1],
-
- i_BITSLIP=0, i_CE0=1, i_RST=0,
- i_CLK0=ClockSignal("pix10x"), i_CLKDIV=ClockSignal("pix2x"),
- i_IOCE=self.serdesstrobe,
-
- o_VALID=pd_valid, o_INCDEC=pd_incdec,
- i_SHIFTIN=pd_edge, o_SHIFTOUT=pd_cascade)
- self.specials += Instance("ISERDES2",
- p_SERDES_MODE="SLAVE",
- p_BITSLIP_ENABLE="FALSE", p_DATA_RATE="SDR", p_DATA_WIDTH=5,
- p_INTERFACE_TYPE="RETIMED",
-
- i_D=pad_delayed_slave,
- o_Q4=dsr2[0],
-
- i_BITSLIP=0, i_CE0=1, i_RST=0,
- i_CLK0=ClockSignal("pix10x"), i_CLKDIV=ClockSignal("pix2x"),
- i_IOCE=self.serdesstrobe,
-
- i_SHIFTIN=pd_cascade, o_SHIFTOUT=pd_edge)
-
- # Phase error accumulator
- lateness = Signal(ntbits, reset=2**(ntbits - 1))
- too_late = Signal()
- too_early = Signal()
- reset_lateness = Signal()
- self.comb += [
- too_late.eq(lateness == (2**ntbits - 1)),
- too_early.eq(lateness == 0)
- ]
- self.sync.pix2x += [
- If(reset_lateness,
- lateness.eq(2**(ntbits - 1))
- ).Elif(~delay_master_busy & ~delay_slave_busy & ~too_late & ~too_early,
- If(pd_valid & pd_incdec, lateness.eq(lateness - 1)),
- If(pd_valid & ~pd_incdec, lateness.eq(lateness + 1))
- )
- ]
-
- # Delay control
- self.submodules.delay_master_done = PulseSynchronizer("pix2x", "sys")
- delay_master_pending = Signal()
- self.sync.pix2x += [
- self.delay_master_done.i.eq(0),
- If(~delay_master_pending,
- If(delay_master_cal | delay_ce, delay_master_pending.eq(1))
- ).Else(
- If(~delay_master_busy,
- self.delay_master_done.i.eq(1),
- delay_master_pending.eq(0)
- )
- )
- ]
- self.submodules.delay_slave_done = PulseSynchronizer("pix2x", "sys")
- delay_slave_pending = Signal()
- self.sync.pix2x += [
- self.delay_slave_done.i.eq(0),
- If(~delay_slave_pending,
- If(delay_slave_cal | delay_ce, delay_slave_pending.eq(1))
- ).Else(
- If(~delay_slave_busy,
- self.delay_slave_done.i.eq(1),
- delay_slave_pending.eq(0)
- )
- )
- ]
-
- self.submodules.do_delay_master_cal = PulseSynchronizer("sys", "pix2x")
- self.submodules.do_delay_master_rst = PulseSynchronizer("sys", "pix2x")
- self.submodules.do_delay_slave_cal = PulseSynchronizer("sys", "pix2x")
- self.submodules.do_delay_slave_rst = PulseSynchronizer("sys", "pix2x")
- self.submodules.do_delay_inc = PulseSynchronizer("sys", "pix2x")
- self.submodules.do_delay_dec = PulseSynchronizer("sys", "pix2x")
- self.comb += [
- delay_master_cal.eq(self.do_delay_master_cal.o),
- delay_master_rst.eq(self.do_delay_master_rst.o),
- delay_slave_cal.eq(self.do_delay_slave_cal.o),
- delay_slave_rst.eq(self.do_delay_slave_rst.o),
- delay_inc.eq(self.do_delay_inc.o),
- delay_ce.eq(self.do_delay_inc.o | self.do_delay_dec.o),
- ]
-
- sys_delay_master_pending = Signal()
- self.sync += [
- If(self.do_delay_master_cal.i | self.do_delay_inc.i | self.do_delay_dec.i,
- sys_delay_master_pending.eq(1)
- ).Elif(self.delay_master_done.o,
- sys_delay_master_pending.eq(0)
- )
- ]
- sys_delay_slave_pending = Signal()
- self.sync += [
- If(self.do_delay_slave_cal.i | self.do_delay_inc.i | self.do_delay_dec.i,
- sys_delay_slave_pending.eq(1)
- ).Elif(self.delay_slave_done.o,
- sys_delay_slave_pending.eq(0)
- )
- ]
-
- self.comb += [
- self.do_delay_master_cal.i.eq(self._dly_ctl.re & self._dly_ctl.r[0]),
- self.do_delay_master_rst.i.eq(self._dly_ctl.re & self._dly_ctl.r[1]),
- self.do_delay_slave_cal.i.eq(self._dly_ctl.re & self._dly_ctl.r[2]),
- self.do_delay_slave_rst.i.eq(self._dly_ctl.re & self._dly_ctl.r[3]),
- self.do_delay_inc.i.eq(self._dly_ctl.re & self._dly_ctl.r[4]),
- self.do_delay_dec.i.eq(self._dly_ctl.re & self._dly_ctl.r[5]),
- self._dly_busy.status.eq(Cat(sys_delay_master_pending, sys_delay_slave_pending))
- ]
-
- # Phase detector control
- self.specials += MultiReg(Cat(too_late, too_early), self._phase.status)
- self.submodules.do_reset_lateness = PulseSynchronizer("sys", "pix2x")
- self.comb += [
- reset_lateness.eq(self.do_reset_lateness.o),
- self.do_reset_lateness.i.eq(self._phase_reset.re)
- ]
-
- # 5:10 deserialization
- dsr = Signal(10)
- self.sync.pix2x += dsr.eq(Cat(dsr[5:], dsr2))
- self.sync.pix += self.d.eq(dsr)
+++ /dev/null
-from migen import *
-from migen.genlib.fifo import AsyncFIFO
-from migen.bank.description import AutoCSR
-from migen.actorlib import structuring, spi
-
-from misoc.cores.dvi_sampler.edid import EDID
-from misoc.cores.dvi_sampler.clocking import Clocking
-from misoc.cores.dvi_sampler.datacapture import DataCapture
-
-# TODO
-#from misoc.mem.sdram.frontend import dma_lasmi
-
-
-class RawDVISampler(Module, AutoCSR):
- def __init__(self, pads, asmiport):
- self.submodules.edid = EDID(pads)
- self.submodules.clocking = Clocking(pads)
-
- invert = False
- try:
- s = getattr(pads, "data0")
- except AttributeError:
- s = getattr(pads, "data0_n")
- invert = True
- self.submodules.data0_cap = DataCapture(8, invert)
- self.comb += [
- self.data0_cap.pad.eq(s),
- self.data0_cap.serdesstrobe.eq(self.clocking.serdesstrobe)
- ]
-
- fifo = RenameClockDomains(AsyncFIFO(10, 256),
- {"write": "pix", "read": "sys"})
- self.submodules += fifo
- self.comb += [
- fifo.din.eq(self.data0_cap.d),
- fifo.we.eq(1)
- ]
-
- pack_factor = asmiport.hub.dw//16
- self.submodules.packer = structuring.Pack([("word", 10), ("pad", 6)], pack_factor)
- self.submodules.cast = structuring.Cast(self.packer.source.payload.layout, asmiport.hub.dw)
- self.submodules.dma = spi.DMAWriteController(dma_lasmi.Writer(lasmim), spi.MODE_SINGLE_SHOT)
- self.comb += [
- self.packer.sink.stb.eq(fifo.readable),
- fifo.re.eq(self.packer.sink.ack),
- self.packer.sink.word.eq(fifo.dout),
- self.packer.source.connect_flat(self.cast.sink),
- self.cast.source.connect_flat(self.dma.data)
- ]
+++ /dev/null
-from migen import *
-from migen.genlib.record import Record
-
-from misoc.cores.dvi_sampler.common import control_tokens, channel_layout
-
-
-class Decoding(Module):
- def __init__(self):
- self.valid_i = Signal()
- self.input = Signal(10)
- self.valid_o = Signal()
- self.output = Record(channel_layout)
-
- ###
-
- self.sync.pix += self.output.de.eq(1)
- for i, t in enumerate(control_tokens):
- self.sync.pix += If(self.input == t,
- self.output.de.eq(0),
- self.output.c.eq(i)
- )
- self.sync.pix += self.output.d[0].eq(self.input[0] ^ self.input[9])
- for i in range(1, 8):
- self.sync.pix += self.output.d[i].eq(self.input[i] ^ self.input[i-1] ^ ~self.input[8])
- self.sync.pix += self.valid_o.eq(self.valid_i)
+++ /dev/null
-from migen import *
-from migen.genlib.fsm import FSM, NextState
-
-from misoc.interconnect.csr import *
-from misoc.interconnect.csr_eventmanager import *
-
-# TODO: rewrite dma_lasmi module
-# TODO: use stream packets to resync DMA
-#from misoc.mem.sdram.frontend import dma_lasmi
-
-
-# Slot status: EMPTY=0 LOADED=1 PENDING=2
-class _Slot(Module, AutoCSR):
- def __init__(self, addr_bits, alignment_bits):
- self.ev_source = EventSourceLevel()
- self.address = Signal(addr_bits)
- self.address_reached = Signal(addr_bits)
- self.address_valid = Signal()
- self.address_done = Signal()
-
- self._status = CSRStorage(2, write_from_dev=True)
- self._address = CSRStorage(addr_bits + alignment_bits, alignment_bits=alignment_bits, write_from_dev=True)
-
- ###
-
- self.comb += [
- self.address.eq(self._address.storage),
- self.address_valid.eq(self._status.storage[0]),
- self._status.dat_w.eq(2),
- self._status.we.eq(self.address_done),
- self._address.dat_w.eq(self.address_reached),
- self._address.we.eq(self.address_done),
- self.ev_source.trigger.eq(self._status.storage[1])
- ]
-
-
-class _SlotArray(Module, AutoCSR):
- def __init__(self, nslots, addr_bits, alignment_bits):
- self.submodules.ev = EventManager()
- self.address = Signal(addr_bits)
- self.address_reached = Signal(addr_bits)
- self.address_valid = Signal()
- self.address_done = Signal()
-
- ###
-
- slots = [_Slot(addr_bits, alignment_bits) for i in range(nslots)]
- for n, slot in enumerate(slots):
- setattr(self.submodules, "slot"+str(n), slot)
- setattr(self.ev, "slot"+str(n), slot.ev_source)
- self.ev.finalize()
-
- change_slot = Signal()
- current_slot = Signal(max=nslots)
- self.sync += If(change_slot, [If(slot.address_valid, current_slot.eq(n)) for n, slot in reversed(list(enumerate(slots)))])
- self.comb += change_slot.eq(~self.address_valid | self.address_done)
-
- self.comb += [
- self.address.eq(Array(slot.address for slot in slots)[current_slot]),
- self.address_valid.eq(Array(slot.address_valid for slot in slots)[current_slot])
- ]
- self.comb += [slot.address_reached.eq(self.address_reached) for slot in slots]
- self.comb += [slot.address_done.eq(self.address_done & (current_slot == n)) for n, slot in enumerate(slots)]
-
-
-class DMA(Module):
- def __init__(self, lasmim, nslots):
- bus_aw = lasmim.aw
- bus_dw = lasmim.dw
- alignment_bits = bits_for(bus_dw//8) - 1
-
- fifo_word_width = 24*bus_dw//32
- self.frame = Sink([("sof", 1), ("pixels", fifo_word_width)])
- self._frame_size = CSRStorage(bus_aw + alignment_bits, alignment_bits=alignment_bits)
- self.submodules._slot_array = _SlotArray(nslots, bus_aw, alignment_bits)
- self.ev = self._slot_array.ev
-
- ###
-
- # address generator + maximum memory word count to prevent DMA buffer overrun
- reset_words = Signal()
- count_word = Signal()
- last_word = Signal()
- current_address = Signal(bus_aw)
- mwords_remaining = Signal(bus_aw)
- self.comb += [
- self._slot_array.address_reached.eq(current_address),
- last_word.eq(mwords_remaining == 1)
- ]
- self.sync += [
- If(reset_words,
- current_address.eq(self._slot_array.address),
- mwords_remaining.eq(self._frame_size.storage)
- ).Elif(count_word,
- current_address.eq(current_address + 1),
- mwords_remaining.eq(mwords_remaining - 1)
- )
- ]
-
- # 24bpp -> 32bpp
- memory_word = Signal(bus_dw)
- pixbits = []
- for i in range(bus_dw//32):
- for j in range(3):
- b = (i*3+j)*8
- pixbits.append(self.frame.pixels[b+6:b+8])
- pixbits.append(self.frame.pixels[b:b+8])
- pixbits.append(0)
- pixbits.append(0)
- self.comb += memory_word.eq(Cat(*pixbits))
-
- # bus accessor
- self.submodules._bus_accessor = dma_lasmi.Writer(lasmim)
- self.comb += [
- self._bus_accessor.address_data.a.eq(current_address),
- self._bus_accessor.address_data.d.eq(memory_word)
- ]
-
- # control FSM
- fsm = FSM()
- self.submodules += fsm
-
- fsm.act("WAIT_SOF",
- reset_words.eq(1),
- self.frame.ack.eq(~self._slot_array.address_valid | ~self.frame.sof),
- If(self._slot_array.address_valid & self.frame.sof & self.frame.stb, NextState("TRANSFER_PIXELS"))
- )
- fsm.act("TRANSFER_PIXELS",
- self.frame.ack.eq(self._bus_accessor.address_data.ack),
- If(self.frame.stb,
- self._bus_accessor.address_data.stb.eq(1),
- If(self._bus_accessor.address_data.ack,
- count_word.eq(1),
- If(last_word, NextState("EOF"))
- )
- )
- )
- fsm.act("EOF",
- If(~self._bus_accessor.busy,
- self._slot_array.address_done.eq(1),
- NextState("WAIT_SOF")
- )
- )
-
- def get_csrs(self):
- return [self._frame_size] + self._slot_array.get_csrs()
+++ /dev/null
-from migen import *
-from migen.fhdl.specials import Tristate
-from migen.genlib.cdc import MultiReg
-from migen.genlib.fsm import FSM, NextState
-from migen.genlib.misc import chooser
-
-from misoc.interconnect.csr import CSRStorage, CSRStatus, AutoCSR
-
-
-_default_edid = [
- 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x3D, 0x17, 0x32, 0x12, 0x2A, 0x6A, 0xBF, 0x00,
- 0x05, 0x17, 0x01, 0x03, 0x80, 0x28, 0x1E, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xB2, 0x0C, 0x00, 0x40, 0x41, 0x00, 0x26, 0x30, 0x18, 0x88,
- 0x36, 0x00, 0x28, 0x1E, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x4D, 0x31, 0x20,
- 0x44, 0x56, 0x49, 0x20, 0x6D, 0x69, 0x78, 0x65, 0x72, 0x0A, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34,
-]
-
-
-class EDID(Module, AutoCSR):
- def __init__(self, pads, default=_default_edid):
- self._hpd_notif = CSRStatus()
- self._hpd_en = CSRStorage()
- self.specials.mem = Memory(8, 128, init=default)
-
- ###
-
- # HPD
- if hasattr(pads, "hpd_notif"):
- self.specials += MultiReg(pads.hpd_notif, self._hpd_notif.status)
- else:
- self.comb += self._hpd_notif.status.eq(1)
- if hasattr(pads, "hpd_en"):
- self.comb += pads.hpd_en.eq(self._hpd_en.storage)
-
- # EDID
- scl_raw = Signal()
- sda_i = Signal()
- sda_raw = Signal()
- sda_drv = Signal()
- _sda_drv_reg = Signal()
- _sda_i_async = Signal()
- self.sync += _sda_drv_reg.eq(sda_drv)
- self.specials += [
- MultiReg(pads.scl, scl_raw),
- Tristate(pads.sda, 0, _sda_drv_reg, _sda_i_async),
- MultiReg(_sda_i_async, sda_raw)
- ]
-
- scl_i = Signal()
- samp_count = Signal(6)
- samp_carry = Signal()
- self.sync += [
- Cat(samp_count, samp_carry).eq(samp_count + 1),
- If(samp_carry,
- scl_i.eq(scl_raw),
- sda_i.eq(sda_raw)
- )
- ]
-
- scl_r = Signal()
- sda_r = Signal()
- scl_rising = Signal()
- sda_rising = Signal()
- sda_falling = Signal()
- self.sync += [
- scl_r.eq(scl_i),
- sda_r.eq(sda_i)
- ]
- self.comb += [
- scl_rising.eq(scl_i & ~scl_r),
- sda_rising.eq(sda_i & ~sda_r),
- sda_falling.eq(~sda_i & sda_r)
- ]
-
- start = Signal()
- self.comb += start.eq(scl_i & sda_falling)
-
- din = Signal(8)
- counter = Signal(max=9)
- self.sync += [
- If(start, counter.eq(0)),
- If(scl_rising,
- If(counter == 8,
- counter.eq(0)
- ).Else(
- counter.eq(counter + 1),
- din.eq(Cat(sda_i, din[:7]))
- )
- )
- ]
-
- is_read = Signal()
- update_is_read = Signal()
- self.sync += If(update_is_read, is_read.eq(din[0]))
-
- offset_counter = Signal(max=128)
- oc_load = Signal()
- oc_inc = Signal()
- self.sync += [
- If(oc_load,
- offset_counter.eq(din)
- ).Elif(oc_inc,
- offset_counter.eq(offset_counter + 1)
- )
- ]
- rdport = self.mem.get_port()
- self.specials += rdport
- self.comb += rdport.adr.eq(offset_counter)
- data_bit = Signal()
-
- zero_drv = Signal()
- data_drv = Signal()
- self.comb += If(zero_drv, sda_drv.eq(1)).Elif(data_drv, sda_drv.eq(~data_bit))
-
- data_drv_en = Signal()
- data_drv_stop = Signal()
- self.sync += If(data_drv_en, data_drv.eq(1)).Elif(data_drv_stop, data_drv.eq(0))
- self.sync += If(data_drv_en, chooser(rdport.dat_r, counter, data_bit, 8, reverse=True))
-
- fsm = FSM()
- self.submodules += fsm
-
- fsm.act("WAIT_START")
- fsm.act("RCV_ADDRESS",
- If(counter == 8,
- If(din[1:] == 0x50,
- update_is_read.eq(1),
- NextState("ACK_ADDRESS0")
- ).Else(
- NextState("WAIT_START")
- )
- )
- )
- fsm.act("ACK_ADDRESS0",
- If(~scl_i, NextState("ACK_ADDRESS1"))
- )
- fsm.act("ACK_ADDRESS1",
- zero_drv.eq(1),
- If(scl_i, NextState("ACK_ADDRESS2"))
- )
- fsm.act("ACK_ADDRESS2",
- zero_drv.eq(1),
- If(~scl_i,
- If(is_read,
- NextState("READ")
- ).Else(
- NextState("RCV_OFFSET")
- )
- )
- )
-
- fsm.act("RCV_OFFSET",
- If(counter == 8,
- oc_load.eq(1),
- NextState("ACK_OFFSET0")
- )
- )
- fsm.act("ACK_OFFSET0",
- If(~scl_i, NextState("ACK_OFFSET1"))
- )
- fsm.act("ACK_OFFSET1",
- zero_drv.eq(1),
- If(scl_i, NextState("ACK_OFFSET2"))
- )
- fsm.act("ACK_OFFSET2",
- zero_drv.eq(1),
- If(~scl_i, NextState("RCV_ADDRESS"))
- )
-
- fsm.act("READ",
- If(~scl_i,
- If(counter == 8,
- data_drv_stop.eq(1),
- NextState("ACK_READ")
- ).Else(
- data_drv_en.eq(1)
- )
- )
- )
- fsm.act("ACK_READ",
- If(scl_rising,
- oc_inc.eq(1),
- If(sda_i,
- NextState("WAIT_START")
- ).Else(
- NextState("READ")
- )
- )
- )
-
- for state in fsm.actions.keys():
- fsm.act(state, If(start, NextState("RCV_ADDRESS")))
- fsm.act(state, If(~self._hpd_en.storage, NextState("WAIT_START")))
+++ /dev/null
-from functools import reduce
-from operator import add, or_
-
-from migen import *
-from migen.genlib.cdc import PulseSynchronizer
-
-from misoc.interconnect.csr import *
-from misoc.cores.dvi_sampler.common import control_tokens
-
-
-class WER(Module, AutoCSR):
- def __init__(self, period_bits=24):
- self.data = Signal(10)
- self._update = CSR()
- self._value = CSRStatus(period_bits)
-
- ###
-
- # pipeline stage 1
- # we ignore the 10th (inversion) bit, as it is independent of the transition minimization
- data_r = Signal(9)
- self.sync.pix += data_r.eq(self.data[:9])
-
- # pipeline stage 2
- transitions = Signal(8)
- self.comb += [transitions[i].eq(data_r[i] ^ data_r[i+1]) for i in range(8)]
- transition_count = Signal(max=9)
- self.sync.pix += transition_count.eq(reduce(add, [transitions[i] for i in range(8)]))
-
- is_control = Signal()
- self.sync.pix += is_control.eq(reduce(or_, [data_r == ct for ct in control_tokens]))
-
- # pipeline stage 3
- is_error = Signal()
- self.sync.pix += is_error.eq((transition_count > 4) & ~is_control)
-
- # counter
- period_counter = Signal(period_bits)
- period_done = Signal()
- self.sync.pix += Cat(period_counter, period_done).eq(period_counter + 1)
-
- wer_counter = Signal(period_bits)
- wer_counter_r = Signal(period_bits)
- wer_counter_r_updated = Signal()
- self.sync.pix += [
- wer_counter_r_updated.eq(period_done),
- If(period_done,
- wer_counter_r.eq(wer_counter),
- wer_counter.eq(0)
- ).Elif(is_error,
- wer_counter.eq(wer_counter + 1)
- )
- ]
-
- # sync to system clock domain
- wer_counter_sys = Signal(period_bits)
- self.submodules.ps_counter = PulseSynchronizer("pix", "sys")
- self.comb += self.ps_counter.i.eq(wer_counter_r_updated)
- self.sync += If(self.ps_counter.o, wer_counter_sys.eq(wer_counter_r))
-
- # register interface
- self.sync += If(self._update.re, self._value.status.eq(wer_counter_sys))
+++ /dev/null
-from misoc.cores.framebuffer.core import Framebuffer
+++ /dev/null
-from migen import *
-from migen.flow.network import *
-from migen.flow import plumbing
-from migen.bank.description import AutoCSR
-from migen.actorlib import structuring, misc
-
-from misoc.mem.sdram.frontend import dma_lasmi
-from misoc.framebuffer.format import bpp, pixel_layout, FrameInitiator, VTG
-from misoc.framebuffer.phy import Driver
-
-
-class Framebuffer(Module, AutoCSR):
- def __init__(self, pads_vga, pads_dvi, lasmim):
- pack_factor = lasmim.dw//bpp
-
- g = DataFlowGraph()
-
- self.fi = FrameInitiator(lasmim.aw, pack_factor)
-
- intseq = misc.IntSequence(lasmim.aw, lasmim.aw)
- dma_out = AbstractActor(plumbing.Buffer)
- g.add_connection(self.fi, intseq, source_subr=self.fi.dma_subr())
- g.add_pipeline(intseq, AbstractActor(plumbing.Buffer), dma_lasmi.Reader(lasmim), dma_out)
-
- cast = structuring.Cast(lasmim.dw, pixel_layout(pack_factor), reverse_to=True)
- vtg = VTG(pack_factor)
- self.driver = Driver(pack_factor, pads_vga, pads_dvi)
-
- g.add_connection(self.fi, vtg, source_subr=self.fi.timing_subr, sink_ep="timing")
- g.add_connection(dma_out, cast)
- g.add_connection(cast, vtg, sink_ep="pixels")
- g.add_connection(vtg, self.driver)
- self.submodules += CompositeActor(g)
+++ /dev/null
-from functools import reduce
-from operator import add
-
-from migen import *
-
-
-control_tokens = [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011]
-
-
-class Encoder(Module):
- def __init__(self):
- self.d = Signal(8)
- self.c = Signal(2)
- self.de = Signal()
-
- self.out = Signal(10)
-
- ###
-
- # stage 1 - count number of 1s in data
- d = Signal(8)
- n1d = Signal(max=9)
- self.sync += [
- n1d.eq(reduce(add, [self.d[i] for i in range(8)])),
- d.eq(self.d)
- ]
-
- # stage 2 - add 9th bit
- q_m = Signal(9)
- q_m8_n = Signal()
- self.comb += q_m8_n.eq((n1d > 4) | ((n1d == 4) & ~d[0]))
- for i in range(8):
- if i:
- curval = curval ^ d[i] ^ q_m8_n
- else:
- curval = d[0]
- self.sync += q_m[i].eq(curval)
- self.sync += q_m[8].eq(~q_m8_n)
-
- # stage 3 - count number of 1s and 0s in q_m[:8]
- q_m_r = Signal(9)
- n0q_m = Signal(max=9)
- n1q_m = Signal(max=9)
- self.sync += [
- n0q_m.eq(reduce(add, [~q_m[i] for i in range(8)])),
- n1q_m.eq(reduce(add, [q_m[i] for i in range(8)])),
- q_m_r.eq(q_m)
- ]
-
- # stage 4 - final encoding
- cnt = Signal((6, True))
-
- s_c = self.c
- s_de = self.de
- for p in range(3):
- new_c = Signal(2)
- new_de = Signal()
- self.sync += new_c.eq(s_c), new_de.eq(s_de)
- s_c, s_de = new_c, new_de
-
- self.sync += If(s_de,
- If((cnt == 0) | (n1q_m == n0q_m),
- self.out[9].eq(~q_m_r[8]),
- self.out[8].eq(q_m_r[8]),
- If(q_m_r[8],
- self.out[:8].eq(q_m_r[:8]),
- cnt.eq(cnt + n1q_m - n0q_m)
- ).Else(
- self.out[:8].eq(~q_m_r[:8]),
- cnt.eq(cnt + n0q_m - n1q_m)
- )
- ).Else(
- If((~cnt[5] & (n1q_m > n0q_m)) | (cnt[5] & (n0q_m > n1q_m)),
- self.out[9].eq(1),
- self.out[8].eq(q_m_r[8]),
- self.out[:8].eq(~q_m_r[:8]),
- cnt.eq(cnt + Cat(0, q_m_r[8]) + n0q_m - n1q_m)
- ).Else(
- self.out[9].eq(0),
- self.out[8].eq(q_m_r[8]),
- self.out[:8].eq(q_m_r[:8]),
- cnt.eq(cnt - Cat(0, ~q_m_r[8]) + n1q_m - n0q_m)
- )
- )
- ).Else(
- self.out.eq(Array(control_tokens)[s_c]),
- cnt.eq(0)
- )
-
-
-class _EncoderSerializer(Module):
- def __init__(self, serdesstrobe, pad_p, pad_n):
- self.submodules.encoder = RenameClockDomains(Encoder(), "pix")
- self.d, self.c, self.de = self.encoder.d, self.encoder.c, self.encoder.de
-
- ###
-
- # 2X soft serialization
- ed_2x = Signal(5)
- self.sync.pix2x += ed_2x.eq(Mux(ClockSignal("pix"), self.encoder.out[:5], self.encoder.out[5:]))
-
- # 5X hard serialization
- cascade_di = Signal()
- cascade_do = Signal()
- cascade_ti = Signal()
- cascade_to = Signal()
- pad_se = Signal()
- self.specials += [
- Instance("OSERDES2",
- p_DATA_WIDTH=5, p_DATA_RATE_OQ="SDR", p_DATA_RATE_OT="SDR",
- p_SERDES_MODE="MASTER", p_OUTPUT_MODE="DIFFERENTIAL",
-
- o_OQ=pad_se,
- i_OCE=1, i_IOCE=serdesstrobe, i_RST=0,
- i_CLK0=ClockSignal("pix10x"), i_CLK1=0, i_CLKDIV=ClockSignal("pix2x"),
- i_D1=ed_2x[4], i_D2=0, i_D3=0, i_D4=0,
- i_T1=0, i_T2=0, i_T3=0, i_T4=0,
- i_TRAIN=0, i_TCE=1,
- i_SHIFTIN1=1, i_SHIFTIN2=1,
- i_SHIFTIN3=cascade_do, i_SHIFTIN4=cascade_to,
- o_SHIFTOUT1=cascade_di, o_SHIFTOUT2=cascade_ti),
- Instance("OSERDES2",
- p_DATA_WIDTH=5, p_DATA_RATE_OQ="SDR", p_DATA_RATE_OT="SDR",
- p_SERDES_MODE="SLAVE", p_OUTPUT_MODE="DIFFERENTIAL",
-
- i_OCE=1, i_IOCE=serdesstrobe, i_RST=0,
- i_CLK0=ClockSignal("pix10x"), i_CLK1=0, i_CLKDIV=ClockSignal("pix2x"),
- i_D1=ed_2x[0], i_D2=ed_2x[1], i_D3=ed_2x[2], i_D4=ed_2x[3],
- i_T1=0, i_T2=0, i_T3=0, i_T4=0,
- i_TRAIN=0, i_TCE=1,
- i_SHIFTIN1=cascade_di, i_SHIFTIN2=cascade_ti,
- i_SHIFTIN3=1, i_SHIFTIN4=1,
- o_SHIFTOUT3=cascade_do, o_SHIFTOUT4=cascade_to),
- Instance("OBUFDS", i_I=pad_se, o_O=pad_p, o_OB=pad_n)
- ]
-
-
-class PHY(Module):
- def __init__(self, serdesstrobe, pads):
- self.hsync = Signal()
- self.vsync = Signal()
- self.de = Signal()
- self.r = Signal(8)
- self.g = Signal(8)
- self.b = Signal(8)
-
- ###
-
- self.submodules.es0 = _EncoderSerializer(serdesstrobe, pads.data0_p, pads.data0_n)
- self.submodules.es1 = _EncoderSerializer(serdesstrobe, pads.data1_p, pads.data1_n)
- self.submodules.es2 = _EncoderSerializer(serdesstrobe, pads.data2_p, pads.data2_n)
- self.comb += [
- self.es0.d.eq(self.r),
- self.es1.d.eq(self.g),
- self.es2.d.eq(self.b),
- self.es0.c.eq(Cat(self.hsync, self.vsync)),
- self.es1.c.eq(0),
- self.es2.c.eq(0),
- self.es0.de.eq(self.de),
- self.es1.de.eq(self.de),
- self.es2.de.eq(self.de),
- ]
-
-
-class _EncoderTB(Module):
- def __init__(self, inputs):
- self.outs = []
- self._iter_inputs = iter(inputs)
- self._end_cycle = None
- self.submodules.dut = Encoder()
- self.comb += self.dut.de.eq(1)
-
- def do_simulation(self, selfp):
- if self._end_cycle is None:
- try:
- nv = next(self._iter_inputs)
- except StopIteration:
- self._end_cycle = selfp.simulator.cycle_counter + 4
- else:
- selfp.dut.d = nv
- if selfp.simulator.cycle_counter == self._end_cycle:
- raise StopSimulation
- if selfp.simulator.cycle_counter > 4:
- self.outs.append(selfp.dut.out)
-
-
-def _bit(i, n):
- return (i >> n) & 1
-
-
-def _decode_tmds(b):
- try:
- c = control_tokens.index(b)
- de = False
- except ValueError:
- c = 0
- de = True
- vsync = bool(c & 2)
- hsync = bool(c & 1)
-
- value = _bit(b, 0) ^ _bit(b, 9)
- for i in range(1, 8):
- value |= (_bit(b, i) ^ _bit(b, i-1) ^ (~_bit(b, 8) & 1)) << i
-
- return de, hsync, vsync, value
-
-if __name__ == "__main__":
- from migen.sim.generic import run_simulation
- from random import Random
-
- rng = Random(788)
- test_list = [rng.randrange(256) for i in range(500)]
- tb = _EncoderTB(test_list)
- run_simulation(tb)
-
- check = [_decode_tmds(out)[3] for out in tb.outs]
- assert(check == test_list)
-
- nb0 = 0
- nb1 = 0
- for out in tb.outs:
- for i in range(10):
- if _bit(out, i):
- nb1 += 1
- else:
- nb0 += 1
- print("0/1: {}/{} ({:.2f})".format(nb0, nb1, nb0/nb1))
+++ /dev/null
-from migen import *
-from migen.flow.actor import *
-from migen.bank.description import CSRStorage
-from migen.genlib.record import Record
-from migen.genlib.fsm import FSM, NextState
-from migen.actorlib import spi
-
-_hbits = 12
-_vbits = 12
-
-bpp = 32
-bpc = 10
-pixel_layout_s = [
- ("pad", bpp-3*bpc),
- ("r", bpc),
- ("g", bpc),
- ("b", bpc)
-]
-
-
-def pixel_layout(pack_factor):
- return [("p"+str(i), pixel_layout_s) for i in range(pack_factor)]
-
-bpc_phy = 8
-phy_layout_s = [
- ("r", bpc_phy),
- ("g", bpc_phy),
- ("b", bpc_phy)
-]
-
-
-def phy_layout(pack_factor):
- r = [("hsync", 1), ("vsync", 1), ("de", 1)]
- for i in range(pack_factor):
- r.append(("p"+str(i), phy_layout_s))
- return r
-
-
-class FrameInitiator(spi.SingleGenerator):
- def __init__(self, bus_aw, pack_factor, ndmas=1):
- h_alignment_bits = log2_int(pack_factor)
- hbits_dyn = _hbits - h_alignment_bits
- bus_alignment_bits = h_alignment_bits + log2_int(bpp//8)
- layout = [
- ("hres", hbits_dyn, 640, h_alignment_bits),
- ("hsync_start", hbits_dyn, 656, h_alignment_bits),
- ("hsync_end", hbits_dyn, 752, h_alignment_bits),
- ("hscan", hbits_dyn, 800, h_alignment_bits),
-
- ("vres", _vbits, 480),
- ("vsync_start", _vbits, 492),
- ("vsync_end", _vbits, 494),
- ("vscan", _vbits, 525),
-
- ("length", bus_aw + bus_alignment_bits, 640*480*bpp//8, bus_alignment_bits)
- ]
- layout += [("base"+str(i), bus_aw + bus_alignment_bits, 0, bus_alignment_bits)
- for i in range(ndmas)]
- spi.SingleGenerator.__init__(self, layout, spi.MODE_CONTINUOUS)
-
- timing_subr = ["hres", "hsync_start", "hsync_end", "hscan",
- "vres", "vsync_start", "vsync_end", "vscan"]
-
- def dma_subr(self, i=0):
- return ["length", "base"+str(i)]
-
-
-class VTG(Module):
- def __init__(self, pack_factor):
- hbits_dyn = _hbits - log2_int(pack_factor)
- timing_layout = [
- ("hres", hbits_dyn),
- ("hsync_start", hbits_dyn),
- ("hsync_end", hbits_dyn),
- ("hscan", hbits_dyn),
- ("vres", _vbits),
- ("vsync_start", _vbits),
- ("vsync_end", _vbits),
- ("vscan", _vbits)]
- self.timing = Sink(timing_layout)
- self.pixels = Sink(pixel_layout(pack_factor))
- self.phy = Source(phy_layout(pack_factor))
- self.busy = Signal()
-
- ###
-
- hactive = Signal()
- vactive = Signal()
- active = Signal()
-
- hcounter = Signal(hbits_dyn)
- vcounter = Signal(_vbits)
-
- skip = bpc - bpc_phy
- self.comb += [
- active.eq(hactive & vactive),
- If(active,
- [getattr(getattr(self.phy.payload, p), c).eq(getattr(getattr(self.pixels.payload, p), c)[skip:])
- for p in ["p"+str(i) for i in range(pack_factor)] for c in ["r", "g", "b"]],
- self.phy.de.eq(1)
- ),
- self.pixels.ack.eq(self.phy.ack & active)
- ]
-
- load_timing = Signal()
- tr = Record(timing_layout)
- self.sync += If(load_timing, tr.eq(self.timing.payload))
-
- generate_en = Signal()
- generate_frame_done = Signal()
- self.sync += [
- generate_frame_done.eq(0),
- If(generate_en,
- hcounter.eq(hcounter + 1),
-
- If(hcounter == 0, hactive.eq(1)),
- If(hcounter == tr.hres, hactive.eq(0)),
- If(hcounter == tr.hsync_start, self.phy.hsync.eq(1)),
- If(hcounter == tr.hsync_end, self.phy.hsync.eq(0)),
- If(hcounter == tr.hscan,
- hcounter.eq(0),
- If(vcounter == tr.vscan,
- vcounter.eq(0),
- generate_frame_done.eq(1)
- ).Else(
- vcounter.eq(vcounter + 1)
- )
- ),
-
- If(vcounter == 0, vactive.eq(1)),
- If(vcounter == tr.vres, vactive.eq(0)),
- If(vcounter == tr.vsync_start, self.phy.vsync.eq(1)),
- If(vcounter == tr.vsync_end, self.phy.vsync.eq(0))
- )
- ]
-
- self.submodules.fsm = FSM()
- self.fsm.act("GET_TIMING",
- self.timing.ack.eq(1),
- load_timing.eq(1),
- If(self.timing.stb, NextState("GENERATE"))
- )
- self.fsm.act("GENERATE",
- self.busy.eq(1),
- If(~active | self.pixels.stb,
- self.phy.stb.eq(1),
- If(self.phy.ack, generate_en.eq(1))
- ),
- If(generate_frame_done, NextState("GET_TIMING"))
- )
+++ /dev/null
-from migen import *
-from migen.genlib.fifo import AsyncFIFO
-from migen.genlib.cdc import MultiReg
-from migen.bank.description import *
-from migen.flow.actor import *
-
-from misoc.framebuffer.format import bpc_phy, phy_layout
-from misoc.framebuffer import dvi
-
-
-class _FIFO(Module):
- def __init__(self, pack_factor):
- self.phy = Sink(phy_layout(pack_factor))
- self.busy = Signal()
-
- self.pix_hsync = Signal()
- self.pix_vsync = Signal()
- self.pix_de = Signal()
- self.pix_r = Signal(bpc_phy)
- self.pix_g = Signal(bpc_phy)
- self.pix_b = Signal(bpc_phy)
-
- ###
-
- fifo = RenameClockDomains(AsyncFIFO(phy_layout(pack_factor), 512),
- {"write": "sys", "read": "pix"})
- self.submodules += fifo
- self.comb += [
- self.phy.ack.eq(fifo.writable),
- fifo.we.eq(self.phy.stb),
- fifo.din.eq(self.phy.payload),
- self.busy.eq(0)
- ]
-
- unpack_counter = Signal(max=pack_factor)
- assert(pack_factor & (pack_factor - 1) == 0) # only support powers of 2
- self.sync.pix += [
- unpack_counter.eq(unpack_counter + 1),
- self.pix_hsync.eq(fifo.dout.hsync),
- self.pix_vsync.eq(fifo.dout.vsync),
- self.pix_de.eq(fifo.dout.de)
- ]
- for i in range(pack_factor):
- pixel = getattr(fifo.dout, "p"+str(i))
- self.sync.pix += If(unpack_counter == i,
- self.pix_r.eq(pixel.r),
- self.pix_g.eq(pixel.g),
- self.pix_b.eq(pixel.b)
- )
- self.comb += fifo.re.eq(unpack_counter == (pack_factor - 1))
-
-
-# This assumes a 50MHz base clock
-class _Clocking(Module, AutoCSR):
- def __init__(self, pads_vga, pads_dvi):
- self._cmd_data = CSRStorage(10)
- self._send_cmd_data = CSR()
- self._send_go = CSR()
- self._status = CSRStatus(4)
-
- self.clock_domains.cd_pix = ClockDomain(reset_less=True)
- if pads_dvi is not None:
- self._pll_reset = CSRStorage()
- self._pll_adr = CSRStorage(5)
- self._pll_dat_r = CSRStatus(16)
- self._pll_dat_w = CSRStorage(16)
- self._pll_read = CSR()
- self._pll_write = CSR()
- self._pll_drdy = CSRStatus()
-
- self.clock_domains.cd_pix2x = ClockDomain(reset_less=True)
- self.clock_domains.cd_pix10x = ClockDomain(reset_less=True)
- self.serdesstrobe = Signal()
-
- ###
-
- # Generate 1x pixel clock
- clk_pix_unbuffered = Signal()
- pix_progdata = Signal()
- pix_progen = Signal()
- pix_progdone = Signal()
- pix_locked = Signal()
- self.specials += Instance("DCM_CLKGEN",
- p_CLKFXDV_DIVIDE=2, p_CLKFX_DIVIDE=4, p_CLKFX_MD_MAX=1.0, p_CLKFX_MULTIPLY=2,
- p_CLKIN_PERIOD=20.0, p_SPREAD_SPECTRUM="NONE", p_STARTUP_WAIT="FALSE",
-
- i_CLKIN=ClockSignal("base50"), o_CLKFX=clk_pix_unbuffered,
- i_PROGCLK=ClockSignal(), i_PROGDATA=pix_progdata, i_PROGEN=pix_progen,
- o_PROGDONE=pix_progdone, o_LOCKED=pix_locked,
- i_FREEZEDCM=0, i_RST=ResetSignal())
-
- remaining_bits = Signal(max=11)
- transmitting = Signal()
- self.comb += transmitting.eq(remaining_bits != 0)
- sr = Signal(10)
- self.sync += [
- If(self._send_cmd_data.re,
- remaining_bits.eq(10),
- sr.eq(self._cmd_data.storage)
- ).Elif(transmitting,
- remaining_bits.eq(remaining_bits - 1),
- sr.eq(sr[1:])
- )
- ]
- self.comb += [
- pix_progdata.eq(transmitting & sr[0]),
- pix_progen.eq(transmitting | self._send_go.re)
- ]
-
- # enforce gap between commands
- busy_counter = Signal(max=14)
- busy = Signal()
- self.comb += busy.eq(busy_counter != 0)
- self.sync += If(self._send_cmd_data.re,
- busy_counter.eq(13)
- ).Elif(busy,
- busy_counter.eq(busy_counter - 1)
- )
-
- mult_locked = Signal()
- self.comb += self._status.status.eq(Cat(busy, pix_progdone, pix_locked, mult_locked))
-
- # Clock multiplication and buffering
- if pads_dvi is None:
- # Just buffer 1x pixel clock
- self.specials += Instance("BUFG", i_I=clk_pix_unbuffered, o_O=self.cd_pix.clk)
- self.comb += mult_locked.eq(pix_locked)
- else:
- # Route unbuffered 1x pixel clock to PLL
- # Generate 1x, 2x and 10x IO pixel clocks
- clkfbout = Signal()
- pll_locked = Signal()
- pll_clk0 = Signal()
- pll_clk1 = Signal()
- pll_clk2 = Signal()
- locked_async = Signal()
- pll_drdy = Signal()
- self.sync += If(self._pll_read.re | self._pll_write.re,
- self._pll_drdy.status.eq(0)
- ).Elif(pll_drdy,
- self._pll_drdy.status.eq(1)
- )
- self.specials += [
- Instance("PLL_ADV",
- p_CLKFBOUT_MULT=10,
- p_CLKOUT0_DIVIDE=1, # pix10x
- p_CLKOUT1_DIVIDE=5, # pix2x
- p_CLKOUT2_DIVIDE=10, # pix
- p_COMPENSATION="INTERNAL",
-
- i_CLKINSEL=1,
- i_CLKIN1=clk_pix_unbuffered,
- o_CLKOUT0=pll_clk0, o_CLKOUT1=pll_clk1, o_CLKOUT2=pll_clk2,
- o_CLKFBOUT=clkfbout, i_CLKFBIN=clkfbout,
- o_LOCKED=pll_locked,
- i_RST=~pix_locked | self._pll_reset.storage,
-
- i_DADDR=self._pll_adr.storage,
- o_DO=self._pll_dat_r.status,
- i_DI=self._pll_dat_w.storage,
- i_DEN=self._pll_read.re | self._pll_write.re,
- i_DWE=self._pll_write.re,
- o_DRDY=pll_drdy,
- i_DCLK=ClockSignal()),
- Instance("BUFPLL", p_DIVIDE=5,
- i_PLLIN=pll_clk0, i_GCLK=ClockSignal("pix2x"), i_LOCKED=pll_locked,
- o_IOCLK=self.cd_pix10x.clk, o_LOCK=locked_async, o_SERDESSTROBE=self.serdesstrobe),
- Instance("BUFG", i_I=pll_clk1, o_O=self.cd_pix2x.clk),
- Instance("BUFG", name="dviout_pix_bufg", i_I=pll_clk2, o_O=self.cd_pix.clk),
- MultiReg(locked_async, mult_locked, "sys")
- ]
-
- # Drive VGA/DVI clock pads
- if pads_vga is not None:
- self.specials += Instance("ODDR2",
- p_DDR_ALIGNMENT="NONE", p_INIT=0, p_SRTYPE="SYNC",
- o_Q=pads_vga.clk,
- i_C0=ClockSignal("pix"),
- i_C1=~ClockSignal("pix"),
- i_CE=1, i_D0=1, i_D1=0,
- i_R=0, i_S=0)
- if pads_dvi is not None:
- dvi_clk_se = Signal()
- self.specials += Instance("ODDR2",
- p_DDR_ALIGNMENT="NONE", p_INIT=0, p_SRTYPE="SYNC",
- o_Q=dvi_clk_se,
- i_C0=ClockSignal("pix"),
- i_C1=~ClockSignal("pix"),
- i_CE=1, i_D0=1, i_D1=0,
- i_R=0, i_S=0)
- self.specials += Instance("OBUFDS", i_I=dvi_clk_se,
- o_O=pads_dvi.clk_p, o_OB=pads_dvi.clk_n)
-
-
-class Driver(Module, AutoCSR):
- def __init__(self, pack_factor, pads_vga, pads_dvi):
- fifo = _FIFO(pack_factor)
- self.submodules += fifo
- self.phy = fifo.phy
- self.busy = fifo.busy
-
- self.submodules.clocking = _Clocking(pads_vga, pads_dvi)
-
- if pads_vga is not None:
- self.comb += [
- pads_vga.hsync_n.eq(~fifo.pix_hsync),
- pads_vga.vsync_n.eq(~fifo.pix_vsync),
- pads_vga.r.eq(fifo.pix_r),
- pads_vga.g.eq(fifo.pix_g),
- pads_vga.b.eq(fifo.pix_b),
- pads_vga.psave_n.eq(1)
- ]
- if pads_dvi is not None:
- self.submodules.dvi_phy = dvi.PHY(self.clocking.serdesstrobe, pads_dvi)
- self.comb += [
- self.dvi_phy.hsync.eq(fifo.pix_hsync),
- self.dvi_phy.vsync.eq(fifo.pix_vsync),
- self.dvi_phy.de.eq(fifo.pix_de),
- self.dvi_phy.r.eq(fifo.pix_r),
- self.dvi_phy.g.eq(fifo.pix_g),
- self.dvi_phy.b.eq(fifo.pix_b)
- ]
+++ /dev/null
-from migen import *
-from migen.genlib.cdc import MultiReg
-
-from misoc.interconnect.csr import *
-
-
-class GPIOIn(Module, AutoCSR):
- def __init__(self, signal):
- self._in = CSRStatus(len(signal))
- self.specials += MultiReg(signal, self._in.status)
-
-
-class GPIOOut(Module, AutoCSR):
- def __init__(self, signal):
- self._out = CSRStorage(len(signal))
- self.comb += signal.eq(self._out.storage)
-
-
-class GPIOInOut(Module):
- def __init__(self, in_signal, out_signal):
- self.submodules.gpio_in = GPIOIn(in_signal)
- self.submodules.gpio_out = GPIOOut(out_signal)
-
- def get_csrs(self):
- return self.gpio_in.get_csrs() + self.gpio_out.get_csrs()
-
-
-class Blinker(Module):
- def __init__(self, signal, divbits=26):
- counter = Signal(divbits)
- self.comb += signal.eq(counter[divbits-1])
- self.sync += counter.eq(counter + 1)
+++ /dev/null
-from migen import *
-
-from misoc.interconnect.csr import *
-
-
-class Identifier(Module, AutoCSR):
- def __init__(self, sysid, frequency, revision=None):
- self._sysid = CSRStatus(16)
- self._frequency = CSRStatus(32)
-
- ###
-
- self.comb += [
- self._sysid.status.eq(sysid),
- self._frequency.status.eq(frequency)
- ]
+++ /dev/null
-from misoc.cores.lasmicon.core import ControllerSettings, LASMIcon
+++ /dev/null
-from migen import *
-from migen.genlib.roundrobin import *
-from migen.genlib.fsm import FSM, NextState
-from migen.genlib.fifo import SyncFIFO
-
-from misoc.cores.lasmicon.multiplexer import *
-
-
-class _AddressSlicer:
- def __init__(self, colbits, address_align):
- self.colbits = colbits
- self.address_align = address_align
-
- def row(self, address):
- split = self.colbits - self.address_align
- if isinstance(address, int):
- return address >> split
- else:
- return address[split:]
-
- def col(self, address):
- split = self.colbits - self.address_align
- if isinstance(address, int):
- return (address & (2**split - 1)) << self.address_align
- else:
- return Cat(Replicate(0, self.address_align), address[:split])
-
-
-class BankMachine(Module):
- def __init__(self, geom_settings, timing_settings, controller_settings, address_align, bankn, req):
- self.refresh_req = Signal()
- self.refresh_gnt = Signal()
- self.cmd = CommandRequestRW(geom_settings.addressbits, geom_settings.bankbits)
-
- ###
-
- # Request FIFO
- layout = [("we", 1), ("adr", len(req.adr))]
- req_in = Record(layout)
- reqf = Record(layout)
- self.submodules.req_fifo = SyncFIFO(layout_len(layout),
- controller_settings.req_queue_size)
- self.comb += [
- self.req_fifo.din.eq(req_in.raw_bits()),
- reqf.raw_bits().eq(self.req_fifo.dout)
- ]
- self.comb += [
- req_in.we.eq(req.we),
- req_in.adr.eq(req.adr),
- self.req_fifo.we.eq(req.stb),
- req.req_ack.eq(self.req_fifo.writable),
-
- self.req_fifo.re.eq(req.dat_w_ack | req.dat_r_ack),
- req.lock.eq(self.req_fifo.readable)
- ]
-
- slicer = _AddressSlicer(geom_settings.colbits, address_align)
-
- # Row tracking
- has_openrow = Signal()
- openrow = Signal(geom_settings.rowbits)
- hit = Signal()
- self.comb += hit.eq(openrow == slicer.row(reqf.adr))
- track_open = Signal()
- track_close = Signal()
- self.sync += [
- If(track_open,
- has_openrow.eq(1),
- openrow.eq(slicer.row(reqf.adr))
- ),
- If(track_close,
- has_openrow.eq(0)
- )
- ]
-
- # Address generation
- s_row_adr = Signal()
- self.comb += [
- self.cmd.ba.eq(bankn),
- If(s_row_adr,
- self.cmd.a.eq(slicer.row(reqf.adr))
- ).Else(
- self.cmd.a.eq(slicer.col(reqf.adr))
- )
- ]
-
- # Respect write-to-precharge specification
- precharge_ok = Signal()
- t_unsafe_precharge = 2 + timing_settings.tWR - 1
- unsafe_precharge_count = Signal(max=t_unsafe_precharge+1)
- self.comb += precharge_ok.eq(unsafe_precharge_count == 0)
- self.sync += [
- If(self.cmd.stb & self.cmd.ack & self.cmd.is_write,
- unsafe_precharge_count.eq(t_unsafe_precharge)
- ).Elif(~precharge_ok,
- unsafe_precharge_count.eq(unsafe_precharge_count-1)
- )
- ]
-
- # Control and command generation FSM
- fsm = FSM()
- self.submodules += fsm
- fsm.act("REGULAR",
- If(self.refresh_req,
- NextState("REFRESH")
- ).Elif(self.req_fifo.readable,
- If(has_openrow,
- If(hit,
- # NB: write-to-read specification is enforced by multiplexer
- self.cmd.stb.eq(1),
- req.dat_w_ack.eq(self.cmd.ack & reqf.we),
- req.dat_r_ack.eq(self.cmd.ack & ~reqf.we),
- self.cmd.is_read.eq(~reqf.we),
- self.cmd.is_write.eq(reqf.we),
- self.cmd.cas_n.eq(0),
- self.cmd.we_n.eq(~reqf.we)
- ).Else(
- NextState("PRECHARGE")
- )
- ).Else(
- NextState("ACTIVATE")
- )
- )
- )
- fsm.act("PRECHARGE",
- # Notes:
- # 1. we are presenting the column address, A10 is always low
- # 2. since we always go to the ACTIVATE state, we do not need
- # to assert track_close.
- If(precharge_ok,
- self.cmd.stb.eq(1),
- If(self.cmd.ack, NextState("TRP")),
- self.cmd.ras_n.eq(0),
- self.cmd.we_n.eq(0),
- self.cmd.is_cmd.eq(1)
- )
- )
- fsm.act("ACTIVATE",
- s_row_adr.eq(1),
- track_open.eq(1),
- self.cmd.stb.eq(1),
- self.cmd.is_cmd.eq(1),
- If(self.cmd.ack, NextState("TRCD")),
- self.cmd.ras_n.eq(0)
- )
- fsm.act("REFRESH",
- self.refresh_gnt.eq(precharge_ok),
- track_close.eq(1),
- self.cmd.is_cmd.eq(1),
- If(~self.refresh_req, NextState("REGULAR"))
- )
- fsm.delayed_enter("TRP", "ACTIVATE", timing_settings.tRP-1)
- fsm.delayed_enter("TRCD", "REGULAR", timing_settings.tRCD-1)
+++ /dev/null
-from migen import *
-
-from misoc.interconnect import dfi, lasmi_bus
-from misoc.cores.lasmicon.refresher import *
-from misoc.cores.lasmicon.bankmachine import *
-from misoc.cores.lasmicon.multiplexer import *
-
-
-class ControllerSettings:
- def __init__(self, req_queue_size=8, read_time=32, write_time=16, with_bandwidth=False):
- self.req_queue_size = req_queue_size
- self.read_time = read_time
- self.write_time = write_time
- self.with_bandwidth = with_bandwidth
-
-
-class LASMIcon(Module):
- def __init__(self, phy_settings, geom_settings, timing_settings,
- controller_settings=None):
- if controller_settings is None:
- controller_settings = ControllerSettings()
- if phy_settings.memtype in ["SDR"]:
- burst_length = phy_settings.nphases*1 # command multiplication*SDR
- elif phy_settings.memtype in ["DDR", "LPDDR", "DDR2", "DDR3"]:
- burst_length = phy_settings.nphases*2 # command multiplication*DDR
- address_align = log2_int(burst_length)
-
- self.dfi = dfi.Interface(geom_settings.addressbits,
- geom_settings.bankbits,
- phy_settings.dfi_databits,
- phy_settings.nphases)
- self.lasmic = lasmi_bus.Interface(
- aw=geom_settings.rowbits + geom_settings.colbits - address_align,
- dw=phy_settings.dfi_databits*phy_settings.nphases,
- nbanks=2**geom_settings.bankbits,
- req_queue_size=controller_settings.req_queue_size,
- read_latency=phy_settings.read_latency+1,
- write_latency=phy_settings.write_latency+1)
- self.nrowbits = geom_settings.colbits - address_align
-
- ###
-
- self.submodules.refresher = Refresher(geom_settings.addressbits, geom_settings.bankbits,
- timing_settings.tRP, timing_settings.tREFI, timing_settings.tRFC)
- self.submodules.bank_machines = [BankMachine(geom_settings, timing_settings, controller_settings, address_align, i,
- getattr(self.lasmic, "bank"+str(i)))
- for i in range(2**geom_settings.bankbits)]
- self.submodules.multiplexer = Multiplexer(phy_settings, geom_settings, timing_settings, controller_settings,
- self.bank_machines, self.refresher,
- self.dfi, self.lasmic)
-
- def get_csrs(self):
- return self.multiplexer.get_csrs()
+++ /dev/null
-from functools import reduce
-from operator import or_, and_
-
-from migen import *
-from migen.genlib.roundrobin import *
-from migen.genlib.fsm import FSM, NextState
-
-from misoc.cores.lasmicon.perf import Bandwidth
-from misoc.interconnect.csr import AutoCSR
-
-
-class CommandRequest:
- def __init__(self, a, ba):
- self.a = Signal(a)
- self.ba = Signal(ba)
- self.cas_n = Signal(reset=1)
- self.ras_n = Signal(reset=1)
- self.we_n = Signal(reset=1)
-
-
-class CommandRequestRW(CommandRequest):
- def __init__(self, a, ba):
- CommandRequest.__init__(self, a, ba)
- self.stb = Signal()
- self.ack = Signal()
- self.is_cmd = Signal()
- self.is_read = Signal()
- self.is_write = Signal()
-
-
-class _CommandChooser(Module):
- def __init__(self, requests):
- self.want_reads = Signal()
- self.want_writes = Signal()
- self.want_cmds = Signal()
- # NB: cas_n/ras_n/we_n are 1 when stb is inactive
- self.cmd = CommandRequestRW(len(requests[0].a), len(requests[0].ba))
-
- ###
-
- rr = RoundRobin(len(requests), SP_CE)
- self.submodules += rr
-
- self.comb += [rr.request[i].eq(req.stb & ((req.is_cmd & self.want_cmds) | ((req.is_read == self.want_reads) | (req.is_write == self.want_writes))))
- for i, req in enumerate(requests)]
-
- stb = Signal()
- self.comb += stb.eq(Array(req.stb for req in requests)[rr.grant])
- for name in ["a", "ba", "is_read", "is_write", "is_cmd"]:
- choices = Array(getattr(req, name) for req in requests)
- self.comb += getattr(self.cmd, name).eq(choices[rr.grant])
- for name in ["cas_n", "ras_n", "we_n"]:
- # we should only assert those signals when stb is 1
- choices = Array(getattr(req, name) for req in requests)
- self.comb += If(self.cmd.stb, getattr(self.cmd, name).eq(choices[rr.grant]))
- self.comb += self.cmd.stb.eq(stb \
- & ((self.cmd.is_cmd & self.want_cmds) | ((self.cmd.is_read == self.want_reads) \
- & (self.cmd.is_write == self.want_writes))))
-
- self.comb += [If(self.cmd.stb & self.cmd.ack & (rr.grant == i), req.ack.eq(1))
- for i, req in enumerate(requests)]
- self.comb += rr.ce.eq(self.cmd.ack)
-
-
-class _Steerer(Module):
- def __init__(self, commands, dfi):
- ncmd = len(commands)
- nph = len(dfi.phases)
- self.sel = [Signal(max=ncmd) for i in range(nph)]
-
- ###
-
- def stb_and(cmd, attr):
- if not hasattr(cmd, "stb"):
- return 0
- else:
- return cmd.stb & getattr(cmd, attr)
- for phase, sel in zip(dfi.phases, self.sel):
- self.comb += [
- phase.cke.eq(1),
- phase.cs_n.eq(0)
- ]
- if hasattr(phase, "odt"):
- self.comb += phase.odt.eq(1)
- if hasattr(phase, "reset_n"):
- self.comb += phase.reset_n.eq(1)
- self.sync += [
- phase.address.eq(Array(cmd.a for cmd in commands)[sel]),
- phase.bank.eq(Array(cmd.ba for cmd in commands)[sel]),
- phase.cas_n.eq(Array(cmd.cas_n for cmd in commands)[sel]),
- phase.ras_n.eq(Array(cmd.ras_n for cmd in commands)[sel]),
- phase.we_n.eq(Array(cmd.we_n for cmd in commands)[sel]),
- phase.rddata_en.eq(Array(stb_and(cmd, "is_read") for cmd in commands)[sel]),
- phase.wrdata_en.eq(Array(stb_and(cmd, "is_write") for cmd in commands)[sel])
- ]
-
-
-class Multiplexer(Module, AutoCSR):
- def __init__(self, phy_settings, geom_settings, timing_settings, controller_settings, bank_machines, refresher, dfi, lasmic,
- with_bandwidth=False):
- assert(phy_settings.nphases == len(dfi.phases))
- self.phy_settings = phy_settings
-
- # Command choosing
- requests = [bm.cmd for bm in bank_machines]
- self.submodules.choose_cmd = choose_cmd = _CommandChooser(requests)
- self.submodules.choose_req = choose_req = _CommandChooser(requests)
- self.comb += [
- choose_cmd.want_reads.eq(0),
- choose_cmd.want_writes.eq(0)
- ]
- if phy_settings.nphases == 1:
- self.comb += [
- choose_cmd.want_cmds.eq(1),
- choose_req.want_cmds.eq(1)
- ]
-
- # Command steering
- nop = CommandRequest(geom_settings.addressbits, geom_settings.bankbits)
- commands = [nop, choose_cmd.cmd, choose_req.cmd, refresher.cmd] # nop must be 1st
- (STEER_NOP, STEER_CMD, STEER_REQ, STEER_REFRESH) = range(4)
- steerer = _Steerer(commands, dfi)
- self.submodules += steerer
-
- # Read/write turnaround
- read_available = Signal()
- write_available = Signal()
- self.comb += [
- read_available.eq(reduce(or_, [req.stb & req.is_read for req in requests])),
- write_available.eq(reduce(or_, [req.stb & req.is_write for req in requests]))
- ]
-
- def anti_starvation(timeout):
- en = Signal()
- max_time = Signal()
- if timeout:
- t = timeout - 1
- time = Signal(max=t+1)
- self.comb += max_time.eq(time == 0)
- self.sync += If(~en,
- time.eq(t)
- ).Elif(~max_time,
- time.eq(time - 1)
- )
- else:
- self.comb += max_time.eq(0)
- return en, max_time
- read_time_en, max_read_time = anti_starvation(controller_settings.read_time)
- write_time_en, max_write_time = anti_starvation(controller_settings.write_time)
-
- # Refresh
- self.comb += [bm.refresh_req.eq(refresher.req) for bm in bank_machines]
- go_to_refresh = Signal()
- self.comb += go_to_refresh.eq(reduce(and_, [bm.refresh_gnt for bm in bank_machines]))
-
- # Datapath
- all_rddata = [p.rddata for p in dfi.phases]
- all_wrdata = [p.wrdata for p in dfi.phases]
- all_wrdata_mask = [p.wrdata_mask for p in dfi.phases]
- self.comb += [
- lasmic.dat_r.eq(Cat(*all_rddata)),
- Cat(*all_wrdata).eq(lasmic.dat_w),
- Cat(*all_wrdata_mask).eq(~lasmic.dat_we)
- ]
-
- # Control FSM
- fsm = FSM()
- self.submodules += fsm
-
- def steerer_sel(steerer, phy_settings, r_w_n):
- r = []
- for i in range(phy_settings.nphases):
- s = steerer.sel[i].eq(STEER_NOP)
- if r_w_n == "read":
- if i == phy_settings.rdphase:
- s = steerer.sel[i].eq(STEER_REQ)
- elif i == phy_settings.rdcmdphase:
- s = steerer.sel[i].eq(STEER_CMD)
- elif r_w_n == "write":
- if i == phy_settings.wrphase:
- s = steerer.sel[i].eq(STEER_REQ)
- elif i == phy_settings.wrcmdphase:
- s = steerer.sel[i].eq(STEER_CMD)
- else:
- raise ValueError
- r.append(s)
- return r
-
- fsm.act("READ",
- read_time_en.eq(1),
- choose_req.want_reads.eq(1),
- choose_cmd.cmd.ack.eq(1),
- choose_req.cmd.ack.eq(1),
- steerer_sel(steerer, phy_settings, "read"),
- If(write_available,
- # TODO: switch only after several cycles of ~read_available?
- If(~read_available | max_read_time, NextState("RTW"))
- ),
- If(go_to_refresh, NextState("REFRESH"))
- )
- fsm.act("WRITE",
- write_time_en.eq(1),
- choose_req.want_writes.eq(1),
- choose_cmd.cmd.ack.eq(1),
- choose_req.cmd.ack.eq(1),
- steerer_sel(steerer, phy_settings, "write"),
- If(read_available,
- If(~write_available | max_write_time, NextState("WTR"))
- ),
- If(go_to_refresh, NextState("REFRESH"))
- )
- fsm.act("REFRESH",
- steerer.sel[0].eq(STEER_REFRESH),
- refresher.ack.eq(1),
- If(~refresher.req, NextState("READ"))
- )
- fsm.delayed_enter("RTW", "WRITE", phy_settings.read_latency-1) # FIXME: reduce this, actual limit is around (cl+1)/nphases
- fsm.delayed_enter("WTR", "READ", timing_settings.tWTR-1)
-
- if controller_settings.with_bandwidth:
- data_width = phy_settings.dfi_databits*phy_settings.nphases
- self.submodules.bandwidth = Bandwidth(self.choose_req.cmd, data_width)
+++ /dev/null
-from migen import *
-
-from misoc.interconnect.csr import *
-
-
-class Bandwidth(Module, AutoCSR):
- def __init__(self, cmd, data_width, period_bits=24):
- self._update = CSR()
- self._nreads = CSRStatus(period_bits)
- self._nwrites = CSRStatus(period_bits)
- self._data_width = CSRStatus(bits_for(data_width), reset=data_width)
-
- ###
-
- cmd_stb = Signal()
- cmd_ack = Signal()
- cmd_is_read = Signal()
- cmd_is_write = Signal()
- self.sync += [
- cmd_stb.eq(cmd.stb),
- cmd_ack.eq(cmd.ack),
- cmd_is_read.eq(cmd.is_read),
- cmd_is_write.eq(cmd.is_write)
- ]
-
- counter = Signal(period_bits)
- period = Signal()
- nreads = Signal(period_bits)
- nwrites = Signal(period_bits)
- nreads_r = Signal(period_bits)
- nwrites_r = Signal(period_bits)
- self.sync += [
- Cat(counter, period).eq(counter + 1),
- If(period,
- nreads_r.eq(nreads),
- nwrites_r.eq(nwrites),
- nreads.eq(0),
- nwrites.eq(0)
- ).Elif(cmd_stb & cmd_ack,
- If(cmd_is_read, nreads.eq(nreads + 1)),
- If(cmd_is_write, nwrites.eq(nwrites + 1)),
- ),
- If(self._update.re,
- self._nreads.status.eq(nreads_r),
- self._nwrites.status.eq(nwrites_r)
- )
- ]
+++ /dev/null
-from migen import *
-from migen.genlib.misc import timeline
-from migen.genlib.fsm import FSM
-
-from misoc.cores.lasmicon.multiplexer import *
-
-
-class Refresher(Module):
- def __init__(self, a, ba, tRP, tREFI, tRFC):
- self.req = Signal()
- self.ack = Signal() # 1st command 1 cycle after assertion of ack
- self.cmd = CommandRequest(a, ba)
-
- ###
-
- # Refresh sequence generator:
- # PRECHARGE ALL --(tRP)--> AUTO REFRESH --(tRFC)--> done
- seq_start = Signal()
- seq_done = Signal()
- self.sync += [
- self.cmd.a.eq(2**10),
- self.cmd.ba.eq(0),
- self.cmd.cas_n.eq(1),
- self.cmd.ras_n.eq(1),
- self.cmd.we_n.eq(1),
- seq_done.eq(0)
- ]
- self.sync += timeline(seq_start, [
- (1, [
- self.cmd.ras_n.eq(0),
- self.cmd.we_n.eq(0)
- ]),
- (1+tRP, [
- self.cmd.cas_n.eq(0),
- self.cmd.ras_n.eq(0)
- ]),
- (1+tRP+tRFC, [
- seq_done.eq(1)
- ])
- ])
-
- # Periodic refresh counter
- counter = Signal(max=tREFI)
- start = Signal()
- self.sync += [
- start.eq(0),
- If(counter == 0,
- start.eq(1),
- counter.eq(tREFI - 1)
- ).Else(
- counter.eq(counter - 1)
- )
- ]
-
- # Control FSM
- fsm = FSM()
- self.submodules += fsm
- fsm.act("IDLE", If(start, NextState("WAIT_GRANT")))
- fsm.act("WAIT_GRANT",
- self.req.eq(1),
- If(self.ack,
- seq_start.eq(1),
- NextState("WAIT_SEQ")
- )
- )
- fsm.act("WAIT_SEQ",
- self.req.eq(1),
- If(seq_done, NextState("IDLE"))
- )
+++ /dev/null
-from migen import *
-from migen.sim.generic import run_simulation
-
-from misoc.mem.sdram.code import lasmibus
-from misoc.mem.sdram.core.lasmicon.bankmachine import *
-
-from test_common import sdram_phy, sdram_geom, sdram_timing, CommandLogger
-
-
-def my_generator():
- for x in range(10):
- yield True, x
- for x in range(10):
- yield False, 128*x
-
-
-class TB(Module):
- def __init__(self):
- self.req = Interface(32, 32, 1,
- sdram_timing.req_queue_size, sdram_phy.read_latency, sdram_phy.write_latency)
- self.submodules.dut = BankMachine(sdram_geom, sdram_timing, 2, 0, self.req)
- self.submodules.logger = CommandLogger(self.dut.cmd, True)
- self.generator = my_generator()
- self.dat_ack_cnt = 0
-
- def do_simulation(self, selfp):
- if selfp.req.dat_ack:
- self.dat_ack_cnt += 1
- if selfp.req.req_ack:
- try:
- we, adr = next(self.generator)
- except StopIteration:
- selfp.req.stb = 0
- if not selfp.req.lock:
- print("data ack count: {0}".format(self.dat_ack_cnt))
- raise StopSimulation
- return
- selfp.req.adr = adr
- selfp.req.we = we
- selfp.req.stb = 1
-
-if __name__ == "__main__":
- run_simulation(TB(), vcd_name="my.vcd")
+++ /dev/null
-from fractions import Fraction
-from math import ceil
-
-from migen import *
-
-from misoc import sdram
-
-MHz = 1000000
-clk_freq = (83 + Fraction(1, 3))*MHz
-
-clk_period_ns = 1000000000/clk_freq
-
-
-def ns(t, margin=True):
- if margin:
- t += clk_period_ns/2
- return ceil(t/clk_period_ns)
-
-sdram_phy = sdram.PhySettings(
- memtype="DDR",
- dfi_databits=64,
- nphases=2,
- rdphase=0,
- wrphase=1,
- rdcmdphase=1,
- wrcmdphase=0,
- cl=3,
- read_latency=5,
- write_latency=0
-)
-
-sdram_geom = sdram.GeomSettings(
- bankbits=2,
- rowbits=13,
- colbits=10
-)
-sdram_timing = sdram.TimingSettings(
- tRP=ns(15),
- tRCD=ns(15),
- tWR=ns(15),
- tWTR=2,
- tREFI=ns(7800, False),
- tRFC=ns(70),
-
- req_queue_size=8,
- read_time=32,
- write_time=16
-)
-
-
-def decode_sdram(ras_n, cas_n, we_n, bank, address):
- elts = []
- if not ras_n and cas_n and we_n:
- elts.append("ACTIVATE")
- elts.append("BANK " + str(bank))
- elts.append("ROW " + str(address))
- elif ras_n and not cas_n and we_n:
- elts.append("READ\t")
- elts.append("BANK " + str(bank))
- elts.append("COL " + str(address))
- elif ras_n and not cas_n and not we_n:
- elts.append("WRITE\t")
- elts.append("BANK " + str(bank))
- elts.append("COL " + str(address))
- elif ras_n and cas_n and not we_n:
- elts.append("BST")
- elif not ras_n and not cas_n and we_n:
- elts.append("AUTO REFRESH")
- elif not ras_n and cas_n and not we_n:
- elts.append("PRECHARGE")
- if address & 2**10:
- elts.append("ALL")
- else:
- elts.append("BANK " + str(bank))
- elif not ras_n and not cas_n and not we_n:
- elts.append("LMR")
- return elts
-
-
-class CommandLogger(Module):
- def __init__(self, cmd, rw=False):
- self.cmd = cmd
- if rw:
- self.comb += self.cmd.ack.eq(1)
-
- def do_simulation(self, selfp):
- elts = ["@" + str(selfp.simulator.cycle_counter)]
- cmdp = selfp.cmd
- elts += decode_sdram(cmdp.ras_n, cmdp.cas_n, cmdp.we_n, cmdp.ba, cmdp.a)
- if len(elts) > 1:
- print("\t".join(elts))
- do_simulation.passive = True
-
-
-class DFILogger(Module):
- def __init__(self, dfi):
- self.dfi = dfi
-
- def do_simulation(self, selfp):
- dfip = selfp.dfi
- for i, p in enumerate(dfip.phases):
- elts = ["@" + str(selfp.simulator.cycle_counter) + ":" + str(i)]
- elts += decode_sdram(p.ras_n, p.cas_n, p.we_n, p.bank, p.address)
- if len(elts) > 1:
- print("\t".join(elts))
- do_simulation.passive = True
+++ /dev/null
-from migen import *
-from migen.sim.generic import run_simulation
-
-from misoc.mem.sdram.core import lasmibus
-from misoc.mem.sdram.core.lasmicon import *
-from misoc.mem.sdram.frontend import dma_lasmi
-
-from test_common import sdram_phy, sdram_geom, sdram_timing, DFILogger
-
-
-class TB(Module):
- def __init__(self):
- self.submodules.ctler = LASMIcon(sdram_phy, sdram_geom, sdram_timing)
- self.submodules.xbar = lasmibus.Crossbar([self.ctler.lasmic], self.ctler.nrowbits)
- self.submodules.logger = DFILogger(self.ctler.dfi)
- self.submodules.writer = dma_lasmi.Writer(self.xbar.get_master())
-
- self.comb += self.writer.address_data.stb.eq(1)
- pl = self.writer.address_data.payload
- pl.a.reset = 255
- pl.d.reset = pl.a.reset*2
- self.sync += If(self.writer.address_data.ack,
- pl.a.eq(pl.a + 1),
- pl.d.eq(pl.d + 2)
- )
- self.open_row = None
-
- def do_simulation(self, selfp):
- dfip = selfp.ctler.dfi
- for p in dfip.phases:
- if p.ras_n and not p.cas_n and not p.we_n: # write
- d = dfip.phases[0].wrdata | (dfip.phases[1].wrdata << 64)
- print(d)
- if d != p.address//2 + p.bank*512 + self.open_row*2048:
- print("**** ERROR ****")
- elif not p.ras_n and p.cas_n and p.we_n: # activate
- self.open_row = p.address
-
-if __name__ == "__main__":
- run_simulation(TB(), ncycles=3500, vcd_name="my.vcd")
+++ /dev/null
-from migen import *
-from migen.sim.generic import run_simulation
-
-from misoc.mem.sdram.core import lasmibus
-from misoc.mem.sdram.core.lasmicon import *
-
-from test_common import sdram_phy, sdram_geom, sdram_timing, DFILogger
-
-
-def my_generator_r(n):
- for x in range(10):
- t = TRead(128*n + 48*n*x)
- yield t
- print("{0:3}: reads done".format(n))
-
-
-def my_generator_w(n):
- for x in range(10):
- t = TWrite(128*n + 48*n*x, x)
- yield t
- print("{0:3}: writes done".format(n))
-
-
-def my_generator(n):
- if n % 2:
- return my_generator_w(n // 2)
- else:
- return my_generator_r(n // 2)
-
-
-class TB(Module):
- def __init__(self):
- self.submodules.dut = LASMIcon(sdram_phy, sdram_geom, sdram_timing)
- self.submodules.xbar = lasmibus.Crossbar([self.dut.lasmic], self.dut.nrowbits)
- self.submodules.logger = DFILogger(self.dut.dfi)
-
- masters = [self.xbar.get_master() for i in range(6)]
- self.initiators = [Initiator(my_generator(n), master)
- for n, master in enumerate(masters)]
- self.submodules += self.initiators
-
-if __name__ == "__main__":
- run_simulation(TB(), vcd_name="my.vcd")
+++ /dev/null
-from random import Random
-
-from migen import *
-from migen.sim.generic import run_simulation
-
-from misoc.mem.sdram.core.lasmicon.refresher import *
-
-from common import CommandLogger
-
-
-class Granter(Module):
- def __init__(self, req, ack):
- self.req = req
- self.ack = ack
- self.state = 0
- self.prng = Random(92837)
-
- def do_simulation(self, selfp):
- elts = ["@" + str(selfp.simulator.cycle_counter)]
-
- if self.state == 0:
- if selfp.req:
- elts.append("Refresher requested access")
- self.state = 1
- elif self.state == 1:
- if self.prng.randrange(0, 5) == 0:
- elts.append("Granted access to refresher")
- selfp.ack = 1
- self.state = 2
- elif self.state == 2:
- if not selfp.req:
- elts.append("Refresher released access")
- selfp.ack = 0
- self.state = 0
-
- if len(elts) > 1:
- print("\t".join(elts))
-
-
-class TB(Module):
- def __init__(self):
- self.submodules.dut = Refresher(13, 2, tRP=3, tREFI=100, tRFC=5)
- self.submodules.logger = CommandLogger(self.dut.cmd)
- self.submodules.granter = Granter(self.dut.req, self.dut.ack)
-
-if __name__ == "__main__":
- run_simulation(TB(), ncycles=400)
+++ /dev/null
-from migen import *
-from migen.bus import wishbone
-from migen.bus.transactions import *
-from migen.sim.generic import run_simulation
-
-from misoc.mem.sdram.core import lasmibus
-from misoc.mem.sdram.core.lasmicon import *
-from misoc.mem.sdram.frontend import wishbone2lasmi
-
-from test_common import sdram_phy, sdram_geom, sdram_timing, DFILogger
-
-l2_size = 8192 # in bytes
-
-
-def my_generator():
- for x in range(20):
- t = TWrite(x, x)
- yield t
- print(str(t) + " delay=" + str(t.latency))
- for x in range(20):
- t = TRead(x)
- yield t
- print(str(t) + " delay=" + str(t.latency))
- for x in range(20):
- t = TRead(x+l2_size//4)
- yield t
- print(str(t) + " delay=" + str(t.latency))
-
-
-class TB(Module):
- def __init__(self):
- self.submodules.ctler = LASMIcon(sdram_phy, sdram_geom, sdram_timing)
- self.submodules.xbar = lasmibus.Crossbar([self.ctler.lasmic], self.ctler.nrowbits)
- self.submodules.logger = DFILogger(self.ctler.dfi)
- self.submodules.bridge = wishbone2lasmi.WB2LASMI(l2_size//4, self.xbar.get_master())
- self.submodules.initiator = wishbone.Initiator(my_generator())
- self.submodules.conn = wishbone.InterconnectPointToPoint(self.initiator.bus, self.bridge.wishbone)
-
-if __name__ == "__main__":
- run_simulation(TB(), vcd_name="my.vcd")
+++ /dev/null
-Unless otherwise noted, LiteEth is copyright (C) 2015 Florent Kermarrec.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-1. Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-2. Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-Other authors retain ownership of their contributions. If a submission can
-reasonably be considered independently copyrightable, it's yours and we
-encourage you to claim it with appropriate copyright notices. This submission
-then falls under the "otherwise noted" category. All submissions are strongly
-encouraged to use the two-clause BSD license reproduced above.
+++ /dev/null
- __ _ __ ______ __ __ ____ _
- / / (_) /____ / __/ /_/ / / |/ (_)__ (_)
- / /__/ / __/ -_) _// __/ _ \/ /|_/ / / _ \/ /
- /____/_/\__/\__/___/\__/_//_/_/ /_/_/_//_/_/
-
- Copyright 2012-2015 / EnjoyDigital / M-Labs Ltd
-
- A small footprint and configurable minimal Ethernet core
- powered by Migen
-
-[> Intro
----------
-LiteEthMini is a subset of LiteEth (https://github.com/enjoy-digital/liteeth)
-intended to be used with a CPU and a software stack.
-
-[> Features
------------
-- Ethernet MAC with various various PHYs (GMII, MII, RGMII, Loopback)
-- SRAM storage and wishbone interface
-
-[> Possible improvements
--------------------------
-- add DMA interface to MAC
-- add SGMII PHY
-- ... See below Support and consulting :)
-
-If you want to support these features, please contact us at florent [AT]
-enjoy-digital.fr. You can also contact our partner on the public mailing list
-devel [AT] lists.m-labs.hk.
-
-[> License
------------
-LiteEthMini is released under the very permissive two-clause BSD license. Under
-the terms of this license, you are authorized to use LiteEthMini for closed-source
-proprietary designs.
-Even though we do not require you to do so, those things are awesome, so please
-do them if possible:
- - tell us that you are using LiteEthMini
- - cite LiteEthMini in publications related to research it has helped
- - send us feedback and suggestions for improvements
- - send us bug reports when something goes wrong
- - send us the modifications and improvements you have done to LiteEthMini.
-
-[> Support and consulting
---------------------------
-We love open-source hardware and like sharing our designs with others.
-
-LiteEthMini is mainly developed and maintained by EnjoyDigital.
-
-If you would like to know more about LiteEthMini or if you are already a happy
-user and would like to extend it for your needs, EnjoyDigital can provide standard
-commercial support as well as consulting services.
-
-So feel free to contact us, we'd love to work with you! (and eventually shorten
-the list of the possible improvements :)
-
-[> Contact
-E-mail: florent [AT] enjoy-digital.fr
\ No newline at end of file
+++ /dev/null
-from migen import *
-from migen.genlib.record import *
-
-from misoc.interconnect.csr import *
-from misoc.interconnect.stream import *
-
-
-class Port:
- def connect(self, port):
- r = [
- Record.connect(self.source, port.sink),
- Record.connect(port.source, self.sink)
- ]
- return r
-
-eth_mtu = 1532
-eth_min_len = 46
-eth_interpacket_gap = 12
-eth_preamble = 0xD555555555555555
-buffer_depth = 2**log2_int(eth_mtu, need_pow2=False)
-
-
-def eth_phy_description(dw):
- payload_layout = [
- ("data", dw),
- ("last_be", dw//8),
- ("error", dw//8)
- ]
- return EndpointDescription(payload_layout, packetized=True)
-
-
-def eth_mac_description(dw):
- payload_layout = mac_header.get_layout() + [
- ("data", dw),
- ("last_be", dw//8),
- ("error", dw//8)
- ]
- return EndpointDescription(payload_layout, packetized=True)
+++ /dev/null
-from migen import *
-
-from misoc.interconnect.csr import *
-from misoc.cores.liteeth_mini.common import *
-from misoc.cores.liteeth_mini.mac.core import LiteEthMACCore
-from misoc.cores.liteeth_mini.mac.frontend.wishbone import LiteEthMACWishboneInterface
-
-
-class LiteEthMAC(Module, AutoCSR):
- def __init__(self, phy, dw,
- interface="wishbone",
- endianness="big",
- with_preamble_crc=True):
- self.submodules.core = LiteEthMACCore(phy, dw, endianness, with_preamble_crc)
- self.csrs = []
- if interface == "wishbone":
- self.submodules.interface = LiteEthMACWishboneInterface(dw, 2, 2)
- self.comb += Port.connect(self.interface, self.core)
- self.ev, self.bus = self.interface.sram.ev, self.interface.bus
- self.csrs = self.interface.get_csrs() + self.core.get_csrs()
- else:
- raise NotImplementedError
-
- def get_csrs(self):
- return self.csrs
+++ /dev/null
-from migen import *
-
-from misoc.interconnect.csr import *
-from misoc.cores.liteeth_mini.common import *
-from misoc.cores.liteeth_mini.mac.core import gap, preamble, crc, padding, last_be
-from misoc.cores.liteeth_mini.phy.mii import LiteEthPHYMII
-
-
-class LiteEthMACCore(Module, AutoCSR):
- def __init__(self, phy, dw, endianness="big",
- with_preamble_crc=True,
- with_padding=True):
- if dw < phy.dw:
- raise ValueError("Core data width({}) must be larger than PHY data width({})".format(dw, phy.dw))
-
- rx_pipeline = [phy]
- tx_pipeline = [phy]
-
- # Interpacket gap
- tx_gap_inserter = gap.LiteEthMACGap(phy.dw)
- rx_gap_checker = gap.LiteEthMACGap(phy.dw, ack_on_gap=True)
- self.submodules += ClockDomainsRenamer("eth_tx")(tx_gap_inserter)
- self.submodules += ClockDomainsRenamer("eth_rx")(rx_gap_checker)
-
- tx_pipeline += [tx_gap_inserter]
- rx_pipeline += [rx_gap_checker]
-
- # Preamble / CRC
- if with_preamble_crc:
- self._preamble_crc = CSRStatus(reset=1)
- # Preamble insert/check
- preamble_inserter = preamble.LiteEthMACPreambleInserter(phy.dw)
- preamble_checker = preamble.LiteEthMACPreambleChecker(phy.dw)
- self.submodules += ClockDomainsRenamer("eth_tx")(preamble_inserter)
- self.submodules += ClockDomainsRenamer("eth_rx")(preamble_checker)
-
- # CRC insert/check
- crc32_inserter = crc.LiteEthMACCRC32Inserter(eth_phy_description(phy.dw))
- crc32_checker = crc.LiteEthMACCRC32Checker(eth_phy_description(phy.dw))
- self.submodules += ClockDomainsRenamer("eth_tx")(crc32_inserter)
- self.submodules += ClockDomainsRenamer("eth_rx")(crc32_checker)
-
- tx_pipeline += [preamble_inserter, crc32_inserter]
- rx_pipeline += [preamble_checker, crc32_checker]
-
- # Padding
- if with_padding:
- padding_inserter = padding.LiteEthMACPaddingInserter(phy.dw, 60)
- padding_checker = padding.LiteEthMACPaddingChecker(phy.dw, 60)
- self.submodules += ClockDomainsRenamer("eth_tx")(padding_inserter)
- self.submodules += ClockDomainsRenamer("eth_rx")(padding_checker)
-
- tx_pipeline += [padding_inserter]
- rx_pipeline += [padding_checker]
-
- # Delimiters
- if dw != 8:
- tx_last_be = last_be.LiteEthMACTXLastBE(phy.dw)
- rx_last_be = last_be.LiteEthMACRXLastBE(phy.dw)
- self.submodules += ClockDomainsRenamer("eth_tx")(tx_last_be)
- self.submodules += ClockDomainsRenamer("eth_rx")(rx_last_be)
-
- tx_pipeline += [tx_last_be]
- rx_pipeline += [rx_last_be]
-
- # Converters
- if dw != phy.dw:
- reverse = endianness == "big"
- tx_converter = Converter(eth_phy_description(dw),
- eth_phy_description(phy.dw),
- reverse=reverse)
- rx_converter = Converter(eth_phy_description(phy.dw),
- eth_phy_description(dw),
- reverse=reverse)
- self.submodules += ClockDomainsRenamer("eth_tx")(tx_converter)
- self.submodules += ClockDomainsRenamer("eth_rx")(rx_converter)
-
- tx_pipeline += [tx_converter]
- rx_pipeline += [rx_converter]
-
- # Cross Domain Crossing
- if isinstance(phy, LiteEthPHYMII):
- fifo_depth = 8
- else:
- fifo_depth = 64
- tx_cdc = AsyncFIFO(eth_phy_description(dw), fifo_depth)
- rx_cdc = AsyncFIFO(eth_phy_description(dw), fifo_depth)
- self.submodules += ClockDomainsRenamer({"write": "sys", "read": "eth_tx"})(tx_cdc)
- self.submodules += ClockDomainsRenamer({"write": "eth_rx", "read": "sys"})(rx_cdc)
-
- tx_pipeline += [tx_cdc]
- rx_pipeline += [rx_cdc]
-
- tx_pipeline_r = list(reversed(tx_pipeline))
- for s, d in zip(tx_pipeline_r, tx_pipeline_r[1:]):
- self.comb += s.source.connect(d.sink)
- for s, d in zip(rx_pipeline, rx_pipeline[1:]):
- self.comb += s.source.connect(d.sink)
- self.sink = tx_pipeline[-1].sink
- self.source = rx_pipeline[-1].source
+++ /dev/null
-from collections import OrderedDict
-from functools import reduce
-from operator import xor
-
-from migen import *
-from migen.genlib.misc import chooser
-
-from misoc.interconnect.stream import *
-
-
-class LiteEthMACCRCEngine(Module):
- """Cyclic Redundancy Check Engine
-
- Compute next CRC value from last CRC value and data input using
- an optimized asynchronous LFSR.
-
- Parameters
- ----------
- data_width : int
- Width of the data bus.
- width : int
- Width of the CRC.
- polynom : int
- Polynom of the CRC (ex: 0x04C11DB7 for IEEE 802.3 CRC)
-
- Attributes
- ----------
- data : in
- Data input.
- last : in
- last CRC value.
- next :
- next CRC value.
- """
- def __init__(self, data_width, width, polynom):
- self.data = Signal(data_width)
- self.last = Signal(width)
- self.next = Signal(width)
-
- # # #
-
- def _optimize_eq(l):
- """
- Replace even numbers of XORs in the equation
- with an equivalent XOR
- """
- d = OrderedDict()
- for e in l:
- if e in d:
- d[e] += 1
- else:
- d[e] = 1
- r = []
- for key, value in d.items():
- if value%2 != 0:
- r.append(key)
- return r
-
- # compute and optimize CRC's LFSR
- curval = [[("state", i)] for i in range(width)]
- for i in range(data_width):
- feedback = curval.pop() + [("din", i)]
- for j in range(width-1):
- if (polynom & (1<<(j+1))):
- curval[j] += feedback
- curval[j] = _optimize_eq(curval[j])
- curval.insert(0, feedback)
-
- # implement logic
- for i in range(width):
- xors = []
- for t, n in curval[i]:
- if t == "state":
- xors += [self.last[n]]
- elif t == "din":
- xors += [self.data[n]]
- self.comb += self.next[i].eq(reduce(xor, xors))
-
-
-@ResetInserter()
-@CEInserter()
-class LiteEthMACCRC32(Module):
- """IEEE 802.3 CRC
-
- Implement an IEEE 802.3 CRC generator/checker.
-
- Parameters
- ----------
- data_width : int
- Width of the data bus.
-
- Attributes
- ----------
- d : in
- Data input.
- value : out
- CRC value (used for generator).
- error : out
- CRC error (used for checker).
- """
- width = 32
- polynom = 0x04C11DB7
- init = 2**width-1
- check = 0xC704DD7B
- def __init__(self, data_width):
- self.data = Signal(data_width)
- self.value = Signal(self.width)
- self.error = Signal()
-
- # # #
-
- self.submodules.engine = LiteEthMACCRCEngine(data_width, self.width, self.polynom)
- reg = Signal(self.width, reset=self.init)
- self.sync += reg.eq(self.engine.next)
- self.comb += [
- self.engine.data.eq(self.data),
- self.engine.last.eq(reg),
-
- self.value.eq(~reg[::-1]),
- self.error.eq(self.engine.next != self.check)
- ]
-
-
-class LiteEthMACCRCInserter(Module):
- """CRC Inserter
-
- Append a CRC at the end of each packet.
-
- Parameters
- ----------
- description : description
- description of the dataflow.
-
- Attributes
- ----------
- sink : in
- Packets input without CRC.
- source : out
- Packets output with CRC.
- """
- def __init__(self, crc_class, description):
- self.sink = sink = Sink(description)
- self.source = source = Source(description)
- self.busy = Signal()
-
- # # #
-
- dw = len(sink.data)
- crc = crc_class(dw)
- fsm = FSM(reset_state="IDLE")
- self.submodules += crc, fsm
-
- fsm.act("IDLE",
- crc.reset.eq(1),
- sink.ack.eq(1),
- If(sink.stb & sink.sop,
- sink.ack.eq(0),
- NextState("COPY"),
- )
- )
- fsm.act("COPY",
- crc.ce.eq(sink.stb & source.ack),
- crc.data.eq(sink.data),
- Record.connect(sink, source),
- source.eop.eq(0),
- If(sink.stb & sink.eop & source.ack,
- NextState("INSERT"),
- )
- )
- ratio = crc.width//dw
- if ratio > 1:
- cnt = Signal(max=ratio, reset=ratio-1)
- cnt_done = Signal()
- fsm.act("INSERT",
- source.stb.eq(1),
- chooser(crc.value, cnt, source.data, reverse=True),
- If(cnt_done,
- source.eop.eq(1),
- If(source.ack, NextState("IDLE"))
- )
- )
- self.comb += cnt_done.eq(cnt == 0)
- self.sync += \
- If(fsm.ongoing("IDLE"),
- cnt.eq(cnt.reset)
- ).Elif(fsm.ongoing("INSERT") & ~cnt_done,
- cnt.eq(cnt - source.ack)
- )
- else:
- fsm.act("INSERT",
- source.stb.eq(1),
- source.eop.eq(1),
- source.data.eq(crc.value),
- If(source.ack, NextState("IDLE"))
- )
- self.comb += self.busy.eq(~fsm.ongoing("IDLE"))
-
-
-class LiteEthMACCRC32Inserter(LiteEthMACCRCInserter):
- def __init__(self, description):
- LiteEthMACCRCInserter.__init__(self, LiteEthMACCRC32, description)
-
-
-class LiteEthMACCRCChecker(Module):
- """CRC Checker
-
- Check CRC at the end of each packet.
-
- Parameters
- ----------
- description : description
- description of the dataflow.
-
- Attributes
- ----------
- sink : in
- Packets input with CRC.
- source : out
- Packets output without CRC and "error" set to 0
- on eop when CRC OK / set to 1 when CRC KO.
- """
- def __init__(self, crc_class, description):
- self.sink = sink = Sink(description)
- self.source = source = Source(description)
- self.busy = Signal()
-
- # # #
-
- dw = len(sink.data)
- crc = crc_class(dw)
- self.submodules += crc
- ratio = crc.width//dw
-
- fifo = ResetInserter()(SyncFIFO(description, ratio + 1))
- self.submodules += fifo
-
- fsm = FSM(reset_state="RESET")
- self.submodules += fsm
-
- fifo_in = Signal()
- fifo_out = Signal()
- fifo_full = Signal()
-
- self.comb += [
- fifo_full.eq(fifo.fifo.level == ratio),
- fifo_in.eq(sink.stb & (~fifo_full | fifo_out)),
- fifo_out.eq(source.stb & source.ack),
-
- Record.connect(sink, fifo.sink),
- fifo.sink.stb.eq(fifo_in),
- self.sink.ack.eq(fifo_in),
-
- source.stb.eq(sink.stb & fifo_full),
- source.sop.eq(fifo.source.sop),
- source.eop.eq(sink.eop),
- fifo.source.ack.eq(fifo_out),
- source.payload.eq(fifo.source.payload),
-
- source.error.eq(sink.error | crc.error),
- ]
-
- fsm.act("RESET",
- crc.reset.eq(1),
- fifo.reset.eq(1),
- NextState("IDLE"),
- )
- self.comb += crc.data.eq(sink.data)
- fsm.act("IDLE",
- If(sink.stb & sink.sop & sink.ack,
- crc.ce.eq(1),
- NextState("COPY")
- )
- )
- fsm.act("COPY",
- If(sink.stb & sink.ack,
- crc.ce.eq(1),
- If(sink.eop,
- NextState("RESET")
- )
- )
- )
- self.comb += self.busy.eq(~fsm.ongoing("IDLE"))
-
-
-class LiteEthMACCRC32Checker(LiteEthMACCRCChecker):
- def __init__(self, description):
- LiteEthMACCRCChecker.__init__(self, LiteEthMACCRC32, description)
+++ /dev/null
-import math
-
-from migen import *
-from migen.genlib.fsm import *
-
-from misoc.interconnect.stream import Sink, Source
-from misoc.cores.liteeth_mini.common import eth_phy_description, eth_interpacket_gap
-
-
-class LiteEthMACGap(Module):
- def __init__(self, dw, ack_on_gap=False):
- self.sink = sink = Sink(eth_phy_description(dw))
- self.source = source = Source(eth_phy_description(dw))
-
- # # #
-
- gap = math.ceil(eth_interpacket_gap/(dw//8))
- counter = Signal(max=gap)
- counter_reset = Signal()
- counter_ce = Signal()
- self.sync += \
- If(counter_reset,
- counter.eq(0)
- ).Elif(counter_ce,
- counter.eq(counter + 1)
- )
-
- self.submodules.fsm = fsm = FSM(reset_state="COPY")
- fsm.act("COPY",
- counter_reset.eq(1),
- Record.connect(sink, source),
- If(sink.stb & sink.eop & sink.ack,
- NextState("GAP")
- )
- )
- fsm.act("GAP",
- counter_ce.eq(1),
- sink.ack.eq(int(ack_on_gap)),
- If(counter == (gap-1),
- NextState("COPY")
- )
- )
+++ /dev/null
-from migen import *
-
-from misoc.interconnect.stream import *
-from misoc.cores.liteeth_mini.common import eth_phy_description
-
-
-class LiteEthMACTXLastBE(Module):
- def __init__(self, dw):
- self.sink = sink = Sink(eth_phy_description(dw))
- self.source = source = Source(eth_phy_description(dw))
-
- # # #
-
- ongoing = Signal()
- self.sync += \
- If(sink.stb & sink.ack,
- If(sink.sop,
- ongoing.eq(1)
- ).Elif(sink.last_be,
- ongoing.eq(0)
- )
- )
- self.comb += [
- source.stb.eq(sink.stb & (sink.sop | ongoing)),
- source.sop.eq(sink.sop),
- source.eop.eq(sink.last_be),
- source.data.eq(sink.data),
- sink.ack.eq(source.ack)
- ]
-
-
-class LiteEthMACRXLastBE(Module):
- def __init__(self, dw):
- self.sink = sink = Sink(eth_phy_description(dw))
- self.source = source = Source(eth_phy_description(dw))
-
- # # #
-
- self.comb += [
- source.stb.eq(sink.stb),
- source.sop.eq(sink.sop),
- source.eop.eq(sink.eop),
- source.data.eq(sink.data),
- source.last_be.eq(sink.eop),
- sink.ack.eq(source.ack)
- ]
+++ /dev/null
-import math
-
-from migen import *
-
-from misoc.interconnect.stream import *
-from misoc.cores.liteeth_mini.common import eth_phy_description
-
-
-class LiteEthMACPaddingInserter(Module):
- def __init__(self, dw, padding):
- self.sink = sink = Sink(eth_phy_description(dw))
- self.source = source = Source(eth_phy_description(dw))
-
- # # #
-
- padding_limit = math.ceil(padding/(dw/8))-1
-
- counter = Signal(16, reset=1)
- counter_done = Signal()
- counter_reset = Signal()
- counter_ce = Signal()
- self.sync += If(counter_reset,
- counter.eq(1)
- ).Elif(counter_ce,
- counter.eq(counter + 1)
- )
- self.comb += [
- counter_reset.eq(sink.stb & sink.sop & sink.ack),
- counter_ce.eq(source.stb & source.ack),
- counter_done.eq(counter >= padding_limit),
- ]
-
- self.submodules.fsm = fsm = FSM(reset_state="IDLE")
- fsm.act("IDLE",
- Record.connect(sink, source),
- If(source.stb & source.ack,
- counter_ce.eq(1),
- If(sink.eop,
- If(~counter_done,
- source.eop.eq(0),
- NextState("PADDING")
- )
- )
- )
- )
- fsm.act("PADDING",
- source.stb.eq(1),
- source.eop.eq(counter_done),
- source.data.eq(0),
- If(source.ack,
- If(counter_done,
- NextState("IDLE")
- )
- )
- )
-
-
-class LiteEthMACPaddingChecker(Module):
- def __init__(self, dw, packet_min_length):
- self.sink = sink = Sink(eth_phy_description(dw))
- self.source = source = Source(eth_phy_description(dw))
-
- # # #
-
- # TODO: see if we should drop the packet when
- # payload size < minimum ethernet payload size
- self.comb += Record.connect(sink, source)
-
+++ /dev/null
-from migen import *
-from migen.genlib.fsm import *
-from migen.genlib.misc import chooser
-from migen.genlib.record import Record
-
-from misoc.interconnect.stream import *
-from misoc.cores.liteeth_mini.common import eth_phy_description, eth_preamble
-
-
-class LiteEthMACPreambleInserter(Module):
- def __init__(self, dw):
- self.sink = Sink(eth_phy_description(dw))
- self.source = Source(eth_phy_description(dw))
-
- # # #
-
- preamble = Signal(64, reset=eth_preamble)
- cnt_max = (64//dw)-1
- cnt = Signal(max=cnt_max+1)
- clr_cnt = Signal()
- inc_cnt = Signal()
-
- self.sync += \
- If(clr_cnt,
- cnt.eq(0)
- ).Elif(inc_cnt,
- cnt.eq(cnt+1)
- )
-
- fsm = FSM(reset_state="IDLE")
- self.submodules += fsm
- fsm.act("IDLE",
- self.sink.ack.eq(1),
- clr_cnt.eq(1),
- If(self.sink.stb & self.sink.sop,
- self.sink.ack.eq(0),
- NextState("INSERT"),
- )
- )
- fsm.act("INSERT",
- self.source.stb.eq(1),
- self.source.sop.eq(cnt == 0),
- chooser(preamble, cnt, self.source.data),
- If(cnt == cnt_max,
- If(self.source.ack, NextState("COPY"))
- ).Else(
- inc_cnt.eq(self.source.ack)
- )
- )
-
- self.comb += [
- self.source.data.eq(self.sink.data),
- self.source.last_be.eq(self.sink.last_be)
- ]
- fsm.act("COPY",
- Record.connect(self.sink, self.source, leave_out=set(["data", "last_be"])),
- self.source.sop.eq(0),
-
- If(self.sink.stb & self.sink.eop & self.source.ack,
- NextState("IDLE"),
- )
- )
-
-
-class LiteEthMACPreambleChecker(Module):
- def __init__(self, dw):
- self.sink = Sink(eth_phy_description(dw))
- self.source = Source(eth_phy_description(dw))
-
- # # #
-
- preamble = Signal(64, reset=eth_preamble)
- cnt_max = (64//dw) - 1
- cnt = Signal(max=cnt_max+1)
- clr_cnt = Signal()
- inc_cnt = Signal()
-
- self.sync += \
- If(clr_cnt,
- cnt.eq(0)
- ).Elif(inc_cnt,
- cnt.eq(cnt+1)
- )
-
- discard = Signal()
- clr_discard = Signal()
- set_discard = Signal()
-
- self.sync += \
- If(clr_discard,
- discard.eq(0)
- ).Elif(set_discard,
- discard.eq(1)
- )
-
- sop = Signal()
- clr_sop = Signal()
- set_sop = Signal()
- self.sync += \
- If(clr_sop,
- sop.eq(0)
- ).Elif(set_sop,
- sop.eq(1)
- )
-
- ref = Signal(dw)
- match = Signal()
- self.comb += [
- chooser(preamble, cnt, ref),
- match.eq(self.sink.data == ref)
- ]
-
- fsm = FSM(reset_state="IDLE")
- self.submodules += fsm
-
- fsm.act("IDLE",
- self.sink.ack.eq(1),
- clr_cnt.eq(1),
- clr_discard.eq(1),
- If(self.sink.stb & self.sink.sop,
- clr_cnt.eq(0),
- inc_cnt.eq(1),
- clr_discard.eq(0),
- set_discard.eq(~match),
- NextState("CHECK"),
- )
- )
- fsm.act("CHECK",
- self.sink.ack.eq(1),
- If(self.sink.stb,
- set_discard.eq(~match),
- If(cnt == cnt_max,
- If(discard | (~match),
- NextState("IDLE")
- ).Else(
- set_sop.eq(1),
- NextState("COPY")
- )
- ).Else(
- inc_cnt.eq(1)
- )
- )
- )
- self.comb += [
- self.source.data.eq(self.sink.data),
- self.source.last_be.eq(self.sink.last_be)
- ]
- fsm.act("COPY",
- Record.connect(self.sink, self.source, leave_out=set(["data", "last_be"])),
- self.source.sop.eq(sop),
- clr_sop.eq(self.source.stb & self.source.ack),
-
- If(self.source.stb & self.source.eop & self.source.ack,
- NextState("IDLE"),
- )
- )
+++ /dev/null
-from misoc import *
-
-from misoc.interconnect.csr import *
-from misoc.interconnect.csr_eventmanager import *
-from misoc.interconnect.stream import *
-
-from misoc.cores.liteeth_mini.common import eth_phy_description
-
-
-class LiteEthMACSRAMWriter(Module, AutoCSR):
- def __init__(self, dw, depth, nslots=2):
- self.sink = sink = Sink(eth_phy_description(dw))
- self.crc_error = Signal()
-
- slotbits = max(log2_int(nslots), 1)
- lengthbits = log2_int(depth*4) # length in bytes
-
- self._slot = CSRStatus(slotbits)
- self._length = CSRStatus(lengthbits)
-
- self.submodules.ev = EventManager()
- self.ev.available = EventSourceLevel()
- self.ev.finalize()
-
- # # #
-
- # packet dropped if no slot available
- sink.ack.reset = 1
-
- # length computation
- increment = Signal(3)
- self.comb += \
- If(sink.last_be[3],
- increment.eq(1)
- ).Elif(sink.last_be[2],
- increment.eq(2)
- ).Elif(sink.last_be[1],
- increment.eq(3)
- ).Else(
- increment.eq(4)
- )
- counter = Signal(lengthbits)
- counter_reset = Signal()
- counter_ce = Signal()
- self.sync += If(counter_reset,
- counter.eq(0)
- ).Elif(counter_ce,
- counter.eq(counter + increment)
- )
-
- # slot computation
- slot = Signal(slotbits)
- slot_ce = Signal()
- self.sync += If(slot_ce, slot.eq(slot + 1))
-
- ongoing = Signal()
-
- # status fifo
- fifo = SyncFIFO([("slot", slotbits), ("length", lengthbits)], nslots)
- self.submodules += fifo
-
- # fsm
- fsm = FSM(reset_state="IDLE")
- self.submodules += fsm
-
- fsm.act("IDLE",
- If(sink.stb & sink.sop,
- If(fifo.sink.ack,
- ongoing.eq(1),
- counter_ce.eq(1),
- NextState("WRITE")
- )
- )
- )
- fsm.act("WRITE",
- counter_ce.eq(sink.stb),
- ongoing.eq(1),
- If(sink.stb & sink.eop,
- If((sink.error & sink.last_be) != 0,
- NextState("DISCARD")
- ).Else(
- NextState("TERMINATE")
- )
- )
- )
- fsm.act("DISCARD",
- counter_reset.eq(1),
- NextState("IDLE")
- )
- self.comb += [
- fifo.sink.slot.eq(slot),
- fifo.sink.length.eq(counter)
- ]
- fsm.act("TERMINATE",
- counter_reset.eq(1),
- slot_ce.eq(1),
- fifo.sink.stb.eq(1),
- NextState("IDLE")
- )
- self.comb += [
- fifo.source.ack.eq(self.ev.available.clear),
- self.ev.available.trigger.eq(fifo.source.stb),
- self._slot.status.eq(fifo.source.slot),
- self._length.status.eq(fifo.source.length),
- ]
-
- # memory
- mems = [None]*nslots
- ports = [None]*nslots
- for n in range(nslots):
- mems[n] = Memory(dw, depth)
- ports[n] = mems[n].get_port(write_capable=True)
- self.specials += ports[n]
- self.mems = mems
-
- cases = {}
- for n, port in enumerate(ports):
- cases[n] = [
- ports[n].adr.eq(counter[2:]),
- ports[n].dat_w.eq(sink.data),
- If(sink.stb & ongoing,
- ports[n].we.eq(0xf)
- )
- ]
- self.comb += Case(slot, cases)
-
-
-class LiteEthMACSRAMReader(Module, AutoCSR):
- def __init__(self, dw, depth, nslots=2):
- self.source = source = Source(eth_phy_description(dw))
-
- slotbits = max(log2_int(nslots), 1)
- lengthbits = log2_int(depth*4) # length in bytes
- self.lengthbits = lengthbits
-
- self._start = CSR()
- self._ready = CSRStatus()
- self._slot = CSRStorage(slotbits)
- self._length = CSRStorage(lengthbits)
-
- self.submodules.ev = EventManager()
- self.ev.done = EventSourcePulse()
- self.ev.finalize()
-
- # # #
-
- # command fifo
- fifo = SyncFIFO([("slot", slotbits), ("length", lengthbits)], nslots)
- self.submodules += fifo
- self.comb += [
- fifo.sink.stb.eq(self._start.re),
- fifo.sink.slot.eq(self._slot.storage),
- fifo.sink.length.eq(self._length.storage),
- self._ready.status.eq(fifo.sink.ack)
- ]
-
- # length computation
- counter = Signal(lengthbits)
- counter_reset = Signal()
- counter_ce = Signal()
- self.sync += If(counter_reset,
- counter.eq(0)
- ).Elif(counter_ce,
- counter.eq(counter + 4)
- )
-
-
- # fsm
- first = Signal()
- last = Signal()
- last_d = Signal()
-
- fsm = FSM(reset_state="IDLE")
- self.submodules += fsm
-
- fsm.act("IDLE",
- counter_reset.eq(1),
- If(fifo.source.stb,
- NextState("CHECK")
- )
- )
- fsm.act("CHECK",
- If(~last_d,
- NextState("SEND"),
- ).Else(
- NextState("END"),
- )
- )
- length_lsb = fifo.source.length[0:2]
- self.comb += [
- If(last,
- If(length_lsb == 3,
- source.last_be.eq(0b0010)
- ).Elif(length_lsb == 2,
- source.last_be.eq(0b0100)
- ).Elif(length_lsb == 1,
- source.last_be.eq(0b1000)
- ).Else(
- source.last_be.eq(0b0001)
- )
- )
- ]
- fsm.act("SEND",
- source.stb.eq(1),
- source.sop.eq(first),
- source.eop.eq(last),
- If(source.ack,
- counter_ce.eq(~last),
- NextState("CHECK")
- )
- )
- fsm.act("END",
- fifo.source.ack.eq(1),
- self.ev.done.trigger.eq(1),
- NextState("IDLE")
- )
-
- # first/last computation
- self.sync += [
- If(fsm.ongoing("IDLE"),
- first.eq(1)
- ).Elif(source.stb & source.ack,
- first.eq(0)
- )
- ]
- self.comb += last.eq((counter + 4) >= fifo.source.length)
- self.sync += last_d.eq(last)
-
- # memory
- rd_slot = fifo.source.slot
-
- mems = [None]*nslots
- ports = [None]*nslots
- for n in range(nslots):
- mems[n] = Memory(dw, depth)
- ports[n] = mems[n].get_port()
- self.specials += ports[n]
- self.mems = mems
-
- cases = {}
- for n, port in enumerate(ports):
- self.comb += ports[n].adr.eq(counter[2:])
- cases[n] = [source.data.eq(port.dat_r)]
- self.comb += Case(rd_slot, cases)
-
-
-class LiteEthMACSRAM(Module, AutoCSR):
- def __init__(self, dw, depth, nrxslots, ntxslots):
- self.submodules.writer = LiteEthMACSRAMWriter(dw, depth, nrxslots)
- self.submodules.reader = LiteEthMACSRAMReader(dw, depth, ntxslots)
- self.submodules.ev = SharedIRQ(self.writer.ev, self.reader.ev)
- self.sink, self.source = self.writer.sink, self.reader.source
+++ /dev/null
-from migen import *
-from migen.fhdl.simplify import FullMemoryWE
-
-from misoc.interconnect import wishbone
-from misoc.interconnect.csr import *
-from misoc.interconnect.stream import *
-from misoc.cores.liteeth_mini.common import eth_phy_description, buffer_depth
-from misoc.cores.liteeth_mini.mac.frontend import sram
-
-
-class LiteEthMACWishboneInterface(Module, AutoCSR):
- def __init__(self, dw, nrxslots=2, ntxslots=2):
- self.sink = Sink(eth_phy_description(dw))
- self.source = Source(eth_phy_description(dw))
- self.bus = wishbone.Interface()
-
- # # #
-
- # storage in SRAM
- sram_depth = buffer_depth//(dw//8)
- self.submodules.sram = sram.LiteEthMACSRAM(dw, sram_depth, nrxslots, ntxslots)
- self.comb += [
- Record.connect(self.sink, self.sram.sink),
- Record.connect(self.sram.source, self.source)
- ]
-
- # Wishbone interface
- wb_rx_sram_ifs = [wishbone.SRAM(self.sram.writer.mems[n], read_only=True)
- for n in range(nrxslots)]
- # TODO: FullMemoryWE should move to Mibuild
- wb_tx_sram_ifs = [FullMemoryWE()(wishbone.SRAM(self.sram.reader.mems[n], read_only=False))
- for n in range(ntxslots)]
- wb_sram_ifs = wb_rx_sram_ifs + wb_tx_sram_ifs
-
- wb_slaves = []
- decoderoffset = log2_int(sram_depth)
- decoderbits = log2_int(len(wb_sram_ifs))
- for n, wb_sram_if in enumerate(wb_sram_ifs):
- def slave_filter(a, v=n):
- return a[decoderoffset:decoderoffset+decoderbits] == v
- wb_slaves.append((slave_filter, wb_sram_if.bus))
- self.submodules += wb_sram_if
- wb_con = wishbone.Decoder(self.bus, wb_slaves, register=True)
- self.submodules += wb_con
+++ /dev/null
-from misoc.cores.liteeth_mini.common import *
-
-
-def LiteEthPHY(clock_pads, pads, clk_freq=None, **kwargs):
- # Autodetect PHY
- if hasattr(clock_pads, "gtx") and len(pads.tx_data) == 8:
- if hasattr(clock_pads, "tx"):
- # This is a 10/100/1G PHY
- from misoc.cores.liteeth_mini.phy.gmii_mii import LiteEthPHYGMIIMII
- return LiteEthPHYGMIIMII(clock_pads, pads, clk_freq=clk_freq, **kwargs)
- else:
- # This is a pure 1G PHY
- from misoc.cores.liteeth_mini.phy.gmii import LiteEthPHYGMII
- return LiteEthPHYGMII(clock_pads, pads, **kwargs)
- elif hasattr(pads, "rx_ctl"):
- # This is a 10/100/1G RGMII PHY
- raise ValueError("RGMII PHYs are specific to vendors (for now), use direct instantiation")
- elif len(pads.tx_data) == 4:
- # This is a MII PHY
- from misoc.cores.liteeth_mini.phy.mii import LiteEthPHYMII
- return LiteEthPHYMII(clock_pads, pads, **kwargs)
- else:
- raise ValueError("Unable to autodetect PHY from platform file, use direct instantiation")
+++ /dev/null
-from migen import *
-from migen.genlib.io import DDROutput
-from migen.genlib.resetsync import AsyncResetSynchronizer
-
-from misoc.cores.liteeth_mini.common import *
-
-
-class LiteEthPHYGMIITX(Module):
- def __init__(self, pads, pads_register=True):
- self.sink = sink = Sink(eth_phy_description(8))
-
- # # #
-
- if hasattr(pads, "tx_er"):
- self.sync += pads.tx_er.eq(0)
- pads_eq = [
- pads.tx_en.eq(sink.stb),
- pads.tx_data.eq(sink.data)
- ]
- if pads_register:
- self.sync += pads_eq
- else:
- self.comb += pads_eq
- self.comb += sink.ack.eq(1)
-
-
-class LiteEthPHYGMIIRX(Module):
- def __init__(self, pads):
- self.source = source = Source(eth_phy_description(8))
-
- # # #
-
- dv_d = Signal()
- self.sync += dv_d.eq(pads.dv)
-
- sop = Signal()
- eop = Signal()
- self.comb += [
- sop.eq(pads.dv & ~dv_d),
- eop.eq(~pads.dv & dv_d)
- ]
- self.sync += [
- source.stb.eq(pads.dv),
- source.sop.eq(sop),
- source.data.eq(pads.rx_data)
- ]
- self.comb += source.eop.eq(eop)
-
-
-class LiteEthPHYGMIICRG(Module, AutoCSR):
- def __init__(self, clock_pads, pads, with_hw_init_reset, mii_mode=0):
- self._reset = CSRStorage()
-
- # # #
-
- self.clock_domains.cd_eth_rx = ClockDomain()
- self.clock_domains.cd_eth_tx = ClockDomain()
-
- # RX : Let the synthesis tool insert the appropriate clock buffer
- self.comb += self.cd_eth_rx.clk.eq(clock_pads.rx)
-
- # TX : GMII: Drive clock_pads.gtx, clock_pads.tx unused
- # MII: Use PHY clock_pads.tx as eth_tx_clk, do not drive clock_pads.gtx
- self.specials += DDROutput(1, mii_mode, clock_pads.gtx, ClockSignal("eth_tx"))
- # XXX Xilinx specific, replace BUFGMUX with a generic clock buffer?
- self.specials += Instance("BUFGMUX",
- i_I0=self.cd_eth_rx.clk,
- i_I1=clock_pads.tx,
- i_S=mii_mode,
- o_O=self.cd_eth_tx.clk)
-
- if with_hw_init_reset:
- reset = Signal()
- counter = Signal(max=512)
- counter_done = Signal()
- counter_ce = Signal()
- self.sync += If(counter_ce, counter.eq(counter + 1))
- self.comb += [
- counter_done.eq(counter == 256),
- counter_ce.eq(~counter_done),
- reset.eq(~counter_done | self._reset.storage)
- ]
- else:
- reset = self._reset.storage
- self.comb += pads.rst_n.eq(~reset)
- self.specials += [
- AsyncResetSynchronizer(self.cd_eth_tx, reset),
- AsyncResetSynchronizer(self.cd_eth_rx, reset),
- ]
-
-
-class LiteEthPHYGMII(Module, AutoCSR):
- def __init__(self, clock_pads, pads, with_hw_init_reset=True):
- self.dw = 8
- self.submodules.crg = LiteEthPHYGMIICRG(clock_pads, pads, with_hw_init_reset)
- self.submodules.tx = ClockDomainsRenamer("eth_tx")(LiteEthPHYGMIITX(pads))
- self.submodules.rx = ClockDomainsRenamer("eth_rx")(LiteEthPHYGMIIRX(pads))
- self.sink, self.source = self.tx.sink, self.rx.source
+++ /dev/null
-from migen import *
-from migen.genlib.io import DDROutput
-from migen.genlib.cdc import PulseSynchronizer
-
-from misoc.interconnect.stream import *
-from misoc.cores.liteeth_mini.common import *
-from misoc.cores.liteeth_mini.phy.gmii import LiteEthPHYGMIICRG
-from misoc.cores.liteeth_mini.phy.mii import LiteEthPHYMIITX, LiteEthPHYMIIRX
-from misoc.cores.liteeth_mini.phy.gmii import LiteEthPHYGMIITX, LiteEthPHYGMIIRX
-
-
-modes = {
- "GMII": 0,
- "MII": 1
-}
-
-tx_pads_layout = [("tx_er", 1), ("tx_en", 1), ("tx_data", 8)]
-rx_pads_layout = [("rx_er", 1), ("dv", 1), ("rx_data", 8)]
-
-
-class LiteEthPHYGMIIMIITX(Module):
- def __init__(self, pads, mode):
- self.sink = sink = Sink(eth_phy_description(8))
-
- # # #
-
- gmii_tx_pads = Record(tx_pads_layout)
- gmii_tx = LiteEthPHYGMIITX(gmii_tx_pads, pads_register=False)
- self.submodules += gmii_tx
-
- mii_tx_pads = Record(tx_pads_layout)
- mii_tx = LiteEthPHYMIITX(mii_tx_pads, pads_register=False)
- self.submodules += mii_tx
-
- demux = Demultiplexer(eth_phy_description(8), 2)
- self.submodules += demux
- self.comb += [
- demux.sel.eq(mode == modes["MII"]),
- Record.connect(sink, demux.sink),
- Record.connect(demux.source0, gmii_tx.sink),
- Record.connect(demux.source1, mii_tx.sink),
- ]
-
- if hasattr(pads, "tx_er"):
- self.comb += pads.tx_er.eq(0)
- self.sync += [
- If(mode == modes["MII"],
- pads.tx_en.eq(mii_tx_pads.tx_en),
- pads.tx_data.eq(mii_tx_pads.tx_data),
- ).Else(
- pads.tx_en.eq(gmii_tx_pads.tx_en),
- pads.tx_data.eq(gmii_tx_pads.tx_data),
- )
- ]
-
-
-class LiteEthPHYGMIIMIIRX(Module):
- def __init__(self, pads, mode):
- self.source = source = Source(eth_phy_description(8))
-
- # # #
-
- pads_d = Record(rx_pads_layout)
- self.sync += [
- pads_d.dv.eq(pads.dv),
- pads_d.rx_data.eq(pads.rx_data)
- ]
-
- gmii_rx = LiteEthPHYGMIIRX(pads_d)
- self.submodules += gmii_rx
-
- mii_rx = LiteEthPHYMIIRX(pads_d)
- self.submodules += mii_rx
-
- mux = Multiplexer(eth_phy_description(8), 2)
- self.submodules += mux
- self.comb += [
- mux.sel.eq(mode == modes["MII"]),
- Record.connect(gmii_rx.source, mux.sink0),
- Record.connect(mii_rx.source, mux.sink1),
- Record.connect(mux.source, source)
- ]
-
-
-class LiteEthGMIIMIIModeDetection(Module, AutoCSR):
- def __init__(self, clk_freq):
- self.mode = Signal()
- self._mode = CSRStatus()
-
- # # #
-
- mode = Signal()
- update_mode = Signal()
- self.sync += \
- If(update_mode,
- self.mode.eq(mode)
- )
- self.comb += self._mode.status.eq(self.mode)
-
- # Principle:
- # sys_clk >= 125MHz
- # eth_rx <= 125Mhz
- # We generate ticks every 1024 clock cycles in eth_rx domain
- # and measure ticks period in sys_clk domain.
-
- # Generate a tick every 1024 clock cycles (eth_rx clock domain)
- eth_tick = Signal()
- eth_counter = Signal(10)
- self.sync.eth_rx += eth_counter.eq(eth_counter + 1)
- self.comb += eth_tick.eq(eth_counter == 0)
-
- # Synchronize tick (sys clock domain)
- sys_tick = Signal()
- eth_ps = PulseSynchronizer("eth_rx", "sys")
- self.comb += [
- eth_ps.i.eq(eth_tick),
- sys_tick.eq(eth_ps.o)
- ]
- self.submodules += eth_ps
-
- # sys_clk domain counter
- sys_counter = Signal(24)
- sys_counter_reset = Signal()
- sys_counter_ce = Signal()
- self.sync += [
- If(sys_counter_reset,
- sys_counter.eq(0)
- ).Elif(sys_counter_ce,
- sys_counter.eq(sys_counter + 1)
- )
- ]
-
- fsm = FSM(reset_state="IDLE")
- self.submodules += fsm
-
- fsm.act("IDLE",
- sys_counter_reset.eq(1),
- If(sys_tick,
- NextState("COUNT")
- )
- )
- fsm.act("COUNT",
- sys_counter_ce.eq(1),
- If(sys_tick,
- NextState("DETECTION")
- )
- )
- fsm.act("DETECTION",
- update_mode.eq(1),
- # if freq < 125MHz-5% use MII mode
- If(sys_counter > int((clk_freq/125000000)*1024*1.05),
- mode.eq(1)
- # if freq >= 125MHz-5% use GMII mode
- ).Else(
- mode.eq(0)
- ),
- NextState("IDLE")
- )
-
-
-class LiteEthPHYGMIIMII(Module, AutoCSR):
- def __init__(self, clock_pads, pads, clk_freq, with_hw_init_reset=True):
- self.dw = 8
- # Note: we can use GMII CRG since it also handles tx clock pad used for MII
- self.submodules.mode_detection = LiteEthGMIIMIIModeDetection(clk_freq)
- mode = self.mode_detection.mode
- self.submodules.crg = LiteEthPHYGMIICRG(clock_pads, pads, with_hw_init_reset, mode == modes["MII"])
- self.submodules.tx = ClockDomainsRenamer("eth_tx")(LiteEthPHYGMIIMIITX(pads, mode))
- self.submodules.rx = ClockDomainsRenamer("eth_rx")(LiteEthPHYGMIIMIIRX(pads, mode))
- self.sink, self.source = self.tx.sink, self.rx.source
+++ /dev/null
-from migen import *
-
-from misoc.interconnect.csr import *
-from misoc.interconnect.stream import *
-from misoc.cores.liteeth_mini.common import *
-from misoc.cores.liteeth.mini.generic import *
-
-
-class LiteEthPHYLoopbackCRG(Module, AutoCSR):
- def __init__(self):
- self._reset = CSRStorage()
-
- # # #
-
- self.clock_domains.cd_eth_rx = ClockDomain()
- self.clock_domains.cd_eth_tx = ClockDomain()
- self.comb += [
- self.cd_eth_rx.clk.eq(ClockSignal()),
- self.cd_eth_tx.clk.eq(ClockSignal())
- ]
-
- reset = self._reset.storage
- self.comb += [
- self.cd_eth_rx.rst.eq(reset),
- self.cd_eth_tx.rst.eq(reset)
- ]
-
-
-class LiteEthPHYLoopback(Module, AutoCSR):
- def __init__(self):
- self.dw = 8
- self.submodules.crg = LiteEthLoopbackPHYCRG()
- self.sink = Sink(eth_phy_description(8))
- self.source = Source(eth_phy_description(8))
- self.comb += Record.connect(self.sink, self.source)
+++ /dev/null
-from migen import *
-
-from misoc.interconnect.csr import *
-from misoc.interconnect.stream import *
-from misoc.cores.liteeth_mini.common import *
-
-
-def converter_description(dw):
- payload_layout = [("data", dw)]
- return EndpointDescription(payload_layout, packetized=True)
-
-
-class LiteEthPHYMIITX(Module):
- def __init__(self, pads, pads_register=True):
- self.sink = sink = Sink(eth_phy_description(8))
-
- # # #
-
- if hasattr(pads, "tx_er"):
- self.sync += pads.tx_er.eq(0)
- converter = Converter(converter_description(8),
- converter_description(4))
- self.submodules += converter
- self.comb += [
- converter.sink.stb.eq(sink.stb),
- converter.sink.data.eq(sink.data),
- sink.ack.eq(converter.sink.ack),
- converter.source.ack.eq(1)
- ]
- pads_eq = [
- pads.tx_en.eq(converter.source.stb),
- pads.tx_data.eq(converter.source.data)
- ]
- if pads_register:
- self.sync += pads_eq
- else:
- self.comb += pads_eq
-
-
-class LiteEthPHYMIIRX(Module):
- def __init__(self, pads):
- self.source = source = Source(eth_phy_description(8))
-
- # # #
-
- sop = Signal(reset=1)
- sop_set = Signal()
- sop_clr = Signal()
- self.sync += If(sop_set, sop.eq(1)).Elif(sop_clr, sop.eq(0))
-
- converter = Converter(converter_description(4),
- converter_description(8))
- converter = ResetInserter()(converter)
- self.submodules += converter
-
- self.sync += [
- converter.reset.eq(~pads.dv),
- converter.sink.stb.eq(1),
- converter.sink.data.eq(pads.rx_data)
- ]
- self.sync += [
- sop_set.eq(~pads.dv),
- sop_clr.eq(pads.dv)
- ]
- self.comb += [
- converter.sink.sop.eq(sop),
- converter.sink.eop.eq(~pads.dv)
- ]
- self.comb += Record.connect(converter.source, source)
-
-
-class LiteEthPHYMIICRG(Module, AutoCSR):
- def __init__(self, clock_pads, pads, with_hw_init_reset):
- self._reset = CSRStorage()
-
- # # #
-
- if hasattr(clock_pads, "phy"):
- self.sync.base50 += clock_pads.phy.eq(~clock_pads.phy)
-
- self.clock_domains.cd_eth_rx = ClockDomain()
- self.clock_domains.cd_eth_tx = ClockDomain()
- self.comb += self.cd_eth_rx.clk.eq(clock_pads.rx)
- self.comb += self.cd_eth_tx.clk.eq(clock_pads.tx)
-
- if with_hw_init_reset:
- reset = Signal()
- counter_done = Signal()
- self.submodules.counter = counter = Counter(max=512)
- self.comb += [
- counter_done.eq(counter.value == 256),
- counter.ce.eq(~counter_done),
- reset.eq(~counter_done | self._reset.storage)
- ]
- else:
- reset = self._reset.storage
- self.comb += pads.rst_n.eq(~reset)
- self.specials += [
- AsyncResetSynchronizer(self.cd_eth_tx, reset),
- AsyncResetSynchronizer(self.cd_eth_rx, reset),
- ]
-
-
-class LiteEthPHYMII(Module, AutoCSR):
- def __init__(self, clock_pads, pads, with_hw_init_reset=True):
- self.dw = 8
- self.submodules.crg = LiteEthPHYMIICRG(clock_pads, pads, with_hw_init_reset)
- self.submodules.tx = ClockDomainsRenamer("eth_tx")(LiteEthPHYMIITX(pads))
- self.submodules.rx = ClockDomainsRenamer("eth_tx")(LiteEthPHYMIIRX(pads))
- self.sink, self.source = self.tx.sink, self.rx.source
+++ /dev/null
-# RGMII PHY for Spartan-6
-
-from migen import *
-from migen.genlib.io import DDROutput
-from migen.genlib.misc import WaitTimer
-from migen.genlib.fsm import FSM, NextState
-
-from misoc.interconnect.stream import *
-from misoc.interconnect.csr import *
-from misoc.cores.liteeth_mini.common import *
-
-
-class LiteEthPHYRGMIITX(Module):
- def __init__(self, pads, pads_register=True):
- self.sink = sink = Sink(eth_phy_description(8))
-
- # # #
-
- self.specials += Instance("ODDR2",
- p_DDR_ALIGNMENT="C0", p_INIT=0, p_SRTYPE="ASYNC",
- i_C0=ClockSignal("eth_tx"), i_C1=~ClockSignal("eth_tx"),
- i_CE=1, i_S=0, i_R=0,
- i_D0=sink.stb, i_D1=sink.stb, o_Q=pads.tx_ctl,
- )
- for i in range(4):
- self.specials += Instance("ODDR2",
- p_DDR_ALIGNMENT="C0", p_INIT=0, p_SRTYPE="ASYNC",
- i_C0=ClockSignal("eth_tx"), i_C1=~ClockSignal("eth_tx"),
- i_CE=1, i_S=0, i_R=0,
- i_D0=sink.data[i], i_D1=sink.data[4+i], o_Q=pads.tx_data[i],
- )
- self.comb += sink.ack.eq(1)
-
-
-class LiteEthPHYRGMIIRX(Module):
- def __init__(self, pads):
- self.source = source = Source(eth_phy_description(8))
-
- # # #
-
- rx_ctl = Signal()
- rx_data = Signal(8)
-
- self.specials += Instance("IDDR2",
- p_DDR_ALIGNMENT="C0", p_INIT_Q0=0, p_INIT_Q1=0, p_SRTYPE="ASYNC",
- i_C0=ClockSignal("eth_rx"), i_C1=~ClockSignal("eth_rx"),
- i_CE=1, i_S=0, i_R=0,
- i_D=pads.rx_ctl, o_Q1=rx_ctl,
- )
- for i in range(4):
- self.specials += Instance("IDDR2",
- p_DDR_ALIGNMENT="C0", p_INIT_Q0=0, p_INIT_Q1=0, p_SRTYPE="ASYNC",
- i_C0=ClockSignal("eth_rx"), i_C1=~ClockSignal("eth_rx"),
- i_CE=1, i_S=0, i_R=0,
- i_D=pads.rx_data[i], o_Q0=rx_data[4+i], o_Q1=rx_data[i],
- )
-
-
- rx_ctl_d = Signal()
- self.sync += rx_ctl_d.eq(rx_ctl)
-
- sop = Signal()
- eop = Signal()
- self.comb += [
- sop.eq(rx_ctl & ~rx_ctl_d),
- eop.eq(~rx_ctl & rx_ctl_d)
- ]
- self.sync += [
- source.stb.eq(rx_ctl),
- source.sop.eq(sop),
- source.data.eq(rx_data)
- ]
- self.comb += source.eop.eq(eop)
-
-
-class LiteEthPHYRGMIICRG(Module, AutoCSR):
- def __init__(self, clock_pads, pads, with_hw_init_reset):
- self._reset = CSRStorage()
-
- # # #
-
- self.clock_domains.cd_eth_rx = ClockDomain()
- self.clock_domains.cd_eth_tx = ClockDomain()
-
-
- # RX
- dcm_reset = Signal()
- dcm_locked = Signal()
-
- timer = WaitTimer(1024)
- fsm = FSM(reset_state="DCM_RESET")
- self.submodules += timer, fsm
-
- fsm.act("DCM_RESET",
- dcm_reset.eq(1),
- timer.wait.eq(1),
- If(timer.done,
- timer.wait.eq(0),
- NextState("DCM_WAIT")
- )
- )
- fsm.act("DCM_WAIT",
- timer.wait.eq(1),
- If(timer.done,
- NextState("DCM_CHECK_LOCK")
- )
- )
- fsm.act("DCM_CHECK_LOCK",
- If(~dcm_locked,
- NextState("DCM_RESET")
- )
- )
-
- clk90_rx = Signal()
- clk0_rx = Signal()
- clk0_rx_bufg = Signal()
- self.specials += Instance("DCM",
- i_CLKIN=clock_pads.rx,
- i_CLKFB=clk0_rx_bufg,
- o_CLK0=clk0_rx,
- o_CLK90=clk90_rx,
- o_LOCKED=dcm_locked,
- i_PSEN=0,
- i_PSCLK=0,
- i_PSINCDEC=0,
- i_RST=dcm_reset
- )
-
- self.specials += Instance("BUFG", i_I=clk0_rx, o_O=clk0_rx_bufg)
- self.specials += Instance("BUFG", i_I=clk90_rx, o_O=self.cd_eth_rx.clk)
-
- # TX
- self.specials += DDROutput(1, 0, clock_pads.tx, ClockSignal("eth_tx"))
- self.specials += Instance("BUFG", i_I=self.cd_eth_rx.clk, o_O=self.cd_eth_tx.clk)
-
- # Reset
- if with_hw_init_reset:
- reset = Signal()
- counter_done = Signal()
- self.submodules.counter = counter = Counter(max=512)
- self.comb += [
- counter_done.eq(counter.value == 256),
- counter.ce.eq(~counter_done),
- reset.eq(~counter_done | self._reset.storage)
- ]
- else:
- reset = self._reset.storage
- self.comb += pads.rst_n.eq(~reset)
- self.specials += [
- AsyncResetSynchronizer(self.cd_eth_tx, reset),
- AsyncResetSynchronizer(self.cd_eth_rx, reset),
- ]
-
-
-class LiteEthPHYRGMII(Module, AutoCSR):
- def __init__(self, clock_pads, pads, with_hw_init_reset=True):
- self.dw = 8
- self.submodules.crg = LiteEthPHYRGMIICRG(clock_pads, pads, with_hw_init_reset)
- self.submodules.tx = ClockDomainsRenamer("eth_tx")(LiteEthPHYRGMIITX(pads))
- self.submodules.rx = ClockDomainsRenamer("eth_rx")(LiteEthPHYRGMIIRX(pads))
- self.sink, self.source = self.tx.sink, self.rx.source
+++ /dev/null
-from misoc.cores.lm32.core import LM32
+++ /dev/null
-import os
-
-from migen import *
-
-from misoc.interconnect import wishbone
-
-
-class LM32(Module):
- def __init__(self, platform, eba_reset):
- self.ibus = i = wishbone.Interface()
- self.dbus = d = wishbone.Interface()
- self.interrupt = Signal(32)
-
- ###
-
- i_adr_o = Signal(32)
- d_adr_o = Signal(32)
- self.specials += Instance("lm32_cpu",
- p_eba_reset=Instance.PreformattedParam("32'h{:08x}".format(eba_reset)),
-
- i_clk_i=ClockSignal(),
- i_rst_i=ResetSignal(),
-
- i_interrupt=self.interrupt,
-
- o_I_ADR_O=i_adr_o,
- o_I_DAT_O=i.dat_w,
- o_I_SEL_O=i.sel,
- o_I_CYC_O=i.cyc,
- o_I_STB_O=i.stb,
- o_I_WE_O=i.we,
- o_I_CTI_O=i.cti,
- o_I_BTE_O=i.bte,
- i_I_DAT_I=i.dat_r,
- i_I_ACK_I=i.ack,
- i_I_ERR_I=i.err,
- i_I_RTY_I=0,
-
- o_D_ADR_O=d_adr_o,
- o_D_DAT_O=d.dat_w,
- o_D_SEL_O=d.sel,
- o_D_CYC_O=d.cyc,
- o_D_STB_O=d.stb,
- o_D_WE_O=d.we,
- o_D_CTI_O=d.cti,
- o_D_BTE_O=d.bte,
- i_D_DAT_I=d.dat_r,
- i_D_ACK_I=d.ack,
- i_D_ERR_I=d.err,
- i_D_RTY_I=0)
-
- self.comb += [
- self.ibus.adr.eq(i_adr_o[2:]),
- self.dbus.adr.eq(d_adr_o[2:])
- ]
-
- # add Verilog sources
- vdir = os.path.join(
- os.path.abspath(os.path.dirname(__file__)), "verilog")
- platform.add_sources(os.path.join(vdir, "submodule", "rtl"),
- "lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v",
- "lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v",
- "lm32_shifter.v", "lm32_multiplier.v", "lm32_mc_arithmetic.v",
- "lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v",
- "lm32_dcache.v", "lm32_debug.v", "lm32_itlb.v", "lm32_dtlb.v")
- platform.add_verilog_include_path(vdir)
+++ /dev/null
-`ifdef LM32_CONFIG_V
-`else
-`define LM32_CONFIG_V
-
-//
-// EXCEPTION VECTORS BASE ADDRESS
-//
-
-// Base address for exception vectors
-`define CFG_EBA_RESET 32'h00000000
-
-// Base address for the debug exception vectors. If the DC_RE flag is
-// set or the at_debug signal is asserted (see CFG_ALTERNATE_EBA) this
-// will also be used for normal exception vectors.
-`define CFG_DEBA_RESET 32'h10000000
-
-// Enable exception vector remapping by external signal
-//`define CFG_ALTERNATE_EBA
-
-
-//
-// ALU OPTIONS
-//
-
-// Enable sign-extension instructions
-`define CFG_SIGN_EXTEND_ENABLED
-
-// Shifter
-// You may either enable the piplined or the multi-cycle barrel
-// shifter. The multi-cycle shifter will stall the pipeline until
-// the result is available after 32 cycles.
-// If both options are disabled, only "right shift by one bit" is
-// available.
-//`define CFG_MC_BARREL_SHIFT_ENABLED
-`define CFG_PL_BARREL_SHIFT_ENABLED
-
-// Multiplier
-// The multiplier is available either in a multi-cycle version or
-// in a pipelined one. The multi-cycle multiplier stalls the pipe
-// for 32 cycles. If both options are disabled, multiply operations
-// are not supported.
-//`define CFG_MC_MULTIPLY_ENABLED
-`define CFG_PL_MULTIPLY_ENABLED
-
-// Enable the multi-cycle divider. Stalls the pipe until the result
-// is ready after 32 cycles. If disabled, the divide operation is not
-// supported.
-`define CFG_MC_DIVIDE_ENABLED
-
-
-//
-// INTERRUPTS
-//
-
-// Enable support for 32 hardware interrupts
-`define CFG_INTERRUPTS_ENABLED
-
-// Enable level-sensitive interrupts. The interrupt line status is
-// reflected in the IP register, which is then read-only.
-`define CFG_LEVEL_SENSITIVE_INTERRUPTS
-
-
-//
-// USER INSTRUCTION
-//
-
-// Enable support for the user opcode.
-//`define CFG_USER_ENABLED
-
-
-//
-// MEMORY MANAGEMENT UNIT
-//
-
-// Enable instruction and data translation lookaside buffers and
-// restricted user mode.
-//`define CFG_MMU_ENABLED
-
-
-//
-// CACHE
-//
-
-// Instruction cache
-`define CFG_ICACHE_ENABLED
-`define CFG_ICACHE_ASSOCIATIVITY 1
-`define CFG_ICACHE_SETS 256
-`define CFG_ICACHE_BYTES_PER_LINE 16
-`define CFG_ICACHE_BASE_ADDRESS 32'h00000000
-`define CFG_ICACHE_LIMIT 32'h7fffffff
-
-// Data cache
-`define CFG_DCACHE_ENABLED
-`define CFG_DCACHE_ASSOCIATIVITY 1
-`define CFG_DCACHE_SETS 256
-`define CFG_DCACHE_BYTES_PER_LINE 16
-`define CFG_DCACHE_BASE_ADDRESS 32'h00000000
-`define CFG_DCACHE_LIMIT 32'h7fffffff
-
-
-//
-// DEBUG OPTION
-//
-
-// Globally enable debugging
-//`define CFG_DEBUG_ENABLED
-
-// Enable the hardware JTAG debugging interface.
-// Note: to use this, there must be a special JTAG module for your
-// device. At the moment, there is only support for the
-// Spartan-6.
-//`define CFG_JTAG_ENABLED
-
-// JTAG UART is a communication channel which uses JTAG to transmit
-// and receive bytes to and from the host computer.
-//`define CFG_JTAG_UART_ENABLED
-
-// Enable reading and writing to the memory and writing CSRs using
-// the JTAG interface.
-//`define CFG_HW_DEBUG_ENABLED
-
-// Number of hardware watchpoints, max. 4
-//`define CFG_WATCHPOINTS 32'h4
-
-// Enable hardware breakpoints
-//`define CFG_ROM_DEBUG_ENABLED
-
-// Number of hardware breakpoints, max. 4
-//`define CFG_BREAKPOINTS 32'h4
-
-// Put the processor into debug mode by an external signal. That is,
-// raise a breakpoint exception. This is useful if you have a debug
-// monitor and a serial line and you want to trap into the monitor on a
-// BREAK symbol on the serial line.
-//`define CFG_EXTERNAL_BREAK_ENABLED
-
-
-//
-// REGISTER FILE
-//
-
-// The following option explicitly infers block RAM for the register
-// file. There is extra logic to avoid parallel writes and reads.
-// Normally, if your synthesizer is smart enough, this should not be
-// necessary because it will automatically infer block RAM for you.
-//`define CFG_EBR_POSEDGE_REGISTER_FILE
-
-// Explicitly infers block RAM, too. But it uses two different clocks,
-// one being shifted by 180deg, for the read and write port. Therefore,
-// no additional logic to avoid the parallel write/reads.
-//`define CFG_EBR_NEGEDGE_REGISTER_FILE
-
-
-//
-// MISCELLANEOUS
-//
-
-// Exceptions on wishbone bus errors
-//`define CFG_BUS_ERRORS_ENABLED
-
-// Enable the cycle counter
-`define CFG_CYCLE_COUNTER_ENABLED
-
-// Embedded instruction ROM using on-chip block RAM
-//`define CFG_IROM_ENABLED
-//`define CFG_IROM_INIT_FILE "NONE"
-//`define CFG_IROM_BASE_ADDRESS 32'h10000000
-//`define CFG_IROM_LIMIT 32'h10000fff
-
-// Embedded data RAM using on-chip block RAM
-//`define CFG_DRAM_ENABLED
-//`define CFG_DRAM_INIT_FILE "NONE"
-//`define CFG_DRAM_BASE_ADDRESS 32'h20000000
-//`define CFG_DRAM_LIMIT 32'h20000fff
-
-// Trace unit
-//`define CFG_TRACE_ENABLED
-
-// Resolve unconditional branches already in the X stage (UNTESTED!)
-//`define CFG_FAST_UNCONDITIONAL_BRANCH
-
-// log2 function
-// If your simulator/synthesizer does not support the $clog2 system
-// function you can use a constant function instead.
-
-function integer clog2;
- input integer value;
- begin
- value = value - 1;
- for (clog2 = 0; value > 0; clog2 = clog2 + 1)
- value = value >> 1;
- end
-endfunction
-
-`define CLOG2 clog2
-
-//`define CLOG2 $clog2
-
-`endif
+++ /dev/null
-from misoc.cores.minicon.core import Minicon
+++ /dev/null
-from functools import reduce
-from operator import or_
-
-from migen import *
-from migen.genlib.fsm import FSM, NextState
-from migen.genlib.misc import WaitTimer
-
-from misoc.interconnect import dfi as dfibus
-from misoc.interconnect import wishbone
-
-
-class _AddressSlicer:
- def __init__(self, colbits, bankbits, rowbits, address_align):
- self.colbits = colbits
- self.bankbits = bankbits
- self.rowbits = rowbits
- self.address_align = address_align
- self.addressbits = colbits - address_align + bankbits + rowbits
-
- def row(self, address):
- split = self.bankbits + self.colbits - self.address_align
- if isinstance(address, int):
- return address >> split
- else:
- return address[split:self.addressbits]
-
- def bank(self, address):
- split = self.colbits - self.address_align
- if isinstance(address, int):
- return (address & (2**(split + self.bankbits) - 1)) >> split
- else:
- return address[split:split+self.bankbits]
-
- def col(self, address):
- split = self.colbits - self.address_align
- if isinstance(address, int):
- return (address & (2**split - 1)) << self.address_align
- else:
- return Cat(Replicate(0, self.address_align), address[:split])
-
-
-@ResetInserter()
-@CEInserter()
-class _Bank(Module):
- def __init__(self, geom_settings):
- self.open = Signal()
- self.row = Signal(geom_settings.rowbits)
-
- self.idle = Signal(reset=1)
- self.hit = Signal()
-
- # # #
-
- row = Signal(geom_settings.rowbits)
- self.sync += \
- If(self.open,
- self.idle.eq(0),
- row.eq(self.row)
- )
- self.comb += self.hit.eq(~self.idle & (self.row == row))
-
-
-class Minicon(Module):
- def __init__(self, phy_settings, geom_settings, timing_settings):
- if phy_settings.memtype in ["SDR"]:
- burst_length = phy_settings.nphases*1 # command multiplication*SDR
- elif phy_settings.memtype in ["DDR", "LPDDR", "DDR2", "DDR3"]:
- burst_length = phy_settings.nphases*2 # command multiplication*DDR
- burst_width = phy_settings.dfi_databits*phy_settings.nphases
- address_align = log2_int(burst_length)
-
- # # #
-
- self.dfi = dfi = dfibus.Interface(geom_settings.addressbits,
- geom_settings.bankbits,
- phy_settings.dfi_databits,
- phy_settings.nphases)
-
- self.bus = bus = wishbone.Interface(burst_width)
-
- rdphase = phy_settings.rdphase
- wrphase = phy_settings.wrphase
-
- precharge_all = Signal()
- activate = Signal()
- refresh = Signal()
- write = Signal()
- read = Signal()
-
- # Compute current column, bank and row from wishbone address
- slicer = _AddressSlicer(geom_settings.colbits,
- geom_settings.bankbits,
- geom_settings.rowbits,
- address_align)
-
- # Manage banks
- bank_idle = Signal()
- bank_hit = Signal()
-
- banks = []
- for i in range(2**geom_settings.bankbits):
- bank = _Bank(geom_settings)
- self.comb += [
- bank.open.eq(activate),
- bank.reset.eq(precharge_all),
- bank.row.eq(slicer.row(bus.adr))
- ]
- banks.append(bank)
- self.submodules += banks
-
- cases = {}
- for i, bank in enumerate(banks):
- cases[i] = [bank.ce.eq(1)]
- self.comb += Case(slicer.bank(bus.adr), cases)
-
- self.comb += [
- bank_hit.eq(reduce(or_, [bank.hit & bank.ce for bank in banks])),
- bank_idle.eq(reduce(or_, [bank.idle & bank.ce for bank in banks])),
- ]
-
- # Timings
- write2precharge_timer = WaitTimer(2 + timing_settings.tWR - 1)
- self.submodules += write2precharge_timer
- self.comb += write2precharge_timer.wait.eq(~write)
-
- refresh_timer = WaitTimer(timing_settings.tREFI)
- self.submodules += refresh_timer
- self.comb += refresh_timer.wait.eq(~refresh)
-
- # Main FSM
- self.submodules.fsm = fsm = FSM()
- fsm.act("IDLE",
- If(refresh_timer.done,
- NextState("PRECHARGE-ALL")
- ).Elif(bus.stb & bus.cyc,
- If(bank_hit,
- If(bus.we,
- NextState("WRITE")
- ).Else(
- NextState("READ")
- )
- ).Elif(~bank_idle,
- If(write2precharge_timer.done,
- NextState("PRECHARGE")
- )
- ).Else(
- NextState("ACTIVATE")
- )
- )
- )
- fsm.act("READ",
- read.eq(1),
- dfi.phases[rdphase].ras_n.eq(1),
- dfi.phases[rdphase].cas_n.eq(0),
- dfi.phases[rdphase].we_n.eq(1),
- dfi.phases[rdphase].rddata_en.eq(1),
- NextState("WAIT-READ-DONE"),
- )
- fsm.act("WAIT-READ-DONE",
- If(dfi.phases[rdphase].rddata_valid,
- bus.ack.eq(1),
- NextState("IDLE")
- )
- )
- fsm.act("WRITE",
- write.eq(1),
- dfi.phases[wrphase].ras_n.eq(1),
- dfi.phases[wrphase].cas_n.eq(0),
- dfi.phases[wrphase].we_n.eq(0),
- dfi.phases[wrphase].wrdata_en.eq(1),
- NextState("WRITE-LATENCY")
- )
- fsm.act("WRITE-ACK",
- bus.ack.eq(1),
- NextState("IDLE")
- )
- fsm.act("PRECHARGE-ALL",
- precharge_all.eq(1),
- dfi.phases[rdphase].ras_n.eq(0),
- dfi.phases[rdphase].cas_n.eq(1),
- dfi.phases[rdphase].we_n.eq(0),
- NextState("PRE-REFRESH")
- )
- fsm.act("PRECHARGE",
- # do no reset bank since we are going to re-open it
- dfi.phases[0].ras_n.eq(0),
- dfi.phases[0].cas_n.eq(1),
- dfi.phases[0].we_n.eq(0),
- NextState("TRP")
- )
- fsm.act("ACTIVATE",
- activate.eq(1),
- dfi.phases[0].ras_n.eq(0),
- dfi.phases[0].cas_n.eq(1),
- dfi.phases[0].we_n.eq(1),
- NextState("TRCD"),
- )
- fsm.act("REFRESH",
- refresh.eq(1),
- dfi.phases[rdphase].ras_n.eq(0),
- dfi.phases[rdphase].cas_n.eq(0),
- dfi.phases[rdphase].we_n.eq(1),
- NextState("POST-REFRESH")
- )
- fsm.delayed_enter("WRITE-LATENCY", "WRITE-ACK", phy_settings.write_latency-1)
- fsm.delayed_enter("TRP", "ACTIVATE", timing_settings.tRP-1)
- fsm.delayed_enter("TRCD", "IDLE", timing_settings.tRCD-1)
- fsm.delayed_enter("PRE-REFRESH", "REFRESH", timing_settings.tRP-1)
- fsm.delayed_enter("POST-REFRESH", "IDLE", timing_settings.tRFC-1)
-
- # DFI commands
- for phase in dfi.phases:
- if hasattr(phase, "reset_n"):
- self.comb += phase.reset_n.eq(1)
- if hasattr(phase, "odt"):
- self.comb += phase.odt.eq(1)
- self.comb += [
- phase.cke.eq(1),
- phase.cs_n.eq(0),
- phase.bank.eq(slicer.bank(bus.adr)),
- If(precharge_all,
- phase.address.eq(2**10)
- ).Elif(activate,
- phase.address.eq(slicer.row(bus.adr))
- ).Elif(write | read,
- phase.address.eq(slicer.col(bus.adr))
- )
- ]
-
- # DFI datapath
- self.comb += [
- bus.dat_r.eq(Cat(phase.rddata for phase in dfi.phases)),
- Cat(phase.wrdata for phase in dfi.phases).eq(bus.dat_w),
- Cat(phase.wrdata_mask for phase in dfi.phases).eq(~bus.sel),
- ]
+++ /dev/null
-from migen import *
-from migen.bus.transactions import TRead, TWrite
-from migen.bus import wishbone
-from migen.sim.generic import Simulator
-from migen.sim import icarus
-from mibuild.platforms import papilio_pro as board
-from misoc import sdram
-from misoc.mem.sdram.core.minicon import Minicon
-from misoc.mem.sdram.phy import gensdrphy
-from itertools import chain
-from os.path import isfile
-import sys
-
-clk_freq = 80000000
-
-from math import ceil
-
-
-def ns(t, margin=True):
- clk_period_ns = 1000000000/clk_freq
- if margin:
- t += clk_period_ns/2
- return ceil(t/clk_period_ns)
-
-
-class MiniconTB(Module):
- def __init__(self, sdrphy, dfi, sdram_geom, sdram_timing, pads, sdram_clk):
-
- self.clk_freq = 80000000
- phy_settings = sdrphy.settings
- rdphase = phy_settings.rdphase
- self.submodules.slave = Minicon(phy_settings, sdram_geom, sdram_timing)
-
- self.submodules.tap = wishbone.Tap(self.slave.bus)
- self.submodules.dc = dc = wishbone.DownConverter(32, phy_settings.nphases*len(dfi.phases[rdphase].rddata))
- self.submodules.master = wishbone.Initiator(self.genxfers(), bus=dc.wishbone_i)
- self.submodules.intercon = wishbone.InterconnectPointToPoint(dc.wishbone_o, self.slave.bus)
-
- self.submodules.sdrphy = self.sdrphy = sdrphy
- self.dfi = dfi
- self.pads = pads
-
- self.specials += Instance("mt48lc4m16a2",
- io_Dq=pads.dq,
- i_Addr=pads.a,
- i_Ba=pads.ba,
- i_Clk=ClockSignal(),
- i_Cke=pads.cke,
- i_Cs_n=pads.cs_n,
- i_Ras_n=pads.ras_n,
- i_Cas_n=pads.cas_n,
- i_We_n=pads.we_n,
- i_Dqm=pads.dm
- )
-
- def genxfers(self):
- cycle = 0
- for a in chain(range(4), range(256, 260), range(1024, 1028)):
- t = TRead(a)
- yield t
- print("read {} in {} cycles".format(t.data, t.latency))
- for a in chain(range(4), range(256, 260), range(1024, 1028), range(4096, 4100)):
- t = TWrite(a, 0xaa55aa55+cycle)
- cycle += 1
- yield t
- print("read {} in {} cycles".format(t.data, t.latency))
- for a in chain(range(4), range(256, 260), range(1024, 1028), range(4096, 4100)):
- t = TRead(a)
- yield t
- print("read {} in {} cycles".format(t.data, t.latency))
-
- def gen_simulation(self, selfp):
- dfi = selfp.dfi
- phy = self.sdrphy
- rdphase = phy.settings.rdphase
- cycle = 0
-
- while True:
- yield
-
-
-class MyTopLevel:
- def __init__(self, vcd_name=None, vcd_level=1,
- top_name="top", dut_type="dut", dut_name="dut",
- cd_name="sys", clk_period=10):
- self.vcd_name = vcd_name
- self.vcd_level = vcd_level
- self.top_name = top_name
- self.dut_type = dut_type
- self.dut_name = dut_name
-
- self._cd_name = cd_name
- self._clk_period = clk_period
-
- cd = ClockDomain(self._cd_name)
- cd_ps = ClockDomain("sys_ps")
- self.clock_domains = [cd, cd_ps]
- self.ios = {cd.clk, cd.rst, cd_ps.clk}
-
- def get(self, sockaddr):
- template1 = """`timescale 1ns / 1ps
-
-module {top_name}();
-
-reg {clk_name};
-reg {rst_name};
-reg sys_ps_clk;
-
-initial begin
- {rst_name} <= 1'b1;
- @(posedge {clk_name});
- {rst_name} <= 1'b0;
-end
-
-always begin
- {clk_name} <= 1'b0;
- #{hclk_period};
- {clk_name} <= 1'b1;
- #{hclk_period};
-end
-
-always @(posedge {clk_name} or negedge {clk_name})
- sys_ps_clk <= #({hclk_period}*2-3) {clk_name};
-
-{dut_type} {dut_name}(
- .{rst_name}({rst_name}),
- .{clk_name}({clk_name}),
- .sys_ps_clk(sys_ps_clk)
-);
-
-initial $migensim_connect("{sockaddr}");
-always @(posedge {clk_name}) $migensim_tick;
-"""
- template2 = """
-initial begin
- $dumpfile("{vcd_name}");
- $dumpvars({vcd_level}, {dut_name});
-end
-"""
- r = template1.format(top_name=self.top_name,
- dut_type=self.dut_type,
- dut_name=self.dut_name,
- clk_name=self._cd_name + "_clk",
- rst_name=self._cd_name + "_rst",
- hclk_period=str(self._clk_period/2),
- sockaddr=sockaddr)
- if self.vcd_name is not None:
- r += template2.format(vcd_name=self.vcd_name,
- vcd_level=str(self.vcd_level),
- dut_name=self.dut_name)
- r += "\nendmodule"
- return r
-
-
-if __name__ == "__main__":
-
- plat = board.Platform()
-
- sdram_geom = sdram.GeomSettings(
- bankbits=2,
- rowbits=12,
- colbits=8
- )
-
- sdram_timing = sdram.TimingSettings(
- tRP=ns(15),
- tRCD=ns(15),
- tWR=ns(14),
- tWTR=2,
- tREFI=ns(64*1000*1000/4096, False),
- tRFC=ns(66),
- req_queue_size=8,
- read_time=32,
- write_time=16
- )
-
- sdram_pads = plat.request("sdram")
- sdram_clk = plat.request("sdram_clock")
-
- sdrphy = gensdrphy.GENSDRPHY(sdram_pads)
-
-# This sets CL to 2 during LMR done on 1st cycle
- sdram_pads.a.reset = 1<<5
-
- s = MiniconTB(sdrphy, sdrphy.dfi, sdram_geom, sdram_timing, pads=sdram_pads, sdram_clk=sdram_clk)
-
- extra_files = ["sdram_model/mt48lc4m16a2.v"]
-
- if not isfile(extra_files[0]):
- print("ERROR: You need to download Micron Verilog simulation model for MT48LC4M16A2 and put it in sdram_model/mt48lc4m16a2.v")
- print("File can be downloaded from this URL: http://www.micron.com/-/media/documents/products/sim%20model/dram/dram/4054mt48lc4m16a2.zip")
- sys.exit(1)
-
- with Simulator(s, MyTopLevel("top.vcd", clk_period=int(1/0.08)), icarus.Runner(extra_files=extra_files, keep_files=True)) as sim:
- sim.run(5000)
+++ /dev/null
-from misoc.cores.mor1kx.core import MOR1KX
+++ /dev/null
-import os
-
-from migen import *
-
-from misoc.interconnect import wishbone
-
-
-class MOR1KX(Module):
- def __init__(self, platform, reset_pc):
- self.ibus = i = wishbone.Interface()
- self.dbus = d = wishbone.Interface()
- self.interrupt = Signal(32)
-
- ###
-
- i_adr_o = Signal(32)
- d_adr_o = Signal(32)
- self.specials += Instance("mor1kx",
- p_FEATURE_INSTRUCTIONCACHE="ENABLED",
- p_OPTION_ICACHE_BLOCK_WIDTH=4,
- p_OPTION_ICACHE_SET_WIDTH=8,
- p_OPTION_ICACHE_WAYS=1,
- p_OPTION_ICACHE_LIMIT_WIDTH=31,
- p_FEATURE_DATACACHE="ENABLED",
- p_OPTION_DCACHE_BLOCK_WIDTH=4,
- p_OPTION_DCACHE_SET_WIDTH=8,
- p_OPTION_DCACHE_WAYS=1,
- p_OPTION_DCACHE_LIMIT_WIDTH=31,
- p_FEATURE_TIMER="NONE",
- p_OPTION_PIC_TRIGGER="LEVEL",
- p_FEATURE_SYSCALL="NONE",
- p_FEATURE_TRAP="NONE",
- p_FEATURE_RANGE="NONE",
- p_FEATURE_OVERFLOW="NONE",
- p_FEATURE_ADDC="ENABLED",
- p_FEATURE_CMOV="ENABLED",
- p_FEATURE_FFL1="ENABLED",
- p_OPTION_CPU0="CAPPUCCINO",
- p_OPTION_RESET_PC=reset_pc,
- p_IBUS_WB_TYPE="B3_REGISTERED_FEEDBACK",
- p_DBUS_WB_TYPE="B3_REGISTERED_FEEDBACK",
-
- i_clk=ClockSignal(),
- i_rst=ResetSignal(),
-
- i_irq_i=self.interrupt,
-
- o_iwbm_adr_o=i_adr_o,
- o_iwbm_dat_o=i.dat_w,
- o_iwbm_sel_o=i.sel,
- o_iwbm_cyc_o=i.cyc,
- o_iwbm_stb_o=i.stb,
- o_iwbm_we_o=i.we,
- o_iwbm_cti_o=i.cti,
- o_iwbm_bte_o=i.bte,
- i_iwbm_dat_i=i.dat_r,
- i_iwbm_ack_i=i.ack,
- i_iwbm_err_i=i.err,
- i_iwbm_rty_i=0,
-
- o_dwbm_adr_o=d_adr_o,
- o_dwbm_dat_o=d.dat_w,
- o_dwbm_sel_o=d.sel,
- o_dwbm_cyc_o=d.cyc,
- o_dwbm_stb_o=d.stb,
- o_dwbm_we_o=d.we,
- o_dwbm_cti_o=d.cti,
- o_dwbm_bte_o=d.bte,
- i_dwbm_dat_i=d.dat_r,
- i_dwbm_ack_i=d.ack,
- i_dwbm_err_i=d.err,
- i_dwbm_rty_i=0)
-
- self.comb += [
- self.ibus.adr.eq(i_adr_o[2:]),
- self.dbus.adr.eq(d_adr_o[2:])
- ]
-
- # add Verilog sources
- vdir = os.path.join(
- os.path.abspath(os.path.dirname(__file__)),
- "verilog", "rtl", "verilog")
- platform.add_source_dir(vdir)
+++ /dev/null
-module mxcrg #(
- parameter in_period = 0.0,
- parameter f_mult = 0,
- parameter f_div = 0,
- parameter clk2x_period = (in_period*f_div)/(2.0*f_mult)
-) (
- input clk50_pad,
- input trigger_reset,
-
- output sys_clk,
- output reg sys_rst,
-
- /* Reset NOR flash */
- output norflash_rst_n,
-
- /* DDR PHY clocks */
- output clk2x_270,
- output clk4x_wr,
- output clk4x_wr_strb,
- output clk4x_rd,
- output clk4x_rd_strb,
-
- /* DDR off-chip clocking */
- output ddr_clk_pad_p,
- output ddr_clk_pad_n,
-
- /* Base clock, buffered */
- output base50_clk
-);
-
-/*
- * Reset
- */
-
-reg [19:0] rst_debounce;
-always @(posedge sys_clk) begin
- if(trigger_reset)
- rst_debounce <= 20'hFFFFF;
- else if(rst_debounce != 20'd0)
- rst_debounce <= rst_debounce - 20'd1;
- sys_rst <= rst_debounce != 20'd0;
-end
-
-initial rst_debounce <= 20'hFFFFF;
-
-/*
- * We must release the Flash reset before the system reset
- * because the Flash needs some time to come out of reset
- * and the CPU begins fetching instructions from it
- * as soon as the system reset is released.
- * From datasheet, minimum reset pulse width is 100ns
- * and reset-to-read time is 150ns.
- */
-
-reg [7:0] flash_rstcounter;
-
-always @(posedge sys_clk) begin
- if(trigger_reset)
- flash_rstcounter <= 8'd0;
- else if(~flash_rstcounter[7])
- flash_rstcounter <= flash_rstcounter + 8'd1;
-end
-
-initial flash_rstcounter <= 8'd0;
-
-assign norflash_rst_n = flash_rstcounter[7];
-
-/*
- * Clock management. Inspired by the NWL reference design.
- */
-
-wire sdr_clk50;
-wire clkdiv;
-
-IBUF #(
- .IOSTANDARD("DEFAULT")
-) clk2_iob (
- .I(clk50_pad),
- .O(sdr_clk50)
-);
-
-BUFIO2 #(
- .DIVIDE(1),
- .DIVIDE_BYPASS("FALSE"),
- .I_INVERT("FALSE")
-) bufio2_inst2 (
- .I(sdr_clk50),
- .IOCLK(),
- .DIVCLK(clkdiv),
- .SERDESSTROBE()
-);
-
-wire pll_lckd;
-wire buf_pll_fb_out;
-wire pllout0;
-wire pllout1;
-wire pllout2;
-wire pllout3;
-wire pllout4;
-wire pllout5;
-
-PLL_ADV #(
- .BANDWIDTH("OPTIMIZED"),
- .CLKFBOUT_MULT(4*f_mult),
- .CLKFBOUT_PHASE(0.0),
- .CLKIN1_PERIOD(in_period),
- .CLKIN2_PERIOD(in_period),
-
- .CLKOUT0_DIVIDE(f_div),
- .CLKOUT0_DUTY_CYCLE(0.5),
- .CLKOUT0_PHASE(0.0),
-
- .CLKOUT1_DIVIDE(f_div),
- .CLKOUT1_DUTY_CYCLE(0.5),
- .CLKOUT1_PHASE(0.0),
-
- .CLKOUT2_DIVIDE(2*f_div),
- .CLKOUT2_DUTY_CYCLE(0.5),
- .CLKOUT2_PHASE(270.0),
-
- .CLKOUT3_DIVIDE(4*f_div),
- .CLKOUT3_DUTY_CYCLE(0.5),
- .CLKOUT3_PHASE(0.0),
-
- .CLKOUT4_DIVIDE(4*f_mult),
- .CLKOUT4_DUTY_CYCLE(0.5),
- .CLKOUT4_PHASE(0.0),
-
- .CLKOUT5_DIVIDE(2*f_div),
- .CLKOUT5_DUTY_CYCLE(0.5),
- .CLKOUT5_PHASE(250.0),
-
- .COMPENSATION("INTERNAL"),
- .DIVCLK_DIVIDE(1),
- .REF_JITTER(0.100),
- .CLK_FEEDBACK("CLKFBOUT"),
- .SIM_DEVICE("SPARTAN6")
-) pll (
- .CLKFBDCM(),
- .CLKFBOUT(buf_pll_fb_out),
- .CLKOUT0(pllout0), /* < x4 clock for writes */
- .CLKOUT1(pllout1), /* < x4 clock for reads */
- .CLKOUT2(pllout2), /* < x2 270 clock for DQS, memory address and control signals */
- .CLKOUT3(pllout3), /* < x1 clock for system and memory controller */
- .CLKOUT4(pllout4), /* < buffered clk50 */
- .CLKOUT5(pllout5), /* < x2 clock to off-chip DDR */
- .CLKOUTDCM0(),
- .CLKOUTDCM1(),
- .CLKOUTDCM2(),
- .CLKOUTDCM3(),
- .CLKOUTDCM4(),
- .CLKOUTDCM5(),
- .DO(),
- .DRDY(),
- .LOCKED(pll_lckd),
- .CLKFBIN(buf_pll_fb_out),
- .CLKIN1(clkdiv),
- .CLKIN2(1'b0),
- .CLKINSEL(1'b1),
- .DADDR(5'b00000),
- .DCLK(1'b0),
- .DEN(1'b0),
- .DI(16'h0000),
- .DWE(1'b0),
- .RST(1'b0),
- .REL(1'b0)
-);
-
-BUFPLL #(
- .DIVIDE(4)
-) wr_bufpll (
- .PLLIN(pllout0),
- .GCLK(sys_clk),
- .LOCKED(pll_lckd),
- .IOCLK(clk4x_wr),
- .LOCK(),
- .SERDESSTROBE(clk4x_wr_strb)
-);
-
-BUFPLL #(
- .DIVIDE(4)
-) rd_bufpll (
- .PLLIN(pllout1),
- .GCLK(sys_clk),
- .LOCKED(pll_lckd),
- .IOCLK(clk4x_rd),
- .LOCK(),
- .SERDESSTROBE(clk4x_rd_strb)
-);
-
-BUFG bufg_x2_2(
- .I(pllout2),
- .O(clk2x_270)
-);
-
-BUFG bufg_x1(
- .I(pllout3),
- .O(sys_clk)
-);
-
-wire base50_clk;
-BUFG bufg_50(
- .I(pllout4),
- .O(base50_clk)
-);
-
-wire clk2x_off;
-BUFG bufg_x2_offclk(
- .I(pllout5),
- .O(clk2x_off)
-);
-
-
-/*
- * SDRAM clock
- */
-
-ODDR2 #(
- .DDR_ALIGNMENT("NONE"),
- .INIT(1'b0),
- .SRTYPE("SYNC")
-) sd_clk_forward_p (
- .Q(ddr_clk_pad_p),
- .C0(clk2x_off),
- .C1(~clk2x_off),
- .CE(1'b1),
- .D0(1'b1),
- .D1(1'b0),
- .R(1'b0),
- .S(1'b0)
-);
-ODDR2 #(
- .DDR_ALIGNMENT("NONE"),
- .INIT(1'b0),
- .SRTYPE("SYNC")
-) sd_clk_forward_n (
- .Q(ddr_clk_pad_n),
- .C0(clk2x_off),
- .C1(~clk2x_off),
- .CE(1'b1),
- .D0(1'b0),
- .D1(1'b1),
- .R(1'b0),
- .S(1'b0)
-);
-
-endmodule
+++ /dev/null
-from migen import *
-from migen.genlib.fsm import FSM, NextState
-
-from misoc.interconnect import wishbone
-
-
-class NorFlash16(Module):
- def __init__(self, pads, rd_timing, wr_timing):
- self.bus = wishbone.Interface()
-
- ###
-
- data = TSTriple(16)
- lsb = Signal()
-
- self.specials += data.get_tristate(pads.d)
- self.comb += [
- data.oe.eq(pads.oe_n),
- pads.ce_n.eq(0)
- ]
-
- load_lo = Signal()
- load_hi = Signal()
- store = Signal()
-
- pads.oe_n.reset, pads.we_n.reset = 1, 1
- self.sync += [
- pads.oe_n.eq(1),
- pads.we_n.eq(1),
-
- # Register data/address to avoid off-chip glitches
- If(self.bus.cyc & self.bus.stb,
- pads.adr.eq(Cat(lsb, self.bus.adr)),
- If(self.bus.we,
- # Only 16-bit writes are supported. Assume sel=0011 or 1100.
- If(self.bus.sel[0],
- data.o.eq(self.bus.dat_w[:16])
- ).Else(
- data.o.eq(self.bus.dat_w[16:])
- )
- ).Else(
- pads.oe_n.eq(0)
- )
- ),
-
- If(load_lo, self.bus.dat_r[:16].eq(data.i)),
- If(load_hi, self.bus.dat_r[16:].eq(data.i)),
- If(store, pads.we_n.eq(0))
- ]
-
- # Typical timing of the flash chips:
- # - 110ns address to output
- # - 50ns write pulse width
- counter = Signal(max=max(rd_timing, wr_timing)+1)
- counter_en = Signal()
- counter_wr_mode = Signal()
- counter_done = Signal()
- self.comb += counter_done.eq(counter == Mux(counter_wr_mode, wr_timing, rd_timing))
- self.sync += If(counter_en & ~counter_done,
- counter.eq(counter + 1)
- ).Else(
- counter.eq(0)
- )
-
- fsm = FSM()
- self.submodules += fsm
-
- fsm.act("IDLE",
- If(self.bus.cyc & self.bus.stb,
- If(self.bus.we,
- NextState("WR")
- ).Else(
- NextState("RD_HI")
- )
- )
- )
- fsm.act("RD_HI",
- lsb.eq(0),
- counter_en.eq(1),
- If(counter_done,
- load_hi.eq(1),
- NextState("RD_LO")
- )
- )
- fsm.act("RD_LO",
- lsb.eq(1),
- counter_en.eq(1),
- If(counter_done,
- load_lo.eq(1),
- NextState("ACK")
- )
- )
- fsm.act("WR",
- # supported cases: sel=0011 [lsb=1] and sel=1100 [lsb=0]
- lsb.eq(self.bus.sel[0]),
- counter_wr_mode.eq(1),
- counter_en.eq(1),
- store.eq(1),
- If(counter_done, NextState("ACK"))
- )
- fsm.act("ACK",
- self.bus.ack.eq(1),
- NextState("IDLE")
- )
+++ /dev/null
-# This file is Copyright (c) 2015 Florent Kermarrec <florent@enjoy-digital.fr>
-# License: BSD
-
-# SDRAM simulation PHY at DFI level
-# tested with SDR/DDR/DDR2/LPDDR/DDR3
-# TODO:
-# - add $display support to Migen and manage timing violations?
-
-from migen import *
-from migen.fhdl.specials import *
-from misoc.mem.sdram.phy.dfi import *
-from misoc.mem import sdram
-
-
-class Bank(Module):
- def __init__(self, data_width, nrows, ncols, burst_length):
- self.activate = Signal()
- self.activate_row = Signal(max=nrows)
- self.precharge = Signal()
-
- self.write = Signal()
- self.write_col = Signal(max=ncols)
- self.write_data = Signal(data_width)
- self.write_mask = Signal(data_width//8)
-
- self.read = Signal()
- self.read_col = Signal(max=ncols)
- self.read_data = Signal(data_width)
-
- ###
- active = Signal()
- row = Signal(max=nrows)
-
- self.sync += \
- If(self.precharge,
- active.eq(0),
- ).Elif(self.activate,
- active.eq(1),
- row.eq(self.activate_row)
- )
-
- self.specials.mem = mem = Memory(data_width, nrows*ncols//burst_length)
- self.specials.write_port = write_port = mem.get_port(write_capable=True,
- we_granularity=8)
- self.specials.read_port = read_port = mem.get_port(async_read=True)
- self.comb += [
- If(active,
- write_port.adr.eq(row*ncols | self.write_col),
- write_port.dat_w.eq(self.write_data),
- write_port.we.eq(Replicate(self.write, data_width//8) & ~self.write_mask),
- If(self.read,
- read_port.adr.eq(row*ncols | self.read_col),
- self.read_data.eq(read_port.dat_r)
- )
- )
- ]
-
-
-class DFIPhase(Module):
- def __init__(self, dfi, n):
- phase = getattr(dfi, "p"+str(n))
-
- self.bank = phase.bank
- self.address = phase.address
-
- self.wrdata = phase.wrdata
- self.wrdata_mask = phase.wrdata_mask
-
- self.rddata = phase.rddata
- self.rddata_valid = phase.rddata_valid
-
- self.activate = Signal()
- self.precharge = Signal()
- self.write = Signal()
- self.read = Signal()
-
- ###
- self.comb += [
- If(~phase.cs_n & ~phase.ras_n & phase.cas_n,
- self.activate.eq(phase.we_n),
- self.precharge.eq(~phase.we_n)
- ),
- If(~phase.cs_n & phase.ras_n & ~phase.cas_n,
- self.write.eq(~phase.we_n),
- self.read.eq(phase.we_n)
- )
- ]
-
-
-class SDRAMPHYSim(Module):
- def __init__(self, module, settings):
- if settings.memtype in ["SDR"]:
- burst_length = settings.nphases*1 # command multiplication*SDR
- elif settings.memtype in ["DDR", "LPDDR", "DDR2", "DDR3"]:
- burst_length = settings.nphases*2 # command multiplication*DDR
-
- addressbits = module.geom_settings.addressbits
- bankbits = module.geom_settings.bankbits
- rowbits = module.geom_settings.rowbits
- colbits = module.geom_settings.colbits
-
- self.settings = settings
- self.module = module
-
- self.dfi = Interface(addressbits, bankbits, self.settings.dfi_databits, self.settings.nphases)
-
- ###
- nbanks = 2**bankbits
- nrows = 2**rowbits
- ncols = 2**colbits
- data_width = self.settings.dfi_databits*self.settings.nphases
-
- # DFI phases
- phases = [DFIPhase(self.dfi, n) for n in range(self.settings.nphases)]
- self.submodules += phases
-
- # banks
- banks = [Bank(data_width, nrows, ncols, burst_length) for i in range(nbanks)]
- self.submodules += banks
-
- # connect DFI phases to banks (cmds, write datapath)
- for nb, bank in enumerate(banks):
- # bank activate
- activates = Signal(len(phases))
- cases = {}
- for np, phase in enumerate(phases):
- self.comb += activates[np].eq(phase.activate)
- cases[2**np] = [
- bank.activate.eq(phase.bank == nb),
- bank.activate_row.eq(phase.address)
- ]
- self.comb += Case(activates, cases)
-
- # bank precharge
- precharges = Signal(len(phases))
- cases = {}
- for np, phase in enumerate(phases):
- self.comb += precharges[np].eq(phase.precharge)
- cases[2**np] = [
- bank.precharge.eq((phase.bank == nb) | phase.address[10])
- ]
- self.comb += Case(precharges, cases)
-
- # bank writes
- writes = Signal(len(phases))
- cases = {}
- for np, phase in enumerate(phases):
- self.comb += writes[np].eq(phase.write)
- cases[2**np] = [
- bank.write.eq(phase.bank == nb),
- bank.write_col.eq(phase.address)
- ]
- self.comb += Case(writes, cases)
- self.comb += [
- bank.write_data.eq(Cat(*[phase.wrdata for phase in phases])),
- bank.write_mask.eq(Cat(*[phase.wrdata_mask for phase in phases]))
- ]
-
- # bank reads
- reads = Signal(len(phases))
- cases = {}
- for np, phase in enumerate(phases):
- self.comb += reads[np].eq(phase.read)
- cases[2**np] = [
- bank.read.eq(phase.bank == nb),
- bank.read_col.eq(phase.address)
- ]
- self.comb += Case(reads, cases)
-
- # connect banks to DFI phases (cmds, read datapath)
- banks_read = Signal()
- banks_read_data = Signal(data_width)
- self.comb += [
- banks_read.eq(optree("|", [bank.read for bank in banks])),
- banks_read_data.eq(optree("|", [bank.read_data for bank in banks]))
- ]
- # simulate read latency
- for i in range(self.settings.read_latency):
- new_banks_read = Signal()
- new_banks_read_data = Signal(data_width)
- self.sync += [
- new_banks_read.eq(banks_read),
- new_banks_read_data.eq(banks_read_data)
- ]
- banks_read = new_banks_read
- banks_read_data = new_banks_read_data
-
- self.comb += [
- Cat(*[phase.rddata_valid for phase in phases]).eq(banks_read),
- Cat(*[phase.rddata for phase in phases]).eq(banks_read_data)
- ]
+++ /dev/null
-from misoc.cores.sdram_phy.gensdrphy import GENSDRPHY
-from misoc.cores.sdram_phy.s6ddrphy import S6HalfRateDDRPHY, S6QuarterRateDDRPHY
-from misoc.cores.sdram_phy.k7ddrphy import K7DDRPHY
+++ /dev/null
-#
-# 1:1 frequency-ratio Generic SDR PHY
-#
-# The GENSDRPHY is validated on CycloneIV (Altera) but since it does
-# not use vendor-dependent code, it can also be used on other architectures.
-#
-# The PHY needs 2 Clock domains:
-# - sys_clk : The System Clock domain
-# - sys_clk_ps : The System Clock domain with its phase shifted
-# (-3ns on C4@100MHz)
-#
-# Assert dfi_wrdata_en and present the data
-# on dfi_wrdata_mask/dfi_wrdata in the same
-# cycle as the write command.
-#
-# Assert dfi_rddata_en in the same cycle as the read
-# command. The data will come back on dfi_rddata
-# 4 cycles later, along with the assertion of
-# dfi_rddata_valid.
-#
-# This PHY only supports CAS Latency 2.
-#
-
-from migen import *
-from migen.genlib.record import *
-from migen.fhdl.specials import Tristate
-
-from misoc.interconnect.dfi import *
-from misoc.cores import sdram_settings
-
-
-class GENSDRPHY(Module):
- def __init__(self, pads):
- addressbits = len(pads.a)
- bankbits = len(pads.ba)
- databits = len(pads.dq)
-
- self.settings = sdram_settings.PhySettings(
- memtype="SDR",
- dfi_databits=databits,
- nphases=1,
- rdphase=0,
- wrphase=0,
- rdcmdphase=0,
- wrcmdphase=0,
- cl=2,
- read_latency=4,
- write_latency=0
- )
-
- self.dfi = Interface(addressbits, bankbits, databits)
-
- ###
-
- #
- # Command/address
- #
- self.sync += [
- pads.a.eq(self.dfi.p0.address),
- pads.ba.eq(self.dfi.p0.bank),
- pads.cke.eq(self.dfi.p0.cke),
- pads.cas_n.eq(self.dfi.p0.cas_n),
- pads.ras_n.eq(self.dfi.p0.ras_n),
- pads.we_n.eq(self.dfi.p0.we_n)
- ]
- if hasattr(pads, "cs_n"):
- self.sync += pads.cs_n.eq(self.dfi.p0.cs_n)
-
- #
- # DQ/DQS/DM data
- #
- sd_dq_out = Signal(databits)
- drive_dq = Signal()
- self.sync += sd_dq_out.eq(self.dfi.p0.wrdata)
- self.specials += Tristate(pads.dq, sd_dq_out, drive_dq)
- self.sync += \
- If(self.dfi.p0.wrdata_en,
- pads.dm.eq(self.dfi.p0.wrdata_mask)
- ).Else(
- pads.dm.eq(0)
- )
- sd_dq_in_ps = Signal(databits)
- self.sync.sys_ps += sd_dq_in_ps.eq(pads.dq)
- self.sync += self.dfi.p0.rddata.eq(sd_dq_in_ps)
-
- #
- # DQ/DM control
- #
- d_dfi_wrdata_en = Signal()
- self.sync += d_dfi_wrdata_en.eq(self.dfi.p0.wrdata_en)
- self.comb += drive_dq.eq(d_dfi_wrdata_en)
-
- rddata_sr = Signal(4)
- self.comb += self.dfi.p0.rddata_valid.eq(rddata_sr[3])
- self.sync += rddata_sr.eq(Cat(self.dfi.p0.rddata_en, rddata_sr[:3]))
+++ /dev/null
-# tCK=5ns CL=7 CWL=6
-
-from migen import *
-
-from misoc.interconnect.dfi import *
-from misoc.interconnect.csr import *
-from misoc.cores import sdram_settings
-
-
-class K7DDRPHY(Module, AutoCSR):
- def __init__(self, pads):
- addressbits = len(pads.a)
- bankbits = len(pads.ba)
- databits = len(pads.dq)
- nphases = 4
-
- self._wlevel_en = CSRStorage()
- self._wlevel_strobe = CSR()
- self._dly_sel = CSRStorage(databits//8)
- self._rdly_dq_rst = CSR()
- self._rdly_dq_inc = CSR()
- self._rdly_dq_bitslip = CSR()
- self._wdly_dq_rst = CSR()
- self._wdly_dq_inc = CSR()
- self._wdly_dqs_rst = CSR()
- self._wdly_dqs_inc = CSR()
-
- self.settings = sdram_settings.PhySettings(
- memtype="DDR3",
- dfi_databits=2*databits,
- nphases=nphases,
- rdphase=0,
- wrphase=2,
- rdcmdphase=1,
- wrcmdphase=0,
- cl=7,
- cwl=6,
- read_latency=6,
- write_latency=2
- )
-
- self.dfi = Interface(addressbits, bankbits, 2*databits, nphases)
-
- ###
-
- # Clock
- sd_clk_se = Signal()
- self.specials += [
- Instance("OSERDESE2",
- p_DATA_WIDTH=8, p_TRISTATE_WIDTH=1,
- p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF",
- p_SERDES_MODE="MASTER",
-
- o_OQ=sd_clk_se,
- i_OCE=1,
- i_RST=ResetSignal(),
- i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal(),
- i_D1=0, i_D2=1, i_D3=0, i_D4=1,
- i_D5=0, i_D6=1, i_D7=0, i_D8=1
- ),
- Instance("OBUFDS",
- i_I=sd_clk_se,
- o_O=pads.clk_p,
- o_OB=pads.clk_n
- )
- ]
-
- # Addresses and commands
- for i in range(addressbits):
- self.specials += \
- Instance("OSERDESE2",
- p_DATA_WIDTH=8, p_TRISTATE_WIDTH=1,
- p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF",
- p_SERDES_MODE="MASTER",
-
- o_OQ=pads.a[i],
- i_OCE=1,
- i_RST=ResetSignal(),
- i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal(),
- i_D1=self.dfi.phases[0].address[i], i_D2=self.dfi.phases[0].address[i],
- i_D3=self.dfi.phases[1].address[i], i_D4=self.dfi.phases[1].address[i],
- i_D5=self.dfi.phases[2].address[i], i_D6=self.dfi.phases[2].address[i],
- i_D7=self.dfi.phases[3].address[i], i_D8=self.dfi.phases[3].address[i]
- )
- for i in range(bankbits):
- self.specials += \
- Instance("OSERDESE2",
- p_DATA_WIDTH=8, p_TRISTATE_WIDTH=1,
- p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF",
- p_SERDES_MODE="MASTER",
-
- o_OQ=pads.ba[i],
- i_OCE=1,
- i_RST=ResetSignal(),
- i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal(),
- i_D1=self.dfi.phases[0].bank[i], i_D2=self.dfi.phases[0].bank[i],
- i_D3=self.dfi.phases[1].bank[i], i_D4=self.dfi.phases[1].bank[i],
- i_D5=self.dfi.phases[2].bank[i], i_D6=self.dfi.phases[2].bank[i],
- i_D7=self.dfi.phases[3].bank[i], i_D8=self.dfi.phases[3].bank[i]
- )
- for name in "ras_n", "cas_n", "we_n", "cs_n", "cke", "odt", "reset_n":
- self.specials += \
- Instance("OSERDESE2",
- p_DATA_WIDTH=8, p_TRISTATE_WIDTH=1,
- p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF",
- p_SERDES_MODE="MASTER",
-
- o_OQ=getattr(pads, name),
- i_OCE=1,
- i_RST=ResetSignal(),
- i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal(),
- i_D1=getattr(self.dfi.phases[0], name), i_D2=getattr(self.dfi.phases[0], name),
- i_D3=getattr(self.dfi.phases[1], name), i_D4=getattr(self.dfi.phases[1], name),
- i_D5=getattr(self.dfi.phases[2], name), i_D6=getattr(self.dfi.phases[2], name),
- i_D7=getattr(self.dfi.phases[3], name), i_D8=getattr(self.dfi.phases[3], name)
- )
-
- # DQS and DM
- oe_dqs = Signal()
- dqs_serdes_pattern = Signal(8)
- self.comb += \
- If(self._wlevel_en.storage,
- If(self._wlevel_strobe.re,
- dqs_serdes_pattern.eq(0b00000001)
- ).Else(
- dqs_serdes_pattern.eq(0b00000000)
- )
- ).Else(
- dqs_serdes_pattern.eq(0b01010101)
- )
- for i in range(databits//8):
- dm_o_nodelay = Signal()
- self.specials += \
- Instance("OSERDESE2",
- p_DATA_WIDTH=8, p_TRISTATE_WIDTH=1,
- p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF",
- p_SERDES_MODE="MASTER",
-
- o_OQ=dm_o_nodelay,
- i_OCE=1,
- i_RST=ResetSignal(),
- i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal(),
- i_D1=self.dfi.phases[0].wrdata_mask[i], i_D2=self.dfi.phases[0].wrdata_mask[databits//8+i],
- i_D3=self.dfi.phases[1].wrdata_mask[i], i_D4=self.dfi.phases[1].wrdata_mask[databits//8+i],
- i_D5=self.dfi.phases[2].wrdata_mask[i], i_D6=self.dfi.phases[2].wrdata_mask[databits//8+i],
- i_D7=self.dfi.phases[3].wrdata_mask[i], i_D8=self.dfi.phases[3].wrdata_mask[databits//8+i]
- )
- self.specials += \
- Instance("ODELAYE2",
- p_DELAY_SRC="ODATAIN", p_SIGNAL_PATTERN="DATA",
- p_CINVCTRL_SEL="FALSE", p_HIGH_PERFORMANCE_MODE="TRUE", p_REFCLK_FREQUENCY=200.0,
- p_PIPE_SEL="FALSE", p_ODELAY_TYPE="VARIABLE", p_ODELAY_VALUE=0,
-
- i_C=ClockSignal(),
- i_LD=self._dly_sel.storage[i] & self._wdly_dq_rst.re,
- i_CE=self._dly_sel.storage[i] & self._wdly_dq_inc.re,
- i_LDPIPEEN=0, i_INC=1,
-
- o_ODATAIN=dm_o_nodelay, o_DATAOUT=pads.dm[i]
- )
-
- dqs_nodelay = Signal()
- dqs_delayed = Signal()
- dqs_t = Signal()
- self.specials += [
- Instance("OSERDESE2",
- p_DATA_WIDTH=8, p_TRISTATE_WIDTH=1,
- p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF",
- p_SERDES_MODE="MASTER",
-
- o_OFB=dqs_nodelay, o_TQ=dqs_t,
- i_OCE=1, i_TCE=1,
- i_RST=ResetSignal(),
- i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal(),
- i_D1=dqs_serdes_pattern[0], i_D2=dqs_serdes_pattern[1],
- i_D3=dqs_serdes_pattern[2], i_D4=dqs_serdes_pattern[3],
- i_D5=dqs_serdes_pattern[4], i_D6=dqs_serdes_pattern[5],
- i_D7=dqs_serdes_pattern[6], i_D8=dqs_serdes_pattern[7],
- i_T1=~oe_dqs
- ),
- Instance("ODELAYE2",
- p_DELAY_SRC="ODATAIN", p_SIGNAL_PATTERN="DATA",
- p_CINVCTRL_SEL="FALSE", p_HIGH_PERFORMANCE_MODE="TRUE", p_REFCLK_FREQUENCY=200.0,
- p_PIPE_SEL="FALSE", p_ODELAY_TYPE="VARIABLE", p_ODELAY_VALUE=6,
-
- i_C=ClockSignal(),
- i_LD=self._dly_sel.storage[i] & self._wdly_dqs_rst.re,
- i_CE=self._dly_sel.storage[i] & self._wdly_dqs_inc.re,
- i_LDPIPEEN=0, i_INC=1,
-
- o_ODATAIN=dqs_nodelay, o_DATAOUT=dqs_delayed
- ),
- Instance("OBUFTDS",
- i_I=dqs_delayed, i_T=dqs_t,
- o_O=pads.dqs_p[i], o_OB=pads.dqs_n[i]
- )
- ]
-
- # DQ
- oe_dq = Signal()
- for i in range(databits):
- dq_o_nodelay = Signal()
- dq_o_delayed = Signal()
- dq_i_nodelay = Signal()
- dq_i_delayed = Signal()
- dq_t = Signal()
- self.specials += [
- Instance("OSERDESE2",
- p_DATA_WIDTH=8, p_TRISTATE_WIDTH=1,
- p_DATA_RATE_OQ="DDR", p_DATA_RATE_TQ="BUF",
- p_SERDES_MODE="MASTER",
-
- o_OQ=dq_o_nodelay, o_TQ=dq_t,
- i_OCE=1, i_TCE=1,
- i_RST=ResetSignal(),
- i_CLK=ClockSignal("sys4x"), i_CLKDIV=ClockSignal(),
- i_D1=self.dfi.phases[0].wrdata[i], i_D2=self.dfi.phases[0].wrdata[databits+i],
- i_D3=self.dfi.phases[1].wrdata[i], i_D4=self.dfi.phases[1].wrdata[databits+i],
- i_D5=self.dfi.phases[2].wrdata[i], i_D6=self.dfi.phases[2].wrdata[databits+i],
- i_D7=self.dfi.phases[3].wrdata[i], i_D8=self.dfi.phases[3].wrdata[databits+i],
- i_T1=~oe_dq
- ),
- Instance("ISERDESE2",
- p_DATA_WIDTH=8, p_DATA_RATE="DDR",
- p_SERDES_MODE="MASTER", p_INTERFACE_TYPE="NETWORKING",
- p_NUM_CE=1, p_IOBDELAY="IFD",
-
- i_DDLY=dq_i_delayed,
- i_CE1=1,
- i_RST=ResetSignal() | (self._dly_sel.storage[i//8] & self._wdly_dq_rst.re),
- i_CLK=ClockSignal("sys4x"), i_CLKB=~ClockSignal("sys4x"), i_CLKDIV=ClockSignal(),
- i_BITSLIP=self._dly_sel.storage[i//8] & self._rdly_dq_bitslip.re,
- o_Q8=self.dfi.phases[0].rddata[i], o_Q7=self.dfi.phases[0].rddata[databits+i],
- o_Q6=self.dfi.phases[1].rddata[i], o_Q5=self.dfi.phases[1].rddata[databits+i],
- o_Q4=self.dfi.phases[2].rddata[i], o_Q3=self.dfi.phases[2].rddata[databits+i],
- o_Q2=self.dfi.phases[3].rddata[i], o_Q1=self.dfi.phases[3].rddata[databits+i]
- ),
- Instance("ODELAYE2",
- p_DELAY_SRC="ODATAIN", p_SIGNAL_PATTERN="DATA",
- p_CINVCTRL_SEL="FALSE", p_HIGH_PERFORMANCE_MODE="TRUE", p_REFCLK_FREQUENCY=200.0,
- p_PIPE_SEL="FALSE", p_ODELAY_TYPE="VARIABLE", p_ODELAY_VALUE=0,
-
- i_C=ClockSignal(),
- i_LD=self._dly_sel.storage[i//8] & self._wdly_dq_rst.re,
- i_CE=self._dly_sel.storage[i//8] & self._wdly_dq_inc.re,
- i_LDPIPEEN=0, i_INC=1,
-
- o_ODATAIN=dq_o_nodelay, o_DATAOUT=dq_o_delayed
- ),
- Instance("IDELAYE2",
- p_DELAY_SRC="IDATAIN", p_SIGNAL_PATTERN="DATA",
- p_CINVCTRL_SEL="FALSE", p_HIGH_PERFORMANCE_MODE="TRUE", p_REFCLK_FREQUENCY=200.0,
- p_PIPE_SEL="FALSE", p_IDELAY_TYPE="VARIABLE", p_IDELAY_VALUE=6,
-
- i_C=ClockSignal(),
- i_LD=self._dly_sel.storage[i//8] & self._rdly_dq_rst.re,
- i_CE=self._dly_sel.storage[i//8] & self._rdly_dq_inc.re,
- i_LDPIPEEN=0, i_INC=1,
-
- i_IDATAIN=dq_i_nodelay, o_DATAOUT=dq_i_delayed
- ),
- Instance("IOBUF",
- i_I=dq_o_delayed, o_O=dq_i_nodelay, i_T=dq_t,
- io_IO=pads.dq[i]
- )
- ]
-
- # Flow control
- #
- # total read latency = 6:
- # 2 cycles through OSERDESE2
- # 2 cycles CAS
- # 2 cycles through ISERDESE2
- rddata_en = self.dfi.phases[self.settings.rdphase].rddata_en
- for i in range(5):
- n_rddata_en = Signal()
- self.sync += n_rddata_en.eq(rddata_en)
- rddata_en = n_rddata_en
- self.sync += [phase.rddata_valid.eq(rddata_en | self._wlevel_en.storage)
- for phase in self.dfi.phases]
-
- oe = Signal()
- last_wrdata_en = Signal(4)
- wrphase = self.dfi.phases[self.settings.wrphase]
- self.sync += last_wrdata_en.eq(Cat(wrphase.wrdata_en, last_wrdata_en[:3]))
- self.comb += oe.eq(last_wrdata_en[1] | last_wrdata_en[2] | last_wrdata_en[3])
- self.sync += \
- If(self._wlevel_en.storage,
- oe_dqs.eq(1), oe_dq.eq(0)
- ).Else(
- oe_dqs.eq(oe), oe_dq.eq(oe)
- )
+++ /dev/null
-# 1:2 and 1:4 frequency-ratio DDR / LPDDR / DDR2 / DDR3 PHYs for Spartan-6
-#
-# Assert dfi_wrdata_en and present the data
-# on dfi_wrdata_mask/dfi_wrdata in the same
-# cycle as the write command.
-#
-# Assert dfi_rddata_en in the same cycle as the read
-# command. The data will come back on dfi_rddata
-# 5 cycles later, along with the assertion
-# of dfi_rddata_valid.
-#
-# This PHY only supports CAS latency 3 for DDR, LPDDR, DDR2
-# and CAS latency 5/CAS write latency 6 for DDR3.
-#
-# Read commands must be sent on phase 0.
-# Write commands must be sent on phase 1.
-#
-
-from functools import reduce
-from operator import or_
-
-from migen import *
-from migen.genlib.record import *
-
-from misoc.interconnect.dfi import *
-from misoc.cores import sdram_settings
-
-
-class S6HalfRateDDRPHY(Module):
- def __init__(self, pads, memtype, rd_bitslip, wr_bitslip, dqs_ddr_alignment):
- if memtype not in ["DDR", "LPDDR", "DDR2", "DDR3"]:
- raise NotImplementedError("S6HalfRateDDRPHY only supports DDR, LPDDR, DDR2 and DDR3")
- addressbits = len(pads.a)
- bankbits = len(pads.ba)
- databits = len(pads.dq)
- nphases = 2
-
- if memtype == "DDR3":
- self.settings = sdram_settings.PhySettings(
- memtype="DDR3",
- dfi_databits=2*databits,
- nphases=nphases,
- rdphase=0,
- wrphase=1,
- rdcmdphase=1,
- wrcmdphase=0,
- cl=5,
- cwl=6,
- read_latency=6,
- write_latency=2
- )
- else:
- self.settings = sdram_settings.PhySettings(
- memtype=memtype,
- dfi_databits=2*databits,
- nphases=nphases,
- rdphase=0,
- wrphase=1,
- rdcmdphase=1,
- wrcmdphase=0,
- cl=3,
- read_latency=5,
- write_latency=0
- )
-
- self.dfi = Interface(addressbits, bankbits, 2*databits, nphases)
- self.clk4x_wr_strb = Signal()
- self.clk4x_rd_strb = Signal()
-
- ###
-
- # sys_clk : system clk, used for dfi interface
- # sdram_half_clk : half rate sdram clk
- # sdram_full_wr_clk : full rate sdram write clk
- # sdram_full_rd_clk : full rate sdram read clk
- sd_sys = getattr(self.sync, "sys")
- sd_sdram_half = getattr(self.sync, "sdram_half")
-
- sys_clk = ClockSignal("sys")
- sdram_half_clk = ClockSignal("sdram_half")
- sdram_full_wr_clk = ClockSignal("sdram_full_wr")
- sdram_full_rd_clk = ClockSignal("sdram_full_rd")
-
- #
- # Command/address
- #
-
- # select active phase
- # sys_clk ----____----____
- # phase_sel(nphases=2) 0 1 0 1 Half Rate
- phase_sel = Signal(log2_int(nphases))
- phase_half = Signal.like(phase_sel)
- phase_sys = Signal.like(phase_half)
-
- sd_sys += phase_sys.eq(phase_half)
-
- sd_sdram_half += [
- If(phase_half == phase_sys,
- phase_sel.eq(0),
- ).Else(
- phase_sel.eq(phase_sel+1)
- ),
- phase_half.eq(phase_half+1),
- ]
-
- # register dfi cmds on half_rate clk
- r_dfi = Array(Record(phase_cmd_description(addressbits, bankbits)) for i in range(nphases))
- for n, phase in enumerate(self.dfi.phases):
- sd_sdram_half += [
- r_dfi[n].reset_n.eq(phase.reset_n),
- r_dfi[n].odt.eq(phase.odt),
- r_dfi[n].address.eq(phase.address),
- r_dfi[n].bank.eq(phase.bank),
- r_dfi[n].cs_n.eq(phase.cs_n),
- r_dfi[n].cke.eq(phase.cke),
- r_dfi[n].cas_n.eq(phase.cas_n),
- r_dfi[n].ras_n.eq(phase.ras_n),
- r_dfi[n].we_n.eq(phase.we_n)
- ]
-
- # output cmds
- sd_sdram_half += [
- pads.a.eq(r_dfi[phase_sel].address),
- pads.ba.eq(r_dfi[phase_sel].bank),
- pads.cke.eq(r_dfi[phase_sel].cke),
- pads.ras_n.eq(r_dfi[phase_sel].ras_n),
- pads.cas_n.eq(r_dfi[phase_sel].cas_n),
- pads.we_n.eq(r_dfi[phase_sel].we_n)
- ]
- # optional pads
- for name in "reset_n", "cs_n", "odt":
- if hasattr(pads, name):
- sd_sdram_half += getattr(pads, name).eq(getattr(r_dfi[phase_sel], name))
-
- #
- # Bitslip
- #
- bitslip_cnt = Signal(4)
- bitslip_inc = Signal()
-
- sd_sys += [
- If(bitslip_cnt == rd_bitslip,
- bitslip_inc.eq(0)
- ).Else(
- bitslip_cnt.eq(bitslip_cnt+1),
- bitslip_inc.eq(1)
- )
- ]
-
- #
- # DQ/DQS/DM data
- #
- sdram_half_clk_n = Signal()
- self.comb += sdram_half_clk_n.eq(~sdram_half_clk)
-
- postamble = Signal()
- drive_dqs = Signal()
- dqs_t_d0 = Signal()
- dqs_t_d1 = Signal()
-
- dqs_o = Signal(databits//8)
- dqs_t = Signal(databits//8)
-
- self.comb += [
- dqs_t_d0.eq(~(drive_dqs | postamble)),
- dqs_t_d1.eq(~drive_dqs),
- ]
-
- for i in range(databits//8):
- # DQS output
- self.specials += Instance("ODDR2",
- p_DDR_ALIGNMENT=dqs_ddr_alignment,
- p_INIT=0,
- p_SRTYPE="ASYNC",
-
- i_C0=sdram_half_clk,
- i_C1=sdram_half_clk_n,
-
- i_CE=1,
- i_D0=0,
- i_D1=1,
- i_R=0,
- i_S=0,
-
- o_Q=dqs_o[i]
- )
-
- # DQS tristate cmd
- self.specials += Instance("ODDR2",
- p_DDR_ALIGNMENT=dqs_ddr_alignment,
- p_INIT=0,
- p_SRTYPE="ASYNC",
-
- i_C0=sdram_half_clk,
- i_C1=sdram_half_clk_n,
-
- i_CE=1,
- i_D0=dqs_t_d0,
- i_D1=dqs_t_d1,
- i_R=0,
- i_S=0,
-
- o_Q=dqs_t[i]
- )
-
- # DQS tristate buffer
- if hasattr(pads, "dqs_n"):
- self.specials += Instance("OBUFTDS",
- i_I=dqs_o[i],
- i_T=dqs_t[i],
-
- o_O=pads.dqs[i],
- o_OB=pads.dqs_n[i],
- )
- else:
- self.specials += Instance("OBUFT",
- i_I=dqs_o[i],
- i_T=dqs_t[i],
-
- o_O=pads.dqs[i]
- )
-
- sd_sdram_half += postamble.eq(drive_dqs)
-
- d_dfi = [Record(phase_wrdata_description(nphases*databits)+phase_rddata_description(nphases*databits))
- for i in range(2*nphases)]
-
- for n, phase in enumerate(self.dfi.phases):
- self.comb += [
- d_dfi[n].wrdata.eq(phase.wrdata),
- d_dfi[n].wrdata_mask.eq(phase.wrdata_mask),
- d_dfi[n].wrdata_en.eq(phase.wrdata_en),
- d_dfi[n].rddata_en.eq(phase.rddata_en),
- ]
- sd_sys += [
- d_dfi[nphases+n].wrdata.eq(phase.wrdata),
- d_dfi[nphases+n].wrdata_mask.eq(phase.wrdata_mask)
- ]
-
-
- drive_dq = Signal()
- drive_dq_n = [Signal() for i in range(2)]
- self.comb += drive_dq_n[0].eq(~drive_dq)
- sd_sys += drive_dq_n[1].eq(drive_dq_n[0])
-
- dq_t = Signal(databits)
- dq_o = Signal(databits)
- dq_i = Signal(databits)
-
- dq_wrdata = []
- for i in range(2):
- for j in reversed(range(nphases)):
- dq_wrdata.append(d_dfi[i*nphases+j].wrdata[:databits])
- dq_wrdata.append(d_dfi[i*nphases+j].wrdata[databits:])
-
- for i in range(databits):
- # Data serializer
- self.specials += Instance("OSERDES2",
- p_DATA_WIDTH=4,
- p_DATA_RATE_OQ="SDR",
- p_DATA_RATE_OT="SDR",
- p_SERDES_MODE="NONE",
- p_OUTPUT_MODE="SINGLE_ENDED",
-
- o_OQ=dq_o[i],
- i_OCE=1,
- i_CLK0=sdram_full_wr_clk,
- i_CLK1=0,
- i_IOCE=self.clk4x_wr_strb,
- i_RST=0,
- i_CLKDIV=sys_clk,
-
- i_D1=dq_wrdata[wr_bitslip+3][i],
- i_D2=dq_wrdata[wr_bitslip+2][i],
- i_D3=dq_wrdata[wr_bitslip+1][i],
- i_D4=dq_wrdata[wr_bitslip+0][i],
-
- o_TQ=dq_t[i],
- i_T1=drive_dq_n[(wr_bitslip+3)//4],
- i_T2=drive_dq_n[(wr_bitslip+2)//4],
- i_T3=drive_dq_n[(wr_bitslip+1)//4],
- i_T4=drive_dq_n[(wr_bitslip+0)//4],
- i_TRAIN=0,
- i_TCE=1,
- i_SHIFTIN1=0,
- i_SHIFTIN2=0,
- i_SHIFTIN3=0,
- i_SHIFTIN4=0,
- )
-
- # Data deserializer
- self.specials += Instance("ISERDES2",
- p_DATA_WIDTH=4,
- p_DATA_RATE="SDR",
- p_BITSLIP_ENABLE="TRUE",
- p_SERDES_MODE="NONE",
- p_INTERFACE_TYPE="RETIMED",
-
- i_D=dq_i[i],
- i_CE0=1,
- i_CLK0=sdram_full_rd_clk,
- i_CLK1=0,
- i_IOCE=self.clk4x_rd_strb,
- i_RST=ResetSignal(),
- i_CLKDIV=sys_clk,
- i_BITSLIP=bitslip_inc,
-
- o_Q1=d_dfi[0*nphases+0].rddata[i+databits],
- o_Q2=d_dfi[0*nphases+0].rddata[i],
- o_Q3=d_dfi[0*nphases+1].rddata[i+databits],
- o_Q4=d_dfi[0*nphases+1].rddata[i],
- )
-
- # Data buffer
- self.specials += Instance("IOBUF",
- i_I=dq_o[i],
- o_O=dq_i[i],
- i_T=dq_t[i],
- io_IO=pads.dq[i]
- )
-
- dq_wrdata_mask = []
- for i in range(2):
- for j in reversed(range(nphases)):
- dq_wrdata_mask.append(d_dfi[i*nphases+j].wrdata_mask[:databits//8])
- dq_wrdata_mask.append(d_dfi[i*nphases+j].wrdata_mask[databits//8:])
-
- for i in range(databits//8):
- # Mask serializer
- self.specials += Instance("OSERDES2",
- p_DATA_WIDTH=4,
- p_DATA_RATE_OQ="SDR",
- p_DATA_RATE_OT="SDR",
- p_SERDES_MODE="NONE",
- p_OUTPUT_MODE="SINGLE_ENDED",
-
- o_OQ=pads.dm[i],
- i_OCE=1,
- i_CLK0=sdram_full_wr_clk,
- i_CLK1=0,
- i_IOCE=self.clk4x_wr_strb,
- i_RST=0,
- i_CLKDIV=sys_clk,
-
- i_D1=dq_wrdata_mask[wr_bitslip+3][i],
- i_D2=dq_wrdata_mask[wr_bitslip+2][i],
- i_D3=dq_wrdata_mask[wr_bitslip+1][i],
- i_D4=dq_wrdata_mask[wr_bitslip+0][i],
-
- i_TRAIN=0,
- i_TCE=0,
- i_SHIFTIN1=0,
- i_SHIFTIN2=0,
- i_SHIFTIN3=0,
- i_SHIFTIN4=0,
- )
-
-
- #
- # DQ/DQS/DM control
- #
-
- # write
- wrdata_en = Signal()
- self.comb += wrdata_en.eq(reduce(or_, [d_dfi[p].wrdata_en for p in range(nphases)]))
-
- if memtype == "DDR3":
- r_drive_dq = Signal(self.settings.cwl-1)
- sd_sdram_half += r_drive_dq.eq(Cat(wrdata_en, r_drive_dq))
- self.comb += drive_dq.eq(r_drive_dq[self.settings.cwl-2])
- else:
- self.comb += drive_dq.eq(wrdata_en)
-
- wrdata_en_d = Signal()
- sd_sys += wrdata_en_d.eq(wrdata_en)
-
- r_dfi_wrdata_en = Signal(max(self.settings.cwl, self.settings.cl))
- sd_sdram_half += r_dfi_wrdata_en.eq(Cat(wrdata_en_d, r_dfi_wrdata_en))
-
- if memtype == "DDR3":
- self.comb += drive_dqs.eq(r_dfi_wrdata_en[self.settings.cwl-1])
- else:
- self.comb += drive_dqs.eq(r_dfi_wrdata_en[1])
-
- # read
- rddata_en = Signal()
- self.comb += rddata_en.eq(reduce(or_, [d_dfi[p].rddata_en for p in range(nphases)]))
-
- rddata_sr = Signal(self.settings.read_latency)
- sd_sys += rddata_sr.eq(Cat(rddata_sr[1:self.settings.read_latency], rddata_en))
-
- for n, phase in enumerate(self.dfi.phases):
- self.comb += [
- phase.rddata.eq(d_dfi[n].rddata),
- phase.rddata_valid.eq(rddata_sr[0]),
- ]
-
-
-class S6QuarterRateDDRPHY(Module):
- def __init__(self, pads, rd_bitslip, wr_bitslip, dqs_ddr_alignment):
- half_rate_phy = S6HalfRateDDRPHY(pads, "DDR3", rd_bitslip, wr_bitslip, dqs_ddr_alignment)
- self.submodules += RenameClockDomains(half_rate_phy, {"sys" : "sys2x"})
-
- addressbits = len(pads.a)
- bankbits = len(pads.ba)
- databits = len(pads.dq)
- nphases = 4
-
- self.settings = sdram_settings.PhySettings(
- memtype="DDR3",
- dfi_databits=2*databits,
- nphases=nphases,
- rdphase=0,
- wrphase=1,
- rdcmdphase=1,
- wrcmdphase=0,
- cl=5,
- cwl=6,
- read_latency=6//2+1,
- write_latency=2//2
- )
-
- self.dfi = Interface(addressbits, bankbits, 2*databits, nphases)
- self.clk8x_wr_strb = half_rate_phy.clk4x_wr_strb
- self.clk8x_rd_strb = half_rate_phy.clk4x_rd_strb
-
- # sys_clk : system clk, used for dfi interface
- # sys2x_clk : 2x system clk
- sd_sys = getattr(self.sync, "sys")
- sd_sys2x = getattr(self.sync, "sys2x")
-
- # select active sys2x phase
- # sys_clk ----____----____
- # phase_sel 0 1 0 1
- phase_sel = Signal()
- phase_sys2x = Signal.like(phase_sel)
- phase_sys = Signal.like(phase_sys2x)
-
- sd_sys += phase_sys.eq(phase_sys2x)
-
- sd_sys2x += [
- If(phase_sys2x == phase_sys,
- phase_sel.eq(0),
- ).Else(
- phase_sel.eq(~phase_sel)
- ),
- phase_sys2x.eq(~phase_sel)
- ]
-
- # DFI adaptation
-
- # Commands and writes
- dfi_leave_out = set(["rddata", "rddata_valid", "wrdata_en"])
- self.comb += [
- If(~phase_sel,
- Record.connect(self.dfi.phases[0], half_rate_phy.dfi.phases[0], leave_out=dfi_leave_out),
- Record.connect(self.dfi.phases[1], half_rate_phy.dfi.phases[1], leave_out=dfi_leave_out),
- ).Else(
- Record.connect(self.dfi.phases[2], half_rate_phy.dfi.phases[0], leave_out=dfi_leave_out),
- Record.connect(self.dfi.phases[3], half_rate_phy.dfi.phases[1], leave_out=dfi_leave_out),
- ),
- ]
- wr_data_en = self.dfi.phases[self.settings.wrphase].wrdata_en & ~phase_sel
- wr_data_en_d = Signal()
- sd_sys2x += wr_data_en_d.eq(wr_data_en)
- self.comb += half_rate_phy.dfi.phases[half_rate_phy.settings.wrphase].wrdata_en.eq(wr_data_en | wr_data_en_d)
-
- # Reads
- rddata = Array(Signal(2*databits) for i in range(2))
- rddata_valid = Signal(2)
-
- for i in range(2):
- sd_sys2x += [
- rddata_valid[i].eq(half_rate_phy.dfi.phases[i].rddata_valid),
- rddata[i].eq(half_rate_phy.dfi.phases[i].rddata)
- ]
-
- sd_sys += [
- self.dfi.phases[0].rddata.eq(rddata[0]),
- self.dfi.phases[0].rddata_valid.eq(rddata_valid[0]),
- self.dfi.phases[1].rddata.eq(rddata[1]),
- self.dfi.phases[1].rddata_valid.eq(rddata_valid[1]),
- self.dfi.phases[2].rddata.eq(half_rate_phy.dfi.phases[0].rddata),
- self.dfi.phases[2].rddata_valid.eq(half_rate_phy.dfi.phases[0].rddata_valid),
- self.dfi.phases[3].rddata.eq(half_rate_phy.dfi.phases[1].rddata),
- self.dfi.phases[3].rddata_valid.eq(half_rate_phy.dfi.phases[1].rddata_valid)
- ]
+++ /dev/null
-from math import ceil
-from collections import namedtuple
-
-from migen import *
-
-
-PhySettingsT = namedtuple("PhySettings", "memtype dfi_databits nphases rdphase wrphase rdcmdphase wrcmdphase cl cwl read_latency write_latency")
-def PhySettings(memtype, dfi_databits, nphases, rdphase, wrphase, rdcmdphase, wrcmdphase, cl, read_latency, write_latency, cwl=0):
- return PhySettingsT(memtype, dfi_databits, nphases, rdphase, wrphase, rdcmdphase, wrcmdphase, cl, cwl, read_latency, write_latency)
-
-GeomSettingsT = namedtuple("_GeomSettings", "bankbits rowbits colbits addressbits")
-def GeomSettings(bankbits, rowbits, colbits):
- return GeomSettingsT(bankbits, rowbits, colbits, max(rowbits, colbits))
-
-TimingSettings = namedtuple("TimingSettings", "tRP tRCD tWR tWTR tREFI tRFC")
-
-
-# TODO:
-# Try to share the maximum information we can between modules:
-# - ex: MT46V32M16 and MT46H32M16 are almost identical (V=DDR, H=LPDDR)
-# - Modules can have different configuration:
-# MT8JTF12864 (1GB), MT8JTF25664 (2GB)
-# but share all others informations, try to create an unique module for all
-# configurations.
-# - Modules can have different speedgrades, add support for it (and also add
-# a check to verify clk_freq is in the supported range)
-
-
-class SDRAMModule:
- def __init__(self, clk_freq, memtype, geom_settings, timing_settings):
- self.clk_freq = clk_freq
- self.memtype = memtype
- self.geom_settings = GeomSettings(
- bankbits=log2_int(geom_settings["nbanks"]),
- rowbits=log2_int(geom_settings["nrows"]),
- colbits=log2_int(geom_settings["ncols"]),
- )
- self.timing_settings = TimingSettings(
- tRP=self.ns(timing_settings["tRP"]),
- tRCD=self.ns(timing_settings["tRCD"]),
- tWR=self.ns(timing_settings["tWR"]),
- tWTR=timing_settings["tWTR"],
- tREFI=self.ns(timing_settings["tREFI"], False),
- tRFC=self.ns(timing_settings["tRFC"])
- )
-
- def ns(self, t, margin=True):
- clk_period_ns = 1000000000/self.clk_freq
- if margin:
- t += clk_period_ns/2
- return ceil(t/clk_period_ns)
-
-
-# SDR
-class IS42S16160(SDRAMModule):
- geom_settings = {
- "nbanks": 4,
- "nrows": 8192,
- "ncols": 512
- }
- # Timings for -7 speedgrade
- timing_settings = {
- "tRP": 20,
- "tRCD": 20,
- "tWR": 20,
- "tWTR": 2,
- "tREFI": 64*1000*1000/8192,
- "tRFC": 70
- }
- def __init__(self, clk_freq):
- SDRAMModule.__init__(self, clk_freq, "SDR", self.geom_settings,
- self.timing_settings)
-
-
-class MT48LC4M16(SDRAMModule):
- geom_settings = {
- "nbanks": 4,
- "nrows": 4096,
- "ncols": 256
- }
- timing_settings = {
- "tRP": 15,
- "tRCD": 15,
- "tWR": 14,
- "tWTR": 2,
- "tREFI": 64*1000*1000/4096,
- "tRFC": 66
- }
- def __init__(self, clk_freq):
- SDRAMModule.__init__(self, clk_freq, "SDR", self.geom_settings,
- self.timing_settings)
-
-
-class AS4C16M16(SDRAMModule):
- geom_settings = {
- "nbanks": 4,
- "nrows": 8192,
- "ncols": 512
- }
- # Timings for -6 speedgrade
- timing_settings = {
- "tRP": 18,
- "tRCD": 18,
- "tWR": 12,
- "tWTR": 2,
- "tREFI": 64*1000*1000/8192,
- "tRFC": 60
- }
- def __init__(self, clk_freq):
- SDRAMModule.__init__(self, clk_freq, "SDR", self.geom_settings,
- self.timing_settings)
-
-
-# DDR
-class MT46V32M16(SDRAMModule):
- geom_settings = {
- "nbanks": 4,
- "nrows": 8192,
- "ncols": 1024
- }
- timing_settings = {
- "tRP": 15,
- "tRCD": 15,
- "tWR": 15,
- "tWTR": 2,
- "tREFI": 64*1000*1000/8192,
- "tRFC": 70
- }
- def __init__(self, clk_freq):
- SDRAMModule.__init__(self, clk_freq, "DDR", self.geom_settings,
- self.timing_settings)
-
-
-# LPDDR
-class MT46H32M16(SDRAMModule):
- geom_settings = {
- "nbanks": 4,
- "nrows": 8192,
- "ncols": 1024
- }
- timing_settings = {
- "tRP": 15,
- "tRCD": 15,
- "tWR": 15,
- "tWTR": 2,
- "tREFI": 64*1000*1000/8192,
- "tRFC": 72
- }
- def __init__(self, clk_freq):
- SDRAMModule.__init__(self, clk_freq, "LPDDR", self.geom_settings,
- self.timing_settings)
-
-
-# DDR2
-class MT47H128M8(SDRAMModule):
- geom_settings = {
- "nbanks": 8,
- "nrows": 16384,
- "ncols": 1024
- }
- timing_settings = {
- "tRP": 15,
- "tRCD": 15,
- "tWR": 15,
- "tWTR": 2,
- "tREFI": 7800,
- "tRFC": 127.5
- }
- def __init__(self, clk_freq):
- SDRAMModule.__init__(self, clk_freq, "DDR2", self.geom_settings,
- self.timing_settings)
-
-
-class P3R1GE4JGF(SDRAMModule):
- geom_settings = {
- "nbanks": 8,
- "nrows": 8192,
- "ncols": 1024
- }
- timing_settings = {
- "tRP": 12.5,
- "tRCD": 12.5,
- "tWR": 15,
- "tWTR": 3,
- "tREFI": 7800,
- "tRFC": 127.5,
- }
-
- def __init__(self, clk_freq):
- SDRAMModule.__init__(self, clk_freq, "DDR2", self.geom_settings,
- self.timing_settings)
-
-
-# DDR3
-class MT8JTF12864(SDRAMModule):
- geom_settings = {
- "nbanks": 8,
- "nrows": 16384,
- "ncols": 1024
- }
- timing_settings = {
- "tRP": 15,
- "tRCD": 15,
- "tWR": 15,
- "tWTR": 2,
- "tREFI": 7800,
- "tRFC": 70
- }
- def __init__(self, clk_freq):
- SDRAMModule.__init__(self, clk_freq, "DDR3", self.geom_settings,
- self.timing_settings)
-
-
-class MT41J128M16(SDRAMModule):
- geom_settings = {
- "nbanks": 8,
- "nrows": 16384,
- "ncols": 1024,
- }
- timing_settings = {
- "tRP": 15,
- "tRCD": 15,
- "tWR": 15,
- "tWTR": 3,
- "tREFI": 64*1000*1000/16384,
- "tRFC": 260,
- }
- def __init__(self, clk_freq):
- SDRAMModule.__init__(self, clk_freq, "DDR3", self.geom_settings,
- self.timing_settings)
+++ /dev/null
-from functools import reduce
-from operator import xor
-
-from migen import *
-
-from misoc.interconnect.csr import *
-from misoc.interconnect import dma_lasmi
-
-# TODO: implement or replace DMAControllers in MiSoC
-
-
-@ResetInserter()
-@CEInserter()
-class LFSR(Module):
- def __init__(self, n_out, n_state=31, taps=[27, 30]):
- self.o = Signal(n_out)
-
- ###
-
- state = Signal(n_state)
- curval = [state[i] for i in range(n_state)]
- curval += [0]*(n_out - n_state)
- for i in range(n_out):
- nv = ~reduce(xor, [curval[tap] for tap in taps])
- curval.insert(0, nv)
- curval.pop()
-
- self.sync += [
- state.eq(Cat(*curval[:n_state])),
- self.o.eq(Cat(*curval))
- ]
-
-
-memtest_magic = 0x361f
-
-
-class Writer(Module):
- def __init__(self, lasmim):
- self._magic = CSRStatus(16)
- self._reset = CSR()
- self._shoot = CSR()
- self.submodules._dma = DMAWriteController(dma_lasmi.Writer(lasmim),
- MODE_EXTERNAL)
-
- ###
-
- self.comb += self._magic.status.eq(memtest_magic)
-
- lfsr = LFSR(lasmim.dw)
- self.submodules += lfsr
- self.comb += lfsr.reset.eq(self._reset.re)
-
- en = Signal()
- en_counter = Signal(lasmim.aw)
- self.comb += en.eq(en_counter != 0)
- self.sync += [
- If(self._shoot.re,
- en_counter.eq(self._dma.length)
- ).Elif(lfsr.ce,
- en_counter.eq(en_counter - 1)
- )
- ]
-
- self.comb += [
- self._dma.trigger.eq(self._shoot.re),
- self._dma.data.stb.eq(en),
- lfsr.ce.eq(en & self._dma.data.ack),
- self._dma.data.d.eq(lfsr.o)
- ]
-
- def get_csrs(self):
- return [self._magic, self._reset, self._shoot] + self._dma.get_csrs()
-
-
-class Reader(Module):
- def __init__(self, lasmim):
- self._magic = CSRStatus(16)
- self._reset = CSR()
- self._error_count = CSRStatus(lasmim.aw)
- self.submodules._dma = DMAReadController(dma_lasmi.Reader(lasmim),
- MODE_SINGLE_SHOT)
-
- ###
-
- self.comb += self._magic.status.eq(memtest_magic)
-
- lfsr = LFSR(lasmim.dw)
- self.submodules += lfsr
- self.comb += lfsr.reset.eq(self._reset.re)
-
- self.comb += [
- lfsr.ce.eq(self._dma.data.stb),
- self._dma.data.ack.eq(1)
- ]
- err_cnt = self._error_count.status
- self.sync += [
- If(self._reset.re,
- err_cnt.eq(0)
- ).Elif(self._dma.data.stb,
- If(self._dma.data.d != lfsr.o, err_cnt.eq(err_cnt + 1))
- )
- ]
-
- def get_csrs(self):
- return [self._magic, self._reset, self._error_count] + self._dma.get_csrs()
-
-
-class _LFSRTB(Module):
- def __init__(self, *args, **kwargs):
- self.submodules.dut = LFSR(*args, **kwargs)
- self.comb += self.dut.ce.eq(1)
-
- def do_simulation(self, selfp):
- print("{0:032x}".format(selfp.dut.o))
-
-if __name__ == "__main__":
- from migen.fhdl import verilog
- from migen.sim.generic import run_simulation
-
- lfsr = LFSR(3, 4, [3, 2])
- print(verilog.convert(lfsr, ios={lfsr.ce, lfsr.reset, lfsr.o}))
-
- run_simulation(_LFSRTB(128), ncycles=20)
+++ /dev/null
-from misoc.spi.core import SPIMaster
+++ /dev/null
-from migen import *
-from migen.bank.description import *
-from migen.genlib.fsm import FSM, NextState
-
-
-class SPIMaster(Module, AutoCSR):
- def __init__(self, pads, width=24, div=2, cpha=1):
- self.pads = pads
-
- self._ctrl = CSR()
- self._length = CSRStorage(8)
- self._status = CSRStatus()
- if hasattr(pads, "mosi"):
- self._mosi = CSRStorage(width)
- if hasattr(pads, "miso"):
- self._miso = CSRStatus(width)
-
- self.irq = Signal()
-
- ###
-
- # ctrl
- start = Signal()
- length = self._length.storage
- enable_cs = Signal()
- enable_shift = Signal()
- done = Signal()
-
- self.comb += [
- start.eq(self._ctrl.re & self._ctrl.r[0]),
- self._status.status.eq(done)
- ]
-
- # clk
- i = Signal(max=div)
- set_clk = Signal()
- clr_clk = Signal()
- self.sync += [
- If(set_clk,
- pads.clk.eq(enable_cs)
- ),
- If(clr_clk,
- pads.clk.eq(0),
- i.eq(0)
- ).Else(
- i.eq(i + 1),
- )
- ]
-
- self.comb += [
- set_clk.eq(i == (div//2-1)),
- clr_clk.eq(i == (div-1))
- ]
-
- # fsm
- cnt = Signal(8)
- clr_cnt = Signal()
- inc_cnt = Signal()
- self.sync += \
- If(clr_cnt,
- cnt.eq(0)
- ).Elif(inc_cnt,
- cnt.eq(cnt+1)
- )
-
- fsm = FSM(reset_state="IDLE")
- self.submodules += fsm
- fsm.act("IDLE",
- If(start,
- NextState("WAIT_CLK")
- ),
- done.eq(1),
- clr_cnt.eq(1)
- )
- fsm.act("WAIT_CLK",
- If(clr_clk,
- NextState("SHIFT")
- ),
- )
- fsm.act("SHIFT",
- If(cnt == length,
- NextState("END")
- ).Else(
- inc_cnt.eq(clr_clk),
- ),
- enable_cs.eq(1),
- enable_shift.eq(1),
- )
- fsm.act("END",
- If(set_clk,
- NextState("IDLE")
- ),
- enable_shift.eq(1),
- self.irq.eq(1)
- )
-
- # miso
- if hasattr(pads, "miso"):
- miso = Signal()
- sr_miso = Signal(width)
-
- # (cpha = 1: capture on clk falling edge)
- if cpha:
- self.sync += \
- If(enable_shift,
- If(clr_clk,
- miso.eq(pads.miso),
- ).Elif(set_clk,
- sr_miso.eq(Cat(miso, sr_miso[:-1]))
- )
- )
- # (cpha = 0: capture on clk rising edge)
- else:
- self.sync += \
- If(enable_shift,
- If(set_clk,
- miso.eq(pads.miso),
- ).Elif(clr_clk,
- sr_miso.eq(Cat(miso, sr_miso[:-1]))
- )
- )
- self.comb += self._miso.status.eq(sr_miso)
-
- # mosi
- if hasattr(pads, "mosi"):
- sr_mosi = Signal(width)
-
- # (cpha = 1: propagated on clk rising edge)
- if cpha:
- self.sync += \
- If(start,
- sr_mosi.eq(self._mosi.storage)
- ).Elif(clr_clk & enable_shift,
- sr_mosi.eq(Cat(Signal(), sr_mosi[:-1]))
- ).Elif(set_clk,
- pads.mosi.eq(sr_mosi[-1])
- )
-
- # (cpha = 0: propagated on clk falling edge)
- else:
- self.sync += [
- If(start,
- sr_mosi.eq(self._mosi.storage)
- ).Elif(set_clk & enable_shift,
- sr_mosi.eq(Cat(Signal(), sr_mosi[:-1]))
- ).Elif(clr_clk,
- pads.mosi.eq(sr_mosi[-1])
- )
- ]
-
- # cs_n
- self.comb += pads.cs_n.eq(~enable_cs)
+++ /dev/null
-from migen import *
-from migen.genlib.record import *
-from migen.sim.generic import run_simulation
-
-from misoc.com.spi import SPIMaster
-
-
-class SPISlave(Module):
- def __init__(self, pads, width):
- self.pads = pads
- self.width = width
-
- ###
-
- self.mosi = 0
- self.miso = 0
-
- self.last_cs_n = 1
- self.last_clk = 0
-
-
- def get_mosi(self):
- return self.mosi
-
- def set_miso(self, value):
- self.miso = value
-
- def do_simulation(self, selfp):
- # detect edges
- cs_n_rising = 0
- cs_n_falling = 0
- clk_rising = 0
- clk_falling = 0
- if selfp.pads.cs_n and not self.last_cs_n:
- cs_n_rising = 1
- if not selfp.pads.cs_n and self.last_cs_n:
- cs_n_falling = 1
- if selfp.pads.clk and not self.last_clk:
- clk_rising = 1
- if not selfp.pads.clk and self.last_clk:
- clk_falling = 1
-
- # input mosi
- if clk_falling and not selfp.pads.cs_n:
- self.mosi = self.mosi << 1
- self.mosi |= selfp.pads.mosi
-
- # output miso
- if (clk_rising and not selfp.pads.cs_n):
- selfp.pads.miso = (self.miso >> (self.width-1)) & 0x1
- self.miso = self.miso << 1
-
- # save signal states
- self.last_cs_n = selfp.pads.cs_n
- self.last_clk = selfp.pads.clk
-
-
-def spi_access(selfp, length, mosi):
- selfp.spi_master._mosi.storage = mosi
- yield
- selfp.spi_master._ctrl.r = (length << 8) | 1
- selfp.spi_master._ctrl.re = 1
- yield
- selfp.spi_master._ctrl.r = 0
- selfp.spi_master._ctrl.re = 0
- yield
- while not (selfp.spi_master._status.status & 0x1):
- yield
-
-
-class TB(Module):
- def __init__(self):
- pads = Record([("cs_n", 1), ("clk", 1), ("mosi", 1), ("miso", 1)])
- self.submodules.spi_master = SPIMaster(pads, 24, 4)
- self.submodules.spi_slave = SPISlave(pads, 24)
-
- def gen_simulation(self, selfp):
- for i in range(16):
- yield
- self.spi_slave.set_miso(0x123457)
- yield from spi_access(selfp, 8, 0x123457)
- print("{:08x}".format(self.spi_slave.get_mosi()))
- print("{:08x}".format(selfp.spi_master._miso.status))
-
-if __name__ == "__main__":
- run_simulation(TB(), ncycles=1000, vcd_name="my.vcd", keep_files=True)
+++ /dev/null
-from migen import *
-from migen.genlib.misc import timeline
-
-from misoc.interconnect import wishbone
-from misoc.interconnect.csr import AutoCSR, CSRStorage, CSRStatus
-
-
-_FAST_READ = 0x0b
-_DIOFR = 0xbb
-_QIOFR = 0xeb
-
-
-def _format_cmd(cmd, spi_width):
- """
- `cmd` is the read instruction. Since everything is transmitted on all
- dq lines (cmd, adr and data), extend/interleave cmd to full pads.dq
- width even if dq1-dq3 are don't care during the command phase:
- For example, for N25Q128, 0xeb is the quad i/o fast read, and
- extended to 4 bits (dq1,dq2,dq3 high) is: 0xfffefeff
- """
- c = 2**(8*spi_width)-1
- for b in range(8):
- if not (cmd>>b)%2:
- c &= ~(1<<(b*spi_width))
- return c
-
-
-class SpiFlash(Module, AutoCSR):
- def __init__(self, pads, dummy=15, div=2, with_bitbang=True):
- """
- Simple SPI flash, e.g. N25Q128 on the LX9 Microboard.
-
- Supports multi-bit pseudo-parallel reads (aka Dual or Quad I/O Fast
- Read). Only supports mode0 (cpol=0, cpha=0).
- Optionally supports software bitbanging (for write, erase, or other commands).
- """
- self.bus = bus = wishbone.Interface()
- spi_width = len(pads.dq)
- if with_bitbang:
- self.bitbang = CSRStorage(4)
- self.miso = CSRStatus()
- self.bitbang_en = CSRStorage()
-
- ###
-
- cs_n = Signal(reset=1)
- clk = Signal()
- dq_oe = Signal()
- wbone_width = len(bus.dat_r)
-
-
- read_cmd_params = {
- 4: (_format_cmd(_QIOFR, 4), 4*8),
- 2: (_format_cmd(_DIOFR, 2), 2*8),
- 1: (_format_cmd(_FAST_READ, 1), 1*8)
- }
- read_cmd, cmd_width = read_cmd_params[spi_width]
- addr_width = 24
-
- pads.cs_n.reset = 1
-
- dq = TSTriple(spi_width)
- self.specials.dq = dq.get_tristate(pads.dq)
-
- sr = Signal(max(cmd_width, addr_width, wbone_width))
- dqs = Replicate(1, spi_width-1)
-
- self.comb += bus.dat_r.eq(sr)
-
- hw_read_logic = [
- pads.clk.eq(clk),
- pads.cs_n.eq(cs_n),
- dq.o.eq(sr[-spi_width:]),
- dq.oe.eq(dq_oe)
- ]
-
- if with_bitbang:
- bitbang_logic = [
- pads.clk.eq(self.bitbang.storage[1]),
- pads.cs_n.eq(self.bitbang.storage[2]),
- dq.o.eq(Cat(self.bitbang.storage[0], dqs)),
- If(self.bitbang.storage[3],
- dq.oe.eq(0)
- ).Else(
- dq.oe.eq(1)
- ),
- If(self.bitbang.storage[1],
- self.miso.status.eq(dq.i[1])
- )
- ]
-
- self.comb += \
- If(self.bitbang_en.storage,
- bitbang_logic
- ).Else(
- hw_read_logic
- )
- else:
- self.comb += hw_read_logic
-
- if div < 2:
- raise ValueError("Unsupported value \'{}\' for div parameter for SpiFlash core".format(div))
- else:
- i = Signal(max=div)
- dqi = Signal(spi_width)
- self.sync += [
- If(i == div//2 - 1,
- clk.eq(1),
- dqi.eq(dq.i),
- ),
- If(i == div - 1,
- i.eq(0),
- clk.eq(0),
- sr.eq(Cat(dqi, sr[:-spi_width]))
- ).Else(
- i.eq(i + 1),
- ),
- ]
-
- # spi is byte-addressed, prefix by zeros
- z = Replicate(0, log2_int(wbone_width//8))
-
- seq = [
- (cmd_width//spi_width*div,
- [dq_oe.eq(1), cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]),
- (addr_width//spi_width*div,
- [sr[-addr_width:].eq(Cat(z, bus.adr))]),
- ((dummy + wbone_width//spi_width)*div,
- [dq_oe.eq(0)]),
- (1,
- [bus.ack.eq(1), cs_n.eq(1)]),
- (div, # tSHSL!
- [bus.ack.eq(0)]),
- (0,
- []),
- ]
-
- # accumulate timeline deltas
- t, tseq = 0, []
- for dt, a in seq:
- tseq.append((t, a))
- t += dt
-
- self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq)
+++ /dev/null
-from migen import *
-
-from misoc.interconnect.csr import *
-from misoc.interconnect.csr_eventmanager import *
-
-
-class Timer(Module, AutoCSR):
- def __init__(self, width=32):
- self._load = CSRStorage(width)
- self._reload = CSRStorage(width)
- self._en = CSRStorage()
- self._update_value = CSR()
- self._value = CSRStatus(width)
-
- self.submodules.ev = EventManager()
- self.ev.zero = EventSourceProcess()
- self.ev.finalize()
-
- ###
-
- value = Signal(width)
- self.sync += [
- If(self._en.storage,
- If(value == 0,
- # set reload to 0 to disable reloading
- value.eq(self._reload.storage)
- ).Else(
- value.eq(value - 1)
- )
- ).Else(
- value.eq(self._load.storage)
- ),
- If(self._update_value.re, self._value.status.eq(value))
- ]
- self.comb += self.ev.zero.trigger.eq(value != 0)
+++ /dev/null
-from misoc.cores.uart.core import UART, RS232PHY
+++ /dev/null
-from migen import *
-from migen.genlib.record import Record
-from migen.genlib.cdc import MultiReg
-
-from misoc.interconnect.csr import *
-from misoc.interconnect.csr_eventmanager import *
-from misoc.interconnect.stream import Source, Sink, SyncFIFO, AsyncFIFO
-
-
-class RS232PHYRX(Module):
- def __init__(self, pads, tuning_word):
- self.source = Source([("data", 8)])
-
- # # #
-
- uart_clk_rxen = Signal()
- phase_accumulator_rx = Signal(32)
-
- rx = Signal()
- self.specials += MultiReg(pads.rx, rx)
- rx_r = Signal()
- rx_reg = Signal(8)
- rx_bitcount = Signal(4)
- rx_busy = Signal()
- rx_done = self.source.stb
- rx_data = self.source.data
- self.sync += [
- rx_done.eq(0),
- rx_r.eq(rx),
- If(~rx_busy,
- If(~rx & rx_r, # look for start bit
- rx_busy.eq(1),
- rx_bitcount.eq(0),
- )
- ).Else(
- If(uart_clk_rxen,
- rx_bitcount.eq(rx_bitcount + 1),
- If(rx_bitcount == 0,
- If(rx, # verify start bit
- rx_busy.eq(0)
- )
- ).Elif(rx_bitcount == 9,
- rx_busy.eq(0),
- If(rx, # verify stop bit
- rx_data.eq(rx_reg),
- rx_done.eq(1)
- )
- ).Else(
- rx_reg.eq(Cat(rx_reg[1:], rx))
- )
- )
- )
- ]
- self.sync += \
- If(rx_busy,
- Cat(phase_accumulator_rx, uart_clk_rxen).eq(phase_accumulator_rx + tuning_word)
- ).Else(
- Cat(phase_accumulator_rx, uart_clk_rxen).eq(2**31)
- )
-
-
-class RS232PHYTX(Module):
- def __init__(self, pads, tuning_word):
- self.sink = Sink([("data", 8)])
-
- # # #
-
- uart_clk_txen = Signal()
- phase_accumulator_tx = Signal(32)
-
- pads.tx.reset = 1
-
- tx_reg = Signal(8)
- tx_bitcount = Signal(4)
- tx_busy = Signal()
- self.sync += [
- self.sink.ack.eq(0),
- If(self.sink.stb & ~tx_busy & ~self.sink.ack,
- tx_reg.eq(self.sink.data),
- tx_bitcount.eq(0),
- tx_busy.eq(1),
- pads.tx.eq(0)
- ).Elif(uart_clk_txen & tx_busy,
- tx_bitcount.eq(tx_bitcount + 1),
- If(tx_bitcount == 8,
- pads.tx.eq(1)
- ).Elif(tx_bitcount == 9,
- pads.tx.eq(1),
- tx_busy.eq(0),
- self.sink.ack.eq(1),
- ).Else(
- pads.tx.eq(tx_reg[0]),
- tx_reg.eq(Cat(tx_reg[1:], 0))
- )
- )
- ]
- self.sync += [
- If(tx_busy,
- Cat(phase_accumulator_tx, uart_clk_txen).eq(phase_accumulator_tx + tuning_word)
- ).Else(
- Cat(phase_accumulator_tx, uart_clk_txen).eq(0)
- )
- ]
-
-
-class RS232PHY(Module, AutoCSR):
- def __init__(self, pads, clk_freq, baudrate=115200):
- self._tuning_word = CSRStorage(32, reset=int((baudrate/clk_freq)*2**32))
- self.submodules.tx = RS232PHYTX(pads, self._tuning_word.storage)
- self.submodules.rx = RS232PHYRX(pads, self._tuning_word.storage)
- self.sink, self.source = self.tx.sink, self.rx.source
-
-
-def _get_uart_fifo(depth, sink_cd="sys", source_cd="sys"):
- if sink_cd != source_cd:
- fifo = AsyncFIFO([("data", 8)], depth)
- return ClockDomainsRenamer({"write": sink_cd, "read": source_cd})(fifo)
- else:
- return SyncFIFO([("data", 8)], depth)
-
-
-class UART(Module, AutoCSR):
- def __init__(self, phy,
- tx_fifo_depth=16,
- rx_fifo_depth=16,
- phy_cd="sys"):
- self._rxtx = CSR(8)
- self._txfull = CSRStatus()
- self._rxempty = CSRStatus()
-
- self.submodules.ev = EventManager()
- self.ev.tx = EventSourceProcess()
- self.ev.rx = EventSourceProcess()
- self.ev.finalize()
-
- # # #
-
- # TX
- tx_fifo = _get_uart_fifo(tx_fifo_depth, source_cd=phy_cd)
- self.submodules += tx_fifo
-
- self.comb += [
- tx_fifo.sink.stb.eq(self._rxtx.re),
- tx_fifo.sink.data.eq(self._rxtx.r),
- self._txfull.status.eq(~tx_fifo.sink.ack),
- Record.connect(tx_fifo.source, phy.sink),
- # Generate TX IRQ when tx_fifo becomes non-full
- self.ev.tx.trigger.eq(~tx_fifo.sink.ack)
- ]
-
- # RX
- rx_fifo = _get_uart_fifo(rx_fifo_depth, sink_cd=phy_cd)
- self.submodules += rx_fifo
-
- self.comb += [
- Record.connect(phy.source, rx_fifo.sink),
- self._rxempty.status.eq(~rx_fifo.source.stb),
- self._rxtx.w.eq(rx_fifo.source.data),
- rx_fifo.source.ack.eq(self.ev.rx.clear),
- # Generate RX IRQ when tx_fifo becomes non-empty
- self.ev.rx.trigger.eq(~rx_fifo.source.stb)
- ]
+++ /dev/null
-# XXX Adapt test to new architecture
-class UARTTB(Module):
- def __init__(self):
- self.clk_freq = 83333333
- self.baud = 3000000
- self.pads = Record([("rx", 1), ("tx", 1)])
- self.submodules.slave = UART(self.pads, self.clk_freq, self.baud)
-
- def wait_for(self, ns_time):
- freq_in_ghz = self.clk_freq/(10**9)
- period = 1/freq_in_ghz
- num_loops = int(ns_time/period)
- for i in range(num_loops+1):
- yield
-
- def gen_simulation(self, selfp):
- baud_in_ghz = self.baud/(10**9)
- uart_period = int(1/baud_in_ghz)
- half_uart_period = int(1/(2*baud_in_ghz))
-
- # Set TX an RX lines idle
- selfp.pads.tx = 1
- selfp.pads.rx = 1
- yield
-
- # First send a few characters
-
- tx_string = "01234"
- print("Sending string: " + tx_string)
- for c in tx_string:
- selfp.slave._r_rxtx.r = ord(c)
- selfp.slave._r_rxtx.re = 1
- yield
- selfp.slave._r_rxtx.re = 0
-
- yield from self.wait_for(half_uart_period)
-
- if selfp.pads.tx:
- print("FAILURE: no start bit sent")
-
- val = 0
- for i in range(8):
- yield from self.wait_for(uart_period)
- val >>= 1
- if selfp.pads.tx:
- val |= 0x80
-
- yield from self.wait_for(uart_period)
-
- if selfp.pads.tx == 0:
- print("FAILURE: no stop bit sent")
-
- if ord(c) != val:
- print("FAILURE: sent decimal value "+str(val)+" (char "+chr(val)+") instead of "+c)
- else:
- print("SUCCESS: sent "+c)
- while selfp.slave.ev.tx.trigger != 1:
- yield
-
- # Then receive a character
-
- rx_string = '5'
- print("Receiving character "+rx_string)
- rx_value = ord(rx_string)
- for i in range(11):
- if (i == 0):
- # start bit
- selfp.pads.rx = 0
- elif (i == 9):
- # stop bit
- selfp.pads.rx = 1
- elif (i == 10):
- selfp.pads.rx = 1
- break
- else:
- selfp.pads.rx = 1 if (rx_value & 1) else 0
- rx_value >>= 1
- yield from self.wait_for(uart_period)
-
- rx_value = ord(rx_string)
- received_value = selfp.slave._r_rxtx.w
- if (received_value == rx_value):
- print("RX SUCCESS: ")
- else:
- print("RX FAILURE: ")
-
- print("received "+chr(received_value))
-
- while True:
- yield
-
-if __name__ == "__main__":
- from migen.sim.generic import Simulator, TopLevel
- from migen.sim import icarus
- with Simulator(UARTTB(), TopLevel("top.vcd", clk_period=int(1/0.08333333)),
- icarus.Runner(keep_files=False)) as s:
- s.run(20000)
+++ /dev/null
-from misoc.integration.soc_core import SoCCore
-from misoc.integration.soc_sdram import SoCSDRAM
+++ /dev/null
-import os
-import subprocess
-import struct
-
-from misoc.integration import cpu_interface, soc_sdram, sdram_init
-
-
-__all__ = ["misoc_software_packages", "misoc_directory",
- "Builder", "builder_args", "builder_argdict"]
-
-
-# in build order (for dependencies)
-misoc_software_packages = [
- "libbase",
- "libcompiler_rt",
- "libdyld",
- "libnet",
- "libunwind",
- "bios"
-]
-
-
-misoc_directory = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
-
-
-def _makefile_escape(s):
- return s.replace("\\", "\\\\")
-
-
-class Builder:
- def __init__(self, soc, output_dir=None,
- compile_software=True, compile_gateware=True,
- gateware_toolchain_path=None,
- csr_csv=None):
- self.soc = soc
- if output_dir is None:
- output_dir = "misoc_{}_{}".format(
- soc.__class__.__name__.lower(),
- soc.platform.name)
- # From Python doc: makedirs() will become confused if the path
- # elements to create include '..'
- self.output_dir = os.path.abspath(output_dir)
- self.compile_software = compile_software
- self.compile_gateware = compile_gateware
- self.gateware_toolchain_path = gateware_toolchain_path
- self.csr_csv = csr_csv
-
- self.software_packages = []
- for name in misoc_software_packages:
- self.add_software_package(
- name, os.path.join(misoc_directory, "software", name))
-
- def add_software_package(self, name, src_dir):
- self.software_packages.append((name, src_dir))
-
- def _generate_includes(self):
- cpu_type = self.soc.cpu_type
- memory_regions = self.soc.get_memory_regions()
- flash_boot_address = getattr(self.soc, "flash_boot_address", None)
- csr_regions = self.soc.get_csr_regions()
- constants = self.soc.get_constants()
- if isinstance(self.soc, soc_sdram.SoCSDRAM) and self.soc._sdram_phy:
- sdram_phy_settings = self.soc._sdram_phy[0].settings
- else:
- sdram_phy_settings = None
-
- buildinc_dir = os.path.join(self.output_dir, "software", "include")
- generated_dir = os.path.join(buildinc_dir, "generated")
- os.makedirs(generated_dir, exist_ok=True)
- with open(os.path.join(generated_dir, "variables.mak"), "w") as f:
- def define(k, v):
- f.write("{}={}\n".format(k, _makefile_escape(v)))
- for k, v in cpu_interface.get_cpu_mak(cpu_type):
- define(k, v)
- define("MISOC_DIRECTORY", misoc_directory)
- define("BUILDINC_DIRECTORY", buildinc_dir)
- for name, src_dir in self.software_packages:
- define(name.upper() + "_DIRECTORY", src_dir)
-
- with open(os.path.join(generated_dir, "output_format.ld"), "w") as f:
- f.write(cpu_interface.get_linker_output_format(cpu_type))
- with open(os.path.join(generated_dir, "regions.ld"), "w") as f:
- f.write(cpu_interface.get_linker_regions(memory_regions))
-
- with open(os.path.join(generated_dir, "mem.h"), "w") as f:
- f.write(cpu_interface.get_mem_header(memory_regions, flash_boot_address))
- with open(os.path.join(generated_dir, "csr.h"), "w") as f:
- f.write(cpu_interface.get_csr_header(csr_regions, constants))
-
- if sdram_phy_settings is not None:
- with open(os.path.join(generated_dir, "sdram_phy.h"), "w") as f:
- f.write(sdram_init.get_sdram_phy_header(sdram_phy_settings))
-
- if self.csr_csv is not None:
- with open(self.csr_csv, "w") as f:
- f.write(cpu_interface.get_csr_csv(csr_regions))
-
- def _generate_software(self):
- for name, src_dir in self.software_packages:
- dst_dir = os.path.join(self.output_dir, "software", name)
- os.makedirs(dst_dir, exist_ok=True)
- src = os.path.join(src_dir, "Makefile")
- dst = os.path.join(dst_dir, "Makefile")
- try:
- os.remove(dst)
- except FileNotFoundError:
- pass
- os.symlink(src, dst)
- if self.compile_software:
- subprocess.check_call(["make", "-C", dst_dir])
-
- def _initialize_rom(self):
- bios_file = os.path.join(self.output_dir, "software", "bios",
- "bios.bin")
- if self.soc.integrated_rom_size:
- with open(bios_file, "rb") as boot_file:
- boot_data = []
- while True:
- w = boot_file.read(4)
- if not w:
- break
- boot_data.append(struct.unpack(">I", w)[0])
- self.soc.initialize_rom(boot_data)
-
- def build(self):
- self.soc.finalize()
-
- if self.soc.integrated_rom_size and not self.compile_software:
- raise ValueError("Software must be compiled in order to "
- "intitialize integrated ROM")
-
- self._generate_includes()
- self._generate_software()
- self._initialize_rom()
- if self.gateware_toolchain_path is None:
- kwargs = dict()
- else:
- kwargs = {"toolchain_path": self.gateware_toolchain_path}
- self.soc.build(build_dir=os.path.join(self.output_dir, "gateware"),
- run=self.compile_gateware, **kwargs)
-
-
-def builder_args(parser):
- parser.add_argument("--output-dir", default=None,
- help="output directory for generated "
- "source files and binaries")
- parser.add_argument("--no-compile-software", action="store_true",
- help="do not compile the software, only generate "
- "build infrastructure")
- parser.add_argument("--no-compile-gateware", action="store_true",
- help="do not compile the gateware, only generate "
- "HDL source files and build scripts")
- parser.add_argument("--gateware-toolchain-path", default=None,
- help="set gateware toolchain (ISE, Quartus, etc.) "
- "installation path")
- parser.add_argument("--csr-csv", default=None,
- help="store CSR map in CSV format into the "
- "specified file")
-
-
-def builder_argdict(args):
- return {
- "output_dir": args.output_dir,
- "compile_software": not args.no_compile_software,
- "compile_gateware": not args.no_compile_gateware,
- "gateware_toolchain_path": args.gateware_toolchain_path,
- "csr_csv": args.csr_csv
- }
+++ /dev/null
-from migen import *
-
-from misoc.interconnect.csr import CSRStatus
-
-
-def get_cpu_mak(cpu):
- if cpu == "lm32":
- triple = "lm32-elf"
- cpuflags = "-mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled"
- clang = ""
- elif cpu == "or1k":
- triple = "or1k-linux"
- cpuflags = "-mhard-mul -mhard-div -mror -mffl1 -maddc"
- clang = "1"
- else:
- raise ValueError("Unsupported CPU type: "+cpu)
- return [
- ("TRIPLE", triple),
- ("CPU", cpu),
- ("CPUFLAGS", cpuflags),
- ("CLANG", clang)
- ]
-
-
-def get_linker_output_format(cpu_type):
- return "OUTPUT_FORMAT(\"elf32-{}\")\n".format(cpu_type)
-
-
-def get_linker_regions(regions):
- r = "MEMORY {\n"
- for name, origin, length in regions:
- r += "\t{} : ORIGIN = 0x{:08x}, LENGTH = 0x{:08x}\n".format(name, origin, length)
- r += "}\n"
- return r
-
-
-def get_mem_header(regions, flash_boot_address):
- r = "#ifndef __GENERATED_MEM_H\n#define __GENERATED_MEM_H\n\n"
- for name, base, size in regions:
- r += "#define {name}_BASE 0x{base:08x}\n#define {name}_SIZE 0x{size:08x}\n\n".format(name=name.upper(), base=base, size=size)
- if flash_boot_address is not None:
- r += "#define FLASH_BOOT_ADDRESS 0x{:08x}\n\n".format(flash_boot_address)
- r += "#endif\n"
- return r
-
-
-def _get_rw_functions(reg_name, reg_base, nwords, busword, read_only, with_access_functions):
- r = ""
-
- r += "#define CSR_"+reg_name.upper()+"_ADDR "+hex(reg_base)+"\n"
- r += "#define CSR_"+reg_name.upper()+"_SIZE "+str(nwords)+"\n"
-
- size = nwords*busword
- if size > 64:
- return r
- elif size > 32:
- ctype = "unsigned long long int"
- elif size > 16:
- ctype = "unsigned int"
- elif size > 8:
- ctype = "unsigned short int"
- else:
- ctype = "unsigned char"
-
- if with_access_functions:
- r += "static inline "+ctype+" "+reg_name+"_read(void) {\n"
- if size > 1:
- r += "\t"+ctype+" r = MMPTR("+hex(reg_base)+");\n"
- for byte in range(1, nwords):
- r += "\tr <<= "+str(busword)+";\n\tr |= MMPTR("+hex(reg_base+4*byte)+");\n"
- r += "\treturn r;\n}\n"
- else:
- r += "\treturn MMPTR("+hex(reg_base)+");\n}\n"
-
- if not read_only:
- r += "static inline void "+reg_name+"_write("+ctype+" value) {\n"
- for word in range(nwords):
- shift = (nwords-word-1)*busword
- if shift:
- value_shifted = "value >> "+str(shift)
- else:
- value_shifted = "value"
- r += "\tMMPTR("+hex(reg_base+4*word)+") = "+value_shifted+";\n"
- r += "}\n"
- return r
-
-
-def get_csr_header(regions, constants, with_access_functions=True):
- r = "#ifndef __GENERATED_CSR_H\n#define __GENERATED_CSR_H\n"
- if with_access_functions:
- r += "#include <hw/common.h>\n"
- for name, origin, busword, obj in regions:
- if isinstance(obj, Memory):
- r += "#define CSR_"+name.upper()+"_BASE "+hex(origin)+"\n"
- else:
- r += "\n/* "+name+" */\n"
- r += "#define CSR_"+name.upper()+"_BASE "+hex(origin)+"\n"
- for csr in obj:
- nr = (csr.size + busword - 1)//busword
- r += _get_rw_functions(name + "_" + csr.name, origin, nr, busword, isinstance(csr, CSRStatus), with_access_functions)
- origin += 4*nr
-
- r += "\n/* constants */\n"
- for name, value in constants:
- r += "#define " + name
- if value is not None:
- if isinstance(value, str):
- r += " \"" + value + "\""
- else:
- r += " " + str(value)
- r += "\n"
-
- r += "\n#endif\n"
- return r
-
-
-def get_csr_csv(regions):
- r = ""
- for name, origin, busword, obj in regions:
- if not isinstance(obj, Memory):
- for csr in obj:
- nr = (csr.size + busword - 1)//busword
- r += "{}_{},0x{:08x},{},{}\n".format(name, csr.name, origin, nr, "ro" if isinstance(csr, CSRStatus) else "rw")
- origin += 4*nr
- return r
+++ /dev/null
-from migen import log2_int
-
-
-def get_sdram_phy_header(sdram_phy_settings):
- r = "#ifndef __GENERATED_SDRAM_PHY_H\n#define __GENERATED_SDRAM_PHY_H\n"
- r += "#include <hw/common.h>\n#include <generated/csr.h>\n#include <hw/flags.h>\n\n"
-
- nphases = sdram_phy_settings.nphases
- r += "#define DFII_NPHASES "+str(nphases)+"\n\n"
-
- r += "static void cdelay(int i);\n"
-
- # commands_px functions
- for n in range(nphases):
- r += """
-static void command_p{n}(int cmd)
-{{
- sdram_dfii_pi{n}_command_write(cmd);
- sdram_dfii_pi{n}_command_issue_write(1);
-}}""".format(n=str(n))
- r += "\n\n"
-
- # rd/wr access macros
- r += """
-#define sdram_dfii_pird_address_write(X) sdram_dfii_pi{rdphase}_address_write(X)
-#define sdram_dfii_piwr_address_write(X) sdram_dfii_pi{wrphase}_address_write(X)
-
-#define sdram_dfii_pird_baddress_write(X) sdram_dfii_pi{rdphase}_baddress_write(X)
-#define sdram_dfii_piwr_baddress_write(X) sdram_dfii_pi{wrphase}_baddress_write(X)
-
-#define command_prd(X) command_p{rdphase}(X)
-#define command_pwr(X) command_p{wrphase}(X)
-""".format(rdphase=str(sdram_phy_settings.rdphase), wrphase=str(sdram_phy_settings.wrphase))
- r += "\n"
-
- #
- # sdrrd/sdrwr functions utilities
- #
- r += "#define DFII_PIX_DATA_SIZE CSR_SDRAM_DFII_PI0_WRDATA_SIZE\n"
- sdram_dfii_pix_wrdata_addr = []
- for n in range(nphases):
- sdram_dfii_pix_wrdata_addr.append("CSR_SDRAM_DFII_PI{n}_WRDATA_ADDR".format(n=n))
- r += """
-const unsigned int sdram_dfii_pix_wrdata_addr[{n}] = {{
- {sdram_dfii_pix_wrdata_addr}
-}};
-""".format(n=nphases, sdram_dfii_pix_wrdata_addr=",\n\t".join(sdram_dfii_pix_wrdata_addr))
-
- sdram_dfii_pix_rddata_addr = []
- for n in range(nphases):
- sdram_dfii_pix_rddata_addr.append("CSR_SDRAM_DFII_PI{n}_RDDATA_ADDR".format(n=n))
- r += """
-const unsigned int sdram_dfii_pix_rddata_addr[{n}] = {{
- {sdram_dfii_pix_rddata_addr}
-}};
-""".format(n=nphases, sdram_dfii_pix_rddata_addr=",\n\t".join(sdram_dfii_pix_rddata_addr))
- r += "\n"
-
- # init sequence
- cmds = {
- "PRECHARGE_ALL": "DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
- "MODE_REGISTER": "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
- "AUTO_REFRESH": "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS",
- "UNRESET": "DFII_CONTROL_ODT|DFII_CONTROL_RESET_N",
- "CKE": "DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N"
- }
-
- cl = sdram_phy_settings.cl
-
- if sdram_phy_settings.memtype == "SDR":
- bl = sdram_phy_settings.nphases
- mr = log2_int(bl) + (cl << 4)
- reset_dll = 1 << 8
-
- init_sequence = [
- ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
- ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
- ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
- ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
- ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
- ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
- ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
- ]
-
- elif sdram_phy_settings.memtype == "DDR":
- bl = 2*sdram_phy_settings.nphases
- mr = log2_int(bl) + (cl << 4)
- emr = 0
- reset_dll = 1 << 8
-
- init_sequence = [
- ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
- ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
- ("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
- ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
- ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
- ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
- ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
- ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
- ]
-
- elif sdram_phy_settings.memtype == "LPDDR":
- bl = 2*sdram_phy_settings.nphases
- mr = log2_int(bl) + (cl << 4)
- emr = 0
- reset_dll = 1 << 8
-
- init_sequence = [
- ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
- ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
- ("Load Extended Mode Register", emr, 2, cmds["MODE_REGISTER"], 0),
- ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
- ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
- ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
- ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
- ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
- ]
-
- elif sdram_phy_settings.memtype == "DDR2":
- bl = 2*sdram_phy_settings.nphases
- wr = 2
- mr = log2_int(bl) + (cl << 4) + (wr << 9)
- emr = 0
- emr2 = 0
- emr3 = 0
- reset_dll = 1 << 8
- ocd = 7 << 7
-
- init_sequence = [
- ("Bring CKE high", 0x0000, 0, cmds["CKE"], 20000),
- ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
- ("Load Extended Mode Register 3", emr3, 3, cmds["MODE_REGISTER"], 0),
- ("Load Extended Mode Register 2", emr2, 2, cmds["MODE_REGISTER"], 0),
- ("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
- ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
- ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
- ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
- ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
- ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200),
- ("Load Extended Mode Register / OCD Default", emr+ocd, 1, cmds["MODE_REGISTER"], 0),
- ("Load Extended Mode Register / OCD Exit", emr, 1, cmds["MODE_REGISTER"], 0),
- ]
- elif sdram_phy_settings.memtype == "DDR3":
- bl = 2*sdram_phy_settings.nphases
-
- def format_mr0(bl, cl, wr, dll_reset):
- bl_to_mr0 = {
- 4: 0b10,
- 8: 0b00
- }
- cl_to_mr0 = {
- 5: 0b0010,
- 6: 0b0100,
- 7: 0b0110,
- 8: 0b1000,
- 9: 0b1010,
- 10: 0b1100,
- 11: 0b1110,
- 12: 0b0001,
- 13: 0b0011,
- 14: 0b0101
- }
- wr_to_mr0 = {
- 16: 0b000,
- 5: 0b001,
- 6: 0b010,
- 7: 0b011,
- 8: 0b100,
- 10: 0b101,
- 12: 0b110,
- 14: 0b111
- }
- mr0 = bl_to_mr0[bl]
- mr0 |= (cl_to_mr0[cl] & 1) << 2
- mr0 |= ((cl_to_mr0[cl] >> 1) & 0b111) << 4
- mr0 |= dll_reset << 8
- mr0 |= wr_to_mr0[wr] << 9
- return mr0
-
- def format_mr1(output_drive_strength, rtt_nom):
- mr1 = ((output_drive_strength >> 0) & 1) << 1
- mr1 |= ((output_drive_strength >> 1) & 1) << 5
- mr1 |= ((rtt_nom >> 0) & 1) << 2
- mr1 |= ((rtt_nom >> 1) & 1) << 6
- mr1 |= ((rtt_nom >> 2) & 1) << 9
- return mr1
-
- def format_mr2(cwl, rtt_wr):
- mr2 = (cwl-5) << 3
- mr2 |= rtt_wr << 9
- return mr2
-
- mr0 = format_mr0(bl, cl, 8, 1) # wr=8 FIXME: this should be ceiling(tWR/tCK)
- mr1 = format_mr1(1, 1) # Output Drive Strength RZQ/7 (34 ohm) / Rtt RZQ/4 (60 ohm)
- mr2 = format_mr2(sdram_phy_settings.cwl, 2) # Rtt(WR) RZQ/4
- mr3 = 0
-
- init_sequence = [
- ("Release reset", 0x0000, 0, cmds["UNRESET"], 50000),
- ("Bring CKE high", 0x0000, 0, cmds["CKE"], 10000),
- ("Load Mode Register 2", mr2, 2, cmds["MODE_REGISTER"], 0),
- ("Load Mode Register 3", mr3, 3, cmds["MODE_REGISTER"], 0),
- ("Load Mode Register 1", mr1, 1, cmds["MODE_REGISTER"], 0),
- ("Load Mode Register 0, CL={0:d}, BL={1:d}".format(cl, bl), mr0, 0, cmds["MODE_REGISTER"], 200),
- ("ZQ Calibration", 0x0400, 0, "DFII_COMMAND_WE|DFII_COMMAND_CS", 200),
- ]
-
- # the value of MR1 needs to be modified during write leveling
- r += "#define DDR3_MR1 {}\n\n".format(mr1)
- else:
- raise NotImplementedError("Unsupported memory type: "+sdram_phy_settings.memtype)
-
- r += "static void init_sequence(void)\n{\n"
- for comment, a, ba, cmd, delay in init_sequence:
- r += "\t/* {0} */\n".format(comment)
- r += "\tsdram_dfii_pi0_address_write({0:#x});\n".format(a)
- r += "\tsdram_dfii_pi0_baddress_write({0:d});\n".format(ba)
- if cmd[:12] == "DFII_CONTROL":
- r += "\tsdram_dfii_control_write({0});\n".format(cmd)
- else:
- r += "\tcommand_p0({0});\n".format(cmd)
- if delay:
- r += "\tcdelay({0:d});\n".format(delay)
- r += "\n"
- r += "}\n"
-
- r += "#endif\n"
-
- return r
+++ /dev/null
-from operator import itemgetter
-
-from migen import *
-
-from misoc.cores import lm32, mor1kx, identifier, timer, uart
-from misoc.interconnect import wishbone, csr_bus, wishbone2csr
-
-
-__all__ = ["mem_decoder", "SoCCore", "soc_core_args", "soc_core_argdict"]
-
-
-def mem_decoder(address, start=26, end=29):
- return lambda a: a[start:end] == ((address >> (start+2)) & (2**(end-start))-1)
-
-
-class SoCCore(Module):
- csr_map = {
- "crg": 0, # user
- "uart_phy": 1, # provided by default (optional)
- "uart": 2, # provided by default (optional)
- "identifier": 3, # provided by default (optional)
- "timer0": 4, # provided by default (optional)
- "buttons": 5, # user
- "leds": 6, # user
- }
- interrupt_map = {
- "uart": 0,
- "timer0": 1,
- }
- mem_map = {
- "rom": 0x00000000, # (default shadow @0x80000000)
- "sram": 0x10000000, # (default shadow @0x90000000)
- "main_ram": 0x40000000, # (default shadow @0xc0000000)
- "csr": 0x60000000, # (default shadow @0xe0000000)
- }
- def __init__(self, platform, clk_freq,
- cpu_type="lm32", cpu_reset_address=0x00000000,
- integrated_rom_size=0,
- integrated_sram_size=4096,
- integrated_main_ram_size=0,
- shadow_base=0x80000000,
- csr_data_width=8, csr_address_width=14,
- with_uart=True, uart_baudrate=115200,
- with_identifier=True,
- with_timer=True):
- self.platform = platform
- self.clk_freq = clk_freq
-
- self.cpu_type = cpu_type
- if integrated_rom_size:
- cpu_reset_address = 0
- self.cpu_reset_address = cpu_reset_address
-
- self.integrated_rom_size = integrated_rom_size
- self.integrated_sram_size = integrated_sram_size
- self.integrated_main_ram_size = integrated_main_ram_size
-
- self.with_uart = with_uart
- self.uart_baudrate = uart_baudrate
-
- self.with_identifier = with_identifier
-
- self.shadow_base = shadow_base
-
- self.csr_data_width = csr_data_width
- self.csr_address_width = csr_address_width
-
- self._memory_regions = [] # list of (name, origin, length)
- self._csr_regions = [] # list of (name, origin, busword, csr_list/Memory)
- self._constants = [] # list of (name, value)
-
- self._wb_masters = []
- self._wb_slaves = []
-
- if cpu_type == "lm32":
- self.submodules.cpu = lm32.LM32(platform, self.cpu_reset_address)
- elif cpu_type == "or1k":
- self.submodules.cpu = mor1kx.MOR1KX(platform, self.cpu_reset_address)
- else:
- raise ValueError("Unsupported CPU type: {}".format(cpu_type))
- self.add_wb_master(self.cpu.ibus)
- self.add_wb_master(self.cpu.dbus)
-
- if integrated_rom_size:
- self.submodules.rom = wishbone.SRAM(integrated_rom_size, read_only=True)
- self.register_rom(self.rom.bus, integrated_rom_size)
-
- if integrated_sram_size:
- self.submodules.sram = wishbone.SRAM(integrated_sram_size)
- self.register_mem("sram", self.mem_map["sram"], self.sram.bus, integrated_sram_size)
-
- # Note: Main Ram can be used when no external SDRAM is available and use SDRAM mapping.
- if integrated_main_ram_size:
- self.submodules.main_ram = wishbone.SRAM(integrated_main_ram_size)
- self.register_mem("main_ram", self.mem_map["main_ram"], self.main_ram.bus, integrated_main_ram_size)
-
- self.submodules.wishbone2csr = wishbone2csr.WB2CSR(
- bus_csr=csr_bus.Interface(csr_data_width, csr_address_width))
- self.register_mem("csr", self.mem_map["csr"], self.wishbone2csr.wishbone)
-
- if with_uart:
- self.submodules.uart_phy = uart.RS232PHY(platform.request("serial"), clk_freq, uart_baudrate)
- self.submodules.uart = uart.UART(self.uart_phy)
-
- if with_identifier:
- platform_id = 0x554E if not hasattr(platform, "identifier") else platform.identifier
- self.submodules.identifier = identifier.Identifier(platform_id, int(clk_freq))
-
- if with_timer:
- self.submodules.timer0 = timer.Timer()
-
- def initialize_rom(self, data):
- self.rom.mem.init = data
-
- def add_wb_master(self, wbm):
- if self.finalized:
- raise FinalizeError
- self._wb_masters.append(wbm)
-
- def add_wb_slave(self, address_decoder, interface):
- if self.finalized:
- raise FinalizeError
- self._wb_slaves.append((address_decoder, interface))
-
- def add_memory_region(self, name, origin, length):
- def in_this_region(addr):
- return addr >= origin and addr < origin + length
- for n, o, l in self._memory_regions:
- if n == name or in_this_region(o) or in_this_region(o+l-1):
- raise ValueError("Memory region conflict between {} and {}".format(n, name))
-
- self._memory_regions.append((name, origin, length))
-
- def register_mem(self, name, address, interface, size=None):
- self.add_wb_slave(mem_decoder(address), interface)
- if size is not None:
- self.add_memory_region(name, address, size)
-
- def register_rom(self, interface, rom_size=0xa000):
- self.add_wb_slave(mem_decoder(self.mem_map["rom"]), interface)
- self.add_memory_region("rom", self.cpu_reset_address, rom_size)
-
- def get_memory_regions(self):
- return self._memory_regions
-
- def check_csr_region(self, name, origin):
- for n, o, l, obj in self._csr_regions:
- if n == name or o == origin:
- raise ValueError("CSR region conflict between {} and {}".format(n, name))
-
- def add_csr_region(self, name, origin, busword, obj):
- self.check_csr_region(name, origin)
- self._csr_regions.append((name, origin, busword, obj))
-
- def get_csr_regions(self):
- return self._csr_regions
-
- def add_constant(self, name, value=None):
- self._constants.append((name, value))
-
- def get_constants(self):
- r = []
- for name, interrupt in sorted(self.interrupt_map.items(), key=itemgetter(1)):
- r.append((name.upper() + "_INTERRUPT", interrupt))
- r += self._constants
- return r
-
- def do_finalize(self):
- registered_mems = {regions[0] for regions in self._memory_regions}
- for mem in "rom", "sram":
- if mem not in registered_mems:
- raise FinalizeError("CPU needs a {} to be registered with register_mem()".format(mem))
-
- # Wishbone
- self.submodules.wishbonecon = wishbone.InterconnectShared(self._wb_masters,
- self._wb_slaves, register=True)
-
- # CSR
- self.submodules.csrbankarray = csr_bus.CSRBankArray(self,
- lambda name, memory: self.csr_map[name if memory is None else name + "_" + memory.name_override],
- data_width=self.csr_data_width, address_width=self.csr_address_width)
- self.submodules.csrcon = csr_bus.Interconnect(
- self.wishbone2csr.csr, self.csrbankarray.get_buses())
- for name, csrs, mapaddr, rmap in self.csrbankarray.banks:
- self.add_csr_region(name, (self.mem_map["csr"] + 0x800*mapaddr) | self.shadow_base, self.csr_data_width, csrs)
- for name, memory, mapaddr, mmap in self.csrbankarray.srams:
- self.add_csr_region(name + "_" + memory.name_override, (self.mem_map["csr"] + 0x800*mapaddr) | self.shadow_base, self.csr_data_width, memory)
-
- # Interrupts
- for k, v in sorted(self.interrupt_map.items(), key=itemgetter(1)):
- if hasattr(self, k):
- self.comb += self.cpu.interrupt[v].eq(getattr(self, k).ev.irq)
-
- def build(self, *args, **kwargs):
- self.platform.build(self, *args, **kwargs)
-
-
-def soc_core_args(parser):
- parser.add_argument("--cpu-type", default=None,
- help="select CPU: lm32, or1k")
- parser.add_argument("--integrated-rom-size", default=None, type=int,
- help="size/enable the integrated (BIOS) ROM")
- parser.add_argument("--integrated-main-ram-size", default=None, type=int,
- help="size/enable the integrated main RAM")
-
-
-def soc_core_argdict(args):
- r = dict()
- for a in "cpu_type", "integrated_rom_size", "integrated_main_ram_size":
- arg = getattr(args, a)
- if arg is not None:
- r[a] = arg
- return r
+++ /dev/null
-from migen import *
-from migen.genlib.record import *
-
-from misoc.interconnect import wishbone, wishbone2lasmi, lasmi_bus
-from misoc.interconnect.csr import AutoCSR
-from misoc.cores import dfii, minicon, lasmicon
-from misoc.integration.soc_core import *
-
-
-__all__ = ["SoCSDRAM", "soc_sdram_args", "soc_sdram_argdict"]
-
-
-class ControllerInjector(Module, AutoCSR):
- def __init__(self, phy, controller_type, geom_settings, timing_settings):
- self.submodules.dfii = dfii.DFIInjector(geom_settings.addressbits, geom_settings.bankbits,
- phy.settings.dfi_databits, phy.settings.nphases)
- self.comb += Record.connect(self.dfii.master, phy.dfi)
-
- if controller_type == "lasmicon":
- self.submodules.controller = controller = lasmicon.LASMIcon(phy.settings,
- geom_settings,
- timing_settings)
- self.comb += Record.connect(controller.dfi, self.dfii.slave)
-
- self.submodules.crossbar = lasmi_bus.LASMIxbar([controller.lasmic],
- controller.nrowbits)
- elif controller_type == "minicon":
- self.submodules.controller = controller = minicon.Minicon(phy.settings,
- geom_settings,
- timing_settings)
- self.comb += Record.connect(controller.dfi, self.dfii.slave)
- else:
- raise ValueError("Unsupported SDRAM controller type")
-
-
-class SoCSDRAM(SoCCore):
- csr_map = {
- "sdram": 8,
- "l2_cache": 9
- }
- csr_map.update(SoCCore.csr_map)
-
- def __init__(self, platform, clk_freq, l2_size=8192, **kwargs):
- SoCCore.__init__(self, platform, clk_freq, **kwargs)
- self.l2_size = l2_size
-
- self._sdram_phy = []
- self._wb_sdram_ifs = []
- self._wb_sdram = wishbone.Interface()
-
- def add_wb_sdram_if(self, interface):
- if self.finalized:
- raise FinalizeError
- self._wb_sdram_ifs.append(interface)
-
- def register_sdram(self, phy, sdram_controller_type, geom_settings, timing_settings):
- assert not self._sdram_phy
- self._sdram_phy.append(phy) # encapsulate in list to prevent CSR scanning
-
- self.submodules.sdram = ControllerInjector(
- phy, sdram_controller_type, geom_settings, timing_settings)
-
- dfi_databits_divisor = 1 if phy.settings.memtype == "SDR" else 2
- sdram_width = phy.settings.dfi_databits//dfi_databits_divisor
- main_ram_size = 2**(geom_settings.bankbits +
- geom_settings.rowbits +
- geom_settings.colbits)*sdram_width//8
- # XXX: Limit main_ram_size to 256MB, we should modify mem_map to allow larger memories.
- main_ram_size = min(main_ram_size, 256*1024*1024)
- if self.l2_size:
- self.add_constant("L2_SIZE", self.l2_size)
-
- # add a Wishbone interface to the DRAM
- wb_sdram = wishbone.Interface()
- self.add_wb_sdram_if(wb_sdram)
- self.register_mem("main_ram", self.mem_map["main_ram"], wb_sdram, main_ram_size)
-
- if sdram_controller_type == "lasmicon":
- if self.l2_size:
- lasmim = self.sdram.crossbar.get_master()
- l2_cache = wishbone.Cache(self.l2_size//4, self._wb_sdram, wishbone.Interface(lasmim.dw))
- # XXX Vivado ->2015.1 workaround, Vivado is not able to map correctly our L2 cache.
- # Issue is reported to Xilinx and should be fixed in next releases (2015.2?).
- # Remove this workaround when fixed by Xilinx.
- from migen.build.xilinx.vivado import XilinxVivadoToolchain
- if isinstance(self.platform.toolchain, XilinxVivadoToolchain):
- from migen.fhdl.simplify import FullMemoryWE
- self.submodules.l2_cache = FullMemoryWE()(l2_cache)
- else:
- self.submodules.l2_cache = l2_cache
- self.submodules.wishbone2lasmi = wishbone2lasmi.WB2LASMI(self.l2_cache.slave, lasmim)
- elif sdram_controller_type == "minicon":
- if self.l2_size:
- l2_cache = wishbone.Cache(self.l2_size//4, self._wb_sdram, self.sdram.controller.bus)
- # XXX Vivado ->2015.1 workaround, Vivado is not able to map correctly our L2 cache.
- # Issue is reported to Xilinx and should be fixed in next releases (2015.2?).
- # Remove this workaround when fixed by Xilinx.
- from migen.build.xilinx.vivado import XilinxVivadoToolchain
- if isinstance(self.platform.toolchain, XilinxVivadoToolchain):
- from migen.fhdl.simplify import FullMemoryWE
- self.submodules.l2_cache = FullMemoryWE()(l2_cache)
- else:
- self.submodules.l2_cache = l2_cache
- else:
- self.submodules.converter = wishbone.Converter(self._wb_sdram, self.sdram.controller.bus)
- else:
- raise ValueError
-
- def do_finalize(self):
- if not self.integrated_main_ram_size:
- if not self._sdram_phy:
- raise FinalizeError("Need to call SDRAMSoC.register_sdram()")
-
- # arbitrate wishbone interfaces to the DRAM
- self.submodules.wb_sdram_con = wishbone.Arbiter(self._wb_sdram_ifs,
- self._wb_sdram)
- SoCCore.do_finalize(self)
-
-
-soc_sdram_args = soc_core_args
-soc_sdram_argdict = soc_core_argdict
+++ /dev/null
-from migen import *
-from migen.util.misc import xdir
-from migen.fhdl.tracer import get_obj_var_name
-
-
-class _CSRBase(DUID):
- def __init__(self, size, name):
- DUID.__init__(self)
- self.name = get_obj_var_name(name)
- if self.name is None:
- raise ValueError("Cannot extract CSR name from code, need to specify.")
- self.size = size
-
-
-class CSR(_CSRBase):
- def __init__(self, size=1, name=None):
- _CSRBase.__init__(self, size, name)
- self.re = Signal(name=self.name + "_re")
- self.r = Signal(self.size, name=self.name + "_r")
- self.w = Signal(self.size, name=self.name + "_w")
-
-
-class _CompoundCSR(_CSRBase, Module):
- def __init__(self, size, name):
- _CSRBase.__init__(self, size, name)
- self.simple_csrs = []
-
- def get_simple_csrs(self):
- if not self.finalized:
- raise FinalizeError
- return self.simple_csrs
-
- def do_finalize(self, busword):
- raise NotImplementedError
-
-
-class CSRStatus(_CompoundCSR):
- def __init__(self, size=1, reset=0, name=None):
- _CompoundCSR.__init__(self, size, name)
- self.status = Signal(self.size, reset=reset)
-
- def do_finalize(self, busword):
- nwords = (self.size + busword - 1)//busword
- for i in reversed(range(nwords)):
- nbits = min(self.size - i*busword, busword)
- sc = CSR(nbits, self.name + str(i) if nwords > 1 else self.name)
- self.comb += sc.w.eq(self.status[i*busword:i*busword+nbits])
- self.simple_csrs.append(sc)
-
-
-class CSRStorage(_CompoundCSR):
- def __init__(self, size=1, reset=0, atomic_write=False, write_from_dev=False, alignment_bits=0, name=None):
- _CompoundCSR.__init__(self, size, name)
- self.alignment_bits = alignment_bits
- self.storage_full = Signal(self.size, reset=reset)
- self.storage = Signal(self.size - self.alignment_bits, reset=reset >> alignment_bits)
- self.comb += self.storage.eq(self.storage_full[self.alignment_bits:])
- self.atomic_write = atomic_write
- self.re = Signal()
- if write_from_dev:
- self.we = Signal()
- self.dat_w = Signal(self.size - self.alignment_bits)
- self.sync += If(self.we, self.storage_full.eq(self.dat_w << self.alignment_bits))
-
- def do_finalize(self, busword):
- nwords = (self.size + busword - 1)//busword
- if nwords > 1 and self.atomic_write:
- backstore = Signal(self.size - busword, name=self.name + "_backstore")
- for i in reversed(range(nwords)):
- nbits = min(self.size - i*busword, busword)
- sc = CSR(nbits, self.name + str(i) if nwords else self.name)
- self.simple_csrs.append(sc)
- lo = i*busword
- hi = lo+nbits
- # read
- if lo >= self.alignment_bits:
- self.comb += sc.w.eq(self.storage_full[lo:hi])
- elif hi > self.alignment_bits:
- self.comb += sc.w.eq(Cat(Replicate(0, hi - self.alignment_bits),
- self.storage_full[self.alignment_bits:hi]))
- else:
- self.comb += sc.w.eq(0)
- # write
- if nwords > 1 and self.atomic_write:
- if i:
- self.sync += If(sc.re, backstore[lo-busword:hi-busword].eq(sc.r))
- else:
- self.sync += If(sc.re, self.storage_full.eq(Cat(sc.r, backstore)))
- else:
- self.sync += If(sc.re, self.storage_full[lo:hi].eq(sc.r))
- self.sync += self.re.eq(sc.re)
-
-
-def csrprefix(prefix, csrs, done):
- for csr in csrs:
- if csr.duid not in done:
- csr.name = prefix + csr.name
- done.add(csr.duid)
-
-
-def memprefix(prefix, memories, done):
- for memory in memories:
- if memory.duid not in done:
- memory.name_override = prefix + memory.name_override
- done.add(memory.duid)
-
-
-def _make_gatherer(method, cls, prefix_cb):
- def gatherer(self):
- try:
- exclude = self.autocsr_exclude
- except AttributeError:
- exclude = {}
- try:
- prefixed = self.__prefixed
- except AttributeError:
- prefixed = self.__prefixed = set()
- r = []
- for k, v in xdir(self, True):
- if k not in exclude:
- if isinstance(v, cls):
- r.append(v)
- elif hasattr(v, method) and callable(getattr(v, method)):
- items = getattr(v, method)()
- prefix_cb(k + "_", items, prefixed)
- r += items
- return sorted(r, key=lambda x: x.duid)
- return gatherer
-
-
-class AutoCSR:
- get_memories = _make_gatherer("get_memories", Memory, memprefix)
- get_csrs = _make_gatherer("get_csrs", _CSRBase, csrprefix)
-
-
-class GenericBank(Module):
- def __init__(self, description, busword):
- # Turn description into simple CSRs and claim ownership of compound CSR modules
- self.simple_csrs = []
- for c in description:
- if isinstance(c, CSR):
- self.simple_csrs.append(c)
- else:
- c.finalize(busword)
- self.simple_csrs += c.get_simple_csrs()
- self.submodules += c
- self.decode_bits = bits_for(len(self.simple_csrs)-1)
+++ /dev/null
-from migen import *
-from migen.genlib.record import *
-from migen.genlib.misc import chooser
-from migen.util.misc import xdir
-
-from misoc.interconnect import csr
-from misoc.interconnect.csr import CSRStorage
-
-
-_layout = [
- ("adr", "address_width", DIR_M_TO_S),
- ("we", 1, DIR_M_TO_S),
- ("dat_w", "data_width", DIR_M_TO_S),
- ("dat_r", "data_width", DIR_S_TO_M)
-]
-
-
-class Interface(Record):
- def __init__(self, data_width=8, address_width=14):
- Record.__init__(self, set_layout_parameters(_layout,
- data_width=data_width, address_width=address_width))
-
-
-class Interconnect(Module):
- def __init__(self, master, slaves):
- self.comb += master.connect(*slaves)
-
-
-class SRAM(Module):
- def __init__(self, mem_or_size, address, read_only=None, init=None, bus=None):
- if bus is None:
- bus = Interface()
- self.bus = bus
- data_width = len(self.bus.dat_w)
- if isinstance(mem_or_size, Memory):
- mem = mem_or_size
- else:
- mem = Memory(data_width, mem_or_size//(data_width//8), init=init)
- csrw_per_memw = (mem.width + data_width - 1)//data_width
- word_bits = log2_int(csrw_per_memw)
- page_bits = log2_int((mem.depth*csrw_per_memw + 511)//512, False)
- if page_bits:
- self._page = CSRStorage(page_bits, name=mem.name_override + "_page")
- else:
- self._page = None
- if read_only is None:
- if hasattr(mem, "bus_read_only"):
- read_only = mem.bus_read_only
- else:
- read_only = False
-
- ###
-
- port = mem.get_port(write_capable=not read_only)
- self.specials += mem, port
-
- sel = Signal()
- sel_r = Signal()
- self.sync += sel_r.eq(sel)
- self.comb += sel.eq(self.bus.adr[9:] == address)
-
- if word_bits:
- word_index = Signal(word_bits)
- word_expanded = Signal(csrw_per_memw*data_width)
- self.sync += word_index.eq(self.bus.adr[:word_bits])
- self.comb += [
- word_expanded.eq(port.dat_r),
- If(sel_r,
- chooser(word_expanded, word_index, self.bus.dat_r, n=csrw_per_memw, reverse=True)
- )
- ]
- if not read_only:
- wregs = []
- for i in range(csrw_per_memw-1):
- wreg = Signal(data_width)
- self.sync += If(sel & self.bus.we & (self.bus.adr[:word_bits] == i), wreg.eq(self.bus.dat_w))
- wregs.append(wreg)
- memword_chunks = [self.bus.dat_w] + list(reversed(wregs))
- self.comb += [
- port.we.eq(sel & self.bus.we & (self.bus.adr[:word_bits] == csrw_per_memw - 1)),
- port.dat_w.eq(Cat(*memword_chunks))
- ]
- else:
- self.comb += If(sel_r, self.bus.dat_r.eq(port.dat_r))
- if not read_only:
- self.comb += [
- port.we.eq(sel & self.bus.we),
- port.dat_w.eq(self.bus.dat_w)
- ]
-
- if self._page is None:
- self.comb += port.adr.eq(self.bus.adr[word_bits:word_bits+len(port.adr)])
- else:
- pv = self._page.storage
- self.comb += port.adr.eq(Cat(self.bus.adr[word_bits:word_bits+len(port.adr)-len(pv)], pv))
-
- def get_csrs(self):
- if self._page is None:
- return []
- else:
- return [self._page]
-
-
-class CSRBank(csr.GenericBank):
- def __init__(self, description, address=0, bus=None):
- if bus is None:
- bus = Interface()
- self.bus = bus
-
- ###
-
- csr.GenericBank.__init__(self, description, len(self.bus.dat_w))
-
- sel = Signal()
- self.comb += sel.eq(self.bus.adr[9:] == address)
-
- for i, c in enumerate(self.simple_csrs):
- self.comb += [
- c.r.eq(self.bus.dat_w[:c.size]),
- c.re.eq(sel & \
- self.bus.we & \
- (self.bus.adr[:self.decode_bits] == i))
- ]
-
- brcases = dict((i, self.bus.dat_r.eq(c.w)) for i, c in enumerate(self.simple_csrs))
- self.sync += [
- self.bus.dat_r.eq(0),
- If(sel, Case(self.bus.adr[:self.decode_bits], brcases))
- ]
-
-
-# address_map(name, memory) returns the CSR offset at which to map
-# the CSR object (register bank or memory).
-# If memory=None, the object is the register bank of object source.name.
-# Otherwise, it is a memory object belonging to source.name.
-# address_map is called exactly once for each object at each call to
-# scan(), so it can have side effects.
-class CSRBankArray(Module):
- def __init__(self, source, address_map, *ifargs, **ifkwargs):
- self.source = source
- self.address_map = address_map
- self.scan(ifargs, ifkwargs)
-
- def scan(self, ifargs, ifkwargs):
- self.banks = []
- self.srams = []
- for name, obj in xdir(self.source, True):
- if hasattr(obj, "get_csrs"):
- csrs = obj.get_csrs()
- else:
- csrs = []
- if hasattr(obj, "get_memories"):
- memories = obj.get_memories()
- for memory in memories:
- mapaddr = self.address_map(name, memory)
- if mapaddr is None:
- continue
- sram_bus = Interface(*ifargs, **ifkwargs)
- mmap = csr.SRAM(memory, mapaddr, bus=sram_bus)
- self.submodules += mmap
- csrs += mmap.get_csrs()
- self.srams.append((name, memory, mapaddr, mmap))
- if csrs:
- mapaddr = self.address_map(name, None)
- if mapaddr is None:
- continue
- bank_bus = Interface(*ifargs, **ifkwargs)
- rmap = CSRBank(csrs, mapaddr, bus=bank_bus)
- self.submodules += rmap
- self.banks.append((name, csrs, mapaddr, rmap))
-
- def get_rmaps(self):
- return [rmap for name, csrs, mapaddr, rmap in self.banks]
-
- def get_mmaps(self):
- return [mmap for name, memory, mapaddr, mmap in self.srams]
-
- def get_buses(self):
- return [i.bus for i in self.get_rmaps() + self.get_mmaps()]
+++ /dev/null
-from functools import reduce
-from operator import or_
-
-from migen import *
-from migen.util.misc import xdir
-
-from misoc.interconnect.csr import *
-
-
-class _EventSource(DUID):
- def __init__(self):
- DUID.__init__(self)
- self.status = Signal() # value in the status register
- self.pending = Signal() # value in the pending register + assert irq if unmasked
- self.trigger = Signal() # trigger signal interface to the user design
- self.clear = Signal() # clearing attempt by W1C to pending register, ignored by some event sources
-
-
-# set on a positive trigger pulse
-class EventSourcePulse(Module, _EventSource):
- def __init__(self):
- _EventSource.__init__(self)
- self.comb += self.status.eq(0)
- self.sync += [
- If(self.clear, self.pending.eq(0)),
- If(self.trigger, self.pending.eq(1))
- ]
-
-
-# set on the falling edge of the trigger, status = trigger
-class EventSourceProcess(Module, _EventSource):
- def __init__(self):
- _EventSource.__init__(self)
- self.comb += self.status.eq(self.trigger)
- old_trigger = Signal()
- self.sync += [
- If(self.clear, self.pending.eq(0)),
- old_trigger.eq(self.trigger),
- If(~self.trigger & old_trigger, self.pending.eq(1))
- ]
-
-
-# all status set by external trigger
-class EventSourceLevel(Module, _EventSource):
- def __init__(self):
- _EventSource.__init__(self)
- self.comb += [
- self.status.eq(self.trigger),
- self.pending.eq(self.trigger)
- ]
-
-
-class EventManager(Module, AutoCSR):
- def __init__(self):
- self.irq = Signal()
-
- def do_finalize(self):
- sources_u = [v for k, v in xdir(self, True) if isinstance(v, _EventSource)]
- sources = sorted(sources_u, key=lambda x: x.duid)
- n = len(sources)
- self.status = CSR(n)
- self.pending = CSR(n)
- self.enable = CSRStorage(n)
-
- for i, source in enumerate(sources):
- self.comb += [
- self.status.w[i].eq(source.status),
- If(self.pending.re & self.pending.r[i], source.clear.eq(1)),
- self.pending.w[i].eq(source.pending)
- ]
-
- irqs = [self.pending.w[i] & self.enable.storage[i] for i in range(n)]
- self.comb += self.irq.eq(reduce(or_, irqs))
-
- def __setattr__(self, name, value):
- object.__setattr__(self, name, value)
- if isinstance(value, _EventSource):
- if self.finalized:
- raise FinalizeError
- self.submodules += value
-
-
-class SharedIRQ(Module):
- def __init__(self, *event_managers):
- self.irq = Signal()
- self.comb += self.irq.eq(reduce(or_, [ev.irq for ev in event_managers]))
+++ /dev/null
-from migen import *
-from migen.genlib.record import *
-
-
-def phase_cmd_description(addressbits, bankbits):
- return [
- ("address", addressbits, DIR_M_TO_S),
- ("bank", bankbits, DIR_M_TO_S),
- ("cas_n", 1, DIR_M_TO_S),
- ("cs_n", 1, DIR_M_TO_S),
- ("ras_n", 1, DIR_M_TO_S),
- ("we_n", 1, DIR_M_TO_S),
- ("cke", 1, DIR_M_TO_S),
- ("odt", 1, DIR_M_TO_S),
- ("reset_n", 1, DIR_M_TO_S)
- ]
-
-
-def phase_wrdata_description(databits):
- return [
- ("wrdata", databits, DIR_M_TO_S),
- ("wrdata_en", 1, DIR_M_TO_S),
- ("wrdata_mask", databits//8, DIR_M_TO_S)
- ]
-
-
-def phase_rddata_description(databits):
- return [
- ("rddata_en", 1, DIR_M_TO_S),
- ("rddata", databits, DIR_S_TO_M),
- ("rddata_valid", 1, DIR_S_TO_M)
- ]
-
-
-def phase_description(addressbits, bankbits, databits):
- r = phase_cmd_description(addressbits, bankbits)
- r += phase_wrdata_description(databits)
- r += phase_rddata_description(databits)
- return r
-
-
-class Interface(Record):
- def __init__(self, addressbits, bankbits, databits, nphases=1):
- layout = [("p"+str(i), phase_description(addressbits, bankbits, databits)) for i in range(nphases)]
- Record.__init__(self, layout)
- self.phases = [getattr(self, "p"+str(i)) for i in range(nphases)]
- for p in self.phases:
- p.cas_n.reset = 1
- p.cs_n.reset = 1
- p.ras_n.reset = 1
- p.we_n.reset = 1
-
- # Returns pairs (DFI-mandated signal name, Migen signal object)
- def get_standard_names(self, m2s=True, s2m=True):
- r = []
- add_suffix = len(self.phases) > 1
- for n, phase in enumerate(self.phases):
- for field, size, direction in phase.layout:
- if (m2s and direction == DIR_M_TO_S) or (s2m and direction == DIR_S_TO_M):
- if add_suffix:
- if direction == DIR_M_TO_S:
- suffix = "_p" + str(n)
- else:
- suffix = "_w" + str(n)
- else:
- suffix = ""
- r.append(("dfi_" + field + suffix, getattr(phase, field)))
- return r
-
-
-class Interconnect(Module):
- def __init__(self, master, slave):
- self.comb += master.connect(slave)
+++ /dev/null
-from migen import *
-from migen.genlib.fifo import SyncFIFO
-
-
-class Reader(Module):
- def __init__(self, lasmim, fifo_depth=None):
- self.address = Sink([("a", lasmim.aw)])
- self.data = Source([("d", lasmim.dw)])
- self.busy = Signal()
-
- ###
-
- if fifo_depth is None:
- fifo_depth = lasmim.req_queue_size + lasmim.read_latency + 2
-
- # request issuance
- request_enable = Signal()
- request_issued = Signal()
-
- self.comb += [
- lasmim.we.eq(0),
- lasmim.stb.eq(self.address.stb & request_enable),
- lasmim.adr.eq(self.address.a),
- self.address.ack.eq(lasmim.req_ack & request_enable),
- request_issued.eq(lasmim.stb & lasmim.req_ack)
- ]
-
- # FIFO reservation level counter
- # incremented when data is planned to be queued
- # decremented when data is dequeued
- data_dequeued = Signal()
- rsv_level = Signal(max=fifo_depth+1)
- self.sync += [
- If(request_issued,
- If(~data_dequeued, rsv_level.eq(rsv_level + 1))
- ).Elif(data_dequeued,
- rsv_level.eq(rsv_level - 1)
- )
- ]
- self.comb += [
- self.busy.eq(rsv_level != 0),
- request_enable.eq(rsv_level != fifo_depth)
- ]
-
- # FIFO
- fifo = SyncFIFO(lasmim.dw, fifo_depth)
- self.submodules += fifo
-
- self.comb += [
- fifo.din.eq(lasmim.dat_r),
- fifo.we.eq(lasmim.dat_r_ack),
-
- self.data.stb.eq(fifo.readable),
- fifo.re.eq(self.data.ack),
- self.data.d.eq(fifo.dout),
- data_dequeued.eq(self.data.stb & self.data.ack)
- ]
-
-
-class Writer(Module):
- def __init__(self, lasmim, fifo_depth=None):
- self.address_data = Sink([("a", lasmim.aw), ("d", lasmim.dw)])
- self.busy = Signal()
-
- ###
-
- if fifo_depth is None:
- fifo_depth = lasmim.req_queue_size + lasmim.write_latency + 2
-
- fifo = SyncFIFO(lasmim.dw, fifo_depth)
- self.submodules += fifo
-
- self.comb += [
- lasmim.we.eq(1),
- lasmim.stb.eq(fifo.writable & self.address_data.stb),
- lasmim.adr.eq(self.address_data.a),
- self.address_data.ack.eq(fifo.writable & lasmim.req_ack),
- fifo.we.eq(self.address_data.stb & lasmim.req_ack),
- fifo.din.eq(self.address_data.d)
- ]
-
- self.comb += [
- If(lasmim.dat_w_ack,
- fifo.re.eq(1),
- lasmim.dat_we.eq(2**(lasmim.dw//8)-1),
- lasmim.dat_w.eq(fifo.dout)
- ),
- self.busy.eq(fifo.readable)
- ]
+++ /dev/null
-from functools import reduce
-from operator import or_
-
-from migen import *
-from migen.genlib import roundrobin
-from migen.genlib.record import *
-
-
-class Interface(Record):
- def __init__(self, aw, dw, nbanks, req_queue_size, read_latency, write_latency):
- self.aw = aw
- self.dw = dw
- self.nbanks = nbanks
- self.req_queue_size = req_queue_size
- self.read_latency = read_latency
- self.write_latency = write_latency
-
- bank_layout = [
- ("adr", aw, DIR_M_TO_S),
- ("we", 1, DIR_M_TO_S),
- ("stb", 1, DIR_M_TO_S),
- ("req_ack", 1, DIR_S_TO_M),
- ("dat_w_ack", 1, DIR_S_TO_M),
- ("dat_r_ack", 1, DIR_S_TO_M),
- ("lock", 1, DIR_S_TO_M)
- ]
- if nbanks > 1:
- layout = [("bank"+str(i), bank_layout) for i in range(nbanks)]
- else:
- layout = bank_layout
- layout += [
- ("dat_w", dw, DIR_M_TO_S),
- ("dat_we", dw//8, DIR_M_TO_S),
- ("dat_r", dw, DIR_S_TO_M)
- ]
- Record.__init__(self, layout)
-
-
-def _getattr_all(l, attr):
- it = iter(l)
- r = getattr(next(it), attr)
- for e in it:
- if getattr(e, attr) != r:
- raise ValueError
- return r
-
-
-class LASMIxbar(Module):
- def __init__(self, controllers, cba_shift):
- self._controllers = controllers
- self._cba_shift = cba_shift
-
- self._rca_bits = _getattr_all(controllers, "aw")
- self._dw = _getattr_all(controllers, "dw")
- self._nbanks = _getattr_all(controllers, "nbanks")
- self._req_queue_size = _getattr_all(controllers, "req_queue_size")
- self._read_latency = _getattr_all(controllers, "read_latency")
- self._write_latency = _getattr_all(controllers, "write_latency")
-
- self._bank_bits = log2_int(self._nbanks, False)
- self._controller_bits = log2_int(len(self._controllers), False)
-
- self._masters = []
-
- def get_master(self):
- if self.finalized:
- raise FinalizeError
- lasmi_master = Interface(self._rca_bits + self._bank_bits + self._controller_bits,
- self._dw, 1, self._req_queue_size, self._read_latency, self._write_latency)
- self._masters.append(lasmi_master)
- return lasmi_master
-
- def do_finalize(self):
- nmasters = len(self._masters)
-
- m_ca, m_ba, m_rca = self._split_master_addresses(self._controller_bits,
- self._bank_bits, self._rca_bits, self._cba_shift)
-
- for nc, controller in enumerate(self._controllers):
- if self._controller_bits:
- controller_selected = [ca == nc for ca in m_ca]
- else:
- controller_selected = [1]*nmasters
- master_req_acks = [0]*nmasters
- master_dat_w_acks = [0]*nmasters
- master_dat_r_acks = [0]*nmasters
-
- rrs = [roundrobin.RoundRobin(nmasters, roundrobin.SP_CE) for n in range(self._nbanks)]
- self.submodules += rrs
- for nb, rr in enumerate(rrs):
- bank = getattr(controller, "bank"+str(nb))
-
- # for each master, determine if another bank locks it
- master_locked = []
- for nm, master in enumerate(self._masters):
- locked = 0
- for other_nb, other_rr in enumerate(rrs):
- if other_nb != nb:
- other_bank = getattr(controller, "bank"+str(other_nb))
- locked = locked | (other_bank.lock & (other_rr.grant == nm))
- master_locked.append(locked)
-
- # arbitrate
- bank_selected = [cs & (ba == nb) & ~locked for cs, ba, locked in zip(controller_selected, m_ba, master_locked)]
- bank_requested = [bs & master.stb for bs, master in zip(bank_selected, self._masters)]
- self.comb += [
- rr.request.eq(Cat(*bank_requested)),
- rr.ce.eq(~bank.stb & ~bank.lock)
- ]
-
- # route requests
- self.comb += [
- bank.adr.eq(Array(m_rca)[rr.grant]),
- bank.we.eq(Array(self._masters)[rr.grant].we),
- bank.stb.eq(Array(bank_requested)[rr.grant])
- ]
- master_req_acks = [master_req_ack | ((rr.grant == nm) & bank_selected[nm] & bank.req_ack)
- for nm, master_req_ack in enumerate(master_req_acks)]
- master_dat_w_acks = [master_dat_w_ack | ((rr.grant == nm) & bank.dat_w_ack)
- for nm, master_dat_w_ack in enumerate(master_dat_w_acks)]
- master_dat_r_acks = [master_dat_r_ack | ((rr.grant == nm) & bank.dat_r_ack)
- for nm, master_dat_r_ack in enumerate(master_dat_r_acks)]
-
- for nm, master_dat_w_ack in enumerate(master_dat_w_acks):
- for i in range(self._write_latency):
- new_master_dat_w_ack = Signal()
- self.sync += new_master_dat_w_ack.eq(master_dat_w_ack)
- master_dat_w_ack = new_master_dat_w_ack
- master_dat_w_acks[nm] = master_dat_w_ack
-
- for nm, master_dat_r_ack in enumerate(master_dat_r_acks):
- for i in range(self._read_latency):
- new_master_dat_r_ack = Signal()
- self.sync += new_master_dat_r_ack.eq(master_dat_r_ack)
- master_dat_r_ack = new_master_dat_r_ack
- master_dat_r_acks[nm] = master_dat_r_ack
-
- self.comb += [master.req_ack.eq(master_req_ack) for master, master_req_ack in zip(self._masters, master_req_acks)]
- self.comb += [master.dat_w_ack.eq(master_dat_w_ack) for master, master_dat_w_ack in zip(self._masters, master_dat_w_acks)]
- self.comb += [master.dat_r_ack.eq(master_dat_r_ack) for master, master_dat_r_ack in zip(self._masters, master_dat_r_acks)]
-
- # route data writes
- controller_selected_wl = controller_selected
- for i in range(self._write_latency):
- n_controller_selected_wl = [Signal() for i in range(nmasters)]
- self.sync += [n.eq(o) for n, o in zip(n_controller_selected_wl, controller_selected_wl)]
- controller_selected_wl = n_controller_selected_wl
- dat_w_maskselect = []
- dat_we_maskselect = []
- for master, selected in zip(self._masters, controller_selected_wl):
- o_dat_w = Signal(self._dw)
- o_dat_we = Signal(self._dw//8)
- self.comb += If(selected,
- o_dat_w.eq(master.dat_w),
- o_dat_we.eq(master.dat_we)
- )
- dat_w_maskselect.append(o_dat_w)
- dat_we_maskselect.append(o_dat_we)
- self.comb += [
- controller.dat_w.eq(reduce(or_, dat_w_maskselect)),
- controller.dat_we.eq(reduce(or_, dat_we_maskselect))
- ]
-
- # route data reads
- if self._controller_bits:
- for master in self._masters:
- controller_sel = Signal(self._controller_bits)
- for nc, controller in enumerate(self._controllers):
- for nb in range(nbanks):
- bank = getattr(controller, "bank"+str(nb))
- self.comb += If(bank.stb & bank.ack, controller_sel.eq(nc))
- for i in range(self._read_latency):
- n_controller_sel = Signal(self._controller_bits)
- self.sync += n_controller_sel.eq(controller_sel)
- controller_sel = n_controller_sel
- self.comb += master.dat_r.eq(Array(self._controllers)[controller_sel].dat_r)
- else:
- self.comb += [master.dat_r.eq(self._controllers[0].dat_r) for master in self._masters]
-
- def _split_master_addresses(self, controller_bits, bank_bits, rca_bits, cba_shift):
- m_ca = [] # controller address
- m_ba = [] # bank address
- m_rca = [] # row and column address
- for master in self._masters:
- cba = Signal(self._controller_bits + self._bank_bits)
- rca = Signal(self._rca_bits)
- cba_upper = cba_shift + controller_bits + bank_bits
- self.comb += cba.eq(master.adr[cba_shift:cba_upper])
- if cba_shift < self._rca_bits:
- if cba_shift:
- self.comb += rca.eq(Cat(master.adr[:cba_shift], master.adr[cba_upper:]))
- else:
- self.comb += rca.eq(master.adr[cba_upper:])
- else:
- self.comb += rca.eq(master.adr[:cba_shift])
-
- if self._controller_bits:
- ca = Signal(self._controller_bits)
- ba = Signal(self._bank_bits)
- self.comb += Cat(ba, ca).eq(cba)
- else:
- ca = None
- ba = cba
-
- m_ca.append(ca)
- m_ba.append(ba)
- m_rca.append(rca)
- return m_ca, m_ba, m_rca
+++ /dev/null
-from migen import *
-from migen.genlib.record import *
-from migen.genlib import fifo
-
-
-def _make_m2s(layout):
- r = []
- for f in layout:
- if isinstance(f[1], (int, tuple)):
- r.append((f[0], f[1], DIR_M_TO_S))
- else:
- r.append((f[0], _make_m2s(f[1])))
- return r
-
-
-class EndpointDescription:
- def __init__(self, payload_layout, packetized=False):
- self.payload_layout = payload_layout
- self.packetized = packetized
-
- def get_full_layout(self):
- reserved = {"stb", "ack", "payload", "sop", "eop", "description"}
- attributed = set()
- for f in self.payload_layout:
- if f[0] in attributed:
- raise ValueError(f[0] + " already attributed in payload layout")
- if f[0] in reserved:
- raise ValueError(f[0] + " cannot be used in endpoint layout")
- attributed.add(f[0])
-
- full_layout = [
- ("payload", _make_m2s(self.payload_layout)),
- ("stb", 1, DIR_M_TO_S),
- ("ack", 1, DIR_S_TO_M)
- ]
- if self.packetized:
- full_layout += [
- ("sop", 1, DIR_M_TO_S),
- ("eop", 1, DIR_M_TO_S)
- ]
- return full_layout
-
-
-class _Endpoint(Record):
- def __init__(self, description_or_layout):
- if isinstance(description_or_layout, EndpointDescription):
- self.description = description_or_layout
- else:
- self.description = EndpointDescription(description_or_layout)
- Record.__init__(self, self.description.get_full_layout())
-
- def __getattr__(self, name):
- return getattr(object.__getattribute__(self, "payload"), name)
-
-
-class Source(_Endpoint):
- def connect(self, sink):
- return Record.connect(self, sink)
-
-
-class Sink(_Endpoint):
- def connect(self, source):
- return source.connect(self)
-
-
-class _FIFOWrapper(Module):
- def __init__(self, fifo_class, layout, depth):
- self.sink = Sink(layout)
- self.source = Source(layout)
- self.busy = Signal()
-
- ###
-
- description = self.sink.description
- fifo_layout = [("payload", description.payload_layout)]
- if description.packetized:
- fifo_layout += [("sop", 1), ("eop", 1)]
-
- self.submodules.fifo = fifo_class(layout_len(fifo_layout), depth)
- fifo_in = Record(fifo_layout)
- fifo_out = Record(fifo_layout)
- self.comb += [
- self.fifo.din.eq(fifo_in.raw_bits()),
- fifo_out.raw_bits().eq(self.fifo.dout)
- ]
-
- self.comb += [
- self.sink.ack.eq(self.fifo.writable),
- self.fifo.we.eq(self.sink.stb),
- fifo_in.payload.eq(self.sink.payload),
-
- self.source.stb.eq(self.fifo.readable),
- self.source.payload.eq(fifo_out.payload),
- self.fifo.re.eq(self.source.ack)
- ]
- if description.packetized:
- self.comb += [
- fifo_in.sop.eq(self.sink.sop),
- fifo_in.eop.eq(self.sink.eop),
- self.source.sop.eq(fifo_out.sop),
- self.source.eop.eq(fifo_out.eop)
- ]
-
-
-class SyncFIFO(_FIFOWrapper):
- def __init__(self, layout, depth, buffered=False):
- _FIFOWrapper.__init__(
- self,
- fifo.SyncFIFOBuffered if buffered else fifo.SyncFIFO,
- layout, depth)
-
-
-class AsyncFIFO(_FIFOWrapper):
- def __init__(self, layout, depth):
- _FIFOWrapper.__init__(self, fifo.AsyncFIFO, layout, depth)
-
-
-class Multiplexer(Module):
- def __init__(self, layout, n):
- self.source = Source(layout)
- sinks = []
- for i in range(n):
- sink = Sink(layout)
- setattr(self, "sink"+str(i), sink)
- sinks.append(sink)
- self.sel = Signal(max=n)
-
- # # #
-
- cases = {}
- for i, sink in enumerate(sinks):
- cases[i] = Record.connect(sink, self.source)
- self.comb += Case(self.sel, cases)
-
-
-class Demultiplexer(Module):
- def __init__(self, layout, n):
- self.sink = Sink(layout)
- sources = []
- for i in range(n):
- source = Source(layout)
- setattr(self, "source"+str(i), source)
- sources.append(source)
- self.sel = Signal(max=n)
-
- # # #
-
- cases = {}
- for i, source in enumerate(sources):
- cases[i] = Record.connect(self.sink, source)
- self.comb += Case(self.sel, cases)
-
-# TODO: clean up code below
-# XXX
-
-from copy import copy
-from migen.util.misc import xdir
-
-def pack_layout(l, n):
- return [("chunk"+str(i), l) for i in range(n)]
-
-def get_endpoints(obj, filt=_Endpoint):
- if hasattr(obj, "get_endpoints") and callable(obj.get_endpoints):
- return obj.get_endpoints(filt)
- r = dict()
- for k, v in xdir(obj, True):
- if isinstance(v, filt):
- r[k] = v
- return r
-
-def get_single_ep(obj, filt):
- eps = get_endpoints(obj, filt)
- if len(eps) != 1:
- raise ValueError("More than one endpoint")
- return list(eps.items())[0]
-
-
-class BinaryActor(Module):
- def __init__(self, *args, **kwargs):
- self.busy = Signal()
- sink = get_single_ep(self, Sink)[1]
- source = get_single_ep(self, Source)[1]
- self.build_binary_control(sink, source, *args, **kwargs)
-
- def build_binary_control(self, sink, source):
- raise NotImplementedError("Binary actor classes must overload build_binary_control_fragment")
-
-
-class CombinatorialActor(BinaryActor):
- def build_binary_control(self, sink, source):
- self.comb += [
- source.stb.eq(sink.stb),
- sink.ack.eq(source.ack),
- self.busy.eq(0)
- ]
- if sink.description.packetized:
- self.comb += [
- source.sop.eq(sink.sop),
- source.eop.eq(sink.eop)
- ]
-
-
-class Unpack(Module):
- def __init__(self, n, layout_to, reverse=False):
- self.source = source = Source(layout_to)
- description_from = copy(source.description)
- description_from.payload_layout = pack_layout(description_from.payload_layout, n)
- self.sink = sink = Sink(description_from)
-
- self.busy = Signal()
-
- ###
-
- mux = Signal(max=n)
- first = Signal()
- last = Signal()
- self.comb += [
- first.eq(mux == 0),
- last.eq(mux == (n-1)),
- source.stb.eq(sink.stb),
- sink.ack.eq(last & source.ack)
- ]
- self.sync += [
- If(source.stb & source.ack,
- If(last,
- mux.eq(0)
- ).Else(
- mux.eq(mux + 1)
- )
- )
- ]
- cases = {}
- for i in range(n):
- chunk = n-i-1 if reverse else i
- cases[i] = [source.payload.raw_bits().eq(getattr(sink.payload, "chunk"+str(chunk)).raw_bits())]
- self.comb += Case(mux, cases).makedefault()
-
- if description_from.packetized:
- self.comb += [
- source.sop.eq(sink.sop & first),
- source.eop.eq(sink.eop & last)
- ]
-
-
-class Pack(Module):
- def __init__(self, layout_from, n, reverse=False):
- self.sink = sink = Sink(layout_from)
- description_to = copy(sink.description)
- description_to.payload_layout = pack_layout(description_to.payload_layout, n)
- self.source = source = Source(description_to)
- self.busy = Signal()
-
- ###
-
- demux = Signal(max=n)
-
- load_part = Signal()
- strobe_all = Signal()
- cases = {}
- for i in range(n):
- chunk = n-i-1 if reverse else i
- cases[i] = [getattr(source.payload, "chunk"+str(chunk)).raw_bits().eq(sink.payload.raw_bits())]
- self.comb += [
- self.busy.eq(strobe_all),
- sink.ack.eq(~strobe_all | source.ack),
- source.stb.eq(strobe_all),
- load_part.eq(sink.stb & sink.ack)
- ]
-
- if description_to.packetized:
- demux_last = ((demux == (n - 1)) | sink.eop)
- else:
- demux_last = (demux == (n - 1))
-
- self.sync += [
- If(source.ack, strobe_all.eq(0)),
- If(load_part,
- Case(demux, cases),
- If(demux_last,
- demux.eq(0),
- strobe_all.eq(1)
- ).Else(
- demux.eq(demux + 1)
- )
- )
- ]
-
- if description_to.packetized:
- self.sync += [
- If(source.stb & source.ack,
- source.sop.eq(sink.sop),
- source.eop.eq(sink.eop),
- ).Elif(sink.stb & sink.ack,
- source.sop.eq(sink.sop | source.sop),
- source.eop.eq(sink.eop | source.eop)
- )
- ]
-
-
-class Chunkerize(CombinatorialActor):
- def __init__(self, layout_from, layout_to, n, reverse=False):
- self.sink = Sink(layout_from)
- if isinstance(layout_to, EndpointDescription):
- layout_to = copy(layout_to)
- layout_to.payload_layout = pack_layout(layout_to.payload_layout, n)
- else:
- layout_to = pack_layout(layout_to, n)
- self.source = Source(layout_to)
- CombinatorialActor.__init__(self)
-
- ###
-
- for i in range(n):
- chunk = n-i-1 if reverse else i
- for f in self.sink.description.payload_layout:
- src = getattr(self.sink, f[0])
- dst = getattr(getattr(self.source, "chunk"+str(chunk)), f[0])
- self.comb += dst.eq(src[i*len(src)//n:(i+1)*len(src)//n])
-
-
-class Unchunkerize(CombinatorialActor):
- def __init__(self, layout_from, n, layout_to, reverse=False):
- if isinstance(layout_from, EndpointDescription):
- fields = layout_from.payload_layout
- layout_from = copy(layout_from)
- layout_from.payload_layout = pack_layout(layout_from.payload_layout, n)
- else:
- fields = layout_from
- layout_from = pack_layout(layout_from, n)
- self.sink = Sink(layout_from)
- self.source = Source(layout_to)
- CombinatorialActor.__init__(self)
-
- ###
-
- for i in range(n):
- chunk = n-i-1 if reverse else i
- for f in fields:
- src = getattr(getattr(self.sink, "chunk"+str(chunk)), f[0])
- dst = getattr(self.source, f[0])
- self.comb += dst[i*len(dst)//n:(i+1)*len(dst)//n].eq(src)
-
-
-class Converter(Module):
- def __init__(self, layout_from, layout_to, reverse=False):
- self.sink = Sink(layout_from)
- self.source = Source(layout_to)
- self.busy = Signal()
-
- ###
-
- width_from = len(self.sink.payload.raw_bits())
- width_to = len(self.source.payload.raw_bits())
-
- # downconverter
- if width_from > width_to:
- if width_from % width_to:
- raise ValueError
- ratio = width_from//width_to
- self.submodules.chunkerize = Chunkerize(layout_from, layout_to, ratio, reverse)
- self.submodules.unpack = Unpack(ratio, layout_to)
-
- self.comb += [
- Record.connect(self.sink, self.chunkerize.sink),
- Record.connect(self.chunkerize.source, self.unpack.sink),
- Record.connect(self.unpack.source, self.source),
- self.busy.eq(self.unpack.busy)
- ]
- # upconverter
- elif width_to > width_from:
- if width_to % width_from:
- raise ValueError
- ratio = width_to//width_from
- self.submodules.pack = Pack(layout_from, ratio)
- self.submodules.unchunkerize = Unchunkerize(layout_from, ratio, layout_to, reverse)
-
- self.comb += [
- Record.connect(self.sink, self.pack.sink),
- Record.connect(self.pack.source, self.unchunkerize.sink),
- Record.connect(self.unchunkerize.source, self.source),
- self.busy.eq(self.pack.busy)
- ]
- # direct connection
- else:
- self.comb += Record.connect(self.sink, self.source)
-
-# XXX
+++ /dev/null
-from functools import reduce
-from operator import or_
-
-from migen import *
-from migen.genlib import roundrobin
-from migen.genlib.record import *
-from migen.genlib.misc import split, displacer, chooser
-from migen.genlib.fsm import FSM, NextState
-
-from misoc.interconnect import csr
-
-# TODO: rewrite without FlipFlop and Counter
-
-
-_layout = [
- ("adr", 30, DIR_M_TO_S),
- ("dat_w", "data_width", DIR_M_TO_S),
- ("dat_r", "data_width", DIR_S_TO_M),
- ("sel", "sel_width", DIR_M_TO_S),
- ("cyc", 1, DIR_M_TO_S),
- ("stb", 1, DIR_M_TO_S),
- ("ack", 1, DIR_S_TO_M),
- ("we", 1, DIR_M_TO_S),
- ("cti", 3, DIR_M_TO_S),
- ("bte", 2, DIR_M_TO_S),
- ("err", 1, DIR_S_TO_M)
-]
-
-
-class Interface(Record):
- def __init__(self, data_width=32):
- Record.__init__(self, set_layout_parameters(_layout,
- data_width=data_width,
- sel_width=data_width//8))
-
- def _do_transaction(self):
- yield self.cyc.eq(1)
- yield self.stb.eq(1)
- yield
- while not (yield self.ack):
- yield
- yield self.cyc.eq(0)
- yield self.stb.eq(0)
-
- def write(self, adr, dat, sel=None):
- if sel is None:
- sel = 2**len(self.sel) - 1
- yield self.adr.eq(adr)
- yield self.dat_w.eq(dat)
- yield self.sel.eq(sel)
- yield self.we.eq(1)
- yield from self._do_transaction()
-
- def read(self, adr):
- yield self.adr.eq(adr)
- yield self.we.eq(0)
- yield from self._do_transaction()
- return (yield self.dat_r)
-
-
-class InterconnectPointToPoint(Module):
- def __init__(self, master, slave):
- self.comb += master.connect(slave)
-
-
-class Arbiter(Module):
- def __init__(self, masters, target):
- self.submodules.rr = roundrobin.RoundRobin(len(masters))
-
- # mux master->slave signals
- for name, size, direction in _layout:
- if direction == DIR_M_TO_S:
- choices = Array(getattr(m, name) for m in masters)
- self.comb += getattr(target, name).eq(choices[self.rr.grant])
-
- # connect slave->master signals
- for name, size, direction in _layout:
- if direction == DIR_S_TO_M:
- source = getattr(target, name)
- for i, m in enumerate(masters):
- dest = getattr(m, name)
- if name == "ack" or name == "err":
- self.comb += dest.eq(source & (self.rr.grant == i))
- else:
- self.comb += dest.eq(source)
-
- # connect bus requests to round-robin selector
- reqs = [m.cyc for m in masters]
- self.comb += self.rr.request.eq(Cat(*reqs))
-
-
-class Decoder(Module):
- # slaves is a list of pairs:
- # 0) function that takes the address signal and returns a FHDL expression
- # that evaluates to 1 when the slave is selected and 0 otherwise.
- # 1) wishbone.Slave reference.
- # register adds flip-flops after the address comparators. Improves timing,
- # but breaks Wishbone combinatorial feedback.
- def __init__(self, master, slaves, register=False):
- ns = len(slaves)
- slave_sel = Signal(ns)
- slave_sel_r = Signal(ns)
-
- # decode slave addresses
- self.comb += [slave_sel[i].eq(fun(master.adr))
- for i, (fun, bus) in enumerate(slaves)]
- if register:
- self.sync += slave_sel_r.eq(slave_sel)
- else:
- self.comb += slave_sel_r.eq(slave_sel)
-
- # connect master->slaves signals except cyc
- for slave in slaves:
- for name, size, direction in _layout:
- if direction == DIR_M_TO_S and name != "cyc":
- self.comb += getattr(slave[1], name).eq(getattr(master, name))
-
- # combine cyc with slave selection signals
- self.comb += [slave[1].cyc.eq(master.cyc & slave_sel[i])
- for i, slave in enumerate(slaves)]
-
- # generate master ack (resp. err) by ORing all slave acks (resp. errs)
- self.comb += [
- master.ack.eq(reduce(or_, [slave[1].ack for slave in slaves])),
- master.err.eq(reduce(or_, [slave[1].err for slave in slaves]))
- ]
-
- # mux (1-hot) slave data return
- masked = [Replicate(slave_sel_r[i], len(master.dat_r)) & slaves[i][1].dat_r for i in range(ns)]
- self.comb += master.dat_r.eq(reduce(or_, masked))
-
-
-class InterconnectShared(Module):
- def __init__(self, masters, slaves, register=False):
- shared = Interface()
- self.submodules += Arbiter(masters, shared)
- self.submodules += Decoder(shared, slaves, register)
-
-
-class Crossbar(Module):
- def __init__(self, masters, slaves, register=False):
- matches, busses = zip(*slaves)
- access = [[Interface() for j in slaves] for i in masters]
- # decode each master into its access row
- for row, master in zip(access, masters):
- row = list(zip(matches, row))
- self.submodules += Decoder(master, row, register)
- # arbitrate each access column onto its slave
- for column, bus in zip(zip(*access), busses):
- self.submodules += Arbiter(column, bus)
-
-
-class DownConverter(Module):
- """DownConverter
-
- This module splits Wishbone accesses from a master interface to a smaller
- slave interface.
-
- Writes:
- Writes from master are splitted N writes to the slave. Access is acked when the last
- access is acked by the slave.
-
- Reads:
- Read from master are splitted in N reads to the the slave. Read datas from
- the slave are cached before being presented concatenated on the last access.
-
- TODO:
- Manage err signal? (Not implemented since we generally don't use it on Migen/MiSoC modules)
- """
- def __init__(self, master, slave):
- dw_from = len(master.dat_r)
- dw_to = len(slave.dat_w)
- ratio = dw_from//dw_to
-
- # # #
-
- read = Signal()
- write = Signal()
-
- counter = Counter(max=ratio)
- self.submodules += counter
- counter_done = Signal()
- self.comb += counter_done.eq(counter.value == ratio-1)
-
- # Main FSM
- self.submodules.fsm = fsm = FSM(reset_state="IDLE")
- fsm.act("IDLE",
- counter.reset.eq(1),
- If(master.stb & master.cyc,
- If(master.we,
- NextState("WRITE")
- ).Else(
- NextState("READ")
- )
- )
- )
- fsm.act("WRITE",
- write.eq(1),
- slave.we.eq(1),
- slave.cyc.eq(1),
- If(master.stb & master.cyc,
- slave.stb.eq(1),
- If(slave.ack,
- counter.ce.eq(1),
- If(counter_done,
- master.ack.eq(1),
- NextState("IDLE")
- )
- )
- ).Elif(~master.cyc,
- NextState("IDLE")
- )
- )
- fsm.act("READ",
- read.eq(1),
- slave.cyc.eq(1),
- If(master.stb & master.cyc,
- slave.stb.eq(1),
- If(slave.ack,
- counter.ce.eq(1),
- If(counter_done,
- master.ack.eq(1),
- NextState("IDLE")
- )
- )
- ).Elif(~master.cyc,
- NextState("IDLE")
- )
- )
-
- # Address
- self.comb += [
- If(counter_done,
- slave.cti.eq(7) # indicate end of burst
- ).Else(
- slave.cti.eq(2)
- ),
- slave.adr.eq(Cat(counter.value, master.adr))
- ]
-
- # Datapath
- cases = {}
- for i in range(ratio):
- cases[i] = [
- slave.sel.eq(master.sel[i*dw_to//8:(i+1)*dw_to]),
- slave.dat_w.eq(master.dat_w[i*dw_to:(i+1)*dw_to])
- ]
- self.comb += Case(counter.value, cases)
-
-
- cached_data = Signal(dw_from)
- self.comb += master.dat_r.eq(Cat(cached_data[dw_to:], slave.dat_r))
- self.sync += \
- If(read & counter.ce,
- cached_data.eq(master.dat_r)
- )
-
-
-class UpConverter(Module):
- """UpConverter
-
- This module up-converts wishbone accesses and bursts from a master interface
- to a wider slave interface. This allows efficient use wishbone bursts.
-
- Writes:
- Wishbone writes are cached before being written to the slave. Access to
- the slave is done at the end of a burst or when address reach end of burst
- addressing.
-
- Reads:
- Cache is refilled only at the beginning of each burst, the subsequent
- reads of a burst use the cached data.
-
- TODO:
- Manage err signal? (Not implemented since we generally don't use it on Migen/MiSoC modules)
- """
- def __init__(self, master, slave):
- dw_from = len(master.dat_r)
- dw_to = len(slave.dat_w)
- ratio = dw_to//dw_from
- ratiobits = log2_int(ratio)
-
- # # #
-
- write = Signal()
- evict = Signal()
- refill = Signal()
- read = Signal()
-
- address = FlipFlop(30)
- self.submodules += address
- self.comb += address.d.eq(master.adr)
-
- counter = Counter(max=ratio)
- self.submodules += counter
- counter_offset = Signal(max=ratio)
- counter_done = Signal()
- self.comb += [
- counter_offset.eq(address.q),
- counter_done.eq((counter.value + counter_offset) == ratio-1)
- ]
-
- cached_data = Signal(dw_to)
- cached_sel = Signal(dw_to//8)
-
- end_of_burst = Signal()
- self.comb += end_of_burst.eq(~master.cyc |
- (master.stb & master.cyc & master.ack & ((master.cti == 7) | counter_done)))
-
-
- need_refill = FlipFlop(reset=1)
- self.submodules += need_refill
- self.comb += [
- need_refill.reset.eq(end_of_burst),
- need_refill.d.eq(0)
- ]
-
- # Main FSM
- self.submodules.fsm = fsm = FSM()
- fsm.act("IDLE",
- counter.reset.eq(1),
- If(master.stb & master.cyc,
- address.ce.eq(1),
- If(master.we,
- NextState("WRITE")
- ).Else(
- If(need_refill.q,
- NextState("REFILL")
- ).Else(
- NextState("READ")
- )
- )
- )
- )
- fsm.act("WRITE",
- If(master.stb & master.cyc,
- write.eq(1),
- counter.ce.eq(1),
- master.ack.eq(1),
- If(counter_done,
- NextState("EVICT")
- )
- ).Elif(~master.cyc,
- NextState("EVICT")
- )
- )
- fsm.act("EVICT",
- evict.eq(1),
- slave.stb.eq(1),
- slave.we.eq(1),
- slave.cyc.eq(1),
- slave.dat_w.eq(cached_data),
- slave.sel.eq(cached_sel),
- If(slave.ack,
- NextState("IDLE")
- )
- )
- fsm.act("REFILL",
- refill.eq(1),
- slave.stb.eq(1),
- slave.cyc.eq(1),
- If(slave.ack,
- need_refill.ce.eq(1),
- NextState("READ")
- )
- )
- fsm.act("READ",
- read.eq(1),
- If(master.stb & master.cyc,
- master.ack.eq(1)
- ),
- NextState("IDLE")
- )
-
- # Address
- self.comb += [
- slave.cti.eq(7), # we are not able to generate bursts since up-converting
- slave.adr.eq(address.q[ratiobits:])
- ]
-
- # Datapath
- cached_datas = [FlipFlop(dw_from) for i in range(ratio)]
- cached_sels = [FlipFlop(dw_from//8) for i in range(ratio)]
- self.submodules += cached_datas, cached_sels
-
- cases = {}
- for i in range(ratio):
- write_sel = Signal()
- cases[i] = write_sel.eq(1)
- self.comb += [
- cached_sels[i].reset.eq(counter.reset),
- If(write,
- cached_datas[i].d.eq(master.dat_w),
- ).Else(
- cached_datas[i].d.eq(slave.dat_r[dw_from*i:dw_from*(i+1)])
- ),
- cached_sels[i].d.eq(master.sel),
- If((write & write_sel) | refill,
- cached_datas[i].ce.eq(1),
- cached_sels[i].ce.eq(1)
- )
- ]
- self.comb += Case(counter.value + counter_offset, cases)
-
- cases = {}
- for i in range(ratio):
- cases[i] = master.dat_r.eq(cached_datas[i].q)
- self.comb += Case(address.q[:ratiobits], cases)
-
- self.comb += [
- cached_data.eq(Cat([cached_data.q for cached_data in cached_datas])),
- cached_sel.eq(Cat([cached_sel.q for cached_sel in cached_sels]))
- ]
-
-
-class Converter(Module):
- """Converter
-
- This module is a wrapper for DownConverter and UpConverter.
- It should preferably be used rather than direct instantiations
- of specific converters.
- """
- def __init__(self, master, slave):
- self.master = master
- self.slave = slave
-
- # # #
-
- dw_from = len(master.dat_r)
- dw_to = len(slave.dat_r)
- if dw_from > dw_to:
- downconverter = DownConverter(master, slave)
- self.submodules += downconverter
- elif dw_from < dw_to:
- upconverter = UpConverter(master, slave)
- self.submodules += upconverter
- else:
- Record.connect(master, slave)
-
-
-class Cache(Module):
- """Cache
-
- This module is a write-back wishbone cache that can be used as a L2 cache.
- Cachesize (in 32-bit words) is the size of the data store and must be a power of 2
- """
- def __init__(self, cachesize, master, slave):
- self.master = master
- self.slave = slave
-
- ###
-
- dw_from = len(master.dat_r)
- dw_to = len(slave.dat_r)
- if dw_to > dw_from and (dw_to % dw_from) != 0:
- raise ValueError("Slave data width must be a multiple of {dw}".format(dw=dw_from))
- if dw_to < dw_from and (dw_from % dw_to) != 0:
- raise ValueError("Master data width must be a multiple of {dw}".format(dw=dw_to))
-
- # Split address:
- # TAG | LINE NUMBER | LINE OFFSET
- offsetbits = log2_int(max(dw_to//dw_from, 1))
- addressbits = len(slave.adr) + offsetbits
- linebits = log2_int(cachesize) - offsetbits
- tagbits = addressbits - linebits
- wordbits = log2_int(max(dw_from//dw_to, 1))
- adr_offset, adr_line, adr_tag = split(master.adr, offsetbits, linebits, tagbits)
- word = Signal(wordbits) if wordbits else None
-
- # Data memory
- data_mem = Memory(dw_to*2**wordbits, 2**linebits)
- data_port = data_mem.get_port(write_capable=True, we_granularity=8)
- self.specials += data_mem, data_port
-
- write_from_slave = Signal()
- if adr_offset is None:
- adr_offset_r = None
- else:
- adr_offset_r = Signal(offsetbits)
- self.sync += adr_offset_r.eq(adr_offset)
-
- self.comb += [
- data_port.adr.eq(adr_line),
- If(write_from_slave,
- displacer(slave.dat_r, word, data_port.dat_w),
- displacer(Replicate(1, dw_to//8), word, data_port.we)
- ).Else(
- data_port.dat_w.eq(Replicate(master.dat_w, max(dw_to//dw_from, 1))),
- If(master.cyc & master.stb & master.we & master.ack,
- displacer(master.sel, adr_offset, data_port.we, 2**offsetbits, reverse=True)
- )
- ),
- chooser(data_port.dat_r, word, slave.dat_w),
- slave.sel.eq(2**(dw_to//8)-1),
- chooser(data_port.dat_r, adr_offset_r, master.dat_r, reverse=True)
- ]
-
-
- # Tag memory
- tag_layout = [("tag", tagbits), ("dirty", 1)]
- tag_mem = Memory(layout_len(tag_layout), 2**linebits)
- tag_port = tag_mem.get_port(write_capable=True)
- self.specials += tag_mem, tag_port
- tag_do = Record(tag_layout)
- tag_di = Record(tag_layout)
- self.comb += [
- tag_do.raw_bits().eq(tag_port.dat_r),
- tag_port.dat_w.eq(tag_di.raw_bits())
- ]
-
- self.comb += [
- tag_port.adr.eq(adr_line),
- tag_di.tag.eq(adr_tag)
- ]
- if word is not None:
- self.comb += slave.adr.eq(Cat(word, adr_line, tag_do.tag))
- else:
- self.comb += slave.adr.eq(Cat(adr_line, tag_do.tag))
-
- # slave word computation, word_clr and word_inc will be simplified
- # at synthesis when wordbits=0
- word_clr = Signal()
- word_inc = Signal()
- if word is not None:
- self.sync += \
- If(word_clr,
- word.eq(0),
- ).Elif(word_inc,
- word.eq(word+1)
- )
-
- def word_is_last(word):
- if word is not None:
- return word == 2**wordbits-1
- else:
- return 1
-
- # Control FSM
- self.submodules.fsm = fsm = FSM(reset_state="IDLE")
- fsm.act("IDLE",
- If(master.cyc & master.stb,
- NextState("TEST_HIT")
- )
- )
- fsm.act("TEST_HIT",
- word_clr.eq(1),
- If(tag_do.tag == adr_tag,
- master.ack.eq(1),
- If(master.we,
- tag_di.dirty.eq(1),
- tag_port.we.eq(1)
- ),
- NextState("IDLE")
- ).Else(
- If(tag_do.dirty,
- NextState("EVICT")
- ).Else(
- NextState("REFILL_WRTAG")
- )
- )
- )
-
- fsm.act("EVICT",
- slave.stb.eq(1),
- slave.cyc.eq(1),
- slave.we.eq(1),
- If(slave.ack,
- word_inc.eq(1),
- If(word_is_last(word),
- NextState("REFILL_WRTAG")
- )
- )
- )
- fsm.act("REFILL_WRTAG",
- # Write the tag first to set the slave address
- tag_port.we.eq(1),
- word_clr.eq(1),
- NextState("REFILL")
- )
- fsm.act("REFILL",
- slave.stb.eq(1),
- slave.cyc.eq(1),
- slave.we.eq(0),
- If(slave.ack,
- write_from_slave.eq(1),
- word_inc.eq(1),
- If(word_is_last(word),
- NextState("TEST_HIT"),
- ).Else(
- NextState("REFILL")
- )
- )
- )
-
-
-class SRAM(Module):
- def __init__(self, mem_or_size, read_only=None, init=None, bus=None):
- if bus is None:
- bus = Interface()
- self.bus = bus
- bus_data_width = len(self.bus.dat_r)
- if isinstance(mem_or_size, Memory):
- assert(mem_or_size.width <= bus_data_width)
- self.mem = mem_or_size
- else:
- self.mem = Memory(bus_data_width, mem_or_size//(bus_data_width//8), init=init)
- if read_only is None:
- if hasattr(self.mem, "bus_read_only"):
- read_only = self.mem.bus_read_only
- else:
- read_only = False
-
- ###
-
- # memory
- port = self.mem.get_port(write_capable=not read_only, we_granularity=8)
- self.specials += self.mem, port
- # generate write enable signal
- if not read_only:
- self.comb += [port.we[i].eq(self.bus.cyc & self.bus.stb & self.bus.we & self.bus.sel[i])
- for i in range(4)]
- # address and data
- self.comb += [
- port.adr.eq(self.bus.adr[:len(port.adr)]),
- self.bus.dat_r.eq(port.dat_r)
- ]
- if not read_only:
- self.comb += port.dat_w.eq(self.bus.dat_w),
- # generate ack
- self.sync += [
- self.bus.ack.eq(0),
- If(self.bus.cyc & self.bus.stb & ~self.bus.ack, self.bus.ack.eq(1))
- ]
-
-
-class CSRBank(csr.GenericBank):
- def __init__(self, description, bus=None):
- if bus is None:
- bus = Interface()
- self.bus = bus
-
- ###
-
- csr.GenericBank.__init__(self, description, len(self.bus.dat_w))
-
- for i, c in enumerate(self.simple_csrs):
- self.comb += [
- c.r.eq(self.bus.dat_w[:c.size]),
- c.re.eq(self.bus.cyc & self.bus.stb & ~self.bus.ack & self.bus.we & \
- (self.bus.adr[:self.decode_bits] == i))
- ]
-
- brcases = dict((i, self.bus.dat_r.eq(c.w)) for i, c in enumerate(self.simple_csrs))
- self.sync += [
- Case(self.bus.adr[:self.decode_bits], brcases),
- If(bus.ack, bus.ack.eq(0)).Elif(bus.cyc & bus.stb, bus.ack.eq(1))
- ]
+++ /dev/null
-from migen import *
-from migen.genlib.misc import timeline
-
-from misoc.interconnect import csr_bus, wishbone
-
-
-class WB2CSR(Module):
- def __init__(self, bus_wishbone=None, bus_csr=None):
- if bus_wishbone is None:
- bus_wishbone = wishbone.Interface()
- self.wishbone = bus_wishbone
- if bus_csr is None:
- bus_csr = csr_bus.Interface()
- self.csr = bus_csr
-
- ###
-
- self.sync += [
- self.csr.we.eq(0),
- self.csr.dat_w.eq(self.wishbone.dat_w),
- self.csr.adr.eq(self.wishbone.adr),
- self.wishbone.dat_r.eq(self.csr.dat_r)
- ]
- self.sync += timeline(self.wishbone.cyc & self.wishbone.stb, [
- (1, [self.csr.we.eq(self.wishbone.we)]),
- (2, [self.wishbone.ack.eq(1)]),
- (3, [self.wishbone.ack.eq(0)])
- ])
+++ /dev/null
-from migen import *
-from migen.genlib.fsm import FSM, NextState
-
-
-class WB2LASMI(Module):
- def __init__(self, wishbone, lasmim):
-
- ###
-
- # Control FSM
- self.submodules.fsm = fsm = FSM(reset_state="IDLE")
- fsm.act("IDLE",
- If(wishbone.cyc & wishbone.stb,
- NextState("REQUEST")
- )
- )
- fsm.act("REQUEST",
- lasmim.stb.eq(1),
- lasmim.we.eq(wishbone.we),
- If(lasmim.req_ack,
- If(wishbone.we,
- NextState("WRITE_DATA")
- ).Else(
- NextState("READ_DATA")
- )
- )
- )
- fsm.act("WRITE_DATA",
- If(lasmim.dat_w_ack,
- lasmim.dat_we.eq(wishbone.sel),
- wishbone.ack.eq(1),
- NextState("IDLE")
- )
- )
- fsm.act("READ_DATA",
- If(lasmim.dat_r_ack,
- wishbone.ack.eq(1),
- NextState("IDLE")
- )
- )
-
- # Address / Datapath
- self.comb += [
- lasmim.adr.eq(wishbone.adr),
- If(lasmim.dat_w_ack,
- lasmim.dat_w.eq(wishbone.dat_w),
- ),
- wishbone.dat_r.eq(lasmim.dat_r)
- ]
+++ /dev/null
-include ../include/generated/variables.mak
-include $(MISOC_DIRECTORY)/software/common.mak
-
-OBJECTS=isr.o sdram.o main.o boot-helper-$(CPU).o boot.o dataflow.o
-
-all: bios.bin
-
-%.bin: %.elf
- $(OBJCOPY) -O binary $< $@
- chmod -x $@
- $(PYTHON) -m misoc.tools.mkmscimg $@
-
-bios.elf: $(BIOS_DIRECTORY)/linker.ld $(OBJECTS)
-
-%.elf:
- $(LD) $(LDFLAGS) -T $< -N -o $@ \
- ../libbase/crt0-$(CPU).o \
- $(OBJECTS) \
- -L../libnet \
- -L../libbase \
- -L../libcompiler_rt \
- -lnet -lbase-nofloat -lcompiler_rt
- chmod -x $@
-
-main.o: $(BIOS_DIRECTORY)/main.c
- $(compile)
-
-%.o: $(BIOS_DIRECTORY)/%.c
- $(compile)
-
-%.o: $(BIOS_DIRECTORY)/%.S
- $(assemble)
-
-clean:
- $(RM) $(OBJECTS) bios.elf bios.bin .*~ *~
-
-.PHONY: all clean main.o
+++ /dev/null
-.section .text, "ax", @progbits
-.global boot_helper
-boot_helper:
- call r4
+++ /dev/null
-.section .text, "ax", @progbits
-.global boot_helper
-boot_helper:
- l.jr r6
- l.nop
+++ /dev/null
-#include <stdio.h>
-#include <console.h>
-#include <uart.h>
-#include <system.h>
-#include <crc.h>
-#include <string.h>
-#include <irq.h>
-
-#include <generated/mem.h>
-#include <generated/csr.h>
-
-#include <net/microudp.h>
-#include <net/tftp.h>
-#include "sfl.h"
-#include "boot.h"
-
-extern void boot_helper(unsigned int r1, unsigned int r2, unsigned int r3, unsigned int addr);
-
-static void __attribute__((noreturn)) boot(unsigned int r1, unsigned int r2, unsigned int r3, unsigned int addr)
-{
- printf("Executing booted program.\n");
- uart_sync();
- irq_setmask(0);
- irq_setie(0);
- flush_cpu_icache();
- boot_helper(r1, r2, r3, addr);
- while(1);
-}
-
-static int check_ack(void)
-{
- int recognized;
- static const char str[SFL_MAGIC_LEN] = SFL_MAGIC_ACK;
-
- timer0_en_write(0);
- timer0_reload_write(0);
- timer0_load_write(identifier_frequency_read()/4);
- timer0_en_write(1);
- timer0_update_value_write(1);
- recognized = 0;
- while(timer0_value_read()) {
- if(uart_read_nonblock()) {
- char c;
- c = uart_read();
- if(c == str[recognized]) {
- recognized++;
- if(recognized == SFL_MAGIC_LEN)
- return 1;
- } else {
- if(c == str[0])
- recognized = 1;
- else
- recognized = 0;
- }
- }
- timer0_update_value_write(1);
- }
- return 0;
-}
-
-#define MAX_FAILED 5
-
-void serialboot(void)
-{
- struct sfl_frame frame;
- int failed;
- unsigned int cmdline_adr, initrdstart_adr, initrdend_adr;
- static const char str[SFL_MAGIC_LEN+1] = SFL_MAGIC_REQ;
- const char *c;
-
- printf("Booting from serial...\n");
-
- c = str;
- while(*c) {
- uart_write(*c);
- c++;
- }
- if(!check_ack()) {
- printf("Timeout\n");
- return;
- }
-
- failed = 0;
- cmdline_adr = initrdstart_adr = initrdend_adr = 0;
- while(1) {
- int i;
- int actualcrc;
- int goodcrc;
-
- /* Grab one frame */
- frame.length = uart_read();
- frame.crc[0] = uart_read();
- frame.crc[1] = uart_read();
- frame.cmd = uart_read();
- for(i=0;i<frame.length;i++)
- frame.payload[i] = uart_read();
-
- /* Check CRC */
- actualcrc = ((int)frame.crc[0] << 8)|(int)frame.crc[1];
- goodcrc = crc16(&frame.cmd, frame.length+1);
- if(actualcrc != goodcrc) {
- failed++;
- if(failed == MAX_FAILED) {
- printf("Too many consecutive errors, aborting");
- return;
- }
- uart_write(SFL_ACK_CRCERROR);
- continue;
- }
-
- /* CRC OK */
- switch(frame.cmd) {
- case SFL_CMD_ABORT:
- failed = 0;
- uart_write(SFL_ACK_SUCCESS);
- return;
- case SFL_CMD_LOAD: {
- char *writepointer;
-
- failed = 0;
- writepointer = (char *)(
- ((unsigned int)frame.payload[0] << 24)
- |((unsigned int)frame.payload[1] << 16)
- |((unsigned int)frame.payload[2] << 8)
- |((unsigned int)frame.payload[3] << 0));
- for(i=4;i<frame.length;i++)
- *(writepointer++) = frame.payload[i];
- uart_write(SFL_ACK_SUCCESS);
- break;
- }
- case SFL_CMD_JUMP: {
- unsigned int addr;
-
- failed = 0;
- addr = ((unsigned int)frame.payload[0] << 24)
- |((unsigned int)frame.payload[1] << 16)
- |((unsigned int)frame.payload[2] << 8)
- |((unsigned int)frame.payload[3] << 0);
- uart_write(SFL_ACK_SUCCESS);
- boot(cmdline_adr, initrdstart_adr, initrdend_adr, addr);
- break;
- }
- case SFL_CMD_CMDLINE:
- failed = 0;
- cmdline_adr = ((unsigned int)frame.payload[0] << 24)
- |((unsigned int)frame.payload[1] << 16)
- |((unsigned int)frame.payload[2] << 8)
- |((unsigned int)frame.payload[3] << 0);
- uart_write(SFL_ACK_SUCCESS);
- break;
- case SFL_CMD_INITRDSTART:
- failed = 0;
- initrdstart_adr = ((unsigned int)frame.payload[0] << 24)
- |((unsigned int)frame.payload[1] << 16)
- |((unsigned int)frame.payload[2] << 8)
- |((unsigned int)frame.payload[3] << 0);
- uart_write(SFL_ACK_SUCCESS);
- break;
- case SFL_CMD_INITRDEND:
- failed = 0;
- initrdend_adr = ((unsigned int)frame.payload[0] << 24)
- |((unsigned int)frame.payload[1] << 16)
- |((unsigned int)frame.payload[2] << 8)
- |((unsigned int)frame.payload[3] << 0);
- uart_write(SFL_ACK_SUCCESS);
- break;
- default:
- failed++;
- if(failed == MAX_FAILED) {
- printf("Too many consecutive errors, aborting");
- return;
- }
- uart_write(SFL_ACK_UNKNOWN);
- break;
- }
- }
-}
-
-#ifdef CSR_ETHMAC_BASE
-
-#define LOCALIP1 192
-#define LOCALIP2 168
-#define LOCALIP3 0
-#define LOCALIP4 42
-#define REMOTEIP1 192
-#define REMOTEIP2 168
-#define REMOTEIP3 0
-#define REMOTEIP4 14
-
-static int tftp_get_v(unsigned int ip, const char *filename, char *buffer)
-{
- int r;
-
- r = tftp_get(ip, filename, buffer);
- if(r > 0)
- printf("Successfully downloaded %d bytes from %s over TFTP\n", r, filename);
- else
- printf("Unable to download %s over TFTP\n", filename);
- return r;
-}
-
-static const unsigned char macadr[6] = {0x10, 0xe2, 0xd5, 0x00, 0x00, 0x00};
-
-void netboot(void)
-{
- int size;
- unsigned int cmdline_adr, initrdstart_adr, initrdend_adr;
- unsigned int ip;
-
- printf("Booting from network...\n");
- printf("Local IP : %d.%d.%d.%d\n", LOCALIP1, LOCALIP2, LOCALIP3, LOCALIP4);
- printf("Remote IP: %d.%d.%d.%d\n", REMOTEIP1, REMOTEIP2, REMOTEIP3, REMOTEIP4);
-
- ip = IPTOINT(REMOTEIP1, REMOTEIP2, REMOTEIP3, REMOTEIP4);
-
- microudp_start(macadr, IPTOINT(LOCALIP1, LOCALIP2, LOCALIP3, LOCALIP4));
-
- if(tftp_get_v(ip, "boot.bin", (void *)MAIN_RAM_BASE) <= 0) {
- printf("Network boot failed\n");
- return;
- }
-
- cmdline_adr = MAIN_RAM_BASE+0x1000000;
- size = tftp_get_v(ip, "cmdline.txt", (void *)cmdline_adr);
- if(size <= 0) {
- printf("No command line parameters found\n");
- cmdline_adr = 0;
- } else
- *((char *)(cmdline_adr+size)) = 0x00;
-
- initrdstart_adr = MAIN_RAM_BASE+0x1002000;
- size = tftp_get_v(ip, "initrd.bin", (void *)initrdstart_adr);
- if(size <= 0) {
- printf("No initial ramdisk found\n");
- initrdstart_adr = 0;
- initrdend_adr = 0;
- } else
- initrdend_adr = initrdstart_adr + size;
-
- boot(cmdline_adr, initrdstart_adr, initrdend_adr, MAIN_RAM_BASE);
-}
-
-#endif
-
-#ifdef FLASH_BOOT_ADDRESS
-void flashboot(void)
-{
- unsigned int *flashbase;
- unsigned int length;
- unsigned int crc;
- unsigned int got_crc;
-
- printf("Booting from flash...\n");
- flashbase = (unsigned int *)FLASH_BOOT_ADDRESS;
- length = *flashbase++;
- crc = *flashbase++;
- if((length < 32) || (length > 4*1024*1024)) {
- printf("Error: Invalid flash boot image length 0x%08x\n", length);
- return;
- }
-
- printf("Loading %d bytes from flash...\n", length);
- memcpy((void *)MAIN_RAM_BASE, flashbase, length);
- got_crc = crc32((unsigned char *)MAIN_RAM_BASE, length);
- if(crc != got_crc) {
- printf("CRC failed (expected %08x, got %08x)\n", crc, got_crc);
- return;
- }
- boot(0, 0, 0, MAIN_RAM_BASE);
-}
-#endif
-
-#ifdef ROM_BOOT_ADDRESS
-/* When firmware is small enough, it can be interesting to run code from an
- embedded blockram memory (faster and not impacted by memory controller
- activity). Define ROM_BOOT_ADDRESS for that and initialize the blockram
- with the firmware data. */
-void romboot(void)
-{
- boot(0, 0, 0, ROM_BOOT_ADDRESS);
-}
-#endif
+++ /dev/null
-#ifndef __BOOT_H
-#define __BOOT_H
-
-void serialboot(void);
-void netboot(void);
-void flashboot(void);
-void romboot(void);
-
-#endif /* __BOOT_H */
+++ /dev/null
-#include <stdio.h>
-
-#include "dataflow.h"
-
-void print_isd_info(unsigned int baseaddr)
-{
- volatile unsigned int *regs;
- int neps;
- int nbytes;
- int i, j;
- int offset;
- unsigned int ack_count, nack_count, cur_status;
-
- regs = (unsigned int *)baseaddr;
- if((regs[0] != 0x6a) || (regs[1] != 0xb4)) {
- printf("Incorrect magic number\n");
- return;
- }
- neps = regs[2];
- nbytes = (regs[3] + 7)/8;
-
- regs[4] = 1; // freeze
- offset = 6; // regs[5] is reset
- for(i=0;i<neps;i++) {
- ack_count = 0;
- for(j=0;j<nbytes;j++) {
- ack_count <<= 8;
- ack_count |= regs[offset++];
- }
- nack_count = 0;
- for(j=0;j<nbytes;j++) {
- nack_count <<= 8;
- nack_count |= regs[offset++];
- }
- cur_status = regs[offset++];
- printf("#%d: ACK_CNT:%10u NAK_CNT:%10u %s %s\n",
- i, ack_count, nack_count,
- cur_status & 1 ? "stb" : " ",
- cur_status & 2 ? "ack" : " ");
- }
- regs[4] = 0; // unfreeze
-}
+++ /dev/null
-#ifndef __DATAFLOW_H
-#define __DATAFLOW_H
-
-void print_isd_info(unsigned int baseaddr);
-
-#endif /* __DATAFLOW_H */
-
+++ /dev/null
-#include <generated/csr.h>
-#include <irq.h>
-#include <uart.h>
-
-void isr(void);
-void isr(void)
-{
- unsigned int irqs;
-
- irqs = irq_pending() & irq_getmask();
-
- if(irqs & (1 << UART_INTERRUPT))
- uart_isr();
-}
+++ /dev/null
-INCLUDE generated/output_format.ld
-ENTRY(_start)
-
-INCLUDE generated/regions.ld
-
-SECTIONS
-{
- .text :
- {
- _ftext = .;
- *(.text .stub .text.* .gnu.linkonce.t.*)
- _etext = .;
- } > rom
-
- .rodata :
- {
- . = ALIGN(4);
- _frodata = .;
- *(.rodata .rodata.* .gnu.linkonce.r.*)
- *(.rodata1)
-
- /* Make sure the file is aligned on disk as well
- as in memory; CRC calculation requires that. */
- FILL(0);
- . = ALIGN(4);
- _erodata = .;
- } > rom
-
- .bss :
- {
- . = ALIGN(4);
- _fbss = .;
- *(.dynsbss)
- *(.sbss .sbss.* .gnu.linkonce.sb.*)
- *(.scommon)
- *(.dynbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- . = ALIGN(4);
- _ebss = .;
- _end = .;
- } > sram
-
- /DISCARD/ :
- {
- *(.eh_frame)
- *(.comment)
- *(.data .data.* .gnu.linkonce.d.*)
- *(.data1)
- *(.sdata .sdata.* .gnu.linkonce.s.*)
- }
-}
-
-PROVIDE(_fstack = ORIGIN(sram) + LENGTH(sram) - 4);
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <console.h>
-#include <string.h>
-#include <uart.h>
-#include <system.h>
-#include <id.h>
-#include <irq.h>
-#include <crc.h>
-
-#include <generated/csr.h>
-#include <generated/mem.h>
-#include <net/microudp.h>
-
-#include "sdram.h"
-#include "dataflow.h"
-#include "boot.h"
-
-/* General address space functions */
-
-#define NUMBER_OF_BYTES_ON_A_LINE 16
-static void dump_bytes(unsigned int *ptr, int count, unsigned addr)
-{
- char *data = (char *)ptr;
- int line_bytes = 0, i = 0;
-
- putsnonl("Memory dump:");
- while(count > 0){
- line_bytes =
- (count > NUMBER_OF_BYTES_ON_A_LINE)?
- NUMBER_OF_BYTES_ON_A_LINE : count;
-
- printf("\n0x%08x ", addr);
- for(i=0;i<line_bytes;i++)
- printf("%02x ", *(unsigned char *)(data+i));
-
- for(;i<NUMBER_OF_BYTES_ON_A_LINE;i++)
- printf(" ");
-
- printf(" ");
-
- for(i=0;i<line_bytes;i++) {
- if((*(data+i) < 0x20) || (*(data+i) > 0x7e))
- printf(".");
- else
- printf("%c", *(data+i));
- }
-
- for(;i<NUMBER_OF_BYTES_ON_A_LINE;i++)
- printf(" ");
-
- data += (char)line_bytes;
- count -= line_bytes;
- addr += line_bytes;
- }
- printf("\n");
-}
-
-static void mr(char *startaddr, char *len)
-{
- char *c;
- unsigned int *addr;
- unsigned int length;
-
- if(*startaddr == 0) {
- printf("mr <address> [length]\n");
- return;
- }
- addr = (unsigned *)strtoul(startaddr, &c, 0);
- if(*c != 0) {
- printf("incorrect address\n");
- return;
- }
- if(*len == 0) {
- length = 4;
- } else {
- length = strtoul(len, &c, 0);
- if(*c != 0) {
- printf("incorrect length\n");
- return;
- }
- }
-
- dump_bytes(addr, length, (unsigned)addr);
-}
-
-static void mw(char *addr, char *value, char *count)
-{
- char *c;
- unsigned int *addr2;
- unsigned int value2;
- unsigned int count2;
- unsigned int i;
-
- if((*addr == 0) || (*value == 0)) {
- printf("mw <address> <value> [count]\n");
- return;
- }
- addr2 = (unsigned int *)strtoul(addr, &c, 0);
- if(*c != 0) {
- printf("incorrect address\n");
- return;
- }
- value2 = strtoul(value, &c, 0);
- if(*c != 0) {
- printf("incorrect value\n");
- return;
- }
- if(*count == 0) {
- count2 = 1;
- } else {
- count2 = strtoul(count, &c, 0);
- if(*c != 0) {
- printf("incorrect count\n");
- return;
- }
- }
- for (i=0;i<count2;i++) *addr2++ = value2;
-}
-
-static void mc(char *dstaddr, char *srcaddr, char *count)
-{
- char *c;
- unsigned int *dstaddr2;
- unsigned int *srcaddr2;
- unsigned int count2;
- unsigned int i;
-
- if((*dstaddr == 0) || (*srcaddr == 0)) {
- printf("mc <dst> <src> [count]\n");
- return;
- }
- dstaddr2 = (unsigned int *)strtoul(dstaddr, &c, 0);
- if(*c != 0) {
- printf("incorrect destination address\n");
- return;
- }
- srcaddr2 = (unsigned int *)strtoul(srcaddr, &c, 0);
- if(*c != 0) {
- printf("incorrect source address\n");
- return;
- }
- if(*count == 0) {
- count2 = 1;
- } else {
- count2 = strtoul(count, &c, 0);
- if(*c != 0) {
- printf("incorrect count\n");
- return;
- }
- }
- for (i=0;i<count2;i++) *dstaddr2++ = *srcaddr2++;
-}
-
-static void crc(char *startaddr, char *len)
-{
- char *c;
- char *addr;
- unsigned int length;
-
- if((*startaddr == 0)||(*len == 0)) {
- printf("crc <address> <length>\n");
- return;
- }
- addr = (char *)strtoul(startaddr, &c, 0);
- if(*c != 0) {
- printf("incorrect address\n");
- return;
- }
- length = strtoul(len, &c, 0);
- if(*c != 0) {
- printf("incorrect length\n");
- return;
- }
-
- printf("CRC32: %08x\n", crc32((unsigned char *)addr, length));
-}
-
-#ifdef __lm32__
-enum {
- CSR_IE = 1, CSR_IM, CSR_IP, CSR_ICC, CSR_DCC, CSR_CC, CSR_CFG, CSR_EBA,
- CSR_DC, CSR_DEBA, CSR_JTX, CSR_JRX, CSR_BP0, CSR_BP1, CSR_BP2, CSR_BP3,
- CSR_WP0, CSR_WP1, CSR_WP2, CSR_WP3,
-};
-
-/* processor registers */
-static int parse_csr(const char *csr)
-{
- if(!strcmp(csr, "ie")) return CSR_IE;
- if(!strcmp(csr, "im")) return CSR_IM;
- if(!strcmp(csr, "ip")) return CSR_IP;
- if(!strcmp(csr, "icc")) return CSR_ICC;
- if(!strcmp(csr, "dcc")) return CSR_DCC;
- if(!strcmp(csr, "cc")) return CSR_CC;
- if(!strcmp(csr, "cfg")) return CSR_CFG;
- if(!strcmp(csr, "eba")) return CSR_EBA;
- if(!strcmp(csr, "dc")) return CSR_DC;
- if(!strcmp(csr, "deba")) return CSR_DEBA;
- if(!strcmp(csr, "jtx")) return CSR_JTX;
- if(!strcmp(csr, "jrx")) return CSR_JRX;
- if(!strcmp(csr, "bp0")) return CSR_BP0;
- if(!strcmp(csr, "bp1")) return CSR_BP1;
- if(!strcmp(csr, "bp2")) return CSR_BP2;
- if(!strcmp(csr, "bp3")) return CSR_BP3;
- if(!strcmp(csr, "wp0")) return CSR_WP0;
- if(!strcmp(csr, "wp1")) return CSR_WP1;
- if(!strcmp(csr, "wp2")) return CSR_WP2;
- if(!strcmp(csr, "wp3")) return CSR_WP3;
-
- return 0;
-}
-
-static void rcsr(char *csr)
-{
- unsigned int csr2;
- register unsigned int value;
-
- if(*csr == 0) {
- printf("rcsr <csr>\n");
- return;
- }
-
- csr2 = parse_csr(csr);
- if(csr2 == 0) {
- printf("incorrect csr\n");
- return;
- }
-
- switch(csr2) {
- case CSR_IE: asm volatile ("rcsr %0,ie":"=r"(value)); break;
- case CSR_IM: asm volatile ("rcsr %0,im":"=r"(value)); break;
- case CSR_IP: asm volatile ("rcsr %0,ip":"=r"(value)); break;
- case CSR_CC: asm volatile ("rcsr %0,cc":"=r"(value)); break;
- case CSR_CFG: asm volatile ("rcsr %0,cfg":"=r"(value)); break;
- case CSR_EBA: asm volatile ("rcsr %0,eba":"=r"(value)); break;
- case CSR_DEBA: asm volatile ("rcsr %0,deba":"=r"(value)); break;
- case CSR_JTX: asm volatile ("rcsr %0,jtx":"=r"(value)); break;
- case CSR_JRX: asm volatile ("rcsr %0,jrx":"=r"(value)); break;
- default: printf("csr write only\n"); return;
- }
-
- printf("%08x\n", value);
-}
-
-static void wcsr(char *csr, char *value)
-{
- char *c;
- unsigned int csr2;
- register unsigned int value2;
-
- if((*csr == 0) || (*value == 0)) {
- printf("wcsr <csr> <address>\n");
- return;
- }
-
- csr2 = parse_csr(csr);
- if(csr2 == 0) {
- printf("incorrect csr\n");
- return;
- }
- value2 = strtoul(value, &c, 0);
- if(*c != 0) {
- printf("incorrect value\n");
- return;
- }
-
- switch(csr2) {
- case CSR_IE: asm volatile ("wcsr ie,%0"::"r"(value2)); break;
- case CSR_IM: asm volatile ("wcsr im,%0"::"r"(value2)); break;
- case CSR_ICC: asm volatile ("wcsr icc,%0"::"r"(value2)); break;
- case CSR_DCC: asm volatile ("wcsr dcc,%0"::"r"(value2)); break;
- case CSR_EBA: asm volatile ("wcsr eba,%0"::"r"(value2)); break;
- case CSR_DC: asm volatile ("wcsr dcc,%0"::"r"(value2)); break;
- case CSR_DEBA: asm volatile ("wcsr deba,%0"::"r"(value2)); break;
- case CSR_JTX: asm volatile ("wcsr jtx,%0"::"r"(value2)); break;
- case CSR_JRX: asm volatile ("wcsr jrx,%0"::"r"(value2)); break;
- case CSR_BP0: asm volatile ("wcsr bp0,%0"::"r"(value2)); break;
- case CSR_BP1: asm volatile ("wcsr bp1,%0"::"r"(value2)); break;
- case CSR_BP2: asm volatile ("wcsr bp2,%0"::"r"(value2)); break;
- case CSR_BP3: asm volatile ("wcsr bp3,%0"::"r"(value2)); break;
- case CSR_WP0: asm volatile ("wcsr wp0,%0"::"r"(value2)); break;
- case CSR_WP1: asm volatile ("wcsr wp1,%0"::"r"(value2)); break;
- case CSR_WP2: asm volatile ("wcsr wp2,%0"::"r"(value2)); break;
- case CSR_WP3: asm volatile ("wcsr wp3,%0"::"r"(value2)); break;
- default: printf("csr read only\n"); return;
- }
-}
-
-#endif /* __lm32__ */
-
-static void dfs(char *baseaddr)
-{
- char *c;
- unsigned int addr;
-
- if(*baseaddr == 0) {
- printf("dfs <address>\n");
- return;
- }
- addr = strtoul(baseaddr, &c, 0);
- if(*c != 0) {
- printf("incorrect address\n");
- return;
- }
- print_isd_info(addr);
-}
-
-/* Init + command line */
-
-static void help(void)
-{
- puts("MiSoC BIOS");
- puts("Available commands:");
- puts("mr - read address space");
- puts("mw - write address space");
- puts("mc - copy address space");
- puts("crc - compute CRC32 of a part of the address space");
-#ifdef __lm32__
- puts("rcsr - read processor CSR");
- puts("wcsr - write processor CSR");
-#endif
-#ifdef CSR_ETHMAC_BASE
- puts("netboot - boot via TFTP");
-#endif
- puts("serialboot - boot via SFL");
-#ifdef FLASH_BOOT_ADDRESS
- puts("flashboot - boot from flash");
-#endif
-#ifdef ROM_BOOT_ADDRESS
- puts("romboot - boot from embedded rom");
-#endif
- puts("revision - display revision");
-#ifdef CSR_SDRAM_BASE
- puts("memtest - run a memory test");
-#endif
-}
-
-static char *get_token(char **str)
-{
- char *c, *d;
-
- c = (char *)strchr(*str, ' ');
- if(c == NULL) {
- d = *str;
- *str = *str+strlen(*str);
- return d;
- }
- *c = 0;
- d = *str;
- *str = c+1;
- return d;
-}
-
-static void do_command(char *c)
-{
- char *token;
-
- token = get_token(&c);
-
- if(strcmp(token, "mr") == 0) mr(get_token(&c), get_token(&c));
- else if(strcmp(token, "mw") == 0) mw(get_token(&c), get_token(&c), get_token(&c));
- else if(strcmp(token, "mc") == 0) mc(get_token(&c), get_token(&c), get_token(&c));
- else if(strcmp(token, "crc") == 0) crc(get_token(&c), get_token(&c));
-
-#ifdef L2_SIZE
- else if(strcmp(token, "flushl2") == 0) flush_l2_cache();
-#endif
-
-#ifdef FLASH_BOOT_ADDRESS
- else if(strcmp(token, "flashboot") == 0) flashboot();
-#endif
-#ifdef ROM_BOOT_ADDRESS
- else if(strcmp(token, "romboot") == 0) romboot();
-#endif
- else if(strcmp(token, "serialboot") == 0) serialboot();
-#ifdef CSR_ETHMAC_BASE
- else if(strcmp(token, "netboot") == 0) netboot();
-#endif
-
- else if(strcmp(token, "help") == 0) help();
-
-#ifdef __lm32__
- else if(strcmp(token, "rcsr") == 0) rcsr(get_token(&c));
- else if(strcmp(token, "wcsr") == 0) wcsr(get_token(&c), get_token(&c));
-#endif
-
-#ifdef CSR_SDRAM_BASE
- else if(strcmp(token, "sdrrow") == 0) sdrrow(get_token(&c));
- else if(strcmp(token, "sdrsw") == 0) sdrsw();
- else if(strcmp(token, "sdrhw") == 0) sdrhw();
- else if(strcmp(token, "sdrrdbuf") == 0) sdrrdbuf(-1);
- else if(strcmp(token, "sdrrd") == 0) sdrrd(get_token(&c), get_token(&c));
- else if(strcmp(token, "sdrrderr") == 0) sdrrderr(get_token(&c));
- else if(strcmp(token, "sdrwr") == 0) sdrwr(get_token(&c));
-#ifdef CSR_DDRPHY_BASE
- else if(strcmp(token, "sdrwlon") == 0) sdrwlon();
- else if(strcmp(token, "sdrwloff") == 0) sdrwloff();
- else if(strcmp(token, "sdrlevel") == 0) sdrlevel();
-#endif
- else if(strcmp(token, "memtest") == 0) memtest();
- else if(strcmp(token, "sdrinit") == 0) sdrinit();
-#endif
-
- else if(strcmp(token, "dfs") == 0) dfs(get_token(&c));
-
- else if(strcmp(token, "") != 0)
- printf("Command not found\n");
-}
-
-extern unsigned int _ftext, _erodata;
-
-static void crcbios(void)
-{
- unsigned int offset_bios;
- unsigned int length;
- unsigned int expected_crc;
- unsigned int actual_crc;
-
- /*
- * _erodata is located right after the end of the flat
- * binary image. The CRC tool writes the 32-bit CRC here.
- * We also use the address of _erodata to know the length
- * of our code.
- */
- offset_bios = (unsigned int)&_ftext;
- expected_crc = _erodata;
- length = (unsigned int)&_erodata - offset_bios;
- actual_crc = crc32((unsigned char *)offset_bios, length);
- if(expected_crc == actual_crc)
- printf("BIOS CRC passed (%08x)\n", actual_crc);
- else {
- printf("BIOS CRC failed (expected %08x, got %08x)\n", expected_crc, actual_crc);
- printf("The system will continue, but expect problems.\n");
- }
-}
-
-static void readstr(char *s, int size)
-{
- char c[2];
- int ptr;
-
- c[1] = 0;
- ptr = 0;
- while(1) {
- c[0] = readchar();
- switch(c[0]) {
- case 0x7f:
- case 0x08:
- if(ptr > 0) {
- ptr--;
- putsnonl("\x08 \x08");
- }
- break;
- case 0x07:
- break;
- case '\r':
- case '\n':
- s[ptr] = 0x00;
- putsnonl("\n");
- return;
- default:
- putsnonl(c);
- s[ptr] = c[0];
- ptr++;
- break;
- }
- }
-}
-
-static int test_user_abort(void)
-{
- char c;
-
- printf("Automatic boot in 2 seconds...\n");
- printf("Q/ESC: abort boot\n");
- printf("F7: boot from serial\n");
-#ifdef CSR_ETHMAC_BASE
- printf("F8: boot from network\n");
-#endif
- timer0_en_write(0);
- timer0_reload_write(0);
- timer0_load_write(identifier_frequency_read()*2);
- timer0_en_write(1);
- timer0_update_value_write(1);
- while(timer0_value_read()) {
- if(readchar_nonblock()) {
- c = readchar();
- if((c == 'Q')||(c == '\e')) {
- puts("Aborted");
- return 0;
- }
- if(c == 0x06) {
- serialboot();
- return 0;
- }
-#ifdef CSR_ETHMAC_BASE
- if(c == 0x07) {
- netboot();
- return 0;
- }
-#endif
- }
- timer0_update_value_write(1);
- }
- return 1;
-}
-
-static void boot_sequence(void)
-{
- if(test_user_abort()) {
-#ifdef FLASH_BOOT_ADDRESS
- flashboot();
-#endif
- serialboot();
-#ifdef CSR_ETHMAC_BASE
-#ifdef CSR_ETHPHY_MODE_DETECTION_MODE_ADDR
- eth_mode();
-#endif
- netboot();
-#endif
-#ifdef ROM_BOOT_ADDRESS
- romboot();
-#endif
- printf("No boot medium found\n");
- }
-}
-
-int main(int i, char **c)
-{
- char buffer[64];
- int sdr_ok;
-
- irq_setmask(0);
- irq_setie(1);
- uart_init();
- puts("\nMiSoC BIOS\n"
- "(c) Copyright 2007-2015 M-Labs Limited\n"
- "Built "__DATE__" "__TIME__"\n");
- crcbios();
- id_print();
-#ifdef CSR_ETHMAC_BASE
- eth_init();
-#endif
-#ifdef CSR_SDRAM_BASE
- sdr_ok = sdrinit();
-#else
- sdr_ok = 1;
-#endif
- if(sdr_ok)
- boot_sequence();
- else
- printf("Memory initialization failed\n");
-
- while(1) {
- putsnonl("\e[1mBIOS>\e[0m ");
- readstr(buffer, 64);
- do_command(buffer);
- }
- return 0;
-}
+++ /dev/null
-#include <generated/csr.h>
-#ifdef CSR_SDRAM_BASE
-
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <generated/sdram_phy.h>
-#include <generated/mem.h>
-#include <hw/flags.h>
-#include <system.h>
-
-#include "sdram.h"
-
-static void cdelay(int i)
-{
- while(i > 0) {
-#if defined (__lm32__)
- __asm__ volatile("nop");
-#elif defined (__or1k__)
- __asm__ volatile("l.nop");
-#else
-#error Unsupported architecture
-#endif
- i--;
- }
-}
-
-void sdrsw(void)
-{
- sdram_dfii_control_write(DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N);
- printf("SDRAM now under software control\n");
-}
-
-void sdrhw(void)
-{
- sdram_dfii_control_write(DFII_CONTROL_SEL);
- printf("SDRAM now under hardware control\n");
-}
-
-void sdrrow(char *_row)
-{
- char *c;
- unsigned int row;
-
- if(*_row == 0) {
- sdram_dfii_pi0_address_write(0x0000);
- sdram_dfii_pi0_baddress_write(0);
- command_p0(DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
- cdelay(15);
- printf("Precharged\n");
- } else {
- row = strtoul(_row, &c, 0);
- if(*c != 0) {
- printf("incorrect row\n");
- return;
- }
- sdram_dfii_pi0_address_write(row);
- sdram_dfii_pi0_baddress_write(0);
- command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CS);
- cdelay(15);
- printf("Activated row %d\n", row);
- }
-}
-
-void sdrrdbuf(int dq)
-{
- int i, p;
- int first_byte, step;
-
- if(dq < 0) {
- first_byte = 0;
- step = 1;
- } else {
- first_byte = DFII_PIX_DATA_SIZE/2 - 1 - dq;
- step = DFII_PIX_DATA_SIZE/2;
- }
-
- for(p=0;p<DFII_NPHASES;p++)
- for(i=first_byte;i<DFII_PIX_DATA_SIZE;i+=step)
- printf("%02x", MMPTR(sdram_dfii_pix_rddata_addr[p]+4*i));
- printf("\n");
-}
-
-void sdrrd(char *startaddr, char *dq)
-{
- char *c;
- unsigned int addr;
- int _dq;
-
- if(*startaddr == 0) {
- printf("sdrrd <address>\n");
- return;
- }
- addr = strtoul(startaddr, &c, 0);
- if(*c != 0) {
- printf("incorrect address\n");
- return;
- }
- if(*dq == 0)
- _dq = -1;
- else {
- _dq = strtoul(dq, &c, 0);
- if(*c != 0) {
- printf("incorrect DQ\n");
- return;
- }
- }
-
- sdram_dfii_pird_address_write(addr);
- sdram_dfii_pird_baddress_write(0);
- command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
- cdelay(15);
- sdrrdbuf(_dq);
-}
-
-void sdrrderr(char *count)
-{
- int addr;
- char *c;
- int _count;
- int i, j, p;
- unsigned char prev_data[DFII_NPHASES*DFII_PIX_DATA_SIZE];
- unsigned char errs[DFII_NPHASES*DFII_PIX_DATA_SIZE];
-
- if(*count == 0) {
- printf("sdrrderr <count>\n");
- return;
- }
- _count = strtoul(count, &c, 0);
- if(*c != 0) {
- printf("incorrect count\n");
- return;
- }
-
- for(i=0;i<DFII_NPHASES*DFII_PIX_DATA_SIZE;i++)
- errs[i] = 0;
- for(addr=0;addr<16;addr++) {
- sdram_dfii_pird_address_write(addr*8);
- sdram_dfii_pird_baddress_write(0);
- command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
- cdelay(15);
- for(p=0;p<DFII_NPHASES;p++)
- for(i=0;i<DFII_PIX_DATA_SIZE;i++)
- prev_data[p*DFII_PIX_DATA_SIZE+i] = MMPTR(sdram_dfii_pix_rddata_addr[p]+4*i);
-
- for(j=0;j<_count;j++) {
- command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
- cdelay(15);
- for(p=0;p<DFII_NPHASES;p++)
- for(i=0;i<DFII_PIX_DATA_SIZE;i++) {
- unsigned char new_data;
-
- new_data = MMPTR(sdram_dfii_pix_rddata_addr[p]+4*i);
- errs[p*DFII_PIX_DATA_SIZE+i] |= prev_data[p*DFII_PIX_DATA_SIZE+i] ^ new_data;
- prev_data[p*DFII_PIX_DATA_SIZE+i] = new_data;
- }
- }
- }
-
- for(i=0;i<DFII_NPHASES*DFII_PIX_DATA_SIZE;i++)
- printf("%02x", errs[i]);
- printf("\n");
- for(p=0;p<DFII_NPHASES;p++)
- for(i=0;i<DFII_PIX_DATA_SIZE;i++)
- printf("%2x", DFII_PIX_DATA_SIZE/2 - 1 - (i % (DFII_PIX_DATA_SIZE/2)));
- printf("\n");
-}
-
-void sdrwr(char *startaddr)
-{
- char *c;
- unsigned int addr;
- int i;
- int p;
-
- if(*startaddr == 0) {
- printf("sdrrd <address>\n");
- return;
- }
- addr = strtoul(startaddr, &c, 0);
- if(*c != 0) {
- printf("incorrect address\n");
- return;
- }
-
- for(p=0;p<DFII_NPHASES;p++)
- for(i=0;i<DFII_PIX_DATA_SIZE;i++)
- MMPTR(sdram_dfii_pix_wrdata_addr[p]+4*i) = 0x10*p + i;
-
- sdram_dfii_piwr_address_write(addr);
- sdram_dfii_piwr_baddress_write(0);
- command_pwr(DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS|DFII_COMMAND_WRDATA);
-}
-
-#ifdef CSR_DDRPHY_BASE
-
-void sdrwlon(void)
-{
- sdram_dfii_pi0_address_write(DDR3_MR1 | (1 << 7));
- sdram_dfii_pi0_baddress_write(1);
- command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
- ddrphy_wlevel_en_write(1);
-}
-
-void sdrwloff(void)
-{
- sdram_dfii_pi0_address_write(DDR3_MR1);
- sdram_dfii_pi0_baddress_write(1);
- command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
- ddrphy_wlevel_en_write(0);
-}
-
-#define ERR_DDRPHY_DELAY 32
-
-static int write_level(int *delay, int *high_skew)
-{
- int i;
- int dq_address;
- unsigned char dq;
- int ok;
-
- printf("Write leveling: ");
-
- sdrwlon();
- cdelay(100);
- for(i=0;i<DFII_PIX_DATA_SIZE/2;i++) {
- dq_address = sdram_dfii_pix_rddata_addr[0]+4*(DFII_PIX_DATA_SIZE/2-1-i);
- ddrphy_dly_sel_write(1 << i);
- ddrphy_wdly_dq_rst_write(1);
- ddrphy_wdly_dqs_rst_write(1);
-
- delay[i] = 0;
-
- ddrphy_wlevel_strobe_write(1);
- cdelay(10);
- dq = MMPTR(dq_address);
- if(dq != 0) {
- /*
- * Assume this DQ group has between 1 and 2 bit times of skew.
- * Bring DQS into the CK=0 zone before continuing leveling.
- */
- high_skew[i] = 1;
- while(dq != 0) {
- delay[i]++;
- if(delay[i] >= ERR_DDRPHY_DELAY)
- break;
- ddrphy_wdly_dq_inc_write(1);
- ddrphy_wdly_dqs_inc_write(1);
- ddrphy_wlevel_strobe_write(1);
- cdelay(10);
- dq = MMPTR(dq_address);
- }
- } else
- high_skew[i] = 0;
-
- while(dq == 0) {
- delay[i]++;
- if(delay[i] >= ERR_DDRPHY_DELAY)
- break;
- ddrphy_wdly_dq_inc_write(1);
- ddrphy_wdly_dqs_inc_write(1);
-
- ddrphy_wlevel_strobe_write(1);
- cdelay(10);
- dq = MMPTR(dq_address);
- }
- }
- sdrwloff();
-
- ok = 1;
- for(i=DFII_PIX_DATA_SIZE/2-1;i>=0;i--) {
- printf("%2d%c ", delay[i], high_skew[i] ? '*' : ' ');
- if(delay[i] >= ERR_DDRPHY_DELAY)
- ok = 0;
- }
-
- if(ok)
- printf("completed\n");
- else
- printf("failed\n");
-
- return ok;
-}
-
-static void read_bitslip(int *delay, int *high_skew)
-{
- int bitslip_thr;
- int i;
-
- bitslip_thr = 0x7fffffff;
- for(i=0;i<DFII_PIX_DATA_SIZE/2;i++)
- if(high_skew[i] && (delay[i] < bitslip_thr))
- bitslip_thr = delay[i];
- if(bitslip_thr == 0x7fffffff)
- return;
- bitslip_thr = bitslip_thr/2;
-
- printf("Read bitslip: ");
- for(i=DFII_PIX_DATA_SIZE/2-1;i>=0;i--)
- if(delay[i] > bitslip_thr) {
- ddrphy_dly_sel_write(1 << i);
- /* 7-series SERDES in DDR mode needs 3 pulses for 1 bitslip */
- ddrphy_rdly_dq_bitslip_write(1);
- ddrphy_rdly_dq_bitslip_write(1);
- ddrphy_rdly_dq_bitslip_write(1);
- printf("%d ", i);
- }
- printf("\n");
-}
-
-static void read_delays(void)
-{
- unsigned int prv;
- unsigned char prs[DFII_NPHASES*DFII_PIX_DATA_SIZE];
- int p, i, j;
- int working;
- int delay, delay_min, delay_max;
-
- printf("Read delays: ");
-
- /* Generate pseudo-random sequence */
- prv = 42;
- for(i=0;i<DFII_NPHASES*DFII_PIX_DATA_SIZE;i++) {
- prv = 1664525*prv + 1013904223;
- prs[i] = prv;
- }
-
- /* Activate */
- sdram_dfii_pi0_address_write(0);
- sdram_dfii_pi0_baddress_write(0);
- command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CS);
- cdelay(15);
-
- /* Write test pattern */
- for(p=0;p<DFII_NPHASES;p++)
- for(i=0;i<DFII_PIX_DATA_SIZE;i++)
- MMPTR(sdram_dfii_pix_wrdata_addr[p]+4*i) = prs[DFII_PIX_DATA_SIZE*p+i];
- sdram_dfii_piwr_address_write(0);
- sdram_dfii_piwr_baddress_write(0);
- command_pwr(DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS|DFII_COMMAND_WRDATA);
-
- /* Calibrate each DQ in turn */
- sdram_dfii_pird_address_write(0);
- sdram_dfii_pird_baddress_write(0);
- for(i=0;i<DFII_PIX_DATA_SIZE/2;i++) {
- ddrphy_dly_sel_write(1 << (DFII_PIX_DATA_SIZE/2-i-1));
- delay = 0;
-
- /* Find smallest working delay */
- ddrphy_rdly_dq_rst_write(1);
- while(1) {
- command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
- cdelay(15);
- working = 1;
- for(p=0;p<DFII_NPHASES;p++) {
- if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*i) != prs[DFII_PIX_DATA_SIZE*p+i])
- working = 0;
- if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*(i+DFII_PIX_DATA_SIZE/2)) != prs[DFII_PIX_DATA_SIZE*p+i+DFII_PIX_DATA_SIZE/2])
- working = 0;
- }
- if(working)
- break;
- delay++;
- if(delay >= ERR_DDRPHY_DELAY)
- break;
- ddrphy_rdly_dq_inc_write(1);
- }
- delay_min = delay;
-
- /* Get a bit further into the working zone */
- delay++;
- ddrphy_rdly_dq_inc_write(1);
-
- /* Find largest working delay */
- while(1) {
- command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
- cdelay(15);
- working = 1;
- for(p=0;p<DFII_NPHASES;p++) {
- if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*i) != prs[DFII_PIX_DATA_SIZE*p+i])
- working = 0;
- if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*(i+DFII_PIX_DATA_SIZE/2)) != prs[DFII_PIX_DATA_SIZE*p+i+DFII_PIX_DATA_SIZE/2])
- working = 0;
- }
- if(!working)
- break;
- delay++;
- if(delay >= ERR_DDRPHY_DELAY)
- break;
- ddrphy_rdly_dq_inc_write(1);
- }
- delay_max = delay;
-
- printf("%d:%02d-%02d ", DFII_PIX_DATA_SIZE/2-i-1, delay_min, delay_max);
-
- /* Set delay to the middle */
- ddrphy_rdly_dq_rst_write(1);
- for(j=0;j<(delay_min+delay_max)/2;j++)
- ddrphy_rdly_dq_inc_write(1);
- }
-
- /* Precharge */
- sdram_dfii_pi0_address_write(0);
- sdram_dfii_pi0_baddress_write(0);
- command_p0(DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
- cdelay(15);
-
- printf("completed\n");
-}
-
-int sdrlevel(void)
-{
- int delay[DFII_PIX_DATA_SIZE/2];
- int high_skew[DFII_PIX_DATA_SIZE/2];
-
- if(!write_level(delay, high_skew))
- return 0;
- read_bitslip(delay, high_skew);
- read_delays();
-
- return 1;
-}
-
-#endif /* CSR_DDRPHY_BASE */
-
-#define TEST_DATA_SIZE (2*1024*1024)
-#define TEST_DATA_RANDOM 1
-
-#define TEST_ADDR_SIZE (32*1024)
-#define TEST_ADDR_RANDOM 0
-
-#define ONEZERO 0xAAAAAAAA
-#define ZEROONE 0x55555555
-
-static unsigned int seed_to_data_32(unsigned int seed, int random)
-{
- if (random)
- return 1664525*seed + 1013904223;
- else
- return seed + 1;
-}
-
-static unsigned short seed_to_data_16(unsigned short seed, int random)
-{
- if (random)
- return 25173*seed + 13849;
- else
- return seed + 1;
-}
-
-int memtest_silent(void)
-{
- volatile unsigned int *array = (unsigned int *)MAIN_RAM_BASE;
- int i;
- unsigned int seed_32;
- unsigned short seed_16;
- unsigned int error_cnt;
-
- error_cnt = 0;
-
- /* test data bus */
- for(i=0;i<128;i++) {
- array[i] = ONEZERO;
- }
- flush_cpu_dcache();
- flush_l2_cache();
- for(i=0;i<128;i++) {
- if(array[i] != ONEZERO)
- error_cnt++;
- }
-
- for(i=0;i<128;i++) {
- array[i] = ZEROONE;
- }
- flush_cpu_dcache();
- flush_l2_cache();
- for(i=0;i<128;i++) {
- if(array[i] != ZEROONE)
- error_cnt++;
- }
-
- /* test counter or random data */
- seed_32 = 0;
- for(i=0;i<TEST_DATA_SIZE/4;i++) {
- seed_32 = seed_to_data_32(seed_32, TEST_DATA_RANDOM);
- array[i] = seed_32;
- }
-
- seed_32 = 0;
- flush_cpu_dcache();
- flush_l2_cache();
- for(i=0;i<TEST_DATA_SIZE/4;i++) {
- seed_32 = seed_to_data_32(seed_32, TEST_DATA_RANDOM);
- if(array[i] != seed_32)
- error_cnt++;
- }
-
- /* test random addressing */
- seed_16 = 0;
- for(i=0;i<TEST_ADDR_SIZE/4;i++) {
- seed_16 = seed_to_data_16(seed_16, TEST_ADDR_RANDOM);
- array[(unsigned int) seed_16] = i;
- }
-
- seed_16 = 0;
- flush_cpu_dcache();
- flush_l2_cache();
- for(i=0;i<TEST_ADDR_SIZE/4;i++) {
- seed_16 = seed_to_data_16(seed_16, TEST_ADDR_RANDOM);
- if(array[(unsigned int) seed_16] != i)
- error_cnt++;
- }
-
- return error_cnt;
-}
-
-int memtest(void)
-{
- unsigned int e;
-
- e = memtest_silent();
- if(e != 0) {
- printf("Memtest failed: %d/%d words incorrect\n", e, 2*128 + TEST_DATA_SIZE/4 + TEST_ADDR_SIZE/4);
- return 0;
- } else {
- printf("Memtest OK\n");
- return 1;
- }
-}
-
-int sdrinit(void)
-{
- printf("Initializing SDRAM...\n");
-
- init_sequence();
-#ifdef CSR_DDRPHY_BASE
- if(!sdrlevel())
- return 0;
-#endif
- sdram_dfii_control_write(DFII_CONTROL_SEL);
- if(!memtest())
- return 0;
-
- return 1;
-}
-
-#endif
+++ /dev/null
-#ifndef __SDRAM_H
-#define __SDRAM_H
-
-#include <generated/csr.h>
-
-void sdrsw(void);
-void sdrhw(void);
-void sdrrow(char *_row);
-void sdrrdbuf(int dq);
-void sdrrd(char *startaddr, char *dq);
-void sdrrderr(char *count);
-void sdrwr(char *startaddr);
-
-#ifdef CSR_DDRPHY_BASE
-void sdrwlon(void);
-void sdrwloff(void);
-int sdrlevel(void);
-#endif
-
-int memtest_silent(void);
-int memtest(void);
-int sdrinit(void);
-
-#endif /* __SDRAM_H */
+++ /dev/null
-#ifndef __SFL_H
-#define __SFL_H
-
-#define SFL_MAGIC_LEN 14
-#define SFL_MAGIC_REQ "sL5DdSMmkekro\n"
-#define SFL_MAGIC_ACK "z6IHG7cYDID6o\n"
-
-struct sfl_frame {
- unsigned char length;
- unsigned char crc[2];
- unsigned char cmd;
- unsigned char payload[255];
-} __attribute__((packed));
-
-/* General commands */
-#define SFL_CMD_ABORT 0x00
-#define SFL_CMD_LOAD 0x01
-#define SFL_CMD_JUMP 0x02
-
-/* Linux-specific commands */
-#define SFL_CMD_CMDLINE 0x03
-#define SFL_CMD_INITRDSTART 0x04
-#define SFL_CMD_INITRDEND 0x05
-
-/* Replies */
-#define SFL_ACK_SUCCESS 'K'
-#define SFL_ACK_CRCERROR 'C'
-#define SFL_ACK_UNKNOWN 'U'
-#define SFL_ACK_ERROR 'E'
-
-#endif /* __SFL_H */
+++ /dev/null
-TARGET_PREFIX=$(TRIPLE)-
-
-RM ?= rm -f
-PYTHON ?= python3
-
-ifeq ($(CLANG),1)
-CC_normal := clang -target $(TRIPLE) -integrated-as
-CX_normal := clang++ -target $(TRIPLE) -integrated-as
-else
-CC_normal := $(TARGET_PREFIX)gcc
-CX_normal := $(TARGET_PREFIX)g++
-endif
-AR_normal := $(TARGET_PREFIX)ar
-LD_normal := $(TARGET_PREFIX)ld
-OBJCOPY_normal := $(TARGET_PREFIX)objcopy
-
-CC_quiet = @echo " CC " $@ && $(CC_normal)
-CX_quiet = @echo " CX " $@ && $(CX_normal)
-AR_quiet = @echo " AR " $@ && $(AR_normal)
-LD_quiet = @echo " LD " $@ && $(LD_normal)
-OBJCOPY_quiet = @echo " OBJCOPY " $@ && $(OBJCOPY_normal)
-
-ifeq ($(V),1)
- CC = $(CC_normal)
- CX = $(CX_normal)
- AR = $(AR_normal)
- LD = $(LD_normal)
- OBJCOPY = $(OBJCOPY_normal)
-else
- CC = $(CC_quiet)
- CX = $(CX_quiet)
- AR = $(AR_quiet)
- LD = $(LD_quiet)
- OBJCOPY = $(OBJCOPY_quiet)
-endif
-
-# Toolchain options
-#
-INCLUDES = -I$(MISOC_DIRECTORY)/software/include/base -I$(MISOC_DIRECTORY)/software/include -I$(MISOC_DIRECTORY)/common -I$(BUILDINC_DIRECTORY)
-COMMONFLAGS = -Os $(CPUFLAGS) -fomit-frame-pointer -Wall -fno-builtin -nostdinc $(INCLUDES)
-CFLAGS = $(COMMONFLAGS) -fexceptions -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes
-CXXFLAGS = $(COMMONFLAGS) -std=c++11 -I$(MISOC_DIRECTORY)/software/include/basec++ -fexceptions -fno-rtti -ffreestanding
-LDFLAGS = -nostdlib -nodefaultlibs -L$(BUILDINC_DIRECTORY)
-
-# compile and generate dependencies, based on
-# http://scottmcpeak.com/autodepend/autodepend.html
-
-define compilexx
-$(CX) -c $(CXXFLAGS) $(1) $< -o $@
-endef
-
-define compile
-$(CC) -c $(CFLAGS) $(1) $< -o $@
-endef
-
-define assemble
-$(CC) -c $(CFLAGS) -o $@ $<
-endef
+++ /dev/null
-#ifndef __ASSERT_H
-#define __ASSERT_H
-
-#define assert(x)
-
-#endif /* __ASSERT_H */
+++ /dev/null
-#ifndef __CONSOLE_H
-#define __CONSOLE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef void (*console_write_hook)(char);
-typedef char (*console_read_hook)(void);
-typedef int (*console_read_nonblock_hook)(void);
-
-void console_set_write_hook(console_write_hook h);
-void console_set_read_hook(console_read_hook r, console_read_nonblock_hook rn);
-
-char readchar(void);
-int readchar_nonblock(void);
-
-void putsnonl(const char *s);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __CONSOLE_H */
+++ /dev/null
-#ifndef __CRC_H
-#define __CRC_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-unsigned short crc16(const unsigned char *buffer, int len);
-unsigned int crc32(const unsigned char *buffer, unsigned int len);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef __CTYPE_H
-#define __CTYPE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * NOTE! This ctype does not handle EOF like the standard C
- * library is required to.
- */
-
-#define _U 0x01 /* upper */
-#define _L 0x02 /* lower */
-#define _D 0x04 /* digit */
-#define _C 0x08 /* cntrl */
-#define _P 0x10 /* punct */
-#define _S 0x20 /* white space (space/lf/tab) */
-#define _X 0x40 /* hex digit */
-#define _SP 0x80 /* hard space (0x20) */
-
-extern const unsigned char _ctype[];
-
-#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
-
-#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0)
-#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0)
-#define iscntrl(c) ((__ismask(c)&(_C)) != 0)
-#define isdigit(c) ((__ismask(c)&(_D)) != 0)
-#define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0)
-#define islower(c) ((__ismask(c)&(_L)) != 0)
-#define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
-#define ispunct(c) ((__ismask(c)&(_P)) != 0)
-/* Note: isspace() must return false for %NUL-terminator */
-#define isspace(c) ((__ismask(c)&(_S)) != 0)
-#define isupper(c) ((__ismask(c)&(_U)) != 0)
-#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0)
-
-#define isascii(c) (((unsigned char)(c))<=0x7f)
-#define toascii(c) (((unsigned char)(c))&0x7f)
-
-static inline unsigned char __tolower(unsigned char c)
-{
- if (isupper(c))
- c -= 'A'-'a';
- return c;
-}
-
-static inline unsigned char __toupper(unsigned char c)
-{
- if (islower(c))
- c -= 'a'-'A';
- return c;
-}
-
-#define tolower(c) __tolower(c)
-#define toupper(c) __toupper(c)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __CTYPE_H */
+++ /dev/null
-#ifndef __ENDIAN_H
-#define __ENDIAN_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define __LITTLE_ENDIAN 0
-#define __BIG_ENDIAN 1
-#define __BYTE_ORDER __BIG_ENDIAN
-
-static inline unsigned int le32toh(unsigned int val)
-{
- return (val & 0xff) << 24 |
- (val & 0xff00) << 8 |
- (val & 0xff0000) >> 8 |
- (val & 0xff000000) >> 24;
-}
-
-static inline unsigned short le16toh(unsigned short val)
-{
- return (val & 0xff) << 8 |
- (val & 0xff00) >> 8;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __ENDIAN_H */
+++ /dev/null
-#ifndef __ERRNO_H
-#define __ERRNO_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern int errno;
-
-#define EPERM 1
-#define EPERM_STR "Operation not permitted"
-#define ENOENT 2
-#define ENOENT_STR "No such file or directory"
-#define ESRCH 3
-#define ESRCH_STR "No such process"
-#define EINTR 4
-#define EINTR_STR "Interrupted system call"
-#define EIO 5
-#define EIO_STR "I/O error"
-#define ENXIO 6
-#define ENXIO_STR "No such device or address"
-#define E2BIG 7
-#define E2BIG_STR "Arg list too long"
-#define ENOEXEC 8
-#define ENOEXEC_STR "Exec format error"
-#define EBADF 9
-#define EBADF_STR "Bad file number"
-#define ECHILD 10
-#define ECHILD_STR "No child processes"
-#define EAGAIN 11
-#define EWOULDBLOCK EAGAIN
-#define EAGAIN_STR "Try again"
-#define ENOMEM 12
-#define ENOMEM_STR "Out of memory"
-#define EACCES 13
-#define EACCES_STR "Permission denied"
-#define EFAULT 14
-#define EFAULT_STR "Bad address"
-#define ENOTBLK 15
-#define ENOTBLK_STR "Block device required"
-#define EBUSY 16
-#define EBUSY_STR "Device or resource busy"
-#define EEXIST 17
-#define EEXIST_STR "File exists"
-#define EXDEV 18
-#define EXDEV_STR "Cross-device link"
-#define ENODEV 19
-#define ENODEV_STR "No such device"
-#define ENOTDIR 20
-#define ENOTDIR_STR "Not a directory"
-#define EISDIR 21
-#define EISDIR_STR "Is a directory"
-#define EINVAL 22
-#define EINVAL_STR "Invalid argument"
-#define ENFILE 23
-#define ENFILE_STR "File table overflow"
-#define EMFILE 24
-#define EMFILE_STR "Too many open files"
-#define ENOTTY 25
-#define ENOTTY_STR "Not a typewriter"
-#define ETXTBSY 26
-#define ETXTBSY_STR "Text file busy"
-#define EFBIG 27
-#define EFBIG_STR "File too large"
-#define ENOSPC 28
-#define ENOSPC_STR "No space left on device"
-#define ESPIPE 29
-#define ESPIPE_STR "Illegal seek"
-#define EROFS 30
-#define EROFS_STR "Read-only file system"
-#define EMLINK 31
-#define EMLINK_STR "Too many links"
-#define EPIPE 32
-#define EPIPE_STR "Broken pipe"
-#define EDOM 33
-#define EDOM_STR "Math argument out of domain of func"
-#define ERANGE 34
-#define ERANGE_STR "Math result not representable"
-#define EDEADLK 35
-#define EDEADLOCK EDEADLK
-#define EDEADLK_STR "Resource deadlock would occur"
-#define ENAMETOOLONG 36
-#define ENAMETOOLONG_STR "File name too long"
-#define ENOLCK 37
-#define ENOLCK_STR "No record locks available"
-#define ENOSYS 38
-#define ENOSYS_STR "Function not implemented"
-#define ENOTEMPTY 39
-#define ENOTEMPTY_STR "Directory not empty"
-#define ELOOP 40
-#define ELOOP_STR "Too many symbolic links encountered"
-#define ENOMSG 42
-#define ENOMSG_STR "No message of desired type"
-#define EIDRM 43
-#define EIDRM_STR "Identifier removed"
-#define ECHRNG 44
-#define ECHRNG_STR "Channel number out of range"
-#define EL2NSYNC 45
-#define EL2NSYNC_STR "Level 2 not synchronized"
-#define EL3HLT 46
-#define EL3HLT_STR "Level 3 halted"
-#define EL3RST 47
-#define EL3RST_STR "Level 3 reset"
-#define ELNRNG 48
-#define ELNRNG_STR "Link number out of range"
-#define EUNATCH 49
-#define EUNATCH_STR "Protocol driver not attached"
-#define ENOCSI 50
-#define ENOCSI_STR "No CSI structure available"
-#define EL2HLT 51
-#define EL2HLT_STR "Level 2 halted"
-#define EBADE 52
-#define EBADE_STR "Invalid exchange"
-#define EBADR 53
-#define EBADR_STR "Invalid request descriptor"
-#define EXFULL 54
-#define EXFULL_STR "Exchange full"
-#define ENOANO 55
-#define ENOANO_STR "No anode"
-#define EBADRQC 56
-#define EBADRQC_STR "Invalid request code"
-#define EBADSLT 57
-#define EBADSLT_STR "Invalid slot"
-#define EBFONT 59
-#define EBFONT_STR "Bad font file format"
-#define ENOSTR 60
-#define ENOSTR_STR "Device not a stream"
-#define ENODATA 61
-#define ENODATA_STR "No data available"
-#define ETIME 62
-#define ETIME_STR "Timer expired"
-#define ENOSR 63
-#define ENOSR_STR "Out of streams resources"
-#define ENONET 64
-#define ENONET_STR "Machine is not on the network"
-#define ENOPKG 65
-#define ENOPKG_STR "Package not installed"
-#define EREMOTE 66
-#define EREMOTE_STR "Object is remote"
-#define ENOLINK 67
-#define ENOLINK_STR "Link has been severed"
-#define EADV 68
-#define EADV_STR "Advertise error"
-#define ESRMNT 69
-#define ESRMNT_STR "Srmount error"
-#define ECOMM 70
-#define ECOMM_STR "Communication error on send"
-#define EPROTO 71
-#define EPROTO_STR "Protocol error"
-#define EMULTIHOP 72
-#define EMULTIHOP_STR "Multihop attempted"
-#define EDOTDOT 73
-#define EDOTDOT_STR "RFS specific error"
-#define EBADMSG 74
-#define EBADMSG_STR "Not a data message"
-#define EOVERFLOW 75
-#define EOVERFLOW_STR "Value too large for defined data type"
-#define ENOTUNIQ 76
-#define ENOTUNIQ_STR "Name not unique on network"
-#define EBADFD 77
-#define EBADFD_STR "File descriptor in bad state"
-#define EREMCHG 78
-#define EREMCHG_STR "Remote address changed"
-#define ELIBACC 79
-#define ELIBACC_STR "Can not access a needed shared library"
-#define ELIBBAD 80
-#define ELIBBAD_STR "Accessing a corrupted shared library"
-#define ELIBSCN 81
-#define ELIBSCN_STR ".lib section in a.out corrupted"
-#define ELIBMAX 82
-#define ELIBMAX_STR "Attempting to link in too many shared libraries"
-#define ELIBEXEC 83
-#define ELIBEXEC_STR "Cannot exec a shared library directly"
-#define EILSEQ 84
-#define EILSEQ_STR "Illegal byte sequence"
-#define ERESTART 85
-#define ERESTART_STR "Interrupted system call should be restarted"
-#define ESTRPIPE 86
-#define ESTRPIPE_STR "Streams pipe error"
-#define EUSERS 87
-#define EUSERS_STR "Too many users"
-#define ENOTSOCK 88
-#define ENOTSOCK_STR "Socket operation on non-socket"
-#define EDESTADDRREQ 89
-#define EDESTADDRREQ_STR "Destination address required"
-#define EMSGSIZE 90
-#define EMSGSIZE_STR "Message too long"
-#define EPROTOTYPE 91
-#define EPROTOTYPE_STR "Protocol wrong type for socket"
-#define ENOPROTOOPT 92
-#define ENOPROTOOPT_STR "Protocol not available"
-#define EPROTONOSUPPORT 93
-#define EPROTONOSUPPORT_STR "Protocol not supported"
-#define ESOCKTNOSUPPORT 94
-#define ESOCKTNOSUPPORT_STR "Socket type not supported"
-#define EOPNOTSUPP 95
-#define EOPNOTSUPP_STR "Operation not supported on transport endpoint"
-#define EPFNOSUPPORT 96
-#define EPFNOSUPPORT_STR "Protocol family not supported"
-#define EAFNOSUPPORT 97
-#define EAFNOSUPPORT_STR "Address family not supported by protocol"
-#define EADDRINUSE 98
-#define EADDRINUSE_STR "Address already in use"
-#define EADDRNOTAVAIL 99
-#define EADDRNOTAVAIL_STR "Cannot assign requested address"
-#define ENETDOWN 100
-#define ENETDOWN_STR "Network is down"
-#define ENETUNREACH 101
-#define ENETUNREACH_STR "Network is unreachable"
-#define ENETRESET 102
-#define ENETRESET_STR "Network dropped connection because of reset"
-#define ECONNABORTED 103
-#define ECONNABORTED_STR "Software caused connection abort"
-#define ECONNRESET 104
-#define ECONNRESET_STR "Connection reset by peer"
-#define ENOBUFS 105
-#define ENOBUFS_STR "No buffer space available"
-#define EISCONN 106
-#define EISCONN_STR "Transport endpoint is already connected"
-#define ENOTCONN 107
-#define ENOTCONN_STR "Transport endpoint is not connected"
-#define ESHUTDOWN 108
-#define ESHUTDOWN_STR "Cannot send after transport endpoint shutdown"
-#define ETOOMANYREFS 109
-#define ETOOMANYREFS_STR "Too many references: cannot splice"
-#define ETIMEDOUT 110
-#define ETIMEDOUT_STR "Connection timed out"
-#define ECONNREFUSED 111
-#define ECONNREFUSED_STR "Connection refused"
-#define EHOSTDOWN 112
-#define EHOSTDOWN_STR "Host is down"
-#define EHOSTUNREACH 113
-#define EHOSTUNREACH_STR "No route to host"
-#define EALREADY 114
-#define EALREADY_STR "Operation already in progress"
-#define EINPROGRESS 115
-#define EINPROGRESS_STR "Operation now in progress"
-#define ESTALE 116
-#define ESTALE_STR "Stale NFS file handle"
-#define EUCLEAN 117
-#define EUCLEAN_STR "Structure needs cleaning"
-#define ENOTNAM 118
-#define ENOTNAM_STR "Not a XENIX named type file"
-#define ENAVAIL 119
-#define ENAVAIL_STR "No XENIX semaphores available"
-#define EISNAM 120
-#define EISNAM_STR "Is a named type file"
-#define EREMOTEIO 121
-#define EREMOTEIO_STR "Remote I/O error"
-#define EDQUOT 122
-#define EDQUOT_STR "Quota exceeded"
-#define ENOMEDIUM 123
-#define ENOMEDIUM_STR "No medium found"
-#define EMEDIUMTYPE 124
-#define EMEDIUMTYPE_STR "Wrong medium type"
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __ERRNO_H */
+++ /dev/null
-#ifndef __FLOAT_H
-#define __FLOAT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
-#define FLT_ROUNDS (__builtin_flt_rounds())
-#define FLT_RADIX __FLT_RADIX__
-
-#define FLT_MANT_DIG __FLT_MANT_DIG__
-#define DBL_MANT_DIG __DBL_MANT_DIG__
-#define LDBL_MANT_DIG __LDBL_MANT_DIG__
-
-#define DECIMAL_DIG __DECIMAL_DIG__
-
-#define FLT_DIG __FLT_DIG__
-#define DBL_DIG __DBL_DIG__
-#define LDBL_DIG __LDBL_DIG__
-
-#define FLT_MIN_EXP __FLT_MIN_EXP__
-#define DBL_MIN_EXP __DBL_MIN_EXP__
-#define LDBL_MIN_EXP __LDBL_MIN_EXP__
-
-#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__
-#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__
-#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__
-
-#define FLT_MAX_EXP __FLT_MAX_EXP__
-#define DBL_MAX_EXP __DBL_MAX_EXP__
-#define LDBL_MAX_EXP __LDBL_MAX_EXP__
-
-#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__
-#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__
-#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__
-
-#define FLT_MAX __FLT_MAX__
-#define DBL_MAX __DBL_MAX__
-#define LDBL_MAX __LDBL_MAX__
-
-#define FLT_EPSILON __FLT_EPSILON__
-#define DBL_EPSILON __DBL_EPSILON__
-#define LDBL_EPSILON __LDBL_EPSILON__
-
-#define FLT_MIN __FLT_MIN__
-#define DBL_MIN __DBL_MIN__
-#define LDBL_MIN __LDBL_MIN__
-
-#define FLT_TRUE_MIN __FLT_DENORM_MIN__
-#define DBL_TRUE_MIN __DBL_DENORM_MIN__
-#define LDBL_TRUE_MIN __LDBL_DENORM_MIN__
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __FLOAT_H */
+++ /dev/null
-#ifndef __ID_H
-#define __ID_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void get_sysid_formatted(char *sysid);
-void id_print(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __ID_H */
+++ /dev/null
-/* Copyright (C) 1997-2014 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-/*
- * ISO C99: 7.8 Format conversion of integer types <inttypes.h>
- */
-
-#ifndef __INTTYPES_H
-#define __INTTYPES_H
-
-# if __WORDSIZE == 64
-# define __PRI64_PREFIX "l"
-# define __PRIPTR_PREFIX "l"
-# else
-# define __PRI64_PREFIX "ll"
-# define __PRIPTR_PREFIX
-# endif
-
-/* Macros for printing format specifiers. */
-
-/* Decimal notation. */
-# define PRId8 "d"
-# define PRId16 "d"
-# define PRId32 "d"
-# define PRId64 __PRI64_PREFIX "d"
-
-# define PRIdLEAST8 "d"
-# define PRIdLEAST16 "d"
-# define PRIdLEAST32 "d"
-# define PRIdLEAST64 __PRI64_PREFIX "d"
-
-# define PRIdFAST8 "d"
-# define PRIdFAST16 __PRIPTR_PREFIX "d"
-# define PRIdFAST32 __PRIPTR_PREFIX "d"
-# define PRIdFAST64 __PRI64_PREFIX "d"
-
-
-# define PRIi8 "i"
-# define PRIi16 "i"
-# define PRIi32 "i"
-# define PRIi64 __PRI64_PREFIX "i"
-
-# define PRIiLEAST8 "i"
-# define PRIiLEAST16 "i"
-# define PRIiLEAST32 "i"
-# define PRIiLEAST64 __PRI64_PREFIX "i"
-
-# define PRIiFAST8 "i"
-# define PRIiFAST16 __PRIPTR_PREFIX "i"
-# define PRIiFAST32 __PRIPTR_PREFIX "i"
-# define PRIiFAST64 __PRI64_PREFIX "i"
-
-/* Octal notation. */
-# define PRIo8 "o"
-# define PRIo16 "o"
-# define PRIo32 "o"
-# define PRIo64 __PRI64_PREFIX "o"
-
-# define PRIoLEAST8 "o"
-# define PRIoLEAST16 "o"
-# define PRIoLEAST32 "o"
-# define PRIoLEAST64 __PRI64_PREFIX "o"
-
-# define PRIoFAST8 "o"
-# define PRIoFAST16 __PRIPTR_PREFIX "o"
-# define PRIoFAST32 __PRIPTR_PREFIX "o"
-# define PRIoFAST64 __PRI64_PREFIX "o"
-
-/* Unsigned integers. */
-# define PRIu8 "u"
-# define PRIu16 "u"
-# define PRIu32 "u"
-# define PRIu64 __PRI64_PREFIX "u"
-
-# define PRIuLEAST8 "u"
-# define PRIuLEAST16 "u"
-# define PRIuLEAST32 "u"
-# define PRIuLEAST64 __PRI64_PREFIX "u"
-
-# define PRIuFAST8 "u"
-# define PRIuFAST16 __PRIPTR_PREFIX "u"
-# define PRIuFAST32 __PRIPTR_PREFIX "u"
-# define PRIuFAST64 __PRI64_PREFIX "u"
-
-/* lowercase hexadecimal notation. */
-# define PRIx8 "x"
-# define PRIx16 "x"
-# define PRIx32 "x"
-# define PRIx64 __PRI64_PREFIX "x"
-
-# define PRIxLEAST8 "x"
-# define PRIxLEAST16 "x"
-# define PRIxLEAST32 "x"
-# define PRIxLEAST64 __PRI64_PREFIX "x"
-
-# define PRIxFAST8 "x"
-# define PRIxFAST16 __PRIPTR_PREFIX "x"
-# define PRIxFAST32 __PRIPTR_PREFIX "x"
-# define PRIxFAST64 __PRI64_PREFIX "x"
-
-/* UPPERCASE hexadecimal notation. */
-# define PRIX8 "X"
-# define PRIX16 "X"
-# define PRIX32 "X"
-# define PRIX64 __PRI64_PREFIX "X"
-
-# define PRIXLEAST8 "X"
-# define PRIXLEAST16 "X"
-# define PRIXLEAST32 "X"
-# define PRIXLEAST64 __PRI64_PREFIX "X"
-
-# define PRIXFAST8 "X"
-# define PRIXFAST16 __PRIPTR_PREFIX "X"
-# define PRIXFAST32 __PRIPTR_PREFIX "X"
-# define PRIXFAST64 __PRI64_PREFIX "X"
-
-/* Macros for printing `intmax_t' and `uintmax_t'. */
-# define PRIdMAX __PRI64_PREFIX "d"
-# define PRIiMAX __PRI64_PREFIX "i"
-# define PRIoMAX __PRI64_PREFIX "o"
-# define PRIuMAX __PRI64_PREFIX "u"
-# define PRIxMAX __PRI64_PREFIX "x"
-# define PRIXMAX __PRI64_PREFIX "X"
-
-
-/* Macros for printing `intptr_t' and `uintptr_t'. */
-# define PRIdPTR __PRIPTR_PREFIX "d"
-# define PRIiPTR __PRIPTR_PREFIX "i"
-# define PRIoPTR __PRIPTR_PREFIX "o"
-# define PRIuPTR __PRIPTR_PREFIX "u"
-# define PRIxPTR __PRIPTR_PREFIX "x"
-# define PRIXPTR __PRIPTR_PREFIX "X"
-
-/* Macros for scanning format specifiers. */
-
-/* Signed decimal notation. */
-# define SCNd8 "hhd"
-# define SCNd16 "hd"
-# define SCNd32 "d"
-# define SCNd64 __PRI64_PREFIX "d"
-
-# define SCNdLEAST8 "hhd"
-# define SCNdLEAST16 "hd"
-# define SCNdLEAST32 "d"
-# define SCNdLEAST64 __PRI64_PREFIX "d"
-
-# define SCNdFAST8 "hhd"
-# define SCNdFAST16 __PRIPTR_PREFIX "d"
-# define SCNdFAST32 __PRIPTR_PREFIX "d"
-# define SCNdFAST64 __PRI64_PREFIX "d"
-
-/* Unsigned decimal notation. */
-# define SCNu8 "hhu"
-# define SCNu16 "hu"
-# define SCNu32 "u"
-# define SCNu64 __PRI64_PREFIX "u"
-
-# define SCNuLEAST8 "hhu"
-# define SCNuLEAST16 "hu"
-# define SCNuLEAST32 "u"
-# define SCNuLEAST64 __PRI64_PREFIX "u"
-
-# define SCNuFAST8 "hhu"
-# define SCNuFAST16 __PRIPTR_PREFIX "u"
-# define SCNuFAST32 __PRIPTR_PREFIX "u"
-# define SCNuFAST64 __PRI64_PREFIX "u"
-
-/* Octal notation. */
-# define SCNo8 "hho"
-# define SCNo16 "ho"
-# define SCNo32 "o"
-# define SCNo64 __PRI64_PREFIX "o"
-
-# define SCNoLEAST8 "hho"
-# define SCNoLEAST16 "ho"
-# define SCNoLEAST32 "o"
-# define SCNoLEAST64 __PRI64_PREFIX "o"
-
-# define SCNoFAST8 "hho"
-# define SCNoFAST16 __PRIPTR_PREFIX "o"
-# define SCNoFAST32 __PRIPTR_PREFIX "o"
-# define SCNoFAST64 __PRI64_PREFIX "o"
-
-/* Hexadecimal notation. */
-# define SCNx8 "hhx"
-# define SCNx16 "hx"
-# define SCNx32 "x"
-# define SCNx64 __PRI64_PREFIX "x"
-
-# define SCNxLEAST8 "hhx"
-# define SCNxLEAST16 "hx"
-# define SCNxLEAST32 "x"
-# define SCNxLEAST64 __PRI64_PREFIX "x"
-
-# define SCNxFAST8 "hhx"
-# define SCNxFAST16 __PRIPTR_PREFIX "x"
-# define SCNxFAST32 __PRIPTR_PREFIX "x"
-# define SCNxFAST64 __PRI64_PREFIX "x"
-
-
-/* Macros for scanning `intmax_t' and `uintmax_t'. */
-# define SCNdMAX __PRI64_PREFIX "d"
-# define SCNiMAX __PRI64_PREFIX "i"
-# define SCNoMAX __PRI64_PREFIX "o"
-# define SCNuMAX __PRI64_PREFIX "u"
-# define SCNxMAX __PRI64_PREFIX "x"
-
-/* Macros for scaning `intptr_t' and `uintptr_t'. */
-# define SCNdPTR __PRIPTR_PREFIX "d"
-# define SCNiPTR __PRIPTR_PREFIX "i"
-# define SCNoPTR __PRIPTR_PREFIX "o"
-# define SCNuPTR __PRIPTR_PREFIX "u"
-# define SCNxPTR __PRIPTR_PREFIX "x"
-
-#endif /* __INTTYPES_H */
+++ /dev/null
-#ifndef __IRQ_H
-#define __IRQ_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __or1k__
-#include <system.h>
-#endif
-
-static inline unsigned int irq_getie(void)
-{
-#if defined (__lm32__)
- unsigned int ie;
- __asm__ __volatile__("rcsr %0, IE" : "=r" (ie));
- return ie;
-#elif defined (__or1k__)
- return !!(mfspr(SPR_SR) & SPR_SR_IEE);
-#else
-#error Unsupported architecture
-#endif
-}
-
-static inline void irq_setie(unsigned int ie)
-{
-#if defined (__lm32__)
- __asm__ __volatile__("wcsr IE, %0" : : "r" (ie));
-#elif defined (__or1k__)
- if (ie & 0x1)
- mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE);
- else
- mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_IEE);
-#else
-#error Unsupported architecture
-#endif
-}
-
-static inline unsigned int irq_getmask(void)
-{
-#if defined (__lm32__)
- unsigned int mask;
- __asm__ __volatile__("rcsr %0, IM" : "=r" (mask));
- return mask;
-#elif defined (__or1k__)
- return mfspr(SPR_PICMR);
-#else
-#error Unsupported architecture
-#endif
-}
-
-static inline void irq_setmask(unsigned int mask)
-{
-#if defined (__lm32__)
- __asm__ __volatile__("wcsr IM, %0" : : "r" (mask));
-#elif defined (__or1k__)
- mtspr(SPR_PICMR, mask);
-#else
-#error Unsupported architecture
-#endif
-}
-
-static inline unsigned int irq_pending(void)
-{
-#if defined (__lm32__)
- unsigned int pending;
- __asm__ __volatile__("rcsr %0, IP" : "=r" (pending));
- return pending;
-#elif defined (__or1k__)
- return mfspr(SPR_PICSR);
-#else
-#error Unsupported architecture
-#endif
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __IRQ_H */
+++ /dev/null
-#ifndef __LIMITS_H
-#define __LIMITS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define ULONG_MAX 0xffffffff
-
-#define UINT_MAX 0xffffffff
-#define INT_MIN 0x80000000
-#define INT_MAX 0x7fffffff
-
-#define USHRT_MAX 0xffff
-#define SHRT_MIN 0x8000
-#define SHRT_MAX 0x7fff
-
-#define UCHAR_MAX 0xff
-
-#define CHAR_BIT 8
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LIMITS_H */
+++ /dev/null
-#ifndef __PTHREAD_H
-#define __PTHREAD_H
-
-typedef int pthread_rwlock_t;
-
-#define PTHREAD_RWLOCK_INITIALIZER 0
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-inline int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
- { return 0; }
-inline int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
- { return 0; }
-inline int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
- { return 0; }
-inline int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
- { return 0; }
-int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
- { return 0; }
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __PTHREAD_H */
+++ /dev/null
-#ifndef __SPIFLASH_H
-#define __SPIFLASH_H
-
-void write_to_flash_page(unsigned int addr, const unsigned char *c, unsigned int len);
-void erase_flash_sector(unsigned int addr);
-void write_to_flash(unsigned int addr, const unsigned char *c, unsigned int len);
-
-#endif /* __SPIFLASH_H */
+++ /dev/null
-/* spr-defs.h - Special purpose registers definitions file
-
- Copyright (C) 2000 Damjan Lampret
- Copyright (C) 2008, 2010 Embecosm Limited
-
- Contributor Damjan Lampret <lampret@opencores.org>
- Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
-
- This program is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 3 of the License, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- more details.
-
- You should have received a copy of the GNU General Public License along
- with this program. If not, see <http: www.gnu.org/licenses/>. */
-
-/* ----------------------------------------------------------------------------
- This code is commented throughout for use with Doxygen.
- --------------------------------------------------------------------------*/
-#ifndef SPR_DEFS__H
-#define SPR_DEFS__H
-
-/* Definition of special-purpose registers (SPRs). */
-
-#define MAX_GRPS (32)
-#define MAX_SPRS_PER_GRP_BITS (11)
-#define MAX_SPRS_PER_GRP (1 << MAX_SPRS_PER_GRP_BITS)
-#define MAX_SPRS (0x10000)
-
-/* Base addresses for the groups */
-#define SPRGROUP_SYS (0<< MAX_SPRS_PER_GRP_BITS)
-#define SPRGROUP_DMMU (1<< MAX_SPRS_PER_GRP_BITS)
-#define SPRGROUP_IMMU (2<< MAX_SPRS_PER_GRP_BITS)
-#define SPRGROUP_DC (3<< MAX_SPRS_PER_GRP_BITS)
-#define SPRGROUP_IC (4<< MAX_SPRS_PER_GRP_BITS)
-#define SPRGROUP_MAC (5<< MAX_SPRS_PER_GRP_BITS)
-#define SPRGROUP_D (6<< MAX_SPRS_PER_GRP_BITS)
-#define SPRGROUP_PC (7<< MAX_SPRS_PER_GRP_BITS)
-#define SPRGROUP_PM (8<< MAX_SPRS_PER_GRP_BITS)
-#define SPRGROUP_PIC (9<< MAX_SPRS_PER_GRP_BITS)
-#define SPRGROUP_TT (10<< MAX_SPRS_PER_GRP_BITS)
-#define SPRGROUP_FP (11<< MAX_SPRS_PER_GRP_BITS)
-
-/* System control and status group */
-#define SPR_VR (SPRGROUP_SYS + 0)
-#define SPR_UPR (SPRGROUP_SYS + 1)
-#define SPR_CPUCFGR (SPRGROUP_SYS + 2)
-#define SPR_DMMUCFGR (SPRGROUP_SYS + 3)
-#define SPR_IMMUCFGR (SPRGROUP_SYS + 4)
-#define SPR_DCCFGR (SPRGROUP_SYS + 5)
-#define SPR_ICCFGR (SPRGROUP_SYS + 6)
-#define SPR_DCFGR (SPRGROUP_SYS + 7)
-#define SPR_PCCFGR (SPRGROUP_SYS + 8)
-#define SPR_VR2 (SPRGROUP_SYS + 9)
-#define SPR_AVR (SPRGROUP_SYS + 10)
-#define SPR_EVBAR (SPRGROUP_SYS + 11)
-#define SPR_AECR (SPRGROUP_SYS + 12)
-#define SPR_AESR (SPRGROUP_SYS + 13)
-#define SPR_NPC (SPRGROUP_SYS + 16) /* CZ 21/06/01 */
-#define SPR_SR (SPRGROUP_SYS + 17) /* CZ 21/06/01 */
-#define SPR_PPC (SPRGROUP_SYS + 18) /* CZ 21/06/01 */
-#define SPR_FPCSR (SPRGROUP_SYS + 20) /* CZ 21/06/01 */
-#define SPR_ISR_BASE (SPRGROUP_SYS + 21)
-#define SPR_EPCR_BASE (SPRGROUP_SYS + 32) /* CZ 21/06/01 */
-#define SPR_EPCR_LAST (SPRGROUP_SYS + 47) /* CZ 21/06/01 */
-#define SPR_EEAR_BASE (SPRGROUP_SYS + 48)
-#define SPR_EEAR_LAST (SPRGROUP_SYS + 63)
-#define SPR_ESR_BASE (SPRGROUP_SYS + 64)
-#define SPR_ESR_LAST (SPRGROUP_SYS + 79)
-#define SPR_GPR_BASE (SPRGROUP_SYS + 1024)
-
-/* Data MMU group */
-#define SPR_DMMUCR (SPRGROUP_DMMU + 0)
-#define SPR_DTLBEIR (SPRGROUP_DMMU + 2)
-#define SPR_DTLBMR_BASE(WAY) (SPRGROUP_DMMU + 0x200 + (WAY) * 0x100)
-#define SPR_DTLBMR_LAST(WAY) (SPRGROUP_DMMU + 0x27f + (WAY) * 0x100)
-#define SPR_DTLBTR_BASE(WAY) (SPRGROUP_DMMU + 0x280 + (WAY) * 0x100)
-#define SPR_DTLBTR_LAST(WAY) (SPRGROUP_DMMU + 0x2ff + (WAY) * 0x100)
-
-/* Instruction MMU group */
-#define SPR_IMMUCR (SPRGROUP_IMMU + 0)
-#define SPR_ITLBEIR (SPRGROUP_IMMU + 2)
-#define SPR_ITLBMR_BASE(WAY) (SPRGROUP_IMMU + 0x200 + (WAY) * 0x100)
-#define SPR_ITLBMR_LAST(WAY) (SPRGROUP_IMMU + 0x27f + (WAY) * 0x100)
-#define SPR_ITLBTR_BASE(WAY) (SPRGROUP_IMMU + 0x280 + (WAY) * 0x100)
-#define SPR_ITLBTR_LAST(WAY) (SPRGROUP_IMMU + 0x2ff + (WAY) * 0x100)
-
-/* Data cache group */
-#define SPR_DCCR (SPRGROUP_DC + 0)
-#define SPR_DCBPR (SPRGROUP_DC + 1)
-#define SPR_DCBFR (SPRGROUP_DC + 2)
-#define SPR_DCBIR (SPRGROUP_DC + 3)
-#define SPR_DCBWR (SPRGROUP_DC + 4)
-#define SPR_DCBLR (SPRGROUP_DC + 5)
-#define SPR_DCR_BASE(WAY) (SPRGROUP_DC + 0x200 + (WAY) * 0x200)
-#define SPR_DCR_LAST(WAY) (SPRGROUP_DC + 0x3ff + (WAY) * 0x200)
-
-/* Instruction cache group */
-#define SPR_ICCR (SPRGROUP_IC + 0)
-#define SPR_ICBPR (SPRGROUP_IC + 1)
-#define SPR_ICBIR (SPRGROUP_IC + 2)
-#define SPR_ICBLR (SPRGROUP_IC + 3)
-#define SPR_ICR_BASE(WAY) (SPRGROUP_IC + 0x200 + (WAY) * 0x200)
-#define SPR_ICR_LAST(WAY) (SPRGROUP_IC + 0x3ff + (WAY) * 0x200)
-
-/* MAC group */
-#define SPR_MACLO (SPRGROUP_MAC + 1)
-#define SPR_MACHI (SPRGROUP_MAC + 2)
-
-/* Debug group */
-#define SPR_DVR(N) (SPRGROUP_D + (N))
-#define SPR_DCR(N) (SPRGROUP_D + 8 + (N))
-#define SPR_DMR1 (SPRGROUP_D + 16)
-#define SPR_DMR2 (SPRGROUP_D + 17)
-#define SPR_DWCR0 (SPRGROUP_D + 18)
-#define SPR_DWCR1 (SPRGROUP_D + 19)
-#define SPR_DSR (SPRGROUP_D + 20)
-#define SPR_DRR (SPRGROUP_D + 21)
-
-/* Performance counters group */
-#define SPR_PCCR(N) (SPRGROUP_PC + (N))
-#define SPR_PCMR(N) (SPRGROUP_PC + 8 + (N))
-
-/* Power management group */
-#define SPR_PMR (SPRGROUP_PM + 0)
-
-/* PIC group */
-#define SPR_PICMR (SPRGROUP_PIC + 0)
-#define SPR_PICPR (SPRGROUP_PIC + 1)
-#define SPR_PICSR (SPRGROUP_PIC + 2)
-
-/* Tick Timer group */
-#define SPR_TTMR (SPRGROUP_TT + 0)
-#define SPR_TTCR (SPRGROUP_TT + 1)
-
-/*
- * Bit definitions for the Version Register
- *
- */
-#define SPR_VR_VER 0xff000000 /* Processor version */
-#define SPR_VR_CFG 0x00ff0000 /* Processor configuration */
-#define SPR_VR_RES 0x0000ff80 /* Reserved */
-#define SPR_VR_UVRP 0x00000040 /* Updated version register present */
-#define SPR_VR_REV 0x0000003f /* Processor revision */
-
-#define SPR_VR_VER_OFF 24
-#define SPR_VR_CFG_OFF 16
-#define SPR_VR_UVRP_OFF 6
-#define SPR_VR_REV_OFF 0
-
-/*
- * Bit definitions for the Unit Present Register
- *
- */
-#define SPR_UPR_UP 0x00000001 /* UPR present */
-#define SPR_UPR_DCP 0x00000002 /* Data cache present */
-#define SPR_UPR_ICP 0x00000004 /* Instruction cache present */
-#define SPR_UPR_DMP 0x00000008 /* Data MMU present */
-#define SPR_UPR_IMP 0x00000010 /* Instruction MMU present */
-#define SPR_UPR_MP 0x00000020 /* MAC present */
-#define SPR_UPR_DUP 0x00000040 /* Debug unit present */
-#define SPR_UPR_PCUP 0x00000080 /* Performance counters unit present */
-#define SPR_UPR_PMP 0x00000100 /* Power management present */
-#define SPR_UPR_PICP 0x00000200 /* PIC present */
-#define SPR_UPR_TTP 0x00000400 /* Tick timer present */
-#define SPR_UPR_RES 0x00fe0000 /* Reserved */
-#define SPR_UPR_CUP 0xff000000 /* Context units present */
-
-/*
- * JPB: Bit definitions for the CPU configuration register
- *
- */
-#define SPR_CPUCFGR_NSGF 0x0000000f /* Number of shadow GPR files */
-#define SPR_CPUCFGR_CGF 0x00000010 /* Custom GPR file */
-#define SPR_CPUCFGR_OB32S 0x00000020 /* ORBIS32 supported */
-#define SPR_CPUCFGR_OB64S 0x00000040 /* ORBIS64 supported */
-#define SPR_CPUCFGR_OF32S 0x00000080 /* ORFPX32 supported */
-#define SPR_CPUCFGR_OF64S 0x00000100 /* ORFPX64 supported */
-#define SPR_CPUCFGR_OV64S 0x00000200 /* ORVDX64 supported */
-#define SPR_CPUCFGR_ND 0x00000400 /* No delay-slot */
-#define SPR_CPUCFGR_AVRP 0x00000800 /* Architecture version register present */
-#define SPR_CPUCFGR_EVBARP 0x00001000 /* Exception vector base address register
- present */
-#define SPR_CPUCFGR_ISRP 0x00002000 /* Implementation-specific registers present */
-#define SPR_CPUCFGR_AECSRP 0x00004000 /* Arithmetic exception control/status
- registers present */
-#define SPR_CPUCFGR_RES 0xffff8000 /* Reserved */
-
-/*
- * Bit definitions for the Version Register 2
- *
- */
-#define SPR_VR2_CPUID 0xff000000 /* Unique CPU identifier */
-#define SPR_VR2_VER 0x00ffffff /* Version */
-
-#define SPR_VR2_CPUID_OFF 24
-#define SPR_VR2_VER_OFF 0
-
-#define SPR_VR2_CPUID_OR1KSIM 0x00
-#define SPR_VR2_CPUID_MOR1KX 0x01
-#define SPR_VR2_CPUID_OR1200 0x12
-#define SPR_VR2_CPUID_ALTOR32 0x32
-#define SPR_VR2_CPUID_OR10 0x10
-
-
-/*
- * Bit definitions for the Architecture Version register
- *
- */
-#define SPR_AVR_MAJ 0xff000000 /* Major architecture version number */
-#define SPR_AVR_MIN 0x00ff0000 /* Minor architecture version number */
-#define SPR_AVR_REV 0x0000ff00 /* Architecture revision number */
-#define SPR_AVR_RES 0x000000ff /* Reserved */
-
-#define SPR_AVR_MAJ_OFF 24
-#define SPR_AVR_MIN_OFF 16
-#define SPR_AVR_REV_OFF 8
-
-/*
- * Bit definitions for the Exception Base Address register
- *
- */
-#define SPR_EVBAR_EVBA 0xffffe000 /* Exception vector base address */
-#define SPR_EVBAR_RES 0x00001fff /* Reserved */
-
-#define SPR_EVBAR_EVBA_OFF 13
-
-/*
- * Bit definitions for the Arithmetic Exception Control register
- *
- */
-#define SPR_AECR_CYADDE 0x00000001 /* Carry on add/subtract exception */
-#define SPR_AECR_OVADDE 0x00000002 /* Overflow on add/subtract exception */
-#define SPR_AECR_CYMULE 0x00000004 /* Carry on multiply exception */
-#define SPR_AECR_OVMULE 0x00000008 /* Overflow on multiply exception */
-#define SPR_AECR_DBZE 0x00000010 /* Divide by zero exception */
-#define SPR_AECR_CYMACADDE 0x00000020 /* Carry on MAC add/subtract exception */
-#define SPR_AECR_OVMACADDE 0x00000040 /* Overflow on MAC add/subtract exception */
-
-#define SPR_AECR_CYADDE_OFF 0
-#define SPR_AECR_OVADDE_OFF 1
-#define SPR_AECR_CYMULE_OFF 2
-#define SPR_AECR_OVMULE_OFF 3
-#define SPR_AECR_DBZE_OFF 4
-#define SPR_AECR_CYMACADDE_OFF 5
-#define SPR_AECR_OVMACADDE_OFF 6
-
-
-/*
- * Bit definitions for the Arithmetic Exception Status register
- *
- */
-#define SPR_AESR_CYADDE 0x00000001 /* Carry on add/subtract exception */
-#define SPR_AESR_OVADDE 0x00000002 /* Overflow on add/subtract exception */
-#define SPR_AESR_CYMULE 0x00000004 /* Carry on multiply exception */
-#define SPR_AESR_OVMULE 0x00000008 /* Overflow on multiply exception */
-#define SPR_AESR_DBZE 0x00000010 /* Divide by zero exception */
-#define SPR_AESR_CYMACADDE 0x00000020 /* Carry on MAC add/subtract exception */
-#define SPR_AESR_OVMACADDE 0x00000040 /* Overflow on MAC add/subtract exception */
-
-#define SPR_AESR_CYADDE_OFF 0
-#define SPR_AESR_OVADDE_OFF 1
-#define SPR_AESR_CYMULE_OFF 2
-#define SPR_AESR_OVMULE_OFF 3
-#define SPR_AESR_DBZE_OFF 4
-#define SPR_AESR_CYMACADDE_OFF 5
-#define SPR_AESR_OVMACADDE_OFF 6
-
-/*
- * JPB: Bit definitions for the Debug configuration register and other
- * constants.
- *
- */
-
-#define SPR_DCFGR_NDP 0x00000007 /* Number of matchpoints mask */
-#define SPR_DCFGR_NDP1 0x00000000 /* One matchpoint supported */
-#define SPR_DCFGR_NDP2 0x00000001 /* Two matchpoints supported */
-#define SPR_DCFGR_NDP3 0x00000002 /* Three matchpoints supported */
-#define SPR_DCFGR_NDP4 0x00000003 /* Four matchpoints supported */
-#define SPR_DCFGR_NDP5 0x00000004 /* Five matchpoints supported */
-#define SPR_DCFGR_NDP6 0x00000005 /* Six matchpoints supported */
-#define SPR_DCFGR_NDP7 0x00000006 /* Seven matchpoints supported */
-#define SPR_DCFGR_NDP8 0x00000007 /* Eight matchpoints supported */
-#define SPR_DCFGR_WPCI 0x00000008 /* Watchpoint counters implemented */
-
-#define MATCHPOINTS_TO_NDP(n) (1 == n ? SPR_DCFGR_NDP1 : \
- 2 == n ? SPR_DCFGR_NDP2 : \
- 3 == n ? SPR_DCFGR_NDP3 : \
- 4 == n ? SPR_DCFGR_NDP4 : \
- 5 == n ? SPR_DCFGR_NDP5 : \
- 6 == n ? SPR_DCFGR_NDP6 : \
- 7 == n ? SPR_DCFGR_NDP7 : SPR_DCFGR_NDP8)
-#define MAX_MATCHPOINTS 8
-#define MAX_WATCHPOINTS (MAX_MATCHPOINTS + 2)
-
-/*
- * Bit definitions for the Supervision Register
- *
- */
-#define SPR_SR_SM 0x00000001 /* Supervisor Mode */
-#define SPR_SR_TEE 0x00000002 /* Tick timer Exception Enable */
-#define SPR_SR_IEE 0x00000004 /* Interrupt Exception Enable */
-#define SPR_SR_DCE 0x00000008 /* Data Cache Enable */
-#define SPR_SR_ICE 0x00000010 /* Instruction Cache Enable */
-#define SPR_SR_DME 0x00000020 /* Data MMU Enable */
-#define SPR_SR_IME 0x00000040 /* Instruction MMU Enable */
-#define SPR_SR_LEE 0x00000080 /* Little Endian Enable */
-#define SPR_SR_CE 0x00000100 /* CID Enable */
-#define SPR_SR_F 0x00000200 /* Condition Flag */
-#define SPR_SR_CY 0x00000400 /* Carry flag */
-#define SPR_SR_OV 0x00000800 /* Overflow flag */
-#define SPR_SR_OVE 0x00001000 /* Overflow flag Exception */
-#define SPR_SR_DSX 0x00002000 /* Delay Slot Exception */
-#define SPR_SR_EPH 0x00004000 /* Exception Prefix High */
-#define SPR_SR_FO 0x00008000 /* Fixed one */
-#define SPR_SR_SUMRA 0x00010000 /* Supervisor SPR read access */
-#define SPR_SR_RES 0x0ffe0000 /* Reserved */
-#define SPR_SR_CID 0xf0000000 /* Context ID */
-
-/*
- * Bit definitions for the Data MMU Control Register
- *
- */
-#define SPR_DMMUCR_P2S 0x0000003e /* Level 2 Page Size */
-#define SPR_DMMUCR_P1S 0x000007c0 /* Level 1 Page Size */
-#define SPR_DMMUCR_VADDR_WIDTH 0x0000f800 /* Virtual ADDR Width */
-#define SPR_DMMUCR_PADDR_WIDTH 0x000f0000 /* Physical ADDR Width */
-
-/*
- * Bit definitions for the Instruction MMU Control Register
- *
- */
-#define SPR_IMMUCR_P2S 0x0000003e /* Level 2 Page Size */
-#define SPR_IMMUCR_P1S 0x000007c0 /* Level 1 Page Size */
-#define SPR_IMMUCR_VADDR_WIDTH 0x0000f800 /* Virtual ADDR Width */
-#define SPR_IMMUCR_PADDR_WIDTH 0x000f0000 /* Physical ADDR Width */
-
-/*
- * Bit definitions for the Data TLB Match Register
- *
- */
-#define SPR_DTLBMR_V 0x00000001 /* Valid */
-#define SPR_DTLBMR_PL1 0x00000002 /* Page Level 1 (if 0 then PL2) */
-#define SPR_DTLBMR_CID 0x0000003c /* Context ID */
-#define SPR_DTLBMR_LRU 0x000000c0 /* Least Recently Used */
-#define SPR_DTLBMR_VPN 0xffffe000 /* Virtual Page Number */
-
-/*
- * Bit definitions for the Data TLB Translate Register
- *
- */
-#define SPR_DTLBTR_CC 0x00000001 /* Cache Coherency */
-#define SPR_DTLBTR_CI 0x00000002 /* Cache Inhibit */
-#define SPR_DTLBTR_WBC 0x00000004 /* Write-Back Cache */
-#define SPR_DTLBTR_WOM 0x00000008 /* Weakly-Ordered Memory */
-#define SPR_DTLBTR_A 0x00000010 /* Accessed */
-#define SPR_DTLBTR_D 0x00000020 /* Dirty */
-#define SPR_DTLBTR_URE 0x00000040 /* User Read Enable */
-#define SPR_DTLBTR_UWE 0x00000080 /* User Write Enable */
-#define SPR_DTLBTR_SRE 0x00000100 /* Supervisor Read Enable */
-#define SPR_DTLBTR_SWE 0x00000200 /* Supervisor Write Enable */
-#define SPR_DTLBTR_PPN 0xffffe000 /* Physical Page Number */
-
-#define DTLB_PR_NOLIMIT ( SPR_DTLBTR_URE | \
- SPR_DTLBTR_UWE | \
- SPR_DTLBTR_SRE | \
- SPR_DTLBTR_SWE )
-
-/*
- * Bit definitions for the Instruction TLB Match Register
- *
- */
-#define SPR_ITLBMR_V 0x00000001 /* Valid */
-#define SPR_ITLBMR_PL1 0x00000002 /* Page Level 1 (if 0 then PL2) */
-#define SPR_ITLBMR_CID 0x0000003c /* Context ID */
-#define SPR_ITLBMR_LRU 0x000000c0 /* Least Recently Used */
-#define SPR_ITLBMR_VPN 0xffffe000 /* Virtual Page Number */
-
-/*
- * Bit definitions for the Instruction TLB Translate Register
- *
- */
-#define SPR_ITLBTR_CC 0x00000001 /* Cache Coherency */
-#define SPR_ITLBTR_CI 0x00000002 /* Cache Inhibit */
-#define SPR_ITLBTR_WBC 0x00000004 /* Write-Back Cache */
-#define SPR_ITLBTR_WOM 0x00000008 /* Weakly-Ordered Memory */
-#define SPR_ITLBTR_A 0x00000010 /* Accessed */
-#define SPR_ITLBTR_D 0x00000020 /* Dirty */
-#define SPR_ITLBTR_SXE 0x00000040 /* User Read Enable */
-#define SPR_ITLBTR_UXE 0x00000080 /* User Write Enable */
-#define SPR_ITLBTR_PPN 0xffffe000 /* Physical Page Number */
-
-#define ITLB_PR_NOLIMIT ( SPR_ITLBTR_SXE | \
- SPR_ITLBTR_UXE )
-
-
-/*
- * Bit definitions for Data Cache Control register
- *
- */
-#define SPR_DCCR_EW 0x000000ff /* Enable ways */
-
-/*
- * Bit definitions for Insn Cache Control register
- *
- */
-#define SPR_ICCR_EW 0x000000ff /* Enable ways */
-
-/*
- * Bit definitions for Data Cache Configuration Register
- *
- */
-
-#define SPR_DCCFGR_NCW 0x00000007
-#define SPR_DCCFGR_NCS 0x00000078
-#define SPR_DCCFGR_CBS 0x00000080
-#define SPR_DCCFGR_CWS 0x00000100
-#define SPR_DCCFGR_CCRI 0x00000200
-#define SPR_DCCFGR_CBIRI 0x00000400
-#define SPR_DCCFGR_CBPRI 0x00000800
-#define SPR_DCCFGR_CBLRI 0x00001000
-#define SPR_DCCFGR_CBFRI 0x00002000
-#define SPR_DCCFGR_CBWBRI 0x00004000
-
-#define SPR_DCCFGR_NCW_OFF 0
-#define SPR_DCCFGR_NCS_OFF 3
-#define SPR_DCCFGR_CBS_OFF 7
-
-/*
- * Bit definitions for Instruction Cache Configuration Register
- *
- */
-#define SPR_ICCFGR_NCW 0x00000007
-#define SPR_ICCFGR_NCS 0x00000078
-#define SPR_ICCFGR_CBS 0x00000080
-#define SPR_ICCFGR_CCRI 0x00000200
-#define SPR_ICCFGR_CBIRI 0x00000400
-#define SPR_ICCFGR_CBPRI 0x00000800
-#define SPR_ICCFGR_CBLRI 0x00001000
-
-#define SPR_ICCFGR_NCW_OFF 0
-#define SPR_ICCFGR_NCS_OFF 3
-#define SPR_ICCFGR_CBS_OFF 7
-
-/*
- * Bit definitions for Data MMU Configuration Register
- *
- */
-
-#define SPR_DMMUCFGR_NTW 0x00000003
-#define SPR_DMMUCFGR_NTS 0x0000001C
-#define SPR_DMMUCFGR_NAE 0x000000E0
-#define SPR_DMMUCFGR_CRI 0x00000100
-#define SPR_DMMUCFGR_PRI 0x00000200
-#define SPR_DMMUCFGR_TEIRI 0x00000400
-#define SPR_DMMUCFGR_HTR 0x00000800
-
-#define SPR_DMMUCFGR_NTW_OFF 0
-#define SPR_DMMUCFGR_NTS_OFF 2
-
-/*
- * Bit definitions for Instruction MMU Configuration Register
- *
- */
-
-#define SPR_IMMUCFGR_NTW 0x00000003
-#define SPR_IMMUCFGR_NTS 0x0000001C
-#define SPR_IMMUCFGR_NAE 0x000000E0
-#define SPR_IMMUCFGR_CRI 0x00000100
-#define SPR_IMMUCFGR_PRI 0x00000200
-#define SPR_IMMUCFGR_TEIRI 0x00000400
-#define SPR_IMMUCFGR_HTR 0x00000800
-
-#define SPR_IMMUCFGR_NTW_OFF 0
-#define SPR_IMMUCFGR_NTS_OFF 2
-
-/*
- * Bit definitions for Debug Control registers
- *
- */
-#define SPR_DCR_DP 0x00000001 /* DVR/DCR present */
-#define SPR_DCR_CC 0x0000000e /* Compare condition */
-#define SPR_DCR_SC 0x00000010 /* Signed compare */
-#define SPR_DCR_CT 0x000000e0 /* Compare to */
-
-/* Bit results with SPR_DCR_CC mask */
-#define SPR_DCR_CC_MASKED 0x00000000
-#define SPR_DCR_CC_EQUAL 0x00000002
-#define SPR_DCR_CC_LESS 0x00000004
-#define SPR_DCR_CC_LESSE 0x00000006
-#define SPR_DCR_CC_GREAT 0x00000008
-#define SPR_DCR_CC_GREATE 0x0000000a
-#define SPR_DCR_CC_NEQUAL 0x0000000c
-
-/* Bit results with SPR_DCR_CT mask */
-#define SPR_DCR_CT_DISABLED 0x00000000
-#define SPR_DCR_CT_IFEA 0x00000020
-#define SPR_DCR_CT_LEA 0x00000040
-#define SPR_DCR_CT_SEA 0x00000060
-#define SPR_DCR_CT_LD 0x00000080
-#define SPR_DCR_CT_SD 0x000000a0
-#define SPR_DCR_CT_LSEA 0x000000c0
-#define SPR_DCR_CT_LSD 0x000000e0
-/* SPR_DCR_CT_LSD doesn't seem to be implemented anywhere in or1ksim. 2004-1-30 HP */
-
-/*
- * Bit definitions for Debug Mode 1 register
- *
- */
-#define SPR_DMR1_CW 0x000fffff /* Chain register pair data */
-#define SPR_DMR1_CW0_AND 0x00000001
-#define SPR_DMR1_CW0_OR 0x00000002
-#define SPR_DMR1_CW0 (SPR_DMR1_CW0_AND | SPR_DMR1_CW0_OR)
-#define SPR_DMR1_CW1_AND 0x00000004
-#define SPR_DMR1_CW1_OR 0x00000008
-#define SPR_DMR1_CW1 (SPR_DMR1_CW1_AND | SPR_DMR1_CW1_OR)
-#define SPR_DMR1_CW2_AND 0x00000010
-#define SPR_DMR1_CW2_OR 0x00000020
-#define SPR_DMR1_CW2 (SPR_DMR1_CW2_AND | SPR_DMR1_CW2_OR)
-#define SPR_DMR1_CW3_AND 0x00000040
-#define SPR_DMR1_CW3_OR 0x00000080
-#define SPR_DMR1_CW3 (SPR_DMR1_CW3_AND | SPR_DMR1_CW3_OR)
-#define SPR_DMR1_CW4_AND 0x00000100
-#define SPR_DMR1_CW4_OR 0x00000200
-#define SPR_DMR1_CW4 (SPR_DMR1_CW4_AND | SPR_DMR1_CW4_OR)
-#define SPR_DMR1_CW5_AND 0x00000400
-#define SPR_DMR1_CW5_OR 0x00000800
-#define SPR_DMR1_CW5 (SPR_DMR1_CW5_AND | SPR_DMR1_CW5_OR)
-#define SPR_DMR1_CW6_AND 0x00001000
-#define SPR_DMR1_CW6_OR 0x00002000
-#define SPR_DMR1_CW6 (SPR_DMR1_CW6_AND | SPR_DMR1_CW6_OR)
-#define SPR_DMR1_CW7_AND 0x00004000
-#define SPR_DMR1_CW7_OR 0x00008000
-#define SPR_DMR1_CW7 (SPR_DMR1_CW7_AND | SPR_DMR1_CW7_OR)
-#define SPR_DMR1_CW8_AND 0x00010000
-#define SPR_DMR1_CW8_OR 0x00020000
-#define SPR_DMR1_CW8 (SPR_DMR1_CW8_AND | SPR_DMR1_CW8_OR)
-#define SPR_DMR1_CW9_AND 0x00040000
-#define SPR_DMR1_CW9_OR 0x00080000
-#define SPR_DMR1_CW9 (SPR_DMR1_CW9_AND | SPR_DMR1_CW9_OR)
-#define SPR_DMR1_RES1 0x00300000 /* Reserved */
-#define SPR_DMR1_ST 0x00400000 /* Single-step trace*/
-#define SPR_DMR1_BT 0x00800000 /* Branch trace */
-#define SPR_DMR1_RES2 0xff000000 /* Reserved */
-
-/*
- * Bit definitions for Debug Mode 2 register. AWTC and WGB corrected by JPB
- *
- */
-#define SPR_DMR2_WCE0 0x00000001 /* Watchpoint counter 0 enable */
-#define SPR_DMR2_WCE1 0x00000002 /* Watchpoint counter 0 enable */
-#define SPR_DMR2_AWTC 0x00000ffc /* Assign watchpoints to counters */
-#define SPR_DMR2_AWTC_OFF 2 /* Bit offset to AWTC field */
-#define SPR_DMR2_WGB 0x003ff000 /* Watchpoints generating breakpoint */
-#define SPR_DMR2_WGB_OFF 12 /* Bit offset to WGB field */
-#define SPR_DMR2_WBS 0xffc00000 /* JPB: Watchpoint status */
-#define SPR_DMR2_WBS_OFF 22 /* Bit offset to WBS field */
-
-/*
- * Bit definitions for Debug watchpoint counter registers
- *
- */
-#define SPR_DWCR_COUNT 0x0000ffff /* Count */
-#define SPR_DWCR_MATCH 0xffff0000 /* Match */
-#define SPR_DWCR_MATCH_OFF 16 /* Match bit offset */
-
-/*
- * Bit definitions for Debug stop register
- *
- */
-#define SPR_DSR_RSTE 0x00000001 /* Reset exception */
-#define SPR_DSR_BUSEE 0x00000002 /* Bus error exception */
-#define SPR_DSR_DPFE 0x00000004 /* Data Page Fault exception */
-#define SPR_DSR_IPFE 0x00000008 /* Insn Page Fault exception */
-#define SPR_DSR_TTE 0x00000010 /* Tick Timer exception */
-#define SPR_DSR_AE 0x00000020 /* Alignment exception */
-#define SPR_DSR_IIE 0x00000040 /* Illegal Instruction exception */
-#define SPR_DSR_IE 0x00000080 /* Interrupt exception */
-#define SPR_DSR_DME 0x00000100 /* DTLB miss exception */
-#define SPR_DSR_IME 0x00000200 /* ITLB miss exception */
-#define SPR_DSR_RE 0x00000400 /* Range exception */
-#define SPR_DSR_SCE 0x00000800 /* System call exception */
-#define SPR_DSR_FPE 0x00001000 /* Floating Point Exception */
-#define SPR_DSR_TE 0x00002000 /* Trap exception */
-
-/*
- * Bit definitions for Debug reason register
- *
- */
-#define SPR_DRR_RSTE 0x00000001 /* Reset exception */
-#define SPR_DRR_BUSEE 0x00000002 /* Bus error exception */
-#define SPR_DRR_DPFE 0x00000004 /* Data Page Fault exception */
-#define SPR_DRR_IPFE 0x00000008 /* Insn Page Fault exception */
-#define SPR_DRR_TTE 0x00000010 /* Tick Timer exception */
-#define SPR_DRR_AE 0x00000020 /* Alignment exception */
-#define SPR_DRR_IIE 0x00000040 /* Illegal Instruction exception */
-#define SPR_DRR_IE 0x00000080 /* Interrupt exception */
-#define SPR_DRR_DME 0x00000100 /* DTLB miss exception */
-#define SPR_DRR_IME 0x00000200 /* ITLB miss exception */
-#define SPR_DRR_RE 0x00000400 /* Range exception */
-#define SPR_DRR_SCE 0x00000800 /* System call exception */
-#define SPR_DRR_FPE 0x00001000 /* Floating Point Exception */
-#define SPR_DRR_TE 0x00002000 /* Trap exception */
-
-/*
- * Bit definitions for Performance counters mode registers
- *
- */
-#define SPR_PCMR_CP 0x00000001 /* Counter present */
-#define SPR_PCMR_UMRA 0x00000002 /* User mode read access */
-#define SPR_PCMR_CISM 0x00000004 /* Count in supervisor mode */
-#define SPR_PCMR_CIUM 0x00000008 /* Count in user mode */
-#define SPR_PCMR_LA 0x00000010 /* Load access event */
-#define SPR_PCMR_SA 0x00000020 /* Store access event */
-#define SPR_PCMR_IF 0x00000040 /* Instruction fetch event*/
-#define SPR_PCMR_DCM 0x00000080 /* Data cache miss event */
-#define SPR_PCMR_ICM 0x00000100 /* Insn cache miss event */
-#define SPR_PCMR_IFS 0x00000200 /* Insn fetch stall event */
-#define SPR_PCMR_LSUS 0x00000400 /* LSU stall event */
-#define SPR_PCMR_BS 0x00000800 /* Branch stall event */
-#define SPR_PCMR_DTLBM 0x00001000 /* DTLB miss event */
-#define SPR_PCMR_ITLBM 0x00002000 /* ITLB miss event */
-#define SPR_PCMR_DDS 0x00004000 /* Data dependency stall event */
-#define SPR_PCMR_WPE 0x03ff8000 /* Watchpoint events */
-
-/*
- * Bit definitions for the Power management register
- *
- */
-#define SPR_PMR_SDF 0x0000000f /* Slow down factor */
-#define SPR_PMR_DME 0x00000010 /* Doze mode enable */
-#define SPR_PMR_SME 0x00000020 /* Sleep mode enable */
-#define SPR_PMR_DCGE 0x00000040 /* Dynamic clock gating enable */
-#define SPR_PMR_SUME 0x00000080 /* Suspend mode enable */
-
-/*
- * Bit definitions for PICMR
- *
- */
-#define SPR_PICMR_IUM 0xfffffffc /* Interrupt unmask */
-
-/*
- * Bit definitions for PICPR
- *
- */
-#define SPR_PICPR_IPRIO 0xfffffffc /* Interrupt priority */
-
-/*
- * Bit definitions for PICSR
- *
- */
-#define SPR_PICSR_IS 0xffffffff /* Interrupt status */
-
-/*
- * Bit definitions for Tick Timer Control Register
- *
- */
-#define SPR_TTCR_PERIOD 0x0fffffff /* Time Period */
-#define SPR_TTMR_PERIOD SPR_TTCR_PERIOD
-#define SPR_TTMR_IP 0x10000000 /* Interrupt Pending */
-#define SPR_TTMR_IE 0x20000000 /* Interrupt Enable */
-#define SPR_TTMR_RT 0x40000000 /* Restart tick */
-#define SPR_TTMR_SR 0x80000000 /* Single run */
-#define SPR_TTMR_CR 0xc0000000 /* Continuous run */
-#define SPR_TTMR_M 0xc0000000 /* Tick mode */
-
-/*
- * Bit definitions for the FP Control Status Register
- *
- */
-#define SPR_FPCSR_FPEE 0x00000001 /* Floating Point Exception Enable */
-#define SPR_FPCSR_RM 0x00000006 /* Rounding Mode */
-#define SPR_FPCSR_OVF 0x00000008 /* Overflow Flag */
-#define SPR_FPCSR_UNF 0x00000010 /* Underflow Flag */
-#define SPR_FPCSR_SNF 0x00000020 /* SNAN Flag */
-#define SPR_FPCSR_QNF 0x00000040 /* QNAN Flag */
-#define SPR_FPCSR_ZF 0x00000080 /* Zero Flag */
-#define SPR_FPCSR_IXF 0x00000100 /* Inexact Flag */
-#define SPR_FPCSR_IVF 0x00000200 /* Invalid Flag */
-#define SPR_FPCSR_INF 0x00000400 /* Infinity Flag */
-#define SPR_FPCSR_DZF 0x00000800 /* Divide By Zero Flag */
-#define SPR_FPCSR_ALLF (SPR_FPCSR_OVF | SPR_FPCSR_UNF | SPR_FPCSR_SNF | \
- SPR_FPCSR_QNF | SPR_FPCSR_ZF | SPR_FPCSR_IXF | \
- SPR_FPCSR_IVF | SPR_FPCSR_INF | SPR_FPCSR_DZF)
-
-#define FPCSR_RM_RN (0<<1)
-#define FPCSR_RM_RZ (1<<1)
-#define FPCSR_RM_RIP (2<<1)
-#define FPCSR_RM_RIN (3<<1)
-
-#endif /* SPR_DEFS__H */
+++ /dev/null
-#ifndef __STDARG_H
-#define __STDARG_H
-
-#include <stdlib.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define va_start(v, l) __builtin_va_start((v), l)
-#define va_arg(ap, type) __builtin_va_arg((ap), type)
-#define va_copy(aq, ap) __builtin_va_copy((aq), (ap))
-#define va_end(ap) __builtin_va_end(ap)
-#define va_list __builtin_va_list
-
-int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
-int vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
-int vsprintf(char *buf, const char *fmt, va_list args);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STDARG_H */
+++ /dev/null
-#ifndef __STDBOOL_H
-#define __STDBOOL_H
-
-#define bool _Bool
-#define true 1
-#define false 0
-
-#endif /* __STDBOOL_H */
+++ /dev/null
-#ifndef __STDDEF_H
-#define __STDDEF_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifdef __cplusplus
-#define NULL 0
-#else
-#define NULL ((void *)0)
-#endif
-
-typedef unsigned long size_t;
-typedef long ptrdiff_t;
-
-#define offsetof(s,m) (size_t)&(((s *)0)->m)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STDDEF_H */
+++ /dev/null
-#ifndef __STDINT_H
-#define __STDINT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef int intptr_t;
-typedef unsigned int uintptr_t;
-
-typedef unsigned long long uint64_t;
-typedef unsigned int uint32_t;
-typedef unsigned short uint16_t;
-typedef unsigned char uint8_t;
-
-typedef long long int64_t;
-typedef int int32_t;
-typedef short int16_t;
-typedef char int8_t;
-
-#define __int_c_join(a, b) a ## b
-#define __int_c(v, suffix) __int_c_join(v, suffix)
-#define __uint_c(v, suffix) __int_c_join(v##U, suffix)
-
-#define INT64_C(v) __int_c(v, LL)
-#define UINT64_C(v) __uint_c(v, LL)
-#define INT32_C(v) v
-#define UINT32_C(v) v##U
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STDINT_H */
+++ /dev/null
-#ifndef __STDIO_H
-#define __STDIO_H
-
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int putchar(int c);
-int puts(const char *s);
-
-int snprintf(char *buf, size_t size, const char *fmt, ...);
-int scnprintf(char *buf, size_t size, const char *fmt, ...);
-int sprintf(char *buf, const char *fmt, ...);
-
-int printf(const char *fmt, ...);
-
-/* Not sure this belongs here... */
-typedef long long loff_t;
-typedef long off_t;
-typedef int mode_t;
-typedef int dev_t;
-
-/*
- * Note: this library does not provide FILE operations.
- * User code must implement them.
- */
-
-#ifndef BUFSIZ
-#define BUFSIZ 1024
-#endif
-
-#ifndef EOF
-#define EOF -1
-#endif
-
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#endif
-
-#ifndef SEEK_CUR
-#define SEEK_CUR 1
-#endif
-
-#ifndef SEEK_END
-#define SEEK_END 2
-#endif
-
-typedef int FILE;
-
-extern FILE *stdin;
-extern FILE *stdout;
-extern FILE *stderr;
-
-int fprintf(FILE *stream, const char *format, ...);
-int fflush(FILE *stream);
-
-FILE *fopen(const char *path, const char *mode);
-FILE *freopen(const char *path, const char *mode, FILE *stream);
-char *fgets(char *s, int size, FILE *stream);
-size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
-size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
-int getc(FILE *stream);
-int fputc(int c, FILE *stream);
-int ferror(FILE *stream);
-int feof(FILE *stream);
-int fclose(FILE *fp);
-
-int fseek(FILE *stream, long offset, int whence);
-long ftell(FILE *stream);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STDIO_H */
+++ /dev/null
-/*
- * MiSoC
- * Copyright (C) 2007, 2008, 2009, 2011 Sebastien Bourdeauducq
- * Copyright (C) Linux kernel developers
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __STDLIB_H
-#define __STDLIB_H
-
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define PRINTF_ZEROPAD 1 /* pad with zero */
-#define PRINTF_SIGN 2 /* unsigned/signed long */
-#define PRINTF_PLUS 4 /* show plus */
-#define PRINTF_SPACE 8 /* space if plus */
-#define PRINTF_LEFT 16 /* left justified */
-#define PRINTF_SPECIAL 32 /* 0x */
-#define PRINTF_LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
-
-#define likely(x) x
-#define unlikely(x) x
-
-static inline int abs(int x)
-{
- return x > 0 ? x : -x;
-}
-
-static inline long int labs(long int x)
-{
- return x > 0 ? x : -x;
-}
-
-unsigned long strtoul(const char *nptr, char **endptr, int base);
-long strtol(const char *nptr, char **endptr, int base);
-double strtod(const char *str, char **endptr);
-
-int skip_atoi(const char **s);
-static inline int atoi(const char *nptr) {
- return strtol(nptr, NULL, 10);
-}
-static inline long atol(const char *nptr) {
- return (long)atoi(nptr);
-}
-char *number(char *buf, char *end, unsigned long num, int base, int size, int precision, int type);
-
-#define RAND_MAX 2147483647
-
-unsigned int rand(void);
-void srand(unsigned int seed);
-void abort(void) __attribute__((noreturn));
-
-void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));
-
-/*
- * The following functions are not provided by this library.
- */
-
-char *getenv(const char *name);
-
-void *malloc(size_t size);
-void free(void *ptr);
-void *realloc(void *ptr, size_t size);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STDLIB_H */
+++ /dev/null
-/*
- * MiSoC
- * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
- * Copyright (C) Linus Torvalds and Linux kernel developers
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __STRING_H
-#define __STRING_H
-
-#include <stddef.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-char *strchr(const char *s, int c);
-char *strpbrk(const char *,const char *);
-char *strrchr(const char *s, int c);
-char *strnchr(const char *s, size_t count, int c);
-char *strcpy(char *dest, const char *src);
-char *strncpy(char *dest, const char *src, size_t count);
-int strcmp(const char *cs, const char *ct);
-int strncmp(const char *cs, const char *ct, size_t count);
-char *strcat(char *dest, const char *src);
-char *strncat(char *dest, const char *src, size_t n);
-size_t strlen(const char *s);
-size_t strnlen(const char *s, size_t count);
-size_t strspn(const char *s, const char *accept);
-int memcmp(const void *cs, const void *ct, size_t count);
-void *memset(void *s, int c, size_t count);
-void *memcpy(void *to, const void *from, size_t n);
-void *memmove(void *dest, const void *src, size_t count);
-char *strstr(const char *s1, const char *s2);
-void *memchr(const void *s, int c, size_t n);
-
-char *strerror(int errnum);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STRING_H */
+++ /dev/null
-#ifndef __SYSTEM_H
-#define __SYSTEM_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void flush_cpu_icache(void);
-void flush_cpu_dcache(void);
-void flush_l2_cache(void);
-
-#ifdef __or1k__
-#include <spr-defs.h>
-static inline unsigned long mfspr(unsigned long add)
-{
- unsigned long ret;
-
- __asm__ __volatile__ ("l.mfspr %0,r0,%1" : "=r" (ret) : "K" (add));
-
- return ret;
-}
-
-static inline void mtspr(unsigned long add, unsigned long val)
-{
- __asm__ __volatile__ ("l.mtspr r0,%1,%0" : : "K" (add), "r" (val));
-}
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __SYSTEM_H */
+++ /dev/null
-#ifndef __TIME_H
-#define __TIME_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void time_init(void);
-int elapsed(int *last_event, int period);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __TIME_H */
+++ /dev/null
-#ifndef __UART_H
-#define __UART_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void uart_init(void);
-void uart_isr(void);
-void uart_sync(void);
-
-void uart_write(char c);
-char uart_read(void);
-int uart_read_nonblock(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+++ /dev/null
-#ifndef __CXX_ALGORITHM
-#define __CXX_ALGORITHM
-
-#endif /* __CXX_ALGORITHM */
+++ /dev/null
-#ifndef __CXX_CSTDDEF
-#define __CXX_CSTDDEF
-
-#include <stddef.h>
-
-namespace std {
- using ::size_t;
- using ::ptrdiff_t;
-}
-
-#endif /* __CXX_CSTDDEF */
+++ /dev/null
-#ifndef __CXX_CSTDLIB
-#define __CXX_CSTDLIB
-
-#include <stdlib.h>
-
-#endif /* __CXX_CSTDLIB */
+++ /dev/null
-#ifndef __CXX_NEW
-#define __CXX_NEW
-
-#include <cstddef>
-
-inline void* operator new (std::size_t size, void* ptr) noexcept
- { return ptr; }
-
-#endif /* __CXX_NEW */
+++ /dev/null
-#ifndef __DLFCN_H
-#define __DLFCN_H
-
-typedef struct
-{
- const char *dli_fname; /* File name of defining object. */
- void *dli_fbase; /* Load address of that object. */
- const char *dli_sname; /* Name of nearest symbol. */
- void *dli_saddr; /* Exact value of nearest symbol. */
-} Dl_info;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern int dl_iterate_phdr (int (*__callback) (struct dl_phdr_info *,
- size_t, void *),
- void *__data);
-
-/* Fill in *INFO with the following information about ADDRESS.
- Returns 0 iff no shared object's segments contain that address. */
-extern int dladdr (const void *__address, Dl_info *__info);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __DLFCN_H */
+++ /dev/null
-#ifndef __DYLD_H
-#define __DYLD_H
-
-#include <elf.h>
-
-struct dyld_info {
- Elf32_Addr base;
- const void *init;
- const char *strtab;
- const Elf32_Sym *symtab;
- struct {
- Elf32_Word nbucket;
- Elf32_Word nchain;
- const Elf32_Word *bucket;
- const Elf32_Word *chain;
- } hash;
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-int dyld_load(const void *shlib, Elf32_Addr base,
- Elf32_Addr (*resolve_import)(const char *),
- struct dyld_info *info, const char **error_out);
-void *dyld_lookup(const char *symbol, struct dyld_info *info);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __DYLD_H */
+++ /dev/null
-/* This file defines standard ELF types, structures, and macros.
- Copyright (C) 1995-2014 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-#ifndef _ELF_H
-#define _ELF_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Standard ELF types. */
-
-#include <stdint.h>
-
-/* Type for a 16-bit quantity. */
-typedef uint16_t Elf32_Half;
-typedef uint16_t Elf64_Half;
-
-/* Types for signed and unsigned 32-bit quantities. */
-typedef uint32_t Elf32_Word;
-typedef int32_t Elf32_Sword;
-typedef uint32_t Elf64_Word;
-typedef int32_t Elf64_Sword;
-
-/* Types for signed and unsigned 64-bit quantities. */
-typedef uint64_t Elf32_Xword;
-typedef int64_t Elf32_Sxword;
-typedef uint64_t Elf64_Xword;
-typedef int64_t Elf64_Sxword;
-
-/* Type of addresses. */
-typedef uint32_t Elf32_Addr;
-typedef uint64_t Elf64_Addr;
-
-/* Type of file offsets. */
-typedef uint32_t Elf32_Off;
-typedef uint64_t Elf64_Off;
-
-/* Type for section indices, which are 16-bit quantities. */
-typedef uint16_t Elf32_Section;
-typedef uint16_t Elf64_Section;
-
-/* Type for version symbol information. */
-typedef Elf32_Half Elf32_Versym;
-typedef Elf64_Half Elf64_Versym;
-
-
-/* The ELF file header. This appears at the start of every ELF file. */
-
-#define EI_NIDENT (16)
-
-typedef struct
-{
- unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
- Elf32_Half e_type; /* Object file type */
- Elf32_Half e_machine; /* Architecture */
- Elf32_Word e_version; /* Object file version */
- Elf32_Addr e_entry; /* Entry point virtual address */
- Elf32_Off e_phoff; /* Program header table file offset */
- Elf32_Off e_shoff; /* Section header table file offset */
- Elf32_Word e_flags; /* Processor-specific flags */
- Elf32_Half e_ehsize; /* ELF header size in bytes */
- Elf32_Half e_phentsize; /* Program header table entry size */
- Elf32_Half e_phnum; /* Program header table entry count */
- Elf32_Half e_shentsize; /* Section header table entry size */
- Elf32_Half e_shnum; /* Section header table entry count */
- Elf32_Half e_shstrndx; /* Section header string table index */
-} Elf32_Ehdr;
-
-typedef struct
-{
- unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
- Elf64_Half e_type; /* Object file type */
- Elf64_Half e_machine; /* Architecture */
- Elf64_Word e_version; /* Object file version */
- Elf64_Addr e_entry; /* Entry point virtual address */
- Elf64_Off e_phoff; /* Program header table file offset */
- Elf64_Off e_shoff; /* Section header table file offset */
- Elf64_Word e_flags; /* Processor-specific flags */
- Elf64_Half e_ehsize; /* ELF header size in bytes */
- Elf64_Half e_phentsize; /* Program header table entry size */
- Elf64_Half e_phnum; /* Program header table entry count */
- Elf64_Half e_shentsize; /* Section header table entry size */
- Elf64_Half e_shnum; /* Section header table entry count */
- Elf64_Half e_shstrndx; /* Section header string table index */
-} Elf64_Ehdr;
-
-/* Fields in the e_ident array. The EI_* macros are indices into the
- array. The macros under each EI_* macro are the values the byte
- may have. */
-
-#define EI_MAG0 0 /* File identification byte 0 index */
-#define ELFMAG0 0x7f /* Magic number byte 0 */
-
-#define EI_MAG1 1 /* File identification byte 1 index */
-#define ELFMAG1 'E' /* Magic number byte 1 */
-
-#define EI_MAG2 2 /* File identification byte 2 index */
-#define ELFMAG2 'L' /* Magic number byte 2 */
-
-#define EI_MAG3 3 /* File identification byte 3 index */
-#define ELFMAG3 'F' /* Magic number byte 3 */
-
-/* Conglomeration of the identification bytes, for easy testing as a word. */
-#define ELFMAG "\177ELF"
-#define SELFMAG 4
-
-#define EI_CLASS 4 /* File class byte index */
-#define ELFCLASSNONE 0 /* Invalid class */
-#define ELFCLASS32 1 /* 32-bit objects */
-#define ELFCLASS64 2 /* 64-bit objects */
-#define ELFCLASSNUM 3
-
-#define EI_DATA 5 /* Data encoding byte index */
-#define ELFDATANONE 0 /* Invalid data encoding */
-#define ELFDATA2LSB 1 /* 2's complement, little endian */
-#define ELFDATA2MSB 2 /* 2's complement, big endian */
-#define ELFDATANUM 3
-
-#define EI_VERSION 6 /* File version byte index */
- /* Value must be EV_CURRENT */
-
-#define EI_OSABI 7 /* OS ABI identification */
-#define ELFOSABI_NONE 0 /* UNIX System V ABI */
-#define ELFOSABI_SYSV 0 /* Alias. */
-#define ELFOSABI_HPUX 1 /* HP-UX */
-#define ELFOSABI_NETBSD 2 /* NetBSD. */
-#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */
-#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */
-#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */
-#define ELFOSABI_AIX 7 /* IBM AIX. */
-#define ELFOSABI_IRIX 8 /* SGI Irix. */
-#define ELFOSABI_FREEBSD 9 /* FreeBSD. */
-#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */
-#define ELFOSABI_MODESTO 11 /* Novell Modesto. */
-#define ELFOSABI_OPENBSD 12 /* OpenBSD. */
-#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */
-#define ELFOSABI_ARM 97 /* ARM */
-#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
-
-#define EI_ABIVERSION 8 /* ABI version */
-
-#define EI_PAD 9 /* Byte index of padding bytes */
-
-/* Legal values for e_type (object file type). */
-
-#define ET_NONE 0 /* No file type */
-#define ET_REL 1 /* Relocatable file */
-#define ET_EXEC 2 /* Executable file */
-#define ET_DYN 3 /* Shared object file */
-#define ET_CORE 4 /* Core file */
-#define ET_NUM 5 /* Number of defined types */
-#define ET_LOOS 0xfe00 /* OS-specific range start */
-#define ET_HIOS 0xfeff /* OS-specific range end */
-#define ET_LOPROC 0xff00 /* Processor-specific range start */
-#define ET_HIPROC 0xffff /* Processor-specific range end */
-
-/* Legal values for e_machine (architecture). */
-
-#define EM_NONE 0 /* No machine */
-#define EM_M32 1 /* AT&T WE 32100 */
-#define EM_SPARC 2 /* SUN SPARC */
-#define EM_386 3 /* Intel 80386 */
-#define EM_68K 4 /* Motorola m68k family */
-#define EM_88K 5 /* Motorola m88k family */
-#define EM_860 7 /* Intel 80860 */
-#define EM_MIPS 8 /* MIPS R3000 big-endian */
-#define EM_S370 9 /* IBM System/370 */
-#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */
-
-#define EM_PARISC 15 /* HPPA */
-#define EM_VPP500 17 /* Fujitsu VPP500 */
-#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
-#define EM_960 19 /* Intel 80960 */
-#define EM_PPC 20 /* PowerPC */
-#define EM_PPC64 21 /* PowerPC 64-bit */
-#define EM_S390 22 /* IBM S390 */
-
-#define EM_V800 36 /* NEC V800 series */
-#define EM_FR20 37 /* Fujitsu FR20 */
-#define EM_RH32 38 /* TRW RH-32 */
-#define EM_RCE 39 /* Motorola RCE */
-#define EM_ARM 40 /* ARM */
-#define EM_FAKE_ALPHA 41 /* Digital Alpha */
-#define EM_SH 42 /* Hitachi SH */
-#define EM_SPARCV9 43 /* SPARC v9 64-bit */
-#define EM_TRICORE 44 /* Siemens Tricore */
-#define EM_ARC 45 /* Argonaut RISC Core */
-#define EM_H8_300 46 /* Hitachi H8/300 */
-#define EM_H8_300H 47 /* Hitachi H8/300H */
-#define EM_H8S 48 /* Hitachi H8S */
-#define EM_H8_500 49 /* Hitachi H8/500 */
-#define EM_IA_64 50 /* Intel Merced */
-#define EM_MIPS_X 51 /* Stanford MIPS-X */
-#define EM_COLDFIRE 52 /* Motorola Coldfire */
-#define EM_68HC12 53 /* Motorola M68HC12 */
-#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/
-#define EM_PCP 55 /* Siemens PCP */
-#define EM_NCPU 56 /* Sony nCPU embeeded RISC */
-#define EM_NDR1 57 /* Denso NDR1 microprocessor */
-#define EM_STARCORE 58 /* Motorola Start*Core processor */
-#define EM_ME16 59 /* Toyota ME16 processor */
-#define EM_ST100 60 /* STMicroelectronic ST100 processor */
-#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/
-#define EM_X86_64 62 /* AMD x86-64 architecture */
-#define EM_PDSP 63 /* Sony DSP Processor */
-
-#define EM_FX66 66 /* Siemens FX66 microcontroller */
-#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */
-#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */
-#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */
-#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */
-#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */
-#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */
-#define EM_SVX 73 /* Silicon Graphics SVx */
-#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */
-#define EM_VAX 75 /* Digital VAX */
-#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
-#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */
-#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */
-#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */
-#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */
-#define EM_HUANY 81 /* Harvard University machine-independent object files */
-#define EM_PRISM 82 /* SiTera Prism */
-#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
-#define EM_FR30 84 /* Fujitsu FR30 */
-#define EM_D10V 85 /* Mitsubishi D10V */
-#define EM_D30V 86 /* Mitsubishi D30V */
-#define EM_V850 87 /* NEC v850 */
-#define EM_M32R 88 /* Mitsubishi M32R */
-#define EM_MN10300 89 /* Matsushita MN10300 */
-#define EM_MN10200 90 /* Matsushita MN10200 */
-#define EM_PJ 91 /* picoJava */
-#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
-#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */
-#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */
-#define EM_AARCH64 183 /* ARM AARCH64 */
-#define EM_TILEPRO 188 /* Tilera TILEPro */
-#define EM_MICROBLAZE 189 /* Xilinx MicroBlaze */
-#define EM_TILEGX 191 /* Tilera TILE-Gx */
-#define EM_NUM 192
-
-/* If it is necessary to assign new unofficial EM_* values, please
- pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
- chances of collision with official or non-GNU unofficial values. */
-
-#define EM_ALPHA 0x9026
-
-/* Legal values for e_version (version). */
-
-#define EV_NONE 0 /* Invalid ELF version */
-#define EV_CURRENT 1 /* Current version */
-#define EV_NUM 2
-
-/* Section header. */
-
-typedef struct
-{
- Elf32_Word sh_name; /* Section name (string tbl index) */
- Elf32_Word sh_type; /* Section type */
- Elf32_Word sh_flags; /* Section flags */
- Elf32_Addr sh_addr; /* Section virtual addr at execution */
- Elf32_Off sh_offset; /* Section file offset */
- Elf32_Word sh_size; /* Section size in bytes */
- Elf32_Word sh_link; /* Link to another section */
- Elf32_Word sh_info; /* Additional section information */
- Elf32_Word sh_addralign; /* Section alignment */
- Elf32_Word sh_entsize; /* Entry size if section holds table */
-} Elf32_Shdr;
-
-typedef struct
-{
- Elf64_Word sh_name; /* Section name (string tbl index) */
- Elf64_Word sh_type; /* Section type */
- Elf64_Xword sh_flags; /* Section flags */
- Elf64_Addr sh_addr; /* Section virtual addr at execution */
- Elf64_Off sh_offset; /* Section file offset */
- Elf64_Xword sh_size; /* Section size in bytes */
- Elf64_Word sh_link; /* Link to another section */
- Elf64_Word sh_info; /* Additional section information */
- Elf64_Xword sh_addralign; /* Section alignment */
- Elf64_Xword sh_entsize; /* Entry size if section holds table */
-} Elf64_Shdr;
-
-/* Special section indices. */
-
-#define SHN_UNDEF 0 /* Undefined section */
-#define SHN_LORESERVE 0xff00 /* Start of reserved indices */
-#define SHN_LOPROC 0xff00 /* Start of processor-specific */
-#define SHN_BEFORE 0xff00 /* Order section before all others
- (Solaris). */
-#define SHN_AFTER 0xff01 /* Order section after all others
- (Solaris). */
-#define SHN_HIPROC 0xff1f /* End of processor-specific */
-#define SHN_LOOS 0xff20 /* Start of OS-specific */
-#define SHN_HIOS 0xff3f /* End of OS-specific */
-#define SHN_ABS 0xfff1 /* Associated symbol is absolute */
-#define SHN_COMMON 0xfff2 /* Associated symbol is common */
-#define SHN_XINDEX 0xffff /* Index is in extra table. */
-#define SHN_HIRESERVE 0xffff /* End of reserved indices */
-
-/* Legal values for sh_type (section type). */
-
-#define SHT_NULL 0 /* Section header table entry unused */
-#define SHT_PROGBITS 1 /* Program data */
-#define SHT_SYMTAB 2 /* Symbol table */
-#define SHT_STRTAB 3 /* String table */
-#define SHT_RELA 4 /* Relocation entries with addends */
-#define SHT_HASH 5 /* Symbol hash table */
-#define SHT_DYNAMIC 6 /* Dynamic linking information */
-#define SHT_NOTE 7 /* Notes */
-#define SHT_NOBITS 8 /* Program space with no data (bss) */
-#define SHT_REL 9 /* Relocation entries, no addends */
-#define SHT_SHLIB 10 /* Reserved */
-#define SHT_DYNSYM 11 /* Dynamic linker symbol table */
-#define SHT_INIT_ARRAY 14 /* Array of constructors */
-#define SHT_FINI_ARRAY 15 /* Array of destructors */
-#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
-#define SHT_GROUP 17 /* Section group */
-#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
-#define SHT_NUM 19 /* Number of defined types. */
-#define SHT_LOOS 0x60000000 /* Start OS-specific. */
-#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */
-#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */
-#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */
-#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */
-#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */
-#define SHT_SUNW_move 0x6ffffffa
-#define SHT_SUNW_COMDAT 0x6ffffffb
-#define SHT_SUNW_syminfo 0x6ffffffc
-#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */
-#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */
-#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */
-#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */
-#define SHT_HIOS 0x6fffffff /* End OS-specific type */
-#define SHT_LOPROC 0x70000000 /* Start of processor-specific */
-#define SHT_HIPROC 0x7fffffff /* End of processor-specific */
-#define SHT_LOUSER 0x80000000 /* Start of application-specific */
-#define SHT_HIUSER 0x8fffffff /* End of application-specific */
-
-/* Legal values for sh_flags (section flags). */
-
-#define SHF_WRITE (1 << 0) /* Writable */
-#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */
-#define SHF_EXECINSTR (1 << 2) /* Executable */
-#define SHF_MERGE (1 << 4) /* Might be merged */
-#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */
-#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */
-#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */
-#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling
- required */
-#define SHF_GROUP (1 << 9) /* Section is member of a group. */
-#define SHF_TLS (1 << 10) /* Section hold thread-local data. */
-#define SHF_MASKOS 0x0ff00000 /* OS-specific. */
-#define SHF_MASKPROC 0xf0000000 /* Processor-specific */
-#define SHF_ORDERED (1 << 30) /* Special ordering requirement
- (Solaris). */
-#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless
- referenced or allocated (Solaris).*/
-
-/* Section group handling. */
-#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */
-
-/* Symbol table entry. */
-
-typedef struct
-{
- Elf32_Word st_name; /* Symbol name (string tbl index) */
- Elf32_Addr st_value; /* Symbol value */
- Elf32_Word st_size; /* Symbol size */
- unsigned char st_info; /* Symbol type and binding */
- unsigned char st_other; /* Symbol visibility */
- Elf32_Section st_shndx; /* Section index */
-} Elf32_Sym;
-
-typedef struct
-{
- Elf64_Word st_name; /* Symbol name (string tbl index) */
- unsigned char st_info; /* Symbol type and binding */
- unsigned char st_other; /* Symbol visibility */
- Elf64_Section st_shndx; /* Section index */
- Elf64_Addr st_value; /* Symbol value */
- Elf64_Xword st_size; /* Symbol size */
-} Elf64_Sym;
-
-/* The syminfo section if available contains additional information about
- every dynamic symbol. */
-
-typedef struct
-{
- Elf32_Half si_boundto; /* Direct bindings, symbol bound to */
- Elf32_Half si_flags; /* Per symbol flags */
-} Elf32_Syminfo;
-
-typedef struct
-{
- Elf64_Half si_boundto; /* Direct bindings, symbol bound to */
- Elf64_Half si_flags; /* Per symbol flags */
-} Elf64_Syminfo;
-
-/* Possible values for si_boundto. */
-#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */
-#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */
-#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */
-
-/* Possible bitmasks for si_flags. */
-#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */
-#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */
-#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */
-#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy
- loaded */
-/* Syminfo version values. */
-#define SYMINFO_NONE 0
-#define SYMINFO_CURRENT 1
-#define SYMINFO_NUM 2
-
-
-/* How to extract and insert information held in the st_info field. */
-
-#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4)
-#define ELF32_ST_TYPE(val) ((val) & 0xf)
-#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
-
-/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */
-#define ELF64_ST_BIND(val) ELF32_ST_BIND (val)
-#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val)
-#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type))
-
-/* Legal values for ST_BIND subfield of st_info (symbol binding). */
-
-#define STB_LOCAL 0 /* Local symbol */
-#define STB_GLOBAL 1 /* Global symbol */
-#define STB_WEAK 2 /* Weak symbol */
-#define STB_NUM 3 /* Number of defined types. */
-#define STB_LOOS 10 /* Start of OS-specific */
-#define STB_GNU_UNIQUE 10 /* Unique symbol. */
-#define STB_HIOS 12 /* End of OS-specific */
-#define STB_LOPROC 13 /* Start of processor-specific */
-#define STB_HIPROC 15 /* End of processor-specific */
-
-/* Legal values for ST_TYPE subfield of st_info (symbol type). */
-
-#define STT_NOTYPE 0 /* Symbol type is unspecified */
-#define STT_OBJECT 1 /* Symbol is a data object */
-#define STT_FUNC 2 /* Symbol is a code object */
-#define STT_SECTION 3 /* Symbol associated with a section */
-#define STT_FILE 4 /* Symbol's name is file name */
-#define STT_COMMON 5 /* Symbol is a common data object */
-#define STT_TLS 6 /* Symbol is thread-local data object*/
-#define STT_NUM 7 /* Number of defined types. */
-#define STT_LOOS 10 /* Start of OS-specific */
-#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */
-#define STT_HIOS 12 /* End of OS-specific */
-#define STT_LOPROC 13 /* Start of processor-specific */
-#define STT_HIPROC 15 /* End of processor-specific */
-
-
-/* Symbol table indices are found in the hash buckets and chain table
- of a symbol hash table section. This special index value indicates
- the end of a chain, meaning no further symbols are found in that bucket. */
-
-#define STN_UNDEF 0 /* End of a chain. */
-
-
-/* How to extract and insert information held in the st_other field. */
-
-#define ELF32_ST_VISIBILITY(o) ((o) & 0x03)
-
-/* For ELF64 the definitions are the same. */
-#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o)
-
-/* Symbol visibility specification encoded in the st_other field. */
-#define STV_DEFAULT 0 /* Default symbol visibility rules */
-#define STV_INTERNAL 1 /* Processor specific hidden class */
-#define STV_HIDDEN 2 /* Sym unavailable in other modules */
-#define STV_PROTECTED 3 /* Not preemptible, not exported */
-
-
-/* Relocation table entry without addend (in section of type SHT_REL). */
-
-typedef struct
-{
- Elf32_Addr r_offset; /* Address */
- Elf32_Word r_info; /* Relocation type and symbol index */
-} Elf32_Rel;
-
-/* I have seen two different definitions of the Elf64_Rel and
- Elf64_Rela structures, so we'll leave them out until Novell (or
- whoever) gets their act together. */
-/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */
-
-typedef struct
-{
- Elf64_Addr r_offset; /* Address */
- Elf64_Xword r_info; /* Relocation type and symbol index */
-} Elf64_Rel;
-
-/* Relocation table entry with addend (in section of type SHT_RELA). */
-
-typedef struct
-{
- Elf32_Addr r_offset; /* Address */
- Elf32_Word r_info; /* Relocation type and symbol index */
- Elf32_Sword r_addend; /* Addend */
-} Elf32_Rela;
-
-typedef struct
-{
- Elf64_Addr r_offset; /* Address */
- Elf64_Xword r_info; /* Relocation type and symbol index */
- Elf64_Sxword r_addend; /* Addend */
-} Elf64_Rela;
-
-/* How to extract and insert information held in the r_info field. */
-
-#define ELF32_R_SYM(val) ((val) >> 8)
-#define ELF32_R_TYPE(val) ((val) & 0xff)
-#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff))
-
-#define ELF64_R_SYM(i) ((i) >> 32)
-#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
-#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type))
-
-/* Program segment header. */
-
-typedef struct
-{
- Elf32_Word p_type; /* Segment type */
- Elf32_Off p_offset; /* Segment file offset */
- Elf32_Addr p_vaddr; /* Segment virtual address */
- Elf32_Addr p_paddr; /* Segment physical address */
- Elf32_Word p_filesz; /* Segment size in file */
- Elf32_Word p_memsz; /* Segment size in memory */
- Elf32_Word p_flags; /* Segment flags */
- Elf32_Word p_align; /* Segment alignment */
-} Elf32_Phdr;
-
-typedef struct
-{
- Elf64_Word p_type; /* Segment type */
- Elf64_Word p_flags; /* Segment flags */
- Elf64_Off p_offset; /* Segment file offset */
- Elf64_Addr p_vaddr; /* Segment virtual address */
- Elf64_Addr p_paddr; /* Segment physical address */
- Elf64_Xword p_filesz; /* Segment size in file */
- Elf64_Xword p_memsz; /* Segment size in memory */
- Elf64_Xword p_align; /* Segment alignment */
-} Elf64_Phdr;
-
-/* Special value for e_phnum. This indicates that the real number of
- program headers is too large to fit into e_phnum. Instead the real
- value is in the field sh_info of section 0. */
-
-#define PN_XNUM 0xffff
-
-/* Legal values for p_type (segment type). */
-
-#define PT_NULL 0 /* Program header table entry unused */
-#define PT_LOAD 1 /* Loadable program segment */
-#define PT_DYNAMIC 2 /* Dynamic linking information */
-#define PT_INTERP 3 /* Program interpreter */
-#define PT_NOTE 4 /* Auxiliary information */
-#define PT_SHLIB 5 /* Reserved */
-#define PT_PHDR 6 /* Entry for header table itself */
-#define PT_TLS 7 /* Thread-local storage segment */
-#define PT_NUM 8 /* Number of defined types */
-#define PT_LOOS 0x60000000 /* Start of OS-specific */
-#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */
-#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */
-#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */
-#define PT_LOSUNW 0x6ffffffa
-#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
-#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */
-#define PT_HISUNW 0x6fffffff
-#define PT_HIOS 0x6fffffff /* End of OS-specific */
-#define PT_LOPROC 0x70000000 /* Start of processor-specific */
-#define PT_HIPROC 0x7fffffff /* End of processor-specific */
-
-/* Legal values for p_flags (segment flags). */
-
-#define PF_X (1 << 0) /* Segment is executable */
-#define PF_W (1 << 1) /* Segment is writable */
-#define PF_R (1 << 2) /* Segment is readable */
-#define PF_MASKOS 0x0ff00000 /* OS-specific */
-#define PF_MASKPROC 0xf0000000 /* Processor-specific */
-
-/* Legal values for note segment descriptor types for core files. */
-
-#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */
-#define NT_FPREGSET 2 /* Contains copy of fpregset struct */
-#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */
-#define NT_PRXREG 4 /* Contains copy of prxregset struct */
-#define NT_TASKSTRUCT 4 /* Contains copy of task structure */
-#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */
-#define NT_AUXV 6 /* Contains copy of auxv array */
-#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */
-#define NT_ASRS 8 /* Contains copy of asrset struct */
-#define NT_PSTATUS 10 /* Contains copy of pstatus struct */
-#define NT_PSINFO 13 /* Contains copy of psinfo struct */
-#define NT_PRCRED 14 /* Contains copy of prcred struct */
-#define NT_UTSNAME 15 /* Contains copy of utsname struct */
-#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */
-#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */
-#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */
-#define NT_SIGINFO 0x53494749 /* Contains copy of siginfo_t,
- size might increase */
-#define NT_FILE 0x46494c45 /* Contains information about mapped
- files */
-#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */
-#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
-#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */
-#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
-#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
-#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */
-#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
-#define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */
-#define NT_S390_TIMER 0x301 /* s390 timer register */
-#define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */
-#define NT_S390_TODPREG 0x303 /* s390 TOD programmable register */
-#define NT_S390_CTRS 0x304 /* s390 control registers */
-#define NT_S390_PREFIX 0x305 /* s390 prefix register */
-#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
-#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */
-#define NT_S390_TDB 0x308 /* s390 transaction diagnostic block */
-#define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */
-#define NT_ARM_TLS 0x401 /* ARM TLS register */
-#define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */
-#define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */
-
-/* Legal values for the note segment descriptor types for object files. */
-
-#define NT_VERSION 1 /* Contains a version string. */
-
-
-/* Dynamic section entry. */
-
-typedef struct
-{
- Elf32_Sword d_tag; /* Dynamic entry type */
- union
- {
- Elf32_Word d_val; /* Integer value */
- Elf32_Addr d_ptr; /* Address value */
- } d_un;
-} Elf32_Dyn;
-
-typedef struct
-{
- Elf64_Sxword d_tag; /* Dynamic entry type */
- union
- {
- Elf64_Xword d_val; /* Integer value */
- Elf64_Addr d_ptr; /* Address value */
- } d_un;
-} Elf64_Dyn;
-
-/* Legal values for d_tag (dynamic entry type). */
-
-#define DT_NULL 0 /* Marks end of dynamic section */
-#define DT_NEEDED 1 /* Name of needed library */
-#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */
-#define DT_PLTGOT 3 /* Processor defined value */
-#define DT_HASH 4 /* Address of symbol hash table */
-#define DT_STRTAB 5 /* Address of string table */
-#define DT_SYMTAB 6 /* Address of symbol table */
-#define DT_RELA 7 /* Address of Rela relocs */
-#define DT_RELASZ 8 /* Total size of Rela relocs */
-#define DT_RELAENT 9 /* Size of one Rela reloc */
-#define DT_STRSZ 10 /* Size of string table */
-#define DT_SYMENT 11 /* Size of one symbol table entry */
-#define DT_INIT 12 /* Address of init function */
-#define DT_FINI 13 /* Address of termination function */
-#define DT_SONAME 14 /* Name of shared object */
-#define DT_RPATH 15 /* Library search path (deprecated) */
-#define DT_SYMBOLIC 16 /* Start symbol search here */
-#define DT_REL 17 /* Address of Rel relocs */
-#define DT_RELSZ 18 /* Total size of Rel relocs */
-#define DT_RELENT 19 /* Size of one Rel reloc */
-#define DT_PLTREL 20 /* Type of reloc in PLT */
-#define DT_DEBUG 21 /* For debugging; unspecified */
-#define DT_TEXTREL 22 /* Reloc might modify .text */
-#define DT_JMPREL 23 /* Address of PLT relocs */
-#define DT_BIND_NOW 24 /* Process relocations of object */
-#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */
-#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */
-#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */
-#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */
-#define DT_RUNPATH 29 /* Library search path */
-#define DT_FLAGS 30 /* Flags for the object being loaded */
-#define DT_ENCODING 32 /* Start of encoded range */
-#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/
-#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */
-#define DT_NUM 34 /* Number used */
-#define DT_LOOS 0x6000000d /* Start of OS-specific */
-#define DT_HIOS 0x6ffff000 /* End of OS-specific */
-#define DT_LOPROC 0x70000000 /* Start of processor-specific */
-#define DT_HIPROC 0x7fffffff /* End of processor-specific */
-#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */
-
-/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
- Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's
- approach. */
-#define DT_VALRNGLO 0x6ffffd00
-#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */
-#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */
-#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */
-#define DT_CHECKSUM 0x6ffffdf8
-#define DT_PLTPADSZ 0x6ffffdf9
-#define DT_MOVEENT 0x6ffffdfa
-#define DT_MOVESZ 0x6ffffdfb
-#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */
-#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting
- the following DT_* entry. */
-#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */
-#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */
-#define DT_VALRNGHI 0x6ffffdff
-#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */
-#define DT_VALNUM 12
-
-/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
- Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
-
- If any adjustment is made to the ELF object after it has been
- built these entries will need to be adjusted. */
-#define DT_ADDRRNGLO 0x6ffffe00
-#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */
-#define DT_TLSDESC_PLT 0x6ffffef6
-#define DT_TLSDESC_GOT 0x6ffffef7
-#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */
-#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */
-#define DT_CONFIG 0x6ffffefa /* Configuration information. */
-#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */
-#define DT_AUDIT 0x6ffffefc /* Object auditing. */
-#define DT_PLTPAD 0x6ffffefd /* PLT padding. */
-#define DT_MOVETAB 0x6ffffefe /* Move table. */
-#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */
-#define DT_ADDRRNGHI 0x6ffffeff
-#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */
-#define DT_ADDRNUM 11
-
-/* The versioning entry types. The next are defined as part of the
- GNU extension. */
-#define DT_VERSYM 0x6ffffff0
-
-#define DT_RELACOUNT 0x6ffffff9
-#define DT_RELCOUNT 0x6ffffffa
-
-/* These were chosen by Sun. */
-#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */
-#define DT_VERDEF 0x6ffffffc /* Address of version definition
- table */
-#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */
-#define DT_VERNEED 0x6ffffffe /* Address of table with needed
- versions */
-#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */
-#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
-#define DT_VERSIONTAGNUM 16
-
-/* Sun added these machine-independent extensions in the "processor-specific"
- range. Be compatible. */
-#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */
-#define DT_FILTER 0x7fffffff /* Shared object to get values from */
-#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
-#define DT_EXTRANUM 3
-
-/* Values of `d_un.d_val' in the DT_FLAGS entry. */
-#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */
-#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */
-#define DF_TEXTREL 0x00000004 /* Object contains text relocations */
-#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */
-#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */
-
-/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
- entry in the dynamic section. */
-#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */
-#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */
-#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */
-#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/
-#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/
-#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/
-#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */
-#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */
-#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */
-#define DF_1_TRANS 0x00000200
-#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */
-#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */
-#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */
-#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/
-#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */
-#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */
-#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */
-#define DF_1_NODIRECT 0x00020000 /* Object has no-direct binding. */
-#define DF_1_IGNMULDEF 0x00040000
-#define DF_1_NOKSYMS 0x00080000
-#define DF_1_NOHDR 0x00100000
-#define DF_1_EDITED 0x00200000 /* Object is modified after built. */
-#define DF_1_NORELOC 0x00400000
-#define DF_1_SYMINTPOSE 0x00800000 /* Object has individual interposers. */
-#define DF_1_GLOBAUDIT 0x01000000 /* Global auditing required. */
-#define DF_1_SINGLETON 0x02000000 /* Singleton symbols are used. */
-
-/* Flags for the feature selection in DT_FEATURE_1. */
-#define DTF_1_PARINIT 0x00000001
-#define DTF_1_CONFEXP 0x00000002
-
-/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */
-#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */
-#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not
- generally available. */
-
-/* Version definition sections. */
-
-typedef struct
-{
- Elf32_Half vd_version; /* Version revision */
- Elf32_Half vd_flags; /* Version information */
- Elf32_Half vd_ndx; /* Version Index */
- Elf32_Half vd_cnt; /* Number of associated aux entries */
- Elf32_Word vd_hash; /* Version name hash value */
- Elf32_Word vd_aux; /* Offset in bytes to verdaux array */
- Elf32_Word vd_next; /* Offset in bytes to next verdef
- entry */
-} Elf32_Verdef;
-
-typedef struct
-{
- Elf64_Half vd_version; /* Version revision */
- Elf64_Half vd_flags; /* Version information */
- Elf64_Half vd_ndx; /* Version Index */
- Elf64_Half vd_cnt; /* Number of associated aux entries */
- Elf64_Word vd_hash; /* Version name hash value */
- Elf64_Word vd_aux; /* Offset in bytes to verdaux array */
- Elf64_Word vd_next; /* Offset in bytes to next verdef
- entry */
-} Elf64_Verdef;
-
-
-/* Legal values for vd_version (version revision). */
-#define VER_DEF_NONE 0 /* No version */
-#define VER_DEF_CURRENT 1 /* Current version */
-#define VER_DEF_NUM 2 /* Given version number */
-
-/* Legal values for vd_flags (version information flags). */
-#define VER_FLG_BASE 0x1 /* Version definition of file itself */
-#define VER_FLG_WEAK 0x2 /* Weak version identifier */
-
-/* Versym symbol index values. */
-#define VER_NDX_LOCAL 0 /* Symbol is local. */
-#define VER_NDX_GLOBAL 1 /* Symbol is global. */
-#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */
-#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */
-
-/* Auxialiary version information. */
-
-typedef struct
-{
- Elf32_Word vda_name; /* Version or dependency names */
- Elf32_Word vda_next; /* Offset in bytes to next verdaux
- entry */
-} Elf32_Verdaux;
-
-typedef struct
-{
- Elf64_Word vda_name; /* Version or dependency names */
- Elf64_Word vda_next; /* Offset in bytes to next verdaux
- entry */
-} Elf64_Verdaux;
-
-
-/* Version dependency section. */
-
-typedef struct
-{
- Elf32_Half vn_version; /* Version of structure */
- Elf32_Half vn_cnt; /* Number of associated aux entries */
- Elf32_Word vn_file; /* Offset of filename for this
- dependency */
- Elf32_Word vn_aux; /* Offset in bytes to vernaux array */
- Elf32_Word vn_next; /* Offset in bytes to next verneed
- entry */
-} Elf32_Verneed;
-
-typedef struct
-{
- Elf64_Half vn_version; /* Version of structure */
- Elf64_Half vn_cnt; /* Number of associated aux entries */
- Elf64_Word vn_file; /* Offset of filename for this
- dependency */
- Elf64_Word vn_aux; /* Offset in bytes to vernaux array */
- Elf64_Word vn_next; /* Offset in bytes to next verneed
- entry */
-} Elf64_Verneed;
-
-
-/* Legal values for vn_version (version revision). */
-#define VER_NEED_NONE 0 /* No version */
-#define VER_NEED_CURRENT 1 /* Current version */
-#define VER_NEED_NUM 2 /* Given version number */
-
-/* Auxiliary needed version information. */
-
-typedef struct
-{
- Elf32_Word vna_hash; /* Hash value of dependency name */
- Elf32_Half vna_flags; /* Dependency specific information */
- Elf32_Half vna_other; /* Unused */
- Elf32_Word vna_name; /* Dependency name string offset */
- Elf32_Word vna_next; /* Offset in bytes to next vernaux
- entry */
-} Elf32_Vernaux;
-
-typedef struct
-{
- Elf64_Word vna_hash; /* Hash value of dependency name */
- Elf64_Half vna_flags; /* Dependency specific information */
- Elf64_Half vna_other; /* Unused */
- Elf64_Word vna_name; /* Dependency name string offset */
- Elf64_Word vna_next; /* Offset in bytes to next vernaux
- entry */
-} Elf64_Vernaux;
-
-
-/* Legal values for vna_flags. */
-#define VER_FLG_WEAK 0x2 /* Weak version identifier */
-
-
-/* Auxiliary vector. */
-
-/* This vector is normally only used by the program interpreter. The
- usual definition in an ABI supplement uses the name auxv_t. The
- vector is not usually defined in a standard <elf.h> file, but it
- can't hurt. We rename it to avoid conflicts. The sizes of these
- types are an arrangement between the exec server and the program
- interpreter, so we don't fully specify them here. */
-
-typedef struct
-{
- uint32_t a_type; /* Entry type */
- union
- {
- uint32_t a_val; /* Integer value */
- /* We use to have pointer elements added here. We cannot do that,
- though, since it does not work when using 32-bit definitions
- on 64-bit platforms and vice versa. */
- } a_un;
-} Elf32_auxv_t;
-
-typedef struct
-{
- uint64_t a_type; /* Entry type */
- union
- {
- uint64_t a_val; /* Integer value */
- /* We use to have pointer elements added here. We cannot do that,
- though, since it does not work when using 32-bit definitions
- on 64-bit platforms and vice versa. */
- } a_un;
-} Elf64_auxv_t;
-
-/* Note section contents. Each entry in the note section begins with
- a header of a fixed form. */
-
-typedef struct
-{
- Elf32_Word n_namesz; /* Length of the note's name. */
- Elf32_Word n_descsz; /* Length of the note's descriptor. */
- Elf32_Word n_type; /* Type of the note. */
-} Elf32_Nhdr;
-
-typedef struct
-{
- Elf64_Word n_namesz; /* Length of the note's name. */
- Elf64_Word n_descsz; /* Length of the note's descriptor. */
- Elf64_Word n_type; /* Type of the note. */
-} Elf64_Nhdr;
-
-/* Known names of notes. */
-
-/* Solaris entries in the note section have this name. */
-#define ELF_NOTE_SOLARIS "SUNW Solaris"
-
-/* Note entries for GNU systems have this name. */
-#define ELF_NOTE_GNU "GNU"
-
-
-/* Defined types of notes for Solaris. */
-
-/* Value of descriptor (one word) is desired pagesize for the binary. */
-#define ELF_NOTE_PAGESIZE_HINT 1
-
-
-/* Defined note types for GNU systems. */
-
-/* ABI information. The descriptor consists of words:
- word 0: OS descriptor
- word 1: major version of the ABI
- word 2: minor version of the ABI
- word 3: subminor version of the ABI
-*/
-#define NT_GNU_ABI_TAG 1
-#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */
-
-/* Known OSes. These values can appear in word 0 of an
- NT_GNU_ABI_TAG note section entry. */
-#define ELF_NOTE_OS_LINUX 0
-#define ELF_NOTE_OS_GNU 1
-#define ELF_NOTE_OS_SOLARIS2 2
-#define ELF_NOTE_OS_FREEBSD 3
-
-/* Synthetic hwcap information. The descriptor begins with two words:
- word 0: number of entries
- word 1: bitmask of enabled entries
- Then follow variable-length entries, one byte followed by a
- '\0'-terminated hwcap name string. The byte gives the bit
- number to test if enabled, (1U << bit) & bitmask. */
-#define NT_GNU_HWCAP 2
-
-/* Build ID bits as generated by ld --build-id.
- The descriptor consists of any nonzero number of bytes. */
-#define NT_GNU_BUILD_ID 3
-
-/* Version note generated by GNU gold containing a version string. */
-#define NT_GNU_GOLD_VERSION 4
-
-
-/* Move records. */
-typedef struct
-{
- Elf32_Xword m_value; /* Symbol value. */
- Elf32_Word m_info; /* Size and index. */
- Elf32_Word m_poffset; /* Symbol offset. */
- Elf32_Half m_repeat; /* Repeat count. */
- Elf32_Half m_stride; /* Stride info. */
-} Elf32_Move;
-
-typedef struct
-{
- Elf64_Xword m_value; /* Symbol value. */
- Elf64_Xword m_info; /* Size and index. */
- Elf64_Xword m_poffset; /* Symbol offset. */
- Elf64_Half m_repeat; /* Repeat count. */
- Elf64_Half m_stride; /* Stride info. */
-} Elf64_Move;
-
-/* Macro to construct move records. */
-#define ELF32_M_SYM(info) ((info) >> 8)
-#define ELF32_M_SIZE(info) ((unsigned char) (info))
-#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size))
-
-#define ELF64_M_SYM(info) ELF32_M_SYM (info)
-#define ELF64_M_SIZE(info) ELF32_M_SIZE (info)
-#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size)
-
-
-/* Motorola 68k specific definitions. */
-
-/* Values for Elf32_Ehdr.e_flags. */
-#define EF_CPU32 0x00810000
-
-/* m68k relocs. */
-
-#define R_68K_NONE 0 /* No reloc */
-#define R_68K_32 1 /* Direct 32 bit */
-#define R_68K_16 2 /* Direct 16 bit */
-#define R_68K_8 3 /* Direct 8 bit */
-#define R_68K_PC32 4 /* PC relative 32 bit */
-#define R_68K_PC16 5 /* PC relative 16 bit */
-#define R_68K_PC8 6 /* PC relative 8 bit */
-#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */
-#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */
-#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */
-#define R_68K_GOT32O 10 /* 32 bit GOT offset */
-#define R_68K_GOT16O 11 /* 16 bit GOT offset */
-#define R_68K_GOT8O 12 /* 8 bit GOT offset */
-#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */
-#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */
-#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */
-#define R_68K_PLT32O 16 /* 32 bit PLT offset */
-#define R_68K_PLT16O 17 /* 16 bit PLT offset */
-#define R_68K_PLT8O 18 /* 8 bit PLT offset */
-#define R_68K_COPY 19 /* Copy symbol at runtime */
-#define R_68K_GLOB_DAT 20 /* Create GOT entry */
-#define R_68K_JMP_SLOT 21 /* Create PLT entry */
-#define R_68K_RELATIVE 22 /* Adjust by program base */
-#define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */
-#define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */
-#define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */
-#define R_68K_TLS_LDM32 28 /* 32 bit GOT offset for LDM */
-#define R_68K_TLS_LDM16 29 /* 16 bit GOT offset for LDM */
-#define R_68K_TLS_LDM8 30 /* 8 bit GOT offset for LDM */
-#define R_68K_TLS_LDO32 31 /* 32 bit module-relative offset */
-#define R_68K_TLS_LDO16 32 /* 16 bit module-relative offset */
-#define R_68K_TLS_LDO8 33 /* 8 bit module-relative offset */
-#define R_68K_TLS_IE32 34 /* 32 bit GOT offset for IE */
-#define R_68K_TLS_IE16 35 /* 16 bit GOT offset for IE */
-#define R_68K_TLS_IE8 36 /* 8 bit GOT offset for IE */
-#define R_68K_TLS_LE32 37 /* 32 bit offset relative to
- static TLS block */
-#define R_68K_TLS_LE16 38 /* 16 bit offset relative to
- static TLS block */
-#define R_68K_TLS_LE8 39 /* 8 bit offset relative to
- static TLS block */
-#define R_68K_TLS_DTPMOD32 40 /* 32 bit module number */
-#define R_68K_TLS_DTPREL32 41 /* 32 bit module-relative offset */
-#define R_68K_TLS_TPREL32 42 /* 32 bit TP-relative offset */
-/* Keep this the last entry. */
-#define R_68K_NUM 43
-
-/* Intel 80386 specific definitions. */
-
-/* i386 relocs. */
-
-#define R_386_NONE 0 /* No reloc */
-#define R_386_32 1 /* Direct 32 bit */
-#define R_386_PC32 2 /* PC relative 32 bit */
-#define R_386_GOT32 3 /* 32 bit GOT entry */
-#define R_386_PLT32 4 /* 32 bit PLT address */
-#define R_386_COPY 5 /* Copy symbol at runtime */
-#define R_386_GLOB_DAT 6 /* Create GOT entry */
-#define R_386_JMP_SLOT 7 /* Create PLT entry */
-#define R_386_RELATIVE 8 /* Adjust by program base */
-#define R_386_GOTOFF 9 /* 32 bit offset to GOT */
-#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */
-#define R_386_32PLT 11
-#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */
-#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS
- block offset */
-#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block
- offset */
-#define R_386_TLS_LE 17 /* Offset relative to static TLS
- block */
-#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of
- general dynamic thread local data */
-#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of
- local dynamic thread local data
- in LE code */
-#define R_386_16 20
-#define R_386_PC16 21
-#define R_386_8 22
-#define R_386_PC8 23
-#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic
- thread local data */
-#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */
-#define R_386_TLS_GD_CALL 26 /* Relocation for call to
- __tls_get_addr() */
-#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */
-#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic
- thread local data in LE code */
-#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */
-#define R_386_TLS_LDM_CALL 30 /* Relocation for call to
- __tls_get_addr() in LDM code */
-#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */
-#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */
-#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS
- block offset */
-#define R_386_TLS_LE_32 34 /* Negated offset relative to static
- TLS block */
-#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */
-#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */
-#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */
-#define R_386_SIZE32 38 /* 32-bit symbol size */
-#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */
-#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS
- descriptor for
- relaxation. */
-#define R_386_TLS_DESC 41 /* TLS descriptor containing
- pointer to code and to
- argument, returning the TLS
- offset for the symbol. */
-#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */
-/* Keep this the last entry. */
-#define R_386_NUM 43
-
-/* SUN SPARC specific definitions. */
-
-/* Legal values for ST_TYPE subfield of st_info (symbol type). */
-
-#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */
-
-/* Values for Elf64_Ehdr.e_flags. */
-
-#define EF_SPARCV9_MM 3
-#define EF_SPARCV9_TSO 0
-#define EF_SPARCV9_PSO 1
-#define EF_SPARCV9_RMO 2
-#define EF_SPARC_LEDATA 0x800000 /* little endian data */
-#define EF_SPARC_EXT_MASK 0xFFFF00
-#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */
-#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */
-#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */
-#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */
-
-/* SPARC relocs. */
-
-#define R_SPARC_NONE 0 /* No reloc */
-#define R_SPARC_8 1 /* Direct 8 bit */
-#define R_SPARC_16 2 /* Direct 16 bit */
-#define R_SPARC_32 3 /* Direct 32 bit */
-#define R_SPARC_DISP8 4 /* PC relative 8 bit */
-#define R_SPARC_DISP16 5 /* PC relative 16 bit */
-#define R_SPARC_DISP32 6 /* PC relative 32 bit */
-#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */
-#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */
-#define R_SPARC_HI22 9 /* High 22 bit */
-#define R_SPARC_22 10 /* Direct 22 bit */
-#define R_SPARC_13 11 /* Direct 13 bit */
-#define R_SPARC_LO10 12 /* Truncated 10 bit */
-#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */
-#define R_SPARC_GOT13 14 /* 13 bit GOT entry */
-#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */
-#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */
-#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */
-#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */
-#define R_SPARC_COPY 19 /* Copy symbol at runtime */
-#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */
-#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */
-#define R_SPARC_RELATIVE 22 /* Adjust by program base */
-#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */
-
-/* Additional Sparc64 relocs. */
-
-#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */
-#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */
-#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */
-#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */
-#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */
-#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */
-#define R_SPARC_10 30 /* Direct 10 bit */
-#define R_SPARC_11 31 /* Direct 11 bit */
-#define R_SPARC_64 32 /* Direct 64 bit */
-#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */
-#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */
-#define R_SPARC_HM10 35 /* High middle 10 bits of ... */
-#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */
-#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */
-#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */
-#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */
-#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */
-#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */
-#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */
-#define R_SPARC_7 43 /* Direct 7 bit */
-#define R_SPARC_5 44 /* Direct 5 bit */
-#define R_SPARC_6 45 /* Direct 6 bit */
-#define R_SPARC_DISP64 46 /* PC relative 64 bit */
-#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */
-#define R_SPARC_HIX22 48 /* High 22 bit complemented */
-#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */
-#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */
-#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */
-#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */
-#define R_SPARC_REGISTER 53 /* Global register usage */
-#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */
-#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */
-#define R_SPARC_TLS_GD_HI22 56
-#define R_SPARC_TLS_GD_LO10 57
-#define R_SPARC_TLS_GD_ADD 58
-#define R_SPARC_TLS_GD_CALL 59
-#define R_SPARC_TLS_LDM_HI22 60
-#define R_SPARC_TLS_LDM_LO10 61
-#define R_SPARC_TLS_LDM_ADD 62
-#define R_SPARC_TLS_LDM_CALL 63
-#define R_SPARC_TLS_LDO_HIX22 64
-#define R_SPARC_TLS_LDO_LOX10 65
-#define R_SPARC_TLS_LDO_ADD 66
-#define R_SPARC_TLS_IE_HI22 67
-#define R_SPARC_TLS_IE_LO10 68
-#define R_SPARC_TLS_IE_LD 69
-#define R_SPARC_TLS_IE_LDX 70
-#define R_SPARC_TLS_IE_ADD 71
-#define R_SPARC_TLS_LE_HIX22 72
-#define R_SPARC_TLS_LE_LOX10 73
-#define R_SPARC_TLS_DTPMOD32 74
-#define R_SPARC_TLS_DTPMOD64 75
-#define R_SPARC_TLS_DTPOFF32 76
-#define R_SPARC_TLS_DTPOFF64 77
-#define R_SPARC_TLS_TPOFF32 78
-#define R_SPARC_TLS_TPOFF64 79
-#define R_SPARC_GOTDATA_HIX22 80
-#define R_SPARC_GOTDATA_LOX10 81
-#define R_SPARC_GOTDATA_OP_HIX22 82
-#define R_SPARC_GOTDATA_OP_LOX10 83
-#define R_SPARC_GOTDATA_OP 84
-#define R_SPARC_H34 85
-#define R_SPARC_SIZE32 86
-#define R_SPARC_SIZE64 87
-#define R_SPARC_WDISP10 88
-#define R_SPARC_JMP_IREL 248
-#define R_SPARC_IRELATIVE 249
-#define R_SPARC_GNU_VTINHERIT 250
-#define R_SPARC_GNU_VTENTRY 251
-#define R_SPARC_REV32 252
-/* Keep this the last entry. */
-#define R_SPARC_NUM 253
-
-/* For Sparc64, legal values for d_tag of Elf64_Dyn. */
-
-#define DT_SPARC_REGISTER 0x70000001
-#define DT_SPARC_NUM 2
-
-/* MIPS R3000 specific definitions. */
-
-/* Legal values for e_flags field of Elf32_Ehdr. */
-
-#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used. */
-#define EF_MIPS_PIC 2 /* Contains PIC code. */
-#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence. */
-#define EF_MIPS_XGOT 8
-#define EF_MIPS_64BIT_WHIRL 16
-#define EF_MIPS_ABI2 32
-#define EF_MIPS_ABI_ON32 64
-#define EF_MIPS_NAN2008 1024 /* Uses IEEE 754-2008 NaN encoding. */
-#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level. */
-
-/* Legal values for MIPS architecture level. */
-
-#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */
-#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */
-#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */
-#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */
-#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */
-#define EF_MIPS_ARCH_32 0x50000000 /* MIPS32 code. */
-#define EF_MIPS_ARCH_64 0x60000000 /* MIPS64 code. */
-#define EF_MIPS_ARCH_32R2 0x70000000 /* MIPS32r2 code. */
-#define EF_MIPS_ARCH_64R2 0x80000000 /* MIPS64r2 code. */
-
-/* The following are unofficial names and should not be used. */
-
-#define E_MIPS_ARCH_1 EF_MIPS_ARCH_1
-#define E_MIPS_ARCH_2 EF_MIPS_ARCH_2
-#define E_MIPS_ARCH_3 EF_MIPS_ARCH_3
-#define E_MIPS_ARCH_4 EF_MIPS_ARCH_4
-#define E_MIPS_ARCH_5 EF_MIPS_ARCH_5
-#define E_MIPS_ARCH_32 EF_MIPS_ARCH_32
-#define E_MIPS_ARCH_64 EF_MIPS_ARCH_64
-
-/* Special section indices. */
-
-#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols. */
-#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */
-#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */
-#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols. */
-#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols. */
-
-/* Legal values for sh_type field of Elf32_Shdr. */
-
-#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link. */
-#define SHT_MIPS_MSYM 0x70000001
-#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols. */
-#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes. */
-#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */
-#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging info. */
-#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information. */
-#define SHT_MIPS_PACKAGE 0x70000007
-#define SHT_MIPS_PACKSYM 0x70000008
-#define SHT_MIPS_RELD 0x70000009
-#define SHT_MIPS_IFACE 0x7000000b
-#define SHT_MIPS_CONTENT 0x7000000c
-#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */
-#define SHT_MIPS_SHDR 0x70000010
-#define SHT_MIPS_FDESC 0x70000011
-#define SHT_MIPS_EXTSYM 0x70000012
-#define SHT_MIPS_DENSE 0x70000013
-#define SHT_MIPS_PDESC 0x70000014
-#define SHT_MIPS_LOCSYM 0x70000015
-#define SHT_MIPS_AUXSYM 0x70000016
-#define SHT_MIPS_OPTSYM 0x70000017
-#define SHT_MIPS_LOCSTR 0x70000018
-#define SHT_MIPS_LINE 0x70000019
-#define SHT_MIPS_RFDESC 0x7000001a
-#define SHT_MIPS_DELTASYM 0x7000001b
-#define SHT_MIPS_DELTAINST 0x7000001c
-#define SHT_MIPS_DELTACLASS 0x7000001d
-#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */
-#define SHT_MIPS_DELTADECL 0x7000001f
-#define SHT_MIPS_SYMBOL_LIB 0x70000020
-#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */
-#define SHT_MIPS_TRANSLATE 0x70000022
-#define SHT_MIPS_PIXIE 0x70000023
-#define SHT_MIPS_XLATE 0x70000024
-#define SHT_MIPS_XLATE_DEBUG 0x70000025
-#define SHT_MIPS_WHIRL 0x70000026
-#define SHT_MIPS_EH_REGION 0x70000027
-#define SHT_MIPS_XLATE_OLD 0x70000028
-#define SHT_MIPS_PDR_EXCEPTION 0x70000029
-
-/* Legal values for sh_flags field of Elf32_Shdr. */
-
-#define SHF_MIPS_GPREL 0x10000000 /* Must be in global data area. */
-#define SHF_MIPS_MERGE 0x20000000
-#define SHF_MIPS_ADDR 0x40000000
-#define SHF_MIPS_STRINGS 0x80000000
-#define SHF_MIPS_NOSTRIP 0x08000000
-#define SHF_MIPS_LOCAL 0x04000000
-#define SHF_MIPS_NAMES 0x02000000
-#define SHF_MIPS_NODUPE 0x01000000
-
-
-/* Symbol tables. */
-
-/* MIPS specific values for `st_other'. */
-#define STO_MIPS_DEFAULT 0x0
-#define STO_MIPS_INTERNAL 0x1
-#define STO_MIPS_HIDDEN 0x2
-#define STO_MIPS_PROTECTED 0x3
-#define STO_MIPS_PLT 0x8
-#define STO_MIPS_SC_ALIGN_UNUSED 0xff
-
-/* MIPS specific values for `st_info'. */
-#define STB_MIPS_SPLIT_COMMON 13
-
-/* Entries found in sections of type SHT_MIPS_GPTAB. */
-
-typedef union
-{
- struct
- {
- Elf32_Word gt_current_g_value; /* -G value used for compilation. */
- Elf32_Word gt_unused; /* Not used. */
- } gt_header; /* First entry in section. */
- struct
- {
- Elf32_Word gt_g_value; /* If this value were used for -G. */
- Elf32_Word gt_bytes; /* This many bytes would be used. */
- } gt_entry; /* Subsequent entries in section. */
-} Elf32_gptab;
-
-/* Entry found in sections of type SHT_MIPS_REGINFO. */
-
-typedef struct
-{
- Elf32_Word ri_gprmask; /* General registers used. */
- Elf32_Word ri_cprmask[4]; /* Coprocessor registers used. */
- Elf32_Sword ri_gp_value; /* $gp register value. */
-} Elf32_RegInfo;
-
-/* Entries found in sections of type SHT_MIPS_OPTIONS. */
-
-typedef struct
-{
- unsigned char kind; /* Determines interpretation of the
- variable part of descriptor. */
- unsigned char size; /* Size of descriptor, including header. */
- Elf32_Section section; /* Section header index of section affected,
- 0 for global options. */
- Elf32_Word info; /* Kind-specific information. */
-} Elf_Options;
-
-/* Values for `kind' field in Elf_Options. */
-
-#define ODK_NULL 0 /* Undefined. */
-#define ODK_REGINFO 1 /* Register usage information. */
-#define ODK_EXCEPTIONS 2 /* Exception processing options. */
-#define ODK_PAD 3 /* Section padding options. */
-#define ODK_HWPATCH 4 /* Hardware workarounds performed */
-#define ODK_FILL 5 /* record the fill value used by the linker. */
-#define ODK_TAGS 6 /* reserve space for desktop tools to write. */
-#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */
-#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */
-
-/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */
-
-#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */
-#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */
-#define OEX_PAGE0 0x10000 /* page zero must be mapped. */
-#define OEX_SMM 0x20000 /* Force sequential memory mode? */
-#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */
-#define OEX_PRECISEFP OEX_FPDBUG
-#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */
-
-#define OEX_FPU_INVAL 0x10
-#define OEX_FPU_DIV0 0x08
-#define OEX_FPU_OFLO 0x04
-#define OEX_FPU_UFLO 0x02
-#define OEX_FPU_INEX 0x01
-
-/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */
-
-#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */
-#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */
-#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */
-#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */
-
-#define OPAD_PREFIX 0x1
-#define OPAD_POSTFIX 0x2
-#define OPAD_SYMBOL 0x4
-
-/* Entry found in `.options' section. */
-
-typedef struct
-{
- Elf32_Word hwp_flags1; /* Extra flags. */
- Elf32_Word hwp_flags2; /* Extra flags. */
-} Elf_Options_Hw;
-
-/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */
-
-#define OHWA0_R4KEOP_CHECKED 0x00000001
-#define OHWA1_R4KEOP_CLEAN 0x00000002
-
-/* MIPS relocs. */
-
-#define R_MIPS_NONE 0 /* No reloc */
-#define R_MIPS_16 1 /* Direct 16 bit */
-#define R_MIPS_32 2 /* Direct 32 bit */
-#define R_MIPS_REL32 3 /* PC relative 32 bit */
-#define R_MIPS_26 4 /* Direct 26 bit shifted */
-#define R_MIPS_HI16 5 /* High 16 bit */
-#define R_MIPS_LO16 6 /* Low 16 bit */
-#define R_MIPS_GPREL16 7 /* GP relative 16 bit */
-#define R_MIPS_LITERAL 8 /* 16 bit literal entry */
-#define R_MIPS_GOT16 9 /* 16 bit GOT entry */
-#define R_MIPS_PC16 10 /* PC relative 16 bit */
-#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */
-#define R_MIPS_GPREL32 12 /* GP relative 32 bit */
-
-#define R_MIPS_SHIFT5 16
-#define R_MIPS_SHIFT6 17
-#define R_MIPS_64 18
-#define R_MIPS_GOT_DISP 19
-#define R_MIPS_GOT_PAGE 20
-#define R_MIPS_GOT_OFST 21
-#define R_MIPS_GOT_HI16 22
-#define R_MIPS_GOT_LO16 23
-#define R_MIPS_SUB 24
-#define R_MIPS_INSERT_A 25
-#define R_MIPS_INSERT_B 26
-#define R_MIPS_DELETE 27
-#define R_MIPS_HIGHER 28
-#define R_MIPS_HIGHEST 29
-#define R_MIPS_CALL_HI16 30
-#define R_MIPS_CALL_LO16 31
-#define R_MIPS_SCN_DISP 32
-#define R_MIPS_REL16 33
-#define R_MIPS_ADD_IMMEDIATE 34
-#define R_MIPS_PJUMP 35
-#define R_MIPS_RELGOT 36
-#define R_MIPS_JALR 37
-#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */
-#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */
-#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */
-#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */
-#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */
-#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */
-#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */
-#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */
-#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */
-#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */
-#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */
-#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */
-#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */
-#define R_MIPS_GLOB_DAT 51
-#define R_MIPS_COPY 126
-#define R_MIPS_JUMP_SLOT 127
-/* Keep this the last entry. */
-#define R_MIPS_NUM 128
-
-/* Legal values for p_type field of Elf32_Phdr. */
-
-#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */
-#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */
-#define PT_MIPS_OPTIONS 0x70000002
-
-/* Special program header types. */
-
-#define PF_MIPS_LOCAL 0x10000000
-
-/* Legal values for d_tag field of Elf32_Dyn. */
-
-#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */
-#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */
-#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */
-#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */
-#define DT_MIPS_FLAGS 0x70000005 /* Flags */
-#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */
-#define DT_MIPS_MSYM 0x70000007
-#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */
-#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */
-#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */
-#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */
-#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */
-#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */
-#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */
-#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */
-#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */
-#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */
-#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */
-#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in
- DT_MIPS_DELTA_CLASS. */
-#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */
-#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
- DT_MIPS_DELTA_INSTANCE. */
-#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */
-#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
- DT_MIPS_DELTA_RELOC. */
-#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta
- relocations refer to. */
-#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
- DT_MIPS_DELTA_SYM. */
-#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
- class declaration. */
-#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
- DT_MIPS_DELTA_CLASSSYM. */
-#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */
-#define DT_MIPS_PIXIE_INIT 0x70000023
-#define DT_MIPS_SYMBOL_LIB 0x70000024
-#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
-#define DT_MIPS_LOCAL_GOTIDX 0x70000026
-#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
-#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
-#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */
-#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */
-#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
-#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
-#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
- function stored in GOT. */
-#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added
- by rld on dlopen() calls. */
-#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
-#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */
-#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */
-/* The address of .got.plt in an executable using the new non-PIC ABI. */
-#define DT_MIPS_PLTGOT 0x70000032
-/* The base of the PLT in an executable using the new non-PIC ABI if that
- PLT is writable. For a non-writable PLT, this is omitted or has a zero
- value. */
-#define DT_MIPS_RWPLT 0x70000034
-#define DT_MIPS_NUM 0x35
-
-/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */
-
-#define RHF_NONE 0 /* No flags */
-#define RHF_QUICKSTART (1 << 0) /* Use quickstart */
-#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */
-#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */
-#define RHF_NO_MOVE (1 << 3)
-#define RHF_SGI_ONLY (1 << 4)
-#define RHF_GUARANTEE_INIT (1 << 5)
-#define RHF_DELTA_C_PLUS_PLUS (1 << 6)
-#define RHF_GUARANTEE_START_INIT (1 << 7)
-#define RHF_PIXIE (1 << 8)
-#define RHF_DEFAULT_DELAY_LOAD (1 << 9)
-#define RHF_REQUICKSTART (1 << 10)
-#define RHF_REQUICKSTARTED (1 << 11)
-#define RHF_CORD (1 << 12)
-#define RHF_NO_UNRES_UNDEF (1 << 13)
-#define RHF_RLD_ORDER_SAFE (1 << 14)
-
-/* Entries found in sections of type SHT_MIPS_LIBLIST. */
-
-typedef struct
-{
- Elf32_Word l_name; /* Name (string table index) */
- Elf32_Word l_time_stamp; /* Timestamp */
- Elf32_Word l_checksum; /* Checksum */
- Elf32_Word l_version; /* Interface version */
- Elf32_Word l_flags; /* Flags */
-} Elf32_Lib;
-
-typedef struct
-{
- Elf64_Word l_name; /* Name (string table index) */
- Elf64_Word l_time_stamp; /* Timestamp */
- Elf64_Word l_checksum; /* Checksum */
- Elf64_Word l_version; /* Interface version */
- Elf64_Word l_flags; /* Flags */
-} Elf64_Lib;
-
-
-/* Legal values for l_flags. */
-
-#define LL_NONE 0
-#define LL_EXACT_MATCH (1 << 0) /* Require exact match */
-#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */
-#define LL_REQUIRE_MINOR (1 << 2)
-#define LL_EXPORTS (1 << 3)
-#define LL_DELAY_LOAD (1 << 4)
-#define LL_DELTA (1 << 5)
-
-/* Entries found in sections of type SHT_MIPS_CONFLICT. */
-
-typedef Elf32_Addr Elf32_Conflict;
-
-
-/* HPPA specific definitions. */
-
-/* Legal values for e_flags field of Elf32_Ehdr. */
-
-#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */
-#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */
-#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */
-#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */
-#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch
- prediction. */
-#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */
-#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */
-
-/* Defined values for `e_flags & EF_PARISC_ARCH' are: */
-
-#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */
-#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */
-#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */
-
-/* Additional section indeces. */
-
-#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared
- symbols in ANSI C. */
-#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */
-
-/* Legal values for sh_type field of Elf32_Shdr. */
-
-#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */
-#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */
-#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */
-
-/* Legal values for sh_flags field of Elf32_Shdr. */
-
-#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */
-#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */
-#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */
-
-/* Legal values for ST_TYPE subfield of st_info (symbol type). */
-
-#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */
-
-#define STT_HP_OPAQUE (STT_LOOS + 0x1)
-#define STT_HP_STUB (STT_LOOS + 0x2)
-
-/* HPPA relocs. */
-
-#define R_PARISC_NONE 0 /* No reloc. */
-#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */
-#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */
-#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */
-#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */
-#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */
-#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */
-#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */
-#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */
-#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */
-#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */
-#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */
-#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */
-#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */
-#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */
-#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */
-#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */
-#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */
-#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */
-#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */
-#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */
-#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */
-#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */
-#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */
-#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */
-#define R_PARISC_FPTR64 64 /* 64 bits function address. */
-#define R_PARISC_PLABEL32 65 /* 32 bits function address. */
-#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */
-#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */
-#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */
-#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */
-#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */
-#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */
-#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */
-#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */
-#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */
-#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */
-#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */
-#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */
-#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */
-#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */
-#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */
-#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */
-#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */
-#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */
-#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */
-#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */
-#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */
-#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */
-#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */
-#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */
-#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */
-#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */
-#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */
-#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */
-#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */
-#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */
-#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */
-#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */
-#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */
-#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */
-#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */
-#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */
-#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */
-#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */
-#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */
-#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */
-#define R_PARISC_LORESERVE 128
-#define R_PARISC_COPY 128 /* Copy relocation. */
-#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */
-#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */
-#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */
-#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */
-#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */
-#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */
-#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/
-#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */
-#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */
-#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */
-#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */
-#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */
-#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */
-#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */
-#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */
-#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/
-#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/
-#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */
-#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */
-#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */
-#define R_PARISC_GNU_VTENTRY 232
-#define R_PARISC_GNU_VTINHERIT 233
-#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */
-#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */
-#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */
-#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */
-#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */
-#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */
-#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */
-#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */
-#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */
-#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */
-#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */
-#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */
-#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L
-#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R
-#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L
-#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R
-#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32
-#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64
-#define R_PARISC_HIRESERVE 255
-
-/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */
-
-#define PT_HP_TLS (PT_LOOS + 0x0)
-#define PT_HP_CORE_NONE (PT_LOOS + 0x1)
-#define PT_HP_CORE_VERSION (PT_LOOS + 0x2)
-#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3)
-#define PT_HP_CORE_COMM (PT_LOOS + 0x4)
-#define PT_HP_CORE_PROC (PT_LOOS + 0x5)
-#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6)
-#define PT_HP_CORE_STACK (PT_LOOS + 0x7)
-#define PT_HP_CORE_SHM (PT_LOOS + 0x8)
-#define PT_HP_CORE_MMF (PT_LOOS + 0x9)
-#define PT_HP_PARALLEL (PT_LOOS + 0x10)
-#define PT_HP_FASTBIND (PT_LOOS + 0x11)
-#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12)
-#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13)
-#define PT_HP_STACK (PT_LOOS + 0x14)
-
-#define PT_PARISC_ARCHEXT 0x70000000
-#define PT_PARISC_UNWIND 0x70000001
-
-/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */
-
-#define PF_PARISC_SBP 0x08000000
-
-#define PF_HP_PAGE_SIZE 0x00100000
-#define PF_HP_FAR_SHARED 0x00200000
-#define PF_HP_NEAR_SHARED 0x00400000
-#define PF_HP_CODE 0x01000000
-#define PF_HP_MODIFY 0x02000000
-#define PF_HP_LAZYSWAP 0x04000000
-#define PF_HP_SBP 0x08000000
-
-
-/* Alpha specific definitions. */
-
-/* Legal values for e_flags field of Elf64_Ehdr. */
-
-#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */
-#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */
-
-/* Legal values for sh_type field of Elf64_Shdr. */
-
-/* These two are primerily concerned with ECOFF debugging info. */
-#define SHT_ALPHA_DEBUG 0x70000001
-#define SHT_ALPHA_REGINFO 0x70000002
-
-/* Legal values for sh_flags field of Elf64_Shdr. */
-
-#define SHF_ALPHA_GPREL 0x10000000
-
-/* Legal values for st_other field of Elf64_Sym. */
-#define STO_ALPHA_NOPV 0x80 /* No PV required. */
-#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */
-
-/* Alpha relocs. */
-
-#define R_ALPHA_NONE 0 /* No reloc */
-#define R_ALPHA_REFLONG 1 /* Direct 32 bit */
-#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */
-#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */
-#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */
-#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */
-#define R_ALPHA_GPDISP 6 /* Add displacement to GP */
-#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */
-#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */
-#define R_ALPHA_SREL16 9 /* PC relative 16 bit */
-#define R_ALPHA_SREL32 10 /* PC relative 32 bit */
-#define R_ALPHA_SREL64 11 /* PC relative 64 bit */
-#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */
-#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */
-#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */
-#define R_ALPHA_COPY 24 /* Copy symbol at runtime */
-#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */
-#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */
-#define R_ALPHA_RELATIVE 27 /* Adjust by program base */
-#define R_ALPHA_TLS_GD_HI 28
-#define R_ALPHA_TLSGD 29
-#define R_ALPHA_TLS_LDM 30
-#define R_ALPHA_DTPMOD64 31
-#define R_ALPHA_GOTDTPREL 32
-#define R_ALPHA_DTPREL64 33
-#define R_ALPHA_DTPRELHI 34
-#define R_ALPHA_DTPRELLO 35
-#define R_ALPHA_DTPREL16 36
-#define R_ALPHA_GOTTPREL 37
-#define R_ALPHA_TPREL64 38
-#define R_ALPHA_TPRELHI 39
-#define R_ALPHA_TPRELLO 40
-#define R_ALPHA_TPREL16 41
-/* Keep this the last entry. */
-#define R_ALPHA_NUM 46
-
-/* Magic values of the LITUSE relocation addend. */
-#define LITUSE_ALPHA_ADDR 0
-#define LITUSE_ALPHA_BASE 1
-#define LITUSE_ALPHA_BYTOFF 2
-#define LITUSE_ALPHA_JSR 3
-#define LITUSE_ALPHA_TLS_GD 4
-#define LITUSE_ALPHA_TLS_LDM 5
-
-/* Legal values for d_tag of Elf64_Dyn. */
-#define DT_ALPHA_PLTRO (DT_LOPROC + 0)
-#define DT_ALPHA_NUM 1
-
-/* PowerPC specific declarations */
-
-/* Values for Elf32/64_Ehdr.e_flags. */
-#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */
-
-/* Cygnus local bits below */
-#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/
-#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib
- flag */
-
-/* PowerPC relocations defined by the ABIs */
-#define R_PPC_NONE 0
-#define R_PPC_ADDR32 1 /* 32bit absolute address */
-#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
-#define R_PPC_ADDR16 3 /* 16bit absolute address */
-#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
-#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
-#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
-#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
-#define R_PPC_ADDR14_BRTAKEN 8
-#define R_PPC_ADDR14_BRNTAKEN 9
-#define R_PPC_REL24 10 /* PC relative 26 bit */
-#define R_PPC_REL14 11 /* PC relative 16 bit */
-#define R_PPC_REL14_BRTAKEN 12
-#define R_PPC_REL14_BRNTAKEN 13
-#define R_PPC_GOT16 14
-#define R_PPC_GOT16_LO 15
-#define R_PPC_GOT16_HI 16
-#define R_PPC_GOT16_HA 17
-#define R_PPC_PLTREL24 18
-#define R_PPC_COPY 19
-#define R_PPC_GLOB_DAT 20
-#define R_PPC_JMP_SLOT 21
-#define R_PPC_RELATIVE 22
-#define R_PPC_LOCAL24PC 23
-#define R_PPC_UADDR32 24
-#define R_PPC_UADDR16 25
-#define R_PPC_REL32 26
-#define R_PPC_PLT32 27
-#define R_PPC_PLTREL32 28
-#define R_PPC_PLT16_LO 29
-#define R_PPC_PLT16_HI 30
-#define R_PPC_PLT16_HA 31
-#define R_PPC_SDAREL16 32
-#define R_PPC_SECTOFF 33
-#define R_PPC_SECTOFF_LO 34
-#define R_PPC_SECTOFF_HI 35
-#define R_PPC_SECTOFF_HA 36
-
-/* PowerPC relocations defined for the TLS access ABI. */
-#define R_PPC_TLS 67 /* none (sym+add)@tls */
-#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */
-#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */
-#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */
-#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */
-#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */
-#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */
-#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */
-#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */
-#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */
-#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */
-#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */
-#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */
-#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */
-#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */
-#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */
-#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */
-#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */
-#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */
-#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */
-#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */
-#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */
-#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */
-#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */
-#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */
-#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */
-#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */
-#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */
-
-/* The remaining relocs are from the Embedded ELF ABI, and are not
- in the SVR4 ELF ABI. */
-#define R_PPC_EMB_NADDR32 101
-#define R_PPC_EMB_NADDR16 102
-#define R_PPC_EMB_NADDR16_LO 103
-#define R_PPC_EMB_NADDR16_HI 104
-#define R_PPC_EMB_NADDR16_HA 105
-#define R_PPC_EMB_SDAI16 106
-#define R_PPC_EMB_SDA2I16 107
-#define R_PPC_EMB_SDA2REL 108
-#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */
-#define R_PPC_EMB_MRKREF 110
-#define R_PPC_EMB_RELSEC16 111
-#define R_PPC_EMB_RELST_LO 112
-#define R_PPC_EMB_RELST_HI 113
-#define R_PPC_EMB_RELST_HA 114
-#define R_PPC_EMB_BIT_FLD 115
-#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */
-
-/* Diab tool relocations. */
-#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */
-#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */
-#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */
-#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */
-#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */
-#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */
-
-/* GNU extension to support local ifunc. */
-#define R_PPC_IRELATIVE 248
-
-/* GNU relocs used in PIC code sequences. */
-#define R_PPC_REL16 249 /* half16 (sym+add-.) */
-#define R_PPC_REL16_LO 250 /* half16 (sym+add-.)@l */
-#define R_PPC_REL16_HI 251 /* half16 (sym+add-.)@h */
-#define R_PPC_REL16_HA 252 /* half16 (sym+add-.)@ha */
-
-/* This is a phony reloc to handle any old fashioned TOC16 references
- that may still be in object files. */
-#define R_PPC_TOC16 255
-
-/* PowerPC specific values for the Dyn d_tag field. */
-#define DT_PPC_GOT (DT_LOPROC + 0)
-#define DT_PPC_NUM 1
-
-/* PowerPC64 relocations defined by the ABIs */
-#define R_PPC64_NONE R_PPC_NONE
-#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address */
-#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned */
-#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address */
-#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of address */
-#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of address. */
-#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */
-#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned */
-#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN
-#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN
-#define R_PPC64_REL24 R_PPC_REL24 /* PC-rel. 26 bit, word aligned */
-#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit */
-#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN
-#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN
-#define R_PPC64_GOT16 R_PPC_GOT16
-#define R_PPC64_GOT16_LO R_PPC_GOT16_LO
-#define R_PPC64_GOT16_HI R_PPC_GOT16_HI
-#define R_PPC64_GOT16_HA R_PPC_GOT16_HA
-
-#define R_PPC64_COPY R_PPC_COPY
-#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT
-#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT
-#define R_PPC64_RELATIVE R_PPC_RELATIVE
-
-#define R_PPC64_UADDR32 R_PPC_UADDR32
-#define R_PPC64_UADDR16 R_PPC_UADDR16
-#define R_PPC64_REL32 R_PPC_REL32
-#define R_PPC64_PLT32 R_PPC_PLT32
-#define R_PPC64_PLTREL32 R_PPC_PLTREL32
-#define R_PPC64_PLT16_LO R_PPC_PLT16_LO
-#define R_PPC64_PLT16_HI R_PPC_PLT16_HI
-#define R_PPC64_PLT16_HA R_PPC_PLT16_HA
-
-#define R_PPC64_SECTOFF R_PPC_SECTOFF
-#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO
-#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI
-#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA
-#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2 */
-#define R_PPC64_ADDR64 38 /* doubleword64 S + A */
-#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */
-#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A) */
-#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A) */
-#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */
-#define R_PPC64_UADDR64 43 /* doubleword64 S + A */
-#define R_PPC64_REL64 44 /* doubleword64 S + A - P */
-#define R_PPC64_PLT64 45 /* doubleword64 L + A */
-#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P */
-#define R_PPC64_TOC16 47 /* half16* S + A - .TOC */
-#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.) */
-#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.) */
-#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.) */
-#define R_PPC64_TOC 51 /* doubleword64 .TOC */
-#define R_PPC64_PLTGOT16 52 /* half16* M + A */
-#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A) */
-#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A) */
-#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A) */
-
-#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2 */
-#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2 */
-#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2 */
-#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2 */
-#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2 */
-#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2 */
-#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2 */
-#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2 */
-#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2 */
-#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2 */
-#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2 */
-
-/* PowerPC64 relocations defined for the TLS access ABI. */
-#define R_PPC64_TLS 67 /* none (sym+add)@tls */
-#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */
-#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */
-#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */
-#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */
-#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */
-#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */
-#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */
-#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */
-#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */
-#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */
-#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */
-#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */
-#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */
-#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */
-#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */
-#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */
-#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */
-#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */
-#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */
-#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */
-#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */
-#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */
-#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */
-#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */
-#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */
-#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */
-#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */
-#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */
-#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */
-#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */
-#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */
-#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */
-#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */
-#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */
-#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */
-#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */
-#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */
-#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */
-#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */
-#define R_PPC64_TLSGD 107 /* none (sym+add)@tlsgd */
-#define R_PPC64_TLSLD 108 /* none (sym+add)@tlsld */
-#define R_PPC64_TOCSAVE 109 /* none */
-
-/* Added when HA and HI relocs were changed to report overflows. */
-#define R_PPC64_ADDR16_HIGH 110
-#define R_PPC64_ADDR16_HIGHA 111
-#define R_PPC64_TPREL16_HIGH 112
-#define R_PPC64_TPREL16_HIGHA 113
-#define R_PPC64_DTPREL16_HIGH 114
-#define R_PPC64_DTPREL16_HIGHA 115
-
-/* GNU extension to support local ifunc. */
-#define R_PPC64_JMP_IREL 247
-#define R_PPC64_IRELATIVE 248
-#define R_PPC64_REL16 249 /* half16 (sym+add-.) */
-#define R_PPC64_REL16_LO 250 /* half16 (sym+add-.)@l */
-#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */
-#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */
-
-/* e_flags bits specifying ABI.
- 1 for original function descriptor using ABI,
- 2 for revised ABI without function descriptors,
- 0 for unspecified or not using any features affected by the differences. */
-#define EF_PPC64_ABI 3
-
-/* PowerPC64 specific values for the Dyn d_tag field. */
-#define DT_PPC64_GLINK (DT_LOPROC + 0)
-#define DT_PPC64_OPD (DT_LOPROC + 1)
-#define DT_PPC64_OPDSZ (DT_LOPROC + 2)
-#define DT_PPC64_OPT (DT_LOPROC + 3)
-#define DT_PPC64_NUM 3
-
-/* PowerPC64 specific values for the DT_PPC64_OPT Dyn entry. */
-#define PPC64_OPT_TLS 1
-#define PPC64_OPT_MULTI_TOC 2
-
-/* PowerPC64 specific values for the Elf64_Sym st_other field. */
-#define STO_PPC64_LOCAL_BIT 5
-#define STO_PPC64_LOCAL_MASK (7 << STO_PPC64_LOCAL_BIT)
-#define PPC64_LOCAL_ENTRY_OFFSET(other) \
- (((1 << (((other) & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT)) >> 2) << 2)
-
-
-/* ARM specific declarations */
-
-/* Processor specific flags for the ELF header e_flags field. */
-#define EF_ARM_RELEXEC 0x01
-#define EF_ARM_HASENTRY 0x02
-#define EF_ARM_INTERWORK 0x04
-#define EF_ARM_APCS_26 0x08
-#define EF_ARM_APCS_FLOAT 0x10
-#define EF_ARM_PIC 0x20
-#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */
-#define EF_ARM_NEW_ABI 0x80
-#define EF_ARM_OLD_ABI 0x100
-#define EF_ARM_SOFT_FLOAT 0x200
-#define EF_ARM_VFP_FLOAT 0x400
-#define EF_ARM_MAVERICK_FLOAT 0x800
-
-#define EF_ARM_ABI_FLOAT_SOFT 0x200 /* NB conflicts with EF_ARM_SOFT_FLOAT */
-#define EF_ARM_ABI_FLOAT_HARD 0x400 /* NB conflicts with EF_ARM_VFP_FLOAT */
-
-
-/* Other constants defined in the ARM ELF spec. version B-01. */
-/* NB. These conflict with values defined above. */
-#define EF_ARM_SYMSARESORTED 0x04
-#define EF_ARM_DYNSYMSUSESEGIDX 0x08
-#define EF_ARM_MAPSYMSFIRST 0x10
-#define EF_ARM_EABIMASK 0XFF000000
-
-/* Constants defined in AAELF. */
-#define EF_ARM_BE8 0x00800000
-#define EF_ARM_LE8 0x00400000
-
-#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
-#define EF_ARM_EABI_UNKNOWN 0x00000000
-#define EF_ARM_EABI_VER1 0x01000000
-#define EF_ARM_EABI_VER2 0x02000000
-#define EF_ARM_EABI_VER3 0x03000000
-#define EF_ARM_EABI_VER4 0x04000000
-#define EF_ARM_EABI_VER5 0x05000000
-
-/* Additional symbol types for Thumb. */
-#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */
-#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */
-
-/* ARM-specific values for sh_flags */
-#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */
-#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined
- in the input to a link step. */
-
-/* ARM-specific program header flags */
-#define PF_ARM_SB 0x10000000 /* Segment contains the location
- addressed by the static base. */
-#define PF_ARM_PI 0x20000000 /* Position-independent segment. */
-#define PF_ARM_ABS 0x40000000 /* Absolute segment. */
-
-/* Processor specific values for the Phdr p_type field. */
-#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */
-
-/* Processor specific values for the Shdr sh_type field. */
-#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */
-#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */
-#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */
-
-
-/* AArch64 relocs. */
-
-#define R_AARCH64_NONE 0 /* No relocation. */
-#define R_AARCH64_ABS64 257 /* Direct 64 bit. */
-#define R_AARCH64_ABS32 258 /* Direct 32 bit. */
-#define R_AARCH64_ABS16 259 /* Direct 16-bit. */
-#define R_AARCH64_PREL64 260 /* PC-relative 64-bit. */
-#define R_AARCH64_PREL32 261 /* PC-relative 32-bit. */
-#define R_AARCH64_PREL16 262 /* PC-relative 16-bit. */
-#define R_AARCH64_MOVW_UABS_G0 263 /* Dir. MOVZ imm. from bits 15:0. */
-#define R_AARCH64_MOVW_UABS_G0_NC 264 /* Likewise for MOVK; no check. */
-#define R_AARCH64_MOVW_UABS_G1 265 /* Dir. MOVZ imm. from bits 31:16. */
-#define R_AARCH64_MOVW_UABS_G1_NC 266 /* Likewise for MOVK; no check. */
-#define R_AARCH64_MOVW_UABS_G2 267 /* Dir. MOVZ imm. from bits 47:32. */
-#define R_AARCH64_MOVW_UABS_G2_NC 268 /* Likewise for MOVK; no check. */
-#define R_AARCH64_MOVW_UABS_G3 269 /* Dir. MOV{K,Z} imm. from 63:48. */
-#define R_AARCH64_MOVW_SABS_G0 270 /* Dir. MOV{N,Z} imm. from 15:0. */
-#define R_AARCH64_MOVW_SABS_G1 271 /* Dir. MOV{N,Z} imm. from 31:16. */
-#define R_AARCH64_MOVW_SABS_G2 272 /* Dir. MOV{N,Z} imm. from 47:32. */
-#define R_AARCH64_LD_PREL_LO19 273 /* PC-rel. LD imm. from bits 20:2. */
-#define R_AARCH64_ADR_PREL_LO21 274 /* PC-rel. ADR imm. from bits 20:0. */
-#define R_AARCH64_ADR_PREL_PG_HI21 275 /* Page-rel. ADRP imm. from 32:12. */
-#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Likewise; no overflow check. */
-#define R_AARCH64_ADD_ABS_LO12_NC 277 /* Dir. ADD imm. from bits 11:0. */
-#define R_AARCH64_LDST8_ABS_LO12_NC 278 /* Likewise for LD/ST; no check. */
-#define R_AARCH64_TSTBR14 279 /* PC-rel. TBZ/TBNZ imm. from 15:2. */
-#define R_AARCH64_CONDBR19 280 /* PC-rel. cond. br. imm. from 20:2. */
-#define R_AARCH64_JUMP26 282 /* PC-rel. B imm. from bits 27:2. */
-#define R_AARCH64_CALL26 283 /* Likewise for CALL. */
-#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* Dir. ADD imm. from bits 11:1. */
-#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* Likewise for bits 11:2. */
-#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* Likewise for bits 11:3. */
-#define R_AARCH64_MOVW_PREL_G0 287 /* PC-rel. MOV{N,Z} imm. from 15:0. */
-#define R_AARCH64_MOVW_PREL_G0_NC 288 /* Likewise for MOVK; no check. */
-#define R_AARCH64_MOVW_PREL_G1 289 /* PC-rel. MOV{N,Z} imm. from 31:16. */
-#define R_AARCH64_MOVW_PREL_G1_NC 290 /* Likewise for MOVK; no check. */
-#define R_AARCH64_MOVW_PREL_G2 291 /* PC-rel. MOV{N,Z} imm. from 47:32. */
-#define R_AARCH64_MOVW_PREL_G2_NC 292 /* Likewise for MOVK; no check. */
-#define R_AARCH64_MOVW_PREL_G3 293 /* PC-rel. MOV{N,Z} imm. from 63:48. */
-#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* Dir. ADD imm. from bits 11:4. */
-#define R_AARCH64_MOVW_GOTOFF_G0 300 /* GOT-rel. off. MOV{N,Z} imm. 15:0. */
-#define R_AARCH64_MOVW_GOTOFF_G0_NC 301 /* Likewise for MOVK; no check. */
-#define R_AARCH64_MOVW_GOTOFF_G1 302 /* GOT-rel. o. MOV{N,Z} imm. 31:16. */
-#define R_AARCH64_MOVW_GOTOFF_G1_NC 303 /* Likewise for MOVK; no check. */
-#define R_AARCH64_MOVW_GOTOFF_G2 304 /* GOT-rel. o. MOV{N,Z} imm. 47:32. */
-#define R_AARCH64_MOVW_GOTOFF_G2_NC 305 /* Likewise for MOVK; no check. */
-#define R_AARCH64_MOVW_GOTOFF_G3 306 /* GOT-rel. o. MOV{N,Z} imm. 63:48. */
-#define R_AARCH64_GOTREL64 307 /* GOT-relative 64-bit. */
-#define R_AARCH64_GOTREL32 308 /* GOT-relative 32-bit. */
-#define R_AARCH64_GOT_LD_PREL19 309 /* PC-rel. GOT off. load imm. 20:2. */
-#define R_AARCH64_LD64_GOTOFF_LO15 310 /* GOT-rel. off. LD/ST imm. 14:3. */
-#define R_AARCH64_ADR_GOT_PAGE 311 /* P-page-rel. GOT off. ADRP 32:12. */
-#define R_AARCH64_LD64_GOT_LO12_NC 312 /* Dir. GOT off. LD/ST imm. 11:3. */
-#define R_AARCH64_LD64_GOTPAGE_LO15 313 /* GOT-page-rel. GOT off. LD/ST 14:3 */
-#define R_AARCH64_TLSGD_ADR_PREL21 512 /* PC-relative ADR imm. 20:0. */
-#define R_AARCH64_TLSGD_ADR_PAGE21 513 /* page-rel. ADRP imm. 32:12. */
-#define R_AARCH64_TLSGD_ADD_LO12_NC 514 /* direct ADD imm. from 11:0. */
-#define R_AARCH64_TLSGD_MOVW_G1 515 /* GOT-rel. MOV{N,Z} 31:16. */
-#define R_AARCH64_TLSGD_MOVW_G0_NC 516 /* GOT-rel. MOVK imm. 15:0. */
-#define R_AARCH64_TLSLD_ADR_PREL21 517 /* Like 512; local dynamic model. */
-#define R_AARCH64_TLSLD_ADR_PAGE21 518 /* Like 513; local dynamic model. */
-#define R_AARCH64_TLSLD_ADD_LO12_NC 519 /* Like 514; local dynamic model. */
-#define R_AARCH64_TLSLD_MOVW_G1 520 /* Like 515; local dynamic model. */
-#define R_AARCH64_TLSLD_MOVW_G0_NC 521 /* Like 516; local dynamic model. */
-#define R_AARCH64_TLSLD_LD_PREL19 522 /* TLS PC-rel. load imm. 20:2. */
-#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* TLS DTP-rel. MOV{N,Z} 47:32. */
-#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* TLS DTP-rel. MOV{N,Z} 31:16. */
-#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* Likewise; MOVK; no check. */
-#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* TLS DTP-rel. MOV{N,Z} 15:0. */
-#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* Likewise; MOVK; no check. */
-#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTP-rel. ADD imm. from 23:12. */
-#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTP-rel. ADD imm. from 11:0. */
-#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* Likewise; no ovfl. check. */
-#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTP-rel. LD/ST imm. 11:0. */
-#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* Likewise; no check. */
-#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTP-rel. LD/ST imm. 11:1. */
-#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* Likewise; no check. */
-#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTP-rel. LD/ST imm. 11:2. */
-#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* Likewise; no check. */
-#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTP-rel. LD/ST imm. 11:3. */
-#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* Likewise; no check. */
-#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* GOT-rel. MOV{N,Z} 31:16. */
-#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* GOT-rel. MOVK 15:0. */
-#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page-rel. ADRP 32:12. */
-#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* Direct LD off. 11:3. */
-#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* PC-rel. load imm. 20:2. */
-#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TLS TP-rel. MOV{N,Z} 47:32. */
-#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TLS TP-rel. MOV{N,Z} 31:16. */
-#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* Likewise; MOVK; no check. */
-#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TLS TP-rel. MOV{N,Z} 15:0. */
-#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* Likewise; MOVK; no check. */
-#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TP-rel. ADD imm. 23:12. */
-#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TP-rel. ADD imm. 11:0. */
-#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* Likewise; no ovfl. check. */
-#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TP-rel. LD/ST off. 11:0. */
-#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* Likewise; no ovfl. check. */
-#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TP-rel. LD/ST off. 11:1. */
-#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* Likewise; no check. */
-#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TP-rel. LD/ST off. 11:2. */
-#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* Likewise; no check. */
-#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TP-rel. LD/ST off. 11:3. */
-#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* Likewise; no check. */
-#define R_AARCH64_TLSDESC_LD_PREL19 560 /* PC-rel. load immediate 20:2. */
-#define R_AARCH64_TLSDESC_ADR_PREL21 561 /* PC-rel. ADR immediate 20:0. */
-#define R_AARCH64_TLSDESC_ADR_PAGE21 562 /* Page-rel. ADRP imm. 32:12. */
-#define R_AARCH64_TLSDESC_LD64_LO12 563 /* Direct LD off. from 11:3. */
-#define R_AARCH64_TLSDESC_ADD_LO12 564 /* Direct ADD imm. from 11:0. */
-#define R_AARCH64_TLSDESC_OFF_G1 565 /* GOT-rel. MOV{N,Z} imm. 31:16. */
-#define R_AARCH64_TLSDESC_OFF_G0_NC 566 /* GOT-rel. MOVK imm. 15:0; no ck. */
-#define R_AARCH64_TLSDESC_LDR 567 /* Relax LDR. */
-#define R_AARCH64_TLSDESC_ADD 568 /* Relax ADD. */
-#define R_AARCH64_TLSDESC_CALL 569 /* Relax BLR. */
-#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 /* TP-rel. LD/ST off. 11:4. */
-#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 /* Likewise; no check. */
-#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 /* DTP-rel. LD/ST imm. 11:4. */
-#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 /* Likewise; no check. */
-#define R_AARCH64_COPY 1024 /* Copy symbol at runtime. */
-#define R_AARCH64_GLOB_DAT 1025 /* Create GOT entry. */
-#define R_AARCH64_JUMP_SLOT 1026 /* Create PLT entry. */
-#define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */
-#define R_AARCH64_TLS_DTPMOD64 1028 /* Module number, 64 bit. */
-#define R_AARCH64_TLS_DTPREL64 1029 /* Module-relative offset, 64 bit. */
-#define R_AARCH64_TLS_TPREL64 1030 /* TP-relative offset, 64 bit. */
-#define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */
-#define R_AARCH64_IRELATIVE 1032 /* STT_GNU_IFUNC relocation. */
-
-/* ARM relocs. */
-
-#define R_ARM_NONE 0 /* No reloc */
-#define R_ARM_PC24 1 /* Deprecated PC relative 26
- bit branch. */
-#define R_ARM_ABS32 2 /* Direct 32 bit */
-#define R_ARM_REL32 3 /* PC relative 32 bit */
-#define R_ARM_PC13 4
-#define R_ARM_ABS16 5 /* Direct 16 bit */
-#define R_ARM_ABS12 6 /* Direct 12 bit */
-#define R_ARM_THM_ABS5 7 /* Direct & 0x7C (LDR, STR). */
-#define R_ARM_ABS8 8 /* Direct 8 bit */
-#define R_ARM_SBREL32 9
-#define R_ARM_THM_PC22 10 /* PC relative 24 bit (Thumb32 BL). */
-#define R_ARM_THM_PC8 11 /* PC relative & 0x3FC
- (Thumb16 LDR, ADD, ADR). */
-#define R_ARM_AMP_VCALL9 12
-#define R_ARM_SWI24 13 /* Obsolete static relocation. */
-#define R_ARM_TLS_DESC 13 /* Dynamic relocation. */
-#define R_ARM_THM_SWI8 14 /* Reserved. */
-#define R_ARM_XPC25 15 /* Reserved. */
-#define R_ARM_THM_XPC22 16 /* Reserved. */
-#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */
-#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */
-#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */
-#define R_ARM_COPY 20 /* Copy symbol at runtime */
-#define R_ARM_GLOB_DAT 21 /* Create GOT entry */
-#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */
-#define R_ARM_RELATIVE 23 /* Adjust by program base */
-#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */
-#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */
-#define R_ARM_GOT32 26 /* 32 bit GOT entry */
-#define R_ARM_PLT32 27 /* Deprecated, 32 bit PLT address. */
-#define R_ARM_CALL 28 /* PC relative 24 bit (BL, BLX). */
-#define R_ARM_JUMP24 29 /* PC relative 24 bit
- (B, BL<cond>). */
-#define R_ARM_THM_JUMP24 30 /* PC relative 24 bit (Thumb32 B.W). */
-#define R_ARM_BASE_ABS 31 /* Adjust by program base. */
-#define R_ARM_ALU_PCREL_7_0 32 /* Obsolete. */
-#define R_ARM_ALU_PCREL_15_8 33 /* Obsolete. */
-#define R_ARM_ALU_PCREL_23_15 34 /* Obsolete. */
-#define R_ARM_LDR_SBREL_11_0 35 /* Deprecated, prog. base relative. */
-#define R_ARM_ALU_SBREL_19_12 36 /* Deprecated, prog. base relative. */
-#define R_ARM_ALU_SBREL_27_20 37 /* Deprecated, prog. base relative. */
-#define R_ARM_TARGET1 38
-#define R_ARM_SBREL31 39 /* Program base relative. */
-#define R_ARM_V4BX 40
-#define R_ARM_TARGET2 41
-#define R_ARM_PREL31 42 /* 32 bit PC relative. */
-#define R_ARM_MOVW_ABS_NC 43 /* Direct 16-bit (MOVW). */
-#define R_ARM_MOVT_ABS 44 /* Direct high 16-bit (MOVT). */
-#define R_ARM_MOVW_PREL_NC 45 /* PC relative 16-bit (MOVW). */
-#define R_ARM_MOVT_PREL 46 /* PC relative (MOVT). */
-#define R_ARM_THM_MOVW_ABS_NC 47 /* Direct 16 bit (Thumb32 MOVW). */
-#define R_ARM_THM_MOVT_ABS 48 /* Direct high 16 bit
- (Thumb32 MOVT). */
-#define R_ARM_THM_MOVW_PREL_NC 49 /* PC relative 16 bit
- (Thumb32 MOVW). */
-#define R_ARM_THM_MOVT_PREL 50 /* PC relative high 16 bit
- (Thumb32 MOVT). */
-#define R_ARM_THM_JUMP19 51 /* PC relative 20 bit
- (Thumb32 B<cond>.W). */
-#define R_ARM_THM_JUMP6 52 /* PC relative X & 0x7E
- (Thumb16 CBZ, CBNZ). */
-#define R_ARM_THM_ALU_PREL_11_0 53 /* PC relative 12 bit
- (Thumb32 ADR.W). */
-#define R_ARM_THM_PC12 54 /* PC relative 12 bit
- (Thumb32 LDR{D,SB,H,SH}). */
-#define R_ARM_ABS32_NOI 55 /* Direct 32-bit. */
-#define R_ARM_REL32_NOI 56 /* PC relative 32-bit. */
-#define R_ARM_ALU_PC_G0_NC 57 /* PC relative (ADD, SUB). */
-#define R_ARM_ALU_PC_G0 58 /* PC relative (ADD, SUB). */
-#define R_ARM_ALU_PC_G1_NC 59 /* PC relative (ADD, SUB). */
-#define R_ARM_ALU_PC_G1 60 /* PC relative (ADD, SUB). */
-#define R_ARM_ALU_PC_G2 61 /* PC relative (ADD, SUB). */
-#define R_ARM_LDR_PC_G1 62 /* PC relative (LDR,STR,LDRB,STRB). */
-#define R_ARM_LDR_PC_G2 63 /* PC relative (LDR,STR,LDRB,STRB). */
-#define R_ARM_LDRS_PC_G0 64 /* PC relative (STR{D,H},
- LDR{D,SB,H,SH}). */
-#define R_ARM_LDRS_PC_G1 65 /* PC relative (STR{D,H},
- LDR{D,SB,H,SH}). */
-#define R_ARM_LDRS_PC_G2 66 /* PC relative (STR{D,H},
- LDR{D,SB,H,SH}). */
-#define R_ARM_LDC_PC_G0 67 /* PC relative (LDC, STC). */
-#define R_ARM_LDC_PC_G1 68 /* PC relative (LDC, STC). */
-#define R_ARM_LDC_PC_G2 69 /* PC relative (LDC, STC). */
-#define R_ARM_ALU_SB_G0_NC 70 /* Program base relative (ADD,SUB). */
-#define R_ARM_ALU_SB_G0 71 /* Program base relative (ADD,SUB). */
-#define R_ARM_ALU_SB_G1_NC 72 /* Program base relative (ADD,SUB). */
-#define R_ARM_ALU_SB_G1 73 /* Program base relative (ADD,SUB). */
-#define R_ARM_ALU_SB_G2 74 /* Program base relative (ADD,SUB). */
-#define R_ARM_LDR_SB_G0 75 /* Program base relative (LDR,
- STR, LDRB, STRB). */
-#define R_ARM_LDR_SB_G1 76 /* Program base relative
- (LDR, STR, LDRB, STRB). */
-#define R_ARM_LDR_SB_G2 77 /* Program base relative
- (LDR, STR, LDRB, STRB). */
-#define R_ARM_LDRS_SB_G0 78 /* Program base relative
- (LDR, STR, LDRB, STRB). */
-#define R_ARM_LDRS_SB_G1 79 /* Program base relative
- (LDR, STR, LDRB, STRB). */
-#define R_ARM_LDRS_SB_G2 80 /* Program base relative
- (LDR, STR, LDRB, STRB). */
-#define R_ARM_LDC_SB_G0 81 /* Program base relative (LDC,STC). */
-#define R_ARM_LDC_SB_G1 82 /* Program base relative (LDC,STC). */
-#define R_ARM_LDC_SB_G2 83 /* Program base relative (LDC,STC). */
-#define R_ARM_MOVW_BREL_NC 84 /* Program base relative 16
- bit (MOVW). */
-#define R_ARM_MOVT_BREL 85 /* Program base relative high
- 16 bit (MOVT). */
-#define R_ARM_MOVW_BREL 86 /* Program base relative 16
- bit (MOVW). */
-#define R_ARM_THM_MOVW_BREL_NC 87 /* Program base relative 16
- bit (Thumb32 MOVW). */
-#define R_ARM_THM_MOVT_BREL 88 /* Program base relative high
- 16 bit (Thumb32 MOVT). */
-#define R_ARM_THM_MOVW_BREL 89 /* Program base relative 16
- bit (Thumb32 MOVW). */
-#define R_ARM_TLS_GOTDESC 90
-#define R_ARM_TLS_CALL 91
-#define R_ARM_TLS_DESCSEQ 92 /* TLS relaxation. */
-#define R_ARM_THM_TLS_CALL 93
-#define R_ARM_PLT32_ABS 94
-#define R_ARM_GOT_ABS 95 /* GOT entry. */
-#define R_ARM_GOT_PREL 96 /* PC relative GOT entry. */
-#define R_ARM_GOT_BREL12 97 /* GOT entry relative to GOT
- origin (LDR). */
-#define R_ARM_GOTOFF12 98 /* 12 bit, GOT entry relative
- to GOT origin (LDR, STR). */
-#define R_ARM_GOTRELAX 99
-#define R_ARM_GNU_VTENTRY 100
-#define R_ARM_GNU_VTINHERIT 101
-#define R_ARM_THM_PC11 102 /* PC relative & 0xFFE (Thumb16 B). */
-#define R_ARM_THM_PC9 103 /* PC relative & 0x1FE
- (Thumb16 B/B<cond>). */
-#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic
- thread local data */
-#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic
- thread local data */
-#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS
- block */
-#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of
- static TLS block offset */
-#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static
- TLS block */
-#define R_ARM_TLS_LDO12 109 /* 12 bit relative to TLS
- block (LDR, STR). */
-#define R_ARM_TLS_LE12 110 /* 12 bit relative to static
- TLS block (LDR, STR). */
-#define R_ARM_TLS_IE12GP 111 /* 12 bit GOT entry relative
- to GOT origin (LDR). */
-#define R_ARM_ME_TOO 128 /* Obsolete. */
-#define R_ARM_THM_TLS_DESCSEQ 129
-#define R_ARM_THM_TLS_DESCSEQ16 129
-#define R_ARM_THM_TLS_DESCSEQ32 130
-#define R_ARM_THM_GOT_BREL12 131 /* GOT entry relative to GOT
- origin, 12 bit (Thumb32 LDR). */
-#define R_ARM_IRELATIVE 160
-#define R_ARM_RXPC25 249
-#define R_ARM_RSBREL32 250
-#define R_ARM_THM_RPC22 251
-#define R_ARM_RREL32 252
-#define R_ARM_RABS22 253
-#define R_ARM_RPC24 254
-#define R_ARM_RBASE 255
-/* Keep this the last entry. */
-#define R_ARM_NUM 256
-
-/* IA-64 specific declarations. */
-
-/* Processor specific flags for the Ehdr e_flags field. */
-#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */
-#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */
-#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */
-
-/* Processor specific values for the Phdr p_type field. */
-#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */
-#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */
-#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12)
-#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13)
-#define PT_IA_64_HP_STACK (PT_LOOS + 0x14)
-
-/* Processor specific flags for the Phdr p_flags field. */
-#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */
-
-/* Processor specific values for the Shdr sh_type field. */
-#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */
-#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */
-
-/* Processor specific flags for the Shdr sh_flags field. */
-#define SHF_IA_64_SHORT 0x10000000 /* section near gp */
-#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */
-
-/* Processor specific values for the Dyn d_tag field. */
-#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0)
-#define DT_IA_64_NUM 1
-
-/* IA-64 relocations. */
-#define R_IA64_NONE 0x00 /* none */
-#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */
-#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */
-#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */
-#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */
-#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */
-#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */
-#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */
-#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */
-#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */
-#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */
-#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */
-#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */
-#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */
-#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */
-#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */
-#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */
-#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */
-#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */
-#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */
-#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */
-#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */
-#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */
-#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */
-#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */
-#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */
-#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */
-#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */
-#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */
-#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */
-#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */
-#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */
-#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */
-#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */
-#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */
-#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */
-#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */
-#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */
-#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */
-#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */
-#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */
-#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */
-#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */
-#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */
-#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */
-#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */
-#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */
-#define R_IA64_REL32MSB 0x6c /* data 4 + REL */
-#define R_IA64_REL32LSB 0x6d /* data 4 + REL */
-#define R_IA64_REL64MSB 0x6e /* data 8 + REL */
-#define R_IA64_REL64LSB 0x6f /* data 8 + REL */
-#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */
-#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */
-#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */
-#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */
-#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */
-#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */
-#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */
-#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */
-#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */
-#define R_IA64_COPY 0x84 /* copy relocation */
-#define R_IA64_SUB 0x85 /* Addend and symbol difference */
-#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */
-#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */
-#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */
-#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */
-#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */
-#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */
-#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */
-#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */
-#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */
-#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */
-#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */
-#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */
-#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */
-#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */
-#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */
-#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */
-#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */
-#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */
-#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */
-
-/* SH specific declarations */
-
-/* Processor specific flags for the ELF header e_flags field. */
-#define EF_SH_MACH_MASK 0x1f
-#define EF_SH_UNKNOWN 0x0
-#define EF_SH1 0x1
-#define EF_SH2 0x2
-#define EF_SH3 0x3
-#define EF_SH_DSP 0x4
-#define EF_SH3_DSP 0x5
-#define EF_SH4AL_DSP 0x6
-#define EF_SH3E 0x8
-#define EF_SH4 0x9
-#define EF_SH2E 0xb
-#define EF_SH4A 0xc
-#define EF_SH2A 0xd
-#define EF_SH4_NOFPU 0x10
-#define EF_SH4A_NOFPU 0x11
-#define EF_SH4_NOMMU_NOFPU 0x12
-#define EF_SH2A_NOFPU 0x13
-#define EF_SH3_NOMMU 0x14
-#define EF_SH2A_SH4_NOFPU 0x15
-#define EF_SH2A_SH3_NOFPU 0x16
-#define EF_SH2A_SH4 0x17
-#define EF_SH2A_SH3E 0x18
-
-/* SH relocs. */
-#define R_SH_NONE 0
-#define R_SH_DIR32 1
-#define R_SH_REL32 2
-#define R_SH_DIR8WPN 3
-#define R_SH_IND12W 4
-#define R_SH_DIR8WPL 5
-#define R_SH_DIR8WPZ 6
-#define R_SH_DIR8BP 7
-#define R_SH_DIR8W 8
-#define R_SH_DIR8L 9
-#define R_SH_SWITCH16 25
-#define R_SH_SWITCH32 26
-#define R_SH_USES 27
-#define R_SH_COUNT 28
-#define R_SH_ALIGN 29
-#define R_SH_CODE 30
-#define R_SH_DATA 31
-#define R_SH_LABEL 32
-#define R_SH_SWITCH8 33
-#define R_SH_GNU_VTINHERIT 34
-#define R_SH_GNU_VTENTRY 35
-#define R_SH_TLS_GD_32 144
-#define R_SH_TLS_LD_32 145
-#define R_SH_TLS_LDO_32 146
-#define R_SH_TLS_IE_32 147
-#define R_SH_TLS_LE_32 148
-#define R_SH_TLS_DTPMOD32 149
-#define R_SH_TLS_DTPOFF32 150
-#define R_SH_TLS_TPOFF32 151
-#define R_SH_GOT32 160
-#define R_SH_PLT32 161
-#define R_SH_COPY 162
-#define R_SH_GLOB_DAT 163
-#define R_SH_JMP_SLOT 164
-#define R_SH_RELATIVE 165
-#define R_SH_GOTOFF 166
-#define R_SH_GOTPC 167
-/* Keep this the last entry. */
-#define R_SH_NUM 256
-
-/* S/390 specific definitions. */
-
-/* Valid values for the e_flags field. */
-
-#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */
-
-/* Additional s390 relocs */
-
-#define R_390_NONE 0 /* No reloc. */
-#define R_390_8 1 /* Direct 8 bit. */
-#define R_390_12 2 /* Direct 12 bit. */
-#define R_390_16 3 /* Direct 16 bit. */
-#define R_390_32 4 /* Direct 32 bit. */
-#define R_390_PC32 5 /* PC relative 32 bit. */
-#define R_390_GOT12 6 /* 12 bit GOT offset. */
-#define R_390_GOT32 7 /* 32 bit GOT offset. */
-#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */
-#define R_390_COPY 9 /* Copy symbol at runtime. */
-#define R_390_GLOB_DAT 10 /* Create GOT entry. */
-#define R_390_JMP_SLOT 11 /* Create PLT entry. */
-#define R_390_RELATIVE 12 /* Adjust by program base. */
-#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */
-#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */
-#define R_390_GOT16 15 /* 16 bit GOT offset. */
-#define R_390_PC16 16 /* PC relative 16 bit. */
-#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */
-#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */
-#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */
-#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */
-#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */
-#define R_390_64 22 /* Direct 64 bit. */
-#define R_390_PC64 23 /* PC relative 64 bit. */
-#define R_390_GOT64 24 /* 64 bit GOT offset. */
-#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */
-#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */
-#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */
-#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */
-#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */
-#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */
-#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */
-#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */
-#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */
-#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */
-#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */
-#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */
-#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */
-#define R_390_TLS_GDCALL 38 /* Tag for function call in general
- dynamic TLS code. */
-#define R_390_TLS_LDCALL 39 /* Tag for function call in local
- dynamic TLS code. */
-#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic
- thread local data. */
-#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic
- thread local data. */
-#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS
- block offset. */
-#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS
- block offset. */
-#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS
- block offset. */
-#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic
- thread local data in LE code. */
-#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic
- thread local data in LE code. */
-#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for
- negated static TLS block offset. */
-#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for
- negated static TLS block offset. */
-#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for
- negated static TLS block offset. */
-#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to
- static TLS block. */
-#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to
- static TLS block. */
-#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS
- block. */
-#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS
- block. */
-#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */
-#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */
-#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS
- block. */
-#define R_390_20 57 /* Direct 20 bit. */
-#define R_390_GOT20 58 /* 20 bit GOT offset. */
-#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */
-#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS
- block offset. */
-#define R_390_IRELATIVE 61 /* STT_GNU_IFUNC relocation. */
-/* Keep this the last entry. */
-#define R_390_NUM 62
-
-
-/* CRIS relocations. */
-#define R_CRIS_NONE 0
-#define R_CRIS_8 1
-#define R_CRIS_16 2
-#define R_CRIS_32 3
-#define R_CRIS_8_PCREL 4
-#define R_CRIS_16_PCREL 5
-#define R_CRIS_32_PCREL 6
-#define R_CRIS_GNU_VTINHERIT 7
-#define R_CRIS_GNU_VTENTRY 8
-#define R_CRIS_COPY 9
-#define R_CRIS_GLOB_DAT 10
-#define R_CRIS_JUMP_SLOT 11
-#define R_CRIS_RELATIVE 12
-#define R_CRIS_16_GOT 13
-#define R_CRIS_32_GOT 14
-#define R_CRIS_16_GOTPLT 15
-#define R_CRIS_32_GOTPLT 16
-#define R_CRIS_32_GOTREL 17
-#define R_CRIS_32_PLT_GOTREL 18
-#define R_CRIS_32_PLT_PCREL 19
-
-#define R_CRIS_NUM 20
-
-
-/* AMD x86-64 relocations. */
-#define R_X86_64_NONE 0 /* No reloc */
-#define R_X86_64_64 1 /* Direct 64 bit */
-#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
-#define R_X86_64_GOT32 3 /* 32 bit GOT entry */
-#define R_X86_64_PLT32 4 /* 32 bit PLT address */
-#define R_X86_64_COPY 5 /* Copy symbol at runtime */
-#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
-#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
-#define R_X86_64_RELATIVE 8 /* Adjust by program base */
-#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative
- offset to GOT */
-#define R_X86_64_32 10 /* Direct 32 bit zero extended */
-#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
-#define R_X86_64_16 12 /* Direct 16 bit zero extended */
-#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */
-#define R_X86_64_8 14 /* Direct 8 bit sign extended */
-#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */
-#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */
-#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */
-#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */
-#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset
- to two GOT entries for GD symbol */
-#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset
- to two GOT entries for LD symbol */
-#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */
-#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset
- to GOT entry for IE symbol */
-#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */
-#define R_X86_64_PC64 24 /* PC relative 64 bit */
-#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */
-#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative
- offset to GOT */
-#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */
-#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset
- to GOT entry */
-#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */
-#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */
-#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset
- to PLT entry */
-#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */
-#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */
-#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */
-#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS
- descriptor. */
-#define R_X86_64_TLSDESC 36 /* TLS descriptor. */
-#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */
-#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */
-
-#define R_X86_64_NUM 39
-
-
-/* AM33 relocations. */
-#define R_MN10300_NONE 0 /* No reloc. */
-#define R_MN10300_32 1 /* Direct 32 bit. */
-#define R_MN10300_16 2 /* Direct 16 bit. */
-#define R_MN10300_8 3 /* Direct 8 bit. */
-#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */
-#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */
-#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */
-#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */
-#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */
-#define R_MN10300_24 9 /* Direct 24 bit. */
-#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */
-#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */
-#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */
-#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */
-#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */
-#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */
-#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */
-#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */
-#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */
-#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */
-#define R_MN10300_COPY 20 /* Copy symbol at runtime. */
-#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */
-#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */
-#define R_MN10300_RELATIVE 23 /* Adjust by program base. */
-#define R_MN10300_TLS_GD 24 /* 32-bit offset for global dynamic. */
-#define R_MN10300_TLS_LD 25 /* 32-bit offset for local dynamic. */
-#define R_MN10300_TLS_LDO 26 /* Module-relative offset. */
-#define R_MN10300_TLS_GOTIE 27 /* GOT offset for static TLS block
- offset. */
-#define R_MN10300_TLS_IE 28 /* GOT address for static TLS block
- offset. */
-#define R_MN10300_TLS_LE 29 /* Offset relative to static TLS
- block. */
-#define R_MN10300_TLS_DTPMOD 30 /* ID of module containing symbol. */
-#define R_MN10300_TLS_DTPOFF 31 /* Offset in module TLS block. */
-#define R_MN10300_TLS_TPOFF 32 /* Offset in static TLS block. */
-#define R_MN10300_SYM_DIFF 33 /* Adjustment for next reloc as needed
- by linker relaxation. */
-#define R_MN10300_ALIGN 34 /* Alignment requirement for linker
- relaxation. */
-#define R_MN10300_NUM 35
-
-
-/* M32R relocs. */
-#define R_M32R_NONE 0 /* No reloc. */
-#define R_M32R_16 1 /* Direct 16 bit. */
-#define R_M32R_32 2 /* Direct 32 bit. */
-#define R_M32R_24 3 /* Direct 24 bit. */
-#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */
-#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */
-#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */
-#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */
-#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */
-#define R_M32R_LO16 9 /* Low 16 bit. */
-#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */
-#define R_M32R_GNU_VTINHERIT 11
-#define R_M32R_GNU_VTENTRY 12
-/* M32R relocs use SHT_RELA. */
-#define R_M32R_16_RELA 33 /* Direct 16 bit. */
-#define R_M32R_32_RELA 34 /* Direct 32 bit. */
-#define R_M32R_24_RELA 35 /* Direct 24 bit. */
-#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */
-#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */
-#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */
-#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */
-#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */
-#define R_M32R_LO16_RELA 41 /* Low 16 bit */
-#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */
-#define R_M32R_RELA_GNU_VTINHERIT 43
-#define R_M32R_RELA_GNU_VTENTRY 44
-#define R_M32R_REL32 45 /* PC relative 32 bit. */
-
-#define R_M32R_GOT24 48 /* 24 bit GOT entry */
-#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */
-#define R_M32R_COPY 50 /* Copy symbol at runtime */
-#define R_M32R_GLOB_DAT 51 /* Create GOT entry */
-#define R_M32R_JMP_SLOT 52 /* Create PLT entry */
-#define R_M32R_RELATIVE 53 /* Adjust by program base */
-#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */
-#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */
-#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned
- low */
-#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed
- low */
-#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */
-#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to
- GOT with unsigned low */
-#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to
- GOT with signed low */
-#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to
- GOT */
-#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT
- with unsigned low */
-#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT
- with signed low */
-#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */
-#define R_M32R_NUM 256 /* Keep this the last entry. */
-
-/* MicroBlaze relocations */
-#define R_MICROBLAZE_NONE 0 /* No reloc. */
-#define R_MICROBLAZE_32 1 /* Direct 32 bit. */
-#define R_MICROBLAZE_32_PCREL 2 /* PC relative 32 bit. */
-#define R_MICROBLAZE_64_PCREL 3 /* PC relative 64 bit. */
-#define R_MICROBLAZE_32_PCREL_LO 4 /* Low 16 bits of PCREL32. */
-#define R_MICROBLAZE_64 5 /* Direct 64 bit. */
-#define R_MICROBLAZE_32_LO 6 /* Low 16 bit. */
-#define R_MICROBLAZE_SRO32 7 /* Read-only small data area. */
-#define R_MICROBLAZE_SRW32 8 /* Read-write small data area. */
-#define R_MICROBLAZE_64_NONE 9 /* No reloc. */
-#define R_MICROBLAZE_32_SYM_OP_SYM 10 /* Symbol Op Symbol relocation. */
-#define R_MICROBLAZE_GNU_VTINHERIT 11 /* GNU C++ vtable hierarchy. */
-#define R_MICROBLAZE_GNU_VTENTRY 12 /* GNU C++ vtable member usage. */
-#define R_MICROBLAZE_GOTPC_64 13 /* PC-relative GOT offset. */
-#define R_MICROBLAZE_GOT_64 14 /* GOT entry offset. */
-#define R_MICROBLAZE_PLT_64 15 /* PLT offset (PC-relative). */
-#define R_MICROBLAZE_REL 16 /* Adjust by program base. */
-#define R_MICROBLAZE_JUMP_SLOT 17 /* Create PLT entry. */
-#define R_MICROBLAZE_GLOB_DAT 18 /* Create GOT entry. */
-#define R_MICROBLAZE_GOTOFF_64 19 /* 64 bit offset to GOT. */
-#define R_MICROBLAZE_GOTOFF_32 20 /* 32 bit offset to GOT. */
-#define R_MICROBLAZE_COPY 21 /* Runtime copy. */
-#define R_MICROBLAZE_TLS 22 /* TLS Reloc. */
-#define R_MICROBLAZE_TLSGD 23 /* TLS General Dynamic. */
-#define R_MICROBLAZE_TLSLD 24 /* TLS Local Dynamic. */
-#define R_MICROBLAZE_TLSDTPMOD32 25 /* TLS Module ID. */
-#define R_MICROBLAZE_TLSDTPREL32 26 /* TLS Offset Within TLS Block. */
-#define R_MICROBLAZE_TLSDTPREL64 27 /* TLS Offset Within TLS Block. */
-#define R_MICROBLAZE_TLSGOTTPREL32 28 /* TLS Offset From Thread Pointer. */
-#define R_MICROBLAZE_TLSTPREL32 29 /* TLS Offset From Thread Pointer. */
-
-/* TILEPro relocations. */
-#define R_TILEPRO_NONE 0 /* No reloc */
-#define R_TILEPRO_32 1 /* Direct 32 bit */
-#define R_TILEPRO_16 2 /* Direct 16 bit */
-#define R_TILEPRO_8 3 /* Direct 8 bit */
-#define R_TILEPRO_32_PCREL 4 /* PC relative 32 bit */
-#define R_TILEPRO_16_PCREL 5 /* PC relative 16 bit */
-#define R_TILEPRO_8_PCREL 6 /* PC relative 8 bit */
-#define R_TILEPRO_LO16 7 /* Low 16 bit */
-#define R_TILEPRO_HI16 8 /* High 16 bit */
-#define R_TILEPRO_HA16 9 /* High 16 bit, adjusted */
-#define R_TILEPRO_COPY 10 /* Copy relocation */
-#define R_TILEPRO_GLOB_DAT 11 /* Create GOT entry */
-#define R_TILEPRO_JMP_SLOT 12 /* Create PLT entry */
-#define R_TILEPRO_RELATIVE 13 /* Adjust by program base */
-#define R_TILEPRO_BROFF_X1 14 /* X1 pipe branch offset */
-#define R_TILEPRO_JOFFLONG_X1 15 /* X1 pipe jump offset */
-#define R_TILEPRO_JOFFLONG_X1_PLT 16 /* X1 pipe jump offset to PLT */
-#define R_TILEPRO_IMM8_X0 17 /* X0 pipe 8-bit */
-#define R_TILEPRO_IMM8_Y0 18 /* Y0 pipe 8-bit */
-#define R_TILEPRO_IMM8_X1 19 /* X1 pipe 8-bit */
-#define R_TILEPRO_IMM8_Y1 20 /* Y1 pipe 8-bit */
-#define R_TILEPRO_MT_IMM15_X1 21 /* X1 pipe mtspr */
-#define R_TILEPRO_MF_IMM15_X1 22 /* X1 pipe mfspr */
-#define R_TILEPRO_IMM16_X0 23 /* X0 pipe 16-bit */
-#define R_TILEPRO_IMM16_X1 24 /* X1 pipe 16-bit */
-#define R_TILEPRO_IMM16_X0_LO 25 /* X0 pipe low 16-bit */
-#define R_TILEPRO_IMM16_X1_LO 26 /* X1 pipe low 16-bit */
-#define R_TILEPRO_IMM16_X0_HI 27 /* X0 pipe high 16-bit */
-#define R_TILEPRO_IMM16_X1_HI 28 /* X1 pipe high 16-bit */
-#define R_TILEPRO_IMM16_X0_HA 29 /* X0 pipe high 16-bit, adjusted */
-#define R_TILEPRO_IMM16_X1_HA 30 /* X1 pipe high 16-bit, adjusted */
-#define R_TILEPRO_IMM16_X0_PCREL 31 /* X0 pipe PC relative 16 bit */
-#define R_TILEPRO_IMM16_X1_PCREL 32 /* X1 pipe PC relative 16 bit */
-#define R_TILEPRO_IMM16_X0_LO_PCREL 33 /* X0 pipe PC relative low 16 bit */
-#define R_TILEPRO_IMM16_X1_LO_PCREL 34 /* X1 pipe PC relative low 16 bit */
-#define R_TILEPRO_IMM16_X0_HI_PCREL 35 /* X0 pipe PC relative high 16 bit */
-#define R_TILEPRO_IMM16_X1_HI_PCREL 36 /* X1 pipe PC relative high 16 bit */
-#define R_TILEPRO_IMM16_X0_HA_PCREL 37 /* X0 pipe PC relative ha() 16 bit */
-#define R_TILEPRO_IMM16_X1_HA_PCREL 38 /* X1 pipe PC relative ha() 16 bit */
-#define R_TILEPRO_IMM16_X0_GOT 39 /* X0 pipe 16-bit GOT offset */
-#define R_TILEPRO_IMM16_X1_GOT 40 /* X1 pipe 16-bit GOT offset */
-#define R_TILEPRO_IMM16_X0_GOT_LO 41 /* X0 pipe low 16-bit GOT offset */
-#define R_TILEPRO_IMM16_X1_GOT_LO 42 /* X1 pipe low 16-bit GOT offset */
-#define R_TILEPRO_IMM16_X0_GOT_HI 43 /* X0 pipe high 16-bit GOT offset */
-#define R_TILEPRO_IMM16_X1_GOT_HI 44 /* X1 pipe high 16-bit GOT offset */
-#define R_TILEPRO_IMM16_X0_GOT_HA 45 /* X0 pipe ha() 16-bit GOT offset */
-#define R_TILEPRO_IMM16_X1_GOT_HA 46 /* X1 pipe ha() 16-bit GOT offset */
-#define R_TILEPRO_MMSTART_X0 47 /* X0 pipe mm "start" */
-#define R_TILEPRO_MMEND_X0 48 /* X0 pipe mm "end" */
-#define R_TILEPRO_MMSTART_X1 49 /* X1 pipe mm "start" */
-#define R_TILEPRO_MMEND_X1 50 /* X1 pipe mm "end" */
-#define R_TILEPRO_SHAMT_X0 51 /* X0 pipe shift amount */
-#define R_TILEPRO_SHAMT_X1 52 /* X1 pipe shift amount */
-#define R_TILEPRO_SHAMT_Y0 53 /* Y0 pipe shift amount */
-#define R_TILEPRO_SHAMT_Y1 54 /* Y1 pipe shift amount */
-#define R_TILEPRO_DEST_IMM8_X1 55 /* X1 pipe destination 8-bit */
-/* Relocs 56-59 are currently not defined. */
-#define R_TILEPRO_TLS_GD_CALL 60 /* "jal" for TLS GD */
-#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61 /* X0 pipe "addi" for TLS GD */
-#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62 /* X1 pipe "addi" for TLS GD */
-#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63 /* Y0 pipe "addi" for TLS GD */
-#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64 /* Y1 pipe "addi" for TLS GD */
-#define R_TILEPRO_TLS_IE_LOAD 65 /* "lw_tls" for TLS IE */
-#define R_TILEPRO_IMM16_X0_TLS_GD 66 /* X0 pipe 16-bit TLS GD offset */
-#define R_TILEPRO_IMM16_X1_TLS_GD 67 /* X1 pipe 16-bit TLS GD offset */
-#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68 /* X0 pipe low 16-bit TLS GD offset */
-#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69 /* X1 pipe low 16-bit TLS GD offset */
-#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70 /* X0 pipe high 16-bit TLS GD offset */
-#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71 /* X1 pipe high 16-bit TLS GD offset */
-#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72 /* X0 pipe ha() 16-bit TLS GD offset */
-#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73 /* X1 pipe ha() 16-bit TLS GD offset */
-#define R_TILEPRO_IMM16_X0_TLS_IE 74 /* X0 pipe 16-bit TLS IE offset */
-#define R_TILEPRO_IMM16_X1_TLS_IE 75 /* X1 pipe 16-bit TLS IE offset */
-#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76 /* X0 pipe low 16-bit TLS IE offset */
-#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77 /* X1 pipe low 16-bit TLS IE offset */
-#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78 /* X0 pipe high 16-bit TLS IE offset */
-#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79 /* X1 pipe high 16-bit TLS IE offset */
-#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80 /* X0 pipe ha() 16-bit TLS IE offset */
-#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81 /* X1 pipe ha() 16-bit TLS IE offset */
-#define R_TILEPRO_TLS_DTPMOD32 82 /* ID of module containing symbol */
-#define R_TILEPRO_TLS_DTPOFF32 83 /* Offset in TLS block */
-#define R_TILEPRO_TLS_TPOFF32 84 /* Offset in static TLS block */
-#define R_TILEPRO_IMM16_X0_TLS_LE 85 /* X0 pipe 16-bit TLS LE offset */
-#define R_TILEPRO_IMM16_X1_TLS_LE 86 /* X1 pipe 16-bit TLS LE offset */
-#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87 /* X0 pipe low 16-bit TLS LE offset */
-#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88 /* X1 pipe low 16-bit TLS LE offset */
-#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89 /* X0 pipe high 16-bit TLS LE offset */
-#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90 /* X1 pipe high 16-bit TLS LE offset */
-#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91 /* X0 pipe ha() 16-bit TLS LE offset */
-#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92 /* X1 pipe ha() 16-bit TLS LE offset */
-
-#define R_TILEPRO_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */
-#define R_TILEPRO_GNU_VTENTRY 129 /* GNU C++ vtable member usage */
-
-#define R_TILEPRO_NUM 130
-
-
-/* TILE-Gx relocations. */
-#define R_TILEGX_NONE 0 /* No reloc */
-#define R_TILEGX_64 1 /* Direct 64 bit */
-#define R_TILEGX_32 2 /* Direct 32 bit */
-#define R_TILEGX_16 3 /* Direct 16 bit */
-#define R_TILEGX_8 4 /* Direct 8 bit */
-#define R_TILEGX_64_PCREL 5 /* PC relative 64 bit */
-#define R_TILEGX_32_PCREL 6 /* PC relative 32 bit */
-#define R_TILEGX_16_PCREL 7 /* PC relative 16 bit */
-#define R_TILEGX_8_PCREL 8 /* PC relative 8 bit */
-#define R_TILEGX_HW0 9 /* hword 0 16-bit */
-#define R_TILEGX_HW1 10 /* hword 1 16-bit */
-#define R_TILEGX_HW2 11 /* hword 2 16-bit */
-#define R_TILEGX_HW3 12 /* hword 3 16-bit */
-#define R_TILEGX_HW0_LAST 13 /* last hword 0 16-bit */
-#define R_TILEGX_HW1_LAST 14 /* last hword 1 16-bit */
-#define R_TILEGX_HW2_LAST 15 /* last hword 2 16-bit */
-#define R_TILEGX_COPY 16 /* Copy relocation */
-#define R_TILEGX_GLOB_DAT 17 /* Create GOT entry */
-#define R_TILEGX_JMP_SLOT 18 /* Create PLT entry */
-#define R_TILEGX_RELATIVE 19 /* Adjust by program base */
-#define R_TILEGX_BROFF_X1 20 /* X1 pipe branch offset */
-#define R_TILEGX_JUMPOFF_X1 21 /* X1 pipe jump offset */
-#define R_TILEGX_JUMPOFF_X1_PLT 22 /* X1 pipe jump offset to PLT */
-#define R_TILEGX_IMM8_X0 23 /* X0 pipe 8-bit */
-#define R_TILEGX_IMM8_Y0 24 /* Y0 pipe 8-bit */
-#define R_TILEGX_IMM8_X1 25 /* X1 pipe 8-bit */
-#define R_TILEGX_IMM8_Y1 26 /* Y1 pipe 8-bit */
-#define R_TILEGX_DEST_IMM8_X1 27 /* X1 pipe destination 8-bit */
-#define R_TILEGX_MT_IMM14_X1 28 /* X1 pipe mtspr */
-#define R_TILEGX_MF_IMM14_X1 29 /* X1 pipe mfspr */
-#define R_TILEGX_MMSTART_X0 30 /* X0 pipe mm "start" */
-#define R_TILEGX_MMEND_X0 31 /* X0 pipe mm "end" */
-#define R_TILEGX_SHAMT_X0 32 /* X0 pipe shift amount */
-#define R_TILEGX_SHAMT_X1 33 /* X1 pipe shift amount */
-#define R_TILEGX_SHAMT_Y0 34 /* Y0 pipe shift amount */
-#define R_TILEGX_SHAMT_Y1 35 /* Y1 pipe shift amount */
-#define R_TILEGX_IMM16_X0_HW0 36 /* X0 pipe hword 0 */
-#define R_TILEGX_IMM16_X1_HW0 37 /* X1 pipe hword 0 */
-#define R_TILEGX_IMM16_X0_HW1 38 /* X0 pipe hword 1 */
-#define R_TILEGX_IMM16_X1_HW1 39 /* X1 pipe hword 1 */
-#define R_TILEGX_IMM16_X0_HW2 40 /* X0 pipe hword 2 */
-#define R_TILEGX_IMM16_X1_HW2 41 /* X1 pipe hword 2 */
-#define R_TILEGX_IMM16_X0_HW3 42 /* X0 pipe hword 3 */
-#define R_TILEGX_IMM16_X1_HW3 43 /* X1 pipe hword 3 */
-#define R_TILEGX_IMM16_X0_HW0_LAST 44 /* X0 pipe last hword 0 */
-#define R_TILEGX_IMM16_X1_HW0_LAST 45 /* X1 pipe last hword 0 */
-#define R_TILEGX_IMM16_X0_HW1_LAST 46 /* X0 pipe last hword 1 */
-#define R_TILEGX_IMM16_X1_HW1_LAST 47 /* X1 pipe last hword 1 */
-#define R_TILEGX_IMM16_X0_HW2_LAST 48 /* X0 pipe last hword 2 */
-#define R_TILEGX_IMM16_X1_HW2_LAST 49 /* X1 pipe last hword 2 */
-#define R_TILEGX_IMM16_X0_HW0_PCREL 50 /* X0 pipe PC relative hword 0 */
-#define R_TILEGX_IMM16_X1_HW0_PCREL 51 /* X1 pipe PC relative hword 0 */
-#define R_TILEGX_IMM16_X0_HW1_PCREL 52 /* X0 pipe PC relative hword 1 */
-#define R_TILEGX_IMM16_X1_HW1_PCREL 53 /* X1 pipe PC relative hword 1 */
-#define R_TILEGX_IMM16_X0_HW2_PCREL 54 /* X0 pipe PC relative hword 2 */
-#define R_TILEGX_IMM16_X1_HW2_PCREL 55 /* X1 pipe PC relative hword 2 */
-#define R_TILEGX_IMM16_X0_HW3_PCREL 56 /* X0 pipe PC relative hword 3 */
-#define R_TILEGX_IMM16_X1_HW3_PCREL 57 /* X1 pipe PC relative hword 3 */
-#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */
-#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */
-#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */
-#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */
-#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */
-#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */
-#define R_TILEGX_IMM16_X0_HW0_GOT 64 /* X0 pipe hword 0 GOT offset */
-#define R_TILEGX_IMM16_X1_HW0_GOT 65 /* X1 pipe hword 0 GOT offset */
-#define R_TILEGX_IMM16_X0_HW0_PLT_PCREL 66 /* X0 pipe PC-rel PLT hword 0 */
-#define R_TILEGX_IMM16_X1_HW0_PLT_PCREL 67 /* X1 pipe PC-rel PLT hword 0 */
-#define R_TILEGX_IMM16_X0_HW1_PLT_PCREL 68 /* X0 pipe PC-rel PLT hword 1 */
-#define R_TILEGX_IMM16_X1_HW1_PLT_PCREL 69 /* X1 pipe PC-rel PLT hword 1 */
-#define R_TILEGX_IMM16_X0_HW2_PLT_PCREL 70 /* X0 pipe PC-rel PLT hword 2 */
-#define R_TILEGX_IMM16_X1_HW2_PLT_PCREL 71 /* X1 pipe PC-rel PLT hword 2 */
-#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */
-#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */
-#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */
-#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */
-#define R_TILEGX_IMM16_X0_HW3_PLT_PCREL 76 /* X0 pipe PC-rel PLT hword 3 */
-#define R_TILEGX_IMM16_X1_HW3_PLT_PCREL 77 /* X1 pipe PC-rel PLT hword 3 */
-#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78 /* X0 pipe hword 0 TLS GD offset */
-#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79 /* X1 pipe hword 0 TLS GD offset */
-#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80 /* X0 pipe hword 0 TLS LE offset */
-#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81 /* X1 pipe hword 0 TLS LE offset */
-#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */
-#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */
-#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */
-#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */
-#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */
-#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */
-#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */
-#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */
-/* Relocs 90-91 are currently not defined. */
-#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92 /* X0 pipe hword 0 TLS IE offset */
-#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93 /* X1 pipe hword 0 TLS IE offset */
-#define R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL 94 /* X0 pipe PC-rel PLT last hword 0 */
-#define R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL 95 /* X1 pipe PC-rel PLT last hword 0 */
-#define R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL 96 /* X0 pipe PC-rel PLT last hword 1 */
-#define R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL 97 /* X1 pipe PC-rel PLT last hword 1 */
-#define R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL 98 /* X0 pipe PC-rel PLT last hword 2 */
-#define R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL 99 /* X1 pipe PC-rel PLT last hword 2 */
-#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */
-#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */
-#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */
-#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */
-/* Relocs 104-105 are currently not defined. */
-#define R_TILEGX_TLS_DTPMOD64 106 /* 64-bit ID of symbol's module */
-#define R_TILEGX_TLS_DTPOFF64 107 /* 64-bit offset in TLS block */
-#define R_TILEGX_TLS_TPOFF64 108 /* 64-bit offset in static TLS block */
-#define R_TILEGX_TLS_DTPMOD32 109 /* 32-bit ID of symbol's module */
-#define R_TILEGX_TLS_DTPOFF32 110 /* 32-bit offset in TLS block */
-#define R_TILEGX_TLS_TPOFF32 111 /* 32-bit offset in static TLS block */
-#define R_TILEGX_TLS_GD_CALL 112 /* "jal" for TLS GD */
-#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113 /* X0 pipe "addi" for TLS GD */
-#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114 /* X1 pipe "addi" for TLS GD */
-#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115 /* Y0 pipe "addi" for TLS GD */
-#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116 /* Y1 pipe "addi" for TLS GD */
-#define R_TILEGX_TLS_IE_LOAD 117 /* "ld_tls" for TLS IE */
-#define R_TILEGX_IMM8_X0_TLS_ADD 118 /* X0 pipe "addi" for TLS GD/IE */
-#define R_TILEGX_IMM8_X1_TLS_ADD 119 /* X1 pipe "addi" for TLS GD/IE */
-#define R_TILEGX_IMM8_Y0_TLS_ADD 120 /* Y0 pipe "addi" for TLS GD/IE */
-#define R_TILEGX_IMM8_Y1_TLS_ADD 121 /* Y1 pipe "addi" for TLS GD/IE */
-
-#define R_TILEGX_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */
-#define R_TILEGX_GNU_VTENTRY 129 /* GNU C++ vtable member usage */
-
-#define R_TILEGX_NUM 130
-
-/* OR1K relocations */
-#define R_OR1K_NONE 0
-#define R_OR1K_32 1
-#define R_OR1K_16 2
-#define R_OR1K_8 3
-#define R_OR1K_LO_16_IN_INSN 4
-#define R_OR1K_HI_16_IN_INSN 5
-#define R_OR1K_INSN_REL_26 6
-#define R_OR1K_GNU_VTENTRY 7
-#define R_OR1K_GNU_VTINHERIT 8
-#define R_OR1K_32_PCREL 9
-#define R_OR1K_16_PCREL 10
-#define R_OR1K_8_PCREL 11
-#define R_OR1K_GOTPC_HI16 12
-#define R_OR1K_GOTPC_LO16 13
-#define R_OR1K_GOT16 14
-#define R_OR1K_PLT26 15
-#define R_OR1K_GOTOFF_HI16 16
-#define R_OR1K_GOTOFF_LO16 17
-#define R_OR1K_COPY 18
-#define R_OR1K_GLOB_DAT 19
-#define R_OR1K_JMP_SLOT 20
-#define R_OR1K_RELATIVE 21
-#define R_OR1K_TLS_GD_HI16 22
-#define R_OR1K_TLS_GD_LO16 23
-#define R_OR1K_TLS_LDM_HI16 24
-#define R_OR1K_TLS_LDM_LO16 25
-#define R_OR1K_TLS_LDO_HI16 26
-#define R_OR1K_TLS_LDO_LO16 27
-#define R_OR1K_TLS_IE_HI16 28
-#define R_OR1K_TLS_IE_LO16 29
-#define R_OR1K_TLS_LE_HI16 30
-#define R_OR1K_TLS_LE_LO16 31
-#define R_OR1K_TLS_TPOFF 32
-#define R_OR1K_TLS_DTPOFF 33
-#define R_OR1K_TLS_DTPMOD 34
-
-#define R_OR1K_NUM 35
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* elf.h */
+++ /dev/null
-#ifndef __LINK_H
-#define __LINK_H
-
-#include <stddef.h>
-#include <elf.h>
-
-#define ElfW(type) Elf32_##type
-
-struct dl_phdr_info {
- ElfW(Addr) dlpi_addr;
- const char *dlpi_name;
- const ElfW(Phdr) *dlpi_phdr;
- ElfW(Half) dlpi_phnum;
-};
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern int dl_iterate_phdr (int (*__callback) (struct dl_phdr_info *,
- size_t, void *),
- void *__data);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __LINK_H */
+++ /dev/null
-#ifndef __HW_COMMON_H
-#define __HW_COMMON_H
-
-#ifdef __ASSEMBLER__
-#define MMPTR(x) x
-#else
-#define MMPTR(x) (*((volatile unsigned int *)(x)))
-#endif
-
-#endif
+++ /dev/null
-#ifndef __HW_ETHMAC_MEM_H
-#define __HW_ETHMAC_MEM_H
-
-#include <generated/mem.h>
-
-#define ETHMAC_RX0_BASE ETHMAC_BASE
-#define ETHMAC_RX1_BASE (ETHMAC_BASE+0x0800)
-#define ETHMAC_TX0_BASE (ETHMAC_BASE+0x1000)
-#define ETHMAC_TX1_BASE (ETHMAC_BASE+0x1800)
-
-#endif
+++ /dev/null
-#ifndef __HW_FLAGS_H
-#define __HW_FLAGS_H
-
-#define UART_EV_TX 0x1
-#define UART_EV_RX 0x2
-
-#define DFII_CONTROL_SEL 0x01
-#define DFII_CONTROL_CKE 0x02
-#define DFII_CONTROL_ODT 0x04
-#define DFII_CONTROL_RESET_N 0x08
-
-#define DFII_COMMAND_CS 0x01
-#define DFII_COMMAND_WE 0x02
-#define DFII_COMMAND_CAS 0x04
-#define DFII_COMMAND_RAS 0x08
-#define DFII_COMMAND_WRDATA 0x10
-#define DFII_COMMAND_RDDATA 0x20
-
-#define ETHMAC_EV_SRAM_WRITER 0x1
-#define ETHMAC_EV_SRAM_READER 0x1
-
-#define CLKGEN_STATUS_BUSY 0x1
-#define CLKGEN_STATUS_PROGDONE 0x2
-#define CLKGEN_STATUS_LOCKED 0x4
-
-#define DVISAMPLER_TOO_LATE 0x1
-#define DVISAMPLER_TOO_EARLY 0x2
-
-#define DVISAMPLER_DELAY_MASTER_CAL 0x01
-#define DVISAMPLER_DELAY_MASTER_RST 0x02
-#define DVISAMPLER_DELAY_SLAVE_CAL 0x04
-#define DVISAMPLER_DELAY_SLAVE_RST 0x08
-#define DVISAMPLER_DELAY_INC 0x10
-#define DVISAMPLER_DELAY_DEC 0x20
-
-#define DVISAMPLER_SLOT_EMPTY 0
-#define DVISAMPLER_SLOT_LOADED 1
-#define DVISAMPLER_SLOT_PENDING 2
-
-#endif /* __HW_FLAGS_H */
+++ /dev/null
-#ifndef __MICROUDP_H
-#define __MICROUDP_H
-
-#define IPTOINT(a, b, c, d) ((a << 24)|(b << 16)|(c << 8)|d)
-
-#define MICROUDP_BUFSIZE (5*1532)
-
-typedef void (*udp_callback)(unsigned int src_ip, unsigned short src_port, unsigned short dst_port, void *data, unsigned int length);
-
-void microudp_start(const unsigned char *macaddr, unsigned int ip);
-int microudp_arp_resolve(unsigned int ip);
-void *microudp_get_tx_buffer(void);
-int microudp_send(unsigned short src_port, unsigned short dst_port, unsigned int length);
-void microudp_set_callback(udp_callback callback);
-void microudp_service(void);
-
-void eth_init(void);
-void eth_mode(void);
-
-#endif /* __MICROUDP_H */
+++ /dev/null
-#ifndef __TFTP_H
-#define __TFTP_H
-
-#include <stdint.h>
-
-int tftp_get(uint32_t ip, const char *filename, void *buffer);
-int tftp_put(uint32_t ip, const char *filename, const void *buffer, int size);
-
-#endif /* __TFTP_H */
-
+++ /dev/null
-include ../include/generated/variables.mak
-include $(MISOC_DIRECTORY)/software/common.mak
-
-OBJECTS=exception.o libc.o errno.o crc16.o crc32.o console.o system.o id.o uart.o time.o qsort.o strtod.o spiflash.o
-
-all: crt0-$(CPU).o libbase.a libbase-nofloat.a
-
-libbase.a: $(OBJECTS) vsnprintf.o
- $(AR) crs libbase.a $(OBJECTS) vsnprintf.o
-
-libbase-nofloat.a: $(OBJECTS) vsnprintf-nofloat.o
- $(AR) crs libbase-nofloat.a $(OBJECTS) vsnprintf-nofloat.o
-
-vsnprintf-nofloat.o: $(LIBBASE_DIRECTORY)/vsnprintf.c
- $(call compile,-DNO_FLOAT)
-
-%.o: $(LIBBASE_DIRECTORY)/%.c
- $(compile)
-
-%.o: $(LIBBASE_DIRECTORY)/%.S
- $(assemble)
-
-.PHONY: all clean
-
-clean:
- $(RM) $(OBJECTS) crt0-$(CPU).o vsnprintf.o vsnprintf-nofloat.o
- $(RM) libbase.a libbase-nofloat.a .*~ *~
+++ /dev/null
-#include <uart.h>
-#include <console.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-FILE *stdin, *stdout, *stderr;
-
-static console_write_hook write_hook;
-static console_read_hook read_hook;
-static console_read_nonblock_hook read_nonblock_hook;
-
-void console_set_write_hook(console_write_hook h)
-{
- write_hook = h;
-}
-
-void console_set_read_hook(console_read_hook r, console_read_nonblock_hook rn)
-{
- read_hook = r;
- read_nonblock_hook = rn;
-}
-
-int putchar(int c)
-{
- uart_write(c);
- if(write_hook != NULL)
- write_hook(c);
- return c;
-}
-
-char readchar(void)
-{
- while(1) {
- if(uart_read_nonblock())
- return uart_read();
- if((read_nonblock_hook != NULL) && read_nonblock_hook())
- return read_hook();
- }
-}
-
-int readchar_nonblock(void)
-{
- return (uart_read_nonblock()
- || ((read_nonblock_hook != NULL) && read_nonblock_hook()));
-}
-
-int puts(const char *s)
-{
- while(*s) {
- putchar(*s);
- s++;
- }
- putchar('\n');
- return 1;
-}
-
-void putsnonl(const char *s)
-{
- while(*s) {
- putchar(*s);
- s++;
- }
-}
-
-#define PRINTF_BUFFER_SIZE 256
-
-int printf(const char *fmt, ...)
-{
- va_list args;
- int len;
- char outbuf[PRINTF_BUFFER_SIZE];
-
- va_start(args, fmt);
- len = vscnprintf(outbuf, sizeof(outbuf), fmt, args);
- va_end(args);
- outbuf[len] = 0;
- putsnonl(outbuf);
-
- return len;
-}
+++ /dev/null
-#include <crc.h>
-
-static const unsigned int crc16_table[256] = {
- 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
- 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
- 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
- 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
- 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
- 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
- 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
- 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
- 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
- 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
- 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
- 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
- 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
- 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
- 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
- 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
- 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
- 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
- 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
- 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
- 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
- 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
- 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
- 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
- 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
- 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
- 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
- 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
- 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
- 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
- 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
- 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
-};
-
-unsigned short crc16(const unsigned char *buffer, int len)
-{
- unsigned short crc;
-
- crc = 0;
- while(len-- > 0)
- crc = crc16_table[((crc >> 8) ^ (*buffer++)) & 0xFF] ^ (crc << 8);
-
- return crc;
-}
+++ /dev/null
-/* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-1998 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include <crc.h>
-
-static const unsigned int crc_table[256] = {
- 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
- 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
- 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
- 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
- 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
- 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
- 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
- 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
- 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
- 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
- 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
- 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
- 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
- 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
- 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
- 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
- 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
- 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
- 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
- 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
- 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
- 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
- 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
- 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
- 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
- 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
- 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
- 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
- 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
- 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
- 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
- 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
- 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
- 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
- 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
- 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
- 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
- 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
- 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
- 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
- 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
- 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
- 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
- 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
- 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
- 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
- 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
- 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
- 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
- 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
- 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
- 0x2d02ef8dL
-};
-
-#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
-#define DO2(buf) DO1(buf); DO1(buf);
-#define DO4(buf) DO2(buf); DO2(buf);
-#define DO8(buf) DO4(buf); DO4(buf);
-
-unsigned int crc32(const unsigned char *buffer, unsigned int len)
-{
- unsigned int crc;
- crc = 0;
- crc = crc ^ 0xffffffffL;
- while(len >= 8) {
- DO8(buffer);
- len -= 8;
- }
- if(len) do {
- DO1(buffer);
- } while(--len);
- return crc ^ 0xffffffffL;
-}
+++ /dev/null
-/*
- * LatticeMico32 C startup code.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/* Exception handlers - Must be 32 bytes long. */
-.section .text, "ax", @progbits
-.global _start
-_start:
-_reset_handler:
- xor r0, r0, r0
- wcsr IE, r0
- mvhi r1, hi(_reset_handler)
- ori r1, r1, lo(_reset_handler)
- wcsr EBA, r1
- bi _crt0
- nop
- nop
-
-_breakpoint_handler:
- bi _breakpoint_handler
- nop
- nop
- nop
- nop
- nop
- nop
- nop
-
-_instruction_bus_error_handler:
- bi _instruction_bus_error_handler
- nop
- nop
- nop
- nop
- nop
- nop
- nop
-
-_watchpoint_hander:
- bi _watchpoint_hander
- nop
- nop
- nop
- nop
- nop
- nop
- nop
-
-_data_bus_error_handler:
- bi _data_bus_error_handler
- nop
- nop
- nop
- nop
- nop
- nop
- nop
-
-_divide_by_zero_handler:
- bi _divide_by_zero_handler
- nop
- nop
- nop
- nop
- nop
- nop
- nop
-
-_interrupt_handler:
- sw (sp+0), ra
- calli .save_all
- calli isr
- bi .restore_all_and_eret
- nop
- nop
- nop
- nop
-
-_syscall_handler:
- bi _syscall_handler
- nop
- nop
- nop
- nop
- nop
- nop
- nop
-
-_crt0:
- /* Setup stack and global pointer */
- mvhi sp, hi(_fstack)
- ori sp, sp, lo(_fstack)
-
- /* Clear BSS */
- mvhi r1, hi(_fbss)
- ori r1, r1, lo(_fbss)
- mvhi r3, hi(_ebss)
- ori r3, r3, lo(_ebss)
-.clearBSS:
- be r1, r3, .callMain
- sw (r1+0), r0
- addi r1, r1, 4
- bi .clearBSS
-
-.callMain:
- bi main
-
-.save_all:
- addi sp, sp, -56
- sw (sp+4), r1
- sw (sp+8), r2
- sw (sp+12), r3
- sw (sp+16), r4
- sw (sp+20), r5
- sw (sp+24), r6
- sw (sp+28), r7
- sw (sp+32), r8
- sw (sp+36), r9
- sw (sp+40), r10
- sw (sp+48), ea
- sw (sp+52), ba
- /* ra needs to be moved from initial stack location */
- lw r1, (sp+56)
- sw (sp+44), r1
- ret
-
-.restore_all_and_eret:
- lw r1, (sp+4)
- lw r2, (sp+8)
- lw r3, (sp+12)
- lw r4, (sp+16)
- lw r5, (sp+20)
- lw r6, (sp+24)
- lw r7, (sp+28)
- lw r8, (sp+32)
- lw r9, (sp+36)
- lw r10, (sp+40)
- lw ra, (sp+44)
- lw ea, (sp+48)
- lw ba, (sp+52)
- addi sp, sp, 56
- eret
+++ /dev/null
-/*
- * (C) Copyright 2012, Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <spr-defs.h>
-
-#define EXCEPTION_STACK_SIZE (4*32)
-
-#define HANDLE_EXCEPTION ; \
- l.addi r1, r1, -EXCEPTION_STACK_SIZE ; \
- l.sw 0x1c(r1), r9 ; \
- l.jal _exception_handler ; \
- l.nop ; \
- l.lwz r9, 0x1c(r1) ; \
- l.addi r1, r1, EXCEPTION_STACK_SIZE ; \
- l.rfe ; \
- l.nop
-
-
-.section .text, "ax", @progbits
-.global _start
-_start:
-_reset_handler:
- l.movhi r0, 0
- l.movhi r1, 0
- l.movhi r2, 0
- l.movhi r3, 0
- l.movhi r4, 0
- l.movhi r5, 0
- l.movhi r6, 0
- l.movhi r7, 0
- l.movhi r8, 0
- l.movhi r9, 0
- l.movhi r10, 0
- l.movhi r11, 0
- l.movhi r12, 0
- l.movhi r13, 0
- l.movhi r14, 0
- l.movhi r15, 0
- l.movhi r16, 0
- l.movhi r17, 0
- l.movhi r18, 0
- l.movhi r19, 0
- l.movhi r20, 0
- l.movhi r21, 0
- l.movhi r22, 0
- l.movhi r23, 0
- l.movhi r24, 0
- l.movhi r25, 0
- l.movhi r26, 0
- l.movhi r27, 0
- l.movhi r28, 0
- l.movhi r29, 0
- l.movhi r30, 0
- l.movhi r31, 0
-
- l.ori r21, r0, SPR_SR_SM
- l.mtspr r0, r21, SPR_SR
- l.movhi r21, hi(_reset_handler)
- l.ori r21, r21, lo(_reset_handler)
- l.mtspr r0, r21, SPR_EVBAR
- /* enable caches */
- l.jal _cache_init
- l.nop
- l.j _crt0
- l.nop
-
- /* bus error */
- .org 0x200
- HANDLE_EXCEPTION
-
- /* data page fault */
- .org 0x300
- HANDLE_EXCEPTION
-
- /* instruction page fault */
- .org 0x400
- HANDLE_EXCEPTION
-
- /* tick timer */
- .org 0x500
- HANDLE_EXCEPTION
-
- /* alignment */
- .org 0x600
- HANDLE_EXCEPTION
-
- /* illegal instruction */
- .org 0x700
- HANDLE_EXCEPTION
-
- /* external interrupt */
- .org 0x800
- HANDLE_EXCEPTION
-
- /* D-TLB miss */
- .org 0x900
- HANDLE_EXCEPTION
-
- /* I-TLB miss */
- .org 0xa00
- HANDLE_EXCEPTION
-
- /* range */
- .org 0xb00
- HANDLE_EXCEPTION
-
- /* system call */
- .org 0xc00
- HANDLE_EXCEPTION
-
- /* floating point */
- .org 0xd00
- HANDLE_EXCEPTION
-
- /* trap */
- .org 0xe00
- HANDLE_EXCEPTION
-
- /* reserved */
- .org 0xf00
- HANDLE_EXCEPTION
-
- .org 0x1000
-_crt0:
- /* Setup stack and global pointer */
- l.movhi r1, hi(_fstack)
- l.ori r1, r1, lo(_fstack)
-
- /* Clear BSS */
- l.movhi r21, hi(_fbss)
- l.ori r21, r21, lo(_fbss)
- l.movhi r3, hi(_ebss)
- l.ori r3, r3, lo(_ebss)
-.clearBSS:
- l.sfeq r21, r3
- l.bf .callMain
- l.nop
- l.sw 0(r21), r0
- l.addi r21, r21, 4
- l.j .clearBSS
- l.nop
-
-.callMain:
- l.j main
- l.nop
-
-_exception_handler:
- l.sw 0x00(r1), r2
- l.sw 0x04(r1), r3
- l.sw 0x08(r1), r4
- l.sw 0x0c(r1), r5
- l.sw 0x10(r1), r6
- l.sw 0x14(r1), r7
- l.sw 0x18(r1), r8
- l.sw 0x20(r1), r10
- l.sw 0x24(r1), r11
- l.sw 0x28(r1), r12
- l.sw 0x2c(r1), r13
- l.sw 0x30(r1), r14
- l.sw 0x34(r1), r15
- l.sw 0x38(r1), r16
- l.sw 0x3c(r1), r17
- l.sw 0x40(r1), r18
- l.sw 0x44(r1), r19
- l.sw 0x48(r1), r20
- l.sw 0x4c(r1), r21
- l.sw 0x50(r1), r22
- l.sw 0x54(r1), r23
- l.sw 0x58(r1), r24
- l.sw 0x5c(r1), r25
- l.sw 0x60(r1), r26
- l.sw 0x64(r1), r27
- l.sw 0x68(r1), r28
- l.sw 0x6c(r1), r29
- l.sw 0x70(r1), r30
- l.sw 0x74(r1), r31
-
- /* Save return address */
- l.or r14, r0, r9
- /* Calculate exception vector from handler address */
- l.andi r3, r9, 0xf00
- l.srli r3, r3, 8
- /* Pass saved register state */
- l.or r4, r0, r1
- /* Extract exception PC */
- l.mfspr r5, r0, SPR_EPCR_BASE
- /* Extract exception effective address */
- l.mfspr r6, r0, SPR_EEAR_BASE
- /* Call exception handler with the link address as argument */
- l.jal exception_handler
- l.nop
-
- /* Load return address */
- l.or r9, r0, r14
- /* Restore state */
- l.lwz r2, 0x00(r1)
- l.lwz r3, 0x04(r1)
- l.lwz r4, 0x08(r1)
- l.lwz r5, 0x0c(r1)
- l.lwz r6, 0x10(r1)
- l.lwz r7, 0x14(r1)
- l.lwz r8, 0x18(r1)
- l.lwz r10, 0x20(r1)
- l.lwz r11, 0x24(r1)
- l.lwz r12, 0x28(r1)
- l.lwz r13, 0x2c(r1)
- l.lwz r14, 0x30(r1)
- l.lwz r15, 0x34(r1)
- l.lwz r16, 0x38(r1)
- l.lwz r17, 0x3c(r1)
- l.lwz r18, 0x40(r1)
- l.lwz r19, 0x44(r1)
- l.lwz r20, 0x48(r1)
- l.lwz r21, 0x4c(r1)
- l.lwz r22, 0x50(r1)
- l.lwz r23, 0x54(r1)
- l.lwz r24, 0x58(r1)
- l.lwz r25, 0x5c(r1)
- l.lwz r26, 0x60(r1)
- l.lwz r27, 0x64(r1)
- l.lwz r28, 0x68(r1)
- l.lwz r29, 0x6c(r1)
- l.lwz r30, 0x70(r1)
- l.lwz r31, 0x74(r1)
- l.jr r9
- l.nop
-
-.global _cache_init
-_cache_init:
- /*
- This function is to be used ONLY during reset, before main() is called.
- TODO: Perhaps break into individual enable instruction/data cache
- sections functions, and provide disable functions, also, all
- callable from C
- */
-
- /* Instruction cache enable */
- /* Check if IC present and skip enabling otherwise */
-#if 1
-.L6:
- l.mfspr r3,r0,SPR_UPR
- l.andi r7,r3,SPR_UPR_ICP
- l.sfeq r7,r0
- l.bf .L8
- l.nop
-
- /* Disable IC */
- l.mfspr r6,r0,SPR_SR
- l.addi r5,r0,-1
- l.xori r5,r5,SPR_SR_ICE
- l.and r5,r6,r5
- l.mtspr r0,r5,SPR_SR
-
- /* Establish cache block size
- If BS=0, 16;
- If BS=1, 32;
- r14 contain block size
- */
- l.mfspr r3,r0,SPR_ICCFGR
- l.andi r7,r3,SPR_ICCFGR_CBS
- l.srli r8,r7,7
- l.ori r4,r0,16
- l.sll r14,r4,r8
-
- /* Establish number of cache sets
- r10 contains number of cache sets
- r8 contains log(# of cache sets)
- */
- l.andi r7,r3,SPR_ICCFGR_NCS
- l.srli r8,r7,3
- l.ori r4,r0,1
- l.sll r10,r4,r8
-
- /* Invalidate IC */
- l.addi r6,r0,0
- l.sll r5,r14,r8
-
-.L7: l.mtspr r0,r6,SPR_ICBIR
- l.sfne r6,r5
- l.bf .L7
- l.add r6,r6,r14
-
- /* Enable IC */
- l.mfspr r6,r0,SPR_SR
- l.ori r6,r6,SPR_SR_ICE
- l.mtspr r0,r6,SPR_SR
- l.nop
- l.nop
- l.nop
- l.nop
- l.nop
- l.nop
- l.nop
- l.nop
- /* Data cache enable */
- /* Check if DC present and skip enabling otherwise */
-#endif
-.L8:
-#if 1
- l.mfspr r3,r0,SPR_UPR
- l.andi r7,r3,SPR_UPR_DCP
- l.sfeq r7,r0
- l.bf .L10
- l.nop
- /* Disable DC */
- l.mfspr r6,r0,SPR_SR
- l.addi r5,r0,-1
- l.xori r5,r5,SPR_SR_DCE
- l.and r5,r6,r5
- l.mtspr r0,r5,SPR_SR
- /* Establish cache block size
- If BS=0, 16;
- If BS=1, 32;
- r14 contain block size
- */
- l.mfspr r3,r0,SPR_DCCFGR
- l.andi r7,r3,SPR_DCCFGR_CBS
- l.srli r8,r7,7
- l.ori r4,r0,16
- l.sll r14,r4,r8
- /* Establish number of cache sets
- r10 contains number of cache sets
- r8 contains log(# of cache sets)
- */
- l.andi r7,r3,SPR_DCCFGR_NCS
- l.srli r8,r7,3
- l.ori r4,r0,1
- l.sll r10,r4,r8
- /* Invalidate DC */
- l.addi r6,r0,0
- l.sll r5,r14,r8
-
-.L9:
- l.mtspr r0,r6,SPR_DCBIR
- l.sfne r6,r5
- l.bf .L9
- l.add r6,r6,r14
- /* Enable DC */
- l.mfspr r6,r0,SPR_SR
- l.ori r6,r6,SPR_SR_DCE
- l.mtspr r0,r6,SPR_SR
-#endif
-.L10:
- /* Return */
- l.jr r9
- l.nop
+++ /dev/null
-#include <string.h>
-#include <errno.h>
-
-int errno;
-
-/************************************************************************
- * Based on: lib/string/lib_strerror.c
- *
- * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * 3. Neither the name NuttX nor the names of its contributors may be
- * used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- ************************************************************************/
-
-struct errno_strmap_s
-{
- int errnum;
- char *str;
-};
-
-/* This table maps all error numbers to descriptive strings.
- * The only assumption that the code makes with regard to this
- * this table is that it is order by error number.
- *
- * The size of this table is quite large. Its size can be
- * reduced by eliminating some of the more obscure error
- * strings.
- */
-
-struct errno_strmap_s g_errnomap[] =
-{
- { EPERM, EPERM_STR },
- { ENOENT, ENOENT_STR },
- { ESRCH, ESRCH_STR },
- { EINTR, EINTR_STR },
- { EIO, EIO_STR },
- { ENXIO, ENXIO_STR },
- { E2BIG, E2BIG_STR },
- { ENOEXEC, ENOEXEC_STR },
- { EBADF, EBADF_STR },
- { ECHILD, ECHILD_STR },
- { EAGAIN, EAGAIN_STR },
- { ENOMEM, ENOMEM_STR },
- { EACCES, EACCES_STR },
- { EFAULT, EFAULT_STR },
- { ENOTBLK, ENOTBLK_STR },
- { EBUSY, EBUSY_STR },
- { EEXIST, EEXIST_STR },
- { EXDEV, EXDEV_STR },
- { ENODEV, ENODEV_STR },
- { ENOTDIR, ENOTDIR_STR },
- { EISDIR, EISDIR_STR },
- { EINVAL, EINVAL_STR },
- { ENFILE, ENFILE_STR },
- { EMFILE, EMFILE_STR },
- { ENOTTY, ENOTTY_STR },
- { ETXTBSY, ETXTBSY_STR },
- { EFBIG, EFBIG_STR },
- { ENOSPC, ENOSPC_STR },
- { ESPIPE, ESPIPE_STR },
- { EROFS, EROFS_STR },
- { EMLINK, EMLINK_STR },
- { EPIPE, EPIPE_STR },
- { EDOM, EDOM_STR },
- { ERANGE, ERANGE_STR },
- { EDEADLK, EDEADLK_STR },
- { ENAMETOOLONG, ENAMETOOLONG_STR },
- { ENOLCK, ENOLCK_STR },
- { ENOSYS, ENOSYS_STR },
- { ENOTEMPTY, ENOTEMPTY_STR },
- { ELOOP, ELOOP_STR },
- { ENOMSG, ENOMSG_STR },
- { EIDRM, EIDRM_STR },
- { ECHRNG, ECHRNG_STR },
- { EL2NSYNC, EL2NSYNC_STR },
- { EL3HLT, EL3HLT_STR },
- { EL3RST, EL3RST_STR },
- { ELNRNG, ELNRNG_STR },
- { EUNATCH, EUNATCH_STR },
- { ENOCSI, ENOCSI_STR },
- { EL2HLT, EL2HLT_STR },
- { EBADE, EBADE_STR },
- { EBADR, EBADR_STR },
- { EXFULL, EXFULL_STR },
- { ENOANO, ENOANO_STR },
- { EBADRQC, EBADRQC_STR },
- { EBADSLT, EBADSLT_STR },
- { EBFONT, EBFONT_STR },
- { ENOSTR, ENOSTR_STR },
- { ENODATA, ENODATA_STR },
- { ETIME, ETIME_STR },
- { ENOSR, ENOSR_STR },
- { ENONET, ENONET_STR },
- { ENOPKG, ENOPKG_STR },
- { EREMOTE, EREMOTE_STR },
- { ENOLINK, ENOLINK_STR },
- { EADV, EADV_STR },
- { ESRMNT, ESRMNT_STR },
- { ECOMM, ECOMM_STR },
- { EPROTO, EPROTO_STR },
- { EMULTIHOP, EMULTIHOP_STR },
- { EDOTDOT, EDOTDOT_STR },
- { EBADMSG, EBADMSG_STR },
- { EOVERFLOW, EOVERFLOW_STR },
- { ENOTUNIQ, ENOTUNIQ_STR },
- { EBADFD, EBADFD_STR },
- { EREMCHG, EREMCHG_STR },
- { ELIBACC, ELIBACC_STR },
- { ELIBBAD, ELIBBAD_STR },
- { ELIBSCN, ELIBSCN_STR },
- { ELIBMAX, ELIBMAX_STR },
- { ELIBEXEC, ELIBEXEC_STR },
- { EILSEQ, EILSEQ_STR },
- { ERESTART, ERESTART_STR },
- { ESTRPIPE, ESTRPIPE_STR },
- { EUSERS, EUSERS_STR },
- { ENOTSOCK, ENOTSOCK_STR },
- { EDESTADDRREQ, EDESTADDRREQ_STR },
- { EMSGSIZE, EMSGSIZE_STR },
- { EPROTOTYPE, EPROTOTYPE_STR },
- { ENOPROTOOPT, ENOPROTOOPT_STR },
- { EPROTONOSUPPORT, EPROTONOSUPPORT_STR },
- { ESOCKTNOSUPPORT, ESOCKTNOSUPPORT_STR },
- { EOPNOTSUPP, EOPNOTSUPP_STR },
- { EPFNOSUPPORT, EPFNOSUPPORT_STR },
- { EAFNOSUPPORT, EAFNOSUPPORT_STR },
- { EADDRINUSE, EADDRINUSE_STR },
- { EADDRNOTAVAIL, EADDRNOTAVAIL_STR },
- { ENETDOWN, ENETDOWN_STR },
- { ENETUNREACH, ENETUNREACH_STR },
- { ENETRESET, ENETRESET_STR },
- { ECONNABORTED, ECONNABORTED_STR },
- { ECONNRESET, ECONNRESET_STR },
- { ENOBUFS, ENOBUFS_STR },
- { EISCONN, EISCONN_STR },
- { ENOTCONN, ENOTCONN_STR },
- { ESHUTDOWN, ESHUTDOWN_STR },
- { ETOOMANYREFS, ETOOMANYREFS_STR },
- { ETIMEDOUT, ETIMEDOUT_STR },
- { ECONNREFUSED, ECONNREFUSED_STR },
- { EHOSTDOWN, EHOSTDOWN_STR },
- { EHOSTUNREACH, EHOSTUNREACH_STR },
- { EALREADY, EALREADY_STR },
- { EINPROGRESS, EINPROGRESS_STR },
- { ESTALE, ESTALE_STR },
- { EUCLEAN, EUCLEAN_STR },
- { ENOTNAM, ENOTNAM_STR },
- { ENAVAIL, ENAVAIL_STR },
- { EISNAM, EISNAM_STR },
- { EREMOTEIO, EREMOTEIO_STR },
- { EDQUOT, EDQUOT_STR },
- { ENOMEDIUM, ENOMEDIUM_STR },
- { EMEDIUMTYPE, EMEDIUMTYPE_STR }
-};
-
-#define NERRNO_STRS (sizeof(g_errnomap) / sizeof(struct errno_strmap_s))
-
-char *strerror(int errnum)
-{
- int ndxlow = 0;
- int ndxhi = NERRNO_STRS - 1;
- int ndxmid;
-
- do
- {
- ndxmid = (ndxlow + ndxhi) >> 1;
- if (errnum > g_errnomap[ndxmid].errnum)
- {
- ndxlow = ndxmid + 1;
- }
- else if (errnum < g_errnomap[ndxmid].errnum)
- {
- ndxhi = ndxmid - 1;
- }
- else
- {
- return g_errnomap[ndxmid].str;
- }
- }
- while (ndxlow <= ndxhi);
- return "Unknown error";
-}
+++ /dev/null
-void isr(void);
-
-#ifdef __or1k__
-
-#define EXTERNAL_IRQ 0x8
-
-void exception_handler(unsigned long vect, unsigned long *regs,
- unsigned long pc, unsigned long ea);
-void exception_handler(unsigned long vect, unsigned long *regs,
- unsigned long pc, unsigned long ea)
-{
- if(vect == EXTERNAL_IRQ) {
- isr();
- } else {
- /* Unhandled exception */
- for(;;);
- }
-}
-#endif
+++ /dev/null
-#include <generated/csr.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <id.h>
-
-void get_sysid_formatted(char *sysid)
-{
- sysid[0] = identifier_sysid_read() >> 8;
- sysid[1] = identifier_sysid_read();
- sysid[2] = 0;
-}
-
-void id_print(void)
-{
- char sysid[3];
-
- get_sysid_formatted(sysid);
- printf("Running on MiSoC (sysid:%s) at %dMHz\n", sysid, identifier_frequency_read()/1000000);
-}
+++ /dev/null
-/*
- * MiSoC
- * Copyright (C) 2007, 2008, 2009, 2010, 2011 Sebastien Bourdeauducq
- * Copyright (C) Linus Torvalds and Linux kernel developers
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <limits.h>
-
-/**
- * strchr - Find the first occurrence of a character in a string
- * @s: The string to be searched
- * @c: The character to search for
- */
-char *strchr(const char *s, int c)
-{
- for (; *s != (char)c; ++s)
- if (*s == '\0')
- return NULL;
- return (char *)s;
-}
-
-/**
- * strpbrk - Find the first occurrence of a set of characters
- * @cs: The string to be searched
- * @ct: The characters to search for
- */
-char *strpbrk(const char *cs, const char *ct)
-{
- const char *sc1, *sc2;
-
- for (sc1 = cs; *sc1 != '\0'; ++sc1) {
- for (sc2 = ct; *sc2 != '\0'; ++sc2) {
- if (*sc1 == *sc2)
- return (char *)sc1;
- }
- }
- return NULL;
-}
-
-/**
- * strrchr - Find the last occurrence of a character in a string
- * @s: The string to be searched
- * @c: The character to search for
- */
-char *strrchr(const char *s, int c)
-{
- const char *p = s + strlen(s);
- do {
- if (*p == (char)c)
- return (char *)p;
- } while (--p >= s);
- return NULL;
-}
-
-/**
- * strnchr - Find a character in a length limited string
- * @s: The string to be searched
- * @count: The number of characters to be searched
- * @c: The character to search for
- */
-char *strnchr(const char *s, size_t count, int c)
-{
- for (; count-- && *s != '\0'; ++s)
- if (*s == (char)c)
- return (char *)s;
- return NULL;
-}
-
-/**
- * strcpy - Copy a %NUL terminated string
- * @dest: Where to copy the string to
- * @src: Where to copy the string from
- */
-char *strcpy(char *dest, const char *src)
-{
- char *tmp = dest;
-
- while ((*dest++ = *src++) != '\0')
- /* nothing */;
- return tmp;
-}
-
-/**
- * strncpy - Copy a length-limited, %NUL-terminated string
- * @dest: Where to copy the string to
- * @src: Where to copy the string from
- * @count: The maximum number of bytes to copy
- *
- * The result is not %NUL-terminated if the source exceeds
- * @count bytes.
- *
- * In the case where the length of @src is less than that of
- * count, the remainder of @dest will be padded with %NUL.
- *
- */
-char *strncpy(char *dest, const char *src, size_t count)
-{
- char *tmp = dest;
-
- while (count) {
- if ((*tmp = *src) != 0)
- src++;
- tmp++;
- count--;
- }
- return dest;
-}
-
-/**
- * strcmp - Compare two strings
- * @cs: One string
- * @ct: Another string
- */
-int strcmp(const char *cs, const char *ct)
-{
- signed char __res;
-
- while (1) {
- if ((__res = *cs - *ct++) != 0 || !*cs++)
- break;
- }
- return __res;
-}
-
-/**
- * strncmp - Compare two strings using the first characters only
- * @cs: One string
- * @ct: Another string
- * @count: Number of characters
- */
-int strncmp(const char *cs, const char *ct, size_t count)
-{
- signed char __res;
- size_t n;
-
- n = 0;
- __res = 0;
- while (n < count) {
- if ((__res = *cs - *ct++) != 0 || !*cs++)
- break;
- n++;
- }
- return __res;
-}
-
-/**
- * strcat - Append one %NUL-terminated string to another
- * @dest: The string to be appended to
- * @src: The string to append to it
- */
-char *strcat(char *dest, const char *src)
-{
- char *tmp = dest;
-
- while (*dest)
- dest++;
- while ((*dest++ = *src++) != '\0')
- ;
- return tmp;
-}
-
-/**
- * strncat - Append a length-limited, %NUL-terminated string to another
- * @dest: The string to be appended to
- * @src: The string to append to it
- * @count: The maximum numbers of bytes to copy
- *
- * Note that in contrast to strncpy(), strncat() ensures the result is
- * terminated.
- */
-char *strncat(char *dest, const char *src, size_t count)
-{
- char *tmp = dest;
-
- if (count) {
- while (*dest)
- dest++;
- while ((*dest++ = *src++) != 0) {
- if (--count == 0) {
- *dest = '\0';
- break;
- }
- }
- }
- return tmp;
-}
-
-/**
- * strlen - Find the length of a string
- * @s: The string to be sized
- */
-size_t strlen(const char *s)
-{
- const char *sc;
-
- for (sc = s; *sc != '\0'; ++sc)
- /* nothing */;
- return sc - s;
-}
-
-/**
- * strnlen - Find the length of a length-limited string
- * @s: The string to be sized
- * @count: The maximum number of bytes to search
- */
-size_t strnlen(const char *s, size_t count)
-{
- const char *sc;
-
- for (sc = s; count-- && *sc != '\0'; ++sc)
- /* nothing */;
- return sc - s;
-}
-
-/**
- * strspn - Calculate the length of the initial substring of @s which only contain letters in @accept
- * @s: The string to be searched
- * @accept: The string to search for
- */
-size_t strspn(const char *s, const char *accept)
-{
- const char *p;
- const char *a;
- size_t count = 0;
-
- for (p = s; *p != '\0'; ++p) {
- for (a = accept; *a != '\0'; ++a) {
- if (*p == *a)
- break;
- }
- if (*a == '\0')
- return count;
- ++count;
- }
- return count;
-}
-
-/**
- * memcmp - Compare two areas of memory
- * @cs: One area of memory
- * @ct: Another area of memory
- * @count: The size of the area.
- */
-int memcmp(const void *cs, const void *ct, size_t count)
-{
- const unsigned char *su1, *su2;
- int res = 0;
-
- for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
- if ((res = *su1 - *su2) != 0)
- break;
- return res;
-}
-
-/**
- * memset - Fill a region of memory with the given value
- * @s: Pointer to the start of the area.
- * @c: The byte to fill the area with
- * @count: The size of the area.
- */
-void *memset(void *s, int c, size_t count)
-{
- char *xs = s;
-
- while (count--)
- *xs++ = c;
- return s;
-}
-
-/**
- * memcpy - Copies one area of memory to another
- * @dest: Destination
- * @src: Source
- * @n: The size to copy.
- */
-void *memcpy(void *to, const void *from, size_t n)
-{
- void *xto = to;
- size_t temp;
-
- if(!n)
- return xto;
- if((long)to & 1) {
- char *cto = to;
- const char *cfrom = from;
- *cto++ = *cfrom++;
- to = cto;
- from = cfrom;
- n--;
- }
- if((long)from & 1) {
- char *cto = to;
- const char *cfrom = from;
- for (; n; n--)
- *cto++ = *cfrom++;
- return xto;
- }
- if(n > 2 && (long)to & 2) {
- short *sto = to;
- const short *sfrom = from;
- *sto++ = *sfrom++;
- to = sto;
- from = sfrom;
- n -= 2;
- }
- if((long)from & 2) {
- short *sto = to;
- const short *sfrom = from;
- temp = n >> 1;
- for (; temp; temp--)
- *sto++ = *sfrom++;
- to = sto;
- from = sfrom;
- if(n & 1) {
- char *cto = to;
- const char *cfrom = from;
- *cto = *cfrom;
- }
- return xto;
- }
- temp = n >> 2;
- if(temp) {
- long *lto = to;
- const long *lfrom = from;
- for(; temp; temp--)
- *lto++ = *lfrom++;
- to = lto;
- from = lfrom;
- }
- if(n & 2) {
- short *sto = to;
- const short *sfrom = from;
- *sto++ = *sfrom++;
- to = sto;
- from = sfrom;
- }
- if(n & 1) {
- char *cto = to;
- const char *cfrom = from;
- *cto = *cfrom;
- }
- return xto;
-}
-
-/**
- * memmove - Copies one area of memory to another, overlap possible
- * @dest: Destination
- * @src: Source
- * @n: The size to copy.
- */
-void *memmove(void *dest, const void *src, size_t count)
-{
- char *tmp, *s;
-
- if(dest <= src) {
- tmp = (char *) dest;
- s = (char *) src;
- while(count--)
- *tmp++ = *s++;
- } else {
- tmp = (char *)dest + count;
- s = (char *)src + count;
- while(count--)
- *--tmp = *--s;
- }
-
- return dest;
-}
-
-/**
- * strstr - Find the first substring in a %NUL terminated string
- * @s1: The string to be searched
- * @s2: The string to search for
- */
-char *strstr(const char *s1, const char *s2)
-{
- size_t l1, l2;
-
- l2 = strlen(s2);
- if (!l2)
- return (char *)s1;
- l1 = strlen(s1);
- while (l1 >= l2) {
- l1--;
- if (!memcmp(s1, s2, l2))
- return (char *)s1;
- s1++;
- }
- return NULL;
-}
-
-/**
- * memchr - Find a character in an area of memory.
- * @s: The memory area
- * @c: The byte to search for
- * @n: The size of the area.
- *
- * returns the address of the first occurrence of @c, or %NULL
- * if @c is not found
- */
-void *memchr(const void *s, int c, size_t n)
-{
- const unsigned char *p = s;
- while (n-- != 0) {
- if ((unsigned char)c == *p++) {
- return (void *)(p - 1);
- }
- }
- return NULL;
-}
-
-/**
- * strtoul - convert a string to an unsigned long
- * @nptr: The start of the string
- * @endptr: A pointer to the end of the parsed string will be placed here
- * @base: The number base to use
- */
-unsigned long strtoul(const char *nptr, char **endptr, int base)
-{
- unsigned long result = 0,value;
-
- if (!base) {
- base = 10;
- if (*nptr == '0') {
- base = 8;
- nptr++;
- if ((toupper(*nptr) == 'X') && isxdigit(nptr[1])) {
- nptr++;
- base = 16;
- }
- }
- } else if (base == 16) {
- if (nptr[0] == '0' && toupper(nptr[1]) == 'X')
- nptr += 2;
- }
- while (isxdigit(*nptr) &&
- (value = isdigit(*nptr) ? *nptr-'0' : toupper(*nptr)-'A'+10) < base) {
- result = result*base + value;
- nptr++;
- }
- if (endptr)
- *endptr = (char *)nptr;
- return result;
-}
-
-/**
- * strtol - convert a string to a signed long
- * @nptr: The start of the string
- * @endptr: A pointer to the end of the parsed string will be placed here
- * @base: The number base to use
- */
-long strtol(const char *nptr, char **endptr, int base)
-{
- if(*nptr=='-')
- return -strtoul(nptr+1,endptr,base);
- return strtoul(nptr,endptr,base);
-}
-
-int skip_atoi(const char **s)
-{
- int i=0;
-
- while (isdigit(**s))
- i = i*10 + *((*s)++) - '0';
- return i;
-}
-
-char *number(char *buf, char *end, unsigned long num, int base, int size, int precision, int type)
-{
- char c,sign,tmp[66];
- const char *digits;
- static const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
- static const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
- int i;
-
- digits = (type & PRINTF_LARGE) ? large_digits : small_digits;
- if (type & PRINTF_LEFT)
- type &= ~PRINTF_ZEROPAD;
- if (base < 2 || base > 36)
- return NULL;
- c = (type & PRINTF_ZEROPAD) ? '0' : ' ';
- sign = 0;
- if (type & PRINTF_SIGN) {
- if ((signed long) num < 0) {
- sign = '-';
- num = - (signed long) num;
- size--;
- } else if (type & PRINTF_PLUS) {
- sign = '+';
- size--;
- } else if (type & PRINTF_SPACE) {
- sign = ' ';
- size--;
- }
- }
- if (type & PRINTF_SPECIAL) {
- if (base == 16)
- size -= 2;
- else if (base == 8)
- size--;
- }
- i = 0;
- if (num == 0)
- tmp[i++]='0';
- else while (num != 0) {
- tmp[i++] = digits[num % base];
- num = num / base;
- }
- if (i > precision)
- precision = i;
- size -= precision;
- if (!(type&(PRINTF_ZEROPAD+PRINTF_LEFT))) {
- while(size-->0) {
- if (buf < end)
- *buf = ' ';
- ++buf;
- }
- }
- if (sign) {
- if (buf < end)
- *buf = sign;
- ++buf;
- }
- if (type & PRINTF_SPECIAL) {
- if (base==8) {
- if (buf < end)
- *buf = '0';
- ++buf;
- } else if (base==16) {
- if (buf < end)
- *buf = '0';
- ++buf;
- if (buf < end)
- *buf = digits[33];
- ++buf;
- }
- }
- if (!(type & PRINTF_LEFT)) {
- while (size-- > 0) {
- if (buf < end)
- *buf = c;
- ++buf;
- }
- }
- while (i < precision--) {
- if (buf < end)
- *buf = '0';
- ++buf;
- }
- while (i-- > 0) {
- if (buf < end)
- *buf = tmp[i];
- ++buf;
- }
- while (size-- > 0) {
- if (buf < end)
- *buf = ' ';
- ++buf;
- }
- return buf;
-}
-
-/**
- * vscnprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @size: The size of the buffer, including the trailing null space
- * @fmt: The format string to use
- * @args: Arguments for the format string
- *
- * The return value is the number of characters which have been written into
- * the @buf not including the trailing '\0'. If @size is <= 0 the function
- * returns 0.
- *
- * Call this function if you are already dealing with a va_list.
- * You probably want scnprintf() instead.
- */
-int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
-{
- int i;
-
- i=vsnprintf(buf,size,fmt,args);
- return (i >= size) ? (size - 1) : i;
-}
-
-
-/**
- * snprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @size: The size of the buffer, including the trailing null space
- * @fmt: The format string to use
- * @...: Arguments for the format string
- *
- * The return value is the number of characters which would be
- * generated for the given input, excluding the trailing null,
- * as per ISO C99. If the return is greater than or equal to
- * @size, the resulting string is truncated.
- */
-int snprintf(char * buf, size_t size, const char *fmt, ...)
-{
- va_list args;
- int i;
-
- va_start(args, fmt);
- i=vsnprintf(buf,size,fmt,args);
- va_end(args);
- return i;
-}
-
-/**
- * scnprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @size: The size of the buffer, including the trailing null space
- * @fmt: The format string to use
- * @...: Arguments for the format string
- *
- * The return value is the number of characters written into @buf not including
- * the trailing '\0'. If @size is <= 0 the function returns 0.
- */
-
-int scnprintf(char * buf, size_t size, const char *fmt, ...)
-{
- va_list args;
- int i;
-
- va_start(args, fmt);
- i = vsnprintf(buf, size, fmt, args);
- va_end(args);
- return (i >= size) ? (size - 1) : i;
-}
-
-/**
- * vsprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @fmt: The format string to use
- * @args: Arguments for the format string
- *
- * The function returns the number of characters written
- * into @buf. Use vsnprintf() or vscnprintf() in order to avoid
- * buffer overflows.
- *
- * Call this function if you are already dealing with a va_list.
- * You probably want sprintf() instead.
- */
-int vsprintf(char *buf, const char *fmt, va_list args)
-{
- return vsnprintf(buf, INT_MAX, fmt, args);
-}
-
-/**
- * sprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @fmt: The format string to use
- * @...: Arguments for the format string
- *
- * The function returns the number of characters written
- * into @buf. Use snprintf() or scnprintf() in order to avoid
- * buffer overflows.
- */
-int sprintf(char * buf, const char *fmt, ...)
-{
- va_list args;
- int i;
-
- va_start(args, fmt);
- i=vsnprintf(buf, INT_MAX, fmt, args);
- va_end(args);
- return i;
-}
-
-/* From linux/lib/ctype.c, Copyright (C) 1991, 1992 Linus Torvalds */
-const unsigned char _ctype[] = {
-_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
-_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
-_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
-_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
-_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
-_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
-_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
-_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
-_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
-_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
-_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
-_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
-_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
-_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
-_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
-_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
-_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */
-_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
-_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */
-_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */
-_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */
-_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
-
-/**
- * rand - Returns a pseudo random number
- */
-
-static unsigned int randseed;
-unsigned int rand(void)
-{
- randseed = 129 * randseed + 907633385;
- return randseed;
-}
-
-void srand(unsigned int seed)
-{
- randseed = seed;
-}
-
-void abort(void)
-{
- printf("Aborted.");
- while(1);
-}
+++ /dev/null
-INCLUDE generated/output_format.ld
-ENTRY(_start)
-
-__DYNAMIC = 0;
-
-INCLUDE generated/regions.ld
-
-SECTIONS
-{
- .text :
- {
- _ftext = .;
- *(.text .stub .text.* .gnu.linkonce.t.*)
- _etext = .;
- } > main_ram
-
- .got :
- {
- _GLOBAL_OFFSET_TABLE_ = .;
- *(.got)
- } > main_ram
-
- .got.plt :
- {
- *(.got.plt)
- } > main_ram
-
- .rodata :
- {
- . = ALIGN(4);
- _frodata = .;
- *(.rodata .rodata.* .gnu.linkonce.r.*)
- *(.rodata1)
- _erodata = .;
- } > main_ram
-
- .data :
- {
- . = ALIGN(4);
- _fdata = .;
- *(.data .data.* .gnu.linkonce.d.*)
- *(.data1)
- *(.sdata .sdata.* .gnu.linkonce.s.*)
- _edata = .;
- } > main_ram
-
- .bss :
- {
- . = ALIGN(4);
- _fbss = .;
- *(.dynsbss)
- *(.sbss .sbss.* .gnu.linkonce.sb.*)
- *(.scommon)
- *(.dynbss)
- *(.bss .bss.* .gnu.linkonce.b.*)
- *(COMMON)
- . = ALIGN(4);
- _ebss = .;
- . = ALIGN(8);
- _heapstart = .;
- } > main_ram
-}
-
-PROVIDE(_fstack = ORIGIN(main_ram) + LENGTH(main_ram) - 4);
+++ /dev/null
-/****************************************************************************
- * lib/stdlib/lib_qsort.c
- *
- * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
- * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
- *
- * Leveraged from:
- *
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- ****************************************************************************/
-
-#include <stdlib.h>
-
-#define min(a, b) (a) < (b) ? a : b
-
-#define swapcode(TYPE, parmi, parmj, n) \
- { \
- long i = (n) / sizeof (TYPE); \
- register TYPE *pi = (TYPE *) (parmi); \
- register TYPE *pj = (TYPE *) (parmj); \
- do { \
- register TYPE t = *pi; \
- *pi++ = *pj; \
- *pj++ = t; \
- } while (--i > 0); \
- }
-
-#define SWAPINIT(a, size) \
- swaptype = ((char *)a - (char *)0) % sizeof(long) || \
- size % sizeof(long) ? 2 : size == sizeof(long)? 0 : 1;
-
-#define swap(a, b) \
- if (swaptype == 0) \
- { \
- long t = *(long *)(a); \
- *(long *)(a) = *(long *)(b); \
- *(long *)(b) = t; \
- } \
- else \
- { \
- swapfunc(a, b, size, swaptype); \
- }
-
-#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
-
-static inline void swapfunc(char *a, char *b, int n, int swaptype);
-static inline char *med3(char *a, char *b, char *c,
- int (*compar)(const void *, const void *));
-
-static inline void swapfunc(char *a, char *b, int n, int swaptype)
-{
- if(swaptype <= 1)
- {
- swapcode(long, a, b, n)
- }
- else
- {
- swapcode(char, a, b, n)
- }
-}
-
-static inline char *med3(char *a, char *b, char *c,
- int (*compar)(const void *, const void *))
-{
- return compar(a, b) < 0 ?
- (compar(b, c) < 0 ? b : (compar(a, c) < 0 ? c : a ))
- :(compar(b, c) > 0 ? b : (compar(a, c) < 0 ? a : c ));
-}
-
-/****************************************************************************
- * Name: qsort
- *
- * Description:
- * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
- *
- ****************************************************************************/
-
-void qsort(void *base, size_t nmemb, size_t size,
- int(*compar)(const void *, const void *))
-{
- char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
- int d, r, swaptype, swap_cnt;
-
-loop:
- SWAPINIT(base, size);
- swap_cnt = 0;
- if (nmemb < 7)
- {
- for (pm = (char *) base + size; pm < (char *) base + nmemb * size; pm += size)
- {
- for (pl = pm; pl > (char *) base && compar(pl - size, pl) > 0; pl -= size)
- {
- swap(pl, pl - size);
- }
- }
- return;
- }
-
- pm = (char *) base + (nmemb / 2) * size;
- if (nmemb > 7)
- {
- pl = base;
- pn = (char *) base + (nmemb - 1) * size;
- if (nmemb > 40)
- {
- d = (nmemb / 8) * size;
- pl = med3(pl, pl + d, pl + 2 * d, compar);
- pm = med3(pm - d, pm, pm + d, compar);
- pn = med3(pn - 2 * d, pn - d, pn, compar);
- }
- pm = med3(pl, pm, pn, compar);
- }
- swap(base, pm);
- pa = pb = (char *) base + size;
-
- pc = pd = (char *) base + (nmemb - 1) * size;
- for (;;)
- {
- while (pb <= pc && (r = compar(pb, base)) <= 0)
- {
- if (r == 0)
- {
- swap_cnt = 1;
- swap(pa, pb);
- pa += size;
- }
- pb += size;
- }
- while (pb <= pc && (r = compar(pc, base)) >= 0)
- {
- if (r == 0)
- {
- swap_cnt = 1;
- swap(pc, pd);
- pd -= size;
- }
- pc -= size;
- }
-
- if (pb > pc)
- {
- break;
- }
-
- swap(pb, pc);
- swap_cnt = 1;
- pb += size;
- pc -= size;
- }
-
- if (swap_cnt == 0)
- {
- /* Switch to insertion sort */
-
- for (pm = (char *) base + size; pm < (char *) base + nmemb * size; pm += size)
- {
- for (pl = pm; pl > (char *) base && compar(pl - size, pl) > 0; pl -= size)
- {
- swap(pl, pl - size);
- }
- }
- return;
- }
-
- pn = (char *) base + nmemb * size;
- r = min(pa - (char *)base, pb - pa);
- vecswap(base, pb - r, r);
- r = min(pd - pc, pn - pd - size);
- vecswap(pb, pn - r, r);
-
- if ((r = pb - pa) > size)
- {
- qsort(base, r / size, size, compar);
- }
-
- if ((r = pd - pc) > size)
- {
- /* Iterate rather than recurse to save stack space */
- base = pn - r;
- nmemb = r / size;
- goto loop;
- }
-}
-
+++ /dev/null
-#include <generated/csr.h>
-
-#if (defined CSR_SPIFLASH_BASE && defined SPIFLASH_PAGE_SIZE)
-
-#include <spiflash.h>
-
-#define PAGE_PROGRAM_CMD 0x02
-#define WRDI_CMD 0x04
-#define RDSR_CMD 0x05
-#define WREN_CMD 0x06
-#define SE_CMD 0xd8
-
-#define BITBANG_CLK (1 << 1)
-#define BITBANG_CS_N (1 << 2)
-#define BITBANG_DQ_INPUT (1 << 3)
-
-#define SR_WIP 1
-
-static void flash_write_byte(unsigned char b);
-static void flash_write_addr(unsigned int addr);
-static void wait_for_device_ready(void);
-
-#define min(a,b) (a>b?b:a)
-
-static void flash_write_byte(unsigned char b)
-{
- int i;
- spiflash_bitbang_write(0); // ~CS_N ~CLK
-
- for(i = 0; i < 8; i++, b <<= 1) {
-
- spiflash_bitbang_write((b & 0x80) >> 7);
- spiflash_bitbang_write(((b & 0x80) >> 7) | BITBANG_CLK);
- }
-
- spiflash_bitbang_write(0); // ~CS_N ~CLK
-
-}
-
-static void flash_write_addr(unsigned int addr)
-{
- int i;
- spiflash_bitbang_write(0);
-
- for(i = 0; i < 24; i++, addr <<= 1) {
- spiflash_bitbang_write((addr & 0x800000) >> 23);
- spiflash_bitbang_write(((addr & 0x800000) >> 23) | BITBANG_CLK);
- }
-
- spiflash_bitbang_write(0);
-}
-
-static void wait_for_device_ready(void)
-{
- unsigned char sr;
- unsigned char i;
- do {
- sr = 0;
- flash_write_byte(RDSR_CMD);
- spiflash_bitbang_write(BITBANG_DQ_INPUT);
- for(i = 0; i < 8; i++) {
- sr <<= 1;
- spiflash_bitbang_write(BITBANG_CLK | BITBANG_DQ_INPUT);
- sr |= spiflash_miso_read();
- spiflash_bitbang_write(0 | BITBANG_DQ_INPUT);
- }
- spiflash_bitbang_write(0);
- spiflash_bitbang_write(BITBANG_CS_N);
- } while(sr & SR_WIP);
-}
-
-void erase_flash_sector(unsigned int addr)
-{
- unsigned int sector_addr = addr & ~(SPIFLASH_SECTOR_SIZE - 1);
-
- spiflash_bitbang_en_write(1);
-
- wait_for_device_ready();
-
- flash_write_byte(WREN_CMD);
- spiflash_bitbang_write(BITBANG_CS_N);
-
- flash_write_byte(SE_CMD);
- flash_write_addr(sector_addr);
- spiflash_bitbang_write(BITBANG_CS_N);
-
- wait_for_device_ready();
-
- spiflash_bitbang_en_write(0);
-}
-
-void write_to_flash_page(unsigned int addr, const unsigned char *c, unsigned int len)
-{
- unsigned int i;
-
- if(len > SPIFLASH_PAGE_SIZE)
- len = SPIFLASH_PAGE_SIZE;
-
- spiflash_bitbang_en_write(1);
-
- wait_for_device_ready();
-
- flash_write_byte(WREN_CMD);
- spiflash_bitbang_write(BITBANG_CS_N);
- flash_write_byte(PAGE_PROGRAM_CMD);
- flash_write_addr((unsigned int)addr);
- for(i = 0; i < len; i++)
- flash_write_byte(*c++);
-
- spiflash_bitbang_write(BITBANG_CS_N);
- spiflash_bitbang_write(0);
-
- wait_for_device_ready();
-
- spiflash_bitbang_en_write(0);
-}
-
-#define SPIFLASH_PAGE_MASK (SPIFLASH_PAGE_SIZE - 1)
-
-void write_to_flash(unsigned int addr, const unsigned char *c, unsigned int len)
-{
- unsigned int written = 0;
-
- if(addr & SPIFLASH_PAGE_MASK) {
- written = min(SPIFLASH_PAGE_SIZE - (addr & SPIFLASH_PAGE_MASK), len);
- write_to_flash_page(addr, c, written);
- c += written;
- addr += written;
- len -= written;
- }
-
- while(len > 0) {
- written = min(len, SPIFLASH_PAGE_SIZE);
- write_to_flash_page(addr, c, written);
- c += written;
- addr += written;
- len -= written;
- }
-}
-
-#endif /* CSR_SPIFLASH_BASE && SPIFLASH_PAGE_SIZE */
+++ /dev/null
-/****************************************************************************
- * lib/string/lib_strtod.c
- * Convert string to double
- *
- * Copyright (C) 2002 Michael Ringgaard. All rights reserved.
- * Copyright (C) 2006-2007 H. Peter Anvin.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- ****************************************************************************/
-
-/****************************************************************************
- * Included Files
- ****************************************************************************/
-
-#include <stdlib.h>
-#include <ctype.h>
-#include <errno.h>
-
-/****************************************************************************
- * Pre-processor definitions
- ****************************************************************************/
-
-/* These are predefined with GCC, but could be issues for other compilers. If
- * not defined, an arbitrary big number is put in for now. These should be
- * added to nuttx/compiler for your compiler.
- */
-
-#if !defined(__DBL_MIN_EXP__) || !defined(__DBL_MAX_EXP__)
-# ifdef CONFIG_CPP_HAVE_WARNING
-# warning "Size of exponent is unknown"
-# endif
-# undef __DBL_MIN_EXP__
-# define __DBL_MIN_EXP__ (-1021)
-# undef __DBL_MAX_EXP__
-# define __DBL_MAX_EXP__ (1024)
-#endif
-
-/****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-static inline int is_real(double x)
-{
- const double infinite = 1.0/0.0;
- return (x < infinite) && (x >= -infinite);
-}
-
-/****************************************************************************
- * Public Functions
- ****************************************************************************/
-
-/***************************************************(************************
- * Name: strtod
- *
- * Description:
- * Convert a string to a double value
- *
- ****************************************************************************/
-
-double strtod(const char *str, char **endptr)
-{
- double number;
- int exponent;
- int negative;
- char *p = (char *) str;
- double p10;
- int n;
- int num_digits;
- int num_decimals;
- const double infinite = 1.0/0.0;
-
- /* Skip leading whitespace */
-
- while (isspace(*p))
- {
- p++;
- }
-
- /* Handle optional sign */
-
- negative = 0;
- switch (*p)
- {
- case '-':
- negative = 1; /* Fall through to increment position */
- case '+':
- p++;
- }
-
- number = 0.;
- exponent = 0;
- num_digits = 0;
- num_decimals = 0;
-
- /* Process string of digits */
-
- while (isdigit(*p))
- {
- number = number * 10. + (*p - '0');
- p++;
- num_digits++;
- }
-
- /* Process decimal part */
-
- if (*p == '.')
- {
- p++;
-
- while (isdigit(*p))
- {
- number = number * 10. + (*p - '0');
- p++;
- num_digits++;
- num_decimals++;
- }
-
- exponent -= num_decimals;
- }
-
- if (num_digits == 0)
- {
- errno = ERANGE;
- return 0.0;
- }
-
- /* Correct for sign */
-
- if (negative)
- {
- number = -number;
- }
-
- /* Process an exponent string */
-
- if (*p == 'e' || *p == 'E')
- {
- /* Handle optional sign */
-
- negative = 0;
- switch(*++p)
- {
- case '-':
- negative = 1; /* Fall through to increment pos */
- case '+':
- p++;
- }
-
- /* Process string of digits */
-
- n = 0;
- while (isdigit(*p))
- {
- n = n * 10 + (*p - '0');
- p++;
- }
-
- if (negative)
- {
- exponent -= n;
- }
- else
- {
- exponent += n;
- }
- }
-
- if (exponent < __DBL_MIN_EXP__ ||
- exponent > __DBL_MAX_EXP__)
- {
- errno = ERANGE;
- return infinite;
- }
-
- /* Scale the result */
-
- p10 = 10.;
- n = exponent;
- if (n < 0) n = -n;
- while (n)
- {
- if (n & 1)
- {
- if (exponent < 0)
- {
- number /= p10;
- }
- else
- {
- number *= p10;
- }
- }
- n >>= 1;
- p10 *= p10;
- }
-
- if (!is_real(number))
- {
- errno = ERANGE;
- }
-
- if (endptr)
- {
- *endptr = p;
- }
-
- return number;
-}
-
+++ /dev/null
-#include <irq.h>
-#include <uart.h>
-#ifdef __or1k__
-#include <spr-defs.h>
-#endif
-
-#include <system.h>
-#include <generated/mem.h>
-#include <generated/csr.h>
-
-void flush_cpu_icache(void)
-{
-#if defined (__lm32__)
- asm volatile(
- "wcsr ICC, r0\n"
- "nop\n"
- "nop\n"
- "nop\n"
- "nop\n"
- );
-#elif defined (__or1k__)
- unsigned long iccfgr;
- unsigned long cache_set_size;
- unsigned long cache_ways;
- unsigned long cache_block_size;
- unsigned long cache_size;
- int i;
-
- iccfgr = mfspr(SPR_ICCFGR);
- cache_ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
- cache_set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
- cache_block_size = (iccfgr & SPR_ICCFGR_CBS) ? 32 : 16;
- cache_size = cache_set_size * cache_ways * cache_block_size;
-
- for (i = 0; i < cache_size; i += cache_block_size)
- mtspr(SPR_ICBIR, i);
-#else
-#error Unsupported architecture
-#endif
-}
-
-void flush_cpu_dcache(void)
-{
-#if defined (__lm32__)
- asm volatile(
- "wcsr DCC, r0\n"
- "nop\n"
- );
-#elif defined (__or1k__)
- unsigned long dccfgr;
- unsigned long cache_set_size;
- unsigned long cache_ways;
- unsigned long cache_block_size;
- unsigned long cache_size;
- int i;
-
- dccfgr = mfspr(SPR_DCCFGR);
- cache_ways = 1 << (dccfgr & SPR_ICCFGR_NCW);
- cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3);
- cache_block_size = (dccfgr & SPR_DCCFGR_CBS) ? 32 : 16;
- cache_size = cache_set_size * cache_ways * cache_block_size;
-
- for (i = 0; i < cache_size; i += cache_block_size)
- mtspr(SPR_DCBIR, i);
-#else
-#error Unsupported architecture
-#endif
-}
-
-#ifdef L2_SIZE
-void flush_l2_cache(void)
-{
- unsigned int i;
- register unsigned int addr;
- register unsigned int dummy;
-
- for(i=0;i<2*L2_SIZE/4;i++) {
- addr = MAIN_RAM_BASE + i*4;
-#if defined (__lm32__)
- __asm__ volatile("lw %0, (%1+0)\n":"=r"(dummy):"r"(addr));
-#elif defined (__or1k__)
- __asm__ volatile("l.lwz %0, 0(%1)\n":"=r"(dummy):"r"(addr));
-#else
-#error Unsupported architecture
-#endif
- }
-}
-#endif
+++ /dev/null
-#include <generated/csr.h>
-#include <time.h>
-
-void time_init(void)
-{
- int t;
-
- timer0_en_write(0);
- t = 2*identifier_frequency_read();
- timer0_reload_write(t);
- timer0_load_write(t);
- timer0_en_write(1);
-}
-
-int elapsed(int *last_event, int period)
-{
- int t, dt;
-
- timer0_update_value_write(1);
- t = timer0_reload_read() - timer0_value_read();
- if(period < 0) {
- *last_event = t;
- return 1;
- }
- dt = t - *last_event;
- if(dt < 0)
- dt += timer0_reload_read();
- if((dt > period) || (dt < 0)) {
- *last_event = t;
- return 1;
- } else
- return 0;
-}
+++ /dev/null
-#include <uart.h>
-#include <irq.h>
-#include <generated/csr.h>
-#include <hw/flags.h>
-
-/*
- * Buffer sizes must be a power of 2 so that modulos can be computed
- * with logical AND.
- */
-
-#define UART_RINGBUFFER_SIZE_RX 128
-#define UART_RINGBUFFER_MASK_RX (UART_RINGBUFFER_SIZE_RX-1)
-
-static char rx_buf[UART_RINGBUFFER_SIZE_RX];
-static volatile unsigned int rx_produce;
-static unsigned int rx_consume;
-
-#define UART_RINGBUFFER_SIZE_TX 128
-#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1)
-
-static char tx_buf[UART_RINGBUFFER_SIZE_TX];
-static unsigned int tx_produce;
-static volatile unsigned int tx_consume;
-
-void uart_isr(void)
-{
- unsigned int stat, rx_produce_next;
-
- stat = uart_ev_pending_read();
-
- if(stat & UART_EV_RX) {
- while(!uart_rxempty_read()) {
- rx_produce_next = (rx_produce + 1) & UART_RINGBUFFER_MASK_RX;
- if(rx_produce_next != rx_consume) {
- rx_buf[rx_produce] = uart_rxtx_read();
- rx_produce = rx_produce_next;
- }
- uart_ev_pending_write(UART_EV_RX);
- }
- }
-
- if(stat & UART_EV_TX) {
- uart_ev_pending_write(UART_EV_TX);
- while((tx_consume != tx_produce) && !uart_txfull_read()) {
- uart_rxtx_write(tx_buf[tx_consume]);
- tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX;
- }
- }
-}
-
-/* Do not use in interrupt handlers! */
-char uart_read(void)
-{
- char c;
-
- if(irq_getie()) {
- while(rx_consume == rx_produce);
- } else if (rx_consume == rx_produce) {
- return 0;
- }
-
- c = rx_buf[rx_consume];
- rx_consume = (rx_consume + 1) & UART_RINGBUFFER_MASK_RX;
- return c;
-}
-
-int uart_read_nonblock(void)
-{
- return (rx_consume != rx_produce);
-}
-
-void uart_write(char c)
-{
- unsigned int oldmask;
- unsigned int tx_produce_next = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX;
-
- if(irq_getie()) {
- while(tx_produce_next == tx_consume);
- } else if(tx_produce_next == tx_consume) {
- return;
- }
-
- oldmask = irq_getmask();
- irq_setmask(oldmask & ~(1 << UART_INTERRUPT));
- if((tx_consume != tx_produce) || uart_txfull_read()) {
- tx_buf[tx_produce] = c;
- tx_produce = tx_produce_next;
- } else {
- uart_rxtx_write(c);
- }
- irq_setmask(oldmask);
-}
-
-void uart_init(void)
-{
- rx_produce = 0;
- rx_consume = 0;
-
- tx_produce = 0;
- tx_consume = 0;
-
- uart_ev_pending_write(uart_ev_pending_read());
- uart_ev_enable_write(UART_EV_TX | UART_EV_RX);
- irq_setmask(irq_getmask() | (1 << UART_INTERRUPT));
-}
-
-void uart_sync(void)
-{
- while(tx_consume != tx_produce);
-}
+++ /dev/null
-/*
- * MiSoC
- * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
- * Copyright (C) Linux kernel developers
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 3 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <ctype.h>
-
-/**
- * vsnprintf - Format a string and place it in a buffer
- * @buf: The buffer to place the result into
- * @size: The size of the buffer, including the trailing null space
- * @fmt: The format string to use
- * @args: Arguments for the format string
- *
- * The return value is the number of characters which would
- * be generated for the given input, excluding the trailing
- * '\0', as per ISO C99. If you want to have the exact
- * number of characters written into @buf as return value
- * (not including the trailing '\0'), use vscnprintf(). If the
- * return is greater than or equal to @size, the resulting
- * string is truncated.
- *
- * Call this function if you are already dealing with a va_list.
- * You probably want snprintf() instead.
- */
-int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
-{
- int len;
- unsigned long long num;
- int i, base;
- char *str, *end, c;
- const char *s;
-
- int flags; /* flags to number() */
-
- int field_width; /* width of output field */
- int precision; /* min. # of digits for integers; max
- number of chars for from string */
- int qualifier; /* 'h', 'l', or 'L' for integer fields */
- /* 'z' support added 23/7/1999 S.H. */
- /* 'z' changed to 'Z' --davidm 1/25/99 */
- /* 't' added for ptrdiff_t */
-
- /* Reject out-of-range values early. Large positive sizes are
- used for unknown buffer sizes. */
- if (unlikely((int) size < 0))
- return 0;
-
- str = buf;
- end = buf + size;
-
- /* Make sure end is always >= buf */
- if (end < buf) {
- end = ((void *)-1);
- size = end - buf;
- }
-
- for (; *fmt ; ++fmt) {
- if (*fmt != '%') {
- if (str < end)
- *str = *fmt;
- ++str;
- continue;
- }
-
- /* process flags */
- flags = 0;
- repeat:
- ++fmt; /* this also skips first '%' */
- switch (*fmt) {
- case '-': flags |= PRINTF_LEFT; goto repeat;
- case '+': flags |= PRINTF_PLUS; goto repeat;
- case ' ': flags |= PRINTF_SPACE; goto repeat;
- case '#': flags |= PRINTF_SPECIAL; goto repeat;
- case '0': flags |= PRINTF_ZEROPAD; goto repeat;
- }
-
- /* get field width */
- field_width = -1;
- if (isdigit(*fmt))
- field_width = skip_atoi(&fmt);
- else if (*fmt == '*') {
- ++fmt;
- /* it's the next argument */
- field_width = va_arg(args, int);
- if (field_width < 0) {
- field_width = -field_width;
- flags |= PRINTF_LEFT;
- }
- }
-
- /* get the precision */
- precision = -1;
- if (*fmt == '.') {
- ++fmt;
- if (isdigit(*fmt))
- precision = skip_atoi(&fmt);
- else if (*fmt == '*') {
- ++fmt;
- /* it's the next argument */
- precision = va_arg(args, int);
- }
- if (precision < 0)
- precision = 0;
- }
-
- /* get the conversion qualifier */
- qualifier = -1;
- if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
- *fmt =='Z' || *fmt == 'z' || *fmt == 't') {
- qualifier = *fmt;
- ++fmt;
- if (qualifier == 'l' && *fmt == 'l') {
- qualifier = 'L';
- ++fmt;
- }
- }
-
- /* default base */
- base = 10;
-
- switch (*fmt) {
- case 'c':
- if (!(flags & PRINTF_LEFT)) {
- while (--field_width > 0) {
- if (str < end)
- *str = ' ';
- ++str;
- }
- }
- c = (unsigned char) va_arg(args, int);
- if (str < end)
- *str = c;
- ++str;
- while (--field_width > 0) {
- if (str < end)
- *str = ' ';
- ++str;
- }
- continue;
-
- case 's':
- s = va_arg(args, char *);
- if (s == NULL)
- s = "<NULL>";
-
- len = strnlen(s, precision);
-
- if (!(flags & PRINTF_LEFT)) {
- while (len < field_width--) {
- if (str < end)
- *str = ' ';
- ++str;
- }
- }
- for (i = 0; i < len; ++i) {
- if (str < end)
- *str = *s;
- ++str; ++s;
- }
- while (len < field_width--) {
- if (str < end)
- *str = ' ';
- ++str;
- }
- continue;
-
- case 'p':
- if (field_width == -1) {
- field_width = 2*sizeof(void *);
- flags |= PRINTF_ZEROPAD;
- }
- str = number(str, end,
- (unsigned long) va_arg(args, void *),
- 16, field_width, precision, flags);
- continue;
-
-#ifndef NO_FLOAT
- case 'g':
- case 'f': {
- int m;
- double f;
- int integer;
-
- f = va_arg(args, double);
- if(f < 0.0) {
- *str = '-';
- str++;
- f = -f;
- }
-
- integer = f;
- if(integer > 0) {
- m = 1;
- while(integer > (m*10)) m *= 10;
- while((m >= 1) && (str < end)) {
- int n;
- n = integer/m;
- *str = '0' + n;
- str++;
- f = f - m*n;
- integer = integer - m*n;
- m /= 10;
- }
- } else if(str < end) {
- *str = '0';
- str++;
- }
-
- if(str < end) {
- *str = '.';
- str++;
- }
-
- for(i=0;i<6;i++) {
- int n;
-
- f = f*10.0;
- n = f;
- f = f - n;
- if(str >= end) break;
- *str = '0' + n;
- str++;
- }
-
- continue;
- }
-#endif
-
- case 'n':
- /* FIXME:
- * What does C99 say about the overflow case here? */
- if (qualifier == 'l') {
- long * ip = va_arg(args, long *);
- *ip = (str - buf);
- } else if (qualifier == 'Z' || qualifier == 'z') {
- size_t * ip = va_arg(args, size_t *);
- *ip = (str - buf);
- } else {
- int * ip = va_arg(args, int *);
- *ip = (str - buf);
- }
- continue;
-
- case '%':
- if (str < end)
- *str = '%';
- ++str;
- continue;
-
- /* integer number formats - set up the flags and "break" */
- case 'o':
- base = 8;
- break;
-
- case 'X':
- flags |= PRINTF_LARGE;
- case 'x':
- base = 16;
- break;
-
- case 'd':
- case 'i':
- flags |= PRINTF_SIGN;
- case 'u':
- break;
-
- default:
- if (str < end)
- *str = '%';
- ++str;
- if (*fmt) {
- if (str < end)
- *str = *fmt;
- ++str;
- } else {
- --fmt;
- }
- continue;
- }
- if (qualifier == 'L')
- num = va_arg(args, long long);
- else if (qualifier == 'l') {
- num = va_arg(args, unsigned long);
- if (flags & PRINTF_SIGN)
- num = (signed long) num;
- } else if (qualifier == 'Z' || qualifier == 'z') {
- num = va_arg(args, size_t);
- } else if (qualifier == 't') {
- num = va_arg(args, ptrdiff_t);
- } else if (qualifier == 'h') {
- num = (unsigned short) va_arg(args, int);
- if (flags & PRINTF_SIGN)
- num = (signed short) num;
- } else {
- num = va_arg(args, unsigned int);
- if (flags & PRINTF_SIGN)
- num = (signed int) num;
- }
- str = number(str, end, num, base,
- field_width, precision, flags);
- }
- if (size > 0) {
- if (str < end)
- *str = '\0';
- else
- end[-1] = '\0';
- }
- /* the trailing null byte doesn't count towards the total */
- return str-buf;
-}
+++ /dev/null
-include ../include/generated/variables.mak
-include $(MISOC_DIRECTORY)/software/common.mak
-
-CFLAGS+=-D_YUGA_LITTLE_ENDIAN=0 -D_YUGA_BIG_ENDIAN=1 -Wno-missing-prototypes
-
-OBJECTS=divsi3.o modsi3.o comparesf2.o comparedf2.o negsf2.o negdf2.o addsf3.o subsf3.o mulsf3.o divsf3.o lshrdi3.o muldi3.o divdi3.o ashldi3.o ashrdi3.o udivmoddi4.o \
- floatsisf.o floatunsisf.o fixsfsi.o fixdfdi.o fixunssfsi.o fixunsdfdi.o adddf3.o subdf3.o muldf3.o divdf3.o floatsidf.o floatunsidf.o floatdidf.o fixdfsi.o fixunsdfsi.o \
- clzsi2.o ctzsi2.o udivdi3.o umoddi3.o moddi3.o ucmpdi2.o
-
-all: libcompiler_rt.a
-
-libcompiler_rt.a: $(OBJECTS)
- $(AR) crs libcompiler_rt.a $(OBJECTS)
-
-%.o: $(MISOC_DIRECTORY)/software/compiler_rt/lib/builtins/%.c
- $(compile)
-
-.PHONY: all clean
-
-clean:
- $(RM) $(OBJECTS) $(OBJECTS:.o=.ts) $(OBJECTS:.o=.d) libcompiler_rt.a .*~ *~
+++ /dev/null
-include ../include/generated/variables.mak
-include $(MISOC_DIRECTORY)/software/common.mak
-
-# lm32 is not supported
-ifeq ($(CPU),lm32)
- ALL_TARGET=
-else
- ALL_TARGET=libdyld.a
-endif
-
-COMMONFLAGS += -I$(MISOC_DIRECTORY)/software/include/dyld
-
-OBJECTS=dyld.o
-
-all: $(ALL_TARGET)
-
-libdyld.a: $(OBJECTS)
- $(AR) crs libdyld.a $(OBJECTS)
-
-%.o: $(LIBDYLD_DIRECTORY)/%.c
- $(compile)
-
-.PHONY: all clean
-
-clean:
- $(RM) $(OBJECTS) libdyld.a .*~ *~
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <dyld.h>
-
-static int fixup_rela(struct dyld_info *info, const Elf32_Rela *rela,
- Elf32_Addr (*resolve_import)(const char *),
- const char **error_out)
-{
- const Elf32_Sym *sym = NULL;
- if(ELF32_R_SYM(rela->r_info) != 0)
- sym = &info->symtab[ELF32_R_SYM(rela->r_info)];
- Elf32_Addr value;
-
- switch(ELF32_R_TYPE(rela->r_info)) {
- case R_OR1K_NONE:
- return 1; // Does nothing.
-
- case R_OR1K_RELATIVE:
- value = info->base + rela->r_addend;
- break;
-
- case R_OR1K_32:
- case R_OR1K_GLOB_DAT:
- case R_OR1K_JMP_SLOT:
- value = (Elf32_Addr)dyld_lookup(&info->strtab[sym->st_name], info);
- if(value != 0)
- break;
-
- value = resolve_import(&info->strtab[sym->st_name]);
- if(value == 0) {
- static char error[256];
- snprintf(error, sizeof(error),
- "ELF object has an unresolved symbol: %s",
- &info->strtab[sym->st_name]);
- *error_out = error;
- return 0;
- }
- break;
-
- default:
- *error_out = "ELF object uses an unsupported relocation type";
- return 0;
- }
-
- memcpy((Elf32_Addr*)(info->base + rela->r_offset), &value,
- sizeof(Elf32_Addr));
-
- return 1;
-}
-
-int dyld_load(const void *shlib, Elf32_Addr base,
- Elf32_Addr (*resolve_import)(const char *),
- struct dyld_info *info, const char **error_out)
-{
- const Elf32_Ehdr *ehdr = (const Elf32_Ehdr *)shlib;
-
- const unsigned char expected_ident[EI_NIDENT] = {
- ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
- ELFCLASS32, ELFDATA2MSB, EV_CURRENT,
- ELFOSABI_NONE, /* ABI version */ 0
- };
- if(memcmp(ehdr->e_ident, expected_ident, EI_NIDENT) ||
- ehdr->e_type != ET_DYN) {
- *error_out = "ELF object is not a shared library";
- return 0;
- }
-
-#ifdef __or1k__
- if(ehdr->e_machine != EM_OPENRISC) {
- *error_out = "ELF object does not contain OpenRISC machine code";
- return 0;
- }
-#else
-#error Unsupported architecture
-#endif
-
- const Elf32_Phdr *phdr = (const Elf32_Phdr *)((intptr_t)shlib + ehdr->e_phoff);
- const Elf32_Dyn *dyn = NULL;
- for(int i = 0; i < ehdr->e_phnum; i++) {
- if(phdr[i].p_type == PT_DYNAMIC)
- dyn = (const Elf32_Dyn *)((intptr_t)shlib + phdr[i].p_offset);
-
- memcpy((void*)(base + phdr[i].p_vaddr),
- (const void*)((intptr_t)shlib + phdr[i].p_offset),
- phdr[i].p_filesz);
- }
-
- if(dyn == NULL) {
- *error_out = "ELF object does not have a PT_DYNAMIC header";
- return 0;
- }
-
- const char *strtab = NULL;
- const Elf32_Sym *symtab = NULL;
- const Elf32_Rela *rela = NULL, *pltrel = NULL;
- const Elf32_Word *hash = NULL;
- Elf32_Word init = 0;
- size_t syment = sizeof(Elf32_Sym), relaent = sizeof(Elf32_Rela),
- relanum = 0, pltrelnum = 0;
- while(dyn->d_tag != DT_NULL) {
- switch(dyn->d_tag) {
- case DT_STRTAB: strtab = (const char *)(base + dyn->d_un.d_ptr); break;
- case DT_SYMTAB: symtab = (const Elf32_Sym *)(base + dyn->d_un.d_ptr); break;
- case DT_SYMENT: syment = dyn->d_un.d_val; break;
- case DT_RELA: rela = (const Elf32_Rela *)(base + dyn->d_un.d_ptr); break;
- case DT_RELAENT: relaent = dyn->d_un.d_val; break;
- case DT_RELASZ: relanum = dyn->d_un.d_val / sizeof(Elf32_Rela); break;
- case DT_JMPREL: pltrel = (const Elf32_Rela *)(base + dyn->d_un.d_ptr); break;
- case DT_PLTRELSZ: pltrelnum = dyn->d_un.d_val / sizeof(Elf32_Rela); break;
- case DT_HASH: hash = (const Elf32_Word *)(base + dyn->d_un.d_ptr); break;
- case DT_INIT: init = dyn->d_un.d_val; break;
-
- case DT_REL:
- *error_out = "ELF object uses Rel relocations, which are not supported";
- return 0;
- }
-
- ++dyn;
- }
-
- if(symtab == NULL || syment == 0 || strtab == NULL) {
- *error_out = "ELF object must contain a symbol table";
- return 0;
- }
-
- if(syment != sizeof(Elf32_Sym) || relaent != sizeof(Elf32_Rela)) {
- *error_out = "ELF object uses an unknown format for symbols and relocations";
- return 0;
- }
-
- info->base = base;
- info->init = (void*)(base + init);
- info->strtab = strtab;
- info->symtab = symtab;
- info->hash.nbucket = hash[0];
- info->hash.nchain = hash[1];
- info->hash.bucket = &hash[2];
- info->hash.chain = &hash[2 + info->hash.nbucket];
-
- for(int i = 0; i < relanum; i++) {
- if(!fixup_rela(info, &rela[i], resolve_import, error_out))
- return 0;
- }
-
- for(int i = 0; i < pltrelnum; i++) {
- if(!fixup_rela(info, &pltrel[i], resolve_import, error_out))
- return 0;
- }
-
- return 1;
-}
-
-static unsigned long elf_hash(const unsigned char *name)
-{
- unsigned long h = 0, g;
- while(*name) {
- h = (h << 4) + *name++;
- if((g = h & 0xf0000000)) {
- h ^= g >> 24;
- h &= ~g;
- }
- }
- return h;
-}
-
-void *dyld_lookup(const char *symbol, struct dyld_info *info)
-{
- unsigned hash = elf_hash((const unsigned char*) symbol);
- unsigned index = info->hash.bucket[hash % info->hash.nbucket];
- while(strcmp(&info->strtab[info->symtab[index].st_name], symbol)) {
- if(index == STN_UNDEF)
- return NULL;
- index = info->hash.chain[index];
- }
-
- Elf32_Addr value = info->symtab[index].st_value;
- if(value != 0)
- return (void*)(info->base + value);
- else
- return NULL;
-}
+++ /dev/null
-include ../include/generated/variables.mak
-include $(MISOC_DIRECTORY)/software/common.mak
-
-OBJECTS=microudp.o tftp.o
-
-all: libnet.a
-
-libnet.a: $(OBJECTS)
- $(AR) crs libnet.a $(OBJECTS)
-
-%.o: $(LIBNET_DIRECTORY)/%.c
- $(compile)
-
-%.o: %.S
- $(assemble)
-
-.PHONY: all clean
-
-clean:
- $(RM) $(OBJECTS) libnet.a .*~ *~
+++ /dev/null
-#include <generated/csr.h>
-#ifdef CSR_ETHMAC_BASE
-
-#include <stdio.h>
-#include <system.h>
-#include <crc.h>
-#include <hw/flags.h>
-#include <hw/ethmac_mem.h>
-
-#include <net/microudp.h>
-
-#define ETHERTYPE_ARP 0x0806
-#define ETHERTYPE_IP 0x0800
-
-#ifdef CSR_ETHMAC_PREAMBLE_CRC_ADDR
-#define HW_PREAMBLE_CRC
-#endif
-
-struct ethernet_header {
-#ifndef HW_PREAMBLE_CRC
- unsigned char preamble[8];
-#endif
- unsigned char destmac[6];
- unsigned char srcmac[6];
- unsigned short ethertype;
-} __attribute__((packed));
-
-static void fill_eth_header(struct ethernet_header *h, const unsigned char *destmac, const unsigned char *srcmac, unsigned short ethertype)
-{
- int i;
-
-#ifndef HW_PREAMBLE_CRC
- for(i=0;i<7;i++)
- h->preamble[i] = 0x55;
- h->preamble[7] = 0xd5;
-#endif
- for(i=0;i<6;i++)
- h->destmac[i] = destmac[i];
- for(i=0;i<6;i++)
- h->srcmac[i] = srcmac[i];
- h->ethertype = ethertype;
-}
-
-#define ARP_HWTYPE_ETHERNET 0x0001
-#define ARP_PROTO_IP 0x0800
-#ifndef HW_PREAMBLE_CRC
-#define ARP_PACKET_LENGTH 68
-#else
-#define ARP_PACKET_LENGTH 60
-#endif
-
-#define ARP_OPCODE_REQUEST 0x0001
-#define ARP_OPCODE_REPLY 0x0002
-
-struct arp_frame {
- unsigned short hwtype;
- unsigned short proto;
- unsigned char hwsize;
- unsigned char protosize;
- unsigned short opcode;
- unsigned char sender_mac[6];
- unsigned int sender_ip;
- unsigned char target_mac[6];
- unsigned int target_ip;
- unsigned char padding[18];
-} __attribute__((packed));
-
-#define IP_IPV4 0x45
-#define IP_DONT_FRAGMENT 0x4000
-#define IP_TTL 64
-#define IP_PROTO_UDP 0x11
-
-struct ip_header {
- unsigned char version;
- unsigned char diff_services;
- unsigned short total_length;
- unsigned short identification;
- unsigned short fragment_offset;
- unsigned char ttl;
- unsigned char proto;
- unsigned short checksum;
- unsigned int src_ip;
- unsigned int dst_ip;
-} __attribute__((packed));
-
-struct udp_header {
- unsigned short src_port;
- unsigned short dst_port;
- unsigned short length;
- unsigned short checksum;
-} __attribute__((packed));
-
-struct udp_frame {
- struct ip_header ip;
- struct udp_header udp;
- char payload[];
-} __attribute__((packed));
-
-struct ethernet_frame {
- struct ethernet_header eth_header;
- union {
- struct arp_frame arp;
- struct udp_frame udp;
- } contents;
-} __attribute__((packed));
-
-typedef union {
- struct ethernet_frame frame;
- unsigned char raw[1532];
-} ethernet_buffer;
-
-
-static unsigned int rxslot;
-static unsigned int rxlen;
-static ethernet_buffer *rxbuffer;
-static ethernet_buffer *rxbuffer0;
-static ethernet_buffer *rxbuffer1;
-static unsigned int txslot;
-static unsigned int txlen;
-static ethernet_buffer *txbuffer;
-static ethernet_buffer *txbuffer0;
-static ethernet_buffer *txbuffer1;
-
-static void send_packet(void)
-{
-#ifndef HW_PREAMBLE_CRC
- unsigned int crc;
- crc = crc32(&txbuffer->raw[8], txlen-8);
- txbuffer->raw[txlen ] = (crc & 0xff);
- txbuffer->raw[txlen+1] = (crc & 0xff00) >> 8;
- txbuffer->raw[txlen+2] = (crc & 0xff0000) >> 16;
- txbuffer->raw[txlen+3] = (crc & 0xff000000) >> 24;
- txlen += 4;
-#endif
- ethmac_sram_reader_slot_write(txslot);
- ethmac_sram_reader_length_write(txlen);
- while(!(ethmac_sram_reader_ready_read()));
- ethmac_sram_reader_start_write(1);
- txslot = (txslot+1)%2;
- if (txslot)
- txbuffer = txbuffer1;
- else
- txbuffer = txbuffer0;
-}
-
-static unsigned char my_mac[6];
-static unsigned int my_ip;
-
-/* ARP cache - one entry only */
-static unsigned char cached_mac[6];
-static unsigned int cached_ip;
-
-static void process_arp(void)
-{
- const struct arp_frame *rx_arp = &rxbuffer->frame.contents.arp;
- struct arp_frame *tx_arp = &txbuffer->frame.contents.arp;
-
- if(rxlen < ARP_PACKET_LENGTH) return;
- if(rx_arp->hwtype != ARP_HWTYPE_ETHERNET) return;
- if(rx_arp->proto != ARP_PROTO_IP) return;
- if(rx_arp->hwsize != 6) return;
- if(rx_arp->protosize != 4) return;
- if(rx_arp->opcode == ARP_OPCODE_REPLY) {
- if(rx_arp->sender_ip == cached_ip) {
- int i;
- for(i=0;i<6;i++)
- cached_mac[i] = rx_arp->sender_mac[i];
- }
- return;
- }
- if(rx_arp->opcode == ARP_OPCODE_REQUEST) {
- if(rx_arp->target_ip == my_ip) {
- int i;
-
- fill_eth_header(&txbuffer->frame.eth_header,
- rx_arp->sender_mac,
- my_mac,
- ETHERTYPE_ARP);
- txlen = ARP_PACKET_LENGTH;
- tx_arp->hwtype = ARP_HWTYPE_ETHERNET;
- tx_arp->proto = ARP_PROTO_IP;
- tx_arp->hwsize = 6;
- tx_arp->protosize = 4;
- tx_arp->opcode = ARP_OPCODE_REPLY;
- tx_arp->sender_ip = my_ip;
- for(i=0;i<6;i++)
- tx_arp->sender_mac[i] = my_mac[i];
- tx_arp->target_ip = rx_arp->sender_ip;
- for(i=0;i<6;i++)
- tx_arp->target_mac[i] = rx_arp->sender_mac[i];
- send_packet();
- }
- return;
- }
-}
-
-static const unsigned char broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
-int microudp_arp_resolve(unsigned int ip)
-{
- struct arp_frame *arp = &txbuffer->frame.contents.arp;
- int i;
- int tries;
- int timeout;
-
- if(cached_ip == ip) {
- for(i=0;i<6;i++)
- if(cached_mac[i]) return 1;
- }
- cached_ip = ip;
- for(i=0;i<6;i++)
- cached_mac[i] = 0;
-
- for(tries=0;tries<5;tries++) {
- /* Send an ARP request */
- fill_eth_header(&txbuffer->frame.eth_header,
- broadcast,
- my_mac,
- ETHERTYPE_ARP);
- txlen = ARP_PACKET_LENGTH;
- arp->hwtype = ARP_HWTYPE_ETHERNET;
- arp->proto = ARP_PROTO_IP;
- arp->hwsize = 6;
- arp->protosize = 4;
- arp->opcode = ARP_OPCODE_REQUEST;
- arp->sender_ip = my_ip;
- for(i=0;i<6;i++)
- arp->sender_mac[i] = my_mac[i];
- arp->target_ip = ip;
- for(i=0;i<6;i++)
- arp->target_mac[i] = 0;
- send_packet();
-
- /* Do we get a reply ? */
- for(timeout=0;timeout<2000000;timeout++) {
- microudp_service();
- for(i=0;i<6;i++)
- if(cached_mac[i]) return 1;
- }
- }
-
- return 0;
-}
-
-static unsigned short ip_checksum(unsigned int r, void *buffer, unsigned int length, int complete)
-{
- unsigned char *ptr;
- unsigned int i;
-
- ptr = (unsigned char *)buffer;
- length >>= 1;
-
- for(i=0;i<length;i++)
- r += ((unsigned int)(ptr[2*i]) << 8)|(unsigned int)(ptr[2*i+1]) ;
-
- /* Add overflows */
- while(r >> 16)
- r = (r & 0xffff) + (r >> 16);
-
- if(complete) {
- r = ~r;
- r &= 0xffff;
- if(r == 0) r = 0xffff;
- }
- return r;
-}
-
-void *microudp_get_tx_buffer(void)
-{
- return txbuffer->frame.contents.udp.payload;
-}
-
-struct pseudo_header {
- unsigned int src_ip;
- unsigned int dst_ip;
- unsigned char zero;
- unsigned char proto;
- unsigned short length;
-} __attribute__((packed));
-
-int microudp_send(unsigned short src_port, unsigned short dst_port, unsigned int length)
-{
- struct pseudo_header h;
- unsigned int r;
-
- if((cached_mac[0] == 0) && (cached_mac[1] == 0) && (cached_mac[2] == 0)
- && (cached_mac[3] == 0) && (cached_mac[4] == 0) && (cached_mac[5] == 0))
- return 0;
-
- txlen = length + sizeof(struct ethernet_header) + sizeof(struct udp_frame);
- if(txlen < ARP_PACKET_LENGTH) txlen = ARP_PACKET_LENGTH;
-
- fill_eth_header(&txbuffer->frame.eth_header,
- cached_mac,
- my_mac,
- ETHERTYPE_IP);
-
- txbuffer->frame.contents.udp.ip.version = IP_IPV4;
- txbuffer->frame.contents.udp.ip.diff_services = 0;
- txbuffer->frame.contents.udp.ip.total_length = length + sizeof(struct udp_frame);
- txbuffer->frame.contents.udp.ip.identification = 0;
- txbuffer->frame.contents.udp.ip.fragment_offset = IP_DONT_FRAGMENT;
- txbuffer->frame.contents.udp.ip.ttl = IP_TTL;
- h.proto = txbuffer->frame.contents.udp.ip.proto = IP_PROTO_UDP;
- txbuffer->frame.contents.udp.ip.checksum = 0;
- h.src_ip = txbuffer->frame.contents.udp.ip.src_ip = my_ip;
- h.dst_ip = txbuffer->frame.contents.udp.ip.dst_ip = cached_ip;
- txbuffer->frame.contents.udp.ip.checksum = ip_checksum(0, &txbuffer->frame.contents.udp.ip,
- sizeof(struct ip_header), 1);
-
- txbuffer->frame.contents.udp.udp.src_port = src_port;
- txbuffer->frame.contents.udp.udp.dst_port = dst_port;
- h.length = txbuffer->frame.contents.udp.udp.length = length + sizeof(struct udp_header);
- txbuffer->frame.contents.udp.udp.checksum = 0;
-
- h.zero = 0;
- r = ip_checksum(0, &h, sizeof(struct pseudo_header), 0);
- if(length & 1) {
- txbuffer->frame.contents.udp.payload[length] = 0;
- length++;
- }
- r = ip_checksum(r, &txbuffer->frame.contents.udp.udp,
- sizeof(struct udp_header)+length, 1);
- txbuffer->frame.contents.udp.udp.checksum = r;
-
- send_packet();
-
- return 1;
-}
-
-static udp_callback rx_callback;
-
-static void process_ip(void)
-{
- if(rxlen < (sizeof(struct ethernet_header)+sizeof(struct udp_frame))) return;
- /* We don't verify UDP and IP checksums and rely on the Ethernet checksum solely */
- if(rxbuffer->frame.contents.udp.ip.version != IP_IPV4) return;
- // check disabled for QEMU compatibility
- //if(rxbuffer->frame.contents.udp.ip.diff_services != 0) return;
- if(rxbuffer->frame.contents.udp.ip.total_length < sizeof(struct udp_frame)) return;
- // check disabled for QEMU compatibility
- //if(rxbuffer->frame.contents.udp.ip.fragment_offset != IP_DONT_FRAGMENT) return;
- if(rxbuffer->frame.contents.udp.ip.proto != IP_PROTO_UDP) return;
- if(rxbuffer->frame.contents.udp.ip.dst_ip != my_ip) return;
- if(rxbuffer->frame.contents.udp.udp.length < sizeof(struct udp_header)) return;
-
- if(rx_callback)
- rx_callback(rxbuffer->frame.contents.udp.ip.src_ip, rxbuffer->frame.contents.udp.udp.src_port, rxbuffer->frame.contents.udp.udp.dst_port, rxbuffer->frame.contents.udp.payload, rxbuffer->frame.contents.udp.udp.length-sizeof(struct udp_header));
-}
-
-void microudp_set_callback(udp_callback callback)
-{
- rx_callback = callback;
-}
-
-static void process_frame(void)
-{
- flush_cpu_dcache();
-
-#ifndef HW_PREAMBLE_CRC
- int i;
- for(i=0;i<7;i++)
- if(rxbuffer->frame.eth_header.preamble[i] != 0x55) return;
- if(rxbuffer->frame.eth_header.preamble[7] != 0xd5) return;
-#endif
-
-#ifndef HW_PREAMBLE_CRC
- unsigned int received_crc;
- unsigned int computed_crc;
- received_crc = ((unsigned int)rxbuffer->raw[rxlen-1] << 24)
- |((unsigned int)rxbuffer->raw[rxlen-2] << 16)
- |((unsigned int)rxbuffer->raw[rxlen-3] << 8)
- |((unsigned int)rxbuffer->raw[rxlen-4]);
- computed_crc = crc32(&rxbuffer->raw[8], rxlen-12);
- if(received_crc != computed_crc) return;
-
- rxlen -= 4; /* strip CRC here to be consistent with TX */
-#endif
-
- if(rxbuffer->frame.eth_header.ethertype == ETHERTYPE_ARP) process_arp();
- else if(rxbuffer->frame.eth_header.ethertype == ETHERTYPE_IP) process_ip();
-}
-
-void microudp_start(const unsigned char *macaddr, unsigned int ip)
-{
- int i;
- ethmac_sram_reader_ev_pending_write(ETHMAC_EV_SRAM_READER);
- ethmac_sram_writer_ev_pending_write(ETHMAC_EV_SRAM_WRITER);
-
- rxbuffer0 = (ethernet_buffer *)ETHMAC_RX0_BASE;
- rxbuffer1 = (ethernet_buffer *)ETHMAC_RX1_BASE;
- txbuffer0 = (ethernet_buffer *)ETHMAC_TX0_BASE;
- txbuffer1 = (ethernet_buffer *)ETHMAC_TX1_BASE;
-
- rxslot = 0;
- txslot = 0;
-
- rxbuffer = rxbuffer0;
- txbuffer = txbuffer0;
-
- for(i=0;i<6;i++)
- my_mac[i] = macaddr[i];
- my_ip = ip;
-
- cached_ip = 0;
- for(i=0;i<6;i++)
- cached_mac[i] = 0;
-
- rx_callback = (udp_callback)0;
-}
-
-void microudp_service(void)
-{
- if(ethmac_sram_writer_ev_pending_read() & ETHMAC_EV_SRAM_WRITER) {
- rxslot = ethmac_sram_writer_slot_read();
- rxlen = ethmac_sram_writer_length_read();
- if (rxslot)
- rxbuffer = rxbuffer1;
- else
- rxbuffer = rxbuffer0;
- process_frame();
- ethmac_sram_writer_ev_pending_write(ETHMAC_EV_SRAM_WRITER);
- }
-}
-
-static void busy_wait(unsigned int ds)
-{
- timer0_en_write(0);
- timer0_reload_write(0);
- timer0_load_write(identifier_frequency_read()/10*ds);
- timer0_en_write(1);
- timer0_update_value_write(1);
- while(timer0_value_read()) timer0_update_value_write(1);
-}
-
-void eth_init(void)
-{
- ethphy_crg_reset_write(0);
- busy_wait(2);
- /* that pesky ethernet PHY needs two resets at times... */
- ethphy_crg_reset_write(1);
- busy_wait(2);
- ethphy_crg_reset_write(0);
- busy_wait(2);
-}
-
-#ifdef CSR_ETHPHY_MODE_DETECTION_MODE_ADDR
-void eth_mode(void)
-{
- printf("Ethernet phy mode: ");
- if (ethphy_mode_detection_mode_read())
- printf("MII");
- else
- printf("GMII");
- printf("\n");
-}
-#endif
-
-#endif
+++ /dev/null
-#include <stdint.h>
-#include <string.h>
-
-#include <net/microudp.h>
-#include <net/tftp.h>
-
-#define PORT_OUT 69
-#define PORT_IN 7642
-
-enum {
- TFTP_RRQ = 1, /* Read request */
- TFTP_WRQ = 2, /* Write request */
- TFTP_DATA = 3, /* Data */
- TFTP_ACK = 4, /* Acknowledgment */
- TFTP_ERROR = 5, /* Error */
-};
-
-#define BLOCK_SIZE 512 /* block size in bytes */
-
-
-static int format_request(uint8_t *buf, uint16_t op, const char *filename)
-{
- int len = strlen(filename);
-
- *buf++ = op >> 8; /* Opcode */
- *buf++ = op;
- memcpy(buf, filename, len);
- buf += len;
- *buf++ = 0x00;
- *buf++ = 'o';
- *buf++ = 'c';
- *buf++ = 't';
- *buf++ = 'e';
- *buf++ = 't';
- *buf++ = 0x00;
- return 9+strlen(filename);
-}
-
-static int format_ack(uint8_t *buf, uint16_t block)
-{
- *buf++ = 0x00; /* Opcode: Ack */
- *buf++ = TFTP_ACK;
- *buf++ = (block & 0xff00) >> 8;
- *buf++ = (block & 0x00ff);
- return 4;
-}
-
-static int format_data(uint8_t *buf, uint16_t block, const void *data, int len)
-{
- *buf++ = 0x00; /* Opcode: Data*/
- *buf++ = TFTP_DATA;
- *buf++ = (block & 0xff00) >> 8;
- *buf++ = (block & 0x00ff);
- memcpy(buf, data, len);
- return len+4;
-}
-
-static uint8_t *packet_data;
-static int total_length;
-static int transfer_finished;
-static uint8_t *dst_buffer;
-static int last_ack; /* signed, so we can use -1 */
-static uint16_t data_port;
-
-static void rx_callback(uint32_t src_ip, uint16_t src_port,
- uint16_t dst_port, void *_data, unsigned int length)
-{
- uint8_t *data = _data;
- uint16_t opcode;
- uint16_t block;
- int i;
- int offset;
-
- if(length < 4) return;
- if(dst_port != PORT_IN) return;
- opcode = data[0] << 8 | data[1];
- block = data[2] << 8 | data[3];
- if(opcode == TFTP_ACK) { /* Acknowledgement */
- data_port = src_port;
- last_ack = block;
- return;
- }
- if(block < 1) return;
- if(opcode == TFTP_DATA) { /* Data */
- length -= 4;
- offset = (block-1)*BLOCK_SIZE;
- for(i=0;i<length;i++)
- dst_buffer[offset+i] = data[i+4];
- total_length += length;
- if(length < BLOCK_SIZE)
- transfer_finished = 1;
-
- packet_data = microudp_get_tx_buffer();
- length = format_ack(packet_data, block);
- microudp_send(PORT_IN, src_port, length);
- }
- if(opcode == TFTP_ERROR) { /* Error */
- total_length = -1;
- transfer_finished = 1;
- }
-}
-
-int tftp_get(uint32_t ip, const char *filename, void *buffer)
-{
- int len;
- int tries;
- int i;
- int length_before;
-
- if(!microudp_arp_resolve(ip))
- return -1;
-
- microudp_set_callback(rx_callback);
-
- dst_buffer = buffer;
-
- total_length = 0;
- transfer_finished = 0;
- tries = 5;
- while(1) {
- packet_data = microudp_get_tx_buffer();
- len = format_request(packet_data, TFTP_RRQ, filename);
- microudp_send(PORT_IN, PORT_OUT, len);
- for(i=0;i<2000000;i++) {
- microudp_service();
- if((total_length > 0) || transfer_finished) break;
- }
- if((total_length > 0) || transfer_finished) break;
- tries--;
- if(tries == 0) {
- microudp_set_callback(NULL);
- return -1;
- }
- }
-
- length_before = total_length;
- while(!transfer_finished) {
- if(length_before != total_length) {
- i = 12000000;
- length_before = total_length;
- }
- if(i-- == 0) {
- microudp_set_callback(NULL);
- return -1;
- }
- microudp_service();
- }
-
- microudp_set_callback(NULL);
-
- return total_length;
-}
-
-int tftp_put(uint32_t ip, const char *filename, const void *buffer, int size)
-{
- int len, send;
- int tries;
- int i;
- int block = 0, sent = 0;
-
- if(!microudp_arp_resolve(ip))
- return -1;
-
- microudp_set_callback(rx_callback);
-
- packet_data = microudp_get_tx_buffer();
-
- total_length = 0;
- transfer_finished = 0;
- tries = 5;
- while(1) {
- packet_data = microudp_get_tx_buffer();
- len = format_request(packet_data, TFTP_WRQ, filename);
- microudp_send(PORT_IN, PORT_OUT, len);
- for(i=0;i<2000000;i++) {
- last_ack = -1;
- microudp_service();
- if(last_ack == block)
- goto send_data;
- if(transfer_finished)
- goto fail;
- }
- tries--;
- if(tries == 0)
- goto fail;
- }
-
-send_data:
- do {
- block++;
- send = sent+BLOCK_SIZE > size ? size-sent : BLOCK_SIZE;
- tries = 5;
- while(1) {
- packet_data = microudp_get_tx_buffer();
- len = format_data(packet_data, block, buffer, send);
- microudp_send(PORT_IN, data_port, len);
- for(i=0;i<12000000;i++) {
- microudp_service();
- if(transfer_finished)
- goto fail;
- if(last_ack == block)
- goto next;
- }
- if (!--tries)
- goto fail;
- }
-next:
- sent += send;
- buffer += send;
- } while (send == BLOCK_SIZE);
-
- microudp_set_callback(NULL);
-
- return sent;
-
-fail:
- microudp_set_callback(NULL);
- return -1;
-}
+++ /dev/null
-include ../include/generated/variables.mak
-include $(MISOC_DIRECTORY)/software/common.mak
-
-# lm32 is not supported
-ifeq ($(CPU),lm32)
- ALL_TARGET=
-else
- ALL_TARGET=libunwind.a
-endif
-
-COMMONFLAGS+=-integrated-as \
- -I. -I$(MISOC_DIRECTORY)/software/include/dyld/ -I$(MISOC_DIRECTORY)/software/unwinder/include/ \
- -I$(LIBUNWIND_DIRECTORY) \
- -D__ELF__ -D__linux__ -D_LIBUNWIND_NO_HEAP -DNDEBUG
-
-OBJECTS=UnwindRegistersSave.o UnwindRegistersRestore.o UnwindLevel1.o libunwind.o
-
-all: $(ALL_TARGET)
-
-libunwind.a: $(OBJECTS)
- $(AR) crs libunwind.a $(OBJECTS)
-
-%.o: $(MISOC_DIRECTORY)/software/unwinder/src/%.cpp
- $(compilexx)
-
-%.o: $(MISOC_DIRECTORY)/software/unwinder/src/%.c
- $(compile)
-
-%.o: $(MISOC_DIRECTORY)/software/unwinder/src/%.S
- $(assemble)
-
-.PHONY: clean
-
-clean:
- $(RM) $(OBJECTS) libunwind.a .*~ *~
+++ /dev/null
-#define LIBCXXABI_ARM_EHABI 0
+++ /dev/null
-MSCDIR=../..
-include $(MSCDIR)/software/common.mak
-
-OBJECTS=isr.o main.o
-
-all: memtest.bin
-
-%.bin: %.elf
- $(OBJCOPY) -O binary $< $@
- chmod -x $@
-
-memtest.elf: $(OBJECTS) libs
-
-%.elf:
- $(LD) $(LDFLAGS) \
- -T $(MSCDIR)/software/libbase/linker-sdram.ld \
- -N -o $@ \
- $(MSCDIR)/software/libbase/crt0-$(CPU).o \
- $(OBJECTS) \
- -L$(MSCDIR)/software/libbase \
- -L$(MSCDIR)/software/libcompiler-rt \
- -lbase -lcompiler-rt
- chmod -x $@
-
-main.o: main.c
- $(compile)
-
-%.o: %.c
- $(compile)
-
-%.o: %.S
- $(assemble)
-
-libs:
- $(MAKE) -C $(MSCDIR)/software/libcompiler-rt
- $(MAKE) -C $(MSCDIR)/software/libbase
-
-load: memtest.bin
- $(MAKE) -C $(MSCDIR)/tools
- $(MSCDIR)/tools/flterm --port /dev/ttyUSB0 --kernel memtest.bin
-
-
-clean:
- $(RM) $(OBJECTS) memtest.elf memtest.bin
- $(RM) .*~ *~
-
-.PHONY: all main.o clean libs load
+++ /dev/null
-#include <generated/csr.h>
-#include <irq.h>
-#include <uart.h>
-
-void isr(void);
-void isr(void)
-{
- unsigned int irqs;
-
- irqs = irq_pending() & irq_getmask();
-
- if(irqs & (1 << UART_INTERRUPT))
- uart_isr();
-}
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-
-#include <irq.h>
-#include <uart.h>
-#include <time.h>
-#include <generated/csr.h>
-#include <generated/mem.h>
-#include <hw/flags.h>
-#include <console.h>
-#include <system.h>
-
-static unsigned int log2(unsigned int v)
-{
- unsigned int r;
- r = 0;
- while(v>>=1) r++;
- return r;
-}
-
-static void membw_service(void)
-{
- static int last_event;
- unsigned long long int nr, nw;
- unsigned long long int f;
- unsigned int rdb, wrb;
- unsigned int dw;
-
- if(elapsed(&last_event, identifier_frequency_read())) {
- sdram_controller_bandwidth_update_write(1);
- nr = sdram_controller_bandwidth_nreads_read();
- nw = sdram_controller_bandwidth_nwrites_read();
- f = identifier_frequency_read();
- dw = sdram_controller_bandwidth_data_width_read();
- rdb = (nr*f >> (24 - log2(dw)))/1000000ULL;
- wrb = (nw*f >> (24 - log2(dw)))/1000000ULL;
- printf("read:%5dMbps write:%5dMbps all:%5dMbps\n", rdb, wrb, rdb + wrb);
- }
-}
-
-//#define DEBUG
-
-static void memtest_service(void)
-{
- static unsigned int test_buffer[(MAIN_RAM_SIZE/2)/4] __attribute__((aligned(16)));
- static unsigned char reading;
- static unsigned int err, total_err;
-#ifdef DEBUG
- int i;
-#endif
-
- if(reading) {
- if(!memtest_w_busy_read()) {
-#ifdef DEBUG
- flush_l2_cache();
- flush_cpu_dcache();
- printf("starting read\n");
- for(i=0;i<64;i++) {
- printf("%08x", test_buffer[i]);
- if((i % 4) == 3)
- printf("\n");
- }
-#endif
- memtest_r_reset_write(1);
- memtest_r_base_write((unsigned int)test_buffer);
- memtest_r_length_write(sizeof(test_buffer));
- memtest_r_shoot_write(1);
- reading = 0;
- }
- } else {
- if(!memtest_r_busy_read()) {
- err = memtest_r_error_count_read();
- total_err += err;
- printf("err=%d\t\ttotal=%d\n", err, total_err);
- memtest_w_reset_write(1);
- memtest_w_base_write((unsigned int)test_buffer);
- memtest_w_length_write(sizeof(test_buffer));
- memtest_w_shoot_write(1);
- reading = 1;
- }
- }
-}
-
-int main(void)
-{
- irq_setmask(0);
- irq_setie(1);
- uart_init();
-
- puts("Memory testing software built "__DATE__" "__TIME__"\n");
-
- if((memtest_w_magic_read() != 0x361f) || (memtest_r_magic_read() != 0x361f)) {
- printf("Memory test cores not detected\n");
- while(1);
- }
-
- time_init();
-
- flush_l2_cache();
- while(1) {
- memtest_service();
- membw_service();
- }
-
- return 0;
-}
+++ /dev/null
-#!/usr/bin/env python3
-
-import argparse
-
-from migen import *
-from migen.build.platforms import de0nano
-
-from misoc.cores.sdram_settings import IS42S16160
-from misoc.cores.sdram_phy import GENSDRPHY
-from misoc.integration.soc_sdram import *
-from misoc.integration.builder import *
-
-
-class _PLL(Module):
- def __init__(self, period_in, name, phase_shift, operation_mode):
- self.clk_in = Signal()
- self.clk_out = Signal()
-
- self.specials += Instance("ALTPLL",
- p_bandwidth_type = "AUTO",
- p_clk0_divide_by = 1,
- p_clk0_duty_cycle = 50,
- p_clk0_multiply_by = 2,
- p_clk0_phase_shift = "{}".format(str(phase_shift)),
- p_compensate_clock = "CLK0",
- p_inclk0_input_frequency = int(period_in*1000),
- p_intended_device_family = "Cyclone IV E",
- p_lpm_hint = "CBX_MODULE_PREFIX={}_pll".format(name),
- p_lpm_type = "altpll",
- p_operation_mode = operation_mode,
- i_inclk=self.clk_in,
- o_clk=self.clk_out,
- i_areset=0,
- i_clkena=0x3f,
- i_clkswitch=0,
- i_configupdate=0,
- i_extclkena=0xf,
- i_fbin=1,
- i_pfdena=1,
- i_phasecounterselect=0xf,
- i_phasestep=1,
- i_phaseupdown=1,
- i_pllena=1,
- i_scanaclr=0,
- i_scanclk=0,
- i_scanclkena=1,
- i_scandata=0,
- i_scanread=0,
- i_scanwrite=0
- )
-
-
-class _CRG(Module):
- def __init__(self, platform):
- self.clock_domains.cd_sys = ClockDomain()
- self.clock_domains.cd_sys_ps = ClockDomain()
- self.clock_domains.cd_por = ClockDomain(reset_less=True)
-
- clk50 = platform.request("clk50")
-
- sys_pll = _PLL(20, "sys", 0, "NORMAL")
- self.submodules += sys_pll
- self.comb += [
- sys_pll.clk_in.eq(clk50),
- self.cd_sys.clk.eq(sys_pll.clk_out)
- ]
-
- sdram_pll = _PLL(20, "sdram", -3000, "ZERO_DELAY_BUFFER")
- self.submodules += sdram_pll
- self.comb += [
- sdram_pll.clk_in.eq(clk50),
- self.cd_sys_ps.clk.eq(sdram_pll.clk_out)
- ]
-
- # Power on Reset (vendor agnostic)
- rst_n = Signal()
- self.sync.por += rst_n.eq(1)
- self.comb += [
- self.cd_por.clk.eq(self.cd_sys.clk),
- self.cd_sys.rst.eq(~rst_n),
- self.cd_sys_ps.rst.eq(~rst_n)
- ]
-
- self.comb += platform.request("sdram_clock").eq(self.cd_sys_ps.clk)
-
-
-class BaseSoC(SoCSDRAM):
- def __init__(self, **kwargs):
- platform = de0nano.Platform()
- SoCSDRAM.__init__(self, platform,
- clk_freq=100*1000000,
- integrated_rom_size=0x8000,
- **kwargs)
-
- self.submodules.crg = _CRG(platform)
-
- if not self.integrated_main_ram_size:
- self.submodules.sdrphy = GENSDRPHY(platform.request("sdram"))
- sdram_module = IS42S16160(self.clk_freq)
- self.register_sdram(self.sdrphy, "minicon",
- sdram_module.geom_settings, sdram_module.timing_settings)
-
-def main():
- parser = argparse.ArgumentParser(description="MiSoC port to the Altera DE0 Nano")
- builder_args(parser)
- soc_sdram_args(parser)
- args = parser.parse_args()
-
- soc = BaseSoC(**soc_sdram_argdict(args))
- builder = Builder(soc, **builder_argdict(args))
- builder.build()
-
-
-if __name__ == "__main__":
- main()
+++ /dev/null
-#!/usr/bin/env python3
-
-import argparse
-
-from migen import *
-from migen.genlib.resetsync import AsyncResetSynchronizer
-from migen.build.platforms import kc705
-
-from misoc.cores.sdram_settings import MT8JTF12864
-from misoc.cores.sdram_phy import k7ddrphy
-from misoc.cores import spi_flash
-from misoc.cores.liteeth_mini.phy import LiteEthPHY
-from misoc.cores.liteeth_mini.mac import LiteEthMAC
-from misoc.integration.soc_core import mem_decoder
-from misoc.integration.soc_sdram import *
-from misoc.integration.builder import *
-
-
-
-class _CRG(Module):
- def __init__(self, platform):
- self.clock_domains.cd_sys = ClockDomain()
- self.clock_domains.cd_sys4x = ClockDomain(reset_less=True)
- self.clock_domains.cd_clk200 = ClockDomain()
-
- clk200 = platform.request("clk200")
- clk200_se = Signal()
- self.specials += Instance("IBUFDS", i_I=clk200.p, i_IB=clk200.n, o_O=clk200_se)
-
- rst = platform.request("cpu_reset")
-
- pll_locked = Signal()
- pll_fb = Signal()
- self.pll_sys = Signal()
- pll_sys4x = Signal()
- pll_clk200 = Signal()
- self.specials += [
- Instance("PLLE2_BASE",
- p_STARTUP_WAIT="FALSE", o_LOCKED=pll_locked,
-
- # VCO @ 1GHz
- p_REF_JITTER1=0.01, p_CLKIN1_PERIOD=5.0,
- p_CLKFBOUT_MULT=5, p_DIVCLK_DIVIDE=1,
- i_CLKIN1=clk200_se, i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb,
-
- # 125MHz
- p_CLKOUT0_DIVIDE=8, p_CLKOUT0_PHASE=0.0, o_CLKOUT0=self.pll_sys,
-
- # 500MHz
- p_CLKOUT1_DIVIDE=2, p_CLKOUT1_PHASE=0.0, o_CLKOUT1=pll_sys4x,
-
- # 200MHz
- p_CLKOUT2_DIVIDE=5, p_CLKOUT2_PHASE=0.0, o_CLKOUT2=pll_clk200,
-
- p_CLKOUT3_DIVIDE=2, p_CLKOUT3_PHASE=0.0, #o_CLKOUT3=,
-
- p_CLKOUT4_DIVIDE=4, p_CLKOUT4_PHASE=0.0, #o_CLKOUT4=
- ),
- Instance("BUFG", i_I=self.pll_sys, o_O=self.cd_sys.clk),
- Instance("BUFG", i_I=pll_sys4x, o_O=self.cd_sys4x.clk),
- Instance("BUFG", i_I=pll_clk200, o_O=self.cd_clk200.clk),
- AsyncResetSynchronizer(self.cd_sys, ~pll_locked | rst),
- AsyncResetSynchronizer(self.cd_clk200, ~pll_locked | rst),
- ]
-
- reset_counter = Signal(4, reset=15)
- ic_reset = Signal(reset=1)
- self.sync.clk200 += \
- If(reset_counter != 0,
- reset_counter.eq(reset_counter - 1)
- ).Else(
- ic_reset.eq(0)
- )
- self.specials += Instance("IDELAYCTRL", i_REFCLK=ClockSignal("clk200"), i_RST=ic_reset)
-
-
-class BaseSoC(SoCSDRAM):
- default_platform = "kc705"
-
- csr_map = {
- "spiflash": 16,
- "ddrphy": 17,
- }
- csr_map.update(SoCSDRAM.csr_map)
-
- def __init__(self, toolchain="ise", sdram_controller_type="minicon", **kwargs):
- platform = kc705.Platform(toolchain=toolchain)
- SoCSDRAM.__init__(self, platform,
- clk_freq=125*1000000, cpu_reset_address=0xaf0000,
- **kwargs)
-
- self.submodules.crg = _CRG(platform)
-
- if not self.integrated_main_ram_size:
- self.submodules.ddrphy = k7ddrphy.K7DDRPHY(platform.request("ddram"))
- sdram_module = MT8JTF12864(self.clk_freq)
- self.register_sdram(self.ddrphy, sdram_controller_type,
- sdram_module.geom_settings, sdram_module.timing_settings)
-
- if not self.integrated_rom_size:
- spiflash_pads = platform.request("spiflash")
- spiflash_pads.clk = Signal()
- self.specials += Instance("STARTUPE2",
- i_CLK=0, i_GSR=0, i_GTS=0, i_KEYCLEARB=0, i_PACK=0,
- i_USRCCLKO=spiflash_pads.clk, i_USRCCLKTS=0, i_USRDONEO=1, i_USRDONETS=1)
- self.submodules.spiflash = spi_flash.SpiFlash(spiflash_pads, dummy=11, div=2)
- self.add_constant("SPIFLASH_PAGE_SIZE", 256)
- self.add_constant("SPIFLASH_SECTOR_SIZE", 0x10000)
- self.flash_boot_address = 0xb00000
- self.register_rom(self.spiflash.bus)
-
-
-class MiniSoC(BaseSoC):
- csr_map = {
- "ethphy": 18,
- "ethmac": 19,
- }
- csr_map.update(BaseSoC.csr_map)
-
- interrupt_map = {
- "ethmac": 2,
- }
- interrupt_map.update(BaseSoC.interrupt_map)
-
- mem_map = {
- "ethmac": 0x30000000, # (shadow @0xb0000000)
- }
- mem_map.update(BaseSoC.mem_map)
-
- def __init__(self, *args, **kwargs):
- BaseSoC.__init__(self, *args, **kwargs)
-
- self.submodules.ethphy = LiteEthPHY(self.platform.request("eth_clocks"),
- self.platform.request("eth"), clk_freq=self.clk_freq)
- self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, interface="wishbone")
- self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus)
- self.add_memory_region("ethmac", self.mem_map["ethmac"] | self.shadow_base, 0x2000)
-
-
-def soc_kc705_args(parser):
- soc_sdram_args(parser)
- parser.add_argument("--toolchain", default="ise",
- help="FPGA toolchain to use: ise, vivado")
-
-
-def soc_kc705_argdict(args):
- r = soc_sdram_argdict(args)
- r["toolchain"] = args.toolchain
- return r
-
-
-def main():
- parser = argparse.ArgumentParser(description="MiSoC port to the KC705")
- builder_args(parser)
- soc_kc705_args(parser)
- parser.add_argument("--with-ethernet", action="store_true",
- help="enable Ethernet support")
- args = parser.parse_args()
-
- cls = MiniSoC if args.with_ethernet else BaseSoC
- soc = cls(**soc_kc705_argdict(args))
- builder = Builder(soc, **builder_argdict(args))
- builder.build()
-
-
-if __name__ == "__main__":
- main()
+++ /dev/null
-#!/usr/bin/env python3
-
-import argparse
-from fractions import Fraction
-
-from migen import *
-from migen.genlib.resetsync import AsyncResetSynchronizer
-from migen.build.platforms import minispartan6
-
-from misoc.cores.sdram_settings import AS4C16M16
-from misoc.cores.sdram_phy import GENSDRPHY
-from misoc.integration.soc_sdram import *
-from misoc.integration.builder import *
-
-
-class _CRG(Module):
- def __init__(self, platform, clk_freq):
- self.clock_domains.cd_sys = ClockDomain()
- self.clock_domains.cd_sys_ps = ClockDomain()
-
- f0 = 32*1000000
- clk32 = platform.request("clk32")
- clk32a = Signal()
- self.specials += Instance("IBUFG", i_I=clk32, o_O=clk32a)
- clk32b = Signal()
- self.specials += Instance("BUFIO2", p_DIVIDE=1,
- p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE",
- i_I=clk32a, o_DIVCLK=clk32b)
- f = Fraction(int(clk_freq), int(f0))
- n, m, p = f.denominator, f.numerator, 8
- assert f0/n*m == clk_freq
- pll_lckd = Signal()
- pll_fb = Signal()
- pll = Signal(6)
- self.specials.pll = Instance("PLL_ADV", p_SIM_DEVICE="SPARTAN6",
- p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL",
- p_REF_JITTER=.01, p_CLK_FEEDBACK="CLKFBOUT",
- i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0,
- p_DIVCLK_DIVIDE=1, p_CLKFBOUT_MULT=m*p//n, p_CLKFBOUT_PHASE=0.,
- i_CLKIN1=clk32b, i_CLKIN2=0, i_CLKINSEL=1,
- p_CLKIN1_PERIOD=1000000000/f0, p_CLKIN2_PERIOD=0.,
- i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd,
- o_CLKOUT0=pll[0], p_CLKOUT0_DUTY_CYCLE=.5,
- o_CLKOUT1=pll[1], p_CLKOUT1_DUTY_CYCLE=.5,
- o_CLKOUT2=pll[2], p_CLKOUT2_DUTY_CYCLE=.5,
- o_CLKOUT3=pll[3], p_CLKOUT3_DUTY_CYCLE=.5,
- o_CLKOUT4=pll[4], p_CLKOUT4_DUTY_CYCLE=.5,
- o_CLKOUT5=pll[5], p_CLKOUT5_DUTY_CYCLE=.5,
- p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p//1,
- p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=p//1,
- p_CLKOUT2_PHASE=0., p_CLKOUT2_DIVIDE=p//1,
- p_CLKOUT3_PHASE=0., p_CLKOUT3_DIVIDE=p//1,
- p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=p//1, # sys
- p_CLKOUT5_PHASE=270., p_CLKOUT5_DIVIDE=p//1, # sys_ps
- )
- self.specials += Instance("BUFG", i_I=pll[4], o_O=self.cd_sys.clk)
- self.specials += Instance("BUFG", i_I=pll[5], o_O=self.cd_sys_ps.clk)
- self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd)
-
- self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE",
- p_INIT=0, p_SRTYPE="SYNC",
- i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1,
- i_C0=self.cd_sys.clk, i_C1=~self.cd_sys.clk,
- o_Q=platform.request("sdram_clock"))
-
-
-class BaseSoC(SoCSDRAM):
- def __init__(self, **kwargs):
- clk_freq = 80*1000000
- platform = minispartan6.Platform()
- SoCSDRAM.__init__(self, platform, clk_freq,
- integrated_rom_size=0x8000,
- **kwargs)
-
- self.submodules.crg = _CRG(platform, clk_freq)
-
- if not self.integrated_main_ram_size:
- self.submodules.sdrphy = GENSDRPHY(platform.request("sdram"))
- sdram_module = AS4C16M16(clk_freq)
- self.register_sdram(self.sdrphy, "minicon",
- sdram_module.geom_settings, sdram_module.timing_settings)
-
-
-def main():
- parser = argparse.ArgumentParser(description="MiSoC port to the MiniSpartan6")
- builder_args(parser)
- soc_sdram_args(parser)
- args = parser.parse_args()
-
- soc = BaseSoC(**soc_sdram_argdict(args))
- builder = Builder(soc, **builder_argdict(args))
- builder.build()
-
-
-if __name__ == "__main__":
- main()
+++ /dev/null
-#!/usr/bin/env python3
-
-import argparse
-import os
-from fractions import Fraction
-from math import ceil
-
-from migen import *
-from migen.build.generic_platform import ConstraintError
-from migen.build.platforms import mixxeo, m1
-
-from misoc.cores.sdram_settings import MT46V32M16
-from misoc.cores.sdram_phy import S6HalfRateDDRPHY
-from misoc.cores import nor_flash_16
-# TODO: from misoc.cores import framebuffer
-from misoc.cores import gpio
-from misoc.cores.liteeth_mini.phy import LiteEthPHY
-from misoc.cores.liteeth_mini.mac import LiteEthMAC
-from misoc.integration.soc_core import mem_decoder
-from misoc.integration.soc_sdram import *
-from misoc.integration.builder import *
-
-
-class _MXCRG(Module):
- def __init__(self, pads, outfreq1x):
- self.clock_domains.cd_sys = ClockDomain()
- self.clock_domains.cd_sdram_half = ClockDomain()
- self.clock_domains.cd_sdram_full_wr = ClockDomain()
- self.clock_domains.cd_sdram_full_rd = ClockDomain()
- self.clock_domains.cd_base50 = ClockDomain(reset_less=True)
-
- self.clk4x_wr_strb = Signal()
- self.clk4x_rd_strb = Signal()
-
- ###
-
- infreq = 50*1000000
- ratio = Fraction(outfreq1x)/Fraction(infreq)
- in_period = float(Fraction(1000000000)/Fraction(infreq))
-
- self.specials += Instance("mxcrg",
- Instance.Parameter("in_period", in_period),
- Instance.Parameter("f_mult", ratio.numerator),
- Instance.Parameter("f_div", ratio.denominator),
- Instance.Input("clk50_pad", pads.clk50),
- Instance.Input("trigger_reset", pads.trigger_reset),
-
- Instance.Output("sys_clk", self.cd_sys.clk),
- Instance.Output("sys_rst", self.cd_sys.rst),
- Instance.Output("clk2x_270", self.cd_sdram_half.clk),
- Instance.Output("clk4x_wr", self.cd_sdram_full_wr.clk),
- Instance.Output("clk4x_rd", self.cd_sdram_full_rd.clk),
- Instance.Output("base50_clk", self.cd_base50.clk),
-
- Instance.Output("clk4x_wr_strb", self.clk4x_wr_strb),
- Instance.Output("clk4x_rd_strb", self.clk4x_rd_strb),
- Instance.Output("norflash_rst_n", pads.norflash_rst_n),
- Instance.Output("ddr_clk_pad_p", pads.ddr_clk_p),
- Instance.Output("ddr_clk_pad_n", pads.ddr_clk_n))
-
-
-class _MXClockPads:
- def __init__(self, platform):
- self.clk50 = platform.request("clk50")
- self.trigger_reset = 0
- try:
- self.trigger_reset = platform.request("user_btn", 1)
- except ConstraintError:
- pass
- self.norflash_rst_n = platform.request("norflash_rst_n")
- ddram_clock = platform.request("ddram_clock")
- self.ddr_clk_p = ddram_clock.p
- self.ddr_clk_n = ddram_clock.n
-
-
-class BaseSoC(SoCSDRAM):
- def __init__(self, platform_name="mixxeo", **kwargs):
- if platform_name == "mixxeo":
- platform = mixxeo.Platform()
- elif platform_name == "m1":
- platform = m1.Platform()
- else:
- raise ValueError
- SoCSDRAM.__init__(self, platform,
- clk_freq=(83 + Fraction(1, 3))*1000000,
- cpu_reset_address=0x00180000,
- **kwargs)
-
- self.submodules.crg = _MXCRG(_MXClockPads(platform), self.clk_freq)
-
- if not self.integrated_main_ram_size:
- sdram_module = MT46V32M16(self.clk_freq)
- self.submodules.ddrphy = S6HalfRateDDRPHY(platform.request("ddram"),
- sdram_module.memtype,
- rd_bitslip=0,
- wr_bitslip=3,
- dqs_ddr_alignment="C1")
- self.register_sdram(self.ddrphy, "lasmicon",
- sdram_module.geom_settings, sdram_module.timing_settings)
- self.comb += [
- self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb),
- self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb)
- ]
-
- if not self.integrated_rom_size:
- clk_period_ns = 1000000000/self.clk_freq
- self.submodules.norflash = nor_flash_16.NorFlash16(
- platform.request("norflash"),
- ceil(110/clk_period_ns), ceil(50/clk_period_ns))
- self.flash_boot_address = 0x001a0000
- self.register_rom(self.norflash.bus)
-
- platform.add_platform_command("""
-INST "mxcrg/wr_bufpll" LOC = "BUFPLL_X0Y2";
-INST "mxcrg/rd_bufpll" LOC = "BUFPLL_X0Y3";
-""")
- platform.add_source(os.path.join(misoc_directory, "cores", "mxcrg.v"))
-
-
-class MiniSoC(BaseSoC):
- csr_map = {
- "ethphy": 16,
- "ethmac": 17,
- }
- csr_map.update(BaseSoC.csr_map)
-
- interrupt_map = {
- "ethmac": 2,
- }
- interrupt_map.update(BaseSoC.interrupt_map)
-
- mem_map = {
- "ethmac": 0x30000000, # (shadow @0xb0000000)
- }
- mem_map.update(BaseSoC.mem_map)
-
- def __init__(self, *args, **kwargs):
- BaseSoC.__init__(self, *args, **kwargs)
-
- platform = self.platform
- if platform.name == "mixxeo":
- self.submodules.leds = gpio.GPIOOut(platform.request("user_led"))
- if platform.name == "m1":
- self.submodules.buttons = gpio.GPIOIn(Cat(platform.request("user_btn", 0),
- platform.request("user_btn", 2)))
- self.submodules.leds = gpio.GPIOOut(Cat(platform.request("user_led", i) for i in range(2)))
-
- self.submodules.ethphy = LiteEthPHY(platform.request("eth_clocks"),
- platform.request("eth"))
- self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, interface="wishbone")
- self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus)
- self.add_memory_region("ethmac", self.mem_map["ethmac"] | self.shadow_base, 0x2000)
-
-
-def get_vga_dvi(platform):
- try:
- pads_vga = platform.request("vga_out")
- except ConstraintError:
- pads_vga = None
- try:
- pads_dvi = platform.request("dvi_out")
- except ConstraintError:
- pads_dvi = None
- else:
- platform.add_platform_command("""
-PIN "dviout_pix_bufg.O" CLOCK_DEDICATED_ROUTE = FALSE;
-""")
- return pads_vga, pads_dvi
-
-
-def add_vga_tig(platform, fb):
- platform.add_platform_command("""
-NET "{vga_clk}" TNM_NET = "GRPvga_clk";
-NET "sys_clk" TNM_NET = "GRPsys_clk";
-TIMESPEC "TSise_sucks1" = FROM "GRPvga_clk" TO "GRPsys_clk" TIG;
-TIMESPEC "TSise_sucks2" = FROM "GRPsys_clk" TO "GRPvga_clk" TIG;
-""", vga_clk=fb.driver.clocking.cd_pix.clk)
-
-
-class FramebufferSoC(MiniSoC):
- csr_map = {
- "fb": 18,
- }
- csr_map.update(MiniSoC.csr_map)
-
- def __init__(self, *args, **kwargs):
- MiniSoC.__init__(self, *args, **kwargs)
- pads_vga, pads_dvi = get_vga_dvi(platform)
- self.submodules.fb = framebuffer.Framebuffer(pads_vga, pads_dvi,
- self.sdram.crossbar.get_master())
- add_vga_tig(platform, self.fb)
-
-
-def main():
- parser = argparse.ArgumentParser(description="MiSoC port to the Mixxeo and Milkymist One")
- builder_args(parser)
- soc_sdram_args(parser)
- parser.add_argument("--platform", default="mixxeo",
- help="platform to build for: mixxeo, m1")
- parser.add_argument("--soc-type", default="base",
- help="SoC type: base, mini, framebuffer")
- args = parser.parse_args()
-
- cls = {
- "base": BaseSoC,
- "mini": MiniSoC,
- "framebuffer": FramebufferSoC
- }[args.soc_type]
- soc = cls(args.platform, **soc_sdram_argdict(args))
- builder = Builder(soc, **builder_argdict(args))
- builder.build()
-
-
-if __name__ == "__main__":
- main()
+++ /dev/null
-#!/usr/bin/env python3
-
-import argparse
-from fractions import Fraction
-
-from migen import *
-from migen.genlib.resetsync import AsyncResetSynchronizer
-from migen.build.platforms import papilio_pro
-
-from misoc.cores.sdram_settings import MT48LC4M16
-from misoc.cores.sdram_phy import GENSDRPHY
-from misoc.cores import spi_flash
-from misoc.integration.soc_sdram import *
-from misoc.integration.builder import *
-
-
-class _CRG(Module):
- def __init__(self, platform, clk_freq):
- self.clock_domains.cd_sys = ClockDomain()
- self.clock_domains.cd_sys_ps = ClockDomain()
-
- f0 = 32*1000000
- clk32 = platform.request("clk32")
- clk32a = Signal()
- self.specials += Instance("IBUFG", i_I=clk32, o_O=clk32a)
- clk32b = Signal()
- self.specials += Instance("BUFIO2", p_DIVIDE=1,
- p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE",
- i_I=clk32a, o_DIVCLK=clk32b)
- f = Fraction(int(clk_freq), int(f0))
- n, m, p = f.denominator, f.numerator, 8
- assert f0/n*m == clk_freq
- pll_lckd = Signal()
- pll_fb = Signal()
- pll = Signal(6)
- self.specials.pll = Instance("PLL_ADV", p_SIM_DEVICE="SPARTAN6",
- p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL",
- p_REF_JITTER=.01, p_CLK_FEEDBACK="CLKFBOUT",
- i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0,
- p_DIVCLK_DIVIDE=1, p_CLKFBOUT_MULT=m*p//n, p_CLKFBOUT_PHASE=0.,
- i_CLKIN1=clk32b, i_CLKIN2=0, i_CLKINSEL=1,
- p_CLKIN1_PERIOD=1000000000/f0, p_CLKIN2_PERIOD=0.,
- i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd,
- o_CLKOUT0=pll[0], p_CLKOUT0_DUTY_CYCLE=.5,
- o_CLKOUT1=pll[1], p_CLKOUT1_DUTY_CYCLE=.5,
- o_CLKOUT2=pll[2], p_CLKOUT2_DUTY_CYCLE=.5,
- o_CLKOUT3=pll[3], p_CLKOUT3_DUTY_CYCLE=.5,
- o_CLKOUT4=pll[4], p_CLKOUT4_DUTY_CYCLE=.5,
- o_CLKOUT5=pll[5], p_CLKOUT5_DUTY_CYCLE=.5,
- p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p//1,
- p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=p//1,
- p_CLKOUT2_PHASE=0., p_CLKOUT2_DIVIDE=p//1,
- p_CLKOUT3_PHASE=0., p_CLKOUT3_DIVIDE=p//1,
- p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=p//1, # sys
- p_CLKOUT5_PHASE=270., p_CLKOUT5_DIVIDE=p//1, # sys_ps
- )
- self.specials += Instance("BUFG", i_I=pll[4], o_O=self.cd_sys.clk)
- self.specials += Instance("BUFG", i_I=pll[5], o_O=self.cd_sys_ps.clk)
- self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd)
-
- self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE",
- p_INIT=0, p_SRTYPE="SYNC",
- i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1,
- i_C0=self.cd_sys.clk, i_C1=~self.cd_sys.clk,
- o_Q=platform.request("sdram_clock"))
-
-
-class BaseSoC(SoCSDRAM):
- csr_map = {
- "spiflash": 16,
- }
- csr_map.update(SoCSDRAM.csr_map)
-
- def __init__(self, **kwargs):
- platform = papilio_pro.Platform()
- clk_freq = 80*1000000
- SoCSDRAM.__init__(self, platform, clk_freq,
- cpu_reset_address=0x60000,
- **kwargs)
-
- self.submodules.crg = _CRG(platform, clk_freq)
-
- if not self.integrated_main_ram_size:
- self.submodules.sdrphy = GENSDRPHY(platform.request("sdram"))
- sdram_module = MT48LC4M16(clk_freq)
- self.register_sdram(self.sdrphy, "minicon",
- sdram_module.geom_settings, sdram_module.timing_settings)
-
- if not self.integrated_rom_size:
- self.submodules.spiflash = spi_flash.SpiFlash(platform.request("spiflash2x"),
- dummy=4, div=6)
- self.flash_boot_address = 0x70000
- self.register_rom(self.spiflash.bus)
-
-
-def main():
- parser = argparse.ArgumentParser(description="MiSoC port to the Papilio Pro")
- builder_args(parser)
- soc_sdram_args(parser)
- args = parser.parse_args()
-
- soc = BaseSoC(**soc_sdram_argdict(args))
- builder = Builder(soc, **builder_argdict(args))
- builder.build()
-
-
-if __name__ == "__main__":
- main()
+++ /dev/null
-#!/usr/bin/env python3
-
-import argparse
-from fractions import Fraction
-
-from migen import *
-from migen.genlib.resetsync import AsyncResetSynchronizer
-from migen.build.platforms import pipistrello
-
-from misoc.cores.sdram_settings import MT46H32M16
-from misoc.cores.sdram_phy import S6HalfRateDDRPHY
-from misoc.cores import spi_flash
-from misoc.integration.soc_sdram import *
-from misoc.integration.builder import *
-
-
-class _CRG(Module):
- def __init__(self, platform, clk_freq):
- self.clock_domains.cd_sys = ClockDomain()
- self.clock_domains.cd_sdram_half = ClockDomain()
- self.clock_domains.cd_sdram_full_wr = ClockDomain()
- self.clock_domains.cd_sdram_full_rd = ClockDomain()
-
- self.clk4x_wr_strb = Signal()
- self.clk4x_rd_strb = Signal()
-
- f0 = Fraction(50, 1)*1000000
- p = 12
- f = Fraction(clk_freq*p, f0)
- n, d = f.numerator, f.denominator
- assert 19e6 <= f0/d <= 500e6 # pfd
- assert 400e6 <= f0*n/d <= 1080e6 # vco
-
- clk50 = platform.request("clk50")
- clk50a = Signal()
- self.specials += Instance("IBUFG", i_I=clk50, o_O=clk50a)
- clk50b = Signal()
- self.specials += Instance("BUFIO2", p_DIVIDE=1,
- p_DIVIDE_BYPASS="TRUE", p_I_INVERT="FALSE",
- i_I=clk50a, o_DIVCLK=clk50b)
- pll_lckd = Signal()
- pll_fb = Signal()
- pll = Signal(6)
- self.specials.pll = Instance("PLL_ADV", p_SIM_DEVICE="SPARTAN6",
- p_BANDWIDTH="OPTIMIZED", p_COMPENSATION="INTERNAL",
- p_REF_JITTER=.01, p_CLK_FEEDBACK="CLKFBOUT",
- i_DADDR=0, i_DCLK=0, i_DEN=0, i_DI=0, i_DWE=0, i_RST=0, i_REL=0,
- p_DIVCLK_DIVIDE=d, p_CLKFBOUT_MULT=n, p_CLKFBOUT_PHASE=0.,
- i_CLKIN1=clk50b, i_CLKIN2=0, i_CLKINSEL=1,
- p_CLKIN1_PERIOD=1e9/f0, p_CLKIN2_PERIOD=0.,
- i_CLKFBIN=pll_fb, o_CLKFBOUT=pll_fb, o_LOCKED=pll_lckd,
- o_CLKOUT0=pll[0], p_CLKOUT0_DUTY_CYCLE=.5,
- o_CLKOUT1=pll[1], p_CLKOUT1_DUTY_CYCLE=.5,
- o_CLKOUT2=pll[2], p_CLKOUT2_DUTY_CYCLE=.5,
- o_CLKOUT3=pll[3], p_CLKOUT3_DUTY_CYCLE=.5,
- o_CLKOUT4=pll[4], p_CLKOUT4_DUTY_CYCLE=.5,
- o_CLKOUT5=pll[5], p_CLKOUT5_DUTY_CYCLE=.5,
- p_CLKOUT0_PHASE=0., p_CLKOUT0_DIVIDE=p//4, # sdram wr rd
- p_CLKOUT1_PHASE=0., p_CLKOUT1_DIVIDE=p//4,
- p_CLKOUT2_PHASE=270., p_CLKOUT2_DIVIDE=p//2, # sdram dqs adr ctrl
- p_CLKOUT3_PHASE=250., p_CLKOUT3_DIVIDE=p//2, # off-chip ddr
- p_CLKOUT4_PHASE=0., p_CLKOUT4_DIVIDE=p//1,
- p_CLKOUT5_PHASE=0., p_CLKOUT5_DIVIDE=p//1, # sys
- )
- self.specials += Instance("BUFG", i_I=pll[5], o_O=self.cd_sys.clk)
- reset = platform.request("user_btn")
- self.clock_domains.cd_por = ClockDomain()
- por = Signal(max=1 << 11, reset=(1 << 11) - 1)
- self.sync.por += If(por != 0, por.eq(por - 1))
- self.comb += self.cd_por.clk.eq(self.cd_sys.clk)
- self.specials += AsyncResetSynchronizer(self.cd_por, reset)
- self.specials += AsyncResetSynchronizer(self.cd_sys, ~pll_lckd | (por > 0))
- self.specials += Instance("BUFG", i_I=pll[2], o_O=self.cd_sdram_half.clk)
- self.specials += Instance("BUFPLL", p_DIVIDE=4,
- i_PLLIN=pll[0], i_GCLK=self.cd_sys.clk,
- i_LOCKED=pll_lckd, o_IOCLK=self.cd_sdram_full_wr.clk,
- o_SERDESSTROBE=self.clk4x_wr_strb)
- self.comb += [
- self.cd_sdram_full_rd.clk.eq(self.cd_sdram_full_wr.clk),
- self.clk4x_rd_strb.eq(self.clk4x_wr_strb),
- ]
- clk_sdram_half_shifted = Signal()
- self.specials += Instance("BUFG", i_I=pll[3], o_O=clk_sdram_half_shifted)
- clk = platform.request("ddram_clock")
- self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE",
- p_INIT=0, p_SRTYPE="SYNC",
- i_D0=1, i_D1=0, i_S=0, i_R=0, i_CE=1,
- i_C0=clk_sdram_half_shifted, i_C1=~clk_sdram_half_shifted,
- o_Q=clk.p)
- self.specials += Instance("ODDR2", p_DDR_ALIGNMENT="NONE",
- p_INIT=0, p_SRTYPE="SYNC",
- i_D0=0, i_D1=1, i_S=0, i_R=0, i_CE=1,
- i_C0=clk_sdram_half_shifted, i_C1=~clk_sdram_half_shifted,
- o_Q=clk.n)
-
-
-class BaseSoC(SoCSDRAM):
- csr_map = {
- "spiflash": 16,
- }
- csr_map.update(SoCSDRAM.csr_map)
-
- def __init__(self, clk_freq=(83 + Fraction(1, 3))*1000*1000, **kwargs):
- platform = pipistrello.Platform()
- SoCSDRAM.__init__(self, platform, clk_freq,
- cpu_reset_address=0x170000, # 1.5 MB
- **kwargs)
-
- self.submodules.crg = _CRG(platform, clk_freq)
-
- if not self.integrated_main_ram_size:
- sdram_module = MT46H32M16(self.clk_freq)
- self.submodules.ddrphy = S6HalfRateDDRPHY(platform.request("ddram"),
- sdram_module.memtype,
- rd_bitslip=1,
- wr_bitslip=3,
- dqs_ddr_alignment="C1")
- self.comb += [
- self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb),
- self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb),
- ]
- self.register_sdram(self.ddrphy, "minicon",
- sdram_module.geom_settings, sdram_module.timing_settings)
-
- if not self.integrated_rom_size:
- self.submodules.spiflash = spi_flash.SpiFlash(platform.request("spiflash4x"),
- dummy=10, div=4)
- self.add_constant("SPIFLASH_PAGE_SIZE", 256)
- self.add_constant("SPIFLASH_SECTOR_SIZE", 0x10000)
- self.flash_boot_address = 0x180000
- self.register_rom(self.spiflash.bus, 0x1000000)
-
-
-soc_pipistrello_args = soc_sdram_args
-soc_pipistrello_argdict = soc_sdram_argdict
-
-
-def main():
- parser = argparse.ArgumentParser(description="MiSoC port to the Pipistrello")
- builder_args(parser)
- soc_pipistrello_args(parser)
- args = parser.parse_args()
-
- soc = BaseSoC(**soc_pipistrello_argdict(args))
- builder = Builder(soc, **builder_argdict(args))
- builder.build()
-
-
-if __name__ == "__main__":
- main()
-
+++ /dev/null
-#!/usr/bin/env python3
-
-import argparse
-import importlib
-
-from migen import *
-from migen.genlib.io import CRG
-
-from misoc.cores.liteeth_mini.phy import LiteEthPHY
-from misoc.cores.liteeth_mini.mac import LiteEthMAC
-from misoc.integration.soc_core import *
-from misoc.integration.builder import *
-
-
-class BaseSoC(SoCCore):
- def __init__(self, platform, **kwargs):
- SoCCore.__init__(self, platform,
- clk_freq=int((1/(platform.default_clk_period))*1000000000),
- integrated_rom_size=0x8000,
- integrated_main_ram_size=16*1024,
- **kwargs)
- self.submodules.crg = CRG(platform.request(platform.default_clk_name))
-
-
-class MiniSoC(BaseSoC):
- csr_map = {
- "ethphy": 20,
- "ethmac": 21
- }
- csr_map.update(BaseSoC.csr_map)
-
- interrupt_map = {
- "ethmac": 2,
- }
- interrupt_map.update(BaseSoC.interrupt_map)
-
- mem_map = {
- "ethmac": 0x30000000, # (shadow @0xb0000000)
- }
- mem_map.update(BaseSoC.mem_map)
-
- def __init__(self, platform, **kwargs):
- BaseSoC.__init__(self, platform, **kwargs)
-
- self.submodules.ethphy = LiteEthPHY(platform.request("eth_clocks"),
- platform.request("eth"))
- self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32,
- interface="wishbone",
- with_preamble_crc=False)
- self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus)
- self.add_memory_region("ethmac", self.mem_map["ethmac"] | self.shadow_base, 0x2000)
-
-
-def main():
- parser = argparse.ArgumentParser(description="Generic MiSoC port")
- builder_args(parser)
- soc_core_args(parser)
- parser.add_argument("--with-ethernet", action="store_true",
- help="enable Ethernet support")
- parser.add_argument("platform",
- help="module name of the Migen platform to build for")
- args = parser.parse_args()
-
- platform_module = importlib.import_module(args.platform)
- platform = platform_module.Platform()
- cls = MiniSoC if args.with_ethernet else BaseSoC
- soc = cls(platform, **soc_core_argdict(args))
- builder = Builder(soc, **builder_argdict(args))
- builder.build()
-
-
-if __name__ == "__main__":
- main()
+++ /dev/null
-#!/usr/bin/env python3
-
-import sys
-import os
-import time
-import serial
-import threading
-import argparse
-
-from serial.tools.miniterm import console, character, LF
-
-sfl_magic_len = 14
-sfl_magic_req = "sL5DdSMmkekro\n"
-sfl_magic_ack = "z6IHG7cYDID6o\n"
-
-# General commands
-sfl_cmd_abort = 0x00
-sfl_cmd_load = 0x01
-sfl_cmd_jump = 0x02
-
-
-# Replies
-sfl_ack_success = 'K'
-sfl_ack_crcerror = 'C'
-sfl_ack_unknown = 'U'
-sfl_ack_error = 'E'
-
-
-crc16_table = [
- 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
- 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
- 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
- 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
- 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
- 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
- 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
- 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
- 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
- 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
- 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
- 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
- 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
- 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
- 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
- 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
- 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
- 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
- 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
- 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
- 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
- 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
- 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
- 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
- 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
- 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
- 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
- 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
- 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
- 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
- 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
- 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
-]
-
-
-def crc16(l):
- crc = 0
- for d in l:
- crc = crc16_table[((crc >> 8) ^ d) & 0xff] ^ (crc << 8)
- return crc & 0xffff
-
-
-class SFLFrame:
- def __init__(self):
- self.length = None
- self.cmd = None
- self.payload = []
- self.crc = None
- self.raw = []
-
- def compute_crc(self):
- crc_data = []
- crc_data.append(self.cmd)
- for d in self.payload:
- crc_data.append(d)
- self.crc = crc16(crc_data)
- return self.crc
-
- def encode(self):
- self.raw = []
- self.raw.append(self.length)
- self.compute_crc()
- for d in self.crc.to_bytes(2, "big"):
- self.raw.append(d)
- self.raw.append(self.cmd)
- for d in self.payload:
- self.raw.append(d)
-
-
-def get_file_data(filename):
- with open(filename, "rb") as f:
- data = []
- while True:
- w = f.read(1)
- if not w:
- break
- data.append(int.from_bytes(w, "big"))
- return data
-
-
-class Flterm:
- def __init__(self, kernel_image, kernel_address):
- self.kernel_image = kernel_image
- self.kernel_address = kernel_address
-
- self.reader_alive = False
- self.writer_alive = False
-
- self.detect_magic_str = " "*len(sfl_magic_req)
-
- def open(self, port, speed):
- self.serial = serial.serial_for_url(
- port,
- baudrate=speed,
- bytesize=8,
- parity="N",
- stopbits=1,
- xonxoff=0,
- timeout=0.25)
- self.serial.flushOutput()
- self.serial.flushInput()
- self.serial.close() # in case port was not correctly closed
- self.serial.open()
-
- def close(self):
- self.serial.close()
-
- def write_exact(self, data):
- if isinstance(data, str):
- self.serial.write(bytes(data, "utf-8"))
- else:
- self.serial.write(serial.to_bytes(data))
-
- def send_frame(self, frame):
- frame.encode()
- retry = 1
- while retry:
- self.write_exact(frame.raw)
- # Get the reply from the device
- reply = character(self.serial.read())
- if reply == sfl_ack_success:
- retry = 0
- elif reply == sfl_ack_crcerror:
- retry = 1
- else:
- print("[FLTERM] Got unknown reply '{}' from the device, aborting.".format(reply))
- return 0
- return 1
-
- def upload(self, filename, address):
- data = get_file_data(filename)
- print("[FLTERM] Uploading {} ({} bytes)...".format(filename, len(data)))
- current_address = address
- position = 0
- length = len(data)
- start = time.time()
- while len(data) != 0:
- print("{}%\r".format(100*position//length), end="")
- frame = SFLFrame()
- frame_data = data[:251]
- frame.length = len(frame_data) + 4
- frame.cmd = sfl_cmd_load
- for d in current_address.to_bytes(4, "big"):
- frame.payload.append(d)
- for d in frame_data:
- frame.payload.append(d)
- if self.send_frame(frame) == 0:
- return
- current_address += len(frame_data)
- position += len(frame_data)
- try:
- data = data[251:]
- except:
- data = []
- end = time.time()
- elapsed = end - start
- print("[FLTERM] Upload complete ({0:.1f}KB/s).".format(length/(elapsed*1024)))
- return length
-
- def boot(self):
- print("[FLTERM] Booting the device.")
- frame = SFLFrame()
- frame.length = 4
- frame.cmd = sfl_cmd_jump
- for d in self.kernel_address.to_bytes(4, "big"):
- frame.payload.append(d)
- self.send_frame(frame)
-
- def detect_magic(self, data):
- if data is not "":
- self.detect_magic_str = self.detect_magic_str[1:] + data
- return self.detect_magic_str == sfl_magic_req
- else:
- return False
-
- def answer_magic(self):
- print("[FLTERM] Received firmware download request from the device.")
- if os.path.exists(self.kernel_image):
- self.write_exact(sfl_magic_ack)
- self.upload(self.kernel_image, self.kernel_address)
- self.boot()
- print("[FLTERM] Done.");
-
- def reader(self):
- try:
- while self.reader_alive:
- c = character(self.serial.read())
- if c == '\r':
- sys.stdout.write('\n')
- else:
- sys.stdout.write(c)
- sys.stdout.flush()
-
- if self.kernel_image is not None:
- if self.detect_magic(c):
- self.answer_magic()
-
- except serial.SerialException:
- self.reader_alive = False
- raise
-
- def start_reader(self):
- self.reader_alive = True
- self.reader_thread = threading.Thread(target=self.reader)
- self.reader_thread.setDaemon(True)
- self.reader_thread.start()
-
- def stop_reader(self):
- self.reader_alive = False
- self.reader_thread.join()
-
- def writer(self):
- try:
- while self.writer_alive:
- try:
- b = console.getkey()
- except KeyboardInterrupt:
- b = serial.to_bytes([3])
- c = character(b)
- if c == chr(0x03):
- self.stop()
- elif c == '\n':
- self.serial.write(LF)
- else:
- self.serial.write(b)
- except:
- self.writer_alive = False
- raise
-
- def start_writer(self):
- self.writer_alive = True
- self.writer_thread = threading.Thread(target=self.writer)
- self.writer_thread.setDaemon(True)
- self.writer_thread.start()
-
- def stop_writer(self):
- self.writer_alive = False
- self.writer_thread.join()
-
- def start(self):
- print("[FLTERM] Starting....")
- self.start_reader()
- self.start_writer()
-
- def stop(self):
- self.reader_alive = False
- self.writer_alive = False
-
- def join(self, writer_only=False):
- self.writer_thread.join()
- if not writer_only:
- self.reader_thread.join()
-
-
-def _get_args():
- parser = argparse.ArgumentParser()
- parser.add_argument("port", help="serial port")
- parser.add_argument("--speed", default=115200, help="serial baudrate")
- parser.add_argument("--kernel", default=None, help="kernel image")
- parser.add_argument("--kernel-adr", type=lambda a: int(a, 0), default=0x40000000, help="kernel address")
- return parser.parse_args()
-
-
-def main():
- args = _get_args()
- flterm = Flterm(args.kernel, args.kernel_adr)
- flterm.open(args.port, args.speed)
- flterm.start()
- try:
- flterm.join(True)
- except KeyboardInterrupt:
- pass
- flterm.join()
-
-
-if __name__ == "__main__":
- main()
+++ /dev/null
-#!/usr/bin/env python3
-
-import argparse
-import binascii
-
-
-def insert_crc(i_filename, fbi_mode=False, o_filename=None):
- if o_filename is None:
- o_filename = i_filename
-
- with open(i_filename, "rb") as f:
- fdata = f.read()
- fcrc = binascii.crc32(fdata).to_bytes(4, byteorder="big")
- flength = len(fdata).to_bytes(4, byteorder="big")
-
- with open(o_filename, "wb") as f:
- if fbi_mode:
- f.write(flength)
- f.write(fcrc)
- f.write(fdata)
- else:
- f.write(fdata)
- f.write(fcrc)
-
-
-def main():
- parser = argparse.ArgumentParser(description="CRC32 computation tool and MiSoC image file writer.")
- parser.add_argument("input", help="input file")
- parser.add_argument("-o", "--output", default=None, help="output file (if not specified, use input file)")
- parser.add_argument("-f", "--fbi", default=False, action="store_true", help="build flash boot image (FBI) file")
- args = parser.parse_args()
- insert_crc(args.input, args.fbi, args.output)
-
-
-if __name__ == "__main__":
- main()
+++ /dev/null
-#!/usr/bin/env python3
-
-import sys
-from setuptools import setup
-from setuptools import find_packages
-
-
-if sys.version_info[:3] < (3, 3):
- raise SystemExit("You need Python 3.3+")
-
-
-setup(
- name="misoc",
- version="0.1",
- description="a high performance and small footprint SoC based on Migen",
- long_description=open("README").read(),
- author="Sebastien Bourdeauducq",
- author_email="sb@m-labs.hk",
- url="http://m-labs.hk",
- download_url="https://github.com/m-labs/misoc",
- license="BSD",
- platforms=["Any"],
- keywords="HDL ASIC FPGA hardware design",
- classifiers=[
- "Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
- "Environment :: Console",
- "Development Status :: Alpha",
- "Intended Audience :: Developers",
- "License :: OSI Approved :: BSD License",
- "Operating System :: OS Independent",
- "Programming Language :: Python",
- ],
- packages=find_packages(),
- include_package_data=True,
- entry_points={
- "console_scripts": [
- "flterm=misoc.tools.flterm:main",
- "mkmscimg=misoc.tools.mkmscimg:main",
- ],
- },
-)
--- /dev/null
+include ../include/generated/variables.mak
+include $(SOC_DIRECTORY)/software/common.mak
+
+OBJECTS=isr.o sdram.o main.o boot-helper-$(CPU).o boot.o dataflow.o
+
+all: bios.bin
+
+%.bin: %.elf
+ $(OBJCOPY) -O binary $< $@
+ chmod -x $@
+ $(PYTHON) -m litex.soc.tools.mkmscimg $@
+
+bios.elf: $(BIOS_DIRECTORY)/linker.ld $(OBJECTS)
+
+%.elf:
+ $(LD) $(LDFLAGS) -T $< -N -o $@ \
+ ../libbase/crt0-$(CPU).o \
+ $(OBJECTS) \
+ -L../libnet \
+ -L../libbase \
+ -L../libcompiler_rt \
+ -lnet -lbase-nofloat -lcompiler_rt
+ chmod -x $@
+
+main.o: $(BIOS_DIRECTORY)/main.c
+ $(compile)
+
+%.o: $(BIOS_DIRECTORY)/%.c
+ $(compile)
+
+%.o: $(BIOS_DIRECTORY)/%.S
+ $(assemble)
+
+clean:
+ $(RM) $(OBJECTS) bios.elf bios.bin .*~ *~
+
+.PHONY: all clean main.o
--- /dev/null
+.section .text, "ax", @progbits
+.global boot_helper
+boot_helper:
+ call r4
--- /dev/null
+.section .text, "ax", @progbits
+.global boot_helper
+boot_helper:
+ l.jr r6
+ l.nop
--- /dev/null
+#include <stdio.h>
+#include <console.h>
+#include <uart.h>
+#include <system.h>
+#include <crc.h>
+#include <string.h>
+#include <irq.h>
+
+#include <generated/mem.h>
+#include <generated/csr.h>
+
+#include <net/microudp.h>
+#include <net/tftp.h>
+#include "sfl.h"
+#include "boot.h"
+
+extern void boot_helper(unsigned int r1, unsigned int r2, unsigned int r3, unsigned int addr);
+
+static void __attribute__((noreturn)) boot(unsigned int r1, unsigned int r2, unsigned int r3, unsigned int addr)
+{
+ printf("Executing booted program.\n");
+ uart_sync();
+ irq_setmask(0);
+ irq_setie(0);
+ flush_cpu_icache();
+ boot_helper(r1, r2, r3, addr);
+ while(1);
+}
+
+static int check_ack(void)
+{
+ int recognized;
+ static const char str[SFL_MAGIC_LEN] = SFL_MAGIC_ACK;
+
+ timer0_en_write(0);
+ timer0_reload_write(0);
+ timer0_load_write(identifier_frequency_read()/4);
+ timer0_en_write(1);
+ timer0_update_value_write(1);
+ recognized = 0;
+ while(timer0_value_read()) {
+ if(uart_read_nonblock()) {
+ char c;
+ c = uart_read();
+ if(c == str[recognized]) {
+ recognized++;
+ if(recognized == SFL_MAGIC_LEN)
+ return 1;
+ } else {
+ if(c == str[0])
+ recognized = 1;
+ else
+ recognized = 0;
+ }
+ }
+ timer0_update_value_write(1);
+ }
+ return 0;
+}
+
+#define MAX_FAILED 5
+
+void serialboot(void)
+{
+ struct sfl_frame frame;
+ int failed;
+ unsigned int cmdline_adr, initrdstart_adr, initrdend_adr;
+ static const char str[SFL_MAGIC_LEN+1] = SFL_MAGIC_REQ;
+ const char *c;
+
+ printf("Booting from serial...\n");
+
+ c = str;
+ while(*c) {
+ uart_write(*c);
+ c++;
+ }
+ if(!check_ack()) {
+ printf("Timeout\n");
+ return;
+ }
+
+ failed = 0;
+ cmdline_adr = initrdstart_adr = initrdend_adr = 0;
+ while(1) {
+ int i;
+ int actualcrc;
+ int goodcrc;
+
+ /* Grab one frame */
+ frame.length = uart_read();
+ frame.crc[0] = uart_read();
+ frame.crc[1] = uart_read();
+ frame.cmd = uart_read();
+ for(i=0;i<frame.length;i++)
+ frame.payload[i] = uart_read();
+
+ /* Check CRC */
+ actualcrc = ((int)frame.crc[0] << 8)|(int)frame.crc[1];
+ goodcrc = crc16(&frame.cmd, frame.length+1);
+ if(actualcrc != goodcrc) {
+ failed++;
+ if(failed == MAX_FAILED) {
+ printf("Too many consecutive errors, aborting");
+ return;
+ }
+ uart_write(SFL_ACK_CRCERROR);
+ continue;
+ }
+
+ /* CRC OK */
+ switch(frame.cmd) {
+ case SFL_CMD_ABORT:
+ failed = 0;
+ uart_write(SFL_ACK_SUCCESS);
+ return;
+ case SFL_CMD_LOAD: {
+ char *writepointer;
+
+ failed = 0;
+ writepointer = (char *)(
+ ((unsigned int)frame.payload[0] << 24)
+ |((unsigned int)frame.payload[1] << 16)
+ |((unsigned int)frame.payload[2] << 8)
+ |((unsigned int)frame.payload[3] << 0));
+ for(i=4;i<frame.length;i++)
+ *(writepointer++) = frame.payload[i];
+ uart_write(SFL_ACK_SUCCESS);
+ break;
+ }
+ case SFL_CMD_JUMP: {
+ unsigned int addr;
+
+ failed = 0;
+ addr = ((unsigned int)frame.payload[0] << 24)
+ |((unsigned int)frame.payload[1] << 16)
+ |((unsigned int)frame.payload[2] << 8)
+ |((unsigned int)frame.payload[3] << 0);
+ uart_write(SFL_ACK_SUCCESS);
+ boot(cmdline_adr, initrdstart_adr, initrdend_adr, addr);
+ break;
+ }
+ case SFL_CMD_CMDLINE:
+ failed = 0;
+ cmdline_adr = ((unsigned int)frame.payload[0] << 24)
+ |((unsigned int)frame.payload[1] << 16)
+ |((unsigned int)frame.payload[2] << 8)
+ |((unsigned int)frame.payload[3] << 0);
+ uart_write(SFL_ACK_SUCCESS);
+ break;
+ case SFL_CMD_INITRDSTART:
+ failed = 0;
+ initrdstart_adr = ((unsigned int)frame.payload[0] << 24)
+ |((unsigned int)frame.payload[1] << 16)
+ |((unsigned int)frame.payload[2] << 8)
+ |((unsigned int)frame.payload[3] << 0);
+ uart_write(SFL_ACK_SUCCESS);
+ break;
+ case SFL_CMD_INITRDEND:
+ failed = 0;
+ initrdend_adr = ((unsigned int)frame.payload[0] << 24)
+ |((unsigned int)frame.payload[1] << 16)
+ |((unsigned int)frame.payload[2] << 8)
+ |((unsigned int)frame.payload[3] << 0);
+ uart_write(SFL_ACK_SUCCESS);
+ break;
+ default:
+ failed++;
+ if(failed == MAX_FAILED) {
+ printf("Too many consecutive errors, aborting");
+ return;
+ }
+ uart_write(SFL_ACK_UNKNOWN);
+ break;
+ }
+ }
+}
+
+#ifdef CSR_ETHMAC_BASE
+
+#define LOCALIP1 192
+#define LOCALIP2 168
+#define LOCALIP3 0
+#define LOCALIP4 42
+#define REMOTEIP1 192
+#define REMOTEIP2 168
+#define REMOTEIP3 0
+#define REMOTEIP4 14
+
+static int tftp_get_v(unsigned int ip, const char *filename, char *buffer)
+{
+ int r;
+
+ r = tftp_get(ip, filename, buffer);
+ if(r > 0)
+ printf("Successfully downloaded %d bytes from %s over TFTP\n", r, filename);
+ else
+ printf("Unable to download %s over TFTP\n", filename);
+ return r;
+}
+
+static const unsigned char macadr[6] = {0x10, 0xe2, 0xd5, 0x00, 0x00, 0x00};
+
+void netboot(void)
+{
+ int size;
+ unsigned int cmdline_adr, initrdstart_adr, initrdend_adr;
+ unsigned int ip;
+
+ printf("Booting from network...\n");
+ printf("Local IP : %d.%d.%d.%d\n", LOCALIP1, LOCALIP2, LOCALIP3, LOCALIP4);
+ printf("Remote IP: %d.%d.%d.%d\n", REMOTEIP1, REMOTEIP2, REMOTEIP3, REMOTEIP4);
+
+ ip = IPTOINT(REMOTEIP1, REMOTEIP2, REMOTEIP3, REMOTEIP4);
+
+ microudp_start(macadr, IPTOINT(LOCALIP1, LOCALIP2, LOCALIP3, LOCALIP4));
+
+ if(tftp_get_v(ip, "boot.bin", (void *)MAIN_RAM_BASE) <= 0) {
+ printf("Network boot failed\n");
+ return;
+ }
+
+ cmdline_adr = MAIN_RAM_BASE+0x1000000;
+ size = tftp_get_v(ip, "cmdline.txt", (void *)cmdline_adr);
+ if(size <= 0) {
+ printf("No command line parameters found\n");
+ cmdline_adr = 0;
+ } else
+ *((char *)(cmdline_adr+size)) = 0x00;
+
+ initrdstart_adr = MAIN_RAM_BASE+0x1002000;
+ size = tftp_get_v(ip, "initrd.bin", (void *)initrdstart_adr);
+ if(size <= 0) {
+ printf("No initial ramdisk found\n");
+ initrdstart_adr = 0;
+ initrdend_adr = 0;
+ } else
+ initrdend_adr = initrdstart_adr + size;
+
+ boot(cmdline_adr, initrdstart_adr, initrdend_adr, MAIN_RAM_BASE);
+}
+
+#endif
+
+#ifdef FLASH_BOOT_ADDRESS
+void flashboot(void)
+{
+ unsigned int *flashbase;
+ unsigned int length;
+ unsigned int crc;
+ unsigned int got_crc;
+
+ printf("Booting from flash...\n");
+ flashbase = (unsigned int *)FLASH_BOOT_ADDRESS;
+ length = *flashbase++;
+ crc = *flashbase++;
+ if((length < 32) || (length > 4*1024*1024)) {
+ printf("Error: Invalid flash boot image length 0x%08x\n", length);
+ return;
+ }
+
+ printf("Loading %d bytes from flash...\n", length);
+ memcpy((void *)MAIN_RAM_BASE, flashbase, length);
+ got_crc = crc32((unsigned char *)MAIN_RAM_BASE, length);
+ if(crc != got_crc) {
+ printf("CRC failed (expected %08x, got %08x)\n", crc, got_crc);
+ return;
+ }
+ boot(0, 0, 0, MAIN_RAM_BASE);
+}
+#endif
+
+#ifdef ROM_BOOT_ADDRESS
+/* When firmware is small enough, it can be interesting to run code from an
+ embedded blockram memory (faster and not impacted by memory controller
+ activity). Define ROM_BOOT_ADDRESS for that and initialize the blockram
+ with the firmware data. */
+void romboot(void)
+{
+ boot(0, 0, 0, ROM_BOOT_ADDRESS);
+}
+#endif
--- /dev/null
+#ifndef __BOOT_H
+#define __BOOT_H
+
+void serialboot(void);
+void netboot(void);
+void flashboot(void);
+void romboot(void);
+
+#endif /* __BOOT_H */
--- /dev/null
+#include <stdio.h>
+
+#include "dataflow.h"
+
+void print_isd_info(unsigned int baseaddr)
+{
+ volatile unsigned int *regs;
+ int neps;
+ int nbytes;
+ int i, j;
+ int offset;
+ unsigned int ack_count, nack_count, cur_status;
+
+ regs = (unsigned int *)baseaddr;
+ if((regs[0] != 0x6a) || (regs[1] != 0xb4)) {
+ printf("Incorrect magic number\n");
+ return;
+ }
+ neps = regs[2];
+ nbytes = (regs[3] + 7)/8;
+
+ regs[4] = 1; // freeze
+ offset = 6; // regs[5] is reset
+ for(i=0;i<neps;i++) {
+ ack_count = 0;
+ for(j=0;j<nbytes;j++) {
+ ack_count <<= 8;
+ ack_count |= regs[offset++];
+ }
+ nack_count = 0;
+ for(j=0;j<nbytes;j++) {
+ nack_count <<= 8;
+ nack_count |= regs[offset++];
+ }
+ cur_status = regs[offset++];
+ printf("#%d: ACK_CNT:%10u NAK_CNT:%10u %s %s\n",
+ i, ack_count, nack_count,
+ cur_status & 1 ? "stb" : " ",
+ cur_status & 2 ? "ack" : " ");
+ }
+ regs[4] = 0; // unfreeze
+}
--- /dev/null
+#ifndef __DATAFLOW_H
+#define __DATAFLOW_H
+
+void print_isd_info(unsigned int baseaddr);
+
+#endif /* __DATAFLOW_H */
+
--- /dev/null
+#include <generated/csr.h>
+#include <irq.h>
+#include <uart.h>
+
+void isr(void);
+void isr(void)
+{
+ unsigned int irqs;
+
+ irqs = irq_pending() & irq_getmask();
+
+ if(irqs & (1 << UART_INTERRUPT))
+ uart_isr();
+}
--- /dev/null
+INCLUDE generated/output_format.ld
+ENTRY(_start)
+
+INCLUDE generated/regions.ld
+
+SECTIONS
+{
+ .text :
+ {
+ _ftext = .;
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ _etext = .;
+ } > rom
+
+ .rodata :
+ {
+ . = ALIGN(4);
+ _frodata = .;
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.rodata1)
+
+ /* Make sure the file is aligned on disk as well
+ as in memory; CRC calculation requires that. */
+ FILL(0);
+ . = ALIGN(4);
+ _erodata = .;
+ } > rom
+
+ .bss :
+ {
+ . = ALIGN(4);
+ _fbss = .;
+ *(.dynsbss)
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = .;
+ _end = .;
+ } > sram
+
+ /DISCARD/ :
+ {
+ *(.eh_frame)
+ *(.comment)
+ *(.data .data.* .gnu.linkonce.d.*)
+ *(.data1)
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ }
+}
+
+PROVIDE(_fstack = ORIGIN(sram) + LENGTH(sram) - 4);
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <console.h>
+#include <string.h>
+#include <uart.h>
+#include <system.h>
+#include <id.h>
+#include <irq.h>
+#include <crc.h>
+
+#include <generated/csr.h>
+#include <generated/mem.h>
+#include <net/microudp.h>
+
+#include "sdram.h"
+#include "dataflow.h"
+#include "boot.h"
+
+/* General address space functions */
+
+#define NUMBER_OF_BYTES_ON_A_LINE 16
+static void dump_bytes(unsigned int *ptr, int count, unsigned addr)
+{
+ char *data = (char *)ptr;
+ int line_bytes = 0, i = 0;
+
+ putsnonl("Memory dump:");
+ while(count > 0){
+ line_bytes =
+ (count > NUMBER_OF_BYTES_ON_A_LINE)?
+ NUMBER_OF_BYTES_ON_A_LINE : count;
+
+ printf("\n0x%08x ", addr);
+ for(i=0;i<line_bytes;i++)
+ printf("%02x ", *(unsigned char *)(data+i));
+
+ for(;i<NUMBER_OF_BYTES_ON_A_LINE;i++)
+ printf(" ");
+
+ printf(" ");
+
+ for(i=0;i<line_bytes;i++) {
+ if((*(data+i) < 0x20) || (*(data+i) > 0x7e))
+ printf(".");
+ else
+ printf("%c", *(data+i));
+ }
+
+ for(;i<NUMBER_OF_BYTES_ON_A_LINE;i++)
+ printf(" ");
+
+ data += (char)line_bytes;
+ count -= line_bytes;
+ addr += line_bytes;
+ }
+ printf("\n");
+}
+
+static void mr(char *startaddr, char *len)
+{
+ char *c;
+ unsigned int *addr;
+ unsigned int length;
+
+ if(*startaddr == 0) {
+ printf("mr <address> [length]\n");
+ return;
+ }
+ addr = (unsigned *)strtoul(startaddr, &c, 0);
+ if(*c != 0) {
+ printf("incorrect address\n");
+ return;
+ }
+ if(*len == 0) {
+ length = 4;
+ } else {
+ length = strtoul(len, &c, 0);
+ if(*c != 0) {
+ printf("incorrect length\n");
+ return;
+ }
+ }
+
+ dump_bytes(addr, length, (unsigned)addr);
+}
+
+static void mw(char *addr, char *value, char *count)
+{
+ char *c;
+ unsigned int *addr2;
+ unsigned int value2;
+ unsigned int count2;
+ unsigned int i;
+
+ if((*addr == 0) || (*value == 0)) {
+ printf("mw <address> <value> [count]\n");
+ return;
+ }
+ addr2 = (unsigned int *)strtoul(addr, &c, 0);
+ if(*c != 0) {
+ printf("incorrect address\n");
+ return;
+ }
+ value2 = strtoul(value, &c, 0);
+ if(*c != 0) {
+ printf("incorrect value\n");
+ return;
+ }
+ if(*count == 0) {
+ count2 = 1;
+ } else {
+ count2 = strtoul(count, &c, 0);
+ if(*c != 0) {
+ printf("incorrect count\n");
+ return;
+ }
+ }
+ for (i=0;i<count2;i++) *addr2++ = value2;
+}
+
+static void mc(char *dstaddr, char *srcaddr, char *count)
+{
+ char *c;
+ unsigned int *dstaddr2;
+ unsigned int *srcaddr2;
+ unsigned int count2;
+ unsigned int i;
+
+ if((*dstaddr == 0) || (*srcaddr == 0)) {
+ printf("mc <dst> <src> [count]\n");
+ return;
+ }
+ dstaddr2 = (unsigned int *)strtoul(dstaddr, &c, 0);
+ if(*c != 0) {
+ printf("incorrect destination address\n");
+ return;
+ }
+ srcaddr2 = (unsigned int *)strtoul(srcaddr, &c, 0);
+ if(*c != 0) {
+ printf("incorrect source address\n");
+ return;
+ }
+ if(*count == 0) {
+ count2 = 1;
+ } else {
+ count2 = strtoul(count, &c, 0);
+ if(*c != 0) {
+ printf("incorrect count\n");
+ return;
+ }
+ }
+ for (i=0;i<count2;i++) *dstaddr2++ = *srcaddr2++;
+}
+
+static void crc(char *startaddr, char *len)
+{
+ char *c;
+ char *addr;
+ unsigned int length;
+
+ if((*startaddr == 0)||(*len == 0)) {
+ printf("crc <address> <length>\n");
+ return;
+ }
+ addr = (char *)strtoul(startaddr, &c, 0);
+ if(*c != 0) {
+ printf("incorrect address\n");
+ return;
+ }
+ length = strtoul(len, &c, 0);
+ if(*c != 0) {
+ printf("incorrect length\n");
+ return;
+ }
+
+ printf("CRC32: %08x\n", crc32((unsigned char *)addr, length));
+}
+
+#ifdef __lm32__
+enum {
+ CSR_IE = 1, CSR_IM, CSR_IP, CSR_ICC, CSR_DCC, CSR_CC, CSR_CFG, CSR_EBA,
+ CSR_DC, CSR_DEBA, CSR_JTX, CSR_JRX, CSR_BP0, CSR_BP1, CSR_BP2, CSR_BP3,
+ CSR_WP0, CSR_WP1, CSR_WP2, CSR_WP3,
+};
+
+/* processor registers */
+static int parse_csr(const char *csr)
+{
+ if(!strcmp(csr, "ie")) return CSR_IE;
+ if(!strcmp(csr, "im")) return CSR_IM;
+ if(!strcmp(csr, "ip")) return CSR_IP;
+ if(!strcmp(csr, "icc")) return CSR_ICC;
+ if(!strcmp(csr, "dcc")) return CSR_DCC;
+ if(!strcmp(csr, "cc")) return CSR_CC;
+ if(!strcmp(csr, "cfg")) return CSR_CFG;
+ if(!strcmp(csr, "eba")) return CSR_EBA;
+ if(!strcmp(csr, "dc")) return CSR_DC;
+ if(!strcmp(csr, "deba")) return CSR_DEBA;
+ if(!strcmp(csr, "jtx")) return CSR_JTX;
+ if(!strcmp(csr, "jrx")) return CSR_JRX;
+ if(!strcmp(csr, "bp0")) return CSR_BP0;
+ if(!strcmp(csr, "bp1")) return CSR_BP1;
+ if(!strcmp(csr, "bp2")) return CSR_BP2;
+ if(!strcmp(csr, "bp3")) return CSR_BP3;
+ if(!strcmp(csr, "wp0")) return CSR_WP0;
+ if(!strcmp(csr, "wp1")) return CSR_WP1;
+ if(!strcmp(csr, "wp2")) return CSR_WP2;
+ if(!strcmp(csr, "wp3")) return CSR_WP3;
+
+ return 0;
+}
+
+static void rcsr(char *csr)
+{
+ unsigned int csr2;
+ register unsigned int value;
+
+ if(*csr == 0) {
+ printf("rcsr <csr>\n");
+ return;
+ }
+
+ csr2 = parse_csr(csr);
+ if(csr2 == 0) {
+ printf("incorrect csr\n");
+ return;
+ }
+
+ switch(csr2) {
+ case CSR_IE: asm volatile ("rcsr %0,ie":"=r"(value)); break;
+ case CSR_IM: asm volatile ("rcsr %0,im":"=r"(value)); break;
+ case CSR_IP: asm volatile ("rcsr %0,ip":"=r"(value)); break;
+ case CSR_CC: asm volatile ("rcsr %0,cc":"=r"(value)); break;
+ case CSR_CFG: asm volatile ("rcsr %0,cfg":"=r"(value)); break;
+ case CSR_EBA: asm volatile ("rcsr %0,eba":"=r"(value)); break;
+ case CSR_DEBA: asm volatile ("rcsr %0,deba":"=r"(value)); break;
+ case CSR_JTX: asm volatile ("rcsr %0,jtx":"=r"(value)); break;
+ case CSR_JRX: asm volatile ("rcsr %0,jrx":"=r"(value)); break;
+ default: printf("csr write only\n"); return;
+ }
+
+ printf("%08x\n", value);
+}
+
+static void wcsr(char *csr, char *value)
+{
+ char *c;
+ unsigned int csr2;
+ register unsigned int value2;
+
+ if((*csr == 0) || (*value == 0)) {
+ printf("wcsr <csr> <address>\n");
+ return;
+ }
+
+ csr2 = parse_csr(csr);
+ if(csr2 == 0) {
+ printf("incorrect csr\n");
+ return;
+ }
+ value2 = strtoul(value, &c, 0);
+ if(*c != 0) {
+ printf("incorrect value\n");
+ return;
+ }
+
+ switch(csr2) {
+ case CSR_IE: asm volatile ("wcsr ie,%0"::"r"(value2)); break;
+ case CSR_IM: asm volatile ("wcsr im,%0"::"r"(value2)); break;
+ case CSR_ICC: asm volatile ("wcsr icc,%0"::"r"(value2)); break;
+ case CSR_DCC: asm volatile ("wcsr dcc,%0"::"r"(value2)); break;
+ case CSR_EBA: asm volatile ("wcsr eba,%0"::"r"(value2)); break;
+ case CSR_DC: asm volatile ("wcsr dcc,%0"::"r"(value2)); break;
+ case CSR_DEBA: asm volatile ("wcsr deba,%0"::"r"(value2)); break;
+ case CSR_JTX: asm volatile ("wcsr jtx,%0"::"r"(value2)); break;
+ case CSR_JRX: asm volatile ("wcsr jrx,%0"::"r"(value2)); break;
+ case CSR_BP0: asm volatile ("wcsr bp0,%0"::"r"(value2)); break;
+ case CSR_BP1: asm volatile ("wcsr bp1,%0"::"r"(value2)); break;
+ case CSR_BP2: asm volatile ("wcsr bp2,%0"::"r"(value2)); break;
+ case CSR_BP3: asm volatile ("wcsr bp3,%0"::"r"(value2)); break;
+ case CSR_WP0: asm volatile ("wcsr wp0,%0"::"r"(value2)); break;
+ case CSR_WP1: asm volatile ("wcsr wp1,%0"::"r"(value2)); break;
+ case CSR_WP2: asm volatile ("wcsr wp2,%0"::"r"(value2)); break;
+ case CSR_WP3: asm volatile ("wcsr wp3,%0"::"r"(value2)); break;
+ default: printf("csr read only\n"); return;
+ }
+}
+
+#endif /* __lm32__ */
+
+static void dfs(char *baseaddr)
+{
+ char *c;
+ unsigned int addr;
+
+ if(*baseaddr == 0) {
+ printf("dfs <address>\n");
+ return;
+ }
+ addr = strtoul(baseaddr, &c, 0);
+ if(*c != 0) {
+ printf("incorrect address\n");
+ return;
+ }
+ print_isd_info(addr);
+}
+
+/* Init + command line */
+
+static void help(void)
+{
+ puts("LiteX SoC BIOS");
+ puts("Available commands:");
+ puts("mr - read address space");
+ puts("mw - write address space");
+ puts("mc - copy address space");
+ puts("crc - compute CRC32 of a part of the address space");
+#ifdef __lm32__
+ puts("rcsr - read processor CSR");
+ puts("wcsr - write processor CSR");
+#endif
+#ifdef CSR_ETHMAC_BASE
+ puts("netboot - boot via TFTP");
+#endif
+ puts("serialboot - boot via SFL");
+#ifdef FLASH_BOOT_ADDRESS
+ puts("flashboot - boot from flash");
+#endif
+#ifdef ROM_BOOT_ADDRESS
+ puts("romboot - boot from embedded rom");
+#endif
+ puts("revision - display revision");
+#ifdef CSR_SDRAM_BASE
+ puts("memtest - run a memory test");
+#endif
+}
+
+static char *get_token(char **str)
+{
+ char *c, *d;
+
+ c = (char *)strchr(*str, ' ');
+ if(c == NULL) {
+ d = *str;
+ *str = *str+strlen(*str);
+ return d;
+ }
+ *c = 0;
+ d = *str;
+ *str = c+1;
+ return d;
+}
+
+static void do_command(char *c)
+{
+ char *token;
+
+ token = get_token(&c);
+
+ if(strcmp(token, "mr") == 0) mr(get_token(&c), get_token(&c));
+ else if(strcmp(token, "mw") == 0) mw(get_token(&c), get_token(&c), get_token(&c));
+ else if(strcmp(token, "mc") == 0) mc(get_token(&c), get_token(&c), get_token(&c));
+ else if(strcmp(token, "crc") == 0) crc(get_token(&c), get_token(&c));
+
+#ifdef L2_SIZE
+ else if(strcmp(token, "flushl2") == 0) flush_l2_cache();
+#endif
+
+#ifdef FLASH_BOOT_ADDRESS
+ else if(strcmp(token, "flashboot") == 0) flashboot();
+#endif
+#ifdef ROM_BOOT_ADDRESS
+ else if(strcmp(token, "romboot") == 0) romboot();
+#endif
+ else if(strcmp(token, "serialboot") == 0) serialboot();
+#ifdef CSR_ETHMAC_BASE
+ else if(strcmp(token, "netboot") == 0) netboot();
+#endif
+
+ else if(strcmp(token, "help") == 0) help();
+
+#ifdef __lm32__
+ else if(strcmp(token, "rcsr") == 0) rcsr(get_token(&c));
+ else if(strcmp(token, "wcsr") == 0) wcsr(get_token(&c), get_token(&c));
+#endif
+
+#ifdef CSR_SDRAM_BASE
+ else if(strcmp(token, "sdrrow") == 0) sdrrow(get_token(&c));
+ else if(strcmp(token, "sdrsw") == 0) sdrsw();
+ else if(strcmp(token, "sdrhw") == 0) sdrhw();
+ else if(strcmp(token, "sdrrdbuf") == 0) sdrrdbuf(-1);
+ else if(strcmp(token, "sdrrd") == 0) sdrrd(get_token(&c), get_token(&c));
+ else if(strcmp(token, "sdrrderr") == 0) sdrrderr(get_token(&c));
+ else if(strcmp(token, "sdrwr") == 0) sdrwr(get_token(&c));
+#ifdef CSR_DDRPHY_BASE
+ else if(strcmp(token, "sdrwlon") == 0) sdrwlon();
+ else if(strcmp(token, "sdrwloff") == 0) sdrwloff();
+ else if(strcmp(token, "sdrlevel") == 0) sdrlevel();
+#endif
+ else if(strcmp(token, "memtest") == 0) memtest();
+ else if(strcmp(token, "sdrinit") == 0) sdrinit();
+#endif
+
+ else if(strcmp(token, "dfs") == 0) dfs(get_token(&c));
+
+ else if(strcmp(token, "") != 0)
+ printf("Command not found\n");
+}
+
+extern unsigned int _ftext, _erodata;
+
+static void crcbios(void)
+{
+ unsigned int offset_bios;
+ unsigned int length;
+ unsigned int expected_crc;
+ unsigned int actual_crc;
+
+ /*
+ * _erodata is located right after the end of the flat
+ * binary image. The CRC tool writes the 32-bit CRC here.
+ * We also use the address of _erodata to know the length
+ * of our code.
+ */
+ offset_bios = (unsigned int)&_ftext;
+ expected_crc = _erodata;
+ length = (unsigned int)&_erodata - offset_bios;
+ actual_crc = crc32((unsigned char *)offset_bios, length);
+ if(expected_crc == actual_crc)
+ printf("BIOS CRC passed (%08x)\n", actual_crc);
+ else {
+ printf("BIOS CRC failed (expected %08x, got %08x)\n", expected_crc, actual_crc);
+ printf("The system will continue, but expect problems.\n");
+ }
+}
+
+static void readstr(char *s, int size)
+{
+ char c[2];
+ int ptr;
+
+ c[1] = 0;
+ ptr = 0;
+ while(1) {
+ c[0] = readchar();
+ switch(c[0]) {
+ case 0x7f:
+ case 0x08:
+ if(ptr > 0) {
+ ptr--;
+ putsnonl("\x08 \x08");
+ }
+ break;
+ case 0x07:
+ break;
+ case '\r':
+ case '\n':
+ s[ptr] = 0x00;
+ putsnonl("\n");
+ return;
+ default:
+ putsnonl(c);
+ s[ptr] = c[0];
+ ptr++;
+ break;
+ }
+ }
+}
+
+static int test_user_abort(void)
+{
+ char c;
+
+ printf("Automatic boot in 2 seconds...\n");
+ printf("Q/ESC: abort boot\n");
+ printf("F7: boot from serial\n");
+#ifdef CSR_ETHMAC_BASE
+ printf("F8: boot from network\n");
+#endif
+ timer0_en_write(0);
+ timer0_reload_write(0);
+ timer0_load_write(identifier_frequency_read()*2);
+ timer0_en_write(1);
+ timer0_update_value_write(1);
+ while(timer0_value_read()) {
+ if(readchar_nonblock()) {
+ c = readchar();
+ if((c == 'Q')||(c == '\e')) {
+ puts("Aborted");
+ return 0;
+ }
+ if(c == 0x06) {
+ serialboot();
+ return 0;
+ }
+#ifdef CSR_ETHMAC_BASE
+ if(c == 0x07) {
+ netboot();
+ return 0;
+ }
+#endif
+ }
+ timer0_update_value_write(1);
+ }
+ return 1;
+}
+
+static void boot_sequence(void)
+{
+ if(test_user_abort()) {
+#ifdef FLASH_BOOT_ADDRESS
+ flashboot();
+#endif
+ serialboot();
+#ifdef CSR_ETHMAC_BASE
+#ifdef CSR_ETHPHY_MODE_DETECTION_MODE_ADDR
+ eth_mode();
+#endif
+ netboot();
+#endif
+#ifdef ROM_BOOT_ADDRESS
+ romboot();
+#endif
+ printf("No boot medium found\n");
+ }
+}
+
+int main(int i, char **c)
+{
+ char buffer[64];
+ int sdr_ok;
+
+ irq_setmask(0);
+ irq_setie(1);
+ uart_init();
+ puts("\nLiteX SoC BIOS\n"
+ "(c) Copyright 2015 Enjoy-Digital\n"
+ "(c) Copyright 2007-2015 M-Labs Limited\n"
+ "Built "__DATE__" "__TIME__"\n");
+ crcbios();
+ id_print();
+#ifdef CSR_ETHMAC_BASE
+ eth_init();
+#endif
+#ifdef CSR_SDRAM_BASE
+ sdr_ok = sdrinit();
+#else
+ sdr_ok = 1;
+#endif
+ if(sdr_ok)
+ boot_sequence();
+ else
+ printf("Memory initialization failed\n");
+
+ while(1) {
+ putsnonl("\e[1mBIOS>\e[0m ");
+ readstr(buffer, 64);
+ do_command(buffer);
+ }
+ return 0;
+}
--- /dev/null
+#include <generated/csr.h>
+#ifdef CSR_SDRAM_BASE
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <generated/sdram_phy.h>
+#include <generated/mem.h>
+#include <hw/flags.h>
+#include <system.h>
+
+#include "sdram.h"
+
+static void cdelay(int i)
+{
+ while(i > 0) {
+#if defined (__lm32__)
+ __asm__ volatile("nop");
+#elif defined (__or1k__)
+ __asm__ volatile("l.nop");
+#else
+#error Unsupported architecture
+#endif
+ i--;
+ }
+}
+
+void sdrsw(void)
+{
+ sdram_dfii_control_write(DFII_CONTROL_CKE|DFII_CONTROL_ODT|DFII_CONTROL_RESET_N);
+ printf("SDRAM now under software control\n");
+}
+
+void sdrhw(void)
+{
+ sdram_dfii_control_write(DFII_CONTROL_SEL);
+ printf("SDRAM now under hardware control\n");
+}
+
+void sdrrow(char *_row)
+{
+ char *c;
+ unsigned int row;
+
+ if(*_row == 0) {
+ sdram_dfii_pi0_address_write(0x0000);
+ sdram_dfii_pi0_baddress_write(0);
+ command_p0(DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
+ cdelay(15);
+ printf("Precharged\n");
+ } else {
+ row = strtoul(_row, &c, 0);
+ if(*c != 0) {
+ printf("incorrect row\n");
+ return;
+ }
+ sdram_dfii_pi0_address_write(row);
+ sdram_dfii_pi0_baddress_write(0);
+ command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CS);
+ cdelay(15);
+ printf("Activated row %d\n", row);
+ }
+}
+
+void sdrrdbuf(int dq)
+{
+ int i, p;
+ int first_byte, step;
+
+ if(dq < 0) {
+ first_byte = 0;
+ step = 1;
+ } else {
+ first_byte = DFII_PIX_DATA_SIZE/2 - 1 - dq;
+ step = DFII_PIX_DATA_SIZE/2;
+ }
+
+ for(p=0;p<DFII_NPHASES;p++)
+ for(i=first_byte;i<DFII_PIX_DATA_SIZE;i+=step)
+ printf("%02x", MMPTR(sdram_dfii_pix_rddata_addr[p]+4*i));
+ printf("\n");
+}
+
+void sdrrd(char *startaddr, char *dq)
+{
+ char *c;
+ unsigned int addr;
+ int _dq;
+
+ if(*startaddr == 0) {
+ printf("sdrrd <address>\n");
+ return;
+ }
+ addr = strtoul(startaddr, &c, 0);
+ if(*c != 0) {
+ printf("incorrect address\n");
+ return;
+ }
+ if(*dq == 0)
+ _dq = -1;
+ else {
+ _dq = strtoul(dq, &c, 0);
+ if(*c != 0) {
+ printf("incorrect DQ\n");
+ return;
+ }
+ }
+
+ sdram_dfii_pird_address_write(addr);
+ sdram_dfii_pird_baddress_write(0);
+ command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
+ cdelay(15);
+ sdrrdbuf(_dq);
+}
+
+void sdrrderr(char *count)
+{
+ int addr;
+ char *c;
+ int _count;
+ int i, j, p;
+ unsigned char prev_data[DFII_NPHASES*DFII_PIX_DATA_SIZE];
+ unsigned char errs[DFII_NPHASES*DFII_PIX_DATA_SIZE];
+
+ if(*count == 0) {
+ printf("sdrrderr <count>\n");
+ return;
+ }
+ _count = strtoul(count, &c, 0);
+ if(*c != 0) {
+ printf("incorrect count\n");
+ return;
+ }
+
+ for(i=0;i<DFII_NPHASES*DFII_PIX_DATA_SIZE;i++)
+ errs[i] = 0;
+ for(addr=0;addr<16;addr++) {
+ sdram_dfii_pird_address_write(addr*8);
+ sdram_dfii_pird_baddress_write(0);
+ command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
+ cdelay(15);
+ for(p=0;p<DFII_NPHASES;p++)
+ for(i=0;i<DFII_PIX_DATA_SIZE;i++)
+ prev_data[p*DFII_PIX_DATA_SIZE+i] = MMPTR(sdram_dfii_pix_rddata_addr[p]+4*i);
+
+ for(j=0;j<_count;j++) {
+ command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
+ cdelay(15);
+ for(p=0;p<DFII_NPHASES;p++)
+ for(i=0;i<DFII_PIX_DATA_SIZE;i++) {
+ unsigned char new_data;
+
+ new_data = MMPTR(sdram_dfii_pix_rddata_addr[p]+4*i);
+ errs[p*DFII_PIX_DATA_SIZE+i] |= prev_data[p*DFII_PIX_DATA_SIZE+i] ^ new_data;
+ prev_data[p*DFII_PIX_DATA_SIZE+i] = new_data;
+ }
+ }
+ }
+
+ for(i=0;i<DFII_NPHASES*DFII_PIX_DATA_SIZE;i++)
+ printf("%02x", errs[i]);
+ printf("\n");
+ for(p=0;p<DFII_NPHASES;p++)
+ for(i=0;i<DFII_PIX_DATA_SIZE;i++)
+ printf("%2x", DFII_PIX_DATA_SIZE/2 - 1 - (i % (DFII_PIX_DATA_SIZE/2)));
+ printf("\n");
+}
+
+void sdrwr(char *startaddr)
+{
+ char *c;
+ unsigned int addr;
+ int i;
+ int p;
+
+ if(*startaddr == 0) {
+ printf("sdrrd <address>\n");
+ return;
+ }
+ addr = strtoul(startaddr, &c, 0);
+ if(*c != 0) {
+ printf("incorrect address\n");
+ return;
+ }
+
+ for(p=0;p<DFII_NPHASES;p++)
+ for(i=0;i<DFII_PIX_DATA_SIZE;i++)
+ MMPTR(sdram_dfii_pix_wrdata_addr[p]+4*i) = 0x10*p + i;
+
+ sdram_dfii_piwr_address_write(addr);
+ sdram_dfii_piwr_baddress_write(0);
+ command_pwr(DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS|DFII_COMMAND_WRDATA);
+}
+
+#ifdef CSR_DDRPHY_BASE
+
+void sdrwlon(void)
+{
+ sdram_dfii_pi0_address_write(DDR3_MR1 | (1 << 7));
+ sdram_dfii_pi0_baddress_write(1);
+ command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
+ ddrphy_wlevel_en_write(1);
+}
+
+void sdrwloff(void)
+{
+ sdram_dfii_pi0_address_write(DDR3_MR1);
+ sdram_dfii_pi0_baddress_write(1);
+ command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
+ ddrphy_wlevel_en_write(0);
+}
+
+#define ERR_DDRPHY_DELAY 32
+
+static int write_level(int *delay, int *high_skew)
+{
+ int i;
+ int dq_address;
+ unsigned char dq;
+ int ok;
+
+ printf("Write leveling: ");
+
+ sdrwlon();
+ cdelay(100);
+ for(i=0;i<DFII_PIX_DATA_SIZE/2;i++) {
+ dq_address = sdram_dfii_pix_rddata_addr[0]+4*(DFII_PIX_DATA_SIZE/2-1-i);
+ ddrphy_dly_sel_write(1 << i);
+ ddrphy_wdly_dq_rst_write(1);
+ ddrphy_wdly_dqs_rst_write(1);
+
+ delay[i] = 0;
+
+ ddrphy_wlevel_strobe_write(1);
+ cdelay(10);
+ dq = MMPTR(dq_address);
+ if(dq != 0) {
+ /*
+ * Assume this DQ group has between 1 and 2 bit times of skew.
+ * Bring DQS into the CK=0 zone before continuing leveling.
+ */
+ high_skew[i] = 1;
+ while(dq != 0) {
+ delay[i]++;
+ if(delay[i] >= ERR_DDRPHY_DELAY)
+ break;
+ ddrphy_wdly_dq_inc_write(1);
+ ddrphy_wdly_dqs_inc_write(1);
+ ddrphy_wlevel_strobe_write(1);
+ cdelay(10);
+ dq = MMPTR(dq_address);
+ }
+ } else
+ high_skew[i] = 0;
+
+ while(dq == 0) {
+ delay[i]++;
+ if(delay[i] >= ERR_DDRPHY_DELAY)
+ break;
+ ddrphy_wdly_dq_inc_write(1);
+ ddrphy_wdly_dqs_inc_write(1);
+
+ ddrphy_wlevel_strobe_write(1);
+ cdelay(10);
+ dq = MMPTR(dq_address);
+ }
+ }
+ sdrwloff();
+
+ ok = 1;
+ for(i=DFII_PIX_DATA_SIZE/2-1;i>=0;i--) {
+ printf("%2d%c ", delay[i], high_skew[i] ? '*' : ' ');
+ if(delay[i] >= ERR_DDRPHY_DELAY)
+ ok = 0;
+ }
+
+ if(ok)
+ printf("completed\n");
+ else
+ printf("failed\n");
+
+ return ok;
+}
+
+static void read_bitslip(int *delay, int *high_skew)
+{
+ int bitslip_thr;
+ int i;
+
+ bitslip_thr = 0x7fffffff;
+ for(i=0;i<DFII_PIX_DATA_SIZE/2;i++)
+ if(high_skew[i] && (delay[i] < bitslip_thr))
+ bitslip_thr = delay[i];
+ if(bitslip_thr == 0x7fffffff)
+ return;
+ bitslip_thr = bitslip_thr/2;
+
+ printf("Read bitslip: ");
+ for(i=DFII_PIX_DATA_SIZE/2-1;i>=0;i--)
+ if(delay[i] > bitslip_thr) {
+ ddrphy_dly_sel_write(1 << i);
+ /* 7-series SERDES in DDR mode needs 3 pulses for 1 bitslip */
+ ddrphy_rdly_dq_bitslip_write(1);
+ ddrphy_rdly_dq_bitslip_write(1);
+ ddrphy_rdly_dq_bitslip_write(1);
+ printf("%d ", i);
+ }
+ printf("\n");
+}
+
+static void read_delays(void)
+{
+ unsigned int prv;
+ unsigned char prs[DFII_NPHASES*DFII_PIX_DATA_SIZE];
+ int p, i, j;
+ int working;
+ int delay, delay_min, delay_max;
+
+ printf("Read delays: ");
+
+ /* Generate pseudo-random sequence */
+ prv = 42;
+ for(i=0;i<DFII_NPHASES*DFII_PIX_DATA_SIZE;i++) {
+ prv = 1664525*prv + 1013904223;
+ prs[i] = prv;
+ }
+
+ /* Activate */
+ sdram_dfii_pi0_address_write(0);
+ sdram_dfii_pi0_baddress_write(0);
+ command_p0(DFII_COMMAND_RAS|DFII_COMMAND_CS);
+ cdelay(15);
+
+ /* Write test pattern */
+ for(p=0;p<DFII_NPHASES;p++)
+ for(i=0;i<DFII_PIX_DATA_SIZE;i++)
+ MMPTR(sdram_dfii_pix_wrdata_addr[p]+4*i) = prs[DFII_PIX_DATA_SIZE*p+i];
+ sdram_dfii_piwr_address_write(0);
+ sdram_dfii_piwr_baddress_write(0);
+ command_pwr(DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS|DFII_COMMAND_WRDATA);
+
+ /* Calibrate each DQ in turn */
+ sdram_dfii_pird_address_write(0);
+ sdram_dfii_pird_baddress_write(0);
+ for(i=0;i<DFII_PIX_DATA_SIZE/2;i++) {
+ ddrphy_dly_sel_write(1 << (DFII_PIX_DATA_SIZE/2-i-1));
+ delay = 0;
+
+ /* Find smallest working delay */
+ ddrphy_rdly_dq_rst_write(1);
+ while(1) {
+ command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
+ cdelay(15);
+ working = 1;
+ for(p=0;p<DFII_NPHASES;p++) {
+ if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*i) != prs[DFII_PIX_DATA_SIZE*p+i])
+ working = 0;
+ if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*(i+DFII_PIX_DATA_SIZE/2)) != prs[DFII_PIX_DATA_SIZE*p+i+DFII_PIX_DATA_SIZE/2])
+ working = 0;
+ }
+ if(working)
+ break;
+ delay++;
+ if(delay >= ERR_DDRPHY_DELAY)
+ break;
+ ddrphy_rdly_dq_inc_write(1);
+ }
+ delay_min = delay;
+
+ /* Get a bit further into the working zone */
+ delay++;
+ ddrphy_rdly_dq_inc_write(1);
+
+ /* Find largest working delay */
+ while(1) {
+ command_prd(DFII_COMMAND_CAS|DFII_COMMAND_CS|DFII_COMMAND_RDDATA);
+ cdelay(15);
+ working = 1;
+ for(p=0;p<DFII_NPHASES;p++) {
+ if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*i) != prs[DFII_PIX_DATA_SIZE*p+i])
+ working = 0;
+ if(MMPTR(sdram_dfii_pix_rddata_addr[p]+4*(i+DFII_PIX_DATA_SIZE/2)) != prs[DFII_PIX_DATA_SIZE*p+i+DFII_PIX_DATA_SIZE/2])
+ working = 0;
+ }
+ if(!working)
+ break;
+ delay++;
+ if(delay >= ERR_DDRPHY_DELAY)
+ break;
+ ddrphy_rdly_dq_inc_write(1);
+ }
+ delay_max = delay;
+
+ printf("%d:%02d-%02d ", DFII_PIX_DATA_SIZE/2-i-1, delay_min, delay_max);
+
+ /* Set delay to the middle */
+ ddrphy_rdly_dq_rst_write(1);
+ for(j=0;j<(delay_min+delay_max)/2;j++)
+ ddrphy_rdly_dq_inc_write(1);
+ }
+
+ /* Precharge */
+ sdram_dfii_pi0_address_write(0);
+ sdram_dfii_pi0_baddress_write(0);
+ command_p0(DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS);
+ cdelay(15);
+
+ printf("completed\n");
+}
+
+int sdrlevel(void)
+{
+ int delay[DFII_PIX_DATA_SIZE/2];
+ int high_skew[DFII_PIX_DATA_SIZE/2];
+
+ if(!write_level(delay, high_skew))
+ return 0;
+ read_bitslip(delay, high_skew);
+ read_delays();
+
+ return 1;
+}
+
+#endif /* CSR_DDRPHY_BASE */
+
+#define TEST_DATA_SIZE (2*1024*1024)
+#define TEST_DATA_RANDOM 1
+
+#define TEST_ADDR_SIZE (32*1024)
+#define TEST_ADDR_RANDOM 0
+
+#define ONEZERO 0xAAAAAAAA
+#define ZEROONE 0x55555555
+
+static unsigned int seed_to_data_32(unsigned int seed, int random)
+{
+ if (random)
+ return 1664525*seed + 1013904223;
+ else
+ return seed + 1;
+}
+
+static unsigned short seed_to_data_16(unsigned short seed, int random)
+{
+ if (random)
+ return 25173*seed + 13849;
+ else
+ return seed + 1;
+}
+
+int memtest_silent(void)
+{
+ volatile unsigned int *array = (unsigned int *)MAIN_RAM_BASE;
+ int i;
+ unsigned int seed_32;
+ unsigned short seed_16;
+ unsigned int error_cnt;
+
+ error_cnt = 0;
+
+ /* test data bus */
+ for(i=0;i<128;i++) {
+ array[i] = ONEZERO;
+ }
+ flush_cpu_dcache();
+ flush_l2_cache();
+ for(i=0;i<128;i++) {
+ if(array[i] != ONEZERO)
+ error_cnt++;
+ }
+
+ for(i=0;i<128;i++) {
+ array[i] = ZEROONE;
+ }
+ flush_cpu_dcache();
+ flush_l2_cache();
+ for(i=0;i<128;i++) {
+ if(array[i] != ZEROONE)
+ error_cnt++;
+ }
+
+ /* test counter or random data */
+ seed_32 = 0;
+ for(i=0;i<TEST_DATA_SIZE/4;i++) {
+ seed_32 = seed_to_data_32(seed_32, TEST_DATA_RANDOM);
+ array[i] = seed_32;
+ }
+
+ seed_32 = 0;
+ flush_cpu_dcache();
+ flush_l2_cache();
+ for(i=0;i<TEST_DATA_SIZE/4;i++) {
+ seed_32 = seed_to_data_32(seed_32, TEST_DATA_RANDOM);
+ if(array[i] != seed_32)
+ error_cnt++;
+ }
+
+ /* test random addressing */
+ seed_16 = 0;
+ for(i=0;i<TEST_ADDR_SIZE/4;i++) {
+ seed_16 = seed_to_data_16(seed_16, TEST_ADDR_RANDOM);
+ array[(unsigned int) seed_16] = i;
+ }
+
+ seed_16 = 0;
+ flush_cpu_dcache();
+ flush_l2_cache();
+ for(i=0;i<TEST_ADDR_SIZE/4;i++) {
+ seed_16 = seed_to_data_16(seed_16, TEST_ADDR_RANDOM);
+ if(array[(unsigned int) seed_16] != i)
+ error_cnt++;
+ }
+
+ return error_cnt;
+}
+
+int memtest(void)
+{
+ unsigned int e;
+
+ e = memtest_silent();
+ if(e != 0) {
+ printf("Memtest failed: %d/%d words incorrect\n", e, 2*128 + TEST_DATA_SIZE/4 + TEST_ADDR_SIZE/4);
+ return 0;
+ } else {
+ printf("Memtest OK\n");
+ return 1;
+ }
+}
+
+int sdrinit(void)
+{
+ printf("Initializing SDRAM...\n");
+
+ init_sequence();
+#ifdef CSR_DDRPHY_BASE
+ if(!sdrlevel())
+ return 0;
+#endif
+ sdram_dfii_control_write(DFII_CONTROL_SEL);
+ if(!memtest())
+ return 0;
+
+ return 1;
+}
+
+#endif
--- /dev/null
+#ifndef __SDRAM_H
+#define __SDRAM_H
+
+#include <generated/csr.h>
+
+void sdrsw(void);
+void sdrhw(void);
+void sdrrow(char *_row);
+void sdrrdbuf(int dq);
+void sdrrd(char *startaddr, char *dq);
+void sdrrderr(char *count);
+void sdrwr(char *startaddr);
+
+#ifdef CSR_DDRPHY_BASE
+void sdrwlon(void);
+void sdrwloff(void);
+int sdrlevel(void);
+#endif
+
+int memtest_silent(void);
+int memtest(void);
+int sdrinit(void);
+
+#endif /* __SDRAM_H */
--- /dev/null
+#ifndef __SFL_H
+#define __SFL_H
+
+#define SFL_MAGIC_LEN 14
+#define SFL_MAGIC_REQ "sL5DdSMmkekro\n"
+#define SFL_MAGIC_ACK "z6IHG7cYDID6o\n"
+
+struct sfl_frame {
+ unsigned char length;
+ unsigned char crc[2];
+ unsigned char cmd;
+ unsigned char payload[255];
+} __attribute__((packed));
+
+/* General commands */
+#define SFL_CMD_ABORT 0x00
+#define SFL_CMD_LOAD 0x01
+#define SFL_CMD_JUMP 0x02
+
+/* Linux-specific commands */
+#define SFL_CMD_CMDLINE 0x03
+#define SFL_CMD_INITRDSTART 0x04
+#define SFL_CMD_INITRDEND 0x05
+
+/* Replies */
+#define SFL_ACK_SUCCESS 'K'
+#define SFL_ACK_CRCERROR 'C'
+#define SFL_ACK_UNKNOWN 'U'
+#define SFL_ACK_ERROR 'E'
+
+#endif /* __SFL_H */
--- /dev/null
+TARGET_PREFIX=$(TRIPLE)-
+
+RM ?= rm -f
+PYTHON ?= python3
+
+ifeq ($(CLANG),1)
+CC_normal := clang -target $(TRIPLE) -integrated-as
+CX_normal := clang++ -target $(TRIPLE) -integrated-as
+else
+CC_normal := $(TARGET_PREFIX)gcc
+CX_normal := $(TARGET_PREFIX)g++
+endif
+AR_normal := $(TARGET_PREFIX)ar
+LD_normal := $(TARGET_PREFIX)ld
+OBJCOPY_normal := $(TARGET_PREFIX)objcopy
+
+CC_quiet = @echo " CC " $@ && $(CC_normal)
+CX_quiet = @echo " CX " $@ && $(CX_normal)
+AR_quiet = @echo " AR " $@ && $(AR_normal)
+LD_quiet = @echo " LD " $@ && $(LD_normal)
+OBJCOPY_quiet = @echo " OBJCOPY " $@ && $(OBJCOPY_normal)
+
+ifeq ($(V),1)
+ CC = $(CC_normal)
+ CX = $(CX_normal)
+ AR = $(AR_normal)
+ LD = $(LD_normal)
+ OBJCOPY = $(OBJCOPY_normal)
+else
+ CC = $(CC_quiet)
+ CX = $(CX_quiet)
+ AR = $(AR_quiet)
+ LD = $(LD_quiet)
+ OBJCOPY = $(OBJCOPY_quiet)
+endif
+
+# Toolchain options
+#
+INCLUDES = -I$(SOC_DIRECTORY)/software/include/base -I$(SOC_DIRECTORY)/software/include -I$(SOC_DIRECTORY)/common -I$(BUILDINC_DIRECTORY)
+COMMONFLAGS = -Os $(CPUFLAGS) -fomit-frame-pointer -Wall -fno-builtin -nostdinc $(INCLUDES)
+CFLAGS = $(COMMONFLAGS) -fexceptions -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes
+CXXFLAGS = $(COMMONFLAGS) -std=c++11 -I$(SOC_DIRECTORY)/software/include/basec++ -fexceptions -fno-rtti -ffreestanding
+LDFLAGS = -nostdlib -nodefaultlibs -L$(BUILDINC_DIRECTORY)
+
+# compile and generate dependencies, based on
+# http://scottmcpeak.com/autodepend/autodepend.html
+
+define compilexx
+$(CX) -c $(CXXFLAGS) $(1) $< -o $@
+endef
+
+define compile
+$(CC) -c $(CFLAGS) $(1) $< -o $@
+endef
+
+define assemble
+$(CC) -c $(CFLAGS) -o $@ $<
+endef
--- /dev/null
+Subproject commit 81fb4f00c2cfe13814765968e09931ffa93b5138
--- /dev/null
+#ifndef __ASSERT_H
+#define __ASSERT_H
+
+#define assert(x)
+
+#endif /* __ASSERT_H */
--- /dev/null
+#ifndef __CONSOLE_H
+#define __CONSOLE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*console_write_hook)(char);
+typedef char (*console_read_hook)(void);
+typedef int (*console_read_nonblock_hook)(void);
+
+void console_set_write_hook(console_write_hook h);
+void console_set_read_hook(console_read_hook r, console_read_nonblock_hook rn);
+
+char readchar(void);
+int readchar_nonblock(void);
+
+void putsnonl(const char *s);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CONSOLE_H */
--- /dev/null
+#ifndef __CRC_H
+#define __CRC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+unsigned short crc16(const unsigned char *buffer, int len);
+unsigned int crc32(const unsigned char *buffer, unsigned int len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+#ifndef __CTYPE_H
+#define __CTYPE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * NOTE! This ctype does not handle EOF like the standard C
+ * library is required to.
+ */
+
+#define _U 0x01 /* upper */
+#define _L 0x02 /* lower */
+#define _D 0x04 /* digit */
+#define _C 0x08 /* cntrl */
+#define _P 0x10 /* punct */
+#define _S 0x20 /* white space (space/lf/tab) */
+#define _X 0x40 /* hex digit */
+#define _SP 0x80 /* hard space (0x20) */
+
+extern const unsigned char _ctype[];
+
+#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
+
+#define isalnum(c) ((__ismask(c)&(_U|_L|_D)) != 0)
+#define isalpha(c) ((__ismask(c)&(_U|_L)) != 0)
+#define iscntrl(c) ((__ismask(c)&(_C)) != 0)
+#define isdigit(c) ((__ismask(c)&(_D)) != 0)
+#define isgraph(c) ((__ismask(c)&(_P|_U|_L|_D)) != 0)
+#define islower(c) ((__ismask(c)&(_L)) != 0)
+#define isprint(c) ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
+#define ispunct(c) ((__ismask(c)&(_P)) != 0)
+/* Note: isspace() must return false for %NUL-terminator */
+#define isspace(c) ((__ismask(c)&(_S)) != 0)
+#define isupper(c) ((__ismask(c)&(_U)) != 0)
+#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0)
+
+#define isascii(c) (((unsigned char)(c))<=0x7f)
+#define toascii(c) (((unsigned char)(c))&0x7f)
+
+static inline unsigned char __tolower(unsigned char c)
+{
+ if (isupper(c))
+ c -= 'A'-'a';
+ return c;
+}
+
+static inline unsigned char __toupper(unsigned char c)
+{
+ if (islower(c))
+ c -= 'a'-'A';
+ return c;
+}
+
+#define tolower(c) __tolower(c)
+#define toupper(c) __toupper(c)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CTYPE_H */
--- /dev/null
+#ifndef __ENDIAN_H
+#define __ENDIAN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define __LITTLE_ENDIAN 0
+#define __BIG_ENDIAN 1
+#define __BYTE_ORDER __BIG_ENDIAN
+
+static inline unsigned int le32toh(unsigned int val)
+{
+ return (val & 0xff) << 24 |
+ (val & 0xff00) << 8 |
+ (val & 0xff0000) >> 8 |
+ (val & 0xff000000) >> 24;
+}
+
+static inline unsigned short le16toh(unsigned short val)
+{
+ return (val & 0xff) << 8 |
+ (val & 0xff00) >> 8;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ENDIAN_H */
--- /dev/null
+#ifndef __ERRNO_H
+#define __ERRNO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int errno;
+
+#define EPERM 1
+#define EPERM_STR "Operation not permitted"
+#define ENOENT 2
+#define ENOENT_STR "No such file or directory"
+#define ESRCH 3
+#define ESRCH_STR "No such process"
+#define EINTR 4
+#define EINTR_STR "Interrupted system call"
+#define EIO 5
+#define EIO_STR "I/O error"
+#define ENXIO 6
+#define ENXIO_STR "No such device or address"
+#define E2BIG 7
+#define E2BIG_STR "Arg list too long"
+#define ENOEXEC 8
+#define ENOEXEC_STR "Exec format error"
+#define EBADF 9
+#define EBADF_STR "Bad file number"
+#define ECHILD 10
+#define ECHILD_STR "No child processes"
+#define EAGAIN 11
+#define EWOULDBLOCK EAGAIN
+#define EAGAIN_STR "Try again"
+#define ENOMEM 12
+#define ENOMEM_STR "Out of memory"
+#define EACCES 13
+#define EACCES_STR "Permission denied"
+#define EFAULT 14
+#define EFAULT_STR "Bad address"
+#define ENOTBLK 15
+#define ENOTBLK_STR "Block device required"
+#define EBUSY 16
+#define EBUSY_STR "Device or resource busy"
+#define EEXIST 17
+#define EEXIST_STR "File exists"
+#define EXDEV 18
+#define EXDEV_STR "Cross-device link"
+#define ENODEV 19
+#define ENODEV_STR "No such device"
+#define ENOTDIR 20
+#define ENOTDIR_STR "Not a directory"
+#define EISDIR 21
+#define EISDIR_STR "Is a directory"
+#define EINVAL 22
+#define EINVAL_STR "Invalid argument"
+#define ENFILE 23
+#define ENFILE_STR "File table overflow"
+#define EMFILE 24
+#define EMFILE_STR "Too many open files"
+#define ENOTTY 25
+#define ENOTTY_STR "Not a typewriter"
+#define ETXTBSY 26
+#define ETXTBSY_STR "Text file busy"
+#define EFBIG 27
+#define EFBIG_STR "File too large"
+#define ENOSPC 28
+#define ENOSPC_STR "No space left on device"
+#define ESPIPE 29
+#define ESPIPE_STR "Illegal seek"
+#define EROFS 30
+#define EROFS_STR "Read-only file system"
+#define EMLINK 31
+#define EMLINK_STR "Too many links"
+#define EPIPE 32
+#define EPIPE_STR "Broken pipe"
+#define EDOM 33
+#define EDOM_STR "Math argument out of domain of func"
+#define ERANGE 34
+#define ERANGE_STR "Math result not representable"
+#define EDEADLK 35
+#define EDEADLOCK EDEADLK
+#define EDEADLK_STR "Resource deadlock would occur"
+#define ENAMETOOLONG 36
+#define ENAMETOOLONG_STR "File name too long"
+#define ENOLCK 37
+#define ENOLCK_STR "No record locks available"
+#define ENOSYS 38
+#define ENOSYS_STR "Function not implemented"
+#define ENOTEMPTY 39
+#define ENOTEMPTY_STR "Directory not empty"
+#define ELOOP 40
+#define ELOOP_STR "Too many symbolic links encountered"
+#define ENOMSG 42
+#define ENOMSG_STR "No message of desired type"
+#define EIDRM 43
+#define EIDRM_STR "Identifier removed"
+#define ECHRNG 44
+#define ECHRNG_STR "Channel number out of range"
+#define EL2NSYNC 45
+#define EL2NSYNC_STR "Level 2 not synchronized"
+#define EL3HLT 46
+#define EL3HLT_STR "Level 3 halted"
+#define EL3RST 47
+#define EL3RST_STR "Level 3 reset"
+#define ELNRNG 48
+#define ELNRNG_STR "Link number out of range"
+#define EUNATCH 49
+#define EUNATCH_STR "Protocol driver not attached"
+#define ENOCSI 50
+#define ENOCSI_STR "No CSI structure available"
+#define EL2HLT 51
+#define EL2HLT_STR "Level 2 halted"
+#define EBADE 52
+#define EBADE_STR "Invalid exchange"
+#define EBADR 53
+#define EBADR_STR "Invalid request descriptor"
+#define EXFULL 54
+#define EXFULL_STR "Exchange full"
+#define ENOANO 55
+#define ENOANO_STR "No anode"
+#define EBADRQC 56
+#define EBADRQC_STR "Invalid request code"
+#define EBADSLT 57
+#define EBADSLT_STR "Invalid slot"
+#define EBFONT 59
+#define EBFONT_STR "Bad font file format"
+#define ENOSTR 60
+#define ENOSTR_STR "Device not a stream"
+#define ENODATA 61
+#define ENODATA_STR "No data available"
+#define ETIME 62
+#define ETIME_STR "Timer expired"
+#define ENOSR 63
+#define ENOSR_STR "Out of streams resources"
+#define ENONET 64
+#define ENONET_STR "Machine is not on the network"
+#define ENOPKG 65
+#define ENOPKG_STR "Package not installed"
+#define EREMOTE 66
+#define EREMOTE_STR "Object is remote"
+#define ENOLINK 67
+#define ENOLINK_STR "Link has been severed"
+#define EADV 68
+#define EADV_STR "Advertise error"
+#define ESRMNT 69
+#define ESRMNT_STR "Srmount error"
+#define ECOMM 70
+#define ECOMM_STR "Communication error on send"
+#define EPROTO 71
+#define EPROTO_STR "Protocol error"
+#define EMULTIHOP 72
+#define EMULTIHOP_STR "Multihop attempted"
+#define EDOTDOT 73
+#define EDOTDOT_STR "RFS specific error"
+#define EBADMSG 74
+#define EBADMSG_STR "Not a data message"
+#define EOVERFLOW 75
+#define EOVERFLOW_STR "Value too large for defined data type"
+#define ENOTUNIQ 76
+#define ENOTUNIQ_STR "Name not unique on network"
+#define EBADFD 77
+#define EBADFD_STR "File descriptor in bad state"
+#define EREMCHG 78
+#define EREMCHG_STR "Remote address changed"
+#define ELIBACC 79
+#define ELIBACC_STR "Can not access a needed shared library"
+#define ELIBBAD 80
+#define ELIBBAD_STR "Accessing a corrupted shared library"
+#define ELIBSCN 81
+#define ELIBSCN_STR ".lib section in a.out corrupted"
+#define ELIBMAX 82
+#define ELIBMAX_STR "Attempting to link in too many shared libraries"
+#define ELIBEXEC 83
+#define ELIBEXEC_STR "Cannot exec a shared library directly"
+#define EILSEQ 84
+#define EILSEQ_STR "Illegal byte sequence"
+#define ERESTART 85
+#define ERESTART_STR "Interrupted system call should be restarted"
+#define ESTRPIPE 86
+#define ESTRPIPE_STR "Streams pipe error"
+#define EUSERS 87
+#define EUSERS_STR "Too many users"
+#define ENOTSOCK 88
+#define ENOTSOCK_STR "Socket operation on non-socket"
+#define EDESTADDRREQ 89
+#define EDESTADDRREQ_STR "Destination address required"
+#define EMSGSIZE 90
+#define EMSGSIZE_STR "Message too long"
+#define EPROTOTYPE 91
+#define EPROTOTYPE_STR "Protocol wrong type for socket"
+#define ENOPROTOOPT 92
+#define ENOPROTOOPT_STR "Protocol not available"
+#define EPROTONOSUPPORT 93
+#define EPROTONOSUPPORT_STR "Protocol not supported"
+#define ESOCKTNOSUPPORT 94
+#define ESOCKTNOSUPPORT_STR "Socket type not supported"
+#define EOPNOTSUPP 95
+#define EOPNOTSUPP_STR "Operation not supported on transport endpoint"
+#define EPFNOSUPPORT 96
+#define EPFNOSUPPORT_STR "Protocol family not supported"
+#define EAFNOSUPPORT 97
+#define EAFNOSUPPORT_STR "Address family not supported by protocol"
+#define EADDRINUSE 98
+#define EADDRINUSE_STR "Address already in use"
+#define EADDRNOTAVAIL 99
+#define EADDRNOTAVAIL_STR "Cannot assign requested address"
+#define ENETDOWN 100
+#define ENETDOWN_STR "Network is down"
+#define ENETUNREACH 101
+#define ENETUNREACH_STR "Network is unreachable"
+#define ENETRESET 102
+#define ENETRESET_STR "Network dropped connection because of reset"
+#define ECONNABORTED 103
+#define ECONNABORTED_STR "Software caused connection abort"
+#define ECONNRESET 104
+#define ECONNRESET_STR "Connection reset by peer"
+#define ENOBUFS 105
+#define ENOBUFS_STR "No buffer space available"
+#define EISCONN 106
+#define EISCONN_STR "Transport endpoint is already connected"
+#define ENOTCONN 107
+#define ENOTCONN_STR "Transport endpoint is not connected"
+#define ESHUTDOWN 108
+#define ESHUTDOWN_STR "Cannot send after transport endpoint shutdown"
+#define ETOOMANYREFS 109
+#define ETOOMANYREFS_STR "Too many references: cannot splice"
+#define ETIMEDOUT 110
+#define ETIMEDOUT_STR "Connection timed out"
+#define ECONNREFUSED 111
+#define ECONNREFUSED_STR "Connection refused"
+#define EHOSTDOWN 112
+#define EHOSTDOWN_STR "Host is down"
+#define EHOSTUNREACH 113
+#define EHOSTUNREACH_STR "No route to host"
+#define EALREADY 114
+#define EALREADY_STR "Operation already in progress"
+#define EINPROGRESS 115
+#define EINPROGRESS_STR "Operation now in progress"
+#define ESTALE 116
+#define ESTALE_STR "Stale NFS file handle"
+#define EUCLEAN 117
+#define EUCLEAN_STR "Structure needs cleaning"
+#define ENOTNAM 118
+#define ENOTNAM_STR "Not a XENIX named type file"
+#define ENAVAIL 119
+#define ENAVAIL_STR "No XENIX semaphores available"
+#define EISNAM 120
+#define EISNAM_STR "Is a named type file"
+#define EREMOTEIO 121
+#define EREMOTEIO_STR "Remote I/O error"
+#define EDQUOT 122
+#define EDQUOT_STR "Quota exceeded"
+#define ENOMEDIUM 123
+#define ENOMEDIUM_STR "No medium found"
+#define EMEDIUMTYPE 124
+#define EMEDIUMTYPE_STR "Wrong medium type"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ERRNO_H */
--- /dev/null
+#ifndef __FLOAT_H
+#define __FLOAT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
+#define FLT_ROUNDS (__builtin_flt_rounds())
+#define FLT_RADIX __FLT_RADIX__
+
+#define FLT_MANT_DIG __FLT_MANT_DIG__
+#define DBL_MANT_DIG __DBL_MANT_DIG__
+#define LDBL_MANT_DIG __LDBL_MANT_DIG__
+
+#define DECIMAL_DIG __DECIMAL_DIG__
+
+#define FLT_DIG __FLT_DIG__
+#define DBL_DIG __DBL_DIG__
+#define LDBL_DIG __LDBL_DIG__
+
+#define FLT_MIN_EXP __FLT_MIN_EXP__
+#define DBL_MIN_EXP __DBL_MIN_EXP__
+#define LDBL_MIN_EXP __LDBL_MIN_EXP__
+
+#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__
+#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__
+#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__
+
+#define FLT_MAX_EXP __FLT_MAX_EXP__
+#define DBL_MAX_EXP __DBL_MAX_EXP__
+#define LDBL_MAX_EXP __LDBL_MAX_EXP__
+
+#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__
+#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__
+#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__
+
+#define FLT_MAX __FLT_MAX__
+#define DBL_MAX __DBL_MAX__
+#define LDBL_MAX __LDBL_MAX__
+
+#define FLT_EPSILON __FLT_EPSILON__
+#define DBL_EPSILON __DBL_EPSILON__
+#define LDBL_EPSILON __LDBL_EPSILON__
+
+#define FLT_MIN __FLT_MIN__
+#define DBL_MIN __DBL_MIN__
+#define LDBL_MIN __LDBL_MIN__
+
+#define FLT_TRUE_MIN __FLT_DENORM_MIN__
+#define DBL_TRUE_MIN __DBL_DENORM_MIN__
+#define LDBL_TRUE_MIN __LDBL_DENORM_MIN__
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __FLOAT_H */
--- /dev/null
+#ifndef __ID_H
+#define __ID_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void get_sysid_formatted(char *sysid);
+void id_print(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __ID_H */
--- /dev/null
+/* Copyright (C) 1997-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/*
+ * ISO C99: 7.8 Format conversion of integer types <inttypes.h>
+ */
+
+#ifndef __INTTYPES_H
+#define __INTTYPES_H
+
+# if __WORDSIZE == 64
+# define __PRI64_PREFIX "l"
+# define __PRIPTR_PREFIX "l"
+# else
+# define __PRI64_PREFIX "ll"
+# define __PRIPTR_PREFIX
+# endif
+
+/* Macros for printing format specifiers. */
+
+/* Decimal notation. */
+# define PRId8 "d"
+# define PRId16 "d"
+# define PRId32 "d"
+# define PRId64 __PRI64_PREFIX "d"
+
+# define PRIdLEAST8 "d"
+# define PRIdLEAST16 "d"
+# define PRIdLEAST32 "d"
+# define PRIdLEAST64 __PRI64_PREFIX "d"
+
+# define PRIdFAST8 "d"
+# define PRIdFAST16 __PRIPTR_PREFIX "d"
+# define PRIdFAST32 __PRIPTR_PREFIX "d"
+# define PRIdFAST64 __PRI64_PREFIX "d"
+
+
+# define PRIi8 "i"
+# define PRIi16 "i"
+# define PRIi32 "i"
+# define PRIi64 __PRI64_PREFIX "i"
+
+# define PRIiLEAST8 "i"
+# define PRIiLEAST16 "i"
+# define PRIiLEAST32 "i"
+# define PRIiLEAST64 __PRI64_PREFIX "i"
+
+# define PRIiFAST8 "i"
+# define PRIiFAST16 __PRIPTR_PREFIX "i"
+# define PRIiFAST32 __PRIPTR_PREFIX "i"
+# define PRIiFAST64 __PRI64_PREFIX "i"
+
+/* Octal notation. */
+# define PRIo8 "o"
+# define PRIo16 "o"
+# define PRIo32 "o"
+# define PRIo64 __PRI64_PREFIX "o"
+
+# define PRIoLEAST8 "o"
+# define PRIoLEAST16 "o"
+# define PRIoLEAST32 "o"
+# define PRIoLEAST64 __PRI64_PREFIX "o"
+
+# define PRIoFAST8 "o"
+# define PRIoFAST16 __PRIPTR_PREFIX "o"
+# define PRIoFAST32 __PRIPTR_PREFIX "o"
+# define PRIoFAST64 __PRI64_PREFIX "o"
+
+/* Unsigned integers. */
+# define PRIu8 "u"
+# define PRIu16 "u"
+# define PRIu32 "u"
+# define PRIu64 __PRI64_PREFIX "u"
+
+# define PRIuLEAST8 "u"
+# define PRIuLEAST16 "u"
+# define PRIuLEAST32 "u"
+# define PRIuLEAST64 __PRI64_PREFIX "u"
+
+# define PRIuFAST8 "u"
+# define PRIuFAST16 __PRIPTR_PREFIX "u"
+# define PRIuFAST32 __PRIPTR_PREFIX "u"
+# define PRIuFAST64 __PRI64_PREFIX "u"
+
+/* lowercase hexadecimal notation. */
+# define PRIx8 "x"
+# define PRIx16 "x"
+# define PRIx32 "x"
+# define PRIx64 __PRI64_PREFIX "x"
+
+# define PRIxLEAST8 "x"
+# define PRIxLEAST16 "x"
+# define PRIxLEAST32 "x"
+# define PRIxLEAST64 __PRI64_PREFIX "x"
+
+# define PRIxFAST8 "x"
+# define PRIxFAST16 __PRIPTR_PREFIX "x"
+# define PRIxFAST32 __PRIPTR_PREFIX "x"
+# define PRIxFAST64 __PRI64_PREFIX "x"
+
+/* UPPERCASE hexadecimal notation. */
+# define PRIX8 "X"
+# define PRIX16 "X"
+# define PRIX32 "X"
+# define PRIX64 __PRI64_PREFIX "X"
+
+# define PRIXLEAST8 "X"
+# define PRIXLEAST16 "X"
+# define PRIXLEAST32 "X"
+# define PRIXLEAST64 __PRI64_PREFIX "X"
+
+# define PRIXFAST8 "X"
+# define PRIXFAST16 __PRIPTR_PREFIX "X"
+# define PRIXFAST32 __PRIPTR_PREFIX "X"
+# define PRIXFAST64 __PRI64_PREFIX "X"
+
+/* Macros for printing `intmax_t' and `uintmax_t'. */
+# define PRIdMAX __PRI64_PREFIX "d"
+# define PRIiMAX __PRI64_PREFIX "i"
+# define PRIoMAX __PRI64_PREFIX "o"
+# define PRIuMAX __PRI64_PREFIX "u"
+# define PRIxMAX __PRI64_PREFIX "x"
+# define PRIXMAX __PRI64_PREFIX "X"
+
+
+/* Macros for printing `intptr_t' and `uintptr_t'. */
+# define PRIdPTR __PRIPTR_PREFIX "d"
+# define PRIiPTR __PRIPTR_PREFIX "i"
+# define PRIoPTR __PRIPTR_PREFIX "o"
+# define PRIuPTR __PRIPTR_PREFIX "u"
+# define PRIxPTR __PRIPTR_PREFIX "x"
+# define PRIXPTR __PRIPTR_PREFIX "X"
+
+/* Macros for scanning format specifiers. */
+
+/* Signed decimal notation. */
+# define SCNd8 "hhd"
+# define SCNd16 "hd"
+# define SCNd32 "d"
+# define SCNd64 __PRI64_PREFIX "d"
+
+# define SCNdLEAST8 "hhd"
+# define SCNdLEAST16 "hd"
+# define SCNdLEAST32 "d"
+# define SCNdLEAST64 __PRI64_PREFIX "d"
+
+# define SCNdFAST8 "hhd"
+# define SCNdFAST16 __PRIPTR_PREFIX "d"
+# define SCNdFAST32 __PRIPTR_PREFIX "d"
+# define SCNdFAST64 __PRI64_PREFIX "d"
+
+/* Unsigned decimal notation. */
+# define SCNu8 "hhu"
+# define SCNu16 "hu"
+# define SCNu32 "u"
+# define SCNu64 __PRI64_PREFIX "u"
+
+# define SCNuLEAST8 "hhu"
+# define SCNuLEAST16 "hu"
+# define SCNuLEAST32 "u"
+# define SCNuLEAST64 __PRI64_PREFIX "u"
+
+# define SCNuFAST8 "hhu"
+# define SCNuFAST16 __PRIPTR_PREFIX "u"
+# define SCNuFAST32 __PRIPTR_PREFIX "u"
+# define SCNuFAST64 __PRI64_PREFIX "u"
+
+/* Octal notation. */
+# define SCNo8 "hho"
+# define SCNo16 "ho"
+# define SCNo32 "o"
+# define SCNo64 __PRI64_PREFIX "o"
+
+# define SCNoLEAST8 "hho"
+# define SCNoLEAST16 "ho"
+# define SCNoLEAST32 "o"
+# define SCNoLEAST64 __PRI64_PREFIX "o"
+
+# define SCNoFAST8 "hho"
+# define SCNoFAST16 __PRIPTR_PREFIX "o"
+# define SCNoFAST32 __PRIPTR_PREFIX "o"
+# define SCNoFAST64 __PRI64_PREFIX "o"
+
+/* Hexadecimal notation. */
+# define SCNx8 "hhx"
+# define SCNx16 "hx"
+# define SCNx32 "x"
+# define SCNx64 __PRI64_PREFIX "x"
+
+# define SCNxLEAST8 "hhx"
+# define SCNxLEAST16 "hx"
+# define SCNxLEAST32 "x"
+# define SCNxLEAST64 __PRI64_PREFIX "x"
+
+# define SCNxFAST8 "hhx"
+# define SCNxFAST16 __PRIPTR_PREFIX "x"
+# define SCNxFAST32 __PRIPTR_PREFIX "x"
+# define SCNxFAST64 __PRI64_PREFIX "x"
+
+
+/* Macros for scanning `intmax_t' and `uintmax_t'. */
+# define SCNdMAX __PRI64_PREFIX "d"
+# define SCNiMAX __PRI64_PREFIX "i"
+# define SCNoMAX __PRI64_PREFIX "o"
+# define SCNuMAX __PRI64_PREFIX "u"
+# define SCNxMAX __PRI64_PREFIX "x"
+
+/* Macros for scaning `intptr_t' and `uintptr_t'. */
+# define SCNdPTR __PRIPTR_PREFIX "d"
+# define SCNiPTR __PRIPTR_PREFIX "i"
+# define SCNoPTR __PRIPTR_PREFIX "o"
+# define SCNuPTR __PRIPTR_PREFIX "u"
+# define SCNxPTR __PRIPTR_PREFIX "x"
+
+#endif /* __INTTYPES_H */
--- /dev/null
+#ifndef __IRQ_H
+#define __IRQ_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __or1k__
+#include <system.h>
+#endif
+
+static inline unsigned int irq_getie(void)
+{
+#if defined (__lm32__)
+ unsigned int ie;
+ __asm__ __volatile__("rcsr %0, IE" : "=r" (ie));
+ return ie;
+#elif defined (__or1k__)
+ return !!(mfspr(SPR_SR) & SPR_SR_IEE);
+#else
+#error Unsupported architecture
+#endif
+}
+
+static inline void irq_setie(unsigned int ie)
+{
+#if defined (__lm32__)
+ __asm__ __volatile__("wcsr IE, %0" : : "r" (ie));
+#elif defined (__or1k__)
+ if (ie & 0x1)
+ mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_IEE);
+ else
+ mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_IEE);
+#else
+#error Unsupported architecture
+#endif
+}
+
+static inline unsigned int irq_getmask(void)
+{
+#if defined (__lm32__)
+ unsigned int mask;
+ __asm__ __volatile__("rcsr %0, IM" : "=r" (mask));
+ return mask;
+#elif defined (__or1k__)
+ return mfspr(SPR_PICMR);
+#else
+#error Unsupported architecture
+#endif
+}
+
+static inline void irq_setmask(unsigned int mask)
+{
+#if defined (__lm32__)
+ __asm__ __volatile__("wcsr IM, %0" : : "r" (mask));
+#elif defined (__or1k__)
+ mtspr(SPR_PICMR, mask);
+#else
+#error Unsupported architecture
+#endif
+}
+
+static inline unsigned int irq_pending(void)
+{
+#if defined (__lm32__)
+ unsigned int pending;
+ __asm__ __volatile__("rcsr %0, IP" : "=r" (pending));
+ return pending;
+#elif defined (__or1k__)
+ return mfspr(SPR_PICSR);
+#else
+#error Unsupported architecture
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __IRQ_H */
--- /dev/null
+#ifndef __LIMITS_H
+#define __LIMITS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ULONG_MAX 0xffffffff
+
+#define UINT_MAX 0xffffffff
+#define INT_MIN 0x80000000
+#define INT_MAX 0x7fffffff
+
+#define USHRT_MAX 0xffff
+#define SHRT_MIN 0x8000
+#define SHRT_MAX 0x7fff
+
+#define UCHAR_MAX 0xff
+
+#define CHAR_BIT 8
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LIMITS_H */
--- /dev/null
+#ifndef __PTHREAD_H
+#define __PTHREAD_H
+
+typedef int pthread_rwlock_t;
+
+#define PTHREAD_RWLOCK_INITIALIZER 0
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+inline int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
+ { return 0; }
+inline int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
+ { return 0; }
+inline int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
+ { return 0; }
+inline int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
+ { return 0; }
+int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
+ { return 0; }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PTHREAD_H */
--- /dev/null
+#ifndef __SPIFLASH_H
+#define __SPIFLASH_H
+
+void write_to_flash_page(unsigned int addr, const unsigned char *c, unsigned int len);
+void erase_flash_sector(unsigned int addr);
+void write_to_flash(unsigned int addr, const unsigned char *c, unsigned int len);
+
+#endif /* __SPIFLASH_H */
--- /dev/null
+/* spr-defs.h - Special purpose registers definitions file
+
+ Copyright (C) 2000 Damjan Lampret
+ Copyright (C) 2008, 2010 Embecosm Limited
+
+ Contributor Damjan Lampret <lampret@opencores.org>
+ Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the Free
+ Software Foundation; either version 3 of the License, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program. If not, see <http: www.gnu.org/licenses/>. */
+
+/* ----------------------------------------------------------------------------
+ This code is commented throughout for use with Doxygen.
+ --------------------------------------------------------------------------*/
+#ifndef SPR_DEFS__H
+#define SPR_DEFS__H
+
+/* Definition of special-purpose registers (SPRs). */
+
+#define MAX_GRPS (32)
+#define MAX_SPRS_PER_GRP_BITS (11)
+#define MAX_SPRS_PER_GRP (1 << MAX_SPRS_PER_GRP_BITS)
+#define MAX_SPRS (0x10000)
+
+/* Base addresses for the groups */
+#define SPRGROUP_SYS (0<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_DMMU (1<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_IMMU (2<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_DC (3<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_IC (4<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_MAC (5<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_D (6<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_PC (7<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_PM (8<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_PIC (9<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_TT (10<< MAX_SPRS_PER_GRP_BITS)
+#define SPRGROUP_FP (11<< MAX_SPRS_PER_GRP_BITS)
+
+/* System control and status group */
+#define SPR_VR (SPRGROUP_SYS + 0)
+#define SPR_UPR (SPRGROUP_SYS + 1)
+#define SPR_CPUCFGR (SPRGROUP_SYS + 2)
+#define SPR_DMMUCFGR (SPRGROUP_SYS + 3)
+#define SPR_IMMUCFGR (SPRGROUP_SYS + 4)
+#define SPR_DCCFGR (SPRGROUP_SYS + 5)
+#define SPR_ICCFGR (SPRGROUP_SYS + 6)
+#define SPR_DCFGR (SPRGROUP_SYS + 7)
+#define SPR_PCCFGR (SPRGROUP_SYS + 8)
+#define SPR_VR2 (SPRGROUP_SYS + 9)
+#define SPR_AVR (SPRGROUP_SYS + 10)
+#define SPR_EVBAR (SPRGROUP_SYS + 11)
+#define SPR_AECR (SPRGROUP_SYS + 12)
+#define SPR_AESR (SPRGROUP_SYS + 13)
+#define SPR_NPC (SPRGROUP_SYS + 16) /* CZ 21/06/01 */
+#define SPR_SR (SPRGROUP_SYS + 17) /* CZ 21/06/01 */
+#define SPR_PPC (SPRGROUP_SYS + 18) /* CZ 21/06/01 */
+#define SPR_FPCSR (SPRGROUP_SYS + 20) /* CZ 21/06/01 */
+#define SPR_ISR_BASE (SPRGROUP_SYS + 21)
+#define SPR_EPCR_BASE (SPRGROUP_SYS + 32) /* CZ 21/06/01 */
+#define SPR_EPCR_LAST (SPRGROUP_SYS + 47) /* CZ 21/06/01 */
+#define SPR_EEAR_BASE (SPRGROUP_SYS + 48)
+#define SPR_EEAR_LAST (SPRGROUP_SYS + 63)
+#define SPR_ESR_BASE (SPRGROUP_SYS + 64)
+#define SPR_ESR_LAST (SPRGROUP_SYS + 79)
+#define SPR_GPR_BASE (SPRGROUP_SYS + 1024)
+
+/* Data MMU group */
+#define SPR_DMMUCR (SPRGROUP_DMMU + 0)
+#define SPR_DTLBEIR (SPRGROUP_DMMU + 2)
+#define SPR_DTLBMR_BASE(WAY) (SPRGROUP_DMMU + 0x200 + (WAY) * 0x100)
+#define SPR_DTLBMR_LAST(WAY) (SPRGROUP_DMMU + 0x27f + (WAY) * 0x100)
+#define SPR_DTLBTR_BASE(WAY) (SPRGROUP_DMMU + 0x280 + (WAY) * 0x100)
+#define SPR_DTLBTR_LAST(WAY) (SPRGROUP_DMMU + 0x2ff + (WAY) * 0x100)
+
+/* Instruction MMU group */
+#define SPR_IMMUCR (SPRGROUP_IMMU + 0)
+#define SPR_ITLBEIR (SPRGROUP_IMMU + 2)
+#define SPR_ITLBMR_BASE(WAY) (SPRGROUP_IMMU + 0x200 + (WAY) * 0x100)
+#define SPR_ITLBMR_LAST(WAY) (SPRGROUP_IMMU + 0x27f + (WAY) * 0x100)
+#define SPR_ITLBTR_BASE(WAY) (SPRGROUP_IMMU + 0x280 + (WAY) * 0x100)
+#define SPR_ITLBTR_LAST(WAY) (SPRGROUP_IMMU + 0x2ff + (WAY) * 0x100)
+
+/* Data cache group */
+#define SPR_DCCR (SPRGROUP_DC + 0)
+#define SPR_DCBPR (SPRGROUP_DC + 1)
+#define SPR_DCBFR (SPRGROUP_DC + 2)
+#define SPR_DCBIR (SPRGROUP_DC + 3)
+#define SPR_DCBWR (SPRGROUP_DC + 4)
+#define SPR_DCBLR (SPRGROUP_DC + 5)
+#define SPR_DCR_BASE(WAY) (SPRGROUP_DC + 0x200 + (WAY) * 0x200)
+#define SPR_DCR_LAST(WAY) (SPRGROUP_DC + 0x3ff + (WAY) * 0x200)
+
+/* Instruction cache group */
+#define SPR_ICCR (SPRGROUP_IC + 0)
+#define SPR_ICBPR (SPRGROUP_IC + 1)
+#define SPR_ICBIR (SPRGROUP_IC + 2)
+#define SPR_ICBLR (SPRGROUP_IC + 3)
+#define SPR_ICR_BASE(WAY) (SPRGROUP_IC + 0x200 + (WAY) * 0x200)
+#define SPR_ICR_LAST(WAY) (SPRGROUP_IC + 0x3ff + (WAY) * 0x200)
+
+/* MAC group */
+#define SPR_MACLO (SPRGROUP_MAC + 1)
+#define SPR_MACHI (SPRGROUP_MAC + 2)
+
+/* Debug group */
+#define SPR_DVR(N) (SPRGROUP_D + (N))
+#define SPR_DCR(N) (SPRGROUP_D + 8 + (N))
+#define SPR_DMR1 (SPRGROUP_D + 16)
+#define SPR_DMR2 (SPRGROUP_D + 17)
+#define SPR_DWCR0 (SPRGROUP_D + 18)
+#define SPR_DWCR1 (SPRGROUP_D + 19)
+#define SPR_DSR (SPRGROUP_D + 20)
+#define SPR_DRR (SPRGROUP_D + 21)
+
+/* Performance counters group */
+#define SPR_PCCR(N) (SPRGROUP_PC + (N))
+#define SPR_PCMR(N) (SPRGROUP_PC + 8 + (N))
+
+/* Power management group */
+#define SPR_PMR (SPRGROUP_PM + 0)
+
+/* PIC group */
+#define SPR_PICMR (SPRGROUP_PIC + 0)
+#define SPR_PICPR (SPRGROUP_PIC + 1)
+#define SPR_PICSR (SPRGROUP_PIC + 2)
+
+/* Tick Timer group */
+#define SPR_TTMR (SPRGROUP_TT + 0)
+#define SPR_TTCR (SPRGROUP_TT + 1)
+
+/*
+ * Bit definitions for the Version Register
+ *
+ */
+#define SPR_VR_VER 0xff000000 /* Processor version */
+#define SPR_VR_CFG 0x00ff0000 /* Processor configuration */
+#define SPR_VR_RES 0x0000ff80 /* Reserved */
+#define SPR_VR_UVRP 0x00000040 /* Updated version register present */
+#define SPR_VR_REV 0x0000003f /* Processor revision */
+
+#define SPR_VR_VER_OFF 24
+#define SPR_VR_CFG_OFF 16
+#define SPR_VR_UVRP_OFF 6
+#define SPR_VR_REV_OFF 0
+
+/*
+ * Bit definitions for the Unit Present Register
+ *
+ */
+#define SPR_UPR_UP 0x00000001 /* UPR present */
+#define SPR_UPR_DCP 0x00000002 /* Data cache present */
+#define SPR_UPR_ICP 0x00000004 /* Instruction cache present */
+#define SPR_UPR_DMP 0x00000008 /* Data MMU present */
+#define SPR_UPR_IMP 0x00000010 /* Instruction MMU present */
+#define SPR_UPR_MP 0x00000020 /* MAC present */
+#define SPR_UPR_DUP 0x00000040 /* Debug unit present */
+#define SPR_UPR_PCUP 0x00000080 /* Performance counters unit present */
+#define SPR_UPR_PMP 0x00000100 /* Power management present */
+#define SPR_UPR_PICP 0x00000200 /* PIC present */
+#define SPR_UPR_TTP 0x00000400 /* Tick timer present */
+#define SPR_UPR_RES 0x00fe0000 /* Reserved */
+#define SPR_UPR_CUP 0xff000000 /* Context units present */
+
+/*
+ * JPB: Bit definitions for the CPU configuration register
+ *
+ */
+#define SPR_CPUCFGR_NSGF 0x0000000f /* Number of shadow GPR files */
+#define SPR_CPUCFGR_CGF 0x00000010 /* Custom GPR file */
+#define SPR_CPUCFGR_OB32S 0x00000020 /* ORBIS32 supported */
+#define SPR_CPUCFGR_OB64S 0x00000040 /* ORBIS64 supported */
+#define SPR_CPUCFGR_OF32S 0x00000080 /* ORFPX32 supported */
+#define SPR_CPUCFGR_OF64S 0x00000100 /* ORFPX64 supported */
+#define SPR_CPUCFGR_OV64S 0x00000200 /* ORVDX64 supported */
+#define SPR_CPUCFGR_ND 0x00000400 /* No delay-slot */
+#define SPR_CPUCFGR_AVRP 0x00000800 /* Architecture version register present */
+#define SPR_CPUCFGR_EVBARP 0x00001000 /* Exception vector base address register
+ present */
+#define SPR_CPUCFGR_ISRP 0x00002000 /* Implementation-specific registers present */
+#define SPR_CPUCFGR_AECSRP 0x00004000 /* Arithmetic exception control/status
+ registers present */
+#define SPR_CPUCFGR_RES 0xffff8000 /* Reserved */
+
+/*
+ * Bit definitions for the Version Register 2
+ *
+ */
+#define SPR_VR2_CPUID 0xff000000 /* Unique CPU identifier */
+#define SPR_VR2_VER 0x00ffffff /* Version */
+
+#define SPR_VR2_CPUID_OFF 24
+#define SPR_VR2_VER_OFF 0
+
+#define SPR_VR2_CPUID_OR1KSIM 0x00
+#define SPR_VR2_CPUID_MOR1KX 0x01
+#define SPR_VR2_CPUID_OR1200 0x12
+#define SPR_VR2_CPUID_ALTOR32 0x32
+#define SPR_VR2_CPUID_OR10 0x10
+
+
+/*
+ * Bit definitions for the Architecture Version register
+ *
+ */
+#define SPR_AVR_MAJ 0xff000000 /* Major architecture version number */
+#define SPR_AVR_MIN 0x00ff0000 /* Minor architecture version number */
+#define SPR_AVR_REV 0x0000ff00 /* Architecture revision number */
+#define SPR_AVR_RES 0x000000ff /* Reserved */
+
+#define SPR_AVR_MAJ_OFF 24
+#define SPR_AVR_MIN_OFF 16
+#define SPR_AVR_REV_OFF 8
+
+/*
+ * Bit definitions for the Exception Base Address register
+ *
+ */
+#define SPR_EVBAR_EVBA 0xffffe000 /* Exception vector base address */
+#define SPR_EVBAR_RES 0x00001fff /* Reserved */
+
+#define SPR_EVBAR_EVBA_OFF 13
+
+/*
+ * Bit definitions for the Arithmetic Exception Control register
+ *
+ */
+#define SPR_AECR_CYADDE 0x00000001 /* Carry on add/subtract exception */
+#define SPR_AECR_OVADDE 0x00000002 /* Overflow on add/subtract exception */
+#define SPR_AECR_CYMULE 0x00000004 /* Carry on multiply exception */
+#define SPR_AECR_OVMULE 0x00000008 /* Overflow on multiply exception */
+#define SPR_AECR_DBZE 0x00000010 /* Divide by zero exception */
+#define SPR_AECR_CYMACADDE 0x00000020 /* Carry on MAC add/subtract exception */
+#define SPR_AECR_OVMACADDE 0x00000040 /* Overflow on MAC add/subtract exception */
+
+#define SPR_AECR_CYADDE_OFF 0
+#define SPR_AECR_OVADDE_OFF 1
+#define SPR_AECR_CYMULE_OFF 2
+#define SPR_AECR_OVMULE_OFF 3
+#define SPR_AECR_DBZE_OFF 4
+#define SPR_AECR_CYMACADDE_OFF 5
+#define SPR_AECR_OVMACADDE_OFF 6
+
+
+/*
+ * Bit definitions for the Arithmetic Exception Status register
+ *
+ */
+#define SPR_AESR_CYADDE 0x00000001 /* Carry on add/subtract exception */
+#define SPR_AESR_OVADDE 0x00000002 /* Overflow on add/subtract exception */
+#define SPR_AESR_CYMULE 0x00000004 /* Carry on multiply exception */
+#define SPR_AESR_OVMULE 0x00000008 /* Overflow on multiply exception */
+#define SPR_AESR_DBZE 0x00000010 /* Divide by zero exception */
+#define SPR_AESR_CYMACADDE 0x00000020 /* Carry on MAC add/subtract exception */
+#define SPR_AESR_OVMACADDE 0x00000040 /* Overflow on MAC add/subtract exception */
+
+#define SPR_AESR_CYADDE_OFF 0
+#define SPR_AESR_OVADDE_OFF 1
+#define SPR_AESR_CYMULE_OFF 2
+#define SPR_AESR_OVMULE_OFF 3
+#define SPR_AESR_DBZE_OFF 4
+#define SPR_AESR_CYMACADDE_OFF 5
+#define SPR_AESR_OVMACADDE_OFF 6
+
+/*
+ * JPB: Bit definitions for the Debug configuration register and other
+ * constants.
+ *
+ */
+
+#define SPR_DCFGR_NDP 0x00000007 /* Number of matchpoints mask */
+#define SPR_DCFGR_NDP1 0x00000000 /* One matchpoint supported */
+#define SPR_DCFGR_NDP2 0x00000001 /* Two matchpoints supported */
+#define SPR_DCFGR_NDP3 0x00000002 /* Three matchpoints supported */
+#define SPR_DCFGR_NDP4 0x00000003 /* Four matchpoints supported */
+#define SPR_DCFGR_NDP5 0x00000004 /* Five matchpoints supported */
+#define SPR_DCFGR_NDP6 0x00000005 /* Six matchpoints supported */
+#define SPR_DCFGR_NDP7 0x00000006 /* Seven matchpoints supported */
+#define SPR_DCFGR_NDP8 0x00000007 /* Eight matchpoints supported */
+#define SPR_DCFGR_WPCI 0x00000008 /* Watchpoint counters implemented */
+
+#define MATCHPOINTS_TO_NDP(n) (1 == n ? SPR_DCFGR_NDP1 : \
+ 2 == n ? SPR_DCFGR_NDP2 : \
+ 3 == n ? SPR_DCFGR_NDP3 : \
+ 4 == n ? SPR_DCFGR_NDP4 : \
+ 5 == n ? SPR_DCFGR_NDP5 : \
+ 6 == n ? SPR_DCFGR_NDP6 : \
+ 7 == n ? SPR_DCFGR_NDP7 : SPR_DCFGR_NDP8)
+#define MAX_MATCHPOINTS 8
+#define MAX_WATCHPOINTS (MAX_MATCHPOINTS + 2)
+
+/*
+ * Bit definitions for the Supervision Register
+ *
+ */
+#define SPR_SR_SM 0x00000001 /* Supervisor Mode */
+#define SPR_SR_TEE 0x00000002 /* Tick timer Exception Enable */
+#define SPR_SR_IEE 0x00000004 /* Interrupt Exception Enable */
+#define SPR_SR_DCE 0x00000008 /* Data Cache Enable */
+#define SPR_SR_ICE 0x00000010 /* Instruction Cache Enable */
+#define SPR_SR_DME 0x00000020 /* Data MMU Enable */
+#define SPR_SR_IME 0x00000040 /* Instruction MMU Enable */
+#define SPR_SR_LEE 0x00000080 /* Little Endian Enable */
+#define SPR_SR_CE 0x00000100 /* CID Enable */
+#define SPR_SR_F 0x00000200 /* Condition Flag */
+#define SPR_SR_CY 0x00000400 /* Carry flag */
+#define SPR_SR_OV 0x00000800 /* Overflow flag */
+#define SPR_SR_OVE 0x00001000 /* Overflow flag Exception */
+#define SPR_SR_DSX 0x00002000 /* Delay Slot Exception */
+#define SPR_SR_EPH 0x00004000 /* Exception Prefix High */
+#define SPR_SR_FO 0x00008000 /* Fixed one */
+#define SPR_SR_SUMRA 0x00010000 /* Supervisor SPR read access */
+#define SPR_SR_RES 0x0ffe0000 /* Reserved */
+#define SPR_SR_CID 0xf0000000 /* Context ID */
+
+/*
+ * Bit definitions for the Data MMU Control Register
+ *
+ */
+#define SPR_DMMUCR_P2S 0x0000003e /* Level 2 Page Size */
+#define SPR_DMMUCR_P1S 0x000007c0 /* Level 1 Page Size */
+#define SPR_DMMUCR_VADDR_WIDTH 0x0000f800 /* Virtual ADDR Width */
+#define SPR_DMMUCR_PADDR_WIDTH 0x000f0000 /* Physical ADDR Width */
+
+/*
+ * Bit definitions for the Instruction MMU Control Register
+ *
+ */
+#define SPR_IMMUCR_P2S 0x0000003e /* Level 2 Page Size */
+#define SPR_IMMUCR_P1S 0x000007c0 /* Level 1 Page Size */
+#define SPR_IMMUCR_VADDR_WIDTH 0x0000f800 /* Virtual ADDR Width */
+#define SPR_IMMUCR_PADDR_WIDTH 0x000f0000 /* Physical ADDR Width */
+
+/*
+ * Bit definitions for the Data TLB Match Register
+ *
+ */
+#define SPR_DTLBMR_V 0x00000001 /* Valid */
+#define SPR_DTLBMR_PL1 0x00000002 /* Page Level 1 (if 0 then PL2) */
+#define SPR_DTLBMR_CID 0x0000003c /* Context ID */
+#define SPR_DTLBMR_LRU 0x000000c0 /* Least Recently Used */
+#define SPR_DTLBMR_VPN 0xffffe000 /* Virtual Page Number */
+
+/*
+ * Bit definitions for the Data TLB Translate Register
+ *
+ */
+#define SPR_DTLBTR_CC 0x00000001 /* Cache Coherency */
+#define SPR_DTLBTR_CI 0x00000002 /* Cache Inhibit */
+#define SPR_DTLBTR_WBC 0x00000004 /* Write-Back Cache */
+#define SPR_DTLBTR_WOM 0x00000008 /* Weakly-Ordered Memory */
+#define SPR_DTLBTR_A 0x00000010 /* Accessed */
+#define SPR_DTLBTR_D 0x00000020 /* Dirty */
+#define SPR_DTLBTR_URE 0x00000040 /* User Read Enable */
+#define SPR_DTLBTR_UWE 0x00000080 /* User Write Enable */
+#define SPR_DTLBTR_SRE 0x00000100 /* Supervisor Read Enable */
+#define SPR_DTLBTR_SWE 0x00000200 /* Supervisor Write Enable */
+#define SPR_DTLBTR_PPN 0xffffe000 /* Physical Page Number */
+
+#define DTLB_PR_NOLIMIT ( SPR_DTLBTR_URE | \
+ SPR_DTLBTR_UWE | \
+ SPR_DTLBTR_SRE | \
+ SPR_DTLBTR_SWE )
+
+/*
+ * Bit definitions for the Instruction TLB Match Register
+ *
+ */
+#define SPR_ITLBMR_V 0x00000001 /* Valid */
+#define SPR_ITLBMR_PL1 0x00000002 /* Page Level 1 (if 0 then PL2) */
+#define SPR_ITLBMR_CID 0x0000003c /* Context ID */
+#define SPR_ITLBMR_LRU 0x000000c0 /* Least Recently Used */
+#define SPR_ITLBMR_VPN 0xffffe000 /* Virtual Page Number */
+
+/*
+ * Bit definitions for the Instruction TLB Translate Register
+ *
+ */
+#define SPR_ITLBTR_CC 0x00000001 /* Cache Coherency */
+#define SPR_ITLBTR_CI 0x00000002 /* Cache Inhibit */
+#define SPR_ITLBTR_WBC 0x00000004 /* Write-Back Cache */
+#define SPR_ITLBTR_WOM 0x00000008 /* Weakly-Ordered Memory */
+#define SPR_ITLBTR_A 0x00000010 /* Accessed */
+#define SPR_ITLBTR_D 0x00000020 /* Dirty */
+#define SPR_ITLBTR_SXE 0x00000040 /* User Read Enable */
+#define SPR_ITLBTR_UXE 0x00000080 /* User Write Enable */
+#define SPR_ITLBTR_PPN 0xffffe000 /* Physical Page Number */
+
+#define ITLB_PR_NOLIMIT ( SPR_ITLBTR_SXE | \
+ SPR_ITLBTR_UXE )
+
+
+/*
+ * Bit definitions for Data Cache Control register
+ *
+ */
+#define SPR_DCCR_EW 0x000000ff /* Enable ways */
+
+/*
+ * Bit definitions for Insn Cache Control register
+ *
+ */
+#define SPR_ICCR_EW 0x000000ff /* Enable ways */
+
+/*
+ * Bit definitions for Data Cache Configuration Register
+ *
+ */
+
+#define SPR_DCCFGR_NCW 0x00000007
+#define SPR_DCCFGR_NCS 0x00000078
+#define SPR_DCCFGR_CBS 0x00000080
+#define SPR_DCCFGR_CWS 0x00000100
+#define SPR_DCCFGR_CCRI 0x00000200
+#define SPR_DCCFGR_CBIRI 0x00000400
+#define SPR_DCCFGR_CBPRI 0x00000800
+#define SPR_DCCFGR_CBLRI 0x00001000
+#define SPR_DCCFGR_CBFRI 0x00002000
+#define SPR_DCCFGR_CBWBRI 0x00004000
+
+#define SPR_DCCFGR_NCW_OFF 0
+#define SPR_DCCFGR_NCS_OFF 3
+#define SPR_DCCFGR_CBS_OFF 7
+
+/*
+ * Bit definitions for Instruction Cache Configuration Register
+ *
+ */
+#define SPR_ICCFGR_NCW 0x00000007
+#define SPR_ICCFGR_NCS 0x00000078
+#define SPR_ICCFGR_CBS 0x00000080
+#define SPR_ICCFGR_CCRI 0x00000200
+#define SPR_ICCFGR_CBIRI 0x00000400
+#define SPR_ICCFGR_CBPRI 0x00000800
+#define SPR_ICCFGR_CBLRI 0x00001000
+
+#define SPR_ICCFGR_NCW_OFF 0
+#define SPR_ICCFGR_NCS_OFF 3
+#define SPR_ICCFGR_CBS_OFF 7
+
+/*
+ * Bit definitions for Data MMU Configuration Register
+ *
+ */
+
+#define SPR_DMMUCFGR_NTW 0x00000003
+#define SPR_DMMUCFGR_NTS 0x0000001C
+#define SPR_DMMUCFGR_NAE 0x000000E0
+#define SPR_DMMUCFGR_CRI 0x00000100
+#define SPR_DMMUCFGR_PRI 0x00000200
+#define SPR_DMMUCFGR_TEIRI 0x00000400
+#define SPR_DMMUCFGR_HTR 0x00000800
+
+#define SPR_DMMUCFGR_NTW_OFF 0
+#define SPR_DMMUCFGR_NTS_OFF 2
+
+/*
+ * Bit definitions for Instruction MMU Configuration Register
+ *
+ */
+
+#define SPR_IMMUCFGR_NTW 0x00000003
+#define SPR_IMMUCFGR_NTS 0x0000001C
+#define SPR_IMMUCFGR_NAE 0x000000E0
+#define SPR_IMMUCFGR_CRI 0x00000100
+#define SPR_IMMUCFGR_PRI 0x00000200
+#define SPR_IMMUCFGR_TEIRI 0x00000400
+#define SPR_IMMUCFGR_HTR 0x00000800
+
+#define SPR_IMMUCFGR_NTW_OFF 0
+#define SPR_IMMUCFGR_NTS_OFF 2
+
+/*
+ * Bit definitions for Debug Control registers
+ *
+ */
+#define SPR_DCR_DP 0x00000001 /* DVR/DCR present */
+#define SPR_DCR_CC 0x0000000e /* Compare condition */
+#define SPR_DCR_SC 0x00000010 /* Signed compare */
+#define SPR_DCR_CT 0x000000e0 /* Compare to */
+
+/* Bit results with SPR_DCR_CC mask */
+#define SPR_DCR_CC_MASKED 0x00000000
+#define SPR_DCR_CC_EQUAL 0x00000002
+#define SPR_DCR_CC_LESS 0x00000004
+#define SPR_DCR_CC_LESSE 0x00000006
+#define SPR_DCR_CC_GREAT 0x00000008
+#define SPR_DCR_CC_GREATE 0x0000000a
+#define SPR_DCR_CC_NEQUAL 0x0000000c
+
+/* Bit results with SPR_DCR_CT mask */
+#define SPR_DCR_CT_DISABLED 0x00000000
+#define SPR_DCR_CT_IFEA 0x00000020
+#define SPR_DCR_CT_LEA 0x00000040
+#define SPR_DCR_CT_SEA 0x00000060
+#define SPR_DCR_CT_LD 0x00000080
+#define SPR_DCR_CT_SD 0x000000a0
+#define SPR_DCR_CT_LSEA 0x000000c0
+#define SPR_DCR_CT_LSD 0x000000e0
+/* SPR_DCR_CT_LSD doesn't seem to be implemented anywhere in or1ksim. 2004-1-30 HP */
+
+/*
+ * Bit definitions for Debug Mode 1 register
+ *
+ */
+#define SPR_DMR1_CW 0x000fffff /* Chain register pair data */
+#define SPR_DMR1_CW0_AND 0x00000001
+#define SPR_DMR1_CW0_OR 0x00000002
+#define SPR_DMR1_CW0 (SPR_DMR1_CW0_AND | SPR_DMR1_CW0_OR)
+#define SPR_DMR1_CW1_AND 0x00000004
+#define SPR_DMR1_CW1_OR 0x00000008
+#define SPR_DMR1_CW1 (SPR_DMR1_CW1_AND | SPR_DMR1_CW1_OR)
+#define SPR_DMR1_CW2_AND 0x00000010
+#define SPR_DMR1_CW2_OR 0x00000020
+#define SPR_DMR1_CW2 (SPR_DMR1_CW2_AND | SPR_DMR1_CW2_OR)
+#define SPR_DMR1_CW3_AND 0x00000040
+#define SPR_DMR1_CW3_OR 0x00000080
+#define SPR_DMR1_CW3 (SPR_DMR1_CW3_AND | SPR_DMR1_CW3_OR)
+#define SPR_DMR1_CW4_AND 0x00000100
+#define SPR_DMR1_CW4_OR 0x00000200
+#define SPR_DMR1_CW4 (SPR_DMR1_CW4_AND | SPR_DMR1_CW4_OR)
+#define SPR_DMR1_CW5_AND 0x00000400
+#define SPR_DMR1_CW5_OR 0x00000800
+#define SPR_DMR1_CW5 (SPR_DMR1_CW5_AND | SPR_DMR1_CW5_OR)
+#define SPR_DMR1_CW6_AND 0x00001000
+#define SPR_DMR1_CW6_OR 0x00002000
+#define SPR_DMR1_CW6 (SPR_DMR1_CW6_AND | SPR_DMR1_CW6_OR)
+#define SPR_DMR1_CW7_AND 0x00004000
+#define SPR_DMR1_CW7_OR 0x00008000
+#define SPR_DMR1_CW7 (SPR_DMR1_CW7_AND | SPR_DMR1_CW7_OR)
+#define SPR_DMR1_CW8_AND 0x00010000
+#define SPR_DMR1_CW8_OR 0x00020000
+#define SPR_DMR1_CW8 (SPR_DMR1_CW8_AND | SPR_DMR1_CW8_OR)
+#define SPR_DMR1_CW9_AND 0x00040000
+#define SPR_DMR1_CW9_OR 0x00080000
+#define SPR_DMR1_CW9 (SPR_DMR1_CW9_AND | SPR_DMR1_CW9_OR)
+#define SPR_DMR1_RES1 0x00300000 /* Reserved */
+#define SPR_DMR1_ST 0x00400000 /* Single-step trace*/
+#define SPR_DMR1_BT 0x00800000 /* Branch trace */
+#define SPR_DMR1_RES2 0xff000000 /* Reserved */
+
+/*
+ * Bit definitions for Debug Mode 2 register. AWTC and WGB corrected by JPB
+ *
+ */
+#define SPR_DMR2_WCE0 0x00000001 /* Watchpoint counter 0 enable */
+#define SPR_DMR2_WCE1 0x00000002 /* Watchpoint counter 0 enable */
+#define SPR_DMR2_AWTC 0x00000ffc /* Assign watchpoints to counters */
+#define SPR_DMR2_AWTC_OFF 2 /* Bit offset to AWTC field */
+#define SPR_DMR2_WGB 0x003ff000 /* Watchpoints generating breakpoint */
+#define SPR_DMR2_WGB_OFF 12 /* Bit offset to WGB field */
+#define SPR_DMR2_WBS 0xffc00000 /* JPB: Watchpoint status */
+#define SPR_DMR2_WBS_OFF 22 /* Bit offset to WBS field */
+
+/*
+ * Bit definitions for Debug watchpoint counter registers
+ *
+ */
+#define SPR_DWCR_COUNT 0x0000ffff /* Count */
+#define SPR_DWCR_MATCH 0xffff0000 /* Match */
+#define SPR_DWCR_MATCH_OFF 16 /* Match bit offset */
+
+/*
+ * Bit definitions for Debug stop register
+ *
+ */
+#define SPR_DSR_RSTE 0x00000001 /* Reset exception */
+#define SPR_DSR_BUSEE 0x00000002 /* Bus error exception */
+#define SPR_DSR_DPFE 0x00000004 /* Data Page Fault exception */
+#define SPR_DSR_IPFE 0x00000008 /* Insn Page Fault exception */
+#define SPR_DSR_TTE 0x00000010 /* Tick Timer exception */
+#define SPR_DSR_AE 0x00000020 /* Alignment exception */
+#define SPR_DSR_IIE 0x00000040 /* Illegal Instruction exception */
+#define SPR_DSR_IE 0x00000080 /* Interrupt exception */
+#define SPR_DSR_DME 0x00000100 /* DTLB miss exception */
+#define SPR_DSR_IME 0x00000200 /* ITLB miss exception */
+#define SPR_DSR_RE 0x00000400 /* Range exception */
+#define SPR_DSR_SCE 0x00000800 /* System call exception */
+#define SPR_DSR_FPE 0x00001000 /* Floating Point Exception */
+#define SPR_DSR_TE 0x00002000 /* Trap exception */
+
+/*
+ * Bit definitions for Debug reason register
+ *
+ */
+#define SPR_DRR_RSTE 0x00000001 /* Reset exception */
+#define SPR_DRR_BUSEE 0x00000002 /* Bus error exception */
+#define SPR_DRR_DPFE 0x00000004 /* Data Page Fault exception */
+#define SPR_DRR_IPFE 0x00000008 /* Insn Page Fault exception */
+#define SPR_DRR_TTE 0x00000010 /* Tick Timer exception */
+#define SPR_DRR_AE 0x00000020 /* Alignment exception */
+#define SPR_DRR_IIE 0x00000040 /* Illegal Instruction exception */
+#define SPR_DRR_IE 0x00000080 /* Interrupt exception */
+#define SPR_DRR_DME 0x00000100 /* DTLB miss exception */
+#define SPR_DRR_IME 0x00000200 /* ITLB miss exception */
+#define SPR_DRR_RE 0x00000400 /* Range exception */
+#define SPR_DRR_SCE 0x00000800 /* System call exception */
+#define SPR_DRR_FPE 0x00001000 /* Floating Point Exception */
+#define SPR_DRR_TE 0x00002000 /* Trap exception */
+
+/*
+ * Bit definitions for Performance counters mode registers
+ *
+ */
+#define SPR_PCMR_CP 0x00000001 /* Counter present */
+#define SPR_PCMR_UMRA 0x00000002 /* User mode read access */
+#define SPR_PCMR_CISM 0x00000004 /* Count in supervisor mode */
+#define SPR_PCMR_CIUM 0x00000008 /* Count in user mode */
+#define SPR_PCMR_LA 0x00000010 /* Load access event */
+#define SPR_PCMR_SA 0x00000020 /* Store access event */
+#define SPR_PCMR_IF 0x00000040 /* Instruction fetch event*/
+#define SPR_PCMR_DCM 0x00000080 /* Data cache miss event */
+#define SPR_PCMR_ICM 0x00000100 /* Insn cache miss event */
+#define SPR_PCMR_IFS 0x00000200 /* Insn fetch stall event */
+#define SPR_PCMR_LSUS 0x00000400 /* LSU stall event */
+#define SPR_PCMR_BS 0x00000800 /* Branch stall event */
+#define SPR_PCMR_DTLBM 0x00001000 /* DTLB miss event */
+#define SPR_PCMR_ITLBM 0x00002000 /* ITLB miss event */
+#define SPR_PCMR_DDS 0x00004000 /* Data dependency stall event */
+#define SPR_PCMR_WPE 0x03ff8000 /* Watchpoint events */
+
+/*
+ * Bit definitions for the Power management register
+ *
+ */
+#define SPR_PMR_SDF 0x0000000f /* Slow down factor */
+#define SPR_PMR_DME 0x00000010 /* Doze mode enable */
+#define SPR_PMR_SME 0x00000020 /* Sleep mode enable */
+#define SPR_PMR_DCGE 0x00000040 /* Dynamic clock gating enable */
+#define SPR_PMR_SUME 0x00000080 /* Suspend mode enable */
+
+/*
+ * Bit definitions for PICMR
+ *
+ */
+#define SPR_PICMR_IUM 0xfffffffc /* Interrupt unmask */
+
+/*
+ * Bit definitions for PICPR
+ *
+ */
+#define SPR_PICPR_IPRIO 0xfffffffc /* Interrupt priority */
+
+/*
+ * Bit definitions for PICSR
+ *
+ */
+#define SPR_PICSR_IS 0xffffffff /* Interrupt status */
+
+/*
+ * Bit definitions for Tick Timer Control Register
+ *
+ */
+#define SPR_TTCR_PERIOD 0x0fffffff /* Time Period */
+#define SPR_TTMR_PERIOD SPR_TTCR_PERIOD
+#define SPR_TTMR_IP 0x10000000 /* Interrupt Pending */
+#define SPR_TTMR_IE 0x20000000 /* Interrupt Enable */
+#define SPR_TTMR_RT 0x40000000 /* Restart tick */
+#define SPR_TTMR_SR 0x80000000 /* Single run */
+#define SPR_TTMR_CR 0xc0000000 /* Continuous run */
+#define SPR_TTMR_M 0xc0000000 /* Tick mode */
+
+/*
+ * Bit definitions for the FP Control Status Register
+ *
+ */
+#define SPR_FPCSR_FPEE 0x00000001 /* Floating Point Exception Enable */
+#define SPR_FPCSR_RM 0x00000006 /* Rounding Mode */
+#define SPR_FPCSR_OVF 0x00000008 /* Overflow Flag */
+#define SPR_FPCSR_UNF 0x00000010 /* Underflow Flag */
+#define SPR_FPCSR_SNF 0x00000020 /* SNAN Flag */
+#define SPR_FPCSR_QNF 0x00000040 /* QNAN Flag */
+#define SPR_FPCSR_ZF 0x00000080 /* Zero Flag */
+#define SPR_FPCSR_IXF 0x00000100 /* Inexact Flag */
+#define SPR_FPCSR_IVF 0x00000200 /* Invalid Flag */
+#define SPR_FPCSR_INF 0x00000400 /* Infinity Flag */
+#define SPR_FPCSR_DZF 0x00000800 /* Divide By Zero Flag */
+#define SPR_FPCSR_ALLF (SPR_FPCSR_OVF | SPR_FPCSR_UNF | SPR_FPCSR_SNF | \
+ SPR_FPCSR_QNF | SPR_FPCSR_ZF | SPR_FPCSR_IXF | \
+ SPR_FPCSR_IVF | SPR_FPCSR_INF | SPR_FPCSR_DZF)
+
+#define FPCSR_RM_RN (0<<1)
+#define FPCSR_RM_RZ (1<<1)
+#define FPCSR_RM_RIP (2<<1)
+#define FPCSR_RM_RIN (3<<1)
+
+#endif /* SPR_DEFS__H */
--- /dev/null
+#ifndef __STDARG_H
+#define __STDARG_H
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define va_start(v, l) __builtin_va_start((v), l)
+#define va_arg(ap, type) __builtin_va_arg((ap), type)
+#define va_copy(aq, ap) __builtin_va_copy((aq), (ap))
+#define va_end(ap) __builtin_va_end(ap)
+#define va_list __builtin_va_list
+
+int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
+int vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
+int vsprintf(char *buf, const char *fmt, va_list args);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STDARG_H */
--- /dev/null
+#ifndef __STDBOOL_H
+#define __STDBOOL_H
+
+#define bool _Bool
+#define true 1
+#define false 0
+
+#endif /* __STDBOOL_H */
--- /dev/null
+#ifndef __STDDEF_H
+#define __STDDEF_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+#define NULL 0
+#else
+#define NULL ((void *)0)
+#endif
+
+typedef unsigned long size_t;
+typedef long ptrdiff_t;
+
+#define offsetof(s,m) (size_t)&(((s *)0)->m)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STDDEF_H */
--- /dev/null
+#ifndef __STDINT_H
+#define __STDINT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int intptr_t;
+typedef unsigned int uintptr_t;
+
+typedef unsigned long long uint64_t;
+typedef unsigned int uint32_t;
+typedef unsigned short uint16_t;
+typedef unsigned char uint8_t;
+
+typedef long long int64_t;
+typedef int int32_t;
+typedef short int16_t;
+typedef char int8_t;
+
+#define __int_c_join(a, b) a ## b
+#define __int_c(v, suffix) __int_c_join(v, suffix)
+#define __uint_c(v, suffix) __int_c_join(v##U, suffix)
+
+#define INT64_C(v) __int_c(v, LL)
+#define UINT64_C(v) __uint_c(v, LL)
+#define INT32_C(v) v
+#define UINT32_C(v) v##U
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STDINT_H */
--- /dev/null
+#ifndef __STDIO_H
+#define __STDIO_H
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int putchar(int c);
+int puts(const char *s);
+
+int snprintf(char *buf, size_t size, const char *fmt, ...);
+int scnprintf(char *buf, size_t size, const char *fmt, ...);
+int sprintf(char *buf, const char *fmt, ...);
+
+int printf(const char *fmt, ...);
+
+/* Not sure this belongs here... */
+typedef long long loff_t;
+typedef long off_t;
+typedef int mode_t;
+typedef int dev_t;
+
+/*
+ * Note: this library does not provide FILE operations.
+ * User code must implement them.
+ */
+
+#ifndef BUFSIZ
+#define BUFSIZ 1024
+#endif
+
+#ifndef EOF
+#define EOF -1
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+
+#ifndef SEEK_CUR
+#define SEEK_CUR 1
+#endif
+
+#ifndef SEEK_END
+#define SEEK_END 2
+#endif
+
+typedef int FILE;
+
+extern FILE *stdin;
+extern FILE *stdout;
+extern FILE *stderr;
+
+int fprintf(FILE *stream, const char *format, ...);
+int fflush(FILE *stream);
+
+FILE *fopen(const char *path, const char *mode);
+FILE *freopen(const char *path, const char *mode, FILE *stream);
+char *fgets(char *s, int size, FILE *stream);
+size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
+size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
+int getc(FILE *stream);
+int fputc(int c, FILE *stream);
+int ferror(FILE *stream);
+int feof(FILE *stream);
+int fclose(FILE *fp);
+
+int fseek(FILE *stream, long offset, int whence);
+long ftell(FILE *stream);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STDIO_H */
--- /dev/null
+/*
+ * MiSoC
+ * Copyright (C) 2007, 2008, 2009, 2011 Sebastien Bourdeauducq
+ * Copyright (C) Linux kernel developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __STDLIB_H
+#define __STDLIB_H
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PRINTF_ZEROPAD 1 /* pad with zero */
+#define PRINTF_SIGN 2 /* unsigned/signed long */
+#define PRINTF_PLUS 4 /* show plus */
+#define PRINTF_SPACE 8 /* space if plus */
+#define PRINTF_LEFT 16 /* left justified */
+#define PRINTF_SPECIAL 32 /* 0x */
+#define PRINTF_LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */
+
+#define likely(x) x
+#define unlikely(x) x
+
+static inline int abs(int x)
+{
+ return x > 0 ? x : -x;
+}
+
+static inline long int labs(long int x)
+{
+ return x > 0 ? x : -x;
+}
+
+unsigned long strtoul(const char *nptr, char **endptr, int base);
+long strtol(const char *nptr, char **endptr, int base);
+double strtod(const char *str, char **endptr);
+
+int skip_atoi(const char **s);
+static inline int atoi(const char *nptr) {
+ return strtol(nptr, NULL, 10);
+}
+static inline long atol(const char *nptr) {
+ return (long)atoi(nptr);
+}
+char *number(char *buf, char *end, unsigned long num, int base, int size, int precision, int type);
+
+#define RAND_MAX 2147483647
+
+unsigned int rand(void);
+void srand(unsigned int seed);
+void abort(void) __attribute__((noreturn));
+
+void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));
+
+/*
+ * The following functions are not provided by this library.
+ */
+
+char *getenv(const char *name);
+
+void *malloc(size_t size);
+void free(void *ptr);
+void *realloc(void *ptr, size_t size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STDLIB_H */
--- /dev/null
+/*
+ * MiSoC
+ * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
+ * Copyright (C) Linus Torvalds and Linux kernel developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __STRING_H
+#define __STRING_H
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+char *strchr(const char *s, int c);
+char *strpbrk(const char *,const char *);
+char *strrchr(const char *s, int c);
+char *strnchr(const char *s, size_t count, int c);
+char *strcpy(char *dest, const char *src);
+char *strncpy(char *dest, const char *src, size_t count);
+int strcmp(const char *cs, const char *ct);
+int strncmp(const char *cs, const char *ct, size_t count);
+char *strcat(char *dest, const char *src);
+char *strncat(char *dest, const char *src, size_t n);
+size_t strlen(const char *s);
+size_t strnlen(const char *s, size_t count);
+size_t strspn(const char *s, const char *accept);
+int memcmp(const void *cs, const void *ct, size_t count);
+void *memset(void *s, int c, size_t count);
+void *memcpy(void *to, const void *from, size_t n);
+void *memmove(void *dest, const void *src, size_t count);
+char *strstr(const char *s1, const char *s2);
+void *memchr(const void *s, int c, size_t n);
+
+char *strerror(int errnum);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STRING_H */
--- /dev/null
+#ifndef __SYSTEM_H
+#define __SYSTEM_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void flush_cpu_icache(void);
+void flush_cpu_dcache(void);
+void flush_l2_cache(void);
+
+#ifdef __or1k__
+#include <spr-defs.h>
+static inline unsigned long mfspr(unsigned long add)
+{
+ unsigned long ret;
+
+ __asm__ __volatile__ ("l.mfspr %0,r0,%1" : "=r" (ret) : "K" (add));
+
+ return ret;
+}
+
+static inline void mtspr(unsigned long add, unsigned long val)
+{
+ __asm__ __volatile__ ("l.mtspr r0,%1,%0" : : "K" (add), "r" (val));
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SYSTEM_H */
--- /dev/null
+#ifndef __TIME_H
+#define __TIME_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void time_init(void);
+int elapsed(int *last_event, int period);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIME_H */
--- /dev/null
+#ifndef __UART_H
+#define __UART_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void uart_init(void);
+void uart_isr(void);
+void uart_sync(void);
+
+void uart_write(char c);
+char uart_read(void);
+int uart_read_nonblock(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
--- /dev/null
+#ifndef __CXX_ALGORITHM
+#define __CXX_ALGORITHM
+
+#endif /* __CXX_ALGORITHM */
--- /dev/null
+#ifndef __CXX_CSTDDEF
+#define __CXX_CSTDDEF
+
+#include <stddef.h>
+
+namespace std {
+ using ::size_t;
+ using ::ptrdiff_t;
+}
+
+#endif /* __CXX_CSTDDEF */
--- /dev/null
+#ifndef __CXX_CSTDLIB
+#define __CXX_CSTDLIB
+
+#include <stdlib.h>
+
+#endif /* __CXX_CSTDLIB */
--- /dev/null
+#ifndef __CXX_NEW
+#define __CXX_NEW
+
+#include <cstddef>
+
+inline void* operator new (std::size_t size, void* ptr) noexcept
+ { return ptr; }
+
+#endif /* __CXX_NEW */
--- /dev/null
+#ifndef __DLFCN_H
+#define __DLFCN_H
+
+typedef struct
+{
+ const char *dli_fname; /* File name of defining object. */
+ void *dli_fbase; /* Load address of that object. */
+ const char *dli_sname; /* Name of nearest symbol. */
+ void *dli_saddr; /* Exact value of nearest symbol. */
+} Dl_info;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int dl_iterate_phdr (int (*__callback) (struct dl_phdr_info *,
+ size_t, void *),
+ void *__data);
+
+/* Fill in *INFO with the following information about ADDRESS.
+ Returns 0 iff no shared object's segments contain that address. */
+extern int dladdr (const void *__address, Dl_info *__info);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DLFCN_H */
--- /dev/null
+#ifndef __DYLD_H
+#define __DYLD_H
+
+#include <elf.h>
+
+struct dyld_info {
+ Elf32_Addr base;
+ const void *init;
+ const char *strtab;
+ const Elf32_Sym *symtab;
+ struct {
+ Elf32_Word nbucket;
+ Elf32_Word nchain;
+ const Elf32_Word *bucket;
+ const Elf32_Word *chain;
+ } hash;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int dyld_load(const void *shlib, Elf32_Addr base,
+ Elf32_Addr (*resolve_import)(const char *),
+ struct dyld_info *info, const char **error_out);
+void *dyld_lookup(const char *symbol, struct dyld_info *info);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __DYLD_H */
--- /dev/null
+/* This file defines standard ELF types, structures, and macros.
+ Copyright (C) 1995-2014 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _ELF_H
+#define _ELF_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Standard ELF types. */
+
+#include <stdint.h>
+
+/* Type for a 16-bit quantity. */
+typedef uint16_t Elf32_Half;
+typedef uint16_t Elf64_Half;
+
+/* Types for signed and unsigned 32-bit quantities. */
+typedef uint32_t Elf32_Word;
+typedef int32_t Elf32_Sword;
+typedef uint32_t Elf64_Word;
+typedef int32_t Elf64_Sword;
+
+/* Types for signed and unsigned 64-bit quantities. */
+typedef uint64_t Elf32_Xword;
+typedef int64_t Elf32_Sxword;
+typedef uint64_t Elf64_Xword;
+typedef int64_t Elf64_Sxword;
+
+/* Type of addresses. */
+typedef uint32_t Elf32_Addr;
+typedef uint64_t Elf64_Addr;
+
+/* Type of file offsets. */
+typedef uint32_t Elf32_Off;
+typedef uint64_t Elf64_Off;
+
+/* Type for section indices, which are 16-bit quantities. */
+typedef uint16_t Elf32_Section;
+typedef uint16_t Elf64_Section;
+
+/* Type for version symbol information. */
+typedef Elf32_Half Elf32_Versym;
+typedef Elf64_Half Elf64_Versym;
+
+
+/* The ELF file header. This appears at the start of every ELF file. */
+
+#define EI_NIDENT (16)
+
+typedef struct
+{
+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
+ Elf32_Half e_type; /* Object file type */
+ Elf32_Half e_machine; /* Architecture */
+ Elf32_Word e_version; /* Object file version */
+ Elf32_Addr e_entry; /* Entry point virtual address */
+ Elf32_Off e_phoff; /* Program header table file offset */
+ Elf32_Off e_shoff; /* Section header table file offset */
+ Elf32_Word e_flags; /* Processor-specific flags */
+ Elf32_Half e_ehsize; /* ELF header size in bytes */
+ Elf32_Half e_phentsize; /* Program header table entry size */
+ Elf32_Half e_phnum; /* Program header table entry count */
+ Elf32_Half e_shentsize; /* Section header table entry size */
+ Elf32_Half e_shnum; /* Section header table entry count */
+ Elf32_Half e_shstrndx; /* Section header string table index */
+} Elf32_Ehdr;
+
+typedef struct
+{
+ unsigned char e_ident[EI_NIDENT]; /* Magic number and other info */
+ Elf64_Half e_type; /* Object file type */
+ Elf64_Half e_machine; /* Architecture */
+ Elf64_Word e_version; /* Object file version */
+ Elf64_Addr e_entry; /* Entry point virtual address */
+ Elf64_Off e_phoff; /* Program header table file offset */
+ Elf64_Off e_shoff; /* Section header table file offset */
+ Elf64_Word e_flags; /* Processor-specific flags */
+ Elf64_Half e_ehsize; /* ELF header size in bytes */
+ Elf64_Half e_phentsize; /* Program header table entry size */
+ Elf64_Half e_phnum; /* Program header table entry count */
+ Elf64_Half e_shentsize; /* Section header table entry size */
+ Elf64_Half e_shnum; /* Section header table entry count */
+ Elf64_Half e_shstrndx; /* Section header string table index */
+} Elf64_Ehdr;
+
+/* Fields in the e_ident array. The EI_* macros are indices into the
+ array. The macros under each EI_* macro are the values the byte
+ may have. */
+
+#define EI_MAG0 0 /* File identification byte 0 index */
+#define ELFMAG0 0x7f /* Magic number byte 0 */
+
+#define EI_MAG1 1 /* File identification byte 1 index */
+#define ELFMAG1 'E' /* Magic number byte 1 */
+
+#define EI_MAG2 2 /* File identification byte 2 index */
+#define ELFMAG2 'L' /* Magic number byte 2 */
+
+#define EI_MAG3 3 /* File identification byte 3 index */
+#define ELFMAG3 'F' /* Magic number byte 3 */
+
+/* Conglomeration of the identification bytes, for easy testing as a word. */
+#define ELFMAG "\177ELF"
+#define SELFMAG 4
+
+#define EI_CLASS 4 /* File class byte index */
+#define ELFCLASSNONE 0 /* Invalid class */
+#define ELFCLASS32 1 /* 32-bit objects */
+#define ELFCLASS64 2 /* 64-bit objects */
+#define ELFCLASSNUM 3
+
+#define EI_DATA 5 /* Data encoding byte index */
+#define ELFDATANONE 0 /* Invalid data encoding */
+#define ELFDATA2LSB 1 /* 2's complement, little endian */
+#define ELFDATA2MSB 2 /* 2's complement, big endian */
+#define ELFDATANUM 3
+
+#define EI_VERSION 6 /* File version byte index */
+ /* Value must be EV_CURRENT */
+
+#define EI_OSABI 7 /* OS ABI identification */
+#define ELFOSABI_NONE 0 /* UNIX System V ABI */
+#define ELFOSABI_SYSV 0 /* Alias. */
+#define ELFOSABI_HPUX 1 /* HP-UX */
+#define ELFOSABI_NETBSD 2 /* NetBSD. */
+#define ELFOSABI_GNU 3 /* Object uses GNU ELF extensions. */
+#define ELFOSABI_LINUX ELFOSABI_GNU /* Compatibility alias. */
+#define ELFOSABI_SOLARIS 6 /* Sun Solaris. */
+#define ELFOSABI_AIX 7 /* IBM AIX. */
+#define ELFOSABI_IRIX 8 /* SGI Irix. */
+#define ELFOSABI_FREEBSD 9 /* FreeBSD. */
+#define ELFOSABI_TRU64 10 /* Compaq TRU64 UNIX. */
+#define ELFOSABI_MODESTO 11 /* Novell Modesto. */
+#define ELFOSABI_OPENBSD 12 /* OpenBSD. */
+#define ELFOSABI_ARM_AEABI 64 /* ARM EABI */
+#define ELFOSABI_ARM 97 /* ARM */
+#define ELFOSABI_STANDALONE 255 /* Standalone (embedded) application */
+
+#define EI_ABIVERSION 8 /* ABI version */
+
+#define EI_PAD 9 /* Byte index of padding bytes */
+
+/* Legal values for e_type (object file type). */
+
+#define ET_NONE 0 /* No file type */
+#define ET_REL 1 /* Relocatable file */
+#define ET_EXEC 2 /* Executable file */
+#define ET_DYN 3 /* Shared object file */
+#define ET_CORE 4 /* Core file */
+#define ET_NUM 5 /* Number of defined types */
+#define ET_LOOS 0xfe00 /* OS-specific range start */
+#define ET_HIOS 0xfeff /* OS-specific range end */
+#define ET_LOPROC 0xff00 /* Processor-specific range start */
+#define ET_HIPROC 0xffff /* Processor-specific range end */
+
+/* Legal values for e_machine (architecture). */
+
+#define EM_NONE 0 /* No machine */
+#define EM_M32 1 /* AT&T WE 32100 */
+#define EM_SPARC 2 /* SUN SPARC */
+#define EM_386 3 /* Intel 80386 */
+#define EM_68K 4 /* Motorola m68k family */
+#define EM_88K 5 /* Motorola m88k family */
+#define EM_860 7 /* Intel 80860 */
+#define EM_MIPS 8 /* MIPS R3000 big-endian */
+#define EM_S370 9 /* IBM System/370 */
+#define EM_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */
+
+#define EM_PARISC 15 /* HPPA */
+#define EM_VPP500 17 /* Fujitsu VPP500 */
+#define EM_SPARC32PLUS 18 /* Sun's "v8plus" */
+#define EM_960 19 /* Intel 80960 */
+#define EM_PPC 20 /* PowerPC */
+#define EM_PPC64 21 /* PowerPC 64-bit */
+#define EM_S390 22 /* IBM S390 */
+
+#define EM_V800 36 /* NEC V800 series */
+#define EM_FR20 37 /* Fujitsu FR20 */
+#define EM_RH32 38 /* TRW RH-32 */
+#define EM_RCE 39 /* Motorola RCE */
+#define EM_ARM 40 /* ARM */
+#define EM_FAKE_ALPHA 41 /* Digital Alpha */
+#define EM_SH 42 /* Hitachi SH */
+#define EM_SPARCV9 43 /* SPARC v9 64-bit */
+#define EM_TRICORE 44 /* Siemens Tricore */
+#define EM_ARC 45 /* Argonaut RISC Core */
+#define EM_H8_300 46 /* Hitachi H8/300 */
+#define EM_H8_300H 47 /* Hitachi H8/300H */
+#define EM_H8S 48 /* Hitachi H8S */
+#define EM_H8_500 49 /* Hitachi H8/500 */
+#define EM_IA_64 50 /* Intel Merced */
+#define EM_MIPS_X 51 /* Stanford MIPS-X */
+#define EM_COLDFIRE 52 /* Motorola Coldfire */
+#define EM_68HC12 53 /* Motorola M68HC12 */
+#define EM_MMA 54 /* Fujitsu MMA Multimedia Accelerator*/
+#define EM_PCP 55 /* Siemens PCP */
+#define EM_NCPU 56 /* Sony nCPU embeeded RISC */
+#define EM_NDR1 57 /* Denso NDR1 microprocessor */
+#define EM_STARCORE 58 /* Motorola Start*Core processor */
+#define EM_ME16 59 /* Toyota ME16 processor */
+#define EM_ST100 60 /* STMicroelectronic ST100 processor */
+#define EM_TINYJ 61 /* Advanced Logic Corp. Tinyj emb.fam*/
+#define EM_X86_64 62 /* AMD x86-64 architecture */
+#define EM_PDSP 63 /* Sony DSP Processor */
+
+#define EM_FX66 66 /* Siemens FX66 microcontroller */
+#define EM_ST9PLUS 67 /* STMicroelectronics ST9+ 8/16 mc */
+#define EM_ST7 68 /* STmicroelectronics ST7 8 bit mc */
+#define EM_68HC16 69 /* Motorola MC68HC16 microcontroller */
+#define EM_68HC11 70 /* Motorola MC68HC11 microcontroller */
+#define EM_68HC08 71 /* Motorola MC68HC08 microcontroller */
+#define EM_68HC05 72 /* Motorola MC68HC05 microcontroller */
+#define EM_SVX 73 /* Silicon Graphics SVx */
+#define EM_ST19 74 /* STMicroelectronics ST19 8 bit mc */
+#define EM_VAX 75 /* Digital VAX */
+#define EM_CRIS 76 /* Axis Communications 32-bit embedded processor */
+#define EM_JAVELIN 77 /* Infineon Technologies 32-bit embedded processor */
+#define EM_FIREPATH 78 /* Element 14 64-bit DSP Processor */
+#define EM_ZSP 79 /* LSI Logic 16-bit DSP Processor */
+#define EM_MMIX 80 /* Donald Knuth's educational 64-bit processor */
+#define EM_HUANY 81 /* Harvard University machine-independent object files */
+#define EM_PRISM 82 /* SiTera Prism */
+#define EM_AVR 83 /* Atmel AVR 8-bit microcontroller */
+#define EM_FR30 84 /* Fujitsu FR30 */
+#define EM_D10V 85 /* Mitsubishi D10V */
+#define EM_D30V 86 /* Mitsubishi D30V */
+#define EM_V850 87 /* NEC v850 */
+#define EM_M32R 88 /* Mitsubishi M32R */
+#define EM_MN10300 89 /* Matsushita MN10300 */
+#define EM_MN10200 90 /* Matsushita MN10200 */
+#define EM_PJ 91 /* picoJava */
+#define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */
+#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */
+#define EM_XTENSA 94 /* Tensilica Xtensa Architecture */
+#define EM_AARCH64 183 /* ARM AARCH64 */
+#define EM_TILEPRO 188 /* Tilera TILEPro */
+#define EM_MICROBLAZE 189 /* Xilinx MicroBlaze */
+#define EM_TILEGX 191 /* Tilera TILE-Gx */
+#define EM_NUM 192
+
+/* If it is necessary to assign new unofficial EM_* values, please
+ pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
+ chances of collision with official or non-GNU unofficial values. */
+
+#define EM_ALPHA 0x9026
+
+/* Legal values for e_version (version). */
+
+#define EV_NONE 0 /* Invalid ELF version */
+#define EV_CURRENT 1 /* Current version */
+#define EV_NUM 2
+
+/* Section header. */
+
+typedef struct
+{
+ Elf32_Word sh_name; /* Section name (string tbl index) */
+ Elf32_Word sh_type; /* Section type */
+ Elf32_Word sh_flags; /* Section flags */
+ Elf32_Addr sh_addr; /* Section virtual addr at execution */
+ Elf32_Off sh_offset; /* Section file offset */
+ Elf32_Word sh_size; /* Section size in bytes */
+ Elf32_Word sh_link; /* Link to another section */
+ Elf32_Word sh_info; /* Additional section information */
+ Elf32_Word sh_addralign; /* Section alignment */
+ Elf32_Word sh_entsize; /* Entry size if section holds table */
+} Elf32_Shdr;
+
+typedef struct
+{
+ Elf64_Word sh_name; /* Section name (string tbl index) */
+ Elf64_Word sh_type; /* Section type */
+ Elf64_Xword sh_flags; /* Section flags */
+ Elf64_Addr sh_addr; /* Section virtual addr at execution */
+ Elf64_Off sh_offset; /* Section file offset */
+ Elf64_Xword sh_size; /* Section size in bytes */
+ Elf64_Word sh_link; /* Link to another section */
+ Elf64_Word sh_info; /* Additional section information */
+ Elf64_Xword sh_addralign; /* Section alignment */
+ Elf64_Xword sh_entsize; /* Entry size if section holds table */
+} Elf64_Shdr;
+
+/* Special section indices. */
+
+#define SHN_UNDEF 0 /* Undefined section */
+#define SHN_LORESERVE 0xff00 /* Start of reserved indices */
+#define SHN_LOPROC 0xff00 /* Start of processor-specific */
+#define SHN_BEFORE 0xff00 /* Order section before all others
+ (Solaris). */
+#define SHN_AFTER 0xff01 /* Order section after all others
+ (Solaris). */
+#define SHN_HIPROC 0xff1f /* End of processor-specific */
+#define SHN_LOOS 0xff20 /* Start of OS-specific */
+#define SHN_HIOS 0xff3f /* End of OS-specific */
+#define SHN_ABS 0xfff1 /* Associated symbol is absolute */
+#define SHN_COMMON 0xfff2 /* Associated symbol is common */
+#define SHN_XINDEX 0xffff /* Index is in extra table. */
+#define SHN_HIRESERVE 0xffff /* End of reserved indices */
+
+/* Legal values for sh_type (section type). */
+
+#define SHT_NULL 0 /* Section header table entry unused */
+#define SHT_PROGBITS 1 /* Program data */
+#define SHT_SYMTAB 2 /* Symbol table */
+#define SHT_STRTAB 3 /* String table */
+#define SHT_RELA 4 /* Relocation entries with addends */
+#define SHT_HASH 5 /* Symbol hash table */
+#define SHT_DYNAMIC 6 /* Dynamic linking information */
+#define SHT_NOTE 7 /* Notes */
+#define SHT_NOBITS 8 /* Program space with no data (bss) */
+#define SHT_REL 9 /* Relocation entries, no addends */
+#define SHT_SHLIB 10 /* Reserved */
+#define SHT_DYNSYM 11 /* Dynamic linker symbol table */
+#define SHT_INIT_ARRAY 14 /* Array of constructors */
+#define SHT_FINI_ARRAY 15 /* Array of destructors */
+#define SHT_PREINIT_ARRAY 16 /* Array of pre-constructors */
+#define SHT_GROUP 17 /* Section group */
+#define SHT_SYMTAB_SHNDX 18 /* Extended section indeces */
+#define SHT_NUM 19 /* Number of defined types. */
+#define SHT_LOOS 0x60000000 /* Start OS-specific. */
+#define SHT_GNU_ATTRIBUTES 0x6ffffff5 /* Object attributes. */
+#define SHT_GNU_HASH 0x6ffffff6 /* GNU-style hash table. */
+#define SHT_GNU_LIBLIST 0x6ffffff7 /* Prelink library list */
+#define SHT_CHECKSUM 0x6ffffff8 /* Checksum for DSO content. */
+#define SHT_LOSUNW 0x6ffffffa /* Sun-specific low bound. */
+#define SHT_SUNW_move 0x6ffffffa
+#define SHT_SUNW_COMDAT 0x6ffffffb
+#define SHT_SUNW_syminfo 0x6ffffffc
+#define SHT_GNU_verdef 0x6ffffffd /* Version definition section. */
+#define SHT_GNU_verneed 0x6ffffffe /* Version needs section. */
+#define SHT_GNU_versym 0x6fffffff /* Version symbol table. */
+#define SHT_HISUNW 0x6fffffff /* Sun-specific high bound. */
+#define SHT_HIOS 0x6fffffff /* End OS-specific type */
+#define SHT_LOPROC 0x70000000 /* Start of processor-specific */
+#define SHT_HIPROC 0x7fffffff /* End of processor-specific */
+#define SHT_LOUSER 0x80000000 /* Start of application-specific */
+#define SHT_HIUSER 0x8fffffff /* End of application-specific */
+
+/* Legal values for sh_flags (section flags). */
+
+#define SHF_WRITE (1 << 0) /* Writable */
+#define SHF_ALLOC (1 << 1) /* Occupies memory during execution */
+#define SHF_EXECINSTR (1 << 2) /* Executable */
+#define SHF_MERGE (1 << 4) /* Might be merged */
+#define SHF_STRINGS (1 << 5) /* Contains nul-terminated strings */
+#define SHF_INFO_LINK (1 << 6) /* `sh_info' contains SHT index */
+#define SHF_LINK_ORDER (1 << 7) /* Preserve order after combining */
+#define SHF_OS_NONCONFORMING (1 << 8) /* Non-standard OS specific handling
+ required */
+#define SHF_GROUP (1 << 9) /* Section is member of a group. */
+#define SHF_TLS (1 << 10) /* Section hold thread-local data. */
+#define SHF_MASKOS 0x0ff00000 /* OS-specific. */
+#define SHF_MASKPROC 0xf0000000 /* Processor-specific */
+#define SHF_ORDERED (1 << 30) /* Special ordering requirement
+ (Solaris). */
+#define SHF_EXCLUDE (1 << 31) /* Section is excluded unless
+ referenced or allocated (Solaris).*/
+
+/* Section group handling. */
+#define GRP_COMDAT 0x1 /* Mark group as COMDAT. */
+
+/* Symbol table entry. */
+
+typedef struct
+{
+ Elf32_Word st_name; /* Symbol name (string tbl index) */
+ Elf32_Addr st_value; /* Symbol value */
+ Elf32_Word st_size; /* Symbol size */
+ unsigned char st_info; /* Symbol type and binding */
+ unsigned char st_other; /* Symbol visibility */
+ Elf32_Section st_shndx; /* Section index */
+} Elf32_Sym;
+
+typedef struct
+{
+ Elf64_Word st_name; /* Symbol name (string tbl index) */
+ unsigned char st_info; /* Symbol type and binding */
+ unsigned char st_other; /* Symbol visibility */
+ Elf64_Section st_shndx; /* Section index */
+ Elf64_Addr st_value; /* Symbol value */
+ Elf64_Xword st_size; /* Symbol size */
+} Elf64_Sym;
+
+/* The syminfo section if available contains additional information about
+ every dynamic symbol. */
+
+typedef struct
+{
+ Elf32_Half si_boundto; /* Direct bindings, symbol bound to */
+ Elf32_Half si_flags; /* Per symbol flags */
+} Elf32_Syminfo;
+
+typedef struct
+{
+ Elf64_Half si_boundto; /* Direct bindings, symbol bound to */
+ Elf64_Half si_flags; /* Per symbol flags */
+} Elf64_Syminfo;
+
+/* Possible values for si_boundto. */
+#define SYMINFO_BT_SELF 0xffff /* Symbol bound to self */
+#define SYMINFO_BT_PARENT 0xfffe /* Symbol bound to parent */
+#define SYMINFO_BT_LOWRESERVE 0xff00 /* Beginning of reserved entries */
+
+/* Possible bitmasks for si_flags. */
+#define SYMINFO_FLG_DIRECT 0x0001 /* Direct bound symbol */
+#define SYMINFO_FLG_PASSTHRU 0x0002 /* Pass-thru symbol for translator */
+#define SYMINFO_FLG_COPY 0x0004 /* Symbol is a copy-reloc */
+#define SYMINFO_FLG_LAZYLOAD 0x0008 /* Symbol bound to object to be lazy
+ loaded */
+/* Syminfo version values. */
+#define SYMINFO_NONE 0
+#define SYMINFO_CURRENT 1
+#define SYMINFO_NUM 2
+
+
+/* How to extract and insert information held in the st_info field. */
+
+#define ELF32_ST_BIND(val) (((unsigned char) (val)) >> 4)
+#define ELF32_ST_TYPE(val) ((val) & 0xf)
+#define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf))
+
+/* Both Elf32_Sym and Elf64_Sym use the same one-byte st_info field. */
+#define ELF64_ST_BIND(val) ELF32_ST_BIND (val)
+#define ELF64_ST_TYPE(val) ELF32_ST_TYPE (val)
+#define ELF64_ST_INFO(bind, type) ELF32_ST_INFO ((bind), (type))
+
+/* Legal values for ST_BIND subfield of st_info (symbol binding). */
+
+#define STB_LOCAL 0 /* Local symbol */
+#define STB_GLOBAL 1 /* Global symbol */
+#define STB_WEAK 2 /* Weak symbol */
+#define STB_NUM 3 /* Number of defined types. */
+#define STB_LOOS 10 /* Start of OS-specific */
+#define STB_GNU_UNIQUE 10 /* Unique symbol. */
+#define STB_HIOS 12 /* End of OS-specific */
+#define STB_LOPROC 13 /* Start of processor-specific */
+#define STB_HIPROC 15 /* End of processor-specific */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type). */
+
+#define STT_NOTYPE 0 /* Symbol type is unspecified */
+#define STT_OBJECT 1 /* Symbol is a data object */
+#define STT_FUNC 2 /* Symbol is a code object */
+#define STT_SECTION 3 /* Symbol associated with a section */
+#define STT_FILE 4 /* Symbol's name is file name */
+#define STT_COMMON 5 /* Symbol is a common data object */
+#define STT_TLS 6 /* Symbol is thread-local data object*/
+#define STT_NUM 7 /* Number of defined types. */
+#define STT_LOOS 10 /* Start of OS-specific */
+#define STT_GNU_IFUNC 10 /* Symbol is indirect code object */
+#define STT_HIOS 12 /* End of OS-specific */
+#define STT_LOPROC 13 /* Start of processor-specific */
+#define STT_HIPROC 15 /* End of processor-specific */
+
+
+/* Symbol table indices are found in the hash buckets and chain table
+ of a symbol hash table section. This special index value indicates
+ the end of a chain, meaning no further symbols are found in that bucket. */
+
+#define STN_UNDEF 0 /* End of a chain. */
+
+
+/* How to extract and insert information held in the st_other field. */
+
+#define ELF32_ST_VISIBILITY(o) ((o) & 0x03)
+
+/* For ELF64 the definitions are the same. */
+#define ELF64_ST_VISIBILITY(o) ELF32_ST_VISIBILITY (o)
+
+/* Symbol visibility specification encoded in the st_other field. */
+#define STV_DEFAULT 0 /* Default symbol visibility rules */
+#define STV_INTERNAL 1 /* Processor specific hidden class */
+#define STV_HIDDEN 2 /* Sym unavailable in other modules */
+#define STV_PROTECTED 3 /* Not preemptible, not exported */
+
+
+/* Relocation table entry without addend (in section of type SHT_REL). */
+
+typedef struct
+{
+ Elf32_Addr r_offset; /* Address */
+ Elf32_Word r_info; /* Relocation type and symbol index */
+} Elf32_Rel;
+
+/* I have seen two different definitions of the Elf64_Rel and
+ Elf64_Rela structures, so we'll leave them out until Novell (or
+ whoever) gets their act together. */
+/* The following, at least, is used on Sparc v9, MIPS, and Alpha. */
+
+typedef struct
+{
+ Elf64_Addr r_offset; /* Address */
+ Elf64_Xword r_info; /* Relocation type and symbol index */
+} Elf64_Rel;
+
+/* Relocation table entry with addend (in section of type SHT_RELA). */
+
+typedef struct
+{
+ Elf32_Addr r_offset; /* Address */
+ Elf32_Word r_info; /* Relocation type and symbol index */
+ Elf32_Sword r_addend; /* Addend */
+} Elf32_Rela;
+
+typedef struct
+{
+ Elf64_Addr r_offset; /* Address */
+ Elf64_Xword r_info; /* Relocation type and symbol index */
+ Elf64_Sxword r_addend; /* Addend */
+} Elf64_Rela;
+
+/* How to extract and insert information held in the r_info field. */
+
+#define ELF32_R_SYM(val) ((val) >> 8)
+#define ELF32_R_TYPE(val) ((val) & 0xff)
+#define ELF32_R_INFO(sym, type) (((sym) << 8) + ((type) & 0xff))
+
+#define ELF64_R_SYM(i) ((i) >> 32)
+#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
+#define ELF64_R_INFO(sym,type) ((((Elf64_Xword) (sym)) << 32) + (type))
+
+/* Program segment header. */
+
+typedef struct
+{
+ Elf32_Word p_type; /* Segment type */
+ Elf32_Off p_offset; /* Segment file offset */
+ Elf32_Addr p_vaddr; /* Segment virtual address */
+ Elf32_Addr p_paddr; /* Segment physical address */
+ Elf32_Word p_filesz; /* Segment size in file */
+ Elf32_Word p_memsz; /* Segment size in memory */
+ Elf32_Word p_flags; /* Segment flags */
+ Elf32_Word p_align; /* Segment alignment */
+} Elf32_Phdr;
+
+typedef struct
+{
+ Elf64_Word p_type; /* Segment type */
+ Elf64_Word p_flags; /* Segment flags */
+ Elf64_Off p_offset; /* Segment file offset */
+ Elf64_Addr p_vaddr; /* Segment virtual address */
+ Elf64_Addr p_paddr; /* Segment physical address */
+ Elf64_Xword p_filesz; /* Segment size in file */
+ Elf64_Xword p_memsz; /* Segment size in memory */
+ Elf64_Xword p_align; /* Segment alignment */
+} Elf64_Phdr;
+
+/* Special value for e_phnum. This indicates that the real number of
+ program headers is too large to fit into e_phnum. Instead the real
+ value is in the field sh_info of section 0. */
+
+#define PN_XNUM 0xffff
+
+/* Legal values for p_type (segment type). */
+
+#define PT_NULL 0 /* Program header table entry unused */
+#define PT_LOAD 1 /* Loadable program segment */
+#define PT_DYNAMIC 2 /* Dynamic linking information */
+#define PT_INTERP 3 /* Program interpreter */
+#define PT_NOTE 4 /* Auxiliary information */
+#define PT_SHLIB 5 /* Reserved */
+#define PT_PHDR 6 /* Entry for header table itself */
+#define PT_TLS 7 /* Thread-local storage segment */
+#define PT_NUM 8 /* Number of defined types */
+#define PT_LOOS 0x60000000 /* Start of OS-specific */
+#define PT_GNU_EH_FRAME 0x6474e550 /* GCC .eh_frame_hdr segment */
+#define PT_GNU_STACK 0x6474e551 /* Indicates stack executability */
+#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */
+#define PT_LOSUNW 0x6ffffffa
+#define PT_SUNWBSS 0x6ffffffa /* Sun Specific segment */
+#define PT_SUNWSTACK 0x6ffffffb /* Stack segment */
+#define PT_HISUNW 0x6fffffff
+#define PT_HIOS 0x6fffffff /* End of OS-specific */
+#define PT_LOPROC 0x70000000 /* Start of processor-specific */
+#define PT_HIPROC 0x7fffffff /* End of processor-specific */
+
+/* Legal values for p_flags (segment flags). */
+
+#define PF_X (1 << 0) /* Segment is executable */
+#define PF_W (1 << 1) /* Segment is writable */
+#define PF_R (1 << 2) /* Segment is readable */
+#define PF_MASKOS 0x0ff00000 /* OS-specific */
+#define PF_MASKPROC 0xf0000000 /* Processor-specific */
+
+/* Legal values for note segment descriptor types for core files. */
+
+#define NT_PRSTATUS 1 /* Contains copy of prstatus struct */
+#define NT_FPREGSET 2 /* Contains copy of fpregset struct */
+#define NT_PRPSINFO 3 /* Contains copy of prpsinfo struct */
+#define NT_PRXREG 4 /* Contains copy of prxregset struct */
+#define NT_TASKSTRUCT 4 /* Contains copy of task structure */
+#define NT_PLATFORM 5 /* String from sysinfo(SI_PLATFORM) */
+#define NT_AUXV 6 /* Contains copy of auxv array */
+#define NT_GWINDOWS 7 /* Contains copy of gwindows struct */
+#define NT_ASRS 8 /* Contains copy of asrset struct */
+#define NT_PSTATUS 10 /* Contains copy of pstatus struct */
+#define NT_PSINFO 13 /* Contains copy of psinfo struct */
+#define NT_PRCRED 14 /* Contains copy of prcred struct */
+#define NT_UTSNAME 15 /* Contains copy of utsname struct */
+#define NT_LWPSTATUS 16 /* Contains copy of lwpstatus struct */
+#define NT_LWPSINFO 17 /* Contains copy of lwpinfo struct */
+#define NT_PRFPXREG 20 /* Contains copy of fprxregset struct */
+#define NT_SIGINFO 0x53494749 /* Contains copy of siginfo_t,
+ size might increase */
+#define NT_FILE 0x46494c45 /* Contains information about mapped
+ files */
+#define NT_PRXFPREG 0x46e62b7f /* Contains copy of user_fxsr_struct */
+#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
+#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */
+#define NT_PPC_VSX 0x102 /* PowerPC VSX registers */
+#define NT_386_TLS 0x200 /* i386 TLS slots (struct user_desc) */
+#define NT_386_IOPERM 0x201 /* x86 io permission bitmap (1=deny) */
+#define NT_X86_XSTATE 0x202 /* x86 extended state using xsave */
+#define NT_S390_HIGH_GPRS 0x300 /* s390 upper register halves */
+#define NT_S390_TIMER 0x301 /* s390 timer register */
+#define NT_S390_TODCMP 0x302 /* s390 TOD clock comparator register */
+#define NT_S390_TODPREG 0x303 /* s390 TOD programmable register */
+#define NT_S390_CTRS 0x304 /* s390 control registers */
+#define NT_S390_PREFIX 0x305 /* s390 prefix register */
+#define NT_S390_LAST_BREAK 0x306 /* s390 breaking event address */
+#define NT_S390_SYSTEM_CALL 0x307 /* s390 system call restart data */
+#define NT_S390_TDB 0x308 /* s390 transaction diagnostic block */
+#define NT_ARM_VFP 0x400 /* ARM VFP/NEON registers */
+#define NT_ARM_TLS 0x401 /* ARM TLS register */
+#define NT_ARM_HW_BREAK 0x402 /* ARM hardware breakpoint registers */
+#define NT_ARM_HW_WATCH 0x403 /* ARM hardware watchpoint registers */
+
+/* Legal values for the note segment descriptor types for object files. */
+
+#define NT_VERSION 1 /* Contains a version string. */
+
+
+/* Dynamic section entry. */
+
+typedef struct
+{
+ Elf32_Sword d_tag; /* Dynamic entry type */
+ union
+ {
+ Elf32_Word d_val; /* Integer value */
+ Elf32_Addr d_ptr; /* Address value */
+ } d_un;
+} Elf32_Dyn;
+
+typedef struct
+{
+ Elf64_Sxword d_tag; /* Dynamic entry type */
+ union
+ {
+ Elf64_Xword d_val; /* Integer value */
+ Elf64_Addr d_ptr; /* Address value */
+ } d_un;
+} Elf64_Dyn;
+
+/* Legal values for d_tag (dynamic entry type). */
+
+#define DT_NULL 0 /* Marks end of dynamic section */
+#define DT_NEEDED 1 /* Name of needed library */
+#define DT_PLTRELSZ 2 /* Size in bytes of PLT relocs */
+#define DT_PLTGOT 3 /* Processor defined value */
+#define DT_HASH 4 /* Address of symbol hash table */
+#define DT_STRTAB 5 /* Address of string table */
+#define DT_SYMTAB 6 /* Address of symbol table */
+#define DT_RELA 7 /* Address of Rela relocs */
+#define DT_RELASZ 8 /* Total size of Rela relocs */
+#define DT_RELAENT 9 /* Size of one Rela reloc */
+#define DT_STRSZ 10 /* Size of string table */
+#define DT_SYMENT 11 /* Size of one symbol table entry */
+#define DT_INIT 12 /* Address of init function */
+#define DT_FINI 13 /* Address of termination function */
+#define DT_SONAME 14 /* Name of shared object */
+#define DT_RPATH 15 /* Library search path (deprecated) */
+#define DT_SYMBOLIC 16 /* Start symbol search here */
+#define DT_REL 17 /* Address of Rel relocs */
+#define DT_RELSZ 18 /* Total size of Rel relocs */
+#define DT_RELENT 19 /* Size of one Rel reloc */
+#define DT_PLTREL 20 /* Type of reloc in PLT */
+#define DT_DEBUG 21 /* For debugging; unspecified */
+#define DT_TEXTREL 22 /* Reloc might modify .text */
+#define DT_JMPREL 23 /* Address of PLT relocs */
+#define DT_BIND_NOW 24 /* Process relocations of object */
+#define DT_INIT_ARRAY 25 /* Array with addresses of init fct */
+#define DT_FINI_ARRAY 26 /* Array with addresses of fini fct */
+#define DT_INIT_ARRAYSZ 27 /* Size in bytes of DT_INIT_ARRAY */
+#define DT_FINI_ARRAYSZ 28 /* Size in bytes of DT_FINI_ARRAY */
+#define DT_RUNPATH 29 /* Library search path */
+#define DT_FLAGS 30 /* Flags for the object being loaded */
+#define DT_ENCODING 32 /* Start of encoded range */
+#define DT_PREINIT_ARRAY 32 /* Array with addresses of preinit fct*/
+#define DT_PREINIT_ARRAYSZ 33 /* size in bytes of DT_PREINIT_ARRAY */
+#define DT_NUM 34 /* Number used */
+#define DT_LOOS 0x6000000d /* Start of OS-specific */
+#define DT_HIOS 0x6ffff000 /* End of OS-specific */
+#define DT_LOPROC 0x70000000 /* Start of processor-specific */
+#define DT_HIPROC 0x7fffffff /* End of processor-specific */
+#define DT_PROCNUM DT_MIPS_NUM /* Most used by any processor */
+
+/* DT_* entries which fall between DT_VALRNGHI & DT_VALRNGLO use the
+ Dyn.d_un.d_val field of the Elf*_Dyn structure. This follows Sun's
+ approach. */
+#define DT_VALRNGLO 0x6ffffd00
+#define DT_GNU_PRELINKED 0x6ffffdf5 /* Prelinking timestamp */
+#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */
+#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */
+#define DT_CHECKSUM 0x6ffffdf8
+#define DT_PLTPADSZ 0x6ffffdf9
+#define DT_MOVEENT 0x6ffffdfa
+#define DT_MOVESZ 0x6ffffdfb
+#define DT_FEATURE_1 0x6ffffdfc /* Feature selection (DTF_*). */
+#define DT_POSFLAG_1 0x6ffffdfd /* Flags for DT_* entries, effecting
+ the following DT_* entry. */
+#define DT_SYMINSZ 0x6ffffdfe /* Size of syminfo table (in bytes) */
+#define DT_SYMINENT 0x6ffffdff /* Entry size of syminfo */
+#define DT_VALRNGHI 0x6ffffdff
+#define DT_VALTAGIDX(tag) (DT_VALRNGHI - (tag)) /* Reverse order! */
+#define DT_VALNUM 12
+
+/* DT_* entries which fall between DT_ADDRRNGHI & DT_ADDRRNGLO use the
+ Dyn.d_un.d_ptr field of the Elf*_Dyn structure.
+
+ If any adjustment is made to the ELF object after it has been
+ built these entries will need to be adjusted. */
+#define DT_ADDRRNGLO 0x6ffffe00
+#define DT_GNU_HASH 0x6ffffef5 /* GNU-style hash table. */
+#define DT_TLSDESC_PLT 0x6ffffef6
+#define DT_TLSDESC_GOT 0x6ffffef7
+#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */
+#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */
+#define DT_CONFIG 0x6ffffefa /* Configuration information. */
+#define DT_DEPAUDIT 0x6ffffefb /* Dependency auditing. */
+#define DT_AUDIT 0x6ffffefc /* Object auditing. */
+#define DT_PLTPAD 0x6ffffefd /* PLT padding. */
+#define DT_MOVETAB 0x6ffffefe /* Move table. */
+#define DT_SYMINFO 0x6ffffeff /* Syminfo table. */
+#define DT_ADDRRNGHI 0x6ffffeff
+#define DT_ADDRTAGIDX(tag) (DT_ADDRRNGHI - (tag)) /* Reverse order! */
+#define DT_ADDRNUM 11
+
+/* The versioning entry types. The next are defined as part of the
+ GNU extension. */
+#define DT_VERSYM 0x6ffffff0
+
+#define DT_RELACOUNT 0x6ffffff9
+#define DT_RELCOUNT 0x6ffffffa
+
+/* These were chosen by Sun. */
+#define DT_FLAGS_1 0x6ffffffb /* State flags, see DF_1_* below. */
+#define DT_VERDEF 0x6ffffffc /* Address of version definition
+ table */
+#define DT_VERDEFNUM 0x6ffffffd /* Number of version definitions */
+#define DT_VERNEED 0x6ffffffe /* Address of table with needed
+ versions */
+#define DT_VERNEEDNUM 0x6fffffff /* Number of needed versions */
+#define DT_VERSIONTAGIDX(tag) (DT_VERNEEDNUM - (tag)) /* Reverse order! */
+#define DT_VERSIONTAGNUM 16
+
+/* Sun added these machine-independent extensions in the "processor-specific"
+ range. Be compatible. */
+#define DT_AUXILIARY 0x7ffffffd /* Shared object to load before self */
+#define DT_FILTER 0x7fffffff /* Shared object to get values from */
+#define DT_EXTRATAGIDX(tag) ((Elf32_Word)-((Elf32_Sword) (tag) <<1>>1)-1)
+#define DT_EXTRANUM 3
+
+/* Values of `d_un.d_val' in the DT_FLAGS entry. */
+#define DF_ORIGIN 0x00000001 /* Object may use DF_ORIGIN */
+#define DF_SYMBOLIC 0x00000002 /* Symbol resolutions starts here */
+#define DF_TEXTREL 0x00000004 /* Object contains text relocations */
+#define DF_BIND_NOW 0x00000008 /* No lazy binding for this object */
+#define DF_STATIC_TLS 0x00000010 /* Module uses the static TLS model */
+
+/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1
+ entry in the dynamic section. */
+#define DF_1_NOW 0x00000001 /* Set RTLD_NOW for this object. */
+#define DF_1_GLOBAL 0x00000002 /* Set RTLD_GLOBAL for this object. */
+#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */
+#define DF_1_NODELETE 0x00000008 /* Set RTLD_NODELETE for this object.*/
+#define DF_1_LOADFLTR 0x00000010 /* Trigger filtee loading at runtime.*/
+#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/
+#define DF_1_NOOPEN 0x00000040 /* Set RTLD_NOOPEN for this object. */
+#define DF_1_ORIGIN 0x00000080 /* $ORIGIN must be handled. */
+#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */
+#define DF_1_TRANS 0x00000200
+#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */
+#define DF_1_NODEFLIB 0x00000800 /* Ignore default lib search path. */
+#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */
+#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/
+#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */
+#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */
+#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */
+#define DF_1_NODIRECT 0x00020000 /* Object has no-direct binding. */
+#define DF_1_IGNMULDEF 0x00040000
+#define DF_1_NOKSYMS 0x00080000
+#define DF_1_NOHDR 0x00100000
+#define DF_1_EDITED 0x00200000 /* Object is modified after built. */
+#define DF_1_NORELOC 0x00400000
+#define DF_1_SYMINTPOSE 0x00800000 /* Object has individual interposers. */
+#define DF_1_GLOBAUDIT 0x01000000 /* Global auditing required. */
+#define DF_1_SINGLETON 0x02000000 /* Singleton symbols are used. */
+
+/* Flags for the feature selection in DT_FEATURE_1. */
+#define DTF_1_PARINIT 0x00000001
+#define DTF_1_CONFEXP 0x00000002
+
+/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */
+#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */
+#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not
+ generally available. */
+
+/* Version definition sections. */
+
+typedef struct
+{
+ Elf32_Half vd_version; /* Version revision */
+ Elf32_Half vd_flags; /* Version information */
+ Elf32_Half vd_ndx; /* Version Index */
+ Elf32_Half vd_cnt; /* Number of associated aux entries */
+ Elf32_Word vd_hash; /* Version name hash value */
+ Elf32_Word vd_aux; /* Offset in bytes to verdaux array */
+ Elf32_Word vd_next; /* Offset in bytes to next verdef
+ entry */
+} Elf32_Verdef;
+
+typedef struct
+{
+ Elf64_Half vd_version; /* Version revision */
+ Elf64_Half vd_flags; /* Version information */
+ Elf64_Half vd_ndx; /* Version Index */
+ Elf64_Half vd_cnt; /* Number of associated aux entries */
+ Elf64_Word vd_hash; /* Version name hash value */
+ Elf64_Word vd_aux; /* Offset in bytes to verdaux array */
+ Elf64_Word vd_next; /* Offset in bytes to next verdef
+ entry */
+} Elf64_Verdef;
+
+
+/* Legal values for vd_version (version revision). */
+#define VER_DEF_NONE 0 /* No version */
+#define VER_DEF_CURRENT 1 /* Current version */
+#define VER_DEF_NUM 2 /* Given version number */
+
+/* Legal values for vd_flags (version information flags). */
+#define VER_FLG_BASE 0x1 /* Version definition of file itself */
+#define VER_FLG_WEAK 0x2 /* Weak version identifier */
+
+/* Versym symbol index values. */
+#define VER_NDX_LOCAL 0 /* Symbol is local. */
+#define VER_NDX_GLOBAL 1 /* Symbol is global. */
+#define VER_NDX_LORESERVE 0xff00 /* Beginning of reserved entries. */
+#define VER_NDX_ELIMINATE 0xff01 /* Symbol is to be eliminated. */
+
+/* Auxialiary version information. */
+
+typedef struct
+{
+ Elf32_Word vda_name; /* Version or dependency names */
+ Elf32_Word vda_next; /* Offset in bytes to next verdaux
+ entry */
+} Elf32_Verdaux;
+
+typedef struct
+{
+ Elf64_Word vda_name; /* Version or dependency names */
+ Elf64_Word vda_next; /* Offset in bytes to next verdaux
+ entry */
+} Elf64_Verdaux;
+
+
+/* Version dependency section. */
+
+typedef struct
+{
+ Elf32_Half vn_version; /* Version of structure */
+ Elf32_Half vn_cnt; /* Number of associated aux entries */
+ Elf32_Word vn_file; /* Offset of filename for this
+ dependency */
+ Elf32_Word vn_aux; /* Offset in bytes to vernaux array */
+ Elf32_Word vn_next; /* Offset in bytes to next verneed
+ entry */
+} Elf32_Verneed;
+
+typedef struct
+{
+ Elf64_Half vn_version; /* Version of structure */
+ Elf64_Half vn_cnt; /* Number of associated aux entries */
+ Elf64_Word vn_file; /* Offset of filename for this
+ dependency */
+ Elf64_Word vn_aux; /* Offset in bytes to vernaux array */
+ Elf64_Word vn_next; /* Offset in bytes to next verneed
+ entry */
+} Elf64_Verneed;
+
+
+/* Legal values for vn_version (version revision). */
+#define VER_NEED_NONE 0 /* No version */
+#define VER_NEED_CURRENT 1 /* Current version */
+#define VER_NEED_NUM 2 /* Given version number */
+
+/* Auxiliary needed version information. */
+
+typedef struct
+{
+ Elf32_Word vna_hash; /* Hash value of dependency name */
+ Elf32_Half vna_flags; /* Dependency specific information */
+ Elf32_Half vna_other; /* Unused */
+ Elf32_Word vna_name; /* Dependency name string offset */
+ Elf32_Word vna_next; /* Offset in bytes to next vernaux
+ entry */
+} Elf32_Vernaux;
+
+typedef struct
+{
+ Elf64_Word vna_hash; /* Hash value of dependency name */
+ Elf64_Half vna_flags; /* Dependency specific information */
+ Elf64_Half vna_other; /* Unused */
+ Elf64_Word vna_name; /* Dependency name string offset */
+ Elf64_Word vna_next; /* Offset in bytes to next vernaux
+ entry */
+} Elf64_Vernaux;
+
+
+/* Legal values for vna_flags. */
+#define VER_FLG_WEAK 0x2 /* Weak version identifier */
+
+
+/* Auxiliary vector. */
+
+/* This vector is normally only used by the program interpreter. The
+ usual definition in an ABI supplement uses the name auxv_t. The
+ vector is not usually defined in a standard <elf.h> file, but it
+ can't hurt. We rename it to avoid conflicts. The sizes of these
+ types are an arrangement between the exec server and the program
+ interpreter, so we don't fully specify them here. */
+
+typedef struct
+{
+ uint32_t a_type; /* Entry type */
+ union
+ {
+ uint32_t a_val; /* Integer value */
+ /* We use to have pointer elements added here. We cannot do that,
+ though, since it does not work when using 32-bit definitions
+ on 64-bit platforms and vice versa. */
+ } a_un;
+} Elf32_auxv_t;
+
+typedef struct
+{
+ uint64_t a_type; /* Entry type */
+ union
+ {
+ uint64_t a_val; /* Integer value */
+ /* We use to have pointer elements added here. We cannot do that,
+ though, since it does not work when using 32-bit definitions
+ on 64-bit platforms and vice versa. */
+ } a_un;
+} Elf64_auxv_t;
+
+/* Note section contents. Each entry in the note section begins with
+ a header of a fixed form. */
+
+typedef struct
+{
+ Elf32_Word n_namesz; /* Length of the note's name. */
+ Elf32_Word n_descsz; /* Length of the note's descriptor. */
+ Elf32_Word n_type; /* Type of the note. */
+} Elf32_Nhdr;
+
+typedef struct
+{
+ Elf64_Word n_namesz; /* Length of the note's name. */
+ Elf64_Word n_descsz; /* Length of the note's descriptor. */
+ Elf64_Word n_type; /* Type of the note. */
+} Elf64_Nhdr;
+
+/* Known names of notes. */
+
+/* Solaris entries in the note section have this name. */
+#define ELF_NOTE_SOLARIS "SUNW Solaris"
+
+/* Note entries for GNU systems have this name. */
+#define ELF_NOTE_GNU "GNU"
+
+
+/* Defined types of notes for Solaris. */
+
+/* Value of descriptor (one word) is desired pagesize for the binary. */
+#define ELF_NOTE_PAGESIZE_HINT 1
+
+
+/* Defined note types for GNU systems. */
+
+/* ABI information. The descriptor consists of words:
+ word 0: OS descriptor
+ word 1: major version of the ABI
+ word 2: minor version of the ABI
+ word 3: subminor version of the ABI
+*/
+#define NT_GNU_ABI_TAG 1
+#define ELF_NOTE_ABI NT_GNU_ABI_TAG /* Old name. */
+
+/* Known OSes. These values can appear in word 0 of an
+ NT_GNU_ABI_TAG note section entry. */
+#define ELF_NOTE_OS_LINUX 0
+#define ELF_NOTE_OS_GNU 1
+#define ELF_NOTE_OS_SOLARIS2 2
+#define ELF_NOTE_OS_FREEBSD 3
+
+/* Synthetic hwcap information. The descriptor begins with two words:
+ word 0: number of entries
+ word 1: bitmask of enabled entries
+ Then follow variable-length entries, one byte followed by a
+ '\0'-terminated hwcap name string. The byte gives the bit
+ number to test if enabled, (1U << bit) & bitmask. */
+#define NT_GNU_HWCAP 2
+
+/* Build ID bits as generated by ld --build-id.
+ The descriptor consists of any nonzero number of bytes. */
+#define NT_GNU_BUILD_ID 3
+
+/* Version note generated by GNU gold containing a version string. */
+#define NT_GNU_GOLD_VERSION 4
+
+
+/* Move records. */
+typedef struct
+{
+ Elf32_Xword m_value; /* Symbol value. */
+ Elf32_Word m_info; /* Size and index. */
+ Elf32_Word m_poffset; /* Symbol offset. */
+ Elf32_Half m_repeat; /* Repeat count. */
+ Elf32_Half m_stride; /* Stride info. */
+} Elf32_Move;
+
+typedef struct
+{
+ Elf64_Xword m_value; /* Symbol value. */
+ Elf64_Xword m_info; /* Size and index. */
+ Elf64_Xword m_poffset; /* Symbol offset. */
+ Elf64_Half m_repeat; /* Repeat count. */
+ Elf64_Half m_stride; /* Stride info. */
+} Elf64_Move;
+
+/* Macro to construct move records. */
+#define ELF32_M_SYM(info) ((info) >> 8)
+#define ELF32_M_SIZE(info) ((unsigned char) (info))
+#define ELF32_M_INFO(sym, size) (((sym) << 8) + (unsigned char) (size))
+
+#define ELF64_M_SYM(info) ELF32_M_SYM (info)
+#define ELF64_M_SIZE(info) ELF32_M_SIZE (info)
+#define ELF64_M_INFO(sym, size) ELF32_M_INFO (sym, size)
+
+
+/* Motorola 68k specific definitions. */
+
+/* Values for Elf32_Ehdr.e_flags. */
+#define EF_CPU32 0x00810000
+
+/* m68k relocs. */
+
+#define R_68K_NONE 0 /* No reloc */
+#define R_68K_32 1 /* Direct 32 bit */
+#define R_68K_16 2 /* Direct 16 bit */
+#define R_68K_8 3 /* Direct 8 bit */
+#define R_68K_PC32 4 /* PC relative 32 bit */
+#define R_68K_PC16 5 /* PC relative 16 bit */
+#define R_68K_PC8 6 /* PC relative 8 bit */
+#define R_68K_GOT32 7 /* 32 bit PC relative GOT entry */
+#define R_68K_GOT16 8 /* 16 bit PC relative GOT entry */
+#define R_68K_GOT8 9 /* 8 bit PC relative GOT entry */
+#define R_68K_GOT32O 10 /* 32 bit GOT offset */
+#define R_68K_GOT16O 11 /* 16 bit GOT offset */
+#define R_68K_GOT8O 12 /* 8 bit GOT offset */
+#define R_68K_PLT32 13 /* 32 bit PC relative PLT address */
+#define R_68K_PLT16 14 /* 16 bit PC relative PLT address */
+#define R_68K_PLT8 15 /* 8 bit PC relative PLT address */
+#define R_68K_PLT32O 16 /* 32 bit PLT offset */
+#define R_68K_PLT16O 17 /* 16 bit PLT offset */
+#define R_68K_PLT8O 18 /* 8 bit PLT offset */
+#define R_68K_COPY 19 /* Copy symbol at runtime */
+#define R_68K_GLOB_DAT 20 /* Create GOT entry */
+#define R_68K_JMP_SLOT 21 /* Create PLT entry */
+#define R_68K_RELATIVE 22 /* Adjust by program base */
+#define R_68K_TLS_GD32 25 /* 32 bit GOT offset for GD */
+#define R_68K_TLS_GD16 26 /* 16 bit GOT offset for GD */
+#define R_68K_TLS_GD8 27 /* 8 bit GOT offset for GD */
+#define R_68K_TLS_LDM32 28 /* 32 bit GOT offset for LDM */
+#define R_68K_TLS_LDM16 29 /* 16 bit GOT offset for LDM */
+#define R_68K_TLS_LDM8 30 /* 8 bit GOT offset for LDM */
+#define R_68K_TLS_LDO32 31 /* 32 bit module-relative offset */
+#define R_68K_TLS_LDO16 32 /* 16 bit module-relative offset */
+#define R_68K_TLS_LDO8 33 /* 8 bit module-relative offset */
+#define R_68K_TLS_IE32 34 /* 32 bit GOT offset for IE */
+#define R_68K_TLS_IE16 35 /* 16 bit GOT offset for IE */
+#define R_68K_TLS_IE8 36 /* 8 bit GOT offset for IE */
+#define R_68K_TLS_LE32 37 /* 32 bit offset relative to
+ static TLS block */
+#define R_68K_TLS_LE16 38 /* 16 bit offset relative to
+ static TLS block */
+#define R_68K_TLS_LE8 39 /* 8 bit offset relative to
+ static TLS block */
+#define R_68K_TLS_DTPMOD32 40 /* 32 bit module number */
+#define R_68K_TLS_DTPREL32 41 /* 32 bit module-relative offset */
+#define R_68K_TLS_TPREL32 42 /* 32 bit TP-relative offset */
+/* Keep this the last entry. */
+#define R_68K_NUM 43
+
+/* Intel 80386 specific definitions. */
+
+/* i386 relocs. */
+
+#define R_386_NONE 0 /* No reloc */
+#define R_386_32 1 /* Direct 32 bit */
+#define R_386_PC32 2 /* PC relative 32 bit */
+#define R_386_GOT32 3 /* 32 bit GOT entry */
+#define R_386_PLT32 4 /* 32 bit PLT address */
+#define R_386_COPY 5 /* Copy symbol at runtime */
+#define R_386_GLOB_DAT 6 /* Create GOT entry */
+#define R_386_JMP_SLOT 7 /* Create PLT entry */
+#define R_386_RELATIVE 8 /* Adjust by program base */
+#define R_386_GOTOFF 9 /* 32 bit offset to GOT */
+#define R_386_GOTPC 10 /* 32 bit PC relative offset to GOT */
+#define R_386_32PLT 11
+#define R_386_TLS_TPOFF 14 /* Offset in static TLS block */
+#define R_386_TLS_IE 15 /* Address of GOT entry for static TLS
+ block offset */
+#define R_386_TLS_GOTIE 16 /* GOT entry for static TLS block
+ offset */
+#define R_386_TLS_LE 17 /* Offset relative to static TLS
+ block */
+#define R_386_TLS_GD 18 /* Direct 32 bit for GNU version of
+ general dynamic thread local data */
+#define R_386_TLS_LDM 19 /* Direct 32 bit for GNU version of
+ local dynamic thread local data
+ in LE code */
+#define R_386_16 20
+#define R_386_PC16 21
+#define R_386_8 22
+#define R_386_PC8 23
+#define R_386_TLS_GD_32 24 /* Direct 32 bit for general dynamic
+ thread local data */
+#define R_386_TLS_GD_PUSH 25 /* Tag for pushl in GD TLS code */
+#define R_386_TLS_GD_CALL 26 /* Relocation for call to
+ __tls_get_addr() */
+#define R_386_TLS_GD_POP 27 /* Tag for popl in GD TLS code */
+#define R_386_TLS_LDM_32 28 /* Direct 32 bit for local dynamic
+ thread local data in LE code */
+#define R_386_TLS_LDM_PUSH 29 /* Tag for pushl in LDM TLS code */
+#define R_386_TLS_LDM_CALL 30 /* Relocation for call to
+ __tls_get_addr() in LDM code */
+#define R_386_TLS_LDM_POP 31 /* Tag for popl in LDM TLS code */
+#define R_386_TLS_LDO_32 32 /* Offset relative to TLS block */
+#define R_386_TLS_IE_32 33 /* GOT entry for negated static TLS
+ block offset */
+#define R_386_TLS_LE_32 34 /* Negated offset relative to static
+ TLS block */
+#define R_386_TLS_DTPMOD32 35 /* ID of module containing symbol */
+#define R_386_TLS_DTPOFF32 36 /* Offset in TLS block */
+#define R_386_TLS_TPOFF32 37 /* Negated offset in static TLS block */
+#define R_386_SIZE32 38 /* 32-bit symbol size */
+#define R_386_TLS_GOTDESC 39 /* GOT offset for TLS descriptor. */
+#define R_386_TLS_DESC_CALL 40 /* Marker of call through TLS
+ descriptor for
+ relaxation. */
+#define R_386_TLS_DESC 41 /* TLS descriptor containing
+ pointer to code and to
+ argument, returning the TLS
+ offset for the symbol. */
+#define R_386_IRELATIVE 42 /* Adjust indirectly by program base */
+/* Keep this the last entry. */
+#define R_386_NUM 43
+
+/* SUN SPARC specific definitions. */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type). */
+
+#define STT_SPARC_REGISTER 13 /* Global register reserved to app. */
+
+/* Values for Elf64_Ehdr.e_flags. */
+
+#define EF_SPARCV9_MM 3
+#define EF_SPARCV9_TSO 0
+#define EF_SPARCV9_PSO 1
+#define EF_SPARCV9_RMO 2
+#define EF_SPARC_LEDATA 0x800000 /* little endian data */
+#define EF_SPARC_EXT_MASK 0xFFFF00
+#define EF_SPARC_32PLUS 0x000100 /* generic V8+ features */
+#define EF_SPARC_SUN_US1 0x000200 /* Sun UltraSPARC1 extensions */
+#define EF_SPARC_HAL_R1 0x000400 /* HAL R1 extensions */
+#define EF_SPARC_SUN_US3 0x000800 /* Sun UltraSPARCIII extensions */
+
+/* SPARC relocs. */
+
+#define R_SPARC_NONE 0 /* No reloc */
+#define R_SPARC_8 1 /* Direct 8 bit */
+#define R_SPARC_16 2 /* Direct 16 bit */
+#define R_SPARC_32 3 /* Direct 32 bit */
+#define R_SPARC_DISP8 4 /* PC relative 8 bit */
+#define R_SPARC_DISP16 5 /* PC relative 16 bit */
+#define R_SPARC_DISP32 6 /* PC relative 32 bit */
+#define R_SPARC_WDISP30 7 /* PC relative 30 bit shifted */
+#define R_SPARC_WDISP22 8 /* PC relative 22 bit shifted */
+#define R_SPARC_HI22 9 /* High 22 bit */
+#define R_SPARC_22 10 /* Direct 22 bit */
+#define R_SPARC_13 11 /* Direct 13 bit */
+#define R_SPARC_LO10 12 /* Truncated 10 bit */
+#define R_SPARC_GOT10 13 /* Truncated 10 bit GOT entry */
+#define R_SPARC_GOT13 14 /* 13 bit GOT entry */
+#define R_SPARC_GOT22 15 /* 22 bit GOT entry shifted */
+#define R_SPARC_PC10 16 /* PC relative 10 bit truncated */
+#define R_SPARC_PC22 17 /* PC relative 22 bit shifted */
+#define R_SPARC_WPLT30 18 /* 30 bit PC relative PLT address */
+#define R_SPARC_COPY 19 /* Copy symbol at runtime */
+#define R_SPARC_GLOB_DAT 20 /* Create GOT entry */
+#define R_SPARC_JMP_SLOT 21 /* Create PLT entry */
+#define R_SPARC_RELATIVE 22 /* Adjust by program base */
+#define R_SPARC_UA32 23 /* Direct 32 bit unaligned */
+
+/* Additional Sparc64 relocs. */
+
+#define R_SPARC_PLT32 24 /* Direct 32 bit ref to PLT entry */
+#define R_SPARC_HIPLT22 25 /* High 22 bit PLT entry */
+#define R_SPARC_LOPLT10 26 /* Truncated 10 bit PLT entry */
+#define R_SPARC_PCPLT32 27 /* PC rel 32 bit ref to PLT entry */
+#define R_SPARC_PCPLT22 28 /* PC rel high 22 bit PLT entry */
+#define R_SPARC_PCPLT10 29 /* PC rel trunc 10 bit PLT entry */
+#define R_SPARC_10 30 /* Direct 10 bit */
+#define R_SPARC_11 31 /* Direct 11 bit */
+#define R_SPARC_64 32 /* Direct 64 bit */
+#define R_SPARC_OLO10 33 /* 10bit with secondary 13bit addend */
+#define R_SPARC_HH22 34 /* Top 22 bits of direct 64 bit */
+#define R_SPARC_HM10 35 /* High middle 10 bits of ... */
+#define R_SPARC_LM22 36 /* Low middle 22 bits of ... */
+#define R_SPARC_PC_HH22 37 /* Top 22 bits of pc rel 64 bit */
+#define R_SPARC_PC_HM10 38 /* High middle 10 bit of ... */
+#define R_SPARC_PC_LM22 39 /* Low miggle 22 bits of ... */
+#define R_SPARC_WDISP16 40 /* PC relative 16 bit shifted */
+#define R_SPARC_WDISP19 41 /* PC relative 19 bit shifted */
+#define R_SPARC_GLOB_JMP 42 /* was part of v9 ABI but was removed */
+#define R_SPARC_7 43 /* Direct 7 bit */
+#define R_SPARC_5 44 /* Direct 5 bit */
+#define R_SPARC_6 45 /* Direct 6 bit */
+#define R_SPARC_DISP64 46 /* PC relative 64 bit */
+#define R_SPARC_PLT64 47 /* Direct 64 bit ref to PLT entry */
+#define R_SPARC_HIX22 48 /* High 22 bit complemented */
+#define R_SPARC_LOX10 49 /* Truncated 11 bit complemented */
+#define R_SPARC_H44 50 /* Direct high 12 of 44 bit */
+#define R_SPARC_M44 51 /* Direct mid 22 of 44 bit */
+#define R_SPARC_L44 52 /* Direct low 10 of 44 bit */
+#define R_SPARC_REGISTER 53 /* Global register usage */
+#define R_SPARC_UA64 54 /* Direct 64 bit unaligned */
+#define R_SPARC_UA16 55 /* Direct 16 bit unaligned */
+#define R_SPARC_TLS_GD_HI22 56
+#define R_SPARC_TLS_GD_LO10 57
+#define R_SPARC_TLS_GD_ADD 58
+#define R_SPARC_TLS_GD_CALL 59
+#define R_SPARC_TLS_LDM_HI22 60
+#define R_SPARC_TLS_LDM_LO10 61
+#define R_SPARC_TLS_LDM_ADD 62
+#define R_SPARC_TLS_LDM_CALL 63
+#define R_SPARC_TLS_LDO_HIX22 64
+#define R_SPARC_TLS_LDO_LOX10 65
+#define R_SPARC_TLS_LDO_ADD 66
+#define R_SPARC_TLS_IE_HI22 67
+#define R_SPARC_TLS_IE_LO10 68
+#define R_SPARC_TLS_IE_LD 69
+#define R_SPARC_TLS_IE_LDX 70
+#define R_SPARC_TLS_IE_ADD 71
+#define R_SPARC_TLS_LE_HIX22 72
+#define R_SPARC_TLS_LE_LOX10 73
+#define R_SPARC_TLS_DTPMOD32 74
+#define R_SPARC_TLS_DTPMOD64 75
+#define R_SPARC_TLS_DTPOFF32 76
+#define R_SPARC_TLS_DTPOFF64 77
+#define R_SPARC_TLS_TPOFF32 78
+#define R_SPARC_TLS_TPOFF64 79
+#define R_SPARC_GOTDATA_HIX22 80
+#define R_SPARC_GOTDATA_LOX10 81
+#define R_SPARC_GOTDATA_OP_HIX22 82
+#define R_SPARC_GOTDATA_OP_LOX10 83
+#define R_SPARC_GOTDATA_OP 84
+#define R_SPARC_H34 85
+#define R_SPARC_SIZE32 86
+#define R_SPARC_SIZE64 87
+#define R_SPARC_WDISP10 88
+#define R_SPARC_JMP_IREL 248
+#define R_SPARC_IRELATIVE 249
+#define R_SPARC_GNU_VTINHERIT 250
+#define R_SPARC_GNU_VTENTRY 251
+#define R_SPARC_REV32 252
+/* Keep this the last entry. */
+#define R_SPARC_NUM 253
+
+/* For Sparc64, legal values for d_tag of Elf64_Dyn. */
+
+#define DT_SPARC_REGISTER 0x70000001
+#define DT_SPARC_NUM 2
+
+/* MIPS R3000 specific definitions. */
+
+/* Legal values for e_flags field of Elf32_Ehdr. */
+
+#define EF_MIPS_NOREORDER 1 /* A .noreorder directive was used. */
+#define EF_MIPS_PIC 2 /* Contains PIC code. */
+#define EF_MIPS_CPIC 4 /* Uses PIC calling sequence. */
+#define EF_MIPS_XGOT 8
+#define EF_MIPS_64BIT_WHIRL 16
+#define EF_MIPS_ABI2 32
+#define EF_MIPS_ABI_ON32 64
+#define EF_MIPS_NAN2008 1024 /* Uses IEEE 754-2008 NaN encoding. */
+#define EF_MIPS_ARCH 0xf0000000 /* MIPS architecture level. */
+
+/* Legal values for MIPS architecture level. */
+
+#define EF_MIPS_ARCH_1 0x00000000 /* -mips1 code. */
+#define EF_MIPS_ARCH_2 0x10000000 /* -mips2 code. */
+#define EF_MIPS_ARCH_3 0x20000000 /* -mips3 code. */
+#define EF_MIPS_ARCH_4 0x30000000 /* -mips4 code. */
+#define EF_MIPS_ARCH_5 0x40000000 /* -mips5 code. */
+#define EF_MIPS_ARCH_32 0x50000000 /* MIPS32 code. */
+#define EF_MIPS_ARCH_64 0x60000000 /* MIPS64 code. */
+#define EF_MIPS_ARCH_32R2 0x70000000 /* MIPS32r2 code. */
+#define EF_MIPS_ARCH_64R2 0x80000000 /* MIPS64r2 code. */
+
+/* The following are unofficial names and should not be used. */
+
+#define E_MIPS_ARCH_1 EF_MIPS_ARCH_1
+#define E_MIPS_ARCH_2 EF_MIPS_ARCH_2
+#define E_MIPS_ARCH_3 EF_MIPS_ARCH_3
+#define E_MIPS_ARCH_4 EF_MIPS_ARCH_4
+#define E_MIPS_ARCH_5 EF_MIPS_ARCH_5
+#define E_MIPS_ARCH_32 EF_MIPS_ARCH_32
+#define E_MIPS_ARCH_64 EF_MIPS_ARCH_64
+
+/* Special section indices. */
+
+#define SHN_MIPS_ACOMMON 0xff00 /* Allocated common symbols. */
+#define SHN_MIPS_TEXT 0xff01 /* Allocated test symbols. */
+#define SHN_MIPS_DATA 0xff02 /* Allocated data symbols. */
+#define SHN_MIPS_SCOMMON 0xff03 /* Small common symbols. */
+#define SHN_MIPS_SUNDEFINED 0xff04 /* Small undefined symbols. */
+
+/* Legal values for sh_type field of Elf32_Shdr. */
+
+#define SHT_MIPS_LIBLIST 0x70000000 /* Shared objects used in link. */
+#define SHT_MIPS_MSYM 0x70000001
+#define SHT_MIPS_CONFLICT 0x70000002 /* Conflicting symbols. */
+#define SHT_MIPS_GPTAB 0x70000003 /* Global data area sizes. */
+#define SHT_MIPS_UCODE 0x70000004 /* Reserved for SGI/MIPS compilers */
+#define SHT_MIPS_DEBUG 0x70000005 /* MIPS ECOFF debugging info. */
+#define SHT_MIPS_REGINFO 0x70000006 /* Register usage information. */
+#define SHT_MIPS_PACKAGE 0x70000007
+#define SHT_MIPS_PACKSYM 0x70000008
+#define SHT_MIPS_RELD 0x70000009
+#define SHT_MIPS_IFACE 0x7000000b
+#define SHT_MIPS_CONTENT 0x7000000c
+#define SHT_MIPS_OPTIONS 0x7000000d /* Miscellaneous options. */
+#define SHT_MIPS_SHDR 0x70000010
+#define SHT_MIPS_FDESC 0x70000011
+#define SHT_MIPS_EXTSYM 0x70000012
+#define SHT_MIPS_DENSE 0x70000013
+#define SHT_MIPS_PDESC 0x70000014
+#define SHT_MIPS_LOCSYM 0x70000015
+#define SHT_MIPS_AUXSYM 0x70000016
+#define SHT_MIPS_OPTSYM 0x70000017
+#define SHT_MIPS_LOCSTR 0x70000018
+#define SHT_MIPS_LINE 0x70000019
+#define SHT_MIPS_RFDESC 0x7000001a
+#define SHT_MIPS_DELTASYM 0x7000001b
+#define SHT_MIPS_DELTAINST 0x7000001c
+#define SHT_MIPS_DELTACLASS 0x7000001d
+#define SHT_MIPS_DWARF 0x7000001e /* DWARF debugging information. */
+#define SHT_MIPS_DELTADECL 0x7000001f
+#define SHT_MIPS_SYMBOL_LIB 0x70000020
+#define SHT_MIPS_EVENTS 0x70000021 /* Event section. */
+#define SHT_MIPS_TRANSLATE 0x70000022
+#define SHT_MIPS_PIXIE 0x70000023
+#define SHT_MIPS_XLATE 0x70000024
+#define SHT_MIPS_XLATE_DEBUG 0x70000025
+#define SHT_MIPS_WHIRL 0x70000026
+#define SHT_MIPS_EH_REGION 0x70000027
+#define SHT_MIPS_XLATE_OLD 0x70000028
+#define SHT_MIPS_PDR_EXCEPTION 0x70000029
+
+/* Legal values for sh_flags field of Elf32_Shdr. */
+
+#define SHF_MIPS_GPREL 0x10000000 /* Must be in global data area. */
+#define SHF_MIPS_MERGE 0x20000000
+#define SHF_MIPS_ADDR 0x40000000
+#define SHF_MIPS_STRINGS 0x80000000
+#define SHF_MIPS_NOSTRIP 0x08000000
+#define SHF_MIPS_LOCAL 0x04000000
+#define SHF_MIPS_NAMES 0x02000000
+#define SHF_MIPS_NODUPE 0x01000000
+
+
+/* Symbol tables. */
+
+/* MIPS specific values for `st_other'. */
+#define STO_MIPS_DEFAULT 0x0
+#define STO_MIPS_INTERNAL 0x1
+#define STO_MIPS_HIDDEN 0x2
+#define STO_MIPS_PROTECTED 0x3
+#define STO_MIPS_PLT 0x8
+#define STO_MIPS_SC_ALIGN_UNUSED 0xff
+
+/* MIPS specific values for `st_info'. */
+#define STB_MIPS_SPLIT_COMMON 13
+
+/* Entries found in sections of type SHT_MIPS_GPTAB. */
+
+typedef union
+{
+ struct
+ {
+ Elf32_Word gt_current_g_value; /* -G value used for compilation. */
+ Elf32_Word gt_unused; /* Not used. */
+ } gt_header; /* First entry in section. */
+ struct
+ {
+ Elf32_Word gt_g_value; /* If this value were used for -G. */
+ Elf32_Word gt_bytes; /* This many bytes would be used. */
+ } gt_entry; /* Subsequent entries in section. */
+} Elf32_gptab;
+
+/* Entry found in sections of type SHT_MIPS_REGINFO. */
+
+typedef struct
+{
+ Elf32_Word ri_gprmask; /* General registers used. */
+ Elf32_Word ri_cprmask[4]; /* Coprocessor registers used. */
+ Elf32_Sword ri_gp_value; /* $gp register value. */
+} Elf32_RegInfo;
+
+/* Entries found in sections of type SHT_MIPS_OPTIONS. */
+
+typedef struct
+{
+ unsigned char kind; /* Determines interpretation of the
+ variable part of descriptor. */
+ unsigned char size; /* Size of descriptor, including header. */
+ Elf32_Section section; /* Section header index of section affected,
+ 0 for global options. */
+ Elf32_Word info; /* Kind-specific information. */
+} Elf_Options;
+
+/* Values for `kind' field in Elf_Options. */
+
+#define ODK_NULL 0 /* Undefined. */
+#define ODK_REGINFO 1 /* Register usage information. */
+#define ODK_EXCEPTIONS 2 /* Exception processing options. */
+#define ODK_PAD 3 /* Section padding options. */
+#define ODK_HWPATCH 4 /* Hardware workarounds performed */
+#define ODK_FILL 5 /* record the fill value used by the linker. */
+#define ODK_TAGS 6 /* reserve space for desktop tools to write. */
+#define ODK_HWAND 7 /* HW workarounds. 'AND' bits when merging. */
+#define ODK_HWOR 8 /* HW workarounds. 'OR' bits when merging. */
+
+/* Values for `info' in Elf_Options for ODK_EXCEPTIONS entries. */
+
+#define OEX_FPU_MIN 0x1f /* FPE's which MUST be enabled. */
+#define OEX_FPU_MAX 0x1f00 /* FPE's which MAY be enabled. */
+#define OEX_PAGE0 0x10000 /* page zero must be mapped. */
+#define OEX_SMM 0x20000 /* Force sequential memory mode? */
+#define OEX_FPDBUG 0x40000 /* Force floating point debug mode? */
+#define OEX_PRECISEFP OEX_FPDBUG
+#define OEX_DISMISS 0x80000 /* Dismiss invalid address faults? */
+
+#define OEX_FPU_INVAL 0x10
+#define OEX_FPU_DIV0 0x08
+#define OEX_FPU_OFLO 0x04
+#define OEX_FPU_UFLO 0x02
+#define OEX_FPU_INEX 0x01
+
+/* Masks for `info' in Elf_Options for an ODK_HWPATCH entry. */
+
+#define OHW_R4KEOP 0x1 /* R4000 end-of-page patch. */
+#define OHW_R8KPFETCH 0x2 /* may need R8000 prefetch patch. */
+#define OHW_R5KEOP 0x4 /* R5000 end-of-page patch. */
+#define OHW_R5KCVTL 0x8 /* R5000 cvt.[ds].l bug. clean=1. */
+
+#define OPAD_PREFIX 0x1
+#define OPAD_POSTFIX 0x2
+#define OPAD_SYMBOL 0x4
+
+/* Entry found in `.options' section. */
+
+typedef struct
+{
+ Elf32_Word hwp_flags1; /* Extra flags. */
+ Elf32_Word hwp_flags2; /* Extra flags. */
+} Elf_Options_Hw;
+
+/* Masks for `info' in ElfOptions for ODK_HWAND and ODK_HWOR entries. */
+
+#define OHWA0_R4KEOP_CHECKED 0x00000001
+#define OHWA1_R4KEOP_CLEAN 0x00000002
+
+/* MIPS relocs. */
+
+#define R_MIPS_NONE 0 /* No reloc */
+#define R_MIPS_16 1 /* Direct 16 bit */
+#define R_MIPS_32 2 /* Direct 32 bit */
+#define R_MIPS_REL32 3 /* PC relative 32 bit */
+#define R_MIPS_26 4 /* Direct 26 bit shifted */
+#define R_MIPS_HI16 5 /* High 16 bit */
+#define R_MIPS_LO16 6 /* Low 16 bit */
+#define R_MIPS_GPREL16 7 /* GP relative 16 bit */
+#define R_MIPS_LITERAL 8 /* 16 bit literal entry */
+#define R_MIPS_GOT16 9 /* 16 bit GOT entry */
+#define R_MIPS_PC16 10 /* PC relative 16 bit */
+#define R_MIPS_CALL16 11 /* 16 bit GOT entry for function */
+#define R_MIPS_GPREL32 12 /* GP relative 32 bit */
+
+#define R_MIPS_SHIFT5 16
+#define R_MIPS_SHIFT6 17
+#define R_MIPS_64 18
+#define R_MIPS_GOT_DISP 19
+#define R_MIPS_GOT_PAGE 20
+#define R_MIPS_GOT_OFST 21
+#define R_MIPS_GOT_HI16 22
+#define R_MIPS_GOT_LO16 23
+#define R_MIPS_SUB 24
+#define R_MIPS_INSERT_A 25
+#define R_MIPS_INSERT_B 26
+#define R_MIPS_DELETE 27
+#define R_MIPS_HIGHER 28
+#define R_MIPS_HIGHEST 29
+#define R_MIPS_CALL_HI16 30
+#define R_MIPS_CALL_LO16 31
+#define R_MIPS_SCN_DISP 32
+#define R_MIPS_REL16 33
+#define R_MIPS_ADD_IMMEDIATE 34
+#define R_MIPS_PJUMP 35
+#define R_MIPS_RELGOT 36
+#define R_MIPS_JALR 37
+#define R_MIPS_TLS_DTPMOD32 38 /* Module number 32 bit */
+#define R_MIPS_TLS_DTPREL32 39 /* Module-relative offset 32 bit */
+#define R_MIPS_TLS_DTPMOD64 40 /* Module number 64 bit */
+#define R_MIPS_TLS_DTPREL64 41 /* Module-relative offset 64 bit */
+#define R_MIPS_TLS_GD 42 /* 16 bit GOT offset for GD */
+#define R_MIPS_TLS_LDM 43 /* 16 bit GOT offset for LDM */
+#define R_MIPS_TLS_DTPREL_HI16 44 /* Module-relative offset, high 16 bits */
+#define R_MIPS_TLS_DTPREL_LO16 45 /* Module-relative offset, low 16 bits */
+#define R_MIPS_TLS_GOTTPREL 46 /* 16 bit GOT offset for IE */
+#define R_MIPS_TLS_TPREL32 47 /* TP-relative offset, 32 bit */
+#define R_MIPS_TLS_TPREL64 48 /* TP-relative offset, 64 bit */
+#define R_MIPS_TLS_TPREL_HI16 49 /* TP-relative offset, high 16 bits */
+#define R_MIPS_TLS_TPREL_LO16 50 /* TP-relative offset, low 16 bits */
+#define R_MIPS_GLOB_DAT 51
+#define R_MIPS_COPY 126
+#define R_MIPS_JUMP_SLOT 127
+/* Keep this the last entry. */
+#define R_MIPS_NUM 128
+
+/* Legal values for p_type field of Elf32_Phdr. */
+
+#define PT_MIPS_REGINFO 0x70000000 /* Register usage information */
+#define PT_MIPS_RTPROC 0x70000001 /* Runtime procedure table. */
+#define PT_MIPS_OPTIONS 0x70000002
+
+/* Special program header types. */
+
+#define PF_MIPS_LOCAL 0x10000000
+
+/* Legal values for d_tag field of Elf32_Dyn. */
+
+#define DT_MIPS_RLD_VERSION 0x70000001 /* Runtime linker interface version */
+#define DT_MIPS_TIME_STAMP 0x70000002 /* Timestamp */
+#define DT_MIPS_ICHECKSUM 0x70000003 /* Checksum */
+#define DT_MIPS_IVERSION 0x70000004 /* Version string (string tbl index) */
+#define DT_MIPS_FLAGS 0x70000005 /* Flags */
+#define DT_MIPS_BASE_ADDRESS 0x70000006 /* Base address */
+#define DT_MIPS_MSYM 0x70000007
+#define DT_MIPS_CONFLICT 0x70000008 /* Address of CONFLICT section */
+#define DT_MIPS_LIBLIST 0x70000009 /* Address of LIBLIST section */
+#define DT_MIPS_LOCAL_GOTNO 0x7000000a /* Number of local GOT entries */
+#define DT_MIPS_CONFLICTNO 0x7000000b /* Number of CONFLICT entries */
+#define DT_MIPS_LIBLISTNO 0x70000010 /* Number of LIBLIST entries */
+#define DT_MIPS_SYMTABNO 0x70000011 /* Number of DYNSYM entries */
+#define DT_MIPS_UNREFEXTNO 0x70000012 /* First external DYNSYM */
+#define DT_MIPS_GOTSYM 0x70000013 /* First GOT entry in DYNSYM */
+#define DT_MIPS_HIPAGENO 0x70000014 /* Number of GOT page table entries */
+#define DT_MIPS_RLD_MAP 0x70000016 /* Address of run time loader map. */
+#define DT_MIPS_DELTA_CLASS 0x70000017 /* Delta C++ class definition. */
+#define DT_MIPS_DELTA_CLASS_NO 0x70000018 /* Number of entries in
+ DT_MIPS_DELTA_CLASS. */
+#define DT_MIPS_DELTA_INSTANCE 0x70000019 /* Delta C++ class instances. */
+#define DT_MIPS_DELTA_INSTANCE_NO 0x7000001a /* Number of entries in
+ DT_MIPS_DELTA_INSTANCE. */
+#define DT_MIPS_DELTA_RELOC 0x7000001b /* Delta relocations. */
+#define DT_MIPS_DELTA_RELOC_NO 0x7000001c /* Number of entries in
+ DT_MIPS_DELTA_RELOC. */
+#define DT_MIPS_DELTA_SYM 0x7000001d /* Delta symbols that Delta
+ relocations refer to. */
+#define DT_MIPS_DELTA_SYM_NO 0x7000001e /* Number of entries in
+ DT_MIPS_DELTA_SYM. */
+#define DT_MIPS_DELTA_CLASSSYM 0x70000020 /* Delta symbols that hold the
+ class declaration. */
+#define DT_MIPS_DELTA_CLASSSYM_NO 0x70000021 /* Number of entries in
+ DT_MIPS_DELTA_CLASSSYM. */
+#define DT_MIPS_CXX_FLAGS 0x70000022 /* Flags indicating for C++ flavor. */
+#define DT_MIPS_PIXIE_INIT 0x70000023
+#define DT_MIPS_SYMBOL_LIB 0x70000024
+#define DT_MIPS_LOCALPAGE_GOTIDX 0x70000025
+#define DT_MIPS_LOCAL_GOTIDX 0x70000026
+#define DT_MIPS_HIDDEN_GOTIDX 0x70000027
+#define DT_MIPS_PROTECTED_GOTIDX 0x70000028
+#define DT_MIPS_OPTIONS 0x70000029 /* Address of .options. */
+#define DT_MIPS_INTERFACE 0x7000002a /* Address of .interface. */
+#define DT_MIPS_DYNSTR_ALIGN 0x7000002b
+#define DT_MIPS_INTERFACE_SIZE 0x7000002c /* Size of the .interface section. */
+#define DT_MIPS_RLD_TEXT_RESOLVE_ADDR 0x7000002d /* Address of rld_text_rsolve
+ function stored in GOT. */
+#define DT_MIPS_PERF_SUFFIX 0x7000002e /* Default suffix of dso to be added
+ by rld on dlopen() calls. */
+#define DT_MIPS_COMPACT_SIZE 0x7000002f /* (O32)Size of compact rel section. */
+#define DT_MIPS_GP_VALUE 0x70000030 /* GP value for aux GOTs. */
+#define DT_MIPS_AUX_DYNAMIC 0x70000031 /* Address of aux .dynamic. */
+/* The address of .got.plt in an executable using the new non-PIC ABI. */
+#define DT_MIPS_PLTGOT 0x70000032
+/* The base of the PLT in an executable using the new non-PIC ABI if that
+ PLT is writable. For a non-writable PLT, this is omitted or has a zero
+ value. */
+#define DT_MIPS_RWPLT 0x70000034
+#define DT_MIPS_NUM 0x35
+
+/* Legal values for DT_MIPS_FLAGS Elf32_Dyn entry. */
+
+#define RHF_NONE 0 /* No flags */
+#define RHF_QUICKSTART (1 << 0) /* Use quickstart */
+#define RHF_NOTPOT (1 << 1) /* Hash size not power of 2 */
+#define RHF_NO_LIBRARY_REPLACEMENT (1 << 2) /* Ignore LD_LIBRARY_PATH */
+#define RHF_NO_MOVE (1 << 3)
+#define RHF_SGI_ONLY (1 << 4)
+#define RHF_GUARANTEE_INIT (1 << 5)
+#define RHF_DELTA_C_PLUS_PLUS (1 << 6)
+#define RHF_GUARANTEE_START_INIT (1 << 7)
+#define RHF_PIXIE (1 << 8)
+#define RHF_DEFAULT_DELAY_LOAD (1 << 9)
+#define RHF_REQUICKSTART (1 << 10)
+#define RHF_REQUICKSTARTED (1 << 11)
+#define RHF_CORD (1 << 12)
+#define RHF_NO_UNRES_UNDEF (1 << 13)
+#define RHF_RLD_ORDER_SAFE (1 << 14)
+
+/* Entries found in sections of type SHT_MIPS_LIBLIST. */
+
+typedef struct
+{
+ Elf32_Word l_name; /* Name (string table index) */
+ Elf32_Word l_time_stamp; /* Timestamp */
+ Elf32_Word l_checksum; /* Checksum */
+ Elf32_Word l_version; /* Interface version */
+ Elf32_Word l_flags; /* Flags */
+} Elf32_Lib;
+
+typedef struct
+{
+ Elf64_Word l_name; /* Name (string table index) */
+ Elf64_Word l_time_stamp; /* Timestamp */
+ Elf64_Word l_checksum; /* Checksum */
+ Elf64_Word l_version; /* Interface version */
+ Elf64_Word l_flags; /* Flags */
+} Elf64_Lib;
+
+
+/* Legal values for l_flags. */
+
+#define LL_NONE 0
+#define LL_EXACT_MATCH (1 << 0) /* Require exact match */
+#define LL_IGNORE_INT_VER (1 << 1) /* Ignore interface version */
+#define LL_REQUIRE_MINOR (1 << 2)
+#define LL_EXPORTS (1 << 3)
+#define LL_DELAY_LOAD (1 << 4)
+#define LL_DELTA (1 << 5)
+
+/* Entries found in sections of type SHT_MIPS_CONFLICT. */
+
+typedef Elf32_Addr Elf32_Conflict;
+
+
+/* HPPA specific definitions. */
+
+/* Legal values for e_flags field of Elf32_Ehdr. */
+
+#define EF_PARISC_TRAPNIL 0x00010000 /* Trap nil pointer dereference. */
+#define EF_PARISC_EXT 0x00020000 /* Program uses arch. extensions. */
+#define EF_PARISC_LSB 0x00040000 /* Program expects little endian. */
+#define EF_PARISC_WIDE 0x00080000 /* Program expects wide mode. */
+#define EF_PARISC_NO_KABP 0x00100000 /* No kernel assisted branch
+ prediction. */
+#define EF_PARISC_LAZYSWAP 0x00400000 /* Allow lazy swapping. */
+#define EF_PARISC_ARCH 0x0000ffff /* Architecture version. */
+
+/* Defined values for `e_flags & EF_PARISC_ARCH' are: */
+
+#define EFA_PARISC_1_0 0x020b /* PA-RISC 1.0 big-endian. */
+#define EFA_PARISC_1_1 0x0210 /* PA-RISC 1.1 big-endian. */
+#define EFA_PARISC_2_0 0x0214 /* PA-RISC 2.0 big-endian. */
+
+/* Additional section indeces. */
+
+#define SHN_PARISC_ANSI_COMMON 0xff00 /* Section for tenatively declared
+ symbols in ANSI C. */
+#define SHN_PARISC_HUGE_COMMON 0xff01 /* Common blocks in huge model. */
+
+/* Legal values for sh_type field of Elf32_Shdr. */
+
+#define SHT_PARISC_EXT 0x70000000 /* Contains product specific ext. */
+#define SHT_PARISC_UNWIND 0x70000001 /* Unwind information. */
+#define SHT_PARISC_DOC 0x70000002 /* Debug info for optimized code. */
+
+/* Legal values for sh_flags field of Elf32_Shdr. */
+
+#define SHF_PARISC_SHORT 0x20000000 /* Section with short addressing. */
+#define SHF_PARISC_HUGE 0x40000000 /* Section far from gp. */
+#define SHF_PARISC_SBP 0x80000000 /* Static branch prediction code. */
+
+/* Legal values for ST_TYPE subfield of st_info (symbol type). */
+
+#define STT_PARISC_MILLICODE 13 /* Millicode function entry point. */
+
+#define STT_HP_OPAQUE (STT_LOOS + 0x1)
+#define STT_HP_STUB (STT_LOOS + 0x2)
+
+/* HPPA relocs. */
+
+#define R_PARISC_NONE 0 /* No reloc. */
+#define R_PARISC_DIR32 1 /* Direct 32-bit reference. */
+#define R_PARISC_DIR21L 2 /* Left 21 bits of eff. address. */
+#define R_PARISC_DIR17R 3 /* Right 17 bits of eff. address. */
+#define R_PARISC_DIR17F 4 /* 17 bits of eff. address. */
+#define R_PARISC_DIR14R 6 /* Right 14 bits of eff. address. */
+#define R_PARISC_PCREL32 9 /* 32-bit rel. address. */
+#define R_PARISC_PCREL21L 10 /* Left 21 bits of rel. address. */
+#define R_PARISC_PCREL17R 11 /* Right 17 bits of rel. address. */
+#define R_PARISC_PCREL17F 12 /* 17 bits of rel. address. */
+#define R_PARISC_PCREL14R 14 /* Right 14 bits of rel. address. */
+#define R_PARISC_DPREL21L 18 /* Left 21 bits of rel. address. */
+#define R_PARISC_DPREL14R 22 /* Right 14 bits of rel. address. */
+#define R_PARISC_GPREL21L 26 /* GP-relative, left 21 bits. */
+#define R_PARISC_GPREL14R 30 /* GP-relative, right 14 bits. */
+#define R_PARISC_LTOFF21L 34 /* LT-relative, left 21 bits. */
+#define R_PARISC_LTOFF14R 38 /* LT-relative, right 14 bits. */
+#define R_PARISC_SECREL32 41 /* 32 bits section rel. address. */
+#define R_PARISC_SEGBASE 48 /* No relocation, set segment base. */
+#define R_PARISC_SEGREL32 49 /* 32 bits segment rel. address. */
+#define R_PARISC_PLTOFF21L 50 /* PLT rel. address, left 21 bits. */
+#define R_PARISC_PLTOFF14R 54 /* PLT rel. address, right 14 bits. */
+#define R_PARISC_LTOFF_FPTR32 57 /* 32 bits LT-rel. function pointer. */
+#define R_PARISC_LTOFF_FPTR21L 58 /* LT-rel. fct ptr, left 21 bits. */
+#define R_PARISC_LTOFF_FPTR14R 62 /* LT-rel. fct ptr, right 14 bits. */
+#define R_PARISC_FPTR64 64 /* 64 bits function address. */
+#define R_PARISC_PLABEL32 65 /* 32 bits function address. */
+#define R_PARISC_PLABEL21L 66 /* Left 21 bits of fdesc address. */
+#define R_PARISC_PLABEL14R 70 /* Right 14 bits of fdesc address. */
+#define R_PARISC_PCREL64 72 /* 64 bits PC-rel. address. */
+#define R_PARISC_PCREL22F 74 /* 22 bits PC-rel. address. */
+#define R_PARISC_PCREL14WR 75 /* PC-rel. address, right 14 bits. */
+#define R_PARISC_PCREL14DR 76 /* PC rel. address, right 14 bits. */
+#define R_PARISC_PCREL16F 77 /* 16 bits PC-rel. address. */
+#define R_PARISC_PCREL16WF 78 /* 16 bits PC-rel. address. */
+#define R_PARISC_PCREL16DF 79 /* 16 bits PC-rel. address. */
+#define R_PARISC_DIR64 80 /* 64 bits of eff. address. */
+#define R_PARISC_DIR14WR 83 /* 14 bits of eff. address. */
+#define R_PARISC_DIR14DR 84 /* 14 bits of eff. address. */
+#define R_PARISC_DIR16F 85 /* 16 bits of eff. address. */
+#define R_PARISC_DIR16WF 86 /* 16 bits of eff. address. */
+#define R_PARISC_DIR16DF 87 /* 16 bits of eff. address. */
+#define R_PARISC_GPREL64 88 /* 64 bits of GP-rel. address. */
+#define R_PARISC_GPREL14WR 91 /* GP-rel. address, right 14 bits. */
+#define R_PARISC_GPREL14DR 92 /* GP-rel. address, right 14 bits. */
+#define R_PARISC_GPREL16F 93 /* 16 bits GP-rel. address. */
+#define R_PARISC_GPREL16WF 94 /* 16 bits GP-rel. address. */
+#define R_PARISC_GPREL16DF 95 /* 16 bits GP-rel. address. */
+#define R_PARISC_LTOFF64 96 /* 64 bits LT-rel. address. */
+#define R_PARISC_LTOFF14WR 99 /* LT-rel. address, right 14 bits. */
+#define R_PARISC_LTOFF14DR 100 /* LT-rel. address, right 14 bits. */
+#define R_PARISC_LTOFF16F 101 /* 16 bits LT-rel. address. */
+#define R_PARISC_LTOFF16WF 102 /* 16 bits LT-rel. address. */
+#define R_PARISC_LTOFF16DF 103 /* 16 bits LT-rel. address. */
+#define R_PARISC_SECREL64 104 /* 64 bits section rel. address. */
+#define R_PARISC_SEGREL64 112 /* 64 bits segment rel. address. */
+#define R_PARISC_PLTOFF14WR 115 /* PLT-rel. address, right 14 bits. */
+#define R_PARISC_PLTOFF14DR 116 /* PLT-rel. address, right 14 bits. */
+#define R_PARISC_PLTOFF16F 117 /* 16 bits LT-rel. address. */
+#define R_PARISC_PLTOFF16WF 118 /* 16 bits PLT-rel. address. */
+#define R_PARISC_PLTOFF16DF 119 /* 16 bits PLT-rel. address. */
+#define R_PARISC_LTOFF_FPTR64 120 /* 64 bits LT-rel. function ptr. */
+#define R_PARISC_LTOFF_FPTR14WR 123 /* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR14DR 124 /* LT-rel. fct. ptr., right 14 bits. */
+#define R_PARISC_LTOFF_FPTR16F 125 /* 16 bits LT-rel. function ptr. */
+#define R_PARISC_LTOFF_FPTR16WF 126 /* 16 bits LT-rel. function ptr. */
+#define R_PARISC_LTOFF_FPTR16DF 127 /* 16 bits LT-rel. function ptr. */
+#define R_PARISC_LORESERVE 128
+#define R_PARISC_COPY 128 /* Copy relocation. */
+#define R_PARISC_IPLT 129 /* Dynamic reloc, imported PLT */
+#define R_PARISC_EPLT 130 /* Dynamic reloc, exported PLT */
+#define R_PARISC_TPREL32 153 /* 32 bits TP-rel. address. */
+#define R_PARISC_TPREL21L 154 /* TP-rel. address, left 21 bits. */
+#define R_PARISC_TPREL14R 158 /* TP-rel. address, right 14 bits. */
+#define R_PARISC_LTOFF_TP21L 162 /* LT-TP-rel. address, left 21 bits. */
+#define R_PARISC_LTOFF_TP14R 166 /* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14F 167 /* 14 bits LT-TP-rel. address. */
+#define R_PARISC_TPREL64 216 /* 64 bits TP-rel. address. */
+#define R_PARISC_TPREL14WR 219 /* TP-rel. address, right 14 bits. */
+#define R_PARISC_TPREL14DR 220 /* TP-rel. address, right 14 bits. */
+#define R_PARISC_TPREL16F 221 /* 16 bits TP-rel. address. */
+#define R_PARISC_TPREL16WF 222 /* 16 bits TP-rel. address. */
+#define R_PARISC_TPREL16DF 223 /* 16 bits TP-rel. address. */
+#define R_PARISC_LTOFF_TP64 224 /* 64 bits LT-TP-rel. address. */
+#define R_PARISC_LTOFF_TP14WR 227 /* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP14DR 228 /* LT-TP-rel. address, right 14 bits.*/
+#define R_PARISC_LTOFF_TP16F 229 /* 16 bits LT-TP-rel. address. */
+#define R_PARISC_LTOFF_TP16WF 230 /* 16 bits LT-TP-rel. address. */
+#define R_PARISC_LTOFF_TP16DF 231 /* 16 bits LT-TP-rel. address. */
+#define R_PARISC_GNU_VTENTRY 232
+#define R_PARISC_GNU_VTINHERIT 233
+#define R_PARISC_TLS_GD21L 234 /* GD 21-bit left. */
+#define R_PARISC_TLS_GD14R 235 /* GD 14-bit right. */
+#define R_PARISC_TLS_GDCALL 236 /* GD call to __t_g_a. */
+#define R_PARISC_TLS_LDM21L 237 /* LD module 21-bit left. */
+#define R_PARISC_TLS_LDM14R 238 /* LD module 14-bit right. */
+#define R_PARISC_TLS_LDMCALL 239 /* LD module call to __t_g_a. */
+#define R_PARISC_TLS_LDO21L 240 /* LD offset 21-bit left. */
+#define R_PARISC_TLS_LDO14R 241 /* LD offset 14-bit right. */
+#define R_PARISC_TLS_DTPMOD32 242 /* DTP module 32-bit. */
+#define R_PARISC_TLS_DTPMOD64 243 /* DTP module 64-bit. */
+#define R_PARISC_TLS_DTPOFF32 244 /* DTP offset 32-bit. */
+#define R_PARISC_TLS_DTPOFF64 245 /* DTP offset 32-bit. */
+#define R_PARISC_TLS_LE21L R_PARISC_TPREL21L
+#define R_PARISC_TLS_LE14R R_PARISC_TPREL14R
+#define R_PARISC_TLS_IE21L R_PARISC_LTOFF_TP21L
+#define R_PARISC_TLS_IE14R R_PARISC_LTOFF_TP14R
+#define R_PARISC_TLS_TPREL32 R_PARISC_TPREL32
+#define R_PARISC_TLS_TPREL64 R_PARISC_TPREL64
+#define R_PARISC_HIRESERVE 255
+
+/* Legal values for p_type field of Elf32_Phdr/Elf64_Phdr. */
+
+#define PT_HP_TLS (PT_LOOS + 0x0)
+#define PT_HP_CORE_NONE (PT_LOOS + 0x1)
+#define PT_HP_CORE_VERSION (PT_LOOS + 0x2)
+#define PT_HP_CORE_KERNEL (PT_LOOS + 0x3)
+#define PT_HP_CORE_COMM (PT_LOOS + 0x4)
+#define PT_HP_CORE_PROC (PT_LOOS + 0x5)
+#define PT_HP_CORE_LOADABLE (PT_LOOS + 0x6)
+#define PT_HP_CORE_STACK (PT_LOOS + 0x7)
+#define PT_HP_CORE_SHM (PT_LOOS + 0x8)
+#define PT_HP_CORE_MMF (PT_LOOS + 0x9)
+#define PT_HP_PARALLEL (PT_LOOS + 0x10)
+#define PT_HP_FASTBIND (PT_LOOS + 0x11)
+#define PT_HP_OPT_ANNOT (PT_LOOS + 0x12)
+#define PT_HP_HSL_ANNOT (PT_LOOS + 0x13)
+#define PT_HP_STACK (PT_LOOS + 0x14)
+
+#define PT_PARISC_ARCHEXT 0x70000000
+#define PT_PARISC_UNWIND 0x70000001
+
+/* Legal values for p_flags field of Elf32_Phdr/Elf64_Phdr. */
+
+#define PF_PARISC_SBP 0x08000000
+
+#define PF_HP_PAGE_SIZE 0x00100000
+#define PF_HP_FAR_SHARED 0x00200000
+#define PF_HP_NEAR_SHARED 0x00400000
+#define PF_HP_CODE 0x01000000
+#define PF_HP_MODIFY 0x02000000
+#define PF_HP_LAZYSWAP 0x04000000
+#define PF_HP_SBP 0x08000000
+
+
+/* Alpha specific definitions. */
+
+/* Legal values for e_flags field of Elf64_Ehdr. */
+
+#define EF_ALPHA_32BIT 1 /* All addresses must be < 2GB. */
+#define EF_ALPHA_CANRELAX 2 /* Relocations for relaxing exist. */
+
+/* Legal values for sh_type field of Elf64_Shdr. */
+
+/* These two are primerily concerned with ECOFF debugging info. */
+#define SHT_ALPHA_DEBUG 0x70000001
+#define SHT_ALPHA_REGINFO 0x70000002
+
+/* Legal values for sh_flags field of Elf64_Shdr. */
+
+#define SHF_ALPHA_GPREL 0x10000000
+
+/* Legal values for st_other field of Elf64_Sym. */
+#define STO_ALPHA_NOPV 0x80 /* No PV required. */
+#define STO_ALPHA_STD_GPLOAD 0x88 /* PV only used for initial ldgp. */
+
+/* Alpha relocs. */
+
+#define R_ALPHA_NONE 0 /* No reloc */
+#define R_ALPHA_REFLONG 1 /* Direct 32 bit */
+#define R_ALPHA_REFQUAD 2 /* Direct 64 bit */
+#define R_ALPHA_GPREL32 3 /* GP relative 32 bit */
+#define R_ALPHA_LITERAL 4 /* GP relative 16 bit w/optimization */
+#define R_ALPHA_LITUSE 5 /* Optimization hint for LITERAL */
+#define R_ALPHA_GPDISP 6 /* Add displacement to GP */
+#define R_ALPHA_BRADDR 7 /* PC+4 relative 23 bit shifted */
+#define R_ALPHA_HINT 8 /* PC+4 relative 16 bit shifted */
+#define R_ALPHA_SREL16 9 /* PC relative 16 bit */
+#define R_ALPHA_SREL32 10 /* PC relative 32 bit */
+#define R_ALPHA_SREL64 11 /* PC relative 64 bit */
+#define R_ALPHA_GPRELHIGH 17 /* GP relative 32 bit, high 16 bits */
+#define R_ALPHA_GPRELLOW 18 /* GP relative 32 bit, low 16 bits */
+#define R_ALPHA_GPREL16 19 /* GP relative 16 bit */
+#define R_ALPHA_COPY 24 /* Copy symbol at runtime */
+#define R_ALPHA_GLOB_DAT 25 /* Create GOT entry */
+#define R_ALPHA_JMP_SLOT 26 /* Create PLT entry */
+#define R_ALPHA_RELATIVE 27 /* Adjust by program base */
+#define R_ALPHA_TLS_GD_HI 28
+#define R_ALPHA_TLSGD 29
+#define R_ALPHA_TLS_LDM 30
+#define R_ALPHA_DTPMOD64 31
+#define R_ALPHA_GOTDTPREL 32
+#define R_ALPHA_DTPREL64 33
+#define R_ALPHA_DTPRELHI 34
+#define R_ALPHA_DTPRELLO 35
+#define R_ALPHA_DTPREL16 36
+#define R_ALPHA_GOTTPREL 37
+#define R_ALPHA_TPREL64 38
+#define R_ALPHA_TPRELHI 39
+#define R_ALPHA_TPRELLO 40
+#define R_ALPHA_TPREL16 41
+/* Keep this the last entry. */
+#define R_ALPHA_NUM 46
+
+/* Magic values of the LITUSE relocation addend. */
+#define LITUSE_ALPHA_ADDR 0
+#define LITUSE_ALPHA_BASE 1
+#define LITUSE_ALPHA_BYTOFF 2
+#define LITUSE_ALPHA_JSR 3
+#define LITUSE_ALPHA_TLS_GD 4
+#define LITUSE_ALPHA_TLS_LDM 5
+
+/* Legal values for d_tag of Elf64_Dyn. */
+#define DT_ALPHA_PLTRO (DT_LOPROC + 0)
+#define DT_ALPHA_NUM 1
+
+/* PowerPC specific declarations */
+
+/* Values for Elf32/64_Ehdr.e_flags. */
+#define EF_PPC_EMB 0x80000000 /* PowerPC embedded flag */
+
+/* Cygnus local bits below */
+#define EF_PPC_RELOCATABLE 0x00010000 /* PowerPC -mrelocatable flag*/
+#define EF_PPC_RELOCATABLE_LIB 0x00008000 /* PowerPC -mrelocatable-lib
+ flag */
+
+/* PowerPC relocations defined by the ABIs */
+#define R_PPC_NONE 0
+#define R_PPC_ADDR32 1 /* 32bit absolute address */
+#define R_PPC_ADDR24 2 /* 26bit address, 2 bits ignored. */
+#define R_PPC_ADDR16 3 /* 16bit absolute address */
+#define R_PPC_ADDR16_LO 4 /* lower 16bit of absolute address */
+#define R_PPC_ADDR16_HI 5 /* high 16bit of absolute address */
+#define R_PPC_ADDR16_HA 6 /* adjusted high 16bit */
+#define R_PPC_ADDR14 7 /* 16bit address, 2 bits ignored */
+#define R_PPC_ADDR14_BRTAKEN 8
+#define R_PPC_ADDR14_BRNTAKEN 9
+#define R_PPC_REL24 10 /* PC relative 26 bit */
+#define R_PPC_REL14 11 /* PC relative 16 bit */
+#define R_PPC_REL14_BRTAKEN 12
+#define R_PPC_REL14_BRNTAKEN 13
+#define R_PPC_GOT16 14
+#define R_PPC_GOT16_LO 15
+#define R_PPC_GOT16_HI 16
+#define R_PPC_GOT16_HA 17
+#define R_PPC_PLTREL24 18
+#define R_PPC_COPY 19
+#define R_PPC_GLOB_DAT 20
+#define R_PPC_JMP_SLOT 21
+#define R_PPC_RELATIVE 22
+#define R_PPC_LOCAL24PC 23
+#define R_PPC_UADDR32 24
+#define R_PPC_UADDR16 25
+#define R_PPC_REL32 26
+#define R_PPC_PLT32 27
+#define R_PPC_PLTREL32 28
+#define R_PPC_PLT16_LO 29
+#define R_PPC_PLT16_HI 30
+#define R_PPC_PLT16_HA 31
+#define R_PPC_SDAREL16 32
+#define R_PPC_SECTOFF 33
+#define R_PPC_SECTOFF_LO 34
+#define R_PPC_SECTOFF_HI 35
+#define R_PPC_SECTOFF_HA 36
+
+/* PowerPC relocations defined for the TLS access ABI. */
+#define R_PPC_TLS 67 /* none (sym+add)@tls */
+#define R_PPC_DTPMOD32 68 /* word32 (sym+add)@dtpmod */
+#define R_PPC_TPREL16 69 /* half16* (sym+add)@tprel */
+#define R_PPC_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */
+#define R_PPC_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */
+#define R_PPC_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */
+#define R_PPC_TPREL32 73 /* word32 (sym+add)@tprel */
+#define R_PPC_DTPREL16 74 /* half16* (sym+add)@dtprel */
+#define R_PPC_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */
+#define R_PPC_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */
+#define R_PPC_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */
+#define R_PPC_DTPREL32 78 /* word32 (sym+add)@dtprel */
+#define R_PPC_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */
+#define R_PPC_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */
+#define R_PPC_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */
+#define R_PPC_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */
+#define R_PPC_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */
+#define R_PPC_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */
+#define R_PPC_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */
+#define R_PPC_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */
+#define R_PPC_GOT_TPREL16 87 /* half16* (sym+add)@got@tprel */
+#define R_PPC_GOT_TPREL16_LO 88 /* half16 (sym+add)@got@tprel@l */
+#define R_PPC_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */
+#define R_PPC_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */
+#define R_PPC_GOT_DTPREL16 91 /* half16* (sym+add)@got@dtprel */
+#define R_PPC_GOT_DTPREL16_LO 92 /* half16* (sym+add)@got@dtprel@l */
+#define R_PPC_GOT_DTPREL16_HI 93 /* half16* (sym+add)@got@dtprel@h */
+#define R_PPC_GOT_DTPREL16_HA 94 /* half16* (sym+add)@got@dtprel@ha */
+
+/* The remaining relocs are from the Embedded ELF ABI, and are not
+ in the SVR4 ELF ABI. */
+#define R_PPC_EMB_NADDR32 101
+#define R_PPC_EMB_NADDR16 102
+#define R_PPC_EMB_NADDR16_LO 103
+#define R_PPC_EMB_NADDR16_HI 104
+#define R_PPC_EMB_NADDR16_HA 105
+#define R_PPC_EMB_SDAI16 106
+#define R_PPC_EMB_SDA2I16 107
+#define R_PPC_EMB_SDA2REL 108
+#define R_PPC_EMB_SDA21 109 /* 16 bit offset in SDA */
+#define R_PPC_EMB_MRKREF 110
+#define R_PPC_EMB_RELSEC16 111
+#define R_PPC_EMB_RELST_LO 112
+#define R_PPC_EMB_RELST_HI 113
+#define R_PPC_EMB_RELST_HA 114
+#define R_PPC_EMB_BIT_FLD 115
+#define R_PPC_EMB_RELSDA 116 /* 16 bit relative offset in SDA */
+
+/* Diab tool relocations. */
+#define R_PPC_DIAB_SDA21_LO 180 /* like EMB_SDA21, but lower 16 bit */
+#define R_PPC_DIAB_SDA21_HI 181 /* like EMB_SDA21, but high 16 bit */
+#define R_PPC_DIAB_SDA21_HA 182 /* like EMB_SDA21, adjusted high 16 */
+#define R_PPC_DIAB_RELSDA_LO 183 /* like EMB_RELSDA, but lower 16 bit */
+#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */
+#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */
+
+/* GNU extension to support local ifunc. */
+#define R_PPC_IRELATIVE 248
+
+/* GNU relocs used in PIC code sequences. */
+#define R_PPC_REL16 249 /* half16 (sym+add-.) */
+#define R_PPC_REL16_LO 250 /* half16 (sym+add-.)@l */
+#define R_PPC_REL16_HI 251 /* half16 (sym+add-.)@h */
+#define R_PPC_REL16_HA 252 /* half16 (sym+add-.)@ha */
+
+/* This is a phony reloc to handle any old fashioned TOC16 references
+ that may still be in object files. */
+#define R_PPC_TOC16 255
+
+/* PowerPC specific values for the Dyn d_tag field. */
+#define DT_PPC_GOT (DT_LOPROC + 0)
+#define DT_PPC_NUM 1
+
+/* PowerPC64 relocations defined by the ABIs */
+#define R_PPC64_NONE R_PPC_NONE
+#define R_PPC64_ADDR32 R_PPC_ADDR32 /* 32bit absolute address */
+#define R_PPC64_ADDR24 R_PPC_ADDR24 /* 26bit address, word aligned */
+#define R_PPC64_ADDR16 R_PPC_ADDR16 /* 16bit absolute address */
+#define R_PPC64_ADDR16_LO R_PPC_ADDR16_LO /* lower 16bits of address */
+#define R_PPC64_ADDR16_HI R_PPC_ADDR16_HI /* high 16bits of address. */
+#define R_PPC64_ADDR16_HA R_PPC_ADDR16_HA /* adjusted high 16bits. */
+#define R_PPC64_ADDR14 R_PPC_ADDR14 /* 16bit address, word aligned */
+#define R_PPC64_ADDR14_BRTAKEN R_PPC_ADDR14_BRTAKEN
+#define R_PPC64_ADDR14_BRNTAKEN R_PPC_ADDR14_BRNTAKEN
+#define R_PPC64_REL24 R_PPC_REL24 /* PC-rel. 26 bit, word aligned */
+#define R_PPC64_REL14 R_PPC_REL14 /* PC relative 16 bit */
+#define R_PPC64_REL14_BRTAKEN R_PPC_REL14_BRTAKEN
+#define R_PPC64_REL14_BRNTAKEN R_PPC_REL14_BRNTAKEN
+#define R_PPC64_GOT16 R_PPC_GOT16
+#define R_PPC64_GOT16_LO R_PPC_GOT16_LO
+#define R_PPC64_GOT16_HI R_PPC_GOT16_HI
+#define R_PPC64_GOT16_HA R_PPC_GOT16_HA
+
+#define R_PPC64_COPY R_PPC_COPY
+#define R_PPC64_GLOB_DAT R_PPC_GLOB_DAT
+#define R_PPC64_JMP_SLOT R_PPC_JMP_SLOT
+#define R_PPC64_RELATIVE R_PPC_RELATIVE
+
+#define R_PPC64_UADDR32 R_PPC_UADDR32
+#define R_PPC64_UADDR16 R_PPC_UADDR16
+#define R_PPC64_REL32 R_PPC_REL32
+#define R_PPC64_PLT32 R_PPC_PLT32
+#define R_PPC64_PLTREL32 R_PPC_PLTREL32
+#define R_PPC64_PLT16_LO R_PPC_PLT16_LO
+#define R_PPC64_PLT16_HI R_PPC_PLT16_HI
+#define R_PPC64_PLT16_HA R_PPC_PLT16_HA
+
+#define R_PPC64_SECTOFF R_PPC_SECTOFF
+#define R_PPC64_SECTOFF_LO R_PPC_SECTOFF_LO
+#define R_PPC64_SECTOFF_HI R_PPC_SECTOFF_HI
+#define R_PPC64_SECTOFF_HA R_PPC_SECTOFF_HA
+#define R_PPC64_ADDR30 37 /* word30 (S + A - P) >> 2 */
+#define R_PPC64_ADDR64 38 /* doubleword64 S + A */
+#define R_PPC64_ADDR16_HIGHER 39 /* half16 #higher(S + A) */
+#define R_PPC64_ADDR16_HIGHERA 40 /* half16 #highera(S + A) */
+#define R_PPC64_ADDR16_HIGHEST 41 /* half16 #highest(S + A) */
+#define R_PPC64_ADDR16_HIGHESTA 42 /* half16 #highesta(S + A) */
+#define R_PPC64_UADDR64 43 /* doubleword64 S + A */
+#define R_PPC64_REL64 44 /* doubleword64 S + A - P */
+#define R_PPC64_PLT64 45 /* doubleword64 L + A */
+#define R_PPC64_PLTREL64 46 /* doubleword64 L + A - P */
+#define R_PPC64_TOC16 47 /* half16* S + A - .TOC */
+#define R_PPC64_TOC16_LO 48 /* half16 #lo(S + A - .TOC.) */
+#define R_PPC64_TOC16_HI 49 /* half16 #hi(S + A - .TOC.) */
+#define R_PPC64_TOC16_HA 50 /* half16 #ha(S + A - .TOC.) */
+#define R_PPC64_TOC 51 /* doubleword64 .TOC */
+#define R_PPC64_PLTGOT16 52 /* half16* M + A */
+#define R_PPC64_PLTGOT16_LO 53 /* half16 #lo(M + A) */
+#define R_PPC64_PLTGOT16_HI 54 /* half16 #hi(M + A) */
+#define R_PPC64_PLTGOT16_HA 55 /* half16 #ha(M + A) */
+
+#define R_PPC64_ADDR16_DS 56 /* half16ds* (S + A) >> 2 */
+#define R_PPC64_ADDR16_LO_DS 57 /* half16ds #lo(S + A) >> 2 */
+#define R_PPC64_GOT16_DS 58 /* half16ds* (G + A) >> 2 */
+#define R_PPC64_GOT16_LO_DS 59 /* half16ds #lo(G + A) >> 2 */
+#define R_PPC64_PLT16_LO_DS 60 /* half16ds #lo(L + A) >> 2 */
+#define R_PPC64_SECTOFF_DS 61 /* half16ds* (R + A) >> 2 */
+#define R_PPC64_SECTOFF_LO_DS 62 /* half16ds #lo(R + A) >> 2 */
+#define R_PPC64_TOC16_DS 63 /* half16ds* (S + A - .TOC.) >> 2 */
+#define R_PPC64_TOC16_LO_DS 64 /* half16ds #lo(S + A - .TOC.) >> 2 */
+#define R_PPC64_PLTGOT16_DS 65 /* half16ds* (M + A) >> 2 */
+#define R_PPC64_PLTGOT16_LO_DS 66 /* half16ds #lo(M + A) >> 2 */
+
+/* PowerPC64 relocations defined for the TLS access ABI. */
+#define R_PPC64_TLS 67 /* none (sym+add)@tls */
+#define R_PPC64_DTPMOD64 68 /* doubleword64 (sym+add)@dtpmod */
+#define R_PPC64_TPREL16 69 /* half16* (sym+add)@tprel */
+#define R_PPC64_TPREL16_LO 70 /* half16 (sym+add)@tprel@l */
+#define R_PPC64_TPREL16_HI 71 /* half16 (sym+add)@tprel@h */
+#define R_PPC64_TPREL16_HA 72 /* half16 (sym+add)@tprel@ha */
+#define R_PPC64_TPREL64 73 /* doubleword64 (sym+add)@tprel */
+#define R_PPC64_DTPREL16 74 /* half16* (sym+add)@dtprel */
+#define R_PPC64_DTPREL16_LO 75 /* half16 (sym+add)@dtprel@l */
+#define R_PPC64_DTPREL16_HI 76 /* half16 (sym+add)@dtprel@h */
+#define R_PPC64_DTPREL16_HA 77 /* half16 (sym+add)@dtprel@ha */
+#define R_PPC64_DTPREL64 78 /* doubleword64 (sym+add)@dtprel */
+#define R_PPC64_GOT_TLSGD16 79 /* half16* (sym+add)@got@tlsgd */
+#define R_PPC64_GOT_TLSGD16_LO 80 /* half16 (sym+add)@got@tlsgd@l */
+#define R_PPC64_GOT_TLSGD16_HI 81 /* half16 (sym+add)@got@tlsgd@h */
+#define R_PPC64_GOT_TLSGD16_HA 82 /* half16 (sym+add)@got@tlsgd@ha */
+#define R_PPC64_GOT_TLSLD16 83 /* half16* (sym+add)@got@tlsld */
+#define R_PPC64_GOT_TLSLD16_LO 84 /* half16 (sym+add)@got@tlsld@l */
+#define R_PPC64_GOT_TLSLD16_HI 85 /* half16 (sym+add)@got@tlsld@h */
+#define R_PPC64_GOT_TLSLD16_HA 86 /* half16 (sym+add)@got@tlsld@ha */
+#define R_PPC64_GOT_TPREL16_DS 87 /* half16ds* (sym+add)@got@tprel */
+#define R_PPC64_GOT_TPREL16_LO_DS 88 /* half16ds (sym+add)@got@tprel@l */
+#define R_PPC64_GOT_TPREL16_HI 89 /* half16 (sym+add)@got@tprel@h */
+#define R_PPC64_GOT_TPREL16_HA 90 /* half16 (sym+add)@got@tprel@ha */
+#define R_PPC64_GOT_DTPREL16_DS 91 /* half16ds* (sym+add)@got@dtprel */
+#define R_PPC64_GOT_DTPREL16_LO_DS 92 /* half16ds (sym+add)@got@dtprel@l */
+#define R_PPC64_GOT_DTPREL16_HI 93 /* half16 (sym+add)@got@dtprel@h */
+#define R_PPC64_GOT_DTPREL16_HA 94 /* half16 (sym+add)@got@dtprel@ha */
+#define R_PPC64_TPREL16_DS 95 /* half16ds* (sym+add)@tprel */
+#define R_PPC64_TPREL16_LO_DS 96 /* half16ds (sym+add)@tprel@l */
+#define R_PPC64_TPREL16_HIGHER 97 /* half16 (sym+add)@tprel@higher */
+#define R_PPC64_TPREL16_HIGHERA 98 /* half16 (sym+add)@tprel@highera */
+#define R_PPC64_TPREL16_HIGHEST 99 /* half16 (sym+add)@tprel@highest */
+#define R_PPC64_TPREL16_HIGHESTA 100 /* half16 (sym+add)@tprel@highesta */
+#define R_PPC64_DTPREL16_DS 101 /* half16ds* (sym+add)@dtprel */
+#define R_PPC64_DTPREL16_LO_DS 102 /* half16ds (sym+add)@dtprel@l */
+#define R_PPC64_DTPREL16_HIGHER 103 /* half16 (sym+add)@dtprel@higher */
+#define R_PPC64_DTPREL16_HIGHERA 104 /* half16 (sym+add)@dtprel@highera */
+#define R_PPC64_DTPREL16_HIGHEST 105 /* half16 (sym+add)@dtprel@highest */
+#define R_PPC64_DTPREL16_HIGHESTA 106 /* half16 (sym+add)@dtprel@highesta */
+#define R_PPC64_TLSGD 107 /* none (sym+add)@tlsgd */
+#define R_PPC64_TLSLD 108 /* none (sym+add)@tlsld */
+#define R_PPC64_TOCSAVE 109 /* none */
+
+/* Added when HA and HI relocs were changed to report overflows. */
+#define R_PPC64_ADDR16_HIGH 110
+#define R_PPC64_ADDR16_HIGHA 111
+#define R_PPC64_TPREL16_HIGH 112
+#define R_PPC64_TPREL16_HIGHA 113
+#define R_PPC64_DTPREL16_HIGH 114
+#define R_PPC64_DTPREL16_HIGHA 115
+
+/* GNU extension to support local ifunc. */
+#define R_PPC64_JMP_IREL 247
+#define R_PPC64_IRELATIVE 248
+#define R_PPC64_REL16 249 /* half16 (sym+add-.) */
+#define R_PPC64_REL16_LO 250 /* half16 (sym+add-.)@l */
+#define R_PPC64_REL16_HI 251 /* half16 (sym+add-.)@h */
+#define R_PPC64_REL16_HA 252 /* half16 (sym+add-.)@ha */
+
+/* e_flags bits specifying ABI.
+ 1 for original function descriptor using ABI,
+ 2 for revised ABI without function descriptors,
+ 0 for unspecified or not using any features affected by the differences. */
+#define EF_PPC64_ABI 3
+
+/* PowerPC64 specific values for the Dyn d_tag field. */
+#define DT_PPC64_GLINK (DT_LOPROC + 0)
+#define DT_PPC64_OPD (DT_LOPROC + 1)
+#define DT_PPC64_OPDSZ (DT_LOPROC + 2)
+#define DT_PPC64_OPT (DT_LOPROC + 3)
+#define DT_PPC64_NUM 3
+
+/* PowerPC64 specific values for the DT_PPC64_OPT Dyn entry. */
+#define PPC64_OPT_TLS 1
+#define PPC64_OPT_MULTI_TOC 2
+
+/* PowerPC64 specific values for the Elf64_Sym st_other field. */
+#define STO_PPC64_LOCAL_BIT 5
+#define STO_PPC64_LOCAL_MASK (7 << STO_PPC64_LOCAL_BIT)
+#define PPC64_LOCAL_ENTRY_OFFSET(other) \
+ (((1 << (((other) & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT)) >> 2) << 2)
+
+
+/* ARM specific declarations */
+
+/* Processor specific flags for the ELF header e_flags field. */
+#define EF_ARM_RELEXEC 0x01
+#define EF_ARM_HASENTRY 0x02
+#define EF_ARM_INTERWORK 0x04
+#define EF_ARM_APCS_26 0x08
+#define EF_ARM_APCS_FLOAT 0x10
+#define EF_ARM_PIC 0x20
+#define EF_ARM_ALIGN8 0x40 /* 8-bit structure alignment is in use */
+#define EF_ARM_NEW_ABI 0x80
+#define EF_ARM_OLD_ABI 0x100
+#define EF_ARM_SOFT_FLOAT 0x200
+#define EF_ARM_VFP_FLOAT 0x400
+#define EF_ARM_MAVERICK_FLOAT 0x800
+
+#define EF_ARM_ABI_FLOAT_SOFT 0x200 /* NB conflicts with EF_ARM_SOFT_FLOAT */
+#define EF_ARM_ABI_FLOAT_HARD 0x400 /* NB conflicts with EF_ARM_VFP_FLOAT */
+
+
+/* Other constants defined in the ARM ELF spec. version B-01. */
+/* NB. These conflict with values defined above. */
+#define EF_ARM_SYMSARESORTED 0x04
+#define EF_ARM_DYNSYMSUSESEGIDX 0x08
+#define EF_ARM_MAPSYMSFIRST 0x10
+#define EF_ARM_EABIMASK 0XFF000000
+
+/* Constants defined in AAELF. */
+#define EF_ARM_BE8 0x00800000
+#define EF_ARM_LE8 0x00400000
+
+#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
+#define EF_ARM_EABI_UNKNOWN 0x00000000
+#define EF_ARM_EABI_VER1 0x01000000
+#define EF_ARM_EABI_VER2 0x02000000
+#define EF_ARM_EABI_VER3 0x03000000
+#define EF_ARM_EABI_VER4 0x04000000
+#define EF_ARM_EABI_VER5 0x05000000
+
+/* Additional symbol types for Thumb. */
+#define STT_ARM_TFUNC STT_LOPROC /* A Thumb function. */
+#define STT_ARM_16BIT STT_HIPROC /* A Thumb label. */
+
+/* ARM-specific values for sh_flags */
+#define SHF_ARM_ENTRYSECT 0x10000000 /* Section contains an entry point */
+#define SHF_ARM_COMDEF 0x80000000 /* Section may be multiply defined
+ in the input to a link step. */
+
+/* ARM-specific program header flags */
+#define PF_ARM_SB 0x10000000 /* Segment contains the location
+ addressed by the static base. */
+#define PF_ARM_PI 0x20000000 /* Position-independent segment. */
+#define PF_ARM_ABS 0x40000000 /* Absolute segment. */
+
+/* Processor specific values for the Phdr p_type field. */
+#define PT_ARM_EXIDX (PT_LOPROC + 1) /* ARM unwind segment. */
+
+/* Processor specific values for the Shdr sh_type field. */
+#define SHT_ARM_EXIDX (SHT_LOPROC + 1) /* ARM unwind section. */
+#define SHT_ARM_PREEMPTMAP (SHT_LOPROC + 2) /* Preemption details. */
+#define SHT_ARM_ATTRIBUTES (SHT_LOPROC + 3) /* ARM attributes section. */
+
+
+/* AArch64 relocs. */
+
+#define R_AARCH64_NONE 0 /* No relocation. */
+#define R_AARCH64_ABS64 257 /* Direct 64 bit. */
+#define R_AARCH64_ABS32 258 /* Direct 32 bit. */
+#define R_AARCH64_ABS16 259 /* Direct 16-bit. */
+#define R_AARCH64_PREL64 260 /* PC-relative 64-bit. */
+#define R_AARCH64_PREL32 261 /* PC-relative 32-bit. */
+#define R_AARCH64_PREL16 262 /* PC-relative 16-bit. */
+#define R_AARCH64_MOVW_UABS_G0 263 /* Dir. MOVZ imm. from bits 15:0. */
+#define R_AARCH64_MOVW_UABS_G0_NC 264 /* Likewise for MOVK; no check. */
+#define R_AARCH64_MOVW_UABS_G1 265 /* Dir. MOVZ imm. from bits 31:16. */
+#define R_AARCH64_MOVW_UABS_G1_NC 266 /* Likewise for MOVK; no check. */
+#define R_AARCH64_MOVW_UABS_G2 267 /* Dir. MOVZ imm. from bits 47:32. */
+#define R_AARCH64_MOVW_UABS_G2_NC 268 /* Likewise for MOVK; no check. */
+#define R_AARCH64_MOVW_UABS_G3 269 /* Dir. MOV{K,Z} imm. from 63:48. */
+#define R_AARCH64_MOVW_SABS_G0 270 /* Dir. MOV{N,Z} imm. from 15:0. */
+#define R_AARCH64_MOVW_SABS_G1 271 /* Dir. MOV{N,Z} imm. from 31:16. */
+#define R_AARCH64_MOVW_SABS_G2 272 /* Dir. MOV{N,Z} imm. from 47:32. */
+#define R_AARCH64_LD_PREL_LO19 273 /* PC-rel. LD imm. from bits 20:2. */
+#define R_AARCH64_ADR_PREL_LO21 274 /* PC-rel. ADR imm. from bits 20:0. */
+#define R_AARCH64_ADR_PREL_PG_HI21 275 /* Page-rel. ADRP imm. from 32:12. */
+#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Likewise; no overflow check. */
+#define R_AARCH64_ADD_ABS_LO12_NC 277 /* Dir. ADD imm. from bits 11:0. */
+#define R_AARCH64_LDST8_ABS_LO12_NC 278 /* Likewise for LD/ST; no check. */
+#define R_AARCH64_TSTBR14 279 /* PC-rel. TBZ/TBNZ imm. from 15:2. */
+#define R_AARCH64_CONDBR19 280 /* PC-rel. cond. br. imm. from 20:2. */
+#define R_AARCH64_JUMP26 282 /* PC-rel. B imm. from bits 27:2. */
+#define R_AARCH64_CALL26 283 /* Likewise for CALL. */
+#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* Dir. ADD imm. from bits 11:1. */
+#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* Likewise for bits 11:2. */
+#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* Likewise for bits 11:3. */
+#define R_AARCH64_MOVW_PREL_G0 287 /* PC-rel. MOV{N,Z} imm. from 15:0. */
+#define R_AARCH64_MOVW_PREL_G0_NC 288 /* Likewise for MOVK; no check. */
+#define R_AARCH64_MOVW_PREL_G1 289 /* PC-rel. MOV{N,Z} imm. from 31:16. */
+#define R_AARCH64_MOVW_PREL_G1_NC 290 /* Likewise for MOVK; no check. */
+#define R_AARCH64_MOVW_PREL_G2 291 /* PC-rel. MOV{N,Z} imm. from 47:32. */
+#define R_AARCH64_MOVW_PREL_G2_NC 292 /* Likewise for MOVK; no check. */
+#define R_AARCH64_MOVW_PREL_G3 293 /* PC-rel. MOV{N,Z} imm. from 63:48. */
+#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* Dir. ADD imm. from bits 11:4. */
+#define R_AARCH64_MOVW_GOTOFF_G0 300 /* GOT-rel. off. MOV{N,Z} imm. 15:0. */
+#define R_AARCH64_MOVW_GOTOFF_G0_NC 301 /* Likewise for MOVK; no check. */
+#define R_AARCH64_MOVW_GOTOFF_G1 302 /* GOT-rel. o. MOV{N,Z} imm. 31:16. */
+#define R_AARCH64_MOVW_GOTOFF_G1_NC 303 /* Likewise for MOVK; no check. */
+#define R_AARCH64_MOVW_GOTOFF_G2 304 /* GOT-rel. o. MOV{N,Z} imm. 47:32. */
+#define R_AARCH64_MOVW_GOTOFF_G2_NC 305 /* Likewise for MOVK; no check. */
+#define R_AARCH64_MOVW_GOTOFF_G3 306 /* GOT-rel. o. MOV{N,Z} imm. 63:48. */
+#define R_AARCH64_GOTREL64 307 /* GOT-relative 64-bit. */
+#define R_AARCH64_GOTREL32 308 /* GOT-relative 32-bit. */
+#define R_AARCH64_GOT_LD_PREL19 309 /* PC-rel. GOT off. load imm. 20:2. */
+#define R_AARCH64_LD64_GOTOFF_LO15 310 /* GOT-rel. off. LD/ST imm. 14:3. */
+#define R_AARCH64_ADR_GOT_PAGE 311 /* P-page-rel. GOT off. ADRP 32:12. */
+#define R_AARCH64_LD64_GOT_LO12_NC 312 /* Dir. GOT off. LD/ST imm. 11:3. */
+#define R_AARCH64_LD64_GOTPAGE_LO15 313 /* GOT-page-rel. GOT off. LD/ST 14:3 */
+#define R_AARCH64_TLSGD_ADR_PREL21 512 /* PC-relative ADR imm. 20:0. */
+#define R_AARCH64_TLSGD_ADR_PAGE21 513 /* page-rel. ADRP imm. 32:12. */
+#define R_AARCH64_TLSGD_ADD_LO12_NC 514 /* direct ADD imm. from 11:0. */
+#define R_AARCH64_TLSGD_MOVW_G1 515 /* GOT-rel. MOV{N,Z} 31:16. */
+#define R_AARCH64_TLSGD_MOVW_G0_NC 516 /* GOT-rel. MOVK imm. 15:0. */
+#define R_AARCH64_TLSLD_ADR_PREL21 517 /* Like 512; local dynamic model. */
+#define R_AARCH64_TLSLD_ADR_PAGE21 518 /* Like 513; local dynamic model. */
+#define R_AARCH64_TLSLD_ADD_LO12_NC 519 /* Like 514; local dynamic model. */
+#define R_AARCH64_TLSLD_MOVW_G1 520 /* Like 515; local dynamic model. */
+#define R_AARCH64_TLSLD_MOVW_G0_NC 521 /* Like 516; local dynamic model. */
+#define R_AARCH64_TLSLD_LD_PREL19 522 /* TLS PC-rel. load imm. 20:2. */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* TLS DTP-rel. MOV{N,Z} 47:32. */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* TLS DTP-rel. MOV{N,Z} 31:16. */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* Likewise; MOVK; no check. */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* TLS DTP-rel. MOV{N,Z} 15:0. */
+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* Likewise; MOVK; no check. */
+#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTP-rel. ADD imm. from 23:12. */
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTP-rel. ADD imm. from 11:0. */
+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* Likewise; no ovfl. check. */
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTP-rel. LD/ST imm. 11:0. */
+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* Likewise; no check. */
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTP-rel. LD/ST imm. 11:1. */
+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* Likewise; no check. */
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTP-rel. LD/ST imm. 11:2. */
+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* Likewise; no check. */
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTP-rel. LD/ST imm. 11:3. */
+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* Likewise; no check. */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* GOT-rel. MOV{N,Z} 31:16. */
+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* GOT-rel. MOVK 15:0. */
+#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page-rel. ADRP 32:12. */
+#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* Direct LD off. 11:3. */
+#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* PC-rel. load imm. 20:2. */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TLS TP-rel. MOV{N,Z} 47:32. */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TLS TP-rel. MOV{N,Z} 31:16. */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* Likewise; MOVK; no check. */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TLS TP-rel. MOV{N,Z} 15:0. */
+#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* Likewise; MOVK; no check. */
+#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TP-rel. ADD imm. 23:12. */
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TP-rel. ADD imm. 11:0. */
+#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* Likewise; no ovfl. check. */
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TP-rel. LD/ST off. 11:0. */
+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* Likewise; no ovfl. check. */
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TP-rel. LD/ST off. 11:1. */
+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* Likewise; no check. */
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TP-rel. LD/ST off. 11:2. */
+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* Likewise; no check. */
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TP-rel. LD/ST off. 11:3. */
+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* Likewise; no check. */
+#define R_AARCH64_TLSDESC_LD_PREL19 560 /* PC-rel. load immediate 20:2. */
+#define R_AARCH64_TLSDESC_ADR_PREL21 561 /* PC-rel. ADR immediate 20:0. */
+#define R_AARCH64_TLSDESC_ADR_PAGE21 562 /* Page-rel. ADRP imm. 32:12. */
+#define R_AARCH64_TLSDESC_LD64_LO12 563 /* Direct LD off. from 11:3. */
+#define R_AARCH64_TLSDESC_ADD_LO12 564 /* Direct ADD imm. from 11:0. */
+#define R_AARCH64_TLSDESC_OFF_G1 565 /* GOT-rel. MOV{N,Z} imm. 31:16. */
+#define R_AARCH64_TLSDESC_OFF_G0_NC 566 /* GOT-rel. MOVK imm. 15:0; no ck. */
+#define R_AARCH64_TLSDESC_LDR 567 /* Relax LDR. */
+#define R_AARCH64_TLSDESC_ADD 568 /* Relax ADD. */
+#define R_AARCH64_TLSDESC_CALL 569 /* Relax BLR. */
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 /* TP-rel. LD/ST off. 11:4. */
+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 /* Likewise; no check. */
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 /* DTP-rel. LD/ST imm. 11:4. */
+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 /* Likewise; no check. */
+#define R_AARCH64_COPY 1024 /* Copy symbol at runtime. */
+#define R_AARCH64_GLOB_DAT 1025 /* Create GOT entry. */
+#define R_AARCH64_JUMP_SLOT 1026 /* Create PLT entry. */
+#define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */
+#define R_AARCH64_TLS_DTPMOD64 1028 /* Module number, 64 bit. */
+#define R_AARCH64_TLS_DTPREL64 1029 /* Module-relative offset, 64 bit. */
+#define R_AARCH64_TLS_TPREL64 1030 /* TP-relative offset, 64 bit. */
+#define R_AARCH64_TLSDESC 1031 /* TLS Descriptor. */
+#define R_AARCH64_IRELATIVE 1032 /* STT_GNU_IFUNC relocation. */
+
+/* ARM relocs. */
+
+#define R_ARM_NONE 0 /* No reloc */
+#define R_ARM_PC24 1 /* Deprecated PC relative 26
+ bit branch. */
+#define R_ARM_ABS32 2 /* Direct 32 bit */
+#define R_ARM_REL32 3 /* PC relative 32 bit */
+#define R_ARM_PC13 4
+#define R_ARM_ABS16 5 /* Direct 16 bit */
+#define R_ARM_ABS12 6 /* Direct 12 bit */
+#define R_ARM_THM_ABS5 7 /* Direct & 0x7C (LDR, STR). */
+#define R_ARM_ABS8 8 /* Direct 8 bit */
+#define R_ARM_SBREL32 9
+#define R_ARM_THM_PC22 10 /* PC relative 24 bit (Thumb32 BL). */
+#define R_ARM_THM_PC8 11 /* PC relative & 0x3FC
+ (Thumb16 LDR, ADD, ADR). */
+#define R_ARM_AMP_VCALL9 12
+#define R_ARM_SWI24 13 /* Obsolete static relocation. */
+#define R_ARM_TLS_DESC 13 /* Dynamic relocation. */
+#define R_ARM_THM_SWI8 14 /* Reserved. */
+#define R_ARM_XPC25 15 /* Reserved. */
+#define R_ARM_THM_XPC22 16 /* Reserved. */
+#define R_ARM_TLS_DTPMOD32 17 /* ID of module containing symbol */
+#define R_ARM_TLS_DTPOFF32 18 /* Offset in TLS block */
+#define R_ARM_TLS_TPOFF32 19 /* Offset in static TLS block */
+#define R_ARM_COPY 20 /* Copy symbol at runtime */
+#define R_ARM_GLOB_DAT 21 /* Create GOT entry */
+#define R_ARM_JUMP_SLOT 22 /* Create PLT entry */
+#define R_ARM_RELATIVE 23 /* Adjust by program base */
+#define R_ARM_GOTOFF 24 /* 32 bit offset to GOT */
+#define R_ARM_GOTPC 25 /* 32 bit PC relative offset to GOT */
+#define R_ARM_GOT32 26 /* 32 bit GOT entry */
+#define R_ARM_PLT32 27 /* Deprecated, 32 bit PLT address. */
+#define R_ARM_CALL 28 /* PC relative 24 bit (BL, BLX). */
+#define R_ARM_JUMP24 29 /* PC relative 24 bit
+ (B, BL<cond>). */
+#define R_ARM_THM_JUMP24 30 /* PC relative 24 bit (Thumb32 B.W). */
+#define R_ARM_BASE_ABS 31 /* Adjust by program base. */
+#define R_ARM_ALU_PCREL_7_0 32 /* Obsolete. */
+#define R_ARM_ALU_PCREL_15_8 33 /* Obsolete. */
+#define R_ARM_ALU_PCREL_23_15 34 /* Obsolete. */
+#define R_ARM_LDR_SBREL_11_0 35 /* Deprecated, prog. base relative. */
+#define R_ARM_ALU_SBREL_19_12 36 /* Deprecated, prog. base relative. */
+#define R_ARM_ALU_SBREL_27_20 37 /* Deprecated, prog. base relative. */
+#define R_ARM_TARGET1 38
+#define R_ARM_SBREL31 39 /* Program base relative. */
+#define R_ARM_V4BX 40
+#define R_ARM_TARGET2 41
+#define R_ARM_PREL31 42 /* 32 bit PC relative. */
+#define R_ARM_MOVW_ABS_NC 43 /* Direct 16-bit (MOVW). */
+#define R_ARM_MOVT_ABS 44 /* Direct high 16-bit (MOVT). */
+#define R_ARM_MOVW_PREL_NC 45 /* PC relative 16-bit (MOVW). */
+#define R_ARM_MOVT_PREL 46 /* PC relative (MOVT). */
+#define R_ARM_THM_MOVW_ABS_NC 47 /* Direct 16 bit (Thumb32 MOVW). */
+#define R_ARM_THM_MOVT_ABS 48 /* Direct high 16 bit
+ (Thumb32 MOVT). */
+#define R_ARM_THM_MOVW_PREL_NC 49 /* PC relative 16 bit
+ (Thumb32 MOVW). */
+#define R_ARM_THM_MOVT_PREL 50 /* PC relative high 16 bit
+ (Thumb32 MOVT). */
+#define R_ARM_THM_JUMP19 51 /* PC relative 20 bit
+ (Thumb32 B<cond>.W). */
+#define R_ARM_THM_JUMP6 52 /* PC relative X & 0x7E
+ (Thumb16 CBZ, CBNZ). */
+#define R_ARM_THM_ALU_PREL_11_0 53 /* PC relative 12 bit
+ (Thumb32 ADR.W). */
+#define R_ARM_THM_PC12 54 /* PC relative 12 bit
+ (Thumb32 LDR{D,SB,H,SH}). */
+#define R_ARM_ABS32_NOI 55 /* Direct 32-bit. */
+#define R_ARM_REL32_NOI 56 /* PC relative 32-bit. */
+#define R_ARM_ALU_PC_G0_NC 57 /* PC relative (ADD, SUB). */
+#define R_ARM_ALU_PC_G0 58 /* PC relative (ADD, SUB). */
+#define R_ARM_ALU_PC_G1_NC 59 /* PC relative (ADD, SUB). */
+#define R_ARM_ALU_PC_G1 60 /* PC relative (ADD, SUB). */
+#define R_ARM_ALU_PC_G2 61 /* PC relative (ADD, SUB). */
+#define R_ARM_LDR_PC_G1 62 /* PC relative (LDR,STR,LDRB,STRB). */
+#define R_ARM_LDR_PC_G2 63 /* PC relative (LDR,STR,LDRB,STRB). */
+#define R_ARM_LDRS_PC_G0 64 /* PC relative (STR{D,H},
+ LDR{D,SB,H,SH}). */
+#define R_ARM_LDRS_PC_G1 65 /* PC relative (STR{D,H},
+ LDR{D,SB,H,SH}). */
+#define R_ARM_LDRS_PC_G2 66 /* PC relative (STR{D,H},
+ LDR{D,SB,H,SH}). */
+#define R_ARM_LDC_PC_G0 67 /* PC relative (LDC, STC). */
+#define R_ARM_LDC_PC_G1 68 /* PC relative (LDC, STC). */
+#define R_ARM_LDC_PC_G2 69 /* PC relative (LDC, STC). */
+#define R_ARM_ALU_SB_G0_NC 70 /* Program base relative (ADD,SUB). */
+#define R_ARM_ALU_SB_G0 71 /* Program base relative (ADD,SUB). */
+#define R_ARM_ALU_SB_G1_NC 72 /* Program base relative (ADD,SUB). */
+#define R_ARM_ALU_SB_G1 73 /* Program base relative (ADD,SUB). */
+#define R_ARM_ALU_SB_G2 74 /* Program base relative (ADD,SUB). */
+#define R_ARM_LDR_SB_G0 75 /* Program base relative (LDR,
+ STR, LDRB, STRB). */
+#define R_ARM_LDR_SB_G1 76 /* Program base relative
+ (LDR, STR, LDRB, STRB). */
+#define R_ARM_LDR_SB_G2 77 /* Program base relative
+ (LDR, STR, LDRB, STRB). */
+#define R_ARM_LDRS_SB_G0 78 /* Program base relative
+ (LDR, STR, LDRB, STRB). */
+#define R_ARM_LDRS_SB_G1 79 /* Program base relative
+ (LDR, STR, LDRB, STRB). */
+#define R_ARM_LDRS_SB_G2 80 /* Program base relative
+ (LDR, STR, LDRB, STRB). */
+#define R_ARM_LDC_SB_G0 81 /* Program base relative (LDC,STC). */
+#define R_ARM_LDC_SB_G1 82 /* Program base relative (LDC,STC). */
+#define R_ARM_LDC_SB_G2 83 /* Program base relative (LDC,STC). */
+#define R_ARM_MOVW_BREL_NC 84 /* Program base relative 16
+ bit (MOVW). */
+#define R_ARM_MOVT_BREL 85 /* Program base relative high
+ 16 bit (MOVT). */
+#define R_ARM_MOVW_BREL 86 /* Program base relative 16
+ bit (MOVW). */
+#define R_ARM_THM_MOVW_BREL_NC 87 /* Program base relative 16
+ bit (Thumb32 MOVW). */
+#define R_ARM_THM_MOVT_BREL 88 /* Program base relative high
+ 16 bit (Thumb32 MOVT). */
+#define R_ARM_THM_MOVW_BREL 89 /* Program base relative 16
+ bit (Thumb32 MOVW). */
+#define R_ARM_TLS_GOTDESC 90
+#define R_ARM_TLS_CALL 91
+#define R_ARM_TLS_DESCSEQ 92 /* TLS relaxation. */
+#define R_ARM_THM_TLS_CALL 93
+#define R_ARM_PLT32_ABS 94
+#define R_ARM_GOT_ABS 95 /* GOT entry. */
+#define R_ARM_GOT_PREL 96 /* PC relative GOT entry. */
+#define R_ARM_GOT_BREL12 97 /* GOT entry relative to GOT
+ origin (LDR). */
+#define R_ARM_GOTOFF12 98 /* 12 bit, GOT entry relative
+ to GOT origin (LDR, STR). */
+#define R_ARM_GOTRELAX 99
+#define R_ARM_GNU_VTENTRY 100
+#define R_ARM_GNU_VTINHERIT 101
+#define R_ARM_THM_PC11 102 /* PC relative & 0xFFE (Thumb16 B). */
+#define R_ARM_THM_PC9 103 /* PC relative & 0x1FE
+ (Thumb16 B/B<cond>). */
+#define R_ARM_TLS_GD32 104 /* PC-rel 32 bit for global dynamic
+ thread local data */
+#define R_ARM_TLS_LDM32 105 /* PC-rel 32 bit for local dynamic
+ thread local data */
+#define R_ARM_TLS_LDO32 106 /* 32 bit offset relative to TLS
+ block */
+#define R_ARM_TLS_IE32 107 /* PC-rel 32 bit for GOT entry of
+ static TLS block offset */
+#define R_ARM_TLS_LE32 108 /* 32 bit offset relative to static
+ TLS block */
+#define R_ARM_TLS_LDO12 109 /* 12 bit relative to TLS
+ block (LDR, STR). */
+#define R_ARM_TLS_LE12 110 /* 12 bit relative to static
+ TLS block (LDR, STR). */
+#define R_ARM_TLS_IE12GP 111 /* 12 bit GOT entry relative
+ to GOT origin (LDR). */
+#define R_ARM_ME_TOO 128 /* Obsolete. */
+#define R_ARM_THM_TLS_DESCSEQ 129
+#define R_ARM_THM_TLS_DESCSEQ16 129
+#define R_ARM_THM_TLS_DESCSEQ32 130
+#define R_ARM_THM_GOT_BREL12 131 /* GOT entry relative to GOT
+ origin, 12 bit (Thumb32 LDR). */
+#define R_ARM_IRELATIVE 160
+#define R_ARM_RXPC25 249
+#define R_ARM_RSBREL32 250
+#define R_ARM_THM_RPC22 251
+#define R_ARM_RREL32 252
+#define R_ARM_RABS22 253
+#define R_ARM_RPC24 254
+#define R_ARM_RBASE 255
+/* Keep this the last entry. */
+#define R_ARM_NUM 256
+
+/* IA-64 specific declarations. */
+
+/* Processor specific flags for the Ehdr e_flags field. */
+#define EF_IA_64_MASKOS 0x0000000f /* os-specific flags */
+#define EF_IA_64_ABI64 0x00000010 /* 64-bit ABI */
+#define EF_IA_64_ARCH 0xff000000 /* arch. version mask */
+
+/* Processor specific values for the Phdr p_type field. */
+#define PT_IA_64_ARCHEXT (PT_LOPROC + 0) /* arch extension bits */
+#define PT_IA_64_UNWIND (PT_LOPROC + 1) /* ia64 unwind bits */
+#define PT_IA_64_HP_OPT_ANOT (PT_LOOS + 0x12)
+#define PT_IA_64_HP_HSL_ANOT (PT_LOOS + 0x13)
+#define PT_IA_64_HP_STACK (PT_LOOS + 0x14)
+
+/* Processor specific flags for the Phdr p_flags field. */
+#define PF_IA_64_NORECOV 0x80000000 /* spec insns w/o recovery */
+
+/* Processor specific values for the Shdr sh_type field. */
+#define SHT_IA_64_EXT (SHT_LOPROC + 0) /* extension bits */
+#define SHT_IA_64_UNWIND (SHT_LOPROC + 1) /* unwind bits */
+
+/* Processor specific flags for the Shdr sh_flags field. */
+#define SHF_IA_64_SHORT 0x10000000 /* section near gp */
+#define SHF_IA_64_NORECOV 0x20000000 /* spec insns w/o recovery */
+
+/* Processor specific values for the Dyn d_tag field. */
+#define DT_IA_64_PLT_RESERVE (DT_LOPROC + 0)
+#define DT_IA_64_NUM 1
+
+/* IA-64 relocations. */
+#define R_IA64_NONE 0x00 /* none */
+#define R_IA64_IMM14 0x21 /* symbol + addend, add imm14 */
+#define R_IA64_IMM22 0x22 /* symbol + addend, add imm22 */
+#define R_IA64_IMM64 0x23 /* symbol + addend, mov imm64 */
+#define R_IA64_DIR32MSB 0x24 /* symbol + addend, data4 MSB */
+#define R_IA64_DIR32LSB 0x25 /* symbol + addend, data4 LSB */
+#define R_IA64_DIR64MSB 0x26 /* symbol + addend, data8 MSB */
+#define R_IA64_DIR64LSB 0x27 /* symbol + addend, data8 LSB */
+#define R_IA64_GPREL22 0x2a /* @gprel(sym + add), add imm22 */
+#define R_IA64_GPREL64I 0x2b /* @gprel(sym + add), mov imm64 */
+#define R_IA64_GPREL32MSB 0x2c /* @gprel(sym + add), data4 MSB */
+#define R_IA64_GPREL32LSB 0x2d /* @gprel(sym + add), data4 LSB */
+#define R_IA64_GPREL64MSB 0x2e /* @gprel(sym + add), data8 MSB */
+#define R_IA64_GPREL64LSB 0x2f /* @gprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF22 0x32 /* @ltoff(sym + add), add imm22 */
+#define R_IA64_LTOFF64I 0x33 /* @ltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF22 0x3a /* @pltoff(sym + add), add imm22 */
+#define R_IA64_PLTOFF64I 0x3b /* @pltoff(sym + add), mov imm64 */
+#define R_IA64_PLTOFF64MSB 0x3e /* @pltoff(sym + add), data8 MSB */
+#define R_IA64_PLTOFF64LSB 0x3f /* @pltoff(sym + add), data8 LSB */
+#define R_IA64_FPTR64I 0x43 /* @fptr(sym + add), mov imm64 */
+#define R_IA64_FPTR32MSB 0x44 /* @fptr(sym + add), data4 MSB */
+#define R_IA64_FPTR32LSB 0x45 /* @fptr(sym + add), data4 LSB */
+#define R_IA64_FPTR64MSB 0x46 /* @fptr(sym + add), data8 MSB */
+#define R_IA64_FPTR64LSB 0x47 /* @fptr(sym + add), data8 LSB */
+#define R_IA64_PCREL60B 0x48 /* @pcrel(sym + add), brl */
+#define R_IA64_PCREL21B 0x49 /* @pcrel(sym + add), ptb, call */
+#define R_IA64_PCREL21M 0x4a /* @pcrel(sym + add), chk.s */
+#define R_IA64_PCREL21F 0x4b /* @pcrel(sym + add), fchkf */
+#define R_IA64_PCREL32MSB 0x4c /* @pcrel(sym + add), data4 MSB */
+#define R_IA64_PCREL32LSB 0x4d /* @pcrel(sym + add), data4 LSB */
+#define R_IA64_PCREL64MSB 0x4e /* @pcrel(sym + add), data8 MSB */
+#define R_IA64_PCREL64LSB 0x4f /* @pcrel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_FPTR22 0x52 /* @ltoff(@fptr(s+a)), imm22 */
+#define R_IA64_LTOFF_FPTR64I 0x53 /* @ltoff(@fptr(s+a)), imm64 */
+#define R_IA64_LTOFF_FPTR32MSB 0x54 /* @ltoff(@fptr(s+a)), data4 MSB */
+#define R_IA64_LTOFF_FPTR32LSB 0x55 /* @ltoff(@fptr(s+a)), data4 LSB */
+#define R_IA64_LTOFF_FPTR64MSB 0x56 /* @ltoff(@fptr(s+a)), data8 MSB */
+#define R_IA64_LTOFF_FPTR64LSB 0x57 /* @ltoff(@fptr(s+a)), data8 LSB */
+#define R_IA64_SEGREL32MSB 0x5c /* @segrel(sym + add), data4 MSB */
+#define R_IA64_SEGREL32LSB 0x5d /* @segrel(sym + add), data4 LSB */
+#define R_IA64_SEGREL64MSB 0x5e /* @segrel(sym + add), data8 MSB */
+#define R_IA64_SEGREL64LSB 0x5f /* @segrel(sym + add), data8 LSB */
+#define R_IA64_SECREL32MSB 0x64 /* @secrel(sym + add), data4 MSB */
+#define R_IA64_SECREL32LSB 0x65 /* @secrel(sym + add), data4 LSB */
+#define R_IA64_SECREL64MSB 0x66 /* @secrel(sym + add), data8 MSB */
+#define R_IA64_SECREL64LSB 0x67 /* @secrel(sym + add), data8 LSB */
+#define R_IA64_REL32MSB 0x6c /* data 4 + REL */
+#define R_IA64_REL32LSB 0x6d /* data 4 + REL */
+#define R_IA64_REL64MSB 0x6e /* data 8 + REL */
+#define R_IA64_REL64LSB 0x6f /* data 8 + REL */
+#define R_IA64_LTV32MSB 0x74 /* symbol + addend, data4 MSB */
+#define R_IA64_LTV32LSB 0x75 /* symbol + addend, data4 LSB */
+#define R_IA64_LTV64MSB 0x76 /* symbol + addend, data8 MSB */
+#define R_IA64_LTV64LSB 0x77 /* symbol + addend, data8 LSB */
+#define R_IA64_PCREL21BI 0x79 /* @pcrel(sym + add), 21bit inst */
+#define R_IA64_PCREL22 0x7a /* @pcrel(sym + add), 22bit inst */
+#define R_IA64_PCREL64I 0x7b /* @pcrel(sym + add), 64bit inst */
+#define R_IA64_IPLTMSB 0x80 /* dynamic reloc, imported PLT, MSB */
+#define R_IA64_IPLTLSB 0x81 /* dynamic reloc, imported PLT, LSB */
+#define R_IA64_COPY 0x84 /* copy relocation */
+#define R_IA64_SUB 0x85 /* Addend and symbol difference */
+#define R_IA64_LTOFF22X 0x86 /* LTOFF22, relaxable. */
+#define R_IA64_LDXMOV 0x87 /* Use of LTOFF22X. */
+#define R_IA64_TPREL14 0x91 /* @tprel(sym + add), imm14 */
+#define R_IA64_TPREL22 0x92 /* @tprel(sym + add), imm22 */
+#define R_IA64_TPREL64I 0x93 /* @tprel(sym + add), imm64 */
+#define R_IA64_TPREL64MSB 0x96 /* @tprel(sym + add), data8 MSB */
+#define R_IA64_TPREL64LSB 0x97 /* @tprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_TPREL22 0x9a /* @ltoff(@tprel(s+a)), imm2 */
+#define R_IA64_DTPMOD64MSB 0xa6 /* @dtpmod(sym + add), data8 MSB */
+#define R_IA64_DTPMOD64LSB 0xa7 /* @dtpmod(sym + add), data8 LSB */
+#define R_IA64_LTOFF_DTPMOD22 0xaa /* @ltoff(@dtpmod(sym + add)), imm22 */
+#define R_IA64_DTPREL14 0xb1 /* @dtprel(sym + add), imm14 */
+#define R_IA64_DTPREL22 0xb2 /* @dtprel(sym + add), imm22 */
+#define R_IA64_DTPREL64I 0xb3 /* @dtprel(sym + add), imm64 */
+#define R_IA64_DTPREL32MSB 0xb4 /* @dtprel(sym + add), data4 MSB */
+#define R_IA64_DTPREL32LSB 0xb5 /* @dtprel(sym + add), data4 LSB */
+#define R_IA64_DTPREL64MSB 0xb6 /* @dtprel(sym + add), data8 MSB */
+#define R_IA64_DTPREL64LSB 0xb7 /* @dtprel(sym + add), data8 LSB */
+#define R_IA64_LTOFF_DTPREL22 0xba /* @ltoff(@dtprel(s+a)), imm22 */
+
+/* SH specific declarations */
+
+/* Processor specific flags for the ELF header e_flags field. */
+#define EF_SH_MACH_MASK 0x1f
+#define EF_SH_UNKNOWN 0x0
+#define EF_SH1 0x1
+#define EF_SH2 0x2
+#define EF_SH3 0x3
+#define EF_SH_DSP 0x4
+#define EF_SH3_DSP 0x5
+#define EF_SH4AL_DSP 0x6
+#define EF_SH3E 0x8
+#define EF_SH4 0x9
+#define EF_SH2E 0xb
+#define EF_SH4A 0xc
+#define EF_SH2A 0xd
+#define EF_SH4_NOFPU 0x10
+#define EF_SH4A_NOFPU 0x11
+#define EF_SH4_NOMMU_NOFPU 0x12
+#define EF_SH2A_NOFPU 0x13
+#define EF_SH3_NOMMU 0x14
+#define EF_SH2A_SH4_NOFPU 0x15
+#define EF_SH2A_SH3_NOFPU 0x16
+#define EF_SH2A_SH4 0x17
+#define EF_SH2A_SH3E 0x18
+
+/* SH relocs. */
+#define R_SH_NONE 0
+#define R_SH_DIR32 1
+#define R_SH_REL32 2
+#define R_SH_DIR8WPN 3
+#define R_SH_IND12W 4
+#define R_SH_DIR8WPL 5
+#define R_SH_DIR8WPZ 6
+#define R_SH_DIR8BP 7
+#define R_SH_DIR8W 8
+#define R_SH_DIR8L 9
+#define R_SH_SWITCH16 25
+#define R_SH_SWITCH32 26
+#define R_SH_USES 27
+#define R_SH_COUNT 28
+#define R_SH_ALIGN 29
+#define R_SH_CODE 30
+#define R_SH_DATA 31
+#define R_SH_LABEL 32
+#define R_SH_SWITCH8 33
+#define R_SH_GNU_VTINHERIT 34
+#define R_SH_GNU_VTENTRY 35
+#define R_SH_TLS_GD_32 144
+#define R_SH_TLS_LD_32 145
+#define R_SH_TLS_LDO_32 146
+#define R_SH_TLS_IE_32 147
+#define R_SH_TLS_LE_32 148
+#define R_SH_TLS_DTPMOD32 149
+#define R_SH_TLS_DTPOFF32 150
+#define R_SH_TLS_TPOFF32 151
+#define R_SH_GOT32 160
+#define R_SH_PLT32 161
+#define R_SH_COPY 162
+#define R_SH_GLOB_DAT 163
+#define R_SH_JMP_SLOT 164
+#define R_SH_RELATIVE 165
+#define R_SH_GOTOFF 166
+#define R_SH_GOTPC 167
+/* Keep this the last entry. */
+#define R_SH_NUM 256
+
+/* S/390 specific definitions. */
+
+/* Valid values for the e_flags field. */
+
+#define EF_S390_HIGH_GPRS 0x00000001 /* High GPRs kernel facility needed. */
+
+/* Additional s390 relocs */
+
+#define R_390_NONE 0 /* No reloc. */
+#define R_390_8 1 /* Direct 8 bit. */
+#define R_390_12 2 /* Direct 12 bit. */
+#define R_390_16 3 /* Direct 16 bit. */
+#define R_390_32 4 /* Direct 32 bit. */
+#define R_390_PC32 5 /* PC relative 32 bit. */
+#define R_390_GOT12 6 /* 12 bit GOT offset. */
+#define R_390_GOT32 7 /* 32 bit GOT offset. */
+#define R_390_PLT32 8 /* 32 bit PC relative PLT address. */
+#define R_390_COPY 9 /* Copy symbol at runtime. */
+#define R_390_GLOB_DAT 10 /* Create GOT entry. */
+#define R_390_JMP_SLOT 11 /* Create PLT entry. */
+#define R_390_RELATIVE 12 /* Adjust by program base. */
+#define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */
+#define R_390_GOTPC 14 /* 32 bit PC relative offset to GOT. */
+#define R_390_GOT16 15 /* 16 bit GOT offset. */
+#define R_390_PC16 16 /* PC relative 16 bit. */
+#define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */
+#define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */
+#define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */
+#define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */
+#define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */
+#define R_390_64 22 /* Direct 64 bit. */
+#define R_390_PC64 23 /* PC relative 64 bit. */
+#define R_390_GOT64 24 /* 64 bit GOT offset. */
+#define R_390_PLT64 25 /* 64 bit PC relative PLT address. */
+#define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */
+#define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */
+#define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */
+#define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */
+#define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */
+#define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */
+#define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */
+#define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */
+#define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */
+#define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */
+#define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */
+#define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */
+#define R_390_TLS_GDCALL 38 /* Tag for function call in general
+ dynamic TLS code. */
+#define R_390_TLS_LDCALL 39 /* Tag for function call in local
+ dynamic TLS code. */
+#define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic
+ thread local data. */
+#define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic
+ thread local data. */
+#define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS
+ block offset. */
+#define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS
+ block offset. */
+#define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS
+ block offset. */
+#define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic
+ thread local data in LE code. */
+#define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic
+ thread local data in LE code. */
+#define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for
+ negated static TLS block offset. */
+#define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for
+ negated static TLS block offset. */
+#define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for
+ negated static TLS block offset. */
+#define R_390_TLS_LE32 50 /* 32 bit negated offset relative to
+ static TLS block. */
+#define R_390_TLS_LE64 51 /* 64 bit negated offset relative to
+ static TLS block. */
+#define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS
+ block. */
+#define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS
+ block. */
+#define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */
+#define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */
+#define R_390_TLS_TPOFF 56 /* Negated offset in static TLS
+ block. */
+#define R_390_20 57 /* Direct 20 bit. */
+#define R_390_GOT20 58 /* 20 bit GOT offset. */
+#define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */
+#define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS
+ block offset. */
+#define R_390_IRELATIVE 61 /* STT_GNU_IFUNC relocation. */
+/* Keep this the last entry. */
+#define R_390_NUM 62
+
+
+/* CRIS relocations. */
+#define R_CRIS_NONE 0
+#define R_CRIS_8 1
+#define R_CRIS_16 2
+#define R_CRIS_32 3
+#define R_CRIS_8_PCREL 4
+#define R_CRIS_16_PCREL 5
+#define R_CRIS_32_PCREL 6
+#define R_CRIS_GNU_VTINHERIT 7
+#define R_CRIS_GNU_VTENTRY 8
+#define R_CRIS_COPY 9
+#define R_CRIS_GLOB_DAT 10
+#define R_CRIS_JUMP_SLOT 11
+#define R_CRIS_RELATIVE 12
+#define R_CRIS_16_GOT 13
+#define R_CRIS_32_GOT 14
+#define R_CRIS_16_GOTPLT 15
+#define R_CRIS_32_GOTPLT 16
+#define R_CRIS_32_GOTREL 17
+#define R_CRIS_32_PLT_GOTREL 18
+#define R_CRIS_32_PLT_PCREL 19
+
+#define R_CRIS_NUM 20
+
+
+/* AMD x86-64 relocations. */
+#define R_X86_64_NONE 0 /* No reloc */
+#define R_X86_64_64 1 /* Direct 64 bit */
+#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
+#define R_X86_64_GOT32 3 /* 32 bit GOT entry */
+#define R_X86_64_PLT32 4 /* 32 bit PLT address */
+#define R_X86_64_COPY 5 /* Copy symbol at runtime */
+#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
+#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
+#define R_X86_64_RELATIVE 8 /* Adjust by program base */
+#define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative
+ offset to GOT */
+#define R_X86_64_32 10 /* Direct 32 bit zero extended */
+#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
+#define R_X86_64_16 12 /* Direct 16 bit zero extended */
+#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */
+#define R_X86_64_8 14 /* Direct 8 bit sign extended */
+#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */
+#define R_X86_64_DTPMOD64 16 /* ID of module containing symbol */
+#define R_X86_64_DTPOFF64 17 /* Offset in module's TLS block */
+#define R_X86_64_TPOFF64 18 /* Offset in initial TLS block */
+#define R_X86_64_TLSGD 19 /* 32 bit signed PC relative offset
+ to two GOT entries for GD symbol */
+#define R_X86_64_TLSLD 20 /* 32 bit signed PC relative offset
+ to two GOT entries for LD symbol */
+#define R_X86_64_DTPOFF32 21 /* Offset in TLS block */
+#define R_X86_64_GOTTPOFF 22 /* 32 bit signed PC relative offset
+ to GOT entry for IE symbol */
+#define R_X86_64_TPOFF32 23 /* Offset in initial TLS block */
+#define R_X86_64_PC64 24 /* PC relative 64 bit */
+#define R_X86_64_GOTOFF64 25 /* 64 bit offset to GOT */
+#define R_X86_64_GOTPC32 26 /* 32 bit signed pc relative
+ offset to GOT */
+#define R_X86_64_GOT64 27 /* 64-bit GOT entry offset */
+#define R_X86_64_GOTPCREL64 28 /* 64-bit PC relative offset
+ to GOT entry */
+#define R_X86_64_GOTPC64 29 /* 64-bit PC relative offset to GOT */
+#define R_X86_64_GOTPLT64 30 /* like GOT64, says PLT entry needed */
+#define R_X86_64_PLTOFF64 31 /* 64-bit GOT relative offset
+ to PLT entry */
+#define R_X86_64_SIZE32 32 /* Size of symbol plus 32-bit addend */
+#define R_X86_64_SIZE64 33 /* Size of symbol plus 64-bit addend */
+#define R_X86_64_GOTPC32_TLSDESC 34 /* GOT offset for TLS descriptor. */
+#define R_X86_64_TLSDESC_CALL 35 /* Marker for call through TLS
+ descriptor. */
+#define R_X86_64_TLSDESC 36 /* TLS descriptor. */
+#define R_X86_64_IRELATIVE 37 /* Adjust indirectly by program base */
+#define R_X86_64_RELATIVE64 38 /* 64-bit adjust by program base */
+
+#define R_X86_64_NUM 39
+
+
+/* AM33 relocations. */
+#define R_MN10300_NONE 0 /* No reloc. */
+#define R_MN10300_32 1 /* Direct 32 bit. */
+#define R_MN10300_16 2 /* Direct 16 bit. */
+#define R_MN10300_8 3 /* Direct 8 bit. */
+#define R_MN10300_PCREL32 4 /* PC-relative 32-bit. */
+#define R_MN10300_PCREL16 5 /* PC-relative 16-bit signed. */
+#define R_MN10300_PCREL8 6 /* PC-relative 8-bit signed. */
+#define R_MN10300_GNU_VTINHERIT 7 /* Ancient C++ vtable garbage... */
+#define R_MN10300_GNU_VTENTRY 8 /* ... collection annotation. */
+#define R_MN10300_24 9 /* Direct 24 bit. */
+#define R_MN10300_GOTPC32 10 /* 32-bit PCrel offset to GOT. */
+#define R_MN10300_GOTPC16 11 /* 16-bit PCrel offset to GOT. */
+#define R_MN10300_GOTOFF32 12 /* 32-bit offset from GOT. */
+#define R_MN10300_GOTOFF24 13 /* 24-bit offset from GOT. */
+#define R_MN10300_GOTOFF16 14 /* 16-bit offset from GOT. */
+#define R_MN10300_PLT32 15 /* 32-bit PCrel to PLT entry. */
+#define R_MN10300_PLT16 16 /* 16-bit PCrel to PLT entry. */
+#define R_MN10300_GOT32 17 /* 32-bit offset to GOT entry. */
+#define R_MN10300_GOT24 18 /* 24-bit offset to GOT entry. */
+#define R_MN10300_GOT16 19 /* 16-bit offset to GOT entry. */
+#define R_MN10300_COPY 20 /* Copy symbol at runtime. */
+#define R_MN10300_GLOB_DAT 21 /* Create GOT entry. */
+#define R_MN10300_JMP_SLOT 22 /* Create PLT entry. */
+#define R_MN10300_RELATIVE 23 /* Adjust by program base. */
+#define R_MN10300_TLS_GD 24 /* 32-bit offset for global dynamic. */
+#define R_MN10300_TLS_LD 25 /* 32-bit offset for local dynamic. */
+#define R_MN10300_TLS_LDO 26 /* Module-relative offset. */
+#define R_MN10300_TLS_GOTIE 27 /* GOT offset for static TLS block
+ offset. */
+#define R_MN10300_TLS_IE 28 /* GOT address for static TLS block
+ offset. */
+#define R_MN10300_TLS_LE 29 /* Offset relative to static TLS
+ block. */
+#define R_MN10300_TLS_DTPMOD 30 /* ID of module containing symbol. */
+#define R_MN10300_TLS_DTPOFF 31 /* Offset in module TLS block. */
+#define R_MN10300_TLS_TPOFF 32 /* Offset in static TLS block. */
+#define R_MN10300_SYM_DIFF 33 /* Adjustment for next reloc as needed
+ by linker relaxation. */
+#define R_MN10300_ALIGN 34 /* Alignment requirement for linker
+ relaxation. */
+#define R_MN10300_NUM 35
+
+
+/* M32R relocs. */
+#define R_M32R_NONE 0 /* No reloc. */
+#define R_M32R_16 1 /* Direct 16 bit. */
+#define R_M32R_32 2 /* Direct 32 bit. */
+#define R_M32R_24 3 /* Direct 24 bit. */
+#define R_M32R_10_PCREL 4 /* PC relative 10 bit shifted. */
+#define R_M32R_18_PCREL 5 /* PC relative 18 bit shifted. */
+#define R_M32R_26_PCREL 6 /* PC relative 26 bit shifted. */
+#define R_M32R_HI16_ULO 7 /* High 16 bit with unsigned low. */
+#define R_M32R_HI16_SLO 8 /* High 16 bit with signed low. */
+#define R_M32R_LO16 9 /* Low 16 bit. */
+#define R_M32R_SDA16 10 /* 16 bit offset in SDA. */
+#define R_M32R_GNU_VTINHERIT 11
+#define R_M32R_GNU_VTENTRY 12
+/* M32R relocs use SHT_RELA. */
+#define R_M32R_16_RELA 33 /* Direct 16 bit. */
+#define R_M32R_32_RELA 34 /* Direct 32 bit. */
+#define R_M32R_24_RELA 35 /* Direct 24 bit. */
+#define R_M32R_10_PCREL_RELA 36 /* PC relative 10 bit shifted. */
+#define R_M32R_18_PCREL_RELA 37 /* PC relative 18 bit shifted. */
+#define R_M32R_26_PCREL_RELA 38 /* PC relative 26 bit shifted. */
+#define R_M32R_HI16_ULO_RELA 39 /* High 16 bit with unsigned low */
+#define R_M32R_HI16_SLO_RELA 40 /* High 16 bit with signed low */
+#define R_M32R_LO16_RELA 41 /* Low 16 bit */
+#define R_M32R_SDA16_RELA 42 /* 16 bit offset in SDA */
+#define R_M32R_RELA_GNU_VTINHERIT 43
+#define R_M32R_RELA_GNU_VTENTRY 44
+#define R_M32R_REL32 45 /* PC relative 32 bit. */
+
+#define R_M32R_GOT24 48 /* 24 bit GOT entry */
+#define R_M32R_26_PLTREL 49 /* 26 bit PC relative to PLT shifted */
+#define R_M32R_COPY 50 /* Copy symbol at runtime */
+#define R_M32R_GLOB_DAT 51 /* Create GOT entry */
+#define R_M32R_JMP_SLOT 52 /* Create PLT entry */
+#define R_M32R_RELATIVE 53 /* Adjust by program base */
+#define R_M32R_GOTOFF 54 /* 24 bit offset to GOT */
+#define R_M32R_GOTPC24 55 /* 24 bit PC relative offset to GOT */
+#define R_M32R_GOT16_HI_ULO 56 /* High 16 bit GOT entry with unsigned
+ low */
+#define R_M32R_GOT16_HI_SLO 57 /* High 16 bit GOT entry with signed
+ low */
+#define R_M32R_GOT16_LO 58 /* Low 16 bit GOT entry */
+#define R_M32R_GOTPC_HI_ULO 59 /* High 16 bit PC relative offset to
+ GOT with unsigned low */
+#define R_M32R_GOTPC_HI_SLO 60 /* High 16 bit PC relative offset to
+ GOT with signed low */
+#define R_M32R_GOTPC_LO 61 /* Low 16 bit PC relative offset to
+ GOT */
+#define R_M32R_GOTOFF_HI_ULO 62 /* High 16 bit offset to GOT
+ with unsigned low */
+#define R_M32R_GOTOFF_HI_SLO 63 /* High 16 bit offset to GOT
+ with signed low */
+#define R_M32R_GOTOFF_LO 64 /* Low 16 bit offset to GOT */
+#define R_M32R_NUM 256 /* Keep this the last entry. */
+
+/* MicroBlaze relocations */
+#define R_MICROBLAZE_NONE 0 /* No reloc. */
+#define R_MICROBLAZE_32 1 /* Direct 32 bit. */
+#define R_MICROBLAZE_32_PCREL 2 /* PC relative 32 bit. */
+#define R_MICROBLAZE_64_PCREL 3 /* PC relative 64 bit. */
+#define R_MICROBLAZE_32_PCREL_LO 4 /* Low 16 bits of PCREL32. */
+#define R_MICROBLAZE_64 5 /* Direct 64 bit. */
+#define R_MICROBLAZE_32_LO 6 /* Low 16 bit. */
+#define R_MICROBLAZE_SRO32 7 /* Read-only small data area. */
+#define R_MICROBLAZE_SRW32 8 /* Read-write small data area. */
+#define R_MICROBLAZE_64_NONE 9 /* No reloc. */
+#define R_MICROBLAZE_32_SYM_OP_SYM 10 /* Symbol Op Symbol relocation. */
+#define R_MICROBLAZE_GNU_VTINHERIT 11 /* GNU C++ vtable hierarchy. */
+#define R_MICROBLAZE_GNU_VTENTRY 12 /* GNU C++ vtable member usage. */
+#define R_MICROBLAZE_GOTPC_64 13 /* PC-relative GOT offset. */
+#define R_MICROBLAZE_GOT_64 14 /* GOT entry offset. */
+#define R_MICROBLAZE_PLT_64 15 /* PLT offset (PC-relative). */
+#define R_MICROBLAZE_REL 16 /* Adjust by program base. */
+#define R_MICROBLAZE_JUMP_SLOT 17 /* Create PLT entry. */
+#define R_MICROBLAZE_GLOB_DAT 18 /* Create GOT entry. */
+#define R_MICROBLAZE_GOTOFF_64 19 /* 64 bit offset to GOT. */
+#define R_MICROBLAZE_GOTOFF_32 20 /* 32 bit offset to GOT. */
+#define R_MICROBLAZE_COPY 21 /* Runtime copy. */
+#define R_MICROBLAZE_TLS 22 /* TLS Reloc. */
+#define R_MICROBLAZE_TLSGD 23 /* TLS General Dynamic. */
+#define R_MICROBLAZE_TLSLD 24 /* TLS Local Dynamic. */
+#define R_MICROBLAZE_TLSDTPMOD32 25 /* TLS Module ID. */
+#define R_MICROBLAZE_TLSDTPREL32 26 /* TLS Offset Within TLS Block. */
+#define R_MICROBLAZE_TLSDTPREL64 27 /* TLS Offset Within TLS Block. */
+#define R_MICROBLAZE_TLSGOTTPREL32 28 /* TLS Offset From Thread Pointer. */
+#define R_MICROBLAZE_TLSTPREL32 29 /* TLS Offset From Thread Pointer. */
+
+/* TILEPro relocations. */
+#define R_TILEPRO_NONE 0 /* No reloc */
+#define R_TILEPRO_32 1 /* Direct 32 bit */
+#define R_TILEPRO_16 2 /* Direct 16 bit */
+#define R_TILEPRO_8 3 /* Direct 8 bit */
+#define R_TILEPRO_32_PCREL 4 /* PC relative 32 bit */
+#define R_TILEPRO_16_PCREL 5 /* PC relative 16 bit */
+#define R_TILEPRO_8_PCREL 6 /* PC relative 8 bit */
+#define R_TILEPRO_LO16 7 /* Low 16 bit */
+#define R_TILEPRO_HI16 8 /* High 16 bit */
+#define R_TILEPRO_HA16 9 /* High 16 bit, adjusted */
+#define R_TILEPRO_COPY 10 /* Copy relocation */
+#define R_TILEPRO_GLOB_DAT 11 /* Create GOT entry */
+#define R_TILEPRO_JMP_SLOT 12 /* Create PLT entry */
+#define R_TILEPRO_RELATIVE 13 /* Adjust by program base */
+#define R_TILEPRO_BROFF_X1 14 /* X1 pipe branch offset */
+#define R_TILEPRO_JOFFLONG_X1 15 /* X1 pipe jump offset */
+#define R_TILEPRO_JOFFLONG_X1_PLT 16 /* X1 pipe jump offset to PLT */
+#define R_TILEPRO_IMM8_X0 17 /* X0 pipe 8-bit */
+#define R_TILEPRO_IMM8_Y0 18 /* Y0 pipe 8-bit */
+#define R_TILEPRO_IMM8_X1 19 /* X1 pipe 8-bit */
+#define R_TILEPRO_IMM8_Y1 20 /* Y1 pipe 8-bit */
+#define R_TILEPRO_MT_IMM15_X1 21 /* X1 pipe mtspr */
+#define R_TILEPRO_MF_IMM15_X1 22 /* X1 pipe mfspr */
+#define R_TILEPRO_IMM16_X0 23 /* X0 pipe 16-bit */
+#define R_TILEPRO_IMM16_X1 24 /* X1 pipe 16-bit */
+#define R_TILEPRO_IMM16_X0_LO 25 /* X0 pipe low 16-bit */
+#define R_TILEPRO_IMM16_X1_LO 26 /* X1 pipe low 16-bit */
+#define R_TILEPRO_IMM16_X0_HI 27 /* X0 pipe high 16-bit */
+#define R_TILEPRO_IMM16_X1_HI 28 /* X1 pipe high 16-bit */
+#define R_TILEPRO_IMM16_X0_HA 29 /* X0 pipe high 16-bit, adjusted */
+#define R_TILEPRO_IMM16_X1_HA 30 /* X1 pipe high 16-bit, adjusted */
+#define R_TILEPRO_IMM16_X0_PCREL 31 /* X0 pipe PC relative 16 bit */
+#define R_TILEPRO_IMM16_X1_PCREL 32 /* X1 pipe PC relative 16 bit */
+#define R_TILEPRO_IMM16_X0_LO_PCREL 33 /* X0 pipe PC relative low 16 bit */
+#define R_TILEPRO_IMM16_X1_LO_PCREL 34 /* X1 pipe PC relative low 16 bit */
+#define R_TILEPRO_IMM16_X0_HI_PCREL 35 /* X0 pipe PC relative high 16 bit */
+#define R_TILEPRO_IMM16_X1_HI_PCREL 36 /* X1 pipe PC relative high 16 bit */
+#define R_TILEPRO_IMM16_X0_HA_PCREL 37 /* X0 pipe PC relative ha() 16 bit */
+#define R_TILEPRO_IMM16_X1_HA_PCREL 38 /* X1 pipe PC relative ha() 16 bit */
+#define R_TILEPRO_IMM16_X0_GOT 39 /* X0 pipe 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT 40 /* X1 pipe 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_LO 41 /* X0 pipe low 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_LO 42 /* X1 pipe low 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_HI 43 /* X0 pipe high 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_HI 44 /* X1 pipe high 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X0_GOT_HA 45 /* X0 pipe ha() 16-bit GOT offset */
+#define R_TILEPRO_IMM16_X1_GOT_HA 46 /* X1 pipe ha() 16-bit GOT offset */
+#define R_TILEPRO_MMSTART_X0 47 /* X0 pipe mm "start" */
+#define R_TILEPRO_MMEND_X0 48 /* X0 pipe mm "end" */
+#define R_TILEPRO_MMSTART_X1 49 /* X1 pipe mm "start" */
+#define R_TILEPRO_MMEND_X1 50 /* X1 pipe mm "end" */
+#define R_TILEPRO_SHAMT_X0 51 /* X0 pipe shift amount */
+#define R_TILEPRO_SHAMT_X1 52 /* X1 pipe shift amount */
+#define R_TILEPRO_SHAMT_Y0 53 /* Y0 pipe shift amount */
+#define R_TILEPRO_SHAMT_Y1 54 /* Y1 pipe shift amount */
+#define R_TILEPRO_DEST_IMM8_X1 55 /* X1 pipe destination 8-bit */
+/* Relocs 56-59 are currently not defined. */
+#define R_TILEPRO_TLS_GD_CALL 60 /* "jal" for TLS GD */
+#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61 /* X0 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62 /* X1 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63 /* Y0 pipe "addi" for TLS GD */
+#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64 /* Y1 pipe "addi" for TLS GD */
+#define R_TILEPRO_TLS_IE_LOAD 65 /* "lw_tls" for TLS IE */
+#define R_TILEPRO_IMM16_X0_TLS_GD 66 /* X0 pipe 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD 67 /* X1 pipe 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68 /* X0 pipe low 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69 /* X1 pipe low 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70 /* X0 pipe high 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71 /* X1 pipe high 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72 /* X0 pipe ha() 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73 /* X1 pipe ha() 16-bit TLS GD offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE 74 /* X0 pipe 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE 75 /* X1 pipe 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76 /* X0 pipe low 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77 /* X1 pipe low 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78 /* X0 pipe high 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79 /* X1 pipe high 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80 /* X0 pipe ha() 16-bit TLS IE offset */
+#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81 /* X1 pipe ha() 16-bit TLS IE offset */
+#define R_TILEPRO_TLS_DTPMOD32 82 /* ID of module containing symbol */
+#define R_TILEPRO_TLS_DTPOFF32 83 /* Offset in TLS block */
+#define R_TILEPRO_TLS_TPOFF32 84 /* Offset in static TLS block */
+#define R_TILEPRO_IMM16_X0_TLS_LE 85 /* X0 pipe 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE 86 /* X1 pipe 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87 /* X0 pipe low 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88 /* X1 pipe low 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89 /* X0 pipe high 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90 /* X1 pipe high 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91 /* X0 pipe ha() 16-bit TLS LE offset */
+#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92 /* X1 pipe ha() 16-bit TLS LE offset */
+
+#define R_TILEPRO_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */
+#define R_TILEPRO_GNU_VTENTRY 129 /* GNU C++ vtable member usage */
+
+#define R_TILEPRO_NUM 130
+
+
+/* TILE-Gx relocations. */
+#define R_TILEGX_NONE 0 /* No reloc */
+#define R_TILEGX_64 1 /* Direct 64 bit */
+#define R_TILEGX_32 2 /* Direct 32 bit */
+#define R_TILEGX_16 3 /* Direct 16 bit */
+#define R_TILEGX_8 4 /* Direct 8 bit */
+#define R_TILEGX_64_PCREL 5 /* PC relative 64 bit */
+#define R_TILEGX_32_PCREL 6 /* PC relative 32 bit */
+#define R_TILEGX_16_PCREL 7 /* PC relative 16 bit */
+#define R_TILEGX_8_PCREL 8 /* PC relative 8 bit */
+#define R_TILEGX_HW0 9 /* hword 0 16-bit */
+#define R_TILEGX_HW1 10 /* hword 1 16-bit */
+#define R_TILEGX_HW2 11 /* hword 2 16-bit */
+#define R_TILEGX_HW3 12 /* hword 3 16-bit */
+#define R_TILEGX_HW0_LAST 13 /* last hword 0 16-bit */
+#define R_TILEGX_HW1_LAST 14 /* last hword 1 16-bit */
+#define R_TILEGX_HW2_LAST 15 /* last hword 2 16-bit */
+#define R_TILEGX_COPY 16 /* Copy relocation */
+#define R_TILEGX_GLOB_DAT 17 /* Create GOT entry */
+#define R_TILEGX_JMP_SLOT 18 /* Create PLT entry */
+#define R_TILEGX_RELATIVE 19 /* Adjust by program base */
+#define R_TILEGX_BROFF_X1 20 /* X1 pipe branch offset */
+#define R_TILEGX_JUMPOFF_X1 21 /* X1 pipe jump offset */
+#define R_TILEGX_JUMPOFF_X1_PLT 22 /* X1 pipe jump offset to PLT */
+#define R_TILEGX_IMM8_X0 23 /* X0 pipe 8-bit */
+#define R_TILEGX_IMM8_Y0 24 /* Y0 pipe 8-bit */
+#define R_TILEGX_IMM8_X1 25 /* X1 pipe 8-bit */
+#define R_TILEGX_IMM8_Y1 26 /* Y1 pipe 8-bit */
+#define R_TILEGX_DEST_IMM8_X1 27 /* X1 pipe destination 8-bit */
+#define R_TILEGX_MT_IMM14_X1 28 /* X1 pipe mtspr */
+#define R_TILEGX_MF_IMM14_X1 29 /* X1 pipe mfspr */
+#define R_TILEGX_MMSTART_X0 30 /* X0 pipe mm "start" */
+#define R_TILEGX_MMEND_X0 31 /* X0 pipe mm "end" */
+#define R_TILEGX_SHAMT_X0 32 /* X0 pipe shift amount */
+#define R_TILEGX_SHAMT_X1 33 /* X1 pipe shift amount */
+#define R_TILEGX_SHAMT_Y0 34 /* Y0 pipe shift amount */
+#define R_TILEGX_SHAMT_Y1 35 /* Y1 pipe shift amount */
+#define R_TILEGX_IMM16_X0_HW0 36 /* X0 pipe hword 0 */
+#define R_TILEGX_IMM16_X1_HW0 37 /* X1 pipe hword 0 */
+#define R_TILEGX_IMM16_X0_HW1 38 /* X0 pipe hword 1 */
+#define R_TILEGX_IMM16_X1_HW1 39 /* X1 pipe hword 1 */
+#define R_TILEGX_IMM16_X0_HW2 40 /* X0 pipe hword 2 */
+#define R_TILEGX_IMM16_X1_HW2 41 /* X1 pipe hword 2 */
+#define R_TILEGX_IMM16_X0_HW3 42 /* X0 pipe hword 3 */
+#define R_TILEGX_IMM16_X1_HW3 43 /* X1 pipe hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_LAST 44 /* X0 pipe last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST 45 /* X1 pipe last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST 46 /* X0 pipe last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST 47 /* X1 pipe last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST 48 /* X0 pipe last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST 49 /* X1 pipe last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_PCREL 50 /* X0 pipe PC relative hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_PCREL 51 /* X1 pipe PC relative hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_PCREL 52 /* X0 pipe PC relative hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_PCREL 53 /* X1 pipe PC relative hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_PCREL 54 /* X0 pipe PC relative hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_PCREL 55 /* X1 pipe PC relative hword 2 */
+#define R_TILEGX_IMM16_X0_HW3_PCREL 56 /* X0 pipe PC relative hword 3 */
+#define R_TILEGX_IMM16_X1_HW3_PCREL 57 /* X1 pipe PC relative hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_GOT 64 /* X0 pipe hword 0 GOT offset */
+#define R_TILEGX_IMM16_X1_HW0_GOT 65 /* X1 pipe hword 0 GOT offset */
+#define R_TILEGX_IMM16_X0_HW0_PLT_PCREL 66 /* X0 pipe PC-rel PLT hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_PLT_PCREL 67 /* X1 pipe PC-rel PLT hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_PLT_PCREL 68 /* X0 pipe PC-rel PLT hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_PLT_PCREL 69 /* X1 pipe PC-rel PLT hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_PLT_PCREL 70 /* X0 pipe PC-rel PLT hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_PLT_PCREL 71 /* X1 pipe PC-rel PLT hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */
+#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */
+#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */
+#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */
+#define R_TILEGX_IMM16_X0_HW3_PLT_PCREL 76 /* X0 pipe PC-rel PLT hword 3 */
+#define R_TILEGX_IMM16_X1_HW3_PLT_PCREL 77 /* X1 pipe PC-rel PLT hword 3 */
+#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78 /* X0 pipe hword 0 TLS GD offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79 /* X1 pipe hword 0 TLS GD offset */
+#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80 /* X0 pipe hword 0 TLS LE offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81 /* X1 pipe hword 0 TLS LE offset */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */
+/* Relocs 90-91 are currently not defined. */
+#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92 /* X0 pipe hword 0 TLS IE offset */
+#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93 /* X1 pipe hword 0 TLS IE offset */
+#define R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL 94 /* X0 pipe PC-rel PLT last hword 0 */
+#define R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL 95 /* X1 pipe PC-rel PLT last hword 0 */
+#define R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL 96 /* X0 pipe PC-rel PLT last hword 1 */
+#define R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL 97 /* X1 pipe PC-rel PLT last hword 1 */
+#define R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL 98 /* X0 pipe PC-rel PLT last hword 2 */
+#define R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL 99 /* X1 pipe PC-rel PLT last hword 2 */
+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */
+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */
+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */
+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */
+/* Relocs 104-105 are currently not defined. */
+#define R_TILEGX_TLS_DTPMOD64 106 /* 64-bit ID of symbol's module */
+#define R_TILEGX_TLS_DTPOFF64 107 /* 64-bit offset in TLS block */
+#define R_TILEGX_TLS_TPOFF64 108 /* 64-bit offset in static TLS block */
+#define R_TILEGX_TLS_DTPMOD32 109 /* 32-bit ID of symbol's module */
+#define R_TILEGX_TLS_DTPOFF32 110 /* 32-bit offset in TLS block */
+#define R_TILEGX_TLS_TPOFF32 111 /* 32-bit offset in static TLS block */
+#define R_TILEGX_TLS_GD_CALL 112 /* "jal" for TLS GD */
+#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113 /* X0 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114 /* X1 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115 /* Y0 pipe "addi" for TLS GD */
+#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116 /* Y1 pipe "addi" for TLS GD */
+#define R_TILEGX_TLS_IE_LOAD 117 /* "ld_tls" for TLS IE */
+#define R_TILEGX_IMM8_X0_TLS_ADD 118 /* X0 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_X1_TLS_ADD 119 /* X1 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_Y0_TLS_ADD 120 /* Y0 pipe "addi" for TLS GD/IE */
+#define R_TILEGX_IMM8_Y1_TLS_ADD 121 /* Y1 pipe "addi" for TLS GD/IE */
+
+#define R_TILEGX_GNU_VTINHERIT 128 /* GNU C++ vtable hierarchy */
+#define R_TILEGX_GNU_VTENTRY 129 /* GNU C++ vtable member usage */
+
+#define R_TILEGX_NUM 130
+
+/* OR1K relocations */
+#define R_OR1K_NONE 0
+#define R_OR1K_32 1
+#define R_OR1K_16 2
+#define R_OR1K_8 3
+#define R_OR1K_LO_16_IN_INSN 4
+#define R_OR1K_HI_16_IN_INSN 5
+#define R_OR1K_INSN_REL_26 6
+#define R_OR1K_GNU_VTENTRY 7
+#define R_OR1K_GNU_VTINHERIT 8
+#define R_OR1K_32_PCREL 9
+#define R_OR1K_16_PCREL 10
+#define R_OR1K_8_PCREL 11
+#define R_OR1K_GOTPC_HI16 12
+#define R_OR1K_GOTPC_LO16 13
+#define R_OR1K_GOT16 14
+#define R_OR1K_PLT26 15
+#define R_OR1K_GOTOFF_HI16 16
+#define R_OR1K_GOTOFF_LO16 17
+#define R_OR1K_COPY 18
+#define R_OR1K_GLOB_DAT 19
+#define R_OR1K_JMP_SLOT 20
+#define R_OR1K_RELATIVE 21
+#define R_OR1K_TLS_GD_HI16 22
+#define R_OR1K_TLS_GD_LO16 23
+#define R_OR1K_TLS_LDM_HI16 24
+#define R_OR1K_TLS_LDM_LO16 25
+#define R_OR1K_TLS_LDO_HI16 26
+#define R_OR1K_TLS_LDO_LO16 27
+#define R_OR1K_TLS_IE_HI16 28
+#define R_OR1K_TLS_IE_LO16 29
+#define R_OR1K_TLS_LE_HI16 30
+#define R_OR1K_TLS_LE_LO16 31
+#define R_OR1K_TLS_TPOFF 32
+#define R_OR1K_TLS_DTPOFF 33
+#define R_OR1K_TLS_DTPMOD 34
+
+#define R_OR1K_NUM 35
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* elf.h */
--- /dev/null
+#ifndef __LINK_H
+#define __LINK_H
+
+#include <stddef.h>
+#include <elf.h>
+
+#define ElfW(type) Elf32_##type
+
+struct dl_phdr_info {
+ ElfW(Addr) dlpi_addr;
+ const char *dlpi_name;
+ const ElfW(Phdr) *dlpi_phdr;
+ ElfW(Half) dlpi_phnum;
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int dl_iterate_phdr (int (*__callback) (struct dl_phdr_info *,
+ size_t, void *),
+ void *__data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __LINK_H */
--- /dev/null
+#ifndef __HW_COMMON_H
+#define __HW_COMMON_H
+
+#ifdef __ASSEMBLER__
+#define MMPTR(x) x
+#else
+#define MMPTR(x) (*((volatile unsigned int *)(x)))
+#endif
+
+#endif
--- /dev/null
+#ifndef __HW_ETHMAC_MEM_H
+#define __HW_ETHMAC_MEM_H
+
+#include <generated/mem.h>
+
+#define ETHMAC_RX0_BASE ETHMAC_BASE
+#define ETHMAC_RX1_BASE (ETHMAC_BASE+0x0800)
+#define ETHMAC_TX0_BASE (ETHMAC_BASE+0x1000)
+#define ETHMAC_TX1_BASE (ETHMAC_BASE+0x1800)
+
+#endif
--- /dev/null
+#ifndef __HW_FLAGS_H
+#define __HW_FLAGS_H
+
+#define UART_EV_TX 0x1
+#define UART_EV_RX 0x2
+
+#define DFII_CONTROL_SEL 0x01
+#define DFII_CONTROL_CKE 0x02
+#define DFII_CONTROL_ODT 0x04
+#define DFII_CONTROL_RESET_N 0x08
+
+#define DFII_COMMAND_CS 0x01
+#define DFII_COMMAND_WE 0x02
+#define DFII_COMMAND_CAS 0x04
+#define DFII_COMMAND_RAS 0x08
+#define DFII_COMMAND_WRDATA 0x10
+#define DFII_COMMAND_RDDATA 0x20
+
+#define ETHMAC_EV_SRAM_WRITER 0x1
+#define ETHMAC_EV_SRAM_READER 0x1
+
+#define CLKGEN_STATUS_BUSY 0x1
+#define CLKGEN_STATUS_PROGDONE 0x2
+#define CLKGEN_STATUS_LOCKED 0x4
+
+#define DVISAMPLER_TOO_LATE 0x1
+#define DVISAMPLER_TOO_EARLY 0x2
+
+#define DVISAMPLER_DELAY_MASTER_CAL 0x01
+#define DVISAMPLER_DELAY_MASTER_RST 0x02
+#define DVISAMPLER_DELAY_SLAVE_CAL 0x04
+#define DVISAMPLER_DELAY_SLAVE_RST 0x08
+#define DVISAMPLER_DELAY_INC 0x10
+#define DVISAMPLER_DELAY_DEC 0x20
+
+#define DVISAMPLER_SLOT_EMPTY 0
+#define DVISAMPLER_SLOT_LOADED 1
+#define DVISAMPLER_SLOT_PENDING 2
+
+#endif /* __HW_FLAGS_H */
--- /dev/null
+#ifndef __MICROUDP_H
+#define __MICROUDP_H
+
+#define IPTOINT(a, b, c, d) ((a << 24)|(b << 16)|(c << 8)|d)
+
+#define MICROUDP_BUFSIZE (5*1532)
+
+typedef void (*udp_callback)(unsigned int src_ip, unsigned short src_port, unsigned short dst_port, void *data, unsigned int length);
+
+void microudp_start(const unsigned char *macaddr, unsigned int ip);
+int microudp_arp_resolve(unsigned int ip);
+void *microudp_get_tx_buffer(void);
+int microudp_send(unsigned short src_port, unsigned short dst_port, unsigned int length);
+void microudp_set_callback(udp_callback callback);
+void microudp_service(void);
+
+void eth_init(void);
+void eth_mode(void);
+
+#endif /* __MICROUDP_H */
--- /dev/null
+#ifndef __TFTP_H
+#define __TFTP_H
+
+#include <stdint.h>
+
+int tftp_get(uint32_t ip, const char *filename, void *buffer);
+int tftp_put(uint32_t ip, const char *filename, const void *buffer, int size);
+
+#endif /* __TFTP_H */
+
--- /dev/null
+include ../include/generated/variables.mak
+include $(SOC_DIRECTORY)/software/common.mak
+
+OBJECTS=exception.o libc.o errno.o crc16.o crc32.o console.o system.o id.o uart.o time.o qsort.o strtod.o spiflash.o
+
+all: crt0-$(CPU).o libbase.a libbase-nofloat.a
+
+libbase.a: $(OBJECTS) vsnprintf.o
+ $(AR) crs libbase.a $(OBJECTS) vsnprintf.o
+
+libbase-nofloat.a: $(OBJECTS) vsnprintf-nofloat.o
+ $(AR) crs libbase-nofloat.a $(OBJECTS) vsnprintf-nofloat.o
+
+vsnprintf-nofloat.o: $(LIBBASE_DIRECTORY)/vsnprintf.c
+ $(call compile,-DNO_FLOAT)
+
+%.o: $(LIBBASE_DIRECTORY)/%.c
+ $(compile)
+
+%.o: $(LIBBASE_DIRECTORY)/%.S
+ $(assemble)
+
+.PHONY: all clean
+
+clean:
+ $(RM) $(OBJECTS) crt0-$(CPU).o vsnprintf.o vsnprintf-nofloat.o
+ $(RM) libbase.a libbase-nofloat.a .*~ *~
--- /dev/null
+#include <uart.h>
+#include <console.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+FILE *stdin, *stdout, *stderr;
+
+static console_write_hook write_hook;
+static console_read_hook read_hook;
+static console_read_nonblock_hook read_nonblock_hook;
+
+void console_set_write_hook(console_write_hook h)
+{
+ write_hook = h;
+}
+
+void console_set_read_hook(console_read_hook r, console_read_nonblock_hook rn)
+{
+ read_hook = r;
+ read_nonblock_hook = rn;
+}
+
+int putchar(int c)
+{
+ uart_write(c);
+ if(write_hook != NULL)
+ write_hook(c);
+ return c;
+}
+
+char readchar(void)
+{
+ while(1) {
+ if(uart_read_nonblock())
+ return uart_read();
+ if((read_nonblock_hook != NULL) && read_nonblock_hook())
+ return read_hook();
+ }
+}
+
+int readchar_nonblock(void)
+{
+ return (uart_read_nonblock()
+ || ((read_nonblock_hook != NULL) && read_nonblock_hook()));
+}
+
+int puts(const char *s)
+{
+ while(*s) {
+ putchar(*s);
+ s++;
+ }
+ putchar('\n');
+ return 1;
+}
+
+void putsnonl(const char *s)
+{
+ while(*s) {
+ putchar(*s);
+ s++;
+ }
+}
+
+#define PRINTF_BUFFER_SIZE 256
+
+int printf(const char *fmt, ...)
+{
+ va_list args;
+ int len;
+ char outbuf[PRINTF_BUFFER_SIZE];
+
+ va_start(args, fmt);
+ len = vscnprintf(outbuf, sizeof(outbuf), fmt, args);
+ va_end(args);
+ outbuf[len] = 0;
+ putsnonl(outbuf);
+
+ return len;
+}
--- /dev/null
+#include <crc.h>
+
+static const unsigned int crc16_table[256] = {
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+ 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
+ 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
+ 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
+ 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
+ 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
+ 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
+ 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
+ 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
+ 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
+ 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
+ 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
+ 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
+ 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
+ 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
+ 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
+ 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
+ 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+ 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
+ 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
+ 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
+ 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
+ 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
+ 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
+ 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
+ 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
+ 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
+};
+
+unsigned short crc16(const unsigned char *buffer, int len)
+{
+ unsigned short crc;
+
+ crc = 0;
+ while(len-- > 0)
+ crc = crc16_table[((crc >> 8) ^ (*buffer++)) & 0xFF] ^ (crc << 8);
+
+ return crc;
+}
--- /dev/null
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include <crc.h>
+
+static const unsigned int crc_table[256] = {
+ 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+ 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+ 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+ 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+ 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+ 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+ 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+ 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+ 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+ 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+ 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+ 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+ 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+ 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+ 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+ 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+ 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+ 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+ 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+ 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+ 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+ 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+ 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+ 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+ 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+ 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+ 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+ 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+ 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+ 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+ 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+ 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+ 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+ 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+ 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+ 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+ 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+ 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+ 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+ 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+ 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+ 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+ 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+ 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+ 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+ 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+ 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+ 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+ 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+ 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+ 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+ 0x2d02ef8dL
+};
+
+#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
+#define DO2(buf) DO1(buf); DO1(buf);
+#define DO4(buf) DO2(buf); DO2(buf);
+#define DO8(buf) DO4(buf); DO4(buf);
+
+unsigned int crc32(const unsigned char *buffer, unsigned int len)
+{
+ unsigned int crc;
+ crc = 0;
+ crc = crc ^ 0xffffffffL;
+ while(len >= 8) {
+ DO8(buffer);
+ len -= 8;
+ }
+ if(len) do {
+ DO1(buffer);
+ } while(--len);
+ return crc ^ 0xffffffffL;
+}
--- /dev/null
+/*
+ * LatticeMico32 C startup code.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Exception handlers - Must be 32 bytes long. */
+.section .text, "ax", @progbits
+.global _start
+_start:
+_reset_handler:
+ xor r0, r0, r0
+ wcsr IE, r0
+ mvhi r1, hi(_reset_handler)
+ ori r1, r1, lo(_reset_handler)
+ wcsr EBA, r1
+ bi _crt0
+ nop
+ nop
+
+_breakpoint_handler:
+ bi _breakpoint_handler
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+_instruction_bus_error_handler:
+ bi _instruction_bus_error_handler
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+_watchpoint_hander:
+ bi _watchpoint_hander
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+_data_bus_error_handler:
+ bi _data_bus_error_handler
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+_divide_by_zero_handler:
+ bi _divide_by_zero_handler
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+_interrupt_handler:
+ sw (sp+0), ra
+ calli .save_all
+ calli isr
+ bi .restore_all_and_eret
+ nop
+ nop
+ nop
+ nop
+
+_syscall_handler:
+ bi _syscall_handler
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+_crt0:
+ /* Setup stack and global pointer */
+ mvhi sp, hi(_fstack)
+ ori sp, sp, lo(_fstack)
+
+ /* Clear BSS */
+ mvhi r1, hi(_fbss)
+ ori r1, r1, lo(_fbss)
+ mvhi r3, hi(_ebss)
+ ori r3, r3, lo(_ebss)
+.clearBSS:
+ be r1, r3, .callMain
+ sw (r1+0), r0
+ addi r1, r1, 4
+ bi .clearBSS
+
+.callMain:
+ bi main
+
+.save_all:
+ addi sp, sp, -56
+ sw (sp+4), r1
+ sw (sp+8), r2
+ sw (sp+12), r3
+ sw (sp+16), r4
+ sw (sp+20), r5
+ sw (sp+24), r6
+ sw (sp+28), r7
+ sw (sp+32), r8
+ sw (sp+36), r9
+ sw (sp+40), r10
+ sw (sp+48), ea
+ sw (sp+52), ba
+ /* ra needs to be moved from initial stack location */
+ lw r1, (sp+56)
+ sw (sp+44), r1
+ ret
+
+.restore_all_and_eret:
+ lw r1, (sp+4)
+ lw r2, (sp+8)
+ lw r3, (sp+12)
+ lw r4, (sp+16)
+ lw r5, (sp+20)
+ lw r6, (sp+24)
+ lw r7, (sp+28)
+ lw r8, (sp+32)
+ lw r9, (sp+36)
+ lw r10, (sp+40)
+ lw ra, (sp+44)
+ lw ea, (sp+48)
+ lw ba, (sp+52)
+ addi sp, sp, 56
+ eret
--- /dev/null
+/*
+ * (C) Copyright 2012, Stefan Kristiansson <stefan.kristiansson@saunalahti.fi>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <spr-defs.h>
+
+#define EXCEPTION_STACK_SIZE (4*32)
+
+#define HANDLE_EXCEPTION ; \
+ l.addi r1, r1, -EXCEPTION_STACK_SIZE ; \
+ l.sw 0x1c(r1), r9 ; \
+ l.jal _exception_handler ; \
+ l.nop ; \
+ l.lwz r9, 0x1c(r1) ; \
+ l.addi r1, r1, EXCEPTION_STACK_SIZE ; \
+ l.rfe ; \
+ l.nop
+
+
+.section .text, "ax", @progbits
+.global _start
+_start:
+_reset_handler:
+ l.movhi r0, 0
+ l.movhi r1, 0
+ l.movhi r2, 0
+ l.movhi r3, 0
+ l.movhi r4, 0
+ l.movhi r5, 0
+ l.movhi r6, 0
+ l.movhi r7, 0
+ l.movhi r8, 0
+ l.movhi r9, 0
+ l.movhi r10, 0
+ l.movhi r11, 0
+ l.movhi r12, 0
+ l.movhi r13, 0
+ l.movhi r14, 0
+ l.movhi r15, 0
+ l.movhi r16, 0
+ l.movhi r17, 0
+ l.movhi r18, 0
+ l.movhi r19, 0
+ l.movhi r20, 0
+ l.movhi r21, 0
+ l.movhi r22, 0
+ l.movhi r23, 0
+ l.movhi r24, 0
+ l.movhi r25, 0
+ l.movhi r26, 0
+ l.movhi r27, 0
+ l.movhi r28, 0
+ l.movhi r29, 0
+ l.movhi r30, 0
+ l.movhi r31, 0
+
+ l.ori r21, r0, SPR_SR_SM
+ l.mtspr r0, r21, SPR_SR
+ l.movhi r21, hi(_reset_handler)
+ l.ori r21, r21, lo(_reset_handler)
+ l.mtspr r0, r21, SPR_EVBAR
+ /* enable caches */
+ l.jal _cache_init
+ l.nop
+ l.j _crt0
+ l.nop
+
+ /* bus error */
+ .org 0x200
+ HANDLE_EXCEPTION
+
+ /* data page fault */
+ .org 0x300
+ HANDLE_EXCEPTION
+
+ /* instruction page fault */
+ .org 0x400
+ HANDLE_EXCEPTION
+
+ /* tick timer */
+ .org 0x500
+ HANDLE_EXCEPTION
+
+ /* alignment */
+ .org 0x600
+ HANDLE_EXCEPTION
+
+ /* illegal instruction */
+ .org 0x700
+ HANDLE_EXCEPTION
+
+ /* external interrupt */
+ .org 0x800
+ HANDLE_EXCEPTION
+
+ /* D-TLB miss */
+ .org 0x900
+ HANDLE_EXCEPTION
+
+ /* I-TLB miss */
+ .org 0xa00
+ HANDLE_EXCEPTION
+
+ /* range */
+ .org 0xb00
+ HANDLE_EXCEPTION
+
+ /* system call */
+ .org 0xc00
+ HANDLE_EXCEPTION
+
+ /* floating point */
+ .org 0xd00
+ HANDLE_EXCEPTION
+
+ /* trap */
+ .org 0xe00
+ HANDLE_EXCEPTION
+
+ /* reserved */
+ .org 0xf00
+ HANDLE_EXCEPTION
+
+ .org 0x1000
+_crt0:
+ /* Setup stack and global pointer */
+ l.movhi r1, hi(_fstack)
+ l.ori r1, r1, lo(_fstack)
+
+ /* Clear BSS */
+ l.movhi r21, hi(_fbss)
+ l.ori r21, r21, lo(_fbss)
+ l.movhi r3, hi(_ebss)
+ l.ori r3, r3, lo(_ebss)
+.clearBSS:
+ l.sfeq r21, r3
+ l.bf .callMain
+ l.nop
+ l.sw 0(r21), r0
+ l.addi r21, r21, 4
+ l.j .clearBSS
+ l.nop
+
+.callMain:
+ l.j main
+ l.nop
+
+_exception_handler:
+ l.sw 0x00(r1), r2
+ l.sw 0x04(r1), r3
+ l.sw 0x08(r1), r4
+ l.sw 0x0c(r1), r5
+ l.sw 0x10(r1), r6
+ l.sw 0x14(r1), r7
+ l.sw 0x18(r1), r8
+ l.sw 0x20(r1), r10
+ l.sw 0x24(r1), r11
+ l.sw 0x28(r1), r12
+ l.sw 0x2c(r1), r13
+ l.sw 0x30(r1), r14
+ l.sw 0x34(r1), r15
+ l.sw 0x38(r1), r16
+ l.sw 0x3c(r1), r17
+ l.sw 0x40(r1), r18
+ l.sw 0x44(r1), r19
+ l.sw 0x48(r1), r20
+ l.sw 0x4c(r1), r21
+ l.sw 0x50(r1), r22
+ l.sw 0x54(r1), r23
+ l.sw 0x58(r1), r24
+ l.sw 0x5c(r1), r25
+ l.sw 0x60(r1), r26
+ l.sw 0x64(r1), r27
+ l.sw 0x68(r1), r28
+ l.sw 0x6c(r1), r29
+ l.sw 0x70(r1), r30
+ l.sw 0x74(r1), r31
+
+ /* Save return address */
+ l.or r14, r0, r9
+ /* Calculate exception vector from handler address */
+ l.andi r3, r9, 0xf00
+ l.srli r3, r3, 8
+ /* Pass saved register state */
+ l.or r4, r0, r1
+ /* Extract exception PC */
+ l.mfspr r5, r0, SPR_EPCR_BASE
+ /* Extract exception effective address */
+ l.mfspr r6, r0, SPR_EEAR_BASE
+ /* Call exception handler with the link address as argument */
+ l.jal exception_handler
+ l.nop
+
+ /* Load return address */
+ l.or r9, r0, r14
+ /* Restore state */
+ l.lwz r2, 0x00(r1)
+ l.lwz r3, 0x04(r1)
+ l.lwz r4, 0x08(r1)
+ l.lwz r5, 0x0c(r1)
+ l.lwz r6, 0x10(r1)
+ l.lwz r7, 0x14(r1)
+ l.lwz r8, 0x18(r1)
+ l.lwz r10, 0x20(r1)
+ l.lwz r11, 0x24(r1)
+ l.lwz r12, 0x28(r1)
+ l.lwz r13, 0x2c(r1)
+ l.lwz r14, 0x30(r1)
+ l.lwz r15, 0x34(r1)
+ l.lwz r16, 0x38(r1)
+ l.lwz r17, 0x3c(r1)
+ l.lwz r18, 0x40(r1)
+ l.lwz r19, 0x44(r1)
+ l.lwz r20, 0x48(r1)
+ l.lwz r21, 0x4c(r1)
+ l.lwz r22, 0x50(r1)
+ l.lwz r23, 0x54(r1)
+ l.lwz r24, 0x58(r1)
+ l.lwz r25, 0x5c(r1)
+ l.lwz r26, 0x60(r1)
+ l.lwz r27, 0x64(r1)
+ l.lwz r28, 0x68(r1)
+ l.lwz r29, 0x6c(r1)
+ l.lwz r30, 0x70(r1)
+ l.lwz r31, 0x74(r1)
+ l.jr r9
+ l.nop
+
+.global _cache_init
+_cache_init:
+ /*
+ This function is to be used ONLY during reset, before main() is called.
+ TODO: Perhaps break into individual enable instruction/data cache
+ sections functions, and provide disable functions, also, all
+ callable from C
+ */
+
+ /* Instruction cache enable */
+ /* Check if IC present and skip enabling otherwise */
+#if 1
+.L6:
+ l.mfspr r3,r0,SPR_UPR
+ l.andi r7,r3,SPR_UPR_ICP
+ l.sfeq r7,r0
+ l.bf .L8
+ l.nop
+
+ /* Disable IC */
+ l.mfspr r6,r0,SPR_SR
+ l.addi r5,r0,-1
+ l.xori r5,r5,SPR_SR_ICE
+ l.and r5,r6,r5
+ l.mtspr r0,r5,SPR_SR
+
+ /* Establish cache block size
+ If BS=0, 16;
+ If BS=1, 32;
+ r14 contain block size
+ */
+ l.mfspr r3,r0,SPR_ICCFGR
+ l.andi r7,r3,SPR_ICCFGR_CBS
+ l.srli r8,r7,7
+ l.ori r4,r0,16
+ l.sll r14,r4,r8
+
+ /* Establish number of cache sets
+ r10 contains number of cache sets
+ r8 contains log(# of cache sets)
+ */
+ l.andi r7,r3,SPR_ICCFGR_NCS
+ l.srli r8,r7,3
+ l.ori r4,r0,1
+ l.sll r10,r4,r8
+
+ /* Invalidate IC */
+ l.addi r6,r0,0
+ l.sll r5,r14,r8
+
+.L7: l.mtspr r0,r6,SPR_ICBIR
+ l.sfne r6,r5
+ l.bf .L7
+ l.add r6,r6,r14
+
+ /* Enable IC */
+ l.mfspr r6,r0,SPR_SR
+ l.ori r6,r6,SPR_SR_ICE
+ l.mtspr r0,r6,SPR_SR
+ l.nop
+ l.nop
+ l.nop
+ l.nop
+ l.nop
+ l.nop
+ l.nop
+ l.nop
+ /* Data cache enable */
+ /* Check if DC present and skip enabling otherwise */
+#endif
+.L8:
+#if 1
+ l.mfspr r3,r0,SPR_UPR
+ l.andi r7,r3,SPR_UPR_DCP
+ l.sfeq r7,r0
+ l.bf .L10
+ l.nop
+ /* Disable DC */
+ l.mfspr r6,r0,SPR_SR
+ l.addi r5,r0,-1
+ l.xori r5,r5,SPR_SR_DCE
+ l.and r5,r6,r5
+ l.mtspr r0,r5,SPR_SR
+ /* Establish cache block size
+ If BS=0, 16;
+ If BS=1, 32;
+ r14 contain block size
+ */
+ l.mfspr r3,r0,SPR_DCCFGR
+ l.andi r7,r3,SPR_DCCFGR_CBS
+ l.srli r8,r7,7
+ l.ori r4,r0,16
+ l.sll r14,r4,r8
+ /* Establish number of cache sets
+ r10 contains number of cache sets
+ r8 contains log(# of cache sets)
+ */
+ l.andi r7,r3,SPR_DCCFGR_NCS
+ l.srli r8,r7,3
+ l.ori r4,r0,1
+ l.sll r10,r4,r8
+ /* Invalidate DC */
+ l.addi r6,r0,0
+ l.sll r5,r14,r8
+
+.L9:
+ l.mtspr r0,r6,SPR_DCBIR
+ l.sfne r6,r5
+ l.bf .L9
+ l.add r6,r6,r14
+ /* Enable DC */
+ l.mfspr r6,r0,SPR_SR
+ l.ori r6,r6,SPR_SR_DCE
+ l.mtspr r0,r6,SPR_SR
+#endif
+.L10:
+ /* Return */
+ l.jr r9
+ l.nop
--- /dev/null
+#include <string.h>
+#include <errno.h>
+
+int errno;
+
+/************************************************************************
+ * Based on: lib/string/lib_strerror.c
+ *
+ * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ * used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ************************************************************************/
+
+struct errno_strmap_s
+{
+ int errnum;
+ char *str;
+};
+
+/* This table maps all error numbers to descriptive strings.
+ * The only assumption that the code makes with regard to this
+ * this table is that it is order by error number.
+ *
+ * The size of this table is quite large. Its size can be
+ * reduced by eliminating some of the more obscure error
+ * strings.
+ */
+
+struct errno_strmap_s g_errnomap[] =
+{
+ { EPERM, EPERM_STR },
+ { ENOENT, ENOENT_STR },
+ { ESRCH, ESRCH_STR },
+ { EINTR, EINTR_STR },
+ { EIO, EIO_STR },
+ { ENXIO, ENXIO_STR },
+ { E2BIG, E2BIG_STR },
+ { ENOEXEC, ENOEXEC_STR },
+ { EBADF, EBADF_STR },
+ { ECHILD, ECHILD_STR },
+ { EAGAIN, EAGAIN_STR },
+ { ENOMEM, ENOMEM_STR },
+ { EACCES, EACCES_STR },
+ { EFAULT, EFAULT_STR },
+ { ENOTBLK, ENOTBLK_STR },
+ { EBUSY, EBUSY_STR },
+ { EEXIST, EEXIST_STR },
+ { EXDEV, EXDEV_STR },
+ { ENODEV, ENODEV_STR },
+ { ENOTDIR, ENOTDIR_STR },
+ { EISDIR, EISDIR_STR },
+ { EINVAL, EINVAL_STR },
+ { ENFILE, ENFILE_STR },
+ { EMFILE, EMFILE_STR },
+ { ENOTTY, ENOTTY_STR },
+ { ETXTBSY, ETXTBSY_STR },
+ { EFBIG, EFBIG_STR },
+ { ENOSPC, ENOSPC_STR },
+ { ESPIPE, ESPIPE_STR },
+ { EROFS, EROFS_STR },
+ { EMLINK, EMLINK_STR },
+ { EPIPE, EPIPE_STR },
+ { EDOM, EDOM_STR },
+ { ERANGE, ERANGE_STR },
+ { EDEADLK, EDEADLK_STR },
+ { ENAMETOOLONG, ENAMETOOLONG_STR },
+ { ENOLCK, ENOLCK_STR },
+ { ENOSYS, ENOSYS_STR },
+ { ENOTEMPTY, ENOTEMPTY_STR },
+ { ELOOP, ELOOP_STR },
+ { ENOMSG, ENOMSG_STR },
+ { EIDRM, EIDRM_STR },
+ { ECHRNG, ECHRNG_STR },
+ { EL2NSYNC, EL2NSYNC_STR },
+ { EL3HLT, EL3HLT_STR },
+ { EL3RST, EL3RST_STR },
+ { ELNRNG, ELNRNG_STR },
+ { EUNATCH, EUNATCH_STR },
+ { ENOCSI, ENOCSI_STR },
+ { EL2HLT, EL2HLT_STR },
+ { EBADE, EBADE_STR },
+ { EBADR, EBADR_STR },
+ { EXFULL, EXFULL_STR },
+ { ENOANO, ENOANO_STR },
+ { EBADRQC, EBADRQC_STR },
+ { EBADSLT, EBADSLT_STR },
+ { EBFONT, EBFONT_STR },
+ { ENOSTR, ENOSTR_STR },
+ { ENODATA, ENODATA_STR },
+ { ETIME, ETIME_STR },
+ { ENOSR, ENOSR_STR },
+ { ENONET, ENONET_STR },
+ { ENOPKG, ENOPKG_STR },
+ { EREMOTE, EREMOTE_STR },
+ { ENOLINK, ENOLINK_STR },
+ { EADV, EADV_STR },
+ { ESRMNT, ESRMNT_STR },
+ { ECOMM, ECOMM_STR },
+ { EPROTO, EPROTO_STR },
+ { EMULTIHOP, EMULTIHOP_STR },
+ { EDOTDOT, EDOTDOT_STR },
+ { EBADMSG, EBADMSG_STR },
+ { EOVERFLOW, EOVERFLOW_STR },
+ { ENOTUNIQ, ENOTUNIQ_STR },
+ { EBADFD, EBADFD_STR },
+ { EREMCHG, EREMCHG_STR },
+ { ELIBACC, ELIBACC_STR },
+ { ELIBBAD, ELIBBAD_STR },
+ { ELIBSCN, ELIBSCN_STR },
+ { ELIBMAX, ELIBMAX_STR },
+ { ELIBEXEC, ELIBEXEC_STR },
+ { EILSEQ, EILSEQ_STR },
+ { ERESTART, ERESTART_STR },
+ { ESTRPIPE, ESTRPIPE_STR },
+ { EUSERS, EUSERS_STR },
+ { ENOTSOCK, ENOTSOCK_STR },
+ { EDESTADDRREQ, EDESTADDRREQ_STR },
+ { EMSGSIZE, EMSGSIZE_STR },
+ { EPROTOTYPE, EPROTOTYPE_STR },
+ { ENOPROTOOPT, ENOPROTOOPT_STR },
+ { EPROTONOSUPPORT, EPROTONOSUPPORT_STR },
+ { ESOCKTNOSUPPORT, ESOCKTNOSUPPORT_STR },
+ { EOPNOTSUPP, EOPNOTSUPP_STR },
+ { EPFNOSUPPORT, EPFNOSUPPORT_STR },
+ { EAFNOSUPPORT, EAFNOSUPPORT_STR },
+ { EADDRINUSE, EADDRINUSE_STR },
+ { EADDRNOTAVAIL, EADDRNOTAVAIL_STR },
+ { ENETDOWN, ENETDOWN_STR },
+ { ENETUNREACH, ENETUNREACH_STR },
+ { ENETRESET, ENETRESET_STR },
+ { ECONNABORTED, ECONNABORTED_STR },
+ { ECONNRESET, ECONNRESET_STR },
+ { ENOBUFS, ENOBUFS_STR },
+ { EISCONN, EISCONN_STR },
+ { ENOTCONN, ENOTCONN_STR },
+ { ESHUTDOWN, ESHUTDOWN_STR },
+ { ETOOMANYREFS, ETOOMANYREFS_STR },
+ { ETIMEDOUT, ETIMEDOUT_STR },
+ { ECONNREFUSED, ECONNREFUSED_STR },
+ { EHOSTDOWN, EHOSTDOWN_STR },
+ { EHOSTUNREACH, EHOSTUNREACH_STR },
+ { EALREADY, EALREADY_STR },
+ { EINPROGRESS, EINPROGRESS_STR },
+ { ESTALE, ESTALE_STR },
+ { EUCLEAN, EUCLEAN_STR },
+ { ENOTNAM, ENOTNAM_STR },
+ { ENAVAIL, ENAVAIL_STR },
+ { EISNAM, EISNAM_STR },
+ { EREMOTEIO, EREMOTEIO_STR },
+ { EDQUOT, EDQUOT_STR },
+ { ENOMEDIUM, ENOMEDIUM_STR },
+ { EMEDIUMTYPE, EMEDIUMTYPE_STR }
+};
+
+#define NERRNO_STRS (sizeof(g_errnomap) / sizeof(struct errno_strmap_s))
+
+char *strerror(int errnum)
+{
+ int ndxlow = 0;
+ int ndxhi = NERRNO_STRS - 1;
+ int ndxmid;
+
+ do
+ {
+ ndxmid = (ndxlow + ndxhi) >> 1;
+ if (errnum > g_errnomap[ndxmid].errnum)
+ {
+ ndxlow = ndxmid + 1;
+ }
+ else if (errnum < g_errnomap[ndxmid].errnum)
+ {
+ ndxhi = ndxmid - 1;
+ }
+ else
+ {
+ return g_errnomap[ndxmid].str;
+ }
+ }
+ while (ndxlow <= ndxhi);
+ return "Unknown error";
+}
--- /dev/null
+void isr(void);
+
+#ifdef __or1k__
+
+#define EXTERNAL_IRQ 0x8
+
+void exception_handler(unsigned long vect, unsigned long *regs,
+ unsigned long pc, unsigned long ea);
+void exception_handler(unsigned long vect, unsigned long *regs,
+ unsigned long pc, unsigned long ea)
+{
+ if(vect == EXTERNAL_IRQ) {
+ isr();
+ } else {
+ /* Unhandled exception */
+ for(;;);
+ }
+}
+#endif
--- /dev/null
+#include <generated/csr.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <id.h>
+
+void get_sysid_formatted(char *sysid)
+{
+ sysid[0] = identifier_sysid_read() >> 8;
+ sysid[1] = identifier_sysid_read();
+ sysid[2] = 0;
+}
+
+void id_print(void)
+{
+ char sysid[3];
+
+ get_sysid_formatted(sysid);
+ printf("Running on LiteX SoC (sysid:%s) at %dMHz\n", sysid, identifier_frequency_read()/1000000);
+}
--- /dev/null
+/*
+ * MiSoC
+ * Copyright (C) 2007, 2008, 2009, 2010, 2011 Sebastien Bourdeauducq
+ * Copyright (C) Linus Torvalds and Linux kernel developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <limits.h>
+
+/**
+ * strchr - Find the first occurrence of a character in a string
+ * @s: The string to be searched
+ * @c: The character to search for
+ */
+char *strchr(const char *s, int c)
+{
+ for (; *s != (char)c; ++s)
+ if (*s == '\0')
+ return NULL;
+ return (char *)s;
+}
+
+/**
+ * strpbrk - Find the first occurrence of a set of characters
+ * @cs: The string to be searched
+ * @ct: The characters to search for
+ */
+char *strpbrk(const char *cs, const char *ct)
+{
+ const char *sc1, *sc2;
+
+ for (sc1 = cs; *sc1 != '\0'; ++sc1) {
+ for (sc2 = ct; *sc2 != '\0'; ++sc2) {
+ if (*sc1 == *sc2)
+ return (char *)sc1;
+ }
+ }
+ return NULL;
+}
+
+/**
+ * strrchr - Find the last occurrence of a character in a string
+ * @s: The string to be searched
+ * @c: The character to search for
+ */
+char *strrchr(const char *s, int c)
+{
+ const char *p = s + strlen(s);
+ do {
+ if (*p == (char)c)
+ return (char *)p;
+ } while (--p >= s);
+ return NULL;
+}
+
+/**
+ * strnchr - Find a character in a length limited string
+ * @s: The string to be searched
+ * @count: The number of characters to be searched
+ * @c: The character to search for
+ */
+char *strnchr(const char *s, size_t count, int c)
+{
+ for (; count-- && *s != '\0'; ++s)
+ if (*s == (char)c)
+ return (char *)s;
+ return NULL;
+}
+
+/**
+ * strcpy - Copy a %NUL terminated string
+ * @dest: Where to copy the string to
+ * @src: Where to copy the string from
+ */
+char *strcpy(char *dest, const char *src)
+{
+ char *tmp = dest;
+
+ while ((*dest++ = *src++) != '\0')
+ /* nothing */;
+ return tmp;
+}
+
+/**
+ * strncpy - Copy a length-limited, %NUL-terminated string
+ * @dest: Where to copy the string to
+ * @src: Where to copy the string from
+ * @count: The maximum number of bytes to copy
+ *
+ * The result is not %NUL-terminated if the source exceeds
+ * @count bytes.
+ *
+ * In the case where the length of @src is less than that of
+ * count, the remainder of @dest will be padded with %NUL.
+ *
+ */
+char *strncpy(char *dest, const char *src, size_t count)
+{
+ char *tmp = dest;
+
+ while (count) {
+ if ((*tmp = *src) != 0)
+ src++;
+ tmp++;
+ count--;
+ }
+ return dest;
+}
+
+/**
+ * strcmp - Compare two strings
+ * @cs: One string
+ * @ct: Another string
+ */
+int strcmp(const char *cs, const char *ct)
+{
+ signed char __res;
+
+ while (1) {
+ if ((__res = *cs - *ct++) != 0 || !*cs++)
+ break;
+ }
+ return __res;
+}
+
+/**
+ * strncmp - Compare two strings using the first characters only
+ * @cs: One string
+ * @ct: Another string
+ * @count: Number of characters
+ */
+int strncmp(const char *cs, const char *ct, size_t count)
+{
+ signed char __res;
+ size_t n;
+
+ n = 0;
+ __res = 0;
+ while (n < count) {
+ if ((__res = *cs - *ct++) != 0 || !*cs++)
+ break;
+ n++;
+ }
+ return __res;
+}
+
+/**
+ * strcat - Append one %NUL-terminated string to another
+ * @dest: The string to be appended to
+ * @src: The string to append to it
+ */
+char *strcat(char *dest, const char *src)
+{
+ char *tmp = dest;
+
+ while (*dest)
+ dest++;
+ while ((*dest++ = *src++) != '\0')
+ ;
+ return tmp;
+}
+
+/**
+ * strncat - Append a length-limited, %NUL-terminated string to another
+ * @dest: The string to be appended to
+ * @src: The string to append to it
+ * @count: The maximum numbers of bytes to copy
+ *
+ * Note that in contrast to strncpy(), strncat() ensures the result is
+ * terminated.
+ */
+char *strncat(char *dest, const char *src, size_t count)
+{
+ char *tmp = dest;
+
+ if (count) {
+ while (*dest)
+ dest++;
+ while ((*dest++ = *src++) != 0) {
+ if (--count == 0) {
+ *dest = '\0';
+ break;
+ }
+ }
+ }
+ return tmp;
+}
+
+/**
+ * strlen - Find the length of a string
+ * @s: The string to be sized
+ */
+size_t strlen(const char *s)
+{
+ const char *sc;
+
+ for (sc = s; *sc != '\0'; ++sc)
+ /* nothing */;
+ return sc - s;
+}
+
+/**
+ * strnlen - Find the length of a length-limited string
+ * @s: The string to be sized
+ * @count: The maximum number of bytes to search
+ */
+size_t strnlen(const char *s, size_t count)
+{
+ const char *sc;
+
+ for (sc = s; count-- && *sc != '\0'; ++sc)
+ /* nothing */;
+ return sc - s;
+}
+
+/**
+ * strspn - Calculate the length of the initial substring of @s which only contain letters in @accept
+ * @s: The string to be searched
+ * @accept: The string to search for
+ */
+size_t strspn(const char *s, const char *accept)
+{
+ const char *p;
+ const char *a;
+ size_t count = 0;
+
+ for (p = s; *p != '\0'; ++p) {
+ for (a = accept; *a != '\0'; ++a) {
+ if (*p == *a)
+ break;
+ }
+ if (*a == '\0')
+ return count;
+ ++count;
+ }
+ return count;
+}
+
+/**
+ * memcmp - Compare two areas of memory
+ * @cs: One area of memory
+ * @ct: Another area of memory
+ * @count: The size of the area.
+ */
+int memcmp(const void *cs, const void *ct, size_t count)
+{
+ const unsigned char *su1, *su2;
+ int res = 0;
+
+ for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
+ if ((res = *su1 - *su2) != 0)
+ break;
+ return res;
+}
+
+/**
+ * memset - Fill a region of memory with the given value
+ * @s: Pointer to the start of the area.
+ * @c: The byte to fill the area with
+ * @count: The size of the area.
+ */
+void *memset(void *s, int c, size_t count)
+{
+ char *xs = s;
+
+ while (count--)
+ *xs++ = c;
+ return s;
+}
+
+/**
+ * memcpy - Copies one area of memory to another
+ * @dest: Destination
+ * @src: Source
+ * @n: The size to copy.
+ */
+void *memcpy(void *to, const void *from, size_t n)
+{
+ void *xto = to;
+ size_t temp;
+
+ if(!n)
+ return xto;
+ if((long)to & 1) {
+ char *cto = to;
+ const char *cfrom = from;
+ *cto++ = *cfrom++;
+ to = cto;
+ from = cfrom;
+ n--;
+ }
+ if((long)from & 1) {
+ char *cto = to;
+ const char *cfrom = from;
+ for (; n; n--)
+ *cto++ = *cfrom++;
+ return xto;
+ }
+ if(n > 2 && (long)to & 2) {
+ short *sto = to;
+ const short *sfrom = from;
+ *sto++ = *sfrom++;
+ to = sto;
+ from = sfrom;
+ n -= 2;
+ }
+ if((long)from & 2) {
+ short *sto = to;
+ const short *sfrom = from;
+ temp = n >> 1;
+ for (; temp; temp--)
+ *sto++ = *sfrom++;
+ to = sto;
+ from = sfrom;
+ if(n & 1) {
+ char *cto = to;
+ const char *cfrom = from;
+ *cto = *cfrom;
+ }
+ return xto;
+ }
+ temp = n >> 2;
+ if(temp) {
+ long *lto = to;
+ const long *lfrom = from;
+ for(; temp; temp--)
+ *lto++ = *lfrom++;
+ to = lto;
+ from = lfrom;
+ }
+ if(n & 2) {
+ short *sto = to;
+ const short *sfrom = from;
+ *sto++ = *sfrom++;
+ to = sto;
+ from = sfrom;
+ }
+ if(n & 1) {
+ char *cto = to;
+ const char *cfrom = from;
+ *cto = *cfrom;
+ }
+ return xto;
+}
+
+/**
+ * memmove - Copies one area of memory to another, overlap possible
+ * @dest: Destination
+ * @src: Source
+ * @n: The size to copy.
+ */
+void *memmove(void *dest, const void *src, size_t count)
+{
+ char *tmp, *s;
+
+ if(dest <= src) {
+ tmp = (char *) dest;
+ s = (char *) src;
+ while(count--)
+ *tmp++ = *s++;
+ } else {
+ tmp = (char *)dest + count;
+ s = (char *)src + count;
+ while(count--)
+ *--tmp = *--s;
+ }
+
+ return dest;
+}
+
+/**
+ * strstr - Find the first substring in a %NUL terminated string
+ * @s1: The string to be searched
+ * @s2: The string to search for
+ */
+char *strstr(const char *s1, const char *s2)
+{
+ size_t l1, l2;
+
+ l2 = strlen(s2);
+ if (!l2)
+ return (char *)s1;
+ l1 = strlen(s1);
+ while (l1 >= l2) {
+ l1--;
+ if (!memcmp(s1, s2, l2))
+ return (char *)s1;
+ s1++;
+ }
+ return NULL;
+}
+
+/**
+ * memchr - Find a character in an area of memory.
+ * @s: The memory area
+ * @c: The byte to search for
+ * @n: The size of the area.
+ *
+ * returns the address of the first occurrence of @c, or %NULL
+ * if @c is not found
+ */
+void *memchr(const void *s, int c, size_t n)
+{
+ const unsigned char *p = s;
+ while (n-- != 0) {
+ if ((unsigned char)c == *p++) {
+ return (void *)(p - 1);
+ }
+ }
+ return NULL;
+}
+
+/**
+ * strtoul - convert a string to an unsigned long
+ * @nptr: The start of the string
+ * @endptr: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+unsigned long strtoul(const char *nptr, char **endptr, int base)
+{
+ unsigned long result = 0,value;
+
+ if (!base) {
+ base = 10;
+ if (*nptr == '0') {
+ base = 8;
+ nptr++;
+ if ((toupper(*nptr) == 'X') && isxdigit(nptr[1])) {
+ nptr++;
+ base = 16;
+ }
+ }
+ } else if (base == 16) {
+ if (nptr[0] == '0' && toupper(nptr[1]) == 'X')
+ nptr += 2;
+ }
+ while (isxdigit(*nptr) &&
+ (value = isdigit(*nptr) ? *nptr-'0' : toupper(*nptr)-'A'+10) < base) {
+ result = result*base + value;
+ nptr++;
+ }
+ if (endptr)
+ *endptr = (char *)nptr;
+ return result;
+}
+
+/**
+ * strtol - convert a string to a signed long
+ * @nptr: The start of the string
+ * @endptr: A pointer to the end of the parsed string will be placed here
+ * @base: The number base to use
+ */
+long strtol(const char *nptr, char **endptr, int base)
+{
+ if(*nptr=='-')
+ return -strtoul(nptr+1,endptr,base);
+ return strtoul(nptr,endptr,base);
+}
+
+int skip_atoi(const char **s)
+{
+ int i=0;
+
+ while (isdigit(**s))
+ i = i*10 + *((*s)++) - '0';
+ return i;
+}
+
+char *number(char *buf, char *end, unsigned long num, int base, int size, int precision, int type)
+{
+ char c,sign,tmp[66];
+ const char *digits;
+ static const char small_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+ static const char large_digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+ int i;
+
+ digits = (type & PRINTF_LARGE) ? large_digits : small_digits;
+ if (type & PRINTF_LEFT)
+ type &= ~PRINTF_ZEROPAD;
+ if (base < 2 || base > 36)
+ return NULL;
+ c = (type & PRINTF_ZEROPAD) ? '0' : ' ';
+ sign = 0;
+ if (type & PRINTF_SIGN) {
+ if ((signed long) num < 0) {
+ sign = '-';
+ num = - (signed long) num;
+ size--;
+ } else if (type & PRINTF_PLUS) {
+ sign = '+';
+ size--;
+ } else if (type & PRINTF_SPACE) {
+ sign = ' ';
+ size--;
+ }
+ }
+ if (type & PRINTF_SPECIAL) {
+ if (base == 16)
+ size -= 2;
+ else if (base == 8)
+ size--;
+ }
+ i = 0;
+ if (num == 0)
+ tmp[i++]='0';
+ else while (num != 0) {
+ tmp[i++] = digits[num % base];
+ num = num / base;
+ }
+ if (i > precision)
+ precision = i;
+ size -= precision;
+ if (!(type&(PRINTF_ZEROPAD+PRINTF_LEFT))) {
+ while(size-->0) {
+ if (buf < end)
+ *buf = ' ';
+ ++buf;
+ }
+ }
+ if (sign) {
+ if (buf < end)
+ *buf = sign;
+ ++buf;
+ }
+ if (type & PRINTF_SPECIAL) {
+ if (base==8) {
+ if (buf < end)
+ *buf = '0';
+ ++buf;
+ } else if (base==16) {
+ if (buf < end)
+ *buf = '0';
+ ++buf;
+ if (buf < end)
+ *buf = digits[33];
+ ++buf;
+ }
+ }
+ if (!(type & PRINTF_LEFT)) {
+ while (size-- > 0) {
+ if (buf < end)
+ *buf = c;
+ ++buf;
+ }
+ }
+ while (i < precision--) {
+ if (buf < end)
+ *buf = '0';
+ ++buf;
+ }
+ while (i-- > 0) {
+ if (buf < end)
+ *buf = tmp[i];
+ ++buf;
+ }
+ while (size-- > 0) {
+ if (buf < end)
+ *buf = ' ';
+ ++buf;
+ }
+ return buf;
+}
+
+/**
+ * vscnprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @size: The size of the buffer, including the trailing null space
+ * @fmt: The format string to use
+ * @args: Arguments for the format string
+ *
+ * The return value is the number of characters which have been written into
+ * the @buf not including the trailing '\0'. If @size is <= 0 the function
+ * returns 0.
+ *
+ * Call this function if you are already dealing with a va_list.
+ * You probably want scnprintf() instead.
+ */
+int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
+{
+ int i;
+
+ i=vsnprintf(buf,size,fmt,args);
+ return (i >= size) ? (size - 1) : i;
+}
+
+
+/**
+ * snprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @size: The size of the buffer, including the trailing null space
+ * @fmt: The format string to use
+ * @...: Arguments for the format string
+ *
+ * The return value is the number of characters which would be
+ * generated for the given input, excluding the trailing null,
+ * as per ISO C99. If the return is greater than or equal to
+ * @size, the resulting string is truncated.
+ */
+int snprintf(char * buf, size_t size, const char *fmt, ...)
+{
+ va_list args;
+ int i;
+
+ va_start(args, fmt);
+ i=vsnprintf(buf,size,fmt,args);
+ va_end(args);
+ return i;
+}
+
+/**
+ * scnprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @size: The size of the buffer, including the trailing null space
+ * @fmt: The format string to use
+ * @...: Arguments for the format string
+ *
+ * The return value is the number of characters written into @buf not including
+ * the trailing '\0'. If @size is <= 0 the function returns 0.
+ */
+
+int scnprintf(char * buf, size_t size, const char *fmt, ...)
+{
+ va_list args;
+ int i;
+
+ va_start(args, fmt);
+ i = vsnprintf(buf, size, fmt, args);
+ va_end(args);
+ return (i >= size) ? (size - 1) : i;
+}
+
+/**
+ * vsprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @fmt: The format string to use
+ * @args: Arguments for the format string
+ *
+ * The function returns the number of characters written
+ * into @buf. Use vsnprintf() or vscnprintf() in order to avoid
+ * buffer overflows.
+ *
+ * Call this function if you are already dealing with a va_list.
+ * You probably want sprintf() instead.
+ */
+int vsprintf(char *buf, const char *fmt, va_list args)
+{
+ return vsnprintf(buf, INT_MAX, fmt, args);
+}
+
+/**
+ * sprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @fmt: The format string to use
+ * @...: Arguments for the format string
+ *
+ * The function returns the number of characters written
+ * into @buf. Use snprintf() or scnprintf() in order to avoid
+ * buffer overflows.
+ */
+int sprintf(char * buf, const char *fmt, ...)
+{
+ va_list args;
+ int i;
+
+ va_start(args, fmt);
+ i=vsnprintf(buf, INT_MAX, fmt, args);
+ va_end(args);
+ return i;
+}
+
+/* From linux/lib/ctype.c, Copyright (C) 1991, 1992 Linus Torvalds */
+const unsigned char _ctype[] = {
+_C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */
+_C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */
+_C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */
+_C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */
+_P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */
+_D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */
+_D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */
+_P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */
+_U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */
+_U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */
+_U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */
+_P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */
+_L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */
+_L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */
+_L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */
+_S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */
+_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */
+_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */
+_U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */
+_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */
+_L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */
+
+/**
+ * rand - Returns a pseudo random number
+ */
+
+static unsigned int randseed;
+unsigned int rand(void)
+{
+ randseed = 129 * randseed + 907633385;
+ return randseed;
+}
+
+void srand(unsigned int seed)
+{
+ randseed = seed;
+}
+
+void abort(void)
+{
+ printf("Aborted.");
+ while(1);
+}
--- /dev/null
+INCLUDE generated/output_format.ld
+ENTRY(_start)
+
+__DYNAMIC = 0;
+
+INCLUDE generated/regions.ld
+
+SECTIONS
+{
+ .text :
+ {
+ _ftext = .;
+ *(.text .stub .text.* .gnu.linkonce.t.*)
+ _etext = .;
+ } > main_ram
+
+ .got :
+ {
+ _GLOBAL_OFFSET_TABLE_ = .;
+ *(.got)
+ } > main_ram
+
+ .got.plt :
+ {
+ *(.got.plt)
+ } > main_ram
+
+ .rodata :
+ {
+ . = ALIGN(4);
+ _frodata = .;
+ *(.rodata .rodata.* .gnu.linkonce.r.*)
+ *(.rodata1)
+ _erodata = .;
+ } > main_ram
+
+ .data :
+ {
+ . = ALIGN(4);
+ _fdata = .;
+ *(.data .data.* .gnu.linkonce.d.*)
+ *(.data1)
+ *(.sdata .sdata.* .gnu.linkonce.s.*)
+ _edata = .;
+ } > main_ram
+
+ .bss :
+ {
+ . = ALIGN(4);
+ _fbss = .;
+ *(.dynsbss)
+ *(.sbss .sbss.* .gnu.linkonce.sb.*)
+ *(.scommon)
+ *(.dynbss)
+ *(.bss .bss.* .gnu.linkonce.b.*)
+ *(COMMON)
+ . = ALIGN(4);
+ _ebss = .;
+ . = ALIGN(8);
+ _heapstart = .;
+ } > main_ram
+}
+
+PROVIDE(_fstack = ORIGIN(main_ram) + LENGTH(main_ram) - 4);
--- /dev/null
+/****************************************************************************
+ * lib/stdlib/lib_qsort.c
+ *
+ * Copyright (C) 2007, 2009, 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * Leveraged from:
+ *
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#include <stdlib.h>
+
+#define min(a, b) (a) < (b) ? a : b
+
+#define swapcode(TYPE, parmi, parmj, n) \
+ { \
+ long i = (n) / sizeof (TYPE); \
+ register TYPE *pi = (TYPE *) (parmi); \
+ register TYPE *pj = (TYPE *) (parmj); \
+ do { \
+ register TYPE t = *pi; \
+ *pi++ = *pj; \
+ *pj++ = t; \
+ } while (--i > 0); \
+ }
+
+#define SWAPINIT(a, size) \
+ swaptype = ((char *)a - (char *)0) % sizeof(long) || \
+ size % sizeof(long) ? 2 : size == sizeof(long)? 0 : 1;
+
+#define swap(a, b) \
+ if (swaptype == 0) \
+ { \
+ long t = *(long *)(a); \
+ *(long *)(a) = *(long *)(b); \
+ *(long *)(b) = t; \
+ } \
+ else \
+ { \
+ swapfunc(a, b, size, swaptype); \
+ }
+
+#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
+
+static inline void swapfunc(char *a, char *b, int n, int swaptype);
+static inline char *med3(char *a, char *b, char *c,
+ int (*compar)(const void *, const void *));
+
+static inline void swapfunc(char *a, char *b, int n, int swaptype)
+{
+ if(swaptype <= 1)
+ {
+ swapcode(long, a, b, n)
+ }
+ else
+ {
+ swapcode(char, a, b, n)
+ }
+}
+
+static inline char *med3(char *a, char *b, char *c,
+ int (*compar)(const void *, const void *))
+{
+ return compar(a, b) < 0 ?
+ (compar(b, c) < 0 ? b : (compar(a, c) < 0 ? c : a ))
+ :(compar(b, c) > 0 ? b : (compar(a, c) < 0 ? a : c ));
+}
+
+/****************************************************************************
+ * Name: qsort
+ *
+ * Description:
+ * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
+ *
+ ****************************************************************************/
+
+void qsort(void *base, size_t nmemb, size_t size,
+ int(*compar)(const void *, const void *))
+{
+ char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
+ int d, r, swaptype, swap_cnt;
+
+loop:
+ SWAPINIT(base, size);
+ swap_cnt = 0;
+ if (nmemb < 7)
+ {
+ for (pm = (char *) base + size; pm < (char *) base + nmemb * size; pm += size)
+ {
+ for (pl = pm; pl > (char *) base && compar(pl - size, pl) > 0; pl -= size)
+ {
+ swap(pl, pl - size);
+ }
+ }
+ return;
+ }
+
+ pm = (char *) base + (nmemb / 2) * size;
+ if (nmemb > 7)
+ {
+ pl = base;
+ pn = (char *) base + (nmemb - 1) * size;
+ if (nmemb > 40)
+ {
+ d = (nmemb / 8) * size;
+ pl = med3(pl, pl + d, pl + 2 * d, compar);
+ pm = med3(pm - d, pm, pm + d, compar);
+ pn = med3(pn - 2 * d, pn - d, pn, compar);
+ }
+ pm = med3(pl, pm, pn, compar);
+ }
+ swap(base, pm);
+ pa = pb = (char *) base + size;
+
+ pc = pd = (char *) base + (nmemb - 1) * size;
+ for (;;)
+ {
+ while (pb <= pc && (r = compar(pb, base)) <= 0)
+ {
+ if (r == 0)
+ {
+ swap_cnt = 1;
+ swap(pa, pb);
+ pa += size;
+ }
+ pb += size;
+ }
+ while (pb <= pc && (r = compar(pc, base)) >= 0)
+ {
+ if (r == 0)
+ {
+ swap_cnt = 1;
+ swap(pc, pd);
+ pd -= size;
+ }
+ pc -= size;
+ }
+
+ if (pb > pc)
+ {
+ break;
+ }
+
+ swap(pb, pc);
+ swap_cnt = 1;
+ pb += size;
+ pc -= size;
+ }
+
+ if (swap_cnt == 0)
+ {
+ /* Switch to insertion sort */
+
+ for (pm = (char *) base + size; pm < (char *) base + nmemb * size; pm += size)
+ {
+ for (pl = pm; pl > (char *) base && compar(pl - size, pl) > 0; pl -= size)
+ {
+ swap(pl, pl - size);
+ }
+ }
+ return;
+ }
+
+ pn = (char *) base + nmemb * size;
+ r = min(pa - (char *)base, pb - pa);
+ vecswap(base, pb - r, r);
+ r = min(pd - pc, pn - pd - size);
+ vecswap(pb, pn - r, r);
+
+ if ((r = pb - pa) > size)
+ {
+ qsort(base, r / size, size, compar);
+ }
+
+ if ((r = pd - pc) > size)
+ {
+ /* Iterate rather than recurse to save stack space */
+ base = pn - r;
+ nmemb = r / size;
+ goto loop;
+ }
+}
+
--- /dev/null
+#include <generated/csr.h>
+
+#if (defined CSR_SPIFLASH_BASE && defined SPIFLASH_PAGE_SIZE)
+
+#include <spiflash.h>
+
+#define PAGE_PROGRAM_CMD 0x02
+#define WRDI_CMD 0x04
+#define RDSR_CMD 0x05
+#define WREN_CMD 0x06
+#define SE_CMD 0xd8
+
+#define BITBANG_CLK (1 << 1)
+#define BITBANG_CS_N (1 << 2)
+#define BITBANG_DQ_INPUT (1 << 3)
+
+#define SR_WIP 1
+
+static void flash_write_byte(unsigned char b);
+static void flash_write_addr(unsigned int addr);
+static void wait_for_device_ready(void);
+
+#define min(a,b) (a>b?b:a)
+
+static void flash_write_byte(unsigned char b)
+{
+ int i;
+ spiflash_bitbang_write(0); // ~CS_N ~CLK
+
+ for(i = 0; i < 8; i++, b <<= 1) {
+
+ spiflash_bitbang_write((b & 0x80) >> 7);
+ spiflash_bitbang_write(((b & 0x80) >> 7) | BITBANG_CLK);
+ }
+
+ spiflash_bitbang_write(0); // ~CS_N ~CLK
+
+}
+
+static void flash_write_addr(unsigned int addr)
+{
+ int i;
+ spiflash_bitbang_write(0);
+
+ for(i = 0; i < 24; i++, addr <<= 1) {
+ spiflash_bitbang_write((addr & 0x800000) >> 23);
+ spiflash_bitbang_write(((addr & 0x800000) >> 23) | BITBANG_CLK);
+ }
+
+ spiflash_bitbang_write(0);
+}
+
+static void wait_for_device_ready(void)
+{
+ unsigned char sr;
+ unsigned char i;
+ do {
+ sr = 0;
+ flash_write_byte(RDSR_CMD);
+ spiflash_bitbang_write(BITBANG_DQ_INPUT);
+ for(i = 0; i < 8; i++) {
+ sr <<= 1;
+ spiflash_bitbang_write(BITBANG_CLK | BITBANG_DQ_INPUT);
+ sr |= spiflash_miso_read();
+ spiflash_bitbang_write(0 | BITBANG_DQ_INPUT);
+ }
+ spiflash_bitbang_write(0);
+ spiflash_bitbang_write(BITBANG_CS_N);
+ } while(sr & SR_WIP);
+}
+
+void erase_flash_sector(unsigned int addr)
+{
+ unsigned int sector_addr = addr & ~(SPIFLASH_SECTOR_SIZE - 1);
+
+ spiflash_bitbang_en_write(1);
+
+ wait_for_device_ready();
+
+ flash_write_byte(WREN_CMD);
+ spiflash_bitbang_write(BITBANG_CS_N);
+
+ flash_write_byte(SE_CMD);
+ flash_write_addr(sector_addr);
+ spiflash_bitbang_write(BITBANG_CS_N);
+
+ wait_for_device_ready();
+
+ spiflash_bitbang_en_write(0);
+}
+
+void write_to_flash_page(unsigned int addr, const unsigned char *c, unsigned int len)
+{
+ unsigned int i;
+
+ if(len > SPIFLASH_PAGE_SIZE)
+ len = SPIFLASH_PAGE_SIZE;
+
+ spiflash_bitbang_en_write(1);
+
+ wait_for_device_ready();
+
+ flash_write_byte(WREN_CMD);
+ spiflash_bitbang_write(BITBANG_CS_N);
+ flash_write_byte(PAGE_PROGRAM_CMD);
+ flash_write_addr((unsigned int)addr);
+ for(i = 0; i < len; i++)
+ flash_write_byte(*c++);
+
+ spiflash_bitbang_write(BITBANG_CS_N);
+ spiflash_bitbang_write(0);
+
+ wait_for_device_ready();
+
+ spiflash_bitbang_en_write(0);
+}
+
+#define SPIFLASH_PAGE_MASK (SPIFLASH_PAGE_SIZE - 1)
+
+void write_to_flash(unsigned int addr, const unsigned char *c, unsigned int len)
+{
+ unsigned int written = 0;
+
+ if(addr & SPIFLASH_PAGE_MASK) {
+ written = min(SPIFLASH_PAGE_SIZE - (addr & SPIFLASH_PAGE_MASK), len);
+ write_to_flash_page(addr, c, written);
+ c += written;
+ addr += written;
+ len -= written;
+ }
+
+ while(len > 0) {
+ written = min(len, SPIFLASH_PAGE_SIZE);
+ write_to_flash_page(addr, c, written);
+ c += written;
+ addr += written;
+ len -= written;
+ }
+}
+
+#endif /* CSR_SPIFLASH_BASE && SPIFLASH_PAGE_SIZE */
--- /dev/null
+/****************************************************************************
+ * lib/string/lib_strtod.c
+ * Convert string to double
+ *
+ * Copyright (C) 2002 Michael Ringgaard. All rights reserved.
+ * Copyright (C) 2006-2007 H. Peter Anvin.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+
+/****************************************************************************
+ * Pre-processor definitions
+ ****************************************************************************/
+
+/* These are predefined with GCC, but could be issues for other compilers. If
+ * not defined, an arbitrary big number is put in for now. These should be
+ * added to nuttx/compiler for your compiler.
+ */
+
+#if !defined(__DBL_MIN_EXP__) || !defined(__DBL_MAX_EXP__)
+# ifdef CONFIG_CPP_HAVE_WARNING
+# warning "Size of exponent is unknown"
+# endif
+# undef __DBL_MIN_EXP__
+# define __DBL_MIN_EXP__ (-1021)
+# undef __DBL_MAX_EXP__
+# define __DBL_MAX_EXP__ (1024)
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static inline int is_real(double x)
+{
+ const double infinite = 1.0/0.0;
+ return (x < infinite) && (x >= -infinite);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/***************************************************(************************
+ * Name: strtod
+ *
+ * Description:
+ * Convert a string to a double value
+ *
+ ****************************************************************************/
+
+double strtod(const char *str, char **endptr)
+{
+ double number;
+ int exponent;
+ int negative;
+ char *p = (char *) str;
+ double p10;
+ int n;
+ int num_digits;
+ int num_decimals;
+ const double infinite = 1.0/0.0;
+
+ /* Skip leading whitespace */
+
+ while (isspace(*p))
+ {
+ p++;
+ }
+
+ /* Handle optional sign */
+
+ negative = 0;
+ switch (*p)
+ {
+ case '-':
+ negative = 1; /* Fall through to increment position */
+ case '+':
+ p++;
+ }
+
+ number = 0.;
+ exponent = 0;
+ num_digits = 0;
+ num_decimals = 0;
+
+ /* Process string of digits */
+
+ while (isdigit(*p))
+ {
+ number = number * 10. + (*p - '0');
+ p++;
+ num_digits++;
+ }
+
+ /* Process decimal part */
+
+ if (*p == '.')
+ {
+ p++;
+
+ while (isdigit(*p))
+ {
+ number = number * 10. + (*p - '0');
+ p++;
+ num_digits++;
+ num_decimals++;
+ }
+
+ exponent -= num_decimals;
+ }
+
+ if (num_digits == 0)
+ {
+ errno = ERANGE;
+ return 0.0;
+ }
+
+ /* Correct for sign */
+
+ if (negative)
+ {
+ number = -number;
+ }
+
+ /* Process an exponent string */
+
+ if (*p == 'e' || *p == 'E')
+ {
+ /* Handle optional sign */
+
+ negative = 0;
+ switch(*++p)
+ {
+ case '-':
+ negative = 1; /* Fall through to increment pos */
+ case '+':
+ p++;
+ }
+
+ /* Process string of digits */
+
+ n = 0;
+ while (isdigit(*p))
+ {
+ n = n * 10 + (*p - '0');
+ p++;
+ }
+
+ if (negative)
+ {
+ exponent -= n;
+ }
+ else
+ {
+ exponent += n;
+ }
+ }
+
+ if (exponent < __DBL_MIN_EXP__ ||
+ exponent > __DBL_MAX_EXP__)
+ {
+ errno = ERANGE;
+ return infinite;
+ }
+
+ /* Scale the result */
+
+ p10 = 10.;
+ n = exponent;
+ if (n < 0) n = -n;
+ while (n)
+ {
+ if (n & 1)
+ {
+ if (exponent < 0)
+ {
+ number /= p10;
+ }
+ else
+ {
+ number *= p10;
+ }
+ }
+ n >>= 1;
+ p10 *= p10;
+ }
+
+ if (!is_real(number))
+ {
+ errno = ERANGE;
+ }
+
+ if (endptr)
+ {
+ *endptr = p;
+ }
+
+ return number;
+}
+
--- /dev/null
+#include <irq.h>
+#include <uart.h>
+#ifdef __or1k__
+#include <spr-defs.h>
+#endif
+
+#include <system.h>
+#include <generated/mem.h>
+#include <generated/csr.h>
+
+void flush_cpu_icache(void)
+{
+#if defined (__lm32__)
+ asm volatile(
+ "wcsr ICC, r0\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ "nop\n"
+ );
+#elif defined (__or1k__)
+ unsigned long iccfgr;
+ unsigned long cache_set_size;
+ unsigned long cache_ways;
+ unsigned long cache_block_size;
+ unsigned long cache_size;
+ int i;
+
+ iccfgr = mfspr(SPR_ICCFGR);
+ cache_ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
+ cache_set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
+ cache_block_size = (iccfgr & SPR_ICCFGR_CBS) ? 32 : 16;
+ cache_size = cache_set_size * cache_ways * cache_block_size;
+
+ for (i = 0; i < cache_size; i += cache_block_size)
+ mtspr(SPR_ICBIR, i);
+#else
+#error Unsupported architecture
+#endif
+}
+
+void flush_cpu_dcache(void)
+{
+#if defined (__lm32__)
+ asm volatile(
+ "wcsr DCC, r0\n"
+ "nop\n"
+ );
+#elif defined (__or1k__)
+ unsigned long dccfgr;
+ unsigned long cache_set_size;
+ unsigned long cache_ways;
+ unsigned long cache_block_size;
+ unsigned long cache_size;
+ int i;
+
+ dccfgr = mfspr(SPR_DCCFGR);
+ cache_ways = 1 << (dccfgr & SPR_ICCFGR_NCW);
+ cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3);
+ cache_block_size = (dccfgr & SPR_DCCFGR_CBS) ? 32 : 16;
+ cache_size = cache_set_size * cache_ways * cache_block_size;
+
+ for (i = 0; i < cache_size; i += cache_block_size)
+ mtspr(SPR_DCBIR, i);
+#else
+#error Unsupported architecture
+#endif
+}
+
+#ifdef L2_SIZE
+void flush_l2_cache(void)
+{
+ unsigned int i;
+ register unsigned int addr;
+ register unsigned int dummy;
+
+ for(i=0;i<2*L2_SIZE/4;i++) {
+ addr = MAIN_RAM_BASE + i*4;
+#if defined (__lm32__)
+ __asm__ volatile("lw %0, (%1+0)\n":"=r"(dummy):"r"(addr));
+#elif defined (__or1k__)
+ __asm__ volatile("l.lwz %0, 0(%1)\n":"=r"(dummy):"r"(addr));
+#else
+#error Unsupported architecture
+#endif
+ }
+}
+#endif
--- /dev/null
+#include <generated/csr.h>
+#include <time.h>
+
+void time_init(void)
+{
+ int t;
+
+ timer0_en_write(0);
+ t = 2*identifier_frequency_read();
+ timer0_reload_write(t);
+ timer0_load_write(t);
+ timer0_en_write(1);
+}
+
+int elapsed(int *last_event, int period)
+{
+ int t, dt;
+
+ timer0_update_value_write(1);
+ t = timer0_reload_read() - timer0_value_read();
+ if(period < 0) {
+ *last_event = t;
+ return 1;
+ }
+ dt = t - *last_event;
+ if(dt < 0)
+ dt += timer0_reload_read();
+ if((dt > period) || (dt < 0)) {
+ *last_event = t;
+ return 1;
+ } else
+ return 0;
+}
--- /dev/null
+#include <uart.h>
+#include <irq.h>
+#include <generated/csr.h>
+#include <hw/flags.h>
+
+/*
+ * Buffer sizes must be a power of 2 so that modulos can be computed
+ * with logical AND.
+ */
+
+#define UART_RINGBUFFER_SIZE_RX 128
+#define UART_RINGBUFFER_MASK_RX (UART_RINGBUFFER_SIZE_RX-1)
+
+static char rx_buf[UART_RINGBUFFER_SIZE_RX];
+static volatile unsigned int rx_produce;
+static unsigned int rx_consume;
+
+#define UART_RINGBUFFER_SIZE_TX 128
+#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX-1)
+
+static char tx_buf[UART_RINGBUFFER_SIZE_TX];
+static unsigned int tx_produce;
+static volatile unsigned int tx_consume;
+
+void uart_isr(void)
+{
+ unsigned int stat, rx_produce_next;
+
+ stat = uart_ev_pending_read();
+
+ if(stat & UART_EV_RX) {
+ while(!uart_rxempty_read()) {
+ rx_produce_next = (rx_produce + 1) & UART_RINGBUFFER_MASK_RX;
+ if(rx_produce_next != rx_consume) {
+ rx_buf[rx_produce] = uart_rxtx_read();
+ rx_produce = rx_produce_next;
+ }
+ uart_ev_pending_write(UART_EV_RX);
+ }
+ }
+
+ if(stat & UART_EV_TX) {
+ uart_ev_pending_write(UART_EV_TX);
+ while((tx_consume != tx_produce) && !uart_txfull_read()) {
+ uart_rxtx_write(tx_buf[tx_consume]);
+ tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX;
+ }
+ }
+}
+
+/* Do not use in interrupt handlers! */
+char uart_read(void)
+{
+ char c;
+
+ if(irq_getie()) {
+ while(rx_consume == rx_produce);
+ } else if (rx_consume == rx_produce) {
+ return 0;
+ }
+
+ c = rx_buf[rx_consume];
+ rx_consume = (rx_consume + 1) & UART_RINGBUFFER_MASK_RX;
+ return c;
+}
+
+int uart_read_nonblock(void)
+{
+ return (rx_consume != rx_produce);
+}
+
+void uart_write(char c)
+{
+ unsigned int oldmask;
+ unsigned int tx_produce_next = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX;
+
+ if(irq_getie()) {
+ while(tx_produce_next == tx_consume);
+ } else if(tx_produce_next == tx_consume) {
+ return;
+ }
+
+ oldmask = irq_getmask();
+ irq_setmask(oldmask & ~(1 << UART_INTERRUPT));
+ if((tx_consume != tx_produce) || uart_txfull_read()) {
+ tx_buf[tx_produce] = c;
+ tx_produce = tx_produce_next;
+ } else {
+ uart_rxtx_write(c);
+ }
+ irq_setmask(oldmask);
+}
+
+void uart_init(void)
+{
+ rx_produce = 0;
+ rx_consume = 0;
+
+ tx_produce = 0;
+ tx_consume = 0;
+
+ uart_ev_pending_write(uart_ev_pending_read());
+ uart_ev_enable_write(UART_EV_TX | UART_EV_RX);
+ irq_setmask(irq_getmask() | (1 << UART_INTERRUPT));
+}
+
+void uart_sync(void)
+{
+ while(tx_consume != tx_produce);
+}
--- /dev/null
+/*
+ * MiSoC
+ * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
+ * Copyright (C) Linux kernel developers
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+
+/**
+ * vsnprintf - Format a string and place it in a buffer
+ * @buf: The buffer to place the result into
+ * @size: The size of the buffer, including the trailing null space
+ * @fmt: The format string to use
+ * @args: Arguments for the format string
+ *
+ * The return value is the number of characters which would
+ * be generated for the given input, excluding the trailing
+ * '\0', as per ISO C99. If you want to have the exact
+ * number of characters written into @buf as return value
+ * (not including the trailing '\0'), use vscnprintf(). If the
+ * return is greater than or equal to @size, the resulting
+ * string is truncated.
+ *
+ * Call this function if you are already dealing with a va_list.
+ * You probably want snprintf() instead.
+ */
+int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
+{
+ int len;
+ unsigned long long num;
+ int i, base;
+ char *str, *end, c;
+ const char *s;
+
+ int flags; /* flags to number() */
+
+ int field_width; /* width of output field */
+ int precision; /* min. # of digits for integers; max
+ number of chars for from string */
+ int qualifier; /* 'h', 'l', or 'L' for integer fields */
+ /* 'z' support added 23/7/1999 S.H. */
+ /* 'z' changed to 'Z' --davidm 1/25/99 */
+ /* 't' added for ptrdiff_t */
+
+ /* Reject out-of-range values early. Large positive sizes are
+ used for unknown buffer sizes. */
+ if (unlikely((int) size < 0))
+ return 0;
+
+ str = buf;
+ end = buf + size;
+
+ /* Make sure end is always >= buf */
+ if (end < buf) {
+ end = ((void *)-1);
+ size = end - buf;
+ }
+
+ for (; *fmt ; ++fmt) {
+ if (*fmt != '%') {
+ if (str < end)
+ *str = *fmt;
+ ++str;
+ continue;
+ }
+
+ /* process flags */
+ flags = 0;
+ repeat:
+ ++fmt; /* this also skips first '%' */
+ switch (*fmt) {
+ case '-': flags |= PRINTF_LEFT; goto repeat;
+ case '+': flags |= PRINTF_PLUS; goto repeat;
+ case ' ': flags |= PRINTF_SPACE; goto repeat;
+ case '#': flags |= PRINTF_SPECIAL; goto repeat;
+ case '0': flags |= PRINTF_ZEROPAD; goto repeat;
+ }
+
+ /* get field width */
+ field_width = -1;
+ if (isdigit(*fmt))
+ field_width = skip_atoi(&fmt);
+ else if (*fmt == '*') {
+ ++fmt;
+ /* it's the next argument */
+ field_width = va_arg(args, int);
+ if (field_width < 0) {
+ field_width = -field_width;
+ flags |= PRINTF_LEFT;
+ }
+ }
+
+ /* get the precision */
+ precision = -1;
+ if (*fmt == '.') {
+ ++fmt;
+ if (isdigit(*fmt))
+ precision = skip_atoi(&fmt);
+ else if (*fmt == '*') {
+ ++fmt;
+ /* it's the next argument */
+ precision = va_arg(args, int);
+ }
+ if (precision < 0)
+ precision = 0;
+ }
+
+ /* get the conversion qualifier */
+ qualifier = -1;
+ if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' ||
+ *fmt =='Z' || *fmt == 'z' || *fmt == 't') {
+ qualifier = *fmt;
+ ++fmt;
+ if (qualifier == 'l' && *fmt == 'l') {
+ qualifier = 'L';
+ ++fmt;
+ }
+ }
+
+ /* default base */
+ base = 10;
+
+ switch (*fmt) {
+ case 'c':
+ if (!(flags & PRINTF_LEFT)) {
+ while (--field_width > 0) {
+ if (str < end)
+ *str = ' ';
+ ++str;
+ }
+ }
+ c = (unsigned char) va_arg(args, int);
+ if (str < end)
+ *str = c;
+ ++str;
+ while (--field_width > 0) {
+ if (str < end)
+ *str = ' ';
+ ++str;
+ }
+ continue;
+
+ case 's':
+ s = va_arg(args, char *);
+ if (s == NULL)
+ s = "<NULL>";
+
+ len = strnlen(s, precision);
+
+ if (!(flags & PRINTF_LEFT)) {
+ while (len < field_width--) {
+ if (str < end)
+ *str = ' ';
+ ++str;
+ }
+ }
+ for (i = 0; i < len; ++i) {
+ if (str < end)
+ *str = *s;
+ ++str; ++s;
+ }
+ while (len < field_width--) {
+ if (str < end)
+ *str = ' ';
+ ++str;
+ }
+ continue;
+
+ case 'p':
+ if (field_width == -1) {
+ field_width = 2*sizeof(void *);
+ flags |= PRINTF_ZEROPAD;
+ }
+ str = number(str, end,
+ (unsigned long) va_arg(args, void *),
+ 16, field_width, precision, flags);
+ continue;
+
+#ifndef NO_FLOAT
+ case 'g':
+ case 'f': {
+ int m;
+ double f;
+ int integer;
+
+ f = va_arg(args, double);
+ if(f < 0.0) {
+ *str = '-';
+ str++;
+ f = -f;
+ }
+
+ integer = f;
+ if(integer > 0) {
+ m = 1;
+ while(integer > (m*10)) m *= 10;
+ while((m >= 1) && (str < end)) {
+ int n;
+ n = integer/m;
+ *str = '0' + n;
+ str++;
+ f = f - m*n;
+ integer = integer - m*n;
+ m /= 10;
+ }
+ } else if(str < end) {
+ *str = '0';
+ str++;
+ }
+
+ if(str < end) {
+ *str = '.';
+ str++;
+ }
+
+ for(i=0;i<6;i++) {
+ int n;
+
+ f = f*10.0;
+ n = f;
+ f = f - n;
+ if(str >= end) break;
+ *str = '0' + n;
+ str++;
+ }
+
+ continue;
+ }
+#endif
+
+ case 'n':
+ /* FIXME:
+ * What does C99 say about the overflow case here? */
+ if (qualifier == 'l') {
+ long * ip = va_arg(args, long *);
+ *ip = (str - buf);
+ } else if (qualifier == 'Z' || qualifier == 'z') {
+ size_t * ip = va_arg(args, size_t *);
+ *ip = (str - buf);
+ } else {
+ int * ip = va_arg(args, int *);
+ *ip = (str - buf);
+ }
+ continue;
+
+ case '%':
+ if (str < end)
+ *str = '%';
+ ++str;
+ continue;
+
+ /* integer number formats - set up the flags and "break" */
+ case 'o':
+ base = 8;
+ break;
+
+ case 'X':
+ flags |= PRINTF_LARGE;
+ case 'x':
+ base = 16;
+ break;
+
+ case 'd':
+ case 'i':
+ flags |= PRINTF_SIGN;
+ case 'u':
+ break;
+
+ default:
+ if (str < end)
+ *str = '%';
+ ++str;
+ if (*fmt) {
+ if (str < end)
+ *str = *fmt;
+ ++str;
+ } else {
+ --fmt;
+ }
+ continue;
+ }
+ if (qualifier == 'L')
+ num = va_arg(args, long long);
+ else if (qualifier == 'l') {
+ num = va_arg(args, unsigned long);
+ if (flags & PRINTF_SIGN)
+ num = (signed long) num;
+ } else if (qualifier == 'Z' || qualifier == 'z') {
+ num = va_arg(args, size_t);
+ } else if (qualifier == 't') {
+ num = va_arg(args, ptrdiff_t);
+ } else if (qualifier == 'h') {
+ num = (unsigned short) va_arg(args, int);
+ if (flags & PRINTF_SIGN)
+ num = (signed short) num;
+ } else {
+ num = va_arg(args, unsigned int);
+ if (flags & PRINTF_SIGN)
+ num = (signed int) num;
+ }
+ str = number(str, end, num, base,
+ field_width, precision, flags);
+ }
+ if (size > 0) {
+ if (str < end)
+ *str = '\0';
+ else
+ end[-1] = '\0';
+ }
+ /* the trailing null byte doesn't count towards the total */
+ return str-buf;
+}
--- /dev/null
+include ../include/generated/variables.mak
+include $(SOC_DIRECTORY)/software/common.mak
+
+CFLAGS+=-D_YUGA_LITTLE_ENDIAN=0 -D_YUGA_BIG_ENDIAN=1 -Wno-missing-prototypes
+
+OBJECTS=divsi3.o modsi3.o comparesf2.o comparedf2.o negsf2.o negdf2.o addsf3.o subsf3.o mulsf3.o divsf3.o lshrdi3.o muldi3.o divdi3.o ashldi3.o ashrdi3.o udivmoddi4.o \
+ floatsisf.o floatunsisf.o fixsfsi.o fixdfdi.o fixunssfsi.o fixunsdfdi.o adddf3.o subdf3.o muldf3.o divdf3.o floatsidf.o floatunsidf.o floatdidf.o fixdfsi.o fixunsdfsi.o \
+ clzsi2.o ctzsi2.o udivdi3.o umoddi3.o moddi3.o ucmpdi2.o
+
+all: libcompiler_rt.a
+
+libcompiler_rt.a: $(OBJECTS)
+ $(AR) crs libcompiler_rt.a $(OBJECTS)
+
+%.o: $(SOC_DIRECTORY)/software/compiler_rt/lib/builtins/%.c
+ $(compile)
+
+.PHONY: all clean
+
+clean:
+ $(RM) $(OBJECTS) $(OBJECTS:.o=.ts) $(OBJECTS:.o=.d) libcompiler_rt.a .*~ *~
--- /dev/null
+include ../include/generated/variables.mak
+include $(SOC_DIRECTORY)/software/common.mak
+
+# lm32 is not supported
+ifeq ($(CPU),lm32)
+ ALL_TARGET=
+else
+ ALL_TARGET=libdyld.a
+endif
+
+COMMONFLAGS += -I$(SOC_DIRECTORY)/software/include/dyld
+
+OBJECTS=dyld.o
+
+all: $(ALL_TARGET)
+
+libdyld.a: $(OBJECTS)
+ $(AR) crs libdyld.a $(OBJECTS)
+
+%.o: $(LIBDYLD_DIRECTORY)/%.c
+ $(compile)
+
+.PHONY: all clean
+
+clean:
+ $(RM) $(OBJECTS) libdyld.a .*~ *~
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <dyld.h>
+
+static int fixup_rela(struct dyld_info *info, const Elf32_Rela *rela,
+ Elf32_Addr (*resolve_import)(const char *),
+ const char **error_out)
+{
+ const Elf32_Sym *sym = NULL;
+ if(ELF32_R_SYM(rela->r_info) != 0)
+ sym = &info->symtab[ELF32_R_SYM(rela->r_info)];
+ Elf32_Addr value;
+
+ switch(ELF32_R_TYPE(rela->r_info)) {
+ case R_OR1K_NONE:
+ return 1; // Does nothing.
+
+ case R_OR1K_RELATIVE:
+ value = info->base + rela->r_addend;
+ break;
+
+ case R_OR1K_32:
+ case R_OR1K_GLOB_DAT:
+ case R_OR1K_JMP_SLOT:
+ value = (Elf32_Addr)dyld_lookup(&info->strtab[sym->st_name], info);
+ if(value != 0)
+ break;
+
+ value = resolve_import(&info->strtab[sym->st_name]);
+ if(value == 0) {
+ static char error[256];
+ snprintf(error, sizeof(error),
+ "ELF object has an unresolved symbol: %s",
+ &info->strtab[sym->st_name]);
+ *error_out = error;
+ return 0;
+ }
+ break;
+
+ default:
+ *error_out = "ELF object uses an unsupported relocation type";
+ return 0;
+ }
+
+ memcpy((Elf32_Addr*)(info->base + rela->r_offset), &value,
+ sizeof(Elf32_Addr));
+
+ return 1;
+}
+
+int dyld_load(const void *shlib, Elf32_Addr base,
+ Elf32_Addr (*resolve_import)(const char *),
+ struct dyld_info *info, const char **error_out)
+{
+ const Elf32_Ehdr *ehdr = (const Elf32_Ehdr *)shlib;
+
+ const unsigned char expected_ident[EI_NIDENT] = {
+ ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
+ ELFCLASS32, ELFDATA2MSB, EV_CURRENT,
+ ELFOSABI_NONE, /* ABI version */ 0
+ };
+ if(memcmp(ehdr->e_ident, expected_ident, EI_NIDENT) ||
+ ehdr->e_type != ET_DYN) {
+ *error_out = "ELF object is not a shared library";
+ return 0;
+ }
+
+#ifdef __or1k__
+ if(ehdr->e_machine != EM_OPENRISC) {
+ *error_out = "ELF object does not contain OpenRISC machine code";
+ return 0;
+ }
+#else
+#error Unsupported architecture
+#endif
+
+ const Elf32_Phdr *phdr = (const Elf32_Phdr *)((intptr_t)shlib + ehdr->e_phoff);
+ const Elf32_Dyn *dyn = NULL;
+ for(int i = 0; i < ehdr->e_phnum; i++) {
+ if(phdr[i].p_type == PT_DYNAMIC)
+ dyn = (const Elf32_Dyn *)((intptr_t)shlib + phdr[i].p_offset);
+
+ memcpy((void*)(base + phdr[i].p_vaddr),
+ (const void*)((intptr_t)shlib + phdr[i].p_offset),
+ phdr[i].p_filesz);
+ }
+
+ if(dyn == NULL) {
+ *error_out = "ELF object does not have a PT_DYNAMIC header";
+ return 0;
+ }
+
+ const char *strtab = NULL;
+ const Elf32_Sym *symtab = NULL;
+ const Elf32_Rela *rela = NULL, *pltrel = NULL;
+ const Elf32_Word *hash = NULL;
+ Elf32_Word init = 0;
+ size_t syment = sizeof(Elf32_Sym), relaent = sizeof(Elf32_Rela),
+ relanum = 0, pltrelnum = 0;
+ while(dyn->d_tag != DT_NULL) {
+ switch(dyn->d_tag) {
+ case DT_STRTAB: strtab = (const char *)(base + dyn->d_un.d_ptr); break;
+ case DT_SYMTAB: symtab = (const Elf32_Sym *)(base + dyn->d_un.d_ptr); break;
+ case DT_SYMENT: syment = dyn->d_un.d_val; break;
+ case DT_RELA: rela = (const Elf32_Rela *)(base + dyn->d_un.d_ptr); break;
+ case DT_RELAENT: relaent = dyn->d_un.d_val; break;
+ case DT_RELASZ: relanum = dyn->d_un.d_val / sizeof(Elf32_Rela); break;
+ case DT_JMPREL: pltrel = (const Elf32_Rela *)(base + dyn->d_un.d_ptr); break;
+ case DT_PLTRELSZ: pltrelnum = dyn->d_un.d_val / sizeof(Elf32_Rela); break;
+ case DT_HASH: hash = (const Elf32_Word *)(base + dyn->d_un.d_ptr); break;
+ case DT_INIT: init = dyn->d_un.d_val; break;
+
+ case DT_REL:
+ *error_out = "ELF object uses Rel relocations, which are not supported";
+ return 0;
+ }
+
+ ++dyn;
+ }
+
+ if(symtab == NULL || syment == 0 || strtab == NULL) {
+ *error_out = "ELF object must contain a symbol table";
+ return 0;
+ }
+
+ if(syment != sizeof(Elf32_Sym) || relaent != sizeof(Elf32_Rela)) {
+ *error_out = "ELF object uses an unknown format for symbols and relocations";
+ return 0;
+ }
+
+ info->base = base;
+ info->init = (void*)(base + init);
+ info->strtab = strtab;
+ info->symtab = symtab;
+ info->hash.nbucket = hash[0];
+ info->hash.nchain = hash[1];
+ info->hash.bucket = &hash[2];
+ info->hash.chain = &hash[2 + info->hash.nbucket];
+
+ for(int i = 0; i < relanum; i++) {
+ if(!fixup_rela(info, &rela[i], resolve_import, error_out))
+ return 0;
+ }
+
+ for(int i = 0; i < pltrelnum; i++) {
+ if(!fixup_rela(info, &pltrel[i], resolve_import, error_out))
+ return 0;
+ }
+
+ return 1;
+}
+
+static unsigned long elf_hash(const unsigned char *name)
+{
+ unsigned long h = 0, g;
+ while(*name) {
+ h = (h << 4) + *name++;
+ if((g = h & 0xf0000000)) {
+ h ^= g >> 24;
+ h &= ~g;
+ }
+ }
+ return h;
+}
+
+void *dyld_lookup(const char *symbol, struct dyld_info *info)
+{
+ unsigned hash = elf_hash((const unsigned char*) symbol);
+ unsigned index = info->hash.bucket[hash % info->hash.nbucket];
+ while(strcmp(&info->strtab[info->symtab[index].st_name], symbol)) {
+ if(index == STN_UNDEF)
+ return NULL;
+ index = info->hash.chain[index];
+ }
+
+ Elf32_Addr value = info->symtab[index].st_value;
+ if(value != 0)
+ return (void*)(info->base + value);
+ else
+ return NULL;
+}
--- /dev/null
+include ../include/generated/variables.mak
+include $(SOC_DIRECTORY)/software/common.mak
+
+OBJECTS=microudp.o tftp.o
+
+all: libnet.a
+
+libnet.a: $(OBJECTS)
+ $(AR) crs libnet.a $(OBJECTS)
+
+%.o: $(LIBNET_DIRECTORY)/%.c
+ $(compile)
+
+%.o: %.S
+ $(assemble)
+
+.PHONY: all clean
+
+clean:
+ $(RM) $(OBJECTS) libnet.a .*~ *~
--- /dev/null
+#include <generated/csr.h>
+#ifdef CSR_ETHMAC_BASE
+
+#include <stdio.h>
+#include <system.h>
+#include <crc.h>
+#include <hw/flags.h>
+#include <hw/ethmac_mem.h>
+
+#include <net/microudp.h>
+
+#define ETHERTYPE_ARP 0x0806
+#define ETHERTYPE_IP 0x0800
+
+#ifdef CSR_ETHMAC_PREAMBLE_CRC_ADDR
+#define HW_PREAMBLE_CRC
+#endif
+
+struct ethernet_header {
+#ifndef HW_PREAMBLE_CRC
+ unsigned char preamble[8];
+#endif
+ unsigned char destmac[6];
+ unsigned char srcmac[6];
+ unsigned short ethertype;
+} __attribute__((packed));
+
+static void fill_eth_header(struct ethernet_header *h, const unsigned char *destmac, const unsigned char *srcmac, unsigned short ethertype)
+{
+ int i;
+
+#ifndef HW_PREAMBLE_CRC
+ for(i=0;i<7;i++)
+ h->preamble[i] = 0x55;
+ h->preamble[7] = 0xd5;
+#endif
+ for(i=0;i<6;i++)
+ h->destmac[i] = destmac[i];
+ for(i=0;i<6;i++)
+ h->srcmac[i] = srcmac[i];
+ h->ethertype = ethertype;
+}
+
+#define ARP_HWTYPE_ETHERNET 0x0001
+#define ARP_PROTO_IP 0x0800
+#ifndef HW_PREAMBLE_CRC
+#define ARP_PACKET_LENGTH 68
+#else
+#define ARP_PACKET_LENGTH 60
+#endif
+
+#define ARP_OPCODE_REQUEST 0x0001
+#define ARP_OPCODE_REPLY 0x0002
+
+struct arp_frame {
+ unsigned short hwtype;
+ unsigned short proto;
+ unsigned char hwsize;
+ unsigned char protosize;
+ unsigned short opcode;
+ unsigned char sender_mac[6];
+ unsigned int sender_ip;
+ unsigned char target_mac[6];
+ unsigned int target_ip;
+ unsigned char padding[18];
+} __attribute__((packed));
+
+#define IP_IPV4 0x45
+#define IP_DONT_FRAGMENT 0x4000
+#define IP_TTL 64
+#define IP_PROTO_UDP 0x11
+
+struct ip_header {
+ unsigned char version;
+ unsigned char diff_services;
+ unsigned short total_length;
+ unsigned short identification;
+ unsigned short fragment_offset;
+ unsigned char ttl;
+ unsigned char proto;
+ unsigned short checksum;
+ unsigned int src_ip;
+ unsigned int dst_ip;
+} __attribute__((packed));
+
+struct udp_header {
+ unsigned short src_port;
+ unsigned short dst_port;
+ unsigned short length;
+ unsigned short checksum;
+} __attribute__((packed));
+
+struct udp_frame {
+ struct ip_header ip;
+ struct udp_header udp;
+ char payload[];
+} __attribute__((packed));
+
+struct ethernet_frame {
+ struct ethernet_header eth_header;
+ union {
+ struct arp_frame arp;
+ struct udp_frame udp;
+ } contents;
+} __attribute__((packed));
+
+typedef union {
+ struct ethernet_frame frame;
+ unsigned char raw[1532];
+} ethernet_buffer;
+
+
+static unsigned int rxslot;
+static unsigned int rxlen;
+static ethernet_buffer *rxbuffer;
+static ethernet_buffer *rxbuffer0;
+static ethernet_buffer *rxbuffer1;
+static unsigned int txslot;
+static unsigned int txlen;
+static ethernet_buffer *txbuffer;
+static ethernet_buffer *txbuffer0;
+static ethernet_buffer *txbuffer1;
+
+static void send_packet(void)
+{
+#ifndef HW_PREAMBLE_CRC
+ unsigned int crc;
+ crc = crc32(&txbuffer->raw[8], txlen-8);
+ txbuffer->raw[txlen ] = (crc & 0xff);
+ txbuffer->raw[txlen+1] = (crc & 0xff00) >> 8;
+ txbuffer->raw[txlen+2] = (crc & 0xff0000) >> 16;
+ txbuffer->raw[txlen+3] = (crc & 0xff000000) >> 24;
+ txlen += 4;
+#endif
+ ethmac_sram_reader_slot_write(txslot);
+ ethmac_sram_reader_length_write(txlen);
+ while(!(ethmac_sram_reader_ready_read()));
+ ethmac_sram_reader_start_write(1);
+ txslot = (txslot+1)%2;
+ if (txslot)
+ txbuffer = txbuffer1;
+ else
+ txbuffer = txbuffer0;
+}
+
+static unsigned char my_mac[6];
+static unsigned int my_ip;
+
+/* ARP cache - one entry only */
+static unsigned char cached_mac[6];
+static unsigned int cached_ip;
+
+static void process_arp(void)
+{
+ const struct arp_frame *rx_arp = &rxbuffer->frame.contents.arp;
+ struct arp_frame *tx_arp = &txbuffer->frame.contents.arp;
+
+ if(rxlen < ARP_PACKET_LENGTH) return;
+ if(rx_arp->hwtype != ARP_HWTYPE_ETHERNET) return;
+ if(rx_arp->proto != ARP_PROTO_IP) return;
+ if(rx_arp->hwsize != 6) return;
+ if(rx_arp->protosize != 4) return;
+ if(rx_arp->opcode == ARP_OPCODE_REPLY) {
+ if(rx_arp->sender_ip == cached_ip) {
+ int i;
+ for(i=0;i<6;i++)
+ cached_mac[i] = rx_arp->sender_mac[i];
+ }
+ return;
+ }
+ if(rx_arp->opcode == ARP_OPCODE_REQUEST) {
+ if(rx_arp->target_ip == my_ip) {
+ int i;
+
+ fill_eth_header(&txbuffer->frame.eth_header,
+ rx_arp->sender_mac,
+ my_mac,
+ ETHERTYPE_ARP);
+ txlen = ARP_PACKET_LENGTH;
+ tx_arp->hwtype = ARP_HWTYPE_ETHERNET;
+ tx_arp->proto = ARP_PROTO_IP;
+ tx_arp->hwsize = 6;
+ tx_arp->protosize = 4;
+ tx_arp->opcode = ARP_OPCODE_REPLY;
+ tx_arp->sender_ip = my_ip;
+ for(i=0;i<6;i++)
+ tx_arp->sender_mac[i] = my_mac[i];
+ tx_arp->target_ip = rx_arp->sender_ip;
+ for(i=0;i<6;i++)
+ tx_arp->target_mac[i] = rx_arp->sender_mac[i];
+ send_packet();
+ }
+ return;
+ }
+}
+
+static const unsigned char broadcast[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+
+int microudp_arp_resolve(unsigned int ip)
+{
+ struct arp_frame *arp = &txbuffer->frame.contents.arp;
+ int i;
+ int tries;
+ int timeout;
+
+ if(cached_ip == ip) {
+ for(i=0;i<6;i++)
+ if(cached_mac[i]) return 1;
+ }
+ cached_ip = ip;
+ for(i=0;i<6;i++)
+ cached_mac[i] = 0;
+
+ for(tries=0;tries<5;tries++) {
+ /* Send an ARP request */
+ fill_eth_header(&txbuffer->frame.eth_header,
+ broadcast,
+ my_mac,
+ ETHERTYPE_ARP);
+ txlen = ARP_PACKET_LENGTH;
+ arp->hwtype = ARP_HWTYPE_ETHERNET;
+ arp->proto = ARP_PROTO_IP;
+ arp->hwsize = 6;
+ arp->protosize = 4;
+ arp->opcode = ARP_OPCODE_REQUEST;
+ arp->sender_ip = my_ip;
+ for(i=0;i<6;i++)
+ arp->sender_mac[i] = my_mac[i];
+ arp->target_ip = ip;
+ for(i=0;i<6;i++)
+ arp->target_mac[i] = 0;
+ send_packet();
+
+ /* Do we get a reply ? */
+ for(timeout=0;timeout<2000000;timeout++) {
+ microudp_service();
+ for(i=0;i<6;i++)
+ if(cached_mac[i]) return 1;
+ }
+ }
+
+ return 0;
+}
+
+static unsigned short ip_checksum(unsigned int r, void *buffer, unsigned int length, int complete)
+{
+ unsigned char *ptr;
+ unsigned int i;
+
+ ptr = (unsigned char *)buffer;
+ length >>= 1;
+
+ for(i=0;i<length;i++)
+ r += ((unsigned int)(ptr[2*i]) << 8)|(unsigned int)(ptr[2*i+1]) ;
+
+ /* Add overflows */
+ while(r >> 16)
+ r = (r & 0xffff) + (r >> 16);
+
+ if(complete) {
+ r = ~r;
+ r &= 0xffff;
+ if(r == 0) r = 0xffff;
+ }
+ return r;
+}
+
+void *microudp_get_tx_buffer(void)
+{
+ return txbuffer->frame.contents.udp.payload;
+}
+
+struct pseudo_header {
+ unsigned int src_ip;
+ unsigned int dst_ip;
+ unsigned char zero;
+ unsigned char proto;
+ unsigned short length;
+} __attribute__((packed));
+
+int microudp_send(unsigned short src_port, unsigned short dst_port, unsigned int length)
+{
+ struct pseudo_header h;
+ unsigned int r;
+
+ if((cached_mac[0] == 0) && (cached_mac[1] == 0) && (cached_mac[2] == 0)
+ && (cached_mac[3] == 0) && (cached_mac[4] == 0) && (cached_mac[5] == 0))
+ return 0;
+
+ txlen = length + sizeof(struct ethernet_header) + sizeof(struct udp_frame);
+ if(txlen < ARP_PACKET_LENGTH) txlen = ARP_PACKET_LENGTH;
+
+ fill_eth_header(&txbuffer->frame.eth_header,
+ cached_mac,
+ my_mac,
+ ETHERTYPE_IP);
+
+ txbuffer->frame.contents.udp.ip.version = IP_IPV4;
+ txbuffer->frame.contents.udp.ip.diff_services = 0;
+ txbuffer->frame.contents.udp.ip.total_length = length + sizeof(struct udp_frame);
+ txbuffer->frame.contents.udp.ip.identification = 0;
+ txbuffer->frame.contents.udp.ip.fragment_offset = IP_DONT_FRAGMENT;
+ txbuffer->frame.contents.udp.ip.ttl = IP_TTL;
+ h.proto = txbuffer->frame.contents.udp.ip.proto = IP_PROTO_UDP;
+ txbuffer->frame.contents.udp.ip.checksum = 0;
+ h.src_ip = txbuffer->frame.contents.udp.ip.src_ip = my_ip;
+ h.dst_ip = txbuffer->frame.contents.udp.ip.dst_ip = cached_ip;
+ txbuffer->frame.contents.udp.ip.checksum = ip_checksum(0, &txbuffer->frame.contents.udp.ip,
+ sizeof(struct ip_header), 1);
+
+ txbuffer->frame.contents.udp.udp.src_port = src_port;
+ txbuffer->frame.contents.udp.udp.dst_port = dst_port;
+ h.length = txbuffer->frame.contents.udp.udp.length = length + sizeof(struct udp_header);
+ txbuffer->frame.contents.udp.udp.checksum = 0;
+
+ h.zero = 0;
+ r = ip_checksum(0, &h, sizeof(struct pseudo_header), 0);
+ if(length & 1) {
+ txbuffer->frame.contents.udp.payload[length] = 0;
+ length++;
+ }
+ r = ip_checksum(r, &txbuffer->frame.contents.udp.udp,
+ sizeof(struct udp_header)+length, 1);
+ txbuffer->frame.contents.udp.udp.checksum = r;
+
+ send_packet();
+
+ return 1;
+}
+
+static udp_callback rx_callback;
+
+static void process_ip(void)
+{
+ if(rxlen < (sizeof(struct ethernet_header)+sizeof(struct udp_frame))) return;
+ /* We don't verify UDP and IP checksums and rely on the Ethernet checksum solely */
+ if(rxbuffer->frame.contents.udp.ip.version != IP_IPV4) return;
+ // check disabled for QEMU compatibility
+ //if(rxbuffer->frame.contents.udp.ip.diff_services != 0) return;
+ if(rxbuffer->frame.contents.udp.ip.total_length < sizeof(struct udp_frame)) return;
+ // check disabled for QEMU compatibility
+ //if(rxbuffer->frame.contents.udp.ip.fragment_offset != IP_DONT_FRAGMENT) return;
+ if(rxbuffer->frame.contents.udp.ip.proto != IP_PROTO_UDP) return;
+ if(rxbuffer->frame.contents.udp.ip.dst_ip != my_ip) return;
+ if(rxbuffer->frame.contents.udp.udp.length < sizeof(struct udp_header)) return;
+
+ if(rx_callback)
+ rx_callback(rxbuffer->frame.contents.udp.ip.src_ip, rxbuffer->frame.contents.udp.udp.src_port, rxbuffer->frame.contents.udp.udp.dst_port, rxbuffer->frame.contents.udp.payload, rxbuffer->frame.contents.udp.udp.length-sizeof(struct udp_header));
+}
+
+void microudp_set_callback(udp_callback callback)
+{
+ rx_callback = callback;
+}
+
+static void process_frame(void)
+{
+ flush_cpu_dcache();
+
+#ifndef HW_PREAMBLE_CRC
+ int i;
+ for(i=0;i<7;i++)
+ if(rxbuffer->frame.eth_header.preamble[i] != 0x55) return;
+ if(rxbuffer->frame.eth_header.preamble[7] != 0xd5) return;
+#endif
+
+#ifndef HW_PREAMBLE_CRC
+ unsigned int received_crc;
+ unsigned int computed_crc;
+ received_crc = ((unsigned int)rxbuffer->raw[rxlen-1] << 24)
+ |((unsigned int)rxbuffer->raw[rxlen-2] << 16)
+ |((unsigned int)rxbuffer->raw[rxlen-3] << 8)
+ |((unsigned int)rxbuffer->raw[rxlen-4]);
+ computed_crc = crc32(&rxbuffer->raw[8], rxlen-12);
+ if(received_crc != computed_crc) return;
+
+ rxlen -= 4; /* strip CRC here to be consistent with TX */
+#endif
+
+ if(rxbuffer->frame.eth_header.ethertype == ETHERTYPE_ARP) process_arp();
+ else if(rxbuffer->frame.eth_header.ethertype == ETHERTYPE_IP) process_ip();
+}
+
+void microudp_start(const unsigned char *macaddr, unsigned int ip)
+{
+ int i;
+ ethmac_sram_reader_ev_pending_write(ETHMAC_EV_SRAM_READER);
+ ethmac_sram_writer_ev_pending_write(ETHMAC_EV_SRAM_WRITER);
+
+ rxbuffer0 = (ethernet_buffer *)ETHMAC_RX0_BASE;
+ rxbuffer1 = (ethernet_buffer *)ETHMAC_RX1_BASE;
+ txbuffer0 = (ethernet_buffer *)ETHMAC_TX0_BASE;
+ txbuffer1 = (ethernet_buffer *)ETHMAC_TX1_BASE;
+
+ rxslot = 0;
+ txslot = 0;
+
+ rxbuffer = rxbuffer0;
+ txbuffer = txbuffer0;
+
+ for(i=0;i<6;i++)
+ my_mac[i] = macaddr[i];
+ my_ip = ip;
+
+ cached_ip = 0;
+ for(i=0;i<6;i++)
+ cached_mac[i] = 0;
+
+ rx_callback = (udp_callback)0;
+}
+
+void microudp_service(void)
+{
+ if(ethmac_sram_writer_ev_pending_read() & ETHMAC_EV_SRAM_WRITER) {
+ rxslot = ethmac_sram_writer_slot_read();
+ rxlen = ethmac_sram_writer_length_read();
+ if (rxslot)
+ rxbuffer = rxbuffer1;
+ else
+ rxbuffer = rxbuffer0;
+ process_frame();
+ ethmac_sram_writer_ev_pending_write(ETHMAC_EV_SRAM_WRITER);
+ }
+}
+
+static void busy_wait(unsigned int ds)
+{
+ timer0_en_write(0);
+ timer0_reload_write(0);
+ timer0_load_write(identifier_frequency_read()/10*ds);
+ timer0_en_write(1);
+ timer0_update_value_write(1);
+ while(timer0_value_read()) timer0_update_value_write(1);
+}
+
+void eth_init(void)
+{
+ ethphy_crg_reset_write(0);
+ busy_wait(2);
+ /* that pesky ethernet PHY needs two resets at times... */
+ ethphy_crg_reset_write(1);
+ busy_wait(2);
+ ethphy_crg_reset_write(0);
+ busy_wait(2);
+}
+
+#ifdef CSR_ETHPHY_MODE_DETECTION_MODE_ADDR
+void eth_mode(void)
+{
+ printf("Ethernet phy mode: ");
+ if (ethphy_mode_detection_mode_read())
+ printf("MII");
+ else
+ printf("GMII");
+ printf("\n");
+}
+#endif
+
+#endif
--- /dev/null
+#include <stdint.h>
+#include <string.h>
+
+#include <net/microudp.h>
+#include <net/tftp.h>
+
+#define PORT_OUT 69
+#define PORT_IN 7642
+
+enum {
+ TFTP_RRQ = 1, /* Read request */
+ TFTP_WRQ = 2, /* Write request */
+ TFTP_DATA = 3, /* Data */
+ TFTP_ACK = 4, /* Acknowledgment */
+ TFTP_ERROR = 5, /* Error */
+};
+
+#define BLOCK_SIZE 512 /* block size in bytes */
+
+
+static int format_request(uint8_t *buf, uint16_t op, const char *filename)
+{
+ int len = strlen(filename);
+
+ *buf++ = op >> 8; /* Opcode */
+ *buf++ = op;
+ memcpy(buf, filename, len);
+ buf += len;
+ *buf++ = 0x00;
+ *buf++ = 'o';
+ *buf++ = 'c';
+ *buf++ = 't';
+ *buf++ = 'e';
+ *buf++ = 't';
+ *buf++ = 0x00;
+ return 9+strlen(filename);
+}
+
+static int format_ack(uint8_t *buf, uint16_t block)
+{
+ *buf++ = 0x00; /* Opcode: Ack */
+ *buf++ = TFTP_ACK;
+ *buf++ = (block & 0xff00) >> 8;
+ *buf++ = (block & 0x00ff);
+ return 4;
+}
+
+static int format_data(uint8_t *buf, uint16_t block, const void *data, int len)
+{
+ *buf++ = 0x00; /* Opcode: Data*/
+ *buf++ = TFTP_DATA;
+ *buf++ = (block & 0xff00) >> 8;
+ *buf++ = (block & 0x00ff);
+ memcpy(buf, data, len);
+ return len+4;
+}
+
+static uint8_t *packet_data;
+static int total_length;
+static int transfer_finished;
+static uint8_t *dst_buffer;
+static int last_ack; /* signed, so we can use -1 */
+static uint16_t data_port;
+
+static void rx_callback(uint32_t src_ip, uint16_t src_port,
+ uint16_t dst_port, void *_data, unsigned int length)
+{
+ uint8_t *data = _data;
+ uint16_t opcode;
+ uint16_t block;
+ int i;
+ int offset;
+
+ if(length < 4) return;
+ if(dst_port != PORT_IN) return;
+ opcode = data[0] << 8 | data[1];
+ block = data[2] << 8 | data[3];
+ if(opcode == TFTP_ACK) { /* Acknowledgement */
+ data_port = src_port;
+ last_ack = block;
+ return;
+ }
+ if(block < 1) return;
+ if(opcode == TFTP_DATA) { /* Data */
+ length -= 4;
+ offset = (block-1)*BLOCK_SIZE;
+ for(i=0;i<length;i++)
+ dst_buffer[offset+i] = data[i+4];
+ total_length += length;
+ if(length < BLOCK_SIZE)
+ transfer_finished = 1;
+
+ packet_data = microudp_get_tx_buffer();
+ length = format_ack(packet_data, block);
+ microudp_send(PORT_IN, src_port, length);
+ }
+ if(opcode == TFTP_ERROR) { /* Error */
+ total_length = -1;
+ transfer_finished = 1;
+ }
+}
+
+int tftp_get(uint32_t ip, const char *filename, void *buffer)
+{
+ int len;
+ int tries;
+ int i;
+ int length_before;
+
+ if(!microudp_arp_resolve(ip))
+ return -1;
+
+ microudp_set_callback(rx_callback);
+
+ dst_buffer = buffer;
+
+ total_length = 0;
+ transfer_finished = 0;
+ tries = 5;
+ while(1) {
+ packet_data = microudp_get_tx_buffer();
+ len = format_request(packet_data, TFTP_RRQ, filename);
+ microudp_send(PORT_IN, PORT_OUT, len);
+ for(i=0;i<2000000;i++) {
+ microudp_service();
+ if((total_length > 0) || transfer_finished) break;
+ }
+ if((total_length > 0) || transfer_finished) break;
+ tries--;
+ if(tries == 0) {
+ microudp_set_callback(NULL);
+ return -1;
+ }
+ }
+
+ length_before = total_length;
+ while(!transfer_finished) {
+ if(length_before != total_length) {
+ i = 12000000;
+ length_before = total_length;
+ }
+ if(i-- == 0) {
+ microudp_set_callback(NULL);
+ return -1;
+ }
+ microudp_service();
+ }
+
+ microudp_set_callback(NULL);
+
+ return total_length;
+}
+
+int tftp_put(uint32_t ip, const char *filename, const void *buffer, int size)
+{
+ int len, send;
+ int tries;
+ int i;
+ int block = 0, sent = 0;
+
+ if(!microudp_arp_resolve(ip))
+ return -1;
+
+ microudp_set_callback(rx_callback);
+
+ packet_data = microudp_get_tx_buffer();
+
+ total_length = 0;
+ transfer_finished = 0;
+ tries = 5;
+ while(1) {
+ packet_data = microudp_get_tx_buffer();
+ len = format_request(packet_data, TFTP_WRQ, filename);
+ microudp_send(PORT_IN, PORT_OUT, len);
+ for(i=0;i<2000000;i++) {
+ last_ack = -1;
+ microudp_service();
+ if(last_ack == block)
+ goto send_data;
+ if(transfer_finished)
+ goto fail;
+ }
+ tries--;
+ if(tries == 0)
+ goto fail;
+ }
+
+send_data:
+ do {
+ block++;
+ send = sent+BLOCK_SIZE > size ? size-sent : BLOCK_SIZE;
+ tries = 5;
+ while(1) {
+ packet_data = microudp_get_tx_buffer();
+ len = format_data(packet_data, block, buffer, send);
+ microudp_send(PORT_IN, data_port, len);
+ for(i=0;i<12000000;i++) {
+ microudp_service();
+ if(transfer_finished)
+ goto fail;
+ if(last_ack == block)
+ goto next;
+ }
+ if (!--tries)
+ goto fail;
+ }
+next:
+ sent += send;
+ buffer += send;
+ } while (send == BLOCK_SIZE);
+
+ microudp_set_callback(NULL);
+
+ return sent;
+
+fail:
+ microudp_set_callback(NULL);
+ return -1;
+}
--- /dev/null
+include ../include/generated/variables.mak
+include $(SOC_DIRECTORY)/software/common.mak
+
+# lm32 is not supported
+ifeq ($(CPU),lm32)
+ ALL_TARGET=
+else
+ ALL_TARGET=libunwind.a
+endif
+
+COMMONFLAGS+=-integrated-as \
+ -I. -I$(SOC_DIRECTORY)/software/include/dyld/ -I$(SOC_DIRECTORY)/software/unwinder/include/ \
+ -I$(LIBUNWIND_DIRECTORY) \
+ -D__ELF__ -D__linux__ -D_LIBUNWIND_NO_HEAP -DNDEBUG
+
+OBJECTS=UnwindRegistersSave.o UnwindRegistersRestore.o UnwindLevel1.o libunwind.o
+
+all: $(ALL_TARGET)
+
+libunwind.a: $(OBJECTS)
+ $(AR) crs libunwind.a $(OBJECTS)
+
+%.o: $(SOC_DIRECTORY)/software/unwinder/src/%.cpp
+ $(compilexx)
+
+%.o: $(SOC_DIRECTORY)/software/unwinder/src/%.c
+ $(compile)
+
+%.o: $(SOC_DIRECTORY)/software/unwinder/src/%.S
+ $(assemble)
+
+.PHONY: clean
+
+clean:
+ $(RM) $(OBJECTS) libunwind.a .*~ *~
--- /dev/null
+#define LIBCXXABI_ARM_EHABI 0
--- /dev/null
+MSCDIR=../..
+include $(MSCDIR)/software/common.mak
+
+OBJECTS=isr.o main.o
+
+all: memtest.bin
+
+%.bin: %.elf
+ $(OBJCOPY) -O binary $< $@
+ chmod -x $@
+
+memtest.elf: $(OBJECTS) libs
+
+%.elf:
+ $(LD) $(LDFLAGS) \
+ -T $(MSCDIR)/software/libbase/linker-sdram.ld \
+ -N -o $@ \
+ $(MSCDIR)/software/libbase/crt0-$(CPU).o \
+ $(OBJECTS) \
+ -L$(MSCDIR)/software/libbase \
+ -L$(MSCDIR)/software/libcompiler-rt \
+ -lbase -lcompiler-rt
+ chmod -x $@
+
+main.o: main.c
+ $(compile)
+
+%.o: %.c
+ $(compile)
+
+%.o: %.S
+ $(assemble)
+
+libs:
+ $(MAKE) -C $(MSCDIR)/software/libcompiler-rt
+ $(MAKE) -C $(MSCDIR)/software/libbase
+
+load: memtest.bin
+ $(MAKE) -C $(MSCDIR)/tools
+ $(MSCDIR)/tools/flterm --port /dev/ttyUSB0 --kernel memtest.bin
+
+
+clean:
+ $(RM) $(OBJECTS) memtest.elf memtest.bin
+ $(RM) .*~ *~
+
+.PHONY: all main.o clean libs load
--- /dev/null
+#include <generated/csr.h>
+#include <irq.h>
+#include <uart.h>
+
+void isr(void);
+void isr(void)
+{
+ unsigned int irqs;
+
+ irqs = irq_pending() & irq_getmask();
+
+ if(irqs & (1 << UART_INTERRUPT))
+ uart_isr();
+}
--- /dev/null
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <irq.h>
+#include <uart.h>
+#include <time.h>
+#include <generated/csr.h>
+#include <generated/mem.h>
+#include <hw/flags.h>
+#include <console.h>
+#include <system.h>
+
+static unsigned int log2(unsigned int v)
+{
+ unsigned int r;
+ r = 0;
+ while(v>>=1) r++;
+ return r;
+}
+
+static void membw_service(void)
+{
+ static int last_event;
+ unsigned long long int nr, nw;
+ unsigned long long int f;
+ unsigned int rdb, wrb;
+ unsigned int dw;
+
+ if(elapsed(&last_event, identifier_frequency_read())) {
+ sdram_controller_bandwidth_update_write(1);
+ nr = sdram_controller_bandwidth_nreads_read();
+ nw = sdram_controller_bandwidth_nwrites_read();
+ f = identifier_frequency_read();
+ dw = sdram_controller_bandwidth_data_width_read();
+ rdb = (nr*f >> (24 - log2(dw)))/1000000ULL;
+ wrb = (nw*f >> (24 - log2(dw)))/1000000ULL;
+ printf("read:%5dMbps write:%5dMbps all:%5dMbps\n", rdb, wrb, rdb + wrb);
+ }
+}
+
+//#define DEBUG
+
+static void memtest_service(void)
+{
+ static unsigned int test_buffer[(MAIN_RAM_SIZE/2)/4] __attribute__((aligned(16)));
+ static unsigned char reading;
+ static unsigned int err, total_err;
+#ifdef DEBUG
+ int i;
+#endif
+
+ if(reading) {
+ if(!memtest_w_busy_read()) {
+#ifdef DEBUG
+ flush_l2_cache();
+ flush_cpu_dcache();
+ printf("starting read\n");
+ for(i=0;i<64;i++) {
+ printf("%08x", test_buffer[i]);
+ if((i % 4) == 3)
+ printf("\n");
+ }
+#endif
+ memtest_r_reset_write(1);
+ memtest_r_base_write((unsigned int)test_buffer);
+ memtest_r_length_write(sizeof(test_buffer));
+ memtest_r_shoot_write(1);
+ reading = 0;
+ }
+ } else {
+ if(!memtest_r_busy_read()) {
+ err = memtest_r_error_count_read();
+ total_err += err;
+ printf("err=%d\t\ttotal=%d\n", err, total_err);
+ memtest_w_reset_write(1);
+ memtest_w_base_write((unsigned int)test_buffer);
+ memtest_w_length_write(sizeof(test_buffer));
+ memtest_w_shoot_write(1);
+ reading = 1;
+ }
+ }
+}
+
+int main(void)
+{
+ irq_setmask(0);
+ irq_setie(1);
+ uart_init();
+
+ puts("Memory testing software built "__DATE__" "__TIME__"\n");
+
+ if((memtest_w_magic_read() != 0x361f) || (memtest_r_magic_read() != 0x361f)) {
+ printf("Memory test cores not detected\n");
+ while(1);
+ }
+
+ time_init();
+
+ flush_l2_cache();
+ while(1) {
+ memtest_service();
+ membw_service();
+ }
+
+ return 0;
+}
--- /dev/null
+Subproject commit 8b1196692d823a090a9879a695050baa7acc39ee
--- /dev/null
+#!/usr/bin/env python3
+
+import sys
+import os
+import time
+import serial
+import threading
+import argparse
+
+from serial.tools.miniterm import console, character, LF
+
+sfl_magic_len = 14
+sfl_magic_req = "sL5DdSMmkekro\n"
+sfl_magic_ack = "z6IHG7cYDID6o\n"
+
+# General commands
+sfl_cmd_abort = 0x00
+sfl_cmd_load = 0x01
+sfl_cmd_jump = 0x02
+
+
+# Replies
+sfl_ack_success = 'K'
+sfl_ack_crcerror = 'C'
+sfl_ack_unknown = 'U'
+sfl_ack_error = 'E'
+
+
+crc16_table = [
+ 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
+ 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
+ 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
+ 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
+ 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
+ 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
+ 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
+ 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
+ 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
+ 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
+ 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
+ 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
+ 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
+ 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
+ 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
+ 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
+ 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
+ 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
+ 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
+ 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
+ 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
+ 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
+ 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
+ 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
+ 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
+ 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
+ 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
+ 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
+ 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
+ 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
+ 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
+ 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
+]
+
+
+def crc16(l):
+ crc = 0
+ for d in l:
+ crc = crc16_table[((crc >> 8) ^ d) & 0xff] ^ (crc << 8)
+ return crc & 0xffff
+
+
+class SFLFrame:
+ def __init__(self):
+ self.length = None
+ self.cmd = None
+ self.payload = []
+ self.crc = None
+ self.raw = []
+
+ def compute_crc(self):
+ crc_data = []
+ crc_data.append(self.cmd)
+ for d in self.payload:
+ crc_data.append(d)
+ self.crc = crc16(crc_data)
+ return self.crc
+
+ def encode(self):
+ self.raw = []
+ self.raw.append(self.length)
+ self.compute_crc()
+ for d in self.crc.to_bytes(2, "big"):
+ self.raw.append(d)
+ self.raw.append(self.cmd)
+ for d in self.payload:
+ self.raw.append(d)
+
+
+def get_file_data(filename):
+ with open(filename, "rb") as f:
+ data = []
+ while True:
+ w = f.read(1)
+ if not w:
+ break
+ data.append(int.from_bytes(w, "big"))
+ return data
+
+
+class Flterm:
+ def __init__(self, kernel_image, kernel_address):
+ self.kernel_image = kernel_image
+ self.kernel_address = kernel_address
+
+ self.reader_alive = False
+ self.writer_alive = False
+
+ self.detect_magic_str = " "*len(sfl_magic_req)
+
+ def open(self, port, speed):
+ self.serial = serial.serial_for_url(
+ port,
+ baudrate=speed,
+ bytesize=8,
+ parity="N",
+ stopbits=1,
+ xonxoff=0,
+ timeout=0.25)
+ self.serial.flushOutput()
+ self.serial.flushInput()
+ self.serial.close() # in case port was not correctly closed
+ self.serial.open()
+
+ def close(self):
+ self.serial.close()
+
+ def write_exact(self, data):
+ if isinstance(data, str):
+ self.serial.write(bytes(data, "utf-8"))
+ else:
+ self.serial.write(serial.to_bytes(data))
+
+ def send_frame(self, frame):
+ frame.encode()
+ retry = 1
+ while retry:
+ self.write_exact(frame.raw)
+ # Get the reply from the device
+ reply = character(self.serial.read())
+ if reply == sfl_ack_success:
+ retry = 0
+ elif reply == sfl_ack_crcerror:
+ retry = 1
+ else:
+ print("[FLTERM] Got unknown reply '{}' from the device, aborting.".format(reply))
+ return 0
+ return 1
+
+ def upload(self, filename, address):
+ data = get_file_data(filename)
+ print("[FLTERM] Uploading {} ({} bytes)...".format(filename, len(data)))
+ current_address = address
+ position = 0
+ length = len(data)
+ start = time.time()
+ while len(data) != 0:
+ print("{}%\r".format(100*position//length), end="")
+ frame = SFLFrame()
+ frame_data = data[:251]
+ frame.length = len(frame_data) + 4
+ frame.cmd = sfl_cmd_load
+ for d in current_address.to_bytes(4, "big"):
+ frame.payload.append(d)
+ for d in frame_data:
+ frame.payload.append(d)
+ if self.send_frame(frame) == 0:
+ return
+ current_address += len(frame_data)
+ position += len(frame_data)
+ try:
+ data = data[251:]
+ except:
+ data = []
+ end = time.time()
+ elapsed = end - start
+ print("[FLTERM] Upload complete ({0:.1f}KB/s).".format(length/(elapsed*1024)))
+ return length
+
+ def boot(self):
+ print("[FLTERM] Booting the device.")
+ frame = SFLFrame()
+ frame.length = 4
+ frame.cmd = sfl_cmd_jump
+ for d in self.kernel_address.to_bytes(4, "big"):
+ frame.payload.append(d)
+ self.send_frame(frame)
+
+ def detect_magic(self, data):
+ if data is not "":
+ self.detect_magic_str = self.detect_magic_str[1:] + data
+ return self.detect_magic_str == sfl_magic_req
+ else:
+ return False
+
+ def answer_magic(self):
+ print("[FLTERM] Received firmware download request from the device.")
+ if os.path.exists(self.kernel_image):
+ self.write_exact(sfl_magic_ack)
+ self.upload(self.kernel_image, self.kernel_address)
+ self.boot()
+ print("[FLTERM] Done.");
+
+ def reader(self):
+ try:
+ while self.reader_alive:
+ c = character(self.serial.read())
+ if c == '\r':
+ sys.stdout.write('\n')
+ else:
+ sys.stdout.write(c)
+ sys.stdout.flush()
+
+ if self.kernel_image is not None:
+ if self.detect_magic(c):
+ self.answer_magic()
+
+ except serial.SerialException:
+ self.reader_alive = False
+ raise
+
+ def start_reader(self):
+ self.reader_alive = True
+ self.reader_thread = threading.Thread(target=self.reader)
+ self.reader_thread.setDaemon(True)
+ self.reader_thread.start()
+
+ def stop_reader(self):
+ self.reader_alive = False
+ self.reader_thread.join()
+
+ def writer(self):
+ try:
+ while self.writer_alive:
+ try:
+ b = console.getkey()
+ except KeyboardInterrupt:
+ b = serial.to_bytes([3])
+ c = character(b)
+ if c == chr(0x03):
+ self.stop()
+ elif c == '\n':
+ self.serial.write(LF)
+ else:
+ self.serial.write(b)
+ except:
+ self.writer_alive = False
+ raise
+
+ def start_writer(self):
+ self.writer_alive = True
+ self.writer_thread = threading.Thread(target=self.writer)
+ self.writer_thread.setDaemon(True)
+ self.writer_thread.start()
+
+ def stop_writer(self):
+ self.writer_alive = False
+ self.writer_thread.join()
+
+ def start(self):
+ print("[FLTERM] Starting....")
+ self.start_reader()
+ self.start_writer()
+
+ def stop(self):
+ self.reader_alive = False
+ self.writer_alive = False
+
+ def join(self, writer_only=False):
+ self.writer_thread.join()
+ if not writer_only:
+ self.reader_thread.join()
+
+
+def _get_args():
+ parser = argparse.ArgumentParser()
+ parser.add_argument("port", help="serial port")
+ parser.add_argument("--speed", default=115200, help="serial baudrate")
+ parser.add_argument("--kernel", default=None, help="kernel image")
+ parser.add_argument("--kernel-adr", type=lambda a: int(a, 0), default=0x40000000, help="kernel address")
+ return parser.parse_args()
+
+
+def main():
+ args = _get_args()
+ flterm = Flterm(args.kernel, args.kernel_adr)
+ flterm.open(args.port, args.speed)
+ flterm.start()
+ try:
+ flterm.join(True)
+ except KeyboardInterrupt:
+ pass
+ flterm.join()
+
+
+if __name__ == "__main__":
+ main()
--- /dev/null
+#!/usr/bin/env python3
+
+import argparse
+import binascii
+
+
+def insert_crc(i_filename, fbi_mode=False, o_filename=None):
+ if o_filename is None:
+ o_filename = i_filename
+
+ with open(i_filename, "rb") as f:
+ fdata = f.read()
+ fcrc = binascii.crc32(fdata).to_bytes(4, byteorder="big")
+ flength = len(fdata).to_bytes(4, byteorder="big")
+
+ with open(o_filename, "wb") as f:
+ if fbi_mode:
+ f.write(flength)
+ f.write(fcrc)
+ f.write(fdata)
+ else:
+ f.write(fdata)
+ f.write(fcrc)
+
+
+def main():
+ parser = argparse.ArgumentParser(description="CRC32 computation tool and MiSoC image file writer.")
+ parser.add_argument("input", help="input file")
+ parser.add_argument("-o", "--output", default=None, help="output file (if not specified, use input file)")
+ parser.add_argument("-f", "--fbi", default=False, action="store_true", help="build flash boot image (FBI) file")
+ args = parser.parse_args()
+ insert_crc(args.input, args.fbi, args.output)
+
+
+if __name__ == "__main__":
+ main()
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import *
-from migen.fhdl.specials import *
-from migen.fhdl.bitcontainer import *
-from migen.fhdl.decorators import *
-
-from migen.sim import *
-
-from migen.genlib.record import *
-from migen.genlib.fsm import *
+++ /dev/null
-from migen.build.altera.platform import AlteraPlatform
-from migen.build.altera.programmer import USBBlaster
+++ /dev/null
-from migen.fhdl.module import Module
-from migen.fhdl.specials import Instance
-from migen.genlib.io import DifferentialInput, DifferentialOutput
-
-
-class AlteraDifferentialInputImpl(Module):
- def __init__(self, i_p, i_n, o):
- self.specials += Instance("ALT_INBUF_DIFF",
- name="ibuf_diff",
- i_i=i_p,
- i_ibar=i_n,
- o_o=o)
-
-
-class AlteraDifferentialInput:
- @staticmethod
- def lower(dr):
- return AlteraDifferentialInputImpl(dr.i_p, dr.i_n, dr.o)
-
-
-class AlteraDifferentialOutputImpl(Module):
- def __init__(self, i, o_p, o_n):
- self.specials += Instance("ALT_OUTBUF_DIFF",
- name="obuf_diff",
- i_i=i,
- o_o=o_p,
- o_obar=o_n)
-
-
-class AlteraDifferentialOutput:
- @staticmethod
- def lower(dr):
- return AlteraDifferentialOutputImpl(dr.i, dr.o_p, dr.o_n)
-
-
-altera_special_overrides = {
- DifferentialInput: AlteraDifferentialInput,
- DifferentialOutput: AlteraDifferentialOutput
-}
+++ /dev/null
-from migen.build.generic_platform import GenericPlatform
-from migen.build.altera import common, quartus
-
-
-class AlteraPlatform(GenericPlatform):
- bitstream_ext = ".sof"
-
- def __init__(self, *args, toolchain="quartus", **kwargs):
- GenericPlatform.__init__(self, *args, **kwargs)
- if toolchain == "quartus":
- self.toolchain = quartus.AlteraQuartusToolchain()
- else:
- raise ValueError("Unknown toolchain")
-
- def get_verilog(self, *args, special_overrides=dict(), **kwargs):
- so = dict(common.altera_special_overrides)
- so.update(special_overrides)
- return GenericPlatform.get_verilog(self, *args, special_overrides=so,
- **kwargs)
-
- def build(self, *args, **kwargs):
- return self.toolchain.build(self, *args, **kwargs)
-
- def add_period_constraint(self, clk, period):
- if hasattr(clk, "p"):
- clk = clk.p
- self.toolchain.add_period_constraint(self, clk, period)
+++ /dev/null
-import subprocess
-
-from migen.build.generic_programmer import GenericProgrammer
-
-
-class USBBlaster(GenericProgrammer):
- needs_bitreverse = False
-
- def load_bitstream(self, bitstream_file, port=0):
- usb_port = "[USB-{}]".format(port)
- subprocess.call(["quartus_pgm", "-m", "jtag", "-c",
- "USB-Blaster{}".format(usb_port), "-o",
- "p;{}".format(bitstream_file)])
+++ /dev/null
-# This file is Copyright (c) 2013 Florent Kermarrec <florent@enjoy-digital.fr>
-# License: BSD
-
-import os
-import subprocess
-
-from migen.fhdl.structure import _Fragment
-
-from migen.build.generic_platform import Pins, IOStandard, Misc
-from migen.build import tools
-
-
-def _format_constraint(c, signame, fmt_r):
- if isinstance(c, Pins):
- return "set_location_assignment -comment \"{name}\" " \
- "-to {signame} Pin_{pin}".format(
- signame=signame,
- name=fmt_r,
- pin=c.identifiers[0])
- elif isinstance(c, IOStandard):
- return "set_instance_assignment -name io_standard " \
- "-comment \"{name}\" \"{std}\" -to {signame}".format(
- signame=signame,
- name=fmt_r,
- std=c.name)
- elif isinstance(c, Misc):
- if not isinstance(c.misc, str) and len(c.misc) == 2:
- return "set_instance_assignment -comment \"{name}\" " \
- "-name {misc[0]} \"{misc[1]}\" -to {signame}".format(
- signame=signame,
- name=fmt_r,
- misc=c.misc)
- else:
- return "set_instance_assignment -comment \"{name}\" " \
- "-name {misc} " \
- "-to {signame}".format(
- signame=signame,
- name=fmt_r,
- misc=c.misc)
-
-
-def _format_qsf(signame, pin, others, resname):
- fmt_r = "{}:{}".format(*resname[:2])
- if resname[2] is not None:
- fmt_r += "." + resname[2]
-
- fmt_c = [_format_constraint(c, signame, fmt_r) for c in
- ([Pins(pin)] + others)]
-
- return '\n'.join(fmt_c)
-
-
-def _build_qsf(named_sc, named_pc):
- lines = []
- for sig, pins, others, resname in named_sc:
- if len(pins) > 1:
- for i, p in enumerate(pins):
- lines.append(
- _format_qsf("{}[{}]".format(sig, i), p, others, resname))
- else:
- lines.append(_format_qsf(sig, pins[0], others, resname))
-
- if named_pc:
- lines.append("")
- lines.append("\n\n".join(named_pc))
-
- lines.append("set_global_assignment -name top_level_entity top")
- return "\n".join(lines)
-
-
-def _build_files(device, sources, vincpaths, named_sc, named_pc, build_name):
- lines = []
- for filename, language, library in sources:
- # Enforce use of SystemVerilog
- # (Quartus does not support global parameters in Verilog)
- if language == "verilog":
- language = "systemverilog"
- lines.append(
- "set_global_assignment -name {lang}_FILE {path} "
- "-library {lib}".format(
- lang=language.upper(),
- path=filename.replace("\\", "/"),
- lib=library))
-
- for path in vincpaths:
- lines.append("set_global_assignment -name SEARCH_PATH {}".format(
- path.replace("\\", "/")))
-
- lines.append(_build_qsf(named_sc, named_pc))
- lines.append("set_global_assignment -name DEVICE {}".format(device))
- tools.write_to_file("{}.qsf".format(build_name), "\n".join(lines))
-
-
-def _run_quartus(build_name, quartus_path):
- build_script_contents = """# Autogenerated by Migen
-
-set -e
-
-quartus_map --read_settings_files=on --write_settings_files=off {build_name} -c {build_name}
-quartus_fit --read_settings_files=off --write_settings_files=off {build_name} -c {build_name}
-quartus_asm --read_settings_files=off --write_settings_files=off {build_name} -c {build_name}
-quartus_sta {build_name} -c {build_name}
-
-""".format(build_name=build_name) # noqa
- build_script_file = "build_" + build_name + ".sh"
- tools.write_to_file(build_script_file,
- build_script_contents,
- force_unix=True)
-
- if subprocess.call(["bash", build_script_file]):
- raise OSError("Subprocess failed")
-
-
-class AlteraQuartusToolchain:
- def build(self, platform, fragment, build_dir="build", build_name="top",
- toolchain_path="/opt/Altera", run=True):
- tools.mkdir_noerror(build_dir)
- os.chdir(build_dir)
-
- if not isinstance(fragment, _Fragment):
- fragment = fragment.get_fragment()
- platform.finalize(fragment)
-
- v_output = platform.get_verilog(fragment)
- named_sc, named_pc = platform.resolve_signals(v_output.ns)
- v_file = build_name + ".v"
- v_output.write(v_file)
- sources = platform.sources | {(v_file, "verilog", "work")}
- _build_files(platform.device,
- sources,
- platform.verilog_include_paths,
- named_sc,
- named_pc,
- build_name)
- if run:
- _run_quartus(build_name, toolchain_path)
-
- os.chdir("..")
-
- return v_output.ns
-
- def add_period_constraint(self, platform, clk, period):
- # TODO: handle differential clk
- platform.add_platform_command(
- "set_global_assignment -name duty_cycle 50 -section_id {clk}",
- clk=clk)
- platform.add_platform_command(
- "set_global_assignment -name fmax_requirement \"{freq} MHz\" "
- "-section_id {clk}".format(freq=(1. / period) * 1000,
- clk="{clk}"),
- clk=clk)
+++ /dev/null
-import os
-
-from migen.build.generic_programmer import GenericProgrammer
-from migen.build.xilinx.programmer import _create_xsvf
-
-try:
- import fl
-except ImportError:
- import fpgalink3 as fl
-
-fl.flInitialise(0)
-
-
-class FPGALink(GenericProgrammer):
- """Using the fpgalink library from makestuff
-
- You will need fpgalink library installed from
- https://github.com/makestuff/libfpgalink
- """
-
- needs_bitreverse = False
-
- def __init__(self, initial_vidpid=None, pin_cfg="D0D2D3D4",
- fpgalink_vidpid="1D50:602B:0002", flash_proxy_basename=None):
- """
- Parameters
- ----------
- initial_vidpid : string
- The USB vendor and product id of the device before fpgalink
- firmware is loaded onto the device.
-
- Format is vid:pid as 4 digit hex numbers.
-
- pin_cfg : string
- FPGALink pin configuration string describing how the JTAG interface
- is hooked up to the programmer.
-
- fpgalink_vidpid : string
- The USB vendor, product and device id of the device after the
- fpgalink firmware is loaded onto the device.
-
- Format is vid:pid:did as 4 digit hex numbers.
- Defaults to 1D50:602B:0002 which is the makestuff FPGALink device.
- """
- GenericProgrammer.__init__(self, flash_proxy_basename)
- self.initial_vidpid = initial_vidpid
- self.fpgalink_vidpid = fpgalink_vidpid
- self.pin_cfg = pin_cfg
-
- def open_device(self):
- ivp = self.initial_vidpid
- vp = self.fpgalink_vidpid
-
- print("Attempting to open connection to FPGALink device", vp, "...")
- try:
- handle = fl.flOpen(self.fpgalink_vidpid)
- except fl.FLException as ex:
- if not ivp:
- raise FLException(
- "Could not open FPGALink device at {0} and"
- " no initial VID:PID was supplied".format(vp))
-
- print("Loading firmware into %s..." % ivp)
- fl.flLoadStandardFirmware(ivp, vp)
-
- print("Awaiting renumeration...")
- if not fl.flAwaitDevice(vp, 600):
- raise fl.FLException(
- "FPGALink device did not renumerate properly"
- " as {0}".format(vp))
-
- print("Attempting to open connection to FPGALink device", vp,
- "again...")
- handle = fl.flOpen(vp)
-
- # Only Nero capable hardware support doing programming.
- assert fl.flIsNeroCapable(handle)
- print("Cable connection opened.")
- return handle
-
- def load_bitstream(self, bitstream_file):
- n = 27
-
- xsvf_file = os.path.splitext(bitstream_file)[0]+'.xsvf'
- print("\nGenerating xsvf formatted bitstream")
- print("="*n)
- if os.path.exists(xsvf_file):
- os.unlink(xsvf_file)
- _create_xsvf(bitstream_file, xsvf_file)
- print("\n"+"="*n+"\n")
-
- print("Programming %s to device." % xsvf_file)
- print("="*n)
- handle = self.open_device()
- print("Programming device...")
- fl.flProgram(handle, "J:"+self.pin_cfg, progFile=xsvf_file)
- print("Programming successful!")
- print("="*n+"\n")
- fl.flClose(handle)
-
- def flash(self, address, data_file):
- raise NotImplementedError("Not supported yet.")
+++ /dev/null
-import os
-
-from migen.fhdl.structure import Signal
-from migen.genlib.record import Record
-from migen.genlib.io import CRG
-from migen.fhdl import verilog, edif
-from migen.build import tools
-
-
-class ConstraintError(Exception):
- pass
-
-
-class Pins:
- def __init__(self, *identifiers):
- self.identifiers = []
- for i in identifiers:
- self.identifiers += i.split()
-
- def __repr__(self):
- return "{}('{}')".format(self.__class__.__name__,
- " ".join(self.identifiers))
-
-
-class IOStandard:
- def __init__(self, name):
- self.name = name
-
- def __repr__(self):
- return "{}('{}')".format(self.__class__.__name__, self.name)
-
-
-class Drive:
- def __init__(self, strength):
- self.strength = strength
-
- def __repr__(self):
- return "{}('{}')".format(self.__class__.__name__, self.strength)
-
-
-class Misc:
- def __init__(self, misc):
- self.misc = misc
-
- def __repr__(self):
- return "{}({})".format(self.__class__.__name__, repr(self.misc))
-
-
-class Subsignal:
- def __init__(self, name, *constraints):
- self.name = name
- self.constraints = list(constraints)
-
- def __repr__(self):
- return "{}('{}', {})".format(
- self.__class__.__name__,
- self.name,
- ", ".join([repr(constr) for constr in self.constraints]))
-
-
-class PlatformInfo:
- def __init__(self, info):
- self.info = info
-
- def __repr__(self):
- return "{}({})".format(self.__class__.__name__, repr(self.info))
-
-
-def _lookup(description, name, number):
- for resource in description:
- if resource[0] == name and (number is None or resource[1] == number):
- return resource
- raise ConstraintError("Resource not found: {}:{}".format(name, number))
-
-
-def _resource_type(resource):
- t = None
- for element in resource[2:]:
- if isinstance(element, Pins):
- assert(t is None)
- t = len(element.identifiers)
- elif isinstance(element, Subsignal):
- if t is None:
- t = []
-
- assert(isinstance(t, list))
- n_bits = None
- for c in element.constraints:
- if isinstance(c, Pins):
- assert(n_bits is None)
- n_bits = len(c.identifiers)
-
- t.append((element.name, n_bits))
-
- return t
-
-
-class ConnectorManager:
- def __init__(self, connectors):
- self.connector_table = dict()
- for connector in connectors:
- cit = iter(connector)
- conn_name = next(cit)
- if isinstance(connector[1], str):
- pin_list = []
- for pins in cit:
- pin_list += pins.split()
- pin_list = [None if pin == "None" else pin for pin in pin_list]
- elif isinstance(connector[1], dict):
- pin_list = connector[1]
- else:
- raise ValueError("Unsupported pin list type {} for connector"
- " {}".format(type(connector[1]), conn_name))
- if conn_name in self.connector_table:
- raise ValueError(
- "Connector specified more than once: {}".format(conn_name))
-
- self.connector_table[conn_name] = pin_list
-
- def resolve_identifiers(self, identifiers):
- r = []
- for identifier in identifiers:
- if ":" in identifier:
- conn, pn = identifier.split(":")
- if pn.isdigit():
- pn = int(pn)
-
- r.append(self.connector_table[conn][pn])
- else:
- r.append(identifier)
-
- return r
-
-
-def _separate_pins(constraints):
- pins = None
- others = []
- for c in constraints:
- if isinstance(c, Pins):
- assert(pins is None)
- pins = c.identifiers
- else:
- others.append(c)
-
- return pins, others
-
-
-class ConstraintManager:
- def __init__(self, io, connectors):
- self.available = list(io)
- self.matched = []
- self.platform_commands = []
- self.connector_manager = ConnectorManager(connectors)
-
- def add_extension(self, io):
- self.available.extend(io)
-
- def request(self, name, number=None):
- resource = _lookup(self.available, name, number)
- rt = _resource_type(resource)
- if isinstance(rt, int):
- obj = Signal(rt, name_override=resource[0])
- else:
- obj = Record(rt, name=resource[0])
-
- for element in resource[2:]:
- if isinstance(element, PlatformInfo):
- obj.platform_info = element.info
- break
-
- self.available.remove(resource)
- self.matched.append((resource, obj))
- return obj
-
- def lookup_request(self, name, number=None):
- for resource, obj in self.matched:
- if resource[0] == name and (number is None or
- resource[1] == number):
- return obj
-
- raise ConstraintError("Resource not found: {}:{}".format(name, number))
-
- def add_platform_command(self, command, **signals):
- self.platform_commands.append((command, signals))
-
- def get_io_signals(self):
- r = set()
- for resource, obj in self.matched:
- if isinstance(obj, Signal):
- r.add(obj)
- else:
- r.update(obj.flatten())
-
- return r
-
- def get_sig_constraints(self):
- r = []
- for resource, obj in self.matched:
- name = resource[0]
- number = resource[1]
- has_subsignals = False
- top_constraints = []
- for element in resource[2:]:
- if isinstance(element, Subsignal):
- has_subsignals = True
- else:
- top_constraints.append(element)
-
- if has_subsignals:
- for element in resource[2:]:
- if isinstance(element, Subsignal):
- sig = getattr(obj, element.name)
- pins, others = _separate_pins(top_constraints +
- element.constraints)
- pins = self.connector_manager.resolve_identifiers(pins)
- r.append((sig, pins, others,
- (name, number, element.name)))
- else:
- pins, others = _separate_pins(top_constraints)
- pins = self.connector_manager.resolve_identifiers(pins)
- r.append((obj, pins, others, (name, number, None)))
-
- return r
-
- def get_platform_commands(self):
- return self.platform_commands
-
-
-class GenericPlatform:
- def __init__(self, device, io, connectors=[], name=None):
- self.device = device
- self.constraint_manager = ConstraintManager(io, connectors)
- if name is None:
- name = self.__module__.split(".")[-1]
- self.name = name
- self.sources = set()
- self.verilog_include_paths = set()
- self.finalized = False
-
- def request(self, *args, **kwargs):
- return self.constraint_manager.request(*args, **kwargs)
-
- def lookup_request(self, *args, **kwargs):
- return self.constraint_manager.lookup_request(*args, **kwargs)
-
- def add_period_constraint(self, clk, period):
- raise NotImplementedError
-
- def add_platform_command(self, *args, **kwargs):
- return self.constraint_manager.add_platform_command(*args, **kwargs)
-
- def add_extension(self, *args, **kwargs):
- return self.constraint_manager.add_extension(*args, **kwargs)
-
- def finalize(self, fragment, *args, **kwargs):
- if self.finalized:
- raise ConstraintError("Already finalized")
- # if none exists, create a default clock domain and drive it
- if not fragment.clock_domains:
- if not hasattr(self, "default_clk_name"):
- raise NotImplementedError(
- "No default clock and no clock domain defined")
- crg = CRG(self.request(self.default_clk_name))
- fragment += crg.get_fragment()
-
- self.do_finalize(fragment, *args, **kwargs)
- self.finalized = True
-
- def do_finalize(self, fragment, *args, **kwargs):
- """overload this and e.g. add_platform_command()'s after the modules
- had their say"""
- if hasattr(self, "default_clk_period"):
- try:
- self.add_period_constraint(
- self.lookup_request(self.default_clk_name),
- self.default_clk_period)
- except ConstraintError:
- pass
-
- def add_source(self, filename, language=None, library=None):
- if language is None:
- language = tools.language_by_filename(filename)
- if language is None:
- language = "verilog"
-
- if library is None:
- library = "work"
-
- self.sources.add((os.path.abspath(filename), language, library))
-
- def add_sources(self, path, *filenames, language=None, library=None):
- for f in filenames:
- self.add_source(os.path.join(path, f), language, library)
-
- def add_source_dir(self, path, recursive=True, library=None):
- dir_files = []
- if recursive:
- for root, dirs, files in os.walk(path):
- for filename in files:
- dir_files.append(os.path.join(root, filename))
- else:
- for item in os.listdir(path):
- if os.path.isfile(os.path.join(path, item)):
- dir_files.append(os.path.join(path, item))
- for filename in dir_files:
- language = tools.language_by_filename(filename)
- if language is not None:
- self.add_source(filename, language, library)
-
- def add_verilog_include_path(self, path):
- self.verilog_include_paths.add(os.path.abspath(path))
-
- def resolve_signals(self, vns):
- # resolve signal names in constraints
- sc = self.constraint_manager.get_sig_constraints()
- named_sc = [(vns.get_name(sig), pins, others, resource)
- for sig, pins, others, resource in sc]
- # resolve signal names in platform commands
- pc = self.constraint_manager.get_platform_commands()
- named_pc = []
- for template, args in pc:
- name_dict = dict((k, vns.get_name(sig)) for k, sig in args.items())
- named_pc.append(template.format(**name_dict))
-
- return named_sc, named_pc
-
- def get_verilog(self, fragment, **kwargs):
- return verilog.convert(
- fragment,
- self.constraint_manager.get_io_signals(),
- create_clock_domains=False, **kwargs)
-
- def get_edif(self, fragment, cell_library, vendor, device, **kwargs):
- return edif.convert(
- fragment,
- self.constraint_manager.get_io_signals(),
- cell_library, vendor, device, **kwargs)
-
- def build(self, fragment):
- raise NotImplementedError("GenericPlatform.build must be overloaded")
-
- def create_programmer(self):
- raise NotImplementedError
+++ /dev/null
-import os
-
-
-class GenericProgrammer:
- def __init__(self, flash_proxy_basename=None):
- self.flash_proxy_basename = flash_proxy_basename
- self.flash_proxy_dirs = [
- "~/.migen", "/usr/local/share/migen", "/usr/share/migen",
- "~/.mlabs", "/usr/local/share/mlabs", "/usr/share/mlabs"]
-
- def set_flash_proxy_dir(self, flash_proxy_dir):
- if flash_proxy_dir is not None:
- self.flash_proxy_dirs = [flash_proxy_dir]
-
- def find_flash_proxy(self):
- for d in self.flash_proxy_dirs:
- fulldir = os.path.abspath(os.path.expanduser(d))
- fullname = os.path.join(fulldir, self.flash_proxy_basename)
- if os.path.exists(fullname):
- return fullname
- raise OSError("Failed to find flash proxy bitstream")
-
- # must be overloaded by specific programmer
- def load_bitstream(self, bitstream_file):
- raise NotImplementedError
-
- # must be overloaded by specific programmer
- def flash(self, address, data_file):
- raise NotImplementedError
-
-
+++ /dev/null
-from migen.build.lattice.platform import LatticePlatform
-from migen.build.lattice.programmer import LatticeProgrammer
+++ /dev/null
-from migen.fhdl.module import Module
-from migen.fhdl.specials import Instance
-from migen.genlib.io import *
-from migen.genlib.resetsync import AsyncResetSynchronizer
-
-
-class LatticeAsyncResetSynchronizerImpl(Module):
- def __init__(self, cd, async_reset):
- rst1 = Signal()
- self.specials += [
- Instance("FD1S3BX", i_D=0, i_PD=async_reset,
- i_CK=cd.clk, o_Q=rst1),
- Instance("FD1S3BX", i_D=rst1, i_PD=async_reset,
- i_CK=cd.clk, o_Q=cd.rst)
- ]
-
-
-class LatticeAsyncResetSynchronizer:
- @staticmethod
- def lower(dr):
- return LatticeAsyncResetSynchronizerImpl(dr.cd, dr.async_reset)
-
-
-class LatticeDDROutputImpl(Module):
- def __init__(self, i1, i2, o, clk):
- self.specials += Instance("ODDRXD1",
- synthesis_directive="ODDRAPPS=\"SCLK_ALIGNED\"",
- i_SCLK=clk,
- i_DA=i1, i_DB=i2, o_Q=o,
- )
-
-
-class LatticeDDROutput:
- @staticmethod
- def lower(dr):
- return LatticeDDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk)
-
-lattice_special_overrides = {
- AsyncResetSynchronizer: LatticeAsyncResetSynchronizer,
- DDROutput: LatticeDDROutput
-}
+++ /dev/null
-# This file is Copyright (c) 2015 Florent Kermarrec <florent@enjoy-digital.fr>
-# License: BSD
-
-import os
-import sys
-import subprocess
-import shutil
-
-from migen.fhdl.structure import _Fragment
-
-from migen.build.generic_platform import *
-from migen.build import tools
-from migen.build.lattice import common
-
-
-def _format_constraint(c):
- if isinstance(c, Pins):
- return ("LOCATE COMP ", " SITE " + "\"" + c.identifiers[0] + "\"")
- elif isinstance(c, IOStandard):
- return ("IOBUF PORT ", " IO_TYPE=" + c.name)
- elif isinstance(c, Misc):
- return c.misc
-
-
-def _format_lpf(signame, pin, others, resname):
- fmt_c = [_format_constraint(c) for c in ([Pins(pin)] + others)]
- r = ""
- for pre, suf in fmt_c:
- r += pre + "\"" + signame + "\"" + suf + ";\n"
- return r
-
-
-def _build_lpf(named_sc, named_pc):
- r = "BLOCK RESETPATHS;\n"
- r += "BLOCK ASYNCPATHS;\n"
- for sig, pins, others, resname in named_sc:
- if len(pins) > 1:
- for i, p in enumerate(pins):
- r += _format_lpf(sig + "[" + str(i) + "]", p, others, resname)
- else:
- r += _format_lpf(sig, pins[0], others, resname)
- if named_pc:
- r += "\n" + "\n\n".join(named_pc)
- return r
-
-
-def _build_files(device, sources, vincpaths, build_name):
- tcl = []
- tcl.append("prj_project new -name \"{}\" -impl \"implementation\" -dev {} -synthesis \"synplify\"".format(build_name, device))
- for path in vincpaths:
- tcl.append("prj_impl option {include path} {\"" + path + "\"}")
- for filename, language, library in sources:
- tcl.append("prj_src add \"" + filename + "\" -work " + library)
- tcl.append("prj_run Synthesis -impl implementation -forceOne")
- tcl.append("prj_run Translate -impl implementation")
- tcl.append("prj_run Map -impl implementation")
- tcl.append("prj_run PAR -impl implementation")
- tcl.append("prj_run Export -impl implementation -task Bitgen")
- tools.write_to_file(build_name + ".tcl", "\n".join(tcl))
-
-
-def _run_diamond(build_name, source, ver=None):
- if sys.platform == "win32" or sys.platform == "cygwin":
- build_script_contents = "REM Autogenerated by Migen\n"
- build_script_contents = "pnmainc " + build_name + ".tcl\n"
- build_script_file = "build_" + build_name + ".bat"
- tools.write_to_file(build_script_file, build_script_contents)
- r = subprocess.call([build_script_file])
- shutil.copy(os.path.join("implementation", build_name + "_implementation.bit"), build_name + ".bit")
- else:
- raise NotImplementedError
-
- if r != 0:
- raise OSError("Subprocess failed")
-
-
-class LatticeDiamondToolchain:
- def build(self, platform, fragment, build_dir="build", build_name="top",
- toolchain_path="/opt/Diamond", run=True):
- tools.mkdir_noerror(build_dir)
- os.chdir(build_dir)
-
- if not isinstance(fragment, _Fragment):
- fragment = fragment.get_fragment()
- platform.finalize(fragment)
-
- v_output = platform.get_verilog(fragment)
- named_sc, named_pc = platform.resolve_signals(v_output.ns)
- v_file = build_name + ".v"
- v_output.write(v_file)
- sources = platform.sources | {(v_file, "verilog", "work")}
- _build_files(platform.device, sources, platform.verilog_include_paths, build_name)
-
- tools.write_to_file(build_name + ".lpf", _build_lpf(named_sc, named_pc))
-
- if run:
- _run_diamond(build_name, toolchain_path)
-
- os.chdir("..")
-
- return v_output.ns
-
- def add_period_constraint(self, platform, clk, period):
- # TODO: handle differential clk
- platform.add_platform_command("""FREQUENCY PORT "{clk}" {freq} MHz;""".format(freq=str(float(1/period)*1000), clk="{clk}"), clk=clk)
+++ /dev/null
-from migen.build.generic_platform import GenericPlatform
-from migen.build.lattice import common, diamond
-
-
-class LatticePlatform(GenericPlatform):
- bitstream_ext = ".bit"
-
- def __init__(self, *args, toolchain="diamond", **kwargs):
- GenericPlatform.__init__(self, *args, **kwargs)
- if toolchain == "diamond":
- self.toolchain = diamond.LatticeDiamondToolchain()
- else:
- raise ValueError("Unknown toolchain")
-
- def get_verilog(self, *args, special_overrides=dict(), **kwargs):
- so = dict(common.lattice_special_overrides)
- so.update(special_overrides)
- return GenericPlatform.get_verilog(self, *args, special_overrides=so, **kwargs)
-
- def build(self, *args, **kwargs):
- return self.toolchain.build(self, *args, **kwargs)
-
- def add_period_constraint(self, clk, period):
- if hasattr(clk, "p"):
- clk = clk.p
- self.toolchain.add_period_constraint(self, clk, period)
+++ /dev/null
-import os
-import subprocess
-
-from migen.build.generic_programmer import GenericProgrammer
-from migen.build import tools
-
-
-# XXX Lattice programmer need an .xcf file, will need clean up and support for more parameters
-_xcf_template = """
-<?xml version='1.0' encoding='utf-8' ?>
-<!DOCTYPE ispXCF SYSTEM "IspXCF.dtd" >
-<ispXCF version="3.4.1">
- <Comment></Comment>
- <Chain>
- <Comm>JTAG</Comm>
- <Device>
- <SelectedProg value="TRUE"/>
- <Pos>1</Pos>
- <Vendor>Lattice</Vendor>
- <Family>LatticeECP3</Family>
- <Name>LFE3-35EA</Name>
- <File>{bitstream_file}</File>
- <Operation>Fast Program</Operation>
- </Device>
- </Chain>
- <ProjectOptions>
- <Program>SEQUENTIAL</Program>
- <Process>ENTIRED CHAIN</Process>
- <OperationOverride>No Override</OperationOverride>
- <StartTAP>TLR</StartTAP>
- <EndTAP>TLR</EndTAP>
- <VerifyUsercode value="FALSE"/>
- </ProjectOptions>
- <CableOptions>
- <CableName>USB2</CableName>
- <PortAdd>FTUSB-0</PortAdd>
- <USBID>Dual RS232-HS A Location 0000 Serial A</USBID>
- <JTAGPinSetting>
- TRST ABSENT;
- ISPEN ABSENT;
- </JTAGPinSetting>
- </CableOptions>
-</ispXCF>
-"""
-
-
-class LatticeProgrammer(GenericProgrammer):
- needs_bitreverse = False
-
- def load_bitstream(self, bitstream_file):
- xcf_file = bitstream_file.replace(".bit", ".xcf")
- xcf_content = _xcf_template.format(bitstream_file=bitstream_file)
- tools.write_to_file(xcf_file, xcf_content)
- subprocess.call(["pgrcmd", "-infile", xcf_file])
+++ /dev/null
-import subprocess
-
-from migen.build.generic_programmer import GenericProgrammer
-
-
-class OpenOCD(GenericProgrammer):
- needs_bitreverse = False
-
- def __init__(self, config, flash_proxy_basename=None):
- GenericProgrammer.__init__(self, flash_proxy_basename)
- self.config = config
-
- def load_bitstream(self, bitstream):
- script = "; ".join([
- "init",
- "pld load 0 {}".format(bitstream),
- "exit",
- ])
- subprocess.call(["openocd", "-f", self.config, "-c", script])
-
- def flash(self, address, data):
- flash_proxy = self.find_flash_proxy()
- script = "; ".join([
- "init",
- "jtagspi_init 0 {}".format(flash_proxy),
- "jtagspi_program {} 0x{:x}".format(data, address),
- "fpga_program",
- "exit"
- ])
- subprocess.call(["openocd", "-f", self.config, "-c", script])
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-_ios = [
- ("clk0", 0, Pins("N9"), IOStandard("LVCMOS18")),
- ("fpga_reset", 0, Pins("T9"), IOStandard("LVCMOS18"), Drive("8")),
- ("fpga_initb", 0, Pins("T12"), IOStandard("LVCMOS18"), Drive("8")),
- ("weim", 0,
- Subsignal("cs4_dtack", Pins("R3"), IOStandard("LVCMOS18"), Drive("8")),
- Subsignal("cs5n", Pins("P10"), IOStandard("LVCMOS18")),
- Subsignal("eb0n", Pins("P9"), IOStandard("LVCMOS18")),
- Subsignal("oen", Pins("R9"), IOStandard("LVCMOS18")),
- Subsignal("data",
- Pins("T5 T6 P7 N8 P12 T13 R13 T14 P5 N6 T3 T11 T4 R5 M10 T10"),
- IOStandard("LVCMOS18"), Drive("8")),
- Subsignal("addr",
- Pins("N5 L7 M7 M8 L8 L9 L10 M11 P11 N11 N12 P13"),
- IOStandard("LVCMOS18"))
- )
-]
-
-_connectors = [
- ("J2",
- "None", # no 0 pin
- "None", # 1 +3v3
- "None", # 2 +3v3
- "None", # 3 GND
- "None", # 4 GND
- "None", # 5 DP USB_OTG_PHY +3V3
- "None", # 6 DM USB_OTG_PHY +3V3
- "None", # 7 VBUS USB_OTG_ PHY +3V3
- "None", # 8 PSW_N USB_OTG_PHY +3V3
- "None", # 9 ID USB_OTG_PHY +3V3
- "None", # 10 FAULT USB_OTG_PHY +3V3
- "None", # 11 RXP Ethernet_PHY +3V3
- "None", # 12 RXN Ethernet_PHY +3V3
- "None", # 13 ETH_LINK Ethernet_PHY +2V8
- "None", # 14 PC_VS2 PC +2V8 PF13
- "None", # 15 PC_VS1 PC +2V8 PF14
- "None", # 16 PC_PWRON PC +2V8 PF16
- "None", # 17 PC_READY PC +2V8 PF17
- "None", # 18 PWM0 PWM0 +2V8 PE5
- "None", # 19 TOUT GPT +2V8 PC14
- "None", # 20 GND POWER
- "None", # 21 VCC01 (IN) BANK1 SUPPLY VCCO1
- "C16", # 22 IO_L24P_1 FPGA_BANK1 VCC01
- "C15", # 23 IO_L24N_1 FPGA_BANK1 VCC01
- "D16", # 24 IO_L22_P1 FPGA_BANK1 VCC01
- "None", # 25 GND POWER
- "B14", # 26 IO_L02N_0 FPGA_BANK0 VCCO0
- "B15", # 27 IO_L02P_0 FPGA_BANK0
- "A13", # 28 IO_L04N_0 FPGA_BANK0
- "A14", # 29 IO_L04P_0 FPGA_BANK0 VCCO0
- "D11", # 30 IO_L03N_0 FPGA_BANK0 VCCO0
- "C12", # 31 IO_L03P_0 FPGA_BANK0 VCCO0
- "A10", # 32 IO_L08N_0 FPGA_BANK0 VCCO0
- "B10", # 33 IO_L08P_0 FPGA_BANK0 VCCO0
- "A9", # 34 IO_L10N_0 / GLCK7 FPGA_BANK0 VCCO0
- "C9", # 35 IO_L10P_0 / GCLK6 FPGA_BANK0 VCCO0
- "B8", # 36 IO_L12N_0 / GCLK11 FPGA_BANK0 VCCO0
- "A8", # 37 IO_L12P_0 / GCLK10 FPGA_BANK0 VCCO0
- "B6", # 38 IO_L15N_0 FPGA_BANK0 VCCO0
- "A6", # 39 IO_L15P_0 FPGA_BANK0 VCCO0
- "B4", # 40 IO_L18N_0 FPGA_BANK0 VCCO0
- "A4", # 41 IO_L18P_0 FPGA_BANK0 VCCO0
- "None", # 42 GND POWER
- "N3", # 43 IO_L24P_3 FPGA_BANK3 VCCO3
- "R1", # 44 IO_L23P_3 FPGA_BANK3 VCCO3
- "P1", # 45 IO_L22N_3 FPGA_BANK3 VCCO3
- "N1", # 46 IO_L20N_3 FPGA_BANK3 VCCO3
- "M1", # 47 IO_L20P_3 FPGA_BANK3 VCCO3
- "H3", # 48 IO_L12P_3 FPGA_BANK3 VCCO3
- "K1", # 49 IO_L15N_3 FPGA_BANK3 VCCO3
- "J1", # 50 IO_L14N_3 FPGA_BANK3 VCCO3
- "H1", # 51 IO_L11N_3 FPGA_BANK3 VCCO3
- "G1", # 52 IO_L08N_3 FPGA_BANK3 VCCO3
- "F1", # 53 IO_L08P_3 FPGA_BANK3 VCCO3
- "E1", # 54 IO_L03N_3 FPGA_BANK3 VCCO3
- "D1", # 55 IO_LO3P_3 FPGA_BANK3 VCCO3
- "C1", # 56 IO_L01N_3 FPGA_BANK3 VCCO3
- "None", # 57 GND POWER
- "None", # 58 TRSTN JTAG +2V8
- "None", # 59 TDI JTAG +2V8
- "None", # 60 TCK JTAG +2V8
- "None", # 61 TDO JTAG +2V8
- "None", # 62 TMS JTAG +2V8
- "None", # 63 GND POWER
- "C2", # 64 IO_L01P_3 FPGA_BANK3 VCCO3
- "D3", # 65 IO_L02N_3 FPGA_BANK3 VCCO3
- "D4", # 66 IO_L02P_3 FPGA_BANK3 VCCO3
- "F4", # 67 IP_LO4N_3 FPGA_BANK3 VCCO3
- "G2", # 68 IO_L11P_3 FPGA_BANK3 VCCO3
- "J2", # 69 IO_L14P_3 FPGA_BANK3 VCCO3
- "K3", # 70 IO_L15P_3 FPGA_BANK3 VCCO3
- "J3", # 71 IO_L12N_3 FPGA_BANK3 VCCO3
- "N2", # 72 IO_L22P_3 FPGA_BANK3 VCCO3
- "P2", # 73 IO_L23N_3 FPGA_BANK3 VCCO3
- "M4", # 74 IO_L24N_3 FPGA_BANK3 VCCO3
- "L6", # 75 IP_L25N_3 FPGA_BANK3 VCCO3
- "None", # 76 VCCO3 (IN) BANK3 SUPPLY VCCO3 (3.3Vmax)
- "None", # 77 VCCO3 (IN) BANK3 SUPPLY VCCO3 (3.3Vmax)
- "A3", # 78 IO_L19P_0 FPGA_BANK0 VCCO0
- "B3", # 79 IO_L19N_0 FPGA_BANK0 VCCO0
- "A5", # 80 IO_L17P_0 FPGA_BANK0 VCCO0
- "C5", # 81 IO_L17N_0 FPGA_BANK0 VCCO0
- "D7", # 82 IO_L16P_0 FPGA_BANK0 VCCO0
- "C6", # 83 IO_L16N_0 FPGA_BANK0 VCCO0
- "C8", # 84 IO_L11P_0 / GCLK8 FPGA_BANK0 VCCO0
- "D8", # 85 IO_L11N_0 / GCLK9 FPGA_BANK0 VCCO0
- "C10", # 86 IO_L09P_0 / GCLK4 FPGA_BANK0 VCCO0
- "D9", # 87 IO_L09N_0 / GCLK5 FPGA_BANK0 VCCO0
- "C11", # 88 IO_L07P_0 FPGA_BANK0 VCCO0
- "A11", # 89 IO_L07N_0 FPGA_BANK0 VCCO0
- "D13", # 90 IO_L01P_0 FPGA_BANK0 VCCO0
- "C13", # 91 IO_L01N_0 FPGA_BANK0 VCCO0
- "None", # 92 VCCO0 (IN) BANK0 SUPPLY VCCO0 (3.3Vmax)
- "None", # 93 VCCO0 (IN) BANK0 SUPPLY VCCO0 (3.3Vmax)
- "None", # 94 GND POWER VCCO0 A13
- "D15", # 95 IO_L22N_1 FPGA_BANK1 VCC01
- "E13", # 96 IO_L23P_1 FPGA_BANK1 VCC01
- "D14", # 97 IO_L23N_1 FPGA_BANK1 VCC01
- "E14", # 98 IO_L20P_1 FPGA_BANK1 VCC01
- "F13", # 99 IO_L20N_1 FPGA_BANK1 VCC01
- "None", # 100 GND POWER (3.3Vmax)
- "None", # 101 USR_RESETN (open CONFIG Pos PC15 +2V8 drain with pullup)
- "None", # 102 TIN GPT +2V8
- "None", # 103 EXTAL_26M CONFIG +2V5
- "None", # 104 RX3 RS232_3 RS232
- "None", # 105 TX3 RS232_3 RS232
- "None", # 106 RX1 RS232_1 RS232
- "None", # 107 TX1 RS232_1 RS232
- "None", # 108 BOOT CONFIG +2V8
- "None", # 109 TXN Ethernet_PHY +3V3
- "None", # 110 TXP Ethernet_PHY +3V3
- "None", # 111 ETH_ACTIVITY Ethernet_PHY +2V8
- "None", # 112 USBH2_NXT USB_HOST2 +2V5 PA3
- "None", # 113 USBH2_DIR USB_HOST2 +2V5 PA1
- "None", # 114 USBH2_DATA7 USB_HOST2 +2V5 PA2
- "None", # 115 USBH2_STP USB_HOST2 +2V5 PA4
- "None") # 116 USBH2_CLK USB_HOST2 +2V5 PA0
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk0"
- default_clk_period = 10
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc3s200a-ft256-4", _ios, _connectors)
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-_ios = [
- ("clk3", 0, Pins("N8"), IOStandard("LVCMOS33")),
- ("clko", 0, Pins("N7"), IOStandard("LVCMOS33")),
- ("fpga_initb", 0, Pins("P3"), IOStandard("LVCMOS33")),
- ("fpga_program", 0, Pins("R2"), IOStandard("LVCMOS33")),
- ("eim", 0,
- Subsignal("bclk", Pins("N12")),
- Subsignal("eb1", Pins("P13")),
- Subsignal("cs1", Pins("R11")),
- Subsignal("cs2", Pins("N9")),
- Subsignal("lba", Pins("R9")),
- Subsignal("eb0", Pins("P7")),
- Subsignal("oe", Pins("R7")),
- Subsignal("rw", Pins("R6")),
- Subsignal("dtack", Pins("N4")),
- Subsignal("wait", Pins("R4")),
- Subsignal("da", Pins("N6 L5 L6 R5 P5 N11 M11 P11 L8 K8 M8 M10 L9 R10 N5 M5")),
- IOStandard("LVCMOS33")
- )
-]
-
-_connectors = [
- ("J2",
- "None", # No 0 pin
- "None", # 1 FPGA Bank1 power
- "None", # 2 FPGA Bank1 power
- "None", # 3 GND
- "B14", # 4 IO_L1P_A25_1
- "B15", # 5 IO_L1N_A24_VREF_1
- "C14", # 6 IO_L33P_A15_M1A10_1
- "C15", # 7 IO_L33N_A14_M1A4_1
- "D13", # 8 IO_L35P_A11_M1A7_1
- "D15", # 9 IO_L35N_A10_M1A2_1
- "E14", # 10 IO_L37P_A7_M1A0_1
- "E15", # 11 IO_L37N_A6_M1A1_1
- "None", # 12 GND
- "F13", # 13 IO_L39P_M1A3_1
- "F15", # 14 IO_L39N_M1ODT_1
- "G14", # 15 IO_L41P_GCLK9_IRDY1_M1RASN_1
- "G15", # 16 IO_L41N_GCLK8_M1CASN_1
- "H13", # 17 IO_L42P_GCLK7_M1UDM_1
- "H15", # 18 IO_L42N_GCLK6_TRDY1_M1LDM
- "J14", # 19 IO_L43P_GCLK5_M1DQ4_1
- "J15", # 20 IO_L43N_GCLK4_M1DQ5_1
- "K13", # 21 IO_L44P_A3_M1DQ6_1
- "K15", # 22 IO_L44N_A2_M1DQ7_1
- "L14", # 23 IO_L45P_A1_M1LDQS_1
- "L15", # 24 IO_L45N_A0_M1LDQSN_1
- "None", # 25 GND
- "E2", # 26 IO_L52P_M3A8_3
- "E1", # 27 IO_L52N_M3A9_3
- "D3", # 28 IO_L54P_M3RESET_3
- "D1", # 29 IO_L54N_M3A11_3
- "F3", # 30 IO_L46P_M3CLK_3
- "F1", # 31 IO_L46N_M3CLKN_3
- "G2", # 32 IO_L44P_GCLK21_M3A5_3
- "G1", # 33 IO_L44N_GCLK20_M3A6_3
- "H3", # 34 IO_L42P_GCLK25_TRDY2_M3UDM_3
- "H1", # 35 IO_L42N_GCLK24_M3LDM_3
- "K3", # 36 IO_L40P_M3DQ6_3
- "K1", # 37 IO_L40N_M3DQ7_3
- "None", # 38 GND
- "None", # 39 GPIO4_16
- "None", # 40 GPIO4_17
- "None", # 41 BOOT_MODE0
- "None", # 42 AUD5_RXFS
- "None", # 43 AUD5_RXC
- "None", # 44 GND
- "None", # 45 AUD5_RXD
- "None", # 46 AUD5_TXC
- "None", # 47 AUD5_TXFS
- "None", # 48 GND
- "None", # 49 SPI2_SCLK_GPT_CMPOUT3
- "None", # 50 SPI2_MISO
- "None", # 51 SPI2_MOSI
- "None", # 52 SPI2_SS1
- "None", # 53 SPI2_SS2
- "None", # 54 SPI2_SS3
- "None", # 55 SPI2_RDY
- "None", # 56 OWIRE
- "None", # 57 GND
- "None", # 58 SPI1_SCLK
- "None", # 59 SPI1_MISO
- "None", # 60 SPI1_MOSI
- "None", # 61 SPI1_SS0
- "None", # 62 SPI1_SS1
- "None", # 63 SPI1_RDY
- "None", # 64 RESET#
- "None", # 65 VIO_H2
- "None", # 66 PMIC_GPIO6
- "None", # 67 TOUCH_X+
- "None", # 68 TOUCH_X-
- "None", # 69 TOUCH_Y+
- "None", # 70 TOUCH_Y-
- "None", # 71 AUXADCIN4
- "None", # 72 AUXADCIN3
- "None", # 73 AUXADCIN2
- "None", # 74 AUXADCIN1
- "None", # 75 PMIC_GPIO7
- "None", # 76 +1v8
- "None", # 77 RESERVED
- "None", # 78 UART3_TXD
- "None", # 79 UART_3_RXD
- "None", # 80 UART2_TXD
- "None", # 81 UART2_RXD
- "None", # 82 UART2_RTS_KEY_COL7
- "None", # 83 UART2_CTS_KEY_COL6
- "None", # 84 UART1_TXD
- "None", # 85 UART1_RXD
- "None", # 86 UART1_RTS
- "None", # 87 UART1_CTS
- "None", # 88 GND
- "None", # 89 AUD3_TXD
- "None", # 90 AUD3_RXD
- "None", # 91 AUD3_FS
- "None", # 92 AUD3_CK
- "None", # 93 GND
- "None", # 94 AUD6_TXFS_KEY_ROW7
- "None", # 95 AUD6_TXC_KEY_ROW6
- "None", # 96 AUD6_RXD_KEY_ROW5
- "None", # 97 AUD6_TXD_KEY_ROW4
- "None", # 98 I2C2_SDA_UART3_CTS
- "None", # 99 I2C2_SCL_UART3_RTS
- "None", # 100 BOOT_MODE1
- "None", # 101 PWM2
- "None", # 102 PWM1
- "None", # 103 GND
- "L1", # 104 IO_L39N_M3LDQSN_3
- "L2", # 105 IO_L39P_M3LDQS_3
- "J1", # 106 IO_L41N_GCLK26_M3DQ5_3
- "J2", # 107 IO_L41P_GCLK27_M3DQ4_3
- "J3", # 108 IO_L43N_GCLK22_IRDY2_M3CASN_3
- "K4", # 109 IO_L43P_GCLK23_M3RASN_3
- "J4", # 110 IO_L45N_M3ODT_3
- "K5", # 111 IO_L45P_M3A3_3
- "C1", # 112 IO_L83N_VREF_3
- "C2", # 113 IO_L83P_3
- "E3", # 114 IO_L53N_M3A12_3
- "D4", # 115 IO_L53P_M3CKE_3
- "None", # 116 GND
- "P15", # 117 IO_L74N_DOUT_BUSY_1
- "P14", # 118 IO_L74P_AWAKE_1
- "N15", # 119 IO_L47N_LDC_M1DQ1_1
- "N14", # 120 IO_L47P_FWE_B_M1DQ0_1
- "M15", # 121 IO_L46N_FOE_B_M1DQ3_1
- "M13", # 122 IO_L46P_FCS_B_M1DQS2_1
- "L12", # 123 IO_L40N_GCLK10_M1A6_1
- "K12", # 124 IO_L40P_GCLK11_M1A5_1
- "K11", # 125 IO_L38N_A4_M1CLKN_1
- "K10", # 126 IO_L38P_A5_M1CLK_1
- "J13", # 127 IO_L36N_A8_M1BA1_1
- "J11", # 128 IO_L36P_A9_M1BA0_1
- "None", # 129 GND
- "G13", # 130 IO_L34N_A12_M1BA2_1_NOTLX4
- "H12", # 131 IO_L34P_A13_M1WE_1_NOTLX4
- "H11", # 132 IO_L32N_A16_M1A9_1_NOTLX4
- "H10", # 133 IO_L32P_A17_M1A8_1_NOTLX4
- "F12", # 134 IO_L31N_A18_M1A12_1_NOTLX4
- "F11", # 135 IO_L31P_A19_M1CKE_1_NOTLX4
- "G12", # 136 IO_L30N_A20_M1A11_1_NOTLX4
- "G11", # 137 IO_L30P_A21_M1RESET_1_NOTLX4
- "None", # 138 GND
- "None", # 139 FPGA_BANK3_POWER
- "None") # 140 FPGA_BANK3_POWER
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk3"
- default_clk_period = 10.526
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6slx9-2csg225", _ios, _connectors)
+++ /dev/null
-# This file is Copyright (c) 2013 Florent Kermarrec <florent@enjoy-digital.fr>
-# License: BSD
-
-from migen.build.generic_platform import *
-from migen.build.altera import AlteraPlatform
-from migen.build.altera.programmer import USBBlaster
-
-
-_io = [
- ("clk50", 0, Pins("R8"), IOStandard("3.3-V LVTTL")),
-
- ("user_led", 0, Pins("A15"), IOStandard("3.3-V LVTTL")),
- ("user_led", 1, Pins("A13"), IOStandard("3.3-V LVTTL")),
- ("user_led", 2, Pins("B13"), IOStandard("3.3-V LVTTL")),
- ("user_led", 3, Pins("A11"), IOStandard("3.3-V LVTTL")),
- ("user_led", 4, Pins("D1"), IOStandard("3.3-V LVTTL")),
- ("user_led", 5, Pins("F3"), IOStandard("3.3-V LVTTL")),
- ("user_led", 6, Pins("B1"), IOStandard("3.3-V LVTTL")),
- ("user_led", 7, Pins("L3"), IOStandard("3.3-V LVTTL")),
-
- ("key", 0, Pins("J15"), IOStandard("3.3-V LVTTL")),
- ("key", 1, Pins("E1"), IOStandard("3.3-V LVTTL")),
-
- ("sw", 0, Pins("M1"), IOStandard("3.3-V LVTTL")),
- ("sw", 1, Pins("T9"), IOStandard("3.3-V LVTTL")),
- ("sw", 2, Pins("B9"), IOStandard("3.3-V LVTTL")),
- ("sw", 3, Pins("M15"), IOStandard("3.3-V LVTTL")),
-
- ("serial", 0,
- Subsignal("tx", Pins("D3"), IOStandard("3.3-V LVTTL")),
- Subsignal("rx", Pins("C3"), IOStandard("3.3-V LVTTL"))
- ),
-
- ("sdram_clock", 0, Pins("R4"), IOStandard("3.3-V LVTTL")),
- ("sdram", 0,
- Subsignal("a", Pins("P2 N5 N6 M8 P8 T7 N8 T6 R1 P1 N2 N1 L4")),
- Subsignal("ba", Pins("M7 M6")),
- Subsignal("cs_n", Pins("P6")),
- Subsignal("cke", Pins("L7")),
- Subsignal("ras_n", Pins("L2")),
- Subsignal("cas_n", Pins("L1")),
- Subsignal("we_n", Pins("C2")),
- Subsignal("dq", Pins("G2 G1 L8 K5 K2 J2 J1 R7 T4 T2 T3 R3 R5 P3 N3 K1")),
- Subsignal("dm", Pins("R6 T5")),
- IOStandard("3.3-V LVTTL")
- ),
-
- ("epcs", 0,
- Subsignal("data0", Pins("H2")),
- Subsignal("dclk", Pins("H1")),
- Subsignal("ncs0", Pins("D2")),
- Subsignal("asd0", Pins("C1")),
- IOStandard("3.3-V LVTTL")
- ),
-
- ("i2c", 0,
- Subsignal("sclk", Pins("F2")),
- Subsignal("sdat", Pins("F1")),
- IOStandard("3.3-V LVTTL")
- ),
-
- ("g_sensor", 0,
- Subsignal("cs_n", Pins("G5")),
- Subsignal("int", Pins("M2")),
- IOStandard("3.3-V LVTTL")
- ),
-
- ("adc", 0,
- Subsignal("cs_n", Pins("A10")),
- Subsignal("saddr", Pins("B10")),
- Subsignal("sclk", Pins("B14")),
- Subsignal("sdat", Pins("A9")),
- IOStandard("3.3-V LVTTL")
- ),
-
- ("gpio_0", 0,
- Pins("D3 C3 A2 A3 B3 B4 A4 B5 A5 D5 B6 A6 B7 D6 A7 C6",
- "C8 E6 E7 D8 E8 F8 F9 E9 C9 D9 E11 E10 C11 B11 A12 D11",
- "D12 B12"),
- IOStandard("3.3-V LVTTL")
- ),
- ("gpio_1", 0,
- Pins("F13 T15 T14 T13 R13 T12 R12 T11 T10 R11 P11 R10 N12 P9 N9 N11",
- "L16 K16 R16 L15 P15 P16 R14 N16 N15 P14 L14 N14 M10 L13 J16 K15",
- "J13 J14"),
- IOStandard("3.3-V LVTTL")
- ),
- ("gpio_2", 0,
- Pins("A14 B16 C14 C16 C15 D16 D15 D14 F15 F16 F14 G16 G15"),
- IOStandard("3.3-V LVTTL")
- ),
-]
-
-
-class Platform(AlteraPlatform):
- default_clk_name = "clk50"
- default_clk_period = 20
-
- def __init__(self):
- AlteraPlatform.__init__(self, "EP4CE22F17C6", _io)
-
- def create_programmer(self):
- return USBBlaster()
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform, XC3SProg, VivadoProgrammer, iMPACT
-from migen.build.xilinx.ise import XilinxISEToolchain
-
-
-_io = [
- ("user_led", 0, Pins("AB8"), IOStandard("LVCMOS15")),
- ("user_led", 1, Pins("AA8"), IOStandard("LVCMOS15")),
- ("user_led", 2, Pins("AC9"), IOStandard("LVCMOS15")),
- ("user_led", 3, Pins("AB9"), IOStandard("LVCMOS15")),
- ("user_led", 4, Pins("AE26"), IOStandard("LVCMOS25")),
- ("user_led", 5, Pins("G19"), IOStandard("LVCMOS25")),
- ("user_led", 6, Pins("E18"), IOStandard("LVCMOS25")),
- ("user_led", 7, Pins("F16"), IOStandard("LVCMOS25")),
-
- ("cpu_reset", 0, Pins("AB7"), IOStandard("LVCMOS15")),
-
- ("user_btn_c", 0, Pins("G12"), IOStandard("LVCMOS25")),
- ("user_btn_n", 0, Pins("AA12"), IOStandard("LVCMOS15")),
- ("user_btn_s", 0, Pins("AB12"), IOStandard("LVCMOS15")),
- ("user_btn_w", 0, Pins("AC6"), IOStandard("LVCMOS15")),
- ("user_btn_e", 0, Pins("AG5"), IOStandard("LVCMOS15")),
-
- ("user_dip_btn", 0, Pins("Y29"), IOStandard("LVCMOS25")),
- ("user_dip_btn", 1, Pins("W29"), IOStandard("LVCMOS25")),
- ("user_dip_btn", 2, Pins("AA28"), IOStandard("LVCMOS25")),
- ("user_dip_btn", 3, Pins("Y28"), IOStandard("LVCMOS25")),
-
- ("user_sma_clock", 0,
- Subsignal("p", Pins("L25"), IOStandard("LVDS_25")),
- Subsignal("n", Pins("K25"), IOStandard("LVDS_25"))
- ),
- ("user_sma_clock_p", 0, Pins("L25"), IOStandard("LVCMOS25")),
- ("user_sma_clock_n", 0, Pins("K25"), IOStandard("LVCMOS25")),
-
- ("user_sma_gpio_p", 0, Pins("Y23"), IOStandard("LVCMOS33")),
- ("user_sma_gpio_n", 0, Pins("Y24"), IOStandard("LVCMOS33")),
-
- ("clk200", 0,
- Subsignal("p", Pins("AD12"), IOStandard("LVDS")),
- Subsignal("n", Pins("AD11"), IOStandard("LVDS"))
- ),
-
- ("clk156", 0,
- Subsignal("p", Pins("K28"), IOStandard("LVDS_25")),
- Subsignal("n", Pins("K29"), IOStandard("LVDS_25"))
- ),
-
- ("i2c", 0,
- Subsignal("scl", Pins("K21")),
- Subsignal("sda", Pins("L21")),
- IOStandard("LVCMOS25")),
-
- ("serial", 0,
- Subsignal("cts", Pins("L27")),
- Subsignal("rts", Pins("K23")),
- Subsignal("tx", Pins("K24")),
- Subsignal("rx", Pins("M19")),
- IOStandard("LVCMOS25")),
-
- ("spiflash", 0, # clock needs to be accessed through STARTUPE2
- Subsignal("cs_n", Pins("U19")),
- Subsignal("dq", Pins("P24", "R25", "R20", "R21")),
- IOStandard("LVCMOS25")
- ),
-
- ("mmc", 0,
- Subsignal("wp", Pins("Y21")),
- Subsignal("det", Pins("AA21")),
- Subsignal("cmd", Pins("AB22")),
- Subsignal("clk", Pins("AB23")),
- Subsignal("dat", Pins("AC20 AA23 AA22 AC21")),
- IOStandard("LVCMOS25")),
-
- ("lcd", 0,
- Subsignal("db", Pins("AA13 AA10 AA11 Y10")),
- Subsignal("e", Pins("AB10")),
- Subsignal("rs", Pins("Y11")),
- Subsignal("rw", Pins("AB13")),
- IOStandard("LVCMOS15")),
-
- ("rotary", 0,
- Subsignal("a", Pins("Y26")),
- Subsignal("b", Pins("Y25")),
- Subsignal("push", Pins("AA26")),
- IOStandard("LVCMOS25")),
-
- ("hdmi", 0,
- Subsignal("d", Pins("B23 A23 E23 D23 F25 E25 E24 D24 F26 E26 G23 G24 J19 H19 L17 L18 K19 K20")),
- Subsignal("de", Pins("H17")),
- Subsignal("clk", Pins("K18")),
- Subsignal("vsync", Pins("H20")),
- Subsignal("hsync", Pins("J18")),
- Subsignal("int", Pins("AH24")),
- Subsignal("spdif", Pins("J17")),
- Subsignal("spdif_out", Pins("G20")),
- IOStandard("LVCMOS25")),
-
- ("ddram", 0,
- Subsignal("a", Pins(
- "AH12 AG13 AG12 AF12 AJ12 AJ13 AJ14 AH14",
- "AK13 AK14 AF13 AE13 AJ11 AH11 AK10 AK11"),
- IOStandard("SSTL15")),
- Subsignal("ba", Pins("AH9 AG9 AK9"), IOStandard("SSTL15")),
- Subsignal("ras_n", Pins("AD9"), IOStandard("SSTL15")),
- Subsignal("cas_n", Pins("AC11"), IOStandard("SSTL15")),
- Subsignal("we_n", Pins("AE9"), IOStandard("SSTL15")),
- Subsignal("cs_n", Pins("AC12"), IOStandard("SSTL15")),
- Subsignal("dm", Pins("Y16 AB17 AF17 AE16 AK5 AJ3 AF6 AC7"),
- IOStandard("SSTL15")),
- Subsignal("dq", Pins(
- "AA15 AA16 AC14 AD14 AA17 AB15 AE15 Y15",
- "AB19 AD16 AC19 AD17 AA18 AB18 AE18 AD18",
- "AG19 AK19 AG18 AF18 AH19 AJ19 AE19 AD19",
- "AK16 AJ17 AG15 AF15 AH17 AG14 AH15 AK15",
- "AK8 AK6 AG7 AF7 AF8 AK4 AJ8 AJ6",
- "AH5 AH6 AJ2 AH2 AH4 AJ4 AK1 AJ1",
- "AF1 AF2 AE4 AE3 AF3 AF5 AE1 AE5",
- "AC1 AD3 AC4 AC5 AE6 AD6 AC2 AD4"),
- IOStandard("SSTL15_T_DCI")),
- Subsignal("dqs_p", Pins("AC16 Y19 AJ18 AH16 AH7 AG2 AG4 AD2"),
- IOStandard("DIFF_SSTL15")),
- Subsignal("dqs_n", Pins("AC15 Y18 AK18 AJ16 AJ7 AH1 AG3 AD1"),
- IOStandard("DIFF_SSTL15")),
- Subsignal("clk_p", Pins("AG10"), IOStandard("DIFF_SSTL15")),
- Subsignal("clk_n", Pins("AH10"), IOStandard("DIFF_SSTL15")),
- Subsignal("cke", Pins("AF10"), IOStandard("SSTL15")),
- Subsignal("odt", Pins("AD8"), IOStandard("SSTL15")),
- Subsignal("reset_n", Pins("AK3"), IOStandard("LVCMOS15")),
- Misc("SLEW=FAST"),
- Misc("VCCAUX_IO=HIGH")
- ),
-
- ("eth_clocks", 0,
- Subsignal("tx", Pins("M28")),
- Subsignal("gtx", Pins("K30")),
- Subsignal("rx", Pins("U27")),
- IOStandard("LVCMOS25")
- ),
- ("eth", 0,
- Subsignal("rst_n", Pins("L20")),
- Subsignal("int_n", Pins("N30")),
- Subsignal("mdio", Pins("J21")),
- Subsignal("mdc", Pins("R23")),
- Subsignal("dv", Pins("R28")),
- Subsignal("rx_er", Pins("V26")),
- Subsignal("rx_data", Pins("U30 U25 T25 U28 R19 T27 T26 T28")),
- Subsignal("tx_en", Pins("M27")),
- Subsignal("tx_er", Pins("N29")),
- Subsignal("tx_data", Pins("N27 N25 M29 L28 J26 K26 L30 J28")),
- Subsignal("col", Pins("W19")),
- Subsignal("crs", Pins("R30")),
- IOStandard("LVCMOS25")
- ),
-
- ("pcie_x1", 0,
- Subsignal("rst_n", Pins("G25"), IOStandard("LVCMOS25")),
- Subsignal("clk_p", Pins("U8")),
- Subsignal("clk_n", Pins("U7")),
- Subsignal("rx_p", Pins("M6")),
- Subsignal("rx_n", Pins("M5")),
- Subsignal("tx_p", Pins("L4")),
- Subsignal("tx_n", Pins("L3"))
- ),
- ("pcie_x2", 0,
- Subsignal("rst_n", Pins("G25"), IOStandard("LVCMOS25")),
- Subsignal("clk_p", Pins("U8")),
- Subsignal("clk_n", Pins("U7")),
- Subsignal("rx_p", Pins("M6 P6")),
- Subsignal("rx_n", Pins("M5 P5")),
- Subsignal("tx_p", Pins("L4 M2")),
- Subsignal("tx_n", Pins("L3 M1"))
- ),
- ("pcie_x4", 0,
- Subsignal("rst_n", Pins("G25"), IOStandard("LVCMOS25")),
- Subsignal("clk_p", Pins("U8")),
- Subsignal("clk_n", Pins("U7")),
- Subsignal("rx_p", Pins("M6 P6 R4 T6")),
- Subsignal("rx_n", Pins("M5 P5 R3 T5")),
- Subsignal("tx_p", Pins("L4 M2 N4 P2")),
- Subsignal("tx_n", Pins("L3 M1 N3 P1"))
- ),
- ("pcie_x8", 0,
- Subsignal("rst_n", Pins("G25"), IOStandard("LVCMOS25")),
- Subsignal("clk_p", Pins("U8")),
- Subsignal("clk_n", Pins("U7")),
- Subsignal("rx_p", Pins("M6 P6 R4 T6 V6 W4 Y6 AA4")),
- Subsignal("rx_n", Pins("M5 P5 R3 T5 V5 W3 Y5 AA3")),
- Subsignal("tx_p", Pins("L4 M2 N4 P2 T2 U4 V2 Y2")),
- Subsignal("tx_n", Pins("L3 M1 N3 P1 T1 U3 V1 Y1"))
- )
-]
-
-_connectors = [
- ("HPC", {
- "DP1_M2C_P": "D6",
- "DP1_M2C_N": "D5",
- "DP2_M2C_P": "B6",
- "DP2_M2C_N": "B5",
- "DP3_M2C_P": "A8",
- "DP3_M2C_N": "A7",
- "DP1_C2M_P": "C4",
- "DP1_C2M_N": "C3",
- "DP2_C2M_P": "B2",
- "DP2_C2M_N": "B1",
- "DP3_C2M_P": "A4",
- "DP3_C2M_N": "A3",
- "DP0_C2M_P": "D2",
- "DP0_C2M_N": "D1",
- "DP0_M2C_P": "E4",
- "DP0_M2C_N": "E3",
- "LA06_P": "H30",
- "LA06_N": "G30",
- "LA10_P": "D29",
- "LA10_N": "C30",
- "LA14_P": "B28",
- "LA14_N": "A28",
- "LA18_CC_P": "F21",
- "LA18_CC_N": "E21",
- "LA27_P": "C19",
- "LA27_N": "B19",
- "HA01_CC_P": "H14",
- "HA01_CC_N": "G14",
- "HA05_P": "F15",
- "HA05_N": "E16",
- "HA09_P": "F12",
- "HA09_N": "E13",
- "HA13_P": "L16",
- "HA13_N": "K16",
- "HA16_P": "L15",
- "HA16_N": "K15",
- "HA20_P": "K13",
- "HA20_N": "J13",
- "CLK1_M2C_P": "D17",
- "CLK1_M2C_N": "D18",
- "LA00_CC_P": "C25",
- "LA00_CC_N": "B25",
- "LA03_P": "H26",
- "LA03_N": "H27",
- "LA08_P": "E29",
- "LA08_N": "E30",
- "LA12_P": "C29",
- "LA12_N": "B29",
- "LA16_P": "B27",
- "LA16_N": "A27",
- "LA20_P": "E19",
- "LA20_N": "D19",
- "LA22_P": "C20",
- "LA22_N": "B20",
- "LA25_P": "G17",
- "LA25_N": "F17",
- "LA29_P": "C17",
- "LA29_N": "B17",
- "LA31_P": "G22",
- "LA31_N": "F22",
- "LA33_P": "H21",
- "LA33_N": "H22",
- "HA03_P": "C12",
- "HA03_N": "B12",
- "HA07_P": "B14",
- "HA07_N": "A15",
- "HA11_P": "B13",
- "HA11_N": "A13",
- "HA14_P": "J16",
- "HA14_N": "H16",
- "HA18_P": "K14",
- "HA18_N": "J14",
- "HA22_P": "L11",
- "HA22_N": "K11",
- "GBTCLK1_M2C_P": "E8",
- "GBTCLK1_M2C_N": "E7",
- "GBTCLK0_M2C_P": "C8",
- "GBTCLK0_M2C_N": "C7",
- "LA01_CC_P": "D26",
- "LA01_CC_N": "C26",
- "LA05_P": "G29",
- "LA05_N": "F30",
- "LA09_P": "B30",
- "LA09_N": "A30",
- "LA13_P": "A25",
- "LA13_N": "A26",
- "LA17_CC_P": "F20",
- "LA17_CC_N": "E20",
- "LA23_P": "B22",
- "LA23_N": "A22",
- "LA26_P": "B18",
- "LA26_N": "A18",
- "PG_M2C": "J29",
- "HA00_CC_P": "D12",
- "HA00_CC_N": "D13",
- "HA04_P": "F11",
- "HA04_N": "E11",
- "HA08_P": "E14",
- "HA08_N": "E15",
- "HA12_P": "C15",
- "HA12_N": "B15",
- "HA15_P": "H15",
- "HA15_N": "G15",
- "HA19_P": "H11",
- "HA19_N": "H12",
- "PRSNT_M2C_B": "M20",
- "CLK0_M2C_P": "D27",
- "CLK0_M2C_N": "C27",
- "LA02_P": "H24",
- "LA02_N": "H25",
- "LA04_P": "G28",
- "LA04_N": "F28",
- "LA07_P": "E28",
- "LA07_N": "D28",
- "LA11_P": "G27",
- "LA11_N": "F27",
- "LA15_P": "C24",
- "LA15_N": "B24",
- "LA19_P": "G18",
- "LA19_N": "F18",
- "LA21_P": "A20",
- "LA21_N": "A21",
- "LA24_P": "A16",
- "LA24_N": "A17",
- "LA28_P": "D16",
- "LA28_N": "C16",
- "LA30_P": "D22",
- "LA30_N": "C22",
- "LA32_P": "D21",
- "LA32_N": "C21",
- "HA02_P": "D11",
- "HA02_N": "C11",
- "HA06_P": "D14",
- "HA06_N": "C14",
- "HA10_P": "A11",
- "HA10_N": "A12",
- "HA17_CC_P": "G13",
- "HA17_CC_N": "F13",
- "HA21_P": "J11",
- "HA21_N": "J12",
- "HA23_P": "L12",
- "HA23_N": "L13",
- }
- ),
- ("LPC", {
- "GBTCLK0_M2C_P": "N8",
- "GBTCLK0_M2C_N": "N7",
- "LA01_CC_P": "AE23",
- "LA01_CC_N": "AF23",
- "LA05_P": "AG22",
- "LA05_N": "AH22",
- "LA09_P": "AK23",
- "LA09_N": "AK24",
- "LA13_P": "AB24",
- "LA13_N": "AC25",
- "LA17_CC_P": "AB27",
- "LA17_CC_N": "AC27",
- "LA23_P": "AH26",
- "LA23_N": "AH27",
- "LA26_P": "AK29",
- "LA26_N": "AK30",
- "CLK0_M2C_P": "AF22",
- "CLK0_M2C_N": "AG23",
- "LA02_P": "AF20",
- "LA02_N": "AF21",
- "LA04_P": "AH21",
- "LA04_N": "AJ21",
- "LA07_P": "AG25",
- "LA07_N": "AH25",
- "LA11_P": "AE25",
- "LA11_N": "AF25",
- "LA15_P": "AC24",
- "LA15_N": "AD24",
- "LA19_P": "AJ26",
- "LA19_N": "AK26",
- "LA21_P": "AG27",
- "LA21_N": "AG28",
- "LA24_P": "AG30",
- "LA24_N": "AH30",
- "LA28_P": "AE30",
- "LA28_N": "AF30",
- "LA30_P": "AB29",
- "LA30_N": "AB30",
- "LA32_P": "Y30",
- "LA32_N": "AA30",
- "LA06_P": "AK20",
- "LA06_N": "AK21",
- "LA10_P": "AJ24",
- "LA10_N": "AK25",
- "LA14_P": "AD21",
- "LA14_N": "AE21",
- "LA18_CC_P": "AD27",
- "LA18_CC_N": "AD28",
- "LA27_P": "AJ28",
- "LA27_N": "AJ29",
- "CLK1_M2C_P": "AG29",
- "CLK1_M2C_N": "AH29",
- "LA00_CC_P": "AD23",
- "LA00_CC_N": "AE24",
- "LA03_P": "AG20",
- "LA03_N": "AH20",
- "LA08_P": "AJ22",
- "LA08_N": "AJ23",
- "LA12_P": "AA20",
- "LA12_N": "AB20",
- "LA16_P": "AC22",
- "LA16_N": "AD22",
- "LA20_P": "AF26",
- "LA20_N": "AF27",
- "LA22_P": "AJ27",
- "LA22_N": "AK28",
- "LA25_P": "AC26",
- "LA25_N": "AD26",
- "LA29_P": "AE28",
- "LA29_N": "AF28",
- "LA31_P": "AD29",
- "LA31_N": "AE29",
- "LA33_P": "AC29",
- "LA33_N": "AC30",
- }
- )
-]
-
-
-class Platform(XilinxPlatform):
- identifier = 0x4B37
- default_clk_name = "clk156"
- default_clk_period = 6.4
-
- def __init__(self, toolchain="vivado", programmer="xc3sprog"):
- XilinxPlatform.__init__(self, "xc7k325t-ffg900-2", _io, _connectors,
- toolchain=toolchain)
- if toolchain == "ise":
- self.toolchain.bitgen_opt = "-g LCK_cycle:6 -g Binary:Yes -w -g ConfigRate:12 -g SPI_buswidth:4"
- elif toolchain == "vivado":
- self.toolchain.bitstream_commands = ["set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]"]
- self.toolchain.additional_commands = ["write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit \"up 0x0 {build_name}.bit\" -file {build_name}.bin"]
- self.programmer = programmer
-
- def create_programmer(self):
- if self.programmer == "xc3sprog":
- return XC3SProg("jtaghs1_fast", "bscan_spi_kc705.bit")
- elif self.programmer == "vivado":
- return VivadoProgrammer()
- elif self.programmer == "impact":
- return iMPACT()
- else:
- raise ValueError("{} programmer is not supported".format(programmer))
-
- def do_finalize(self, fragment):
- XilinxPlatform.do_finalize(self, fragment)
- try:
- self.add_period_constraint(self.lookup_request("clk200").p, 5.0)
- except ConstraintError:
- pass
- try:
- self.add_period_constraint(self.lookup_request("eth_clocks").rx, 8.0)
- except ConstraintError:
- pass
- if isinstance(self.toolchain, XilinxISEToolchain):
- self.add_platform_command("CONFIG DCI_CASCADE = \"33 32 34\";")
- else:
- self.add_platform_command("set_property DCI_CASCADE {{32 34}} [get_iobanks 33]")
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-_io = [
- ("user_btn", 0, Pins("V4"), IOStandard("LVCMOS33"),
- Misc("PULLDOWN"), Misc("TIG")),
-
- ("user_led", 0, Pins("P4"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")),
- ("user_led", 1, Pins("L6"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")),
- ("user_led", 2, Pins("F5"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")),
- ("user_led", 3, Pins("C2"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")),
-
- ("user_dip", 0, Pins("B3"), Misc("PULLDOWN"), IOStandard("LVCMOS33")),
- ("user_dip", 1, Pins("A3"), Misc("PULLDOWN"), IOStandard("LVCMOS33")),
- ("user_dip", 2, Pins("B4"), Misc("PULLDOWN"), IOStandard("LVCMOS33")),
- ("user_dip", 3, Pins("A4"), Misc("PULLDOWN"), IOStandard("LVCMOS33")),
-
- # TI CDCE913 programmable triple-output PLL
- ("clk_y1", 0, Pins("V10"), IOStandard("LVCMOS33")), # default: 40 MHz
- ("clk_y2", 0, Pins("K15"), IOStandard("LVCMOS33")), # default: 66 2/3 MHz
- ("clk_y3", 0, Pins("C10"), IOStandard("LVCMOS33")), # default: 100 MHz
-
- # Maxim DS1088LU oscillator, not populated
- ("clk_backup", 0, Pins("R8"), IOStandard("LVCMOS33")),
-
- # TI CDCE913 PLL I2C control
- ("pll", 0,
- Subsignal("scl", Pins("P12")),
- Subsignal("sda", Pins("U13")),
- Misc("PULLUP"),
- IOStandard("LVCMOS33")),
-
- # Micron N25Q128 SPI Flash
- ("spiflash", 0,
- Subsignal("clk", Pins("R15")),
- Subsignal("cs_n", Pins("V3")),
- Subsignal("dq", Pins("T13 R13 T14 V14")),
- IOStandard("LVCMOS33")),
-
- # PMOD extension connectors
- ("pmod", 0,
- Subsignal("d", Pins("F15 F16 C17 C18 F14 G14 D17 D18")),
- IOStandard("LVCMOS33")),
- ("pmod", 1,
- Subsignal("d", Pins("H12 G13 E16 E18 K12 K13 F17 F18")),
- IOStandard("LVCMOS33")),
-
- ("pmod_diff", 0,
- Subsignal("io", Pins("F15 C17 F14 D17 H12 E16 K12 F17")),
- Subsignal("iob", Pins("F16 C18 G14 D18 G13 E18 K13 F18")),
- IOStandard("LVCMOS33")),
-
- ("serial", 0,
- Subsignal("tx", Pins("T7"), Misc("SLEW=SLOW")),
- Subsignal("rx", Pins("R7"), Misc("PULLUP")),
- IOStandard("LVCMOS33")),
-
- ("ddram_clock", 0,
- Subsignal("p", Pins("G3")),
- Subsignal("n", Pins("G1")),
- IOStandard("MOBILE_DDR")), # actually DIFF_
-
- # Micron MT46H32M16LFBF-5 LPDDR
- ("ddram", 0,
- Subsignal("a", Pins("J7 J6 H5 L7 F3 H4 H3 H6 "
- "D2 D1 F4 D3 G6")),
- Subsignal("ba", Pins("F2 F1")),
- Subsignal("dq", Pins("L2 L1 K2 K1 H2 H1 J3 J1 "
- "M3 M1 N2 N1 T2 T1 U2 U1")),
- Subsignal("cke", Pins("H7")),
- Subsignal("we_n", Pins("E3")),
- Subsignal("cs_n", Pins("K6")), # NC!
- Subsignal("cas_n", Pins("K5")),
- Subsignal("ras_n", Pins("L5")),
- Subsignal("dm", Pins("K3", "K4")),
- Subsignal("dqs", Pins("L4", "P2")),
- Subsignal("rzq", Pins("N4")),
- IOStandard("MOBILE_DDR")),
-
- # Nat Semi DP83848J 10/100 Ethernet PHY
- # pull-ups on col and rx_data set phy addr to 11111b
- # and prevent isolate mode (addr 00000b)
- ("eth_clocks", 0,
- Subsignal("rx", Pins("L15")),
- Subsignal("tx", Pins("H17")),
- IOStandard("LVCMOS33")),
-
- ("eth", 0,
- Subsignal("col", Pins("M18"), Misc("PULLUP")),
- Subsignal("crs", Pins("N17"), Misc("PULLDOWN")),
- Subsignal("mdc", Pins("M16"), Misc("PULLDOWN")),
- Subsignal("mdio", Pins("L18"), Misc("PULLUP")), # 1k5 ext PULLUP
- Subsignal("rst_n", Pins("T18"), Misc("TIG")),
- Subsignal("rx_data", Pins("T17 N16 N15 P18"), Misc("PULLUP")),
- Subsignal("dv", Pins("P17"), Misc("PULLDOWN")), # MII
- Subsignal("rx_er", Pins("N18"), Misc("PULLUP")), # auto MDIX
- Subsignal("tx_data", Pins("K18 K17 J18 J16")),
- Subsignal("tx_en", Pins("L17")),
- Subsignal("tx_er", Pins("L16")), # NC!
- IOStandard("LVCMOS33")),
- ]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk_y3"
- default_clk_period = 10
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6slx9-2csg324", _io)
- self.add_platform_command("""
-CONFIG VCCAUX = "3.3";
-""")
- self.toolchain.bitgen_opt = "-g LCK_cycle:6 -g Binary:Yes -w -g SPI_buswidth:4"
- self.toolchain.ise_commands = """
-promgen -w -spi -c FF -p mcs -o {build_name}.mcs -u 0 {build_name}.bit
-"""
-
- def do_finalize(self, fragment):
- XilinxPlatform.do_finalize(self, fragment)
-
- try:
- eth_clocks = self.lookup_request("eth_clocks")
- self.add_period_constraint(eth_clocks.rx, 40)
- self.add_period_constraint(eth_clocks.tx, 40)
- self.add_platform_command("""
-TIMESPEC "TS{phy_tx_clk}_io" = FROM "GRP{phy_tx_clk}" TO "PADS" 10 ns;
-TIMESPEC "TS{phy_rx_clk}_io" = FROM "PADS" TO "GRP{phy_rx_clk}" 10 ns;
-""", phy_rx_clk=eth_clocks.rx, phy_tx_clk=eth_clocks.tx)
- except ConstraintError:
- pass
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-from migen.build.xilinx.programmer import UrJTAG
-
-
-_io = [
- ("user_led", 0, Pins("B16"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")),
- ("user_led", 1, Pins("A16"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")),
-
- ("user_btn", 0, Pins("AB4"), IOStandard("LVCMOS33")),
- ("user_btn", 1, Pins("AA4"), IOStandard("LVCMOS33")),
- ("user_btn", 2, Pins("AB5"), IOStandard("LVCMOS33")),
-
- ("clk50", 0, Pins("AB11"), IOStandard("LVCMOS33")),
-
- # When executing softcore code in-place from the flash, we want
- # the flash reset to be released before the system reset.
- ("norflash_rst_n", 0, Pins("P22"), IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8)),
- ("norflash", 0,
- Subsignal("adr", Pins("L22 L20 K22 K21 J19 H20 F22",
- "F21 K17 J17 E22 E20 H18 H19 F20",
- "G19 C22 C20 D22 D21 F19 F18 D20 D19")),
- Subsignal("d", Pins("AA20 U14 U13 AA6 AB6 W4 Y4 Y7",
- "AA2 AB2 V15 AA18 AB18 Y13 AA12 AB12"), Misc("PULLDOWN")),
- Subsignal("oe_n", Pins("M22")),
- Subsignal("we_n", Pins("N20")),
- Subsignal("ce_n", Pins("M21")),
- IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8)
- ),
-
- ("serial", 0,
- Subsignal("tx", Pins("L17"), IOStandard("LVCMOS33"), Misc("SLEW=SLOW")),
- Subsignal("rx", Pins("K18"), IOStandard("LVCMOS33"), Misc("PULLUP"))
- ),
-
- ("ddram_clock", 0,
- Subsignal("p", Pins("M3")),
- Subsignal("n", Pins("L4")),
- IOStandard("SSTL2_I")
- ),
- ("ddram", 0,
- Subsignal("a", Pins("B1 B2 H8 J7 E4 D5 K7 F5 G6 C1 C3 D1 D2")),
- Subsignal("ba", Pins("A2 E6")),
- Subsignal("cs_n", Pins("F7")),
- Subsignal("cke", Pins("G7")),
- Subsignal("ras_n", Pins("E5")),
- Subsignal("cas_n", Pins("C4")),
- Subsignal("we_n", Pins("D3")),
- Subsignal("dq", Pins("Y2 W3 W1 P8 P7 P6 P5 T4 T3",
- "U4 V3 N6 N7 M7 M8 R4 P4 M6 L6 P3 N4",
- "M5 V2 V1 U3 U1 T2 T1 R3 R1 P2 P1")),
- Subsignal("dm", Pins("E1 E3 F3 G4")),
- Subsignal("dqs", Pins("F1 F2 H5 H6")),
- IOStandard("SSTL2_I")
- ),
-
- ("eth_clocks", 0,
- Subsignal("phy", Pins("M20")),
- Subsignal("rx", Pins("H22")),
- Subsignal("tx", Pins("H21")),
- IOStandard("LVCMOS33")
- ),
- ("eth", 0,
- Subsignal("rst_n", Pins("R22")),
- Subsignal("dv", Pins("V21")),
- Subsignal("rx_er", Pins("V22")),
- Subsignal("rx_data", Pins("U22 U20 T22 T21")),
- Subsignal("tx_en", Pins("N19")),
- Subsignal("tx_er", Pins("M19")),
- Subsignal("tx_data", Pins("M16 L15 P19 P20")),
- Subsignal("col", Pins("W20")),
- Subsignal("crs", Pins("W22")),
- IOStandard("LVCMOS33")
- ),
-
- ("vga_out", 0,
- Subsignal("clk", Pins("A11")),
- Subsignal("r", Pins("C6 B6 A6 C7 A7 B8 A8 D9")),
- Subsignal("g", Pins("C8 C9 A9 D7 D8 D10 C10 B10")),
- Subsignal("b", Pins("D11 C12 B12 A12 C13 A13 D14 C14")),
- Subsignal("hsync_n", Pins("A14")),
- Subsignal("vsync_n", Pins("C15")),
- Subsignal("psave_n", Pins("B14")),
- IOStandard("LVCMOS33")
- ),
-
- ("mmc", 0,
- Subsignal("clk", Pins("A10")),
- Subsignal("cmd", Pins("B18")),
- Subsignal("dat", Pins("A18 E16 C17 A17")),
- IOStandard("LVCMOS33")
- ),
-
- # Digital video mixer extension board
- ("dvi_in", 0,
- Subsignal("clk", Pins("A20")),
- Subsignal("data0_n", Pins("A21")),
- Subsignal("data1", Pins("B21")),
- Subsignal("data2_n", Pins("B22")),
- Subsignal("scl", Pins("G16")),
- Subsignal("sda", Pins("G17")),
- IOStandard("LVCMOS33")
- ),
- ("dvi_in", 1,
- Subsignal("clk", Pins("H17")),
- Subsignal("data0_n", Pins("H16")),
- Subsignal("data1", Pins("F17")),
- Subsignal("data2_n", Pins("F16")),
- Subsignal("scl", Pins("J16")),
- Subsignal("sda", Pins("K16")),
- IOStandard("LVCMOS33")
- ),
- ("dvi_pots", 0,
- Subsignal("charge", Pins("A18")), # SD_DAT0
- Subsignal("blackout", Pins("C17")), # SD_DAT2
- Subsignal("crossfade", Pins("A17")), # SD_DAT3
- IOStandard("LVCMOS33")
- )
-]
-
-
-class Platform(XilinxPlatform):
- identifier = 0x4D31
- default_clk_name = "clk50"
- default_clk_period = 20
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6slx45-fgg484-2", _io)
-
- def create_programmer(self):
- return UrJTAG(cable="milkymist", flash_proxy_basename="fjmem-m1.bit")
-
- def do_finalize(self, fragment):
- XilinxPlatform.do_finalize(self, fragment)
-
- try:
- eth_clocks = self.lookup_request("eth_clocks")
- self.add_period_constraint(eth_clocks.rx, 40)
- self.add_period_constraint(eth_clocks.tx, 40)
- self.add_platform_command("""
-TIMESPEC "TS{phy_tx_clk}_io" = FROM "GRP{phy_tx_clk}" TO "PADS" 10 ns;
-TIMESPEC "TS{phy_rx_clk}_io" = FROM "PADS" TO "GRP{phy_rx_clk}" 10 ns;
-""", phy_rx_clk=eth_clocks.rx, phy_tx_clk=eth_clocks.tx)
- except ConstraintError:
- pass
-
- for i in range(2):
- si = "dviclk"+str(i)
- try:
- self.add_period_constraint(self.lookup_request("dvi_in", i).clk, 26.7)
- except ConstraintError:
- pass
+++ /dev/null
-# This file is Copyright (c) 2015 William D. Jones <thor0505@comcast.net>
-# License: BSD
-
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-from migen.build.xilinx.programmer import XC3SProg
-
-
-_io = [
- ("clk50", 0, Pins("P43"), IOStandard("LVCMOS33")),
-
- ("user_btn", 0, Pins("P41"), IOStandard("LVTTL")),
-
- # The serial interface and flash memory have a shared SPI bus.
- # FPGA is secondary
- ("spiserial", 0,
- Subsignal("cs_n", Pins("P39"), IOStandard("LVTTL")),
- Subsignal("clk", Pins("P53"), IOStandard("LVTTL")),
- Subsignal("mosi", Pins("P46"), IOStandard("LVTTL")),
- Subsignal("miso", Pins("P51"), IOStandard("LVTTL"))
- ),
-
- # FPGA is primary
- ("spiflash", 0,
- Subsignal("cs_n", Pins("P27"), IOStandard("LVTTL")),
- Subsignal("clk", Pins("P53"), IOStandard("LVTTL")),
- Subsignal("mosi", Pins("P46"), IOStandard("LVTTL")),
- Subsignal("miso", Pins("P51"), IOStandard("LVTTL"))
- ),
-
- ("spiflash2x", 0,
- Subsignal("cs_n", Pins("P27")),
- Subsignal("clk", Pins("P53")),
- Subsignal("dq", Pins("P46", "P51")),
- IOStandard("LVTTL"), Misc("SLEW=FAST")
- ),
-
- # ADC over SPI- FPGA is primary
- ("adc", 0,
- Subsignal("cs_n", Pins("P12"), IOStandard("LVTTL")),
- Subsignal("clk", Pins("P9"), IOStandard("LVTTL")),
- Subsignal("mosi", Pins("P10"), IOStandard("LVTTL")),
- Subsignal("miso", Pins("P21"), IOStandard("LVTTL"))
- ),
-
- # GPIO control- SRAM and connectors are shared: these pins control how
- # to access each. Recommended to combine with gpio_sram_bus extension,
- # since these pins are related but not exposed on connectors.
- ("gpio_ctl", 0,
- Subsignal("ce_n", Pins("P3")), # Memory chip-enable. Called MEM_CEN
- # in schematic.
- Subsignal("bussw_oe_n", Pins("P30")), # 5V tolerant GPIO is shared
- # w/ memory using this pin.
- IOStandard("LVTTL"), Misc("SLEW=FAST")
- )
-]
-
-# Perhaps define some connectors as having a specific purpose- i.e. a 5V GPIO
-# bus with data, peripheral-select, and control signals?
-_connectors = [
- ("GPIO", """P59 P60 P61 P62 P64 P57
- P56 P52 P50 P49 P85 P84
- P83 P78 P77 P65 P70 P71
- P72 P73 P5 P4 P6 P98
- P94 P93 P90 P89 P88 P86"""), # 5V I/O- LVTTL
- ("DIO", "P20 P32 P33 P34 P35 P36 P37"), # Fast 3.3V IO (Directly attached
- # to FPGA)- LVCMOS33
- ("CLKIO", "P40 P44"), # Clock IO (Can be used as GPIO)- LVCMOS33
- ("INPUT", "P68 P97 P7 P82"), # Input-only pins- LVCMOS33
- ("LED", "P13 P15 P16 P19") # LEDs can be used as pins as well- LVTTL.
-]
-
-# Some default useful extensions- use platform.add_extension() to use, e.g.
-# from migen.build.platforms import mercury
-# plat = mercury.Platform()
-# plat.add_extension(mercury.gpio_sram)
-
-# SRAM and 5V-tolerant I/O share a parallel bus on 200k gate version. The SRAM
-# controller needs to take care of switching the bus between the two. Meant to
-# be Cat() into one GPIO bus, and combined with gpio_ctl.
-gpio_sram = [
- ("gpio_sram_bus", 0,
- Subsignal("a", Pins("""GPIO:0 GPIO:1 GPIO:2 GPIO:3
- GPIO:4 GPIO:5 GPIO:6 GPIO:7
- GPIO:8 GPIO:9 GPIO:10 GPIO:11
- GPIO:12 GPIO:13 GPIO:14 GPIO:15
- GPIO:16 GPIO:17 GPIO:18 GPIO:19""")),
- # A19 is actually unused- free for GPIO
- # 8-bit data bus
- Subsignal("d", Pins("""GPIO:20 GPIO:21 GPIO:22 GPIO:23
- GPIO:24 GPIO:25 GPIO:26 GPIO:27""")),
- Subsignal("we_n", Pins("GPIO:28")),
- Subsignal("unused", Pins("GPIO:29")), # Only used by GPIO.
- # Subsignal("oe_n", Pins()), # If OE wasn't tied to ground on Mercury,
- # this pin would be here.
- IOStandard("LVTTL"), Misc("SLEW=FAST")
- )
-]
-
-# The "serial port" is in fact over SPI. The creators of the board provide a
-# VHDL file for talking over this interface. In light of space constraints and
-# the fact that both the FT245RL and FPGA can BOTH be SPI primaries, however,
-# it may be necessary to sacrifice two "high-speed" (DIO, INPUT) pins instead.
-serial = [
- ("serial", 0,
- Subsignal("tx", Pins("DIO:0"), IOStandard("LVCMOS33")), # FTDI D1
- Subsignal("rx", Pins("INPUT:0"), IOStandard("LVCMOS33"))
- ) # FTDI D0
-]
-
-leds = [
- ("user_led", 0, Pins("LED:0"), IOStandard("LVTTL")),
- ("user_led", 1, Pins("LED:1"), IOStandard("LVTTL")),
- ("user_led", 2, Pins("LED:2"), IOStandard("LVTTL")),
- ("user_led", 3, Pins("LED:3"), IOStandard("LVTTL"))
-]
-
-# See: http://www.micro-nova.com/mercury-baseboard/
-# Not implemented yet.
-baseboard = [
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk50"
- default_clk_period = 20
-
- def __init__(self, device="xc3s200a-4-vq100"):
- XilinxPlatform.__init__(self, device, _io, _connectors)
- # Small device- optimize for AREA instead of SPEED (LM32 runs at about
- # 60-65MHz in AREA configuration).
- self.toolchain.xst_opt = """-ifmt MIXED
--use_new_parser yes
--opt_mode AREA
--register_balancing yes"""
-
- def create_programmer(self):
- raise NotImplementedError
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-_io = [
- ("clk100", 0, Pins("V10"), IOStandard("LVCMOS33")),
- ("clk12", 0, Pins("D9"), IOStandard("LVCMOS33")),
-
- ("serial", 0,
- Subsignal("tx", Pins("A8"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST")),
- Subsignal("rx", Pins("B8"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST"))),
-
- ("spiflash", 0,
- Subsignal("cs_n", Pins("V3")),
- Subsignal("clk", Pins("R15")),
- Subsignal("mosi", Pins("T13")),
- Subsignal("miso", Pins("R13"), Misc("PULLUP")),
- IOStandard("LVCMOS33"), Misc("SLEW=FAST")),
-
- ("ddram_clock", 0,
- Subsignal("p", Pins("G3")),
- Subsignal("n", Pins("G1")),
- IOStandard("MOBILE_DDR")),
-
- ("ddram", 0,
- Subsignal("a", Pins("J7 J6 H5 L7 F3 H4 H3 H6 D2 D1 F4 D3 G6")),
- Subsignal("ba", Pins("F2 F1")),
- Subsignal("cke", Pins("H7")),
- Subsignal("ras_n", Pins("L5")),
- Subsignal("cas_n", Pins("K5")),
- Subsignal("we_n", Pins("E3")),
- Subsignal(
- "dq", Pins("L2 L1 K2 K1 H2 H1 J3 J1 M3 M1 N2 N1 T2 T1 U2 U1")
- ),
- Subsignal("dqs", Pins("L4 P2")),
- Subsignal("dm", Pins("K3 K4")),
- IOStandard("MOBILE_DDR")),
-
- ("dipswitch", 0, Pins("C17"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("dipswitch", 1, Pins("C18"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("dipswitch", 2, Pins("D17"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("dipswitch", 3, Pins("D18"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("dipswitch", 4, Pins("E18"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("dipswitch", 5, Pins("E16"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("dipswitch", 6, Pins("F18"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("dipswitch", 7, Pins("F17"), IOStandard("LVCMOS33"), Misc("PULLUP")),
-
- ("buttonswitch", 0, Pins("K18"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("buttonswitch", 1, Pins("K17"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("buttonswitch", 2, Pins("L17"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("buttonswitch", 3, Pins("M16"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("buttonswitch", 4, Pins("L18"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("buttonswitch", 5, Pins("M18"), IOStandard("LVCMOS33"), Misc("PULLUP")),
-
- ("user_led", 0, Pins("T18"), IOStandard("LVCMOS33"), Drive(8)),
- ("user_led", 1, Pins("T17"), IOStandard("LVCMOS33"), Drive(8)),
- ("user_led", 2, Pins("U18"), IOStandard("LVCMOS33"), Drive(8)),
- ("user_led", 3, Pins("U17"), IOStandard("LVCMOS33"), Drive(8)),
- ("user_led", 4, Pins("N16"), IOStandard("LVCMOS33"), Drive(8)),
- ("user_led", 5, Pins("N15"), IOStandard("LVCMOS33"), Drive(8)),
- ("user_led", 6, Pins("P16"), IOStandard("LVCMOS33"), Drive(8)),
- ("user_led", 7, Pins("P15"), IOStandard("LVCMOS33"), Drive(8)),
-
- ("mmc", 0,
- Subsignal("dat", Pins("K14 G18 J13 L13"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST")),
-
- Subsignal("cmd", Pins("G16"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST")),
-
- Subsignal("clk", Pins("L12"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST"))),
-
- ("sevenseg", 0,
- Subsignal("segment7", Pins("A3"), IOStandard("LVCMOS33")), # A
- Subsignal("segment6", Pins("B4"), IOStandard("LVCMOS33")), # B
- Subsignal("segment5", Pins("A4"), IOStandard("LVCMOS33")), # C
- Subsignal("segment4", Pins("C4"), IOStandard("LVCMOS33")), # D
- Subsignal("segment3", Pins("C5"), IOStandard("LVCMOS33")), # E
- Subsignal("segment2", Pins("D6"), IOStandard("LVCMOS33")), # F
- Subsignal("segment1", Pins("C6"), IOStandard("LVCMOS33")), # G
- Subsignal("segment0", Pins("A5"), IOStandard("LVCMOS33")), # Dot
- Subsignal("enable0", Pins("B2"), IOStandard("LVCMOS33")), # EN0
- Subsignal("enable1", Pins("A2"), IOStandard("LVCMOS33")), # EN1
- Subsignal("enable2", Pins("B3"), IOStandard("LVCMOS33"))), # EN2
-
-
- ("audio", 0,
- Subsignal("channel1", Pins("B16"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST")),
- Subsignal("channel2", Pins("A16"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST"))),
-
- ("vga_out", 0,
- Subsignal("hsync_n", Pins("B12"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST")),
- Subsignal("vsync_n", Pins("A12"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST")),
- Subsignal("r", Pins("A9 B9 C9"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST")),
- Subsignal("g", Pins("C10 A10 C11"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST")),
- Subsignal("b", Pins("B11 A11"), IOStandard("LVCMOS33"),
- Misc("SLEW=FAST")))
-]
-
-_connectors = [
- ("P6", "T3 R3 V5 U5 V4 T4 V7 U7"),
- ("P7", "V11 U11 V13 U13 T10 R10 T11 R11"),
- ("P8", "L16 L15 K16 K15 J18 J16 H18 H17")
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk100"
- default_clk_period = 10
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6slx9-csg324-2", _io, _connectors)
-
- def create_programmer(self):
- raise NotImplementedError
+++ /dev/null
-# This file is Copyright (c) 2015 Matt O'Gorman <mog@rldn.net>
-# License: BSD
-
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-from migen.build.xilinx.programmer import XC3SProg, FpgaProg
-
-
-_io = [
- ("user_led", 0, Pins("P11"), IOStandard("LVCMOS33")),
- ("user_led", 1, Pins("N9"), IOStandard("LVCMOS33")),
- ("user_led", 2, Pins("M9"), IOStandard("LVCMOS33")),
- ("user_led", 3, Pins("P9"), IOStandard("LVCMOS33")),
- ("user_led", 4, Pins("T8"), IOStandard("LVCMOS33")),
- ("user_led", 5, Pins("N8"), IOStandard("LVCMOS33")),
- ("user_led", 6, Pins("P8"), IOStandard("LVCMOS33")),
- ("user_led", 7, Pins("P7"), IOStandard("LVCMOS33")),
-
- ("user_sw", 0, Pins("L1"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("user_sw", 1, Pins("L3"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("user_sw", 2, Pins("L4"), IOStandard("LVCMOS33"), Misc("PULLUP")),
- ("user_sw", 3, Pins("L5"), IOStandard("LVCMOS33"), Misc("PULLUP")),
-
- ("clk32", 0, Pins("J4"), IOStandard("LVCMOS33")),
- ("clk50", 0, Pins("K3"), IOStandard("LVCMOS33")),
-
- ("spiflash", 0,
- Subsignal("cs_n", Pins("T3"), IOStandard("LVCMOS33")),
- Subsignal("clk", Pins("R11"), IOStandard("LVCMOS33")),
- Subsignal("mosi", Pins("T10"), IOStandard("LVCMOS33")),
- Subsignal("miso", Pins("P10"), IOStandard("LVCMOS33"))
- ),
-
- ("adc", 0,
- Subsignal("cs_n", Pins("F6"), IOStandard("LVCMOS33")),
- Subsignal("clk", Pins("G6"), IOStandard("LVCMOS33")),
- Subsignal("mosi", Pins("H4"), IOStandard("LVCMOS33")),
- Subsignal("miso", Pins("H5"), IOStandard("LVCMOS33"))
- ),
-
- ("serial", 0,
- Subsignal("tx", Pins("N6"), IOStandard("LVCMOS33")), # FTDI D1
- Subsignal("rx", Pins("M7"), IOStandard("LVCMOS33")) # FTDI D0
- ),
-
- ("audio", 0,
- Subsignal("a0", Pins("B8"), IOStandard("LVCMOS33")),
- Subsignal("a1", Pins("A8"), IOStandard("LVCMOS33"))
- ),
-
- ("sdram_clock", 0, Pins("G16"), IOStandard("LVCMOS33"), Misc("SLEW=FAST")),
- ("sdram", 0,
- Subsignal("a", Pins("T15 R16 P15 P16 N16 M15 M16 L16 K15 K16 R15 J16 H15")),
- Subsignal("dq", Pins("T13 T12 R12 T9 R9 T7 R7 T6 F16 E15 E16 D16 B16 B15 C16 C15")),
- Subsignal("we_n", Pins("R5")),
- Subsignal("ras_n", Pins("R2")),
- Subsignal("cas_n", Pins("T4")),
- Subsignal("cs_n", Pins("R1")),
- Subsignal("cke", Pins("H16")),
- Subsignal("ba", Pins("R14 T14")),
- Subsignal("dm", Pins("T5 F15")),
- IOStandard("LVCMOS33"), Misc("SLEW=FAST")
- ),
-
- ("usb_fifo", 0,
- Subsignal("data", Pins("M7 N6 M6 P5 N5 P4 P2 P1")),
- Subsignal("rxf_n", Pins("N3")),
- Subsignal("txe_n", Pins("N1")),
- Subsignal("rd_n", Pins("M1")),
- Subsignal("wr_n", Pins("M2")),
- Subsignal("siwua", Pins("M3")),
- IOStandard("LVCMOS33"), Drive(8), Misc("SLEW=FAST")
- ),
-
- ("sd", 0,
- Subsignal("sck", Pins("L12")),
- Subsignal("d3", Pins("K12")),
- Subsignal("d", Pins("M10")),
- Subsignal("d1", Pins("L10")),
- Subsignal("d2", Pins("J11")),
- Subsignal("cmd", Pins("K11")),
- IOStandard("LVCMOS33")
- ),
-
- ("dvi_in", 0,
- Subsignal("clk_p", Pins("C9"), IOStandard("TMDS_33")),
- Subsignal("clk_n", Pins("A9"), IOStandard("TMDS_33")),
- Subsignal("data_p", Pins("C7 B6 B5"), IOStandard("TMDS_33")),
- Subsignal("data_n", Pins("A7 A6 A5"), IOStandard("TMDS_33")),
- Subsignal("scl", Pins("C1"), IOStandard("LVCMOS33")),
- Subsignal("sda", Pins("B1"), IOStandard("LVCMOS33"))
- ),
-
- ("dvi_out", 0,
- Subsignal("clk_p", Pins("B14"), IOStandard("TMDS_33")),
- Subsignal("clk_n", Pins("A14"), IOStandard("TMDS_33")),
- Subsignal("data_p", Pins("C13 B12 C11"), IOStandard("TMDS_33")),
- Subsignal("data_n", Pins("A13 A12 A11"), IOStandard("TMDS_33")),
- )
-]
-
-_connectors = [
- ("A", "E7 C8 D8 E8 D9 A10 B10 C10 E10 F9 F10 D11"),
- ("B", "E11 D14 D12 E12 E13 F13 F12 F14 G12 H14 J14"),
- ("C", "J13 J12 K14 L14 L13 M14 M13 N14 M12 N12 P12 M11"),
- ("D", "D6 C6 E6 C5"),
- ("E", "D5 A4 G5 A3 B3 A2 B2 C3 C2 D3 D1 E3"),
- ("F", "E2 E1 E4 F4 F5 G3 F3 G1 H3 H1 H2 J1")
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk32"
- default_clk_period = 31.25
-
- def __init__(self, device="xc6slx9", programmer="xc3sprog"):
- self.programmer = programmer
- XilinxPlatform.__init__(self, device+"-3-ftg256", _io, _connectors)
-
- def create_programmer(self):
- if self.programmer == "xc3sprog":
- return XC3SProg("minispartan6", "bscan_spi_minispartan6.bit")
- elif self.programmer == "fpgaprog":
- return FpgaProg()
- else:
- raise ValueError("{} programmer is not supported".format(programmer))
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-from migen.build.xilinx.programmer import UrJTAG
-
-
-_io = [
- ("user_led", 0, Pins("V5"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")),
-
- ("clk50", 0, Pins("AB13"), IOStandard("LVCMOS33")),
-
- # When executing softcore code in-place from the flash, we want
- # the flash reset to be released before the system reset.
- ("norflash_rst_n", 0, Pins("P22"), IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8)),
- ("norflash", 0,
- Subsignal("adr", Pins("L22 L20 K22 K21 J19 H20 F22",
- "F21 K17 J17 E22 E20 H18 H19 F20",
- "G19 C22 C20 D22 D21 F19 F18 D20 D19")),
- Subsignal("d", Pins("AA20 U14 U13 AA6 AB6 W4 Y4 Y7",
- "AA2 AB2 V15 AA18 AB18 Y13 AA12 AB12"), Misc("PULLDOWN")),
- Subsignal("oe_n", Pins("M22")),
- Subsignal("we_n", Pins("N20")),
- Subsignal("ce_n", Pins("M21")),
- IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8)
- ),
-
- ("serial", 0,
- Subsignal("tx", Pins("L17"), IOStandard("LVCMOS33"), Misc("SLEW=SLOW")),
- Subsignal("rx", Pins("K18"), IOStandard("LVCMOS33"), Misc("PULLUP"))
- ),
-
- ("ddram_clock", 0,
- Subsignal("p", Pins("M3")),
- Subsignal("n", Pins("L4")),
- IOStandard("SSTL2_I")
- ),
- ("ddram", 0,
- Subsignal("a", Pins("B1 B2 H8 J7 E4 D5 K7 F5 G6 C1 C3 D1 D2")),
- Subsignal("ba", Pins("A2 E6")),
- Subsignal("cs_n", Pins("F7")),
- Subsignal("cke", Pins("G7")),
- Subsignal("ras_n", Pins("E5")),
- Subsignal("cas_n", Pins("C4")),
- Subsignal("we_n", Pins("D3")),
- Subsignal("dq", Pins("Y2 W3 W1 P8 P7 P6 P5 T4 T3",
- "U4 V3 N6 N7 M7 M8 R4 P4 M6 L6 P3 N4",
- "M5 V2 V1 U3 U1 T2 T1 R3 R1 P2 P1")),
- Subsignal("dm", Pins("E1 E3 F3 G4")),
- Subsignal("dqs", Pins("F1 F2 H5 H6")),
- IOStandard("SSTL2_I")
- ),
-
- ("eth_clocks", 0,
- Subsignal("phy", Pins("M20")),
- Subsignal("rx", Pins("H22")),
- Subsignal("tx", Pins("H21")),
- IOStandard("LVCMOS33")
- ),
- ("eth", 0,
- Subsignal("rst_n", Pins("R22")),
- Subsignal("dv", Pins("V21")),
- Subsignal("rx_er", Pins("V22")),
- Subsignal("rx_data", Pins("U22 U20 T22 T21")),
- Subsignal("tx_en", Pins("N19")),
- Subsignal("tx_er", Pins("M19")),
- Subsignal("tx_data", Pins("M16 L15 P19 P20")),
- Subsignal("col", Pins("W20")),
- Subsignal("crs", Pins("W22")),
- IOStandard("LVCMOS33")
- ),
-
- ("vga_out", 0,
- Subsignal("clk", Pins("A10")),
- Subsignal("r", Pins("C6 B6 A6 C7 A7 B8 A8 D9")),
- Subsignal("g", Pins("C8 C9 A9 D7 D8 D10 C10 B10")),
- Subsignal("b", Pins("D11 C12 B12 A12 C13 A13 D14 C14")),
- Subsignal("hsync_n", Pins("A14")),
- Subsignal("vsync_n", Pins("C15")),
- Subsignal("psave_n", Pins("B14")),
- IOStandard("LVCMOS33")
- ),
- ("dvi_out", 0,
- Subsignal("clk_p", Pins("W12"), IOStandard("TMDS_33")),
- Subsignal("clk_n", Pins("Y12"), IOStandard("TMDS_33")),
- Subsignal("data0_p", Pins("Y16"), IOStandard("TMDS_33")),
- Subsignal("data0_n", Pins("W15"), IOStandard("TMDS_33")),
- Subsignal("data1_p", Pins("AA16"), IOStandard("TMDS_33")),
- Subsignal("data1_n", Pins("AB16"), IOStandard("TMDS_33")),
- Subsignal("data2_p", Pins("Y15"), IOStandard("TMDS_33")),
- Subsignal("data2_n", Pins("AB15"), IOStandard("TMDS_33")),
- ),
-
- ("mmc", 0,
- Subsignal("clk", Pins("J3")),
- Subsignal("cmd", Pins("K1")),
- Subsignal("dat", Pins("J6 K6 N1 K5")),
- IOStandard("LVCMOS33")
- ),
-
- ("dvi_in", 0,
- Subsignal("clk_p", Pins("K20"), IOStandard("TMDS_33")),
- Subsignal("clk_n", Pins("K19"), IOStandard("TMDS_33")),
- Subsignal("data0_p", Pins("B21"), IOStandard("TMDS_33")),
- Subsignal("data0_n", Pins("B22"), IOStandard("TMDS_33")),
- Subsignal("data1_p", Pins("A20"), IOStandard("TMDS_33")),
- Subsignal("data1_n", Pins("A21"), IOStandard("TMDS_33")),
- Subsignal("data2_p", Pins("K16"), IOStandard("TMDS_33")),
- Subsignal("data2_n", Pins("J16"), IOStandard("TMDS_33")),
- Subsignal("scl", Pins("G20"), IOStandard("LVCMOS33")),
- Subsignal("sda", Pins("H16"), IOStandard("LVCMOS33")),
- Subsignal("hpd_notif", Pins("G22"), IOStandard("LVCMOS33")),
- Subsignal("hpd_en", Pins("G17"), IOStandard("LVCMOS33"))
- ),
- ("dvi_in", 1,
- Subsignal("clk_p", Pins("C11"), IOStandard("TMDS_33")),
- Subsignal("clk_n", Pins("A11"), IOStandard("TMDS_33")),
- Subsignal("data0_p", Pins("B18"), IOStandard("TMDS_33")),
- Subsignal("data0_n", Pins("A18"), IOStandard("TMDS_33")),
- Subsignal("data1_p", Pins("C17"), IOStandard("TMDS_33")),
- Subsignal("data1_n", Pins("A17"), IOStandard("TMDS_33")),
- Subsignal("data2_p", Pins("E16"), IOStandard("TMDS_33")),
- Subsignal("data2_n", Pins("D17"), IOStandard("TMDS_33")),
- Subsignal("scl", Pins("F17"), IOStandard("LVCMOS33")),
- Subsignal("sda", Pins("F16"), IOStandard("LVCMOS33")),
- Subsignal("hpd_notif", Pins("G16"), IOStandard("LVCMOS33")),
- Subsignal("hpd_en", Pins("B20"), IOStandard("LVCMOS33"))
- ),
- ("dvi_in", 2,
- Subsignal("clk_p", Pins("Y11"), IOStandard("TMDS_33")),
- Subsignal("clk_n", Pins("AB11"), IOStandard("TMDS_33")),
- Subsignal("data0_p", Pins("V11"), IOStandard("TMDS_33")),
- Subsignal("data0_n", Pins("W11"), IOStandard("TMDS_33")),
- Subsignal("data1_p", Pins("AA10"), IOStandard("TMDS_33")),
- Subsignal("data1_n", Pins("AB10"), IOStandard("TMDS_33")),
- Subsignal("data2_p", Pins("R11"), IOStandard("TMDS_33")),
- Subsignal("data2_n", Pins("T11"), IOStandard("TMDS_33")),
- Subsignal("scl", Pins("C16"), IOStandard("LVCMOS33")),
- Subsignal("sda", Pins("B16"), IOStandard("LVCMOS33")),
- Subsignal("hpd_notif", Pins("D6"), IOStandard("LVCMOS33")),
- Subsignal("hpd_en", Pins("A4"), IOStandard("LVCMOS33"))
- ),
- ("dvi_in", 3,
- Subsignal("clk_p", Pins("J20"), IOStandard("TMDS_33")),
- Subsignal("clk_n", Pins("J22"), IOStandard("TMDS_33")),
- Subsignal("data0_p", Pins("P18"), IOStandard("TMDS_33")),
- Subsignal("data0_n", Pins("R19"), IOStandard("TMDS_33")),
- Subsignal("data1_p", Pins("P17"), IOStandard("TMDS_33")),
- Subsignal("data1_n", Pins("N16"), IOStandard("TMDS_33")),
- Subsignal("data2_p", Pins("M17"), IOStandard("TMDS_33")),
- Subsignal("data2_n", Pins("M18"), IOStandard("TMDS_33")),
- Subsignal("scl", Pins("P21"), IOStandard("LVCMOS33")),
- Subsignal("sda", Pins("N22"), IOStandard("LVCMOS33")),
- Subsignal("hpd_notif", Pins("H17"), IOStandard("LVCMOS33")),
- Subsignal("hpd_en", Pins("C19"), IOStandard("LVCMOS33"))
- ),
-]
-
-
-class Platform(XilinxPlatform):
- identifier = 0x4D58
- default_clk_name = "clk50"
- default_clk_period = 20
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6slx45-fgg484-2", _io)
- self.add_platform_command("CONFIG VCCAUX=\"3.3\";\n")
-
- def create_programmer(self):
- return UrJTAG("fjmem-mixxeo.bit")
-
- def do_finalize(self, fragment):
- XilinxPlatform.do_finalize(self, fragment)
-
- try:
- eth_clocks = self.lookup_request("eth_clocks")
- self.add_period_constraint(eth_clocks.rx, 40)
- self.add_period_constraint(eth_clocks.tx, 40)
- self.add_platform_command("""
-TIMESPEC "TS{phy_tx_clk}_io" = FROM "GRP{phy_tx_clk}" TO "PADS" 10 ns;
-TIMESPEC "TS{phy_rx_clk}_io" = FROM "PADS" TO "GRP{phy_rx_clk}" 10 ns;
-""", phy_rx_clk=eth_clocks.rx, phy_tx_clk=eth_clocks.tx)
- except ConstraintError:
- pass
-
- for i in range(4):
- try:
- self.add_period_constraint(self.lookup_request("dvi_in", i).clk_p, 12)
- except ConstraintError:
- pass
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-_io = [
- # System clock (Differential 200MHz)
- ("clk200", 0,
- Subsignal("p", Pins("J9"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")),
- Subsignal("n", Pins("H9"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE"))
- ),
-
- # User clock (66MHz)
- ("clk66", 0, Pins("U23"), IOStandard("LVCMOS25")),
-
- # CPU reset switch
- ("cpu_reset", 0, Pins("H10"), IOStandard("SSTL15")),
-
- # LEDs
- ("user_led", 0, Pins("AC22"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")),
- ("user_led", 1, Pins("AC24"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")),
- ("user_led", 2, Pins("AE22"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")),
- ("user_led", 3, Pins("AE23"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")),
- ("user_led", 4, Pins("AB23"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")),
- ("user_led", 5, Pins("AG23"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")),
- ("user_led", 6, Pins("AE24"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")),
- ("user_led", 7, Pins("AD24"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")),
-
- # USB-to-UART
- ("serial", 0,
- Subsignal("tx", Pins("J25"), IOStandard("LVCMOS25")),
- Subsignal("rx", Pins("J24"), IOStandard("LVCMOS25"))
- ),
-
- # 10/100/1000 Tri-Speed Ethernet PHY
- ("eth_clocks", 0,
- Subsignal("rx", Pins("AP11")),
- Subsignal("tx", Pins("AD12")),
- IOStandard("LVCMOS25")
- ),
- ("eth", 0,
- Subsignal("rst_n", Pins("AH13")),
- Subsignal("dv", Pins("AM13")),
- Subsignal("rx_er", Pins("AG12")),
- Subsignal("rx_data", Pins("AN13 AF14 AE14 AN12 AM12 AD11 AC12 AC13")),
- Subsignal("tx_en", Pins("AJ10")),
- Subsignal("tx_er", Pins("AH10")),
- Subsignal("tx_data", Pins("AM11 AL11 AG10 AG11 AL10 AM10 AE11 AF11")),
- Subsignal("col", Pins("AK13")),
- Subsignal("crs", Pins("AL13")),
- IOStandard("LVCMOS25")
- )
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk200"
- default_clk_period = 5
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6vlx240t-ff1156-1", _io)
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-from migen.build.xilinx.programmer import XC3SProg
-
-
-_io = [
- ("user_led", 0, Pins("P112"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")),
-
- ("clk32", 0, Pins("P94"), IOStandard("LVCMOS33")),
-
- ("serial", 0,
- Subsignal("tx", Pins("P105"), IOStandard("LVCMOS33"), Misc("SLEW=SLOW")),
- Subsignal("rx", Pins("P101"), IOStandard("LVCMOS33"), Misc("PULLUP"))
- ),
-
- ("spiflash", 0,
- Subsignal("cs_n", Pins("P38")),
- Subsignal("clk", Pins("P70")),
- Subsignal("mosi", Pins("P64")),
- Subsignal("miso", Pins("P65"), Misc("PULLUP")),
- IOStandard("LVCMOS33"), Misc("SLEW=FAST")
- ),
- ("spiflash2x", 0,
- Subsignal("cs_n", Pins("P38")),
- Subsignal("clk", Pins("P70")),
- Subsignal("dq", Pins("P64", "P65")),
- IOStandard("LVCMOS33"), Misc("SLEW=FAST")
- ),
-
- ("sdram_clock", 0, Pins("P32"), IOStandard("LVCMOS33"), Misc("SLEW=FAST")),
- ("sdram", 0,
- Subsignal("a", Pins("P140 P139 P138 P137 P46 P45 P44",
- "P43 P41 P40 P141 P35 P34")),
- Subsignal("ba", Pins("P143 P142")),
- Subsignal("cs_n", Pins("P1")),
- Subsignal("cke", Pins("P33")),
- Subsignal("ras_n", Pins("P2")),
- Subsignal("cas_n", Pins("P5")),
- Subsignal("we_n", Pins("P6")),
- Subsignal("dq", Pins("P9 P10 P11 P12 P14 P15 P16 P8 P21 P22 P23 P24 P26 P27 P29 P30")),
- Subsignal("dm", Pins("P7 P17")),
- IOStandard("LVCMOS33"), Misc("SLEW=FAST")
- )
-]
-
-_connectors = [
- ("A", "P48 P51 P56 P58 P61 P66 P67 P75 P79 P81 P83 P85 P88 P93 P98 P100"),
- ("B", "P99 P97 P92 P87 P84 P82 P80 P78 P74 P95 P62 P59 P57 P55 P50 P47"),
- ("C", "P114 P115 P116 P117 P118 P119 P120 P121 P123 P124 P126 P127 P131 P132 P133 P134")
-]
-
-
-class Platform(XilinxPlatform):
- identifier = 0x5050
- default_clk_name = "clk32"
- default_clk_period = 31.25
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6slx9-tqg144-2", _io, _connectors)
-
- def create_programmer(self):
- return XC3SProg("papilio", "bscan_spi_lx9_papilio.bit")
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-from migen.build.xilinx.programmer import XC3SProg
-
-
-_io = [
- ("user_led", 0, Pins("V16"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # green at hdmi
- ("user_led", 1, Pins("U16"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # red at hdmi
- ("user_led", 2, Pins("A16"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # green at msd
- ("user_led", 3, Pins("A15"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # red at msd
- ("user_led", 4, Pins("A12"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # red at usb
-
- ("user_btn", 0, Pins("N14"), IOStandard("LVTTL"), Misc("PULLDOWN")),
-
- ("clk50", 0, Pins("H17"), IOStandard("LVTTL")),
-
- ("serial", 0,
- Subsignal("tx", Pins("A10")),
- Subsignal("rx", Pins("A11"), Misc("PULLUP")),
- Subsignal("cts", Pins("C10"), Misc("PULLUP")),
- Subsignal("rts", Pins("A9"), Misc("PULLUP")),
- IOStandard("LVTTL"),
- ),
-
- ("usb_fifo", 0,
- Subsignal("data", Pins("A11 A10 C10 A9 B9 A8 B8 A7")),
- Subsignal("rxf_n", Pins("C7")),
- Subsignal("txe_n", Pins("A6")),
- Subsignal("rd_n", Pins("B6")),
- Subsignal("wr_n", Pins("A5")),
- Subsignal("siwua", Pins("C5")),
- IOStandard("LVTTL"),
- ),
-
- ("hdmi", 0,
- Subsignal("clk_p", Pins("U5"), IOStandard("TMDS_33")),
- Subsignal("clk_n", Pins("V5"), IOStandard("TMDS_33")),
- Subsignal("data0_p", Pins("T6"), IOStandard("TMDS_33")),
- Subsignal("data0_n", Pins("V6"), IOStandard("TMDS_33")),
- Subsignal("data1_p", Pins("U7"), IOStandard("TMDS_33")),
- Subsignal("data1_n", Pins("V7"), IOStandard("TMDS_33")),
- Subsignal("data2_p", Pins("U8"), IOStandard("TMDS_33")),
- Subsignal("data2_n", Pins("V8"), IOStandard("TMDS_33")),
- Subsignal("scl", Pins("V9"), IOStandard("I2C")),
- Subsignal("sda", Pins("T9"), IOStandard("I2C")),
- Subsignal("hpd_notif", Pins("R8"), IOStandard("LVTTL")),
- ),
-
- ("spiflash", 0,
- Subsignal("cs_n", Pins("V3")),
- Subsignal("clk", Pins("R15")),
- Subsignal("mosi", Pins("T13")),
- Subsignal("miso", Pins("R13"), Misc("PULLUP")),
- Subsignal("wp", Pins("T14")),
- Subsignal("hold", Pins("V14")),
- IOStandard("LVTTL"), Misc("SLEW=FAST")
- ),
-
- ("spiflash2x", 0,
- Subsignal("cs_n", Pins("V3")),
- Subsignal("clk", Pins("R15")),
- Subsignal("dq", Pins("T13 R13"), Misc("PULLUP")),
- Subsignal("wp", Pins("T14")),
- Subsignal("hold", Pins("V14")),
- IOStandard("LVTTL"), Misc("SLEW=FAST")
- ),
-
- ("spiflash4x", 0,
- Subsignal("cs_n", Pins("V3")),
- Subsignal("clk", Pins("R15")),
- Subsignal("dq", Pins("T13 R13 T14 V14"), Misc("PULLUP")),
- IOStandard("LVTTL"), Misc("SLEW=FAST")
- ),
-
- ("mmc", 0,
- Subsignal("clk", Pins("A3")),
- Subsignal("cmd", Pins("B3"), Misc("PULLUP")),
- Subsignal("dat", Pins("B4 A4 B2 A2"), Misc("PULLUP")),
- IOStandard("SDIO")
- ),
-
- ("mmc_spi", 0,
- Subsignal("cs_n", Pins("A2"), Misc("PULLUP")),
- Subsignal("clk", Pins("A3")),
- Subsignal("mosi", Pins("B3")),
- Subsignal("miso", Pins("B4"), Misc("PULLUP")),
- IOStandard("SDIO")
- ),
-
- ("audio", 0,
- Subsignal("l", Pins("R7"), Misc("SLEW=SLOW")),
- Subsignal("r", Pins("T7"), Misc("SLEW=SLOW")),
- IOStandard("LVTTL"),
- ),
-
- ("pmod", 0,
- Subsignal("d", Pins("D9 C8 D6 C4 B11 C9 D8 C6")),
- IOStandard("LVTTL")
- ),
-
- ("ddram_clock", 0,
- Subsignal("p", Pins("G3")),
- Subsignal("n", Pins("G1")),
- IOStandard("MOBILE_DDR")
- ),
-
- ("ddram", 0,
- Subsignal("a", Pins("J7 J6 H5 L7 F3 H4 H3 H6 D2 D1 F4 D3 G6")),
- Subsignal("ba", Pins("F2 F1")),
- Subsignal("cke", Pins("H7")),
- Subsignal("ras_n", Pins("L5")),
- Subsignal("cas_n", Pins("K5")),
- Subsignal("we_n", Pins("E3")),
- Subsignal("dq", Pins("L2 L1 K2 K1 H2 H1 J3 J1 M3 M1 N2 N1 T2 T1 U2 U1")),
- Subsignal("dqs", Pins("L4 P2")),
- Subsignal("dm", Pins("K3 K4")),
- IOStandard("MOBILE_DDR")
- )
-]
-
-_connectors = [
- ("A", "U18 T17 P17 P16 N16 N17 M16 L15 L17 K15 K17 J16 H15 H18 F18 D18"),
- ("B", "C18 E18 G18 H16 J18 K18 K16 L18 L16 M18 N18 N15 P15 P18 T18 U17"),
- ("C", "F17 F16 E16 G16 F15 G14 F14 H14 H13 J13 G13 H12 K14 K13 K12 L12"),
-]
-
-
-class Platform(XilinxPlatform):
- identifier = 0x5049
- default_clk_name = "clk50"
- default_clk_period = 20
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6slx45-csg324-3", _io, _connectors)
- self.toolchain.bitgen_opt += " -g Compress -g ConfigRate:6"
-
- def create_programmer(self):
- return XC3SProg("papilio", "bscan_spi_lx45_csg324.bit")
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-_io = [
- ("user_led", 0, Pins("Y3")),
- ("user_led", 1, Pins("Y1")),
- ("user_led", 2, Pins("W2")),
- ("user_led", 3, Pins("W1")),
- ("user_led", 4, Pins("V3")),
- ("user_led", 5, Pins("V1")),
- ("user_led", 6, Pins("U2")),
- ("user_led", 7, Pins("U1")),
-
- ("clk100", 0,
- Subsignal("p", Pins("B14"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")),
- Subsignal("n", Pins("A14"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE"))
- ),
-
- ("gpio", 0, Pins("R8")),
-
- ("gpmc", 0,
- Subsignal("clk", Pins("R26")),
- Subsignal("a", Pins("N17 N18 L23 L24 N19 N20 N21 N22 P17 P19")),
- Subsignal("d", Pins("N23 N24 R18 R19 P21 P22 R20 R21 P24 P26 R23 R24 T22 T23 U23 R25")),
- Subsignal("we_n", Pins("W26")),
- Subsignal("oe_n", Pins("AA25")),
- Subsignal("ale_n", Pins("AA26")),
- Subsignal("wait", Pins("AD26")), # WAIT1/BUSY0
- IOStandard("LVCMOS33")),
- # Warning: CS are numbered 1-7 on ARM side and 0-6 on FPGA side.
- # Numbers here are given on the FPGA side.
- ("gpmc_ce_n", 0, Pins("V23"), IOStandard("LVCMOS33")), # nCS0
- ("gpmc_ce_n", 1, Pins("U25"), IOStandard("LVCMOS33")), # nCS1
- ("gpmc_ce_n", 2, Pins("W25"), IOStandard("LVCMOS33")), # nCS6
- ("gpmc_dmareq_n", 0, Pins("T24"), IOStandard("LVCMOS33")), # nCS2
- ("gpmc_dmareq_n", 1, Pins("T26"), IOStandard("LVCMOS33")), # nCS3
- ("gpmc_dmareq_n", 2, Pins("V24"), IOStandard("LVCMOS33")), # nCS4
- ("gpmc_dmareq_n", 3, Pins("V26"), IOStandard("LVCMOS33")), # nCS5
-
- # FMC150
- ("fmc150_ctrl", 0,
- Subsignal("spi_sclk", Pins("AE5")),
- Subsignal("spi_data", Pins("AF5")),
-
- Subsignal("adc_sdo", Pins("U13")),
- Subsignal("adc_en_n", Pins("AA15")),
- Subsignal("adc_reset", Pins("V13")),
-
- Subsignal("cdce_sdo", Pins("AA8")),
- Subsignal("cdce_en_n", Pins("Y9")),
- Subsignal("cdce_reset_n", Pins("AB7")),
- Subsignal("cdce_pd_n", Pins("AC6")),
- Subsignal("cdce_pll_status", Pins("W7")),
- Subsignal("cdce_ref_en", Pins("W8")),
-
- Subsignal("dac_sdo", Pins("W9")),
- Subsignal("dac_en_n", Pins("W10")),
-
- Subsignal("mon_sdo", Pins("AC5")),
- Subsignal("mon_en_n", Pins("AD6")),
- Subsignal("mon_reset_n", Pins("AF6")),
- Subsignal("mon_int_n", Pins("AD5")),
-
- Subsignal("pg_c2m", Pins("AA23"), IOStandard("LVCMOS33"))
- ),
- ("ti_dac", 0, # DAC3283
- Subsignal("dat_p", Pins("AA10 AA9 V11 Y11 W14 Y12 AD14 AE13"), IOStandard("LVDS_25")),
- Subsignal("dat_n", Pins("AB11 AB9 V10 AA11 Y13 AA12 AF14 AF13"), IOStandard("LVDS_25")),
- Subsignal("frame_p", Pins("AB13"), IOStandard("LVDS_25")),
- Subsignal("frame_n", Pins("AA13"), IOStandard("LVDS_25")),
- Subsignal("txenable", Pins("AB15"), IOStandard("LVCMOS25"))
- ),
- ("ti_adc", 0, # ADS62P49
- Subsignal("dat_a_p", Pins("AB14 Y21 W20 AB22 V18 W17 AA21")),
- Subsignal("dat_a_n", Pins("AC14 AA22 Y20 AC22 W19 W18 AB21")),
- Subsignal("dat_b_p", Pins("Y17 U15 AA19 W16 AA18 Y15 V14")),
- Subsignal("dat_b_n", Pins("AA17 V16 AB19 Y16 AB17 AA16 V15")),
- IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")
- ),
- ("fmc150_clocks", 0,
- Subsignal("dac_clk_p", Pins("V12"), IOStandard("LVDS_25")),
- Subsignal("dac_clk_n", Pins("W12"), IOStandard("LVDS_25")),
- Subsignal("adc_clk_p", Pins("AE15"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")),
- Subsignal("adc_clk_n", Pins("AF15"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")),
- Subsignal("clk_to_fpga", Pins("W24"), IOStandard("LVCMOS25"))
- ),
-
- ("fmc150_ext_trigger", 0, Pins("U26")),
-
- # Vermeer radar testbed
- # Switch controller
- ("pca9555", 0,
- Subsignal("sda", Pins("C13")),
- Subsignal("scl", Pins("G8")),
- IOStandard("LVCMOS33")
- ),
- # TX path
- ("pe43602", 0,
- Subsignal("d", Pins("H8")),
- Subsignal("clk", Pins("B3")),
- Subsignal("le", Pins("F7")),
- IOStandard("LVCMOS33")
- ),
- ("rfmd2081", 0,
- Subsignal("enx", Pins("E5")),
- Subsignal("sclk", Pins("G6")),
- Subsignal("sdata", Pins("F5")),
- Subsignal("locked", Pins("E6")),
- IOStandard("LVCMOS33")
- ),
- # RX path
- ("lmh6521", 0,
- Subsignal("scsb", Pins("C5")),
- Subsignal("sclk", Pins("G10")),
- Subsignal("sdi", Pins("D5")),
- Subsignal("sdo", Pins("F9")),
- IOStandard("LVCMOS33")
- ),
- ("lmh6521", 1,
- Subsignal("scsb", Pins("E10")),
- Subsignal("sclk", Pins("A4")),
- Subsignal("sdi", Pins("B4")),
- Subsignal("sdo", Pins("H10")),
- IOStandard("LVCMOS33")
- ),
- ("rffc5071", 0,
- Subsignal("enx", Pins("A2")),
- Subsignal("sclk", Pins("G9")),
- Subsignal("sdata", Pins("H9")),
- Subsignal("locked", Pins("A3")),
- IOStandard("LVCMOS33")
- )
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk100"
- default_clk_period = 10
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6slx150t-fgg676-3", _io)
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-_io = [
- ("epb", 0,
- Subsignal("cs_n", Pins("K13")),
- Subsignal("r_w_n", Pins("AF20")),
- Subsignal("be_n", Pins("AF14 AF18")),
- Subsignal("oe_n", Pins("AF21")),
- Subsignal("addr", Pins("AE23 AE22 AG18 AG12 AG15 AG23 AF19 AE12 AG16 AF13 AG20 AF23",
- "AH17 AH15 L20 J22 H22 L15 L16 K22 K21 K16 J15")),
- Subsignal("addr_gp", Pins("L21 G22 K23 K14 L14 J12")),
- Subsignal("data", Pins("AF15 AE16 AE21 AD20 AF16 AE17 AE19 AD19 AG22 AH22 AH12 AG13",
- "AH20 AH19 AH14 AH13")),
- Subsignal("rdy", Pins("K12")),
- IOStandard("LVCMOS33")
- ),
- ("roach_clocks", 0,
- Subsignal("epb_clk", Pins("AH18"), IOStandard("LVCMOS33")),
- Subsignal("sys_clk_n", Pins("H13")),
- Subsignal("sys_clk_p", Pins("J14")),
- Subsignal("aux0_clk_p", Pins("G15")),
- Subsignal("aux0_clk_n", Pins("G16")),
- Subsignal("aux1_clk_p", Pins("H14")),
- Subsignal("aux1_clk_n", Pins("H15")),
- Subsignal("dly_clk_n", Pins("J17")),
- Subsignal("dly_clk_p", Pins("J16")),
- ),
-]
-
-
-class Platform(XilinxPlatform):
- def __init__(self):
- XilinxPlatform.__init__(self, "xc5vsx95t-ff1136-1", _io)
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.sim import SimPlatform
-
-
-class SimPins(Pins):
- def __init__(self, n):
- Pins.__init__(self, "s "*n)
-
-_io = [
- ("sys_clk", 0, SimPins(1)),
- ("sys_rst", 0, SimPins(1)),
- ("serial", 0,
- Subsignal("source_stb", SimPins(1)),
- Subsignal("source_ack", SimPins(1)),
- Subsignal("source_data", SimPins(8)),
-
- Subsignal("sink_stb", SimPins(1)),
- Subsignal("sink_ack", SimPins(1)),
- Subsignal("sink_data", SimPins(8)),
- ),
- ("eth_clocks", 0,
- Subsignal("none", SimPins(1)),
- ),
- ("eth", 0,
- Subsignal("source_stb", SimPins(1)),
- Subsignal("source_ack", SimPins(1)),
- Subsignal("source_data", SimPins(8)),
-
- Subsignal("sink_stb", SimPins(1)),
- Subsignal("sink_ack", SimPins(1)),
- Subsignal("sink_data", SimPins(8)),
- ),
-]
-
-
-class Platform(SimPlatform):
- is_sim = True
- default_clk_name = "sys_clk"
- default_clk_period = 1000 # on modern computers simulate at ~ 1MHz
-
- def __init__(self):
- SimPlatform.__init__(self, "SIM", _io)
-
- def do_finalize(self, fragment):
- pass
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-_io = [
- ("clk64", 0,
- Subsignal("p", Pins("R7")),
- Subsignal("n", Pins("T7")),
- IOStandard("LVDS_33"),
- Misc("DIFF_TERM=TRUE"),
- ),
-
- ("pps", 0, Pins("M14"), Misc("TIG")),
- ("reset_n", 0, Pins("D5"), Misc("TIG")),
- ("codec_reset", 0, Pins("B14")),
- # recycles fpga_cfg_cclk for reset from fw
- ("ext_reset", 0, Pins("R14")),
-
- ("i2c", 0,
- Subsignal("sda", Pins("T13")),
- Subsignal("scl", Pins("R13")),
- ),
-
- ("cgen", 0,
- Subsignal("st_ld", Pins("M13")),
- Subsignal("st_refmon", Pins("J14")),
- Subsignal("st_status", Pins("P6")),
- Subsignal("ref_sel", Pins("T2")),
- Subsignal("sync_b", Pins("H15")),
- ),
-
- ("fx2_ifclk", 0, Pins("T8")),
- ("fx2_gpif", 0,
- Subsignal("d", Pins("P8 P9 N9 T9 R9 P11 P13 N12 "
- "T3 R3 P5 N6 T6 T5 N8 P7")),
- Subsignal("ctl", Pins("M7 M9 M11 P12")),
- Subsignal("slwr", Pins("T4")), # rdy0
- Subsignal("slrd", Pins("R5")), # rdy1
- # Subsignal("rdy2", Pins("T10")),
- # Subsignal("rdy3", Pins("N11")),
- # Subsignal("cs", Pins("P12")),
- Subsignal("sloe", Pins("R11")),
- Subsignal("pktend", Pins("P10")),
- Subsignal("adr", Pins("T11 H16")),
- ),
-
- ("user_led", 0, Pins("P4"), Misc("TIG")),
- ("user_led", 1, Pins("N4"), Misc("TIG")),
- ("user_led", 2, Pins("R2"), Misc("TIG")),
-
- ("debug_clk", 0, Pins("K15 K14")),
- ("debug", 0, Pins(
- "K16 J16 C16 C15 E13 D14 D16 D15 "
- "E14 F13 G13 F14 E16 F15 H13 G14 "
- "G16 F16 J12 J13 L14 L16 M15 M16 "
- "L13 K13 P16 N16 R15 P15 N13 N14")),
-
- ("adc", 0,
- Subsignal("sync", Pins("D10")),
- Subsignal("d", Pins("A4 B3 A3 D9 C10 A9 C9 D8 "
- "C8 B8 A8 B15")),
- ),
- ("dac", 0,
- Subsignal("blank", Pins("K1")),
- Subsignal("sync", Pins("J2")),
- Subsignal("d", Pins("J1 H3 J3 G2 H1 N3 M4 R1 "
- "P2 P1 M1 N1 M3 L4")),
- ),
- ("codec_spi", 0,
- Subsignal("sclk", Pins("K3")),
- Subsignal("sen", Pins("D13")),
- Subsignal("mosi", Pins("C13")),
- Subsignal("miso", Pins("G4")),
- ),
-
- ("aux_spi", 0,
- Subsignal("sen", Pins("C12")),
- Subsignal("sclk", Pins("D12")),
- Subsignal("miso", Pins("J5")),
- ),
- ("rx_io", 0, Pins("D7 C6 A6 B6 E9 A7 C7 B10 "
- "A10 C11 A11 D11 B12 A12 A14 A13")),
- ("tx_io", 0, Pins("K4 L3 L2 F1 F3 G3 E3 E2 "
- "E4 F4 D1 E1 D4 D3 C2 C1")),
- ("rx_spi", 0,
- Subsignal("miso", Pins("E6")),
- Subsignal("sen", Pins("B4")),
- Subsignal("mosi", Pins("A5")),
- Subsignal("sclk", Pins("C5")),
- ),
- ("tx_spi", 0,
- Subsignal("miso", Pins("J4")),
- Subsignal("sen", Pins("N2")),
- Subsignal("mosi", Pins("L1")),
- Subsignal("sclk", Pins("G1")),
- ),
-
- # these are just for information. do not request.
- ("mystery_bus", 0, Pins("C4 E7")),
- ("fpga_cfg",
- Subsignal("din", Pins("T14")),
- Subsignal("cclk", Pins("R14")),
- Subsignal("init_b", Pins("T12")),
- Subsignal("prog_b", Pins("A2")),
- Subsignal("done", Pins("T15")),
- ),
- ("jtag",
- Subsignal("tms", Pins("B2")),
- Subsignal("tdo", Pins("B16")),
- Subsignal("tdi", Pins("B1")),
- Subsignal("tck", Pins("A15")),
- ),
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk64"
- default_clk_period = 15.625
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc3s1400a-ft256-4", _io)
- self.toolchain.bitgen_opt = "-g LCK_cycle:6 -g Binary:Yes -w -g UnusedPin:PullUp"
-
- def do_finalize(self, fragment):
- XilinxPlatform.do_finalize(self, fragment)
-
- self.add_platform_command("""
-TIMESPEC TS_Pad2Pad = FROM PADS TO PADS 7 ns;
-""")
-
- try:
- ifclk = self.lookup_request("fx2_ifclk")
- gpif = self.lookup_request("fx2_gpif")
- for i, d in [(gpif.d, "in"), (gpif.d, "out"),
- (gpif.ctl, "in"), (gpif.adr, "out"),
- (gpif.slwr, "out"), (gpif.sloe, "out"),
- (gpif.slrd, "out"), (gpif.pktend, "out")]:
- if len(i) > 1:
- q = "(*)"
- else:
- q = ""
- self.add_platform_command("""
-INST "{i}%s" TNM = gpif_net_%s;
-""" % (q, d), i=i)
- self.add_platform_command("""
-NET "{ifclk}" TNM_NET = "GRPifclk";
-TIMESPEC "TSifclk" = PERIOD "GRPifclk" 20833 ps HIGH 50%;
-TIMEGRP "gpif_net_in" OFFSET = IN 5 ns VALID 10 ns BEFORE "{ifclk}" RISING;
-TIMEGRP "gpif_net_out" OFFSET = OUT 7 ns AFTER "{ifclk}" RISING;
-""", ifclk=ifclk)
- except ConstraintError:
- pass
+++ /dev/null
-# This file is Copyright (c) 2013 Florent Kermarrec <florent@enjoy-digital.fr>
-# License: BSD
-
-from migen.build.generic_platform import *
-from migen.build.lattice import LatticePlatform
-from migen.build.lattice.programmer import LatticeProgrammer
-
-
-_io = [
- ("clk100", 0, Pins("L5"), IOStandard("LVDS25")),
- ("rst_n", 0, Pins("A21"), IOStandard("LVCMOS33")),
-
- ("user_led", 0, Pins("Y20"), IOStandard("LVCMOS33")),
- ("user_led", 1, Pins("AA21"), IOStandard("LVCMOS33")),
- ("user_led", 2, Pins("U18"), IOStandard("LVCMOS33")),
- ("user_led", 3, Pins("U19"), IOStandard("LVCMOS33")),
- ("user_led", 4, Pins("W19"), IOStandard("LVCMOS33")),
- ("user_led", 5, Pins("V19"), IOStandard("LVCMOS33")),
- ("user_led", 6, Pins("AB20"), IOStandard("LVCMOS33")),
- ("user_led", 7, Pins("AA20"), IOStandard("LVCMOS33")),
-
- ("user_dip_btn", 0, Pins("J7"), IOStandard("LVCMOS15")),
- ("user_dip_btn", 1, Pins("J6"), IOStandard("LVCMOS15")),
- ("user_dip_btn", 2, Pins("H2"), IOStandard("LVCMOS15")),
- ("user_dip_btn", 3, Pins("H3"), IOStandard("LVCMOS15")),
- ("user_dip_btn", 4, Pins("J3"), IOStandard("LVCMOS15")),
- ("user_dip_btn", 5, Pins("K3"), IOStandard("LVCMOS15")),
- ("user_dip_btn", 6, Pins("J2"), IOStandard("LVCMOS15")),
- ("user_dip_btn", 7, Pins("J1"), IOStandard("LVCMOS15")),
-
- ("serial", 0,
- Subsignal("tx", Pins("B11"), IOStandard("LVCMOS33")), # X4 IO0
- Subsignal("rx", Pins("B12"), IOStandard("LVCMOS33")), # X4 IO1
- ),
-
- ("eth_clocks", 0,
- Subsignal("tx", Pins("C12")),
- Subsignal("gtx", Pins("M2")),
- Subsignal("rx", Pins("L4")),
- IOStandard("LVCMOS33")
- ),
- ("eth", 0,
- Subsignal("rst_n", Pins("L3")),
- Subsignal("mdio", Pins("L2")),
- Subsignal("mdc", Pins("V4")),
- Subsignal("dv", Pins("M1")),
- Subsignal("rx_er", Pins("M4")),
- Subsignal("rx_data", Pins("M5 N1 N6 P6 T2 R2 P5 P3")),
- Subsignal("tx_en", Pins("V3")),
- Subsignal("tx_data", Pins("V1 U1 R3 P1 N5 N3 N4 N2")),
- Subsignal("col", Pins("R1")),
- Subsignal("crs", Pins("P4")),
- IOStandard("LVCMOS33")
- ),
-
- ("eth_clocks", 1,
- Subsignal("tx", Pins("M21")),
- Subsignal("gtx", Pins("M19")),
- Subsignal("rx", Pins("N19")),
- IOStandard("LVCMOS33")
- ),
- ("eth", 1,
- Subsignal("rst_n", Pins("R21")),
- Subsignal("mdio", Pins("U16")),
- Subsignal("mdc", Pins("Y18")),
- Subsignal("dv", Pins("U15")),
- Subsignal("rx_er", Pins("V20")),
- Subsignal("rx_data", Pins("AB17 AA17 R19 V21 T17 R18 W21 Y21")),
- Subsignal("tx_en", Pins("V22")),
- Subsignal("tx_data", Pins("W22 R16 P17 Y22 T21 U22 P20 U20")),
- Subsignal("col", Pins("N18")),
- Subsignal("crs", Pins("P19")),
- IOStandard("LVCMOS33")
- ),
-]
-
-
-class Platform(LatticePlatform):
- default_clk_name = "clk100"
- default_clk_period = 10
-
- def __init__(self):
- LatticePlatform.__init__(self, "LFE3-35EA-6FN484C", _io)
-
- def do_finalize(self, fragment):
- LatticePlatform.do_finalize(self, fragment)
- try:
- self.add_period_constraint(self.lookup_request("eth_clocks", 0).rx, 8.0)
- except ConstraintError:
- pass
- try:
- self.add_period_constraint(self.lookup_request("eth_clocks", 1).rx, 8.0)
- except ConstraintError:
- pass
- def create_programmer(self):
- return LatticeProgrammer()
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-# Bank 34 and 35 voltage depend on J18 jumper setting
-_io = [
- ("clk100", 0, Pins("Y9"), IOStandard("LVCMOS33")),
-
- ("user_btn", 0, Pins("P16"), IOStandard("LVCMOS18")), # center
- ("user_btn", 1, Pins("R16"), IOStandard("LVCMOS18")), # down
- ("user_btn", 2, Pins("N15"), IOStandard("LVCMOS18")), # left
- ("user_btn", 3, Pins("R18"), IOStandard("LVCMOS18")), # right
- ("user_btn", 4, Pins("T18"), IOStandard("LVCMOS18")), # up
-
- ("user_sw", 0, Pins("F22"), IOStandard("LVCMOS18")),
- ("user_sw", 1, Pins("G22"), IOStandard("LVCMOS18")),
- ("user_sw", 2, Pins("H22"), IOStandard("LVCMOS18")),
- ("user_sw", 3, Pins("F21"), IOStandard("LVCMOS18")),
- ("user_sw", 4, Pins("H19"), IOStandard("LVCMOS18")),
- ("user_sw", 5, Pins("H18"), IOStandard("LVCMOS18")),
- ("user_sw", 6, Pins("H17"), IOStandard("LVCMOS18")),
- ("user_sw", 7, Pins("M15"), IOStandard("LVCMOS18")),
-
- ("user_led", 0, Pins("T22"), IOStandard("LVCMOS33")),
- ("user_led", 1, Pins("T21"), IOStandard("LVCMOS33")),
- ("user_led", 2, Pins("U22"), IOStandard("LVCMOS33")),
- ("user_led", 3, Pins("U21"), IOStandard("LVCMOS33")),
- ("user_led", 4, Pins("V22"), IOStandard("LVCMOS33")),
- ("user_led", 5, Pins("W22"), IOStandard("LVCMOS33")),
- ("user_led", 6, Pins("U19"), IOStandard("LVCMOS33")),
- ("user_led", 7, Pins("U14"), IOStandard("LVCMOS33")),
-
- # A
- ("pmod", 0, Pins("Y11 AA11 Y10 AA9 AB11 AB10 AB9 AA8"),
- IOStandard("LVCMOS33")),
- # B
- ("pmod", 1, Pins("W12 W11 V10 W8 V12 W10 V9 V8"),
- IOStandard("LVCMOS33")),
- # C
- ("pmod", 2,
- Subsignal("n", Pins("AB6 AA4 T6 U4")),
- Subsignal("p", Pins("AB7 Y4 R6 T4")),
- IOStandard("LVCMOS33")),
- # D
- ("pmod", 3,
- Subsignal("n", Pins("W7 V4 W5 U5")),
- Subsignal("p", Pins("V7 V5 W6 U6")),
- IOStandard("LVCMOS33")),
-
- ("audio", 0,
- Subsignal("adr", Pins("AB1 Y5")),
- Subsignal("gpio", Pins("Y8 AA7 AA6 Y6")),
- Subsignal("mclk", Pins("AB2")),
- Subsignal("sck", Pins("AB4")),
- Subsignal("sda", Pins("AB5")),
- IOStandard("LVCMOS33")),
-
- ("oled", 0,
- Subsignal("dc", Pins("U10")),
- Subsignal("res", Pins("U9")),
- Subsignal("sclk", Pins("AB12")),
- Subsignal("sdin", Pins("AA12")),
- Subsignal("vbat", Pins("U11")),
- Subsignal("vdd", Pins("U12")),
- IOStandard("LVCMOS33")),
-
- ("hdmi", 0,
- Subsignal("clk", Pins("W18")),
- Subsignal("d", Pins(
- "Y13 AA13 AA14 Y14 AB15 AB16 AA16 AB17 "
- "AA17 Y15 W13 W15 V15 U17 V14 V13")),
- Subsignal("de", Pins("U16")),
- Subsignal("hsync", Pins("V17")),
- Subsignal("vsync", Pins("W17")),
- Subsignal("int", Pins("W16")),
- Subsignal("scl", Pins("AA18")),
- Subsignal("sda", Pins("Y16")),
- Subsignal("spdif", Pins("U15")),
- Subsignal("spdifo", Pins("Y18")),
- IOStandard("LVCMOS33")),
-
- ("netic16", 0,
- Subsignal("w20", Pins("W20")),
- Subsignal("w21", Pins("W21")),
- IOStandard("LVCMOS33")),
-
- ("vga", 0,
- Subsignal("r", Pins("V20 U20 V19 V18")),
- Subsignal("g", Pins("AB22 AA22 AB21 AA21")),
- Subsignal("b", Pins("Y21 Y20 AB20 AB19")),
- Subsignal("hsync_n", Pins("AA19")),
- Subsignal("vsync_n", Pins("Y19")),
- IOStandard("LVCMOS33")),
-
- ("usb_otg", 0,
- Subsignal("vbusoc", Pins("L16")),
- Subsignal("reset_n", Pins("G17")),
- IOStandard("LVCMOS18")),
-
- ("pudc_b", 0, Pins("K16"), IOStandard("LVCMOS18")),
-
- ("xadc", 0,
- Subsignal("gio", Pins("H15 R15 K15 J15")),
- Subsignal("ad0_n", Pins("E16")),
- Subsignal("ad0_p", Pins("F16")),
- Subsignal("ad8_n", Pins("D17")),
- Subsignal("ad8_p", Pins("D16")),
- IOStandard("LVCMOS18")),
-
- ("fmc_clocks", 0,
- Subsignal("clk0_n", Pins("L19")),
- Subsignal("clk0_p", Pins("L18")),
- Subsignal("clk1_n", Pins("C19")),
- Subsignal("clk1_p", Pins("D18")),
- IOStandard("LVCMOS18")),
-
- ("fmc", 0,
- Subsignal("scl", Pins("R7")),
- Subsignal("sda", Pins("U7")),
-
- Subsignal("prsnt", Pins("AB14")),
-
- # 0, 1, 17, 18 can be clock signals
- Subsignal("la_n", Pins(
- "M20 N20 P18 P22 M22 K18 L22 T17 "
- "J22 R21 T19 N18 P21 M17 K20 J17 "
- "K21 B20 C20 G16 G21 E20 F19 D15 "
- "A19 C22 E18 D21 A17 C18 B15 B17 "
- "A22 B22")),
- Subsignal("la_p", Pins(
- "M19 N19 P17 N22 M21 J18 L21 T16 "
- "J21 R20 R19 N17 P20 L17 K19 J16 "
- "J20 B19 D20 G15 G20 E19 G19 E15 "
- "A18 D22 F18 E21 A16 C17 C15 B16 "
- "A21 B21")),
- IOStandard("LVCMOS18")),
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk100"
- default_clk_period = 10
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc7z020-clg484-1", _io)
+++ /dev/null
-from migen.build.generic_platform import *
-from migen.build.xilinx import XilinxPlatform
-
-
-_io = [
- ("clk_fx", 0, Pins("L22"), IOStandard("LVCMOS33")),
- ("clk_if", 0, Pins("K20"), IOStandard("LVCMOS33")),
- ("rst", 0, Pins("A18")),
- # PROG_B and DONE: AA1 U16
-
- ("fx2", 0,
- Subsignal("sloe", Pins("U15"), Drive(12)), # M1
- Subsignal("slrd", Pins("N22"), Drive(12)),
- Subsignal("slwr", Pins("M22"), Drive(12)),
- Subsignal("pktend", Pins("AB5"), Drive(12)), # CSO
- Subsignal("fifoadr", Pins("W17 Y18"), Drive(12)), # CCLK M0
- Subsignal("cont", Pins("G20")),
- Subsignal("fd", Pins("Y17 V13 W13 AA8 AB8 W6 Y6 Y9 "
- "V21 V22 U20 U22 R20 R22 P18 P19")),
- Subsignal("flag", Pins("F20 F19 F18 AB17")), # - - - CSI/MOSI
- Subsignal("rdy25", Pins("M21 K21 K22 J21")),
- Subsignal("ctl35", Pins("D19 E20 N20")),
- Subsignal("int45", Pins("C18 V17")),
- Subsignal("pc", Pins("G20 T10 V5 AB9 G19 H20 H19 H18")),
- # - DOUT/BUSY INIT_B RDWR_B DO CS CLK DI
- IOStandard("LVCMOS33")),
-
- ("mm", 0,
- Subsignal("a", Pins("M20 M19 M18 N19 T19 T21 T22 R19 ",
- "P20 P21 P22 J22 H21 H22 G22 F21")),
- Subsignal("d", Pins("D20 C20 C19 B21 B20 J19 K19 L19"), Drive(2)),
- Subsignal("wr_n", Pins("C22")),
- Subsignal("rd_n", Pins("D21")),
- Subsignal("psen_n", Pins("D22")),
- IOStandard("LVCMOS33")),
-
- ("serial", 0,
- Subsignal("tx", Pins("B22"), Misc("SLEW=QUIETIO")),
- Subsignal("rx", Pins("A21"), Misc("PULLDOWN")),
- IOStandard("LVCMOS33")),
-
- ("ddram_clock", 0,
- Subsignal("p", Pins("F2"), Misc("OUT_TERM=UNTUNED_50")),
- Subsignal("n", Pins("F1"), Misc("OUT_TERM=UNTUNED_50")),
- IOStandard("SSTL18_II")),
-
- ("ddram", 0,
- Subsignal("dqs", Pins("L3 T2"), IOStandard("SSTL18_II"), # DIFF_
- Misc("IN_TERM=NONE")),
- Subsignal("dqs_n", Pins("L1 T1"), IOStandard("SSTL18_II"), # DIFF_
- Misc("IN_TERM=NONE")),
- Subsignal("dm", Pins("H1 H2"), Misc("OUT_TERM=UNTUNED_50")),
- Subsignal("dq", Pins("M1 M2 J1 K2 J3 K1 N3 N1 "
- "U1 U3 P1 R3 P2 R1 V2 V1"), Misc("IN_TERM=NONE")),
- Subsignal("ras_n", Pins("N4"), Misc("OUT_TERM=UNTUNED_50")),
- Subsignal("cas_n", Pins("P3"), Misc("OUT_TERM=UNTUNED_50")),
- Subsignal("a", Pins("M5 K6 B1 J4 L4 K3 M4 K5 G3 G1 K4 C3 C1"),
- Misc("OUT_TERM=UNTUNED_50")),
- Subsignal("ba", Pins("E3 E1 D1"), Misc("OUT_TERM=UNTUNED_50")),
- Subsignal("cke", Pins("J6"), Misc("OUT_TERM=UNTUNED_50")),
- Subsignal("cs_n", Pins("H6")), # NC!
- Subsignal("odt", Pins("M3"), Misc("OUT_TERM=UNTUNED_50")),
- Subsignal("we_n", Pins("D2")),
- Subsignal("rzq", Pins("AA2")),
- Subsignal("zio", Pins("Y2")),
- IOStandard("SSTL18_II")),
-
- ("i2c", 0,
- Subsignal("scl", Pins("F22")),
- Subsignal("sda", Pins("E22")),
- IOStandard("LVCMOS33")),
-
- ("sd", 0,
- Subsignal("sck", Pins("H11")),
- Subsignal("d3", Pins("H14")),
- Subsignal("d", Pins("P10")),
- Subsignal("d1", Pins("T18")),
- Subsignal("d2", Pins("R17")),
- Subsignal("cmd", Pins("H13")),
- IOStandard("LVCMOS33")),
-
-]
-
-
-class Platform(XilinxPlatform):
- default_clk_name = "clk_if"
- default_clk_period = 20
-
- def __init__(self):
- XilinxPlatform.__init__(self, "xc6slx150-3csg484", _io)
- self.add_platform_command("""
-CONFIG VCCAUX = "2.5";
-""")
-
- def do_finalize(self, fragment):
- XilinxPlatform.do_finalize(self, fragment)
-
- try:
- clk_if = self.lookup_request("clk_if")
- clk_fx = self.lookup_request("clk_fx")
- self.add_platform_command("""
-NET "{clk_if}" TNM_NET = "GRPclk_if";
-NET "{clk_fx}" TNM_NET = "GRPclk_fx";
-TIMESPEC "TSclk_fx" = PERIOD "GRPclk_fx" 20.83333 ns HIGH 50%;
-TIMESPEC "TSclk_if" = PERIOD "GRPclk_if" 20 ns HIGH 50%;
-TIMESPEC "TSclk_fx2if" = FROM "GRPclk_fx" TO "GRPclk_if" 3 ns DATAPATHONLY;
-TIMESPEC "TSclk_if2fx" = FROM "GRPclk_if" TO "GRPclk_fx" 3 ns DATAPATHONLY;
-""", clk_if=clk_if, clk_fx=clk_fx)
- except ConstraintError:
- pass
+++ /dev/null
-from migen.build.sim.platform import SimPlatform
+++ /dev/null
-sim_special_overrides = {}
+++ /dev/null
-// This file is Copyright (c) 2015 Florent Kermarrec <florent@enjoy-digital.fr>
-// License: BSD
-#include "Vdut.h"
-#include "verilated.h"
-#include "verilated_vcd_c.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <termios.h>
-#include <sys/poll.h>
-
-#include <linux/if.h>
-#include <linux/if_tun.h>
-
-/* ios */
-
-#ifdef SERIAL_SOURCE_STB
-#define WITH_SERIAL
-#endif
-
-#ifdef ETH_SOURCE_STB
-#define WITH_ETH
-#endif
-
-#define MAX(a,b) (((a)>(b))?(a):(b))
-#define MIN(a,b) (((a)<(b))?(a):(b))
-
-int trace = 0;
-
-vluint64_t main_time = 0;
-double sc_time_stamp()
-{
- return main_time;
-}
-
-/* Sim struct */
-struct sim {
- bool run;
-
- unsigned int tick;
- clock_t start;
- clock_t end;
- float speed;
-
-#ifdef WITH_SERIAL_PTY
- char serial_dev[64];
- int serial_fd;
- unsigned char serial_rx_data;
- unsigned char serial_tx_data;
-#endif
-#ifdef WITH_ETH
- const char *eth_dev;
- const char *eth_tap;
- int eth_fd;
- unsigned char eth_txbuffer[2048];
- unsigned char eth_rxbuffer[2048];
- int eth_txbuffer_len;
- int eth_rxbuffer_len;
- int eth_rxbuffer_pos;
- int eth_last_source_stb;
-#endif
-};
-
-/* Serial functions */
-#ifndef WITH_SERIAL_PTY
-struct termios orig_termios;
-
-void reset_terminal_mode(void)
-{
- tcsetattr(0, TCSANOW, &orig_termios);
-}
-
-void set_conio_terminal_mode(void)
-{
- struct termios new_termios;
-
- /* take two copies - one for now, one for later */
- tcgetattr(0, &orig_termios);
- memcpy(&new_termios, &orig_termios, sizeof(new_termios));
-
- /* register cleanup handler, and set the new terminal mode */
- atexit(reset_terminal_mode);
- cfmakeraw(&new_termios);
- tcsetattr(0, TCSANOW, &new_termios);
-}
-
-int kbhit(void)
-{
- struct timeval tv = { 0L, 0L };
- fd_set fds;
- FD_ZERO(&fds);
- FD_SET(0, &fds);
- return select(1, &fds, NULL, NULL, &tv);
-}
-
-int getch(void)
-{
- int r;
- unsigned char c;
- if((r = read(0, &c, sizeof(c))) < 0) {
- return r;
- } else {
- return c;
- }
-}
-#endif
-
-/* Ethernet functions */
-/* create tap:
- openvpn --mktun --dev tap0
- ifconfig tap0 192.168.0.14 up
- mknod /dev/net/tap0 c 10 200
- delete tap:
- openvpn --rmtun --dev tap0 */
-#ifdef WITH_ETH
-void eth_init(struct sim *s, const char *dev, const char*tap)
-{
- s->eth_txbuffer_len = 0;
- s->eth_rxbuffer_len = 0;
- s->eth_rxbuffer_pos = 0;
- s->eth_last_source_stb = 0;
- s->eth_dev = dev;
- s->eth_tap = tap;
-}
-
-void eth_open(struct sim *s)
-{
-
- struct ifreq ifr;
- s->eth_fd = open (s->eth_dev, O_RDWR);
- if(s->eth_fd < 0) {
- fprintf(stderr, " Could not open dev %s\n", s->eth_dev);
- return;
- }
-
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
- strncpy(ifr.ifr_name, s->eth_tap, IFNAMSIZ);
-
- if(ioctl(s->eth_fd, TUNSETIFF, (void *) &ifr) < 0) {
- fprintf(stderr, " Could not set %s\n", s->eth_tap);
- close(s->eth_fd);
- }
- return;
-}
-
-int eth_close(struct sim *s)
-{
- if(s->eth_fd < 0)
- close(s->eth_fd);
-}
-
-void eth_write(struct sim *s, unsigned char *buf, int len)
-{
- write(s->eth_fd, buf, len);
-}
-
-int eth_read(struct sim *s, unsigned char *buf)
-{
-
- struct pollfd fds[1];
- int n;
- int len;
-
- fds[0].fd = s->eth_fd;
- fds[0].events = POLLIN;
-
- n = poll(fds, 1, 0);
- if((n > 0) && ((fds[0].revents & POLLIN) == POLLIN)) {
- len = read(s->eth_fd, buf, 1532);
- } else {
- len = 0;
- }
- return len;
-}
-#endif
-
-Vdut* dut;
-VerilatedVcdC* tfp;
-
-#ifndef WITH_SERIAL_PTY
-int console_service(struct sim *s)
-{
- /* fpga --> console */
- SERIAL_SOURCE_ACK = 1;
- if(SERIAL_SOURCE_STB == 1) {
- if(SERIAL_SOURCE_DATA == '\n')
- putchar('\r');
- putchar(SERIAL_SOURCE_DATA);
- fflush(stdout);
- }
-
- /* console --> fpga */
- SERIAL_SINK_STB = 0;
- if(s->tick%(1000) == 0) {
- if(kbhit()) {
- char c = getch();
- if(c == 27 && !kbhit()) {
- printf("\r\n");
- return -1;
- } else {
- SERIAL_SINK_STB = 1;
- SERIAL_SINK_DATA = c;
- }
- }
- }
- return 0;
-}
-#else
-void console_init(struct sim *s)
-{
- FILE *f;
- f = fopen("/tmp/simserial","r");
- fscanf(f, "%[^\n]", s->serial_dev);
- fclose(f);
- return;
-}
-
-void console_open(struct sim *s)
-{
- s->serial_fd = open(s->serial_dev, O_RDWR);
- if(s->serial_fd < 0) {
- fprintf(stderr, " Could not open dev %s\n", s->serial_dev);
- return;
- }
- return;
-}
-
-int console_close(struct sim *s)
-{
- if(s->serial_fd < 0)
- close(s->serial_fd);
-}
-
-void console_write(struct sim *s, unsigned char *buf, int len)
-{
- write(s->serial_fd, buf, len);
-}
-
-int console_read(struct sim *s, unsigned char *buf)
-{
- struct pollfd fds[1];
- int n;
- int len;
-
- fds[0].fd = s->serial_fd;
- fds[0].events = POLLIN;
-
- n = poll(fds, 1, 0);
- if((n > 0) && ((fds[0].revents & POLLIN) == POLLIN)) {
- len = read(s->serial_fd, buf, 1);
- } else {
- len = 0;
- }
- return len;
-}
-
-int console_service(struct sim *s)
-{
- /* fpga --> console */
- SERIAL_SOURCE_ACK = 1;
- if(SERIAL_SOURCE_STB == 1) {
- s->serial_tx_data = SERIAL_SOURCE_DATA;
- console_write(s, &(s->serial_tx_data), 1);
- }
-
- /* console --> fpga */
- SERIAL_SINK_STB = 0;
- if(console_read(s, &(s->serial_rx_data)))
- {
- SERIAL_SINK_STB = 1;
- SERIAL_SINK_DATA = s->serial_rx_data;
- }
- return 0;
-}
-#endif
-
-#ifdef WITH_ETH
-int ethernet_service(struct sim *s) {
- /* fpga --> tap */
- ETH_SOURCE_ACK = 1;
- if(ETH_SOURCE_STB == 1) {
- s->eth_txbuffer[s->eth_txbuffer_len] = ETH_SOURCE_DATA;
- s->eth_txbuffer_len++;
- } else {
- if(s->eth_last_source_stb) {
- eth_write(s, s->eth_txbuffer, s->eth_txbuffer_len);
- s->eth_txbuffer_len = 0;
- }
- }
- s->eth_last_source_stb = ETH_SOURCE_STB;
-
- /* tap --> fpga */
- if(s->eth_rxbuffer_len == 0) {
- ETH_SINK_STB = 0;
- s->eth_rxbuffer_pos = 0;
- s->eth_rxbuffer_len = eth_read(s, s->eth_rxbuffer);
- } else {
- if(s->eth_rxbuffer_pos < MAX(s->eth_rxbuffer_len, 60)) {
- ETH_SINK_STB = 1;
- ETH_SINK_DATA = s->eth_rxbuffer[s->eth_rxbuffer_pos];
- s->eth_rxbuffer_pos++;
- } else {
- ETH_SINK_STB = 0;
- s->eth_rxbuffer_len = 0;
- memset(s->eth_rxbuffer, 0, 1532);
- }
- }
-}
-#endif
-
-void sim_tick(struct sim *s)
-{
- SYS_CLK = s->tick%2;
- dut->eval();
- if(trace)
- tfp->dump(s->tick);
- s->tick++;
-}
-
-void sim_init(struct sim *s)
-{
- int i;
- s->tick = 0;
-#ifdef SYS_RST
- SYS_RST = 1;
- SYS_CLK = 0;
- for (i=0; i<8; i++)
- sim_tick(s);
- SYS_RST = 0;
-#endif
- s->start = clock();
-}
-
-int main(int argc, char **argv, char **env)
-{
- float speed;
-
-#ifndef WITH_SERIAL_PTY
- set_conio_terminal_mode();
-#endif
-
- Verilated::commandArgs(argc, argv);
- dut = new Vdut;
-
- Verilated::traceEverOn(true);
- tfp = new VerilatedVcdC;
- dut->trace(tfp, 99);
- tfp->open("dut.vcd");
-
- struct sim s;
- sim_init(&s);
-
-#ifdef WITH_SERIAL_PTY
- console_init(&s);
- console_open(&s);
-#endif
-
-#ifdef WITH_ETH
- eth_init(&s, "/dev/net/tap0", "tap0"); // XXX get this from /tmp/simethernet
- eth_open(&s);
-#endif
-
- s.run = true;
- while(s.run) {
- sim_tick(&s);
- if(SYS_CLK) {
-#ifdef WITH_SERIAL
- if(console_service(&s) != 0)
- s.run = false;
-#endif
-#ifdef WITH_ETH
- ethernet_service(&s);
-#endif
- }
- }
- s.end = clock();
-
- speed = (s.tick/2)/((s.end-s.start)/CLOCKS_PER_SEC);
-
- printf("average speed: %3.3f MHz\n\r", speed/1000000);
-
- tfp->close();
-
-
-#ifdef WITH_SERIAL_PTY
- console_close(&s);
-#endif
-#ifdef WITH_ETH
- eth_close(&s);
-#endif
-
- exit(0);
-}
+++ /dev/null
-from migen.build.generic_platform import GenericPlatform
-from migen.build.sim import common, verilator
-
-
-class SimPlatform(GenericPlatform):
- def __init__(self, *args, toolchain="verilator", **kwargs):
- GenericPlatform.__init__(self, *args, **kwargs)
- if toolchain == "verilator":
- self.toolchain = verilator.SimVerilatorToolchain()
- else:
- raise ValueError("Unknown toolchain")
-
- def get_verilog(self, *args, special_overrides=dict(), **kwargs):
- so = dict(common.sim_special_overrides)
- so.update(special_overrides)
- return GenericPlatform.get_verilog(self, *args, special_overrides=so, **kwargs)
-
- def build(self, *args, **kwargs):
- return self.toolchain.build(self, *args, **kwargs)
-
+++ /dev/null
-# This file is Copyright (c) 2015 Florent Kermarrec <florent@enjoy-digital.fr>
-# License: BSD
-
-import os
-import subprocess
-
-from migen.fhdl.structure import _Fragment
-from migen.build import tools
-from migen.build.generic_platform import *
-
-
-def _build_tb(platform, vns, serial, template):
- def io_name(resource, subsignal=None):
- res = platform.lookup_request(resource)
- if subsignal is not None:
- res = getattr(res, subsignal)
- return vns.get_name(res)
-
- ios = """
-#define SYS_CLK dut->{sys_clk}
-""".format(sys_clk=io_name("sys_clk"))
-
- if serial == "pty":
- ios += "#define WITH_SERIAL_PTY"
- elif serial == "console":
- pass
- else:
- raise ValueError
- try:
- ios += """
-#define SERIAL_SOURCE_STB dut->{serial_source_stb}
-#define SERIAL_SOURCE_ACK dut->{serial_source_ack}
-#define SERIAL_SOURCE_DATA dut->{serial_source_data}
-
-#define SERIAL_SINK_STB dut->{serial_sink_stb}
-#define SERIAL_SINK_ACK dut->{serial_sink_ack}
-#define SERIAL_SINK_DATA dut->{serial_sink_data}
-""".format(
- serial_source_stb=io_name("serial", "source_stb"),
- serial_source_ack=io_name("serial", "source_ack"),
- serial_source_data=io_name("serial", "source_data"),
-
- serial_sink_stb=io_name("serial", "sink_stb"),
- serial_sink_ack=io_name("serial", "sink_ack"),
- serial_sink_data=io_name("serial", "sink_data"),
- )
- except:
- pass
-
- try:
- ios += """
-#define ETH_SOURCE_STB dut->{eth_source_stb}
-#define ETH_SOURCE_ACK dut->{eth_source_ack}
-#define ETH_SOURCE_DATA dut->{eth_source_data}
-
-#define ETH_SINK_STB dut->{eth_sink_stb}
-#define ETH_SINK_ACK dut->{eth_sink_ack}
-#define ETH_SINK_DATA dut->{eth_sink_data}
-""".format(
- eth_source_stb=io_name("eth", "source_stb"),
- eth_source_ack=io_name("eth", "source_ack"),
- eth_source_data=io_name("eth", "source_data"),
-
- eth_sink_stb=io_name("eth", "sink_stb"),
- eth_sink_ack=io_name("eth", "sink_ack"),
- eth_sink_data=io_name("eth", "sink_data"),
- )
- except:
- pass
-
- content = ""
- f = open(template, "r")
- done = False
- for l in f:
- content += l
- if "/* ios */" in l and not done:
- content += ios
- done = True
-
- f.close()
- tools.write_to_file("dut_tb.cpp", content)
-
-
-def _build_sim(platform, vns, build_name, include_paths, sim_path, serial, verbose):
- include = ""
- for path in include_paths:
- include += "-I"+path+" "
-
- build_script_contents = """# Autogenerated by Migen
- rm -rf obj_dir/
-verilator {disable_warnings} -O3 --cc dut.v --exe dut_tb.cpp -LDFLAGS "-lpthread" -trace {include}
-make -j -C obj_dir/ -f Vdut.mk Vdut
-
-""".format(
- disable_warnings="-Wno-fatal",
- include=include)
- build_script_file = "build_" + build_name + ".sh"
- tools.write_to_file(build_script_file, build_script_contents, force_unix=True)
-
- _build_tb(platform, vns, serial, os.path.join("..", sim_path, "dut_tb.cpp"))
- if verbose:
- r = subprocess.call(["bash", build_script_file])
- else:
- r = subprocess.call(["bash", build_script_file], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
- if r != 0:
- raise OSError("Subprocess failed")
-
-
-def _run_sim(build_name):
- run_script_contents = """obj_dir/Vdut
-"""
- run_script_file = "run_" + build_name + ".sh"
- tools.write_to_file(run_script_file, run_script_contents, force_unix=True)
- r = subprocess.call(["bash", run_script_file])
- if r != 0:
- raise OSError("Subprocess failed")
-
-
-class SimVerilatorToolchain:
- # XXX fir sim_path
- def build(self, platform, fragment, build_dir="build", build_name="top",
- sim_path="../migen/migen/build/sim/", serial="console",
- run=True, verbose=False):
- tools.mkdir_noerror(build_dir)
- os.chdir(build_dir)
-
- if not isinstance(fragment, _Fragment):
- fragment = fragment.get_fragment()
- platform.finalize(fragment)
-
- v_output = platform.get_verilog(fragment)
- named_sc, named_pc = platform.resolve_signals(v_output.ns)
- v_output.write("dut.v")
-
- include_paths = []
- for source in platform.sources:
- path = os.path.dirname(source[0]).replace("\\", "\/")
- if path not in include_paths:
- include_paths.append(path)
- include_paths += platform.verilog_include_paths
- _build_sim(platform, v_output.ns, build_name, include_paths, sim_path, serial, verbose)
-
- if run:
- _run_sim(build_name)
-
- os.chdir("..")
-
- return v_output.ns
+++ /dev/null
-import os
-import struct
-from distutils.version import StrictVersion
-
-
-def mkdir_noerror(d):
- try:
- os.mkdir(d)
- except OSError:
- pass
-
-
-def language_by_filename(name):
- extension = name.rsplit(".")[-1]
- if extension in ["v", "vh", "vo"]:
- return "verilog"
- if extension in ["vhd", "vhdl", "vho"]:
- return "vhdl"
- return None
-
-
-def write_to_file(filename, contents, force_unix=False):
- newline = None
- if force_unix:
- newline = "\n"
- with open(filename, "w", newline=newline) as f:
- f.write(contents)
-
-
-def arch_bits():
- return struct.calcsize("P")*8
-
-
-def versions(path):
- for n in os.listdir(path):
- full = os.path.join(path, n)
- if not os.path.isdir(full):
- continue
- try:
- yield StrictVersion(n)
- except ValueError:
- continue
+++ /dev/null
-from migen.build.xilinx.platform import XilinxPlatform
-from migen.build.xilinx.programmer import UrJTAG, XC3SProg, FpgaProg, VivadoProgrammer, iMPACT, Adept
+++ /dev/null
-import os
-import sys
-from distutils.version import StrictVersion
-
-from migen.fhdl.structure import *
-from migen.fhdl.specials import Instance
-from migen.fhdl.module import Module
-from migen.fhdl.specials import SynthesisDirective
-from migen.genlib.cdc import *
-from migen.genlib.resetsync import AsyncResetSynchronizer
-from migen.genlib.io import *
-
-from migen.build import tools
-
-
-def settings(path, ver=None, sub=None):
- vers = list(tools.versions(path))
- if ver is None:
- ver = max(vers)
- else:
- ver = StrictVersion(ver)
- assert ver in vers
-
- full = os.path.join(path, str(ver))
- if sub:
- full = os.path.join(full, sub)
-
- search = [64, 32]
- if tools.arch_bits() == 32:
- search.reverse()
-
- if sys.platform == "win32" or sys.platform == "cygwin":
- script_ext = "bat"
- else:
- script_ext = "sh"
-
- for b in search:
- settings = os.path.join(full, "settings{0}.{1}".format(b, script_ext))
- if os.path.exists(settings):
- return settings
-
- raise OSError("no settings file found")
-
-
-class XilinxNoRetimingImpl(Module):
- def __init__(self, reg):
- self.specials += SynthesisDirective("attribute register_balancing of {r} is no", r=reg)
-
-
-class XilinxNoRetiming:
- @staticmethod
- def lower(dr):
- return XilinxNoRetimingImpl(dr.reg)
-
-
-class XilinxMultiRegImpl(MultiRegImpl):
- def __init__(self, *args, **kwargs):
- MultiRegImpl.__init__(self, *args, **kwargs)
- self.specials += [SynthesisDirective("attribute shreg_extract of {r} is no", r=r)
- for r in self.regs]
-
-
-class XilinxMultiReg:
- @staticmethod
- def lower(dr):
- return XilinxMultiRegImpl(dr.i, dr.o, dr.odomain, dr.n)
-
-
-class XilinxAsyncResetSynchronizerImpl(Module):
- def __init__(self, cd, async_reset):
- rst1 = Signal()
- self.specials += [
- Instance("FDPE", p_INIT=1, i_D=0, i_PRE=async_reset,
- i_CE=1, i_C=cd.clk, o_Q=rst1),
- Instance("FDPE", p_INIT=1, i_D=rst1, i_PRE=async_reset,
- i_CE=1, i_C=cd.clk, o_Q=cd.rst)
- ]
-
-
-class XilinxAsyncResetSynchronizer:
- @staticmethod
- def lower(dr):
- return XilinxAsyncResetSynchronizerImpl(dr.cd, dr.async_reset)
-
-
-class XilinxDifferentialInputImpl(Module):
- def __init__(self, i_p, i_n, o):
- self.specials += Instance("IBUFDS", i_I=i_p, i_IB=i_n, o_O=o)
-
-
-class XilinxDifferentialInput:
- @staticmethod
- def lower(dr):
- return XilinxDifferentialInputImpl(dr.i_p, dr.i_n, dr.o)
-
-
-class XilinxDifferentialOutputImpl(Module):
- def __init__(self, i, o_p, o_n):
- self.specials += Instance("OBUFDS", i_I=i, o_O=o_p, o_OB=o_n)
-
-
-class XilinxDifferentialOutput:
- @staticmethod
- def lower(dr):
- return XilinxDifferentialOutputImpl(dr.i, dr.o_p, dr.o_n)
-
-
-class XilinxDDROutputImpl(Module):
- def __init__(self, i1, i2, o, clk):
- self.specials += Instance("ODDR2",
- p_DDR_ALIGNMENT="NONE", p_INIT=0, p_SRTYPE="SYNC",
- i_C0=clk, i_C1=~clk, i_CE=1, i_S=0, i_R=0,
- i_D0=i1, i_D1=i2, o_Q=o,
- )
-
-
-class XilinxDDROutput:
- @staticmethod
- def lower(dr):
- return XilinxDDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk)
-
-
-xilinx_special_overrides = {
- NoRetiming: XilinxNoRetiming,
- MultiReg: XilinxMultiReg,
- AsyncResetSynchronizer: XilinxAsyncResetSynchronizer,
- DifferentialInput: XilinxDifferentialInput,
- DifferentialOutput: XilinxDifferentialOutput,
- DDROutput: XilinxDDROutput
-}
-
-
-class XilinxDDROutputImplS7(Module):
- def __init__(self, i1, i2, o, clk):
- self.specials += Instance("ODDR",
- p_DDR_CLK_EDGE="SAME_EDGE",
- i_C=clk, i_CE=1, i_S=0, i_R=0,
- i_D1=i1, i_D2=i2, o_Q=o,
- )
-
-
-class XilinxDDROutputS7:
- @staticmethod
- def lower(dr):
- return XilinxDDROutputImplS7(dr.i1, dr.i2, dr.o, dr.clk)
-
-
-xilinx_s7_special_overrides = {
- DDROutput: XilinxDDROutputS7
-}
+++ /dev/null
-import os
-import subprocess
-import sys
-
-from migen.fhdl.structure import _Fragment
-from migen.build.generic_platform import *
-from migen.build import tools
-from migen.build.xilinx import common
-
-
-def _format_constraint(c):
- if isinstance(c, Pins):
- return "LOC=" + c.identifiers[0]
- elif isinstance(c, IOStandard):
- return "IOSTANDARD=" + c.name
- elif isinstance(c, Drive):
- return "DRIVE=" + str(c.strength)
- elif isinstance(c, Misc):
- return c.misc
-
-
-def _format_ucf(signame, pin, others, resname):
- fmt_c = []
- for c in [Pins(pin)] + others:
- fc = _format_constraint(c)
- if fc is not None:
- fmt_c.append(fc)
- fmt_r = resname[0] + ":" + str(resname[1])
- if resname[2] is not None:
- fmt_r += "." + resname[2]
- return "NET \"" + signame + "\" " + " | ".join(fmt_c) + "; # " + fmt_r + "\n"
-
-
-def _build_ucf(named_sc, named_pc):
- r = ""
- for sig, pins, others, resname in named_sc:
- if len(pins) > 1:
- for i, p in enumerate(pins):
- r += _format_ucf(sig + "(" + str(i) + ")", p, others, resname)
- else:
- r += _format_ucf(sig, pins[0], others, resname)
- if named_pc:
- r += "\n" + "\n\n".join(named_pc)
- return r
-
-
-def _build_xst_files(device, sources, vincpaths, build_name, xst_opt):
- prj_contents = ""
- for filename, language, library in sources:
- prj_contents += language + " " + library + " " + filename + "\n"
- tools.write_to_file(build_name + ".prj", prj_contents)
-
- xst_contents = """run
--ifn {build_name}.prj
--top top
-{xst_opt}
--ofn {build_name}.ngc
--p {device}
-""".format(build_name=build_name, xst_opt=xst_opt, device=device)
- for path in vincpaths:
- xst_contents += "-vlgincdir " + path + "\n"
- tools.write_to_file(build_name + ".xst", xst_contents)
-
-
-def _run_yosys(device, sources, vincpaths, build_name):
- ys_contents = ""
- incflags = ""
- for path in vincpaths:
- incflags += " -I" + path
- for filename, language, library in sources:
- ys_contents += "read_{}{} {}\n".format(language, incflags, filename)
-
- ys_contents += """hierarchy -check -top top
-proc; memory; opt; fsm; opt
-synth_xilinx -top top -edif {build_name}.edif""".format(build_name=build_name)
-
- ys_name = build_name + ".ys"
- tools.write_to_file(ys_name, ys_contents)
- r = subprocess.call(["yosys", ys_name])
- if r != 0:
- raise OSError("Subprocess failed")
-
-
-def _run_ise(build_name, ise_path, source, mode, ngdbuild_opt,
- bitgen_opt, ise_commands, map_opt, par_opt, ver=None):
- if sys.platform == "win32" or sys.platform == "cygwin":
- source_cmd = "call "
- script_ext = ".bat"
- shell = ["cmd", "/c"]
- build_script_contents = "@echo off\nrem Autogenerated by Migen\n"
- else:
- source_cmd = "source "
- script_ext = ".sh"
- shell = ["bash"]
- build_script_contents = "# Autogenerated by Migen\nset -e\n"
- if source:
- settings = common.settings(ise_path, ver, "ISE_DS")
- build_script_contents += source_cmd + settings + "\n"
- if mode == "edif":
- ext = "edif"
- else:
- ext = "ngc"
- build_script_contents += """
-xst -ifn {build_name}.xst
-"""
-
- build_script_contents += """
-ngdbuild {ngdbuild_opt} -uc {build_name}.ucf {build_name}.{ext} {build_name}.ngd
-map {map_opt} -o {build_name}_map.ncd {build_name}.ngd {build_name}.pcf
-par {par_opt} {build_name}_map.ncd {build_name}.ncd {build_name}.pcf
-bitgen {bitgen_opt} {build_name}.ncd {build_name}.bit
-"""
- build_script_contents = build_script_contents.format(build_name=build_name,
- ngdbuild_opt=ngdbuild_opt, bitgen_opt=bitgen_opt, ext=ext,
- par_opt=par_opt, map_opt=map_opt)
- build_script_contents += ise_commands.format(build_name=build_name)
- build_script_file = "build_" + build_name + script_ext
- tools.write_to_file(build_script_file, build_script_contents, force_unix=False)
- command = shell + [build_script_file]
- r = subprocess.call(command)
- if r != 0:
- raise OSError("Subprocess failed")
-
-
-class XilinxISEToolchain:
- def __init__(self):
- self.xst_opt = """-ifmt MIXED
--use_new_parser yes
--opt_mode SPEED
--register_balancing yes"""
- self.map_opt = "-ol high -w"
- self.par_opt = "-ol high -w"
- self.ngdbuild_opt = ""
- self.bitgen_opt = "-g Binary:Yes -w"
- self.ise_commands = ""
-
- def build(self, platform, fragment, build_dir="build", build_name="top",
- toolchain_path=None, source=None, run=True, mode="xst"):
- if not isinstance(fragment, _Fragment):
- fragment = fragment.get_fragment()
- if toolchain_path is None:
- if sys.platform == "win32":
- toolchain_path = "C:\\Xilinx"
- elif sys.platform == "cygwin":
- toolchain_path = "/cygdrive/c/Xilinx"
- else:
- toolchain_path = "/opt/Xilinx"
- if source is None:
- source = sys.platform != "win32"
-
- platform.finalize(fragment)
- ngdbuild_opt = self.ngdbuild_opt
- vns = None
-
- tools.mkdir_noerror(build_dir)
- cwd = os.getcwd()
- os.chdir(build_dir)
- try:
- if mode == "xst" or mode == "yosys":
- v_output = platform.get_verilog(fragment)
- vns = v_output.ns
- named_sc, named_pc = platform.resolve_signals(vns)
- v_file = build_name + ".v"
- v_output.write(v_file)
- sources = platform.sources | {(v_file, "verilog", "work")}
- if mode == "xst":
- _build_xst_files(platform.device, sources, platform.verilog_include_paths, build_name, self.xst_opt)
- isemode = "xst"
- else:
- _run_yosys(platform.device, sources, platform.verilog_include_paths, build_name)
- isemode = "edif"
- ngdbuild_opt += "-p " + platform.device
-
- if mode == "mist":
- from mist import synthesize
- synthesize(fragment, platform.constraint_manager.get_io_signals())
-
- if mode == "edif" or mode == "mist":
- e_output = platform.get_edif(fragment)
- vns = e_output.ns
- named_sc, named_pc = platform.resolve_signals(vns)
- e_file = build_name + ".edif"
- e_output.write(e_file)
- isemode = "edif"
-
- tools.write_to_file(build_name + ".ucf", _build_ucf(named_sc, named_pc))
- if run:
- _run_ise(build_name, toolchain_path, source, isemode,
- ngdbuild_opt, self.bitgen_opt, self.ise_commands,
- self.map_opt, self.par_opt)
- finally:
- os.chdir(cwd)
-
- return vns
-
- def add_period_constraint(self, platform, clk, period):
- platform.add_platform_command("""NET "{clk}" TNM_NET = "GRP{clk}";
-TIMESPEC "TS{clk}" = PERIOD "GRP{clk}" """+str(period)+""" ns HIGH 50%;""", clk=clk)
+++ /dev/null
-from migen.build.generic_platform import GenericPlatform
-from migen.build.xilinx import common, vivado, ise
-
-
-class XilinxPlatform(GenericPlatform):
- bitstream_ext = ".bit"
-
- def __init__(self, *args, toolchain="ise", **kwargs):
- GenericPlatform.__init__(self, *args, **kwargs)
- if toolchain == "ise":
- self.toolchain = ise.XilinxISEToolchain()
- elif toolchain == "vivado":
- self.toolchain = vivado.XilinxVivadoToolchain()
- else:
- raise ValueError("Unknown toolchain")
-
- def get_verilog(self, *args, special_overrides=dict(), **kwargs):
- so = dict(common.xilinx_special_overrides)
- if self.device[:3] == "xc7":
- so.update(common.xilinx_s7_special_overrides)
- so.update(special_overrides)
- return GenericPlatform.get_verilog(self, *args, special_overrides=so, **kwargs)
-
- def get_edif(self, fragment, **kwargs):
- return GenericPlatform.get_edif(self, fragment, "UNISIMS", "Xilinx", self.device, **kwargs)
-
- def build(self, *args, **kwargs):
- return self.toolchain.build(self, *args, **kwargs)
-
- def add_period_constraint(self, clk, period):
- if hasattr(clk, "p"):
- clk = clk.p
- self.toolchain.add_period_constraint(self, clk, period)
+++ /dev/null
-import os
-import sys
-import subprocess
-
-from migen.build.generic_programmer import GenericProgrammer
-from migen.build.xilinx import common
-
-
-def _run_urjtag(cmds):
- with subprocess.Popen("jtag", stdin=subprocess.PIPE) as process:
- process.stdin.write(cmds.encode("ASCII"))
- process.communicate()
-
-
-class UrJTAG(GenericProgrammer):
- needs_bitreverse = True
-
- def __init__(self, cable, flash_proxy_basename=None):
- GenericProgrammer.__init__(self, flash_proxy_basename)
- self.cable = cable
-
- def load_bitstream(self, bitstream_file):
- cmds = """cable {cable}
-detect
-pld load {bitstream}
-quit
-""".format(bitstream=bitstream_file, cable=self.cable)
- _run_urjtag(cmds)
-
- def flash(self, address, data_file):
- flash_proxy = self.find_flash_proxy()
- cmds = """cable {cable}
-detect
-pld load "{flash_proxy}"
-initbus fjmem opcode=000010
-frequency 6000000
-detectflash 0
-endian big
-flashmem "{address}" "{data_file}" noverify
-""".format(flash_proxy=flash_proxy, address=address, data_file=data_file,
- cable=self.cable)
- _run_urjtag(cmds)
-
-
-class XC3SProg(GenericProgrammer):
- needs_bitreverse = False
-
- def __init__(self, cable, flash_proxy_basename=None):
- GenericProgrammer.__init__(self, flash_proxy_basename)
- self.cable = cable
-
- def load_bitstream(self, bitstream_file):
- subprocess.call(["xc3sprog", "-v", "-c", self.cable, bitstream_file])
-
- def flash(self, address, data_file):
- flash_proxy = self.find_flash_proxy()
- subprocess.call(["xc3sprog", "-v", "-c", self.cable, "-I"+flash_proxy, "{}:w:0x{:x}:BIN".format(data_file, address)])
-
-
-
-class FpgaProg(GenericProgrammer):
- needs_bitreverse = False
-
- def __init__(self, flash_proxy_basename=None):
- GenericProgrammer.__init__(self, flash_proxy_basename)
-
- def load_bitstream(self, bitstream_file):
- subprocess.call(["fpgaprog", "-v", "-f", bitstream_file])
-
- def flash(self, address, data_file):
- if address != 0:
- raise ValueError("fpga prog needs a main bitstream at address 0")
- flash_proxy = self.find_flash_proxy()
- subprocess.call(["fpgaprog", "-v", "-sa", "-r", "-b", flash_proxy,
- "-f", data_file])
-
-
-def _run_impact(cmds):
- with subprocess.Popen("impact -batch", stdin=subprocess.PIPE, shell=True) as process:
- process.stdin.write(cmds.encode("ASCII"))
- process.communicate()
- return process.returncode
-
-
-def _create_xsvf(bitstream_file, xsvf_file):
- assert os.path.exists(bitstream_file), bitstream_file
- assert not os.path.exists(xsvf_file), xsvf_file
- assert 0 == _run_impact("""
-setPreference -pref KeepSVF:True
-setMode -bs
-setCable -port xsvf -file {xsvf}
-addDevice -p 1 -file {bitstream}
-program -p 1
-quit
-""".format(bitstream=bitstream_file, xsvf=xsvf_file))
-
-
-class iMPACT(GenericProgrammer):
- needs_bitreverse = False
-
- def load_bitstream(self, bitstream_file):
- cmds = """setMode -bs
-setCable -p auto
-addDevice -p 1 -file {bitstream}
-program -p 1
-quit
-""".format(bitstream=bitstream_file)
- _run_impact(cmds)
-
-
-def _run_vivado(path, ver, cmds):
- if sys.platform == "win32" or sys.platform == "cygwin":
- vivado_cmd = "vivado -mode tcl"
- else:
- settings = common.settings(path, ver)
- vivado_cmd = "bash -c \"source " + settings + "&& vivado -mode tcl\""
- with subprocess.Popen(vivado_cmd, stdin=subprocess.PIPE, shell=True) as process:
- process.stdin.write(cmds.encode("ASCII"))
- process.communicate()
-
-
-class VivadoProgrammer(GenericProgrammer):
- needs_bitreverse = False
- def __init__(self, vivado_path="/opt/Xilinx/Vivado", vivado_ver=None,
- flash_part="n25q256-3.3v-spi-x1_x2_x4"):
- GenericProgrammer.__init__(self)
- self.vivado_path = vivado_path
- self.vivado_ver = vivado_ver
- self.flash_part = flash_part
-
- def load_bitstream(self, bitstream_file):
- cmds = """open_hw
-connect_hw_server
-open_hw_target [lindex [get_hw_targets -of_objects [get_hw_servers localhost]] 0]
-
-set_property PROBES.FILE {{}} [lindex [get_hw_devices] 0]
-set_property PROGRAM.FILE {{{bitstream}}} [lindex [get_hw_devices] 0]
-
-program_hw_devices [lindex [get_hw_devices] 0]
-refresh_hw_device [lindex [get_hw_devices] 0]
-
-quit
-""".format(bitstream=bitstream_file)
- _run_vivado(self.vivado_path, self.vivado_ver, cmds)
-
- # XXX works to flash bitstream, adapt it to flash bios
- def flash(self, address, data_file):
- cmds = """open_hw
-connect_hw_server
-open_hw_target [lindex [get_hw_targets -of_objects [get_hw_servers localhost]] 0]
-create_hw_cfgmem -hw_device [lindex [get_hw_devices] 0] -mem_dev [lindex [get_cfgmem_parts {{{flash_part}}}] 0]
-
-set_property PROGRAM.BLANK_CHECK 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-set_property PROGRAM.ERASE 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-set_property PROGRAM.CFG_PROGRAM 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-set_property PROGRAM.VERIFY 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-refresh_hw_device [lindex [get_hw_devices] 0]
-
-set_property PROGRAM.ADDRESS_RANGE {{use_file}} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-set_property PROGRAM.FILES [list "{data}" ] [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0]]
-set_property PROGRAM.UNUSED_PIN_TERMINATION {{pull-none}} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-set_property PROGRAM.BLANK_CHECK 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-set_property PROGRAM.ERASE 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-set_property PROGRAM.CFG_PROGRAM 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-set_property PROGRAM.VERIFY 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-
-startgroup
-if {{![string equal [get_property PROGRAM.HW_CFGMEM_TYPE [lindex [get_hw_devices] 0]] [get_property MEM_TYPE [get_property CFGMEM_PART [get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]]]] }} {{ create_hw_bitstream -hw_device [lindex [get_hw_devices] 0] [get_property PROGRAM.HW_CFGMEM_BITFILE [ lindex [get_hw_devices] 0]]; program_hw_devices [lindex [get_hw_devices] 0]; }};
-program_hw_cfgmem -hw_cfgmem [get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]
-endgroup
-
-quit
-""".format(data=data_file, flash_part=self.flash_part)
- _run_vivado(self.vivado_path, self.vivado_ver, cmds)
-
-
-class Adept(GenericProgrammer):
- """Using the Adept tool with an onboard Digilent "USB JTAG" cable.
-
- You need to install Adept Utilities V2 from
- http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,66,828&Prod=ADEPT2
- """
-
- needs_bitreverse = False
-
- def __init__(self, board, index, flash_proxy_basename=None):
- GenericProgrammer.__init__(self, flash_proxy_basename)
- self.board = board
- self.index = index
-
- def load_bitstream(self, bitstream_file):
- subprocess.call([
- "djtgcfg",
- "--verbose",
- "prog", "-d", self.board,
- "-i", str(self.index),
- "-f", bitstream_file,
- ])
-
- def flash(self, address, data_file):
- raise ValueError("Flashing unsupported with DigilentAdept tools")
+++ /dev/null
-# This file is Copyright (c) 2014 Florent Kermarrec <florent@enjoy-digital.fr>
-# License: BSD
-
-import os
-import subprocess
-import sys
-
-from migen.fhdl.structure import _Fragment
-from migen.build.generic_platform import *
-from migen.build import tools
-from migen.build.xilinx import common
-
-
-def _format_constraint(c):
- if isinstance(c, Pins):
- return "set_property LOC " + c.identifiers[0]
- elif isinstance(c, IOStandard):
- return "set_property IOSTANDARD " + c.name
- elif isinstance(c, Drive):
- return "set_property DRIVE " + str(c.strength)
- elif isinstance(c, Misc):
- return "set_property " + c.misc.replace("=", " ")
- else:
- raise ValueError("unknown constraint {}".format(c))
-
-
-def _format_xdc(signame, resname, *constraints):
- fmt_c = [_format_constraint(c) for c in constraints]
- fmt_r = resname[0] + ":" + str(resname[1])
- if resname[2] is not None:
- fmt_r += "." + resname[2]
- r = " ## {}\n".format(fmt_r)
- for c in fmt_c:
- r += c + " [get_ports " + signame + "]\n"
- return r
-
-
-def _build_xdc(named_sc, named_pc):
- r = ""
- for sig, pins, others, resname in named_sc:
- if len(pins) > 1:
- for i, p in enumerate(pins):
- r += _format_xdc(sig + "[" + str(i) + "]", resname, Pins(p), *others)
- elif pins:
- r += _format_xdc(sig, resname, Pins(pins[0]), *others)
- else:
- r += _format_xdc(sig, resname, *others)
- if named_pc:
- r += "\n" + "\n\n".join(named_pc)
- return r
-
-
-def _run_vivado(build_name, vivado_path, source, ver=None):
- if sys.platform == "win32" or sys.platform == "cygwin":
- build_script_contents = "REM Autogenerated by Migen\n"
- build_script_contents += "vivado -mode batch -source " + build_name + ".tcl\n"
- build_script_file = "build_" + build_name + ".bat"
- tools.write_to_file(build_script_file, build_script_contents)
- r = subprocess.call([build_script_file])
- else:
- build_script_contents = "# Autogenerated by Migen\nset -e\n"
- settings = common.settings(vivado_path, ver)
- build_script_contents += "source " + settings + "\n"
- build_script_contents += "vivado -mode batch -source " + build_name + ".tcl\n"
- build_script_file = "build_" + build_name + ".sh"
- tools.write_to_file(build_script_file, build_script_contents)
- r = subprocess.call(["bash", build_script_file])
-
- if r != 0:
- raise OSError("Subprocess failed")
-
-
-class XilinxVivadoToolchain:
- def __init__(self):
- self.bitstream_commands = []
- self.additional_commands = []
- self.pre_synthesis_commands = []
- self.with_phys_opt = False
-
- def _build_batch(self, platform, sources, build_name):
- tcl = []
- for filename, language, library in sources:
- filename_tcl = "{" + filename + "}"
- tcl.append("add_files " + filename_tcl)
- tcl.append("set_property library {} [get_files {}]"
- .format(library, filename_tcl))
-
- tcl.append("read_xdc {}.xdc".format(build_name))
- tcl.extend(c.format(build_name=build_name) for c in self.pre_synthesis_commands)
- tcl.append("synth_design -top top -part {} -include_dirs {{{}}}".format(platform.device, " ".join(platform.verilog_include_paths)))
- tcl.append("report_utilization -hierarchical -file {}_utilization_hierarchical_synth.rpt".format(build_name))
- tcl.append("report_utilization -file {}_utilization_synth.rpt".format(build_name))
- tcl.append("place_design")
- if self.with_phys_opt:
- tcl.append("phys_opt_design -directive AddRetime")
- tcl.append("report_utilization -hierarchical -file {}_utilization_hierarchical_place.rpt".format(build_name))
- tcl.append("report_utilization -file {}_utilization_place.rpt".format(build_name))
- tcl.append("report_io -file {}_io.rpt".format(build_name))
- tcl.append("report_control_sets -verbose -file {}_control_sets.rpt".format(build_name))
- tcl.append("report_clock_utilization -file {}_clock_utilization.rpt".format(build_name))
- tcl.append("route_design")
- tcl.append("report_route_status -file {}_route_status.rpt".format(build_name))
- tcl.append("report_drc -file {}_drc.rpt".format(build_name))
- tcl.append("report_timing_summary -max_paths 10 -file {}_timing.rpt".format(build_name))
- tcl.append("report_power -file {}_power.rpt".format(build_name))
- for bitstream_command in self.bitstream_commands:
- tcl.append(bitstream_command.format(build_name=build_name))
- tcl.append("write_bitstream -force {}.bit ".format(build_name))
- for additional_command in self.additional_commands:
- tcl.append(additional_command.format(build_name=build_name))
- tcl.append("quit")
- tools.write_to_file(build_name + ".tcl", "\n".join(tcl))
-
- def build(self, platform, fragment, build_dir="build", build_name="top",
- toolchain_path="/opt/Xilinx/Vivado", source=True, run=True):
- tools.mkdir_noerror(build_dir)
- os.chdir(build_dir)
-
- if not isinstance(fragment, _Fragment):
- fragment = fragment.get_fragment()
- platform.finalize(fragment)
- v_output = platform.get_verilog(fragment)
- named_sc, named_pc = platform.resolve_signals(v_output.ns)
- v_file = build_name + ".v"
- v_output.write(v_file)
- sources = platform.sources | {(v_file, "verilog", "work")}
- self._build_batch(platform, sources, build_name)
- tools.write_to_file(build_name + ".xdc", _build_xdc(named_sc, named_pc))
- if run:
- _run_vivado(build_name, toolchain_path, source)
-
- os.chdir("..")
-
- return v_output.ns
-
- def add_period_constraint(self, platform, clk, period):
- platform.add_platform_command("""create_clock -name {clk} -period """ + \
- str(period) + """ [get_ports {clk}]""", clk=clk)
+++ /dev/null
-from migen.fhdl import structure as f
-
-
-__all__ = ["log2_int", "bits_for", "value_bits_sign"]
-
-
-def log2_int(n, need_pow2=True):
- l = 1
- r = 0
- while l < n:
- l *= 2
- r += 1
- if need_pow2 and l != n:
- raise ValueError("Not a power of 2")
- return r
-
-
-def bits_for(n, require_sign_bit=False):
- if n > 0:
- r = log2_int(n + 1, False)
- else:
- require_sign_bit = True
- r = log2_int(-n, False)
- if require_sign_bit:
- r += 1
- return r
-
-
-def value_bits_sign(v):
- """Bit length and signedness of a value.
-
- Parameters
- ----------
- v : Value
-
- Returns
- -------
- int, bool
- Number of bits required to store `v` or available in `v`, followed by
- whether `v` has a sign bit (included in the bit count).
-
- Examples
- --------
- >>> value_bits_sign(f.Signal(8))
- 8, False
- >>> value_bits_sign(C(0xaa))
- 8, False
- """
- if isinstance(v, (f.Constant, f.Signal)):
- return v.nbits, v.signed
- elif isinstance(v, (f.ClockSignal, f.ResetSignal)):
- return 1, False
- elif isinstance(v, f._Operator):
- obs = list(map(value_bits_sign, v.operands))
- if v.op == "+" or v.op == "-":
- if not obs[0][1] and not obs[1][1]:
- # both operands unsigned
- return max(obs[0][0], obs[1][0]) + 1, False
- elif obs[0][1] and obs[1][1]:
- # both operands signed
- return max(obs[0][0], obs[1][0]) + 1, True
- elif not obs[0][1] and obs[1][1]:
- # first operand unsigned (add sign bit), second operand signed
- return max(obs[0][0] + 1, obs[1][0]) + 1, True
- else:
- # first signed, second operand unsigned (add sign bit)
- return max(obs[0][0], obs[1][0] + 1) + 1, True
- elif v.op == "*":
- if not obs[0][1] and not obs[1][1]:
- # both operands unsigned
- return obs[0][0] + obs[1][0], False
- elif obs[0][1] and obs[1][1]:
- # both operands signed
- return obs[0][0] + obs[1][0] - 1, True
- else:
- # one operand signed, the other unsigned (add sign bit)
- return obs[0][0] + obs[1][0] + 1 - 1, True
- elif v.op == "<<<":
- if obs[1][1]:
- extra = 2**(obs[1][0] - 1) - 1
- else:
- extra = 2**obs[1][0] - 1
- return obs[0][0] + extra, obs[0][1]
- elif v.op == ">>>":
- if obs[1][1]:
- extra = 2**(obs[1][0] - 1)
- else:
- extra = 0
- return obs[0][0] + extra, obs[0][1]
- elif v.op == "&" or v.op == "^" or v.op == "|":
- if not obs[0][1] and not obs[1][1]:
- # both operands unsigned
- return max(obs[0][0], obs[1][0]), False
- elif obs[0][1] and obs[1][1]:
- # both operands signed
- return max(obs[0][0], obs[1][0]), True
- elif not obs[0][1] and obs[1][1]:
- # first operand unsigned (add sign bit), second operand signed
- return max(obs[0][0] + 1, obs[1][0]), True
- else:
- # first signed, second operand unsigned (add sign bit)
- return max(obs[0][0], obs[1][0] + 1), True
- elif v.op == "<" or v.op == "<=" or v.op == "==" or v.op == "!=" \
- or v.op == ">" or v.op == ">=":
- return 1, False
- elif v.op == "~":
- return obs[0]
- else:
- raise TypeError
- elif isinstance(v, f._Slice):
- return v.stop - v.start, value_bits_sign(v.value)[1]
- elif isinstance(v, f.Cat):
- return sum(value_bits_sign(sv)[0] for sv in v.l), False
- elif isinstance(v, f.Replicate):
- return (value_bits_sign(v.v)[0])*v.n, False
- elif isinstance(v, f._ArrayProxy):
- bsc = list(map(value_bits_sign, v.choices))
- return max(bs[0] for bs in bsc), any(bs[1] for bs in bsc)
- else:
- raise TypeError("Can not calculate bit length of {} {}".format(
- type(v), v))
+++ /dev/null
-from operator import itemgetter
-
-
-class ConvOutput:
- def __init__(self):
- self.main_source = ""
- self.data_files = dict()
-
- def set_main_source(self, src):
- self.main_source = src
-
- def add_data_file(self, filename_base, content):
- filename = filename_base
- i = 1
- while filename in self.data_files:
- parts = filename_base.split(".", maxsplit=1)
- parts[0] += "_" + str(i)
- filename = ".".join(parts)
- i += 1
- self.data_files[filename] = content
- return filename
-
- def __str__(self):
- r = self.main_source + "\n"
- for filename, content in sorted(self.data_files.items(),
- key=itemgetter(0)):
- r += filename + ":\n" + content
- return r
-
- def write(self, main_filename):
- with open(main_filename, "w") as f:
- f.write(self.main_source)
- for filename, content in self.data_files.items():
- with open(filename, "w") as f:
- f.write(content)
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-from migen.fhdl.tools import insert_reset, rename_clock_domain
-
-
-__all__ = ["CEInserter", "ResetInserter", "ClockDomainsRenamer",
- "ModuleTransformer"]
-
-
-class ModuleTransformer:
- # overload this in derived classes
- def transform_instance(self, i):
- pass
-
- # overload this in derived classes
- def transform_fragment(self, i, f):
- pass
-
- def wrap_class(self, victim):
- class Wrapped(victim):
- def __init__(i, *args, **kwargs):
- victim.__init__(i, *args, **kwargs)
- self.transform_instance(i)
-
- def get_fragment(i):
- f = victim.get_fragment(i)
- self.transform_fragment(i, f)
- return f
-
- Wrapped.__name__ = victim.__name__
- # "{}_{}".format(self.__class__.__name__, victim.__name__)
- return Wrapped
-
- def wrap_instance(self, victim):
- self.transform_instance(victim)
- orig_get_fragment = victim.get_fragment
-
- def get_fragment():
- f = orig_get_fragment()
- self.transform_fragment(victim, f)
- return f
-
- victim.get_fragment = get_fragment
- return victim
-
- def __call__(self, victim):
- if isinstance(victim, Module):
- return self.wrap_instance(victim)
- else:
- return self.wrap_class(victim)
-
-
-class ControlInserter(ModuleTransformer):
- control_name = None # override this
-
- def __init__(self, clock_domains=None):
- self.clock_domains = clock_domains
-
- def transform_instance(self, i):
- if self.clock_domains is None:
- ctl = Signal(name=self.control_name)
- assert not hasattr(i, self.control_name)
- setattr(i, self.control_name, ctl)
- else:
- for cd in self.clock_domains:
- name = self.control_name + "_" + cd
- ctl = Signal(name=name)
- assert not hasattr(i, name)
- setattr(i, name, ctl)
-
- def transform_fragment(self, i, f):
- if self.clock_domains is None:
- if len(f.sync) != 1:
- raise ValueError("Control signal clock domains must be specified when module has more than one domain")
- cdn = list(f.sync.keys())[0]
- to_insert = [(getattr(i, self.control_name), cdn)]
- else:
- to_insert = [(getattr(i, self.control_name + "_" + cdn), cdn)
- for cdn in self.clock_domains]
- self.transform_fragment_insert(i, f, to_insert)
-
-
-class CEInserter(ControlInserter):
- control_name = "ce"
-
- def transform_fragment_insert(self, i, f, to_insert):
- for ce, cdn in to_insert:
- f.sync[cdn] = [If(ce, *f.sync[cdn])]
-
-
-class ResetInserter(ControlInserter):
- control_name = "reset"
-
- def transform_fragment_insert(self, i, f, to_insert):
- for reset, cdn in to_insert:
- f.sync[cdn] = insert_reset(reset, f.sync[cdn])
-
-
-class ClockDomainsRenamer(ModuleTransformer):
- def __init__(self, cd_remapping):
- if isinstance(cd_remapping, str):
- cd_remapping = {"sys": cd_remapping}
- self.cd_remapping = cd_remapping
-
- def transform_fragment(self, i, f):
- for old, new in self.cd_remapping.items():
- rename_clock_domain(f, old, new)
+++ /dev/null
-from collections import OrderedDict, namedtuple
-
-from migen.fhdl.structure import *
-from migen.fhdl.namer import build_namespace
-from migen.fhdl.tools import list_special_ios
-from migen.fhdl.structure import _Fragment
-from migen.fhdl.conv_output import ConvOutput
-
-
-_Port = namedtuple("_Port", "name direction")
-_Cell = namedtuple("_Cell", "name ports")
-_Property = namedtuple("_Property", "name value")
-_Instance = namedtuple("_Instance", "name cell properties")
-_NetBranch = namedtuple("_NetBranch", "portname instancename")
-
-
-def _write_cells(cells):
- r = ""
- for cell in cells:
- r += """
- (cell {0.name}
- (cellType GENERIC)
- (view view_1
- (viewType NETLIST)
- (interface""".format(cell)
- for port in cell.ports:
- r += """
- (port {0.name} (direction {0.direction}))""".format(port)
- r += """
- )
- )
- )"""
- return r
-
-
-def _write_io(ios):
- r = ""
- for s in ios:
- r += """
- (port {0.name} (direction {0.direction}))""".format(s)
- return r
-
-
-def _write_instantiations(instances, cell_library):
- instantiations = ""
- for instance in instances:
- instantiations += """
- (instance {0.name}
- (viewRef view_1 (cellRef {0.cell} (libraryRef {1})))""".format(instance, cell_library)
- for prop in instance.properties:
- instantiations += """
- (property {0} (string "{1}"))""".format(prop.name, prop.value)
- instantiations += """
- )"""
- return instantiations
-
-
-def _write_connections(connections):
- r = ""
- for netname, branches in connections.items():
- r += """
- (net {0}
- (joined""".format(netname)
- for branch in branches:
- r += """
- (portRef {0}{1})""".format(branch.portname, "" if branch.instancename == "" else " (instanceRef {})".format(branch.instancename))
- r += """
- )
- )"""
- return r
-
-
-def _write_edif(cells, ios, instances, connections, cell_library, design_name, part, vendor):
- r = """(edif {0}
- (edifVersion 2 0 0)
- (edifLevel 0)
- (keywordMap (keywordLevel 0))
- (external {1}
- (edifLevel 0)
- (technology (numberDefinition))""".format(design_name, cell_library)
- r += _write_cells(cells)
- r += """
- )
- (library {0}_lib
- (edifLevel 0)
- (technology (numberDefinition))
- (cell {0}
- (cellType GENERIC)
- (view view_1
- (viewType NETLIST)
- (interface""".format(design_name)
- r += _write_io(ios)
- r += """
- (designator "{0}")
- )
- (contents""".format(part)
- r += _write_instantiations(instances, cell_library)
- r += _write_connections(connections)
- r += """
- )
- )
- )
- )
- (design {0}
- (cellRef {0} (libraryRef {0}_lib))
- (property PART (string "{1}") (owner "{2}"))
- )
-)""".format(design_name, part, vendor)
-
- return r
-
-
-def _generate_cells(f):
- cell_dict = OrderedDict()
- for special in f.specials:
- if isinstance(special, Instance):
- port_list = []
- for port in special.items:
- if isinstance(port, Instance.Input):
- port_list.append(_Port(port.name, "INPUT"))
- elif isinstance(port, Instance.Output):
- port_list.append(_Port(port.name, "OUTPUT"))
- elif isinstance(port, Instance.InOut):
- port_list.append(_Port(port.name, "INOUT"))
- elif isinstance(port, Instance.Parameter):
- pass
- else:
- raise NotImplementedError("Unsupported instance item")
- if special.of in cell_dict:
- if set(port_list) != set(cell_dict[special.of]):
- raise ValueError("All instances must have the same ports for EDIF conversion")
- else:
- cell_dict[special.of] = port_list
- else:
- raise ValueError("EDIF conversion can only handle synthesized fragments")
- return [_Cell(k, v) for k, v in cell_dict.items()]
-
-
-def _generate_instances(f, ns):
- instances = []
- for special in f.specials:
- if isinstance(special, Instance):
- props = []
- for prop in special.items:
- if isinstance(prop, Instance.Input):
- pass
- elif isinstance(prop, Instance.Output):
- pass
- elif isinstance(prop, Instance.InOut):
- pass
- elif isinstance(prop, Instance.Parameter):
- props.append(_Property(name=prop.name, value=prop.value))
- else:
- raise NotImplementedError("Unsupported instance item")
- instances.append(_Instance(name=ns.get_name(special), cell=special.of, properties=props))
- else:
- raise ValueError("EDIF conversion can only handle synthesized fragments")
- return instances
-
-
-def _generate_ios(f, ios, ns):
- outs = list_special_ios(f, False, True, False)
- inouts = list_special_ios(f, False, False, True)
- r = []
- for io in ios:
- direction = "OUTPUT" if io in outs else "INOUT" if io in inouts else "INPUT"
- r.append(_Port(name=ns.get_name(io), direction=direction))
- return r
-
-
-def _generate_connections(f, ios, ns):
- r = OrderedDict()
- for special in f.specials:
- if isinstance(special, Instance):
- instname = ns.get_name(special)
- for port in special.items:
- if isinstance(port, Instance._IO):
- s = ns.get_name(port.expr)
- if s not in r:
- r[s] = []
- r[s].append(_NetBranch(portname=port.name, instancename=instname))
- elif isinstance(port, Instance.Parameter):
- pass
- else:
- raise NotImplementedError("Unsupported instance item")
- else:
- raise ValueError("EDIF conversion can only handle synthesized fragments")
- for s in ios:
- io = ns.get_name(s)
- if io not in r:
- r[io] = []
- r[io].append(_NetBranch(portname=io, instancename=""))
- return r
-
-
-def convert(f, ios, cell_library, vendor, device, name="top"):
- if not isinstance(f, _Fragment):
- f = f.get_fragment()
- if f.comb != [] or f.sync != {}:
- raise ValueError("EDIF conversion can only handle synthesized fragments")
- if ios is None:
- ios = set()
- cells = _generate_cells(f)
- ns = build_namespace(list_special_ios(f, True, True, True))
- instances = _generate_instances(f, ns)
- inouts = _generate_ios(f, ios, ns)
- connections = _generate_connections(f, ios, ns)
- src = _write_edif(cells, inouts, instances, connections, cell_library, name, device, vendor)
-
- r = ConvOutput()
- r.set_main_source(src)
- r.ns = ns
- return r
+++ /dev/null
-import collections
-from itertools import combinations
-
-from migen.util.misc import flat_iteration
-from migen.fhdl.structure import *
-from migen.fhdl.structure import _Fragment
-from migen.fhdl.tools import rename_clock_domain
-
-
-__all__ = ["Module", "FinalizeError"]
-
-
-class FinalizeError(Exception):
- pass
-
-
-def _flat_list(e):
- if isinstance(e, collections.Iterable):
- return flat_iteration(e)
- else:
- return [e]
-
-
-class _ModuleProxy:
- def __init__(self, fm):
- object.__setattr__(self, "_fm", fm)
-
-
-class _ModuleComb(_ModuleProxy):
- def __iadd__(self, other):
- self._fm._fragment.comb += _flat_list(other)
- return self
-
-
-def _cd_append(d, key, statements):
- try:
- l = d[key]
- except KeyError:
- l = []
- d[key] = l
- l += _flat_list(statements)
-
-
-class _ModuleSyncCD:
- def __init__(self, fm, cd):
- self._fm = fm
- self._cd = cd
-
- def __iadd__(self, other):
- _cd_append(self._fm._fragment.sync, self._cd, other)
- return self
-
-
-class _ModuleSync(_ModuleProxy):
- def __iadd__(self, other):
- _cd_append(self._fm._fragment.sync, "sys", other)
- return self
-
- def __getattr__(self, name):
- return _ModuleSyncCD(self._fm, name)
-
- def __setattr__(self, name, value):
- if not isinstance(value, _ModuleSyncCD):
- raise AttributeError("Attempted to assign sync property - use += instead")
-
-
-# _ModuleForwardAttr enables user classes to do e.g.:
-# self.subm.foobar = SomeModule()
-# and then access the submodule with self.foobar.
-class _ModuleForwardAttr:
- def __setattr__(self, name, value):
- self.__iadd__(value)
- setattr(self._fm, name, value)
-
-
-class _ModuleSpecials(_ModuleProxy, _ModuleForwardAttr):
- def __iadd__(self, other):
- self._fm._fragment.specials |= set(_flat_list(other))
- return self
-
-
-class _ModuleSubmodules(_ModuleProxy):
- def __setattr__(self, name, value):
- self._fm._submodules += [(name, e) for e in _flat_list(value)]
- setattr(self._fm, name, value)
-
- def __iadd__(self, other):
- self._fm._submodules += [(None, e) for e in _flat_list(other)]
- return self
-
-
-class _ModuleClockDomains(_ModuleProxy, _ModuleForwardAttr):
- def __iadd__(self, other):
- self._fm._fragment.clock_domains += _flat_list(other)
- return self
-
-
-class Module:
- def get_fragment(self):
- assert(not self.get_fragment_called)
- self.get_fragment_called = True
- self.finalize()
- return self._fragment
-
- def __getattr__(self, name):
- if name == "comb":
- return _ModuleComb(self)
- elif name == "sync":
- return _ModuleSync(self)
- elif name == "specials":
- return _ModuleSpecials(self)
- elif name == "submodules":
- return _ModuleSubmodules(self)
- elif name == "clock_domains":
- return _ModuleClockDomains(self)
-
- # hack to have initialized regular attributes without using __init__
- # (which would require derived classes to call it)
- elif name == "finalized":
- self.finalized = False
- return self.finalized
- elif name == "_fragment":
- self._fragment = _Fragment()
- return self._fragment
- elif name == "_submodules":
- self._submodules = []
- return self._submodules
- elif name == "_clock_domains":
- self._clock_domains = []
- return self._clock_domains
- elif name == "get_fragment_called":
- self.get_fragment_called = False
- return self.get_fragment_called
-
- else:
- raise AttributeError("'"+self.__class__.__name__+"' object has no attribute '"+name+"'")
-
- def __setattr__(self, name, value):
- if name in ["comb", "sync", "specials", "submodules", "clock_domains"]:
- if not isinstance(value, _ModuleProxy):
- raise AttributeError("Attempted to assign special Module property - use += instead")
- else:
- object.__setattr__(self, name, value)
-
- def _collect_submodules(self):
- r = []
- for name, submodule in self._submodules:
- if not submodule.get_fragment_called:
- r.append((name, submodule.get_fragment()))
- return r
-
- def finalize(self, *args, **kwargs):
- if not self.finalized:
- self.finalized = True
- # finalize existing submodules before finalizing us
- subfragments = self._collect_submodules()
- self.do_finalize(*args, **kwargs)
- # finalize submodules created by do_finalize
- subfragments += self._collect_submodules()
- # resolve clock domain name conflicts
- needs_renaming = set()
- for (mod_name1, f1), (mod_name2, f2) in combinations(subfragments, 2):
- f1_names = set(cd.name for cd in f1.clock_domains)
- f2_names = set(cd.name for cd in f2.clock_domains)
- common_names = f1_names & f2_names
- if common_names:
- if mod_name1 is None or mod_name2 is None:
- raise ValueError("Multiple submodules with local clock domains cannot be anonymous")
- if mod_name1 == mod_name2:
- raise ValueError("Multiple submodules with local clock domains cannot have the same name")
- needs_renaming |= common_names
- for mod_name, f in subfragments:
- for cd in f.clock_domains:
- if cd.name in needs_renaming:
- rename_clock_domain(f, cd.name, mod_name + "_" + cd.name)
- # sum subfragments
- for mod_name, f in subfragments:
- self._fragment += f
-
- def do_finalize(self):
- pass
-
- def do_exit(self, *args, **kwargs):
- for name, submodule in self._submodules:
- submodule.do_exit(*args, **kwargs)
+++ /dev/null
-from collections import OrderedDict
-from itertools import combinations
-
-from migen.fhdl.structure import *
-
-
-class _Node:
- def __init__(self):
- self.signal_count = 0
- self.numbers = set()
- self.use_name = False
- self.use_number = False
- self.children = OrderedDict()
-
-
-def _display_tree(filename, tree):
- from migen.util.treeviz import RenderNode
-
- def _to_render_node(name, node):
- children = [_to_render_node(k, v) for k, v in node.children.items()]
- if node.use_name:
- if node.use_number:
- color = (0.5, 0.9, 0.8)
- else:
- color = (0.8, 0.5, 0.9)
- else:
- if node.use_number:
- color = (0.9, 0.8, 0.5)
- else:
- color = (0.8, 0.8, 0.8)
- label = "{0}\n{1} signals\n{2}".format(name, node.signal_count, node.numbers)
- return RenderNode(label, children, color=color)
-
- top = _to_render_node("top", tree)
- top.to_svg(filename)
-
-
-def _build_tree(signals, basic_tree=None):
- root = _Node()
- for signal in signals:
- current_b = basic_tree
- current = root
- current.signal_count += 1
- for name, number in signal.backtrace:
- if basic_tree is None:
- use_number = False
- else:
- current_b = current_b.children[name]
- use_number = current_b.use_number
- if use_number:
- key = (name, number)
- else:
- key = name
- try:
- current = current.children[key]
- except KeyError:
- new = _Node()
- current.children[key] = new
- current = new
- current.numbers.add(number)
- if use_number:
- current.all_numbers = sorted(current_b.numbers)
- current.signal_count += 1
- return root
-
-
-def _set_use_name(node, node_name=""):
- cnames = [(k, _set_use_name(v, k)) for k, v in node.children.items()]
- for (c1_prefix, c1_names), (c2_prefix, c2_names) in combinations(cnames, 2):
- if not c1_names.isdisjoint(c2_names):
- node.children[c1_prefix].use_name = True
- node.children[c2_prefix].use_name = True
- r = set()
- for c_prefix, c_names in cnames:
- if node.children[c_prefix].use_name:
- for c_name in c_names:
- r.add((c_prefix, ) + c_name)
- else:
- r |= c_names
-
- if node.signal_count > sum(c.signal_count for c in node.children.values()):
- node.use_name = True
- r.add((node_name, ))
-
- return r
-
-
-def _name_signal(tree, signal):
- elements = []
- treepos = tree
- for step_name, step_n in signal.backtrace:
- try:
- treepos = treepos.children[(step_name, step_n)]
- use_number = True
- except KeyError:
- treepos = treepos.children[step_name]
- use_number = False
- if treepos.use_name:
- elname = step_name
- if use_number:
- elname += str(treepos.all_numbers.index(step_n))
- elements.append(elname)
- return "_".join(elements)
-
-
-def _build_pnd_from_tree(tree, signals):
- return dict((signal, _name_signal(tree, signal)) for signal in signals)
-
-
-def _invert_pnd(pnd):
- inv_pnd = dict()
- for k, v in pnd.items():
- inv_pnd[v] = inv_pnd.get(v, [])
- inv_pnd[v].append(k)
- return inv_pnd
-
-
-def _list_conflicting_signals(pnd):
- inv_pnd = _invert_pnd(pnd)
- r = set()
- for k, v in inv_pnd.items():
- if len(v) > 1:
- r.update(v)
- return r
-
-
-def _set_use_number(tree, signals):
- for signal in signals:
- current = tree
- for step_name, step_n in signal.backtrace:
- current = current.children[step_name]
- current.use_number = current.signal_count > len(current.numbers) and len(current.numbers) > 1
-
-_debug = False
-
-
-def _build_pnd_for_group(group_n, signals):
- basic_tree = _build_tree(signals)
- _set_use_name(basic_tree)
- if _debug:
- _display_tree("tree{0}_basic.svg".format(group_n), basic_tree)
- pnd = _build_pnd_from_tree(basic_tree, signals)
-
- # If there are conflicts, try splitting the tree by numbers
- # on paths taken by conflicting signals.
- conflicting_signals = _list_conflicting_signals(pnd)
- if conflicting_signals:
- _set_use_number(basic_tree, conflicting_signals)
- if _debug:
- print("namer: using split-by-number strategy (group {0})".format(group_n))
- _display_tree("tree{0}_marked.svg".format(group_n), basic_tree)
- numbered_tree = _build_tree(signals, basic_tree)
- _set_use_name(numbered_tree)
- if _debug:
- _display_tree("tree{0}_numbered.svg".format(group_n), numbered_tree)
- pnd = _build_pnd_from_tree(numbered_tree, signals)
- else:
- if _debug:
- print("namer: using basic strategy (group {0})".format(group_n))
-
- # ...then add number suffixes by DUID
- inv_pnd = _invert_pnd(pnd)
- duid_suffixed = False
- for name, signals in inv_pnd.items():
- if len(signals) > 1:
- duid_suffixed = True
- for n, signal in enumerate(sorted(signals, key=lambda x: x.duid)):
- pnd[signal] += str(n)
- if _debug and duid_suffixed:
- print("namer: using DUID suffixes (group {0})".format(group_n))
-
- return pnd
-
-
-def _build_signal_groups(signals):
- r = []
- for signal in signals:
- # build chain of related signals
- related_list = []
- cur_signal = signal
- while cur_signal is not None:
- related_list.insert(0, cur_signal)
- cur_signal = cur_signal.related
- # add to groups
- for _ in range(len(related_list) - len(r)):
- r.append(set())
- for target_set, source_signal in zip(r, related_list):
- target_set.add(source_signal)
- # with the algorithm above and a list of all signals,
- # a signal appears in all groups of a lower number than its.
- # make signals appear only in their group of highest number.
- for s1, s2 in zip(r, r[1:]):
- s1 -= s2
- return r
-
-
-def _build_pnd(signals):
- groups = _build_signal_groups(signals)
- gpnds = [_build_pnd_for_group(n, gsignals) for n, gsignals in enumerate(groups)]
-
- pnd = dict()
- for gn, gpnd in enumerate(gpnds):
- for signal, name in gpnd.items():
- result = name
- cur_gn = gn
- cur_signal = signal
- while cur_signal.related is not None:
- cur_signal = cur_signal.related
- cur_gn -= 1
- result = gpnds[cur_gn][cur_signal] + "_" + result
- pnd[signal] = result
-
- return pnd
-
-
-def build_namespace(signals, reserved_keywords=set()):
- pnd = _build_pnd(signals)
- ns = Namespace(pnd, reserved_keywords)
- # register signals with name_override
- for signal in signals:
- if signal.name_override is not None:
- ns.get_name(signal)
- return ns
-
-
-class Namespace:
- def __init__(self, pnd, reserved_keywords=set()):
- self.counts = {k: 1 for k in reserved_keywords}
- self.sigs = {}
- self.pnd = pnd
- self.clock_domains = dict()
-
- def get_name(self, sig):
- if isinstance(sig, ClockSignal):
- sig = self.clock_domains[sig.cd].clk
- if isinstance(sig, ResetSignal):
- sig = self.clock_domains[sig.cd].rst
- if sig is None:
- raise ValueError("Attempted to obtain name of non-existent "
- "reset signal of domain "+sig.cd)
-
- if sig.name_override is not None:
- sig_name = sig.name_override
- else:
- sig_name = self.pnd[sig]
- try:
- n = self.sigs[sig]
- except KeyError:
- try:
- n = self.counts[sig_name]
- except KeyError:
- n = 0
- self.sigs[sig] = n
- self.counts[sig_name] = n + 1
- if n:
- return sig_name + "_" + str(n)
- else:
- return sig_name
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.specials import Memory, _MemoryPort, WRITE_FIRST, NO_CHANGE
-from migen.fhdl.decorators import ModuleTransformer
-from migen.util.misc import gcd_multiple
-
-
-class FullMemoryWE(ModuleTransformer):
- def __init__(self):
- self.replacments = dict()
-
- def transform_fragment(self, i, f):
- newspecials = set()
-
- for orig in f.specials:
- if not isinstance(orig, Memory):
- newspecials.add(orig)
- continue
- global_granularity = gcd_multiple([p.we_granularity if p.we_granularity else orig.width for p in orig.ports])
- if global_granularity == orig.width:
- newspecials.add(orig) # nothing to do
- else:
- newmems = []
- for i in range(orig.width//global_granularity):
- if orig.init is None:
- newinit = None
- else:
- newinit = [(v >> i*global_granularity) & (2**global_granularity - 1) for v in orig.init]
- newmem = Memory(global_granularity, orig.depth, newinit, orig.name_override + "_grain" + str(i))
- newspecials.add(newmem)
- newmems.append(newmem)
- for port in orig.ports:
- port_granularity = port.we_granularity if port.we_granularity else orig.width
- newport = _MemoryPort(
- adr=port.adr,
-
- dat_r=port.dat_r[i*global_granularity:(i+1)*global_granularity] if port.dat_r is not None else None,
- we=port.we[i*global_granularity//port_granularity] if port.we is not None else None,
- dat_w=port.dat_w[i*global_granularity:(i+1)*global_granularity] if port.dat_w is not None else None,
-
- async_read=port.async_read,
- re=port.re,
- we_granularity=0,
- mode=port.mode,
- clock_domain=port.clock.cd)
- newmem.ports.append(newport)
- newspecials.add(newport)
- self.replacments[orig] = newmems
-
- f.specials = newspecials
-
-
-class MemoryToArray(ModuleTransformer):
- def __init__(self):
- self.replacements = dict()
-
- def transform_fragment(self, i, f):
- newspecials = set()
-
- for mem in f.specials:
- if not isinstance(mem, Memory):
- newspecials.add(mem)
- continue
-
- storage = Array()
- self.replacements[mem] = storage
- init = []
- if mem.init is not None:
- init = mem.init
- for d in init:
- mem_storage = Signal(mem.width, reset=d)
- storage.append(mem_storage)
- for _ in range(mem.depth-len(init)):
- mem_storage = Signal(mem.width)
- storage.append(mem_storage)
-
- for port in mem.ports:
- if port.we_granularity:
- raise NotImplementedError
- try:
- sync = f.sync[port.clock.cd]
- except KeyError:
- sync = f.sync[port.clock.cd] = []
-
- # read
- if port.async_read:
- f.comb.append(port.dat_r.eq(storage[port.adr]))
- else:
- if port.mode == WRITE_FIRST and port.we is not None:
- adr_reg = Signal.like(port.adr)
- rd_stmt = adr_reg.eq(port.adr)
- f.comb.append(port.dat_r.eq(storage[adr_reg]))
- elif port.mode == NO_CHANGE and port.we is not None:
- rd_stmt = If(~port.we, port.dat_r.eq(storage[port.adr]))
- else: # READ_FIRST or port.we is None, simplest case
- rd_stmt = port.dat_r.eq(storage[port.adr])
- if port.re is None:
- sync.append(rd_stmt)
- else:
- sync.append(If(port.re, rd_stmt))
-
- # write
- if port.we is not None:
- if port.we_granularity:
- n = mem.width//port.we_granularity
- for i in range(n):
- m = i*port.we_granularity
- M = (i+1)*port.we_granularity
- sync.append(If(port.we[i],
- storage[port.adr][m:M].eq(port.dat_w)))
- else:
- sync.append(If(port.we,
- storage[port.adr].eq(port.dat_w)))
-
- f.specials = newspecials
+++ /dev/null
-from operator import itemgetter
-
-from migen.fhdl.structure import *
-from migen.fhdl.structure import _Value
-from migen.fhdl.bitcontainer import bits_for, value_bits_sign
-from migen.fhdl.tools import *
-from migen.fhdl.tracer import get_obj_var_name
-from migen.fhdl.verilog import _printexpr as verilog_printexpr
-
-
-__all__ = ["TSTriple", "Instance", "Memory",
- "READ_FIRST", "WRITE_FIRST", "NO_CHANGE"]
-
-
-class Special(DUID):
- def iter_expressions(self):
- for x in []:
- yield x
-
- def rename_clock_domain(self, old, new):
- for obj, attr, direction in self.iter_expressions():
- rename_clock_domain_expr(getattr(obj, attr), old, new)
-
- def list_clock_domains(self):
- r = set()
- for obj, attr, direction in self.iter_expressions():
- r |= list_clock_domains_expr(getattr(obj, attr))
- return r
-
- def list_ios(self, ins, outs, inouts):
- r = set()
- for obj, attr, direction in self.iter_expressions():
- if (direction == SPECIAL_INPUT and ins) \
- or (direction == SPECIAL_OUTPUT and outs) \
- or (direction == SPECIAL_INOUT and inouts):
- signals = list_signals(getattr(obj, attr))
- r.update(signals)
- return r
-
-
-class Tristate(Special):
- def __init__(self, target, o, oe, i=None):
- Special.__init__(self)
- self.target = wrap(target)
- self.o = wrap(o)
- self.oe = wrap(oe)
- self.i = wrap(i) if i is not None else None
-
- def iter_expressions(self):
- for attr, target_context in [
- ("target", SPECIAL_INOUT),
- ("o", SPECIAL_INPUT),
- ("oe", SPECIAL_INPUT),
- ("i", SPECIAL_OUTPUT)]:
- if getattr(self, attr) is not None:
- yield self, attr, target_context
-
- @staticmethod
- def emit_verilog(tristate, ns, add_data_file):
- def pe(e):
- return verilog_printexpr(ns, e)[0]
- w, s = value_bits_sign(tristate.target)
- r = "assign " + pe(tristate.target) + " = " \
- + pe(tristate.oe) + " ? " + pe(tristate.o) \
- + " : " + str(w) + "'bz;\n"
- if tristate.i is not None:
- r += "assign " + pe(tristate.i) + " = " + pe(tristate.target) + ";\n"
- r += "\n"
- return r
-
-
-class TSTriple:
- def __init__(self, bits_sign=None, min=None, max=None, reset_o=0, reset_oe=0):
- self.o = Signal(bits_sign, min=min, max=max, reset=reset_o)
- self.oe = Signal(reset=reset_oe)
- self.i = Signal(bits_sign, min=min, max=max)
-
- def get_tristate(self, target):
- return Tristate(target, self.o, self.oe, self.i)
-
-
-class Instance(Special):
- class _IO:
- def __init__(self, name, expr=None):
- self.name = name
- if expr is None:
- expr = Signal()
- self.expr = wrap(expr)
- class Input(_IO):
- pass
- class Output(_IO):
- pass
- class InOut(_IO):
- pass
- class Parameter:
- def __init__(self, name, value):
- self.name = name
- if isinstance(value, (int, bool)):
- value = Constant(value)
- self.value = value
- class PreformattedParam(str):
- pass
-
- def __init__(self, of, *items, name="", synthesis_directive=None, **kwargs):
- Special.__init__(self)
- self.of = of
- if name:
- self.name_override = name
- else:
- self.name_override = of
- self.items = list(items)
- self.synthesis_directive = synthesis_directive
- for k, v in sorted(kwargs.items(), key=itemgetter(0)):
- item_type, item_name = k.split("_", maxsplit=1)
- item_class = {
- "i": Instance.Input,
- "o": Instance.Output,
- "io": Instance.InOut,
- "p": Instance.Parameter
- }[item_type]
- self.items.append(item_class(item_name, v))
-
- def get_io(self, name):
- for item in self.items:
- if isinstance(item, Instance._IO) and item.name == name:
- return item.expr
-
- def iter_expressions(self):
- for item in self.items:
- if isinstance(item, Instance.Input):
- yield item, "expr", SPECIAL_INPUT
- elif isinstance(item, Instance.Output):
- yield item, "expr", SPECIAL_OUTPUT
- elif isinstance(item, Instance.InOut):
- yield item, "expr", SPECIAL_INOUT
-
- @staticmethod
- def emit_verilog(instance, ns, add_data_file):
- r = instance.of + " "
- parameters = list(filter(lambda i: isinstance(i, Instance.Parameter), instance.items))
- if parameters:
- r += "#(\n"
- firstp = True
- for p in parameters:
- if not firstp:
- r += ",\n"
- firstp = False
- r += "\t." + p.name + "("
- if isinstance(p.value, Constant):
- r += verilog_printexpr(ns, p.value)[0]
- elif isinstance(p.value, float):
- r += str(p.value)
- elif isinstance(p.value, Instance.PreformattedParam):
- r += p.value
- elif isinstance(p.value, str):
- r += "\"" + p.value + "\""
- else:
- raise TypeError
- r += ")"
- r += "\n) "
- r += ns.get_name(instance)
- if parameters: r += " "
- r += "(\n"
- firstp = True
- for p in instance.items:
- if isinstance(p, Instance._IO):
- name_inst = p.name
- name_design = verilog_printexpr(ns, p.expr)[0]
- if not firstp:
- r += ",\n"
- firstp = False
- r += "\t." + name_inst + "(" + name_design + ")"
- if not firstp:
- r += "\n"
- if instance.synthesis_directive is not None:
- synthesis_directive = "/* synthesis {} */".format(instance.synthesis_directive)
- r += ")" + synthesis_directive + ";\n\n"
- else:
- r += ");\n\n"
- return r
-
-
-(READ_FIRST, WRITE_FIRST, NO_CHANGE) = range(3)
-
-
-class _MemoryPort(Special):
- def __init__(self, adr, dat_r, we=None, dat_w=None,
- async_read=False, re=None, we_granularity=0, mode=WRITE_FIRST,
- clock_domain="sys"):
- Special.__init__(self)
- self.adr = adr
- self.dat_r = dat_r
- self.we = we
- self.dat_w = dat_w
- self.async_read = async_read
- self.re = re
- self.we_granularity = we_granularity
- self.mode = mode
- self.clock = ClockSignal(clock_domain)
-
- def iter_expressions(self):
- for attr, target_context in [
- ("adr", SPECIAL_INPUT),
- ("we", SPECIAL_INPUT),
- ("dat_w", SPECIAL_INPUT),
- ("re", SPECIAL_INPUT),
- ("dat_r", SPECIAL_OUTPUT),
- ("clock", SPECIAL_INPUT)]:
- yield self, attr, target_context
-
- @staticmethod
- def emit_verilog(port, ns, add_data_file):
- return "" # done by parent Memory object
-
-
-class _MemoryLocation(_Value):
- def __init__(self, memory, index):
- _Value.__init__(self)
- self.memory = memory
- self.index = wrap(index)
-
-
-class Memory(Special):
- def __init__(self, width, depth, init=None, name=None):
- Special.__init__(self)
- self.width = width
- self.depth = depth
- self.ports = []
- self.init = init
- self.name_override = get_obj_var_name(name, "mem")
-
- def __getitem__(self, index):
- # simulation only
- return _MemoryLocation(self, index)
-
- def get_port(self, write_capable=False, async_read=False,
- has_re=False, we_granularity=0, mode=WRITE_FIRST,
- clock_domain="sys"):
- if we_granularity >= self.width:
- we_granularity = 0
- adr = Signal(max=self.depth)
- dat_r = Signal(self.width)
- if write_capable:
- if we_granularity:
- we = Signal(self.width//we_granularity)
- else:
- we = Signal()
- dat_w = Signal(self.width)
- else:
- we = None
- dat_w = None
- if has_re:
- re = Signal()
- else:
- re = None
- mp = _MemoryPort(adr, dat_r, we, dat_w,
- async_read, re, we_granularity, mode,
- clock_domain)
- self.ports.append(mp)
- return mp
-
- @staticmethod
- def emit_verilog(memory, ns, add_data_file):
- r = ""
- def gn(e):
- if isinstance(e, Memory):
- return ns.get_name(e)
- else:
- return verilog_printexpr(ns, e)[0]
- adrbits = bits_for(memory.depth-1)
-
- r += "reg [" + str(memory.width-1) + ":0] " \
- + gn(memory) \
- + "[0:" + str(memory.depth-1) + "];\n"
-
- adr_regs = {}
- data_regs = {}
- for port in memory.ports:
- if not port.async_read:
- if port.mode == WRITE_FIRST and port.we is not None:
- adr_reg = Signal(name_override="memadr")
- r += "reg [" + str(adrbits-1) + ":0] " \
- + gn(adr_reg) + ";\n"
- adr_regs[id(port)] = adr_reg
- else:
- data_reg = Signal(name_override="memdat")
- r += "reg [" + str(memory.width-1) + ":0] " \
- + gn(data_reg) + ";\n"
- data_regs[id(port)] = data_reg
-
- for port in memory.ports:
- r += "always @(posedge " + gn(port.clock) + ") begin\n"
- if port.we is not None:
- if port.we_granularity:
- n = memory.width//port.we_granularity
- for i in range(n):
- m = i*port.we_granularity
- M = (i+1)*port.we_granularity-1
- sl = "[" + str(M) + ":" + str(m) + "]"
- r += "\tif (" + gn(port.we) + "[" + str(i) + "])\n"
- r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "]" + sl + " <= " + gn(port.dat_w) + sl + ";\n"
- else:
- r += "\tif (" + gn(port.we) + ")\n"
- r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "] <= " + gn(port.dat_w) + ";\n"
- if not port.async_read:
- if port.mode == WRITE_FIRST and port.we is not None:
- rd = "\t" + gn(adr_regs[id(port)]) + " <= " + gn(port.adr) + ";\n"
- else:
- bassign = gn(data_regs[id(port)]) + " <= " + gn(memory) + "[" + gn(port.adr) + "];\n"
- if port.mode == READ_FIRST or port.we is None:
- rd = "\t" + bassign
- elif port.mode == NO_CHANGE:
- rd = "\tif (!" + gn(port.we) + ")\n" \
- + "\t\t" + bassign
- if port.re is None:
- r += rd
- else:
- r += "\tif (" + gn(port.re) + ")\n"
- r += "\t" + rd.replace("\n\t", "\n\t\t")
- r += "end\n\n"
-
- for port in memory.ports:
- if port.async_read:
- r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(port.adr) + "];\n"
- else:
- if port.mode == WRITE_FIRST and port.we is not None:
- r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(adr_regs[id(port)]) + "];\n"
- else:
- r += "assign " + gn(port.dat_r) + " = " + gn(data_regs[id(port)]) + ";\n"
- r += "\n"
-
- if memory.init is not None:
- content = ""
- for d in memory.init:
- content += "{:x}\n".format(d)
- memory_filename = add_data_file(gn(memory) + ".init", content)
-
- r += "initial begin\n"
- r += "\t$readmemh(\"" + memory_filename + "\", " + gn(memory) + ");\n"
- r += "end\n\n"
-
- return r
-
-
-class SynthesisDirective(Special):
- def __init__(self, template, **signals):
- Special.__init__(self)
- self.template = template
- self.signals = signals
-
- @staticmethod
- def emit_verilog(directive, ns, add_data_file):
- name_dict = dict((k, ns.get_name(sig)) for k, sig in directive.signals.items())
- formatted = directive.template.format(**name_dict)
- return "// synthesis " + formatted + "\n"
-
-
-class Keep(SynthesisDirective):
- def __init__(self, signal):
- SynthesisDirective.__init__(self, "attribute keep of {s} is true", s=signal)
+++ /dev/null
-import builtins as _builtins
-import collections as _collections
-
-from migen.fhdl import tracer as _tracer
-from migen.util.misc import flat_iteration as _flat_iteration
-
-
-class DUID:
- """Deterministic Unique IDentifier"""
- __next_uid = 0
- def __init__(self):
- self.duid = DUID.__next_uid
- DUID.__next_uid += 1
-
-
-class _Value(DUID):
- """Base class for operands
-
- Instances of `_Value` or its subclasses can be operands to
- arithmetic, comparison, bitwise, and logic operators.
- They can be assigned (:meth:`eq`) or indexed/sliced (using the usual
- Python indexing and slicing notation).
-
- Values created from integers have the minimum bit width to necessary to
- represent the integer.
- """
- def __bool__(self):
- # Special case: Constants and Signals are part of a set or used as
- # dictionary keys, and Python needs to check for equality.
- if isinstance(self, _Operator) and self.op == "==":
- a, b = self.operands
- if isinstance(a, Constant) and isinstance(b, Constant):
- return a.value == b.value
- if isinstance(a, Signal) and isinstance(b, Signal):
- return a is b
- if (isinstance(a, Constant) and isinstance(b, Signal)
- or isinstance(a, Signal) and isinstance(a, Constant)):
- return False
- raise TypeError("Attempted to convert Migen value to boolean")
-
- def __invert__(self):
- return _Operator("~", [self])
- def __neg__(self):
- return _Operator("-", [self])
-
- def __add__(self, other):
- return _Operator("+", [self, other])
- def __radd__(self, other):
- return _Operator("+", [other, self])
- def __sub__(self, other):
- return _Operator("-", [self, other])
- def __rsub__(self, other):
- return _Operator("-", [other, self])
- def __mul__(self, other):
- return _Operator("*", [self, other])
- def __rmul__(self, other):
- return _Operator("*", [other, self])
- def __lshift__(self, other):
- return _Operator("<<<", [self, other])
- def __rlshift__(self, other):
- return _Operator("<<<", [other, self])
- def __rshift__(self, other):
- return _Operator(">>>", [self, other])
- def __rrshift__(self, other):
- return _Operator(">>>", [other, self])
- def __and__(self, other):
- return _Operator("&", [self, other])
- def __rand__(self, other):
- return _Operator("&", [other, self])
- def __xor__(self, other):
- return _Operator("^", [self, other])
- def __rxor__(self, other):
- return _Operator("^", [other, self])
- def __or__(self, other):
- return _Operator("|", [self, other])
- def __ror__(self, other):
- return _Operator("|", [other, self])
-
- def __lt__(self, other):
- return _Operator("<", [self, other])
- def __le__(self, other):
- return _Operator("<=", [self, other])
- def __eq__(self, other):
- return _Operator("==", [self, other])
- def __ne__(self, other):
- return _Operator("!=", [self, other])
- def __gt__(self, other):
- return _Operator(">", [self, other])
- def __ge__(self, other):
- return _Operator(">=", [self, other])
-
- def __len__(self):
- from migen.fhdl.bitcontainer import value_bits_sign
- return value_bits_sign(self)[0]
-
- def __getitem__(self, key):
- n = len(self)
- if isinstance(key, int):
- if key >= n:
- raise IndexError
- if key < 0:
- key += n
- return _Slice(self, key, key+1)
- elif isinstance(key, slice):
- start, stop, step = key.indices(n)
- if step != 1:
- return Cat(self[i] for i in range(start, stop, step))
- return _Slice(self, start, stop)
- else:
- raise TypeError
-
- def eq(self, r):
- """Assignment
-
- Parameters
- ----------
- r : _Value, in
- Value to be assigned.
-
- Returns
- -------
- _Assign
- Assignment statement that can be used in combinatorial or
- synchronous context.
- """
- return _Assign(self, r)
-
- def __hash__(self):
- raise TypeError("unhashable type: '{}'".format(type(self).__name__))
-
-
-def wrap(value):
- """Ensures that the passed object is a Migen value. Booleans and integers
- are automatically wrapped into ``Constant``."""
- if isinstance(value, (bool, int)):
- value = Constant(value)
- if not isinstance(value, _Value):
- raise TypeError("Object is not a Migen value")
- return value
-
-
-class _Operator(_Value):
- def __init__(self, op, operands):
- _Value.__init__(self)
- self.op = op
- self.operands = [wrap(o) for o in operands]
-
-
-def Mux(sel, val1, val0):
- """Multiplex between two values
-
- Parameters
- ----------
- sel : _Value(1), in
- Selector.
- val1 : _Value(N), in
- val0 : _Value(N), in
- Input values.
-
- Returns
- -------
- _Value(N), out
- Output `_Value`. If `sel` is asserted, the Mux returns
- `val1`, else `val0`.
- """
- return _Operator("m", [sel, val1, val0])
-
-
-class _Slice(_Value):
- def __init__(self, value, start, stop):
- _Value.__init__(self)
- if not isinstance(start, int) or not isinstance(stop, int):
- raise TypeError("Slice boundaries must be integers")
- self.value = wrap(value)
- self.start = start
- self.stop = stop
-
-
-class Cat(_Value):
- """Concatenate values
-
- Form a compound `_Value` from several smaller ones by concatenation.
- The first argument occupies the lower bits of the result.
- The return value can be used on either side of an assignment, that
- is, the concatenated value can be used as an argument on the RHS or
- as a target on the LHS. If it is used on the LHS, it must solely
- consist of `Signal` s, slices of `Signal` s, and other concatenations
- meeting these properties. The bit length of the return value is the sum of
- the bit lengths of the arguments::
-
- len(Cat(args)) == sum(len(arg) for arg in args)
-
- Parameters
- ----------
- *args : _Values or iterables of _Values, inout
- `_Value` s to be concatenated.
-
- Returns
- -------
- Cat, inout
- Resulting `_Value` obtained by concatentation.
- """
- def __init__(self, *args):
- _Value.__init__(self)
- self.l = [wrap(v) for v in _flat_iteration(args)]
-
-
-class Replicate(_Value):
- """Replicate a value
-
- An input value is replicated (repeated) several times
- to be used on the RHS of assignments::
-
- len(Replicate(s, n)) == len(s)*n
-
- Parameters
- ----------
- v : _Value, in
- Input value to be replicated.
- n : int
- Number of replications.
-
- Returns
- -------
- Replicate, out
- Replicated value.
- """
- def __init__(self, v, n):
- _Value.__init__(self)
- if not isinstance(n, int) or n < 0:
- raise TypeError("Replication count must be a positive integer")
- self.v = wrap(v)
- self.n = n
-
-
-class Constant(_Value):
- """A constant, HDL-literal integer `_Value`
-
- Parameters
- ----------
- value : int
- bits_sign : int or tuple or None
- Either an integer `bits` or a tuple `(bits, signed)`
- specifying the number of bits in this `Constant` and whether it is
- signed (can represent negative values). `bits_sign` defaults
- to the minimum width and signedness of `value`.
- """
- def __init__(self, value, bits_sign=None):
- from migen.fhdl.bitcontainer import bits_for
-
- _Value.__init__(self)
-
- self.value = int(value)
- if bits_sign is None:
- bits_sign = bits_for(self.value), self.value < 0
- elif isinstance(bits_sign, int):
- bits_sign = bits_sign, self.value < 0
- self.nbits, self.signed = bits_sign
- if not isinstance(self.nbits, int) or self.nbits <= 0:
- raise TypeError("Width must be a strictly positive integer")
-
- def __hash__(self):
- return self.value
-
-
-C = Constant # shorthand
-
-
-class Signal(_Value):
- """A `_Value` that can change
-
- The `Signal` object represents a value that is expected to change
- in the circuit. It does exactly what Verilog's `wire` and
- `reg` and VHDL's `signal` do.
-
- A `Signal` can be indexed to access a subset of its bits. Negative
- indices (`signal[-1]`) and the extended Python slicing notation
- (`signal[start:stop:step]`) are supported.
- The indices 0 and -1 are the least and most significant bits
- respectively.
-
- Parameters
- ----------
- bits_sign : int or tuple
- Either an integer `bits` or a tuple `(bits, signed)`
- specifying the number of bits in this `Signal` and whether it is
- signed (can represent negative values). `signed` defaults to
- `False`.
- name : str or None
- Name hint for this signal. If `None` (default) the name is
- inferred from the variable name this `Signal` is assigned to.
- Name collisions are automatically resolved by prepending
- names of objects that contain this `Signal` and by
- appending integer sequences.
- variable : bool
- Deprecated.
- reset : int
- Reset (synchronous) or default (combinatorial) value.
- When this `Signal` is assigned to in synchronous context and the
- corresponding clock domain is reset, the `Signal` assumes the
- given value. When this `Signal` is unassigned in combinatorial
- context (due to conditional assignments not being taken),
- the `Signal` assumes its `reset` value. Defaults to 0.
- name_override : str or None
- Do not use the inferred name but the given one.
- min : int or None
- max : int or None
- If `bits_sign` is `None`, the signal bit width and signedness are
- determined by the integer range given by `min` (inclusive,
- defaults to 0) and `max` (exclusive, defaults to 2).
- related : Signal or None
- """
- def __init__(self, bits_sign=None, name=None, variable=False, reset=0, name_override=None, min=None, max=None, related=None):
- from migen.fhdl.bitcontainer import bits_for
-
- _Value.__init__(self)
-
- # determine number of bits and signedness
- if bits_sign is None:
- if min is None:
- min = 0
- if max is None:
- max = 2
- max -= 1 # make both bounds inclusive
- assert(min < max)
- self.signed = min < 0 or max < 0
- self.nbits = _builtins.max(bits_for(min, self.signed), bits_for(max, self.signed))
- else:
- assert(min is None and max is None)
- if isinstance(bits_sign, tuple):
- self.nbits, self.signed = bits_sign
- else:
- self.nbits, self.signed = bits_sign, False
- if not isinstance(self.nbits, int) or self.nbits <= 0:
- raise ValueError("Signal width must be a strictly positive integer")
-
- self.variable = variable # deprecated
- self.reset = reset
- self.name_override = name_override
- self.backtrace = _tracer.trace_back(name)
- self.related = related
-
- def __setattr__(self, k, v):
- if k == "reset":
- v = wrap(v)
- _Value.__setattr__(self, k, v)
-
- def __repr__(self):
- return "<Signal " + (self.backtrace[-1][0] or "anonymous") + " at " + hex(id(self)) + ">"
-
- @classmethod
- def like(cls, other, **kwargs):
- """Create Signal based on another.
-
- Parameters
- ----------
- other : _Value
- Object to base this Signal on.
-
- See `migen.fhdl.bitcontainer.value_bits_sign` for details.
- """
- from migen.fhdl.bitcontainer import value_bits_sign
- return cls(bits_sign=value_bits_sign(other), **kwargs)
-
- def __hash__(self):
- return self.duid
-
-
-class ClockSignal(_Value):
- """Clock signal for a given clock domain
-
- `ClockSignal` s for a given clock domain can be retrieved multiple
- times. They all ultimately refer to the same signal.
-
- Parameters
- ----------
- cd : str
- Clock domain to obtain a clock signal for. Defaults to `"sys"`.
- """
- def __init__(self, cd="sys"):
- _Value.__init__(self)
- if not isinstance(cd, str):
- raise TypeError("Argument of ClockSignal must be a string")
- self.cd = cd
-
-
-class ResetSignal(_Value):
- """Reset signal for a given clock domain
-
- `ResetSignal` s for a given clock domain can be retrieved multiple
- times. They all ultimately refer to the same signal.
-
- Parameters
- ----------
- cd : str
- Clock domain to obtain a reset signal for. Defaults to `"sys"`.
- allow_reset_less : bool
- If the clock domain is resetless, return 0 instead of reporting an
- error.
- """
- def __init__(self, cd="sys", allow_reset_less=False):
- _Value.__init__(self)
- if not isinstance(cd, str):
- raise TypeError("Argument of ResetSignal must be a string")
- self.cd = cd
- self.allow_reset_less = allow_reset_less
-
-
-# statements
-
-
-class _Statement:
- pass
-
-
-class _Assign(_Statement):
- def __init__(self, l, r):
- self.l = wrap(l)
- self.r = wrap(r)
-
-
-def _check_statement(s):
- if isinstance(s, _collections.Iterable):
- return all(_check_statement(ss) for ss in s)
- else:
- return isinstance(s, _Statement)
-
-
-class If(_Statement):
- """Conditional execution of statements
-
- Parameters
- ----------
- cond : _Value(1), in
- Condition
- *t : Statements
- Statements to execute if `cond` is asserted.
-
- Examples
- --------
- >>> a = Signal()
- >>> b = Signal()
- >>> c = Signal()
- >>> d = Signal()
- >>> If(a,
- ... b.eq(1)
- ... ).Elif(c,
- ... b.eq(0)
- ... ).Else(
- ... b.eq(d)
- ... )
- """
- def __init__(self, cond, *t):
- if not _check_statement(t):
- raise TypeError("Not all test body objects are Migen statements")
- self.cond = wrap(cond)
- self.t = list(t)
- self.f = []
-
- def Else(self, *f):
- """Add an `else` conditional block
-
- Parameters
- ----------
- *f : Statements
- Statements to execute if all previous conditions fail.
- """
- if not _check_statement(f):
- raise TypeError("Not all test body objects are Migen statements")
- _insert_else(self, list(f))
- return self
-
- def Elif(self, cond, *t):
- """Add an `else if` conditional block
-
- Parameters
- ----------
- cond : _Value(1), in
- Condition
- *t : Statements
- Statements to execute if previous conditions fail and `cond`
- is asserted.
- """
- _insert_else(self, [If(cond, *t)])
- return self
-
-
-def _insert_else(obj, clause):
- o = obj
- while o.f:
- assert(len(o.f) == 1)
- assert(isinstance(o.f[0], If))
- o = o.f[0]
- o.f = clause
-
-
-class Case(_Statement):
- """Case/Switch statement
-
- Parameters
- ----------
- test : _Value, in
- Selector value used to decide which block to execute
- cases : dict
- Dictionary of cases. The keys are numeric constants to compare
- with `test`. The values are statements to be executed the
- corresponding key matches `test`. The dictionary may contain a
- string key `"default"` to mark a fall-through case that is
- executed if no other key matches.
-
- Examples
- --------
- >>> a = Signal()
- >>> b = Signal()
- >>> Case(a, {
- ... 0: b.eq(1),
- ... 1: b.eq(0),
- ... "default": b.eq(0),
- ... })
- """
- def __init__(self, test, cases):
- self.test = wrap(test)
- self.cases = dict()
- for k, v in cases.items():
- if isinstance(k, (bool, int)):
- k = Constant(k)
- if (not isinstance(k, Constant)
- and not (isinstance(k, str) and k == "default")):
- raise TypeError("Case object is not a Migen constant")
- if not isinstance(v, _collections.Iterable):
- v = [v]
- if not _check_statement(v):
- raise TypeError("Not all objects for case {} "
- "are Migen statements".format(k))
- self.cases[k] = v
-
- def makedefault(self, key=None):
- """Mark a key as the default case
-
- Deletes/substitutes any previously existing default case.
-
- Parameters
- ----------
- key : int or None
- Key to use as default case if no other key matches.
- By default, the largest key is the default key.
- """
- if key is None:
- for choice in self.cases.keys():
- if key is None or choice.value > key.value:
- key = choice
- self.cases["default"] = self.cases[key]
- del self.cases[key]
- return self
-
-
-# arrays
-
-
-class _ArrayProxy(_Value):
- def __init__(self, choices, key):
- _Value.__init__(self)
- self.choices = []
- for c in choices:
- if isinstance(c, (bool, int)):
- c = Constant(c)
- self.choices.append(c)
- self.key = key
-
- def __getattr__(self, attr):
- return _ArrayProxy([getattr(choice, attr) for choice in self.choices],
- self.key)
-
- def __getitem__(self, key):
- return _ArrayProxy([choice.__getitem__(key) for choice in self.choices],
- self.key)
-
-
-class Array(list):
- """Addressable multiplexer
-
- An array is created from an iterable of values and indexed using the
- usual Python simple indexing notation (no negative indices or
- slices). It can be indexed by numeric constants, `_Value` s, or
- `Signal` s.
-
- The result of indexing the array is a proxy for the entry at the
- given index that can be used on either RHS or LHS of assignments.
-
- An array can be indexed multiple times.
-
- Multidimensional arrays are supported by packing inner arrays into
- outer arrays.
-
- Parameters
- ----------
- values : iterable of ints, _Values, Signals
- Entries of the array. Each entry can be a numeric constant, a
- `Signal` or a `Record`.
-
- Examples
- --------
- >>> a = Array(range(10))
- >>> b = Signal(max=10)
- >>> c = Signal(max=10)
- >>> b.eq(a[9 - c])
- """
- def __getitem__(self, key):
- if isinstance(key, Constant):
- return list.__getitem__(self, key.value)
- elif isinstance(key, _Value):
- return _ArrayProxy(self, key)
- else:
- return list.__getitem__(self, key)
-
-
-class ClockDomain:
- """Synchronous domain
-
- Parameters
- ----------
- name : str or None
- Domain name. If None (the default) the name is inferred from the
- variable name this `ClockDomain` is assigned to (stripping any
- `"cd_"` prefix).
- reset_less : bool
- The domain does not use a reset signal. Registers within this
- domain are still all initialized to their reset state once, e.g.
- through Verilog `"initial"` statements.
-
- Attributes
- ----------
- clk : Signal, inout
- The clock for this domain. Can be driven or used to drive other
- signals (preferably in combinatorial context).
- rst : Signal or None, inout
- Reset signal for this domain. Can be driven or used to drive.
- """
- def __init__(self, name=None, reset_less=False):
- self.name = _tracer.get_obj_var_name(name)
- if self.name is None:
- raise ValueError("Cannot extract clock domain name from code, need to specify.")
- if self.name.startswith("cd_"):
- self.name = self.name[3:]
- if self.name[0].isdigit():
- raise ValueError("Clock domain name cannot start with a number.")
- self.clk = Signal(name_override=self.name + "_clk")
- if reset_less:
- self.rst = None
- else:
- self.rst = Signal(name_override=self.name + "_rst")
-
- def rename(self, new_name):
- """Rename the clock domain
-
- Parameters
- ----------
- new_name : str
- New name
- """
- self.name = new_name
- self.clk.name_override = new_name + "_clk"
- if self.rst is not None:
- self.rst.name_override = new_name + "_rst"
-
-
-class _ClockDomainList(list):
- def __getitem__(self, key):
- if isinstance(key, str):
- for cd in self:
- if cd.name == key:
- return cd
- raise KeyError(key)
- else:
- return list.__getitem__(self, key)
-
-
-(SPECIAL_INPUT, SPECIAL_OUTPUT, SPECIAL_INOUT) = range(3)
-
-
-class _Fragment:
- def __init__(self, comb=None, sync=None, specials=None, clock_domains=None):
- if comb is None: comb = []
- if sync is None: sync = dict()
- if specials is None: specials = set()
- if clock_domains is None: clock_domains = _ClockDomainList()
-
- self.comb = comb
- self.sync = sync
- self.specials = specials
- self.clock_domains = _ClockDomainList(clock_domains)
-
- def __add__(self, other):
- newsync = _collections.defaultdict(list)
- for k, v in self.sync.items():
- newsync[k] = v[:]
- for k, v in other.sync.items():
- newsync[k].extend(v)
- return _Fragment(self.comb + other.comb, newsync,
- self.specials | other.specials,
- self.clock_domains + other.clock_domains)
-
- def __iadd__(self, other):
- newsync = _collections.defaultdict(list)
- for k, v in self.sync.items():
- newsync[k] = v[:]
- for k, v in other.sync.items():
- newsync[k].extend(v)
- self.comb += other.comb
- self.sync = newsync
- self.specials |= other.specials
- self.clock_domains += other.clock_domains
- return self
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.structure import _Slice, _Assign
-from migen.fhdl.visit import NodeVisitor, NodeTransformer
-from migen.fhdl.bitcontainer import value_bits_sign
-from migen.util.misc import flat_iteration
-
-
-class _SignalLister(NodeVisitor):
- def __init__(self):
- self.output_list = set()
-
- def visit_Signal(self, node):
- self.output_list.add(node)
-
-
-class _TargetLister(NodeVisitor):
- def __init__(self):
- self.output_list = set()
- self.target_context = False
-
- def visit_Signal(self, node):
- if self.target_context:
- self.output_list.add(node)
-
- def visit_Assign(self, node):
- self.target_context = True
- self.visit(node.l)
- self.target_context = False
-
- def visit_ArrayProxy(self, node):
- for choice in node.choices:
- self.visit(choice)
-
-
-class _InputLister(NodeVisitor):
- def __init__(self):
- self.output_list = set()
-
- def visit_Signal(self, node):
- self.output_list.add(node)
-
- def visit_Assign(self, node):
- self.visit(node.r)
-
-
-def list_signals(node):
- lister = _SignalLister()
- lister.visit(node)
- return lister.output_list
-
-
-def list_targets(node):
- lister = _TargetLister()
- lister.visit(node)
- return lister.output_list
-
-
-def list_inputs(node):
- lister = _InputLister()
- lister.visit(node)
- return lister.output_list
-
-
-def _resort_statements(ol):
- return [statement for i, statement in
- sorted(ol, key=lambda x: x[0])]
-
-
-def group_by_targets(sl):
- groups = []
- seen = set()
- for order, stmt in enumerate(flat_iteration(sl)):
- targets = set(list_targets(stmt))
- group = [(order, stmt)]
- disjoint = targets.isdisjoint(seen)
- seen |= targets
- if not disjoint:
- groups, old_groups = [], groups
- for old_targets, old_group in old_groups:
- if targets.isdisjoint(old_targets):
- groups.append((old_targets, old_group))
- else:
- targets |= old_targets
- group += old_group
- groups.append((targets, group))
- return [(targets, _resort_statements(stmts))
- for targets, stmts in groups]
-
-
-def list_special_ios(f, ins, outs, inouts):
- r = set()
- for special in f.specials:
- r |= special.list_ios(ins, outs, inouts)
- return r
-
-
-class _ClockDomainLister(NodeVisitor):
- def __init__(self):
- self.clock_domains = set()
-
- def visit_ClockSignal(self, node):
- self.clock_domains.add(node.cd)
-
- def visit_ResetSignal(self, node):
- self.clock_domains.add(node.cd)
-
- def visit_clock_domains(self, node):
- for clockname, statements in node.items():
- self.clock_domains.add(clockname)
- self.visit(statements)
-
-
-def list_clock_domains_expr(f):
- cdl = _ClockDomainLister()
- cdl.visit(f)
- return cdl.clock_domains
-
-
-def list_clock_domains(f):
- r = list_clock_domains_expr(f)
- for special in f.specials:
- r |= special.list_clock_domains()
- for cd in f.clock_domains:
- r.add(cd.name)
- return r
-
-
-def is_variable(node):
- if isinstance(node, Signal):
- return node.variable
- elif isinstance(node, _Slice):
- return is_variable(node.value)
- elif isinstance(node, Cat):
- arevars = list(map(is_variable, node.l))
- r = arevars[0]
- for x in arevars:
- if x != r:
- raise TypeError
- return r
- else:
- raise TypeError
-
-
-def generate_reset(rst, sl):
- targets = list_targets(sl)
- return [t.eq(t.reset) for t in sorted(targets, key=lambda x: x.duid)]
-
-
-def insert_reset(rst, sl):
- return [If(rst, *generate_reset(rst, sl)).Else(*sl)]
-
-
-def insert_resets(f):
- newsync = dict()
- for k, v in f.sync.items():
- if f.clock_domains[k].rst is not None:
- newsync[k] = insert_reset(ResetSignal(k), v)
- else:
- newsync[k] = v
- f.sync = newsync
-
-
-class _Lowerer(NodeTransformer):
- def __init__(self):
- self.target_context = False
- self.extra_stmts = []
- self.comb = []
-
- def visit_Assign(self, node):
- old_target_context, old_extra_stmts = self.target_context, self.extra_stmts
- self.extra_stmts = []
-
- self.target_context = True
- lhs = self.visit(node.l)
- self.target_context = False
- rhs = self.visit(node.r)
- r = _Assign(lhs, rhs)
- if self.extra_stmts:
- r = [r] + self.extra_stmts
-
- self.target_context, self.extra_stmts = old_target_context, old_extra_stmts
- return r
-
-
-# Basics are FHDL structure elements that back-ends are not required to support
-# but can be expressed in terms of other elements (lowered) before conversion.
-class _BasicLowerer(_Lowerer):
- def __init__(self, clock_domains):
- self.clock_domains = clock_domains
- _Lowerer.__init__(self)
-
- def visit_ArrayProxy(self, node):
- # TODO: rewrite without variables
- array_muxed = Signal(value_bits_sign(node), variable=True)
- if self.target_context:
- k = self.visit(node.key)
- cases = {}
- for n, choice in enumerate(node.choices):
- cases[n] = [self.visit_Assign(_Assign(choice, array_muxed))]
- self.extra_stmts.append(Case(k, cases).makedefault())
- else:
- cases = dict((n, _Assign(array_muxed, self.visit(choice)))
- for n, choice in enumerate(node.choices))
- self.comb.append(Case(self.visit(node.key), cases).makedefault())
- return array_muxed
-
- def visit_ClockSignal(self, node):
- return self.clock_domains[node.cd].clk
-
- def visit_ResetSignal(self, node):
- rst = self.clock_domains[node.cd].rst
- if rst is None:
- if node.allow_reset_less:
- return 0
- else:
- raise ValueError("Attempted to get reset signal of resetless"
- " domain '{}'".format(node.cd))
- else:
- return rst
-
-
-class _ComplexSliceLowerer(_Lowerer):
- def visit_Slice(self, node):
- if not isinstance(node.value, Signal):
- slice_proxy = Signal(value_bits_sign(node.value))
- if self.target_context:
- a = _Assign(node.value, slice_proxy)
- else:
- a = _Assign(slice_proxy, node.value)
- self.comb.append(self.visit_Assign(a))
- node = _Slice(slice_proxy, node.start, node.stop)
- return NodeTransformer.visit_Slice(self, node)
-
-
-def _apply_lowerer(l, f):
- f = l.visit(f)
- f.comb += l.comb
-
- for special in f.specials:
- for obj, attr, direction in special.iter_expressions():
- if direction != SPECIAL_INOUT:
- # inouts are only supported by Migen when connected directly to top-level
- # in this case, they are Signal and never need lowering
- l.comb = []
- l.target_context = direction != SPECIAL_INPUT
- l.extra_stmts = []
- expr = getattr(obj, attr)
- expr = l.visit(expr)
- setattr(obj, attr, expr)
- f.comb += l.comb + l.extra_stmts
-
- return f
-
-
-def lower_basics(f):
- return _apply_lowerer(_BasicLowerer(f.clock_domains), f)
-
-
-def lower_complex_slices(f):
- return _apply_lowerer(_ComplexSliceLowerer(), f)
-
-
-class _ClockDomainRenamer(NodeVisitor):
- def __init__(self, old, new):
- self.old = old
- self.new = new
-
- def visit_ClockSignal(self, node):
- if node.cd == self.old:
- node.cd = self.new
-
- def visit_ResetSignal(self, node):
- if node.cd == self.old:
- node.cd = self.new
-
-
-def rename_clock_domain_expr(f, old, new):
- cdr = _ClockDomainRenamer(old, new)
- cdr.visit(f)
-
-
-def rename_clock_domain(f, old, new):
- rename_clock_domain_expr(f, old, new)
- if new != old:
- if old in f.sync:
- if new in f.sync:
- f.sync[new].extend(f.sync[old])
- else:
- f.sync[new] = f.sync[old]
- del f.sync[old]
- for special in f.specials:
- special.rename_clock_domain(old, new)
- try:
- cd = f.clock_domains[old]
- except KeyError:
- pass
- else:
- cd.rename(new)
+++ /dev/null
-import inspect
-from opcode import opname
-from collections import defaultdict
-
-
-def get_var_name(frame):
- code = frame.f_code
- call_index = frame.f_lasti
- call_opc = opname[code.co_code[call_index]]
- if call_opc != "CALL_FUNCTION" and call_opc != "CALL_FUNCTION_VAR":
- return None
- index = call_index+3
- while True:
- opc = opname[code.co_code[index]]
- if opc == "STORE_NAME" or opc == "STORE_ATTR":
- name_index = int(code.co_code[index+1])
- return code.co_names[name_index]
- elif opc == "STORE_FAST":
- name_index = int(code.co_code[index+1])
- return code.co_varnames[name_index]
- elif opc == "STORE_DEREF":
- name_index = int(code.co_code[index+1])
- return code.co_cellvars[name_index]
- elif opc == "LOAD_GLOBAL" or opc == "LOAD_ATTR" or opc == "LOAD_FAST" or opc == "LOAD_DEREF":
- index += 3
- elif opc == "DUP_TOP":
- index += 1
- elif opc == "BUILD_LIST":
- index += 3
- else:
- return None
-
-
-def remove_underscore(s):
- if len(s) > 2 and s[0] == "_" and s[1] != "_":
- s = s[1:]
- return s
-
-
-def get_obj_var_name(override=None, default=None):
- if override:
- return override
-
- frame = inspect.currentframe().f_back
- # We can be called via derived classes. Go back the stack frames
- # until we reach the first class that does not inherit from us.
- ourclass = frame.f_locals["self"].__class__
- while "self" in frame.f_locals and isinstance(frame.f_locals["self"], ourclass):
- frame = frame.f_back
-
- vn = get_var_name(frame)
- if vn is None:
- vn = default
- else:
- vn = remove_underscore(vn)
- return vn
-
-name_to_idx = defaultdict(int)
-classname_to_objs = dict()
-
-
-def index_id(l, obj):
- for n, e in enumerate(l):
- if id(e) == id(obj):
- return n
- raise ValueError
-
-
-def trace_back(varname=None):
- l = []
- frame = inspect.currentframe().f_back.f_back
- while frame is not None:
- if varname is None:
- varname = get_var_name(frame)
- if varname is not None:
- varname = remove_underscore(varname)
- l.insert(0, (varname, name_to_idx[varname]))
- name_to_idx[varname] += 1
-
- try:
- obj = frame.f_locals["self"]
- except KeyError:
- obj = None
- if hasattr(obj, "__del__"):
- obj = None
-
- if obj is None:
- if varname is not None:
- coname = frame.f_code.co_name
- if coname == "<module>":
- modules = frame.f_globals["__name__"]
- modules = modules.split(".")
- coname = modules[len(modules)-1]
- coname = remove_underscore(coname)
- l.insert(0, (coname, name_to_idx[coname]))
- name_to_idx[coname] += 1
- else:
- classname = obj.__class__.__name__.lower()
- try:
- objs = classname_to_objs[classname]
- except KeyError:
- classname_to_objs[classname] = [obj]
- idx = 0
- else:
- try:
- idx = index_id(objs, obj)
- except ValueError:
- idx = len(objs)
- objs.append(obj)
- classname = remove_underscore(classname)
- l.insert(0, (classname, idx))
-
- varname = None
- frame = frame.f_back
- return l
+++ /dev/null
-from functools import partial
-from operator import itemgetter
-import collections
-
-from migen.fhdl.structure import *
-from migen.fhdl.structure import _Operator, _Slice, _Assign, _Fragment
-from migen.fhdl.tools import *
-from migen.fhdl.bitcontainer import bits_for
-from migen.fhdl.namer import build_namespace
-from migen.fhdl.conv_output import ConvOutput
-
-
-_reserved_keywords = {
- "always", "and", "assign", "automatic", "begin", "buf", "bufif0", "bufif1",
- "case", "casex", "casez", "cell", "cmos", "config", "deassign", "default",
- "defparam", "design", "disable", "edge", "else", "end", "endcase",
- "endconfig", "endfunction", "endgenerate", "endmodule", "endprimitive",
- "endspecify", "endtable", "endtask", "event", "for", "force", "forever",
- "fork", "function", "generate", "genvar", "highz0", "highz1", "if",
- "ifnone", "incdir", "include", "initial", "inout", "input",
- "instance", "integer", "join", "large", "liblist", "library", "localparam",
- "macromodule", "medium", "module", "nand", "negedge", "nmos", "nor",
- "noshowcancelled", "not", "notif0", "notif1", "or", "output", "parameter",
- "pmos", "posedge", "primitive", "pull0", "pull1" "pulldown",
- "pullup", "pulsestyle_onevent", "pulsestyle_ondetect", "remos", "real",
- "realtime", "reg", "release", "repeat", "rnmos", "rpmos", "rtran",
- "rtranif0", "rtranif1", "scalared", "showcancelled", "signed", "small",
- "specify", "specparam", "strong0", "strong1", "supply0", "supply1",
- "table", "task", "time", "tran", "tranif0", "tranif1", "tri", "tri0",
- "tri1", "triand", "trior", "trireg", "unsigned", "use", "vectored", "wait",
- "wand", "weak0", "weak1", "while", "wire", "wor","xnor", "xor"
-}
-
-
-def _printsig(ns, s):
- if s.signed:
- n = "signed "
- else:
- n = ""
- if len(s) > 1:
- n += "[" + str(len(s)-1) + ":0] "
- n += ns.get_name(s)
- return n
-
-
-def _printconstant(node):
- if node.signed:
- return (str(node.nbits) + "'sd" + str(2**node.nbits + node.value),
- True)
- else:
- return str(node.nbits) + "'d" + str(node.value), False
-
-
-def _printexpr(ns, node):
- if isinstance(node, Constant):
- return _printconstant(node)
- elif isinstance(node, Signal):
- return ns.get_name(node), node.signed
- elif isinstance(node, _Operator):
- arity = len(node.operands)
- r1, s1 = _printexpr(ns, node.operands[0])
- if arity == 1:
- if node.op == "-":
- if s1:
- r = node.op + r1
- else:
- r = "-$signed({1'd0, " + r1 + "})"
- s = True
- else:
- r = node.op + r1
- s = s1
- elif arity == 2:
- r2, s2 = _printexpr(ns, node.operands[1])
- if node.op not in ["<<<", ">>>"]:
- if s2 and not s1:
- r1 = "$signed({1'd0, " + r1 + "})"
- if s1 and not s2:
- r2 = "$signed({1'd0, " + r2 + "})"
- r = r1 + " " + node.op + " " + r2
- s = s1 or s2
- elif arity == 3:
- assert node.op == "m"
- r2, s2 = _printexpr(ns, node.operands[1])
- r3, s3 = _printexpr(ns, node.operands[2])
- if s2 and not s3:
- r3 = "$signed({1'd0, " + r3 + "})"
- if s3 and not s2:
- r2 = "$signed({1'd0, " + r2 + "})"
- r = r1 + " ? " + r2 + " : " + r3
- s = s2 or s3
- else:
- raise TypeError
- return "(" + r + ")", s
- elif isinstance(node, _Slice):
- # Verilog does not like us slicing non-array signals...
- if isinstance(node.value, Signal) \
- and len(node.value) == 1 \
- and node.start == 0 and node.stop == 1:
- return _printexpr(ns, node.value)
-
- if node.start + 1 == node.stop:
- sr = "[" + str(node.start) + "]"
- else:
- sr = "[" + str(node.stop-1) + ":" + str(node.start) + "]"
- r, s = _printexpr(ns, node.value)
- return r + sr, s
- elif isinstance(node, Cat):
- l = [_printexpr(ns, v)[0] for v in reversed(node.l)]
- return "{" + ", ".join(l) + "}", False
- elif isinstance(node, Replicate):
- return "{" + str(node.n) + "{" + _printexpr(ns, node.v)[0] + "}}", False
- else:
- raise TypeError("Expression of unrecognized type: '{}'".format(type(node).__name__))
-
-
-(_AT_BLOCKING, _AT_NONBLOCKING, _AT_SIGNAL) = range(3)
-
-
-def _printnode(ns, at, level, node):
- if node is None:
- return ""
- elif isinstance(node, _Assign):
- if at == _AT_BLOCKING:
- assignment = " = "
- elif at == _AT_NONBLOCKING:
- assignment = " <= "
- elif is_variable(node.l):
- assignment = " = "
- else:
- assignment = " <= "
- return "\t"*level + _printexpr(ns, node.l)[0] + assignment + _printexpr(ns, node.r)[0] + ";\n"
- elif isinstance(node, collections.Iterable):
- return "".join(list(map(partial(_printnode, ns, at, level), node)))
- elif isinstance(node, If):
- r = "\t"*level + "if (" + _printexpr(ns, node.cond)[0] + ") begin\n"
- r += _printnode(ns, at, level + 1, node.t)
- if node.f:
- r += "\t"*level + "end else begin\n"
- r += _printnode(ns, at, level + 1, node.f)
- r += "\t"*level + "end\n"
- return r
- elif isinstance(node, Case):
- if node.cases:
- r = "\t"*level + "case (" + _printexpr(ns, node.test)[0] + ")\n"
- css = [(k, v) for k, v in node.cases.items() if isinstance(k, Constant)]
- css = sorted(css, key=lambda x: x[0].value)
- for choice, statements in css:
- r += "\t"*(level + 1) + _printexpr(ns, choice)[0] + ": begin\n"
- r += _printnode(ns, at, level + 2, statements)
- r += "\t"*(level + 1) + "end\n"
- if "default" in node.cases:
- r += "\t"*(level + 1) + "default: begin\n"
- r += _printnode(ns, at, level + 2, node.cases["default"])
- r += "\t"*(level + 1) + "end\n"
- r += "\t"*level + "endcase\n"
- return r
- else:
- return ""
- else:
- raise TypeError("Node of unrecognized type: "+str(type(node)))
-
-
-def _list_comb_wires(f):
- r = set()
- groups = group_by_targets(f.comb)
- for g in groups:
- if len(g[1]) == 1 and isinstance(g[1][0], _Assign):
- r |= g[0]
- return r
-
-
-def _printheader(f, ios, name, ns,
- reg_initialization):
- sigs = list_signals(f) | list_special_ios(f, True, True, True)
- special_outs = list_special_ios(f, False, True, True)
- inouts = list_special_ios(f, False, False, True)
- targets = list_targets(f) | special_outs
- wires = _list_comb_wires(f) | special_outs
- r = "module " + name + "(\n"
- firstp = True
- for sig in sorted(ios, key=lambda x: x.duid):
- if not firstp:
- r += ",\n"
- firstp = False
- if sig in inouts:
- r += "\tinout " + _printsig(ns, sig)
- elif sig in targets:
- if sig in wires:
- r += "\toutput " + _printsig(ns, sig)
- else:
- r += "\toutput reg " + _printsig(ns, sig)
- else:
- r += "\tinput " + _printsig(ns, sig)
- r += "\n);\n\n"
- for sig in sorted(sigs - ios, key=lambda x: x.duid):
- if sig in wires:
- r += "wire " + _printsig(ns, sig) + ";\n"
- else:
- if reg_initialization:
- r += "reg " + _printsig(ns, sig) + " = " + _printexpr(ns, sig.reset)[0] + ";\n"
- else:
- r += "reg " + _printsig(ns, sig) + ";\n"
- r += "\n"
- return r
-
-
-def _printcomb(f, ns,
- display_run,
- dummy_signal,
- blocking_assign):
- r = ""
- if f.comb:
- if dummy_signal:
- # Generate a dummy event to get the simulator
- # to run the combinatorial process once at the beginning.
- syn_off = "// synthesis translate_off\n"
- syn_on = "// synthesis translate_on\n"
- dummy_s = Signal(name_override="dummy_s")
- r += syn_off
- r += "reg " + _printsig(ns, dummy_s) + ";\n"
- r += "initial " + ns.get_name(dummy_s) + " <= 1'd0;\n"
- r += syn_on
-
- groups = group_by_targets(f.comb)
-
- for n, g in enumerate(groups):
- if len(g[1]) == 1 and isinstance(g[1][0], _Assign):
- r += "assign " + _printnode(ns, _AT_BLOCKING, 0, g[1][0])
- else:
- if dummy_signal:
- dummy_d = Signal(name_override="dummy_d")
- r += "\n" + syn_off
- r += "reg " + _printsig(ns, dummy_d) + ";\n"
- r += syn_on
-
- r += "always @(*) begin\n"
- if display_run:
- r += "\t$display(\"Running comb block #" + str(n) + "\");\n"
- if blocking_assign:
- for t in g[0]:
- r += "\t" + ns.get_name(t) + " = " + _printexpr(ns, t.reset)[0] + ";\n"
- r += _printnode(ns, _AT_BLOCKING, 1, g[1])
- else:
- for t in g[0]:
- r += "\t" + ns.get_name(t) + " <= " + _printexpr(ns, t.reset)[0] + ";\n"
- r += _printnode(ns, _AT_NONBLOCKING, 1, g[1])
- if dummy_signal:
- r += syn_off
- r += "\t" + ns.get_name(dummy_d) + " <= " + ns.get_name(dummy_s) + ";\n"
- r += syn_on
- r += "end\n"
- r += "\n"
- return r
-
-
-def _printsync(f, ns):
- r = ""
- for k, v in sorted(f.sync.items(), key=itemgetter(0)):
- r += "always @(posedge " + ns.get_name(f.clock_domains[k].clk) + ") begin\n"
- r += _printnode(ns, _AT_SIGNAL, 1, v)
- r += "end\n\n"
- return r
-
-
-def _call_special_classmethod(overrides, obj, method, *args, **kwargs):
- cl = obj.__class__
- if cl in overrides:
- cl = overrides[cl]
- if hasattr(cl, method):
- return getattr(cl, method)(obj, *args, **kwargs)
- else:
- return None
-
-
-def _lower_specials_step(overrides, specials):
- f = _Fragment()
- lowered_specials = set()
- for special in sorted(specials, key=lambda x: x.duid):
- impl = _call_special_classmethod(overrides, special, "lower")
- if impl is not None:
- f += impl.get_fragment()
- lowered_specials.add(special)
- return f, lowered_specials
-
-
-def _can_lower(overrides, specials):
- for special in specials:
- cl = special.__class__
- if cl in overrides:
- cl = overrides[cl]
- if hasattr(cl, "lower"):
- return True
- return False
-
-
-def _lower_specials(overrides, specials):
- f, lowered_specials = _lower_specials_step(overrides, specials)
- while _can_lower(overrides, f.specials):
- f2, lowered_specials2 = _lower_specials_step(overrides, f.specials)
- f += f2
- lowered_specials |= lowered_specials2
- f.specials -= lowered_specials2
- return f, lowered_specials
-
-
-def _printspecials(overrides, specials, ns, add_data_file):
- r = ""
- for special in sorted(specials, key=lambda x: x.duid):
- pr = _call_special_classmethod(overrides, special, "emit_verilog", ns, add_data_file)
- if pr is None:
- raise NotImplementedError("Special " + str(special) + " failed to implement emit_verilog")
- r += pr
- return r
-
-
-def convert(f, ios=None, name="top",
- special_overrides=dict(),
- create_clock_domains=True,
- display_run=False, asic_syntax=False):
- r = ConvOutput()
- if not isinstance(f, _Fragment):
- f = f.get_fragment()
- if ios is None:
- ios = set()
-
- for cd_name in sorted(list_clock_domains(f)):
- try:
- f.clock_domains[cd_name]
- except KeyError:
- if create_clock_domains:
- cd = ClockDomain(cd_name)
- f.clock_domains.append(cd)
- ios |= {cd.clk, cd.rst}
- else:
- raise KeyError("Unresolved clock domain: '"+cd_name+"'")
-
- f = lower_complex_slices(f)
- insert_resets(f)
- f = lower_basics(f)
- fs, lowered_specials = _lower_specials(special_overrides, f.specials)
- f += lower_basics(fs)
-
- ns = build_namespace(list_signals(f) \
- | list_special_ios(f, True, True, True) \
- | ios, _reserved_keywords)
- ns.clock_domains = f.clock_domains
- r.ns = ns
-
- src = "/* Machine-generated using Migen */\n"
- src += _printheader(f, ios, name, ns,
- reg_initialization=not asic_syntax)
- src += _printcomb(f, ns,
- display_run=display_run,
- dummy_signal=not asic_syntax,
- blocking_assign=asic_syntax)
- src += _printsync(f, ns)
- src += _printspecials(special_overrides, f.specials - lowered_specials, ns, r.add_data_file)
- src += "endmodule\n"
- r.set_main_source(src)
-
- return r
+++ /dev/null
-from copy import copy
-
-from migen.fhdl.structure import *
-from migen.fhdl.structure import (_Operator, _Slice, _Assign, _ArrayProxy,
- _Fragment)
-
-
-class NodeVisitor:
- def visit(self, node):
- if isinstance(node, Constant):
- self.visit_Constant(node)
- elif isinstance(node, Signal):
- self.visit_Signal(node)
- elif isinstance(node, ClockSignal):
- self.visit_ClockSignal(node)
- elif isinstance(node, ResetSignal):
- self.visit_ResetSignal(node)
- elif isinstance(node, _Operator):
- self.visit_Operator(node)
- elif isinstance(node, _Slice):
- self.visit_Slice(node)
- elif isinstance(node, Cat):
- self.visit_Cat(node)
- elif isinstance(node, Replicate):
- self.visit_Replicate(node)
- elif isinstance(node, _Assign):
- self.visit_Assign(node)
- elif isinstance(node, If):
- self.visit_If(node)
- elif isinstance(node, Case):
- self.visit_Case(node)
- elif isinstance(node, _Fragment):
- self.visit_Fragment(node)
- elif isinstance(node, (list, tuple)):
- self.visit_statements(node)
- elif isinstance(node, dict):
- self.visit_clock_domains(node)
- elif isinstance(node, _ArrayProxy):
- self.visit_ArrayProxy(node)
- elif node is not None:
- self.visit_unknown(node)
-
- def visit_Constant(self, node):
- pass
-
- def visit_Signal(self, node):
- pass
-
- def visit_ClockSignal(self, node):
- pass
-
- def visit_ResetSignal(self, node):
- pass
-
- def visit_Operator(self, node):
- for o in node.operands:
- self.visit(o)
-
- def visit_Slice(self, node):
- self.visit(node.value)
-
- def visit_Cat(self, node):
- for e in node.l:
- self.visit(e)
-
- def visit_Replicate(self, node):
- self.visit(node.v)
-
- def visit_Assign(self, node):
- self.visit(node.l)
- self.visit(node.r)
-
- def visit_If(self, node):
- self.visit(node.cond)
- self.visit(node.t)
- self.visit(node.f)
-
- def visit_Case(self, node):
- self.visit(node.test)
- for v, statements in node.cases.items():
- self.visit(statements)
-
- def visit_Fragment(self, node):
- self.visit(node.comb)
- self.visit(node.sync)
-
- def visit_statements(self, node):
- for statement in node:
- self.visit(statement)
-
- def visit_clock_domains(self, node):
- for clockname, statements in node.items():
- self.visit(statements)
-
- def visit_ArrayProxy(self, node):
- for choice in node.choices:
- self.visit(choice)
- self.visit(node.key)
-
- def visit_unknown(self, node):
- pass
-
-
-# Default methods always copy the node, except for:
-# - Signals, ClockSignals and ResetSignals
-# - Unknown objects
-# - All fragment fields except comb and sync
-# In those cases, the original node is returned unchanged.
-class NodeTransformer:
- def visit(self, node):
- if isinstance(node, Constant):
- return self.visit_Constant(node)
- elif isinstance(node, Signal):
- return self.visit_Signal(node)
- elif isinstance(node, ClockSignal):
- return self.visit_ClockSignal(node)
- elif isinstance(node, ResetSignal):
- return self.visit_ResetSignal(node)
- elif isinstance(node, _Operator):
- return self.visit_Operator(node)
- elif isinstance(node, _Slice):
- return self.visit_Slice(node)
- elif isinstance(node, Cat):
- return self.visit_Cat(node)
- elif isinstance(node, Replicate):
- return self.visit_Replicate(node)
- elif isinstance(node, _Assign):
- return self.visit_Assign(node)
- elif isinstance(node, If):
- return self.visit_If(node)
- elif isinstance(node, Case):
- return self.visit_Case(node)
- elif isinstance(node, _Fragment):
- return self.visit_Fragment(node)
- elif isinstance(node, (list, tuple)):
- return self.visit_statements(node)
- elif isinstance(node, dict):
- return self.visit_clock_domains(node)
- elif isinstance(node, _ArrayProxy):
- return self.visit_ArrayProxy(node)
- elif node is not None:
- return self.visit_unknown(node)
- else:
- return None
-
- def visit_Constant(self, node):
- return node
-
- def visit_Signal(self, node):
- return node
-
- def visit_ClockSignal(self, node):
- return node
-
- def visit_ResetSignal(self, node):
- return node
-
- def visit_Operator(self, node):
- return _Operator(node.op, [self.visit(o) for o in node.operands])
-
- def visit_Slice(self, node):
- return _Slice(self.visit(node.value), node.start, node.stop)
-
- def visit_Cat(self, node):
- return Cat(*[self.visit(e) for e in node.l])
-
- def visit_Replicate(self, node):
- return Replicate(self.visit(node.v), node.n)
-
- def visit_Assign(self, node):
- return _Assign(self.visit(node.l), self.visit(node.r))
-
- def visit_If(self, node):
- r = If(self.visit(node.cond))
- r.t = self.visit(node.t)
- r.f = self.visit(node.f)
- return r
-
- def visit_Case(self, node):
- cases = dict((v, self.visit(statements)) for v, statements in node.cases.items())
- r = Case(self.visit(node.test), cases)
- return r
-
- def visit_Fragment(self, node):
- r = copy(node)
- r.comb = self.visit(node.comb)
- r.sync = self.visit(node.sync)
- return r
-
- # NOTE: this will always return a list, even if node is a tuple
- def visit_statements(self, node):
- return [self.visit(statement) for statement in node]
-
- def visit_clock_domains(self, node):
- return dict((clockname, self.visit(statements)) for clockname, statements in node.items())
-
- def visit_ArrayProxy(self, node):
- return _ArrayProxy([self.visit(choice) for choice in node.choices],
- self.visit(node.key))
-
- def visit_unknown(self, node):
- return node
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-from migen.fhdl.specials import Special
-from migen.fhdl.bitcontainer import value_bits_sign
-from migen.genlib.misc import WaitTimer
-
-
-class NoRetiming(Special):
- def __init__(self, reg):
- Special.__init__(self)
- self.reg = reg
-
- # do nothing
- @staticmethod
- def lower(dr):
- return Module()
-
-
-class MultiRegImpl(Module):
- def __init__(self, i, o, odomain, n):
- self.i = i
- self.o = o
- self.odomain = odomain
-
- w, signed = value_bits_sign(self.i)
- self.regs = [Signal((w, signed)) for i in range(n)]
-
- ###
-
- src = self.i
- for reg in self.regs:
- sd = getattr(self.sync, self.odomain)
- sd += reg.eq(src)
- src = reg
- self.comb += self.o.eq(src)
- self.specials += [NoRetiming(reg) for reg in self.regs]
-
-
-class MultiReg(Special):
- def __init__(self, i, o, odomain="sys", n=2):
- Special.__init__(self)
- self.i = wrap(i)
- self.o = wrap(o)
- self.odomain = odomain
- self.n = n
-
- def iter_expressions(self):
- yield self, "i", SPECIAL_INPUT
- yield self, "o", SPECIAL_OUTPUT
-
- def rename_clock_domain(self, old, new):
- Special.rename_clock_domain(self, old, new)
- if self.odomain == old:
- self.odomain = new
-
- def list_clock_domains(self):
- r = Special.list_clock_domains(self)
- r.add(self.odomain)
- return r
-
- @staticmethod
- def lower(dr):
- return MultiRegImpl(dr.i, dr.o, dr.odomain, dr.n)
-
-
-class PulseSynchronizer(Module):
- def __init__(self, idomain, odomain):
- self.i = Signal()
- self.o = Signal()
-
- ###
-
- toggle_i = Signal()
- toggle_o = Signal()
- toggle_o_r = Signal()
-
- sync_i = getattr(self.sync, idomain)
- sync_o = getattr(self.sync, odomain)
-
- sync_i += If(self.i, toggle_i.eq(~toggle_i))
- self.specials += MultiReg(toggle_i, toggle_o, odomain)
- sync_o += toggle_o_r.eq(toggle_o)
- self.comb += self.o.eq(toggle_o ^ toggle_o_r)
-
-
-class BusSynchronizer(Module):
- """Clock domain transfer of several bits at once.
-
- Ensures that all the bits form a single word that was present
- synchronously in the input clock domain (unlike direct use of
- ``MultiReg``)."""
- def __init__(self, width, idomain, odomain, timeout=128):
- self.i = Signal(width)
- self.o = Signal(width)
-
- if width == 1:
- self.specials += MultiReg(self.i, self.o, odomain)
- else:
- sync_i = getattr(self.sync, idomain)
- sync_o = getattr(self.sync, odomain)
-
- starter = Signal(reset=1)
- sync_i += starter.eq(0)
- self.submodules._ping = PulseSynchronizer(idomain, odomain)
- self.submodules._pong = PulseSynchronizer(odomain, idomain)
- self.submodules._timeout = WaitTimer(timeout)
- self.comb += [
- self._timeout.wait.eq(~self._ping.i),
- self._ping.i.eq(starter | self._pong.o | self._timeout.done),
- self._pong.i.eq(self._ping.i)
- ]
-
- ibuffer = Signal(width)
- obuffer = Signal(width)
- sync_i += If(self._pong.o, ibuffer.eq(self.i))
- self.specials += MultiReg(ibuffer, obuffer, odomain)
- sync_o += If(self._ping.o, self.o.eq(obuffer))
-
-
-class GrayCounter(Module):
- def __init__(self, width):
- self.ce = Signal()
- self.q = Signal(width)
- self.q_next = Signal(width)
- self.q_binary = Signal(width)
- self.q_next_binary = Signal(width)
-
- ###
-
- self.comb += [
- If(self.ce,
- self.q_next_binary.eq(self.q_binary + 1)
- ).Else(
- self.q_next_binary.eq(self.q_binary)
- ),
- self.q_next.eq(self.q_next_binary ^ self.q_next_binary[1:])
- ]
- self.sync += [
- self.q_binary.eq(self.q_next_binary),
- self.q.eq(self.q_next)
- ]
+++ /dev/null
-"""
-Encoders and decoders between binary and one-hot representation
-"""
-
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-
-
-class Encoder(Module):
- """Encode one-hot to binary
-
- If `n` is low, the `o` th bit in `i` is asserted, else none or
- multiple bits are asserted.
-
- Parameters
- ----------
- width : int
- Bit width of the input
-
- Attributes
- ----------
- i : Signal(width), in
- One-hot input
- o : Signal(max=width), out
- Encoded binary
- n : Signal(1), out
- Invalid, either none or multiple input bits are asserted
- """
- def __init__(self, width):
- self.i = Signal(width) # one-hot
- self.o = Signal(max=max(2, width)) # binary
- self.n = Signal() # invalid: none or multiple
- act = dict((1<<j, self.o.eq(j)) for j in range(width))
- act["default"] = self.n.eq(1)
- self.comb += Case(self.i, act)
-
-
-class PriorityEncoder(Module):
- """Priority encode requests to binary
-
- If `n` is low, the `o` th bit in `i` is asserted and the bits below
- `o` are unasserted, else `o == 0`. The LSB has priority.
-
- Parameters
- ----------
- width : int
- Bit width of the input
-
- Attributes
- ----------
- i : Signal(width), in
- Input requests
- o : Signal(max=width), out
- Encoded binary
- n : Signal(1), out
- Invalid, no input bits are asserted
- """
- def __init__(self, width):
- self.i = Signal(width) # one-hot, lsb has priority
- self.o = Signal(max=max(2, width)) # binary
- self.n = Signal() # none
- for j in range(width)[::-1]: # last has priority
- self.comb += If(self.i[j], self.o.eq(j))
- self.comb += self.n.eq(self.i == 0)
-
-
-class Decoder(Module):
- """Decode binary to one-hot
-
- If `n` is low, the `i` th bit in `o` is asserted, the others are
- not, else `o == 0`.
-
- Parameters
- ----------
- width : int
- Bit width of the output
-
- Attributes
- ----------
- i : Signal(max=width), in
- Input binary
- o : Signal(width), out
- Decoded one-hot
- n : Signal(1), in
- Invalid, no output bits are to be asserted
- """
-
- def __init__(self, width):
- self.i = Signal(max=max(2, width)) # binary
- self.n = Signal() # none/invalid
- self.o = Signal(width) # one-hot
- act = dict((j, self.o.eq(1<<j)) for j in range(width))
- self.comb += Case(self.i, act)
- self.comb += If(self.n, self.o.eq(0))
-
-
-class PriorityDecoder(Decoder):
- pass # same
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-
-
-class Divider(Module):
- def __init__(self, w):
- self.start_i = Signal()
- self.dividend_i = Signal(w)
- self.divisor_i = Signal(w)
- self.ready_o = Signal()
- self.quotient_o = Signal(w)
- self.remainder_o = Signal(w)
-
- ###
-
- qr = Signal(2*w)
- counter = Signal(max=w+1)
- divisor_r = Signal(w)
- diff = Signal(w+1)
-
- self.comb += [
- self.quotient_o.eq(qr[:w]),
- self.remainder_o.eq(qr[w:]),
- self.ready_o.eq(counter == 0),
- diff.eq(qr[w-1:] - divisor_r)
- ]
- self.sync += [
- If(self.start_i,
- counter.eq(w),
- qr.eq(self.dividend_i),
- divisor_r.eq(self.divisor_i)
- ).Elif(~self.ready_o,
- If(diff[w],
- qr.eq(Cat(0, qr[:2*w-1]))
- ).Else(
- qr.eq(Cat(1, qr[:w-1], diff[:w]))
- ),
- counter.eq(counter - 1)
- )
- ]
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-from migen.fhdl.specials import Memory
-from migen.fhdl.bitcontainer import log2_int
-from migen.fhdl.decorators import ClockDomainsRenamer
-from migen.genlib.cdc import NoRetiming, MultiReg, GrayCounter
-
-
-def _inc(signal, modulo):
- if modulo == 2**len(signal):
- return signal.eq(signal + 1)
- else:
- return If(signal == (modulo - 1),
- signal.eq(0)
- ).Else(
- signal.eq(signal + 1)
- )
-
-
-class _FIFOInterface:
- """
- Data written to the input interface (`din`, `we`, `writable`) is
- buffered and can be read at the output interface (`dout`, `re`,
- `readable`). The data entry written first to the input
- also appears first on the output.
-
- Parameters
- ----------
- width : int
- Bit width for the data.
- depth : int
- Depth of the FIFO.
-
- Attributes
- ----------
- din : in, width
- Input data
- writable : out
- There is space in the FIFO and `we` can be asserted to load new data.
- we : in
- Write enable signal to latch `din` into the FIFO. Does nothing if
- `writable` is not asserted.
- dout : out, width
- Output data. Only valid if `readable` is asserted.
- readable : out
- Output data `dout` valid, FIFO not empty.
- re : in
- Acknowledge `dout`. If asserted, the next entry will be
- available on the next cycle (if `readable` is high then).
- """
- def __init__(self, width, depth):
- self.we = Signal()
- self.writable = Signal() # not full
- self.re = Signal()
- self.readable = Signal() # not empty
-
- self.din = Signal(width)
- self.dout = Signal(width)
- self.width = width
-
-
-class SyncFIFO(Module, _FIFOInterface):
- """Synchronous FIFO (first in, first out)
-
- Read and write interfaces are accessed from the same clock domain.
- If different clock domains are needed, use :class:`AsyncFIFO`.
-
- {interface}
- level : out
- Number of unread entries.
- replace : in
- Replaces the last entry written into the FIFO with `din`. Does nothing
- if that entry has already been read (i.e. the FIFO is empty).
- Assert in conjunction with `we`.
- """
- __doc__ = __doc__.format(interface=_FIFOInterface.__doc__)
-
- def __init__(self, width, depth, fwft=True):
- _FIFOInterface.__init__(self, width, depth)
-
- self.level = Signal(max=depth+1)
- self.replace = Signal()
-
- ###
-
- produce = Signal(max=depth)
- consume = Signal(max=depth)
- storage = Memory(self.width, depth)
- self.specials += storage
-
- wrport = storage.get_port(write_capable=True)
- self.specials += wrport
- self.comb += [
- If(self.replace,
- wrport.adr.eq(produce-1)
- ).Else(
- wrport.adr.eq(produce)
- ),
- wrport.dat_w.eq(self.din),
- wrport.we.eq(self.we & (self.writable | self.replace))
- ]
- self.sync += If(self.we & self.writable & ~self.replace,
- _inc(produce, depth))
-
- do_read = Signal()
- self.comb += do_read.eq(self.readable & self.re)
-
- rdport = storage.get_port(async_read=fwft, has_re=not fwft)
- self.specials += rdport
- self.comb += [
- rdport.adr.eq(consume),
- self.dout.eq(rdport.dat_r)
- ]
- if not fwft:
- self.comb += rdport.re.eq(do_read)
- self.sync += If(do_read, _inc(consume, depth))
-
- self.sync += \
- If(self.we & self.writable & ~self.replace,
- If(~do_read, self.level.eq(self.level + 1))
- ).Elif(do_read,
- self.level.eq(self.level - 1)
- )
- self.comb += [
- self.writable.eq(self.level != depth),
- self.readable.eq(self.level != 0)
- ]
-
-
-class SyncFIFOBuffered(Module, _FIFOInterface):
- def __init__(self, width, depth):
- _FIFOInterface.__init__(self, width, depth)
- self.submodules.fifo = fifo = SyncFIFO(width, depth, False)
-
- self.writable = fifo.writable
- self.din = fifo.din
- self.we = fifo.we
- self.dout = fifo.dout
- self.level = Signal(max=depth+2)
-
- ###
-
- self.comb += fifo.re.eq(fifo.readable & (~self.readable | self.re))
- self.sync += \
- If(fifo.re,
- self.readable.eq(1),
- ).Elif(self.re,
- self.readable.eq(0),
- )
- self.comb += self.level.eq(fifo.level + self.readable)
-
-
-class AsyncFIFO(Module, _FIFOInterface):
- """Asynchronous FIFO (first in, first out)
-
- Read and write interfaces are accessed from different clock domains,
- named `read` and `write`. Use `ClockDomainsRenamer` to rename to
- other names.
-
- {interface}
- """
- __doc__ = __doc__.format(interface=_FIFOInterface.__doc__)
-
- def __init__(self, width, depth):
- _FIFOInterface.__init__(self, width, depth)
-
- ###
-
- depth_bits = log2_int(depth, True)
-
- produce = ClockDomainsRenamer("write")(GrayCounter(depth_bits+1))
- consume = ClockDomainsRenamer("read")(GrayCounter(depth_bits+1))
- self.submodules += produce, consume
- self.comb += [
- produce.ce.eq(self.writable & self.we),
- consume.ce.eq(self.readable & self.re)
- ]
-
- produce_rdomain = Signal(depth_bits+1)
- self.specials += [
- NoRetiming(produce.q),
- MultiReg(produce.q, produce_rdomain, "read")
- ]
- consume_wdomain = Signal(depth_bits+1)
- self.specials += [
- NoRetiming(consume.q),
- MultiReg(consume.q, consume_wdomain, "write")
- ]
- if depth_bits == 1:
- self.comb += self.writable.eq((produce.q[-1] == consume_wdomain[-1])
- | (produce.q[-2] == consume_wdomain[-2]))
- else:
- self.comb += [
- self.writable.eq((produce.q[-1] == consume_wdomain[-1])
- | (produce.q[-2] == consume_wdomain[-2])
- | (produce.q[:-2] != consume_wdomain[:-2]))
- ]
- self.comb += self.readable.eq(consume.q != produce_rdomain)
-
- storage = Memory(self.width, depth)
- self.specials += storage
- wrport = storage.get_port(write_capable=True, clock_domain="write")
- self.specials += wrport
- self.comb += [
- wrport.adr.eq(produce.q_binary[:-1]),
- wrport.dat_w.eq(self.din),
- wrport.we.eq(produce.ce)
- ]
- rdport = storage.get_port(clock_domain="read")
- self.specials += rdport
- self.comb += [
- rdport.adr.eq(consume.q_next_binary[:-1]),
- self.dout.eq(rdport.dat_r)
- ]
+++ /dev/null
-from collections import OrderedDict
-
-from migen.fhdl.structure import *
-from migen.fhdl.structure import _Statement, _Slice, _ArrayProxy
-from migen.fhdl.module import Module, FinalizeError
-from migen.fhdl.visit import NodeTransformer
-from migen.fhdl.bitcontainer import value_bits_sign
-
-
-__all__ = ["AnonymousState", "NextState", "NextValue", "FSM"]
-
-
-class AnonymousState:
- pass
-
-
-# do not use namedtuple here as it inherits tuple
-# and the latter is used elsewhere in FHDL
-class NextState(_Statement):
- def __init__(self, state):
- self.state = state
-
-
-class NextValue(_Statement):
- def __init__(self, target, value):
- self.target = target
- self.value = value
-
-
-def _target_eq(a, b):
- if type(a) != type(b):
- return False
- ty = type(a)
- if ty == Constant:
- return a.value == b.value
- elif ty == Signal:
- return a is b
- elif ty == Cat:
- return all(_target_eq(x, y) for x, y in zip(a.l, b.l))
- elif ty == _Slice:
- return (_target_eq(a.value, b.value)
- and a.start == b.start
- and a.end == b.end)
- elif ty == _ArrayProxy:
- return (all(_target_eq(x, y) for x, y in zip(a.choices, b.choices))
- and _target_eq(a.key, b.key))
- else:
- raise ValueError("NextValue cannot be used with target type '{}'"
- .format(ty))
-
-
-class _LowerNext(NodeTransformer):
- def __init__(self, next_state_signal, encoding, aliases):
- self.next_state_signal = next_state_signal
- self.encoding = encoding
- self.aliases = aliases
- # (target, next_value_ce, next_value)
- self.registers = []
-
- def _get_register_control(self, target):
- for x in self.registers:
- if _target_eq(target, x[0]):
- return x[1], x[2]
- raise KeyError
-
- def visit_unknown(self, node):
- if isinstance(node, NextState):
- try:
- actual_state = self.aliases[node.state]
- except KeyError:
- actual_state = node.state
- return self.next_state_signal.eq(self.encoding[actual_state])
- elif isinstance(node, NextValue):
- try:
- next_value_ce, next_value = self._get_register_control(node.target)
- except KeyError:
- related = node.target if isinstance(node.target, Signal) else None
- next_value = Signal(bits_sign=value_bits_sign(node.target), related=related)
- next_value_ce = Signal(related=related)
- self.registers.append((node.target, next_value_ce, next_value))
- return next_value.eq(node.value), next_value_ce.eq(1)
- else:
- return node
-
-
-class FSM(Module):
- def __init__(self, reset_state=None):
- self.actions = OrderedDict()
- self.state_aliases = dict()
- self.reset_state = reset_state
-
- self.before_entering_signals = OrderedDict()
- self.before_leaving_signals = OrderedDict()
- self.after_entering_signals = OrderedDict()
- self.after_leaving_signals = OrderedDict()
-
- def act(self, state, *statements):
- if self.finalized:
- raise FinalizeError
- if self.reset_state is None:
- self.reset_state = state
- if state not in self.actions:
- self.actions[state] = []
- self.actions[state] += statements
-
- def delayed_enter(self, name, target, delay):
- if self.finalized:
- raise FinalizeError
- if delay > 0:
- state = name
- for i in range(delay):
- if i == delay - 1:
- next_state = target
- else:
- next_state = AnonymousState()
- self.act(state, NextState(next_state))
- state = next_state
- else:
- self.state_aliases[name] = target
-
- def ongoing(self, state):
- is_ongoing = Signal()
- self.act(state, is_ongoing.eq(1))
- return is_ongoing
-
- def _get_signal(self, d, state):
- if state not in self.actions:
- self.actions[state] = []
- try:
- return d[state]
- except KeyError:
- is_el = Signal()
- d[state] = is_el
- return is_el
-
- def before_entering(self, state):
- return self._get_signal(self.before_entering_signals, state)
-
- def before_leaving(self, state):
- return self._get_signal(self.before_leaving_signals, state)
-
- def after_entering(self, state):
- signal = self._get_signal(self.after_entering_signals, state)
- self.sync += signal.eq(self.before_entering(state))
- return signal
-
- def after_leaving(self, state):
- signal = self._get_signal(self.after_leaving_signals, state)
- self.sync += signal.eq(self.before_leaving(state))
- return signal
-
- def do_finalize(self):
- nstates = len(self.actions)
- self.encoding = dict((s, n) for n, s in enumerate(self.actions.keys()))
- self.state = Signal(max=nstates, reset=self.encoding[self.reset_state])
- self.next_state = Signal(max=nstates)
-
- ln = _LowerNext(self.next_state, self.encoding, self.state_aliases)
- cases = dict((self.encoding[k], ln.visit(v)) for k, v in self.actions.items() if v)
- self.comb += [
- self.next_state.eq(self.state),
- Case(self.state, cases).makedefault(self.encoding[self.reset_state])
- ]
- self.sync += self.state.eq(self.next_state)
- for register, next_value_ce, next_value in ln.registers:
- self.sync += If(next_value_ce, register.eq(next_value))
-
- # drive entering/leaving signals
- for state, signal in self.before_leaving_signals.items():
- encoded = self.encoding[state]
- self.comb += signal.eq((self.state == encoded) & ~(self.next_state == encoded))
- if self.reset_state in self.after_entering_signals:
- self.after_entering_signals[self.reset_state].reset = 1
- for state, signal in self.before_entering_signals.items():
- encoded = self.encoding[state]
- self.comb += signal.eq(~(self.state == encoded) & (self.next_state == encoded))
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-from migen.fhdl.specials import Special
-
-
-class DifferentialInput(Special):
- def __init__(self, i_p, i_n, o):
- Special.__init__(self)
- self.i_p = wrap(i_p)
- self.i_n = wrap(i_n)
- self.o = wrap(o)
-
- def iter_expressions(self):
- yield self, "i_p", SPECIAL_INPUT
- yield self, "i_n", SPECIAL_INPUT
- yield self, "o", SPECIAL_OUTPUT
-
- @staticmethod
- def lower(dr):
- raise NotImplementedError("Attempted to use a differential input, but platform does not support them")
-
-
-class DifferentialOutput(Special):
- def __init__(self, i, o_p, o_n):
- Special.__init__(self)
- self.i = wrap(i)
- self.o_p = wrap(o_p)
- self.o_n = wrap(o_n)
-
- def iter_expressions(self):
- yield self, "i", SPECIAL_INPUT
- yield self, "o_p", SPECIAL_OUTPUT
- yield self, "o_n", SPECIAL_OUTPUT
-
- @staticmethod
- def lower(dr):
- raise NotImplementedError("Attempted to use a differential output, but platform does not support them")
-
-
-class CRG(Module):
- def __init__(self, clk, rst=0):
- self.clock_domains.cd_sys = ClockDomain()
- self.clock_domains.cd_por = ClockDomain(reset_less=True)
-
- if hasattr(clk, "p"):
- clk_se = Signal()
- self.specials += DifferentialInput(clk.p, clk.n, clk_se)
- clk = clk_se
-
- # Power on Reset (vendor agnostic)
- int_rst = Signal(reset=1)
- self.sync.por += int_rst.eq(rst)
- self.comb += [
- self.cd_sys.clk.eq(clk),
- self.cd_por.clk.eq(clk),
- self.cd_sys.rst.eq(int_rst)
- ]
-
-
-class DDRInput(Special):
- def __init__(self, i, o1, o2, clk=ClockSignal()):
- Special.__init__(self)
- self.i = wrap(i)
- self.o1 = wrap(o1)
- self.o2 = wrap(o2)
- self.clk = wrap(clk)
-
- def iter_expressions(self):
- yield self, "i", SPECIAL_INPUT
- yield self, "o1", SPECIAL_OUTPUT
- yield self, "o2", SPECIAL_OUTPUT
- yield self, "clk", SPECIAL_INPUT
-
- @staticmethod
- def lower(dr):
- raise NotImplementedError("Attempted to use a DDR input, but platform does not support them")
-
-
-class DDROutput(Special):
- def __init__(self, i1, i2, o, clk=ClockSignal()):
- Special.__init__(self)
- self.i1 = i1
- self.i2 = i2
- self.o = o
- self.clk = clk
-
- def iter_expressions(self):
- yield self, "i1", SPECIAL_INPUT
- yield self, "i2", SPECIAL_INPUT
- yield self, "o", SPECIAL_OUTPUT
- yield self, "clk", SPECIAL_INPUT
-
- @staticmethod
- def lower(dr):
- raise NotImplementedError("Attempted to use a DDR output, but platform does not support them")
-
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-from migen.fhdl.bitcontainer import bits_for
-
-
-def split(v, *counts):
- r = []
- offset = 0
- for n in counts:
- if n != 0:
- r.append(v[offset:offset+n])
- else:
- r.append(None)
- offset += n
- return tuple(r)
-
-
-def displacer(signal, shift, output, n=None, reverse=False):
- if shift is None:
- return output.eq(signal)
- if n is None:
- n = 2**len(shift)
- w = len(signal)
- if reverse:
- r = reversed(range(n))
- else:
- r = range(n)
- l = [Replicate(shift == i, w) & signal for i in r]
- return output.eq(Cat(*l))
-
-
-def chooser(signal, shift, output, n=None, reverse=False):
- if shift is None:
- return output.eq(signal)
- if n is None:
- n = 2**len(shift)
- w = len(output)
- cases = {}
- for i in range(n):
- if reverse:
- s = n - i - 1
- else:
- s = i
- cases[i] = [output.eq(signal[s*w:(s+1)*w])]
- return Case(shift, cases).makedefault()
-
-
-def timeline(trigger, events):
- lastevent = max([e[0] for e in events])
- counter = Signal(max=lastevent+1)
-
- counterlogic = If(counter != 0,
- counter.eq(counter + 1)
- ).Elif(trigger,
- counter.eq(1)
- )
- # insert counter reset if it doesn't naturally overflow
- # (test if lastevent+1 is a power of 2)
- if (lastevent & (lastevent + 1)) != 0:
- counterlogic = If(counter == lastevent,
- counter.eq(0)
- ).Else(
- counterlogic
- )
-
- def get_cond(e):
- if e[0] == 0:
- return trigger & (counter == 0)
- else:
- return counter == e[0]
- sync = [If(get_cond(e), *e[1]) for e in events]
- sync.append(counterlogic)
- return sync
-
-
-class WaitTimer(Module):
- def __init__(self, t):
- self.wait = Signal()
- self.done = Signal()
-
- # # #
-
- count = Signal(bits_for(t), reset=t)
- self.comb += self.done.eq(count == 0)
- self.sync += \
- If(self.wait,
- If(~self.done, count.eq(count - 1))
- ).Else(count.eq(count.reset))
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.tracer import get_obj_var_name
-
-from functools import reduce
-from operator import or_
-
-
-(DIR_NONE, DIR_S_TO_M, DIR_M_TO_S) = range(3)
-
-# Possible layout elements:
-# 1. (name, size)
-# 2. (name, size, direction)
-# 3. (name, sublayout)
-# size can be an int, or a (int, bool) tuple for signed numbers
-# sublayout must be a list
-
-
-def set_layout_parameters(layout, **layout_dict):
- def resolve(p):
- if isinstance(p, str):
- try:
- return layout_dict[p]
- except KeyError:
- return p
- else:
- return p
-
- r = []
- for f in layout:
- if isinstance(f[1], (int, tuple, str)): # cases 1/2
- if len(f) == 3:
- r.append((f[0], resolve(f[1]), f[2]))
- else:
- r.append((f[0], resolve(f[1])))
- elif isinstance(f[1], list): # case 3
- r.append((f[0], set_layout_parameters(f[1], **layout_dict)))
- else:
- raise TypeError
- return r
-
-
-def layout_len(layout):
- r = 0
- for f in layout:
- if isinstance(f[1], (int, tuple)): # cases 1/2
- if len(f) == 3:
- fname, fsize, fdirection = f
- else:
- fname, fsize = f
- elif isinstance(f[1], list): # case 3
- fname, fsublayout = f
- fsize = layout_len(fsublayout)
- else:
- raise TypeError
- if isinstance(fsize, tuple):
- r += fsize[0]
- else:
- r += fsize
- return r
-
-
-def layout_get(layout, name):
- for f in layout:
- if f[0] == name:
- return f
- raise KeyError(name)
-
-
-def layout_partial(layout, *elements):
- r = []
- for path in elements:
- path_s = path.split("/")
- last = path_s.pop()
- copy_ref = layout
- insert_ref = r
- for hop in path_s:
- name, copy_ref = layout_get(copy_ref, hop)
- try:
- name, insert_ref = layout_get(insert_ref, hop)
- except KeyError:
- new_insert_ref = []
- insert_ref.append((hop, new_insert_ref))
- insert_ref = new_insert_ref
- insert_ref.append(layout_get(copy_ref, last))
- return r
-
-
-class Record:
- def __init__(self, layout, name=None):
- self.name = get_obj_var_name(name, "")
- self.layout = layout
-
- if self.name:
- prefix = self.name + "_"
- else:
- prefix = ""
- for f in self.layout:
- if isinstance(f[1], (int, tuple)): # cases 1/2
- if(len(f) == 3):
- fname, fsize, fdirection = f
- else:
- fname, fsize = f
- finst = Signal(fsize, name=prefix + fname)
- elif isinstance(f[1], list): # case 3
- fname, fsublayout = f
- finst = Record(fsublayout, prefix + fname)
- else:
- raise TypeError
- setattr(self, fname, finst)
-
- def eq(self, other):
- return [getattr(self, f[0]).eq(getattr(other, f[0]))
- for f in self.layout if hasattr(other, f[0])]
-
- def iter_flat(self):
- for f in self.layout:
- e = getattr(self, f[0])
- if isinstance(e, Signal):
- if len(f) == 3:
- yield e, f[2]
- else:
- yield e, DIR_NONE
- elif isinstance(e, Record):
- yield from e.iter_flat()
- else:
- raise TypeError
-
- def flatten(self):
- return [signal for signal, direction in self.iter_flat()]
-
- def raw_bits(self):
- return Cat(*self.flatten())
-
- def connect(self, *slaves, leave_out=set()):
- if isinstance(leave_out, str):
- leave_out = {leave_out}
- r = []
- for f in self.layout:
- field = f[0]
- if field not in leave_out:
- self_e = getattr(self, field)
- if isinstance(self_e, Signal):
- direction = f[2]
- if direction == DIR_M_TO_S:
- r += [getattr(slave, field).eq(self_e) for slave in slaves]
- elif direction == DIR_S_TO_M:
- r.append(self_e.eq(reduce(or_, [getattr(slave, field) for slave in slaves])))
- else:
- raise TypeError
- else:
- for slave in slaves:
- r += self_e.connect(getattr(slave, field), leave_out=leave_out)
- return r
-
- def connect_flat(self, *slaves):
- r = []
- iter_slaves = [slave.iter_flat() for slave in slaves]
- for m_signal, m_direction in self.iter_flat():
- if m_direction == DIR_M_TO_S:
- for iter_slave in iter_slaves:
- s_signal, s_direction = next(iter_slave)
- assert(s_direction == DIR_M_TO_S)
- r.append(s_signal.eq(m_signal))
- elif m_direction == DIR_S_TO_M:
- s_signals = []
- for iter_slave in iter_slaves:
- s_signal, s_direction = next(iter_slave)
- assert(s_direction == DIR_S_TO_M)
- s_signals.append(s_signal)
- r.append(m_signal.eq(reduce(or_, s_signals)))
- else:
- raise TypeError
- return r
-
- def __len__(self):
- return layout_len(self.layout)
-
- def __repr__(self):
- return "<Record " + ":".join(f[0] for f in self.layout) + " at " + hex(id(self)) + ">"
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.specials import Special
-
-
-class AsyncResetSynchronizer(Special):
- def __init__(self, cd, async_reset):
- Special.__init__(self)
- self.cd = cd
- self.async_reset = wrap(async_reset)
-
- def iter_expressions(self):
- yield self.cd, "clk", SPECIAL_INPUT
- yield self.cd, "rst", SPECIAL_OUTPUT
- yield self, "async_reset", SPECIAL_INPUT
-
- @staticmethod
- def lower(dr):
- raise NotImplementedError("Attempted to use a reset synchronizer, but platform does not support them")
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-
-
-(SP_WITHDRAW, SP_CE) = range(2)
-
-
-class RoundRobin(Module):
- def __init__(self, n, switch_policy=SP_WITHDRAW):
- self.request = Signal(n)
- self.grant = Signal(max=max(2, n))
- self.switch_policy = switch_policy
- if self.switch_policy == SP_CE:
- self.ce = Signal()
-
- ###
-
- if n > 1:
- cases = {}
- for i in range(n):
- switch = []
- for j in reversed(range(i+1, i+n)):
- t = j % n
- switch = [
- If(self.request[t],
- self.grant.eq(t)
- ).Else(
- *switch
- )
- ]
- if self.switch_policy == SP_WITHDRAW:
- case = [If(~self.request[i], *switch)]
- else:
- case = switch
- cases[i] = case
- statement = Case(self.grant, cases)
- if self.switch_policy == SP_CE:
- statement = If(self.ce, statement)
- self.sync += statement
- else:
- self.comb += self.grant.eq(0)
+++ /dev/null
-from migen.fhdl.structure import *
-from migen.fhdl.module import Module
-
-
-class BitonicSort(Module):
- """Combinatorial sorting network
-
- The Bitonic sort is implemented as a combinatorial sort using
- comparators and multiplexers. Its asymptotic complexity (in terms of
- number of comparators/muxes) is O(n log(n)**2), like mergesort or
- shellsort.
-
- http://www.dps.uibk.ac.at/~cosenza/teaching/gpu/sort-batcher.pdf
-
- http://www.inf.fh-flensburg.de/lang/algorithmen/sortieren/bitonic/bitonicen.htm
-
- http://www.myhdl.org/doku.php/cookbook:bitonic
-
- Parameters
- ----------
- n : int
- Number of inputs and output signals.
- m : int
- Bit width of inputs and outputs. Or a tuple of `(m, signed)`.
- ascending : bool
- Sort direction. `True` if input is to be sorted ascending,
- `False` for descending. Defaults to ascending.
-
- Attributes
- ----------
- i : list of Signals, in
- Input values, each `m` wide.
- o : list of Signals, out
- Output values, sorted, each `m` bits wide.
- """
- def __init__(self, n, m, ascending=True):
- self.i = [Signal(m) for i in range(n)]
- self.o = [Signal(m) for i in range(n)]
- self._sort(self.i, self.o, int(ascending), m)
-
- def _sort_two(self, i0, i1, o0, o1, dir):
- self.comb += [
- o0.eq(i0),
- o1.eq(i1),
- If(dir == (i0 > i1),
- o0.eq(i1),
- o1.eq(i0),
- )]
-
- def _merge(self, i, o, dir, m):
- n = len(i)
- k = n//2
- if n > 1:
- t = [Signal(m) for j in range(n)]
- for j in range(k):
- self._sort_two(i[j], i[j + k], t[j], t[j + k], dir)
- self._merge(t[:k], o[:k], dir, m)
- self._merge(t[k:], o[k:], dir, m)
- else:
- self.comb += o[0].eq(i[0])
-
- def _sort(self, i, o, dir, m):
- n = len(i)
- k = n//2
- if n > 1:
- t = [Signal(m) for j in range(n)]
- self._sort(i[:k], t[:k], 1, m) # ascending
- self._sort(i[k:], t[k:], 0, m) # descending
- self._merge(t, o, dir, m)
- else:
- self.comb += o[0].eq(i[0])
+++ /dev/null
-from migen.sim.core import Simulator, run_simulation
+++ /dev/null
-import operator
-import collections
-import inspect
-
-from migen.fhdl.structure import *
-from migen.fhdl.structure import (_Value, _Statement,
- _Operator, _Slice, _ArrayProxy,
- _Assign, _Fragment)
-from migen.fhdl.bitcontainer import value_bits_sign
-from migen.fhdl.tools import list_signals, list_targets, insert_resets
-from migen.fhdl.simplify import MemoryToArray
-from migen.fhdl.specials import _MemoryLocation
-from migen.sim.vcd import VCDWriter, DummyVCDWriter
-
-
-class ClockState:
- def __init__(self, high, half_period, time_before_trans):
- self.high = high
- self.half_period = half_period
- self.time_before_trans = time_before_trans
-
-
-class TimeManager:
- def __init__(self, description):
- self.clocks = dict()
-
- for k, period_phase in description.items():
- if isinstance(period_phase, tuple):
- period, phase = period_phase
- else:
- period = period_phase
- phase = 0
- half_period = period//2
- if phase >= half_period:
- phase -= half_period
- high = True
- else:
- high = False
- self.clocks[k] = ClockState(high, half_period, half_period - phase)
-
- def tick(self):
- rising = set()
- falling = set()
- dt = min(cs.time_before_trans for cs in self.clocks.values())
- for k, cs in self.clocks.items():
- if cs.time_before_trans == dt:
- cs.high = not cs.high
- if cs.high:
- rising.add(k)
- else:
- falling.add(k)
- cs.time_before_trans -= dt
- if not cs.time_before_trans:
- cs.time_before_trans += cs.half_period
- return dt, rising, falling
-
-
-str2op = {
- "~": operator.invert,
- "+": operator.add,
- "-": operator.sub,
- "*": operator.mul,
-
- ">>>": operator.rshift,
- "<<<": operator.lshift,
-
- "&": operator.and_,
- "^": operator.xor,
- "|": operator.or_,
-
- "<": operator.lt,
- "<=": operator.le,
- "==": operator.eq,
- "!=": operator.ne,
- ">": operator.gt,
- ">=": operator.ge,
-}
-
-
-def _truncate(value, nbits, signed):
- value = value & (2**nbits - 1)
- if signed and (value & 2**(nbits - 1)):
- value -= 2**nbits
- return value
-
-
-class Evaluator:
- def __init__(self, clock_domains, replaced_memories):
- self.clock_domains = clock_domains
- self.replaced_memories = replaced_memories
- self.signal_values = dict()
- self.modifications = dict()
-
- def commit(self):
- r = set()
- for k, v in self.modifications.items():
- if k not in self.signal_values or self.signal_values[k] != v:
- self.signal_values[k] = v
- r.add(k)
- self.modifications.clear()
- return r
-
- def eval(self, node, postcommit=False):
- if isinstance(node, Constant):
- return node.value
- elif isinstance(node, Signal):
- if postcommit:
- try:
- return self.modifications[node]
- except KeyError:
- pass
- try:
- return self.signal_values[node]
- except KeyError:
- return node.reset.value
- elif isinstance(node, _Operator):
- operands = [self.eval(o, postcommit) for o in node.operands]
- if node.op == "-":
- if len(operands) == 1:
- return -operands[0]
- else:
- return operands[0] - operands[1]
- elif node.op == "m":
- return operands[1] if operands[0] else operands[2]
- else:
- return str2op[node.op](*operands)
- elif isinstance(node, _Slice):
- v = self.eval(node.value, postcommit)
- idx = range(node.start, node.stop)
- return sum(((v >> i) & 1) << j for j, i in enumerate(idx))
- elif isinstance(node, Cat):
- shift = 0
- r = 0
- for element in node.l:
- nbits = len(element)
- # make value always positive
- r |= (self.eval(element, postcommit) & (2**nbits-1)) << shift
- shift += nbits
- return r
- elif isinstance(node, _ArrayProxy):
- return self.eval(node.choices[self.eval(node.key, postcommit)],
- postcommit)
- elif isinstance(node, _MemoryLocation):
- array = self.replaced_memories[node.memory]
- return self.eval(array[self.eval(node.index, postcommit)], postcommit)
- elif isinstance(node, ClockSignal):
- return self.eval(self.clock_domains[node.cd].clk, postcommit)
- elif isinstance(node, ResetSignal):
- rst = self.clock_domains[node.cd].rst
- if rst is None:
- if node.allow_reset_less:
- return 0
- else:
- raise ValueError("Attempted to get reset signal of resetless"
- " domain '{}'".format(node.cd))
- else:
- return self.eval(rst, postcommit)
- else:
- raise NotImplementedError
-
- def assign(self, node, value):
- if isinstance(node, Signal):
- assert not node.variable
- self.modifications[node] = _truncate(value,
- node.nbits, node.signed)
- elif isinstance(node, Cat):
- for element in node.l:
- nbits = len(element)
- self.assign(element, value & (2**nbits-1))
- value >>= nbits
- elif isinstance(node, _Slice):
- full_value = self.eval(node.value, True)
- # clear bits assigned to by the slice
- full_value &= ~((2**node.stop-1) - (2**node.start-1))
- # set them to the new value
- value &= 2**(node.stop - node.start)-1
- full_value |= value << node.start
- self.assign(node.value, full_value)
- elif isinstance(node, _ArrayProxy):
- self.assign(node.choices[self.eval(node.key)], value)
- elif isinstance(node, _MemoryLocation):
- array = self.replaced_memories[node.memory]
- self.assign(array[self.eval(node.index)], value)
- else:
- raise NotImplementedError
-
- def execute(self, statements):
- for s in statements:
- if isinstance(s, _Assign):
- self.assign(s.l, self.eval(s.r))
- elif isinstance(s, If):
- if self.eval(s.cond) & (2**len(s.cond) - 1):
- self.execute(s.t)
- else:
- self.execute(s.f)
- elif isinstance(s, Case):
- nbits, signed = value_bits_sign(s.test)
- test = _truncate(self.eval(s.test), nbits, signed)
- found = False
- for k, v in s.cases.items():
- if isinstance(k, Constant) and k.value == test:
- self.execute(v)
- found = True
- break
- if not found and "default" in s.cases:
- self.execute(s.cases["default"])
- elif isinstance(s, collections.Iterable):
- self.execute(s)
- else:
- raise NotImplementedError
-
-
-# TODO: instances via Iverilog/VPI
-class Simulator:
- def __init__(self, fragment_or_module, generators, clocks={"sys": 10}, vcd_name=None):
- if isinstance(fragment_or_module, _Fragment):
- self.fragment = fragment_or_module
- else:
- self.fragment = fragment_or_module.get_fragment()
- if not isinstance(generators, dict):
- generators = {"sys": generators}
- self.generators = dict()
- for k, v in generators.items():
- if (isinstance(v, collections.Iterable)
- and not inspect.isgenerator(v)):
- self.generators[k] = list(v)
- else:
- self.generators[k] = [v]
-
- self.time = TimeManager(clocks)
- for clock in clocks.keys():
- if clock not in self.fragment.clock_domains:
- cd = ClockDomain(name=clock, reset_less=True)
- cd.clk.reset = C(self.time.clocks[clock].high)
- self.fragment.clock_domains.append(cd)
-
- mta = MemoryToArray()
- mta.transform_fragment(None, self.fragment)
- insert_resets(self.fragment)
- # comb signals return to their reset value if nothing assigns them
- self.fragment.comb[0:0] = [s.eq(s.reset)
- for s in list_targets(self.fragment.comb)]
- self.evaluator = Evaluator(self.fragment.clock_domains,
- mta.replacements)
-
- if vcd_name is None:
- self.vcd = DummyVCDWriter()
- else:
- signals = list_signals(self.fragment)
- for cd in self.fragment.clock_domains:
- signals.add(cd.clk)
- if cd.rst is not None:
- signals.add(cd.rst)
- for memory_array in mta.replacements.values():
- signals |= set(memory_array)
- signals = sorted(signals, key=lambda x: x.duid)
- self.vcd = VCDWriter(vcd_name, signals)
-
- def __enter__(self):
- return self
-
- def __exit__(self, type, value, traceback):
- self.close()
-
- def close(self):
- self.vcd.close()
-
- def _commit_and_comb_propagate(self):
- # TODO: optimize
- all_modified = set()
- modified = self.evaluator.commit()
- all_modified |= modified
- while modified:
- self.evaluator.execute(self.fragment.comb)
- modified = self.evaluator.commit()
- all_modified |= modified
- for signal in all_modified:
- self.vcd.set(signal, self.evaluator.signal_values[signal])
-
- def _evalexec_nested_lists(self, x):
- if isinstance(x, list):
- return [self._evalexec_nested_lists(e) for e in x]
- elif isinstance(x, _Value):
- return self.evaluator.eval(x)
- elif isinstance(x, _Statement):
- self.evaluator.execute([x])
- return None
- else:
- raise ValueError
-
- def _process_generators(self, cd):
- exhausted = []
- for generator in self.generators[cd]:
- reply = None
- while True:
- try:
- request = generator.send(reply)
- if request is None:
- break # next cycle
- else:
- reply = self._evalexec_nested_lists(request)
- except StopIteration:
- exhausted.append(generator)
- break
- for generator in exhausted:
- self.generators[cd].remove(generator)
-
- def _continue_simulation(self):
- # TODO: passive generators
- return any(self.generators.values())
-
- def run(self):
- self.evaluator.execute(self.fragment.comb)
- self._commit_and_comb_propagate()
-
- while True:
- dt, rising, falling = self.time.tick()
- self.vcd.delay(dt)
- for cd in rising:
- self.evaluator.assign(self.fragment.clock_domains[cd].clk, 1)
- if cd in self.fragment.sync:
- self.evaluator.execute(self.fragment.sync[cd])
- if cd in self.generators:
- self._process_generators(cd)
- for cd in falling:
- self.evaluator.assign(self.fragment.clock_domains[cd].clk, 0)
- self._commit_and_comb_propagate()
-
- if not self._continue_simulation():
- break
-
-
-def run_simulation(*args, **kwargs):
- with Simulator(*args, **kwargs) as s:
- s.run()
+++ /dev/null
-from itertools import count
-
-from migen.fhdl.namer import build_namespace
-
-
-def vcd_codes():
- codechars = [chr(i) for i in range(33, 127)]
- for n in count():
- q, r = divmod(n, len(codechars))
- code = codechars[r]
- while q > 0:
- q, r = divmod(q, len(codechars))
- code = codechars[r] + code
- yield code
-
-
-class VCDWriter:
- def __init__(self, filename, signals):
- self.fo = open(filename, "w")
- self.codes = dict()
- self.signal_values = dict()
- self.t = 0
-
- try:
- ns = build_namespace(signals)
- codes = vcd_codes()
- for signal in signals:
- name = ns.get_name(signal)
- code = next(codes)
- self.codes[signal] = code
- self.fo.write("$var wire {len} {code} {name} $end\n"
- .format(name=name, code=code, len=len(signal)))
- self.fo.write("$dumpvars\n")
- for signal in signals:
- value = signal.reset.value
- self._write_value(signal, value)
- self.signal_values[signal] = value
- self.fo.write("$end\n")
- self.fo.write("#0\n")
- except:
- self.close()
- raise
-
- def _write_value(self, signal, value):
- l = len(signal)
- if value < 0:
- value += 2**l
- if l > 1:
- fmtstr = "b{:0" + str(l) + "b} {}\n"
- else:
- fmtstr = "{}{}\n"
- self.fo.write(fmtstr.format(value, self.codes[signal]))
-
- def set(self, signal, value):
- if self.signal_values[signal] != value:
- self._write_value(signal, value)
- self.signal_values[signal] = value
-
- def delay(self, delay):
- self.t += delay
- self.fo.write("#{}\n".format(self.t))
-
- def close(self):
- self.fo.close()
-
-
-class DummyVCDWriter:
- def set(self, signal, value):
- pass
-
- def delay(self, delay):
- pass
-
- def close(self):
- pass
+++ /dev/null
-from migen import *
-from migen.fhdl import verilog
-
-
-class SimCase:
- def setUp(self, *args, **kwargs):
- self.tb = self.TestBench(*args, **kwargs)
-
- def test_to_verilog(self):
- verilog.convert(self.tb)
-
- def run_with(self, generator):
- run_simulation(self.tb, generator)
+++ /dev/null
-import unittest
-
-from migen import *
-from migen.genlib.coding import *
-
-from migen.test.support import SimCase
-
-
-class EncCase(SimCase, unittest.TestCase):
- class TestBench(Module):
- def __init__(self):
- self.submodules.dut = Encoder(8)
-
- def test_sizes(self):
- self.assertEqual(len(self.tb.dut.i), 8)
- self.assertEqual(len(self.tb.dut.o), 3)
- self.assertEqual(len(self.tb.dut.n), 1)
-
- def test_run_sequence(self):
- seq = list(range(1<<8))
- def gen():
- for _ in range(256):
- if seq:
- yield self.tb.dut.i.eq(seq.pop(0))
- if (yield self.tb.dut.n):
- self.assertNotIn((yield self.tb.dut.i), [1<<i for i in range(8)])
- else:
- self.assertEqual((yield self.tb.dut.i), 1<<(yield self.tb.dut.o))
- yield
- self.run_with(gen())
-
-
-class PrioEncCase(SimCase, unittest.TestCase):
- class TestBench(Module):
- def __init__(self):
- self.submodules.dut = PriorityEncoder(8)
-
- def test_sizes(self):
- self.assertEqual(len(self.tb.dut.i), 8)
- self.assertEqual(len(self.tb.dut.o), 3)
- self.assertEqual(len(self.tb.dut.n), 1)
-
- def test_run_sequence(self):
- seq = list(range(1<<8))
- def gen():
- for _ in range(256):
- if seq:
- yield self.tb.dut.i.eq(seq.pop(0))
- i = yield self.tb.dut.i
- if (yield self.tb.dut.n):
- self.assertEqual(i, 0)
- else:
- o = yield self.tb.dut.o
- if o > 0:
- self.assertEqual(i & 1<<(o - 1), 0)
- self.assertGreaterEqual(i, 1<<o)
- yield
- self.run_with(gen())
-
-
-class DecCase(SimCase, unittest.TestCase):
- class TestBench(Module):
- def __init__(self):
- self.submodules.dut = Decoder(8)
-
- def test_sizes(self):
- self.assertEqual(len(self.tb.dut.i), 3)
- self.assertEqual(len(self.tb.dut.o), 8)
- self.assertEqual(len(self.tb.dut.n), 1)
-
- def test_run_sequence(self):
- seq = list(range(8*2))
- def gen():
- for _ in range(256):
- if seq:
- i = seq.pop()
- yield self.tb.dut.i.eq(i//2)
- yield self.tb.dut.n.eq(i%2)
- i = yield self.tb.dut.i
- o = yield self.tb.dut.o
- if (yield self.tb.dut.n):
- self.assertEqual(o, 0)
- else:
- self.assertEqual(o, 1<<i)
- self.run_with(gen())
-
-
-class SmallPrioEncCase(SimCase, unittest.TestCase):
- class TestBench(Module):
- def __init__(self):
- self.submodules.dut = PriorityEncoder(1)
-
- def test_sizes(self):
- self.assertEqual(len(self.tb.dut.i), 1)
- self.assertEqual(len(self.tb.dut.o), 1)
- self.assertEqual(len(self.tb.dut.n), 1)
-
- def test_run_sequence(self):
- seq = list(range(1))
- def gen():
- for _ in range(5):
- if seq:
- yield self.tb.dut.i.eq(seq.pop(0))
- i = yield self.tb.dut.i
- if (yield self.tb.dut.n):
- self.assertEqual(i, 0)
- else:
- o = yield self.tb.dut.o
- if o > 0:
- self.assertEqual(i & 1<<(o - 1), 0)
- self.assertGreaterEqual(i, 1<<o)
- yield
- self.run_with(gen())
+++ /dev/null
-import unittest
-
-from migen import *
-from migen.test.support import SimCase
-
-
-class ConstantCase(SimCase, unittest.TestCase):
- class TestBench(Module):
- def __init__(self):
- self.sigs = [
- (Signal(3), Constant(0), 0),
- (Signal(3), Constant(5), 5),
- (Signal(3), Constant(1, 2), 1),
- (Signal(3), Constant(-1, 7), 7),
- (Signal(3), Constant(0b10101)[:3], 0b101),
- (Signal(3), Constant(0b10101)[1:4], 0b10),
- (Signal(4), Constant(0b1100)[::-1], 0b0011),
- ]
- self.comb += [a.eq(b) for a, b, c in self.sigs]
-
- def test_comparisons(self):
- def gen():
- for s, l, v in self.tb.sigs:
- s = yield s
- self.assertEqual(
- s, int(v),
- "got {}, want {} from literal {}".format(
- s, v, l))
- self.run_with(gen())
+++ /dev/null
-import unittest
-
-from migen import *
-from migen.genlib.divider import Divider
-from migen.test.support import SimCase
-
-
-class DivisionCase(SimCase, unittest.TestCase):
- class TestBench(Module):
- def __init__(self):
- self.submodules.dut = Divider(4)
-
- def test_division(self):
- def gen():
- for dividend in range(16):
- for divisor in range(1, 16):
- with self.subTest(dividend=dividend, divisor=divisor):
- yield self.tb.dut.dividend_i.eq(dividend)
- yield self.tb.dut.divisor_i.eq(divisor)
- yield self.tb.dut.start_i.eq(1)
- yield
- yield self.tb.dut.start_i.eq(0)
- yield
- while not (yield self.tb.dut.ready_o):
- yield
- self.assertEqual((yield self.tb.dut.quotient_o), dividend//divisor)
- self.assertEqual((yield self.tb.dut.remainder_o), dividend%divisor)
- self.run_with(gen())
+++ /dev/null
-import unittest
-import os.path
-import sys
-import subprocess
-
-
-def _make_test_method(name, foldername):
- def test_method(self):
- filename = name + ".py"
- example_path = os.path.abspath(
- os.path.join(os.path.dirname(__file__), "..", "..", "examples"))
- filepath = os.path.join(example_path, foldername, filename)
- subprocess.check_call(
- [sys.executable, filepath],
- stdout=subprocess.DEVNULL
- )
-
- return test_method
-
-
-class TestExamplesSim(unittest.TestCase):
- pass
-
-for name in ("basic1",
- "basic2",
- # skip "fir" as it depends on SciPy
- # "fir",
- "memory"):
- setattr(TestExamplesSim, "test_" + name,
- _make_test_method(name, "sim"))
-
-
-class TestExamplesBasic(unittest.TestCase):
- pass
-
-for name in ("arrays",
- "fsm",
- "graycounter",
- "local_cd",
- "memory",
- "namer",
- "psync",
- "record",
- "reslice",
- "tristate",
- "two_dividers"):
- setattr(TestExamplesBasic, "test_" + name,
- _make_test_method(name, "basic"))
-
+++ /dev/null
-import unittest
-from itertools import count
-
-from migen import *
-from migen.genlib.fifo import SyncFIFO
-
-from migen.test.support import SimCase
-
-
-class SyncFIFOCase(SimCase, unittest.TestCase):
- class TestBench(Module):
- def __init__(self):
- self.submodules.dut = SyncFIFO(64, 2)
-
- self.sync += [
- If(self.dut.we & self.dut.writable,
- self.dut.din[:32].eq(self.dut.din[:32] + 1),
- self.dut.din[32:].eq(self.dut.din[32:] + 2)
- )
- ]
-
- def test_run_sequence(self):
- seq = list(range(20))
- def gen():
- for cycle in count():
- # fire re and we at "random"
- yield self.tb.dut.we.eq(cycle % 2 == 0)
- yield self.tb.dut.re.eq(cycle % 3 == 0)
- # the output if valid must be correct
- if (yield self.tb.dut.readable) and (yield self.tb.dut.re):
- try:
- i = seq.pop(0)
- except IndexError:
- break
- self.assertEqual((yield self.tb.dut.dout[:32]), i)
- self.assertEqual((yield self.tb.dut.dout[32:]), i*2)
- yield
- self.run_with(gen())
-
- def test_replace(self):
- seq = [x for x in range(20) if x % 5]
- def gen():
- for cycle in count():
- yield self.tb.dut.we.eq(cycle % 2 == 0)
- yield self.tb.dut.re.eq(cycle % 7 == 0)
- yield self.tb.dut.replace.eq(
- (yield self.tb.dut.din[:32]) % 5 == 1)
- if (yield self.tb.dut.readable) and (yield self.tb.dut.re):
- try:
- i = seq.pop(0)
- except IndexError:
- break
- self.assertEqual((yield self.tb.dut.dout[:32]), i)
- self.assertEqual((yield self.tb.dut.dout[32:]), i*2)
- yield
- self.run_with(gen())
+++ /dev/null
-import unittest
-
-from migen import *
-from migen.test.support import SimCase
-
-
-class SignedCase(SimCase, unittest.TestCase):
- class TestBench(Module):
- def __init__(self):
- self.a = Signal((3, True))
- self.b = Signal((4, True))
- comps = [
- lambda p, q: p > q,
- lambda p, q: p >= q,
- lambda p, q: p < q,
- lambda p, q: p <= q,
- lambda p, q: p == q,
- lambda p, q: p != q,
- ]
- self.vals = []
- for asign in 1, -1:
- for bsign in 1, -1:
- for f in comps:
- r = Signal()
- r0 = f(asign*self.a, bsign*self.b)
- self.comb += r.eq(r0)
- self.vals.append((asign, bsign, f, r, r0.op))
-
- def test_comparisons(self):
- def gen():
- for i in range(-4, 4):
- yield self.tb.a.eq(i)
- yield self.tb.b.eq(i)
- a = yield self.tb.a
- b = yield self.tb.b
- for asign, bsign, f, r, op in self.tb.vals:
- r, r0 = (yield r), f(asign*a, bsign*b)
- self.assertEqual(r, int(r0),
- "got {}, want {}*{} {} {}*{} = {}".format(
- r, asign, a, op, bsign, b, r0))
- yield
- self.run_with(gen())
+++ /dev/null
-import unittest
-
-from migen import *
-
-
-def _same_slices(a, b):
- return a.value is b.value and a.start == b.start and a.stop == b.stop
-
-
-class SignalSizeCase(unittest.TestCase):
- def setUp(self):
- self.i = C(0xaa)
- self.j = C(-127)
- self.s = Signal((13, True))
-
- def test_len(self):
- self.assertEqual(len(self.s), 13)
- self.assertEqual(len(self.i), 8)
- self.assertEqual(len(self.j), 8)
+++ /dev/null
-import unittest
-from random import randrange
-
-from migen import *
-from migen.genlib.sort import *
-
-from migen.test.support import SimCase
-
-
-class BitonicCase(SimCase, unittest.TestCase):
- class TestBench(Module):
- def __init__(self):
- self.submodules.dut = BitonicSort(8, 4, ascending=True)
-
- def test_sizes(self):
- self.assertEqual(len(self.tb.dut.i), 8)
- self.assertEqual(len(self.tb.dut.o), 8)
- for i in range(8):
- self.assertEqual(len(self.tb.dut.i[i]), 4)
- self.assertEqual(len(self.tb.dut.o[i]), 4)
-
- def test_sort(self):
- def gen():
- for repeat in range(20):
- for i in self.tb.dut.i:
- yield i.eq(randrange(1<<len(i)))
- yield
- self.assertEqual(sorted((yield self.tb.dut.i)),
- (yield self.tb.dut.o))
- self.run_with(gen())
+++ /dev/null
-import unittest
-import subprocess
-import os
-
-from migen import *
-from migen.fhdl.verilog import convert
-
-
-# Create a module with some combinatorial, some sequential, and some simple
-# assigns
-class SyntaxModule(Module):
- def __init__(self):
- x = [Signal(8) for y in range(10)]
- y = [Signal(8) for z in range(10)]
- en = Signal()
- a = Signal()
- b = Signal()
- z = Signal()
- as_src = Signal(16);
- as_tgt1 = Signal(16);
- as_tgt2 = Signal(16);
- self.io = {a, b, z, en, as_src, as_tgt1, as_tgt2}
-
- self.comb += If(a, z.eq(b))
- self.comb += as_tgt1.eq(as_src)
- self.comb += as_tgt2.eq(100)
- for xi in x:
- self.io.add(xi)
- for xi in range(1, len(x)):
- self.comb += If(en, y[xi].eq(x[xi-1])).Else(y[xi].eq(x[xi]))
- self.sync += x[xi].eq(y[xi])
-
-
-# Create unit test to build module, run Verilator and check for errors
-class SyntaxCase(unittest.TestCase):
- def base_test(self, name, asic_syntax, options=[]):
- filename = "test_module_{}.v".format(name)
- t = SyntaxModule()
- c = convert(t, t.io, name="test_module", asic_syntax=asic_syntax)
- f = open(filename, "w")
- f.write(str(c))
- f.close()
- subprocess.check_call("verilator --lint-only " + " ".join(options) + " " + filename,
- stdout=subprocess.DEVNULL,
- stderr=subprocess.DEVNULL, shell=True)
- os.unlink(filename)
-
- # XXX for now desactivate, travis-ci's Verilator seems to behave differently
- # XXX upgrade travis-ci's Verilator?
- #def test_generic_syntax(self):
- # options = [
- # "-Wno-WIDTH",
- # "-Wno-COMBDLY",
- # "-Wno-INITIALDLY"
- # ]
- # self.base_test("generic", False, options)
-
- def test_asic_syntax(self):
- options = [
- "-Wno-WIDTH", # XXX should we improve ASIC backend to remove this?
- ]
- self.base_test("asic", True, options)
+++ /dev/null
-from fractions import gcd
-import collections
-
-
-def flat_iteration(l):
- for element in l:
- if isinstance(element, collections.Iterable):
- for element2 in flat_iteration(element):
- yield element2
- else:
- yield element
-
-
-def xdir(obj, return_values=False):
- for attr in dir(obj):
- if attr[:2] != "__" and attr[-2:] != "__":
- if return_values:
- yield attr, getattr(obj, attr)
- else:
- yield attr
-
-
-def gcd_multiple(numbers):
- l = len(numbers)
- if l == 1:
- return numbers[0]
- else:
- s = l//2
- return gcd(gcd_multiple(numbers[:s]), gcd_multiple(numbers[s:]))
+++ /dev/null
-import cairo
-import math
-
-
-def _cairo_draw_node(ctx, dx, radius, color, outer_color, s):
- ctx.save()
-
- ctx.translate(dx, 0)
-
- ctx.set_line_width(0.0)
- gradient_color = cairo.RadialGradient(0, 0, 0, 0, 0, radius)
- gradient_color.add_color_stop_rgb(0, *color)
- gradient_color.add_color_stop_rgb(1, *outer_color)
- ctx.set_source(gradient_color)
- ctx.arc(0, 0, radius, 0, 2*math.pi)
- ctx.fill()
-
- lines = s.split("\n")
- textws = []
- texths = []
- for line in lines:
- x_bearing, y_bearing, w, h, x_advance, y_advance = ctx.text_extents(line)
- textws.append(w)
- texths.append(h + 2)
- ctx.translate(0, -sum(texths[1:])/2)
- for line, w, h in zip(lines, textws, texths):
- ctx.translate(-w/2, h/2)
- ctx.move_to(0, 0)
- ctx.set_source_rgb(0, 0, 0)
- ctx.show_text(line)
- ctx.translate(w/2, h/2)
-
- ctx.restore()
-
-
-def _cairo_draw_connection(ctx, x0, y0, color0, x1, y1, color1):
- ctx.move_to(x0, y0)
- ctx.curve_to(x0, y0+20, x1, y1-20, x1, y1)
- ctx.set_line_width(1.2)
- gradient_color = cairo.LinearGradient(x0, y0, x1, y1)
- gradient_color.add_color_stop_rgb(0, *color0)
- gradient_color.add_color_stop_rgb(1, *color1)
- ctx.set_source(gradient_color)
- ctx.stroke()
-
-
-class RenderNode:
- def __init__(self, label, children=None, color=(0.8, 0.8, 0.8), radius=40):
- self.label = label
- if children is None:
- children = []
- self.children = children
- self.color = color
- self.outer_color = (color[0]*3/5, color[1]*3/5, color[2]*3/5)
- self.radius = radius
- self.pitch = self.radius*3
-
- def get_dimensions(self):
- if self.children:
- cws, chs, cdxs = zip(*[c.get_dimensions() for c in self.children])
- w = sum(cws)
- h = self.pitch + max(chs)
- dx = cws[0]/4 - cws[-1]/4
- else:
- w = h = self.pitch
- dx = 0
- return w, h, dx
-
- def render(self, ctx):
- if self.children:
- cws, chs, cdxs = zip(*[c.get_dimensions() for c in self.children])
- first_child_x = -sum(cws)/2
-
- ctx.save()
- ctx.translate(first_child_x, self.pitch)
- for c, w in zip(self.children, cws):
- ctx.translate(w/2, 0)
- c.render(ctx)
- ctx.translate(w/2, 0)
- ctx.restore()
-
- dx = cws[0]/4 - cws[-1]/4
-
- current_x = first_child_x
- for c, w, cdx in zip(self.children, cws, cdxs):
- current_y = self.pitch - c.radius
- current_x += w/2
- _cairo_draw_connection(ctx, dx, self.radius, self.outer_color, current_x+cdx, current_y, c.outer_color)
- current_x += w/2
- else:
- dx = 0
- _cairo_draw_node(ctx, dx, self.radius, self.color, self.outer_color, self.label)
-
- def to_svg(self, name):
- w, h, dx = self.get_dimensions()
- surface = cairo.SVGSurface(name, w, h)
- ctx = cairo.Context(surface)
- ctx.translate(w/2, self.pitch/2)
- self.render(ctx)
- surface.finish()
-
-
-def _test():
- xns = [RenderNode("X"+str(n)) for n in range(5)]
- yns = [RenderNode("Y"+str(n), [RenderNode("foo", color=(0.1*n, 0.5+0.2*n, 1.0-0.3*n))]) for n in range(3)]
- n1 = RenderNode("n1", yns)
- n2 = RenderNode("n2", xns, color=(0.8, 0.5, 0.9))
- top = RenderNode("top", [n1, n2])
- top.to_svg("test.svg")
-
-if __name__ == "__main__":
- _test()
setup(
- name="migen",
- version="0.2",
- description="Python toolbox for building complex digital hardware",
- long_description=open("README.rst").read(),
- author="Sebastien Bourdeauducq",
- author_email="sb@m-labs.hk",
- url="http://m-labs.hk",
- download_url="https://github.com/m-labs/migen",
- packages=find_packages(),
- test_suite="migen.test",
+ name="litex",
+ version="1.0",
+ description="Python tools to design FPGA cores and SoCs",
+ long_description=open("README").read(),
+ author="Florent Kermarrec",
+ author_email="florent@enjoy-digital.fr",
+ url="http://enjoy-digital.fr",
+ download_url="https://github.com/enjoy-digital/litex",
license="BSD",
platforms=["Any"],
keywords="HDL ASIC FPGA hardware design",
"Operating System :: OS Independent",
"Programming Language :: Python",
],
+ packages=find_packages(),
+ include_package_data=True,
+ entry_points={
+ "console_scripts": [
+ "flterm=litex.soc.tools.flterm:main",
+ "mkmscimg=litex.soc.tools.mkmscimg:main",
+ ],
+ },
)
+++ /dev/null
-#!/bin/sh
-# Copyright Robert Jordens <robert@joerdens.org> 2014,2015
-
-# assuming your xilinx toolchain lives in /opt/Xilinx,
-# run `strace_tailor.sh /opt/Xilinx/ [synthesis script] [options]`,
-# e.g. for the pipistrello target of misoc:
-# strace_tailor.sh /opt/Xilinx/ ./make.py -t pipistrello build-bitstream
-# then in your current directory, `opt/Xilinx/*` is the
-# minimal toolchain required for this synthesis script run.
-
-PREFIX=$1
-shift
-strace -e trace=file,process -f -o strace.log $@
-sed -n 's|^.*"\('"$PREFIX"'[^"]*\)".*$|\1|p' strace.log \
- | sort | uniq | xargs -d '\n' \
- cp --parent --no-dereference --preserve=all -t .