coriolis/crlcore/python/helpers/Display.py

288 lines
11 KiB
Python
Raw Normal View History

# -*- Mode:Python -*-
import os
import os.path
import sys
import string
import Cfg
import Viewer
Support for mixing real pads & symbolic core. Wrapper around s2r. * Change: In Hurricane::Error constructors disable the backtrace generation. (*very* slow). * Change: In Hurricane::Library::getHierarchicalname(), more compact naming. Remove the name of the root library. * New: In Hurricane::Net, new type "FUSED", for component with no net. More efficient than having one net for each. * Change: In CellViewer, BreakpointWidget, use Angry Birds icons. * Change: In CellWidget::State, use the hierarchical name (cached) as key to the state. This allow to load two cells with the same name but from different libraries in the widget history. * Change: In PyGraphics, export "isEnabled()" and "isHighDpi()" functions. * Change: In CRL/etc/symbolic/cmos/plugin.conf, and CRL/etc/common/plugin.conf use the physical dimensions converters. * Change: In CRL/etc/symbolic/cmos/technology.conf, make the GDS layer table coherent with the default Alliance cmos.rds. * New: CRL/python/helpers/io.py, put ErrorMessage new implementation here, along with a new ErrorWidget written in PyQt4. It seems finally that PyQt4 can be used alongside Coriolis Qt widgets. New ErrorMessage.catch() static function to manage all exceptions in except clauses. * Change: In CRL/python/helpers/, no longer use ErrorMessage.wrapPrint(), directly print it. Rewrite the utilities to display Python stack traces "textStacktrace()" and "showStacktrace()". * Change: In CRL::AllianceFramework, shorten the names of the libraries. * Change: In CRL::ApParser & CRL::ApDriver, more accurate translation between Alliance connectors (C record) and Hurricane::Pin objects. Pin are no longer made square but thin and oriented in the connecting direction. Use the new fused net for unnamed components. * New: In CRL::GdsParser, implementation of SREF parsing, i.e. instances. Due to the unordered nature of the GDS stream, instances creation are delayed until the whole stream has been parsed and only then are they created. For the sake of reading back Alliance s2r GDS, we assume that any TEXT following a boundary is the Net name the boundary (component) belongs to. Create abutment box for Cells, computed from the bounding box, so the Hurricane QuadTree could work properly. Make use of the fused net for unnamed components. * New: In Cumulus/plugins/chip, complete rewrite of the I/O pad management. Now we can mix real (foundry) pads and a symbolic core. To cleanly support the de-coupling between the real part and the symbolic one we introduce a new intermediary hierarchical level, the corona. We have now: Chip --> Pads + Corona --> Core. At chip level (and if we are using real pads) the layout is fully real (excepting the corona). The Corona contains everything that is symbolic. It has symbolic wires extending outward the abutment box to make contact with the real wires coming from the pads. In the pad ring we can use corners instances (or not), pad spacers or directly draw wires between connectors ring pads. Provide two flavors: placement only or full place & route. WARNING: If routing in a second step, *do not route* the *Chip* but the *Corona*. * Change: In Cumulus/plugins/clocktree, give the modified Cell an additional extension of "_cts" (Clock Tree Synthesis) instead of "_clocked", to follow the common convention. * New: In cumulus/plugins/S2R.py, encapsulate call to Alliance S2R and reload the translated Cell in the editor. * New: In cumulus/plugins/core2chip, provide an utility to automatically create a chip from a core. To work this plugins must have a basic understanding of the pad functionalities which may differs from foundry to foundry. So a base class CoreToChip is created, then for each supported pad foundry a derived class is added. Currently we support AMS c35b4 and Alliance symbolic cmos. * Bug: In Anabatic::Configuration, read the right configuration parameter "anabatic.topRoutinglayer" (Katana), and not the one for Katabatic... * Change: In Unicorn/cgt.py, process the plugins in alphabetical order to ensure a reproductible ordering of the menus...
2019-05-22 07:34:32 -05:00
from helpers.io import ErrorMessage
from helpers.io import WarningMessage
from helpers import Debug
from helpers.Patterns import patternsLUT
displayFile = '<displayFile has not been set>'
stdColors = \
{ 'Black' : '0,0,0'
, 'Gray50' : '050,050,050'
, 'Gray238' : '238,238,238'
, 'White' : '255,255,255'
, 'Seashell4' : '139,134,130'
, 'Red' : '255,0,0' # Shade of Reds.
, 'OrangeRed' : "255,69,0"
, 'DarkOrange' : "255,140,0"
, 'Orange' : "255,165,0"
, 'Wheat' : "245,222,179"
, 'LightPink' : '255,182,193'
, 'Green' : '0,255,0' # Shade of Green.
, 'LawnGreen' : '124,252,0'
, 'Blue' : '0,0,255' # Shade of Blue.
, 'Aqua' : '0,255,255'
, 'DarkTurquoise' : '0,206,209'
, 'BlueViolet' : '138,43,226'
, 'Violet' : '238;130;238' # Shade of Violets.
, 'Magenta' : '255,0,255'
, 'Magenta4' : '139,0,139'
, 'Tan' : '210,180,140' # Shade of Browns
, 'Yellow' : '255,255,0' # Shade of Yellows.
, 'LightYellow' : '255,255,224'
}
def checkAttribute ( options, attribute, goodType ):
if goodType == float and isinstance(options[attribute],int): return True
if not isinstance(options[attribute],goodType):
raise ErrorMessage( 1,
['The <%s> attribute of Drawing must be %s, not %s.' \
% (attribute,str(goodType).split("'")[1],helpers.stype(options[attribute]))
,str(options[attribute])])
return True
def checkColor ( color ):
if not isinstance(color,str):
raise ErrorMessage( 1,
['The <color> attribute of Drawing must be str, not %s.' % (helpers.stype(color))
,str(options[attribute])])
# Try a predefined color lookup.
if stdColors.has_key(color): return stdColors[color]
# Try a RGB hexa: #RRGGBB.
if color[0] == '#':
for digit in color[1:]:
if not digit in string.hexdigits:
raise ErrorMessage( 1,
['Non-hexadecimal digit \'%c\' in <color> attribute of Drawing.' % digit
,color])
if len(color) != 7:
raise ErrorMessage( 1,
['<color> attribute of Drawing do not have exactly six digits.' % digit
,color])
return color
# Try a RGB tuple (R,G,B).
rgb = color.split(',')
if len(rgb) != 3:
raise ErrorMessage( 1,
['<color> attribute of Drawing is neither hexa nor RGB nor predefined.'
,color])
for component in rgb:
for digit in component:
if not digit in string.digits:
raise ErrorMessage( 1,
['Bad RGB <color> component \'%s\' of Drawing, not an integer.' % component
,color])
value = int(component)
if value < 0 or value > 255:
raise ErrorMessage( 1,
['Bad RGB <color> component \'%s\' of Drawing, not between 0 and 255.' % component
,color])
return color
class StyleType ( object ):
Style = 1
Inherit = 2
Darkening = 3
Group = 4
Drawing = 5
def __init__ ( self, code ):
self._code = code
return
def __int__ ( self ):
return self._code
def __str__ ( self ):
if self._code == StyleType.Style: return 'Style'
if self._code == StyleType.Inherit: return 'Inherit'
if self._code == StyleType.Darkening: return 'Darkening'
if self._code == StyleType.Group: return 'Group'
if self._code == StyleType.Drawing: return 'Drawing'
return 'Unknown (%d)', self._code
def __repr__ ( self ):
return str(self)
Style = StyleType(StyleType.Style)
Inherit = StyleType(StyleType.Inherit)
Darkening = StyleType(StyleType.Darkening)
Group = StyleType(StyleType.Group)
Drawing = StyleType(StyleType.Drawing)
def loadStyleTuple ( styleTuple ):
style = None
group = 'NoGroup'
entryNo = 0
for styleEntry in styleTuple:
entryNo += 1
try:
if styleEntry[0] == Style:
if len(styleEntry) != 3:
raise ErrorMessage(1,['Malformed entry in <styleTable>.'
,'Style must have exactly three fields: (Style,id,description).'
,str(styleEntry)
])
styleType, styleId, description = styleEntry
if not isinstance(styleId,str):
raise ErrorMessage(1,['The second Style field, <id> must be a string, not a %s.' % helpers.stype(styleId)
,str(styleEntry)])
if not isinstance(description,str):
raise ErrorMessage(1,['The third Style field, <description> must be a string, not a %s.' % helpers.stype(styleId)
,str(styleEntry)])
style = Viewer.DisplayStyle(styleId)
style.setDescription(description)
if not style:
raise ErrorMessage(1,['Bad entry order in <styleTable>.'
,'First entry must be of Style type.'
])
if styleEntry[0] == Inherit:
if len(styleEntry) != 2:
raise ErrorMessage(1,['Malformed entry in <didplayTable>.'
,'Inherit must have exactly two fields: (Inherit,id).'
,str(styleEntry)
])
styleType, styleId = styleEntry
if not isinstance(styleId,str):
raise ErrorMessage(1,['The second Inherit field, <id> must be a string, not a %s.' % helpers.stype(styleId)
,str(styleEntry)])
style.inheritFrom(styleId)
if styleEntry[0] == Darkening:
if len(styleEntry) != 4:
raise ErrorMessage(1,['Malformed entry in <didplayTable>.'
,'Darkening (HSV color) must have exactly four fields: (Darkening,hue,value,saturation).'
,str(styleEntry)
])
styleType, hue, value, saturation = styleEntry
if not isinstance(hue ,float) or \
not isinstance(value ,float) or \
not isinstance(saturation,float) :
raise ErrorMessage(1,['<hue>, <val> & <sat> fields of Darkening must be floats.'
,'%s is (Type, %s, %s, %s)' % (str(styleEntry)
,helpers.stype(hue)
,helpers.stype(value)
,helpers.stype(saturation))
])
style.setDarkening(Viewer.DisplayStyle.HSVr( hue, value, saturation ))
elif styleEntry[0] == Group:
if len(styleEntry) != 2:
raise ErrorMessage(1,['Malformed entry in <styleTable>.'
,'Group must have exactly two fields: (Group,group).'
,str(styleEntry)
])
styleType, group = styleEntry
if not isinstance(group,str):
raise ErrorMessage(1,['The second Group field, <group> must be a string, not a %s.' % helpers.stype(group)
,str(styleEntry)])
elif styleEntry[0] == Drawing:
if len(styleEntry) != 3:
raise ErrorMessage(1,['Malformed entry in <styleTable>.'
,'Rule must have exactly three fields: (Drawing,dname,{dict}).'
,str(styleEntry)
])
styleType, name, options = styleEntry
arguments = { 'group':group, 'name':name }
for key in options.keys():
if key == 'color':
arguments[key] = checkColor(options[key])
continue
elif key == 'border': checkAttribute(options,'border',int)
elif key == 'pattern':
if patternsLUT.has_key(options[key]):
arguments[key] = patternsLUT[ options[key] ].hexa
continue
pass
elif key == 'threshold': checkAttribute(options,'threshold',float)
elif key == 'goMatched': checkAttribute(options,'goMatched',bool)
else:
w = WarningMessage( ['Unknown Drawing option: <%s>' % key
,'In %s:<styleTable>:"%s" at index %d.' \
% (displayFile,style.getName(),entryNo)] )
print w
continue
arguments[key] = options[key]
style.addDrawingStyle( **arguments )
except Exception, e:
if style:
footer = 'In %s:<styleTable>:"%s" at index %d.' % (displayFile,style.getName(),entryNo)
else:
footer = 'In %s:<styleTable> at index %d.' % (displayFile,entryNo)
Support for mixing real pads & symbolic core. Wrapper around s2r. * Change: In Hurricane::Error constructors disable the backtrace generation. (*very* slow). * Change: In Hurricane::Library::getHierarchicalname(), more compact naming. Remove the name of the root library. * New: In Hurricane::Net, new type "FUSED", for component with no net. More efficient than having one net for each. * Change: In CellViewer, BreakpointWidget, use Angry Birds icons. * Change: In CellWidget::State, use the hierarchical name (cached) as key to the state. This allow to load two cells with the same name but from different libraries in the widget history. * Change: In PyGraphics, export "isEnabled()" and "isHighDpi()" functions. * Change: In CRL/etc/symbolic/cmos/plugin.conf, and CRL/etc/common/plugin.conf use the physical dimensions converters. * Change: In CRL/etc/symbolic/cmos/technology.conf, make the GDS layer table coherent with the default Alliance cmos.rds. * New: CRL/python/helpers/io.py, put ErrorMessage new implementation here, along with a new ErrorWidget written in PyQt4. It seems finally that PyQt4 can be used alongside Coriolis Qt widgets. New ErrorMessage.catch() static function to manage all exceptions in except clauses. * Change: In CRL/python/helpers/, no longer use ErrorMessage.wrapPrint(), directly print it. Rewrite the utilities to display Python stack traces "textStacktrace()" and "showStacktrace()". * Change: In CRL::AllianceFramework, shorten the names of the libraries. * Change: In CRL::ApParser & CRL::ApDriver, more accurate translation between Alliance connectors (C record) and Hurricane::Pin objects. Pin are no longer made square but thin and oriented in the connecting direction. Use the new fused net for unnamed components. * New: In CRL::GdsParser, implementation of SREF parsing, i.e. instances. Due to the unordered nature of the GDS stream, instances creation are delayed until the whole stream has been parsed and only then are they created. For the sake of reading back Alliance s2r GDS, we assume that any TEXT following a boundary is the Net name the boundary (component) belongs to. Create abutment box for Cells, computed from the bounding box, so the Hurricane QuadTree could work properly. Make use of the fused net for unnamed components. * New: In Cumulus/plugins/chip, complete rewrite of the I/O pad management. Now we can mix real (foundry) pads and a symbolic core. To cleanly support the de-coupling between the real part and the symbolic one we introduce a new intermediary hierarchical level, the corona. We have now: Chip --> Pads + Corona --> Core. At chip level (and if we are using real pads) the layout is fully real (excepting the corona). The Corona contains everything that is symbolic. It has symbolic wires extending outward the abutment box to make contact with the real wires coming from the pads. In the pad ring we can use corners instances (or not), pad spacers or directly draw wires between connectors ring pads. Provide two flavors: placement only or full place & route. WARNING: If routing in a second step, *do not route* the *Chip* but the *Corona*. * Change: In Cumulus/plugins/clocktree, give the modified Cell an additional extension of "_cts" (Clock Tree Synthesis) instead of "_clocked", to follow the common convention. * New: In cumulus/plugins/S2R.py, encapsulate call to Alliance S2R and reload the translated Cell in the editor. * New: In cumulus/plugins/core2chip, provide an utility to automatically create a chip from a core. To work this plugins must have a basic understanding of the pad functionalities which may differs from foundry to foundry. So a base class CoreToChip is created, then for each supported pad foundry a derived class is added. Currently we support AMS c35b4 and Alliance symbolic cmos. * Bug: In Anabatic::Configuration, read the right configuration parameter "anabatic.topRoutinglayer" (Katana), and not the one for Katabatic... * Change: In Unicorn/cgt.py, process the plugins in alphabetical order to ensure a reproductible ordering of the menus...
2019-05-22 07:34:32 -05:00
e = ErrorMessage( e )
e.addMessage( footer )
print e
if not style: break
if style != None:
Viewer.Graphics.addStyle( style )
return
def loadStyles ( stylesTable, fromFile ):
global displayFile
displayFile = fromFile
try:
# Check for three levels of tuple for a correct <styleTable>.
if not isinstance(stylesTable,tuple):
raise ErrorMessage(1,['Malformed <styleTable>, not even a one level deep tuple.'])
if not isinstance(stylesTable[0],tuple):
raise ErrorMessage(1,['Malformed <styleTable>, only two level deep tuple.'])
for styleTuple in stylesTable:
loadStyleTuple( styleTuple )
except Exception, e:
styleTableExample = [ 'Should be a three level deep tuple:'
,' ( ( (Style, id, description)'
,' , (Entry1, ...)'
,' , (Entry2, ...)'
,' , (EntryN, ...)'
,' )'
,' ,)'
,'If only one style is defined, do not forget the last extra comma.'
,'(putting a level of parenthesis do not create a tuple for one item)'
,'In %s:<styleTable>.' % displayFile
]
Support for mixing real pads & symbolic core. Wrapper around s2r. * Change: In Hurricane::Error constructors disable the backtrace generation. (*very* slow). * Change: In Hurricane::Library::getHierarchicalname(), more compact naming. Remove the name of the root library. * New: In Hurricane::Net, new type "FUSED", for component with no net. More efficient than having one net for each. * Change: In CellViewer, BreakpointWidget, use Angry Birds icons. * Change: In CellWidget::State, use the hierarchical name (cached) as key to the state. This allow to load two cells with the same name but from different libraries in the widget history. * Change: In PyGraphics, export "isEnabled()" and "isHighDpi()" functions. * Change: In CRL/etc/symbolic/cmos/plugin.conf, and CRL/etc/common/plugin.conf use the physical dimensions converters. * Change: In CRL/etc/symbolic/cmos/technology.conf, make the GDS layer table coherent with the default Alliance cmos.rds. * New: CRL/python/helpers/io.py, put ErrorMessage new implementation here, along with a new ErrorWidget written in PyQt4. It seems finally that PyQt4 can be used alongside Coriolis Qt widgets. New ErrorMessage.catch() static function to manage all exceptions in except clauses. * Change: In CRL/python/helpers/, no longer use ErrorMessage.wrapPrint(), directly print it. Rewrite the utilities to display Python stack traces "textStacktrace()" and "showStacktrace()". * Change: In CRL::AllianceFramework, shorten the names of the libraries. * Change: In CRL::ApParser & CRL::ApDriver, more accurate translation between Alliance connectors (C record) and Hurricane::Pin objects. Pin are no longer made square but thin and oriented in the connecting direction. Use the new fused net for unnamed components. * New: In CRL::GdsParser, implementation of SREF parsing, i.e. instances. Due to the unordered nature of the GDS stream, instances creation are delayed until the whole stream has been parsed and only then are they created. For the sake of reading back Alliance s2r GDS, we assume that any TEXT following a boundary is the Net name the boundary (component) belongs to. Create abutment box for Cells, computed from the bounding box, so the Hurricane QuadTree could work properly. Make use of the fused net for unnamed components. * New: In Cumulus/plugins/chip, complete rewrite of the I/O pad management. Now we can mix real (foundry) pads and a symbolic core. To cleanly support the de-coupling between the real part and the symbolic one we introduce a new intermediary hierarchical level, the corona. We have now: Chip --> Pads + Corona --> Core. At chip level (and if we are using real pads) the layout is fully real (excepting the corona). The Corona contains everything that is symbolic. It has symbolic wires extending outward the abutment box to make contact with the real wires coming from the pads. In the pad ring we can use corners instances (or not), pad spacers or directly draw wires between connectors ring pads. Provide two flavors: placement only or full place & route. WARNING: If routing in a second step, *do not route* the *Chip* but the *Corona*. * Change: In Cumulus/plugins/clocktree, give the modified Cell an additional extension of "_cts" (Clock Tree Synthesis) instead of "_clocked", to follow the common convention. * New: In cumulus/plugins/S2R.py, encapsulate call to Alliance S2R and reload the translated Cell in the editor. * New: In cumulus/plugins/core2chip, provide an utility to automatically create a chip from a core. To work this plugins must have a basic understanding of the pad functionalities which may differs from foundry to foundry. So a base class CoreToChip is created, then for each supported pad foundry a derived class is added. Currently we support AMS c35b4 and Alliance symbolic cmos. * Bug: In Anabatic::Configuration, read the right configuration parameter "anabatic.topRoutinglayer" (Katana), and not the one for Katabatic... * Change: In Unicorn/cgt.py, process the plugins in alphabetical order to ensure a reproductible ordering of the menus...
2019-05-22 07:34:32 -05:00
e = ErrorMessage( e )
e.addMessage( styleTableExample )
print e
return
def loadDefaultStyle ( styleName, fromFile ):
global displayFile
displayFile = fromFile
Viewer.Graphics.setStyle( styleName )
return