fhdl: inline synthesis directive support
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 22 Feb 2013 18:10:02 +0000 (19:10 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Fri, 22 Feb 2013 18:10:02 +0000 (19:10 +0100)
doc/fhdl.rst
examples/basic/psync.py
migen/fhdl/specials.py

index 91d545aa51580e2951543b4d25899c9fc748bb83..82f846ceaa1b4e518b066ff6b8d25a861f92ec64 100644 (file)
@@ -199,6 +199,13 @@ Options to ``get_port`` are:
 
 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)
+
 Fragments
 *********
 A "fragment" is a unit of logic, which is composed of:
index 4ca25f5d1e78638f98c1b36f06b8778c9eb0b09f..9ee09e947d1db83afcbec41704f4ee8e26dbe722 100644 (file)
@@ -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 @@ osync = [
        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)
index 829601d83cddc5097dbdb4f651c9972ac9ad5154..981b2bd4b8b90c8286a3d2ff5fe881fc8e4c9f80 100644 (file)
@@ -309,3 +309,18 @@ class Memory(Special):
                        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"