Added GDSII driver. Bug in Blif parser.

* New: In CRL, implement a true GDSII driver. The driver is directly under
    CRL and do not use an intermediate structure in vlsisapd. The ASCII
    GDSII is removed.
      Huge polygons are not supported yet. Have to be split up in
    sub-polygons of less than 4000 vertexes.
      Symbolic layout can be exported to give a rough idea of the layout
    but RDS expension is not applied. Symbolic composite layers are
    expansed into their basic layers so the design *looks* normal.
* Deprecated: In CRL, remove all traces of the old XML configuration
    parsers. No one needs them now, including Chams.
* Bug: In CRL::BlifParser, before blindly loading the model of a subckt
    from disk with AllianceFramework, checks if it is in the Catalog
    first. Load with AllianceFramework only cells that are in the
    Catalog.
      This prevent a file of the same name than a model to be loaded
    shadowing the later defintion of the model in the Blif file.
      All this is due to the fact that Blif could be non-ordered for
    the models...
* Change: In Hurricane::BasicLayer, the "extract number" is replaced
    by a GdsLayer and GdsDatatype to generate accurate GDS files.
    Even if datatype is 0 most of the time.
      Update all the "technology.conf" files in CRL to provide those
    two numbers.
This commit is contained in:
Jean-Paul Chaput 2018-05-15 10:03:13 +02:00
parent 41c9959e30
commit 4a65a8d4e7
37 changed files with 859 additions and 2491 deletions

View File

