Clean parameters for routing topologies. Improved 2RL- support.
Previously, the relevant NetBuilder and routing strategies where directly guessed from the RoutingGauge traits. This is no longer doable as the combinations increases. Now to configure both the global and detailed router we need three "parameters" : 1. The routing gauge itself (tells which layers are in which directions) and how to make the VIAs. 2. The NetBuilder to use, they are identified by strings. Currently we support: * "HV,3RL+", for all SxLib derived standard cells. * "VH,2RL", for hybrid routing (over the cell, but terminals are also in the first RL). * "2RL-", for strict channel routing. * "VH,3RL+", an attempt for FreePDK 45, not optimized enough to be considered as usable. 3. The routing style, mostly affect the way the GCell grid will be built. * VH : first RL is V. * HV : first RL is H. * OTH : Run in full over-the-cell mode (needs at least 3RL). * Channel : Run in *strict* channel routing mode (no routing over the standard cells). * Hybrid : Create channels, but can use H tracks over the standard cells. Thoses three parameters are partly overlapping and must be sets in a consistent manner, otherwise strange results may occurs. * New: CRL::RoutingGauge::getFirstRoutingGauge(), to get the lowest layer available for routing (not a PinOnly, not a PowerSupply). * Change: In CRL::RoutingGauge::isHV() and isVH(), were previously always returning false when the gauge was 2RL only. Now, check on the first usable RL. * Bug: In cumulus/plugins.block.configuration._loadRoutingGauge(), there was a bad computation of the deep RLs when the top layer was not defined. Occured for 2RL gauges only. * Bug: In Anabatic::RpsInRow::slacken() (LayerAssign), forgotten curly braces in the test to skip METAL2 terminals. * Change: In Etestian::BloatChannel::getDx(), adjust the bloating policy to converge on Arlet6502. Always ensure that there is a 50% ratio between terminal used V-tracks and free ones. If there is more than 80% of terminals, add one more track. * Bug: In AnabaticEngine & KatanaEngine, KatanaEngine is a derived class of AnabaticEngine. They uses Anabatic::Configuration and Katana::Configuration that also derives from each other. I though I had made one configuration attribute in the base class that was using the right Configuration. But no. I did have two configurations attributes, one in AnabaticEngine and one in KatanaEngine, the later "shadowing" the former. As a results, parameters modified in AnabaticEngine, *after* the initial creation of the tool *where never seen* at Katana level (due to it's own duplicate). What a mess. Now there is only one attribute in the *base* class Anabatic, which is created through a new virtual function _createConfiguration() called in _postCreate() which allocate the right Configuration according to the dynamic type of the tool (KatanaEngine). In KatanaEngine, access the configuration through the attribute (_configuration) and not the accessor (getConfiguration()). * Bug: In KatanaEngine, no longer directly use the _configuration attribute (which is not accessible anyway) but the getConfiguration() accessor. The accessor perform a static_cast from the Super::getConfiguration() into Katana::Configuration. Complete cleanup of the various configuration accessors. * New: AnabaticEngine::setupNetBuilder(), perform an early check of the requested NetBuilderStyle. The NetBuilderStyle is just a string that will be matched against the (hard-coded) supported NetBuilders. Then check the topological characteristics against the capabilities of the gauge (HV, VH and so on). Still a bit too hard-coded for now. This function has been split from AnabaticEngine::_loadGrByNet(). * Change: AnabaticEngine::isChannelStyle() renamed from isChannelMode(). * New: In Anabatic::Configuration, two new attributes to select the topology and routing style: - _netBuilderStyle to explicitely select the NetBuilder to use. It's a string, which is provided by each NetBuilder. - _routingStyle to define how the overall routing will work. It's a set of flags (StyleFlags): * VH : first RL is V. * HV : first RL is H. * OTH : Run in full over-the-cell mode (needs at least 3RL). * Channel : Run in *strict* channel routing mode (no routing over the standard cells). * Hybrid : Create channels, but can use H tracks over the standard cells. * New: In anabatic/Constants, add StyleFlags to define how the router should operate (see above). * Bug: In Anabatic::GCell, in CTOR, no reason to set up the HChannelGCell flag. * Bug: In Anabatic::GCell::updateDensity(), when computing layers non contiguous saturation, do not systematically skip RL 0, but only if it's PinOnly. * Change: In Anabatic::NetBuilder, rename isTwoMetal by isStrictChannel. * Change: In Anabatic::NetBuilderHV, rename doRp_AccessNorthPin() in doRp_AccessNorthSouthPin(). More accurate. * Bug: In NetBuilderHV::_do_1G_xM1_1PinM2(), the wires to connect the M1 terminals where created *twice*. Uterly stupid, there where placed in overlap by the router! * New: In AnabaticEngine, new accessors to the NetBuilderStyle and RoutingStyle, proxies towards Configuration. * Bug: In Manipulator::relax(), if there are two doglegs to be done, but they are in the same GCell, only do one (the conflicting interval) is short. * Change: In Katana::Session, rename isChannelMode() into isChannelStyle(). * Change: In TrackSegment::isUnbreakable() and isStrap(), return false when the base segment is a *weak global* (aligned with a global one). * Change: In Katana::Row::createChannel(), correctly distinguish between *strict channel* style and *hybrid* style. Tag the GCells as std cells row or channels only in the former case.
This commit is contained in:
parent
e262c7bd1a
commit
c131e7a948
|
@ -34,6 +34,7 @@
|
|||
#include "crlcore/Histogram.h"
|
||||
#include "anabatic/GCell.h"
|
||||
#include "anabatic/AutoContactTerminal.h"
|
||||
#include "anabatic/NetBuilderHybridVH.h"
|
||||
#include "anabatic/NetBuilderM2.h"
|
||||
#include "anabatic/NetBuilderHV.h"
|
||||
#include "anabatic/NetBuilderVH.h"
|
||||
|
@ -383,25 +384,27 @@ namespace Anabatic {
|
|||
, _edgeCapacitiesLut()
|
||||
, _blockageNet (cell->getNet("blockagenet"))
|
||||
, _diodeCell (NULL)
|
||||
{
|
||||
_matrix.setCell( cell, _configuration->getSliceHeight() );
|
||||
Edge::unity = _configuration->getSliceHeight();
|
||||
|
||||
if (not _blockageNet) {
|
||||
_blockageNet = Net::create( cell, "blockagenet" );
|
||||
_blockageNet->setType( Net::Type::BLOCKAGE );
|
||||
}
|
||||
}
|
||||
{ }
|
||||
|
||||
|
||||
void AnabaticEngine::_postCreate ()
|
||||
{
|
||||
Super::_postCreate();
|
||||
|
||||
_diodeCell = DataBase::getDB()->getCell( getConfiguration()->getDiodeName() );;
|
||||
_configuration = _createConfiguration();
|
||||
setupNetBuilder();
|
||||
_matrix.setCell( getCell(), _configuration->getSliceHeight() );
|
||||
Edge::unity = _configuration->getSliceHeight();
|
||||
|
||||
if (not _blockageNet) {
|
||||
_blockageNet = Net::create( getCell(), "blockagenet" );
|
||||
_blockageNet->setType( Net::Type::BLOCKAGE );
|
||||
}
|
||||
|
||||
_diodeCell = DataBase::getDB()->getCell( _configuration->getDiodeName() );;
|
||||
if (not _diodeCell) {
|
||||
cerr << Warning( "AnabaticEngine::_postCreate() Unable to find \"%s\" diode cell."
|
||||
, getConfiguration()->getDiodeName().c_str()
|
||||
, _configuration->getDiodeName().c_str()
|
||||
) << endl;
|
||||
}
|
||||
|
||||
|
@ -412,6 +415,10 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
Configuration* AnabaticEngine::_createConfiguration ()
|
||||
{ return new Configuration(); }
|
||||
|
||||
|
||||
AnabaticEngine* AnabaticEngine::create ( Cell* cell )
|
||||
{
|
||||
if (not cell) throw Error( "AnabaticEngine::create(): NULL cell argument." );
|
||||
|
@ -623,7 +630,7 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
|
||||
RoutingGauge* rg = getConfiguration()->getRoutingGauge();
|
||||
RoutingGauge* rg = _configuration->getRoutingGauge();
|
||||
size_t errorCount = 0;
|
||||
ostringstream errors;
|
||||
errors << "AnabaticEngine::checkPlacement():\n";
|
||||
|
@ -852,7 +859,7 @@ namespace Anabatic {
|
|||
if (horizontal) {
|
||||
splitted = Horizontal::create( breakContact
|
||||
, targetContact
|
||||
, getConfiguration()->getGHorizontalLayer()
|
||||
, _configuration->getGHorizontalLayer()
|
||||
, horizontal->getY()
|
||||
, DbU::fromLambda(2.0)
|
||||
);
|
||||
|
@ -861,7 +868,7 @@ namespace Anabatic {
|
|||
if (vertical) {
|
||||
splitted = Vertical::create( breakContact
|
||||
, targetContact
|
||||
, getConfiguration()->getGVerticalLayer()
|
||||
, _configuration->getGVerticalLayer()
|
||||
, vertical->getX()
|
||||
, DbU::fromLambda(2.0)
|
||||
);
|
||||
|
@ -1097,7 +1104,7 @@ namespace Anabatic {
|
|||
|
||||
for ( Net* net : getCell()->getNets() ) {
|
||||
for ( Component* component : net->getComponents() ) {
|
||||
if (getConfiguration()->isGLayer(component->getLayer())) {
|
||||
if (_configuration->isGLayer(component->getLayer())) {
|
||||
cerr << Error( "AnabaticEngine::cleanupGlobal(): Remaining global routing,\n"
|
||||
" %s"
|
||||
, getString(component).c_str()
|
||||
|
@ -1124,7 +1131,7 @@ namespace Anabatic {
|
|||
}
|
||||
cleanupGlobal();
|
||||
|
||||
if (not getConfiguration()->isTwoMetals()) relaxOverConstraineds();
|
||||
if (not _configuration->isTwoMetals()) relaxOverConstraineds();
|
||||
|
||||
_state = EngineActive;
|
||||
}
|
||||
|
@ -1241,6 +1248,64 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
void AnabaticEngine::setupNetBuilder ()
|
||||
{
|
||||
uint32_t gaugeKind = 4;
|
||||
if (NetBuilderHybridVH::getStyle() == getNetBuilderStyle()) gaugeKind = 0;
|
||||
else if (NetBuilderM2 ::getStyle() == getNetBuilderStyle()) gaugeKind = 1;
|
||||
else if (NetBuilderVH ::getStyle() == getNetBuilderStyle()) gaugeKind = 2;
|
||||
else if (NetBuilderHV ::getStyle() == getNetBuilderStyle()) gaugeKind = 3;
|
||||
|
||||
if (gaugeKind == 0) {
|
||||
if (not _configuration->isVH())
|
||||
throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"."
|
||||
, getString(_configuration->getRoutingGauge()->getName()).c_str()
|
||||
, getNetBuilderStyle().c_str() );
|
||||
if (getRoutingStyle() == StyleFlags::NoStyle) {
|
||||
_configuration->setRoutingStyle( StyleFlags::VH
|
||||
| StyleFlags::Channel
|
||||
| StyleFlags::Hybrid );
|
||||
}
|
||||
}
|
||||
else if (gaugeKind == 1) {
|
||||
if (getRoutingStyle() == StyleFlags::NoStyle) {
|
||||
_configuration->setRoutingStyle( StyleFlags::Channel );
|
||||
}
|
||||
}
|
||||
else if (gaugeKind == 2) {
|
||||
if (not _configuration->isVH())
|
||||
throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"."
|
||||
, getString(_configuration->getRoutingGauge()->getName()).c_str()
|
||||
, getNetBuilderStyle().c_str() );
|
||||
if (_configuration->getRoutingGauge()->getUsableLayers() < 3)
|
||||
throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"."
|
||||
, getString(_configuration->getRoutingGauge()->getName()).c_str()
|
||||
, getNetBuilderStyle().c_str() );
|
||||
if (getRoutingStyle() == StyleFlags::NoStyle) {
|
||||
_configuration->setRoutingStyle( StyleFlags::VH
|
||||
| StyleFlags::OTH );
|
||||
}
|
||||
}
|
||||
else if (gaugeKind == 3) {
|
||||
if (not _configuration->isHV())
|
||||
throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"."
|
||||
, getString(_configuration->getRoutingGauge()->getName()).c_str()
|
||||
, getNetBuilderStyle().c_str() );
|
||||
if (_configuration->getRoutingGauge()->getUsableLayers() < 3)
|
||||
throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"."
|
||||
, getString(_configuration->getRoutingGauge()->getName()).c_str()
|
||||
, getNetBuilderStyle().c_str() );
|
||||
if (getRoutingStyle() == StyleFlags::NoStyle) {
|
||||
_configuration->setRoutingStyle( StyleFlags::HV
|
||||
| StyleFlags::OTH );
|
||||
}
|
||||
}
|
||||
if (gaugeKind == 4) {
|
||||
throw Error( "AnabaticEngine::_loadGrByNet(): Unsupported kind of routing auge style \"%s\"."
|
||||
, getNetBuilderStyle().c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
void AnabaticEngine::_loadGrByNet ()
|
||||
{
|
||||
cmess1 << " o Building detailed routing from global. " << endl;
|
||||
|
@ -1250,12 +1315,13 @@ namespace Anabatic {
|
|||
startMeasures();
|
||||
openSession();
|
||||
|
||||
int gaugeKind = 3;
|
||||
if (getConfiguration()->isTwoMetals()) gaugeKind = 0;
|
||||
if (getConfiguration()->isHV ()) gaugeKind = 1;
|
||||
if (getConfiguration()->isVH ()) gaugeKind = 2;
|
||||
uint32_t gaugeKind = 4;
|
||||
if (NetBuilderHybridVH::getStyle() == getNetBuilderStyle()) gaugeKind = 0;
|
||||
else if (NetBuilderM2 ::getStyle() == getNetBuilderStyle()) gaugeKind = 1;
|
||||
else if (NetBuilderVH ::getStyle() == getNetBuilderStyle()) gaugeKind = 2;
|
||||
else if (NetBuilderHV ::getStyle() == getNetBuilderStyle()) gaugeKind = 3;
|
||||
|
||||
if (gaugeKind < 3) {
|
||||
if (gaugeKind < 4) {
|
||||
for ( Net* net : getCell()->getNets() ) {
|
||||
if (NetRoutingExtension::isShortNet(net)) {
|
||||
//AutoSegment::setShortNetMode( true );
|
||||
|
@ -1269,9 +1335,10 @@ namespace Anabatic {
|
|||
AutoSegment::setAnalogMode( NetRoutingExtension::isAnalog(net) );
|
||||
|
||||
switch ( gaugeKind ) {
|
||||
case 0: NetBuilder::load<NetBuilderM2>( this, net ); break;
|
||||
case 1: NetBuilder::load<NetBuilderHV>( this, net ); break;
|
||||
case 2: NetBuilder::load<NetBuilderVH>( this, net ); break;
|
||||
case 0: NetBuilder::load<NetBuilderHybridVH>( this, net ); break;
|
||||
case 1: NetBuilder::load<NetBuilderM2> ( this, net ); break;
|
||||
case 2: NetBuilder::load<NetBuilderVH> ( this, net ); break;
|
||||
case 3: NetBuilder::load<NetBuilderHV> ( this, net ); break;
|
||||
}
|
||||
|
||||
Session::revalidate();
|
||||
|
@ -1290,11 +1357,6 @@ namespace Anabatic {
|
|||
stopMeasures();
|
||||
|
||||
cmess2 << Dots::asSizet(" - Short nets",shortNets) << endl;
|
||||
|
||||
if (gaugeKind > 2) {
|
||||
throw Error( "AnabaticEngine::_loadGrByNet(): Unsupported kind of routing gauge \"%s\"."
|
||||
, getString(getConfiguration()->getRoutingGauge()->getName()).c_str() );
|
||||
}
|
||||
|
||||
printMeasures( "load" );
|
||||
|
||||
|
@ -1626,7 +1688,7 @@ namespace Anabatic {
|
|||
|
||||
EdgeCapacity* AnabaticEngine::_createCapacity ( Flags flags, Interval span )
|
||||
{
|
||||
size_t depth = getConfiguration()->getAllowedDepth();
|
||||
size_t depth = _configuration->getAllowedDepth();
|
||||
EdgeCapacity* edgeCapacity = NULL;
|
||||
|
||||
flags &= Flags::EdgeCapacityMask;
|
||||
|
@ -1668,7 +1730,7 @@ namespace Anabatic {
|
|||
UpdateSession::open();
|
||||
|
||||
for ( auto rp : rps ) {
|
||||
if (not getConfiguration()->selectRpComponent(rp))
|
||||
if (not _configuration->selectRpComponent(rp))
|
||||
cerr << Warning( "AnabaticEngine::computeEdgeCapacities(): %s has no components on grid.", getString(rp).c_str() ) << endl;
|
||||
|
||||
Point center = rp->getBoundingBox().getCenter();
|
||||
|
|
|
@ -406,8 +406,8 @@ namespace Anabatic {
|
|||
if (horizontals[1] != NULL) ++count;
|
||||
if (verticals [0] != NULL) ++count;
|
||||
if (verticals [1] != NULL) ++count;
|
||||
if (count > 1) {
|
||||
showTopologyError( "Terminal has more than one segment." );
|
||||
if (count != 1) {
|
||||
showTopologyError( "Terminal has not *exactly* one segment." );
|
||||
}
|
||||
if (horizontals[0] != NULL ) {
|
||||
_segment = Session::lookup( horizontals[0] );
|
||||
|
|
|
@ -1808,7 +1808,7 @@ namespace Anabatic {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (not Session::getAnabatic()->isChannelMode()
|
||||
if (not Session::getAnabatic()->isChannelStyle()
|
||||
and (getDepth() == 1) and isSpinBottom()) return false;
|
||||
if ((flags & Flags::WithPerpands) and _reduceds) return false;
|
||||
|
||||
|
@ -3284,7 +3284,7 @@ namespace Anabatic {
|
|||
Flags perpandFlags = (currentSegment->getAutoSource() == sourceContact)
|
||||
? Flags::Source : Flags::Target;
|
||||
perpandiculars.push_back( make_tuple( currentSegment, perpandFlags ));
|
||||
if (Session::getAnabatic()->isChannelMode()) {
|
||||
if (Session::getAnabatic()->isChannelStyle()) {
|
||||
if (currentSegment->isNonPref() and currentSegment->isFixed()) {
|
||||
if (perpandFlags & Flags::Source) isSourceBoundToChannel = true;
|
||||
else isTargetBoundToChannel = true;
|
||||
|
|
|
@ -36,9 +36,10 @@ endif ( CHECK_DETERMINISM )
|
|||
anabatic/NetBuilderM2.h
|
||||
anabatic/NetBuilderHV.h
|
||||
anabatic/NetBuilderVH.h
|
||||
anabatic/NetBuilderHybridVH.h
|
||||
anabatic/ChipTools.h
|
||||
)
|
||||
set( pyIncludes )
|
||||
set( pyIncludes anabatic/PyStyleFlags.h )
|
||||
set( cpps Constants.cpp
|
||||
Configuration.cpp
|
||||
Matrix.cpp
|
||||
|
@ -62,13 +63,15 @@ endif ( CHECK_DETERMINISM )
|
|||
NetBuilderM2.cpp
|
||||
NetBuilderHV.cpp
|
||||
NetBuilderVH.cpp
|
||||
NetBuilderHybridVH.cpp
|
||||
ChipTools.cpp
|
||||
LayerAssign.cpp
|
||||
AntennaProtect.cpp
|
||||
PreRouteds.cpp
|
||||
AnabaticEngine.cpp
|
||||
)
|
||||
set( pyCpps PyAnabatic.cpp
|
||||
set( pyCpps PyStyleFlags.cpp
|
||||
PyAnabatic.cpp
|
||||
)
|
||||
|
||||
set( depLibs ${ETESIAN_LIBRARIES}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// -*- mode: C++; explicit-buffer-name: "Configuration.cpp<anabatic>" -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2016-2018, All Rights Reserved
|
||||
// Copyright (c) Sorbonne Université 2016-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -78,6 +78,8 @@ namespace Anabatic {
|
|||
, _ddepthv (ndepth)
|
||||
, _ddepthh (ndepth)
|
||||
, _ddepthc (ndepth)
|
||||
, _netBuilderStyle (Cfg::getParamString("anabatic.netBuilderStyle","HV,3RL+")->asString() )
|
||||
, _routingStyle (Cfg::getParamInt ("anabatic.routingStyle" ,StyleFlags::NoStyle)->asInt() )
|
||||
, _cg (NULL)
|
||||
, _rg (NULL)
|
||||
, _extensionCaps ()
|
||||
|
@ -187,6 +189,8 @@ namespace Anabatic {
|
|||
, _ddepthv (other._ddepthv)
|
||||
, _ddepthh (other._ddepthh)
|
||||
, _ddepthc (other._ddepthc)
|
||||
, _netBuilderStyle (other._netBuilderStyle)
|
||||
, _routingStyle (other._routingStyle)
|
||||
, _cg (NULL)
|
||||
, _rg (NULL)
|
||||
, _extensionCaps (other._extensionCaps)
|
||||
|
@ -223,6 +227,10 @@ namespace Anabatic {
|
|||
|
||||
bool Configuration::isTwoMetals () const
|
||||
{ return _rg->isTwoMetals(); }
|
||||
|
||||
|
||||
bool Configuration::isHybrid () const
|
||||
{ return _routingStyle & StyleFlags::Hybrid; }
|
||||
|
||||
|
||||
bool Configuration::isHV () const
|
||||
|
|
|
@ -14,16 +14,22 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include "hurricane/Error.h"
|
||||
#include "anabatic/Constants.h"
|
||||
|
||||
|
||||
namespace Anabatic {
|
||||
|
||||
using std::hex;
|
||||
using std::string;
|
||||
using std::ostringstream;
|
||||
using Hurricane::BaseFlags;
|
||||
using Hurricane::Error;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::Flags".
|
||||
|
||||
const BaseFlags Flags::NoFlags = 0;
|
||||
// Flags used for both objects states & functions arguments.
|
||||
const BaseFlags Flags::Horizontal = (1L << 0);
|
||||
|
@ -211,4 +217,69 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::StyleFlags".
|
||||
|
||||
|
||||
const BaseFlags StyleFlags::NoStyle = 0;
|
||||
const BaseFlags StyleFlags::HV = (1L << 0);
|
||||
const BaseFlags StyleFlags::VH = (1L << 1);
|
||||
const BaseFlags StyleFlags::OTH = (1L << 2);
|
||||
const BaseFlags StyleFlags::Channel = (1L << 3);
|
||||
const BaseFlags StyleFlags::Hybrid = (1L << 4);
|
||||
|
||||
|
||||
StyleFlags::~StyleFlags ()
|
||||
{ }
|
||||
|
||||
|
||||
StyleFlags StyleFlags::toFlag ( std::string textFlag )
|
||||
{
|
||||
if (textFlag == "HV") return HV;
|
||||
if (textFlag == "VH") return VH;
|
||||
if (textFlag == "OTH") return OTH;
|
||||
if (textFlag == "Channel") return Channel;
|
||||
if (textFlag == "Hybrid") return Hybrid;
|
||||
if (textFlag == "NoStyle") return NoStyle;
|
||||
std::cerr << Error( "StyleFlags::toFlag(): Unknown flag value \"%s\"", textFlag.c_str() ) << std::endl;
|
||||
return NoStyle;
|
||||
}
|
||||
|
||||
|
||||
StyleFlags StyleFlags::from ( std::string textFlags )
|
||||
{
|
||||
size_t start = 0;
|
||||
size_t stop = textFlags.find( '|' );
|
||||
while ( stop != string::npos ) {
|
||||
*this |= toFlag( textFlags.substr( start, stop-start-1 ));
|
||||
start = stop + 1;
|
||||
stop = textFlags.find( '|', start );
|
||||
}
|
||||
*this |= toFlag( textFlags.substr( stop+1 ));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
string StyleFlags::asString () const
|
||||
{
|
||||
ostringstream s;
|
||||
|
||||
if (_flags & (uint64_t)HV) { s << (s.tellp() ? "|" : "") << "HV"; }
|
||||
if (_flags & (uint64_t)VH) { s << (s.tellp() ? "|" : "") << "VH"; }
|
||||
if (_flags & (uint64_t)OTH) { s << (s.tellp() ? "|" : "") << "OTH"; }
|
||||
if (_flags & (uint64_t)Channel) { s << (s.tellp() ? "|" : "") << "Channel"; }
|
||||
if (_flags & (uint64_t)Hybrid ) { s << (s.tellp() ? "|" : "") << "Hybrid"; }
|
||||
s << " (0x" << hex << _flags << ")";
|
||||
return s.str();
|
||||
}
|
||||
|
||||
|
||||
string StyleFlags::_getTypeName () const
|
||||
{ return "Anabatic::StyleFlags"; }
|
||||
|
||||
|
||||
string StyleFlags::_getString () const
|
||||
{ return asString(); }
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
|
|
@ -285,7 +285,7 @@ namespace Anabatic {
|
|||
: Super(anabatic->getCell())
|
||||
, _observable ()
|
||||
, _anabatic (anabatic)
|
||||
, _flags (Flags::HChannelGCell|Flags::Invalidated)
|
||||
, _flags (Flags::Invalidated)
|
||||
, _westEdges ()
|
||||
, _eastEdges ()
|
||||
, _southEdges ()
|
||||
|
@ -1557,7 +1557,8 @@ namespace Anabatic {
|
|||
int contiguousNonSaturated = 0;
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
uLengths2[i] += _blockages[i];
|
||||
if (not i) continue;
|
||||
if (Session::getLayerGauge(i)->getType() & Constant::PinOnly)
|
||||
continue;
|
||||
if (Session::getLayerGauge(i)->getType() & Constant::PowerSupply)
|
||||
continue;
|
||||
if ((float)(_blockages[i] * Session::getPitch(i)) > 0.60*(float)(width*height))
|
||||
|
|
|
@ -218,9 +218,10 @@ namespace {
|
|||
cdebug_log(149,0) << "Slacken from: " << rp << endl;
|
||||
|
||||
if (rp->getLayer()) {
|
||||
if (_anabatic->getConfiguration()->getLayerDepth(rp->getLayer()) == 1)
|
||||
if (_anabatic->getConfiguration()->getLayerDepth(rp->getLayer()) == 1) {
|
||||
cdebug_log(149,0) << "In METAL2, skiping" << endl;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for ( Component* component : rp->getSlaveComponents() ) {
|
||||
|
|
|
@ -227,7 +227,7 @@ namespace Anabatic {
|
|||
// -------------------------------------------------------------------
|
||||
// Class : "NetBuilder".
|
||||
|
||||
|
||||
|
||||
void NetBuilder::getPositions ( Component* anchor, Point& source, Point& target )
|
||||
{
|
||||
Segment* segment = dynamic_cast<Segment*>( anchor );
|
||||
|
@ -368,7 +368,7 @@ namespace Anabatic {
|
|||
, _routingPadAutoSegments()
|
||||
, _toFixSegments ()
|
||||
, _degree (0)
|
||||
, _isTwoMetals (false)
|
||||
, _isStrictChannel (false)
|
||||
, _sourceFlags (0)
|
||||
, _flags (0)
|
||||
{ }
|
||||
|
@ -396,8 +396,8 @@ namespace Anabatic {
|
|||
_norths .clear();
|
||||
_souths .clear();
|
||||
_routingPads .clear();
|
||||
_toFixSegments .clear();
|
||||
_routingPadAutoSegments.clear();
|
||||
_toFixSegments .clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -416,14 +416,15 @@ namespace Anabatic {
|
|||
{
|
||||
clear();
|
||||
|
||||
_isTwoMetals = anbt->getConfiguration()->isTwoMetals();
|
||||
_sourceFlags = sourceFlags;
|
||||
_sourceContact = sourceContact;
|
||||
_fromHook = fromHook;
|
||||
_isStrictChannel = anbt->isChannelStyle() and not anbt->isHybridStyle();
|
||||
_sourceFlags = sourceFlags;
|
||||
_sourceContact = sourceContact;
|
||||
_fromHook = fromHook;
|
||||
|
||||
cdebug_log(145,1) << "NetBuilder::setStartHook()" << endl;
|
||||
cdebug_log(145,0) << "* _fromHook: " << fromHook << endl;
|
||||
cdebug_log(145,0) << "* _sourceContact:" << sourceContact << endl;
|
||||
cdebug_log(145,0) << "_isStrictChannel:" << _isStrictChannel << endl;
|
||||
|
||||
if (not _fromHook) {
|
||||
cdebug_tabw(145,-1);
|
||||
|
@ -573,7 +574,6 @@ namespace Anabatic {
|
|||
<< "+" << (int)_connexity.fields.Pad
|
||||
<< "] " << _gcell
|
||||
<< endl;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -671,13 +671,16 @@ namespace Anabatic {
|
|||
cdebug_log(145,0) << "getSourceFlags():" << getSourceFlags()
|
||||
<< " getFlags():" << getFlags() << endl;
|
||||
|
||||
if (not isTwoMetals()) {
|
||||
if (not isStrictChannel()) {
|
||||
_southWestContact = NULL;
|
||||
_northEastContact = NULL;
|
||||
}
|
||||
|
||||
if (not _gcell->isAnalog()) {
|
||||
if (isTwoMetals() and not _sourceContact) _fromHook = NULL;
|
||||
if (isStrictChannel() and not _sourceContact) {
|
||||
cdebug_log(145,0) << "No _sourceContact, resetting _fromHook" << endl;
|
||||
_fromHook = NULL;
|
||||
}
|
||||
|
||||
switch ( _connexity.connexity ) {
|
||||
case Conn_1G_1Pad:
|
||||
|
@ -787,7 +790,7 @@ namespace Anabatic {
|
|||
case Conn_1G_1M1_1M3: _do_1G_xM1 (); break;
|
||||
case Conn_2G_1M1_1M2: _do_xG_1M1_1M2 (); break;
|
||||
default:
|
||||
if (not isTwoMetals())
|
||||
//if (not isStrictChannel())
|
||||
throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n"
|
||||
" The global routing seems to be defective."
|
||||
, _connexity.connexity
|
||||
|
@ -803,6 +806,9 @@ namespace Anabatic {
|
|||
_do_xG();
|
||||
}
|
||||
|
||||
cdebug_log(145,0) << "SouthWest: " << _southWestContact << endl;
|
||||
cdebug_log(145,0) << "NorthEast: " << _northEastContact << endl;
|
||||
|
||||
if (not _do_globalSegment()) {
|
||||
cdebug_log(145,0) << "No global generated, finish." << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
|
@ -1143,7 +1149,9 @@ namespace Anabatic {
|
|||
|
||||
bool NetBuilder::_do_xG_1PinM2 ()
|
||||
{
|
||||
throw Error ( "%s::_do_xG_1PinM2() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||
throw Error( "%s::_do_xG_1PinM2() method *not* reimplemented from base class.\n"
|
||||
" On %s"
|
||||
, getTypeName().c_str(), getString(getNet()).c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2008-2018, All Rights Reserved
|
||||
// Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -66,6 +66,10 @@ namespace Anabatic {
|
|||
|
||||
NetBuilderHV::~NetBuilderHV () { }
|
||||
|
||||
|
||||
string NetBuilderHV::getStyle ()
|
||||
{ return "HV,3RL+"; }
|
||||
|
||||
|
||||
void NetBuilderHV::doRp_AutoContacts ( GCell* gcell
|
||||
, Component* rp
|
||||
|
@ -348,9 +352,9 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
AutoContact* NetBuilderHV::doRp_AccessNorthPin ( GCell* gcell, RoutingPad* rp )
|
||||
AutoContact* NetBuilderHV::doRp_AccessNorthSouthPin ( GCell* gcell, RoutingPad* rp )
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_AccessNorthPin() " << rp << endl;
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_AccessNorthSouthPin() " << rp << endl;
|
||||
|
||||
AutoContact* rpSourceContact = NULL;
|
||||
AutoContact* rpContactTarget = NULL;
|
||||
|
@ -389,7 +393,7 @@ namespace Anabatic {
|
|||
|
||||
AutoContact* NetBuilderHV::doRp_AccessEastWestPin ( GCell* gcell, RoutingPad* rp )
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_AccessNorthPin() " << rp << endl;
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_AccessEastWestPin() " << rp << endl;
|
||||
|
||||
Net* net = rp->getNet();
|
||||
Pin* pin = dynamic_cast<Pin*>( rp->getOccurrence().getEntity() );
|
||||
|
@ -942,9 +946,9 @@ namespace Anabatic {
|
|||
|
||||
AutoContact* rpSourceContact = NULL;
|
||||
|
||||
rpSourceContact = doRp_AccessNorthPin( getGCell(), getRoutingPads()[0] );
|
||||
rpSourceContact = doRp_AccessNorthSouthPin( getGCell(), getRoutingPads()[0] );
|
||||
|
||||
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
AutoSegment::create( rpSourceContact, turn1, Flags::Vertical );
|
||||
|
||||
if (north() or south()) {
|
||||
|
@ -1182,12 +1186,6 @@ namespace Anabatic {
|
|||
|
||||
setBothCornerContacts( turn );
|
||||
}
|
||||
|
||||
for ( size_t i=1 ; i<rpsM1.size() ; ++i ) {
|
||||
AutoContact* leftContact = doRp_Access( getGCell(), getRoutingPads()[i-1], HAccess );
|
||||
AutoContact* rightContact = doRp_Access( getGCell(), getRoutingPads()[i ], HAccess );
|
||||
AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
|
@ -1271,7 +1269,7 @@ namespace Anabatic {
|
|||
AutoContact* htee = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( contact1, htee, Flags::Horizontal );
|
||||
|
||||
rpSourceContact = doRp_AccessNorthPin( getGCell(), pinM3 );
|
||||
rpSourceContact = doRp_AccessNorthSouthPin( getGCell(), pinM3 );
|
||||
|
||||
if (north() or south()) {
|
||||
AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(1) );
|
||||
|
@ -2061,7 +2059,7 @@ namespace Anabatic {
|
|||
if ( (pinDir == Pin::AccessDirection::NORTH)
|
||||
or (pinDir == Pin::AccessDirection::SOUTH) ) {
|
||||
doRp_AutoContacts( gcell1, rpM1s[0], source, turn1, DoSourceContact );
|
||||
target = doRp_AccessNorthPin( gcell1, rpPin );
|
||||
target = doRp_AccessNorthSouthPin( gcell1, rpPin );
|
||||
turn1 = AutoContactTurn::create( gcell1, rpPin->getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( source, turn1 , Flags::Horizontal );
|
||||
AutoSegment::create( turn1 , target, Flags::Vertical );
|
||||
|
|
|
@ -0,0 +1,604 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | A n a b a t i c - Routing Toolbox |
|
||||
// | |
|
||||
// | Author : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./NetBuilderHybridVH.cpp" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/Breakpoint.h"
|
||||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "hurricane/Layer.h"
|
||||
#include "hurricane/BasicLayer.h"
|
||||
#include "hurricane/RegularLayer.h"
|
||||
#include "hurricane/Technology.h"
|
||||
#include "hurricane/DataBase.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/NetExternalComponents.h"
|
||||
#include "hurricane/NetRoutingProperty.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "hurricane/RoutingPads.h"
|
||||
#include "hurricane/Pin.h"
|
||||
#include "hurricane/Pad.h"
|
||||
#include "hurricane/Plug.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "hurricane/Instance.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "crlcore/AllianceFramework.h"
|
||||
#include "crlcore/RoutingGauge.h"
|
||||
#include "crlcore/Measures.h"
|
||||
#include "anabatic/AutoContactTerminal.h"
|
||||
#include "anabatic/AutoContactTurn.h"
|
||||
#include "anabatic/AutoContactHTee.h"
|
||||
#include "anabatic/AutoContactVTee.h"
|
||||
#include "anabatic/AutoSegment.h"
|
||||
#include "anabatic/NetBuilderHybridVH.h"
|
||||
#include "anabatic/AnabaticEngine.h"
|
||||
|
||||
|
||||
namespace Anabatic {
|
||||
|
||||
using std::swap;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Pin;
|
||||
|
||||
|
||||
NetBuilderHybridVH::NetBuilderHybridVH ()
|
||||
: NetBuilder()
|
||||
{ }
|
||||
|
||||
|
||||
NetBuilderHybridVH::~NetBuilderHybridVH () { }
|
||||
|
||||
|
||||
string NetBuilderHybridVH::getStyle ()
|
||||
{ return "VH,2RL"; }
|
||||
|
||||
|
||||
void NetBuilderHybridVH::doRp_AutoContacts ( GCell* gcell
|
||||
, Component* rp
|
||||
, AutoContact*& source
|
||||
, AutoContact*& target
|
||||
, uint64_t flags
|
||||
)
|
||||
{
|
||||
throw Error ( "%s::dpRp_AutoContacts() method must never be called.", getTypeName().c_str() );
|
||||
}
|
||||
|
||||
|
||||
AutoContact* NetBuilderHybridVH::doRp_Access ( GCell* gcell, Component* rp, uint64_t flags )
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_Access()" << endl;
|
||||
cdebug_log(145,0) << rp << endl;
|
||||
|
||||
const Layer* rpLayer = rp->getLayer();
|
||||
const Layer* viaLayer = Session::getDContactLayer();
|
||||
DbU::Unit viaSide = Session::getDContactWidth();
|
||||
Point position = rp->getCenter();
|
||||
AutoContact* rpContact = AutoContactTerminal::create( gcell, rp, rpLayer, position, viaSide, viaSide );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return rpContact;
|
||||
}
|
||||
|
||||
|
||||
AutoContact* NetBuilderHybridVH::doRp_AccessNorthSouthPin ( GCell* gcell, RoutingPad* rp )
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_AccessNorthSouthPin() " << rp << endl;
|
||||
|
||||
AutoContact* rpContact = doRp_Access( gcell, rp, NoFlags );
|
||||
AutoContact* turn = NULL;
|
||||
|
||||
Net* net = rp->getNet();
|
||||
Pin* pin = dynamic_cast<Pin*>( rp->getOccurrence().getEntity() );
|
||||
Pin::AccessDirection pinDir = pin->getAccessDirection();
|
||||
if (pinDir == Pin::AccessDirection::NORTH) {
|
||||
turn = AutoContactTurn::create( gcell, net, Session::getRoutingLayer(0) );
|
||||
AutoSegment* segment = AutoSegment::create( rpContact, turn, Flags::Vertical );
|
||||
segment->setAxis( rp->getX(), Flags::Force );
|
||||
segment->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis );
|
||||
rpContact = turn;
|
||||
|
||||
turn = AutoContactTurn::create( gcell, net, Session::getContactLayer(0) );
|
||||
segment = AutoSegment::create( rpContact, turn, Flags::Horizontal );
|
||||
rpContact = turn;
|
||||
|
||||
DbU::Unit axis = gcell->getYMax() - Session::getDHorizontalPitch();
|
||||
cdebug_log(145,0) << "axis:" << DbU::getValueString(axis) << endl;
|
||||
|
||||
segment->setAxis( axis, Flags::Force );
|
||||
//segment->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis );
|
||||
cdebug_log(145,0) << segment << endl;
|
||||
} else {
|
||||
turn = rpContact;
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return turn;
|
||||
}
|
||||
|
||||
|
||||
AutoContact* NetBuilderHybridVH::doRp_AccessEastWestPin ( GCell* gcell, RoutingPad* rp )
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_AccessEastWestPin() " << rp << endl;
|
||||
|
||||
Net* net = rp->getNet();
|
||||
Pin* pin = dynamic_cast<Pin*>( rp->getOccurrence().getEntity() );
|
||||
Pin::AccessDirection pinDir = pin->getAccessDirection();
|
||||
AutoContact* rpContact = doRp_Access( gcell, rp, NoFlags );
|
||||
AutoContact* turn = NULL;
|
||||
AutoSegment* segment = NULL;
|
||||
|
||||
turn = AutoContactTurn::create( gcell, net, Session::getContactLayer(0) );
|
||||
segment = AutoSegment::create( rpContact, turn, Flags::Horizontal );
|
||||
segment->setAxis( pin->getCenter().getY(), Flags::Force );
|
||||
|
||||
rpContact = turn;
|
||||
turn = AutoContactTurn::create( gcell, net, Session::getContactLayer(0) );
|
||||
segment = AutoSegment::create( rpContact, turn, Flags::Vertical );
|
||||
|
||||
DbU::Unit axis = 0;
|
||||
if (pinDir == Pin::AccessDirection::EAST)
|
||||
axis = gcell->getXMax() - Session::getDVerticalPitch();
|
||||
else
|
||||
axis = gcell->getXMin() + Session::getDVerticalPitch();
|
||||
segment->setAxis( axis );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return turn;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHybridVH::doRp_xG_1M1 ( RoutingPad* rp )
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_xG_1M1()" << endl;
|
||||
|
||||
AutoContact* swContact = nullptr;
|
||||
if (west() or south()) {
|
||||
AutoContact* termContact = doRp_Access( getGCell(), rp, NoFlags );
|
||||
if (west() and south()) {
|
||||
swContact = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
AutoSegment::create( termContact, swContact, Flags::Vertical );
|
||||
} else {
|
||||
if (west()) {
|
||||
swContact = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
AutoSegment::create( termContact, swContact, Flags::Vertical );
|
||||
} else
|
||||
swContact = termContact;
|
||||
}
|
||||
setSouthWestContact( swContact );
|
||||
}
|
||||
|
||||
AutoContact* neContact = nullptr;
|
||||
if (east() or north()) {
|
||||
AutoContact* termContact = doRp_Access( getGCell(), rp, NoFlags );
|
||||
if (east() and north()) {
|
||||
neContact = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
AutoSegment::create( termContact, neContact, Flags::Vertical );
|
||||
} else {
|
||||
if (east()) {
|
||||
neContact = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
AutoSegment::create( termContact, neContact, Flags::Vertical );
|
||||
} else
|
||||
neContact = termContact;
|
||||
}
|
||||
setNorthEastContact( neContact );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHybridVH::_do_xG_1M1 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_xG_1M1()" << endl;
|
||||
|
||||
doRp_xG_1M1( getRoutingPads()[0] );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHybridVH::doRp_xG_xM1_xM3 ( const vector<RoutingPad*>& rps )
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_xG_xM1()" << endl;
|
||||
|
||||
AutoContact* prevContact = nullptr;
|
||||
AutoContact* currContact = nullptr;
|
||||
|
||||
for ( size_t i=0 ; i<rps.size() ; ++i ) {
|
||||
prevContact = currContact;
|
||||
AutoContact* currTerm = doRp_Access( getGCell(), rps[i], NoFlags );
|
||||
|
||||
if (i == 0) {
|
||||
if (west() or south()) {
|
||||
AutoContact* swContact = nullptr;
|
||||
currContact = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
if (west() and south()) {
|
||||
swContact = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
} else {
|
||||
if (west())
|
||||
swContact = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
else
|
||||
swContact = currContact;
|
||||
}
|
||||
if (swContact != currContact)
|
||||
AutoSegment::create( currContact, swContact, Flags::Vertical );
|
||||
setSouthWestContact( swContact );
|
||||
} else {
|
||||
currContact = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
}
|
||||
AutoSegment::create( currTerm, currContact, Flags::Vertical );
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i+1 == rps.size()) {
|
||||
if (east() or north()) {
|
||||
AutoContact* neContact = nullptr;
|
||||
currContact = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
if (east() and north()) {
|
||||
neContact = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
} else {
|
||||
if (east())
|
||||
neContact = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
else
|
||||
neContact = currContact;
|
||||
}
|
||||
if (neContact != currContact)
|
||||
AutoSegment::create( currContact, neContact, Flags::Vertical );
|
||||
setNorthEastContact( neContact );
|
||||
} else {
|
||||
currContact = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
}
|
||||
AutoSegment::create( currTerm, currContact, Flags::Vertical );
|
||||
} else {
|
||||
currContact = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
}
|
||||
|
||||
AutoSegment::create( prevContact, currContact, Flags::Horizontal );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHybridVH::_do_xG_xM1_xM3 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_xG_xM1()" << endl;
|
||||
|
||||
sortRpByX( getRoutingPads(), NoFlags ); // increasing X.
|
||||
doRp_xG_xM1_xM3( getRoutingPads() );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHybridVH::_do_1G_xM1 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_1G_xM1()" << endl;
|
||||
|
||||
if (getConnexity().fields.M1 == 1)
|
||||
_do_xG_1M1();
|
||||
else
|
||||
_do_xG_xM1_xM3();
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHybridVH::_do_xG ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_xG()" << endl;
|
||||
|
||||
const Layer* viaLayer = Session::getContactLayer( 0 );
|
||||
if (getConnexity().fields.globals == 2) {
|
||||
setBothCornerContacts( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
} else if (getConnexity().fields.globals == 3) {
|
||||
if (east() and west()) {
|
||||
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
|
||||
if (south()) swapCornerContacts();
|
||||
|
||||
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Vertical );
|
||||
} else {
|
||||
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
|
||||
setNorthEastContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer ) );
|
||||
if (west()) swapCornerContacts();
|
||||
|
||||
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Horizontal );
|
||||
}
|
||||
} else { // fields.globals == 4.
|
||||
AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
|
||||
setSouthWestContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer ) );
|
||||
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
|
||||
AutoSegment::create( getSouthWestContact(), turn, Flags::Horizontal );
|
||||
AutoSegment::create( turn, getNorthEastContact(), Flags::Vertical );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHybridVH::_do_1G_1PinM1 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_1G_1PinM1() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||
|
||||
AutoContact* rpContact = doRp_AccessNorthSouthPin( getGCell(), getRoutingPads()[0] );
|
||||
|
||||
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
AutoSegment::create( rpContact, turn1, Flags::Vertical );
|
||||
|
||||
if (north() or south()) {
|
||||
AutoContact* turn2 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
AutoSegment::create( turn1, turn2, Flags::Horizontal );
|
||||
turn1 = turn2;
|
||||
}
|
||||
setBothCornerContacts( turn1 );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHybridVH::_do_2G_1PinM1 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_2G_1PinM1() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||
|
||||
AutoContact* rpContact = doRp_AccessNorthSouthPin( getGCell(), getRoutingPads()[0] );
|
||||
AutoContact* tee = nullptr;
|
||||
|
||||
if (east() and west()) {
|
||||
tee = AutoContactHTee::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
} else {
|
||||
tee = AutoContactVTee::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
}
|
||||
AutoSegment::create( rpContact, tee, Flags::Vertical );
|
||||
setBothCornerContacts( tee );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHybridVH::doRp_1G_1PinM2 ( RoutingPad* rp )
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_1G_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||
|
||||
AutoContact* rpContact = doRp_AccessEastWestPin( getGCell(), rp );
|
||||
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
AutoSegment::create( rpContact, turn1, Flags::Horizontal );
|
||||
|
||||
if (east() or west()) {
|
||||
AutoContact* turn2 = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
AutoSegment::create( turn1, turn2, Flags::Vertical );
|
||||
turn1 = turn2;
|
||||
}
|
||||
setBothCornerContacts( turn1 );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHybridVH::_do_1G_1PinM2 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_1G_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||
|
||||
doRp_1G_1PinM2( getRoutingPads()[0] );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHybridVH::_do_xG_1PinM2 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_xG_1PinM2()" << endl;
|
||||
|
||||
AutoContact* rpContact = doRp_AccessEastWestPin( getGCell(), getRoutingPads()[0] );
|
||||
AutoContact* neContact = nullptr;
|
||||
AutoContact* swContact = nullptr;
|
||||
|
||||
const Layer* viaLayer = Session::getContactLayer( 0 );
|
||||
if (getConnexity().fields.globals == 2) {
|
||||
if (north() and south())
|
||||
neContact = AutoContactVTee::create( getGCell(), getNet(), viaLayer );
|
||||
else
|
||||
neContact = AutoContactHTee::create( getGCell(), getNet(), viaLayer );
|
||||
AutoSegment::create( rpContact, neContact, Flags::Horizontal );
|
||||
setBothCornerContacts( neContact );
|
||||
} else if (getConnexity().fields.globals == 3) {
|
||||
swContact = AutoContactVTee::create( getGCell(), getNet(), viaLayer );
|
||||
neContact = AutoContactVTee::create( getGCell(), getNet(), viaLayer );
|
||||
if (west())
|
||||
AutoSegment::create( rpContact, neContact, Flags::Horizontal );
|
||||
else
|
||||
AutoSegment::create( rpContact, swContact, Flags::Horizontal );
|
||||
AutoSegment::create( swContact, neContact, Flags::Vertical );
|
||||
setNorthEastContact( neContact );
|
||||
setSouthWestContact( swContact );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHybridVH::_do_1G_xM1_1PinM2 ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_1G_xM1_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl;
|
||||
|
||||
sortRpByX( getRoutingPads(), NoFlags ); // increasing X.
|
||||
|
||||
vector<RoutingPad*> rpsM1;
|
||||
RoutingPad* rpM2 = nullptr;
|
||||
for ( RoutingPad* rp : getRoutingPads() ) {
|
||||
if (dynamic_cast<Pin*>(rp->getOccurrence().getEntity())) rpM2 = rp;
|
||||
else rpsM1.push_back( rp );
|
||||
}
|
||||
if (rpsM1.size() > 1)
|
||||
doRp_xG_xM1_xM3( rpsM1 );
|
||||
else
|
||||
doRp_xG_1M1( rpsM1[0] );
|
||||
|
||||
|
||||
Pin* pin = dynamic_cast<Pin*>( rpM2->getOccurrence().getEntity() );
|
||||
Pin::AccessDirection pinDir = pin->getAccessDirection();
|
||||
AutoContact* rpContact = doRp_AccessEastWestPin( getGCell(), rpM2 );
|
||||
AutoContact* rpM1Contact = nullptr;
|
||||
if (pinDir == Pin::AccessDirection::EAST)
|
||||
rpM1Contact = doRp_Access( getGCell(), rpsM1.back(), NoFlags );
|
||||
else
|
||||
rpM1Contact = doRp_Access( getGCell(), rpsM1.front(), NoFlags );
|
||||
AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
AutoSegment::create( rpM1Contact, turn, Flags::Vertical );
|
||||
AutoSegment::create( rpContact , turn, Flags::Horizontal );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilderHybridVH::_do_1G_1M1 () { return false; }
|
||||
bool NetBuilderHybridVH::_do_2G_1M1 () { return false; }
|
||||
// bool NetBuilderHybridVH::_do_xG_1Pad () { return false; }
|
||||
// bool NetBuilderHybridVH::_do_xG_xM2 () { return false; }
|
||||
// bool NetBuilderHybridVH::_do_1G_1M3 () { return false; }
|
||||
// bool NetBuilderHybridVH::_do_xG_xM3 () { return false; }
|
||||
// bool NetBuilderHybridVH::_do_xG_1M1_1M2 () { return false; }
|
||||
// bool NetBuilderHybridVH::_do_4G_1M2 () { return false; }
|
||||
bool NetBuilderHybridVH::_do_2G () { return false; }
|
||||
|
||||
|
||||
bool NetBuilderHybridVH::_do_globalSegment ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_globalSegment()" << endl;
|
||||
cdebug_log(145,0) << "getSourceFlags():" << getSourceFlags()
|
||||
<< " getFlags():" << getFlags() << endl;
|
||||
|
||||
if (getSourceContact()) {
|
||||
uint64_t segmentBound = getSegmentHookType( getFromHook() );
|
||||
AutoContact* targetContact
|
||||
= (segmentBound & (NorthBound|EastBound)) ? getNorthEastContact() : getSouthWestContact() ;
|
||||
if (not getFromHook()) cerr << "getFromHook() is NULL !" << endl;
|
||||
|
||||
AutoContact* sourceContact = getSourceContact();
|
||||
if (segmentBound & (NorthBound|SouthBound)) {
|
||||
AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
AutoSegment::create( sourceContact, turn, Flags::Vertical );
|
||||
sourceContact = AutoContactTurn::create( getGCell(), getNet(), Session::getContactLayer(0) );
|
||||
AutoSegment::create( sourceContact, turn, Flags::Horizontal );
|
||||
}
|
||||
Segment* baseSegment = static_cast<Segment*>( getFromHook()->getComponent() );
|
||||
AutoSegment* globalSegment = AutoSegment::create( sourceContact
|
||||
, targetContact
|
||||
, baseSegment
|
||||
);
|
||||
globalSegment->setFlags( (getDegree() == 2) ? AutoSegment::SegBipoint : 0 );
|
||||
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
|
||||
|
||||
// HARDCODED VALUE.
|
||||
if ( (getTopology() & Global_Fixed) and (globalSegment->getAnchoredLength() < 2*Session::getSliceHeight()) )
|
||||
addToFixSegments( globalSegment );
|
||||
|
||||
if (getConnexity().fields.globals < 2) {
|
||||
cdebug_tabw(145,-1);
|
||||
return false;
|
||||
}
|
||||
} else
|
||||
setFromHook( NULL );
|
||||
|
||||
push( east (), getNorthEastContact() );
|
||||
push( west (), getSouthWestContact() );
|
||||
push( north(), getNorthEastContact() );
|
||||
push( south(), getSouthWestContact() );
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void NetBuilderHybridVH::singleGCell ( AnabaticEngine* anbt, Net* net )
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::singleGCell() " << net << endl;
|
||||
|
||||
vector<RoutingPad*> rps;
|
||||
for ( RoutingPad* irp : net->getRoutingPads() )
|
||||
rps.push_back( irp );
|
||||
|
||||
if (rps.size() < 2) {
|
||||
cerr << Error( "%s::singleGCell(): For %s, less than two Plugs/Pins (%d)."
|
||||
, getTypeName().c_str()
|
||||
, getString(net).c_str()
|
||||
, rps.size() ) << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
sortRpByX( rps, NetBuilder::NoFlags ); // increasing X.
|
||||
|
||||
GCell* gcell1 = anbt->getGCellUnder( rps.front()->getCenter() );
|
||||
GCell* gcell2 = anbt->getGCellUnder( rps.back ()->getCenter() );
|
||||
|
||||
if (not gcell1) {
|
||||
cerr << Error( "No GCell under %s.", getString(rps.front()).c_str() ) << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
if (gcell1 != gcell2) {
|
||||
cerr << Error( "Not under a single GCell %s.", getString(rps.back()).c_str() ) << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
AutoContact* prevContact = nullptr;
|
||||
AutoContact* currContact = nullptr;
|
||||
|
||||
for ( size_t i=0 ; i<rps.size() ; ++i ) {
|
||||
prevContact = currContact;
|
||||
AutoContact* currTerm = doRp_Access( gcell1, rps[i], NoFlags );
|
||||
|
||||
if (i == 0) {
|
||||
currContact = AutoContactTurn::create( gcell1, net, Session::getContactLayer(0) );
|
||||
AutoSegment::create( currTerm, currContact, Flags::Vertical );
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i+1 == rps.size()) {
|
||||
currContact = AutoContactTurn::create( gcell1, net, Session::getContactLayer(0) );
|
||||
} else {
|
||||
currContact = AutoContactHTee::create( gcell1, net, Session::getContactLayer(0) );
|
||||
}
|
||||
AutoSegment::create( currTerm , currContact, Flags::Vertical );
|
||||
AutoSegment::create( prevContact, currContact, Flags::Horizontal );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
}
|
||||
|
||||
|
||||
string NetBuilderHybridVH::getTypeName () const
|
||||
{ return "NetBuilderHybridVH"; }
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
|
@ -61,6 +61,10 @@ namespace Anabatic {
|
|||
|
||||
NetBuilderM2::~NetBuilderM2 () { }
|
||||
|
||||
|
||||
string NetBuilderM2::getStyle ()
|
||||
{ return "2RL-"; }
|
||||
|
||||
|
||||
void NetBuilderM2::doRp_AutoContacts ( GCell* gcell
|
||||
, Component* rp
|
||||
|
|
|
@ -66,6 +66,10 @@ namespace Anabatic {
|
|||
|
||||
NetBuilderVH::~NetBuilderVH () { }
|
||||
|
||||
|
||||
string NetBuilderVH::getStyle ()
|
||||
{ return "VH,3RL+"; }
|
||||
|
||||
|
||||
void NetBuilderVH::doRp_AutoContacts ( GCell* gcell
|
||||
, Component* rp
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "hurricane/isobar/PyHurricane.h"
|
||||
#include "hurricane/isobar/PyCell.h"
|
||||
#include "anabatic/Constants.h"
|
||||
#include "anabatic/PyStyleFlags.h"
|
||||
|
||||
|
||||
namespace Anabatic {
|
||||
|
@ -76,6 +76,10 @@ extern "C" {
|
|||
{
|
||||
cdebug_log(32,0) << "PyInit_Anabatic()" << endl;
|
||||
|
||||
PyStyleFlags_LinkPyType();
|
||||
|
||||
PYTYPE_READY( StyleFlags );
|
||||
|
||||
PyObject* module = PyModule_Create( &PyAnabatic_ModuleDef );
|
||||
if (module == NULL) {
|
||||
cerr << "[ERROR]\n"
|
||||
|
@ -83,6 +87,9 @@ extern "C" {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
Py_INCREF( &PyTypeStyleFlags );
|
||||
PyModule_AddObject( module, "StyleFlags", (PyObject*)&PyTypeStyleFlags );
|
||||
|
||||
PyObject* dictionnary = PyModule_GetDict(module);
|
||||
PyObject* constant;
|
||||
|
||||
|
@ -93,6 +100,7 @@ extern "C" {
|
|||
LoadObjectConstant( dictionnary,EngineLayerAssignNoGlobalM2V,"EngineLayerAssignNoGlobalM2V" );
|
||||
LoadObjectConstant( dictionnary,EngineNoNetLayerAssign ,"EngineNoNetLayerAssign" );
|
||||
|
||||
PyStyleFlags_postModuleInit();
|
||||
return module;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | A n a b a t i c - Global Routing Toolbox |
|
||||
// | |
|
||||
// | Author : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./PyStyleFlags.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include "anabatic/PyStyleFlags.h"
|
||||
|
||||
|
||||
namespace Anabatic {
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::hex;
|
||||
using std::ostringstream;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Isobar::ProxyProperty;
|
||||
using Isobar::ProxyError;
|
||||
using Isobar::ConstructorError;
|
||||
using Isobar::HurricaneError;
|
||||
using Isobar::HurricaneWarning;
|
||||
using Isobar::ParseOneArg;
|
||||
using Isobar::ParseTwoArg;
|
||||
using Isobar::getPyHash;
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
||||
|
||||
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(StyleFlags,status,function)
|
||||
|
||||
|
||||
// +=================================================================+
|
||||
// | "PyStyleFlags" Python Module Code Part |
|
||||
// +=================================================================+
|
||||
|
||||
#if defined(__PYTHON_MODULE__)
|
||||
|
||||
|
||||
PyMethodDef PyStyleFlags_Methods[] =
|
||||
{ {NULL, NULL, 0, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
||||
PythonOnlyDeleteMethod(StyleFlags)
|
||||
|
||||
DirectReprMethod (PyStyleFlags_Repr, PyStyleFlags, StyleFlags)
|
||||
DirectStrMethod (PyStyleFlags_Str, PyStyleFlags, StyleFlags)
|
||||
DirectCmpByValueMethod(PyStyleFlags_Cmp, IsPyStyleFlags, PyStyleFlags)
|
||||
DirectHashMethod (PyStyleFlags_Hash, StyleFlags)
|
||||
|
||||
extern void PyStyleFlags_LinkPyType() {
|
||||
cdebug_log(20,0) << "PyStyleFlags_LinkType()" << endl;
|
||||
PyTypeStyleFlags.tp_dealloc = (destructor) PyStyleFlags_DeAlloc;
|
||||
PyTypeStyleFlags.tp_richcompare = (richcmpfunc)PyStyleFlags_Cmp;
|
||||
PyTypeStyleFlags.tp_repr = (reprfunc) PyStyleFlags_Repr;
|
||||
PyTypeStyleFlags.tp_str = (reprfunc) PyStyleFlags_Str;
|
||||
PyTypeStyleFlags.tp_hash = (hashfunc) PyStyleFlags_Hash;
|
||||
PyTypeStyleFlags.tp_methods = PyStyleFlags_Methods;
|
||||
}
|
||||
|
||||
|
||||
#else // End of Python Module Code Part.
|
||||
|
||||
|
||||
// +=================================================================+
|
||||
// | "PyStyleFlags" Shared Library Code Part |
|
||||
// +=================================================================+
|
||||
|
||||
// Link/Creation Method.
|
||||
PyTypeObjectDefinitions(StyleFlags)
|
||||
|
||||
|
||||
extern void PyStyleFlags_postModuleInit ()
|
||||
{
|
||||
PyObject* constant = NULL;
|
||||
LoadObjectConstant( PyTypeStyleFlags.tp_dict, (uint64_t)StyleFlags::NoStyle, "NoStyle" );
|
||||
LoadObjectConstant( PyTypeStyleFlags.tp_dict, (uint64_t)StyleFlags::HV , "HV" );
|
||||
LoadObjectConstant( PyTypeStyleFlags.tp_dict, (uint64_t)StyleFlags::VH , "VH" );
|
||||
LoadObjectConstant( PyTypeStyleFlags.tp_dict, (uint64_t)StyleFlags::OTH , "OTH" );
|
||||
LoadObjectConstant( PyTypeStyleFlags.tp_dict, (uint64_t)StyleFlags::Channel, "Channel" );
|
||||
LoadObjectConstant( PyTypeStyleFlags.tp_dict, (uint64_t)StyleFlags::Hybrid , "Hybrid" );
|
||||
}
|
||||
|
||||
|
||||
#endif // Shared Library Code Part.
|
||||
|
||||
} // extern "C".
|
||||
|
||||
|
||||
#if !defined(__PYTHON_MODULE__)
|
||||
|
||||
|
||||
extern StyleFlags PyInt_AsStyleFlags ( PyObject* object )
|
||||
{
|
||||
uint64_t value = (uint64_t)Isobar::PyAny_AsLong( object );
|
||||
if ( (value == (uint64_t)StyleFlags::NoStyle)
|
||||
or (value == (uint64_t)StyleFlags::HV)
|
||||
or (value == (uint64_t)StyleFlags::VH)
|
||||
or (value == (uint64_t)StyleFlags::OTH)
|
||||
or (value == (uint64_t)StyleFlags::Channel)
|
||||
or (value == (uint64_t)StyleFlags::Hybrid))
|
||||
return value;
|
||||
return StyleFlags::NoStyle;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
} // Isobar namespace.
|
||||
|
|
@ -419,12 +419,16 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
StyleFlags Session::getRoutingStyle ()
|
||||
{ return get("getRoutingStyle()")->_anabatic->getRoutingStyle(); }
|
||||
|
||||
|
||||
bool Session::isInDemoMode ()
|
||||
{ return get("isInDemoMode()")->_anabatic->isInDemoMode(); }
|
||||
|
||||
|
||||
bool Session::isChannelMode ()
|
||||
{ return get("isChannelMode()")->_anabatic->isChannelMode(); }
|
||||
bool Session::isChannelStyle ()
|
||||
{ return get("isChannelStyle()")->_anabatic->isChannelStyle(); }
|
||||
|
||||
|
||||
float Session::getSaturateRatio ()
|
||||
|
|
|
@ -1,646 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2008-2018, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | A n a b a t i c - Routing Toolbox |
|
||||
// | |
|
||||
// | Author : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Header : "./anabatic/AutoSegment.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef ANABATIC_AUTOSEGMENT_H
|
||||
#define ANABATIC_AUTOSEGMENT_H
|
||||
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
#include "hurricane/Interval.h"
|
||||
#include "hurricane/Segment.h"
|
||||
#include "hurricane/Components.h"
|
||||
#include "hurricane/Contact.h"
|
||||
namespace Hurricane {
|
||||
class Layer;
|
||||
class Horizontal;
|
||||
class Vertical;
|
||||
class Cell;
|
||||
}
|
||||
#include "crlcore/RoutingGauge.h"
|
||||
#include "anabatic/Constants.h"
|
||||
#include "anabatic/GCell.h"
|
||||
#include "anabatic/AutoSegments.h"
|
||||
#include "anabatic/Session.h"
|
||||
|
||||
|
||||
namespace Anabatic {
|
||||
|
||||
using std::array;
|
||||
using std::set;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::binary_function;
|
||||
using Hurricane::StaticObservable;
|
||||
using Hurricane::BaseObserver;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::Interval;
|
||||
using Hurricane::Layer;
|
||||
using Hurricane::Components;
|
||||
using Hurricane::Horizontal;
|
||||
using Hurricane::Vertical;
|
||||
using Hurricane::Cell;
|
||||
using CRL::RoutingGauge;
|
||||
|
||||
class AutoHorizontal;
|
||||
class AutoVertical;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "AutoSegment".
|
||||
|
||||
|
||||
|
||||
class AutoSegment {
|
||||
friend class AutoHorizontal;
|
||||
friend class AutoVertical;
|
||||
|
||||
public:
|
||||
static const uint64_t SegNoFlags = 0L;
|
||||
static const uint64_t SegHorizontal = (1L<< 0);
|
||||
static const uint64_t SegFixed = (1L<< 1);
|
||||
static const uint64_t SegFixedAxis = (1L<< 2);
|
||||
static const uint64_t SegGlobal = (1L<< 3);
|
||||
static const uint64_t SegWeakGlobal = (1L<< 4);
|
||||
static const uint64_t SegLongLocal = (1L<< 5);
|
||||
static const uint64_t SegCanonical = (1L<< 6);
|
||||
static const uint64_t SegBipoint = (1L<< 7);
|
||||
static const uint64_t SegDogleg = (1L<< 8);
|
||||
static const uint64_t SegStrap = (1L<< 9);
|
||||
static const uint64_t SegSourceTop = (1L<<10);
|
||||
static const uint64_t SegSourceBottom = (1L<<11);
|
||||
static const uint64_t SegTargetTop = (1L<<12);
|
||||
static const uint64_t SegTargetBottom = (1L<<13);
|
||||
static const uint64_t SegIsReduced = (1L<<14);
|
||||
static const uint64_t SegDrag = (1L<<15);
|
||||
static const uint64_t SegLayerChange = (1L<<16);
|
||||
static const uint64_t SegSourceTerminal = (1L<<17); // Replace Terminal.
|
||||
static const uint64_t SegTargetTerminal = (1L<<18); // Replace Terminal.
|
||||
static const uint64_t SegStrongTerminal = SegSourceTerminal|SegTargetTerminal;
|
||||
static const uint64_t SegWeakTerminal1 = (1L<<19); // Replace TopologicalEnd.
|
||||
static const uint64_t SegWeakTerminal2 = (1L<<20); // Replace TopologicalEnd.
|
||||
static const uint64_t SegNotSourceAligned = (1L<<21);
|
||||
static const uint64_t SegNotTargetAligned = (1L<<22);
|
||||
static const uint64_t SegUnbound = (1L<<23);
|
||||
static const uint64_t SegHalfSlackened = (1L<<24);
|
||||
static const uint64_t SegSlackened = (1L<<25);
|
||||
static const uint64_t SegAxisSet = (1L<<26);
|
||||
static const uint64_t SegInvalidated = (1L<<27);
|
||||
static const uint64_t SegInvalidatedSource = (1L<<28);
|
||||
static const uint64_t SegInvalidatedTarget = (1L<<29);
|
||||
static const uint64_t SegInvalidatedLayer = (1L<<30);
|
||||
static const uint64_t SegCreated = (1L<<31);
|
||||
static const uint64_t SegUserDefined = (1L<<32);
|
||||
static const uint64_t SegAnalog = (1L<<33);
|
||||
static const uint64_t SegWide = (1L<<34);
|
||||
// Masks.
|
||||
static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2;
|
||||
static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned;
|
||||
static const uint64_t SegSpinTop = SegSourceTop |SegTargetTop;
|
||||
static const uint64_t SegSpinBottom = SegSourceBottom |SegTargetBottom;
|
||||
static const uint64_t SegDepthSpin = SegSpinTop |SegSpinBottom;
|
||||
|
||||
public:
|
||||
class Observable : public StaticObservable<1> {
|
||||
public:
|
||||
enum Indexes { TrackSegment = 0
|
||||
};
|
||||
public:
|
||||
inline Observable ();
|
||||
private:
|
||||
Observable ( const StaticObservable& );
|
||||
Observable& operator= ( const StaticObservable& );
|
||||
};
|
||||
public:
|
||||
enum ObserverFlag { Create = (1 << 0)
|
||||
, Destroy = (1 << 1)
|
||||
, Invalidate = (1 << 2)
|
||||
, Revalidate = (1 << 3)
|
||||
, RevalidatePPitch = (1 << 4)
|
||||
};
|
||||
public:
|
||||
typedef std::function< void(AutoSegment*) > RevalidateCb_t;
|
||||
public:
|
||||
static void setAnalogMode ( bool );
|
||||
static bool getAnalogMode ();
|
||||
inline static DbU::Unit getViaToTopCap ( size_t depth );
|
||||
inline static DbU::Unit getViaToBottomCap ( size_t depth );
|
||||
inline static DbU::Unit getViaToSameCap ( size_t depth );
|
||||
static AutoSegment* create ( AutoContact* source
|
||||
, AutoContact* target
|
||||
, Segment* hurricaneSegment
|
||||
);
|
||||
static AutoSegment* create ( AutoContact* source
|
||||
, AutoContact* target
|
||||
, Flags dir
|
||||
, size_t depth=RoutingGauge::nlayerdepth
|
||||
);
|
||||
void destroy ();
|
||||
// Wrapped Segment Functions.
|
||||
virtual Segment* base () const = 0;
|
||||
virtual Segment* base () = 0;
|
||||
virtual Horizontal* getHorizontal () { return NULL; };
|
||||
virtual Vertical* getVertical () { return NULL; };
|
||||
inline Cell* getCell () const;
|
||||
inline Net* getNet () const;
|
||||
inline const Layer* getLayer () const;
|
||||
inline Box getBoundingBox () const;
|
||||
inline Hook* getSourceHook ();
|
||||
inline Hook* getTargetHook ();
|
||||
inline Contact* getSource () const;
|
||||
inline Contact* getTarget () const;
|
||||
inline Component* getOppositeAnchor ( Component* ) const;
|
||||
inline Components getAnchors () const;
|
||||
virtual DbU::Unit getX () const;
|
||||
virtual DbU::Unit getY () const;
|
||||
inline DbU::Unit getWidth () const;
|
||||
inline DbU::Unit getContactWidth () const;
|
||||
inline DbU::Unit getLength () const;
|
||||
inline DbU::Unit getSourcePosition () const;
|
||||
inline DbU::Unit getTargetPosition () const;
|
||||
inline DbU::Unit getSourceX () const;
|
||||
inline DbU::Unit getSourceY () const;
|
||||
inline DbU::Unit getTargetX () const;
|
||||
inline DbU::Unit getTargetY () const;
|
||||
inline void invert ();
|
||||
inline void setLayer ( const Layer* );
|
||||
// Predicates.
|
||||
inline bool isHorizontal () const;
|
||||
inline bool isVertical () const;
|
||||
inline bool isGlobal () const;
|
||||
inline bool isWeakGlobal () const;
|
||||
inline bool isLongLocal () const;
|
||||
inline bool isLocal () const;
|
||||
inline bool isFixed () const;
|
||||
inline bool isFixedAxis () const;
|
||||
inline bool isBipoint () const;
|
||||
inline bool isWeakTerminal () const;
|
||||
inline bool isWeakTerminal1 () const;
|
||||
inline bool isWeakTerminal2 () const;
|
||||
inline bool isTerminal () const;
|
||||
inline bool isDrag () const;
|
||||
inline bool isNotSourceAligned () const;
|
||||
inline bool isNotTargetAligned () const;
|
||||
inline bool isNotAligned () const;
|
||||
bool isStrongTerminal ( Flags flags=Flags::NoFlags ) const;
|
||||
inline bool isSourceTerminal () const;
|
||||
inline bool isTargetTerminal () const;
|
||||
inline bool isLayerChange () const;
|
||||
inline bool isSpinTop () const;
|
||||
inline bool isSpinBottom () const;
|
||||
inline bool isSpinTopOrBottom () const;
|
||||
inline bool isReduced () const;
|
||||
inline bool isStrap () const;
|
||||
inline bool isDogleg () const;
|
||||
inline bool isUnbound () const;
|
||||
inline bool isInvalidated () const;
|
||||
inline bool isInvalidatedLayer () const;
|
||||
inline bool isCreated () const;
|
||||
inline bool isCanonical () const;
|
||||
inline bool isUnsetAxis () const;
|
||||
inline bool isSlackened () const;
|
||||
inline bool isUserDefined () const;
|
||||
bool isReduceCandidate () const;
|
||||
bool isUTurn () const;
|
||||
inline bool isAnalog () const;
|
||||
inline bool isWide () const;
|
||||
virtual bool _canSlacken () const = 0;
|
||||
bool canReduce () const;
|
||||
bool mustRaise () const;
|
||||
Flags canDogleg ( Interval );
|
||||
virtual bool canMoveULeft ( float reserve=0.0 ) const = 0;
|
||||
virtual bool canMoveURight ( float reserve=0.0 ) const = 0;
|
||||
bool canMoveUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
|
||||
bool canPivotUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
|
||||
bool canPivotDown ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
|
||||
bool canSlacken ( Flags flags=Flags::NoFlags ) const;
|
||||
virtual bool checkPositions () const = 0;
|
||||
virtual bool checkConstraints () const = 0;
|
||||
bool checkDepthSpin () const;
|
||||
// Accessors.
|
||||
inline unsigned long getId () const;
|
||||
inline uint64_t getFlags () const;
|
||||
virtual Flags getDirection () const = 0;
|
||||
inline GCell* getGCell () const;
|
||||
virtual bool getGCells ( vector<GCell*>& ) const = 0;
|
||||
inline AutoContact* getAutoSource () const;
|
||||
inline AutoContact* getAutoTarget () const;
|
||||
AutoContact* getOppositeAnchor ( AutoContact* ) const;
|
||||
size_t getPerpandicularsBound ( set<AutoSegment*>& );
|
||||
inline AutoSegment* getParent () const;
|
||||
inline unsigned int getDepth () const;
|
||||
inline DbU::Unit getPitch () const;
|
||||
DbU::Unit getPPitch () const;
|
||||
#if DISABLED
|
||||
DbU::Unit getExtensionCap () const;
|
||||
#endif
|
||||
DbU::Unit getExtensionCap ( Flags ) const;
|
||||
inline DbU::Unit getAxis () const;
|
||||
void getEndAxes ( DbU::Unit& sourceAxis, DbU::Unit& targetAxis ) const;
|
||||
virtual DbU::Unit getSourceU () const = 0;
|
||||
virtual DbU::Unit getTargetU () const = 0;
|
||||
virtual DbU::Unit getDuSource () const = 0;
|
||||
virtual DbU::Unit getDuTarget () const = 0;
|
||||
inline DbU::Unit getOrigin () const;
|
||||
inline DbU::Unit getExtremity () const;
|
||||
virtual Interval getSpanU () const = 0;
|
||||
Interval getMinSpanU () const;
|
||||
virtual Interval getSourceConstraints ( Flags flags=Flags::NoFlags ) const = 0;
|
||||
virtual Interval getTargetConstraints ( Flags flags=Flags::NoFlags ) const = 0;
|
||||
virtual bool getConstraints ( DbU::Unit& min, DbU::Unit& max ) const = 0;
|
||||
inline bool getConstraints ( Interval& i ) const;
|
||||
inline const Interval& getUserConstraints () const;
|
||||
inline const Interval& getNativeConstraints () const;
|
||||
virtual DbU::Unit getSlack () const;
|
||||
inline DbU::Unit getOptimalMin () const;
|
||||
inline DbU::Unit getOptimalMax () const;
|
||||
inline DbU::Unit getNativeMin () const;
|
||||
inline DbU::Unit getNativeMax () const;
|
||||
Interval& getOptimal ( Interval& i ) const;
|
||||
virtual DbU::Unit getCost ( DbU::Unit axis ) const;
|
||||
virtual AutoSegment* getCanonical ( DbU::Unit& min , DbU::Unit& max );
|
||||
inline AutoSegment* getCanonical ( Interval& i );
|
||||
float getMaxUnderDensity ( Flags flags );
|
||||
// Modifiers.
|
||||
inline void unsetFlags ( uint64_t );
|
||||
inline void setFlags ( uint64_t );
|
||||
void setFlagsOnAligneds ( uint64_t );
|
||||
inline void incReduceds ();
|
||||
inline void decReduceds ();
|
||||
virtual void setDuSource ( DbU::Unit du ) = 0;
|
||||
virtual void setDuTarget ( DbU::Unit du ) = 0;
|
||||
void computeTerminal ();
|
||||
virtual void updateOrient () = 0;
|
||||
virtual void updatePositions () = 0;
|
||||
virtual void updateNativeConstraints () = 0;
|
||||
void updateSourceSpin ();
|
||||
void updateTargetSpin ();
|
||||
void sourceDetach ();
|
||||
void targetDetach ();
|
||||
void sourceAttach ( AutoContact* );
|
||||
void targetAttach ( AutoContact* );
|
||||
//inline void mergeUserConstraints ( const Interval& );
|
||||
void mergeUserConstraints ( const Interval& );
|
||||
inline void resetUserConstraints ();
|
||||
inline void setOptimalMin ( DbU::Unit min );
|
||||
inline void setOptimalMax ( DbU::Unit max );
|
||||
inline void mergeNativeMin ( DbU::Unit min );
|
||||
inline void mergeNativeMax ( DbU::Unit max );
|
||||
inline void resetNativeConstraints ( DbU::Unit min, DbU::Unit max );
|
||||
bool checkNotInvalidated () const;
|
||||
inline void setParent ( AutoSegment* );
|
||||
void revalidate ();
|
||||
AutoSegment* makeDogleg ( AutoContact* );
|
||||
Flags makeDogleg ( Interval, Flags flags=Flags::NoFlags );
|
||||
Flags makeDogleg ( GCell* , Flags flags=Flags::NoFlags );
|
||||
virtual Flags _makeDogleg ( GCell* , Flags flags ) = 0;
|
||||
virtual bool moveULeft () = 0;
|
||||
virtual bool moveURight () = 0;
|
||||
bool slacken ( Flags flags );
|
||||
virtual bool _slacken ( Flags flags ) = 0;
|
||||
void _changeDepth ( unsigned int depth, Flags flags );
|
||||
void changeDepth ( unsigned int depth, Flags flags );
|
||||
bool moveUp ( Flags flags=Flags::NoFlags );
|
||||
bool moveDown ( Flags flags=Flags::NoFlags );
|
||||
bool reduceDoglegLayer ();
|
||||
bool reduce ();
|
||||
bool raise ();
|
||||
// Canonical Modifiers.
|
||||
AutoSegment* canonize ( Flags flags=Flags::NoFlags );
|
||||
virtual void invalidate ( Flags flags=Flags::Propagate );
|
||||
void invalidate ( AutoContact* );
|
||||
void computeOptimal ( set<AutoSegment*>& processeds );
|
||||
void setAxis ( DbU::Unit, Flags flags=Flags::NoFlags );
|
||||
bool toConstraintAxis ( Flags flags=Flags::Realignate );
|
||||
bool toOptimalAxis ( Flags flags=Flags::Realignate );
|
||||
// Collections & Filters.
|
||||
AutoSegments getOnSourceContact ( Flags direction );
|
||||
AutoSegments getOnTargetContact ( Flags direction );
|
||||
AutoSegments getCachedOnSourceContact ( Flags direction );
|
||||
AutoSegments getCachedOnTargetContact ( Flags direction );
|
||||
AutoSegments getAligneds ( Flags flags=Flags::NoFlags );
|
||||
AutoSegments getConnecteds ( Flags flags=Flags::NoFlags );
|
||||
AutoSegments getPerpandiculars ( Flags flags=Flags::NoFlags );
|
||||
size_t getAlignedContacts ( map<AutoContact*,int>& ) const ;
|
||||
// Observers.
|
||||
template< typename OwnerT >
|
||||
inline OwnerT* getObserver ( size_t slot );
|
||||
inline void setObserver ( size_t slot, BaseObserver* );
|
||||
inline void notify ( unsigned int flags );
|
||||
// Inspector Management.
|
||||
virtual Record* _getRecord () const = 0;
|
||||
virtual string _getString () const = 0;
|
||||
virtual string _getTypeName () const = 0;
|
||||
// Non-reviewed atomic modifiers.
|
||||
bool _check () const;
|
||||
#if THIS_IS_DISABLED
|
||||
virtual void desalignate ( AutoContact* ) = 0;
|
||||
bool shearUp ( GCell*
|
||||
, AutoSegment*& movedUp
|
||||
, float reserve
|
||||
, Flags flags );
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// Internal: Static Attributes.
|
||||
static size_t _allocateds;
|
||||
static size_t _globalsCount;
|
||||
static bool _analogMode;
|
||||
static bool _initialized;
|
||||
static vector< array<DbU::Unit*,3> > _extensionCaps;
|
||||
// Internal: Attributes.
|
||||
const unsigned long _id;
|
||||
GCell* _gcell;
|
||||
uint64_t _flags;
|
||||
unsigned int _depth : 8;
|
||||
unsigned int _optimalMin :16;
|
||||
unsigned int _optimalMax :16;
|
||||
unsigned int _reduceds : 2;
|
||||
DbU::Unit _sourcePosition;
|
||||
DbU::Unit _targetPosition;
|
||||
Interval _userConstraints;
|
||||
Interval _nativeConstraints;
|
||||
AutoSegment* _parent;
|
||||
Observable _observers;
|
||||
|
||||
// Internal: Constructors & Destructors.
|
||||
protected:
|
||||
AutoSegment ( Segment* segment );
|
||||
virtual ~AutoSegment ();
|
||||
static void _preCreate ( AutoContact* source, AutoContact* target );
|
||||
virtual void _postCreate ();
|
||||
virtual void _preDestroy ();
|
||||
static void _initialize ();
|
||||
private:
|
||||
AutoSegment ( const AutoSegment& );
|
||||
AutoSegment& operator= ( const AutoSegment& );
|
||||
protected:
|
||||
void _invalidate ();
|
||||
inline uint64_t _getFlags () const;
|
||||
std::string _getStringFlags () const;
|
||||
virtual void _setAxis ( DbU::Unit ) = 0;
|
||||
|
||||
public:
|
||||
struct CompareId : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||
inline bool operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const;
|
||||
};
|
||||
public:
|
||||
struct CompareByDepthLength : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
|
||||
};
|
||||
public:
|
||||
struct CompareByDepthAxis : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
|
||||
};
|
||||
public:
|
||||
typedef std::set<AutoSegment*,CompareByDepthLength> DepthLengthSet;
|
||||
typedef std::set<AutoSegment*,CompareId> IdSet;
|
||||
|
||||
// Static Utilities.
|
||||
public:
|
||||
static inline uint64_t swapSourceTargetFlags ( AutoSegment* );
|
||||
static inline bool areAlignedsAndDiffLayer ( AutoSegment*, AutoSegment* );
|
||||
static AutoSegment* getGlobalThroughDogleg ( AutoSegment* dogleg, AutoContact* from );
|
||||
static bool isTopologicalBound ( AutoSegment* seed, Flags flags );
|
||||
static inline bool arePerpandiculars ( AutoSegment* a, AutoSegment* b );
|
||||
static inline bool arePerpandiculars ( bool isHorizontalA, AutoSegment* b );
|
||||
static inline bool areAligneds ( AutoSegment* a, AutoSegment* b );
|
||||
static Flags getPerpandicularState ( AutoContact* contact
|
||||
, AutoSegment* source
|
||||
, AutoSegment* current
|
||||
, bool isHorizontalMaster
|
||||
, const Layer* masterLayer=NULL
|
||||
);
|
||||
static inline Flags getPerpandicularState ( AutoContact* contact
|
||||
, AutoSegment* source
|
||||
, AutoSegment* current
|
||||
, AutoSegment* master
|
||||
);
|
||||
static void getTopologicalInfos ( AutoSegment* seed
|
||||
, vector<AutoSegment*>& collapseds
|
||||
, vector<AutoSegment*>& perpandiculars
|
||||
, DbU::Unit& leftBound
|
||||
, DbU::Unit& rightBound
|
||||
);
|
||||
static int getTerminalCount ( AutoSegment* seed
|
||||
, vector<AutoSegment*>& collapseds
|
||||
);
|
||||
static inline int getTerminalCount ( AutoSegment* seed );
|
||||
static inline size_t getGlobalsCount ();
|
||||
static inline size_t getAllocateds ();
|
||||
static inline unsigned long getMaxId ();
|
||||
};
|
||||
|
||||
|
||||
// Inline Functions.
|
||||
inline DbU::Unit AutoSegment::getViaToTopCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][0]) : 0; }
|
||||
inline DbU::Unit AutoSegment::getViaToBottomCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][1]) : 0; }
|
||||
inline DbU::Unit AutoSegment::getViaToSameCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][2]) : 0; }
|
||||
inline unsigned long AutoSegment::getId () const { return _id; }
|
||||
inline Cell* AutoSegment::getCell () const { return base()->getCell(); }
|
||||
inline Net* AutoSegment::getNet () const { return base()->getNet(); }
|
||||
inline const Layer* AutoSegment::getLayer () const { return base()->getLayer(); }
|
||||
inline Box AutoSegment::getBoundingBox () const { return base()->getBoundingBox(); }
|
||||
inline Hook* AutoSegment::getSourceHook () { return base()->getSourceHook(); }
|
||||
inline Hook* AutoSegment::getTargetHook () { return base()->getTargetHook(); }
|
||||
inline Contact* AutoSegment::getSource () const { return static_cast<Contact*>(base()->getSource()); }
|
||||
inline Contact* AutoSegment::getTarget () const { return static_cast<Contact*>(base()->getTarget()); }
|
||||
inline Component* AutoSegment::getOppositeAnchor ( Component* anchor ) const { return base()->getOppositeAnchor(anchor); };
|
||||
inline AutoSegment* AutoSegment::getParent () const { return _parent; }
|
||||
inline DbU::Unit AutoSegment::getSourcePosition () const { return _sourcePosition; }
|
||||
inline DbU::Unit AutoSegment::getTargetPosition () const { return _targetPosition; }
|
||||
inline DbU::Unit AutoSegment::getSourceX () const { return base()->getSourceX(); }
|
||||
inline DbU::Unit AutoSegment::getSourceY () const { return base()->getSourceY(); }
|
||||
inline DbU::Unit AutoSegment::getTargetX () const { return base()->getTargetX(); }
|
||||
inline DbU::Unit AutoSegment::getTargetY () const { return base()->getTargetY(); }
|
||||
inline DbU::Unit AutoSegment::getWidth () const { return base()->getWidth(); }
|
||||
inline DbU::Unit AutoSegment::getLength () const { return base()->getLength(); }
|
||||
inline void AutoSegment::invert () { base()->invert(); }
|
||||
inline GCell* AutoSegment::getGCell () const { return _gcell; }
|
||||
inline AutoContact* AutoSegment::getAutoSource () const { return Session::lookup(getSource()); }
|
||||
inline AutoContact* AutoSegment::getAutoTarget () const { return Session::lookup(getTarget()); }
|
||||
inline bool AutoSegment::getConstraints ( Interval& i ) const { return getConstraints(i.getVMin(),i.getVMax()); }
|
||||
inline AutoSegment* AutoSegment::getCanonical ( Interval& i ) { return getCanonical(i.getVMin(),i.getVMax()); }
|
||||
inline unsigned int AutoSegment::getDepth () const { return _depth; }
|
||||
inline DbU::Unit AutoSegment::getPitch () const { return Session::getPitch(getDepth(),Flags::NoFlags); }
|
||||
inline DbU::Unit AutoSegment::getAxis () const { return isHorizontal()?base()->getY():base()->getX(); }
|
||||
inline DbU::Unit AutoSegment::getOrigin () const { return isHorizontal()?_gcell->getYMin():_gcell->getXMin(); }
|
||||
inline DbU::Unit AutoSegment::getExtremity () const { return isHorizontal()?_gcell->getYMax():_gcell->getXMax(); }
|
||||
inline DbU::Unit AutoSegment::getOptimalMin () const { return DbU::lambda(_optimalMin) + getOrigin(); }
|
||||
inline DbU::Unit AutoSegment::getOptimalMax () const { return DbU::lambda(_optimalMax) + getOrigin(); }
|
||||
inline DbU::Unit AutoSegment::getNativeMin () const { return _nativeConstraints.getVMin(); }
|
||||
inline DbU::Unit AutoSegment::getNativeMax () const { return _nativeConstraints.getVMax(); }
|
||||
inline const Interval& AutoSegment::getUserConstraints () const { return _userConstraints; }
|
||||
inline const Interval& AutoSegment::getNativeConstraints () const { return _nativeConstraints; }
|
||||
|
||||
inline bool AutoSegment::isHorizontal () const { return _flags & SegHorizontal; }
|
||||
inline bool AutoSegment::isVertical () const { return not (_flags & SegHorizontal); }
|
||||
inline bool AutoSegment::isFixed () const { return _flags & SegFixed; }
|
||||
inline bool AutoSegment::isFixedAxis () const { return _flags & SegFixedAxis; }
|
||||
inline bool AutoSegment::isGlobal () const { return _flags & SegGlobal; }
|
||||
inline bool AutoSegment::isWeakGlobal () const { return _flags & SegWeakGlobal; }
|
||||
inline bool AutoSegment::isLongLocal () const { return _flags & SegLongLocal; }
|
||||
inline bool AutoSegment::isLocal () const { return not (_flags & SegGlobal); }
|
||||
inline bool AutoSegment::isBipoint () const { return _flags & SegBipoint; }
|
||||
inline bool AutoSegment::isWeakTerminal () const { return _flags & SegWeakTerminal; }
|
||||
inline bool AutoSegment::isWeakTerminal1 () const { return _flags & SegWeakTerminal1; }
|
||||
inline bool AutoSegment::isWeakTerminal2 () const { return _flags & SegWeakTerminal2; }
|
||||
inline bool AutoSegment::isSourceTerminal () const { return _flags & SegSourceTerminal; }
|
||||
inline bool AutoSegment::isTargetTerminal () const { return _flags & SegTargetTerminal; }
|
||||
inline bool AutoSegment::isTerminal () const { return _flags & SegStrongTerminal; }
|
||||
inline bool AutoSegment::isDrag () const { return _flags & SegDrag; }
|
||||
inline bool AutoSegment::isNotSourceAligned () const { return _flags & SegNotSourceAligned; }
|
||||
inline bool AutoSegment::isNotTargetAligned () const { return _flags & SegNotTargetAligned; }
|
||||
inline bool AutoSegment::isNotAligned () const { return (_flags & SegNotAligned) == SegNotAligned; }
|
||||
inline bool AutoSegment::isDogleg () const { return _flags & SegDogleg ; }
|
||||
inline bool AutoSegment::isUnbound () const { return _flags & SegUnbound ; }
|
||||
inline bool AutoSegment::isStrap () const { return _flags & SegStrap; }
|
||||
inline bool AutoSegment::isLayerChange () const { return _flags & SegLayerChange; }
|
||||
inline bool AutoSegment::isSpinTop () const { return ((_flags & SegSpinTop ) == SegSpinTop); }
|
||||
inline bool AutoSegment::isSpinBottom () const { return ((_flags & SegSpinBottom) == SegSpinBottom); }
|
||||
inline bool AutoSegment::isSpinTopOrBottom () const { return isSpinTop() or isSpinBottom(); }
|
||||
inline bool AutoSegment::isReduced () const { return _flags & SegIsReduced; }
|
||||
inline bool AutoSegment::isSlackened () const { return _flags & SegSlackened; }
|
||||
inline bool AutoSegment::isCanonical () const { return _flags & SegCanonical; }
|
||||
inline bool AutoSegment::isUnsetAxis () const { return not (_flags & SegAxisSet); }
|
||||
inline bool AutoSegment::isInvalidated () const { return _flags & SegInvalidated; }
|
||||
inline bool AutoSegment::isInvalidatedLayer () const { return _flags & SegInvalidatedLayer; }
|
||||
inline bool AutoSegment::isCreated () const { return _flags & SegCreated; }
|
||||
inline bool AutoSegment::isUserDefined () const { return _flags & SegUserDefined; }
|
||||
inline bool AutoSegment::isAnalog () const { return _flags & SegAnalog; }
|
||||
inline bool AutoSegment::isWide () const { return _flags & SegWide; }
|
||||
inline void AutoSegment::setFlags ( uint64_t flags ) { _flags |= flags; }
|
||||
inline void AutoSegment::unsetFlags ( uint64_t flags ) { _flags &= ~flags; }
|
||||
|
||||
inline uint64_t AutoSegment::getFlags () const { return _flags; }
|
||||
inline uint64_t AutoSegment::_getFlags () const { return _flags; }
|
||||
inline void AutoSegment::incReduceds () { if (_reduceds<3) ++_reduceds; }
|
||||
inline void AutoSegment::decReduceds () { if (_reduceds>0) --_reduceds; }
|
||||
inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); _flags|=SegInvalidatedLayer; }
|
||||
inline void AutoSegment::setOptimalMin ( DbU::Unit min ) { _optimalMin = (unsigned int)DbU::getLambda(min-getOrigin()); }
|
||||
inline void AutoSegment::setOptimalMax ( DbU::Unit max ) { _optimalMax = (unsigned int)DbU::getLambda(max-getOrigin()); }
|
||||
inline void AutoSegment::mergeNativeMin ( DbU::Unit min ) { _nativeConstraints.getVMin() = std::max( min, _nativeConstraints.getVMin() ); }
|
||||
inline void AutoSegment::mergeNativeMax ( DbU::Unit max ) { _nativeConstraints.getVMax() = std::min( max, _nativeConstraints.getVMax() ); }
|
||||
inline void AutoSegment::resetNativeConstraints ( DbU::Unit min, DbU::Unit max ) { _nativeConstraints = Interval( min, max ); }
|
||||
//inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); }
|
||||
inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); }
|
||||
|
||||
|
||||
inline DbU::Unit AutoSegment::getContactWidth () const
|
||||
{ return getWidth() + Session::getViaWidth(getLayer()) - Session::getWireWidth(getLayer()); }
|
||||
|
||||
|
||||
inline void AutoSegment::setParent ( AutoSegment* parent )
|
||||
{
|
||||
if ( parent == this ) {
|
||||
cerr << "Parentage Looping: " << parent->_getString() << endl;
|
||||
}
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
inline bool AutoSegment::CompareId::operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const
|
||||
{ return lhs->getId() < rhs->getId(); }
|
||||
|
||||
inline uint64_t AutoSegment::swapSourceTargetFlags ( AutoSegment* segment )
|
||||
{
|
||||
uint64_t segFlags = segment->getFlags();
|
||||
uint64_t swapFlags = segment->getFlags() & ~(SegSourceTop |SegTargetTop
|
||||
|SegSourceBottom |SegTargetBottom
|
||||
|SegSourceTerminal |SegTargetTerminal
|
||||
|SegNotSourceAligned |SegNotTargetAligned
|
||||
|SegInvalidatedSource|SegInvalidatedTarget
|
||||
);
|
||||
|
||||
swapFlags |= (segFlags & SegSourceTop ) ? SegTargetTop : SegNoFlags;
|
||||
swapFlags |= (segFlags & SegSourceBottom ) ? SegTargetBottom : SegNoFlags;
|
||||
swapFlags |= (segFlags & SegSourceTerminal ) ? SegTargetTerminal : SegNoFlags;
|
||||
swapFlags |= (segFlags & SegNotSourceAligned ) ? SegNotTargetAligned : SegNoFlags;
|
||||
swapFlags |= (segFlags & SegInvalidatedSource) ? SegInvalidatedTarget : SegNoFlags;
|
||||
|
||||
swapFlags |= (segFlags & SegTargetTop ) ? SegSourceTop : SegNoFlags;
|
||||
swapFlags |= (segFlags & SegTargetBottom ) ? SegSourceBottom : SegNoFlags;
|
||||
swapFlags |= (segFlags & SegTargetTerminal ) ? SegSourceTerminal : SegNoFlags;
|
||||
swapFlags |= (segFlags & SegNotTargetAligned ) ? SegNotSourceAligned : SegNoFlags;
|
||||
swapFlags |= (segFlags & SegInvalidatedTarget) ? SegInvalidatedSource : SegNoFlags;
|
||||
return swapFlags;
|
||||
}
|
||||
|
||||
inline bool AutoSegment::areAlignedsAndDiffLayer ( AutoSegment* s1, AutoSegment* s2 )
|
||||
{ return s1 and s2
|
||||
and (s1->isHorizontal() == s2->isHorizontal())
|
||||
and (s1->getLayer() != s2->getLayer()); }
|
||||
|
||||
inline bool AutoSegment::arePerpandiculars ( AutoSegment* a, AutoSegment* b )
|
||||
{ return a and b and (a->isHorizontal() != b->isHorizontal()); }
|
||||
|
||||
inline bool AutoSegment::arePerpandiculars ( bool isHorizontalA, AutoSegment* b )
|
||||
{ return b and (isHorizontalA != b->isHorizontal()); }
|
||||
|
||||
inline bool AutoSegment::areAligneds ( AutoSegment* a, AutoSegment* b )
|
||||
{ return a and b and (a->isHorizontal() == b->isHorizontal()); }
|
||||
|
||||
inline Flags AutoSegment::getPerpandicularState ( AutoContact* contact
|
||||
, AutoSegment* source
|
||||
, AutoSegment* current
|
||||
, AutoSegment* master )
|
||||
{
|
||||
return getPerpandicularState ( contact, source, current, master->isHorizontal(), master->getLayer() );
|
||||
}
|
||||
|
||||
|
||||
inline int AutoSegment::getTerminalCount ( AutoSegment* seed )
|
||||
{
|
||||
cdebug_log(145,0) << "getTerminalCount() - " << seed << endl;
|
||||
|
||||
vector<AutoSegment*> collapseds;
|
||||
vector<AutoSegment*> perpandiculars;
|
||||
DbU::Unit leftBound;
|
||||
DbU::Unit rightBound;
|
||||
|
||||
getTopologicalInfos ( seed
|
||||
, collapseds
|
||||
, perpandiculars
|
||||
, leftBound
|
||||
, rightBound
|
||||
);
|
||||
|
||||
return getTerminalCount ( seed, collapseds );
|
||||
}
|
||||
|
||||
|
||||
inline size_t AutoSegment::getGlobalsCount () { return _globalsCount; }
|
||||
inline size_t AutoSegment::getAllocateds () { return _allocateds; }
|
||||
|
||||
|
||||
inline void AutoSegment::setObserver ( size_t slot, BaseObserver* observer )
|
||||
{ _observers.setObserver( slot, observer ); }
|
||||
|
||||
template<typename OwnerT>
|
||||
inline OwnerT* AutoSegment::getObserver ( size_t slot )
|
||||
{ return _observers.getObserver<OwnerT>(slot); }
|
||||
|
||||
inline void AutoSegment::notify ( unsigned int flags )
|
||||
{ _observers.notify( flags ); }
|
||||
|
||||
inline AutoSegment::Observable::Observable () : StaticObservable<1>() { }
|
||||
|
||||
|
||||
} // End of Anabatic namespace.
|
||||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::AutoSegment);
|
||||
|
||||
|
||||
# endif // ANABATIC_AUTOSEGMENT_H
|
|
@ -45,6 +45,7 @@ namespace Anabatic {
|
|||
using Hurricane::NetRoutingState;
|
||||
using CRL::ToolEngine;
|
||||
|
||||
class NetBuilder;
|
||||
class AnabaticEngine;
|
||||
|
||||
|
||||
|
@ -194,7 +195,6 @@ namespace Anabatic {
|
|||
static const uint32_t DigitalMode = (1 << 0);
|
||||
static const uint32_t AnalogMode = (1 << 1);
|
||||
static const uint32_t MixedMode = (1 << 2);
|
||||
static const uint32_t ChannelMode = (1 << 3);
|
||||
static const uint32_t AverageHVDensity = 1; // Average between all densities.
|
||||
static const uint32_t AverageHDensity = 2; // Average between all H densities.
|
||||
static const uint32_t AverageVDensity = 3; // Average between all V densities.
|
||||
|
@ -211,11 +211,14 @@ namespace Anabatic {
|
|||
inline bool isDigitalMode () const;
|
||||
inline bool isAnalogMode () const;
|
||||
inline bool isMixedMode () const;
|
||||
inline bool isChannelMode () const;
|
||||
inline bool isChannelStyle () const;
|
||||
inline bool isHybridStyle () const;
|
||||
static const Name& staticGetName ();
|
||||
virtual const Name& getName () const;
|
||||
virtual Configuration* getConfiguration ();
|
||||
virtual const Configuration* getConfiguration () const;
|
||||
inline std::string getNetBuilderStyle () const;
|
||||
inline StyleFlags getRoutingStyle () const;
|
||||
inline uint64_t getDensityMode () const;
|
||||
inline CellViewer* getViewer () const;
|
||||
inline void setViewer ( CellViewer* );
|
||||
|
@ -276,6 +279,7 @@ namespace Anabatic {
|
|||
void invalidateRoutingPads ();
|
||||
void updateDensity ();
|
||||
size_t checkGCellDensities ();
|
||||
void setupNetBuilder ();
|
||||
inline void setRoutingMode ( uint32_t );
|
||||
inline void resetRoutingMode ( uint32_t );
|
||||
inline void setGlobalThreshold ( DbU::Unit );
|
||||
|
@ -343,12 +347,15 @@ namespace Anabatic {
|
|||
virtual void _postCreate ();
|
||||
virtual void _preDestroy ();
|
||||
void _gutAnabatic ();
|
||||
virtual Configuration* _createConfiguration ();
|
||||
private:
|
||||
AnabaticEngine ( const AnabaticEngine& );
|
||||
AnabaticEngine& operator= ( const AnabaticEngine& );
|
||||
private:
|
||||
static Name _toolName;
|
||||
protected:
|
||||
Configuration* _configuration;
|
||||
private:
|
||||
ChipTools _chipTools;
|
||||
EngineState _state;
|
||||
Matrix _matrix;
|
||||
|
@ -369,58 +376,61 @@ namespace Anabatic {
|
|||
};
|
||||
|
||||
|
||||
inline bool AnabaticEngine::isDigitalMode () const { return (_routingMode & DigitalMode); };
|
||||
inline bool AnabaticEngine::isAnalogMode () const { return (_routingMode & AnalogMode); };
|
||||
inline bool AnabaticEngine::isMixedMode () const { return (_routingMode & MixedMode); };
|
||||
inline bool AnabaticEngine::isChannelMode () const { return (_routingMode & ChannelMode); };
|
||||
inline void AnabaticEngine::setRoutingMode ( uint32_t mode ) { _routingMode |= mode; };
|
||||
inline void AnabaticEngine::resetRoutingMode ( uint32_t mode ) { _routingMode &= ~mode; };
|
||||
inline EngineState AnabaticEngine::getState () const { return _state; }
|
||||
inline void AnabaticEngine::setState ( EngineState state ) { _state = state; }
|
||||
inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; }
|
||||
inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; }
|
||||
inline const Matrix* AnabaticEngine::getMatrix () const { return &_matrix; }
|
||||
inline const vector<GCell*>& AnabaticEngine::getGCells () const { return _gcells; }
|
||||
inline const vector<Edge*>& AnabaticEngine::getOvEdges () const { return _ovEdges; }
|
||||
inline GCell* AnabaticEngine::getSouthWestGCell () const { return _gcells[0]; }
|
||||
inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); }
|
||||
inline GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); }
|
||||
inline GCellsUnder AnabaticEngine::getGCellsUnder ( Segment* s ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,s) ); }
|
||||
inline GCellsUnder AnabaticEngine::getGCellsUnder ( Point source, Point target ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,source,target) ); }
|
||||
inline Edges AnabaticEngine::getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags ) const { return new Path_Edges(source,target,pathFlags); }
|
||||
inline uint64_t AnabaticEngine::getDensityMode () const { return _densityMode; }
|
||||
inline void AnabaticEngine::setDensityMode ( uint64_t mode ) { _densityMode=mode; }
|
||||
inline void AnabaticEngine::setBlockageNet ( Net* net ) { _blockageNet = net; }
|
||||
inline const AutoContactLut& AnabaticEngine::_getAutoContactLut () const { return _autoContactLut; }
|
||||
inline const AutoSegmentLut& AnabaticEngine::_getAutoSegmentLut () const { return _autoSegmentLut; }
|
||||
inline const Flags& AnabaticEngine::flags () const { return _flags; }
|
||||
inline Flags& AnabaticEngine::flags () { return _flags; }
|
||||
inline bool AnabaticEngine::doDestroyBaseContact () const { return _flags & Flags::DestroyBaseContact; }
|
||||
inline bool AnabaticEngine::doDestroyBaseSegment () const { return _flags & Flags::DestroyBaseSegment; }
|
||||
inline bool AnabaticEngine::doDestroyTool () const { return _state >= EngineGutted; }
|
||||
inline bool AnabaticEngine::doWarnOnGCellOverload () const { return _flags & Flags::WarnOnGCellOverload; }
|
||||
inline bool AnabaticEngine::isCanonizeDisabled () const { return _flags & Flags::DisableCanonize; }
|
||||
inline bool AnabaticEngine::isInDemoMode () const { return _flags & Flags::DemoMode; }
|
||||
inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); }
|
||||
inline DbU::Unit AnabaticEngine::getAntennaGateMaxWL () const { return getConfiguration()->getAntennaGateMaxWL(); }
|
||||
inline DbU::Unit AnabaticEngine::getAntennaDiodeMaxWL () const { return getConfiguration()->getAntennaDiodeMaxWL(); }
|
||||
inline DbU::Unit AnabaticEngine::getGlobalThreshold () const { return _configuration->getGlobalThreshold(); }
|
||||
inline float AnabaticEngine::getSaturateRatio () const { return _configuration->getSaturateRatio(); }
|
||||
inline size_t AnabaticEngine::getSaturateRp () const { return _configuration->getSaturateRp(); }
|
||||
inline void AnabaticEngine::setSaturateRatio ( float ratio ) { _configuration->setSaturateRatio(ratio); }
|
||||
inline void AnabaticEngine::setSaturateRp ( size_t threshold ) { _configuration->setSaturateRp(threshold); }
|
||||
inline Cell* AnabaticEngine::getDiodeCell () const { return _diodeCell; }
|
||||
inline Net* AnabaticEngine::getBlockageNet () const { return _blockageNet; }
|
||||
inline const ChipTools& AnabaticEngine::getChipTools () const { return _chipTools; }
|
||||
inline const vector<NetData*>& AnabaticEngine::getNetOrdering () const { return _netOrdering; }
|
||||
inline void AnabaticEngine::setGlobalThreshold ( DbU::Unit threshold ) { _configuration->setGlobalThreshold(threshold); }
|
||||
inline const NetDatas& AnabaticEngine::getNetDatas () const { return _netDatas; }
|
||||
inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); }
|
||||
inline void AnabaticEngine::_resizeMatrix () { _matrix.resize( getCell(), getGCells() ); }
|
||||
inline void AnabaticEngine::_updateGContacts ( Flags flags ) { for ( GCell* gcell : getGCells() ) gcell->updateGContacts(flags); }
|
||||
inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; }
|
||||
inline void AnabaticEngine::disableCanonize () { _flags |= Flags::DisableCanonize; }
|
||||
inline void AnabaticEngine::enableCanonize () { _flags.reset( Flags::DisableCanonize ); }
|
||||
inline bool AnabaticEngine::isDigitalMode () const { return (_routingMode & DigitalMode); };
|
||||
inline bool AnabaticEngine::isAnalogMode () const { return (_routingMode & AnalogMode); };
|
||||
inline bool AnabaticEngine::isMixedMode () const { return (_routingMode & MixedMode); };
|
||||
inline bool AnabaticEngine::isChannelStyle () const { return (_configuration->getRoutingStyle() & StyleFlags::Channel); };
|
||||
inline bool AnabaticEngine::isHybridStyle () const { return (_configuration->getRoutingStyle() & StyleFlags::Hybrid); };
|
||||
inline void AnabaticEngine::setRoutingMode ( uint32_t mode ) { _routingMode |= mode; };
|
||||
inline void AnabaticEngine::resetRoutingMode ( uint32_t mode ) { _routingMode &= ~mode; };
|
||||
inline EngineState AnabaticEngine::getState () const { return _state; }
|
||||
inline void AnabaticEngine::setState ( EngineState state ) { _state = state; }
|
||||
inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; }
|
||||
inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; }
|
||||
inline const Matrix* AnabaticEngine::getMatrix () const { return &_matrix; }
|
||||
inline const vector<GCell*>& AnabaticEngine::getGCells () const { return _gcells; }
|
||||
inline const vector<Edge*>& AnabaticEngine::getOvEdges () const { return _ovEdges; }
|
||||
inline GCell* AnabaticEngine::getSouthWestGCell () const { return _gcells[0]; }
|
||||
inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); }
|
||||
inline GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); }
|
||||
inline GCellsUnder AnabaticEngine::getGCellsUnder ( Segment* s ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,s) ); }
|
||||
inline GCellsUnder AnabaticEngine::getGCellsUnder ( Point source, Point target ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,source,target) ); }
|
||||
inline Edges AnabaticEngine::getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags ) const { return new Path_Edges(source,target,pathFlags); }
|
||||
inline uint64_t AnabaticEngine::getDensityMode () const { return _densityMode; }
|
||||
inline void AnabaticEngine::setDensityMode ( uint64_t mode ) { _densityMode=mode; }
|
||||
inline void AnabaticEngine::setBlockageNet ( Net* net ) { _blockageNet = net; }
|
||||
inline const AutoContactLut& AnabaticEngine::_getAutoContactLut () const { return _autoContactLut; }
|
||||
inline const AutoSegmentLut& AnabaticEngine::_getAutoSegmentLut () const { return _autoSegmentLut; }
|
||||
inline const Flags& AnabaticEngine::flags () const { return _flags; }
|
||||
inline Flags& AnabaticEngine::flags () { return _flags; }
|
||||
inline bool AnabaticEngine::doDestroyBaseContact () const { return _flags & Flags::DestroyBaseContact; }
|
||||
inline bool AnabaticEngine::doDestroyBaseSegment () const { return _flags & Flags::DestroyBaseSegment; }
|
||||
inline bool AnabaticEngine::doDestroyTool () const { return _state >= EngineGutted; }
|
||||
inline bool AnabaticEngine::doWarnOnGCellOverload () const { return _flags & Flags::WarnOnGCellOverload; }
|
||||
inline bool AnabaticEngine::isCanonizeDisabled () const { return _flags & Flags::DisableCanonize; }
|
||||
inline bool AnabaticEngine::isInDemoMode () const { return _flags & Flags::DemoMode; }
|
||||
inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); }
|
||||
inline std::string AnabaticEngine::getNetBuilderStyle () const { return _configuration->getNetBuilderStyle(); }
|
||||
inline StyleFlags AnabaticEngine::getRoutingStyle () const { return _configuration->getRoutingStyle(); }
|
||||
inline DbU::Unit AnabaticEngine::getAntennaGateMaxWL () const { return _configuration->getAntennaGateMaxWL(); }
|
||||
inline DbU::Unit AnabaticEngine::getAntennaDiodeMaxWL () const { return _configuration->getAntennaDiodeMaxWL(); }
|
||||
inline DbU::Unit AnabaticEngine::getGlobalThreshold () const { return _configuration->getGlobalThreshold(); }
|
||||
inline float AnabaticEngine::getSaturateRatio () const { return _configuration->getSaturateRatio(); }
|
||||
inline size_t AnabaticEngine::getSaturateRp () const { return _configuration->getSaturateRp(); }
|
||||
inline void AnabaticEngine::setSaturateRatio ( float ratio ) { _configuration->setSaturateRatio(ratio); }
|
||||
inline void AnabaticEngine::setSaturateRp ( size_t threshold ) { _configuration->setSaturateRp(threshold); }
|
||||
inline Cell* AnabaticEngine::getDiodeCell () const { return _diodeCell; }
|
||||
inline Net* AnabaticEngine::getBlockageNet () const { return _blockageNet; }
|
||||
inline const ChipTools& AnabaticEngine::getChipTools () const { return _chipTools; }
|
||||
inline const vector<NetData*>& AnabaticEngine::getNetOrdering () const { return _netOrdering; }
|
||||
inline void AnabaticEngine::setGlobalThreshold ( DbU::Unit threshold ) { _configuration->setGlobalThreshold(threshold); }
|
||||
inline const NetDatas& AnabaticEngine::getNetDatas () const { return _netDatas; }
|
||||
inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); }
|
||||
inline void AnabaticEngine::_resizeMatrix () { _matrix.resize( getCell(), getGCells() ); }
|
||||
inline void AnabaticEngine::_updateGContacts ( Flags flags ) { for ( GCell* gcell : getGCells() ) gcell->updateGContacts(flags); }
|
||||
inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; }
|
||||
inline void AnabaticEngine::disableCanonize () { _flags |= Flags::DisableCanonize; }
|
||||
inline void AnabaticEngine::enableCanonize () { _flags.reset( Flags::DisableCanonize ); }
|
||||
|
||||
inline void AnabaticEngine::_add ( GCell* gcell )
|
||||
{
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// -*- mode: C++; explicit-buffer-name: "Configuration.h<anabatic>" -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2016-2018, All Rights Reserved
|
||||
// Copyright (c) Sorbonne Université 2016-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -66,8 +66,11 @@ namespace Anabatic {
|
|||
bool isGMetal ( const Layer* ) const;
|
||||
bool isGContact ( const Layer* ) const;
|
||||
bool isTwoMetals () const;
|
||||
bool isHybrid () const;
|
||||
bool isHV () const;
|
||||
bool isVH () const;
|
||||
inline std::string getNetBuilderStyle () const;
|
||||
inline StyleFlags getRoutingStyle () const;
|
||||
const Layer* getGContactLayer () const;
|
||||
const Layer* getGHorizontalLayer () const;
|
||||
const Layer* getGVerticalLayer () const;
|
||||
|
@ -132,6 +135,8 @@ namespace Anabatic {
|
|||
int getGlobalIterations () const;
|
||||
DbU::Unit isOnRoutingGrid ( RoutingPad* ) const;
|
||||
bool selectRpComponent ( RoutingPad* ) const;
|
||||
inline void setRoutingStyle ( StyleFlags );
|
||||
inline void resetRoutingStyle ( StyleFlags );
|
||||
virtual void print ( Cell* ) const;
|
||||
virtual Record* _getRecord () const;
|
||||
virtual string _getString () const;
|
||||
|
@ -146,6 +151,8 @@ namespace Anabatic {
|
|||
size_t _ddepthv;
|
||||
size_t _ddepthh;
|
||||
size_t _ddepthc;
|
||||
std::string _netBuilderStyle;
|
||||
StyleFlags _routingStyle;
|
||||
CellGauge* _cg;
|
||||
RoutingGauge* _rg;
|
||||
std::vector<DbU::Unit> _extensionCaps;
|
||||
|
@ -169,6 +176,8 @@ namespace Anabatic {
|
|||
};
|
||||
|
||||
|
||||
inline std::string Configuration::getNetBuilderStyle () const { return _netBuilderStyle; }
|
||||
inline StyleFlags Configuration::getRoutingStyle () const { return _routingStyle; }
|
||||
inline bool Configuration::isGLayer ( const Layer* layer ) const { return isGMetal(layer) or isGContact(layer); }
|
||||
inline size_t Configuration::getGHorizontalDepth () const { return _gdepthh; }
|
||||
inline size_t Configuration::getGVerticalDepth () const { return _gdepthv; }
|
||||
|
@ -193,6 +202,8 @@ namespace Anabatic {
|
|||
inline std::string Configuration::getDiodeName () const { return _diodeName; }
|
||||
inline DbU::Unit Configuration::getAntennaGateMaxWL () const { return _antennaGateMaxWL; }
|
||||
inline DbU::Unit Configuration::getAntennaDiodeMaxWL () const { return _antennaDiodeMaxWL; }
|
||||
inline void Configuration::setRoutingStyle ( StyleFlags flags ) { _routingStyle = flags; }
|
||||
inline void Configuration::resetRoutingStyle ( StyleFlags flags ) { _routingStyle &= ~flags; }
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
namespace Anabatic {
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::Flags".
|
||||
|
||||
class Flags : public Hurricane::BaseFlags {
|
||||
public:
|
||||
static const BaseFlags NoFlags ; // = 0;
|
||||
|
@ -121,6 +124,39 @@ namespace Anabatic {
|
|||
Flags::Flags ( const Hurricane::BaseFlags& flags ) : BaseFlags(flags) { }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::StyleFlags".
|
||||
|
||||
class StyleFlags : public Hurricane::BaseFlags {
|
||||
public:
|
||||
static const BaseFlags NoStyle; // = 0;
|
||||
static const BaseFlags HV ; // = (1 << 0);
|
||||
static const BaseFlags VH ; // = (1 << 1);
|
||||
static const BaseFlags OTH ; // = (1 << 2);
|
||||
static const BaseFlags Channel; // = (1 << 3);
|
||||
static const BaseFlags Hybrid ; // = (1 << 4);
|
||||
public:
|
||||
inline StyleFlags ( std::string );
|
||||
inline StyleFlags ( uint64_t flags = NoStyle );
|
||||
inline StyleFlags ( const Hurricane::BaseFlags& );
|
||||
virtual ~StyleFlags ();
|
||||
static StyleFlags toFlag ( std::string );
|
||||
StyleFlags from ( std::string );
|
||||
virtual std::string asString () const;
|
||||
virtual std::string _getTypeName () const;
|
||||
virtual std::string _getString () const;
|
||||
};
|
||||
|
||||
|
||||
StyleFlags::StyleFlags ( std::string textFlags ) : BaseFlags(NoStyle) { from(textFlags); }
|
||||
StyleFlags::StyleFlags ( uint64_t flags ) : BaseFlags(flags) { }
|
||||
StyleFlags::StyleFlags ( const Hurricane::BaseFlags& flags ) : BaseFlags(flags) { }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Misc. enums.
|
||||
|
||||
|
||||
enum FlagsMode { FlagsFunction = 1
|
||||
};
|
||||
|
||||
|
|
|
@ -112,13 +112,13 @@ namespace Anabatic {
|
|||
, SouthWest = SouthBound|WestBound
|
||||
, NorthEast = NorthBound|EastBound
|
||||
};
|
||||
enum TopologyFlag { Global_Vertical_End = 0x00000001
|
||||
, Global_Horizontal_End = 0x00000002
|
||||
, Global_Horizontal = 0x00000004
|
||||
, Global_Vertical = 0x00000008
|
||||
, Global_Turn = 0x00000010
|
||||
, Global_Fork = 0x00000020
|
||||
, Global_Fixed = 0x00000040
|
||||
enum TopologyFlag { Global_Vertical_End = (1 << 0)
|
||||
, Global_Horizontal_End = (1 << 1)
|
||||
, Global_Horizontal = (1 << 2)
|
||||
, Global_Vertical = (1 << 3)
|
||||
, Global_Turn = (1 << 4)
|
||||
, Global_Fork = (1 << 5)
|
||||
, Global_Fixed = (1 << 6)
|
||||
, Global_End = Global_Vertical_End | Global_Horizontal_End
|
||||
, Global_Split = Global_Horizontal | Global_Vertical | Global_Fork
|
||||
};
|
||||
|
@ -157,7 +157,7 @@ namespace Anabatic {
|
|||
NetBuilder ();
|
||||
virtual ~NetBuilder ();
|
||||
void clear ();
|
||||
inline bool isTwoMetals () const;
|
||||
inline bool isStrictChannel () const;
|
||||
inline bool isUpperMetalRp () const;
|
||||
inline AnabaticEngine* getAnabatic () const;
|
||||
inline unsigned int getDegree () const;
|
||||
|
@ -386,13 +386,13 @@ namespace Anabatic {
|
|||
map<Component*,AutoSegment*> _routingPadAutoSegments;
|
||||
vector<AutoSegment*> _toFixSegments;
|
||||
unsigned int _degree;
|
||||
bool _isTwoMetals;
|
||||
bool _isStrictChannel;
|
||||
uint64_t _sourceFlags;
|
||||
uint64_t _flags;
|
||||
};
|
||||
|
||||
|
||||
inline bool NetBuilder::isTwoMetals () const { return _isTwoMetals; }
|
||||
inline bool NetBuilder::isStrictChannel () const { return _isStrictChannel; }
|
||||
inline AnabaticEngine* NetBuilder::getAnabatic () const { return _anabatic; }
|
||||
inline unsigned int NetBuilder::getDegree () const { return _degree; }
|
||||
inline NetBuilder::UConnexity NetBuilder::getConnexity () const { return _connexity; }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2008-2018, All Rights Reserved
|
||||
// Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -26,43 +26,44 @@ namespace Anabatic {
|
|||
|
||||
class NetBuilderHV : public NetBuilder {
|
||||
public:
|
||||
NetBuilderHV ();
|
||||
virtual ~NetBuilderHV ();
|
||||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
|
||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
|
||||
AutoContact* doRp_AccessNorthPin ( GCell*, RoutingPad* );
|
||||
AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* );
|
||||
NetBuilderHV ();
|
||||
virtual ~NetBuilderHV ();
|
||||
static std::string getStyle ();
|
||||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
|
||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
|
||||
AutoContact* doRp_AccessNorthSouthPin ( GCell*, RoutingPad* );
|
||||
AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* );
|
||||
private:
|
||||
virtual bool _do_1G_1M1 ();
|
||||
virtual bool _do_1G_xM1 ();
|
||||
virtual bool _do_xG ();
|
||||
virtual bool _do_2G ();
|
||||
virtual bool _do_2G_1M1 ();
|
||||
virtual bool _do_xG_1Pad ();
|
||||
virtual bool _do_1G_1PinM1 ();
|
||||
virtual bool _do_2G_1PinM1 ();
|
||||
virtual bool _do_1G_1PinM2 ();
|
||||
virtual bool _do_xG_1PinM2 ();
|
||||
virtual bool _do_1G_1PinM3 ();
|
||||
virtual bool _do_xG_1PinM3 ();
|
||||
virtual bool _do_xG_1M1 ();
|
||||
virtual bool _do_xG_1M1_1M2 ();
|
||||
virtual bool _do_xG_xM1_xM3 ();
|
||||
virtual bool _do_4G_1M2 ();
|
||||
virtual bool _do_xG_xM2 ();
|
||||
virtual bool _do_1G_1M3 ();
|
||||
virtual bool _do_xG_xM3 ();
|
||||
bool _do_xG_xM3_baseRouting ();
|
||||
bool _do_xG_xM3_upperRouting ();
|
||||
virtual bool _do_1G_xM1_1PinM2 ();
|
||||
virtual bool _do_2G_xM1_1PinM2 ();
|
||||
virtual bool _do_1G_1M1_1PinM3 ();
|
||||
virtual bool _do_2G_xM1_1PinM3 ();
|
||||
virtual bool _do_3G_xM1_1PinM3 ();
|
||||
virtual bool _do_globalSegment ();
|
||||
virtual void singleGCell ( AnabaticEngine*, Net* );
|
||||
public:
|
||||
virtual string getTypeName () const;
|
||||
virtual bool _do_1G_1M1 ();
|
||||
virtual bool _do_1G_xM1 ();
|
||||
virtual bool _do_xG ();
|
||||
virtual bool _do_2G ();
|
||||
virtual bool _do_2G_1M1 ();
|
||||
virtual bool _do_xG_1Pad ();
|
||||
virtual bool _do_1G_1PinM1 ();
|
||||
virtual bool _do_2G_1PinM1 ();
|
||||
virtual bool _do_1G_1PinM2 ();
|
||||
virtual bool _do_xG_1PinM2 ();
|
||||
virtual bool _do_1G_1PinM3 ();
|
||||
virtual bool _do_xG_1PinM3 ();
|
||||
virtual bool _do_xG_1M1 ();
|
||||
virtual bool _do_xG_1M1_1M2 ();
|
||||
virtual bool _do_xG_xM1_xM3 ();
|
||||
virtual bool _do_4G_1M2 ();
|
||||
virtual bool _do_xG_xM2 ();
|
||||
virtual bool _do_1G_1M3 ();
|
||||
virtual bool _do_xG_xM3 ();
|
||||
bool _do_xG_xM3_baseRouting ();
|
||||
bool _do_xG_xM3_upperRouting ();
|
||||
virtual bool _do_1G_xM1_1PinM2 ();
|
||||
virtual bool _do_2G_xM1_1PinM2 ();
|
||||
virtual bool _do_1G_1M1_1PinM3 ();
|
||||
virtual bool _do_2G_xM1_1PinM3 ();
|
||||
virtual bool _do_3G_xM1_1PinM3 ();
|
||||
virtual bool _do_globalSegment ();
|
||||
virtual void singleGCell ( AnabaticEngine*, Net* );
|
||||
public:
|
||||
virtual string getTypeName () const;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | A n a b a t i c - Routing Toolbox |
|
||||
// | |
|
||||
// | Author : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Header : "./anabatic/NetBuilderHybridVH.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
#pragma once
|
||||
#include "anabatic/NetBuilder.h"
|
||||
|
||||
|
||||
namespace Anabatic {
|
||||
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// Class : "NetBuilderHybridVH".
|
||||
|
||||
class NetBuilderHybridVH : public NetBuilder {
|
||||
public:
|
||||
NetBuilderHybridVH ();
|
||||
virtual ~NetBuilderHybridVH ();
|
||||
static std::string getStyle ();
|
||||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
|
||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
|
||||
AutoContact* doRp_AccessEastWestPin ( GCell* , RoutingPad* );
|
||||
AutoContact* doRp_AccessNorthSouthPin ( GCell* , RoutingPad* );
|
||||
private:
|
||||
bool doRp_xG_1M1 ( RoutingPad* );
|
||||
bool doRp_1G_1PinM2 ( RoutingPad* );
|
||||
bool doRp_xG_xM1_xM3 ( const std::vector<RoutingPad*>& );
|
||||
virtual bool _do_1G_1M1 ();
|
||||
virtual bool _do_2G_1M1 ();
|
||||
virtual bool _do_xG_1M1 ();
|
||||
virtual bool _do_xG ();
|
||||
bool _do_xG_xM1 ();
|
||||
virtual bool _do_globalSegment ();
|
||||
// Should never occur, so just return false.
|
||||
// virtual bool _do_xG_1Pad ();
|
||||
// virtual bool _do_1G_1PinM2 ();
|
||||
virtual bool _do_1G_xM1 ();
|
||||
// virtual bool _do_xG_xM2 ();
|
||||
// virtual bool _do_1G_1M3 ();
|
||||
// virtual bool _do_xG_xM3 ();
|
||||
// virtual bool _do_xG_1M1_1M2 ();
|
||||
virtual bool _do_xG_xM1_xM3 ();
|
||||
virtual bool _do_1G_xM1_1PinM2 ();
|
||||
// virtual bool _do_4G_1M2 ();
|
||||
virtual bool _do_2G ();
|
||||
virtual bool _do_2G_1PinM1 ();
|
||||
virtual bool _do_1G_1PinM1 ();
|
||||
virtual bool _do_1G_1PinM2 ();
|
||||
virtual bool _do_xG_1PinM2 ();
|
||||
virtual void singleGCell ( AnabaticEngine*, Net* );
|
||||
public:
|
||||
virtual string getTypeName () const;
|
||||
};
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
|
@ -1,7 +1,7 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2008-2018, All Rights Reserved
|
||||
// Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -13,9 +13,7 @@
|
|||
// | C++ Header : "./anabatic/NetBuilderM2.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
#ifndef ANABATIC_NET_BUILDER_M2_H
|
||||
#define ANABATIC_NET_BUILDER_M2_H
|
||||
|
||||
#pragma once
|
||||
#include "anabatic/NetBuilder.h"
|
||||
|
||||
|
||||
|
@ -29,6 +27,7 @@ namespace Anabatic {
|
|||
public:
|
||||
NetBuilderM2 ();
|
||||
virtual ~NetBuilderM2 ();
|
||||
static std::string getStyle ();
|
||||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
|
||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
|
||||
private:
|
||||
|
@ -53,5 +52,3 @@ namespace Anabatic {
|
|||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
||||
#endif // ANABATIC_NET_BUILDER_M2_H
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2017-2018, All Rights Reserved
|
||||
// Copyright (c) Sorbonne Université 2017-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -27,6 +27,7 @@ namespace Anabatic {
|
|||
public:
|
||||
NetBuilderVH ();
|
||||
virtual ~NetBuilderVH ();
|
||||
static std::string getStyle ();
|
||||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
|
||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
|
||||
private:
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | A n a b a t i c - Global Routing Toolbox |
|
||||
// | |
|
||||
// | Author : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Header : "./hurricane/isobar/PyStyleFlags.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#include "hurricane/isobar/PyHurricane.h"
|
||||
#include "anabatic/Constants.h"
|
||||
|
||||
|
||||
namespace Anabatic {
|
||||
|
||||
extern "C" {
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Python Object : "PyStyleFlags".
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
StyleFlags* _object;
|
||||
} PyStyleFlags;
|
||||
|
||||
|
||||
extern PyTypeObject PyTypeStyleFlags;
|
||||
extern PyMethodDef PyStyleFlags_Methods[];
|
||||
|
||||
extern PyObject* PyStyleFlags_Link ( StyleFlags* );
|
||||
extern void PyStyleFlags_LinkPyType ();
|
||||
extern void PyStyleFlags_postModuleInit ();
|
||||
|
||||
#define IsPyStyleFlags(v) ( (v)->ob_type == &PyTypeStyleFlags )
|
||||
#define PYSTYLEFLAGS(v) ( (PyStyleFlags*)(v) )
|
||||
#define PYSTYLEFLAGS_O(v) ( PYSTYLEFLAGS(v)->_object )
|
||||
|
||||
} // extern "C".
|
||||
|
||||
|
||||
extern Anabatic::StyleFlags PyInt_AsStyleFlags ( PyObject* );
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
|
@ -76,11 +76,12 @@ namespace Anabatic {
|
|||
static inline bool doDestroyBaseSegment ();
|
||||
static inline bool doDestroyTool ();
|
||||
static bool isInDemoMode ();
|
||||
static bool isChannelMode ();
|
||||
static bool isChannelStyle ();
|
||||
static bool doWarnGCellOverload ();
|
||||
static Session* get ( const char* message=NULL );
|
||||
static inline Technology* getTechnology ();
|
||||
static inline AnabaticEngine* getAnabatic ();
|
||||
static StyleFlags getRoutingStyle ();
|
||||
static inline const Configuration* getConfiguration ();
|
||||
static float getSaturateRatio ();
|
||||
static size_t getSaturateRp ();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2008-2018, All Rights Reserved
|
||||
// Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -143,6 +143,17 @@ namespace CRL {
|
|||
}
|
||||
|
||||
|
||||
RoutingLayerGauge* RoutingGauge::getFirstRoutingGauge () const
|
||||
{
|
||||
for ( RoutingLayerGauge* rlg : _layerGauges ) {
|
||||
if ( (rlg->getType() != Constant::LayerGaugeType::PinOnly)
|
||||
and (rlg->getType() != Constant::PowerSupply) )
|
||||
return rlg;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
RoutingLayerGauge* RoutingGauge::getHorizontalGauge () const
|
||||
{
|
||||
RoutingLayerGauge* pinOnly = NULL;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2008-2018, All Rights Reserved
|
||||
// Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -49,58 +49,59 @@ namespace CRL {
|
|||
// Constants.
|
||||
static const size_t nlayerdepth;
|
||||
// Constructors & Destructors.
|
||||
static RoutingGauge* create ( const char* name );
|
||||
virtual void destroy ();
|
||||
// Predicates.
|
||||
inline bool isSymbolic () const;
|
||||
inline bool isTwoMetals () const;
|
||||
inline bool isSuperPitched () const;
|
||||
inline bool isHV () const;
|
||||
inline bool isVH () const;
|
||||
inline bool hasPowerSupply () const;
|
||||
bool hasLayer ( const Layer* ) const;
|
||||
// Accessors.
|
||||
RoutingGauge* getClone () const;
|
||||
inline const Name getName () const;
|
||||
inline Technology* getTechnology () const;
|
||||
inline size_t getDepth () const;
|
||||
inline size_t getUsableLayers () const;
|
||||
inline DbU::Unit getHorizontalPitch () const;
|
||||
inline DbU::Unit getVerticalPitch () const;
|
||||
RoutingLayerGauge* getHorizontalGauge () const;
|
||||
RoutingLayerGauge* getVerticalGauge () const;
|
||||
RoutingLayerGauge* getPowerSupplyGauge () const;
|
||||
RoutingLayerGauge* getLayerGauge ( const Layer* ) const;
|
||||
size_t getViaDepth ( const Layer* ) const;
|
||||
size_t getLayerDepth ( const Layer* ) const;
|
||||
unsigned int getLayerType ( const Layer* ) const;
|
||||
unsigned int getLayerDirection ( const Layer* ) const;
|
||||
DbU::Unit getPitch ( const Layer* ) const;
|
||||
DbU::Unit getOffset ( const Layer* ) const;
|
||||
DbU::Unit getWireWidth ( const Layer* ) const;
|
||||
DbU::Unit getPWireWidth ( const Layer* ) const;
|
||||
DbU::Unit getViaWidth ( const Layer* ) const;
|
||||
RoutingLayerGauge* getLayerGauge ( size_t depth ) const;
|
||||
inline unsigned int getLayerDirection ( size_t depth ) const;
|
||||
inline unsigned int getLayerType ( size_t depth ) const;
|
||||
inline DbU::Unit getLayerPitch ( size_t depth ) const;
|
||||
inline DbU::Unit getLayerOffset ( size_t depth ) const;
|
||||
inline DbU::Unit getLayerWireWidth ( size_t depth ) const;
|
||||
inline DbU::Unit getLayerPWireWidth ( size_t depth ) const;
|
||||
inline DbU::Unit getViaWidth ( size_t depth ) const;
|
||||
const Layer* getRoutingLayer ( size_t depth ) const;
|
||||
Layer* getContactLayer ( size_t depth ) const;
|
||||
const vector<RoutingLayerGauge*>&
|
||||
getLayerGauges () const;
|
||||
// Methods.
|
||||
void addLayerGauge ( RoutingLayerGauge* layerGauge );
|
||||
void checkConnexity () const;
|
||||
inline void setSymbolic ( bool );
|
||||
// Hurricane Managment.
|
||||
void toJson ( JsonWriter* ) const;
|
||||
virtual Record* _getRecord ( Record* record=NULL ) const;
|
||||
virtual string _getString () const;
|
||||
virtual string _getTypeName () const;
|
||||
static RoutingGauge* create ( const char* name );
|
||||
virtual void destroy ();
|
||||
// Predicates.
|
||||
inline bool isSymbolic () const;
|
||||
inline bool isTwoMetals () const;
|
||||
inline bool isSuperPitched () const;
|
||||
inline bool isHV () const;
|
||||
inline bool isVH () const;
|
||||
inline bool hasPowerSupply () const;
|
||||
bool hasLayer ( const Layer* ) const;
|
||||
// Accessors.
|
||||
RoutingGauge* getClone () const;
|
||||
inline const Name getName () const;
|
||||
inline Technology* getTechnology () const;
|
||||
inline size_t getDepth () const;
|
||||
inline size_t getUsableLayers () const;
|
||||
inline DbU::Unit getHorizontalPitch () const;
|
||||
inline DbU::Unit getVerticalPitch () const;
|
||||
RoutingLayerGauge* getFirstRoutingGauge () const;
|
||||
RoutingLayerGauge* getHorizontalGauge () const;
|
||||
RoutingLayerGauge* getVerticalGauge () const;
|
||||
RoutingLayerGauge* getPowerSupplyGauge () const;
|
||||
RoutingLayerGauge* getLayerGauge ( const Layer* ) const;
|
||||
size_t getViaDepth ( const Layer* ) const;
|
||||
size_t getLayerDepth ( const Layer* ) const;
|
||||
unsigned int getLayerType ( const Layer* ) const;
|
||||
unsigned int getLayerDirection ( const Layer* ) const;
|
||||
DbU::Unit getPitch ( const Layer* ) const;
|
||||
DbU::Unit getOffset ( const Layer* ) const;
|
||||
DbU::Unit getWireWidth ( const Layer* ) const;
|
||||
DbU::Unit getPWireWidth ( const Layer* ) const;
|
||||
DbU::Unit getViaWidth ( const Layer* ) const;
|
||||
RoutingLayerGauge* getLayerGauge ( size_t depth ) const;
|
||||
inline unsigned int getLayerDirection ( size_t depth ) const;
|
||||
inline unsigned int getLayerType ( size_t depth ) const;
|
||||
inline DbU::Unit getLayerPitch ( size_t depth ) const;
|
||||
inline DbU::Unit getLayerOffset ( size_t depth ) const;
|
||||
inline DbU::Unit getLayerWireWidth ( size_t depth ) const;
|
||||
inline DbU::Unit getLayerPWireWidth ( size_t depth ) const;
|
||||
inline DbU::Unit getViaWidth ( size_t depth ) const;
|
||||
const Layer* getRoutingLayer ( size_t depth ) const;
|
||||
Layer* getContactLayer ( size_t depth ) const;
|
||||
const vector<RoutingLayerGauge*>&
|
||||
getLayerGauges () const;
|
||||
// Methods.
|
||||
void addLayerGauge ( RoutingLayerGauge* layerGauge );
|
||||
void checkConnexity () const;
|
||||
inline void setSymbolic ( bool );
|
||||
// Hurricane Managment.
|
||||
void toJson ( JsonWriter* ) const;
|
||||
virtual Record* _getRecord ( Record* record=NULL ) const;
|
||||
virtual string _getString () const;
|
||||
virtual string _getTypeName () const;
|
||||
|
||||
protected:
|
||||
// Internal - Attributes.
|
||||
|
@ -124,8 +125,8 @@ namespace CRL {
|
|||
inline bool RoutingGauge::isSymbolic () const { return _isSymbolic; }
|
||||
inline bool RoutingGauge::isSuperPitched () const { return _isSuperPitched; }
|
||||
inline bool RoutingGauge::isTwoMetals () const { return (_usableLayers < 3); }
|
||||
inline bool RoutingGauge::isHV () const { return not isTwoMetals() and (getLayerGauge(1)->isHorizontal()); }
|
||||
inline bool RoutingGauge::isVH () const { return not isTwoMetals() and (getLayerGauge(1)->isVertical()); }
|
||||
inline bool RoutingGauge::isHV () const { return getFirstRoutingGauge()->isHorizontal(); }
|
||||
inline bool RoutingGauge::isVH () const { return getFirstRoutingGauge()->isVertical(); }
|
||||
inline bool RoutingGauge::hasPowerSupply () const { return (getPowerSupplyGauge() != NULL); }
|
||||
inline const Name RoutingGauge::getName () const { return _name; }
|
||||
inline size_t RoutingGauge::getDepth () const { return _layerGauges.size(); }
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
|
||||
// Copyright (c) Sorbonne Université 2012-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | Alliance / Hurricane Interface |
|
||||
// | |
|
||||
// | Author : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Module : "./PyRoutingGauge.cpp" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
|
|
@ -768,7 +768,7 @@ class Block ( object ):
|
|||
self.katana.layerAssign ( Anabatic.EngineNoNetLayerAssign )
|
||||
self.katana.runNegociate ( Katana.Flags.NoFlags )
|
||||
success = self.katana.isDetailedRoutingSuccess()
|
||||
Breakpoint.stop( 100, 'Block.route() done, success:{}.'.format(success) )
|
||||
Breakpoint.stop( 99, 'Block.route() done, success:{}.'.format(success) )
|
||||
self.katana.finalizeLayout()
|
||||
if self.conf.cfg.katana.dumpMeasures is True:
|
||||
self.katana.dumpMeasures()
|
||||
|
|
|
@ -154,7 +154,7 @@ class GaugeConf ( object ):
|
|||
if not self.topLayerDepth:
|
||||
print( WarningMessage( 'Gauge top layer not defined, using top of gauge ({}).' \
|
||||
.format(self._routingGauge.getDepth()) ))
|
||||
self._topLayerDepth = self._routingGauge.getDepth() - 1
|
||||
self.topLayerDepth = self._routingGauge.getDepth() - 1
|
||||
|
||||
self.horizontalDepth = -1
|
||||
self.verticalDepth = -1
|
||||
|
|
|
@ -166,17 +166,19 @@ namespace Etesian {
|
|||
Box ab ( cell->getAbutmentBox() );
|
||||
DbU::Unit vpitch = etesian->getSliceStep();;
|
||||
int xsize = (ab.getWidth() + vpitch - 1) / vpitch;
|
||||
int extra = 0;
|
||||
float termRatio = (float)terminals / (float)(ab.getWidth() / vpitch);
|
||||
if (termRatio > 0.8) extra += 1;
|
||||
if (termRatio > 0.5) {
|
||||
return vpitch * (2*terminals + extra - xsize);
|
||||
}
|
||||
return 0;
|
||||
|
||||
// float termRatio = (float)terminals / (float)(ab.getWidth() / vpitch);
|
||||
// if (termRatio > 0.5) {
|
||||
// return vpitch*6;
|
||||
// }
|
||||
|
||||
// if (xsize < 4) return vpitch*4;
|
||||
// if (xsize < 6) return vpitch*2;
|
||||
// if (xsize < 8) return vpitch*1;
|
||||
|
||||
return vpitch*3;
|
||||
// if (xsize < 4) return vpitch*4;
|
||||
// if (xsize < 6) return vpitch*2;
|
||||
// if (xsize < 8) return vpitch*1;
|
||||
|
||||
// return vpitch*3;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// -*- mode: C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2017-2018, All Rights Reserved
|
||||
// Copyright (c) Sorbonne Université 2017-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -50,6 +50,16 @@ namespace Katana {
|
|||
// Class : "Katana::Row".
|
||||
|
||||
|
||||
Row::Row ( Block* block, DbU::Unit y )
|
||||
: _block (block)
|
||||
, _isHybrid (block->getKatana()->isHybridStyle())
|
||||
, _y (y)
|
||||
, _occurrences ()
|
||||
, _southWest (NULL)
|
||||
, _channelHeight(1)
|
||||
{ }
|
||||
|
||||
|
||||
void Row::add ( DbU::Unit x, Occurrence occurrence )
|
||||
{
|
||||
auto iocc = _occurrences.find( x );
|
||||
|
@ -137,17 +147,21 @@ namespace Katana {
|
|||
}
|
||||
}
|
||||
|
||||
southWest->setType( Anabatic::Flags::StdCellRow );
|
||||
if (channel) channel->setType( Anabatic::Flags::ChannelRow );
|
||||
if (not _isHybrid) {
|
||||
southWest->setType( Anabatic::Flags::StdCellRow );
|
||||
if (channel) channel->setType( Anabatic::Flags::ChannelRow );
|
||||
}
|
||||
|
||||
DbU::Unit xmax = getCell()->getAbutmentBox().getXMax() - sliceHeight;
|
||||
DbU::Unit xcut = _southWest->getXMin() + sliceHeight;
|
||||
for ( ; xcut < xmax ; xcut += sliceHeight ) {
|
||||
southWest = southWest->vcut( xcut );
|
||||
southWest->setType( Anabatic::Flags::StdCellRow );
|
||||
if (not _isHybrid)
|
||||
southWest->setType( Anabatic::Flags::StdCellRow );
|
||||
if (channel) {
|
||||
channel = channel->vcut( xcut );
|
||||
channel->setType( Anabatic::Flags::ChannelRow );
|
||||
if (not _isHybrid)
|
||||
channel->setType( Anabatic::Flags::ChannelRow );
|
||||
channel->getWestEdge()->setFlags( Flags::InfiniteCapacity );
|
||||
}
|
||||
}
|
||||
|
@ -196,17 +210,16 @@ namespace Katana {
|
|||
|
||||
uint32_t Row::computeChannelHeight ()
|
||||
{
|
||||
_channelHeight = 2;
|
||||
_channelHeight = 4;
|
||||
|
||||
GCell* gcell = getSouthWest()->getNorth();
|
||||
while ( gcell ) {
|
||||
_channelHeight = std::max( _channelHeight, (uint32_t)gcell->getNetCount() );
|
||||
// Edge* east = gcell->getEastEdge();
|
||||
// if (east)
|
||||
// _channelHeight = std::max( _channelHeight, east->getRealOccupancy() );
|
||||
//_channelHeight = std::max( _channelHeight, (uint32_t)gcell->getNetCount() );
|
||||
Edge* east = gcell->getEastEdge();
|
||||
if (east)
|
||||
_channelHeight = std::max( _channelHeight, east->getRealOccupancy() );
|
||||
gcell = gcell->getEast();
|
||||
}
|
||||
_channelHeight += 2;
|
||||
|
||||
return _channelHeight;
|
||||
}
|
||||
|
@ -233,7 +246,7 @@ namespace Katana {
|
|||
: _katana(katana)
|
||||
, _cell (cell)
|
||||
, _rows ()
|
||||
{
|
||||
{
|
||||
for ( Occurrence occurrence : _cell->getTerminalNetlistInstanceOccurrences() ) {
|
||||
add( occurrence );
|
||||
}
|
||||
|
@ -312,7 +325,8 @@ namespace Katana {
|
|||
Session::close();
|
||||
_katana->openSession();
|
||||
|
||||
for ( Row* row : _rows ) row->routingPadsSubBreak();
|
||||
if (not _katana->isHybridStyle())
|
||||
for ( Row* row : _rows ) row->routingPadsSubBreak();
|
||||
|
||||
if (not sessionReUse) Session::close();
|
||||
}
|
||||
|
@ -322,6 +336,8 @@ namespace Katana {
|
|||
{
|
||||
cmess1 << " o Sizing routing channels." << endl;
|
||||
|
||||
Breakpoint::stop( 1, "About to compute/resize channel heights." );
|
||||
|
||||
bool sessionReUse = Session::isOpen();
|
||||
if (not sessionReUse) _katana->openSession();
|
||||
|
||||
|
|
|
@ -180,6 +180,8 @@ namespace Katana {
|
|||
if (not cmess1.enabled()) return;
|
||||
|
||||
cout << " o Configuration of ToolEngine<Katana> for Cell <" << cell->getName() << ">" << endl;
|
||||
cout << Dots::asString(" - Net builder style" ,getNetBuilderStyle()) << endl;
|
||||
cout << Dots::asString(" - Routing style" ,getRoutingStyle().asString()) << endl;
|
||||
cout << Dots::asUInt (" - Dijkstra GR search halo" ,getSearchHalo()) << endl;
|
||||
cout << Dots::asBool (" - Use GR density estimate" ,useGlobalEstimate()) << endl;
|
||||
cout << Dots::asBool (" - Use static bloat profile" ,useStaticBloatProfile()) << endl;
|
||||
|
|
|
@ -126,7 +126,7 @@ namespace Katana {
|
|||
perpandicular = Session::lookup( basePerpand->getCanonical(interval)->base() );
|
||||
}
|
||||
if (not perpandicular) {
|
||||
if (not (Session::isChannelMode()
|
||||
if (not (Session::isChannelStyle()
|
||||
and (basePerpand->isReduced() or basePerpand->isNonPref())))
|
||||
cerr << Bug( "Not a TrackSegment: %s\n (perpandicular: %s)"
|
||||
//, getString((void*)basePerpand->getCanonical(interval)->base()).c_str()
|
||||
|
|
|
@ -389,7 +389,7 @@ namespace Katana {
|
|||
|
||||
startMeasures();
|
||||
|
||||
if (isChannelMode()) createChannels();
|
||||
if (isChannelStyle()) createChannels();
|
||||
|
||||
if (getGCells().size() == 1) {
|
||||
cmess1 << " o Building regular grid..." << endl;
|
||||
|
@ -518,7 +518,7 @@ namespace Katana {
|
|||
, getConfiguration()->getEdgeHScaling() ));
|
||||
const vector<Edge*>& ovEdges = getOvEdges();
|
||||
|
||||
if (isChannelMode())
|
||||
if (isChannelStyle())
|
||||
dijkstra->setSearchAreaHalo( Session::getSliceHeight()*10 );
|
||||
else
|
||||
dijkstra->setSearchAreaHalo( Session::getSliceHeight()*getSearchHalo() );
|
||||
|
@ -685,7 +685,7 @@ namespace Katana {
|
|||
addMeasure<uint32_t>( "H-ovE", hoverflow, 12 );
|
||||
addMeasure<uint32_t>( "V-ovE", voverflow, 12 );
|
||||
|
||||
if (not Session::isChannelMode())
|
||||
if (not Session::isChannelStyle())
|
||||
_buildBloatProfile();
|
||||
|
||||
if (flags & Flags::ShowFailedNets ) selectNets ( this, nets );
|
||||
|
@ -706,7 +706,7 @@ namespace Katana {
|
|||
delete dijkstra;
|
||||
|
||||
Session::close();
|
||||
if (isChannelMode()) {
|
||||
if (isChannelStyle()) {
|
||||
setupRoutingPlanes();
|
||||
setupPowerRails();
|
||||
protectRoutingPads();
|
||||
|
|
|
@ -188,7 +188,6 @@ namespace Katana {
|
|||
KatanaEngine::KatanaEngine ( Cell* cell )
|
||||
: Super (cell)
|
||||
, _viewer (NULL)
|
||||
, _configuration (new Configuration())
|
||||
, _blocks ()
|
||||
, _routingPlanes ()
|
||||
, _negociateWindow(NULL)
|
||||
|
@ -197,24 +196,29 @@ namespace Katana {
|
|||
, _symmetrics ()
|
||||
, _stage (StageNegociate)
|
||||
, _successState (0)
|
||||
{
|
||||
//Entity::setMemoryLimit( 1024 ); // 1Gb.
|
||||
addMeasure<size_t>( "Gates"
|
||||
, AllianceFramework::getInstancesCount(cell,AllianceFramework::IgnoreNonLogic
|
||||
|AllianceFramework::TerminalNetlist
|
||||
|AllianceFramework::Recursive) );
|
||||
}
|
||||
{ }
|
||||
|
||||
|
||||
void KatanaEngine::_postCreate ()
|
||||
{
|
||||
Super::_postCreate();
|
||||
|
||||
//Entity::setMemoryLimit( 1024 ); // 1Gb.
|
||||
addMeasure<size_t>( "Gates"
|
||||
, AllianceFramework::getInstancesCount(getCell()
|
||||
,AllianceFramework::IgnoreNonLogic
|
||||
|AllianceFramework::TerminalNetlist
|
||||
|AllianceFramework::Recursive) );
|
||||
|
||||
// Flute: load POWV9.dat & POST9.dat
|
||||
Flute::readLUT( System::getPath( "coriolis_top" ).toString() );
|
||||
}
|
||||
|
||||
|
||||
Configuration* KatanaEngine::_createConfiguration ()
|
||||
{ return new Configuration(); }
|
||||
|
||||
|
||||
void KatanaEngine::_runKatanaInit ()
|
||||
{
|
||||
Utilities::Path pythonSitePackages = System::getPath("pythonSitePackages");
|
||||
|
@ -246,7 +250,7 @@ namespace Katana {
|
|||
|
||||
setupChannelMode();
|
||||
setupGlobalGraph( 0 );
|
||||
if (not isChannelMode()) {
|
||||
if (not isChannelStyle()) {
|
||||
setupRoutingPlanes();
|
||||
}
|
||||
setupSpecialNets();
|
||||
|
@ -254,7 +258,7 @@ namespace Katana {
|
|||
setState( Anabatic::EngineDriving );
|
||||
throw Error( "KatanaEngine::digitalInit(): All nets are already routed, doing nothing." );
|
||||
} else {
|
||||
if (not isChannelMode()) {
|
||||
if (not isChannelStyle()) {
|
||||
setupPowerRails();
|
||||
protectRoutingPads();
|
||||
}
|
||||
|
@ -287,6 +291,7 @@ namespace Katana {
|
|||
|
||||
RoutingGauge* rg = getConfiguration()->getRoutingGauge();
|
||||
if (rg->isTwoMetals()) {
|
||||
cmess1 << " - Running in channel mode." << endl;
|
||||
setRoutingMode( ChannelMode );
|
||||
|
||||
size_t maxDepth = rg->getDepth();
|
||||
|
@ -361,7 +366,7 @@ namespace Katana {
|
|||
|
||||
|
||||
KatanaEngine::~KatanaEngine ()
|
||||
{ delete _configuration; }
|
||||
{ }
|
||||
|
||||
|
||||
const Name& KatanaEngine::getName () const
|
||||
|
@ -369,24 +374,28 @@ namespace Katana {
|
|||
|
||||
|
||||
Configuration* KatanaEngine::getConfiguration ()
|
||||
{ return _configuration; }
|
||||
{ return static_cast<Configuration*>( Super::getConfiguration() ); }
|
||||
|
||||
|
||||
const Configuration* KatanaEngine::getConfiguration () const
|
||||
{ return static_cast<const Configuration*>( Super::getConfiguration() ); }
|
||||
|
||||
|
||||
uint32_t KatanaEngine::getRipupLimit ( const TrackElement* segment ) const
|
||||
{
|
||||
if (segment->isBlockage()) return 0;
|
||||
|
||||
if (segment->isStrap ()) return _configuration->getRipupLimit( Configuration::StrapRipupLimit );
|
||||
if (segment->isUnbreakable()) return _configuration->getRipupLimit( Configuration::StrapRipupLimit );
|
||||
if (segment->isShortNet ()) return _configuration->getRipupLimit( Configuration::ShortNetRipupLimit );
|
||||
if (segment->isStrap ()) return getConfiguration()->getRipupLimit( Configuration::StrapRipupLimit );
|
||||
if (segment->isUnbreakable()) return getConfiguration()->getRipupLimit( Configuration::StrapRipupLimit );
|
||||
if (segment->isShortNet ()) return getConfiguration()->getRipupLimit( Configuration::ShortNetRipupLimit );
|
||||
if (segment->isGlobal ()) {
|
||||
vector<GCell*> gcells;
|
||||
segment->getGCells( gcells );
|
||||
if (gcells.size() > 2)
|
||||
return _configuration->getRipupLimit( Configuration::LongGlobalRipupLimit );
|
||||
return _configuration->getRipupLimit( Configuration::GlobalRipupLimit );
|
||||
return getConfiguration()->getRipupLimit( Configuration::LongGlobalRipupLimit );
|
||||
return getConfiguration()->getRipupLimit( Configuration::GlobalRipupLimit );
|
||||
}
|
||||
return _configuration->getRipupLimit( Configuration::LocalRipupLimit );
|
||||
return getConfiguration()->getRipupLimit( Configuration::LocalRipupLimit );
|
||||
}
|
||||
|
||||
|
||||
|
@ -553,7 +562,7 @@ namespace Katana {
|
|||
}
|
||||
}
|
||||
|
||||
if (Session::isChannelMode()) {
|
||||
if (Session::isChannelStyle()) {
|
||||
for ( GCell* gcell : getGCells() ) {
|
||||
if (not gcell->isStdCellRow()) continue;
|
||||
|
||||
|
@ -852,7 +861,7 @@ namespace Katana {
|
|||
|
||||
TrackElement* trackSegment = Session::lookup( segment );
|
||||
if (not trackSegment) {
|
||||
if ( isChannelMode()
|
||||
if ( isChannelStyle()
|
||||
and autoSegment->isFixed()
|
||||
and autoSegment->isHorizontal()
|
||||
and autoSegment->isNonPref())
|
||||
|
@ -998,7 +1007,6 @@ namespace Katana {
|
|||
Record* record = Super::_getRecord ();
|
||||
|
||||
if (record) {
|
||||
record->add( getSlot( "_configuration", _configuration ) );
|
||||
record->add( getSlot( "_blocks" , &_blocks ) );
|
||||
record->add( getSlot( "_routingPlanes", &_routingPlanes ) );
|
||||
record->add( getSlot( "_symmetrics" , &_symmetrics ) );
|
||||
|
|
|
@ -343,7 +343,7 @@ namespace Katana {
|
|||
// Look for closest enclosing min & max GCells indexes.
|
||||
for ( igcell=0 ; igcell<gcells.size() ; igcell++ ) {
|
||||
uside = gcells[igcell]->getSide(_segment->getDirection());
|
||||
cdebug_log(159,0) << "| " << setw(3) << igcell << " " << gcells[igcell] << " uside: " << uside << endl;
|
||||
cdebug_log(159,0) << "| " << igcell << " " << gcells[igcell] << " uside: " << uside << endl;
|
||||
|
||||
if (uside.contains(interval.getVMin())) {
|
||||
iminconflict = igcell;
|
||||
|
@ -437,6 +437,8 @@ namespace Katana {
|
|||
} else if (iminconflict == gcells.size()-1) {
|
||||
dogLegCount--;
|
||||
firstDoglegIsMin = true;
|
||||
} else {
|
||||
dogLegCount--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -724,7 +726,7 @@ namespace Katana {
|
|||
}
|
||||
if ( segment2->isBlockage()
|
||||
or (segment2->isFixed()
|
||||
and not (segment2->isVertical() and Session::getKatanaEngine()->isChannelMode()))) {
|
||||
and not (segment2->isVertical() and Session::getKatanaEngine()->isChannelStyle()))) {
|
||||
cdebug_log(159,0) << "Overlap is blockage or fixed." << endl;
|
||||
success = false;
|
||||
continue;
|
||||
|
|
|
@ -62,7 +62,7 @@ namespace {
|
|||
|
||||
if ( segment->isBlockage()
|
||||
or (segment->isFixed()
|
||||
and not (segment->isVertical() and Session::getKatanaEngine()->isChannelMode()))) {
|
||||
and not (segment->isVertical() and Session::getKatanaEngine()->isChannelStyle()))) {
|
||||
cdebug_log(159,0) << "Infinite cost from: " << segment << endl;
|
||||
cost.setInfinite ();
|
||||
cost.setOverlap ();
|
||||
|
@ -292,7 +292,7 @@ namespace Katana {
|
|||
{
|
||||
_gcells = gcells;
|
||||
|
||||
if (not Session::getKatanaEngine()->isChannelMode()) loadRoutingPads( this );
|
||||
if (not Session::getKatanaEngine()->isChannelStyle()) loadRoutingPads( this );
|
||||
Session::revalidate();
|
||||
|
||||
for ( auto element : Session::getKatanaEngine()->_getAutoSegmentLut() ) {
|
||||
|
@ -331,7 +331,7 @@ namespace Katana {
|
|||
// Special case: fixed AutoSegments must not interfere with blockages.
|
||||
// Ugly: uses of getExtensionCap().
|
||||
if (autoSegment->isFixed()) {
|
||||
if (Session::isChannelMode() and autoSegment->isReduced()) {
|
||||
if (Session::isChannelStyle() and autoSegment->isReduced()) {
|
||||
cdebug_log(159,0) << "* Fixed segment is reduced, ignore " << autoSegment << endl;
|
||||
cdebug_tabw(159,-1);
|
||||
return NULL;
|
||||
|
@ -342,7 +342,7 @@ namespace Katana {
|
|||
Interval fixedSpan;
|
||||
Interval blockageSpan;
|
||||
|
||||
if (Session::isChannelMode() and autoSegment->isNonPref()) {
|
||||
if (Session::isChannelStyle() and autoSegment->isNonPref()) {
|
||||
cdebug_log(159,0) << "Fixed in non-preferred direction, do not attempt to set on track." << endl;
|
||||
cdebug_tabw(159,-1);
|
||||
DebugSession::close();
|
||||
|
|
|
@ -1207,7 +1207,7 @@ namespace Katana {
|
|||
if ( (layer->getMaterial() != BasicLayer::Material::metal)
|
||||
and (layer->getMaterial() != BasicLayer::Material::blockage) )
|
||||
continue;
|
||||
if (_configuration->isGMetal(layer)) continue;
|
||||
if (getConfiguration()->isGMetal(layer)) continue;
|
||||
if (not query.hasBasicLayer(layer)) continue;
|
||||
|
||||
query.setBasicLayer( layer );
|
||||
|
|
|
@ -123,7 +123,7 @@ extern "C" {
|
|||
if (katana == NULL) {
|
||||
katana = KatanaEngine::create(cell);
|
||||
if (cmess1.enabled())
|
||||
katana->getKatanaConfiguration()->print(cell);
|
||||
katana->getConfiguration()->print(cell);
|
||||
} else
|
||||
cerr << Warning("%s already has a Katana engine.",getString(cell).c_str()) << endl;
|
||||
HCATCH
|
||||
|
|
|
@ -703,7 +703,8 @@ namespace Katana {
|
|||
} else if ( _segment->base()->getAutoSource()->isFixed()
|
||||
or _segment->base()->getAutoTarget()->isFixed()) {
|
||||
cdebug_log(159,0) << "Not expanding on fixed segments:" << _constraints << endl;
|
||||
} else if ( Session::getRoutingGauge()->isTwoMetals()
|
||||
} else if ( ( Session::getKatanaEngine()->isChannelStyle()
|
||||
and not Session::getKatanaEngine()->isHybridStyle())
|
||||
and _segment->base()->isHorizontal()) {
|
||||
cdebug_log(159,0) << "Not expanding on horizontal segments in channel mode:" << _constraints << endl;
|
||||
} else {
|
||||
|
|
|
@ -1514,10 +1514,12 @@ namespace Katana {
|
|||
_data2->resetRipupCount();
|
||||
}
|
||||
|
||||
if ( segment1->isStrap()
|
||||
or segment1->isUnbreakable()) { success = _slackenStrap ( segment1, _data1, flags ); }
|
||||
else if (segment1->isLocal()) { success = _slackenLocal ( segment1, _data1, flags ); }
|
||||
else { success = _slackenGlobal( segment1, _data1, flags ); }
|
||||
if (segment1->isStrap() or segment1->isUnbreakable())
|
||||
success = _slackenStrap ( segment1, _data1, flags );
|
||||
else if (segment1->isLocal())
|
||||
success = _slackenLocal ( segment1, _data1, flags );
|
||||
else
|
||||
success = _slackenGlobal( segment1, _data1, flags );
|
||||
|
||||
if (success) {
|
||||
actionFlags |= SegmentAction::ResetRipup;
|
||||
|
|
|
@ -136,6 +136,7 @@ namespace Katana {
|
|||
bool TrackElement::isFixedAxis () const { return false; }
|
||||
bool TrackElement::isLocal () const { return true; }
|
||||
bool TrackElement::isGlobal () const { return not isLocal(); }
|
||||
bool TrackElement::isWeakGlobal () const { return false; }
|
||||
bool TrackElement::isBipoint () const { return false; }
|
||||
bool TrackElement::isTerminal () const { return false; }
|
||||
bool TrackElement::isDrag () const { return false; }
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace Katana {
|
|||
_element = Session::lookup( _locator.getElement()->getCanonical(bounds)->base() );
|
||||
if (not _element) {
|
||||
AutoSegment* segment = _locator.getElement()->getCanonical(bounds);
|
||||
if (Session::isChannelMode()
|
||||
if (Session::isChannelStyle()
|
||||
and not ((segment->isReduced() or segment->isNonPref()) and segment->isFixed()))
|
||||
cerr << Bug( "Canonical segment without TrackElement on %s."
|
||||
, getString(segment).c_str()) << endl;
|
||||
|
@ -73,7 +73,7 @@ namespace Katana {
|
|||
_element = Session::lookup( _locator.getElement()->getCanonical(bounds)->base() );
|
||||
if (not _element ) {
|
||||
AutoSegment* segment = _locator.getElement()->getCanonical(bounds);
|
||||
if (Session::isChannelMode()
|
||||
if (Session::isChannelStyle()
|
||||
and not ((segment->isReduced() or segment->isNonPref()) and segment->isFixed()))
|
||||
cerr << Bug( "Canonical segment without TrackElement on %s."
|
||||
, getString(segment).c_str() ) << endl;
|
||||
|
|
|
@ -176,14 +176,15 @@ namespace Katana {
|
|||
bool TrackSegment::isFixedAxis () const { return _base->isFixedAxis(); }
|
||||
bool TrackSegment::isHorizontal () const { return _base->isHorizontal(); }
|
||||
bool TrackSegment::isVertical () const { return _base->isVertical(); }
|
||||
bool TrackSegment::isLocal () const { return not _base->isWeakGlobal() and not _base->isGlobal(); }
|
||||
bool TrackSegment::isLocal () const { return not _base->isGlobal() and not _base->isWeakGlobal(); }
|
||||
bool TrackSegment::isGlobal () const { return _base->isWeakGlobal() or _base->isGlobal(); }
|
||||
bool TrackSegment::isUnbreakable () const { return _base->isUnbreakable(); }
|
||||
bool TrackSegment::isWeakGlobal () const { return _base->isWeakGlobal(); }
|
||||
bool TrackSegment::isUnbreakable () const { return _base->isUnbreakable() and not _base->isWeakGlobal(); }
|
||||
bool TrackSegment::isBipoint () const { return _base->isBipoint(); }
|
||||
bool TrackSegment::isTerminal () const { return _base->isTerminal(); }
|
||||
bool TrackSegment::isDrag () const { return _base->isDrag(); }
|
||||
bool TrackSegment::isStrongTerminal ( Flags flags ) const { return _base->isStrongTerminal(flags); }
|
||||
bool TrackSegment::isStrap () const { return _base->isStrap(); }
|
||||
bool TrackSegment::isStrap () const { return _base->isStrap() and not _base->isWeakGlobal(); }
|
||||
bool TrackSegment::isSlackened () const { return _base->isSlackened(); }
|
||||
bool TrackSegment::isDogleg () const { return _base->isDogleg(); }
|
||||
bool TrackSegment::isShortDogleg () const { return _flags & TElemShortDogleg; }
|
||||
|
|
|
@ -105,7 +105,7 @@ namespace Katana {
|
|||
}
|
||||
|
||||
if ( not perpandicular ) {
|
||||
if (Session::isChannelMode()
|
||||
if (Session::isChannelStyle()
|
||||
and not (basePerpand->isReduced() or basePerpand->isNonPref()))
|
||||
cerr << Bug("Not a TrackSegment: %s:%s\n (perpandicular: %s:%s)"
|
||||
,getString((void*)basePerpand->getCanonical(interval)->base()).c_str()
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2017-2018, All Rights Reserved
|
||||
// Copyright (c) Sorbonne Université 2017-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -47,7 +47,7 @@ namespace Katana {
|
|||
|
||||
class Row {
|
||||
public:
|
||||
inline Row ( Block*, DbU::Unit );
|
||||
Row ( Block*, DbU::Unit );
|
||||
inline Block* getBlock () const;
|
||||
inline Cell* getCell () const;
|
||||
inline DbU::Unit getY () const;
|
||||
|
@ -62,6 +62,7 @@ namespace Katana {
|
|||
Record* _getRecord () const;
|
||||
private:
|
||||
Block* _block;
|
||||
bool _isHybrid;
|
||||
DbU::Unit _y;
|
||||
map<DbU::Unit,Occurrence> _occurrences;
|
||||
GCell* _southWest;
|
||||
|
@ -69,9 +70,6 @@ namespace Katana {
|
|||
};
|
||||
|
||||
|
||||
inline Row::Row ( Block* block, DbU::Unit y )
|
||||
: _block(block), _y(y), _occurrences(), _southWest(NULL), _channelHeight(1) { }
|
||||
|
||||
inline DbU::Unit Row::getY () const { return _y; }
|
||||
inline Block* Row::getBlock () const { return _block; }
|
||||
inline GCell* Row::getSouthWest () const { return _southWest; }
|
||||
|
@ -83,15 +81,16 @@ namespace Katana {
|
|||
|
||||
class Block {
|
||||
public:
|
||||
Block ( KatanaEngine*, Cell* );
|
||||
~Block ();
|
||||
inline Cell* getCell () const;
|
||||
Row* getAt ( DbU::Unit y ) const;
|
||||
void add ( Occurrence );
|
||||
void createChannels ();
|
||||
void resizeChannels ();
|
||||
string _getString () const;
|
||||
Record* _getRecord () const;
|
||||
Block ( KatanaEngine*, Cell* );
|
||||
~Block ();
|
||||
inline KatanaEngine* getKatana () const;
|
||||
inline Cell* getCell () const;
|
||||
Row* getAt ( DbU::Unit y ) const;
|
||||
void add ( Occurrence );
|
||||
void createChannels ();
|
||||
void resizeChannels ();
|
||||
string _getString () const;
|
||||
Record* _getRecord () const;
|
||||
private:
|
||||
KatanaEngine* _katana;
|
||||
Cell* _cell;
|
||||
|
@ -99,7 +98,8 @@ namespace Katana {
|
|||
};
|
||||
|
||||
|
||||
inline Cell* Block::getCell () const { return _cell; }
|
||||
inline KatanaEngine* Block::getKatana () const { return _katana; }
|
||||
inline Cell* Block::getCell () const { return _cell; }
|
||||
|
||||
|
||||
// Deferred Row functions.
|
||||
|
|
|
@ -71,8 +71,8 @@ namespace Katana {
|
|||
inline bool useStaticBloatProfile () const;
|
||||
inline CellViewer* getViewer () const;
|
||||
inline AnabaticEngine* base ();
|
||||
inline Configuration* getKatanaConfiguration ();
|
||||
virtual Configuration* getConfiguration ();
|
||||
const Configuration* getConfiguration () const;
|
||||
Configuration* getConfiguration ();
|
||||
inline uint32_t getSuccessState () const;
|
||||
inline uint32_t getStage () const;
|
||||
inline uint64_t getEventsLimit () const;
|
||||
|
@ -152,12 +152,12 @@ namespace Katana {
|
|||
virtual Record* _getRecord () const;
|
||||
virtual string _getString () const;
|
||||
virtual string _getTypeName () const;
|
||||
virtual Configuration* _createConfiguration ();
|
||||
private:
|
||||
// Attributes.
|
||||
static Name _toolName;
|
||||
protected:
|
||||
CellViewer* _viewer;
|
||||
Configuration* _configuration;
|
||||
vector<Block*> _blocks;
|
||||
vector<RoutingPlane*> _routingPlanes;
|
||||
NegociateWindow* _negociateWindow;
|
||||
|
@ -181,26 +181,25 @@ namespace Katana {
|
|||
// Inline Functions.
|
||||
inline bool KatanaEngine::isGlobalRoutingSuccess () const { return (_successState & GlobalRoutingSuccess); }
|
||||
inline bool KatanaEngine::isDetailedRoutingSuccess() const { return (_successState & DetailedRoutingSuccess); }
|
||||
inline bool KatanaEngine::useClockTree () const { return _configuration->useClockTree(); }
|
||||
inline bool KatanaEngine::useGlobalEstimate () const { return _configuration->useGlobalEstimate(); }
|
||||
inline bool KatanaEngine::useStaticBloatProfile () const { return _configuration->useStaticBloatProfile(); }
|
||||
inline bool KatanaEngine::useClockTree () const { return getConfiguration()->useClockTree(); }
|
||||
inline bool KatanaEngine::useGlobalEstimate () const { return getConfiguration()->useGlobalEstimate(); }
|
||||
inline bool KatanaEngine::useStaticBloatProfile () const { return getConfiguration()->useStaticBloatProfile(); }
|
||||
inline CellViewer* KatanaEngine::getViewer () const { return _viewer; }
|
||||
inline AnabaticEngine* KatanaEngine::base () { return static_cast<AnabaticEngine*>(this); }
|
||||
inline Configuration* KatanaEngine::getKatanaConfiguration () { return _configuration; }
|
||||
inline uint32_t KatanaEngine::getStage () const { return _stage; }
|
||||
inline Configuration::PostEventCb_t& KatanaEngine::getPostEventCb () { return _configuration->getPostEventCb(); }
|
||||
inline Configuration::PostEventCb_t& KatanaEngine::getPostEventCb () { return getConfiguration()->getPostEventCb(); }
|
||||
inline uint32_t KatanaEngine::getSuccessState () const { return _successState; }
|
||||
inline uint64_t KatanaEngine::getEventsLimit () const { return _configuration->getEventsLimit(); }
|
||||
inline uint32_t KatanaEngine::getRipupCost () const { return _configuration->getRipupCost(); }
|
||||
inline uint32_t KatanaEngine::getSearchHalo () const { return _configuration->getSearchHalo(); }
|
||||
inline uint32_t KatanaEngine::getBloatOverloadAdd () const { return _configuration->getBloatOverloadAdd(); }
|
||||
inline uint32_t KatanaEngine::getHTracksReservedLocal () const { return _configuration->getHTracksReservedLocal(); }
|
||||
inline uint32_t KatanaEngine::getVTracksReservedLocal () const { return _configuration->getVTracksReservedLocal(); }
|
||||
inline uint32_t KatanaEngine::getTermSatReservedLocal () const { return _configuration->getTermSatReservedLocal(); }
|
||||
inline uint32_t KatanaEngine::getTermSatThreshold () const { return _configuration->getTermSatThreshold(); }
|
||||
inline uint32_t KatanaEngine::getRipupLimit ( uint32_t type ) const { return _configuration->getRipupLimit(type); }
|
||||
inline uint32_t KatanaEngine::getTrackFill () const { return _configuration->getTrackFill(); }
|
||||
inline bool KatanaEngine::profileEventCosts () const { return _configuration->profileEventCosts(); }
|
||||
inline uint64_t KatanaEngine::getEventsLimit () const { return getConfiguration()->getEventsLimit(); }
|
||||
inline uint32_t KatanaEngine::getRipupCost () const { return getConfiguration()->getRipupCost(); }
|
||||
inline uint32_t KatanaEngine::getSearchHalo () const { return getConfiguration()->getSearchHalo(); }
|
||||
inline uint32_t KatanaEngine::getBloatOverloadAdd () const { return getConfiguration()->getBloatOverloadAdd(); }
|
||||
inline uint32_t KatanaEngine::getHTracksReservedLocal () const { return getConfiguration()->getHTracksReservedLocal(); }
|
||||
inline uint32_t KatanaEngine::getVTracksReservedLocal () const { return getConfiguration()->getVTracksReservedLocal(); }
|
||||
inline uint32_t KatanaEngine::getTermSatReservedLocal () const { return getConfiguration()->getTermSatReservedLocal(); }
|
||||
inline uint32_t KatanaEngine::getTermSatThreshold () const { return getConfiguration()->getTermSatThreshold(); }
|
||||
inline uint32_t KatanaEngine::getRipupLimit ( uint32_t type ) const { return getConfiguration()->getRipupLimit(type); }
|
||||
inline uint32_t KatanaEngine::getTrackFill () const { return getConfiguration()->getTrackFill(); }
|
||||
inline bool KatanaEngine::profileEventCosts () const { return getConfiguration()->profileEventCosts(); }
|
||||
inline const DataSymmetricMap& KatanaEngine::getSymmetrics () const { return _symmetrics; }
|
||||
inline Block* KatanaEngine::getBlock ( size_t i ) const { return (i < _blocks.size()) ? _blocks[i] : NULL; }
|
||||
inline NegociateWindow* KatanaEngine::getNegociateWindow () { return _negociateWindow; }
|
||||
|
@ -209,16 +208,16 @@ namespace Katana {
|
|||
KatanaEngine::getRoutingPlanes () const { return _routingPlanes; }
|
||||
inline void KatanaEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; }
|
||||
inline void KatanaEngine::setStage ( uint32_t stage ) { _stage=stage; }
|
||||
inline void KatanaEngine::setEventLimit ( uint64_t limit ) { _configuration->setEventsLimit(limit); }
|
||||
inline void KatanaEngine::setRipupLimit ( uint32_t type, uint32_t limit ) { _configuration->setRipupLimit(limit,type); }
|
||||
inline void KatanaEngine::setRipupCost ( uint32_t cost ) { _configuration->setRipupCost(cost); }
|
||||
inline void KatanaEngine::setBloatOverloadAdd ( uint32_t add ) { _configuration->setBloatOverloadAdd(add); }
|
||||
inline void KatanaEngine::setHTracksReservedLocal ( uint32_t reserved ) { _configuration->setHTracksReservedLocal(reserved); }
|
||||
inline void KatanaEngine::setVTracksReservedLocal ( uint32_t reserved ) { _configuration->setVTracksReservedLocal(reserved); }
|
||||
inline void KatanaEngine::setEventLimit ( uint64_t limit ) { getConfiguration()->setEventsLimit(limit); }
|
||||
inline void KatanaEngine::setRipupLimit ( uint32_t type, uint32_t limit ) { getConfiguration()->setRipupLimit(limit,type); }
|
||||
inline void KatanaEngine::setRipupCost ( uint32_t cost ) { getConfiguration()->setRipupCost(cost); }
|
||||
inline void KatanaEngine::setBloatOverloadAdd ( uint32_t add ) { getConfiguration()->setBloatOverloadAdd(add); }
|
||||
inline void KatanaEngine::setHTracksReservedLocal ( uint32_t reserved ) { getConfiguration()->setHTracksReservedLocal(reserved); }
|
||||
inline void KatanaEngine::setVTracksReservedLocal ( uint32_t reserved ) { getConfiguration()->setVTracksReservedLocal(reserved); }
|
||||
inline void KatanaEngine::addBlock ( Block* block ) { _blocks.push_back(block); }
|
||||
inline void KatanaEngine::setMinimumWL ( double minimum ) { _minimumWL = minimum; }
|
||||
inline void KatanaEngine::setPostEventCb ( Configuration::PostEventCb_t cb ) { _configuration->setPostEventCb(cb); }
|
||||
inline void KatanaEngine::printConfiguration () const { _configuration->print(getCell()); }
|
||||
inline void KatanaEngine::setPostEventCb ( Configuration::PostEventCb_t cb ) { getConfiguration()->setPostEventCb(cb); }
|
||||
inline void KatanaEngine::printConfiguration () const { getConfiguration()->print(getCell()); }
|
||||
inline TrackElement* KatanaEngine::_lookup ( AutoSegment* segment ) const { return segment->getObserver<TrackElement>(AutoSegment::Observable::TrackSegment); }
|
||||
|
||||
inline void KatanaEngine::_addShortDogleg ( TrackElement* segmentA, TrackElement* segmentB )
|
||||
|
|
|
@ -109,6 +109,7 @@ namespace Katana {
|
|||
virtual bool isUnbreakable () const;
|
||||
virtual bool isLocal () const;
|
||||
virtual bool isGlobal () const;
|
||||
virtual bool isWeakGlobal () const;
|
||||
virtual bool isBipoint () const;
|
||||
virtual bool isTerminal () const;
|
||||
virtual bool isDrag () const;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2008-2018, All Rights Reserved
|
||||
// Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -14,9 +14,7 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef KATANA_TRACK_SEGMENT_H
|
||||
#define KATANA_TRACK_SEGMENT_H
|
||||
|
||||
#pragma once
|
||||
#include <set>
|
||||
#include <functional>
|
||||
#include "katana/TrackElement.h"
|
||||
|
@ -68,6 +66,7 @@ namespace Katana {
|
|||
virtual bool isVertical () const;
|
||||
virtual bool isLocal () const;
|
||||
virtual bool isGlobal () const;
|
||||
virtual bool isWeakGlobal () const;
|
||||
virtual bool isBipoint () const;
|
||||
virtual bool isTerminal () const;
|
||||
virtual bool isDrag () const;
|
||||
|
@ -192,5 +191,3 @@ namespace Katana {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Katana::TrackSegment);
|
||||
|
||||
#endif // KATANA_TRACK_SEGMENT_H
|
||||
|
|
Loading…
Reference in New Issue