// -*- C++ -*- #include #include #include #include #include #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 ."; const QString SymbolicTechnologyParser::UnnamedSymbolicLayerError = "Missing name attribute in <%1>."; const QString SymbolicTechnologyParser::UnnamedLayerError = "Missing name attribute in ."; const QString SymbolicTechnologyParser::InvalidRulePathError = "Invalid rule path \"%1\"."; const QString SymbolicTechnologyParser::MissingValueError = "Rule \"%1\" has no 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)); 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::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::iterator it = _layers.find ( layerName ); if ( it == _layers.end() ) { if ( !ignoreError ) printError ( UndefinedLayerError.arg(name) ); return NULL; } BasicLayer* basicLayer = dynamic_cast ( 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, "" ); 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 = ""; switch ( id ) { case OpenFile: message = "Technology configuration"; break; } return message; } } // End of CRL namespace.