Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 2 commits
  • 3 files changed
  • 0 comments
  • 1 contributor
52  doc/fhdl.rst
Source Rendered
@@ -132,8 +132,27 @@ and write it with: ::
132 132
 
133 133
 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.
134 134
 
135  
-Special elements
136  
-****************
  135
+Specials
  136
+********
  137
+
  138
+Tri-state I/O
  139
+=============
  140
+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.
  141
+
  142
+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: ::
  143
+
  144
+  Instance("Tristate",
  145
+    Instance.Inout("target", target),
  146
+    Instance.Input("o", o),
  147
+    Instance.Input("oe", oe),
  148
+    Instance.Output("i", i)
  149
+  )
  150
+
  151
+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.
  152
+
  153
+A ``Tristate`` object can be created from a ``TSTriple`` object by calling the ``get_tristate`` method.
  154
+
  155
+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.
137 156
 
138 157
 Instances
139 158
 =========
@@ -178,26 +197,14 @@ Options to ``get_port`` are:
178 197
 
179 198
 * ``clock_domain`` (default: ``"sys"``): the clock domain used for reading and writing from this port.
180 199
 
181  
-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.
  200
+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.
182 201
 
183  
-Tri-state I/O
184  
-=============
185  
-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.
  202
+Inline synthesis directives
  203
+===========================
186 204
 
187  
-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: ::
  205
+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: ::
188 206
 
189  
-  Instance("Tristate",
190  
-    Instance.Inout("target", target),
191  
-    Instance.Input("o", o),
192  
-    Instance.Input("oe", oe),
193  
-    Instance.Output("i", i)
194  
-  )
195  
-
196  
-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.
197  
-
198  
-A ``Tristate`` object can be created from a ``TSTriple`` object by calling the ``get_tristate`` method.
199  
-
200  
-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.
  207
+  SynthesisDirective("attribute keep of {clksig} is true", clksig=clock_domain.clk)
201 208
 
202 209
 Fragments
203 210
 *********
@@ -205,15 +212,15 @@ A "fragment" is a unit of logic, which is composed of:
205 212
 
206 213
 * A list of combinatorial statements.
207 214
 * A list of synchronous statements, or a clock domain name -> synchronous statements dictionary.
208  
-* A list of instances.
209  
-* A list of tri-states.
210  
-* A list of memories.
  215
+* A set of specials (memories, instances, etc.)
211 216
 * A list of simulation functions (see :ref:`simulating`).
212 217
 
213 218
 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.
214 219
 
215 220
 Fragments can be passed to the back-end for conversion to Verilog.
216 221
 
  222
+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.
  223
+
217 224
 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.
218 225
 
219 226
 Conversion for synthesis
@@ -225,7 +232,6 @@ Migen does not provide support for any specific synthesis tools or ASIC/FPGA tec
225 232
 
226 233
 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.
227 234
 
228  
-
229 235
 Multi-clock-domain designs
230 236
 **************************
231 237
 
11  examples/basic/psync.py
... ...
@@ -1,4 +1,5 @@
1 1
 from migen.fhdl.structure import *
  2
+from migen.fhdl.specials import SynthesisDirective
2 3
 from migen.fhdl import verilog
3 4
 
4 5
 # convert pulse into level change
@@ -14,10 +15,16 @@
14 15
 	slevel[2].eq(slevel[1])
15 16
 ]
16 17
 
  18
+# disable shift register extraction
  19
+disable_srl = {
  20
+	SynthesisDirective("attribute shreg_extract of {signal} is no", signal=slevel[0]),
  21
+	SynthesisDirective("attribute shreg_extract of {signal} is no", signal=slevel[1])
  22
+}
  23
+
17 24
 # regenerate pulse
18 25
 o = Signal()
19 26
 comb = [o.eq(slevel[1] ^ slevel[2])]
20 27
 
21  
-f = Fragment(comb, {"i": isync, "o": osync})
22  
-v = verilog.convert(f, ios={i, o})
  28
+f = Fragment(comb, {"i": isync, "o": osync}, specials=disable_srl)
  29
+v = verilog.convert(f, {i, o})
23 30
 print(v)
15  migen/fhdl/specials.py
@@ -309,3 +309,18 @@ def emit_verilog(memory, ns, clock_domains):
309 309
 			r += "end\n\n"
310 310
 		
311 311
 		return r
  312
+
  313
+class SynthesisDirective(Special):
  314
+	def __init__(self, template, **signals):
  315
+		Special.__init__(self)
  316
+		self.template = template
  317
+		self.signals = signals
  318
+
  319
+	def list_ios(self, ins, outs, inouts):
  320
+		return set()
  321
+
  322
+	@staticmethod
  323
+	def emit_verilog(directive, ns, clock_domains):
  324
+		name_dict = dict((k, ns.get_name(sig)) for k, sig in directive.signals.items())
  325
+		formatted = directive.template.format(**name_dict)
  326
+		return "// synthesis " + formatted + "\n"

No commit comments for this range

Something went wrong with that request. Please try again.