litex: reorganize things, first work working version

This commit is contained in:
Florent Kermarrec 2015-11-07 12:26:46 +01:00
parent 637634f312
commit 6a0f85dc42
476 changed files with 487 additions and 21805 deletions

8
.gitignore vendored
View File

@ -1,7 +1,5 @@
__pycache__
*.pyc
*.egg-info/
vpi/*.o
vpi/migensim.vpi
examples/*.vcd
doc/_build
*.egg-info
*.vcd
outgoing

12
.gitmodules vendored Normal file
View File

@ -0,0 +1,12 @@
[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

View File

@ -1,52 +0,0 @@
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}"

3
MANIFEST.in Normal file
View File

@ -0,0 +1,3 @@
graft litex/soc/software
graft litex/soc/cores/cpu/lm32/verilog
graft litex/soc/cores/cpu/mor1kx/verilog

42
README Normal file
View File

@ -0,0 +1,42 @@
__ _ __ _ __
/ / (_) /____ | |/_/
/ /__/ / __/ -_)> <
/____/_/\__/\__/_/|_|
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

View File

@ -1,82 +0,0 @@
### 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!"

View File

@ -1 +0,0 @@
%PYTHON% setup.py install

View File

@ -1,28 +0,0 @@
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'

View File

@ -1,130 +0,0 @@
# 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."

0
doc/_build/.keep_me vendored
View File

View File

View File

View File

@ -1,223 +0,0 @@
# -*- 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)
]

View File

@ -1,362 +0,0 @@
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.

View File

@ -1,11 +0,0 @@
Migen manual
############
.. toctree::
:maxdepth: 2
introduction
fhdl
simulation
synthesis
reference

View File

@ -1,73 +0,0 @@
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.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

View File

@ -1,224 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 9.0 KiB

View File

@ -1,37 +0,0 @@
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:

View File

@ -1,6 +0,0 @@
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]

View File

@ -1,4 +0,0 @@
Synthesizing a Migen design
###########################
[To be written]

View File

@ -1,28 +0,0 @@
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()))

View File

@ -1,31 +0,0 @@
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}))

View File

@ -1,18 +0,0 @@
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")

View File

@ -1,68 +0,0 @@
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()

View File

@ -1,19 +0,0 @@
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}))

View File

@ -1,17 +0,0 @@
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))

View File

@ -1,44 +0,0 @@
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()))

View File

@ -1,23 +0,0 @@
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)

View File

@ -1,26 +0,0 @@
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"))

View File

@ -1,19 +0,0 @@
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()))

View File

@ -1,13 +0,0 @@
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}))

View File

@ -1,19 +0,0 @@
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}))

View File

@ -1,29 +0,0 @@
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")

View File

@ -1,37 +0,0 @@
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")

View File

@ -1,67 +0,0 @@
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}))

View File

@ -1,26 +0,0 @@
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))

View File

@ -1,9 +1,9 @@
# 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
from litex.build.generic_platform import *
from litex.build.altera import AlteraPlatform
from litex.build.altera.programmer import USBBlaster
_io = [

View File

@ -1,6 +1,6 @@
from migen.build.generic_platform import *
from migen.build.xilinx import XilinxPlatform, XC3SProg, VivadoProgrammer, iMPACT
from migen.build.xilinx.ise import XilinxISEToolchain
from litex.build.generic_platform import *
from litex.build.xilinx import XilinxPlatform, XC3SProg, VivadoProgrammer, iMPACT
from litex.build.xilinx.ise import XilinxISEToolchain
_io = [

View File

@ -1,9 +1,9 @@
# 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
from litex.build.generic_platform import *
from litex.build.xilinx import XilinxPlatform
from litex.build.xilinx.programmer import XC3SProg, FpgaProg
_io = [

View File

@ -1,5 +1,5 @@
from migen.build.generic_platform import *
from migen.build.sim import SimPlatform
from litex.build.generic_platform import *
from litex.build.sim import SimPlatform
class SimPins(Pins):

View File

@ -1,9 +1,9 @@
# 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
from litex.build.generic_platform import *
from litex.build.lattice import LatticePlatform
from litex.build.lattice.programmer import LatticeProgrammer
_io = [

View File

@ -2,13 +2,13 @@
import argparse
from migen import *
from migen.build.platforms import de0nano
from litex.gen import *
from litex.boards.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 *
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):
@ -101,7 +101,7 @@ class BaseSoC(SoCSDRAM):
sdram_module.geom_settings, sdram_module.timing_settings)
def main():
parser = argparse.ArgumentParser(description="MiSoC port to the Altera DE0 Nano")
parser = argparse.ArgumentParser(description="LiteX SoC port to the Altera DE0 Nano")
builder_args(parser)
soc_sdram_args(parser)
args = parser.parse_args()

View File

@ -2,19 +2,19 @@
import argparse
from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer
from migen.build.platforms import kc705
from litex.gen import *
from litex.gen.genlib.resetsync import AsyncResetSynchronizer
from litex.boards.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 *
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):
@ -150,7 +150,7 @@ def soc_kc705_argdict(args):
def main():
parser = argparse.ArgumentParser(description="MiSoC port to the KC705")
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",

View File

@ -3,14 +3,14 @@
import argparse
from fractions import Fraction
from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer
from migen.build.platforms import minispartan6
from litex.gen import *
from litex.gen.genlib.resetsync import AsyncResetSynchronizer
from litex.boards.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 *
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):
@ -82,7 +82,7 @@ class BaseSoC(SoCSDRAM):
def main():
parser = argparse.ArgumentParser(description="MiSoC port to the MiniSpartan6")
parser = argparse.ArgumentParser(description="LiteX SoC port to the MiniSpartan6")
builder_args(parser)
soc_sdram_args(parser)
args = parser.parse_args()

View File

@ -3,15 +3,15 @@
import argparse
from fractions import Fraction
from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer
from migen.build.platforms import papilio_pro
from litex.gen import *
from litex.gen.genlib.resetsync import AsyncResetSynchronizer
from litex.boards.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 *
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):
@ -94,7 +94,7 @@ class BaseSoC(SoCSDRAM):
def main():
parser = argparse.ArgumentParser(description="MiSoC port to the Papilio Pro")
parser = argparse.ArgumentParser(description="LiteX SoC port to the Papilio Pro")
builder_args(parser)
soc_sdram_args(parser)
args = parser.parse_args()

View File

@ -3,15 +3,15 @@
import argparse
from fractions import Fraction
from migen import *
from migen.genlib.resetsync import AsyncResetSynchronizer
from migen.build.platforms import pipistrello
from litex.gen import *
from litex.gen.genlib.resetsync import AsyncResetSynchronizer
from litex.boards.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 *
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):
@ -136,7 +136,7 @@ soc_pipistrello_argdict = soc_sdram_argdict
def main():
parser = argparse.ArgumentParser(description="MiSoC port to the Pipistrello")
parser = argparse.ArgumentParser(description="LiteX SoC port to the Pipistrello")
builder_args(parser)
soc_pipistrello_args(parser)
args = parser.parse_args()

View File

@ -3,13 +3,14 @@
import argparse
import importlib
from migen import *
from migen.genlib.io import CRG
from litex.gen import *
from litex.gen.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 *
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):
@ -52,13 +53,13 @@ class MiniSoC(BaseSoC):
def main():
parser = argparse.ArgumentParser(description="Generic MiSoC port")
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 Migen platform to build for")
help="module name of the platform to build for")
args = parser.parse_args()
platform_module = importlib.import_module(args.platform)

View File

@ -0,0 +1,2 @@
from litex.build.altera.platform import AlteraPlatform
from litex.build.altera.programmer import USBBlaster

View File

@ -1,6 +1,6 @@
from migen.fhdl.module import Module
from migen.fhdl.specials import Instance
from migen.genlib.io import DifferentialInput, DifferentialOutput
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):

View File

@ -1,5 +1,5 @@
from migen.build.generic_platform import GenericPlatform
from migen.build.altera import common, quartus
from litex.build.generic_platform import GenericPlatform
from litex.build.altera import common, quartus
class AlteraPlatform(GenericPlatform):

View File

@ -1,6 +1,6 @@
import subprocess
from migen.build.generic_programmer import GenericProgrammer
from litex.build.generic_programmer import GenericProgrammer
class USBBlaster(GenericProgrammer):

View File

@ -4,10 +4,10 @@
import os
import subprocess
from migen.fhdl.structure import _Fragment
from litex.gen.fhdl.structure import _Fragment
from migen.build.generic_platform import Pins, IOStandard, Misc
from migen.build import tools
from litex.build.generic_platform import Pins, IOStandard, Misc
from litex.build import tools
def _format_constraint(c, signame, fmt_r):
@ -92,7 +92,7 @@ def _build_files(device, sources, vincpaths, named_sc, named_pc, build_name):
def _run_quartus(build_name, quartus_path):
build_script_contents = """# Autogenerated by Migen
build_script_contents = """# Autogenerated by LiteX
set -e

View File

@ -1,10 +1,10 @@
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
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):

View File

@ -5,8 +5,7 @@ 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"]
"~/.litex", "/usr/local/share/litex", "/usr/share/litex"]
def set_flash_proxy_dir(self, flash_proxy_dir):
if flash_proxy_dir is not None:

View File

@ -0,0 +1,2 @@
from litex.build.lattice.platform import LatticePlatform
from litex.build.lattice.programmer import LatticeProgrammer

View File

@ -1,7 +1,7 @@
from migen.fhdl.module import Module
from migen.fhdl.specials import Instance
from migen.genlib.io import *
from migen.genlib.resetsync import AsyncResetSynchronizer
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):

View File

@ -6,11 +6,11 @@ import sys
import subprocess
import shutil
from migen.fhdl.structure import _Fragment
from litex.gen.fhdl.structure import _Fragment
from migen.build.generic_platform import *
from migen.build import tools
from migen.build.lattice import common
from litex.build.generic_platform import *
from litex.build import tools
from litex.build.lattice import common
def _format_constraint(c):
@ -61,7 +61,7 @@ def _build_files(device, sources, vincpaths, build_name):
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 = "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)

View File

@ -1,5 +1,5 @@
from migen.build.generic_platform import GenericPlatform
from migen.build.lattice import common, diamond
from litex.build.generic_platform import GenericPlatform
from litex.build.lattice import common, diamond
class LatticePlatform(GenericPlatform):

View File

@ -1,8 +1,8 @@
import os
import subprocess
from migen.build.generic_programmer import GenericProgrammer
from migen.build import tools
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

View File

@ -1,6 +1,6 @@
import subprocess
from migen.build.generic_programmer import GenericProgrammer
from litex.build.generic_programmer import GenericProgrammer
class OpenOCD(GenericProgrammer):

View File

@ -0,0 +1 @@
from litex.build.sim.platform import SimPlatform

View File

@ -1,5 +1,5 @@
from migen.build.generic_platform import GenericPlatform
from migen.build.sim import common, verilator
from litex.build.generic_platform import GenericPlatform
from litex.build.sim import common, verilator
class SimPlatform(GenericPlatform):

View File

@ -4,9 +4,9 @@
import os
import subprocess
from migen.fhdl.structure import _Fragment
from migen.build import tools
from migen.build.generic_platform import *
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):
@ -86,7 +86,7 @@ def _build_sim(platform, vns, build_name, include_paths, sim_path, serial, verbo
for path in include_paths:
include += "-I"+path+" "
build_script_contents = """# Autogenerated by Migen
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

View File

@ -0,0 +1,2 @@
from litex.build.xilinx.platform import XilinxPlatform
from litex.build.xilinx.programmer import UrJTAG, XC3SProg, FpgaProg, VivadoProgrammer, iMPACT, Adept

View File

@ -2,15 +2,15 @@ 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 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 migen.build import tools
from litex.build import tools
def settings(path, ver=None, sub=None):

View File

@ -2,10 +2,10 @@ 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
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):
@ -87,12 +87,12 @@ def _run_ise(build_name, ise_path, source, mode, ngdbuild_opt,
source_cmd = "call "
script_ext = ".bat"
shell = ["cmd", "/c"]
build_script_contents = "@echo off\nrem Autogenerated by Migen\n"
build_script_contents = "@echo off\nrem Autogenerated by LiteX\n"
else:
source_cmd = "source "
script_ext = ".sh"
shell = ["bash"]
build_script_contents = "# Autogenerated by Migen\nset -e\n"
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"

View File

@ -1,5 +1,5 @@
from migen.build.generic_platform import GenericPlatform
from migen.build.xilinx import common, vivado, ise
from litex.build.generic_platform import GenericPlatform
from litex.build.xilinx import common, vivado, ise
class XilinxPlatform(GenericPlatform):

View File

@ -2,8 +2,8 @@ import os
import sys
import subprocess
from migen.build.generic_programmer import GenericProgrammer
from migen.build.xilinx import common
from litex.build.generic_programmer import GenericProgrammer
from litex.build.xilinx import common
def _run_urjtag(cmds):

View File

@ -5,10 +5,10 @@ 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
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):
@ -52,13 +52,13 @@ def _build_xdc(named_sc, named_pc):
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 = "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 Migen\nset -e\n"
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"

View File

@ -1,7 +0,0 @@
__pycache__
*.pyc
*.egg-info/
vpi/*.o
vpi/migensim.vpi
examples/*.vcd
doc/_build

View File

@ -1,52 +0,0 @@
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}"

View File

@ -1,31 +0,0 @@
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.

View File

@ -1,82 +0,0 @@
### 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!"

10
litex/gen/__init__.py Normal file
View File

@ -0,0 +1,10 @@
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 *

View File

@ -1 +0,0 @@
%PYTHON% setup.py install

View File

@ -1,28 +0,0 @@
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'

View File

@ -1,130 +0,0 @@
# 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."

View File

View File

View File

@ -1,223 +0,0 @@
# -*- 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)
]

View File

@ -1,362 +0,0 @@
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.

View File

@ -1,11 +0,0 @@
Migen manual
############
.. toctree::
:maxdepth: 2
introduction
fhdl
simulation
synthesis
reference

View File

@ -1,73 +0,0 @@
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.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

View File

@ -1,224 +0,0 @@
<?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>

Before

Width:  |  Height:  |  Size: 9.0 KiB

View File

@ -1,37 +0,0 @@
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:

View File

@ -1,6 +0,0 @@
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]

View File

@ -1,4 +0,0 @@
Synthesizing a Migen design
###########################
[To be written]

View File

@ -1,28 +0,0 @@
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()))

View File

@ -1,31 +0,0 @@
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}))

Some files were not shown because too many files have changed in this diff Show More