Updated documentation Python/Tutorial to catch up with API improvements.
This commit is contained in:
parent
440547a1c5
commit
16428ffaa9
|
@ -32,83 +32,6 @@ go through all the components of a trans-hierarchical net.
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
For a starter, how to get all the leaf cells...
|
||||
|
||||
|
||||
9.5 Dynamically decorating data-base objects
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When writing algorithms directly in Python, it may come in handy to be
|
||||
able to add attributes over the Hurricane data-base objects. As C++
|
||||
objects exposed to the Python realm cannot natively do so (it would
|
||||
means to be able to modify a C++ aobject attributes *at runtime*),
|
||||
we add a special Property tasked with handling the extra Python
|
||||
attributes. The syntax has been made as simple as possible.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from Hurricane import PythonAttributes
|
||||
|
||||
class MyAttribute ( object ):
|
||||
count = 0
|
||||
|
||||
def __init__ ( self ):
|
||||
self.value = MyAttribute.count
|
||||
print( '{} has been created'.format(self) )
|
||||
MyAttribute.count += 1
|
||||
|
||||
def __del__ ( self ):
|
||||
print( '{} has been deleted'.format(self) )
|
||||
|
||||
def __str__ ( self ):
|
||||
return '<MyAttribute {}>'.format(self.value)
|
||||
|
||||
|
||||
def demoAttributes ( cell ):
|
||||
PythonAttributes.enable( cell )
|
||||
cell.myAttribute0 = MyAttribute()
|
||||
cell.myAttribute1 = MyAttribute()
|
||||
print( 'cell.myAttribute0 =', cell.myAttribute0 )
|
||||
del cell.myAttribute0
|
||||
PythonAttributes.disable( cell )
|
||||
|
||||
|
||||
Detailing the life cycle of Python attributes on a DBo_:
|
||||
|
||||
1. Enabling the addition of Python attribute on a DBo_:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
PythonAttributes.enable( cell )
|
||||
|
||||
2. Adding/removing properties on the DBo_:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
cell.myAttribute0 = MyAttribute()
|
||||
cell.myAttribute1 = MyAttribute()
|
||||
print( 'cell.myAttribute0 =', cell.myAttribute0 )
|
||||
del cell.myAttribute0
|
||||
|
||||
3. And finally disabling the use of Python attributes on the DBo.
|
||||
Any still attached Python attributes will be released.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
PythonAttributes.disable( cell )
|
||||
|
||||
.. note::
|
||||
|
||||
When the attributes of a DBo_ are released it does not automatically
|
||||
imply that they are removed. Their reference count is decreased, and
|
||||
if they are only referenced here, they will be deleted. But if other
|
||||
variables still holds reference onto them, they will stay allocateds.
|
||||
|
||||
4. There is no need to keep track of all the DBo_ that have Python
|
||||
attributes to disable them. One can directly call:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
PythonAttributes.disableAll()
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -51,15 +51,12 @@ environment is provided by the |CRL| module.
|
|||
|
||||
from Hurricane import *
|
||||
from CRL import *
|
||||
from helpers.overlay import UpdateSession
|
||||
|
||||
af = AllianceFramework.get()
|
||||
UpdateSession.open()
|
||||
|
||||
cell = af.createCell( 'my_inv' )
|
||||
|
||||
# Build then save the Cell.
|
||||
|
||||
UpdateSession.close()
|
||||
with UpdateSession():
|
||||
cell = af.createCell( 'my_inv' )
|
||||
# Build then save the Cell.
|
||||
|
||||
|
||||
This is the simplest call to ``createCell()``, and in that case, the newly
|
||||
|
@ -89,6 +86,24 @@ two conversion functions are provided:
|
|||
In the weakly typed |Python| world, :cb:`lbd` is *float* while :cb:`unit`
|
||||
is *integer*.
|
||||
|
||||
In order to reduce the number of characters one has to code, the :cb:`helpers`
|
||||
module provides three very short function to perform conversion *towards*
|
||||
DbU_ :
|
||||
|
||||
.. code-block:: Python
|
||||
|
||||
def l ( value ):
|
||||
"""Convert a lambda into a DbU."""
|
||||
return DbU.fromLambda( value )
|
||||
|
||||
def u ( value ):
|
||||
"""Convert a length in micrometer into a DbU."""
|
||||
return DbU.fromPhysical( value, Hurricane.DbU.UnitPowerMicro )
|
||||
|
||||
def n ( value ):
|
||||
"""Convert a length in nanometer into a DbU."""
|
||||
return DbU.fromPhysical( value, Hurricane.DbU.UnitPowerNano )
|
||||
|
||||
|
||||
3.5 Setting up the Abutment Box
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -99,20 +114,17 @@ corner ``(x2,y2)``.
|
|||
|
||||
.. code-block:: Python
|
||||
|
||||
b = Box( DbU.fromLambda( 0.0) # x1
|
||||
, DbU.fromLambda( 0.0) # y1
|
||||
, DbU.fromLambda(15.0) # x2
|
||||
, DbU.fromLambda(50.0) ) # y2
|
||||
b = Box( l( 0.0) # x1
|
||||
, l( 0.0) # y1
|
||||
, l(15.0) # x2
|
||||
, l(50.0) ) # y2
|
||||
cell.setAbutmentBox( b )
|
||||
|
||||
Or more simply:
|
||||
|
||||
.. code-block:: Python
|
||||
|
||||
cell.setAbutmentBox( Box( DbU.fromLambda( 0.0)
|
||||
, DbU.fromLambda( 0.0)
|
||||
, DbU.fromLambda(15.0)
|
||||
, DbU.fromLambda(50.0) ) )
|
||||
cell.setAbutmentBox( Box( l( 0.0), l( 0.0), l(15.0), l(50.0) ) )
|
||||
|
||||
|
||||
3.6 Adding Nets and Components
|
||||
|
@ -180,12 +192,12 @@ of ``METAL1``.
|
|||
|
||||
.. code-block:: Python
|
||||
|
||||
segment = Vertical.create( i # The owner Net.
|
||||
, layer # The layer.
|
||||
, DbU.fromLambda( 5.0 ) # The X coordinate.
|
||||
, DbU.fromLambda( 2.0 ) # The width.
|
||||
, DbU.fromLambda( 10.0 ) # The Y source coordinate.
|
||||
, DbU.fromLambda( 40.0 ) ) # The Y target coordinate.
|
||||
segment = Vertical.create( i # The owner Net.
|
||||
, layer # The layer.
|
||||
, l( 5.0 ) # The X coordinate.
|
||||
, l( 2.0 ) # The width.
|
||||
, l( 10.0 ) # The Y source coordinate.
|
||||
, l( 40.0 ) ) # The Y target coordinate.
|
||||
|
||||
With this overload of the ``Vertical.create()`` function the segment is created at an
|
||||
absolute position. There is a second overload for creating a relatively placed
|
||||
|
@ -236,101 +248,99 @@ explanation of that part of the code, refer to `5. Make a script runnable throug
|
|||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
from Hurricane import *
|
||||
from CRL import *
|
||||
|
||||
|
||||
def toDbU ( l ): return DbU.fromLambda(l)
|
||||
from Hurricane import DataBase, NetExternalComponents, Net, \
|
||||
DbU, Point, Box, Horizontal, Vertical, Contact, RoutingPad, \
|
||||
Breakpoint
|
||||
from CRL import AllianceFramework, Catalog
|
||||
from helpers import l
|
||||
from helpers.overlay import UpdateSession
|
||||
|
||||
|
||||
def doBreak ( level, message ):
|
||||
UpdateSession.close()
|
||||
"""Put a breakpoint into the script."""
|
||||
Breakpoint.stop( level, message )
|
||||
UpdateSession.open()
|
||||
|
||||
|
||||
def buildInvertor ( editor ):
|
||||
UpdateSession.open()
|
||||
|
||||
cell = AllianceFramework.get().createCell( 'invertor' )
|
||||
cell.setTerminal( True )
|
||||
|
||||
cell.setAbutmentBox( Box( toDbU(0.0), toDbU(0.0), toDbU(15.0), toDbU(50.0) ) )
|
||||
"""Build step by step an invertor standard cell."""
|
||||
with UpdateSession():
|
||||
cell = AllianceFramework.get().createCell( 'invertor' )
|
||||
cell.setTerminalNetlist( True )
|
||||
cell.setAbutmentBox( Box( l(0.0), l(0.0), l(15.0), l(50.0) ) )
|
||||
|
||||
if editor:
|
||||
UpdateSession.close()
|
||||
editor.setCell( cell )
|
||||
editor.fit()
|
||||
UpdateSession.open()
|
||||
|
||||
technology = DataBase.getDB().getTechnology()
|
||||
metal1 = technology.getLayer( "METAL1" )
|
||||
poly = technology.getLayer( "POLY" )
|
||||
ptrans = technology.getLayer( "PTRANS" )
|
||||
ntrans = technology.getLayer( "NTRANS" )
|
||||
pdif = technology.getLayer( "PDIF" )
|
||||
ndif = technology.getLayer( "NDIF" )
|
||||
contdifn = technology.getLayer( "CONT_DIF_N" )
|
||||
contdifp = technology.getLayer( "CONT_DIF_P" )
|
||||
nwell = technology.getLayer( "NWELL" )
|
||||
contpoly = technology.getLayer( "CONT_POLY" )
|
||||
ntie = technology.getLayer( "NTIE" )
|
||||
|
||||
net = Net.create( cell, "nwell" )
|
||||
Vertical.create( net, nwell, toDbU(7.5), toDbU(15.0), toDbU(27.0), toDbU(51.0) )
|
||||
|
||||
vdd = Net.create( cell, "vdd" )
|
||||
vdd.setExternal( True )
|
||||
vdd.setGlobal ( True )
|
||||
h = Horizontal.create(vdd, metal1, toDbU(47.0), toDbU(6.0), toDbU(0.0), toDbU(15.0) )
|
||||
NetExternalComponents.setExternal( h )
|
||||
Contact.create ( vdd, contdifn, toDbU(10.0), toDbU(47.0), toDbU( 1.0), toDbU( 1.0) )
|
||||
Contact.create ( vdd, contdifp, toDbU( 4.0), toDbU(45.0), toDbU( 1.0), toDbU( 1.0) )
|
||||
Vertical.create( vdd, pdif , toDbU( 3.5), toDbU( 4.0), toDbU(28.0), toDbU(46.0) )
|
||||
Vertical.create( vdd, ntie , toDbU(10.0), toDbU( 3.0), toDbU(43.0), toDbU(48.0) )
|
||||
with UpdateSession():
|
||||
technology = DataBase.getDB().getTechnology()
|
||||
metal1 = technology.getLayer( "METAL1" )
|
||||
poly = technology.getLayer( "POLY" )
|
||||
ptrans = technology.getLayer( "PTRANS" )
|
||||
ntrans = technology.getLayer( "NTRANS" )
|
||||
pdif = technology.getLayer( "PDIF" )
|
||||
ndif = technology.getLayer( "NDIF" )
|
||||
contdifn = technology.getLayer( "CONT_DIF_N" )
|
||||
contdifp = technology.getLayer( "CONT_DIF_P" )
|
||||
nwell = technology.getLayer( "NWELL" )
|
||||
contpoly = technology.getLayer( "CONT_POLY" )
|
||||
ntie = technology.getLayer( "NTIE" )
|
||||
|
||||
net = Net.create( cell, "nwell" )
|
||||
Vertical.create( net, nwell, l(7.5), l(15.0), l(27.0), l(51.0) )
|
||||
|
||||
vdd = Net.create( cell, "vdd" )
|
||||
vdd.setExternal( True )
|
||||
vdd.setGlobal ( True )
|
||||
h = Horizontal.create(vdd, metal1, l(47.0), l(6.0), l(0.0), l(15.0) )
|
||||
NetExternalComponents.setExternal( h )
|
||||
Contact.create ( vdd, contdifn, l(10.0), l(47.0), l( 1.0), l( 1.0) )
|
||||
Contact.create ( vdd, contdifp, l( 4.0), l(45.0), l( 1.0), l( 1.0) )
|
||||
Vertical.create( vdd, pdif , l( 3.5), l( 4.0), l(28.0), l(46.0) )
|
||||
Vertical.create( vdd, ntie , l(10.0), l( 3.0), l(43.0), l(48.0) )
|
||||
doBreak( 1, 'Done building vdd.' )
|
||||
|
||||
vss = Net.create( cell, "vss" )
|
||||
vss.setExternal( True )
|
||||
vss.setGlobal ( True )
|
||||
h = Horizontal.create(vss, metal1, toDbU(3.0), toDbU(6.0), toDbU(0.0), toDbU(15.0))
|
||||
NetExternalComponents.setExternal( h )
|
||||
Vertical.create( vss, ndif , toDbU(3.5), toDbU(4.0), toDbU(4.0), toDbU(12.0) )
|
||||
Contact.create ( vss, contdifn, toDbU(4.0), toDbU(5.0), toDbU(1.0), toDbU( 1.0) )
|
||||
with UpdateSession():
|
||||
vss = Net.create( cell, "vss" )
|
||||
vss.setExternal( True )
|
||||
vss.setGlobal ( True )
|
||||
h = Horizontal.create(vss, metal1, l(3.0), l(6.0), l(0.0), l(15.0))
|
||||
NetExternalComponents.setExternal( h )
|
||||
Vertical.create( vss, ndif , l(3.5), l(4.0), l(4.0), l(12.0) )
|
||||
Contact.create ( vss, contdifn, l(4.0), l(5.0), l(1.0), l( 1.0) )
|
||||
doBreak( 1, 'Done building vss.' )
|
||||
|
||||
i = Net.create( cell, "i" )
|
||||
i.setExternal( True )
|
||||
v = Vertical.create ( i, metal1, toDbU(5.0), toDbU(2.0), toDbU(10.0), toDbU(40.0) )
|
||||
NetExternalComponents.setExternal( v )
|
||||
Vertical.create ( i, ptrans , toDbU( 7.0), toDbU( 1.0), toDbU(26.0), toDbU(39.0) )
|
||||
Vertical.create ( i, ntrans , toDbU( 7.0), toDbU( 1.0), toDbU( 6.0), toDbU(14.0) )
|
||||
Vertical.create ( i, poly , toDbU( 7.0), toDbU( 1.0), toDbU(14.0), toDbU(26.0) )
|
||||
Horizontal.create( i, poly , toDbU(20.0), toDbU( 3.0), toDbU( 4.0), toDbU( 7.0) )
|
||||
Contact.create ( i, contpoly, toDbU( 5.0), toDbU(20.0), toDbU( 1.0), toDbU( 1.0) )
|
||||
with UpdateSession():
|
||||
i = Net.create( cell, "i" )
|
||||
i.setExternal( True )
|
||||
v = Vertical.create ( i, metal1, l(5.0), l(2.0), l(10.0), l(40.0) )
|
||||
NetExternalComponents.setExternal( v )
|
||||
Vertical.create ( i, ptrans , l( 7.0), l( 1.0), l(26.0), l(39.0) )
|
||||
Vertical.create ( i, ntrans , l( 7.0), l( 1.0), l( 6.0), l(14.0) )
|
||||
Vertical.create ( i, poly , l( 7.0), l( 1.0), l(14.0), l(26.0) )
|
||||
Horizontal.create( i, poly , l(20.0), l( 3.0), l( 4.0), l( 7.0) )
|
||||
Contact.create ( i, contpoly, l( 5.0), l(20.0), l( 1.0), l( 1.0) )
|
||||
doBreak( 1, 'Done building i.' )
|
||||
|
||||
nq = Net.create ( cell, "nq" )
|
||||
nq.setExternal( True )
|
||||
v = Vertical.create( nq, metal1, toDbU(10.0), toDbU(2.0), toDbU(10.0), toDbU(40.0) )
|
||||
NetExternalComponents.setExternal( v )
|
||||
Vertical.create( nq, pdif , toDbU(10.0), toDbU( 3.0), toDbU(28.0), toDbU(37.0) )
|
||||
Vertical.create( nq, ndif , toDbU(10.0), toDbU( 3.0), toDbU( 8.0), toDbU(12.0) )
|
||||
Contact.create ( nq, contdifp, toDbU(10.0), toDbU(35.0), toDbU( 1.0), toDbU( 1.0) )
|
||||
Contact.create ( nq, contdifp, toDbU(10.0), toDbU(30.5), toDbU( 1.0), toDbU( 1.0) )
|
||||
Contact.create ( nq, contdifn, toDbU(10.0), toDbU(10.0), toDbU( 1.0), toDbU( 1.0) )
|
||||
with UpdateSession():
|
||||
nq = Net.create ( cell, "nq" )
|
||||
nq.setExternal( True )
|
||||
v = Vertical.create( nq, metal1, l(10.0), l(2.0), l(10.0), l(40.0) )
|
||||
NetExternalComponents.setExternal( v )
|
||||
Vertical.create( nq, pdif , l(10.0), l( 3.0), l(28.0), l(37.0) )
|
||||
Vertical.create( nq, ndif , l(10.0), l( 3.0), l( 8.0), l(12.0) )
|
||||
Contact.create ( nq, contdifp, l(10.0), l(35.0), l( 1.0), l( 1.0) )
|
||||
Contact.create ( nq, contdifp, l(10.0), l(30.5), l( 1.0), l( 1.0) )
|
||||
Contact.create ( nq, contdifn, l(10.0), l(10.0), l( 1.0), l( 1.0) )
|
||||
doBreak( 1, 'Done building q.' )
|
||||
|
||||
UpdateSession.close()
|
||||
AllianceFramework.get().saveCell( cell, Catalog.State.Views )
|
||||
|
||||
return
|
||||
|
||||
|
||||
def scriptMain ( **kw ):
|
||||
"""The Mandatory function to be run by Coriolis interactively."""
|
||||
editor = None
|
||||
if kw.has_key('editor') and kw['editor']:
|
||||
editor = kw['editor']
|
||||
|
||||
if 'editor' in kw and kw['editor']:
|
||||
editor = kw['editor']
|
||||
buildInvertor( editor )
|
||||
return True
|
||||
|
|
|
@ -33,29 +33,25 @@ using the menu:
|
|||
.. code-block:: Python
|
||||
|
||||
def buildInvertor ( editor ):
|
||||
UpdateSession.open()
|
||||
|
||||
cell = AllianceFramework.get().createCell( 'invertor' )
|
||||
cell.setTerminal( True )
|
||||
|
||||
cell.setAbutmentBox( Box( toDbU(0.0), toDbU(0.0), toDbU(15.0), toDbU(50.0) ) )
|
||||
|
||||
"""Build step by step an invertor standard cell."""
|
||||
with UpdateSession():
|
||||
cell = AllianceFramework.get().createCell( 'invertor' )
|
||||
cell.setTerminalNetlist( True )
|
||||
|
||||
cell.setAbutmentBox( Box( l(0.0), l(0.0), l(15.0), l(50.0) ) )
|
||||
if editor:
|
||||
UpdateSession.close()
|
||||
editor.setCell( cell )
|
||||
editor.fit()
|
||||
UpdateSession.open()
|
||||
editor.setCell( cell )
|
||||
editor.fit()
|
||||
|
||||
# The rest of the script...
|
||||
|
||||
return
|
||||
|
||||
|
||||
def scriptMain ( **kw ):
|
||||
"""The Mandatory function to be run by Coriolis interactively."""
|
||||
editor = None
|
||||
if kw.has_key('editor') and kw['editor']:
|
||||
editor = kw['editor']
|
||||
|
||||
if 'editor' in kw and kw['editor']:
|
||||
editor = kw['editor']
|
||||
buildInvertor( editor )
|
||||
return True
|
||||
|
||||
|
@ -64,8 +60,8 @@ using the menu:
|
|||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
It is possible to add breakpoints inside a script by calling the ``Breakpoint.stop()``
|
||||
function. To be able to see exactly what has just been mofied, we must close the
|
||||
UpdateSession_ just before calling the breakpoint and reopen it just after.
|
||||
function. To be able to see exactly what has just been modified, be sure to have
|
||||
closed any UpdateSession_ before calling breakpoints.
|
||||
The ``Breakpoint.stop()`` function takes two arguments:
|
||||
|
||||
#. The ``level`` above which it will be active.
|
||||
|
@ -76,6 +72,4 @@ We can create a little function to ease the work:
|
|||
.. code-block:: Python
|
||||
|
||||
def doBreak ( level, message ):
|
||||
UpdateSession.close()
|
||||
Breakpoint.stop( level, message )
|
||||
UpdateSession.open()
|
||||
|
|
|
@ -23,12 +23,12 @@ allowing to simply write:
|
|||
.. code-block:: Python
|
||||
|
||||
for net in cell.getNets():
|
||||
print 'Components of', net
|
||||
for component in net.getComponents():
|
||||
print '|', component
|
||||
print( 'Components of', net )
|
||||
for component in net.getComponents():
|
||||
print( '|', component )
|
||||
|
||||
|
||||
In C++ we would have written:
|
||||
In C++ we would have been written:
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
|
@ -54,13 +54,13 @@ loop. For example:
|
|||
|
||||
cellNets = []
|
||||
for net in cell.getNets():
|
||||
cellNets.append( net )
|
||||
cellNets.append( net )
|
||||
|
||||
# Remove all the anonymous nets.
|
||||
for net in cellNets:
|
||||
if net.getName().endswith('nymous_'):
|
||||
print 'Destroy', net
|
||||
net.destroy()
|
||||
if net.getName().endswith('nymous_'):
|
||||
print( 'Destroy', net )
|
||||
net.destroy()
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -37,53 +37,68 @@ Use it like this (don't forget the ``eval`` **and** the backquotes):
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You may create, in the directory you are lanching |Coriolis| tools, a special
|
||||
sub-directory ``.coriolis2/`` that can contain two configuration files:
|
||||
sub-directory ``coriolis2/`` that can contain the configuration files:
|
||||
|
||||
* ``techno.py`` tells which technology to use.
|
||||
* ``__init__.py`` to tell |Python| this directory is a module.
|
||||
* ``settings.py`` can override almost any default configuration setting.
|
||||
|
||||
Those two files are *optional*, if they do not exist the default settings
|
||||
will be used and the technology is ``symbolic/cmos`` (i.e. purely symbolic).
|
||||
|
||||
.. note:: Those two files will by processed by the |Python| interpreter,
|
||||
so they can contain any code in addition to the mandatory
|
||||
variables.
|
||||
|
||||
|
||||
2.2.1 The :cb:`techno.py` File
|
||||
------------------------------
|
||||
2.3 The :cb:`settings.py` File
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Must provide one variable named :cb:`technology` which values the path towards
|
||||
the technology file. The available technologies are installed under
|
||||
``<CORIOLIS_INSTALL>/etc/coriolis2``. For example, to use the 45nm FreeDPK
|
||||
which is in: ::
|
||||
The attributes name and definitions of :cb:`cfg` are detailed
|
||||
in `CGT - The Graphical Interface <../UsersGuide/ViewerTools.html>`_.
|
||||
|
||||
<CORIOLIS_INSTALL>/etc/coriolis2/45/freepdk_45/
|
||||
**Selecting the Technology**
|
||||
|
||||
The ``techno.py`` file must contain:
|
||||
The important line here is:
|
||||
|
||||
.. code-block:: Python
|
||||
|
||||
technology = '45/freepdk_45'
|
||||
|
||||
import symbolic.cmos
|
||||
|
||||
2.2.2 The :cb:`settings.py` File
|
||||
--------------------------------
|
||||
|
||||
The entries of the ``parametersTable`` and their definitions are detailed
|
||||
in `CGT - The Graphical Interface <../UsersGuide/ViewerTools.html>`_.
|
||||
This import loads and setup the technology used througout this run of
|
||||
|Coriolis|. One and only one technology can be loaded in a |Coriolis| run.
|
||||
|
||||
Example of file:
|
||||
|
||||
.. code-block:: Python
|
||||
|
||||
defaultStyle = 'Alliance.Classic [black]'
|
||||
# -*- Mode:Python -*-
|
||||
|
||||
parametersTable = \
|
||||
( ('misc.catchCore' , TypeBool , False )
|
||||
, ('misc.info' , TypeBool , False )
|
||||
, ('misc.paranoid' , TypeBool , False )
|
||||
, ('misc.bug' , TypeBool , False )
|
||||
, ('misc.logMode' , TypeBool , False )
|
||||
, ('misc.verboseLevel1' , TypeBool , False )
|
||||
, ('misc.verboseLevel2' , TypeBool , True )
|
||||
)
|
||||
import os
|
||||
import Cfg
|
||||
import Viewer
|
||||
import CRL
|
||||
import symbolic.cmos
|
||||
from helpers import overlay
|
||||
|
||||
if 'CELLS_TOP' in os.environ:
|
||||
cellsTop = os.environ['CELLS_TOP']
|
||||
else:
|
||||
cellsTop = '../../../cells'
|
||||
|
||||
with overlay.CfgCache(priority=Cfg.Parameter.Priority.UserFile) as cfg:
|
||||
cfg.misc.catchCore = False
|
||||
cfg.misc.info = False
|
||||
cfg.misc.paranoid = False
|
||||
cfg.misc.bug = False
|
||||
cfg.misc.logMode = True
|
||||
cfg.misc.verboseLevel1 = True
|
||||
cfg.misc.verboseLevel2 = True
|
||||
cfg.misc.minTraceLevel = 1900
|
||||
cfg.misc.maxTraceLevel = 3000
|
||||
cfg.katana.eventsLimit = 1000000
|
||||
cfg.katana.termSatReservedLocal = 6
|
||||
cfg.katana.termSatThreshold = 9
|
||||
Viewer.Graphics.setStyle( 'Alliance.Classic [black]' )
|
||||
af = CRL.AllianceFramework.get()
|
||||
env = af.getEnvironment()
|
||||
env.setCLOCK( '^ck$|m_clock|^clk$' )
|
||||
env.addSYSTEM_LIBRARY( library=cellsTop+'/nsxlib', mode=CRL.Environment.Prepend )
|
||||
env.addSYSTEM_LIBRARY( library=cellsTop+'/niolib', mode=CRL.Environment.Prepend )
|
||||
|
|
|
@ -17,8 +17,25 @@ of |Python| objects or use |Python| containers to store them.
|
|||
The only limitation is that you may not use |Hurricane| classes as base
|
||||
classes in |Python|.
|
||||
|
||||
All |Hurricane| objects implements the |Python| ``__str__()`` function,
|
||||
they print the result of the C++ method ``::getString()``.
|
||||
All the example scripts given in this tutorial con be found under: ::
|
||||
|
||||
<CORIOLIS_INSTALL>/share/doc/coriolis2/examples/scripts/
|
||||
|
||||
Provided scripts:
|
||||
|
||||
======================= ==============================================================
|
||||
**Script** **Feature**
|
||||
======================= ==============================================================
|
||||
:cb:`coriolisLogo.py` Draw a layout of the |Coriolis| logo
|
||||
:cb:`diagonals.py` Test the :cb:`Hurricane::Diagonal` class
|
||||
:cb:`polygons.py` Test the :cb:`Hurricane::Polygon` class
|
||||
:cb:`rectilinear.py` Test the :cb:`Hurricane::rectilinear` class
|
||||
:cb:`invertor.py` Procedural build of the layout of an invertor standard cell
|
||||
:cb:`fulladder.py` Procedural build of a small netlist along with it's manual
|
||||
placement and the routing of one net (:cb:`"a"`)
|
||||
:cb:`toolengines.py` Build the netlist (only) of the full adder then call the
|
||||
place and route engines
|
||||
======================= ==============================================================
|
||||
|
||||
|
||||
1.1 Terminology
|
||||
|
@ -61,17 +78,45 @@ Mostly:
|
|||
to use ``string``.
|
||||
* Coordinates are expressed in ``DbU`` which are ``long`` with a special
|
||||
semantic (see ??).
|
||||
* All |Hurricane| objects implements the |Python| ``__str__()`` function,
|
||||
they print the result of the C++ method ``::getString()``.
|
||||
|
||||
In ``hurricane/Session.h`` header we have:
|
||||
In ``hurricane/Net.h`` header we have:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
namespace Hurricane {
|
||||
|
||||
class UpdateSession {
|
||||
class Net : public Entity {
|
||||
public:
|
||||
static void open ();
|
||||
static void close ();
|
||||
class Direction {
|
||||
public: enum Code { DirIn = 0x0001
|
||||
, DirOut = 0x0002
|
||||
, DirUndefined = 0x0000
|
||||
, ConnTristate = 0x0100
|
||||
, ConnWiredOr = 0x0200
|
||||
, UNDEFINED = DirUndefined
|
||||
, IN = DirIn
|
||||
, OUT = DirOut
|
||||
, INOUT = DirIn | DirOut
|
||||
, TRISTATE = DirOut | ConnTristate
|
||||
, TRANSCV = DirIn | DirOut | ConnTristate
|
||||
, WOR_OUT = DirOut | ConnWiredOr
|
||||
, WOR_INOUT = DirIn | DirOut | ConnWiredOr
|
||||
, DirMask = DirIn | DirOut | DirUndefined
|
||||
};
|
||||
// [The rest of Class Direction]
|
||||
};
|
||||
public:
|
||||
static Net* create ( Cell* , const Name& );
|
||||
bool isGlobal ();
|
||||
bool isExternal ();
|
||||
const Direction& getDirection ();
|
||||
void setName ( Name );
|
||||
void setGlobal ( bool );
|
||||
void setExternal ( bool );
|
||||
void setDirection ( const Direction& );
|
||||
// [The rest of Class Net]
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -81,15 +126,18 @@ So we can use it the following way in C++:
|
|||
|
||||
.. code-block:: c++
|
||||
|
||||
#include "hurricane/Session.h"
|
||||
#include "hurricane/Net.h"
|
||||
|
||||
using namespace Hurricane;
|
||||
|
||||
void doSomething ()
|
||||
void addNetToCell ( Cell* cell )
|
||||
{
|
||||
UpdateSession::open();
|
||||
// Something...
|
||||
UpdateSession::close();
|
||||
Net* net = Net::create( cell, "new_net" );
|
||||
net->setGlobal ( false );
|
||||
net->setExternal ( true );
|
||||
net->setDirection( Net.Direction.IN );
|
||||
cout << "Created " << net << endl;
|
||||
return net;
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,12 +145,15 @@ The equivalent |Python| code will be:
|
|||
|
||||
.. code-block:: Python
|
||||
|
||||
from Hurricane import *
|
||||
from Hurricane import Net
|
||||
|
||||
def doSomething ():
|
||||
UpdateSession.open()
|
||||
# Something...
|
||||
UpdateSession.close()
|
||||
def addNetToCell ( cell ):
|
||||
net = Net.create( cell, "new_net" )
|
||||
net.setGlobal ( False )
|
||||
net.setExternal( True )
|
||||
net.setDirection( Net.Direction.IN )
|
||||
print( "Created", net )
|
||||
return net
|
||||
|
||||
|
||||
1.3 Various Kinds of Constructors
|
||||
|
@ -130,9 +181,152 @@ Regarding the memory allocation, the |Hurricane| database contains two kind of o
|
|||
|
||||
.. code-block:: Python
|
||||
|
||||
from Hurricane import DbU, Box
|
||||
|
||||
def myfunc():
|
||||
bb = Box( DbU.fromLambda( 0.0)
|
||||
, DbU.fromLambda( 0.0)
|
||||
, DbU.fromLambda(15.0)
|
||||
, DbU.fromLambda(50.0) )
|
||||
return # bb will be freed at that point.
|
||||
bb = Box( DbU.fromLambda( 0.0)
|
||||
, DbU.fromLambda( 0.0)
|
||||
, DbU.fromLambda(15.0)
|
||||
, DbU.fromLambda(50.0) )
|
||||
return # bb will be freed at that point.
|
||||
|
||||
|
||||
1.4 Collections and Iterators
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Hurricane Collection_ behave like containers under |Python| and provide
|
||||
support for the :cb:`iterator` protocol.
|
||||
|
||||
.. code-block:: Python
|
||||
|
||||
from Hurricane import Net, Horizontal
|
||||
|
||||
def delAllHorizontals ( net ):
|
||||
horizontals = []
|
||||
for component in net.getComponents():
|
||||
if isinstance(component,Horizontal):
|
||||
horizontals.append( component )
|
||||
# Now we can remove the Horizontals.
|
||||
for horizontal in horizontals:
|
||||
horizontal.destroy()
|
||||
|
||||
.. note:: **Never remove an element from a Collection_ while iterating over it**.
|
||||
You must save the to be removed elements in an auxiliary container
|
||||
then remove them, like shown in the example above
|
||||
|
||||
|
||||
1.5 Dynamically decorating data-base objects
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When writing algorithms directly in Python, it may come in handy to be
|
||||
able to add attributes over the Hurricane data-base objects. As C++
|
||||
objects exposed to the Python realm cannot natively do so (it would
|
||||
means to be able to modify a C++ aobject attributes *at runtime*),
|
||||
we add a special Property tasked with handling the extra Python
|
||||
attributes. The syntax has been made as simple as possible.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from Hurricane import PythonAttributes
|
||||
|
||||
class MyAttribute ( object ):
|
||||
count = 0
|
||||
|
||||
def __init__ ( self ):
|
||||
self.value = MyAttribute.count
|
||||
print( '{} has been created'.format(self) )
|
||||
MyAttribute.count += 1
|
||||
|
||||
def __del__ ( self ):
|
||||
print( '{} has been deleted'.format(self) )
|
||||
|
||||
def __str__ ( self ):
|
||||
return '<MyAttribute {}>'.format(self.value)
|
||||
|
||||
|
||||
def demoAttributes ( cell ):
|
||||
PythonAttributes.enable( cell )
|
||||
cell.myAttribute0 = MyAttribute()
|
||||
cell.myAttribute1 = MyAttribute()
|
||||
print( 'cell.myAttribute0 =', cell.myAttribute0 )
|
||||
del cell.myAttribute0
|
||||
PythonAttributes.disable( cell )
|
||||
|
||||
|
||||
Detailing the life cycle of Python attributes on a DBo_:
|
||||
|
||||
1. Enabling the addition of Python attribute on a DBo_:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
PythonAttributes.enable( cell )
|
||||
|
||||
2. Adding/removing properties on the DBo_:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
cell.myAttribute0 = MyAttribute()
|
||||
cell.myAttribute1 = MyAttribute()
|
||||
print( 'cell.myAttribute0 =', cell.myAttribute0 )
|
||||
del cell.myAttribute0
|
||||
|
||||
3. And finally disabling the use of Python attributes on the DBo.
|
||||
Any still attached Python attributes will be released.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
PythonAttributes.disable( cell )
|
||||
|
||||
.. note::
|
||||
|
||||
When the attributes of a DBo_ are released it does not automatically
|
||||
imply that they are removed. Their reference count is decreased, and
|
||||
if they are only referenced here, they will be deleted. But if other
|
||||
variables still holds reference onto them, they will stay allocateds.
|
||||
|
||||
4. There is no need to keep track of all the DBo_ that have Python
|
||||
attributes to disable them. One can directly call:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
PythonAttributes.disableAll()
|
||||
|
||||
|
||||
1.6 Adapting C++ : Overlay
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Sometimes, the use of a wrapped C++ feature would be counter intuitive regarding
|
||||
the |Python| feature. For those cases the :cb:`overlay` module provide an
|
||||
adaptation of the C++ API for a more *Python-like* code. A typical example is
|
||||
with the UpdateSession_ mechanism.
|
||||
|
||||
Using directly the C++ wrapper, we would write a code like this:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from Hurricane import UpdateSession, Net, Vertical
|
||||
from helpers import l
|
||||
|
||||
def editCell ( cell ):
|
||||
UpdateSession.open()
|
||||
net = Net.create( cell, "nwell" )
|
||||
Vertical.create( net, nwell, l(7.5), l(15.0), l(27.0), l(51.0) )
|
||||
# Continued cell's layout building.
|
||||
# ...
|
||||
UpdateSession.close()
|
||||
|
||||
|
||||
But, using the :cb:`overlay` we got the more *pythonic* code:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from Hurricane import Net, Vertical
|
||||
from helpers import l
|
||||
from helpers.overlay import UpdateSession
|
||||
|
||||
def editCell ( cell ):
|
||||
with UpdateSession():
|
||||
net = Net.create( cell, "nwell" )
|
||||
Vertical.create( net, nwell, l(7.5), l(15.0), l(27.0), l(51.0) )
|
||||
# Continued cell's layout building.
|
||||
# ...
|
||||
|
|
|
@ -140,9 +140,7 @@ we also must set its *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.setTransformation( Transformation( l(0.0), l(100.0), Transformation.Orientation.MY ) )
|
||||
xr2_1.setPlacementStatus( Instance.PlacementStatus.PLACED )
|
||||
|
||||
|
||||
|
@ -196,19 +194,19 @@ contacts.
|
|||
|
||||
# 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 )
|
||||
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) )
|
||||
contact1 = Contact.create( rp1, via12, l( 0.0), l(-15.0) )
|
||||
contact2 = Contact.create( rp2, via12, l( 0.0), l( 10.0) )
|
||||
turn = Contact.create( a , via23, l(10.0), l( 35.0) )
|
||||
Horizontal.create( contact2, turn , metal2, l(35.0), l(2.0) )
|
||||
Vertical .create( turn , contact1 , metal3, l(10.0), l(2.0) )
|
||||
|
||||
|
||||
.. note:: In order to better see the layout of the wiring only, open the
|
||||
|
@ -227,136 +225,140 @@ directory (under the the root of the |Coriolis| installation).
|
|||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
from Hurricane import *
|
||||
from CRL import *
|
||||
|
||||
|
||||
def toDbU ( l ): return DbU.fromLambda(l)
|
||||
from Hurricane import DataBase, Instance, Box, Net, Horizontal, Vertical, Contact, \
|
||||
RoutingPad, Transformation, Occurrence, \
|
||||
Breakpoint
|
||||
from CRL import AllianceFramework, Catalog, Gds
|
||||
from helpers import l
|
||||
from helpers.overlay import UpdateSession
|
||||
|
||||
|
||||
def doBreak ( level, message ):
|
||||
UpdateSession.close()
|
||||
"""Put a breakpoint into the script."""
|
||||
Breakpoint.stop( level, message )
|
||||
UpdateSession.open()
|
||||
|
||||
|
||||
def buildFulladder ( editor ):
|
||||
|
||||
# Get the Framework and all the master cells.
|
||||
"""Build step by step full adder (netlist & placement)."""
|
||||
# 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) ) )
|
||||
with UpdateSession():
|
||||
fulladder = af.createCell( 'fulladder' )
|
||||
fulladder.setAbutmentBox( Box( l(0.0), l(0.0), l(90.0), l(100.0) ) )
|
||||
|
||||
if editor:
|
||||
UpdateSession.close()
|
||||
editor.setCell( fulladder )
|
||||
editor.fit()
|
||||
UpdateSession.open()
|
||||
editor.setCell( fulladder )
|
||||
editor.fit()
|
||||
|
||||
# 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 )
|
||||
with UpdateSession():
|
||||
# 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 )
|
||||
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 )
|
||||
|
||||
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 )
|
||||
# Instances placement.
|
||||
with UpdateSession():
|
||||
a2_1.setTransformation( Transformation( l(0.0)
|
||||
, l(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 )
|
||||
|
||||
with UpdateSession():
|
||||
xr2_1.setTransformation( Transformation( l( 0.0)
|
||||
, l(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 )
|
||||
|
||||
with UpdateSession():
|
||||
a2_2.setTransformation( Transformation( l(25.0)
|
||||
, l( 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 )
|
||||
|
||||
with UpdateSession():
|
||||
xr2_2.setTransformation( Transformation( l( 45.0)
|
||||
, l(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 )
|
||||
|
||||
with UpdateSession():
|
||||
o2_1.setTransformation( Transformation( l(65.0)
|
||||
, l( 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 )
|
||||
# Add filler cells.
|
||||
with UpdateSession():
|
||||
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( l(50.0)
|
||||
, l( 0.0)
|
||||
, Transformation.Orientation.ID ) )
|
||||
filler_1.setPlacementStatus( Instance.PlacementStatus.PLACED )
|
||||
|
||||
filler_2.setTransformation( Transformation( l(60.0)
|
||||
, l( 0.0)
|
||||
, Transformation.Orientation.ID ) )
|
||||
filler_2.setPlacementStatus( Instance.PlacementStatus.PLACED )
|
||||
doBreak( 1, 'Filler cell placeds' )
|
||||
|
||||
# Getting the layers.
|
||||
|
@ -366,32 +368,30 @@ directory (under the the root of the |Coriolis| installation).
|
|||
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 )
|
||||
with UpdateSession():
|
||||
# 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()
|
||||
# Then regular wiring.
|
||||
contact1 = Contact.create( rp1, via12, l( 0.0), l(-15.0) )
|
||||
contact2 = Contact.create( rp2, via12, l( 0.0), l( 10.0) )
|
||||
turn = Contact.create( a , via23, l(10.0), l( 35.0) )
|
||||
Horizontal.create( contact2, turn , metal2, l(35.0), l(2.0) )
|
||||
Vertical .create( turn , contact1 , metal3, l(10.0), l(2.0) )
|
||||
|
||||
af.saveCell( fulladder, Catalog.State.Views )
|
||||
return
|
||||
|
||||
|
||||
def scriptMain ( **kw ):
|
||||
"""The Mandatory function to be run by Coriolis interactively."""
|
||||
editor = None
|
||||
if kw.has_key('editor') and kw['editor']:
|
||||
editor = kw['editor']
|
||||
|
||||
if 'editor' in kw and kw['editor']:
|
||||
editor = kw['editor']
|
||||
buildFulladder( editor )
|
||||
return True
|
||||
|
|
|
@ -34,16 +34,16 @@ You can configure the placer in two ways:
|
|||
file. For example:
|
||||
|
||||
.. code-block:: Python
|
||||
|
||||
with overlay.CfgCache(priority=Cfg.Parameter.Priority.UserFile) as cfg:
|
||||
cfg.etesian.effort = 2
|
||||
cfg.etesian.uniformDensity = True
|
||||
cfg.etesian.spaceMargin = 0.8
|
||||
cfg.etesian.aspectRatio = 1.0
|
||||
|
||||
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
|
||||
area (``etesian.uniformDensity``), with ``80%`` of free space
|
||||
added and an aspect ratio of ``100%`` (square shape).
|
||||
|
||||
|
||||
|
@ -87,7 +87,7 @@ previously. The call to the ToolEngines_ is made inside the new function
|
|||
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
|
||||
.. note:: The space margin for this example is very high (``80%``), it's only
|
||||
because it's too small for the placer to run correctly. For normal
|
||||
case it is around ``3%``.
|
||||
|
||||
|
@ -105,91 +105,82 @@ previously. The call to the ToolEngines_ is made inside the new function
|
|||
# Everybody needs it.
|
||||
af = AllianceFramework.get()
|
||||
|
||||
|
||||
def toDbU ( l ): return DbU.fromLambda(l)
|
||||
|
||||
|
||||
def buildFulladder ( editor ):
|
||||
|
||||
# Get the Framework and all the master cells.
|
||||
# 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()
|
||||
with UpdateSession():
|
||||
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 )
|
||||
|
||||
af.saveCell( fulladder, Catalog.State.Views )
|
||||
return fulladder
|
||||
|
||||
|
||||
def placeAndRoute ( editor, cell ):
|
||||
# Run the placer.
|
||||
# Run the placer.
|
||||
etesian = Etesian.EtesianEngine.create(cell)
|
||||
etesian.place()
|
||||
|
||||
if editor:
|
||||
editor.setCell( cell )
|
||||
editor.fit()
|
||||
editor.setCell( cell )
|
||||
editor.fit()
|
||||
|
||||
Breakpoint.stop( 1, 'After placement' )
|
||||
|
||||
# Run the router.
|
||||
# Run the router.
|
||||
katana = Katana.KatanaEngine.create(cell)
|
||||
katana.digitalInit ()
|
||||
katana.runGlobalRouter ()
|
||||
|
@ -198,14 +189,12 @@ previously. The call to the ToolEngines_ is made inside the new function
|
|||
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']
|
||||
|
||||
if 'editor' in kw and kw['editor']:
|
||||
editor = kw['editor']
|
||||
fulladder = buildFulladder( editor )
|
||||
placeAndRoute( editor, fulladder )
|
||||
return True
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,23 +0,0 @@
|
|||
|
||||
# -*- Mode:Python -*-
|
||||
|
||||
|
||||
defaultStyle = 'Alliance.Classic [black]'
|
||||
|
||||
parametersTable = \
|
||||
( ('misc.catchCore' , TypeBool , False )
|
||||
, ('misc.info' , TypeBool , False )
|
||||
, ('misc.paranoid' , TypeBool , False )
|
||||
, ('misc.bug' , TypeBool , False )
|
||||
, ('misc.logMode' , TypeBool , False )
|
||||
, ('misc.verboseLevel1' , TypeBool , False )
|
||||
, ('misc.verboseLevel2' , TypeBool , True )
|
||||
, ('misc.traceLevel' , TypeInt , 1000 )
|
||||
, ('etesian.spaceMargin' , TypePercentage, 30.0 )
|
||||
, ('etesian.aspectRatio' , TypePercentage, 100.0 )
|
||||
# Kite parameters.
|
||||
, ("kite.eventsLimit" , TypeInt , 1000000 )
|
||||
, ('katabatic.topRoutingLayer', TypeString , 'METAL5')
|
||||
, ("kite.hTracksReservedLocal", TypeInt , 4 )
|
||||
, ("kite.vTracksReservedLocal", TypeInt , 3 )
|
||||
)
|
|
@ -1 +0,0 @@
|
|||
technology = 'symbolic/cmos'
|
|
@ -4,6 +4,9 @@
|
|||
install ( FILES invertor.py
|
||||
fulladder.py
|
||||
polygons.py
|
||||
toolengines.py DESTINATION ${examplesInstallDir}/scripts )
|
||||
install ( DIRECTORY .coriolis2 DESTINATION ${examplesInstallDir}/scripts )
|
||||
diagonals.py
|
||||
rectilinear.py
|
||||
coriolisLogo.py
|
||||
toolengines.py DESTINATION ${examplesInstallDir}/scripts )
|
||||
install ( DIRECTORY coriolis2 DESTINATION ${examplesInstallDir}/scripts )
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
# -*- Mode:Python -*-
|
||||
|
||||
import os
|
||||
import Cfg
|
||||
import Viewer
|
||||
import CRL
|
||||
import symbolic.cmos
|
||||
from helpers import overlay
|
||||
|
||||
#if 'CELLS_TOP' in os.environ:
|
||||
# cellsTop = os.environ['CELLS_TOP']
|
||||
#else:
|
||||
# cellsTop = '../../../cells'
|
||||
|
||||
with overlay.CfgCache(priority=Cfg.Parameter.Priority.UserFile) as cfg:
|
||||
cfg.misc.catchCore = False
|
||||
cfg.misc.info = False
|
||||
cfg.misc.paranoid = False
|
||||
cfg.misc.bug = False
|
||||
cfg.misc.logMode = True
|
||||
cfg.misc.verboseLevel1 = True
|
||||
cfg.misc.verboseLevel2 = True
|
||||
cfg.misc.minTraceLevel = 1900
|
||||
cfg.misc.maxTraceLevel = 3000
|
||||
cfg.etesian.effort = 2
|
||||
cfg.etesian.uniformDensity = True
|
||||
cfg.etesian.spaceMargin = 0.8
|
||||
cfg.etesian.aspectRatio = 1.0
|
||||
cfg.katana.eventsLimit = 1000000
|
||||
cfg.katana.termSatReservedLocal = 6
|
||||
cfg.katana.termSatThreshold = 9
|
||||
Viewer.Graphics.setStyle( 'Alliance.Classic [black]' )
|
||||
#af = CRL.AllianceFramework.get()
|
||||
#env = af.getEnvironment()
|
||||
#env.setCLOCK( '^ck$|m_clock|^clk$' )
|
||||
#env.addSYSTEM_LIBRARY( library=cellsTop+'/nsxlib', mode=CRL.Environment.Prepend )
|
||||
#env.addSYSTEM_LIBRARY( library=cellsTop+'/niolib', mode=CRL.Environment.Prepend )
|
|
@ -1,73 +1,61 @@
|
|||
#!/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()
|
||||
from Hurricane import DataBase, Box, Net, Vertical, Horizontal
|
||||
from CRL import AllianceFramework, Catalog
|
||||
from helpers import l
|
||||
from helpers.overlay import UpdateSession
|
||||
|
||||
|
||||
def drawLogo ( editor ):
|
||||
UpdateSession.open()
|
||||
|
||||
cell = AllianceFramework.get().createCell( 'coriolis_logo' )
|
||||
cell.setTerminal( True )
|
||||
|
||||
cell.setAbutmentBox( Box( toDbU(-16.0), toDbU(-16.0), toDbU(76.0), toDbU(76.0) ) )
|
||||
|
||||
"""Draw a small logo of Coriolis in GDS."""
|
||||
with UpdateSession():
|
||||
cell = AllianceFramework.get().createCell( 'coriolis_logo' )
|
||||
cell.setTerminalNetlist( True )
|
||||
cell.setAbutmentBox( Box( l(-16.0), l(-16.0), l(76.0), l(76.0) ) )
|
||||
|
||||
if editor:
|
||||
UpdateSession.close()
|
||||
editor.setCell( cell )
|
||||
editor.fit()
|
||||
UpdateSession.open()
|
||||
|
||||
technology = DataBase.getDB().getTechnology()
|
||||
metal1 = technology.getLayer( "metal1" )
|
||||
metal2 = technology.getLayer( "metal2" )
|
||||
metal4 = technology.getLayer( "metal4" )
|
||||
poly = technology.getLayer( "POLY" )
|
||||
ptrans = technology.getLayer( "PTRANS" )
|
||||
ntrans = technology.getLayer( "NTRANS" )
|
||||
pdif = technology.getLayer( "PDIF" )
|
||||
ndif = technology.getLayer( "NDIF" )
|
||||
contdifn = technology.getLayer( "CONT_DIF_N" )
|
||||
contdifp = technology.getLayer( "CONT_DIF_P" )
|
||||
nwell = technology.getLayer( "NWELL" )
|
||||
contpoly = technology.getLayer( "CONT_POLY" )
|
||||
ntie = technology.getLayer( "NTIE" )
|
||||
|
||||
net = Net.create( cell, 'logo' )
|
||||
net.setExternal( True )
|
||||
|
||||
Vertical .create( net, metal1, toDbU(10.0), toDbU(12.0), toDbU( 4.0), toDbU(56.0) )
|
||||
Horizontal.create( net, metal1, toDbU(50.0), toDbU(12.0), toDbU( 4.0), toDbU(56.0) )
|
||||
Vertical .create( net, metal1, toDbU(50.0), toDbU(12.0), toDbU(56.0), toDbU( 4.0) )
|
||||
Horizontal.create( net, metal1, toDbU(10.0), toDbU(12.0), toDbU(56.0), toDbU( 4.0) )
|
||||
|
||||
Vertical .create( net, metal1, toDbU(-6.0), toDbU(12.0), toDbU(22.0), toDbU(56.0) )
|
||||
Horizontal.create( net, metal1, toDbU(66.0), toDbU(12.0), toDbU(22.0), toDbU(56.0) )
|
||||
Vertical .create( net, metal1, toDbU(66.0), toDbU(12.0), toDbU(36.0), toDbU( 4.0) )
|
||||
Horizontal.create( net, metal1, toDbU(-6.0), toDbU(12.0), toDbU(36.0), toDbU( 4.0) )
|
||||
|
||||
Horizontal.create( net, nwell, toDbU(30.0), toDbU(92.0), toDbU(-16.0), toDbU(76.0) )
|
||||
|
||||
UpdateSession.close()
|
||||
|
||||
editor.setCell( cell )
|
||||
editor.fit()
|
||||
|
||||
with UpdateSession():
|
||||
technology = DataBase.getDB().getTechnology()
|
||||
metal1 = technology.getLayer( "metal1" )
|
||||
metal2 = technology.getLayer( "metal2" )
|
||||
metal4 = technology.getLayer( "metal4" )
|
||||
poly = technology.getLayer( "POLY" )
|
||||
ptrans = technology.getLayer( "PTRANS" )
|
||||
ntrans = technology.getLayer( "NTRANS" )
|
||||
pdif = technology.getLayer( "PDIF" )
|
||||
ndif = technology.getLayer( "NDIF" )
|
||||
contdifn = technology.getLayer( "CONT_DIF_N" )
|
||||
contdifp = technology.getLayer( "CONT_DIF_P" )
|
||||
nwell = technology.getLayer( "NWELL" )
|
||||
contpoly = technology.getLayer( "CONT_POLY" )
|
||||
ntie = technology.getLayer( "NTIE" )
|
||||
|
||||
net = Net.create( cell, 'logo' )
|
||||
net.setExternal( True )
|
||||
|
||||
Vertical .create( net, metal1, l(10.0), l(12.0), l( 4.0), l(56.0) )
|
||||
Horizontal.create( net, metal1, l(50.0), l(12.0), l( 4.0), l(56.0) )
|
||||
Vertical .create( net, metal1, l(50.0), l(12.0), l(56.0), l( 4.0) )
|
||||
Horizontal.create( net, metal1, l(10.0), l(12.0), l(56.0), l( 4.0) )
|
||||
|
||||
Vertical .create( net, metal1, l(-6.0), l(12.0), l(22.0), l(56.0) )
|
||||
Horizontal.create( net, metal1, l(66.0), l(12.0), l(22.0), l(56.0) )
|
||||
Vertical .create( net, metal1, l(66.0), l(12.0), l(36.0), l( 4.0) )
|
||||
Horizontal.create( net, metal1, l(-6.0), l(12.0), l(36.0), l( 4.0) )
|
||||
|
||||
Horizontal.create( net, nwell, l(30.0), l(92.0), l(-16.0), l(76.0) )
|
||||
|
||||
AllianceFramework.get().saveCell( cell, Catalog.State.Views )
|
||||
return
|
||||
|
||||
|
||||
def scriptMain ( **kw ):
|
||||
"""The mandatory function to be called by Coriolis CGT/Unicorn."""
|
||||
editor = None
|
||||
if kw.has_key('editor') and kw['editor']:
|
||||
editor = kw['editor']
|
||||
|
||||
if 'editor' in kw and kw['editor']:
|
||||
editor = kw['editor']
|
||||
drawLogo( editor )
|
||||
return True
|
||||
|
|
|
@ -1,34 +1,25 @@
|
|||
#!/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()
|
||||
from Hurricane import DataBase, DbU, Point, Box, Net, Vertical, Horizontal, Diagonal
|
||||
from CRL import AllianceFramework, Catalog, Gds
|
||||
from helpers import l
|
||||
from helpers.overlay import UpdateSession
|
||||
|
||||
|
||||
def buildDiagonals ( editor ):
|
||||
DbU.setPolygonStep( toDbU(1.0) )
|
||||
"""Check the Diagonal segments of Hurricane."""
|
||||
DbU.setPolygonStep( l(1.0) )
|
||||
|
||||
UpdateSession.open()
|
||||
with UpdateSession():
|
||||
cell = AllianceFramework.get().createCell( 'diagonal' )
|
||||
cell.setTerminalNetlist( True )
|
||||
|
||||
cell = AllianceFramework.get().createCell( 'diagonal' )
|
||||
cell.setTerminal( True )
|
||||
|
||||
cell.setAbutmentBox( Box( toDbU(-5.0), toDbU(-5.0), toDbU(65.0), toDbU(75.0) ) )
|
||||
cell.setAbutmentBox( Box( l(-5.0), l(-5.0), l(65.0), l(75.0) ) )
|
||||
|
||||
if editor:
|
||||
UpdateSession.close()
|
||||
editor.setCell( cell )
|
||||
editor.fit()
|
||||
UpdateSession.open()
|
||||
editor.setCell( cell )
|
||||
editor.fit()
|
||||
|
||||
technology = DataBase.getDB().getTechnology()
|
||||
metal1 = technology.getLayer( "metal1" )
|
||||
|
@ -45,45 +36,42 @@ def buildDiagonals ( editor ):
|
|||
contpoly = technology.getLayer( "CONT_POLY" )
|
||||
ntie = technology.getLayer( "NTIE" )
|
||||
|
||||
|
||||
net = Net.create( cell, 'my_net' )
|
||||
net.setExternal( True )
|
||||
|
||||
Diagonal.create( net, metal2
|
||||
, Point( toDbU(20.0), toDbU(10.0) )
|
||||
, Point( toDbU(10.0), toDbU(20.0) )
|
||||
, toDbU(4.0)
|
||||
)
|
||||
Vertical.create( net, metal2, toDbU(10.0), toDbU(4.0), toDbU(20.0), toDbU(30.0) )
|
||||
Diagonal.create( net, metal2
|
||||
, Point( toDbU(10.0), toDbU(30.0) )
|
||||
, Point( toDbU(20.0), toDbU(40.0) )
|
||||
, toDbU(4.0)
|
||||
)
|
||||
Horizontal.create( net, metal2, toDbU(40.0), toDbU(4.0), toDbU(20.0), toDbU(30.0) )
|
||||
Diagonal.create( net, metal2
|
||||
, Point( toDbU(30.0), toDbU(40.0) )
|
||||
, Point( toDbU(40.0), toDbU(30.0) )
|
||||
, toDbU(4.0)
|
||||
)
|
||||
Vertical.create( net, metal2, toDbU(40.0), toDbU(4.0), toDbU(30.0), toDbU(20.0) )
|
||||
Diagonal.create( net, metal2
|
||||
, Point( toDbU(40.0), toDbU(20.0) )
|
||||
, Point( toDbU(30.0), toDbU(10.0) )
|
||||
, toDbU(4.0)
|
||||
)
|
||||
Horizontal.create( net, metal2, toDbU(10.0), toDbU(4.0), toDbU(30.0), toDbU(20.0) )
|
||||
|
||||
UpdateSession.close()
|
||||
with UpdateSession():
|
||||
net = Net.create( cell, 'my_net' )
|
||||
net.setExternal( True )
|
||||
|
||||
Diagonal.create( net, metal2
|
||||
, Point( l(20.0), l(10.0) )
|
||||
, Point( l(10.0), l(20.0) )
|
||||
, l(4.0)
|
||||
)
|
||||
Vertical.create( net, metal2, l(10.0), l(4.0), l(20.0), l(30.0) )
|
||||
Diagonal.create( net, metal2
|
||||
, Point( l(10.0), l(30.0) )
|
||||
, Point( l(20.0), l(40.0) )
|
||||
, l(4.0)
|
||||
)
|
||||
Horizontal.create( net, metal2, l(40.0), l(4.0), l(20.0), l(30.0) )
|
||||
Diagonal.create( net, metal2
|
||||
, Point( l(30.0), l(40.0) )
|
||||
, Point( l(40.0), l(30.0) )
|
||||
, l(4.0)
|
||||
)
|
||||
Vertical.create( net, metal2, l(40.0), l(4.0), l(30.0), l(20.0) )
|
||||
Diagonal.create( net, metal2
|
||||
, Point( l(40.0), l(20.0) )
|
||||
, Point( l(30.0), l(10.0) )
|
||||
, l(4.0)
|
||||
)
|
||||
Horizontal.create( net, metal2, l(10.0), l(4.0), l(30.0), l(20.0) )
|
||||
|
||||
Gds.save( cell )
|
||||
return
|
||||
|
||||
|
||||
def scriptMain ( **kw ):
|
||||
"""The mandatory function to be called by Coriolis CGT/Unicorn."""
|
||||
editor = None
|
||||
if kw.has_key('editor') and kw['editor']:
|
||||
editor = kw['editor']
|
||||
|
||||
if 'editor' in kw and kw['editor']:
|
||||
editor = kw['editor']
|
||||
buildDiagonals( editor )
|
||||
return True
|
||||
|
|
|
@ -1,172 +1,175 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
from Hurricane import *
|
||||
from CRL import *
|
||||
|
||||
|
||||
def toDbU ( l ): return DbU.fromLambda(l)
|
||||
from Hurricane import DataBase, Instance, Box, Net, Horizontal, Vertical, Contact, \
|
||||
RoutingPad, Transformation, Occurrence, \
|
||||
Breakpoint
|
||||
from CRL import AllianceFramework, Catalog, Gds
|
||||
from helpers import l
|
||||
from helpers.overlay import UpdateSession
|
||||
|
||||
|
||||
def doBreak ( level, message ):
|
||||
UpdateSession.close()
|
||||
Breakpoint.stop( level, message )
|
||||
UpdateSession.open()
|
||||
|
||||
|
||||
def buildFulladder ( editor ):
|
||||
|
||||
# Get the Framework and all the master cells.
|
||||
"""
|
||||
Build a full adder, place it, add filler cells and create routing
|
||||
for the "a" net.
|
||||
"""
|
||||
# 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) ) )
|
||||
|
||||
with UpdateSession():
|
||||
fulladder = af.createCell( 'fulladder' )
|
||||
fulladder.setAbutmentBox( Box( l(0.0), l(0.0), l(90.0), l(100.0) ) )
|
||||
if editor:
|
||||
UpdateSession.close()
|
||||
editor.setCell( fulladder )
|
||||
editor.fit()
|
||||
UpdateSession.open()
|
||||
editor.setCell( fulladder )
|
||||
editor.fit()
|
||||
|
||||
# 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 )
|
||||
with UpdateSession():
|
||||
# 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 )
|
||||
# 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' )
|
||||
with UpdateSession():
|
||||
# Instances placement.
|
||||
a2_1.setTransformation( Transformation( l(0.0)
|
||||
, l(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' )
|
||||
with UpdateSession():
|
||||
xr2_1.setTransformation( Transformation( l( 0.0)
|
||||
, l(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' )
|
||||
with UpdateSession():
|
||||
a2_2.setTransformation( Transformation( l(25.0)
|
||||
, l( 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' )
|
||||
with UpdateSession():
|
||||
xr2_2.setTransformation( Transformation( l( 45.0)
|
||||
, l(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' )
|
||||
with UpdateSession():
|
||||
o2_1.setTransformation( Transformation( l(65.0)
|
||||
, l( 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.
|
||||
with UpdateSession():
|
||||
# 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( l(50.0)
|
||||
, l( 0.0)
|
||||
, Transformation.Orientation.ID ) )
|
||||
filler_1.setPlacementStatus( Instance.PlacementStatus.PLACED )
|
||||
|
||||
filler_2.setTransformation( Transformation( l(60.0)
|
||||
, l( 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()
|
||||
with UpdateSession():
|
||||
# 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, l( 0.0), l(-15.0) )
|
||||
contact2 = Contact.create( rp2, via12, l( 0.0), l( 10.0) )
|
||||
turn = Contact.create( a , via23, l(10.0), l( 35.0) )
|
||||
Horizontal.create( contact2, turn , metal2, l(35.0), l(2.0) )
|
||||
Vertical .create( turn , contact1, metal3, l(10.0), l(2.0) )
|
||||
|
||||
af.saveCell( fulladder, Catalog.State.Views )
|
||||
Gds.save( fulladder )
|
||||
return
|
||||
|
||||
|
||||
def scriptMain ( **kw ):
|
||||
"""The mandatory function to be called by Coriolis CGT/Unicorn."""
|
||||
editor = None
|
||||
if kw.has_key('editor') and kw['editor']:
|
||||
editor = kw['editor']
|
||||
|
||||
if 'editor' in kw and kw['editor']:
|
||||
editor = kw['editor']
|
||||
buildFulladder( editor )
|
||||
return True
|
||||
|
|
|
@ -1,32 +1,28 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
from Hurricane import *
|
||||
from CRL import *
|
||||
|
||||
|
||||
def toDbU ( l ): return DbU.fromLambda(l)
|
||||
from Hurricane import DataBase, NetExternalComponents, Net, \
|
||||
DbU, Point, Box, Horizontal, Vertical, Contact, RoutingPad, \
|
||||
Breakpoint
|
||||
from CRL import AllianceFramework, Catalog
|
||||
from helpers import l
|
||||
from helpers.overlay import UpdateSession
|
||||
|
||||
|
||||
def doBreak ( level, message ):
|
||||
UpdateSession.close()
|
||||
"""Put a breakpoint into the script."""
|
||||
Breakpoint.stop( level, message )
|
||||
UpdateSession.open()
|
||||
|
||||
|
||||
def buildInvertor ( editor ):
|
||||
UpdateSession.open()
|
||||
|
||||
cell = AllianceFramework.get().createCell( 'invertor' )
|
||||
cell.setTerminal( True )
|
||||
|
||||
cell.setAbutmentBox( Box( toDbU(0.0), toDbU(0.0), toDbU(15.0), toDbU(50.0) ) )
|
||||
|
||||
"""Build step by step an invertor standard cell."""
|
||||
with UpdateSession():
|
||||
cell = AllianceFramework.get().createCell( 'invertor' )
|
||||
cell.setTerminalNetlist( True )
|
||||
cell.setAbutmentBox( Box( l(0.0), l(0.0), l(15.0), l(50.0) ) )
|
||||
if editor:
|
||||
UpdateSession.close()
|
||||
editor.setCell( cell )
|
||||
editor.fit()
|
||||
UpdateSession.open()
|
||||
editor.setCell( cell )
|
||||
editor.fit()
|
||||
|
||||
technology = DataBase.getDB().getTechnology()
|
||||
metal1 = technology.getLayer( "METAL1" )
|
||||
|
@ -41,61 +37,62 @@ def buildInvertor ( editor ):
|
|||
contpoly = technology.getLayer( "CONT_POLY" )
|
||||
ntie = technology.getLayer( "NTIE" )
|
||||
|
||||
net = Net.create( cell, "nwell" )
|
||||
Vertical.create( net, nwell, toDbU(7.5), toDbU(15.0), toDbU(27.0), toDbU(51.0) )
|
||||
|
||||
vdd = Net.create( cell, "vdd" )
|
||||
vdd.setExternal( True )
|
||||
vdd.setGlobal ( True )
|
||||
h = Horizontal.create(vdd, metal1, toDbU(47.0), toDbU(6.0), toDbU(0.0), toDbU(15.0) )
|
||||
NetExternalComponents.setExternal( h )
|
||||
Contact.create ( vdd, contdifn, toDbU(10.0), toDbU(47.0), toDbU( 1.0), toDbU( 1.0) )
|
||||
Contact.create ( vdd, contdifp, toDbU( 4.0), toDbU(45.0), toDbU( 1.0), toDbU( 1.0) )
|
||||
Vertical.create( vdd, pdif , toDbU( 3.5), toDbU( 4.0), toDbU(28.0), toDbU(46.0) )
|
||||
Vertical.create( vdd, ntie , toDbU(10.0), toDbU( 3.0), toDbU(43.0), toDbU(48.0) )
|
||||
with UpdateSession():
|
||||
net = Net.create( cell, "nwell" )
|
||||
Vertical.create( net, nwell, l(7.5), l(15.0), l(27.0), l(51.0) )
|
||||
|
||||
vdd = Net.create( cell, "vdd" )
|
||||
vdd.setExternal( True )
|
||||
vdd.setGlobal ( True )
|
||||
h = Horizontal.create(vdd, metal1, l(47.0), l(6.0), l(0.0), l(15.0) )
|
||||
NetExternalComponents.setExternal( h )
|
||||
Contact.create ( vdd, contdifn, l(10.0), l(47.0), l( 1.0), l( 1.0) )
|
||||
Contact.create ( vdd, contdifp, l( 4.0), l(45.0), l( 1.0), l( 1.0) )
|
||||
Vertical.create( vdd, pdif , l( 3.5), l( 4.0), l(28.0), l(46.0) )
|
||||
Vertical.create( vdd, ntie , l(10.0), l( 3.0), l(43.0), l(48.0) )
|
||||
doBreak( 1, 'Done building vdd.' )
|
||||
|
||||
vss = Net.create( cell, "vss" )
|
||||
vss.setExternal( True )
|
||||
vss.setGlobal ( True )
|
||||
h = Horizontal.create(vss, metal1, toDbU(3.0), toDbU(6.0), toDbU(0.0), toDbU(15.0))
|
||||
NetExternalComponents.setExternal( h )
|
||||
Vertical.create( vss, ndif , toDbU(3.5), toDbU(4.0), toDbU(4.0), toDbU(12.0) )
|
||||
Contact.create ( vss, contdifn, toDbU(4.0), toDbU(5.0), toDbU(1.0), toDbU( 1.0) )
|
||||
with UpdateSession():
|
||||
vss = Net.create( cell, "vss" )
|
||||
vss.setExternal( True )
|
||||
vss.setGlobal ( True )
|
||||
h = Horizontal.create(vss, metal1, l(3.0), l(6.0), l(0.0), l(15.0))
|
||||
NetExternalComponents.setExternal( h )
|
||||
Vertical.create( vss, ndif , l(3.5), l(4.0), l(4.0), l(12.0) )
|
||||
Contact.create ( vss, contdifn, l(4.0), l(5.0), l(1.0), l( 1.0) )
|
||||
doBreak( 1, 'Done building vss.' )
|
||||
|
||||
i = Net.create( cell, "i" )
|
||||
i.setExternal( True )
|
||||
v = Vertical.create ( i, metal1, toDbU(5.0), toDbU(2.0), toDbU(10.0), toDbU(40.0) )
|
||||
NetExternalComponents.setExternal( v )
|
||||
Vertical.create ( i, ptrans , toDbU( 7.0), toDbU( 1.0), toDbU(26.0), toDbU(39.0) )
|
||||
Vertical.create ( i, ntrans , toDbU( 7.0), toDbU( 1.0), toDbU( 6.0), toDbU(14.0) )
|
||||
Vertical.create ( i, poly , toDbU( 7.0), toDbU( 1.0), toDbU(14.0), toDbU(26.0) )
|
||||
Horizontal.create( i, poly , toDbU(20.0), toDbU( 3.0), toDbU( 4.0), toDbU( 7.0) )
|
||||
Contact.create ( i, contpoly, toDbU( 5.0), toDbU(20.0), toDbU( 1.0), toDbU( 1.0) )
|
||||
with UpdateSession():
|
||||
i = Net.create( cell, "i" )
|
||||
i.setExternal( True )
|
||||
v = Vertical.create ( i, metal1, l(5.0), l(2.0), l(10.0), l(40.0) )
|
||||
NetExternalComponents.setExternal( v )
|
||||
Vertical.create ( i, ptrans , l( 7.0), l( 1.0), l(26.0), l(39.0) )
|
||||
Vertical.create ( i, ntrans , l( 7.0), l( 1.0), l( 6.0), l(14.0) )
|
||||
Vertical.create ( i, poly , l( 7.0), l( 1.0), l(14.0), l(26.0) )
|
||||
Horizontal.create( i, poly , l(20.0), l( 3.0), l( 4.0), l( 7.0) )
|
||||
Contact.create ( i, contpoly, l( 5.0), l(20.0), l( 1.0), l( 1.0) )
|
||||
doBreak( 1, 'Done building i.' )
|
||||
|
||||
nq = Net.create ( cell, "nq" )
|
||||
nq.setExternal( True )
|
||||
v = Vertical.create( nq, metal1, toDbU(10.0), toDbU(2.0), toDbU(10.0), toDbU(40.0) )
|
||||
NetExternalComponents.setExternal( v )
|
||||
Vertical.create( nq, pdif , toDbU(10.0), toDbU( 3.0), toDbU(28.0), toDbU(37.0) )
|
||||
Vertical.create( nq, ndif , toDbU(10.0), toDbU( 3.0), toDbU( 8.0), toDbU(12.0) )
|
||||
Contact.create ( nq, contdifp, toDbU(10.0), toDbU(35.0), toDbU( 1.0), toDbU( 1.0) )
|
||||
Contact.create ( nq, contdifp, toDbU(10.0), toDbU(30.5), toDbU( 1.0), toDbU( 1.0) )
|
||||
Contact.create ( nq, contdifn, toDbU(10.0), toDbU(10.0), toDbU( 1.0), toDbU( 1.0) )
|
||||
with UpdateSession():
|
||||
nq = Net.create ( cell, "nq" )
|
||||
nq.setExternal( True )
|
||||
v = Vertical.create( nq, metal1, l(10.0), l(2.0), l(10.0), l(40.0) )
|
||||
NetExternalComponents.setExternal( v )
|
||||
Vertical.create( nq, pdif , l(10.0), l( 3.0), l(28.0), l(37.0) )
|
||||
Vertical.create( nq, ndif , l(10.0), l( 3.0), l( 8.0), l(12.0) )
|
||||
Contact.create ( nq, contdifp, l(10.0), l(35.0), l( 1.0), l( 1.0) )
|
||||
Contact.create ( nq, contdifp, l(10.0), l(30.5), l( 1.0), l( 1.0) )
|
||||
Contact.create ( nq, contdifn, l(10.0), l(10.0), l( 1.0), l( 1.0) )
|
||||
doBreak( 1, 'Done building q.' )
|
||||
|
||||
UpdateSession.close()
|
||||
|
||||
AllianceFramework.get().saveCell( cell, Catalog.State.Views )
|
||||
return
|
||||
|
||||
|
||||
def scriptMain ( **kw ):
|
||||
"""The mandatory function to be called by Coriolis CGT/Unicorn."""
|
||||
editor = None
|
||||
if kw.has_key('editor') and kw['editor']:
|
||||
editor = kw['editor']
|
||||
|
||||
if 'editor' in kw and kw['editor']:
|
||||
editor = kw['editor']
|
||||
buildInvertor( editor )
|
||||
return True
|
||||
|
|
|
@ -1,36 +1,24 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
from Hurricane import *
|
||||
from CRL import *
|
||||
|
||||
|
||||
def toDbU ( l ): return DbU.fromLambda(l)
|
||||
def toMicron ( u ): return DbU.toPhysical( u, DbU.UnitPowerMicro )
|
||||
|
||||
|
||||
def doBreak ( level, message ):
|
||||
UpdateSession.close()
|
||||
Breakpoint.stop( level, message )
|
||||
UpdateSession.open()
|
||||
from Hurricane import DataBase, NetExternalComponents, Net, \
|
||||
DbU, Point, Box, Polygon
|
||||
from CRL import AllianceFramework, Catalog, Gds
|
||||
from helpers import l, u
|
||||
from helpers.overlay import UpdateSession
|
||||
|
||||
|
||||
def buildPolygons ( editor ):
|
||||
#DbU.setPolygonStep( toDbU(0.1) )
|
||||
|
||||
UpdateSession.open()
|
||||
|
||||
cell = AllianceFramework.get().createCell( 'polygons' )
|
||||
cell.setTerminal( True )
|
||||
|
||||
cell.setAbutmentBox( Box( toDbU(-5.0), toDbU(-5.0), toDbU(65.0), toDbU(75.0) ) )
|
||||
#cell.setAbutmentBox( Box( toDbU(-5.0), toDbU(-5.0), toDbU(21.0), toDbU(35.0) ) )
|
||||
|
||||
"""Draw a set of Polygons checking all possible combination."""
|
||||
#DbU.setPolygonStep( l(0.1) )
|
||||
with UpdateSession():
|
||||
cell = AllianceFramework.get().createCell( 'polygons' )
|
||||
cell.setTerminalNetlist( True )
|
||||
cell.setAbutmentBox( Box( l(-5.0), l(-5.0), l(65.0), l(75.0) ) )
|
||||
#cell.setAbutmentBox( Box( l(-5.0), l(-5.0), l(21.0), l(35.0) ) )
|
||||
if editor:
|
||||
UpdateSession.close()
|
||||
editor.setCell( cell )
|
||||
editor.fit()
|
||||
UpdateSession.open()
|
||||
editor.setCell( cell )
|
||||
editor.fit()
|
||||
|
||||
technology = DataBase.getDB().getTechnology()
|
||||
metal1 = technology.getLayer( "METAL1" )
|
||||
|
@ -48,124 +36,117 @@ def buildPolygons ( editor ):
|
|||
contpoly = technology.getLayer( "CONT_POLY" )
|
||||
ntie = technology.getLayer( "NTIE" )
|
||||
|
||||
|
||||
net = Net.create( cell, 'my_net' )
|
||||
net.setExternal( True )
|
||||
#points = [ Point( toDbU( 0.0), toDbU( 0.0) )
|
||||
# , Point( toDbU( 10.0), toDbU( 0.0) )
|
||||
# , Point( toDbU( 7.0), toDbU( 8.0) )
|
||||
# , Point( toDbU( 3.0), toDbU( 8.0) ) ]
|
||||
#p = Polygon.create( net, metal4, points )
|
||||
|
||||
# Counter-clockwise, slope > 1.
|
||||
points = [ Point( toDbU( 3.0), toDbU( 0.0) )
|
||||
, Point( toDbU( 13.0), toDbU( 0.0) )
|
||||
, Point( toDbU( 16.0), toDbU( 10.0) )
|
||||
, Point( toDbU( 16.0), toDbU( 20.0) )
|
||||
, Point( toDbU( 13.0), toDbU( 30.0) )
|
||||
, Point( toDbU( 3.0), toDbU( 30.0) )
|
||||
, Point( toDbU( 0.0), toDbU( 20.0) )
|
||||
, Point( toDbU( 0.0), toDbU( 10.0) ) ]
|
||||
p = Polygon.create( net, metal2, points )
|
||||
#p.translate( toDbU(40.0), toDbU(0.0) )
|
||||
|
||||
# clockwise, slope > 1.
|
||||
points = [ Point( toDbU( 0.0), toDbU( 10.0) )
|
||||
, Point( toDbU( 0.0), toDbU( 20.0) )
|
||||
, Point( toDbU( 3.0), toDbU( 30.0) )
|
||||
, Point( toDbU( 13.0), toDbU( 30.0) )
|
||||
, Point( toDbU( 16.0), toDbU( 20.0) )
|
||||
, Point( toDbU( 16.0), toDbU( 10.0) )
|
||||
, Point( toDbU( 13.0), toDbU( 0.0) )
|
||||
, Point( toDbU( 3.0), toDbU( 0.0) ) ]
|
||||
p = Polygon.create( net, metal2, points )
|
||||
p.translate( toDbU(0.0), toDbU(40.0) )
|
||||
|
||||
# Counter-clockwise, slope < 1.
|
||||
points = [ Point( toDbU( 10.0), toDbU( 0.0) )
|
||||
, Point( toDbU( 20.0), toDbU( 0.0) )
|
||||
, Point( toDbU( 30.0), toDbU( 3.0) )
|
||||
, Point( toDbU( 30.0), toDbU( 13.0) )
|
||||
, Point( toDbU( 20.0), toDbU( 16.0) )
|
||||
, Point( toDbU( 10.0), toDbU( 16.0) )
|
||||
, Point( toDbU( 0.0), toDbU( 13.0) )
|
||||
, Point( toDbU( 0.0), toDbU( 3.0) ) ]
|
||||
p = Polygon.create( net, metal2, points )
|
||||
p.translate( toDbU(30.0), toDbU(0.0) )
|
||||
|
||||
# clockwise.
|
||||
points = [ Point( toDbU( 0.0), toDbU( 3.0) )
|
||||
, Point( toDbU( 0.0), toDbU( 13.0) )
|
||||
, Point( toDbU( 10.0), toDbU( 16.0) )
|
||||
, Point( toDbU( 20.0), toDbU( 16.0) )
|
||||
, Point( toDbU( 30.0), toDbU( 13.0) )
|
||||
, Point( toDbU( 30.0), toDbU( 3.0) )
|
||||
, Point( toDbU( 20.0), toDbU( 0.0) )
|
||||
, Point( toDbU( 10.0), toDbU( 0.0) ) ]
|
||||
p = Polygon.create( net, metal2, points )
|
||||
p.translate( toDbU(30.0), toDbU(40.0) )
|
||||
|
||||
# Big parallelogram.
|
||||
points = [ Point( toDbU( 0.0), toDbU( 0.0) )
|
||||
, Point( toDbU( 20.0), toDbU( 20.0) )
|
||||
, Point( toDbU( 60.0), toDbU( 20.0) )
|
||||
, Point( toDbU( 40.0), toDbU( 0.0) ) ]
|
||||
p = Polygon.create( net, metal3, points )
|
||||
p.translate( toDbU(70.0), toDbU(0.0) )
|
||||
with UpdateSession():
|
||||
net = Net.create( cell, 'my_net' )
|
||||
net.setExternal( True )
|
||||
#points = [ Point( l( 0.0), l( 0.0) )
|
||||
# , Point( l( 10.0), l( 0.0) )
|
||||
# , Point( l( 7.0), l( 8.0) )
|
||||
# , Point( l( 3.0), l( 8.0) ) ]
|
||||
#p = Polygon.create( net, metal4, points )
|
||||
|
||||
points = [ Point( toDbU( 0.0), toDbU( 20.0) )
|
||||
, Point( toDbU( 40.0), toDbU( 20.0) )
|
||||
, Point( toDbU( 60.0), toDbU( 0.0) )
|
||||
, Point( toDbU( 20.0), toDbU( 0.0) ) ]
|
||||
p = Polygon.create( net, metal3, points )
|
||||
p.translate( toDbU(140.0), toDbU(0.0) )
|
||||
# Counter-clockwise, slope > 1.
|
||||
points = [ Point( l( 3.0), l( 0.0) )
|
||||
, Point( l( 13.0), l( 0.0) )
|
||||
, Point( l( 16.0), l( 10.0) )
|
||||
, Point( l( 16.0), l( 20.0) )
|
||||
, Point( l( 13.0), l( 30.0) )
|
||||
, Point( l( 3.0), l( 30.0) )
|
||||
, Point( l( 0.0), l( 20.0) )
|
||||
, Point( l( 0.0), l( 10.0) ) ]
|
||||
p = Polygon.create( net, metal2, points )
|
||||
#p.translate( l(40.0), l(0.0) )
|
||||
|
||||
points = [ Point( toDbU( 0.0), toDbU( 0.0) )
|
||||
, Point( toDbU( 0.0), toDbU( 10.0) )
|
||||
, Point( toDbU( 20.0), toDbU( 30.0) )
|
||||
, Point( toDbU( 60.0), toDbU( 30.0) )
|
||||
, Point( toDbU( 60.0), toDbU( 20.0) )
|
||||
, Point( toDbU( 40.0), toDbU( 0.0) ) ]
|
||||
p = Polygon.create( net, metal3, points )
|
||||
p.translate( toDbU(70.0), toDbU(40.0) )
|
||||
# clockwise, slope > 1.
|
||||
points = [ Point( l( 0.0), l( 10.0) )
|
||||
, Point( l( 0.0), l( 20.0) )
|
||||
, Point( l( 3.0), l( 30.0) )
|
||||
, Point( l( 13.0), l( 30.0) )
|
||||
, Point( l( 16.0), l( 20.0) )
|
||||
, Point( l( 16.0), l( 10.0) )
|
||||
, Point( l( 13.0), l( 0.0) )
|
||||
, Point( l( 3.0), l( 0.0) ) ]
|
||||
p = Polygon.create( net, metal2, points )
|
||||
p.translate( l(0.0), l(40.0) )
|
||||
|
||||
points = [ Point( toDbU( 0.0), toDbU( 20.0) )
|
||||
, Point( toDbU( 0.0), toDbU( 30.0) )
|
||||
, Point( toDbU( 40.0), toDbU( 30.0) )
|
||||
, Point( toDbU( 60.0), toDbU( 10.0) )
|
||||
, Point( toDbU( 60.0), toDbU( 0.0) )
|
||||
, Point( toDbU( 20.0), toDbU( 0.0) ) ]
|
||||
p = Polygon.create( net, metal3, points )
|
||||
p.translate( toDbU(140.0), toDbU(40.0) )
|
||||
|
||||
|
||||
print 'Normalized and manhattanized contour:'
|
||||
i = 0
|
||||
for point in p.getMContour():
|
||||
print '| %d '%i, point \
|
||||
, '[%fum %fum]' % ( toMicron(point.getX()) \
|
||||
, toMicron(point.getY()) )
|
||||
i += 1
|
||||
|
||||
print 'Sub-polygons (for GDSII generation)'
|
||||
subpolygons = p.getSubPolygons()
|
||||
for i in range(len(subpolygons)):
|
||||
print '+ Sub-Polygon %d:' % i
|
||||
for j in range(len(subpolygons[i])):
|
||||
print ' [%3d]' % j, subpolygons[i][j] \
|
||||
, '[%fum %fum]' % ( toMicron(subpolygons[i][j].getX()) \
|
||||
, toMicron(subpolygons[i][j].getY()) )
|
||||
|
||||
UpdateSession.close()
|
||||
# Counter-clockwise, slope < 1.
|
||||
points = [ Point( l( 10.0), l( 0.0) )
|
||||
, Point( l( 20.0), l( 0.0) )
|
||||
, Point( l( 30.0), l( 3.0) )
|
||||
, Point( l( 30.0), l( 13.0) )
|
||||
, Point( l( 20.0), l( 16.0) )
|
||||
, Point( l( 10.0), l( 16.0) )
|
||||
, Point( l( 0.0), l( 13.0) )
|
||||
, Point( l( 0.0), l( 3.0) ) ]
|
||||
p = Polygon.create( net, metal2, points )
|
||||
p.translate( l(30.0), l(0.0) )
|
||||
|
||||
# clockwise.
|
||||
points = [ Point( l( 0.0), l( 3.0) )
|
||||
, Point( l( 0.0), l( 13.0) )
|
||||
, Point( l( 10.0), l( 16.0) )
|
||||
, Point( l( 20.0), l( 16.0) )
|
||||
, Point( l( 30.0), l( 13.0) )
|
||||
, Point( l( 30.0), l( 3.0) )
|
||||
, Point( l( 20.0), l( 0.0) )
|
||||
, Point( l( 10.0), l( 0.0) ) ]
|
||||
p = Polygon.create( net, metal2, points )
|
||||
p.translate( l(30.0), l(40.0) )
|
||||
|
||||
# Big parallelogram.
|
||||
points = [ Point( l( 0.0), l( 0.0) )
|
||||
, Point( l( 20.0), l( 20.0) )
|
||||
, Point( l( 60.0), l( 20.0) )
|
||||
, Point( l( 40.0), l( 0.0) ) ]
|
||||
p = Polygon.create( net, metal3, points )
|
||||
p.translate( l(70.0), l(0.0) )
|
||||
|
||||
points = [ Point( l( 0.0), l( 20.0) )
|
||||
, Point( l( 40.0), l( 20.0) )
|
||||
, Point( l( 60.0), l( 0.0) )
|
||||
, Point( l( 20.0), l( 0.0) ) ]
|
||||
p = Polygon.create( net, metal3, points )
|
||||
p.translate( l(140.0), l(0.0) )
|
||||
|
||||
points = [ Point( l( 0.0), l( 0.0) )
|
||||
, Point( l( 0.0), l( 10.0) )
|
||||
, Point( l( 20.0), l( 30.0) )
|
||||
, Point( l( 60.0), l( 30.0) )
|
||||
, Point( l( 60.0), l( 20.0) )
|
||||
, Point( l( 40.0), l( 0.0) ) ]
|
||||
p = Polygon.create( net, metal3, points )
|
||||
p.translate( l(70.0), l(40.0) )
|
||||
|
||||
points = [ Point( l( 0.0), l( 20.0) )
|
||||
, Point( l( 0.0), l( 30.0) )
|
||||
, Point( l( 40.0), l( 30.0) )
|
||||
, Point( l( 60.0), l( 10.0) )
|
||||
, Point( l( 60.0), l( 0.0) )
|
||||
, Point( l( 20.0), l( 0.0) ) ]
|
||||
p = Polygon.create( net, metal3, points )
|
||||
p.translate( l(140.0), l(40.0) )
|
||||
|
||||
print( 'Normalized and manhattanized contour:' )
|
||||
i = 0
|
||||
for point in p.getMContour():
|
||||
print( '| %d '%i, point, '[%fum %fum]' % ( u(point.getX()), u(point.getY()) ))
|
||||
i += 1
|
||||
|
||||
print( 'Sub-polygons (for GDSII generation)' )
|
||||
subpolygons = p.getSubPolygons()
|
||||
for i in range(len(subpolygons)):
|
||||
print( '+ Sub-Polygon %d:' % i )
|
||||
for j in range(len(subpolygons[i])):
|
||||
print( ' [%3d]' % j, subpolygons[i][j] \
|
||||
, '[%fum %fum]' % ( u(subpolygons[i][j].getX()), u(subpolygons[i][j].getY()) ))
|
||||
|
||||
Gds.save( cell )
|
||||
return
|
||||
|
||||
|
||||
def scriptMain ( **kw ):
|
||||
"""The mandatory function to be called by Coriolis CGT/Unicorn."""
|
||||
editor = None
|
||||
if kw.has_key('editor') and kw['editor']:
|
||||
editor = kw['editor']
|
||||
|
||||
if 'editor' in kw and kw['editor']:
|
||||
editor = kw['editor']
|
||||
buildPolygons( editor )
|
||||
return True
|
||||
|
|
|
@ -1,34 +1,23 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
from Hurricane import *
|
||||
from CRL import *
|
||||
|
||||
|
||||
def toDbU ( l ): return DbU.fromLambda(l)
|
||||
def toMicron ( u ): return DbU.toPhysical( u, DbU.UnitPowerMicro )
|
||||
|
||||
|
||||
def doBreak ( level, message ):
|
||||
UpdateSession.close()
|
||||
Breakpoint.stop( level, message )
|
||||
UpdateSession.open()
|
||||
from Hurricane import DataBase, Net, \
|
||||
DbU, Point, Box, Rectilinear
|
||||
from CRL import AllianceFramework, Catalog, Gds
|
||||
from helpers import l, u
|
||||
from helpers.overlay import UpdateSession
|
||||
|
||||
|
||||
def buildRectilinear ( editor ):
|
||||
UpdateSession.open()
|
||||
|
||||
cell = AllianceFramework.get().createCell( 'Rectilinear' )
|
||||
cell.setTerminal( True )
|
||||
|
||||
cell.setAbutmentBox( Box( toDbU(-5.0), toDbU(-5.0), toDbU(65.0), toDbU(75.0) ) )
|
||||
#cell.setAbutmentBox( Box( toDbU(-5.0), toDbU(-5.0), toDbU(21.0), toDbU(35.0) ) )
|
||||
|
||||
"""Check Hurricane.Rectilinear class."""
|
||||
with UpdateSession():
|
||||
cell = AllianceFramework.get().createCell( 'Rectilinear' )
|
||||
cell.setTerminalNetlist( True )
|
||||
cell.setAbutmentBox( Box( l(-5.0), l(-5.0), l(65.0), l(75.0) ) )
|
||||
#cell.setAbutmentBox( Box( l(-5.0), l(-5.0), l(21.0), l(35.0) ) )
|
||||
if editor:
|
||||
UpdateSession.close()
|
||||
editor.setCell( cell )
|
||||
editor.fit()
|
||||
UpdateSession.open()
|
||||
editor.setCell( cell )
|
||||
editor.fit()
|
||||
|
||||
technology = DataBase.getDB().getTechnology()
|
||||
metal1 = technology.getLayer( "METAL1" )
|
||||
|
@ -46,37 +35,32 @@ def buildRectilinear ( editor ):
|
|||
contpoly = technology.getLayer( "CONT_POLY" )
|
||||
ntie = technology.getLayer( "NTIE" )
|
||||
|
||||
|
||||
net = Net.create( cell, 'my_net' )
|
||||
net.setExternal( True )
|
||||
|
||||
points = [ Point( toDbU( 0.0), toDbU( 0.0) )
|
||||
, Point( toDbU( 0.0), toDbU( 10.0) )
|
||||
, Point( toDbU( 20.0), toDbU( 30.0) )
|
||||
, Point( toDbU( 30.0), toDbU( 30.0) )
|
||||
, Point( toDbU( 30.0), toDbU( 20.0) )
|
||||
, Point( toDbU( 10.0), toDbU( 0.0) ) ]
|
||||
r = Rectilinear.create( net, metal2, points )
|
||||
|
||||
|
||||
#print 'Normalized and manhattanized contour:'
|
||||
#i = 0
|
||||
#for point in p.getMContour():
|
||||
# print '| %d '%i, point \
|
||||
# , '[%fum %fum]' % ( toMicron(point.getX()) \
|
||||
# , toMicron(point.getY()) )
|
||||
# i += 1
|
||||
|
||||
UpdateSession.close()
|
||||
with UpdateSession():
|
||||
net = Net.create( cell, 'my_net' )
|
||||
net.setExternal( True )
|
||||
|
||||
points = [ Point( l( 0.0), l( 0.0) )
|
||||
, Point( l( 0.0), l( 10.0) )
|
||||
, Point( l( 20.0), l( 30.0) )
|
||||
, Point( l( 30.0), l( 30.0) )
|
||||
, Point( l( 30.0), l( 20.0) )
|
||||
, Point( l( 10.0), l( 0.0) ) ]
|
||||
r = Rectilinear.create( net, metal2, points )
|
||||
|
||||
|
||||
#print( 'Normalized and manhattanized contour:' )
|
||||
#i = 0
|
||||
#for point in p.getMContour():
|
||||
# print( '| %d '%i, point, '[%fum %fum]' % ( u(point.getX()), u(point.getY()) ))
|
||||
# i += 1
|
||||
|
||||
Gds.save( cell )
|
||||
return
|
||||
|
||||
|
||||
def scriptMain ( **kw ):
|
||||
"""The mandatory function to be called by Coriolis CGT/Unicorn."""
|
||||
editor = None
|
||||
if kw.has_key('editor') and kw['editor']:
|
||||
editor = kw['editor']
|
||||
|
||||
if 'editor' in kw and kw['editor']:
|
||||
editor = kw['editor']
|
||||
buildRectilinear( editor )
|
||||
return True
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import sys
|
||||
from Hurricane import *
|
||||
from CRL import *
|
||||
from Hurricane import Instance, Net, Horizontal, Vertical, Contact, \
|
||||
RoutingPad, Transformation, \
|
||||
Breakpoint
|
||||
from CRL import AllianceFramework, Catalog
|
||||
from helpers import l
|
||||
from helpers.overlay import UpdateSession
|
||||
import Etesian
|
||||
import Anabatic
|
||||
import Katana
|
||||
|
@ -11,112 +15,109 @@ import Katana
|
|||
af = AllianceFramework.get()
|
||||
|
||||
|
||||
def toDbU ( l ): return DbU.fromLambda(l)
|
||||
|
||||
|
||||
def doBreak ( level, message ):
|
||||
UpdateSession.close()
|
||||
Breakpoint.stop( level, message )
|
||||
UpdateSession.open()
|
||||
|
||||
|
||||
def buildFulladder ( editor ):
|
||||
"""Build the netlist of a full adder."""
|
||||
|
||||
# Get the Framework and all the master cells.
|
||||
# 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()
|
||||
with UpdateSession():
|
||||
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 )
|
||||
|
||||
af.saveCell( fulladder, Catalog.State.Views )
|
||||
return fulladder
|
||||
|
||||
|
||||
def placeAndRoute ( editor, cell ):
|
||||
# Run the placer.
|
||||
etesian = Etesian.EtesianEngine.create(cell)
|
||||
"""
|
||||
Direct call of the ToolEngines:
|
||||
|
||||
* Etesian: placement.
|
||||
* Katana: routing.
|
||||
"""
|
||||
|
||||
# Run the placer.
|
||||
etesian = Etesian.EtesianEngine.create( cell )
|
||||
etesian.place()
|
||||
|
||||
if editor:
|
||||
editor.setCell( cell )
|
||||
editor.fit()
|
||||
|
||||
editor.setCell( cell )
|
||||
editor.fit()
|
||||
Breakpoint.stop( 1, 'After placement' )
|
||||
|
||||
# Run the router.
|
||||
katana = Katana.KatanaEngine.create(cell)
|
||||
# Run the router.
|
||||
katana = Katana.KatanaEngine.create( cell )
|
||||
katana.digitalInit ()
|
||||
katana.runGlobalRouter ()
|
||||
katana.runGlobalRouter ( Katana.Flags.NoFlags )
|
||||
katana.loadGlobalRouting( Anabatic.EngineLoadGrByNet )
|
||||
katana.layerAssign ( Anabatic.EngineNoNetLayerAssign )
|
||||
katana.runNegociate ( Katana.Flags.NoFlags )
|
||||
|
||||
af.saveCell( cell, Catalog.State.Views )
|
||||
return
|
||||
|
||||
|
||||
def scriptMain ( **kw ):
|
||||
"""The mandatory function to be called by Coriolis CGT/Unicorn."""
|
||||
editor = None
|
||||
if kw.has_key('editor') and kw['editor']:
|
||||
editor = kw['editor']
|
||||
|
||||
if 'editor' in kw and kw['editor']:
|
||||
editor = kw['editor']
|
||||
fulladder = buildFulladder( editor )
|
||||
placeAndRoute( editor, fulladder )
|
||||
return True
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -100,7 +100,8 @@ div#contents ul > li > a {
|
|||
*/
|
||||
|
||||
span.cb {
|
||||
background: yellow;
|
||||
font-family: "courrier";
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.note {
|
||||
|
|
|
@ -100,7 +100,8 @@ div#contents ul > li > a {
|
|||
*/
|
||||
|
||||
span.cb {
|
||||
background: yellow;
|
||||
font-family: "courrier";
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.note {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2017-2021, All Rights Reserved
|
||||
# Copyright (c) Sorbonne Université 2017-2022, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
|
@ -21,20 +21,12 @@ try:
|
|||
import Viewer
|
||||
import CRL
|
||||
import helpers
|
||||
from helpers.io import ErrorMessage
|
||||
from helpers.io import WarningMessage
|
||||
from helpers import showPythonTrace
|
||||
from helpers import showPythonTrace, trace, l, u, n
|
||||
from helpers.io import ErrorMessage, WarningMessage
|
||||
from helpers.overlay import UpdateSession
|
||||
import plugins
|
||||
from Hurricane import DataBase
|
||||
from Hurricane import Breakpoint
|
||||
from Hurricane import UpdateSession
|
||||
from Hurricane import DbU
|
||||
from Hurricane import Box
|
||||
from Hurricane import Contact
|
||||
from Hurricane import Vertical
|
||||
from Hurricane import Horizontal
|
||||
from Hurricane import Net
|
||||
from Hurricane import Cell
|
||||
from Hurricane import DataBase, Breakpoint, DbU, Box, Contact, \
|
||||
Vertical, Horizontal, Net, Cell
|
||||
except ImportError as e:
|
||||
serror = str(e)
|
||||
if serror.startswith('No module named'):
|
||||
|
@ -44,8 +36,6 @@ except ImportError as e:
|
|||
if serror.find('cannot open shared object file'):
|
||||
library = serror.split(':')[0]
|
||||
print( '[ERROR] The "{}" shared library cannot be loaded.'.format(library) )
|
||||
print( ' Under RHEL 6, you must be under devtoolset-2.' )
|
||||
print( ' (scl enable devtoolset-2 bash)' )
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print( '[ERROR] A strange exception occurred while loading the basic Coriolis/Python' )
|
||||
|
@ -66,70 +56,66 @@ def runDemo ( cell, editor ):
|
|||
if cell:
|
||||
print( WarningMessage( '"demo_cell" has already been created, do not run twice.' ))
|
||||
return
|
||||
UpdateSession.open()
|
||||
cell = Cell.create( library, 'demo_cell' )
|
||||
cell.setAbutmentBox( Box( DbU.fromLambda( 0.0), DbU.fromLambda( 0.0)
|
||||
, DbU.fromLambda(15.0), DbU.fromLambda(50.0) ) )
|
||||
UpdateSession.close()
|
||||
with UpdateSession():
|
||||
cell = Cell.create( library, 'demo_cell' )
|
||||
cell.setAbutmentBox( Box( l( 0.0), l( 0.0), l(15.0), l(50.0) ) )
|
||||
|
||||
if editor: editor.setCell( cell )
|
||||
Breakpoint.stop( 1, 'Abutment box has been drawn.' )
|
||||
UpdateSession.open()
|
||||
|
||||
technology = DataBase.getDB().getTechnology()
|
||||
nwell = technology.getLayer( 'NWELL' )
|
||||
ntrans = technology.getLayer( 'NTRANS' )
|
||||
ptrans = technology.getLayer( 'PTRANS' )
|
||||
diffN = technology.getLayer( 'NDIF' )
|
||||
diffP = technology.getLayer( 'PDIF' )
|
||||
contDiffN = technology.getLayer( 'CONT_DIF_N' )
|
||||
contDiffP = technology.getLayer( 'CONT_DIF_P' )
|
||||
contPoly = technology.getLayer( 'CONT_POLY' )
|
||||
poly = technology.getLayer( 'POLY' )
|
||||
metal1 = technology.getLayer( 'METAL1' )
|
||||
|
||||
nwellNet = Net.create( cell, 'nwell' )
|
||||
Horizontal.create( nwellNet, nwell, DbU.fromLambda(39.0), DbU.fromLambda(24.0), DbU.fromLambda(0.0), DbU.fromLambda(15.0) )
|
||||
vss = Net.create( cell, 'vss' )
|
||||
vdd = Net.create( cell, 'vdd' )
|
||||
Horizontal.create( vss, metal1 , DbU.fromLambda(3.0), DbU.fromLambda(6.0), DbU.fromLambda(0.0), DbU.fromLambda(15.0) )
|
||||
Vertical.create ( vss, diffN , DbU.fromLambda(3.5), DbU.fromLambda(4.0), DbU.fromLambda(4.0), DbU.fromLambda(12.0) )
|
||||
Contact.create ( vss, contDiffN, DbU.fromLambda(4.0), DbU.fromLambda(5.0) )
|
||||
Horizontal.create( vdd, metal1 , DbU.fromLambda(47.0), DbU.fromLambda( 6.0), DbU.fromLambda( 0.0), DbU.fromLambda(15.0) )
|
||||
Vertical.create ( vdd, diffP , DbU.fromLambda( 3.5), DbU.fromLambda( 4.0), DbU.fromLambda(28.0), DbU.fromLambda(46.0) )
|
||||
Contact.create ( vdd, contDiffP, DbU.fromLambda( 4.0), DbU.fromLambda(45.0) )
|
||||
UpdateSession.close()
|
||||
with UpdateSession():
|
||||
technology = DataBase.getDB().getTechnology()
|
||||
nwell = technology.getLayer( 'NWELL' )
|
||||
ntrans = technology.getLayer( 'NTRANS' )
|
||||
ptrans = technology.getLayer( 'PTRANS' )
|
||||
diffN = technology.getLayer( 'NDIF' )
|
||||
diffP = technology.getLayer( 'PDIF' )
|
||||
contDiffN = technology.getLayer( 'CONT_DIF_N' )
|
||||
contDiffP = technology.getLayer( 'CONT_DIF_P' )
|
||||
contPoly = technology.getLayer( 'CONT_POLY' )
|
||||
poly = technology.getLayer( 'POLY' )
|
||||
metal1 = technology.getLayer( 'METAL1' )
|
||||
|
||||
nwellNet = Net.create( cell, 'nwell' )
|
||||
Horizontal.create( nwellNet, nwell, l(39.0), l(24.0), l(0.0), l(15.0) )
|
||||
vss = Net.create( cell, 'vss' )
|
||||
vdd = Net.create( cell, 'vdd' )
|
||||
Horizontal.create( vss, metal1 , l(3.0), l(6.0), l(0.0), l(15.0) )
|
||||
Vertical.create ( vss, diffN , l(3.5), l(4.0), l(4.0), l(12.0) )
|
||||
Contact.create ( vss, contDiffN, l(4.0), l(5.0) )
|
||||
Horizontal.create( vdd, metal1 , l(47.0), l( 6.0), l( 0.0), l(15.0) )
|
||||
Vertical.create ( vdd, diffP , l( 3.5), l( 4.0), l(28.0), l(46.0) )
|
||||
Contact.create ( vdd, contDiffP, l( 4.0), l(45.0) )
|
||||
Breakpoint.stop( 1, 'Power nets have been drawn.' )
|
||||
|
||||
UpdateSession.open()
|
||||
nq = Net.create( cell, 'nq' )
|
||||
Vertical.create ( nq, diffN , DbU.fromLambda(10.0), DbU.fromLambda( 3.0), DbU.fromLambda( 8.0), DbU.fromLambda(12.0) )
|
||||
Vertical.create ( nq, diffP , DbU.fromLambda(10.0), DbU.fromLambda( 3.0), DbU.fromLambda(28.0), DbU.fromLambda(37.0) )
|
||||
Contact.create ( nq, contDiffN, DbU.fromLambda(10.0), DbU.fromLambda(10.0) )
|
||||
Contact.create ( nq, contDiffP, DbU.fromLambda(10.0), DbU.fromLambda(30.0) )
|
||||
Contact.create ( nq, contDiffP, DbU.fromLambda(10.0), DbU.fromLambda(35.0) )
|
||||
Vertical.create ( nq, metal1 , DbU.fromLambda(10.0), DbU.fromLambda( 2.0), DbU.fromLambda(10.0), DbU.fromLambda(40.0) )
|
||||
UpdateSession.close()
|
||||
with UpdateSession():
|
||||
nq = Net.create( cell, 'nq' )
|
||||
Vertical.create ( nq, diffN , l(10.0), l( 3.0), l( 8.0), l(12.0) )
|
||||
Vertical.create ( nq, diffP , l(10.0), l( 3.0), l(28.0), l(37.0) )
|
||||
Contact.create ( nq, contDiffN, l(10.0), l(10.0) )
|
||||
Contact.create ( nq, contDiffP, l(10.0), l(30.0) )
|
||||
Contact.create ( nq, contDiffP, l(10.0), l(35.0) )
|
||||
Vertical.create ( nq, metal1 , l(10.0), l( 2.0), l(10.0), l(40.0) )
|
||||
Breakpoint.stop( 1, 'Output has been drawn.' )
|
||||
|
||||
UpdateSession.open()
|
||||
i = Net.create( cell, 'i' )
|
||||
Vertical.create ( i, ntrans , DbU.fromLambda( 7.0), DbU.fromLambda( 1.0), DbU.fromLambda( 6.0), DbU.fromLambda(14.0) )
|
||||
Vertical.create ( i, poly , DbU.fromLambda( 7.0), DbU.fromLambda( 1.0), DbU.fromLambda(14.0), DbU.fromLambda(26.0) )
|
||||
Vertical.create ( i, ptrans , DbU.fromLambda( 7.0), DbU.fromLambda( 1.0), DbU.fromLambda(26.0), DbU.fromLambda(39.0) )
|
||||
Horizontal.create( i, poly , DbU.fromLambda(20.0), DbU.fromLambda( 3.0), DbU.fromLambda( 4.0), DbU.fromLambda( 7.0) )
|
||||
Contact.create ( i, contPoly , DbU.fromLambda( 5.0), DbU.fromLambda(20.0) )
|
||||
Vertical.create ( i, metal1 , DbU.fromLambda( 5.0), DbU.fromLambda( 2.0), DbU.fromLambda(10.0), DbU.fromLambda(40.0) )
|
||||
|
||||
UpdateSession.close()
|
||||
with UpdateSession():
|
||||
i = Net.create( cell, 'i' )
|
||||
Vertical.create ( i, ntrans , l( 7.0), l( 1.0), l( 6.0), l(14.0) )
|
||||
Vertical.create ( i, poly , l( 7.0), l( 1.0), l(14.0), l(26.0) )
|
||||
Vertical.create ( i, ptrans , l( 7.0), l( 1.0), l(26.0), l(39.0) )
|
||||
Horizontal.create( i, poly , l(20.0), l( 3.0), l( 4.0), l( 7.0) )
|
||||
Contact.create ( i, contPoly , l( 5.0), l(20.0) )
|
||||
Vertical.create ( i, metal1 , l( 5.0), l( 2.0), l(10.0), l(40.0) )
|
||||
Breakpoint.stop( 1, 'Input has been drawn.' )
|
||||
return
|
||||
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Plugin hook functions, unicornHook:menus, ScritMain:call
|
||||
|
||||
def unicornHook ( **kw ):
|
||||
"""
|
||||
The mandatory function to make the plugin appears in the menus.
|
||||
"""
|
||||
|
||||
editor = kw['editor']
|
||||
editor.addMenu( 'tutorials' , 'Tutorials', Viewer.CellViewer.TopMenu )
|
||||
#editor.addMenu( 'tutorials.plugins', 'Plugins' , Viewer.CellViewer.NoFlags )
|
||||
|
@ -143,13 +129,17 @@ def unicornHook ( **kw ):
|
|||
|
||||
|
||||
def scriptMain ( **kw ):
|
||||
try:
|
||||
helpers.staticInitialization( quiet=True )
|
||||
#helpers.setTraceLevel( 550 )
|
||||
Breakpoint.setStopLevel( 1 )
|
||||
print( ' o Breakpoint level: {}.'.format(Breakpoint.getStopLevel()) )
|
||||
cell, editor = plugins.kwParseMain( **kw )
|
||||
runDemo( cell, editor )
|
||||
except Exception as e:
|
||||
helpers.io.catch( e )
|
||||
return 0
|
||||
"""
|
||||
The mandatory function from which a plugin will be called by Coriolis CGT/Unicorn.
|
||||
"""
|
||||
|
||||
try:
|
||||
helpers.staticInitialization( quiet=True )
|
||||
#helpers.setTraceLevel( 550 )
|
||||
Breakpoint.setStopLevel( 1 )
|
||||
print( ' o Breakpoint level: {}.'.format(Breakpoint.getStopLevel()) )
|
||||
cell, editor = plugins.kwParseMain( **kw )
|
||||
runDemo( cell, editor )
|
||||
except Exception as e:
|
||||
helpers.io.catch( e )
|
||||
return 0
|
||||
|
|
Loading…
Reference in New Issue