Support for Net alias names. Blif parser enhancements.

* New: In Hurricane, In Net & Cell, support for Net aliases names.
    Use a structure based on a simple ring of NetAliasHook. The Net
    holds a global map, sorted by names of all the aliases of all Nets.
    Elements NetAliasesHook of the map are slaves of ring whose master
    is an attribute of the Net (it is *not* in the map, as the primary
    name of the Net).
      In case of merge, the aliases of both Nets are merged and the
    name of the merged one become an alias.
      The Cell::getNet() looks in both the Net map and the aliases to
    find a Net by name.
* Bug: In CRL Core, in coriolisInit.py, reoder the loading of the
    configuration files so the real technology is read as early as
    possible to set up the <gridsPerLambda> factor before any lambda
    is actually computed...
* Bug: In CRL Core, in AcmSigda, do not try to fed the file when it
    has failed to be opened. Throw a clean exception instead.
* New: In CRL Core, in Toolbox, add a NamingScheme object to convert
    a design into VHDL compliant names (mainly from Blif/Verilog).
    This is extensible in any case.
* New: In CRL Core, in BlifParser, slightly more informative warning
    messages. Align the loading progress information on the other
    parsers.
      Add a capability to select which component of the design will
    be returned, if there are more than one. Use the "." as separator.
    For exemple you can request "Processor.Alu", which will load
    the "Alu" component from the design in "Processor.blif".
      To be able to save a Blif loaded design, systematically convert
    all the name for VHDL compliance, as it is the format used by
    the Coriolis native files (vst).
      Export the Blif parser to the Python interface.
* New: In Kite, In NegociateWindow, add a counter of the number of
    remaining events. Gives an idea of the ETA...
* New: In Unicorn, in cgt.by, add an option to load a Blif design from
    the command line.
* New: In Cumulus, new RSave plugin to save both netlist & layout.
    Partly redundant with the previous one. Have to better organize
    that later.
This commit is contained in:
Jean-Paul Chaput 2015-04-16 15:40:02 +02:00
parent 2cbb072e6c
commit ef9936e87c
33 changed files with 1330 additions and 319 deletions

View File

@ -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'] = \

View File

@ -0,0 +1,26 @@
# -*- Mode:Python; explicit-buffer-name: "plugins.conf<cmos>" -*-
#
# 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')
)

View File

@ -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) ]

View File

@ -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

View File

@ -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 );

View File

@ -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))

View File

