diff --git a/doc/fhdl.rst b/doc/fhdl.rst index 01bd9c79f..86cef407f 100644 --- a/doc/fhdl.rst +++ b/doc/fhdl.rst @@ -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,9 +134,9 @@ 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), diff --git a/migen/fhdl/module.py b/migen/fhdl/module.py index 02ea70878..bacaf91b9 100644 --- a/migen/fhdl/module.py +++ b/migen/fhdl/module.py @@ -2,6 +2,7 @@ import collections 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 @@ class Module: 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 = [] diff --git a/migen/fhdl/structure.py b/migen/fhdl/structure.py index 08500d8a4..7928316c8 100644 --- a/migen/fhdl/structure.py +++ b/migen/fhdl/structure.py @@ -250,7 +250,7 @@ class _ClockDomainList(list): (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() @@ -258,12 +258,9 @@ class Fragment: 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 @@ class Fragment: 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) - diff --git a/migen/fhdl/verilog.py b/migen/fhdl/verilog.py index 7a6f7ce68..f608338cd 100644 --- a/migen/fhdl/verilog.py +++ b/migen/fhdl/verilog.py @@ -2,7 +2,7 @@ from functools import partial 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() diff --git a/migen/fhdl/visit.py b/migen/fhdl/visit.py index 66c2fd94b..3965a1b62 100644 --- a/migen/fhdl/visit.py +++ b/migen/fhdl/visit.py @@ -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 @@ class NodeVisitor: 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 @@ class NodeTransformer: 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) diff --git a/migen/sim/generic.py b/migen/sim/generic.py index ab52e29eb..305873298 100644 --- a/migen/sim/generic.py +++ b/migen/sim/generic.py @@ -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