@ -199,23 +199,23 @@ layersExtensionsTable = \
# Format of an entry in the table:
# (Symbolic_Name, CIF_Name, GDSII_Number)
gdsLayersTable = \
( ("pWell" , "CWN" , 41)
, ("nWell" , "CWP" , 42)
, ("active" , "CAA" , 43)
, ("pImplant", "CSP" , 44)
, ("nImplant", "CSN" , 45)
, ("poly" , "CPG" , 46)
, ("poly2" , "CM1" , 49) # poly2 is in fact metal1.
, ("cut0" , "CCC" , 25)
, ("metal1" , "CM1" , 49)
, ("cut1" , "CV1" , 50)
, ("metal2" , "CM2" , 51)
, ("cut2" , "CV2" , 61)
, ("metal3" , "CM3" , 62)
, ("cut3" , "CV3" , 30)
, ("metal4" , "CM4" , 31)
, ("cut4" , "CV4" , 32)
, ("metal5" , "CM5" , 33)
, ("cut5" , "CV5" , 36)
, ("metal6" , "CM6" , 37)
( ("pWell" , "CWN" , 41, 0)
, ("nWell" , "CWP" , 42, 0)
, ("active" , "CAA" , 43, 0)
, ("pImplant", "CSP" , 44, 0)
, ("nImplant", "CSN" , 45, 0)
, ("poly" , "CPG" , 46, 0)
, ("poly2" , "CM1" , 49, 0) # poly2 is in fact metal1.
, ("cut0" , "CCC" , 25, 0)
, ("metal1" , "CM1" , 49, 0)
, ("cut1" , "CV1" , 50, 0)
, ("metal2" , "CM2" , 51, 0)
, ("cut2" , "CV2" , 61, 0)
, ("metal3" , "CM3" , 62, 0)
, ("cut3" , "CV3" , 30, 0)
, ("metal4" , "CM4" , 31, 0)
, ("cut4" , "CV4" , 32, 0)
, ("metal5" , "CM5" , 33, 0)
, ("cut5" , "CV5" , 36, 0)
, ("metal6" , "CM6" , 37, 0)
)

View File

@ -254,30 +254,30 @@ gdsLayersTable = \
# Format of an entry in the table:
# (Symbolic_Name, CIF_Name, GDSII_Number)
gdsLayersTable = \
( ("pWell" , "CWN" , 2)
, ("nWell" , "CWP" , 3)
, ("active" , "CAA" , 1)
, ("pImplant", "CSP" , 5)
, ("nImplant", "CSN" , 4)
, ("poly" , "CPG" , 9)
, ("cut0" , "CCC" , 10)
, ("metal1" , "CM1" , 11)
, ("cut1" , "CV1" , 12)
, ("metal2" , "CM2" , 13)
, ("cut2" , "CV2" , 14)
, ("metal3" , "CM3" , 15)
, ("cut3" , "CV3" , 16)
, ("metal4" , "CM4" , 17)
, ("cut4" , "CV4" , 18)
, ("metal5" , "CM5" , 19)
, ("cut5" , "CV5" , 20)
, ("metal6" , "CM6" , 21)
, ("cut6" , "CV6" , 22)
, ("metal7" , "CM7" , 23)
, ("cut7" , "CV7" , 24)
, ("metal8" , "CM8" , 25)
, ("cut8" , "CV8" , 26)
, ("metal9" , "CM9" , 27)
, ("cut9" , "CV9" , 28)
, ("metal10" , "CM10" , 29)
( ("pWell" , "CWN" , 2, 0)
, ("nWell" , "CWP" , 3, 0)
, ("active" , "CAA" , 1, 0)
, ("pImplant", "CSP" , 5, 0)
, ("nImplant", "CSN" , 4, 0)
, ("poly" , "CPG" , 9, 0)
, ("cut0" , "CCC" , 10, 0)
, ("metal1" , "CM1" , 11, 0)
, ("cut1" , "CV1" , 12, 0)
, ("metal2" , "CM2" , 13, 0)
, ("cut2" , "CV2" , 14, 0)
, ("metal3" , "CM3" , 15, 0)
, ("cut3" , "CV3" , 16, 0)
, ("metal4" , "CM4" , 17, 0)
, ("cut4" , "CV4" , 18, 0)
, ("metal5" , "CM5" , 19, 0)
, ("cut5" , "CV5" , 20, 0)
, ("metal6" , "CM6" , 21, 0)
, ("cut6" , "CV6" , 22, 0)
, ("metal7" , "CM7" , 23, 0)
, ("cut7" , "CV7" , 24, 0)
, ("metal8" , "CM8" , 25, 0)
, ("cut8" , "CV8" , 26, 0)
, ("metal9" , "CM9" , 27, 0)
, ("cut9" , "CV9" , 28, 0)
, ("metal10" , "CM10" , 29, 0)
)

View File

@ -177,21 +177,21 @@ layersExtensionsTable = \
gdsLayersTable = \
( ("nWell" , "NWELL" , 3)
, ("nImplant", "NPLUS" , 26)
, ("pImplant", "PPLUS" , 25)
, ("active" , "ACTIVE" , 6)
, ("poly" , "POLY" , 17)
, ("cut0" , "CONTACT", 30)
, ("metal1" , "METAL1" , 31)
, ("cut1" , "VIA1" , 51)
, ("metal2" , "METAL2" , 32)
, ("cut2" , "VIA2" , 52)
, ("metal3" , "METAL3" , 33)
, ("cut3" , "VIA3" , 53)
, ("metal4" , "METAL4" , 34)
, ("cut4" , "VIA4" , 54)
, ("metal5" , "METAL5" , 35)
, ("cut5" , "VIA5" , 55)
, ("metal6" , "METAL6" , 36)
( ("nWell" , "NWELL" , 3, 0)
, ("nImplant", "NPLUS" , 26, 0)
, ("pImplant", "PPLUS" , 25, 0)
, ("active" , "ACTIVE" , 6, 0)
, ("poly" , "POLY" , 17, 0)
, ("cut0" , "CONTACT", 30, 0)
, ("metal1" , "METAL1" , 31, 0)
, ("cut1" , "VIA1" , 51, 0)
, ("metal2" , "METAL2" , 32, 0)
, ("cut2" , "VIA2" , 52, 0)
, ("metal3" , "METAL3" , 33, 0)
, ("cut3" , "VIA3" , 53, 0)
, ("metal4" , "METAL4" , 34, 0)
, ("cut4" , "VIA4" , 54, 0)
, ("metal5" , "METAL5" , 35, 0)
, ("cut5" , "VIA5" , 55, 0)
, ("metal6" , "METAL6" , 36, 0)
)

View File

@ -174,21 +174,21 @@ layersExtensionsTable = \
gdsLayersTable = \
( ("nWell" , "NWELL" , 3)
, ("nImplant", "NPLUS" , 26)
, ("pImplant", "PPLUS" , 25)
, ("active" , "ACTIVE" , 6)
, ("poly" , "POLY" , 17)
, ("cut0" , "CONTACT", 30)
, ("metal1" , "METAL1" , 31)
, ("cut1" , "VIA1" , 51)
, ("metal2" , "METAL2" , 32)
, ("cut2" , "VIA2" , 52)
, ("metal3" , "METAL3" , 33)
, ("cut3" , "VIA3" , 53)
, ("metal4" , "METAL4" , 34)
, ("cut4" , "VIA4" , 54)
, ("metal5" , "METAL5" , 35)
, ("cut5" , "VIA5" , 55)
, ("metal6" , "METAL6" , 36)
( ("nWell" , "NWELL" , 3, 0)
, ("nImplant", "NPLUS" , 26, 0)
, ("pImplant", "PPLUS" , 25, 0)
, ("active" , "ACTIVE" , 6, 0)
, ("poly" , "POLY" , 17, 0)
, ("cut0" , "CONTACT", 30, 0)
, ("metal1" , "METAL1" , 31, 0)
, ("cut1" , "VIA1" , 51, 0)
, ("metal2" , "METAL2" , 32, 0)
, ("cut2" , "VIA2" , 52, 0)
, ("metal3" , "METAL3" , 33, 0)
, ("cut3" , "VIA3" , 53, 0)
, ("metal4" , "METAL4" , 34, 0)
, ("cut4" , "VIA4" , 54, 0)
, ("metal5" , "METAL5" , 35, 0)
, ("cut5" , "VIA5" , 55, 0)
, ("metal6" , "METAL6" , 36, 0)
)

View File

@ -64,23 +64,6 @@ class Gauge ( object ):
return None
def xmlToConf ( xmlPath ):
hasExtention = False
components = xmlPath.split(os.sep)
filename = components[-1]
if filename.endswith('.xml'):
hasExtention = True
filename = filename[:-4]
if filename.endswith('.conf'):
hasExtention = True
filename = filename[:-5]
filename = filename.replace('.','_')
confPath = os.sep.join(components[:-1] + [filename])
if hasExtention:
confPath += '.conf'
return confPath
def _loadAllianceConfig ( af, allianceConfig ):
env = af.getEnvironment()

View File

@ -200,10 +200,3 @@ def loadLayout ( layoutData, fromFile ):
except Exception, e:
ErrorMessage.wrapPrint(e,'In %s:<layoutTable> at index %d.' % (confFile,entryNo))
return
def loadCompatXml ():
xmlConf = helpers.sysConfDir+'/tools.configuration.xml'
print 'Load XML', xmlConf
Cfg.Configuration.get().readFromFile(xmlConf)
return

View File

@ -308,16 +308,22 @@ def loadGdsLayers ( realLayersTable, confFile ):
entryNo += 1
try:
if len(entry) != 3:
if len(entry) != 4:
raise ErrorMessage(1,['Malformed entry in <realLayersTable>.'
,'Must have exactly three fields: (symb_name,real_name,GDSII_extnb).'
,'Must have exactly four fields: (symb_name,real_name,GDSII_layer,GDSII_datatype).'
,str(entry)
])
symbName, realName, gdsiiExtractNumber = entry
if not isinstance(gdsiiExtractNumber,int):
symbName, realName, gdsiiLayer,gdsiiDatatype = entry
if not isinstance(gdsiiLayer,int):
raise ErrorMessage(1,['Incoherency in <realLayersTable> entry.'
,'GDSII exctract number is not of int type (%s).' \
% helpers.stype(gdsiiExtractNumber)
,'GDSII layer number is not of int type (%s).' \
% helpers.stype(gdsiiLayer)
,str(entry)
])
if not isinstance(gdsiiDatatype,int):
raise ErrorMessage(1,['Incoherency in <realLayersTable> entry.'
,'GDSII layer Datatype is not of int type (%s).' \
% helpers.stype(gdsiiDatatype)
,str(entry)
])
@ -328,8 +334,9 @@ def loadGdsLayers ( realLayersTable, confFile ):
% (symbName,realName)
,str(entry)
])
basicLayer.setRealName ( realName )
basicLayer.setExtractNumber( gdsiiExtractNumber )
basicLayer.setRealName ( realName )
basicLayer.setGds2Layer ( gdsiiLayer )
basicLayer.setGds2Datatype( gdsiiDatatype )
except Exception, e:
ErrorMessage.wrapPrint(e,'In %s:<gdsLayersTable> at entry %d.' % (technologyFile,entryNo))

View File

@ -24,9 +24,6 @@
#include "hurricane/Instance.h"
#include "hurricane/viewer/Graphics.h"
#include "crlcore/Utilities.h"
#include "crlcore/GraphicsParser.h"
#include "crlcore/SymbolicTechnologyParser.h"
#include "crlcore/RealTechnologyParser.h"
#include "crlcore/CellGauge.h"
#include "crlcore/RoutingGauge.h"
#include "crlcore/RoutingLayerGauge.h"
@ -35,7 +32,9 @@
namespace CRL {
using namespace std;
using namespace std::placeholders;
using Hurricane::DataBase;
using Hurricane::Initializer;
using Hurricane::JsonTypes;
using Hurricane::JsonArray;
@ -204,22 +203,6 @@ namespace CRL {
//cmess1 << " o Reading Alliance Environment." << endl;
//_environment.loadFromShell ();
//_environment.loadFromXml ();
string userEnvironment = Environment::getEnv ( "HOME", "<HomeDirectory>" );
//_environment.loadFromXml ( userEnvironment+"/.environment.alliance.xml", false );
char cwd[1024];
getcwd ( cwd, 1024 );
string cwdEnvironment = cwd;
//_environment.loadFromXml ( cwdEnvironment+"/.environment.alliance.xml", false );
//SymbolicTechnologyParser::load ( db, _environment.getSYMBOLIC_TECHNOLOGY() );
//RealTechnologyParser::load ( db, _environment.getREAL_TECHNOLOGY() );
//GraphicsParser::load ( _environment.getDISPLAY() );
//if ( !_environment.getDisplayStyle().empty() )
// Graphics::setStyle ( _environment.getDisplayStyle() );
}
@ -314,6 +297,14 @@ namespace CRL {
{ _observers.notify( flags ); }
Catalog::State* AllianceFramework::isInCatalog ( const Name& name )
{ return getCatalog()->getState( name, false ); }
Catalog::State* AllianceFramework::isInCatalog ( string name )
{ return getCatalog()->getState( Name(name), false ); }
AllianceLibrary* AllianceFramework::getAllianceLibrary ( unsigned index )
{
if ( index >= _libraries.size() )

View File

@ -25,7 +25,6 @@
${CRLCORE_SOURCE_DIR}/src/ccore/blif
${CRLCORE_SOURCE_DIR}/src/ccore/alliance/ap
${CRLCORE_SOURCE_DIR}/src/ccore/alliance/vst
${CRLCORE_SOURCE_DIR}/src/ccore/agds
${CRLCORE_SOURCE_DIR}/src/ccore/cif
${CRLCORE_SOURCE_DIR}/src/ccore/spice
${CRLCORE_SOURCE_DIR}/src/ccore/liberty
@ -48,7 +47,6 @@
crlcore/Banner.h
crlcore/Histogram.h
crlcore/COptions.h
crlcore/XmlParser.h
crlcore/GdsDriver.h
crlcore/OAParser.h
crlcore/OADriver.h
@ -63,6 +61,7 @@
crlcore/DefExport.h
crlcore/LefImport.h
crlcore/LefExport.h
crlcore/Gds.h
crlcore/Blif.h
crlcore/AcmSigda.h
crlcore/Iccad04Lefdef.h
@ -78,9 +77,6 @@
crlcore/RoutingGauge.h
crlcore/RoutingLayerGauge.h
crlcore/CellGauge.h
crlcore/SymbolicTechnologyParser.h
crlcore/RealTechnologyParser.h
crlcore/GraphicsParser.h
crlcore/AllianceFramework.h
crlcore/ToolEngine.h
crlcore/ToolEngines.h
@ -96,8 +92,6 @@
Banner.cpp
COptions.cpp
Histogram.cpp
XmlParser.cpp
GdsDriver.cpp
OAParserDriver.cpp
CifDriver.cpp
SearchPath.cpp
@ -108,9 +102,6 @@
RoutingGauge.cpp
CellGauge.cpp
RoutingLayerGauge.cpp
SymbolicTechnologyParser.cpp
RealTechnologyParser.cpp
GraphicsParser.cpp
AllianceFramework.cpp
ToolEngine.cpp
GraphicToolEngine.cpp
@ -125,7 +116,7 @@
set ( ap_cpps alliance/ap/ApParser.cpp
alliance/ap/ApDriver.cpp
)
set ( agds_cpps agds/AgdsDriver.cpp
set ( gds_cpps gds/GdsDriver.cpp
)
set ( cif_cpps cif/CifDriver.cpp
)
@ -290,7 +281,7 @@
add_library ( crlcore ${ccore_cpps}
${moc_cpps}
${ap_cpps}
${agds_cpps}
${gds_cpps}
${cif_cpps}
${toolbox_cpps}
${vst_parser_cpps}

View File

@ -193,7 +193,7 @@ namespace CRL {
state = new State ();
_states [ name ] = state;
}
return ( state );
return state;
}

View File

@ -19,32 +19,6 @@
#include "crlcore/AllianceFramework.h"
namespace {
// const char *missingMandatoryAttr =
// "CRoutingGauge::createFromXml () :\n\n"
// " Can't found mandatory attribute \"%s\".\n";
// const char *badAttrValue =
// "CRoutingGauge::createFromXml () :\n\n"
// " Invalid value \"%s\" for attribute \"%s\".\n";
// const char *missingCellGaugeTag =
// "::createCellGaugeFromXml () :\n\n"
// " Can't found \"cellgauge\" tag.\n"
// " (XML file := \"%s\").\n";
// const char *missingCellGaugeNameAttr =
// "::createCellGaugeFromXml () :\n\n"
// " Can't found cellgauge name tag attribute.\n";
// const char *emptyCellGaugeNameAttr =
// "::createCellGaugeFromXml () :\n\n"
// " cellgauge name tag attribute is empty.\n";
} // Anonymous namespace.
namespace CRL {
using namespace std;

View File

@ -18,9 +18,7 @@
#include <cstdlib>
#include <map>
#include <iomanip>
#include <QXmlStreamReader>
#include "crlcore/Utilities.h"
#include "crlcore/XmlParser.h"
#include "crlcore/Environment.h"
#include "crlcore/AllianceFramework.h"
@ -43,469 +41,13 @@ namespace {
"Environment::Environment() :\n"
" %s logical format \"%s\" incoherent with physical format \"%s\".\n";
const string sysConfDir = SYS_CONF_DIR;
class XmlEnvironmentParser : public XmlParser {
// Methods.
public:
static XmlEnvironmentParser* create ( Environment& env
, QXmlStreamReader* reader );
static bool load ( Environment& env
, const string& path
, bool warnNotFound=true );
// Internal - enum.
protected:
enum TagSet { TagsEnvironment = 2
, TagsVariable
, TagsTechnologies
, TagsHurricane
, TagsReal
, TagsDisplay
, TagsConfig
, TagsLibraries
, TagsCatalog
, TagsWorking
, TagsSystem
, TagsLibrary
, TagsFormats
, TagsScale
, TagsInput
, TagsOutput
, TagsLogical
, TagsPhysical
, TagsSignals
, TagsPOWER
, TagsGROUND
, TagsClock
, TagsBlockage
, TagsTableSize
};
enum State { HurricaneTechnology = 1
, RealTechnology
, Display
, WorkingLibrary
, SystemLibrary
, InputFormats
, OutputFormats
};
// Internal - Attributes.
Environment& _environment;
map<string,string> _variables;
unsigned int _state;
// Internal - Constructors.
XmlEnvironmentParser ( Environment& env
, QXmlStreamReader* reader=NULL );
XmlEnvironmentParser ( const XmlEnvironmentParser& );
XmlEnvironmentParser& operator= ( const XmlEnvironmentParser& );
// Internal - Methods.
const string& getVariable ( const string& name );
void setVariable ( const string& name, const string& value );
string& expandVariables ( string& value );
void parseEnvironment ();
void parseVariable ();
void parseTechnologies ();
void parseHurricane ();
void parseReal ();
void parseDisplay ();
void parseDisplayStyle ();
void parseConfig ();
void parseLibraries ();
void parseCatalog ();
void parseWorking ();
void parseSystem ();
void parseLibrary ();
void parseFormats ();
void parseScale ();
void parseInput ();
void parseOutput ();
void parseLogical ();
void parsePhysical ();
void parseSignals ();
void parsePOWER ();
void parseGROUND ();
void parseClock ();
void parseBlockage ();
virtual void _postLoad ();
virtual const char* _getMessage ( MessageId id );
};
XmlEnvironmentParser::XmlEnvironmentParser ( Environment& env, QXmlStreamReader* reader )
: XmlParser(reader,TagsTableSize)
, _environment(env)
, _state(0)
{
addTagEntry ( TagsStandAlone , "environment" , (tagParser_t)&XmlEnvironmentParser::parseEnvironment );
addTagEntry ( TagsEnvironment , "variable" , (tagParser_t)&XmlEnvironmentParser::parseVariable );
addTagEntry ( TagsEnvironment , "technologies", (tagParser_t)&XmlEnvironmentParser::parseTechnologies );
addTagEntry ( TagsTechnologies, "hurricane" , (tagParser_t)&XmlEnvironmentParser::parseHurricane );
addTagEntry ( TagsHurricane , "config" , (tagParser_t)&XmlEnvironmentParser::parseConfig );
addTagEntry ( TagsTechnologies, "real" , (tagParser_t)&XmlEnvironmentParser::parseReal );
addTagEntry ( TagsReal , "config" , (tagParser_t)&XmlEnvironmentParser::parseConfig );
addTagEntry ( TagsTechnologies, "display" , (tagParser_t)&XmlEnvironmentParser::parseDisplay );
addTagEntry ( TagsDisplay , "config" , (tagParser_t)&XmlEnvironmentParser::parseConfig );
addTagEntry ( TagsDisplay , "displaystyle", (tagParser_t)&XmlEnvironmentParser::parseDisplayStyle );
addTagEntry ( TagsEnvironment , "libraries" , (tagParser_t)&XmlEnvironmentParser::parseLibraries );
addTagEntry ( TagsLibraries , "catalog" , (tagParser_t)&XmlEnvironmentParser::parseCatalog );
addTagEntry ( TagsLibraries , "working" , (tagParser_t)&XmlEnvironmentParser::parseWorking );
addTagEntry ( TagsWorking , "library" , (tagParser_t)&XmlEnvironmentParser::parseLibrary );
addTagEntry ( TagsLibraries , "system" , (tagParser_t)&XmlEnvironmentParser::parseSystem );
addTagEntry ( TagsSystem , "library" , (tagParser_t)&XmlEnvironmentParser::parseLibrary );
addTagEntry ( TagsEnvironment , "formats" , (tagParser_t)&XmlEnvironmentParser::parseFormats );
addTagEntry ( TagsFormats , "scale" , (tagParser_t)&XmlEnvironmentParser::parseScale );
addTagEntry ( TagsFormats , "input" , (tagParser_t)&XmlEnvironmentParser::parseInput );
addTagEntry ( TagsInput , "logical" , (tagParser_t)&XmlEnvironmentParser::parseLogical );
addTagEntry ( TagsInput , "physical" , (tagParser_t)&XmlEnvironmentParser::parsePhysical );
addTagEntry ( TagsFormats , "output" , (tagParser_t)&XmlEnvironmentParser::parseOutput );
addTagEntry ( TagsOutput , "logical" , (tagParser_t)&XmlEnvironmentParser::parseLogical );
addTagEntry ( TagsOutput , "physical" , (tagParser_t)&XmlEnvironmentParser::parsePhysical );
addTagEntry ( TagsEnvironment , "signals" , (tagParser_t)&XmlEnvironmentParser::parseSignals );
addTagEntry ( TagsSignals , "vdd" , (tagParser_t)&XmlEnvironmentParser::parsePOWER );
addTagEntry ( TagsSignals , "vss" , (tagParser_t)&XmlEnvironmentParser::parseGROUND );
addTagEntry ( TagsSignals , "clock" , (tagParser_t)&XmlEnvironmentParser::parseClock );
addTagEntry ( TagsSignals , "blockage" , (tagParser_t)&XmlEnvironmentParser::parseBlockage );
setVariable ( "CORIOLIS_TOP", _environment.getCORIOLIS_TOP() );
}
XmlEnvironmentParser* XmlEnvironmentParser::create ( Environment& env
, QXmlStreamReader* reader )
{
return new XmlEnvironmentParser ( env, reader );
}
bool XmlEnvironmentParser::load ( Environment& env, const string& path, bool warnNotFound )
{
XmlEnvironmentParser ep ( env );
string envPath = path;
if ( path.empty() ) {
if ( sysConfDir[0] == '/' )
envPath = sysConfDir + "/coriolis2/environment.alliance.xml" ;
else
envPath = env.getCORIOLIS_TOP() + "/" + sysConfDir + "/coriolis2/environment.alliance.xml" ;
}
return ep._load ( envPath, warnNotFound );
}
const string& XmlEnvironmentParser::getVariable ( const string& name )
{
static const string nullValue = "";
map<string,string>::iterator it = _variables.find ( name );
if ( it != _variables.end() )
return it->second;
return nullValue;
}
void XmlEnvironmentParser::setVariable ( const string& name, const string& value )
{
if ( !getVariable(name).empty() )
cerr << "[WARNING] Overriding variable \"" << name << "\".\n" << endl;
_variables [ name ] = value;
}
string& XmlEnvironmentParser::expandVariables ( string& variable )
{
size_t dollar;
size_t vbegin;
size_t vend;
bool braces = false;
while ( (dollar = variable.find('$')) != string::npos ) {
if ( variable[dollar+1] == '{' ) {
braces = true;
vbegin = dollar+2;
vend = variable.find ( '}', vbegin );
if ( vend == string::npos ) {
cerr << "[ERROR] Unmatched brace while expanding variables." << endl;
break;
}
} else {
vbegin = dollar+1;
for ( vend = vbegin ; vend < variable.size() ; vend++ )
if ( !isalnum(variable[vend]) ) break;
}
const string& substitute = getVariable ( variable.substr(vbegin,vend-vbegin) );
if ( substitute.empty() ) {
cerr << "[ERROR] Reference to undefined variable \""
<< variable.substr(vbegin,vend-vbegin+(braces?1:0)) << "\"." << endl;
variable [ dollar ] = '_';
continue;
}
variable.replace ( dollar, vend-dollar+(braces?1:0), substitute );
}
return variable;
}
void XmlEnvironmentParser::parseEnvironment ()
{
parseTags ( TagsEnvironment );
}
void XmlEnvironmentParser::parseVariable ()
{
QString value;
QString name;
name = _reader->attributes().value("name").toString();
if ( name.isEmpty() )
cerr << "[ERROR] Unnamed variable." << endl;
else {
value = _reader->attributes().value("value").toString();
if ( value.isEmpty() )
cerr << "[ERROR] variable \"" << qPrintable(name) << "\" has no value." << endl;
else
setVariable ( name.toStdString(), value.toStdString() );
}
parseNoChilds ();
}
void XmlEnvironmentParser::parseTechnologies ()
{
parseTags ( TagsTechnologies );
}
void XmlEnvironmentParser::parseHurricane ()
{
_state = HurricaneTechnology;
parseTags ( TagsHurricane );
}
void XmlEnvironmentParser::parseReal ()
{
_state = RealTechnology;
parseTags ( TagsReal );
}
void XmlEnvironmentParser::parseDisplay ()
{
_state = Display;
parseTags ( TagsDisplay );
}
void XmlEnvironmentParser::parseDisplayStyle ()
{
QString value;
value = _reader->attributes().value("name").toString();
if ( !value.isEmpty() )
_environment.setDisplayStyle ( value.toStdString().c_str() );
else
cerr << "[ERROR] Unnamed display style." << endl;
parseNoChilds ();
}
void XmlEnvironmentParser::parseConfig ()
{
#if THIS_IS_DISABLED
string config = readTextAsString().toStdString();
expandVariables ( config );
switch ( _state ) {
case HurricaneTechnology: _environment.setSYMBOLIC_TECHNOLOGY ( config.c_str() ); break;
case RealTechnology: _environment.setREAL_TECHNOLOGY ( config.c_str() ); break;
case Display: _environment.setDISPLAY ( config.c_str() ); break;
}
#endif
}
void XmlEnvironmentParser::parseLibraries ()
{
parseTags ( TagsLibraries );
}
void XmlEnvironmentParser::parseCatalog ()
{
_environment.setCATALOG ( readTextAsString().toStdString().c_str() );
}
void XmlEnvironmentParser::parseWorking ()
{
_state = WorkingLibrary;
parseTags ( TagsWorking );
}
void XmlEnvironmentParser::parseSystem ()
{
_state = SystemLibrary;
QString operation;
// operation = _reader->attributes().value("operation").toString();
// if ( operation.isEmpty() )
// _environment.getLIBRARIES().reset();
// else if ( operation != "append" )
// cerr << "[ERROR] Invalid value for attribute \"operation\" of <system>: \""
// << qPrintable(operation) << "\"." << endl;
parseTags ( TagsSystem );
}
void XmlEnvironmentParser::parseLibrary ()
{
unsigned int mode = Environment::Append;
QString modeAttribute = _reader->attributes().value("mode").toString();
QString nameAttribute = _reader->attributes().value("name").toString();
if ( not modeAttribute.isEmpty() ) {
if ( modeAttribute == "append" ) mode = Environment::Append;
else if ( modeAttribute == "prepend" ) mode = Environment::Prepend;
else if ( modeAttribute == "replace" ) mode = Environment::Replace;
else
cerr << "[ERROR] Invalid value for attribute \"mode\" of <library>: \""
<< qPrintable(modeAttribute) << "\"." << endl;
}
string library = readTextAsString().toStdString();
expandVariables ( library );
string libName = nameAttribute.toStdString();
if ( libName.empty() ) libName = SearchPath::extractLibName ( library );
switch ( _state ) {
case WorkingLibrary: _environment.setWORKING_LIBRARY ( library.c_str() ); break;
case SystemLibrary: _environment.addSYSTEM_LIBRARY ( library.c_str(), libName.c_str(), mode ); break;
}
}
void XmlEnvironmentParser::parseFormats ()
{
parseTags ( TagsFormats );
}
void XmlEnvironmentParser::parseScale ()
{
_environment.setSCALE_X ( readTextAsLong() );
}
void XmlEnvironmentParser::parseInput ()
{
_state = InputFormats;
parseTags ( TagsInput );
}
void XmlEnvironmentParser::parseOutput ()
{
_state = OutputFormats;
parseTags ( TagsOutput );
}
void XmlEnvironmentParser::parseLogical ()
{
string format = readTextAsString().toStdString();
switch ( _state ) {
case InputFormats: _environment.setIN_LO ( format.c_str() ); break;
case OutputFormats: _environment.setOUT_LO ( format.c_str() ); break;
}
}
void XmlEnvironmentParser::parsePhysical ()
{
string format = readTextAsString().toStdString();
switch ( _state ) {
case InputFormats: _environment.setIN_PH ( format.c_str() ); break;
case OutputFormats: _environment.setOUT_PH ( format.c_str() ); break;
}
}
void XmlEnvironmentParser::parseSignals ()
{
parseTags ( TagsSignals );
}
void XmlEnvironmentParser::parsePOWER ()
{
_environment.setPOWER ( readTextAsString().toStdString().c_str() );
}
void XmlEnvironmentParser::parseGROUND ()
{
_environment.setGROUND ( readTextAsString().toStdString().c_str() );
}
void XmlEnvironmentParser::parseClock ()
{
_environment.setCLOCK ( readTextAsString().toStdString().c_str() );
}
void XmlEnvironmentParser::parseBlockage ()
{
_environment.setBLOCKAGE ( readTextAsString().toStdString().c_str() );
}
void XmlEnvironmentParser::_postLoad ()
{
}
const char* XmlEnvironmentParser::_getMessage ( MessageId id )
{
const char* message = "<unknwown message id>";
switch ( id ) {
case OpenFile: message = "environment"; break;
}
return message;
}
} // End of anonymous namespace.
namespace CRL {
using namespace std;
using Hurricane::Initializer;
using Hurricane::JsonTypes;

View File

@ -1,221 +0,0 @@
// -*- C++ -*-
# include <cassert>
# include <string>
# include <QXmlStreamReader>
# include "hurricane/viewer/DisplayStyle.h"
# include "hurricane/viewer/Graphics.h"
# include "crlcore/GraphicsParser.h"
namespace CRL {
using Hurricane::Graphics;
void GraphicsParser::parseDefault ()
{
QString state = readTextAsString ();
if ( state == "true" )
_defaultDisplayStyle = _displayStyle;
}
void GraphicsParser::parseInherit ()
{
Name name = readTextAsString().toStdString();
DisplayStyle* baseStyle = Graphics::getStyle ( name );
if ( baseStyle )
_displayStyle->inheritFrom ( baseStyle );
else
cerr << "[ERROR] Base style \"" << getString(name)
<< "\" of \"" << getString(_displayStyle->getName())
<< "\" doesn't exist (yet?)." << endl;
}
void GraphicsParser::parseDescription ()
{
string description = readTextAsString().toStdString();
_displayStyle->setDescription ( description );
}
void GraphicsParser::parseDarkening ()
{
QString attribute;
float hue = 1.0;
float saturation = 1.0;
float value = 1.0;
attribute = _reader->attributes().value("hue").toString();
if ( not attribute.isEmpty() )
hue = attribute.toFloat ();
attribute = _reader->attributes().value("saturation").toString();
if ( not attribute.isEmpty() )
saturation = attribute.toFloat ();
attribute = _reader->attributes().value("value").toString();
if ( not attribute.isEmpty() )
value = attribute.toFloat ();
_displayStyle->setDarkening ( DisplayStyle::HSVr(hue,saturation,value) );
parseNoChilds ();
}
void GraphicsParser::parseDrawingStyle ()
{
string pattern = "FFFFFFFFFFFFFFFF";
int red = 255;
int green = 255;
int blue = 255;
int border = 0;
float threshold = 1.0;
Name drawingStyleName = "unnamed";
bool goMatched = true;
QString value;
value = _reader->attributes().value("name").toString();
if ( !value.isEmpty() )
drawingStyleName = value.toStdString ();
else
cerr << "[ERROR] Unnamed drawing style." << endl;
value = _reader->attributes().value("color").toString();
if ( !value.isEmpty() ) {
QStringList components = value.split ( "," );
if ( components.size() == 3 ) {
red = components[0].toInt ();
green = components[1].toInt ();
blue = components[2].toInt ();
} else
cerr << "[ERROR] Malformed color attribute." << endl;
} else
cerr << "[ERROR] Missing madatory color attribute." << endl;
value = _reader->attributes().value("pattern").toString();
if ( !value.isEmpty() )
pattern = value.toStdString ();
value = _reader->attributes().value("border").toString();
if ( !value.isEmpty() )
border = value.toInt ();
value = _reader->attributes().value("threshold").toString();
if ( !value.isEmpty() )
threshold = value.toFloat ();
value = _reader->attributes().value("goMatched").toString().toLower();
if ( value == "true" ) goMatched = true;
else if ( value == "false" ) goMatched = false;
_displayStyle->addDrawingStyle ( _drawingGroupName
, drawingStyleName
, pattern
, red
, green
, blue
, border
, threshold
, goMatched
);
parseNoChilds ();
}
void GraphicsParser::parseDrawingGroup ()
{
_drawingGroupName = _reader->attributes().value("name").toString().toStdString();
if ( _drawingGroupName.isEmpty() )
cerr << "[ERROR] Empty group name." << endl;
parseTags ( TagsDrawingGroup );
}
void GraphicsParser::parseDisplayStyle ()
{
Name name = _reader->attributes().value("name").toString().toStdString();
_displayStyle = new DisplayStyle ( name );
Graphics::addStyle ( _displayStyle );
if ( !_defaultDisplayStyle )
_defaultDisplayStyle = _displayStyle;
parseTags ( TagsDisplayStyle );
}
void GraphicsParser::parseDisplayStyles ()
{
parseTags ( TagsDisplayStyles );
}
void GraphicsParser::parseGraphics ()
{
parseTags ( TagsGraphics );
if ( _defaultDisplayStyle )
Graphics::setStyle ( _defaultDisplayStyle->getName() );
}
GraphicsParser::GraphicsParser ( QXmlStreamReader* reader )
: XmlParser(reader,6)
, _displayStyle(NULL)
, _defaultDisplayStyle(NULL)
, _drawingGroupName()
{
addTagEntry ( TagsStandAlone , "graphics" , (tagParser_t)&GraphicsParser::parseGraphics );
addTagEntry ( TagsGraphics , "displaystyles", (tagParser_t)&GraphicsParser::parseDisplayStyles );
addTagEntry ( TagsDisplayStyles, "displaystyle" , (tagParser_t)&GraphicsParser::parseDisplayStyle );
addTagEntry ( TagsDisplayStyle , "group" , (tagParser_t)&GraphicsParser::parseDrawingGroup );
addTagEntry ( TagsDisplayStyle , "default" , (tagParser_t)&GraphicsParser::parseDefault );
addTagEntry ( TagsDisplayStyle , "inherit" , (tagParser_t)&GraphicsParser::parseInherit );
addTagEntry ( TagsDisplayStyle , "description" , (tagParser_t)&GraphicsParser::parseDescription );
addTagEntry ( TagsDisplayStyle , "darkening" , (tagParser_t)&GraphicsParser::parseDarkening );
addTagEntry ( TagsDrawingGroup , "drawingstyle" , (tagParser_t)&GraphicsParser::parseDrawingStyle );
}
GraphicsParser* GraphicsParser::create ( QXmlStreamReader* reader )
{
return new GraphicsParser ( reader );
}
bool GraphicsParser::load ( const string& path )
{
GraphicsParser gp;
return gp._load ( path );
}
void GraphicsParser::_postLoad ()
{
if ( getDefaultDisplayStyle() )
Graphics::setStyle ( getDefaultDisplayStyle()->getName() );
}
const char* GraphicsParser::_getMessage ( MessageId id )
{
const char* message = "<unknwown message id>";
switch ( id ) {
case OpenFile: message = "graphics configuration"; break;
}
return message;
}
} // End of CRL namespace.

View File

@ -1,225 +0,0 @@
// -*- C++ -*-
# include <cassert>
# include <string>
# include <QStringList>
# include <QXmlStreamReader>
# include "hurricane/Error.h"
# include "hurricane/Warning.h"
# include "hurricane/DbU.h"
# include "hurricane/DataBase.h"
# include "hurricane/Technology.h"
# include "hurricane/BasicLayer.h"
# include "crlcore/Utilities.h"
# include "crlcore/RealTechnologyParser.h"
namespace CRL {
using namespace std;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::DbU;
const QString RealTechnologyParser::MissingSymbolicNameError = "Missing symbolic layer name attribute";
const QString RealTechnologyParser::MissingRealNameError = "Missing real layer name attribute";
const QString RealTechnologyParser::InvalidSymbolicNameError = "Reference to unknown symbolic layer \"%1\"";
const QString RealTechnologyParser::MissingGridValueError = "Missing grid value attribute";
const QString RealTechnologyParser::MissingGridsPerLambdaValueError = "Missing gridsperlambda value attribute";
const QString RealTechnologyParser::MissingGridUnitError = "Missing grid unit attribute";
const QString RealTechnologyParser::UnknownGridUnitError = "Unknown grid unit kind \"%1\"";
void RealTechnologyParser::parseTechnology ()
{
parseTags ( TagsTechnology );
}
void RealTechnologyParser::parseReal ()
{
parseTags ( TagsReal );
}
void RealTechnologyParser::parseName ()
{
// May do something of the name here...
readTextAsString();
}
void RealTechnologyParser::parseGrid ()
{
QString value;
double gridValue = 1.0;
DbU::UnitPower gridUnit = DbU::Micro;
value = _reader->attributes().value("value").toString();
if ( !value.isEmpty() )
gridValue = value.toDouble ();
else
printError ( MissingGridValueError );
value = _reader->attributes().value("unit").toString();
if ( !value.isEmpty() ) {
if ( value == "pico" ) gridUnit = DbU::Pico;
else if ( value == "nano" ) gridUnit = DbU::Nano;
else if ( value == "micron" ) gridUnit = DbU::Micro;
else if ( value == "milli" ) gridUnit = DbU::Milli;
else if ( value == "unity" ) gridUnit = DbU::Unity;
else if ( value == "kilo" ) gridUnit = DbU::Kilo;
else
printError ( UnknownGridUnitError.arg(value) );
}
else
printError ( MissingGridUnitError );
DbU::setPhysicalsPerGrid ( gridValue, gridUnit );
parseNoChilds ();
}
void RealTechnologyParser::parseGridsPerLambda ()
{
QString value;
double gridsPerLambda = 10.0;
value = _reader->attributes().value("value").toString();
if ( !value.isEmpty() )
gridsPerLambda = value.toInt ();
else
printError ( MissingGridsPerLambdaValueError );
DbU::setGridsPerLambda ( gridsPerLambda );
parseNoChilds ();
}
void RealTechnologyParser::parseLayers ()
{
parseTags ( TagsLayers );
}
void RealTechnologyParser::parseProcessLayer ()
{
QString value;
string symbolicName;
string realName;
unsigned int gdsIInumber = (unsigned int)-1;
value = _reader->attributes().value("symbolic").toString();
if ( !value.isEmpty() )
symbolicName = value.toStdString ();
else
printError ( MissingSymbolicNameError );
value = _reader->attributes().value("real").toString();
if ( !value.isEmpty() )
realName = value.toStdString ();
else
printError ( MissingRealNameError );
value = _reader->attributes().value("gdsII").toString();
if ( !value.isEmpty() )
gdsIInumber = value.toUInt ();
if ( !symbolicName.empty() ) {
BasicLayer* basicLayer = _technology->getBasicLayer ( symbolicName );
if ( basicLayer ) {
basicLayer->setRealName ( realName.c_str() );
basicLayer->setExtractNumber ( gdsIInumber );
} else
printError ( InvalidSymbolicNameError.arg(symbolicName.c_str()) );
}
parseNoChilds ();
}
RealTechnologyParser::RealTechnologyParser ( DataBase* db, QXmlStreamReader* reader )
: XmlParser(reader,TagSetSize)
, _dataBase(db)
, _technology(NULL)
{
assert ( _dataBase != NULL );
_technology = db->getTechnology ();
assert ( _technology != NULL );
addTagEntry ( TagsStandAlone, "technology" , (tagParser_t)&RealTechnologyParser::parseTechnology );
addTagEntry ( TagsTechnology, "real" , (tagParser_t)&RealTechnologyParser::parseReal );
addTagEntry ( TagsReal , "name" , (tagParser_t)&RealTechnologyParser::parseName );
addTagEntry ( TagsReal , "grid" , (tagParser_t)&RealTechnologyParser::parseGrid );
addTagEntry ( TagsReal , "gridsperlambda", (tagParser_t)&RealTechnologyParser::parseGridsPerLambda );
addTagEntry ( TagsReal , "layers" , (tagParser_t)&RealTechnologyParser::parseLayers );
addTagEntry ( TagsLayers , "processlayer" , (tagParser_t)&RealTechnologyParser::parseProcessLayer );
}
RealTechnologyParser* RealTechnologyParser::create ( DataBase* db, QXmlStreamReader* reader )
{
return new RealTechnologyParser ( db, reader );
}
bool RealTechnologyParser::load ( DataBase* db, const string& path )
{
bool aborted = false;
try {
RealTechnologyParser rtp ( db );
return rtp._load ( path );
}
catch ( Error& e ) {
cerr << e.what() << endl;
aborted = true;
}
catch ( ... ) {
cout << "[ERROR] Abnormal termination: unknown exception.\n" << endl;
exit ( 2 );
}
if ( aborted ) {
cerr << "[ERROR] Aborting & unloading S2R Technology." << endl;
//Technology* technology = db->getTechnology ();
//if ( technology ) technology->destroy ();
exit ( 1 );
}
return false;
}
void RealTechnologyParser::_postLoad ()
{
}
const char* RealTechnologyParser::_getMessage ( MessageId id )
{
const char* message = "<unknwown message id>";
switch ( id ) {
case OpenFile: message = "S2R Technology configuration"; break;
}
return message;
}
} // End of CRL namespace.

View File

@ -21,7 +21,6 @@
#include "hurricane/ViaLayer.h"
#include "hurricane/Technology.h"
#include "hurricane/DataBase.h"
#include "crlcore/XmlParser.h"
#include "crlcore/RoutingLayerGauge.h"
#include "crlcore/RoutingGauge.h"
#include "crlcore/AllianceFramework.h"
@ -40,6 +39,7 @@ namespace {
namespace CRL {
using namespace std;
using Hurricane::JsonTypes;
using Hurricane::JsonArray;
using Hurricane::DataBase;

View File

@ -1,575 +0,0 @@
// -*- C++ -*-
#include <cassert>
#include <string>
#include <algorithm>
#include <QStringList>
#include <QXmlStreamReader>
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/DbU.h"
#include "hurricane/DataBase.h"
#include "hurricane/Technology.h"
#include "hurricane/BasicLayer.h"
#include "hurricane/RegularLayer.h"
#include "hurricane/DiffusionLayer.h"
#include "hurricane/TransistorLayer.h"
#include "hurricane/ViaLayer.h"
#include "hurricane/ContactLayer.h"
#include "crlcore/SymbolicTechnologyParser.h"
#include "crlcore/Utilities.h"
namespace CRL {
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::DbU;
using Hurricane::RegularLayer;
using Hurricane::DiffusionLayer;
using Hurricane::TransistorLayer;
using Hurricane::TransistorLayer;
using Hurricane::ContactLayer;
using Hurricane::ViaLayer;
const QString SymbolicTechnologyParser::UnnamedRuleError = "Rule has an empty name.";
const QString SymbolicTechnologyParser::UnnamedBasicLayerError = "Missing name attribute in <basiclayer>.";
const QString SymbolicTechnologyParser::UnnamedSymbolicLayerError = "Missing name attribute in <%1>.";
const QString SymbolicTechnologyParser::UnnamedLayerError = "Missing name attribute in <layer>.";
const QString SymbolicTechnologyParser::InvalidRulePathError = "Invalid rule path \"%1\".";
const QString SymbolicTechnologyParser::MissingValueError = "Rule \"%1\" has no <value> attribute.";
const QString SymbolicTechnologyParser::UnknownRuleError = "Misspelled or unknown rule \"%1\".";
const QString SymbolicTechnologyParser::UndefinedLayerError = "Reference to yet undefined layer \"%1\".";
const QString SymbolicTechnologyParser::NotACompositeLayerError = "Rule layer \"%1\" is not a composite layer.";
const QString SymbolicTechnologyParser::NotABasicLayerError = "Rule sub-layer \"%1\" is not a basic layer.";
const QString SymbolicTechnologyParser::LayerOutnumber = "More than %1 sub-layers in <%2>.";
const QString SymbolicTechnologyParser::LayerMissingLayer = "Less than %1 sub-layers in <%2>.";
void SymbolicTechnologyParser::parseTechnology ()
{
parseTags ( TagsTechnology );
}
void SymbolicTechnologyParser::parseName ()
{
_technology->setName ( readTextAsString().toStdString().c_str() );
}
void SymbolicTechnologyParser::parseBasicLayer ()
{
QString value;
string layerName;
BasicLayer::Material layerMaterial = BasicLayer::Material::other;
unsigned extractNumber = 0;
value = _reader->attributes().value("name").toString();
if ( !value.isEmpty() )
layerName = value.toStdString ();
else
printError ( UnnamedBasicLayerError );
value = _reader->attributes().value("material").toString();
if ( !value.isEmpty() ) {
if ( value == "nWell" ) layerMaterial = BasicLayer::Material::nWell;
else if ( value == "pWell" ) layerMaterial = BasicLayer::Material::pWell;
else if ( value == "nImplant" ) layerMaterial = BasicLayer::Material::nImplant;
else if ( value == "pImplant" ) layerMaterial = BasicLayer::Material::pImplant;
else if ( value == "active" ) layerMaterial = BasicLayer::Material::active;
else if ( value == "poly" ) layerMaterial = BasicLayer::Material::poly;
else if ( value == "cut" ) layerMaterial = BasicLayer::Material::cut;
else if ( value == "metal" ) layerMaterial = BasicLayer::Material::metal;
else if ( value == "blockage" ) layerMaterial = BasicLayer::Material::blockage;
else if ( value == "other" ) layerMaterial = BasicLayer::Material::other;
}
if ( !layerName.empty() ) {
_basicLayer = BasicLayer::create ( _technology, layerName, layerMaterial, extractNumber );
_layers [ _basicLayer->getName() ] = _basicLayer;
}
value = _reader->attributes().value("basiclayer").toString();
if ( not value.isEmpty() and (layerMaterial == BasicLayer::Material::blockage) ) {
layerName = value.toStdString ();
BasicLayer* routingLayer = _technology->getBasicLayer ( layerName.c_str() );
if ( routingLayer and _basicLayer ) {
routingLayer->setBlockageLayer ( _basicLayer );
}
}
parseNoChilds ();
_basicLayer = NULL;
}
void SymbolicTechnologyParser::parseRegularLayer ()
{
QString value;
string layerName;
RegularLayer* regularLayer = NULL;
value = _reader->attributes().value("name").toString();
if ( !value.isEmpty() )
layerName = value.toStdString ();
else
printError ( UnnamedSymbolicLayerError.arg("regularlayer") );
_layerComponents.clear ();
parseTags ( TagsBasicLayers );
if ( !layerName.empty() ) {
if ( !_layerComponents.empty() ) {
if ( _layerComponents.size() > 1 )
printError ( LayerOutnumber.arg("1","regularlayer") );
regularLayer = RegularLayer::create ( _technology, layerName );
regularLayer->setBasicLayer ( _layerComponents[0] );
_layers [ regularLayer->getName() ] = regularLayer;
_layerComponents.clear ();
}
}
}
void SymbolicTechnologyParser::parseDiffusionLayer ()
{
QString value;
string layerName;
DiffusionLayer* layer = NULL;
value = _reader->attributes().value("name").toString();
if ( !value.isEmpty() )
layerName = value.toStdString ();
else
printError ( UnnamedSymbolicLayerError.arg("diffusionlayer") );
_layerComponents.clear ();
parseTags ( TagsBasicLayers );
if ( !layerName.empty() ) {
reverse ( _layerComponents.begin(), _layerComponents.end() );
switch ( _layerComponents.size() ) {
case 0:
case 1:
printError ( LayerMissingLayer.arg("2","diffusionlayer") );
break;
case 2:
_layerComponents.push_back ( NULL );
default:
layer = DiffusionLayer::create ( _technology
, layerName
, _layerComponents[0]
, _layerComponents[1]
, _layerComponents[2]
);
_layers [ layer->getName() ] = layer;
if ( _layerComponents.size() > 3 )
printError ( LayerOutnumber.arg("3","diffusionlayer") );
}
}
_layerComponents.clear ();
}
void SymbolicTechnologyParser::parseTransistorLayer ()
{
QString value;
string layerName;
TransistorLayer* layer = NULL;
value = _reader->attributes().value("name").toString();
if ( !value.isEmpty() )
layerName = value.toStdString ();
else
printError ( UnnamedSymbolicLayerError.arg("transistorlayer") );
_layerComponents.clear ();
parseTags ( TagsBasicLayers );
if ( !layerName.empty() ) {
reverse ( _layerComponents.begin(), _layerComponents.end() );
switch ( _layerComponents.size() ) {
case 0:
case 1:
case 2:
printError ( LayerMissingLayer.arg("3","transistorlayer") );
break;
case 3:
_layerComponents.push_back ( NULL );
default:
layer = TransistorLayer::create ( _technology
, layerName
, _layerComponents[0]
, _layerComponents[1]
, _layerComponents[2]
, _layerComponents[3]
);
_layers [ layer->getName() ] = layer;
if ( _layerComponents.size() > 4 )
printError ( LayerOutnumber.arg("4","transistorlayer") );
}
}
_layerComponents.clear ();
}
void SymbolicTechnologyParser::parseContactLayer ()
{
QString value;
string layerName;
ContactLayer* layer = NULL;
value = _reader->attributes().value("name").toString();
if ( !value.isEmpty() )
layerName = value.toStdString ();
else
printError ( UnnamedSymbolicLayerError.arg("contactlayer") );
_layerComponents.clear ();
parseTags ( TagsBasicLayers );
if ( !layerName.empty() ) {
reverse ( _layerComponents.begin(), _layerComponents.end() );
switch ( _layerComponents.size() ) {
case 0:
case 1:
case 2:
case 3:
printError ( LayerMissingLayer.arg("3","contactlayer") );
break;
case 4:
_layerComponents.push_back ( NULL );
default:
layer = ContactLayer::create ( _technology
, layerName
, _layerComponents[0]
, _layerComponents[1]
, _layerComponents[2]
, _layerComponents[3]
, _layerComponents[4]
);
_layers [ layer->getName() ] = layer;
if ( _layerComponents.size() > 5 )
printError ( LayerOutnumber.arg("5","contactlayer") );
}
}
_layerComponents.clear ();
}
void SymbolicTechnologyParser::parseViaLayer ()
{
QString value;
string layerName;
ViaLayer* layer = NULL;
value = _reader->attributes().value("name").toString();
if ( !value.isEmpty() )
layerName = value.toStdString ();
else
printError ( UnnamedSymbolicLayerError.arg("vialayer") );
_layerComponents.clear ();
parseTags ( TagsBasicLayers );
if ( !layerName.empty() ) {
reverse ( _layerComponents.begin(), _layerComponents.end() );
switch ( _layerComponents.size() ) {
case 0:
case 1:
printError ( LayerMissingLayer.arg("3","vialayer") );
break;
default:
layer = ViaLayer::create ( _technology
, layerName
, _layerComponents[0]
, _layerComponents[1]
, _layerComponents[2]
);
_layers [ layer->getName() ] = layer;
if ( _layerComponents.size() > 3 )
printError ( LayerOutnumber.arg("3","vialayer") );
}
}
_layerComponents.clear ();
}
void SymbolicTechnologyParser::parseLayer ()
{
QString value;
string layerName;
value = _reader->attributes().value("name").toString();
if ( !value.isEmpty() )
layerName = value.toStdString ();
else
printError ( UnnamedLayerError );
if ( !layerName.empty() ) {
BasicLayer* basicLayer = getBasicLayer ( QString(layerName.c_str()), false );
if ( basicLayer )
_layerComponents.push_back ( basicLayer );
}
parseNoChilds ();
}
void SymbolicTechnologyParser::parseSymbolic ()
{
parseTags ( TagsSymbolic );
}
void SymbolicTechnologyParser::parsePrecision ()
{
DbU::setPrecision ( readTextAsUInt() );
}
void SymbolicTechnologyParser::parseGridStep ()
{
//DbU::setGridStep ( DbU::symbolic( readTextAsDouble()) );
parseNoChilds ();
}
void SymbolicTechnologyParser::parseRules ()
{
parseTags ( TagsRules );
}
void SymbolicTechnologyParser::parseRule ()
{
double doubleValue = 0.0;
Layer* ruleLayer = NULL;
BasicLayer* basicLayer = NULL;
QString ruleName;
unsigned int ruleType;
ruleName = _reader->attributes().value("name").toString();
if ( !ruleName.isEmpty() ) {
//cerr << qPrintable(ruleName) << endl;
ruleType = splitRulePath ( ruleName, ruleLayer, basicLayer );
if ( ( ruleType != InvalidRule ) && ( ruleLayer ) ) {
QString ruleValue = _reader->attributes().value("value").toString();
if ( !ruleValue.isEmpty() ) {
switch ( ruleType & ValueMask ) {
case DoubleValue: doubleValue = ruleValue.toDouble(); break;
}
switch ( ruleType ) {
case ExtentionCap: ruleLayer->setExtentionCap (basicLayer,DbU::lambda(doubleValue)); break;
case ExtentionWidth: ruleLayer->setExtentionWidth(basicLayer,DbU::lambda(doubleValue)); break;
case Enclosure: ruleLayer->setEnclosure (basicLayer,DbU::lambda(doubleValue),Layer::EnclosureH|Layer::EnclosureV); break;
case MinimumWidth: ruleLayer->setMinimalSize (DbU::lambda(doubleValue)); break;
case MinimumSide: ruleLayer->setMinimalSize (DbU::lambda(doubleValue)); break;
}
} else
printError ( MissingValueError.arg(ruleName) );
} else
if ( ruleLayer )
printError ( UnknownRuleError.arg(ruleName) );
} else
printError ( UnnamedRuleError );
parseNoChilds ();
}
unsigned int SymbolicTechnologyParser::splitRulePath ( const QString& path
, Layer*& ruleLayer
, BasicLayer*& basicLayer
)
{
ruleLayer = NULL;
basicLayer = NULL;
unsigned int ruleType = InvalidRule;
QStringList pathElements = path.split ( "." );
if ( pathElements.isEmpty() ) {
printError ( InvalidRulePathError.arg(path) );
return ruleType;
}
ruleLayer = getLayer ( pathElements[0], false );
pathElements.pop_front ();
basicLayer = getBasicLayer ( pathElements[0], true );
if ( basicLayer ) pathElements.pop_front ();
QString tailPath = pathElements.join ( "." );
if ( tailPath == "extention.cap" ) ruleType = ExtentionCap;
else if ( tailPath == "extention.width" ) ruleType = ExtentionWidth;
else if ( tailPath == "enclosure" ) ruleType = Enclosure;
else if ( tailPath == "minimum.width" ) ruleType = MinimumWidth;
else if ( tailPath == "minimum.side" ) ruleType = MinimumSide;
return ruleType;
}
Layer* SymbolicTechnologyParser::getLayer ( const QString& name, bool ignoreError )
{
Name layerName = name.toStdString();
map<const Name,Layer*>::iterator it = _layers.find ( layerName );
if ( it == _layers.end() ) {
if ( !ignoreError )
printError ( UndefinedLayerError.arg(name) );
return NULL;
}
return it->second;
}
BasicLayer* SymbolicTechnologyParser::getBasicLayer ( const QString& name, bool ignoreError )
{
Name layerName = name.toStdString();
map<const Name,Layer*>::iterator it = _layers.find ( layerName );
if ( it == _layers.end() ) {
if ( !ignoreError )
printError ( UndefinedLayerError.arg(name) );
return NULL;
}
BasicLayer* basicLayer = dynamic_cast<BasicLayer*> ( it->second );
if ( !basicLayer )
printError ( NotABasicLayerError.arg(name) );
return basicLayer;
}
SymbolicTechnologyParser::SymbolicTechnologyParser ( DataBase* db, QXmlStreamReader* reader )
: XmlParser(reader,TagSetSize)
, _dataBase(db)
, _technology(NULL)
, _basicLayer(NULL)
, _layers()
, _layerComponents()
{
assert ( _dataBase != NULL );
_technology = db->getTechnology ();
if ( !_technology )
_technology = Technology::create ( db, "<SymbolicTechnologyParser>" );
addTagEntry ( TagsStandAlone , "technology" , (tagParser_t)&SymbolicTechnologyParser::parseTechnology );
addTagEntry ( TagsTechnology , "name" , (tagParser_t)&SymbolicTechnologyParser::parseName );
addTagEntry ( TagsTechnology , "basiclayer" , (tagParser_t)&SymbolicTechnologyParser::parseBasicLayer );
addTagEntry ( TagsTechnology , "regularlayer" , (tagParser_t)&SymbolicTechnologyParser::parseRegularLayer );
addTagEntry ( TagsTechnology , "diffusionlayer" , (tagParser_t)&SymbolicTechnologyParser::parseDiffusionLayer );
addTagEntry ( TagsTechnology , "transistorlayer", (tagParser_t)&SymbolicTechnologyParser::parseTransistorLayer );
addTagEntry ( TagsTechnology , "vialayer" , (tagParser_t)&SymbolicTechnologyParser::parseViaLayer );
addTagEntry ( TagsTechnology , "contactlayer" , (tagParser_t)&SymbolicTechnologyParser::parseContactLayer );
addTagEntry ( TagsBasicLayers , "layer" , (tagParser_t)&SymbolicTechnologyParser::parseLayer );
addTagEntry ( TagsTechnology , "symbolic" , (tagParser_t)&SymbolicTechnologyParser::parseSymbolic );
addTagEntry ( TagsSymbolic , "precision" , (tagParser_t)&SymbolicTechnologyParser::parsePrecision );
addTagEntry ( TagsSymbolic , "gridstep" , (tagParser_t)&SymbolicTechnologyParser::parseGridStep );
addTagEntry ( TagsSymbolic , "rules" , (tagParser_t)&SymbolicTechnologyParser::parseRules );
addTagEntry ( TagsRules , "rule" , (tagParser_t)&SymbolicTechnologyParser::parseRule );
}
SymbolicTechnologyParser* SymbolicTechnologyParser::create ( DataBase* db, QXmlStreamReader* reader )
{
return new SymbolicTechnologyParser ( db, reader );
}
bool SymbolicTechnologyParser::load ( DataBase* db, const string& path )
{
bool aborted = false;
try {
SymbolicTechnologyParser tp ( db );
return tp._load ( path );
}
catch ( Error& e ) {
cerr << e.what() << endl;
aborted = true;
}
catch ( ... ) {
cout << "[ERROR] Abnormal termination: unknown exception.\n" << endl;
exit ( 2 );
}
if ( aborted ) {
cerr << "[ERROR] Aborting & unloading Technology." << endl;
//Technology* technology = db->getTechnology ();
//if ( technology ) technology->destroy ();
exit ( 1 );
}
return false;
}
void SymbolicTechnologyParser::_postLoad ()
{
// Fixme.
_technology->setSymbolicLayer ( "POLY" );
_technology->setSymbolicLayer ( "METAL1" );
_technology->setSymbolicLayer ( "METAL2" );
_technology->setSymbolicLayer ( "METAL3" );
_technology->setSymbolicLayer ( "METAL4" );
_technology->setSymbolicLayer ( "METAL5" );
_technology->setSymbolicLayer ( "METAL6" );
_technology->setSymbolicLayer ( "BLOCKAGE1" );
_technology->setSymbolicLayer ( "BLOCKAGE2" );
_technology->setSymbolicLayer ( "BLOCKAGE3" );
_technology->setSymbolicLayer ( "BLOCKAGE4" );
_technology->setSymbolicLayer ( "BLOCKAGE5" );
_technology->setSymbolicLayer ( "BLOCKAGE6" );
_technology->setSymbolicLayer ( "gmetalh" );
_technology->setSymbolicLayer ( "gmetalv" );
_technology->setSymbolicLayer ( "VIA12" );
_technology->setSymbolicLayer ( "VIA23" );
_technology->setSymbolicLayer ( "VIA34" );
_technology->setSymbolicLayer ( "VIA45" );
_technology->setSymbolicLayer ( "VIA56" );
_technology->setSymbolicLayer ( "gcontact" );
}
const char* SymbolicTechnologyParser::_getMessage ( MessageId id )
{
const char* message = "<unknwown message id>";
switch ( id ) {
case OpenFile: message = "Technology configuration"; break;
}
return message;
}
} // End of CRL namespace.

View File

@ -443,18 +443,6 @@ namespace CRL {
Utilities::Path sysConfDir = getPath("etc");
Utilities::Path pythonSitePackages = getPath("pythonSitePackages");
#if XML_NOT_DISABLED
bool systemConfFound = false;
Utilities::Path systemConfFile = sysConfDir / "tools.configuration.xml";
if ( systemConfFile.exists() ) {
systemConfFound = true;
conf->readFromFile ( systemConfFile.string() );
} else {
cerr << Warning("System configuration file:\n <%s> not found."
,systemConfFile.string().c_str()) << endl;
}
#endif
//bool systemConfFound = false;
Utilities::Path systemConfFile = pythonSitePackages / "crlcore" / "coriolisInit.py";
if ( systemConfFile.exists() ) {
@ -470,21 +458,6 @@ namespace CRL {
,systemConfFile.toString().c_str()) << endl;
}
//bool homeConfFound = false;
Utilities::Path homeConfFile = getPath("home");
homeConfFile /= ".coriolis2.configuration.xml";
if ( homeConfFile.exists() ) {
//homeConfFound = true;
conf->readFromFile ( homeConfFile.toString() );
}
//bool dotConfFound = false;
Utilities::Path dotConfFile = "./.coriolis2.configuration.xml";
if ( dotConfFile.exists() ) {
//dotConfFound = true;
conf->readFromFile ( dotConfFile.toString() );
}
// Delayed printing, as we known only now whether VerboseLevel1 is requested.
//if ( cmess1.enabled() ) {
// cmess1 << " o Reading Configuration. " << endl;

View File

@ -1,190 +0,0 @@
// -*- C++ -*-
#include <cassert>
#include <string>
#include <QFile>
#include <QXmlStreamReader>
#include "crlcore/Utilities.h"
#include "crlcore/XmlParser.h"
namespace CRL {
XmlParser::XmlParser ( QXmlStreamReader* reader, size_t tagsTablesSize )
: _tagsTables(tagsTablesSize)
, _reader(reader)
{
}
XmlParser::~XmlParser ()
{
}
bool XmlParser::_load ( const string& path, bool warnNotFound )
{
QFile file ( path.c_str() );
if ( path.empty() or (not file.open(QFile::ReadOnly|QFile::Text)) ) {
if ( warnNotFound ) {
cerr << "[ERROR] Cannot open " << _getMessage(OpenFile) << " file:" << endl;
cerr << " \"" << path << "\"." << endl;
}
return false;
}
//cmess1 << " - <" << path << ">." << endl;
QXmlStreamReader reader ( &file );
_reader = &reader;
parseStandAlone ();
file.close ();
if ( reader.hasError() ) {
cerr << "[ERROR] Syntax error " << _getMessage(OpenFile) << " in file:" << endl;
cerr << " \"" << path << "\"." << endl;
cerr << " (" << qPrintable(reader.errorString()) << ", line:"
<< reader.lineNumber() << ")" << endl;
return false;
}
_postLoad ();
return true;
}
void XmlParser::addTagEntry ( int tagSet, const char* tag, tagParser_t tagParser )
{
if ( (size_t)tagSet >= _tagsTables.size() ) {
cerr << "[ERROR] tagSet id " << tagSet << " is not within tag table range." << endl;
cerr << " (disabling management of tag: " << tag << ")" << endl;
return;
}
_tagsTables[tagSet].push_back ( TagEntry(tag,tagParser) );
}
void XmlParser::parseTags ( int tagSet )
{
assert ( (size_t)tagSet < _tagsTables.size() );
TagsTable& tags = _tagsTables[tagSet];
_reader->readNext ();
while ( !_reader->atEnd() ) {
if ( _reader->isEndElement() ) {
_reader->readNext();
break;
}
if ( _reader->isStartElement() ) {
size_t entry = 0;
for ( ; entry<tags.size() ; entry++ ) {
if ( _reader->name() == tags[entry]._name ) {
(this->*(tags[entry]._parser)) ();
break;
}
}
if ( entry >= tags.size() ) {
// if ( tags.size() == 1 ) {
// _reader->raiseError ( QString("missing <%1> tag").arg(tags[0]._name) );
// }
parseUnknownTag ();
}
} else
_reader->readNext ();
}
}
void XmlParser::parseUnknownTag ()
{
cerr << "[WARNING] Skipping unknown tag: <"
<< qPrintable(_reader->name().toString()) << ">." << endl;
_reader->readNext ();
while ( !_reader->atEnd() ) {
if ( _reader->isEndElement() ) {
_reader->readNext();
break;
}
if ( _reader->isStartElement() ) {
parseUnknownTag ();
} else
_reader->readNext ();
}
}
void XmlParser::parseStandAlone ()
{
parseTags ( TagsStandAlone );
}
// const char* XmlParser::readTextAsAscii ()
// {
// const char* value = _reader->readElementText().toStdString().c_str();
// if ( _reader->isEndElement() ) _reader->readNext ();
// return value;
// }
QString XmlParser::readTextAsString ()
{
QString value = _reader->readElementText();
if ( _reader->isEndElement() ) _reader->readNext ();
return value;
}
unsigned int XmlParser::readTextAsUInt ()
{
unsigned int value = _reader->readElementText().toUInt();
if ( _reader->isEndElement() ) _reader->readNext ();
return value;
}
long XmlParser::readTextAsLong ()
{
long value = _reader->readElementText().toLong();
if ( _reader->isEndElement() ) _reader->readNext ();
return value;
}
double XmlParser::readTextAsDouble ()
{
double value = _reader->readElementText().toDouble();
if ( _reader->isEndElement() ) _reader->readNext ();
return value;
}
void XmlParser::printError ( const QString& error, ostream& o )
{
o << "[ERROR] " << qPrintable(error) << endl;
QFile* file = dynamic_cast<QFile*> ( _reader->device() );
QString fileName = "<not a file>";
if ( file )
fileName = file->fileName();
o << " (line: " << _reader->lineNumber()
<< ", file: " << qPrintable(fileName) << ")" << endl;
}
} // End of CRL namespace.

View File

@ -292,13 +292,21 @@ namespace {
, _connections ()
, _model (NULL)
{
Cell* cell = AllianceFramework::get()->getCell( modelName, Catalog::State::Views|Catalog::State::Foreign, 0 );
if (cell) {
_model = Model::find( getString(cell->getName()) );
AllianceFramework* af = AllianceFramework::get();
if (af->isInCatalog(modelName)) {
_model = Model::find( modelName );
if (not _model) {
_model = new Model ( cell );
_model = new Model ( af->getCell( modelName, Catalog::State::Views, 0 ) );
}
}
// Cell* cell = AllianceFramework::get()->getCell( modelName, Catalog::State::Views|Catalog::State::Foreign, 0 );
// if (cell) {
// _model = Model::find( getString(cell->getName()) );
// if (not _model) {
// _model = new Model ( cell );
// }
// }
}
inline Model* Subckt::getModel () const { return _model; }
@ -733,21 +741,21 @@ namespace CRL {
if (tokenize.state() & Tokenize::CoverAlias) {
blifModel->mergeAlias( blifLine[1], blifLine[2] );
} else if (tokenize.state() & Tokenize::CoverZero) {
cerr << Warning( "Blif::load() Definition of an alias <%s> of VSS in a \".names\". Maybe you should use tie cells?\n"
" File \"%s.blif\" at line %u."
, blifLine[1].c_str()
, blifFile.c_str()
, tokenize.lineno()
) << endl;
cparanoid << Warning( "Blif::load() Definition of an alias <%s> of VSS in a \".names\". Maybe you should use tie cells?\n"
" File \"%s.blif\" at line %u."
, blifLine[1].c_str()
, blifFile.c_str()
, tokenize.lineno()
) << endl;
//blifModel->mergeAlias( blifLine[1], "vss" );
blifModel->getCell()->getNet( blifModel->getGroundName() )->addAlias( blifLine[1] );
} else if (tokenize.state() & Tokenize::CoverOne ) {
cerr << Warning( "Blif::load() Definition of an alias <%s> of VDD in a \".names\". Maybe you should use tie cells?\n"
" File \"%s.blif\" at line %u."
, blifLine[1].c_str()
, blifFile.c_str()
, tokenize.lineno()
) << endl;
cparanoid << Warning( "Blif::load() Definition of an alias <%s> of VDD in a \".names\". Maybe you should use tie cells?\n"
" File \"%s.blif\" at line %u."
, blifLine[1].c_str()
, blifFile.c_str()
, tokenize.lineno()
) << endl;
//blifModel->mergeAlias( blifLine[1], "vdd" );
blifModel->getCell()->getNet( blifModel->getPowerName() )->addAlias( blifLine[1] );
} else {

View File

@ -74,7 +74,7 @@ void CifQuery::goCallback(Go* go) {
else {
return;
}
Polygon* poly = new Polygon ( layer->getExtractNumber() );
Polygon* poly = new Polygon ( layer->getGds2Layer() );
long xMin = (long)round(DbU::getPhysical(b.getXMin(), DbU::Nano));
long yMin = (long)round(DbU::getPhysical(b.getYMin(), DbU::Nano));
long xMax = (long)round(DbU::getPhysical(b.getXMax(), DbU::Nano));

View File

@ -8,7 +8,7 @@
// | Alliance / Hurricane Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./crlcore/AllianceFramework.h" |
// +-----------------------------------------------------------------+
@ -63,6 +63,8 @@ namespace CRL {
static AllianceFramework* get ();
string getPrint () const;
// Predicates.
Catalog::State* isInCatalog ( const Name& );
Catalog::State* isInCatalog ( string );
inline bool isPOWER ( const char* name );
inline bool isPOWER ( const string& name );
inline bool isPOWER ( const Name& name );

View File

@ -1,192 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Project.
// Copyright (C) Laboratoire LIP6 - Departement ASIM
// Universite Pierre et Marie Curie
//
// Main contributors :
// Christophe Alexandre <Christophe.Alexandre@lip6.fr>
// Sophie Belloeil <Sophie.Belloeil@lip6.fr>
// Hugo Clément <Hugo.Clement@lip6.fr>
// Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
// Damien Dupuis <Damien.Dupuis@lip6.fr>
// Christian Masson <Christian.Masson@lip6.fr>
// Marek Sroka <Marek.Sroka@lip6.fr>
//
// The Coriolis Project is free software; you can redistribute it
// and/or modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// The Coriolis Project is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with the Coriolis Project; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA
//
// License-Tag
// Authors-Tag
// ===================================================================
//
// $Id: CLayerConnexity.h,v 1.7 2007/07/29 15:27:22 jpc Exp $
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | C o r e L i b r a r y |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Header : "./CLayerConnexity.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
# ifndef __CRL_LAYER_CONNEXITY_H__
# define __CRL_LAYER_CONNEXITY_H__
# include <map>
# include "hurricane/Layer.h"
# include "hurricane/BasicLayer.h"
# include "hurricane/Contact.h"
# include "hurricane/Utilities.h"
# include "hurricane/CXML.h"
# include "hurricane/Slot.h"
namespace CRL {
// -------------------------------------------------------------------
// Forward Declarations.
class CDataBase;
// -------------------------------------------------------------------
// Class : "Eolienne::CLayerConnexity".
class CLayerConnexity {
// Types.
protected:
typedef vector<Layer*> LayerTable;
typedef map<Layer::Mask,Layer*> MaskLayerMap;
typedef map<Layer*,Layer*> LayerMap;
// Attributes.
protected:
Layer::Mask _cutMask;
LayerTable _layerTable;
MaskLayerMap _contactMap;
MaskLayerMap _oppositeMap;
MaskLayerMap _contactTopMap;
MaskLayerMap _contactBottomMap;
LayerMap _topMap;
LayerMap _bottomMap;
LayerMap _connectorMap;
// Constructors.
protected:
CLayerConnexity ();
void _postCreate ();
private:
CLayerConnexity ( const CLayerConnexity& );
CLayerConnexity& operator= ( const CLayerConnexity& );
// Destructors.
protected:
virtual ~CLayerConnexity ();
virtual void _preDestroy ();
public:
virtual void destroy();
// Accessors.
public:
Layer* getContactLayer ( Layer* layer1, Layer* layer2 ) const;
Layer* getContactTopLayer ( Layer* layer ) const;
Layer* getContactBottomLayer ( Layer* layer ) const;
Layer* getOppositeLayer ( Contact* contact, Layer* layer ) const;
Layer* getTopLayer ( Layer* layer ) const;
Layer* getBottomLayer ( Layer* layer ) const;
bool IsOnTop ( Layer* layer1, Layer* layer2 ) const;
bool IsConnectorLayer ( Layer* layer ) const;
Layer* getNonConnectorLayer ( Layer* layer ) const;
Layer* getLayer ( unsigned index ) const;
unsigned getIndex ( Layer* layer ) const;
unsigned getLayerTableSize () const { return _layerTable.size(); };
// Modifiers.
public:
void AddContact ( Layer* bottomLayer, Layer* topLayer, Layer* contact );
void SortLayers ();
// XML related constructors.
public:
static void createFromXml ( CLayerConnexity* lc, CXmlNode& tree );
// Hurricane Managment.
public:
Record* _getRecord () const;
string _getString () const;
string _getTypeName() const { return ( "CRL::CLayerConnexity" ); };
// Friends.
friend class CDataBase;
};
// x-----------------------------------------------------------------x
// | Functions Declarations |
// x-----------------------------------------------------------------x
// Global CLayerConnexity access.
CLayerConnexity* getCLayerConnexity ();
unsigned getLayerTableSize ();
unsigned getIndex ( Layer* layer );
Layer* getLayer ( unsigned index );
Layer* getContactLayer ( Layer* layer1, Layer* layer2 );
inline Layer* getContactLayer ( unsigned index1, unsigned index2 )
{ return getContactLayer(getLayer(index1),getLayer(index2)); };
Layer* getContactTopLayer ( Layer* layer );
Layer* getContactBottomLayer ( Layer* layer );
Layer* getOppositeLayer ( Contact* contact, Layer* layer );
Layer* getTopLayer ( Layer* layer );
Layer* getBottomLayer ( Layer* layer );
bool IsOnTop ( Layer* layer1, Layer* layer2 );
bool IsConnectorLayer ( Layer* layer );
Layer* getNonConnectorLayer ( Layer* layer );
} // End of namespace CRL.
// x-----------------------------------------------------------------x
// | Functions Overload for Hurricane Managment |
// x-----------------------------------------------------------------x
# endif

View File

@ -8,7 +8,7 @@
// | Alliance / Hurricane Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./crlcore/Catalog.h" |
// +-----------------------------------------------------------------+

View File

@ -0,0 +1,41 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2018-2018, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | G D S I I / Hurricane Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./crlcore/Gds.h" |
// +-----------------------------------------------------------------+
#ifndef CRL_GDS_H
#define CRL_GDS_H
#include <string>
namespace Hurricane {
class Cell;
}
namespace CRL {
using Hurricane::Cell;
class Gds {
public:
static bool save ( Cell* );
};
} // CRL namespace.
# endif

View File

@ -1,73 +0,0 @@
// -*- C++ -*-
# ifndef __CRL_GRAPHICS_PARSER_H__
# define __CRL_GRAPHICS_PARSER_H__
# include "hurricane/Name.h"
# include "crlcore/XmlParser.h"
namespace Hurricane {
class DisplayStyle;
}
namespace CRL {
using Hurricane::Name;
using Hurricane::DisplayStyle;
class GraphicsParser : public XmlParser {
// Methods.
public:
static GraphicsParser* create ( QXmlStreamReader* reader );
static bool load ( const string& path );
inline DisplayStyle* getDefaultDisplayStyle () const;
// Internal - enum.
protected:
enum TagSet { TagsGraphics = 2
, TagsDisplayStyles = 3
, TagsDisplayStyle = 4
, TagsDrawingGroup = 5
};
// Internal - Attributes.
DisplayStyle* _displayStyle;
DisplayStyle* _defaultDisplayStyle;
Name _drawingGroupName;
// Internal - Constructors.
GraphicsParser ( QXmlStreamReader* reader=NULL );
GraphicsParser ( const GraphicsParser& );
GraphicsParser& operator= ( const GraphicsParser& );
// Internal - Methods.
void parseDefault ();
void parseDescription ();
void parseDarkening ();
void parseInherit ();
void parseDrawingStyle ();
void parseDrawingGroup ();
void parseDisplayStyle ();
void parseDisplayStyles ();
void parseGraphics ();
virtual void _postLoad ();
virtual const char* _getMessage ( MessageId id );
};
inline DisplayStyle* GraphicsParser::getDefaultDisplayStyle () const
{ return _defaultDisplayStyle; }
} // End of CRL namespace.
# endif

View File

@ -1,80 +0,0 @@
// -*- C++ -*-
#ifndef __CRL_REAL_TECHNOLOGY_PARSER_H__
#define __CRL_REAL_TECHNOLOGY_PARSER_H__
class QString;
#include "crlcore/XmlParser.h"
namespace Hurricane {
class DataBase;
class Technology;
class Layer;
class BasicLayer;
}
namespace CRL {
using Hurricane::DataBase;
using Hurricane::Technology;
using Hurricane::Layer;
using Hurricane::BasicLayer;
class RealTechnologyParser : public XmlParser {
// Methods.
public:
static RealTechnologyParser* create ( DataBase* db, QXmlStreamReader* reader );
static bool load ( DataBase* db, const string& path );
// Internal - enum.
protected:
enum TagSet { TagsTechnology = 2
, TagsReal
, TagsName
, TagsLayers
, TagsProcessLayer
, TagSetSize
};
// Internal - Attributes.
static const QString MissingSymbolicNameError;
static const QString MissingRealNameError;
static const QString InvalidSymbolicNameError;
static const QString MissingGridValueError;
static const QString MissingGridsPerLambdaValueError;
static const QString MissingGridUnitError;
static const QString UnknownGridUnitError;
DataBase* _dataBase;
Technology* _technology;
// Internal - Constructors.
RealTechnologyParser ( DataBase* db, QXmlStreamReader* reader=NULL );
RealTechnologyParser ( const RealTechnologyParser& );
RealTechnologyParser& operator= ( const RealTechnologyParser& );
// Internal - Methods.
void parseTechnology ();
void parseReal ();
void parseName ();
void parseGrid ();
void parseGridsPerLambda ();
void parseLayers ();
void parseProcessLayer ();
virtual void _postLoad ();
virtual const char* _getMessage ( MessageId id );
};
} // End of CRL namespace.
#endif

View File

@ -1,119 +0,0 @@
// -*- C++ -*-
# ifndef __CRL_SYMBOLIC_TECHNOLOGY_PARSER_H__
# define __CRL_SYMBOLIC_TECHNOLOGY_PARSER_H__
class QString;
# include "crlcore/XmlParser.h"
namespace Hurricane {
class DataBase;
class Technology;
class Layer;
class BasicLayer;
}
namespace CRL {
using namespace std;
using Hurricane::Name;
using Hurricane::DataBase;
using Hurricane::Technology;
using Hurricane::Layer;
using Hurricane::BasicLayer;
class SymbolicTechnologyParser : public XmlParser {
public:
// Methods.
static SymbolicTechnologyParser* create ( DataBase* db, QXmlStreamReader* reader );
static bool load ( DataBase* db, const string& path );
// Internal - enum.
protected:
enum TagSet { TagsTechnology = 2
, TagsName
, TagsBasicLayer
, TagsBasicLayers
, TagsLayer
, TagsSymbolic
, TagsPrecision
, TagsGridStep
, TagsRules
, TagsRule
, TagSetSize
};
enum RuleType { DoubleValue = (1<<0)
, ValueMask = DoubleValue
, ExtentionCap = (1<<4) | DoubleValue
, ExtentionWidth = (1<<5) | DoubleValue
, Enclosure = (1<<6) | DoubleValue
, MinimumWidth = (1<<7) | DoubleValue
, MinimumSide = (1<<8) | DoubleValue
, InvalidRule = (unsigned int)-1
};
// Internal - Attributes.
static const QString UnnamedRuleError;
static const QString UnnamedBasicLayerError;
static const QString UnnamedSymbolicLayerError;
static const QString UnnamedLayerError;
static const QString InvalidRulePathError;
static const QString MissingValueError;
static const QString UnknownRuleError;
static const QString UndefinedLayerError;
static const QString NotACompositeLayerError;
static const QString NotABasicLayerError;
static const QString LayerOutnumber;
static const QString LayerMissingLayer;
DataBase* _dataBase;
Technology* _technology;
BasicLayer* _basicLayer;
map<const Name,Layer*> _layers;
vector<BasicLayer*> _layerComponents;
// Internal - Constructors.
SymbolicTechnologyParser ( DataBase* db, QXmlStreamReader* reader=NULL );
SymbolicTechnologyParser ( const SymbolicTechnologyParser& );
SymbolicTechnologyParser& operator= ( const SymbolicTechnologyParser& );
// Internal - Methods.
void parseTechnology ();
void parseName ();
void parseBasicLayer ();
void parseRegularLayer ();
void parseDiffusionLayer ();
void parseTransistorLayer ();
void parseViaLayer ();
void parseContactLayer ();
void parseLayer ();
void parseSymbolic ();
void parsePrecision ();
void parseGridStep ();
void parseRules ();
void parseRule ();
unsigned int splitRulePath ( const QString& path
, Layer*& ruleLayer
, BasicLayer*& basicLayer
);
BasicLayer* getBasicLayer ( const QString& name, bool ignoreError );
Layer* getLayer ( const QString& name, bool ignoreError );
virtual void _postLoad ();
virtual const char* _getMessage ( MessageId id );
};
} // End of CRL namespace.
# endif

View File

@ -1,88 +0,0 @@
// -*- C++ -*-
# ifndef __CRL_XML_PARSER_H__
# define __CRL_XML_PARSER_H__
# include <iostream>
# include <vector>
# include <QString>
class QXmlStreamReader;
namespace CRL {
using namespace std;
class XmlParser {
// Internal - Subclass: TagEntry.
protected:
typedef void (XmlParser::* tagParser_t)();
struct TagEntry {
const char* _name;
tagParser_t _parser;
inline TagEntry ( const char* name, tagParser_t parser );
};
// Internal - Subclass: TagTable.
enum BasicTagSet { TagsNoChilds = 0
, TagsStandAlone = 1
};
class TagsTable : public vector<TagEntry> { };
// Internal - MessageId.
enum MessageId { OpenFile = 0 };
// Internal - Attributes.
vector<TagsTable> _tagsTables;
QXmlStreamReader* _reader;
// Internal - Constructors & destructors.
XmlParser ( QXmlStreamReader* reader, size_t tagsTablesSize );
XmlParser ( const XmlParser& );
virtual ~XmlParser ();
XmlParser& operator= ( const XmlParser& );
// Internal - Methods.
void addTagEntry ( int tagSet, const char* tag, tagParser_t tagParser );
void parseTags ( int tagSet );
void parseUnknownTag ();
void parseStandAlone ();
inline void parseNoChilds ();
// const char* readTextAsAscii ();
QString readTextAsString ();
unsigned int readTextAsUInt ();
long readTextAsLong ();
double readTextAsDouble ();
bool _load ( const string& path, bool warnNotFound=true );
virtual void _postLoad () = 0;
virtual const char* _getMessage ( MessageId id ) = 0;
virtual void printError ( const QString& error, ostream& o=cerr );
};
// Inline Functions.
inline XmlParser::TagEntry::TagEntry ( const char* name
, XmlParser::tagParser_t parser
) : _name(name)
, _parser(parser)
{ }
inline void XmlParser::parseNoChilds () { parseTags(TagsNoChilds); }
} // End of CRL namespace.
# endif

View File

@ -0,0 +1,599 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2018-2018, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | G D S I I / Hurricane Interface |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Module : "./gds/GdsDriver.cpp" |
// +-----------------------------------------------------------------+
#include <ctime>
#include <string>
#include <sstream>
#include <fstream>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
#include <vector>
using namespace std;
#include "vlsisapd/configuration/Configuration.h"
#include "hurricane/Warning.h"
#include "hurricane/BasicLayer.h"
#include "hurricane/Horizontal.h"
#include "hurricane/Vertical.h"
#include "hurricane/Diagonal.h"
#include "hurricane/Pad.h"
#include "hurricane/Net.h"
#include "hurricane/Cell.h"
#include "hurricane/Plug.h"
#include "hurricane/Instance.h"
using namespace Hurricane;
#include "crlcore/Utilities.h"
#include "crlcore/NetExtension.h"
#include "crlcore/ToolBox.h"
#include "crlcore/Gds.h"
using namespace CRL;
namespace {
using namespace std;
// -------------------------------------------------------------------
// Class : "::DepthOrder".
class DepthOrder {
private:
typedef map <const Cell*,size_t,Entity::CompareById> CellMap;
typedef pair<const Cell*,size_t> CellDepth;
class CompareDepth {
public:
inline bool operator() ( const CellDepth& lhs, const CellDepth& rhs );
};
public:
DepthOrder ( const Cell* top );
inline const vector<CellDepth>& getCellDepths () const;
private:
size_t computeDepth ( CellMap&, const Cell* );
private:
vector<CellDepth> _cellDepths;
};
inline bool DepthOrder::CompareDepth::operator() ( const CellDepth& lhs, const CellDepth& rhs )
{
if (lhs.second < rhs.second) return true;
if (lhs.second > rhs.second) return false;
return lhs.first->getId() < rhs.first->getId();
}
inline const vector<DepthOrder::CellDepth>& DepthOrder::getCellDepths () const { return _cellDepths; }
DepthOrder::DepthOrder ( const Cell* top )
{
CellMap cellMap;
computeDepth( cellMap, top );
for ( auto element : cellMap ) _cellDepths.push_back( element );
sort( _cellDepths.begin(), _cellDepths.end(), CompareDepth() );
}
size_t DepthOrder::computeDepth ( CellMap& cellMap, const Cell* cell )
{
auto ielement = cellMap.find( cell );
if (ielement != cellMap.end()) return (*ielement).second;
size_t depth = 0;
for ( const Instance* instance : cell->getInstances() ) {
depth = std::max( depth, computeDepth(cellMap,instance->getMasterCell()) + 1 );
}
cellMap.insert( make_pair(cell,depth) );
return depth;
}
// -------------------------------------------------------------------
// Class : "::GdsRecord".
class GdsRecord {
public:
// Data Types.
static const uint16_t NoData = 0x0000;
static const uint16_t BitArray = 0x0001;
static const uint16_t TwoByteInteger = 0x0002; // Signed, 16 bits.
static const uint16_t FourByteInteger = 0x0003; // Signed, 32 bits.
static const uint16_t FourByteReal = 0x0004; // Unused.
static const uint16_t EightByteReal = 0x0005;
static const uint16_t String = 0x0006;
// Record Types.
static const uint16_t HEADER = 0x0000 | TwoByteInteger;
static const uint16_t BGNLIB = 0x0100 | TwoByteInteger;
static const uint16_t LIBNAME = 0x0200 | String;
static const uint16_t UNITS = 0x0300 | EightByteReal;
static const uint16_t ENDLIB = 0x0400 | NoData;
static const uint16_t BGNSTR = 0x0500 | TwoByteInteger;
static const uint16_t STRNAME = 0x0600 | String;
static const uint16_t ENDSTR = 0x0700 | NoData;
static const uint16_t BOUNDARY = 0x0800 | NoData;
static const uint16_t PATH = 0x0900 | NoData;
static const uint16_t SREF = 0x0a00 | NoData;
static const uint16_t AREF = 0x0b00 | NoData;
static const uint16_t TEXT = 0x0c00 | NoData;
static const uint16_t LAYER = 0x0d00 | TwoByteInteger;
static const uint16_t DATATYPE = 0x0e00 | TwoByteInteger;
static const uint16_t WIDTH = 0x0f00 | FourByteInteger;
static const uint16_t XY = 0x1000 | FourByteInteger;
static const uint16_t ENDEL = 0x1100 | NoData;
static const uint16_t SNAME = 0x1200 | String;
static const uint16_t COLROW = 0x1300 | TwoByteInteger;
static const uint16_t TEXTNODE = 0x1400 | NoData; // Unused.
static const uint16_t NODE = 0x1500 | NoData;
static const uint16_t TEXTTYPE = 0x1600 | TwoByteInteger;
static const uint16_t PRESENTATION = 0x1700 | BitArray;
static const uint16_t SPACING = 0x1800 | NoData; // Discontinued.
static const uint16_t STRING = 0x1900 | String;
static const uint16_t STRANS = 0x1a00 | BitArray;
static const uint16_t MAG = 0x1b00 | EightByteReal;
static const uint16_t ANGLE = 0x1c00 | EightByteReal;
static const uint16_t REFLIBS = 0x1f00 | String;
static const uint16_t FONTS = 0x2000 | String;
static const uint16_t PATHTYPE = 0x2100 | TwoByteInteger;
static const uint16_t GENERATIONS = 0x2200 | TwoByteInteger;
static const uint16_t ATTRTABLE = 0x2300 | String;
static const uint16_t STYPTABLE = 0x2400 | String; // Unreleased.
static const uint16_t STRTYPE = 0x2500 | TwoByteInteger; // Unreleased.
static const uint16_t ELFLAGS = 0x2600 | BitArray;
static const uint16_t ELKEY = 0x2700 | FourByteInteger; // Unreleased.
static const uint16_t LINKTYPE = 0x2800 | TwoByteInteger; // Unreleased.
static const uint16_t LINKKEYS = 0x2900 | FourByteInteger; // Unreleased.
static const uint16_t NODETYPE = 0x2a00 | TwoByteInteger;
static const uint16_t PROPATTR = 0x2b00 | TwoByteInteger;
static const uint16_t PROPVALUE = 0x2c00 | String;
static const uint16_t BOX = 0x2d00 | NoData;
static const uint16_t BOXTYPE = 0x2e00 | TwoByteInteger;
static const uint16_t PLEX = 0x2f00 | FourByteInteger;
static const uint16_t BGNEXTN = 0x3000 | FourByteInteger; // CustomPlus.
static const uint16_t ENDEXTN = 0x3100 | FourByteInteger; // CustomPlus.
static const uint16_t TAPENUM = 0x3200 | TwoByteInteger;
static const uint16_t TAPECODE = 0x3300 | TwoByteInteger;
static const uint16_t STRCLASS = 0x3400 | BitArray; // CustomPlus.
static const uint16_t RESERVED = 0x3500 | FourByteInteger; // Future use.
static const uint16_t FORMAT = 0x3600 | TwoByteInteger;
static const uint16_t MASK = 0x3700 | String; // Filtered format.
static const uint16_t ENDMASKS = 0x3800 | NoData; // Filtered format.
static const uint16_t LIBDIRSIZE = 0x3900 | TwoByteInteger;
static const uint16_t SRFNAME = 0x3a00 | String;
static const uint16_t LIBSECUR = 0x3b00 | TwoByteInteger;
public:
GdsRecord ( uint16_t type );
GdsRecord ( uint16_t type, int16_t );
GdsRecord ( uint16_t type, int32_t );
GdsRecord ( uint16_t type, string );
inline uint16_t getType () const;
void toStream ( ostream& ) const;
void push ( uint16_t );
void push ( int16_t );
void push ( int32_t );
void push ( string );
void push ( double );
private:
vector<char> _bytes;
};
inline uint16_t GdsRecord::getType () const { return (_bytes[0]<<8) + _bytes[1]; }
GdsRecord::GdsRecord ( uint16_t type )
: _bytes()
{
push( type );
}
GdsRecord::GdsRecord ( uint16_t type, int16_t value )
: _bytes()
{
push( type );
push( value );
}
GdsRecord::GdsRecord ( uint16_t type, int32_t value )
: _bytes()
{
push( type );
push( value );
}
GdsRecord::GdsRecord ( uint16_t type, string s )
: _bytes()
{
push( type );
push( s );
}
void GdsRecord::push ( uint16_t i )
{
const unsigned char* bytearray = reinterpret_cast<const unsigned char*>( &i );
_bytes.push_back( bytearray[1] );
_bytes.push_back( bytearray[0] );
}
void GdsRecord::push ( int16_t i )
{
const unsigned char* bytearray = reinterpret_cast<const unsigned char*>( &i );
_bytes.push_back( bytearray[1] );
_bytes.push_back( bytearray[0] );
}
void GdsRecord::push ( int32_t i )
{
const unsigned char* bytearray = reinterpret_cast<const unsigned char*>( &i );
_bytes.push_back( bytearray[3] );
_bytes.push_back( bytearray[2] );
_bytes.push_back( bytearray[1] );
_bytes.push_back( bytearray[0] );
}
void GdsRecord::push ( string s )
{
for ( size_t i=0 ; i<s.size() ; ++i ) _bytes.push_back( s[i] );
if (s.size()%2) _bytes.push_back( (char)0 );
}
void GdsRecord::push ( double d )
{
size_t end = _bytes.size();
_bytes.insert( _bytes.end(), 8, (char)0 );
_bytes[end] = 0;
if (d < 0) {
_bytes[end] = char (0x80);
d = -d;
}
// compute the next power of 16 that that value will fit in
int e = 0;
if (d < 1e-77 /*~16^-64*/) {
d = 0;
} else {
double log16 = log(d) / log(16.0);
e = int( ceil(log(d) / log(16.0)) );
if (e == log16) ++e;
}
d /= pow( 16.0, e-14 );
//tl_assert (e >= -64 && e < 64);
_bytes[end] |= ((e + 64) & 0x7f);
uint64_t m = uint64_t(d + 0.5);
for ( int i=7 ; i>0 ; --i ) {
_bytes[end+i] = (m & 0xff);
m >>= 8;
}
}
void GdsRecord::toStream ( ostream& stream ) const
{
uint16_t length = (uint16_t)( _bytes.size()+2 );
const unsigned char* bytearray = reinterpret_cast<const unsigned char*>( &length );
// Little endian (x86).
stream.put( bytearray[1] );
stream.put( bytearray[0] );
for ( char byte : _bytes ) stream.put( byte );
}
ostream& operator<< ( ostream& o, const GdsRecord& r ) { r .toStream( o ); return o; }
ostream& operator<< ( ostream& o, const GdsRecord* r ) { r->toStream( o ); return o; }
// -------------------------------------------------------------------
// Class : "::GdsStream".
class GdsStream {
public:
static const GdsRecord BOUNDARY;
static const GdsRecord ENDLIB;
static const GdsRecord ENDEL;
static const GdsRecord ENDSTR;
static const GdsRecord SREF;
public:
GdsStream ( string filename );
~GdsStream ();
static inline GdsRecord PROPATTR ( int16_t );
static inline GdsRecord DATATYPE ( int16_t );
static inline GdsRecord PROPVALUE ( string );
static inline GdsRecord STRNAME ( string );
static inline GdsRecord STRNAME ( const Name& );
static inline GdsRecord SNAME ( string );
static inline GdsRecord SNAME ( const Name& );
GdsStream& operator<< ( const GdsRecord& );
GdsStream& operator<< ( const BasicLayer* );
GdsStream& operator<< ( const Box& );
GdsStream& operator<< ( const Points );
GdsStream& operator<< ( const Cell* );
GdsStream& operator<< ( const Transformation& );
private:
ofstream _ostream;
};
const GdsRecord GdsStream::BOUNDARY = GdsRecord(GdsRecord::BOUNDARY);
const GdsRecord GdsStream::ENDLIB = GdsRecord(GdsRecord::ENDLIB);
const GdsRecord GdsStream::ENDEL = GdsRecord(GdsRecord::ENDEL);
const GdsRecord GdsStream::ENDSTR = GdsRecord(GdsRecord::ENDSTR);
const GdsRecord GdsStream::SREF = GdsRecord(GdsRecord::SREF);
inline GdsRecord GdsStream::PROPATTR ( int16_t v ) { return GdsRecord(GdsRecord::PROPATTR,v); }
inline GdsRecord GdsStream::DATATYPE ( int16_t v ) { return GdsRecord(GdsRecord::DATATYPE,v); }
inline GdsRecord GdsStream::PROPVALUE ( string s ) { return GdsRecord(GdsRecord::PROPVALUE,s); }
inline GdsRecord GdsStream::STRNAME ( string s ) { return GdsRecord(GdsRecord::STRNAME,s); }
inline GdsRecord GdsStream::STRNAME ( const Name& n ) { return GdsRecord(GdsRecord::STRNAME,getString(n)); }
inline GdsRecord GdsStream::SNAME ( string s ) { return GdsRecord(GdsRecord::SNAME,s); }
inline GdsRecord GdsStream::SNAME ( const Name& n ) { return GdsRecord(GdsRecord::SNAME,getString(n)); }
GdsStream::GdsStream ( string filename )
: _ostream()
{
_ostream.open( filename, ios_base::out );
GdsRecord record ( GdsRecord::HEADER );
record.push( (uint16_t)600 );
_ostream << record;
time_t t = time( 0 );
tm* now = localtime( &t );
record = GdsRecord( GdsRecord::BGNLIB );
// Last modification time.
record.push( now->tm_year+1900 );
record.push( now->tm_mon );
record.push( now->tm_mday );
record.push( now->tm_hour );
record.push( now->tm_sec );
// Last access time.
record.push( now->tm_year+1900 );
record.push( now->tm_mon );
record.push( now->tm_mday );
record.push( now->tm_hour );
record.push( now->tm_sec );
_ostream << record;
// Generate a GDSII which coordinates are relatives to the um.
double gridPerUu = 10e-6 / DbU::getPhysicalsPerGrid();
record = GdsRecord( GdsRecord::UNITS );
record.push( gridPerUu );
record.push( DbU::getPhysicalsPerGrid() );
_ostream << record;
}
GdsStream::~GdsStream ()
{
_ostream << ENDLIB;
_ostream.close();
}
GdsStream& GdsStream::operator<< ( const GdsRecord& record )
{ _ostream << record; return *this; }
GdsStream& GdsStream::operator<< ( const BasicLayer* layer )
{
GdsRecord record ( GdsRecord::LAYER );
record.push( (int16_t)layer->getGds2Layer() );
_ostream << record;
record = GdsRecord( GdsRecord::DATATYPE );
record.push( (int16_t)layer->getGds2Datatype() );
_ostream << record;
return *this;
}
GdsStream& GdsStream::operator<< ( const Transformation& transf )
{
const uint16_t f_reflexion = (1 << 15);
GdsRecord record ( GdsRecord::STRANS );
uint16_t flags = 0;
double angle = 0.0;
if (transf.getOrientation() != Transformation::Orientation::ID) {
switch ( transf.getOrientation() ) {
case Transformation::Orientation::ID:
break;
case Transformation::Orientation::R1:
angle = 90.0;
break;
case Transformation::Orientation::R2:
angle = 180.0;
break;
case Transformation::Orientation::R3:
angle = 270.0;
break;
case Transformation::Orientation::MX:
flags |= f_reflexion;
angle = -180.0;
break;
case Transformation::Orientation::XR:
flags |= f_reflexion;
angle = -90.0;
break;
case Transformation::Orientation::MY:
flags |= f_reflexion;
break;
case Transformation::Orientation::YR:
flags |= f_reflexion;
angle = 90.0;
break;
}
}
record.push( flags );
_ostream << record;
if (angle != 0.0) {
record = GdsRecord( GdsRecord::ANGLE );
record.push( angle );
_ostream << record;
}
record = GdsRecord( GdsRecord::XY );
record.push( (int32_t)DbU::toGrid(transf.getTx()) );
record.push( (int32_t)DbU::toGrid(transf.getTy()) );
_ostream << record;
return *this;
}
GdsStream& GdsStream::operator<< ( const Box& box )
{
GdsRecord record ( GdsRecord::XY );
for ( size_t i=0 ; i<5 ; ++i ) {
Point p;
switch ( i%4 ) {
case 0: p = Point( box.getXMin(), box.getYMin() ); break;
case 1: p = Point( box.getXMin(), box.getYMax() ); break;
case 2: p = Point( box.getXMax(), box.getYMax() ); break;
case 3: p = Point( box.getXMax(), box.getYMin() ); break;
}
record.push( (int32_t)DbU::toGrid(p.getX()) );
record.push( (int32_t)DbU::toGrid(p.getY()) );
}
_ostream << record;
return *this;
}
GdsStream& GdsStream::operator<< ( Points points )
{
GdsRecord record ( GdsRecord::XY );
Point first = points.getFirst();
for ( Point p : points ) {
record.push( (int32_t)DbU::toGrid(p.getX()) );
record.push( (int32_t)DbU::toGrid(p.getY()) );
}
record.push( (int32_t)DbU::toGrid(first.getX()) );
record.push( (int32_t)DbU::toGrid(first.getY()) );
_ostream << record;
return *this;
}
GdsStream& GdsStream::operator<< ( const Cell* cell )
{
time_t t = time( 0 );
tm* now = localtime( &t );
GdsRecord record ( GdsRecord::BGNSTR );
// Last modification time.
record.push( now->tm_year+1900 );
record.push( now->tm_mon );
record.push( now->tm_mday);
record.push( now->tm_hour);
record.push( now->tm_sec );
// Last access time.
record.push( now->tm_year+1900 );
record.push( now->tm_mon );
record.push( now->tm_mday);
record.push( now->tm_hour);
record.push( now->tm_sec );
_ostream << record;
_ostream << STRNAME(cell->getName());
for ( Instance* instance : cell->getInstances() ) {
if (instance->getPlacementStatus() == Instance::PlacementStatus::UNPLACED) continue;
(*this) << SREF;
(*this) << SNAME( instance->getMasterCell()->getName() );
(*this) << instance->getTransformation();
(*this) << ENDEL;
}
for ( Net* net : cell->getNets() ) {
for ( Component* component : net->getComponents() ) {
Diagonal* diagonal = dynamic_cast<Diagonal*>(component);
if (diagonal) {
for ( const BasicLayer* layer : component->getLayer()->getBasicLayers() ) {
(*this) << BOUNDARY;
(*this) << layer;
(*this) << diagonal->getContour();
(*this) << ENDEL;
}
} else if ( dynamic_cast<Horizontal*>(component)
or dynamic_cast<Vertical *>(component)
or dynamic_cast<Contact *>(component)
or dynamic_cast<Pad *>(component)) {
for ( const BasicLayer* layer : component->getLayer()->getBasicLayers() ) {
(*this) << BOUNDARY;
(*this) << layer;
(*this) << component->getBoundingBox(layer);
(*this) << ENDEL;
}
}
}
}
(*this) << ENDSTR;
return *this;
}
} // Anonymous namespace.
namespace CRL {
// -------------------------------------------------------------------
// Class : "CRL::Gds".
bool Gds::save ( Cell* cell )
{
string cellFile = getString(cell->getName()) + ".gds";
GdsStream gstream ( cellFile );
DepthOrder cellOrder ( cell );
for ( auto element : cellOrder.getCellDepths() ) gstream << element.first;
return true;
}
} // CRL namespace.

View File

@ -22,9 +22,6 @@
#include "crlcore/PyRoutingGauge.h"
#include "crlcore/PyAllianceLibrary.h"
#include "crlcore/PyAllianceFramework.h"
#include "crlcore/GraphicsParser.h"
#include "crlcore/SymbolicTechnologyParser.h"
#include "crlcore/RealTechnologyParser.h"
namespace CRL {
@ -323,6 +320,23 @@ extern "C" {
}
static PyObject* PyAllianceFramework_isInCatalog ( PyAllianceFramework* self, PyObject* args )
{
cdebug_log(30,0) << "PyAllianceFramework_isInCatalog ()" << endl;
char* name = NULL;
HTRY
METHOD_HEAD("AllianceFramework.isInCatalog()")
if ( not PyArg_ParseTuple(args,"s",&name) ) {
PyErr_SetString( ConstructorError, "AllianceFramework.isInCatalog(): Invalid number or bad type of parameters.");
return NULL;
}
if (af->isInCatalog(Name(name))) Py_RETURN_TRUE;
HCATCH
Py_RETURN_FALSE;
}
static PyObject* PyAllianceFramework_addRoutingGauge ( PyAllianceFramework* self, PyObject* args )
{
cdebug_log(30,0) << "PyAllianceFramework_addRoutingGauge ()" << endl;
@ -485,6 +499,8 @@ extern "C" {
, "Load in memory all Cells from an Alliance Library." }
, { "isPad" , (PyCFunction)PyAllianceFramework_isPad , METH_VARARGS
, "Tells if a cell name is a Pad." }
, { "isInCatalog" , (PyCFunction)PyAllianceFramework_isInCatalog , METH_VARARGS
, "Tells if a cell name is referenced in the Catalog." }
, { "addCellGauge" , (PyCFunction)PyAllianceFramework_addCellGauge , METH_VARARGS
, "Add a new cell gauge." }
, { "getCellGauge" , (PyCFunction)PyAllianceFramework_getCellGauge , METH_VARARGS

View File

@ -167,7 +167,8 @@ namespace Hurricane {
BasicLayer::BasicLayer ( Technology* technology
, const Name& name
, const Material& material
, unsigned extractNumber
, unsigned gds2Layer
, unsigned gds2Datatype
, const DbU::Unit& minimalSize
, const DbU::Unit& minimalSpacing
) : Layer(technology
@ -175,7 +176,8 @@ namespace Hurricane {
,minimalSize
,minimalSpacing)
,_material (material)
,_extractNumber (extractNumber)
,_gds2Layer (gds2Layer)
,_gds2Datatype (gds2Datatype)
,_blockageLayer (NULL)
,_realName ("<not associated>")
{ }
@ -184,13 +186,14 @@ namespace Hurricane {
BasicLayer* BasicLayer::create ( Technology* technology
, const Name& name
, const Material& material
, unsigned extractNumber
, unsigned gds2Layer
, unsigned gds2Datatype
, const DbU::Unit& minimalSize
, const DbU::Unit& minimalSpacing
)
{
BasicLayer* basicLayer =
new BasicLayer(technology, name, material, extractNumber, minimalSize, minimalSpacing);
new BasicLayer(technology, name, material, gds2Layer, gds2Datatype, minimalSize, minimalSpacing);
basicLayer->_postCreate();
@ -223,8 +226,8 @@ namespace Hurricane {
if ( _material == Material::metal ) getTechnology()->_getMetalMask().set(getMask());
if ( _material == Material::cut ) getTechnology()->_getCutMask ().set(getMask());
if (_extractNumber) {
Mask extractMask = (1 << _extractNumber);
if (_gds2Layer) {
Mask extractMask = (1 << _gds2Layer);
if (!extractMask)
throw Error("Can't create " + _TName("BasicLayer") + " : extract mask capacity overflow");
@ -267,6 +270,8 @@ namespace Hurricane {
record->add(getSlot("_material" , &_material));
record->add(getSlot("_realName" , &_realName));
record->add(getSlot("_blockageLayer", _blockageLayer));
record->add(getSlot("_gds2Layer" , _gds2Layer));
record->add(getSlot("_gds2Datatype" , _gds2Datatype));
}
return record;
}
@ -277,7 +282,8 @@ namespace Hurricane {
Super::_toJson( writer );
jsonWrite( writer, "_material" , getString(&_material) );
jsonWrite( writer, "_extractNumber", _extractNumber );
jsonWrite( writer, "_gds2Layer" , _gds2Layer );
jsonWrite( writer, "_gds2Datatype" , _gds2Datatype );
jsonWrite( writer, "_realName" , _realName );
if (_blockageLayer) {
jsonWrite( writer, "_blockageLayer", _blockageLayer->getName() );
@ -354,10 +360,11 @@ namespace Hurricane {
cdebug_log(19,0) << "JsonBasicLayer::JsonBasicLayer()" << endl;
add( "_material" , typeid(string) );
add( "_extractNumber", typeid(string) );
add( "_blockageLayer", typeid(string) );
add( "_realName" , typeid(string) );
add( "_material" , typeid(string) );
add( "_gds2Layer" , typeid(int64_t) );
add( "_gds2Datatype" , typeid(int64_t) );
add( "_blockageLayer", typeid(string) );
add( "_realName" , typeid(string) );
}
@ -389,7 +396,8 @@ namespace Hurricane {
DbU::Unit minimalSpacing = get<int64_t>( stack, "_minimalSpacing" );
bool isSymbolic = get<bool> ( stack, "_symbolic" );
string materialName = get<string> ( stack, "_material" );
unsigned int extractNumber = get<int64_t>( stack, "_extractNumber" );
unsigned int gds2Layer = get<int64_t>( stack, "_gds2Layer" );
unsigned int gds2Datatype = get<int64_t>( stack, "_gds2Datatype" );
string blockageLayer = get<string> ( stack, "_blockageLayer" );
string realName = get<string> ( stack, "_realName" );
@ -401,7 +409,8 @@ namespace Hurricane {
basicLayer = BasicLayer::create( techno
, name
, material
, extractNumber
, gds2Layer
, gds2Datatype
, minimalSize
, minimalSpacing
);

View File

@ -83,19 +83,22 @@ namespace Hurricane {
static BasicLayer* create ( Technology* technology
, const Name& name
, const Material& material
, unsigned extractNumber
, unsigned gds2Layer
, unsigned gds2Datatype
, const DbU::Unit& minimalSize = 0
, const DbU::Unit& minimalSpacing = 0
);
// Accessors.
inline const Material& getMaterial () const;
inline unsigned getExtractNumber () const;
inline unsigned getGds2Layer () const;
inline unsigned getGds2Datatype () const;
virtual BasicLayers getBasicLayers () const;
virtual BasicLayer* getBlockageLayer () const;
inline const Name& getRealName () const;
// Updators
inline void setBlockageLayer ( BasicLayer* layer);
inline void setExtractNumber ( unsigned int );
inline void setGds2Layer ( unsigned int );
inline void setGds2Datatype ( unsigned int );
inline void setRealName ( const char* realName);
// Hurricane Managment.
virtual void _toJson ( JsonWriter* writer ) const;
@ -107,7 +110,8 @@ namespace Hurricane {
private:
// Internal: Attributes
Material _material;
unsigned _extractNumber;
unsigned _gds2Layer;
unsigned _gds2Datatype;
BasicLayer* _blockageLayer;
Name _realName;
@ -116,7 +120,8 @@ namespace Hurricane {
BasicLayer ( Technology* technology
, const Name& name
, const Material& material
, unsigned extractNumber
, unsigned gds2Layer
, unsigned gds2Datatype
, const DbU::Unit& minimalSize = 0
, const DbU::Unit& minimalSpacing = 0
);
@ -132,10 +137,12 @@ namespace Hurricane {
inline string BasicLayer::Material::_getTypeName () const { return _TName("BasicLayer::Material"); }
inline const BasicLayer::Material&
BasicLayer::getMaterial () const { return _material; }
inline unsigned BasicLayer::getExtractNumber () const { return _extractNumber; }
inline unsigned BasicLayer::getGds2Layer () const { return _gds2Layer; }
inline unsigned BasicLayer::getGds2Datatype () const { return _gds2Datatype; }
inline const Name& BasicLayer::getRealName () const { return _realName; }
inline void BasicLayer::setBlockageLayer ( BasicLayer* layer) { _blockageLayer = layer; }
inline void BasicLayer::setExtractNumber ( unsigned int number ) { _extractNumber=number; }
inline void BasicLayer::setGds2Layer ( unsigned int number ) { _gds2Layer=number; }
inline void BasicLayer::setGds2Datatype ( unsigned int number ) { _gds2Datatype=number; }
inline void BasicLayer::setRealName ( const char* realName) { _realName = realName; }

View File

@ -55,16 +55,18 @@ extern "C" {
PyObject* pyTechnology = NULL;
char* name = NULL;
PyObject* pyMaterial = NULL;
unsigned int extractNumber = 0;
unsigned int gds2Layer = 0;
unsigned int gds2Datatype = 0;
PyObject* pyMinimalSize = NULL;
PyObject* pyMinimalSpacing = NULL;
if (PyArg_ParseTuple( args
, "OsO|IOO:BasicLayer.create"
, "OsO|IIOO:BasicLayer.create"
, &pyTechnology
, &name
, &pyMaterial
, &extractNumber
, &gds2Layer
, &gds2Datatype
, &pyMinimalSize
, &pyMinimalSpacing
)) {
@ -80,7 +82,8 @@ extern "C" {
basicLayer = BasicLayer::create( PYTECHNOLOGY_O(pyTechnology)
, Name(name)
, *PYMATERIAL_O(pyMaterial)
, extractNumber
, gds2Layer
, gds2Datatype
, (pyMinimalSize) ? PyAny_AsLong(pyMinimalSize) : 0
, (pyMinimalSpacing) ? PyAny_AsLong(pyMinimalSpacing) : 0
);
@ -110,8 +113,9 @@ extern "C" {
updatorFromBasicLayer (setBlockageLayer,PyBasicLayer,BasicLayer)
accessorLayerFromVoid (getBlockageLayer,PyBasicLayer,BasicLayer)
DirectSetLongAttribute (PyBasicLayer_setExtractNumber,setExtractNumber,PyBasicLayer,BasicLayer)
DirectSetCStringAttribute(PyBasicLayer_setRealName ,setRealName ,PyBasicLayer,BasicLayer)
DirectSetLongAttribute (PyBasicLayer_setGds2Layer ,setGds2Layer ,PyBasicLayer,BasicLayer)
DirectSetLongAttribute (PyBasicLayer_setGds2Datatype,setGds2Datatype,PyBasicLayer,BasicLayer)
DirectSetCStringAttribute(PyBasicLayer_setRealName ,setRealName ,PyBasicLayer,BasicLayer)
// Standart destroy (Attribute).
@ -130,8 +134,10 @@ extern "C" {
, "Returns the associated blockage layer, if any." }
, { "setBlockageLayer" , (PyCFunction)PyBasicLayer_setBlockageLayer , METH_VARARGS
, "Sets the blockage layer associated to this one." }
, { "setExtractNumber" , (PyCFunction)PyBasicLayer_setExtractNumber , METH_VARARGS
, "Sets the layer extract number (for GDSII)." }
, { "setGds2Layer" , (PyCFunction)PyBasicLayer_setGds2Layer , METH_VARARGS
, "Sets the GDSII layer number." }
, { "setGds2Datatype" , (PyCFunction)PyBasicLayer_setGds2Datatype , METH_VARARGS
, "Sets the GDSII layer Datatype." }
, { "setRealName" , (PyCFunction)PyBasicLayer_setRealName , METH_VARARGS
, "Sets the real name of this layer (as seen in GDSII)." }
, { "destroy" , (PyCFunction)PyBasicLayer_destroy , METH_NOARGS

View File

@ -78,9 +78,9 @@ namespace Unicorn {
formatLabel->setFont ( Graphics::getNormalFont(true) );
hLayout2->addWidget ( formatLabel );
_formatComboBox->addItem ( tr("JSON (experimental)") , Json );
_formatComboBox->addItem ( tr("GDSII") , Gds );
_formatComboBox->addItem ( tr("Alliance compliant DEF"), AllianceDef );
_formatComboBox->addItem ( tr("ASCII/GDSII (AGDS)") , AsciiGds );
_formatComboBox->addItem ( tr("JSON (experimental)") , Json );
hLayout2->addWidget ( _formatComboBox );
QVBoxLayout* vLayout = new QVBoxLayout ();

View File

@ -1,26 +1,17 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved
// Copyright (c) UPMC 2008-2018, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | U n i c o r n - M a i n G U I |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./SaveCellDialog.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
// +-----------------------------------------------------------------+
#include <iostream>

View File

@ -31,12 +31,12 @@
#include "crlcore/AcmSigda.h"
#include "crlcore/Ispd04Bookshelf.h"
#include "crlcore/Ispd05Bookshelf.h"
#include "crlcore/Gds.h"
#include "crlcore/Blif.h"
#include "crlcore/Iccad04Lefdef.h"
#include "crlcore/LefImport.h"
#include "crlcore/DefImport.h"
#include "crlcore/DefExport.h"
#include "crlcore/GdsDriver.h"
#include "unicorn/ImportCell.h"
#include "unicorn/OpenCellDialog.h"
#include "unicorn/SaveCellDialog.h"
@ -61,12 +61,12 @@ namespace Unicorn {
using CRL::AcmSigda;
using CRL::Ispd04;
using CRL::Ispd05;
using CRL::Gds;
using CRL::Blif;
using CRL::Iccad04Lefdef;
using CRL::LefImport;
using CRL::DefImport;
using CRL::DefExport;
using CRL::GdsDriver;
// -------------------------------------------------------------------
@ -298,10 +298,8 @@ namespace Unicorn {
case ExportCellDialog::AllianceDef:
DefExport::drive ( cell, DefExport::WithLEF );
break;
case ExportCellDialog::AsciiGds:
{ GdsDriver gdsDriver ( cell );
gdsDriver.save( getString(cell->getName())+".agds" );
}
case ExportCellDialog::Gds:
Gds::save( cell );
break;
case ExportCellDialog::Json:
{ //DebugSession::open( 19, 20 );

View File

@ -31,7 +31,7 @@ namespace Unicorn {
Q_OBJECT;
public:
enum Formats { AllianceDef=1, AsciiGds=2, Json=3 };
enum Formats { AllianceDef=1, Gds=2, Json=3 };
public:
ExportCellDialog ( QWidget* parent=NULL );
bool runDialog ( QString& name, int& format );