@ -21,18 +21,19 @@
#include <vector>
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<model> models;
ParserState state = EXT;
bool hasName;
string line;
vector<string> current_names;
while(getline(ccell, line)){
istringstream linestream(line);
vector<string> 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<model> models;
ParserState state = EXT;
bool hasName = true;
string line;
vector<string> current_names;
while(getline(ccell, line)){
istringstream linestream(line);
vector<string> 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.size() ; ++iname ) {
if (iname) mess << ", ";
mess << "\'" << current_names[iname] << "\'";
}
cerr << Warning(mess.str()) << endl;
}
mess << "\n";
cerr << Warning(mess.str());
else{
// Name statement is an alias: the second signal will map to the first
models.back().aliases.push_back(pair<string, string>(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<string, string>(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<Net::Direction::Code>(D | it->second);
}
else{
models.back().pins.insert(pair<string, Net::Direction>(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<string, string>(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<Net::Direction::Code>(D | it->second);
}
else{
ostringstream mess;
mess << "Unable to parse the subckt pin specification <"
<< token << ">\n";
Error(mess.str());
models.back().pins.insert(pair<string, Net::Direction>(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<string, string>(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<Cell*> 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<string> 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; i<models.size(); ++i){
cmess2 << " " << tab++ << "+ " << models[i].name << " [instances]" << endl;
auto const & M = models[i];
Cell * design = model_cells[i];
for(size_t j=0; j<M.subcircuits.size(); ++j){
auto & S = M.subcircuits[j];
ostringstream subckt_name;
subckt_name << "subckt_" << j;
Cell * cell = framework->getCell(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<Cell*> 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<string> 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; i<models.size(); ++i){
cmess2 << "Handling model " << models[i].name << endl;
auto const & M = models[i];
Cell * design = model_cells[i];
for(int j=0; j<M.subcircuits.size(); ++j){
auto & S = M.subcircuits[j];
ostringstream subckt_name;
subckt_name << "subckt_" << j;
Cell * cell = framework->getCell(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.

View File

@ -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 <functional>
#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

View File

@ -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 <cctype>
#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<vlogName.size() ; ++i ) {
if (vlogName[i] == '(') ++parCount;
if (vlogName[i] == '[') ++parCount;
}
char leftPar = (parCount > 1) ? '_' : '(';
char rightPar = (parCount > 1) ? '_' : ')';
for ( size_t i=0 ; i<vlogName.size() ; ++i ) {
char translated = tolower( vlogName[i] );
if ( (i == 0) and (isdigit(translated)) )
vhdlName += 'N';
if (translated == '\\') translated = '_';
if (translated == '$' ) translated = '_';
if (translated == '?' ) translated = '_';
if (translated == ':' ) translated = '_';
if (translated == '[' ) translated = leftPar;
if (translated == ']' ) translated = rightPar;
if (translated == '_') {
if (i == 0 ) continue;
if (i == vlogName.size()-1) break;
if (vhdlName.back() == '_') continue;
}
vhdlName += translated;
}
return Name(vhdlName);
}
void NamingScheme::toVhdl ( Cell* topCell, unsigned int flags )
{
if (not topCell) return;
converter_t converter = nullptr;
if (flags & FromVerilog)
converter = vlogToVhdl;
if (converter == nullptr) return;
topCell->setName( converter(topCell->getName()) );
vector<Net*> nets;
forEach ( Net*, inet, topCell->getNets() ) nets.push_back( *inet );
for ( auto net : nets ) net->setName( converter( net->getName() ) );
vector<Instance*> instances;
set<Cell*> 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.

View File

@ -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<vlogName.size() ; ++i ) {
char translated = vlogName[i];
if (translated == '\\') translated = '_';
if (translated == '$' ) translated = '_';
if (translated == '?' ) translated = '_';
if (translated == '[' ) translated = '(';
if (translated == ']' ) translated = ')';
vhdlName += translated;
}
return Name(vhdlName);
}
} // Anonymous namespace.
namespace CRL {
using Hurricane::ForEachIterator;
using Hurricane::Net;
using Hurricane::Cell;
using Hurricane::Instance;
void toVhdlName ( Cell* topCell, unsigned int flags )
{
if (not topCell) return;
vector<Net*> nets;
forEach ( Net*, inet, topCell->getNets() ) nets.push_back( *inet );
for ( auto net : nets ) net->setName( vlogToVhdl( inet->getName() ) );
vector<Instance*> instances;
set<Cell*> 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.

View File

@ -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}

View File

@ -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 <string>
#include <sstream>
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.

View File

@ -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 , "<Environment>" , 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 ();

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 <coriolis> 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

View File

@ -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

View File

@ -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;
}

View File

@ -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"

View File

@ -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
// ***********************
{

View File

@ -17,6 +17,7 @@
// not, see <http://www.gnu.org/licenses/>.
// ****************************************************************************************************
#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<NetAliasName*>( 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;
}

View File

@ -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
// <http://www.gnu.org/licenses/>.
//
// +-----------------------------------------------------------------+
// | 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<NetAliasName*>( dynamic_cast<const NetAliasName*>(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<NetAliasName*> slaves;
for ( NetAliasHook* current=getNext() ; current->getNext()!=this ; current=current->getNext() ) {
slaves.push_back( dynamic_cast<NetAliasName*>(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 "<NetMainName " + getString(getName()) + ">"; }
// -------------------------------------------------------------------
// 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 "<NetAliasName " + getString(getName()) + " <> " + getString(getNet()->getName()) + ">"; }
Record* NetAliasName::_getRecord () const
{
Record* record = NetAliasHook::_getRecord();
if (record) {
record->add ( getSlot("_name", &_name) );
}
return record;
}
} // Hurricane namespace.

View File

@ -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
// ********

View File

@ -31,7 +31,7 @@ class Component;
// ****************************************************************************************************
// Hook declaration
// ****************************************************************************************************
class Hook {
// *********

View File

@ -77,6 +77,7 @@ class Name {
// **********
public: bool isEmpty() const;
public: size_t size() const;
// Others
// ******

View File

@ -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;};

View File

@ -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
// <http://www.gnu.org/licenses/>.
//
// +-----------------------------------------------------------------+
// | 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 <string>
#include <set>
#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<NetAliasName*,NetAliasName::Less> AliasNameSet;
} // Namespace Hurricane.
INSPECTOR_P_SUPPORT(Hurricane::NetAliasHook);
INSPECTOR_P_SUPPORT(Hurricane::NetMainName);
INSPECTOR_P_SUPPORT(Hurricane::NetAliasName);
#endif // HURRICANE_NET_ALIAS_H

View File

@ -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.
//

View File

@ -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 <net> to the net <this> 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 */

View File

@ -387,7 +387,7 @@ namespace Kite {
_eventHistory.clear();
_eventQueue.load( _segments );
cmess2 << " <queue:" << right << setw(8) << setfill('0') << _eventQueue.size() << ">" << endl;
if (inltrace(500)) _eventQueue.dump();
size_t count = 0;
@ -396,11 +396,14 @@ namespace Kite {
RoutingEvent* event = _eventQueue.pop();
if (tty::enabled()) {
cmess2 << " <event:" << tty::bold << right << setw(7) << setfill('0')
<< RoutingEvent::getProcesseds() << setfill(' ') << tty::reset << ">" << tty::cr;
cmess2 << " <event:" << tty::bold << right << setw(8) << setfill('0')
<< RoutingEvent::getProcesseds() << tty::reset
<< " remains:" << right << setw(8) << setfill('0')
<< _eventQueue.size()
<< setfill(' ') << tty::reset << ">" << tty::cr;
cmess2.flush ();
} else {
cmess2 << " <event:" << right << setw(7) << setfill('0')
cmess2 << " <event:" << right << setw(8) << setfill('0')
<< RoutingEvent::getProcesseds() << setfill(' ') << " "
<< event->getEventLevel() << ":" << event->getPriority() << "> "
<< event->getSegment()
@ -428,6 +431,8 @@ namespace Kite {
}
}
_eventQueue.commit();
cmess2 << " <repair.queue:" << right << setw(8) << setfill('0')
<< _eventQueue.size() << ">" << endl;
count = 0;
//_eventQueue.prepareRepair();
@ -435,11 +440,14 @@ namespace Kite {
RoutingEvent* event = _eventQueue.pop();
if (tty::enabled()) {
cmess2 << " <repair.event:" << tty::bold << setw(7) << setfill('0')
<< RoutingEvent::getProcesseds() << setfill(' ') << tty::reset << ">" << tty::cr;
cmess2 << " <repair.event:" << tty::bold << setw(8) << setfill('0')
<< RoutingEvent::getProcesseds() << tty::reset
<< " remains:" << right << setw(8) << setfill('0')
<< _eventQueue.size() << ">"
<< setfill(' ') << tty::reset << tty::cr;
cmess2.flush();
} else {
cmess2 << " <repair.event:" << setw(7) << setfill('0')
cmess2 << " <repair.event:" << setw(8) << setfill('0')
<< RoutingEvent::getProcesseds() << setfill(' ') << " "
<< event->getEventLevel() << ":" << event->getPriority() << "> "
<< event->getSegment()

View File

@ -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 |

View File

@ -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: