coriolis/anabatic/src/Configuration.cpp

356 lines
11 KiB
C++
Raw Normal View History

// -*- mode: C++; explicit-buffer-name: "Configuration.cpp<anabatic>" -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2016, 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 : "./Configuration.cpp" |
// +-----------------------------------------------------------------+
#include <iostream>
#include <iomanip>
#include <vector>
#include "vlsisapd/configuration/Configuration.h"
#include "hurricane/Warning.h"
#include "hurricane/Error.h"
#include "hurricane/Technology.h"
#include "hurricane/DataBase.h"
#include "hurricane/RegularLayer.h"
#include "hurricane/Cell.h"
#include "crlcore/Utilities.h"
#include "crlcore/CellGauge.h"
#include "crlcore/RoutingGauge.h"
#include "crlcore/RoutingLayerGauge.h"
#include "crlcore/AllianceFramework.h"
#include "anabatic/Configuration.h"
namespace Anabatic {
using std::cout;
using std::cerr;
using std::endl;
using std::setprecision;
using std::ostringstream;
using std::vector;
using Hurricane::tab;
using Hurricane::Warning;
using Hurricane::Error;
using Hurricane::Technology;
using Hurricane::DataBase;
using Hurricane::RegularLayer;
using CRL::AllianceFramework;
using CRL::RoutingGauge;
using CRL::RoutingLayerGauge;
// -------------------------------------------------------------------
// Class : "Anabatic::Configuration".
Configuration::Configuration () { }
Configuration::~Configuration () { }
// -------------------------------------------------------------------
// Class : "Anabatic::ConfigurationConcrete".
ConfigurationConcrete::ConfigurationConcrete ( const CellGauge* cg, const RoutingGauge* rg )
: Configuration ()
, _cg (NULL)
, _rg (NULL)
, _extensionCaps ()
, _allowedDepth (0)
, _edgeLength (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeLength",24)->asInt()))
, _edgeWidth (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeWidth" , 4)->asInt()))
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
, _edgeCostH (Cfg::getParamDouble("anabatic.edgeCostH", 9.0)->asDouble())
, _edgeCostK (Cfg::getParamDouble("anabatic.edgeCostK",-10.0)->asDouble())
Anabatic transient commit 10. Ripup & reroute support in Dijsktra. * New: In Anabatic: - In AnabaticEngine, keep track of overflowed edges. - In AnabaticEngine, getNetsFromedge() to lookup all nets going through an Edge. - In Configuration, read the Kite "reserved local" parameter to decrease the Edge capacity (it's a guessing of the cost of the local routing). - In Edge, add an attribute to know if there is an associated segment of the current net (set by Dijkstra::_traceback()). Transparently manage the overflowed edges. - In GCell_Edges, correct a filtering bug when not all sides are selecteds. - New GCell::getEdgeTo() to find the edge between two adjacent GCells. - New GCell::unrefContact() to automatically removes global contacts no longer used by any global segments (used during the ripup step). - In Dijkstra::load(), now able to "reload" and already partially or completly routed net (look for Contact of "gcontact" layer and their attached segments). - In Dijkstra, keep the last net loaded until the next one is. Put the cleanup operations in an isolated function "_cleanup()". - In Dijkstra::_selectFirstsource() and run(), load first source component made of multiple vertexes. - In Dijkstra::_trackback(), link the Net segments to the Edges. - New Dijkstra::ripup(), Dijkstra::_propagateRipup() to perform the ripup of one edge of a Net (must be loaded in Dijkstra first). Dijkstra::_tagConnecteds() setup the connexId of a set of Vertexes - that are connecteds through edges *with* segments. - In GraphicAnabaticengine & GlobalRoute.cpp, embryo of a global routing tool with ripup & reroute.
2016-06-26 07:32:32 -05:00
, _hEdgeLocal (Cfg::getParamInt("kite.hTracksReservedLocal",0)->asInt())
, _vEdgeLocal (Cfg::getParamInt("kite.vTracksReservedLocal",0)->asInt())
{
if (cg == NULL) cg = AllianceFramework::get()->getCellGauge();
if (rg == NULL) rg = AllianceFramework::get()->getRoutingGauge();
_cg = cg->getClone();
_rg = rg->getClone();
if (Cfg::hasParameter("anabatic.topRoutingLayer")) {
_setTopRoutingLayer( Cfg::getParamString("anabatic.topRoutingLayer")->asString() );
} else
_allowedDepth = rg->getDepth()-1;
_gmetalh = DataBase::getDB()->getTechnology()->getLayer("gmetalh");
_gmetalv = DataBase::getDB()->getTechnology()->getLayer("gmetalv");
_gcontact = DataBase::getDB()->getTechnology()->getLayer("gcontact");
if (_gcontact == NULL) cerr << Warning("Cannot get \"gcontact\" layer from the Technology.") << endl;
if (_gmetalv == NULL) cerr << Warning("Cannot get \"gmetalv\" layer from the Technology.") << endl;
if (_gmetalh == NULL) cerr << Warning("Cannot get \"gmetalh\" layer from the Technology.") << endl;
//DbU::Unit sliceHeight = _cg->getSliceHeight();
const vector<RoutingLayerGauge*>& layerGauges = rg->getLayerGauges();
for ( size_t depth=0 ; depth < layerGauges.size() ; ++depth ) {
const RegularLayer* regularLayer = dynamic_cast<const RegularLayer*>( layerGauges[depth]->getLayer() );
if (regularLayer)
_extensionCaps.push_back( regularLayer->getExtentionCap() );
else {
_extensionCaps.push_back( 0 );
cerr << Warning( "Routing layer at depth %d is *not* a RegularLayer, cannot guess extension cap.\n"
" (%s)"
, depth
, getString(layerGauges[depth]->getLayer()).c_str()
) << endl;
}
}
}
ConfigurationConcrete::ConfigurationConcrete ( const ConfigurationConcrete& other )
: Configuration()
, _gmetalh (other._gmetalh)
, _gmetalv (other._gmetalv)
, _gcontact (other._gcontact)
, _cg (NULL)
, _rg (NULL)
, _extensionCaps(other._extensionCaps)
, _allowedDepth (other._allowedDepth)
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
, _edgeCostH (other._edgeCostH)
, _edgeCostK (other._edgeCostK)
{
if (other._cg) _cg = other._cg->getClone();
if (other._rg) _rg = other._rg->getClone();
}
ConfigurationConcrete::~ConfigurationConcrete ()
{
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
cdebug_log(145,0) << "About to delete attribute _rg (RoutingGauge)." << endl;
_cg->destroy ();
_rg->destroy ();
}
ConfigurationConcrete* ConfigurationConcrete::clone () const
{ return new ConfigurationConcrete(*this); }
bool ConfigurationConcrete::isGMetal ( const Layer* layer ) const
{ return (layer and ((layer == _gmetalh) or (layer == _gmetalv))); }
bool ConfigurationConcrete::isGContact ( const Layer* layer ) const
{ return (layer and (layer == _gcontact)); }
const Layer* ConfigurationConcrete::getGContactLayer () const
{ return _gcontact; }
const Layer* ConfigurationConcrete::getGHorizontalLayer () const
{ return _gmetalh; }
const Layer* ConfigurationConcrete::getGVerticalLayer () const
{ return _gmetalv; }
size_t ConfigurationConcrete::getDepth () const
{ return _rg->getDepth(); }
size_t ConfigurationConcrete::getAllowedDepth () const
{ return _allowedDepth; }
size_t ConfigurationConcrete::getLayerDepth ( const Layer* layer ) const
{ return _rg->getLayerDepth(layer); }
CellGauge* ConfigurationConcrete::getCellGauge () const
{ return _cg; }
RoutingGauge* ConfigurationConcrete::getRoutingGauge () const
{ return _rg; }
RoutingLayerGauge* ConfigurationConcrete::getLayerGauge ( size_t depth ) const
{ return _rg->getLayerGauge(depth); }
const Layer* ConfigurationConcrete::getRoutingLayer ( size_t depth ) const
{ return _rg->getRoutingLayer(depth); }
Layer* ConfigurationConcrete::getContactLayer ( size_t depth ) const
{ return _rg->getContactLayer(depth); }
DbU::Unit ConfigurationConcrete::getSliceHeight () const
{ return _cg->getSliceHeight(); }
DbU::Unit ConfigurationConcrete::getSliceStep () const
{ return _cg->getSliceStep(); }
DbU::Unit ConfigurationConcrete::getPitch ( const Layer* layer, Flags flags ) const
{ return getPitch( getLayerDepth(layer), flags ); }
DbU::Unit ConfigurationConcrete::getOffset ( const Layer* layer ) const
{ return getOffset( getLayerDepth(layer) ); }
DbU::Unit ConfigurationConcrete::getExtensionCap ( const Layer* layer ) const
{ return getExtensionCap( getLayerDepth(layer) ); }
DbU::Unit ConfigurationConcrete::getWireWidth ( const Layer* layer ) const
{ return getWireWidth( getLayerDepth(layer) ); }
Flags ConfigurationConcrete::getDirection ( const Layer* layer ) const
{ return getDirection( getLayerDepth(layer) ); }
DbU::Unit ConfigurationConcrete::getPitch ( size_t depth, Flags flags ) const
{
if (flags == Flags::NoFlags) return _rg->getLayerPitch(depth);
if (flags & Flags::PitchAbove) {
if (depth < getAllowedDepth())
return _rg->getLayerPitch( depth + 1 );
else {
if ( (depth > 0) and (_rg->getLayerType(depth-1) != Constant::PinOnly) )
return _rg->getLayerPitch( depth - 1 );
}
}
if (flags & Flags::PitchBelow) {
if ( (depth > 0) and (_rg->getLayerType(depth-1) != Constant::PinOnly) )
return _rg->getLayerPitch( depth - 1 );
else {
if (depth < getAllowedDepth())
return _rg->getLayerPitch( depth + 1 );
}
}
// Should issue at least a warning here.
return _rg->getLayerPitch(depth);
}
DbU::Unit ConfigurationConcrete::getOffset ( size_t depth ) const
{ return _rg->getLayerOffset(depth); }
DbU::Unit ConfigurationConcrete::getWireWidth ( size_t depth ) const
{ return _rg->getLayerWireWidth(depth); }
DbU::Unit ConfigurationConcrete::getExtensionCap ( size_t depth ) const
{ return _extensionCaps[depth]; }
Flags ConfigurationConcrete::getDirection ( size_t depth ) const
{ return _rg->getLayerDirection(depth); }
void ConfigurationConcrete::setAllowedDepth ( size_t allowedDepth )
{ _allowedDepth = (allowedDepth > getDepth()) ? getDepth() : allowedDepth; }
void ConfigurationConcrete::_setTopRoutingLayer ( Name name )
{
for ( size_t depth=0 ; depth<_rg->getDepth() ; ++depth ) {
if (_rg->getRoutingLayer(depth)->getName() == name) {
_allowedDepth = _rg->getLayerGauge(depth)->getDepth();
return;
}
}
cerr << Error( "In Configuration::Concrete::_setTopRoutingLayer():\n"
" The routing gauge <%s> has no layer named <%s>"
, getString(_rg->getName()).c_str()
, getString(name).c_str() ) << endl;
}
DbU::Unit ConfigurationConcrete::getEdgeLength () const
{ return _edgeLength; }
DbU::Unit ConfigurationConcrete::getEdgeWidth () const
{ return _edgeWidth; }
Anabatic transient commit 10. Ripup & reroute support in Dijsktra. * New: In Anabatic: - In AnabaticEngine, keep track of overflowed edges. - In AnabaticEngine, getNetsFromedge() to lookup all nets going through an Edge. - In Configuration, read the Kite "reserved local" parameter to decrease the Edge capacity (it's a guessing of the cost of the local routing). - In Edge, add an attribute to know if there is an associated segment of the current net (set by Dijkstra::_traceback()). Transparently manage the overflowed edges. - In GCell_Edges, correct a filtering bug when not all sides are selecteds. - New GCell::getEdgeTo() to find the edge between two adjacent GCells. - New GCell::unrefContact() to automatically removes global contacts no longer used by any global segments (used during the ripup step). - In Dijkstra::load(), now able to "reload" and already partially or completly routed net (look for Contact of "gcontact" layer and their attached segments). - In Dijkstra, keep the last net loaded until the next one is. Put the cleanup operations in an isolated function "_cleanup()". - In Dijkstra::_selectFirstsource() and run(), load first source component made of multiple vertexes. - In Dijkstra::_trackback(), link the Net segments to the Edges. - New Dijkstra::ripup(), Dijkstra::_propagateRipup() to perform the ripup of one edge of a Net (must be loaded in Dijkstra first). Dijkstra::_tagConnecteds() setup the connexId of a set of Vertexes - that are connecteds through edges *with* segments. - In GraphicAnabaticengine & GlobalRoute.cpp, embryo of a global routing tool with ripup & reroute.
2016-06-26 07:32:32 -05:00
size_t ConfigurationConcrete::getHEdgeLocal () const
{ return _hEdgeLocal; }
size_t ConfigurationConcrete::getVEdgeLocal () const
{ return _vEdgeLocal; }
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
float ConfigurationConcrete::getEdgeCostH () const
{ return _edgeCostH; }
float ConfigurationConcrete::getEdgeCostK () const
{ return _edgeCostK; }
void ConfigurationConcrete::print ( Cell* cell ) const
{
string topLayerName = "UNKOWN";
const Layer* topLayer = _rg->getRoutingLayer( _allowedDepth );
if (topLayer)
topLayerName = getString( topLayer->getName() );
cout << " o Configuration of ToolEngine<Anabatic> for Cell <" << cell->getName() << ">" << endl;
cout << Dots::asIdentifier(" - Routing Gauge" ,getString(_rg->getName())) << endl;
cout << Dots::asString (" - Top routing layer" ,topLayerName) << endl;
}
string ConfigurationConcrete::_getTypeName () const
{
return "ConfigurationConcrete";
}
string ConfigurationConcrete::_getString () const
{
ostringstream os;
os << "<" << _getTypeName() << " " << _rg->getName() << ">";
return os.str();
}
Record* ConfigurationConcrete::_getRecord () const
{
Record* record = new Record ( _getString() );
Anabatic transient commit 8. More Dijkstra bugs correcteds. * Bug: In Anabatic: - In _propagate(), on reaching a target, forgot to remove it from the queue before pushing it back with the new distance. It also simplificate the core algorithm as target as treated normal nodes. * New: In Anabatic: - Update cdebug to use the fastest macro version. - More readable drawings of GCells and Edges. - Added timer support. - The distance is now computed in DbU::Unit (aka long) and not in normalized float. - The distance function is now a callback (std::function<>) that can be changed (a default is provided at initialization). - New concept of branch in the agglomerated connex component. Each trace back part create a "branch" (tagged with a "branchId"). When a node is reached with the same distance, but from two different branches, choose the the branch that was lastly created. This create a slightly different tree which grows outward from the newest branches. - Makes the horizontal edges *slightly* longer than the vertical ones to skew the tree to use vertical edges, as it is usually less congested than the horiontal one (due to metal1 cell terminals). It is also my understanding that it is useful to reduce the number of vias, whithout introducing a via cost. * New: In Bootstrap: - Script sprof.py to perform sprof & demangle libraries execution profile. * ToDo: In Anabatic: - Corner optimization. Sometimes when two corners are possible, the wrong one is choosen. That is, one of it's edge cannot be used for further grow of the tree.
2016-06-17 06:09:34 -05:00
record->add ( getSlot( "_rg" , _rg ) );
record->add ( getSlot( "_gmetalh" , _gmetalh ) );
record->add ( getSlot( "_gmetalv" , _gmetalv ) );
record->add ( getSlot( "_gcontact" , _gcontact ) );
record->add ( getSlot( "_allowedDepth", _allowedDepth ) );
record->add ( getSlot( "_edgeCostH" , _edgeCostH ) );
record->add ( getSlot( "_edgeCostK" , _edgeCostK ) );
return ( record );
}
} // Anabatic namespace.