* ./crlcore:

- New: In AllianceFramework constructor, now look for an XML configuration
        file in the current directory (<cwd>/.environment.alliance.xml).
    - New: DefParser, DefDriver & LefDriver are replaced by DefImport, DefExport
        and LefExport (resp.). LEF/DEF parser/driver are no longer integrated
        in among Alliance ones due to too much difference in data organisation.
        Instead they are build as Import/Export utilities.
    - New: Iccad04Lefdef import the ICCAD'04 benchmarks into the SxLib format
        suitable for Knik/Kite. They are derived from the ISPD'98 (ibm01--ibm18)
        benchmarks. Many corrections are applieds to ensure a more realistic
        representation.
          Generate a new library from the LEF file "on the fly".
    - New: Ispd04Bookshelf import the ISPD'04 benchmarks in SxLib from bookshelf.
        Thoses benchmarks can be placeds whith fastplace. Unfortunatly fastplace
        do not manage blocks and reduce them to standard cell which is not
        usable for detailed placement. Too bad, the parser exists still.
          Make uses of the new vlsisapd/bookshelf parser. A whole library is
        generated "on the fly" on the basis of "one node, one Cell" (so we have
        a bijection between Cell and Instance). The result of this parsing is
        different from the one of the stand-alone ispd04 binary in the sense it
        fits the circuit to the SxLib gauge thus changing the routing capacity:
        from 16 to 20.
    - Change: In ApDriver, the lookup modify the lookup table for matching
        Alliance layers against Hurricane ones, "OBSTACLEx" became "BLOCKAGEx".
    - Change: In default <enviromnent.alliance.xml> adds the name of the
        blockage net: "^obstacleNet$". Some work over the coherency of the
        blockage managment remains to be done.
    - Change: In AllianceFramework, partial rewrite of the get/creation of
        AllianceLibrary to fit the requirements of the "on the fly" generation
        from the benchmarks loaders. And correct some bugs by the way.
    - Change: In Environment, suppress any reference to LEF technology as LEF/
        DEF is now used as import/exports.
    - Bug: In VstDriver, perform only one lookup for global signals among all
        nets and not for each instance master cell. That was making the driver
        quadratic! Now it's linear and reasonably fast.
This commit is contained in:
Jean-Paul Chaput 2010-08-18 20:22:10 +00:00
parent dd405e619f
commit 4426fc4f0c
26 changed files with 3815 additions and 268 deletions

View File

@ -1,4 +1,3 @@
install ( FILES FindCORIOLIS.cmake
FindOPENACCESS.cmake
FindLEFDEF.cmake
DESTINATION share/cmake/Modules )

View File

@ -1,119 +0,0 @@
# - Find the LEF/DEF includes and libraries.
# The following variables are set if LEF/DEF is found. If LEF/DEF is not
# found, LEFDEF_FOUND is set to false.
# LEFDEF_FOUND - True when LEF/DEF is found.
# LEFDEF_INCLUDE_DIR - the path to where the LEF/DEF include files are.
# LEFDEF_LIBRARIES - The path to where the LEF/DEF library files are.
#
# The DEF C API library: LEFDEF_CDEF_LIBRARY
# LEFDEF_CDEF_LIBRARY_RELEASE
# LEFDEF_CDEF_LIBRARY_DEBUG
#
# The DEF C API library (zlib) : LEFDEF_ZCDEF_LIBRARY
# LEFDEF_ZCDEF_LIBRARY_RELEASE
# LEFDEF_ZCDEF_LIBRARY_DEBUG
#
# The DEF C++ API library: LEFDEF_DEF_LIBRARY
# LEFDEF_DEF_LIBRARY_RELEASE
# LEFDEF_DEF_LIBRARY_DEBUG
#
# The DEF C++ API library (zlib) : LEFDEF_ZDEF_LIBRARY
# LEFDEF_ZDEF_LIBRARY_RELEASE
# LEFDEF_ZDEF_LIBRARY_DEBUG
#
# The LEF C API library: LEFDEF_CLEF_LIBRARY
# LEFDEF_CLEF_LIBRARY_RELEASE
# LEFDEF_CLEF_LIBRARY_DEBUG
#
# The LEF C API library (zlib) : LEFDEF_ZCLEF_LIBRARY
# LEFDEF_ZCLEF_LIBRARY_RELEASE
# LEFDEF_ZCLEF_LIBRARY_DEBUG
#
# The LEF C++ API library: LEFDEF_LEF_LIBRARY
# LEFDEF_LEF_LIBRARY_RELEASE
# LEFDEF_LEF_LIBRARY_DEBUG
#
# The LEF C++ API library (zlib) : LEFDEF_ZLEF_LIBRARY
# LEFDEF_ZLEF_LIBRARY_RELEASE
# LEFDEF_ZLEF_LIBRARY_DEBUG
macro ( _find_lefdef_lib varname libname )
find_library ( LEFDEF_${varname}_LIBRARY_RELEASE NAMES ${libname} PATHS ${LEFDEF_LIBRARY_DIR} )
find_library ( LEFDEF_${varname}_LIBRARY_DEBUG NAMES ${libname}_Debug PATHS ${LEFDEF_LIBRARY_DIR} )
if ( LEFDEF_${varname}_LIBRARY_RELEASE AND NOT LEFDEF_${varname}_LIBRARY_DEBUG )
set ( LEFDEF_${varname}_LIBRARY_DEBUG ${LEFDEF_${varname}_LIBRARY_RELEASE}
CACHE STRING "Path to a library" FORCE )
endif ( LEFDEF_${varname}_LIBRARY_RELEASE AND NOT LEFDEF_${varname}_LIBRARY_DEBUG )
if ( LEFDEF_${varname}_LIBRARY_DEBUG AND NOT LEFDEF_${varname}_LIBRARY_RELEASE )
set ( LEFDEF_${varname}_LIBRARY_RELEASE LEFDEF_${varname}_LIBRARY_DEBUG
CACHE STRING "Path to a library" FORCE )
endif ( LEFDEF_${varname}_LIBRARY_DEBUG AND NOT LEFDEF_${varname}_LIBRARY_RELEASE )
if ( LEFDEF_${varname}_LIBRARY_RELEASE )
list ( APPEND LEFDEF_LIBRARIES "optimized" ${LEFDEF_${varname}_LIBRARY_RELEASE}
"debug" ${LEFDEF_${varname}_LIBRARY_DEBUG} )
set ( LEFDEF_${varname}_LIBRARY_FOUND 1 )
mark_as_advanced ( LEFDEF_${varname}_LIBRARY_RELEASE
LEFDEF_${varname}_LIBRARY_DEBUG )
else ( LEFDEF_${varname}_LIBRARY_RELEASE )
set ( LEFDEF_FOUND "NO" )
endif ( LEFDEF_${varname}_LIBRARY_RELEASE )
endmacro ( _find_lefdef_lib )
set ( LEFDEF_INCLUDE_DIR_DESCRIPTION "directory containing the LEF/DEF include files. E.g /opt/lefdef-5.6/include" )
set ( LEFDEF_LIBRARY_DIR_DESCRIPTION "directory containing the LEF/DEF library files. E.g /opt/lefdef-5.6/lib" )
set ( LEFDEF_DIR_MESSAGE "Set the LEFDEF_INCLUDE_DIR cmake cache entry to the ${LEFDEF_INCLUDE_DIR_DESCRIPTION}" )
# Don't even bother under Win32
if ( UNIX )
set ( LEFDEF_FOUND "YES" )
set ( LEFDEF_SEARCH_PATH $ENV{LEFDEF_TOP}
"/opt/lefdef-5.6"
"/opt/lefdef-5.7"
"/opt/lefdef")
set ( LEFDEF_LIBRARIES "" )
set ( LEFDEF_LIBRARY_SEARCH_PATH "" )
foreach ( element ${LEFDEF_SEARCH_PATH} )
list ( APPEND LEFDEF_LIBRARY_SEARCH_PATH "${element}/lib" )
endforeach ( element ${LEFDEF_SEARCH_PATH} )
find_path ( LEFDEF_INCLUDE_DIR NAMES "defiDefs.h"
PATHS ${LEFDEF_SEARCH_PATH}
PATH_SUFFIXES "include"
DOC "The ${LEFDEF_INCLUDE_DIR_DESCRIPTION}" )
find_path ( LEFDEF_LIBRARY_DIR NAMES "libdef.a" "libdef_Debug.a"
PATHS ${LEFDEF_LIBRARY_SEARCH_PATH}
DOC "The ${LEFDEF_LIBRARY_DIR_DESCRIPTION}" )
if ( LEFDEF_INCLUDE_DIR AND LEFDEF_LIBRARY_DIR )
_find_lefdef_lib ( "CDEF" "cdef" )
_find_lefdef_lib ( "ZCDEF" "cdefzlib" )
_find_lefdef_lib ( "DEF" "def" )
_find_lefdef_lib ( "ZDEF" "defzlib" )
_find_lefdef_lib ( "CLEF" "clef" )
_find_lefdef_lib ( "ZCLEF" "clefzlib" )
_find_lefdef_lib ( "LEF" "lef" )
_find_lefdef_lib ( "ZLEF" "lefzlib" )
else ( LEFDEF_INCLUDE_DIR AND LEFDEF_LIBRARY_DIR )
set ( LEFDEF_FOUND "NO" )
endif ( LEFDEF_INCLUDE_DIR AND LEFDEF_LIBRARY_DIR )
mark_as_advanced ( LEFDEF_INCLUDE_DIR LEFDEF_LIBRARY_DIR LEFDEF_LIBRARIES )
if ( LEFDEF_FOUND )
add_definitions ( -DHAVE_LEFDEF )
if ( NOT LEFDEF_FIND_QUIETLY )
message ( STATUS "Found LEF/DEF" )
endif ( NOT LEFDEF_FIND_QUIETLY )
else ( LEFDEF_FOUND )
if ( LEFDEF_FIND_REQUIRED )
message ( STATUS "LEF/DEF libraries and/or includes NOT found!" )
endif ( LEFDEF_FIND_REQUIRED )
endif ( LEFDEF_FOUND )
endif ( UNIX )

View File

@ -8,9 +8,6 @@
<real>
<config>${CORIOLIS_TOP}/etc/coriolis2/technology.cmos130.s2r.xml</config>
</real>
<lef>
<config>${CORIOLIS_TOP}/etc/coriolis2/cmos.lef</config>
</lef>
<display>
<config>${CORIOLIS_TOP}/etc/coriolis2/display.xml</config>
</display>
@ -46,5 +43,6 @@
<vdd>vdd</vdd>
<vss>vss</vss>
<clock>^do_not_find_ck$</clock>
<obstacle>^obstacleNet$</obstacle>
</signals>
</environment>

View File

@ -70,10 +70,12 @@
<parameter id="mauka.annealingRowMult" type="percentage" value="5" min="0"/>
<!-- Katabatic -->
<parameter id="katabatic.saturateRatio" type="percentage" value="80"/>
<parameter id="katabatic.saturateRp" type="int" value="8"/>
<parameter id="katabatic.globalLengthThreshold" type="int" value="1450"/>
<!-- Kite -->
<parameter id="kite.edgeCapacity" type="percentage" value="65" min="0" max="100"/>
<parameter id="kite.expandStep" type="percentage" value="100" min="0" max="100"/>
<parameter id="kite.globalMinBreak" type="int" value="1450"/>
<parameter id="kite.ripupCost" type="int" value="3" min="0"/>
<parameter id="kite.borderRipupLimit" type="int" value="26" min="1"/>
<parameter id="kite.strapRipupLimit" type="int" value="16" min="1"/>
@ -127,19 +129,21 @@
<tab name="kite">
<widget type="title" label="Katabatic - Routing Database"/>
<widget id="katabatic.saturateRatio" label="Saturate Ratio (%)" column="0"/>
<widget id="katabatic.saturateRp" label="Saturate RoutingPad" column="0"/>
<widget id="katabatic.globalLengthThreshold" label="Global Length Threshold" column="0"/>
<widget type="rule"/>
<widget type="title" label="Kite - Detailed Router"/>
<widget id="kite.edgeCapacity" label="Edge Capacity (%)" column="0"/>
<widget id="kite.expandStep" label="Expand Step (%)" column="0"/>
<widget id="kite.eventsLimit" label="Events Limit" column="0"/>
<widget id="kite.ripupCost" label="Ripup Cost" column="1" spinbox="true"/>
<widget id="kite.edgeCapacity" label="Edge Capacity (%)" column="0"/>
<widget id="kite.expandStep" label="Expand Step (%)" column="0"/>
<widget id="kite.globalMinBreak" label="Global Length Min Break" column="0"/>
<widget id="kite.eventsLimit" label="Events Limit" column="0"/>
<widget id="kite.ripupCost" label="Ripup Cost" column="1" spinbox="true"/>
<widget type="section" label="Ripup Limits" column="1"/>
<widget id="kite.borderRipupLimit" label="Borders" column="1" spinbox="true"/>
<widget id="kite.strapRipupLimit" label="Straps" column="1" spinbox="true"/>
<widget id="kite.localRipupLimit" label="Locals" column="1" spinbox="true"/>
<widget id="kite.globalRipupLimit" label="Globals" column="1" spinbox="true"/>
<widget id="kite.longGlobalRipupLimit" label="Long Globals" column="1" spinbox="true"/>
<widget id="kite.borderRipupLimit" label="Borders" column="1" spinbox="true"/>
<widget id="kite.strapRipupLimit" label="Straps" column="1" spinbox="true"/>
<widget id="kite.localRipupLimit" label="Locals" column="1" spinbox="true"/>
<widget id="kite.globalRipupLimit" label="Globals" column="1" spinbox="true"/>
<widget id="kite.longGlobalRipupLimit" label="Long Globals" column="1" spinbox="true"/>
<widget type="rule"/>
</tab>
<tab name="Stratus1">

View File

