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: m-labs/migen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: fcd48dafec4e
Choose a base ref
...
head repository: m-labs/migen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: b96eb339afd7
Choose a head ref
  • 2 commits
  • 8 files changed
  • 1 contributor

Commits on Jul 25, 2013

  1. fhdl: do not export Fragment

    Sebastien Bourdeauducq committed Jul 25, 2013
    Copy the full SHA
    b7ed19c View commit details
  2. fhdl: compact Instance syntax

    Sebastien Bourdeauducq committed Jul 25, 2013
    Copy the full SHA
    b96eb33 View commit details
Showing with 42 additions and 34 deletions.
  1. +7 −7 doc/fhdl.rst
  2. +1 −1 examples/basic/arrays.py
  3. +2 −1 migen/fhdl/module.py
  4. +20 −10 migen/fhdl/specials.py
  5. +3 −7 migen/fhdl/structure.py
  6. +3 −3 migen/fhdl/verilog.py
  7. +3 −3 migen/fhdl/visit.py
  8. +3 −2 migen/sim/generic.py
14 changes: 7 additions & 7 deletions doc/fhdl.rst
Original file line number Diff line number Diff line change
@@ -112,7 +112,7 @@ 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 fragment ultimately evaluates to a ``Signal`` for all possible values of the indices. This allows the creation of lists of structured data.
* 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: ::
@@ -134,15 +134,15 @@ 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 in fragments. 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.
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 a ``Fragment`` is ``Tristate``, and it behaves exactly like an instance of a tri-state I/O buffer that would be defined as follows: ::
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",
Instance.Inout("target", target),
Instance.Input("o", o),
Instance.Input("oe", oe),
Instance.Output("i", i)
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.
2 changes: 1 addition & 1 deletion examples/basic/arrays.py
Original file line number Diff line number Diff line change
@@ -21,6 +21,6 @@ def __init__(self):

ina = Array(Signal() for a in range(dx))
outa = Array(Signal() for a in range(dy))
self.specials += Instance("test", Instance.Output("O", outa[y]), Instance.Input("I", ina[x]))
self.specials += Instance("test", o_O=outa[y], i_I=ina[x])

print(verilog.convert(Example()))
3 changes: 2 additions & 1 deletion migen/fhdl/module.py
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
from itertools import combinations

from migen.fhdl.structure import *
from migen.fhdl.structure import _Fragment
from migen.fhdl.specials import Special
from migen.fhdl.tools import flat_iteration, rename_clock_domain

@@ -108,7 +109,7 @@ def __getattr__(self, name):
sim = [self.do_simulation]
except AttributeError:
sim = []
self._fragment = Fragment(sim=sim)
self._fragment = _Fragment(sim=sim)
return self._fragment
elif name == "_submodules":
self._submodules = []
30 changes: 20 additions & 10 deletions migen/fhdl/specials.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from operator import itemgetter

from migen.fhdl.structure import *
from migen.fhdl.size import bits_for, value_bits_sign
from migen.fhdl.tools import *
@@ -68,15 +70,6 @@ def get_tristate(self, target):
return Tristate(target, self.o, self.oe, self.i)

class Instance(Special):
def __init__(self, of, *items, name=""):
Special.__init__(self)
self.of = of
if name:
self.name_override = name
else:
self.name_override = of
self.items = items

class _IO:
def __init__(self, name, expr=None):
self.name = name
@@ -89,11 +82,28 @@ class Output(_IO):
pass
class InOut(_IO):
pass

class Parameter:
def __init__(self, name, value):
self.name = name
self.value = value

def __init__(self, of, *items, name="", **kwargs):
Special.__init__(self)
self.of = of
if name:
self.name_override = name
else:
self.name_override = of
self.items = list(items)
for k, v in sorted(kwargs.items(), key=itemgetter(1)):
item_type, item_name = k.split("_", maxsplit=1)
item_class = {
"i": Instance.Input,
"o": Instance.Output,
"io": Instance.InOut,
"p": Instance.Parameter
}[item_type]
self.items.append(item_class(item_name, v))

def get_io(self, name):
for item in self.items:
10 changes: 3 additions & 7 deletions migen/fhdl/structure.py
Original file line number Diff line number Diff line change
@@ -250,20 +250,17 @@ def __getitem__(self, key):

