diff --git a/crlcore/etc/vsc200/kite.conf b/crlcore/etc/vsc200/kite.conf index e028661f..d339882f 100644 --- a/crlcore/etc/vsc200/kite.conf +++ b/crlcore/etc/vsc200/kite.conf @@ -26,7 +26,7 @@ parametersTable = \ # Format of routingGaugesTable (dictionary): # A list of entry of the form: # ( METAL_NAME, (Direction, Type, depth, density, offset, pitch, wire_width, via_width) ) - + routingGaugesTable = {} routingGaugesTable['vsclib'] = \ diff --git a/crlcore/etc/vsc200/plugins.conf b/crlcore/etc/vsc200/plugins.conf new file mode 100644 index 00000000..80c68ba5 --- /dev/null +++ b/crlcore/etc/vsc200/plugins.conf @@ -0,0 +1,26 @@ +# -*- Mode:Python; explicit-buffer-name: "plugins.conf" -*- +# +# THIS SETTINGS ARE NOT CORRECT. MUST ADJUST THEM FOR VSC200. + +import helpers + +# Contains the layout (shared by all technologies). +#execfile( helpers.sysConfDir+'/common/plugins.conf' ) + + +# Parameters for chip plugin. +parametersTable = \ + ( ("chip.block.rails.count" , TypeInt , 5 ) + , ("chip.block.rails.hWidth" , TypeInt , 12 ) + , ("chip.block.rails.vWidth" , TypeInt , 12 ) + , ("chip.block.rails.hSpacing" , TypeInt , 6 ) + , ("chip.block.rails.vSpacing" , TypeInt , 6 ) + , ('chip.pad.pck' , TypeString, 'pck_px') + , ('chip.pad.pvddick' , TypeString, 'pvddick_px') + , ('chip.pad.pvssick' , TypeString, 'pvssick_px') + , ('chip.pad.pvddeck' , TypeString, 'pvddeck_px') + , ('chip.pad.pvsseck' , TypeString, 'pvsseck_px') + , ('clockTree.minimumSide' , TypeInt , 300) + , ('clockTree.buffer' , TypeString, 'buf_x2') + , ('clockTree.placerEngine' , TypeString, 'Etesian') + ) diff --git a/crlcore/python/coriolisInit.py b/crlcore/python/coriolisInit.py index 31e947db..0cc65a0c 100644 --- a/crlcore/python/coriolisInit.py +++ b/crlcore/python/coriolisInit.py @@ -103,6 +103,7 @@ def coriolisConfigure(): confFiles = [ (helpers.symbolicDir+'/alliance.conf' , SystemFile|AllianceHelper) , (helpers.symbolicDir+'/technology.conf', SystemFile|SymbolicHelper) + , (helpers.realDir +'/technology.conf', SystemFile|RealHelper) , (helpers.symbolicDir+'/patterns.conf' , SystemFile|PatternsHelper) , (helpers.symbolicDir+'/display.conf' , SystemFile|DisplayHelper) , (helpers.symbolicDir+'/misc.conf' , SystemFile|ConfigurationHelper) @@ -110,7 +111,6 @@ def coriolisConfigure(): , (helpers.symbolicDir+'/kite.conf' , SystemFile|ConfigurationHelper|KiteHelper) , (helpers.symbolicDir+'/stratus1.conf' , SystemFile|ConfigurationHelper) , (helpers.symbolicDir+'/plugins.conf' , SystemFile|ConfigurationHelper) - , (helpers.realDir +'/technology.conf', SystemFile|RealHelper) ] if os.getenv('HOME'): confFiles += [ (os.getenv('HOME')+'/.coriolis2/settings.py', 0) ] diff --git a/crlcore/src/ccore/CMakeLists.txt b/crlcore/src/ccore/CMakeLists.txt index 44e2de57..44e1913a 100644 --- a/crlcore/src/ccore/CMakeLists.txt +++ b/crlcore/src/ccore/CMakeLists.txt @@ -128,6 +128,7 @@ toolbox/ToolBox.cpp toolbox/UniqueCellOccurrences.cpp toolbox/RoutingPads.cpp + toolbox/NamingScheme.cpp ) set ( vst_driver_cpps alliance/vst/VstDriver.cpp ) set ( properties_cpps properties/NetExtension.cpp diff --git a/crlcore/src/ccore/acmsigda/AcmSigdaParserGrammar.yy b/crlcore/src/ccore/acmsigda/AcmSigdaParserGrammar.yy index f57deefc..a1912e33 100644 --- a/crlcore/src/ccore/acmsigda/AcmSigdaParserGrammar.yy +++ b/crlcore/src/ccore/acmsigda/AcmSigdaParserGrammar.yy @@ -335,6 +335,11 @@ namespace CRL { __framework->loadLibraryCells ( "sxlib" ); } + IoFile ccell ( benchmark+".bench" ); + ccell.open ( "r" ); + if (not ccell.isOpen()) + throw Error( "AcmSigda::load(): Unable to open file %s.bench.", benchmark.c_str() ); + Cell* cell = __framework->createCell ( benchmark ); CatalogProperty *sprop = @@ -349,8 +354,6 @@ namespace CRL { addGlobalNets ( cell ); - IoFile ccell ( benchmark+".bench" ); - ccell.open ( "r" ); yyin = ccell.getFile (); if ( not firstCall ) yyrestart ( yyin ); diff --git a/crlcore/src/ccore/alliance/vst/VstDriver.cpp b/crlcore/src/ccore/alliance/vst/VstDriver.cpp index e577bbc0..8ef6fea8 100644 --- a/crlcore/src/ccore/alliance/vst/VstDriver.cpp +++ b/crlcore/src/ccore/alliance/vst/VstDriver.cpp @@ -118,7 +118,7 @@ struct StringSort return (*string1 < *string2); if ((string1->find('(', string1OpenPar + 1) != string::npos) || (string2->find('(', string2OpenPar + 1) != string::npos)) - throw Error("malformed string, multi '('"); + throw Error("malformed string, multi '(' in <%s>", string2->c_str()); string::size_type string1ClosePar = string1->rfind(')'); string::size_type string2ClosePar = string2->rfind(')'); if ((string1ClosePar == string::npos) || (string2ClosePar == string::npos)) diff --git a/crlcore/src/ccore/blif/BlifParser.cpp b/crlcore/src/ccore/blif/BlifParser.cpp index 96512d35..aa653cf7 100644 --- a/crlcore/src/ccore/blif/BlifParser.cpp +++ b/crlcore/src/ccore/blif/BlifParser.cpp @@ -21,18 +21,19 @@ #include using namespace std; -#include "hurricane/Warning.h" -#include "hurricane/Net.h" -#include "hurricane/Cell.h" -#include "hurricane/Plug.h" -#include "hurricane/Instance.h" -#include "hurricane/UpdateSession.h" +#include "hurricane/Warning.h" +#include "hurricane/Net.h" +#include "hurricane/Cell.h" +#include "hurricane/Plug.h" +#include "hurricane/Instance.h" +#include "hurricane/UpdateSession.h" using namespace Hurricane; #include "crlcore/Utilities.h" #include "crlcore/Catalog.h" #include "crlcore/AllianceFramework.h" #include "crlcore/NetExtension.h" +#include "crlcore/ToolBox.h" #include "crlcore/Blif.h" using namespace CRL; @@ -61,16 +62,12 @@ namespace { } Net* vssint = instcell->getNet( "vss" ); Net* vddint = instcell->getNet( "vdd" ); - cerr << "Got instance nets" << endl; Net* vssext = design->getNet( "vss" ); Net* vddext = design->getNet( "vdd" ); - cerr << "Got cell nets" << endl; auto vssplug = instance->getPlug( vssint ); auto vddplug = instance->getPlug( vddint ); - cerr << "Got plugs: " << vssplug << " and " << vddplug << endl; vssplug->setNet( vssext ); vddplug->setNet( vddext ); - cerr << "Updated nets" << endl; } void SetNetType ( Net* net, AllianceFramework * framework ) @@ -142,270 +139,296 @@ namespace CRL { // Ignores all ".names" and uses only the .subckt, .model, .input and .output // -Cell * Blif::load ( string cellPath ) //, Cell *cell ) -{ - using namespace std; + Cell* Blif::load ( string cellPath ) + { + using namespace std; - auto framework = AllianceFramework::get (); - - std::ifstream ccell ( cellPath+".blif" ); - if(ccell.fail()){ - throw Error("Unable to open the file\n"); - } - cmess2 << " " << tab << "+ " << cellPath << " [BLIF]" << endl; - - std::vector models; - ParserState state = EXT; - bool hasName; - - string line; - vector current_names; - while(getline(ccell, line)){ - istringstream linestream(line); - vector tokens = tokenize(line); - if(not tokens.empty()){ - string const token = tokens.back(); - tokens.pop_back(); - assert(not token.empty()); - if(token[0] == '.'){ - // Process finished .names statement - if(not current_names.empty()){ - if( current_names.size() != 4 - or current_names[2] != "1" or current_names[3] != "1" - ){ - ostringstream mess; - mess << ".names statement is not an alias and will be ignored " - << "(map to standard cells for functions and tie cells for constants)\n"; - for(string const & S: current_names){ - mess << S << " "; + Cell* mainModel = NULL; + string mainName; + string blifFile = cellPath; + size_t dot = cellPath.find_first_of('.'); + if (dot != string::npos) { + blifFile = cellPath.substr( 0, dot ); + mainName = cellPath.substr( dot+1 ); + } + + auto framework = AllianceFramework::get (); + + std::ifstream ccell ( blifFile+".blif" ); + if(ccell.fail()){ + throw Error( "Unable to open BLIF file %s.blif\n", blifFile.c_str() ); + } + cmess2 << " " << tab++ << "+ " << blifFile << " [blif]" << endl; + + std::vector models; + ParserState state = EXT; + bool hasName = true; + + string line; + vector current_names; + while(getline(ccell, line)){ + istringstream linestream(line); + vector tokens = tokenize(line); + if(not tokens.empty()){ + string const token = tokens.back(); + tokens.pop_back(); + assert(not token.empty()); + if(token[0] == '.'){ + // Process finished .names statement + if(not current_names.empty()){ + if( current_names.size() != 4 + or current_names[2] != "1" or current_names[3] != "1" + ){ + ostringstream mess; + mess << "\'.names\' statement is not an alias and will be ignored.\n" + << " Map to standard cells for functions and tie cells for constants.\n" + << " "; + for ( size_t iname=0 ; iname(current_names[0], current_names[1])); + } + current_names.clear(); + } + if(token == ".model"){ + if(state != EXT) + throw Error("Nested model are not supported\n"); + state = MODEL; + hasName = false; + models.push_back(model()); + } + else if(token == ".subckt"){ + if(state == EXT) + throw Error("Subcircuit without an enclosing model are not supported\n"); + if(state == MODEL and not hasName) + throw Error("Model has no name\n"); + state = SUBCKT; + hasName = false; + models.back().subcircuits.push_back(subckt()); + } + else if(token == ".names"){ + if(state == EXT) + throw Error("Names without an enclosing model are not supported\n"); + if(state == MODEL and not hasName) + throw Error("Model has no name\n"); + state = NAMES; + } + else if(token == ".latch"){ + throw Error("Latch constructs are not understood by the parser\n"); + } + else if(token == ".inputs"){ + if(state == EXT) + throw Error("Inputs have been found without an enclosing model\n"); + state = INPUTS; + } + else if(token == ".outputs"){ + if(state == EXT) + throw Error("Outputs have been found without an enclosing model\n"); + state = OUTPUTS; + } + else if(token == ".end"){ + if(state == EXT) + throw Error("A .end has been found out of a model\n"); + state = EXT; } else{ - // Name statement is an alias: the second signal will map to the first - models.back().aliases.push_back(pair(current_names[0], current_names[1])); + ostringstream mess; + mess << "Unknown control token <" << token << ">\n"; + throw Error(mess.str()); } - current_names.clear(); + } - if(token == ".model"){ - if(state != EXT) - throw Error("Nested model are not supported\n"); - state = MODEL; - hasName = false; - models.push_back(model()); - } - else if(token == ".subckt"){ - if(state == EXT) - throw Error("Subcircuit without an enclosing model are not supported\n"); - if(state == MODEL and not hasName) - throw Error("Model has no name\n"); - state = SUBCKT; - hasName = false; - models.back().subcircuits.push_back(subckt()); - } - else if(token == ".names"){ - if(state == EXT) - throw Error("Names without an enclosing model are not supported\n"); - if(state == MODEL and not hasName) - throw Error("Model has no name\n"); - state = NAMES; - } - else if(token == ".latch"){ - throw Error("Latch constructs are not understood by the parser\n"); - } - else if(token == ".inputs"){ - if(state == EXT) - throw Error("Inputs have been found without an enclosing model\n"); - state = INPUTS; - } - else if(token == ".outputs"){ - if(state == EXT) - throw Error("Outputs have been found without an enclosing model\n"); - state = OUTPUTS; - } - else if(token == ".end"){ - if(state == EXT) - throw Error("A .end has been found out of a model\n"); - state = EXT; + else if(state == NAMES){ + // Part of a cover for a logic function + current_names.push_back(token); } else{ ostringstream mess; - mess << "Unknown control token <" << token << ">\n"; + mess << "Encountered a non-control token at the beginning of a line: <" << token << ">\n"; throw Error(mess.str()); } - } - else if(state == NAMES){ - // Part of a cover for a logic function - current_names.push_back(token); - } - else{ - ostringstream mess; - mess << "Encountered a non-control token at the beginning of a line: <" << token << ">\n"; - throw Error(mess.str()); - } - } - // Process all tokens after the control - while(not tokens.empty()){ - string const token = tokens.back(); - tokens.pop_back(); - assert(not token.empty()); - // Either a pin or an input/output definition - if(state == INPUTS or state == OUTPUTS){ - auto it = models.back().pins.find(token); - Net::Direction D = (state == INPUTS)? Net::Direction::DirIn : Net::Direction::DirOut; - if(it != models.back().pins.end()){ - it->second = static_cast(D | it->second); - } - else{ - models.back().pins.insert(pair(token, D)); - } - } - else if(state == SUBCKT){ - if(hasName){ - // Encountered a pin: need to be processed - auto equal_pos = token.find_first_of('='); - if(equal_pos+1 < token.size()){ - string before_space = token.substr(0, equal_pos); - string after_space = token.substr(equal_pos+1, string::npos); - models.back().subcircuits.back().pins.push_back(pair(before_space, after_space)); + // Process all tokens after the control + while(not tokens.empty()){ + string const token = tokens.back(); + tokens.pop_back(); + assert(not token.empty()); + // Either a pin or an input/output definition + if(state == INPUTS or state == OUTPUTS){ + auto it = models.back().pins.find(token); + Net::Direction D = (state == INPUTS)? Net::Direction::DirIn : Net::Direction::DirOut; + if(it != models.back().pins.end()){ + it->second = static_cast(D | it->second); } else{ - ostringstream mess; - mess << "Unable to parse the subckt pin specification <" - << token << ">\n"; - Error(mess.str()); + models.back().pins.insert(pair(token, D)); + } + } + else if(state == SUBCKT){ + if(hasName){ + // Encountered a pin: need to be processed + auto equal_pos = token.find_first_of('='); + if(equal_pos+1 < token.size()){ + string before_space = token.substr(0, equal_pos); + string after_space = token.substr(equal_pos+1, string::npos); + models.back().subcircuits.back().pins.push_back(pair(before_space, after_space)); + } + else{ + ostringstream mess; + mess << "Unable to parse the subckt pin specification <" + << token << ">\n"; + Error(mess.str()); + } + } + else{ + models.back().subcircuits.back().cell = token; + hasName = true; + } + } + else if(state == NAMES){ + current_names.push_back(token); + } + else if(state == MODEL){ + if(hasName) + throw Error("Unexpected token after model name\n"); + else{ + models.back().name = token; + cmess2 << " " << tab << "+ " << token << " [interface+signals]" << endl; + hasName = true; } } else{ - models.back().subcircuits.back().cell = token; - hasName = true; + throw Error("Unexpected token\n"); } } - else if(state == NAMES){ - current_names.push_back(token); + line.clear(); + } + if(state != EXT){ + cerr << Warning("End of model has not been found\n"); + } + + /* + for(auto & M : models){ + cout << "Model: " << M.name << endl; + for(auto & S : M.subcircuits){ + cout << "\tInstance of " << S.cell; + for(auto & P : S.pins){ + cout << " " << P.first << ":" << P.second; + } + cout << endl; } - else if(state == MODEL){ - if(hasName) - throw Error("Unexpected token after model name\n"); - else{ - models.back().name = token; - cmess2 << "Processing model <" << token << ">" << endl; - hasName = true; + } + */ + + // Two passes: first create the cells and their nets, then create the internals + std::vector model_cells; + for(auto M : models){ + Cell * design = framework->createCell(M.name); + if(design == NULL){ + throw Error("Model " + M.name + " is NULL\n"); + } + if (M.name == mainName) mainModel = design; + + model_cells.push_back(design); + addSupplyNets(design); + + unordered_set net_names; + for(auto const & S : M.subcircuits){ + for(auto const & P : S.pins){ + net_names.insert(P.second); + } + for(auto const & A : M.aliases){ + net_names.insert(A.first); + net_names.insert(A.second); } } - else{ - throw Error("Unexpected token\n"); + + for(auto const & P : M.pins){ + net_names.insert(P.first); + } + + for(string const & N : net_names){ + Net* new_net = Net::create( design, N ); + auto it = M.pins.find(N); + if(it != M.pins.end()){ + new_net->setExternal( true ); + new_net->setDirection( it->second ); + } } } - line.clear(); - } - if(state != EXT){ - cerr << Warning("End of model has not been found\n"); + + // Second pass: every cell and its nets have already been created + for(size_t i=0; igetCell(S.cell, Catalog::State::Views, 0); + if(cell == NULL){ + throw Error("Cell <" + S.cell + "> to instanciate hasn't been found\n"); + } + //cmess2 << "Creating instance <" << subckt_name.str() << "> of <" << S.cell << "> in <" << models[i].name << ">" << endl; + Instance* instance = Instance::create( design, subckt_name.str(), cell); + + for(auto & P : S.pins){ + Net* internalNet = cell->getNet( P.first ); + Net* externalNet = design->getNet( P.second ); + assert(internalNet != NULL and externalNet != NULL and instance != NULL); + instance->getPlug( internalNet )->setNet( externalNet ); + } + //connectSupplyNets(instance, design); + } + // Merge the aliased nets + for(auto alias : M.aliases){ + //cmess2 << "Merging nets <" << alias.first << "> and <" << alias.second << ">" << endl; + Net * first_net = design->getNet( alias.first ); + Net * second_net = design->getNet( alias.second ); + if(first_net == NULL or second_net == NULL){ + ostringstream mess; + mess << "Trying to create an alias for non-instantiated nets:"; + if(first_net == NULL) + mess << " <" << alias.first << ">"; + if(second_net == NULL) + mess << " <" << alias.second << ">"; + mess << ", will be ignored\n"; + cerr << Warning(mess.str()); + continue; + } + if(!first_net->isExternal()) + swap(first_net, second_net); // If only one net is external, it needs to be the first + first_net->merge(second_net); + } + --tab; + } + --tab; + + for ( auto model : model_cells ) + CRL::NamingScheme::toVhdl( model, CRL::NamingScheme::Recursive|CRL::NamingScheme::FromVerilog ); + + if(model_cells.empty()){ + throw Error("No model found in the file\n"); + } + else if(mainModel) { + return mainModel; + } + else if (model_cells.size() > 1){ + cerr << Warning( "Blif::load(): Several models found, returned the first one %s.\n" + , getString(model_cells[0]->getName()).c_str() + ); + } + + return model_cells[0]; } - /* - for(auto & M : models){ - cout << "Model: " << M.name << endl; - for(auto & S : M.subcircuits){ - cout << "\tInstance of " << S.cell; - for(auto & P : S.pins){ - cout << " " << P.first << ":" << P.second; - } - cout << endl; - } - } - */ - // Two passes: first create the cells and their nets, then create the internals - std::vector model_cells; - for(auto M : models){ - Cell * design = framework->createCell(M.name); - if(design == NULL){ - throw Error("Model " + M.name + " is NULL\n"); - } - model_cells.push_back(design); - addSupplyNets(design); - - unordered_set net_names; - for(auto const & S : M.subcircuits){ - for(auto const & P : S.pins){ - net_names.insert(P.second); - } - for(auto const & A : M.aliases){ - net_names.insert(A.first); - net_names.insert(A.second); - } - } - for(auto const & P : M.pins){ - net_names.insert(P.first); - } - - for(string const & N : net_names){ - Net* new_net = Net::create( design, N ); - auto it = M.pins.find(N); - if(it != M.pins.end()){ - new_net->setExternal( true ); - new_net->setDirection( it->second ); - } - } - } - // Second pass: every cell and its nets have already been created - for(int i=0; igetCell(S.cell, Catalog::State::Views, 0); - if(cell == NULL){ - throw Error("Cell <" + S.cell + "> to instanciate hasn't been found\n"); - } - //cmess2 << "Creating instance <" << subckt_name.str() << "> of <" << S.cell << "> in <" << models[i].name << ">" << endl; - Instance* instance = Instance::create( design, subckt_name.str(), cell); - - for(auto & P : S.pins){ - Net* internalNet = cell->getNet( P.first ); - Net* externalNet = design->getNet( P.second ); - assert(internalNet != NULL and externalNet != NULL and instance != NULL); - instance->getPlug( internalNet )->setNet( externalNet ); - } - //connectSupplyNets(instance, design); - } - // Merge the aliased nets - for(auto alias : M.aliases){ - //cmess2 << "Merging nets <" << alias.first << "> and <" << alias.second << ">" << endl; - Net * first_net = design->getNet( alias.first ); - Net * second_net = design->getNet( alias.second ); - if(first_net == NULL or second_net == NULL){ - ostringstream mess; - mess << "Trying to create an alias for non-instantiated nets:"; - if(first_net == NULL) - mess << " <" << alias.first << ">"; - if(second_net == NULL) - mess << " <" << alias.second << ">"; - mess << ", will be ignored\n"; - cerr << Warning(mess.str()); - continue; - } - if(!first_net->isExternal()) - swap(first_net, second_net); // If only one net is external, it needs to be the first - first_net->merge(second_net); - } - } - cmess2 << "BLIF file loaded" << endl; - if(model_cells.empty()){ - throw Error("No model found in the file\n"); - } - else if(model_cells.size() > 1){ - cerr << Warning("Several models found: returned the first one\n"); - } - return model_cells[0]; -} - -} +} // CRL namespace. diff --git a/crlcore/src/ccore/crlcore/ToolBox.h b/crlcore/src/ccore/crlcore/ToolBox.h index 8c90582a..2f90021f 100644 --- a/crlcore/src/ccore/crlcore/ToolBox.h +++ b/crlcore/src/ccore/crlcore/ToolBox.h @@ -1,13 +1,7 @@ - - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved -// -// =================================================================== -// -// $Id$ +// Copyright (c) UPMC 2008-2015, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -20,12 +14,13 @@ // +-----------------------------------------------------------------+ -#ifndef __CRL_TOOLBOX_H__ -#define __CRL_TOOLBOX_H__ +#ifndef CRL_TOOLBOX_H +#define CRL_TOOLBOX_H -#include "hurricane/Cell.h" -#include "hurricane/Net.h" -#include "hurricane/Component.h" +#include +#include "hurricane/Cell.h" +#include "hurricane/Net.h" +#include "hurricane/Component.h" namespace CRL { @@ -41,6 +36,9 @@ namespace CRL { using Hurricane::Library; using Hurricane::Occurrence; + + + Component* getBestExternalComponent ( Net* ); bool placeNet ( Net* ); void placeNets ( Cell* ); @@ -61,6 +59,21 @@ namespace CRL { size_t getInstancesCount ( const Cell* cell ); void setNetsPosition ( Cell* ); -} // End of CRL namespace. -#endif // __CRL_TOOLBOX_H__ + class NamingScheme { + public: + enum Flag { NoFlags = 0x0000 + , Recursive = 0x0001 + , FromVerilog = 0x0002 + }; + public: + typedef std::function< Name(const Name&) > converter_t; + public: + static Name vlogToVhdl ( const Name& vlogName ); + static void toVhdl ( Cell* topCell, unsigned int flags ); + }; + + +} // CRL namespace. + +#endif // CRL_TOOLBOX_H diff --git a/crlcore/src/ccore/toolbox/NamingScheme.cpp b/crlcore/src/ccore/toolbox/NamingScheme.cpp new file mode 100644 index 00000000..cd4b130f --- /dev/null +++ b/crlcore/src/ccore/toolbox/NamingScheme.cpp @@ -0,0 +1,98 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2015, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./toolbox/ToVhdlName.h" | +// +-----------------------------------------------------------------+ + + +#include +#include "crlcore/ToolBox.h" +#include "hurricane/Instance.h" + + +namespace CRL { + + using namespace std; + using Hurricane::ForEachIterator; + using Hurricane::Net; + using Hurricane::Cell; + using Hurricane::Instance; + + + Name NamingScheme::vlogToVhdl ( const Name& vlogName ) + { + string vhdlName; + + size_t parCount = 0; + for ( size_t i=0 ; i 1) ? '_' : '('; + char rightPar = (parCount > 1) ? '_' : ')'; + + for ( size_t i=0 ; isetName( converter(topCell->getName()) ); + + vector nets; + forEach ( Net*, inet, topCell->getNets() ) nets.push_back( *inet ); + for ( auto net : nets ) net->setName( converter( net->getName() ) ); + + vector instances; + set models; + forEach ( Instance*, iinst, topCell->getInstances() ) { + instances.push_back( *iinst ); + models.insert( iinst->getMasterCell() ); + } + for ( auto inst : instances ) inst->setName( converter( inst->getName() ) ); + + if (flags & Recursive) + for ( auto model : models ) toVhdl( model, flags ); + } + + +} // CRL namespace. diff --git a/crlcore/src/ccore/toolbox/ToVhdlName.cpp b/crlcore/src/ccore/toolbox/ToVhdlName.cpp new file mode 100644 index 00000000..e0a7ec87 --- /dev/null +++ b/crlcore/src/ccore/toolbox/ToVhdlName.cpp @@ -0,0 +1,80 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2015, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./toolbox/ToVhdlName.h" | +// +-----------------------------------------------------------------+ + + +#include "crlcore/ToolBox.h" +#include "hurricane/Instance.h" + + +namespace { + + using namespace std; + using Hurricane::Name; + + + Name vlogToVhdl ( const Name& vlogName ) + { + string vhdlName; + + for ( size_t i=0 ; i nets; + forEach ( Net*, inet, topCell->getNets() ) nets.push_back( *inet ); + for ( auto net : nets ) net->setName( vlogToVhdl( inet->getName() ) ); + + vector instances; + set models; + forEach ( Instance*, iinst, topCell->getInstances() ) { + instances.push_back( *iinst ); + models.insert( iinst->getMasterCell() ); + } + for ( auto inst : instances ) inst->setName( vlogToVhdl( inst->getName() ) ); + + for ( auto model : models ) toVhdlName( model, flags ); + } + + +} // CRL namespace. diff --git a/crlcore/src/pyCRL/CMakeLists.txt b/crlcore/src/pyCRL/CMakeLists.txt index 3596a2be..9cea2fb4 100644 --- a/crlcore/src/pyCRL/CMakeLists.txt +++ b/crlcore/src/pyCRL/CMakeLists.txt @@ -41,6 +41,7 @@ PyGraphicToolEngine.cpp PyAcmSigda.cpp PyIspd05.cpp + PyBlif.cpp ) set( pyIncludes crlcore/PyBanner.h crlcore/PyCatalog.h @@ -56,6 +57,7 @@ crlcore/PyGraphicToolEngine.h crlcore/PyAcmSigda.h crlcore/PyIspd05.h + crlcore/PyBlif.h ) set( depLibs crlcore ${HURRICANE_PYTHON_LIBRARIES} diff --git a/crlcore/src/pyCRL/PyBlif.cpp b/crlcore/src/pyCRL/PyBlif.cpp new file mode 100644 index 00000000..e3222f83 --- /dev/null +++ b/crlcore/src/pyCRL/PyBlif.cpp @@ -0,0 +1,107 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2015, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./PyBlif.cpp" | +// +-----------------------------------------------------------------+ + + +#include "crlcore/PyBlif.h" +#include "hurricane/isobar/PyCell.h" +#include +#include + + +namespace CRL { + + using std::cerr; + using std::endl; + using std::hex; + using std::string; + using std::ostringstream; + using Hurricane::tab; + using Hurricane::in_trace; + using Hurricane::Error; + using Hurricane::Warning; + using Isobar::ProxyProperty; + using Isobar::ProxyError; + using Isobar::ConstructorError; + using Isobar::HurricaneError; + using Isobar::HurricaneWarning; + using Isobar::ParseOneArg; + using Isobar::ParseTwoArg; + using Isobar::__cs; + using Isobar::PyCell_Link; + + +extern "C" { + + +#if defined(__PYTHON_MODULE__) + +// +=================================================================+ +// | "PyBlif" Python Module Code Part | +// +=================================================================+ + + + static PyObject* PyBlif_load ( PyObject*, PyObject* args ) + { + trace << "PyBlif_load()" << endl; + + Cell* cell = NULL; + + HTRY + char* benchName = NULL; + + if (PyArg_ParseTuple( args, "s:Blif.load", &benchName )) { + cell = Blif::load( benchName ); + } else { + PyErr_SetString ( ConstructorError, "Blif.load(): Bad type or bad number of parameters." ); + return NULL; + } + HCATCH + + return (PyObject*)PyCell_Link(cell); + } + + + // Standart Destroy (Attribute). + + + PyMethodDef PyBlif_Methods[] = + { { "load" , (PyCFunction)PyBlif_load , METH_VARARGS|METH_STATIC + , "Load a complete Blif design." } + //, { "destroy" , (PyCFunction)PyBlif_destroy , METH_VARARGS + // , "Destroy the associated hurricane object. The python object remains." } + , {NULL, NULL, 0, NULL} /* sentinel */ + }; + + + NoObjectDeleteMethod(Blif) + PyTypeObjectLinkPyTypeWithoutObject(Blif,Blif) + + +#else // End of Python Module Code Part. + + +// +=================================================================+ +// | "PyBlif" Shared Library Code Part | +// +=================================================================+ + + // Type Definition. + PyTypeObjectDefinitionsOfModule(CRL,Blif) + + +#endif // End of Shared Library Code Part. + +} // extern "C". + +} // CRL namespace. diff --git a/crlcore/src/pyCRL/PyCRL.cpp b/crlcore/src/pyCRL/PyCRL.cpp index 314852ce..3d712602 100644 --- a/crlcore/src/pyCRL/PyCRL.cpp +++ b/crlcore/src/pyCRL/PyCRL.cpp @@ -1,7 +1,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2010-2015, All Rights Reserved +// Copyright (c) UPMC 2010-2015, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -30,6 +30,7 @@ #include "crlcore/PyToolEngineCollection.h" #include "crlcore/PyAcmSigda.h" #include "crlcore/PyIspd05.h" +#include "crlcore/PyBlif.h" namespace CRL { @@ -92,6 +93,7 @@ extern "C" { PyToolEngineCollection_LinkPyType (); PyAcmSigda_LinkPyType (); PyIspd05_LinkPyType (); + PyBlif_LinkPyType (); PYTYPE_READY ( Banner ); PYTYPE_READY ( CatalogState ); @@ -108,6 +110,7 @@ extern "C" { PYTYPE_READY ( ToolEngineCollectionLocator ); PYTYPE_READY ( AcmSigda ); PYTYPE_READY ( Ispd05 ); + PYTYPE_READY ( Blif ); // Identifier string can take up to 10 characters. __cs.addType ( "alcEnv" , &PyTypeEnvironment , "" , false ); @@ -153,6 +156,8 @@ extern "C" { PyModule_AddObject ( module, "AcmSigda", (PyObject*)&PyTypeAcmSigda ); Py_INCREF ( &PyTypeIspd05 ); PyModule_AddObject ( module, "Ispd05", (PyObject*)&PyTypeIspd05 ); + Py_INCREF ( &PyTypeBlif ); + PyModule_AddObject ( module, "Blif", (PyObject*)&PyTypeBlif ); PyCatalog_postModuleInit (); PyEnvironment_postModuleInit (); diff --git a/crlcore/src/pyCRL/crlcore/PyBlif.h b/crlcore/src/pyCRL/crlcore/PyBlif.h new file mode 100644 index 00000000..07d3027f --- /dev/null +++ b/crlcore/src/pyCRL/crlcore/PyBlif.h @@ -0,0 +1,55 @@ + +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2015-2015, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | Alliance / Hurricane Interface | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Header : "./crlcore/PyBlif.h" | +// +-----------------------------------------------------------------+ + + +#ifndef CRL_PY_BLIF_H +#define CRL_PY_BLIF_H + +#include "hurricane/isobar/PyHurricane.h" +#include "crlcore/Blif.h" + + +namespace CRL { + +extern "C" { + + +// ------------------------------------------------------------------- +// Python Object : "PyBlif". + + typedef struct { + PyObject_HEAD + } PyBlif; + + +// ------------------------------------------------------------------- +// Functions & Types exported to "PyCRL.ccp". + + extern PyTypeObject PyTypeBlif; + extern PyMethodDef PyBlif_Methods[]; + + extern void PyBlif_LinkPyType(); + + +#define IsPyBlif(v) ( (v)->ob_type == &PyTypeBlif ) +#define PY_BLIF(v) ( (PyBlif*)(v) ) + + +} // extern "C". + +} // Hurricane namespace. + +#endif // CRL_PY_BLIF_H diff --git a/cumulus/src/CMakeLists.txt b/cumulus/src/CMakeLists.txt index 9d0349f6..76c65e31 100644 --- a/cumulus/src/CMakeLists.txt +++ b/cumulus/src/CMakeLists.txt @@ -8,6 +8,7 @@ ${CMAKE_CURRENT_SOURCE_DIR}/plugins/ChipPlugin.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/ClockTreePlugin.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/RSavePlugin.py + ${CMAKE_CURRENT_SOURCE_DIR}/plugins/RSavePluginAll.py ) set ( pyPluginCT ${CMAKE_CURRENT_SOURCE_DIR}/plugins/clocktree/__init__.py ${CMAKE_CURRENT_SOURCE_DIR}/plugins/clocktree/RSMT.py diff --git a/cumulus/src/plugins/RSavePlugin.py b/cumulus/src/plugins/RSavePlugin.py index 64176286..f8d90ee9 100644 --- a/cumulus/src/plugins/RSavePlugin.py +++ b/cumulus/src/plugins/RSavePlugin.py @@ -68,7 +68,7 @@ def rsave ( cell, depth=0 ): def unicornHook ( **kw ): plugins.kwUnicornHook( 'plugins.rsave' - , 'R-Save Cell' + , 'R-Save Cell (layout)' , 'Recursively Save Top Cell and it\'s Instances' , sys.modules[__name__].__file__ , **kw diff --git a/cumulus/src/plugins/RSavePluginAll.py b/cumulus/src/plugins/RSavePluginAll.py new file mode 100644 index 00000000..82107fa1 --- /dev/null +++ b/cumulus/src/plugins/RSavePluginAll.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python +# +# This file is part of the Coriolis Software. +# Copyright (c) UPMC 2015-2015, All Rights Reserved +# +# +-----------------------------------------------------------------+ +# | C O R I O L I S | +# | C u m u l u s - P y t h o n T o o l s | +# | | +# | Author : Jean-Paul CHAPUT | +# | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +# | =============================================================== | +# | Python : "./plugins/RSavePluginAll.py" | +# +-----------------------------------------------------------------+ + + +try: + import sys + import traceback + import os.path + import Cfg + import CRL + import helpers + from helpers import ErrorMessage + from helpers import WarningMessage + import plugins +except ImportError, e: + serror = str(e) + if serror.startswith('No module named'): + module = serror.split()[-1] + print '[ERROR] The <%s> python module or symbol cannot be loaded.' % module + print ' Please check the integrity of the package.' + if str(e).find('cannot open shared object file'): + library = serror.split(':')[0] + print '[ERROR] The <%s> shared library cannot be loaded.' % library + print ' Under RHEL 6, you must be under devtoolset-2.' + print ' (scl enable devtoolset-2 bash)' + sys.exit(1) +except Exception, e: + print '[ERROR] A strange exception occurred while loading the basic Coriolis/Python' + print ' modules. Something may be wrong at Python/C API level.\n' + print ' %s' % e + sys.exit(2) + + +# Write back layout to disk if everything has gone fine. +# Must write all the sub-blocks of the core but *not* the +# standard cell (mainly the feed-through). + +def rsave ( cell, depth=0 ): + if cell.isTerminal(): return + + framework = CRL.AllianceFramework.get() + if depth == 0: print ' o Recursive Save-Cell.' + + print ' %s+ %s (netlist+layout).' % ( ' '*(depth*2), cell.getName() ) + framework.saveCell( cell, CRL.Catalog.State.Views ) + + for instance in cell.getInstances(): + masterCell = instance.getMasterCell() + if not masterCell.isTerminal(): + rsave( masterCell, depth+1 ) + return + + +# -------------------------------------------------------------------- +# Plugin hook functions, unicornHook:menus, ScritMain:call + +def unicornHook ( **kw ): + plugins.kwUnicornHook( 'plugins.rsaveAll' + , 'R-Save Cell (All)' + , 'Recursively Save Top Cell and it\'s Instances' + , sys.modules[__name__].__file__ + , **kw + ) + return + + +def ScriptMain ( **kw ): + try: + helpers.staticInitialization( quiet=True ) + #helpers.setTraceLevel( 550 ) + + cell, editor = plugins.kwParseMain( **kw ) + + if not cell: + print WarningMessage( 'No Cell loaded in the editor (yet), nothing done.' ) + return 0 + + rsave( cell ) + + except ErrorMessage, e: + print e; errorCode = e.code + except Exception, e: + print '\n\n', e; errorCode = 1 + traceback.print_tb(sys.exc_info()[2]) + + sys.stdout.flush() + sys.stderr.flush() + + return 0 diff --git a/hurricane/src/hurricane/CMakeLists.txt b/hurricane/src/hurricane/CMakeLists.txt index 51b2c167..654de379 100644 --- a/hurricane/src/hurricane/CMakeLists.txt +++ b/hurricane/src/hurricane/CMakeLists.txt @@ -48,6 +48,7 @@ hurricane/MultisetCollection.h hurricane/Marker.h hurricane/Markers.h hurricane/Name.h hurricane/Names.h + hurricane/NetAlias.h hurricane/NetExternalComponents.h hurricane/NetRoutingProperty.h hurricane/Net.h hurricane/Nets.h @@ -124,6 +125,7 @@ Entity.cpp Cell.cpp CellCollections.cpp + NetAlias.cpp Net.cpp DeepNet.cpp HyperNet.cpp diff --git a/hurricane/src/hurricane/Cell.cpp b/hurricane/src/hurricane/Cell.cpp index d9da0675..a793ad41 100644 --- a/hurricane/src/hurricane/Cell.cpp +++ b/hurricane/src/hurricane/Cell.cpp @@ -161,6 +161,28 @@ bool Cell::isCalledBy(Cell* cell) const return false; } +bool Cell::isNetAlias ( const Name& name ) const +// ********************************************* +{ + NetAliasName key(name); + return _netAliasSet.find(&key) != _netAliasSet.end(); +} + +Net* Cell::getNet ( const Name& name ) const +//****************************************** +{ + Net* net = _netMap.getElement(name); + if (net) return net; + + NetAliasName key(name); + AliasNameSet::iterator ialias = _netAliasSet.find( &key ); + if (ialias != _netAliasSet.end()) + return (*ialias)->getNet(); + + return NULL; +} + + void Cell::setName(const Name& name) // ********************************* { @@ -360,7 +382,11 @@ void Cell::_preDestroy() for_each_marker(marker, getMarkers()) marker->destroy(); end_for; for_each_instance(slaveInstance, getSlaveInstances()) slaveInstance->destroy(); end_for; for_each_instance(instance, getInstances()) instance->destroy(); end_for; - for_each_net(net, getNets()) net->destroy(); end_for; + forEach( Net*, inet, getNets() ) { + inet->_getMainName().detachAll(); + inet->destroy(); + } + for ( auto islave : _netAliasSet ) delete islave; for_each_slice(slice, getSlices()) slice->_destroy(); end_for; while(!_extensionSlices.empty()) _removeSlice(_extensionSlices.begin()->second); @@ -382,20 +408,21 @@ Record* Cell::_getRecord() const { Record* record = Inherit::_getRecord(); if (record) { - record->add(getSlot("Library", _library)); - record->add(getSlot("Name", &_name)); - record->add(getSlot("Instances", &_instanceMap)); - record->add(getSlot("QuadTree", &_quadTree)); - record->add(getSlot("SlaveInstances", &_slaveInstanceSet)); - record->add(getSlot("Nets", &_netMap)); - record->add(getSlot("Pins", &_pinMap)); - record->add(getSlot("Slices", &_sliceMap)); - record->add(getSlot("Markers", &_markerSet)); - record->add(getSlot("SlaveEntityMap", &_slaveEntityMap)); - record->add(getSlot("AbutmentBox", &_abutmentBox)); - record->add(getSlot("BoundingBox", &_boundingBox)); - record->add(getSlot("isTerminal", &_isTerminal)); - record->add(getSlot("isFlattenLeaf", &_isFlattenLeaf)); + record->add(getSlot("_library", _library)); + record->add(getSlot("_name", &_name)); + record->add(getSlot("_instances", &_instanceMap)); + record->add(getSlot("_quadTree", &_quadTree)); + record->add(getSlot("_slaveInstances", &_slaveInstanceSet)); + record->add(getSlot("_netMap", &_netMap)); + record->add(getSlot("_netAliasSet", &_netAliasSet)); + record->add(getSlot("_pinMap", &_pinMap)); + record->add(getSlot("_sliceMap", &_sliceMap)); + record->add(getSlot("_markerSet", &_markerSet)); + record->add(getSlot("_slaveEntityMap", &_slaveEntityMap)); + record->add(getSlot("_abutmentBox", &_abutmentBox)); + record->add(getSlot("_boundingBox", &_boundingBox)); + record->add(getSlot("_isTerminal", &_isTerminal)); + record->add(getSlot("_isFlattenLeaf", &_isFlattenLeaf)); } return record; } diff --git a/hurricane/src/hurricane/DBo.cpp b/hurricane/src/hurricane/DBo.cpp index daad74b6..53431460 100644 --- a/hurricane/src/hurricane/DBo.cpp +++ b/hurricane/src/hurricane/DBo.cpp @@ -1,7 +1,6 @@ - // -*- C++ -*- // -// Copyright (c) BULL S.A. 2000-2009, All Rights Reserved +// Copyright (c) BULL S.A. 2000-2015, All Rights Reserved // // This file is part of Hurricane. // @@ -21,10 +20,7 @@ // // =================================================================== // -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | H U R R I C A N E | // | V L S I B a c k e n d D a t a - B a s e | // | | @@ -32,10 +28,7 @@ // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Module : "./DBo.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ #include "hurricane/Property.h" diff --git a/hurricane/src/hurricane/Name.cpp b/hurricane/src/hurricane/Name.cpp index 66c74205..fd360533 100644 --- a/hurricane/src/hurricane/Name.cpp +++ b/hurricane/src/hurricane/Name.cpp @@ -165,6 +165,12 @@ char Name::operator[](unsigned index) const return _sharedName->_string[index]; } +size_t Name::size() const +// ********************** +{ + return _sharedName->_string.size(); +} + bool Name::isEmpty() const // *********************** { diff --git a/hurricane/src/hurricane/Net.cpp b/hurricane/src/hurricane/Net.cpp index 892e4ed1..04a4f87a 100644 --- a/hurricane/src/hurricane/Net.cpp +++ b/hurricane/src/hurricane/Net.cpp @@ -17,6 +17,7 @@ // not, see . // **************************************************************************************************** +#include "hurricane/Warning.h" #include "hurricane/Net.h" #include "hurricane/Cell.h" #include "hurricane/Instance.h" @@ -263,7 +264,8 @@ Net::Net(Cell* cell, const Name& name) _position(0,0), _componentSet(), _rubberSet(), - _nextOfCellNetMap(NULL) + _nextOfCellNetMap(NULL), + _mainName(this) { if (!_cell) throw Error("Can't create " + _TName("Net") + " : null cell"); @@ -504,6 +506,36 @@ void Net::setDirection(const Direction& direction) _direction = direction; } +bool Net::addAlias(const Name& name ) +// ********************************** +{ + if (getCell()->getNet(name)) { + cerr << Warning( "Net::addAlias(): Cannot add alias %s to net %s, already taken." + , getString(name).c_str() + , getString(getName()).c_str() + ) << endl; + return false; + } + + NetAliasName* slave = new NetAliasName ( name ); + _mainName.attach( slave ); + getCell()->_addNetAlias( slave ); + + return true; +} + +bool Net::removeAlias(const Name& name ) +// ************************************* +{ + NetAliasName* slave = _mainName.find( name ); + if (slave) { + slave->detach(); + getCell()->_removeNetAlias( slave ); + return true; + } + return false; +} + void Net::materialize() // ******************** { @@ -600,7 +632,17 @@ void Net::merge(Net* net) } } + Name mergedName = net->getName(); + NetAliasName* slaves = NULL; + if (net->_mainName.isAttached()) { + slaves = dynamic_cast( net->_mainName.getNext() ); + net->_mainName.detach(); + } + net->destroy(); + + if (slaves) _mainName.attach( slaves ); + addAlias( mergedName ); } void Net::_postCreate() @@ -648,6 +690,7 @@ void Net::_preDestroy() end_for; } + _mainName.clear(); _cell->_getNetMap()._remove(this); } @@ -664,17 +707,18 @@ Record* Net::_getRecord() const { Record* record = Inherit::_getRecord(); if (record) { - record->add(getSlot("Cell", _cell)); - record->add(getSlot("Name", &_name)); - record->add(getSlot("Arity", &_arity)); - record->add(getSlot("Global", &_isGlobal)); - record->add(getSlot("External", &_isExternal)); - record->add(getSlot("Automatic", &_isAutomatic)); - record->add(getSlot("Type", &_type)); - record->add(getSlot("Direction", &_direction)); - record->add(getSlot("Position", &_position)); - record->add(getSlot("Components", &_componentSet)); - record->add(getSlot("Rubbers", &_rubberSet)); + record->add(getSlot("_cell", _cell)); + record->add(getSlot("_name", &_name)); + record->add(getSlot("_arity", &_arity)); + record->add(getSlot("_isGlobal", &_isGlobal)); + record->add(getSlot("_isExternal", &_isExternal)); + record->add(getSlot("_isAutomatic", &_isAutomatic)); + record->add(getSlot("_type", &_type)); + record->add(getSlot("_direction", &_direction)); + record->add(getSlot("_position", &_position)); + record->add(getSlot("_componentsSet", &_componentSet)); + record->add(getSlot("_rubberSet", &_rubberSet)); + record->add(getSlot("_mainName", &_mainName)); } return record; } diff --git a/hurricane/src/hurricane/NetAlias.cpp b/hurricane/src/hurricane/NetAlias.cpp new file mode 100644 index 00000000..4accc53b --- /dev/null +++ b/hurricane/src/hurricane/NetAlias.cpp @@ -0,0 +1,213 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2015-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./NetAlias.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/NetAlias.h" +#include "hurricane/Net.h" +#include "hurricane/Cell.h" + + +namespace Hurricane { + + using namespace std; + + +// ------------------------------------------------------------------- +// Class : "Hurricane::NetAliasHook". + + NetAliasHook::NetAliasHook () + : _next(this) + { } + + + NetAliasHook::~NetAliasHook () + { if (isAttached()) detach(); } + + + bool NetAliasHook::isAttached () const + { return (_next != this); } + + + NetAliasName* NetAliasHook::find ( const Name& name ) const + { + const NetAliasHook* current = this; + do { + if ( not isMaster() and (current->getName() == name) ) + return const_cast( dynamic_cast(current) ); + + current = current->_next; + } while ( current != this ); + + return NULL; + } + + + NetAliasHook* NetAliasHook::getNext () const + { return _next; } + + + NetAliasHook* NetAliasHook::getPrevious () const + { + NetAliasHook* current = _next; + while ( current->_next != this ) + current = current->_next; + return current; + } + + + void NetAliasHook::attach ( NetAliasHook* otherRing ) + { + NetAliasHook* otherRingPrev = otherRing->getPrevious(); + + otherRingPrev->_next = _next; + _next = otherRing; + } + + + void NetAliasHook::detach () + { + if (not isAttached()) return; + + NetAliasHook* prev = getPrevious(); + + prev->_next = _next; + _next = this; + } + + + void NetAliasHook::detachAll () + { + NetAliasHook* current = _next; + _next = this; + + while ( current != this ) + { + NetAliasHook* next = current->_next; + current->_next = current; + current = next; + } + } + + + Record* NetAliasHook::_getRecord () const + { + Record* record = new Record ( getString(this) ); + record->add ( getSlot("_next", &_next) ); + return record; + } + + +// ------------------------------------------------------------------- +// Class : "Hurricane::NetMainName". + + ptrdiff_t NetMainName::_offset = 0; + + + NetMainName::NetMainName ( Net* owner ) + : NetAliasHook() + { + if (not _offset) _offset = (ptrdiff_t)this - (ptrdiff_t)owner; + } + + + NetMainName::~NetMainName () + { clear(); } + + + void NetMainName::clear () + { + vector slaves; + for ( NetAliasHook* current=getNext() ; current->getNext()!=this ; current=current->getNext() ) { + slaves.push_back( dynamic_cast(current) ); + } + detachAll(); + + AliasNameSet& slaveAliases = getNet()->getCell()->_getNetAliasSet(); + for ( auto slave : slaves ) { + slaveAliases.erase( slave ); + delete slave; + } + } + + + bool NetMainName::isMaster () const { return true; } + bool NetMainName::isSlave () const { return false; } + Name NetMainName::getName () const { return getNet()->getName(); } + Net* NetMainName::getNet () const { return (Net*)((ptrdiff_t)this - _offset); } + string NetMainName::_getString () const { return ""; } + +// ------------------------------------------------------------------- +// Class : "Hurricane::NetAliasName". + + + NetAliasName::NetAliasName ( Name name ) + : NetAliasHook() + , _name (name) + { } + + + NetAliasName::~NetAliasName () + { + if (isAttached()) { + cerr << Error("NetAliasName::~NetAliasName() still attached, prepare to crash.") << endl; + } + } + + + bool NetAliasName::isMaster () const { return false; } + bool NetAliasName::isSlave () const { return true; } + Name NetAliasName::getName () const { return _name; } + + + Net* NetAliasName::getNet () const + { + NetAliasHook* current = this->getNext(); + while (current != this) { + if (current->isMaster()) return current->getNet(); + current = current->getNext(); + } + return NULL; + } + + + string NetAliasName::_getString () const + { return " " + getString(getNet()->getName()) + ">"; } + + + Record* NetAliasName::_getRecord () const + { + Record* record = NetAliasHook::_getRecord(); + if (record) { + record->add ( getSlot("_name", &_name) ); + } + return record; + } + +} // Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Cell.h b/hurricane/src/hurricane/hurricane/Cell.h index f8ab3069..099c8fe6 100644 --- a/hurricane/src/hurricane/hurricane/Cell.h +++ b/hurricane/src/hurricane/hurricane/Cell.h @@ -42,6 +42,7 @@ //#include "hurricane/IntrusiveMap.h" #include "hurricane/IntrusiveSet.h" #include "hurricane/MapCollection.h" +#include "hurricane/NetAlias.h" @@ -182,6 +183,7 @@ class Cell : public Entity { private: Cell* _nextOfLibraryCellMap; private: Cell* _nextOfSymbolCellSet; private: SlaveEntityMap _slaveEntityMap; + private: AliasNameSet _netAliasSet; private: Observable _observers; private: unsigned int _flags; @@ -211,10 +213,14 @@ class Cell : public Entity { public: MarkerSet& _getMarkerSet() {return _markerSet;}; public: Cell* _getNextOfLibraryCellMap() const {return _nextOfLibraryCellMap;}; public: Cell* _getNextOfSymbolCellSet() const {return _nextOfSymbolCellSet;}; + public: AliasNameSet& _getNetAliasSet() { return _netAliasSet; } public: void _setNextOfLibraryCellMap(Cell* cell) {_nextOfLibraryCellMap = cell;}; public: void _setNextOfSymbolCellSet(Cell* cell) {_nextOfSymbolCellSet = cell;}; + public: void _addNetAlias(NetAliasName* alias) { _netAliasSet.insert(alias); } + public: void _removeNetAlias(NetAliasName* alias) { _netAliasSet.erase(alias); } + public: void _fit(const Box& box); public: void _unfit(const Box& box); @@ -257,7 +263,7 @@ class Cell : public Entity { public: Instances getLeafInstancesUnder(const Box& area) const; public: Instances getNonLeafInstances() const; public: Instances getNonLeafInstancesUnder(const Box& area) const; - public: Net* getNet(const Name& name) const {return _netMap.getElement(name);}; + public: Net* getNet(const Name& name) const; public: DeepNet* getDeepNet( Path, const Net* ) const; public: Nets getNets() const {return _netMap.getElements();}; public: Nets getGlobalNets() const; @@ -309,6 +315,7 @@ class Cell : public Entity { public: bool isLeaf() const; public: bool isPad() const {return _isPad;}; public: bool isFlattenedNets() const {return _flags & FlattenedNets;}; + public: bool isNetAlias(const Name& name) const; // Updators // ******** diff --git a/hurricane/src/hurricane/hurricane/Hook.h b/hurricane/src/hurricane/hurricane/Hook.h index 50526834..f60b4eeb 100644 --- a/hurricane/src/hurricane/hurricane/Hook.h +++ b/hurricane/src/hurricane/hurricane/Hook.h @@ -31,7 +31,7 @@ class Component; // **************************************************************************************************** // Hook declaration // **************************************************************************************************** - + class Hook { // ********* diff --git a/hurricane/src/hurricane/hurricane/Name.h b/hurricane/src/hurricane/hurricane/Name.h index c6d1152f..7facc425 100644 --- a/hurricane/src/hurricane/hurricane/Name.h +++ b/hurricane/src/hurricane/hurricane/Name.h @@ -77,6 +77,7 @@ class Name { // ********** public: bool isEmpty() const; + public: size_t size() const; // Others // ****** diff --git a/hurricane/src/hurricane/hurricane/Net.h b/hurricane/src/hurricane/hurricane/Net.h index c9f1939a..c6fd2ce3 100644 --- a/hurricane/src/hurricane/hurricane/Net.h +++ b/hurricane/src/hurricane/hurricane/Net.h @@ -36,6 +36,7 @@ #include "hurricane/Pads.h" #include "hurricane/IntrusiveSet.h" #include "hurricane/Path.h" +#include "hurricane/NetAlias.h" namespace Hurricane { @@ -153,6 +154,7 @@ class Net : public Entity { private: ComponentSet _componentSet; private: RubberSet _rubberSet; private: Net* _nextOfCellNetMap; + private: NetMainName _mainName; // Constructors // ************ @@ -226,6 +228,8 @@ class Net : public Entity { public: void setPosition(const Point& position); public: void materialize(); public: void unmaterialize(); + public: bool addAlias(const Name& name); + public: bool removeAlias(const Name& name); public: void merge(Net* net); // Others @@ -238,6 +242,7 @@ class Net : public Entity { public: virtual string _getTypeName() const {return _TName("Net");}; public: virtual string _getString() const; public: virtual Record* _getRecord() const; + public: NetMainName& _getMainName() { return _mainName; } public: ComponentSet& _getComponentSet() {return _componentSet;}; public: RubberSet& _getRubberSet() {return _rubberSet;}; public: Net* _getNextOfCellNetMap() const {return _nextOfCellNetMap;}; diff --git a/hurricane/src/hurricane/hurricane/NetAlias.h b/hurricane/src/hurricane/hurricane/NetAlias.h new file mode 100644 index 00000000..0924ccf7 --- /dev/null +++ b/hurricane/src/hurricane/hurricane/NetAlias.h @@ -0,0 +1,140 @@ +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2015-2015, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// +-----------------------------------------------------------------+ +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricane/NetAlias.h" | +// +-----------------------------------------------------------------+ + + +#ifndef HURRICANE_NET_ALIAS_H +#define HURRICANE_NET_ALIAS_H + +#include +#include +#include "hurricane/Name.h" + + +namespace Hurricane { + + class Record; + class Net; + class NetAliasName; + + +// ------------------------------------------------------------------- +// Class : "Hurricane::NetAliasHook". + + class NetAliasHook { + public: + bool isAttached () const; + virtual bool isMaster () const = 0; + virtual bool isSlave () const = 0; + virtual Name getName () const = 0; + virtual Net* getNet () const = 0; + NetAliasHook* getNext () const; + NetAliasHook* getPrevious () const; + NetAliasName* find ( const Name& ) const; + void attach ( NetAliasHook* ); + void detach (); + void detachAll (); + virtual std::string _getString () const = 0; + virtual Record* _getRecord () const; + public: + NetAliasHook (); + virtual ~NetAliasHook (); + private: + NetAliasHook ( const NetAliasHook& ); + NetAliasHook& operator= ( const NetAliasHook& ); + private: + NetAliasHook* _next; + }; + + +// ------------------------------------------------------------------- +// Class : "Hurricane::NetMainName". + + class NetMainName : public NetAliasHook { + public: + virtual bool isMaster () const; + virtual bool isSlave () const; + virtual Name getName () const; + virtual Net* getNet () const; + virtual std::string _getString () const; + void clear (); + public: + NetMainName ( Net* ); + virtual ~NetMainName (); + private: + NetMainName ( const NetMainName& ); + NetMainName& operator= ( const NetMainName& ); + private: + static ptrdiff_t _offset; + }; + + +// ------------------------------------------------------------------- +// Class : "Hurricane::NetAliasName". + + class NetAliasName : public NetAliasHook { + public: + class Less { + public: + inline bool operator() ( const NetAliasName* lhs, const NetAliasName* rhs ) const; + }; + public: + virtual bool isMaster () const; + virtual bool isSlave () const; + virtual Name getName () const; + virtual Net* getNet () const; + virtual std::string _getString () const; + virtual Record* _getRecord () const; + public: + NetAliasName ( Name ); + virtual ~NetAliasName (); + private: + NetAliasName ( const NetAliasName& ); + NetAliasName& operator= ( const NetAliasName& ); + private: + Name _name; + }; + + + inline bool NetAliasName::Less::operator() ( const NetAliasName* lhs + , const NetAliasName* rhs ) const + { return lhs->getName() < rhs->getName(); } + + + typedef std::set AliasNameSet; + + +} // Namespace Hurricane. + + +INSPECTOR_P_SUPPORT(Hurricane::NetAliasHook); +INSPECTOR_P_SUPPORT(Hurricane::NetMainName); +INSPECTOR_P_SUPPORT(Hurricane::NetAliasName); + +#endif // HURRICANE_NET_ALIAS_H diff --git a/hurricane/src/hurricane/hurricane/NetExternalComponents.h b/hurricane/src/hurricane/hurricane/NetExternalComponents.h index 2e3c04e5..5836812a 100644 --- a/hurricane/src/hurricane/hurricane/NetExternalComponents.h +++ b/hurricane/src/hurricane/hurricane/NetExternalComponents.h @@ -1,7 +1,6 @@ - // -*- C++ -*- // -// Copyright (c) BULL S.A. 2000-2013, All Rights Reserved +// Copyright (c) BULL S.A. 2000-2015, All Rights Reserved // // This file is part of Hurricane. // diff --git a/hurricane/src/isobar/PyNet.cpp b/hurricane/src/isobar/PyNet.cpp index 08ceca56..75323207 100644 --- a/hurricane/src/isobar/PyNet.cpp +++ b/hurricane/src/isobar/PyNet.cpp @@ -391,6 +391,53 @@ extern "C" { } + // --------------------------------------------------------------- + // Attribute Method : "PyNet_addAlias ()" + + static PyObject* PyNet_addAlias ( PyNet *self, PyObject* args ) + { + trace << "PyNet_addAlias()" << endl; + + HTRY + METHOD_HEAD ( "Net.addAlias()" ) + + char* name; + if (PyArg_ParseTuple(args,"s:Net.addAlias",args,name)) { + if (net->addAlias(Name(name))) Py_RETURN_TRUE; + } else { + PyErr_SetString( ConstructorError, "Bad parameters given to Net.addAlias()." ); + return NULL; + } + + HCATCH + + Py_RETURN_FALSE; + } + + + // --------------------------------------------------------------- + // Attribute Method : "PyNet_removeAlias ()" + + static PyObject* PyNet_removeAlias ( PyNet *self, PyObject* args ) + { + trace << "PyNet_removeAlias()" << endl; + + HTRY + METHOD_HEAD ( "Net.removeAlias()" ) + + char* name; + if (PyArg_ParseTuple(args,"s:Net.removeAlias",args,name)) { + if (net->removeAlias(Name(name))) Py_RETURN_TRUE; + } else { + PyErr_SetString( ConstructorError, "Bad parameters given to Net.removeAlias()." ); + return NULL; + } + + HCATCH + + Py_RETURN_FALSE; + } + // --------------------------------------------------------------- // Attribute Method : "PyNet_setPosition ()" @@ -429,7 +476,6 @@ extern "C" { PyErr_SetString (ConstructorError, "invalid number of parameters for Net.merge."); return NULL; } - HCATCH Py_RETURN_NONE; @@ -470,6 +516,8 @@ extern "C" { , { "setType" , (PyCFunction)PyNet_setType , METH_VARARGS, "set the type of the net." } , { "setDirection" , (PyCFunction)PyNet_setDirection , METH_VARARGS, "set the direction of the net." } , { "setPosition" , (PyCFunction)PyNet_setPosition , METH_VARARGS, "set the X,Y location of the net." } + , { "addAlias" , (PyCFunction)PyNet_addAlias , METH_VARARGS, "Add an alias name to the net." } + , { "removeAlias" , (PyCFunction)PyNet_removeAlias , METH_VARARGS, "Remove an alias name from the net." } , { "merge" , (PyCFunction)PyNet_merge , METH_VARARGS, "Merges the net to the net which keeps its characteristics (arity, global, external and direction)." } , { "destroy" , (PyCFunction)PyNet_destroy , METH_NOARGS , "Destroy associated hurricane object, the python object remains." } , {NULL, NULL, 0, NULL} /* sentinel */ diff --git a/kite/src/NegociateWindow.cpp b/kite/src/NegociateWindow.cpp index acdf7b8b..3427bdd7 100644 --- a/kite/src/NegociateWindow.cpp +++ b/kite/src/NegociateWindow.cpp @@ -387,7 +387,7 @@ namespace Kite { _eventHistory.clear(); _eventQueue.load( _segments ); - + cmess2 << " " << endl; if (inltrace(500)) _eventQueue.dump(); size_t count = 0; @@ -396,11 +396,14 @@ namespace Kite { RoutingEvent* event = _eventQueue.pop(); if (tty::enabled()) { - cmess2 << " " << tty::cr; + cmess2 << " " << tty::cr; cmess2.flush (); } else { - cmess2 << " getEventLevel() << ":" << event->getPriority() << "> " << event->getSegment() @@ -428,6 +431,8 @@ namespace Kite { } } _eventQueue.commit(); + cmess2 << " " << endl; count = 0; //_eventQueue.prepareRepair(); @@ -435,11 +440,14 @@ namespace Kite { RoutingEvent* event = _eventQueue.pop(); if (tty::enabled()) { - cmess2 << " " << tty::cr; + cmess2 << " " + << setfill(' ') << tty::reset << tty::cr; cmess2.flush(); } else { - cmess2 << " getEventLevel() << ":" << event->getPriority() << "> " << event->getSegment() diff --git a/kite/src/kite/RoutingEventQueue.h b/kite/src/kite/RoutingEventQueue.h index 2bbebeb5..b1eb488d 100644 --- a/kite/src/kite/RoutingEventQueue.h +++ b/kite/src/kite/RoutingEventQueue.h @@ -1,7 +1,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2013, All Rights Reserved +// Copyright (c) UPMC 2008-2015, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | diff --git a/unicorn/src/cgt.py b/unicorn/src/cgt.py index 7360693c..9862475a 100755 --- a/unicorn/src/cgt.py +++ b/unicorn/src/cgt.py @@ -88,6 +88,7 @@ if __name__ == '__main__': parser = optparse.OptionParser(usage) parser.add_option( '-c', '--cell' , type='string' , dest='cell' , help='The name of the cell to load, whithout extension.') parser.add_option( '--acm-sigda-89' , type='string' , dest='acmSigdaName' , help='An ACM/SIGDA 89 bench name to load, whithout extension.') + parser.add_option( '--blif' , type='string' , dest='blifName' , help='A Blif (Yosys) design name to load, whithout extension.') parser.add_option( '--ispd-05' , type='string' , dest='ispd05name' , help='An ISPD 05 bench (placement) name to load, whithout extension.') parser.add_option( '--script' , type='string' , dest='script' , help='Run a Python or Stratus script.') parser.add_option( '-v', '--verbose' , action='store_true', dest='verbose' , help='First level of verbosity.') @@ -147,6 +148,8 @@ if __name__ == '__main__': cell = CRL.AcmSigda.load(options.acmSigdaName) elif options.ispd05name: cell = CRL.Ispd05.load(options.ispd05name) + elif options.blifName: + cell = CRL.Blif.load(options.blifName) elif options.cell: cell = af.getCell(options.cell, CRL.Catalog.State.Views) else: