Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: amaranth-lang/amaranth
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 2f3852abf4ef^
Choose a base ref
...
head repository: amaranth-lang/amaranth
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 51ed974e2f44
Choose a head ref
  • 2 commits
  • 22 files changed
  • 1 contributor

Commits on May 4, 2020

  1. tracer: fix get_var_name() to work on toplevel attributes.

    E.g. this now works:
    
        >>> class dummy: pass
        >>> self = dummy()
        >>> self.foo = Signal()
        >>> self.foo.name
        'foo'
    whitequark committed May 4, 2020
    Copy the full SHA
    2f3852a View commit details

Commits on May 17, 2020

  1. [WIP] doc

    To render correctly, the docs require:
     * pygments/pygments#1441
     * readthedocs/sphinx_rtd_theme#838
    whitequark committed May 17, 2020
    Copy the full SHA
    51ed974 View commit details
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -13,6 +13,6 @@ __pycache__/
*.gtkw

# misc user-created
*.il
*.v
/*.il
/*.v
/build
1 change: 1 addition & 0 deletions doc/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
_build/
24 changes: 24 additions & 0 deletions doc/_code/led_blinker.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from nmigen import *


class LEDBlinker(Elaboratable):
def elaborate(self, platform):
m = Module()

led = platform.request("led")

half_freq = int(platform.default_clk_frequency // 2)
timer = Signal(range(half_freq + 1))

with m.If(timer == half_freq):
m.d.sync += led.eq(~led)
m.d.sync += timer.eq(0)
with m.Else():
m.d.sync += timer.eq(timer + 1)

return m
# --- BUILD ---
from nmigen_boards.icestick import *


ICEStickPlatform().build(LEDBlinker(), do_program=True)
79 changes: 79 additions & 0 deletions doc/_code/up_counter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
from nmigen import *


class UpCounter(Elaboratable):
"""
A 16-bit up counter with a fixed limit.
Parameters
----------
limit : int
The value at which the counter overflows.
Attributes
----------
en : Signal, in
The counter is incremented if ``en`` is asserted, and retains
its value otherwise.
ovf : Signal, out
``ovf`` is asserted when the counter reaches its limit.
"""
def __init__(self, limit):
self.limit = limit

# Ports
self.en = Signal()
self.ovf = Signal()

# State
self.count = Signal(16)

def elaborate(self, platform):
m = Module()

m.d.comb += self.ovf.eq(self.count == self.limit)

with m.If(self.en):
with m.If(self.ovf):
m.d.sync += self.count.eq(0)
with m.Else():
m.d.sync += self.count.eq(self.count + 1)

return m
# --- TEST ---
from nmigen.back.pysim import Simulator


dut = UpCounter(25)
def bench():
# Disabled counter should not overflow.
yield dut.en.eq(0)
for _ in range(30):
yield
assert not (yield dut.ovf)

# Once enabled, the counter should overflow in 25 cycles.
yield dut.en.eq(1)
for _ in range(25):
yield
assert not (yield dut.ovf)
yield
assert (yield dut.ovf)

# The overflow should clear in one cycle.
yield
assert not (yield dut.ovf)


sim = Simulator(dut)
sim.add_clock(1e-6) # 1 MHz
sim.add_sync_process(bench)
with sim.write_vcd("up_counter.vcd"):
sim.run()
# --- CONVERT ---
from nmigen.back import verilog


top = UpCounter(25)
with open("up_counter.v", "w") as f:
f.write(verilog.convert(top, ports=[top.en, top.ovf]))
49 changes: 49 additions & 0 deletions doc/_code/up_counter.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
(* generator = "nMigen" *)
module top(clk, rst, en, ovf);
(* src = "<nmigen-root>/nmigen/hdl/ir.py:526" *)
input clk;
(* src = "<nmigen-root>/nmigen/hdl/ir.py:526" *)
input rst;
(* src = "up_counter.py:26" *)
input en;
(* src = "up_counter.py:27" *)
output ovf;
(* src = "up_counter.py:30" *)
reg [15:0] count = 16'h0000;
(* src = "up_counter.py:30" *)
reg [15:0] \count$next ;
(* src = "up_counter.py:35" *)
wire \$1 ;
(* src = "up_counter.py:41" *)
wire [16:0] \$3 ;
(* src = "up_counter.py:41" *)
wire [16:0] \$4 ;
assign \$1 = count == (* src = "up_counter.py:35" *) 5'h19;
assign \$4 = count + (* src = "up_counter.py:41" *) 1'h1;
always @(posedge clk)
count <= \count$next ;
always @* begin
\count$next = count;
(* src = "up_counter.py:37" *)
casez (en)
/* src = "up_counter.py:37" */
1'h1:
(* src = "up_counter.py:38" *)
casez (ovf)
/* src = "up_counter.py:38" */
1'h1:
\count$next = 16'h0000;
/* src = "up_counter.py:40" */
default:
\count$next = \$3 [15:0];
endcase
endcase
(* src = "<nmigen-root>/nmigen/hdl/xfrm.py:518" *)
casez (rst)
1'h1:
\count$next = 16'h0000;
endcase
end
assign \$3 = \$4 ;
assign ovf = \$1 ;
endmodule
File renamed without changes.
File renamed without changes.
Binary file added doc/_images/up_counter_gtkwave.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions doc/_static/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/* Some of our section titles are looong */
.wy-menu-vertical { width: 340px; }

