diff --git a/doc/fhdl.rst b/doc/fhdl.rst index 91d545aa5..82f846cea 100644 --- a/doc/fhdl.rst +++ b/doc/fhdl.rst @@ -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: diff --git a/examples/basic/psync.py b/examples/basic/psync.py index 4ca25f5d1..9ee09e947 100644 --- a/examples/basic/psync.py +++ b/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 @@ 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) diff --git a/migen/fhdl/specials.py b/migen/fhdl/specials.py index 829601d83..981b2bd4b 100644 --- a/migen/fhdl/specials.py +++ b/migen/fhdl/specials.py @@ -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"