From 17bff6a30397291ba5c5060730c840ce29856097 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 24 Oct 2023 13:49:42 +0200 Subject: [PATCH 01/51] Add support for MOSIS & AMS350 (c35b4) in designflow.technos. --- cumulus/src/designflow/technos.py | 125 ++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) diff --git a/cumulus/src/designflow/technos.py b/cumulus/src/designflow/technos.py index f807780d4..396d71838 100644 --- a/cumulus/src/designflow/technos.py +++ b/cumulus/src/designflow/technos.py @@ -186,6 +186,65 @@ def setupCMOS45 ( useNsxlib=False, checkToolkit=None, cellsTop=None ): break +def setupMOSIS ( checkToolkit=None, cellsTop=None ): + from .. import Cfg + from .. import Viewer + from .. import CRL + from ..helpers import overlay, l, u, n + from .yosys import Yosys + import coriolis.technos.node180.scn6m_deep_09 + + Where( checkToolkit ) + if cellsTop is None: + cellsTop = Where.cellsTop + else: + if isinstance(cellsTop,str): + cellsTop = Path( cellsTop ) + + with overlay.CfgCache(priority=Cfg.Parameter.Priority.UserFile) as cfg: + cfg.misc.catchCore = False + cfg.misc.info = False + cfg.misc.paranoid = False + cfg.misc.bug = False + cfg.misc.logMode = True + cfg.misc.verboseLevel1 = True + cfg.misc.verboseLevel2 = True + cfg.misc.minTraceLevel = 1900 + cfg.misc.maxTraceLevel = 3000 + cfg.katana.eventsLimit = 1000000 + cfg.etesian.graphics = 3 + cfg.etesian.spaceMargin = 0.05 + cfg.etesian.aspectRatio = 1.0 + cfg.anabatic.edgeLenght = 24 + cfg.anabatic.edgeWidth = 8 + cfg.katana.termSatReservedLocal = 6 + cfg.katana.termSatThreshold = 9 + + Viewer.Graphics.setStyle( 'Alliance.Classic [black]' ) + af = CRL.AllianceFramework.get() + env = af.getEnvironment() + env.setCLOCK( '^ck$|m_clock|^clk$' ) + + sxlib = cellsTop / 'nsxlib' + iolib = cellsTop / 'niolib' + liberty = sxlib / 'nsxlib.lib' + env.addSYSTEM_LIBRARY( library=iolib.as_posix(), mode=CRL.Environment.Prepend ) + env.addSYSTEM_LIBRARY( library=sxlib.as_posix(), mode=CRL.Environment.Prepend ) + if not sxlib.is_dir(): + print( '[ERROR] technos.setupCMOS45(): nsxlib directory do *not* exists:' ) + print( ' "{}"'.format(sxlib.as_posix()) ) + + Yosys.setLiberty( liberty ) + #ShellEnv.RDS_TECHNO_NAME = (Where.checkToolkit / 'etc' / 'FreePDK45.rds').as_posix() + + path = None + for pathVar in [ 'PATH', 'path' ]: + if pathVar in os.environ: + path = os.environ[ pathVar ] + os.environ[ pathVar ] = path + ':' + (Where.allianceTop / 'bin').as_posix() + break + + def setupSky130_c4m ( checkToolkit=None, pdkMasterTop=None ): from .. import Cfg from .. import Viewer @@ -447,3 +506,69 @@ def setupGF180MCU_GF ( checkToolkit=None, pdkTop=None ): Yosys.setLiberty( liberty ) ShellEnv.CHECK_TOOLKIT = Where.checkToolkit.as_posix() + + +def setupAMS350 ( checkToolkit=None, ndaTop=None, cellsTop=None ): + from .. import Cfg + from .. import Viewer + from .. import CRL + from ..helpers import setNdaTopDir, overlay, l, u, n + from .yosys import Yosys + + if isinstance(ndaTop,str): + ndaTop = Path( ndaTop ) + setNdaTopDir( ndaTop.as_posix() ) + if not ndaTop.is_dir(): + print( '[ERROR] technos.setupAMS350(): ndaTop directory do *not* exists:' ) + print( ' "{}"'.format(ndaTop.as_posix()) ) + import NDA.node350.c35b4 + + Where( checkToolkit ) + if cellsTop is None: + cellsTop = Where.cellsTop + else: + if isinstance(cellsTop,str): + cellsTop = Path( cellsTop ) + + with overlay.CfgCache(priority=Cfg.Parameter.Priority.UserFile) as cfg: + cfg.misc.catchCore = False + cfg.misc.info = False + cfg.misc.paranoid = False + cfg.misc.bug = False + cfg.misc.logMode = True + cfg.misc.verboseLevel1 = True + cfg.misc.verboseLevel2 = True + cfg.misc.minTraceLevel = 1900 + cfg.misc.maxTraceLevel = 3000 + cfg.katana.eventsLimit = 1000000 + cfg.etesian.graphics = 3 + cfg.etesian.spaceMargin = 0.05 + cfg.etesian.aspectRatio = 1.0 + cfg.anabatic.edgeLenght = 24 + cfg.anabatic.edgeWidth = 8 + cfg.katana.termSatReservedLocal = 6 + cfg.katana.termSatThreshold = 9 + + Viewer.Graphics.setStyle( 'Alliance.Classic [black]' ) + af = CRL.AllianceFramework.get() + env = af.getEnvironment() + env.setCLOCK( '^ck$|m_clock|^clk$' ) + + sxlib = cellsTop / 'nsxlib' + iolib = cellsTop / 'niolib' + liberty = sxlib / 'nsxlib.lib' + env.addSYSTEM_LIBRARY( library=iolib.as_posix(), mode=CRL.Environment.Prepend ) + env.addSYSTEM_LIBRARY( library=sxlib.as_posix(), mode=CRL.Environment.Prepend ) + if not sxlib.is_dir(): + print( '[ERROR] technos.setupAMS350(): nsxlib directory do *not* exists:' ) + print( ' "{}"'.format(sxlib.as_posix()) ) + + Yosys.setLiberty( liberty ) + #ShellEnv.RDS_TECHNO_NAME = (Where.checkToolkit / 'etc' / 'FreePDK45.rds').as_posix() + + path = None + for pathVar in [ 'PATH', 'path' ]: + if pathVar in os.environ: + path = os.environ[ pathVar ] + os.environ[ pathVar ] = path + ':' + (Where.allianceTop / 'bin').as_posix() + break From 4ff63cfe16b64c83f82303acd798bb19b22ddc9d Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 24 Oct 2023 13:50:52 +0200 Subject: [PATCH 02/51] The karakaze tool (AnalogDesign) was forgotten in the installation. --- meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/meson.build b/meson.build index d1ca26218..2446ab5bf 100644 --- a/meson.build +++ b/meson.build @@ -113,6 +113,7 @@ subdir('equinox') subdir('solstice') subdir('unicorn') subdir('oroshi') +subdir('karakaze') subdir('bora') subdir('cumulus') subdir('tutorial') From 7926084f78e8ebc78baf9684b011d2bed736df3f Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Fri, 20 Oct 2023 11:01:38 +0200 Subject: [PATCH 03/51] Intalling the techno files for gf180mcu_c4m from CRL. --- crlcore/python/meson.build | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/crlcore/python/meson.build b/crlcore/python/meson.build index e5dcfab05..3d1ce67c9 100644 --- a/crlcore/python/meson.build +++ b/crlcore/python/meson.build @@ -36,6 +36,14 @@ py.install_sources( subdir: 'coriolis/technos/node180/gf180mcu', ) +py.install_sources( + 'technos/node180/gf180mcu_c4m/__init__.py', + 'technos/node180/gf180mcu_c4m/techno.py', + 'technos/node180/gf180mcu_c4m/StdCell3V3Lib.py', + 'technos/node180/gf180mcu_c4m/iolib.py', + subdir: 'coriolis/technos/node180/gf180mcu_c4m', +) + py.install_sources( 'technos/node180/scn6m_deep_09/__init__.py', 'technos/node180/scn6m_deep_09/alliance.py', From 1b31166c304c5885cc5262280df39222f1a11de1 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Fri, 20 Oct 2023 12:26:21 +0200 Subject: [PATCH 04/51] The designflow sv2v, svase & surelog were forgotten in the merges. --- cumulus/src/designflow/meson.build | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cumulus/src/designflow/meson.build b/cumulus/src/designflow/meson.build index 0eca0a58e..56aa9db6b 100644 --- a/cumulus/src/designflow/meson.build +++ b/cumulus/src/designflow/meson.build @@ -22,6 +22,9 @@ designflow = files([ 'pnrcheck.py', 'routecheck.py', 's2r.py', + 'surelog.py', + 'sv2v.py', + 'svase.py', 'task.py', 'technos.py', 'vasy.py', From 8aa6565ce31143319a1920652345a3456de7f8ab Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Fri, 20 Oct 2023 14:36:08 +0200 Subject: [PATCH 05/51] One more forgotten to install gf180mcu file. --- cumulus/src/plugins/core2chip/meson.build | 1 + 1 file changed, 1 insertion(+) diff --git a/cumulus/src/plugins/core2chip/meson.build b/cumulus/src/plugins/core2chip/meson.build index 19b54a45e..5aa301c5f 100644 --- a/cumulus/src/plugins/core2chip/meson.build +++ b/cumulus/src/plugins/core2chip/meson.build @@ -2,6 +2,7 @@ core2chip = files([ '__init__.py', 'cmos.py', 'core2chip.py', + 'gf180mcu.py', 'libresocio.py', 'niolib.py', 'phlib.py', From 118913c01db0aae01f23742f5afa7bf9f92e5085 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 24 Oct 2023 13:42:24 +0200 Subject: [PATCH 06/51] Must setup the Coriolis source directory in regression tests. --- .github/workflows/regression.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml index 98e09c975..739fab73a 100644 --- a/.github/workflows/regression.yml +++ b/.github/workflows/regression.yml @@ -58,7 +58,7 @@ jobs: run: | export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" cd ${{ github.workspace }}/coriolis-2.x/src/coriolis - make -f Makefile.LIP6 install install_alliance + make -f Makefile.LIP6 SRC_DIR=${{ github.workspace }}/coriolis-2.x/src install install_alliance - name: Check for binaries run: ls -1 ${{ github.workspace }}/coriolis-2.x/release/install/bin - name: Run the reference set of designs From 4ca2809fc97d3a5cd872bb9c61bfaabd93dad321 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Sat, 25 Nov 2023 12:39:27 +0100 Subject: [PATCH 07/51] Create separate rules for meson configure & setup. --- Makefile.LIP6 | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Makefile.LIP6 b/Makefile.LIP6 index 42c436a9b..c483d09c8 100644 --- a/Makefile.LIP6 +++ b/Makefile.LIP6 @@ -63,11 +63,15 @@ $(CORIOLIS_SRC)/.pdm-plugins/bin/pdm: $(HOME)/.local/bin/pdm @$(localpath) pdm install --no-self -d --plugins -configure: +setup: @$(localpath) pdm run meson setup ${BUILDDIR} --prefix=$(PREFIX) -Dpython.install_env=prefix -install: check_dir $(CORIOLIS_SRC)/.pdm-plugins/bin/pdm configure +configure: + @$(localpath) pdm run meson configure ${BUILDDIR} --prefix=$(PREFIX) -Dpython.install_env=prefix + + +install: check_dir $(CORIOLIS_SRC)/.pdm-plugins/bin/pdm setup @$(localpath) pdm run meson install -C $(BUILDDIR) @echo ""; \ echo "============================================================================"; \ From 60bc1143f50fc276972d4ba7b6b309612f5cd21b Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 29 Nov 2023 21:44:47 +0100 Subject: [PATCH 08/51] New Rectilinear::getAsBiggestrectangles() method. * Returns the set of biggest rectangles inscribed inside the Rectilinear. This is *not* a partition, the rectangles overlaps. This is intended for the router to select the biggest rectangle in the direction he sees fit and making it a RoutingPad. --- .gitignore | 1 + documentation/examples/scripts/rectilinear.py | 10 +- hurricane/src/hurricane/Rectilinear.cpp | 490 +++++++++++++++++- .../src/hurricane/hurricane/Rectilinear.h | 4 + hurricane/src/isobar/PyRectilinear.cpp | 43 +- unittests/python/dodo.py | 34 ++ unittests/python/test_rectilinear.py | 8 +- 7 files changed, 562 insertions(+), 28 deletions(-) create mode 100644 unittests/python/dodo.py diff --git a/.gitignore b/.gitignore index 2e3fcedb5..0be67268a 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ build/ venv/ coriolis.egg-info/ .pdm-python +.doit.db bootstrap/coriolis2.spec diff --git a/documentation/examples/scripts/rectilinear.py b/documentation/examples/scripts/rectilinear.py index a5358ab71..23fa7e560 100644 --- a/documentation/examples/scripts/rectilinear.py +++ b/documentation/examples/scripts/rectilinear.py @@ -1,11 +1,11 @@ #!/usr/bin/python import sys -from Hurricane import DataBase, Net, \ - DbU, Point, Box, Rectilinear -from CRL import AllianceFramework, Catalog, Gds -from helpers import l, u -from helpers.overlay import UpdateSession +from coriolis.Hurricane import DataBase, Net, \ + DbU, Point, Box, Rectilinear +from coriolis.CRL import AllianceFramework, Catalog, Gds +from coriolis.helpers import l, u +from coriolis.helpers.overlay import UpdateSession def buildRectilinear ( editor ): diff --git a/hurricane/src/hurricane/Rectilinear.cpp b/hurricane/src/hurricane/Rectilinear.cpp index 63564ed7e..a50eab4c1 100644 --- a/hurricane/src/hurricane/Rectilinear.cpp +++ b/hurricane/src/hurricane/Rectilinear.cpp @@ -38,6 +38,7 @@ #include "hurricane/Cell.h" #include "hurricane/Error.h" #include "hurricane/Warning.h" +#include "hurricane/DebugSession.h" namespace { @@ -48,48 +49,144 @@ namespace { using Hurricane::Box; using Hurricane::Interval; using Hurricane::Rectilinear; + using Hurricane::DebugSession; + +// ------------------------------------------------------------------- +// Class : "SweepInterval". - class SweepInterval : public Interval { + + class SweepInterval { public: - inline SweepInterval ( DbU::Unit vmin , DbU::Unit vmax, DbU::Unit xmin ); - inline SweepInterval ( Interval&, DbU::Unit xmin ); - inline SweepInterval& inflate ( DbU::Unit dvMin, DbU::Unit dvMax ); - inline SweepInterval& merge ( DbU::Unit v ); - inline DbU::Unit getXMin () const; - inline void setXMin ( DbU::Unit ); - inline string _getString () const; + inline SweepInterval (); + inline SweepInterval ( const SweepInterval& ); + inline SweepInterval ( DbU::Unit vmin , DbU::Unit vmax, DbU::Unit xmin ); + inline SweepInterval ( Interval&, DbU::Unit xmin ); + inline bool isEmpty () const; + inline bool isKeep () const; + inline bool isNewLeft () const; + inline bool isExactMatch () const; + inline bool isSplinter () const; + inline bool isPonctual () const; + inline uint32_t getId () const; + inline DbU::Unit getVMin () const; + inline DbU::Unit getVMax () const; + inline DbU::Unit getSize () const; + inline const Interval& getSpan () const; + inline void inflate ( DbU::Unit dvMin, DbU::Unit dvMax ); + inline void updateSpan ( const Interval& ); + inline void merge ( DbU::Unit v ); + inline DbU::Unit getXMin () const; + inline void setXMin ( DbU::Unit ); + inline void setKeep (); + inline void setNewLeft (); + inline void setExactMatch (); + inline void setSplinter (); + inline void unsetNewLeft (); + inline void unsetSplinter (); + inline void clearUpdateFlags (); + inline string _getString () const; + inline bool operator< ( const SweepInterval& ) const; + private: + const uint32_t NOFLAGS = 0; + const uint32_t UPDATED = (1<<0); + const uint32_t CARVED = (1<<1); + const uint32_t ENLARGED = (1<<2); + const uint32_t EMPTY = (1<<3); + const uint32_t NEW_LEFT = (1<<4); + const uint32_t KEEP = (1<<5); + const uint32_t EXACT_MATCH = (1<<6); + const uint32_t SPLINTER = (1<<7); + static uint32_t _idCounter; private: + uint32_t _id; + Interval _span; + Interval _nextSpan; DbU::Unit _xMin; + uint32_t _flags; }; + + uint32_t SweepInterval::_idCounter = 0; + - inline SweepInterval::SweepInterval ( DbU::Unit vmin , DbU::Unit vmax, DbU::Unit xmin ) - : Interval(vmin,vmax) - , _xMin (xmin) + inline SweepInterval::SweepInterval () + : _id (_idCounter++) + , _span () + , _xMin (0) + , _flags(EMPTY|NEW_LEFT) { } + + inline SweepInterval::SweepInterval ( DbU::Unit vmin , DbU::Unit vmax, DbU::Unit xmin ) + : _id (_idCounter++) + , _span (vmin,vmax) + , _xMin (xmin) + , _flags(NOFLAGS|NEW_LEFT) + { } + + inline SweepInterval::SweepInterval ( Interval& base, DbU::Unit xmin ) - : Interval(base) - , _xMin (xmin) + : _id (_idCounter++) + , _span (base) + , _xMin (xmin) + , _flags(NEW_LEFT) { } - inline SweepInterval& SweepInterval::inflate ( DbU::Unit dvMin, DbU::Unit dvMax ) { Interval::inflate(dvMin,dvMax); return *this; } - inline SweepInterval& SweepInterval::merge ( DbU::Unit v ) { Interval::merge(v); return *this; } - inline DbU::Unit SweepInterval::getXMin () const { return _xMin; } - inline void SweepInterval::setXMin ( DbU::Unit xmin ) { _xMin=xmin; } + + inline SweepInterval::SweepInterval ( const SweepInterval& other ) + : _id (_idCounter++) + , _span (other._span) + , _xMin (other._xMin) + , _flags(other._flags) + { } + + + inline bool SweepInterval::operator< ( const SweepInterval& o ) const + { + if (_span.getVMin() != o._span.getVMin()) return _span.getVMin() < o._span.getVMin(); + if (_span.getVMax() != o._span.getVMax()) return _span.getVMax() < o._span.getVMax(); + if (_xMin != o._xMin) return _xMin < o._xMin; + return _id < o._id; + } + + + inline bool SweepInterval::isEmpty () const { return (_flags & EMPTY); } + inline bool SweepInterval::isKeep () const { return (_flags & KEEP); } + inline bool SweepInterval::isNewLeft () const { return (_flags & NEW_LEFT); } + inline bool SweepInterval::isExactMatch () const { return (_flags & EXACT_MATCH); } + inline bool SweepInterval::isSplinter () const { return (_flags & SPLINTER); } + inline bool SweepInterval::isPonctual () const { return _span.isPonctual(); } + inline uint32_t SweepInterval::getId () const { return _id; } + inline const Interval& SweepInterval::getSpan () const { return _span; } + inline DbU::Unit SweepInterval::getVMin () const { return _span.getVMin(); } + inline DbU::Unit SweepInterval::getVMax () const { return _span.getVMax(); } + inline DbU::Unit SweepInterval::getSize () const { return _span.getSize(); } + inline void SweepInterval::inflate ( DbU::Unit dvMin, DbU::Unit dvMax ) { _span.inflate(dvMin,dvMax); } + inline void SweepInterval::merge ( DbU::Unit v ) { _span.merge(v); } + inline DbU::Unit SweepInterval::getXMin () const { return _xMin; } + inline void SweepInterval::setXMin ( DbU::Unit xmin ) { _xMin=xmin; } + inline void SweepInterval::setKeep () { _flags |= KEEP; } + inline void SweepInterval::setNewLeft () { _flags |= NEW_LEFT; } + inline void SweepInterval::setExactMatch () { _flags |= EXACT_MATCH; } + inline void SweepInterval::setSplinter () { _flags |= SPLINTER; } + inline void SweepInterval::unsetNewLeft () { _flags &= ~NEW_LEFT; } + inline void SweepInterval::unsetSplinter () { _flags &= ~SPLINTER; } + inline void SweepInterval::clearUpdateFlags () { _flags &= ~(KEEP | NEW_LEFT | EXACT_MATCH); } + inline void SweepInterval::updateSpan ( const Interval& v ) { _span.intersection(v); } + inline string SweepInterval::_getString () const { string s; - s += "@" + DbU::getValueString(_xMin); - s += " [" + DbU::getValueString(getVMin()); - s += " " + DbU::getValueString(getVMax()) + "]"; + s += ""; return s; } -} // Anonymous namespace. +} GETSTRING_VALUE_SUPPORT(::SweepInterval); @@ -98,6 +195,10 @@ GETSTRING_VALUE_SUPPORT(::SweepInterval); namespace { +// ------------------------------------------------------------------- +// Class : "SweepLine". + + class SweepLine { public: SweepLine ( const Rectilinear*, vector& ); @@ -314,6 +415,339 @@ namespace { cdebug_log(17,0) << "| " << b << endl; } + +// ------------------------------------------------------------------- +// Class : "SweepLineBig". + + + class SweepLineBig { + public: + SweepLineBig ( const Rectilinear* + , vector& + , DbU::Unit xThreshold + , DbU::Unit yThreshold ); + ~SweepLineBig (); + void addVEdge ( DbU::Unit ymin, DbU::Unit ymax, DbU::Unit x ); + void loadVEdges (); + void updateLeftSide (); + void process ( Interval ); + void process ( const pair< DbU::Unit, list >& ); + void flushBoxes ( const Interval& ); + void toBox ( SweepInterval& ); + void asRectangles (); + private: + const Rectilinear* _rectilinear; + vector& _boxes; + list< pair< DbU::Unit, list > > _vedges; + list< SweepInterval > _sweepLine; + list< SweepInterval > _leftSides; + DbU::Unit _currX; + DbU::Unit _xThreshold; + DbU::Unit _yThreshold; + }; + + + SweepLineBig::SweepLineBig ( const Rectilinear* r + , vector& boxes + , DbU::Unit xThreshold + , DbU::Unit yThreshold ) + : _rectilinear(r) + , _boxes (boxes) + , _vedges () + , _sweepLine () + , _leftSides () + , _currX (0) + , _xThreshold (xThreshold) + , _yThreshold (yThreshold) + { + cdebug_log(17,1) << "SweepLineBig::SweepLineBig()" << endl; + cdebug_log(17,0) << "_xThreshold=" << DbU::getValueString(_xThreshold) << endl; + cdebug_log(17,0) << "_yThreshold=" << DbU::getValueString(_yThreshold) << endl; + } + + + SweepLineBig::~SweepLineBig () + { + cdebug_tabw(17,-1); + } + + + void SweepLineBig::addVEdge ( DbU::Unit ymin, DbU::Unit ymax, DbU::Unit x ) + { + if (ymin > ymax) std::swap( ymin, ymax ); + + cdebug_log(17,1) << "SweepLineBig::addVEdge() @"<< DbU::getValueString(x) + << " [" << DbU::getValueString(ymin) + << " " << DbU::getValueString(ymax) << "]" << endl; + + bool inserted = false; + for ( auto ix = _vedges.begin() ; ix != _vedges.end() ; ++ix ) { + cdebug_log(17,0) << "| Looking @" << DbU::getValueString(ix->first) + << " size=" << ix->second.size() << endl; + + if (ix->first > x) { + _vedges.insert( ix, make_pair( x, list() )); + cdebug_log(17,0) << "+ add new @" << DbU::getValueString(x) << endl; + --ix; + } + if (ix->first == x) { + for ( auto iintv = ix->second.begin() ; iintv != ix->second.end() ; ++iintv ) { + if (iintv->getVMin() >= ymax) { + ix->second.insert( iintv, Interval(ymin,ymax) ); + inserted = true; + break; + } + } + if (not inserted) { + ix->second.push_back( Interval(ymin,ymax) ); + inserted = true; + } + break; + } + } + if (not inserted) { + cdebug_log(17,0) << "+ add new (back) @" << DbU::getValueString(x) << endl; + _vedges.push_back( make_pair( x, list() )); + _vedges.back().second.push_back( Interval(ymin,ymax) ); + } + + cdebug_tabw(17,-1); + } + + + void SweepLineBig::loadVEdges () + { + const vector& points = _rectilinear->getPoints(); + for ( size_t i=0 ; i 0) and (_currX - intv.getXMin() < _xThreshold)) return; + if ((_yThreshold > 0) and (intv.getSize() < _yThreshold)) return; + + _boxes.push_back( Box( intv.getXMin(), intv.getVMin() + , _currX , intv.getVMax() )); + cdebug_log(17,0) << " toBox() " << _boxes.back() << endl; + } + + + void SweepLineBig::updateLeftSide () + { + cdebug_log(17,1) << "SweepLineBig::updateLeftSide() @" << DbU::getValueString(_currX) << endl; + for ( auto isweep = _sweepLine.begin() ; isweep != _sweepLine.end() ; ++isweep ) { + cdebug_log(17,1) << "Sweep " << *isweep << endl; + DbU::Unit leftX = _currX; + for ( auto ileft = _leftSides.begin() ; (ileft != _leftSides.end()) ; ++ileft ) { + cdebug_log(17,0) << "| Left side " << *ileft << endl; + if (ileft->isNewLeft()) { + ileft->unsetNewLeft(); + continue; + } + if (isweep->getSpan() == ileft->getSpan()) { + cdebug_log(17,0) << "> Exact match" << endl; + isweep->setExactMatch(); + ileft ->setKeep(); + continue; + } + if (isweep->getSpan().contains( ileft->getSpan() )) { + cdebug_log(17,0) << "> Contained" << endl; + ileft->setKeep(); + continue; + } + if (ileft->getSpan().contains( isweep->getSpan() )) { + cdebug_log(17,0) << "> Full shrink" << endl; + if (not ileft->isSplinter()) toBox( *ileft ); + ileft->setKeep(); + _leftSides.push_back( SweepInterval( isweep->getVMax(), ileft->getVMax(), ileft->getXMin() ) ); + _leftSides.back().setSplinter(); + cdebug_log(17,0) << "+ Add remainder " << _leftSides.back() << endl; + ileft->updateSpan( isweep->getSpan() ); + ileft->unsetSplinter(); + isweep->setExactMatch(); + continue; + } + if (isweep->getSpan().intersect( ileft->getSpan() )) { + cdebug_log(17,0) << "> Intersect" << endl; + toBox( *ileft ); + ileft->updateSpan( isweep->getSpan() ); + ileft->unsetSplinter(); + if (not ileft->isPonctual()) ileft->setKeep(); + cdebug_log(17,0) << "> Shrinked span " << *ileft << endl; + continue; + } + } + + if (not isweep->isExactMatch()) { + _leftSides.push_back( SweepInterval( *isweep )); + _leftSides.back().setXMin( leftX ); + _leftSides.back().setKeep(); + cdebug_log(17,0) << "+ Added span " << _leftSides.back() << endl; + } + cdebug_tabw(17,-1); + } + + cdebug_log(17,0) << "Clean sweepline flags" << endl; + for ( auto isweep = _sweepLine.begin() ; isweep != _sweepLine.end() ; ++isweep ) { + isweep->clearUpdateFlags(); + } + _leftSides.sort(); + cdebug_log(17,0) << "Delete closed left sides & clean flags" << endl; + for ( auto ileft = _leftSides.begin() ; ileft != _leftSides.end() ; ) { + cdebug_log(17,0) << "| " << *ileft << endl; + auto ileftNext = ileft; + ileftNext++; + if (ileftNext != _leftSides.end()) { + if ( (ileft->getSpan().getVMin() == ileftNext->getSpan().getVMin()) + and (ileft->getSpan().getVMax() == ileftNext->getSpan().getVMax())) { + cdebug_log(17,0) << "> Remove duplicate " << *ileftNext << endl; + _leftSides.erase( ileftNext ); + continue; + } + } + if (not ileft->isKeep()) { + cdebug_log(17,0) << "> Remove/close " << *ileft << endl; + auto ileftNext = ileft; + ++ileftNext; + if (not ileft->isSplinter()) { + toBox( *ileft ); + } + _leftSides.erase( ileft ); + ileft = ileftNext; + continue; + } + ileft->clearUpdateFlags(); + ileft++; + } + cdebug_tabw(17,-1); + } + + + void SweepLineBig::process ( Interval v ) + { + cdebug_log(17,1) << "SweepLineBig::process(Interval&) " + << " [" << DbU::getValueString(v.getVMin()) + << " " << DbU::getValueString(v.getVMax()) << "]" << endl; + bool done = false; + for ( auto iintv = _sweepLine.begin() ; iintv != _sweepLine.end() ; ++iintv ) { + cdebug_log(17,0) << "> Sweepline element " << *iintv << endl; + // Extractor p. 9 (a). + if (v.getVMax() < iintv->getVMin()) { + cdebug_log(17,0) << "case (a): new left side" << endl; + _sweepLine.insert( iintv, SweepInterval(v,_currX) ); + done = true; + break; + } + // Extractor p. 9 (f). + if ( (v.getVMin() == iintv->getVMin()) + and (v.getVMax() == iintv->getVMax()) ) { + cdebug_log(17,0) << "case (f): closing right side" << endl; + _sweepLine.erase( iintv ); + done = true; + break; + } + // Extractor p. 9 (b). + if (v.getVMax() == iintv->getVMin()) { + cdebug_log(17,0) << "case (b): extend min" << endl; + iintv->merge( v.getVMin() ); + done = true; + break; + } + // Extractor p. 9 (g). + if (v.getVMax() == iintv->getVMax()) { + cdebug_log(17,0) << "case (g): carve" << endl; + iintv->inflate( 0, v.getVMin() - iintv->getVMax() ); + cdebug_log(17,0) << "| " << (*iintv) << endl; + done = true; + break; + } + // Extractor p. 9 (h). + if (v.getVMin() == iintv->getVMin()) { + cdebug_log(17,0) << "case (h): carve" << endl; + iintv->inflate(iintv->getVMin() - v.getVMax(), 0 ); + done = true; + break; + } + // Extractor p. 9 (c). + if ( (v.getVMin() > iintv->getVMin()) + and (v.getVMax() < iintv->getVMax()) ) { + cdebug_log(17,0) << "case (c): carve" << endl; + DbU::Unit wholeVMin = iintv->getVMin(); + iintv->inflate( iintv->getVMin() - v.getVMax(), 0 ); + cdebug_log(17,0) << "| " << (*iintv) << endl; + _sweepLine.insert( iintv, SweepInterval( wholeVMin, v.getVMin(), _currX ) ); + cdebug_log(17,0) << "| " << (*iintv) << endl; + done = true; + break; + } + // Extractor p. 9 (d,e). + if (v.getVMin() == iintv->getVMax()) { + cdebug_log(17,0) << "case (d,e): merge" << endl; + auto iintvNext = iintv; + ++iintvNext; + // Extractor p. 9 (d). + if (iintvNext == _sweepLine.end()) { + cdebug_log(17,0) << "case (d): end of vertical line" << endl; + iintv->merge( v.getVMax() ); + iintv->setXMin( _currX ); + } else { + // Extractor p. 9 (d). + if (v.getVMax() < iintvNext->getVMin()) { + cdebug_log(17,0) << "case (d): extend max" << endl; + iintv->merge( v.getVMax() ); + iintv->setXMin( _currX ); + } else { + // Extractor p. 9 (e). + cdebug_log(17,0) << "case (e): interval joining" << endl; + iintv->merge( iintvNext->getVMax() ); + iintv->setXMin( _currX ); + _sweepLine.erase( iintvNext ); + } + } + done = true; + break; + } + } + if (not done) { + _sweepLine.push_back( SweepInterval(v,_currX) ); + } + + cdebug_tabw(17,-1); + } + + + void SweepLineBig::process ( const pair< DbU::Unit, list >& intervals ) + { + cdebug_log(17,1) << "SweepLineBig::process() @"<< DbU::getValueString(intervals.first) + << " size=" << intervals.second.size() << endl; + _currX = intervals.first; + for ( const Interval& v : intervals.second ) process( v ); + updateLeftSide(); + cdebug_tabw(17,-1); + } + + + void SweepLineBig::asRectangles () + { + loadVEdges(); + for ( auto intervals : _vedges ) { + process( intervals ); + } + cdebug_log(17,0) << "SweepLineBig::asRectangles() size=" << _boxes.size() << endl; + for ( const Box& b : _boxes ) + cdebug_log(17,0) << "| " << b << endl; + } + } // Anonymous namespace. @@ -479,6 +913,20 @@ namespace Hurricane { } + bool Rectilinear::getAsBiggestRectangles ( std::vector& rectangles + , DbU::Unit xThreshold + , DbU::Unit yThreshold + ) const + { + //DebugSession::open( 17, 18 ); + rectangles.clear(); + if (not isRectilinear()) return false; + SweepLineBig( this, rectangles, xThreshold, yThreshold ).asRectangles(); + //DebugSession::close(); + return true; + } + + Box Rectilinear::getNearestHSide ( DbU::Unit y ) const { Box side; diff --git a/hurricane/src/hurricane/hurricane/Rectilinear.h b/hurricane/src/hurricane/hurricane/Rectilinear.h index 9a51ddb7b..74d41848d 100644 --- a/hurricane/src/hurricane/hurricane/Rectilinear.h +++ b/hurricane/src/hurricane/hurricane/Rectilinear.h @@ -59,6 +59,10 @@ namespace Hurricane { virtual const Layer* getLayer () const; inline Points getContour () const; bool getAsRectangles ( std::vector& ) const; + bool getAsBiggestRectangles + ( std::vector& + , DbU::Unit xThreshold=0 + , DbU::Unit yThreshold=0 ) const; inline const vector& getPoints () const; Box getNearestHSide ( DbU::Unit y ) const; // Mutators. diff --git a/hurricane/src/isobar/PyRectilinear.cpp b/hurricane/src/isobar/PyRectilinear.cpp index ca0e371b4..04f7e2d37 100644 --- a/hurricane/src/isobar/PyRectilinear.cpp +++ b/hurricane/src/isobar/PyRectilinear.cpp @@ -219,6 +219,44 @@ extern "C" { } + static PyObject* PyRectilinear_getAsBiggestRectangles ( PyRectilinear *self, PyObject* args ) + { + cdebug_log(20,0) << "Rectilinear.getAsBiggestRectangles()" << endl; + + HTRY + METHOD_HEAD( "Rectilinear.getAsBiggestRectangles()" ) + + PyObject* pyList = NULL; + PyObject* pyHT = NULL; + PyObject* pyVT = NULL; + if (not PyArg_ParseTuple( args, "O|OO:Rectilinear.getAsBiggestRectangles", &pyList, &pyHT, &pyVT )) { + PyErr_SetString( ConstructorError, "Rectilinear.getAsBiggestRectangles(): Must have exactly one parameter." ); + return NULL; + } + if (not PyList_Check(pyList)) { + PyErr_SetString( ConstructorError, "Rectilinear.getAsBiggestRectangles(): Argument must be a list." ); + return NULL; + } + + PyList_SetSlice( pyList, 0, PyList_Size(pyList), NULL ); + vector boxes; + if (pyHT and pyVT) + rectilinear->getAsBiggestRectangles( boxes, PyAny_AsLong(pyHT), PyAny_AsLong(pyVT) ); + else + rectilinear->getAsBiggestRectangles( boxes ); + for ( size_t i=0 ; i_object = new Box ( boxes[i] ); + PyList_Append( pyList, (PyObject*)pyBox ); + } + HCATCH + + Py_RETURN_NONE; + } + + // --------------------------------------------------------------- // PyRectilinear Attribute Method table. @@ -231,7 +269,10 @@ extern "C" { , { "getBoundingBox" , (PyCFunction)PyRectilinear_getBoundingBox , METH_NOARGS , "Return the Rectilinear Bounding Box." } , { "setPoints" , (PyCFunction)PyRectilinear_setPoints , METH_VARARGS, "Sets the Rectilinear Bounding Box." } , { "translate" , (PyCFunction)PyRectilinear_translate , METH_VARARGS, "Translates the Rectilinear of dx and dy." } - , { "getAsRectangles", (PyCFunction)PyRectilinear_getAsRectangles, METH_VARARGS, "Return the rectangle coverage." } + , { "getAsRectangles", (PyCFunction)PyRectilinear_getAsRectangles, METH_VARARGS, "Return the rectangle vertical coverage." } + , { "getAsBiggestRectangles" + , (PyCFunction)PyRectilinear_getAsBiggestRectangles + , METH_VARARGS, "Return the biggest rectangle coverage." } , { "destroy" , (PyCFunction)PyRectilinear_destroy , METH_NOARGS , "Destroy associated hurricane object, the python object remains." } , {NULL, NULL, 0, NULL} /* sentinel */ diff --git a/unittests/python/dodo.py b/unittests/python/dodo.py new file mode 100644 index 000000000..d27a72fb9 --- /dev/null +++ b/unittests/python/dodo.py @@ -0,0 +1,34 @@ + +import socket +from pathlib import Path + +#useTechno = 'MOSIS' +#useTechno = 'AMS350' +useTechno = 'CMOS' + +checkToolkit = Path.home() / 'coriolis-2.x' / 'src' / 'alliance-check-toolkit' +if useTechno == 'AMS350': + hostname = socket.gethostname() + if hostname.startswith('lepka'): + ndaTop = Path( '/dsk/l1/jpc/crypted/soc/techno' ) + if not ndaTop.is_dir(): + print( '[ERROR] You forgot to mount the NDA encrypted directory, stupid!' ) + else: + ndaTop = '/users/soft/techno/techno' + from coriolis.designflow.technos import setupAMS350 + setupAMS350( checkToolkit=checkToolkit, ndaTop=ndaTop ) +elif useTechno == 'MOSIS': + from coriolis.designflow.technos import setupMOSIS + setupMOSIS( checkToolkit=checkToolkit ) +elif useTechno == 'CMOS': + from coriolis.designflow.technos import setupCMOS + setupCMOS( checkToolkit=checkToolkit ) + +DOIT_CONFIG = { 'verbosity' : 2 } + +from coriolis.designflow.pnr import PnR +from coriolis.designflow.clean import Clean +PnR.textMode = True + +ruleCgt = PnR .mkRule( 'cgt' ) +ruleClean = Clean.mkRule() diff --git a/unittests/python/test_rectilinear.py b/unittests/python/test_rectilinear.py index 447dce17b..e1103e1c9 100644 --- a/unittests/python/test_rectilinear.py +++ b/unittests/python/test_rectilinear.py @@ -17,7 +17,7 @@ def testRectilinear ( editor ): with UpdateSession(): cell = AllianceFramework.get().createCell( 'Rectilinear' ) cell.setTerminalNetlist( True ) - cell.setAbutmentBox( Box( l(-5.0), l(-5.0), l(400.0), l(200.0) ) ) + cell.setAbutmentBox( Box( l(-5.0), l(-5.0), l(524.0), l(200.0) ) ) #cell.setAbutmentBox( Box( l(-5.0), l(-5.0), l(21.0), l(35.0) ) ) if editor: editor.setCell( cell ) @@ -155,6 +155,12 @@ def testRectilinear ( editor ): for box in boxes: box.translate( l(180.0), l(0.0) ) Pad.create( net, metal3, box ) + boxes = [] + r.getAsBiggestRectangles( boxes, l(15.0), l(15.0) ) + #print( 'boxes={}'.format( boxes )) + for box in boxes: + box.translate( l(360.0), l(0.0) ) + Pad.create( net, metal4, box ) Gds.save( cell ) From 4146bae2f0a8ed825c8e53bb7e1349f28a3bd1b0 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 29 Nov 2023 21:50:25 +0100 Subject: [PATCH 09/51] In technos.setupCMOS(), find liberty from ALLIANCE_TOP instead of CELLS_TOP. --- cumulus/src/designflow/technos.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cumulus/src/designflow/technos.py b/cumulus/src/designflow/technos.py index 396d71838..3976cfe3f 100644 --- a/cumulus/src/designflow/technos.py +++ b/cumulus/src/designflow/technos.py @@ -73,7 +73,7 @@ def setupCMOS ( checkToolkit=None ): env.addSYSTEM_LIBRARY( library=(Where.checkToolkit / 'cells' / 'niolib').as_posix() , mode =CRL.Environment.Append ) - Yosys.setLiberty( Where.cellsTop / 'sxlib' / 'sxlib.lib' ) + Yosys.setLiberty( Where.allianceTop / 'cells' / 'sxlib' / 'sxlib.lib' ) ShellEnv.RDS_TECHNO_NAME = (Where.allianceTop / 'etc' / 'cmos.rds').as_posix() path = None From e8def68339e35becc4fa69f1fc349c81a25508a0 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Mon, 4 Dec 2023 12:33:04 +0100 Subject: [PATCH 10/51] Slightly clrearer display of C++ exception catched through Python. --- hurricane/src/isobar/hurricane/isobar/PyHurricane.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hurricane/src/isobar/hurricane/isobar/PyHurricane.h b/hurricane/src/isobar/hurricane/isobar/PyHurricane.h index 69ae20c8b..7aeccbc56 100644 --- a/hurricane/src/isobar/hurricane/isobar/PyHurricane.h +++ b/hurricane/src/isobar/hurricane/isobar/PyHurricane.h @@ -1653,19 +1653,19 @@ extern "C" { # define HCATCH \ } \ catch ( const Warning& w ) { \ - std::string message = getString(w); \ + std::string message = "\n" + getString(w); \ PyErr_Warn ( HurricaneWarning, const_cast(message.c_str()) ); \ std::cerr << message << std::endl; \ } \ catch ( const Error& e ) { \ - std::string message = getString(e); \ + std::string message = "\n" + getString(e); \ if (not e.where().empty()) message += "\n" + e.where(); \ PyErr_SetString ( HurricaneError, message.c_str() ); \ std::cerr << message << std::endl; \ return NULL; \ } \ catch ( const Bug& e ) { \ - std::string message = getString(e); \ + std::string message = "\n" + getString(e); \ PyErr_SetString ( HurricaneError, message.c_str() ); \ std::cerr << message << std::endl; \ return NULL; \ @@ -1677,7 +1677,7 @@ extern "C" { return NULL; \ } \ catch ( const std::exception& e ) { \ - std::string message = std::string(e.what()); \ + std::string message = "\n" + std::string(e.what()); \ PyErr_SetString ( HurricaneError, message.c_str() ); \ std::cerr << message << std::endl; \ return NULL; \ From 33e5861e68d2bb17efab94be9258dee24578760a Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Mon, 4 Dec 2023 12:34:35 +0100 Subject: [PATCH 11/51] Systematically throw an error in case of faulty contact topology. --- anabatic/src/AutoContact.cpp | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/anabatic/src/AutoContact.cpp b/anabatic/src/AutoContact.cpp index c81eaa461..dbc7a99b8 100644 --- a/anabatic/src/AutoContact.cpp +++ b/anabatic/src/AutoContact.cpp @@ -392,38 +392,39 @@ namespace Anabatic { void AutoContact::showTopologyError ( const std::string& message, Flags flags ) { - Component* anchor = NULL; - Horizontal** horizontals = new Horizontal* [10]; - Vertical** verticals = new Vertical* [10]; - - if (not (flags & Flags::CParanoid)) cparanoid.setStreamMask( mstream::PassThrough ); + Component* anchor = NULL; + Horizontal** horizontals = new Horizontal* [10]; + Vertical** verticals = new Vertical* [10]; + ostringstream strError; + strError << "In topology of " << this << "\n"; _getTopology ( base(), anchor, horizontals, verticals, 10 ); - cparanoid << Error("In topology of %s",getString(this).c_str()) << endl; - if (anchor) cparanoid << " A: " << anchor << endl; + if (anchor) strError << " A: " << anchor << "\n"; for ( size_t i=0 ; (i<10) and (horizontals[i] != NULL); ++i ) { AutoSegment* autoSegment = Session::lookup ( horizontals[i] ); if (autoSegment != NULL) - cparanoid << " " << (autoSegment->isGlobal()?'G':'L') << ": " << autoSegment << endl; + strError << " " << (autoSegment->isGlobal()?'G':'L') << ": " << autoSegment << "\n"; else - cparanoid << " ?: " << horizontals[i] << endl; + strError << " ?: " << horizontals[i] << "\n"; } for ( size_t i=0 ; (i<10) and (verticals[i] != NULL); ++i ) { AutoSegment* autoSegment = Session::lookup ( verticals[i] ); if (autoSegment != NULL) - cparanoid << " " << (autoSegment->isGlobal()?'G':'L') << ": " << autoSegment << endl; + strError << " " << (autoSegment->isGlobal()?'G':'L') << ": " << autoSegment << "\n"; else - cparanoid << " ?: " << verticals[i] << endl; + strError << " ?: " << verticals[i] << "\n"; } - cparanoid << " " << message << endl; - if (not (flags & Flags::CParanoid)) cparanoid.unsetStreamMask( mstream::PassThrough ); - + strError << " " << message << "\n"; + Error error ( strError.str().c_str() ); + delete [] horizontals; delete [] verticals; + + throw error; } From 55678be817299c7bd4529b8a4103fdb6a145cd26 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 5 Dec 2023 22:00:52 +0100 Subject: [PATCH 12/51] Reorganization of the size detection of RoutingPad. --- anabatic/src/Configuration.cpp | 79 +++++++++++++++-- anabatic/src/Constants.cpp | 37 ++++---- anabatic/src/Dijkstra.cpp | 6 +- anabatic/src/NetBuilder.cpp | 84 ++++--------------- anabatic/src/NetBuilderHV.cpp | 37 ++++---- anabatic/src/NetBuilderHybridVH.cpp | 4 +- anabatic/src/NetBuilderM2.cpp | 8 +- anabatic/src/NetBuilderVH.cpp | 6 +- anabatic/src/PyStyleFlags.cpp | 16 ++-- anabatic/src/anabatic/Configuration.h | 6 +- anabatic/src/anabatic/Constants.h | 13 +-- anabatic/src/anabatic/NetBuilder.h | 26 +++--- anabatic/src/anabatic/NetBuilderHV.h | 4 +- anabatic/src/anabatic/NetBuilderHybridVH.h | 8 +- anabatic/src/anabatic/NetBuilderM2.h | 4 +- anabatic/src/anabatic/NetBuilderVH.h | 4 +- anabatic/src/anabatic/Session.h | 2 + hurricane/src/hurricane/RoutingPad.cpp | 14 ++++ .../src/hurricane/hurricane/RoutingPad.h | 21 +++++ 19 files changed, 223 insertions(+), 156 deletions(-) diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index 81d10971a..caf94f090 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.cpp @@ -231,6 +231,10 @@ namespace Anabatic { bool Configuration::isHybrid () const { return _routingStyle & StyleFlags::Hybrid; } + + + bool Configuration::isM1Offgrid () const + { return _routingStyle & StyleFlags::M1Offgrid; } bool Configuration::isHV () const @@ -509,11 +513,10 @@ namespace Anabatic { Component* candidate = dynamic_cast( component ); if (not candidate - or (candidate->getLayer()->getMask() != metal1->getMask()) ) - candidate = dynamic_cast(component); - if (not candidate) + or (candidate->getLayer()->getMask() != metal1->getMask()) ) { candidate = dynamic_cast( component ); - if (not candidate) continue; + if (not candidate) continue; + } Box bb = transformation.getBox( candidate->getBoundingBox() ); DbU::Unit trackPos = 0; @@ -559,17 +562,81 @@ namespace Anabatic { } } + bool rvalue = false; if (bestComponent) { rp->setExternalComponent( bestComponent ); cdebug_log(112,0) << "Using best candidate:" << bestComponent << endl; cdebug_tabw(112,-1); - return true; + rvalue = true; } + checkRoutingPadSize( rp ); cdebug_tabw(112,-1); - return false; + return rvalue; #endif } + + + void Configuration::getPositions ( RoutingPad* rp, Point& source, Point& target ) const + { + source = rp->getSourcePosition(); + target = rp->getTargetPosition(); + + if (source == target) return; + if (source.getX() > target.getX()) std::swap( source, target ); + if (source.getY() > target.getY()) std::swap( source, target ); + + if (not getRoutingGauge()->isSymbolic()) { + size_t rpDepth = getLayerDepth( rp->getLayer() ); + Flags direction = getDirection ( rpDepth ); + DbU::Unit wwidth = getWireWidth ( rpDepth ) / 2; + cdebug_log(145,0) << "Not a symbolic gauge, shrink positions of " << DbU::getValueString(wwidth) << endl; + if (rpDepth == 0) return; + if (direction.contains(Flags::Horizontal)) { + cdebug_log(145,0) << "H shrink" << endl; + source.translate( wwidth, 0 ); + target.translate( -wwidth, 0 ); + } else { + cdebug_log(145,0) << "V shrink" << endl; + source.translate( 0, wwidth ); + target.translate( 0, -wwidth ); + } + } else { + cdebug_log(145,0) << "Symbolic gauge, no shrink" << endl; + } + } + + + void Configuration::checkRoutingPadSize ( RoutingPad* rp ) const + { + Point source; + Point target; + + size_t rpDepth = getLayerDepth( rp->getLayer() ); + if (rpDepth == 0) ++rpDepth; + else return; + + getPositions( rp, source, target ); + + DbU::Unit width = abs( target.getX() - source.getX() ); + DbU::Unit height = abs( target.getY() - source.getY() ); + + uint64_t flags = 0; + flags |= (width < 3*getPitch(rpDepth)) ? RoutingPad::HSmall : 0; + flags |= (height < 3*getPitch(rpDepth)) ? RoutingPad::VSmall : 0; + flags |= ((width == 0) && (height == 0)) ? RoutingPad::Punctual : 0; + //if ((flags & RoutingPad::HSmall) and (flags & RoutingPad::VSmall)) + // flags |= RoutingPad::Punctual; + + rp->unsetFlags( RoutingPad::SizeFlags ); + rp->setFlags ( flags ); + cdebug_log(145,0) << "::checkRoutingPadSize(): pitch[" << rpDepth << "]:" + << DbU::getValueString(getPitch(rpDepth)) << " " + << ((flags & RoutingPad::HSmall ) ? "HSmall " : " ") + << ((flags & RoutingPad::VSmall ) ? "VSmall " : " ") + << ((flags & RoutingPad::Punctual) ? "Punctual " : " ") + << endl; + } void Configuration::print ( Cell* cell ) const diff --git a/anabatic/src/Constants.cpp b/anabatic/src/Constants.cpp index dc4c2beeb..267bdcd9c 100644 --- a/anabatic/src/Constants.cpp +++ b/anabatic/src/Constants.cpp @@ -222,12 +222,13 @@ 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); + 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); + const BaseFlags StyleFlags::M1Offgrid = (1L << 5); StyleFlags::~StyleFlags () @@ -236,12 +237,13 @@ namespace Anabatic { 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; + 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; + if (textFlag == "M1Offgrid") return M1Offgrid; std::cerr << Error( "StyleFlags::toFlag(): Unknown flag value \"%s\"", textFlag.c_str() ) << std::endl; return NoStyle; } @@ -265,11 +267,12 @@ namespace Anabatic { { 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"; } + 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"; } + if (_flags & (uint64_t)M1Offgrid) { s << (s.tellp() ? "|" : "") << "M1Offgrid"; } s << " (0x" << hex << _flags << ")"; return s.str(); } diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp index fda73355a..796178622 100644 --- a/anabatic/src/Dijkstra.cpp +++ b/anabatic/src/Dijkstra.cpp @@ -1563,8 +1563,10 @@ namespace Anabatic { uint32_t driverCount = 0; for ( auto rp : rps ) { - if (not _anabatic->getConfiguration()->selectRpComponent(rp)) - cerr << Warning( "Dijktra::load(): %s has no components on grid.", getString(rp).c_str() ) << endl; + if (not _anabatic->getConfiguration()->selectRpComponent(rp)) { + if (not _anabatic->getConfiguration()->isM1Offgrid()) + cerr << Warning( "Dijktra::load(): %s has no components on grid.", getString(rp).c_str() ) << endl; + } cdebug_log(112,0) << "@ rp: " << rp << ", getCenter(): " << rp->getBoundingBox().getCenter() << endl; Point center = rp->getBoundingBox().getCenter(); diff --git a/anabatic/src/NetBuilder.cpp b/anabatic/src/NetBuilder.cpp index b9b858c25..3bcff2158 100644 --- a/anabatic/src/NetBuilder.cpp +++ b/anabatic/src/NetBuilder.cpp @@ -228,73 +228,19 @@ namespace Anabatic { // Class : "NetBuilder". - void NetBuilder::getPositions ( Component* anchor, Point& source, Point& target ) + uint64_t NetBuilder::checkRoutingPadSize ( RoutingPad* rp ) { - Segment* segment = dynamic_cast( anchor ); - if (segment) { - source = segment->getSourcePosition(); - target = segment->getTargetPosition(); - } else { - RoutingPad* rp = dynamic_cast( anchor ); - if (rp) { - source = rp->getSourcePosition(); - target = rp->getTargetPosition(); - } else { - source = anchor->getPosition(); - target = anchor->getPosition(); - return; - } - } - - if (source == target) return; - if (source.getX() > target.getX()) swap( source, target ); - if (source.getY() > target.getY()) swap( source, target ); - - if (not Session::getRoutingGauge()->isSymbolic()) { - size_t rpDepth = Session::getLayerDepth( anchor->getLayer() ); - Flags direction = Session::getDirection ( rpDepth ); - DbU::Unit wwidth = Session::getWireWidth (rpDepth) / 2; - cdebug_log(145,0) << "Not a symbolic gauge, shrink positions of " << DbU::getValueString(wwidth) << endl; - if (rpDepth == 0) return; - if (direction.contains(Flags::Horizontal)) { - cdebug_log(145,0) << "H shrink" << endl; - source.translate( wwidth, 0 ); - target.translate( -wwidth, 0 ); - } else { - cdebug_log(145,0) << "V shrink" << endl; - source.translate( 0, wwidth ); - target.translate( 0, -wwidth ); - } - } else { - cdebug_log(145,0) << "Symbolic gauge, no shrink" << endl; - } - } - - - uint64_t NetBuilder::checkRoutingPadSize ( Component* anchor ) - { - Point source; - Point target; - - size_t anchorDepth = Session::getLayerDepth( anchor->getLayer() ); - if (anchorDepth == 0) ++anchorDepth; - - NetBuilder::getPositions( anchor, source, target ); - - DbU::Unit width = abs( target.getX() - source.getX() ); - DbU::Unit height = abs( target.getY() - source.getY() ); - - uint64_t flags = 0; - flags |= (width < 3*Session::getPitch(anchorDepth)) ? NetBuilder::HSmall : 0; - flags |= (height < 3*Session::getPitch(anchorDepth)) ? NetBuilder::VSmall : 0; - flags |= ((width == 0) && (height == 0)) ? NetBuilder::Punctual : 0; - - cdebug_log(145,0) << "::checkRoutingPadSize(): pitch[" << anchorDepth << "]:" - << DbU::getValueString(Session::getPitch(anchorDepth)) << " " - << ((flags & NetBuilder::HSmall) ? "HSmall " : " ") - << ((flags & NetBuilder::VSmall) ? "VSmall " : " ") - << endl; - + uint32_t rpFlags = rp->getFlags(); + uint32_t flags = 0; + flags |= (rpFlags & RoutingPad::VSmall ) ? VSmall : 0; + flags |= (rpFlags & RoutingPad::HSmall ) ? HSmall : 0; + flags |= (rpFlags & RoutingPad::Punctual ) ? Punctual : 0; + flags |= (rpFlags & RoutingPad::M1Offgrid) ? M1Offgrid : 0; + cdebug_log(145,0) << "::checkRoutingPadSize(): " + << ((flags & NetBuilder::HSmall ) ? "HSmall " : " ") + << ((flags & NetBuilder::VSmall ) ? "VSmall " : " ") + << ((flags & NetBuilder::Punctual) ? "Punctual " : " ") + << rp << endl; return flags; } @@ -1045,7 +991,7 @@ namespace Anabatic { } - void NetBuilder::doRp_StairCaseH ( GCell* gcell, Component* rp1, Component* rp2 ) + void NetBuilder::doRp_StairCaseH ( GCell* gcell, RoutingPad* rp1, RoutingPad* rp2 ) { cdebug_log(145,0) << "doRp_StairCaseH()" << endl; @@ -1079,7 +1025,7 @@ namespace Anabatic { } - void NetBuilder::doRp_StairCaseV ( GCell* gcell, Component* rp1, Component* rp2 ) + void NetBuilder::doRp_StairCaseV ( GCell* gcell, RoutingPad* rp1, RoutingPad* rp2 ) { cdebug_log(145,0) << "doRp_StairCaseV()" << endl; @@ -1302,7 +1248,7 @@ namespace Anabatic { cdebug_log(145,1) << "NetBuilder::singleGCell() " << net << endl; vector rpM1s; - Component* rpM2 = NULL; + RoutingPad* rpM2 = NULL; for ( RoutingPad* rp : net->getRoutingPads() ) { if ( Session::getRoutingGauge()->getLayerDepth(rp->getLayer()) diff --git a/anabatic/src/NetBuilderHV.cpp b/anabatic/src/NetBuilderHV.cpp index b81051310..d5fe342ca 100644 --- a/anabatic/src/NetBuilderHV.cpp +++ b/anabatic/src/NetBuilderHV.cpp @@ -72,7 +72,7 @@ namespace Anabatic { void NetBuilderHV::doRp_AutoContacts ( GCell* gcell - , Component* rp + , RoutingPad* rp , AutoContact*& source , AutoContact*& target , uint64_t flags @@ -97,7 +97,7 @@ namespace Anabatic { Flags direction = Session::getDirection ( rpDepth ); DbU::Unit viaSide = Session::getViaWidth ( rpDepth ); - getPositions( rp, sourcePosition, targetPosition ); + Session::getPositions( rp, sourcePosition, targetPosition ); GCell* sourceGCell = Session::getAnabatic()->getGCellUnder( sourcePosition ); GCell* targetGCell = Session::getAnabatic()->getGCellUnder( targetPosition ); @@ -242,7 +242,7 @@ namespace Anabatic { } - AutoContact* NetBuilderHV::doRp_Access ( GCell* gcell, Component* rp, uint64_t flags ) + AutoContact* NetBuilderHV::doRp_Access ( GCell* gcell, RoutingPad* rp, uint64_t flags ) { cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl; @@ -266,6 +266,7 @@ namespace Anabatic { cdebug_log(145,0) << "METAL3 override." << endl; contactLayer = Session::getRoutingLayer( 2 ); wireDepth = 2; + flags &= ~(Punctual|VSmall); } if (flags & HAccess) { @@ -471,7 +472,7 @@ namespace Anabatic { AutoSegment::create( leftContact, rightContact, Flags::Horizontal ); } - Component* globalRp = NULL; + RoutingPad* globalRp = NULL; if (east()) globalRp = getRoutingPads()[getRoutingPads().size()-1]; else if (west()) globalRp = getRoutingPads()[0]; else { @@ -1334,7 +1335,8 @@ namespace Anabatic { uint64_t flags = checkRoutingPadSize( getRoutingPads()[0] ); if (flags & VSmall) { - doRp_AutoContacts( getGCell(), getRoutingPads()[0], contact1, contact2, NoFlags ); + doRp_AutoContacts( getGCell(), getRoutingPads()[0], contact1, contact2, NoFlags ); + //contact1 = doRp_Access( getGCell(), getRoutingPads()[0], NoFlags ); contact2 = AutoContactHTee::create( getGCell(), getNet(), viaLayer1 ); AutoSegment::create( contact1, contact2, Flags::Vertical ); @@ -1366,8 +1368,11 @@ namespace Anabatic { setSouthWestContact( (east()) ? contact2 : contact3 ); setNorthEastContact( (east()) ? contact3 : contact2 ); } else { - AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], NoFlags ); - AutoContact* contact2 = AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ); + AutoContact* contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess ); + AutoContact* contact2 = AutoContactTurn::create( getGCell(), getNet(), viaLayer1 ); + AutoSegment::create( contact1, contact2, Flags::Horizontal ); + contact1 = contact2; + contact2 = AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ); AutoSegment::create( contact1, contact2, Flags::Vertical ); AutoContact* contact3 = AutoContactVTee::create( getGCell(), getNet(), viaLayer1 ); AutoSegment::create( contact2, contact3, Flags::Vertical ); @@ -1397,8 +1402,8 @@ namespace Anabatic { { cdebug_log(145,1) << getTypeName() << "::_do_xG_1M1_1M2() [Managed Configuration]" << endl; - Component* rpL1; - Component* rpL2; + RoutingPad* rpL1; + RoutingPad* rpL2; if (getRoutingPads()[0]->getLayer() == Session::getBuildRoutingLayer(0)) { rpL1 = getRoutingPads()[0]; rpL2 = getRoutingPads()[1]; @@ -1471,7 +1476,7 @@ namespace Anabatic { cdebug_log(145,0) << "east: " << east() << endl; cdebug_log(145,0) << "west: " << west() << endl; - Component* rpM3 = NULL; + RoutingPad* rpM3 = NULL; if (getRoutingPads()[0]->getLayer() == Session::getBuildRoutingLayer(2)) rpM3 = getRoutingPads()[0]; @@ -1535,7 +1540,7 @@ namespace Anabatic { } // All RoutingPad are M1. - Component* southWestRp = getRoutingPads()[0]; + RoutingPad* southWestRp = getRoutingPads()[0]; cdebug_log(145,0) << "| Initial S-W Global RP: " << southWestRp << endl; // for ( size_t i=1 ; igetBoundingBox().getHeight() >= 4*Session::getPitch(1)) break; @@ -1557,7 +1562,7 @@ namespace Anabatic { AutoSegment::create( rpContact, getSouthWestContact(), Flags::Horizontal ); } - Component* northEastRp = getRoutingPads()[getRoutingPads().size()-1]; + RoutingPad* northEastRp = getRoutingPads()[getRoutingPads().size()-1]; cdebug_log(145,0) << "| Initial N-E Global RP: " << northEastRp << endl; if (getRoutingPads().size() > 1) { @@ -1593,7 +1598,7 @@ namespace Anabatic { { cdebug_log(145,1) << getTypeName() << "::_do_4G_1M2() [Managed Configuration]" << endl; - Component* rpL2 = getRoutingPads()[0]; + RoutingPad* rpL2 = getRoutingPads()[0]; cdebug_log(145,0) << "rpL2 := " << rpL2 << endl; AutoContact* rpL2ContactSource = NULL; @@ -1620,7 +1625,7 @@ namespace Anabatic { << (int)getConnexity().fields.globals << "G_" << (int)getConnexity().fields.M2 << "M2() [Managed Configuration - x]" << endl; - Component* biggestRp = getRoutingPads()[0]; + RoutingPad* biggestRp = getRoutingPads()[0]; for ( size_t i=1 ; igetBoundingBox().getWidth() > biggestRp->getBoundingBox().getWidth()) @@ -1768,7 +1773,7 @@ namespace Anabatic { } AutoContact* unusedContact = NULL; - Component* rp = getRoutingPads()[0]; + RoutingPad* rp = getRoutingPads()[0]; if (west() and not south()) { setSouthWestContact( doRp_Access( getGCell(), rp, HAccess ) ); @@ -1964,7 +1969,7 @@ namespace Anabatic { cdebug_log(145,1) << "NetBuilderHV::singleGCell() " << net << endl; vector rpM1s; - Component* rpM2 = NULL; + RoutingPad* rpM2 = NULL; RoutingPad* rpPin = NULL; for ( RoutingPad* rp : net->getRoutingPads() ) { diff --git a/anabatic/src/NetBuilderHybridVH.cpp b/anabatic/src/NetBuilderHybridVH.cpp index 5b7b85b46..fff63f2f8 100644 --- a/anabatic/src/NetBuilderHybridVH.cpp +++ b/anabatic/src/NetBuilderHybridVH.cpp @@ -70,7 +70,7 @@ namespace Anabatic { void NetBuilderHybridVH::doRp_AutoContacts ( GCell* gcell - , Component* rp + , RoutingPad* rp , AutoContact*& source , AutoContact*& target , uint64_t flags @@ -80,7 +80,7 @@ namespace Anabatic { } - AutoContact* NetBuilderHybridVH::doRp_Access ( GCell* gcell, Component* rp, uint64_t flags ) + AutoContact* NetBuilderHybridVH::doRp_Access ( GCell* gcell, RoutingPad* rp, uint64_t flags ) { cdebug_log(145,1) << getTypeName() << "::doRp_Access()" << endl; cdebug_log(145,0) << rp << endl; diff --git a/anabatic/src/NetBuilderM2.cpp b/anabatic/src/NetBuilderM2.cpp index c3de1875d..e4cb73549 100644 --- a/anabatic/src/NetBuilderM2.cpp +++ b/anabatic/src/NetBuilderM2.cpp @@ -67,7 +67,7 @@ namespace Anabatic { void NetBuilderM2::doRp_AutoContacts ( GCell* gcell - , Component* rp + , RoutingPad* rp , AutoContact*& source , AutoContact*& target , uint64_t flags @@ -85,7 +85,7 @@ namespace Anabatic { Flags direction = Session::getDirection ( rpDepth ); DbU::Unit viaSide = Session::getViaWidth ( rpDepth ); - getPositions( rp, sourcePosition, targetPosition ); + Session::getPositions( rp, sourcePosition, targetPosition ); if (sourcePosition.getX() > targetPosition.getX()) swap( sourcePosition, targetPosition ); if (sourcePosition.getY() > targetPosition.getY()) swap( sourcePosition, targetPosition ); @@ -156,7 +156,7 @@ namespace Anabatic { } - AutoContact* NetBuilderM2::doRp_Access ( GCell* gcell, Component* rp, uint64_t flags ) + AutoContact* NetBuilderM2::doRp_Access ( GCell* gcell, RoutingPad* rp, uint64_t flags ) { cdebug_log(145,1) << getTypeName() << "::doRp_Access()" << endl; cdebug_log(145,0) << rp << endl; @@ -168,7 +168,7 @@ namespace Anabatic { DbU::Unit viaSide = Session::getDContactWidth(); DbU::Unit ypitch = Session::getDVerticalPitch(); - getPositions( rp, sourcePosition, targetPosition ); + Session::getPositions( rp, sourcePosition, targetPosition ); if (sourcePosition.getX() > targetPosition.getX()) swap( sourcePosition, targetPosition ); if (sourcePosition.getY() > targetPosition.getY()) swap( sourcePosition, targetPosition ); diff --git a/anabatic/src/NetBuilderVH.cpp b/anabatic/src/NetBuilderVH.cpp index c92063465..a0ddf4f81 100644 --- a/anabatic/src/NetBuilderVH.cpp +++ b/anabatic/src/NetBuilderVH.cpp @@ -72,7 +72,7 @@ namespace Anabatic { void NetBuilderVH::doRp_AutoContacts ( GCell* gcell - , Component* rp + , RoutingPad* rp , AutoContact*& source , AutoContact*& target , uint64_t flags @@ -90,7 +90,7 @@ namespace Anabatic { Flags direction = Session::getDirection ( rpDepth ); DbU::Unit viaSide = Session::getViaWidth ( rpDepth ); - getPositions( rp, sourcePosition, targetPosition ); + Session::getPositions( rp, sourcePosition, targetPosition ); if (sourcePosition.getX() > targetPosition.getX()) swap( sourcePosition, targetPosition ); if (sourcePosition.getY() > targetPosition.getY()) swap( sourcePosition, targetPosition ); @@ -178,7 +178,7 @@ namespace Anabatic { } - AutoContact* NetBuilderVH::doRp_Access ( GCell* gcell, Component* rp, uint64_t flags ) + AutoContact* NetBuilderVH::doRp_Access ( GCell* gcell, RoutingPad* rp, uint64_t flags ) { cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl; diff --git a/anabatic/src/PyStyleFlags.cpp b/anabatic/src/PyStyleFlags.cpp index 1a911ccc8..73105d252 100644 --- a/anabatic/src/PyStyleFlags.cpp +++ b/anabatic/src/PyStyleFlags.cpp @@ -86,12 +86,13 @@ extern "C" { 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" ); + 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" ); + LoadObjectConstant( PyTypeStyleFlags.tp_dict, (uint64_t)StyleFlags::M1Offgrid, "M1Offgrid" ); } @@ -111,7 +112,8 @@ extern "C" { or (value == (uint64_t)StyleFlags::VH) or (value == (uint64_t)StyleFlags::OTH) or (value == (uint64_t)StyleFlags::Channel) - or (value == (uint64_t)StyleFlags::Hybrid)) + or (value == (uint64_t)StyleFlags::Hybrid) + or (value == (uint64_t)StyleFlags::M1Offgrid)) return value; return StyleFlags::NoStyle; } diff --git a/anabatic/src/anabatic/Configuration.h b/anabatic/src/anabatic/Configuration.h index 33e278d6e..d0e16cc6e 100644 --- a/anabatic/src/anabatic/Configuration.h +++ b/anabatic/src/anabatic/Configuration.h @@ -42,6 +42,7 @@ namespace Anabatic { using Hurricane::Name; using Hurricane::Layer; using Hurricane::DbU; + using Hurricane::Point; using Hurricane::RoutingPad; using Hurricane::Cell; using CRL::CellGauge; @@ -67,6 +68,7 @@ namespace Anabatic { bool isGContact ( const Layer* ) const; bool isTwoMetals () const; bool isHybrid () const; + bool isM1Offgrid () const; bool isHV () const; bool isVH () const; inline std::string getNetBuilderStyle () const; @@ -104,7 +106,7 @@ namespace Anabatic { Layer* getContactLayer ( size_t depth ) const; DbU::Unit getSliceHeight () const; DbU::Unit getSliceStep () const; - DbU::Unit getPitch ( size_t depth, Flags flags ) const; + DbU::Unit getPitch ( size_t depth, Flags flags=Flags::NoFlags ) const; DbU::Unit getOffset ( size_t depth ) const; DbU::Unit getWireWidth ( size_t depth ) const; DbU::Unit getPWireWidth ( size_t depth ) const; @@ -134,6 +136,8 @@ namespace Anabatic { float getEdgeHScaling () const; int getGlobalIterations () const; DbU::Unit isOnRoutingGrid ( RoutingPad* ) const; + void getPositions ( RoutingPad* , Point& source, Point& target ) const; + void checkRoutingPadSize ( RoutingPad* ) const; bool selectRpComponent ( RoutingPad* ) const; inline void setRoutingStyle ( StyleFlags ); inline void resetRoutingStyle ( StyleFlags ); diff --git a/anabatic/src/anabatic/Constants.h b/anabatic/src/anabatic/Constants.h index 92e975644..462654a65 100644 --- a/anabatic/src/anabatic/Constants.h +++ b/anabatic/src/anabatic/Constants.h @@ -130,12 +130,13 @@ namespace Anabatic { 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); + 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); + static const BaseFlags M1Offgrid; // = (1 << 5); public: inline StyleFlags ( std::string ); inline StyleFlags ( uint64_t flags = NoStyle ); diff --git a/anabatic/src/anabatic/NetBuilder.h b/anabatic/src/anabatic/NetBuilder.h index 9d08f33fd..5b4d09b9c 100644 --- a/anabatic/src/anabatic/NetBuilder.h +++ b/anabatic/src/anabatic/NetBuilder.h @@ -88,13 +88,14 @@ namespace Anabatic { class NetBuilder { public: - enum FunctionFlags { NoFlags = (1 << 0) - , SortDecreasing = (1 << 1) - , HAccess = (1 << 2) - , HAccessEW = (1 << 3) - , VSmall = (1 << 4) - , HSmall = (1 << 5) - , Punctual = (1 << 6) + enum FunctionFlags { NoFlags = 0 + , SortDecreasing = (1 << 0) + , HAccess = (1 << 1) + , HAccessEW = (1 << 2) + , VSmall = (1 << 3) + , HSmall = (1 << 4) + , Punctual = (1 << 5) + , M1Offgrid = (1 << 6) , HCollapse = (1 << 7) , VCollapse = (1 << 8) , Terminal = (1 << 9) @@ -145,8 +146,7 @@ namespace Anabatic { public: template< typename BuilderT > static void load ( AnabaticEngine*, Net* ); - static void getPositions ( Component* anchor, Point& source, Point& target ); - static uint64_t checkRoutingPadSize ( Component* anchor ); + static uint64_t checkRoutingPadSize ( RoutingPad* rp ); static Hook* getSegmentOppositeHook ( Hook* hook ); static uint64_t getSegmentHookType ( Hook* hook ); static void sortHookByX ( vector& , uint64_t flags=NoFlags ); @@ -209,12 +209,12 @@ namespace Anabatic { inline void addToFixSegments ( AutoSegment* ); bool push ( Hook* to, AutoContact* contact, uint64_t flags=0 ); bool isInsideBlockage ( GCell*, Component* ) const; - virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags ) = 0; - virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags ) = 0; + virtual void doRp_AutoContacts ( GCell*, RoutingPad*, AutoContact*& source, AutoContact*& target, uint64_t flags ) = 0; + virtual AutoContact* doRp_Access ( GCell*, RoutingPad*, uint64_t flags ) = 0; virtual AutoContact* doRp_AccessPad ( RoutingPad*, uint64_t flags ); virtual AutoContact* doRp_AccessAnalog ( GCell*, RoutingPad*, uint64_t flags ); - void doRp_StairCaseH ( GCell*, Component* rp1, Component* rp2 ); - void doRp_StairCaseV ( GCell*, Component* rp1, Component* rp2 ); + void doRp_StairCaseH ( GCell*, RoutingPad* rp1, RoutingPad* rp2 ); + void doRp_StairCaseV ( GCell*, RoutingPad* rp1, RoutingPad* rp2 ); void _load ( AnabaticEngine*, Net* ); private: virtual bool _do_xG (); diff --git a/anabatic/src/anabatic/NetBuilderHV.h b/anabatic/src/anabatic/NetBuilderHV.h index f25802b75..96096b8ec 100644 --- a/anabatic/src/anabatic/NetBuilderHV.h +++ b/anabatic/src/anabatic/NetBuilderHV.h @@ -29,8 +29,8 @@ namespace Anabatic { 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 ); + virtual void doRp_AutoContacts ( GCell*, RoutingPad*, AutoContact*& source, AutoContact*& target, uint64_t flags ); + virtual AutoContact* doRp_Access ( GCell*, RoutingPad*, uint64_t flags ); AutoContact* doRp_AccessNorthSouthPin ( GCell*, RoutingPad* ); AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* ); private: diff --git a/anabatic/src/anabatic/NetBuilderHybridVH.h b/anabatic/src/anabatic/NetBuilderHybridVH.h index 2b791e5c3..e36902025 100644 --- a/anabatic/src/anabatic/NetBuilderHybridVH.h +++ b/anabatic/src/anabatic/NetBuilderHybridVH.h @@ -28,10 +28,10 @@ namespace Anabatic { 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* ); + virtual void doRp_AutoContacts ( GCell*, RoutingPad*, AutoContact*& source, AutoContact*& target, uint64_t flags ); + virtual AutoContact* doRp_Access ( GCell*, RoutingPad*, uint64_t flags ); + AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* ); + AutoContact* doRp_AccessNorthSouthPin ( GCell*, RoutingPad* ); private: bool doRp_xG_1M1 ( RoutingPad* ); bool doRp_1G_1PinM2 ( RoutingPad* ); diff --git a/anabatic/src/anabatic/NetBuilderM2.h b/anabatic/src/anabatic/NetBuilderM2.h index 389459f8e..602056a76 100644 --- a/anabatic/src/anabatic/NetBuilderM2.h +++ b/anabatic/src/anabatic/NetBuilderM2.h @@ -28,8 +28,8 @@ namespace Anabatic { 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 ); + virtual void doRp_AutoContacts ( GCell*, RoutingPad*, AutoContact*& source, AutoContact*& target, uint64_t flags ); + virtual AutoContact* doRp_Access ( GCell*, RoutingPad*, uint64_t flags ); private: virtual bool _do_1G_1M1 (); virtual bool _do_2G_1M1 (); diff --git a/anabatic/src/anabatic/NetBuilderVH.h b/anabatic/src/anabatic/NetBuilderVH.h index c29105181..70728a872 100644 --- a/anabatic/src/anabatic/NetBuilderVH.h +++ b/anabatic/src/anabatic/NetBuilderVH.h @@ -28,8 +28,8 @@ namespace Anabatic { 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 ); + virtual void doRp_AutoContacts ( GCell*, RoutingPad*, AutoContact*& source, AutoContact*& target, uint64_t flags ); + virtual AutoContact* doRp_Access ( GCell*, RoutingPad*, uint64_t flags ); private: virtual bool _do_1G_1PinM2 (); virtual bool _do_xG_1PinM2 (); diff --git a/anabatic/src/anabatic/Session.h b/anabatic/src/anabatic/Session.h index c2d438ee5..b83757ed1 100644 --- a/anabatic/src/anabatic/Session.h +++ b/anabatic/src/anabatic/Session.h @@ -138,6 +138,7 @@ namespace Anabatic { static inline DbU::Unit getExtensionCap ( const Layer* ); static inline DbU::Unit getNearestTrackAxis ( const Layer*, DbU::Unit, uint32_t mode ); static inline Point getNearestGridPoint ( Point, Box constraints ); + static inline void getPositions ( RoutingPad*, Point&, Point& ); static inline size_t getSegmentStackSize (); static inline size_t getContactStackSize (); static inline const vector& getInvalidateds (); @@ -286,6 +287,7 @@ namespace Anabatic { inline Flags Session::getDirection ( const Layer* layer ) { return getDirection( getLayerDepth(layer) ); } inline Point Session::getNearestGridPoint ( Point p, Box b ) { return get("getNearestGridPoint()")->_getNearestGridPoint(p,b); } inline DbU::Unit Session::getNearestTrackAxis ( const Layer* layer, DbU::Unit axis, uint32_t mode ) { return get("getNearestTrackAxis()")->_getNearestTrackAxis(layer,axis,mode); } + inline void Session::getPositions ( RoutingPad* rp, Point& source, Point& target ) { getConfiguration()->getPositions(rp,source,target); } inline void Session::_dogleg ( AutoSegment* segment ) { _doglegs.push_back(segment); } inline void Session::_doglegReset () { _doglegs.clear(); } diff --git a/hurricane/src/hurricane/RoutingPad.cpp b/hurricane/src/hurricane/RoutingPad.cpp index e2cd13e6f..d652d6d92 100644 --- a/hurricane/src/hurricane/RoutingPad.cpp +++ b/hurricane/src/hurricane/RoutingPad.cpp @@ -57,6 +57,7 @@ namespace Hurricane { RoutingPad::RoutingPad ( Net* net, Occurrence occurrence ) : Inherit (net) , _occurrence(occurrence) + , _flags (0) { } @@ -267,12 +268,24 @@ namespace Hurricane { jsonWrite( writer, "_occurrence", &_occurrence ); } + + std::string RoutingPad::getStringFlags () const { + string s; + s += ((_flags & HSmall ) ? "h" : "-"); + s += ((_flags & VSmall ) ? "v" : "-"); + s += ((_flags & Punctual ) ? "p" : "-"); + s += ((_flags & M1Offgrid) ? "o" : "-"); + return s; + } + + string RoutingPad::_getString () const { string s = Inherit::_getString(); s.insert(s.length() - 1, " [" + DbU::getValueString(getX())); s.insert(s.length() - 1, " " + DbU::getValueString(getY())); s.insert(s.length() - 1, "] "); + s.insert(s.length() - 1, getStringFlags() + " "); s.insert(s.length() - 1, getString(_occurrence)); return s; } @@ -283,6 +296,7 @@ namespace Hurricane { Record* record = Inherit::_getRecord(); if ( record ) { record->add(getSlot("_occurrence",_occurrence)); + record->add(getSlot("_flags" ,_flags )); } return record; } diff --git a/hurricane/src/hurricane/hurricane/RoutingPad.h b/hurricane/src/hurricane/hurricane/RoutingPad.h index aa81e8bde..583b51258 100644 --- a/hurricane/src/hurricane/hurricane/RoutingPad.h +++ b/hurricane/src/hurricane/hurricane/RoutingPad.h @@ -53,6 +53,11 @@ namespace Hurricane { static const uint32_t IsOnSegment = (1 << 4); static const uint32_t IsOnPad = (1 << 5); static const uint32_t ComponentSelection = BiggestArea|HighestLayer|LowestLayer; + static const uint32_t HSmall = (1 << 6); + static const uint32_t VSmall = (1 << 7); + static const uint32_t Punctual = (1 << 8); + static const uint32_t M1Offgrid = (1 << 9); + static const uint32_t SizeFlags = HSmall|VSmall|Punctual|M1Offgrid; public: static RoutingPad* create ( Net*, Occurrence, uint32_t flags=0 ); static RoutingPad* create ( Pin* ); @@ -60,6 +65,11 @@ namespace Hurricane { // Accessors. bool isPlacedOccurrence ( uint32_t flags ) const; inline bool isAtTopLevel () const; + inline bool isHSmall () const; + inline bool isVSmall () const; + inline bool isPunctual () const; + inline bool isM1Offgrid () const; + inline uint32_t getFlags () const; inline Occurrence getOccurrence () const; Occurrence getPlugOccurrence (); virtual const Layer* getLayer () const; @@ -75,11 +85,14 @@ namespace Hurricane { DbU::Unit getSourceY () const; DbU::Unit getTargetX () const; DbU::Unit getTargetY () const; + std::string getStringFlags () const; // Mutators. virtual void translate ( const DbU::Unit& dx, const DbU::Unit& dy ); void setExternalComponent ( Component* ); Component* setOnBestComponent ( uint32_t flags ); void restorePlugOccurrence (); + inline void setFlags ( uint32_t ); + inline void unsetFlags ( uint32_t ); // Miscellaeous. template T* _getEntityAs () const; @@ -95,11 +108,19 @@ namespace Hurricane { private: // Attributes. Occurrence _occurrence; + uint32_t _flags; }; inline bool RoutingPad::isAtTopLevel () const { return _occurrence.getPath().isEmpty(); } + inline bool RoutingPad::isHSmall () const { return (_flags & HSmall); } + inline bool RoutingPad::isVSmall () const { return (_flags & VSmall); } + inline bool RoutingPad::isPunctual () const { return (_flags & Punctual); } + inline bool RoutingPad::isM1Offgrid () const { return (_flags & M1Offgrid); } + inline uint32_t RoutingPad::getFlags () const { return _flags; } inline Occurrence RoutingPad::getOccurrence () const { return _occurrence; }; + inline void RoutingPad::setFlags ( uint32_t flags ) { _flags |= flags; } + inline void RoutingPad::unsetFlags ( uint32_t flags ) { _flags &= ~flags; } template From 845cd30288acb140119cf60c97c86da80f7a1ad1 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 5 Dec 2023 22:08:48 +0100 Subject: [PATCH 13/51] Implementation of Pin Rectilinear Support --- .../technos/node180/gf180mcu/mcu9t5v0.py | 21 +- crlcore/src/ccore/crlcore/LefImport.h | 16 +- crlcore/src/ccore/lefdef/LefImport.cpp | 209 ++++++++++++++---- crlcore/src/pyCRL/PyCRL.cpp | 1 + crlcore/src/pyCRL/PyLefImport.cpp | 31 +++ crlcore/src/pyCRL/crlcore/PyLefImport.h | 7 +- 6 files changed, 219 insertions(+), 66 deletions(-) diff --git a/crlcore/python/technos/node180/gf180mcu/mcu9t5v0.py b/crlcore/python/technos/node180/gf180mcu/mcu9t5v0.py index 3b2348fa8..905df2a6d 100644 --- a/crlcore/python/technos/node180/gf180mcu/mcu9t5v0.py +++ b/crlcore/python/technos/node180/gf180mcu/mcu9t5v0.py @@ -28,7 +28,7 @@ def _routing (): rg.setSymbolic( False ) rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer( 'Metal1' ) # metal - , RoutingLayerGauge.Horizontal # preferred routing direction + , RoutingLayerGauge.Vertical # preferred routing direction , RoutingLayerGauge.PinOnly # layer usage , 0 # depth , 0.0 # density (deprecated) @@ -40,7 +40,7 @@ def _routing (): , u(0.0 ) )) # obstacle dW rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer( 'Metal2' ) # metal - , RoutingLayerGauge.Vertical # preferred routing direction + , RoutingLayerGauge.Horizontal # preferred routing direction , RoutingLayerGauge.Default # layer usage , 1 # depth , 0.0 # density (deprecated) @@ -52,7 +52,7 @@ def _routing (): , u(0.0 ) )) # obstacle dW rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer( 'Metal3' ) # metal - , RoutingLayerGauge.Horizontal # preferred routing direction + , RoutingLayerGauge.Vertical # preferred routing direction , RoutingLayerGauge.Default # layer usage , 2 # depth , 0.0 # density (deprecated) @@ -64,7 +64,7 @@ def _routing (): , u(0.0 ) )) # obstacle dW rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer( 'Metal4' ) # metal - , RoutingLayerGauge.Vertical # preferred routing direction + , RoutingLayerGauge.Horizontal # preferred routing direction , RoutingLayerGauge.Default # layer usage , 3 # depth , 0.0 # density (deprecated) @@ -76,7 +76,7 @@ def _routing (): , u(0.0 ) )) # obstacle dW rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer( 'Metal5' ) # metal - , RoutingLayerGauge.Horizontal # preferred routing direction + , RoutingLayerGauge.Vertical # preferred routing direction , RoutingLayerGauge.Default # layer usage , 4 # depth , 0.0 # density (deprecated) @@ -88,7 +88,7 @@ def _routing (): , u(0.0 ) )) # obstacle dW rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer( 'MetalTop' ) # metal - , RoutingLayerGauge.Vertical # preferred routing direction + , RoutingLayerGauge.Horizontal # preferred routing direction , RoutingLayerGauge.PowerSupply # layer usage , 5 # depth , 0.0 # density (deprecated) @@ -148,10 +148,10 @@ def _routing (): ) cfg.anabatic.routingGauge = 'mcu9t5v0' cfg.anabatic.cellGauge = 'LEF.GF018hv5v_green_sc9' - cfg.anabatic.globalLengthThreshold = 1450 + cfg.anabatic.globalLengthThreshold = 30*u(5.04) cfg.anabatic.saturateRatio = 0.90 cfg.anabatic.saturateRp = 10 - #cfg.anabatic.topRoutingLayer = 'mt2' + cfg.anabatic.topRoutingLayer = 'Metal5' cfg.anabatic.edgeLength = 192 cfg.anabatic.edgeWidth = 32 cfg.anabatic.edgeCostH = 9.0 @@ -162,8 +162,8 @@ def _routing (): cfg.anabatic.globalIterations = [ 1, 100 ] cfg.anabatic.gcell.displayMode = 1 cfg.anabatic.gcell.displayMode = (("Boundary", 1), ("Density", 2)) - cfg.anabatic.netBuilderStyle = 'VH,3RL+' - cfg.anabatic.routingStyle = StyleFlags.VH + cfg.anabatic.netBuilderStyle = 'HV,3RL+' + cfg.anabatic.routingStyle = StyleFlags.HV|StyleFlags.M1Offgrid cfg.katana.disableStackedVias = False cfg.katana.hTracksReservedLocal = 4 cfg.katana.hTracksReservedLocal = [0, 20] @@ -302,6 +302,7 @@ def _loadStdLib ( cellsTop ): io.vprint( 2, ' (__file__="{}")'.format( os.path.abspath( __file__ ))) LefImport.load( (cellsTop / '..' / 'tech' / 'gf180mcu_6LM_1TM_9K_9t_tech.lef').as_posix() ) LefImport.setMergeLibrary( cellLib ) + LefImport.setPinFilter( u(0.26), u(0.84), LefImport.PinFilter_TALLEST ) for cellDir in cellsTop.iterdir(): for lefFile in sorted(cellDir.glob('*.lef')): LefImport.load( lefFile.as_posix() ) diff --git a/crlcore/src/ccore/crlcore/LefImport.h b/crlcore/src/ccore/crlcore/LefImport.h index d0ecd8441..f94bc91f6 100644 --- a/crlcore/src/ccore/crlcore/LefImport.h +++ b/crlcore/src/ccore/crlcore/LefImport.h @@ -14,11 +14,10 @@ // +-----------------------------------------------------------------+ -#ifndef CRL_LEF_IMPORT_H -#define CRL_LEF_IMPORT_H - +#pragma once #include +#include namespace Hurricane { class Library; } @@ -26,17 +25,22 @@ namespace Hurricane { namespace CRL { + using Hurricane::DbU; + class LefImport { + public: + static const uint32_t PinFilter_NOFLAGS = 0; + static const uint32_t PinFilter_TALLEST = (1<<0); + static const uint32_t PinFilter_WIDEST = (1<<1); + static const uint32_t PinFilter_LARGEST = (1<<2); public: static void reset (); static Hurricane::Library* load ( std::string fileName ); static void setMergeLibrary ( Hurricane::Library* ); static void setGdsForeignDirectory ( std::string path ); + static void setPinFilter ( DbU::Unit xThreshold, DbU::Unit yThreshold, uint32_t flags ); }; } // CRL namespace. - - -#endif // CRL_DEF_IMPORT_H diff --git a/crlcore/src/ccore/lefdef/LefImport.cpp b/crlcore/src/ccore/lefdef/LefImport.cpp index 2d471bc02..6414d9ea9 100644 --- a/crlcore/src/ccore/lefdef/LefImport.cpp +++ b/crlcore/src/ccore/lefdef/LefImport.cpp @@ -37,6 +37,7 @@ #include "hurricane/Cell.h" #include "hurricane/Library.h" #include "hurricane/UpdateSession.h" +#include "hurricane/DebugSession.h" #include "crlcore/Utilities.h" #include "crlcore/ToolBox.h" #include "crlcore/RoutingGauge.h" @@ -69,12 +70,62 @@ namespace { vdd->setType ( Net::Type::POWER ); } #endif + + + class PinRectilinearFilter { + public: + PinRectilinearFilter ( DbU::Unit xThreshold=0 + , DbU::Unit yThreshold=0 + , uint32_t flags=LefImport::PinFilter_NOFLAGS ); + bool match ( const Box& candidate, const Box& best ); + inline DbU::Unit getXThreshold () const; + inline DbU::Unit getYThreshold () const; + inline uint32_t getFlags () const; + inline void setXThreshold ( DbU::Unit ); + inline void setYThreshold ( DbU::Unit ); + inline void setFlags ( uint32_t ); + private: + DbU::Unit _xThreshold; + DbU::Unit _yThreshold; + uint32_t _flags; + }; + + + PinRectilinearFilter::PinRectilinearFilter ( DbU::Unit xThreshold, DbU::Unit yThreshold, uint32_t flags ) + : _xThreshold(xThreshold) + , _yThreshold(yThreshold) + , _flags (flags) + { } + + + inline DbU::Unit PinRectilinearFilter::getXThreshold () const { return _xThreshold; } + inline DbU::Unit PinRectilinearFilter::getYThreshold () const { return _yThreshold; } + inline uint32_t PinRectilinearFilter::getFlags () const { return _flags; } + inline void PinRectilinearFilter::setXThreshold ( DbU::Unit xThreshold ) { _xThreshold=xThreshold; } + inline void PinRectilinearFilter::setYThreshold ( DbU::Unit yThreshold ) { _yThreshold=yThreshold; } + inline void PinRectilinearFilter::setFlags ( uint32_t flags ) { _flags=flags; } + + + bool PinRectilinearFilter::match ( const Box& candidate, const Box& best ) + { + if (candidate.getWidth () < _xThreshold) return false; + if (candidate.getHeight() < _yThreshold) return false; + if (_flags & LefImport::PinFilter_TALLEST) return (candidate.getHeight() > best.getHeight()); + if (_flags & LefImport::PinFilter_WIDEST ) return (candidate.getWidth () > best.getWidth ()); + if (_flags & LefImport::PinFilter_LARGEST) { + float candidateArea = (float)candidate.getWidth() * (float)candidate.getHeight(); + float bestArea = (float)best .getWidth() * (float)best .getHeight(); + return (candidateArea > bestArea); + } + return false; + } class LefParser { public: static void setMergeLibrary ( Library* ); static void setGdsForeignDirectory ( string ); + static void setPinFilter ( DbU::Unit xThreshold, DbU::Unit yThreshold, uint32_t flags ); static DbU::Unit fromLefUnits ( int ); static Layer* getLayer ( string ); static void addLayer ( string, Layer* ); @@ -136,32 +187,33 @@ namespace { void _pinStdPostProcess (); void _pinPadPostProcess (); private: - static string _gdsForeignDirectory; - static Library* _mergeLibrary; - string _file; - string _libraryName; - Library* _library; - string _foreignPath; - Point _foreignPosition; - Net* _gdsPower; - Net* _gdsGround; - Cell* _cell; - Net* _net; - string _busBits; - double _unitsMicrons; - DbU::Unit _oneGrid; + static string _gdsForeignDirectory; + static Library* _mergeLibrary; + static PinRectilinearFilter _pinFilter; + string _file; + string _libraryName; + Library* _library; + string _foreignPath; + Point _foreignPosition; + Net* _gdsPower; + Net* _gdsGround; + Cell* _cell; + Net* _net; + string _busBits; + double _unitsMicrons; + DbU::Unit _oneGrid; map< string, vector > _pinComponents; - static map _layerLut; - vector _unmatchedLayers; - vector _errors; - int _nthMetal; - int _nthCut; - int _nthRouting; - RoutingGauge* _routingGauge; - CellGauge* _cellGauge; - DbU::Unit _minTerminalWidth; - static DbU::Unit _coreSiteX; - static DbU::Unit _coreSiteY; + static map _layerLut; + vector _unmatchedLayers; + vector _errors; + int _nthMetal; + int _nthCut; + int _nthRouting; + RoutingGauge* _routingGauge; + CellGauge* _cellGauge; + DbU::Unit _minTerminalWidth; + static DbU::Unit _coreSiteX; + static DbU::Unit _coreSiteY; }; @@ -215,11 +267,12 @@ namespace { } - string LefParser::_gdsForeignDirectory = ""; - Library* LefParser::_mergeLibrary = nullptr; - map LefParser::_layerLut; - DbU::Unit LefParser::_coreSiteX = 0; - DbU::Unit LefParser::_coreSiteY = 0; + string LefParser::_gdsForeignDirectory = ""; + Library* LefParser::_mergeLibrary = nullptr; + PinRectilinearFilter LefParser::_pinFilter; + map LefParser::_layerLut; + DbU::Unit LefParser::_coreSiteX = 0; + DbU::Unit LefParser::_coreSiteY = 0; void LefParser::setMergeLibrary ( Library* library ) @@ -230,6 +283,14 @@ namespace { { _gdsForeignDirectory = path; } + void LefParser::setPinFilter ( DbU::Unit xThreshold, DbU::Unit yThreshold, uint32_t flags ) + { + _pinFilter.setXThreshold( xThreshold ); + _pinFilter.setYThreshold( yThreshold ); + _pinFilter.setFlags ( flags ); + } + + void LefParser::reset () { _layerLut.clear(); @@ -861,7 +922,9 @@ namespace { const RoutingLayerGauge* gaugeMetal2 = _routingGauge->getLayerGauge( 1 ); Box ab = _cell->getAbutmentBox(); - //cerr << " @ _pinStdPostProcess" << endl; + if (_cell->getName() == "gf180mcu_fd_sc_mcu9t5v0__inv_1") + DebugSession::open( 100, 110 ); + cdebug_log(100,1) << "@ _pinStdPostProcess" << endl; for ( auto element : _pinComponents ) { string pinName = element.first; @@ -926,14 +989,13 @@ namespace { } Rectilinear* rectilinear = dynamic_cast( component ); if (rectilinear) { - cerr << " > " << rectilinear << endl; + cdebug_log(100,0) << "+ " << rectilinear << endl; if (rectilinear->getLayer()->getMask() != metal1->getMask()) continue; vector boxes; - rectilinear->getAsRectangles( boxes ); - if (component->getNet()->isSupply()) { + rectilinear->getAsRectangles( boxes ); ongrids.push_back( Horizontal::create( rectilinear->getNet() , rectilinear->getLayer() , boxes.front().getYCenter() @@ -943,21 +1005,65 @@ namespace { ) ); } else { + rectilinear->getAsBiggestRectangles( boxes + , _pinFilter.getXThreshold() + , _pinFilter.getYThreshold() ); + Box best; + for ( const Box& candidate : boxes ) { + if (_pinFilter.match(candidate,best)) + best = candidate; + } + if (not best.isEmpty()) { +#if EXTENDED_COVERAGE + DbU::Unit ymin = gaugeMetal2->getTrackPosition( ab.getYMin() + , ab.getXMax() + , best.getYMin() + gaugeMetal2->getViaWidth()/2 + , Constant::Superior ); + DbU::Unit ymax = gaugeMetal2->getTrackPosition( ab.getYMin() + , ab.getXMax() + , best.getYMax() - gaugeMetal2->getViaWidth()/2 + , Constant::Inferior ); + ongrids.push_back( Vertical::create( rectilinear->getNet() + , rectilinear->getLayer() + , best.getXCenter() + , best.getWidth() + , ymin - gaugeMetal2->getViaWidth()/2 + , ymax + gaugeMetal2->getViaWidth()/2 + ) + ); + cdebug_log(100,0) << "| -> " << ongrids.back() << endl; +#endif + ongrids.push_back( Vertical::create( rectilinear->getNet() + , rectilinear->getLayer() + , best.getXCenter() + , best.getWidth() + , best.getYMin() + , best.getYMax() + ) + ); + cdebug_log(100,0) << "| -> " << ongrids.back() << endl; + } +#if THIS_IS_DISABLED for ( const Box& box : boxes ) { - DbU::Unit nearestX = gaugeMetal2->getTrackPosition( ab.getXMin() - , ab.getXMax() - , box.getXCenter() - , Constant::Nearest ); - DbU::Unit xmin = std::min( box.getXMin(), nearestX - gaugeMetal2->getViaWidth()/2 ); - DbU::Unit xmax = std::max( box.getXMax(), nearestX + gaugeMetal2->getViaWidth()/2 ); + cdebug_log(100,0) << "| " << box << endl; + // Assume M2 is horizontal. + DbU::Unit ymin = gaugeMetal2->getTrackPosition( ab.getYMin() + , ab.getXMax() + , box.getYMin() + gaugeMetal2->getViaWidth()/2 + , Constant::Superior ); + DbU::Unit ymax = gaugeMetal2->getTrackPosition( ab.getYMin() + , ab.getXMax() + , box.getYMax() - gaugeMetal2->getViaWidth()/2 + , Constant::Inferior ); ongrids.push_back( Vertical::create( rectilinear->getNet() , rectilinear->getLayer() - , (xmax+xmin)/2 - , xmax-xmin - , box.getYMin() - , box.getYMax() + , box.getXCenter() + , box.getWidth() + , ymin - gaugeMetal2->getViaWidth()/2 + , ymax + gaugeMetal2->getViaWidth()/2 ) ); + cdebug_log(100,0) << "| -> " << ongrids.back() << endl; // DbU::Unit neighbor = nearestY // + ((nearestY > box.getYCenter()) ? 1 : -1) * gaugeMetal2->getPitch(); @@ -973,6 +1079,7 @@ namespace { // ); // } } +#endif } } } @@ -990,6 +1097,10 @@ namespace { } } } + + cdebug_tabw(100,-1); + if (_cell->getName() == "gf180mcu_fd_sc_mcu9t5v0__inv_1") + DebugSession::close(); } @@ -1214,4 +1325,12 @@ namespace CRL { } -} // End of CRL namespace. + void LefImport::setPinFilter ( DbU::Unit xThreshold, DbU::Unit yThreshold, uint32_t flags ) + { +#if defined(HAVE_LEFDEF) + LefParser::setPinFilter( xThreshold, yThreshold, flags ); +#endif + } + + +} // CRL namespace. diff --git a/crlcore/src/pyCRL/PyCRL.cpp b/crlcore/src/pyCRL/PyCRL.cpp index 6c5ea9bff..f4ac3e4ba 100644 --- a/crlcore/src/pyCRL/PyCRL.cpp +++ b/crlcore/src/pyCRL/PyCRL.cpp @@ -231,6 +231,7 @@ extern "C" { PySpice_postModuleInit (); PyVerilog_postModuleInit (); PyGds_postModuleInit (); + PyLefImport_postModuleInit (); PyDefExport_postModuleInit (); //PyObject* dictionnary = PyModule_GetDict ( module ); diff --git a/crlcore/src/pyCRL/PyLefImport.cpp b/crlcore/src/pyCRL/PyLefImport.cpp index 0986d5db2..a6fd6bb32 100644 --- a/crlcore/src/pyCRL/PyLefImport.cpp +++ b/crlcore/src/pyCRL/PyLefImport.cpp @@ -38,6 +38,7 @@ namespace CRL { using Isobar::ConstructorError; using Isobar::HurricaneError; using Isobar::HurricaneWarning; + using Isobar::PyAny_AsLong; using Isobar::getPyHash; using Isobar::ParseOneArg; using Isobar::ParseTwoArg; @@ -125,6 +126,24 @@ extern "C" { } + static PyObject* PyLefImport_setPinFilter ( PyObject*, PyObject* args ) + { + cdebug_log(30,0) << "PyLefImport_setPinFilter()" << endl; + HTRY + PyObject* pyXThreshold = NULL; + PyObject* pyYThreshold = NULL; + unsigned int flags = 0; + if (PyArg_ParseTuple( args, "OOI:LefImport.setPinFilter", &pyXThreshold, &pyYThreshold, &flags )) { + LefImport::setPinFilter( PyAny_AsLong(pyXThreshold), PyAny_AsLong(pyXThreshold), flags ); + } else { + PyErr_SetString ( ConstructorError, "LefImport.setPinFilter(): Bad type or bad number of parameters." ); + return NULL; + } + HCATCH + Py_RETURN_NONE; + } + + // Standart Destroy (Attribute). @@ -137,6 +156,8 @@ extern "C" { , "Merge into this library instead of creating a new one." } , { "setGdsForeignDirectory", (PyCFunction)PyLefImport_setGdsForeignDirectory, METH_VARARGS|METH_STATIC , "Set the directory where to find FOREIGN GDS files." } + , { "setPinFilter" , (PyCFunction)PyLefImport_setPinFilter , METH_VARARGS|METH_STATIC + , "Select the way Rectilinear pins are converted to one rectangle." } //, { "destroy" , (PyCFunction)PyLefImport_destroy , METH_VARARGS // , "Destroy the associated hurricane object. The python object remains." } , {NULL, NULL, 0, NULL} /* sentinel */ @@ -158,6 +179,16 @@ extern "C" { PyTypeObjectDefinitionsOfModule(CRL,LefImport) + extern void PyLefImport_postModuleInit () + { + PyObject* constant; + LoadObjectConstant(PyTypeLefImport.tp_dict,LefImport::PinFilter_NOFLAGS,"PinFilter_NOFLAGS"); + LoadObjectConstant(PyTypeLefImport.tp_dict,LefImport::PinFilter_TALLEST,"PinFilter_TALLEST"); + LoadObjectConstant(PyTypeLefImport.tp_dict,LefImport::PinFilter_WIDEST ,"PinFilter_WIDEST" ); + LoadObjectConstant(PyTypeLefImport.tp_dict,LefImport::PinFilter_LARGEST,"PinFilter_LARGEST" ); + } + + #endif // End of Shared Library Code Part. } // extern "C". diff --git a/crlcore/src/pyCRL/crlcore/PyLefImport.h b/crlcore/src/pyCRL/crlcore/PyLefImport.h index dca57938a..9f1442a20 100644 --- a/crlcore/src/pyCRL/crlcore/PyLefImport.h +++ b/crlcore/src/pyCRL/crlcore/PyLefImport.h @@ -15,9 +15,7 @@ // +-----------------------------------------------------------------+ -#ifndef CRL_PY_LEF_IMPORT_H -#define CRL_PY_LEF_IMPORT_H - +#pragma once #include "hurricane/isobar/PyHurricane.h" #include "crlcore/LefImport.h" @@ -42,6 +40,7 @@ extern "C" { extern PyMethodDef PyLefImport_Methods[]; extern void PyLefImport_LinkPyType(); + extern void PyLefImport_postModuleInit(); #define IsPyLefImport(v) ( (v)->ob_type == &PyTypeLefImport ) @@ -51,5 +50,3 @@ extern "C" { } // extern "C". } // CRL namespace. - -#endif // CRL_PY_LEF_IMPORT_H From af8c71fe5cde10383e13ac47916f8c7f902859db Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 5 Dec 2023 23:25:25 +0100 Subject: [PATCH 14/51] Create the first technical log entry. --- .../content/images/notes/Katana-Debug_3.png | Bin 0 -> 184587 bytes documentation/content/pages/documentation.rst | 3 + .../pages/technical-log/December_2023.rst | 75 ++++++++++++++++++ .../pages/technical-log/TechnicalLog_HTML.rst | 22 +++++ documentation/etc/definitions.rst | 3 + documentation/meson.build | 1 + documentation/pelicanconf.py.in | 3 + 7 files changed, 107 insertions(+) create mode 100755 documentation/content/images/notes/Katana-Debug_3.png create mode 100644 documentation/content/pages/technical-log/December_2023.rst create mode 100644 documentation/content/pages/technical-log/TechnicalLog_HTML.rst diff --git a/documentation/content/images/notes/Katana-Debug_3.png b/documentation/content/images/notes/Katana-Debug_3.png new file mode 100755 index 0000000000000000000000000000000000000000..51c336cc179ff6220a4ac2af08d466617459f138 GIT binary patch literal 184587 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̗UuMe-b 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

YouCxx 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 z zk&Oi%)M*9|yo;34Y8m!*%m?7{Kwt?Nv%lVsL3*KfpMxH<9AeIXV*3d##Su*5Frc>r z;$d;9pFpeyR6){rJ24?q}7%a*5g2^vb_*rznrbH<9&sM9ymL@DEsZtj?O1wraVD z!@cUXLs{pAmOSgpdM@;kX`u3*XwBl)A!`l{h_=+~DL*f+&A)TFb>Eps>}MwL796df z{bOYEwkvaKsbt6D5!$emfuOwmtW1|=*XTBOSEq`naH8+%# z&};=mUBINdfn1|@?0BtBT&3X&nZ5aX z+!5mU{0Xv^wsFfO-ZVNdPY#q3s72?~bUjGR7{|`fVF3gU~ zuW&FU$Hf3f)K}&nqn*3ngbHtO$Ab573ev=&Vq|}w`k?03hu!*yQ3p>Ft7<7>>^r#j zt<{IszC&`-60gf|I7VvQ7X(6UP6<48-G$^SlFW`y0l3gOj^kxx8F@&k=z4@!8s$zL z#lZ#7Ix2Q?w0t5W!IWk$wR1$cPdmZ5%KZWQApr%=)dtt`zC^q+J3Gs`BX=hOb>(+1 zSGcYT8{R2!os(_bHhxFUY#|1C|NqxF3*#o9H-ea@4V9#)G+&@0EuPPVZ74)?0k?kF zui^ILB(VJJ8)101BEEN%eLnk{3oxByTdCpP$e$AgU-EXNU!EWMIFGznPO|wk@p#$- zU3&sY8Yhs@Xmsve)VVZpH#9OV-Txq8bxkK6J%@)w>3 z3j3KOboYl3A6RTgFW13QB%ek@1uO;Snf`)$*(r>wU6Fe-_c#h3jg&s+=H`ZP_8zQP z4#-xi*f;5}iD#n9Anki9AI&lG^KC^QrmUw{NMnZlv%4JZ}FNwjjgvC&)gC<4$%6 zF!Lvn@AQM(b>j}0fH!_cc5W)9ItIUCu8VGR!Uo#i$e5#kz5YeT`Vxk3uBIfq1)6eh ziapvaJ@3Q6dGF-p47}a4a2pDB1nP-xp^Ir-Wgst8L91nbs?mJZJoHf3DY}BA5GS}-mHqqbA%G@dHn72dlj*s6SDluV``X%-7rF!?P^Lbn7DSulQBmY({(|O+`gK zOEs6$=_TtF);v5sb%0bx873@|auZPzdVb+iEnNNn4yCSmy5r6fH`)ZWL`NQZ`)B74 zPuWH{w+>n61s*v2{?47T;+`Xho6u>JSU5^_PIeaS^Yr=iY@x~p7i<04KD^?Uc|~+4 zc8w*PVGs(MgA~3J#KOj{xzrTQ6v8=|=&LAh-nPw~h#xpP!HUPEq@;Xe{rt)9@M}_~ zKqI#f+9j@ZL5!@#@|e_w8<&w~FFZtaNy8w7Nl*k6RW&OKqKU%`3zYbk zdR_(baWeQ|845X9NjUWDJVQsaJ9XTr1ZteZxP!HwG2r@zoU!d#35HuHbHz~vPlJ3Q z;%g!zp6*zT?)62T(`@vRs+h^34#|ll%Pgq`dzIvcq0o~IWRSxR<*s4`2F(BV?c5ur zVBaPCWAsVU9?cNR97e=e#uLb>CC@i->U@a&C!)tEuZi0zRsajQEjM#MOvYJ^jB%Yj zS1PSEftP51NQMlw3(=}7_xk)fTz{RXjz|Fdw97LB-`3ARnu)ofMvFh@3sc z(3y~`JVSNxKe^|AGS3UCgiEmk({+;yKnt3Cp zdCw|V^suctIOzySsBW+SXs0eucx%#(gd;a)Ft&=Pt7xc3!8LiLy*c<}&Rx40xi~4u zN=dQxQ#mDmwr0`IU8-GW3NiGKsnM>L8S1}sLd@+VKXrsjG6g80S|^Z`PkjH_ZUx7K zgsYG$E@>b+^;kWNGcPiEy+8~>0P~F=KS(0fw_izaJwG!_l8Y2EOWLx4$3n-kQgaWvjH%{h0F7yb;sS)*-PadN`3f^g3eJEALKa2v zOBYxs@*)_;Aulh%nu9&v4Efhyg$BkQG&k?UlQWT#LR8RCR~^Rc&PJ+GKycjM+k1S~ z;a!|4)I>rb`-4aBFg)0MM|P}`KZHHp58z9{iadQ$_2tW2a?#ktL?IMNqm2MKFV3_B z8(trXs*TQ-WG5RqGTCrsHYnhA@uho?UKA4-SKa%M?E|FX4yl%9b4FFQJT-%q24a#Q zM-(V@5i$ilggd-etnJ4JT24+5BpaXRNl83*37_*_=B<(da-$M3a)PTe4_oQU&7PEIbcc zlqoOEH_TziXhXyANaG+O=z5xo(Wx{~(1rG4eLazEa{KSG5?;9NHr&>@hUA? zWGE`hafeSZ3P!p2@~mC5BU#7}*D*>#fQVFpFp#Kz1p0b=`D`FFz@fSBIqkQ0r(2NUM1u@~nq^(!W-de} ze~oidKJk--7h-t2j1e)TJ#>n`7@0?2{l3KtxRn38% zY74ng{sfFrS zsxYh-AQz{d*b{`x0zBzM4X@)EQ3RUDnmnZLFGJ+Gd5LI)t%A=wgz0$KedKS98e1r& zNGs*_A`-gvl?xdFWC}%j*rR*0|BP00_Fc#_NK@RgLM;Zx33cr?I(;8)^xQ&%Lp({TFxi)CwWsK+uZI6lM&^QhBS4Dy^H4l?3OtUl ze7a0?f&Wpq4R?fZODp znUdt0Ev}ox99pbonB^#bw3B8Ul+#@4&I=`Y<*hLI)M_e!uRs~Pfb_MD z`;-7ml-D}(S6{>vNr&Yli-nB|6Oq2)o>=jdCNDu3aBR4bR}A^`Utf_6uPFNX-(GPkx$X}#sGYHb z{M|-?I+&^#|NWE&a1A$&*IiknFaHEpZy^wegOLxnfDt%e8%Kq{=1iLpDVxo%T)EPb zCkSb&nP2(OpFdM;^AJ`dKk-VXJ+{9Ks+UF7Z04sS3k2vvJ#sY0|G(i27=x32q7RM4 zs3XX{yI((t^)i;PEC=zEgoF<3P~5#ElLrBk1x*Yor)2}CQBdyp^UOqe@X_s{*!oV_ zKmkOizr15qRm5{uO`kP)c_KQObS$jk=|U)5fn*2H_c?cW!>K`8>LVDs3@1-^3Q-G* z5$mLCTm{XZ>hZ*7yUt!y==S&5L$+T>UU{S($7ol%ApFRqkzoRka*~d%0d~Jv?CB5) z^W%_{tvqjAg{l*rZ9h0B!SThAz_KEokq?5LMU!WyKaMQRo~j2|Lc-QcdtY{$5XR>x z%KBBdOul{lHfWLxQv}y>O{X&f2SSpnihju20fTedoge%hTmNVm&;t9+fCFffcA&VG z?&54g)euSgEq9~h@q?IU_JiL3pG|kQnacH%SiMCOu=A=_s{&{tB@|Rj^t=)tc45pc z5k=(=0;?${G1x6vAQ5T+R445hd=!@p-ElDgoe1U9bS8pPjQf$j`|xY?0x#Lu!w;ke~lS$7wp9s>5N%O{MJHjA0BgjUe;Ao7^lP_I21{ zP#`n$b3|O7N?Q z*J@Ap_i5zl!v=0P(9!GUx;Q=4Nr`Um)C{oTiJ$xpaDfdbPBndSX8Td|6{H|A zaH%3_R@za8k6dm7bfTiQm4oc_OR#`Wfw<^Zt5^Fhj)pH0`g&7Y)#}FDWJ9@5pHL!3 zCn^rWS^*Q!GZ4K1m;lebOZ?i13^0kMzmO)})qm>)#&R2eB!zbKApm$f-q>6n*gifv z2@8+`jTO4YrgUG1W&wRqEO~Bow-fLIV-#*Oc@h5#25S#YEgQapK!pI)B%DSrAcSm9 zQM!Vh2Ec~CBw^q$1i}jgpM3Ii1&*uVu2*0Dplc5*JQFs(*`dj5`0XO*fb1}@{r-I& zx+HOd4bujx3TL~;%it&h^*#6AOwf9wI40SDyx17;SOidoQBIj`2|+r8B$I()CPj@g ziMC1E@me=$vS6D9Kg=AYii#o;d=uD9$3gF^)>gT7p0X&2cx1qj{0}Ak4b}*PC_pkA zE@9srAQ<}N&`lP2%-ir`v(!w> zOlgy9(n?xLmXI)#%32YTrI3A@NV2ObL$o4mM0R4xlD)-}Y}vOk*_RNC?B97k%scNK z|M&R5|L1s*Cd9=?AH^KYlHcmL7saM0m1PIcc;seG&B{a;dhyLKX^5Qk7sN6L% z!Wy8}-L}m^Pipqg_V1aL!U@c7ow9S{#!>=!OZpMW8sP|r<;xYc>@V_XDyBLC5GeUb zNbGV?&O>FC#H+U zaK)T%92KYxx(J0lk`N9GM0Aj_xeXwT4BvO-0nzK)QxHlpXaGb{@)Vj#scrFx-@~~d zcP5^Hc|C6on}*kO1|jn}kb)GCWPL=yYL6D0GH;{b-GiTE-WZ^v=sfR}OQ{zxewgWM z$8ohHU1?nH!hBPMm0J;kxrE92$yhCrX^hv&V!zkU>~>XVTc9xJf7_T$NjYvdly|;e zgDZV!9VE!Bn-IquE(_`T`#!ck7+UkKxVN<3ohVMrScP;c*V>vIxeWWOSD$OA9&Q-h zjHPxJoq!@z4%6L5N#Zt7Dpp36@Jl35D)s$Xu~X)um(?893)|<|pE=FVX4O&(yalwhPST~w&Szti*vMaHIE*Jy;_S-I~I zScH@cSFa(bOQ!uQHZHqP?k7u?{hdnpz&%6{K-P6MD&_zg^hOUnX|)D+L6HKvty_y* zW7qvw>BpML)5lz;-Y;j-AKhEgOXX4Rh;J4(D0B8xWv{aY(1S&zY;)~Sfy2fa6zH*@ zIoFi@L|r>k4!_5(nEC@DE9`_Qrwpje2Ac?Duy`V{mEmnv-uXjl6@OKQ-(8WB<1b&m zt4R6rD22MdGO{Qy@Y28?A#0V?*N13y!zJF81Au`l1myfSMr%D^KLBmIy#0W&mV53* zK(5<|4NDvdRJe6c5s!E1Rfd^%L0TFEYSJ!E)9f@ zf_@f^10+z)BcnBWdOo>vj$vQ9?>bIaN1^tvq4c~`aUcAx6 zHvN)qM=G_CaT`GFx?4|ZJG-4@4=MsrKG;B`@_41lku{H{rdx()H0{5>X5+GERZ55W z5hHPoP%-mt5jNKx8PDl@%i;s}_FjDs>e^PR9H^iYxP^?&X0_|OUmIQL>1g;g zCFRwuDJR69C<)X`|A&&mp*T-Th)!1AEkJq7TlI<(hY!oNToF)uXD-+KK<46bOco}Za*L=K%7vy z%*A+vF0xX|8>8x$L_lwb<_QQe;ro&xYhVsfc;F>+c6OHeD5Bj2jPvu2F>;%x_F8wR zo&MPl*nqb^YwX6E)wZ2&;`mVy_EaNBFGC>*5+NPhl7&>&Bq zJ>x~KBt%mjD0*bq$X%(GiuicqbT|I^tmTRj=(UudCkJo;OnA)WMxYPQS;)sB-78L( zx*@>NkCq5^Z(PfPRB^s0$v^D0n@yx|y9R8R^i&6FQrpCp+$$S!u4Dtd;vi#5o@ej! z&V)ZmO7i0YI0WoA-D-J!VFjSw{m9QpVBOn>-ia_;=3V77hJ6B0EyCV(Yeezws1oK- z#hbSbLv+(4QOSYDnf?}?B#q=3PQf>u2yTQ0TGdhs#DSZExC3kxtOTy5gKmyCzjRA1 z3bi!6(W6w^A`@c&QHL$ya(YDwjcmyo9DrMD5Nbi4V$StrGZ3e?5$t1G!9tAyY4mS; z1{h!Kfg-;+sg>LQ!!l1U7KW+%ejk7m&PyVAcP9e}#n@t~4_iF~ih2x-Q*){XS_$9# z;m=OFDR$vpSnnB8;81SY;+f%?h%$p<-^(`Xch@rR;32t8>&SMihCmW4iG_IL^*iW` z>r;$XTBZ~NDzCD4HU3y}TEtBP4<`j*mCs(MFxPxx6{%S8U%{f}D{l zrUnMC)Lg;V&Ms2K1pxCr!q3iyU{Ars+|;x*vLj1rc?F} zs5zKnw&JV?IPWn#`XTN}tvkJ?vAOy1#r3q@5K6%sENJ`+ygI_le;VlPyM>IMgKJMm z&pX$2F^SIz%oa60T(}6LGUp9wXT^#Mr5F!cOl6Y?>|pj z?;3IY?cQnwxetsdngSODaXIN_k{kh|ss3xWe|=;U^B&0%X;WQ~JER)mS+|t$Dy>rw zKEQyseGlXOt$qv{T~;l*YPB>$M=q<8immm2cPfT&N4#QBMF_K{&JBaS(u&9Ja}0Rw zCW1SB!Il=$-VrQaINY6skghW&8*qF*1mA5*NMP9$5+Cj#-@|gG9d(cP6i!Qi$**Ha;&nF|BT;|lA5|sS4j^CeIMU* zbOPD9IzHmIAP`)xucJq{zvY!ku6G!|oF-N?**Y_5&8Q)#;&jIkERI`;2G;d8($ZwQ zCAUTGLWHFyPuie~SytDxTznC4T`}wTmyVqnr+_C0{1lvJA5b^S^KM`}^%U<;DV6g* z;$-OCn3%o~U3(r!$t842EH~Ono~scljwv?-o-GmBBebUUcG)90OvA5Kj`70ivA`Og z##*CVgnIRqGeV@xR`qb53wC$8DZlWE1M{)`N>^p)ZA8H}>3*5f9*hVrR4o;q>Pd^)jsMkWa;L)O@tT@$i~hZ?5D zu6(Tb9si8xAjPX|sW5js*6B-v-WiS;x~NH03{DqzylfyjIjZWu)DLAX#jU^VRURHi=~toqIL+PoJ;+R|?CRTES68vgCu08Zu7DD!em+&oDk?r1 z!Eo)6wfk(G*Ktj!GN&x)@S!KB;Ut%!PCiKY+N>SBtqb-d`R|UfpV8fF{($6fsFSGE zu+E3o4sp+(IULRssPEL*wyVUh;fl$h_XQE#GS%Ak5e%mnCXba*SEfJiZ_9U&zR+V} z_+&R=C6V6#2NCBV8D+GDo#Iox83vR@!Gw*?<<7%3V{&Jjz^`*8caDnGP_v|T`K=x+ zz_p4_6e*M$oSXRm*|EEuZ^Ni?8_(y(yTTyOu4WEKP~@h#0!#|Wr5WwTp$lmo*3$t% zNdP?_)d<9EW(#+U7NFVoTv)=1jT*duh+Ow1IF#4Ix!`cfzTjvU&+F}E26S_mVIB)y z|CX5YKH5D#Hyu3ZIqv8wb@7`ur*Sqz?!S`@R0Gu$E(6QPWZ9#gbYyS+skoJT`F~^!bd8TOLvIu1njuv9xR=#fM!3E8(VY^v*E zu29In)(R^B`g9`|Mn3zjW{M*IdK6FIzq{*Gp~#?bs-MXIOQgi&6sBibr~#9E-(hQu z7#j!m!E@{nsrB<5(T|ed$*>ueH<0m{xN-nKQa5+&=OxVcCCD4tp)PJ&POxi0x%w|d z;9Wm@q<*YN;E`M+61K|O+p>Q2Kac#xFR<&A0o z@Xu4)O~QB!pOdFgY+k5_?c4KLgKC*sX&eL;O36P#Dh zsi`eh(m1fdI$Z17Kn?Qybox7hsc{58CyM0@en8;WQBh*L*N6lJ%USN*=ctW zYV)ddrXMBuG=6<&oOJ5$gy<6suH#F;p)%Ram33j+bBM{0Vn&w)SdS_>4d=78V|CkP zU&$aBHw6QD`R6e9N`TilsSIwsPk8&ww1)TZMM6wt#QC&G&Rbr+DhSC{8!U}W zr}(SLVBJX>Fi%}>P=<-{ulgDq&0*V(z8R@O4-v!l8KBUSm-`QoxgXXryTKev8@IW1t zM=fM2;NxXAT5v~tYwW`Rv)`6oNbfx#YwBMO8mYVoP>0p9*lgjPZ|x-Q=z7TsVWzjo zH|7p+tZFQPLeQ(}m&1oI47MUe4X~DbQH@YmWpLHo`1#=ev=6Ltj+vVeA?_(XmZNpW z@27<$z2m}ak2g1!ut$~H@pS-VUfmS=?6zxez@0I2RNx9n7f6trC|#4o&vWr5p2qDp2F@4`B7^_L-kzQp&_zk>Kj2r`k7%e zZ0)xec*-^bnQv}BVR+?XC0U(!WKK`1PYbcUCf=*9>x;Y20p-E;=E)9SKwJ=i3JQtp zbWR4@$9o!=0@0J2JrqzndHt1f0-F|D z{OAyaDud<;|HJ7bH9G~of_F2Y(o_7x;%>RjhTrnf5=CaVYV%=RKK^&>xd&KApcWm5 zooIQ~o#ApcAv6y7vy6;p7%@)jp(f{ML zXx{SXc2S^2RzmXr515?(6}zetW^tryWnM9@?bg{zCHLBPPEKsNZ`vZUp zdDyS(jCh||!NF1NunwI(j?TOqQujKv8CFijByoqsGIHbEVS@{&P z)7!>(|H|bhc)8~u={2oJ0R9G|COYSbDJn(IvSAv(+)~Wv`Ry>BPw2Y9b*Z@(Rn7_ya*}z35sQ*hNw@%3=AoW4(el)L()-rl}CcXXAm%cOIWr83R!I`N9 zi^#{fre7TnJ$10XL-dH!RCb`>TZc=Z@cMYqLad{W4g=PG)tuLQ1kTQyh+jo}pvmLTEXnZKtEt z4iX#Z!&RzqoSmLH1C@IpiG+^_XJKCp9ni-UBJz;P9N2;udGs-q%21%nXv}^|a5_wt z)~q$PXhsOY_^mHz1qn*OlC3POskv}vPFOOu^+FStTrO1eibkiasX-Gp$0DW);|=b; z{U-;DTXR!RbLQaT@~MCp6d%!YV0RcB9nJuT-<4~C)3TA7_ow%e4>Q5D@4>iTg29Fl z2(LC_8;d!rh=TCDnuCMn>Tm!cePBD8;S%$AIhe>PLot`=#%u&7Jp1>rr1SydbtK&l z5v{W`Q?av}WwM=<9gLIXm`zP6g7iEJw&6udI^DDd!t(y9XF$E*c<6P->ZSL0G@0if zM$sh+o`pc)5j&%2`{sA?%S+S6FT=po#=6q*TKOaE7Sl*RW&(|rr+x#Dap1U>GF z8Luf2@Mu5(lmX#9_HZW%I^#gj{~J+A3q`s%>GY7*ROkBK^b(jcPZ<}gx`h2y5Zo;0 z_bVP&4*2^b#12uAA5Oy?dHDF&5M8(;tQ`^H#T_dlbFjknx*ssKLiFo-Xp7@Y)}DDt z!G9TK8fnc}0xb0dK|7|)2jx)kNxmEl1j z`}S0K*;#}!C=XvE+5Mc7E;^&UGd(!7u~{FTt1bV1g{a`uFAC5pgISsKO-0z*d6@rz zcuEf}AAw8cT_pcfIIUcFnw^xq!osJ0tkFPD zSFK6=KQW-PtDlR3VYyU5>;b=$8>wLKLO=GC%9)w{~sN-!W_Qw;kUm^tyynJ3(!`(^0;o zw8vP@89vxtV25?CFzJso#Biv)3cYK>ibsbJq0h5TLI9uk7*4@w@gGpv8Tdt@V2a$6 zJB3fIXcYK%sUG{j9dYa!NvJG6pU0)A+mtDI2k6WrK3i7qdp5k46mgm_dmtX5+6A{_ z>Mg4^t}xdtCTEh1V&hd!*t~~0?u0_0^T~^!{X~HLIH~q2iZf7Hs?2e2EO>6z=?-{+ zLdDwqYc{WYi$Fu~%VgO2mu0!1mU+6Q7)Nf~eSTf{rHUE7hPfw-Z1mMV(i0r z<{3z+9tbbJLM>_=8`T=G-=Yqk_}Nju{a8`Qx37w(pE-?{k2KbTG8s`Df_g+oBNaug zoLY0#L%?Q$V_O^9{-kG=@8TG2{Qk9*`FL@-YIZ_Ffz*>D7uK-{ z*xJX#Fy;6!-;jJ6jAr=0s5e9&;%EIo%a!v0(dfbl}+Z7qKt)iae5$faUFL4LQl8)3=kzBEFx!t*BgNm^7x3atdG9YOR z7`r_!yms2m%ueH@8)g#Tp{$n~FZOK7;;zlP)^~57RERDn8&>iayKppoVV2W9sG&0H#CP%J zP`P6&6Q`3*Qn1nTAG*tfwY-Oxz2!7jnjnv(HtAa&Fa<~G*vIz*kal!ckMei_8M1Gp zR1FpLx*{gy7gLvT#s)~eYtYKhs{E&4OmW|C0|@?h#xqI>cCi2m=6?zvA~8EHEiL)x znqNT$hdmL?%*dcqWoK-px@-XBS*OSm$Skw$`>F`vM|%*+Q3ufI;xx2U0I(gtC(5HT zqI4}o8!)f`tYXmkRS|xVmI1h9#_b%}AcI|`!n-dV?OZ@~t5Z9+u4X#9y;90`5F%gP z!5esQZB&4pLEi{=JpZLfwpSi=1u60*kID!ky*-cT#{bkGZ@?f{?gv!56^sMbE!{Zd z9X!8PoopiELNXG2W@fmrT)tUS36`;qx|k{Y)EPlk&4a#ic~|BK?y&%|8PrJ8Z6KQj z3A!#otfr~a6={Di*#JOCb%GRRoo;(#m(Qah;-;uEI5}E*{Z;yYQ}iSxBOIz!Y8xTw zy|*{IVL#t1UIq;LxR!LNHilJQWj8r3!D<{Z{Ow%-1%m}F;AB7DY*xCkMDmj-I+cbF z!LZ2&GQLmsu=m@AE2Pd}VY}ow+{79sB0_-C5bEh;j*iOE^vftK>|7907*RQc|G@^Y zBq&BM-|XNFhPJ*l1$7rReDoZdm>IJEv7(5ueJLmfytsaHc05;Wy>J=CFRM^eGylXP z%xAhUDxG}#+X_r1q?Q4EAG2^)wYN?OI4Nd?cDW{tSI=Y93_Y)_D-3$`#$eF~p~?`WCy6M3?`T&1EYLh>Wn zJ>`QoY>O0|F-OTlp&-k*`*-C`u0k&n9ftAsBK#eoQTfZd_YfJcu1sF|cB zG&Ue7^6}KA6{|P3GwdLlXj&ZI4>dylEEW7>rk!gu+LcD0-n*@r9KC-f=(Tzc)b^MO z)OlLÐ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 T9OyRou2|>E^SJ1~^^5-nX}ZG; literal 0 HcmV?d00001 diff --git a/documentation/content/pages/documentation.rst b/documentation/content/pages/documentation.rst index e43cddbe8..8674f5dae 100644 --- a/documentation/content/pages/documentation.rst +++ b/documentation/content/pages/documentation.rst @@ -104,6 +104,9 @@ Coriolis Documentation `Oroshi Reference <../doc/oroshi/index.html>`_ |br| Analog devices generators + + `Technical Log <{filename}/pages/technical-log/TechnicalLog_HTML.rst>`_ |br| + Technical logs (history of changes & fixes). Third Party Documentation diff --git a/documentation/content/pages/technical-log/December_2023.rst b/documentation/content/pages/technical-log/December_2023.rst new file mode 100644 index 000000000..0fef0586f --- /dev/null +++ b/documentation/content/pages/technical-log/December_2023.rst @@ -0,0 +1,75 @@ +.. -*- Mode: rst -*- + + +December 2023 +============= + + +|BUG| Bad Topology in ``NetBuilderHV::_do_xG_1M1()`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In case of three globals (one ``M1`` terminal) and *no* south global, +the generated topology was wrong. We were accessing the terminal directly +with a vertical segment. It was creating a layer gap between *that* +vertical, which is ``M3`` and and terminal in ``M1``. This is also +too rigid a configuration. + +Fix: add an horizontal, in ``M2``, to access the terminal. + +Yoyo + +Occured on ``benchs/RISC-V/Minerva/sky130_c4m/``. + +.. image:: {static}/images/notes/Katana-Debug_3.png + :alt: Faulty _do_xG_1M3 (no South) configuration. + :align: center + :width: 40% + + +|CHANGE| Reorganization of the size detection of ``RoutingPad`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Instead of detecting the size characteristics of a ``RoutingPad`` at a late +stage when calling ``NetBuilder::_doRp_Access()``, do it once when first +loading the net in ``Dijkstra::load()`` with ``Configuration::selectRpcomponent()``. + +Add a new flag attribute on ``RoutingPad`` in order to store various +additionnal informations. Currently, the size characteristics. + +Add an ``M1Offgrid`` flags for the terminal characteristics set. + +Move ``getPositions()`` and ``checkRoutingPadSize()`` from ``NetBuilder`` to +``Anabatic::Configuration()``. + +In ``Anabatic::Configuration``, add support for the ``M1Offgrid`` options, +that allows fully offgrid terminals. + +The ``Anabatic::Configuration::checkRoutingpadSize()`` now store the +characteristics of the terminal (``HSmall``, ``VSmall``, ...) directly in +the flags of the ``RoutingPad``. + +For the whole function stack, work directly on ``RoutingPad*`` instead of +``Component*`` : + +* ``NetBuilder::_doRp_StairCaseH()`` +* ``NetBuilder::_doRp_StairCaseV()`` +* ``NetBuilderHV::_doRp_Access()`` +* ``NetBuilderHV::_doRp_AutoContacts()`` +* ``NetBuilderHybridHV::_doRp_Access()`` +* ``NetBuilderHybridHV::_doRp_AutoContacts()`` +* ``NetBuilderM2::_doRp_Access()`` +* ``NetBuilderM2::_doRp_AutoContacts()`` + + +|NEW| Implementation of Pin Rectilinear Support +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Add a ``PinRectilinearFilter`` to the ``LefImport`` parser in order to select +on which kind of biggest rectangle extracted from the ``Rectilinear`` we want +to create the ``Vertical`` or ``Horizontal`` *only* external component. +We can choose betwen the *tallest*, *widest* or *largest* (area). +There is also a minimum size filtering (to prune too small rectangle +from the start). + +Make use of the new feature in ``gf180mcu/mcu9t5v0.py``. + diff --git a/documentation/content/pages/technical-log/TechnicalLog_HTML.rst b/documentation/content/pages/technical-log/TechnicalLog_HTML.rst new file mode 100644 index 000000000..edf8a05a6 --- /dev/null +++ b/documentation/content/pages/technical-log/TechnicalLog_HTML.rst @@ -0,0 +1,22 @@ +.. -*- Mode: rst -*- + +====================== +Coriolis Technical Log +====================== + + +:slug: technical-log +:date: 2023-12-05 16:00 +:Authors: Jean-Paul Chaput +:Contact: +:Version: December 5, 2023 (jpc) +:status: hidden + + +.. include:: ../../../etc/definitions.rst + +.. contents:: + :depth: 2 + +.. include:: December_2023.rst + diff --git a/documentation/etc/definitions.rst b/documentation/etc/definitions.rst index 898592b5b..d836bc9fb 100644 --- a/documentation/etc/definitions.rst +++ b/documentation/etc/definitions.rst @@ -167,6 +167,9 @@ .. |man| replace:: :cb:`man` +.. |BUG| replace:: **BUG** +.. |NEW| replace:: **NEW** +.. |CHANGE| replace:: **CHANGE** .. |KeyUp| replace:: :fboxtt:`Up` .. |KeyDown| replace:: :fboxtt:`Down` .. |KeyLeft| replace:: :fboxtt:`Left` diff --git a/documentation/meson.build b/documentation/meson.build index 73f37dfdc..4ab103ea6 100644 --- a/documentation/meson.build +++ b/documentation/meson.build @@ -41,6 +41,7 @@ rstcontent = files( 'content/pages/stratus/Patterns.rst', 'content/pages/stratus/Stratus_HTML.rst', 'content/pages/symbolic-layout.rst', + 'content/pages/technical-log/TechnicalLog_HTML.rst', 'content/pages/users-guide/Configuration.rst', 'content/pages/users-guide/DesignFlow.rst', 'content/pages/users-guide/Installation.rst', diff --git a/documentation/pelicanconf.py.in b/documentation/pelicanconf.py.in index 351a5d222..73be94f31 100644 --- a/documentation/pelicanconf.py.in +++ b/documentation/pelicanconf.py.in @@ -18,6 +18,7 @@ STATIC_PATHS = [ 'pages/users-guide', 'pages/check-toolkit', 'pages/design-flow', 'pages/rds', + 'pages/technical-log', 'images', ] @@ -97,6 +98,8 @@ IGNORE_FILES = [ 'UsersGuide.rst' # For User's Guide. , 'DbU.rst' , 'Name.rst' + , 'December_2023.rst' # For Technical Logs + , 'Stratus.rst' # For Stratus. , 'Developper.rst' , 'DpGen.rst' From 8485f0b4266e5799b07837966cdfd597a602ff63 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 10 Jan 2024 17:32:50 +0100 Subject: [PATCH 15/51] The karakaze tool (AnalogDesign) was forgotten in the installation. This is pursing me! --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 2446ab5bf..342ac088b 100644 --- a/meson.build +++ b/meson.build @@ -111,10 +111,10 @@ subdir('katana') subdir('tramontana') subdir('equinox') subdir('solstice') -subdir('unicorn') subdir('oroshi') subdir('karakaze') subdir('bora') +subdir('unicorn') subdir('cumulus') subdir('tutorial') subdir('documentation') From 95b4577290fd85b6608c473c5b78cf98302151ab Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 6 Dec 2023 15:23:16 +0100 Subject: [PATCH 16/51] Make the left menu *not* overlap the page contents. --- documentation/themes/nest-coriolis/static/css/coriolis.css | 2 ++ 1 file changed, 2 insertions(+) diff --git a/documentation/themes/nest-coriolis/static/css/coriolis.css b/documentation/themes/nest-coriolis/static/css/coriolis.css index 012cf8c3d..5ded13d0a 100644 --- a/documentation/themes/nest-coriolis/static/css/coriolis.css +++ b/documentation/themes/nest-coriolis/static/css/coriolis.css @@ -63,6 +63,8 @@ div#contents { float: left; top: 260px; left: 20px; + width: 30%; + z-index: -1; } } From 983cf4b1c0ed42a84dce74ab974dbcacd0ddb3b2 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 6 Dec 2023 15:24:05 +0100 Subject: [PATCH 17/51] Add all the .rst page dependencies to meson.buil. --- documentation/content/pages/technical-log/December_2023.rst | 2 +- documentation/meson.build | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/documentation/content/pages/technical-log/December_2023.rst b/documentation/content/pages/technical-log/December_2023.rst index 0fef0586f..fc41d5bb6 100644 --- a/documentation/content/pages/technical-log/December_2023.rst +++ b/documentation/content/pages/technical-log/December_2023.rst @@ -23,7 +23,7 @@ Occured on ``benchs/RISC-V/Minerva/sky130_c4m/``. .. image:: {static}/images/notes/Katana-Debug_3.png :alt: Faulty _do_xG_1M3 (no South) configuration. :align: center - :width: 40% + :width: 60% |CHANGE| Reorganization of the size detection of ``RoutingPad`` diff --git a/documentation/meson.build b/documentation/meson.build index 4ab103ea6..83104b2b1 100644 --- a/documentation/meson.build +++ b/documentation/meson.build @@ -42,6 +42,7 @@ rstcontent = files( 'content/pages/stratus/Stratus_HTML.rst', 'content/pages/symbolic-layout.rst', 'content/pages/technical-log/TechnicalLog_HTML.rst', + 'content/pages/technical-log/December_2023.rst', 'content/pages/users-guide/Configuration.rst', 'content/pages/users-guide/DesignFlow.rst', 'content/pages/users-guide/Installation.rst', From 30861eb4e2e0658dd4e03935e2ab0cca408bd50a Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Mon, 18 Dec 2023 20:04:19 +0100 Subject: [PATCH 18/51] In GF180MCU techno, configuration now support HV or VH topologies. --- .../technos/node180/gf180mcu/mcu9t5v0.py | 33 +++++--- .../python/technos/node180/gf180mcu/techno.py | 82 +++++++++++++++---- 2 files changed, 84 insertions(+), 31 deletions(-) diff --git a/crlcore/python/technos/node180/gf180mcu/mcu9t5v0.py b/crlcore/python/technos/node180/gf180mcu/mcu9t5v0.py index 905df2a6d..79252dab9 100644 --- a/crlcore/python/technos/node180/gf180mcu/mcu9t5v0.py +++ b/crlcore/python/technos/node180/gf180mcu/mcu9t5v0.py @@ -17,7 +17,7 @@ __all__ = [ "setup" ] -def _routing (): +def _routing ( useHV ): """ Define the routing gauge along with the various P&R tool parameters. """ @@ -26,9 +26,15 @@ def _routing (): tech = db.getTechnology() rg = RoutingGauge.create('mcu9t5v0') rg.setSymbolic( False ) + if useHV: + dirM1 = RoutingLayerGauge.Vertical + dirM2 = RoutingLayerGauge.Horizontal + else: + dirM1 = RoutingLayerGauge.Horizontal + dirM2 = RoutingLayerGauge.Vertical rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer( 'Metal1' ) # metal - , RoutingLayerGauge.Vertical # preferred routing direction + , dirM1 # preferred routing direction , RoutingLayerGauge.PinOnly # layer usage , 0 # depth , 0.0 # density (deprecated) @@ -40,7 +46,7 @@ def _routing (): , u(0.0 ) )) # obstacle dW rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer( 'Metal2' ) # metal - , RoutingLayerGauge.Horizontal # preferred routing direction + , dirM2 # preferred routing direction , RoutingLayerGauge.Default # layer usage , 1 # depth , 0.0 # density (deprecated) @@ -52,7 +58,7 @@ def _routing (): , u(0.0 ) )) # obstacle dW rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer( 'Metal3' ) # metal - , RoutingLayerGauge.Vertical # preferred routing direction + , dirM1 # preferred routing direction , RoutingLayerGauge.Default # layer usage , 2 # depth , 0.0 # density (deprecated) @@ -64,7 +70,7 @@ def _routing (): , u(0.0 ) )) # obstacle dW rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer( 'Metal4' ) # metal - , RoutingLayerGauge.Horizontal # preferred routing direction + , dirM2 # preferred routing direction , RoutingLayerGauge.Default # layer usage , 3 # depth , 0.0 # density (deprecated) @@ -76,7 +82,7 @@ def _routing (): , u(0.0 ) )) # obstacle dW rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer( 'Metal5' ) # metal - , RoutingLayerGauge.Vertical # preferred routing direction + , dirM1 # preferred routing direction , RoutingLayerGauge.Default # layer usage , 4 # depth , 0.0 # density (deprecated) @@ -88,7 +94,7 @@ def _routing (): , u(0.0 ) )) # obstacle dW rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer( 'MetalTop' ) # metal - , RoutingLayerGauge.Horizontal # preferred routing direction + , dirM2 # preferred routing direction , RoutingLayerGauge.PowerSupply # layer usage , 5 # depth , 0.0 # density (deprecated) @@ -112,7 +118,7 @@ def _routing (): with CfgCache(priority=Cfg.Parameter.Priority.ConfigurationFile) as cfg: env = af.getEnvironment() - env.setRegister( '.*__dff.*' ) + env.setRegister( '.*_dff.*' ) # Place & Route setup cfg.viewer.minimumSize = 500 cfg.viewer.pixelThreshold = 2 @@ -162,8 +168,8 @@ def _routing (): cfg.anabatic.globalIterations = [ 1, 100 ] cfg.anabatic.gcell.displayMode = 1 cfg.anabatic.gcell.displayMode = (("Boundary", 1), ("Density", 2)) - cfg.anabatic.netBuilderStyle = 'HV,3RL+' - cfg.anabatic.routingStyle = StyleFlags.HV|StyleFlags.M1Offgrid + cfg.anabatic.netBuilderStyle = 'VH,3RL+' + cfg.anabatic.routingStyle = StyleFlags.VH|StyleFlags.M1Offgrid cfg.katana.disableStackedVias = False cfg.katana.hTracksReservedLocal = 4 cfg.katana.hTracksReservedLocal = [0, 20] @@ -302,7 +308,8 @@ def _loadStdLib ( cellsTop ): io.vprint( 2, ' (__file__="{}")'.format( os.path.abspath( __file__ ))) LefImport.load( (cellsTop / '..' / 'tech' / 'gf180mcu_6LM_1TM_9K_9t_tech.lef').as_posix() ) LefImport.setMergeLibrary( cellLib ) - LefImport.setPinFilter( u(0.26), u(0.84), LefImport.PinFilter_TALLEST ) + #LefImport.setPinFilter( u(0.84), u(0.26), LefImport.PinFilter_WIDEST ) + LefImport.setPinFilter( u(0.26), u(0.26), LefImport.PinFilter_WIDEST ) for cellDir in cellsTop.iterdir(): for lefFile in sorted(cellDir.glob('*.lef')): LefImport.load( lefFile.as_posix() ) @@ -322,7 +329,7 @@ def _loadIoLib (): , Gds.NoGdsPrefix ) -def setup ( cellsTop ): - _routing() +def setup ( cellsTop, useHV ): + _routing( useHV ) _loadStdLib( cellsTop ) #_loadIoLib() diff --git a/crlcore/python/technos/node180/gf180mcu/techno.py b/crlcore/python/technos/node180/gf180mcu/techno.py index 3eb541b1e..9dfee0145 100644 --- a/crlcore/python/technos/node180/gf180mcu/techno.py +++ b/crlcore/python/technos/node180/gf180mcu/techno.py @@ -15,7 +15,52 @@ __all__ = [ 'setup' ] -def _setup_techno(): +class VIAS ( object ): + """ + Create all the VIAs in the technology. The enclosures of the VIAs + are choosen according to the kind of routing gauge : HV or VH. + Be sure to make them coherent. + + The enclosure are given for the HV case. + + * Side : size of the *square* central cut (hole). + * BHE : Bottom Horizontal Enclosure. + * BVE : Bottom Vertical Enclosure. + * THE : Top Horizontal Enclosure. + * TVE : Top Vertical Enclosure. + """ + + # + # Name | BMetal | Cut | TMetal | Side| BHE | BVH | THE | TVE | + # 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | + ViaDatas = ( ( 'VIA12', 'Metal1', 'Via1', 'Metal2' , 0.22, 0.06, 0.00, 0.06, 0.01 ) + , ( 'VIA23', 'Metal2', 'Via2', 'Metal3' , 0.26, 0.06, 0.01, 0.01, 0.06 ) + , ( 'VIA34', 'Metal3', 'Via3', 'Metal4' , 0.26, 0.01, 0.06, 0.06, 0.01 ) + , ( 'VIA45', 'Metal4', 'Via4', 'Metal5' , 0.26, 0.06, 0.01, 0.01, 0.06 ) + , ( 'VIA5T', 'Metal5', 'Via5', 'MetalTop', 0.26, 0.01, 0.06, 0.06, 0.01 ) + ) + + def __init__ ( self, useHV ): + self.useHV = useHV + + def setup ( self, tech ): + if self.useHV: + bhindex = 5 + bvindex = 6 + thindex = 7 + tvindex = 8 + else: + bhindex = 6 + bvindex = 5 + thindex = 8 + tvindex = 7 + for datas in VIAS.ViaDatas: + VIA = createVia( tech, datas[0], datas[1], datas[2], datas[3], u(datas[4]) ) + setEnclosures( VIA, tech.getLayer(datas[1]), ( u(datas[bhindex]), u(datas[bvindex]) )) + setEnclosures( VIA, tech.getLayer(datas[3]), ( u(datas[thindex]), u(datas[tvindex]) )) + + +def _setup_techno( useHV ): io.vprint( 1, ' o Setup GF180MCU technology.' ) io.vprint( 2, ' (__file__="{}")'.format( os.path.abspath( __file__ ))) @@ -79,21 +124,22 @@ def _setup_techno(): CONT = createVia( tech, 'CONT_POLY2', 'Poly2', 'Contact', 'Metal1', u(0.22) ) setEnclosures( CONT, Poly2 , u(0.07) ) setEnclosures( CONT, Metal1, u(0.12) ) - VIA12 = createVia( tech, 'VIA12', 'Metal1', 'Via1', 'Metal2', u(0.26) ) - setEnclosures( VIA12, Metal1, (u(0.06), u(0.00)) ) - setEnclosures( VIA12, Metal2, (u(0.06), u(0.01)) ) - VIA23 = createVia( tech, 'VIA23', 'Metal2', 'Via2', 'Metal3', u(0.26) ) - setEnclosures( VIA23, Metal2, (u(0.06), u(0.01)) ) - setEnclosures( VIA23, Metal3, (u(0.01), u(0.06)) ) - VIA34 = createVia( tech, 'VIA34', 'Metal3', 'Via3', 'Metal4', u(0.26) ) - setEnclosures( VIA34, Metal3, (u(0.01), u(0.06)) ) - setEnclosures( VIA34, Metal4, (u(0.06), u(0.01)) ) - VIA45 = createVia( tech, 'VIA45', 'Metal4', 'Via4', 'Metal5', u(0.26) ) - setEnclosures( VIA45, Metal4, (u(0.06), u(0.01)) ) - setEnclosures( VIA45, Metal5, (u(0.01), u(0.06)) ) - VIA5T = createVia( tech, 'VIA5T', 'Metal5', 'Via5', 'MetalTop', u(0.26) ) - setEnclosures( VIA5T, Metal5 , (u(0.01), u(0.06)) ) - setEnclosures( VIA5T, MetalTop, (u(0.06), u(0.01)) ) + VIAS( useHV ).setup( tech ) + #VIA12 = createVia( tech, 'VIA12', 'Metal1', 'Via1', 'Metal2', u(0.26) ) + #setEnclosures( VIA12, Metal1, (u(0.06), u(0.00)) ) + #setEnclosures( VIA12, Metal2, (u(0.06), u(0.01)) ) + #VIA23 = createVia( tech, 'VIA23', 'Metal2', 'Via2', 'Metal3', u(0.26) ) + #setEnclosures( VIA23, Metal2, (u(0.06), u(0.01)) ) + #setEnclosures( VIA23, Metal3, (u(0.01), u(0.06)) ) + #VIA34 = createVia( tech, 'VIA34', 'Metal3', 'Via3', 'Metal4', u(0.26) ) + #setEnclosures( VIA34, Metal3, (u(0.01), u(0.06)) ) + #setEnclosures( VIA34, Metal4, (u(0.06), u(0.01)) ) + #VIA45 = createVia( tech, 'VIA45', 'Metal4', 'Via4', 'Metal5', u(0.26) ) + #setEnclosures( VIA45, Metal4, (u(0.06), u(0.01)) ) + #setEnclosures( VIA45, Metal5, (u(0.01), u(0.06)) ) + #VIA5T = createVia( tech, 'VIA5T', 'Metal5', 'Via5', 'MetalTop', u(0.26) ) + #setEnclosures( VIA5T, Metal5 , (u(0.01), u(0.06)) ) + #setEnclosures( VIA5T, MetalTop, (u(0.06), u(0.01)) ) Border = createBL( tech, 'Border', BasicLayer.Material.other, gds2Layer=63 ) @@ -307,8 +353,8 @@ def _setup_display(): Viewer.Graphics.setStyle( 'Alliance.Classic [black]' ) -def setup(): - _setup_techno() +def setup( useHV ): + _setup_techno( useHV ) _setup_display() try: from .techno_fix import fix From 3829a80635288fa33f0120094b1bcb6fb2492a20 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Mon, 18 Dec 2023 20:05:14 +0100 Subject: [PATCH 19/51] In LefParser::_pinStdPostProcess(), improved way to choose H/V. * Instead of choosing the kind of segments in accordance to the rounting gauge, use the form factor of the rectangle. --- crlcore/src/ccore/lefdef/LefImport.cpp | 28 ++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/crlcore/src/ccore/lefdef/LefImport.cpp b/crlcore/src/ccore/lefdef/LefImport.cpp index 6414d9ea9..c60af3f17 100644 --- a/crlcore/src/ccore/lefdef/LefImport.cpp +++ b/crlcore/src/ccore/lefdef/LefImport.cpp @@ -1033,14 +1033,26 @@ namespace { ); cdebug_log(100,0) << "| -> " << ongrids.back() << endl; #endif - ongrids.push_back( Vertical::create( rectilinear->getNet() - , rectilinear->getLayer() - , best.getXCenter() - , best.getWidth() - , best.getYMin() - , best.getYMax() - ) - ); + //if (gaugeMetal2->isHorizontal()) { + if (best.getWidth() < best.getHeight()) { + ongrids.push_back( Vertical::create( rectilinear->getNet() + , rectilinear->getLayer() + , best.getXCenter() + , best.getWidth() + , best.getYMin() + , best.getYMax() + ) + ); + } else { + ongrids.push_back( Horizontal::create( rectilinear->getNet() + , rectilinear->getLayer() + , best.getYCenter() + , best.getHeight() + , best.getXMin() + , best.getXMax() + ) + ); + } cdebug_log(100,0) << "| -> " << ongrids.back() << endl; } #if THIS_IS_DISABLED From 246fa6d25e65f6fa99a717161eba76f64e59bb5f Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Mon, 18 Dec 2023 20:07:25 +0100 Subject: [PATCH 20/51] In technos.setupGF180MCU_GF(), provide a flag to select HV or VH. --- cumulus/src/designflow/technos.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cumulus/src/designflow/technos.py b/cumulus/src/designflow/technos.py index 3976cfe3f..b70dd13ac 100644 --- a/cumulus/src/designflow/technos.py +++ b/cumulus/src/designflow/technos.py @@ -459,7 +459,7 @@ def setupTSMC_c180_c4m ( checkToolkit=None, ndaTop=None ): ShellEnv.CHECK_TOOLKIT = Where.checkToolkit.as_posix() -def setupGF180MCU_GF ( checkToolkit=None, pdkTop=None ): +def setupGF180MCU_GF ( checkToolkit=None, pdkTop=None, useHV=False ): from .. import Cfg from .. import Viewer from .. import CRL @@ -482,8 +482,8 @@ def setupGF180MCU_GF ( checkToolkit=None, pdkTop=None ): from coriolis.technos.node180.gf180mcu import techno from coriolis.technos.node180.gf180mcu import mcu9t5v0 - techno.setup() - mcu9t5v0.setup( cellsTop ) + techno.setup( useHV ) + mcu9t5v0.setup( cellsTop, useHV ) with overlay.CfgCache(priority=Cfg.Parameter.Priority.UserFile) as cfg: cfg.misc.catchCore = False @@ -496,7 +496,7 @@ def setupGF180MCU_GF ( checkToolkit=None, pdkTop=None ): cfg.misc.verboseLevel1 = False cfg.misc.verboseLevel2 = False cfg.etesian.graphics = 2 - cfg.anabatic.topRoutingLayer = 'm4' + cfg.anabatic.topRoutingLayer = 'Metal5' cfg.katana.eventsLimit = 4000000 af = CRL.AllianceFramework.get() #lg5 = af.getRoutingGauge( 'mcu9t' ).getLayerGauge( 5 ) From 04fde508a41d5f1aa22fc9967df65f1bc435ee05 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Mon, 18 Dec 2023 20:39:23 +0100 Subject: [PATCH 21/51] Support for offgrid M1 & VH topologies (WIP 1). * In AnabaticEngine::loadGlobalRouting(), call relaxOverConstraineds() only if M1 is vertical (may write another one for M1 horizontal). * In AnabaticEngine::computeEdgeCapacities(), don't complain for offgrid M1 if it is allowed... * In AutoContactTerminal::updateGeometry(), implement dragging on horizontal M1. * In AutoSegment::getExtensionCap(), manage the case when neither source nor target is requested. Return the bottom layer cap in that instance (for M1 terminals). * In AutoVertical::updatePositions(), on non-preferred segments, the extention must be further extendend as to include perpendiculars axis of tracks that we may impact. * In AutoHorizontal::updatePositions(), idem. * In Configuration::selectRpComponent(), detect M1 offgrid components and flag them. HSmall & VSmall are now forced to be flagged as *punctual*. * In NetBuilderHV, support for M1 offgrid terminals. Systematically use doRp_Accesss() and never call directly doRp_AutoContacts(). * In NetBuilderVH, general overhaul & bug fixes. * In RoutingPad, add a flag to tell that a component has been selected. * In RoutingPlane::getTrackByPosition(), add failsafe when we are before the first track axis or after the last. --- anabatic/src/AnabaticEngine.cpp | 8 +- anabatic/src/AutoContactTerminal.cpp | 21 +- anabatic/src/AutoHorizontal.cpp | 10 + anabatic/src/AutoSegment.cpp | 38 +-- anabatic/src/AutoVertical.cpp | 10 + anabatic/src/Configuration.cpp | 68 +++-- anabatic/src/NetBuilder.cpp | 5 +- anabatic/src/NetBuilderHV.cpp | 79 ++++-- anabatic/src/NetBuilderVH.cpp | 246 +++++++++++++++--- anabatic/src/anabatic/NetBuilderHV.h | 1 + anabatic/src/anabatic/NetBuilderVH.h | 42 +-- .../technos/node180/gf180mcu/mcu9t5v0.py | 16 +- .../content/images/notes/Katana-Debug_4.png | Bin 0 -> 169761 bytes .../content/images/notes/Katana-Debug_5.png | Bin 0 -> 120053 bytes .../content/images/notes/Katana-Debug_6.png | Bin 0 -> 166785 bytes .../content/images/notes/Katana-Debug_7.png | Bin 0 -> 145334 bytes .../content/images/notes/Katana-Debug_9.png | Bin 0 -> 115555 bytes .../pages/python-tutorial/definitions.rst | 3 +- .../pages/technical-log/December_2023.rst | 99 ++++++- documentation/etc/definitions.rst | 9 +- documentation/meson.build | 1 + .../themes/nest-coriolis/static/css/nest.css | 2 +- hurricane/src/hurricane/RoutingPad.cpp | 12 +- .../src/hurricane/hurricane/RoutingPad.h | 21 +- katana/src/NegociateWindow.cpp | 5 +- katana/src/PreProcess.cpp | 2 + katana/src/RoutingPlane.cpp | 8 +- katana/src/SegmentFsm.cpp | 2 + katana/src/Track.cpp | 22 +- katana/src/TrackElement.cpp | 9 +- katana/src/TrackSegment.cpp | 2 +- katana/src/TrackSegmentNonPref.cpp | 5 + 32 files changed, 584 insertions(+), 162 deletions(-) create mode 100755 documentation/content/images/notes/Katana-Debug_4.png create mode 100755 documentation/content/images/notes/Katana-Debug_5.png create mode 100755 documentation/content/images/notes/Katana-Debug_6.png create mode 100755 documentation/content/images/notes/Katana-Debug_7.png create mode 100755 documentation/content/images/notes/Katana-Debug_9.png diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index b0bbf16c1..2d650cde5 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -1177,7 +1177,10 @@ namespace Anabatic { } cleanupGlobal(); - if (not _configuration->isTwoMetals()) relaxOverConstraineds(); + if (not _configuration->isTwoMetals()) { + if (_configuration->getDirection((size_t)0) & Flags::Vertical) + relaxOverConstraineds(); + } _state = EngineActive; } @@ -1776,7 +1779,8 @@ namespace Anabatic { UpdateSession::open(); for ( auto rp : rps ) { - if (not _configuration->selectRpComponent(rp)) + bool offgrid = _configuration->selectRpComponent(rp); + if (not offgrid and not _configuration->isM1Offgrid()) cerr << Warning( "AnabaticEngine::computeEdgeCapacities(): %s has no components on grid.", getString(rp).c_str() ) << endl; Point center = rp->getBoundingBox().getCenter(); diff --git a/anabatic/src/AutoContactTerminal.cpp b/anabatic/src/AutoContactTerminal.cpp index c3a96fc46..3ef2c45fa 100644 --- a/anabatic/src/AutoContactTerminal.cpp +++ b/anabatic/src/AutoContactTerminal.cpp @@ -475,6 +475,25 @@ namespace Anabatic { setHeight( _segment->getContactWidth() ); } + if (canDrag()) { + AutoContact* opposite = _segment->getOppositeAnchor(this); + AutoSegment* perpandicular = opposite->getPerpandicular( _segment ); + if (perpandicular) { + cdebug_log(145,0) << "Draging H interval [" + << DbU::getValueString(getCBXMin()) << " " + << DbU::getValueString(getCBXMax()) << "]" << endl; + Point onGrid = Session::getNearestGridPoint( Point(perpandicular->getAxis(),getY()) + , getConstraintBox() ); + DbU::Unit x = onGrid.getX(); + x = std::min( x, getCBXMax() ); + x = std::max( x, getCBXMin() ); + setX( x ); + cdebug_log(145,0) << "Dragging to X @" << DbU::getValueString(x) + << " pitched:" << DbU::getValueString(onGrid.getX()) + << " " << getConstraintBox() << endl; + } + } + if (not getUConstraints(Flags::Vertical).contains(axis)) { cdebug_log(145,0) << "Cached: " << _segment << endl; message << "Terminal horizontal segment Y " << DbU::getValueString(axis) @@ -503,7 +522,7 @@ namespace Anabatic { AutoContact* opposite = _segment->getOppositeAnchor(this); AutoSegment* perpandicular = opposite->getPerpandicular( _segment ); if (perpandicular) { - cdebug_log(145,0) << "Draging V interval [" + cdebug_log(145,0) << "Dragging V interval [" << DbU::getValueString(getCBYMin()) << " " << DbU::getValueString(getCBYMax()) << "]" << endl; DbU::Unit y = perpandicular->getAxis(); diff --git a/anabatic/src/AutoHorizontal.cpp b/anabatic/src/AutoHorizontal.cpp index 3746a6981..77b8f3764 100644 --- a/anabatic/src/AutoHorizontal.cpp +++ b/anabatic/src/AutoHorizontal.cpp @@ -541,6 +541,11 @@ namespace Anabatic { { _sourcePosition = getSourceU() - getExtensionCap(Flags::Source); _targetPosition = getTargetU() + getExtensionCap(Flags::Target); + if (isNonPref()) { + DbU::Unit halfCap = getExtensionCap( Flags::NoFlags ); + _sourcePosition -= halfCap; + _targetPosition += halfCap; + } } @@ -562,6 +567,11 @@ namespace Anabatic { bool coherency = true; DbU::Unit sourcePosition = _horizontal->getSource()->getX() - getExtensionCap(Flags::Source); DbU::Unit targetPosition = _horizontal->getTarget()->getX() + getExtensionCap(Flags::Target); + if (isNonPref()) { + DbU::Unit halfCap = getExtensionCap( Flags::NoFlags ); + sourcePosition -= halfCap; + targetPosition += halfCap; + } if ( _sourcePosition != sourcePosition ) { cerr << "extensionCap: " << DbU::getValueString(getExtensionCap(Flags::Source)) << endl; diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index ac7d982e5..98653ab6e 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -789,23 +789,28 @@ namespace Anabatic { // cdebug_log(150,0) << "-> Custom cap (-duSource):" << DbU::getValueString(cap) << endl; } } - } - - if (flags & Flags::Target) { - if (getFlags() & SegTargetTop ) cap = getViaToTopCap (depth); - else if (getFlags() & SegTargetBottom) cap = getViaToBottomCap(depth); - else cap = getViaToSameCap (depth); - // cdebug_log(150,0) << "getExtensionCap(): (target) flags:" << getFlags() - // << " VIA cap:" << DbU::getValueString(cap) - // << " t:" << (getFlags() & SegSourceBottom) - // << " b:" << (getFlags() & SegSourceTop) - // << endl; - if (not (flags & Flags::NoSegExt)) { - // cdebug_log(150,0) << "duTarget=" << DbU::getValueString(getDuTarget()) << endl; - if (getDuTarget() > cap) { - cap = getDuTarget(); - // cdebug_log(150,0) << "-> Custom cap (+duTarget):" << DbU::getValueString(cap) << endl; + } else { + if (flags & Flags::Target) { + if (getFlags() & SegTargetTop ) cap = getViaToTopCap (depth); + else if (getFlags() & SegTargetBottom) cap = getViaToBottomCap(depth); + else cap = getViaToSameCap (depth); + // cdebug_log(150,0) << "getExtensionCap(): (target) flags:" << getFlags() + // << " VIA cap:" << DbU::getValueString(cap) + // << " t:" << (getFlags() & SegSourceBottom) + // << " b:" << (getFlags() & SegSourceTop) + // << endl; + if (not (flags & Flags::NoSegExt)) { + // cdebug_log(150,0) << "duTarget=" << DbU::getValueString(getDuTarget()) << endl; + if (getDuTarget() > cap) { + cap = getDuTarget(); + // cdebug_log(150,0) << "-> Custom cap (+duTarget):" << DbU::getValueString(cap) << endl; + } } + } else { + cap = getViaToBottomCap( depth ); + // cdebug_log(150,0) << "getExtensionCap(): (force bottom) flags:" << getFlags() + // << " VIA cap:" << DbU::getValueString(cap) + // << endl; } } @@ -823,6 +828,7 @@ namespace Anabatic { if (getLayer()->isSymbolic() and (cap < getWidth()/2)) cap = getWidth()/2; if (not (flags & Flags::LayerCapOnly)) cap += getLayer()->getMinimalSpacing()/2; + // cdebug_log(150,0) << "getExtensionCap(): cap=" << DbU::getValueString(cap) << endl; return cap; } diff --git a/anabatic/src/AutoVertical.cpp b/anabatic/src/AutoVertical.cpp index 790c0438a..1cc33294f 100644 --- a/anabatic/src/AutoVertical.cpp +++ b/anabatic/src/AutoVertical.cpp @@ -432,6 +432,11 @@ namespace Anabatic { { _sourcePosition = getSourceU() - getExtensionCap(Flags::Source); _targetPosition = getTargetU() + getExtensionCap(Flags::Target); + if (isNonPref()) { + DbU::Unit halfCap = getExtensionCap( Flags::NoFlags ); + _sourcePosition -= halfCap; + _targetPosition += halfCap; + } } @@ -453,6 +458,11 @@ namespace Anabatic { bool coherency = true; DbU::Unit sourcePosition = _vertical->getSource()->getY() - getExtensionCap(Flags::Source); DbU::Unit targetPosition = _vertical->getTarget()->getY() + getExtensionCap(Flags::Target); + if (isNonPref()) { + DbU::Unit halfCap = getExtensionCap( Flags::NoFlags ); + sourcePosition -= halfCap; + targetPosition += halfCap; + } if ( _sourcePosition != sourcePosition ) { cerr << Error ( "%s\n Source position incoherency: " diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index caf94f090..5610ef4c0 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.cpp @@ -20,6 +20,7 @@ #include "hurricane/configuration/Configuration.h" #include "hurricane/Warning.h" #include "hurricane/Error.h" +#include "hurricane/DebugSession.h" #include "hurricane/Technology.h" #include "hurricane/DataBase.h" #include "hurricane/BasicLayer.h" @@ -51,6 +52,7 @@ namespace Anabatic { using Hurricane::tab; using Hurricane::Warning; using Hurricane::Error; + using Hurricane::DebugSession; using Hurricane::Transformation; using Hurricane::Technology; using Hurricane::DataBase; @@ -464,11 +466,14 @@ namespace Anabatic { bool Configuration::selectRpComponent ( RoutingPad* rp ) const { + DebugSession::open( rp->getNet(), 112, 120 ); cdebug_log(112,1) << "selectRpComponent(): " << rp << endl; + //rp->setFlags( RoutingPad::SelectedComponent ); if (rp->isAtTopLevel()) { cdebug_log(112,0) << "> RP is at top level, must not change it." << endl; cdebug_tabw(112,-1); + DebugSession::close(); return true; } @@ -476,9 +481,17 @@ namespace Anabatic { #if BETTER_FOR_TSMC rp->setOnBestComponent( RoutingPad::BiggestArea ); cdebug_tabw(112,-1); + DebugSession::close(); return true; #else + if (rp->hasSelectedComponent()) { + cdebug_tabw(112,-1); + DebugSession::close(); + return not rp->isM1Offgrid(); + } + Box ab = rp->getCell()->getAbutmentBox(); + const Layer* via12 = getContactLayer( 0 ); const Layer* metal1 = getLayerGauge( 0 )->getLayer(); RoutingLayerGauge* gauge = getLayerGauge( 1 ); Occurrence occurrence = rp->getPlugOccurrence(); @@ -491,11 +504,15 @@ namespace Anabatic { if (current and (current->getLayer()->getMask() != metal1->getMask())) { cdebug_log(112,0) << "> using default non-metal1 segment." << endl; cdebug_tabw(112,-1); + DebugSession::close(); return true; } - DbU::Unit bestSpan = 0; - Component* bestComponent = NULL; + DbU::Unit bestSpan = 0; + Component* ongridComponent = NULL; + Component* offgridComponent = NULL; + DbU::Unit viaShrink = _rg->getViaWidth( (size_t)0 ) / 2 + + via12->getBottomEnclosure( Layer::EnclosureH ); cdebug_log(112,0) << "Looking into: " << masterNet->getCell() << endl; for ( Component* component : masterNet->getComponents() ) { @@ -507,7 +524,7 @@ namespace Anabatic { if (dynamic_cast(component)) { cdebug_log(112,0) << " Pins are always considered best candidates:" << component << endl; - bestComponent = component; + ongridComponent = component; break; } @@ -523,6 +540,7 @@ namespace Anabatic { DbU::Unit minPos = DbU::Max; DbU::Unit maxPos = DbU::Min; + bb.inflate( -viaShrink ); if (gauge->isVertical()) { trackPos = gauge->getTrackPosition( ab.getXMin() , ab.getXMax() @@ -532,8 +550,8 @@ namespace Anabatic { maxPos = bb.getXMax(); cdebug_log(112,0) << "Vertical gauge: " << gauge << endl; - cdebug_log(112,0) << "ab.getXMin(): " << DbU::getValueString(bb.getXMin()) << endl; - cdebug_log(112,0) << "ab.getXMax(): " << DbU::getValueString(bb.getXMax()) << endl; + cdebug_log(112,0) << "ab.getXMin(): " << DbU::getValueString(ab.getXMin()) << endl; + cdebug_log(112,0) << "ab.getXMax(): " << DbU::getValueString(ab.getXMax()) << endl; cdebug_log(112,0) << "bb.getCenter(): " << DbU::getValueString(bb.getCenter().getX()) << endl; } else { trackPos = gauge->getTrackPosition( ab.getYMin() @@ -544,8 +562,8 @@ namespace Anabatic { maxPos = bb.getYMax(); cdebug_log(112,0) << "Horizontal gauge: " << gauge << endl; - cdebug_log(112,0) << "ab.getYMin(): " << DbU::getValueString(bb.getYMin()) << endl; - cdebug_log(112,0) << "ab.getYMax(): " << DbU::getValueString(bb.getYMax()) << endl; + cdebug_log(112,0) << "ab.getYMin(): " << DbU::getValueString(ab.getYMin()) << endl; + cdebug_log(112,0) << "ab.getYMax(): " << DbU::getValueString(ab.getYMax()) << endl; cdebug_log(112,0) << "bb.getCenter(): " << DbU::getValueString(bb.getCenter().getY()) << endl; } @@ -553,25 +571,39 @@ namespace Anabatic { cdebug_log(112,0) << "| " << transformation << endl; cdebug_log(112,0) << "| " << bb << " of:" << candidate << endl; cdebug_log(112,0) << "| Nearest Pos: " << DbU::getValueString(trackPos) << endl; + cdebug_log(112,0) << "| " << DbU::getValueString(minPos) << " < trackPos < " + << DbU::getValueString(maxPos) << endl; if ( (trackPos >= minPos) and (trackPos <= maxPos) ) { - if (not bestComponent or (bestSpan < maxPos-minPos)) { - bestComponent = component; - bestSpan = maxPos - minPos; + if (not ongridComponent or (bestSpan < maxPos-minPos)) { + ongridComponent = component; + bestSpan = maxPos - minPos; } + } else { + cdebug_log(112,0) << "Component is offgrid." << endl; + offgridComponent = candidate; } } bool rvalue = false; - if (bestComponent) { - rp->setExternalComponent( bestComponent ); - cdebug_log(112,0) << "Using best candidate:" << bestComponent << endl; - cdebug_tabw(112,-1); + if (ongridComponent) { + rp->setExternalComponent( ongridComponent ); + cdebug_log(112,0) << "Using best candidate:" << ongridComponent << endl; rvalue = true; + } else { + if (not offgridComponent) + throw Error( "Configuration::selectRpComponent(): On %s,\n" + " No suitable external component found." + , getString(rp).c_str() + ); + rp->setExternalComponent( offgridComponent ); + rp->setFlags( RoutingPad::M1Offgrid ); + cdebug_log(112,0) << "Using offgrid candidate:" << offgridComponent << endl; } checkRoutingPadSize( rp ); cdebug_tabw(112,-1); + DebugSession::close(); return rvalue; #endif } @@ -624,11 +656,11 @@ namespace Anabatic { uint64_t flags = 0; flags |= (width < 3*getPitch(rpDepth)) ? RoutingPad::HSmall : 0; flags |= (height < 3*getPitch(rpDepth)) ? RoutingPad::VSmall : 0; - flags |= ((width == 0) && (height == 0)) ? RoutingPad::Punctual : 0; - //if ((flags & RoutingPad::HSmall) and (flags & RoutingPad::VSmall)) - // flags |= RoutingPad::Punctual; + //flags |= ((width == 0) && (height == 0)) ? RoutingPad::Punctual : 0; + if ((flags & RoutingPad::HSmall) and (flags & RoutingPad::VSmall)) + flags |= RoutingPad::Punctual; - rp->unsetFlags( RoutingPad::SizeFlags ); + rp->unsetFlags( RoutingPad::HSmall|RoutingPad::VSmall|RoutingPad::Punctual ); rp->setFlags ( flags ); cdebug_log(145,0) << "::checkRoutingPadSize(): pitch[" << rpDepth << "]:" << DbU::getValueString(getPitch(rpDepth)) << " " diff --git a/anabatic/src/NetBuilder.cpp b/anabatic/src/NetBuilder.cpp index 3bcff2158..1fcb5be86 100644 --- a/anabatic/src/NetBuilder.cpp +++ b/anabatic/src/NetBuilder.cpp @@ -1196,7 +1196,10 @@ namespace Anabatic { bool NetBuilder::_do_1G_1M1_1PinM3 () { - throw Error ( "%s::_do_1G_1M1_1PinM3() method *not* reimplemented from base class.", getTypeName().c_str() ); + throw Error ( "%s::_do_1G_1M1_1PinM3() method *not* reimplemented from base class.\n" + " On %s" + , getTypeName().c_str() + , getString(getNet()).c_str() ); return false; } diff --git a/anabatic/src/NetBuilderHV.cpp b/anabatic/src/NetBuilderHV.cpp index d5fe342ca..ebf7d4199 100644 --- a/anabatic/src/NetBuilderHV.cpp +++ b/anabatic/src/NetBuilderHV.cpp @@ -245,6 +245,10 @@ namespace Anabatic { AutoContact* NetBuilderHV::doRp_Access ( GCell* gcell, RoutingPad* rp, uint64_t flags ) { cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl; + if (rp->isM1Offgrid()) { + cdebug_tabw(145,-1); + return doRp_AccessOffgrid( gcell, rp, flags ); + } size_t rpDepth = Session::getLayerDepth( rp->getLayer() ); AutoContact* rpSourceContact = NULL; @@ -362,6 +366,39 @@ namespace Anabatic { } + AutoContact* NetBuilderHV::doRp_AccessOffgrid ( GCell* gcell, RoutingPad* rp, uint64_t flags ) + { + cdebug_log(145,1) << getTypeName() << "::doRp_AccessOffgrid() - flags:" << flags << endl; + + size_t rpDepth = Session::getLayerDepth( rp->getLayer() ); + AutoContact* rpSourceContact = NULL; + AutoContact* rpContactTarget = NULL; + doRp_AutoContacts( gcell, rp, rpSourceContact, rpContactTarget, flags ); + + AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getBuildRoutingLayer(rpDepth+1) ); + AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical|Flags::UseNonPref ); + rpSourceContact = subContact1; + + subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getBuildContactLayer(rpDepth+1) ); + AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal ); + rpSourceContact = subContact1; + + subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getBuildContactLayer(rpDepth+1) ); + AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical ); + rpSourceContact = subContact1; + + if (not (flags & HAccess)) { + subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getBuildContactLayer(rpDepth+1) ); + AutoSegment::create( rpSourceContact, subContact1, Flags::Horizontal ); + rpSourceContact = subContact1; + } + + cdebug_tabw(145,-1); + + return rpSourceContact; + } + + AutoContact* NetBuilderHV::doRp_AccessNorthSouthPin ( GCell* gcell, RoutingPad* rp ) { cdebug_log(145,1) << getTypeName() << "::doRp_AccessNorthSouthPin() " << rp << endl; @@ -1335,17 +1372,19 @@ namespace Anabatic { uint64_t flags = checkRoutingPadSize( getRoutingPads()[0] ); if (flags & VSmall) { - doRp_AutoContacts( getGCell(), getRoutingPads()[0], contact1, contact2, NoFlags ); - //contact1 = doRp_Access( getGCell(), getRoutingPads()[0], NoFlags ); + //doRp_AutoContacts( getGCell(), getRoutingPads()[0], contact1, contact2, NoFlags ); + contact1 = doRp_Access( getGCell(), getRoutingPads()[0], NoFlags ); contact2 = AutoContactHTee::create( getGCell(), getNet(), viaLayer1 ); AutoSegment::create( contact1, contact2, Flags::Vertical ); setBothCornerContacts( contact2 ); } else { - doRp_AutoContacts( getGCell(), getRoutingPads()[0], contact1, contact2, NoFlags ); + //doRp_AutoContacts( getGCell(), getRoutingPads()[0], contact1, contact2, NoFlags ); + contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess ); setSouthWestContact( contact1 ); - doRp_AutoContacts( getGCell(), getRoutingPads()[0], contact1, contact2, NoFlags ); + //doRp_AutoContacts( getGCell(), getRoutingPads()[0], contact1, contact2, NoFlags ); + contact1 = doRp_Access( getGCell(), getRoutingPads()[0], HAccess ); setNorthEastContact( contact1 ); } } else { @@ -2023,28 +2062,24 @@ namespace Anabatic { AutoContact* target = NULL; for ( size_t irp=1 ; irpgetUConstraints(Flags::Vertical).intersect(target->getUConstraints(Flags::Vertical))) { uint64_t flags = checkRoutingPadSize( rpM1s[irp-1] ); - if ((flags & VSmall) or Session::getConfiguration()->isVH()) { - if (Session::getConfiguration()->isHV()) { - turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() ); - AutoSegment::create( source, turn1, Flags::Horizontal ); - source = turn1; - } + if (flags & VSmall) { + turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() ); + AutoSegment::create( source, turn1, Flags::Horizontal ); + source = turn1; turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() ); AutoSegment::create( source, turn1 , Flags::Vertical ); source = turn1; } flags = checkRoutingPadSize( rpM1s[irp] ); - if ((flags & VSmall) or Session::getConfiguration()->isVH()) { - if (Session::getConfiguration()->isHV()) { - turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() ); - AutoSegment::create( target, turn1, Flags::Horizontal ); - target = turn1; - } + if (flags & VSmall) { + turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() ); + AutoSegment::create( target, turn1, Flags::Horizontal ); + target = turn1; turn1 = AutoContactTurn::create( gcell1, rpM1s[irp]->getNet(), Session::getDContactLayer() ); AutoSegment::create( target, turn1 , Flags::Vertical ); target = turn1; @@ -2060,8 +2095,8 @@ namespace Anabatic { } if (rpM2) { - doRp_AutoContacts( gcell1, rpM1s[0], source, turn1, DoSourceContact ); - doRp_AutoContacts( gcell1, rpM2 , target, turn1, DoSourceContact ); + source = doRp_Access( gcell1, rpM1s[0], HAccess ); + target = doRp_Access( gcell1, rpM2 , HAccess ); turn1 = AutoContactTurn::create( gcell1, rpM2->getNet(), Session::getBuildContactLayer(1) ); AutoSegment::create( source, turn1 , Flags::Horizontal ); AutoSegment::create( turn1 , target, Flags::Vertical ); @@ -2073,7 +2108,7 @@ namespace Anabatic { if ( (pinDir == Pin::AccessDirection::NORTH) or (pinDir == Pin::AccessDirection::SOUTH) ) { - doRp_AutoContacts( gcell1, rpM1s[0], source, turn1, DoSourceContact ); + source = doRp_Access( gcell1, rpM1s[0], HAccess ); target = doRp_AccessNorthSouthPin( gcell1, rpPin ); turn1 = AutoContactTurn::create( gcell1, rpPin->getNet(), Session::getBuildContactLayer(1) ); AutoSegment::create( source, turn1 , Flags::Horizontal ); @@ -2084,7 +2119,7 @@ namespace Anabatic { if (pinDir == Pin::AccessDirection::EAST) closest = rpM1s.back(); else closest = rpM1s.front(); - doRp_AutoContacts( gcell1, closest, source, turn1, DoSourceContact ); + source = doRp_Access( gcell1, closest, HAccess ); target = doRp_AccessEastWestPin( gcell1, rpPin ); AutoSegment::create( source, target , Flags::Horizontal ); } diff --git a/anabatic/src/NetBuilderVH.cpp b/anabatic/src/NetBuilderVH.cpp index a0ddf4f81..cbf83c609 100644 --- a/anabatic/src/NetBuilderVH.cpp +++ b/anabatic/src/NetBuilderVH.cpp @@ -188,37 +188,47 @@ namespace Anabatic { size_t rpDepth = Session::getLayerDepth( rp->getLayer() ); flags |= checkRoutingPadSize( rp ); - doRp_AutoContacts( gcell, rp, rpContactSource, rpContactTarget, flags ); + const Layer* viaLayer1 = Session::getBuildContactLayer( 1 ); + + if (rp->isM1Offgrid() or (flags & HSmall)) { + AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getBuildRoutingLayer(rpDepth+1) ); + AutoSegment::create( rpContactSource, subContact1, Flags::Horizontal|Flags::UseNonPref ); + rpContactSource = subContact1; + } - if (rpDepth % 2 == 0) { // RP should be vertical (M1, M3). + cdebug_log(145,0) << "rpDepth=" << rpDepth << endl; + if (rpDepth % 2 == 0) { // RP should be horizontal (M1, M3). if (not (flags & (HAccess|HAccessEW))) { - AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) ); - AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) ); - AutoSegment::create( rpContactSource, subContact1, Flags::Vertical , rpDepth+2 ); - AutoSegment::create( subContact1, subContact2, Flags::Horizontal, rpDepth+1 ); + cdebug_log(145,0) << "case not(HAccess|HAccessEW)" << endl; + AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), viaLayer1 ); + AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), viaLayer1 ); + AutoSegment::create( rpContactSource, subContact1, Flags::Vertical ); + AutoSegment::create( subContact1, subContact2, Flags::Horizontal); rpContactSource = subContact2; } else { if (flags & VSmall) { + cdebug_log(145,0) << "case VSmall" << endl; AutoContact* subContact1 = NULL; if (flags & HAccessEW) - subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) ); + subContact1 = AutoContactHTee::create( gcell, rp->getNet(), viaLayer1 ); else - subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) ); + subContact1 = AutoContactTurn::create( gcell, rp->getNet(), viaLayer1 ); AutoSegment::create( rpContactSource, subContact1, Flags::Vertical ); rpContactSource = subContact1; } } - } else { // RP should be horizontal (M2). + } else { // RP should be vertical (M2). if (flags & (HAccess|HAccessEW)) { + cdebug_log(145,0) << "case HAccess|HAccessEW" << endl; AutoContact* subContact1 = NULL; if (flags & HAccessEW) - subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) ); + subContact1 = AutoContactHTee::create( gcell, rp->getNet(), viaLayer1 ); else - subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) ); + subContact1 = AutoContactTurn::create( gcell, rp->getNet(), viaLayer1 ); - AutoSegment::create( rpContactSource, subContact1, Flags::Vertical, rpDepth+1 ); + AutoSegment::create( rpContactSource, subContact1, Flags::Vertical ); rpContactSource = subContact1; } } @@ -229,6 +239,80 @@ namespace Anabatic { } + AutoContact* NetBuilderVH::doRp_AccessNorthSouthPin ( GCell* gcell, RoutingPad* rp ) + { + cdebug_log(145,1) << getTypeName() << "::doRp_AccessNorthSouthPin() " << rp << endl; + + AutoContact* rpSourceContact = NULL; + AutoContact* rpContactTarget = NULL; + AutoContact* turn = NULL; + + doRp_AutoContacts( gcell, rp, rpSourceContact, rpContactTarget, NoProtect ); + + Net* net = rp->getNet(); + Pin* pin = dynamic_cast( rp->getOccurrence().getEntity() ); + Pin::AccessDirection pinDir = pin->getAccessDirection(); + if (pinDir == Pin::AccessDirection::NORTH) { + turn = AutoContactTurn::create( gcell, net, Session::getBuildRoutingLayer(1) ); + AutoSegment* segment = AutoSegment::create( rpSourceContact, turn, Flags::Vertical ); + segment->setAxis( rp->getX(), Flags::Force ); + segment->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis ); + rpSourceContact = turn; + + turn = AutoContactTurn::create( gcell, net, Session::getBuildContactLayer(1) ); + segment = AutoSegment::create( rpSourceContact, turn, Flags::Horizontal ); + rpSourceContact = 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 = rpSourceContact; + } + + cdebug_tabw(145,-1); + return turn; + } + + + AutoContact* NetBuilderVH::doRp_AccessEastWestPin ( GCell* gcell, RoutingPad* rp ) + { + cdebug_log(145,1) << getTypeName() << "::doRp_AccessEastWestPin() " << rp << endl; + + Net* net = rp->getNet(); + Pin* pin = dynamic_cast( rp->getOccurrence().getEntity() ); + Pin::AccessDirection pinDir = pin->getAccessDirection(); + AutoContact* rpSourceContact = NULL; + AutoContact* rpContactTarget = NULL; + AutoContact* turn = NULL; + AutoSegment* segment = NULL; + + doRp_AutoContacts( gcell, rp, rpSourceContact, rpContactTarget, NoProtect ); + + turn = AutoContactTurn::create( gcell, net, Session::getBuildContactLayer(1) ); + segment = AutoSegment::create( rpSourceContact, turn, Flags::Horizontal ); + segment->setAxis( pin->getCenter().getY(), Flags::Force ); + + rpSourceContact = turn; + turn = AutoContactTurn::create( gcell, net, Session::getBuildContactLayer(1) ); + segment = AutoSegment::create( rpSourceContact, 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 NetBuilderVH::_do_1G_1PinM2 () { cdebug_log(145,1) << getTypeName() << "::_do_1G_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl; @@ -401,21 +485,23 @@ namespace Anabatic { cdebug_log(145,0) << "east: " << east() << endl; cdebug_log(145,0) << "west: " << west() << endl; - AutoContact* tee = NULL; - if (east() and west()) { - tee = doRp_Access( getGCell(), getRoutingPads()[0], HAccessEW|VSmall ); + AutoContact* tee = doRp_Access( getGCell(), getRoutingPads()[0], HAccessEW|VSmall ); + setBothCornerContacts( tee ); + } else if (north() and south()) { + AutoContact* tee = doRp_Access( getGCell(), getRoutingPads()[0], HAccessEW|VSmall ); + AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getDContactLayer() ); + AutoContact* turn2 = AutoContactTurn::create( getGCell(), getNet(), Session::getDContactLayer() ); + AutoSegment::create( turn1, tee, Flags::Horizontal ); + AutoSegment::create( turn2, tee, Flags::Horizontal ); + setSouthWestContact( turn1 ); + setNorthEastContact( turn2 ); } else { AutoContact* turn = doRp_Access( getGCell(), getRoutingPads()[0], HAccess|VSmall ); - - if (east() or west()) - tee = AutoContactHTee::create( getGCell(), getNet(), Session::getDContactLayer() ); - else - tee = AutoContactVTee::create( getGCell(), getNet(), Session::getDContactLayer() ); - + AutoContact* tee = AutoContactHTee::create( getGCell(), getNet(), Session::getDContactLayer() ); AutoSegment::create( turn, tee, Flags::Horizontal ); + setBothCornerContacts( tee ); } - setBothCornerContacts( tee ); cdebug_tabw(145,-1); return true; @@ -494,6 +580,65 @@ namespace Anabatic { return true; } + bool NetBuilderVH::_do_1G_1M1_1PinM3 () + { + cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1_1PinM3() [Delegated] " << getTopology() << endl; + bool rvalue = false; + rvalue = NetBuilderVH::_do_1G_xM1_1PinM3 (); + cdebug_tabw(145,-1); + return rvalue; + } + + + bool NetBuilderVH::_do_1G_xM1_1PinM3 () + { + cdebug_log(145,1) << getTypeName() << "::_do_1G_xM1_1PinM3() [Managed Configuration - Optimized] " << getTopology() << endl; + + sortRpByX( getRoutingPads(), NoFlags ); // increasing X. + + vector rpsM1; + RoutingPad* pinM3 = NULL; + for ( RoutingPad* rp : getRoutingPads() ) { + if (dynamic_cast(rp->getOccurrence().getEntity())) pinM3 = rp; + else rpsM1.push_back( rp ); + } + + for ( size_t i=1 ; i rps; + vector rpM1s; + RoutingPad* rpPin = NULL; for ( RoutingPad* rp : net->getRoutingPads() ) { + if (dynamic_cast(rp->getOccurrence().getEntity())) { + rpPin = rp; + continue; + } if (Session::getRoutingGauge()->getLayerDepth(rp->getLayer()) == 0) { - rps.push_back( rp ); + rpM1s.push_back( rp ); continue; } cerr << Error( "%s::singleGCell(): Non metal1 terminals are not managed yet.\n" @@ -591,16 +741,17 @@ namespace Anabatic { return; } - if (rps.size() < 2) { - cerr << Error( "%s::singleGCell(): For %s, less than two Plugs/Pins (%d)." + if (rpM1s.size() + ((rpPin)?1:0) < 2) { + cerr << Error( "%s::singleGCell(): For %s, less than two Plugs/Pins (%d+%d)." , getTypeName().c_str() , getString(net).c_str() - , rps.size() ) << endl; + , rpM1s.size() + , (rpPin?1:0) ) << endl; cdebug_tabw(145,-1); return; } - if (rps.empty()) { + if (rpM1s.empty()) { cerr << Error( "%s::singleGCell(): No terminals for Net \"%s\"." , getTypeName().c_str() , getString(net->getName()).c_str() ) << endl; @@ -608,22 +759,22 @@ namespace Anabatic { return; } - sortRpByX( rps, NetBuilder::NoFlags ); // increasing X. + sortRpByX( rpM1s, NetBuilder::NoFlags ); // increasing X. - GCell* gcell1 = anbt->getGCellUnder( (*rps.begin ())->getCenter() ); - GCell* gcell2 = anbt->getGCellUnder( (*rps.rbegin())->getCenter() ); + GCell* gcell1 = anbt->getGCellUnder( (*rpM1s.begin ())->getCenter() ); + GCell* gcell2 = anbt->getGCellUnder( (*rpM1s.rbegin())->getCenter() ); if (not gcell1) { cerr << Error( "%s::singleGCell(): No GCell under %s." , getTypeName().c_str() - , getString(*(rps.begin())).c_str() ) << endl; + , getString(*(rpM1s.begin())).c_str() ) << endl; cdebug_tabw(145,-1); return; } if (gcell1 != gcell2) { cerr << Error( "%s::singleGCell(): Not under a single GCell %s." , getTypeName().c_str() - , getString(*(rps.rbegin())).c_str() ) << endl; + , getString(*(rpM1s.rbegin())).c_str() ) << endl; cdebug_tabw(145,-1); return; } @@ -633,12 +784,35 @@ namespace Anabatic { AutoContact* source = NULL; AutoContact* target = NULL; - for ( size_t irp=1 ; irp( rpPin->getOccurrence().getEntity() ); + Pin::AccessDirection pinDir = pin->getAccessDirection(); + + if ( (pinDir == Pin::AccessDirection::NORTH) + or (pinDir == Pin::AccessDirection::SOUTH) ) { + source = doRp_Access( gcell1, rpM1s[0], HAccess ); + target = doRp_AccessNorthSouthPin( gcell1, rpPin ); + AutoContact* turn1 = AutoContactTurn::create( gcell1, rpPin->getNet(), Session::getBuildContactLayer(1) ); + AutoSegment::create( source, turn1 , Flags::Horizontal ); + AutoSegment::create( turn1 , target, Flags::Vertical ); + } else { + RoutingPad* closest = NULL; + + if (pinDir == Pin::AccessDirection::EAST) closest = rpM1s.back(); + else closest = rpM1s.front(); + + source = doRp_Access( gcell1, closest, HAccess ); + target = doRp_AccessEastWestPin( gcell1, rpPin ); + AutoSegment::create( source, target, Flags::Horizontal ); + } + } + cdebug_tabw(145,-1); } diff --git a/anabatic/src/anabatic/NetBuilderHV.h b/anabatic/src/anabatic/NetBuilderHV.h index 96096b8ec..1f72745cf 100644 --- a/anabatic/src/anabatic/NetBuilderHV.h +++ b/anabatic/src/anabatic/NetBuilderHV.h @@ -31,6 +31,7 @@ namespace Anabatic { static std::string getStyle (); virtual void doRp_AutoContacts ( GCell*, RoutingPad*, AutoContact*& source, AutoContact*& target, uint64_t flags ); virtual AutoContact* doRp_Access ( GCell*, RoutingPad*, uint64_t flags ); + AutoContact* doRp_AccessOffgrid ( GCell*, RoutingPad*, uint64_t flags ); AutoContact* doRp_AccessNorthSouthPin ( GCell*, RoutingPad* ); AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* ); private: diff --git a/anabatic/src/anabatic/NetBuilderVH.h b/anabatic/src/anabatic/NetBuilderVH.h index 70728a872..a7b8d8e53 100644 --- a/anabatic/src/anabatic/NetBuilderVH.h +++ b/anabatic/src/anabatic/NetBuilderVH.h @@ -25,26 +25,30 @@ namespace Anabatic { class NetBuilderVH : public NetBuilder { public: - NetBuilderVH (); - virtual ~NetBuilderVH (); - static std::string getStyle (); - virtual void doRp_AutoContacts ( GCell*, RoutingPad*, AutoContact*& source, AutoContact*& target, uint64_t flags ); - virtual AutoContact* doRp_Access ( GCell*, RoutingPad*, uint64_t flags ); + NetBuilderVH (); + virtual ~NetBuilderVH (); + static std::string getStyle (); + virtual void doRp_AutoContacts ( GCell*, RoutingPad*, AutoContact*& source, AutoContact*& target, uint64_t flags ); + virtual AutoContact* doRp_Access ( GCell*, RoutingPad*, uint64_t flags ); + AutoContact* doRp_AccessNorthSouthPin ( GCell*, RoutingPad* ); + AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* ); private: - virtual bool _do_1G_1PinM2 (); - virtual bool _do_xG_1PinM2 (); - virtual bool _do_1G_1PinM3 (); - virtual bool _do_xG_1PinM3 (); - virtual bool _do_1G_1M1 (); - virtual bool _do_1G_xM1 (); - virtual bool _do_2G_1M1 (); - virtual bool _do_xG_xM1_xM3 (); - virtual bool _do_xG (); - virtual bool _do_2G (); - virtual bool _do_globalSegment (); - virtual void singleGCell ( AnabaticEngine*, Net* ); - public: - virtual string getTypeName () const; + virtual bool _do_1G_1PinM2 (); + virtual bool _do_xG_1PinM2 (); + virtual bool _do_1G_1PinM3 (); + virtual bool _do_xG_1PinM3 (); + virtual bool _do_1G_1M1 (); + virtual bool _do_1G_xM1 (); + virtual bool _do_2G_1M1 (); + virtual bool _do_xG_xM1_xM3 (); + virtual bool _do_1G_1M1_1PinM3 (); + virtual bool _do_xG (); + virtual bool _do_2G (); + virtual bool _do_globalSegment (); + virtual void singleGCell ( AnabaticEngine*, Net* ); + bool _do_1G_xM1_1PinM3 (); + public: + virtual string getTypeName () const; }; diff --git a/crlcore/python/technos/node180/gf180mcu/mcu9t5v0.py b/crlcore/python/technos/node180/gf180mcu/mcu9t5v0.py index 79252dab9..cc8d7bfb2 100644 --- a/crlcore/python/technos/node180/gf180mcu/mcu9t5v0.py +++ b/crlcore/python/technos/node180/gf180mcu/mcu9t5v0.py @@ -27,11 +27,15 @@ def _routing ( useHV ): rg = RoutingGauge.create('mcu9t5v0') rg.setSymbolic( False ) if useHV: - dirM1 = RoutingLayerGauge.Vertical - dirM2 = RoutingLayerGauge.Horizontal + dirM1 = RoutingLayerGauge.Vertical + dirM2 = RoutingLayerGauge.Horizontal + netBuilderStyle = 'HV,3RL+' + routingStyle = StyleFlags.HV|StyleFlags.M1Offgrid else: - dirM1 = RoutingLayerGauge.Horizontal - dirM2 = RoutingLayerGauge.Vertical + dirM1 = RoutingLayerGauge.Horizontal + dirM2 = RoutingLayerGauge.Vertical + netBuilderStyle = 'VH,3RL+' + routingStyle = StyleFlags.VH|StyleFlags.M1Offgrid rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer( 'Metal1' ) # metal , dirM1 # preferred routing direction @@ -168,8 +172,8 @@ def _routing ( useHV ): cfg.anabatic.globalIterations = [ 1, 100 ] cfg.anabatic.gcell.displayMode = 1 cfg.anabatic.gcell.displayMode = (("Boundary", 1), ("Density", 2)) - cfg.anabatic.netBuilderStyle = 'VH,3RL+' - cfg.anabatic.routingStyle = StyleFlags.VH|StyleFlags.M1Offgrid + cfg.anabatic.netBuilderStyle = netBuilderStyle + cfg.anabatic.routingStyle = routingStyle cfg.katana.disableStackedVias = False cfg.katana.hTracksReservedLocal = 4 cfg.katana.hTracksReservedLocal = [0, 20] diff --git a/documentation/content/images/notes/Katana-Debug_4.png b/documentation/content/images/notes/Katana-Debug_4.png new file mode 100755 index 0000000000000000000000000000000000000000..9fcb6a8117741ac1d9b5afaafa1f7db1f850b86e GIT binary patch literal 169761 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 B>r?;$ literal 0 HcmV?d00001 diff --git a/documentation/content/images/notes/Katana-Debug_5.png b/documentation/content/images/notes/Katana-Debug_5.png new file mode 100755 index 0000000000000000000000000000000000000000..dd6fa7cbc51e5d3027238296cbdd01e68f0514a1 GIT binary patch literal 120053 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

    Ia{eW_MAMa45BA~=+alcT*< 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�l+n2P*k3EvFP8 zPI4GSN|x*$dZe8=;Tbf9x?%`JNu>4`JyUwsa&b68rAT}flF}>|jH0bRxKj-vt6~PX zsc0RDjjS=$HiaZyW?=hF?3AcDGPti8WeMczbH)js0C=w za3uJHY%SnV3)1kM8%OMFVnyphE|a zp}qj!9n6n{v*0oKvRL=x^Qijonjzox-{(^jx{;U_G<(}ahS1tGzemn|hM;w5k-)s^ zg^?mzOBOYOh>2G%=+EMeI~&*U9n-tggYv{?+oP(2m7~qbLEvFh-#iww=Nlb52OP}J zQeWrH+x3EM@enI`9k2;M@WD+B1$LGEnFumZTQ0AO)|HXmx^?Toqv>&){B@dL)#5;H zn)@C{=>~pi9@&nG2gL<;<#JBpix)4df2k=D{H=9Lao**DsdZ=~l6>pDdR7l8#t##Q zogKe4uZ_spLieKuU`_B8q?;7iE zPZk`>c_LmhJ*(q_d*uEDP0dZ&CYQhZcG~mbOuqG4J!OjZt%9GgT#U`J4l#9Y?`qqf zaBOcvO1z`>;oUXj38kK=l=cQHm(G)J?=OBSQ)n~%&c3K~X_b=CrMTr&gFNJ`3W0dF zt{o0}<+e8`pBEwf56Fh0u@Kp(fjSD+QVKz`fb7fBkWf#>0LDS1UjYL}R_s0oo0taF zWn$y}TqPhXDJi*Jso-MlHkfMJqhH$#qqk8XUOo*udD$WRTW=nL$w`1_Gj7GjZ7#APSH3w5b?pL{=OXwL(uXVG ze&uE=dZszCNP>i+*r<%`6Bymd%WY9i#;`Hf{avQ!pj~B&8Jo%IIaq6d2*$DNkLI@* zxygphT`13!3Y{^O@Bw7trqwo|lhBeAg-#-0G+pzs+BVP#|56qb@z$S=vFh1J#htTqPm|%fKd4rI#dtD6Ua} zRNyn^NIN>!@$pMKHsD8%A|pNYHKgC$o_qit=vt(02TsSoU`@}5xFW!wExG{tU2lGw z6@qm@f@iAb4~vOO)KPqkdNU~Vg5W)RFj~_Gx6%#WBQKH#3m|mBG&JSp+IH)swsRH? z=$FJAmqu8>yM3`_J--T-z*D_9tkp+K=gCXipj9LN{$YNu`_qfFa==qS22+6pVdl&$ zG6_vk8_qHF7=kc)HuA8sC!6xD8?W!8Ps03PP&~soJN*|t0_d<^tCJy#+j_a4UlbZA z#xRI=_!}10E~0w+q-w>+u9dGLm-yZxZ>f~+CLSIjQ-e(TePCyL^hCS*FROPIO^g;1 zE%Gqmdw%dQ&8U0xt+O(yd{%Y%9@tY)bllY4T+#C~a2yGt##W6)vzqg>%J-hxuZ~WY zNSX#?q}-Rsqlb}hrl4q7#crI>SK$#Jtftscc1XyMEMyN*@Qee^Pc6DlFrKc+oWSaC zlk_nf8&=Zhs_fSaVqKoU;HbNVc00mZ#t&K`?BV3J?ViV17_eE)10-?KzBSL#TJegq z51Us;_sA=XK9>^HI^VxPxui!VIAHX*EoqMvpo5h-dhVTna)DEXyV>=FC3SUy`&Y{z z^!WZ{9Ix}{FDg7Y{dlUr=LsRX-^CCX#MNsDE)rkzKyB_d5XCH*no!{YmP0lKS|yBM z;gL#;1~w?p5SWdnY7WFj3=!h%gVk)i!ZtWGIH_OX6#0JE#2>Smz5cK~5$SQpYrSju zBDAT{NaWltCt8~fJ?+akf5E%w{gN3**)~IWI8orHhXVfAd8FstH0*CQK<0-rA;Vgqc@kQ_o37ZCrNhL!XXHt#_#|)Uq<2SeZ5jce* zF}-3hJCccKDrTn@uyeR)Dfsc`qo{~Oww+;F&JPcV&+>B4s$a@baI*1u->a`+jq~8y zOm;>X`QKZ7h)6eCvxRW&b6NX6P(`~ZALLr=yeS;lCNuE(!2KQ+^^hSOjF_+khlKW@G!5Fhwj5T7IC7WZ?iA0>{rsQIjFJv?$#GOn>gK6qvnkfwQIN9@{+l zVq}o&_8Lj)jFJ8S{l*2%Cr*lDv_!_C8GF2ZJ#$z4*ruj)l8%`{677fj=}^W$N4AuP z!0D^W=+E%CHL9pFVYEuXOp1PDS+GTGavK>p|L#5{AGbw+rMCOVlwvr#VQTPa-#T2}W<;oW zAI~g4>?%*jX(o6&lY62SBLaL$B0wi2jos(o0lcAM*A7QVN0bD|)hn%}Pf$mi9G7pv zIw-yP@tryNiIWB?Dw(%1(|Hdv!F_YFB6t5XIo3eJvWgg1qutZx{yxDR*B(tyF7vTQ z?5fXKR8-2ryMZa&WmXc$ibu}Xw;0S$%RwLwb8MmG0aqth zCPZs3soQ2JR_W{8z*U~Mak*L=ufJ}z=GDO%$K_ow^*AS9Ix2;JeWZ-saA-@>*1&U+ zat7471x8sf*MH+}bmtDIV^>{Cw645NqWzB1>TW!cxz9D@GRZdOy{gZHtvTJj--ToV12_bNKs z&^88H*oTZ)Y?v>W&Vj|t6jRSvTJ{)J&gY1`mErLIY11bwSrp?3Ne{8<*cv944+XGu zJgrcQZE3LbIhG_?qSFQ#2e8)+>llmbYE)3Sf_2<5gFJ26$5eP8T*>Y>AzW}rQpnqG za%U3TMC-iP_P`Tt4?R3siEw<#c#(OF;b6M8e>=yupYv0BJlFg8mUtl$vF^&^5~>}h z#4{DSMC92bGp>um667qogbqgSwyz@-1afZ{($+~ZQKu@D)Ku=WfqSfcugHkG-ZEbW zaYDDa%u(_QBIG+*hbS{wiAKT*Ne?mV3l zx(Mx2{?8`>*^SYbo;+em;mv`w?Bn7Be*JjXk|_Amrb);SD`ULQo6Tj9(5zouF?o72 zHRYwW!DatCxbW%_xMbn(_DOsdbRal2)vn|uHih^F4vqqzPtLdA{{CzXBEr>GXgW9t zN&q7-Ors&QusGuHeD*Z|c!>DWHBI{}$ir2BjSh+3e-~#CnU6=(jeyUtSPt(HI^^+u zgdfmL#y;Veu>o@Bn>^;(51h&8q0dTrRh-=H@_R^#akK`b z{Ql9>zs@{W7#Vv%tY#tx4vx5-Pmjj0_MH1UR_$hke2H68iyrd(v2f-k*0Zt+H^ZU8 zh~qKxi>dG*tGu|bjvItRR1&*TyA0>1Y?(*&I5$FKL_c>m6|Lamct^Kla8%*;zJ(J# zfTRd$7+joW(-RUafJ)asR?_Jpspqlk``0S9UG_nxe@!^0EF)sWgnj++FZZBvpW zi6S2V{ucfn3pLT|d%D25qZl9tXJYp64x1~0(gp)#w9`{=osUZWsq)ZSuS0@;jp1wW zb`E^`&G!l#<0uK^0yvS#83?v(ZR_y}xEYnkFRI?EW~i_KECH38%3@-QosnS-f!J{Tg?H z=P3dUoWot7yKOO(Yui-o2=Dua87FN@j_={$R&;ZlN}r*Sf5BFCPcp4LgRFyq4)?NU z>1}~ygMXY@8?e)qjIEC+PE$6hA~auLCal>XnJb?ewW~U%&k$r9E>Jm~f7bWkS2963 zZ@|JdFYSZJ^L}}YNHYtBc8+5O`kWWs)u|n-hhV|4dOa4|)D+$TpmA*KGU);$>Qm2 zg`@Qr4+13BThqMgb8Q|{ncPo0oy`GrTXS>erIOu`T~}CP`%UmKPw8SHm)#%DCjkob zaIF0wZyvix!vVD9pthp*YM}}O-Y?vQJO=cu3iX5C z77`LmdvyFZ7MyPE&zZj4jqJ%&8P0W0#t(vDxgnj5!RT$QdgEK#wRS-RnTVpLAM~AsZBFi}I0+@pLNw%s+>5d~l}-A1 z8p)E%ADCl*O{m8A%P)Ipt6rh5{WW_l$6C-hc=| zX}ON0RF~Ha5NT_@^#TER6*L@xBI^~+ZB<6!?UK0+DxP|<5WbGc581D*{XqW`usjfF z7nNx8@GN&6wUA0KKuv`nDENc-H0Gm~oKosd1%YMMQcu`>Tw)nWKTTkDDD%tQ@+mh* zv?}6oR58sWJg4v>*Hx-t?O}pa%Y)ZLok-ae`K?BPk0Nw7G)BoLJQdcF**JjgOI8g&;VO`Z|#s%H`55)qN0?rEnNfF=b2p( zQ&+G7E_GG`_p6raa2Au2jcQ*Z&psH~_+K9U`2 zA4uJI_yeqY$f5)g6(SEksFDR#y%Z_6!xg^Py}i*4LV>G+_KpDZnp@SHArjvR;vMnG z{dRX7G$0YRxOr2R5*e5m)P5>PDRy~pawc1CvV{kpMtT6#f}};cTR!a`jAjH9HMegc zm7EQDOwBit;(%a0lHV&CDObu~bfk7lBlm?g>XmPTAn#2wWO-tA?lv@jg%P+4Dd{eF zCszi;guVBB`9r#B9FtR@^)lI}e)M35CDUtentY-o%4&^_HlkWo=N*{l><|SbPipX+ zq9^)1@&!t8R^`1{6hD#bbv9_8LUlO5u*SnRU3GOB&~qET_XcNZ>gbqf3aX^6HhFf> z^y#2N*=y^z6R>-I{My~f$Y{?@Ij)je!3pth})=gjZ2Zn(wle6@u)BWCEy zh1ZfsnAY!0zgK756=GBv%(6Zn2Z<&*WQEJzLO%40rKNR9vO*pv>{a}F zLbwsCoNx#^^hLq>yNf=8Cty&LG~p>oMJYy%HP!}G%(!5BPbGzvWXhuyINmt z*jp{KMHdPQ7-K36)H6ZQ9ec^Xj)gN-$)-GuLbd{^z=o7q^!{E}VYt|Rr zoMXkEgtWG@wZ+2r8+CtP({B8rwI%S<;G>wkT2rr`|8tmdi@CL3fjqUNA*`0+RVWih zh#Ec7Izu>ZHjec$>$BuKZ$H!>k+;op+#U)vs*G8SP^;@K*|L+?YJSWXoXS;os(D*b9zu!e&_D4QOpWD=y|(-!MN09?#jW)rTU6D>&wUM3RQI_x>#@ zhz&~M3sr^eG|?ZQ!lch-kizB9oEf;=grwl9=>YktkHrT#Rr2HPB4s{wg;f86;t)BM z+AwFAk8Z5D6?1A;2Y>!>{cFJ?VKo~`u}||NblfgRnCe1N6M_*KFS4sw!^mQrgX87H zYg39LjY4ITaw=2IAHjyHAG4&Nhn3B2L$6y_-k*V$Yr|p!hfgG{tu3@z&1|E+E99vc z9^blwfq_ssygjNGWv4)BeIvhS__<66?G=TW+o#LH>~0B^_>?O~iOzhspY|k--tgmp zoU9-7sGmJ%|2B&!kQ!po2&G;AoF2+T`~{FdNeZ&@tdiAy=PZ=&vM*L(Y(lf+OYXr(OAmF6_8ir8Ba&9`8MuJvcEhMLAoT1B zdl1-r@<&Z{mMveN(C(gGb7pY+;uwUBN*Zuqgh4}*>qN{`BULUFQ-t*>+MV79RD=*NDfBK z(7M2FC5a;?$9i9O)jJDk18yv!sFFxYBQK9VFq30t?@X-Wjc6(>_8 zm5Tf&5|8x9GhqZpwbf}hREtI^k@~oygA#?u!ET+>o7STI_McBA6?OH}^r)Pk@U2wonSVY6si~0GCW@H`=05b*L zNfO)JNT}-4(K6^ym(4YSWbxTnhf(Xa{>tN%@Ub#;H(zk_FD1*DW<#~Nf@6=|4+kC} zMT-l*O^-n^)vw|n+D+sl=+xNc@2Zr7FEt!B;S&{$Ghcb7ZTsMrmm4i4DKpXq%V$xs zV;!6LW*ke)lQA4hdTk|G5p%<%E<1Nn;dz3Jk?uY{lN%LQfJNBP@)u6bAt*F@tg={y zSrF-G5aCL6BKfN$N4MPe-EDdusNHO;ut!p?c_0$zsDr4!^|o5%7Nr&&)SR<97jT|z zN5HfZ!Hu{T^4@oMTz5j6lsEs_-f;dp$BD77Kc3Daa=f}@{nsd-JiK9~k_?oX_A}iQ zwOuaO4NK}4)}d~Z%#V>KJk+)I!iDHpZs?7aMoWKlEWb?uYdy0>&1MjL7EO5`YVpRZ zQR;Dg?I%T=kQ1S$xf7!d_)qtR+ao3s)G>W6p>gWK2$igJ4!5Huy$4VGhRnFuTn~rQ z2JRfZP!AtU#iDfAgtgIac_|PoQHcGGK=<@>FCB+%)L@R;5R+svL?M^pzya5xxyq90 zo_7oz5}B(jcp?!Rro}?lGSosn)xCf;0|K+p0<~^x6@fci!?}0h=m^2`eH}DQs&`+M zM!aCtwxnM$~kF+R*lL3zI#eT|Oxqw@Ac`8rCeSN4!TxqLK<5BitoGDFfj zGJ5gQ8A}Sx)=D{Lgu%~8wx_r8D}?r4c`pG1*LimhBMYz?kvX|QN?3hh4WzY5aay#M z*<#MAdKb?*`Q$tk7*7_v&4t|j7=Ssl-1K3}XzbNBR|+Q%spm=b{i?itiJt&0!DL|6 zHXE3ZoK%V09&U?q{U!*n1k4m)&H~?Fn^k=bG`!eyR;3kRB<#&;B;g`{_4z!9!Kd6i zQ4WpqYRx@HKpeXfqmCSv#B!F|>-#^f&}att3AF*faE4sx4Meu;U6i6HQ#2w-x#(&l zP!$`;2S32Y)b?xty)VP0_MCh7%7Qf=11Y^6VzhE<5GIQB*l>fsf}W1S?CymRKjKa{R=jKY z+31r2I`{tUn-ag1;2jd?bPMrd@DQ%B+e8yh1|akon)#3X|EqH4vq_q37qlc1KgfZU zD?P?V{t<34AspIiBf3Bane$REexct?8t)} z8WMQdYj|}re@{%&uD>q`CXAYc15G!toJ9Gb@_TH4D#v`R%$(_#MeLFHd_0=T2<=SC zah#7Xt`5COKNBbT=oE2+ldFJ5rc=Pmr)Esy@Lo;Ud3vbmWX#T_Aur#7k4ACD!+aXX zH|y8kyvV)r&d2y}7bq0@Qcx&S zOonJv9XBkVso$UV_)tqr(t}g&C?6#vWMCi%6qnFs?;ggRhQ%W1KMR!lRAsbKTJiR* zvuj8_wo5fQCNpy)fguMO3i`-n%#X$>H6_$aAAoVWD>b2t)8xc(aEOvd_tE(?NKqpy zJTrzsVW3ENGyST7u^66Fd&>Mvb|)A1a$b;zaxLYyF-%Py+x}RTF|TIca+ntUg0$Ac z!KDDo!SeJ&Z^n~o0USy2k4K|y10(#k84SB>Yez@G!)l0N*qk|xW0nxLjE-YuQ-G%d zH4;R*+Fh+V9I~ZM_fw7|!O0Voz2JMiD1{>%)V*u9yD$kg z^ch-i_ruR3j7R5NJd<8&Bm(DGLPyOxEHoVC^lEIuK}k4>DI!|2iZEj6;IU~1&aX!no&N_&3Bz zjZuJ4hV}qPk--qW|3P1Hl3@gGL#8_jen0)H5tpo~@uayQb*V-m#lC9{w>-ldLK1T0 zA9J{Ug|Gg<=0upavHRhFCg4`EF`{?O=hJW1Z2A17QEYEjXkY)44q@N-hN+@*oo}$$ zP?Zatfk`Z7-5Tu0x6Tn^6+>188$SqDTkA40ga;`Zvd)Xl4IsrSi`q(zf*esw_BBa{ zvQAEJ-t?(@q7<&fDjrq!&@)mvk5WNIH~=u9Tlfm=B_LZwzBd#yt#`RHa2VNiZyS7^#_&Bkg<*R{XqTa@<4Hn&zI%Dq# zyU9_LyeqOs76@xErDrcRuMSGkULr-+16(}~dsLI{$Zxm&T5=Zjm zq4wXMwwb=dfn!Q-OX15Z<3o_DLj0wMVXJdG672T&57Z17w;_l6)3ChoRmBBu3VQx@ zAtfcmf>WB8UL6`R8h6?Oww``vI~2G_Ugr>N^YUi7PqsK3WpfhZI+Hn4)7AS@dDpXh zbB{p(>Eaf;Z_T`H?$_23YKu&J;{`a|fJ@qj} zcm_VM*IypM2CWql_Vq`8)gP%(I44IOl2GdE4qB^TjbA;SD4!g1nIqN)(D+Tv`1_c8 zh@q%(D+l-najPiPW4=XZVkp&NqI0aaGbQxM`T86#NT5uDD z9s1x83SKN58dEd7+b^~s05J&Yi-w}gO~BNU=LYdBzs0k<3z6_HNM}uj#kIoF*?oSN zZm~u8JPLBzy}cHbrUc)cjHx4}fa?bY!JY{yvFL{L4Hpz?q&NkqO70k>Glt3m^km4k zlH^}-NYb1~LC?DUY;Q3T$`w-8zOD=Ht{?3&z-3pITJMn4iLT!>j5v08JWyVrj z!!Vw|);zILW9UPfjd|PX`$L(Fsa_JofE?IlPEG)@b{FbCPck#7r5sRkdM8uDNQ}aw z!-n_l`vEMnM2jTn!phZgE?E=J3Za+|Td|U4TH_lRo4nT%I}J$6{H-JXh=Peki_EQ&St(ncM88 z&)O@TKCei6Br4~6^;EmkW$tFjUsP9r5X_(EfKJ9{8l4l=Q}uF}T~$@>0?c4T(R#mV z4fPgSd}+-+UDzbPobv`%>9F_F1VZR@h=s>Cz{%ZT!*FNt8jipM}JO_ zoQvvFmLcU82xh6H$||00yOYpzH#CX_S2>mv{37$421hef)6LS*1UQOq-n{4c%z;Mb<@k`gP7B(UG3+wJBI-utO~+YFD7w51hB^+1 zg7|HEXy9IOvB)9x^!IQ9BHAB{bAXC zuH!IJ_qiu}@3cd+Xdu&D2b=t|kyg4Sx3t}mc;;x6a1N5 zT8QZ4sYn=CPmgiP%MO-`s4T zBG9st&=f|q#Zkd%G}&=a!67D=p%18K^jL`Urs7|0XN7OsbeDGw6A!(d#b`{~zoL(y zd<$C&_Q;<3u7Cendi7+0HOWCX3sJQED?9Yepl}!QawgQ|h&s|6Mxb73zQq8N1x$5Y z9E{APBL-&dBo576fI_oJQQl??HO9?5o9YfdWfPmt{PdxsW+6`sl4tIiiXaZ(N`TU7 z(dL&cn>CB((Y+mUAg{^|dcS(n@AVY{7EwuiA9f9j8W}1qjq&k{Nlo+Qdw(*$zpbmU z`*eZo!o_Uk3GWyR#+(Yg^EoJHbhFJCYxwjE6cq1Sxt3wLUi={xW{4a-h2hhh$=C&PeeD) zQ*5xgtwQ$#D5FeYxj`>t+Lk!UI-10ijHce1 zjBaHp9`>F;Fl_Q7`THHnKrKSXDXnc_ptrYR5+%)}L5)KN%7*|$=Ryy}|6~-WmC0@} z$}WB^NU@u?vqfYcRWoU&nkTiB=LU}Mv9F&SNR6E@XC8(CWAu-UGSn)* zKwXMnU+tF{CkdYRqWtZ5n!g1kzI^p+p5q_iIL;=|V`^+|4|lq3?AxmtlJLPEk@iDiw6f=+IdT!MoE?rR%4snnf!(KMcN7l zVR#%+c+4<09IS7dWf#`F^aU1hf#h8FnjmEJ=!&->hriMqL0M+yF<+cym^eceP3$@r zT223vSAvn-@P3$ieH~pybzH^F z9TOjl#!bq~Xp|p~vL~EuNA9>vi#N0}+G4x6^brN#WQ_DIT}pV<_Swv8DAd{pX=jgoJTX|gZTO5+IdqEX$%IMS0^2{&vUm$ zNhZS#smd+%t2z;-vInt$EPs`i;I^_o2glDAzWQ*;Lq0QbWGt@aS=W7r3))teERok1gFLTg2lZ9Xyse|IzYh(h#PVGm}@Rg{kqHx)g z2o#pu!=JAU-=~Z%^)$zNL->AUGO9!>8*$sI))I=_ps7KJa%Z?^G8x~S3ivAMUb0Z8 zBlkKc1oyNACU%hav+lPm1fPm(*qXeb9cV+`MM5WJn~{UxbvE5^fg-7fs4E+w0=|+0 z!Qh5QtYWnX`g;(ED79{_NKnbOI4J@q48j-c3k_Ea)N(E5=Z7K=)LIfjEhh8-{{8#? z(Q6Ka;6OD~@wUeT7)*qf_DH{y!0Y98FkjZ_;J$3sT|mobA9c0PQ%Ebk6&qXpSlOpU zRkA;_N>nTtEh;C~Gt*zOSik-DHNS1%JFso9d5{16^9E^X@$~1~orEdfjBoPY*I#+* zW?uA~*Yc)j_@;*J0oCAcOD@zo1j4l%m29ZeIe?2p=AUZMa7z$F)-U_U&)4^> zpks}jNR1&XmZs&oTsfN0J{6NPiNgV|fMnFl@6{p9OG$!;Y1 zh^a%x6!pUd!GTmitOJizTAbK;ieVA_ki#F%AZgJqe!r~5ZLa-DRhqlkEGwCDk$g$ z$d7~;7KQ%YWAAq1?wYq`Rv=%GQnS(s)j#Xmz^I{9#A;E)&hsD$$7T9E?rn+gkzDeJ zXtl~5f!wAD#YiM^z*5_3Ev$ zjcNyZ)q~dkv_w8=&3@jCek-?$)_oDn_jI$UyHn@W#0A=#<(#v))2z#-I-~6Fy#>7* z6%&&K@ap&LHX$J)3uLiyjK_;@>$6Q)Wl=3E4)Ey#VVW=s(sgipHc?9imMthA4LEO}%rc)%@8T+>E`5C+%b5Z>BChA;n zHmCVOq-sm!@`DEtS{>^~nEQCHM?Nyxx;8ds_1W%!^X=QCK4}+8sGP3t3Pl_>J-@s> z^Z>TMu9cM-9)KVGZyLu}3d$j;y#yXlQ_M_rc-&gfa+Tg9fQFN50qDo&f@FS9^B zpr;P9NN%~?iUMU^p=Zo*Tn{-|nV_67>r1k1aoJ+1^9!sUnLkeY z0!)~PGy4Di?f;Dd*2MoG*1>o4q+}~fjpK0^!@x4?-o5#fipi2T-Ml9+B2 zjPimjOcKUXDQP8X+Z*=CD6a+iH%`utTecW>HtHW&i7CIQ$c4NbXRKRpTU*;yWtH`D zadDh0-BNR<^H=d?AnAxs!Gb4zyVW%{uYBuMeO00MFg7EL1q&0KXgjv^tH-+0rcbM5-|l@cC}WBwnt z0NcQI-ph=^GxzM-+GEEPA3T`DnVCM3Wqzz&b>z&tl*mnIgF0K0mN@t0tcgRu&kYU; zdIaS-@#>emwMDpXemmhQ^~x{4Rf%uFz*O6{@7%l2)6r3Zru1&@77>9|I=_$NVoBS8IW6;o7yCr zoSB*V<`OgT35kg$xkE^$fmc3=kDs5PpI?|OwRY`VxwwieF!nYdYKn@E#yPqZGKw4= z!MGjybZzr7p5GKY9;T%&#Ul)-x5m8%m{$m!8t|mY*NeCNe7Ko**h*>n;>9OBdH5yT z7~AnR6DJ>7cEg4kR7MQ0{g|HKs)L6Pops6l`ocRQD$Vrt@@jZGOXdnvRP&{j!m&m- ze^j2!O!Uam*o2q2b%BH1z{7(C+xVKvXAiY^-gGr>#`udnBAE%Vn(;*nG1_Rq)5BCXz(x!uzT(n#>3dqvENWW^Jd^^ zBY)TPEp^ZEv}!=_CvCjxvO;YYebX~^Q??)N%AxdsP>z5Hln+^;`4-S8QhI|v5zkGg zR-3j_-lZBw^njdxJ*0tF)MK1p1LyfJx=4rvR=B020g}T!jBXbS4n98C$i|F$Dc`Rg6hLzandB+*L zL`30AG31VKYE<}E)|V4LaFTqho>k+2uYY^J2DB;u0Q+F}r;&fp*}ZZ$7@|z};VTc; z*x1O(&Rt)-BhNp;#Kcc}QYVL1!Am^61Y5>n+}}~%5L)GLK5s2EJQsG6VJ1rkjjUDS z2&fG7e6+Gn9KA!X=9xtVxiC3hp-1F}Qr|wZlkW`MHY^=|A(KjdwCX$RLb+O*vNy8a zw+}%2KdX-(+SC)k=dUpF4ly;8>8?rT@`^PK1{h6+oUMN`ch%`U+Z7vkUPJfA z2`d0MP=Y9YJisk%jcT{Pa%!mNOPH*( zDZrV50-%}q4Z66Rni^+kXAy|UaB}fTGG1B*C#0_?UpYI08bsKp(-9u*TzR@`CpUd- zFkcq0IlvNRIKaE_$o&w-8dY`ei3N?TlJD1kbfxHE7=kTvw&`Bl(7EEF<32fn5Sx0I zl&g2-b|xHH>K%fe^2HrVV2W5!ZdTS18p2b$g}Gx7RmcTmIqehgJ|*ylf+NTckL1^O zE-APK-LM7Xwh#vSVrVosw zhg7}7U@>S@8Cp5Pvy)qv`{r0E!bZpXD`_87Tn?0aDgJO+E+{}}DF2|KGL%_f4;DjI zl$?-A5-_in`a-$W4b9GGAQRry1W)EXu|P039NbhWu%Pzl#Y2K(C%k0>=``b2!kOrn z)vFX}2~I3FH7$eIim}fKI}c8`ufTtZOj4gF?9(MUg(Q3%%6{`zy4f>MXDve>FrIky z=WJtsTXFZUZ4)L2BY`T@jt3C*!D%##>T}q|hUZ>xV`B`_AtyZK`|rPZjXfvr96(M@ zxt_dYAl!Opc=q+{P1i<*h|AjKrSt>+Vd>zDy_1^i>U;yP<>SJ!U=&gZ&#v*SVat91 z1awc*uqKBW?Co+S$f8#NQYc3AB10-Lz)r)*C~cTaWq?SGbkHoDzrw=801xeQbMqZq zHNb)6+(^t#!PE%TeWycY!1;8Xl9GQEigW)v`{lgMS;y24LYvt)Hk^&yh!Ab&TI$C; zr78t&Rm%GMa`+(zup3BXXid!Y*dHEG;_4rR@4V*Ve+1U~N4g9Dg#p7wb_Io5Mn6X% zC9vNy1izQUTkTpoJF^%$ogdk!S}q_K3nwTNjf_MHSiZr*%S}w4!asL_XSfxRzCH+DqMzi254&`tdb!#^vz|-{gOk=ZSP|H*I*(fX1!6wVl&fia znG+s{nKUk3P1Gf~WS)XO0_$wXW|gZU8#Zv*3idJ+Bw!bbimbIc(sHvA%vuF)Zfe@b z{l|-^tG)uU&Fz?bS3?tN@O@O83%5s35MW2@x`ZlHpz4tazQ1Dy9Oy)@8UdYW+_s#n zS7!n-q2yIP)v2Pk))9{23vgaUTyO{pj1-(WNFeZ0eN)p>xjW2Q?TrY3|9kH~F-&T5 zJ1)mTQQ}JeA@|Ca8NeVgq1*TDA!0JWT#Z;Z^$#K%CSY<{;TIe)LIFhAkNQ7bvhl^) z_@k1`4*qC8I#2jOB;0hQtCs z{)U$d<9RO3X$XI-UUaL-Nk)7=uu3;HG&-qV0k196ThqaBw4rxX_dtcuHD`BMo^wv- z;bc$VKMR>*vDn>7(x7TEo;B;)Q6Jt_BkM|zPm+JYweq45GVa+uC+n8EAW;o!Zk7_Qqn9JO2 z$^4L@?zDD|-Q4F>AezwS6R8EGBit2*jHh6@MOgGhR27UhO!vqtqp%#>EozaOT7psw zl4GqQmhbCRZy*^O4zQ5!HyrKlETQfq;7z#u-d<`9hMr+mi4y$eUJ|`yvA9gHnqn-5 ze*QJ`eWC}pK)ar4xkW~Ne21@ZD}Y-s>a{0uAa2B?YfoELFUM79s&o*7fI+-PEm@Ej&qxOOv=^a%7`zR z?P%38kJJGI1I=1t9-SS8u3iK?Elo@)5nc89LUwo380K6}T$QHo9S^z#F3%`7h};ws zrHrg1XD}ED+te~M#^pl*U9M>>cz56iRgWHvy{ojkPk z+OA49C?_OcQo&uAb$+V^XhzYsa`wBstKqAHp!Jcg?&9XQd%O^eFv^7Jon%9VAz`Yc zO7M}N=A@)qMm(6}A9k;@@{5v+A4U-lBg52is~wP_7r^~Lz{kPj5i)mnz8oHc97Pi^ z-)SyD4T+bK;CIE=FwC2sd-W>Vfp=OPgF*2x&`SE);&AVf3?Pd2B^3syyQ>#)v?MF* z6cs`dj3-Dw`zCwy5sU`#@0vWYzX{x)w^PxpMk=GPnTIW`ow~I z5a|%rkIQ)B$IjM$GB`kk`ha85r*HDlDG(;WK^7jfg|G`}-s$}(Z*6FUQu*WhGYru3 z<;xz)4&tVt`FcS1xB3O3(W9eQ3libMVMTKl{>^_kHZ%;~&;Ei5njVs?2;F~~By3n^ zmkh)c3?KJfW?6~5B|O}dqL{%)Dc3FF+?xtI?8sS9PRT8dT05^EP z#;><6(GyAI@W)Nu`y)t&-3~wtS43&JAICt zE1*~#nb&vY?vOO&=eO{c>XHK}N1Lap$U3R16igZ_NeSYwR3A!*pJrq!!oH!|254te zgcSg_#Oe{dq+uf1bo;c06UqZxjRFr51fjPR5`@--3|1;~rDH+z2~-u$VKB7CFN@5q zphO>xeIaabfw57*gUbaKof;xhfGJe*baoQy%02^ zNHQd;Y;5)k-VgC6=OZhGkK=Ju2tz<%zYG5Fq!CBhEfC1D^T7d@{S$*AgSpV6u^tq3->(!F7IPLEEPQzD^|2-cGaE2T4^>MMCAPK zTPd0Y`!N=Mw^%&Rb>(6{|9BSAso-8aPoQs2xCN$=j9r0V_qddLlSyS z?+gf`YfjsPUP#$`<2U%S-bBptu_%HD@~hpCdZemt=>^i`YdM#60qp!^>44&;NQCs-ik9ir9r|EWJ5&% zevjE+zC4}5AZ^gf${lnbDzR&fP2|9*V9!&44)EB|Gx6HBORkhBL3tHPtiTI=k}RRl zk@rLx9gbZeQ6TZq(sCOj3a~HuOhkl2DUWzD7Qwxv_Q>h4KubN>k$XRa-f&BJFX}l3 zi0Id<=u>89TPNZWOBOG#=dd9ogZiV818FUEN@SoJ9A6`WFHi{*q-H{q zT-tfsBMS%uo>_a`r|;?03x#5FCPuH4f1e1J7Zn*1R~_86BWOyM(;f3FoC(fOMheKH z5u%Oo33Me;7j#1icQ;2>$}gqI#=Z$)GkWuDed>V1U=W=1Dxr?LW1D&&zIby0JPZzc zxEfLQv=z~(&>)%Z!r94ww|AXJPB_DXRz5f|H^5YT7~=M zZXq1*PPp9N9Y6=zU)~T3p3{}Vj;o;KzoQ;gh`_J z@RadLjJRqIL@~&NWpq1!3s@wq7Wfk^PrwZF_s>6k5`uOk!NsJpg-8g1!Xub|i!E~) z{d^&ULsP0I)RgYDuFwovaY#7z_4Oix0GJ(4Kmo(c-v_Ls^5s$xe$v7p_?x$))&(&f zbXNRb1%{e@eP6E$Vl1s-{^Vc*!-Apazmf$MzG+f3>gxErABQg{?*Pph>U&!BpbO?i z^jC0{4V9!Q1B;f?H0TL0-v(-mlJ+HVLX=Sj=uIX2LDzfNPx$o;xdi^1>Rq6^ z_D`N*Sd~FGFmF(y&M{?m@M*a0Qg%epOQg*qNafB9C-+QY9JJgk#fW1H1UyKU~lfsDV?EiR`+-B2NsN zM~scMpB^Zhl&gmnWq^krJ8rWhrlkp=?}GYALH-mr|11{62hvHZb@Xgxf?^X&U7L@| zjh-k2Fp~{2MxT&r!0s?j(71-%Ok+L-;)c!wQ4-NNx7c%qxs5w8YJ6(i!?>B!EgM^Y5+C4~{IJiH+sb_ZqlMj>R%g<+1ve5m#@Nkl9Z{hB(oe^! z^8o$)GXMAVj9q{E9b376r_W!1{kH$vg4j7(eb)T$54S|34qarhQ0URSQum-s2eo|J ztkua!piNhG1?F`{*}k>^Mu(>_-yyFtL3FXX)jx2N@Tx}L7$=E}i0JgUwT^xs+N#6+ zfrTk&g>jN5?T|ZXere^`+||jIm&HN3V%8$9x^q|1hAe*8iX_RHHa{$|YiN}5c)Wde zn?w^8m?LKKv-%@aS@uto9(k9pKqWCk=O<3~xnJ$lsO52zZ5ksc260Y}i$C8SSO#UI zwEAH==JRp4E!mCp>P-`HOVGC^@P9o-g}^bUs>7}hOUv| z<$O(pth1%XYar6sw~V)Rfzl#$&73;khTt@R)*&a$Ptc=zXp;1o{5m#=!|y)2E#}nq z+}!v3`};rOIoOo)tgWrXx{pSU4KFvj)bqCFen42CcWJ-6zn@>nlcUJFLk9>mjh|RA z7fTzvMfoFtT6=rgq3xug-+nS$j8V-_u&*Yo8D&%5z za!lFCZ!c5RF3MBxx3iJRC$AW>Z09Gh7|DTQwHbT%dCm5RCxb-78v_HO1CfP@ga(ri z@-*1bCn(4i&08tSIn_$ws9P;HoApi$n%5ywY;1&|ma}+dR9oCSJiMB6G|+|!pGmLo zECKT)I_Xg?bjN4<0f0Kf3VM;X;OydZJ~G8s(cGMX}`!yT0#m3fAJ6VZ_bLNyH3Pb50sN1+;lo2KzX-gD|2n>KT#$}vO^kP+3RyNA# z7kZcqQ7eqxFenb&ckDRZa^PtjS~?xXO7DXkgQVq%Z<{eBPgsA8XVePtm+*McPS&9+ zKj~>~9E|3}44tp=mTkrM!jZo8QS}jwfLzVt#3Mf7?B;e6XV12@Jcv#Ukju!~T_`&* z@nYG)0mEx~;&O9vV==uqtZx=FHz^5+!N~F~9(=dzNQ*ThWUHX5e}%U_2+TW!O@?mt z7md;f->5Prjld(z0C73Sxb6419)BvDVqxL#;ql{l9q>CP14ocEQgti5uEH+UapUyy zgBXCc=vs3iWhq#wq8#Yv7{2$#G?hEYLIUx`XyAIJ?rxUv;%qUi5f#Vd7fgKljlhB1 zm(40cCg}<5^}TaHz|q><+s}ObysvGevEkwoXc?c1iXwFv=uYO_Ulo^)cIT;1tF&c= zlW}fz`()4n-rO?rQH$?7Zr)sr+g1LI2;b~Z~xn$h9ODld&#yw z;Pfri_jWghqPzW+(?QDXyEY{hymoKJB?V>aW|s{q_bcbYt8P z2GCpfn$NF$`F#gqhs1tEb_&*1Vz;3;ZwB%pQ|`|y<#}w|7HT~o&r4m<Ln+u#Cuhgxuiq_4H4h*c2 zI)p?<&Sr%5eS)J=9?)YC-;@>)R*N5NG_2RI)FR+XdpislDsvgZI-_PqljA=Yw#X?CMKsFyVtz(bWt*f zCx1%D`Lq@fc-DJT2QOBPa?k36lQ|J7Ey~K=_{K|Gby$JbHB+^1R$aXQWvkk6mhCa$ zo^PLekC&=J{`A0eIP0@#qY}H6HOrBcIi{5;`; zxHxeLyFq)XEUPL4_(8cB)CT^Gs+LwdepQ&jFXH- zfHyBUd~dst&wSMO;G`U_g=4c=EEWnC3_x_~NMU{LA8;a&QHGcYy@O|Of2KLGpf2ef zfq=8r)U=s(Xp2S-?&s|8o(Z$v8CH;8P=LNIL@d{z+0x6^d9m!nqFLyeH-rQ3{;tDd z3`uI%bKll)(a)BE(GR0p-vy&HwNV3IQz1umI(1Fhv&|cY8}B5J=sOhS-9H^KzJ~^- x^z#~b>zCm*5z#NhYkRL>hDrbX_P#b|lHr$=2W<^c>&xjktmAPnt^MY^e*w}pk!Sz_ literal 0 HcmV?d00001 diff --git a/documentation/content/images/notes/Katana-Debug_6.png b/documentation/content/images/notes/Katana-Debug_6.png new file mode 100755 index 0000000000000000000000000000000000000000..179f311a505c3873f7a88662c0e9bee2c728855b GIT binary patch literal 166785 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

    2wTv>@U)Ii=s(L-1bRK`BkfTj0pK@NwY4R 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 literal 0 HcmV?d00001 diff --git a/documentation/content/images/notes/Katana-Debug_7.png b/documentation/content/images/notes/Katana-Debug_7.png new file mode 100755 index 0000000000000000000000000000000000000000..de6a2598495489a8e9d90f139b58e048cc5a5c28 GIT binary patch literal 145334 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∈96MCVD4HZtd&BF%qR7pXG7+{pxy#Af(g$ut5 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

    1ZeN+mP867xtXTgyK2nJKiCjP)1Q!=!t|`% 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 literal 0 HcmV?d00001 diff --git a/documentation/content/images/notes/Katana-Debug_9.png b/documentation/content/images/notes/Katana-Debug_9.png new file mode 100755 index 0000000000000000000000000000000000000000..0b4b5116007fb8dc586929a4852356a3694a65f1 GIT binary patch literal 115555 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�oV-}J{VdUI}R+Nuaz!`QABpDyc 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 literal 0 HcmV?d00001 diff --git a/documentation/content/pages/python-tutorial/definitions.rst b/documentation/content/pages/python-tutorial/definitions.rst index 7bd40f2af..17a55e8aa 100644 --- a/documentation/content/pages/python-tutorial/definitions.rst +++ b/documentation/content/pages/python-tutorial/definitions.rst @@ -1,7 +1,7 @@ .. -*- Mode: rst -*- -.. Hurricane doxygen doc links. +.. Hurricane/doxygen doc links. .. _Breakpoint: ../doc/hurricane/classHurricane_1_1Breakpoint.html .. _UpdateSession: ../doc/hurricane/classHurricane_1_1UpdateSession.html .. _Layer: ../doc/hurricane/classHurricane_1_1Layer.html @@ -23,7 +23,6 @@ .. _Contact: ../doc/hurricane/classHurricane_1_1Contact.html .. _Contacts: ../doc/hurricane/classHurricane_1_1Contact.html .. _Pad: ../doc/hurricane/classHurricane_1_1Pad.html -.. _RoutingPad: ../doc/hurricane/classHurricane_1_1RoutingPad.html .. _RoutingPads: ../doc/hurricane/classHurricane_1_1RoutingPad.html .. _Horizontal: ../doc/hurricane/classHurricane_1_1Horizontal.html .. _Vertical: ../doc/hurricane/classHurricane_1_1Vertical.html diff --git a/documentation/content/pages/technical-log/December_2023.rst b/documentation/content/pages/technical-log/December_2023.rst index fc41d5bb6..266e58bfc 100644 --- a/documentation/content/pages/technical-log/December_2023.rst +++ b/documentation/content/pages/technical-log/December_2023.rst @@ -16,8 +16,6 @@ too rigid a configuration. Fix: add an horizontal, in ``M2``, to access the terminal. -Yoyo - Occured on ``benchs/RISC-V/Minerva/sky130_c4m/``. .. image:: {static}/images/notes/Katana-Debug_3.png @@ -26,14 +24,14 @@ Occured on ``benchs/RISC-V/Minerva/sky130_c4m/``. :width: 60% -|CHANGE| Reorganization of the size detection of ``RoutingPad`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +|CHANGE| Reorganization of the size detection of RoutingPad +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Instead of detecting the size characteristics of a ``RoutingPad`` at a late +Instead of detecting the size characteristics of a RoutingPad_ at a late stage when calling ``NetBuilder::_doRp_Access()``, do it once when first loading the net in ``Dijkstra::load()`` with ``Configuration::selectRpcomponent()``. -Add a new flag attribute on ``RoutingPad`` in order to store various +Add a new flag attribute on RoutingPad_ in order to store various additionnal informations. Currently, the size characteristics. Add an ``M1Offgrid`` flags for the terminal characteristics set. @@ -48,7 +46,7 @@ The ``Anabatic::Configuration::checkRoutingpadSize()`` now store the characteristics of the terminal (``HSmall``, ``VSmall``, ...) directly in the flags of the ``RoutingPad``. -For the whole function stack, work directly on ``RoutingPad*`` instead of +For the whole function stack, work directly on RoutingPad_ instead of ``Component*`` : * ``NetBuilder::_doRp_StairCaseH()`` @@ -73,3 +71,90 @@ from the start). Make use of the new feature in ``gf180mcu/mcu9t5v0.py``. + +|NEW| Support for offgrid M1 & VH topologies (WIP 1) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +1. Add a flag attribute in RoutingPad_ +--------------------------------------- + +To avoid re-computing informations about the RoutingPad_, namely it's size +characteristics (h-small, v-small, punctual, offgrid), add a ``flag`` attribute +in order to store those informations. They are computed in +``Anabatic::Configuration::selectRpComponent()``. + + +2. Implement horizontal dragging ``AutoContactTerminal::updateGeometry()`` +-------------------------------------------------------------------------- + +Dragging can occurs when an ``AutoContactTerminal`` is anchored on an +horizontal RoutingPad_ **and** the opposite of the connecting segment +is also horizontal. In that case, the connecting segment, which is +*perpandicular* can be *dragged* over the RoutingPad_ as to minimize +the length of the opposite horizontal. + +This feature was until now, only implemenred for verticals. + +.. image:: {static}/images/notes/Katana-Debug_7.png + :alt: Vertical dragging configuration. + :align: center + :width: 60% + + +3. Clarify sourcePosition & targetPosition on AutoSegments +---------------------------------------------------------- + +The ``_sourcePosition`` and ``_targetPosition`` of ``AutoHorizontal`` or +``AutoVertical`` have slighty different meanings whether the segment is +in preferred routing direction or not. + +A. **In preferred routing direction** (fig. a) the position extend from + the segment for *half* the minimum spacing (plus half the size of the + starting or ending VIA). With neighboring segments extentions + computed the same, we ensure that the minimal spacing is always kept. + The complex work of computing the value of the extension of the end + cap of a segment is done by ``AutoSegment::getExtensionCap()``. + +B. **In perpandicular routing direction** (fig. b) the ``_sourcePosition`` + to ``_targetPosition`` interval should cross all the perpandicular + track axis that it has a footprint on. As it may be misaligned and + likely to impinge on the leftmost or rightmost one. In that case, + we must extend by the *minimal spacing* (not it's half). + +.. image:: {static}/images/notes/Katana-Debug_9.png + :alt: Preferred & non-preferred track footprint. + :align: center + :width: 60% + + +The figure below is a simplificated description on how ``AutoSegment::getExtensionCap()`` +compute the extension from the ``sourceU`` coordinate. ``sourceU`` being the +starting or ending coordinate of segment, usually the axis of the perpandicular +it is connected to. + +.. image:: {static}/images/notes/Katana-Debug_6.png + :alt: Preferred & non-preferred track footprint. + :align: center + :width: 60% + + +4. Write topology for NetBuilderVH::_do_2G_1M1() +------------------------------------------------ + +.. image:: {static}/images/notes/Katana-Debug_5.png + :alt: topology of NetBuilderVH::_do_2G_1M1(). + :align: center + :width: 60% + + +4. Allow selection of HV or VH topologies for GF180MCU +------------------------------------------------------ + +In order to ease testing whithout constantly changing the configuration +file, provide a boolean in ``technos.setupGF180MCU_GF()`` to select it. + +In the ``dodo.py``, add: + +.. code-block:: python + + setupGF180MCU_GF( checkToolkit='../../..', pdkTop='../../../../gf180mcu-pdk', useHV=False ) diff --git a/documentation/etc/definitions.rst b/documentation/etc/definitions.rst index d836bc9fb..c67192f37 100644 --- a/documentation/etc/definitions.rst +++ b/documentation/etc/definitions.rst @@ -167,9 +167,9 @@ .. |man| replace:: :cb:`man` -.. |BUG| replace:: **BUG** -.. |NEW| replace:: **NEW** -.. |CHANGE| replace:: **CHANGE** +.. |BUG| replace:: **BUG** | +.. |NEW| replace:: **NEW** | +.. |CHANGE| replace:: **CHANGE** | .. |KeyUp| replace:: :fboxtt:`Up` .. |KeyDown| replace:: :fboxtt:`Down` .. |KeyLeft| replace:: :fboxtt:`Left` @@ -264,3 +264,6 @@ .. |blif| replace:: :cb:`blif` .. |kgr| replace:: :cb:`kgr` .. |dot_conf| replace:: :cb:`.conf` + +.. Link to Hurricane doc (Doxygen) +.. _RoutingPad: {static}/doc/hurricane/classHurricane_1_1RoutingPad.html diff --git a/documentation/meson.build b/documentation/meson.build index 83104b2b1..13f675383 100644 --- a/documentation/meson.build +++ b/documentation/meson.build @@ -10,6 +10,7 @@ pdfcontent = files( rstcontent = files( + 'etc/definitions.rst', 'content/pages/design-flow/DesignFlow_HTML.rst', 'content/pages/design-flow/QuickStart.rst', 'content/pages/documentation.rst', diff --git a/documentation/themes/nest-coriolis/static/css/nest.css b/documentation/themes/nest-coriolis/static/css/nest.css index 0bf90a22b..dc6d133a1 100644 --- a/documentation/themes/nest-coriolis/static/css/nest.css +++ b/documentation/themes/nest-coriolis/static/css/nest.css @@ -121,7 +121,7 @@ code { padding: 3px 6px; } padding-left: 5px; padding-right: 5px; background:#fcfce1; - font-size: 14px; + font-size: 12px; font-weight: 400; font-family: Consolas, monaco, monospace; color: #000; diff --git a/hurricane/src/hurricane/RoutingPad.cpp b/hurricane/src/hurricane/RoutingPad.cpp index d652d6d92..6b9dc3e77 100644 --- a/hurricane/src/hurricane/RoutingPad.cpp +++ b/hurricane/src/hurricane/RoutingPad.cpp @@ -269,12 +269,14 @@ namespace Hurricane { } - std::string RoutingPad::getStringFlags () const { + std::string RoutingPad::getStringFlags () const + { string s; - s += ((_flags & HSmall ) ? "h" : "-"); - s += ((_flags & VSmall ) ? "v" : "-"); - s += ((_flags & Punctual ) ? "p" : "-"); - s += ((_flags & M1Offgrid) ? "o" : "-"); + s += ((_flags & SelectedComponent) ? "S" : "-"); + s += ((_flags & HSmall ) ? "h" : "-"); + s += ((_flags & VSmall ) ? "v" : "-"); + s += ((_flags & Punctual ) ? "p" : "-"); + s += ((_flags & M1Offgrid ) ? "o" : "-"); return s; } diff --git a/hurricane/src/hurricane/hurricane/RoutingPad.h b/hurricane/src/hurricane/hurricane/RoutingPad.h index 583b51258..ab77b6bda 100644 --- a/hurricane/src/hurricane/hurricane/RoutingPad.h +++ b/hurricane/src/hurricane/hurricane/RoutingPad.h @@ -58,6 +58,7 @@ namespace Hurricane { static const uint32_t Punctual = (1 << 8); static const uint32_t M1Offgrid = (1 << 9); static const uint32_t SizeFlags = HSmall|VSmall|Punctual|M1Offgrid; + static const uint32_t SelectedComponent = (1 << 10); public: static RoutingPad* create ( Net*, Occurrence, uint32_t flags=0 ); static RoutingPad* create ( Pin* ); @@ -69,6 +70,7 @@ namespace Hurricane { inline bool isVSmall () const; inline bool isPunctual () const; inline bool isM1Offgrid () const; + inline bool hasSelectedComponent () const; inline uint32_t getFlags () const; inline Occurrence getOccurrence () const; Occurrence getPlugOccurrence (); @@ -112,15 +114,16 @@ namespace Hurricane { }; - inline bool RoutingPad::isAtTopLevel () const { return _occurrence.getPath().isEmpty(); } - inline bool RoutingPad::isHSmall () const { return (_flags & HSmall); } - inline bool RoutingPad::isVSmall () const { return (_flags & VSmall); } - inline bool RoutingPad::isPunctual () const { return (_flags & Punctual); } - inline bool RoutingPad::isM1Offgrid () const { return (_flags & M1Offgrid); } - inline uint32_t RoutingPad::getFlags () const { return _flags; } - inline Occurrence RoutingPad::getOccurrence () const { return _occurrence; }; - inline void RoutingPad::setFlags ( uint32_t flags ) { _flags |= flags; } - inline void RoutingPad::unsetFlags ( uint32_t flags ) { _flags &= ~flags; } + inline bool RoutingPad::isAtTopLevel () const { return _occurrence.getPath().isEmpty(); } + inline bool RoutingPad::isHSmall () const { return (_flags & HSmall); } + inline bool RoutingPad::isVSmall () const { return (_flags & VSmall); } + inline bool RoutingPad::isPunctual () const { return (_flags & Punctual); } + inline bool RoutingPad::isM1Offgrid () const { return (_flags & M1Offgrid); } + inline bool RoutingPad::hasSelectedComponent () const { return (_flags & SelectedComponent); } + inline uint32_t RoutingPad::getFlags () const { return _flags; } + inline Occurrence RoutingPad::getOccurrence () const { return _occurrence; }; + inline void RoutingPad::setFlags ( uint32_t flags ) { _flags |= flags; } + inline void RoutingPad::unsetFlags ( uint32_t flags ) { _flags &= ~flags; } template diff --git a/katana/src/NegociateWindow.cpp b/katana/src/NegociateWindow.cpp index 71f8366a0..42ca1cffa 100644 --- a/katana/src/NegociateWindow.cpp +++ b/katana/src/NegociateWindow.cpp @@ -207,7 +207,10 @@ namespace { size_t rlDepth = depth - rg->getFirstRoutingLayer(); if (rlDepth == 0) { TrackMarker::create( rp, depth+1 ); - //if (isVH) TrackMarker::create( rp, depth+2 ); + // if (rp->isM1Offgrid()) { + // TrackMarker::create( rp, depth+2 ); + // } + // if (isVH) TrackMarker::create( rp, depth+2 ); } if (rlDepth == 1) { if ((depth == 0) and (depth+1 < rg->getDepth())) diff --git a/katana/src/PreProcess.cpp b/katana/src/PreProcess.cpp index fda16fef7..9a6fc819e 100644 --- a/katana/src/PreProcess.cpp +++ b/katana/src/PreProcess.cpp @@ -120,6 +120,7 @@ namespace { void propagateCagedConstraints ( TrackElement* segment, set& faileds ) { + DebugSession::open( segment->getNet(), 150, 160 ); cdebug_log(159,0) << "propagateCagedConstraints(): " << segment << endl; if (not segment->isFixed()) return; @@ -217,6 +218,7 @@ namespace { } cdebug_tabw(159,-1); + DebugSession::close(); } diff --git a/katana/src/RoutingPlane.cpp b/katana/src/RoutingPlane.cpp index ee4fefaf1..c9ef21fe5 100644 --- a/katana/src/RoutingPlane.cpp +++ b/katana/src/RoutingPlane.cpp @@ -160,10 +160,14 @@ namespace Katana { Track* RoutingPlane::getTrackByPosition ( DbU::Unit axis, uint32_t mode ) const { + if (_tracks.empty()) return nullptr; + if (axis < getAxisMin()) return _tracks.front(); + if (axis > getAxisMax()) return _tracks.back(); + size_t index = getLayerGauge()->getTrackIndex( getAxisMin(), getAxisMax(), axis, mode ); if (index == getTracksSize()) { - if (not index) return NULL; - if ((mode == Constant::Superior) or (mode == Constant::Exact)) return NULL; + if (not index) return nullptr; + if ((mode == Constant::Superior) or (mode == Constant::Exact)) return nullptr; --index; } diff --git a/katana/src/SegmentFsm.cpp b/katana/src/SegmentFsm.cpp index 633bb9531..b0cfe1a8c 100644 --- a/katana/src/SegmentFsm.cpp +++ b/katana/src/SegmentFsm.cpp @@ -558,6 +558,8 @@ namespace Katana { Track* baseTrack = plane->getTrackByPosition( segment1->base()->getSourcePosition(), Constant::Superior ); RoutingPlane* perpPlane = plane->getTop(); if (not perpPlane) perpPlane = plane->getBottom(); + cdebug_log(155,0) << "sourcePosition():" << DbU::getValueString(segment1->base()->getSourcePosition()) << endl; + cdebug_log(155,0) << " -> baseTrack:" << baseTrack << endl; for ( Track* ptrack : Tracks_Range::get(perpPlane,_constraint) ) { _costs.push_back( new TrackCost(segment1,NULL,baseTrack,NULL,ptrack->getAxis(),0) ); diff --git a/katana/src/Track.cpp b/katana/src/Track.cpp index 07d1ebcb6..362808151 100644 --- a/katana/src/Track.cpp +++ b/katana/src/Track.cpp @@ -811,13 +811,14 @@ namespace Katana { for ( size_t i=0 ; i<_segments.size() ; i++ ) { if (_segments[i]) { - bool inTrackRange = false; + bool inTrackRange = false; + Interval axisSpan; if (_segments[i]->isNonPref()) { - DbU::Unit min = 0; - DbU::Unit max = 0; - _segments[i]->base()->getCanonical( min, max ); - inTrackRange = Interval(min,max).contains( _axis ); + axisSpan = Interval ( _segments[i]->base()->getSourcePosition() + , _segments[i]->base()->getTargetPosition() ); + axisSpan.inflate( _segments[i]->base()->getExtensionCap( Anabatic::Flags::NoFlags )); + inTrackRange = axisSpan.contains( _axis ); } else { Interval trackRange ( _segments[i]->getAxis() - (_segments[i]->getTrackSpan()*_segments[i]->getPitch())/2 , _segments[i]->getAxis() + (_segments[i]->getTrackSpan()*_segments[i]->getPitch())/2 ); @@ -835,13 +836,16 @@ namespace Katana { cerr << "[CHECK] incoherency at " << i << " " << _segments[i] << " is detached." << endl; coherency = false; - } else { + } else { if ( (_segments[i]->getTrack() != this) and not inTrackRange ) { cerr << "[CHECK] incoherency at " << i << " " - << _segments[i] << " is in track " - << _segments[i]->getTrack() << endl; + << _segments[i] << " (span=" + << _segments[i]->getTrackSpan() << ") " << axisSpan + << "\n is in track " + << this << "\n instead of " + << _segments[i]->getTrack() + << endl; coherency = false; - cerr << _segments[i]->getTrackSpan() << endl; } } if ( (_segments[i]->getAxis() != getAxis()) and not inTrackRange ) { diff --git a/katana/src/TrackElement.cpp b/katana/src/TrackElement.cpp index 0adfa03b0..3d51e7120 100644 --- a/katana/src/TrackElement.cpp +++ b/katana/src/TrackElement.cpp @@ -185,7 +185,6 @@ namespace Katana { TrackElement* TrackElement::getSymmetric () { return NULL; } // Mutators. void TrackElement::addTrackCount ( int32_t ) { } - void TrackElement::setTrack ( Track* track ) { _track = track; } void TrackElement::setSymmetric ( TrackElement* ) { } void TrackElement::updateFreedomDegree () { } void TrackElement::setDoglegLevel ( uint32_t ) { } @@ -277,6 +276,14 @@ namespace Katana { } + void TrackElement::setTrack ( Track* track ) + { + cdebug_log(155,0) << "TrackElement::setTrack(): " << this << endl; + cdebug_log(155,0) << " -> " << track << endl; + _track = track; + } + + string TrackElement::_getTypeName () const { return "TrackElement"; } diff --git a/katana/src/TrackSegment.cpp b/katana/src/TrackSegment.cpp index 77382dfbe..23870a200 100644 --- a/katana/src/TrackSegment.cpp +++ b/katana/src/TrackSegment.cpp @@ -487,7 +487,7 @@ namespace Katana { if (isNonPref()) { Interval perpandicularSpan ( getAxis() ); - perpandicularSpan.inflate( base()->getExtensionCap( Anabatic::Flags::Source ) ); + perpandicularSpan.inflate( base()->getExtensionCap( Anabatic::Flags::Source )); _sourceU = perpandicularSpan.getVMin(); _targetU = perpandicularSpan.getVMax(); diff --git a/katana/src/TrackSegmentNonPref.cpp b/katana/src/TrackSegmentNonPref.cpp index d1f5afd18..3b9d3a157 100644 --- a/katana/src/TrackSegmentNonPref.cpp +++ b/katana/src/TrackSegmentNonPref.cpp @@ -98,8 +98,13 @@ namespace Katana { RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(_base->getLayer()); Interval newAxisSpan ( _base->getSourcePosition(), _base->getTargetPosition() ); + //newAxisSpan.inflate( base()->getExtensionCap( Anabatic::Flags::NoFlags )); Track* ntrack = plane->getTrackByPosition( newAxisSpan.getVMin(), Constant::Superior ); + cdebug_log(159,0) << "getSourceU(): " << DbU::getValueString( _base->getSourceU() ) << endl; + cdebug_log(159,0) << "getTargetU(): " << DbU::getValueString( _base->getTargetU() ) << endl; + cdebug_log(159,0) << "getSourcePosition(): " << DbU::getValueString( _base->getSourcePosition() ) << endl; + cdebug_log(159,0) << "getTargetPosition(): " << DbU::getValueString( _base->getTargetPosition() ) << endl; cdebug_log(159,0) << "new Axis span: " << newAxisSpan << endl; if (ntrack) { From 1a98984cb9132ea777ee5fbd37832600c121d8b5 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Thu, 21 Dec 2023 16:44:55 +0100 Subject: [PATCH 22/51] New type of LayerRoutingGauge : LocalOnly, for local interconnect. --- anabatic/src/EdgeCapacity.cpp | 4 ++-- anabatic/src/GCell.cpp | 6 ++++-- .../technos/node180/gf180mcu/mcu9t5v0.py | 2 +- crlcore/src/ccore/RoutingGauge.cpp | 18 ++++++++++++++---- crlcore/src/ccore/crlcore/RoutingGauge.h | 5 ++++- crlcore/src/ccore/crlcore/RoutingLayerGauge.h | 11 +++++++++-- crlcore/src/pyCRL/PyConstant.cpp | 1 + crlcore/src/pyCRL/PyRoutingLayerGauge.cpp | 5 +++++ cumulus/src/plugins/block/configuration.py | 2 ++ katana/src/ProtectRoutingPads.cpp | 2 +- katana/src/RoutingPlane.cpp | 3 --- katana/src/Track.cpp | 2 +- 12 files changed, 44 insertions(+), 17 deletions(-) diff --git a/anabatic/src/EdgeCapacity.cpp b/anabatic/src/EdgeCapacity.cpp index 84e944ddd..1d48a1906 100644 --- a/anabatic/src/EdgeCapacity.cpp +++ b/anabatic/src/EdgeCapacity.cpp @@ -54,14 +54,14 @@ namespace Anabatic { if (layerGauges[depth]->getDirection() != Constant::Horizontal) continue; _capacities[depth] = layerGauges[depth]->getTrackNumber( span.getVMin() - ab.getYMin() , span.getVMax() - ab.getYMin() ); - //cdebug_log(110,0) << "Horizontal edge capacity:" << capacity << endl; + //cdebug_log(110,0) << "Horizontal edge capacity:" << _capacities[depth] << endl; } if (_flags & Flags::Vertical) { if (layerGauges[depth]->getDirection() != Constant::Vertical) continue; _capacities[depth] = layerGauges[depth]->getTrackNumber( span.getVMin() - ab.getXMin() , span.getVMax() - ab.getXMin() ); - //cdebug_log(110,0) << "Vertical edge capacity:" << capacity << endl; + //cdebug_log(110,0) << "Vertical edge capacity:" << _capacities[depth] << endl; } } } diff --git a/anabatic/src/GCell.cpp b/anabatic/src/GCell.cpp index beeedea02..21d13f963 100644 --- a/anabatic/src/GCell.cpp +++ b/anabatic/src/GCell.cpp @@ -324,7 +324,7 @@ namespace Anabatic { _fragmentations[i] = 0.0; _globalsCount [i] = 0.0; - if (Session::getRoutingGauge()->getLayerGauge(i)->getType() == Constant::PinOnly) + if (not Session::getRoutingGauge()->getLayerGauge(i)->isUsable()) ++_pinDepth; } @@ -1349,7 +1349,7 @@ namespace Anabatic { for ( size_t depth=0 ; depth<_depth ; ++depth ) { RoutingLayerGauge* rlg = Session::getLayerGauge( depth ); - if (rlg->getType() & Constant::PinOnly) continue; + if (not rlg->isUsable()) continue; if (_densities[depth] >= 0.9) { if (depth+2 < _depth) { Edge* edge = (rlg->getDirection() == Constant::Vertical) ? getNorthEdge() @@ -1557,6 +1557,8 @@ namespace Anabatic { int contiguousNonSaturated = 0; for ( size_t i=0 ; i<_depth ; i++ ) { uLengths2[i] += _blockages[i]; + if (Session::getLayerGauge(i)->getType() & Constant::LocalOnly) + continue; if (Session::getLayerGauge(i)->getType() & Constant::PinOnly) continue; if (Session::getLayerGauge(i)->getType() & Constant::PowerSupply) diff --git a/crlcore/python/technos/node180/gf180mcu/mcu9t5v0.py b/crlcore/python/technos/node180/gf180mcu/mcu9t5v0.py index cc8d7bfb2..0d9090bfc 100644 --- a/crlcore/python/technos/node180/gf180mcu/mcu9t5v0.py +++ b/crlcore/python/technos/node180/gf180mcu/mcu9t5v0.py @@ -39,7 +39,7 @@ def _routing ( useHV ): rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer( 'Metal1' ) # metal , dirM1 # preferred routing direction - , RoutingLayerGauge.PinOnly # layer usage + , RoutingLayerGauge.LocalOnly # layer usage , 0 # depth , 0.0 # density (deprecated) , u(0.0) # track offset from AB diff --git a/crlcore/src/ccore/RoutingGauge.cpp b/crlcore/src/ccore/RoutingGauge.cpp index 983e793c8..05ec24b10 100644 --- a/crlcore/src/ccore/RoutingGauge.cpp +++ b/crlcore/src/ccore/RoutingGauge.cpp @@ -161,7 +161,7 @@ namespace CRL { for ( size_t i=_firstRoutingLayer ; i<_layerGauges.size() ; ++i ) { RoutingLayerGauge* gauge = _layerGauges[i]; if (gauge->isHorizontal()) { - if (gauge->getType() != Constant::LayerGaugeType::PinOnly) + if (gauge->isUsable()) return gauge; else if (not pinOnly) pinOnly = gauge; @@ -177,7 +177,7 @@ namespace CRL { for ( size_t i=_firstRoutingLayer ; i<_layerGauges.size() ; ++i ) { RoutingLayerGauge* gauge = _layerGauges[i]; if (gauge->isVertical()) { - if (gauge->getType() != Constant::LayerGaugeType::PinOnly) + if (gauge->isUsable()) return gauge; else if (not pinOnly) pinOnly = gauge; @@ -185,6 +185,16 @@ namespace CRL { } return pinOnly; } + + + bool RoutingGauge::isUsable ( const Layer* layer ) const + { + for ( size_t i=0 ; i < _layerGauges.size() ; i++ ) { + if (_layerGauges[i]->getLayer()->getMask() == layer->getMask()) + return _layerGauges[i]->isUsable(); + } + return false; + } RoutingLayerGauge* RoutingGauge::getLayerGauge ( size_t depth ) const @@ -358,8 +368,8 @@ namespace CRL { ,getString(_layerGauges[i ]->getLayer()).c_str() ,getString(_layerGauges[i+1]->getLayer()).c_str()) << endl; } - if ( _layerGauges[i+1]->getType() == Constant::PinOnly ) { - cerr << Error("In %s: only first layer can be PinOnly.\n" + if ( not _layerGauges[i+1]->isUsable() ) { + cerr << Error("In %s: only first layer can be PinOnly or LocalOnly.\n" " (%s at depth %d)" ,getString(this).c_str() ,getString(_layerGauges[i+1]).c_str() diff --git a/crlcore/src/ccore/crlcore/RoutingGauge.h b/crlcore/src/ccore/crlcore/RoutingGauge.h index 7ca0ed34d..c257bbae2 100644 --- a/crlcore/src/ccore/crlcore/RoutingGauge.h +++ b/crlcore/src/ccore/crlcore/RoutingGauge.h @@ -74,6 +74,7 @@ namespace CRL { RoutingLayerGauge* getVerticalGauge () const; RoutingLayerGauge* getPowerSupplyGauge () const; RoutingLayerGauge* getLayerGauge ( const Layer* ) const; + bool isUsable ( const Layer* ) const; size_t getViaDepth ( const Layer* ) const; size_t getLayerDepth ( const Layer* ) const; unsigned int getLayerType ( const Layer* ) const; @@ -86,8 +87,9 @@ namespace CRL { RoutingLayerGauge* getLayerGauge ( size_t depth ) const; const Layer* getRoutingLayer ( size_t depth ) const; Layer* getContactLayer ( size_t depth ) const; - inline unsigned int getLayerDirection ( size_t depth ) const; + inline bool isUsable ( size_t depth ) const; inline unsigned int getLayerType ( size_t depth ) const; + inline unsigned int getLayerDirection ( 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; @@ -140,6 +142,7 @@ namespace CRL { inline DbU::Unit RoutingGauge::getVerticalPitch () const { return getVerticalGauge ()->getPitch(); } inline size_t RoutingGauge::getDepth () const { return _layerGauges.size(); } inline DbU::Unit RoutingGauge::getViaWidth ( size_t depth ) const { return getLayerGauge(depth)->getViaWidth(); } + inline bool RoutingGauge::isUsable ( size_t depth ) const { return getLayerGauge(depth)->isUsable(); } inline unsigned int RoutingGauge::getLayerType ( size_t depth ) const { return getLayerGauge(depth)->getType(); } inline unsigned int RoutingGauge::getLayerDirection ( size_t depth ) const { return getLayerGauge(depth)->getDirection(); } inline DbU::Unit RoutingGauge::getLayerPitch ( size_t depth ) const { return getLayerGauge(depth)->getPitch(); } diff --git a/crlcore/src/ccore/crlcore/RoutingLayerGauge.h b/crlcore/src/ccore/crlcore/RoutingLayerGauge.h index f42172614..b5546f670 100644 --- a/crlcore/src/ccore/crlcore/RoutingLayerGauge.h +++ b/crlcore/src/ccore/crlcore/RoutingLayerGauge.h @@ -38,8 +38,9 @@ namespace Constant { , Unusable = (1 << 4) , PowerSupply = (1 << 5) , PinOnly = (1 << 6) - , Default = (1 << 7) - , BottomPowerSupply = (1 << 8) + , LocalOnly = (1 << 7) + , Default = (1 << 8) + , BottomPowerSupply = (1 << 9) }; enum Round { Superior = (1 << 10) @@ -94,6 +95,7 @@ namespace CRL { // Accessors. inline bool isHorizontal () const; inline bool isVertical () const; + inline bool isUsable () const; inline const Layer* getLayer () const; inline const Layer* getBlockageLayer () const; unsigned int getDepth () const; @@ -178,6 +180,8 @@ namespace CRL { inline bool RoutingLayerGauge::isHorizontal () const { return (_direction == Constant::Direction::Horizontal); } inline bool RoutingLayerGauge::isVertical () const { return (_direction == Constant::Direction::Vertical); } + inline bool RoutingLayerGauge::isUsable () const { return (_type != Constant::LayerGaugeType::PinOnly) + and (_type != Constant::LayerGaugeType::LocalOnly); } inline const Layer* RoutingLayerGauge::getLayer () const { return _layer; } inline unsigned int RoutingLayerGauge::getDepth () const { return _depth; } inline const Layer* RoutingLayerGauge::getBlockageLayer () const { return _blockageLayer; } @@ -270,6 +274,7 @@ inline void from ( Constant::LayerGaugeType& type, const std::string& s ) { if (s == "Unusable" ) type = Constant::Unusable; else if (s == "PinOnly" ) type = Constant::PinOnly; + else if (s == "LocalOnly" ) type = Constant::LocalOnly; else if (s == "PowerSupply" ) type = Constant::PowerSupply; else if (s == "PowerSupply|Bottom") type = Constant::BottomPowerSupply; else { @@ -289,6 +294,7 @@ inline std::string getString case Constant::Bottom: return "Bottom (error)"; case Constant::Unusable: return "Unusable"; case Constant::PinOnly: return "PinOnly"; + case Constant::LocalOnly: return "LocalOnly"; case Constant::Default: return "Default"; case Constant::PowerSupply: return "PowerSupply"; case Constant::BottomPowerSupply: return "PowerSupply|Bottom"; @@ -311,6 +317,7 @@ inline std::string getString case Constant::Bottom: return "Bottom (error)"; case Constant::Unusable: return "Unusable"; case Constant::PinOnly: return "PinOnly"; + case Constant::LocalOnly: return "LocalOnly"; case Constant::Default: return "Default"; case Constant::PowerSupply: return "PowerSupply"; case Constant::BottomPowerSupply: return "PowerSupply|Bottom"; diff --git a/crlcore/src/pyCRL/PyConstant.cpp b/crlcore/src/pyCRL/PyConstant.cpp index 100eb4504..faa5a8e0b 100644 --- a/crlcore/src/pyCRL/PyConstant.cpp +++ b/crlcore/src/pyCRL/PyConstant.cpp @@ -62,6 +62,7 @@ extern "C" { LoadObjectConstant( dictionnary, Constant::Vertical , "Vertical" ) LoadObjectConstant( dictionnary, Constant::Default , "Default" ) LoadObjectConstant( dictionnary, Constant::PinOnly , "PinOnly" ) + LoadObjectConstant( dictionnary, Constant::LocalOnly , "LocalOnly" ) LoadObjectConstant( dictionnary, Constant::Superior , "Superior" ) LoadObjectConstant( dictionnary, Constant::Inferior , "Inferior" ) LoadObjectConstant( dictionnary, Constant::Nearest , "Nearest" ) diff --git a/crlcore/src/pyCRL/PyRoutingLayerGauge.cpp b/crlcore/src/pyCRL/PyRoutingLayerGauge.cpp index 944f376ff..07a622fe3 100644 --- a/crlcore/src/pyCRL/PyRoutingLayerGauge.cpp +++ b/crlcore/src/pyCRL/PyRoutingLayerGauge.cpp @@ -111,6 +111,7 @@ extern "C" { case Constant::BottomPowerSupply: case Constant::PowerSupply: case Constant::PinOnly: + case Constant::LocalOnly: case Constant::Default: break; default: PyErr_SetString ( ConstructorError, "Bad value for type argument of RoutingLayerGauge.create()." ); @@ -267,6 +268,7 @@ extern "C" { DirectGetUIntAttribute (PyRoutingLayerGauge_getDirection ,getDirection ,PyRoutingLayerGauge,RoutingLayerGauge) DirectGetUIntAttribute (PyRoutingLayerGauge_getType ,getType ,PyRoutingLayerGauge,RoutingLayerGauge) DirectGetDoubleAttribute(PyRoutingLayerGauge_getDensity ,getDensity ,PyRoutingLayerGauge,RoutingLayerGauge) + DirectGetBoolAttribute (PyRoutingLayerGauge_isUsable ,isUsable ,PyRoutingLayerGauge,RoutingLayerGauge) DirectGetLongAttribute (PyRoutingLayerGauge_getOffset ,getOffset ,PyRoutingLayerGauge,RoutingLayerGauge) DirectGetLongAttribute (PyRoutingLayerGauge_getPitch ,getPitch ,PyRoutingLayerGauge,RoutingLayerGauge) DirectGetLongAttribute (PyRoutingLayerGauge_getHalfPitch ,getHalfPitch ,PyRoutingLayerGauge,RoutingLayerGauge) @@ -286,6 +288,8 @@ extern "C" { PyMethodDef PyRoutingLayerGauge_Methods[] = { { "create" , (PyCFunction)PyRoutingLayerGauge_create , METH_VARARGS|METH_STATIC , "Create a new RoutingLayerGauge." } + , { "isUsable" , (PyCFunction)PyRoutingLayerGauge_isUsable , METH_NOARGS + , "Tells if the layer is usable for standard routing." } , { "getLayer" , (PyCFunction)PyRoutingLayerGauge_getLayer , METH_NOARGS , "Returns the associated routing layer." } , { "getBlockageLayer" , (PyCFunction)PyRoutingLayerGauge_getBlockageLayer, METH_NOARGS @@ -357,6 +361,7 @@ extern "C" { LoadObjectConstant(PyTypeRoutingLayerGauge.tp_dict,Constant::Vertical ,"Vertical" ); LoadObjectConstant(PyTypeRoutingLayerGauge.tp_dict,Constant::Unusable ,"Unusable" ); LoadObjectConstant(PyTypeRoutingLayerGauge.tp_dict,Constant::PinOnly ,"PinOnly" ); + LoadObjectConstant(PyTypeRoutingLayerGauge.tp_dict,Constant::LocalOnly ,"LocalOnly" ); LoadObjectConstant(PyTypeRoutingLayerGauge.tp_dict,Constant::PowerSupply ,"PowerSupply" ); LoadObjectConstant(PyTypeRoutingLayerGauge.tp_dict,Constant::BottomPowerSupply,"BottomPowerSupply" ); LoadObjectConstant(PyTypeRoutingLayerGauge.tp_dict,Constant::Default ,"Default" ); diff --git a/cumulus/src/plugins/block/configuration.py b/cumulus/src/plugins/block/configuration.py index b010c83e4..e556b2694 100644 --- a/cumulus/src/plugins/block/configuration.py +++ b/cumulus/src/plugins/block/configuration.py @@ -175,6 +175,8 @@ def _loadRoutingGauge ( self ): continue if self._routingGauge.getLayerGauge(depth).getType() == RoutingLayerGauge.PinOnly: continue + if self._routingGauge.getLayerGauge(depth).getType() == RoutingLayerGauge.LocalOnly: + continue if self._routingGauge.getLayerGauge(depth).getType() == RoutingLayerGauge.BottomPowerSupply: continue if self._routingGauge.getLayerGauge(depth).getType() == RoutingLayerGauge.PowerSupply: diff --git a/katana/src/ProtectRoutingPads.cpp b/katana/src/ProtectRoutingPads.cpp index af8486950..ace7f8efb 100644 --- a/katana/src/ProtectRoutingPads.cpp +++ b/katana/src/ProtectRoutingPads.cpp @@ -90,7 +90,7 @@ namespace { cdebug_tabw(145,-1); return; } - if (Session::getRoutingGauge()->getLayerType(usedComponent->getLayer()) == Constant::PinOnly) { + if (not Session::getRoutingGauge()->isUsable(usedComponent->getLayer())) { cdebug_tabw(145,-1); return; } diff --git a/katana/src/RoutingPlane.cpp b/katana/src/RoutingPlane.cpp index c9ef21fe5..aa171a489 100644 --- a/katana/src/RoutingPlane.cpp +++ b/katana/src/RoutingPlane.cpp @@ -95,9 +95,6 @@ namespace Katana { if (not plane->_layerGauge) throw Error( badLayerGauge, depth, getString(katana->getConfiguration()->getRoutingGauge()).c_str() ); - uint32_t gaugeDepth = 0; - if (Session::getLayerGauge(gaugeDepth)->getType() == Constant::PinOnly) ++gaugeDepth; - DbU::Unit extensionCap = ( std::max( Session::getWireWidth(depth), Session::getViaWidth(depth) ) + Session::getPitch(depth) ) / 2; diff --git a/katana/src/Track.cpp b/katana/src/Track.cpp index 362808151..f4d13b861 100644 --- a/katana/src/Track.cpp +++ b/katana/src/Track.cpp @@ -1220,7 +1220,7 @@ namespace Katana { { if (not getKatanaEngine()->getTrackFill()) return; if (getIndex() % getKatanaEngine()->getTrackFill() != 0) return; - if (getLayerGauge()->getType() == Constant::PinOnly) return; + if (not getLayerGauge()->isUsable()) return; if (getLayerGauge()->getDepth() > getKatanaEngine()->getConfiguration()->getAllowedDepth()) return; Net* fillNet = getKatanaEngine()->getCell()->getNet( "dummy_filler_net" ); From d4105d8fe3aae2bce6ab68766b15bf1aeb80d435 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Thu, 21 Dec 2023 16:46:44 +0100 Subject: [PATCH 23/51] Do not process the blockages layers in FlattenPower (not needed). --- etesian/src/FlattenPower.cpp | 5 ++--- hurricane/src/hurricane/hurricane/Query.h | 22 +++++++++++++--------- katana/src/PowerRails.cpp | 14 ++++++++++---- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/etesian/src/FlattenPower.cpp b/etesian/src/FlattenPower.cpp index b8483c8d8..e45b1d14f 100644 --- a/etesian/src/FlattenPower.cpp +++ b/etesian/src/FlattenPower.cpp @@ -952,7 +952,7 @@ namespace Etesian { string gaugeName = Cfg::getParamString("anabatic.routingGauge","sxlib")->asString(); RoutingGauge* rg = AllianceFramework::get()->getRoutingGauge( gaugeName ); if (not rg) - throw Error( "EtesianEngine::falttenPower(): No routing gauge named \"%s\"", gaugeName.c_str() ); + throw Error( "EtesianEngine::flattenPower(): No routing gauge named \"%s\"", gaugeName.c_str() ); //DebugSession::open( 150, 160 ); UpdateSession::open(); @@ -962,8 +962,7 @@ namespace Etesian { query.setStopCellFlags( Cell::Flags::AbstractedSupply ); for ( BasicLayer* layer : technology->getBasicLayers() ) { - if ( (layer->getMaterial() != BasicLayer::Material::metal) - and (layer->getMaterial() != BasicLayer::Material::blockage) ) + if (layer->getMaterial() != BasicLayer::Material::metal) continue; if (not query.hasBasicLayer(layer)) continue; diff --git a/hurricane/src/hurricane/hurricane/Query.h b/hurricane/src/hurricane/hurricane/Query.h index 3324cbe08..24d923419 100644 --- a/hurricane/src/hurricane/hurricane/Query.h +++ b/hurricane/src/hurricane/hurricane/Query.h @@ -130,6 +130,7 @@ namespace Hurricane { inline void setStartLevel ( unsigned int level ); inline void setStopLevel ( unsigned int level ); inline void setStopCellFlags ( Cell::Flags ); + inline void unsetStopCellFlags ( Cell::Flags ); inline void init (); inline void updateTransformation (); inline bool levelDown (); @@ -197,6 +198,7 @@ namespace Hurricane { inline void QueryStack::setStartLevel ( unsigned int level ) { _startLevel = level; } inline void QueryStack::setStopLevel ( unsigned int level ) { _stopLevel = level; } inline void QueryStack::setStopCellFlags ( Cell::Flags flags ) { _stopCellFlags = flags; } + inline void QueryStack::unsetStopCellFlags ( Cell::Flags flags ) { _stopCellFlags.reset(flags); } inline void QueryStack::init () @@ -372,6 +374,7 @@ namespace Hurricane { inline void setStartLevel ( unsigned int level ); inline void setStopLevel ( unsigned int level ); inline void setStopCellFlags ( Cell::Flags ); + inline void unsetStopCellFlags ( Cell::Flags ); virtual void doQuery (); protected: @@ -385,15 +388,16 @@ namespace Hurricane { // Query Inline Functions. - inline void Query::setCell ( Cell* cell ) { _stack.setTopCell(cell); } - inline void Query::setArea ( const Box& area ) { _stack.setTopArea(area); } - inline void Query::setThreshold ( DbU::Unit threshold ) { _stack.setThreshold(threshold); } - inline void Query::setTransformation ( const Transformation& transformation ) { _stack.setTopTransformation(transformation); } - inline void Query::setFilter ( Mask filter ) { _filter = filter; } - inline void Query::setExtensionMask ( ExtensionSlice::Mask mask ) { _extensionMask = mask; } - inline void Query::setStartLevel ( unsigned int level ) { _stack.setStartLevel(level); } - inline void Query::setStopLevel ( unsigned int level ) { _stack.setStopLevel(level); } - inline void Query::setStopCellFlags ( Cell::Flags flags ) { _stack.setStopCellFlags(flags); } + inline void Query::setCell ( Cell* cell ) { _stack.setTopCell(cell); } + inline void Query::setArea ( const Box& area ) { _stack.setTopArea(area); } + inline void Query::setThreshold ( DbU::Unit threshold ) { _stack.setThreshold(threshold); } + inline void Query::setTransformation ( const Transformation& transformation ) { _stack.setTopTransformation(transformation); } + inline void Query::setFilter ( Mask filter ) { _filter = filter; } + inline void Query::setExtensionMask ( ExtensionSlice::Mask mask ) { _extensionMask = mask; } + inline void Query::setStartLevel ( unsigned int level ) { _stack.setStartLevel(level); } + inline void Query::setStopLevel ( unsigned int level ) { _stack.setStopLevel(level); } + inline void Query::setStopCellFlags ( Cell::Flags flags ) { _stack.setStopCellFlags(flags); } + inline void Query::unsetStopCellFlags ( Cell::Flags flags ) { _stack.unsetStopCellFlags(flags); } inline unsigned int Query::getStartLevel () const { return _stack.getStartLevel(); } inline unsigned int Query::getStopLevel () const { return _stack.getStopLevel(); } diff --git a/katana/src/PowerRails.cpp b/katana/src/PowerRails.cpp index 32e9bd401..806f9a43f 100644 --- a/katana/src/PowerRails.cpp +++ b/katana/src/PowerRails.cpp @@ -510,8 +510,8 @@ namespace { << " , ww/2:" << DbU::getValueString(plane->getLayerGauge()->getHalfWireWidth()) << ")" << endl; - // if ( type == Constant::PinOnly ) { - // cdebug_log(159,0) << " Layer is PinOnly." << endl; + // if ( (type == Constant::PinOnly) or (type == Constant::LocalOnly) ) { + // cdebug_log(159,0) << " Layer is PinOnly or LocalOnly." << endl; // return; // } @@ -813,7 +813,7 @@ namespace { _planes.insert( make_pair(basicLayer,new Plane(lg->getLayer(),rp)) ); - //if (lg->getType() == Constant::PinOnly) continue; + //if (not lg->isUsable()) continue; const BasicLayer* blockageLayer = dynamic_cast( lg->getBlockageLayer() ); if (not blockageLayer) continue; @@ -981,6 +981,12 @@ namespace { if (not activePlane) return; + if (static_cast(activePlane->getLayer())->getMaterial() + != BasicLayer::Material::blockage) + setStopCellFlags( Cell::Flags::AbstractedSupply ); + else + unsetStopCellFlags( Cell::Flags::AbstractedSupply ); + cmess1 << " - PowerRails in " << activePlane->getLayer()->getName() << " ..." << endl; Query::doQuery(); } @@ -1103,6 +1109,7 @@ namespace { << " " << basicLayer << endl; _powerRailsPlanes.merge( bb, rootNet ); + } else { } } } @@ -1195,7 +1202,6 @@ namespace Katana { QueryPowerRails query ( this ); Technology* technology = DataBase::getDB()->getTechnology(); - query.setStopCellFlags( Cell::Flags::AbstractedSupply ); for ( BasicLayer* layer : technology->getBasicLayers() ) { if ( (layer->getMaterial() != BasicLayer::Material::metal) and (layer->getMaterial() != BasicLayer::Material::blockage) ) From 65cae59e29dfafea21df08f35db29498024c7d33 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 26 Dec 2023 15:38:40 +0100 Subject: [PATCH 24/51] A DebugSession was left open in Katana::PropagateCagedConstraints(). --- katana/src/PreProcess.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/katana/src/PreProcess.cpp b/katana/src/PreProcess.cpp index 9a6fc819e..bd41d8d6e 100644 --- a/katana/src/PreProcess.cpp +++ b/katana/src/PreProcess.cpp @@ -137,6 +137,7 @@ namespace { if ( not track ) { cerr << Bug( "%s is not inserted in a ", getString(segment).c_str() ) << endl; + DebugSession::close(); return; } @@ -168,12 +169,15 @@ namespace { if (minConstraint > maxConstraint) { cerr << Bug( "%s have too tight caging constraints.", getString(segment).c_str() ) << endl; + cdebug_tabw(159,-1); + DebugSession::close(); return; } if ( (minConstraint <= uside.getVMin()) and (maxConstraint >= uside.getVMax()) ) { cdebug_log(159,0) << "No constraints [" << DbU::getValueString(minConstraint) << ":" << DbU::getValueString(maxConstraint) << " vs. " << uside << endl; + DebugSession::close(); return; } @@ -204,6 +208,7 @@ namespace { if (perpandiculars.size() == 0) { cdebug_log(159,0) << "No perpandiculars to " << segment << endl; cdebug_tabw(159,-1); + DebugSession::close(); return; } From aff70efd9292392e8f7b0c711a9691673c491c2e Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 26 Dec 2023 15:47:49 +0100 Subject: [PATCH 25/51] Create a new type of TrakElement : TrackBlockage. * TrackBlockage do not rely on an existing AutoSegment, or even a Segment, it is a portion of Track that we declare as blocked. * Used to manage the blockages coming for the LocalOnly planes, typically terminal planes. As it is not related to a Segment, we do not need to flatten the obstacles coming from the standard cells (would be a lot of them). * In PowerRails, also support blockages from Rectilinear, decomposed in vertical rectangles. * In Session, add a mechanism for TrackElement that have been put in their track *before* closing the session (used for TrackBlockage). --- katana/src/PowerRails.cpp | 89 +++++++---- katana/src/Session.cpp | 24 ++- katana/src/TrackBlockage.cpp | 245 ++++++++++++++++++++++++++++++ katana/src/katana/TrackBlockage.h | 87 +++++++++++ katana/src/katana/TrackElement.h | 31 ++-- katana/src/meson.build | 1 + 6 files changed, 425 insertions(+), 52 deletions(-) create mode 100644 katana/src/TrackBlockage.cpp create mode 100644 katana/src/katana/TrackBlockage.h diff --git a/katana/src/PowerRails.cpp b/katana/src/PowerRails.cpp index 806f9a43f..dc5a24500 100644 --- a/katana/src/PowerRails.cpp +++ b/katana/src/PowerRails.cpp @@ -38,6 +38,7 @@ #include "anabatic/GCell.h" #include "katana/RoutingPlane.h" #include "katana/TrackFixedSegment.h" +#include "katana/TrackBlockage.h" #include "katana/Track.h" #include "katana/KatanaEngine.h" @@ -1050,7 +1051,7 @@ namespace { } const Segment* segment = dynamic_cast(component); - if ( segment != NULL ) { + if (segment) { _goMatchCount++; cdebug_log(159,0) << " Merging PowerRail element: " << segment << endl; @@ -1073,46 +1074,74 @@ namespace { transformation.applyOn ( bb ); _powerRailsPlanes.merge ( bb, rootNet ); - } else { - const Contact* contact = dynamic_cast(component); - if ( contact != NULL ) { - _goMatchCount++; + return; + } - Box bb = contact->getBoundingBox ( basicLayer ); - transformation.applyOn ( bb ); + const Contact* contact = dynamic_cast(component); + if (contact) { + _goMatchCount++; - cdebug_log(159,0) << " Merging PowerRail element: " << contact << " bb:" << bb - << " " << basicLayer << endl; + Box bb = contact->getBoundingBox ( basicLayer ); + transformation.applyOn ( bb ); + + cdebug_log(159,0) << " Merging PowerRail element: " << contact << " bb:" << bb + << " " << basicLayer << endl; - _powerRailsPlanes.merge ( bb, rootNet ); - } else { - const Pad* pad = dynamic_cast(component); - if (pad != NULL) { - _goMatchCount++; + _powerRailsPlanes.merge ( bb, rootNet ); + return; + } - Box bb = pad->getBoundingBox( basicLayer ); - transformation.applyOn( bb ); + const Pad* pad = dynamic_cast(component); + if (pad) { + _goMatchCount++; + + Box bb = pad->getBoundingBox( basicLayer ); + transformation.applyOn( bb ); - cdebug_log(159,0) << " Merging PowerRail element: " << pad << " bb:" << bb - << " " << basicLayer << endl; - - _powerRailsPlanes.merge( bb, rootNet ); - } else { - const Rectilinear* rectilinear = dynamic_cast(component); - if (rectilinear and (rectilinear->getPoints().size() == 5)) { - _goMatchCount++; + cdebug_log(159,0) << " Merging PowerRail element: " << pad << " bb:" << bb + << " " << basicLayer << endl; + + _powerRailsPlanes.merge( bb, rootNet ); + return; + } - Box bb = rectilinear->getBoundingBox( basicLayer ); - transformation.applyOn( bb ); + const Rectilinear* rectilinear = dynamic_cast(component); + if (rectilinear and (rectilinear->getPoints().size() == 5)) { + _goMatchCount++; + + Box bb = rectilinear->getBoundingBox( basicLayer ); + transformation.applyOn( bb ); - cdebug_log(159,0) << " Merging PowerRail element: " << rectilinear << " bb:" << bb - << " " << basicLayer << endl; + cdebug_log(159,0) << " Merging PowerRail element: " << rectilinear << " bb:" << bb + << " " << basicLayer << endl; - _powerRailsPlanes.merge( bb, rootNet ); - } else { + _powerRailsPlanes.merge( bb, rootNet ); + return; + } + + if (rectilinear) { + if (not _powerRailsPlanes.getActivePlane()->getLayer()->isBlockage()) return; + _goMatchCount++; + + RoutingPlane* plane = _powerRailsPlanes.getActivePlane()->getRoutingPlane(); + RoutingLayerGauge* rlg = plane->getLayerGauge(); + DbU::Unit delta = plane->getLayerGauge()->getPitch() - 1; + vector boxes; + rectilinear->getAsRectangles( boxes ); + if (rlg->isHorizontal()) { + for ( Box bb : boxes ) { + transformation.applyOn( bb ); + DbU::Unit axisMin = bb.getYMin() - delta; + DbU::Unit axisMax = bb.getYMax() + delta; + + Track* track = plane->getTrackByPosition( axisMin, Constant::Superior ); + for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNextTrack() ) { + TrackElement* element = TrackBlockage::create ( track, bb ); + cdebug_log(159,0) << " Insert in " << track << "+" << element << endl; } } } + return; } } } diff --git a/katana/src/Session.cpp b/katana/src/Session.cpp index 8d7be68ff..dd7f51ee8 100644 --- a/katana/src/Session.cpp +++ b/katana/src/Session.cpp @@ -258,6 +258,7 @@ namespace Katana { _doRemovalEvents(); //if (checkTrack) checkTrack->check( overlaps, "Session::_revalidate() - check track 82 @270." ); + cdebug_log(159,1) << "Processing Track insert event" << endl; for ( const Event& event : _insertEvents ) { if (event._segment) { if (event._segment->getAxis() != event._axis) event._segment->setAxis( event._axis ); @@ -266,6 +267,7 @@ namespace Katana { if (event._marker) event._track->insert( event._marker ); } _insertEvents.clear(); + cdebug_log(159,-1) << "Insert events processeds" << endl; _doRemovalEvents( false ); //if (checkTrack) checkTrack->check( overlaps, "Session::_revalidate() - check track 82 @270." ); @@ -418,14 +420,20 @@ namespace Katana { << "\n @" << DbU::getValueString(axis) << " " << track << endl; - if ( check and (segment->getTrack() != NULL) ) { - cerr << Bug("Session::addInsertEvent(): Segment already in Track." - "\n %s." - "\n to %s." - ,getString(segment).c_str() - ,getString(track).c_str() - ) << endl; - return; + if (segment->getTrack()) { + if (segment->isForwardSetTrack()) { + segment->unsetFlags( TElemForwardSetTrack ); + } else { + if (check) { + cerr << Bug( "Session::addInsertEvent(): Segment already in Track." + "\n %s." + "\n to %s." + , getString(segment).c_str() + , getString(track).c_str() + ) << endl; + return; + } + } } _insertEvents.push_back( Event(segment,track,axis) ); diff --git a/katana/src/TrackBlockage.cpp b/katana/src/TrackBlockage.cpp new file mode 100644 index 000000000..040558c19 --- /dev/null +++ b/katana/src/TrackBlockage.cpp @@ -0,0 +1,245 @@ +// -*- 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@lip6.fr | +// | =============================================================== | +// | C++ Module : "./TrackBlockage.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include "hurricane/Bug.h" +#include "hurricane/Warning.h" +#include "hurricane/Net.h" +#include "hurricane/Name.h" +#include "hurricane/RegularLayer.h" +#include "hurricane/Technology.h" +#include "hurricane/DataBase.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "anabatic/AutoContact.h" +#include "crlcore/RoutingGauge.h" +#include "katana/DataNegociate.h" +#include "katana/TrackBlockage.h" +#include "katana/TrackCost.h" +#include "katana/Track.h" +#include "katana/RoutingPlane.h" +#include "katana/Session.h" +#include "katana/RoutingEvent.h" +#include "katana/NegociateWindow.h" +#include "katana/KatanaEngine.h" + + +namespace Katana { + + using namespace std; + using Hurricane::Warning; + using Hurricane::Bug; + using Hurricane::Error; + using Hurricane::Net; + using Hurricane::Name; + using Hurricane::RegularLayer; + using Hurricane::Technology; + using Hurricane::DataBase; + using Hurricane::Horizontal; + using Hurricane::Vertical; + using Anabatic::GCellsUnder; + + +// ------------------------------------------------------------------- +// Class : "TrackBlockage". + + + TrackBlockage::TrackBlockage ( Track* track, Box boundingBox ) + : TrackElement(NULL) + , _boundingBox(boundingBox) + { + cdebug_log(159,0) << "TrackBlockage::TrackBlockage() track=" << track << endl; + + setFlags( TElemFixed|TElemBlockage|TElemForwardSetTrack ); + setTrack( track ); + + uint32_t depth = track->getDepth(); + //Technology* technology = DataBase::getDB()->getTechnology(); + //const Layer* layer1 = track->getLayer()->getBlockageLayer(); + //RegularLayer* layer2 = dynamic_cast(technology->getLayer(layer1->getMask())); + //if (layer2) { + //cerr << track->getLayer() << " minSpace:" << DbU::getValueString(track->getLayer()->getMinimalSpacing()) << endl; + + Point source; + Point target; + Interval segside; + Interval uside = track->getKatanaEngine()->getUSide( track->getDirection() ); + DbU::Unit cap = track->getLayer()->getMinimalSpacing()/2 /*+ track->getLayer()->getExtentionCap()*/; + cdebug_log(159,0) << "uside:" << uside << " cap:" << DbU::getValueString(cap) << endl; + cdebug_log(159,0) << "bb:" << boundingBox << endl; + if (track->getDirection() == Flags::Horizontal) { + segside = Interval( boundingBox.getXMin(), boundingBox.getXMax() ); + _sourceU = max( boundingBox.getXMin() - cap, uside.getVMin()); + _targetU = min( boundingBox.getXMax() + cap, uside.getVMax()); + source = Point( boundingBox.getXMin(), track->getAxis() ); + target = Point( boundingBox.getXMax(), track->getAxis() ); + } else { + segside = Interval( boundingBox.getYMin(), boundingBox.getYMax() ); + _sourceU = max( boundingBox.getYMin() - cap, uside.getVMin()); + _targetU = min( boundingBox.getYMax() + cap, uside.getVMax()); + source = Point( track->getAxis(), boundingBox.getYMin() ); + target = Point( track->getAxis(), boundingBox.getYMax() ); + } + + if (track->getRoutingPlane()->getLayerGauge()->isUsable()) { + Flags gcellFlags = Flags::NoFlags; + GCellsUnder gcells = track->getKatanaEngine()->getGCellsUnder( source, target ); + for ( size_t i=0 ; isize() ; ++i ) { + GCell* gcell = gcells->gcellAt(i); + gcell->addBlockage + ( depth, gcell->getSide( track->getDirection() ).getIntersection( segside ).getSize() ); + gcell->flags() |= gcellFlags; + } + } + } + + + void TrackBlockage::_postCreate () + { TrackElement::_postCreate(); } + + + TrackBlockage::~TrackBlockage () + { } + + + void TrackBlockage::_preDestroy () + { + cdebug_log(155,0) << "TrackBlockage::_preDestroy() - " << (void*)this << endl; + TrackElement::_preDestroy(); + } + + + TrackElement* TrackBlockage::create ( Track* track, Box boundingBox ) + { + TrackBlockage* trackBlockage = NULL; + if (not track) + throw Error( "TrackBlockage::create(): NULL track argument." ); + + cdebug_log(159,0) << "TrackBlockage::create() track:" << track << endl; + trackBlockage = new TrackBlockage ( track, boundingBox ); + trackBlockage->_postCreate(); + cdebug_log(159,0) << "TrackBlockage::create(): " << trackBlockage << endl; + Session::addInsertEvent( trackBlockage, track, track->getAxis() ); + return trackBlockage; + } + + + AutoSegment* TrackBlockage::base () const { return NULL; } + Segment* TrackBlockage::getSegment () const { return NULL; } + DbU::Unit TrackBlockage::getAxis () const { return getTrack()->getAxis(); } + bool TrackBlockage::isHorizontal () const { return getTrack()->isHorizontal(); } + bool TrackBlockage::isVertical () const { return getTrack()->isVertical(); } + bool TrackBlockage::isFixed () const { return true; } + bool TrackBlockage::isPriorityLocked () const { return false; } + Flags TrackBlockage::getDirection () const { return getTrack()->getDirection(); } + DbU::Unit TrackBlockage::getWidth () const { return _boundingBox.getWidth(); } + const Layer* TrackBlockage::getLayer () const { return getTrack()->getLayer(); } + unsigned int TrackBlockage::getDepth () const { return Session::getLayerDepth(getLayer()); } + Interval TrackBlockage::getFreeInterval () const { return Interval(); } + size_t TrackBlockage::getTrackSpan () const { return 1; } + + + DbU::Unit TrackBlockage::getSourceAxis () const + { return (isHorizontal()) ? _boundingBox.getXMin() : _boundingBox.getYMin(); } + + + DbU::Unit TrackBlockage::getTargetAxis () const + { return (isHorizontal()) ? _boundingBox.getXMax() : _boundingBox.getYMax(); } + + + unsigned long TrackBlockage::getId () const + { + cerr << Error("::getId() called on %s.",_getString().c_str()) << endl; + return 0; + } + + + Net* TrackBlockage::getNet () const + { return Session::getBlockageNet(); } + + + TrackElement* TrackBlockage::getNext () const + { + size_t dummy = _track->find( this ); + return _track->getNext( dummy, getNet() ); + } + + + TrackElement* TrackBlockage::getPrevious () const + { + size_t dummy = _track->find( this ); + return _track->getPrevious( dummy, getNet() ); + } + + + void TrackBlockage::addOverlapCost ( TrackCost& cost ) const + { cost.getTrack()->addOverlapCost( cost ); } + + + float TrackBlockage::getPriority () const + { return 0.0; } + + + void TrackBlockage::setPriorityLock ( bool ) + { } + + + void TrackBlockage::forcePriority ( float ) + { } + + + void TrackBlockage::computePriority () + { } + + + void TrackBlockage::computeAlignedPriority () + { } + + + void TrackBlockage::detach ( TrackSet& removeds ) + { + // cerr << Error( "TrackBlockage::detach(): Must never be called on %s." + // , getString(this).c_str()) << endl; + } + + + string TrackBlockage::_getTypeName () const + { return "TrackBlockage"; } + + + string TrackBlockage::_getString () const + { + string s1 = string("getIndex()) + "] " + + getString(getLayer()->getName()) + " @" + + DbU::getValueString(getTrack()->getAxis()) + + " [" + DbU::getValueString(_sourceU) + + ":" + DbU::getValueString(_targetU) + "]" + + " " + DbU::getValueString(_targetU-_sourceU) + + " FBN>"; + return s1; + } + + + Record* TrackBlockage::_getRecord () const + { + Record* record = TrackElement::_getRecord(); + record->add( getSlot( "_boundingBox", &_boundingBox ) ); + return record; + } + + +} // Katana namespace. diff --git a/katana/src/katana/TrackBlockage.h b/katana/src/katana/TrackBlockage.h new file mode 100644 index 000000000..3246b3279 --- /dev/null +++ b/katana/src/katana/TrackBlockage.h @@ -0,0 +1,87 @@ +// -*- 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++ Header : "./katana/TrackBlockage.h" | +// +-----------------------------------------------------------------+ + + +#pragma once +#include "katana/TrackElement.h" + + +namespace Katana { + + using std::string; + using std::map; + using Hurricane::Record; + using Hurricane::Interval; + using Hurricane::DbU; + using Hurricane::Net; + using Hurricane::Layer; + + class Track; + + +// ------------------------------------------------------------------- +// Class : "TrackBlockage". + + class TrackBlockage : public TrackElement { + public: + static TrackElement* create ( Katana::Track*, Box ); + public: + virtual AutoSegment* base () const; + virtual Segment* getSegment () const; + virtual bool isHorizontal () const; + virtual bool isVertical () const; + virtual bool isFixed () const; + virtual bool isPriorityLocked () const; + virtual unsigned long getId () const; + virtual Flags getDirection () const; + virtual Net* getNet () const; + virtual DbU::Unit getWidth () const; + virtual unsigned int getDepth () const; + virtual const Layer* getLayer () const; + virtual size_t getTrackSpan () const; + virtual TrackElement* getNext () const; + virtual TrackElement* getPrevious () const; + virtual DbU::Unit getAxis () const; + inline DbU::Unit getSourceAxis () const; + virtual DbU::Unit getTargetAxis () const; + virtual Interval getFreeInterval () const; + virtual void addOverlapCost ( TrackCost& ) const; + virtual float getPriority () const; + virtual void setPriorityLock ( bool ); + virtual void forcePriority ( float ); + virtual void computePriority (); + virtual void computeAlignedPriority (); + virtual void detach ( TrackSet& ); + virtual Record* _getRecord () const; + virtual string _getString () const; + virtual string _getTypeName () const; + private: + Box _boundingBox; + protected: + // Constructors & Destructors. + TrackBlockage ( Track*, Box ) ; + virtual ~TrackBlockage (); + virtual void _postCreate (); + virtual void _preDestroy (); + private: + TrackBlockage ( const TrackBlockage& ) = delete; + TrackBlockage& operator= ( const TrackBlockage& ) = delete; + }; + + +} // Katana namespace. + + +INSPECTOR_P_SUPPORT(Katana::TrackBlockage); diff --git a/katana/src/katana/TrackElement.h b/katana/src/katana/TrackElement.h index 12fa0dc3a..cfd8e5343 100644 --- a/katana/src/katana/TrackElement.h +++ b/katana/src/katana/TrackElement.h @@ -64,20 +64,21 @@ namespace Katana { // ------------------------------------------------------------------- // Class : "TrackElement". - const uint32_t TElemCreated = (1 << 0); - const uint32_t TElemBlockage = (1 << 2); - const uint32_t TElemFixed = (1 << 3); - const uint32_t TElemLocked = (1 << 4); - const uint32_t TElemRouted = (1 << 5); - const uint32_t TElemUseBlockageNet = (1 << 6); - const uint32_t TElemShortDogleg = (1 << 7); - const uint32_t TElemSourceDogleg = (1 << 8); - const uint32_t TElemTargetDogleg = (1 << 9); - const uint32_t TElemAlignBottom = (1 << 10); - const uint32_t TElemAlignCenter = (1 << 11); - const uint32_t TElemAlignTop = (1 << 12); - const uint32_t TElemRipple = (1 << 13); - const uint32_t TElemInvalidated = (1 << 14); + const uint32_t TElemCreated = (1 << 0); + const uint32_t TElemBlockage = (1 << 2); + const uint32_t TElemFixed = (1 << 3); + const uint32_t TElemLocked = (1 << 4); + const uint32_t TElemRouted = (1 << 5); + const uint32_t TElemUseBlockageNet = (1 << 6); + const uint32_t TElemShortDogleg = (1 << 7); + const uint32_t TElemSourceDogleg = (1 << 8); + const uint32_t TElemTargetDogleg = (1 << 9); + const uint32_t TElemAlignBottom = (1 << 10); + const uint32_t TElemAlignCenter = (1 << 11); + const uint32_t TElemAlignTop = (1 << 12); + const uint32_t TElemRipple = (1 << 13); + const uint32_t TElemInvalidated = (1 << 14); + const uint32_t TElemForwardSetTrack = (1 << 15); struct Compare { @@ -131,6 +132,7 @@ namespace Katana { inline bool isBlockage () const; inline bool isLocked () const; inline bool isRouted () const; + inline bool isForwardSetTrack () const; virtual bool hasSymmetric () const; inline bool hasSourceDogleg () const; inline bool hasTargetDogleg () const; @@ -256,6 +258,7 @@ namespace Katana { inline bool TrackElement::isBlockage () const { return _flags & TElemBlockage; } inline bool TrackElement::isLocked () const { return _flags & TElemLocked; } inline bool TrackElement::isRouted () const { return _flags & TElemRouted; } + inline bool TrackElement::isForwardSetTrack () const { return _flags & TElemForwardSetTrack; } inline bool TrackElement::hasSourceDogleg () const { return _flags & TElemSourceDogleg; } inline bool TrackElement::hasTargetDogleg () const { return _flags & TElemTargetDogleg; } inline bool TrackElement::canRipple () const { return _flags & TElemRipple; } diff --git a/katana/src/meson.build b/katana/src/meson.build index 401ed6769..f0bed8e56 100644 --- a/katana/src/meson.build +++ b/katana/src/meson.build @@ -21,6 +21,7 @@ katana = shared_library( 'Block.cpp', 'DataNegociate.cpp', 'DataSymmetric.cpp', + 'TrackBlockage.cpp', 'TrackCost.cpp', 'TrackElement.cpp', 'TrackElements.cpp', From b715212ae491619f3a119a33823e5b538b341483 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 26 Dec 2023 15:50:00 +0100 Subject: [PATCH 26/51] More adjustements for the perpandicular track span & positions. --- anabatic/src/AutoHorizontal.cpp | 4 ++-- anabatic/src/AutoSegment.cpp | 3 ++- anabatic/src/AutoVertical.cpp | 4 ++-- katana/src/TrackSegmentNonPref.cpp | 1 - 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/anabatic/src/AutoHorizontal.cpp b/anabatic/src/AutoHorizontal.cpp index 77b8f3764..c0a3af301 100644 --- a/anabatic/src/AutoHorizontal.cpp +++ b/anabatic/src/AutoHorizontal.cpp @@ -542,7 +542,7 @@ namespace Anabatic { _sourcePosition = getSourceU() - getExtensionCap(Flags::Source); _targetPosition = getTargetU() + getExtensionCap(Flags::Target); if (isNonPref()) { - DbU::Unit halfCap = getExtensionCap( Flags::NoFlags ); + DbU::Unit halfCap = getExtensionCap( Flags::NoFlags ) -1; _sourcePosition -= halfCap; _targetPosition += halfCap; } @@ -568,7 +568,7 @@ namespace Anabatic { DbU::Unit sourcePosition = _horizontal->getSource()->getX() - getExtensionCap(Flags::Source); DbU::Unit targetPosition = _horizontal->getTarget()->getX() + getExtensionCap(Flags::Target); if (isNonPref()) { - DbU::Unit halfCap = getExtensionCap( Flags::NoFlags ); + DbU::Unit halfCap = getExtensionCap( Flags::NoFlags ) -1; sourcePosition -= halfCap; targetPosition += halfCap; } diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index 98653ab6e..a8fa962c2 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -807,7 +807,8 @@ namespace Anabatic { } } } else { - cap = getViaToBottomCap( depth ); + //cap = getViaToBottomCap( depth ); + cap = getViaToSameCap( depth ); // cdebug_log(150,0) << "getExtensionCap(): (force bottom) flags:" << getFlags() // << " VIA cap:" << DbU::getValueString(cap) // << endl; diff --git a/anabatic/src/AutoVertical.cpp b/anabatic/src/AutoVertical.cpp index 1cc33294f..72bf5d4c0 100644 --- a/anabatic/src/AutoVertical.cpp +++ b/anabatic/src/AutoVertical.cpp @@ -433,7 +433,7 @@ namespace Anabatic { _sourcePosition = getSourceU() - getExtensionCap(Flags::Source); _targetPosition = getTargetU() + getExtensionCap(Flags::Target); if (isNonPref()) { - DbU::Unit halfCap = getExtensionCap( Flags::NoFlags ); + DbU::Unit halfCap = getExtensionCap( Flags::NoFlags ) - 1; _sourcePosition -= halfCap; _targetPosition += halfCap; } @@ -459,7 +459,7 @@ namespace Anabatic { DbU::Unit sourcePosition = _vertical->getSource()->getY() - getExtensionCap(Flags::Source); DbU::Unit targetPosition = _vertical->getTarget()->getY() + getExtensionCap(Flags::Target); if (isNonPref()) { - DbU::Unit halfCap = getExtensionCap( Flags::NoFlags ); + DbU::Unit halfCap = getExtensionCap( Flags::NoFlags ) - 1; sourcePosition -= halfCap; targetPosition += halfCap; } diff --git a/katana/src/TrackSegmentNonPref.cpp b/katana/src/TrackSegmentNonPref.cpp index 3b9d3a157..e985d0756 100644 --- a/katana/src/TrackSegmentNonPref.cpp +++ b/katana/src/TrackSegmentNonPref.cpp @@ -98,7 +98,6 @@ namespace Katana { RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(_base->getLayer()); Interval newAxisSpan ( _base->getSourcePosition(), _base->getTargetPosition() ); - //newAxisSpan.inflate( base()->getExtensionCap( Anabatic::Flags::NoFlags )); Track* ntrack = plane->getTrackByPosition( newAxisSpan.getVMin(), Constant::Superior ); cdebug_log(159,0) << "getSourceU(): " << DbU::getValueString( _base->getSourceU() ) << endl; From e8d5582d6ae33baff6a328d66cb2172a6be99ef6 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 26 Dec 2023 19:06:29 +0100 Subject: [PATCH 27/51] Keep track of the position of the BreakpointWidget. --- hurricane/src/viewer/BreakpointWidget.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/hurricane/src/viewer/BreakpointWidget.cpp b/hurricane/src/viewer/BreakpointWidget.cpp index ce5272417..ed1295d92 100644 --- a/hurricane/src/viewer/BreakpointWidget.cpp +++ b/hurricane/src/viewer/BreakpointWidget.cpp @@ -43,14 +43,16 @@ namespace Hurricane { //_message->setTextFormat ( Qt::RichText ); _message->setText ( "No Message Yet" ); + _message->setSizePolicy ( QSizePolicy::Expanding, QSizePolicy::Expanding ); QLabel* stopLabel = new QLabel (); stopLabel->setText ( "Adjust Stop Level:" ); QPushButton* ok = new QPushButton (); - ok->setIcon ( QIcon(":/images/angry-birds-chuck.png") ); - ok->setFlat ( true ); - ok->setIconSize ( (Graphics::isHighDpi() ? QSize(200,200) : QSize(80,80)) ); + ok->setIcon ( QIcon(":/images/angry-birds-chuck.png") ); + ok->setFlat ( true ); + ok->setIconSize ( (Graphics::isHighDpi() ? QSize(200,200) : QSize(80,80)) ); + ok->setSizePolicy ( QSizePolicy::Fixed, QSizePolicy::Fixed ); QFrame* vLine = new QFrame (); vLine->setFrameShape ( QFrame::VLine ); @@ -58,7 +60,7 @@ namespace Hurricane { QGridLayout* layout = new QGridLayout (); //layout->setSizeConstraint ( QLayout::SetFixedSize ); - layout->addWidget ( _message , 0, 0 ); + layout->addWidget ( _message , 0, 0, 1, 2 ); layout->addWidget ( stopLabel , 1, 0 ); layout->addWidget ( _stopLevel, 1, 1 ); layout->addWidget ( vLine , 0, 2, 2, 1 ); @@ -73,6 +75,8 @@ namespace Hurricane { int BreakpointWidget::execNoModal () { + static QRect position; + if (isVisible()) return -1; // while (QApplication::hasPendingEvents()) { @@ -83,6 +87,7 @@ namespace Hurricane { _isFinished = false; show (); + if (not position.isNull()) setGeometry( position ); // Snipet code from Qt's QDialog. _eventLoop = new QEventLoop (); @@ -90,6 +95,7 @@ namespace Hurricane { _eventLoop->exec( QEventLoop::DialogExec ); _eventLoop = NULL; + position = geometry(); if (guard.isNull()) return QDialog::Rejected; return result(); From b624c77368d93e2cfe70f291a1ddfa29d7e94200 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Thu, 28 Dec 2023 16:57:05 +0100 Subject: [PATCH 28/51] Display the "ripup ratio" in Katana::Statistics (NegociateWidow). --- .../pages/technical-log/December_2023.rst | 11 ++ documentation/etc/definitions.rst | 5 + katana/src/NegociateWindow.cpp | 112 +++++++++--------- katana/src/katana/NegociateWindow.h | 61 ++++++---- 4 files changed, 112 insertions(+), 77 deletions(-) diff --git a/documentation/content/pages/technical-log/December_2023.rst b/documentation/content/pages/technical-log/December_2023.rst index 266e58bfc..3f4633721 100644 --- a/documentation/content/pages/technical-log/December_2023.rst +++ b/documentation/content/pages/technical-log/December_2023.rst @@ -158,3 +158,14 @@ In the ``dodo.py``, add: .. code-block:: python setupGF180MCU_GF( checkToolkit='../../..', pdkTop='../../../../gf180mcu-pdk', useHV=False ) + + +|NEW| Display the "ripup ratio" in Katana::Statistics +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This ratio is an attempt at characterizing the *hardness* of a design +(very elusive concept). It is crudely done for now, as it is just a +ratio between the initial number of events (which is equal to the +number of |TrackElements| to place). It do not take into account the +dogleg creation process that will introduce more primary events +as the net topologie are slackened. diff --git a/documentation/etc/definitions.rst b/documentation/etc/definitions.rst index c67192f37..663afca6d 100644 --- a/documentation/etc/definitions.rst +++ b/documentation/etc/definitions.rst @@ -267,3 +267,8 @@ .. Link to Hurricane doc (Doxygen) .. _RoutingPad: {static}/doc/hurricane/classHurricane_1_1RoutingPad.html +.. |AutoSegment| replace:: :cb:`AutoSegment` +.. |AutoSegments| replace:: :cb:`AutoSegments` +.. |TrackElement| replace:: :cb:`TrackElement` +.. |TrackElements| replace:: :cb:`TrackElements` + diff --git a/katana/src/NegociateWindow.cpp b/katana/src/NegociateWindow.cpp index 42ca1cffa..daffb1e2a 100644 --- a/katana/src/NegociateWindow.cpp +++ b/katana/src/NegociateWindow.cpp @@ -624,6 +624,7 @@ namespace Katana { _eventQueue.load( _segments ); cmess2 << " " << endl; if (cdebug.enabled(9000)) _eventQueue.dump(); + _statistics.setLoadedEventsCount( _eventQueue.size() ); size_t count = 0; _katana->setStage( StageNegociate ); @@ -668,69 +669,69 @@ namespace Katana { event->process( _eventQueue, _eventHistory, _eventLoop ); count++; - // if (event->getSegment()->getNet()->getId() == 239546) { - // UpdateSession::close(); - // ostringstream message; - // message << "After processing an event from Net id:239546\n" << event; - // Breakpoint::stop( 0, message.str() ); - // UpdateSession::open(); - // } + //if (event->getSegment()->getNet()->getId() == 239546) { + // UpdateSession::close(); + // ostringstream message; + // message << "After processing an event from Net id:239546\n" << event; + // Breakpoint::stop( 0, message.str() ); + // UpdateSession::open(); + //} //if (count and not (count % 500)) { // _pack( count, false ); //} - // if (RoutingEvent::getProcesseds() == 65092) { - // UpdateSession::close(); - // Breakpoint::stop( 0, "Overlap has happened" ); - // UpdateSession::open(); - // } + //if (RoutingEvent::getProcesseds() == 65092) { + // UpdateSession::close(); + // Breakpoint::stop( 0, "Overlap has happened" ); + // UpdateSession::open(); + //} if (RoutingEvent::getProcesseds() >= limit) setInterrupt( true ); } + _statistics.setProcessedEventsCount( RoutingEvent::getProcesseds() ); //_pack( count, true ); - _negociateRepair(); + _negociateRepair(); - if (_katana->getConfiguration()->runRealignStage()) { - cmess1 << " o Realign Stage." << endl; - - cdebug_log(159,0) << "Loadind realign queue." << endl; - _katana->setStage( StageRealign ); - for ( size_t i=0 ; (i<_eventHistory.size()) and not isInterrupted() ; i++ ) { - RoutingEvent* event = _eventHistory.getNth(i); - if (not event->isCloned() and event->getSegment()->canRealign()) - event->reschedule( _eventQueue, 0 ); - } - _eventQueue.commit(); - cmess2 << " " << setfill(' ') << endl; - count = 0; - while ( not _eventQueue.empty() and not isInterrupted() ) { - RoutingEvent* event = _eventQueue.pop(); - if (tty::enabled()) { - cmess2 << " " - << setfill(' ') << tty::reset << tty::cr; - cmess2.flush(); - } else { - cmess2 << " getEventLevel() << ":" << event->getPriority() << "> " - << event->getSegment() - << endl; - cmess2.flush(); - } - event->process( _eventQueue, _eventHistory, _eventLoop ); - count++; - if (RoutingEvent::getProcesseds() >= limit) setInterrupt( true ); + if (_katana->getConfiguration()->runRealignStage()) { + cmess1 << " o Realign Stage." << endl; + + cdebug_log(159,0) << "Loadind realign queue." << endl; + _katana->setStage( StageRealign ); + for ( size_t i=0 ; (i<_eventHistory.size()) and not isInterrupted() ; i++ ) { + RoutingEvent* event = _eventHistory.getNth(i); + if (not event->isCloned() and event->getSegment()->canRealign()) + event->reschedule( _eventQueue, 0 ); + } + _eventQueue.commit(); + cmess2 << " " << setfill(' ') << endl; + count = 0; + while ( not _eventQueue.empty() and not isInterrupted() ) { + RoutingEvent* event = _eventQueue.pop(); + if (tty::enabled()) { + cmess2 << " " + << setfill(' ') << tty::reset << tty::cr; + cmess2.flush(); + } else { + cmess2 << " getEventLevel() << ":" << event->getPriority() << "> " + << event->getSegment() + << endl; + cmess2.flush(); } - - _negociateRepair(); + event->process( _eventQueue, _eventHistory, _eventLoop ); + count++; + if (RoutingEvent::getProcesseds() >= limit) setInterrupt( true ); } - if (count and cmess2.enabled() and tty::enabled()) cmess1 << endl; - //} + _negociateRepair(); + } + + if (count and cmess2.enabled() and tty::enabled()) cmess1 << endl; size_t eventsCount = _eventHistory.size(); @@ -860,9 +861,14 @@ namespace Katana { void NegociateWindow::printStatistics () const { + float ripupRatio = 100.0 * _statistics.getRipupRatio(); + ostringstream os; + os << setprecision(2) << fixed << ripupRatio << "%"; + cmess1 << " o Computing statistics." << endl; - cmess1 << Dots::asSizet(" - Processeds Events Total",RoutingEvent::getProcesseds()) << endl; - cmess1 << Dots::asSizet(" - Unique Events Total" + cmess1 << Dots::asString( " - Event ripup ratio", os.str() ) << endl; + cmess1 << Dots::asSizet ( " - Processeds Events Total",RoutingEvent::getProcesseds()) << endl; + cmess1 << Dots::asSizet ( " - Unique Events Total" ,(RoutingEvent::getProcesseds() - RoutingEvent::getCloneds())) << endl; cmess1 << Dots::asSizet(" - # of GCells",_statistics.getGCellsCount()) << endl; _katana->printCompletion(); diff --git a/katana/src/katana/NegociateWindow.h b/katana/src/katana/NegociateWindow.h index a48cc587c..243f5ba33 100644 --- a/katana/src/katana/NegociateWindow.h +++ b/katana/src/katana/NegociateWindow.h @@ -39,40 +39,53 @@ namespace Katana { class Statistics { public: - inline Statistics (); - inline size_t getGCellsCount () const; - inline size_t getSegmentsCount () const; - inline size_t getEventsCount () const; - inline void setGCellsCount ( size_t ); - inline void setSegmentsCount ( size_t ); - inline void setEventsCount ( size_t ); - inline void incGCellCount ( size_t ); - inline void incSegmentsCount ( size_t ); - inline void incEventsCount ( size_t ); - inline Statistics& operator+= ( const Statistics& ); + inline Statistics (); + inline size_t getGCellsCount () const; + inline size_t getSegmentsCount () const; + inline size_t getEventsCount () const; + inline size_t getLoadedEventsCount () const; + inline size_t getProcessedEventsCount () const; + inline float getRipupRatio () const; + inline void setGCellsCount ( size_t ); + inline void setSegmentsCount ( size_t ); + inline void setEventsCount ( size_t ); + inline void setLoadedEventsCount ( size_t ); + inline void setProcessedEventsCount ( size_t ); + inline void incGCellCount ( size_t ); + inline void incSegmentsCount ( size_t ); + inline void incEventsCount ( size_t ); + inline Statistics& operator+= ( const Statistics& ); private: size_t _gcellsCount; size_t _segmentsCount; size_t _eventsCount; - + size_t _loadedEventsCount; + size_t _processedEventsCount; }; inline Statistics::Statistics () - : _gcellsCount (0) - , _segmentsCount (0) - , _eventsCount (0) + : _gcellsCount (0) + , _segmentsCount (0) + , _eventsCount (0) + , _loadedEventsCount (0) + , _processedEventsCount(0) { } - inline size_t Statistics::getGCellsCount () const { return _gcellsCount; } - inline size_t Statistics::getSegmentsCount () const { return _segmentsCount; } - inline size_t Statistics::getEventsCount () const { return _eventsCount; } - inline void Statistics::setGCellsCount ( size_t count ) { _gcellsCount = count; } - inline void Statistics::setSegmentsCount ( size_t count ) { _segmentsCount = count; } - inline void Statistics::setEventsCount ( size_t count ) { _eventsCount = count; } - inline void Statistics::incGCellCount ( size_t count ) { _gcellsCount += count; } - inline void Statistics::incSegmentsCount ( size_t count ) { _segmentsCount += count; } - inline void Statistics::incEventsCount ( size_t count ) { _eventsCount += count; } + inline size_t Statistics::getGCellsCount () const { return _gcellsCount; } + inline size_t Statistics::getSegmentsCount () const { return _segmentsCount; } + inline size_t Statistics::getEventsCount () const { return _eventsCount; } + inline size_t Statistics::getLoadedEventsCount () const { return _loadedEventsCount; } + inline size_t Statistics::getProcessedEventsCount () const { return _processedEventsCount; } + inline float Statistics::getRipupRatio () const { return (_loadedEventsCount) ? ((float)(_processedEventsCount - _loadedEventsCount) / (float)_loadedEventsCount) : 0.0; } + inline void Statistics::setGCellsCount ( size_t count ) { _gcellsCount = count; } + inline void Statistics::setSegmentsCount ( size_t count ) { _segmentsCount = count; } + inline void Statistics::setLoadedEventsCount ( size_t count ) { _loadedEventsCount = count; } + inline void Statistics::setProcessedEventsCount ( size_t count ) { _processedEventsCount = count; } + inline void Statistics::setEventsCount ( size_t count ) { _eventsCount = count; } + inline void Statistics::incGCellCount ( size_t count ) { _gcellsCount += count; } + inline void Statistics::incSegmentsCount ( size_t count ) { _segmentsCount += count; } + inline void Statistics::incEventsCount ( size_t count ) { _eventsCount += count; } inline Statistics& Statistics::operator+= ( const Statistics& other ) { From 4db450ed34ccb7f024c65c00a73bf288a95f6292 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Sat, 30 Dec 2023 16:35:27 +0100 Subject: [PATCH 29/51] Support saving & restoring positions and settings of graphic windows. --- crlcore/src/LibraryManager/LibraryManager.cpp | 21 +++++ .../LibraryManager/crlcore/LibraryManager.h | 8 +- .../pages/technical-log/December_2023.rst | 26 +++++++ hurricane/src/viewer/BreakpointWidget.cpp | 31 +++++++- hurricane/src/viewer/CellViewer.cpp | 42 ++++++++-- hurricane/src/viewer/ControllerWidget.cpp | 77 +++++++++++++++++++ hurricane/src/viewer/DisplayFilterWidget.cpp | 53 +++++++++++++ hurricane/src/viewer/GraphicsWidget.cpp | 24 ++++++ hurricane/src/viewer/HApplication.cpp | 21 +++-- hurricane/src/viewer/NetlistWidget.cpp | 20 +++++ hurricane/src/viewer/PaletteWidget.cpp | 28 +++++++ .../hurricane/viewer/BreakpointWidget.h | 34 ++++---- .../src/viewer/hurricane/viewer/CellViewer.h | 16 ++++ .../hurricane/viewer/ControllerWidget.h | 22 ++++-- .../hurricane/viewer/DisplayFilterWidget.h | 11 +-- .../viewer/hurricane/viewer/GraphicsWidget.h | 11 +-- .../viewer/hurricane/viewer/HApplication.h | 17 ++-- .../viewer/hurricane/viewer/NetlistWidget.h | 2 + .../viewer/hurricane/viewer/PaletteWidget.h | 2 + unicorn/src/UnicornGui.cpp | 39 ++++++++-- unicorn/src/unicorn/UnicornGui.h | 2 + 21 files changed, 427 insertions(+), 80 deletions(-) diff --git a/crlcore/src/LibraryManager/LibraryManager.cpp b/crlcore/src/LibraryManager/LibraryManager.cpp index ac29980a7..5cf1f8290 100644 --- a/crlcore/src/LibraryManager/LibraryManager.cpp +++ b/crlcore/src/LibraryManager/LibraryManager.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -170,4 +171,24 @@ namespace CRL { { _cellsWidget->updateLibrary(); } + void LibraryManager::readQtSettings () + { + QSettings settings; + QString sizeKey = QString( "LibraryManager/geometry" ); + if (not settings.contains(sizeKey)) return; + settings.beginGroup( QString("LibraryManager") ); + restoreGeometry( settings.value( "geometry" ).toByteArray() ); + settings.endGroup(); + } + + + void LibraryManager::saveQtSettings () + { + QSettings settings; + settings.beginGroup( QString("LibraryManager") ); + settings.setValue( "geometry", saveGeometry() ); + settings.endGroup(); + } + + } // CRL namespace. diff --git a/crlcore/src/LibraryManager/crlcore/LibraryManager.h b/crlcore/src/LibraryManager/crlcore/LibraryManager.h index 285b486c7..884821f06 100644 --- a/crlcore/src/LibraryManager/crlcore/LibraryManager.h +++ b/crlcore/src/LibraryManager/crlcore/LibraryManager.h @@ -14,9 +14,7 @@ // +-----------------------------------------------------------------+ -#ifndef CRL_LIBRARY_MANAGER_H -#define CRL_LIBRARY_MANAGER_H - +#pragma once #include #include "hurricane/Observer.h" @@ -54,6 +52,8 @@ namespace CRL { public: LibraryManager ( QWidget* parent=NULL ); ~LibraryManager (); + void readQtSettings (); + void saveQtSettings (); inline void setCellViewer ( CellViewer* ); inline CellViewer* getCellViewer () const; inline LibrariesWidget* getLibrariesWidget () const; @@ -78,5 +78,3 @@ namespace CRL { } // CRL namespace. - -#endif // CRL_LIBRARY_WIDGET_H diff --git a/documentation/content/pages/technical-log/December_2023.rst b/documentation/content/pages/technical-log/December_2023.rst index 3f4633721..14342871c 100644 --- a/documentation/content/pages/technical-log/December_2023.rst +++ b/documentation/content/pages/technical-log/December_2023.rst @@ -169,3 +169,29 @@ ratio between the initial number of events (which is equal to the number of |TrackElements| to place). It do not take into account the dogleg creation process that will introduce more primary events as the net topologie are slackened. + + +|NEW| Support saving & restoring positions and settings of graphic windows +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The positions of the windows and *some* of the settings of the controller +can be saved and restored. The saving does not occurs at the closing of +the application. You have to take a *snapshot* of the state using the +``File -> Save settings`` menu. This allow to restart the application +in an initial state of your choosing and not at point you left it the +last time it was run. + +Widgets supporting the saving of their configuration gets two more methods: + +.. code:: C++ + + MyWidget::saveQtSettings(); + MyWidget::readQtSettings(); + +Currently we are saving: + +* ``UnicornGui`` +* ``CellViewer`` +* ``LibraryManager`` +* ``ControllerWidget`` and some of it's tabs. +* ``Breakpoint`` diff --git a/hurricane/src/viewer/BreakpointWidget.cpp b/hurricane/src/viewer/BreakpointWidget.cpp index ed1295d92..38d24ea07 100644 --- a/hurricane/src/viewer/BreakpointWidget.cpp +++ b/hurricane/src/viewer/BreakpointWidget.cpp @@ -14,6 +14,7 @@ // +-----------------------------------------------------------------+ +#include #include #include #include @@ -29,6 +30,30 @@ namespace Hurricane { + QByteArray BreakpointWidget::_geometry; + + + void BreakpointWidget::readQtSettings () + { + QSettings settings; + QString sizeKey = QString( "BreakpointWidget/geometry" ); + if (not settings.contains(sizeKey)) return; + settings.beginGroup( QString("BreakpointWidget") ); + _geometry = settings.value( "geometry" ).toByteArray(); + settings.endGroup(); + } + + + void BreakpointWidget::saveQtSettings () + { + if (_geometry.isNull()) return; + QSettings settings; + settings.beginGroup( QString("BreakpointWidget") ); + settings.setValue( "geometry", _geometry ); + settings.endGroup(); + } + + BreakpointWidget::BreakpointWidget ( QWidget* parent ) : QDialog (parent) , _message (new QLabel()) @@ -75,8 +100,6 @@ namespace Hurricane { int BreakpointWidget::execNoModal () { - static QRect position; - if (isVisible()) return -1; // while (QApplication::hasPendingEvents()) { @@ -87,7 +110,7 @@ namespace Hurricane { _isFinished = false; show (); - if (not position.isNull()) setGeometry( position ); + if (not _geometry.isNull()) restoreGeometry( _geometry ); // Snipet code from Qt's QDialog. _eventLoop = new QEventLoop (); @@ -95,7 +118,7 @@ namespace Hurricane { _eventLoop->exec( QEventLoop::DialogExec ); _eventLoop = NULL; - position = geometry(); + _geometry = saveGeometry(); if (guard.isNull()) return QDialog::Rejected; return result(); diff --git a/hurricane/src/viewer/CellViewer.cpp b/hurricane/src/viewer/CellViewer.cpp index a2b3f40e9..8f0cc0bc7 100644 --- a/hurricane/src/viewer/CellViewer.cpp +++ b/hurricane/src/viewer/CellViewer.cpp @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -88,7 +89,8 @@ namespace Hurricane { // ------------------------------------------------------------------- // Class : "CellViewer". - QString CellViewer::_prefixWPath ( "viewer.menuBar." ); + QString CellViewer::_prefixWPath ( "viewer.menuBar." ); + vector CellViewer::_allViewers; CellViewer::CellViewer ( QWidget* parent ) : QMainWindow (parent) @@ -115,6 +117,7 @@ namespace Hurricane { , _updateState (ExternalEmit) , _pyScriptName () { + _allViewers.push_back( this ); setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred ); setObjectName( "viewer" ); menuBar()->setObjectName ( _getAbsWidgetPath("") ); @@ -183,6 +186,12 @@ namespace Hurricane { _controller->deleteLater (); //_script->deleteLater (); _goto->deleteLater (); + for ( auto iviewer = _allViewers.begin() ; iviewer != _allViewers.end() ; ++iviewer ) { + if (*iviewer == this ) { + _allViewers.erase( iviewer ); + break; + } + } } @@ -490,12 +499,6 @@ namespace Hurricane { ); connect( action, SIGNAL(triggered()), this, SLOT(close()) ); - action = addToMenu( "file.close" - , tr("&Close") - , tr("Close This Coriolis CellViewer") - , QKeySequence(tr("CTRL+W")) - ); - action = addToMenu( "file.exit" , tr("&Exit") , tr("Exit All Coriolis CellViewer") @@ -711,6 +714,31 @@ namespace Hurricane { } + void CellViewer::readQtSettings () + { + size_t viewerId = getAllViewers().size() - 1; + QSettings settings; + QString sizeKey = QString( "CellViewer/%1/geometry" ).arg( viewerId ); + if (not settings.contains(sizeKey)) return; + settings.beginGroup( QString("CellViewer/%1").arg(viewerId) ); + restoreGeometry( settings.value( "geometry" ).toByteArray() ); + getControllerWidget()->readQtSettings( viewerId ); + settings.endGroup(); + } + + + void CellViewer::saveQtSettings () + { + QSettings settings; + for ( size_t i=0 ; i<_allViewers.size() ; ++i ) { + settings.beginGroup( QString("CellViewer/%1").arg(i) ); + settings.setValue( "geometry", _allViewers[i]->saveGeometry() ); + _allViewers[i]->getControllerWidget()->saveQtSettings( i ); + settings.endGroup(); + } + } + + void CellViewer::doGoto () { if ( _goto->exec() == QDialog::Accepted ) { diff --git a/hurricane/src/viewer/ControllerWidget.cpp b/hurricane/src/viewer/ControllerWidget.cpp index 4b425f108..fae111e58 100644 --- a/hurricane/src/viewer/ControllerWidget.cpp +++ b/hurricane/src/viewer/ControllerWidget.cpp @@ -14,6 +14,7 @@ // +-----------------------------------------------------------------+ +#include #include #include #include @@ -77,6 +78,14 @@ namespace Hurricane { { } + void ControllerTab::readQtSettings ( size_t viewerId ) + { } + + + void ControllerTab::saveQtSettings ( size_t viewerId ) const + { } + + // ------------------------------------------------------------------- // Class : "Hurricane::TabGraphics". @@ -107,6 +116,14 @@ namespace Hurricane { { _graphics->rereadGraphics(); } + void TabGraphics::readQtSettings ( size_t viewerId ) + { _graphics->readQtSettings( viewerId ); } + + + void TabGraphics::saveQtSettings ( size_t viewerId ) const + { _graphics->saveQtSettings( viewerId );} + + // ------------------------------------------------------------------- // Class : "Hurricane::TabDisplayFilter". @@ -133,6 +150,14 @@ namespace Hurricane { } + void TabDisplayFilter::readQtSettings ( size_t viewerId ) + { _displayFilter->readQtSettings( viewerId ); } + + + void TabDisplayFilter::saveQtSettings ( size_t viewerId ) const + { _displayFilter->saveQtSettings( viewerId );} + + // ------------------------------------------------------------------- // Class : "Hurricane::TabPalette". @@ -170,6 +195,14 @@ namespace Hurricane { { _palette->rereadGraphics(); } + void TabPalette::readQtSettings ( size_t viewerId ) + { _palette->readQtSettings( viewerId ); } + + + void TabPalette::saveQtSettings ( size_t viewerId ) const + { _palette->saveQtSettings( viewerId );} + + // ------------------------------------------------------------------- // Class : "Hurricane::TabNetlist". @@ -279,6 +312,14 @@ namespace Hurricane { } + + void TabNetlist::readQtSettings ( size_t viewerId ) + { _netlistBrowser->readQtSettings( viewerId ); } + + + void TabNetlist::saveQtSettings ( size_t viewerId ) const + { _netlistBrowser->saveQtSettings( viewerId );} + // ------------------------------------------------------------------- // Class : "Hurricane::TabNetlist". @@ -671,6 +712,42 @@ namespace Hurricane { } + void ControllerWidget::readQtSettings ( size_t viewerId ) + { + QSettings settings; + QString sizeKey = QString( "CellViewer/%1/controller/geometry" ).arg( viewerId ); + if (not settings.contains(sizeKey)) return; + settings.beginGroup( QString("CellViewer/%1/controller").arg(viewerId) ); + restoreGeometry( settings.value( "geometry" ).toByteArray() ); + _tabGraphics ->readQtSettings( viewerId ); + _tabPalette ->readQtSettings( viewerId ); + _tabDisplayFilter->readQtSettings( viewerId ); + _tabNetlist ->readQtSettings( viewerId ); + _tabHierarchy ->readQtSettings( viewerId ); + _tabSelection ->readQtSettings( viewerId ); + _tabInspector ->readQtSettings( viewerId ); + _tabSettings ->readQtSettings( viewerId ); + settings.endGroup(); + } + + + void ControllerWidget::saveQtSettings ( size_t viewerId ) const + { + QSettings settings; + settings.beginGroup( QString("CellViewer/%1/controller").arg(viewerId) ); + settings.setValue( "geometry", saveGeometry() ); + _tabGraphics ->saveQtSettings( viewerId ); + _tabPalette ->saveQtSettings( viewerId ); + _tabDisplayFilter->saveQtSettings( viewerId ); + _tabNetlist ->saveQtSettings( viewerId ); + _tabHierarchy ->saveQtSettings( viewerId ); + _tabSelection ->saveQtSettings( viewerId ); + _tabInspector ->saveQtSettings( viewerId ); + _tabSettings ->saveQtSettings( viewerId ); + settings.endGroup(); + } + + // ------------------------------------------------------------------- // Class : "ControllerWidget::GraphicsObserver". diff --git a/hurricane/src/viewer/DisplayFilterWidget.cpp b/hurricane/src/viewer/DisplayFilterWidget.cpp index 273d0f27c..3d4b28bdf 100644 --- a/hurricane/src/viewer/DisplayFilterWidget.cpp +++ b/hurricane/src/viewer/DisplayFilterWidget.cpp @@ -14,6 +14,7 @@ // +-----------------------------------------------------------------+ +#include #include #include #include @@ -437,4 +438,56 @@ namespace Hurricane { } + void DisplayFilterWidget::readQtSettings ( size_t viewerId ) + { + QSettings settings; + QString checkKey = QString( "CellViewer/%1/controller/displayFilter/hierarchyStartLevel" ).arg( viewerId ); + if (not settings.contains(checkKey)) return; + settings.beginGroup( QString("CellViewer/%1/controller/displayFilter").arg(viewerId) ); + + _cellWidget->setStartLevel( settings.value( "hierarchyStartLevel" ).toInt() ); + _cellWidget->setStopLevel ( settings.value( "hierarchyStopLevel" ).toInt() ); + + Query::Mask queryFilter = _cellWidget->getQueryFilter(); + queryFilter.unset( Query::DoMasterCells|Query::DoTerminalCells|Query::DoComponents ); + if (settings.value( "processMasterCells" ).toBool()) queryFilter.set( Query::DoMasterCells ); + if (settings.value( "processTerminalCells" ).toBool()) queryFilter.set( Query::DoTerminalCells ); + if (settings.value( "processComponents" ).toBool()) queryFilter.set( Query::DoComponents ); + _cellWidget->setQueryFilter( queryFilter ); + + switch ( settings.value( "rubbers" ).toInt() ) { + case CellWidget::Steiner: _cellWidget->setRubberShape( CellWidget::Steiner ); break; + case CellWidget::Centric: _cellWidget->setRubberShape( CellWidget::Centric ); break; + case CellWidget::Barycentric: _cellWidget->setRubberShape( CellWidget::Barycentric ); break; + } + + switch ( settings.value( "layoutMode" ).toInt() ) { + case 0: _cellWidget->changeDbuMode( DbU::Symbolic, _cellWidget->getUnitPower() ); break; + case 1: _cellWidget->changeDbuMode( DbU::Grid , _cellWidget->getUnitPower() ); break; + case 2: _cellWidget->changeDbuMode( DbU::Physical, DbU::Micro ); break; + case 3: _cellWidget->changeDbuMode( DbU::Physical, DbU::Nano ); break; + } + settings.endGroup(); + } + + + void DisplayFilterWidget::saveQtSettings ( size_t viewerId ) const + { + QSettings settings; + settings.beginGroup( QString("CellViewer/%1/controller/displayFilter").arg(viewerId) ); + settings.setValue( "hierarchyStartLevel" , _startSpinBox ->value () ); + settings.setValue( "hierarchyStopLevel" , _stopSpinBox ->value () ); + settings.setValue( "processMasterCells" , _doMasterCells ->isChecked() ); + settings.setValue( "processTerminalCells", _doTerminalCells->isChecked() ); + settings.setValue( "processComponents" , _doComponents ->isChecked() ); + settings.setValue( "rubbers" , (int)_cellWidget->getRubberShape() ); + int layoutMode = 0; + if (_cellWidget->symbolicMode()) layoutMode = 0; + if (_cellWidget->gridMode()) layoutMode = 1; + if (_cellWidget->physicalMode() and (_cellWidget->getUnitPower() == DbU::Micro)) layoutMode = 2; + if (_cellWidget->physicalMode() and (_cellWidget->getUnitPower() == DbU::Nano )) layoutMode = 3; + settings.setValue( "layoutMode", layoutMode ); + settings.endGroup(); + } + } diff --git a/hurricane/src/viewer/GraphicsWidget.cpp b/hurricane/src/viewer/GraphicsWidget.cpp index 72ba08689..b28818318 100644 --- a/hurricane/src/viewer/GraphicsWidget.cpp +++ b/hurricane/src/viewer/GraphicsWidget.cpp @@ -14,6 +14,7 @@ // +-----------------------------------------------------------------+ +#include #include #include #include @@ -134,4 +135,27 @@ namespace Hurricane { } + void GraphicsWidget::readQtSettings ( size_t viewerId ) + { + QSettings settings; + QString checkKey = QString( "CellViewer/%1/controller/graphics/displayStyle" ).arg( viewerId ); + if (not settings.contains(checkKey)) return; + settings.beginGroup( QString("CellViewer/%1/controller/graphics").arg(viewerId) ); + int styleId = settings.value( "displayStyle" ).toInt(); + if (styleId >= 0) { + _cellWidget->setStyle( (size_t)styleId ); + _stylesGroup->button( styleId )->setChecked( true ); + } + settings.endGroup(); + } + + + void GraphicsWidget::saveQtSettings ( size_t viewerId ) const + { + QSettings settings; + settings.beginGroup( QString("CellViewer/%1/controller/graphics").arg(viewerId) ); + settings.setValue( "displayStyle" , _stylesGroup->checkedId() ); + settings.endGroup(); + } + } // Hurricane namespace. diff --git a/hurricane/src/viewer/HApplication.cpp b/hurricane/src/viewer/HApplication.cpp index f168b7fd5..244de8173 100644 --- a/hurricane/src/viewer/HApplication.cpp +++ b/hurricane/src/viewer/HApplication.cpp @@ -16,6 +16,7 @@ #include #include +#include #include "hurricane/Bug.h" #include "hurricane/Error.h" #include "hurricane/viewer/Graphics.h" @@ -38,28 +39,28 @@ namespace Hurricane { HApplication::HApplication ( int& argc, char** argv ) : QApplication ( argc, argv ) - { } + { sharedCtor(); } HApplication::HApplication ( int& argc, char** argv, bool GUIenabled ) : QApplication ( argc, argv, GUIenabled ) - { } + { sharedCtor(); } // HApplication::HApplication ( int& argc, char** argv, Type type ) // : QApplication ( argc, argv, type ) -// { } +// { sharedCtor(); } #if defined(Q_WS_X11) HApplication::HApplication ( Display* display, Qt::HANDLE visual, Qt::HANDLE colormap ) : QApplication ( display, visual, colormap ) - { } + { sharedCtor(); } HApplication::HApplication ( Display* display, int& argc, char** argv, Qt::HANDLE visual, Qt::HANDLE colormap ) : QApplication ( display, argc, argv, visual, colormap ) - { } + { sharedCtor(); } #endif @@ -91,4 +92,12 @@ namespace Hurricane { } -} // End of Hurricane namespace. + void HApplication::sharedCtor () + { + QCoreApplication::setOrganizationName ( "SU-LIP6" ); + QCoreApplication::setOrganizationDomain( "lip6.fr" ); + QCoreApplication::setApplicationName ( "Coriolis" ); + } + + +} // Hurricane namespace. diff --git a/hurricane/src/viewer/NetlistWidget.cpp b/hurricane/src/viewer/NetlistWidget.cpp index 8902993a7..75aaa0382 100644 --- a/hurricane/src/viewer/NetlistWidget.cpp +++ b/hurricane/src/viewer/NetlistWidget.cpp @@ -14,6 +14,7 @@ // +-----------------------------------------------------------------+ +#include #include #include #include @@ -185,4 +186,23 @@ namespace Hurricane { } + void NetlistWidget::readQtSettings ( size_t viewerId ) + { + QSettings settings; + QString checkKey = QString( "CellViewer/%1/controller/netlist/filterPattern" ).arg( viewerId ); + if (not settings.contains(checkKey)) return; + settings.beginGroup( QString("CellViewer/%1/controller/netlist").arg(viewerId) ); + _filterPatternLineEdit->setText( settings.value( "filterPattern" ).toString() ); + settings.endGroup(); + } + + + void NetlistWidget::saveQtSettings ( size_t viewerId ) const + { + QSettings settings; + settings.beginGroup( QString("CellViewer/%1/controller/netlist").arg(viewerId) ); + settings.setValue( "filterPattern", _filterPatternLineEdit->text() ); + settings.endGroup(); + } + } // End of Hurricane namespace. diff --git a/hurricane/src/viewer/PaletteWidget.cpp b/hurricane/src/viewer/PaletteWidget.cpp index a17b7d7ff..68bc2f616 100644 --- a/hurricane/src/viewer/PaletteWidget.cpp +++ b/hurricane/src/viewer/PaletteWidget.cpp @@ -15,6 +15,7 @@ #include +#include #include #include #include @@ -535,4 +536,31 @@ namespace Hurricane { } + void PaletteWidget::readQtSettings ( size_t viewerId ) + { + QSettings settings; + QString fallbackKey = QString( "CellViewer/%1/controller/palette/fallback/visible" ).arg( viewerId ); + if (not settings.contains(fallbackKey)) return; + settings.beginGroup( QString("CellViewer/%1/controller/palette").arg(viewerId) ); + for ( auto item : _layerItems ) { + QString itemKey = QString("%1/visible").arg( getString(item.first).c_str() ); + if (not settings.contains(itemKey)) continue; + item.second->setItemVisible ( settings.value( itemKey ).toBool() ); + item.second->setItemSelectable( settings.value( itemKey.replace("visible","selectable") ).toBool() ); + } + settings.endGroup(); + } + + + void PaletteWidget::saveQtSettings ( size_t viewerId ) const + { + QSettings settings; + settings.beginGroup( QString("CellViewer/%1/controller/palette").arg(viewerId) ); + for ( auto item : _layerItems ) { + settings.setValue( QString( "%1/visible" ).arg(getString(item.first).c_str()), item.second->isItemVisible () ); + settings.setValue( QString( "%1/selectable" ).arg(getString(item.first).c_str()), item.second->isItemSelectable() ); + } + settings.endGroup(); + } + } // Hurricane namespace. diff --git a/hurricane/src/viewer/hurricane/viewer/BreakpointWidget.h b/hurricane/src/viewer/hurricane/viewer/BreakpointWidget.h index 9d7561f5c..eee1525b1 100644 --- a/hurricane/src/viewer/hurricane/viewer/BreakpointWidget.h +++ b/hurricane/src/viewer/hurricane/viewer/BreakpointWidget.h @@ -14,9 +14,7 @@ // +-----------------------------------------------------------------+ -#ifndef HURRICANE_BREAKPOINT_WIDGET_H -#define HURRICANE_BREAKPOINT_WIDGET_H - +#pragma once #include #include class QLabel; @@ -28,27 +26,27 @@ namespace Hurricane { class BreakpointWidget : public QDialog { Q_OBJECT; - public: - BreakpointWidget ( QWidget* parent=NULL); - void setMessage ( const QString& ); - int getStopLevel () const; - void setStopLevel ( int ); - int execNoModal (); + static void readQtSettings (); + static void saveQtSettings (); + public: + BreakpointWidget ( QWidget* parent=NULL); + void setMessage ( const QString& ); + int getStopLevel () const; + void setStopLevel ( int ); + int execNoModal (); public slots: - void updateStopLevel ( int ); + void updateStopLevel ( int ); protected slots: - void raiseFinished ( int ); - + void raiseFinished ( int ); private: - QLabel* _message; - QSpinBox* _stopLevel; - bool _isFinished; - QEventLoop* _eventLoop; + static QByteArray _geometry; + QLabel* _message; + QSpinBox* _stopLevel; + bool _isFinished; + QEventLoop* _eventLoop; }; } // Hurricane namespace. - -#endif // HURRICANE_BREAKPOINT_WIDGET_H diff --git a/hurricane/src/viewer/hurricane/viewer/CellViewer.h b/hurricane/src/viewer/hurricane/viewer/CellViewer.h index 55946f906..2813b9c78 100644 --- a/hurricane/src/viewer/hurricane/viewer/CellViewer.h +++ b/hurricane/src/viewer/hurricane/viewer/CellViewer.h @@ -82,11 +82,16 @@ namespace Hurricane { typedef std::map< const QString, boost::any > ActionLut; typedef bool (QWidget::* SlotMethod)(); public: + static inline const std::vector& + getAllViewers (); static void notify ( CellViewer*, unsigned int flags ); public: CellViewer ( QWidget* parent=NULL ); virtual ~CellViewer (); inline bool isToolInterrupted () const; + inline size_t getSettingsId () const; + void readQtSettings (); + void saveQtSettings (); void refreshTitle (); QMenu* createDebugMenu (); bool hasMenu ( const QString& path ) const; @@ -175,6 +180,7 @@ namespace Hurricane { void _runScript ( QString scriptPath ); protected: + static std::vector _allViewers; static QString _prefixWPath; Observer _cellObserver; QString _applicationName; @@ -205,6 +211,8 @@ namespace Hurricane { // Inline Functions. + inline const std::vector& + CellViewer::getAllViewers () { return _allViewers; } inline bool CellViewer::isToolInterrupted () const { return _toolInterrupt; } inline Observer* CellViewer::getCellObserver () { return &_cellObserver; } inline CellWidget* CellViewer::getCellWidget () { return _cellWidget; } @@ -226,6 +234,14 @@ namespace Hurricane { inline void CellViewer::setDbuMode ( int mode ) { _cellWidget->setDbuMode(mode); } + inline size_t CellViewer::getSettingsId () const + { + for ( size_t i=0; i<_allViewers.size() ; ++i ) { + if (_allViewers[i] == this) return i; + } + return 0; + } + } // Hurricane namespace. diff --git a/hurricane/src/viewer/hurricane/viewer/ControllerWidget.h b/hurricane/src/viewer/hurricane/viewer/ControllerWidget.h index a74f27135..82ef6182d 100644 --- a/hurricane/src/viewer/hurricane/viewer/ControllerWidget.h +++ b/hurricane/src/viewer/hurricane/viewer/ControllerWidget.h @@ -14,10 +14,7 @@ // +-----------------------------------------------------------------+ -#ifndef HURRICANE_CONTROLLER_WIDGET_H -#define HURRICANE_CONTROLLER_WIDGET_H - - +#pragma once #include class QCheckBox; class QComboBox; @@ -57,6 +54,8 @@ namespace Hurricane { public: ControllerTab ( QWidget* parent=NULL ); inline CellWidget* getCellWidget (); + virtual void saveQtSettings ( size_t viewerId ) const; + virtual void readQtSettings ( size_t viewerId ); public slots: virtual void setCellWidget ( CellWidget* ); virtual void setCell ( Cell* ); @@ -86,6 +85,8 @@ namespace Hurricane { public slots: void setCellWidget ( CellWidget* ); virtual void graphicsUpdated (); + virtual void saveQtSettings ( size_t viewerId ) const; + virtual void readQtSettings ( size_t viewerId ); protected: GraphicsWidget* _graphics; @@ -105,6 +106,8 @@ namespace Hurricane { public: TabDisplayFilter ( QWidget* parent=NULL ); inline DisplayFilterWidget* getDisplayFilter (); + virtual void saveQtSettings ( size_t viewerId ) const; + virtual void readQtSettings ( size_t viewerId ); public slots: virtual void setCellWidget ( CellWidget* ); @@ -126,6 +129,8 @@ namespace Hurricane { public: TabPalette ( QWidget* parent=NULL ); inline PaletteWidget* getPalette (); + virtual void saveQtSettings ( size_t viewerId ) const; + virtual void readQtSettings ( size_t viewerId ); public slots: virtual void setCellWidget ( CellWidget* ); virtual void graphicsUpdated (); @@ -152,6 +157,8 @@ namespace Hurricane { inline QCheckBox* getSyncSelection (); virtual void cellPreModificate (); virtual void cellPostModificate (); + virtual void saveQtSettings ( size_t viewerId ) const; + virtual void readQtSettings ( size_t viewerId ); public slots: virtual void setCell ( Cell* ); virtual void setCellWidget ( CellWidget* ); @@ -313,6 +320,8 @@ namespace Hurricane { void setCellWidget ( CellWidget* ); //inline int addSetting ( QWidget* page, const QString& label ); void insertTabAfter ( const QString& ref, QWidget*, const QString& label ); + void saveQtSettings ( size_t viewerId ) const; + void readQtSettings ( size_t viewerId ); public slots: void graphicsUpdated (); void cellPreModificate (); @@ -347,7 +356,4 @@ namespace Hurricane { //inline int ControllerWidget::addSetting ( QWidget* page, const QString& label ) { return _tabSettings->addSetting(page,label); } -} // End of Hurricane namespace. - - -#endif // __HURRICANE_CONTROLLER_WIDGET__ +} // Hurricane namespace. diff --git a/hurricane/src/viewer/hurricane/viewer/DisplayFilterWidget.h b/hurricane/src/viewer/hurricane/viewer/DisplayFilterWidget.h index b3f5ef26a..6d043aca5 100644 --- a/hurricane/src/viewer/hurricane/viewer/DisplayFilterWidget.h +++ b/hurricane/src/viewer/hurricane/viewer/DisplayFilterWidget.h @@ -14,11 +14,8 @@ // +-----------------------------------------------------------------+ -#ifndef HURRICANE_DISPLAY_FILTER_WIDGET_H -#define HURRICANE_DISPLAY_FILTER_WIDGET_H - - -#include +#pragma once +#include class QSpinBox; class QCheckBox; @@ -36,6 +33,8 @@ namespace Hurricane { public: DisplayFilterWidget ( QWidget* parent=NULL ); void setCellWidget ( CellWidget* ); + void saveQtSettings ( size_t viewerId ) const; + void readQtSettings ( size_t viewerId ); signals: void queryFilterChanged (); void dbuModeChanged ( unsigned int mode, DbU::UnitPower ); @@ -76,5 +75,3 @@ namespace Hurricane { } // Hurricane namespace. - -#endif // HURRICANE_DISPLAY_FILTER_WIDGET_H diff --git a/hurricane/src/viewer/hurricane/viewer/GraphicsWidget.h b/hurricane/src/viewer/hurricane/viewer/GraphicsWidget.h index 76667d79f..57a316868 100644 --- a/hurricane/src/viewer/hurricane/viewer/GraphicsWidget.h +++ b/hurricane/src/viewer/hurricane/viewer/GraphicsWidget.h @@ -14,11 +14,8 @@ // +-----------------------------------------------------------------+ -#ifndef HURRICANE_GRAPHICS_WIDGET_H -#define HURRICANE_GRAPHICS_WIDGET_H - - -#include +#pragma once +#include class QGridLayout; class QButtonGroup; @@ -37,6 +34,8 @@ namespace Hurricane { void readGraphics (); void resetGraphics (); void rereadGraphics (); + void saveQtSettings ( size_t viewerId ) const; + void readQtSettings ( size_t viewerId ); public slots: void changeStyle (); void setStyle ( int id ); @@ -50,5 +49,3 @@ namespace Hurricane { } // Hurricane namespace. - -#endif diff --git a/hurricane/src/viewer/hurricane/viewer/HApplication.h b/hurricane/src/viewer/hurricane/viewer/HApplication.h index 5df116bbf..c69061bdc 100644 --- a/hurricane/src/viewer/hurricane/viewer/HApplication.h +++ b/hurricane/src/viewer/hurricane/viewer/HApplication.h @@ -1,25 +1,21 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC 2008-2018, All Rights Reserved +// Copyright (c) Sorbonne Université 2008-2018, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | // | U n i c o r n - M a i n G U I | // | | // | Author : Jean-Paul CHAPUT | -// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Header : "./HApplication.h" | // +-----------------------------------------------------------------+ - - -#ifndef HURRICANE_HAPPLICATION_H -#define HURRICANE_HAPPLICATION_H - -#include +#pragma once +#include namespace Hurricane { @@ -27,7 +23,6 @@ namespace Hurricane { class HApplication : public QApplication { Q_OBJECT; - public: HApplication ( int& argc, char** argv ); HApplication ( int& argc, char** argv, bool GUIenabled ); @@ -37,11 +32,9 @@ namespace Hurricane { HApplication ( Display*, int& argc, char** argv, Qt::HANDLE visual=0, Qt::HANDLE colormap=0 ); #endif virtual bool notify ( QObject*, QEvent* ); + void sharedCtor (); }; } // End of Hurricane namespace. - -#endif // __HURRICANE_HAPPLICATION__ - diff --git a/hurricane/src/viewer/hurricane/viewer/NetlistWidget.h b/hurricane/src/viewer/hurricane/viewer/NetlistWidget.h index 68dedac9b..e1b328940 100644 --- a/hurricane/src/viewer/hurricane/viewer/NetlistWidget.h +++ b/hurricane/src/viewer/hurricane/viewer/NetlistWidget.h @@ -138,6 +138,8 @@ namespace Hurricane { void setCell ( Cell* ); void goTo ( int ); void updateSelecteds (); + void saveQtSettings ( size_t viewerId ) const; + void readQtSettings ( size_t viewerId ); signals: void netSelected ( Occurrence ); void netUnselected ( Occurrence ); diff --git a/hurricane/src/viewer/hurricane/viewer/PaletteWidget.h b/hurricane/src/viewer/hurricane/viewer/PaletteWidget.h index 624501fd6..e188400f0 100644 --- a/hurricane/src/viewer/hurricane/viewer/PaletteWidget.h +++ b/hurricane/src/viewer/hurricane/viewer/PaletteWidget.h @@ -64,6 +64,8 @@ namespace Hurricane { void readGraphics (); void resetGraphics (); void rereadGraphics (); + void saveQtSettings ( size_t viewerId ) const; + void readQtSettings ( size_t viewerId ); signals: void paletteChanged (); public slots: diff --git a/unicorn/src/UnicornGui.cpp b/unicorn/src/UnicornGui.cpp index 99d6dd067..eb604d281 100644 --- a/unicorn/src/UnicornGui.cpp +++ b/unicorn/src/UnicornGui.cpp @@ -23,6 +23,7 @@ #include "hurricane/isobar/Script.h" #include "hurricane/viewer/CellViewer.h" #include "hurricane/viewer/PyCellViewer.h" +#include "hurricane/viewer/BreakpointWidget.h" #include "crlcore/Utilities.h" #include "crlcore/Catalog.h" #include "crlcore/AllianceFramework.h" @@ -54,6 +55,7 @@ namespace Unicorn { using Hurricane::jsonCellParse; using Hurricane::DataBase; using Hurricane::Library; + using Hurricane::BreakpointWidget; using CRL::System; using CRL::Catalog; using CRL::AllianceFramework; @@ -171,15 +173,24 @@ namespace Unicorn { connect ( exportAction, SIGNAL(triggered()), this, SLOT(exportCell()) ); } - QAction* action = addToMenu( "tools.libraryManager" - , tr("Library Manager") - , tr("Browse through Views, Cells & Libraries") - , QKeySequence(tr("CTRL+M")) - , QIcon() - , "tools.script" + QAction* action = addToMenu( "file.saveSettings" + , tr("Save settings") + , tr("Save windows size & positions") + , QKeySequence() ); + connect( action, SIGNAL(triggered()), this, SLOT(saveQtSettings()) ); + + action = addToMenu( "tools.libraryManager" + , tr("Library Manager") + , tr("Browse through Views, Cells & Libraries") + , QKeySequence(tr("CTRL+M")) + , QIcon() + , "tools.script" + ); connect( action, SIGNAL(triggered()), _libraryManager, SLOT(toggleShow()) ); connect( this , SIGNAL(cellLoadedFromDisk(Cell*)), _libraryManager, SLOT(updateLibrary(Cell*)) ); + + readQtSettings(); } @@ -191,6 +202,22 @@ namespace Unicorn { } + void UnicornGui::readQtSettings () + { + CellViewer::readQtSettings(); + BreakpointWidget::readQtSettings(); + _libraryManager->readQtSettings(); + } + + + void UnicornGui::saveQtSettings () + { + CellViewer::saveQtSettings(); + BreakpointWidget::saveQtSettings(); + _libraryManager->saveQtSettings(); + } + + Cell* UnicornGui::getCellFromDb ( const char* name ) { Cell* cell = DataBase::getDB()->getCell( name ); diff --git a/unicorn/src/unicorn/UnicornGui.h b/unicorn/src/unicorn/UnicornGui.h index c610f46ad..bcef8ac08 100644 --- a/unicorn/src/unicorn/UnicornGui.h +++ b/unicorn/src/unicorn/UnicornGui.h @@ -52,6 +52,7 @@ namespace Unicorn { public: static UnicornGui* create ( QWidget* parent=NULL ); void destroy (); + void readQtSettings (); static inline Banner& getBanner (); virtual Cell* getCellFromDb ( const char* name ); inline ImportCell* getImportCell (); @@ -59,6 +60,7 @@ namespace Unicorn { virtual UnicornGui* vcreate () const; virtual std::string _getString () const; public slots: + void saveQtSettings (); void openCell (); void saveCell (); void importCell (); From 5927fe4747df2e440d2c44e5a6bb69b0f63d77f2 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Mon, 1 Jan 2024 15:28:12 +0100 Subject: [PATCH 30/51] In Rectilinear, support for horizontal slicing. --- hurricane/src/hurricane/Rectilinear.cpp | 261 ++++++++++++++++-- .../src/hurricane/hurricane/Rectilinear.h | 5 +- hurricane/src/isobar/PyHurricane.cpp | 1 + hurricane/src/isobar/PyRectilinear.cpp | 16 +- .../isobar/hurricane/isobar/PyRectilinear.h | 11 +- unittests/python/test_rectilinear.py | 9 +- 6 files changed, 271 insertions(+), 32 deletions(-) diff --git a/hurricane/src/hurricane/Rectilinear.cpp b/hurricane/src/hurricane/Rectilinear.cpp index a50eab4c1..5bc61dba4 100644 --- a/hurricane/src/hurricane/Rectilinear.cpp +++ b/hurricane/src/hurricane/Rectilinear.cpp @@ -196,13 +196,13 @@ namespace { // ------------------------------------------------------------------- -// Class : "SweepLine". +// Class : "VSweepLine". - class SweepLine { + class VSweepLine { public: - SweepLine ( const Rectilinear*, vector& ); - ~SweepLine (); + VSweepLine ( const Rectilinear*, vector& ); + ~VSweepLine (); void addVEdge ( DbU::Unit ymin, DbU::Unit ymax, DbU::Unit x ); void loadVEdges (); void process ( Interval ); @@ -219,7 +219,7 @@ namespace { }; - SweepLine::SweepLine ( const Rectilinear* r, vector& boxes ) + VSweepLine::VSweepLine ( const Rectilinear* r, vector& boxes ) : _rectilinear(r) , _boxes (boxes) , _vedges () @@ -227,21 +227,21 @@ namespace { , _prevX (0) , _currX (0) { - cdebug_log(17,1) << "SweepLine::SweepLine()" << endl; + cdebug_log(17,1) << "VSweepLine::VSweepLine()" << endl; } - SweepLine::~SweepLine () + VSweepLine::~VSweepLine () { cdebug_tabw(17,-1); } - void SweepLine::addVEdge ( DbU::Unit ymin, DbU::Unit ymax, DbU::Unit x ) + void VSweepLine::addVEdge ( DbU::Unit ymin, DbU::Unit ymax, DbU::Unit x ) { if (ymin > ymax) std::swap( ymin, ymax ); - cdebug_log(17,1) << "SweepLine::addVEdge() @"<< DbU::getValueString(x) + cdebug_log(17,1) << "VSweepLine::addVEdge() @"<< DbU::getValueString(x) << " [" << DbU::getValueString(ymin) << " " << DbU::getValueString(ymax) << "]" << endl; @@ -280,7 +280,7 @@ namespace { } - void SweepLine::loadVEdges () + void VSweepLine::loadVEdges () { const vector& points = _rectilinear->getPoints(); for ( size_t i=0 ; i >& intervals ) + void VSweepLine::process ( const pair< DbU::Unit, list >& intervals ) { - cdebug_log(17,1) << "SweepLine::process() @"<< DbU::getValueString(intervals.first) + cdebug_log(17,1) << "VSweepLine::process() @"<< DbU::getValueString(intervals.first) << " size=" << intervals.second.size() << endl; _currX = intervals.first; for ( const Interval& v : intervals.second ) process( v ); @@ -404,18 +404,238 @@ namespace { } - void SweepLine::asRectangles () + void VSweepLine::asRectangles () { loadVEdges(); for ( auto intervals : _vedges ) { process( intervals ); } - cdebug_log(17,0) << "SweepLine::asRectangles() size=" << _boxes.size() << endl; + cdebug_log(17,0) << "VSweepLine::asRectangles() size=" << _boxes.size() << endl; for ( const Box& b : _boxes ) cdebug_log(17,0) << "| " << b << endl; } +// ------------------------------------------------------------------- +// Class : "HSweepLine". + + + class HSweepLine { + public: + HSweepLine ( const Rectilinear*, vector& ); + ~HSweepLine (); + void addHEdge ( DbU::Unit xmin, DbU::Unit xmax, DbU::Unit y ); + void loadHEdges (); + void process ( Interval ); + void process ( const pair< DbU::Unit, list >& ); + void toBox ( SweepInterval& ); + void asRectangles (); + private: + const Rectilinear* _rectilinear; + vector& _boxes; + list< pair< DbU::Unit, list > > _vedges; + list< SweepInterval > _sweepLine; + DbU::Unit _prevY; + DbU::Unit _currY; + }; + + + HSweepLine::HSweepLine ( const Rectilinear* r, vector& boxes ) + : _rectilinear(r) + , _boxes (boxes) + , _vedges () + , _sweepLine () + , _prevY (0) + , _currY (0) + { + cdebug_log(17,1) << "HSweepLine::HSweepLine()" << endl; + } + + + HSweepLine::~HSweepLine () + { + cdebug_tabw(17,-1); + } + + + void HSweepLine::addHEdge ( DbU::Unit xmin, DbU::Unit xmax, DbU::Unit y ) + { + if (xmin > xmax) std::swap( xmin, xmax ); + + cdebug_log(17,1) << "HSweepLine::addHEdge() @"<< DbU::getValueString(y) + << " [" << DbU::getValueString(xmin) + << " " << DbU::getValueString(xmax) << "]" << endl; + + bool inserted = false; + for ( auto iy = _vedges.begin() ; iy != _vedges.end() ; ++iy ) { + cdebug_log(17,0) << "| Looking @" << DbU::getValueString(iy->first) + << " size=" << iy->second.size() << endl; + + if (iy->first > y) { + _vedges.insert( iy, make_pair( y, list() )); + cdebug_log(17,0) << "+ add new @" << DbU::getValueString(y) << endl; + --iy; + } + if (iy->first == y) { + for ( auto iintv = iy->second.begin() ; iintv != iy->second.end() ; ++iintv ) { + if (iintv->getVMin() >= xmax) { + iy->second.insert( iintv, Interval(xmin,xmax) ); + inserted = true; + break; + } + } + if (not inserted) { + iy->second.push_back( Interval(xmin,xmax) ); + inserted = true; + } + break; + } + } + if (not inserted) { + cdebug_log(17,0) << "+ add new (back) @" << DbU::getValueString(y) << endl; + _vedges.push_back( make_pair( y, list() )); + _vedges.back().second.push_back( Interval(xmin,xmax) ); + } + + cdebug_tabw(17,-1); + } + + + void HSweepLine::loadHEdges () + { + const vector& points = _rectilinear->getPoints(); + for ( size_t i=0 ; igetVMin()) { + _sweepLine.insert( iintv, SweepInterval(v,_currY) ); + done = true; + break; + } + // Extractor p. 9 (f). + if ( (v.getVMin() == iintv->getVMin()) + and (v.getVMax() == iintv->getVMax()) ) { + toBox( *iintv ); + _sweepLine.erase( iintv ); + done = true; + break; + } + // Extractor p. 9 (b). + if (v.getVMax() == iintv->getVMin()) { + toBox( *iintv ); + iintv->merge( v.getVMin() ); + done = true; + break; + } + // Extractor p. 9 (g). + if (v.getVMax() == iintv->getVMax()) { + toBox( *iintv ); + cdebug_log(17,0) << "case (g): carve" << endl; + iintv->inflate( 0, v.getVMin() - iintv->getVMax() ); + cdebug_log(17,0) << "| " << (*iintv) << endl; + done = true; + break; + } + // Extractor p. 9 (h). + if (v.getVMin() == iintv->getVMin()) { + toBox( *iintv ); + iintv->inflate(iintv->getVMin() - v.getVMax(), 0 ); + done = true; + break; + } + // Extractor p. 9 (c). + if ( (v.getVMin() > iintv->getVMin()) + and (v.getVMax() < iintv->getVMax()) ) { + toBox( *iintv ); + cdebug_log(17,0) << "case (c): carve" << endl; + DbU::Unit wholeVMin = iintv->getVMin(); + iintv->inflate( iintv->getVMin() - v.getVMax(), 0 ); + cdebug_log(17,0) << "| " << (*iintv) << endl; + _sweepLine.insert( iintv, SweepInterval( wholeVMin, v.getVMin(), _currY ) ); + cdebug_log(17,0) << "| " << (*(--iintv)) << endl; + done = true; + break; + } + // Extractor p. 9 (d,e). + if (v.getVMin() == iintv->getVMax()) { + auto iintvNext = iintv; + ++iintvNext; + // Extractor p. 9 (d). + if (iintvNext == _sweepLine.end()) { + toBox( *iintv ); + iintv->merge( v.getVMax() ); + } else { + // Extractor p. 9 (d). + if (v.getVMax() < iintvNext->getVMin()) { + toBox( *iintv ); + iintv->merge( v.getVMax() ); + } else { + // Extractor p. 9 (e). + toBox( *iintv ); + toBox( *iintvNext ); + iintv->merge( iintvNext->getVMax() ); + _sweepLine.erase( iintvNext ); + } + } + done = true; + break; + } + } + if (not done) { + _sweepLine.push_back( SweepInterval(v,_currY) ); + } + + cdebug_tabw(17,-1); + } + + + void HSweepLine::process ( const pair< DbU::Unit, list >& intervals ) + { + cdebug_log(17,1) << "HSweepLine::process() @"<< DbU::getValueString(intervals.first) + << " size=" << intervals.second.size() << endl; + _currY = intervals.first; + for ( const Interval& v : intervals.second ) process( v ); + cdebug_tabw(17,-1); + } + + + void HSweepLine::asRectangles () + { + loadHEdges(); + for ( auto intervals : _vedges ) { + process( intervals ); + } + cdebug_log(17,0) << "HSweepLine::asRectangles() size=" << _boxes.size() << endl; + for ( const Box& b : _boxes ) + cdebug_log(17,0) << "| " << b << endl; + } + + // ------------------------------------------------------------------- // Class : "SweepLineBig". @@ -904,11 +1124,14 @@ namespace Hurricane { } - bool Rectilinear::getAsRectangles ( std::vector& rectangles ) const + bool Rectilinear::getAsRectangles ( std::vector& rectangles, uint32_t flags ) const { rectangles.clear(); if (not isRectilinear()) return false; - SweepLine( this, rectangles ).asRectangles(); + if (flags & VSliced) + VSweepLine( this, rectangles ).asRectangles(); + else + HSweepLine( this, rectangles ).asRectangles(); return true; } diff --git a/hurricane/src/hurricane/hurricane/Rectilinear.h b/hurricane/src/hurricane/hurricane/Rectilinear.h index 74d41848d..63669cade 100644 --- a/hurricane/src/hurricane/hurricane/Rectilinear.h +++ b/hurricane/src/hurricane/hurricane/Rectilinear.h @@ -44,7 +44,8 @@ namespace Hurricane { public: typedef Component Super; static const uint32_t IsRectilinear = (1<<0); - + static const uint32_t VSliced = (1<<1); + static const uint32_t HSliced = (1<<2); public: static Rectilinear* create ( Net*, const Layer*, const vector& ); // Accessors. @@ -58,7 +59,7 @@ namespace Hurricane { virtual Point getPoint ( size_t i ) const; virtual const Layer* getLayer () const; inline Points getContour () const; - bool getAsRectangles ( std::vector& ) const; + bool getAsRectangles ( std::vector&, uint32_t flags=VSliced ) const; bool getAsBiggestRectangles ( std::vector& , DbU::Unit xThreshold=0 diff --git a/hurricane/src/isobar/PyHurricane.cpp b/hurricane/src/isobar/PyHurricane.cpp index 3abe04cee..e97aeca5a 100644 --- a/hurricane/src/isobar/PyHurricane.cpp +++ b/hurricane/src/isobar/PyHurricane.cpp @@ -901,6 +901,7 @@ extern "C" { PyBasicLayer_postModuleInit(); PyPin_postModuleInit(); PyRoutingPad_postModuleInit(); + PyRectilinear_postModuleInit(); PyNet_postModuleInit(); PyNetRoutingState_postModuleInit(); PyCell_postModuleInit(); diff --git a/hurricane/src/isobar/PyRectilinear.cpp b/hurricane/src/isobar/PyRectilinear.cpp index 04f7e2d37..56f66616a 100644 --- a/hurricane/src/isobar/PyRectilinear.cpp +++ b/hurricane/src/isobar/PyRectilinear.cpp @@ -193,8 +193,9 @@ extern "C" { HTRY METHOD_HEAD( "Rectilinear.getAsRectangles()" ) - PyObject* pyList = NULL; - if (not PyArg_ParseTuple( args, "O:Rectilinear.getAsRectangles", &pyList )) { + PyObject* pyList = NULL; + unsigned int pyFlags = Rectilinear::VSliced; + if (not PyArg_ParseTuple( args, "O|I:Rectilinear.getAsRectangles", &pyList, &pyFlags )) { PyErr_SetString( ConstructorError, "Rectilinear.getAsRectangles(): Must have exactly one parameter." ); return NULL; } @@ -205,7 +206,7 @@ extern "C" { PyList_SetSlice( pyList, 0, PyList_Size(pyList), NULL ); vector boxes; - rectilinear->getAsRectangles( boxes ); + rectilinear->getAsRectangles( boxes, pyFlags ); for ( size_t i=0 ; iob_type == &PyTypeRectilinear ) @@ -52,5 +51,3 @@ namespace Isobar { } // extern "C". } // Isobar namespace. - -#endif // PY_RECTILINEAR_H diff --git a/unittests/python/test_rectilinear.py b/unittests/python/test_rectilinear.py index e1103e1c9..184b58e05 100644 --- a/unittests/python/test_rectilinear.py +++ b/unittests/python/test_rectilinear.py @@ -17,7 +17,7 @@ def testRectilinear ( editor ): with UpdateSession(): cell = AllianceFramework.get().createCell( 'Rectilinear' ) cell.setTerminalNetlist( True ) - cell.setAbutmentBox( Box( l(-5.0), l(-5.0), l(524.0), l(200.0) ) ) + cell.setAbutmentBox( Box( l(-5.0), l(-5.0), l(704.0), l(200.0) ) ) #cell.setAbutmentBox( Box( l(-5.0), l(-5.0), l(21.0), l(35.0) ) ) if editor: editor.setCell( cell ) @@ -28,6 +28,7 @@ def testRectilinear ( editor ): metal2 = technology.getLayer( "METAL2" ) metal3 = technology.getLayer( "METAL3" ) metal4 = technology.getLayer( "METAL4" ) + metal5 = technology.getLayer( "METAL5" ) poly = technology.getLayer( "POLY" ) ptrans = technology.getLayer( "PTRANS" ) ntrans = technology.getLayer( "NTRANS" ) @@ -161,6 +162,12 @@ def testRectilinear ( editor ): for box in boxes: box.translate( l(360.0), l(0.0) ) Pad.create( net, metal4, box ) + boxes = [] + r.getAsRectangles( boxes, Rectilinear.HSliced ) + #print( 'boxes={}'.format( boxes )) + for box in boxes: + box.translate( l(540.0), l(0.0) ) + Pad.create( net, metal5, box ) Gds.save( cell ) From c607d43e3abf219f1bd08189ac04ecf3098befd8 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Mon, 1 Jan 2024 20:31:37 +0100 Subject: [PATCH 31/51] Support Rectilinear in the two setupPowerRails() (Etesian & Katana). --- etesian/src/FlattenPower.cpp | 127 +++++++++++----------- hurricane/src/hurricane/hurricane/Query.h | 3 + katana/src/PowerRails.cpp | 70 ++++++------ 3 files changed, 101 insertions(+), 99 deletions(-) diff --git a/etesian/src/FlattenPower.cpp b/etesian/src/FlattenPower.cpp index e45b1d14f..44f803c16 100644 --- a/etesian/src/FlattenPower.cpp +++ b/etesian/src/FlattenPower.cpp @@ -856,72 +856,75 @@ namespace { { cdebug_log(159,0) << "addToPowerRail: go=" << go << endl; const Component* component = dynamic_cast( go ); - if (component) { - if ( _framework->isPad(getMasterCell()) - and ( (_routingGauge->getLayerDepth(component->getLayer()) < 2) - or (component->getLayer()->getBasicLayers().getFirst()->getMaterial() - != BasicLayer::Material::blockage) ) ) - return; - - Net* rootNet = _blockageNet; - if (not _isBlockagePlane) { - rootNet = _powerRailsPlanes.getRootNet(component->getNet(),getPath()); - if (not NetExternalComponents::isExternal(component)) return; - } - if (not rootNet) { - cdebug_log(159,0) << " rootNet is NULL, not taken into account." << endl; - return; - } - cdebug_log(159,0) << " rootNet " << rootNet << " " - << go->getCell() << " (" << go->getCell()->isTerminal() << ")" << endl; + if (not component) return; + + if ( _framework->isPad(getMasterCell()) + and ( (_routingGauge->getLayerDepth(component->getLayer()) < 2) + or (component->getLayer()->getBasicLayers().getFirst()->getMaterial() + != BasicLayer::Material::blockage) ) ) + return; - const Segment* segment = dynamic_cast( component ); - if (segment) { - _goMatchCount++; - cdebug_log(159,0) << " Merging PowerRail element: " << segment << endl; + Net* rootNet = _blockageNet; + if (not _isBlockagePlane) { + rootNet = _powerRailsPlanes.getRootNet(component->getNet(),getPath()); + if (not NetExternalComponents::isExternal(component)) return; + } + if (not rootNet) { + cdebug_log(159,0) << " rootNet is NULL, not taken into account." << endl; + return; + } + cdebug_log(159,0) << " rootNet " << rootNet << " " + << go->getCell() << " (" << go->getCell()->isTerminal() << ")" << endl; - Box bb = segment->getBoundingBox( basicLayer ); - transformation.applyOn( bb ); - _powerRailsPlanes.merge( bb, rootNet ); - } else { - const Contact* contact = dynamic_cast( component ); - if (contact) { - _goMatchCount++; + const Segment* segment = dynamic_cast( component ); + if (segment) { + _goMatchCount++; + cdebug_log(159,0) << " Merging PowerRail element: " << segment << endl; - Box bb = contact->getBoundingBox( basicLayer ); - transformation.applyOn( bb ); + Box bb = segment->getBoundingBox( basicLayer ); + transformation.applyOn( bb ); + _powerRailsPlanes.merge( bb, rootNet ); + return; + } - cdebug_log(159,0) << " Merging PowerRail element: " << contact << " bb:" << bb - << " " << basicLayer << endl; - - _powerRailsPlanes.merge( bb, rootNet ); - } else { - const Pad* pad = dynamic_cast( component ); - if (pad) { - _goMatchCount++; - - Box bb = pad->getBoundingBox( basicLayer ); - transformation.applyOn( bb ); - - cdebug_log(159,0) << " Merging PowerRail element: " << pad << " bb:" << bb - << " " << basicLayer << endl; - - _powerRailsPlanes.merge( bb, rootNet ); - } else { - const Rectilinear* rectilinear = dynamic_cast( component ); - if (rectilinear and (rectilinear->getPoints().size() == 5)) { - _goMatchCount++; - - Box bb = rectilinear->getBoundingBox( basicLayer ); - transformation.applyOn( bb ); - - cdebug_log(159,0) << " Merging PowerRail element: " << rectilinear << " bb:" << bb - << " " << basicLayer << endl; - - _powerRailsPlanes.merge( bb, rootNet ); - } - } - } + const Contact* contact = dynamic_cast( component ); + if (contact) { + _goMatchCount++; + + Box bb = contact->getBoundingBox( basicLayer ); + transformation.applyOn( bb ); + + cdebug_log(159,0) << " Merging PowerRail element: " << contact << " bb:" << bb + << " " << basicLayer << endl; + + _powerRailsPlanes.merge( bb, rootNet ); + return; + } + + const Pad* pad = dynamic_cast( component ); + if (pad) { + _goMatchCount++; + + Box bb = pad->getBoundingBox( basicLayer ); + transformation.applyOn( bb ); + + cdebug_log(159,0) << " Merging PowerRail element: " << pad << " bb:" << bb + << " " << basicLayer << endl; + + _powerRailsPlanes.merge( bb, rootNet ); + return; + } + + const Rectilinear* rectilinear = dynamic_cast( component ); + if (rectilinear) { + _goMatchCount++; + cdebug_log(159,0) << " Merging PowerRail element: " << rectilinear << " " << basicLayer << endl; + vector boxes; + rectilinear->getAsRectangles( boxes, Rectilinear::HSliced ); + for ( Box bb : boxes ) { + transformation.applyOn( bb ); + cdebug_log(159,0) << " | " << " bb:" << bb << endl; + _powerRailsPlanes.merge( bb, rootNet ); } } } diff --git a/hurricane/src/hurricane/hurricane/Query.h b/hurricane/src/hurricane/hurricane/Query.h index 24d923419..d0080af71 100644 --- a/hurricane/src/hurricane/hurricane/Query.h +++ b/hurricane/src/hurricane/hurricane/Query.h @@ -413,3 +413,6 @@ namespace Hurricane { } // Hurricane namespace. + + +INSPECTOR_PR_SUPPORT(Hurricane::Query::Mask); diff --git a/katana/src/PowerRails.cpp b/katana/src/PowerRails.cpp index dc5a24500..7dce97d09 100644 --- a/katana/src/PowerRails.cpp +++ b/katana/src/PowerRails.cpp @@ -982,13 +982,13 @@ namespace { if (not activePlane) return; + cmess1 << " - PowerRails in " << activePlane->getLayer()->getName() << " ..." << endl; if (static_cast(activePlane->getLayer())->getMaterial() != BasicLayer::Material::blockage) setStopCellFlags( Cell::Flags::AbstractedSupply ); else unsetStopCellFlags( Cell::Flags::AbstractedSupply ); - cmess1 << " - PowerRails in " << activePlane->getLayer()->getName() << " ..." << endl; Query::doQuery(); } @@ -1015,8 +1015,8 @@ namespace { , const Transformation& transformation ) { - const Component* component = dynamic_cast(go); - if ( component ) { + const Component* component = dynamic_cast( go ); + if (component) { if ( _framework->isPad(getMasterCell()) and ( (_routingGauge->getLayerDepth(component->getLayer()) < 2) or (component->getLayer()->getBasicLayers().getFirst()->getMaterial() != BasicLayer::Material::blockage) ) ) @@ -1024,19 +1024,19 @@ namespace { Net* rootNet = _katana->getBlockageNet(); if (not _isBlockagePlane) { - rootNet = _powerRailsPlanes.getRootNet(component->getNet(),getPath()); + rootNet = _powerRailsPlanes.getRootNet( component->getNet(), getPath() ); } #if 0 - Net* rootNet = NULL; - if ( not _isBlockagePlane ) - rootNet = _powerRailsPlanes.getRootNet(component->getNet(),getPath()); + Net* rootNet = nullptr; + if (not _isBlockagePlane) + rootNet = _powerRailsPlanes.getRootNet( component->getNet(), getPath() ); else { rootNet = _katana->getBlockageNet(); } #endif - if ( rootNet == NULL ) { + if (not rootNet) { cdebug_log(159,0) << " rootNet is NULL, not taken into account." << endl; return; } @@ -1050,14 +1050,13 @@ namespace { return; } - const Segment* segment = dynamic_cast(component); + const Segment* segment = dynamic_cast( component ); if (segment) { _goMatchCount++; cdebug_log(159,0) << " Merging PowerRail element: " << segment << endl; - Box bb = segment->getBoundingBox ( basicLayer ); - - uint32_t depth = _routingGauge->getLayerDepth ( segment->getLayer() ); + Box bb = segment->getBoundingBox( basicLayer ); + uint32_t depth = _routingGauge->getLayerDepth( segment->getLayer() ); if ( _chipTools.isChip() and ((depth == 2) or (depth == 3)) @@ -1065,33 +1064,32 @@ namespace { and (segment->getLength() > _chipTools.getPadWidth()) and (_katana->getChipTools().getCorona().contains(bb)) ) { switch ( depth ) { - case 2: _vRingSegments.push_back ( segment ); break; // M3 V. - case 3: _hRingSegments.push_back ( segment ); break; // M4 H. + case 2: _vRingSegments.push_back( segment ); break; // M3 V. + case 3: _hRingSegments.push_back( segment ); break; // M4 H. } return; } - transformation.applyOn ( bb ); - - _powerRailsPlanes.merge ( bb, rootNet ); + transformation.applyOn( bb ); + _powerRailsPlanes.merge( bb, rootNet ); return; } - const Contact* contact = dynamic_cast(component); + const Contact* contact = dynamic_cast( component ); if (contact) { _goMatchCount++; Box bb = contact->getBoundingBox ( basicLayer ); - transformation.applyOn ( bb ); + transformation.applyOn( bb ); cdebug_log(159,0) << " Merging PowerRail element: " << contact << " bb:" << bb << " " << basicLayer << endl; - _powerRailsPlanes.merge ( bb, rootNet ); + _powerRailsPlanes.merge( bb, rootNet ); return; } - const Pad* pad = dynamic_cast(component); + const Pad* pad = dynamic_cast( component ); if (pad) { _goMatchCount++; @@ -1105,24 +1103,22 @@ namespace { return; } - const Rectilinear* rectilinear = dynamic_cast(component); - if (rectilinear and (rectilinear->getPoints().size() == 5)) { - _goMatchCount++; - - Box bb = rectilinear->getBoundingBox( basicLayer ); - transformation.applyOn( bb ); - - cdebug_log(159,0) << " Merging PowerRail element: " << rectilinear << " bb:" << bb - << " " << basicLayer << endl; - - _powerRailsPlanes.merge( bb, rootNet ); - return; - } - + const Rectilinear* rectilinear = dynamic_cast( component ); if (rectilinear) { - if (not _powerRailsPlanes.getActivePlane()->getLayer()->isBlockage()) return; - _goMatchCount++; + if (not _powerRailsPlanes.getActivePlane()->getLayer()->isBlockage()) { + _goMatchCount++; + vector boxes; + rectilinear->getAsRectangles( boxes, Rectilinear::HSliced ); + for ( Box bb : boxes ) { + transformation.applyOn( bb ); + cdebug_log(159,0) << " Merging PowerRail element: " << rectilinear << " bb:" << bb + << " " << basicLayer << endl; + _powerRailsPlanes.merge( bb, rootNet ); + } + return; + } + _goMatchCount++; RoutingPlane* plane = _powerRailsPlanes.getActivePlane()->getRoutingPlane(); RoutingLayerGauge* rlg = plane->getLayerGauge(); DbU::Unit delta = plane->getLayerGauge()->getPitch() - 1; From f7a339a84b1cec9b37f94433785a7400268075ec Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Mon, 1 Jan 2024 20:33:06 +0100 Subject: [PATCH 32/51] Fix TrackBlockage::_getString() when the is not yet a track (transient). --- katana/src/TrackBlockage.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/katana/src/TrackBlockage.cpp b/katana/src/TrackBlockage.cpp index 040558c19..6784eb44e 100644 --- a/katana/src/TrackBlockage.cpp +++ b/katana/src/TrackBlockage.cpp @@ -222,14 +222,18 @@ namespace Katana { string TrackBlockage::_getString () const { - string s1 = string("getIndex()) + "] " - + getString(getLayer()->getName()) + " @" - + DbU::getValueString(getTrack()->getAxis()) - + " [" + DbU::getValueString(_sourceU) - + ":" + DbU::getValueString(_targetU) + "]" - + " " + DbU::getValueString(_targetU-_sourceU) - + " FBN>"; + string s1 = string("getIndex()) + "] " + + getString(getLayer()->getName()) + " @" + + DbU::getValueString(getTrack()->getAxis()); + } else { + s1 += "[i] layer @axis"; + } + s1 += " [" + DbU::getValueString(_sourceU) + + ":" + DbU::getValueString(_targetU) + "]" + + " " + DbU::getValueString(_targetU-_sourceU) + + " FBN>"; return s1; } From b03c7e37825fabf5e0ad04a54fe7c3e9a43437cc Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Mon, 1 Jan 2024 20:44:29 +0100 Subject: [PATCH 33/51] protectRoutingPads() call moved from ::digitalInit() to ::runGlobalrouter(). --- katana/src/KatanaEngine.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/katana/src/KatanaEngine.cpp b/katana/src/KatanaEngine.cpp index a4ca24431..e78ae09c8 100644 --- a/katana/src/KatanaEngine.cpp +++ b/katana/src/KatanaEngine.cpp @@ -246,15 +246,6 @@ namespace Katana { setState( Anabatic::EngineDriving ); throw Error( "KatanaEngine::digitalInit(): All nets are already routed, doing nothing." ); } - - if (not isChannelStyle()) { - if (!(flags & Flags::PlacementCallback)) { - setupPowerRails(); - Flags protectFlags = (getConfiguration()->getNetBuilderStyle() == "VH,2RL") - ? Flags::ProtectSelf : Flags::NoFlags; - protectRoutingPads( protectFlags ); - } - } cdebug_tabw(155,-1); } From bdc035f8ac762b9e4c1ef4f951244f8cc9640bd0 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Fri, 5 Jan 2024 11:19:59 +0100 Subject: [PATCH 34/51] Support for offgrid M1 & VH topologies (WIP 2). * Renaming TrackBlockage into a more flexible TrackFixedSpan than can handle both blockage and terminal reservation. Allow to change the associated net of a TrackFixedSegment, to easily manage conflicts. * Manage the segment unbreakble flag at the AutoSegment::create() flag level (need to be added to Constant). * In AutoSegment::makeDogleg(AutoContact*), don't check if the break point is under the source/target GCell, in some case it could be slightly outside (SegForOffgrid case). * In AutoSegment::create(), get the correct wire with for metal1 segments. * In RoutingPad, add the ability to manually select what is to be considered as the center of the RP. See Configuration::selectRpComponent(). * In Configuration::selectRpComponent(), force the center of the RoutingPad so it is in the GCell that have an accessible track (due to offgrid). * In Disjkstra::load(), use RoutingPad::getUserCenter() to locate the relevant GCell. * In NetBuilderVH::doRp_Access(), more complex creation of wiring for offgrid metal1 terminals. Allow local metal2 to be one track outside it's owning GCell (set the SegForOffgrid flag). * In Anabatic::propagateConstraintsFromRp(), manage the case of offgrid RoutingPad. Allow a one pitch margin on each side (widow of two pitchs which should contains at least a grid point). * In GlobalRoute::runGlobalRouter(), protect the RoutingPad in Constant::LocalOnly layer gauge. * In protectRoutingpads(), manage conflicts when a part of a track may be reached by multiple terminals or overlap a blockage. Use a simple strategy : in case of overlap, change into blockage. Session must be revalidated after each terminal so the tracks are up to date for overlap search for the next one. * In RoutingEvent::revalidate(), expand the track axis constraint of one pitch in case of an offgrid flagged segment (set in NetBuilderVH::doRp_Access()). * In Track::getBeginIndex(), finally manage the case where consecutive segments of a same net are *not* overlapping (was assumed so before). * In Track::expandFreeInterval(), fix wrong management of the case BeginIsSegmentMax with a begin index of 0. This is a very corner case causing error only at the very beginning of a track. * New proxy method TrackElement::isForOffgrid(). --- anabatic/src/AutoSegment.cpp | 13 +- anabatic/src/Configuration.cpp | 6 + anabatic/src/Constants.cpp | 31 ++- anabatic/src/Dijkstra.cpp | 4 +- anabatic/src/NetBuilderVH.cpp | 35 ++- anabatic/src/NetConstraints.cpp | 47 +++- anabatic/src/anabatic/AutoSegment.h | 3 + anabatic/src/anabatic/Constants.h | 3 + .../src/hurricane/hurricane/RoutingPad.h | 8 + katana/src/GlobalRoute.cpp | 7 +- katana/src/KatanaEngine.cpp | 11 +- katana/src/PowerRails.cpp | 4 +- katana/src/ProtectRoutingPads.cpp | 97 +++++-- katana/src/RoutingEvent.cpp | 4 + katana/src/Track.cpp | 24 +- katana/src/TrackBlockage.cpp | 249 ----------------- katana/src/TrackElement.cpp | 1 + katana/src/TrackFixedSpan.cpp | 251 ++++++++++++++++++ katana/src/TrackSegment.cpp | 1 + katana/src/katana/TrackBlockage.h | 87 ------ katana/src/katana/TrackElement.h | 1 + katana/src/katana/TrackFixedSpan.h | 101 +++++++ katana/src/katana/TrackSegment.h | 1 + katana/src/meson.build | 2 +- 24 files changed, 576 insertions(+), 415 deletions(-) delete mode 100644 katana/src/TrackBlockage.cpp create mode 100644 katana/src/TrackFixedSpan.cpp delete mode 100644 katana/src/katana/TrackBlockage.h create mode 100644 katana/src/katana/TrackFixedSpan.h diff --git a/anabatic/src/AutoSegment.cpp b/anabatic/src/AutoSegment.cpp index a8fa962c2..aaab0e053 100644 --- a/anabatic/src/AutoSegment.cpp +++ b/anabatic/src/AutoSegment.cpp @@ -2551,7 +2551,7 @@ namespace Anabatic { cdebug_log(149,0) << "isSource:" << isSource << endl; - makeDogleg( from->getGCell(), Flags::NoCheckLayer ); + makeDogleg( from->getGCell(), Flags::NoCheckLayer|Flags::NoCheckGCell ); if (doglegs.size() == index) { cdebug_tabw(149,-1); return NULL; @@ -2704,7 +2704,7 @@ namespace Anabatic { return 0; } - if (doglegGCell->getSide(getDirection()).intersect(getSpanU())) { + if ((flags & Flags::NoCheckGCell) or doglegGCell->getSide(getDirection()).intersect(getSpanU())) { cdebug_log(149,0) << "Dogleg in " << this << " spanU:" << getSpanU() << endl; rflags = _makeDogleg( doglegGCell, flags ); } else { @@ -2829,7 +2829,7 @@ namespace Anabatic { DbU::Unit verticalWidth = Session::getDVerticalWidth(); if (not Session::getAnabatic()->getConfiguration()->isGMetal(hurricaneSegment->getLayer())) { size_t depth = Session::getAnabatic()->getConfiguration()->getLayerDepth( hurricaneSegment->getLayer() ); - if (depth > 2) { + if ((depth == 0) or (depth > 2)) { horizontalLayer = verticalLayer = hurricaneSegment->getLayer(); horizontalWidth = Session::getAnabatic()->getConfiguration()->getWireWidth( depth ); verticalWidth = Session::getAnabatic()->getConfiguration()->getPWireWidth( depth ); @@ -3073,9 +3073,10 @@ namespace Anabatic { } else throw Error( badSegment, getString(source).c_str(), getString(target).c_str() ); - if (wPitch > 1) segment->setFlags( SegWide ); - if (source->canDrag() or target->canDrag()) segment->setFlags( SegDrag ); - if (dir & Flags::UseNonPref) segment->setFlags( SegNonPref ); + if (wPitch > 1) segment->setFlags( SegWide ); + if (source->canDrag() or target->canDrag()) segment->setFlags( SegDrag ); + if (dir & Flags::UseNonPref) segment->setFlags( SegNonPref ); + if (dir & Flags::Unbreakable) segment->setFlags( SegUnbreakable ); if (dir.contains(Flags::UseNonPref|Flags::OnVSmall)) segment->setFlags( SegOnVSmall ); return segment; diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index 5610ef4c0..fc04aa6ca 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.cpp @@ -508,6 +508,7 @@ namespace Anabatic { return true; } + Point ongridCenter; DbU::Unit bestSpan = 0; Component* ongridComponent = NULL; Component* offgridComponent = NULL; @@ -578,6 +579,10 @@ namespace Anabatic { if (not ongridComponent or (bestSpan < maxPos-minPos)) { ongridComponent = component; bestSpan = maxPos - minPos; + if (gauge->isVertical()) + ongridCenter = Point( trackPos, bb.getCenter().getY() ); + else + ongridCenter = Point( bb.getCenter().getX(), trackPos ); } } else { cdebug_log(112,0) << "Component is offgrid." << endl; @@ -588,6 +593,7 @@ namespace Anabatic { bool rvalue = false; if (ongridComponent) { rp->setExternalComponent( ongridComponent ); + rp->setUserCenter( ongridCenter ); cdebug_log(112,0) << "Using best candidate:" << ongridComponent << endl; rvalue = true; } else { diff --git a/anabatic/src/Constants.cpp b/anabatic/src/Constants.cpp index 267bdcd9c..81c1fc70c 100644 --- a/anabatic/src/Constants.cpp +++ b/anabatic/src/Constants.cpp @@ -119,20 +119,23 @@ namespace Anabatic { const BaseFlags Flags::DoglegOnRight = (1L << 24); const BaseFlags Flags::WithNeighbors = (1L << 25); const BaseFlags Flags::NoCheckLayer = (1L << 26); - const BaseFlags Flags::HalfSlacken = (1L << 27); - const BaseFlags Flags::NoGCellShrink = (1L << 28); - const BaseFlags Flags::CParanoid = (1L << 29); - const BaseFlags Flags::CheckLowDensity = (1L << 30); - const BaseFlags Flags::CheckLowUpDensity = (1L << 31); - const BaseFlags Flags::NoUpdate = (1L << 32); - const BaseFlags Flags::NorthPath = (1L << 33); - const BaseFlags Flags::UseNonPref = (1L << 34); - const BaseFlags Flags::Force = (1L << 35); - const BaseFlags Flags::LayerCapOnly = (1L << 36); - const BaseFlags Flags::NoMinLength = (1L << 37); - const BaseFlags Flags::NoSegExt = (1L << 38); - const BaseFlags Flags::NullLength = (1L << 39); - const BaseFlags Flags::OnVSmall = (1L << 40); + const BaseFlags Flags::NoCheckGCell = (1L << 27); + const BaseFlags Flags::HalfSlacken = (1L << 28); + const BaseFlags Flags::NoGCellShrink = (1L << 29); + const BaseFlags Flags::CParanoid = (1L << 30); + const BaseFlags Flags::CheckLowDensity = (1L << 31); + const BaseFlags Flags::CheckLowUpDensity = (1L << 32); + const BaseFlags Flags::NoUpdate = (1L << 33); + const BaseFlags Flags::NorthPath = (1L << 34); + const BaseFlags Flags::UseNonPref = (1L << 35); + const BaseFlags Flags::Force = (1L << 36); + const BaseFlags Flags::LayerCapOnly = (1L << 37); + const BaseFlags Flags::NoMinLength = (1L << 38); + const BaseFlags Flags::NoSegExt = (1L << 39); + const BaseFlags Flags::NullLength = (1L << 40); + const BaseFlags Flags::OnVSmall = (1L << 41); + const BaseFlags Flags::Unbreakable = (1L << 42); + const BaseFlags Flags::ForOffgrid = (1L << 43); Flags::~Flags () diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp index 796178622..2ec28cd48 100644 --- a/anabatic/src/Dijkstra.cpp +++ b/anabatic/src/Dijkstra.cpp @@ -1568,8 +1568,8 @@ namespace Anabatic { cerr << Warning( "Dijktra::load(): %s has no components on grid.", getString(rp).c_str() ) << endl; } - cdebug_log(112,0) << "@ rp: " << rp << ", getCenter(): " << rp->getBoundingBox().getCenter() << endl; - Point center = rp->getBoundingBox().getCenter(); + cdebug_log(112,0) << "@ rp: " << rp << ", getUserCenter(): " << rp->getUserCenter() << endl; + Point center = rp->getUserCenter(); GCell* gcell = _anabatic->getGCellUnder( center ); Box bb = rp->getBoundingBox(); bool isDriver = false; diff --git a/anabatic/src/NetBuilderVH.cpp b/anabatic/src/NetBuilderVH.cpp index cbf83c609..29ae2019b 100644 --- a/anabatic/src/NetBuilderVH.cpp +++ b/anabatic/src/NetBuilderVH.cpp @@ -57,6 +57,7 @@ namespace Anabatic { using Hurricane::Warning; using Hurricane::Error; using Hurricane::Pin; + using Constant::LayerGaugeType; NetBuilderVH::NetBuilderVH () @@ -182,18 +183,36 @@ namespace Anabatic { { cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl; - AutoContact* rpContactSource = NULL; - AutoContact* rpContactTarget = NULL; - const Layer* rpLayer = rp->getLayer(); - size_t rpDepth = Session::getLayerDepth( rp->getLayer() ); + AutoSegment* segment = nullptr; + AutoContact* rpContactSource = nullptr; + AutoContact* rpContactTarget = nullptr; + const Layer* rpLayer = rp->getLayer(); + size_t rpDepth = Session::getLayerDepth( rpLayer ); + RoutingLayerGauge* rlg = Session::getLayerGauge( rpLayer ); + uint64_t offgridFlag = 0; flags |= checkRoutingPadSize( rp ); doRp_AutoContacts( gcell, rp, rpContactSource, rpContactTarget, flags ); const Layer* viaLayer1 = Session::getBuildContactLayer( 1 ); - if (rp->isM1Offgrid() or (flags & HSmall)) { + if (rp->isM1Offgrid() /*or (flags & HSmall)*/) { AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getBuildRoutingLayer(rpDepth+1) ); - AutoSegment::create( rpContactSource, subContact1, Flags::Horizontal|Flags::UseNonPref ); + Flags segFlags = Flags::NoFlags; + size_t segDepth = 1; + offgridFlag |= AutoSegment::SegForOffgrid; + if (rlg->getType() == LayerGaugeType::LocalOnly) { + segDepth = 0; + if (flags & VSmall) { + segment = AutoSegment::create( rpContactSource + , subContact1 + , segFlags|Flags::Vertical|Flags::UseNonPref + , segDepth ); + rpContactSource = subContact1; + subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getBuildRoutingLayer(rpDepth+1) ); + segFlags |= Flags::Unbreakable; + } + } + AutoSegment::create( rpContactSource, subContact1, segFlags|Flags::Horizontal, segDepth ); rpContactSource = subContact1; } @@ -203,7 +222,7 @@ namespace Anabatic { cdebug_log(145,0) << "case not(HAccess|HAccessEW)" << endl; AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), viaLayer1 ); AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), viaLayer1 ); - AutoSegment::create( rpContactSource, subContact1, Flags::Vertical ); + AutoSegment::create( rpContactSource, subContact1, Flags::Vertical )->setFlags( offgridFlag ); AutoSegment::create( subContact1, subContact2, Flags::Horizontal); rpContactSource = subContact2; } else { @@ -215,7 +234,7 @@ namespace Anabatic { else subContact1 = AutoContactTurn::create( gcell, rp->getNet(), viaLayer1 ); - AutoSegment::create( rpContactSource, subContact1, Flags::Vertical ); + AutoSegment::create( rpContactSource, subContact1, Flags::Vertical )->setFlags( offgridFlag ); rpContactSource = subContact1; } } diff --git a/anabatic/src/NetConstraints.cpp b/anabatic/src/NetConstraints.cpp index f78fbf2bf..839bb272e 100644 --- a/anabatic/src/NetConstraints.cpp +++ b/anabatic/src/NetConstraints.cpp @@ -62,6 +62,8 @@ namespace { void propagateConstraintFromRp ( RoutingPad* rp ) { cdebug_log(146,1) << "propagateConstraintFromRp() - " << rp << endl; + RoutingLayerGauge* rlg = Session::getLayerGauge( rp->getLayer() ); + bool allowOffgrid = (rlg->getType() == Constant::LocalOnly); for ( Component* component : rp->getSlaveComponents() ) { cdebug_log(146,0) << "slave component: " << component << endl; @@ -74,19 +76,25 @@ namespace { set verticalSegments; set horizontalSegments; + set offgridSegments; for ( AutoSegment* segment : sourceContact->getAutoSegments() ) { cdebug_log(146,0) << "Examining: " << segment << endl; - AutoContact* targetContact = segment->getOppositeAnchor(sourceContact); + AutoContact* targetContact = segment->getOppositeAnchor( sourceContact ); if (targetContact) { + if (allowOffgrid and (segment->getLayer() == rp->getLayer()) and segment->isNonPref()) { + cdebug_log(146,0) << "On offgrid stack " << segment << endl; + offgridSegments.insert( segment ); + continue; + } if (segment->isHorizontal()) { cdebug_log(146,0) << "On horizontal stack " << segment << endl; horizontalSegments.insert( segment ); - } else { - cdebug_log(146,0) << "On vertical stack " << segment << endl; - verticalSegments.insert( segment ); + continue; } + cdebug_log(146,0) << "On vertical stack " << segment << endl; + verticalSegments.insert( segment ); } } @@ -94,7 +102,7 @@ namespace { cdebug_log(146,0) << "Propagate constraint on horizontal segments" << endl; for ( AutoSegment* horizontal : horizontalSegments ) { - AutoContact* contact = NULL; + AutoContact* contact = nullptr; for ( AutoSegment* aligned : horizontal->getAligneds(Flags::WithSelf) ) { cdebug_log(146,0) << "aligned horizontal: " << aligned << endl; @@ -121,7 +129,7 @@ namespace { cdebug_log(146,0) << "Propagate constraint on vertical segments" << endl; for ( AutoSegment* vertical : verticalSegments ) { - AutoContact* contact = NULL; + AutoContact* contact = nullptr; for ( AutoSegment* aligned : vertical->getAligneds(Flags::WithSelf) ) { cdebug_log(146,0) << "aligned vertical: " << aligned << endl; @@ -141,6 +149,33 @@ namespace { } } } + + // Special case of offgrid segments (usually local M1). + cdebug_log(146,0) << "Propagate constraint on offgrid segments" << endl; + + for ( AutoSegment* perpandicular : offgridSegments ) { + AutoContact* targetContact = perpandicular->getOppositeAnchor( sourceContact ); + Box nonPrefConstraint = constraintBox; + Box ongridConstraint = constraintBox; + if (rlg->isHorizontal()) { + nonPrefConstraint.inflate( 0, rlg->getPitch(), 0, rlg->getPitch() ); + } else { + nonPrefConstraint.inflate( rlg->getPitch(), 0, rlg->getPitch(), 0 ); + } + ongridConstraint.inflate( rlg->getPitch() ); + + cdebug_log(146,0) << "perpandicular offgrid: " << perpandicular << endl; + targetContact->setConstraintBox( nonPrefConstraint ); + cdebug_log(146,0) << "Apply to first turn: " << targetContact << endl; + if (not targetContact->isTurn()) continue; + + AutoSegment* parallel = targetContact->getPerpandicular( perpandicular ); + cdebug_log(146,0) << "parallel offgrid: " << parallel << endl; + targetContact = parallel->getOppositeAnchor( targetContact ); + if (not targetContact) continue; + targetContact->setConstraintBox( ongridConstraint ); + cdebug_log(146,0) << "Apply to second turn: " << targetContact << endl; + } } } diff --git a/anabatic/src/anabatic/AutoSegment.h b/anabatic/src/anabatic/AutoSegment.h index 894041606..bdb11cea5 100644 --- a/anabatic/src/anabatic/AutoSegment.h +++ b/anabatic/src/anabatic/AutoSegment.h @@ -110,6 +110,7 @@ namespace Anabatic { static const uint64_t SegAtMinArea = (1L<<38); static const uint64_t SegNoMoveUp = (1L<<39); static const uint64_t SegOnVSmall = (1L<<40); + static const uint64_t SegForOffgrid = (1L<<41); // Masks. static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2; static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned; @@ -204,6 +205,7 @@ namespace Anabatic { inline bool isUnbreakable () const; inline bool isNonPref () const; inline bool isNonPrefOnVSmall () const; + inline bool isForOffgrid () const; inline bool isDrag () const; inline bool isAtMinArea () const; inline bool isNotSourceAligned () const; @@ -539,6 +541,7 @@ namespace Anabatic { inline bool AutoSegment::isUnbreakable () const { return _flags & SegUnbreakable; } inline bool AutoSegment::isNonPref () const { return _flags & SegNonPref; } inline bool AutoSegment::isNonPrefOnVSmall () const { return (_flags & SegNonPref) and (_flags & SegOnVSmall); } + inline bool AutoSegment::isForOffgrid () const { return _flags & SegForOffgrid; } inline bool AutoSegment::isBipoint () const { return _flags & SegBipoint; } inline bool AutoSegment::isWeakTerminal () const { return (_rpDistance < 2); } inline bool AutoSegment::isWeakTerminal1 () const { return (_rpDistance == 1); } diff --git a/anabatic/src/anabatic/Constants.h b/anabatic/src/anabatic/Constants.h index 462654a65..01de41147 100644 --- a/anabatic/src/anabatic/Constants.h +++ b/anabatic/src/anabatic/Constants.h @@ -97,6 +97,7 @@ namespace Anabatic { static const BaseFlags DoglegOnRight ; static const BaseFlags WithNeighbors ; static const BaseFlags NoCheckLayer ; + static const BaseFlags NoCheckGCell ; static const BaseFlags HalfSlacken ; static const BaseFlags NoGCellShrink ; static const BaseFlags CParanoid ; @@ -111,6 +112,8 @@ namespace Anabatic { static const BaseFlags NoSegExt ; static const BaseFlags NullLength ; static const BaseFlags OnVSmall ; + static const BaseFlags Unbreakable ; + static const BaseFlags ForOffgrid ; public: inline Flags ( uint64_t flags = NoFlags ); inline Flags ( const Hurricane::BaseFlags& ); diff --git a/hurricane/src/hurricane/hurricane/RoutingPad.h b/hurricane/src/hurricane/hurricane/RoutingPad.h index ab77b6bda..575a4fa5d 100644 --- a/hurricane/src/hurricane/hurricane/RoutingPad.h +++ b/hurricane/src/hurricane/hurricane/RoutingPad.h @@ -57,6 +57,7 @@ namespace Hurricane { static const uint32_t VSmall = (1 << 7); static const uint32_t Punctual = (1 << 8); static const uint32_t M1Offgrid = (1 << 9); + static const uint32_t UserCenter = (1 << 10); static const uint32_t SizeFlags = HSmall|VSmall|Punctual|M1Offgrid; static const uint32_t SelectedComponent = (1 << 10); public: @@ -70,7 +71,9 @@ namespace Hurricane { inline bool isVSmall () const; inline bool isPunctual () const; inline bool isM1Offgrid () const; + inline bool hasUserCenter () const; inline bool hasSelectedComponent () const; + inline Point getUserCenter () const; inline uint32_t getFlags () const; inline Occurrence getOccurrence () const; Occurrence getPlugOccurrence (); @@ -92,6 +95,7 @@ namespace Hurricane { virtual void translate ( const DbU::Unit& dx, const DbU::Unit& dy ); void setExternalComponent ( Component* ); Component* setOnBestComponent ( uint32_t flags ); + inline void setUserCenter ( const Point& ); void restorePlugOccurrence (); inline void setFlags ( uint32_t ); inline void unsetFlags ( uint32_t ); @@ -111,6 +115,7 @@ namespace Hurricane { // Attributes. Occurrence _occurrence; uint32_t _flags; + Point _userCenter; }; @@ -120,10 +125,13 @@ namespace Hurricane { inline bool RoutingPad::isPunctual () const { return (_flags & Punctual); } inline bool RoutingPad::isM1Offgrid () const { return (_flags & M1Offgrid); } inline bool RoutingPad::hasSelectedComponent () const { return (_flags & SelectedComponent); } + inline bool RoutingPad::hasUserCenter () const { return (_flags & UserCenter); } + inline Point RoutingPad::getUserCenter () const { return (hasUserCenter()) ? _userCenter : getCenter(); } inline uint32_t RoutingPad::getFlags () const { return _flags; } inline Occurrence RoutingPad::getOccurrence () const { return _occurrence; }; inline void RoutingPad::setFlags ( uint32_t flags ) { _flags |= flags; } inline void RoutingPad::unsetFlags ( uint32_t flags ) { _flags &= ~flags; } + inline void RoutingPad::setUserCenter ( const Point& center ) { _flags |= UserCenter; _userCenter = center; } template diff --git a/katana/src/GlobalRoute.cpp b/katana/src/GlobalRoute.cpp index 262e1914b..504cf4f7e 100644 --- a/katana/src/GlobalRoute.cpp +++ b/katana/src/GlobalRoute.cpp @@ -506,8 +506,11 @@ namespace Katana { if (not isChannelStyle()) { if (!(flags & Flags::PlacementCallback)) { setupPowerRails(); - Flags protectFlags = (getConfiguration()->getNetBuilderStyle() == "VH,2RL") - ? Flags::ProtectSelf : Flags::NoFlags; + Flags protectFlags = Flags::NoFlags; + if (getConfiguration()->getNetBuilderStyle() == "VH,2RL") + protectFlags |= Flags::ProtectSelf; + if (getConfiguration()->getLayerGauge(0)->getType() == Constant::LocalOnly) + protectFlags |= Flags::ProtectSelf; protectRoutingPads( protectFlags ); } } diff --git a/katana/src/KatanaEngine.cpp b/katana/src/KatanaEngine.cpp index e78ae09c8..5a43feda5 100644 --- a/katana/src/KatanaEngine.cpp +++ b/katana/src/KatanaEngine.cpp @@ -482,16 +482,7 @@ namespace Katana { } cdebug_log(159,0) << "Capacity from: " << element << ":" << elementCapacity << endl; - Segment* segment = element->getSegment(); - Interval segmentUSpan; - - source = segment->getSourcePosition(); - target = segment->getTargetPosition(); - if (track->getDirection() == Flags::Vertical) - segmentUSpan = Interval( source.getY(), target.getY() ); - else - segmentUSpan = Interval( source.getX(), target.getX() ); - + Interval segmentUSpan = Interval( element->getSourceU(), element->getTargetU() ); if (uspan.isEmpty()) { uspan = segmentUSpan; continue; diff --git a/katana/src/PowerRails.cpp b/katana/src/PowerRails.cpp index 7dce97d09..ef2e2d3e1 100644 --- a/katana/src/PowerRails.cpp +++ b/katana/src/PowerRails.cpp @@ -38,7 +38,7 @@ #include "anabatic/GCell.h" #include "katana/RoutingPlane.h" #include "katana/TrackFixedSegment.h" -#include "katana/TrackBlockage.h" +#include "katana/TrackFixedSpan.h" #include "katana/Track.h" #include "katana/KatanaEngine.h" @@ -1132,7 +1132,7 @@ namespace { Track* track = plane->getTrackByPosition( axisMin, Constant::Superior ); for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNextTrack() ) { - TrackElement* element = TrackBlockage::create ( track, bb ); + TrackElement* element = TrackFixedSpan::create ( nullptr, bb, track ); cdebug_log(159,0) << " Insert in " << track << "+" << element << endl; } } diff --git a/katana/src/ProtectRoutingPads.cpp b/katana/src/ProtectRoutingPads.cpp index ace7f8efb..4798b671d 100644 --- a/katana/src/ProtectRoutingPads.cpp +++ b/katana/src/ProtectRoutingPads.cpp @@ -37,6 +37,7 @@ #include "katana/RoutingPlane.h" #include "katana/TrackSegment.h" #include "katana/TrackFixedSegment.h" +#include "katana/TrackFixedSpan.h" #include "katana/Track.h" #include "katana/KatanaEngine.h" @@ -78,19 +79,22 @@ namespace { Name padNetName = "pad"; Component* usedComponent = rp->_getEntityAs(); Path path = rp->getOccurrence().getPath(); + Net* net = rp->getNet(); Net* masterNet = usedComponent->getNet(); Transformation transformation = path.getTransformation(); if (dynamic_cast(usedComponent)) { cerr << Error( "Katana::protectRoutingPad(): A RoutingPad of \"%s\" is still on it's Plug.\n" " (%s)" - , getString(rp->getNet()->getName()).c_str() + , getString(net->getName()).c_str() , getString(usedComponent).c_str() ) << endl; cdebug_tabw(145,-1); return; } - if (not Session::getRoutingGauge()->isUsable(usedComponent->getLayer())) { + RoutingLayerGauge* rlg = Session::getLayerGauge( rp->getLayer() ); + if (not ( (rlg->getType() == Constant::Default ) + or (rlg->getType() == Constant::LocalOnly))) { cdebug_tabw(145,-1); return; } @@ -99,8 +103,8 @@ namespace { cdebug_log(145,0) << "masterNet: " << masterNet << endl; if (CatalogExtension::isPad(masterNet->getCell())) { - if ( rp->getNet()->isPower() - or (rp->getNet()->getName() == padNetName) ) { + if ( net->isPower() + or (net->getName() == padNetName) ) { cdebug_tabw(145,-1); return; } @@ -126,6 +130,7 @@ namespace { DbU::Unit delta = plane->getLayerGauge()->getPitch() - wireWidth/2 - DbU::fromLambda(0.1); + DbU::Unit cap = plane->getLayer()->getMinimalSpacing() / 2; DbU::Unit extension = segments[i]->getLayer()->getExtentionCap(); Box bb ( segments[i]->getBoundingBox() ); @@ -133,6 +138,7 @@ namespace { cdebug_log(145,0) << "@ " << segments[i] << " bb:" << bb << endl; cdebug_log(145,0) << "delta=" << DbU::getValueString(delta) << endl; + cdebug_log(145,0) << "cap=" << DbU::getValueString(cap) << endl; if ( direction == Flags::Horizontal ) { DbU::Unit axisMin = bb.getYMin() - delta; @@ -140,15 +146,41 @@ namespace { Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior ); for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNextTrack() ) { - Horizontal* segment = Horizontal::create ( rp->getNet() - , segments[i]->getLayer() - , track->getAxis() - , wireWidth - , bb.getXMin()+extension - , bb.getXMax()-extension - ); - TrackFixedSegment::create ( track, segment ); - cdebug_log(145,0) << "| " << segment << endl; + cdebug_log(145,0) << "> track " << track << endl; + // Horizontal* segment = Horizontal::create ( net + // , segments[i]->getLayer() + // , track->getAxis() + // , wireWidth + // , bb.getXMin()+extension + // , bb.getXMax()-extension + // ); + // TrackFixedSegment::create ( track, segment ); + // cdebug_log(145,0) << "| " << segment << endl; + Interval termSpan = Interval( bb.getXMin(), bb.getXMax() ).inflate( cap ); + Interval freeSpan = track->getFreeInterval( bb.getXCenter() ); + cdebug_log(145,0) << "| termSpan " << termSpan << endl; + cdebug_log(145,0) << "| freeSpan " << freeSpan << endl; + bool overlap = false; + bool conflict = false; + if (not freeSpan.contains(termSpan)) { + overlap = true; + size_t ovBegin = 0; + size_t ovEnd = 0; + track->getOverlapBounds( termSpan, ovBegin, ovEnd ); + for ( ; ovBegin <= ovEnd ; ++ovBegin ) { + TrackElement* overlaped = track->getSegment( ovBegin ); + TrackFixedSpan* fixedSpan = dynamic_cast( overlaped ); + if (fixedSpan) { + if (not fixedSpan->isBlockage()) + fixedSpan->setNet( nullptr ); + } else + conflict = true; + } + } + if (not conflict) { + TrackFixedSpan* element = TrackFixedSpan::create( ((overlap) ? nullptr : net), bb, track ); + cdebug_log(145,0) << "| " << element << endl; + } } } else { DbU::Unit axisMin = bb.getXMin() - delta; @@ -156,18 +188,39 @@ namespace { Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior ); for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNextTrack() ) { - Vertical* segment = Vertical::create ( rp->getNet() - , segments[i]->getLayer() - , track->getAxis() - , wireWidth - , bb.getYMin()+extension - , bb.getYMax()-extension - ); - TrackFixedSegment::create ( track, segment ); - cdebug_log(145,0) << "| " << segment << endl; + // Vertical* segment = Vertical::create ( net + // , segments[i]->getLayer() + // , track->getAxis() + // , wireWidth + // , bb.getYMin()+extension + // , bb.getYMax()-extension + // ); + // TrackFixedSegment::create ( track, segment ); + // cdebug_log(145,0) << "| " << segment << endl; + Interval termSpan = Interval( bb.getYMin(), bb.getYMax() ); + Interval freeSpan = track->getFreeInterval( bb.getYCenter() ); + bool overlap = false; + bool conflict = false; + if (not freeSpan.contains(termSpan)) { + TrackElement* overlaped = track->getSegment( bb.getXCenter() ); + if (overlaped) { + overlap = true; + TrackFixedSpan* fixedSpan = dynamic_cast( overlaped ); + if (fixedSpan) { + if (not fixedSpan->isBlockage()) + fixedSpan->setNet( nullptr ); + } else + conflict = true; + } + } + if (not conflict) { + TrackFixedSpan* element = TrackFixedSpan::create( ((overlap) ? nullptr : net), bb, track ); + cdebug_log(145,0) << "| " << element << endl; + } } } } + Session::revalidate(); cdebug_tabw(145,-1); } diff --git a/katana/src/RoutingEvent.cpp b/katana/src/RoutingEvent.cpp index 41cda40e3..85e7be787 100644 --- a/katana/src/RoutingEvent.cpp +++ b/katana/src/RoutingEvent.cpp @@ -712,6 +712,10 @@ namespace Katana { _constraints.inflate( Session::getSliceHeight() ); cdebug_log(159,0) << "Expanding (after):" << _constraints << endl; } + } else { + if (_segment->isForOffgrid()) { + _constraints.inflate( _segment->getPitch() ); + } } if (_segment->isShortDogleg()) { diff --git a/katana/src/Track.cpp b/katana/src/Track.cpp index f4d13b861..4d7de6258 100644 --- a/katana/src/Track.cpp +++ b/katana/src/Track.cpp @@ -466,15 +466,22 @@ namespace Katana { vector::const_iterator lowerBound = lower_bound( _segments.begin(), _segments.end(), position, SourceCompare() ); begin = lowerBound - _segments.begin(); + cdebug_log(155,0) << " lower_bound begin=" << begin << endl; - // This is suspicious. - // I guess this has been written for the case of overlapping segments from the same - // net, we find the first one of the overlapped sets. But what if they are not overlapping - // but still from the same net? size_t sameNetDelta = 0; if (begin < _segments.size()) { - for ( ; (begin > 0) and (_segments[begin-1]->getNet() == _segments[begin]->getNet()) - ; --begin, ++sameNetDelta ); + Interval span = _segments[begin]->getCanonicalInterval(); + size_t minBegin = begin; + for ( size_t i=begin; (i > 0) and (_segments[i-1]->getNet() == _segments[i]->getNet()) + ; --i ) { + Interval current = _segments[i-1]->getCanonicalInterval(); + if (current.intersect(span)) { + span.merge( current ); + minBegin = i - 1; + } + } + sameNetDelta = begin - minBegin; + begin = minBegin; } state = 0; @@ -719,6 +726,11 @@ namespace Katana { minFree = getOccupiedInterval(begin).getVMax(); cdebug_log(155,0) << "minFree:" << DbU::getValueString(minFree) << " begin:" << begin << endl; } + } else { + if (state & BeginIsSegmentMax) { + if (_segments[begin]->getNet() != net) + minFree = getOccupiedInterval(begin).getVMax(); + } } if (not (state & EndIsTrackMax) ) { diff --git a/katana/src/TrackBlockage.cpp b/katana/src/TrackBlockage.cpp deleted file mode 100644 index 6784eb44e..000000000 --- a/katana/src/TrackBlockage.cpp +++ /dev/null @@ -1,249 +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 | -// | 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@lip6.fr | -// | =============================================================== | -// | C++ Module : "./TrackBlockage.cpp" | -// +-----------------------------------------------------------------+ - - -#include -#include "hurricane/Bug.h" -#include "hurricane/Warning.h" -#include "hurricane/Net.h" -#include "hurricane/Name.h" -#include "hurricane/RegularLayer.h" -#include "hurricane/Technology.h" -#include "hurricane/DataBase.h" -#include "hurricane/Horizontal.h" -#include "hurricane/Vertical.h" -#include "anabatic/AutoContact.h" -#include "crlcore/RoutingGauge.h" -#include "katana/DataNegociate.h" -#include "katana/TrackBlockage.h" -#include "katana/TrackCost.h" -#include "katana/Track.h" -#include "katana/RoutingPlane.h" -#include "katana/Session.h" -#include "katana/RoutingEvent.h" -#include "katana/NegociateWindow.h" -#include "katana/KatanaEngine.h" - - -namespace Katana { - - using namespace std; - using Hurricane::Warning; - using Hurricane::Bug; - using Hurricane::Error; - using Hurricane::Net; - using Hurricane::Name; - using Hurricane::RegularLayer; - using Hurricane::Technology; - using Hurricane::DataBase; - using Hurricane::Horizontal; - using Hurricane::Vertical; - using Anabatic::GCellsUnder; - - -// ------------------------------------------------------------------- -// Class : "TrackBlockage". - - - TrackBlockage::TrackBlockage ( Track* track, Box boundingBox ) - : TrackElement(NULL) - , _boundingBox(boundingBox) - { - cdebug_log(159,0) << "TrackBlockage::TrackBlockage() track=" << track << endl; - - setFlags( TElemFixed|TElemBlockage|TElemForwardSetTrack ); - setTrack( track ); - - uint32_t depth = track->getDepth(); - //Technology* technology = DataBase::getDB()->getTechnology(); - //const Layer* layer1 = track->getLayer()->getBlockageLayer(); - //RegularLayer* layer2 = dynamic_cast(technology->getLayer(layer1->getMask())); - //if (layer2) { - //cerr << track->getLayer() << " minSpace:" << DbU::getValueString(track->getLayer()->getMinimalSpacing()) << endl; - - Point source; - Point target; - Interval segside; - Interval uside = track->getKatanaEngine()->getUSide( track->getDirection() ); - DbU::Unit cap = track->getLayer()->getMinimalSpacing()/2 /*+ track->getLayer()->getExtentionCap()*/; - cdebug_log(159,0) << "uside:" << uside << " cap:" << DbU::getValueString(cap) << endl; - cdebug_log(159,0) << "bb:" << boundingBox << endl; - if (track->getDirection() == Flags::Horizontal) { - segside = Interval( boundingBox.getXMin(), boundingBox.getXMax() ); - _sourceU = max( boundingBox.getXMin() - cap, uside.getVMin()); - _targetU = min( boundingBox.getXMax() + cap, uside.getVMax()); - source = Point( boundingBox.getXMin(), track->getAxis() ); - target = Point( boundingBox.getXMax(), track->getAxis() ); - } else { - segside = Interval( boundingBox.getYMin(), boundingBox.getYMax() ); - _sourceU = max( boundingBox.getYMin() - cap, uside.getVMin()); - _targetU = min( boundingBox.getYMax() + cap, uside.getVMax()); - source = Point( track->getAxis(), boundingBox.getYMin() ); - target = Point( track->getAxis(), boundingBox.getYMax() ); - } - - if (track->getRoutingPlane()->getLayerGauge()->isUsable()) { - Flags gcellFlags = Flags::NoFlags; - GCellsUnder gcells = track->getKatanaEngine()->getGCellsUnder( source, target ); - for ( size_t i=0 ; isize() ; ++i ) { - GCell* gcell = gcells->gcellAt(i); - gcell->addBlockage - ( depth, gcell->getSide( track->getDirection() ).getIntersection( segside ).getSize() ); - gcell->flags() |= gcellFlags; - } - } - } - - - void TrackBlockage::_postCreate () - { TrackElement::_postCreate(); } - - - TrackBlockage::~TrackBlockage () - { } - - - void TrackBlockage::_preDestroy () - { - cdebug_log(155,0) << "TrackBlockage::_preDestroy() - " << (void*)this << endl; - TrackElement::_preDestroy(); - } - - - TrackElement* TrackBlockage::create ( Track* track, Box boundingBox ) - { - TrackBlockage* trackBlockage = NULL; - if (not track) - throw Error( "TrackBlockage::create(): NULL track argument." ); - - cdebug_log(159,0) << "TrackBlockage::create() track:" << track << endl; - trackBlockage = new TrackBlockage ( track, boundingBox ); - trackBlockage->_postCreate(); - cdebug_log(159,0) << "TrackBlockage::create(): " << trackBlockage << endl; - Session::addInsertEvent( trackBlockage, track, track->getAxis() ); - return trackBlockage; - } - - - AutoSegment* TrackBlockage::base () const { return NULL; } - Segment* TrackBlockage::getSegment () const { return NULL; } - DbU::Unit TrackBlockage::getAxis () const { return getTrack()->getAxis(); } - bool TrackBlockage::isHorizontal () const { return getTrack()->isHorizontal(); } - bool TrackBlockage::isVertical () const { return getTrack()->isVertical(); } - bool TrackBlockage::isFixed () const { return true; } - bool TrackBlockage::isPriorityLocked () const { return false; } - Flags TrackBlockage::getDirection () const { return getTrack()->getDirection(); } - DbU::Unit TrackBlockage::getWidth () const { return _boundingBox.getWidth(); } - const Layer* TrackBlockage::getLayer () const { return getTrack()->getLayer(); } - unsigned int TrackBlockage::getDepth () const { return Session::getLayerDepth(getLayer()); } - Interval TrackBlockage::getFreeInterval () const { return Interval(); } - size_t TrackBlockage::getTrackSpan () const { return 1; } - - - DbU::Unit TrackBlockage::getSourceAxis () const - { return (isHorizontal()) ? _boundingBox.getXMin() : _boundingBox.getYMin(); } - - - DbU::Unit TrackBlockage::getTargetAxis () const - { return (isHorizontal()) ? _boundingBox.getXMax() : _boundingBox.getYMax(); } - - - unsigned long TrackBlockage::getId () const - { - cerr << Error("::getId() called on %s.",_getString().c_str()) << endl; - return 0; - } - - - Net* TrackBlockage::getNet () const - { return Session::getBlockageNet(); } - - - TrackElement* TrackBlockage::getNext () const - { - size_t dummy = _track->find( this ); - return _track->getNext( dummy, getNet() ); - } - - - TrackElement* TrackBlockage::getPrevious () const - { - size_t dummy = _track->find( this ); - return _track->getPrevious( dummy, getNet() ); - } - - - void TrackBlockage::addOverlapCost ( TrackCost& cost ) const - { cost.getTrack()->addOverlapCost( cost ); } - - - float TrackBlockage::getPriority () const - { return 0.0; } - - - void TrackBlockage::setPriorityLock ( bool ) - { } - - - void TrackBlockage::forcePriority ( float ) - { } - - - void TrackBlockage::computePriority () - { } - - - void TrackBlockage::computeAlignedPriority () - { } - - - void TrackBlockage::detach ( TrackSet& removeds ) - { - // cerr << Error( "TrackBlockage::detach(): Must never be called on %s." - // , getString(this).c_str()) << endl; - } - - - string TrackBlockage::_getTypeName () const - { return "TrackBlockage"; } - - - string TrackBlockage::_getString () const - { - string s1 = string("getIndex()) + "] " - + getString(getLayer()->getName()) + " @" - + DbU::getValueString(getTrack()->getAxis()); - } else { - s1 += "[i] layer @axis"; - } - s1 += " [" + DbU::getValueString(_sourceU) - + ":" + DbU::getValueString(_targetU) + "]" - + " " + DbU::getValueString(_targetU-_sourceU) - + " FBN>"; - return s1; - } - - - Record* TrackBlockage::_getRecord () const - { - Record* record = TrackElement::_getRecord(); - record->add( getSlot( "_boundingBox", &_boundingBox ) ); - return record; - } - - -} // Katana namespace. diff --git a/katana/src/TrackElement.cpp b/katana/src/TrackElement.cpp index 3d51e7120..4e41e9165 100644 --- a/katana/src/TrackElement.cpp +++ b/katana/src/TrackElement.cpp @@ -143,6 +143,7 @@ namespace Katana { bool TrackElement::isStrongTerminal ( Flags ) const { return false; } bool TrackElement::isStrap () const { return false; } bool TrackElement::isUnbreakable () const { return false; } + bool TrackElement::isForOffgrid () const { return false; } bool TrackElement::isSlackened () const { return false; } bool TrackElement::isDogleg () const { return false; } bool TrackElement::isShortDogleg () const { return false; } diff --git a/katana/src/TrackFixedSpan.cpp b/katana/src/TrackFixedSpan.cpp new file mode 100644 index 000000000..244cd81c4 --- /dev/null +++ b/katana/src/TrackFixedSpan.cpp @@ -0,0 +1,251 @@ +// -*- 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@lip6.fr | +// | =============================================================== | +// | C++ Module : "./TrackFixedSpan.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include "hurricane/Bug.h" +#include "hurricane/Warning.h" +#include "hurricane/Net.h" +#include "hurricane/Name.h" +#include "hurricane/RegularLayer.h" +#include "hurricane/Technology.h" +#include "hurricane/DataBase.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "anabatic/AutoContact.h" +#include "crlcore/RoutingGauge.h" +#include "katana/DataNegociate.h" +#include "katana/TrackFixedSpan.h" +#include "katana/TrackCost.h" +#include "katana/Track.h" +#include "katana/RoutingPlane.h" +#include "katana/Session.h" +#include "katana/RoutingEvent.h" +#include "katana/NegociateWindow.h" +#include "katana/KatanaEngine.h" + + +namespace Katana { + + using namespace std; + using Hurricane::Warning; + using Hurricane::Bug; + using Hurricane::Error; + using Hurricane::Net; + using Hurricane::Name; + using Hurricane::RegularLayer; + using Hurricane::Technology; + using Hurricane::DataBase; + using Hurricane::Horizontal; + using Hurricane::Vertical; + using Anabatic::GCellsUnder; + + +// ------------------------------------------------------------------- +// Class : "TrackFixedSpan". + + + TrackFixedSpan::TrackFixedSpan ( Net* net, const Box& bb, Track* track ) + : TrackElement(NULL) + , _net (net) + , _boundingBox(bb) + { + uint32_t depth = track->getDepth(); + //Technology* technology = DataBase::getDB()->getTechnology(); + //const Layer* layer1 = track->getLayer()->getTerminalLayer(); + //RegularLayer* layer2 = dynamic_cast(technology->getLayer(layer1->getMask())); + //if (layer2) { + //cerr << track->getLayer() << " minSpace:" << DbU::getValueString(track->getLayer()->getMinimalSpacing()) << endl; + + Point source; + Point target; + Interval segside; + Interval uside = track->getKatanaEngine()->getUSide( track->getDirection() ); + DbU::Unit cap = track->getLayer()->getMinimalSpacing()/2 /*+ track->getLayer()->getExtentionCap()*/; + cdebug_log(159,0) << "uside:" << uside << " cap:" << DbU::getValueString(cap) << endl; + cdebug_log(159,0) << "bb:" << _boundingBox << endl; + if (track->getDirection() == Flags::Horizontal) { + segside = Interval( _boundingBox.getXMin(), _boundingBox.getXMax() ); + _sourceU = max( _boundingBox.getXMin() - cap, uside.getVMin()); + _targetU = min( _boundingBox.getXMax() + cap, uside.getVMax()); + source = Point( _boundingBox.getXMin(), track->getAxis() ); + target = Point( _boundingBox.getXMax(), track->getAxis() ); + } else { + segside = Interval( _boundingBox.getYMin(), _boundingBox.getYMax() ); + _sourceU = max( _boundingBox.getYMin() - cap, uside.getVMin()); + _targetU = min( _boundingBox.getYMax() + cap, uside.getVMax()); + source = Point( track->getAxis(), _boundingBox.getYMin() ); + target = Point( track->getAxis(), _boundingBox.getYMax() ); + } + + setFlags( TElemFixed|TElemForwardSetTrack ); + setTrack( track ); + + if (not net or (net == Session::getBlockageNet())) { + _net = Session::getBlockageNet(); + setFlags( TElemBlockage ); + if (track->getRoutingPlane()->getLayerGauge()->isUsable()) { + GCellsUnder gcells = track->getKatanaEngine()->getGCellsUnder( source, target ); + for ( size_t i=0 ; isize() ; ++i ) { + GCell* gcell = gcells->gcellAt(i); + gcell->addBlockage + ( depth, gcell->getSide( track->getDirection() ).getIntersection( segside ).getSize() ); + } + } + } + } + + + void TrackFixedSpan::_postCreate () + { TrackElement::_postCreate(); } + + + TrackFixedSpan::~TrackFixedSpan () + { } + + + void TrackFixedSpan::_preDestroy () + { + cdebug_log(155,0) << "TrackFixedSpan::_preDestroy() - " << (void*)this << endl; + TrackElement::_preDestroy(); + } + + + TrackFixedSpan* TrackFixedSpan::create ( Net* net, const Box& bb, Track* track ) + { + TrackFixedSpan* trackTerminal = nullptr; + if (not track) + throw Error( "TrackFixedSpan::create(): NULL track argument." ); + + cdebug_log(159,0) << "TrackFixedSpan::create() track:" << track << endl; + trackTerminal = new TrackFixedSpan ( net, bb, track ); + trackTerminal->_postCreate(); + cdebug_log(159,0) << trackTerminal << endl; + Session::addInsertEvent( trackTerminal, track, track->getAxis() ); + return trackTerminal; + } + + + AutoSegment* TrackFixedSpan::base () const { return nullptr; } + Segment* TrackFixedSpan::getSegment () const { return nullptr; } + DbU::Unit TrackFixedSpan::getAxis () const { return getTrack()->getAxis(); } + bool TrackFixedSpan::isHorizontal () const { return getTrack()->isHorizontal(); } + bool TrackFixedSpan::isVertical () const { return getTrack()->isVertical(); } + bool TrackFixedSpan::isFixed () const { return true; } + bool TrackFixedSpan::isPriorityLocked () const { return false; } + Net* TrackFixedSpan::getNet () const { return _net; } + Flags TrackFixedSpan::getDirection () const { return getTrack()->getDirection(); } + DbU::Unit TrackFixedSpan::getWidth () const { return _boundingBox.getWidth(); } + const Layer* TrackFixedSpan::getLayer () const { return getTrack()->getLayer(); } + unsigned int TrackFixedSpan::getDepth () const { return Session::getLayerDepth(getLayer()); } + Interval TrackFixedSpan::getFreeInterval () const { return Interval(); } + size_t TrackFixedSpan::getTrackSpan () const { return 1; } + + + DbU::Unit TrackFixedSpan::getSourceAxis () const + { return (isHorizontal()) ? _boundingBox.getXMin() : _boundingBox.getYMin(); } + + + DbU::Unit TrackFixedSpan::getTargetAxis () const + { return (isHorizontal()) ? _boundingBox.getXMax() : _boundingBox.getYMax(); } + + + unsigned long TrackFixedSpan::getId () const + { + cerr << Error("TrackFixedSpan::getId() called on %s.",_getString().c_str()) << endl; + return 0; + } + + + TrackElement* TrackFixedSpan::getNext () const + { + size_t dummy = _track->find( this ); + return _track->getNext( dummy, getNet() ); + } + + + TrackElement* TrackFixedSpan::getPrevious () const + { + size_t dummy = _track->find( this ); + return _track->getPrevious( dummy, getNet() ); + } + + + void TrackFixedSpan::addOverlapCost ( TrackCost& cost ) const + { cost.getTrack()->addOverlapCost( cost ); } + + + float TrackFixedSpan::getPriority () const + { return 0.0; } + + + void TrackFixedSpan::setPriorityLock ( bool ) + { } + + + void TrackFixedSpan::forcePriority ( float ) + { } + + + void TrackFixedSpan::computePriority () + { } + + + void TrackFixedSpan::computeAlignedPriority () + { } + + + void TrackFixedSpan::detach ( TrackSet& removeds ) + { + // cerr << Error( "TrackFixedSpan::detach(): Must never be called on %s." + // , getString(this).c_str()) << endl; + } + + + string TrackFixedSpan::_getTypeName () const + { return "TrackFixedSpan"; } + + + string TrackFixedSpan::_getString () const + { + string s1 = string("getName()) : "net") + "\" "; + if (getTrack()) { + s1 += "[" + getString(getTrack()->getIndex()) + "] " + + getString(getLayer()->getName()) + " @" + + DbU::getValueString(getTrack()->getAxis()); + } else { + s1 += "[i] layer @axis"; + } + s1 += " [" + DbU::getValueString(_sourceU) + + ":" + DbU::getValueString(_targetU) + "]" + + " " + DbU::getValueString(_targetU-_sourceU) + + " F"; + s1 += (isBlockage() ? "B" : "-"); + s1 += "N>"; + return s1; + } + + + Record* TrackFixedSpan::_getRecord () const + { + Record* record = TrackElement::_getRecord(); + record->add( getSlot( "_net", _net ) ); + record->add( getSlot( "_boundingBox", &_boundingBox ) ); + return record; + } + + +} // Katana namespace. diff --git a/katana/src/TrackSegment.cpp b/katana/src/TrackSegment.cpp index 23870a200..89f29d503 100644 --- a/katana/src/TrackSegment.cpp +++ b/katana/src/TrackSegment.cpp @@ -180,6 +180,7 @@ namespace Katana { bool TrackSegment::isGlobal () const { return _base->isWeakGlobal() or _base->isGlobal(); } bool TrackSegment::isWeakGlobal () const { return _base->isWeakGlobal(); } bool TrackSegment::isUnbreakable () const { return _base->isUnbreakable() and not _base->isWeakGlobal(); } + bool TrackSegment::isForOffgrid () const { return _base->isForOffgrid(); } bool TrackSegment::isBipoint () const { return _base->isBipoint(); } bool TrackSegment::isTerminal () const { return _base->isTerminal(); } bool TrackSegment::isDrag () const { return _base->isDrag(); } diff --git a/katana/src/katana/TrackBlockage.h b/katana/src/katana/TrackBlockage.h deleted file mode 100644 index 3246b3279..000000000 --- a/katana/src/katana/TrackBlockage.h +++ /dev/null @@ -1,87 +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 | -// | 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++ Header : "./katana/TrackBlockage.h" | -// +-----------------------------------------------------------------+ - - -#pragma once -#include "katana/TrackElement.h" - - -namespace Katana { - - using std::string; - using std::map; - using Hurricane::Record; - using Hurricane::Interval; - using Hurricane::DbU; - using Hurricane::Net; - using Hurricane::Layer; - - class Track; - - -// ------------------------------------------------------------------- -// Class : "TrackBlockage". - - class TrackBlockage : public TrackElement { - public: - static TrackElement* create ( Katana::Track*, Box ); - public: - virtual AutoSegment* base () const; - virtual Segment* getSegment () const; - virtual bool isHorizontal () const; - virtual bool isVertical () const; - virtual bool isFixed () const; - virtual bool isPriorityLocked () const; - virtual unsigned long getId () const; - virtual Flags getDirection () const; - virtual Net* getNet () const; - virtual DbU::Unit getWidth () const; - virtual unsigned int getDepth () const; - virtual const Layer* getLayer () const; - virtual size_t getTrackSpan () const; - virtual TrackElement* getNext () const; - virtual TrackElement* getPrevious () const; - virtual DbU::Unit getAxis () const; - inline DbU::Unit getSourceAxis () const; - virtual DbU::Unit getTargetAxis () const; - virtual Interval getFreeInterval () const; - virtual void addOverlapCost ( TrackCost& ) const; - virtual float getPriority () const; - virtual void setPriorityLock ( bool ); - virtual void forcePriority ( float ); - virtual void computePriority (); - virtual void computeAlignedPriority (); - virtual void detach ( TrackSet& ); - virtual Record* _getRecord () const; - virtual string _getString () const; - virtual string _getTypeName () const; - private: - Box _boundingBox; - protected: - // Constructors & Destructors. - TrackBlockage ( Track*, Box ) ; - virtual ~TrackBlockage (); - virtual void _postCreate (); - virtual void _preDestroy (); - private: - TrackBlockage ( const TrackBlockage& ) = delete; - TrackBlockage& operator= ( const TrackBlockage& ) = delete; - }; - - -} // Katana namespace. - - -INSPECTOR_P_SUPPORT(Katana::TrackBlockage); diff --git a/katana/src/katana/TrackElement.h b/katana/src/katana/TrackElement.h index cfd8e5343..1aabb1364 100644 --- a/katana/src/katana/TrackElement.h +++ b/katana/src/katana/TrackElement.h @@ -116,6 +116,7 @@ namespace Katana { virtual bool isTerminal () const; virtual bool isDrag () const; virtual bool isStrongTerminal ( Flags flags=Flags::NoFlags ) const; + virtual bool isForOffgrid () const; virtual bool isStrap () const; virtual bool isSlackened () const; virtual bool isDogleg () const; diff --git a/katana/src/katana/TrackFixedSpan.h b/katana/src/katana/TrackFixedSpan.h new file mode 100644 index 000000000..b36c272b7 --- /dev/null +++ b/katana/src/katana/TrackFixedSpan.h @@ -0,0 +1,101 @@ +// -*- 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++ Header : "./katana/TrackFixedSpan.h" | +// +-----------------------------------------------------------------+ + + +#pragma once +#include "katana/TrackElement.h" + + +namespace Katana { + + using std::string; + using std::map; + using Hurricane::Record; + using Hurricane::Interval; + using Hurricane::DbU; + using Hurricane::Net; + using Hurricane::Layer; + + class Track; + + +// ------------------------------------------------------------------- +// Class : "TrackFixedSpan". + + class TrackFixedSpan : public TrackElement { + public: + static TrackFixedSpan* create ( Net*, const Box&, Track* ); + public: + virtual AutoSegment* base () const; + virtual Segment* getSegment () const; + virtual bool isHorizontal () const; + virtual bool isVertical () const; + virtual bool isFixed () const; + virtual bool isPriorityLocked () const; + virtual unsigned long getId () const; + virtual Net* getNet () const; + virtual Flags getDirection () const; + virtual DbU::Unit getWidth () const; + virtual unsigned int getDepth () const; + virtual const Layer* getLayer () const; + virtual size_t getTrackSpan () const; + virtual TrackElement* getNext () const; + virtual TrackElement* getPrevious () const; + virtual DbU::Unit getAxis () const; + inline DbU::Unit getSourceAxis () const; + virtual DbU::Unit getTargetAxis () const; + virtual Interval getFreeInterval () const; + virtual void addOverlapCost ( TrackCost& ) const; + virtual float getPriority () const; + virtual void setPriorityLock ( bool ); + virtual void forcePriority ( float ); + virtual void computePriority (); + virtual void computeAlignedPriority (); + inline void setNet ( Net* ); + virtual void detach ( TrackSet& ); + virtual Record* _getRecord () const; + virtual string _getString () const; + virtual string _getTypeName () const; + private: + Net* _net; + Box _boundingBox; + protected: + // Constructors & Destructors. + TrackFixedSpan ( Net*, const Box&, Track* ) ; + virtual ~TrackFixedSpan (); + virtual void _postCreate (); + virtual void _preDestroy (); + private: + TrackFixedSpan ( const TrackFixedSpan& ) = delete; + TrackFixedSpan& operator= ( const TrackFixedSpan& ) = delete; + }; + + + inline void TrackFixedSpan::setNet ( Net* net ) + { + if (not net or (net == Session::getBlockageNet())) { + _net = Session::getBlockageNet(); + setFlags( TElemBlockage ); + } else { + _net = net; + unsetFlags( TElemBlockage ); + } + } + + +} // Katana namespace. + + +INSPECTOR_P_SUPPORT(Katana::TrackFixedSpan); diff --git a/katana/src/katana/TrackSegment.h b/katana/src/katana/TrackSegment.h index 79f4d36af..8a3a1c847 100644 --- a/katana/src/katana/TrackSegment.h +++ b/katana/src/katana/TrackSegment.h @@ -73,6 +73,7 @@ namespace Katana { virtual bool isStrongTerminal ( Flags flags=Flags::NoFlags ) const; virtual bool isStrap () const; virtual bool isUnbreakable () const; + virtual bool isForOffgrid () const; virtual bool isSlackened () const; virtual bool isDogleg () const; virtual bool isShortDogleg () const; diff --git a/katana/src/meson.build b/katana/src/meson.build index f0bed8e56..1dca979c0 100644 --- a/katana/src/meson.build +++ b/katana/src/meson.build @@ -21,7 +21,6 @@ katana = shared_library( 'Block.cpp', 'DataNegociate.cpp', 'DataSymmetric.cpp', - 'TrackBlockage.cpp', 'TrackCost.cpp', 'TrackElement.cpp', 'TrackElements.cpp', @@ -30,6 +29,7 @@ katana = shared_library( 'TrackSegmentNonPref.cpp', 'TrackSegmentWide.cpp', 'TrackFixedSegment.cpp', + 'TrackFixedSpan.cpp', 'TrackMarker.cpp', 'Track.cpp', 'Tracks.cpp', From 6d37f7c6a2ae26607286ef883983079ae7ec85f6 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 10 Jan 2024 17:22:27 +0100 Subject: [PATCH 35/51] Support for offgrid M1 & VH topologies (WIP 3). * In AutoContact, add a flag to tag metal-only contact (for offgrid segments on metal1 mostly. * In DataNegociate::update(), when computing perpandicular constraints, when processing a non-pref, if S/T is metal-only, add a one pitch slack. * In PowerPlanes, when decomposing Rectilinear, do it *perpandicular* to the preferred routing direction. If it's horizontal, then slice vertically. * In protectRoutingpads(), full rework on how the track fixed span intervals are computeds. Must give a set of non-overlaping ones. So if they are changed into blockages they won't generate overlaps in tracks. * In Track, beginning of support for partial reorder (may give some speed-up in the end). --- anabatic/src/AutoContactTerminal.cpp | 2 + anabatic/src/anabatic/AutoContact.h | 3 + katana/src/DataNegociate.cpp | 10 +- katana/src/PowerRails.cpp | 2 +- katana/src/ProtectRoutingPads.cpp | 232 +++++++++++++++++---------- katana/src/SegmentFsm.cpp | 1 + katana/src/Track.cpp | 26 +++ katana/src/katana/Track.h | 10 ++ 8 files changed, 199 insertions(+), 87 deletions(-) diff --git a/anabatic/src/AutoContactTerminal.cpp b/anabatic/src/AutoContactTerminal.cpp index 3ef2c45fa..f1a05932b 100644 --- a/anabatic/src/AutoContactTerminal.cpp +++ b/anabatic/src/AutoContactTerminal.cpp @@ -464,6 +464,8 @@ namespace Anabatic { ostringstream message; if (not hasBadTopology()) { + if (getAnchor()->getLayer() == getLayer()) setFlags ( CntMetalOnly ); + else unsetFlags( CntMetalOnly ); Box anchorBb = getAnchor()->getBoundingBox(); anchorBb.inflate( Session::getViaWidth (getAnchor()->getLayer()) - Session::getWireWidth(getAnchor()->getLayer()) ); diff --git a/anabatic/src/anabatic/AutoContact.h b/anabatic/src/anabatic/AutoContact.h index 175feb712..62a9bee69 100644 --- a/anabatic/src/anabatic/AutoContact.h +++ b/anabatic/src/anabatic/AutoContact.h @@ -73,6 +73,7 @@ namespace Anabatic { , CntDrag = (1 << 16) , CntHDogleg = (1 << 17) , CntVDogleg = (1 << 18) + , CntMetalOnly = (1 << 19) }; class AutoContact { @@ -123,6 +124,7 @@ namespace Anabatic { inline bool isUserNativeConstraints () const; inline bool isHDogleg () const; inline bool isVDogleg () const; + inline bool isMetalOnly () const; virtual bool isOnPin () const; inline bool hasBadTopology () const; bool canDestroy ( Flags flags=Flags::NoFlags ) const; @@ -267,6 +269,7 @@ namespace Anabatic { inline bool AutoContact::isVTee () const { return _flags&CntVTee; } inline bool AutoContact::isHDogleg () const { return _flags&CntHDogleg; } inline bool AutoContact::isVDogleg () const { return _flags&CntVDogleg; } + inline bool AutoContact::isMetalOnly () const { return _flags&CntMetalOnly; } inline bool AutoContact::hasBadTopology () const { return _flags&CntBadTopology; } inline bool AutoContact::canDrag () const { return _flags&CntDrag; } inline size_t AutoContact::getId () const { return _id; } diff --git a/katana/src/DataNegociate.cpp b/katana/src/DataNegociate.cpp index 1121355e8..fb9d10a82 100644 --- a/katana/src/DataNegociate.cpp +++ b/katana/src/DataNegociate.cpp @@ -160,17 +160,19 @@ namespace Katana { Interval trackFree ( false ); if (source->canDrag()) { + DbU::Unit slack = (source->isMetalOnly()) ? pitch : 0; if (direction & Flags::Horizontal) - trackFree.intersection( source->getCBYMin(), source->getCBYMax() ); + trackFree.intersection( source->getCBYMin()-slack, source->getCBYMax()+slack ); else - trackFree.intersection( source->getCBXMin(), source->getCBXMax() ); + trackFree.intersection( source->getCBXMin()-slack, source->getCBXMax()+slack ); cdebug_log(159,0) << "trackFree (source drag): " << trackFree << endl; } if (target->canDrag()) { + DbU::Unit slack = (target->isMetalOnly()) ? pitch : 0; if (direction & Flags::Horizontal) - trackFree.intersection( target->getCBYMin(), target->getCBYMax() ); + trackFree.intersection( target->getCBYMin()-slack, target->getCBYMax()+slack ); else - trackFree.intersection( target->getCBXMin(), target->getCBXMax() ); + trackFree.intersection( target->getCBXMin()-slack, target->getCBXMax()+slack ); cdebug_log(159,0) << "trackFree (target drag): " << trackFree << endl; } diff --git a/katana/src/PowerRails.cpp b/katana/src/PowerRails.cpp index ef2e2d3e1..a7722f831 100644 --- a/katana/src/PowerRails.cpp +++ b/katana/src/PowerRails.cpp @@ -1108,7 +1108,7 @@ namespace { if (not _powerRailsPlanes.getActivePlane()->getLayer()->isBlockage()) { _goMatchCount++; vector boxes; - rectilinear->getAsRectangles( boxes, Rectilinear::HSliced ); + rectilinear->getAsRectangles( boxes, Rectilinear::VSliced ); for ( Box bb : boxes ) { transformation.applyOn( bb ); cdebug_log(159,0) << " Merging PowerRail element: " << rectilinear << " bb:" << bb diff --git a/katana/src/ProtectRoutingPads.cpp b/katana/src/ProtectRoutingPads.cpp index 4798b671d..f78268e7e 100644 --- a/katana/src/ProtectRoutingPads.cpp +++ b/katana/src/ProtectRoutingPads.cpp @@ -24,6 +24,7 @@ #include "hurricane/RegularLayer.h" #include "hurricane/Horizontal.h" #include "hurricane/Vertical.h" +#include "hurricane/Rectilinear.h" #include "hurricane/RoutingPad.h" #include "hurricane/Occurrence.h" #include "hurricane/Cell.h" @@ -58,6 +59,7 @@ namespace { using Hurricane::RegularLayer; using Hurricane::Horizontal; using Hurricane::Vertical; + using Hurricane::Rectilinear; using Hurricane::Plug; using Hurricane::Transformation; using Hurricane::RoutingPad; @@ -72,6 +74,29 @@ namespace { using namespace Katana; + class CompareIntervalByVMin { + public: + inline bool operator () ( const Interval& lhs, const Interval& rhs ) const + { + if (lhs.getVMin() < rhs.getVMin()) + return true; + else { + if ( (lhs.getVMin() == rhs.getVMin()) + and (lhs.getVMax() > rhs.getVMax()) ) + return true; + } + return false; + } + }; + + + class CompareTrackByAxis { + public: + inline bool operator () ( const Track* lhs, const Track* rhs ) const + { return lhs->getAxis() < rhs->getAxis(); } + }; + + void protectRoutingPad ( RoutingPad* rp, Flags flags ) { cdebug_log(145,1) << "::protectRoutingPad() " << rp << endl; @@ -110,114 +135,157 @@ namespace { } } - vector segments; - - for ( Segment* segment : masterNet->getSegments() ) { - RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(segment->getLayer()); + vector< pair > bbs; + for ( Component* component : masterNet->getComponents() ) { + const Layer* layer = component->getLayer(); + RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer( layer ); if (not plane) continue; - if (usedComponent == dynamic_cast(segment) - and not (flags & Flags::ProtectSelf)) continue; - if (not NetExternalComponents::isExternal(segment)) continue; + Segment* segment = dynamic_cast( component ); + if (segment) { + Box bb = segment->getBoundingBox(); + transformation.applyOn( bb ); + bbs.push_back( make_pair( bb, layer )); + cdebug_log(145,0) << "@ " << segment << " bb:" << bb << endl; + continue; + } - segments.push_back( segment ); + Rectilinear* rectilinear = dynamic_cast( component ); + if (rectilinear) { + cdebug_log(145,0) << "@ " << rectilinear << endl; + vector rbbs; + rectilinear->getAsRectangles( rbbs, (plane->isVertical() ? Rectilinear::HSliced + : Rectilinear::VSliced )); + for ( Box& bb : rbbs ) { + transformation.applyOn( bb ); + bbs.push_back( make_pair( bb, layer )); + cdebug_log(145,0) << "| bb:" << bb << endl; + } + continue; + } } - for ( size_t i=0 ; igetRoutingPlaneByLayer(segments[i]->getLayer()); + map, CompareTrackByAxis > intervalsByTracks; + for ( auto item : bbs ) { + RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer( item.second ); Flags direction = plane->getDirection(); DbU::Unit wireWidth = plane->getLayerGauge()->getWireWidth(); DbU::Unit delta = plane->getLayerGauge()->getPitch() - wireWidth/2 - DbU::fromLambda(0.1); DbU::Unit cap = plane->getLayer()->getMinimalSpacing() / 2; - DbU::Unit extension = segments[i]->getLayer()->getExtentionCap(); - Box bb ( segments[i]->getBoundingBox() ); + DbU::Unit extension = item.second->getExtentionCap(); + Box bb ( item.first ); - transformation.applyOn ( bb ); - - cdebug_log(145,0) << "@ " << segments[i] << " bb:" << bb << endl; + cdebug_log(145,0) << "@ bb:" << bb << endl; cdebug_log(145,0) << "delta=" << DbU::getValueString(delta) << endl; - cdebug_log(145,0) << "cap=" << DbU::getValueString(cap) << endl; + cdebug_log(145,0) << "cap=" << DbU::getValueString(cap) << endl; - if ( direction == Flags::Horizontal ) { + if (direction == Flags::Horizontal) { DbU::Unit axisMin = bb.getYMin() - delta; DbU::Unit axisMax = bb.getYMax() + delta; - Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior ); + Track* track = plane->getTrackByPosition( axisMin, Constant::Superior ); for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNextTrack() ) { cdebug_log(145,0) << "> track " << track << endl; - // Horizontal* segment = Horizontal::create ( net - // , segments[i]->getLayer() - // , track->getAxis() - // , wireWidth - // , bb.getXMin()+extension - // , bb.getXMax()-extension - // ); - // TrackFixedSegment::create ( track, segment ); - // cdebug_log(145,0) << "| " << segment << endl; - Interval termSpan = Interval( bb.getXMin(), bb.getXMax() ).inflate( cap ); - Interval freeSpan = track->getFreeInterval( bb.getXCenter() ); - cdebug_log(145,0) << "| termSpan " << termSpan << endl; - cdebug_log(145,0) << "| freeSpan " << freeSpan << endl; - bool overlap = false; - bool conflict = false; - if (not freeSpan.contains(termSpan)) { - overlap = true; - size_t ovBegin = 0; - size_t ovEnd = 0; - track->getOverlapBounds( termSpan, ovBegin, ovEnd ); - for ( ; ovBegin <= ovEnd ; ++ovBegin ) { - TrackElement* overlaped = track->getSegment( ovBegin ); - TrackFixedSpan* fixedSpan = dynamic_cast( overlaped ); - if (fixedSpan) { - if (not fixedSpan->isBlockage()) - fixedSpan->setNet( nullptr ); - } else - conflict = true; - } - } - if (not conflict) { - TrackFixedSpan* element = TrackFixedSpan::create( ((overlap) ? nullptr : net), bb, track ); - cdebug_log(145,0) << "| " << element << endl; - } + intervalsByTracks[ track ].push_back( Interval( bb.getXMin(), bb.getXMax() )); } } else { DbU::Unit axisMin = bb.getXMin() - delta; DbU::Unit axisMax = bb.getXMax() + delta; - Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior ); + Track* track = plane->getTrackByPosition( axisMin, Constant::Superior ); for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNextTrack() ) { - // Vertical* segment = Vertical::create ( net - // , segments[i]->getLayer() - // , track->getAxis() - // , wireWidth - // , bb.getYMin()+extension - // , bb.getYMax()-extension - // ); - // TrackFixedSegment::create ( track, segment ); - // cdebug_log(145,0) << "| " << segment << endl; - Interval termSpan = Interval( bb.getYMin(), bb.getYMax() ); - Interval freeSpan = track->getFreeInterval( bb.getYCenter() ); - bool overlap = false; - bool conflict = false; - if (not freeSpan.contains(termSpan)) { - TrackElement* overlaped = track->getSegment( bb.getXCenter() ); - if (overlaped) { - overlap = true; - TrackFixedSpan* fixedSpan = dynamic_cast( overlaped ); - if (fixedSpan) { - if (not fixedSpan->isBlockage()) - fixedSpan->setNet( nullptr ); - } else - conflict = true; - } + cdebug_log(145,0) << "> track " << track << endl; + intervalsByTracks[ track ].push_back( Interval( bb.getYMin(), bb.getYMax() ) ); + } + } + } + + for ( auto item : intervalsByTracks ) { + Track*& track = const_cast( item.first ); + vector& intervals = item.second; + DbU::Unit cap = track->getLayer()->getMinimalSpacing() / 2; + DbU::Unit halfWidth = track->getLayer()->getMinimalSize () / 2; + cdebug_log(145,0) << "> track " << track << endl; + + sort( intervals.begin(), intervals.end(), CompareIntervalByVMin() ); + Interval fullSpan = intervals[0]; + cdebug_log(145,0) << "| fullSpan " << fullSpan << endl; + for ( size_t i=1 ; i < intervals.size() ; ) { + if (fullSpan.contains(intervals[i])) { + cdebug_log(145,0) << "| contained " << intervals[i] << endl; + intervals.erase( intervals.begin() + i ); + continue; + } + if (fullSpan.intersect(intervals[i])) { + cdebug_log(145,0) << "| intersect " << intervals[i] << endl; + fullSpan.merge( intervals[i].getVMax() ); + cdebug_log(145,0) << "| fullSpan " << fullSpan << endl; + if ( (intervals[i ].getSize() < 2*cap) + or (intervals[i-1].getSize() < 2*cap)) { + cdebug_log(145,0) << "| too narrow, merge " << endl; + intervals[i-1].merge( fullSpan.getVMax() ); + intervals.erase( intervals.begin() + i ); + continue; } - if (not conflict) { - TrackFixedSpan* element = TrackFixedSpan::create( ((overlap) ? nullptr : net), bb, track ); - cdebug_log(145,0) << "| " << element << endl; + cdebug_log(145,0) << "| separate" << endl; + intervals[i-1] = Interval( intervals[i-1].getVMin() , intervals[i].getVMin() - cap ); + intervals[i ] = Interval( intervals[i ].getVMin() + cap, intervals[i].getVMax() ); + ++i; + continue; + } + if (fullSpan.getVMax() > intervals[i-1].getVMax()) { + cdebug_log(145,0) << "| expand last" << endl; + intervals[i-1].merge( fullSpan.getVMax()); + } + + fullSpan = intervals[i]; + ++i; + } + + cdebug_log(145,0) << "Cleaned up on " << track << endl; + for ( size_t i=0 ; igetFreeInterval( intervals[i].getCenter() ); + cdebug_log(145,0) << "| termSpan " << termSpan << endl; + cdebug_log(145,0) << "| freeSpan " << freeSpan << endl; + bool overlap = false; + bool conflict = false; + if (freeSpan.isEmpty() or not freeSpan.contains(termSpan)) { + overlap = true; + size_t ovBegin = 0; + size_t ovEnd = 0; + track->getOverlapBounds( termSpan, ovBegin, ovEnd ); + for ( ; ovBegin <= ovEnd ; ++ovBegin ) { + TrackElement* overlaped = track->getSegment( ovBegin ); + TrackFixedSpan* fixedSpan = dynamic_cast( overlaped ); + if (fixedSpan) { + if (not fixedSpan->isBlockage()) + fixedSpan->setNet( nullptr ); + } else + conflict = true; } } + cdebug_log(145,0) << "| overlap =" << overlap << endl; + cdebug_log(145,0) << "| conflict=" << conflict << endl; + if (not conflict) { + Box bb; + if (track->isHorizontal()) + bb = Box( intervals[i].getVMin(), track->getAxis()-halfWidth + , intervals[i].getVMax(), track->getAxis()+halfWidth ); + else + bb = Box( track->getAxis()-halfWidth, intervals[i].getVMin() + , track->getAxis()+halfWidth, intervals[i].getVMax() ); + TrackFixedSpan* element = TrackFixedSpan::create( ((overlap) ? nullptr : net), bb, track ); + cdebug_log(145,0) << "| " << element << endl; + } + } } Session::revalidate(); @@ -246,7 +314,7 @@ namespace Katana { for ( Net* net : getCell()->getNets() ) { if (net->isSupply()) continue; - DebugSession::open( net, 145, 150 ); + //DebugSession::open( net, 145, 150 ); cdebug_log(145,0) << "Protect RoutingPads of " << net << endl; NetData* data = getNetData( net ); @@ -259,7 +327,7 @@ namespace Katana { for ( size_t i=0 ; i No candidate track found." << endl; _state = EmptyTrackList; } diff --git a/katana/src/Track.cpp b/katana/src/Track.cpp index 4d7de6258..5b7cfb2c7 100644 --- a/katana/src/Track.cpp +++ b/katana/src/Track.cpp @@ -288,6 +288,8 @@ namespace Katana { , _localAssigned(false) , _segmentsValid(false) , _markersValid (false) + , _minInvalid (routingPlane->getTrackMin()) + , _maxInvalid (routingPlane->getTrackMax()) { } @@ -787,6 +789,7 @@ namespace Katana { cdebug_log(159,0) << "Insert in [" << 0 << "] " << this << segment << endl; _segments.push_back( segment ); _segmentsValid = false; + updateInvalidBounds( segment ); if (segment->isWide() or segment->isNonPref()) { cdebug_log(155,0) << "Segment is wide or non-pref, trackSpan:" << segment->getTrackSpan() << endl; @@ -795,6 +798,7 @@ namespace Katana { cdebug_log(159,0) << "Insert in [" << i << "] " << wtrack << segment << endl; wtrack->_segments.push_back ( segment ); wtrack->_segmentsValid = false; + wtrack->updateInvalidBounds( segment ); wtrack = wtrack->getNextTrack(); } } @@ -1040,6 +1044,28 @@ namespace Katana { std::sort( _segments.begin(), _segments.end(), SegmentCompare() ); _segmentsValid = true; } + // Net* blockageNet = Session::getBlockageNet(); + // uint32_t state = 0; + // size_t i = 0; + // getBeginIndex( _minInvalid+1, i, state ); + // for ( ; (i+1<_segments.size()) and (_segments[i+1]->getSourceU() < _maxInvalid) ; ++i ) { + // TrackFixedSpan* first = dynamic_cast( _segments[i ] ); + // TrackFixedSpan* second = dynamic_cast( _segments[i+1] ); + // if (not first or not second) continue; + // if ( (first->getTargetU() > second->getSourceU()) + // and (first->getNet() != second->getNet() )) { + // if (first->getTargetU() >= second->getTargetU()) { + // // End of second is fully enclosed in first. + // // Shrink first, set second as blockage. + // } else { + // // End of second sticks out of first. + // // Changes boudaries so they no longer overlap. + // } + // } + // } + + _minInvalid = _routingPlane->getTrackMin(); + _maxInvalid = _routingPlane->getTrackMax(); if (not _markersValid) { std::sort( _markers.begin(), _markers.end(), TrackMarker::Compare() ); diff --git a/katana/src/katana/Track.h b/katana/src/katana/Track.h index d504d62af..f49440fac 100644 --- a/katana/src/katana/Track.h +++ b/katana/src/katana/Track.h @@ -111,6 +111,7 @@ namespace Katana { void invalidate (); void insert ( TrackElement* ); void insert ( TrackMarker* ); + inline void updateInvalidBounds ( TrackElement* ); void setSegment ( TrackElement*, size_t ); size_t doRemoval (); void doReorder (); @@ -130,6 +131,8 @@ namespace Katana { bool _localAssigned; bool _segmentsValid; bool _markersValid; + DbU::Unit _minInvalid; + DbU::Unit _maxInvalid; protected: // Constructors & Destructors. @@ -220,6 +223,13 @@ namespace Katana { } + inline void Track::updateInvalidBounds ( TrackElement* element ) + { + _minInvalid = std::min( _minInvalid, element->getSourceU() ); + _maxInvalid = std::max( _maxInvalid, element->getTargetU() ); + } + + inline bool Track::Compare::operator() ( const Track* lhs, const Track* rhs ) const { if (lhs->isHorizontal() xor rhs->isHorizontal()) return lhs->isHorizontal(); From 9f675e8d3b8f357b731e7e8d910810363d5cf998 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 10 Jan 2024 17:23:13 +0100 Subject: [PATCH 36/51] Ignore Emacs backup files. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0be67268a..ed9a4ff53 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ *.pyc *.log *.bak +.#* TAGS GTAGS From 72a4e8038999c25607fb6dbf8662f6bfab2cadfe Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 10 Jan 2024 17:25:03 +0100 Subject: [PATCH 37/51] Fix in oroshi.Stack, PMOS must be in nWell (not pWell). --- oroshi/python/stack.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oroshi/python/stack.py b/oroshi/python/stack.py index 1f83a72b6..607194c2c 100644 --- a/oroshi/python/stack.py +++ b/oroshi/python/stack.py @@ -602,7 +602,7 @@ def __init__ ( self, device, NERC, NIRC ): else: self.tImplantLayer = rules.getRealLayer( 'pImplant' ) self.bImplantLayer = rules.getRealLayer( 'nImplant' ) - self.wellLayer = rules.getRealLayer( 'pWell' ) + self.wellLayer = rules.getRealLayer( 'nWell' ) return From 508e5722d353338a6bd0cfbe61745de0b6a74a8f Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 10 Jan 2024 17:29:09 +0100 Subject: [PATCH 38/51] Seems that when doc only is acivated, we no longer could compile. --- Makefile.LIP6 | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/Makefile.LIP6 b/Makefile.LIP6 index c483d09c8..f93b15498 100644 --- a/Makefile.LIP6 +++ b/Makefile.LIP6 @@ -63,15 +63,19 @@ $(CORIOLIS_SRC)/.pdm-plugins/bin/pdm: $(HOME)/.local/bin/pdm @$(localpath) pdm install --no-self -d --plugins +wipe: + @$(localpath) pdm run meson setup ${BUILDDIR} --wipe -Dpython.install_env=prefix -Donly-docs=false + + setup: - @$(localpath) pdm run meson setup ${BUILDDIR} --prefix=$(PREFIX) -Dpython.install_env=prefix + @$(localpath) pdm run meson setup ${BUILDDIR} --prefix=$(PREFIX) -Dpython.install_env=prefix -Donly-docs=false configure: @$(localpath) pdm run meson configure ${BUILDDIR} --prefix=$(PREFIX) -Dpython.install_env=prefix -install: check_dir $(CORIOLIS_SRC)/.pdm-plugins/bin/pdm setup +install: check_dir $(CORIOLIS_SRC)/.pdm-plugins/bin/pdm setup configure @$(localpath) pdm run meson install -C $(BUILDDIR) @echo ""; \ echo "============================================================================"; \ @@ -84,7 +88,6 @@ install: check_dir $(CORIOLIS_SRC)/.pdm-plugins/bin/pdm setup install_docs: check_dir $(CORIOLIS_SRC)/.pdm-plugins/bin/pdm configure @$(localpath) pdm run meson configure ${BUILDDIR} --prefix=$(PREFIX) \ - -Donly-docs=true \ -Ddocs=true @$(localpath) pdm run meson install -C $(BUILDDIR) @@ -96,10 +99,10 @@ install_alliance: sed -i 's,dirs="\\$$newdirs documentation",dirs="$$newdirs",' ./autostuff; \ ./autostuff clean; \ ./autostuff; \ - mkdir -p $(BUILDDIR); \ + mkdir -p $(BUILDDIR); \ cd $(BUILDDIR); \ $(ALLIANCE_SRC)/configure --prefix=$(PREFIX) --enable-alc-shared; \ - make -j1 install + make -j1 install clean_build: check_dir From a8eff158e7906fb3ea543a8cacec8337d5974b95 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 10 Jan 2024 23:19:12 +0100 Subject: [PATCH 39/51] Fixes in protectRoutingPads(). * Restrict the RoutingPad boxes to the cell abutment box. * Check that there are overlaping bounds returned by Tracks::getOverlapBounds(). * Pass the current net to Track::getFreeInterval(), so it is not considered a blockage... --- katana/src/ProtectRoutingPads.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/katana/src/ProtectRoutingPads.cpp b/katana/src/ProtectRoutingPads.cpp index f78268e7e..2bf508cf9 100644 --- a/katana/src/ProtectRoutingPads.cpp +++ b/katana/src/ProtectRoutingPads.cpp @@ -107,6 +107,7 @@ namespace { Net* net = rp->getNet(); Net* masterNet = usedComponent->getNet(); Transformation transformation = path.getTransformation(); + Box ab = rp->getCell()->getAbutmentBox(); if (dynamic_cast(usedComponent)) { cerr << Error( "Katana::protectRoutingPad(): A RoutingPad of \"%s\" is still on it's Plug.\n" @@ -175,11 +176,12 @@ namespace { - DbU::fromLambda(0.1); DbU::Unit cap = plane->getLayer()->getMinimalSpacing() / 2; DbU::Unit extension = item.second->getExtentionCap(); - Box bb ( item.first ); + Box bb = item.first.getIntersection( ab ); cdebug_log(145,0) << "@ bb:" << bb << endl; cdebug_log(145,0) << "delta=" << DbU::getValueString(delta) << endl; cdebug_log(145,0) << "cap=" << DbU::getValueString(cap) << endl; + if (bb.isEmpty()) continue; if (direction == Flags::Horizontal) { DbU::Unit axisMin = bb.getYMin() - delta; @@ -252,7 +254,7 @@ namespace { for ( size_t i=0 ; igetFreeInterval( intervals[i].getCenter() ); + Interval freeSpan = track->getFreeInterval( intervals[i].getCenter(), net ); cdebug_log(145,0) << "| termSpan " << termSpan << endl; cdebug_log(145,0) << "| freeSpan " << freeSpan << endl; bool overlap = false; @@ -262,14 +264,16 @@ namespace { size_t ovBegin = 0; size_t ovEnd = 0; track->getOverlapBounds( termSpan, ovBegin, ovEnd ); - for ( ; ovBegin <= ovEnd ; ++ovBegin ) { - TrackElement* overlaped = track->getSegment( ovBegin ); - TrackFixedSpan* fixedSpan = dynamic_cast( overlaped ); - if (fixedSpan) { - if (not fixedSpan->isBlockage()) - fixedSpan->setNet( nullptr ); - } else - conflict = true; + if (ovBegin != Track::npos) { + for ( ; ovBegin <= ovEnd ; ++ovBegin ) { + TrackElement* overlaped = track->getSegment( ovBegin ); + TrackFixedSpan* fixedSpan = dynamic_cast( overlaped ); + if (fixedSpan) { + if (not fixedSpan->isBlockage()) + fixedSpan->setNet( nullptr ); + } else + conflict = true; + } } } cdebug_log(145,0) << "| overlap =" << overlap << endl; @@ -314,7 +318,7 @@ namespace Katana { for ( Net* net : getCell()->getNets() ) { if (net->isSupply()) continue; - //DebugSession::open( net, 145, 150 ); + DebugSession::open( net, 145, 150 ); cdebug_log(145,0) << "Protect RoutingPads of " << net << endl; NetData* data = getNetData( net ); @@ -327,7 +331,7 @@ namespace Katana { for ( size_t i=0 ; i Date: Wed, 10 Jan 2024 23:21:07 +0100 Subject: [PATCH 40/51] In selectRpComponent(), do not deflate VIAs in symbolic mode. --- anabatic/src/AnabaticEngine.cpp | 4 ++-- anabatic/src/Configuration.cpp | 9 +++++++-- anabatic/src/anabatic/Configuration.h | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/anabatic/src/AnabaticEngine.cpp b/anabatic/src/AnabaticEngine.cpp index 2d650cde5..cf78961c3 100644 --- a/anabatic/src/AnabaticEngine.cpp +++ b/anabatic/src/AnabaticEngine.cpp @@ -1779,8 +1779,8 @@ namespace Anabatic { UpdateSession::open(); for ( auto rp : rps ) { - bool offgrid = _configuration->selectRpComponent(rp); - if (not offgrid and not _configuration->isM1Offgrid()) + bool ongrid = _configuration->selectRpComponent(rp); + if (not ongrid and not _configuration->isM1Offgrid()) cerr << Warning( "AnabaticEngine::computeEdgeCapacities(): %s has no components on grid.", getString(rp).c_str() ) << endl; Point center = rp->getBoundingBox().getCenter(); diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index fc04aa6ca..ceab0ab1e 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.cpp @@ -227,6 +227,10 @@ namespace Anabatic { { return new Configuration(*this); } + bool Configuration::isSymbolic () const + { return _rg->isSymbolic(); } + + bool Configuration::isTwoMetals () const { return _rg->isTwoMetals(); } @@ -512,8 +516,9 @@ namespace Anabatic { DbU::Unit bestSpan = 0; Component* ongridComponent = NULL; Component* offgridComponent = NULL; - DbU::Unit viaShrink = _rg->getViaWidth( (size_t)0 ) / 2 - + via12->getBottomEnclosure( Layer::EnclosureH ); + DbU::Unit viaShrink = 0; + if (not isSymbolic()) + viaShrink = _rg->getViaWidth( (size_t)0 )/2 + via12->getBottomEnclosure( Layer::EnclosureH ); cdebug_log(112,0) << "Looking into: " << masterNet->getCell() << endl; for ( Component* component : masterNet->getComponents() ) { diff --git a/anabatic/src/anabatic/Configuration.h b/anabatic/src/anabatic/Configuration.h index d0e16cc6e..bcd14dc9c 100644 --- a/anabatic/src/anabatic/Configuration.h +++ b/anabatic/src/anabatic/Configuration.h @@ -66,6 +66,7 @@ namespace Anabatic { inline bool isGLayer ( const Layer* ) const; bool isGMetal ( const Layer* ) const; bool isGContact ( const Layer* ) const; + bool isSymbolic () const; bool isTwoMetals () const; bool isHybrid () const; bool isM1Offgrid () const; From 76322a9fa6603685931e6cc086b8e642f12b455b Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 29 Nov 2023 21:44:47 +0100 Subject: [PATCH 41/51] New Rectilinear::getAsBiggestrectangles() method. * Returns the set of biggest rectangles inscribed inside the Rectilinear. This is *not* a partition, the rectangles overlaps. This is intended for the router to select the biggest rectangle in the direction he sees fit and making it a RoutingPad. --- hurricane/src/hurricane/Rectilinear.cpp | 347 ++++++++++++++++++++++++ hurricane/src/isobar/PyRectilinear.cpp | 38 +++ 2 files changed, 385 insertions(+) diff --git a/hurricane/src/hurricane/Rectilinear.cpp b/hurricane/src/hurricane/Rectilinear.cpp index 5bc61dba4..01ddc9c86 100644 --- a/hurricane/src/hurricane/Rectilinear.cpp +++ b/hurricane/src/hurricane/Rectilinear.cpp @@ -968,6 +968,339 @@ namespace { cdebug_log(17,0) << "| " << b << endl; } + +// ------------------------------------------------------------------- +// Class : "SweepLineBig". + + + class SweepLineBig { + public: + SweepLineBig ( const Rectilinear* + , vector& + , DbU::Unit xThreshold + , DbU::Unit yThreshold ); + ~SweepLineBig (); + void addVEdge ( DbU::Unit ymin, DbU::Unit ymax, DbU::Unit x ); + void loadVEdges (); + void updateLeftSide (); + void process ( Interval ); + void process ( const pair< DbU::Unit, list >& ); + void flushBoxes ( const Interval& ); + void toBox ( SweepInterval& ); + void asRectangles (); + private: + const Rectilinear* _rectilinear; + vector& _boxes; + list< pair< DbU::Unit, list > > _vedges; + list< SweepInterval > _sweepLine; + list< SweepInterval > _leftSides; + DbU::Unit _currX; + DbU::Unit _xThreshold; + DbU::Unit _yThreshold; + }; + + + SweepLineBig::SweepLineBig ( const Rectilinear* r + , vector& boxes + , DbU::Unit xThreshold + , DbU::Unit yThreshold ) + : _rectilinear(r) + , _boxes (boxes) + , _vedges () + , _sweepLine () + , _leftSides () + , _currX (0) + , _xThreshold (xThreshold) + , _yThreshold (yThreshold) + { + cdebug_log(17,1) << "SweepLineBig::SweepLineBig()" << endl; + cdebug_log(17,0) << "_xThreshold=" << DbU::getValueString(_xThreshold) << endl; + cdebug_log(17,0) << "_yThreshold=" << DbU::getValueString(_yThreshold) << endl; + } + + + SweepLineBig::~SweepLineBig () + { + cdebug_tabw(17,-1); + } + + + void SweepLineBig::addVEdge ( DbU::Unit ymin, DbU::Unit ymax, DbU::Unit x ) + { + if (ymin > ymax) std::swap( ymin, ymax ); + + cdebug_log(17,1) << "SweepLineBig::addVEdge() @"<< DbU::getValueString(x) + << " [" << DbU::getValueString(ymin) + << " " << DbU::getValueString(ymax) << "]" << endl; + + bool inserted = false; + for ( auto ix = _vedges.begin() ; ix != _vedges.end() ; ++ix ) { + cdebug_log(17,0) << "| Looking @" << DbU::getValueString(ix->first) + << " size=" << ix->second.size() << endl; + + if (ix->first > x) { + _vedges.insert( ix, make_pair( x, list() )); + cdebug_log(17,0) << "+ add new @" << DbU::getValueString(x) << endl; + --ix; + } + if (ix->first == x) { + for ( auto iintv = ix->second.begin() ; iintv != ix->second.end() ; ++iintv ) { + if (iintv->getVMin() >= ymax) { + ix->second.insert( iintv, Interval(ymin,ymax) ); + inserted = true; + break; + } + } + if (not inserted) { + ix->second.push_back( Interval(ymin,ymax) ); + inserted = true; + } + break; + } + } + if (not inserted) { + cdebug_log(17,0) << "+ add new (back) @" << DbU::getValueString(x) << endl; + _vedges.push_back( make_pair( x, list() )); + _vedges.back().second.push_back( Interval(ymin,ymax) ); + } + + cdebug_tabw(17,-1); + } + + + void SweepLineBig::loadVEdges () + { + const vector& points = _rectilinear->getPoints(); + for ( size_t i=0 ; i 0) and (_currX - intv.getXMin() < _xThreshold)) return; + if ((_yThreshold > 0) and (intv.getSize() < _yThreshold)) return; + + _boxes.push_back( Box( intv.getXMin(), intv.getVMin() + , _currX , intv.getVMax() )); + cdebug_log(17,0) << " toBox() " << _boxes.back() << endl; + } + + + void SweepLineBig::updateLeftSide () + { + cdebug_log(17,1) << "SweepLineBig::updateLeftSide() @" << DbU::getValueString(_currX) << endl; + for ( auto isweep = _sweepLine.begin() ; isweep != _sweepLine.end() ; ++isweep ) { + cdebug_log(17,1) << "Sweep " << *isweep << endl; + DbU::Unit leftX = _currX; + for ( auto ileft = _leftSides.begin() ; (ileft != _leftSides.end()) ; ++ileft ) { + cdebug_log(17,0) << "| Left side " << *ileft << endl; + if (ileft->isNewLeft()) { + ileft->unsetNewLeft(); + continue; + } + if (isweep->getSpan() == ileft->getSpan()) { + cdebug_log(17,0) << "> Exact match" << endl; + isweep->setExactMatch(); + ileft ->setKeep(); + continue; + } + if (isweep->getSpan().contains( ileft->getSpan() )) { + cdebug_log(17,0) << "> Contained" << endl; + ileft->setKeep(); + continue; + } + if (ileft->getSpan().contains( isweep->getSpan() )) { + cdebug_log(17,0) << "> Full shrink" << endl; + if (not ileft->isSplinter()) toBox( *ileft ); + ileft->setKeep(); + _leftSides.push_back( SweepInterval( isweep->getVMax(), ileft->getVMax(), ileft->getXMin() ) ); + _leftSides.back().setSplinter(); + cdebug_log(17,0) << "+ Add remainder " << _leftSides.back() << endl; + ileft->updateSpan( isweep->getSpan() ); + ileft->unsetSplinter(); + isweep->setExactMatch(); + continue; + } + if (isweep->getSpan().intersect( ileft->getSpan() )) { + cdebug_log(17,0) << "> Intersect" << endl; + toBox( *ileft ); + ileft->updateSpan( isweep->getSpan() ); + ileft->unsetSplinter(); + if (not ileft->isPonctual()) ileft->setKeep(); + cdebug_log(17,0) << "> Shrinked span " << *ileft << endl; + continue; + } + } + + if (not isweep->isExactMatch()) { + _leftSides.push_back( SweepInterval( *isweep )); + _leftSides.back().setXMin( leftX ); + _leftSides.back().setKeep(); + cdebug_log(17,0) << "+ Added span " << _leftSides.back() << endl; + } + cdebug_tabw(17,-1); + } + + cdebug_log(17,0) << "Clean sweepline flags" << endl; + for ( auto isweep = _sweepLine.begin() ; isweep != _sweepLine.end() ; ++isweep ) { + isweep->clearUpdateFlags(); + } + _leftSides.sort(); + cdebug_log(17,0) << "Delete closed left sides & clean flags" << endl; + for ( auto ileft = _leftSides.begin() ; ileft != _leftSides.end() ; ) { + cdebug_log(17,0) << "| " << *ileft << endl; + auto ileftNext = ileft; + ileftNext++; + if (ileftNext != _leftSides.end()) { + if ( (ileft->getSpan().getVMin() == ileftNext->getSpan().getVMin()) + and (ileft->getSpan().getVMax() == ileftNext->getSpan().getVMax())) { + cdebug_log(17,0) << "> Remove duplicate " << *ileftNext << endl; + _leftSides.erase( ileftNext ); + continue; + } + } + if (not ileft->isKeep()) { + cdebug_log(17,0) << "> Remove/close " << *ileft << endl; + auto ileftNext = ileft; + ++ileftNext; + if (not ileft->isSplinter()) { + toBox( *ileft ); + } + _leftSides.erase( ileft ); + ileft = ileftNext; + continue; + } + ileft->clearUpdateFlags(); + ileft++; + } + cdebug_tabw(17,-1); + } + + + void SweepLineBig::process ( Interval v ) + { + cdebug_log(17,1) << "SweepLineBig::process(Interval&) " + << " [" << DbU::getValueString(v.getVMin()) + << " " << DbU::getValueString(v.getVMax()) << "]" << endl; + bool done = false; + for ( auto iintv = _sweepLine.begin() ; iintv != _sweepLine.end() ; ++iintv ) { + cdebug_log(17,0) << "> Sweepline element " << *iintv << endl; + // Extractor p. 9 (a). + if (v.getVMax() < iintv->getVMin()) { + cdebug_log(17,0) << "case (a): new left side" << endl; + _sweepLine.insert( iintv, SweepInterval(v,_currX) ); + done = true; + break; + } + // Extractor p. 9 (f). + if ( (v.getVMin() == iintv->getVMin()) + and (v.getVMax() == iintv->getVMax()) ) { + cdebug_log(17,0) << "case (f): closing right side" << endl; + _sweepLine.erase( iintv ); + done = true; + break; + } + // Extractor p. 9 (b). + if (v.getVMax() == iintv->getVMin()) { + cdebug_log(17,0) << "case (b): extend min" << endl; + iintv->merge( v.getVMin() ); + done = true; + break; + } + // Extractor p. 9 (g). + if (v.getVMax() == iintv->getVMax()) { + cdebug_log(17,0) << "case (g): carve" << endl; + iintv->inflate( 0, v.getVMin() - iintv->getVMax() ); + cdebug_log(17,0) << "| " << (*iintv) << endl; + done = true; + break; + } + // Extractor p. 9 (h). + if (v.getVMin() == iintv->getVMin()) { + cdebug_log(17,0) << "case (h): carve" << endl; + iintv->inflate(iintv->getVMin() - v.getVMax(), 0 ); + done = true; + break; + } + // Extractor p. 9 (c). + if ( (v.getVMin() > iintv->getVMin()) + and (v.getVMax() < iintv->getVMax()) ) { + cdebug_log(17,0) << "case (c): carve" << endl; + DbU::Unit wholeVMin = iintv->getVMin(); + iintv->inflate( iintv->getVMin() - v.getVMax(), 0 ); + cdebug_log(17,0) << "| " << (*iintv) << endl; + _sweepLine.insert( iintv, SweepInterval( wholeVMin, v.getVMin(), _currX ) ); + cdebug_log(17,0) << "| " << (*iintv) << endl; + done = true; + break; + } + // Extractor p. 9 (d,e). + if (v.getVMin() == iintv->getVMax()) { + cdebug_log(17,0) << "case (d,e): merge" << endl; + auto iintvNext = iintv; + ++iintvNext; + // Extractor p. 9 (d). + if (iintvNext == _sweepLine.end()) { + cdebug_log(17,0) << "case (d): end of vertical line" << endl; + iintv->merge( v.getVMax() ); + iintv->setXMin( _currX ); + } else { + // Extractor p. 9 (d). + if (v.getVMax() < iintvNext->getVMin()) { + cdebug_log(17,0) << "case (d): extend max" << endl; + iintv->merge( v.getVMax() ); + iintv->setXMin( _currX ); + } else { + // Extractor p. 9 (e). + cdebug_log(17,0) << "case (e): interval joining" << endl; + iintv->merge( iintvNext->getVMax() ); + iintv->setXMin( _currX ); + _sweepLine.erase( iintvNext ); + } + } + done = true; + break; + } + } + if (not done) { + _sweepLine.push_back( SweepInterval(v,_currX) ); + } + + cdebug_tabw(17,-1); + } + + + void SweepLineBig::process ( const pair< DbU::Unit, list >& intervals ) + { + cdebug_log(17,1) << "SweepLineBig::process() @"<< DbU::getValueString(intervals.first) + << " size=" << intervals.second.size() << endl; + _currX = intervals.first; + for ( const Interval& v : intervals.second ) process( v ); + updateLeftSide(); + cdebug_tabw(17,-1); + } + + + void SweepLineBig::asRectangles () + { + loadVEdges(); + for ( auto intervals : _vedges ) { + process( intervals ); + } + cdebug_log(17,0) << "SweepLineBig::asRectangles() size=" << _boxes.size() << endl; + for ( const Box& b : _boxes ) + cdebug_log(17,0) << "| " << b << endl; + } + } // Anonymous namespace. @@ -1150,6 +1483,20 @@ namespace Hurricane { } + bool Rectilinear::getAsBiggestRectangles ( std::vector& rectangles + , DbU::Unit xThreshold + , DbU::Unit yThreshold + ) const + { + //DebugSession::open( 17, 18 ); + rectangles.clear(); + if (not isRectilinear()) return false; + SweepLineBig( this, rectangles, xThreshold, yThreshold ).asRectangles(); + //DebugSession::close(); + return true; + } + + Box Rectilinear::getNearestHSide ( DbU::Unit y ) const { Box side; diff --git a/hurricane/src/isobar/PyRectilinear.cpp b/hurricane/src/isobar/PyRectilinear.cpp index 56f66616a..4948de139 100644 --- a/hurricane/src/isobar/PyRectilinear.cpp +++ b/hurricane/src/isobar/PyRectilinear.cpp @@ -258,6 +258,44 @@ extern "C" { } + static PyObject* PyRectilinear_getAsBiggestRectangles ( PyRectilinear *self, PyObject* args ) + { + cdebug_log(20,0) << "Rectilinear.getAsBiggestRectangles()" << endl; + + HTRY + METHOD_HEAD( "Rectilinear.getAsBiggestRectangles()" ) + + PyObject* pyList = NULL; + PyObject* pyHT = NULL; + PyObject* pyVT = NULL; + if (not PyArg_ParseTuple( args, "O|OO:Rectilinear.getAsBiggestRectangles", &pyList, &pyHT, &pyVT )) { + PyErr_SetString( ConstructorError, "Rectilinear.getAsBiggestRectangles(): Must have exactly one parameter." ); + return NULL; + } + if (not PyList_Check(pyList)) { + PyErr_SetString( ConstructorError, "Rectilinear.getAsBiggestRectangles(): Argument must be a list." ); + return NULL; + } + + PyList_SetSlice( pyList, 0, PyList_Size(pyList), NULL ); + vector boxes; + if (pyHT and pyVT) + rectilinear->getAsBiggestRectangles( boxes, PyAny_AsLong(pyHT), PyAny_AsLong(pyVT) ); + else + rectilinear->getAsBiggestRectangles( boxes ); + for ( size_t i=0 ; i_object = new Box ( boxes[i] ); + PyList_Append( pyList, (PyObject*)pyBox ); + } + HCATCH + + Py_RETURN_NONE; + } + + // --------------------------------------------------------------- // PyRectilinear Attribute Method table. From 428783516d04b364e55de652c4b08ac0e5117011 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Mon, 18 Dec 2023 20:39:23 +0100 Subject: [PATCH 42/51] Support for offgrid M1 & VH topologies (WIP 1). * In AnabaticEngine::loadGlobalRouting(), call relaxOverConstraineds() only if M1 is vertical (may write another one for M1 horizontal). * In AnabaticEngine::computeEdgeCapacities(), don't complain for offgrid M1 if it is allowed... * In AutoContactTerminal::updateGeometry(), implement dragging on horizontal M1. * In AutoSegment::getExtensionCap(), manage the case when neither source nor target is requested. Return the bottom layer cap in that instance (for M1 terminals). * In AutoVertical::updatePositions(), on non-preferred segments, the extention must be further extendend as to include perpendiculars axis of tracks that we may impact. * In AutoHorizontal::updatePositions(), idem. * In Configuration::selectRpComponent(), detect M1 offgrid components and flag them. HSmall & VSmall are now forced to be flagged as *punctual*. * In NetBuilderHV, support for M1 offgrid terminals. Systematically use doRp_Accesss() and never call directly doRp_AutoContacts(). * In NetBuilderVH, general overhaul & bug fixes. * In RoutingPad, add a flag to tell that a component has been selected. * In RoutingPlane::getTrackByPosition(), add failsafe when we are before the first track axis or after the last. --- katana/src/TrackSegmentNonPref.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/katana/src/TrackSegmentNonPref.cpp b/katana/src/TrackSegmentNonPref.cpp index e985d0756..3b9d3a157 100644 --- a/katana/src/TrackSegmentNonPref.cpp +++ b/katana/src/TrackSegmentNonPref.cpp @@ -98,6 +98,7 @@ namespace Katana { RoutingPlane* plane = Session::getKatanaEngine()->getRoutingPlaneByLayer(_base->getLayer()); Interval newAxisSpan ( _base->getSourcePosition(), _base->getTargetPosition() ); + //newAxisSpan.inflate( base()->getExtensionCap( Anabatic::Flags::NoFlags )); Track* ntrack = plane->getTrackByPosition( newAxisSpan.getVMin(), Constant::Superior ); cdebug_log(159,0) << "getSourceU(): " << DbU::getValueString( _base->getSourceU() ) << endl; From 26d1428299cc5d26849b3e7c881dbfffe8e4c20d Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Thu, 11 Jan 2024 11:22:31 +0100 Subject: [PATCH 43/51] Removing code duplication due to a bad merge in Rectilinear. --- hurricane/src/hurricane/Rectilinear.cpp | 347 ------------------------ hurricane/src/isobar/PyRectilinear.cpp | 38 --- 2 files changed, 385 deletions(-) diff --git a/hurricane/src/hurricane/Rectilinear.cpp b/hurricane/src/hurricane/Rectilinear.cpp index 01ddc9c86..5bc61dba4 100644 --- a/hurricane/src/hurricane/Rectilinear.cpp +++ b/hurricane/src/hurricane/Rectilinear.cpp @@ -968,339 +968,6 @@ namespace { cdebug_log(17,0) << "| " << b << endl; } - -// ------------------------------------------------------------------- -// Class : "SweepLineBig". - - - class SweepLineBig { - public: - SweepLineBig ( const Rectilinear* - , vector& - , DbU::Unit xThreshold - , DbU::Unit yThreshold ); - ~SweepLineBig (); - void addVEdge ( DbU::Unit ymin, DbU::Unit ymax, DbU::Unit x ); - void loadVEdges (); - void updateLeftSide (); - void process ( Interval ); - void process ( const pair< DbU::Unit, list >& ); - void flushBoxes ( const Interval& ); - void toBox ( SweepInterval& ); - void asRectangles (); - private: - const Rectilinear* _rectilinear; - vector& _boxes; - list< pair< DbU::Unit, list > > _vedges; - list< SweepInterval > _sweepLine; - list< SweepInterval > _leftSides; - DbU::Unit _currX; - DbU::Unit _xThreshold; - DbU::Unit _yThreshold; - }; - - - SweepLineBig::SweepLineBig ( const Rectilinear* r - , vector& boxes - , DbU::Unit xThreshold - , DbU::Unit yThreshold ) - : _rectilinear(r) - , _boxes (boxes) - , _vedges () - , _sweepLine () - , _leftSides () - , _currX (0) - , _xThreshold (xThreshold) - , _yThreshold (yThreshold) - { - cdebug_log(17,1) << "SweepLineBig::SweepLineBig()" << endl; - cdebug_log(17,0) << "_xThreshold=" << DbU::getValueString(_xThreshold) << endl; - cdebug_log(17,0) << "_yThreshold=" << DbU::getValueString(_yThreshold) << endl; - } - - - SweepLineBig::~SweepLineBig () - { - cdebug_tabw(17,-1); - } - - - void SweepLineBig::addVEdge ( DbU::Unit ymin, DbU::Unit ymax, DbU::Unit x ) - { - if (ymin > ymax) std::swap( ymin, ymax ); - - cdebug_log(17,1) << "SweepLineBig::addVEdge() @"<< DbU::getValueString(x) - << " [" << DbU::getValueString(ymin) - << " " << DbU::getValueString(ymax) << "]" << endl; - - bool inserted = false; - for ( auto ix = _vedges.begin() ; ix != _vedges.end() ; ++ix ) { - cdebug_log(17,0) << "| Looking @" << DbU::getValueString(ix->first) - << " size=" << ix->second.size() << endl; - - if (ix->first > x) { - _vedges.insert( ix, make_pair( x, list() )); - cdebug_log(17,0) << "+ add new @" << DbU::getValueString(x) << endl; - --ix; - } - if (ix->first == x) { - for ( auto iintv = ix->second.begin() ; iintv != ix->second.end() ; ++iintv ) { - if (iintv->getVMin() >= ymax) { - ix->second.insert( iintv, Interval(ymin,ymax) ); - inserted = true; - break; - } - } - if (not inserted) { - ix->second.push_back( Interval(ymin,ymax) ); - inserted = true; - } - break; - } - } - if (not inserted) { - cdebug_log(17,0) << "+ add new (back) @" << DbU::getValueString(x) << endl; - _vedges.push_back( make_pair( x, list() )); - _vedges.back().second.push_back( Interval(ymin,ymax) ); - } - - cdebug_tabw(17,-1); - } - - - void SweepLineBig::loadVEdges () - { - const vector& points = _rectilinear->getPoints(); - for ( size_t i=0 ; i 0) and (_currX - intv.getXMin() < _xThreshold)) return; - if ((_yThreshold > 0) and (intv.getSize() < _yThreshold)) return; - - _boxes.push_back( Box( intv.getXMin(), intv.getVMin() - , _currX , intv.getVMax() )); - cdebug_log(17,0) << " toBox() " << _boxes.back() << endl; - } - - - void SweepLineBig::updateLeftSide () - { - cdebug_log(17,1) << "SweepLineBig::updateLeftSide() @" << DbU::getValueString(_currX) << endl; - for ( auto isweep = _sweepLine.begin() ; isweep != _sweepLine.end() ; ++isweep ) { - cdebug_log(17,1) << "Sweep " << *isweep << endl; - DbU::Unit leftX = _currX; - for ( auto ileft = _leftSides.begin() ; (ileft != _leftSides.end()) ; ++ileft ) { - cdebug_log(17,0) << "| Left side " << *ileft << endl; - if (ileft->isNewLeft()) { - ileft->unsetNewLeft(); - continue; - } - if (isweep->getSpan() == ileft->getSpan()) { - cdebug_log(17,0) << "> Exact match" << endl; - isweep->setExactMatch(); - ileft ->setKeep(); - continue; - } - if (isweep->getSpan().contains( ileft->getSpan() )) { - cdebug_log(17,0) << "> Contained" << endl; - ileft->setKeep(); - continue; - } - if (ileft->getSpan().contains( isweep->getSpan() )) { - cdebug_log(17,0) << "> Full shrink" << endl; - if (not ileft->isSplinter()) toBox( *ileft ); - ileft->setKeep(); - _leftSides.push_back( SweepInterval( isweep->getVMax(), ileft->getVMax(), ileft->getXMin() ) ); - _leftSides.back().setSplinter(); - cdebug_log(17,0) << "+ Add remainder " << _leftSides.back() << endl; - ileft->updateSpan( isweep->getSpan() ); - ileft->unsetSplinter(); - isweep->setExactMatch(); - continue; - } - if (isweep->getSpan().intersect( ileft->getSpan() )) { - cdebug_log(17,0) << "> Intersect" << endl; - toBox( *ileft ); - ileft->updateSpan( isweep->getSpan() ); - ileft->unsetSplinter(); - if (not ileft->isPonctual()) ileft->setKeep(); - cdebug_log(17,0) << "> Shrinked span " << *ileft << endl; - continue; - } - } - - if (not isweep->isExactMatch()) { - _leftSides.push_back( SweepInterval( *isweep )); - _leftSides.back().setXMin( leftX ); - _leftSides.back().setKeep(); - cdebug_log(17,0) << "+ Added span " << _leftSides.back() << endl; - } - cdebug_tabw(17,-1); - } - - cdebug_log(17,0) << "Clean sweepline flags" << endl; - for ( auto isweep = _sweepLine.begin() ; isweep != _sweepLine.end() ; ++isweep ) { - isweep->clearUpdateFlags(); - } - _leftSides.sort(); - cdebug_log(17,0) << "Delete closed left sides & clean flags" << endl; - for ( auto ileft = _leftSides.begin() ; ileft != _leftSides.end() ; ) { - cdebug_log(17,0) << "| " << *ileft << endl; - auto ileftNext = ileft; - ileftNext++; - if (ileftNext != _leftSides.end()) { - if ( (ileft->getSpan().getVMin() == ileftNext->getSpan().getVMin()) - and (ileft->getSpan().getVMax() == ileftNext->getSpan().getVMax())) { - cdebug_log(17,0) << "> Remove duplicate " << *ileftNext << endl; - _leftSides.erase( ileftNext ); - continue; - } - } - if (not ileft->isKeep()) { - cdebug_log(17,0) << "> Remove/close " << *ileft << endl; - auto ileftNext = ileft; - ++ileftNext; - if (not ileft->isSplinter()) { - toBox( *ileft ); - } - _leftSides.erase( ileft ); - ileft = ileftNext; - continue; - } - ileft->clearUpdateFlags(); - ileft++; - } - cdebug_tabw(17,-1); - } - - - void SweepLineBig::process ( Interval v ) - { - cdebug_log(17,1) << "SweepLineBig::process(Interval&) " - << " [" << DbU::getValueString(v.getVMin()) - << " " << DbU::getValueString(v.getVMax()) << "]" << endl; - bool done = false; - for ( auto iintv = _sweepLine.begin() ; iintv != _sweepLine.end() ; ++iintv ) { - cdebug_log(17,0) << "> Sweepline element " << *iintv << endl; - // Extractor p. 9 (a). - if (v.getVMax() < iintv->getVMin()) { - cdebug_log(17,0) << "case (a): new left side" << endl; - _sweepLine.insert( iintv, SweepInterval(v,_currX) ); - done = true; - break; - } - // Extractor p. 9 (f). - if ( (v.getVMin() == iintv->getVMin()) - and (v.getVMax() == iintv->getVMax()) ) { - cdebug_log(17,0) << "case (f): closing right side" << endl; - _sweepLine.erase( iintv ); - done = true; - break; - } - // Extractor p. 9 (b). - if (v.getVMax() == iintv->getVMin()) { - cdebug_log(17,0) << "case (b): extend min" << endl; - iintv->merge( v.getVMin() ); - done = true; - break; - } - // Extractor p. 9 (g). - if (v.getVMax() == iintv->getVMax()) { - cdebug_log(17,0) << "case (g): carve" << endl; - iintv->inflate( 0, v.getVMin() - iintv->getVMax() ); - cdebug_log(17,0) << "| " << (*iintv) << endl; - done = true; - break; - } - // Extractor p. 9 (h). - if (v.getVMin() == iintv->getVMin()) { - cdebug_log(17,0) << "case (h): carve" << endl; - iintv->inflate(iintv->getVMin() - v.getVMax(), 0 ); - done = true; - break; - } - // Extractor p. 9 (c). - if ( (v.getVMin() > iintv->getVMin()) - and (v.getVMax() < iintv->getVMax()) ) { - cdebug_log(17,0) << "case (c): carve" << endl; - DbU::Unit wholeVMin = iintv->getVMin(); - iintv->inflate( iintv->getVMin() - v.getVMax(), 0 ); - cdebug_log(17,0) << "| " << (*iintv) << endl; - _sweepLine.insert( iintv, SweepInterval( wholeVMin, v.getVMin(), _currX ) ); - cdebug_log(17,0) << "| " << (*iintv) << endl; - done = true; - break; - } - // Extractor p. 9 (d,e). - if (v.getVMin() == iintv->getVMax()) { - cdebug_log(17,0) << "case (d,e): merge" << endl; - auto iintvNext = iintv; - ++iintvNext; - // Extractor p. 9 (d). - if (iintvNext == _sweepLine.end()) { - cdebug_log(17,0) << "case (d): end of vertical line" << endl; - iintv->merge( v.getVMax() ); - iintv->setXMin( _currX ); - } else { - // Extractor p. 9 (d). - if (v.getVMax() < iintvNext->getVMin()) { - cdebug_log(17,0) << "case (d): extend max" << endl; - iintv->merge( v.getVMax() ); - iintv->setXMin( _currX ); - } else { - // Extractor p. 9 (e). - cdebug_log(17,0) << "case (e): interval joining" << endl; - iintv->merge( iintvNext->getVMax() ); - iintv->setXMin( _currX ); - _sweepLine.erase( iintvNext ); - } - } - done = true; - break; - } - } - if (not done) { - _sweepLine.push_back( SweepInterval(v,_currX) ); - } - - cdebug_tabw(17,-1); - } - - - void SweepLineBig::process ( const pair< DbU::Unit, list >& intervals ) - { - cdebug_log(17,1) << "SweepLineBig::process() @"<< DbU::getValueString(intervals.first) - << " size=" << intervals.second.size() << endl; - _currX = intervals.first; - for ( const Interval& v : intervals.second ) process( v ); - updateLeftSide(); - cdebug_tabw(17,-1); - } - - - void SweepLineBig::asRectangles () - { - loadVEdges(); - for ( auto intervals : _vedges ) { - process( intervals ); - } - cdebug_log(17,0) << "SweepLineBig::asRectangles() size=" << _boxes.size() << endl; - for ( const Box& b : _boxes ) - cdebug_log(17,0) << "| " << b << endl; - } - } // Anonymous namespace. @@ -1483,20 +1150,6 @@ namespace Hurricane { } - bool Rectilinear::getAsBiggestRectangles ( std::vector& rectangles - , DbU::Unit xThreshold - , DbU::Unit yThreshold - ) const - { - //DebugSession::open( 17, 18 ); - rectangles.clear(); - if (not isRectilinear()) return false; - SweepLineBig( this, rectangles, xThreshold, yThreshold ).asRectangles(); - //DebugSession::close(); - return true; - } - - Box Rectilinear::getNearestHSide ( DbU::Unit y ) const { Box side; diff --git a/hurricane/src/isobar/PyRectilinear.cpp b/hurricane/src/isobar/PyRectilinear.cpp index 4948de139..56f66616a 100644 --- a/hurricane/src/isobar/PyRectilinear.cpp +++ b/hurricane/src/isobar/PyRectilinear.cpp @@ -258,44 +258,6 @@ extern "C" { } - static PyObject* PyRectilinear_getAsBiggestRectangles ( PyRectilinear *self, PyObject* args ) - { - cdebug_log(20,0) << "Rectilinear.getAsBiggestRectangles()" << endl; - - HTRY - METHOD_HEAD( "Rectilinear.getAsBiggestRectangles()" ) - - PyObject* pyList = NULL; - PyObject* pyHT = NULL; - PyObject* pyVT = NULL; - if (not PyArg_ParseTuple( args, "O|OO:Rectilinear.getAsBiggestRectangles", &pyList, &pyHT, &pyVT )) { - PyErr_SetString( ConstructorError, "Rectilinear.getAsBiggestRectangles(): Must have exactly one parameter." ); - return NULL; - } - if (not PyList_Check(pyList)) { - PyErr_SetString( ConstructorError, "Rectilinear.getAsBiggestRectangles(): Argument must be a list." ); - return NULL; - } - - PyList_SetSlice( pyList, 0, PyList_Size(pyList), NULL ); - vector boxes; - if (pyHT and pyVT) - rectilinear->getAsBiggestRectangles( boxes, PyAny_AsLong(pyHT), PyAny_AsLong(pyVT) ); - else - rectilinear->getAsBiggestRectangles( boxes ); - for ( size_t i=0 ; i_object = new Box ( boxes[i] ); - PyList_Append( pyList, (PyObject*)pyBox ); - } - HCATCH - - Py_RETURN_NONE; - } - - // --------------------------------------------------------------- // PyRectilinear Attribute Method table. From 4d18fc6cca8ac521442398d4f65cb39a2c8e1010 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 16 Jan 2024 15:33:20 +0100 Subject: [PATCH 44/51] Force DoglegDown when slackening and AutoSegment from a Terminal. --- anabatic/src/AutoHorizontal.cpp | 13 +++++++---- anabatic/src/AutoVertical.cpp | 9 ++++--- anabatic/src/Constants.cpp | 39 ++++++++++++++++--------------- anabatic/src/anabatic/Constants.h | 1 + 4 files changed, 35 insertions(+), 27 deletions(-) diff --git a/anabatic/src/AutoHorizontal.cpp b/anabatic/src/AutoHorizontal.cpp index c0a3af301..734d89fcd 100644 --- a/anabatic/src/AutoHorizontal.cpp +++ b/anabatic/src/AutoHorizontal.cpp @@ -386,13 +386,13 @@ namespace Anabatic { int nativeSlack = nativeConstraints.getSize() / getPitch(); cdebug_log(149,0) << "Source constraint: " << constraints - << " slack:" << slack - << " native slack:" << nativeSlack << endl; + << " slack:" << slack + << " native slack:" << nativeSlack << endl; cdebug_log(149,0) << "Perpand constraints on target: " << perpandConstraints << endl; // Ugly: GCell's track number is hardwired. if (isNonPrefSource or (nativeSlack < lowSlack) or (nativeSlack - slack < 3)) { cdebug_log(149,0) << "Slackening from Source: " << source << endl; - _makeDogleg( source->getGCell(), Flags::NoFlags ); + _makeDogleg( source->getGCell(), Flags::DoglegDown ); sourceSlackened = true; } else if (slack < 10) { halfSlackened = true; @@ -430,7 +430,7 @@ namespace Anabatic { << " native slack:" << nativeSlack << endl; if (isNonPrefTarget or (nativeSlack < lowSlack) or (nativeSlack - slack < 3)) { cdebug_log(149,0) << "Slackening from Target: " << target << endl; - parallel->_makeDogleg( target->getGCell(), Flags::NoFlags ); + parallel->_makeDogleg( target->getGCell(), Flags::DoglegDown ); targetSlackened = true; } else if (slack < 10) { halfSlackened = true; @@ -889,7 +889,10 @@ namespace Anabatic { } else if (Session::getRoutingGauge()->isVH()) { upLayer = (depth < 2); } else { - upLayer = (depth+1 <= Session::getConfiguration()->getAllowedDepth()); + if ((depth > 0) and (flags & Flags::DoglegDown)) + upLayer = not (Session::getConfiguration()->isUsable( depth-1 )); + else + upLayer = (depth+1 <= Session::getConfiguration()->getAllowedDepth()); } size_t doglegDepth = depth + ((upLayer)?1:-1); diff --git a/anabatic/src/AutoVertical.cpp b/anabatic/src/AutoVertical.cpp index 72bf5d4c0..68f0f15d9 100644 --- a/anabatic/src/AutoVertical.cpp +++ b/anabatic/src/AutoVertical.cpp @@ -317,7 +317,7 @@ namespace Anabatic { // Ugly: GCell's track number is hardwired. if ((slack < lowSlack) or (nativeSlack - slack < 3)) { - _makeDogleg( source->getGCell(), Flags::NoFlags ); + _makeDogleg( source->getGCell(), Flags::DoglegDown ); sourceSlackened = true; } else if (slack < 10) { halfSlackened = true; @@ -348,7 +348,7 @@ namespace Anabatic { // Ugly: GCell's track number is hardwired. if ((slack < lowSlack) or (nativeSlack - slack < 3)) { - _makeDogleg( target->getGCell(), Flags::NoFlags ); + _makeDogleg( target->getGCell(), Flags::DoglegDown ); targetSlackened = true; } else if (slack < 10) { halfSlackened = true; @@ -750,7 +750,10 @@ namespace Anabatic { } else if (Session::getRoutingGauge()->isVH()) { upLayer = (depth < 2); } else { - upLayer = (depth+1 <= Session::getConfiguration()->getAllowedDepth()); + if ((depth > 0) and (flags & Flags::DoglegDown)) + upLayer = not (Session::getConfiguration()->isUsable( depth-1 )); + else + upLayer = (depth+1 <= Session::getConfiguration()->getAllowedDepth()); } size_t doglegDepth = depth + ((upLayer)?1:-1); diff --git a/anabatic/src/Constants.cpp b/anabatic/src/Constants.cpp index 81c1fc70c..9ced3e3f7 100644 --- a/anabatic/src/Constants.cpp +++ b/anabatic/src/Constants.cpp @@ -117,25 +117,26 @@ namespace Anabatic { const BaseFlags Flags::Superior = (1L << 22); const BaseFlags Flags::DoglegOnLeft = (1L << 23); const BaseFlags Flags::DoglegOnRight = (1L << 24); - const BaseFlags Flags::WithNeighbors = (1L << 25); - const BaseFlags Flags::NoCheckLayer = (1L << 26); - const BaseFlags Flags::NoCheckGCell = (1L << 27); - const BaseFlags Flags::HalfSlacken = (1L << 28); - const BaseFlags Flags::NoGCellShrink = (1L << 29); - const BaseFlags Flags::CParanoid = (1L << 30); - const BaseFlags Flags::CheckLowDensity = (1L << 31); - const BaseFlags Flags::CheckLowUpDensity = (1L << 32); - const BaseFlags Flags::NoUpdate = (1L << 33); - const BaseFlags Flags::NorthPath = (1L << 34); - const BaseFlags Flags::UseNonPref = (1L << 35); - const BaseFlags Flags::Force = (1L << 36); - const BaseFlags Flags::LayerCapOnly = (1L << 37); - const BaseFlags Flags::NoMinLength = (1L << 38); - const BaseFlags Flags::NoSegExt = (1L << 39); - const BaseFlags Flags::NullLength = (1L << 40); - const BaseFlags Flags::OnVSmall = (1L << 41); - const BaseFlags Flags::Unbreakable = (1L << 42); - const BaseFlags Flags::ForOffgrid = (1L << 43); + const BaseFlags Flags::DoglegDown = (1L << 25); + const BaseFlags Flags::WithNeighbors = (1L << 26); + const BaseFlags Flags::NoCheckLayer = (1L << 27); + const BaseFlags Flags::NoCheckGCell = (1L << 28); + const BaseFlags Flags::HalfSlacken = (1L << 29); + const BaseFlags Flags::NoGCellShrink = (1L << 30); + const BaseFlags Flags::CParanoid = (1L << 31); + const BaseFlags Flags::CheckLowDensity = (1L << 32); + const BaseFlags Flags::CheckLowUpDensity = (1L << 33); + const BaseFlags Flags::NoUpdate = (1L << 34); + const BaseFlags Flags::NorthPath = (1L << 35); + const BaseFlags Flags::UseNonPref = (1L << 36); + const BaseFlags Flags::Force = (1L << 37); + const BaseFlags Flags::LayerCapOnly = (1L << 38); + const BaseFlags Flags::NoMinLength = (1L << 39); + const BaseFlags Flags::NoSegExt = (1L << 40); + const BaseFlags Flags::NullLength = (1L << 41); + const BaseFlags Flags::OnVSmall = (1L << 42); + const BaseFlags Flags::Unbreakable = (1L << 43); + const BaseFlags Flags::ForOffgrid = (1L << 44); Flags::~Flags () diff --git a/anabatic/src/anabatic/Constants.h b/anabatic/src/anabatic/Constants.h index 01de41147..d5040d1ef 100644 --- a/anabatic/src/anabatic/Constants.h +++ b/anabatic/src/anabatic/Constants.h @@ -95,6 +95,7 @@ namespace Anabatic { static const BaseFlags Superior ; static const BaseFlags DoglegOnLeft ; static const BaseFlags DoglegOnRight ; + static const BaseFlags DoglegDown ; static const BaseFlags WithNeighbors ; static const BaseFlags NoCheckLayer ; static const BaseFlags NoCheckGCell ; From 8f74dc44b513af118bca7e32c658300a096e8f1e Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 16 Jan 2024 15:35:35 +0100 Subject: [PATCH 45/51] In NetBuilderHV, check for up density before moving up a global. --- anabatic/src/GCell.cpp | 67 +++++++++++++++++++++++++++++++++++ anabatic/src/NetBuilderHV.cpp | 28 +++++++++++++-- anabatic/src/anabatic/GCell.h | 8 +++++ 3 files changed, 100 insertions(+), 3 deletions(-) diff --git a/anabatic/src/GCell.cpp b/anabatic/src/GCell.cpp index 21d13f963..f52039ddd 100644 --- a/anabatic/src/GCell.cpp +++ b/anabatic/src/GCell.cpp @@ -1929,6 +1929,73 @@ namespace Anabatic { } + bool GCell::getHGCellsUnder ( vector& gcells + , GCell* gcell + , GCell* end + , DbU::Unit yprobe + ) + { + vector().swap( gcells ); + + cdebug_log(144,0) << "yprobe: " << DbU::getValueString(yprobe) << endl; + + bool success = true; + if (gcell->getXMin() > end->getXMin()) std::swap( gcell, end ); + if (yprobe == gcell->getConstraintYMax()) yprobe--; + + gcells.push_back( gcell ); + while ( gcell != end ) { + gcell = gcell->getEast( yprobe ); + if (not gcell) { + success = false; + cerr << Error( "GCell::getHGCellsUnder() : NULL GCell under\n" + " begin:%s\n" + " end: %s" + , getString(gcell).c_str() + , getString(end ).c_str() + ) << endl; + break; + } + gcells.push_back( gcell ); + } + return success; + } + + + bool GCell::getVGCellsUnder ( vector& gcells + , GCell* gcell + , GCell* end + , DbU::Unit xprobe + ) + { + vector().swap( gcells ); + + cdebug_log(144,0) << "xprobe: " << DbU::getValueString(xprobe) << endl; + + bool success = true; + if (gcell->getYMin() > end->getYMin()) std::swap( gcell, end ); + if (xprobe == gcell->getConstraintXMax()) xprobe--; + + gcells.push_back( gcell ); + while ( gcell != end ) { + gcell = gcell->getNorth( xprobe ); + + if (not gcell) { + success = false; + cerr << Error( "GCell::getVGCellsUnder() : NULL GCell under\n" + " begin:%s\n" + " end: %s" + , getString(gcell).c_str() + , getString(end ).c_str() + ) << endl; + break; + } + gcells.push_back( gcell ); + } + return success; + } + + // ------------------------------------------------------------------- // Class : "Anabatic::GCellDensitySet". diff --git a/anabatic/src/NetBuilderHV.cpp b/anabatic/src/NetBuilderHV.cpp index ebf7d4199..a984c587e 100644 --- a/anabatic/src/NetBuilderHV.cpp +++ b/anabatic/src/NetBuilderHV.cpp @@ -1965,11 +1965,33 @@ namespace Anabatic { Segment* baseSegment = static_cast( getFromHook()->getComponent() ); if ( (getSourceFlags() | getFlags()) & ToUpperRouting) { cdebug_log(145,0) << "Moving up global" << endl; + vector gcells; size_t gdepth = Session::getGHorizontalDepth(); - if (dynamic_cast(baseSegment)) + if (dynamic_cast(baseSegment)) { gdepth = Session::getGVerticalDepth(); - baseSegment->setLayer( Session::getBuildRoutingLayer( gdepth+2 )); - baseSegment->setWidth( Session::getWireWidth( gdepth+2 )); + GCell::getVGCellsUnder( gcells + , getSourceContact()->getGCell() + , targetContact->getGCell() + , baseSegment->getX() ); + } else { + GCell::getHGCellsUnder( gcells + , getSourceContact()->getGCell() + , targetContact->getGCell() + , baseSegment->getY() ); + } + bool canMoveUp = true; + for ( GCell* gcell : gcells ) { + if (not gcell->hasFreeTrack(gdepth+2,2.0)) { + canMoveUp = false; + break; + } + } + if (canMoveUp) { + baseSegment->setLayer( Session::getBuildRoutingLayer( gdepth+2 )); + baseSegment->setWidth( Session::getWireWidth( gdepth+2 )); + } else { + cdebug_log(145,0) << "-> Cancel move up, not enough up free track" << endl; + } } AutoSegment* globalSegment = AutoSegment::create( getSourceContact() diff --git a/anabatic/src/anabatic/GCell.h b/anabatic/src/anabatic/GCell.h index d181161ec..13120e540 100644 --- a/anabatic/src/anabatic/GCell.h +++ b/anabatic/src/anabatic/GCell.h @@ -137,6 +137,14 @@ namespace Anabatic { static Box getBorder ( const GCell*, const GCell* ); static inline DbU::Unit getMatrixHSide (); static inline DbU::Unit getMatrixVSide (); + static bool getHGCellsUnder ( vector& gcells + , GCell* gcell + , GCell* end + , DbU::Unit yprobe ); + static bool getVGCellsUnder ( vector& gcells + , GCell* gcell + , GCell* end + , DbU::Unit xprobe ); public: static GCell* create ( AnabaticEngine* ); public: From aab4c5a1774228a264351012c03a1270c9c90278 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 16 Jan 2024 16:19:02 +0100 Subject: [PATCH 46/51] Added isUsable() and getFirstroutingLayer() proxies to Anabatic::Configuration. --- anabatic/src/Configuration.cpp | 8 ++++++++ anabatic/src/anabatic/Configuration.h | 8 +++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/anabatic/src/Configuration.cpp b/anabatic/src/Configuration.cpp index ceab0ab1e..b5d87bf16 100644 --- a/anabatic/src/Configuration.cpp +++ b/anabatic/src/Configuration.cpp @@ -249,6 +249,14 @@ namespace Anabatic { bool Configuration::isVH () const { return _rg->isVH(); } + + + bool Configuration::isUsable ( size_t depth ) const + { return _rg->isUsable( depth ); } + + + size_t Configuration::getFirstRoutingLayer () const + { return _rg->getFirstRoutingLayer(); } bool Configuration::isGMetal ( const Layer* layer ) const diff --git a/anabatic/src/anabatic/Configuration.h b/anabatic/src/anabatic/Configuration.h index bcd14dc9c..bd29c05db 100644 --- a/anabatic/src/anabatic/Configuration.h +++ b/anabatic/src/anabatic/Configuration.h @@ -63,15 +63,17 @@ namespace Anabatic { virtual ~Configuration (); virtual Configuration* clone () const; // Methods. - inline bool isGLayer ( const Layer* ) const; - bool isGMetal ( const Layer* ) const; - bool isGContact ( const Layer* ) const; bool isSymbolic () const; bool isTwoMetals () const; bool isHybrid () const; bool isM1Offgrid () const; bool isHV () const; bool isVH () const; + inline bool isGLayer ( const Layer* ) const; + bool isGMetal ( const Layer* ) const; + bool isGContact ( const Layer* ) const; + bool isUsable ( size_t depth ) const; + size_t getFirstRoutingLayer () const; inline std::string getNetBuilderStyle () const; inline StyleFlags getRoutingStyle () const; const Layer* getGContactLayer () const; From 533b1022eb846d078b0bb023d927c73a81e69d2a Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 16 Jan 2024 16:20:13 +0100 Subject: [PATCH 47/51] Export RoutingLayerGauge::isHorizontal() & isVertical() to Python. --- crlcore/src/pyCRL/PyRoutingLayerGauge.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crlcore/src/pyCRL/PyRoutingLayerGauge.cpp b/crlcore/src/pyCRL/PyRoutingLayerGauge.cpp index 07a622fe3..e73617163 100644 --- a/crlcore/src/pyCRL/PyRoutingLayerGauge.cpp +++ b/crlcore/src/pyCRL/PyRoutingLayerGauge.cpp @@ -269,6 +269,8 @@ extern "C" { DirectGetUIntAttribute (PyRoutingLayerGauge_getType ,getType ,PyRoutingLayerGauge,RoutingLayerGauge) DirectGetDoubleAttribute(PyRoutingLayerGauge_getDensity ,getDensity ,PyRoutingLayerGauge,RoutingLayerGauge) DirectGetBoolAttribute (PyRoutingLayerGauge_isUsable ,isUsable ,PyRoutingLayerGauge,RoutingLayerGauge) + DirectGetBoolAttribute (PyRoutingLayerGauge_isHorizontal ,isHorizontal ,PyRoutingLayerGauge,RoutingLayerGauge) + DirectGetBoolAttribute (PyRoutingLayerGauge_isVertical ,isVertical ,PyRoutingLayerGauge,RoutingLayerGauge) DirectGetLongAttribute (PyRoutingLayerGauge_getOffset ,getOffset ,PyRoutingLayerGauge,RoutingLayerGauge) DirectGetLongAttribute (PyRoutingLayerGauge_getPitch ,getPitch ,PyRoutingLayerGauge,RoutingLayerGauge) DirectGetLongAttribute (PyRoutingLayerGauge_getHalfPitch ,getHalfPitch ,PyRoutingLayerGauge,RoutingLayerGauge) @@ -290,6 +292,10 @@ extern "C" { , "Create a new RoutingLayerGauge." } , { "isUsable" , (PyCFunction)PyRoutingLayerGauge_isUsable , METH_NOARGS , "Tells if the layer is usable for standard routing." } + , { "isHorizontal" , (PyCFunction)PyRoutingLayerGauge_isHorizontal , METH_NOARGS + , "Tells if the layer prefered routing direction is horizontal." } + , { "isVertical" , (PyCFunction)PyRoutingLayerGauge_isVertical , METH_NOARGS + , "Tells if the layer prefered routing direction is vertical." } , { "getLayer" , (PyCFunction)PyRoutingLayerGauge_getLayer , METH_NOARGS , "Returns the associated routing layer." } , { "getBlockageLayer" , (PyCFunction)PyRoutingLayerGauge_getBlockageLayer, METH_NOARGS From feff2defaa25a4daa6049bfd4ee69da8397e1b34 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 16 Jan 2024 19:45:22 +0100 Subject: [PATCH 48/51] Add a failsafe in case the graphic style index no longer exists. --- hurricane/src/viewer/GraphicsWidget.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/hurricane/src/viewer/GraphicsWidget.cpp b/hurricane/src/viewer/GraphicsWidget.cpp index b28818318..53592d53d 100644 --- a/hurricane/src/viewer/GraphicsWidget.cpp +++ b/hurricane/src/viewer/GraphicsWidget.cpp @@ -137,14 +137,21 @@ namespace Hurricane { void GraphicsWidget::readQtSettings ( size_t viewerId ) { + const vector& styles = Graphics::getStyles (); QSettings settings; QString checkKey = QString( "CellViewer/%1/controller/graphics/displayStyle" ).arg( viewerId ); if (not settings.contains(checkKey)) return; settings.beginGroup( QString("CellViewer/%1/controller/graphics").arg(viewerId) ); int styleId = settings.value( "displayStyle" ).toInt(); if (styleId >= 0) { - _cellWidget->setStyle( (size_t)styleId ); - _stylesGroup->button( styleId )->setChecked( true ); + if ((size_t)styleId < styles.size()) { + _cellWidget->setStyle( (size_t)styleId ); + _stylesGroup->button( styleId )->setChecked( true ); + } else { + cerr << Warning( "GraphicsWidget::readQtSettings(): Unable to restore style id=%d (only %d styles)." + , styleId, styles.size() + ) << endl; + } } settings.endGroup(); } From e8ed673c8891f64c660cd6c1c14b59a52dde5a9b Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 16 Jan 2024 19:46:29 +0100 Subject: [PATCH 49/51] Fix wrong import path. --- cumulus/src/designflow/graal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cumulus/src/designflow/graal.py b/cumulus/src/designflow/graal.py index 6faacf0aa..60d2277e5 100644 --- a/cumulus/src/designflow/graal.py +++ b/cumulus/src/designflow/graal.py @@ -34,7 +34,7 @@ def __repr__ ( self ): return '<{}>'.format( ' '.join(self.command) ) def doTask ( self ): - from helpers.io import ErrorMessage + from ..helpers.io import ErrorMessage shellEnv = ShellEnv() shellEnv[ 'MBK_IN_PH' ] = self.layoutFile.suffix[1:] From 1418f475d2f26b54ee4ef4dbf8fbdb5b43a5fe69 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 16 Jan 2024 19:48:53 +0100 Subject: [PATCH 50/51] Manage layer change for south terminals of a macro. --- cumulus/src/plugins/block/block.py | 2 +- cumulus/src/plugins/macro/macro.py | 51 ++++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/cumulus/src/plugins/block/block.py b/cumulus/src/plugins/block/block.py index fd0792efb..c80188470 100644 --- a/cumulus/src/plugins/block/block.py +++ b/cumulus/src/plugins/block/block.py @@ -702,7 +702,7 @@ def placeMacro ( self, ipath, transf ): with UpdateSession(): instance = self.rgetCoreInstance( ipath ) macro = Macro.wrap( instance.getMasterCell() - , self.conf.routingGauge.getName(), 3, 2 ) + , self.conf.routingGauge.getName(), 3, 3 ) instanceAb = instance.getMasterCell().getAbutmentBox() coreTransf = self.conf.icore.getTransformation() if self.conf.isCoreBlock: diff --git a/cumulus/src/plugins/macro/macro.py b/cumulus/src/plugins/macro/macro.py index aac97ef64..cc0c5aaee 100644 --- a/cumulus/src/plugins/macro/macro.py +++ b/cumulus/src/plugins/macro/macro.py @@ -124,7 +124,7 @@ def __init__ ( self, macroCell, gaugeName, hMargin, vMargin ): that are half free and half occluded by the block itself may cause (stupid) deadlock to appear. """ - trace( 550, '\tMacro.__init__() {}\n'.format(macroCell) ) + trace( 550, '+,', '\tMacro.__init__() {}\n'.format(macroCell) ) self.cell = macroCell Macro.LUT[ self.cell ] = self @@ -224,6 +224,7 @@ def __init__ ( self, macroCell, gaugeName, hMargin, vMargin ): with UpdateSession(): for component in westPins: + trace( 550, '\twestPin {}\n'.format( component )) NetExternalComponents.setInternal( component ) pitch = self.rg.getPitch( component.getLayer() ) ppitch = self.getPPitch( component.getLayer() ) @@ -317,6 +318,7 @@ def __init__ ( self, macroCell, gaugeName, hMargin, vMargin ): ) NetExternalComponents.setExternal( horizontal ) for component in eastPins: + trace( 550, '\teastPin {}\n'.format( component )) layer = component.getLayer() if layer.getMask() != gaugeMetal2.getLayer().getMask(): useBigVia = True @@ -363,13 +365,23 @@ def __init__ ( self, macroCell, gaugeName, hMargin, vMargin ): ) NetExternalComponents.setExternal( horizontal ) for component in southPins: + trace( 550, '\tsouthPin {}\n'.format( component )) NetExternalComponents.setInternal( component ) - pitch = self.rg.getPitch( component.getLayer() ) + innerRg = self.rg.getLayerGauge( component.getLayer() ) + outerRg = innerRg + vDepth = innerRg.getDepth() + if innerRg.isHorizontal(): + #if vDepth+1 < self.rg.getAllowedDepth(): vDepth += 1 + #else: vDepth -= 1 + outerRg = self.rg.getLayerGauge( vDepth + 1 ) + if outerRg.getLayer().getMask() != innerRg.getLayer().getMask(): + useBigVia = True + pitch = self.rg.getPitch( outerRg.getLayer() ) ppitch = self.getPPitch( component.getLayer() ) - wwidth = self.getWireWidth( component.getLayer() ) + wwidth = self.getWireWidth( outerRg.getLayer() ) bb = component.getBoundingBox() xAxis = bb.getXCenter() - xOngrid = self.getNearestTrackAxis( component.getLayer(), xAxis ) + xOngrid = self.getNearestTrackAxis( outerRg.getLayer(), xAxis ) yMax = bb.getYMin() yMin = yMax - vMargin*ppitch width = bb.getWidth() @@ -382,22 +394,33 @@ def __init__ ( self, macroCell, gaugeName, hMargin, vMargin ): else: ppXAxis += width//2 ppXOngrid -= wwidth//2 - horizontal = Horizontal.create( component.getNet() - , component.getLayer() - , bb.getYMin() - , width - , ppXAxis - , ppXOngrid - ) + if useBigVia: + bvia = BigVia( component.getNet() + , innerRg.getDepth() + , xOngrid + , bb.getYMin() + wwidth + , wwidth + , 3*wwidth + , flags=BigVia.AllowAllExpand ) + bvia.mergeDepth( outerRg.getDepth() ) + bvia.doLayout() + else: + horizontal = Horizontal.create( component.getNet() + , component.getLayer() + , bb.getYMin() + , width + , ppXAxis + , ppXOngrid + ) vertical = Vertical.create( component.getNet() - , component.getLayer() + , outerRg.getLayer() , xOngrid , wwidth , yMin , yMax ) vertical = Vertical.create( component.getNet() - , component.getLayer() + , outerRg.getLayer() , xOngrid , wwidth , yMin @@ -405,6 +428,7 @@ def __init__ ( self, macroCell, gaugeName, hMargin, vMargin ): ) NetExternalComponents.setExternal( vertical ) for component in northPins: + trace( 550, '\tnorthPin {}\n'.format( component )) layer = component.getLayer() if layer.getMask() != gaugeMetal3.getLayer().getMask(): useBigVia = True @@ -462,3 +486,4 @@ def __init__ ( self, macroCell, gaugeName, hMargin, vMargin ): ) NetExternalComponents.setExternal( vertical ) self.cell.setAbutmentBox( self.outerAb ) + trace( 550, '-' ) From 758fe3a640cdd3f3dc9ecd214ea25d6404f0c293 Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Tue, 16 Jan 2024 19:51:47 +0100 Subject: [PATCH 51/51] More accurate search for obstacle of the H-Tree sub-branches. --- cumulus/src/plugins/block/spares.py | 64 +++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/cumulus/src/plugins/block/spares.py b/cumulus/src/plugins/block/spares.py index b5b93b373..a2406b2ce 100644 --- a/cumulus/src/plugins/block/spares.py +++ b/cumulus/src/plugins/block/spares.py @@ -21,7 +21,7 @@ from ...Hurricane import Breakpoint, DbU, Box, Transformation, Box, \ Path, Layer, Occurrence, Net, RoutingPad, \ Horizontal, Vertical, Contact, Pin, Plug, \ - Instance + Instance, Point from ...CRL import AllianceFramework, RoutingLayerGauge from ...helpers import trace, dots, l, u, n from ...helpers.io import ErrorMessage, WarningMessage, catch @@ -276,27 +276,54 @@ def create ( spares ): @staticmethod def isUsedArea ( spares, area, rtag, raiseError ): - centerArea = Box( area.getCenter() ) sliceHeight = spares.conf.sliceHeight - centerArea.inflate( 4*sliceHeight, sliceHeight ) - trace( 540, '\tQuadTree.isUnderArea(): {} {} of {}\n'.format(rtag,centerArea,spares.conf.cell) ) + if rtag[-2:] == 'bl': + vWireArea = Box( area.getXCenter(), area.getYCenter() + , area.getXCenter(), area.getYMax () ) + hWireArea = Box( area.getXCenter(), area.getYMax() + , area.getXMax (), area.getYMax() ) + elif rtag[-2:] == 'br': + vWireArea = Box( area.getXCenter(), area.getYCenter() + , area.getXCenter(), area.getYMax () ) + hWireArea = Box( area.getXCenter(), area.getYMax() + , area.getXMin (), area.getYMax() ) + elif rtag[-2:] == 'tl': + vWireArea = Box( area.getXCenter(), area.getYCenter() + , area.getXCenter(), area.getYMin () ) + hWireArea = Box( area.getXCenter(), area.getYMin() + , area.getXMax (), area.getYMin() ) + elif rtag[-2:] == 'tr': + vWireArea = Box( area.getXCenter(), area.getYCenter() + , area.getXCenter(), area.getYMin () ) + hWireArea = Box( area.getXCenter(), area.getYMin() + , area.getXMin (), area.getYMin() ) + else: + vWireArea = Box( area.getXCenter(), area.getYCenter() ) + hWireArea = vWireArea + vWireArea.inflate( 0, sliceHeight ) + hWireArea.inflate( sliceHeight, 0 ) + trace( 540, '\tQuadTree.isUsedArea(): {} {} of {}\n'.format(rtag,hWireArea,vWireArea,spares.conf.cell) ) trace( 540, '\t{}\n'.format( spares.conf.cellPnR )) - for occurrence in spares.conf.cellPnR.getTerminalNetlistInstanceOccurrencesUnder( centerArea ): - if not isinstance(occurrence.getEntity(),Instance): - continue - instance = occurrence.getEntity() - masterCell = instance.getMasterCell() - if not masterCell.isTerminalNetlist(): - continue - trace( 540, '\t| Overlap {}\n'.format(occurrence.getEntity()) ) - if raiseError: - raise Error%essage( 1, [ 'QuadTree.create(): Unable to create QuadTree under area {}' \ - .format(area) - , 'Area center is under fixed block {}' .format() - ] ) - return True + for treeBox in vWireArea, hWireArea: + for occurrence in spares.conf.cellPnR.getTerminalNetlistInstanceOccurrencesUnder( treeBox ): + if not isinstance(occurrence.getEntity(),Instance): + continue + instance = occurrence.getEntity() + masterCell = instance.getMasterCell() + if not masterCell.isTerminalNetlist(): + continue + if instance.getName().startswith('spare_'): + continue + trace( 540, '\t| Overlap {}\n'.format(occurrence.getEntity()) ) + if raiseError: + raise Error%essage( 1, [ 'QuadTree.create(): Unable to create QuadTree under area {}' \ + .format(area) + , 'Area center is under fixed block {}' .format() + ] ) + return True sys.stdout.flush() sys.stderr.flush() + trace( 540, '\t-> Area is clear.\n' ) return False @staticmethod @@ -305,6 +332,7 @@ def _create ( spares, parent, area, tag, raiseError=False ): if QuadTree.isUsedArea( spares, area, childRtag, raiseError ): return None qt = QuadTree( spares, parent, area, childRtag ) + trace( 540, '\tQuadTree._create(): {}\n'.format(qt) ) return qt def __init__ ( self, spares, parent, area, rtag='root' ):

    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