/* Many of our diagnostics are even longer */
.rst-content pre.literal-block, .rst-content div[class^="highlight"] pre, .rst-content .linenodiv pre { white-space: pre-wrap; }
27 changes: 27 additions & 0 deletions doc/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import os, sys
sys.path.insert(0, os.path.abspath("."))

import nmigen

project = "nMigen core"
version = nmigen.__version__
release = version.split("+")[0]
copyright = "2020, nMigen developers"

extensions = [
"sphinx.ext.intersphinx",
"sphinx.ext.doctest",
"sphinx.ext.todo",
"sphinx_rtd_theme",
]

with open(".gitignore") as f:
exclude_patterns = [line.strip() for line in f.readlines()]

intersphinx_mapping = {"python": ("https://docs.python.org/3", None)}

todo_include_todos = True

html_theme = "sphinx_rtd_theme"
html_static_path = ["_static"]
html_css_files = ["custom.css"]
20 changes: 20 additions & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
The nMigen core manual
######################

.. toctree::
:maxdepth: 2

intro
install
start
lang

Index
=====

* :ref:`genindex`

Search
======

* :ref:`search`
121 changes: 121 additions & 0 deletions doc/install.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
Installation
############

System requirements
===================

nMigen requires Python 3.6; it works on CPython_ 3.6 (or newer), and works faster on PyPy3.6_ 7.2 (or newer).

Simulating nMigen code requires no additional software. However, a waveform viewer like GTKWave_ is invaluable for debugging.

Converting nMigen code to Verilog requires Yosys_ 0.9 (or newer).

Synthesizing, placing and routing an nMigen design for an FPGA requires Yosys_ 0.9 (or newer), as well as the FPGA family specific toolchain.

.. TODO: Link to FPGA family docs here
.. _CPython: https://www.python.org/
.. _PyPy3.6: https://www.pypy.org/
.. _Yosys: http://www.clifford.at/yosys/
.. _GTKWave: http://gtkwave.sourceforge.net/


Installing prerequisites
========================

... on Windows
--------------

.. todo::

Determine what's appropriate here (do we put Python in PATH? what about Yosys? is there something better than GTKWave? do we just give up and suggest WSL?)


... on Debian Linux
-------------------

nMigen works on Debian 10 or newer. The required version of Yosys is available in the main repository since Debian 11, but requires the Backports_ repository on Debian 10. Run:

.. note: debian 10 provides: python3 3.7.3, yosys 0.8 (yosys 0.9 in backports)
.. note: debian 11 provides: python3 3.8.2, yosys 0.9
.. code-block:: shell
$ sudo apt-get install python3-pip yosys gtkwave
.. _Backports: https://wiki.debian.org/Backports


... on Ubuntu Linux
-------------------

nMigen works on Ubuntu 20.04 LTS or newer.

.. note: ubuntu 20.04 provides: python3 3.8.2, yosys 0.9
.. code-block:: shell
$ sudo apt-get install python3-pip yosys gtkwave
... on macOS
------------

nMigen works best with Homebrew_. Run:

.. code-block:: shell
$ brew install python yosys gtkwave
.. _Homebrew: https://brew.sh


... on other platforms
----------------------

Refer to the `Yosys README`_ for detailed build instructions.

.. _Yosys README: https://github.com/YosysHQ/yosys/#setup


Installing nMigen
=================

The latest release of nMigen should work well for most applications. Any development snapshot---commit from the ``master`` branch of nMigen---should be similarly reliable, but is likely to include experimental API changes that will be in flux until the next release. With that in mind, development snapshots can be used to try out new functionality or to avoid bugs fixed since the last release.


Latest release
--------------

To install the latest release of nMigen, run:

.. code-block:: shell
$ pip3 install --upgrade nmigen
Development snapshot
--------------------

To install a development snapshot of nMigen for the first time, run:

.. code-block:: shell
$ git clone https://github.com/nmigen/nmigen
$ cd nmigen
$ pip3 install --editable .
Any changes made to the ``nmigen`` directory will immediately affect any code that uses nMigen. To update the snapshot, run:

.. code-block:: shell
$ cd nmigen
$ git pull --ff-only origin master
Installing board definitions
=============================

.. todo::

Explain how to install `<https://github.com/nmigen/nmigen-boards>`_.
Loading