Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 2 commits
  • 3 files changed
  • 0 commit comments
  • 1 contributor
Showing with 53 additions and 25 deletions.
  1. +29 −23 doc/fhdl.rst
  2. +9 −2 examples/basic/psync.py
  3. +15 −0 migen/fhdl/specials.py
View
52 doc/fhdl.rst
@@ -132,8 +132,27 @@ and write it with: ::
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.
-Special elements
-****************
+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.
+
+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: ::
+
+ Instance("Tristate",
+ Instance.Inout("target", target),
+ Instance.Input("o", o),
+ Instance.Input("oe", oe),
+ Instance.Output("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
=========
@@ -178,26 +197,14 @@ Options to ``get_port`` are:
* ``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 generator function can be overriden using the ``memory_handler`` parameter of the conversion function.
+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.
-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.
+Inline synthesis directives
+===========================
-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: ::
+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: ::
- Instance("Tristate",
- Instance.Inout("target", target),
- Instance.Input("o", o),
- Instance.Input("oe", oe),
- Instance.Output("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 generator function can be overriden using the ``tristate_handler`` parameter of the conversion function.
+ SynthesisDirective("attribute keep of {clksig} is true", clksig=clock_domain.clk)
Fragments
*********
@@ -205,15 +212,15 @@ A "fragment" is a unit of logic, which is composed of:
* A list of combinatorial statements.
* A list of synchronous statements, or a clock domain name -> synchronous statements dictionary.
-* A list of instances.
-* A list of tri-states.
-* A list of memories.
+* A set of specials (memories, instances, etc.)
* A list of simulation functions (see :ref:`simulating`).
Fragments can reference arbitrary signals, including signals that are referenced in other fragments. Fragments can be combined using the "+" operator, which returns a new fragment containing the concatenation of each matched pair of lists.
Fragments can be passed to the back-end for conversion to Verilog.
+Specials are using a set, not a list, to facilitate sharing of certain elements by different components of a design. For example, one component may use a static memory buffer that another component would map onto a bus, using another port to that memory. Both components should reference the memory object in their fragments, but that memory should appear only once in the final design. The Python ``set`` provides this functionality.
+
By convention, classes that generate logic implement a method called ``get_fragment``. When called, this method builds a new fragment implementing the desired functionality of the class, and returns it. This convention allows fragments to be built automatically by combining the fragments from all relevant objects in the local scope, by using the autofragment module.
Conversion for synthesis
@@ -225,7 +232,6 @@ Migen does not provide support for any specific synthesis tools or ASIC/FPGA tec
The Mibuild package, available separately from the Migen website, provides scripts to interface third-party FPGA tools to Migen and a database of boards for the easy deployment of designs.
-
Multi-clock-domain designs
**************************
View
11 examples/basic/psync.py
@@ -1,4 +1,5 @@
from migen.fhdl.structure import *
+from migen.fhdl.specials import SynthesisDirective
from migen.fhdl import verilog
# convert pulse into level change
@@ -14,10 +15,16 @@
slevel[2].eq(slevel[1])
]
+# disable shift register extraction
+disable_srl = {
+ SynthesisDirective("attribute shreg_extract of {signal} is no", signal=slevel[0]),
+ SynthesisDirective("attribute shreg_extract of {signal} is no", signal=slevel[1])
+}
+
# regenerate pulse
o = Signal()
comb = [o.eq(slevel[1] ^ slevel[2])]
-f = Fragment(comb, {"i": isync, "o": osync})
-v = verilog.convert(f, ios={i, o})
+f = Fragment(comb, {"i": isync, "o": osync}, specials=disable_srl)
+v = verilog.convert(f, {i, o})
print(v)
View
15 migen/fhdl/specials.py
@@ -309,3 +309,18 @@ def emit_verilog(memory, ns, clock_domains):
r += "end\n\n"
return r
+
+class SynthesisDirective(Special):
+ def __init__(self, template, **signals):
+ Special.__init__(self)
+ self.template = template
+ self.signals = signals
+
+ def list_ios(self, ins, outs, inouts):
+ return set()
+
+ @staticmethod
+ def emit_verilog(directive, ns, clock_domains):
+ name_dict = dict((k, ns.get_name(sig)) for k, sig in directive.signals.items())
+ formatted = directive.template.format(**name_dict)
+ return "// synthesis " + formatted + "\n"

No commit comments for this range

Something went wrong with that request. Please try again.