coriolis/katana/src/TrackSegmentRegular.cpp

112 lines
3.4 KiB
C++
Raw Normal View History

// -*- 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 |
// | K i t e - D e t a i l e d R o u t e r |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
// | =============================================================== |
// | C++ Module : "./TrackSegmentRegular.cpp" |
// +-----------------------------------------------------------------+
#include <sstream>
#include <limits>
#include "hurricane/Bug.h"
#include "hurricane/Warning.h"
#include "hurricane/BasicLayer.h"
#include "hurricane/Net.h"
#include "hurricane/Name.h"
#include "hurricane/RoutingPad.h"
#include "anabatic/AutoContact.h"
#include "anabatic/GCell.h"
#include "crlcore/RoutingGauge.h"
#include "katana/DataNegociate.h"
#include "katana/TrackSegmentRegular.h"
#include "katana/Track.h"
#include "katana/Session.h"
#include "katana/RoutingEvent.h"
#include "katana/NegociateWindow.h"
#include "katana/KatanaEngine.h"
namespace Katana {
using namespace std;
using Hurricane::tab;
using Hurricane::Bug;
using Hurricane::Error;
using Hurricane::BasicLayer;
using Hurricane::Net;
using Hurricane::Name;
using Hurricane::RoutingPad;
Katana manage wide wires, and they can also be symmetric. * New: In Anabatic::AutoContact and the derived classes, manages wide wires. The contact self dimension itself according to the segments it is connected to. Special case for the AutoContactTerminal which also read the size of the component it is anchored upon. New refresh method "updateSize()" and flag CntInvalidatedWidth. to compute the size. In AutoContactTerminal, compute the constraint box according to the width of the segment. * New: In Anabatic::AutoSegment, flags are now implemented as "static const" attributes of the class. The flags are stored into a uint64_t as they are more than 32. Added new flag "SegWide" and associated predicates. * Change: In GCellTopology::_doHChannel() and GCellTopology::_doVChannel(), uses the simpler overload of AutoSegment::create() in order to detect the wire width automatically. * New: In Katana::Manipulator, split insertToTrack() and forceToTrack() into a one-track method and a segment level method that iterate over the track span of the segment. * New: In Katana::SegmentFsm, for each cost in the table, now allow access to a specific track. So the base functions have now two parameters: "icost" and "itrack" (has a cost can have multiple tracks in the case of wide segments). * Change: In Katana::TrackElement, remove the index of the element inside it's track, as for a wide segment it will not be meaningful for the non-base track. This means that we have to use the Track::find() method each time instead. Remove the wide flag, as it is a duplicate of the one in AutoSegment. Added a getTrackCount() method to tell the number of track the segment is inserted into. Needed in the Track destroy step to delete a segment only when the last track that refers it is destroyed. Added getSymmetricAxis() to correct the computation of the symmetric base track in case of wide segment as the base track is not centered but the the leftmost one. * Change: In Track::insert() insert wide segments in their whole track span. * Change: In TrackCost, create an array of costs according to the segment track span. * Change: In TrackSegment::create(), now activate the factory and create wide segments. * Bug: In Katana::AutoSegments_Perpandicular, correct the debug indentation problem (ever shifting to the right).
2017-07-28 08:30:22 -05:00
using Anabatic::AutoSegment;
using Anabatic::perpandicularTo;
// -------------------------------------------------------------------
// Class : "TrackSegmentRegular".
TrackSegmentRegular::TrackSegmentRegular ( AutoSegment* segment, Track* track )
: Super(segment,track)
{
// cdebug_log(155,0) << "CTOR TrackSegmentRegular " << (void*)this << ":" << this << endl;
// cdebug_log(155,0) << " over " << (void*)segment << ":" << segment << endl;
}
void TrackSegmentRegular::_postCreate ()
{
Super::_postCreate();
}
TrackSegmentRegular::~TrackSegmentRegular ()
{
}
void TrackSegmentRegular::_preDestroy ()
{
Super::_preDestroy();
}
size_t TrackSegmentRegular::getTrackSpan () const { return 1; }
void TrackSegmentRegular::addOverlapCost ( TrackCost& cost ) const
{
uint32_t depth = Session::getRoutingGauge()->getLayerDepth(getLayer());
bool inLocalDepth = (depth < 3);
bool isOneLocalTrack = (isLocal()) and (base()->getAutoSource()->getGCell()->getGlobalsCount(depth) >= 9.0);
Track* track = cost.getTrack();
if (not track) return;
cost.setFlags( (isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0 );
cost.setFlags( (isAnalog()) ? TrackCost::Analog : 0 );
track->addOverlapCost( cost );
cost.setDistanceToFixed();
cost.incAxisWeight ( getDataNegociate()->getRoutingEvent()->getAxisWeight(track->getAxis()) );
cost.incDeltaPerpand ( getDataNegociate()->getWiringDelta(track->getAxis()) );
if (isGlobal()) cost.setForGlobal();
if ( inLocalDepth and (cost.getDataState() == DataNegociate::MaximumSlack) )
cost.setInfinite();
if ( isOneLocalTrack
and cost.isOverlapGlobal()
and (cost.getDataState() >= DataNegociate::ConflictSolveByHistory) )
cost.setInfinite();
}
} // Katana namespace.