Typo in CMakeLists.txt : AND instead of "and".

This commit is contained in:
Jean-Paul Chaput 2018-06-06 23:22:18 +02:00
parent 767407736d
commit c5034a9156
12 changed files with 706 additions and 7 deletions

View File

@ -7,7 +7,7 @@
tabs.css
)
if (BUILD_DOC and DOXYGEN_FOUND)
if (BUILD_DOC AND DOXYGEN_FOUND)
add_custom_target ( documentation ALL
cd ${CRLCORE_SOURCE_DIR}/doc/crlcore
&& ${DOXYGEN_EXECUTABLE} doxyfile

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,36 @@
.. -*- Mode: rst -*-
.. include:: ../etc/definitions.rst
.. include:: ./definitions.rst
9. Advanced Topics
==================
This is a place holder as well as a reminder to myself to write this part of
the documentation.
9.1 Occurrence
~~~~~~~~~~~~~~
The trans-hierarchical workhorse.
9.2 RoutingPads
~~~~~~~~~~~~~~~
Unlike the Plugs_ that only make connexions between two **adjacent**
hierarchical levels, RoutingPads_ can refer to a deeply buried terminal.
9.3 HyperNets
~~~~~~~~~~~~~
This class is part of the *virtual flattening* mechanisms, it allows to
go through all the components of a trans-hierarchical net.
9.4 Miscellaeous trans-hierarchical functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For a starter, how to get all the leaf cells...

View File

@ -0,0 +1,399 @@
.. -*- Mode: rst -*-
.. include:: ../etc/definitions.rst
.. include:: ./definitions.rst
6. Making a hierarchical Cell -- Netlist
========================================
To illustrate the topic, we will build the netlist of a fulladder from
standard cell.
|fulladder_1|
6.1 Creating an Instance_
~~~~~~~~~~~~~~~~~~~~~~~~~
Creating an Instance_ is straigthforward, the constructor needs only three
parameters:
#. The Cell_ **into which** the instance is to be created.
#. The name of the instance.
#. The **master cell**, the Cell_ model it refers to. The master cell
will be part of the hierarchical level just below the ``fulladder``
cell.
.. note:: Do not confuse the cell the instance is create into (``fulladder``)
and the cells it refers to (the *master cell* ``xr2_x2``).
.. code-block:: Python
af = AllianceFramework.get()
xr2_x2 = af.getCell( 'xr2_x1', Catalog.State.Views )
fulladder = af.createCell( 'fulladder' )
xr2_1 = Instance.create( fulladder, 'xr2_1', xr2_x2 )
6.2 Creating Nets and connecting to Instances
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An Instance_ as one Plug_ for each external net of the *master cell*.
The plug allows to create a **logical** connexion bewteen a Net_ of
``fulladder`` and a net from an Instance_ *master cell*.
A plug is somewhat equivalent to an *instance terminal* in others
well known databases.
Therefore, a plug is related to two nets:
#. The net of the *master cell* it is linked to. Obviously that
net cannot be changed. You can access the master net with the
function ``plug.getMasterNet()``.
#. The net of ``fulladder`` the plug is connected to. This can
be set, it is how we build the netlist. To set the net, use
the function ``plug.setNet( net )``. It the argument is ``None``,
the plug is *disconnected*.
To find the plug of an instance associated to a given net in
the *master cell*, use ``instance.getPlug( masterNet )``.
The ``masterNet`` argument being an object of class net (not
it's name).
Building the :cb:`a` net of ``fulladder``:
.. code-block:: Python
a = Net.create( fulladder, "a" )
a.setExternal( True )
xr2_1.getPlug( xr2_x2.getNet("i0") ).setNet( a )
a2_1 .getPlug( a2_x2.getNet("i0") ).setNet( a )
.. note:: **Limitation of Hurricane Netlists.** There is no explicit
terminal object in the |Hurricane| database. Plugs are
generated *on the fly* for each *external net* of the
instance. One important consequence is that a *net*
cannot appear on the interface as two differently named
terminals (sometimes referred as *weekly connected*
terminals). There is a strict bijection between external
nets and plugs.
While it may be restrictive, it enforce cleaner designs
and make it possible for the HyperNet_ concept/class.
6.3 Power supplies special case
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
For supplies, it may be tedious to connect the Plugs_ of each cell one by one
(and create a lot of uneeded objects). To avoid that, we may use **Named
connections**. If a signal in ``fulladder`` is set to *global*, then it will
be considered as connected to any signal with the *same name* and *global* in
the master cell of the instances.
.. code-block:: Python
vdd = Net.create( fulladder, "vdd" )
vdd.setExternal( True )
vdd.setGlobal ( True ) # Will be connected to all the instances.
6.4 Creating the physical view of a Cell netlist
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Even if loaded in the viewer, an Instance will not be displayed
until it is placed.
6.4.1 Transformation
--------------------
To place an Instance, we apply a Transformation_ to the coordinate system
of the *master cell*. A transformation is composed of two operations :
#. An Orientation_, which can be a symmetry or a rotation (or a combination
of those two). The Orientation **is applied first** to the coordinate
system of the *master cell*. The complete list of Orientation and their
codes are given on the Orientation documentation page.
#. A **Translation**, applied in second. Translation are represented by
Points_.
The transformation is a change of coordinate system, be aware that if the
abutment box lower left corner of the *master* cell is **not** at ``(0,0)``
the result of the Transformation may not be what you expect. To simplificate
the computation of the transformation of an instance, always place the
lower left corner of the abutment box at ``(0,0)``
6.4.2 Placing an Instance
-------------------------
Assuming that we want to place the cells of the ``fulladder`` into two rows,
that the abutment box lower left corner is at ``(0,0)`` (same for the
``xr2_x2`` *master cell* layout). Here is the code to place the ``xr2_1``
instance to left of the second row.
Setting the translation on an Instance_ is not enough to make it be displayed,
we also must set it's *placement status* to ``Instance.PlacementStatus.PLACED``.
.. code-block:: Python
xr2_1.setTransformation( Transformation( DbU.fromLambda( 0.0)
, DbU.fromLambda(100.0)
, Transformation.Orientation.MY ) )
xr2_1.setPlacementStatus( Instance.PlacementStatus.PLACED )
6.4.3 Nets -- From Plugs to RoutingPads
---------------------------------------
As was stated before, Plugs_ represent a logical connexion between two
levels of hierarchy. To make the physical connexion to the *master net*
in the instance, we now must create, in the ``fulladder``, a special
component which is a kind of *reference* to a component of the
*master net* (in the master cell).
The so called *special component* is a RoutingPad_.
The ``RoutingPad`` can be considered as an equivalent to ``pin`` in others
well known databases.
.. code-block:: Python
rp = RoutingPad.create( a
, Occurrence( xr2_1.getPlug( xr2_x2.getNet("i0")) )
, RoutingPad.BiggestArea )
For the second parameter, we must pass an Occurrence_. Occurrence objects will
be explained in detail later, for now, suffice to say that we must construct the
Occurrence object with one parameter : the Plug_ for which we want to create a
physical connexion.
The RoutingPad_ ``rp`` will be a component of the ``a`` net.
The third argument ask the constructor of the RoutingPad_ to select in the
master net, the component which has the biggest area.
.. note:: **Component selection.** Not all the components of a net can be
selected for connexion through a RoutingPad_. The candidates must
have been flagged with the NetExternalComponents_ class.
See `3.6.3 Creating a Component`_.
6.4.4 Nets -- Regular wiring
----------------------------
After the creation of the RoutingPads_, the wiring is to be created with
ordinary layout components (Horizontal_, Vertical_ and Contact_ possibly
articulated). Here is the complete code for net ``a``. We made an articulated
layout where contacts are created over RoutingPads_ then segments over
contacts.
.. code-block:: Python
# Build wiring for a.
# Create RoutingPads first.
rp1 = RoutingPad.create( a
, Occurrence( xr2_1.getPlug( xr2_x2.getNet("i0")) )
, RoutingPad.BiggestArea )
rp2 = RoutingPad.create( a
, Occurrence( a2_1.getPlug( a2_x2.getNet("i0")) )
, RoutingPad.BiggestArea )
# Then regular wiring.
contact1 = Contact.create( rp1, via12, toDbU( 0.0), toDbU(-15.0) )
contact2 = Contact.create( rp2, via12, toDbU( 0.0), toDbU( 10.0) )
turn = Contact.create( a , via23, toDbU(10.0), toDbU( 35.0) )
Horizontal.create( contact2, turn , metal2, toDbU(35.0), toDbU(2.0) )
Vertical .create( turn , contact1 , metal3, toDbU(10.0), toDbU(2.0) )
.. note:: In order to better see the layout of the wiring only, open the
``Controller`` and in the :fboxtt:`Filter` tab, uncheck
:fboxtt:`Process Terminal Cells`.
6.5 The Complete Example File
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The example file ``fulladder.py`` can be found in the ``share/doc/coriolis2/examples/scripts/``
directory (under the the root of the |Coriolis| installation).
.. code-block:: Python
#!/usr/bin/python
import sys
from Hurricane import *
from CRL import *
def toDbU ( l ): return DbU.fromLambda(l)
def doBreak ( level, message ):
UpdateSession.close()
Breakpoint.stop( level, message )
UpdateSession.open()
def buildFulladder ( editor ):
# Get the Framework and all the master cells.
af = AllianceFramework.get()
xr2_x2 = af.getCell( 'xr2_x1', Catalog.State.Views )
a2_x2 = af.getCell( 'a2_x2' , Catalog.State.Views )
o2_x2 = af.getCell( 'o2_x2' , Catalog.State.Views )
UpdateSession.open()
fulladder = af.createCell( 'fulladder' )
fulladder.setAbutmentBox( Box( toDbU(0.0), toDbU(0.0), toDbU(90.0), toDbU(100.0) ) )
if editor:
UpdateSession.close()
editor.setCell( fulladder )
editor.fit()
UpdateSession.open()
# Create Instances.
a2_1 = Instance.create( fulladder, 'a2_1', a2_x2 )
a2_2 = Instance.create( fulladder, 'a2_2', a2_x2 )
xr2_1 = Instance.create( fulladder, 'xr2_1', xr2_x2 )
xr2_2 = Instance.create( fulladder, 'xr2_2', xr2_x2 )
o2_1 = Instance.create( fulladder, 'o2_1', o2_x2 )
# Create Nets.
vss = Net.create( fulladder, "vss" )
vss.setExternal( True )
vss.setGlobal ( True )
vdd = Net.create( fulladder, "vdd" )
vdd.setExternal( True )
vdd.setGlobal ( True )
cin = Net.create( fulladder, "cin" )
cin.setExternal( True )
xr2_2.getPlug( xr2_x2.getNet('i0') ).setNet( cin )
a2_2 .getPlug( a2_x2.getNet('i0') ).setNet( cin )
a = Net.create( fulladder, 'a' )
a.setExternal( True )
xr2_1.getPlug( xr2_x2.getNet('i0') ).setNet( a )
a2_1 .getPlug( a2_x2.getNet('i0') ).setNet( a )
b = Net.create( fulladder, 'b' )
b.setExternal( True )
xr2_1.getPlug( xr2_x2.getNet('i1') ).setNet( b )
a2_1 .getPlug( a2_x2.getNet('i1') ).setNet( b )
sout_1 = Net.create( fulladder, 'sout_1' )
xr2_1.getPlug( xr2_x2.getNet('q' ) ).setNet( sout_1 )
xr2_2.getPlug( xr2_x2.getNet('i1') ).setNet( sout_1 )
a2_2 .getPlug( a2_x2.getNet('i1') ).setNet( sout_1 )
carry_1 = Net.create( fulladder, 'carry_1' )
a2_1.getPlug( a2_x2.getNet('q' ) ).setNet( carry_1 )
o2_1.getPlug( o2_x2.getNet('i1') ).setNet( carry_1 )
carry_2 = Net.create( fulladder, 'carry_2' )
a2_2.getPlug( a2_x2.getNet('q' ) ).setNet( carry_2 )
o2_1.getPlug( o2_x2.getNet('i0') ).setNet( carry_2 )
sout = Net.create( fulladder, 'sout' )
sout.setExternal( True )
xr2_2.getPlug( xr2_x2.getNet('q') ).setNet( sout )
cout = Net.create( fulladder, 'cout' )
cout.setExternal( True )
o2_1.getPlug( o2_x2.getNet('q') ).setNet( cout )
# Instances placement.
a2_1.setTransformation( Transformation( toDbU(0.0)
, toDbU(0.0)
, Transformation.Orientation.ID ) )
a2_1.setPlacementStatus( Instance.PlacementStatus.PLACED )
doBreak( 1, 'Placed a2_1' )
xr2_1.setTransformation( Transformation( toDbU( 0.0)
, toDbU(100.0)
, Transformation.Orientation.MY ) )
xr2_1.setPlacementStatus( Instance.PlacementStatus.PLACED )
doBreak( 1, 'Placed xr2_1' )
a2_2.setTransformation( Transformation( toDbU(25.0)
, toDbU( 0.0)
, Transformation.Orientation.ID ) )
a2_2.setPlacementStatus( Instance.PlacementStatus.PLACED )
doBreak( 1, 'Placed a2_2' )
xr2_2.setTransformation( Transformation( toDbU( 45.0)
, toDbU(100.0)
, Transformation.Orientation.MY ) )
xr2_2.setPlacementStatus( Instance.PlacementStatus.PLACED )
doBreak( 1, 'Placed xr2_2' )
o2_1.setTransformation( Transformation( toDbU(65.0)
, toDbU( 0.0)
, Transformation.Orientation.ID ) )
o2_1.setPlacementStatus( Instance.PlacementStatus.PLACED )
doBreak( 1, 'Placed o2_1' )
# Add filler cells.
tie_x0 = af.getCell( 'tie_x0', Catalog.State.Views )
rowend_x0 = af.getCell( 'rowend_x0', Catalog.State.Views )
filler_1 = Instance.create( fulladder, 'filler_1', tie_x0 )
filler_2 = Instance.create( fulladder, 'filler_2', rowend_x0 )
filler_1.setTransformation( Transformation( toDbU(50.0)
, toDbU( 0.0)
, Transformation.Orientation.ID ) )
filler_1.setPlacementStatus( Instance.PlacementStatus.PLACED )
filler_2.setTransformation( Transformation( toDbU(60.0)
, toDbU( 0.0)
, Transformation.Orientation.ID ) )
filler_2.setPlacementStatus( Instance.PlacementStatus.PLACED )
doBreak( 1, 'Filler cell placeds' )
# Getting the layers.
technology = DataBase.getDB().getTechnology()
metal2 = technology.getLayer( "METAL2" )
metal3 = technology.getLayer( "METAL3" )
via12 = technology.getLayer( "VIA12" )
via23 = technology.getLayer( "VIA23" )
# Build wiring for a.
# Create RoutingPads first.
rp1 = RoutingPad.create( a
, Occurrence( xr2_1.getPlug( xr2_x2.getNet("i0")) )
, RoutingPad.BiggestArea )
rp2 = RoutingPad.create( a
, Occurrence( a2_1.getPlug( a2_x2.getNet("i0")) )
, RoutingPad.BiggestArea )
# Then regular wiring.
contact1 = Contact.create( rp1, via12, toDbU( 0.0), toDbU(-15.0) )
contact2 = Contact.create( rp2, via12, toDbU( 0.0), toDbU( 10.0) )
turn = Contact.create( a , via23, toDbU(10.0), toDbU( 35.0) )
Horizontal.create( contact2, turn , metal2, toDbU(35.0), toDbU(2.0) )
Vertical .create( turn , contact1 , metal3, toDbU(10.0), toDbU(2.0) )
UpdateSession.close()
af.saveCell( fulladder, Catalog.State.Views )
return
def ScriptMain ( **kw ):
editor = None
if kw.has_key('editor') and kw['editor']:
editor = kw['editor']
buildFulladder( editor )
return True

View File

@ -0,0 +1,51 @@
.. -*- Mode: rst -*-
.. include:: ../etc/definitions.rst
.. include:: ./definitions.rst
7. Working in real mode
=======================
The AllianceFramework_ only manage *symbolic* layout as |Alliance| do.
But |Coriolis| is also able to work directly in *real* mode, meaning
that distances will be expresseds in microns instead of lambdas.
The *real* mode will be illustrated by working with the FreePDK45_.
We will assume that the FreePDK45_ archives is installed under: ::
/home/dks/
7.1 Loading a |LEF| file
~~~~~~~~~~~~~~~~~~~~~~~~
Importing a |LEF| file is simple, you just call the static function
``LefImport.load()``. Multiple |LEF| file can be imported one after
another.
.. code-block:: Python
# You must set "DKsdir" to where you did install the NCSU FreePDK 45nm DK.
DKsdir = '/home/dks'
library = LefImport.load( DKsdir + '/FreePDK45/osu_soc/lib/files/gscl45nm.lef' )
.. note:: **Technology checking.** The first imported |LEF| file must contains the
technology. The technology described in the |LEF| file will be checked
against the one configured in the running instance of |Coriolis| to look
for any discrepencies.
7.2 Loading a |Blif| file -- |Yosys|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The |Blif| format is generated by the Yosys_ logic synthetizer. Here again, it is
pretty straightforward: call the static function ``Blif.load()``. If you did make
your synthesis on a cell library not managed by AllianceFramework_, For example
the one of the FreePDK45, you must load it prior to calling the |Blif| loader.
.. code-block:: Python
cell = Blif.load( 'snx' ) # load "snx.blif" in the working directory.

View File

@ -0,0 +1,213 @@
.. -*- Mode: rst -*-
.. include:: ../etc/definitions.rst
.. include:: ./definitions.rst
8. Tool Engines (CRL Core)
==========================
The ToolEngine_ class is the base class for all tools developpeds in
|Coriolis|. In the rest of the tutorial we will use the names ``tool``
or ``engine`` as synonyms.
8.1 Placer -- Etesian
~~~~~~~~~~~~~~~~~~~~~
To run the placer, create the |Etesian| engine, then call the ``place()``
function.
.. code-block:: Python
import Etesian
# [...]
etesian = Etesian.EtesianEngine.create(cell)
etesian.place()
You can configure the placer in two ways:
#. Prior to the creation of the engine, setup an abutment for the cell.
The placer will fit the cells into that area. If the area is too
small, it will issue an error.
#. Setup |Etesian| parameters through the ``settings.py`` configuration
file. For example:
.. code-block:: Python
parametersTable = \
( ("etesian.effort" , TypeEnumerate , 2 )
, ('etesian.uniformDensity' , TypeBool , True )
, ('etesian.spaceMargin' , TypePercentage, 3.0 )
, ('etesian.aspectRatio' , TypePercentage, 100.0 )
)
With this setup, the cells will be spread uniformally over the
area (``etesian.uniformDensity``), with ``3.0%`` of free space
added and an aspect ratio of ``100%`` (square shape).
8.1 Router -- Katana
~~~~~~~~~~~~~~~~~~~~
Like for |Etesian|, you have to create the engine on the cell then call
the sequence of functions detailed below.
.. note:: **Kite vs. Katana.** There are currently two router in |Coriolis|,
|Kite| is the old one and digital only. |Katana| is a re-implementation
with support for mixed routing (digital **and** analog).
Until |Katana| is fully implemented we keep both of them.
.. code-block:: Python
import Anabatic
import Katana
# [...]
katana = Katana.KatanaEngine.create(cell)
katana.digitalInit ()
katana.runGlobalRouter ()
katana.loadGlobalRouting( Anabatic.EngineLoadGrByNet )
katana.layerAssign ( Anabatic.EngineNoNetLayerAssign )
katana.runNegociate ( Katana.Flags.NoFlags )
8.2 A Complete Example
~~~~~~~~~~~~~~~~~~~~~~~
The example file ``toolengines.py`` can be found in the ``share/doc/coriolis2/examples/scripts/``
directory (under the the root of the |Coriolis| installation).
This script automatically place and route the ``fulladder`` netlist as seen
previously. The call to the ToolEngines_ is made inside the new function
``placeAndRoute()``.
.. note:: As the ``ToolEngine`` take care of opening and closing UpdateSession_, we
do not need the wrapper function ``doBreak()`` around the breakpoints.
We directly call Breakpoint_.
.. note:: The space margin for this example is very high (``30%``), it's only
because it's too small for the placer to run correctly. For normal
case it is around ``3%``.
.. code-block:: Python
#!/usr/bin/python
import sys
from Hurricane import *
from CRL import *
import Etesian
import Anabatic
import Katana
# Everybody needs it.
af = AllianceFramework.get()
def toDbU ( l ): return DbU.fromLambda(l)
def buildFulladder ( editor ):
# Get the Framework and all the master cells.
xr2_x2 = af.getCell( 'xr2_x1', Catalog.State.Views )
a2_x2 = af.getCell( 'a2_x2' , Catalog.State.Views )
o2_x2 = af.getCell( 'o2_x2' , Catalog.State.Views )
UpdateSession.open()
fulladder = af.createCell( 'fulladder' )
# Create Instances.
a2_1 = Instance.create( fulladder, 'a2_1', a2_x2 )
a2_2 = Instance.create( fulladder, 'a2_2', a2_x2 )
xr2_1 = Instance.create( fulladder, 'xr2_1', xr2_x2 )
xr2_2 = Instance.create( fulladder, 'xr2_2', xr2_x2 )
o2_1 = Instance.create( fulladder, 'o2_1', o2_x2 )
# Create Nets.
vss = Net.create( fulladder, "vss" )
vss.setExternal( True )
vss.setGlobal ( True )
vdd = Net.create( fulladder, "vdd" )
vdd.setExternal( True )
vdd.setGlobal ( True )
cin = Net.create( fulladder, "cin" )
cin.setExternal( True )
xr2_2.getPlug( xr2_x2.getNet('i0') ).setNet( cin )
a2_2 .getPlug( a2_x2.getNet('i0') ).setNet( cin )
a = Net.create( fulladder, 'a' )
a.setExternal( True )
xr2_1.getPlug( xr2_x2.getNet('i0') ).setNet( a )
a2_1 .getPlug( a2_x2.getNet('i0') ).setNet( a )
b = Net.create( fulladder, 'b' )
b.setExternal( True )
xr2_1.getPlug( xr2_x2.getNet('i1') ).setNet( b )
a2_1 .getPlug( a2_x2.getNet('i1') ).setNet( b )
sout_1 = Net.create( fulladder, 'sout_1' )
xr2_1.getPlug( xr2_x2.getNet('q' ) ).setNet( sout_1 )
xr2_2.getPlug( xr2_x2.getNet('i1') ).setNet( sout_1 )
a2_2 .getPlug( a2_x2.getNet('i1') ).setNet( sout_1 )
carry_1 = Net.create( fulladder, 'carry_1' )
a2_1.getPlug( a2_x2.getNet('q' ) ).setNet( carry_1 )
o2_1.getPlug( o2_x2.getNet('i1') ).setNet( carry_1 )
carry_2 = Net.create( fulladder, 'carry_2' )
a2_2.getPlug( a2_x2.getNet('q' ) ).setNet( carry_2 )
o2_1.getPlug( o2_x2.getNet('i0') ).setNet( carry_2 )
sout = Net.create( fulladder, 'sout' )
sout.setExternal( True )
xr2_2.getPlug( xr2_x2.getNet('q') ).setNet( sout )
cout = Net.create( fulladder, 'cout' )
cout.setExternal( True )
o2_1.getPlug( o2_x2.getNet('q') ).setNet( cout )
UpdateSession.close()
af.saveCell( fulladder, Catalog.State.Views )
return fulladder
def placeAndRoute ( editor, cell ):
# Run the placer.
etesian = Etesian.EtesianEngine.create(cell)
etesian.place()
if editor:
editor.setCell( cell )
editor.fit()
Breakpoint.stop( 1, 'After placement' )
# Run the router.
katana = Katana.KatanaEngine.create(cell)
katana.digitalInit ()
katana.runGlobalRouter ()
katana.loadGlobalRouting( Anabatic.EngineLoadGrByNet )
katana.layerAssign ( Anabatic.EngineNoNetLayerAssign )
katana.runNegociate ( Katana.Flags.NoFlags )
af.saveCell( cell, Catalog.State.Views )
return
def ScriptMain ( **kw ):
editor = None
if kw.has_key('editor') and kw['editor']:
editor = kw['editor']
fulladder = buildFulladder( editor )
placeAndRoute( editor, fulladder )
return True

View File

@ -7,7 +7,7 @@
tabs.css
)
if(BUILD_DOC and DOXYGEN_FOUND)
if(BUILD_DOC AND DOXYGEN_FOUND)
add_custom_target ( hurricaneDoc ALL
cd ${HURRICANE_SOURCE_DIR}/doc/hurricane
&& ${DOXYGEN_EXECUTABLE} doxyfile

View File

@ -7,7 +7,7 @@
tabs.css
)
if(BUILD_DOC and DOXYGEN_FOUND)
if(BUILD_DOC AND DOXYGEN_FOUND)
add_custom_target ( viewerDoc ALL
cd ${HURRICANE_SOURCE_DIR}/doc/viewer
&& ${DOXYGEN_EXECUTABLE} doxyfile

View File

@ -8,7 +8,7 @@
tabs.css
)
if(BUILD_DOC and DOXYGEN_FOUND)
if(BUILD_DOC AND DOXYGEN_FOUND)
add_custom_target ( doc ALL
cd ${KATABATIC_SOURCE_DIR}/doc
&& ${DOXYGEN_EXECUTABLE} doxyfile

View File

@ -8,7 +8,7 @@
tabs.css
)
if (BUILD_DOC and DOXYGEN_FOUND)
if (BUILD_DOC AND DOXYGEN_FOUND)
add_custom_target ( doc ALL
cd ${KITE_SOURCE_DIR}/doc
&& ${DOXYGEN_EXECUTABLE} doxyfile

View File

@ -7,7 +7,7 @@
tabs.css
)
if (BUILD_DOC and DOXYGEN_FOUND)
if (BUILD_DOC AND DOXYGEN_FOUND)
add_custom_target ( documentation ALL
cd ${UNICORN_SOURCE_DIR}/doc/unicorn
&& ${DOXYGEN_EXECUTABLE} doxyfile

View File

@ -1,5 +1,5 @@
if(BUILD_DOC and DOXYGEN_FOUND)
if(BUILD_DOC AND DOXYGEN_FOUND)
add_custom_target( doc ALL
cd ${VLSISAPD_SOURCE_DIR}/doc && ${DOXYGEN_EXECUTABLE} doxyfile )
endif()