@ -23,6 +23,7 @@
// x-----------------------------------------------------------------x
#include <unistd.h>
#include "hurricane/Warning.h"
#include "hurricane/Technology.h"
#include "hurricane/DataBase.h"
@ -78,6 +79,11 @@ namespace CRL {
string userEnvironment = Environment::getEnv ( "HOME", "<HomeDirectory>" );
_environment.loadFromXml ( userEnvironment+"/.environment.alliance.xml", false );
char cwd[1024];
getcwd ( cwd, 1024 );
string cwdEnvironment = cwd;
_environment.loadFromXml ( cwdEnvironment+"/.environment.alliance.xml", false );
SymbolicTechnologyParser::load ( db, _environment.getSYMBOLIC_TECHNOLOGY() );
RealTechnologyParser::load ( db, _environment.getREAL_TECHNOLOGY() );
GraphicsParser::load ( _environment.getDISPLAY() );
@ -85,9 +91,9 @@ namespace CRL {
if ( !_environment.getDisplayStyle().empty() )
Graphics::setStyle ( _environment.getDisplayStyle() );
bool hasCatalog;
SearchPath& LIBRARIES = _environment.getLIBRARIES ();
Library* rootLibrary = db->getRootLibrary ();
unsigned int flags = InSearchPath;
SearchPath& LIBRARIES = _environment.getLIBRARIES ();
Library* rootLibrary = db->getRootLibrary ();
cmess2 << " o Creating Alliance Framework root library." << endl;
if ( !rootLibrary )
@ -99,15 +105,13 @@ namespace CRL {
cmess2 << " o Loading libraries (working first)." << endl;
for ( unsigned i=0 ; i<LIBRARIES.getSize() ; i++ ) {
Name libraryName = LIBRARIES[i];
createLibrary ( LIBRARIES[i], flags );
_libraries.push_back ( getAllianceLibrary(libraryName,hasCatalog) );
cmess2 << " - \"" << libraryName._getString() << "\"";
cmess2 << " - \"" << LIBRARIES[i] << "\"";
cmess2.flush();
if ( hasCatalog ) cmess2 << " [have CATAL]." << endl;
else cmess2 << " [no CATAL]" << endl;
if ( flags&HasCatalog ) cmess2 << " [have CATAL]." << endl;
else cmess2 << " [no CATAL]" << endl;
}
// Temporary: create the SxLib routing gauge.
@ -187,6 +191,35 @@ namespace CRL {
, DbU::lambda(2) // Wire width.
, DbU::lambda(3) // Via width.
) );
routingLayer = technology->getLayer("METAL6");
if ( routingLayer == NULL ) break;
sxlibRg->addLayerGauge ( RoutingLayerGauge::create( routingLayer
, Constant::Horizontal
, Constant::Default
, 5 // Depth (?).
, 0 // Density.
, DbU::lambda(0) // Offset.
, DbU::lambda(5) // Pitch.
, DbU::lambda(2) // Wire width.
, DbU::lambda(3) // Via width.
) );
#if 0
routingLayer = technology->getLayer("METAL7");
if ( routingLayer == NULL ) break;
sxlibRg->addLayerGauge ( RoutingLayerGauge::create( routingLayer
, Constant::Vertical
, Constant::Default
, 7 // Depth (?).
, 0 // Density.
, DbU::lambda(0) // Offset.
, DbU::lambda(5) // Pitch.
, DbU::lambda(2) // Wire width.
, DbU::lambda(3) // Via width.
) );
#endif
}
addRoutingGauge ( sxlibRg );
@ -244,34 +277,37 @@ namespace CRL {
}
AllianceLibrary* AllianceFramework::getAllianceLibrary ( const Name &path , bool &flag )
AllianceLibrary* AllianceFramework::getAllianceLibrary ( unsigned index )
{
if ( index >= _libraries.size() )
return NULL;
return _libraries[index];
}
AllianceLibrary* AllianceFramework::getAllianceLibrary ( const Name &path, unsigned int& flags )
{
string spath = getString ( path );
size_t slash = spath.rfind ( '/' );
string sname = spath.substr ( (slash!=string::npos)?slash+1:0 );
AllianceLibrary* library = new AllianceLibrary ( path, Library::create(getParentLibrary(),sname) );
string catalog = spath + "/" + _environment.getCATALOG();
for ( size_t ilib=0 ; ilib<_libraries.size() ; ++ilib ) {
if ( _libraries[ilib]->getLibrary()->getName() == sname )
return _libraries[ilib];
}
flag = false;
if ( _catalog.loadFromFile(catalog,library->getLibrary()) ) flag = true;
return (flags&CreateLibrary) ? createLibrary ( getString(path), flags ) : NULL;
}
ParserFormatSlot& parser = _parsers.getParserSlot ( spath, Catalog::State::Physical, _environment );
if ( !parser.loadByLib() ) return library;
size_t base = spath.find_last_of ( '/' );
if ( base == spath.npos ) return library;
string file = spath.substr(base+1,spath.size()-base);
// Load the whole library.
if ( ! _readLocate(file,Catalog::State::State::Logical,true) ) return library;
// Call the parser function.
(parser.getParsLib())( _environment.getLIBRARIES().getSelected() , library->getLibrary() , _catalog );
return library;
AllianceLibrary* AllianceFramework::getAllianceLibrary ( Library* library )
{
for ( size_t ilib=0 ; ilib<_libraries.size() ; ++ilib ) {
if ( _libraries[ilib]->getLibrary() == library ) return _libraries[ilib];
}
return NULL;
}
@ -336,19 +372,97 @@ namespace CRL {
}
Cell* AllianceFramework::createCell ( const string& name )
AllianceLibrary* AllianceFramework::createLibrary ( const string& path, unsigned int& flags )
{
size_t slash = path.rfind ( '/' );
string libName = path.substr ( (slash!=string::npos)?slash+1:0 );
flags &= ~HasCatalog;
AllianceLibrary* library = getAllianceLibrary ( libName, flags );
if ( library != NULL ) {
cerr << Warning("AllianceFramework::createLibrary(): Attempt to re-create <%s>, using already existing."
,libName.c_str()) << endl;
return library;
}
SearchPath& LIBRARIES = _environment.getLIBRARIES ();
if ( not (flags & InSearchPath) ) LIBRARIES.prepend ( path );
else LIBRARIES.select ( path );
library = new AllianceLibrary ( path, Library::create(getParentLibrary(),libName) );
AllianceLibraries::iterator ilib = _libraries.begin();
for ( size_t i=0 ; i<LIBRARIES.getIndex() ; ++i, ++ilib );
_libraries.insert ( ilib, library );
string catalog = path + "/" + _environment.getCATALOG();
if ( _catalog.loadFromFile(catalog,library->getLibrary()) ) flags |= HasCatalog;
ParserFormatSlot& parser = _parsers.getParserSlot ( path, Catalog::State::Physical, _environment );
if ( not parser.loadByLib() ) return library;
if ( slash == path.npos ) return library;
string file = path.substr(slash+1,path.size()-slash);
// Load the whole library.
if ( ! _readLocate(file,Catalog::State::State::Logical,true) ) return library;
// Call the parser function.
(parser.getParsLib())( _environment.getLIBRARIES().getSelected() , library->getLibrary() , _catalog );
return library;
}
void AllianceFramework::saveLibrary ( Library* library )
{
if ( library == NULL ) return;
AllianceLibrary* alibrary = getAllianceLibrary ( library );
if ( alibrary == NULL ) {
throw Error("AllianceFramework::saveLibrary(): Cannot save non-Alliance library <%s>."
,getString(library->getName()).c_str());
}
saveLibrary ( alibrary );
}
void AllianceFramework::saveLibrary ( AllianceLibrary* library )
{
if ( library == NULL ) return;
bfs::path libPath ( getString(library->getPath()) );
if ( not bfs::exists(libPath) ) {
bfs::create_directory(libPath);
}
forEach ( Cell*, icell, library->getLibrary()->getCells() ) {
saveCell ( *icell, Catalog::State::Views );
}
}
Cell* AllianceFramework::createCell ( const string& name, AllianceLibrary* library )
{
Catalog::State* state = _catalog.getState ( name );
// The cell is not in the CATAL : add an entry.
if ( state == NULL ) state = _catalog.getState ( name, true );
if ( library == NULL )
library = _libraries[0];
if ( !state->getCell() ) {
state->setPhysical ( true );
state->setLogical ( true );
state->setDepth ( 1 );
state->setCell ( Cell::create ( _libraries[0]->getLibrary() , name ) );
state->setCell ( Cell::create ( library->getLibrary() , name ) );
state->getCell ()->put ( CatalogProperty::create(state) );
state->getCell ()->setFlattenLeaf ( false );
}
@ -357,14 +471,15 @@ namespace CRL {
}
void AllianceFramework::saveCell ( Cell* cell , unsigned int mode )
void AllianceFramework::saveCell ( Cell* cell, unsigned int mode )
{
if ( !cell ) return;
if ( cell == NULL ) return;
string name = getString(cell->getName());
DriverSlot* driver;
unsigned int saveMode;
unsigned int savedViews = 0;
string name = getString(cell->getName());
DriverSlot* driver;
unsigned int saveMode = 0;
unsigned int savedViews = 0;
AllianceLibrary* library = getAllianceLibrary ( cell->getLibrary() );
for ( int i=0 ; i<2 ; i++ ) {
// Check is the view is requested for saving or already saved.
@ -381,6 +496,8 @@ namespace CRL {
driver = & ( _drivers.getDriverSlot ( name, saveMode, _environment ) );
// Try to open cell file (file extention is supplied by the parser).
if ( library != NULL )
_environment.getLIBRARIES().select ( getString(library->getPath()) );
if ( !_writeLocate(name,saveMode,false) ) continue;
// Call the driver function.
@ -473,7 +590,7 @@ namespace CRL {
// Try to open using the library driver.
name = file + "." + getString(format.getExtLib());
LIBRARIES.locate ( name, ios::out|ios::trunc, 0, 1 );
LIBRARIES.locate ( name, ios::out|ios::trunc );
if ( LIBRARIES.hasSelected() ) return true;
} else {
if ( !format.getDrivCell() ) return false;
@ -481,7 +598,7 @@ namespace CRL {
// Try to open using the cell driver.
name = file + "." + getString(format.getExtCell());
LIBRARIES.locate ( name, ios::out|ios::trunc, 0, 1 );
LIBRARIES.locate ( name, ios::out|ios::trunc );
if ( LIBRARIES.hasSelected() ) return true;
}
return false;

View File

@ -16,6 +16,8 @@
${CRLCORE_SOURCE_DIR}/src/ccore/properties
${CRLCORE_SOURCE_DIR}/src/ccore/bookshelf
${CRLCORE_SOURCE_DIR}/src/ccore/acmsigda
${CRLCORE_SOURCE_DIR}/src/ccore/ispd04
${CRLCORE_SOURCE_DIR}/src/ccore/iccad04
${CRLCORE_SOURCE_DIR}/src/ccore/cspice
${CRLCORE_SOURCE_DIR}/src/ccore/lefdef
${CRLCORE_SOURCE_DIR}/src/ccore/alliance/ap
@ -52,6 +54,11 @@
crlcore/AllianceLibrary.h
crlcore/ParsersDrivers.h
crlcore/LefDefExtension.h
crlcore/DefImport.h
crlcore/DefExport.h
crlcore/LefExport.h
crlcore/Iccad04Lefdef.h
crlcore/Ispd04Bookshelf.h
crlcore/Ioc.h
crlcore/NetExtension.h
crlcore/Measures.h
@ -123,20 +130,28 @@
# liberty/TimingEvent.cpp
# liberty/LuTable.cpp
# )
set ( lefdef_cpps lefdef/LefDef.h
# set ( lefdef_cpps lefdef/LefDef.h
# lefdef/LefDefExtension.cpp
# lefdef/LefParser.cpp
# lefdef/DefParser.cpp
# lefdef/DefDriver.cpp
# )
set ( lefdef_cpps lefdef/LefExport.cpp
lefdef/DefExport.cpp
lefdef/DefImport.cpp
lefdef/LefDefExtension.cpp
lefdef/LefParser.cpp
lefdef/DefParser.cpp
lefdef/DefDriver.cpp
)
)
set ( iccad04_cpps iccad04/Iccad04Lefdef.cpp )
set ( ispd04_cpps ispd04/Ispd04Bookshelf.cpp )
if ( LEFDEF_FOUND )
include_directories ( ${LEFDEF_INCLUDE_DIR} )
endif ( LEFDEF_FOUND )
if ( OA_FOUND )
include_directories ( ${OA_INCLUDE_DIR} )
endif ( OA_FOUND )
set (openaccess_cpps openaccess/OpenAccessDriver.cpp
openaccess/OpenAccessParser.cpp )
set (openaccess_cpps openaccess/OpenAccessParser.cpp
openaccess/OpenAccessDriver.cpp
)
set ( VstParserSourceDir ${CRLCORE_SOURCE_DIR}/src/ccore/alliance/vst )
set ( VstParserBinaryDir ${CRLCORE_BINARY_DIR}/src/ccore/alliance/vst )
@ -269,6 +284,8 @@
${liberty_parser_cpps}
${bookshelf_cpps}
${acmsigda_parser_cpps}
${iccad04_cpps}
${ispd04_cpps}
${spice_cpps}
${lefdef_cpps}
${openaccess_cpps}
@ -276,6 +293,7 @@
target_link_libraries ( crlcore ${HURRICANE_PYTHON_LIBRARIES}
${HURRICANE_GRAPHICAL_LIBRARIES}
${HURRICANE_LIBRARIES}
${BOOKSHELF_LIBRARY}
${CONFIGURATION_LIBRARY}
${CIF_LIBRARY}
${AGDS_LIBRARY}

View File

@ -73,7 +73,6 @@ namespace {
, TagsTechnologies
, TagsHurricane
, TagsReal
, TagsLEF
, TagsDisplay
, TagsConfig
, TagsLibraries
@ -96,7 +95,6 @@ namespace {
};
enum State { HurricaneTechnology = 1
, RealTechnology
, LEFTechnology
, Display
, WorkingLibrary
, SystemLibrary
@ -124,7 +122,6 @@ namespace {
void parseTechnologies ();
void parseHurricane ();
void parseReal ();
void parseLEF ();
void parseDisplay ();
void parseDisplayStyle ();
void parseConfig ();
@ -164,8 +161,6 @@ namespace {
addTagEntry ( TagsHurricane , "config" , (tagParser_t)&XmlEnvironmentParser::parseConfig );
addTagEntry ( TagsTechnologies, "real" , (tagParser_t)&XmlEnvironmentParser::parseReal );
addTagEntry ( TagsReal , "config" , (tagParser_t)&XmlEnvironmentParser::parseConfig );
addTagEntry ( TagsTechnologies, "lef" , (tagParser_t)&XmlEnvironmentParser::parseLEF );
addTagEntry ( TagsLEF , "config" , (tagParser_t)&XmlEnvironmentParser::parseConfig );
addTagEntry ( TagsTechnologies, "display" , (tagParser_t)&XmlEnvironmentParser::parseDisplay );
addTagEntry ( TagsDisplay , "config" , (tagParser_t)&XmlEnvironmentParser::parseConfig );
addTagEntry ( TagsDisplay , "displaystyle", (tagParser_t)&XmlEnvironmentParser::parseDisplayStyle );
@ -323,13 +318,6 @@ namespace {
}
void XmlEnvironmentParser::parseLEF ()
{
_state = LEFTechnology;
parseTags ( TagsLEF );
}
void XmlEnvironmentParser::parseDisplay ()
{
_state = Display;
@ -357,7 +345,6 @@ namespace {
expandVariables ( config );
switch ( _state ) {
case HurricaneTechnology: _environment.setSYMBOLIC_TECHNOLOGY ( config.c_str() ); break;
case LEFTechnology: _environment.setLEF_TECHNOLOGY ( config.c_str() ); break;
case RealTechnology: _environment.setREAL_TECHNOLOGY ( config.c_str() ); break;
case Display: _environment.setDISPLAY ( config.c_str() ); break;
}
@ -528,7 +515,6 @@ namespace CRL {
, _displayStyle ()
, _SCALE_X (10)
, _SYMBOLIC_TECHNOLOGY("")
, _LEF_TECHNOLOGY ("")
, _DISPLAY ("")
, _IN_LO ("vst")
, _IN_PH ("ap")
@ -644,8 +630,6 @@ namespace CRL {
<< " \"" << _CORIOLIS_TOP << "\"\n"
<< " - Symbolic Technology:\n"
<< " \"" << _SYMBOLIC_TECHNOLOGY << "\"\n"
<< " - LEF Technology:\n"
<< " \"" << _LEF_TECHNOLOGY << "\"\n"
<< " - Display configuration:\n"
<< " \"" << _DISPLAY << "\"\n";

View File

@ -11,7 +11,7 @@ namespace CRL {
OADriver::OADriver(Cell* cell) : _cell(cell) {}
void OADriver::save(const std::string& filePath) {
CRL::OpenAccess::oaDriver(filePath, _cell);
//CRL::OpenAccess::oaDriver(filePath, _cell);
}
OAParser::OAParser(const std::string& cellLibPath,const std::string& cellLibName,

View File

@ -51,19 +51,18 @@
# include "hurricane/DBo.h"
#include "hurricane/DBo.h"
# include "crlcore/Utilities.h"
# include "crlcore/Environment.h"
# include "crlcore/Catalog.h"
# include "crlcore/ParsersDrivers.h"
# include "Ap.h"
# include "Vst.h"
# include "Spice.h"
# include "Bookshelf.h"
# include "AcmSigda.h"
# include "LefDef.h"
# include "openaccess/OpenAccess.h"
#include "crlcore/Utilities.h"
#include "crlcore/Environment.h"
#include "crlcore/Catalog.h"
#include "crlcore/ParsersDrivers.h"
#include "Ap.h"
#include "Vst.h"
#include "Spice.h"
#include "Bookshelf.h"
#include "AcmSigda.h"
#include "openaccess/OpenAccess.h"
namespace {
@ -214,15 +213,13 @@ namespace CRL {
ParsersMap::ParsersMap (): map<Name,ParserFormatSlot>()
{
// Register the Alliance default parsers.
registerSlot ( "ap" , (CellParser_t*)apParser , "ap" );
registerSlot ( "vst", (CellParser_t*)vstParser , "vst" );
registerSlot ( "vst", (CellParser_t*)vstParser , "vbe" );
registerSlot ( "spi", (CellParser_t*)spiceParser , "spi" );
registerSlot ( "def", (CellParser_t*)defParser , "def" );
registerSlot ( "def", (LibraryParser_t*)lefParser , "lef" );
registerSlot ( "oa", (CellParser_t*)OpenAccess::oaCellParser , "oa" );
// registerSlot ( "oa", (LibraryParser_t*)OpenAccess::oaLibParser , "oa" );
registerSlot ( "aux", (CellParser_t*)bookshelfParser, "aux" );
registerSlot ( "ap" , (CellParser_t*)apParser , "ap" );
registerSlot ( "vst" , (CellParser_t*)vstParser , "vst" );
registerSlot ( "vst" , (CellParser_t*)vstParser , "vbe" );
registerSlot ( "spi" , (CellParser_t*)spiceParser , "spi" );
registerSlot ( "oa" , (CellParser_t*)OpenAccess::oaCellParser , "oa" );
//registerSlot ( "oa" , (LibraryParser_t*)OpenAccess::oaLibParser, "oa" );
registerSlot ( "aux" , (CellParser_t*)bookshelfParser, "aux" );
registerSlot ( "bench", (CellParser_t*)acmSigdaParser , "bench" );
}
@ -333,10 +330,10 @@ namespace CRL {
// Register the Alliance default drivers.
registerSlot ( "ap" , (CellDriver_t*)apDriver , "ap" );
registerSlot ( "vst", (CellDriver_t*)vstDriver , "vst" );
registerSlot ( "def", (CellDriver_t*)defDriver , "def" );
//registerSlot ( "def", (CellDriver_t*)defDriver , "def" );
registerSlot ( "aux", (CellDriver_t*)bookshelfDriver, "test.aux" );
registerSlot ( "spi", (CellDriver_t*)spiceDriver , "spi" );
registerSlot ( "oa" , (CellDriver_t*)OpenAccess::oaDriver, "oa");
//registerSlot ( "oa" , (CellDriver_t*)OpenAccess::oaDriver, "oa");
}

View File

@ -26,42 +26,86 @@
# include "crlcore/SearchPath.h"
namespace {
using namespace std;
} // End of anonymous namespace.
namespace CRL {
using namespace std;
const size_t SearchPath::npos = (size_t)-1;
const size_t SearchPath::npos = (size_t)-1;
const string SearchPath::_selectFailed = "<File or directory not found>";
SearchPath::SearchPath ()
: _paths ()
, _index (npos)
, _selected("")
, _selected(_selectFailed)
{ }
bool SearchPath::_canOpen ( const string& directory, const string& file, ios::openmode mode )
{
_selected = directory + "/" + file;
fstream filestream ( _selected.c_str(), mode );
if ( filestream.is_open() ) {
filestream.close ();
return true;
}
_selected = _selectFailed;
return false;
}
void SearchPath::prepend ( const std::string& path )
{
vector<string>::iterator ipath = _paths.begin();
_index = 0;
if ( ipath != _paths.end() ) { ++ipath; ++_index; }
_paths.insert ( ipath, path );
}
void SearchPath::replace ( const string& path, size_t index )
{
_index = index;
if ( index < _paths.size() )
_paths[index] = path;
}
size_t SearchPath ::locate ( const string& file, ios::openmode mode, int first, int last )
void SearchPath::select ( const string& path )
{
for ( int i=max(0,first) ; i < min((int)_paths.size(),last) ; i++ ) {
string path = _paths[i] + "/" + file;
for ( size_t ipath=0 ; ipath < _paths.size() ; ++ipath ) {
if ( _paths[ipath] == path ) {
_selected = _paths[ipath];
_index = ipath;
return;
}
}
fstream filestream ( path.c_str(), mode );
if ( filestream.is_open() ) {
filestream.close ();
_selected = path;
_selected = _selectFailed;
_index = npos;
}
size_t SearchPath::locate ( const string& file, ios::openmode mode, int first, int last )
{
if ( hasSelected() and _canOpen(_paths[_index],file,mode) ) return _index;
for ( int i=max(0,first) ; i < min((int)_paths.size(),last) ; i++ ) {
if ( _canOpen(_paths[i],file,mode) ) {
return _index = i;
}
}
_selected = "<File not found>";
return _index = npos;
}

View File

@ -95,12 +95,12 @@ bool toMBKLayer ( const char*& mbkLayer
tableLayer [ "METAL5" ] = "ALU5";
tableLayer [ "METAL6" ] = "ALU6";
tableLayer [ "OBSTACLE1" ] = "TALU1";
tableLayer [ "OBSTACLE2" ] = "TALU2";
tableLayer [ "OBSTACLE3" ] = "TALU3";
tableLayer [ "OBSTACLE4" ] = "TALU4";
tableLayer [ "OBSTACLE5" ] = "TALU5";
tableLayer [ "OBSTACLE6" ] = "TALU6";
tableLayer [ "BLOCKAGE1" ] = "TALU1";
tableLayer [ "BLOCKAGE2" ] = "TALU2";
tableLayer [ "BLOCKAGE3" ] = "TALU3";
tableLayer [ "BLOCKAGE4" ] = "TALU4";
tableLayer [ "BLOCKAGE5" ] = "TALU5";
tableLayer [ "BLOCKAGE6" ] = "TALU6";
tableConnector [ "METAL1" ] = "CALU1";
tableConnector [ "METAL2" ] = "CALU2";

View File

@ -50,6 +50,48 @@ namespace {
using namespace CRL;
class GlobalNetLookup {
public:
inline void addLookup ( Net* );
inline Net* lookup ( const string& );
inline bool isGlobal ( Net* );
inline void clear ();
private:
map<string,Net*> _globalNets;
};
inline void GlobalNetLookup::addLookup ( Net* globalNet )
{
if ( globalNet == NULL ) return;
_globalNets.insert ( make_pair(getString(globalNet->getName())
,globalNet
) );
}
inline Net* GlobalNetLookup::lookup ( const string& name )
{
map<string,Net*>::iterator inet = _globalNets.find(name);
if ( inet == _globalNets.end() ) return NULL;
return (*inet).second;
}
inline bool GlobalNetLookup::isGlobal ( Net* globalNet )
{
if ( globalNet == NULL ) return false;
return (lookup(getString(globalNet->getName())) != NULL);
}
inline void GlobalNetLookup::clear ()
{ _globalNets.clear (); }
GlobalNetLookup __globalNets;
void FilterPointsInStrings(string& s) {
// Problem in VST... : the . which seems to represent hierachy paths
// in ap is not supported...
@ -297,18 +339,20 @@ void DumpSignalList(ofstream &ccell, Cell* cell)
{
StringPtVector netsString;
NetSet netSet;
for_each_net(net, cell->getInternalNets())
forEach(Net*, inet, cell->getNets())
{
string* stringName = new string(net->getName()._getString());
if ( not (*inet)->isExternal() ) {
string* stringName = new string(inet->getName()._getString());
FilterPointsInStrings(*stringName);
netsString.push_back(stringName);
NetSet::iterator nsit = netSet.find(net);
NetSet::iterator nsit = netSet.find(*inet);
if (nsit != netSet.end())
{
throw Error("two times the same name");
}
netSet.insert(net);
end_for;
throw Error("two times the same name");
netSet.insert(*inet);
}
if ( (*inet)->isGlobal() ) {
__globalNets.addLookup ( *inet );
}
}
sort(netsString.begin(), netsString.end(), StringSort());
@ -412,7 +456,7 @@ void DumpConnectionList(ofstream &ccell, Instance*instance)
throw Error("Cannot find net named " + *string1);
}
if (string1OpenPar == string::npos)
{
{
Plug* plug = spmit->second;
string connectedNetName;
if (plug->isConnected()) {
@ -430,19 +474,21 @@ void DumpConnectionList(ofstream &ccell, Instance*instance)
Net* masterNet = plug->getMasterNet();
if (masterNet->isGlobal()) // connection by name
{
for_each_net(globalnet, instance->getCell()->getGlobalNets())
Net* globalNet = __globalNets.lookup ( getString(masterNet->getName()) );
if ( globalNet != NULL ) connectedNetName = getString(globalNet->getName());
#if VERY_SLOW
for_each_net(globalnet, instance->getCell()->getGlobalNets())
{
if (globalnet->getName() == masterNet->getName())
if (globalnet->getName() == masterNet->getName())
{
connectedNetName = string(masterNet->getName()._getString());
break;
connectedNetName = string(masterNet->getName()._getString());
break;
}
end_for;
}
if (connectedNetName == string())
{
throw Error("No global net " + masterNet->getName()._getString() + " in cell " + instance->getCell()->getName()._getString());
end_for;
}
#endif
if ( connectedNetName.empty() )
throw Error("No global net " + masterNet->getName()._getString() + " in cell " + instance->getCell()->getName()._getString());
}
else
@ -616,6 +662,8 @@ namespace CRL {
void vstDriver ( const string cellPath, Cell *cell, unsigned int &saveState )
{
__globalNets.clear ();
::std::ofstream ccell ( cellPath.c_str() );
ccell << "entity " << cell->getName() << " is" << endl;
DumpPortList(ccell, cell);

View File

@ -28,6 +28,7 @@
#include <map>
#include <limits>
#include "crlcore/Environment.h"
#include "crlcore/AllianceLibrary.h"
@ -45,6 +46,7 @@ namespace CRL {
class AllianceFramework {
public:
enum InstancesCountFlags { Recursive=0x1, IgnoreFeeds=0x2 };
enum LibraryFlags { CreateLibrary=0x1, InSearchPath=0x2, HasCatalog=0x4 };
public:
// Constructors.
static AllianceFramework* create ();
@ -71,8 +73,13 @@ namespace CRL {
inline Catalog* getCatalog ();
inline const Name& getParentLibraryName () const;
inline Library* getParentLibrary ();
Library* getLibrary ( unsigned index );
AllianceLibrary* getAllianceLibrary ( const Name& path, bool& flag );
Library* getLibrary ( unsigned int index );
AllianceLibrary* getAllianceLibrary ( unsigned int index );
AllianceLibrary* getAllianceLibrary ( const Name& path, unsigned int& flags );
AllianceLibrary* getAllianceLibrary ( Library* );
AllianceLibrary* createLibrary ( const string& path, unsigned int& flags );
void saveLibrary ( Library* );
void saveLibrary ( AllianceLibrary* );
RoutingGauge* getRoutingGauge ( const Name& name="" );
CellGauge* getCellGauge ( const Name& name="" );
inline const Name getDefaultCGPinLayerName () const;
@ -83,11 +90,11 @@ namespace CRL {
Cell* getCell ( const string& name
, unsigned int mode
, unsigned int depth=(unsigned int)-1 );
Cell* createCell ( const string& name );
void saveCell ( Cell* cell , unsigned int mode );
unsigned int loadLibraryCells ( Library* library );
unsigned int loadLibraryCells ( const Name& name );
static size_t getInstancesCount ( Cell* cell, unsigned int flags );
Cell* createCell ( const string& name, AllianceLibrary* library=NULL );
void saveCell ( Cell* , unsigned int mode );
unsigned int loadLibraryCells ( Library* );
unsigned int loadLibraryCells ( const Name& );
static size_t getInstancesCount ( Cell*, unsigned int flags );
// Internals - Attributes.
protected:
@ -115,6 +122,7 @@ namespace CRL {
// Internals - Methods.
bool _readLocate ( const string& file, unsigned int mode, bool isLib=false );
bool _writeLocate ( const string& file, unsigned int mode, bool isLib=false );
AllianceLibrary* _createLibrary ( const string& path, bool& hasCatalog );
};

View File

@ -0,0 +1,49 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | C a d e n c e D E F E x p o r t e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Header : "./crlcore/DefExport.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __CRL_DEF_EXPORT__
#define __CRL_DEF_EXPORT__
namespace Hurricane {
class Cell;
}
namespace CRL {
class DefExport {
public:
enum Flag { WithLEF=0x1, ExpandDieArea=0x2 };
public:
static void drive ( Hurricane::Cell*, unsigned int flags );
};
} // End of CRL namespace.
#endif // __CRL_DEF_EXPORT__

View File

@ -0,0 +1,50 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | C a d e n c e D E F I m p o r t e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Header : "./crlcore/DefImport.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __CRL_DEF_IMPORT__
#define __CRL_DEF_IMPORT__
#include <string>
namespace Hurricane {
class Cell;
}
namespace CRL {
class DefImport {
public:
enum Flags { FitAbOnCells=0x1 };
public:
static Hurricane::Cell* load ( std::string design, unsigned int flags );
};
} // End of CRL namespace.
#endif // __CRL_DEF_IMPORT__

View File

@ -53,7 +53,6 @@ namespace CRL {
inline long getSCALE_X () const;
inline const std::string& getSYMBOLIC_TECHNOLOGY () const;
inline const std::string& getREAL_TECHNOLOGY () const;
inline const std::string& getLEF_TECHNOLOGY () const;
inline const std::string& getDISPLAY () const;
inline const std::string& getIN_LO () const;
inline const std::string& getIN_PH () const;
@ -79,7 +78,6 @@ namespace CRL {
inline void setSCALE_X ( long value );
inline void setSYMBOLIC_TECHNOLOGY ( const char* value );
inline void setREAL_TECHNOLOGY ( const char* value );
inline void setLEF_TECHNOLOGY ( const char* value );
inline void setDISPLAY ( const char* value );
inline void setIN_LO ( const char* value );
inline void setIN_PH ( const char* value );
@ -102,7 +100,6 @@ namespace CRL {
std::string _displayStyle;
long _SCALE_X;
std::string _SYMBOLIC_TECHNOLOGY;
std::string _LEF_TECHNOLOGY;
std::string _REAL_TECHNOLOGY;
std::string _DISPLAY;
std::string _IN_LO;
@ -134,7 +131,6 @@ namespace CRL {
inline long Environment::getSCALE_X () const { return _SCALE_X; }
inline const std::string& Environment::getSYMBOLIC_TECHNOLOGY () const { return _SYMBOLIC_TECHNOLOGY; }
inline const std::string& Environment::getREAL_TECHNOLOGY () const { return _REAL_TECHNOLOGY; }
inline const std::string& Environment::getLEF_TECHNOLOGY () const { return _LEF_TECHNOLOGY; }
inline const std::string& Environment::getDISPLAY () const { return _DISPLAY; }
inline const std::string& Environment::getIN_LO () const { return _IN_LO; }
inline const std::string& Environment::getIN_PH () const { return _IN_PH; }
@ -151,7 +147,6 @@ namespace CRL {
inline void Environment::setSCALE_X ( long value ) { _SCALE_X = value; }
inline void Environment::setSYMBOLIC_TECHNOLOGY ( const char* value ) { _SYMBOLIC_TECHNOLOGY = value; }
inline void Environment::setREAL_TECHNOLOGY ( const char* value ) { _REAL_TECHNOLOGY = value; }
inline void Environment::setLEF_TECHNOLOGY ( const char* value ) { _LEF_TECHNOLOGY = value; }
inline void Environment::setDISPLAY ( const char* value ) { _DISPLAY = value; }
inline void Environment::setIN_LO ( const char* value ) { _IN_LO = value; }
inline void Environment::setIN_PH ( const char* value ) { _IN_PH = value; }

View File

@ -0,0 +1,52 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | ICCAD04 IBM Standard Cell Benchmarks |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Header : "./crlcore/Iccad04Lefdef.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __CRL_ICCAD04_LEFDEF__
#define __CRL_ICCAD04_LEFDEF__
#include <string>
namespace Hurricane {
class Cell;
}
namespace CRL {
using Hurricane::Cell;
class Iccad04Lefdef {
public:
enum Flags { NoFlags=0x0 };
public:
static Cell* load ( std::string benchmark, unsigned int flags=0 );
};
} // End of CRL namespace.
#endif // __CRL_ICCAD04_LEFDEF__

View File

@ -0,0 +1,51 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | ISPD04 IBM Standard Cell Benchmarks |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Header : "./crlcore/Ispd04Bookshelf.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __CRL_ISPD04_BOOKSHELF__
#define __CRL_ISPD04_BOOKSHELF__
#include <string>
namespace Hurricane {
class Cell;
}
namespace CRL {
using Hurricane::Cell;
class Ispd04 {
public:
static Cell* load ( std::string benchmark );
};
} // End of CRL namespace.
#endif // __CRL_ISPD04_BOOKSHELF__

View File

@ -0,0 +1,51 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | C a d e n c e D E F E x p o r t e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Header : "./crlcore/LefExport.h" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#ifndef __CRL_LEF_EXPORT__
#define __CRL_LEF_EXPORT__
namespace Hurricane {
class Cell;
class Library;
}
namespace CRL {
class LefExport {
public:
enum Flag { WithTechnology=0x1 };
public:
static void drive ( Hurricane::Cell* , unsigned int flags );
static void drive ( Hurricane::Library*, unsigned int flags );
};
} // End of CRL namespace.
#endif // __CRL_LEF_EXPORT__

View File

@ -48,24 +48,30 @@ namespace CRL {
public:
inline void reset ();
inline void append ( const std::string& path );
inline void prepend ( const std::string& path );
void prepend ( const std::string& path );
void replace ( const std::string& path, size_t index );
size_t locate ( const std::string& file
, std::ios::openmode mode =std::ios::in
, int first=0
, int last =64 );
void select ( const std::string& );
inline size_t getSize () const;
inline const std::string& getSelected () const;
inline size_t getIndex () const;
bool hasSelected () const;
inline bool hasSelected () const;
size_t hasPath ( const std::string& path ) const;
const std::string& operator[] ( size_t index ) const;
private:
static const std::string _selectFailed;
std::vector<std::string> _paths;
size_t _index;
std::string _selected;
private:
SearchPath ( const SearchPath& );
bool _canOpen ( const std::string& directory
, const std::string& file
, std::ios::openmode mode
);
public:
inline std::string _getTypeName () const;
std::string _getString () const;
@ -75,7 +81,6 @@ namespace CRL {
// Inline Functions.
inline void SearchPath::reset () { _paths.resize(1); }
inline void SearchPath::prepend ( const std::string& path ) { _paths.insert ( _paths.begin(), path ); }
inline void SearchPath::append ( const std::string& path ) { _paths.push_back(path); }
inline size_t SearchPath::getSize () const { return _paths.size(); }
inline const std::string& SearchPath::getSelected () const { return _selected; }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,227 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | ISPD04 IBM Standard Cell Benchmarks |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Module : "./Ispd04Bookshelf.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include <memory>
#include "vlsisapd/bookshelf/Exception.h"
#include "vlsisapd/bookshelf/Node.h"
#include "vlsisapd/bookshelf/Pin.h"
#include "vlsisapd/bookshelf/Net.h"
#include "vlsisapd/bookshelf/Circuit.h"
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/DataBase.h"
#include "hurricane/Technology.h"
#include "hurricane/Net.h"
#include "hurricane/NetExternalComponents.h"
#include "hurricane/Horizontal.h"
#include "hurricane/Vertical.h"
#include "hurricane/Cell.h"
#include "hurricane/Library.h"
#include "hurricane/UpdateSession.h"
#include "crlcore/AllianceFramework.h"
#include "crlcore/ToolBox.h"
#include "crlcore/Ispd04Bookshelf.h"
namespace {
using namespace std;
using namespace Hurricane;
using namespace CRL;
void addSupplyNets ( Cell* cell )
{
Net* vss = Net::create ( cell, "vss" );
vss->setExternal ( true );
vss->setGlobal ( true );
vss->setType ( Net::Type::GROUND );
Net* vdd = Net::create ( cell, "vdd" );
vdd->setExternal ( true );
vdd->setGlobal ( true );
vdd->setType ( Net::Type::POWER );
}
Cell* toMasterCell ( AllianceFramework* af, Bookshelf::Node* node )
{
if ( node->getHeight() > 16.0 ) return NULL;
Technology* technology = DataBase::getDB()->getTechnology();
Layer* METAL1 = technology->getLayer ( "METAL1" );
Cell* master = af->createCell ( node->getName() );
Box abutmentBox ( DbU::lambda( 0.0 )
, DbU::lambda( 0.0 )
, DbU::lambda( node->getWidth()*5.0 )
, DbU::lambda( 50.0 )
);
master->setAbutmentBox ( abutmentBox );
addSupplyNets ( master );
Segment* segment = Horizontal::create ( master->getNet("vss")
, METAL1
, abutmentBox.getYMin()+DbU::lambda(3.0)
, DbU::lambda(6.0)
, abutmentBox.getXMin()
, abutmentBox.getXMax()
);
NetExternalComponents::setExternal ( segment );
segment = Horizontal::create ( master->getNet("vdd")
, METAL1
, abutmentBox.getYMax()-DbU::lambda(3.0)
, DbU::lambda( 6.0)
, abutmentBox.getXMin()
, abutmentBox.getXMax()
);
NetExternalComponents::setExternal ( segment );
map<size_t,Bookshelf::Pin*>& pins = node->getPins();
map<size_t,Bookshelf::Pin*>::iterator ipin = pins.begin();
if ( node->getWidth() < (double)pins.size() )
throw Error("Ispd04::load(): Node <%s> has only %.1f pitchs, cannot hold %zd terminals."
,node->getName().c_str(),node->getWidth(),pins.size());
DbU::Unit pinXMin = abutmentBox.getXMin() + DbU::lambda(5.0);
DbU::Unit pinXMax = abutmentBox.getXMax() - ((node->getWidth() > (double)pins.size()) ? DbU::lambda(5.0) : 0);
DbU::Unit pinX;
for ( size_t pinnb=0 ; ipin != pins.end() ; ++ipin, ++pinnb ) {
Net* net = Net::create ( master, (*ipin).second->getNet()->getName() );
net->setExternal ( true );
if ( pinnb % 2 ) {
pinX = pinXMax;
pinXMax -= DbU::lambda(5.0);
} else {
pinX = pinXMin;
pinXMin += DbU::lambda(5.0);
}
segment = Vertical::create ( net
, METAL1
, pinX
, DbU::lambda(1.0)
, abutmentBox.getYMin() + DbU::lambda(10.0)
, abutmentBox.getYMax() - DbU::lambda(10.0)
);
NetExternalComponents::setExternal ( segment );
}
return master;
}
} // End of anonymous namespace.
namespace CRL {
using std::string;
using std::map;
using std::auto_ptr;
using Hurricane::Library;
using Hurricane::Transformation;
using Hurricane::UpdateSession;
Cell* Ispd04::load ( string benchmark )
{
AllianceFramework* af = AllianceFramework::get ();
UpdateSession::open ();
auto_ptr<Bookshelf::Circuit> circuit ( Bookshelf::Circuit::parse(benchmark) );
Cell* cell = af->createCell ( benchmark );
addSupplyNets ( cell );
vector<Bookshelf::Net*>& nets = circuit->getNets ();
vector<Bookshelf::Net*>::iterator inet = nets.begin();
for ( ; inet != nets.end() ; ++inet ) {
Net::create ( cell, (*inet)->getName() );
}
map<string,Bookshelf::Node*>& nodes = circuit->getNodes();
map<string,Bookshelf::Node*>::iterator inode = nodes.begin();
Box abutmentBox;
for ( ; inode != nodes.end() ; ++inode ) {
Bookshelf::Node* node = (*inode).second;
if ( node->isTerminal () ) continue;
Cell* master = toMasterCell ( af, node );
if ( master == NULL ) {
cerr << Warning("Skipping megacell <%s>.",node->getName().c_str()) << endl;
continue;
}
Instance* instance = Instance::create ( cell, node->getName(), master );
map<size_t,Bookshelf::Pin*>& pins = node->getPins();
map<size_t,Bookshelf::Pin*>::iterator ipin = pins.begin();
for ( size_t pinnb=0 ; ipin != pins.end() ; ++ipin, ++pinnb ) {
Name netName ( (*ipin).second->getNet()->getName());
Net* masterNet = master->getNet ( netName );
instance->getPlug ( masterNet )->setNet ( cell->getNet(netName) );
DbU::Unit x = DbU::lambda( node->getX() * 5.0);
DbU::Unit y = DbU::lambda((node->getY()/16.0) * 50.0);
if ( node->getOrientation() != Bookshelf::Orientation::N ) {
cerr << Warning("Skipping cell <%s>, unsupported orientation.",node->getName().c_str()) << endl;
continue;
}
Box masterABox = master->getAbutmentBox();
Transformation::Orientation orientation
= ( (int)(node->getY())%32 ) ? Transformation::Orientation::MY
: Transformation::Orientation::ID;
//Transformation::Orientation orientation = Transformation::Orientation::ID;
Transformation instanceTransformation = getTransformation(masterABox, x, y, orientation);
instance->setTransformation ( instanceTransformation );
instance->setPlacementStatus ( Instance::PlacementStatus::PLACED );
abutmentBox.merge ( instance->getAbutmentBox() );
}
}
cell->setAbutmentBox ( abutmentBox );
UpdateSession::close ();
return cell;
}
} // End of CRL namespace.

View File

@ -0,0 +1,634 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | C a d e n c e D E F E x p o r t e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Module : "./crlcore/DefExport.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include <memory>
#if HAVE_LEFDEF
# include "lefwWriter.hpp"
# include "defwWriter.hpp"
# include "defwWriterCalls.hpp"
#endif
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/DataBase.h"
#include "hurricane/Technology.h"
#include "hurricane/Net.h"
#include "hurricane/NetExternalComponents.h"
#include "hurricane/Horizontal.h"
#include "hurricane/Vertical.h"
#include "hurricane/Cell.h"
#include "hurricane/Library.h"
#include "hurricane/UpdateSession.h"
#include "crlcore/Utilities.h"
#include "crlcore/ToolBox.h"
#include "crlcore/RoutingGauge.h"
#include "crlcore/RoutingLayerGauge.h"
#include "crlcore/AllianceFramework.h"
#include "crlcore/LefExport.h"
#include "crlcore/DefExport.h"
#if HAVE_LEFDEF
namespace {
using namespace std;
using namespace Hurricane;
using namespace CRL;
#define CHECK_STATUS_CBK(status) if ((status) != 0) return driver->checkStatus(status);
#define CHECK_STATUS_DRV(status) if ((status) != 0) return checkStatus(status);
#define RETURN_CHECK_STATUS_CBK(status) return driver->checkStatus(status);
#define RETURN_CHECK_STATUS_DRV(status) return checkStatus(status);
class DefDriver {
public:
static void drive ( Cell* cell, unsigned int flags );
static int getUnits ();
static int toDefUnits ( DbU::Unit );
static DbU::Unit getSliceHeight ();
static DbU::Unit getPitchWidth ();
~DefDriver ();
int write ();
private:
DefDriver ( Cell*, const string& designName, FILE*, unsigned int flags );
inline Cell* getCell ();
inline const string& getDesignName () const;
inline unsigned int getFlags () const;
inline int getStatus () const;
int checkStatus ( int status );
private:
static int _designCbk ( defwCallbackType_e, defiUserData );
static int _designEndCbk ( defwCallbackType_e, defiUserData );
static int _historyCbk ( defwCallbackType_e, defiUserData );
static int _versionCbk ( defwCallbackType_e, defiUserData );
static int _dividerCbk ( defwCallbackType_e, defiUserData );
static int _busBitCbk ( defwCallbackType_e, defiUserData );
static int _unitsCbk ( defwCallbackType_e, defiUserData );
static int _technologyCbk ( defwCallbackType_e, defiUserData );
static int _dieAreaCbk ( defwCallbackType_e, defiUserData );
static int _gcellGridCbk ( defwCallbackType_e, defiUserData );
static int _rowCbk ( defwCallbackType_e, defiUserData );
static int _trackCbk ( defwCallbackType_e, defiUserData );
static int _viaCbk ( defwCallbackType_e, defiUserData );
static int _pinCbk ( defwCallbackType_e, defiUserData );
static int _pinPropCbk ( defwCallbackType_e, defiUserData );
static int _componentCbk ( defwCallbackType_e, defiUserData );
static int _netCbk ( defwCallbackType_e, defiUserData );
static int _snetCbk ( defwCallbackType_e, defiUserData );
static int _extensionCbk ( defwCallbackType_e, defiUserData );
static int _groupCbk ( defwCallbackType_e, defiUserData );
static int _propDefCbk ( defwCallbackType_e, defiUserData );
static int _regionCbk ( defwCallbackType_e, defiUserData );
static int _scanchainCbk ( defwCallbackType_e, defiUserData );
private:
static int _units;
static DbU::Unit _sliceHeight;
static DbU::Unit _pitchWidth;
Cell* _cell;
string _designName;
FILE* _defStream;
unsigned int _flags;
int _status;
};
int DefDriver::_units = 100;
int DefDriver::getUnits () { return _units; }
int DefDriver::toDefUnits ( DbU::Unit u ) { return (int)round(DbU::getLambda(u)*getUnits()); }
DbU::Unit DefDriver::getSliceHeight () { return _sliceHeight; }
DbU::Unit DefDriver::getPitchWidth () { return _pitchWidth; };
inline Cell* DefDriver::getCell () { return _cell; }
inline unsigned int DefDriver::getFlags () const { return _flags; }
inline int DefDriver::getStatus () const { return _status; }
inline const string& DefDriver::getDesignName () const { return _designName; }
DefDriver::DefDriver ( Cell* cell, const string& designName, FILE* defStream, unsigned int flags )
: _cell (cell)
, _designName(designName)
, _defStream (defStream)
, _flags (flags)
, _status (0)
{
_sliceHeight = DbU::lambda(50.0);
_pitchWidth = DbU::lambda( 5.0);
_status = defwInitCbk ( _defStream );
if ( _status != 0 ) return;
defwSetDesignCbk ( _designCbk );
defwSetDesignEndCbk ( _designEndCbk );
defwSetHistoryCbk ( _historyCbk );
defwSetVersionCbk ( _versionCbk );
defwSetDividerCbk ( _dividerCbk );
defwSetBusBitCbk ( _busBitCbk );
defwSetUnitsCbk ( _unitsCbk );
defwSetTechnologyCbk ( _technologyCbk );
defwSetDieAreaCbk ( _dieAreaCbk );
defwSetGcellGridCbk ( _gcellGridCbk );
defwSetRowCbk ( _rowCbk );
defwSetTrackCbk ( _trackCbk );
defwSetViaCbk ( _viaCbk );
defwSetPinCbk ( _pinCbk );
defwSetPinPropCbk ( _pinPropCbk );
defwSetComponentCbk ( _componentCbk );
defwSetNetCbk ( _netCbk );
defwSetSNetCbk ( _snetCbk );
defwSetExtCbk ( _extensionCbk );
defwSetGroupCbk ( _groupCbk );
defwSetPropDefCbk ( _propDefCbk );
defwSetRegionCbk ( _regionCbk );
defwSetScanchainCbk ( _scanchainCbk );
}
DefDriver::~DefDriver ()
{ }
int DefDriver::write ()
{
return checkStatus ( defwWrite(_defStream,_designName.c_str(),(void*)this) );
}
int DefDriver::checkStatus ( int status )
{
if ( (_status=status) != 0 ) {
defwPrintError ( _status );
cerr << Error("DefDriver::drive(): Error occured while driving <%s>.",_designName.c_str()) << endl;
}
return _status;
}
int DefDriver::_versionCbk ( defwCallbackType_e, defiUserData udata )
{
DefDriver* driver = (DefDriver*)udata;
defwNewLine ();
defwAddComment ( "DEF generated by Coriolis2 DEF exporter." );
defwNewLine ();
return driver->checkStatus ( defwVersion(5,7) );
}
int DefDriver::_designCbk ( defwCallbackType_e, defiUserData udata )
{
DefDriver* driver = (DefDriver*)udata;
defwNewLine ();
return driver->checkStatus ( defwDesignName(driver->getDesignName().c_str()) );
}
int DefDriver::_designEndCbk ( defwCallbackType_e, defiUserData udata )
{
DefDriver* driver = (DefDriver*)udata;
return driver->checkStatus ( defwEnd() );
}
int DefDriver::_historyCbk ( defwCallbackType_e, defiUserData udata )
{
//DefDriver* driver = (DefDriver*)udata;
return 0;
}
int DefDriver::_dividerCbk ( defwCallbackType_e, defiUserData udata )
{
DefDriver* driver = (DefDriver*)udata;
defwNewLine ();
return driver->checkStatus ( defwDividerChar(".") );
}
int DefDriver::_busBitCbk ( defwCallbackType_e, defiUserData udata )
{
DefDriver* driver = (DefDriver*)udata;
return driver->checkStatus ( defwBusBitChars("()") );
}
int DefDriver::_unitsCbk ( defwCallbackType_e, defiUserData udata )
{
DefDriver* driver = (DefDriver*)udata;
defwNewLine ();
return driver->checkStatus ( defwUnits (DefDriver::getUnits()) );
}
int DefDriver::_technologyCbk ( defwCallbackType_e, defiUserData udata )
{
DefDriver* driver = (DefDriver*)udata;
return driver->checkStatus ( defwTechnology("symbolic") );
}
int DefDriver::_dieAreaCbk ( defwCallbackType_e, defiUserData udata )
{
DefDriver* driver = (DefDriver*)udata;
Box abutmentBox ( driver->getCell()->getAbutmentBox() );
if ( driver->getFlags() & DefExport::ExpandDieArea ) {
abutmentBox.inflate ( DefDriver::getPitchWidth() );
}
if ( not abutmentBox.isEmpty()) {
defwNewLine ();
driver->checkStatus
( defwDieArea ( (int)( toDefUnits(abutmentBox.getXMin()) )
, (int)( toDefUnits(abutmentBox.getYMin()) )
, (int)( toDefUnits(abutmentBox.getXMax()) )
, (int)( toDefUnits(abutmentBox.getYMax()) )
)
);
}
return driver->getStatus();
}
int DefDriver::_gcellGridCbk ( defwCallbackType_e, defiUserData udata )
{
//DefDriver* driver = (DefDriver*)udata;
return 0;
}
int DefDriver::_rowCbk ( defwCallbackType_e, defiUserData udata )
{
DefDriver* driver = (DefDriver*)udata;
int status = 0;
Cell* cell = driver->getCell();
Box abutmentBox ( cell->getAbutmentBox() );
int origY = (int)( toDefUnits(abutmentBox.getYMin()) );
int origX = (int)( toDefUnits(abutmentBox.getXMin()) );
int stepY = (int)( toDefUnits(DefDriver::getSliceHeight()) );
int stepX = (int)( toDefUnits(DefDriver::getPitchWidth ()) );
int rowsNb = abutmentBox.getHeight() / DefDriver::getSliceHeight();
int columnsNb = abutmentBox.getWidth () / DefDriver::getPitchWidth ();
ostringstream comment;
comment << rowsNb << " rows of " << columnsNb << " pitchs.";
defwNewLine ();
defwAddComment ( comment.str().c_str() );
for ( int row=0 ; row < rowsNb ; ++row ) {
ostringstream rowId;
rowId << "row_" << setw(5) << setfill('0') << row;
status = driver->checkStatus
( defwRowStr ( rowId.str().c_str()
, "core"
, origX
, origY
, (row%2) ? "FN" : "N"
, columnsNb
, 1
, stepX
, stepY
)
);
if ( status != 0 ) break;
origY += stepY;
}
return 0;
}
int DefDriver::_trackCbk ( defwCallbackType_e, defiUserData udata )
{
DefDriver* driver = (DefDriver*)udata;
Cell* cell = driver->getCell();
Box abutmentBox ( cell->getAbutmentBox() );
const vector<RoutingLayerGauge*>& rg
= AllianceFramework::get()->getRoutingGauge("sxlib")->getLayerGauges();
int status = 0;
const char* layerName[1];
for ( size_t ilayer=0 ; ilayer<rg.size() ; ++ilayer ) {
string name = getString ( rg[ilayer]->getLayer()->getName() );
layerName[0] = name.c_str();
const char* master; // i.e. direction.
int doCount;
int doStart;
int doStep = toDefUnits ( rg[ilayer]->getPitch() );
if ( rg[ilayer]->getDirection() == Constant::Horizontal ) {
master = "X";
doStart = toDefUnits ( abutmentBox.getYMin() + rg[ilayer]->getOffset() );
doCount = toDefUnits ( abutmentBox.getHeight() ) / doStep;
} else {
master = "Y";
doStart = toDefUnits ( abutmentBox.getXMin() + rg[ilayer]->getOffset() );
doCount = toDefUnits ( abutmentBox.getWidth() ) / doStep;
}
status = defwTracks ( master, doStart, doCount, doStep, 1, layerName );
CHECK_STATUS_CBK(status);
}
RETURN_CHECK_STATUS_CBK(status);
}
int DefDriver::_viaCbk ( defwCallbackType_e, defiUserData udata )
{
//DefDriver* driver = (DefDriver*)udata;
return 0;
}
int DefDriver::_pinCbk ( defwCallbackType_e, defiUserData udata )
{
DefDriver* driver = (DefDriver*)udata;
int status = 0;
Cell* cell = driver->getCell();
int pinsNb = 0;
forEach ( Net*, inet, cell->getNets() ) {
if ( (*inet)->isExternal() ) ++pinsNb;
}
status = defwStartPins ( pinsNb );
if ( status != 0 ) return driver->checkStatus(status);
forEach ( Net*, inet, cell->getNets() ) {
if ( not (*inet)->isExternal() ) continue;
const char* netUse = NULL;
if ( (*inet)->isGround() ) netUse = "GROUND";
if ( (*inet)->isPower () ) netUse = "POWER";
if ( (*inet)->isClock () ) netUse = "CLOCK";
status = defwPin ( getString((*inet)->getName()).c_str() // pin name.
, getString((*inet)->getName()).c_str() // net name (same).
, (netUse != NULL) ? 1 : 0 // special.
, (netUse != NULL) ? "INPUT" : "INOUT" // direction.
, netUse // use.
, NULL // placement status.
, 0 // status X.
, 0 // status Y.
, -1 // orient.
, NULL // layer.
, 0, 0, 0, 0 // geometry.
);
if ( status != 0 ) return driver->checkStatus(status);
}
return driver->checkStatus ( defwEndPins() );
}
int DefDriver::_pinPropCbk ( defwCallbackType_e, defiUserData udata )
{
//DefDriver* driver = (DefDriver*)udata;
return 0;
}
int DefDriver::_componentCbk ( defwCallbackType_e, defiUserData udata )
{
DefDriver* driver = (DefDriver*)udata;
int status = 0;
Cell* cell = driver->getCell();
status = defwNewLine ();
CHECK_STATUS_CBK(status);
status = defwStartComponents ( cell->getInstances().getSize() );
CHECK_STATUS_CBK(status);
forEach ( Instance*, iinstance, cell->getInstances() ) {
status = defwComponent ( getString((*iinstance)->getName()).c_str()
, getString((*iinstance)->getMasterCell()->getName()).c_str()
, 0 // numNetNames (disabled).
, NULL // netNames (disabled).
, NULL // eeq (electrical equivalence).
, NULL // genName.
, NULL // genParameters.
, NULL // source (who has created it).
, 0 // numForeigns.
, NULL // foreigns.
, NULL // foreignsX[].
, NULL // foreignsY[].
, NULL // foreignsOrient[].
, "UNPLACED" // status (placement status).
, 0 // status X (disabled).
, 0 // status Y (disabled).
, 0 // status orientation (disabled).
, 0.0 // weight (disabled).
, NULL // region (disabled).
, 0, 0, 0, 0 // region coordinates.
);
if ( status != 0 ) return driver->checkStatus(status);
}
return driver->checkStatus ( defwEndComponents() );
}
int DefDriver::_netCbk ( defwCallbackType_e, defiUserData udata )
{
DefDriver* driver = (DefDriver*)udata;
int status = 0;
Cell* cell = driver->getCell();
int netsNb = 0;
forEach ( Net*, inet, cell->getNets() ) {
if ( (*inet)->isSupply() or (*inet)->isClock() ) continue;
++netsNb;
}
status = defwStartNets ( netsNb );
if ( status != 0 ) return driver->checkStatus(status);
forEach ( Net*, inet, cell->getNets() ) {
if ( (*inet)->isSupply() or (*inet)->isClock() ) continue;
status = defwNet ( getString((*inet)->getName()).c_str() );
if ( status != 0 ) return driver->checkStatus(status);
forEach ( Plug*, iplug, (*inet)->getPlugs() ) {
status = defwNetConnection ( getString((*iplug)->getInstance ()->getName()).c_str()
, getString((*iplug)->getMasterNet()->getName()).c_str()
, 0
);
if ( status != 0 ) return driver->checkStatus(status);
}
status = defwNetEndOneNet ();
if ( status != 0 ) return driver->checkStatus(status);
}
return driver->checkStatus ( defwEndNets() );
}
int DefDriver::_snetCbk ( defwCallbackType_e, defiUserData udata )
{
DefDriver* driver = (DefDriver*)udata;
int status = 0;
Cell* cell = driver->getCell();
int netsNb = 0;
forEach ( Net*, inet, cell->getNets() ) {
if ( (*inet)->isSupply() or (*inet)->isClock() ) ++netsNb;
}
status = defwStartSpecialNets ( netsNb );
if ( status != 0 ) return driver->checkStatus(status);
forEach ( Net*, inet, cell->getNets() ) {
const char* netUse = NULL;
if ( (*inet)->isGround() ) netUse = "GROUND";
if ( (*inet)->isPower () ) netUse = "POWER";
if ( (*inet)->isClock () ) netUse = "CLOCK";
if ( netUse == NULL ) continue;
status = defwSpecialNet ( getString((*inet)->getName()).c_str() );
if ( status != 0 ) return driver->checkStatus(status);
status = defwSpecialNetConnection ( "*"
, getString((*inet)->getName()).c_str()
, 0
);
if ( status != 0 ) return driver->checkStatus(status);
status = defwSpecialNetUse ( netUse );
if ( status != 0 ) return driver->checkStatus(status);
status = defwSpecialNetEndOneNet ();
if ( status != 0 ) return driver->checkStatus(status);
}
return driver->checkStatus ( defwEndSpecialNets() );
}
int DefDriver::_extensionCbk ( defwCallbackType_e, defiUserData udata )
{
//DefDriver* driver = (DefDriver*)udata;
return 0;
}
int DefDriver::_groupCbk ( defwCallbackType_e, defiUserData udata )
{
//DefDriver* driver = (DefDriver*)udata;
return 0;
}
int DefDriver::_propDefCbk ( defwCallbackType_e, defiUserData udata )
{
//DefDriver* driver = (DefDriver*)udata;
return 0;
}
int DefDriver::_regionCbk ( defwCallbackType_e, defiUserData udata )
{
//DefDriver* driver = (DefDriver*)udata;
return 0;
}
int DefDriver::_scanchainCbk ( defwCallbackType_e, defiUserData udata )
{
//DefDriver* driver = (DefDriver*)udata;
return 0;
}
void DefDriver::drive ( Cell* cell, unsigned int flags )
{
FILE* defStream = NULL;
try {
string designName = getString(cell->getName()) + "export";
string path = "./" + designName + ".def";
cmess1 << " o Export DEF: <" << path << ">" << endl;
defStream = fopen ( path.c_str(), "w" );
if ( defStream == NULL )
throw Error("DefDriver::drive(): Cannot open <%s>.",path.c_str());
auto_ptr<DefDriver> driver ( new DefDriver(cell,designName,defStream,flags) );
driver->write ();
}
catch ( ... ) {
if ( defStream != NULL ) fclose ( defStream );
throw;
}
fclose ( defStream );
}
} // End of anonymous namespace.
#endif // HAVE_LEFDEF.
namespace CRL {
using std::cerr;
using std::endl;
using std::string;
using Hurricane::Library;
using Hurricane::Transformation;
using Hurricane::UpdateSession;
void DefExport::drive ( Cell* cell, unsigned int flags )
{
#if HAVE_LEFDEF
DefDriver::drive ( cell, flags );
if ( flags & WithLEF ) LefExport::drive ( cell, LefExport::WithTechnology );
#else
cerr << "[ERROR] CRL::DefExport::drive(): \n"
<< " Coriolis2 hasn't been compiled with LEF/DEF support. To enable LEF/DEF\n"
<< " support, you may obtain parser/driver from Si2 (www.si2.org) then recompile."
<< endl;
#endif
}
} // End of CRL namespace.

View File

@ -0,0 +1,457 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | C a d e n c e D E F I m p o r t e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Module : "./DefImport.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include <cstdio>
#include <cstring>
#include <memory>
#if HAVE_LEFDEF
# include "lefrReader.hpp"
# include "defrReader.hpp"
#endif
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/DataBase.h"
#include "hurricane/Technology.h"
#include "hurricane/Net.h"
#include "hurricane/NetExternalComponents.h"
#include "hurricane/Horizontal.h"
#include "hurricane/Vertical.h"
#include "hurricane/Cell.h"
#include "hurricane/Library.h"
#include "hurricane/UpdateSession.h"
#include "crlcore/Utilities.h"
#include "crlcore/ToolBox.h"
#include "crlcore/AllianceFramework.h"
#include "crlcore/DefImport.h"
#if HAVE_LEFDEF
namespace {
using namespace std;
using namespace Hurricane;
using namespace CRL;
void addSupplyNets ( Cell* cell )
{
Net* vss = Net::create ( cell, "vss" );
vss->setExternal ( true );
vss->setGlobal ( true );
vss->setType ( Net::Type::GROUND );
Net* vdd = Net::create ( cell, "vdd" );
vdd->setExternal ( true );
vdd->setGlobal ( true );
vdd->setType ( Net::Type::POWER );
}
class DefParser {
public:
static AllianceFramework* getFramework ();
static DbU::Unit fromDefUnits ( int );
static Transformation::Orientation
fromDefOrientation ( int orient );
static Transformation getTransformation ( const Box&
, const DbU::Unit x
, const DbU::Unit y
, const Transformation::Orientation
);
static Cell* parse ( string file, unsigned int flags );
DefParser ( string& file, AllianceLibrary*, unsigned int flags );
~DefParser ();
inline bool hasErrors ();
inline unsigned int getFlags () const;
inline AllianceLibrary* getLibrary ();
inline Cell* getCell ();
inline size_t getPitchs () const;
inline size_t getSlices () const;
inline const Box& getFitOnCellsDieArea () const;
Net* lookupNet ( const string& );
inline vector<string>& getErrors ();
inline void pushError ( const string& );
int flushErrors ();
inline void clearErrors ();
inline void setPitchs ( size_t );
inline void setSlices ( size_t );
void addNetLookup ( const string& netName, Net* );
inline void mergeToFitOnCellsDieArea ( const Box& );
private:
static int _designEndCbk ( defrCallbackType_e, void* , defiUserData );
static int _dieAreaCbk ( defrCallbackType_e, defiBox* , defiUserData );
static int _pinCbk ( defrCallbackType_e, defiPin* , defiUserData );
static int _componentCbk ( defrCallbackType_e, defiComponent*, defiUserData );
static int _componentEndCbk ( defrCallbackType_e, void* , defiUserData );
static int _netCbk ( defrCallbackType_e, defiNet* , defiUserData );
Cell* _createCell ( const char* name );
private:
static double _defUnits;
static AllianceFramework* _framework;
string _file;
unsigned int _flags;
AllianceLibrary* _library;
Cell* _cell;
size_t _pitchs;
size_t _slices;
Box _fitOnCellsDieArea;
map<string,Net*> _netsLookup;
vector<string> _errors;
};
double DefParser::_defUnits = 0.01;
AllianceFramework* DefParser::_framework = NULL;
DefParser::DefParser ( string& file, AllianceLibrary* library, unsigned int flags )
: _file (file)
, _flags (flags)
, _library (library)
, _cell (NULL)
, _pitchs (0)
, _slices (0)
, _fitOnCellsDieArea()
, _netsLookup ()
, _errors ()
{
defrInit ();
defrSetDesignEndCbk ( _designEndCbk );
defrSetDieAreaCbk ( _dieAreaCbk );
defrSetPinCbk ( _pinCbk );
defrSetComponentCbk ( _componentCbk );
defrSetComponentEndCbk ( _componentEndCbk );
defrSetNetCbk ( _netCbk );
defrSetNetEndCbk ( _componentEndCbk );
}
DefParser::~DefParser ()
{
defrReset ();
}
AllianceFramework* DefParser::getFramework () { return _framework; }
inline DbU::Unit DefParser::fromDefUnits ( int u ) { return DbU::lambda(_defUnits*(double)u); }
inline bool DefParser::hasErrors () { return not _errors.empty(); }
inline unsigned int DefParser::getFlags () const { return _flags; }
inline AllianceLibrary* DefParser::getLibrary () { return _library; }
inline Cell* DefParser::getCell () { return _cell; }
inline size_t DefParser::getPitchs () const { return _pitchs; }
inline size_t DefParser::getSlices () const { return _slices; }
inline const Box& DefParser::getFitOnCellsDieArea () const { return _fitOnCellsDieArea; }
inline vector<string>& DefParser::getErrors () { return _errors; }
inline void DefParser::pushError ( const string& error ) { _errors.push_back(error); }
inline void DefParser::clearErrors () { return _errors.clear(); }
inline void DefParser::setPitchs ( size_t pitchs ) { _pitchs=pitchs; }
inline void DefParser::setSlices ( size_t slices ) { _slices=slices; }
inline void DefParser::mergeToFitOnCellsDieArea ( const Box& box ) { _fitOnCellsDieArea.merge(box); }
Transformation::Orientation DefParser::fromDefOrientation ( int orient )
{
// Note : the codes between DEF & Hurricane matches.
// This function is just to be clear.
switch ( orient ) {
default:
case 0: break; // N, default.
case 1: return Transformation::Orientation::R1; // W
case 2: return Transformation::Orientation::R2; // S
case 3: return Transformation::Orientation::R3; // E
case 4: return Transformation::Orientation::MX; // FN
case 5: return Transformation::Orientation::XR; // FW
case 6: return Transformation::Orientation::MY; // FS
case 7: return Transformation::Orientation::YR; // FE
}
return Transformation::Orientation::ID;
}
Transformation DefParser::getTransformation ( const Box& abox
, DbU::Unit x
, DbU::Unit y
, const Transformation::Orientation orientation
)
{
switch (orientation) {
default:
case Transformation::Orientation::ID: return Transformation ( x, y, orientation );
case Transformation::Orientation::R1: return Transformation ( x, y+abox.getWidth(), orientation );
case Transformation::Orientation::R2: return Transformation ( x+abox.getWidth (), y+abox.getHeight(), orientation );
case Transformation::Orientation::R3: return Transformation ( x+abox.getHeight(), y, orientation );
case Transformation::Orientation::MX: return Transformation ( x+abox.getWidth (), y, orientation );
case Transformation::Orientation::XR: return Transformation ( x+abox.getHeight(), y+abox.getWidth(), orientation );
case Transformation::Orientation::MY: return Transformation ( x, y+abox.getHeight(), orientation );
case Transformation::Orientation::YR: return Transformation ( x+abox.getHeight(), y+abox.getWidth(), orientation );
}
return Transformation ();
}
Cell* DefParser::_createCell ( const char* name )
{
_cell = DefParser::getFramework()->createCell ( name, NULL );
addSupplyNets ( _cell );
return _cell;
}
int DefParser::flushErrors ()
{
int code = (hasErrors()) ? 1 : 0;
for ( size_t ierror=0 ; ierror < _errors.size() ; ++ierror ) {
string message = "DefImport::load(): " + _errors[ierror];
cerr << Error(message.c_str(),getString(_cell->getName()).c_str()) << endl;
}
clearErrors ();
return code;
}
Net* DefParser::lookupNet ( const string& netName )
{
map<string,Net*>::iterator imap = _netsLookup.find(netName);
if ( imap == _netsLookup.end() ) return NULL;
return (*imap).second;
}
void DefParser::addNetLookup ( const string& netName, Net* net )
{
if ( lookupNet(netName) == NULL ) _netsLookup.insert ( make_pair(netName,net) );
}
int DefParser::_designEndCbk ( defrCallbackType_e c, void*, lefiUserData ud )
{
DefParser* parser = (DefParser*)ud;
if ( (parser->getFlags() & DefImport::FitAbOnCells)
and not parser->getFitOnCellsDieArea().isEmpty() ) {
parser->getCell()->setAbutmentBox ( parser->getFitOnCellsDieArea() );
}
return 0;
}
int DefParser::_dieAreaCbk ( defrCallbackType_e c, defiBox* box, lefiUserData ud )
{
DefParser* parser = (DefParser*)ud;
parser->getCell()->setAbutmentBox
( Box ( fromDefUnits(box->xl())
, fromDefUnits(box->yl())
, fromDefUnits(box->xh())
, fromDefUnits(box->yh()) ) );
return 0;
}
int DefParser::_pinCbk ( defrCallbackType_e c, defiPin* pin, lefiUserData ud )
{
DefParser* parser = (DefParser*)ud;
//cout << " - Pin " << pin->pinName() << ":" << pin->netName() << endl;
Net* hnet = parser->getCell()->getNet ( pin->netName() );
if ( hnet == NULL ) {
hnet = Net::create ( parser->getCell(), pin->netName() );
parser->addNetLookup ( pin->netName(), hnet );
if ( string(pin->netName()).compare(pin->pinName()) != 0 )
parser->addNetLookup ( pin->pinName(), hnet );
}
return 0;
}
int DefParser::_componentCbk ( defrCallbackType_e c, defiComponent* component, lefiUserData ud )
{
DefParser* parser = (DefParser*)ud;
string componentName = component->name();
string componentId = component->id();
Cell* masterCell = DefParser::getFramework()->getCell ( componentName, Catalog::State::Views );
if ( masterCell == NULL ) {
ostringstream message;
message << "Unknown model/Cell (LEF MACRO) " << componentName << " in <%s>.";
parser->pushError ( message.str() );
return 0;
}
Transformation placement;
Instance::PlacementStatus state ( Instance::PlacementStatus::UNPLACED );
if ( component->isPlaced() or component->isFixed() ) {
state = (component->isPlaced()) ? Instance::PlacementStatus::PLACED
: Instance::PlacementStatus::FIXED;
placement = getTransformation ( masterCell->getAbutmentBox()
, fromDefUnits(component->placementX())
, fromDefUnits(component->placementY())
, fromDefOrientation ( component->placementOrient() )
);
}
Instance* instance = Instance::create ( parser->getCell()
, componentId
, masterCell
, placement
, state
);
if ( state != Instance::PlacementStatus::UNPLACED ) {
parser->mergeToFitOnCellsDieArea ( instance->getAbutmentBox() );
}
return 0;
}
int DefParser::_netCbk ( defrCallbackType_e c, defiNet* net, lefiUserData ud )
{
static size_t netCount = 0;
DefParser* parser = (DefParser*)ud;
//cout << " - Net " << net->name() << endl;
Net* hnet = parser->lookupNet ( net->name() );
if ( hnet == NULL )
hnet = Net::create ( parser->getCell(), net->name() );
if (tty::enabled()) {
cmess2 << " " << tty::bold << setw(7) << setfill('0') << ++netCount << ":" << setfill(' ')
<< tty::reset << setw(40) << "<" << net->name() << "> " << tty::cr;
cmess2.flush ();
}
int numConnections = net->numConnections();
for ( int icon=0 ; icon<numConnections ; ++icon ) {
string instanceName = net->instance(icon);
string pinName = net->pin(icon);
// Connect to an external pin.
if ( instanceName.compare("PIN") == 0 ) continue;
Instance* instance = parser->getCell()->getInstance ( instanceName );
if ( instance == NULL ) {
ostringstream message;
message << "Unknown instance (DEF COMPONENT) <" << instanceName << "> in <%s>.";
parser->pushError ( message.str() );
continue;
}
Net* masterNet = instance->getMasterCell()->getNet ( pinName );
if ( masterNet == NULL ) {
ostringstream message;
message << "Unknown PIN <" << pinName << "> in instance <"
<< instanceName << "> (LEF MACRO) in <%s>.";
parser->pushError ( message.str() );
continue;
}
instance->getPlug(masterNet)->setNet(hnet);
}
return 0;
}
int DefParser::_componentEndCbk ( defrCallbackType_e c, void*, lefiUserData ud )
{
DefParser* parser = (DefParser*)ud;
return parser->flushErrors ();
}
Cell* DefParser::parse ( string file, unsigned int flags )
{
cmess1 << " o DEF: <" << file << ">" << endl;
size_t iext = file.rfind ( '.' );
if ( file.compare(iext,4,".def") != 0 )
throw Error ("DefImport::load(): DEF files must have \".def\" extension <%s>.",file.c_str());
_framework = AllianceFramework::get ();
size_t islash = file.rfind ( '/' );
string designName = file.substr ( ((islash == string::npos) ? 0 : islash), file.size()-4 );
AllianceLibrary* library = _framework->getAllianceLibrary ( (unsigned int)0 );
auto_ptr<DefParser> parser ( new DefParser(file,library,flags) );
FILE* defStream = fopen ( file.c_str(), "r" );
if ( defStream == NULL )
throw Error ("DefImport::load(): Cannot open DEF file <%s>.",file.c_str());
parser->_createCell ( designName.c_str() );
defrRead ( defStream, file.c_str(), (defiUserData)parser.get(), 1 );
fclose ( defStream );
return parser->getCell();
}
} // End of anonymous namespace.
#endif // HAVE_LEFDEF
namespace CRL {
using std::cerr;
using std::endl;
using std::string;
using Hurricane::UpdateSession;
Cell* DefImport::load ( string design, unsigned int flags )
{
UpdateSession::open ();
Cell* cell = NULL;
#if HAVE_LEFDEF
cell = DefParser::parse ( design+".def", flags );
#else
cerr << "[ERROR] CRL::DefImport::load(): \n"
<< " Coriolis2 hasn't been compiled with LEF/DEF support. To enable LEF/DEF\n"
<< " support, you may obtain parser/driver from Si2 (www.si2.org) then recompile."
<< endl;
#endif
UpdateSession::close ();
return cell;
}
} // End of CRL namespace.

View File

@ -0,0 +1,747 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2010-2010, All Rights Reserved
//
// ===================================================================
//
// $Id$
//
// x-----------------------------------------------------------------x
// | |
// | C O R I O L I S |
// | C a d e n c e D E F E x p o r t e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Module : "./crlcore/LefExport.cpp" |
// | *************************************************************** |
// | U p d a t e s |
// | |
// x-----------------------------------------------------------------x
#include <memory>
#ifdef HAVE_LEFDEF
#include "lefwWriter.hpp"
#include "lefwWriterCalls.hpp"
#endif
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/DataBase.h"
#include "hurricane/RegularLayer.h"
#include "hurricane/Technology.h"
#include "hurricane/Net.h"
#include "hurricane/NetExternalComponents.h"
#include "hurricane/Horizontal.h"
#include "hurricane/Vertical.h"
#include "hurricane/Cell.h"
#include "hurricane/Library.h"
#include "hurricane/UpdateSession.h"
#include "crlcore/Utilities.h"
#include "crlcore/ToolBox.h"
#include "crlcore/RoutingLayerGauge.h"
#include "crlcore/RoutingGauge.h"
#include "crlcore/CellGauge.h"
#include "crlcore/AllianceFramework.h"
#include "crlcore/LefExport.h"
#ifdef HAVE_LEFDEF
namespace {
using namespace std;
using namespace Hurricane;
using namespace CRL;
#define CHECK_STATUS(status) if ((status) != 0) return checkStatus(status);
#define RETURN_CHECK_STATUS(status) return checkStatus(status);
class LefDriver {
public:
static void drive ( const set<Cell*>&
, const string& libraryName
, unsigned int flags
);
static int getUnits ();
static double toLefUnits ( DbU::Unit );
static DbU::Unit getSliceHeight ();
static DbU::Unit getPitchWidth ();
~LefDriver ();
int write ();
private:
LefDriver ( const set<Cell*>&
, const string& libraryName
, unsigned int flags
, FILE*
);
inline unsigned int getFlags () const;
inline const set<Cell*> getCells () const;
inline const string& getLibraryName () const;
inline AllianceFramework* getFramework ();
inline int getStatus () const;
int checkStatus ( int status );
private:
static int _versionCbk ( lefwCallbackType_e, lefiUserData );
static int _busBitCharsCbk ( lefwCallbackType_e, lefiUserData );
static int _clearanceMeasureCbk ( lefwCallbackType_e, lefiUserData );
static int _dividerCharCbk ( lefwCallbackType_e, lefiUserData );
static int _unitsCbk ( lefwCallbackType_e, lefiUserData );
static int _extCbk ( lefwCallbackType_e, lefiUserData );
static int _propDefCbk ( lefwCallbackType_e, lefiUserData );
static int _endLibCbk ( lefwCallbackType_e, lefiUserData );
static int _layerCbk ( lefwCallbackType_e, lefiUserData );
static int _macroCbk ( lefwCallbackType_e, lefiUserData );
static int _manufacturingGridCbk ( lefwCallbackType_e, lefiUserData );
static int _nonDefaultCbk ( lefwCallbackType_e, lefiUserData );
static int _siteCbk ( lefwCallbackType_e, lefiUserData );
static int _spacingCbk ( lefwCallbackType_e, lefiUserData );
static int _useMinSpacingCbk ( lefwCallbackType_e, lefiUserData );
static int _viaCbk ( lefwCallbackType_e, lefiUserData );
static int _viaRuleCbk ( lefwCallbackType_e, lefiUserData );
int _driveRoutingLayer ( RoutingLayerGauge* );
int _driveCutLayer ( Layer* );
int _driveMacro ( Cell* );
private:
static AllianceFramework* _framework;
static int _units;
static DbU::Unit _sliceHeight;
static DbU::Unit _pitchWidth;
unsigned int _flags;
const set<Cell*> _cells;
string _libraryName;
FILE* _lefStream;
int _status;
};
int LefDriver::_units = 100;
AllianceFramework* LefDriver::_framework = NULL;
int LefDriver::getUnits () { return _units; }
double LefDriver::toLefUnits ( DbU::Unit u ) { return DbU::getLambda(u)/**getUnits()*/; }
DbU::Unit LefDriver::getSliceHeight () { return _sliceHeight; }
DbU::Unit LefDriver::getPitchWidth () { return _pitchWidth; };
inline AllianceFramework* LefDriver::getFramework () { return _framework; }
inline unsigned int LefDriver::getFlags () const { return _flags; }
inline const set<Cell*> LefDriver::getCells () const { return _cells; }
inline int LefDriver::getStatus () const { return _status; }
inline const string& LefDriver::getLibraryName () const { return _libraryName; }
LefDriver::LefDriver ( const set<Cell*>& cells, const string& libraryName, unsigned int flags, FILE* lefStream )
: _flags (flags)
, _cells (cells)
, _libraryName(libraryName)
, _lefStream (lefStream)
, _status (0)
{
if ( _framework == NULL ) {
_framework = AllianceFramework::get ();
CellGauge* cg = _framework->getCellGauge("sxlib");
_sliceHeight = cg->getSliceHeight ();
_pitchWidth = cg->getPitch ();
}
_status = lefwInitCbk ( _lefStream );
if ( _status != 0 ) return;
lefwSetVersionCbk ( _versionCbk );
lefwSetBusBitCharsCbk ( _busBitCharsCbk );
lefwSetDividerCharCbk ( _dividerCharCbk );
lefwSetSiteCbk ( _siteCbk );
lefwSetUnitsCbk ( _unitsCbk );
lefwSetManufacturingGridCbk ( _manufacturingGridCbk );
lefwSetClearanceMeasureCbk ( _clearanceMeasureCbk );
lefwSetExtCbk ( _extCbk );
lefwSetLayerCbk ( _layerCbk );
lefwSetMacroCbk ( _macroCbk );
lefwSetPropDefCbk ( _propDefCbk );
lefwSetSpacingCbk ( _spacingCbk );
lefwSetUseMinSpacingCbk ( _useMinSpacingCbk );
lefwSetNonDefaultCbk ( _nonDefaultCbk );
lefwSetViaCbk ( _viaCbk );
lefwSetViaRuleCbk ( _viaRuleCbk );
lefwSetEndLibCbk ( _endLibCbk );
}
LefDriver::~LefDriver ()
{ }
int LefDriver::write ()
{
return checkStatus ( lefwWrite(_lefStream,_libraryName.c_str(),(void*)this) );
}
int LefDriver::checkStatus ( int status )
{
if ( (_status=status) != 0 ) {
lefwPrintError ( _status );
cerr << Error("LefDriver::drive(): Error occured while driving <%s>.",_libraryName.c_str()) << endl;
}
return _status;
}
int LefDriver::_driveRoutingLayer ( RoutingLayerGauge* lg )
{
if ( lg == NULL ) return 0;
_status = lefwStartLayerRouting ( getString(lg->getLayer()->getName()).c_str() );
if ( _status != 0 ) return _status;
_status = lefwLayerRouting ( (lg->getDirection() == Constant::Horizontal) ? "HORIZONTAL" : "VERTICAL"
, toLefUnits(lg->getWireWidth())
);
if ( _status != 0 ) return _status;
_status = lefwLayerRoutingOffset ( toLefUnits(lg->getOffset()) );
if ( _status != 0 ) return _status;
_status = lefwLayerRoutingPitch ( toLefUnits(lg->getPitch()) );
if ( _status != 0 ) return _status;
_status = lefwLayerRoutingSpacing ( toLefUnits(lg->getPitch()-lg->getWireWidth()-DbU::lambda(1.0)) );
if ( _status != 0 ) return _status;
return _status = lefwEndLayerRouting ( getString(lg->getLayer()->getName()).c_str() );
}
int LefDriver::_driveCutLayer ( Layer* layer )
{
if ( layer == NULL ) return 0;
_status = lefwStartLayer ( getString(layer->getName()).c_str(), "CUT" );
if ( _status != 0 ) return _status;
_status = lefwLayerWidth ( toLefUnits(DbU::lambda(1.0)) );
if ( _status != 0 ) return _status;
return _status = lefwEndLayer ( getString(layer->getName()).c_str() );
}
int LefDriver::_driveMacro ( Cell* cell )
{
_status = lefwStartMacro ( getString(cell->getName()).c_str() );
CHECK_STATUS(_status);
Box abutmentBox ( cell->getAbutmentBox() );
double pitchWidth = toLefUnits ( LefDriver::getPitchWidth () );
double sliceHeight = toLefUnits ( LefDriver::getSliceHeight() );
int slices = (int)floor( abutmentBox.getHeight() / LefDriver::getSliceHeight() );
int pitchs = (int)floor( abutmentBox.getWidth () / LefDriver::getPitchWidth () );
_status = lefwMacroClass ( (slices > 1) ? "BLOCK" : "CORE"
, (slices > 1) ? "BLACKBOX" : NULL
);
CHECK_STATUS(_status);
double originX = toLefUnits ( abutmentBox.getXMin() );
double originY = toLefUnits ( abutmentBox.getYMin() );
if ( (originX != 0.0) or (originY != 0.0) )
cerr << Warning("Cell <%s> origin is in (%s,%s), shifting to (0,0)."
,getString(cell->getName()).c_str()
,DbU::getValueString(abutmentBox.getXMin()).c_str()
,DbU::getValueString(abutmentBox.getYMin()).c_str()
) << endl;
_status = lefwMacroOrigin ( 0.0, 0.0 );
CHECK_STATUS(_status);
double sizeX = toLefUnits ( abutmentBox.getWidth () );
double sizeY = toLefUnits ( abutmentBox.getHeight() );
_status = lefwMacroSize ( sizeX, sizeY );
CHECK_STATUS(_status);
_status = lefwMacroSymmetry ( "X Y" );
CHECK_STATUS(_status);
_status = lefwMacroSite ( "core" );
CHECK_STATUS(_status);
if ( slices > 1 ) {
for ( int islice=0 ; islice<slices ; ++islice ) {
_status = lefwMacroSitePatternStr ( "core" // site name.
, originX // X origin.
, originY + sliceHeight*islice // Y origin.
, (islice % 2) ? "FS" : "N" // orientation.
, pitchs // num X.
, 1 // num Y.
, pitchWidth // space X (STEP X).
, sliceHeight // space Y (STEP Y).
);
CHECK_STATUS(_status);
}
}
Net* obstacleNet = NULL;
forEach ( Net*, inet, cell->getNets() ) {
Net* net = *inet;
if ( (obstacleNet == NULL) and _framework->isOBSTACLE(net->getName()) )
obstacleNet = net;
if ( not net->isExternal() ) continue;
_status = lefwStartMacroPin ( getString(net->getName()).c_str() );
CHECK_STATUS(_status);
_status = lefwMacroPinDirection ( "INPUT" );
CHECK_STATUS(_status);
if ( net->isSupply() ) {
_status = lefwMacroPinShape ( "ABUTMENT" );
CHECK_STATUS(_status);
}
const char* pinUse = "SIGNAL";
if ( net->isGround() ) pinUse = "GROUND";
else if ( net->isPower () ) pinUse = "POWER";
else if ( net->isClock () ) pinUse = "CLOCK";
_status = lefwMacroPinUse ( pinUse );
CHECK_STATUS(_status);
_status = lefwStartMacroPinPort ( NULL );
CHECK_STATUS(_status);
const Layer* layer = NULL;
forEach ( Component*, icomponent, net->getComponents() ) {
if ( not NetExternalComponents::isExternal(*icomponent) ) continue;
if ( layer != (*icomponent)->getLayer() ) {
layer = (*icomponent)->getLayer();
_status = lefwMacroPinPortLayer ( getString(layer->getName()).c_str(), 0 );
CHECK_STATUS(_status);
}
Box bb ( (*icomponent)->getBoundingBox() );
_status = lefwMacroPinPortLayerRect ( toLefUnits(bb.getXMin())-originX // xl
, toLefUnits(bb.getYMin())-originY // yl
, toLefUnits(bb.getXMax())-originX // xh
, toLefUnits(bb.getYMax())-originY // yh
, 0 // ITERATE numX
, 0 // ITERATE numY
, 0 // ITERATE spaceX
, 0 // ITERATE spaceY
);
CHECK_STATUS(_status);
}
_status = lefwEndMacroPinPort ();
CHECK_STATUS(_status);
_status = lefwEndMacroPin ( getString(net->getName()).c_str() );
CHECK_STATUS(_status);
}
#if 0
_status = lefwStartMacroObs ();
CHECK_STATUS(_status);
double supplyHalfWidth = toLefUnits ( DbU::lambda(6.0) );
double sliceHeight = toLefUnits ( LefDriver::getSliceHeight() );
#endif
double METAL1HalfMinDist = toLefUnits ( DbU::lambda(1.0) );
#if 0
_status = lefwMacroObsLayer ( "METAL1", METAL1HalfMinDist );
CHECK_STATUS(_status);
_status = lefwMacroObsLayerRect ( METAL1HalfMinDist // xl
, METAL1HalfMinDist + supplyHalfWidth // yl
, sizeX - METAL1HalfMinDist // xh
, sliceHeight - METAL1HalfMinDist - supplyHalfWidth // yh
, 1 // ITERATE columns
, slices // ITERATE rows
, sizeX // ITERATE spaceX
, toLefUnits(LefDriver::getSliceHeight()) // ITERATE spaceY
);
CHECK_STATUS(_status);
#endif
if ( obstacleNet != 0 ) {
_status = lefwStartMacroObs ();
CHECK_STATUS(_status);
const Layer* blockageLayer = NULL;
forEach ( Component*, icomponent, obstacleNet->getComponents() ) {
if ( dynamic_cast<Segment*>(*icomponent) == NULL ) continue;
if ( blockageLayer != (*icomponent)->getLayer() ) {
blockageLayer = (*icomponent)->getLayer();
RegularLayer* routingLayer = NULL;
forEach ( RegularLayer*, ilayer, DataBase::getDB()->getTechnology()->getRegularLayers() ) {
if ( (*ilayer)->getBlockageLayer() == NULL ) continue;
if ( (*ilayer)->getBlockageLayer()->getMask() != blockageLayer->getMask() ) continue;
routingLayer = *ilayer;
break;
}
if ( routingLayer != NULL ) {
_status = lefwMacroObsLayer ( getString(routingLayer->getName()).c_str(), METAL1HalfMinDist );
CHECK_STATUS(_status);
}
}
Box bb ( (*icomponent)->getBoundingBox() );
_status = lefwMacroObsLayerRect ( toLefUnits(bb.getXMin())-originX // xl
, toLefUnits(bb.getYMin())-originY // yl
, toLefUnits(bb.getXMax())-originX // xh
, toLefUnits(bb.getYMax())-originY // yh
, 0 // ITERATE numX
, 0 // ITERATE numY
, 0 // ITERATE spaceX
, 0 // ITERATE spaceY
);
CHECK_STATUS(_status);
}
_status = lefwEndMacroObs ();
CHECK_STATUS(_status);
}
#if 0
_status = lefwEndMacroObs ();
CHECK_STATUS(_status);
#endif
_status = lefwEndMacro ( getString(cell->getName()).c_str() );
RETURN_CHECK_STATUS(_status);
}
int LefDriver::_versionCbk ( lefwCallbackType_e, lefiUserData udata )
{
LefDriver* driver = (LefDriver*)udata;
ostringstream comment;
comment << "For design <" << driver->getLibraryName() << ">.";
lefwNewLine ();
lefwAddComment ( "LEF generated by Coriolis2 DEF exporter." );
lefwAddComment ( comment.str().c_str() );
lefwNewLine ();
return driver->checkStatus ( lefwVersion(5,7) );
}
int LefDriver::_busBitCharsCbk ( lefwCallbackType_e, lefiUserData udata )
{
LefDriver* driver = (LefDriver*)udata;
lefwNewLine ();
return driver->checkStatus ( lefwBusBitChars("()") );
}
int LefDriver::_dividerCharCbk ( lefwCallbackType_e, lefiUserData udata )
{
LefDriver* driver = (LefDriver*)udata;
return driver->checkStatus ( lefwDividerChar(".") );
}
int LefDriver::_unitsCbk ( lefwCallbackType_e, lefiUserData udata )
{
LefDriver* driver = (LefDriver*)udata;
lefwNewLine ();
int status = lefwStartUnits ();
if ( status != 0 ) return driver->checkStatus(status);
status = lefwUnits ( 0 // time.
, 0 // capacitance.
, 0 // resistance.
, 0 // power.
, 0 // current.
, 0 // voltage.
, LefDriver::getUnits() // database.
);
if ( status != 0 ) return driver->checkStatus(status);
return driver->checkStatus ( lefwEndUnits() );
}
int LefDriver::_layerCbk ( lefwCallbackType_e, lefiUserData udata )
{
LefDriver* driver = (LefDriver*)udata;
Technology* technology = DataBase::getDB()->getTechnology();
const vector<RoutingLayerGauge*>& rg
= driver->getFramework()->getRoutingGauge("sxlib")->getLayerGauges();
int status = 0;
for ( size_t ilayer=0 ; ilayer<rg.size() ; ++ilayer ) {
if ( ilayer > 0 ) {
status = driver->_driveCutLayer ( technology->getCutBelow(rg[ilayer]->getLayer()) );
if ( status != 0 ) return driver->checkStatus(status);
}
status = driver->_driveRoutingLayer ( rg[ilayer] );
if ( status != 0 ) return driver->checkStatus(status);
}
return status;
}
int LefDriver::_siteCbk ( lefwCallbackType_e, lefiUserData udata )
{
LefDriver* driver = (LefDriver*)udata;
int status = lefwSite ( "core"
, "CORE"
, "Y"
, toLefUnits(LefDriver::getPitchWidth ())
, toLefUnits(LefDriver::getSliceHeight())
);
if ( status != 0 ) return driver->checkStatus(status);
return driver->checkStatus(lefwEndSite("core"));
}
int LefDriver::_extCbk ( lefwCallbackType_e, lefiUserData udata )
{
//LefDriver* driver = (LefDriver*)udata;
return 0;
}
int LefDriver::_propDefCbk ( lefwCallbackType_e, lefiUserData udata )
{
//LefDriver* driver = (LefDriver*)udata;
return 0;
}
int LefDriver::_clearanceMeasureCbk ( lefwCallbackType_e, lefiUserData udata )
{
//LefDriver* driver = (LefDriver*)udata;
return 0;
}
int LefDriver::_endLibCbk ( lefwCallbackType_e, lefiUserData udata )
{
LefDriver* driver = (LefDriver*)udata;
return driver->checkStatus ( lefwEnd() );
}
int LefDriver::_macroCbk ( lefwCallbackType_e, lefiUserData udata )
{
LefDriver* driver = (LefDriver*)udata;
const set<Cell*>& cells = driver->getCells ();
set<Cell*>::const_iterator icell = cells.begin();
for ( ; (icell != cells.end()) and (driver->getStatus() == 0) ; ++icell ) {
driver->_driveMacro ( *icell );
}
return driver->getStatus();
}
int LefDriver::_manufacturingGridCbk ( lefwCallbackType_e, lefiUserData udata )
{
#if 0
// The driver puts it before UNITS, which seems to displease Cadence Encounter.
// So, as long as it doesn't prevent Encounter to works, disable it.
LefDriver* driver = (LefDriver*)udata;
return driver->checkStatus ( lefwManufacturingGrid ( LefDriver::getUnits()/10.0 ) );
#else
return 0;
#endif
}
int LefDriver::_nonDefaultCbk ( lefwCallbackType_e, lefiUserData udata )
{
//LefDriver* driver = (LefDriver*)udata;
return 0;
}
int LefDriver::_spacingCbk ( lefwCallbackType_e, lefiUserData udata )
{
//LefDriver* driver = (LefDriver*)udata;
return 0;
}
int LefDriver::_useMinSpacingCbk ( lefwCallbackType_e, lefiUserData udata )
{
//LefDriver* driver = (LefDriver*)udata;
return 0;
}
int LefDriver::_viaCbk ( lefwCallbackType_e, lefiUserData udata )
{
LefDriver* driver = (LefDriver*)udata;
Technology* technology = DataBase::getDB()->getTechnology();
const vector<RoutingLayerGauge*>& rg
= driver->getFramework()->getRoutingGauge("sxlib")->getLayerGauges();
int status = 0;
for ( size_t ilayer=1 ; ilayer<rg.size() ; ++ilayer ) {
const Layer* topLayer = rg[ilayer]->getLayer();
const Layer* bottomLayer = topLayer->getMetalBelow();
const Layer* cutLayer = topLayer->getCutBelow();
const Layer* viaLayer = technology->getViaBetween ( topLayer, bottomLayer );
status = lefwStartVia ( getString(viaLayer->getName()).c_str(), "DEFAULT" );
if ( status != 0 ) return driver->checkStatus(status);
// Bottom Layer.
status = lefwViaLayer ( getString(bottomLayer->getName()).c_str() );
if ( status != 0 ) return driver->checkStatus(status);
double side = toLefUnits ( (ilayer == 1) ? DbU::lambda(1.0) : DbU::lambda(1.5) );
status = lefwViaLayerRect ( -side
, -side
, side
, side
);
if ( status != 0 ) return driver->checkStatus(status);
// Cut Layer.
status = lefwViaLayer ( getString(cutLayer->getName()).c_str() );
if ( status != 0 ) return driver->checkStatus(status);
side = toLefUnits ( DbU::lambda(0.5) );
status = lefwViaLayerRect ( -side
, -side
, side
, side
);
if ( status != 0 ) return driver->checkStatus(status);
// Top Layer.
status = lefwViaLayer ( getString(topLayer->getName()).c_str() );
if ( status != 0 ) return driver->checkStatus(status);
side = toLefUnits ( DbU::lambda(1.5) );
status = lefwViaLayerRect ( -side
, -side
, side
, side
);
if ( status != 0 ) return driver->checkStatus(status);
status = lefwEndVia ( getString(viaLayer->getName()).c_str() );
if ( status != 0 ) return driver->checkStatus(status);
}
return 0;
return 0;
}
int LefDriver::_viaRuleCbk ( lefwCallbackType_e, lefiUserData udata )
{
//LefDriver* driver = (LefDriver*)udata;
return 0;
}
void LefDriver::drive ( const set<Cell*>& cells, const string& libraryName, unsigned int flags )
{
FILE* lefStream = NULL;
try {
string path = "./" + libraryName + ".lef";
cmess1 << " o Export LEF: <" << path << ">" << endl;
lefStream = fopen ( path.c_str(), "w" );
if ( lefStream == NULL )
throw Error("LefDriver::drive(): Cannot open <%s>.",path.c_str());
auto_ptr<LefDriver> driver ( new LefDriver(cells,libraryName,flags,lefStream) );
driver->write ();
}
catch ( ... ) {
if ( lefStream != NULL ) fclose ( lefStream );
throw;
}
fclose ( lefStream );
}
} // End of anonymous namespace.
#endif // HAVE_LEFDEF.
namespace CRL {
using std::string;
using Hurricane::Library;
using Hurricane::Transformation;
using Hurricane::UpdateSession;
void LefExport::drive ( Cell* cell, unsigned int flags )
{
#if HAVE_LEFDEF
string libraryName = "symbolic";
set<Cell*> cells;
if ( cell != NULL ) {
libraryName = getString(cell->getName()) + "export";
forEach ( Instance*, iinstance, cell->getInstances() ) {
if ( cells.find((*iinstance)->getMasterCell()) == cells.end())
cells.insert ( (*iinstance)->getMasterCell() );
}
}
LefDriver::drive ( cells, libraryName, flags );
#else
cerr << "[ERROR] CRL::LefExport::drive(Cell*): \n"
<< " Coriolis2 hasn't been compiled with LEF/DEF support. To enable LEF/DEF"
<< " support, you may contact Si2 (www.si2.org) then recompile."
<< endl;
#endif
}
void LefExport::drive ( Library* library, unsigned int flags )
{
#ifdef HAVE_LEFDEF
string libraryName = "symbolic";
set<Cell*> cells;
if ( library != NULL ) {
libraryName = getString(library->getName());
forEach ( Cell*, icell, library->getCells() ) {
if ( cells.find(*icell) == cells.end())
cells.insert ( *icell );
}
}
LefDriver::drive ( cells, libraryName, flags );
#else
cerr << "[ERROR] CRL::LefExport::drive(Library*): \n"
<< " Coriolis2 hasn't been compiled with LEF/DEF support. To enable LEF/DEF\n"
<< " support, you may obtain parser/driver from Si2 (www.si2.org) then recompile."
<< endl;
#endif
}
} // End of CRL namespace.

View File

@ -143,7 +143,7 @@ int main ( int argc, char *argv[] )
dbo_ptr<AllianceFramework> af ( AllianceFramework::create() );
// Technology* technology = DataBase::getDB()->getTechnology();
Technology* technology = DataBase::getDB()->getTechnology();
// technology->setWorkingLayer ( "cut0" );
// technology->setWorkingLayer ( "cut1" );
// technology->setWorkingLayer ( "cut2" );
@ -162,6 +162,11 @@ int main ( int argc, char *argv[] )
// technology->setWorkingLayer ( "VIA45" );
// technology->setWorkingLayer ( "VIA56" );
Layer* contact = technology->getLayer("CONT_POLY");
cerr << "CONT_POLY Mask " << contact->getMask() << endl;
cerr << contact->getTop() << " is top of CONT_POLY" << endl;
cerr << contact->getBottom() << " is bottom of CONT_POLY" << endl;
// Layer* metal2 = technology->getLayer("METAL2");
// Layer* above = technology->getLayer("METAL2")->getMetalAbove();
// cerr << above << " is above METAL2" << endl;