(SPECIAL_INPUT, SPECIAL_OUTPUT, SPECIAL_INOUT) = range(3)

class Fragment:
class _Fragment:
def __init__(self, comb=None, sync=None, specials=None, clock_domains=None, sim=None):
if comb is None: comb = []
if sync is None: sync = dict()
if specials is None: specials = set()
if clock_domains is None: clock_domains = _ClockDomainList()
if sim is None: sim = []

if isinstance(sync, list):
sync = {"sys": sync}

self.comb = comb
self.sync = sync
self.specials = set(specials)
self.specials = specials
self.clock_domains = _ClockDomainList(clock_domains)
self.sim = sim

@@ -273,8 +270,7 @@ def __add__(self, other):
newsync[k] = v[:]
for k, v in other.sync.items():
newsync[k].extend(v)
return Fragment(self.comb + other.comb, newsync,
return _Fragment(self.comb + other.comb, newsync,
self.specials | other.specials,
self.clock_domains + other.clock_domains,
self.sim + other.sim)

6 changes: 3 additions & 3 deletions migen/fhdl/verilog.py
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
from operator import itemgetter

from migen.fhdl.structure import *
from migen.fhdl.structure import _Operator, _Slice, _Assign
from migen.fhdl.structure import _Operator, _Slice, _Assign, _Fragment
from migen.fhdl.tools import *
from migen.fhdl.size import bits_for, flen
from migen.fhdl.namer import Namespace, build_namespace
@@ -232,7 +232,7 @@ def _call_special_classmethod(overrides, obj, method, *args, **kwargs):
return None

def _lower_specials_step(overrides, specials):
f = Fragment()
f = _Fragment()
lowered_specials = set()
for special in sorted(specials, key=lambda x: x.huid):
impl = _call_special_classmethod(overrides, special, "lower")
@@ -286,7 +286,7 @@ def convert(f, ios=None, name="top",
special_overrides=dict(),
create_clock_domains=True,
display_run=False):
if not isinstance(f, Fragment):
if not isinstance(f, _Fragment):
f = f.get_fragment()
if ios is None:
ios = set()
6 changes: 3 additions & 3 deletions migen/fhdl/visit.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from copy import copy

from migen.fhdl.structure import *
from migen.fhdl.structure import _Operator, _Slice, _Assign, _ArrayProxy
from migen.fhdl.structure import _Operator, _Slice, _Assign, _ArrayProxy, _Fragment

class NodeVisitor:
def visit(self, node):
@@ -27,7 +27,7 @@ def visit(self, node):
self.visit_If(node)
elif isinstance(node, Case):
self.visit_Case(node)
elif isinstance(node, Fragment):
elif isinstance(node, _Fragment):
self.visit_Fragment(node)
elif isinstance(node, (list, tuple)):
self.visit_statements(node)
@@ -127,7 +127,7 @@ def visit(self, node):
return self.visit_If(node)
elif isinstance(node, Case):
return self.visit_Case(node)
elif isinstance(node, Fragment):
elif isinstance(node, _Fragment):
return self.visit_Fragment(node)
elif isinstance(node, (list, tuple)):
return self.visit_statements(node)
5 changes: 3 additions & 2 deletions migen/sim/generic.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from migen.fhdl.std import *
from migen.fhdl.structure import _Fragment
from migen.fhdl import verilog
from migen.sim.ipc import *
from migen.sim import icarus
@@ -76,13 +77,13 @@ def _call_sim(fragment, simulator):

class Simulator:
def __init__(self, fragment, top_level=None, sim_runner=None, sockaddr="simsocket", **vopts):
if not isinstance(fragment, Fragment):
if not isinstance(fragment, _Fragment):
fragment = fragment.get_fragment()
if top_level is None:
top_level = TopLevel()
if sim_runner is None:
sim_runner = icarus.Runner()
self.fragment = fragment + Fragment(clock_domains=top_level.clock_domains)
self.fragment = fragment + _Fragment(clock_domains=top_level.clock_domains)
self.top_level = top_level
self.ipc = Initiator(sockaddr)
self.sim_runner = sim_runner