2018-10-01 09:52:17 -05:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
from Hurricane import DataBase
|
|
|
|
from Hurricane import UpdateSession
|
|
|
|
from Hurricane import DbU
|
|
|
|
from Hurricane import Box
|
|
|
|
import helpers
|
|
|
|
from helpers import trace
|
|
|
|
|
2020-04-10 05:15:23 -05:00
|
|
|
#helpers.setTraceLevel( 1000 )
|
2018-10-01 09:52:17 -05:00
|
|
|
|
2020-04-08 04:24:42 -05:00
|
|
|
try:
|
|
|
|
import Analog
|
|
|
|
import oroshi
|
|
|
|
import oroshi.paramsmatrix
|
|
|
|
import oroshi.stack
|
Migration towards Python3, first stage: still based on C-Macros.
* New: Python/C++ API level:
* Write a new C++/template wrapper to get rid of boost::python
* The int & long Python type are now merged. So a C/C++ level,
it became "PyLong_X" (remove "PyInt_X") and at Python code
level, it became "int" (remove "long").
* Change: VLSISAPD finally defunct.
* Configuration is now integrated as a Hurricane component,
makes use of the new C++/template wrapper.
* vlsisapd is now defunct. Keep it in the source for now as
some remaining non essential code may have to be ported in
the future.
* Note: Python code (copy of the migration howto):
* New print function syntax print().
* Changed "dict.has_key(k)" for "k" in dict.
* Changed "except Exception, e" for "except Exception as e".
* The division "/" is now the floating point division, even if
both operand are integers. So 3/2 now gives 1.5 and no longer 1.
The integer division is now "//" : 1 = 3//2. So have to carefully
review the code to update. Most of the time we want to use "//".
We must never change to float for long that, in fact, represents
DbU (exposed as Python int type).
* execfile() must be replaced by exec(open("file").read()).
* iter().__next__() becomes iter(x).__next__().
* __getslice__() has been removed, integrated to __getitem__().
* The formating used for str(type(o)) has changed, so In Stratus,
have to update them ("<class 'MyClass'>" instead of "MyClass").
* the "types" module no longer supply values for default types
like str (types.StringType) or list (types.StringType).
Must use "isinstance()" where they were occuring.
* Remove the 'L' to indicate "long integer" (like "12L"), now
all Python integer are long.
* Change in bootstrap:
* Ported Coriolis builder (ccb) to Python3.
* Ported Coriolis socInstaller.py to Python3.
* Note: In PyQt4+Python3, QVariant no longer exists. Use None or
directly convert using the python syntax: bool(x), int(x), ...
By default, it is a string (str).
* Note: PyQt4 bindings & Python3 under SL7.
* In order to compile user's must upgrade to my own rebuild of
PyQt 4 & 5 bindings 4.19.21-1.el7.soc.
* Bug: In cumulus/plugins.block.htree.HTree.splitNet(), set the root
buffer of the H-Tree to the original signal (mainly: top clock).
Strangely, it was only done when working in full chip mode.
2021-09-19 12:41:24 -05:00
|
|
|
except Exception as e:
|
2020-04-08 04:24:42 -05:00
|
|
|
helpers.io.catch( e )
|
2018-10-01 09:52:17 -05:00
|
|
|
|
|
|
|
|
2018-10-18 11:10:01 -05:00
|
|
|
def checkCoherency ( device, bbMode ):
|
|
|
|
message = '[ERROR] DifferentialPair.checkCoherency():\n'
|
2018-10-01 09:52:17 -05:00
|
|
|
|
|
|
|
techno = DataBase.getDB().getTechnology()
|
2018-10-18 11:10:01 -05:00
|
|
|
rules = oroshi.getRules()
|
2018-10-01 09:52:17 -05:00
|
|
|
|
2018-10-18 11:10:01 -05:00
|
|
|
W = device.getParameter( 'W' ).getValue()
|
|
|
|
M = device.getParameter( 'M' ).getValue()
|
Migration towards Python3, first stage: still based on C-Macros.
* New: Python/C++ API level:
* Write a new C++/template wrapper to get rid of boost::python
* The int & long Python type are now merged. So a C/C++ level,
it became "PyLong_X" (remove "PyInt_X") and at Python code
level, it became "int" (remove "long").
* Change: VLSISAPD finally defunct.
* Configuration is now integrated as a Hurricane component,
makes use of the new C++/template wrapper.
* vlsisapd is now defunct. Keep it in the source for now as
some remaining non essential code may have to be ported in
the future.
* Note: Python code (copy of the migration howto):
* New print function syntax print().
* Changed "dict.has_key(k)" for "k" in dict.
* Changed "except Exception, e" for "except Exception as e".
* The division "/" is now the floating point division, even if
both operand are integers. So 3/2 now gives 1.5 and no longer 1.
The integer division is now "//" : 1 = 3//2. So have to carefully
review the code to update. Most of the time we want to use "//".
We must never change to float for long that, in fact, represents
DbU (exposed as Python int type).
* execfile() must be replaced by exec(open("file").read()).
* iter().__next__() becomes iter(x).__next__().
* __getslice__() has been removed, integrated to __getitem__().
* The formating used for str(type(o)) has changed, so In Stratus,
have to update them ("<class 'MyClass'>" instead of "MyClass").
* the "types" module no longer supply values for default types
like str (types.StringType) or list (types.StringType).
Must use "isinstance()" where they were occuring.
* Remove the 'L' to indicate "long integer" (like "12L"), now
all Python integer are long.
* Change in bootstrap:
* Ported Coriolis builder (ccb) to Python3.
* Ported Coriolis socInstaller.py to Python3.
* Note: In PyQt4+Python3, QVariant no longer exists. Use None or
directly convert using the python syntax: bool(x), int(x), ...
By default, it is a string (str).
* Note: PyQt4 bindings & Python3 under SL7.
* In order to compile user's must upgrade to my own rebuild of
PyQt 4 & 5 bindings 4.19.21-1.el7.soc.
* Bug: In cumulus/plugins.block.htree.HTree.splitNet(), set the root
buffer of the H-Tree to the original signal (mainly: top clock).
Strangely, it was only done when working in full chip mode.
2021-09-19 12:41:24 -05:00
|
|
|
mMax = W // rules.transistorMinW
|
2018-10-01 09:52:17 -05:00
|
|
|
if M > mMax:
|
|
|
|
message += \
|
2018-10-18 11:10:01 -05:00
|
|
|
' W/M ratio must be greater than transistor minimal width (%s)\n' \
|
2018-10-01 09:52:17 -05:00
|
|
|
' Please increase W or decrease M.' \
|
2018-10-18 11:10:01 -05:00
|
|
|
% DbU.getValueString(rules.transistorMinW)
|
2018-10-01 09:52:17 -05:00
|
|
|
return False, message
|
|
|
|
|
2018-10-18 11:10:01 -05:00
|
|
|
Mint = device.getParameter( 'Mint' ).getValue()
|
|
|
|
if Mint != 2:
|
|
|
|
message += ' For interdigitaded layout style, Mint *must* be equal to 2 (not %d)\n' % Mint
|
2018-10-01 09:52:17 -05:00
|
|
|
return False, message
|
|
|
|
|
|
|
|
return True, ''
|
|
|
|
|
|
|
|
|
2018-10-18 11:10:01 -05:00
|
|
|
def layout ( device, bbMode ):
|
2018-10-01 09:52:17 -05:00
|
|
|
|
|
|
|
trace( 100, ',+', '\tWIP_DP.layout() called.\n' )
|
|
|
|
nerc = device.getParameter( 'NERC' ).getValue()
|
|
|
|
nirc = device.getParameter( 'NIRC' ).getValue()
|
|
|
|
|
2020-04-08 04:24:42 -05:00
|
|
|
stack = oroshi.stack.Stack( device, nerc, nirc )
|
2018-10-01 09:52:17 -05:00
|
|
|
|
|
|
|
bw = str(device.getParameter( 'B.w' ).getValue())
|
|
|
|
d1w = str(device.getParameter( 'D1.w' ).getValue())
|
|
|
|
d2w = str(device.getParameter( 'D2.w' ).getValue())
|
|
|
|
g1w = str(device.getParameter( 'G1.w' ).getValue())
|
|
|
|
g2w = str(device.getParameter( 'G2.w' ).getValue())
|
|
|
|
sw = str(device.getParameter( 'S.w' ).getValue())
|
|
|
|
|
|
|
|
diffMap = { 'D1w':str(device.getParameter( 'D1.w' ).getValue())
|
|
|
|
, 'D2w':str(device.getParameter( 'D2.w' ).getValue())
|
|
|
|
, 'Sw' :str(device.getParameter( 'S.w' ).getValue())
|
|
|
|
, 'G1w':str(device.getParameter( 'G1.w' ).getValue())
|
|
|
|
, 'G2w':str(device.getParameter( 'G2.w' ).getValue())
|
|
|
|
, 'Bw' :str(device.getParameter( 'B.w' ).getValue())
|
|
|
|
}
|
|
|
|
|
|
|
|
M = device.getM()
|
|
|
|
remain = M % device.getMint()
|
|
|
|
westWirings = ''
|
|
|
|
eastWirings = ''
|
|
|
|
for i in range(device.getExternalDummy()):
|
|
|
|
westWirings = westWirings + 'B.bX.{Bw} B.bX.{Bw} '
|
|
|
|
eastWirings = ' B.bX.{Bw} B.bX.{Bw}' + eastWirings
|
|
|
|
if remain:
|
|
|
|
westWirings = westWirings + 'D1.b1.{D1w} G1.b0.{G1w} '
|
|
|
|
eastWirings = ' G2.t0.{G2w} D2.t1.{D2w}' + eastWirings
|
|
|
|
westWirings = westWirings + 'S.b2.{Sw} '
|
|
|
|
|
|
|
|
|
|
|
|
mintWirings = ''
|
Migration towards Python3, first stage: still based on C-Macros.
* New: Python/C++ API level:
* Write a new C++/template wrapper to get rid of boost::python
* The int & long Python type are now merged. So a C/C++ level,
it became "PyLong_X" (remove "PyInt_X") and at Python code
level, it became "int" (remove "long").
* Change: VLSISAPD finally defunct.
* Configuration is now integrated as a Hurricane component,
makes use of the new C++/template wrapper.
* vlsisapd is now defunct. Keep it in the source for now as
some remaining non essential code may have to be ported in
the future.
* Note: Python code (copy of the migration howto):
* New print function syntax print().
* Changed "dict.has_key(k)" for "k" in dict.
* Changed "except Exception, e" for "except Exception as e".
* The division "/" is now the floating point division, even if
both operand are integers. So 3/2 now gives 1.5 and no longer 1.
The integer division is now "//" : 1 = 3//2. So have to carefully
review the code to update. Most of the time we want to use "//".
We must never change to float for long that, in fact, represents
DbU (exposed as Python int type).
* execfile() must be replaced by exec(open("file").read()).
* iter().__next__() becomes iter(x).__next__().
* __getslice__() has been removed, integrated to __getitem__().
* The formating used for str(type(o)) has changed, so In Stratus,
have to update them ("<class 'MyClass'>" instead of "MyClass").
* the "types" module no longer supply values for default types
like str (types.StringType) or list (types.StringType).
Must use "isinstance()" where they were occuring.
* Remove the 'L' to indicate "long integer" (like "12L"), now
all Python integer are long.
* Change in bootstrap:
* Ported Coriolis builder (ccb) to Python3.
* Ported Coriolis socInstaller.py to Python3.
* Note: In PyQt4+Python3, QVariant no longer exists. Use None or
directly convert using the python syntax: bool(x), int(x), ...
By default, it is a string (str).
* Note: PyQt4 bindings & Python3 under SL7.
* In order to compile user's must upgrade to my own rebuild of
PyQt 4 & 5 bindings 4.19.21-1.el7.soc.
* Bug: In cumulus/plugins.block.htree.HTree.splitNet(), set the root
buffer of the H-Tree to the original signal (mainly: top clock).
Strangely, it was only done when working in full chip mode.
2021-09-19 12:41:24 -05:00
|
|
|
for i in range( (M // device.getMint())*2 ):
|
2018-10-01 09:52:17 -05:00
|
|
|
if (i + remain) % 2: mintWirings += 'G2.t0.{G2w} D2.t1.{D2w} G2.t0.{G2w} S.b2.{Sw} '
|
|
|
|
else: mintWirings += 'G1.b0.{G1w} D1.b1.{D1w} G1.b0.{G1w} S.b2.{Sw} '
|
|
|
|
|
|
|
|
wirings = westWirings + mintWirings + eastWirings
|
|
|
|
|
|
|
|
stack.setWirings( wirings.format( **diffMap ) )
|
|
|
|
stack.doLayout ( bbMode )
|
|
|
|
|
2020-04-08 04:24:42 -05:00
|
|
|
paramsMatrix = oroshi.paramsmatrix.ParamsMatrix()
|
First stage in analog capacitor integration
* Bug: In Technology::getPhysicalRule(), if the named layerdo not exists,
throw an exception instead of silently putting a NULL pointer inside
a rule.
* New: In Hurricane/Analog, new parameters classes for capacitor devices:
- Analog::Matrix, a matrix of null or positives integers to encode
capacitor matrix matching.
- Analog::Capacities, a list of float values for all component of a
multi-capacitor.
* New: In Hurricane::Script, add a "getFileName()" method to get the full
path name of the Python module.
* Change: In Analog::LayoutGenerator, completly remove the logger utility
as it is no longer used. Simply print error messages instead.
* Change: In Analog::MetaCapacitor, rename top & bottom plate 'T' & 'B'.
Accessors renamed in "getTopPlate()" & "getBottomPlate()".
* New: In Analog::MultiCapacitor, complete rewrite. Makes use of the
new parameters "capacities" and "matrix". Dynamically generates it's
terminals as we do not know beforehand how many capacitors could be
put in it.
* Bug: In isobar/PyHurricane.h, in Type object definition, do not prepend
a "Py" to class name (so the keep the C++ name).
* Change: In CRL/etc/scn6m_deep_09/devices.py, add entry for the new
capacitor generator.
* New: In oroshi/python/ParamsMatrix, add a "family" entry in the [0,0]
element to distinguish between transistor, capacitor and resistor.
(this is the matrix of values returned to the LayoutGenerator after
device generation).
Now have one "setGlobalParams()" function per family.
* New: In oroshi/python/Rules.py, added DTR rules needed by capacitors.
Catch exceptions if something wrong append when we extract the rules
from the technology.
* New: In Bora, the devices are no longer *only* transistors, so the
possibles configurations are no longer defined only by a number of
fingers. We must be able to support any kind of range of configuration.
So the explicit range of number of fingers is replaced by a base
class ParameterRange, and it's derived classes:
- Bora::StepParameterRange, to encode the possible number of fingers
of a transistor (the former only possibility).
- Bora::MatrixParameterRange, to encode all the possible matching
scheme for a capacitor. As there is no way to compress it, this
is a vector of Matrix (from Analog).
* Change: In Bora::DSlicingNode::_place(), the ParameterRange has to be set
on the right configuration (through the index) before being called.
The generation parameters are taken from the active item in the
ParameterRange.
* Change: In Bora::NodeSets::create(), iterate over the ParameterRange
to build all the configuration. Adjustement to the routing gauge
pitchs are moved into the DBoxSet CTOR to save a lot of code.
Semantic change: the index in the NodeSets is now the index in
the associated ParameterRange and no longer the number of fingers
of a transistor.
Check that the ParameterRange dynamic class is consitent with the
device family.
* Change: In Bora::DBoxSet, same semantic change as for NodeSets, the
number of finger become an index in ParameterRange.
In DBoxSet::create(), now also perform the abutment box adjustement
to the RoutingGauge, if possible.
* New: In Karakaze/python/AnalogDesign.py, add support for Capacitor
devices.
2019-11-07 10:05:49 -06:00
|
|
|
paramsMatrix.setGlobalTransistorParams( oroshi.toUnity(stack.w)
|
|
|
|
, oroshi.toUnity(stack.L)
|
|
|
|
, device.getM()
|
|
|
|
, stack.boundingBox
|
|
|
|
)
|
2018-10-01 09:52:17 -05:00
|
|
|
paramsMatrix.setStacks( [ stack ] )
|
|
|
|
trace( 100, '++' )
|
|
|
|
paramsMatrix.trace()
|
|
|
|
trace( 100, '---' )
|
|
|
|
|
|
|
|
return paramsMatrix.getMatrix()
|