From ac85c0cca4fc5baab221c0e5f42115b202d8415f Mon Sep 17 00:00:00 2001 From: Jean-Paul Chaput Date: Wed, 4 Dec 2013 00:59:29 +0000 Subject: [PATCH] * ./kite: - New: Whole replacement by Kite3. --- kite/CMakeLists.txt | 5 +- kite/doc/ASIM-bigfonts.css | 353 -- kite/doc/ASIM.css | 485 --- kite/doc/CMakeLists.txt | 5 +- kite/doc/RoutingEvent.dox | 799 +--- kite/doc/Session.dox | 236 +- kite/doc/Track.dox | 782 ++-- kite/doc/TrackSegment.dox | 243 +- kite/doc/asimbook.cls | 798 ---- kite/doc/doxyfile | 48 +- kite/doc/footer.html | 2 +- kite/doc/header.html | 9 +- kite/doc/images/ConflictSolve-1.fig | 96 + kite/doc/images/ConflictSolve-1.png | Bin 0 -> 4012 bytes kite/doc/images/ConflictSolveByHistory-1.fig | 89 + kite/doc/images/ConflictSolveByHistory-1.png | Bin 0 -> 7147 bytes kite/doc/images/ConflictSolveByHistory-2.fig | 116 + kite/doc/images/ConflictSolveByHistory-2.png | Bin 0 -> 9543 bytes kite/doc/images/ConflictSolveByHistory.fig | 93 + kite/doc/images/ConflictSolveByPlaceds-1.fig | 145 + kite/doc/images/ConflictSolveByPlaceds-1.png | Bin 0 -> 9107 bytes kite/doc/images/DataNegociate-1.fig | 145 + kite/doc/images/DataNegociate-1.png | Bin 0 -> 7254 bytes kite/doc/images/DataNegociate-2.fig | 164 + kite/doc/images/DataNegociate-2.png | Bin 0 -> 7889 bytes kite/doc/images/ManipulatorRelax-1.fig | 158 + kite/doc/images/ManipulatorRelax-1.png | Bin 0 -> 11208 bytes kite/doc/images/ManipulatorRelax-2.fig | 163 + kite/doc/images/ManipulatorRelax-2.png | Bin 0 -> 11638 bytes kite/doc/images/ManipulatorRelax-3.fig | 152 + kite/doc/images/ManipulatorRelax-3.png | Bin 0 -> 12516 bytes kite/doc/images/ManipulatorRelax-4.fig | 152 + kite/doc/images/ManipulatorRelax-4.png | Bin 0 -> 12810 bytes kite/doc/images/RoutingEvent-1.fig | 66 - kite/doc/images/RoutingEvent-10.fig | 46 - kite/doc/images/RoutingEvent-11.fig | 124 - kite/doc/images/RoutingEvent-12.fig | 127 - kite/doc/images/RoutingEvent-13.fig | 108 - kite/doc/images/RoutingEvent-14.fig | 110 - kite/doc/images/RoutingEvent-15.fig | 96 - kite/doc/images/RoutingEvent-2.fig | 82 - kite/doc/images/RoutingEvent-3.fig | 98 - kite/doc/images/RoutingPlane-1.fig | 61 + kite/doc/images/RoutingPlane-1.png | Bin 0 -> 5936 bytes kite/doc/images/Track-0.fig | 212 + kite/doc/images/Track-0.png | Bin 0 -> 15385 bytes kite/doc/images/Track-1.fig | 322 +- kite/doc/images/Track-1.png | Bin 6262 -> 11371 bytes kite/doc/images/Track-2.fig | 328 +- kite/doc/images/Track-2.png | Bin 8319 -> 11720 bytes kite/doc/images/Track-3.fig | 165 - kite/doc/images/Track-4.fig | 83 - kite/doc/images/Track-5.fig | 74 - kite/doc/images/TrackBeginIndex-1.fig | 269 ++ kite/doc/images/TrackBeginIndex-1.png | Bin 0 -> 20034 bytes kite/doc/images/TrackEnclosingBounds-1.fig | 269 ++ kite/doc/images/TrackOccupiedInterval-1.fig | 69 + kite/doc/images/TrackOccupiedInterval-1.png | Bin 0 -> 3988 bytes kite/doc/images/TrackSegment-10.fig | 93 + kite/doc/images/TrackSegment-10.png | Bin 0 -> 10096 bytes kite/doc/images/TrackSegment-11.fig | 432 ++ kite/doc/images/TrackSegment-11.png | Bin 0 -> 4053 bytes kite/doc/images/TrackSegmentCost-1.fig | 57 - kite/doc/images/TrackSegmentCost-2.fig | 51 - kite/doc/images/TrackSegmentCost-3.fig | 105 - kite/doc/images/_makeDogleg-10.fig | 271 ++ kite/doc/images/_makeDogleg-10.png | Bin 0 -> 14309 bytes kite/src/BuildPowerRails.cpp | 381 +- kite/src/CMakeLists.txt | 72 +- kite/src/Configuration.cpp | 38 +- kite/src/DataNegociate.cpp | 222 +- kite/src/GraphicKiteEngine.cpp | 375 +- kite/src/HorizontalTrack.cpp | 20 +- kite/src/KiteEngine.cpp | 781 ++-- kite/src/KiteMain.cpp | 44 +- kite/src/Manipulator.cpp | 1412 ++++++ kite/src/NegociateWindow.cpp | 399 +- kite/src/PreProcess.cpp | 312 +- kite/src/ProtectRoutingPads.cpp | 72 +- kite/src/PyGraphicKiteEngine.cpp | 2 +- kite/src/PyKite.cpp | 28 +- kite/src/PyKiteEngine.cpp | 2 +- kite/src/RoutingEvent.cpp | 4061 +----------------- kite/src/RoutingEventHistory.cpp | 27 +- kite/src/RoutingEventLoop.cpp | 25 +- kite/src/RoutingEventQueue.cpp | 150 +- kite/src/RoutingPlane.cpp | 139 +- kite/src/SegmentFsm.cpp | 1241 ++++++ kite/src/Session.cpp | 214 +- kite/src/Track.cpp | 430 +- kite/src/TrackCost.cpp | 61 +- kite/src/TrackElement.cpp | 312 +- kite/src/TrackElements.cpp | 55 +- kite/src/TrackFixedSegment.cpp | 166 +- kite/src/TrackMarker.cpp | 53 +- kite/src/TrackSegment.cpp | 890 ++-- kite/src/TrackSegmentCost.cpp | 16 +- kite/src/Tracks.cpp | 44 +- kite/src/VerticalTrack.cpp | 20 +- kite/src/kite/Configuration.h | 34 +- kite/src/kite/Constants.h | 52 + kite/src/kite/DataNegociate.h | 169 +- kite/src/kite/GraphicKiteEngine.h | 32 +- kite/src/kite/HorizontalTrack.h | 29 +- kite/src/kite/KiteEngine.h | 55 +- kite/src/kite/Manipulator.h | 98 + kite/src/kite/NegociateWindow.h | 64 +- kite/src/kite/PyGraphicKiteEngine.h | 10 +- kite/src/kite/PyKiteEngine.h | 8 +- kite/src/kite/RoutingEvent.h | 215 +- kite/src/kite/RoutingEventHistory.h | 32 +- kite/src/kite/RoutingEventLoop.h | 27 +- kite/src/kite/RoutingEventQueue.h | 40 +- kite/src/kite/RoutingPlane.h | 42 +- kite/src/kite/SegmentFsm.h | 185 + kite/src/kite/Session.h | 53 +- kite/src/kite/Track.h | 116 +- kite/src/kite/TrackCost.h | 32 +- kite/src/kite/TrackElement.h | 329 +- kite/src/kite/TrackElements.h | 60 +- kite/src/kite/TrackFixedSegment.h | 40 +- kite/src/kite/TrackMarker.h | 27 +- kite/src/kite/TrackSegment.h | 219 +- kite/src/kite/TrackSegmentCost.h | 16 +- kite/src/kite/Tracks.h | 35 +- kite/src/kite/VerticalTrack.h | 25 +- 126 files changed, 11012 insertions(+), 12052 deletions(-) delete mode 100644 kite/doc/ASIM-bigfonts.css delete mode 100644 kite/doc/ASIM.css delete mode 100644 kite/doc/asimbook.cls create mode 100644 kite/doc/images/ConflictSolve-1.fig create mode 100644 kite/doc/images/ConflictSolve-1.png create mode 100644 kite/doc/images/ConflictSolveByHistory-1.fig create mode 100644 kite/doc/images/ConflictSolveByHistory-1.png create mode 100644 kite/doc/images/ConflictSolveByHistory-2.fig create mode 100644 kite/doc/images/ConflictSolveByHistory-2.png create mode 100644 kite/doc/images/ConflictSolveByHistory.fig create mode 100644 kite/doc/images/ConflictSolveByPlaceds-1.fig create mode 100644 kite/doc/images/ConflictSolveByPlaceds-1.png create mode 100644 kite/doc/images/DataNegociate-1.fig create mode 100644 kite/doc/images/DataNegociate-1.png create mode 100644 kite/doc/images/DataNegociate-2.fig create mode 100644 kite/doc/images/DataNegociate-2.png create mode 100644 kite/doc/images/ManipulatorRelax-1.fig create mode 100644 kite/doc/images/ManipulatorRelax-1.png create mode 100644 kite/doc/images/ManipulatorRelax-2.fig create mode 100644 kite/doc/images/ManipulatorRelax-2.png create mode 100644 kite/doc/images/ManipulatorRelax-3.fig create mode 100644 kite/doc/images/ManipulatorRelax-3.png create mode 100644 kite/doc/images/ManipulatorRelax-4.fig create mode 100644 kite/doc/images/ManipulatorRelax-4.png delete mode 100644 kite/doc/images/RoutingEvent-1.fig delete mode 100644 kite/doc/images/RoutingEvent-10.fig delete mode 100644 kite/doc/images/RoutingEvent-11.fig delete mode 100644 kite/doc/images/RoutingEvent-12.fig delete mode 100644 kite/doc/images/RoutingEvent-13.fig delete mode 100644 kite/doc/images/RoutingEvent-14.fig delete mode 100644 kite/doc/images/RoutingEvent-15.fig delete mode 100644 kite/doc/images/RoutingEvent-2.fig delete mode 100644 kite/doc/images/RoutingEvent-3.fig create mode 100644 kite/doc/images/RoutingPlane-1.fig create mode 100644 kite/doc/images/RoutingPlane-1.png create mode 100644 kite/doc/images/Track-0.fig create mode 100644 kite/doc/images/Track-0.png delete mode 100644 kite/doc/images/Track-3.fig delete mode 100644 kite/doc/images/Track-4.fig delete mode 100644 kite/doc/images/Track-5.fig create mode 100644 kite/doc/images/TrackBeginIndex-1.fig create mode 100644 kite/doc/images/TrackBeginIndex-1.png create mode 100644 kite/doc/images/TrackEnclosingBounds-1.fig create mode 100644 kite/doc/images/TrackOccupiedInterval-1.fig create mode 100644 kite/doc/images/TrackOccupiedInterval-1.png create mode 100644 kite/doc/images/TrackSegment-10.fig create mode 100644 kite/doc/images/TrackSegment-10.png create mode 100644 kite/doc/images/TrackSegment-11.fig create mode 100644 kite/doc/images/TrackSegment-11.png delete mode 100644 kite/doc/images/TrackSegmentCost-1.fig delete mode 100644 kite/doc/images/TrackSegmentCost-2.fig delete mode 100644 kite/doc/images/TrackSegmentCost-3.fig create mode 100644 kite/doc/images/_makeDogleg-10.fig create mode 100644 kite/doc/images/_makeDogleg-10.png create mode 100644 kite/src/Manipulator.cpp create mode 100644 kite/src/SegmentFsm.cpp create mode 100644 kite/src/kite/Constants.h create mode 100644 kite/src/kite/Manipulator.h create mode 100644 kite/src/kite/SegmentFsm.h diff --git a/kite/CMakeLists.txt b/kite/CMakeLists.txt index 35f5786f..ca5985a6 100644 --- a/kite/CMakeLists.txt +++ b/kite/CMakeLists.txt @@ -1,3 +1,4 @@ +# -*- explicit-buffer-name: "CMakeLists.txt" -*- project(KITE) @@ -40,6 +41,6 @@ add_subdirectory(src) add_subdirectory(cmake_modules) - if(BUILD_DOC AND DOXYGEN_FOUND AND IS_DIRECTORY doc) + if(BUILD_DOC AND DOXYGEN_FOUND) add_subdirectory(doc) - endif(BUILD_DOC AND DOXYGEN_FOUND AND IS_DIRECTORY doc) + endif(BUILD_DOC AND DOXYGEN_FOUND) diff --git a/kite/doc/ASIM-bigfonts.css b/kite/doc/ASIM-bigfonts.css deleted file mode 100644 index f8ec6823..00000000 --- a/kite/doc/ASIM-bigfonts.css +++ /dev/null @@ -1,353 +0,0 @@ - - -/* - * x-----------------------------------------------------------------x - * | HTML Standart Tags | - * x-----------------------------------------------------------------x - */ - - html, body, th, td, tr, p, li, h1, h2, h3, h4, h5, h6 { - font-size: 100%; - font-family: verdana, sans-serif; - } - - body { - color: black; - background: white; - background-color: white; - background-position: top left; - background-attachment: fixed; - background-repeat: no-repeat; - margin-top: 2em; - margin-right: 10%; - margin-left: 10%; - } - - hr { - height: 1px; - border: 0; - color: #004400; - background-color: #004400; - } - - - h1, h2, h3, h4, h5, h6 { - font-family: verdana, sans-serif; - } - - h1 { text-align: center; } - h2, h3, h4, h5, h6 { text-align: left; - padding-top: 2em; - } - h1, h2, h3 { font-family: "Trebuchet MS", sans-serif; - color: #09550B; - } - h1 { font-weight: bold; font-size: 170%; } - h2 { font-weight: bold; font-size: 140%; } - h3 { font-weight: bold; font-size: 118%; } - h4 { font-weight: bold; font-size: 100%; } - h5 { font-style: italic; font-size: 100%; } - h6 { font-variant: small-caps; font-size: 100%; } - - .hide { - display: none; - color: white; - } - - - p { - margin-top: 0.6em; - margin-bottom: 0.6em; - margin-left: 0.0em; - margin-right: 0.0em; - } - - - address { - text-align: right; - font-weight: bold; - font-style: italic; - font-size: 80%; - } - - - caption { font-weight: bold } - - - blockquote { - margin-left: 4em; - margin-right: 4em; - margin-top: 0.8em; - margin-bottom: 0.8em; - font-style: italic; - color: #003300; - } - - blockquote p { - margin-bottom: 0; - } - - blockquote address { - margin: 0; - } - - - table { - border-collapse: collapse; - } - - dt, dd { margin-top: 0; margin-bottom: 0; } - dt { font-weight: bold; } - - - pre, tt, code { - font-family: "andale mono", monospace; - font-size: 100%; - white-space: pre; - } - - pre { - font-size: 80%; - border: solid; - border-width: thin; - border-color: #003300; - background-color: #EEEEEE; - padding: 0.5em; - margin-left: 2em; - margin-right: 2em - } - - tt { color: green; } - em { font-style: italic; font-weight: bold; } - strong { font-weight: bold; } - - span.textit { font-style: italic; } - span.textbf { font-weight: bold; } - - .small { font-size: 90%; } - .white { color: #FFFFFF; } - - - ul.toc { - list-style: disc; - list-style: none; - } - - - a:link img, a:visited img { border-style: none; } - a img { color: white; } - - a:link, a:active, a:visited { - color: #09550B; - text-decoration: none; - } - - a:hover, a:focus { - color: #FF9900; - text-decoration: underline; - } - - - - -/* - * x-----------------------------------------------------------------x - * | Doxygen Specific Classes | - * x-----------------------------------------------------------------x - */ - - -/* ------------------------------------------------------------------- - * Header & Footer Classes (customized top page navigation bar). - */ - - table.header { - width: 100%; - /*background-color: #EEEEEE;*/ - background-color: #CCE6CA; - } - - h1.header { - font-family: times, verdana, sans-serif; - } - - td.header { - /*width: 14%;*/ - text-align: center; - font-weight: bold; - font-family: verdana, sans-serif; - } - - table.footer { - width: 100%; - } - - td.leftFoot1, td.leftFoot2 { - text-align: left; - } - - td.rightFoot1, td.rightFoot2 { - text-align: right; - } - - td.leftFoot2 { - font-family: time; - font-weight: bold; - } - - td.rightFoot2 { - font-weight: bold; - } - - div.ah { - font-family: time; - font-size: 250%; - } - - -/* ------------------------------------------------------------------- - * Quick Index Class (top page navigation bar). - */ - - div.qindex, div.nav { - width: 100%; - /*background-color: #DADAEF;*/ - /*background-color: #eeeeff;*/ - /*background-color: #EEEEEE;*/ - background-color: #CCE6CA; - border: 1px solid #003300; - text-align: center; - margin: 2px; - padding: 2px; - line-height: 140%; - } - - a.qindex, a.qindex:visited, a.qindex:hover, a.qindexHL, a.el, a.elRef { - text-decoration: none; - font-weight: bold; - } - - a.qindex, a.qindex:visited { - color: #09550B; - } - - a.qindex:hover { - background-color: #ddddff; - } - - a.qindexHL, a.qindexHL:hover, a.qindexHL:visited { - background-color: #0c780c; - color: #ffffff; - border: 1px double #9295C2; - } - - a.code:link, a.code:visited, a.codeRef:link, a.codeRef:visited { - text-decoration: none; - font-weight: normal; - color: #0000ff; - } - - .indexkey { - background-color: #eeeeff; - border: 1px solid #b0b0b0; - padding: 2px 15px; - } - - .indexkey, .indexvalue { - background-color: #eeeeff; - border: 1px solid #b0b0b0; - padding: 2px 15px; - } - - .indexkey { - width: 40%; - } - - .indexvalue { - width: 80%; - } - - -/* ------------------------------------------------------------------- - * Verbatim Source Code / Examples. - */ - - pre.fragment { background-color: #EEEEEE; } - - span.keyword { color: #008000 } - span.keywordtype { color: #604020 } - span.keywordflow { color: #e08000 } - span.comment { color: #800000 } - span.preprocessor { color: #806020 } - span.stringliteral { color: #002080 } - span.charliteral { color: #008080 } - - -/* ------------------------------------------------------------------- - * Attributes Listing. - */ - - .mdTable { - /*border: 1px solid #868686;*/ - /*background-color: #DADAEF;*/ - /*background-color: #F4F4FB;*/ - border: 1px none #868686; - /*background-color: #B8E6B8;*/ - background-color: #CCE6CA; - margin-top: 25px; - } - - .mdRow { - padding: 5px 10px; - } - - /* This Mozilla/Firefox bug has been corrected from v1.5. - * .mdname1 { - * padding: 3px 0px 0px 0px; - * } - */ - - .mdescLeft, .mdescRight { - padding: 0px 8px 4px 8px; - font-size: 12px; - font-style: italic; - /*background-color: #FAFAFA;*/ - border-top: 1px none #E0E0E0; - border-right: 1px none #E0E0E0; - border-bottom: 1px none #E0E0E0; - border-left: 1px none #E0E0E0; - margin: 0px; - } - - .memItemLeft, .memItemRight, .memTemplItemLeft { - padding: 1px 0px 0px 8px; - margin: 4px; - border-top-width: 1px; - border-right-width: 1px; - border-bottom-width: 1px; - border-left-width: 1px; - border-top-color: #0c0c0c; - border-right-color: #0c0c0c; - border-bottom-color: #0c0c0c; - border-left-color: #0c0c0c; - border-top-style: solid; - border-right-style: none; - border-bottom-style: none; - border-left-style: none; - /*background-color: #DADAEF;*/ - /*background-color: #eeeeff;*/ - /*background-color: #EEEEEE;*/ - background-color: #CCE6CA; - } - - .memItemLeft { font-size: 12px; } - .memItemRight { font-size: 13px; } - .memTemplItemLeft { font-size: 12px; } - .memTemplItemRight { font-size: 13px; } - - .memTemplParams { - color: #606060; - background-color: #DADAEF; - font-size: 12px; - } - diff --git a/kite/doc/ASIM.css b/kite/doc/ASIM.css deleted file mode 100644 index 6d92a0c5..00000000 --- a/kite/doc/ASIM.css +++ /dev/null @@ -1,485 +0,0 @@ - - -/* - * x-----------------------------------------------------------------x - * | HTML Standart Tags | - * x-----------------------------------------------------------------x - */ - - html, body, th, td, tr, p, li, h1, h2, h3, h4, h5, h6 { - font-size: 96%; - font-family: verdana, sans-serif; - } - - body { - color: black; - background: white; - background-color: white; - background-position: top left; - background-attachment: fixed; - background-repeat: no-repeat; - margin-top: 2em; - margin-right: 8%; - margin-left: 8%; - } - - hr { - height: 1px; - border: 0; - color: #004400; - background-color: #004400; - } - - - h1, h2, h3, h4, h5, h6 { - font-family: verdana, sans-serif; - } - - h1 { text-align: center; } - h2, h3, h4, h5, h6 { text-align: left; - padding-top: 2em; - } - h1, h2, h3 { font-family: "Trebuchet MS", sans-serif; - color: #09550B; - } - h1 { font-weight: bold; font-size: 170%; } - h2 { font-weight: bold; font-size: 140%; } - h3 { font-weight: bold; font-size: 118%; } - h4 { font-weight: bold; font-size: 100%; } - h5 { font-style: italic; font-size: 100%; } - h6 { font-variant: small-caps; font-size: 100%; } - - h2.classHierarchy { - /*border: 1px none #008500;*/ - border: 1px none #000000; - border-top-width: 2px; - border-top-style: solid; - padding-top: 1em; - } - - - .hide { - display: none; - color: white; - } - - - p { - margin-top: 0.6em; - margin-bottom: 0.6em; - margin-left: 0.0em; - margin-right: 0.0em; - } - - - address { - text-align: right; - font-weight: bold; - font-style: italic; - font-size: 80%; - } - - - caption { font-weight: bold } - - - blockquote { - margin-left: 4em; - margin-right: 4em; - margin-top: 0.8em; - margin-bottom: 0.8em; - font-style: italic; - color: #003300; - } - - blockquote p { - margin-bottom: 0; - } - - blockquote address { - margin: 0; - } - - - table { - border-collapse: collapse; - } - - dt, dd { margin-top: 0; margin-bottom: 0; } - dt { font-weight: bold; } - - - pre, tt, code { - font-family: "andale mono", monospace; - font-size: 100%; - white-space: pre; - } - - pre { - font-size: 80%; - border: dashed; - border-width: thin; - border-color: #003300; - /* - background-color: #EEEEEE; - */ - background-color: #FCFCE1; - padding: 0.5em; - margin-left: 2em; - margin-right: 2em - } - - tt { color: green; } - em { font-style: italic; - font-weight: bold; } - strong { font-weight: bold; } - - span.textit { font-style: italic; } - span.textbf { font-weight: bold; } - - .small { font-size: 90%; } - .white { color: #FFFFFF; } - - - ul.toc { - list-style: disc; - list-style: none; - } - - - a:link img, a:visited img { border-style: none; } - a img { color: white; } - - a:link, a:active, a:visited { - color: #09550B; - text-decoration: none; - } - - a:hover, a:focus { - color: #FF9900; - text-decoration: underline; - } - - - - -/* - * x-----------------------------------------------------------------x - * | Doxygen Specific Classes | - * x-----------------------------------------------------------------x - */ - - -/* ------------------------------------------------------------------- - * Header & Footer Classes (customized top page navigation bar). - */ - - h1.header { - font-size: 200%; - font-family: times, verdana, sans-serif; - } - - center.header { - background-color: #CCE6CA; - } - - table.header { - /*width: 100%;*/ - /*background-color: #EEEEEE;*/ - background-color: #CCE6CA; - } - - table.header td { - padding: 2px 14px; - text-align: center; - font-weight: bold; - font-family: verdana, sans-serif; - font-size: 110%; - } - - table.footer1, table.footer2 { width: 100%; } - td.LFooter { text-align: left; } - td.RFooter { text-align: right; } - td.CFooter { text-align: center;} - table.footer2 td.RFooter { font-weight: bold; width: 35% } - table.footer2 td.CFooter { width: 30% } - table.footer2 td.LFooter { font-weight: bold; width: 35%; font-family: time; } - - table.classHierarchy { - border-collapse: separate; - border-spacing: 5px; - font-size: 110%; - } - - table.classHierarchy tr { - border: 1px solid blue; - } - - table.classHierarchy td.normal { - border: 1px solid #CCE6CA; - width: 140pt; - text-align: center; - font-weight: bold; - background-color: #CCE6CA; - } - - table.classHierarchy td.virtual { - border: 1px solid black; - width: 140pt; - text-align: center; - font-weight: bold; - } - - table.classHierarchy td.wnormal { - border: 1px solid #CCE6CA; - width: 240pt; - text-align: center; - font-weight: bold; - background-color: #CCE6CA; - } - - table.classHierarchy td.wvirtual { - border: 1px solid black; - width: 240pt; - text-align: center; - font-weight: bold; - } - - div.ah { - font-family: time; - font-size: 250%; - } - - -/* ------------------------------------------------------------------- - * Quick Index Class (top page navigation bar). - */ - - div.qindex, div.nav { - width: 100%-4px; - /*background-color: #DADAEF;*/ - /*background-color: #eeeeff;*/ - /*background-color: #EEEEEE;*/ - background-color: #CCE6CA; - border: 0px solid #003300; - text-align: center; - margin: 0px; - padding: 2px; - line-height: 140%; - } - - a.qindex, a.qindex:visited, a.qindex:hover, a.qindexHL, a.el, a.elRef { - text-decoration: none; - font-weight: bold; - } - - a.qindex, a.qindex:visited { - color: #09550B; - } - - a.qindex:hover { - background-color: #ddddff; - } - - a.qindexHL, a.qindexHL:hover, a.qindexHL:visited { - background-color: #0c780c; - color: #ffffff; - border: 1px double #9295C2; - } - - a.code:link, a.code:visited, a.codeRef:link, a.codeRef:visited { - text-decoration: none; - font-weight: normal; - color: #0000ff; - } - - .indexkey { - background-color: #eeeeff; - border: 1px solid #b0b0b0; - padding: 2px 15px; - } - - .indexkey, .indexvalue { - background-color: #eeeeff; - border: 1px solid #b0b0b0; - padding: 2px 15px; - } - - .indexkey { - width: 40%; - } - - .indexvalue { - width: 80%; - } - - h3 a[name="index__"], - h3 a[name="index_a"], - h3 a[name="index_b"], - h3 a[name="index_c"], - h3 a[name="index_d"], - h3 a[name="index_e"], - h3 a[name="index_f"], - h3 a[name="index_g"], - h3 a[name="index_h"], - h3 a[name="index_i"], - h3 a[name="index_j"], - h3 a[name="index_k"], - h3 a[name="index_l"], - h3 a[name="index_m"], - h3 a[name="index_n"], - h3 a[name="index_o"], - h3 a[name="index_p"], - h3 a[name="index_q"], - h3 a[name="index_r"], - h3 a[name="index_s"], - h3 a[name="index_t"], - h3 a[name="index_u"], - h3 a[name="index_v"], - h3 a[name="index_w"], - h3 a[name="index_x"], - h3 a[name="index_y"], - h3 a[name="index_z"], - h3 a[name="index_0"], - h3 a[name="index_1"], - h3 a[name="index_2"], - h3 a[name="index_3"], - h3 a[name="index_4"], - h3 a[name="index_5"], - h3 a[name="index_6"], - h3 a[name="index_7"], - h3 a[name="index_8"], - h3 a[name="index_9"] - { - font-family: time; - font-size: 250%; - } - - -/* ------------------------------------------------------------------- - * Verbatim Source Code / Examples. - */ - - /* pre.fragment { background-color: #EEEEEE; } */ - - span.keyword { color: #008000 } - span.keywordtype { color: #604020 } - span.keywordflow { color: #e08000 } - span.comment { color: #800000 } - span.preprocessor { color: #806020 } - span.stringliteral { color: #002080 } - span.charliteral { color: #008080 } - - -/* ------------------------------------------------------------------- - * Attributes Listing. - */ - - .mdTable { - /*border: 1px solid #868686;*/ - /*background-color: #DADAEF;*/ - /*background-color: #F4F4FB;*/ - border: 1px none #008500; - border-left-width: 1px; - border-left-style: solid; - /*background-color: #B8E6B8;*/ - /*background-color: #CCE6CA;*/ - margin-top: 25px; - font-size: 105%; - } - - .mdRow { - padding: 5px 10px; - } - - /* This Mozilla/Firefox bug has been corrected from v1.5. - * .mdname1 { - * padding: 3px 0px 0px 0px; - * } - */ - - .mdescLeft, .mdescRight { - padding: 0px 8px 4px 8px; - font-size: 11px; - font-style: italic; - /*background-color: #FAFAFA;*/ - border-top: 1px none #E0E0E0; - border-right: 1px none #E0E0E0; - border-bottom: 1px none #E0E0E0; - border-left: 1px none #E0E0E0; - margin: 0px; - } - - .memitem { - margin-bottom: 30px; - border: 1px none #008500; - } - - .memproto { - background-color: #CCE6CA; - border-left-width: 4px; - border-left-style: solid; - border-color: #008500; - } - - .memname { - white-space: nowrap; - padding-left: 5px; - font-size: 105%; - } - - - .memdoc{ - padding-left: 5px; - /*margin-top: -8px;*/ - border-left-width: 1px; - border-left-style: solid; - border-color: #008500; - } - - .memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight { - padding: 1px 0px 0px 8px; - margin: 4px; - border-top-width: 1px; - border-right-width: 1px; - border-bottom-width: 1px; - border-left-width: 1px; - border-top-color: #0c0c0c; - border-right-color: #0c0c0c; - border-bottom-color: #0c0c0c; - border-left-color: #0c0c0c; - border-top-style: solid; - border-right-style: none; - border-bottom-style: none; - border-left-style: none; - /*background-color: #DADAEF;*/ - /*background-color: #eeeeff;*/ - /*background-color: #EEEEEE;*/ - background-color: #CCE6CA; - } - - .memTemplItemLeft, .memTemplItemRight { - border-bottom-width: 2px; - border-bottom-style: solid; - font-weight: bold; - } - - .memItemLeft { font-size: 11px; } - .memItemRight { font-size: 12px; } - .memTemplItemLeft { font-size: 11px; } - .memTemplItemRight { font-size: 12px; } - - .memTemplParams { - color: #FFFFFF; - background-color: #000000; - font-size: 11px; - font-weight: bold; - } - - .groupText, .groupHeader { - color: #09550B; - margin-top: 15px; - font-size: 130%; - font-weight: bold; - } - diff --git a/kite/doc/CMakeLists.txt b/kite/doc/CMakeLists.txt index 0e41c9e0..29be9b3d 100644 --- a/kite/doc/CMakeLists.txt +++ b/kite/doc/CMakeLists.txt @@ -1,3 +1,4 @@ +# -*- explicit-buffer-name: "CMakeLists.txt" -*- set ( htmlInstallDir share/doc/coriolis2/en/html/kite ) set ( latexInstallDir share/doc/coriolis2/en/latex/kite ) @@ -5,8 +6,8 @@ add_custom_target ( doc ALL cd ${KITE_SOURCE_DIR}/doc && ${DOXYGEN_EXECUTABLE} doxyfile ) install ( DIRECTORY html/ DESTINATION ${htmlInstallDir} ) -# install ( FILES customHierarchy.html DESTINATION ${htmlInstallDir} ) -# install ( FILES customSummary.html DESTINATION ${htmlInstallDir} ) + install ( FILES customHierarchy.html DESTINATION ${htmlInstallDir} ) + install ( FILES customSummary.html DESTINATION ${htmlInstallDir} ) install ( DIRECTORY latex/ DESTINATION ${latexInstallDir} ) install ( FILES asimbook.cls DESTINATION ${latexInstallDir} ) diff --git a/kite/doc/RoutingEvent.dox b/kite/doc/RoutingEvent.dox index 031e85e6..e95601a6 100644 --- a/kite/doc/RoutingEvent.dox +++ b/kite/doc/RoutingEvent.dox @@ -1,597 +1,246 @@ - // -*- C++ -*- namespace Kite { + /*! \class RoutingEvent::Key + * \brief RoutingEvent cached key for maps + * + * The key is used as a cache in RoutingEvent, that is, the RoutingEvent + * attributes could be modificated without the key changing. It is + * important for the key to remain stable as it used in the various + * event queue as the sorting attribute. The key should be updated + * only when the RoutingEvent is temporarily whidrawn from the queue. + * + * Cached attributes: (used in that lexicographical order for sorting) + * - \b 1 -- \c eventLevel. + * - \b 2 -- \c canRipple. + * - \b 3 -- \c priority. + * - \b 4 -- \c length. + * - \b 5 -- \c isHorizontal. + * - \b 6 -- \c axis. + * - \b 7 -- \c sourceU. + * - \b 8 -- \c net (name). + * - \b 9 -- \c id. + * - \b X -- \c slackenStrap \b unused. + * - \b X -- \c tracksNb \b unused. + * + * It is internally managed by RoutingEvent and the queue. + */ + + //! \function RoutingEvent::Key::update ( const RoutingEvent* event ); + //! Cache the value of the key from \c event. + /*! \class RoutingEvent - * \brief Manage TrackSegment routing requests. + * \brief Atomic Placement Request for a TrackSegment * - * The \RoutingEvent is the workhorse of Kite. A \RoutingEvent is - * associated to one \TrackSegment. One \TrackSegment could be - * associated to many \RoutingEvent in the queue, but only one - * of those is active (marked as unprocessed). + * \red{The trackFrees attribute has to be reviewed not sure it's still useful.} * - * \see ClassManipulator. - * - * \section secProcessAlgorithm Description of the process() method - * -\code -void RoutingEvent::process () -{ - if ( isProcessed() ) return; - setProcessed (); - incRipupCount (); - - if ( getRipupCount() > MAX_RIPUP_COUNT ) { - // We are *not* in ripup mode. - // The event's segment has to be topologically modified. - modifyTopology ( _segment ); - } else { - // We are in ripup mode. - // Other overlaping segments are to be removeds/pusheds. It can result in - // segment breaking *if* other segment came from an already routed GCell. - - // optimal, constraint, perpandicular. - computeAllIntervals (); - - // Find & order all candidates Tracks. - candidates = computeCostOnCandidateTracks (); - sort ( candidates ); - - if ( candidates[0].isFree() ) { - // Case -A.1- "Free Track". - candidate[0].insert ( _segment ); - } else if ( candidates[0].isSoftOverlap() - || candidates[0].isHardOverlap() ) { - // Case -A.2- "Soft Overlap". - // Case -A.3- "Hard Overlap". - for ( size_t i=0 ; i - *
  • New \c isLocal() method on \TrackSegment. Tells if the \TrackSegment - * is associated only to local AutoSegment. - *
  • Increase the overlap cost of a \TrackSegment from an already routed - * GCell routing set. - * - * - * - * \section secRoutingEventInterval The various intervals of a RoutingEvent - * - * The three Intervals controlling a RoutingEvent : all those intervals - * defines the track range in which the \TrackSegment could be inserted. - *
      - *
    • The optimal interval : where the \Net wirelength will be - * minimal (comes from \c Katabatic::AutoSegment). - *
    • The constraint interval : the interval outside of which - * the \Net connexity would be broken. This is the bigger interval - * but it must be strictly respected (also comes from - * \c Katabatic::AutoSegment). - *
    • The perpandicular interval : for each perpandicular - * \TrackSegment connected, the intersection of the free interval - * around them in their track. - * - * It is important to note that the \TrackSegment overlaping in the - * target track is not removed from the track. It is it's perpandiculars - * which are, along with a modification of theirs left axis weight and/or - * right axis weight. - * - * Second remark: no overlap will be created (due to the non-removal of - * overlaping \TrackSegments) because the insertion is delayed in case - * of overlap. - *
    - * The perpandicular interval comes from perpandicular constraints on \TrackSegment - * of the same \c Net. The left/right axis weights comes from requests of - * other \c Nets. - * - * \image html RoutingEvent-1.png "RoutingEvent Intervals" - * \image latex RoutingEvent-1.pdf "RoutingEvent Intervals" width=0.6\textwidth - * - * Example of perpandicular interval computation : - * - * \image html RoutingEvent-2.png "Perpandicular Interval" - * \image latex RoutingEvent-2.pdf "Perpandicular Interval" - * - * - * \section secRoutingEventRules Rules governing RoutingEvents - * - * \RoutingEvent respect the following rules: - *
      - *
    • A \TrackSegment can only be displaced by it's associated \RoutingEvent. - *
    • Corollary: the only \TrackSegment displaced while processing a - * \RoutingEvent is the one associated to the event. - *
    • Conflicts occurs between the \RoutingEvent \TrackSegment and already - * placed others \TrackSegment. - * - * The conflict can be solved by displacing/modifying others - * \TrackSegment or by modifying the to be inserted one. In the later - * case, the newly created or modified \TrackSegment are (re)scheduleds - * before the would be inserted. - *
    • Conflicting \TrackSegments are only removed from their \Track - * but their axis remains unchanged. Movement requests are passed - * through increase of the left/right axis weights, if needed. - *
    • \TrackSegment are inserted only, and only if there is enough free space. - * That is, if any kind of overlap occurs, it is not inserted - * but rescheduled. The blocking \TrackSegments are then - * rescheduled after the current one. - *
    • Each \RoutingEvent processing takes place inside a one atomic - * Session. That is, the coherency of the data-base is restored - * immediatly afterward (both Kite & Katabatic). - *
    - * - * \remark Be very careful to distinguish between Session commands, which affects - * \Track and \TrackSegment insertion/update/removal and schedule/re-schedule - * events, which relates to the negociation algorithm. - * - * Re-ordering rules: - *
      - *
    1. In normal mode, that is, no maximum ripup has been reached, the - * blocking other \TrackSegment are removed and the current - * is rescheduled before them. - *
    2. In maximum ripup mode, some \TrackSegment has to give way. - *
        - *
      • If the current one is modified, it must be rescheduled after - * it's modified bits are rescheduleds. - *
      • If others are modifieds they must be rescheduled after - * the current one (so it will grabs the place). - *
      - *
    - * - * - * \section secRoutingEventCycle RoutingEvent life cycle - * - * As an active \RoutingEvent is associated with one and only one \TrackSegment - * we can talk indeferently of \RoutingEvent lifecycle or \TrackSegment - * lifecycle. - * - * Below is the ordered list of states that a \RoutingEvent could be in. - * The order correspond to increasing level of slackening/freedom. - * Transition between states occurs each time a maximum ripup is reached. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
     \b Id \b Type \b Local  \b Global \b Action
    \e 1\c Minimize\e yes\e notry to fit into a hole
    \e 2\c DogLeg\e yes\e noDogleg : analyse overlap and try to solve it by breaking (self)
    \e 3\c Desalignate\e yes\e yeson a set of alignated \TrackSegment, suppress the - * alignment constraints, thus making then independants - *
    \e 4\c Slacken\e yes\e yesif the target/source constraint is less than the - * GCell, adds perpandicular straps to free the \TrackSegment. - * This occurs to free from terminal constraints - *
    \e 5\c ConflictSolve1\e yes\e yestry to find in the history a reccurent dislodger, - * and break (self) to accomodate it - *
    \e 6\c ConflictSolve2\e no\e yestry to find a Track on which we can dislodge - * an other \TrackSegment - *
    \e 7\c MoveUp\e no\e yestry to go on upper layer. - *
    \e 8\c Unimplemented\e no\e yeswe failed to place this \TrackSegment - *
    - * - * - * \section secManageMaximumRipup Managing the maximum ripup case - * -\code -bool State::manageMaximumRipup () -{ - bool success = false; - - if ( !_segment->isGlobal() ) { - // Candidates Tracks (ignore optimal & perpandiculars). - candidates = computeAllIntervals (); - overlap = _segment->getInterval(); - - for ( size_t i=0 ; i reject. - // Local vs. Terminal => reject. - if ( others[0]->isLocal() || others[0]->isTerminal() ) continue; - - // Local vs. Global (not routed yet). - if ( others[i]->getOrder() >= _segment->getOrder() ) { - success = modifyTopology(others[0]); - break; - } - - // Local vs. Global (already routed). - success = relax(_others[0],overlap); - if ( success ) break; - } - } - } - - if ( !success ) { - // Global vs. Local. - // Failed Local vs. Any. - success = modifyTopology(_segment); - } - return success; -} -\endcode - * - * - * \section secModifyTopology Description of the modifyTopology() method - * -\code -bool Manipulator::modifyTopology ( TrackSegment* segment ) -{ - bool success = false; - - if ( segment->isLocal() ) { - if ( segment->canMinimize() { - segment->minimize(); - success = true; - } - if ( segment->canDogLeg() ) { - // Case -C.4- "Self Relax". - segment->makeDogLeg(); - success = true; - } - } else if ( segment->canDesalignate() ) { - // Case -C.5- "Desalignate". - segment->desalignate(); - success = true; - } else if ( segment->canSlacken() ) { - // Case -C.6- "Slacken". - segment->slacken(); - success = true; - } else { - RipupHistory* history = RipupHistory(segment); - GCell* dogLegGCell = history.getDogLegGCell(); - - if ( dogLegGCell ) { - if ( segment->canDogLegAt(dogLegGCell) ) { - segment->makeDogLeg(dogLegGCell) - success = true; - } - } else { - // Dislodgers seems to far in ripup history. - // Recheck the Track, maybe they have vanish. - Track* track = getTrack(segment); - if ( track->getFreeInterval(segment) ) { - track.insert ( segment ); - success = true; - } - } - } - - if ( segment->canMoveUp() ) { - segment->moveUp (); - success = true; - } - - if ( success ) { - resetRipupCount(segment); - } else { - cerr << "[UNIMPLEMENTED] " << segment << endl; - } - - return success; -} -\endcode - * - * - * \section secHardSoftOverlap Hard and soft overlap - * - * Schematic execution of a \RoutingEvent leading to a set aside. - *
      - *
    1. The scheduler try to place the \TrackSegment on top of the - * event queue, calling process(). - *
    2. There is a soft overlap on the best candidate track, a set - * aside is issued. - *
    3. Each \TrackSegment in conflict in the candidate track has the - * \RoutingEvent bounds of it's perpandicular \TrackSegment modificated - * according to the free space requested through setLeftBound() or setRightBound(). - *
    4. If a perpandicular is already in a \Track is removed from it and scheduled for - * immediate re-routing (it's event level is increased so it pops - * out immediately from the queue). - *
    5. If the perpandicular is not routed yet, we are done. - * - * Note that this technique of modificating a \RoutingEvent yet to come is - * kind a like seeing the future... - *
    - * - * \image html RoutingEvent-3.png "Set aside schematic" - * \image latex RoutingEvent-3.pdf "Set aside schematic" - * - * - * \section setDetructionStrategy Destruction Strategy - * - * \RoutingEvent are not destroyed as soon as they have been processed by - * the scheduler. Instead, they are stored in the historical queue. - * They are two reasons for that behavior : - *
      - *
    • \RoutingEvent are used to store algorithmic informations that - * must persist until the negociation algorithm have fully - * completed (bound interval in particular). - *
    • When ripup phases takes place and maximum ripup count is - * reached, the history can be used to find the whole set of - * \TrackSegment in conflict an made an educated guess about - * which one must be relaxed. - *
    - * - * \important This is the history queue which is responsible for freeing all the - * \RoutingEvent in his destructor. - * - * - * \section secRoutingEventCase Routing Event actions - * - *
      - *
    • Free Track Case - * - * There is a sufficent free space in the candidate \Track to insert the - * \TrackSegment. The \TrackSegment is inserted. - * - * \important This is the only way for a \TrackSegment to be inserted into a \Track. - * - * \image html RoutingEvent-10.png - * \image latex RoutingEvent-10.pdf - * - * - *
    • Soft Overlap Case - * - * Already inserted \TrackSegment a & b could be shrunk - * to make place for \TrackSegment c. Parallel overlaping \TrackSegment - * are not removed, their perpandiculars are with updated left/right axis weight. - * - * The a perpandicular belongs the same GCell routing set so it - * is removed from is \Track to be displaced. - * - * The b perdandicular belongs to a more prioritary GCell routing - * set, which has therefore be placed earlier so it can't be removed. - * Instead it is broken. - * - * \image html RoutingEvent-11.png - * \image latex RoutingEvent-11.pdf - * - * - *
    • Hard Overlap Case - * - * No way to shrunk overlaping \TrackSegment to make place for c. - * All parallel overlaping \TrackSegments must be removeds to be displaced - * on other \Tracks. - * - * The a parallel belongs to a more prioritary GCell routing set - * so it can be removed, it is therefore broken. - * - * The b parallel belongs the same GCell routing set so it can be - * removed to be displaced. - * - * \image html RoutingEvent-12.png - * \image latex RoutingEvent-12.pdf - * - * - *
    • Self Relax - * - * Instead of trying to displace overlaping \TrackSegments we break the - * current one. - * - * \image html RoutingEvent-13.png - * \image latex RoutingEvent-13.pdf - * - * - *
    • Self Desalignate - * - * Instead of trying to displace overlaping \TrackSegments we desalignate - * it's components (by supressing alignement constraints on it's - * AutoContacts). We do not create new Katabatic components but new - * \TrackSegments will appears. - * - * \image html RoutingEvent-14.png - * \image latex RoutingEvent-14.pdf - * - * - *
    • Self Slacken - * - * Instead of trying to displace overlaping \TrackSegments we slacken - * the current one. This is different than desalignate because we create - * new Katabatic component to relax any AutoContact transmitted constraints. - * This operation is most likely to be applied on \TrackSegments that are - * directly connecteds to terminals. - * - * \image html RoutingEvent-15.png - * \image latex RoutingEvent-15.pdf - * - *
    + * Cached key for stable sorting, see RoutingEvent::Key. */ - /*! \function bool RoutingEvent::isProcessed () const; - * \return \true if this event has already been processed. - * - * \remark Note that inside a _setAside() a \RoutingEvent can be re-posted for - * a given \TrackSegment which has been processed yet. This can lead - * to two or more \RoutingEvent in the queue (as we cannot easily remove - * a \RoutingEvent already in the queue). We need this new \RoutingEvent - * because we want to reschedule with a new priority/slack. - * As we cannot remove the previous \RoutingEvent, we mark it as - * processed for it to be ignored by the scheduler. + //! \enum RoutingEvent::Mode + //! The working mode of the router, affect how events are to + //! be handled. + + //! \var RoutingEvent::Negociate + //! This is the normal mode of operation, topological modifications + //! and ripup are enableds. + + //! \var RoutingEvent::Pack + //! First post-processing step. For each segment, tries to find a + //! more compact position for a segment, but without riping any others. + + //! \var RoutingEvent::Repair + //! Second post-processing step, try to find a suitable location for + //! a segment more aggressively. + + //! \function unsigned int RoutingEvent::getStage (); + //! \sreturn The stage the router is in (see RoutingEvent::Mode). + + //! \function size_t RoutingEvent::getAllocateds (); + //! \sreturn The number of RoutingEvent currently allocateds. + + //! \function size_t RoutingEvent::getProcesseds (); + //! \sreturn The number of RoutingEvent that have been processeds since + //! the last call to RoutingEvent::resetProcesseds(). + + //! \function void RoutingEvent::resetProcesseds (); + //! \sreturn Reset the number of processeds events. + + //! \function unsigned int RoutingEvent::setStage ( unsigned int mode ); + //! Sets the router's stage (see RoutingEvent::Mode). + + //! \function RoutingEvent* RoutingEvent::create ( TrackElement* element, unsigned int mode ); + //! \param element The element for which to create the event. + //! \param mode The mode into which this event will be valid. + //! + //! RoutingEvent constructor. + + //! \function RoutingEvent* RoutingEvent::clone () const; + //! \return A clone of the event. + //! + //! Cloning an event is slightly different from copying it (which is forbidden). + //! There can be multiple events for one \c element but only one must be + //! active at a time. This is a cheap way of implementing the rescheduling + //! mechanism. The original event remains the active one, but it's cloned + //! flag is raised. The cloned event is created inactive and with a null + //! \e eventLevel. + + //! \function void RoutingEvent::destroy (); + //! The destructor. + + //! \function bool RoutingEvent::isCloned () const; + //! \sreturn \true if this event has been cloned at least once. + + //! \function bool RoutingEvent::isValid () const; + //! \sreturn \true if the cached informations from the \e element are valid + //! (i.e. the element has not been changed). + + //! \function bool RoutingEvent::isUnimplemented () const; + //! \sreturn \true if the event has tried to use an unimplemented feature. + + //! \function bool RoutingEvent::isProcessed () const; + //! \sreturn \true if the event has been processed. + + //! \function bool RoutingEvent::isDisabled () const; + //! \sreturn \true if the event is \b not the active one. It should be discarted + //! by the algorithm. + + //! \function bool RoutingEvent::isForcedToHint () const; + //! \sreturn \true the \e element must be placed exacltly on the given axis hint. + + //! \function bool RoutingEvent::isRipedByLocal () const; + //! \sreturn \true the \e element (global) has been riped up to place a local one. + + //! \function bool RoutingEvent::canMinimize () const; + //! \sreturn \true the \e element could still be minimized. + + //! \function unsigned int RoutingEvent::getMode () const; + //! \sreturn the mode the event must be taken into account to. + + //! \function unsigned int RoutingEvent::getState () const; + //! \sreturn the mode the router is currently in. + + //! \function const Key& RoutingEvent::getKey () const; + //! \sreturn The \e key to use in map & queue for this event. + + //! \function TrackElement* RoutingEvent::getSegment () const; + //! \sreturn The associated segment. + + //! \function const vector& RoutingEvent::getPerpandiculars () const; + //! \sreturn A vector of cached perpandiculars to the associated segment. + + //! \function DbU::Unit RoutingEvent::getAxisHint () const; + //! \sreturn The preferred position for the segment axis. + + //! \function DbU::Unit RoutingEvent::getAxisHistory () const; + //! \sreturn The previous position of the segment axis (before it's current position). + + //! \function DbU::Unit RoutingEvent::getAxisWeight ( DbU::Unit axis ) const; + //! \sreturn The distance between \c axis and the preferred position. + + //! \function const Interval& RoutingEvent::getOptimal () const; + //! \sreturn The range of positions for the optimal axis (cached). + + //! \function const Interval& RoutingEvent::getConstraints () const; + //! \sreturn The range of legal positions for the axis. + + /*! \function unsigned int RoutingEvent::getPriority () const; + * \sreturn The priority of the event, it quantify the degree of freedom of the + * segment. Currently it's computed from the length of the segment + * and it's slack: + \f[ + priority = (slack(segment)+1.0) \times (length(segment)+1.0) + \f] + * A high priority means that the segment will be harder to place + * thus it will be scheduled first. With this function, longer + * segments will be placed first. */ - /*! \function TrackSegment* RoutingEvent::getSegment () const; - * \Return The associated and unique \TrackSegment. - */ + //! \function unsigned int RoutingEvent::getEventLevel () const; + //! \sreturn The event level of the event, used to tweak the order inside the event + //! queue. It differs from the priority in the sense that it isn't a + //! topologicaly based value, but manipulated by the algorithm. - /*! \function unsigned long RoutingEvent::getPriority () const; - * \Return The second criterion used to sort \RoutingEvents in the negociation queue. - * Currently, it is the area of the associated \TrackSegment, which in - * turn return the slack (not a very fortunate choice of name...). - */ + //! \function unsigned int RoutingEvent::getTracksNb () const; + //! \sreturn The number of tracks avalaibles for the segment to be placed. - /*! \function unsigned int RoutingEvent::getEventLevel () const; - * \Return The first criterion used to sort \RoutingEvents in the negociation queue. - * It is used to re-schedule a \RoutingEvent and make the new event be - * processed before the original one, which is marked as - * processed to be ignored. - * - * \see setEventLevel(). - */ + //! \function unsigned int RoutingEvent::getInsertState () const; + //! \return The kind of track insertion that will be intended. It's a counter + //! whose values have the following meaning: + //! - \b 1 : normal insert. + //! - \b 2 : shrink the segment to it's minimum before inserting. + //! - \b 3 : attempt to ripup conflicting others before inserting. - /*! \function RoutingEvent* RoutingEvent::getClone () const; - * \Return An exact copy of the current \RoutingEvent. - */ + //! \function void RoutingEvent::revalidate (); + //! Perform an event revalidation. - /*! \function RoutingEvent* RoutingEvent::reschedule ( RoutingEventQueue& queue ); - * \param queue The \RoutingEvent queue. - * \return The rescheduled \RoutingEvent. May be \NULL if it cannot be rescheduled. - */ + //! \function void RoutingEvent::updateKey (); + //! Update the key with the new values from the event, the key \e must + //! not be inserted in the queue when this method is called. - /*! \function void RoutingEvent::setProcessed ( bool state=true ); - * \param state The state into which the event is to be put. - * - * Mark the event as processed. This arises in two cases : - *
      - *
    • The event has really been processed by the process() member - * function. - *
    • There has been a fork from this event and it has been - * superseded by a newly rescheduled one, so we have to - * invalidate this one. - *
    - */ + //! \function void RoutingEvent::process ( RoutingEventQueue& queue, RoutingEventHistory& history, RoutingEventLoop& loop ); + //! \param queue The main event queue. + //! \param history The event's history list. + //! \param loop The loop detector. + //! + //! Process the event, that is: + //! - First, check if there is no looping, if any, do not process the + //! event but dicard it (marked as unimplemented). + //! - Second, attempt to place the associated segment. Pass it to the relevant + //! function, according to the router's mode (\c _processNegociate(), + //! \c processPack() or \c _processRepair() ). + //! Once processed, the event is added to both \c history (for the record) + //! and \c loop to check if we are not looping. - /*! \function void RoutingEvent::setEventLevel ( unsigned int level ); - * \param level The new event level. - * - * \see getEventLevel(). - */ + //! \function void RoutingEvent::setSegment ( TrackElement* element ); + //! Change the associated \c segment. \red{Used only by TrackSegment::swapTrack().} - /*! \function void RoutingEvent::process ( RoutingEventQueue& queue, RoutingEventHistory& history ); - * \param queue The event queue from the negociate algorithm. - * \param history The event history. - * - * Perform all the operations shared by all \RoutingEvent classes then - * calls the virtual _subProcess() functions. - * - * Shared operations are : - *
      - *
    1. Invalidating all perpandicular \TrackSegments. - *
    2. Computing the free interval allowed by the free intervals - * in perpandicular \Tracks holding the perpandicular \TrackSegments. - *
    3. Merging in the various constraints intervals : from the - * \TrackSegment itself, from the free intervals in the - * perpandicular \Tracks and from the \RoutingEvent bound - * constraints. - *
    4. Finding the candidate \Tracks for the \RoutingEvent, - * using \c Track_Spiral \Collection. - *
    - * The results of the shared operation are passed to derived classes - * trough the \c State internal structure. - */ + //! \function RoutingEvent* RoutingEvent::reschedule ( RoutingEventQueue& queue, unsigned int eventLevel); + //! \return The newly reinserted event. Depending on the cases it could be itself. + //! + //! Insert or reinsert an event in the scheduler. The \c eventLevel parameter only + //! allows to increase the level (if it is less than the current level of the + //! event, it will be ignored). + //! + //! Cloning Management. As an event could be cloned, if we try to re-insert + //! a disabled original, we must first lookup the currently cloned active event. + //! This is done through the associated \c segment which must always be associated + //! with the active event (if any). + //! + //! Unimplemented Protection. If the unimplemented flag is set the reschedule + //! is cancelled (\c NULL is returned). + //! + //! Unprocessed Event. The event is still in queue, waiting to be + //! processed, then just repush it in the queue with it's new level. + //! + //! Processed Event. Clone the already processed one, activate it + //! and push it on the queue. + //! + //! Router's Mode. The mode is also updated. - /* \function bool RoutingEvent::_setAside ( Track* track, size_t begin, size_t end, Net* net, Interval interval, RoutingEventQueue& queue ); - * \param track The track in wich to make free space. - * \param begin The index of the first overlaping TrackSegment. - * \param end The index of the last overlaping TrackSegment. - * \param net The net for which we want to insert a TrackSegment. - * \param interval The interval which must be made empty. - * \param queue The queue of RoutingEvent. - * - * Manage the case of soft overlap. Create or enlarge a free space - * in \c track so it can contain the requested \interval. [begin:end] defines - * the range of indexes of overlaping \TrackSegment in \c track. - * Displace TrackSegment that are perpandicular to those overlaping, - * remove them from their \c Track if needed and issue an associated \RoutingEvent - * with an updated bound constraint. Note that the overlaping \TrackSegment - * themselves are not removed from the \c track. - * - * A note on implementation : - *
      - *
    • \c data1 : the DataNegociate of the to be inserted \TrackSegment. - *
    • \c segment2 : the current overlaping \TrackSegment (from \c begin - * to \c end). - *
    • \c data2 : the DataNegociate of the overlaping \TrackSegment. - *
    • \c segment3 : a \TrackSegment perpandicular to \c segment2. - *
    - */ + //! \function void RoutingEvent::setMode ( unsigned int mode ); + //! Set the mode in which the event must be processed (see RoutingEvent::Mode). - /* \function void RoutingEvent::_ripup ( Track* track, Net* net, Interval interval, size_t begin, size_t end, RoutingEventQueue& queue ); - * \param track The track in wich to make free space. - * \param net The net for which we want to insert a TrackSegment. - * \param interval The interval which must be made empty. - * \param begin The index of the first overlaping TrackSegment. - * \param end The index of the last overlaping TrackSegment. - * \param queue The queue of RoutingEvent. - * - * Manage the case of hard overlap, that is bluntly remove - * any \TrackSegment overlaping \interval. Issue both a remove event - * (to \c Session) and a \RoutingEvent to re-process the dislodged - * \TrackSegment. - */ + //! \function void RoutingEvent::setState ( unsigned int state ); + //! Proxy mutator for DataNegociate::setState(). - } // End of Kite namespace. + //! \function void RoutingEvent::setAxisHintFromParent (); + //! Sets the axis hint from it's parent segment. The parentage is found + //! through the TrackSegment parentage. + + //! \function void RoutingEvent::incInsertState (); + //! Increment the insertion state. + //! + //! \sa RoutingEvent::getInsertState(). + + //! \function void RoutingEvent::resetInsertState (); + //! Reset the insertion state. + //! + //! \sa RoutingEvent::getInsertState(). + + //! \function void RoutingEvent::setEventLevel ( unsigned int level ); + //! Set the event level (user-controlled re-ordering). + + } diff --git a/kite/doc/Session.dox b/kite/doc/Session.dox index 45ca9041..dc6dd463 100644 --- a/kite/doc/Session.dox +++ b/kite/doc/Session.dox @@ -1,133 +1,163 @@ - - // -*- C++ -*- + // -*- mode: C++; explicit-buffer-name: "Session.dox" -*- namespace Kite { /*! \class Session - * \brief Kite update Session (\b API). + * \brief Kite update Session * * Session extend the Katabatic update session to the Kite * router level. Mainly by managing Track update. * + * Difference between Kite & Katabatic sessions: + * - In Katabatic, segments are actually moved \e before the + * revalidation, then \e during the revalidation, contacts + * and topologies are adjusteds + * - In Kite, nothing is moved until the revalidation. + * Requests for segment displacement are queued for the session. + * + * Asymmetry between invalidation & revalidation: + * - When a TrackSegment (or directly an AutoSegment) is invalidated + * both associated AutoSegment and TrackSegment are invalidated + * (through the Observer mechanism). + * - When an AutoSegment is revalidated, the TrackSegment is \b not + * immediatly revalidated. See the revalidate algorithm for more + * details. + * + * Indirect TrackSegment invalidation: + * - TrackSegment invalidation do not result only from direct insertion + * in Track. For example, any or all of it's perpandicular can be + * invalidated trough the Katabatic::Session update (the perpandicular + * Katabatic::AutoSegment is revalidated, generating invalidation on their + * associated TrackSegment). + * * For details on how Katabatic Sessions works, have a look to - * \ref katabaticSession. + * Katabatic::Session. * * * \section secSessionMechanism The Session Mechanism. * * Delayed modification procedure : - *
      - *
    1. Modifications events are recorded into the Session. - * At this step, no modification are actually done, the - * data-base retains it's previous state and coherency. - *
    2. The Revalidate() procedure is called (or the Session - * is closed), then all the modification events are applied. - * the data-base is in it's new state. - *
    + * - Modifications events are recorded (queued) into the Session. + * At this step, no modification are actually done, the + * data-base retains it's previous state and coherency. + * - The \c revalidate() procedure is called (or the Session + * is closed), then all the modification events are applied. + * The data-base is in now in it's new state. * * * \section secKiteSessionRevalidate The Revalidate Algorithm. * * Revalidation steps : - *
      - *
    1. process all remove events. detach TrackSegment from - * their Track, but do not remove the pointer from the - * internal \vector. - *
    2. Pack all Track in which removal have took place. - *
    3. process all insert events. This is the time TrackSegment - * are moved into their new Track (physical displacement). - *
    4. Call the Katabatic::Session::revalidate() method. - *
    5. Recompute the canonical position of source and target - * of all invalidateds TrackSegment (take account of - * extention modifications). - *
    6. Perform a sort() on all Track that have been modifieds. - *
    - */ - - - /*! \name Accessors - */ - // \{ - - /*! \function static Session* Session::get (); - * \Return The currently opened session, \c NULL if no session has - * been opened. - */ - - /*! \function static KiteEngine* Session::getKiteEngine (); - * \Return The Kite ToolEngine associated to the current update - * session. - */ - - // \} - - - /*! \name Miscellaneous - */ - // \{ - - /*! \function bool Session::isEmpty (); - * Ensure that the Session is empty and can be closed (deleted) - * safely. - */ - - /*! \function static Session* Session::open ( KiteEngine* kite ); - * \param kite A Kite ToolEngine on which to work. - * \return A new Kite update Session. + * - Process all remove events. detach TrackSegment from + * their Track, but do not remove the pointer from the + * internal \vector. + * - Pack all Track in which removal have took place. + * - Process all insert events. This is the time TrackSegment + * are moved into their new Track (physical displacement). + * It is at this point that the invalidation of both AutoSegment + * and TrackSEgment is done. + * - Call the Katabatic::Session::revalidate() method which + * will recompute the correct contact extensions and topologies. + * \e After this step the Katabatic data-base is up to date, + * but \e not the Kite one. AutoSEgment are revalidated. + * - Recompute the canonical position of source and target + * of all invalidateds TrackSegment (take account of + * extention modifications). The set of invalidated TrackSegment + * is computed from the revalidated AutoSegment, that is + * AutoSegment that are canonical. + * - Perform a sort() on all Track that have been modifieds. * - * Open a new Kite update Session on the \c kite \c ToolEngine. - * At this point only one session can be opened at a time. Attempt - * to open a second one will result in an exception. - */ - - // \} - - - /*! \name Event Scheduling - */ - // \{ - - /* \function void Session::addInvalidated ( TrackSegment* segment ); - * \param segment An AutoSegment that has been moved. + * Note: We cannot use the Observer mechanism to automatically + * update TrackSegment from an AutoSegment, because we must wait for all + * AutoSegments (canonical or not) involved into the TrackSegment to be + * up to date before we can update it. * - * add \e segment to the \vector of TrackSegment for which we - * have to recompute the canonical size (i.e. extentions may - * have moved). + * Note: Have to talk about the special case when new canonical + * AutoSegment appears after dogleg creation. + * + * + * \section secKiteSessionLookup The Lookup Mechanism + * + * There are two lookup mechanisms: + * - From a Hurricane::Segment, we uses the Katabatic segment lookup + * table (slow, stored in a \c map<>). + * - From a Katabatic::AutoSegment, we uses the Observer, it's owner + * is the TrackSegment (fast). */ - /*! \function void Session::addInsertEvent ( TrackSegment* segment, Track* track ); - * \param segment An AutoSegment to insert in a Track. - * \param track The Track into which the \e segment will be inserted. - * - * Schedule the insertion of \e segment into Track \e track. - * The \e segment must not already be part of a Track. - */ + //! \function Session* Session::open ( KiteEngine* kite ); + //! \param kite A Kite ToolEngine on which to work. + //! \return A new Kite update Session. + //! + //! Open a new Kite update Session on the \c kite \c ToolEngine. + //! At this point only one session can be opened at a time. Attempt + //! to open a second one will result in an exception. - /*! \function void Session::addRemoveEvent ( TrackSegment* segment ); - * \param segment An AutoSegment to remove from a Track. - * - * Schedule the removal of \e segment from Track \e track. - */ + //! \function Session* Session::get ( const char* message=NULL ); + //! \sreturn The currently opened session, \c NULL if no session has + //! been opened. - /*! \function void Session::addMoveEvent ( TrackSegment* segment, Track* track ); - * \param segment An AutoSegment to move into a new Track. - * \param track The Track into which the \e segment will be moved. - * - * Schedule the displacement of \e segment into Track \e track. - */ + //! \function Katabatic::Session* Session::base (); + //! \sreturn The Session, casted as it's base object. - /*! \function void Session::addSortEvent ( Track* track, bool forced=false ); - * \param track The Track to update. - * \param forced Force the invalidation of the \Track. - * - * Schedule the update of Track \e track. If the \Track has not been - * invalidated, no actual sort will takes place. To force a sort - * (manually invalidating the \Track), sets \b forced to \true. - * - * \see Track::pack() & Track::sort(). - */ + //! \function bool Session::isEmpty (); + //! Ensure that the Session is empty and can be closed (deleted) + //! safely. + + //! \function Configuration* Session::getConfiguration (); + //! \sreturn The Kite Configuration of the Router (proxy helper). + + //! \function Net* Session::getBlockageNet (); + //! \sreturn The net used to create blockage components (proxy helper). + + //! \function KiteEngine* Session::getKiteEngine (); + //! \sreturn The Kite ToolEngine associated to the current update + //! session (proxy helper). + + //! \function NegociateWindow* Session::getNegociateWindow (); + //! \sreturn The current NegociateWindow (proxy helper). + + //! \function Katabatic::GCell* Session::getGCellUnder ( DbU::Unit x, DbU::Unit y ); + //! \sreturn The GCell under \c (x,y) (proxy helper, see Katabatic::GCellGrid::getGCell()). + + //! \function void Session::addInsertEvent ( TrackElement* segment, Track* track ); + //! \param segment An AutoSegment to insert in a Track. + //! \param track The Track into which the \e segment will be inserted. + //! + //! Schedule the insertion of \e segment into Track \e track. + //! The \e segment must not already be part of a Track. + + //! \function void Session::addRemoveEvent ( TrackElement* segment ); + //! \param segment A TrackSegment to remove from a Track. + //! + //! Schedule the removal of \e segment from Track \e track. + + //! \function void Session::addMoveEvent ( TrackElement* segment, Track* track ); + //! \param segment An AutoSegment to move into a new Track. + //! \param track The Track into which the \e segment will be moved. + //! + //! Schedule the displacement of \e segment into Track \e track. + + //! \function void Session::addSortEvent ( Track* track, bool forced=false ); + //! \param track The Track to update. + //! \param forced Force the invalidation of the \Track. + //! + //! Schedule the update of Track \e track. If the \Track has not been + //! invalidated, no actual sort will takes place. To force a sort + //! (manually invalidating the \Track), sets \b forced to \true. + //! + //! \sa Track::pack() & Track::sort(). + + //! \function void Session::revalidate (); + //! Applies all the requested modifications, but keeping the session + //! opened. + + //! \function TrackElement* Session::lookup ( Segment* segment ); + //! \sreturn the TrackElement associated to \c segment. + + //! \function TrackElement* Session::lookup ( AutoSegment* segment ); + //! \sreturn the TrackElement associated to \c segment. - // \} } diff --git a/kite/doc/Track.dox b/kite/doc/Track.dox index 3422d6ee..a7b3f156 100644 --- a/kite/doc/Track.dox +++ b/kite/doc/Track.dox @@ -7,391 +7,481 @@ /*! \class Track * \brief Structure managing one routing track. * + * \section secTrackPurpose Track Purpose + * + * We use an array of regularly spaced Track as a geometrical + * fast access structure. It allows to know whether an area is used or + * not. The whole area may be seen as a set of adjoining tiles of fixed + * \e width but variable \e length. + * + * The figure (1.b) show, for an horizontal, track the relation + * between y,min,max and the occupied area of the plane. + * \c min and \c max must take into account segment extensions (\c e) and + * the minimal distance between two rectangles (\c MD) of the same layer. + * We assume that the width of the segment, augmented of all it's + * contraints is no greater than \c TS (in fact it's how \c TS must be + * calculated). + * + * For the whole track array, see RoutingPlane. + * + * \image html Track-0.png "Fig 1: Track Area" + * + * * \section secTrackImplementation Track Implementation * - * Basically a Track is a sorted vector of TrackSegment, TrackSegment - * beeing a decoration of the Katabatic::AutoSegment. Managment rules : - *
      - *
    • Rule 1 : the vector of TrackSegment is sorted by - * increasing source positions. - *
    • Rule 2 : two consecutives segments TrackSegment do - * not overlap, except in case of rule 3. - *
    • Rule 3 : if they belongs to the same \Net, two - * consecutive segments can overlap, see Track::getNetUsedInterval(). - *
    + * A Track is implemented with a sorted vector of TrackElement. + * TrackElements from differents nets must not overlap. + * The sorting order is defined as follow: + * - TrackElements are sorted by increasing source (\e min) + * positions. + * - In case of overlap (i.e. belongs to the same net), if + * they share the same source position, then they are sorted + * by \e decreasing length. This way, the longest one will be + * the first encountered when walking through the Track in + * increasing index order. * - * \image html Track-1.png "Track Structure" + * Figure 2.b shows the details of the Track [1] of + * figure 1.a. Net \b \ show an exemple of overlapping. + * + * \image html Track-1.png "Fig 2: Track Structure" * \image latex Track-1.pdf "Track Structure" width=0.7\textwidth * + * In addition to the TrackSegments, the Track also manage additionnal + * informations through a second vector of TrackMarkers. TrackMarker + * are currently used only to hints at how strongly a terminal is + * dependant on that portion of Track to be accessed. * - * updates procedures * - * Kite extend the Katabatic::Session mechanism to manage Track - * modifications. - * - * Indexes vs. Iterators + * \subsection ssecTrackIndexes Indexes vs. Iterators * * Numerical indexes have been prefered over iterators because they can * be used more easily by objects other the Track itself for referencing. * So internal managment follow the same rule, handling indexes or * reference to indexes. * - * Looking up free/used zones * - * The most important operation performed on a Track is to locate - * free or used zones at a given point. We uses the \STL \lower_bound - * function to find the index in the vector from a position. - * It relies heavily on the hypothesis that consecutives TrackSegment - * do not overlap, however, as segments from a same net can overlap - * the \c max() function is more complex than the \c min(). In fact - * it has to aggregate all the overlaping TrackSegment from the - * same \Net (getUsedNetInterval()). + * \subsection ssecTrackUpdate Update Mechanism * - * \image html Track-2.png "Track Zones - First Approach" - * \image latex Track-2.pdf "Track Zones - First Approach" width=0.7\textwidth + * When a TrackElement is normaly inserted in a Track, a two way link + * is established. The Track has an entry in it's vector refering to + * TrackElement, and conversely, the TrackElement has it's \c track + * field pointing to it's owning Track. * - * As can be seen on the previous figure it is slightly more - * efficient to work on \c lower_bound-1 instead of \c lower_bound. + * TrackElement Removal * - * \image html Track-3.png "Track Zones - Optimized" - * \image latex Track-3.pdf "Track Zones - Optimized" width=0.7\textwidth - */ - - /*! \enum Track::IndexState - * Indicates how to compute the bounds of the interval enclosing - * a given position. + * To remove a TrackElement from a Track, we break one of those two links: + * the TrackElement cease to refer to the owning Track, marking him for + * removal which will occurs at the next track revalidation (Track::doRemoval()). + * In figure 3, the TrackElement belonging to net \b \ is + * marked for removal. * - * \note According to \e position, the interval can be a free interval - * or a used interval. - */ - - /*! \var Track::MinTrackMin - * Minimum/Source : uses the Track minimum. - */ - - /*! \var Track::MinSegmentMin - * Minimum/Source : uses the begin segment minimum (source). - */ - - /*! \var Track::MinSegmentMax - * Minimum/Source : uses the begin segment maximum (target). - */ - - /*! \var Track::MaxTrackMax - * Maximum/Target : uses the Track maximum. - */ - - /*! \var Track::MaxSegmentMin - * Maximum/Target : uses the end segment minimum (source). - */ - - /*! \var Track::MaxNextSegmentMin - * Maximum/Target : uses the next to end segment minimum (source). - */ - - /*! \var Track::MaxSegmentMax - * Maximum/Target : uses the end segment maximum (target). - */ - - /*! \var Track::BeforeFirst - * Interval type : free, before the first interval [case (1)]. - */ - - /*! \var Track::Inside - * Interval type : used, in the Track [case (2)]. - */ - - /*! \var Track::Outside - * Interval type : free, between two used TrackSegment [case (3)]. - */ - - /*! \var Track::AfterLast - * Interval type : free, after the last used TrackSegment [case (4)]. - */ - - /*! \var Track::EmptyTrack - * Interval type : free, and the Track is empty [case (5)]. - */ - - /*! \var Track::MinMask - * Mask value : used to reset all the minimal values. - */ - - /*! \var Track::MaxMask - * Mask value : used to reset all the maximal values. - */ - - /*! \var Track::NPOS; - * A special index value (greatest integer) meaning that - * an index is invalid. - */ - - - /*! \name Accessors - */ - // \{ - - /*! \function RoutingPlane* Track::getRoutingPlane () const; - * \Return The RoutingPlane owning this Track. - */ - - /*! \function KiteEngine* Track::getKiteEngine () const; - * \Return The KiteEngine owning this Track. - */ - - /*! \function RoutingPlane* Track::getIndex () const; - * \Return The index of this Track in the RoutingPlane Track vector. - */ - - /*! \function Layer* Track::getLayer () const; - * \Return The \Layer of the Track. - */ - - /*! \function DbU::Unit Track::getAxis () const; - * \Return The Axis of the Track. - */ - - /*! \function DbU::Unit Track::getMin () const; - * \Return The minimal allowed coordinate of the Track. - */ - - /*! \function DbU::Unit Track::getMax () const; - * \Return The maximal allowed coordinate of the Track. - */ - - /*! \function Track* Track::getNext () const; - * \Return The next Ttrack in the \RoutingPlane vector. That is the - * one with the axis immediatly superior. - */ - - /*! \function Track* Track::getPrevious () const; - * \Return The previous Track in the \RoutingPlane vector. That is the - * one with the axis immediatly inferior. - */ - - /*! \function size_t Track::getSize () const; - * \Return The total number of TrackSegment in the Track. - */ - - /*! \function Point Track::getPosition ( DbU::Unit position ) const; - * \Return the point at \c (position,getAxis()) for horizontal Track - * at or \c (getAxis(),position) for vertical Track. - */ - - // \} - - - /*! \name TrackSegment Accessors - */ - // \{ - - /*! \function TrackSegment* Track::getNext ( size_t& index, Net* net ) const; - * \param index Index of the starting TrackSegment. - * \param net A \Net to ignore. - * \return The next TrackSegment (\NULL if not found). + * \image html Track-2.png "Fig 3: TrackElement Removal" * - * find, starting from TrackSegment at \e index the next TrackSegment - * ignoring TrackSegment from \e net. \e index is modified to point - * on the returned TrackSegment. If there's no next TrackSegment (\NULL) - * then index is set to Track::NPOS. - */ - - /*! \function TrackSegment* Track::getPrevious ( size_t& index, Net* net ) const; - * \param index Index of the starting TrackSegment. - * \param net A \Net to ignore. - * \return The previous TrackSegment (\NULL if not found). + * TrackElement Insertion * - * find, starting from TrackSegment at \e index the previous TrackSegment - * ignoring TrackSegment from \e net. \e index is modified to point - * on the returned TrackSegment. If there's no previous TrackSegment (\NULL) - * then index is set to Track::NPOS. - */ - - /*! \function TrackSegment* Track::getNextFixed ( size_t& index ) const; - * \param index Index of the starting TrackSegment. - * \return The first previous \e Fixed TrackSegment. + * When a TrackElement is inserted into a Track, the two way link is + * immediatly created (but the TrackElement is not yet at it's final + * place in the Track's vector). Before inserting a TrackElement we + * check that it's been already detached (\c track field to \c NULL). * - * find, starting from TrackSegment at \e index the first previous - * with a \e Fixed attribute set. \e index is modified to point on the - * returned TrackSegment. If there's no previous TrackSegment (\NULL) - * then index is set to Track::NPOS. - */ - - /*! \function TrackSegment* Track::getSegment ( size_t index ) const; - * \param index The index of the TrackSegment. - * \return The TrackSegment at \e index. The result will be \NULL in the - * follwing cases : - *
      - *
    • \e index is outside the sorted zone. - *
    • \e index points to a hole in the Track. - *
    • \e index is equal to Track::NPOS. - *
    - */ - - /*! \function TrackSegment* Track::getSegment ( DbU::Unit position ) const; - * \param position The position where to search. - * \return The TrackSegment whose starting point is immediatly inferior to \e position. - */ - - /*! \function size_t Track::find ( const TrackSegment* segment ) const; - * \Return the \e index of \e segment inside the Track. If the \e segment do - * not belongs to the Track, return Track::NPOS. - */ - - /*! \function void Track::getIBounds ( DbU::Unit position, size_t& begin, size_t& end, unsigned int& state ) const; - * \param position The position where to search. - * \param begin Index of the starting bound. - * \param end Index of the ending bound. - * \param state how to use the returned \e indexes. - * \return The TrackSegment index around \e position. + * It is at that step that the TrackElement axis is actually updated + * through a call to TrackElement::setAxis(). + * + * Revalidation Sequence * - * The relation between the returned \e index and the position is - * given through the \e state parameter. + * After a Track has been modificated either the Track element vector or + * the MarkerElement vector (or both) has been invalidateds. Revalidation + * take place in three steps: + * - Track::doRemoval(), remove all TrackElement marked for removal. + * - Track::insert(), insert the TrackElement into their new Track. + * - Track::doReorder(), sort the TrackElement of the vector, that is, put the + * newly inserted elements at their right place. * - * \note It uses the \lower_bound \STL function. - */ - - /*! \function DbU::Unit Track::getSourcePosition ( size_t index ) const; - * \Return The canonical source position of TrackSegment at index \e index. - * If \e index is equal to Track::NPOS, returns zero. - */ - - /*! \function DbU::Unit Track::getSourcePosition ( vector::iterator it ) const; - * \Return The canonical source position of TrackSegment pointed by iterator \e it. - * If \e it is equal to \c end() , returns zero. - */ - - /*! \function DbU::Unit Track::getMinimalPosition ( size_t index, unsigned int state ) const; - * \Return The minmal position (lower bound) of an interval, starting near index \e index - * with state \e state. + * Each step must be done for all Tracks before proceeding to the + * next. This way a TrackElement \c track field doesn't get set \e before + * it has been actually removed from it's previous Track. + * + * * - * \see Track::IndexState. - */ - - /*! \function DbU::Unit Track::getMaximalPosition ( size_t index, unsigned int state ) const; - * \Return The maximal position (upper bound) of an interval, ending near index \e index - * with state \e state. + * \subsection ssecTrackOperations Main Operations on Tracks * - * \see Track::IndexState. - */ - - /*! \function Interval Track::getFreeInterval ( DbU::Unit position, Net* net ) const; - * \param position where fo find a free interval. - * \param net for which net to find the free interval. - * \return The longuest free interval enclosing \e position (may be empty). - */ - - /*! \function Interval Track::expandUsedInterval ( size_t& begin, size_t& end ) const; - * \param begin index on any of the overlaping TrackSegment. This value - * is then modified to point on the lower TrackSegment of the set. - * \param end initial value is ignored. sets to the index of the rightmost - * extended TrackSegment of the set (i.e. the one setting the - * upper bound). - * \return the whole interval used by a set of overlaping TrackSegment. + * Helper Function: Track::getBeginIndex() * - * \image html Track-4.png "Overlap - Example 1" - * \image html Track-5.png "Overlap - Example 2" - * \image latex Track-4.pdf "Overlap - Example 1" width=0.7\textwidth - * \image latex Track-5.pdf "Overlap - Example 2" width=0.7\textwidth - */ - - /*! \function Interval Track::expandFreeInterval ( size_t& begin, size_t& end, unsigned int state, Net* net ) const; - * \param begin the lowest used TrackSegment. - * \param end the highest used TrackSegment. - * \param state the enclosing characterics. - * \param net the for wich we seek place. - * \Return The longuest free interval between \c ]begin,end[ . + * Return in \c begin the index of the TrackElement whose minimum is immediately + * below the requested \c position on the Track axis. The second returned + * parameter \c state is a set of flags to tell how the \c begin index + * has to be interpreted. * - * \note \c ]begin,end[ must define a free interval between two TrackSegment. - */ - - /*! \function void Track::_check ( const char* message=NULL ) const; - * \param message An iformative message, only printed if an error occurs. - * \return \true if the Track contains no incoherencies. + * Helper Function: Track::getOccupiedInterval() * - * Perform a complete Track check. Looks for the following incoherencies : - *
      - *
    • TrackSegment do not refers this Track. - *
    • TrackSegment is detached (TrackSegment::getTrack() is \NULL). - *
    • TrackSegment is hollow, this one is very unlikely as hollow - * TrackSegment are only created for the \lower_bound. - *
    • \NULL pointers (should never occurs, nevertheless...) - *
    • And finally, call checkOverlap(). - *
    + * Returns the complete interval of a set of overlapping TrackElement from + * the same net. */ - /*! \function void Track::checkOverlap () const; - * \return the number of overlaping TrackSegment. - * - * Perform the following checks : - *
      - *
    • Two consecutive TrackSegment from different \Net must not - * overlap. - *
    • For TrackSegment starting from the same position, the - * longuest must be first. - *
    - */ + //! \enum Track::IndexState + //! Indicates how to compute the bounds of the interval enclosing + //! a given \c position on track axis. + //! + //! \note According to \e position, the interval can be a free interval + //! or a used interval. - /*! \function void Track::getOverlapBounds ( Interval interval, size_t& begin, size_t& end ) const; - * \param interval the overlaping interval. - * \param begin where to store the starting bound. - * \param end where to store the ending bound. - * - * find the range of TrackSegment intersecting \e interval. - * Note that when the \e interval lower bound crosses a set of - * overlaping intervals from the same \Net, the interval at - * \e begin will crosses the lower bound but some following - * of the same \Net may not. - */ + //! \var Track::BeginIsTrackMin + //! (implies \c begin=0) there is no TrackElement \e before \c position - /*! \function DbU::Unit Track::getOverlapCost ( Interval interval, Net* net, size_t begin, size_t end ) const; - * \param interval the overlaping interval. - * \param net a Net to ignore (null cost). - * \param begin the starting bound. - * \param end the ending bound. - * \return The cost of the overlap. - * - * compute the cost of the overlap of \e interval with the range - * \c [begin,end] of TrackSegment. Any TrackSegment belonging to - * \e net will be ignored. - */ + //! \var Track::BeginIsSegmentMin + //! The \c begin segment starts \e before \c position and ends \e after. - /*! \function DbU::Unit Track::getOverlapCost ( Interval interval, Net* net ) const; - * \param interval the overlaping interval. - * \param net a Net to ignore (null cost). - * - * compute the overlap of \e interval with TrackSegment from - * the current Track, ignoring thoses belonging to \e net. - */ + //! \var Track::BeginIsSegmentMax + //! The \c begin segment starts and ends \e before \c position. - // \} + //! \var Track::EndIsTrackMax + //! There is no TrackElement \e after \c position. + //! \var Track::EndIsSegmentMin + //! The \c begin segment starts \e before \c position. - /*! \name Updators - */ - // \{ + //! \var Track::EndIsNextSegmentMin + //! The \c begin segment starts and ends \e before \c position. So the maximum + //! is given by the \c minimum of the \e next TrackElement. - /*! \function void Track::insert ( TrackSegment* segment ); - * adds \e segment to the Track. Must only be used inside a - * TrackSession. - * - * \see TrackSession. - */ + //! \var Track::EndIsSegmentMax + //! The \c begin segment starts \e before \c position and ends \e after. - /*! \function size_t Track::pack (); - * \Return The number of removeds TrackSegment. - * - * Suppress all the TrackSegment that have been withdraw from the - * Track. TrackSegment must be withdraw trough the TrackSegment::detach() - * method which sets their owning Track to \NULL (the removal criterion). - */ + //! \var Track::BeforeFirstElement + //! the \c position is before the first TrackElement. - /*! \function void Track::sort (); - * - * sort the the vector. Must be called \e after the Pack() method, - * so no detached TrackSegment are presents. - */ + //! \var Track::InsideElement + //! the \c position is inside a TrackElement. - // \} + //! \var Track::OutsideElement + //! the \c position is in free zone between two TrackElements. + + //! \var Track::AfterLastElement + //! the position is after the end of the last element. + + //! \var Track::EmptyTrack + //! the track is still empty. + + //! \var Track::BeginMask + //! To extract the \e begin part from a combination of flags. + + //! \var Track::EndMask + //! To extract the \e end part from a combination of flags. + + //! \var Track::npos; + //! A special index value (greatest integer) meaning that + //! an index is invalid. + + //! \function bool Track::isHorizontal () const; + //! \sreturn \true if the Track in horizontal direction. + + //! \function bool Track::isVertical () const; + //! \sreturn \true if the Track in vertical direction. + + //! \function bool Track::isLocalAssigned () const; + //! \sreturn \true is the Track should be preferentially used for local routing. + + //! \function RoutingPlane* Track::getRoutingPlane () const; + //! \sreturn The RoutingPlane owning this Track. + + //! \function KiteEngine* Track::getKiteEngine () const; + //! \sreturn The KiteEngine owning this Track. + + //! \function unsigned int Track::getDirection () const; + //! \sreturn The direction of the Track, either Katabatic::KbHorizontal or + //! Katabatic::KbVertical. + + //! \function RoutingPlane* Track::getIndex () const; + //! \sreturn The index of this Track in the RoutingPlane Track vector. + + //! \function unsigned int Track::getDepth () const; + //! \sreturn The depth (as given by the RoutingGauge) of the Track's layer. + + //! \function Layer* Track::getLayer () const; + //! \sreturn The \Layer of the Track. + + //! \function Layer* Track::getBlockageLayer () const; + //! \sreturn The associated blockage \Layer to the Track's layer. + + //! \function DbU::Unit Track::getAxis () const; + //! \sreturn The Axis of the Track. + + //! \function DbU::Unit Track::getMin () const; + //! \sreturn The minimal allowed coordinate of the Track. + + //! \function DbU::Unit Track::getMax () const; + //! \sreturn The maximal allowed coordinate of the Track. + + //! \function Track* Track::getNextTrack () const; + //! \sreturn The next Track in the \RoutingPlane vector. That is the + //! one with the axis immediatly superior. + + //! \function Track* Track::getPreviousTrack () const; + //! \sreturn The previous Track in the \RoutingPlane vector. That is the + //! one with the axis immediatly inferior. + + //! \function size_t Track::getSize () const; + //! \sreturn The total number of TrackSegment in the Track. + + //! \function Point Track::getPosition ( DbU::Unit position ) const; + //! \sreturn the point at \c (position,getAxis()) for horizontal Track + //! at or \c (getAxis(),position) for vertical Track. + + //! \function TrackSegment* Track::getSegment ( size_t index ) const; + //! \param index The index of the TrackSegment. + //! \return The TrackSegment at \e index. The result will be \NULL in the + //! follwing cases : + //! - \e index is outside the sorted zone. + //! - \e index points to a hole in the Track. + //! - \e index is equal to Track::npos. + + //! \function TrackSegment* Track::getSegment ( DbU::Unit position ) const; + //! \param position The position where to search. + //! \return The TrackSegment whose starting point is immediatly inferior to \e position. + + //! \function TrackSegment* Track::getNext ( size_t& index, Net* net ) const; + //! \param index Index of the starting TrackSegment. + //! \param net A \Net to ignore. + //! \return The next TrackSegment (\NULL if not found). + //! + //! Find, starting from TrackSegment at \e index the next TrackSegment + //! ignoring TrackSegment from \e net. \e index is modified to point + //! on the returned TrackSegment. If there's no next TrackSegment (\NULL) + //! then index is set to Track::npos. + + //! \function TrackSegment* Track::getPrevious ( size_t& index, Net* net ) const; + //! \param index Index of the starting TrackSegment. + //! \param net A \Net to ignore. + //! \return The previous TrackSegment (\NULL if not found). + //! + //! find, starting from TrackSegment at \e index the previous TrackSegment + //! ignoring TrackSegment from \e net. \e index is modified to point + //! on the returned TrackSegment. If there's no previous TrackSegment (\NULL) + //! then index is set to Track::npos. + + //! \function TrackSegment* Track::getNextFixed ( size_t& index ) const; + //! \param index Index of the starting TrackSegment. + //! \return The first previous \e Fixed TrackSegment. + //! + //! find, starting from TrackSegment at \e index the first previous + //! with a \e Fixed attribute set. \e index is modified to point on the + //! returned TrackSegment. If there's no previous TrackSegment (\NULL) + //! then index is set to Track::npos. + + //! \function size_t Track::find ( const TrackElement* element ) const; + //! \sreturn the \e index of \e element inside the Track. If the \e element do + //! not belongs to the Track, return Track::npos. + + //! \function DbU::Unit Track::getSourcePosition ( size_t index ) const; + //! \sreturn The source position of TrackSegment at index \e index. + //! If \e index is equal to Track::npos, returns zero. + + //! \function DbU::Unit Track::getSourcePosition ( vector::iterator it ) const; + //! \sreturn The source position of TrackSegment pointed by iterator \e it. + //! If \e it is equal to \c end() , returns zero. + + //! \function DbU::Unit Track::getMinimalPosition ( size_t index, unsigned int state ) const; + //! \sreturn Extract the minimal position from the interval at \c index in accordance + //! to \c state hinting. + //! + //! \sa Track::IndexState. + + //! \function DbU::Unit Track::getMaximalPosition ( size_t index, unsigned int state ) const; + //! \sreturn Extract the maximal position from the interval at \c index in accordance + //! to \c state hinting. + //! + //! \sa Track::IndexState. + + //! \function Interval Track::getFreeInterval ( DbU::Unit position, Net* net=NULL ) const; + //! \param position where fo find a free interval. + //! \param net for which net to find the free interval. + //! \sreturn The longuest free interval enclosing \e position (may be empty). + + //! \function Interval Track::getOccupiedInterval ( size_t& begin ) const; + //! \param begin index of one of the TrackElement set. May be modificated. + //! \sreturn the whole interval used by a set of overlaping TrackSegment. + //! + //! As TrackElement from a same net can overlap, the interval of one of + //! them do not give the full extend of the Track occupation at this point. + //! This function looks for all overlaping segments and returns the + //! merged interval. Additionnaly it sets \c begin to the index of the + //! lowest TrackElement of the set. + //! + //! \image html TrackOccupiedInterval-1.png "Fig 4: Track::getOccuppiedInterval()" + + //! \function Interval Track::expandFreeInterval ( size_t& begin, size_t& end, unsigned int state, Net* net ) const; + //! \param begin the lowest used TrackSegment. + //! \param end the highest used TrackSegment. + //! \param state tells how to interpret the \c begin & \c end indexes. + //! \param net the for wich we seek place. + //! \sreturn The longuest free interval between \c ]begin,end[ . + //! + //! Starting from the initial [begin,end] interval, expand the + //! interval to encompass all free space or segments belonging to \c net. + //! \c state may be used to compute the interval bounds from \c begin + //! and \c end instead of directly using the returned \c interval. + //! + //! \note \c ]begin,end[ must define a free interval between two TrackSegment. + + //! \function void Track::getBeginIndex ( DbU::Unit position, size_t& begin, unsigned int& state ) const; + //! \param position The position where to search. + //! \param begin Index of the immediatly inferior TrackElement. + //! \param state how to interpret the returned \c begin. + //! + //! Return in \c begin the index of the TrackElement whose minimum is immediately + //! below the requested \c position on the Track axis. The second returned + //! parameter \c state is a set of flags to tell how the \c begin index + //! has to be interpreted. + //! + //! Flags for the \c state are: + //! - Track::BeginIsTrackMin : (implies \c begin=0) there is no TrackElement + //! \e before \c position. + //! - Track::EndIsSegmentMin : The \c begin segment starts \e before \c position. + //! - Track::BeginIsSegmentMin : The \c begin segment starts \e before \c position + //! and ends \e after. + //! - Track::EndIsSegmentMax : The \c begin segment starts \e before \c position + //! and ends \e after. + //! - Track::BeginIsSegmentMax : The \c begin segment starts and ends \e before + //! \c position. + //! - Track::EndIsNextSegmentMin : The \c begin segment starts and ends \e before + //! \c position. So the maximum is given by the \c minimum of the \e next + //! TrackElement. + //! - Track::EndIsTrackMax : There is no TrackElement \e after \c position. + //! + //! Based on the previous flags, we build the \c state parameter: + //! - Track::BeforeFirstElement : the \c position is before the first TrackElement. + //! - Track::InsideElement : the \c position is inside a TrackElement. + //! - Track::OutsideElement : the \c position is in free zone between two + //! TrackElements. + //! - Track::AfterLastElement : the position is after the end of the last + //! element. + //! - Track::EmptyTrack : the track is still empty. + //! + //! To separate flags relevant to \e begin and \e end informations, two masks + //! are provideds: + //! - Track::BeginMask + //! - Track::EndMask + //! + //! \image html TrackBeginIndex-1.png "Fig 3: Track::getBeginIndex()" + //! + //! Reminder for myself: + //! The Track::getBeginIndex() function relies on the \STL \lower_bound + //! function. \c lower_bound() finds the TrackElement immediately \e superior + //! to \c position (shown on Figure 3 by the \c LB label in white on black). + //! + //! The relation between the returned \c begin index and the position is + //! given through the \c state parameter. + + //! \function void Track::getOverlapBounds ( Interval interval, size_t& begin, size_t& end ) const; + //! \param interval the overlaping interval. + //! \param begin where to store the starting bound. + //! \param end where to store the ending bound. + //! + //! find the range of TrackSegment intersecting \e interval. + //! Note that when the \e interval lower bound crosses a set of + //! overlaping intervals from the same \Net, the interval at + //! \e begin will crosses the lower bound but some following + //! of the same \Net may not. + + //! \function TrackCost Track::getOverlapCost ( Interval interval, Net* net, size_t begin, size_t end, unsigned int flags ) const; + //! \param interval the overlaping interval. + //! \param net a Net to ignore (null cost). + //! \param begin the starting bound. + //! \param end the ending bound. + //! \param flags passed to the overlap cost function. + //! \return The cost of the overlap. + //! + //! Compute the cost of the overlap of \e interval with the range + //! \c [begin,end] of TrackSegment. Any TrackSegment belonging to + //! \e net will be ignored. + + //! \function TrackCost Track::getOverlapCost ( Interval interval, Net* net, unsigned int flags ) const; + //! \param interval the overlaping interval. + //! \param net a Net to ignore (null cost). + //! \param flags passed to the overlap cost function. + //! + //! Compute the overlap cost of \e interval with TrackSegment from + //! the current Track, ignoring thoses belonging to \e net. + + //! \function TrackCost Track::getOverlapCost ( TrackElement* segment, unsigned int flags ) const; + //! \param segment under which to compute overlap cost. + //! \param flags passed to the overlap cost function. + //! + //! Compute the overlap cost of \c segment with TrackSegment from + //! the current Track (interval and net are deduced from \c segment). + + //! \function void Track::getTerminalWeight ( Interval interval, Net* net, size_t& count, unsigned int& weight ) const; + //! \param interval under which to compute terminal weight. + //! \param net a net to be ignored. + //! \param count incremented of the number of track markers under the + //! \c interval. + //! \param weight incremented of the sum of the weight of the track markers + //! under the \c interval. + //! + //! Compute and return the sum of the weight of the track markers (see TrackMarker) + //! under \c interval ignoring \c net (that is, \e for \c net). + //! + //! \remark The referenced variables \c count and \c weight are not reset to + //! zero by this function. It is of the caller's responsability. + + //! \function bool Track::check ( unsigned int& overlaps, const char* message=NULL ) const; + //! \param overlaps The number of overlaping segments. + //! \param message An iformative message, only printed if an error occurs. + //! \return \true if the Track contains no incoherencies. + //! + //! Perform a complete Track check. Looks for the following incoherencies : + //! - TrackSegment do not refers this Track. + //! - TrackSegment is detached (TrackSegment::getTrack() is \NULL). + //! - TrackSegment is hollow, this one is very unlikely as hollow + //! TrackSegment are only created for the \lower_bound. + //! - \NULL pointers (should never occurs, nevertheless...) + //! - Two consecutive TrackSegment from different \Net must not + //! overlap. + //! - For TrackSegment starting from the same position, the + //! longuest must be first. + + //! \function void Track::invalidate (); + //! Inconditionnaly invalidate the Track, regardless if it has been + //! modificated. The Track will be forced to be revalidated on closure + //! of the current session. + + //! \function void Track::insert ( TrackElement* segment ); + //! Adds \e segment to the Track. Must only be used inside a + //! Session. They must appears \e after Track::doRemoval() + //! and \e before Track::doReorder(). + //! + //! \sa Kite::Session. + + //! \function void Track::insert ( TrackMarker* marker ); + //! Adds \e marker to the Track. Must only be used inside a + //! Session. + //! + //! \sa Kite::Session. + + //! \function void Track::setSegment ( TrackElement* element, size_t index ); + //! Directly affect the Track entry at position \c index to + //! \c element (use with great care). + //! + //! \sa Kite::Session. + + //! \function size_t Track::doRemoval (); + //! \sreturn The number of removeds TrackSegment. + //! + //! Suppress all the TrackSegment that have been withdraw from the + //! Track. TrackSegment must be withdraw trough the TrackSegment::detach() + //! method which sets their owning Track to \NULL (the removal criterion). + //! It uses the \STL \e remove_if algorithm that put all the to be removed + //! elements at the end of the vector. + //! + //! \sa Kite::Session. + + //! \function void Track::doReorder (); + //! + //! (Re)sort the TrackElement of the vector. Must be called \e after: + //! - Track::doRemoval() so no detached TrackSegment are presents. + //! - All calls to Track::insert(), as the newly inserted elements + //! are put at the back of the vector. + //! + //! \sa Kite::Session. } diff --git a/kite/doc/TrackSegment.dox b/kite/doc/TrackSegment.dox index cb68db85..eb8e54ca 100644 --- a/kite/doc/TrackSegment.dox +++ b/kite/doc/TrackSegment.dox @@ -1,18 +1,13 @@ - // -*- C++ -*- namespace Kite { - /*! \typedef SegmentOverlapCostCB - * Prototype of overlap cost callback functions. - * - * \see TrackSegment::setOverlapCostCB(), TrackSegment::getOverlapCost(). - */ - /*! \class TrackSegment * \brief Derived Katabatic::AutoSegment for the router. * + * \image html TrackSegment-10.png "Fig 1: TrackSegment Context" + * * We create one TrackSegment per aligned Katabatic::AutoSegment set, * the TrackSegment is associated to the canonical one of the set. * @@ -21,150 +16,114 @@ * The drawback beeing that whenever one segment from the aligned * set has it's extention modified, the full extention must be * recomputed. - */ - - - /*! \name Constructors & Destructors - */ - // \{ - - /*! \function static TrackSegment* TrackSegment::create ( AutoSegment* segment, Track* track, bool& created ); - * \param segment The Katabatic AutoSegment to decorate. - * \param track A Track into which insert the TrackSegment (may be \NULL). - * \param created This flag is sets is a new TrackSegment has be created. - * \return A TrackSegment wrapped around an AutoSegment. * - * Constructor mainly used at loading time to decorate the Katabatic - * data-base with the router attributes. - */ - - // \} - - - /*! \name Predicates - */ - // \{ - - /*! \function bool TrackSegment::isLocked () const; - * \Return \True if the TrackSegment is locked (cannot be deleted from the - * Track). - */ - - // \} - - - /*! \name Callback modifier - */ - // \{ - - /*! \function SegmentOverlapCostCB* TrackSegment::setOverlapCostCB ( SegmentOverlapCostCB* cb ); - * \param cb the new overlap cost callback. - * \return the previous overlap cost callback. * - * sets the overlap callback. - */ - - // \} - - - /*! \name Accessors - */ - // \{ - - /*! \function Track* TrackSegment::getTrack () const; - * \Return The Track in which this TrackSegment is inserted (can be \NULL). - */ - - /*! \function size_t TrackSegment::getIndex () const; - * \Return Index of the TrackSegment inside the Track's vector. set to - * Track::NPOS if not inserted in any Track. - */ - - /*! \function unsigned long TrackSegment::getArea () const; - * \Return The priority value used for TrackSegment sorting. Currently, - * the slack of the AutoSegment. - */ - - /*! \function TrackSegment* TrackSegment::getNext () const; - * \Return The next TrackSegment in the Track (can be \NULL). + * \section secTSLazyRevalidate Lazy Revalidate * - * \see Track::getNext(). - */ - - /*! \function TrackSegment* TrackSegment::getPrevious () const; - * \Return The previous TrackSegment in the Track (can be \NULL). + * When the TrackSegment::revalidate() method is called, it only update + * the cached size of the segment (from the AutoSegment set of aligneds) + * and the track into which it may be inserted. * - * \see Track::getPrevious(). - */ - - /*! \function Interval TrackSegment::getFreeInterval () const; - * \Return The free interval around this TrackSegment in the Track. - */ - - /*! \function DbU::Unit TrackSegment::getSourceCanonical () const; - * \Return The leftmost position of the associated aligned segment set. - */ - - /*! \function DbU::Unit TrackSegment::getTargetCanonical () const; - * \Return The rightmost position of the associated aligned segment set. - */ - - /*! \function DbU::Unit TrackSegment::getCanonicalInterval () const; - * \Return The canonical interval of the associated aligned segment set. - */ - - /* \function DbU::Unit TrackSegment::getOverlapCost ( Interval interval, Net* net ) const; - * \param interval the overlaping interval. - * \param net the \Net owning the overlaping interval. - * \return The cost of overlaping the TrackSegment with \e interval from \Net \e net. - */ - - // \} - - - /*! \name Modifiers - */ - // \{ - - /*! \function void TrackSegment::setLock ( bool state ); - * \param state set the Track locking state. - */ - - /*! \function void TrackSegment::setTrack ( Track* track ); - * \param track The Track the TrackSegment is assigned to. - */ - - /*! \function void TrackSegment::setIndex ( size_t index ); - * \param index The index of TrackSegment in the Track's vector. - */ - - /*! \function void TrackSegment::setArea (); - * compute the the sorting criterion used as priority, for - * now it's simply the AutoSegment's slack. - */ - - /*! \function void TrackSegment::detach (); - * remove the TrackSegment from the Track. + * The associated DataNegociate and RoutingEvent are \b not updated. + * - The RoutingEvent will be updated when it's key is updated, + * typically during a requeueing operation \b and in the + * SegmentFsm constructor. This should be optimzed in the future. + * - The DataNegociate is updated \e only in the SegmentFsm + * constructor. This is the most costly of the two updates as + * it perform a perpandicular & parallel connexity exploration. * - * \important This function do not update the Track itself. The - * program must take care of it under penalty of introducing - * incoherencies. * - * \see Track::detach(). + * \section secDogleg Dogleg Management + * + * The basic AutoSegment::canDogleg() method is declined in three more + * dedicated methods in this class: + * - TrackSegment::canDogleg(), for locals only, check if a break + * is possible, never break a segment more than once (to avoid + * fragmentation). + * - TrackSegment::canDogleg(Katabatic::GCell*,unsigned int flags) + * for globals, check that the segment is breakable in the desired + * GCell. Never break twice in the first/last GCell (fragmentation + * limitation), but may \e reuse an already existing dogleg. + * - TrackSegment::canDogleg(Interval), for locals only, direct proxy + * for the AutoSegment method. Never allow more than one break. + * + * Relationship between AutoSegment and TrackSegment + * + * Figure 2 below, shows an example of dogleg creation: + * - At the Katabatic level, AutoSegment \c id:12 is broken. Thus + * the creation of AutoSegments \c id:20 and \c id:21. As per + * specification, the orignal segment \c id:10 remains on the + * left side (source) of the break. + * - But, because the canonical of the former aligned AutoSegment + * set \c (10,11,12,13,14) was on the \e right side of the break, + * the new parallel TrackSegment will be created on the \c left + * side, associated to the newly promoted canonical AutoSegment + * \c id:12. + * + * \image html _makeDogleg-10.png "Fig 2: Dogleg Management" + * + * The TrackSegment::_postDoglegs() method called by all flavors of + * TrackSegment::makeDogleg() methods is responsible for creating new + * TrackSegments for the new doglegs (there may be more than one), it + * also update the dogleg level and source/target dogleg flags. + * + * \redB{This section is not finished.} I need to review the parent and + * doglevel numbering management. There seems to be a risk of infinite + * fragmentation as the numbering of the original segment is not + * increased, we should create a \e break counter separate from + * deepness. + * + * + * \section secWeakGlobal Global, Weak Global and Local Segments + * + * There's a slight semantic change between Katabatic and Kite about + * what is local and what is local. This is due to how we consider the + * intermediate status of \e WeakGlobal. + * + * A \c WeakGlobal segment is a local segment which is aligned with a + * global (though a VTee or an HTee contact). + * + * In Katabatic a local segment is one that is not \c Global, a local segment + * can be both \c Local and \c WeakGlobal. + * + * In Kite a local segment is one that is neither \c Global or \c WeakGlobal. + * The \c WeakGlobal sides with \c Global unlike in Katabatic. + * */ - /* \function void TrackSegment::autoInvalidate (); - * add \e this TrackSegment to the Kite level update Session. - * Something maybe buggy here, or at least not very clean. - */ + //! \function static TrackSegment* TrackSegment::create ( AutoSegment* segment, Track* track, bool& created ); + //! \param segment The Katabatic AutoSegment to decorate. + //! \param track A Track into which insert the TrackSegment (may be \NULL). + //! \param created This flag is sets is a new TrackSegment has be created. + //! \return A TrackSegment wrapped around an AutoSegment. + //! + //! Constructor mainly used at loading time to decorate the Katabatic + //! data-base with the router attributes. - /* \function void TrackSegment::refreshCanonical (); - * Recompute the letfmost & rightmost position of the collapsed set. - * Must be done after each modification of the TrackSegment. - * Dealt by the TrackSession mechanism. - * - */ + //! \function unsigned long TrackElement::getFreedomDegree() const; + //! \sreturn The degree of freedom of the element. It is used as a priority value + //! when sorting TrackElement (in RoutingEvent). + //! + //! Currently, it is the \e slack of the Katabatic::AutoSegment. - // \} + //! \function void TrackSegment::revalidate (); + //! Actualize the TrackSegment characteristics from the supporting + //! elements (set of AutoSegment). + //! + //! This method do not update the DataNegociate or the RoutingEvent. + //! This is a lazy update delayed until the constructor of SegmentFsm is called. + //! (see \ref secTSLazyRevalidate "Lazy Revalidate"). + + //! \function TrackSegment* TrackSegment::_postDoglegs ( TrackElement*& perpandicular, TrackElement*& parallel ); + //! Post-process to be called inside the various dogleg creation or slacken + //! methods. Iterate through the newly created AutoSegments to create, for + //! the perpandicular and the new parallel associateds + //! TrackSegments. Also sets the dogleg levels and flags of the newly + //! created elements. + //! + //! The session dogleg reset is called at the end of this method. The \c perpandicular + //! and \c parallel references to pointers contains the newly created segments + //! for the \b last dogleg. If more than one was created, you cannot access them + //! (the need has not arised yet). } diff --git a/kite/doc/asimbook.cls b/kite/doc/asimbook.cls deleted file mode 100644 index 54270780..00000000 --- a/kite/doc/asimbook.cls +++ /dev/null @@ -1,798 +0,0 @@ -%% -%% This is file `book.cls', -%% generated with the docstrip utility. -%% -%% The original source files were: -%% -%% classes.dtx (with options: `book') -%% -%% This is a generated file. -%% -%% Copyright 1993 1994 1995 1996 1997 1998 1999 2000 2001 -%% The LaTeX3 Project and any individual authors listed elsewhere -%% in this file. -%% -%% This file was generated from file(s) of the LaTeX base system. -%% -------------------------------------------------------------- -%% -%% It may be distributed and/or modified under the -%% conditions of the LaTeX Project Public License, either version 1.2 -%% of this license or (at your option) any later version. -%% The latest version of this license is in -%% http://www.latex-project.org/lppl.txt -%% and version 1.2 or later is part of all distributions of LaTeX -%% version 1999/12/01 or later. -%% -%% This file may only be distributed together with a copy of the LaTeX -%% base system. You may however distribute the LaTeX base system without -%% such generated files. -%% -%% The list of all files belonging to the LaTeX base distribution is -%% given in the file `manifest.txt'. See also `legal.txt' for additional -%% information. -%% -%% \CharacterTable -%% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z -%% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z -%% Digits \0\1\2\3\4\5\6\7\8\9 -%% Exclamation \! Double quote \" Hash (number) \# -%% Dollar \$ Percent \% Ampersand \& -%% Acute accent \' Left paren \( Right paren \) -%% Asterisk \* Plus \+ Comma \, -%% Minus \- Point \. Solidus \/ -%% Colon \: Semicolon \; Less than \< -%% Equals \= Greater than \> Question mark \? -%% Commercial at \@ Left bracket \[ Backslash \\ -%% Right bracket \] Circumflex \^ Underscore \_ -%% Grave accent \` Left brace \{ Vertical bar \| -%% Right brace \} Tilde \~} -\NeedsTeXFormat{LaTeX2e}[1995/12/01] -\ProvidesClass{asimbook} - [2005/11/21 v1.0 - ASIM LaTeX document class] -\newcommand\@ptsize{} -\newif\if@restonecol -\newif\if@titlepage -\@titlepagetrue -\newif\if@openright -\newif\if@mainmatter \@mainmattertrue -\if@compatibility\else -\DeclareOption{a4paper} - {\setlength\paperheight {297mm}% - \setlength\paperwidth {210mm}} -\DeclareOption{a5paper} - {\setlength\paperheight {210mm}% - \setlength\paperwidth {148mm}} -\DeclareOption{b5paper} - {\setlength\paperheight {250mm}% - \setlength\paperwidth {176mm}} -\DeclareOption{letterpaper} - {\setlength\paperheight {11in}% - \setlength\paperwidth {8.5in}} -\DeclareOption{legalpaper} - {\setlength\paperheight {14in}% - \setlength\paperwidth {8.5in}} -\DeclareOption{executivepaper} - {\setlength\paperheight {10.5in}% - \setlength\paperwidth {7.25in}} -\DeclareOption{landscape} - {\setlength\@tempdima {\paperheight}% - \setlength\paperheight {\paperwidth}% - \setlength\paperwidth {\@tempdima}} -\fi -\if@compatibility - \renewcommand\@ptsize{0} -\else -\DeclareOption{10pt}{\renewcommand\@ptsize{0}} -\fi -\DeclareOption{11pt}{\renewcommand\@ptsize{1}} -\DeclareOption{12pt}{\renewcommand\@ptsize{2}} -\if@compatibility\else -\DeclareOption{oneside}{\@twosidefalse \@mparswitchfalse} -\fi -\DeclareOption{twoside}{\@twosidetrue \@mparswitchtrue} -\DeclareOption{draft}{\setlength\overfullrule{5pt}} -\if@compatibility\else -\DeclareOption{final}{\setlength\overfullrule{0pt}} -\fi -\DeclareOption{titlepage}{\@titlepagetrue} -\if@compatibility\else -\DeclareOption{notitlepage}{\@titlepagefalse} -\fi -\if@compatibility -\@openrighttrue -\else -\DeclareOption{openright}{\@openrighttrue} -\DeclareOption{openany}{\@openrightfalse} -\fi -\if@compatibility\else -\DeclareOption{onecolumn}{\@twocolumnfalse} -\fi -\DeclareOption{twocolumn}{\@twocolumntrue} -\DeclareOption{leqno}{\input{leqno.clo}} -\DeclareOption{fleqn}{\input{fleqn.clo}} -\DeclareOption{openbib}{% - \AtEndOfPackage{% - \renewcommand\@openbib@code{% - \advance\leftmargin\bibindent - \itemindent -\bibindent - \listparindent \itemindent - \parsep \z@ - }% - \renewcommand\newblock{\par}}% -} -\ExecuteOptions{letterpaper,10pt,twoside,onecolumn,final,openright} -\ProcessOptions -\input{bk1\@ptsize.clo} -\setlength\lineskip{1\p@} -\setlength\normallineskip{1\p@} -\renewcommand\baselinestretch{} -\setlength\parskip{0\p@ \@plus \p@} -\@lowpenalty 51 -\@medpenalty 151 -\@highpenalty 301 -\setcounter{topnumber}{2} -\renewcommand\topfraction{.7} -\setcounter{bottomnumber}{1} -\renewcommand\bottomfraction{.3} -\setcounter{totalnumber}{3} -\renewcommand\textfraction{.2} -\renewcommand\floatpagefraction{.5} -\setcounter{dbltopnumber}{2} -\renewcommand\dbltopfraction{.7} -\renewcommand\dblfloatpagefraction{.5} -%%%% Select Chapter font. -\newcommand \textchapter [1] {\textsf{\textbf{#1}}} -\newcommand \fontchapter {\sffamily \bfseries} -\if@twoside - \def\ps@headings{% - \let\@oddfoot\@empty\let\@evenfoot\@empty - \def\@evenhead{\thepage\hfil\slshape\leftmark}% - \def\@oddhead{{\slshape\rightmark}\hfil\thepage}% - \let\@mkboth\markboth - \def\chaptermark##1{% - \markboth {\MakeUppercase{% - \ifnum \c@secnumdepth >\m@ne - \if@mainmatter - \@chapapp\ \thechapter. \ % - \fi - \fi - ##1}}{}}% - \def\sectionmark##1{% - \markright {\MakeUppercase{% - \ifnum \c@secnumdepth >\z@ - \thesection. \ % - \fi - ##1}}}} -\else - \def\ps@headings{% - \let\@oddfoot\@empty - \def\@oddhead{{\slshape\rightmark}\hfil\thepage}% - \let\@mkboth\markboth - \def\chaptermark##1{% - \markright {\MakeUppercase{% - \ifnum \c@secnumdepth >\m@ne - \if@mainmatter - \@chapapp\ \thechapter. \ % - \fi - \fi - ##1}}}} -\fi -\def\ps@myheadings{% - \let\@oddfoot\@empty\let\@evenfoot\@empty - \def\@evenhead{\thepage\hfil\slshape\leftmark}% - \def\@oddhead{{\slshape\rightmark}\hfil\thepage}% - \let\@mkboth\@gobbletwo - \let\chaptermark\@gobble - \let\sectionmark\@gobble - } - \if@titlepage - \newcommand\maketitle{\begin{titlepage}% - \let\footnotesize\small - \let\footnoterule\relax - \let \footnote \thanks - \null\vfil - \vskip 60\p@ - \begin{center}% - {\LARGE \@title \par}% - \vskip 3em% - {\large - \lineskip .75em% - \begin{tabular}[t]{c}% - \@author - \end{tabular}\par}% - \vskip 1.5em% - {\large \@date \par}% % Set date in \large size. - \end{center}\par - \@thanks - \vfil\null - \end{titlepage}% - \setcounter{footnote}{0}% - \global\let\thanks\relax - \global\let\maketitle\relax - \global\let\@thanks\@empty - \global\let\@author\@empty - \global\let\@date\@empty - \global\let\@title\@empty - \global\let\title\relax - \global\let\author\relax - \global\let\date\relax - \global\let\and\relax -} -\else -\newcommand\maketitle{\par - \begingroup - \renewcommand\thefootnote{\@fnsymbol\c@footnote}% - \def\@makefnmark{\rlap{\@textsuperscript{\normalfont\@thefnmark}}}% - \long\def\@makefntext##1{\parindent 1em\noindent - \hb@xt@1.8em{% - \hss\@textsuperscript{\normalfont\@thefnmark}}##1}% - \if@twocolumn - \ifnum \col@number=\@ne - \@maketitle - \else - \twocolumn[\@maketitle]% - \fi - \else - \newpage - \global\@topnum\z@ % Prevents figures from going at top of page. - \@maketitle - \fi - \thispagestyle{plain}\@thanks - \endgroup - \setcounter{footnote}{0}% - \global\let\thanks\relax - \global\let\maketitle\relax - \global\let\@maketitle\relax - \global\let\@thanks\@empty - \global\let\@author\@empty - \global\let\@date\@empty - \global\let\@title\@empty - \global\let\title\relax - \global\let\author\relax - \global\let\date\relax - \global\let\and\relax -} -\def\@maketitle{% - \newpage - \null - \vskip 2em% - \begin{center}% - \let \footnote \thanks - {\LARGE \@title \par}% - \vskip 1.5em% - {\large - \lineskip .5em% - \begin{tabular}[t]{c}% - \@author - \end{tabular}\par}% - \vskip 1em% - {\large \@date}% - \end{center}% - \par - \vskip 1.5em} -\fi -\newcommand*\chaptermark[1]{} -\setcounter{secnumdepth}{2} -\newcounter {part} -\newcounter {chapter} -\newcounter {section}[chapter] -\newcounter {subsection}[section] -\newcounter {subsubsection}[subsection] -\newcounter {paragraph}[subsubsection] -\newcounter {subparagraph}[paragraph] -\renewcommand \thepart {\@Roman\c@part} -\renewcommand \thechapter {\@arabic\c@chapter} -\renewcommand \thesection {\thechapter.\@arabic\c@section} -\renewcommand\thesubsection {\thesection.\@arabic\c@subsection} -\renewcommand\thesubsubsection{\thesubsection .\@arabic\c@subsubsection} -\renewcommand\theparagraph {\thesubsubsection.\@arabic\c@paragraph} -\renewcommand\thesubparagraph {\theparagraph.\@arabic\c@subparagraph} -\newcommand\@chapapp{\chaptername} -\newcommand\frontmatter{% - \cleardoublepage - \@mainmatterfalse - \pagenumbering{roman}} -\newcommand\mainmatter{% - \cleardoublepage - \@mainmattertrue - \pagenumbering{arabic}} -\newcommand\backmatter{% - \if@openright - \cleardoublepage - \else - \clearpage - \fi - \@mainmatterfalse} -\newcommand\part{% - \if@openright - \cleardoublepage - \else - \clearpage - \fi - \thispagestyle{plain}% - \if@twocolumn - \onecolumn - \@tempswatrue - \else - \@tempswafalse - \fi - \null\vfil - \secdef\@part\@spart} - -\def\@part[#1]#2{% - \ifnum \c@secnumdepth >-2\relax - \refstepcounter{part}% - \addcontentsline{toc}{part}{\thepart\hspace{1em}#1}% - \else - \addcontentsline{toc}{part}{#1}% - \fi - \markboth{}{}% - {\centering - \interlinepenalty \@M - \normalfont - \ifnum \c@secnumdepth >-2\relax - \huge\bfseries \partname\nobreakspace\thepart - \par - \vskip 20\p@ - \fi - \Huge \bfseries #2\par}% - \@endpart} -\def\@spart#1{% - {\centering - \interlinepenalty \@M - \normalfont - \Huge \bfseries #1\par}% - \@endpart} -\def\@endpart{\vfil\newpage - \if@twoside - \if@openright - \null - \thispagestyle{empty}% - \newpage - \fi - \fi - \if@tempswa - \twocolumn - \fi} -\newcommand\chapter{\if@openright\cleardoublepage\else\clearpage\fi - \thispagestyle{plain}% - \global\@topnum\z@ - \@afterindentfalse - \secdef\@chapter\@schapter} -\def\@chapter[#1]#2{\ifnum \c@secnumdepth >\m@ne - \if@mainmatter - \refstepcounter{chapter}% - \typeout{\@chapapp\space\thechapter.}% - \addcontentsline{toc}{chapter}% - {\protect\numberline{\thechapter}#1}% - \else - \addcontentsline{toc}{chapter}{#1}% - \fi - \else - \addcontentsline{toc}{chapter}{#1}% - \fi - \chaptermark{#1}% - \addtocontents{lof}{\protect\addvspace{10\p@}}% - \addtocontents{lot}{\protect\addvspace{10\p@}}% - \if@twocolumn - \@topnewpage[\@makechapterhead{#2}]% - \else - \@makechapterhead{#2}% - \@afterheading - \fi} -%%%%\def\@makechapterhead#1{% -%%%% \vspace*{50\p@}% -%%%% {\parindent \z@ \raggedright \normalfont -%%%% \ifnum \c@secnumdepth >\m@ne -%%%% \if@mainmatter -%%%% \huge\bfseries \@chapapp\space \thechapter -%%%% \par\nobreak -%%%% \vskip 20\p@ -%%%% \fi -%%%% \fi -%%%% \interlinepenalty\@M -%%%% \Huge \bfseries #1\par\nobreak -%%%% \vskip 40\p@ -%%%% }} - \newlength \titlewidth - \setlength \titlewidth {\textwidth} - \addtolength \titlewidth {\marginparwidth} - \addtolength \titlewidth {\marginparsep} - \def\@makechapterhead#1{% - \vspace*{50\p@}% - {\parindent \z@ \raggedleft \fontchapter - \ifnum \c@secnumdepth >\m@ne - \if@mainmatter - \huge \@chapapp\space \thechapter - \par\nobreak - \vskip 20\p@ - \fi - \fi - \interlinepenalty\@M - \hsize=\titlewidth - \Huge #1 \par\nobreak - \hsize=\textwidth - \vskip 40\p@ - }} -\def\@schapter#1{\if@twocolumn - \@topnewpage[\@makeschapterhead{#1}]% - \else - \@makeschapterhead{#1}% - \@afterheading - \fi} -%%%%\def\@makeschapterhead#1{% -%%%% \vspace*{50\p@}% -%%%% {\parindent \z@ \raggedright -%%%% \normalfont -%%%% \interlinepenalty\@M -%%%% \Huge \bfseries #1\par\nobreak -%%%% \vskip 40\p@ -%%%% }} - \def\@makeschapterhead#1{% - \vspace*{50\p@}% - {\parindent \z@ \raggedright - \normalfont - \interlinepenalty\@M - \hsize=\titlewidth - \flushright - \Huge \bfseries #1\par\nobreak - \hsize=\textwidth - \vskip 40\p@ - }} -\newcommand\section{\@startsection {section}{1}{\z@}% - {-3.5ex \@plus -1ex \@minus -.2ex}% - {2.3ex \@plus.2ex}% - {\normalfont\Large\bfseries}} -\newcommand\subsection{\@startsection{subsection}{2}{\z@}% - {-3.25ex\@plus -1ex \@minus -.2ex}% - {1.5ex \@plus .2ex}% - {\normalfont\large\bfseries}} -\newcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}% - {-3.25ex\@plus -1ex \@minus -.2ex}% - {1.5ex \@plus .2ex}% - {\normalfont\normalsize\bfseries}} -\newcommand\paragraph{\@startsection{paragraph}{4}{\z@}% - {3.25ex \@plus1ex \@minus.2ex}% - {-1em}% - {\normalfont\normalsize\bfseries}} -\newcommand\subparagraph{\@startsection{subparagraph}{5}{\parindent}% - {3.25ex \@plus1ex \@minus .2ex}% - {-1em}% - {\normalfont\normalsize\bfseries}} -\if@twocolumn - \setlength\leftmargini {2em} -\else - \setlength\leftmargini {2.5em} -\fi -\leftmargin \leftmargini -\setlength\leftmarginii {2.2em} -\setlength\leftmarginiii {1.87em} -\setlength\leftmarginiv {1.7em} -\if@twocolumn - \setlength\leftmarginv {.5em} - \setlength\leftmarginvi {.5em} -\else - \setlength\leftmarginv {1em} - \setlength\leftmarginvi {1em} -\fi -\setlength \labelsep {.5em} -\setlength \labelwidth{\leftmargini} -\addtolength\labelwidth{-\labelsep} -\@beginparpenalty -\@lowpenalty -\@endparpenalty -\@lowpenalty -\@itempenalty -\@lowpenalty -\renewcommand\theenumi{\@arabic\c@enumi} -\renewcommand\theenumii{\@alph\c@enumii} -\renewcommand\theenumiii{\@roman\c@enumiii} -\renewcommand\theenumiv{\@Alph\c@enumiv} -\newcommand\labelenumi{\theenumi.} -\newcommand\labelenumii{(\theenumii)} -\newcommand\labelenumiii{\theenumiii.} -\newcommand\labelenumiv{\theenumiv.} -\renewcommand\p@enumii{\theenumi} -\renewcommand\p@enumiii{\theenumi(\theenumii)} -\renewcommand\p@enumiv{\p@enumiii\theenumiii} -\newcommand\labelitemi{\textbullet} -\newcommand\labelitemii{\normalfont\bfseries \textendash} -\newcommand\labelitemiii{\textasteriskcentered} -\newcommand\labelitemiv{\textperiodcentered} -\newenvironment{description} - {\list{}{\labelwidth\z@ \itemindent-\leftmargin - \let\makelabel\descriptionlabel}} - {\endlist} -\newcommand*\descriptionlabel[1]{\hspace\labelsep - \normalfont\bfseries #1} -\newenvironment{verse} - {\let\\\@centercr - \list{}{\itemsep \z@ - \itemindent -1.5em% - \listparindent\itemindent - \rightmargin \leftmargin - \advance\leftmargin 1.5em}% - \item\relax} - {\endlist} -\newenvironment{quotation} - {\list{}{\listparindent 1.5em% - \itemindent \listparindent - \rightmargin \leftmargin - \parsep \z@ \@plus\p@}% - \item\relax} - {\endlist} -\newenvironment{quote} - {\list{}{\rightmargin\leftmargin}% - \item\relax} - {\endlist} -\if@compatibility -\newenvironment{titlepage} - {% - \cleardoublepage - \if@twocolumn - \@restonecoltrue\onecolumn - \else - \@restonecolfalse\newpage - \fi - \thispagestyle{empty}% - \setcounter{page}\z@ - }% - {\if@restonecol\twocolumn \else \newpage \fi - } -\else -\newenvironment{titlepage} - {% - \cleardoublepage - \if@twocolumn - \@restonecoltrue\onecolumn - \else - \@restonecolfalse\newpage - \fi - \thispagestyle{empty}% - \setcounter{page}\@ne - }% - {\if@restonecol\twocolumn \else \newpage \fi - \if@twoside\else - \setcounter{page}\@ne - \fi - } -\fi -\newcommand\appendix{\par - \setcounter{chapter}{0}% - \setcounter{section}{0}% - \gdef\@chapapp{\appendixname}% - \gdef\thechapter{\@Alph\c@chapter}} -\setlength\arraycolsep{5\p@} -\setlength\tabcolsep{6\p@} -\setlength\arrayrulewidth{.4\p@} -\setlength\doublerulesep{2\p@} -\setlength\tabbingsep{\labelsep} -\skip\@mpfootins = \skip\footins -\setlength\fboxsep{3\p@} -\setlength\fboxrule{.4\p@} -\@addtoreset {equation}{chapter} -\renewcommand\theequation - {\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@equation} -\newcounter{figure}[chapter] -\renewcommand \thefigure - {\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@figure} -\def\fps@figure{tbp} -\def\ftype@figure{1} -\def\ext@figure{lof} -\def\fnum@figure{\figurename\nobreakspace\thefigure} -\newenvironment{figure} - {\@float{figure}} - {\end@float} -\newenvironment{figure*} - {\@dblfloat{figure}} - {\end@dblfloat} -\newcounter{table}[chapter] -\renewcommand \thetable - {\ifnum \c@chapter>\z@ \thechapter.\fi \@arabic\c@table} -\def\fps@table{tbp} -\def\ftype@table{2} -\def\ext@table{lot} -\def\fnum@table{\tablename\nobreakspace\thetable} -\newenvironment{table} - {\@float{table}} - {\end@float} -\newenvironment{table*} - {\@dblfloat{table}} - {\end@dblfloat} -\newlength\abovecaptionskip -\newlength\belowcaptionskip -\setlength\abovecaptionskip{10\p@} -\setlength\belowcaptionskip{0\p@} -\long\def\@makecaption#1#2{% - \vskip\abovecaptionskip - \sbox\@tempboxa{#1: #2}% - \ifdim \wd\@tempboxa >\hsize - #1: #2\par - \else - \global \@minipagefalse - \hb@xt@\hsize{\hfil\box\@tempboxa\hfil}% - \fi - \vskip\belowcaptionskip} -\DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm} -\DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf} -\DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt} -\DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf} -\DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit} -\DeclareOldFontCommand{\sl}{\normalfont\slshape}{\@nomath\sl} -\DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc} -\DeclareRobustCommand*\cal{\@fontswitch\relax\mathcal} -\DeclareRobustCommand*\mit{\@fontswitch\relax\mathnormal} -\newcommand\@pnumwidth{1.55em} -\newcommand\@tocrmarg{2.55em} -\newcommand\@dotsep{4.5} -\setcounter{tocdepth}{2} -\newcommand\tableofcontents{% - \if@twocolumn - \@restonecoltrue\onecolumn - \else - \@restonecolfalse - \fi - \chapter*{\contentsname - \@mkboth{% - \MakeUppercase\contentsname}{\MakeUppercase\contentsname}}% - \@starttoc{toc}% - \if@restonecol\twocolumn\fi - } -\newcommand*\l@part[2]{% - \ifnum \c@tocdepth >-2\relax - \addpenalty{-\@highpenalty}% - \addvspace{2.25em \@plus\p@}% - \setlength\@tempdima{3em}% - \begingroup - \parindent \z@ \rightskip \@pnumwidth - \parfillskip -\@pnumwidth - {\leavevmode - \large \bfseries #1\hfil \hb@xt@\@pnumwidth{\hss #2}}\par - \nobreak - \global\@nobreaktrue - \everypar{\global\@nobreakfalse\everypar{}}% - \endgroup - \fi} -%%%%\newcommand*\l@chapter[2]{% -%%%% \ifnum \c@tocdepth >\m@ne -%%%% \addpenalty{-\@highpenalty}% -%%%% \vskip 1.0em \@plus\p@ -%%%% \setlength\@tempdima{1.5em}% -%%%% \begingroup -%%%% \parindent \z@ \rightskip \@pnumwidth -%%%% \parfillskip -\@pnumwidth -%%%% \leavevmode \bfseries -%%%% \advance\leftskip\@tempdima -%%%% \hskip -\leftskip -%%%% #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par -%%%% \penalty\@highpenalty -%%%% \endgroup -%%%% \fi} -\newcommand\l@chapter[2]{% - \ifnum \c@tocdepth >\m@ne - \addpenalty{-\@highpenalty}% - \vskip 1.0em \@plus\p@ - \setlength\@tempdima{1.5em}% - \begingroup - \parindent \z@ \rightskip \@pnumwidth - \parfillskip -\@pnumwidth - \leavevmode \fontchapter - \advance\leftskip\@tempdima - \hskip -\leftskip - #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par - \penalty\@highpenalty - \endgroup - \fi} -\newcommand*\l@section{\@dottedtocline{1}{1.5em}{2.3em}} -\newcommand*\l@subsection{\@dottedtocline{2}{3.8em}{3.2em}} -\newcommand*\l@subsubsection{\@dottedtocline{3}{7.0em}{4.1em}} -\newcommand*\l@paragraph{\@dottedtocline{4}{10em}{5em}} -\newcommand*\l@subparagraph{\@dottedtocline{5}{12em}{6em}} -\newcommand\listoffigures{% - \if@twocolumn - \@restonecoltrue\onecolumn - \else - \@restonecolfalse - \fi - \chapter*{\listfigurename}% - \@mkboth{\MakeUppercase\listfigurename}% - {\MakeUppercase\listfigurename}% - \@starttoc{lof}% - \if@restonecol\twocolumn\fi - } -\newcommand*\l@figure{\@dottedtocline{1}{1.5em}{2.3em}} -\newcommand\listoftables{% - \if@twocolumn - \@restonecoltrue\onecolumn - \else - \@restonecolfalse - \fi - \chapter*{\listtablename}% - \@mkboth{% - \MakeUppercase\listtablename}% - {\MakeUppercase\listtablename}% - \@starttoc{lot}% - \if@restonecol\twocolumn\fi - } -\let\l@table\l@figure -\newdimen\bibindent -\setlength\bibindent{1.5em} -\newenvironment{thebibliography}[1] - {\chapter*{\bibname}% - \@mkboth{\MakeUppercase\bibname}{\MakeUppercase\bibname}% - \list{\@biblabel{\@arabic\c@enumiv}}% - {\settowidth\labelwidth{\@biblabel{#1}}% - \leftmargin\labelwidth - \advance\leftmargin\labelsep - \@openbib@code - \usecounter{enumiv}% - \let\p@enumiv\@empty - \renewcommand\theenumiv{\@arabic\c@enumiv}}% - \sloppy - \clubpenalty4000 - \@clubpenalty \clubpenalty - \widowpenalty4000% - \sfcode`\.\@m} - {\def\@noitemerr - {\@latex@warning{Empty `thebibliography' environment}}% - \endlist} -\newcommand\newblock{\hskip .11em\@plus.33em\@minus.07em} -\let\@openbib@code\@empty -\newenvironment{theindex} - {\if@twocolumn - \@restonecolfalse - \else - \@restonecoltrue - \fi - \columnseprule \z@ - \columnsep 35\p@ - \twocolumn[\@makeschapterhead{\indexname}]% - \@mkboth{\MakeUppercase\indexname}% - {\MakeUppercase\indexname}% - \thispagestyle{plain}\parindent\z@ - \parskip\z@ \@plus .3\p@\relax - \let\item\@idxitem} - {\if@restonecol\onecolumn\else\clearpage\fi} -\newcommand\@idxitem{\par\hangindent 40\p@} -\newcommand\subitem{\@idxitem \hspace*{20\p@}} -\newcommand\subsubitem{\@idxitem \hspace*{30\p@}} -\newcommand\indexspace{\par \vskip 10\p@ \@plus5\p@ \@minus3\p@\relax} -\renewcommand\footnoterule{% - \kern-3\p@ - \hrule\@width.4\columnwidth - \kern2.6\p@} -\@addtoreset{footnote}{chapter} -\newcommand\@makefntext[1]{% - \parindent 1em% - \noindent - \hb@xt@1.8em{\hss\@makefnmark}#1} -\newcommand\contentsname{Contents} -\newcommand\listfigurename{List of Figures} -\newcommand\listtablename{List of Tables} -\newcommand\bibname{Bibliography} -\newcommand\indexname{Index} -\newcommand\figurename{Figure} -\newcommand\tablename{Table} -\newcommand\partname{Part} -\newcommand\chaptername{Chapter} -\newcommand\appendixname{Appendix} -\def\today{\ifcase\month\or - January\or February\or March\or April\or May\or June\or - July\or August\or September\or October\or November\or December\fi - \space\number\day, \number\year} -\setlength\columnsep{10\p@} -\setlength\columnseprule{0\p@} -\pagestyle{headings} -\pagenumbering{arabic} -\if@twoside -\else - \raggedbottom -\fi -\if@twocolumn - \twocolumn - \sloppy - \flushbottom -\else - \onecolumn -\fi -\endinput -%% -%% End of file `book.cls'. diff --git a/kite/doc/doxyfile b/kite/doc/doxyfile index a51583ff..9824b7d8 100644 --- a/kite/doc/doxyfile +++ b/kite/doc/doxyfile @@ -1,3 +1,5 @@ +# -*- explicit-buffer-name: "doxyfile" -*- + # Doxyfile 1.3.4 # -------------------------------------------------------------------- @@ -24,7 +26,8 @@ TAB_SIZE = 2 ALIASES = "function=\fn"\ "important=\par Important:\n"\ "remark=\par Remark:\n"\ - "Return=Returns:"\ + "sreturn=\b Returns:"\ + "sa=See also: "\ "True=\b True"\ "true=\b true"\ "False=\b False"\ @@ -33,7 +36,7 @@ ALIASES = "function=\fn"\ "HORIZONTAL=\b HORIZONTAL"\ "NULL=\c NULL"\ "vector=\c vector"\ - "lower_bound=\c lower_bound"\ + "lower_bound=\c lower_bound()"\ "Collection=\c Collection"\ "Collections=\c Collections"\ "Interval=\c Interval"\ @@ -72,7 +75,9 @@ ALIASES = "function=\fn"\ "Session=\c Session"\ "Sessions=\c Sessions"\ "Hurricane=Hurricane"\ - "STL=STL" + "STL=STL"\ + "red{1}=\1" \ + "redB{1}=\1" OPTIMIZE_OUTPUT_FOR_C = NO OPTIMIZE_OUTPUT_JAVA = NO SUBGROUPING = YES @@ -91,7 +96,7 @@ HIDE_FRIEND_COMPOUNDS = NO HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES -HIDE_SCOPE_NAMES = NO +HIDE_SCOPE_NAMES = YES SHOW_INCLUDE_FILES = YES INLINE_INFO = YES SORT_MEMBER_DOCS = NO @@ -117,13 +122,30 @@ WARN_LOGFILE = # Configuration options related to the input files INPUT = \ - ../src/kite/TrackSegment.h ../src/TrackSegment.cpp TrackSegment.dox \ - ../src/kite/TrackSegmentCost.h ../src/TrackSegmentCost.cpp TrackSegmentCost.dox \ - ../src/kite/Track.h ../src/Track.cpp Track.dox \ - ../src/kite/TrackCost.h ../src/TrackCost.cpp TrackCost.dox \ - ../src/kite/RoutingEvent.h ../src/RoutingEvent.cpp RoutingEvent.dox \ - ../src/kite/Session.h Session.dox \ - Kite.dox + ../src/kite/Constants.h Constants.dox \ + ../src/kite/KiteEngine.h KiteEngine.dox \ + ../src/kite/DataNegociate.h ../src/DataNegociate.cpp DataNegociate.dox \ + ../src/kite/TrackMarker.h ../src/TrackMarker.cpp TrackMarker.dox \ + ../src/kite/TrackElement.h ../src/TrackElement.cpp TrackElement.dox \ + ../src/kite/TrackSegment.h ../src/TrackSegment.cpp TrackSegment.dox \ + ../src/kite/TrackFixedSegment.h ../src/TrackFixedSegment.cpp TrackFixedSegment.dox \ + ../src/kite/Track.h ../src/Track.cpp Track.dox \ + ../src/kite/HorizontalTrack.h ../src/HorizontalTrack.cpp HorizontalTrack.dox \ + ../src/kite/VerticalTrack.h ../src/VerticalTrack.cpp VerticalTrack.dox \ + ../src/kite/RoutingPlane.h ../src/RoutingPlane.cpp RoutingPlane.dox \ + ../src/kite/Manipulator.h ../src/Manipulator.cpp Manipulator.dox \ + ../src/kite/SegmentFsm.h ../src/SegmentFsm.cpp SegmentFsm.dox \ + ../src/kite/RoutingEvent.h ../src/RoutingEvent.cpp RoutingEvent.dox \ + ../src/kite/RoutingEventQueue.h ../src/RoutingEventQueue.cpp RoutingEventQueue.dox \ + ../src/kite/RoutingEventLoop.h ../src/RoutingEventLoop.cpp RoutingEventLoop.dox \ + ../src/kite/RoutingEventHistory.h ../src/RoutingEventHistory.cpp RoutingEventHistory.dox \ + ../src/kite/NegociateWindow.h ../src/NegociateWindow.cpp NegociateWindow.dox \ + ../src/kite/Session.h Session.dox \ + Kite.dox \ + notes.dox + +# ../src/kite/TrackSegmentCost.h ../src/TrackSegmentCost.cpp TrackSegmentCost.dox \ +# ../src/kite/TrackCost.h ../src/TrackCost.cpp TrackCost.dox \ FILE_PATTERNS = *.h \ *.cpp \ @@ -166,7 +188,7 @@ HTML_OUTPUT = html HTML_FILE_EXTENSION = .html HTML_HEADER = header.html HTML_FOOTER = footer.html -HTML_STYLESHEET = ASIM.css +HTML_STYLESHEET = SoC.css HTML_ALIGN_MEMBERS = YES GENERATE_HTMLHELP = NO CHM_FILE = @@ -250,7 +272,7 @@ SKIP_FUNCTION_MACROS = YES # -------------------------------------------------------------------- # Configuration options related to external references -TAGFILES = ../../../../hurricane/doc/hurricane/html/hurricane.tag=../hurricane \ +TAGFILES = ../../hurricane/doc/hurricane/html/hurricane.tag=../hurricane \ ../../katabatic/doc/html/katabatic.tag=../katabatic GENERATE_TAGFILE = html/kite.tag ALLEXTERNALS = NO diff --git a/kite/doc/footer.html b/kite/doc/footer.html index d0245539..e0fc72ad 100644 --- a/kite/doc/footer.html +++ b/kite/doc/footer.html @@ -9,7 +9,7 @@ - +
    Kite - Detailed RouterCopyright © 2008-2009 LIP6. All rights reservedCopyright © 2008-2013 UPMC. All rights reserved
    diff --git a/kite/doc/header.html b/kite/doc/header.html index bf039968..0806b4a4 100644 --- a/kite/doc/header.html +++ b/kite/doc/header.html @@ -1,17 +1,16 @@ - Kite - Detailed Router: Router Documentation - + Kite - Detailed Router +

    Kite - Detailed Router

    - - + - + diff --git a/kite/doc/images/ConflictSolve-1.fig b/kite/doc/images/ConflictSolve-1.fig new file mode 100644 index 00000000..d36cc429 --- /dev/null +++ b/kite/doc/images/ConflictSolve-1.fig @@ -0,0 +1,96 @@ +#FIG 3.2 Produced by xfig version 3.2.5a +Landscape +Center +Inches +Letter +80.00 +Single +-2 +1200 2 +0 32 #ffffdd +6 750 525 11400 1050 +2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2400 600 9900 600 +2 1 0 1 0 7 100 -1 -1 0.000 0 0 -1 0 0 2 + 1200 900 11400 900 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1500 900 4500 900 +4 0 0 50 -1 12 14 0.0000 4 105 150 1500 825 a\001 +4 2 0 50 -1 14 14 0.0000 4 180 450 1200 975 [3]\001 +-6 +6 750 975 11400 1350 +2 1 0 1 0 7 100 -1 -1 0.000 0 0 -1 0 0 2 + 1200 1200 11400 1200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2100 1200 5100 1200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 8100 1200 11100 1200 +4 0 0 50 -1 12 14 0.0000 4 150 150 2100 1125 b\001 +4 0 0 50 -1 12 14 0.0000 4 150 150 8100 1125 f\001 +4 2 0 50 -1 14 14 0.0000 4 180 450 1200 1275 [2]\001 +-6 +6 750 1275 11400 1650 +2 1 0 1 0 7 100 -1 -1 0.000 0 0 -1 0 0 2 + 1200 1500 11400 1500 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2700 1500 5700 1500 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 7500 1500 10500 1500 +4 0 0 50 -1 12 14 0.0000 4 105 150 2700 1425 c\001 +4 0 0 50 -1 12 14 0.0000 4 105 150 7500 1425 e\001 +4 2 0 50 -1 14 14 0.0000 4 180 450 1200 1575 [1]\001 +-6 +6 750 1575 11400 1950 +2 1 0 1 0 7 100 -1 -1 0.000 0 0 -1 0 0 2 + 1200 1800 11400 1800 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6900 1800 9900 1800 +4 0 0 50 -1 12 14 0.0000 4 150 150 6900 1725 d\001 +4 2 0 50 -1 14 14 0.0000 4 180 450 1200 1875 [0]\001 +-6 +6 750 2775 11400 4050 +6 750 2775 11400 3150 +2 1 0 1 0 7 100 -1 -1 0.000 0 0 -1 0 0 2 + 1200 3000 11400 3000 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1500 3000 4500 3000 +4 0 0 50 -1 12 14 0.0000 4 105 150 1500 2925 a\001 +4 2 0 50 -1 14 14 0.0000 4 180 450 1200 3075 [3]\001 +-6 +6 750 3075 11400 3450 +2 1 0 1 0 7 100 -1 -1 0.000 0 0 -1 0 0 2 + 1200 3300 11400 3300 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2100 3300 5100 3300 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 8100 3300 11100 3300 +4 0 0 50 -1 12 14 0.0000 4 150 150 2100 3225 b\001 +4 0 0 50 -1 12 14 0.0000 4 150 150 8100 3225 f\001 +4 2 0 50 -1 14 14 0.0000 4 180 450 1200 3375 [2]\001 +-6 +6 750 3375 11400 3750 +2 1 0 1 0 7 100 -1 -1 0.000 0 0 -1 0 0 2 + 1200 3600 11400 3600 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2700 3600 5700 3600 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 7575 3600 10575 3600 +4 0 0 50 -1 12 14 0.0000 4 105 150 2700 3525 c\001 +4 0 0 50 -1 12 14 0.0000 4 105 150 7575 3525 e\001 +4 2 0 50 -1 14 14 0.0000 4 180 450 1200 3675 [1]\001 +-6 +6 750 3675 11400 4050 +2 1 0 1 0 7 100 -1 -1 0.000 0 0 -1 0 0 2 + 1200 3900 11400 3900 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6900 3900 9900 3900 +4 0 0 50 -1 12 14 0.0000 4 150 150 6900 3825 d\001 +4 0 4 50 -1 14 14 0.0000 4 150 150 2400 3825 g\001 +4 2 0 50 -1 14 14 0.0000 4 180 450 1200 3975 [0]\001 +-6 +2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 2400 3900 6300 3900 6300 3000 9900 3000 +-6 +2 2 0 0 0 32 200 -1 20 0.000 0 0 -1 0 0 5 + 675 0 11700 0 11700 4500 675 4500 675 0 +4 0 4 50 -1 14 14 0.0000 4 150 150 2400 525 g\001 diff --git a/kite/doc/images/ConflictSolve-1.png b/kite/doc/images/ConflictSolve-1.png new file mode 100644 index 0000000000000000000000000000000000000000..d3e70ce2255bc4e7a6f87e1991e35e5933f67175 GIT binary patch literal 4012 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 LMY>o1yMy@;gu1#x literal 0 HcmV?d00001 diff --git a/kite/doc/images/ConflictSolveByHistory-2.fig b/kite/doc/images/ConflictSolveByHistory-2.fig new file mode 100644 index 00000000..b1000acb --- /dev/null +++ b/kite/doc/images/ConflictSolveByHistory-2.fig @@ -0,0 +1,116 @@ +#FIG 3.2 Produced by xfig version 3.2.5a +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +0 32 #ffffdd +6 1425 6825 5850 7575 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 1575 6900 1500 6900 1500 7500 1575 7500 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 3375 6900 3300 6900 3300 7500 3375 7500 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 2775 7425 2700 7425 2700 6975 2775 6975 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 5775 7425 5700 7425 5700 6975 5775 6975 +2 2 0 0 0 0 70 -1 10 0.000 0 0 -1 0 0 5 + 1500 7050 3300 7050 3300 7350 1500 7350 1500 7050 +2 1 0 4 1 7 60 -1 -1 0.000 0 0 -1 0 0 2 + 1500 7200 5700 7200 +2 2 0 0 0 0 70 -1 10 0.000 0 0 -1 0 0 5 + 2700 7125 5700 7125 5700 7275 2700 7275 2700 7125 +-6 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 3375 2700 3300 2700 3300 3300 3375 3300 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 5175 2700 5100 2700 5100 3300 5175 3300 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 4575 3225 4500 3225 4500 2775 4575 2775 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 7575 3225 7500 3225 7500 2775 7575 2775 +2 2 0 0 0 0 70 -1 10 0.000 0 0 -1 0 0 5 + 3300 2850 5100 2850 5100 3150 3300 3150 3300 2850 +2 1 0 4 1 7 60 -1 -1 0.000 0 0 -1 0 0 2 + 3300 3000 7500 3000 +2 2 0 0 0 0 70 -1 10 0.000 0 0 -1 0 0 5 + 4500 2925 7500 2925 7500 3075 4500 3075 4500 2925 +2 1 0 1 0 7 100 -1 -1 0.000 0 0 -1 0 0 2 + 1200 3000 9600 3000 +2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 6375 2250 6300 2250 6300 2550 6375 2550 +2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 1875 2250 1800 2250 1800 2550 1875 2550 +2 2 0 0 0 4 60 -1 10 0.000 0 0 -1 0 0 5 + 1800 2325 6300 2325 6300 2475 1800 2475 1800 2325 +2 1 0 1 4 7 60 -1 -1 0.000 0 0 -1 0 0 2 + 3300 1800 3300 3900 +2 1 0 1 4 7 60 -1 -1 0.000 0 0 -1 0 0 2 + 7500 1800 7500 3900 +2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 1875 4050 1800 4050 1800 4350 1875 4350 +2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 6375 4950 6300 4950 6300 5250 6375 5250 +2 1 0 4 4 7 60 -1 -1 0.000 0 0 -1 0 0 2 + 3000 4200 3000 5100 +2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 3225 4050 3150 4050 3150 4350 3225 4350 +2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 2925 4950 2850 4950 2850 5250 2925 5250 +2 2 0 0 0 4 60 -1 10 0.000 0 0 -1 0 0 5 + 1800 4125 3150 4125 3150 4275 1800 4275 1800 4125 +2 2 0 0 0 4 60 -1 10 0.000 0 0 -1 0 0 5 + 2850 5025 6300 5025 6300 5175 2850 5175 2850 5025 +2 1 0 1 0 7 100 -1 -1 0.000 0 0 -1 0 0 2 + 1200 7200 9600 7200 +2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 6375 6450 6300 6450 6300 6750 6375 6750 +2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 1875 6450 1800 6450 1800 6750 1875 6750 +2 2 0 0 0 4 60 -1 10 0.000 0 0 -1 0 0 5 + 1800 6525 6300 6525 6300 6675 1800 6675 1800 6525 +2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 1875 8250 1800 8250 1800 8550 1875 8550 +2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 6375 9150 6300 9150 6300 9450 6375 9450 +2 1 0 1 4 7 60 -1 -1 0.000 0 0 -1 0 0 2 + 1500 6000 1500 8100 +2 1 0 1 4 7 60 -1 -1 0.000 0 0 -1 0 0 2 + 5700 6000 5700 8100 +2 1 0 4 4 7 60 -1 -1 0.000 0 0 -1 0 0 2 + 6000 8400 6000 9300 +2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 6225 8250 6150 8250 6150 8550 6225 8550 +2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 5925 9150 5850 9150 5850 9450 5925 9450 +2 2 0 0 0 4 60 -1 10 0.000 0 0 -1 0 0 5 + 1800 8325 6150 8325 6150 8475 1800 8475 1800 8325 +2 2 0 0 0 4 60 -1 10 0.000 0 0 -1 0 0 5 + 5850 9225 6300 9225 6300 9375 5850 9375 5850 9225 +2 2 0 0 0 32 200 -1 20 0.000 0 0 -1 0 0 5 + 900 1500 9900 1500 9900 10200 900 10200 900 1500 +3 0 0 1 4 7 50 -1 -1 0.000 0 1 0 3 + 0 0 1.00 60.00 120.00 + 1800 2400 1500 2550 1500 3000 + 0.000 1.000 0.000 +3 0 0 1 4 7 60 -1 -1 0.000 0 1 0 4 + 0 0 1.00 60.00 120.00 + 3300 2325 2700 3000 2700 3900 3000 4500 + 0.000 1.000 1.000 0.000 +3 0 0 1 4 7 60 -1 -1 0.000 0 1 0 4 + 0 0 1.00 60.00 120.00 + 5700 6525 5100 7200 5100 8100 6000 8850 + 0.000 1.000 1.000 0.000 +4 1 4 40 -1 14 14 0.0000 4 150 1500 4050 2250 conflicted\001 +4 0 4 60 -1 12 14 0.0000 4 195 1800 3375 3900 sourceDogleg\001 +4 0 4 60 -1 12 14 0.0000 4 195 1800 7575 3900 targetDogleg\001 +4 0 0 50 -1 12 14 0.0000 4 150 1650 3375 1950 minConflict\001 +4 0 0 50 -1 12 14 0.0000 4 150 1650 7575 1950 maxConflict\001 +4 1 0 50 -1 14 16 0.0000 4 210 3960 4500 5700 (a) - Break under Source\001 +4 1 4 40 -1 14 14 0.0000 4 150 1500 4050 6450 conflicted\001 +4 0 4 60 -1 12 14 0.0000 4 195 1800 1575 8100 sourceDogleg\001 +4 0 4 60 -1 12 14 0.0000 4 195 1800 5775 8100 targetDogleg\001 +4 1 0 50 -1 14 16 0.0000 4 225 3960 4425 9900 (b) - Break under Target\001 diff --git a/kite/doc/images/ConflictSolveByHistory-2.png b/kite/doc/images/ConflictSolveByHistory-2.png new file mode 100644 index 0000000000000000000000000000000000000000..2b4761f518999fe77c0e3a2195b0bc7dcb911c02 GIT binary patch literal 9543 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 literal 0 HcmV?d00001 diff --git a/kite/doc/images/DataNegociate-1.fig b/kite/doc/images/DataNegociate-1.fig new file mode 100644 index 00000000..73791a82 --- /dev/null +++ b/kite/doc/images/DataNegociate-1.fig @@ -0,0 +1,145 @@ +#FIG 3.2 Produced by xfig version 3.2.5a +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +0 32 #ffffdd +6 2475 975 2925 1275 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2550 1200 2850 1200 +2 1 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 2 + 2700 1050 2700 1200 +-6 +6 3225 1125 3675 1425 +2 1 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 2 + 3300 1200 3600 1200 +2 1 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 2 + 3450 1350 3450 1200 +-6 +6 4125 975 4575 1275 +2 1 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 2 + 4200 1200 4500 1200 +2 1 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 2 + 4350 1050 4350 1200 +-6 +6 5175 975 5475 1425 +2 1 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 2 + 5400 1350 5400 1050 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 5250 1200 5400 1200 +-6 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 3 + 1800 1200 1650 1200 1650 1350 +2 1 0 2 4 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 2700 1200 2700 300 +2 1 0 2 4 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 3450 1200 3450 1800 +2 1 0 2 4 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 4350 1200 4350 600 +2 1 0 2 4 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 5400 1200 5400 1800 +2 1 0 2 4 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 5400 1200 5400 0 +2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2 + 1650 1950 1650 2250 +2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2 + 1500 2100 1650 2100 +2 1 0 2 4 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 1650 2100 1650 2850 +2 1 3 1 0 7 70 -1 -1 4.000 0 0 7 0 0 2 + 1725 2850 6300 2850 +2 1 3 1 0 7 70 -1 -1 4.000 0 0 7 0 0 2 + 4425 600 6300 600 +2 1 3 1 0 7 70 -1 -1 4.000 0 0 7 0 0 2 + 2775 300 6300 300 +2 1 3 1 0 7 70 -1 -1 4.000 0 0 7 0 0 2 + 5475 0 6300 0 +2 1 0 2 4 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 1650 1200 1650 2100 +2 1 3 1 4 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 1725 2100 6300 2100 +2 1 0 2 0 7 70 -1 -1 6.000 0 0 -1 0 0 2 + 1650 1200 2700 1200 +2 1 0 2 0 7 70 -1 -1 6.000 0 0 -1 0 0 2 + 3450 1200 5400 1200 +2 1 0 2 0 7 69 -1 -1 6.000 0 0 -1 0 0 2 + 6000 0 6300 0 +2 1 0 2 0 7 69 -1 -1 6.000 0 0 -1 0 0 2 + 6000 300 6300 300 +2 1 0 2 0 7 69 -1 -1 6.000 0 0 -1 0 0 2 + 6000 600 6300 600 +2 1 0 2 0 7 69 -1 -1 6.000 0 0 -1 0 0 2 + 6000 1800 6300 1800 +2 1 0 2 0 7 69 -1 -1 6.000 0 0 -1 0 0 2 + 6000 2850 6300 2850 +2 1 0 2 4 7 69 -1 -1 6.000 0 0 -1 0 0 2 + 6000 2100 6300 2100 +2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 3 + 1650 2700 1650 2850 1500 2850 +2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 3 + 2550 300 2700 300 2700 450 +2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 3 + 4200 600 4350 600 4350 750 +2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 3 + 5250 0 5400 0 5400 150 +2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 3 + 3450 1650 3450 1800 3300 1800 +2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 3 + 5400 1650 5400 1800 5550 1800 +2 1 0 2 0 7 60 -1 -1 6.000 0 0 -1 1 0 2 + 0 0 2.00 120.00 240.00 + 1200 3150 1200 -600 +2 1 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 1125 2850 1275 2850 +2 1 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 1125 2100 1275 2100 +2 1 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 1125 1200 1275 1200 +2 1 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 1125 300 1275 300 +2 1 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 1125 0 1275 0 +2 1 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 1125 600 1275 600 +2 1 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 1125 1800 1275 1800 +2 1 3 1 0 7 70 -1 -1 4.000 0 0 7 0 0 2 + 5475 1200 6300 1200 +2 1 0 2 0 7 69 -1 -1 6.000 0 0 -1 0 0 2 + 6000 1200 6300 1200 +2 1 3 1 0 7 70 -1 -1 4.000 0 0 7 0 0 2 + 3525 1800 6300 1800 +2 1 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 6900 -450 7200 -450 +2 1 0 2 4 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 6900 150 7200 150 +2 2 1 0 32 32 100 -1 20 2.000 0 0 -1 0 0 5 + 600 -900 8850 -900 8850 3750 600 3750 600 -900 +2 2 0 2 0 0 50 -1 10 0.000 0 0 -1 0 0 5 + 6900 -225 7200 -225 7200 -150 6900 -150 6900 -225 +2 2 0 2 0 7 50 -1 10 0.000 0 0 -1 0 0 5 + 2700 1200 3450 1200 3450 1275 2700 1275 2700 1200 +4 1 0 60 -1 14 10 0.0000 4 105 210 6150 2775 -1\001 +4 1 0 60 -1 14 10 0.0000 4 105 210 6150 1725 -2\001 +4 1 0 60 -1 14 10 0.0000 4 105 210 6150 525 +1\001 +4 1 0 60 -1 14 10 0.0000 4 105 210 6150 -75 +1\001 +4 1 0 60 -1 14 10 0.0000 4 105 210 6150 225 +1\001 +4 1 4 60 -1 14 10 0.0000 4 105 105 6150 2025 0\001 +4 2 0 60 -1 14 12 0.0000 4 135 120 1050 -450 y\001 +4 2 0 60 -1 14 10 0.0000 4 105 210 1050 0 29\001 +4 2 0 60 -1 14 10 0.0000 4 105 210 1050 300 27\001 +4 2 0 60 -1 14 10 0.0000 4 105 210 1050 600 25\001 +4 2 0 60 -1 14 10 0.0000 4 105 210 1050 1200 21\001 +4 2 0 60 -1 14 10 0.0000 4 105 210 1050 2100 15\001 +4 2 0 60 -1 14 10 0.0000 4 105 210 1050 2850 10\001 +4 1 0 60 -1 14 12 0.0000 4 150 3360 3750 3450 _attractors=[10,17,25,27,29]\001 +4 2 0 60 -1 14 10 0.0000 4 105 210 1050 1800 17\001 +4 1 0 60 -1 14 10 0.0000 4 135 315 6150 1125 N/A\001 +4 1 0 60 -1 14 12 0.0000 4 165 480 6150 -450 spin\001 +4 0 0 60 -1 14 10 0.0000 4 135 840 7275 -450 aligneds\001 +4 0 0 60 -1 14 10 0.0000 4 105 945 7275 -150 canonical\001 +4 0 0 60 -1 14 10 0.0000 4 135 1470 7275 150 perpandiculars\001 diff --git a/kite/doc/images/DataNegociate-1.png b/kite/doc/images/DataNegociate-1.png new file mode 100644 index 0000000000000000000000000000000000000000..867aa1aaaaa293d5fae77c95a5390228b3eef112 GIT binary patch literal 7254 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 literal 0 HcmV?d00001 diff --git a/kite/doc/images/DataNegociate-2.fig b/kite/doc/images/DataNegociate-2.fig new file mode 100644 index 00000000..5ef62a1a --- /dev/null +++ b/kite/doc/images/DataNegociate-2.fig @@ -0,0 +1,164 @@ +#FIG 3.2 Produced by xfig version 3.2.5a +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +0 32 #ffffdd +6 2475 975 2925 1275 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 2550 1200 2850 1200 +2 1 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 2 + 2700 1050 2700 1200 +-6 +6 3225 1125 3675 1425 +2 1 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 2 + 3300 1200 3600 1200 +2 1 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 2 + 3450 1350 3450 1200 +-6 +6 4125 975 4575 1275 +2 1 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 2 + 4200 1200 4500 1200 +2 1 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 2 + 4350 1050 4350 1200 +-6 +6 5175 975 5475 1425 +2 1 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 2 + 5400 1350 5400 1050 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 2 + 5250 1200 5400 1200 +-6 +6 6150 3000 7650 3300 +3 0 0 1 0 7 50 -1 -1 4.000 0 0 0 4 + 6150 3000 6150 3150 6900 3150 6900 3300 + 0.000 1.000 1.000 0.000 +3 0 0 1 0 7 50 -1 -1 4.000 0 0 0 4 + 7650 3000 7650 3150 6900 3150 6900 3300 + 0.000 1.000 1.000 0.000 +-6 +6 4725 3375 8700 3675 +6 6000 3375 8700 3675 +4 0 0 50 -1 32 14 0.0000 4 195 225 6225 3600 S(\001 +4 0 0 50 -1 12 14 0.0000 4 45 150 6000 3600 =\001 +4 0 0 50 -1 12 12 0.0000 4 150 2160 6450 3600 |axis - attractor|\001 +4 0 0 50 -1 32 14 0.0000 4 195 75 8625 3600 )\001 +-6 +4 1 0 50 -1 14 10 0.0000 4 135 1155 5325 3600 wiringDelta\001 +-6 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 3 + 1800 1200 1650 1200 1650 1350 +2 1 0 2 4 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 2700 1200 2700 300 +2 1 0 2 4 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 3450 1200 3450 1800 +2 1 0 2 4 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 4350 1200 4350 600 +2 1 0 2 4 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 5400 1200 5400 1800 +2 1 0 2 4 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 5400 1200 5400 0 +2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2 + 1650 1950 1650 2250 +2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2 + 1500 2100 1650 2100 +2 1 0 2 4 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 1650 2100 1650 2850 +2 1 0 2 4 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 1650 1200 1650 2100 +2 1 0 2 0 7 70 -1 -1 6.000 0 0 -1 0 0 2 + 1650 1200 2700 1200 +2 1 0 2 0 7 70 -1 -1 6.000 0 0 -1 0 0 2 + 3450 1200 5400 1200 +2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 3 + 1650 2700 1650 2850 1500 2850 +2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 3 + 2550 300 2700 300 2700 450 +2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 3 + 4200 600 4350 600 4350 750 +2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 3 + 5250 0 5400 0 5400 150 +2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 3 + 3450 1650 3450 1800 3300 1800 +2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 3 + 5400 1650 5400 1800 5550 1800 +2 1 0 2 0 7 60 -1 -1 6.000 0 0 -1 1 0 2 + 0 0 2.00 120.00 240.00 + 1200 3150 1200 -600 +2 1 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 1125 2850 1275 2850 +2 1 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 1125 2100 1275 2100 +2 1 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 1125 1200 1275 1200 +2 1 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 1125 300 1275 300 +2 1 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 1125 0 1275 0 +2 1 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 1125 600 1275 600 +2 1 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 1125 1800 1275 1800 +2 2 0 2 0 7 50 -1 10 0.000 0 0 -1 0 0 5 + 2700 1200 3450 1200 3450 1275 2700 1275 2700 1200 +2 1 3 1 0 7 70 -1 -1 4.000 0 0 7 0 0 2 + 1725 2850 6525 2850 +2 1 3 1 0 7 70 -1 -1 4.000 0 0 7 0 0 2 + 3525 1800 6525 1800 +2 1 3 1 0 7 70 -1 -1 4.000 0 0 7 0 0 2 + 5475 1200 6675 1200 +2 1 3 1 0 7 70 -1 -1 4.000 0 0 7 0 0 2 + 4425 600 6825 600 +2 1 3 1 0 7 70 -1 -1 4.000 0 0 7 0 0 2 + 2775 300 6975 300 +2 1 3 1 0 7 70 -1 -1 4.000 0 0 7 0 0 2 + 5475 0 7125 0 +2 1 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 2 + 6300 2250 7350 2250 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 + 0 0 1.00 60.00 120.00 + 0 0 1.00 60.00 120.00 + 6450 2250 6450 1800 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 + 0 0 1.00 60.00 120.00 + 0 0 1.00 60.00 120.00 + 6450 2250 6450 2850 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 + 0 0 1.00 60.00 120.00 + 0 0 1.00 60.00 120.00 + 6600 2250 6600 1200 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 + 0 0 1.00 60.00 120.00 + 0 0 1.00 60.00 120.00 + 6750 2250 6750 600 +2 1 0 2 4 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 7950 150 8250 150 +2 2 0 2 0 7 50 -1 10 0.000 0 0 -1 0 0 5 + 7950 -225 8250 -225 8250 -150 7950 -150 7950 -225 +2 1 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 2 + 7950 -450 8250 -450 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 + 0 0 1.00 60.00 120.00 + 0 0 1.00 60.00 120.00 + 6900 300 6900 2250 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 + 0 0 1.00 60.00 120.00 + 0 0 1.00 60.00 120.00 + 7050 0 7050 2250 +2 2 1 0 32 32 100 -1 20 2.000 0 0 -1 0 0 5 + 600 -900 10050 -900 10050 3900 600 3900 600 -900 +4 2 0 60 -1 14 12 0.0000 4 135 120 1050 -450 y\001 +4 2 0 60 -1 14 10 0.0000 4 105 210 1050 0 29\001 +4 2 0 60 -1 14 10 0.0000 4 105 210 1050 300 27\001 +4 2 0 60 -1 14 10 0.0000 4 105 210 1050 600 25\001 +4 2 0 60 -1 14 10 0.0000 4 105 210 1050 1200 21\001 +4 2 0 60 -1 14 10 0.0000 4 105 210 1050 2100 15\001 +4 2 0 60 -1 14 10 0.0000 4 105 210 1050 2850 10\001 +4 2 0 60 -1 14 10 0.0000 4 105 210 1050 1800 17\001 +4 0 0 60 -1 14 10 0.0000 4 135 1470 8400 150 perpandiculars\001 +4 0 0 60 -1 14 10 0.0000 4 105 945 8400 -150 canonical\001 +4 0 0 60 -1 14 10 0.0000 4 135 840 8400 -450 aligneds\001 +4 0 0 50 -1 14 10 0.0000 4 105 420 7500 2250 axis\001 diff --git a/kite/doc/images/DataNegociate-2.png b/kite/doc/images/DataNegociate-2.png new file mode 100644 index 0000000000000000000000000000000000000000..142e5cbd98fcdb1f46a3da62d39584737083d58f GIT binary patch literal 7889 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 literal 0 HcmV?d00001 diff --git a/kite/doc/images/ManipulatorRelax-1.fig b/kite/doc/images/ManipulatorRelax-1.fig new file mode 100644 index 00000000..9bcb65c1 --- /dev/null +++ b/kite/doc/images/ManipulatorRelax-1.fig @@ -0,0 +1,158 @@ +#FIG 3.2 Produced by xfig version 3.2.5a +Landscape +Center +Inches +Letter +80.00 +Single +-2 +1200 2 +0 32 #ffffdd +6 1200 1200 2625 1500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 1200 1200 2100 1200 2100 1500 1200 1500 1200 1200 +4 0 7 50 -1 14 14 0.0000 4 150 750 1275 1425 id:10\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 2175 1425 d:7\001 +-6 +6 1200 6900 2625 7200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 1200 6900 2100 6900 2100 7200 1200 7200 1200 6900 +4 0 7 50 -1 14 14 0.0000 4 150 750 1275 7125 id:10\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 2175 7125 d:7\001 +-6 +1 4 0 0 0 7 50 -1 0 2.000 1 0.0000 5100 2700 75 75 5025 2700 5175 2700 +1 4 0 0 0 7 50 -1 0 2.000 1 0.0000 8100 2700 75 75 8025 2700 8175 2700 +1 4 0 0 0 7 50 -1 0 2.000 1 0.0000 5100 6000 75 75 5025 6000 5175 6000 +1 4 0 0 0 7 50 -1 0 2.000 1 0.0000 8100 6000 75 75 8025 6000 8175 6000 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 3000 1200 3000 3000 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 4800 1200 4800 3000 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 6600 1200 6600 3000 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 8400 1200 8400 3000 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 10200 1200 10200 3000 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 12000 1200 12000 3000 +2 1 0 4 1 7 50 -1 -1 10.000 0 0 -1 0 0 2 + 5400 900 7200 900 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 3000 1200 3900 1200 3900 1500 3000 1500 3000 1200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 4800 1200 5700 1200 5700 1500 4800 1500 4800 1200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 6600 1200 7500 1200 7500 1500 6600 1500 6600 1200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 8400 1200 9300 1200 9300 1500 8400 1500 8400 1200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 10200 1200 11100 1200 11100 1500 10200 1500 10200 1200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 12000 1200 12900 1200 12900 1500 12000 1500 12000 1200 +2 1 0 4 4 7 50 -1 -1 10.000 0 0 -1 0 0 2 + 1800 2400 12600 2400 +2 2 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 5 + 1200 1200 13800 1200 13800 3000 1200 3000 1200 1200 +2 1 0 1 1 7 80 -1 0 4.000 0 0 -1 0 0 2 + 5400 825 5400 2700 +2 1 0 1 1 7 80 -1 0 4.000 0 0 -1 0 0 2 + 7200 825 7200 2700 +2 1 0 2 0 7 80 -1 0 6.000 0 0 -1 0 0 2 + 5100 2700 5100 3600 +2 1 0 2 0 7 80 -1 0 6.000 0 0 -1 0 0 2 + 8100 2700 8100 3600 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 3 + 2400 7200 2400 7425 3000 7425 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 3 + 1650 7275 1650 7725 3000 7725 +2 2 0 0 1 1 110 -1 30 2.000 0 0 -1 0 0 5 + 5100 4125 5400 4125 5400 6000 5100 6000 5100 4125 +2 2 0 0 1 1 110 -1 30 2.000 0 0 -1 0 0 5 + 7200 4125 7500 4125 7500 6000 7200 6000 7200 4125 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 3000 4500 3000 6300 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 4800 4500 4800 6300 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 6600 4500 6600 6300 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 8400 4500 8400 6300 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 10200 4500 10200 6300 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 12000 4500 12000 6300 +2 1 0 4 1 7 50 -1 -1 10.000 0 0 -1 0 0 2 + 5400 4200 7200 4200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 1200 4500 2100 4500 2100 4800 1200 4800 1200 4500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 3000 4500 3900 4500 3900 4800 3000 4800 3000 4500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 4800 4500 5700 4500 5700 4800 4800 4800 4800 4500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 6600 4500 7500 4500 7500 4800 6600 4800 6600 4500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 8400 4500 9300 4500 9300 4800 8400 4800 8400 4500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 10200 4500 11100 4500 11100 4800 10200 4800 10200 4500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 12000 4500 12900 4500 12900 4800 12000 4800 12000 4500 +2 1 0 4 4 7 50 -1 -1 10.000 0 0 -1 0 0 2 + 1800 5700 5100 5700 +2 2 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 5 + 1200 4500 13800 4500 13800 6300 1200 6300 1200 4500 +2 1 0 1 1 7 80 -1 0 4.000 0 0 -1 0 0 2 + 5400 4125 5400 6000 +2 1 0 1 1 7 80 -1 0 4.000 0 0 -1 0 0 2 + 7200 4125 7200 6000 +2 1 0 4 19 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 5100 5700 5100 5100 7500 5100 7500 5700 12600 5700 +2 1 0 8 19 7 40 -1 -1 18.000 0 0 -1 0 0 3 + 4875 5700 5100 5700 5100 5475 +2 1 0 8 19 7 40 -1 -1 18.000 0 0 -1 0 0 3 + 5100 5325 5100 5100 5250 5100 +2 1 0 8 19 7 40 -1 -1 18.000 0 0 -1 0 0 3 + 7275 5100 7500 5100 7500 5250 +2 1 0 8 19 7 40 -1 -1 18.000 0 0 -1 0 0 3 + 7500 5475 7500 5700 7725 5700 +2 2 0 0 0 32 200 -1 20 0.000 0 0 -1 0 0 5 + 600 300 14400 300 14400 8100 600 8100 600 300 +4 0 7 50 -1 14 14 0.0000 4 150 750 3075 1425 id:11\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 4875 1425 id:12\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 6675 1425 id:13\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 8475 1425 id:14\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 10275 1425 id:15\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 12075 1425 id:16\001 +4 0 0 50 -1 12 14 0.0000 4 150 1800 8250 3600 imaxconflict\001 +4 2 0 50 -1 12 14 0.0000 4 150 1800 5025 3600 iminconflict\001 +4 1 1 50 -1 12 14 0.0000 4 150 1200 6300 750 interval\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 5775 1425 d:5\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 3975 1425 d:6\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 11175 1425 d:3\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 12975 1425 d:7\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 7575 1425 d:5\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 9375 1425 d:7\001 +4 0 0 50 -1 14 14 0.0000 4 195 1950 3075 7500 GCell density\001 +4 0 0 50 -1 14 14 0.0000 4 150 1200 3075 7800 GCell id\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 3075 4725 id:11\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 4875 4725 id:12\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 6675 4725 id:13\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 8475 4725 id:14\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 10275 4725 id:15\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 12075 4725 id:16\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 1275 4725 id:10\001 +4 1 1 50 -1 12 14 0.0000 4 150 1200 6300 4050 interval\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 5775 4725 d:5\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 3975 4725 d:6\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 2175 4725 d:7\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 11175 4725 d:3\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 12975 4725 d:7\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 7575 4725 d:5\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 9375 4725 d:7\001 +4 1 19 50 -1 14 14 0.0000 4 195 450 4800 5250 (b)\001 +4 1 19 50 -1 14 14 0.0000 4 195 450 6300 5325 (c)\001 +4 1 19 50 -1 14 14 0.0000 4 195 450 7800 5250 (d)\001 +4 1 19 50 -1 14 14 0.0000 4 195 450 12375 5550 (e)\001 +4 1 4 50 -1 14 14 0.0000 4 195 450 1950 5550 (a)\001 +4 1 4 50 -1 14 14 0.0000 4 195 450 1950 2250 (a)\001 diff --git a/kite/doc/images/ManipulatorRelax-1.png b/kite/doc/images/ManipulatorRelax-1.png new file mode 100644 index 0000000000000000000000000000000000000000..852202e4439b0a65e0e9e6e3b9cc0231cab3a3f1 GIT binary patch literal 11208 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 literal 0 HcmV?d00001 diff --git a/kite/doc/images/ManipulatorRelax-2.fig b/kite/doc/images/ManipulatorRelax-2.fig new file mode 100644 index 00000000..773b4196 --- /dev/null +++ b/kite/doc/images/ManipulatorRelax-2.fig @@ -0,0 +1,163 @@ +#FIG 3.2 Produced by xfig version 3.2.5a +Landscape +Center +Inches +Letter +80.00 +Single +-2 +1200 2 +0 32 #ffffdd +6 1200 1200 2625 1500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 1200 1200 2100 1200 2100 1500 1200 1500 1200 1200 +4 0 7 50 -1 14 14 0.0000 4 150 750 1275 1425 id:10\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 2175 1425 d:7\001 +-6 +6 1200 6900 2625 7200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 1200 6900 2100 6900 2100 7200 1200 7200 1200 6900 +4 0 7 50 -1 14 14 0.0000 4 150 750 1275 7125 id:10\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 2175 7125 d:7\001 +-6 +1 4 0 0 0 7 50 -1 0 2.000 1 0.0000 5100 6000 75 75 5025 6000 5175 6000 +1 4 0 0 0 7 50 -1 0 2.000 1 0.0000 5100 2700 75 75 5025 2700 5175 2700 +1 4 0 0 0 7 50 -1 0 2.000 1 0.0000 8100 2700 75 75 8025 2700 8175 2700 +1 4 0 0 0 7 50 -1 0 2.000 1 0.0000 10500 2700 75 75 10425 2700 10575 2700 +1 4 0 0 0 7 50 -1 0 2.000 1 0.0000 10500 6000 75 75 10425 6000 10575 6000 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 3000 4500 3000 6300 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 4800 4500 4800 6300 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 6600 4500 6600 6300 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 8400 4500 8400 6300 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 10200 4500 10200 6300 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 12000 4500 12000 6300 +2 1 0 4 1 7 50 -1 -1 10.000 0 0 -1 0 0 2 + 5400 4200 7200 4200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 1200 4500 2100 4500 2100 4800 1200 4800 1200 4500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 3000 4500 3900 4500 3900 4800 3000 4800 3000 4500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 4800 4500 5700 4500 5700 4800 4800 4800 4800 4500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 6600 4500 7500 4500 7500 4800 6600 4800 6600 4500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 8400 4500 9300 4500 9300 4800 8400 4800 8400 4500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 10200 4500 11100 4500 11100 4800 10200 4800 10200 4500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 12000 4500 12900 4500 12900 4800 12000 4800 12000 4500 +2 1 0 4 4 7 50 -1 -1 10.000 0 0 -1 0 0 2 + 1800 5700 5100 5700 +2 2 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 5 + 1200 4500 13800 4500 13800 6300 1200 6300 1200 4500 +2 1 0 1 1 7 80 -1 0 4.000 0 0 -1 0 0 2 + 5400 4125 5400 6000 +2 1 0 1 1 7 80 -1 0 4.000 0 0 -1 0 0 2 + 7200 4125 7200 6000 +2 1 0 8 19 7 40 -1 -1 18.000 0 0 -1 0 0 3 + 4875 5700 5100 5700 5100 5475 +2 1 0 8 19 7 40 -1 -1 18.000 0 0 -1 0 0 3 + 5100 5325 5100 5100 5250 5100 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 3000 1200 3000 3000 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 4800 1200 4800 3000 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 6600 1200 6600 3000 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 8400 1200 8400 3000 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 10200 1200 10200 3000 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 12000 1200 12000 3000 +2 1 0 4 1 7 50 -1 -1 10.000 0 0 -1 0 0 2 + 5400 900 7200 900 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 3000 1200 3900 1200 3900 1500 3000 1500 3000 1200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 4800 1200 5700 1200 5700 1500 4800 1500 4800 1200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 6600 1200 7500 1200 7500 1500 6600 1500 6600 1200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 8400 1200 9300 1200 9300 1500 8400 1500 8400 1200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 10200 1200 11100 1200 11100 1500 10200 1500 10200 1200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 12000 1200 12900 1200 12900 1500 12000 1500 12000 1200 +2 1 0 4 4 7 50 -1 -1 10.000 0 0 -1 0 0 2 + 1800 2400 12600 2400 +2 2 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 5 + 1200 1200 13800 1200 13800 3000 1200 3000 1200 1200 +2 1 0 1 1 7 80 -1 0 4.000 0 0 -1 0 0 2 + 5400 825 5400 2700 +2 1 0 1 1 7 80 -1 0 4.000 0 0 -1 0 0 2 + 7200 825 7200 2700 +2 1 0 2 0 7 80 -1 0 6.000 0 0 -1 0 0 2 + 5100 2700 5100 3600 +2 1 0 2 0 7 80 -1 0 6.000 0 0 -1 0 0 2 + 10500 2700 10500 3600 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 3 + 2400 7200 2400 7425 2925 7425 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 3 + 1650 7200 1650 7725 2925 7725 +2 2 0 0 1 1 110 -1 36 2.000 0 0 -1 0 0 5 + 5100 4125 5400 4125 5400 6000 5100 6000 5100 4125 +2 2 0 0 1 1 110 -1 36 2.000 0 0 -1 0 0 5 + 7200 4125 7500 4125 7500 6000 7200 6000 7200 4125 +2 1 0 4 19 7 50 -1 -1 10.000 0 0 -1 0 0 5 + 5100 5700 5100 5100 11100 5100 11100 5700 12600 5700 +2 1 0 8 19 7 40 -1 -1 18.000 0 0 -1 0 0 3 + 10875 5100 11100 5100 11100 5250 +2 1 0 8 19 7 40 -1 -1 18.000 0 0 -1 0 0 3 + 11100 5475 11100 5700 11325 5700 +2 2 0 0 0 32 200 -1 20 0.000 0 0 -1 0 0 5 + 600 300 14400 300 14400 8100 600 8100 600 300 +3 0 0 1 0 7 50 -1 -1 4.000 0 1 0 4 + 0 0 1.00 120.00 240.00 + 8100 2700 8700 2400 9900 3000 10500 2700 + 0.000 1.000 1.000 0.000 +4 0 7 50 -1 14 14 0.0000 4 150 750 3075 4725 id:11\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 4875 4725 id:12\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 6675 4725 id:13\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 8475 4725 id:14\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 10275 4725 id:15\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 12075 4725 id:16\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 1275 4725 id:10\001 +4 1 1 50 -1 12 14 0.0000 4 150 1200 6300 4050 interval\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 5775 4725 d:5\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 3975 4725 d:6\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 2175 4725 d:7\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 11175 4725 d:3\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 12975 4725 d:7\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 7575 4725 d:5\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 9375 4725 d:7\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 3075 1425 id:11\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 4875 1425 id:12\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 6675 1425 id:13\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 8475 1425 id:14\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 10275 1425 id:15\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 12075 1425 id:16\001 +4 2 0 50 -1 12 14 0.0000 4 150 1800 5025 3600 iminconflict\001 +4 1 1 50 -1 12 14 0.0000 4 150 1200 6300 750 interval\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 5775 1425 d:5\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 3975 1425 d:6\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 11175 1425 d:3\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 12975 1425 d:7\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 7575 1425 d:5\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 9375 1425 d:7\001 +4 0 0 50 -1 12 14 0.0000 4 150 1800 10575 3600 imaxconflict\001 +4 0 0 50 -1 14 14 0.0000 4 195 1950 3000 7500 GCell density\001 +4 0 0 50 -1 14 14 0.0000 4 150 1200 3000 7800 GCell id\001 +4 1 19 50 -1 14 14 0.0000 4 195 450 12450 5550 (e)\001 +4 1 4 50 -1 14 14 0.0000 4 195 450 1950 5550 (a)\001 +4 1 4 50 -1 14 14 0.0000 4 195 450 1950 2250 (a)\001 +4 1 19 50 -1 14 14 0.0000 4 195 450 4800 5250 (b)\001 +4 1 19 50 -1 14 14 0.0000 4 195 450 6000 5325 (c)\001 +4 1 19 50 -1 14 14 0.0000 4 195 450 11400 5250 (d)\001 diff --git a/kite/doc/images/ManipulatorRelax-2.png b/kite/doc/images/ManipulatorRelax-2.png new file mode 100644 index 0000000000000000000000000000000000000000..16c7bdf6fbd8f827653312759beeb54c3867cec9 GIT binary patch literal 11638 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 literal 0 HcmV?d00001 diff --git a/kite/doc/images/ManipulatorRelax-3.fig b/kite/doc/images/ManipulatorRelax-3.fig new file mode 100644 index 00000000..759f7b33 --- /dev/null +++ b/kite/doc/images/ManipulatorRelax-3.fig @@ -0,0 +1,152 @@ +#FIG 3.2 Produced by xfig version 3.2.5a +Landscape +Center +Inches +Letter +80.00 +Single +-2 +1200 2 +0 32 #ffffdd +6 1200 1200 2625 1500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 1200 1200 2100 1200 2100 1500 1200 1500 1200 1200 +4 0 7 50 -1 14 14 0.0000 4 150 750 1275 1425 id:10\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 2175 1425 d:7\001 +-6 +6 1200 6900 2625 7200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 1200 6900 2100 6900 2100 7200 1200 7200 1200 6900 +4 0 7 50 -1 14 14 0.0000 4 150 750 1275 7125 id:10\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 2175 7125 d:7\001 +-6 +1 4 0 0 0 7 50 -1 0 2.000 1 0.0000 5100 6000 75 75 5025 6000 5175 6000 +1 4 0 0 0 7 50 -1 0 2.000 1 0.0000 5100 2700 75 75 5025 2700 5175 2700 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 3000 4500 3000 6300 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 4800 4500 4800 6300 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 6600 4500 6600 6300 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 8400 4500 8400 6300 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 10200 4500 10200 6300 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 12000 4500 12000 6300 +2 1 0 4 1 7 50 -1 -1 10.000 0 0 -1 0 0 2 + 5400 4200 13500 4200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 1200 4500 2100 4500 2100 4800 1200 4800 1200 4500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 3000 4500 3900 4500 3900 4800 3000 4800 3000 4500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 4800 4500 5700 4500 5700 4800 4800 4800 4800 4500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 6600 4500 7500 4500 7500 4800 6600 4800 6600 4500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 8400 4500 9300 4500 9300 4800 8400 4800 8400 4500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 10200 4500 11100 4500 11100 4800 10200 4800 10200 4500 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 12000 4500 12900 4500 12900 4800 12000 4800 12000 4500 +2 1 0 4 4 7 50 -1 -1 10.000 0 0 -1 0 0 2 + 1800 5700 5100 5700 +2 2 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 5 + 1200 4500 13800 4500 13800 6300 1200 6300 1200 4500 +2 1 0 1 1 7 80 -1 0 4.000 0 0 -1 0 0 2 + 5400 4125 5400 6000 +2 1 0 8 19 7 40 -1 -1 18.000 0 0 -1 0 0 3 + 4875 5700 5100 5700 5100 5475 +2 1 0 8 19 7 40 -1 -1 18.000 0 0 -1 0 0 3 + 5100 5325 5100 5100 5250 5100 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 3000 1200 3000 3000 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 4800 1200 4800 3000 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 6600 1200 6600 3000 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 8400 1200 8400 3000 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 10200 1200 10200 3000 +2 1 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 2 + 12000 1200 12000 3000 +2 1 0 4 1 7 50 -1 -1 10.000 0 0 -1 0 0 2 + 5400 900 13500 900 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 3000 1200 3900 1200 3900 1500 3000 1500 3000 1200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 4800 1200 5700 1200 5700 1500 4800 1500 4800 1200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 6600 1200 7500 1200 7500 1500 6600 1500 6600 1200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 8400 1200 9300 1200 9300 1500 8400 1500 8400 1200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 10200 1200 11100 1200 11100 1500 10200 1500 10200 1200 +2 2 0 1 0 7 100 -1 0 4.000 0 0 -1 0 0 5 + 12000 1200 12900 1200 12900 1500 12000 1500 12000 1200 +2 1 0 4 4 7 50 -1 -1 10.000 0 0 -1 0 0 2 + 1800 2400 11400 2400 +2 2 1 1 0 7 70 -1 -1 4.000 0 0 -1 0 0 5 + 1200 1200 13800 1200 13800 3000 1200 3000 1200 1200 +2 1 0 1 1 7 80 -1 0 4.000 0 0 -1 0 0 2 + 5400 825 5400 2700 +2 1 0 2 0 7 80 -1 0 6.000 0 0 -1 0 0 2 + 5100 2700 5100 3600 +2 1 0 2 0 7 80 -1 0 6.000 0 0 -1 0 0 2 + 10500 3300 10500 3600 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 3 + 2400 7200 2400 7425 2925 7425 +2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 3 + 1650 7200 1650 7725 2925 7725 +2 2 0 0 1 1 110 -1 36 2.000 0 0 -1 0 0 5 + 5100 4125 5400 4125 5400 6000 5100 6000 5100 4125 +2 1 0 1 1 7 80 -1 0 4.000 0 0 -1 0 0 2 + 13500 825 13500 2700 +2 1 0 1 0 1 50 -1 36 0.000 0 0 -1 0 0 2 + 10500 3525 12375 3525 +2 1 0 4 19 7 50 -1 -1 10.000 0 0 -1 0 0 3 + 5100 5700 5100 5100 12600 5100 +2 1 0 1 1 7 80 -1 0 4.000 0 0 -1 0 0 2 + 13500 4125 13500 6000 +2 2 0 0 0 32 200 -1 20 0.000 0 0 -1 0 0 5 + 600 300 14400 300 14400 8100 600 8100 600 300 +4 0 7 50 -1 14 14 0.0000 4 150 750 3075 4725 id:11\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 4875 4725 id:12\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 6675 4725 id:13\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 8475 4725 id:14\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 10275 4725 id:15\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 12075 4725 id:16\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 1275 4725 id:10\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 5775 4725 d:5\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 3975 4725 d:6\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 2175 4725 d:7\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 11175 4725 d:3\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 12975 4725 d:7\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 7575 4725 d:5\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 9375 4725 d:7\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 3075 1425 id:11\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 4875 1425 id:12\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 6675 1425 id:13\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 8475 1425 id:14\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 10275 1425 id:15\001 +4 0 7 50 -1 14 14 0.0000 4 150 750 12075 1425 id:16\001 +4 2 0 50 -1 12 14 0.0000 4 150 1800 5025 3600 iminconflict\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 5775 1425 d:5\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 3975 1425 d:6\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 11175 1425 d:3\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 12975 1425 d:7\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 7575 1425 d:5\001 +4 0 0 50 -1 12 14 0.0000 4 150 450 9375 1425 d:7\001 +4 0 0 50 -1 12 14 0.0000 4 150 1800 10575 3600 imaxconflict\001 +4 0 0 50 -1 14 14 0.0000 4 195 1950 3000 7500 GCell density\001 +4 0 0 50 -1 14 14 0.0000 4 150 1200 3000 7800 GCell id\001 +4 1 4 50 -1 14 14 0.0000 4 195 450 1950 5550 (a)\001 +4 1 4 50 -1 14 14 0.0000 4 195 450 1950 2250 (a)\001 +4 1 19 50 -1 14 14 0.0000 4 195 450 4800 5250 (b)\001 +4 1 19 50 -1 14 14 0.0000 4 195 450 6000 5325 (c)\001 +4 1 1 50 -1 12 14 0.0000 4 150 1200 9600 825 interval\001 +4 0 0 50 -1 14 14 0.0000 4 195 6600 5700 7200 The only dogleg is the min, the axis must be\001 +4 0 0 50 -1 14 14 0.0000 4 195 7050 5700 7500 pushed to the left to stay clear of .\001 +4 1 1 50 -1 12 14 0.0000 4 150 1200 9600 4125 interval\001 diff --git a/kite/doc/images/ManipulatorRelax-3.png b/kite/doc/images/ManipulatorRelax-3.png new file mode 100644 index 0000000000000000000000000000000000000000..5914e169101c8a000db0d2cd9f85a1c132c93ab3 GIT binary patch literal 12516 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.\001 +4 1 4 50 -1 14 14 0.0000 4 195 450 3525 2250 (a)\001 +4 1 1 50 -1 12 14 0.0000 4 150 1200 5100 825 interval\001 +4 0 0 50 -1 12 14 0.0000 4 150 1800 8775 3600 imaxconflict\001 +4 1 1 50 -1 12 14 0.0000 4 150 1200 5100 4125 interval\001 +4 1 19 50 -1 14 14 0.0000 4 195 450 12450 5325 (c)\001 +4 1 19 50 -1 14 14 0.0000 4 195 450 9675 5250 (b)\001 diff --git a/kite/doc/images/ManipulatorRelax-4.png b/kite/doc/images/ManipulatorRelax-4.png new file mode 100644 index 0000000000000000000000000000000000000000..9b7f16492f28f580ae1c80921990f0da72e7a9ae GIT binary patch literal 12810 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 X1^-VA;SKXj3!O!}2Cnu$3)FuAW{8o0 literal 0 HcmV?d00001 diff --git a/kite/doc/images/Track-0.fig b/kite/doc/images/Track-0.fig new file mode 100644 index 00000000..b75e1aac --- /dev/null +++ b/kite/doc/images/Track-0.fig @@ -0,0 +1,212 @@ +#FIG 3.2 Produced by xfig version 3.2.5a +Landscape +Center +Inches +Letter +90.00 +Single +-2 +1200 2 +0 32 #ffffdd +6 3225 7725 6975 8475 +6 3450 7950 3750 8250 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3525 8025 3675 8175 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3675 8025 3525 8175 +-6 +6 6450 7950 6750 8250 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 6525 8025 6675 8175 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 6675 8025 6525 8175 +-6 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 3450 7800 3300 7950 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 3600 7800 3300 8100 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 3750 7800 3300 8250 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 3900 7800 3300 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 4050 7800 3450 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 4200 7800 3600 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 4350 7800 3750 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 4500 7800 3900 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 4650 7800 4050 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 4800 7800 4200 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 4950 7800 4350 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 5100 7800 4500 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 5250 7800 4650 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 5400 7800 4800 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 5550 7800 4950 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 5700 7800 5100 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 5850 7800 5250 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 6000 7800 5400 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 6150 7800 5550 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 6300 7800 5700 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 6450 7800 5850 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 6600 7800 6000 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 6750 7800 6150 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 6900 7800 6300 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 6900 7950 6450 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 6900 8100 6600 8400 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2 + 6900 8250 6750 8400 +2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5 + 3300 7800 6900 7800 6900 8400 3300 8400 3300 7800 +-6 +6 2400 10350 7950 11175 +4 0 0 50 -1 14 14 0.0000 4 135 450 2400 10500 TS:\001 +4 0 0 40 -1 14 14 0.0000 4 135 450 2400 10800 MD:\001 +4 0 0 40 -1 14 14 0.0000 4 105 300 2400 11100 e:\001 +4 0 0 40 -1 14 14 0.0000 4 195 1950 3000 10500 Track Spacing\001 +4 0 0 40 -1 14 14 0.0000 4 195 4950 3000 10800 Minimal Distance (layer to layer)\001 +4 0 0 40 -1 14 14 0.0000 4 195 3000 3000 11100 Extension (of layer)\001 +-6 +2 1 0 2 0 32 50 -1 20 0.000 0 0 -1 0 0 2 + 1200 3300 8400 3300 +2 1 0 2 0 32 50 -1 20 0.000 0 0 -1 0 0 2 + 1200 3900 8400 3900 +2 1 0 2 0 32 50 -1 20 0.000 0 0 -1 0 0 2 + 1200 4500 8400 4500 +2 1 0 2 0 32 50 -1 20 0.000 0 0 -1 0 0 2 + 1200 5100 8400 5100 +2 2 0 1 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 1500 3600 2100 3600 2100 4200 1500 4200 1500 3600 +2 2 0 1 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 3000 3600 3900 3600 3900 4200 3000 4200 3000 3600 +2 2 0 1 0 7 60 -1 15 0.000 0 0 -1 0 0 5 + 2100 3600 2700 3600 2700 4200 2100 4200 2100 3600 +2 2 0 1 4 4 60 -1 30 0.000 0 0 -1 0 0 5 + 4200 3600 5100 3600 5100 4200 4200 4200 4200 3600 +2 2 0 1 4 4 60 -1 35 0.000 0 0 -1 0 0 5 + 5100 3600 5700 3600 5700 4200 5100 4200 5100 3600 +2 2 0 1 4 4 60 -1 37 0.000 0 0 -1 0 0 5 + 5700 3600 6300 3600 6300 4200 5700 4200 5700 3600 +2 2 0 1 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 6900 3600 7800 3600 7800 4200 6900 4200 6900 3600 +2 2 0 1 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 1200 3000 2400 3000 2400 3600 1200 3600 1200 3000 +2 2 0 1 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 2400 3000 3300 3000 3300 3600 2400 3600 2400 3000 +2 2 0 1 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 4800 3000 6000 3000 6000 3600 4800 3600 4800 3000 +2 2 0 1 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 1800 4200 7500 4200 7500 4800 1800 4800 1800 4200 +2 2 0 1 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 1500 4800 2400 4800 2400 5400 1500 5400 1500 4800 +2 2 0 1 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 3000 4800 3900 4800 3900 5400 3000 5400 3000 4800 +2 2 0 1 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 3900 4800 4500 4800 4500 5400 3900 5400 3900 4800 +2 2 0 1 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 5100 4800 6300 4800 6300 5400 5100 5400 5100 4800 +2 2 0 1 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 6300 4800 6900 4800 6900 5400 6300 5400 6300 4800 +2 2 0 1 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 7200 4800 8100 4800 8100 5400 7200 5400 7200 4800 +2 1 0 4 0 32 50 -1 20 0.000 0 0 -1 0 0 2 + 2700 8100 7500 8100 +2 1 0 4 0 32 50 -1 20 0.000 0 0 -1 0 0 2 + 2700 9300 7500 9300 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 7275 8700 7800 8700 8100 9300 8775 9300 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 7575 8100 8700 8100 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 7275 7500 7800 7500 8100 6900 8700 6900 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2625 6900 1500 6900 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2625 8100 900 8100 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 7200 8775 7200 9900 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 + 3 1 1.00 60.00 120.00 + 3 1 1.00 60.00 120.00 + 8625 6900 8625 8100 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 + 3 1 1.00 60.00 120.00 + 3 1 1.00 60.00 120.00 + 8625 8100 8625 9300 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 1 2 + 3 1 1.00 60.00 120.00 + 3 1 1.00 60.00 120.00 + 1575 6900 1575 8100 +2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 900 8100 1200 8100 +2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3000 9600 3000 9900 +2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 7200 9600 7200 9900 +2 1 0 4 0 32 50 -1 20 0.000 0 0 -1 0 0 2 + 2700 6900 7500 6900 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3000 8775 3000 9900 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3600 8775 3600 9900 +2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3600 9600 3600 9900 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 1.00 60.00 120.00 + 1500 8850 3000 8850 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 1.00 60.00 120.00 + 3525 8850 3300 8850 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3000 8850 3300 8850 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3225 9150 3600 9150 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 1.00 60.00 120.00 + 1500 9150 3300 9150 +2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 1.00 60.00 120.00 + 3825 9150 3600 9150 +2 2 0 1 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 3000 7500 7200 7500 7200 8700 3000 8700 3000 7500 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3300 8475 3300 9225 +2 2 0 0 0 32 100 -1 20 0.000 0 0 -1 0 0 5 + 300 2700 9300 2700 9300 13200 300 13200 300 2700 +4 1 0 50 -1 14 14 1.5708 4 195 600 8550 7500 TS/2\001 +4 1 0 50 -1 14 14 1.5708 4 195 600 8550 8700 TS/2\001 +4 1 0 50 -1 14 14 1.5708 4 135 300 1500 7500 TS\001 +4 1 0 50 -1 14 14 0.0000 4 105 450 7500 9900 max\001 +4 1 0 50 -1 14 14 0.0000 4 150 150 675 8175 y\001 +4 1 0 50 -1 18 16 0.0000 4 255 330 5100 6000 (a)\001 +4 0 0 40 -1 14 14 0.0000 4 105 150 1500 9075 e\001 +4 0 0 40 -1 14 14 0.0000 4 195 600 1500 8775 MD/2\001 +4 1 0 50 -1 14 14 0.0000 4 150 450 2700 9900 min\001 +4 0 0 40 -1 14 14 0.0000 4 150 300 3750 9900 x1\001 +4 1 0 50 -1 14 16 0.0000 4 255 7095 5100 11700 area(y,min,max) = (min,y-TS/2) (max,y+TS/2)\001 +4 1 0 50 -1 14 16 0.0000 4 225 3135 5100 12000 min = x1 - e - MD/2\001 +4 1 0 50 -1 14 16 0.0000 4 225 3135 5100 12300 max = x2 + e + MD/2\001 +4 1 0 50 -1 18 16 0.0000 4 255 345 5100 12900 (b)\001 +4 0 0 40 -1 14 16 0.0000 4 210 495 600 3375 [0]\001 +4 0 0 40 -1 14 16 0.0000 4 225 495 600 3975 [1]\001 +4 0 0 40 -1 14 16 0.0000 4 210 495 600 4575 [2]\001 +4 0 0 40 -1 14 16 0.0000 4 210 495 600 5175 [3]\001 diff --git a/kite/doc/images/Track-0.png b/kite/doc/images/Track-0.png new file mode 100644 index 0000000000000000000000000000000000000000..39d9033ca3d7b2768e2bf1089c7b947692ad83b2 GIT binary patch literal 15385 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\001 +4 0 0 50 -1 14 16 1.5708 4 210 825 1875 4950 [5,8[\001 +4 1 7 40 -1 14 16 1.5708 4 165 330 1875 2025 TS\001 -6 -2 2 0 1 0 7 50 -1 -1 4.000 0 0 -1 0 0 5 - 0 0 4725 0 4725 6525 0 6525 0 0 +6 2100 1725 2700 5325 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 2175 2250 2625 2250 2625 5250 2175 5250 2175 2250 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2175 3750 2625 3750 +2 2 0 2 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 2175 2250 2175 1800 2625 1800 2625 2250 2175 2250 +4 0 0 50 -1 14 16 1.5708 4 165 990 2475 3450 net\001 +4 1 7 40 -1 14 16 1.5708 4 165 330 2475 2025 TS\001 +4 0 0 50 -1 14 16 1.5708 4 225 990 2475 4950 [8,10[\001 +-6 +6 2700 1725 3300 5325 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 2775 2250 3225 2250 3225 5250 2775 5250 2775 2250 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2775 3750 3225 3750 +2 2 0 2 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 2775 2250 2775 1800 3225 1800 3225 2250 2775 2250 +4 0 0 50 -1 14 16 1.5708 4 165 990 3075 3450 net\001 +4 0 0 50 -1 14 16 1.5708 4 225 1155 3075 4950 [12,30[\001 +4 1 7 40 -1 14 16 1.5708 4 165 330 3075 2025 TS\001 +-6 +6 3300 1725 3900 5325 +2 2 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 3375 2250 3375 5250 3825 5250 3825 2250 3375 2250 +2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3375 3750 3825 3750 +2 2 0 2 4 4 50 -1 20 0.000 0 0 -1 0 0 5 + 3375 2250 3375 1800 3825 1800 3825 2250 3375 2250 +4 0 4 50 -1 14 16 1.5708 4 165 990 3675 3450 net\001 +4 0 4 50 -1 14 16 1.5708 4 225 1155 3675 4950 [31,38[\001 +4 1 7 40 -1 14 16 1.5708 4 165 330 3675 2025 TS\001 +-6 +6 3900 1725 4500 5325 +2 2 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 3975 2250 3975 5250 4425 5250 4425 2250 3975 2250 +2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3975 3750 4425 3750 +2 2 0 2 4 4 50 -1 20 0.000 0 0 -1 0 0 5 + 3975 2250 3975 1800 4425 1800 4425 2250 3975 2250 +4 0 4 50 -1 14 16 1.5708 4 165 990 4275 3450 net\001 +4 0 4 50 -1 14 16 1.5708 4 225 1155 4275 4950 [31,35[\001 +4 1 7 40 -1 14 16 1.5708 4 165 330 4275 2025 TS\001 +-6 +6 4500 1725 5100 5325 +2 2 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 4575 2250 4575 5250 5025 5250 5025 2250 4575 2250 +2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 4575 3750 5025 3750 +2 2 0 2 4 4 50 -1 20 0.000 0 0 -1 0 0 5 + 4575 2250 4575 1800 5025 1800 5025 2250 4575 2250 +4 0 4 50 -1 14 16 1.5708 4 165 990 4875 3450 net\001 +4 0 4 50 -1 14 16 1.5708 4 210 1155 4875 4950 [34,40[\001 +4 1 7 40 -1 14 16 1.5708 4 165 330 4875 2025 TS\001 +-6 +6 5100 1725 5700 5325 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 5175 2250 5625 2250 5625 5250 5175 5250 5175 2250 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5175 3750 5625 3750 +2 2 0 2 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 5175 2250 5175 1800 5625 1800 5625 2250 5175 2250 +4 0 0 50 -1 14 16 1.5708 4 165 990 5475 3450 net\001 +4 0 0 50 -1 14 16 1.5708 4 210 1155 5475 4950 [45,50[\001 +4 1 7 40 -1 14 16 1.5708 4 165 330 5475 2025 TS\001 +-6 +6 1350 6525 1575 7275 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1425 6600 1425 7200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1500 6600 1500 7200 +-6 +6 8925 6525 9150 7275 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9000 6600 9000 7200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9075 6600 9075 7200 +-6 +1 4 0 2 4 7 50 -1 -1 0.000 1 0.0000 3600 750 75 75 3525 750 3675 750 +1 4 0 2 4 7 50 -1 -1 0.000 1 0.0000 4200 750 75 75 4125 750 4275 750 +1 4 0 2 4 7 50 -1 -1 0.000 1 0.0000 4800 750 75 75 4725 750 4875 750 +1 4 0 2 0 7 50 -1 -1 0.000 1 0.0000 5400 750 75 75 5325 750 5475 750 +1 4 0 2 0 7 50 -1 -1 0.000 1 0.0000 3000 750 75 75 2925 750 3075 750 +1 4 0 2 0 7 50 -1 -1 0.000 1 0.0000 2400 750 75 75 2325 750 2475 750 +1 4 0 2 0 7 50 -1 -1 0.000 1 0.0000 1800 750 75 75 1725 750 1875 750 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2100 600 2100 900 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2700 600 2700 900 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3300 600 3300 900 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3900 600 3900 900 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 4500 600 4500 900 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5100 600 5100 900 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5700 600 5700 900 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1500 600 6300 600 6300 900 1500 900 1500 600 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 2.00 120.00 240.00 + 1800 825 1800 1800 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 2.00 120.00 240.00 + 2400 825 2400 1800 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 2.00 120.00 240.00 + 3000 825 3000 1800 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 2.00 120.00 240.00 + 5400 825 5400 1800 +2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 2.00 120.00 240.00 + 4800 825 4800 1800 +2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 2.00 120.00 240.00 + 4200 825 4200 1800 +2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 2.00 120.00 240.00 + 3600 825 3600 1800 +2 2 0 2 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 1500 300 2700 300 2700 600 1500 600 1500 300 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 1875 6600 1800 6600 1800 7200 1875 7200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 2475 6600 2400 6600 2400 7200 2475 7200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 3075 6600 3000 6600 3000 7200 3075 7200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 3375 6600 3300 6600 3300 7200 3375 7200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 4275 6600 4200 6600 4200 7200 4275 7200 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 1800 6750 2400 6750 2400 7050 1800 7050 1800 6750 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 3300 6750 4200 6750 4200 7050 3300 7050 3300 6750 +2 2 0 0 0 7 60 -1 15 0.000 0 0 -1 0 0 5 + 2400 6750 3000 6750 3000 7050 2400 7050 2400 6750 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 4 + 4575 6600 4500 6600 4500 7200 4575 7200 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 4 + 4875 6600 4800 6600 4800 7200 4875 7200 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 4 + 5475 6600 5400 6600 5400 7200 5475 7200 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 4 + 6075 6600 6000 6600 6000 7200 6075 7200 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 4 + 6675 6600 6600 6600 6600 7200 6675 7200 +2 2 0 0 4 4 61 -1 35 0.000 0 0 -1 0 0 5 + 4500 6750 6000 6750 6000 7050 4500 7050 4500 6750 +2 2 0 0 4 4 62 -1 30 0.000 0 0 -1 0 0 5 + 4500 6675 5400 6675 5400 7125 4500 7125 4500 6675 +2 2 0 0 4 4 60 -1 38 0.000 0 0 -1 0 0 5 + 4800 6825 6600 6825 6600 6975 4800 6975 4800 6825 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 7575 6600 7500 6600 7500 7200 7575 7200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 8475 6600 8400 6600 8400 7200 8475 7200 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 7500 6750 8400 6750 8400 7050 7500 7050 7500 6750 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1200 6900 9300 6900 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 2.00 120.00 240.00 + 1800 5250 1800 6600 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 2.00 120.00 240.00 + 2400 5250 2400 6600 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 2.00 120.00 240.00 + 3000 5250 3300 6600 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 2.00 120.00 240.00 + 5400 5250 7500 6600 +2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 2.00 120.00 240.00 + 3600 5250 4500 6600 +2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 2.00 120.00 240.00 + 4200 5250 4500 6600 +2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 3 1 2.00 120.00 240.00 + 4800 5250 4800 6600 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 4500 7275 4500 8100 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 4800 7275 4800 8100 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5400 7275 5400 8100 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6000 7275 6000 8100 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6600 7275 6600 8100 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 4200 7275 4200 8100 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3300 7275 3300 8100 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3000 7275 3000 8100 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2400 7275 2400 8100 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1800 7275 1800 8100 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 7500 7275 7500 8100 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 8400 7275 8400 8100 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9000 7275 9000 8100 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1500 7275 1500 8100 +2 2 0 0 0 32 100 -1 20 0.000 0 0 -1 0 0 5 + 300 0 9600 0 9600 8700 300 8700 300 0 +4 1 7 40 -1 14 16 0.0000 4 165 825 2100 525 Track\001 +4 0 0 50 -1 16 12 0.0000 4 135 105 1800 8250 5\001 +4 0 0 50 -1 16 12 0.0000 4 135 105 2400 8250 8\001 +4 0 0 50 -1 16 12 0.0000 4 135 210 3000 8250 10\001 +4 0 0 50 -1 16 12 0.0000 4 135 210 3300 8250 12\001 +4 0 0 50 -1 16 12 0.0000 4 135 210 4200 8250 30\001 +4 0 4 50 -1 16 12 0.0000 4 135 210 4500 8250 31\001 +4 0 4 50 -1 16 12 0.0000 4 135 210 4800 8250 34\001 +4 0 4 50 -1 16 12 0.0000 4 135 210 5400 8250 35\001 +4 0 4 50 -1 16 12 0.0000 4 135 210 6000 8250 38\001 +4 0 4 50 -1 16 12 0.0000 4 135 210 6600 8250 40\001 +4 0 0 50 -1 16 12 0.0000 4 135 210 7500 8250 45\001 +4 0 0 50 -1 16 12 0.0000 4 135 210 8400 8250 50\001 +4 0 0 50 -1 16 12 0.0000 4 135 210 9000 8250 60\001 +4 0 0 50 -1 16 12 0.0000 4 135 105 1500 8250 0\001 +4 0 0 50 -1 18 16 0.0000 4 255 330 600 675 (a)\001 +4 0 0 50 -1 18 16 0.0000 4 255 345 600 6975 (b)\001 diff --git a/kite/doc/images/Track-1.png b/kite/doc/images/Track-1.png index 9cc6d7b94f506e45b04e409449bf0c8cd6ff30e5..f3810eab375c264c11c90912e16078b895538b60 100644 GIT binary patch literal 11371 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 diff --git a/kite/doc/images/Track-2.fig b/kite/doc/images/Track-2.fig index 0d1538f8..d396bc36 100644 --- a/kite/doc/images/Track-2.fig +++ b/kite/doc/images/Track-2.fig @@ -1,150 +1,198 @@ -#FIG 3.2 +#FIG 3.2 Produced by xfig version 3.2.5a Landscape Center -Metric +Inches Letter 100.00 Single -2 1200 2 -6 360 855 540 1395 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 405 900 405 1350 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 495 900 495 1350 +0 32 #ffffdd +6 600 -525 8175 3075 +6 3525 1275 7575 1875 +6 3525 1275 4125 1875 +2 2 0 2 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 3600 1350 4050 1350 4050 1800 3600 1800 3600 1350 +4 1 7 40 -1 14 16 0.0000 4 165 330 3825 1650 TS\001 -6 -6 7785 855 7965 1395 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 7830 900 7830 1350 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 7920 900 7920 1350 +1 4 0 2 0 7 50 -1 -1 0.000 1 0.0000 7275 1575 75 75 7200 1575 7350 1575 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5550 1350 5550 1800 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 7500 1350 4050 1350 4050 1800 7500 1800 7500 1350 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 7050 1350 7050 1800 +4 0 0 50 -1 14 16 0.0000 4 165 990 5850 1650 net\001 +4 0 0 50 -1 14 16 0.0000 4 210 825 4350 1650 [5,8[\001 -6 -6 0 0 135 720 -3 0 0 2 0 7 50 -1 -1 0.000 0 0 0 6 - 113 22 68 68 68 135 68 248 68 315 23 360 - 0.000 1.000 1.000 1.000 1.000 0.000 -3 0 0 2 0 7 50 -1 -1 0.000 0 0 0 6 - 113 698 68 653 68 585 68 473 68 405 23 360 - 0.000 1.000 1.000 1.000 1.000 0.000 +6 3525 1875 7575 2475 +6 3525 1875 4125 2475 +2 2 0 2 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 3600 1950 4050 1950 4050 2400 3600 2400 3600 1950 +4 1 7 40 -1 14 16 0.0000 4 165 330 3825 2250 TS\001 -6 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 1485 1935 135 135 1350 1935 1620 1935 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 2160 1935 135 135 2025 1935 2295 1935 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 3510 1935 135 135 3375 1935 3645 1935 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 5310 1935 135 135 5175 1935 5445 1935 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 6300 1935 135 135 6165 1935 6435 1935 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 7335 1935 135 135 7200 1935 7470 1935 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 900 2610 135 135 765 2610 1035 2610 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 900 3060 135 135 765 3060 1035 3060 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 900 3510 135 135 765 3510 1035 3510 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 900 3960 135 135 765 3960 1035 3960 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 900 4410 135 135 765 4410 1035 4410 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 900 4860 135 135 765 4860 1035 4860 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 810 1935 135 135 675 1935 945 1935 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 315 1125 8010 1125 -2 2 0 0 0 7 60 -1 16 0.000 0 0 -1 0 0 5 - 1125 1035 1800 1035 1800 1215 1125 1215 1125 1035 -2 2 0 0 0 7 60 -1 16 0.000 0 0 -1 0 0 5 - 2475 1035 3600 1035 3600 1215 2475 1215 2475 1035 -2 2 0 0 0 7 60 -1 16 0.000 0 0 -1 0 0 5 - 5850 1035 6750 1035 6750 1215 5850 1215 5850 1035 -2 1 0 2 0 7 50 -1 19 0.000 0 0 -1 0 0 2 - 1125 0 1125 900 -2 1 0 2 0 7 50 -1 19 0.000 0 0 -1 0 0 2 - 2475 0 2475 900 -2 1 0 2 0 7 50 -1 19 0.000 0 0 -1 0 0 2 - 5850 0 5850 900 -2 1 0 2 0 7 50 -1 19 0.000 0 0 -1 0 0 2 - 3375 0 3375 810 -2 1 0 0 0 7 60 -1 15 0.000 0 0 -1 0 0 7 - 1125 540 1125 450 2250 450 2475 540 2250 630 1125 630 - 1125 540 -2 1 0 0 0 7 60 -1 15 0.000 0 0 -1 0 0 7 - 2475 540 2475 450 3150 450 3375 540 3150 630 2475 630 - 2475 540 -2 1 0 0 0 7 60 -1 15 0.000 0 0 -1 0 0 7 - 3375 540 3375 450 5625 450 5850 540 5625 630 3375 630 - 3375 540 -2 1 0 0 0 7 60 -1 15 0.000 0 0 -1 0 0 7 - 5850 540 5850 450 7650 450 7875 540 7650 630 5850 630 - 5850 540 -2 1 0 0 0 7 60 -1 15 0.000 0 0 -1 0 0 7 - 450 540 450 450 900 450 1125 540 900 630 450 630 - 450 540 -2 2 0 0 0 7 70 -1 19 0.000 0 0 -1 0 0 5 - 3375 990 4500 990 4500 1260 3375 1260 3375 990 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - -1575 -675 8325 -675 8325 5400 -1575 5400 -1575 -675 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 6795 945 6750 945 6750 1305 6795 1305 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 5895 945 5850 945 5850 1305 5895 1305 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 4545 855 4500 855 4500 1395 4545 1395 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 3645 945 3600 945 3600 1305 3645 1305 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 3420 855 3375 855 3375 1395 3420 1395 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 2520 945 2475 945 2475 1305 2520 1305 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 1845 945 1800 945 1800 1305 1845 1305 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 1170 945 1125 945 1125 1305 1170 1305 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 675 2385 4410 2385 4410 5085 675 5085 675 2385 -4 1 0 50 -1 14 12 0.0000 4 135 105 1125 -45 3\001 -4 1 0 50 -1 14 12 0.0000 4 135 105 2475 -45 9\001 -4 1 0 50 -1 14 12 0.0000 4 135 210 3375 -45 13\001 -4 1 0 50 -1 14 12 0.0000 4 135 210 5850 -45 24\001 -4 1 0 50 -1 14 12 0.0000 4 165 315 810 225 [0]\001 -4 1 0 50 -1 14 12 0.0000 4 165 315 1800 225 [1]\001 -4 1 0 50 -1 14 12 0.0000 4 165 315 2925 225 [2]\001 -4 1 0 50 -1 14 12 0.0000 4 165 315 4635 225 [3]\001 -4 1 0 50 -1 14 12 0.0000 4 165 315 6975 225 [4]\001 -4 0 0 50 -1 14 12 1.5708 4 120 420 7920 0 _max\001 -4 0 0 50 -1 14 12 1.5708 4 165 420 450 0 _min\001 -4 2 0 50 -1 18 12 0.0000 4 180 1125 -90 405 lower_bound\001 -4 1 7 40 -1 18 14 0.0000 4 150 120 810 2025 1\001 -4 1 7 40 -1 18 14 0.0000 4 150 120 1485 2025 2\001 -4 1 7 40 -1 18 14 0.0000 4 150 120 2160 2025 3\001 -4 1 7 40 -1 18 14 0.0000 4 150 120 3510 2025 2\001 -4 1 7 40 -1 18 14 0.0000 4 150 120 5310 2025 3\001 -4 1 7 40 -1 18 14 0.0000 4 150 120 6300 2025 4\001 -4 1 7 40 -1 18 14 0.0000 4 150 120 7335 2025 5\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 1215 4905 [\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 1215 4455 [\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 1215 4005 [\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 1215 3555 [\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 1215 3105 [\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 1215 2655 [\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 4140 3105 ]\001 -4 0 0 50 -1 14 14 0.0000 4 180 540 1395 2655 _min\001 -4 0 0 50 -1 14 14 0.0000 4 60 135 2700 3150 ,\001 -4 0 0 50 -1 14 14 0.0000 4 180 1080 2925 3105 max(i-1)\001 -4 0 0 50 -1 14 14 0.0000 4 180 1080 1440 3105 min(i-1)\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 4140 2655 ]\001 -4 0 0 50 -1 14 14 0.0000 4 180 810 2925 2655 min(i)\001 -4 0 0 50 -1 14 14 0.0000 4 60 135 2700 2700 ,\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 4140 3555 ]\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 4140 4005 ]\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 4140 4455 ]\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 4140 4905 ]\001 -4 0 0 50 -1 14 14 0.0000 4 180 810 2925 3555 min(i)\001 -4 0 0 50 -1 14 14 0.0000 4 180 1080 2925 4005 max(i-1)\001 -4 0 0 50 -1 14 14 0.0000 4 135 540 2925 4455 _max\001 -4 0 0 50 -1 14 14 0.0000 4 135 540 2925 4905 _max\001 -4 0 0 50 -1 14 14 0.0000 4 180 1215 1440 3555 _max(i-1)\001 -4 0 0 50 -1 14 14 0.0000 4 180 1080 1440 4005 min(i-1)\001 -4 0 0 50 -1 14 14 0.0000 4 180 1080 1440 4455 max(i-1)\001 -4 0 0 50 -1 14 14 0.0000 4 180 540 1440 4905 _min\001 -4 0 0 50 -1 14 14 0.0000 4 60 135 2700 3600 ,\001 -4 0 0 50 -1 14 14 0.0000 4 60 135 2700 4050 ,\001 -4 0 0 50 -1 14 14 0.0000 4 60 135 2700 4500 ,\001 -4 0 0 50 -1 14 14 0.0000 4 60 135 2700 4950 ,\001 -4 1 7 40 -1 10 14 0.0000 4 135 90 900 2700 1\001 -4 1 7 40 -1 18 14 0.0000 4 150 120 900 3150 2\001 -4 1 7 40 -1 18 14 0.0000 4 150 120 900 3600 3\001 -4 1 7 40 -1 18 14 0.0000 4 150 120 900 4050 4\001 -4 1 7 40 -1 18 14 0.0000 4 150 120 900 4500 5\001 -4 1 7 40 -1 18 14 0.0000 4 150 120 900 4950 6\001 +1 4 0 2 0 7 50 -1 -1 0.000 1 0.0000 7275 2175 75 75 7200 2175 7350 2175 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5550 1950 5550 2400 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 7500 1950 7500 2400 4050 2400 4050 1950 7500 1950 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 7050 1950 7050 2400 +4 0 0 50 -1 14 16 0.0000 4 165 990 5850 2250 net\001 +4 0 0 50 -1 14 16 0.0000 4 225 990 4350 2250 [8,10[\001 +-6 +6 3525 2475 7575 3075 +6 3525 2475 4125 3075 +2 2 0 2 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 3600 2550 4050 2550 4050 3000 3600 3000 3600 2550 +4 1 7 40 -1 14 16 0.0000 4 165 330 3825 2850 TS\001 +-6 +1 4 0 2 0 7 50 -1 -1 0.000 1 0.0000 7275 2775 75 75 7200 2775 7350 2775 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5550 2550 5550 3000 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 7500 2550 7500 3000 4050 3000 4050 2550 7500 2550 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 7050 2550 7050 3000 +4 0 0 50 -1 14 16 0.0000 4 165 990 5850 2850 net\001 +4 0 0 50 -1 14 16 0.0000 4 225 1155 4350 2850 [12,30[\001 +-6 +6 1425 225 6375 975 +1 4 0 2 0 7 50 -1 -1 0.000 1 0.0000 3000 750 75 75 2925 750 3075 750 +1 4 0 2 0 7 50 -1 -1 0.000 1 0.0000 2400 750 75 75 2325 750 2475 750 +1 4 0 2 0 7 50 -1 -1 0.000 1 0.0000 1800 750 75 75 1725 750 1875 750 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2100 600 2100 900 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2700 600 2700 900 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3300 600 3300 900 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3900 600 3900 900 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 4500 600 4500 900 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5100 600 5100 900 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5700 600 5700 900 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1500 600 6300 600 6300 900 1500 900 1500 600 +2 2 0 2 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 1500 300 2700 300 2700 600 1500 600 1500 300 +4 1 7 40 -1 14 16 0.0000 4 165 825 2100 525 Track\001 +-6 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 4 + 3 1 2.00 120.00 240.00 + 3000 825 3000 1425 3150 1575 3600 1575 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 4 + 3 1 2.00 120.00 240.00 + 2400 825 2400 2025 2550 2175 3600 2175 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 4 + 3 1 2.00 120.00 240.00 + 1800 825 1800 2625 1950 2775 3600 2775 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 8 + 3 1 2.00 120.00 240.00 + 2550 300 2550 0 2700 -150 7650 -150 7800 0 7800 1425 + 7650 1575 7350 1575 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 8 + 3 1 2.00 120.00 240.00 + 2400 300 2400 -150 2550 -300 7800 -300 7950 -150 7950 2025 + 7800 2175 7500 2175 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 8 + 3 1 2.00 120.00 240.00 + 2250 300 2250 -300 2400 -450 7950 -450 8100 -300 8100 2625 + 7950 2775 7500 2775 +2 1 0 4 4 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 7650 1950 7800 2400 +2 1 0 4 4 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 7800 1950 7650 2400 +4 0 0 50 -1 18 16 0.0000 4 255 330 600 675 (a)\001 +-6 +6 3525 6525 7575 7125 +6 3525 6525 4125 7125 +2 2 0 2 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 3600 6600 4050 6600 4050 7050 3600 7050 3600 6600 +4 1 7 40 -1 14 16 0.0000 4 165 330 3825 6900 TS\001 +-6 +1 4 0 2 0 7 50 -1 -1 0.000 1 0.0000 7275 6825 75 75 7200 6825 7350 6825 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5550 6600 5550 7050 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 7500 6600 7500 7050 4050 7050 4050 6600 7500 6600 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 7050 6600 7050 7050 +4 0 0 50 -1 14 16 0.0000 4 165 990 5850 6900 net\001 +4 0 0 50 -1 14 16 0.0000 4 225 1155 4350 6900 [12,30[\001 +-6 +6 3525 5325 7575 5925 +6 3525 5325 4125 5925 +2 2 0 2 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 3600 5400 4050 5400 4050 5850 3600 5850 3600 5400 +4 1 7 40 -1 14 16 0.0000 4 165 330 3825 5700 TS\001 +-6 +1 4 0 2 0 7 50 -1 -1 0.000 1 0.0000 7275 5625 75 75 7200 5625 7350 5625 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5550 5400 5550 5850 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 7500 5400 4050 5400 4050 5850 7500 5850 7500 5400 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 7050 5400 7050 5850 +4 0 0 50 -1 14 16 0.0000 4 165 990 5850 5700 net\001 +4 0 0 50 -1 14 16 0.0000 4 210 825 4350 5700 [5,8[\001 +-6 +6 3525 5925 7575 6525 +2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5550 6000 5550 6450 +2 2 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 7500 6000 4050 6000 4050 6450 7500 6450 7500 6000 +2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 7050 6000 7050 6450 +2 2 0 2 4 4 50 -1 20 0.000 0 0 -1 0 0 5 + 3600 6000 4050 6000 4050 6450 3600 6450 3600 6000 +4 0 4 50 -1 14 16 0.0000 4 165 990 5850 6300 net\001 +4 0 4 50 -1 14 16 0.0000 4 225 990 4350 6300 [8,10[\001 +4 1 7 40 -1 14 16 0.0000 4 165 330 3825 6300 TS\001 +4 1 4 50 -1 14 10 0.0000 4 90 420 7275 6300 NULL\001 +-6 +1 4 0 2 0 7 50 -1 -1 0.000 1 0.0000 3000 4800 75 75 2925 4800 3075 4800 +1 4 0 2 4 7 50 -1 -1 0.000 1 0.0000 2400 4800 75 75 2325 4800 2475 4800 +1 4 0 2 0 7 50 -1 -1 0.000 1 0.0000 1800 4800 75 75 1725 4800 1875 4800 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 4 + 3 1 2.00 120.00 240.00 + 3000 4875 3000 5475 3150 5625 3600 5625 +2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 1 0 4 + 3 1 2.00 120.00 240.00 + 2400 4875 2400 6075 2550 6225 3600 6225 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 1 0 4 + 3 1 2.00 120.00 240.00 + 1800 4875 1800 6675 1950 6825 3600 6825 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 8 + 3 1 2.00 120.00 240.00 + 2550 4350 2550 4050 2700 3900 7650 3900 7800 4050 7800 5475 + 7650 5625 7350 5625 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 1 8 + 3 1 2.00 120.00 240.00 + 2250 4350 2250 3750 2400 3600 7950 3600 8100 3750 8100 6675 + 7950 6825 7500 6825 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2100 4650 2100 4950 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2700 4650 2700 4950 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3300 4650 3300 4950 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3900 4650 3900 4950 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 4500 4650 4500 4950 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5100 4650 5100 4950 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5700 4650 5700 4950 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1500 4650 6300 4650 6300 4950 1500 4950 1500 4650 +2 2 0 2 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 1500 4350 2700 4350 2700 4650 1500 4650 1500 4350 +2 2 0 0 0 32 100 -1 20 0.000 0 0 -1 0 0 5 + 450 -750 8400 -750 8400 7350 450 7350 450 -750 +4 0 0 50 -1 18 16 0.0000 4 255 345 600 4725 (b)\001 +4 1 7 40 -1 14 16 0.0000 4 165 825 2100 4575 Track\001 diff --git a/kite/doc/images/Track-2.png b/kite/doc/images/Track-2.png index d86778946e03348aaa12c4313eb6fdabfabeb00c..96699293f0d0fd5e29b9032ae6db1b4536422587 100644 GIT binary patch literal 11720 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 O=&V9cO=$f6dhj1VQ$yJR literal 8319 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 KKM()WL;njp-5#9) diff --git a/kite/doc/images/Track-3.fig b/kite/doc/images/Track-3.fig deleted file mode 100644 index 6808410d..00000000 --- a/kite/doc/images/Track-3.fig +++ /dev/null @@ -1,165 +0,0 @@ -#FIG 3.2 -Landscape -Center -Metric -Letter -100.00 -Single --2 -1200 2 -6 360 855 540 1395 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 405 900 405 1350 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 495 900 495 1350 --6 -6 7785 855 7965 1395 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 7830 900 7830 1350 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 7920 900 7920 1350 --6 -6 0 0 135 720 -3 0 0 2 0 7 50 -1 -1 0.000 0 0 0 6 - 113 22 68 68 68 135 68 248 68 315 23 360 - 0.000 1.000 1.000 1.000 1.000 0.000 -3 0 0 2 0 7 50 -1 -1 0.000 0 0 0 6 - 113 698 68 653 68 585 68 473 68 405 23 360 - 0.000 1.000 1.000 1.000 1.000 0.000 --6 -6 630 1755 990 2115 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 810 1935 135 135 675 1935 945 1935 -4 1 7 40 -1 18 14 0.0000 4 150 120 810 2025 1\001 --6 -6 1305 1755 1665 2115 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 1485 1935 135 135 1350 1935 1620 1935 -4 1 7 40 -1 18 14 0.0000 4 150 120 1485 2025 2\001 --6 -6 1980 1755 2340 2115 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 2160 1935 135 135 2025 1935 2295 1935 -4 1 7 40 -1 18 14 0.0000 4 150 120 2160 2025 3\001 --6 -6 3330 1755 3690 2115 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 3510 1935 135 135 3375 1935 3645 1935 -4 1 7 40 -1 18 14 0.0000 4 150 120 3510 2025 2\001 --6 -6 5130 1755 5490 2115 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 5310 1935 135 135 5175 1935 5445 1935 -4 1 7 40 -1 18 14 0.0000 4 150 120 5310 2025 3\001 --6 -6 675 2340 4410 4635 -6 720 2385 1080 2745 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 900 2565 135 135 765 2565 1035 2565 -4 1 7 40 -1 18 14 0.0000 4 150 120 900 2655 1\001 --6 -6 720 2835 1080 3195 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 900 3015 135 135 765 3015 1035 3015 -4 1 7 40 -1 18 14 0.0000 4 150 120 900 3105 2\001 --6 -6 720 3285 1080 3645 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 900 3465 135 135 765 3465 1035 3465 -4 1 7 40 -1 18 14 0.0000 4 150 120 900 3555 3\001 --6 -6 720 3735 1080 4095 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 900 3915 135 135 765 3915 1035 3915 -4 1 7 40 -1 18 14 0.0000 4 150 120 900 4005 4\001 --6 -6 720 4185 1080 4545 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 900 4365 135 135 765 4365 1035 4365 -4 1 7 40 -1 18 14 0.0000 4 150 120 900 4455 5\001 --6 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 675 2340 4410 2340 4410 4635 675 4635 675 2340 -4 0 0 50 -1 14 14 0.0000 4 180 135 1215 3960 [\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 1215 3510 [\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 1215 3060 [\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 1215 2610 [\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 4140 3060 ]\001 -4 0 0 50 -1 14 14 0.0000 4 180 540 1395 2610 _min\001 -4 0 0 50 -1 14 14 0.0000 4 60 135 2700 3105 ,\001 -4 0 0 50 -1 14 14 0.0000 4 180 810 2925 3060 max(i)\001 -4 0 0 50 -1 14 14 0.0000 4 180 810 1440 3060 min(i)\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 4140 2610 ]\001 -4 0 0 50 -1 14 14 0.0000 4 180 810 2925 2610 min(i)\001 -4 0 0 50 -1 14 14 0.0000 4 60 135 2700 2655 ,\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 4140 3510 ]\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 4140 3960 ]\001 -4 0 0 50 -1 14 14 0.0000 4 180 1080 2925 3510 min(i+1)\001 -4 0 0 50 -1 14 14 0.0000 4 135 540 2925 3960 _max\001 -4 0 0 50 -1 14 14 0.0000 4 180 810 1440 3510 max(i)\001 -4 0 0 50 -1 14 14 0.0000 4 180 810 1440 3960 max(i)\001 -4 0 0 50 -1 14 14 0.0000 4 60 135 2700 3555 ,\001 -4 0 0 50 -1 14 14 0.0000 4 60 135 2700 4005 ,\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 1215 4410 [\001 -4 0 0 50 -1 14 14 0.0000 4 180 540 1440 4410 _min\001 -4 0 0 50 -1 14 14 0.0000 4 60 135 2700 4455 ,\001 -4 0 0 50 -1 14 14 0.0000 4 135 540 2925 4410 _max\001 -4 0 0 50 -1 14 14 0.0000 4 180 135 4140 4410 ]\001 --6 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 7335 1935 135 135 7200 1935 7470 1935 -1 4 0 1 0 7 50 -1 0 0.000 1 0.0000 6300 1935 135 135 6165 1935 6435 1935 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 315 1125 8010 1125 -2 2 0 0 0 7 60 -1 16 0.000 0 0 -1 0 0 5 - 1125 1035 1800 1035 1800 1215 1125 1215 1125 1035 -2 2 0 0 0 7 60 -1 16 0.000 0 0 -1 0 0 5 - 2475 1035 3600 1035 3600 1215 2475 1215 2475 1035 -2 2 0 0 0 7 60 -1 16 0.000 0 0 -1 0 0 5 - 5850 1035 6750 1035 6750 1215 5850 1215 5850 1035 -2 1 0 2 0 7 50 -1 19 0.000 0 0 -1 0 0 2 - 1125 0 1125 900 -2 1 0 2 0 7 50 -1 19 0.000 0 0 -1 0 0 2 - 2475 0 2475 900 -2 1 0 2 0 7 50 -1 19 0.000 0 0 -1 0 0 2 - 5850 0 5850 900 -2 1 0 2 0 7 50 -1 19 0.000 0 0 -1 0 0 2 - 3375 0 3375 810 -2 1 0 0 0 7 60 -1 15 0.000 0 0 -1 0 0 7 - 1125 540 1125 450 2250 450 2475 540 2250 630 1125 630 - 1125 540 -2 1 0 0 0 7 60 -1 15 0.000 0 0 -1 0 0 7 - 2475 540 2475 450 3150 450 3375 540 3150 630 2475 630 - 2475 540 -2 1 0 0 0 7 60 -1 15 0.000 0 0 -1 0 0 7 - 3375 540 3375 450 5625 450 5850 540 5625 630 3375 630 - 3375 540 -2 1 0 0 0 7 60 -1 15 0.000 0 0 -1 0 0 7 - 5850 540 5850 450 7650 450 7875 540 7650 630 5850 630 - 5850 540 -2 1 0 0 0 7 60 -1 15 0.000 0 0 -1 0 0 7 - 450 540 450 450 900 450 1125 540 900 630 450 630 - 450 540 -2 2 0 0 0 7 70 -1 19 0.000 0 0 -1 0 0 5 - 3375 990 4500 990 4500 1260 3375 1260 3375 990 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - -1800 -675 8325 -675 8325 4950 -1800 4950 -1800 -675 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 1170 945 1125 945 1125 1305 1170 1305 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 1845 945 1800 945 1800 1305 1845 1305 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 2520 945 2475 945 2475 1305 2520 1305 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 3420 855 3375 855 3375 1395 3420 1395 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 3645 945 3600 945 3600 1305 3645 1305 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 4545 855 4500 855 4500 1395 4545 1395 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 5895 945 5850 945 5850 1305 5895 1305 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 6795 945 6750 945 6750 1305 6795 1305 -4 1 0 50 -1 14 12 0.0000 4 135 105 1125 -45 3\001 -4 1 0 50 -1 14 12 0.0000 4 135 105 2475 -45 9\001 -4 1 0 50 -1 14 12 0.0000 4 135 210 3375 -45 13\001 -4 1 0 50 -1 14 12 0.0000 4 135 210 5850 -45 24\001 -4 1 0 50 -1 14 12 0.0000 4 165 315 810 225 [0]\001 -4 1 0 50 -1 14 12 0.0000 4 165 315 1800 225 [0]\001 -4 1 0 50 -1 14 12 0.0000 4 165 315 2925 225 [1]\001 -4 1 0 50 -1 14 12 0.0000 4 165 315 4635 225 [2]\001 -4 1 0 50 -1 14 12 0.0000 4 165 315 6975 225 [3]\001 -4 0 0 50 -1 14 12 1.5708 4 120 420 7920 0 _max\001 -4 0 0 50 -1 14 12 1.5708 4 165 420 450 0 _min\001 -4 2 0 50 -1 18 12 0.0000 4 180 1425 -90 405 lower_bound - 1\001 -4 1 7 40 -1 18 14 0.0000 4 150 120 6300 2025 2\001 -4 1 7 40 -1 18 14 0.0000 4 150 120 7335 2025 4\001 diff --git a/kite/doc/images/Track-4.fig b/kite/doc/images/Track-4.fig deleted file mode 100644 index 23c699f6..00000000 --- a/kite/doc/images/Track-4.fig +++ /dev/null @@ -1,83 +0,0 @@ -#FIG 3.2 -Landscape -Center -Metric -Letter -100.00 -Single --2 -1200 2 -6 360 855 540 1395 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 405 900 405 1350 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 495 900 495 1350 --6 -6 7785 855 7965 1395 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 7830 900 7830 1350 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 7920 900 7920 1350 --6 -1 4 0 1 0 7 50 -1 -1 0.000 1 0.0000 3600 1800 90 90 3510 1800 3690 1800 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 315 1125 8010 1125 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 1395 855 1350 855 1350 1395 1395 1395 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 2295 945 2250 945 2250 1305 2295 1305 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 3195 945 3150 945 3150 1305 3195 1305 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 4095 945 4050 945 4050 1305 4095 1305 -2 2 0 0 0 7 60 -1 16 0.000 0 0 -1 0 0 5 - 4050 1035 4950 1035 4950 1215 4050 1215 4050 1035 -2 2 0 0 0 7 60 -1 16 0.000 0 0 -1 0 0 5 - 2250 1035 3150 1035 3150 1215 2250 1215 2250 1035 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 7470 945 7425 945 7425 1305 7470 1305 -2 2 0 0 0 7 60 -1 16 0.000 0 0 -1 0 0 5 - 6525 1035 7425 1035 7425 1215 6525 1215 6525 1035 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 6570 945 6525 945 6525 1305 6570 1305 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 5895 855 5850 855 5850 1395 5895 1395 -2 2 0 0 0 7 70 -1 19 0.000 0 0 -1 0 0 5 - 1350 990 5850 990 5850 1260 1350 1260 1350 990 -2 1 0 2 0 7 50 -1 19 0.000 0 0 -1 0 0 2 - 2250 0 2250 855 -2 1 0 2 0 7 50 -1 19 0.000 0 0 -1 0 0 2 - 1350 0 1350 765 -2 1 0 2 0 7 50 -1 19 0.000 0 0 -1 0 0 2 - 4050 0 4050 855 -2 1 0 2 0 7 50 -1 19 0.000 0 0 -1 0 0 2 - 6525 0 6525 855 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 3 1 1.00 60.00 120.00 - 3600 2250 3600 1215 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 3 1 1.00 60.00 120.00 - 3510 1800 2295 1800 -2 1 3 2 0 7 50 -1 -1 4.500 0 0 -1 0 0 2 - 2250 1395 2250 2250 -2 1 3 2 0 7 50 -1 -1 4.500 0 0 -1 0 0 2 - 1350 1485 1350 2250 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 3 1 1.00 60.00 120.00 - 2250 2025 1350 2025 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 4995 945 4950 945 4950 1305 4995 1305 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 0 -675 8325 -675 8325 3375 0 3375 0 -675 -3 0 0 2 0 7 50 -1 -1 0.000 0 0 0 6 - 1350 2475 1575 2700 1800 2700 3150 2700 3375 2700 3600 2925 - 0.000 1.000 1.000 1.000 1.000 0.000 -3 0 0 2 0 7 50 -1 -1 0.000 0 0 0 6 - 5850 2475 5625 2700 5400 2700 4050 2700 3825 2700 3600 2925 - 0.000 1.000 1.000 1.000 1.000 0.000 -4 1 0 50 -1 14 12 0.0000 4 135 105 1350 -45 4\001 -4 1 0 50 -1 14 12 0.0000 4 135 105 2250 -45 8\001 -4 1 0 50 -1 14 12 0.0000 4 135 210 4050 -45 16\001 -4 1 0 50 -1 14 12 0.0000 4 135 210 6525 -45 27\001 -4 1 0 50 -1 14 12 0.0000 4 180 840 3600 2475 position\001 -4 1 0 50 -1 18 14 0.0000 4 210 2820 3600 3150 Overlaping TrackSegments\001 diff --git a/kite/doc/images/Track-5.fig b/kite/doc/images/Track-5.fig deleted file mode 100644 index 8a712345..00000000 --- a/kite/doc/images/Track-5.fig +++ /dev/null @@ -1,74 +0,0 @@ -#FIG 3.2 -Landscape -Center -Metric -Letter -100.00 -Single --2 -1200 2 -6 360 855 540 1395 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 405 900 405 1350 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 495 900 495 1350 --6 -6 7785 855 7965 1395 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 7830 900 7830 1350 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 7920 900 7920 1350 --6 -1 4 0 1 0 7 50 -1 -1 0.000 1 0.0000 3600 1800 90 90 3510 1800 3690 1800 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 - 315 1125 8010 1125 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 1395 855 1350 855 1350 1395 1395 1395 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 2295 945 2250 945 2250 1305 2295 1305 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 7470 945 7425 945 7425 1305 7470 1305 -2 2 0 0 0 7 60 -1 16 0.000 0 0 -1 0 0 5 - 6525 1035 7425 1035 7425 1215 6525 1215 6525 1035 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 6570 945 6525 945 6525 1305 6570 1305 -2 1 0 2 0 7 50 -1 19 0.000 0 0 -1 0 0 2 - 2250 0 2250 855 -2 1 0 2 0 7 50 -1 19 0.000 0 0 -1 0 0 2 - 1350 0 1350 765 -2 1 0 2 0 7 50 -1 19 0.000 0 0 -1 0 0 2 - 6525 0 6525 855 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 3 1 1.00 60.00 120.00 - 3600 2250 3600 1215 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 3 1 1.00 60.00 120.00 - 3510 1800 2295 1800 -2 1 3 2 0 7 50 -1 -1 4.500 0 0 -1 0 0 2 - 2250 1395 2250 2250 -2 1 3 2 0 7 50 -1 -1 4.500 0 0 -1 0 0 2 - 1350 1485 1350 2250 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 - 3 1 1.00 60.00 120.00 - 2250 2025 1350 2025 -2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 - 0 -675 8325 -675 8325 3375 0 3375 0 -675 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 4095 945 4050 945 4050 1305 4095 1305 -2 2 0 0 0 7 60 -1 16 0.000 0 0 -1 0 0 5 - 2250 1035 4050 1035 4050 1215 2250 1215 2250 1035 -2 1 0 4 0 7 50 -1 -1 0.000 0 0 7 0 0 4 - 2970 855 2925 855 2925 1395 2970 1395 -2 2 0 0 0 7 70 -1 19 0.000 0 0 -1 0 0 5 - 1350 990 2925 990 2925 1260 1350 1260 1350 990 -3 0 0 2 0 7 50 -1 -1 0.000 0 0 0 6 - 4095 2475 3825 2700 3600 2700 3150 2700 2925 2700 2700 2925 - 0.000 1.000 1.000 1.000 1.000 0.000 -3 0 0 2 0 7 50 -1 -1 0.000 0 0 0 6 - 1350 2475 1575 2700 1800 2700 2250 2700 2475 2700 2700 2925 - 0.000 1.000 1.000 1.000 1.000 0.000 -4 1 0 50 -1 14 12 0.0000 4 135 105 1350 -45 4\001 -4 1 0 50 -1 14 12 0.0000 4 135 105 2250 -45 8\001 -4 1 0 50 -1 14 12 0.0000 4 135 210 6525 -45 27\001 -4 1 0 50 -1 14 12 0.0000 4 180 840 3600 2475 position\001 -4 1 0 50 -1 18 14 0.0000 4 210 2820 3600 3150 Overlaping TrackSegments\001 diff --git a/kite/doc/images/TrackBeginIndex-1.fig b/kite/doc/images/TrackBeginIndex-1.fig new file mode 100644 index 00000000..a50aa6fe --- /dev/null +++ b/kite/doc/images/TrackBeginIndex-1.fig @@ -0,0 +1,269 @@ +#FIG 3.2 Produced by xfig version 3.2.5a +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +0 32 #ffffdd +6 1725 8325 2850 9075 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 1800 8550 2700 8550 2700 8850 1800 8850 1800 8550 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 1875 8400 1800 8400 1800 9000 1875 9000 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 2775 8400 2700 8400 2700 9000 2775 9000 +-6 +6 3225 8325 4050 9075 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 3975 8400 3900 8400 3900 9000 3975 9000 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 3300 8550 3900 8550 3900 8850 3300 8850 3300 8550 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 3375 8400 3300 8400 3300 9000 3375 9000 +-6 +6 6000 4200 6450 4800 +6 6000 4500 6450 4800 +2 2 0 1 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 6000 4500 6450 4500 6450 4800 6000 4800 6000 4500 +4 0 7 40 -1 14 14 0.0000 4 135 300 6075 4725 LB\001 +-6 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6000 4200 6000 4800 +-6 +6 6000 6600 6450 7200 +6 6000 6900 6450 7200 +2 2 0 1 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 6000 6900 6450 6900 6450 7200 6000 7200 6000 6900 +4 0 7 40 -1 14 14 0.0000 4 135 300 6075 7125 LB\001 +-6 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6000 6600 6000 7200 +-6 +6 9000 9000 9450 9600 +6 9000 9300 9450 9600 +2 2 0 1 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 9000 9300 9450 9300 9450 9600 9000 9600 9000 9300 +4 0 7 40 -1 14 14 0.0000 4 135 300 9075 9525 LB\001 +-6 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9000 9000 9000 9600 +-6 +6 9000 11400 9450 12000 +6 9000 11700 9450 12000 +2 2 0 1 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 9000 11700 9450 11700 9450 12000 9000 12000 9000 11700 +4 0 7 40 -1 14 14 0.0000 4 135 300 9075 11925 LB\001 +-6 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9000 11400 9000 12000 +-6 +6 3600 1200 4050 1800 +6 3600 1500 4050 1800 +2 2 0 1 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 3600 1500 4050 1500 4050 1800 3600 1800 3600 1500 +4 0 7 40 -1 14 14 0.0000 4 135 300 3675 1725 LB\001 +-6 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3600 1200 3600 1800 +-6 +6 8925 525 9150 1275 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9000 600 9000 1200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9075 600 9075 1200 +-6 +6 5925 525 6750 1275 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 6675 600 6600 600 6600 1200 6675 1200 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 6000 750 6600 750 6600 1050 6000 1050 6000 750 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 6075 600 6000 600 6000 1200 6075 1200 +-6 +6 8925 3525 9150 4275 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9000 3600 9000 4200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9075 3600 9075 4200 +-6 +6 5925 3525 6750 4275 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 6675 3600 6600 3600 6600 4200 6675 4200 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 6000 3750 6600 3750 6600 4050 6000 4050 6000 3750 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 6075 3600 6000 3600 6000 4200 6075 4200 +-6 +6 8925 5925 9150 6675 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9000 6000 9000 6600 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9075 6000 9075 6600 +-6 +6 4125 6300 6000 7200 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 4200 7200 4200 6300 +4 0 0 50 -1 14 12 0.0000 4 120 1680 4275 7200 OutsideElement\001 +4 0 0 50 -1 12 14 0.0000 4 135 450 4275 6975 Pos\001 +-6 +6 3300 5400 5475 6000 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3300 5400 3300 6000 +4 0 4 50 -1 12 14 0.0000 4 195 1050 3375 5550 begin:0\001 +4 0 4 50 -1 14 12 0.0000 4 165 2040 3375 5775 BeginIsSegmentMax\001 +-6 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2400 2400 2400 900 +2 1 0 4 4 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1500 10800 1500 11400 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1200 11100 9300 11100 +2 1 0 4 4 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1425 10800 1425 11400 +2 1 0 4 1 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 9000 10800 9000 11400 +2 1 0 4 1 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 9075 10800 9075 11400 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 6900 12000 6900 11100 +2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9000 10200 9000 10800 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1500 10200 1500 10800 +2 1 0 4 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1500 8400 1500 9000 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1200 8700 9300 8700 +2 1 0 4 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1425 8400 1425 9000 +2 1 0 4 4 7 51 -1 -1 0.000 0 0 -1 0 0 4 + 5775 8400 5700 8400 5700 9000 5775 9000 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 4800 8550 5700 8550 5700 8850 4800 8850 4800 8550 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 4875 8400 4800 8400 4800 9000 4875 9000 +2 1 0 4 1 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 9000 8400 9000 9000 +2 1 0 4 1 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 9075 8400 9075 9000 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 6900 9600 6900 8700 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5700 7800 5700 8400 +2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9000 7800 9000 8400 +2 1 0 4 4 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1425 600 1425 1200 +2 1 0 4 4 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1500 600 1500 1200 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1500 0 1500 600 +2 1 0 4 1 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 3675 600 3600 600 3600 1200 3675 1200 +2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3600 0 3600 600 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1200 900 9300 900 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 8475 600 8400 600 8400 1200 8475 1200 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 7500 750 8400 750 8400 1050 7500 1050 7500 750 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 7575 600 7500 600 7500 1200 7575 1200 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 3600 750 4500 750 4500 1050 3600 1050 3600 750 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 4575 600 4500 600 4500 1200 4575 1200 +2 1 0 4 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1500 3600 1500 4200 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1200 3900 9300 3900 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 8475 3600 8400 3600 8400 4200 8475 4200 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 7500 3750 8400 3750 8400 4050 7500 4050 7500 3750 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 7575 3600 7500 3600 7500 4200 7575 4200 +2 1 0 4 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1425 3600 1425 4200 +2 1 0 4 4 7 51 -1 -1 0.000 0 0 -1 0 0 4 + 2475 3600 2400 3600 2400 4200 2475 4200 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3000 4800 3000 3900 +2 1 0 4 1 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 5175 3600 5100 3600 5100 4200 5175 4200 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 2400 3750 5100 3750 5100 4050 2400 4050 2400 3750 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2400 3000 2400 3600 +2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5100 3000 5100 3600 +2 1 0 4 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1500 6000 1500 6600 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1200 6300 9300 6300 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 8475 6000 8400 6000 8400 6600 8475 6600 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 7500 6150 8400 6150 8400 6450 7500 6450 7500 6150 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 7575 6000 7500 6000 7500 6600 7575 6600 +2 1 0 4 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1425 6000 1425 6600 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 6675 6000 6600 6000 6600 6600 6675 6600 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 6000 6150 6600 6150 6600 6450 6000 6450 6000 6150 +2 1 0 4 1 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 6075 6000 6000 6000 6000 6600 6075 6600 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 2400 6150 3300 6150 3300 6450 2400 6450 2400 6150 +2 1 0 4 4 7 51 -1 -1 0.000 0 0 -1 0 0 4 + 3375 6000 3300 6000 3300 6600 3375 6600 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 2475 6000 2400 6000 2400 6600 2475 6600 +2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6000 5400 6000 6000 +2 2 0 0 0 32 100 -1 20 0.000 0 0 -1 0 0 5 + 900 -300 10800 -300 10800 12300 900 12300 900 -300 +4 0 0 50 -1 14 12 0.0000 4 120 2160 2475 2400 BeforeFirstElement\001 +4 0 0 50 -1 12 14 0.0000 4 135 450 2475 2175 Pos\001 +4 0 0 50 -1 14 12 0.0000 4 165 1200 6975 12000 EmptyTrack\001 +4 0 0 50 -1 12 14 0.0000 4 135 450 6975 11775 Pos\001 +4 0 1 50 -1 14 12 0.0000 4 120 1560 9075 10575 EndIsTrackMax\001 +4 0 4 50 -1 12 14 0.0000 4 195 1050 1575 10350 begin:0\001 +4 0 4 50 -1 14 12 0.0000 4 165 1800 1575 10575 BeginIsTrackMin\001 +4 0 0 50 -1 14 12 0.0000 4 120 1920 6975 9600 AfterLastElement\001 +4 0 0 50 -1 12 14 0.0000 4 135 450 6975 9375 Pos\001 +4 0 4 50 -1 12 14 0.0000 4 195 1050 5775 7950 begin:2\001 +4 0 4 50 -1 14 12 0.0000 4 165 2040 5775 8175 BeginIsSegmentMax\001 +4 0 1 50 -1 14 12 0.0000 4 120 1560 9075 8175 EndIsTrackMax\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 4050 825 [0]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 6300 825 [1]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 7950 825 [2]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 3750 3825 [0]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 2850 6225 [0]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 6300 3825 [1]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 6300 6225 [1]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 7950 3825 [2]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 7950 6225 [2]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 2250 8625 [0]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 5250 8625 [2]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 3600 8625 [1]\001 +4 0 4 50 -1 12 14 0.0000 4 195 1050 1575 150 begin:0\001 +4 0 4 50 -1 14 12 0.0000 4 165 1800 1575 375 BeginIsTrackMin\001 +4 0 1 50 -1 14 12 0.0000 4 165 1800 3675 375 EndIsSegmentMin\001 +4 0 0 50 -1 14 12 0.0000 4 120 1560 3075 4800 InsideElement\001 +4 0 0 50 -1 12 14 0.0000 4 135 450 3075 4575 Pos\001 +4 0 4 50 -1 12 14 0.0000 4 195 1050 2475 3150 begin:0\001 +4 0 4 50 -1 14 12 0.0000 4 165 2040 2475 3375 BeginIsSegmentMin\001 +4 0 1 50 -1 14 12 0.0000 4 165 1800 5175 3375 EndIsSegmentMax\001 +4 0 1 50 -1 14 12 0.0000 4 165 2280 6075 5775 EndIsNextSegmentMin\001 diff --git a/kite/doc/images/TrackBeginIndex-1.png b/kite/doc/images/TrackBeginIndex-1.png new file mode 100644 index 0000000000000000000000000000000000000000..c171092a4705466bc698331d3e506fd816e61638 GIT binary patch literal 20034 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

    RS({`6CB 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 literal 0 HcmV?d00001 diff --git a/kite/doc/images/TrackEnclosingBounds-1.fig b/kite/doc/images/TrackEnclosingBounds-1.fig new file mode 100644 index 00000000..a50aa6fe --- /dev/null +++ b/kite/doc/images/TrackEnclosingBounds-1.fig @@ -0,0 +1,269 @@ +#FIG 3.2 Produced by xfig version 3.2.5a +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +0 32 #ffffdd +6 1725 8325 2850 9075 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 1800 8550 2700 8550 2700 8850 1800 8850 1800 8550 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 1875 8400 1800 8400 1800 9000 1875 9000 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 2775 8400 2700 8400 2700 9000 2775 9000 +-6 +6 3225 8325 4050 9075 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 3975 8400 3900 8400 3900 9000 3975 9000 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 3300 8550 3900 8550 3900 8850 3300 8850 3300 8550 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 3375 8400 3300 8400 3300 9000 3375 9000 +-6 +6 6000 4200 6450 4800 +6 6000 4500 6450 4800 +2 2 0 1 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 6000 4500 6450 4500 6450 4800 6000 4800 6000 4500 +4 0 7 40 -1 14 14 0.0000 4 135 300 6075 4725 LB\001 +-6 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6000 4200 6000 4800 +-6 +6 6000 6600 6450 7200 +6 6000 6900 6450 7200 +2 2 0 1 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 6000 6900 6450 6900 6450 7200 6000 7200 6000 6900 +4 0 7 40 -1 14 14 0.0000 4 135 300 6075 7125 LB\001 +-6 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6000 6600 6000 7200 +-6 +6 9000 9000 9450 9600 +6 9000 9300 9450 9600 +2 2 0 1 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 9000 9300 9450 9300 9450 9600 9000 9600 9000 9300 +4 0 7 40 -1 14 14 0.0000 4 135 300 9075 9525 LB\001 +-6 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9000 9000 9000 9600 +-6 +6 9000 11400 9450 12000 +6 9000 11700 9450 12000 +2 2 0 1 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 9000 11700 9450 11700 9450 12000 9000 12000 9000 11700 +4 0 7 40 -1 14 14 0.0000 4 135 300 9075 11925 LB\001 +-6 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9000 11400 9000 12000 +-6 +6 3600 1200 4050 1800 +6 3600 1500 4050 1800 +2 2 0 1 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 3600 1500 4050 1500 4050 1800 3600 1800 3600 1500 +4 0 7 40 -1 14 14 0.0000 4 135 300 3675 1725 LB\001 +-6 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3600 1200 3600 1800 +-6 +6 8925 525 9150 1275 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9000 600 9000 1200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9075 600 9075 1200 +-6 +6 5925 525 6750 1275 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 6675 600 6600 600 6600 1200 6675 1200 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 6000 750 6600 750 6600 1050 6000 1050 6000 750 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 6075 600 6000 600 6000 1200 6075 1200 +-6 +6 8925 3525 9150 4275 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9000 3600 9000 4200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9075 3600 9075 4200 +-6 +6 5925 3525 6750 4275 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 6675 3600 6600 3600 6600 4200 6675 4200 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 6000 3750 6600 3750 6600 4050 6000 4050 6000 3750 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 6075 3600 6000 3600 6000 4200 6075 4200 +-6 +6 8925 5925 9150 6675 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9000 6000 9000 6600 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9075 6000 9075 6600 +-6 +6 4125 6300 6000 7200 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 4200 7200 4200 6300 +4 0 0 50 -1 14 12 0.0000 4 120 1680 4275 7200 OutsideElement\001 +4 0 0 50 -1 12 14 0.0000 4 135 450 4275 6975 Pos\001 +-6 +6 3300 5400 5475 6000 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3300 5400 3300 6000 +4 0 4 50 -1 12 14 0.0000 4 195 1050 3375 5550 begin:0\001 +4 0 4 50 -1 14 12 0.0000 4 165 2040 3375 5775 BeginIsSegmentMax\001 +-6 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 2400 2400 2400 900 +2 1 0 4 4 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1500 10800 1500 11400 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1200 11100 9300 11100 +2 1 0 4 4 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1425 10800 1425 11400 +2 1 0 4 1 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 9000 10800 9000 11400 +2 1 0 4 1 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 9075 10800 9075 11400 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 6900 12000 6900 11100 +2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9000 10200 9000 10800 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1500 10200 1500 10800 +2 1 0 4 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1500 8400 1500 9000 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1200 8700 9300 8700 +2 1 0 4 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1425 8400 1425 9000 +2 1 0 4 4 7 51 -1 -1 0.000 0 0 -1 0 0 4 + 5775 8400 5700 8400 5700 9000 5775 9000 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 4800 8550 5700 8550 5700 8850 4800 8850 4800 8550 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 4875 8400 4800 8400 4800 9000 4875 9000 +2 1 0 4 1 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 9000 8400 9000 9000 +2 1 0 4 1 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 9075 8400 9075 9000 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 6900 9600 6900 8700 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5700 7800 5700 8400 +2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9000 7800 9000 8400 +2 1 0 4 4 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1425 600 1425 1200 +2 1 0 4 4 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1500 600 1500 1200 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1500 0 1500 600 +2 1 0 4 1 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 3675 600 3600 600 3600 1200 3675 1200 +2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3600 0 3600 600 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1200 900 9300 900 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 8475 600 8400 600 8400 1200 8475 1200 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 7500 750 8400 750 8400 1050 7500 1050 7500 750 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 7575 600 7500 600 7500 1200 7575 1200 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 3600 750 4500 750 4500 1050 3600 1050 3600 750 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 4575 600 4500 600 4500 1200 4575 1200 +2 1 0 4 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1500 3600 1500 4200 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1200 3900 9300 3900 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 8475 3600 8400 3600 8400 4200 8475 4200 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 7500 3750 8400 3750 8400 4050 7500 4050 7500 3750 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 7575 3600 7500 3600 7500 4200 7575 4200 +2 1 0 4 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1425 3600 1425 4200 +2 1 0 4 4 7 51 -1 -1 0.000 0 0 -1 0 0 4 + 2475 3600 2400 3600 2400 4200 2475 4200 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 0 0 1.00 60.00 120.00 + 3000 4800 3000 3900 +2 1 0 4 1 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 5175 3600 5100 3600 5100 4200 5175 4200 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 2400 3750 5100 3750 5100 4050 2400 4050 2400 3750 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2400 3000 2400 3600 +2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5100 3000 5100 3600 +2 1 0 4 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1500 6000 1500 6600 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1200 6300 9300 6300 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 8475 6000 8400 6000 8400 6600 8475 6600 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 7500 6150 8400 6150 8400 6450 7500 6450 7500 6150 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 7575 6000 7500 6000 7500 6600 7575 6600 +2 1 0 4 0 7 51 -1 -1 0.000 0 0 -1 0 0 2 + 1425 6000 1425 6600 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 6675 6000 6600 6000 6600 6600 6675 6600 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 6000 6150 6600 6150 6600 6450 6000 6450 6000 6150 +2 1 0 4 1 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 6075 6000 6000 6000 6000 6600 6075 6600 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 2400 6150 3300 6150 3300 6450 2400 6450 2400 6150 +2 1 0 4 4 7 51 -1 -1 0.000 0 0 -1 0 0 4 + 3375 6000 3300 6000 3300 6600 3375 6600 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 2475 6000 2400 6000 2400 6600 2475 6600 +2 1 0 1 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6000 5400 6000 6000 +2 2 0 0 0 32 100 -1 20 0.000 0 0 -1 0 0 5 + 900 -300 10800 -300 10800 12300 900 12300 900 -300 +4 0 0 50 -1 14 12 0.0000 4 120 2160 2475 2400 BeforeFirstElement\001 +4 0 0 50 -1 12 14 0.0000 4 135 450 2475 2175 Pos\001 +4 0 0 50 -1 14 12 0.0000 4 165 1200 6975 12000 EmptyTrack\001 +4 0 0 50 -1 12 14 0.0000 4 135 450 6975 11775 Pos\001 +4 0 1 50 -1 14 12 0.0000 4 120 1560 9075 10575 EndIsTrackMax\001 +4 0 4 50 -1 12 14 0.0000 4 195 1050 1575 10350 begin:0\001 +4 0 4 50 -1 14 12 0.0000 4 165 1800 1575 10575 BeginIsTrackMin\001 +4 0 0 50 -1 14 12 0.0000 4 120 1920 6975 9600 AfterLastElement\001 +4 0 0 50 -1 12 14 0.0000 4 135 450 6975 9375 Pos\001 +4 0 4 50 -1 12 14 0.0000 4 195 1050 5775 7950 begin:2\001 +4 0 4 50 -1 14 12 0.0000 4 165 2040 5775 8175 BeginIsSegmentMax\001 +4 0 1 50 -1 14 12 0.0000 4 120 1560 9075 8175 EndIsTrackMax\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 4050 825 [0]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 6300 825 [1]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 7950 825 [2]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 3750 3825 [0]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 2850 6225 [0]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 6300 3825 [1]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 6300 6225 [1]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 7950 3825 [2]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 7950 6225 [2]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 2250 8625 [0]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 5250 8625 [2]\001 +4 1 0 40 -1 14 14 0.0000 4 180 450 3600 8625 [1]\001 +4 0 4 50 -1 12 14 0.0000 4 195 1050 1575 150 begin:0\001 +4 0 4 50 -1 14 12 0.0000 4 165 1800 1575 375 BeginIsTrackMin\001 +4 0 1 50 -1 14 12 0.0000 4 165 1800 3675 375 EndIsSegmentMin\001 +4 0 0 50 -1 14 12 0.0000 4 120 1560 3075 4800 InsideElement\001 +4 0 0 50 -1 12 14 0.0000 4 135 450 3075 4575 Pos\001 +4 0 4 50 -1 12 14 0.0000 4 195 1050 2475 3150 begin:0\001 +4 0 4 50 -1 14 12 0.0000 4 165 2040 2475 3375 BeginIsSegmentMin\001 +4 0 1 50 -1 14 12 0.0000 4 165 1800 5175 3375 EndIsSegmentMax\001 +4 0 1 50 -1 14 12 0.0000 4 165 2280 6075 5775 EndIsNextSegmentMin\001 diff --git a/kite/doc/images/TrackOccupiedInterval-1.fig b/kite/doc/images/TrackOccupiedInterval-1.fig new file mode 100644 index 00000000..8235ff18 --- /dev/null +++ b/kite/doc/images/TrackOccupiedInterval-1.fig @@ -0,0 +1,69 @@ +#FIG 3.2 Produced by xfig version 3.2.5a +Landscape +Center +Inches +Letter +90.00 +Single +-2 +1200 2 +0 32 #ffffdd +6 1350 6525 1575 7275 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1425 6600 1425 7200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1500 6600 1500 7200 +-6 +6 8925 6525 9150 7275 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9000 6600 9000 7200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 9075 6600 9075 7200 +-6 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 1875 6600 1800 6600 1800 7200 1875 7200 +2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 2475 6600 2400 6600 2400 7200 2475 7200 +2 2 0 0 0 7 60 -1 10 0.000 0 0 -1 0 0 5 + 1800 6750 2400 6750 2400 7050 1800 7050 1800 6750 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 4 + 3375 6600 3300 6600 3300 7200 3375 7200 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 4 + 4575 6600 4500 6600 4500 7200 4575 7200 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 4 + 7875 6600 7800 6600 7800 7200 7875 7200 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 4 + 6675 6600 6600 6600 6600 7200 6675 7200 +2 1 0 4 4 7 55 -1 -1 0.000 0 0 -1 0 0 4 + 5775 6600 5700 6600 5700 7200 5775 7200 +2 2 0 0 4 4 62 -1 30 0.000 0 0 -1 0 0 5 + 5700 6975 7800 6975 7800 7050 5700 7050 5700 6975 +2 2 0 0 4 4 62 -1 30 0.000 0 0 -1 0 0 5 + 3300 6750 6600 6750 6600 6825 3300 6825 3300 6750 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1200 6900 9300 6900 +2 2 0 0 4 4 62 -1 30 0.000 0 0 -1 0 0 5 + 3300 6975 4500 6975 4500 7050 3300 7050 3300 6975 +2 1 0 1 4 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5700 6000 5700 6600 +2 1 0 1 4 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3300 6000 3300 6600 +2 1 0 1 4 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 3300 7275 3300 7800 +2 1 0 1 4 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 7800 7275 7800 7800 +2 1 0 1 4 7 40 -1 -1 0.000 0 0 -1 1 1 2 + 0 0 1.00 60.00 120.00 + 0 0 1.00 60.00 120.00 + 3300 7725 7800 7725 +2 2 0 0 0 32 100 -1 20 0.000 0 0 -1 0 0 5 + 900 5700 9600 5700 9600 8400 900 8400 900 5700 +4 1 0 40 -1 14 14 0.0000 4 180 450 2100 6825 [0]\001 +4 1 4 40 -1 14 14 0.0000 4 180 450 3900 6750 [1]\001 +4 1 4 40 -1 14 14 0.0000 4 180 450 3900 7125 [2]\001 +4 1 4 40 -1 14 14 0.0000 4 180 450 6150 7125 [3]\001 +4 0 4 40 -1 14 14 0.0000 4 195 1050 3375 6150 begin:1\001 +4 0 4 40 -1 14 14 0.0000 4 195 1050 5775 6150 begin:3\001 +4 1 4 40 -1 14 14 0.0000 4 150 2550 5550 7950 returned interval\001 +4 0 4 40 -1 12 14 0.0000 4 180 1200 3300 6375 (return)\001 +4 0 4 40 -1 12 14 0.0000 4 180 900 5700 6375 (call)\001 diff --git a/kite/doc/images/TrackOccupiedInterval-1.png b/kite/doc/images/TrackOccupiedInterval-1.png new file mode 100644 index 0000000000000000000000000000000000000000..98715f57345de61434509e40665d93d46f447c56 GIT binary patch literal 3988 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 Ga{mUc;_Ybw literal 0 HcmV?d00001 diff --git a/kite/doc/images/TrackSegment-10.fig b/kite/doc/images/TrackSegment-10.fig new file mode 100644 index 00000000..428ed315 --- /dev/null +++ b/kite/doc/images/TrackSegment-10.fig @@ -0,0 +1,93 @@ +#FIG 3.2 Produced by xfig version 3.2.5a +Landscape +Center +Inches +Letter +90.00 +Single +-2 +1200 2 +0 32 #ffffdd +1 4 0 2 4 7 50 -1 -1 0.000 1 0.0000 3975 2400 75 75 3900 2400 4050 2400 +1 4 0 2 4 7 50 -1 -1 0.000 1 0.0000 3975 3300 75 75 3900 3300 4050 3300 +1 4 0 2 4 7 50 -1 -1 0.000 1 0.0000 3975 3600 75 75 3900 3600 4050 3600 +1 4 0 2 0 7 50 -1 -1 0.000 1 0.0000 3000 750 75 75 2925 750 3075 750 +1 4 0 2 4 7 50 -1 -1 0.000 1 0.0000 2400 750 75 75 2325 750 2475 750 +1 4 0 2 0 7 50 -1 -1 0.000 1 0.0000 1800 750 75 75 1725 750 1875 750 +1 4 0 2 4 7 50 -1 -1 0.000 1 0.0000 7125 5550 75 75 7050 5550 7200 5550 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3000 2550 5100 2550 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3000 2850 5100 2850 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3000 3150 5100 3150 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3000 3450 5100 3450 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 5100 1950 5100 3750 3000 3750 3000 1950 5100 1950 +2 2 0 2 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 3000 1950 5100 1950 5100 2250 3000 2250 3000 1950 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6150 3750 8250 3750 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 8250 3150 8250 4350 6150 4350 6150 3150 8250 3150 +2 2 0 2 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 6150 3150 8250 3150 8250 3450 6150 3450 6150 3150 +2 2 0 2 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 9000 5400 11100 5400 11100 5700 9000 5700 9000 5400 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 11100 5400 11100 6000 9000 6000 9000 5400 11100 5400 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 0 4 + 1 1 1.00 60.00 120.00 + 2400 825 2400 1950 2550 2100 3000 2100 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2100 600 2100 900 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2700 600 2700 900 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3300 600 3300 900 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3900 600 3900 900 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 4500 600 4500 900 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5100 600 5100 900 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5700 600 5700 900 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 1500 600 6300 600 6300 900 1500 900 1500 600 +2 2 0 2 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 1500 300 2700 300 2700 600 1500 600 1500 300 +2 2 0 2 0 7 50 -1 0 0.000 0 0 -1 0 0 5 + 6150 4800 8250 4800 8250 5100 6150 5100 6150 4800 +2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6150 5400 8250 5400 +2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 + 8250 4800 8250 5700 6150 5700 6150 4800 8250 4800 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 0 8 + 1 1 1.00 60.00 120.00 + 4050 2400 6750 2400 6900 2250 6900 -150 6750 -300 2250 -300 + 2100 -150 2100 300 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 4050 3300 6150 3300 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 0 6 + 1 1 1.00 60.00 120.00 + 4050 3600 5250 3600 5400 3750 5400 4800 5550 4950 6150 4950 +2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 7200 5550 9000 5550 +2 2 0 0 0 32 100 -1 20 0.000 0 0 -1 0 0 5 + 1200 -450 11400 -450 11400 6150 1200 6150 1200 -450 +4 0 0 50 -1 14 14 0.0000 4 150 900 3075 2775 net\001 +4 0 0 50 -1 14 14 0.0000 4 195 900 3075 3075 [8,10[\001 +4 0 7 40 -1 14 14 0.0000 4 195 1800 3075 2175 TrackSegment\001 +4 0 7 40 -1 14 14 0.0000 4 180 1650 6225 3375 AutoSegment\001 +4 0 0 50 -1 14 14 0.0000 4 150 900 6225 3675 net\001 +4 0 0 50 -1 14 16 0.0000 4 225 990 6225 3975 _flags\001 +4 0 0 50 -1 14 12 0.0000 4 165 1440 6450 4200 SegCanonical\001 +4 0 7 40 -1 14 14 0.0000 4 195 1800 9075 5625 RoutingEvent\001 +4 0 0 50 -1 14 14 0.0000 4 150 900 9075 5925 net\001 +4 1 7 40 -1 14 16 0.0000 4 165 825 2100 525 Track\001 +4 0 7 40 -1 14 14 0.0000 4 195 1950 6225 5025 DataNegociate\001 +4 0 0 50 -1 14 14 0.0000 4 150 900 6225 5325 net\001 diff --git a/kite/doc/images/TrackSegment-10.png b/kite/doc/images/TrackSegment-10.png new file mode 100644 index 0000000000000000000000000000000000000000..352837ca36c18e444623feabc4f2d82133bb2ef3 GIT binary patch literal 10096 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 literal 0 HcmV?d00001 diff --git a/kite/doc/images/TrackSegmentCost-1.fig b/kite/doc/images/TrackSegmentCost-1.fig deleted file mode 100644 index 9c50d7ff..00000000 --- a/kite/doc/images/TrackSegmentCost-1.fig +++ /dev/null @@ -1,57 +0,0 @@ -#FIG 3.2 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -2 2 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 5 - 3825 2625 3975 2625 3975 2775 3825 2775 3825 2625 -2 1 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 2 - 3900 2700 11400 2700 -2 2 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 5 - 5025 2625 5175 2625 5175 2775 5025 2775 5025 2625 -2 2 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 5 - 11325 2625 11475 2625 11475 2775 11325 2775 11325 2625 -2 2 0 1 0 7 60 -1 -1 4.000 0 0 -1 0 0 5 - 3600 2100 6300 2100 6300 3000 3600 3000 3600 2100 -2 2 0 1 0 7 60 -1 -1 4.000 0 0 -1 0 0 5 - 3000 1200 4800 1200 4800 3600 3000 3600 3000 1200 -2 2 0 1 0 7 60 -1 -1 4.000 0 0 -1 0 0 5 - 10800 2100 12000 2100 12000 3600 10800 3600 10800 2100 -2 1 0 4 0 7 60 -1 -1 10.000 0 0 -1 0 0 2 - 4800 3675 4800 4500 -2 1 0 4 0 7 60 -1 -1 10.000 0 0 -1 0 0 2 - 6300 3075 6300 4500 -2 1 0 4 0 7 60 -1 -1 10.000 0 0 -1 0 0 2 - 10800 3675 10800 4500 -2 1 0 1 4 7 50 -1 -1 0.000 0 0 7 1 0 2 - 3 1 4.00 60.00 120.00 - 12900 4800 10800 4800 -2 1 0 1 4 7 50 -1 -1 4.000 0 0 7 0 0 2 - 4800 4800 10800 4800 -2 1 0 1 4 7 50 -1 -1 4.000 0 0 7 0 0 2 - 4800 4500 4800 5100 -2 1 0 1 4 7 50 -1 -1 4.000 0 0 7 0 0 2 - 10800 4500 10800 5100 -2 1 0 1 4 7 50 -1 -1 0.000 0 0 7 1 0 2 - 3 1 4.00 60.00 120.00 - 2700 4800 4800 4800 -2 2 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 5 - 2100 600 13500 600 13500 5400 2100 5400 2100 600 -3 0 0 1 0 7 60 -1 -1 0.000 0 0 0 3 - 3900 2700 3375 2025 3000 1200 - 0.000 1.000 0.000 -3 0 0 1 0 7 60 -1 -1 4.000 0 0 0 3 - 5025 2700 4350 2550 3600 2100 - 0.000 1.000 0.000 -3 0 0 1 0 7 60 -1 -1 4.000 0 0 0 3 - 11400 2700 11025 2475 10800 2100 - 0.000 1.000 0.000 -4 0 0 50 -1 14 12 1.5708 4 120 630 4725 4500 CBXMax\001 -4 0 0 50 -1 14 12 1.5708 4 120 630 6225 4500 CBXMax\001 -4 0 0 50 -1 14 12 1.5708 4 135 630 10725 4500 CBXmin\001 -4 2 4 50 -1 14 18 0.0000 4 180 1485 4500 5100 leftBound\001 -4 0 4 50 -1 14 18 0.0000 4 240 1650 11100 5100 rightBound\001 diff --git a/kite/doc/images/TrackSegmentCost-2.fig b/kite/doc/images/TrackSegmentCost-2.fig deleted file mode 100644 index ade66dcf..00000000 --- a/kite/doc/images/TrackSegmentCost-2.fig +++ /dev/null @@ -1,51 +0,0 @@ -#FIG 3.2 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -2 2 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 5 - 3825 2625 3975 2625 3975 2775 3825 2775 3825 2625 -2 1 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 2 - 3900 2700 11400 2700 -2 2 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 5 - 5025 2625 5175 2625 5175 2775 5025 2775 5025 2625 -2 2 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 5 - 11325 2625 11475 2625 11475 2775 11325 2775 11325 2625 -2 1 0 1 4 7 50 -1 -1 0.000 0 0 7 1 0 2 - 3 1 4.00 60.00 120.00 - 12900 4800 10800 4800 -2 1 0 1 4 7 50 -1 -1 4.000 0 0 7 0 0 2 - 4800 4800 10800 4800 -2 1 0 1 4 7 50 -1 -1 4.000 0 0 7 0 0 2 - 4800 4500 4800 5100 -2 1 0 1 4 7 50 -1 -1 4.000 0 0 7 0 0 2 - 10800 4500 10800 5100 -2 1 0 1 4 7 50 -1 -1 0.000 0 0 7 1 0 2 - 3 1 4.00 60.00 120.00 - 2700 4800 4800 4800 -2 1 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 2 - 4800 3900 10800 3900 -2 2 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 5 - 10725 3825 10875 3825 10875 3975 10725 3975 10725 3825 -2 2 0 4 0 7 50 -1 -1 10.000 0 0 7 0 0 5 - 4725 3825 4875 3825 4875 3975 4725 3975 4725 3825 -2 2 0 4 0 7 60 -1 -1 10.000 0 0 -1 0 0 5 - 4650 3750 4950 3750 4950 4050 4650 4050 4650 3750 -2 1 3 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 2 - 3900 2700 4800 3900 -2 1 3 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 2 - 5100 2700 4800 3900 -2 1 3 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 2 - 11400 2700 10800 3900 -2 1 0 2 0 7 60 -1 -1 6.000 0 0 -1 1 0 2 - 3 1 2.00 120.00 240.00 - 3300 2100 3300 4500 -2 2 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 5 - 2100 1500 13500 1500 13500 5400 2100 5400 2100 1500 -4 2 4 50 -1 14 18 0.0000 4 180 1485 4500 5100 leftBound\001 -4 0 4 50 -1 14 18 0.0000 4 240 1650 11100 5100 rightBound\001 -4 1 0 60 -1 14 14 1.5708 4 150 1890 3225 3150 maximal shrunk\001 diff --git a/kite/doc/images/TrackSegmentCost-3.fig b/kite/doc/images/TrackSegmentCost-3.fig deleted file mode 100644 index 02549997..00000000 --- a/kite/doc/images/TrackSegmentCost-3.fig +++ /dev/null @@ -1,105 +0,0 @@ -#FIG 3.2 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -2 2 0 4 0 7 50 -1 -1 10.000 0 0 -1 0 0 5 - 3525 3225 3675 3225 3675 3375 3525 3375 3525 3225 -2 2 0 4 0 7 50 -1 -1 10.000 0 0 -1 0 0 5 - 5025 3225 5175 3225 5175 3375 5025 3375 5025 3225 -2 2 0 4 0 7 50 -1 -1 10.000 0 0 -1 0 0 5 - 9825 3225 9975 3225 9975 3375 9825 3375 9825 3225 -2 1 0 4 0 7 50 -1 -1 10.000 0 0 -1 0 0 2 - 3600 3300 9900 3300 -2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2 - 3600 3300 3600 600 -2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2 - 5100 4500 5100 1500 -2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2 - 9900 5100 9900 3300 -2 2 0 4 0 7 50 -1 -1 10.000 0 0 -1 0 0 5 - 7125 3225 7275 3225 7275 3375 7125 3375 7125 3225 -2 2 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 5 - 7050 3000 7350 3000 7350 3600 7050 3600 7050 3000 -2 2 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 5 - 3525 525 3675 525 3675 675 3525 675 3525 525 -2 2 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 5 - 5025 1425 5175 1425 5175 1575 5025 1575 5025 1425 -2 2 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 5 - 5025 4425 5175 4425 5175 4575 5025 4575 5025 4425 -2 2 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 5 - 3525 2025 3675 2025 3675 2175 3525 2175 3525 2025 -2 2 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 5 - 9825 5025 9975 5025 9975 5175 9825 5175 9825 5025 -2 1 0 1 4 7 60 -1 -1 4.000 0 0 -1 0 0 2 - 3750 600 11700 600 -2 1 0 1 4 7 60 -1 -1 4.000 0 0 -1 0 0 2 - 5250 1500 11700 1500 -2 1 0 1 4 7 60 -1 -1 4.000 0 0 -1 0 0 2 - 10050 3300 11700 3300 -2 1 0 1 4 7 60 -1 -1 4.000 0 0 -1 0 0 2 - 10050 5100 11700 5100 -2 1 0 1 0 7 60 -1 -1 4.000 0 0 -1 0 0 2 - 3600 3450 3600 6000 -2 1 0 1 0 7 60 -1 -1 4.000 0 0 -1 0 0 2 - 5100 4650 5100 6000 -2 1 0 1 0 7 60 -1 -1 4.000 0 0 -1 0 0 2 - 7200 3675 7200 6000 -2 1 0 1 0 7 60 -1 -1 4.000 0 0 -1 0 0 2 - 9900 5250 9900 6000 -2 1 0 1 4 7 60 -1 -1 4.000 0 0 -1 0 0 2 - 5250 4500 11700 4500 -2 1 0 1 0 7 60 -1 -1 0.000 0 0 -1 1 0 2 - 1 0 1.00 120.00 240.00 - 2700 5700 10500 5700 -2 1 0 1 4 7 60 -1 -1 0.000 0 0 -1 1 0 2 - 1 0 1.00 120.00 240.00 - 3000 6000 3000 0 -2 1 0 4 4 7 60 -1 -1 0.000 0 0 -1 0 0 2 - 2925 4500 3075 4500 -2 1 0 4 4 7 60 -1 -1 0.000 0 0 -1 0 0 2 - 2925 5100 3075 5100 -2 1 0 4 4 7 60 -1 -1 0.000 0 0 -1 0 0 2 - 2925 2100 3075 2100 -2 1 0 4 4 7 60 -1 -1 0.000 0 0 -1 0 0 2 - 2925 3300 3075 3300 -2 1 0 4 4 7 60 -1 -1 0.000 0 0 -1 0 0 2 - 2925 600 3075 600 -2 1 0 4 0 7 60 -1 -1 0.000 0 0 -1 0 0 2 - 3600 5625 3600 5775 -2 1 0 4 0 7 60 -1 -1 0.000 0 0 -1 0 0 2 - 5100 5625 5100 5775 -2 1 0 4 0 7 60 -1 -1 0.000 0 0 -1 0 0 2 - 9900 5625 9900 5775 -2 1 0 4 0 7 60 -1 -1 0.000 0 0 -1 0 0 2 - 7200 5625 7200 5775 -2 1 0 4 4 7 60 -1 -1 0.000 0 0 -1 0 0 2 - 2925 1500 3075 1500 -2 2 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 5 - 2100 -600 12300 -600 12300 6600 2100 6600 2100 -600 -4 0 4 60 -1 18 14 0.0000 4 210 1260 10200 1425 right @7: 16\001 -4 0 4 60 -1 18 14 0.0000 4 210 1260 10200 525 right @2: 19\001 -4 0 4 60 -1 18 14 0.0000 4 210 1800 10200 3225 punctual @14: 10\001 -4 0 4 60 -1 18 14 0.0000 4 180 1080 10200 5025 left @23: 4\001 -4 0 4 60 -1 18 14 0.0000 4 180 960 10200 4425 left @7: 6\001 -4 1 4 60 -1 18 14 0.0000 4 165 150 3450 1725 A\001 -4 1 4 60 -1 18 14 0.0000 4 165 150 3750 2775 B\001 -4 1 4 60 -1 18 14 0.0000 4 165 165 5250 2475 C\001 -4 1 4 60 -1 18 14 0.0000 4 165 165 7500 3600 D\001 -4 1 4 60 -1 18 14 0.0000 4 165 135 9750 4200 E\001 -4 1 0 60 -1 18 14 0.0000 4 150 120 3600 6300 2\001 -4 1 0 60 -1 18 14 0.0000 4 150 120 5100 6300 7\001 -4 1 0 60 -1 18 14 0.0000 4 150 240 7200 6300 14\001 -4 1 0 60 -1 18 14 0.0000 4 150 240 9900 6300 23\001 -4 2 4 60 -1 18 14 0.0000 4 150 120 2850 5100 4\001 -4 2 4 60 -1 18 14 0.0000 4 150 120 2850 4500 6\001 -4 2 4 60 -1 18 14 0.0000 4 150 240 2850 3300 10\001 -4 2 4 60 -1 18 14 0.0000 4 150 240 2850 2100 14\001 -4 2 4 60 -1 18 14 0.0000 4 150 240 2850 600 19\001 -4 1 4 60 -1 14 14 0.0000 4 135 135 3000 -75 Y\001 -4 1 0 60 -1 14 14 0.0000 4 135 135 10650 5775 X\001 -4 2 4 60 -1 18 14 0.0000 4 150 240 2850 1500 16\001 diff --git a/kite/doc/images/_makeDogleg-10.fig b/kite/doc/images/_makeDogleg-10.fig new file mode 100644 index 00000000..3b0b0512 --- /dev/null +++ b/kite/doc/images/_makeDogleg-10.fig @@ -0,0 +1,271 @@ +#FIG 3.2 Produced by xfig version 3.2.5a +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +0 32 #ffffdd +6 450 3000 750 4350 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 3225 675 3075 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 3300 675 3150 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 3375 675 3225 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 3450 675 3300 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 3525 675 3375 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 3600 675 3450 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 3675 675 3525 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 3750 675 3600 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 3825 675 3675 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 3900 675 3750 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 3975 675 3825 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 4050 675 3900 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 4125 675 3975 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 4200 675 4050 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 4275 675 4125 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 3150 600 3075 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 600 4275 675 4200 +2 2 0 2 1 32 50 -1 -1 6.000 0 0 -1 0 0 5 + 525 3075 675 3075 675 4275 525 4275 525 3075 +-6 +6 1425 3075 1875 3375 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1500 3300 1800 3300 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1650 3150 1650 3300 +-6 +6 2325 3225 2775 3525 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2400 3300 2700 3300 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2550 3450 2550 3300 +-6 +6 450 900 750 2250 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 1125 675 975 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 1200 675 1050 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 1275 675 1125 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 1350 675 1200 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 1425 675 1275 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 1500 675 1350 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 1575 675 1425 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 1650 675 1500 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 1725 675 1575 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 1800 675 1650 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 1875 675 1725 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 1950 675 1800 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 2025 675 1875 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 2100 675 1950 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 2175 675 2025 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 525 1050 600 975 +2 1 0 1 1 32 50 -1 -1 4.000 0 0 -1 0 0 2 + 600 2175 675 2100 +2 2 0 2 1 32 50 -1 -1 6.000 0 0 -1 0 0 5 + 525 975 675 975 675 2175 525 2175 525 975 +-6 +6 1425 975 1875 1275 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1500 1200 1800 1200 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 1650 1050 1650 1200 +-6 +6 2325 1125 2775 1425 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2400 1200 2700 1200 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 2550 1350 2550 1200 +-6 +6 -825 6450 7425 7575 +2 1 0 2 0 32 40 -1 -1 0.000 0 0 -1 0 0 2 + -750 6525 -150 6525 +2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + -750 6825 -150 6825 +2 1 0 2 4 32 40 -1 -1 0.000 0 0 -1 0 0 2 + -750 7125 -150 7125 +2 2 0 0 0 0 60 -1 4 2.000 0 0 -1 0 0 5 + -750 7350 -150 7350 -150 7425 -750 7425 -750 7350 +4 0 0 60 -1 18 12 0.0000 4 195 2115 0 6600 parallel AutoSegments\001 +4 0 0 60 -1 18 12 0.0000 4 195 2715 0 6900 perpandicular AutoSegments\001 +4 0 0 60 -1 18 12 0.0000 4 195 2700 0 7200 newly created AutoSegments\001 +4 0 0 60 -1 18 12 0.0000 4 195 1440 0 7500 TrackSegments\001 +4 0 0 60 -1 14 12 0.0000 4 165 2880 4050 6600 dogleg[N+0] = 10 (paral)\001 +4 0 0 60 -1 14 12 0.0000 4 165 3120 4050 6900 dogleg[N+1] = 20 (perpand)\001 +4 0 0 60 -1 14 12 0.0000 4 165 3360 4050 7200 dogleg[N+2] = 21 (new paral)\001 +-6 +2 2 0 4 0 32 40 -1 -1 10.000 0 0 -1 0 0 5 + 525 3225 675 3225 675 3375 525 3375 525 3225 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 1050 3300 1050 3000 1350 3000 1350 3300 +2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1650 3300 1650 2550 +2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2550 3300 2550 4050 +2 1 0 2 0 32 40 -1 -1 0.000 0 0 -1 0 0 2 + 1650 3300 2550 3300 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 1950 3300 1950 3000 2250 3000 2250 3300 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 2925 3300 2925 3000 3225 3000 3225 3300 +2 1 0 2 0 32 40 -1 -1 0.000 0 0 -1 0 0 2 + 2625 3300 3450 3300 +2 1 3 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 + 0 0 1.00 60.00 120.00 + 0 0 1.00 60.00 120.00 + 3450 5550 450 5550 +2 1 3 1 0 7 50 -1 -1 4.000 0 0 -1 1 1 2 + 0 0 1.00 60.00 120.00 + 0 0 1.00 60.00 120.00 + 6150 5550 3450 5550 +2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 3450 3300 3450 4800 +2 1 0 4 4 32 40 -1 -1 0.000 0 0 -1 0 0 3 + 3300 3300 3450 3300 3450 3450 +2 1 0 2 4 32 40 -1 -1 0.000 0 0 -1 0 0 2 + 3450 4800 4350 4800 +2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 4350 4800 4350 4050 +2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5250 4800 5250 4050 +2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6150 4800 6150 5550 +2 1 0 4 0 32 40 -1 -1 0.000 0 0 -1 0 0 3 + 6000 4800 6150 4800 6150 4950 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4200 4800 4500 4800 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4350 4650 4350 4800 +2 1 0 2 0 32 40 -1 -1 0.000 0 0 -1 0 0 2 + 4350 4800 5250 4800 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 4650 4800 4650 4500 4950 4500 4950 4800 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5100 4800 5400 4800 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5250 4650 5250 4800 +2 1 0 2 0 32 40 -1 -1 0.000 0 0 -1 0 0 2 + 5250 4800 6150 4800 +2 1 0 4 4 32 40 -1 -1 0.000 0 0 -1 0 0 3 + 3600 4800 3450 4800 3450 4650 +2 1 0 1 4 7 50 -1 -1 4.000 0 0 -1 0 0 4 + 3450 4200 3150 4200 3150 3900 3450 3900 +2 1 0 2 0 32 40 -1 -1 0.000 0 0 -1 0 0 2 + 675 3300 1650 3300 +2 1 0 1 4 7 50 -1 -1 4.000 0 0 -1 0 0 4 + 3750 4800 3750 4500 4050 4500 4050 4800 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 5550 4800 5550 4500 5850 4500 5850 4800 +2 2 0 4 0 32 40 -1 -1 10.000 0 0 -1 0 0 5 + 525 1125 675 1125 675 1275 525 1275 525 1125 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 1050 1200 1050 900 1350 900 1350 1200 +2 1 0 2 0 32 40 -1 -1 0.000 0 0 -1 0 0 2 + 3450 1200 4350 1200 +2 1 0 2 0 32 40 -1 -1 0.000 0 0 -1 0 0 2 + 2550 1200 3450 1200 +2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 1650 1200 1650 450 +2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 2550 1200 2550 1950 +2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 4350 1200 4350 450 +2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 5250 1200 5250 450 +2 1 0 2 1 7 50 -1 -1 0.000 0 0 -1 0 0 2 + 6150 1200 6150 1950 +2 1 0 2 0 32 40 -1 -1 0.000 0 0 -1 0 0 2 + 675 1200 1650 1200 +2 1 0 2 0 32 40 -1 -1 0.000 0 0 -1 0 0 2 + 1650 1200 2550 1200 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 1950 1200 1950 900 2250 900 2250 1200 +2 1 0 4 0 32 40 -1 -1 0.000 0 0 -1 0 0 3 + 6000 1200 6150 1200 6150 1350 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4200 1200 4500 1200 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 4350 1050 4350 1200 +2 1 0 2 0 32 40 -1 -1 0.000 0 0 -1 0 0 2 + 4350 1200 5250 1200 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 4650 1200 4650 900 4950 900 4950 1200 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5100 1200 5400 1200 +2 1 0 4 0 7 40 -1 -1 0.000 0 0 -1 0 0 2 + 5250 1050 5250 1200 +2 1 0 2 0 32 40 -1 -1 0.000 0 0 -1 0 0 2 + 5250 1200 6150 1200 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 5550 1200 5550 900 5850 900 5850 1200 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4 + 3300 1200 3300 900 3600 900 3600 1200 +2 1 3 1 4 7 50 -1 -1 4.000 0 0 -1 0 0 2 + 3450 2700 3450 5700 +2 2 0 0 4 4 60 -1 35 2.000 0 0 -1 0 0 5 + 3600 3300 3675 3300 3675 4800 3600 4800 3600 3300 +2 2 0 0 0 0 60 -1 4 2.000 0 0 -1 0 0 5 + 3450 5025 6150 5025 6150 5100 3450 5100 3450 5025 +2 1 0 1 0 0 60 -1 -1 4.000 0 0 -1 0 0 2 + 2925 3300 2925 3525 +2 1 0 1 0 0 60 -1 -1 4.000 0 0 -1 0 0 2 + 5550 4800 5550 5100 +2 1 0 1 4 0 60 -1 -1 4.000 0 0 -1 0 0 2 + 3450 4200 3675 4200 +2 2 0 0 0 0 60 -1 4 2.000 0 0 -1 0 0 5 + 600 1500 6150 1500 6150 1425 600 1425 600 1500 +2 1 0 1 0 0 60 -1 -1 4.000 0 0 -1 0 0 2 + 5550 1200 5550 1500 +2 2 0 0 4 4 60 -1 35 2.000 0 0 -1 0 0 5 + 3450 3525 3450 3600 600 3600 600 3525 3450 3525 +2 2 0 0 0 32 70 -1 21 2.000 0 0 -1 0 0 5 + -900 300 7500 300 7500 7800 -900 7800 -900 300 +4 1 0 50 -1 14 12 0.0000 4 120 240 1200 3225 14\001 +4 1 0 50 -1 14 12 0.0000 4 120 240 2100 3225 13\001 +4 1 0 50 -1 14 12 0.0000 4 120 240 3075 3225 12\001 +4 1 0 50 -1 14 10 0.0000 4 105 945 1950 5700 left side\001 +4 1 0 50 -1 14 10 0.0000 4 135 1050 4800 5700 right side\001 +4 1 0 50 -1 14 12 0.0000 4 120 240 4800 4725 11\001 +4 1 4 50 -1 14 12 0.0000 4 120 240 3300 4125 20\001 +4 1 0 50 -1 14 12 0.0000 4 120 240 5700 4725 10\001 +4 1 4 50 -1 14 12 0.0000 4 120 240 3900 4725 21\001 +4 1 0 50 -1 14 12 0.0000 4 120 240 1200 1125 14\001 +4 1 0 50 -1 14 12 0.0000 4 120 240 2100 1125 13\001 +4 1 0 50 -1 14 12 0.0000 4 120 240 4800 1125 11\001 +4 1 0 50 -1 14 12 0.0000 4 120 240 5700 1125 10\001 +4 1 0 50 -1 14 12 0.0000 4 120 240 3450 1125 12\001 +4 1 0 50 -1 14 10 0.0000 4 90 105 5700 1350 C\001 +4 1 0 50 -1 14 10 0.0000 4 90 105 5700 4950 C\001 +4 1 4 50 -1 14 10 0.0000 4 90 105 3525 4125 C\001 +4 1 4 50 -1 14 10 0.0000 4 90 105 3075 3450 C\001 diff --git a/kite/doc/images/_makeDogleg-10.png b/kite/doc/images/_makeDogleg-10.png new file mode 100644 index 0000000000000000000000000000000000000000..94781e611d133aecaa065562a93f41fb9b967809 GIT binary patch literal 14309 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 literal 0 HcmV?d00001 diff --git a/kite/src/BuildPowerRails.cpp b/kite/src/BuildPowerRails.cpp index f8b615b7..2f002ab8 100644 --- a/kite/src/BuildPowerRails.cpp +++ b/kite/src/BuildPowerRails.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -15,27 +14,26 @@ // +-----------------------------------------------------------------+ -#include -#include - -#include "hurricane/Error.h" -#include "hurricane/Warning.h" -#include "hurricane/DataBase.h" -#include "hurricane/Technology.h" -#include "hurricane/BasicLayer.h" -#include "hurricane/RegularLayer.h" -#include "hurricane/Horizontal.h" -#include "hurricane/Vertical.h" -#include "hurricane/NetExternalComponents.h" -#include "hurricane/Instance.h" -#include "hurricane/Plug.h" -#include "hurricane/Path.h" -#include "hurricane/Query.h" -#include "crlcore/AllianceFramework.h" -#include "kite/RoutingPlane.h" -#include "kite/TrackFixedSegment.h" -#include "kite/Track.h" -#include "kite/KiteEngine.h" +#include +#include +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/RegularLayer.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "hurricane/NetExternalComponents.h" +#include "hurricane/Instance.h" +#include "hurricane/Plug.h" +#include "hurricane/Path.h" +#include "hurricane/Query.h" +#include "crlcore/AllianceFramework.h" +#include "kite/RoutingPlane.h" +#include "kite/TrackFixedSegment.h" +#include "kite/Track.h" +#include "kite/KiteEngine.h" namespace { @@ -43,6 +41,8 @@ namespace { using namespace std; using Hurricane::tab; using Hurricane::inltrace; + using Hurricane::ltracein; + using Hurricane::ltraceout; using Hurricane::ForEachIterator; using Hurricane::Warning; using Hurricane::Error; @@ -72,7 +72,6 @@ namespace { // ------------------------------------------------------------------- // Class : "::GlobalNetTable". - class GlobalNetTable { public: GlobalNetTable ( Cell* ); @@ -208,7 +207,7 @@ namespace { if ( _vddi == NULL ) cerr << Error("Missing / net at top level." ) << endl; if ( _vssi == NULL ) cerr << Error("Missing / net at top level." ) << endl; - if ( _ckc == NULL ) cerr << Warning("No net at top level." ) << endl; + if ( _ckc == NULL ) cparanoid << Warning("No net at top level." ) << endl; } @@ -257,23 +256,23 @@ namespace { // ------------------------------------------------------------------- // Class : "::PowerRailsPlanes". - class PowerRailsPlanes { - private: + public: class Rails; class Plane; class Rail { public: - Rail ( Rails*, DbU::Unit axis, DbU::Unit width ); - inline DbU::Unit getAxis () const; - inline DbU::Unit getWidth () const; - inline Rails* getRails () const; - inline RoutingPlane* getRoutingPlane () const; - inline Constant::Direction getDirection () const; - inline Net* getNet () const; - void merge ( DbU::Unit source, DbU::Unit target ); - void doLayout ( const Layer* ); + Rail ( Rails*, DbU::Unit axis, DbU::Unit width ); + inline DbU::Unit getAxis () const; + inline DbU::Unit getWidth () const; + inline Rails* getRails () const; + inline RoutingPlane* getRoutingPlane () const; + inline unsigned int getDirection () const; + inline Net* getNet () const; + void merge ( DbU::Unit source, DbU::Unit target ); + void doLayout ( const Layer* ); + string _getString () const; private: Rails* _rails; DbU::Unit _axis; @@ -297,41 +296,47 @@ namespace { DbU::Unit _width; }; - private: + public: class Rails { public: - Rails ( Plane*, Constant::Direction, Net* ); - ~Rails (); - inline Plane* getPlane (); - inline RoutingPlane* getRoutingPlane (); - inline Constant::Direction getDirection () const; - inline Net* getNet () const; - void merge ( const Box& ); - void doLayout ( const Layer* ); + Rails ( Plane*, unsigned int direction, Net* ); + ~Rails (); + inline Plane* getPlane (); + inline RoutingPlane* getRoutingPlane (); + inline unsigned int getDirection () const; + inline Net* getNet () const; + void merge ( const Box& ); + void doLayout ( const Layer* ); private: - Plane* _plane; - Constant::Direction _direction; - Net* _net; - vector _rails; + Plane* _plane; + unsigned int _direction; + Net* _net; + vector _rails; }; - private: + public: class Plane { public: - Plane ( const Layer*, RoutingPlane* ); - ~Plane (); - inline const Layer* getLayer () const; - inline RoutingPlane* getRoutingPlane (); - inline Constant::Direction getDirection () const; - void merge ( const Box&, Net* ); - void doLayout (); + typedef map RailsMap; + public: + Plane ( const Layer*, RoutingPlane* ); + ~Plane (); + inline const Layer* getLayer () const; + inline RoutingPlane* getRoutingPlane (); + inline unsigned int getDirection () const; + inline unsigned int getPowerDirection () const; + void merge ( const Box&, Net* ); + void doLayout (); private: const Layer* _layer; RoutingPlane* _routingPlane; - map _horizontalRails; - map _verticalRails; + RailsMap _horizontalRails; + RailsMap _verticalRails; + unsigned int _powerDirection; }; + public: + typedef map PlanesMap; public: PowerRailsPlanes ( KiteEngine* ); ~PowerRailsPlanes (); @@ -342,73 +347,104 @@ namespace { void merge ( const Box&, Net* ); void doLayout (); private: - KiteEngine* _kite; - GlobalNetTable _globalNets; - map _planes; - Plane* _activePlane; + KiteEngine* _kite; + GlobalNetTable _globalNets; + PlanesMap _planes; + Plane* _activePlane; }; +} // Anonymous namespace. + + +namespace { + + PowerRailsPlanes::Rail::Rail ( Rails* rails, DbU::Unit axis, DbU::Unit width ) : _rails (rails) , _axis (axis) , _width (width) , _chunks() { - ltrace(300) << " new Rail " << (void*)this + ltrace(300) << " new Rail " << " @" << DbU::getValueString(axis) << " " << getRoutingPlane()->getLayer()->getName() << " " << getRails()->getNet() - << " " << getString(getDirection()) << endl; + << " " << ((getDirection()==KbHorizontal) ? "Horizontal" : "Vertical")<< endl; } - inline DbU::Unit PowerRailsPlanes::Rail::getAxis () const { return _axis; } - inline DbU::Unit PowerRailsPlanes::Rail::getWidth () const { return _width; } - inline PowerRailsPlanes::Rails* PowerRailsPlanes::Rail::getRails () const { return _rails; } - inline RoutingPlane* PowerRailsPlanes::Rail::getRoutingPlane () const { return _rails->getRoutingPlane(); } - inline Constant::Direction PowerRailsPlanes::Rail::getDirection () const { return _rails->getDirection(); } - inline Net* PowerRailsPlanes::Rail::getNet () const { return _rails->getNet(); } + inline DbU::Unit PowerRailsPlanes::Rail::getAxis () const { return _axis; } + inline DbU::Unit PowerRailsPlanes::Rail::getWidth () const { return _width; } + inline PowerRailsPlanes::Rails* PowerRailsPlanes::Rail::getRails () const { return _rails; } + inline RoutingPlane* PowerRailsPlanes::Rail::getRoutingPlane () const { return _rails->getRoutingPlane(); } + inline unsigned int PowerRailsPlanes::Rail::getDirection () const { return _rails->getDirection(); } + inline Net* PowerRailsPlanes::Rail::getNet () const { return _rails->getNet(); } void PowerRailsPlanes::Rail::merge ( DbU::Unit source, DbU::Unit target ) { - Interval chunkMerge ( source, target ); - ltrace(300) << " Rail::merge() " << chunkMerge << endl; + Interval chunkToMerge ( source, target ); + ltrace(300) << " Rail::merge() " + << ((getDirection()==KbHorizontal) ? "Horizontal" : "Vertical") + << " " << chunkToMerge << endl; + ltrace(300) << " | " << _getString() << endl; list::iterator imerge = _chunks.end(); list::iterator ichunk = _chunks.begin(); while ( ichunk != _chunks.end() ) { - if ( chunkMerge.getVMax() < (*ichunk).getVMin() ) { - _chunks.insert ( ichunk, chunkMerge ); - break; + if (imerge == _chunks.end()) { + if (chunkToMerge.getVMax() < (*ichunk).getVMin()) { + ltrace(300) << " | Insert before " << *ichunk << endl; + imerge = _chunks.insert( ichunk, chunkToMerge ); + break; + } + + if (chunkToMerge.intersect(*ichunk)) { + ltrace(300) << " | Merge with " << *ichunk << endl; + imerge = ichunk; + (*imerge).merge( chunkToMerge ); + } + } else { + if (chunkToMerge.getVMax() >= (*ichunk).getVMin()) { + (*imerge).merge( *ichunk ); + ltrace(300) << " | Absorb (erase) " << *ichunk << endl; + ichunk = _chunks.erase( ichunk ); + continue; + } else + break; } - if ( chunkMerge.intersect(*ichunk) ) { - if ( imerge == _chunks.end() ) { - imerge = ichunk; - (*imerge).merge ( chunkMerge ); - } else { - (*imerge).merge ( *ichunk ); - ichunk = _chunks.erase ( ichunk ); - continue; - } - } - ichunk++; + // if (chunkToMerge.intersect(*ichunk)) { + // if (imerge == _chunks.end()) { + // ltrace(300) << " | Merge with " << *ichunk << endl; + // imerge = ichunk; + // (*imerge).merge( chunkToMerge ); + // } else { + // (*imerge).merge( *ichunk ); + // ltrace(300) << " | Absorb (erase) " << *ichunk << endl; + // ichunk = _chunks.erase( ichunk ); + // continue; + // } + // } + ++ichunk; } - if ( imerge == _chunks.end() ) { - _chunks.insert ( ichunk, chunkMerge ); - ltrace(300) << " | Add on " << DbU::getValueString(_axis) << " " << chunkMerge << endl; + if (imerge == _chunks.end()) { + _chunks.insert( ichunk, chunkToMerge ); + ltrace(300) << " | Insert at end " << DbU::getValueString(_axis) << " " << chunkToMerge << endl; + ltrace(300) << " | " << _getString() << endl; } } void PowerRailsPlanes::Rail::doLayout ( const Layer* layer ) { - ltrace(300) << "Doing layout of rail: " << (void*)this + ltrace(300) << "Doing layout of rail: " << " " << layer->getName() - << " " << getString(getDirection()) << " @" << DbU::getValueString(_axis) << endl; + << " " << ((getDirection()==KbHorizontal) ? "Horizontal" : "Vertical") + << " @" << DbU::getValueString(_axis) << endl; + ltrace(300) << _getString() << endl; Net* net = getNet(); RoutingPlane* plane = getRoutingPlane(); @@ -418,18 +454,33 @@ namespace { - DbU::lambda(0.1); DbU::Unit extension = layer->getExtentionCap(); //DbU::Unit extension = Session::getExtentionCap(); - unsigned int type = plane->getLayerGauge()->getType(); + //unsigned int type = plane->getLayerGauge()->getType(); DbU::Unit axisMin = 0; DbU::Unit axisMax = 0; - if ( type == Constant::PinOnly ) { - ltrace(300) << " Layer is PinOnly." << endl; - return; - } + // if ( type == Constant::PinOnly ) { + // ltrace(300) << " Layer is PinOnly." << endl; + // return; + // } - if ( getDirection() == Constant::Horizontal ) { - list::iterator ichunk = _chunks.begin(); - for ( ; ichunk != _chunks.end() ; ichunk++ ) { + if ( getDirection() == KbHorizontal ) { + list::iterator ichunk = _chunks.begin(); + list::iterator ichunknext = ichunk; + ++ichunknext; + + for ( ; ichunk != _chunks.end() ; ++ichunk, ++ichunknext ) { + + if (ichunknext != _chunks.end()) { + if ((*ichunk).intersect(*ichunknext)) + cerr << Error( "Overlaping consecutive chunks in %s %s Rail @%s:\n" + " %s" + , getString(layer->getName()).c_str() + , ((getDirection()==KbHorizontal) ? "Horizontal" : "Vertical") + , DbU::getValueString(_axis).c_str() + , _getString().c_str() + ) << endl; + } + ltrace(300) << " chunk: [" << DbU::getValueString((*ichunk).getVMin()) << ":" << DbU::getValueString((*ichunk).getVMax()) << "]" << endl; @@ -447,7 +498,7 @@ namespace { axisMax = _axis + _width/2 + delta; Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior ); - for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) { + for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNextTrack() ) { TrackElement* element = TrackFixedSegment::create ( track, segment ); ltrace(300) << " Insert in " << track << "+" << element << endl; } @@ -472,15 +523,32 @@ namespace { axisMax = _axis + _width/2 + delta; Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior ); - for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) { + for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNextTrack() ) { TrackElement* element = TrackFixedSegment::create ( track, segment ); - ltrace(300) << " Insert in " << track << "+" << (void*)element << ":" << element << endl; + ltrace(300) << " Insert in " << track << "+" << element << endl; } } } } + string PowerRailsPlanes::Rail::_getString () const + { + ostringstream os; + + os << "::const_iterator ichunk = _chunks.begin(); + for ( ; ichunk != _chunks.end() ; ++ichunk ) { + if (ichunk != _chunks.begin()) os << " "; + os << "[" << DbU::getValueString((*ichunk).getVMin()) + << " " << DbU::getValueString((*ichunk).getVMax()) << "]"; + } + os << ">"; + return os.str(); + } + + inline bool PowerRailsPlanes::RailCompare::operator() ( const Rail* lhs, const Rail* rhs ) { if ( lhs->getAxis () < rhs->getAxis () ) return true; @@ -499,16 +567,16 @@ namespace { { return (rail->getAxis() == _axis) and (rail->getWidth() == _width); } - PowerRailsPlanes::Rails::Rails ( PowerRailsPlanes::Plane* plane, Constant::Direction direction, Net* net ) - : _plane (plane) - , _direction(direction) - , _net (net) - , _rails () + PowerRailsPlanes::Rails::Rails ( PowerRailsPlanes::Plane* plane , unsigned int direction , Net* net ) + : _plane (plane) + , _direction (direction) + , _net (net) + , _rails () { ltrace(300) << " new Rails @" << " " << getRoutingPlane()->getLayer()->getName() << " " << net - << " " << getString(getDirection()) << endl; + << " " << ((getDirection()==KbHorizontal) ? "Horizontal": "Vertical") << endl; } @@ -521,10 +589,10 @@ namespace { } - inline PowerRailsPlanes::Plane* PowerRailsPlanes::Rails::getPlane () { return _plane; } - inline RoutingPlane* PowerRailsPlanes::Rails::getRoutingPlane () { return getPlane()->getRoutingPlane(); } - inline Constant::Direction PowerRailsPlanes::Rails::getDirection () const { return _direction; } - inline Net* PowerRailsPlanes::Rails::getNet () const { return _net; } + inline PowerRailsPlanes::Plane* PowerRailsPlanes::Rails::getPlane () { return _plane; } + inline RoutingPlane* PowerRailsPlanes::Rails::getRoutingPlane () { return getPlane()->getRoutingPlane(); } + inline unsigned int PowerRailsPlanes::Rails::getDirection () const { return _direction; } + inline Net* PowerRailsPlanes::Rails::getNet () const { return _net; } void PowerRailsPlanes::Rails::merge ( const Box& bb ) @@ -534,7 +602,7 @@ namespace { DbU::Unit sourceU; DbU::Unit targetU; - if ( getDirection() == Constant::Horizontal ) { + if (getDirection() == KbHorizontal) { axis = bb.getYCenter(); width = bb.getHeight(); sourceU = bb.getXMin(); @@ -564,7 +632,7 @@ namespace { void PowerRailsPlanes::Rails::doLayout ( const Layer* layer ) { ltrace(300) << "Doing layout of rails: " << layer->getName() - << " " << getString(_direction) + << " " << ((_direction==KbHorizontal) ? "Horizontal" : "Vertical") << " " << _net->getName() << endl; for ( size_t irail=0 ; irail<_rails.size() ; irail++ ) @@ -577,14 +645,18 @@ namespace { , _routingPlane (routingPlane) , _horizontalRails () , _verticalRails () + , _powerDirection (routingPlane->getDirection()) { ltrace(300) << "New Plane " << _layer->getName() << " " << _routingPlane << endl; + + // Hard-coded SxLib gauge. + if (_routingPlane->getDepth() == 0) _powerDirection = KbHorizontal; } PowerRailsPlanes::Plane::~Plane () { - map::iterator irail = _horizontalRails.begin(); + RailsMap::iterator irail = _horizontalRails.begin(); for ( ; irail != _horizontalRails.end() ; ++irail ) { delete (*irail).second; } @@ -595,30 +667,35 @@ namespace { } - inline const Layer* PowerRailsPlanes::Plane::getLayer () const { return _layer; } - inline RoutingPlane* PowerRailsPlanes::Plane::getRoutingPlane () { return _routingPlane; } - inline Constant::Direction PowerRailsPlanes::Plane::getDirection () const { return (Constant::Direction)_routingPlane->getDirection(); } + inline const Layer* PowerRailsPlanes::Plane::getLayer () const { return _layer; } + inline RoutingPlane* PowerRailsPlanes::Plane::getRoutingPlane () { return _routingPlane; } + inline unsigned int PowerRailsPlanes::Plane::getDirection () const { return _routingPlane->getDirection(); } + inline unsigned int PowerRailsPlanes::Plane::getPowerDirection () const { return _powerDirection; } void PowerRailsPlanes::Plane::merge ( const Box& bb, Net* net ) { Rails* rails = NULL; - ltrace(300) << " Plane::merge() " << net->getName() << " " << (void*)net << endl; + ltrace(300) << " Plane::merge() " << net->getName() << " " << bb << endl; - if ( getDirection() == Constant::Horizontal ) { - map::iterator irails = _horizontalRails.find(net); + unsigned int direction = getDirection(); + if ( (net->getType() == Net::Type::POWER) or (net->getType() == Net::Type::GROUND) ) + direction = getPowerDirection(); + + if (direction == KbHorizontal) { + RailsMap::iterator irails = _horizontalRails.find(net); if ( irails == _horizontalRails.end() ) { - rails = new Rails(this,Constant::Horizontal,net); + rails = new Rails(this,KbHorizontal,net); _horizontalRails.insert ( make_pair(net,rails) ); } else rails = (*irails).second; rails->merge ( bb ); } else { - map::iterator irails = _verticalRails.find(net); + RailsMap::iterator irails = _verticalRails.find(net); if ( irails == _verticalRails.end() ) { - rails = new Rails(this,Constant::Vertical,net); + rails = new Rails(this,KbVertical,net); _verticalRails.insert ( make_pair(net,rails) ); } else rails = (*irails).second; @@ -633,7 +710,7 @@ namespace { { ltrace(300) << "Doing layout of plane: " << _layer->getName() << endl; - map::iterator irails = _horizontalRails.begin(); + RailsMap::iterator irails = _horizontalRails.begin(); for ( ; irails != _horizontalRails.end() ; ++irails ) { (*irails).second->doLayout(_layer); } @@ -650,7 +727,7 @@ namespace { , _planes () , _activePlane(NULL) { - _globalNets.setBlockage ( kite->getBlockageNet() ); + _globalNets.setBlockage( kite->getBlockageNet() ); Technology* technology = DataBase::getDB()->getTechnology(); RoutingGauge* rg = _kite->getConfiguration()->getRoutingGauge(); @@ -668,14 +745,12 @@ namespace { RoutingPlane* rp = _kite->getRoutingPlaneByIndex(lg->getDepth()); ltrace(300) << "Plane:" << rp << endl; - _planes.insert ( make_pair(regular->getBasicLayer(),new Plane(regular,rp)) ); + _planes.insert( make_pair(regular->getBasicLayer(),new Plane(regular,rp)) ); const BasicLayer* blockageLayer = regular->getBasicLayer()->getBlockageLayer(); - if ( not blockageLayer ) continue; + if (not blockageLayer) continue; - _planes.insert ( make_pair(blockageLayer,new Plane(blockageLayer,rp)) ); - - ltrace(300) << "OK" << endl; + _planes.insert( make_pair(blockageLayer,new Plane(blockageLayer,rp)) ); } } @@ -699,7 +774,7 @@ namespace { bool PowerRailsPlanes::setActivePlane ( const BasicLayer* layer ) { - map::iterator iplane = _planes.find(layer); + PlanesMap::iterator iplane = _planes.find(layer); if ( iplane == _planes.end() ) return false; _activePlane = iplane->second; @@ -727,7 +802,7 @@ namespace { void PowerRailsPlanes::doLayout () { - map::iterator iplane = _planes.begin(); + PlanesMap::iterator iplane = _planes.begin(); for ( ; iplane != _planes.end() ; iplane++ ) iplane->second->doLayout (); } @@ -737,7 +812,6 @@ namespace { // ------------------------------------------------------------------- // Class : "::QueryPowerRails". - class QueryPowerRails : public Query { public: QueryPowerRails ( KiteEngine* ); @@ -811,8 +885,16 @@ namespace { void QueryPowerRails::doQuery () { - if ( not _powerRailsPlanes.getActivePlane() ) return; - Query::doQuery (); + PowerRailsPlanes::Plane* activePlane = _powerRailsPlanes.getActivePlane(); + + if (not activePlane) return; + // if (activePlane->getRoutingPlane()->getLayerGauge()->getType() == Constant::PinOnly) { + // cmess1 << " - PowerRails in " << activePlane->getLayer()->getName() << " - Skipped (PinOnly layer)." << endl; + // return; + // } + + cmess1 << " - PowerRails in " << activePlane->getLayer()->getName() << " ..." << endl; + Query::doQuery(); } @@ -827,6 +909,8 @@ namespace { void QueryPowerRails::goCallback ( Go* go ) { + //ltrace(80) << "QueryPowerRails::goCallback() " << go->getId() << ":" << go + // << " " << getPath().getName() << endl; addToPowerRail ( go, getBasicLayer(), getArea(), getTransformation() ); } @@ -961,10 +1045,10 @@ namespace Kite { { cmess1 << " o Building power rails." << endl; - if ( not _blockageNet ) { + if (not _blockageNet) { _blockageNet = getCell()->getNet("blockagenet"); - if ( not _blockageNet ) - _blockageNet = Net::create ( getCell(), "blockagenet" ); + if (not _blockageNet) + _blockageNet = Net::create( getCell(), "blockagenet" ); } QueryPowerRails query ( this ); @@ -974,21 +1058,18 @@ namespace Kite { if ( (iLayer->getMaterial() != BasicLayer::Material::metal) and (iLayer->getMaterial() != BasicLayer::Material::blockage) ) continue; - if ( _configuration->isGMetal(*iLayer) ) continue; + if (_configuration->isGMetal(*iLayer)) continue; + if (not query.hasBasicLayer(*iLayer)) continue; - cmess1 << " - PowerRails in " << iLayer->getName() << " ..." << endl; - - if ( not query.hasBasicLayer(*iLayer) ) continue; - - query.setBasicLayer ( *iLayer ); - query.doQuery (); + query.setBasicLayer( *iLayer ); + query.doQuery (); } - query.ringAddToPowerRails (); - query.doLayout (); + query.ringAddToPowerRails(); + query.doLayout(); cmess1 << " - " << query.getGoMatchCount() << " power rails elements found." << endl; Session::revalidate (); } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/CMakeLists.txt b/kite/src/CMakeLists.txt index 7b6668e6..9c2ebdcd 100644 --- a/kite/src/CMakeLists.txt +++ b/kite/src/CMakeLists.txt @@ -1,3 +1,4 @@ +# -*- explicit-buffer-name: "CMakeLists.txt" -*- include ( ${QT_USE_FILE} ) @@ -8,7 +9,7 @@ ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_PATH} ) - set ( includes kite/TrackSegmentCost.h + set ( includes kite/Constants.h kite/TrackCost.h kite/DataNegociate.h kite/TrackElement.h kite/TrackElements.h @@ -19,12 +20,14 @@ kite/Tracks.h kite/HorizontalTrack.h kite/VerticalTrack.h + kite/RoutingPlane.h kite/Session.h + kite/Manipulator.h + kite/SegmentFsm.h kite/RoutingEvent.h kite/RoutingEventQueue.h kite/RoutingEventHistory.h kite/RoutingEventLoop.h - kite/RoutingPlane.h kite/NegociateWindow.h kite/Configuration.h kite/KiteEngine.h @@ -34,8 +37,7 @@ kite/PyGraphicKiteEngine.h ) set ( mocIncludes kite/GraphicKiteEngine.h ) - set ( cpps TrackSegmentCost.cpp - TrackCost.cpp + set ( cpps TrackCost.cpp DataNegociate.cpp TrackElement.cpp TrackElements.cpp @@ -46,16 +48,18 @@ Tracks.cpp HorizontalTrack.cpp VerticalTrack.cpp + RoutingPlane.cpp Session.cpp + Manipulator.cpp + SegmentFsm.cpp RoutingEvent.cpp RoutingEventQueue.cpp RoutingEventHistory.cpp RoutingEventLoop.cpp - RoutingPlane.cpp + NegociateWindow.cpp BuildPowerRails.cpp ProtectRoutingPads.cpp PreProcess.cpp - NegociateWindow.cpp Configuration.cpp KiteEngine.cpp GraphicKiteEngine.cpp @@ -68,42 +72,42 @@ qt4_wrap_cpp ( mocCpps ${mocIncludes} ) - add_library ( kite ${cpps} ${mocCpps} ${pyCpps} ) - set_target_properties ( kite PROPERTIES VERSION 1.0 SOVERSION 1 ) - target_link_libraries ( kite ${KATABATIC_LIBRARIES} - ${KNIK_LIBRARIES} - ${NIMBUS_LIBRARIES} - ${CORIOLIS_LIBRARIES} - ${HURRICANE_PYTHON_LIBRARIES} - ${HURRICANE_GRAPHICAL_LIBRARIES} - ${HURRICANE_LIBRARIES} - ${CONFIGURATION_LIBRARY} - ${BOOKSHELF_LIBRARY} - ${CIF_LIBRARY} - ${AGDS_LIBRARY} - ${LEFDEF_LIBRARIES} - ${OA_LIBRARIES} - ${QT_LIBRARIES} - ${Boost_LIBRARIES} - ${LIBXML2_LIBRARIES} - ${PYTHON_LIBRARIES} -lutil - ${LIBEXECINFO_LIBRARIES} + add_library ( kite ${cpps} ${mocCpps} ${pyCpps} ) + set_target_properties ( kite PROPERTIES VERSION 1.0 SOVERSION 1 ) + target_link_libraries ( kite ${KATABATIC_LIBRARIES} + ${KNIK_LIBRARIES} + ${NIMBUS_LIBRARIES} + ${CORIOLIS_LIBRARIES} + ${HURRICANE_PYTHON_LIBRARIES} + ${HURRICANE_GRAPHICAL_LIBRARIES} + ${HURRICANE_LIBRARIES} + ${CONFIGURATION_LIBRARY} + ${BOOKSHELF_LIBRARY} + ${CIF_LIBRARY} + ${AGDS_LIBRARY} + ${LEFDEF_LIBRARIES} + ${OA_LIBRARIES} + ${QT_LIBRARIES} + ${Boost_LIBRARIES} + ${LIBXML2_LIBRARIES} + ${PYTHON_LIBRARIES} -lutil + ${LIBEXECINFO_LIBRARIES} ) - add_library ( pyKite MODULE ${pyCpps} ) - set_target_properties ( pyKite PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -D__PYTHON_MODULE__=1" + add_library ( pyKite MODULE ${pyCpps} ) + set_target_properties ( pyKite PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -D__PYTHON_MODULE__=1" PREFIX "" OUTPUT_NAME "Kite" ) - add_executable ( kite.bin ${kitecpps} ) - target_link_libraries ( kite.bin kite ) - target_link_libraries ( pyKite kite +# add_executable ( kite.bin ${kitecpps} ) +#target_link_libraries ( kite.bin kite ) + target_link_libraries ( pyKite kite ${CORIOLIS_PYTHON_LIBRARIES} ) - install ( TARGETS kite DESTINATION lib${LIB_SUFFIX} ) - install ( TARGETS kite.bin DESTINATION bin ) - install ( TARGETS pyKite DESTINATION ${PYTHON_SITE_PACKAGES} ) + install ( TARGETS kite DESTINATION lib${LIB_SUFFIX} ) +# install ( TARGETS kite.bin DESTINATION bin ) + install ( TARGETS pyKite DESTINATION ${PYTHON_SITE_PACKAGES} ) install ( FILES ${includes} ${mocIncludes} diff --git a/kite/src/Configuration.cpp b/kite/src/Configuration.cpp index d82dd6f1..8d8e8472 100644 --- a/kite/src/Configuration.cpp +++ b/kite/src/Configuration.cpp @@ -1,15 +1,9 @@ - -// -*- C++ -*- +// -*- mode: C++; explicit-buffer-name: "Configuration.cpp" -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 | // | | @@ -17,25 +11,19 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./Configuration.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#include - -#include "vlsisapd/configuration/Configuration.h" -#include "hurricane/Cell.h" -#include "crlcore/Utilities.h" -#include "kite/Configuration.h" -#include "kite/KiteEngine.h" - +#include +#include "vlsisapd/configuration/Configuration.h" +#include "hurricane/Cell.h" +#include "crlcore/Utilities.h" +#include "kite/Configuration.h" +#include "kite/KiteEngine.h" namespace Kite { - using std::cout; using std::cerr; using std::endl; @@ -123,6 +111,10 @@ namespace Kite { { return _base->isGMetal(layer); } + bool Configuration::isGContact ( const Layer* layer ) const + { return _base->isGContact(layer); } + + size_t Configuration::getDepth () const { return _base->getDepth(); } @@ -281,4 +273,4 @@ namespace Kite { -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/DataNegociate.cpp b/kite/src/DataNegociate.cpp index a410e7f4..33907dff 100644 --- a/kite/src/DataNegociate.cpp +++ b/kite/src/DataNegociate.cpp @@ -2,7 +2,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -15,14 +15,31 @@ // +-----------------------------------------------------------------+ -#include -#include -#include "kite/DataNegociate.h" +#include +#include +#include "hurricane/Bug.h" +#include "hurricane/DebugSession.h" +#include "katabatic/AutoSegment.h" +#include "kite/DataNegociate.h" +#include "kite/RoutingEvent.h" namespace Kite { + using std::cerr; + using std::endl; + using std::map; + using std::multimap; + using std::make_pair; using std::ostringstream; + using Hurricane::Bug; + using Hurricane::DebugSession; + using Hurricane::inltrace; + using Hurricane::ltracein; + using Hurricane::ltraceout; + using Hurricane::tab; + using Katabatic::KbHorizontal; + using Katabatic::KbPropagate; // ------------------------------------------------------------------- @@ -30,12 +47,19 @@ namespace Kite { DataNegociate::DataNegociate ( TrackElement* trackSegment ) - : _routingEvent(NULL) - , _trackSegment(trackSegment) - , _cost (trackSegment) - , _state (RipupPerpandiculars) - , _stateCount (1) - //, _z (RoutingGauge::getLayerDepth(trackSegment->getLayer())) + : _trackSegment (trackSegment) + , _childSegment (NULL) + , _routingEvent (NULL) + , _net (trackSegment->getNet()) + , _state (RipupPerpandiculars) + , _stateCount (1) + , _terminals (0) + , _ripupCount (0) + , _leftMinExtend (DbU::Max) + , _rightMinExtend (DbU::Min) + , _attractors () + , _perpandiculars () + , _perpandicularFree(false) { } @@ -43,25 +67,164 @@ namespace Kite { { } + DbU::Unit DataNegociate::getWiringDelta ( DbU::Unit axis ) const + { + DbU::Unit attraction = 0; + for ( size_t i=0 ; i < _attractors.size() ; i++ ) { + if ( _attractors[i] > axis ) attraction += _attractors[i] - axis; + else attraction += axis - _attractors[i]; + } + return attraction; + } + + void DataNegociate::update () - { _cost.update ( _trackSegment ); } + { + DebugSession::open( _trackSegment->getNet(), 148 ); + + ltrace(148) << "DataNegociate::update() - " << _trackSegment << endl; + ltracein(148); + + vector collapseds; + vector perpandiculars; + map attractorSpins; + + _perpandiculars.clear(); + AutoSegment::getTopologicalInfos( _trackSegment->base() + , collapseds + , perpandiculars + , _leftMinExtend + , _rightMinExtend + ); + + _terminals = AutoSegment::getTerminalCount( _trackSegment->base(), collapseds ); + _attractors.clear(); + _perpandiculars.clear(); + _perpandicularFree = Interval(false); + + ltrace(148) << "Extracting attractors from perpandiculars." << endl; + for ( size_t i=0 ; i < perpandiculars.size() ; i++ ) { + Interval interval; + TrackElement* perpandicular; + + if (perpandiculars[i]->isCanonical()) { + perpandicular = Session::lookup( perpandiculars[i]->base() ); + if (perpandicular) perpandicular->getCanonical( interval ); + } else { + perpandicular = Session::lookup( perpandiculars[i]->getCanonical(interval)->base() ); + } + if (not perpandicular) { + cerr << Bug( "Not a TrackSegment: %s\n (perpandicular: %s)" + //, getString((void*)perpandiculars[i]->getCanonical(interval)->base()).c_str() + , getString(perpandiculars[i]->getCanonical(interval)).c_str() + //, getString((void*)perpandiculars[i]->base()).c_str() + , getString(perpandiculars[i]).c_str() + ) << endl; + continue; + } + + if (RoutingEvent::getStage() == RoutingEvent::Repair) + perpandicular->base()->setFlagsOnAligneds( Katabatic::SegUnbound ); + + interval.inflate( DbU::lambda(-0.5) ); + + ltrace(148) << "| perpandicular: " << perpandiculars[i] << endl; + ltrace(148) << "| canonical: " << perpandicular << endl; + ltracein(148); + ltrace(148) << "Canonical // interval: " << interval << endl; + + _perpandiculars.push_back( perpandicular ); + if (perpandicular->getTrack()) { + Interval trackFree = perpandicular->getFreeInterval(); + ltrace(148) << "Track Perpandicular Free: " << trackFree << endl; + + _perpandicularFree.intersection( trackFree ); + } else { + ltrace(148) << "Not in any track " << perpandicular << endl; + } + + if (interval.isPonctual()) { + ltrace(148) << "Punctual attractor @" << DbU::getValueString(interval.getVMin()) << endl; + _attractors.push_back( interval.getVMin() ); + ltraceout(148); + continue; + } + + if ( (interval.getVMin() != _trackSegment->getAxis()) + or AutoSegment::isTopologicalBound(perpandiculars[i] + ,perpandicular->isHorizontal() ? KbHorizontal : 0 + ) ) { + map::iterator iattractor = attractorSpins.find( interval.getVMin() ); + if (iattractor == attractorSpins.end()) { + attractorSpins.insert( make_pair(interval.getVMin(),-1) ); + } else { + iattractor->second -= 1; + } + ltrace(148) << "Left attractor @" << DbU::getValueString(interval.getVMin()) << endl; + } + + if ( (interval.getVMax() != _trackSegment->getAxis()) + or AutoSegment::isTopologicalBound(perpandiculars[i] + ,KbPropagate | (perpandicular->isHorizontal() ? KbHorizontal : 0) + ) ) { + map::iterator iattractor = attractorSpins.find( interval.getVMax() ); + if (iattractor == attractorSpins.end()) { + attractorSpins.insert( make_pair(interval.getVMax(),1) ); + } else { + iattractor->second += 1; + } + ltrace(148) << "Right attractor @" << DbU::getValueString(interval.getVMax()) << endl; + } + + ltraceout(148); + } + if ( not _trackSegment->isTerminal() and (_perpandiculars.size() < 2) ) + cerr << Bug( "Less than two perpandiculars on %s.", getString(_trackSegment).c_str() ) << endl; + + map::iterator iattractor = attractorSpins.begin(); + for ( ; iattractor != attractorSpins.end() ; iattractor++ ) { + if (iattractor->second != 0) + _attractors.push_back( iattractor->first ); + } + + ostringstream s; + s << "Attractors ["; + for ( size_t i=0 ; i<_attractors.size() ; i++ ) { + if ( i ) s << ", "; + s << DbU::getValueString( _attractors[i] ); + } + s << "]"; + ltrace(148) << s.str() << endl; + ltrace(200) << "Perpandicular Free: " << _perpandicularFree << endl; + + + ltraceout(148); + DebugSession::close(); + } string DataNegociate::_getString () const { return "<" + _getTypeName() + " " - + getString(_trackSegment) - + ">"; + + getString(_trackSegment) + " " + + getString(_terminals) + + " [" + DbU::getValueString(_leftMinExtend) + + ":" + DbU::getValueString(_rightMinExtend) + + "]>"; } Record* DataNegociate::_getRecord () const { Record* record = new Record ( getString(this) ); - record->add ( getSlot ( "_routingEvent", _routingEvent ) ); - record->add ( getSlot ( "_trackSegment", _trackSegment ) ); - record->add ( getSlot ( "_cost" , &_cost ) ); - //record->add ( getSlot ( "_z" , _z ) ); + record->add( getSlot ( "_routingEvent" , _routingEvent ) ); + record->add( getSlot ( "_trackSegment" , _trackSegment ) ); + record->add( getSlot ( "_childSegment" , _childSegment ) ); + record->add( getSlot ( "_terminals" , _terminals ) ); + record->add( getSlot ( "_ripupCount" , _ripupCount ) ); + record->add( DbU::getValueSlot( "_leftMinExtend" , &_leftMinExtend ) ); + record->add( DbU::getValueSlot( "_rightMinExtend", &_rightMinExtend ) ); + record->add( getSlot ( "_net" , _net ) ); return record; } @@ -71,18 +234,17 @@ namespace Kite { { ostringstream s; switch ( data->_state ) { - case RipupPerpandiculars: s << "RipupPerpandiculars"; break; - case Minimize: s << "Minimize"; break; - case DogLeg: s << "DogLeg"; break; - case Desalignate: s << "Desalignate"; break; - case Slacken: s << "Slacken"; break; - case ConflictSolve1: s << "ConflictSolve1"; break; - case ConflictSolve2: s << "ConflictSolve2"; break; - case LocalVsGlobal: s << "LocalVsGlobal"; break; - case MoveUp: s << "MoveUp"; break; - case MaximumSlack: s << "MaximumSlack"; break; - case Unimplemented: s << "Unimplemented"; break; - case Repair: s << "REPAIR"; break; + case RipupPerpandiculars: s << "RipupPerpandiculars"; break; + case Minimize: s << "Minimize"; break; + case Dogleg: s << "Dogleg"; break; + case Slacken: s << "Slacken"; break; + case ConflictSolveByHistory: s << "ConflictSolveByHistory1"; break; + case ConflictSolveByPlaceds: s << "ConflictSolveByPlaceds"; break; + case LocalVsGlobal: s << "LocalVsGlobal"; break; + case MoveUp: s << "MoveUp"; break; + case MaximumSlack: s << "MaximumSlack"; break; + case Unimplemented: s << "Unimplemented"; break; + case Repair: s << "REPAIR"; break; default: s << "Unknown(" << data->_state << ")"; break; } @@ -91,4 +253,4 @@ namespace Kite { } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/GraphicKiteEngine.cpp b/kite/src/GraphicKiteEngine.cpp index 6aef6d2e..2065e339 100644 --- a/kite/src/GraphicKiteEngine.cpp +++ b/kite/src/GraphicKiteEngine.cpp @@ -2,14 +2,9 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 | // | | @@ -17,46 +12,41 @@ // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Header : "./GraphicKiteEngine.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +//#include namespace Kite { - using namespace std; using Hurricane::Error; using Hurricane::Warning; @@ -79,9 +69,7 @@ namespace Kite { void GraphicKiteEngine::initKatabaticAc ( CellWidget* widget ) - { - //cerr << "GraphicKatabaticEngine::initKatabaticGo()" << endl; - } + { } void GraphicKiteEngine::drawKatabaticAc ( CellWidget* widget @@ -95,11 +83,11 @@ namespace Kite { void GraphicKiteEngine::initKatabaticGCell ( CellWidget* widget ) { - widget->getDrawingPlanes().setPen ( Qt::NoPen ); + widget->getDrawingPlanes().setPen( Qt::NoPen ); - KiteEngine* kite = KiteEngine::get ( widget->getCell() ); + KiteEngine* kite = KiteEngine::get( widget->getCell() ); if ( kite ) { - kite->getGCellGrid()->setDensityMode ( Katabatic::GCellGrid::MaxDensity ); + kite->getGCellGrid()->setDensityMode( Katabatic::GCellGrid::MaxDensity ); } } @@ -115,7 +103,7 @@ namespace Kite { QPainter& painter = widget->getPainter(); size_t density = (size_t)( gcell->getDensity() * 255.0 ); - if ( density > 255 ) density = 255; + if (density > 255) density = 255; painter.setBrush ( Graphics::getColorScale(ColorScale::Fire).getBrush(density,widget->getDarkening()) ); @@ -131,12 +119,12 @@ namespace Kite { { Cell* cell = getCell (); - KiteEngine* kite = KiteEngine::get ( cell ); - if ( not kite ) { - kite = KiteEngine::create ( cell ); - kite->setPostEventCb ( boost::bind(&GraphicKiteEngine::postEvent,this) ); + KiteEngine* kite = KiteEngine::get( cell ); + if (not kite) { + kite = KiteEngine::create( cell ); + kite->setPostEventCb( boost::bind(&GraphicKiteEngine::postEvent,this) ); } else - cerr << Warning("%s already has a Kite engine.",getString(cell).c_str()) << endl; + cerr << Warning( "%s already has a Kite engine.", getString(cell).c_str() ) << endl; return kite; } @@ -146,13 +134,13 @@ namespace Kite { { // Currently, only one framework is avalaible: Alliance. - KiteEngine* kite = KiteEngine::get ( getCell() ); - if ( kite ) return kite; + KiteEngine* kite = KiteEngine::get( getCell() ); + if (kite) return kite; - kite = createEngine (); + kite = createEngine(); - if ( not kite ) - throw Error("Failed to create Kite engine on %s.",getString(getCell()).c_str()); + if (not kite) + throw Error( "Failed to create Kite engine on %s.", getString(getCell()).c_str() ); return kite; } @@ -160,28 +148,28 @@ namespace Kite { void GraphicKiteEngine::saveGlobalSolution () { - KiteEngine* kite = KiteEngine::get ( getCell() ); - if ( kite ) kite->saveGlobalSolution (); + KiteEngine* kite = KiteEngine::get( getCell() ); + if (kite) kite->saveGlobalSolution (); } void GraphicKiteEngine::loadGlobalSolution () { - KiteEngine* kite = getForFramework (); + KiteEngine* kite = getForFramework(); - emit cellPreModificated (); - kite->runGlobalRouter ( LoadGlobalSolution ); - emit cellPostModificated (); + emit cellPreModificated(); + kite->runGlobalRouter( KtLoadGlobalRouting ); + emit cellPostModificated(); } void GraphicKiteEngine::globalRoute () { - KiteEngine* kite = getForFramework (); + KiteEngine* kite = getForFramework(); - emit cellPreModificated (); - kite->runGlobalRouter ( BuildGlobalSolution ); - emit cellPostModificated (); + emit cellPreModificated(); + kite->runGlobalRouter( KtBuildGlobalRouting ); + emit cellPostModificated(); } @@ -189,73 +177,61 @@ namespace Kite { { static KatabaticEngine::NetSet routingNets; - KiteEngine* kite = KiteEngine::get ( getCell() ); - if ( not kite ) { - throw Error("KiteEngine not created yet, run the global router first."); + KiteEngine* kite = KiteEngine::get( getCell() ); + if (not kite) { + throw Error( "KiteEngine not created yet, run the global router first." ); } - if ( cmess1.enabled() ) - kite->printConfiguration (); + if (cmess1.enabled()) kite->printConfiguration(); + emit cellPreModificated(); + _viewer->clearToolInterrupt(); + kite->loadGlobalRouting( Katabatic::EngineLoadGrByNet, routingNets ); + emit cellPostModificated(); emit cellPreModificated (); - - _viewer->clearToolInterrupt (); - - kite->loadGlobalRouting ( Katabatic::LoadGrByNet, routingNets ); - emit cellPostModificated (); - - //Breakpoint::stop ( 0, "Point d'arret:
      LayerAssingByTrunk()
    " - // "Assignment des layers, methode globale." ); - emit cellPreModificated (); - kite->layerAssign ( Katabatic::NoNetLayerAssign ); - emit cellPostModificated (); - - //Breakpoint::stop ( 0, "Point d'arret:
      runNegociate()
    " - // "Routage par Negociation." ); - emit cellPreModificated (); - kite->runNegociate (); - emit cellPostModificated (); + kite->balanceGlobalDensity (); + kite->layerAssign ( Katabatic::EngineNoNetLayerAssign ); + emit cellPostModificated(); + emit cellPreModificated(); + kite->runNegociate(); + emit cellPostModificated(); } void GraphicKiteEngine::finalize () { - emit cellPreModificated (); - KiteEngine* kite = KiteEngine::get ( getCell() ); - if ( kite ) { - kite->finalizeLayout (); - //kite->dumpMeasures (); - kite->destroy (); + emit cellPreModificated(); + KiteEngine* kite = KiteEngine::get( getCell() ); + if (kite) { + kite->finalizeLayout(); + kite->destroy(); } - emit cellPostModificated (); + emit cellPostModificated(); } void GraphicKiteEngine::save () { - //KiteEngine* kite = KiteEngine::get ( getCell() ); - //if ( kite ) { - Cell* cell = getCell(); - AllianceFramework* af = AllianceFramework::get (); + Cell* cell = getCell(); + AllianceFramework* af = AllianceFramework::get(); - string name = getString(cell->getName()) + "_kite"; - cell->setName ( name ); - af->saveCell ( cell, Catalog::State::Physical ); - //} + string name = getString(cell->getName()) + "_kite"; + cell->setName( name ); + af->saveCell( cell, Catalog::State::Physical ); } void GraphicKiteEngine::route () { - globalRoute (); - detailRoute (); - finalize (); + globalRoute(); + detailRoute(); + finalize (); } void GraphicKiteEngine::dumpMeasures () { - KiteEngine* kite = getForFramework (); - if ( kite ) kite->dumpMeasures (); + KiteEngine* kite = getForFramework(); + if (kite) kite->dumpMeasures(); } @@ -263,19 +239,13 @@ namespace Kite { { static unsigned int count = 0; - if ( not (count++ % 500) ) { - //UpdateSession::close (); + if (not (count++ % 500)) { + QApplication::processEvents(); - //_viewer->getCellWidget()->refresh (); - QApplication::processEvents (); - - //UpdateSession::open (); - - if ( _viewer->isToolInterrupted() ) { - KiteEngine* kite = KiteEngine::get ( getCell() ); - if ( kite ) kite->setInterrupt ( true ); - - _viewer->clearToolInterrupt (); + if (_viewer->isToolInterrupted()) { + KiteEngine* kite = KiteEngine::get( getCell() ); + if (kite) kite->setInterrupt( true ); + _viewer->clearToolInterrupt(); } } } @@ -283,122 +253,109 @@ namespace Kite { void GraphicKiteEngine::addToMenu ( CellViewer* viewer ) { - assert ( _viewer == NULL ); + assert( _viewer == NULL ); _viewer = viewer; QMenu* prMenu = _viewer->findChild("viewer.menuBar.placeAndRoute"); QMenu* stepMenu = _viewer->findChild("viewer.menuBar.placeAndRoute.stepByStep"); - if ( !prMenu ) { + if (prMenu == NULL) { QMenuBar* menuBar = _viewer->findChild("viewer.menuBar"); - if ( !menuBar ) { - cerr << Warning("GraphicKiteEngine::addToMenu() - No MenuBar in parent widget.") << endl; + if (menuBar == NULL) { + cerr << Warning( "GraphicKiteEngine::addToMenu() - No MenuBar in parent widget." ) << endl; return; } - prMenu = menuBar->addMenu ( tr("P&&R") ); - prMenu->setObjectName ( "viewer.menuBar.placeAndRoute" ); + prMenu = menuBar->addMenu( tr("P&&R") ); + prMenu->setObjectName( "viewer.menuBar.placeAndRoute" ); - stepMenu = prMenu->addMenu ( tr("&Step by Step") ); - stepMenu->setObjectName ( "viewer.menuBar.placeAndRoute.stepByStep" ); + stepMenu = prMenu->addMenu( tr("&Step by Step") ); + stepMenu->setObjectName( "viewer.menuBar.placeAndRoute.stepByStep" ); - prMenu->addSeparator (); + prMenu->addSeparator(); } QAction* dRouteAction = _viewer->findChild("viewer.menuBar.placeAndRoute.detailedRoute"); - if ( dRouteAction ) - cerr << Warning("GraphicKiteEngine::addToMenu() - Kite detailed router already hooked in.") << endl; + if (dRouteAction) + cerr << Warning( "GraphicKiteEngine::addToMenu() - Kite detailed router already hooked in." ) << endl; else { - stepMenu->addSeparator (); + stepMenu->addSeparator(); - QAction* gRouteAction = new QAction ( tr("Kite - &Global Route"), _viewer ); - gRouteAction->setObjectName ( "viewer.menuBar.placeAndRoute.stepBystep.globalRoute" ); - gRouteAction->setStatusTip ( tr("Run the Knik global router") ); - gRouteAction->setVisible ( true ); - stepMenu->addAction ( gRouteAction ); + QAction* gRouteAction = new QAction ( tr("Kite - &Global Route"), _viewer ); + gRouteAction->setObjectName( "viewer.menuBar.placeAndRoute.stepBystep.globalRoute" ); + gRouteAction->setStatusTip ( tr("Run the Knik global router") ); + gRouteAction->setVisible ( true ); + stepMenu->addAction( gRouteAction ); - QAction* gLoadSolutionAction = new QAction ( tr("Kite - &Load Global Routing"), _viewer ); - gLoadSolutionAction->setObjectName ( "viewer.menuBar.placeAndRoute.stepByStep.loadGlobalRouting" ); - gLoadSolutionAction->setStatusTip ( tr("Load a solution for the global routing (.kgr)") ); - gLoadSolutionAction->setVisible ( true ); - stepMenu->addAction ( gLoadSolutionAction ); + QAction* gLoadSolutionAction = new QAction ( tr("Kite - &Load Global Routing"), _viewer ); + gLoadSolutionAction->setObjectName( "viewer.menuBar.placeAndRoute.stepByStep.loadGlobalRouting" ); + gLoadSolutionAction->setStatusTip ( tr("Load a solution for the global routing (.kgr)") ); + gLoadSolutionAction->setVisible ( true ); + stepMenu->addAction( gLoadSolutionAction ); - QAction* gSaveSolutionAction = new QAction ( tr("Kite - &Save Global Routing"), _viewer ); - gSaveSolutionAction->setObjectName ( "viewer.menuBar.placeAndRoute.stepByStep.saveGlobalRouting" ); - gSaveSolutionAction->setStatusTip ( tr("Save a global router solution (.kgr)") ); - gSaveSolutionAction->setVisible ( true ); - stepMenu->addAction ( gSaveSolutionAction ); + QAction* gSaveSolutionAction = new QAction ( tr("Kite - &Save Global Routing"), _viewer ); + gSaveSolutionAction->setObjectName( "viewer.menuBar.placeAndRoute.stepByStep.saveGlobalRouting" ); + gSaveSolutionAction->setStatusTip ( tr("Save a global router solution (.kgr)") ); + gSaveSolutionAction->setVisible ( true ); + stepMenu->addAction( gSaveSolutionAction ); - dRouteAction = new QAction ( tr("Kite - &Detailed Route"), _viewer ); - dRouteAction->setObjectName ( "viewer.menuBar.placeAndRoute.stepBystep.detailedRoute" ); - dRouteAction->setStatusTip ( tr("Run the Kite detailed router") ); - dRouteAction->setVisible ( true ); - stepMenu->addAction ( dRouteAction ); + dRouteAction = new QAction ( tr("Kite - &Detailed Route"), _viewer ); + dRouteAction->setObjectName( "viewer.menuBar.placeAndRoute.stepBystep.detailedRoute" ); + dRouteAction->setStatusTip ( tr("Run the Kite detailed router") ); + dRouteAction->setVisible ( true ); + stepMenu->addAction( dRouteAction ); - QAction* dFinalizeAction = new QAction ( tr("Kite - &Finalize Routing"), _viewer ); - dFinalizeAction->setObjectName ( "viewer.menuBar.placeAndRoute.stepBystep.finalize" ); - dFinalizeAction->setStatusTip ( tr("Closing Routing") ); - dFinalizeAction->setVisible ( true ); - stepMenu->addAction ( dFinalizeAction ); + QAction* dFinalizeAction = new QAction( tr("Kite - &Finalize Routing"), _viewer ); + dFinalizeAction->setObjectName( "viewer.menuBar.placeAndRoute.stepBystep.finalize" ); + dFinalizeAction->setStatusTip ( tr("Closing Routing") ); + dFinalizeAction->setVisible ( true ); + stepMenu->addAction( dFinalizeAction ); QAction* dDumpMeasuresAction = new QAction ( tr("Kite - Dump &Measures"), _viewer ); - dDumpMeasuresAction->setObjectName ( "viewer.menuBar.placeAndRoute.stepBystep.dumpMeasures" ); - dDumpMeasuresAction->setStatusTip ( tr("Dumping Measurements on the disk") ); - dDumpMeasuresAction->setVisible ( true ); - stepMenu->addAction ( dDumpMeasuresAction ); + dDumpMeasuresAction->setObjectName( "viewer.menuBar.placeAndRoute.stepBystep.dumpMeasures" ); + dDumpMeasuresAction->setStatusTip ( tr("Dumping Measurements on the disk") ); + dDumpMeasuresAction->setVisible ( true ); + stepMenu->addAction( dDumpMeasuresAction ); QAction* dSaveAction = new QAction ( tr("Kite - &Save Design"), _viewer ); - dSaveAction->setObjectName ( "viewer.menuBar.placeAndRoute.stepBystep.save" ); - dSaveAction->setStatusTip ( tr("Save routed design (temporary hack)") ); - dSaveAction->setVisible ( true ); - stepMenu->addAction ( dSaveAction ); + dSaveAction->setObjectName( "viewer.menuBar.placeAndRoute.stepBystep.save" ); + dSaveAction->setStatusTip ( tr("Save routed design (temporary hack)") ); + dSaveAction->setVisible ( true ); + stepMenu->addAction( dSaveAction ); - QAction* routeAction = new QAction ( tr("Kite - &Route"), _viewer ); - routeAction->setObjectName ( "viewer.menuBar.placeAndRoute.route" ); - routeAction->setStatusTip ( tr("Route the design (global & detailed)") ); - routeAction->setVisible ( true ); - prMenu->addAction ( routeAction ); + QAction* routeAction = new QAction ( tr("Kite - &Route"), _viewer ); + routeAction->setObjectName( "viewer.menuBar.placeAndRoute.route" ); + routeAction->setStatusTip ( tr("Route the design (global & detailed)") ); + routeAction->setVisible ( true ); + prMenu->addAction( routeAction ); - connect ( gLoadSolutionAction, SIGNAL(triggered()), this, SLOT(loadGlobalSolution()) ); - connect ( gSaveSolutionAction, SIGNAL(triggered()), this, SLOT(saveGlobalSolution()) ); - connect ( gRouteAction , SIGNAL(triggered()), this, SLOT(globalRoute ()) ); - connect ( dRouteAction , SIGNAL(triggered()), this, SLOT(detailRoute ()) ); - connect ( dFinalizeAction , SIGNAL(triggered()), this, SLOT(finalize ()) ); - connect ( dSaveAction , SIGNAL(triggered()), this, SLOT(save ()) ); - connect ( dDumpMeasuresAction, SIGNAL(triggered()), this, SLOT(dumpMeasures ()) ); - connect ( routeAction , SIGNAL(triggered()), this, SLOT(route ()) ); + connect( gLoadSolutionAction, SIGNAL(triggered()), this, SLOT(loadGlobalSolution()) ); + connect( gSaveSolutionAction, SIGNAL(triggered()), this, SLOT(saveGlobalSolution()) ); + connect( gRouteAction , SIGNAL(triggered()), this, SLOT(globalRoute ()) ); + connect( dRouteAction , SIGNAL(triggered()), this, SLOT(detailRoute ()) ); + connect( dFinalizeAction , SIGNAL(triggered()), this, SLOT(finalize ()) ); + connect( dSaveAction , SIGNAL(triggered()), this, SLOT(save ()) ); + connect( dDumpMeasuresAction, SIGNAL(triggered()), this, SLOT(dumpMeasures ()) ); + connect( routeAction , SIGNAL(triggered()), this, SLOT(route ()) ); } - connect ( this, SIGNAL(cellPreModificated ()), _viewer->getCellWidget(), SLOT(cellPreModificate ()) ); - connect ( this, SIGNAL(cellPostModificated()), _viewer->getCellWidget(), SLOT(cellPostModificate()) ); - - // ControllerWidget* controller = _viewer->getControllerWidget(); - // ConfigurationWidget* setting = controller->getSettings() - // ->findChild("controller.tabSettings.setting.kite"); - - // if ( setting == NULL ) { - // setting = new ConfigurationWidget (); - // setting->setObjectName ( "controller.tabSettings.setting.kite" ); - // setting->setConfiguration ( Configuration::getDefault() ); - // controller->addSetting ( setting, "Kite" ); - // } + connect( this, SIGNAL(cellPreModificated ()), _viewer->getCellWidget(), SLOT(cellPreModificate ()) ); + connect( this, SIGNAL(cellPostModificated()), _viewer->getCellWidget(), SLOT(cellPostModificate()) ); } const Name& GraphicKiteEngine::getName () const - { - return KiteEngine::staticGetName (); - } + { return KiteEngine::staticGetName(); } Cell* GraphicKiteEngine::getCell () { - if ( !_viewer ) { - throw Error ( "Kite: GraphicKiteEngine not bound to any Viewer." ); + if (_viewer == NULL) { + throw Error( "Kite: GraphicKiteEngine not bound to any Viewer." ); return NULL; } - if ( !_viewer->getCell() ) { - throw Error ( "Kite: No Cell is loaded into the Viewer." ); + if (_viewer->getCell() == NULL) { + throw Error( "Kite: No Cell is loaded into the Viewer." ); return NULL; } @@ -408,7 +365,7 @@ namespace Kite { GraphicKiteEngine* GraphicKiteEngine::grab () { - if ( !_references ) { + if (not _references) { _singleton = new GraphicKiteEngine (); } _references++; @@ -419,8 +376,8 @@ namespace Kite { size_t GraphicKiteEngine::release () { - _references--; - if ( !_references ) { + --_references; + if (not _references) { delete _singleton; _singleton = NULL; } @@ -430,12 +387,12 @@ namespace Kite { GraphicKiteEngine::GraphicKiteEngine () : GraphicTool() - , _viewer(NULL) + , _viewer (NULL) { - addDrawGo ( "Knik::Edge" , GraphicKnikEngine::initKnikEdges , GraphicKnikEngine::drawKnikEdges ); - addDrawGo ( "Knik::Vertex" , GraphicKnikEngine::initKnikVertex, GraphicKnikEngine::drawKnikVertex ); - addDrawGo ( "Katabatic::Ac" , initKatabaticAc , drawKatabaticAc ); - addDrawGo ( "Katabatic::GCell", initKatabaticGCell, drawKatabaticGCell ); + addDrawGo( "Knik::Edge" , GraphicKnikEngine::initKnikEdges , GraphicKnikEngine::drawKnikEdges ); + addDrawGo( "Knik::Vertex" , GraphicKnikEngine::initKnikVertex, GraphicKnikEngine::drawKnikVertex ); + addDrawGo( "Katabatic::Ac" , initKatabaticAc , drawKatabaticAc ); + addDrawGo( "Katabatic::GCell", initKatabaticGCell, drawKatabaticGCell ); } @@ -443,4 +400,4 @@ namespace Kite { { } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/HorizontalTrack.cpp b/kite/src/HorizontalTrack.cpp index 70ea05da..dd45b9d5 100644 --- a/kite/src/HorizontalTrack.cpp +++ b/kite/src/HorizontalTrack.cpp @@ -2,14 +2,9 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 | // | | @@ -17,13 +12,10 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./HorizontalTrack.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#include "kite/HorizontalTrack.h" +#include "kite/HorizontalTrack.h" namespace Kite { @@ -61,7 +53,7 @@ namespace Kite { bool HorizontalTrack::isHorizontal () const { return true; } bool HorizontalTrack::isVertical () const { return false; } - unsigned int HorizontalTrack::getDirection () const { return Constant::Horizontal; } + unsigned int HorizontalTrack::getDirection () const { return KbHorizontal; } Point HorizontalTrack::getPosition ( DbU::Unit coordinate ) const @@ -81,4 +73,4 @@ namespace Kite { } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/KiteEngine.cpp b/kite/src/KiteEngine.cpp index b1586d29..d90cdbc2 100644 --- a/kite/src/KiteEngine.cpp +++ b/kite/src/KiteEngine.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -15,49 +14,49 @@ // +-----------------------------------------------------------------+ -#include -#include -#include - -#include "hurricane/DebugSession.h" -#include "hurricane/Bug.h" -#include "hurricane/Error.h" -#include "hurricane/Warning.h" -#include "hurricane/Breakpoint.h" -#include "hurricane/Layer.h" -#include "hurricane/Net.h" -#include "hurricane/Pad.h" -#include "hurricane/Plug.h" -#include "hurricane/Cell.h" -#include "hurricane/Instance.h" -#include "hurricane/Vertical.h" -#include "hurricane/Horizontal.h" -#include "hurricane/UpdateSession.h" -#include "crlcore/Measures.h" -#include "knik/Vertex.h" -#include "knik/Edge.h" -#include "knik/Graph.h" -#include "knik/KnikEngine.h" -#include "katabatic/AutoContact.h" -#include "katabatic/GCellGrid.h" -#include "kite/DataNegociate.h" -#include "kite/RoutingPlane.h" -#include "kite/Session.h" -#include "kite/NegociateWindow.h" -#include "kite/KiteEngine.h" +#include +#include +#include +#include "hurricane/DebugSession.h" +#include "hurricane/Bug.h" +#include "hurricane/Error.h" +#include "hurricane/Warning.h" +#include "hurricane/Breakpoint.h" +#include "hurricane/Layer.h" +#include "hurricane/Net.h" +#include "hurricane/Pad.h" +#include "hurricane/Plug.h" +#include "hurricane/Cell.h" +#include "hurricane/Instance.h" +#include "hurricane/Vertical.h" +#include "hurricane/Horizontal.h" +#include "hurricane/UpdateSession.h" +#include "crlcore/Measures.h" +#include "knik/Vertex.h" +#include "knik/Edge.h" +#include "knik/Graph.h" +#include "knik/KnikEngine.h" +#include "katabatic/AutoContact.h" +#include "katabatic/GCellGrid.h" +#include "kite/DataNegociate.h" +#include "kite/RoutingPlane.h" +#include "kite/Session.h" +#include "kite/NegociateWindow.h" +#include "kite/KiteEngine.h" namespace Kite { - using std::cout; using std::cerr; using std::endl; using std::setw; using std::left; + using std::ostream; using std::ofstream; using std::ostringstream; using std::setprecision; + using std::vector; using Hurricane::DebugSession; using Hurricane::tab; using Hurricane::inltrace; @@ -68,6 +67,7 @@ namespace Kite { using Hurricane::Error; using Hurricane::Warning; using Hurricane::Breakpoint; + using Hurricane::Box; using Hurricane::Torus; using Hurricane::Layer; using Hurricane::Cell; @@ -76,6 +76,7 @@ namespace Kite { using CRL::MeasuresSet; using Knik::KnikEngine; using Katabatic::AutoContact; + using Katabatic::AutoSegmentLut; using Katabatic::ChipTools; @@ -87,7 +88,6 @@ namespace Kite { // ------------------------------------------------------------------- // Class : "Kite::KiteEngine". - Name KiteEngine::_toolName = "Kite"; @@ -96,24 +96,19 @@ namespace Kite { KiteEngine* KiteEngine::get ( const Cell* cell ) - { - return static_cast(ToolEngine::get(cell,staticGetName())); - } + { return static_cast(ToolEngine::get(cell,staticGetName())); } KiteEngine::KiteEngine ( Cell* cell ) - : KatabaticEngine (cell) - , _knik (NULL) - , _blockageNet (NULL) - , _configuration (new Configuration(getKatabaticConfiguration())) - , _routingPlanes () - , _negociateWindow (NULL) - , _trackSegmentLut () - , _minimumWL (0.0) - , _toolSuccess (false) - { - //_configuration->setAllowedDepth ( 3 ); - } + : KatabaticEngine (cell) + , _knik (NULL) + , _blockageNet (NULL) + , _configuration (new Configuration(getKatabaticConfiguration())) + , _routingPlanes () + , _negociateWindow(NULL) + , _minimumWL (0.0) + , _toolSuccess (false) + { } void KiteEngine::_postCreate () @@ -123,9 +118,9 @@ namespace Kite { #ifdef KNIK_NOT_EMBEDDED size_t maxDepth = getRoutingGauge()->getDepth(); - _routingPlanes.reserve ( maxDepth ); + _routingPlanes.reserve( maxDepth ); for ( size_t depth=0 ; depth < maxDepth ; depth++ ) { - _routingPlanes.push_back ( RoutingPlane::create ( this, depth ) ); + _routingPlanes.push_back( RoutingPlane::create( this, depth ) ); } #endif } @@ -135,37 +130,45 @@ namespace Kite { { KiteEngine* kite = new KiteEngine ( cell ); - kite->_postCreate (); + kite->_postCreate(); return kite; } void KiteEngine::_preDestroy () { - ltrace(90) << "KiteEngine::_preDestroy ()" << endl; + ltrace(90) << "KiteEngine::_preDestroy()" << endl; ltracein(90); cmess1 << " o Deleting ToolEngine<" << getName() << "> from Cell <" << _cell->getName() << ">" << endl; - if ( getState() < Katabatic::StateGutted ) - setState ( Katabatic::StatePreDestroying ); + if (getState() < Katabatic::EngineGutted) + setState( Katabatic::EnginePreDestroying ); - _gutKite (); - KatabaticEngine::_preDestroy (); + _gutKite(); + KatabaticEngine::_preDestroy(); cmess2 << " - RoutingEvents := " << RoutingEvent::getAllocateds() << endl; - _knik->destroy (); + if (not ToolEngine::inDestroyAll()) { + KnikEngine* attachedKnik = KnikEngine::get( getCell() ); + + if (_knik != attachedKnik) { + cerr << Error("Knik attribute differs from the Cell attached one (must be the same)\n" + " On: <%s>." + ,getString(getCell()->getName()).c_str()) << endl; + _knik = attachedKnik; + } + _knik->destroy(); + } ltraceout(90); } KiteEngine::~KiteEngine () - { - delete _configuration; - } + { delete _configuration; } const Name& KiteEngine::getName () const @@ -178,24 +181,23 @@ namespace Kite { unsigned int KiteEngine::getRipupLimit ( const TrackElement* segment ) const { - if ( segment->isBlockage() ) return 0; + if (segment->isBlockage()) return 0; - if ( segment->isStrap () ) return _configuration->getRipupLimit(Configuration::StrapRipupLimit); - if ( segment->isGlobal() ) { + if (segment->isStrap ()) return _configuration->getRipupLimit( Configuration::StrapRipupLimit ); + if (segment->isGlobal()) { Katabatic::GCellVector gcells; - segment->getGCells(gcells); - if ( gcells.size() > 2 ) - return _configuration->getRipupLimit(Configuration::LongGlobalRipupLimit); - return _configuration->getRipupLimit(Configuration::GlobalRipupLimit); + segment->getGCells( gcells ); + if (gcells.size() > 2) + return _configuration->getRipupLimit( Configuration::LongGlobalRipupLimit ); + return _configuration->getRipupLimit( Configuration::GlobalRipupLimit ); } - return _configuration->getRipupLimit(Configuration::LocalRipupLimit); + return _configuration->getRipupLimit( Configuration::LocalRipupLimit ); } RoutingPlane* KiteEngine::getRoutingPlaneByIndex ( size_t index ) const { - if ( index >= getRoutingPlanesSize() ) return NULL; - + if (index >= getRoutingPlanesSize() ) return NULL; return _routingPlanes[index]; } @@ -203,7 +205,7 @@ namespace Kite { RoutingPlane* KiteEngine::getRoutingPlaneByLayer ( const Layer* layer ) const { for ( size_t index=0 ; index < getRoutingPlanesSize() ; index++ ) { - if ( _routingPlanes[index]->getLayer() == layer ) + if (_routingPlanes[index]->getLayer() == layer) return _routingPlanes[index]; } return NULL; @@ -212,17 +214,17 @@ namespace Kite { Track* KiteEngine::getTrackByPosition ( const Layer* layer, DbU::Unit axis, unsigned int mode ) const { - RoutingPlane* plane = getRoutingPlaneByLayer ( layer ); - if ( !plane ) return NULL; + RoutingPlane* plane = getRoutingPlaneByLayer( layer ); + if (not plane) return NULL; - return plane->getTrackByPosition ( axis, mode ); + return plane->getTrackByPosition( axis, mode ); } void KiteEngine::setInterrupt ( bool state ) { - if ( _negociateWindow ) { - _negociateWindow->setInterrupt ( state ); + if (_negociateWindow) { + _negociateWindow->setInterrupt( state ); cerr << "Interrupt [CRTL+C] of " << this << endl; } } @@ -232,67 +234,62 @@ namespace Kite { { Cell* cell = getCell(); Box cellBb = cell->getBoundingBox(); - if ( not _knik ) { - //if ( cell->getRubbers().getFirst() == NULL ) - cell->flattenNets ( (mode==BuildGlobalSolution) ); - - //Breakpoint::stop ( 0, "Point d'arret:
      createGlobalGraph() " - // "after net virtual flattening." ); - - KatabaticEngine::chipPrep (); - - KnikEngine::setEdgeCapacityPercent ( 1.0 ); - _knik = KnikEngine::create ( cell - , 1 // _congestion - , 2 // _preCongestion - , false // _benchMode - , true // _useSegments - , 2.5 // _edgeCost - ); - //if ( mode == LoadGlobalSolution ) - _knik->createRoutingGraph (); - KnikEngine::setEdgeCapacityPercent ( getEdgeCapacityPercent() ); - + if (not _knik) { + cell->flattenNets( mode & KtBuildGlobalRouting ); + + KatabaticEngine::chipPrep(); + + KnikEngine::setEdgeCapacityPercent( 1.0 ); + _knik = KnikEngine::create( cell + , 1 // _congestion + , 2 // _preCongestion + , false // _benchMode + , true // _useSegments + , 2.5 // _edgeCost + ); + _knik->createRoutingGraph(); + KnikEngine::setEdgeCapacityPercent( getEdgeCapacityPercent() ); + // Decrease the edge's capacity only under the core area. const ChipTools& chipTools = getChipTools(); float corePercent = getEdgeCapacityPercent(); float coronaPercent = 0.80; - + forEach ( Knik::Vertex*, ivertex, _knik->getRoutingGraph()->getVertexes() ) { for ( int i=0 ; i<2 ; ++i ) { Knik::Edge* edge = NULL; bool isVEdge = false; - - if ( i==0 ) { + + if (i==0) { edge = ivertex->getHEdgeOut(); - if ( not edge ) continue; - - if ( chipTools.intersectHPads(edge->getBoundingBox()) ) { - edge->setCapacity ( 0 ); + if (not edge) continue; + + if (chipTools.intersectHPads(edge->getBoundingBox())) { + edge->setCapacity( 0 ); continue; } isVEdge = false; } else { edge = ivertex->getVEdgeOut(); - if ( not edge ) continue; - - if ( chipTools.intersectVPads(edge->getBoundingBox()) ) { - edge->setCapacity ( 0 ); + if (not edge) continue; + + if (chipTools.intersectVPads(edge->getBoundingBox())) { + edge->setCapacity( 0 ); continue; } isVEdge = true; } - + float edgePercent = 1.00; - if ( chipTools.getCorona().getInnerBox().contains(edge->getBoundingBox()) ) { + if (chipTools.getCorona().getInnerBox().contains(edge->getBoundingBox())) { edgePercent = corePercent; - } else if ( chipTools.getCorona().getOuterBox().contains(edge->getBoundingBox()) ) { + } else if (chipTools.getCorona().getOuterBox().contains(edge->getBoundingBox())) { edgePercent = coronaPercent; isVEdge = false; } - + unsigned int capacity = (unsigned int)(edge->getCapacity() * edgePercent ) - ((isVEdge) ? 1 : 0); - edge->setCapacity ( capacity ); + edge->setCapacity( capacity ); } } } @@ -301,26 +298,26 @@ namespace Kite { void KiteEngine::createDetailedGrid () { - KatabaticEngine::createDetailedGrid (); + KatabaticEngine::createDetailedGrid(); size_t maxDepth = getRoutingGauge()->getDepth(); - _routingPlanes.reserve ( maxDepth ); + _routingPlanes.reserve( maxDepth ); for ( size_t depth=0 ; depth < maxDepth ; depth++ ) { - _routingPlanes.push_back ( RoutingPlane::create ( this, depth ) ); + _routingPlanes.push_back( RoutingPlane::create ( this, depth ) ); } } void KiteEngine::saveGlobalSolution () { - if ( getState() < Katabatic::StateGlobalLoaded ) - throw Error ("KiteEngine::saveGlobalSolution() : global routing not present yet."); + if (getState() < Katabatic::EngineGlobalLoaded) + throw Error ("KiteEngine::saveGlobalSolution(): Global routing not present yet."); - if ( getState() > Katabatic::StateGlobalLoaded ) - throw Error ("KiteEngine::saveGlobalSolution() : cannot save after detailed routing."); + if (getState() > Katabatic::EngineGlobalLoaded) + throw Error ("KiteEngine::saveGlobalSolution(): Cannot save after detailed routing."); - _knik->saveSolution (); + _knik->saveSolution(); } @@ -334,28 +331,27 @@ namespace Kite { int vEdgeCapacity = 0; for ( size_t depth=0 ; depth<_routingPlanes.size() ; ++depth ) { RoutingPlane* rp = _routingPlanes[depth]; - if ( rp->getLayerGauge()->getType() == Constant::PinOnly ) continue; + if (rp->getLayerGauge()->getType() == Constant::PinOnly ) continue; - if ( rp->getDirection() == Constant::Horizontal ) ++hEdgeCapacity; + if (rp->getDirection() == KbHorizontal) ++hEdgeCapacity; else ++vEdgeCapacity; } for ( size_t depth=0 ; depth<_routingPlanes.size() ; ++depth ) { RoutingPlane* rp = _routingPlanes[depth]; - if ( rp->getLayerGauge()->getType() == Constant::PinOnly ) continue; + if (rp->getLayerGauge()->getType() == Constant::PinOnly ) continue; size_t tracksSize = rp->getTracksSize(); for ( size_t itrack=0 ; itrackgetTrackByIndex ( itrack ); - //Knik::Edge* edge = NULL; ltrace(300) << "Capacity from: " << track << endl; - if ( track->getDirection() == Constant::Horizontal ) { + if (track->getDirection() == KbHorizontal) { for ( size_t ielement=0 ; ielementgetSize() ; ++ielement ) { - TrackElement* element = track->getSegment ( ielement ); - - if ( element->getNet() == NULL ) { + TrackElement* element = track->getSegment( ielement ); + + if (element->getNet() == NULL) { ltrace(300) << "Reject capacity from (not Net): " << (void*)element << ":" << element << endl; continue; } @@ -370,35 +366,30 @@ namespace Kite { ltrace(300) << "Capacity from: " << (void*)element << ":" << element << ":" << elementCapacity << endl; - Katabatic::GCell* gcell = getGCellGrid()->getGCell ( Point(element->getSourceU(),track->getAxis()) ); - Katabatic::GCell* end = getGCellGrid()->getGCell ( Point(element->getTargetU(),track->getAxis()) ); + Katabatic::GCell* gcell = getGCellGrid()->getGCell( Point(element->getSourceU(),track->getAxis()) ); + Katabatic::GCell* end = getGCellGrid()->getGCell( Point(element->getTargetU(),track->getAxis()) ); Katabatic::GCell* right = NULL; - if ( not gcell ) { + if (not gcell) { cerr << Warning("annotageGlobalGraph(): TrackElement outside GCell grid.") << endl; continue; } while ( gcell and (gcell != end) ) { right = gcell->getRight(); - if ( right == NULL ) break; - _knik->increaseEdgeCapacity ( gcell->getColumn() - , gcell->getRow() - , right->getColumn() - , right->getRow() - , elementCapacity ); - // edge = _knik->getEdge ( gcell->getColumn() - // , gcell->getRow() - // , right->getColumn() - // , right->getRow() - // ); + if (right == NULL) break; + _knik->increaseEdgeCapacity( gcell->getColumn() + , gcell->getRow() + , right->getColumn() + , right->getRow() + , elementCapacity ); gcell = right; } } } else { for ( size_t ielement=0 ; ielementgetSize() ; ++ielement ) { - TrackElement* element = track->getSegment ( ielement ); + TrackElement* element = track->getSegment( ielement ); - if ( element->getNet() == NULL ) { + if (element->getNet() == NULL) { ltrace(300) << "Reject capacity from (not Net): " << (void*)element << ":" << element << endl; continue; } @@ -413,26 +404,21 @@ namespace Kite { ltrace(300) << "Capacity from: " << (void*)element << ":" << element << ":" << elementCapacity << endl; - Katabatic::GCell* gcell = getGCellGrid()->getGCell ( Point(track->getAxis(),element->getSourceU()) ); - Katabatic::GCell* end = getGCellGrid()->getGCell ( Point(track->getAxis(),element->getTargetU()) ); + Katabatic::GCell* gcell = getGCellGrid()->getGCell( Point(track->getAxis(),element->getSourceU()) ); + Katabatic::GCell* end = getGCellGrid()->getGCell( Point(track->getAxis(),element->getTargetU()) ); Katabatic::GCell* up = NULL; - if ( not gcell ) { + if (not gcell) { cerr << Warning("annotageGlobalGraph(): TrackElement outside GCell grid.") << endl; continue; } while ( gcell and (gcell != end) ) { up = gcell->getUp(); - if ( up == NULL ) break; - _knik->increaseEdgeCapacity ( gcell->getColumn() - , gcell->getRow() - , up->getColumn() - , up->getRow() - , elementCapacity ); - // edge = _knik->getEdge ( gcell->getColumn() - // , gcell->getRow() - // , up->getColumn() - // , up->getRow() - // ); + if (up == NULL) break; + _knik->increaseEdgeCapacity( gcell->getColumn() + , gcell->getRow() + , up->getColumn() + , up->getRow() + , elementCapacity ); gcell = up; } } @@ -444,167 +430,142 @@ namespace Kite { void KiteEngine::runGlobalRouter ( unsigned int mode ) { - if ( getState() >= Katabatic::StateGlobalLoaded ) - throw Error ("KiteEngine::runGlobalRouter() : global routing already done or loaded."); + if (getState() >= Katabatic::EngineGlobalLoaded) + throw Error ("KiteEngine::runGlobalRouter(): Global routing already done or loaded."); - Session::open ( this ); + Session::open( this ); - createGlobalGraph ( mode ); + createGlobalGraph( mode ); - //DebugSession::addToTrace ( getCell(), "nb(0)" ); - //DebugSession::addToTrace ( getCell(), "ram_adri(0)" ); - //DebugSession::addToTrace ( getCell(), "rsdnbr_sd(9)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_1m_dp_res_re(21)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_1m_dp_soper_se(20)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_1m_dp_res_re(20)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_1m_dp_addsub32_carith_se_gi_1_29" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.instaddbracry_sd.gi_1_29" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.instseqadr_sd.pi_2_18" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.instseqadr_sd.gi_0_18" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.instseqadr_sd.gi_2_18" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.instseqadr_sd.gi_1_17" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_1m_dp_res_se(28)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.etat32_otheri_sd_2.enx" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.yoper_se(31)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.toper_se(5)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.toper_rd(24)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.soper_se(20)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.shift32_rshift_se.muxoutput(67)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.shift32_rshift_se.muxoutput(71)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.imdsgn_sd0" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.res_re(12)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.res_re(20)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.nextpc_rd(21)" ); - //DebugSession::addToTrace ( getCell(), "addr_i(1)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.otheri_sd(29)" ); - //DebugSession::addToTrace ( getCell(), "d_in_i(22)" ); - //DebugSession::addToTrace ( getCell(), "ng_i" ); - //DebugSession::addToTrace ( getCell(), "d_out_i(14)" ); - //DebugSession::addToTrace ( getCell(), "d_out_i(19)" ); - //DebugSession::addToTrace ( getCell(), "dout_e_i(1)" ); - //DebugSession::addToTrace ( getCell(), "dout_e_i(2)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.aux78" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.nxr2_x1_2_sig" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.na4_x1_23_sig" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.ao22_x2_38_sig" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.ao22_x2_sig" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.rsdnbr_sd(25)" ); - //DebugSession::addToTrace ( getCell(), "d_out_i(28)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_1m_ct_mbk_buf_opcod_sd_0" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.break_re" ); - //DebugSession::addToTrace ( getCell(), "d_atype_i(0)" ); - //DebugSession::addToTrace ( getCell(), "addr_i(7)" ); - //DebugSession::addToTrace ( getCell(), "addr_i(8)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.break_re" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.opcod_sd_2" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_opcod_sd_1" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.opcod_rd(1)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.i_write_sm" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_i_ri(29)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_opcod_rd(0)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_opcod_sd_3" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.opcod_sd_5" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.no4_x1_7_sig" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.on12_x1_15_sig" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.na3_x1_46_sig" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.o2_x2_11_sig" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.nextsr_rx(27)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_wsr_sm" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.i_ri(5)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_aux144" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_aux143" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_aux61" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.aux4" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_hold_si" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_i_ri(30)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.data_rm(0)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.toper_se(0)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.res_se(17)" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.pi_2_22" ); - //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.pi_2_23" ); - // DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.pi_4_24" ); - // DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.pi_4_28" ); - // DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.gi_1_25" ); - // //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.gi_2_23" ); - // //DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.gi_0_28" ); - // // NO MOVE UP FOR IT... - // DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.gi_3_23" ); - // DebugSession::addToTrace ( getCell(), "mips_r3000_core.mips_r3000_1m_dp.addsub32_carith_se.gi_3_28" ); - //DebugSession::addToTrace ( getCell(), "cout_to_pads" ); - //DebugSession::addToTrace ( getCell(), "mux_5.sel0" ); - //DebugSession::addToTrace ( getCell(), "wm_rf.nandr0" ); - //DebugSession::addToTrace ( getCell(), "adder_sub.gi_2_18" ); - //DebugSession::addToTrace ( getCell(), "adder_sub.pi_3_20" ); - //DebugSession::addToTrace ( getCell(), "core.iram.na4_x1_2_sig" ); - //DebugSession::addToTrace ( getCell(), "core.ialu.mx3_x2_4_sig" ); + // Test signals from . + //DebugSession::addToTrace( getCell(), "auxsc37" ); + // Test signals from . + //DebugSession::addToTrace( getCell(), "acc_reg_ckx" ); + //DebugSession::addToTrace( getCell(), "acc_reg_nckx" ); + //DebugSession::addToTrace( getCell(), "i(0)" ); + //DebugSession::addToTrace( getCell(), "ram_adrb_14" ); + //DebugSession::addToTrace( getCell(), "ram_adrb_9" ); + //DebugSession::addToTrace( getCell(), "ram_adra(11)" ); + //DebugSession::addToTrace( getCell(), "ram_adra(7)" ); + //DebugSession::addToTrace( getCell(), "ram_adrb(8)" ); + //DebugSession::addToTrace( getCell(), "alu_carry(1)" ); + //DebugSession::addToTrace( getCell(), "alu_np(0)" ); + //DebugSession::addToTrace( getCell(), "ram_d(3)" ); + //DebugSession::addToTrace( getCell(), "ram_q1(0)" ); + //DebugSession::addToTrace( getCell(), "ram_i_up" ); + // Test signals from (M1-VLSI). + //DebugSession::addToTrace( getCell(), "zero_to_pads" ); + //DebugSession::addToTrace( getCell(), "shift_r" ); + // Test signals from (R3000,micro-programmed). + //DebugSession::addToTrace( getCell(), "scout" ); + //DebugSession::addToTrace( getCell(), "adr_1_n" ); + //DebugSession::addToTrace( getCell(), "codop_18" ); + //DebugSession::addToTrace( getCell(), "frz_ctl(10)" ); + //DebugSession::addToTrace( getCell(), "ctl_seq_mbk_not_ep_80" ); + //DebugSession::addToTrace( getCell(), "ctl_sts_mbk_not_ctlrw_in_2" ); + //DebugSession::addToTrace( getCell(), "dpt_wm_rf_adr4x" ); + //DebugSession::addToTrace( getCell(), "crsrin_1" ); + //DebugSession::addToTrace( getCell(), "ctl_seq_oa2ao222_x2_2" ); + //DebugSession::addToTrace( getCell(), "dpt_ishifter_muxoutput_81" ); + //DebugSession::addToTrace( getCell(), "ctl_seq_mbk_not_ep_7" ); + //DebugSession::addToTrace( getCell(), "ctl_sts_mbk_not_adel_r" ); + //DebugSession::addToTrace( getCell(), "ctl_seq_no2_x1_88" ); + //DebugSession::addToTrace( getCell(), "ctl_seq_ep_31" ); + //DebugSession::addToTrace( getCell(), "dpt_opyir16ins_mxn1" ); + //DebugSession::addToTrace( getCell(), "dpt_ishifter_muxoutput_132" ); + // Test signals from (R3000,pipeline). + //DebugSession::addToTrace( getCell(), "nb(0)" ); + //DebugSession::addToTrace( getCell(), "mips_r3000_1m_dp_mux32_data_e_sm_sel0" ); + //DebugSession::addToTrace( getCell(), "mips_r3000_1m_dp_lo_rw(16)" ); + //DebugSession::addToTrace( getCell(), "mips_r3000_1m_dp_hi_rw(27)" ); + //DebugSession::addToTrace( getCell(), "mips_r3000_1m_dp_data_e_sm(25)" ); + //DebugSession::addToTrace( getCell(), "mips_r3000_1m_dp_nul_s_eq_z_sd_nul_3" ); + //DebugSession::addToTrace( getCell(), "mips_r3000_1m_dp_shift32_rshift_se_muxoutput(143)" ); + //DebugSession::addToTrace( getCell(), "rsdnbr_sd(19)" ); + //DebugSession::addToTrace( getCell(), "mips_r3000_1m_dp_res_se(14)" ); + //DebugSession::addToTrace( getCell(), "mips_r3000_1m_dp_res_re(0)" ); + //DebugSession::addToTrace( getCell(), "wreg_sw(1)" ); + //DebugSession::addToTrace( getCell(), "mips_r3000_1m_dp_shift32_rshift_se_msb" ); + //DebugSession::addToTrace( getCell(), "mips_r3000_1m_ct_mx2_x2_2_sig" ); + //DebugSession::addToTrace( getCell(), "mips_r3000_1m_dp_mux32_s_mw_se_sel0" ); + //DebugSession::addToTrace( getCell(), "mips_r3000_1m_dp_mux32_badr_sd_sel1" ); + //DebugSession::addToTrace( getCell(), "mips_r3000_1m_dp_addsub32_carith_se_pi_3_21" ); + //Test signals from (R3000,pipeline+chip). + //DebugSession::addToTrace( getCell(), "mips_r3000_core.mips_r3000_1m_dp.banc.reada0" ); + //DebugSession::addToTrace( getCell(), "mips_r3000_core.mips_r3000_1m_ct.i_ri(29)" ); + //DebugSession::addToTrace( getCell(), "mips_r3000_core.mips_r3000_1m_ct.not_opcod_re(4)" ); + //DebugSession::addToTrace( getCell(), "d_out_i(10)" ); + //DebugSession::addToTrace( getCell(), "dout_e_i(0)" ); + //DebugSession::addToTrace( getCell(), "dout_e_i(1)" ); + //DebugSession::addToTrace( getCell(), "dout_e_i(2)" ); + //DebugSession::addToTrace( getCell(), "i_ack_i" ); + //DebugSession::addToTrace( getCell(), "mips_r3000_core.mips_r3000_1m_dp.data_rm(7)" ); - createDetailedGrid (); - buildPowerRails (); - protectRoutingPads (); + createDetailedGrid(); + buildPowerRails(); + protectRoutingPads(); - Session::revalidate (); + Session::revalidate(); - if ( mode == LoadGlobalSolution ) { - _knik->loadSolution (); + if (mode & KtLoadGlobalRouting) { + _knik->loadSolution(); } else { - annotateGlobalGraph (); - _knik->run (); + annotateGlobalGraph(); + _knik->run(); } - setState ( Katabatic::StateGlobalLoaded ); + setState( Katabatic::EngineGlobalLoaded ); - Session::close (); + Session::close(); } - + void KiteEngine::loadGlobalRouting ( unsigned int method, KatabaticEngine::NetSet& nets ) { - KatabaticEngine::loadGlobalRouting ( method, nets ); + KatabaticEngine::loadGlobalRouting( method, nets ); - Session::open ( this ); - //KatabaticEngine::chipPrep (); - getGCellGrid()->checkEdgeSaturation ( getEdgeCapacityPercent() ); - Session::close (); + Session::open( this ); + getGCellGrid()->checkEdgeSaturation( getEdgeCapacityPercent() ); + Session::close(); } void KiteEngine::runNegociate ( unsigned int slowMotion ) { - if ( _negociateWindow ) return; + if (_negociateWindow) return; - startMeasures (); + startMeasures(); - Session::open ( this ); + Session::open( this ); - _negociateWindow = NegociateWindow::create ( this ); - _negociateWindow->setGCells ( *(getGCellGrid()->getGCellVector()) ); - preProcess (); - _computeCagedConstraints (); - _negociateWindow->run ( slowMotion ); - _negociateWindow->printStatistics (); - _negociateWindow->destroy (); + _negociateWindow = NegociateWindow::create( this ); + _negociateWindow->setGCells( *(getGCellGrid()->getGCellVector()) ); + _computeCagedConstraints(); + _negociateWindow->run( slowMotion ); + _negociateWindow->printStatistics(); + _negociateWindow->destroy(); _negociateWindow = NULL; - Session::close (); + Session::close(); //if ( _editor ) _editor->refresh (); - stopMeasures (); - printMeasures ( "algo" ); - printCompletion (); + stopMeasures(); + printMeasures( "algo" ); - Session::open ( this ); + Session::open( this ); unsigned int overlaps = 0; float edgeCapacity = 1.0; - KnikEngine* knik = KnikEngine::get ( getCell() ); + KnikEngine* knik = KnikEngine::get( getCell() ); - if ( knik ) - edgeCapacity = knik->getEdgeCapacityPercent(); + if (knik) edgeCapacity = knik->getEdgeCapacityPercent(); - cmess2 << " o Post-checking Knik capacity overload " << (edgeCapacity*100.0) << "%." << endl; + if (cparanoid.enabled()) { + cparanoid << " o Post-checking Knik capacity overload " << (edgeCapacity*100.0) << "%." << endl; + getGCellGrid()->checkEdgeSaturation( edgeCapacity ); + } - getGCellGrid()->checkEdgeSaturation ( edgeCapacity ); - _check ( overlaps ); - Session::close (); + _check( overlaps ); + Session::close(); _toolSuccess = _toolSuccess and (overlaps == 0); } @@ -612,94 +573,106 @@ namespace Kite { void KiteEngine::printCompletion () const { - cmess1 << " o Computing Completion ratios." << endl; - cmess1 << " - Unrouted segments :" << endl; + size_t routeds = 0; + unsigned long long totalWireLength = 0; + unsigned long long routedWireLength = 0; + vector unrouteds; + ostringstream result; - size_t routeds = 0; - size_t unrouteds = 0; - unsigned long long totalWireLength = 0; - unsigned long long routedWireLength = 0; + AutoSegmentLut::const_iterator ilut = _getAutoSegmentLut().begin(); + for ( ; ilut != _getAutoSegmentLut().end() ; ilut++ ) { + TrackElement* segment = _lookup( ilut->second ); + if (segment == NULL) continue; - TrackElementLut::const_iterator ilut = _trackSegmentLut.begin(); - for ( ; ilut != _trackSegmentLut.end() ; ilut++ ) { - unsigned long long wl = (unsigned long long)DbU::getLambda(ilut->second->getLength()); - if ( wl > 100000 ) { + unsigned long long wl = (unsigned long long)DbU::getLambda( segment->getLength() ); + if (wl > 100000) { cerr << Error("KiteEngine::printCompletion(): Suspiciously long wire: %llu for %p:%s" - ,wl,ilut->first,getString(ilut->second).c_str()) << endl; + ,wl,ilut->first,getString(segment).c_str()) << endl; continue; } + + if (segment->isFixed() or segment->isBlockage()) continue; + totalWireLength += wl; - if ( ilut->second->getTrack() != NULL ) { + if (segment->getTrack() != NULL) { routeds++; routedWireLength += wl; } else { - cout << " " << setw(4) << ++unrouteds << "| " << ilut->second << endl; + unrouteds.push_back( segment ); } } - float segmentRatio = (float)(routeds) / (float)(_trackSegmentLut.size()) * 100.0; - float wireLengthRatio = (float)(routedWireLength) / (float)(totalWireLength) * 100.0; + float segmentRatio = (float)(routeds) / (float)(routeds+unrouteds.size()) * 100.0; + float wireLengthRatio = (float)(routedWireLength) / (float)(totalWireLength) * 100.0; - cmess1 << " - Track Segment Completion Ratio := " - << setprecision(4) << segmentRatio - << "% [" << routeds << "/" << _trackSegmentLut.size() << "] " - << (_trackSegmentLut.size() - routeds) << " remains." << endl; - cmess1 << " - Wire Length Completion Ratio := " - << setprecision(4) << wireLengthRatio - << "% [" << totalWireLength << "] " - << (totalWireLength - routedWireLength) << " remains." << endl; + result << setprecision(4) << segmentRatio + << "% [" << routeds << "+" << unrouteds.size() << "]"; + cmess1 << Dots::asString( " - Track Segment Completion Ratio", result.str() ) << endl; + + result.str(""); + result << setprecision(4) << wireLengthRatio + << "% [" << totalWireLength << "+" + << (totalWireLength - routedWireLength) << "]"; + cmess1 << Dots::asString( " - Wire Length Completion Ratio", result.str() ) << endl; float expandRatio = 1.0; - if ( _minimumWL != 0.0 ) { + if (_minimumWL != 0.0) { expandRatio = ((totalWireLength-_minimumWL) / _minimumWL) * 100.0; - cmess1 << " - Wire Length Expand Ratio := " - << setprecision(3) << expandRatio - << "% [min:" << setprecision(9) << _minimumWL << "] " - << endl; + + result.str(""); + result << setprecision(3) << expandRatio << "% [min:" << setprecision(9) << _minimumWL << "]"; + cmess1 << Dots::asString( " - Wire Length Expand Ratio", result.str() ) << endl; } - _toolSuccess = (unrouteds == 0); + _toolSuccess = (unrouteds.empty()); - addMeasure ( getCell(), "Segs" , routeds+unrouteds ); - addMeasure ( getCell(), "DWL(l)" , totalWireLength , 12 ); - addMeasure ( getCell(), "fWL(l)" , totalWireLength-routedWireLength , 12); - addMeasure ( getCell(), "WLER(%)", (expandRatio-1.0)*100.0 ); - } + if (not unrouteds.empty()) { + cerr << " o Routing did not complete, unrouted segments:" << endl; + for ( size_t i=0; i ( getCell(), "Segs" , routeds+unrouteds.size() ); + addMeasure( getCell(), "DWL(l)" , totalWireLength , 12 ); + addMeasure( getCell(), "fWL(l)" , totalWireLength-routedWireLength , 12 ); + addMeasure ( getCell(), "WLER(%)", (expandRatio-1.0)*100.0 ); +} void KiteEngine::dumpMeasures ( ostream& out ) const { vector measuresLabels; - measuresLabels.push_back ( "Gates" ); - measuresLabels.push_back ( "GCells" ); - measuresLabels.push_back ( "knikT" ); - measuresLabels.push_back ( "knikS" ); - measuresLabels.push_back ( "GWL(l)" ); - measuresLabels.push_back ( "Area(l2)"); - measuresLabels.push_back ( "Sat." ); - measuresLabels.push_back ( "loadT" ); - measuresLabels.push_back ( "loadS" ); - measuresLabels.push_back ( "Globals" ); - measuresLabels.push_back ( "Edges" ); - measuresLabels.push_back ( "assignT" ); - measuresLabels.push_back ( "algoT" ); - measuresLabels.push_back ( "algoS" ); - measuresLabels.push_back ( "finT" ); - measuresLabels.push_back ( "Segs" ); - measuresLabels.push_back ( "DWL(l)" ); - measuresLabels.push_back ( "fWL(l)" ); - measuresLabels.push_back ( "WLER(%)" ); - measuresLabels.push_back ( "Events" ); - measuresLabels.push_back ( "UEvents" ); + measuresLabels.push_back( "Gates" ); + measuresLabels.push_back( "GCells" ); + measuresLabels.push_back( "knikT" ); + measuresLabels.push_back( "knikS" ); + measuresLabels.push_back( "GWL(l)" ); + measuresLabels.push_back( "Area(l2)"); + measuresLabels.push_back( "Sat." ); + measuresLabels.push_back( "loadT" ); + measuresLabels.push_back( "loadS" ); + measuresLabels.push_back( "Globals" ); + measuresLabels.push_back( "Edges" ); + measuresLabels.push_back( "assignT" ); + measuresLabels.push_back( "algoT" ); + measuresLabels.push_back( "algoS" ); + measuresLabels.push_back( "finT" ); + measuresLabels.push_back( "Segs" ); + measuresLabels.push_back( "DWL(l)" ); + measuresLabels.push_back( "fWL(l)" ); + measuresLabels.push_back( "WLER(%)" ); + measuresLabels.push_back( "Events" ); + measuresLabels.push_back( "UEvents" ); - const MeasuresSet* measures = Measures::get(getCell()); + const MeasuresSet* measures = Measures::get( getCell() ); out << "#" << endl; out << "# " << getCell()->getName() << endl; out << measures->toStringHeaders(measuresLabels) << endl; out << measures->toStringDatas (measuresLabels) << endl; - measures->toGnuplot ( "GCells Density Histogram", getString(getCell()->getName()) ); + measures->toGnuplot( "GCells Density Histogram", getString(getCell()->getName()) ); } @@ -709,8 +682,8 @@ namespace Kite { path << getCell()->getName() << ".knik-kite.dat"; ofstream sfile ( path.str().c_str() ); - dumpMeasures ( sfile ); - sfile.close (); + dumpMeasures( sfile ); + sfile.close(); } @@ -719,33 +692,28 @@ namespace Kite { cmess1 << " o Checking Kite Database coherency." << endl; bool coherency = true; - coherency = coherency && KatabaticEngine::_check ( message ); + coherency = coherency and KatabaticEngine::_check( message ); for ( size_t i=0 ; i<_routingPlanes.size() ; i++ ) coherency = _routingPlanes[i]->_check(overlap) and coherency; Katabatic::Session* ktbtSession = Session::base (); forEach ( Net*, inet, getCell()->getNets() ) { forEach ( Segment*, isegment, inet->getComponents().getSubSet() ) { - AutoSegment* autoSegment = ktbtSession->lookup ( *isegment ); - if ( not autoSegment ) continue; - if ( not autoSegment->isCanonical() ) continue; + AutoSegment* autoSegment = ktbtSession->lookup( *isegment ); + if (not autoSegment) continue; + if (not autoSegment->isCanonical()) continue; - TrackElement* trackSegment = Session::lookup ( *isegment ); - if ( not trackSegment ) { + TrackElement* trackSegment = Session::lookup( *isegment ); + if (not trackSegment) { coherency = false; - cerr << Bug("%p %s without Track Segment" - ,autoSegment - ,getString(autoSegment).c_str() - ) << endl; + cerr << Bug( "%p %s without Track Segment" + , autoSegment + , getString(autoSegment).c_str() ) << endl; } else - trackSegment->_check (); + trackSegment->_check(); } } -#if defined(CHECK_DATABASE) - //Session::getKiteEngine()->setInterrupt ( not coherency ); -#endif - return coherency; } @@ -753,14 +721,14 @@ namespace Kite { void KiteEngine::finalizeLayout () { ltrace(90) << "KiteEngine::finalizeLayout()" << endl; - if ( getState() > Katabatic::StateDriving ) return; + if (getState() > Katabatic::EngineDriving) return; ltracein(90); - setState ( Katabatic::StateDriving ); - _gutKite (); + setState( Katabatic::EngineDriving ); + _gutKite(); - KatabaticEngine::finalizeLayout (); + KatabaticEngine::finalizeLayout(); ltrace(90) << "State: " << getState() << endl; ltraceout(90); @@ -773,15 +741,15 @@ namespace Kite { ltracein(90); ltrace(90) << "State: " << getState() << endl; - if ( getState() < Katabatic::StateGutted ) { - Session::open ( this ); + if (getState() < Katabatic::EngineGutted) { + Session::open( this ); size_t maxDepth = getRoutingGauge()->getDepth(); for ( size_t depth=0 ; depth < maxDepth ; depth++ ) { - _routingPlanes[depth]->destroy (); + _routingPlanes[depth]->destroy(); } - Session::close (); + Session::close(); } ltraceout(90); @@ -790,52 +758,10 @@ namespace Kite { TrackElement* KiteEngine::_lookup ( Segment* segment ) const { - TrackElementLut::const_iterator it = _trackSegmentLut.find ( segment ); - if ( it == _trackSegmentLut.end() ) { - AutoSegment* autoSegment = KatabaticEngine::_lookup ( segment ); - if ( not autoSegment or autoSegment->isCanonical() ) return NULL; + AutoSegment* autoSegment = KatabaticEngine::_lookup( segment ); + if (not autoSegment or not autoSegment->isCanonical()) return NULL; - Interval dummy; - autoSegment = autoSegment->getCanonical ( dummy ); - it = _trackSegmentLut.find ( autoSegment->base() ); - - if ( it == _trackSegmentLut.end() ) return NULL; - } - return (*it).second; - } - - - void KiteEngine::_link ( TrackElement* trackSegment ) - { - if ( getState() > Katabatic::StateActive ) return; - - if ( !trackSegment ) { - cerr << Bug("KiteEngine::_link(): Rejecting NULL TrackElement.") << endl; - return; - } - - _trackSegmentLut [ trackSegment->base()->base() ] = trackSegment; - // Not needed: Canonical search is done before lookup. -// forEach ( AutoSegment*, isegment, trackSegment->base()->getCollapseds() ) { -// _trackSegmentLut [ isegment->base() ] = trackSegment; -// } - } - - - void KiteEngine::_unlink ( TrackElement* trackSegment ) - { - if ( getState() > Katabatic::StateActive ) return; - - TrackElementLut::iterator it = _trackSegmentLut.find ( trackSegment->base()->base() ); - if ( it != _trackSegmentLut.end() ) - _trackSegmentLut.erase ( it ); - - // Not needed: Canonical search is done before lookup. -// forEach ( AutoSegment*, isegment, trackSegment->base()->getCollapseds() ) { -// TrackElementLut::iterator it = _trackSegmentLut.find ( isegment->base() ); -// if ( it != _trackSegmentLut.end() ) -// _trackSegmentLut.erase ( it ); -// } + return _lookup( autoSegment ); } @@ -844,15 +770,15 @@ namespace Kite { cerr << " o Checking " << net << endl; forEach ( Segment*, isegment, net->getComponents().getSubSet() ) { - TrackElement* trackSegment = _lookup ( *isegment ); - if ( trackSegment ) { - trackSegment->_check (); + TrackElement* trackSegment = _lookup( *isegment ); + if (trackSegment) { + trackSegment->_check(); AutoContact* autoContact = trackSegment->base()->getAutoSource(); - if ( autoContact ) autoContact->checkTopology (); + if (autoContact) autoContact->checkTopology (); autoContact = trackSegment->base()->getAutoTarget(); - if ( autoContact ) autoContact->checkTopology (); + if (autoContact) autoContact->checkTopology (); } } } @@ -865,12 +791,7 @@ namespace Kite { string KiteEngine::_getString () const { ostringstream os; - - os << "<" << "KiteEngine " - << _cell->getName () << " " - // << getString(_rg->getName()) - << ">"; - + os << "<" << "KiteEngine " << _cell->getName () << ">"; return os.str(); } @@ -879,12 +800,12 @@ namespace Kite { { Record* record = KatabaticEngine::_getRecord (); - if ( record ) { - record->add ( getSlot ( "_routingPlanes", &_routingPlanes ) ); - record->add ( getSlot ( "_configuration", _configuration ) ); + if (record) { + record->add( getSlot( "_routingPlanes", &_routingPlanes ) ); + record->add( getSlot( "_configuration", _configuration ) ); } return record; } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/KiteMain.cpp b/kite/src/KiteMain.cpp index ecce5b83..57e37802 100644 --- a/kite/src/KiteMain.cpp +++ b/kite/src/KiteMain.cpp @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2013, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -15,31 +14,31 @@ // +-----------------------------------------------------------------+ -#include +#include using namespace std; -#include +#include namespace bopts = boost::program_options; -#include "vlsisapd/configuration/Configuration.h" -#include "hurricane/DebugSession.h" -#include "hurricane/DataBase.h" -#include "hurricane/Cell.h" -#include "hurricane/Warning.h" -#include "hurricane/UpdateSession.h" +#include "vlsisapd/configuration/Configuration.h" +#include "hurricane/DebugSession.h" +#include "hurricane/DataBase.h" +#include "hurricane/Cell.h" +#include "hurricane/Warning.h" +#include "hurricane/UpdateSession.h" using namespace Hurricane; -#include "crlcore/Utilities.h" -#include "crlcore/Banner.h" -#include "crlcore/AllianceFramework.h" -#include "crlcore/Hierarchy.h" -#include "crlcore/ToolBox.h" +#include "crlcore/Utilities.h" +#include "crlcore/Banner.h" +#include "crlcore/AllianceFramework.h" +#include "crlcore/Hierarchy.h" +#include "crlcore/ToolBox.h" using namespace CRL; -#include "knik/KnikEngine.h" +#include "knik/KnikEngine.h" using namespace Knik; -#include "kite/KiteEngine.h" +#include "kite/KiteEngine.h" using namespace Kite; @@ -145,8 +144,8 @@ int main ( int argc, char *argv[] ) } KatabaticEngine::NetSet routingNets; - unsigned int globalFlags = (loadGlobal) ? Kite::LoadGlobalSolution - : Kite::BuildGlobalSolution; + unsigned int globalFlags = (loadGlobal) ? Kite::KtLoadGlobalRouting + : Kite::KtBuildGlobalRouting; KiteEngine* kite = KiteEngine::create( cell ); if (showConf) kite->printConfiguration(); @@ -154,9 +153,10 @@ int main ( int argc, char *argv[] ) kite->runGlobalRouter( globalFlags ); if (saveGlobal) kite->saveGlobalSolution (); - kite->loadGlobalRouting( Katabatic::LoadGrByNet, routingNets ); - kite->layerAssign ( Katabatic::NoNetLayerAssign ); - kite->runNegociate (); + kite->loadGlobalRouting ( Katabatic::EngineLoadGrByNet, routingNets ); + kite->balanceGlobalDensity(); + kite->layerAssign ( Katabatic::EngineNoNetLayerAssign ); + kite->runNegociate (); kiteSuccess = kite->getToolSuccess(); kite->finalizeLayout (); diff --git a/kite/src/Manipulator.cpp b/kite/src/Manipulator.cpp new file mode 100644 index 00000000..b8a39f2f --- /dev/null +++ b/kite/src/Manipulator.cpp @@ -0,0 +1,1412 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2013, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | K i t e - D e t a i l e d R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./Manipulator.cpp" | +// +-----------------------------------------------------------------+ + + +#include "hurricane/DebugSession.h" +#include "hurricane/Bug.h" +#include "kite/TrackSegment.h" +#include "kite/Track.h" +#include "kite/Tracks.h" +#include "kite/DataNegociate.h" +#include "kite/RoutingPlane.h" +#include "kite/RoutingEvent.h" +#include "kite/SegmentFsm.h" +#include "kite/Manipulator.h" +#include "kite/KiteEngine.h" + + +namespace { + + using namespace std; + using namespace Hurricane; + using namespace Kite; + using Katabatic::GCell; + + +// ------------------------------------------------------------------- +// Class : "LvGCandidate". + + class LvGCandidate { + public: + struct Compare : public binary_function { + inline bool operator() ( const LvGCandidate& lhs, const LvGCandidate& rhs ) const; + }; + public: + inline LvGCandidate ( TrackElement* segment=NULL, Interval overlap=Interval(), size_t terminals=0 ); + inline TrackElement* getSegment () const; + inline const Interval& getOverlap () const; + inline size_t getTerminals () const; + private: + TrackElement* _segment; + Interval _overlap; + size_t _terminals; + }; + + inline LvGCandidate::LvGCandidate ( TrackElement* segment, Interval overlap, size_t terminals ) + : _segment (segment) + , _overlap (overlap) + , _terminals(terminals) + { } + + inline TrackElement* LvGCandidate::getSegment () const { return _segment; } + inline const Interval& LvGCandidate::getOverlap () const { return _overlap; } + inline size_t LvGCandidate::getTerminals () const { return _terminals; } + + inline bool LvGCandidate::Compare::operator() ( const LvGCandidate& lhs, const LvGCandidate& rhs ) const + { + if ( lhs.getTerminals() != rhs.getTerminals() ) + return lhs.getTerminals() < rhs.getTerminals(); + + if ( lhs.getOverlap() != rhs.getOverlap() ) + return lhs.getOverlap().getSize() > rhs.getOverlap().getSize(); + + return lhs.getSegment()->getAxis() < rhs.getSegment()->getAxis(); + } + + +} // Anonymous namespace. + + +namespace Kite { + + using Hurricane::Bug; + +// ------------------------------------------------------------------- +// Class : "Manipulator". + + Manipulator::Manipulator ( TrackElement* segment, SegmentFsm& S ) + : _segment(segment) + , _data (NULL) + , _event (NULL) + , _fsm (S) + { + if (not _segment) + throw Error( "Manipulator::Manipulator(): cannot build upon a NULL TrackElement." ); + + DebugSession::open( _segment->getNet(), 200 ); + + _data = _segment->getDataNegociate(); + if (_data) _event = _data->getRoutingEvent(); + } + + + Manipulator::~Manipulator () + { DebugSession::close(); } + + + bool Manipulator::canRipup ( unsigned int flags ) const + { + if (_data) { + if (not _event or _event->isUnimplemented()) return false; + + unsigned int limit = Session::getKiteEngine()->getRipupLimit(_segment); + unsigned int count = _data->getRipupCount() + ((flags & NotOnLastRipup) ? 1 : 0); + + return (count < limit); + } + return false; + } + + + bool Manipulator::isCaged ( DbU::Unit axis ) const + { + Track* track = _segment->getTrack(); + if ( not track ) return false; + + TrackElement* neighbor = _segment->getPrevious(); + if (neighbor and (neighbor->isFixed() or neighbor->isBlockage())) { + if (abs(axis - neighbor->getTargetU()) < DbU::lambda(10.0)) + return true; + } + + neighbor = _segment->getNext(); + if (neighbor and (neighbor->isFixed() or neighbor->isBlockage())) { + if (abs(axis - neighbor->getSourceU()) < DbU::lambda(10.0)) + return true; + } + + return false; + } + + + bool Manipulator::ripup ( unsigned int type, DbU::Unit axisHint ) + { + ltrace(200) << "Manipulator::ripup() " << endl; + + if (not canRipup()) return false; + + if (_segment->isFixed()) return false; + if (_data == NULL) return true; + + _fsm.addAction( _segment, type, axisHint ); + return true; + } + + + bool Manipulator::ripupPerpandiculars ( unsigned int flags ) + { + ltrace(200) << "Manipulator::ripupPerpandiculars() - " << flags << endl; + + bool success = true; + bool cagedPerpandiculars = false; + Interval constraints ( _event->getConstraints() ); + Interval perpandicularConstraints ( constraints ); + size_t placedPerpandiculars = 0; + unsigned int parallelActionFlags = SegmentAction::SelfRipup|SegmentAction::EventLevel4; + unsigned int perpandicularActionFlags = SegmentAction::SelfRipupPerpand; + + if (flags & Manipulator::PerpandicularsFirst) { + parallelActionFlags &= ~SegmentAction::EventLevel4; + perpandicularActionFlags |= SegmentAction::EventLevel4; + if (flags & Manipulator::ToRipupLimit) + perpandicularActionFlags |= SegmentAction::ToRipupLimit; + } else { + if (flags & Manipulator::ToRipupLimit) + parallelActionFlags |= SegmentAction::ToRipupLimit; + } + + ltrace(200) << "Pure constraints: " << constraints << endl; + + Track* track = NULL; + const vector& perpandiculars = _event->getPerpandiculars(); + + for ( size_t i=0 ; i < perpandiculars.size() ; i++ ) { + track = perpandiculars[i]->getTrack(); + if (not track) { + // The perpandicular is not placed yet. + if (flags & Manipulator::PerpandicularsFirst) { + _fsm.addAction( perpandiculars[i], perpandicularActionFlags ); + } + continue; + } + + bool dislodgeCaged = false; + if (Manipulator(perpandiculars[i],_fsm).isCaged(_event->getSegment()->getAxis())) { + cagedPerpandiculars = true; + dislodgeCaged = true; + } + + placedPerpandiculars++; + + // Try to ripup the perpandicular. + DataNegociate* data2 = perpandiculars[i]->getDataNegociate(); + ltrace(200) << "| " << perpandiculars[i] << endl; + + if ( (flags & Manipulator::ToMoveUp) and (data2->getState() < DataNegociate::MoveUp) ) + data2->setState( DataNegociate::MoveUp ); + + if (Manipulator(perpandiculars[i],_fsm).ripup(perpandicularActionFlags)) { + if (dislodgeCaged) { + // Ugly: hard-coded uses of pitch. + _event->setAxisHint( _event->getSegment()->getAxis() + DbU::lambda(5.0) ); + } + continue; + } + + // Cannot ripup the perpandicular, try to ripup it's neigbors. + size_t begin; + size_t end; + track->getOverlapBounds( constraints, begin, end ); + + for ( ; (begin < end) ; begin++ ) { + TrackElement* other = track->getSegment(begin); + + if (other->getNet() == _event->getSegment()->getNet()) continue; + + Interval otherCanonical ( other->getCanonicalInterval() ); + if (not otherCanonical.intersect(constraints)) continue; + + // Try to ripup conflicting neighbor. + if (Manipulator(other,_fsm).canRipup()) { + ltrace(200) << " | Ripup: " << begin << " " << other << endl; + _fsm.addAction( other, SegmentAction::OtherRipup ); + } else { + ltrace(200) << "Aborted ripup of perpandiculars, fixed or blocked." << endl; + return false; + } + } + } + + if (cagedPerpandiculars and not placedPerpandiculars) { + ltrace(200) << "Aborted ripup of perpandiculars, constraints are due to fixed/blockage." << endl; + _fsm.addAction( _segment, SegmentAction::SelfRipup ); + return true; + } + + if (_segment->isLocal() and not placedPerpandiculars) { + ltrace(200) << "No placed perpandiculars, tight native constraints, place perpandiculars FIRST." << endl; + for ( size_t i=0 ; i < perpandiculars.size() ; i++ ) { + _fsm.addAction( perpandiculars[i], perpandicularActionFlags|SegmentAction::EventLevel4 ); + } + _fsm.addAction( _segment, parallelActionFlags ); + return true; + } + + RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(_segment->getLayer()); + size_t tracksNb = 0; + + track = plane->getTrackByPosition(constraints.getVMin()); + + if (track and (track->getAxis() < constraints.getVMin())) track = track->getNextTrack(); + for ( ; track && (track->getAxis() <= constraints.getVMax()) + ; track = track->getNextTrack(), tracksNb++ ); + + if (_segment->isLocal() and (tracksNb < 2)) success = ripple(); + + _fsm.addAction( _segment, parallelActionFlags ); + return success; + } + + + bool Manipulator::relax ( Interval interval, unsigned int flags ) + { + interval.inflate( - Session::getExtensionCap() /*+ DbU::lambda(5.0)*/ ); // Ugly. + ltrace(200) << "Manipulator::relax() of: " << _segment << " " << interval << endl; + + if (_segment->isFixed()) return false; + if (not interval.intersect(_segment->getCanonicalInterval())) return false; + if (not _data) return false; + + if ( _segment->isTerminal() + and (_segment->getLayer() == Session::getRoutingGauge()->getRoutingLayer(1)) ) { + if (interval.contains(_segment->base()->getAutoSource()->getX())) return false; + if (interval.contains(_segment->base()->getAutoTarget()->getX())) return false; + } + + ltracein(200); + bool success = true; + bool expand = _segment->isGlobal() and (flags&AllowExpand); + ltrace(200) << "Expand:" << expand << endl; + + Katabatic::GCellVector gcells; + _segment->getGCells( gcells ); + + if (gcells.size() < 2 ){ + cerr << Bug( "relax() Cannot break %s,\n only in %s." + , getString(_segment).c_str() + , getString(gcells[0]).c_str() + ) << endl; + ltraceout(200); + return false; + } + + unsigned int depth = Session::getRoutingGauge()->getLayerDepth(_segment->getLayer()); + Interval uside; + size_t dogLegCount = 0; + size_t iminconflict = gcells.size(); + size_t imaxconflict = gcells.size(); + size_t igcell; + + // Look for closest enclosing min & max GCells indexes. + for ( igcell=0 ; igcellgetSide(_segment->getDirection()); + ltrace(200) << "| " << setw(3) << igcell << " " << gcells[igcell] << " uside: " << uside << endl; + + if (uside.contains(interval.getVMin())) { + iminconflict = igcell; + ltrace(200) << "> Min conflict: " << iminconflict << endl; + } + if (uside.contains(interval.getVMax())) { + imaxconflict = igcell; + ltrace(200) << "> Max conflict: " << imaxconflict << endl; + } + } + + // Expand min & max to enclose GCells of greatest or equal order + // (i.e. less saturateds) + bool minExpanded = false; + bool maxExpanded = false; + if (expand) { + if (iminconflict < gcells.size()) { + //ltrace(200) << "Expand min" << endl; + + size_t imindensity = 0; + for ( size_t iexpand=1 ; iexpandcanDogleg(gcells[iexpand],KtAllowDoglegReuse)) continue; + + // ltrace(200) << " Density " + // << "Density " << Session::getRoutingGauge()->getRoutingLayer(depth)->getName() + // << " min. dens.:" << gcells[imindensity]->getDensity(depth) + // << " exp. dens.:" << gcells[iexpand ]->getDensity(depth) + // << endl; + + if (gcells[imindensity]->getDensity(depth) - gcells[iexpand]->getDensity(depth) > 1e-3) { + imindensity = iexpand; + //ltrace(200) << "Accepted expand " << imindensity << endl; + } + } + + if (iminconflict != imindensity) minExpanded = true; + iminconflict = (imindensity>0) ? imindensity : gcells.size(); + } + + if (imaxconflict < gcells.size()) { + //ltrace(200) << "Expand max" << endl; + + size_t imindensity = imaxconflict; + for ( size_t iexpand=imaxconflict+1 ; iexpandcanDogleg(gcells[iexpand],KtAllowDoglegReuse)) continue; + + // ltrace(200) << " Density " + // << Session::getRoutingGauge()->getRoutingLayer(depth)->getName() + // << " min. dens.:" << gcells[imindensity]->getDensity(depth) + // << " exp. dens.:" << gcells[iexpand ]->getDensity(depth) + // << endl; + + if (gcells[imindensity]->getDensity(depth) - gcells[iexpand]->getDensity(depth) > 1e-3) { + imindensity = iexpand; + //ltrace(200) << "Accepted expand " << imindensity << endl; + } + } + + if (imindensity != imaxconflict) maxExpanded = true; + imaxconflict = (imindensity < gcells.size()) ? imindensity : gcells.size(); + } + } + ltrace(200) << "minExpanded:" << minExpanded << " (" << iminconflict + << ") maxExpanded:" << maxExpanded << " (" << imaxconflict << ")" << endl; + + // Check for full enclosure. + if ( ( (iminconflict == gcells.size()) and (imaxconflict == gcells.size() ) ) + or ( (iminconflict == 0) and (imaxconflict == gcells.size()-1) )) { + cinfo << "[INFO] Manipulator::relax(): Segment fully enclosed in interval." << endl; + ltraceout(200); + return false; + } + + // Suppress min/max if it's the first/last. + if ((iminconflict < gcells.size()) and (imaxconflict == gcells.size()-1)) imaxconflict = gcells.size(); + if ((imaxconflict < gcells.size()) and (iminconflict == 0)) iminconflict = gcells.size(); + + // Compute number of doglegs and nature of the *first* dogleg. + // (first can be min or max, second can only be max) + bool firstDoglegIsMin = false; + if (iminconflict < gcells.size()) { dogLegCount++; firstDoglegIsMin = true; } + if (imaxconflict < gcells.size()) dogLegCount++; + + switch ( dogLegCount ) { + case 2: + // Compact only if the double dogleg is at beginning or end. + if (iminconflict == imaxconflict) { + if (iminconflict == 0) { + // First dogleg is max. + dogLegCount--; + } else if (iminconflict == gcells.size()-1) { + dogLegCount--; + firstDoglegIsMin = true; + } + } + break; + case 1: break; + case 0: + cerr << Bug( "Manipulator::relax() Can't find a GCell suitable for making dogleg." + , getString(interval).c_str() ) << endl; + ltraceout(200); + return false; + } + + ltrace(200) << "| Has to do " << dogLegCount << " doglegs." << endl; + + // Check of "min is less than one track close the edge" (while not expanded). + // AND we are on the first GCell AND there's one dogleg only. + if (not minExpanded and (iminconflict == 0) and (imaxconflict == gcells.size())) { + ltrace(200) << "Cannot break in first GCell only." << endl; + ltraceout(200); + return false; + } + + // Check of "min is less than one track close the edge" (while not expanded). + if ( /*not minExpanded and*/ (iminconflict > 0) and (iminconflict < gcells.size()) ) { + uside = gcells[iminconflict-1]->getSide(_segment->getDirection()); + ltrace(200) << "GCell Edge Comparison (min): " << uside + << " vs. " << DbU::getValueString(interval.getVMin()) << endl; + // Ugly: One lambda shrink. + if (interval.getVMin()-DbU::lambda(1.0) <= uside.getVMax()) { + ltrace(200) << "Using previous GCell." << endl; + iminconflict--; + } + } + + // Check if there is only one dogleg AND it's the last one. + if (not maxExpanded and (iminconflict == gcells.size()) and (imaxconflict == gcells.size()-1)) { + ltrace(200) << "Cannot break in last GCell only." << endl; + ltraceout(200); + return false; + } + + // Check of "max is less than one track close the edge" (while not expanded). + if ((imaxconflict < gcells.size()-1)) { + uside = gcells[imaxconflict+1]->getSide( _segment->getDirection() ); + ltrace(200) << "GCell Edge Comparison (max): " << uside + << " vs. " << DbU::getValueString(interval.getVMax()) << endl; + // Ugly: Direct uses of routing pitch. + if (interval.getVMax()+DbU::lambda(5.0) >= uside.getVMin()) { + interval.inflate( 0, DbU::fromLambda(5.0) ); + ltrace(200) << "Using next GCell " << interval << endl; + imaxconflict++; + } + } + + size_t ifirstDogleg = gcells.size(); + size_t isecondDogleg = gcells.size(); + if (not firstDoglegIsMin) { + ifirstDogleg = imaxconflict; + } else { + ifirstDogleg = iminconflict; + isecondDogleg = imaxconflict; + } + + // Making first dogleg. + ltrace(200) << "Making FIRST dogleg at " << ifirstDogleg << endl; + TrackElement* segment1 = NULL; + TrackElement* segment2 = NULL; + Track* track = _segment->getTrack(); + Katabatic::GCell* dogLegGCell = gcells[ifirstDogleg]; + TrackElement* dogleg = NULL; + DbU::Unit doglegAxis; + bool doglegReuse1 = false; + bool doglegReuse2 = false; + + // Try to reuse existing dogleg if broken at either end. + if (ifirstDogleg == 0) dogleg = _segment->getSourceDogleg(); + if (ifirstDogleg == gcells.size()-1) dogleg = _segment->getTargetDogleg(); + if (dogleg) { + ltrace(200) << "Reusing dogleg." << endl; + doglegReuse1 = true; + segment1 = _segment; + } else { + // Try to create a new dogleg. + if (not _segment->canDogleg(dogLegGCell)) { + ltrace(200) << "Cannot create FIRST dogleg." << endl; + ltraceout(200); + return false; + } + _segment->makeDogleg( dogLegGCell, dogleg, segment1 ); + } + + if (firstDoglegIsMin) { + if (minExpanded) { + doglegAxis = dogLegGCell->getSide( _segment->getDirection() ).getCenter(); + //ltrace(200) << "MARK 1 doglegAxis: " << DbU::getValueString(doglegAxis) << endl; + } else { + // Ugly: hardcoded pitch. + doglegAxis = interval.getVMin() - DbU::lambda(5.0); + //ltrace(200) << "MARK 2 doglegAxis: " << DbU::getValueString(doglegAxis) << endl; + } + } else { + if (maxExpanded) { + doglegAxis = dogLegGCell->getSide( _segment->getDirection() ).getVMin(); + //ltrace(200) << "MARK 3 doglegAxis: " << DbU::getValueString(doglegAxis) << endl; + } else { + // Ugly: hardcoded pitch (5.0 - 1.0). + doglegAxis = interval.getVMax() + DbU::lambda(4.0); + //ltrace(200) << "MARK 4 doglegAxis: " << DbU::getValueString(doglegAxis) << endl; + } + } + if (doglegReuse1) _fsm.addAction( dogleg, SegmentAction::OtherRipup ); + else dogleg->setAxis( doglegAxis ); + + // If event is present, the dogleg is in the current RoutingSet. + RoutingEvent* event = dogleg->getDataNegociate()->getRoutingEvent(); + if (event) { + ltrace(200) << "Set Axis Hint: @" << DbU::getValueString(doglegAxis) << " " << dogleg << endl; + event->setAxisHint( doglegAxis ); + } else { + ltrace(200) << "Dogleg has no RoutingEvent yet." << endl; + } + + // Making second dogleg. + if (dogLegCount > 1) { + ltrace(200) << "Making SECOND dogleg at " << isecondDogleg + << " on " << segment1 << endl; + + dogleg = NULL; + dogLegGCell = gcells[isecondDogleg]; + + if (ifirstDogleg == isecondDogleg) { + ltrace(200) << "Double break in same GCell." << endl; + segment1->setFlags( TElemSourceDogleg ); + } + + if (isecondDogleg == gcells.size()-1) dogleg = segment1->getTargetDogleg(); + if (dogleg) { + ltrace(200) << "Reusing dogleg." << endl; + doglegReuse2 = true; + segment2 = segment1; + } else { + // Try to create a new dogleg. + if (not segment1->canDogleg(dogLegGCell)) { + ltrace(200) << "Cannot create SECOND dogleg." << endl; + ltraceout(200); + return false; + } + segment1->makeDogleg( dogLegGCell, dogleg, segment2 ); + } + + if (maxExpanded) { + doglegAxis = dogLegGCell->getSide(segment1->getDirection()/*,false*/).getCenter(); + } else { + // Ugly: hardcoded pitch. + doglegAxis = interval.getVMax() + DbU::lambda(5.0); + } + if (doglegReuse2) _fsm.addAction( dogleg, SegmentAction::OtherRipup ); + else dogleg->setAxis( doglegAxis ); + + // If event is present, the dogleg is in the current RoutingSet. + RoutingEvent* event = dogleg->getDataNegociate()->getRoutingEvent(); + if (event) { + ltrace(200) << "Set Axis Hint: @" << DbU::getValueString(doglegAxis) << " " << dogleg << endl; + event->setAxisHint( doglegAxis ); + } else { + ltrace(200) << "Dogleg has no RoutingEvent yet." << endl; + } + + // This cases seems never to occurs. + const vector& doglegs = Session::getDoglegs(); + for ( size_t i=0 ; igetTrack() and track) { + ltrace(200) << "Direct Track insert of: " << segment << endl; + Session::addInsertEvent( segment, track ); + } + } + } + + switch ( dogLegCount ) { + case 1: + if (not doglegReuse1) { + if (firstDoglegIsMin) + _segment->getDataNegociate()->setState( DataNegociate::RipupPerpandiculars, true ); + else + segment1->getDataNegociate()->setState( DataNegociate::RipupPerpandiculars, true ); + } + if ((flags & NoDoglegReuse) and (doglegReuse1 or doglegReuse2 )) + success = false; + break; + case 2: + if (not doglegReuse1) + _segment->getDataNegociate()->setState( DataNegociate::RipupPerpandiculars, true ); + if ( not doglegReuse2 ) + segment2->getDataNegociate()->setState( DataNegociate::RipupPerpandiculars, true ); + break; + } + + if (_segment->isLocal()) { + ltrace(200) << "Reset state of: " << _segment << endl; + _segment->getDataNegociate()->setState( DataNegociate::RipupPerpandiculars, true ); + } else { + ltrace(200) << "No state reset: " << _segment << endl; + } + + if ((not doglegReuse1) and segment1 and segment1->isLocal()) { + ltrace(200) << "Reset state of: " << segment1 << endl; + segment1->getDataNegociate()->setState( DataNegociate::RipupPerpandiculars, true ); + } + + if ((not doglegReuse2) and segment2 and segment2->isLocal()) { + ltrace(200) << "Reset state of: " << segment2 << endl; + segment2->getDataNegociate()->setState( DataNegociate::RipupPerpandiculars, true ); + } + + ltraceout(200); + return success; + } + + + bool Manipulator::insertInTrack ( size_t itrack ) + { + Track* track = _fsm.getTrack(itrack); + size_t begin = _fsm.getBegin(itrack); + size_t end = _fsm.getEnd (itrack); + Net* ownerNet = _segment->getNet(); + Interval toFree (_segment->getCanonicalInterval()); + Net* ripupNet = NULL; + set canonicals; + DbU::Unit rightAxisHint = 0; + DbU::Unit leftAxisHint = 0; + bool leftIntrication = false; + bool rightIntrication = false; + bool success = true; + unsigned long maxId = AutoSegment::getMaxId(); + + ltrace(200) << "Manipulator::insertInTrack() - " << toFree << endl; + + for ( size_t i = begin ; success && (i < end) ; i++ ) { + TrackElement* segment2 = track->getSegment(i); + + ltrace(200) << "* Looking // " << segment2 << endl; + + if ( segment2->getNet() == ownerNet ) continue; + if ( not toFree.intersect(segment2->getCanonicalInterval()) ) continue; + if ( segment2->isBlockage() or segment2->isFixed() ) { + success = false; + continue; + } + if ( segment2->getId() >= maxId ) continue; + ripupNet = segment2->getNet(); + + DataNegociate* data2 = segment2->getDataNegociate(); + if ( !data2 ) { + ltrace(200) << "No DataNegociate, ignoring." << endl; + continue; + } + + if ( data2->getState() == DataNegociate::MaximumSlack ) { + ltrace(200) << "At " << DataNegociate::getStateString(data2) + << " for " << segment2 << endl; + success = false; + continue; + } + + bool shrinkLeft = false; + bool shrinkRight = false; + + if ( data2->getRightMinExtend() < toFree.getVMin() ) { + ltrace(200) << "- Shrink right edge (push left) " << segment2 << endl; + shrinkRight = true; + TrackElement* rightNeighbor2 = track->getSegment(i+1); + if ( rightNeighbor2 && (rightNeighbor2->getNet() == segment2->getNet()) ) { + Interval interval1 = segment2->getCanonicalInterval(); + Interval interval2 = rightNeighbor2->getCanonicalInterval(); + + if ( interval1.intersect(interval2) && (interval2.getVMax() > interval1.getVMax()) ) + shrinkLeft = true; + } + } + + if ( data2->getLeftMinExtend() > toFree.getVMax() ) { + ltrace(200) << "- Shrink left edge (push right) " << segment2 << endl; + shrinkLeft = true; + if ( i > 0 ) { + TrackElement* leftNeighbor2 = track->getSegment(i-1); + if ( leftNeighbor2 && (leftNeighbor2->getNet() == segment2->getNet()) ) { + Interval interval1 = segment2->getCanonicalInterval(); + Interval interval2 = leftNeighbor2->getCanonicalInterval(); + + if ( interval1.intersect(interval2) && (interval2.getVMin() < interval1.getVMin()) ) + shrinkRight = true; + } + } + } + + if ( _segment->isLocal() and segment2->isLocal() ) { + if ( shrinkLeft and shrinkRight ) { + Interval interval1 = segment2->getCanonicalInterval(); + if ( toFree.getCenter() < interval1.getCenter() ) shrinkRight = false; + else shrinkLeft = false; + } + } + + ltrace(200) << "- Hard overlap/enclosure/shrink " << segment2 << endl; + if ( _segment->isStrap() and segment2->isGlobal() ) continue; + if ( not (success = Manipulator(segment2,_fsm).ripup(SegmentAction::OtherRipup)) ) + continue; + + canonicals.clear (); + forEach ( TrackElement*, isegment3 + , segment2->getPerpandiculars().getSubSet(TrackElements_UniqCanonical(canonicals)) ) { + DataNegociate* data3 = isegment3->getDataNegociate(); + if ( not data3 ) continue; + + RoutingEvent* event3 = data3->getRoutingEvent(); + if ( not event3 ) continue; + + if ( not toFree.intersect(event3->getConstraints()) ) { + ltrace(200) << " . " << *isegment3 << endl; + continue; + } + + ltrace(200) << " | " << *isegment3 << endl; + + if ( shrinkRight xor shrinkLeft ) { + if ( shrinkRight ) { + if ( not (success=Manipulator(*isegment3,_fsm) + .ripup( SegmentAction::OtherRipupPerpandAndPushAside + , toFree.getVMin() - DbU::lambda(2.5) + )) ) + break; + + if ( event3->getTracksFree() == 1 ) { + ltrace(200) << "Potential left intrication with other perpandicular." << endl; + if ( isegment3->getAxis() == segment2->getTargetU() - Session::getExtensionCap() ) { + leftIntrication = true; + leftAxisHint = isegment3->getAxis(); + } + } + } + if ( shrinkLeft ) { + if ( not (success=Manipulator(*isegment3,_fsm) + .ripup( SegmentAction::OtherRipupPerpandAndPushAside + , toFree.getVMax() + DbU::lambda(2.5) + )) ) + break; + if ( event3->getTracksFree() == 1 ) { + ltrace(200) << "Potential right intrication with other perpandicular." << endl; + if ( isegment3->getAxis() == segment2->getSourceU() + Session::getExtensionCap() ) { + rightIntrication = true; + rightAxisHint = isegment3->getAxis(); + } + } + } + } else { + if ( not (success=Manipulator(*isegment3,_fsm).ripup( SegmentAction::OtherRipup + | SegmentAction::EventLevel3 + )) ) + break; + } + } + if ( not success ) break; + } + + if ( success ) { + ltrace(200) << "Manipulator::insertInTrack() success" << endl; + + _fsm.setState ( SegmentFsm::OtherRipup ); + _fsm.addAction ( _segment + , SegmentAction::SelfInsert|SegmentAction::MoveToAxis|SegmentAction::EventLevel4 + , _fsm.getCost(itrack).getTrack()->getAxis() ); + + unsigned int flags = 0; + if ( rightIntrication ) flags |= RightAxisHint; + if ( leftIntrication ) flags |= LeftAxisHint; + if ( flags ) + Manipulator(_segment,_fsm).shrinkToTrack(itrack,flags,leftAxisHint,rightAxisHint); + } else + _fsm.clearActions (); + + return success; + } + + + bool Manipulator::forceToTrack ( size_t itrack ) + { + Track* track = _fsm.getTrack(itrack); + size_t begin = _fsm.getBegin(itrack); + size_t end = _fsm.getEnd (itrack); + Net* ownerNet = _segment->getNet(); + Interval toFree (_segment->getCanonicalInterval()); + Net* ripupNet = NULL; + set canonicals; + bool success = true; + + ltrace(200) << "Manipulator::forceToTrack() - " << toFree << endl; + + for ( size_t i=begin ; success and (i < end) ; ++i ) { + TrackElement* segment2 = track->getSegment(i); + + ltrace(200) << "* Looking // " << segment2 << endl; + + if (segment2->getNet() == ownerNet) continue; + if (not toFree.intersect(segment2->getCanonicalInterval())) continue; + if (segment2->isFixed()) { + success = false; + continue; + } + ripupNet = segment2->getNet(); + + DataNegociate* data2 = segment2->getDataNegociate(); + if (not data2 ) { + ltrace(200) << "No DataNegociate, ignoring." << endl; + continue; + } + + ltrace(200) << "- Forced ripup " << segment2 << endl; + if (not (success=Manipulator(segment2,_fsm).ripup(SegmentAction::OtherRipup))) + continue; + + canonicals.clear(); + forEach ( TrackElement*, isegment3 + , segment2->getPerpandiculars().getSubSet(TrackElements_UniqCanonical(canonicals)) ) { + DataNegociate* data3 = isegment3->getDataNegociate(); + if (not data3) continue; + + RoutingEvent* event3 = data3->getRoutingEvent(); + if (not event3) continue; + + if (Manipulator(*isegment3,_fsm).canRipup()) + _fsm.addAction( *isegment3, SegmentAction::OtherRipup ); + } + } + + if (success) { + _fsm.setState ( SegmentFsm::OtherRipup ); + _fsm.addAction( _segment + , SegmentAction::SelfInsert|SegmentAction::MoveToAxis + , _fsm.getCost(itrack).getTrack()->getAxis() ); + } + + return success; + } + + + bool Manipulator::shrinkToTrack ( size_t i, unsigned int flags, DbU::Unit leftAxisHint, DbU::Unit rightAxisHint ) + { +#if THIS_IS_DISABLED + Track* track = _fsm.getTrack(i); + size_t begin = _fsm.getBegin(i); + size_t end = _fsm.getEnd (i); + Net* ownerNet = _segment->getNet(); + set canonicals; + bool success = true; + DbU::Unit leftExtend = _segment->getSourceU() + Session::getExtensionCap(); + DbU::Unit rightExtend = _segment->getSourceU() - Session::getExtensionCap(); + + ltrace(200) << "Manipulator::shrinkToTrack()" << endl; + + if (_segment->isLocal()) return false; + Interval shrunkFree = _segment->base()->getMinSpanU(); + + ltrace(200) << "* " << shrunkFree << endl; + + for ( size_t i = begin ; success and (i < end) ; ++i ) { + TrackElement* segment2 = track->getSegment(i); + + ltrace(200) << "* Looking // " << segment2 << endl; + + if (segment2->getNet() == ownerNet) continue; + if (segment2->isFixed()) { success = false; continue; } + if (not shrunkFree.intersect(segment2->getCanonicalInterval())) continue; + + success = false; + } + + if (success) { + set perpandiculars; + set::iterator iperpand; + + DbU::Unit axisHint; + if (not (flags & LeftAxisHint )) leftAxisHint = shrunkFree.getCenter(); + if (not (flags & RightAxisHint)) rightAxisHint = shrunkFree.getCenter(); + + _segment->getPerpandicularsBound( perpandiculars ); + for ( iperpand = perpandiculars.begin() ; iperpand != perpandiculars.end() ; ++iperpand ) { + DataNegociate* data2 = (*iperpand)->getDataNegociate(); + if (data2) { + ltrace(200) << "| perpandicular bound:" << *iperpand << endl; + success = Manipulator(*iperpand,_fsm).ripup( SegmentAction::SelfRipupPerpandWithAxisHint ); + if (success) { + if ((*iperpand)->getAxis() == leftExtend ) axisHint = leftAxisHint; + else if ((*iperpand)->getAxis() == rightExtend) axisHint = rightAxisHint; + else { + cinfo << "[INFO] Bound Axis is neither left nor right\n " << (*iperpand) << endl; + axisHint = shrunkFree.getCenter(); + } + + _fsm.getActions()[_fsm.getActions().size()-1].setAxisHint( axisHint ); + } + } + } + + _fsm.addAction( _segment, SegmentAction::SelfInsert ); + _fsm.setState ( SegmentFsm::OtherRipup ); + + ltrace(200) << "Successful shrinkToTrack." << endl; + return true; + } +#endif + + return false; + } + + + bool Manipulator::forceOverLocals () + { + ltrace(200) << "Manipulator::forceOverLocals()" << endl; + ltracein(200); + + vector& costs = _fsm.getCosts(); + size_t itrack = 0; + for ( ; itrackgetNet(); + Interval toFree (_segment->getCanonicalInterval()); + + for ( size_t i = begin ; success and (i < end) ; i++ ) { + TrackElement* segment2 = track->getSegment(i); + + ltrace(200) << "* Looking // " << segment2 << endl; + + if ( segment2->getNet() == ownerNet ) continue; + if ( not toFree.intersect(segment2->getCanonicalInterval()) ) continue; + if ( segment2->isFixed() ) { + success = false; + continue; + } + + DataNegociate* data2 = segment2->getDataNegociate(); + if ( not data2 ) { + ltrace(200) << "No DataNegociate, ignoring." << endl; + success = false; + continue; + } + + ltrace(200) << "- Forced ripup " << segment2 << endl; + if ( not (success=Manipulator(segment2,_fsm).ripup(SegmentAction::OtherRipup)) ) { + continue; + } + } + + if (success) { + _fsm.setState ( SegmentFsm::OtherRipup ); + _fsm.addAction( _segment + , SegmentAction::SelfInsert|SegmentAction::MoveToAxis + , _fsm.getCost(itrack).getTrack()->getAxis() + ); + break; + } + } + + ltraceout(200); + return (itrack < costs.size()); + } + + + bool Manipulator::slacken ( unsigned int flags ) + { + ltrace(200) << "Manipulator::slacken() " << _segment << endl; + + if ( _segment->isFixed ()) return false; + if (not _segment->canSlacken()) return false; + + return _segment->slacken( flags ); + } + + + bool Manipulator::ripple () + { + ltrace(200) << "Manipulator::ripple() from " << _segment << endl; + + //if (not _segment->canRipple()) return false; + if (not _segment->isLocal()) return false; + + Net* net = _segment->getNet(); + Interval uside = _segment->base()->getAutoSource()->getGCell()->getSide ( Katabatic::perpandicularTo(_segment->getDirection())/*, false*/ ); + RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(_segment->getLayer()); + + ltracein(200); + forEach ( Track*, itrack, Tracks_Range::get(plane,uside)) { + size_t begin; + size_t end; + + itrack->getOverlapBounds( _segment->getCanonicalInterval(), begin, end ); + for ( ; begin < end ; begin++ ) { + TrackElement* other = itrack->getSegment(begin); + ltrace(200) << "| " << other << endl; + + if (other->getNet() == net) continue; + if (not other->canRipple()) continue; + + DataNegociate* otherData = other->getDataNegociate(); + if (not otherData) continue; + + DbU::Unit shiftedAxisHint; + RoutingEvent* otherEvent = otherData->getRoutingEvent(); + + if (other->getAxis() < _segment->getAxis()) { + // Ugly: routing pitch. + shiftedAxisHint = otherEvent->getAxisHint() - DbU::lambda(5.0); + if (shiftedAxisHint < uside.getVMin()) + shiftedAxisHint = uside.getVMin(); + } else { + // Ugly: routing pitch. + shiftedAxisHint = otherEvent->getAxisHint() + DbU::lambda(5.0); + if (shiftedAxisHint > uside.getVMax()) + shiftedAxisHint = uside.getVMax(); + } + + otherEvent->setAxisHint( shiftedAxisHint ); + _fsm.addAction( other, SegmentAction::OtherRipup ); + } + } + ltraceout(200); + + return true; + } + + + bool Manipulator::pivotUp () + { + ltrace(200) << "Manipulator::pivotUp() " << _segment << endl; + return false; + + if (_segment->isFixed()) return false; + if (_segment->isStrap()) return false; + + float reserve = (_segment->isLocal()) ? 0.5 : 1.0; + if (not _segment->canMoveUp(reserve)) return false; + + return _segment->moveUp( Katabatic::KbNoFlags ); + } + + + bool Manipulator::pivotDown () + { + ltrace(200) << "Manipulator::pivotDown() " << _segment << endl; + return false; + + if ( _segment->isFixed () ) return false; + if ( _segment->isStrap () ) return false; + if (not _segment->canPivotDown(2.0)) return false; + + return _segment->moveDown( Katabatic::KbNoFlags ); + } + + + bool Manipulator::moveUp ( unsigned int flags ) + { + ltrace(200) << "Manipulator::moveUp() " << _segment << endl; + + unsigned int kflags = Katabatic::KbWithNeighbors; + //kflags |= (flags & AllowLocalMoveUp ) ? Katabatic::AutoSegment::AllowLocal : 0; + kflags |= (flags & AllowTerminalMoveUp) ? Katabatic::KbAllowTerminal : 0; + + if (_segment->isFixed()) return false; + if (not (flags & AllowLocalMoveUp)) { + if (_segment->isLocal()) { + if (not _segment->canPivotUp(0.5)) return false; + } else { + if (_segment->getLength() < DbU::lambda(100.0)) { + if (not (flags & AllowShortPivotUp)) return false; + if (not _segment->canPivotUp(1.0)) return false; + } + if (not _segment->canMoveUp(0.5,kflags)) return false; + } + } else { + if (not _segment->canMoveUp(0.5,kflags)) return false; + } + return _segment->moveUp( kflags ); + } + + + bool Manipulator::makeDogleg () + { + ltrace(200) << "Manipulator::makeDogleg() " << _segment << endl; + + if ( _segment->isFixed()) return false; + if (not _segment->isLocal()) return false; + if (_segment->getLength() < 5*DbU::lambda(5.0)) return false; + + if (_fsm.getCosts().size()) { + Track* track = _fsm.getTrack(0); + size_t begin = _fsm.getBegin(0); + size_t end = _fsm.getEnd (0); + Net* ownerNet = _segment->getNet(); + Interval toFree (_segment->getCanonicalInterval()); + Interval overlap; + + for ( size_t i=begin ; igetSegment(i); + + ltrace(200) << "* Looking // " << segment2 << endl; + + if ( segment2->getNet() == ownerNet) continue; + if (not toFree.intersect(segment2->getCanonicalInterval())) continue; + + if (overlap.isEmpty()) + overlap = segment2->getCanonicalInterval(); + else + overlap.merge( segment2->getCanonicalInterval() ); + } + + if (not overlap.isEmpty() and makeDogleg(overlap)) return true; + } + + if (not _segment->canDogleg()) return false; + _segment->makeDogleg(); + + return true; + } + + + bool Manipulator::makeDogleg ( Interval overlap ) + { + ltrace(200) << "Manipulator::makeDogleg(Interval) " << _segment << endl; + ltrace(200) << overlap << endl; + + if ( _segment->isFixed () ) return false; + if (not _segment->canDogleg(overlap)) return false; + + unsigned int flags = 0; + TrackElement* dogleg = _segment->makeDogleg(overlap,flags); + if (dogleg) { + ltrace(200) << "Manipulator::makeDogleg(Interval) - Push dogleg to the " + << ((flags&Katabatic::KbDoglegOnLeft)?"left":"right") << endl; + if (_segment->isTerminal()) { + Katabatic::AutoContact* contact = + (flags&Katabatic::KbDoglegOnLeft) ? _segment->base()->getAutoSource() + : _segment->base()->getAutoTarget(); + DbU::Unit axisHint = (_segment->isHorizontal()) ? contact->getX() : contact->getY(); + RoutingEvent* event = dogleg->getDataNegociate()->getRoutingEvent(); + if (event) { + event->setAxisHint ( axisHint ); + event->setForcedToHint( true ); + ltrace(200) << "Forced to axis hint @" << DbU::getValueString(axisHint) << endl; + } + } + return true; + } + + return false; + } + + + bool Manipulator::makeDogleg ( DbU::Unit position ) + { + ltrace(200) << "Manipulator::makeDogleg(position) " << _segment << endl; + ltrace(200) << "Breaking position: " << DbU::getValueString(position) << endl; + + if (_segment->isFixed()) return false; + + Katabatic::GCellVector gcells; + _segment->getGCells( gcells ); + + size_t igcell = 0; + for ( ; igcellgetSide(_segment->getDirection()).contains(position)) + break; + } + if (igcell == gcells.size()) return false; + if (not _segment->canDogleg(gcells[igcell])) return false; + + TrackElement* dogleg = NULL; + TrackElement* parallel = NULL; + _segment->makeDogleg( gcells[igcell], dogleg, parallel ); + return (dogleg != NULL); + } + + + bool Manipulator::minimize () + { + ltrace(200) << "Manipulator::minimize() " << _segment << endl; + + if (_segment->isFixed()) return false; + if (not _event->canMinimize()) return false; + + DbU::Unit minSpan = DbU::Max; + DbU::Unit maxSpan = DbU::Min; + Interval punctualSpan ( false ); + + if (_segment->base()->getAutoSource()->getAnchor()) { + ltrace(200) << " | " << _segment->base()->getAutoSource() << endl; + Interval constraints ( _segment->base()->getAutoSource()->getUConstraints + (perpandicularTo(_segment->getDirection())) ); + ltrace(200) << " | Constraints: " << constraints << endl; + + minSpan = min( minSpan, constraints.getVMax() ); + maxSpan = max( maxSpan, constraints.getVMin() ); + punctualSpan.intersection( constraints ); + } + + if (_segment->base()->getAutoTarget()->getAnchor()) { + ltrace(200) << " | " << _segment->base()->getAutoTarget() << endl; + Interval constraints ( _segment->base()->getAutoTarget()->getUConstraints + (perpandicularTo(_segment->getDirection())) ); + ltrace(200) << " | Constraints: " << constraints << endl; + + minSpan = min( minSpan, constraints.getVMax() ); + maxSpan = max( maxSpan, constraints.getVMin() ); + punctualSpan.intersection( constraints ); + } + + const vector& perpandiculars = _event->getPerpandiculars(); + for ( size_t i=0 ; igetDataNegociate(); + if (not data2) continue; + + ltrace(200) << " | " << perpandiculars[i] << endl; + + RoutingEvent* event2 = data2->getRoutingEvent(); + if (not event2) continue; + + ltrace(200) << " | Constraints: " << event2->getConstraints() << endl; + + minSpan = min( minSpan, event2->getConstraints().getVMax() ); + maxSpan = max( maxSpan, event2->getConstraints().getVMin() ); + punctualSpan.intersection( event2->getConstraints() ); + } + if (minSpan > maxSpan) swap( minSpan, maxSpan ); + + ltrace(200) << "punctualSpan: " << punctualSpan + << " min/max span: [" << DbU::getValueString(minSpan) + << ":" << DbU::getValueString(maxSpan) << "]" + << " long: [" << minSpan + << ":" << maxSpan << "]" << endl; + + vector holes; + for ( size_t itrack=0 ; itrack<_fsm.getCosts().size() ; itrack++ ) { + size_t begin = _fsm.getBegin(itrack); + size_t end = _fsm.getEnd (itrack); + Track* track = _fsm.getTrack(itrack); + + if (end < track->getSize()) end++; + + ltrace(200) << "Looking for holes in " << _fsm.getCost(itrack) << endl; + + TrackElement* otherPrevious = NULL; + // ToDo: Manage disjoint but subsequent segment of a Net. + // (currently, that hole will not be found). + for ( ; begin < end ; begin++ ) { + TrackElement* otherSegment = track->getSegment(begin); + if (otherSegment->getNet() == _segment->getNet()) continue; + if (not otherPrevious) { + holes.push_back( Interval(track->getMin() + ,otherSegment->getSourceU()) ); + ltrace(200) << "| First hole: " << holes.back() << " " << otherSegment << endl; + } else { + if (otherSegment->getNet() == otherPrevious->getNet()) continue; + + holes.push_back( Interval(otherPrevious->getTargetU() + ,otherSegment ->getSourceU()) ); + ltrace(200) << "| Found hole: " << holes.back() + << " " << otherPrevious << " <-> " << " " << otherSegment << endl; + } + otherPrevious = otherSegment; + } + } + + if (holes.empty()) { + ltrace(200) << "No holes found to minimize into." << endl; + return false; + } + + Interval currentSpan = _segment->getCanonicalInterval(); + Interval biggestHole; + for ( size_t i=0 ; i currentSpan.getIntersection(biggestHole).getSize() ) + biggestHole = holes[i]; + } + + DbU::Unit axisHint = 0; + if (not punctualSpan.isEmpty()) { + bool success = false; + + if (biggestHole.intersect(punctualSpan)) { + ltrace(200) << "Go as punctual into biggest hole: " << biggestHole << endl; + axisHint = biggestHole.intersection(punctualSpan).getCenter(); + success = true; + } else { + for ( size_t i=0 ; igetDataNegociate(); + if (not data2) continue; + + ltrace(200) << " | " << perpandiculars[i] << endl; + + RoutingEvent* event2 = data2->getRoutingEvent(); + if (not event2) continue; + + _fsm.addAction( perpandiculars[i], SegmentAction::SelfRipupPerpandWithAxisHint, axisHint ); + } + + _event->setMinimized(); + + return true; + } + + + void Manipulator::reprocessPerpandiculars () + { + if ( _event->getAxisHistory() == _event->getAxisHint() ) return; + + bool moveLeft = (_event->getAxisHistory() > _event->getAxisHint()); + + const vector& perpandiculars = _event->getPerpandiculars(); + for ( size_t iperpand=0 ; iperpandgetDataNegociate(); + + if ( perpandicular->isFixed() ) continue; + if ( not data ) continue; + if ( not perpandicular->getTrack() ) continue; + if ( not Manipulator(perpandicular,_fsm).canRipup() + or (data->getState() >= DataNegociate::MaximumSlack) ) continue; + + // Ugly: ExtensionCap usage. + if ( moveLeft ) { + if ( perpandicular->getTargetU()-Session::getExtensionCap() == _event->getAxisHistory() ) + _fsm.addAction ( perpandicular, SegmentAction::OtherRipupPerpandAndPacking ); + } else { + if ( perpandicular->getSourceU()+Session::getExtensionCap() == _event->getAxisHistory() ) + _fsm.addAction ( perpandicular, SegmentAction::OtherRipupPerpandAndPacking ); + } + } + } + + + void Manipulator::repackPerpandiculars () + { + ltrace(200) << "Manipulator::repackPerpandiculars()" << endl; + + const vector& perpandiculars = _event->getPerpandiculars(); + for ( size_t iperpand=0 ; iperpandgetDataNegociate(); + + if (perpandicular->isFixed ()) continue; + if (perpandicular->isGlobal()) continue; + if (not data) continue; + + if (RoutingEvent::getStage() == RoutingEvent::Repair) { + data->setState( DataNegociate::Repair ); + if (data->getStateCount() > 1) data->resetStateCount(); + } + _fsm.addAction( perpandicular, SegmentAction::SelfRipupPerpand ); + } + _fsm.addAction( _segment, SegmentAction::SelfRipup|SegmentAction::EventLevel4 ); + } + + +} // Kite namespace. diff --git a/kite/src/NegociateWindow.cpp b/kite/src/NegociateWindow.cpp index 915385a5..64929ff2 100644 --- a/kite/src/NegociateWindow.cpp +++ b/kite/src/NegociateWindow.cpp @@ -2,7 +2,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -15,34 +15,32 @@ // +-----------------------------------------------------------------+ -#include -#include -#include - -#include "hurricane/Warning.h" -#include "hurricane/Bug.h" -#include "hurricane/RoutingPad.h" -#include "hurricane/Net.h" -#include "hurricane/Cell.h" -#include "crlcore/Utilities.h" -#include "crlcore/AllianceFramework.h" -#include "crlcore/Measures.h" -#include "crlcore/Histogram.h" -#include "katabatic/AutoContact.h" -#include "katabatic/GCellGrid.h" - -#include "kite/DataNegociate.h" -#include "kite/TrackElement.h" -#include "kite/TrackMarker.h" -#include "kite/TrackCost.h" -#include "kite/Track.h" -#include "kite/TrackSegment.h" -#include "kite/RoutingPlane.h" -#include "kite/RoutingEventQueue.h" -#include "kite/RoutingEventHistory.h" -#include "kite/RoutingEventLoop.h" -#include "kite/NegociateWindow.h" -#include "kite/KiteEngine.h" +#include +#include +#include +#include "hurricane/Warning.h" +#include "hurricane/Bug.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Net.h" +#include "hurricane/Cell.h" +#include "crlcore/Utilities.h" +#include "crlcore/AllianceFramework.h" +#include "crlcore/Measures.h" +#include "crlcore/Histogram.h" +#include "katabatic/AutoContact.h" +#include "katabatic/GCellGrid.h" +#include "kite/DataNegociate.h" +#include "kite/TrackElement.h" +#include "kite/TrackMarker.h" +#include "kite/TrackCost.h" +#include "kite/Track.h" +#include "kite/TrackSegment.h" +#include "kite/RoutingPlane.h" +#include "kite/RoutingEventQueue.h" +#include "kite/RoutingEventHistory.h" +#include "kite/RoutingEventLoop.h" +#include "kite/NegociateWindow.h" +#include "kite/KiteEngine.h" namespace { @@ -57,69 +55,56 @@ namespace { { Interval intersect = segment->getCanonicalInterval(); - if ( not intersect.intersect(cost.getInterval()) ) return; + if (not intersect.intersect(cost.getInterval())) return; - if ( segment->isBlockage() or segment->isFixed() ) { + if (segment->isBlockage() or segment->isFixed()) { ltrace(200) << "Infinite cost from: " << segment << endl; - cost.setInfinite (); - cost.setOverlap (); - cost.setHardOverlap (); - cost.setBlockage (); + cost.setInfinite (); + cost.setOverlap (); + cost.setHardOverlap(); + cost.setBlockage (); return; } - if ( cost.getInterval().getVMax() > intersect.getVMax() ) cost.setLeftOverlap(); - if ( cost.getInterval().getVMin() < intersect.getVMin() ) cost.setRightOverlap(); + if (cost.getInterval().getVMax() > intersect.getVMax()) cost.setLeftOverlap(); + if (cost.getInterval().getVMin() < intersect.getVMin()) cost.setRightOverlap(); - //cost.setLonguestOverlap ( intersect.getSize() ); - //intersect.intersection ( cost.getInterval() ); - - if ( not intersect.contains(cost.getInterval()) ) - intersect.intersection ( cost.getInterval() ); + if (not intersect.contains(cost.getInterval())) + intersect.intersection( cost.getInterval() ); else { - cost.setLonguestOverlap ( intersect.getSize() ); - cost.setGlobalEnclosed (); + cost.setLonguestOverlap( intersect.getSize() ); + cost.setGlobalEnclosed(); } - DataNegociate* data = segment->getDataNegociate (); - if ( not data ) return; + DataNegociate* data = segment->getDataNegociate(); + if (not data) return; - cost.mergeRipupCount ( data->getRipupCount() ); + cost.mergeRipupCount( data->getRipupCount() ); if ( segment->isLocal() ) { - cost.mergeDataState ( data->getState() ); - if ( data->getState() >= DataNegociate::LocalVsGlobal ) { + cost.mergeDataState( data->getState() ); + if (data->getState() >= DataNegociate::LocalVsGlobal) { ltrace(200) << "MaximumSlack/LocalVsGlobal for " << segment << endl; } } - if ( segment->isGlobal() ) { - //if ( data->getState() >= DataNegociate::ConflictSolve1 ) { - cost.setOverlapGlobal(); - //} - if ( (cost.getFlags() & TrackCost::LocalAndTopDepth) - and (data->getState() >= DataNegociate::MoveUp) ) { - cost.setInfinite (); - cost.setOverlap (); - cost.setHardOverlap (); - return; - } + if (segment->isGlobal()) { + cost.setOverlapGlobal(); + if ( (cost.getFlags() & TrackCost::LocalAndTopDepth) + and (data->getState() >= DataNegociate::MoveUp) ) { + cost.setInfinite (); + cost.setOverlap (); + cost.setHardOverlap(); + return; + } } - // if ( data->getRipupCount() > 3 ) { - // ltrace(200) << "Infinite cost from: " << segment << endl; - // cost.setFixed (); - // cost.setInfinite (); - // cost.setOverlap (); - // cost.setHardOverlap (); - // return; - // } - - cost.setOverlap (); - if ( segment->isLocal() or (Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) < 3) ) - cost.incTerminals ( data->getCost().getTerminals()*100 ); + cost.setOverlap(); + if ( segment->isLocal() + or (cost.isForGlobal() and (Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) < 3)) ) + cost.incTerminals( data->getTerminals()*100 ); ltrace(200) << "| Increment Delta: " << DbU::getValueString(intersect.getSize()) << endl; - cost.incDelta ( intersect.getSize() ); + cost.incDelta( intersect.getSize() ); } @@ -129,24 +114,22 @@ namespace { RoutingGauge* rg = nw->getKiteEngine()->getRoutingGauge(); forEach ( Net*, inet, nw->getCell()->getNets() ) { - if ( inet->getType() == Net::Type::POWER ) continue; - if ( inet->getType() == Net::Type::GROUND ) continue; - if ( inet->getType() == Net::Type::CLOCK ) continue; - if ( af->isBLOCKAGE(inet->getName()) ) continue; + if (inet->getType() == Net::Type::POWER ) continue; + if (inet->getType() == Net::Type::GROUND) continue; + if (inet->getType() == Net::Type::CLOCK ) continue; + if (af->isBLOCKAGE(inet->getName())) continue; forEach ( RoutingPad*, irp, inet->getRoutingPads() ) { size_t depth = rg->getLayerDepth(irp->getLayer()); - if ( depth > 0 ) continue; - if ( depth == 0 ) { - TrackMarker::create ( *irp, 1 ); - //TrackMarker::create ( *irp, 2 ); - } + if (depth > 0) continue; + if (depth == 0) + TrackMarker::create( *irp, 1 ); } } } -} // End of local namespace. +} // Anonymous namespace. namespace Kite { @@ -167,6 +150,8 @@ namespace Kite { using CRL::Histogram; using CRL::addMeasure; using Katabatic::AutoContact; + using Katabatic::AutoSegmentLut; + using Katabatic::perpandicularTo; // ------------------------------------------------------------------- @@ -207,111 +192,115 @@ namespace Kite { void NegociateWindow::setGCells ( const Katabatic::GCellVector& gcells ) { _gcells = gcells; - //sort ( _gcells.begin(), _gcells.end(), Katabatic::GCell::CompareGCellById() ); - loadRoutingPads ( this ); - Session::revalidate (); + loadRoutingPads( this ); + Session::revalidate(); - TrackElement* segment; - TrackElementLut lut = Session::getKiteEngine()->_getTrackElementLut(); - TrackElementLut::iterator it = lut.begin (); + TrackElement* segment; + AutoSegmentLut lut = Session::getKiteEngine()->_getAutoSegmentLut(); + AutoSegmentLut::iterator it = lut.begin (); for ( ; it != lut.end() ; it++ ) { - segment = it->second; - segment->getDataNegociate()->update(); + segment = Session::lookup( it->second ); + if (segment) segment->getDataNegociate()->update(); } - _statistics.setGCellsCount ( _gcells.size() ); + _statistics.setGCellsCount( _gcells.size() ); } - void NegociateWindow::addInsertEvent ( TrackElement* segment, unsigned int level ) + void NegociateWindow::addRoutingEvent ( TrackElement* segment, unsigned int level ) { DataNegociate* data = segment->getDataNegociate(); - if ( not data or not data->hasRoutingEvent() ) - _eventQueue.add ( segment, level ); + if (not data or not data->hasRoutingEvent()) + _eventQueue.add( segment, level ); else - cerr << Bug("NegociateWidow::addInsertEvent(): Try to adds twice the same TrackElement event." - "\n %p:%s." - ,(void*)segment->base()->base() - ,getString(segment).c_str() + cerr << Bug( "NegociateWidow::addRoutingEvent(): Try to adds twice the same TrackElement event." + "\n %p:%s." + , (void*)segment->base()->base() + , getString(segment).c_str() ) << endl; } - TrackElement* NegociateWindow::addTrackSegment ( AutoSegment* autoSegment, bool loading ) + TrackElement* NegociateWindow::createTrackSegment ( AutoSegment* autoSegment, unsigned int flags ) { - ltrace(200) << "NegociateWindow::addTrackSegment() - " << autoSegment << endl; + ltrace(200) << "NegociateWindow::createTrackSegment() - " << autoSegment << endl; ltracein(159); // Special case: fixed AutoSegments must not interfere with blockages. // Ugly: uses of getExtensionCap(). - if ( autoSegment->isFixed() ) { + if (autoSegment->isFixed()) { RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(autoSegment->getLayer()); - Track* track = plane->getTrackByPosition ( autoSegment->getAxis() ); + Track* track = plane->getTrackByPosition( autoSegment->getAxis() ); size_t begin; size_t end; Interval fixedSpan; Interval blockageSpan; - autoSegment->getCanonical ( fixedSpan ); - fixedSpan.inflate ( Session::getExtensionCap()-1 ); + autoSegment->getCanonical( fixedSpan ); + fixedSpan.inflate( Session::getExtensionCap()-1 ); - track->getOverlapBounds ( fixedSpan, begin, end ); + track->getOverlapBounds( fixedSpan, begin, end ); for ( ; (begin < end) ; begin++ ) { TrackElement* other = track->getSegment(begin); ltrace(200) << "| overlap: " << other << endl; - if ( not other->isBlockage() ) continue; + if (not other->isBlockage()) continue; - other->getCanonical ( blockageSpan ); - blockageSpan.inflate(Session::getExtensionCap()); + other->getCanonical( blockageSpan ); + blockageSpan.inflate( Session::getExtensionCap() ); ltrace(200) << " fixed:" << fixedSpan << " vs. blockage:" << blockageSpan << endl; - if ( not fixedSpan.intersect(blockageSpan) ) continue; + if (not fixedSpan.intersect(blockageSpan)) continue; // Overlap between fixed & blockage. ltrace(200) << "* Blockage overlap: " << autoSegment << endl; - Session::destroyRequest ( autoSegment ); - - cerr << Warning("Overlap between fixed %s and blockage at %s." - ,getString(autoSegment).c_str(),getString(blockageSpan).c_str()) << endl; + Session::destroyRequest( autoSegment ); + cerr << Warning( "Overlap between fixed %s and blockage at %s." + , getString(autoSegment).c_str() + , getString(blockageSpan).c_str() ) << endl; + ltraceout(159); return NULL; } } Interval span; - autoSegment = autoSegment->getCanonical ( span ); + autoSegment = autoSegment->getCanonical( span ); bool created; - TrackElement* trackSegment = TrackSegment::create ( autoSegment, NULL, created ); + TrackElement* trackSegment = TrackSegment::create( autoSegment, NULL, created ); - if ( not loading ) + if (not (flags & KtLoadingStage)) ltrace(159) << "* lookup: " << autoSegment << endl; - if ( created ) { + if (created) { ltrace(159) << "* " << trackSegment << endl; RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(autoSegment->getLayer()); Track* track = plane->getTrackByPosition ( autoSegment->getAxis() ); - Interval uside = autoSegment->getAutoSource()->getGCell()->getUSide ( Constant::perpandicular(autoSegment->getDirection())/*, false */); + Interval uside = autoSegment->getAutoSource()->getGCell()->getSide( perpandicularTo(autoSegment->getDirection()) ); - if ( track->getAxis() > uside.getVMax() ) track = track->getPrevious(); - if ( track->getAxis() < uside.getVMin() ) track = track->getNext(); + if (track->getAxis() > uside.getVMax()) track = track->getPreviousTrack(); + if (track->getAxis() < uside.getVMin()) track = track->getNextTrack(); - trackSegment->setAxis ( track->getAxis(), Katabatic::Realignate|Katabatic::AxisSet ); - trackSegment->invalidate (); + ltrace(159) << "* GCell U-side " << uside << endl; + ltrace(159) << "* " << plane << endl; + ltrace(159) << "* " << track << endl; - if ( trackSegment->isFixed() ) { - Session::addInsertEvent ( trackSegment, track ); + trackSegment->setAxis( track->getAxis(), Katabatic::SegAxisSet ); + trackSegment->invalidate(); + + if (trackSegment->isFixed()) { + Session::addInsertEvent( trackSegment, track ); } else { - _segments.push_back ( trackSegment ); + _segments.push_back( trackSegment ); } } - if ( not created and not loading ) { + if (not created and not (flags & KtLoadingStage)) { ltrace(200) << "TrackSegment already exists (and not in loading stage)." << endl; } @@ -331,19 +320,19 @@ namespace Kite { Segment* segment; TrackElement* trackSegment; - vector* contacts = _gcells[igcell]->getContacts(); - for ( size_t i=0 ; isize() ; i++ ) { - forEach ( Hook*, ihook, (*contacts)[i]->getBodyHook()->getSlaveHooks() ) { + const vector& contacts = _gcells[igcell]->getContacts(); + for ( size_t i=0 ; igetBodyHook()->getSlaveHooks() ) { Hook* sourceHook = dynamic_cast(*ihook); - if ( not sourceHook ) continue; + if (not sourceHook) continue; segment = dynamic_cast(sourceHook->getComponent()); - trackSegment = Session::lookup ( segment ); - if ( trackSegment ) { - if ( accounteds.find(trackSegment) != accounteds.end() ) continue; + trackSegment = Session::lookup( segment ); + if (trackSegment) { + if (accounteds.find(trackSegment) != accounteds.end()) continue; - accounteds.insert ( trackSegment ); - gcellWL += DbU::getLambda ( trackSegment->getLength() ); + accounteds.insert( trackSegment ); + gcellWL += DbU::getLambda( trackSegment->getLength() ); } } } @@ -365,14 +354,14 @@ namespace Kite { AutoSegment* autoSegment; ltrace(149) << "AutoSegments from AutoContacts" << endl; - vector* contacts = gcell->getContacts(); - for ( size_t i=0 ; isize() ; i++ ) { - forEach ( Component*, component, (*contacts)[i]->getSlaveComponents() ) { + const vector& contacts = gcell->getContacts(); + for ( size_t i=0 ; igetSlaveComponents() ) { segment = dynamic_cast(*component); - autoSegment = Session::base()->lookup ( segment ); + autoSegment = Session::base()->lookup( segment ); ltrace(149) << autoSegment << endl; - if ( autoSegment and autoSegment->isCanonical() ) { - addTrackSegment ( autoSegment, true ); + if (autoSegment and autoSegment->isCanonical()) { + createTrackSegment( autoSegment, KtLoadingStage ); } } } @@ -384,21 +373,21 @@ namespace Kite { size_t NegociateWindow::_negociate () { + ltrace(500) << "Deter| NegociateWindow::_negociate()" << endl; ltrace(150) << "NegociateWindow::_negociate() - " << _segments.size() << endl; ltracein(149); cmess1 << " o Negociation Stage." << endl; unsigned long limit = _kite->getEventsLimit(); - //unsigned long limit = 25586; _eventHistory.clear(); - _eventQueue.load ( _segments ); + _eventQueue.load( _segments ); size_t count = 0; - RoutingEvent::setStage ( RoutingEvent::Negociate ); + RoutingEvent::setStage( RoutingEvent::Negociate ); while ( not _eventQueue.empty() and not isInterrupted() ) { - RoutingEvent* event = _eventQueue.pop (); + RoutingEvent* event = _eventQueue.pop(); if (tty::enabled()) { cmess2 << " getEventLevel() << ":" << event->getPriority() << "> " << event->getSegment() - //<< "> @" << DbU::getValueString(event->getSegment()->getAxis()) - //<< " id:" << event->getSegment()->getId() - //<< " " << event->getSegment()->getNet()->getName() << endl; cmess2.flush(); } - event->process ( _eventQueue, _eventHistory, _eventLoop ); + event->process( _eventQueue, _eventHistory, _eventLoop ); count++; - if ( RoutingEvent::getProcesseds() >= limit ) setInterrupt ( true ); + if (RoutingEvent::getProcesseds() >= limit) setInterrupt( true ); } - if (count and tty::enabled()) cmess1 << endl; + if (count and cmess2.enabled() and tty::enabled()) cmess1 << endl; + ltrace(500) << "Deter| Repair Stage" << endl; cmess1 << " o Repair Stage." << endl; ltrace(200) << "Loadind Repair queue." << endl; - RoutingEvent::setStage ( RoutingEvent::Repair ); + RoutingEvent::setStage( RoutingEvent::Repair ); for ( size_t i=0 ; (i<_eventHistory.size()) and not isInterrupted() ; i++ ) { RoutingEvent* event = _eventHistory.getNth(i); - if ( not event->isCloned() and event->isUnimplemented() ) { - event->reschedule ( _eventQueue, 0 ); + if (not event->isCloned() and event->isUnimplemented()) { + event->reschedule( _eventQueue, 0 ); } } - _eventQueue.commit (); + _eventQueue.commit(); count = 0; + //_eventQueue.prepareRepair(); while ( not _eventQueue.empty() and not isInterrupted() ) { - RoutingEvent* event = _eventQueue.pop (); + RoutingEvent* event = _eventQueue.pop(); if (tty::enabled()) { cmess2 << " " << tty::cr; - cmess2.flush (); + cmess2.flush(); } else { cmess2 << " getEventLevel() << ":" << event->getPriority() << "> " << event->getSegment() - //<< "> @" << DbU::getValueString(event->getSegment()->getAxis()) - //<< " id:" << event->getSegment()->getId() - //<< " " << event->getSegment()->getNet()->getName() << endl; cmess2.flush(); } - event->process ( _eventQueue, _eventHistory, _eventLoop ); + event->process( _eventQueue, _eventHistory, _eventLoop ); count++; - if ( RoutingEvent::getProcesseds() >= limit ) setInterrupt ( true ); + if (RoutingEvent::getProcesseds() >= limit ) setInterrupt( true ); } - // { - // ltrace(200) << (void*)event << " [" - // << (event->isCloned ()?"C":"-") - // << (event->isDisabled ()?"d":"-") - // << (event->isUnimplemented()?"u":"-") << "] " - // << event->getSegment() << endl; - // if ( not event->isCloned() and event->isUnimplemented() ) { - // count++; - // event->setProcessed ( false ); - // event->setMode ( RoutingEvent::Repair ); - // event->process ( _eventQueue, _eventHistory, _eventLoop ); - - // if (tty::enabled()) { - // cmess1 << " " << tty::cr; - // cmess1.flush (); - // } else { - // cmess1 << " " << endl; - // } - // } - // } - if (count and tty::enabled()) cmess1 << endl; + if (count and cmess2.enabled() and tty::enabled()) cmess1 << endl; size_t eventsCount = _eventHistory.size(); _eventHistory.clear(); _eventQueue.clear(); - if ( RoutingEvent::getAllocateds() > 0 ) { - cerr << Bug("%d events remains after clear.",RoutingEvent::getAllocateds()) << endl; + if (RoutingEvent::getAllocateds() > 0) { + cerr << Bug( "%d events remains after clear.", RoutingEvent::getAllocateds() ) << endl; } - // if ( _slowMotion && getCellWidget() ) { - // Session::close (); - // getCellWidget()->refresh(); - // Session::open ( _kiteEngine ); - // } - - _statistics.setEventsCount ( eventsCount ); + _statistics.setEventsCount( eventsCount ); ltraceout(149); return eventsCount; @@ -516,28 +472,30 @@ namespace Kite { cmess1 << " o Running Negociate Algorithm" << endl; - TrackElement::setOverlapCostCB ( NegociateOverlapCost ); - RoutingEvent::resetProcesseds (); + TrackElement::setOverlapCostCB( NegociateOverlapCost ); + RoutingEvent::resetProcesseds(); for ( size_t igcell=0 ; igcell<_gcells.size() ; ++igcell ) { - _createRouting ( _gcells[igcell] ); + _createRouting( _gcells[igcell] ); } - Session::revalidate (); + Session::revalidate(); + _kite->preProcess(); + Session::revalidate(); - getKiteEngine()->setMinimumWL ( computeWirelength() ); + getKiteEngine()->setMinimumWL( computeWirelength() ); #if defined(CHECK_DATABASE) unsigned int overlaps = 0; - Session::getKiteEngine()->_check(overlaps,"after _createRouting(GCell*)"); + Session::getKiteEngine()->_check( overlaps, "after _createRouting(GCell*)" ); #endif _slowMotion = slowMotion; - _negociate (); + _negociate(); Session::get()->isEmpty(); # if defined(CHECK_DATABASE) - _kite->_check ( overlaps, "after negociation" ); + _kite->_check( overlaps, "after negociation" ); # endif ltraceout(149); @@ -551,6 +509,7 @@ namespace Kite { cmess1 << Dots::asSizet(" - Unique Events Total" ,(RoutingEvent::getProcesseds() - RoutingEvent::getCloneds())) << endl; cmess1 << Dots::asSizet(" - # of GCells",_statistics.getGCellsCount()) << endl; + _kite->printCompletion(); addMeasure( getCell(), "Events" , RoutingEvent::getProcesseds(), 12 ); addMeasure( getCell(), "UEvents", RoutingEvent::getProcesseds()-RoutingEvent::getCloneds(), 12 ); @@ -558,27 +517,27 @@ namespace Kite { Histogram* densityHistogram = new Histogram ( 1.0, 0.1, 2 ); addMeasure( getCell(), "GCells Density Histogram", densityHistogram ); - densityHistogram->setFileExtension ( ".density.histogram" ); - densityHistogram->setMainTitle ( "GCell Densities" ); - densityHistogram->setTitle ( "Avg. Density", 0 ); - densityHistogram->setTitle ( "Peak Density", 1 ); - densityHistogram->setColor ( "green", 0 ); - densityHistogram->setColor ( "red" , 1 ); + densityHistogram->setFileExtension( ".density.histogram" ); + densityHistogram->setMainTitle ( "GCell Densities" ); + densityHistogram->setTitle ( "Avg. Density", 0 ); + densityHistogram->setTitle ( "Peak Density", 1 ); + densityHistogram->setColor ( "green", 0 ); + densityHistogram->setColor ( "red" , 1 ); const Katabatic::GCellVector* gcells = getKiteEngine()->getGCellGrid()->getGCellVector(); - getKiteEngine()->getGCellGrid()->setDensityMode ( Katabatic::GCellGrid::MaxHVDensity ); + getKiteEngine()->getGCellGrid()->setDensityMode( Katabatic::GCellGrid::MaxHVDensity ); for ( size_t igcell=0 ; igcell<(*gcells).size() ; ++igcell ) { - densityHistogram->addSample ( (*gcells)[igcell]->getDensity(), 0 ); + densityHistogram->addSample( (*gcells)[igcell]->getDensity(), 0 ); } - getKiteEngine()->getGCellGrid()->setDensityMode ( Katabatic::GCellGrid::MaxDensity ); + getKiteEngine()->getGCellGrid()->setDensityMode( Katabatic::GCellGrid::MaxDensity ); for ( size_t igcell=0 ; igcell<(*gcells).size() ; ++igcell ) { - densityHistogram->addSample ( (*gcells)[igcell]->getDensity(), 1 ); + densityHistogram->addSample( (*gcells)[igcell]->getDensity(), 1 ); } - densityHistogram->normalize ( 0 ); - densityHistogram->normalize ( 1 ); + densityHistogram->normalize( 0 ); + densityHistogram->normalize( 1 ); } @@ -587,7 +546,7 @@ namespace Kite { ostringstream os; os << "<" << _getTypeName() << ">"; - return ( os.str() ); + return os.str(); } @@ -595,9 +554,9 @@ namespace Kite { { Record* record = new Record ( _getString() ); - record->add ( getSlot ( "_gcells", _gcells ) ); - return ( record ); + record->add( getSlot( "_gcells", _gcells ) ); + return record; } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/PreProcess.cpp b/kite/src/PreProcess.cpp index 12d6bc33..3afe513a 100644 --- a/kite/src/PreProcess.cpp +++ b/kite/src/PreProcess.cpp @@ -2,14 +2,9 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 | // | | @@ -17,39 +12,35 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./PreProcess.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ - - -#include - -#include "hurricane/Bug.h" -#include "hurricane/Warning.h" -#include "hurricane/Net.h" -#include "hurricane/Name.h" -#include "hurricane/RoutingPad.h" -#include "katabatic/AutoContact.h" -#include "kite/DataNegociate.h" -#include "kite/TrackElement.h" -#include "kite/Track.h" -#include "kite/RoutingPlane.h" -#include "kite/NegociateWindow.h" -#include "kite/Session.h" -#include "kite/KiteEngine.h" - +#include +#include "hurricane/DebugSession.h" +#include "hurricane/Bug.h" +#include "hurricane/Warning.h" +#include "hurricane/Net.h" +#include "hurricane/Name.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Horizontal.h" +#include "katabatic/AutoContactTerminal.h" +#include "kite/DataNegociate.h" +#include "kite/TrackElement.h" +#include "kite/Track.h" +#include "kite/RoutingPlane.h" +#include "kite/NegociateWindow.h" +#include "kite/Session.h" +#include "kite/KiteEngine.h" namespace { - using namespace std; using namespace Hurricane; using namespace CRL; using namespace Kite; + using Katabatic::perpandicularTo; + using Katabatic::AutoContactTerminal; void getPerpandiculars ( TrackElement* segment @@ -58,9 +49,6 @@ namespace { , vector& perpandiculars ) { - //AutoContact* to = segment->base()->getAutoSource(); - //to = (to != from) ? to : segment->base()->getAutoTarget(); - TrackElement* perpandicular; forEach ( Segment*, isegment, segment->base()->getAutoSource()->getSlaveComponents().getSubSet() ) { perpandicular = Session::lookup ( *isegment ); @@ -108,21 +96,22 @@ namespace { void propagateCagedConstraints ( TrackElement* segment, set& faileds ) { - if ( not segment->isFixed() ) return; + if (not segment->isFixed()) return; ltrace(200) << "Propagate caging: " << segment << endl; Track* track = segment->getTrack(); - unsigned int direction = Session::getRoutingGauge()->getLayerDirection(segment->getLayer()); + //unsigned int direction = Session::getRoutingGauge()->getLayerDirection(segment->getLayer()); + unsigned int direction = segment->getDirection(); Katabatic::AutoContact* source = segment->base()->getAutoSource(); RoutingPad* rp = NULL; - Interval uside = source->getGCell()->getUSide(direction); + Interval uside = source->getGCell()->getSide(direction); DbU::Unit minConstraint = DbU::Min; DbU::Unit maxConstraint = DbU::Max; vector perpandiculars; if ( not track ) { - cerr << Bug("%s is not inserted in a ",getString(segment).c_str()) << endl; + cerr << Bug( "%s is not inserted in a ", getString(segment).c_str() ) << endl; return; } @@ -130,30 +119,30 @@ namespace { TrackElement* parallel; size_t i = segment->getIndex(); while ( i > 0 ) { - parallel = track->getSegment(--i); - if ( not parallel ) continue; - if ( parallel->getTargetU() < uside.getVMin() ) break; - if ( parallel->getNet() == segment->getNet() ) continue; - if ( not parallel->isFixed() ) continue; + parallel = track->getSegment( --i ); + if (not parallel) continue; + if (parallel->getTargetU() < uside.getVMin()) break; + if (parallel->getNet() == segment->getNet()) continue; + if (not parallel->isFixed()) continue; ltrace(200) << "Min Constraint from: " << parallel << endl; - minConstraint = max ( minConstraint, parallel->getTargetU() ); + minConstraint = max( minConstraint, parallel->getTargetU() ); } i = segment->getIndex(); while ( i < track->getSize()-1 ) { - parallel = track->getSegment(++i); - if ( not parallel ) continue; - if ( parallel->getSourceU() > uside.getVMax() ) break; - if ( parallel->getNet() == segment->getNet() ) continue; - if ( not parallel->isFixed() ) continue; + parallel = track->getSegment( ++i ); + if (not parallel) continue; + if (parallel->getSourceU() > uside.getVMax()) break; + if (parallel->getNet() == segment->getNet()) continue; + if (not parallel->isFixed()) continue; ltrace(200) << "Max Constraint from: " << parallel << endl; - maxConstraint = min ( maxConstraint, parallel->getSourceU() ); + maxConstraint = min( maxConstraint, parallel->getSourceU() ); } - if ( minConstraint > maxConstraint ) { - cerr << Bug("%s have too tight caging constraints.",getString(segment).c_str()) << endl; + if (minConstraint > maxConstraint) { + cerr << Bug( "%s have too tight caging constraints.", getString(segment).c_str() ) << endl; return; } if ( (minConstraint <= uside.getVMin()) and (maxConstraint >= uside.getVMax()) ) { @@ -164,29 +153,29 @@ namespace { } // Finding perpandiculars, by way of the source & target RoutingPad. - if ( source->getAnchor() ) { + if (source->getAnchor()) { rp = dynamic_cast(source->getAnchor()); - if ( rp ) { + if (rp) { TrackElement* parallel; forEach ( Segment*, isegment, rp->getSlaveComponents().getSubSet() ) { - parallel = Session::lookup ( *isegment ); + parallel = Session::lookup( *isegment ); ltrace(200) << "* " << parallel << endl; - if ( parallel->isFixed () ) continue; - if ( parallel->isGlobal() ) continue; - getPerpandiculars ( parallel, source, direction, perpandiculars ); - getPerpandiculars ( parallel, segment->base()->getAutoTarget(), direction, perpandiculars ); + if (parallel->isFixed ()) continue; + if (parallel->isGlobal()) continue; + getPerpandiculars( parallel, source, direction, perpandiculars ); + getPerpandiculars( parallel, segment->base()->getAutoTarget(), direction, perpandiculars ); } } else { - cerr << Bug("%s is not anchored on a \n (%s)" - ,getString(source).c_str() - ,getString(source->getAnchor()).c_str()) << endl; + cerr << Bug( "%s is not anchored on a \n (%s)" + , getString(source).c_str() + , getString(source->getAnchor()).c_str() ) << endl; } } // Apply caging constraints to perpandiculars. ltracein(200); - if ( perpandiculars.size() == 0 ) { + if (perpandiculars.size() == 0) { ltrace(200) << "No perpandiculars to " << segment << endl; ltraceout(200); return; @@ -195,10 +184,10 @@ namespace { Interval constraints ( minConstraint, maxConstraint ); for ( size_t iperpand=0 ; iperpandbase()->mergeUserConstraints ( constraints ); - if ( perpandiculars[iperpand]->base()->getUserConstraints().isEmpty() ) { + perpandiculars[iperpand]->base()->mergeUserConstraints( constraints ); + if (perpandiculars[iperpand]->base()->getUserConstraints().isEmpty()) { ltrace(200) << "Cumulative caged constraints are too tight on " << perpandiculars[iperpand] << endl; - findFailedPerpandiculars ( rp, direction, faileds ); + findFailedPerpandiculars( rp, direction, faileds ); } } @@ -206,81 +195,108 @@ namespace { } + void moveUpCaged ( TrackElement* segment ) + { + DebugSession::open( segment->getNet(), 150 ); + ltrace(150) << "::moveUpCaged() " << segment << endl; + ltracein(150); + + //Configuration* configuration = Session::getConfiguration(); + //const Layer* metal2 = configuration->getRoutingLayer( 1 ); + //const Layer* metal3 = configuration->getRoutingLayer( 2 ); + + Katabatic::AutoContact* support = segment->base()->getAutoSource(); + RoutingPad* rp = dynamic_cast(support->getAnchor()); + + forEach( Component*, icomponent, rp->getSlaveComponents() ) { + Horizontal* baseSegment = dynamic_cast( *icomponent ); + TrackElement* accessSegment = Session::lookup( baseSegment ); + + if (accessSegment and not accessSegment->isFixed()) { + accessSegment->moveUp( Katabatic::KbNoFlags ); + } + } + + ltraceout(150); + DebugSession::close(); + } + + void protectCagedTerminals ( Track* track ) { - Configuration* configuration = Session::getConfiguration (); - const Layer* metal2 = configuration->getRoutingLayer ( 1 ); - const Layer* metal3 = configuration->getRoutingLayer ( 2 ); + ltrace(150) << "protectCagedTerminals() " << track << endl; + ltracein(150); - for ( size_t i=0 ; igetSize() ; i++ ) { - TrackElement* segment = track->getSegment ( i ); + DbU::Unit lastMovedUp = track->getMin(); + unsigned int moveUpCount = 0; + + Configuration* configuration = Session::getConfiguration(); + const Layer* metal2 = configuration->getRoutingLayer( 1 ); + const Layer* metal3 = configuration->getRoutingLayer( 2 ); + Net* neighborNet = NULL; + + if (track->getLayer() != metal2) { + ltraceout(150); + return; + } + + for ( size_t i=0 ; igetSize() ; ++i ) { + TrackElement* segment = track->getSegment(i); if ( segment and segment->isFixed() and segment->isTerminal() ) { - Interval freeInterval = track->getFreeInterval ( segment->getSourceU(), segment->getNet() ); + Interval freeInterval = track->getFreeInterval( segment->getSourceU(), segment->getNet() ); - if ( freeInterval.getSize() < DbU::lambda(30.0) ) { + //if (freeInterval.getSize() < DbU::lambda(5.0)*6) { + if ( (segment->getSourceU() - freeInterval.getVMin() < DbU::lambda(5.0)*3) + or (freeInterval.getVMax() - segment->getTargetU() < DbU::lambda(5.0)*3) ) { cinfo << "Caged terminal: " << segment << endl; - if ( segment->getLayer() != metal2 ) continue; - if ( segment->getLength() >= DbU::lambda(5.0) ) continue; + if ( (segment->getLayer() != metal2) + or (segment->getLength() >= DbU::lambda(5.0)) + or (segment->getNet() == neighborNet) ) { + neighborNet = segment->getNet(); + continue; + } + + if (segment->getSourceU() - lastMovedUp < DbU::lambda(5.0)*4) { + ++moveUpCount; + if (moveUpCount % 2 == 0) { + moveUpCaged( segment ); + } + } else { + moveUpCount = 0; + } + lastMovedUp = segment->getSourceU(); Katabatic::AutoContact* support = segment->base()->getAutoSource(); RoutingPad* rp = dynamic_cast(support->getAnchor()); - + Katabatic::AutoContact* source - = Katabatic::AutoContact::fromRp ( support->getGCell() - , rp - , metal3 - , rp->getSourcePosition() - , DbU::lambda(1.0), DbU::lambda(1.0) - , true - ); - + = Katabatic::AutoContactTerminal::create( support->getGCell() + , rp + , metal3 + , rp->getSourcePosition() + , DbU::lambda(1.0), DbU::lambda(1.0) + ); + source->setFlags( Katabatic::CntIgnoreAnchor ); + Katabatic::AutoContact* target = - Katabatic::AutoContact::fromRp ( support->getGCell() - , rp - , metal3 - , rp->getSourcePosition() - , DbU::lambda(1.0), DbU::lambda(1.0) - , true - ); - - AutoSegment* segment = AutoSegment::create ( source - , target - , Constant::Vertical - , AutoSegment::Local - , true - , false - ); - segment->setFixed ( true ); - Session::getNegociateWindow()->addTrackSegment ( segment, true ); - -#if DISABLED - // Force slackening. - bool breakFlag = false; - forEach ( Contact*, icontact, rp->getSlaveComponents().getSubSet() ) { - forEach ( Segment*, isegment, icontact->getSlaveComponents().getSubSet() ) { - TrackElement* trackSegment = Session::lookup(*isegment); - if ( not trackSegment or trackSegment->isFixed() ) continue; - - if ( trackSegment->isHorizontal() ) { - ltrace(200) << "M2 to slacken for " << rp << endl; - breakFlag = true; - - const vector& dogLegs = Session::getDogLegs(); - - trackSegment->base()->makeDogLeg ( gcell->base(), true ); - GCell::addTrackSegment ( gcell, dogLegs[1], true ); - GCell::addTrackSegment ( gcell, dogLegs[2], true ); - Session::revalidate (); - } - - if ( breakFlag ) break; - } - if ( breakFlag ) break; - } -#endif + Katabatic::AutoContactTerminal::create( support->getGCell() + , rp + , metal3 + , rp->getSourcePosition() + , DbU::lambda(1.0), DbU::lambda(1.0) + ); + target->setFlags( Katabatic::CntIgnoreAnchor ); + + AutoSegment* fixedSegment = AutoSegment::create( source, target, Katabatic::KbVertical ); + fixedSegment->setFlags( Katabatic::SegFixed ); + Session::getNegociateWindow()->createTrackSegment( fixedSegment, KtLoadingStage ); } + + neighborNet = segment->getNet(); } } + + ltraceout(150); } @@ -293,17 +309,18 @@ namespace Kite { using Hurricane::Bug; using Hurricane::Net; using Hurricane::Name; + using Katabatic::AutoSegmentLut; void KiteEngine::preProcess () { - for ( size_t i=0 ; i<_routingPlanes.size() ; i++ ) { + for ( size_t i=0 ; i<_routingPlanes.size() ; ++i ) { RoutingPlane* plane = _routingPlanes[i]; - Track* track = plane->getTrackByIndex ( 0 ); + Track* track = plane->getTrackByIndex( 0 ); while ( track ) { - protectCagedTerminals ( track ); - track = track->getNext (); + protectCagedTerminals( track ); + track = track->getNextTrack(); } } Session::revalidate (); @@ -314,32 +331,17 @@ namespace Kite { { set faileds; - TrackElementLut::iterator isegment = _trackSegmentLut.begin(); - for ( ; isegment != _trackSegmentLut.end() ; isegment++ ) { - if ( not isegment->second->isFixed() ) continue; - propagateCagedConstraints ( isegment->second, faileds ); + TrackElement* segment = NULL; + AutoSegmentLut::const_iterator isegment = _getAutoSegmentLut().begin(); + for ( ; isegment != _getAutoSegmentLut().end() ; isegment++ ) { + segment = _lookup( isegment->second ); + if (not segment or not segment->isFixed()) continue; + + DebugSession::open( segment->getNet() ); + propagateCagedConstraints( segment, faileds ); + DebugSession::close(); } } - void KiteEngine::_computeCagedConstraints ( Net* net, set& faileds ) - { - TrackElement* segment = NULL; - - forEach ( Segment*, isegment, net->getComponents().getSubSet() ) { - segment = Session::lookup ( *isegment ); - if ( not segment ) continue; - - segment->base()->resetUserConstraints(); - } - - forEach ( Segment*, isegment, net->getComponents().getSubSet() ) { - segment = Session::lookup ( *isegment ); - if ( not segment ) continue; - - propagateCagedConstraints ( segment, faileds ); - } - } - - -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/ProtectRoutingPads.cpp b/kite/src/ProtectRoutingPads.cpp index b1e8eee5..90926c42 100644 --- a/kite/src/ProtectRoutingPads.cpp +++ b/kite/src/ProtectRoutingPads.cpp @@ -2,14 +2,9 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 | // | | @@ -17,36 +12,32 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./ProtectRoutingPads.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#include -#include - -#include "hurricane/DataBase.h" -#include "hurricane/Technology.h" -#include "hurricane/BasicLayer.h" -#include "hurricane/RegularLayer.h" -#include "hurricane/Horizontal.h" -#include "hurricane/Vertical.h" -#include "hurricane/RoutingPad.h" -#include "hurricane/Occurrence.h" -#include "hurricane/Cell.h" -#include "hurricane/NetExternalComponents.h" -#include "crlcore/Catalog.h" -#include "katabatic/AutoContact.h" -#include "katabatic/AutoSegment.h" -#include "katabatic/GCell.h" -#include "katabatic/GCellGrid.h" -#include "katabatic/KatabaticEngine.h" -#include "kite/RoutingPlane.h" -#include "kite/TrackSegment.h" -#include "kite/TrackFixedSegment.h" -#include "kite/Track.h" -#include "kite/KiteEngine.h" +#include +#include +#include "hurricane/DataBase.h" +#include "hurricane/Technology.h" +#include "hurricane/BasicLayer.h" +#include "hurricane/RegularLayer.h" +#include "hurricane/Horizontal.h" +#include "hurricane/Vertical.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Occurrence.h" +#include "hurricane/Cell.h" +#include "hurricane/NetExternalComponents.h" +#include "crlcore/Catalog.h" +#include "katabatic/AutoContact.h" +#include "katabatic/AutoSegment.h" +#include "katabatic/GCell.h" +#include "katabatic/GCellGrid.h" +#include "katabatic/KatabaticEngine.h" +#include "kite/RoutingPlane.h" +#include "kite/TrackSegment.h" +#include "kite/TrackFixedSegment.h" +#include "kite/Track.h" +#include "kite/KiteEngine.h" namespace { @@ -114,12 +105,12 @@ namespace { transformation.applyOn ( bb ); //cinfo << "bb: " << bb << endl; - if ( direction == Constant::Horizontal ) { + if ( direction == KbHorizontal ) { 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->getNext() ) { + for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNextTrack() ) { Horizontal* segment = Horizontal::create ( rp->getNet() , segments[i]->getLayer() , track->getAxis() @@ -134,7 +125,7 @@ namespace { DbU::Unit axisMax = bb.getXMax() + delta; Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior ); - for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) { + for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNextTrack() ) { Vertical* segment = Vertical::create ( rp->getNet() , segments[i]->getLayer() , track->getAxis() @@ -167,9 +158,6 @@ namespace Kite { cmess1 << " o Protect external components not useds as RoutingPads." << endl; forEach ( Net*, inet, getCell()->getNets() ) { - // cerr << *inet << " isSupply():" << (*inet)->isSupply() - // << " " << (*inet)->getType() - // << endl; if ( (*inet)->isSupply() ) continue; vector rps; @@ -185,4 +173,4 @@ namespace Kite { } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/PyGraphicKiteEngine.cpp b/kite/src/PyGraphicKiteEngine.cpp index 41bf4bee..15f29db6 100644 --- a/kite/src/PyGraphicKiteEngine.cpp +++ b/kite/src/PyGraphicKiteEngine.cpp @@ -2,7 +2,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2013, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | diff --git a/kite/src/PyKite.cpp b/kite/src/PyKite.cpp index 5c3dc9ab..f884b2a3 100644 --- a/kite/src/PyKite.cpp +++ b/kite/src/PyKite.cpp @@ -2,7 +2,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved +// Copyright (c) UPMC/LIP6 2012-2013, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -68,30 +68,30 @@ extern "C" { DL_EXPORT(void) initKite () { trace << "initKite()" << endl; - PyKiteEngine_LinkPyType (); - PyGraphicKiteEngine_LinkPyType (); + PyKiteEngine_LinkPyType(); + PyGraphicKiteEngine_LinkPyType(); - PYTYPE_READY_SUB ( KiteEngine , ToolEngine ); - PYTYPE_READY_SUB ( GraphicKiteEngine, GraphicTool ); + PYTYPE_READY_SUB( KiteEngine , ToolEngine ); + PYTYPE_READY_SUB( GraphicKiteEngine, GraphicTool ); - PyObject* module = Py_InitModule ( "Kite", PyKite_Methods ); - if ( module == NULL ) { + PyObject* module = Py_InitModule( "Kite", PyKite_Methods ); + if (module == NULL) { cerr << "[ERROR]\n" << " Failed to initialize Kite module." << endl; return; } - Py_INCREF ( &PyTypeKiteEngine ); - PyModule_AddObject ( module, "KiteEngine", (PyObject*)&PyTypeKiteEngine ); - Py_INCREF ( &PyTypeGraphicKiteEngine ); - PyModule_AddObject ( module, "GraphicKiteEngine", (PyObject*)&PyTypeGraphicKiteEngine ); + Py_INCREF( &PyTypeKiteEngine ); + PyModule_AddObject( module, "KiteEngine", (PyObject*)&PyTypeKiteEngine ); + Py_INCREF( &PyTypeGraphicKiteEngine ); + PyModule_AddObject( module, "GraphicKiteEngine", (PyObject*)&PyTypeGraphicKiteEngine ); - PyObject* dictionnary = PyModule_GetDict(module); + PyObject* dictionnary = PyModule_GetDict( module ); PyObject* constant; - LoadObjectConstant(dictionnary,BuildGlobalSolution,"BuildGlobalSolution"); - LoadObjectConstant(dictionnary,LoadGlobalSolution ,"LoadGlobalSolution" ); + LoadObjectConstant( dictionnary, KtBuildGlobalRouting, "KtBuildGlobalRouting" ); + LoadObjectConstant( dictionnary, KtLoadGlobalRouting , "KtLoadGlobalRouting" ); } diff --git a/kite/src/PyKiteEngine.cpp b/kite/src/PyKiteEngine.cpp index 0c28bf1d..ef247664 100644 --- a/kite/src/PyKiteEngine.cpp +++ b/kite/src/PyKiteEngine.cpp @@ -2,7 +2,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2010-2012, All Rights Reserved +// Copyright (c) UPMC/LIP6 2010-2013, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | diff --git a/kite/src/RoutingEvent.cpp b/kite/src/RoutingEvent.cpp index 09e56fc0..b9c9d89b 100644 --- a/kite/src/RoutingEvent.cpp +++ b/kite/src/RoutingEvent.cpp @@ -2,7 +2,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -15,3497 +15,52 @@ // +-----------------------------------------------------------------+ -#include -#include -#include -#include "vlsisapd/configuration/Configuration.h" -#include "hurricane/Bug.h" -#include "hurricane/DebugSession.h" -#include "hurricane/Breakpoint.h" -#include "hurricane/Net.h" -#include "hurricane/Layer.h" -#include "katabatic/AutoContact.h" -#include "kite/DataNegociate.h" -#include "kite/TrackElement.h" -#include "kite/Track.h" -#include "kite/Tracks.h" -#include "kite/RoutingPlane.h" -#include "kite/RoutingEvent.h" -#include "kite/RoutingEventHistory.h" -#include "kite/RoutingEventQueue.h" -#include "kite/RoutingEventLoop.h" -#include "kite/NegociateWindow.h" -#include "kite/Session.h" -#include "kite/KiteEngine.h" - - -namespace { - - /*! \defgroup ClassManipulator Manipulator Class - */ - - //! \addtogroup ClassManipulator - //! \{ - - /*! \class Manipulator - * \brief Handle \TrackElement ripup & topological modifications. - * - * Handles all \TrackElement modifications. - */ - - /*! \function Manipulator::Manipulator ( TrackElement* segment, State& state ); - * \param segment The \TrackElement to manipulate. - * \param state The \RoutingEvent state. - */ - - /*! \function TrackElement* Manipulator::getSegment () const; - * \Return The working \TrackElement. - */ - - /*! \function DataNegociate* Manipulator::getData () const; - * \Return The DataNegociate of the \TrackElement. - */ - - /*! \function RoutingEvent* Manipulator::getEvent () const; - * \Return The \RoutingEvent associated to the \TrackElement. May be - * \NULL if it belongs to a more prioritary GCell RoutingSet. - */ - - /*! \function bool Manipulator::canRipup () const; - * \return \true if the maximum ripup & reset count has not been reached. - */ - - /*! \function bool Manipulator::ripup ( Interval overlap, unsigned int type, DbU::Unit axisHint ); - * \param overlap The Interval that should be cleared. - * \param type The type of ripup action. - * \param axisHint An indication as where to move the riped up segment. - * \return \True if the operation has succedeed. - * - * If the \TrackElement cannot be riped up (it cames from a more - * prioritary GCell RoutingSet), then it tries to relax it. - */ - - /*! \function bool Manipulator::ripup ( DbU::Unit point, unsigned int type, DbU::Unit axisHint ); - * \param point The point around which the \Track should be cleared. - * \param type The type of ripup action. - * \param axisHint An indication as where to move the riped up segment. - * \return \True if the operation has succedeed. - * - * \see The other ripup method. - */ - - /*! \function bool Manipulator::relax ( Interval overlap ); - * \param overlap The overlaping interval to free. - * \return \true if the operation has succeeded. - * - * Finds the appropriate dogleg GCells to break the \TrackElement. - * There could be one or two breaks whether the overlap is fully - * enclosed or not. - */ - - /*! \function bool Manipulator::modifyTopology (); - * \return \true if the operation has succeeded. - * - * Try to changes the \TrackElement topology. - */ - - /*! \function bool Manipulator::insertInTrack ( size_t i ); - * \param i The index of \Track into which insert. - * \return \true if the operation has succeeded. - * - * Try to insert the \TrackElement into the \Track i. - * The index is relative to the State's \Track vector. - */ - - /*! \function bool Manipulator::desalignate (); - * \return \true if the operation has succeeded. - * - * Try to desalignate the \TrackElement. - */ - - /*! \function bool Manipulator::slacken (); - * \return \true if the operation has succeeded. - * - * Try to slacken the \TrackElement. - */ - - /*! \function bool Manipulator::moveUp (); - * \return \true if the operation has succeeded. - * - * Try to move up the \TrackElement. - */ - - /*! \function bool Manipulator::makeDogLeg (); - * \return \true if the operation has succeeded. - * - * Try to make a dog leg on the \TrackElement. - * This method is restricted to local \TrackElement only. - */ - - /*! \function bool Manipulator::minimize (); - * \return \true if the operation has succeeded. - * - * Try to mimize the wirelength of the \TrackElement. - * This operation can only be done once. - */ - - /*! \function bool Manipulator::relax ( size_t i ); - * \param i The index of the selected \Track. - * \return \true if the operation has succeeded. - * - * Try to make a dog leg on the \TrackElement. - * This method is restricted to local \TrackElement only. - */ - - //! \} - - - using namespace std; - using namespace Hurricane; - using namespace Kite; - using Katabatic::GCell; - - -// ------------------------------------------------------------------- -// Class : "LvGCandidate". - - - class LvGCandidate { - public: - struct Compare : public binary_function { - inline bool operator() ( const LvGCandidate& lhs, const LvGCandidate& rhs ) const; - }; - public: - inline LvGCandidate ( TrackElement* segment=NULL, Interval overlap=Interval(), size_t terminals=0 ); - inline TrackElement* getSegment () const; - inline const Interval& getOverlap () const; - inline size_t getTerminals () const; - private: - TrackElement* _segment; - Interval _overlap; - size_t _terminals; - }; - - inline LvGCandidate::LvGCandidate ( TrackElement* segment, Interval overlap, size_t terminals ) - : _segment (segment) - , _overlap (overlap) - , _terminals(terminals) - { } - - inline TrackElement* LvGCandidate::getSegment () const { return _segment; } - inline const Interval& LvGCandidate::getOverlap () const { return _overlap; } - inline size_t LvGCandidate::getTerminals () const { return _terminals; } - - inline bool LvGCandidate::Compare::operator() ( const LvGCandidate& lhs, const LvGCandidate& rhs ) const - { - if ( lhs.getTerminals() != rhs.getTerminals() ) - return lhs.getTerminals() < rhs.getTerminals(); - - if ( lhs.getOverlap() != rhs.getOverlap() ) - return lhs.getOverlap().getSize() > rhs.getOverlap().getSize(); - - return lhs.getSegment()->getAxis() < rhs.getSegment()->getAxis(); - } - - -// ------------------------------------------------------------------- -// Class : "Cs1Candidate". - - - class Cs1Candidate { - public: - inline Cs1Candidate ( Track* track=NULL ); - inline Track* getTrack () const; - inline size_t getBegin () const; - inline size_t getEnd () const; - inline size_t getLength () const; - inline Interval getConflict ( size_t ); - inline Interval getLongestConflict () const; - inline DbU::Unit getBreakPos () const; - inline DbU::Unit getConflictLength () const; - inline void setBegin ( size_t ); - inline void setEnd ( size_t ); - inline void addConflict ( const Interval& ); - void consolidate (); - public: - friend inline bool operator< ( const Cs1Candidate&, const Cs1Candidate& ); - private: - Track* _track; - size_t _begin; - size_t _end; - vector _conflicts; - Interval _longestConflict; - DbU::Unit _breakPos; - DbU::Unit _conflictLength; - }; - - - inline Cs1Candidate::Cs1Candidate ( Track* track ) - : _track (track) - , _begin (0) - , _end (0) - , _conflicts () - , _longestConflict() - , _breakPos (0) - , _conflictLength (0) - { } - - inline Track* Cs1Candidate::getTrack () const { return _track; } - inline size_t Cs1Candidate::getBegin () const { return _begin; } - inline size_t Cs1Candidate::getEnd () const { return _end; } - inline size_t Cs1Candidate::getLength () const { return _conflicts.size(); } - inline Interval Cs1Candidate::getLongestConflict () const { return _longestConflict; } - inline DbU::Unit Cs1Candidate::getBreakPos () const { return _breakPos; } - inline void Cs1Candidate::setBegin ( size_t i ) { _begin=i; } - inline void Cs1Candidate::setEnd ( size_t i ) { _end=i; } - - inline void Cs1Candidate::addConflict ( const Interval& conflict ) - { - _conflicts.push_back(conflict); - _conflictLength += conflict.getSize(); - - if ( conflict.getSize() > _longestConflict.getSize() ) - _longestConflict = conflict; - } - - inline Interval Cs1Candidate::getConflict ( size_t i ) - { - if (i >= _conflicts.size()) return Interval(); - return _conflicts[i]; - } - - inline bool operator< ( const Cs1Candidate& lhs, const Cs1Candidate& rhs ) - { - //DbU::Unit delta = lhs._conflicts.size() - rhs._conflicts.size(); - DbU::Unit delta = lhs._longestConflict.getSize() - rhs._longestConflict.getSize(); - if ( delta < 0 ) return true; - if ( delta > 0 ) return false; - - return lhs._conflictLength < rhs._conflictLength; - } -//{ return lhs._conflictLength < rhs._conflictLength; } - - void Cs1Candidate::consolidate () - { - if ( _conflicts.size() > 0 ) { - DbU::Unit halfConflict = 0; - size_t i = 0; - for ( ; i<_conflicts.size()-1 ; ++i ) { - halfConflict += _conflicts.size(); - if ( halfConflict > _conflictLength/2 ) - break; - } - - // Ugly: hard-coded pitch. - _breakPos = _conflicts[i].getVMin() - DbU::lambda(5.0); - } - } - - -// ------------------------------------------------------------------- -// Class : "FindPath". - - - class PathElement { - public: - class UniqCompare { - public: - inline bool operator () ( const PathElement*, const PathElement* ); - }; - public: - class QueueCompare { - public: - inline bool operator() ( const PathElement*, const PathElement* ); - }; - public: - PathElement ( PathElement*, Track*, const Interval& span ); - inline PathElement* getBack () const; - inline Track* getTrack () const; - inline const Interval& getSpan () const; - private: - PathElement* _back; - Track* _track; - Interval _span; - }; - - - typedef priority_queue< PathElement*, vector, PathElement::QueueCompare > PathElementQueue; - typedef set< PathElement*, PathElement::UniqCompare > UniqPathElement; - - - PathElement::PathElement ( PathElement* back, Track* track, const Interval& span ) - : _back (back) - , _track(track) - , _span (span) - { } - - - inline PathElement* PathElement::getBack () const { return _back; } - inline Track* PathElement::getTrack () const { return _track; } - inline const Interval& PathElement::getSpan () const { return _span; } - - - bool PathElement::QueueCompare::operator() ( const PathElement* lhs, const PathElement* rhs ) - { - DbU::Unit delta = lhs->getSpan().getSize() - rhs->getSpan().getSize(); - if ( delta < 0 ) return true; - if ( delta > 0 ) return false; - - delta = lhs->getSpan().getVMax() - rhs->getSpan().getVMax(); - if ( delta < 0 ) return true; - - delta = lhs->getTrack()->getAxis() - rhs->getTrack()->getAxis(); - if ( delta > 0 ) return true; - - return false; - } - - - inline bool PathElement::UniqCompare::operator () ( const PathElement* lhs, const PathElement* rhs ) - { - DbU::Unit delta = lhs->getTrack()->getAxis() - rhs->getTrack()->getAxis(); - if ( delta < 0 ) return true; - if ( delta > 0 ) return false; - - delta = lhs->getSpan().getVMin() - rhs->getSpan().getVMin(); - if ( delta < 0 ) return true; - - return false; - } - - - class FindPath { - public: - FindPath ( const vector& - , Net* - , DbU::Unit from - , DbU::Unit to - ); - inline Net* getNet () const; - inline DbU::Unit getFrom () const; - inline DbU::Unit getTo () const; - inline const vector& getTracks () const; - const vector& computeDoglegPos ( DbU::Unit allowedGap ); - private: - Net* _net; - vector _tracks; - DbU::Unit _from; - DbU::Unit _to; - vector _doglegPos; - }; - - - FindPath::FindPath ( const vector& tracks, Net* net, DbU::Unit from, DbU::Unit to ) - : _net (net) - , _tracks (tracks) - , _from (from) - , _to (to) - , _doglegPos() - { } - - - inline Net* FindPath::getNet () const { return _net; } - inline DbU::Unit FindPath::getFrom () const { return _from; } - inline DbU::Unit FindPath::getTo () const { return _to; } - inline const vector& FindPath::getTracks () const { return _tracks; } - - const vector& FindPath::computeDoglegPos ( DbU::Unit allowedGap ) - { - PathElementQueue peQueue; - UniqPathElement peUniq; - - ltrace(200) << "FindPath::computeDoglegPos()" << endl; - ltracein(200); - - allowedGap /= 2; - - // Initial loading of the queue. - for ( size_t itrack=0; itrack < _tracks.size() ; ++itrack ) { - Interval span ( _tracks[itrack]->getFreeInterval(_from,_net)); - span.inflate ( allowedGap ); - - if ( not span.contains(_from) ) continue; - if ( span.contains(_to) ) continue; - - PathElement* pe = new PathElement(NULL,_tracks[itrack],span); - if ( peUniq.find(pe) != peUniq.end() ) { delete pe; continue; } - - ltrace(200) << "| Start Push: " << pe->getSpan() << " " << pe->getTrack() << endl; - - peUniq.insert ( pe ); - peQueue.push ( pe ); - } - - // Queue exploration. - while ( not peQueue.empty() ) { - PathElement* pe = peQueue.top (); - peQueue.pop (); - - ltrace(200) << "| Pop: " << pe->getSpan() << " " << pe->getTrack() << endl; - - // Ugly: hard-coded pitch. - DbU::Unit fromPos = pe->getSpan().getVMax() - DbU::lambda(5.0); - - for ( size_t itrack=0; itrack < _tracks.size() ; ++itrack ) { - ltrace(200) << "| Looking: " << _tracks[itrack] << endl; - - Interval toSpan ( _tracks[itrack]->getFreeInterval(fromPos,_net) ); - toSpan.inflate ( allowedGap ); - if ( not toSpan.contains(fromPos) or (pe->getSpan().getVMax() >= toSpan.getVMax()) ) - continue; - - // <_to> position reached, backtrack. - if ( toSpan.contains(_to) ) { - ltrace(200) << "| NoPush: " << toSpan << " " << _tracks[itrack] << endl; - - vector doglegPos; - - PathElement* fromPe = pe; - while ( fromPe ) { - doglegPos.insert ( doglegPos.begin(), fromPe->getSpan().getVMax()-DbU::lambda(5.0) ); - fromPe = fromPe->getBack(); - } - ltrace(200) << "| Path found (" << doglegPos.size() << " doglegs)" << endl; - for ( size_t ipos=0 ; iposgetSpan() << " " << toPe->getTrack() << endl; - } - } - - UniqPathElement::iterator ipe = peUniq.begin(); - for ( ; ipe != peUniq.end() ; ++ipe ) delete (*ipe); - - ltraceout(200); - return _doglegPos; - } - - -// ------------------------------------------------------------------- -// Class : "UnionItervals". - - - class UnionIntervals { - public: - inline UnionIntervals (); - void addInterval ( Interval& ); - inline size_t size () const; - inline bool empty () const; - inline list::const_iterator begin () const; - inline list::const_iterator end () const; - inline DbU::Unit getVMin () const; - inline DbU::Unit getVMax () const; - string _getString (); - private: - list _intervals; - }; - - - inline UnionIntervals::UnionIntervals () : _intervals() { } - inline list::const_iterator UnionIntervals::begin () const { return _intervals.begin(); } - inline list::const_iterator UnionIntervals::end () const { return _intervals.end(); } - inline size_t UnionIntervals::size () const { return _intervals.size(); } - inline bool UnionIntervals::empty () const { return _intervals.empty(); } - inline DbU::Unit UnionIntervals::getVMin () const { return (empty()) ? DbU::Max : (*begin()).getVMin(); } - inline DbU::Unit UnionIntervals::getVMax () const { return (empty()) ? DbU::Min : (*begin()).getVMax(); } - - - void UnionIntervals::addInterval ( Interval& interval ) - { - ltrace(200) << "UnionInterval::addInterval() - " << interval << endl; - - list::iterator iintv = _intervals.begin (); - - bool merged = false; - while ( iintv != _intervals.end() ) { - if ( !merged ) { - if ( interval.getVMax() < (*iintv).getVMin() ) { _intervals.insert ( iintv, interval ); return; } - if ( interval.getVMin() > (*iintv).getVMax() ) { iintv++; continue; } - - merged = true; - interval = (*iintv).merge ( interval ); - iintv++; - } else { - if ( (*iintv).intersect ( interval ) ) { - interval = (*iintv).merge ( interval ); - iintv = _intervals.erase ( iintv ); - continue; - } else - break; - } - } - - if ( !merged ) _intervals.push_back ( interval ); - } - - - string UnionIntervals::_getString () - { - ostringstream s; - - list::iterator iintv = _intervals.begin(); - for ( ; iintv != _intervals.end() ; iintv++ ) { - s << " [" << DbU::getValueString((*iintv).getVMin()) - << ":" << DbU::getValueString((*iintv).getVMax()) << "]"; - } - return s.str(); - } - - -// ------------------------------------------------------------------- -// Class : "RipupHistory". - - - class RipupHistory { - public: - RipupHistory ( RoutingEvent* ); - inline bool isDislodger ( RoutingEvent* ) const; - inline size_t size () const; - inline size_t getDislodgersCount () const; - void addAxis ( DbU::Unit ); - void addAxis ( RoutingEvent* ); - bool hasAxis ( DbU::Unit ) const; - UnionIntervals* getUnionIntervals ( DbU::Unit ); - void addDislodger ( RoutingEvent* ); - void addDislodger ( TrackElement* ); - void print ( ostream& ); - private: - RoutingEvent* _masterEvent; - map _dislodgers; - size_t _dislodgersCount; - }; - - - RipupHistory::RipupHistory ( RoutingEvent* event ) - : _masterEvent(event) - , _dislodgers() - , _dislodgersCount(0) - { - const Interval& perpandicular = _masterEvent->getPerpandicular(); - RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(_masterEvent->getSegment()->getLayer()); - Track* track; - if ( !perpandicular.isEmpty() ) { - track = plane->getTrackByPosition(perpandicular.getVMin()); - - if ( track && (track->getAxis() < perpandicular.getVMin()) ) track = track->getNext(); - for ( ; track && (track->getAxis() <= perpandicular.getVMax()) - ; track = track->getNext() ) - addAxis ( track->getAxis() ); - } - - track = plane->getTrackByPosition(_masterEvent->getSegment()->getAxis()); - if ( track ) { - size_t begin; - size_t end; - Interval interval = _masterEvent->getSegment()->getCanonicalInterval(); - track->getOverlapBounds ( interval, begin, end ); - - if ( begin != Track::NPOS ) { - for ( ; begin < end ; begin++ ) { - TrackElement* other = track->getSegment(begin); - if ( other->getNet() == _masterEvent->getSegment()->getNet() ) continue; - if ( !interval.intersect(other->getCanonicalInterval()) ) continue; - - addDislodger ( other ); - } - } - } - } - - - inline bool RipupHistory::isDislodger ( RoutingEvent* event ) const { return hasAxis(event->getSegment()->getAxis()); } - inline size_t RipupHistory::size () const { return _dislodgers.size(); } - inline size_t RipupHistory::getDislodgersCount () const { return _dislodgersCount; } - - - void RipupHistory::addAxis ( DbU::Unit axis ) - { - if ( hasAxis(axis) ) return; - _dislodgers.insert ( make_pair(axis,UnionIntervals()) ); - } - - - void RipupHistory::addAxis ( RoutingEvent* event ) - { - addAxis ( event->getAxisHistory() ); - } - - - bool RipupHistory::hasAxis ( DbU::Unit axis ) const - { - return _dislodgers.find(axis) != _dislodgers.end(); - } - - - UnionIntervals* RipupHistory::getUnionIntervals ( DbU::Unit axis ) - { - map::iterator iunion = _dislodgers.find ( axis ); - if ( iunion == _dislodgers.end() ) return NULL; - - return &(iunion->second); - } - - - void RipupHistory::addDislodger ( RoutingEvent* event ) - { - if ( event->getSegment() == _masterEvent->getSegment() ) return; - if ( event->getSegment()->getLayer() != _masterEvent->getSegment()->getLayer() ) return; - - UnionIntervals* intervals = getUnionIntervals ( event->getAxisHistory() ); - if ( !intervals ) return; - - Interval canonical = event->getSegment()->getCanonicalInterval(); - intervals->addInterval ( canonical ); - - _dislodgersCount++; - } - - - void RipupHistory::addDislodger ( TrackElement* segment ) - { - if ( _masterEvent->getSegment()->getNet() == segment->getNet() ) return; - - UnionIntervals* intervals = getUnionIntervals ( segment->getAxis() ); - if ( !intervals ) return; - - Interval canonical = segment->getCanonicalInterval(); - intervals->addInterval ( canonical ); - - _dislodgersCount++; - } - - - void RipupHistory::print ( ostream& o ) - { - o << "[HISTORY] " << _masterEvent << endl; - - map::iterator iunion = _dislodgers.begin(); - for ( ; iunion != _dislodgers.end() ; iunion++ ) - o << " @" << DbU::getValueString(iunion->first) - << " " << (iunion->second)._getString() << endl; - } - - -// ------------------------------------------------------------------- -// Class : "::SegmentAction". - - - class SegmentAction { - public: - enum Type { Self = (1<< 0) - , Other = (1<< 1) - , Ripup = (1<< 2) - , Insert = (1<< 3) - , ResetRipup = (1<< 4) - , AxisHint = (1<< 5) - , Perpandicular = (1<< 6) - , EventLevel1 = (1<< 7) - , EventLevel2 = (1<< 8) - , EventLevel3 = (1<< 9) - , EventLevel4 = (1<<10) - , EventLevel5 = (1<<11) - , PackingMode = (1<<12) - , ToState = (1<<13) - , ToRipupLimit = (1<<14) - , RipedByLocal = (1<<15) - , SelfInsert = Self |Insert - , SelfRipup = Self |Ripup - , SelfRipupPerpand = Self |Ripup | Perpandicular - , SelfRipupAndReset = Self |Ripup | Perpandicular - , SelfShrinkPerpand = Self |Ripup | Perpandicular|EventLevel4 - , SelfRipupAndAxisHint = Self |Ripup | Perpandicular|EventLevel4| AxisHint - , OtherRipup = Other|Ripup - , OtherPushAside = Other|Ripup | Perpandicular|EventLevel3 - , OtherPacking = Other|Ripup | Perpandicular|EventLevel4|PackingMode - }; - public: - SegmentAction ( TrackElement* - , unsigned int type - , DbU::Unit axisHint=0 - , unsigned int toState =0 - ); - inline TrackElement* getSegment () const; - inline unsigned int getType () const; - inline void setAxisHint ( DbU::Unit ); - inline unsigned int setFlag ( unsigned int ); - bool doAction ( RoutingEventQueue& ); - private: - TrackElement* _segment; - unsigned int _type; - DbU::Unit _axisHint; - unsigned int _toState; - }; - - - inline TrackElement* SegmentAction::getSegment () const { return _segment; } - inline unsigned int SegmentAction::getType () const { return _type; } - inline void SegmentAction::setAxisHint ( DbU::Unit axis ) { _axisHint = axis; } - inline unsigned int SegmentAction::setFlag ( unsigned int flag ) { _type |= flag; return _type; } - - - SegmentAction::SegmentAction ( TrackElement* segment - , unsigned int type - , DbU::Unit axisHint - , unsigned int toState - ) - : _segment (segment) - , _type (type) - , _axisHint(axisHint) - , _toState (toState) - { } - - - bool SegmentAction::doAction ( RoutingEventQueue& queue ) - { - // Note: - // "_immediate" ripup flags was associated with "perpandicular", as they - // must be re-inserted *before* any parallel. Must look to solve the redundancy. - - DebugSession::open ( _segment->getNet(), 200 ); - - if ( _type & Perpandicular ) { - ltrace(200) << "* Riping Pp " << _segment << endl; - } else { - ltrace(200) << "* Riping // " << _segment << endl; - } - - if ( _segment->isFixed() ) { DebugSession::close(); return true; } - - DataNegociate* data = _segment->getDataNegociate(); - if ( data == NULL ) { DebugSession::close(); return true; } - - if ( _type & ResetRipup ) data->resetRipupCount (); - - if ( _type & ToState ) { - data->setState ( _toState ); - data->setRipupCount ( Session::getKiteEngine()->getRipupLimit(_segment) ); - } - - if ( _segment->getTrack() ) Session::addRemoveEvent ( _segment ); - - RoutingEvent* event = data->getRoutingEvent(); - if ( event == NULL ) { - cerr << Bug("Missing Event on %p:%s" - ,_segment->base()->base(),getString(_segment).c_str()) << endl; - DebugSession::close(); - return true; - } - - if ( (_type & AxisHint) /*and not _segment->isSlackenDogLeg()*/ ) { - ltrace(200) << "Setting Axis Hint: @" << DbU::getValueString(_axisHint) << endl; - event->setAxisHint ( _axisHint ); - } - - if ( _type & ToRipupLimit ) { - unsigned int limit = Session::getKiteEngine()->getRipupLimit(_segment); - if ( limit > data->getRipupCount() ) - data->setRipupCount ( limit ); - } - - unsigned int eventLevel = 0; - if ( _type & EventLevel1 ) eventLevel = 1; - if ( _type & EventLevel2 ) eventLevel = 2; - if ( _type & EventLevel3 ) eventLevel = 3; - if ( _type & EventLevel4 ) eventLevel = 4; - if ( _type & EventLevel5 ) eventLevel = 5; - event->setRipedByLocal ( _type&RipedByLocal ); - - RoutingEvent* fork = event->reschedule ( queue, eventLevel ); - - if ( fork ) { - unsigned int mode = RoutingEvent::Repair; - if ( RoutingEvent::getStage() < RoutingEvent::Repair ) - mode = (_type&PackingMode) ? RoutingEvent::Pack : RoutingEvent::Negociate; - fork->setMode ( mode ); - } - - DebugSession::close (); - return true; - } - - -// ------------------------------------------------------------------- -// Class Declaration : "::State". - - - class State { - - public: - enum StateValues { MissingData = (1<<0) - , EmptyTrackList = (1<<1) - , Inserted = (1<<2) - , Self = (1<<3) - , Other = (1<<4) - , Ripup = (1<<5) - , MaximumRipup = (1<<6) - , TopologyModificated = (1<<7) - , SelfInserted = Self | Inserted - , SelfMaximumRipup = Self | MaximumRipup - , OtherRipup = Other | Ripup - , OtherTopologyModificated = Other | TopologyModificated - , SelfTopologyModificated = Self | TopologyModificated - }; - enum SlackenFlags { NoRecursive = (1<<0) - , NoTransition = (1<<1) - }; - - public: - State ( RoutingEvent* - , RoutingEventQueue& - , RoutingEventHistory& - ); - inline bool isFullBlocked () const; - inline RoutingEvent* getEvent (); - inline RoutingEventQueue& getQueue (); - inline RoutingEventHistory& getHistory (); - inline unsigned int getState (); - inline DataNegociate* getData (); - inline Interval& getConstraint (); - inline Interval& getOptimal (); - inline vector& getCosts (); - inline TrackCost& getCost ( size_t ); - inline Track* getTrack ( size_t ); - inline size_t getBegin ( size_t ); - inline size_t getEnd ( size_t ); - inline void setState ( unsigned int ); - inline void addAction ( TrackElement* - , unsigned int type - , DbU::Unit axisHint=0 - , unsigned int toState =0 - ); - inline vector& getActions (); - bool doActions (); - inline void clearActions (); - bool insertInTrack ( size_t ); - bool conflictSolve1_v1a (); - bool conflictSolve1_v1b (); - bool conflictSolve1_v2 (); - bool conflictSolve2 (); - bool desaturate (); - bool slackenTopology ( unsigned int flags=0 ); - bool solveFullBlockages (); - - private: - RoutingEvent* _event; - RoutingEventQueue& _queue; - RoutingEventHistory& _history; - unsigned int _state; - DataNegociate* _data; - Interval _constraint; - Interval _optimal; - vector _costs; - vector _actions; - bool _fullBlocked; - }; - - -// ------------------------------------------------------------------- -// Class Declaration : "::Manipulator". - - - class Manipulator { - public: - enum { ToRipupLimit = 0x001 - , AllowExpand = 0x002 - , NoExpand = 0x004 - , PerpandicularsFirst = 0x008 - , ToMoveUp = 0x010 - , AllowLocalMoveUp = 0x020 - , AllowTerminalMoveUp = 0x040 - , AllowShortPivotUp = 0x080 - , NoDoglegReuse = 0x100 - }; - enum { LeftAxisHint=1, RightAxisHint=2 }; - enum { HasNextRipup=0x2 }; - public: - Manipulator ( TrackElement*, State& ); - ~Manipulator (); - inline TrackElement* getSegment () const; - inline DataNegociate* getData () const; - inline RoutingEvent* getEvent () const; - bool canRipup ( unsigned int flags=0 ) const; - bool isCaged ( DbU::Unit ) const; - bool ripup ( Interval overlap - , unsigned int type - , DbU::Unit axisHint=0 - , unsigned int toState =0 - ); - bool ripup ( DbU::Unit point - , unsigned int type - , DbU::Unit axisHint=0 - ); - bool ripupPerpandiculars ( unsigned int flags=0 ); - void repackPerpandiculars ( bool ripInserted=true ); - bool ripple (); - bool goOutsideGCell (); - bool minimize (); - bool desalignate (); - bool slacken (); - bool pivotUp (); - bool pivotDown (); - bool moveUp ( unsigned int flags=0 ); - bool makeDogLeg (); - bool makeDogLeg ( DbU::Unit ); - bool makeDogLeg ( Interval ); - bool relax ( Interval, unsigned int flags=AllowExpand ); - bool relax ( size_t ); - bool insertInTrack ( size_t ); - bool shrinkToTrack ( size_t - , unsigned int flags=0 - , DbU::Unit leftAxisHint=0 - , DbU::Unit rightAxisHint=0 - ); - bool forceToTrack ( size_t ); - bool forceOverLocals (); - void reprocessPerpandiculars (); - private: - TrackElement* _segment; - DataNegociate* _data; - RoutingEvent* _event; - State& _S; - }; - - -// ------------------------------------------------------------------- -// Class Definition : "::State". - - - State::State ( RoutingEvent* event, RoutingEventQueue& queue, RoutingEventHistory& history ) - : _event (event) - , _queue (queue) - , _history (history) - , _state (0) - , _data (NULL) - , _constraint () - , _optimal () - , _costs () - , _actions () - , _fullBlocked (true) - { - TrackElement* segment = _event->getSegment(); - unsigned int depth = Session::getRoutingGauge()->getLayerDepth(segment->getLayer()); - _event->setTracksFree ( 0 ); - - _data = segment->getDataNegociate(); - if ( !_data ) { - _state = MissingData; - return; - } - - _data->update (); - _event->invalidate ( true ); // Optimizable. - _event->revalidate ( true ); - - _constraint = _event->getConstraints(); - _optimal = _event->getOptimal(); - - const Interval& perpandicular = _event->getPerpandicular (); - - ltrace(148) << "Katabatic intervals:" << endl; - ltrace(148) << "* Optimal: " << _optimal << endl; - ltrace(148) << "* Constraints: " << _constraint << endl; - ltrace(148) << "* Perpandicular: " << perpandicular << endl; - ltrace(148) << "* OptimalAxis: " << _event->getOptimalAxis() << endl; - ltrace(148) << "* AxisHint: " << DbU::getValueString(_event->getAxisHint()) << endl; - - if ( _event->getTracksNb() ) { - if ( _constraint.getIntersection(perpandicular).isEmpty() ) { - ltrace(200) << "Perpandicular free is too tight." << endl; - _state = EmptyTrackList; - } else - _constraint.intersection ( perpandicular ); - } else { - ltrace(200) << "No Track in perpandicular free." << endl; - _state = EmptyTrackList; - } - - if ( _state == EmptyTrackList ) return; - - ltrace(148) << "Negociate intervals:" << endl; - ltrace(148) << "* Optimal: " << _optimal << endl; - ltrace(148) << "* Constraints: " << _constraint << endl; - ltracein(148); - - // if ( segment->isLocal() and (_data->getState() >= DataNegociate::MaximumSlack) ) - // _constraint.inflate ( 0, DbU::lambda(1.0) ); - - bool inLocalDepth = (depth < 3); - bool isOneLocalTrack = (segment->isLocal()) - and (segment->base()->getAutoSource()->getGCell()->getGlobalsCount(depth) >= 9.0); - - RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(segment->getLayer()); - forEach ( Track*, itrack, Tracks_Range::get(plane,_constraint)) { - unsigned int costflags = 0; - costflags |= (segment->isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0; - - _costs.push_back ( itrack->getOverlapCost(segment,costflags) ); - _costs.back().setAxisWeight ( _event->getAxisWeight(itrack->getAxis()) ); - _costs.back().incDeltaPerpand ( _data->getCost().getWiringDelta(itrack->getAxis()) ); - - if ( inLocalDepth and (_costs.back().getDataState() == DataNegociate::MaximumSlack) ) - _costs.back().setInfinite (); - - if ( isOneLocalTrack - and _costs.back().isOverlapGlobal() - and (_costs.back().getDataState() >= DataNegociate::ConflictSolve1) ) - _costs.back().setInfinite (); - - _costs.back().consolidate (); - if ( _fullBlocked and (not _costs.back().isBlockage() and not _costs.back().isFixed()) ) - _fullBlocked = false; - - ltrace(149) << "| " << (*itrack) << " - " << _costs.back() << endl; - } - ltraceout(148); - - if ( _costs.empty() ) { - Track* nearest = plane->getTrackByPosition(_constraint.getCenter()); - - if ( (nearest->getAxis() < _constraint.getVMin()) - or (nearest->getAxis() > _constraint.getVMax()) ) { - //setUnimplemented (); - //cerr << "[UNIMPLEMENTED] " << segment << " no Track in constraint interval " - // << _constraint << " " << "." << endl; - } else { - cerr << Bug(" %s Track_Range() failed to find Tracks in %s (they exists)." - ,getString(segment).c_str() - ,getString(_constraint).c_str() - ) << endl; - } - _state = EmptyTrackList; - } - - unsigned int flags = 0; - flags |= (segment->isStrap()) ? TrackCost::IgnoreAxisWeight : 0; - flags |= (segment->isLocal() - and (_data->getState() < DataNegociate::Minimize) - and (_data->getRipupCount() < 5)) - ? TrackCost::DiscardGlobals : 0; - flags |= (RoutingEvent::getStage() == RoutingEvent::Repair) ? TrackCost::IgnoreSharedLength : 0; - - if ( flags & TrackCost::DiscardGlobals ) { - ltrace(200) << "TrackCost::Compare() - DiscardGlobals" << endl; - } - - sort ( _costs.begin(), _costs.end(), TrackCost::Compare(flags) ); - - size_t i=0; - for ( ; (i<_costs.size()) and _costs[i].isFree() ; i++ ); - _event->setTracksFree ( i ); - } - - - inline bool State::isFullBlocked () const { return _fullBlocked and _costs.size(); } - inline RoutingEvent* State::getEvent () { return _event; } - inline RoutingEventQueue& State::getQueue () { return _queue; } - inline RoutingEventHistory& State::getHistory () { return _history; } - inline unsigned int State::getState () { return _state; } - inline DataNegociate* State::getData () { return _data; } - inline Interval& State::getConstraint () { return _constraint; } - inline Interval& State::getOptimal () { return _optimal; } - inline vector& State::getCosts () { return _costs; } - inline TrackCost& State::getCost ( size_t i ) { return _costs[i]; } - inline Track* State::getTrack ( size_t i ) { return _costs[i].getTrack(); } - inline size_t State::getBegin ( size_t i ) { return _costs[i].getBegin(); } - inline size_t State::getEnd ( size_t i ) { return _costs[i].getEnd(); } - inline vector& State::getActions () { return _actions; } - inline void State::setState ( unsigned int state ) { _state = state; } - inline void State::clearActions () { _actions.clear(); } - - - void State::addAction ( TrackElement* segment - , unsigned int type - , DbU::Unit axisHint - , unsigned int toState ) - { - if ( not segment->isFixed() ) { - _actions.push_back ( SegmentAction(segment,type,axisHint,toState) ); - ltrace(200) << "State::addAction(): " << segment << endl; - } - } - - - bool State::doActions () - { - ltrace(200) << "State::doActions() - " << _actions.size() << endl; - - bool ripupOthersParallel = false; - bool ripedByLocal = getEvent()->getSegment()->isLocal(); - - for ( size_t i=0 ; i<_actions.size() ; i++ ) { - if ( ripedByLocal ) _actions[i].setFlag ( SegmentAction::RipedByLocal ); - if ( _actions[i].getType() & SegmentAction::OtherRipup ) { - ripupOthersParallel = true; - } - } - - for ( size_t i=0 ; i<_actions.size() ; i++ ) { - if ( (_actions[i].getType() & SegmentAction::SelfInsert) and ripupOthersParallel ) - _actions[i].setFlag ( SegmentAction::EventLevel3 ); - - DebugSession::open ( _actions[i].getSegment()->getNet(), 200 ); - if ( not _actions[i].doAction(_queue) ) { - cinfo << "[INFO] Failed action on " << _actions[i].getSegment() << endl; - } - DebugSession::close (); - } - - _actions.clear (); - return true; - } - - - bool State::insertInTrack ( size_t i ) - { - ltrace(200) << "State::insertInTrack() istate:" << _event->getInsertState() - << " track:" << i << endl; - - _event->incInsertState(); - switch ( _event->getInsertState() ) { - case 1: - if ( Manipulator(_event->getSegment(),*this).insertInTrack(i) ) return true; - _event->incInsertState(); - case 2: - if ( Manipulator(_event->getSegment(),*this).shrinkToTrack(i) ) return true; - _event->incInsertState(); - case 3: - if ( Manipulator(_event->getSegment(),*this).forceToTrack(i) ) return true; - _event->incInsertState(); - } - return false; - } - - - bool State::conflictSolve2 () - { - bool success = false; - RipupHistory ripupHistory ( _event ); - RoutingEvent* event; - TrackElement* segment = _event->getSegment(); - - ltrace(200) << "State::conflictSolve2()" << endl; - - size_t maxDepth = min ( getHistory().size(), (size_t)300 ); - size_t depth = 0; - while ( (ripupHistory.getDislodgersCount() < 3) and (depth < maxDepth) ) { - event = getHistory().getRNth(depth++); - if ( !event ) continue; - if ( (event->getSegment() != segment) and ripupHistory.isDislodger(event) ) - ripupHistory.addDislodger ( event ); - } - - //ripupHistory.print ( cout ); - - UnionIntervals* intervals = ripupHistory.getUnionIntervals ( segment->getAxis() ); - if ( intervals && !intervals->empty() ) { - - DbU::Unit minConflict = intervals->getVMin(); - DbU::Unit maxConflict = intervals->getVMax(); - Interval canonical = segment->getCanonicalInterval(); - bool sourceDogLeg = canonical.contains(minConflict); - bool targetDogLeg = canonical.contains(maxConflict); - - if ( sourceDogLeg || targetDogLeg ) { - Point breakPoint; - if ( segment->isHorizontal() ) - breakPoint = Point ( (sourceDogLeg)?minConflict:maxConflict ,segment->getAxis() ); - else - breakPoint = Point ( segment->getAxis(), (sourceDogLeg)?minConflict:maxConflict ); - - Katabatic::GCell* dogLegGCell = Session::getGCellUnder ( breakPoint.getX(), breakPoint.getY() ); - if ( dogLegGCell ) { - if ( segment->canDogLegAt(dogLegGCell) ) { - if ( segment->makeDogLeg(dogLegGCell) ) - success = true; - } - } else { - cerr << Bug("No GCell under %s.",getString(breakPoint).c_str()) << endl; - } - - if ( !success ) { - if ( segment->isHorizontal() ) - breakPoint = Point ( (targetDogLeg)?maxConflict:minConflict ,segment->getAxis() ); - else - breakPoint = Point ( segment->getAxis(), (targetDogLeg)?maxConflict:minConflict ); - - Katabatic::GCell* dogLegGCell = Session::getGCellUnder ( breakPoint.getX(), breakPoint.getY() ); - if ( dogLegGCell ) { - if ( segment->canDogLegAt(dogLegGCell) ) { - if ( segment->makeDogLeg(dogLegGCell) ) - success = true; - } - } else { - cerr << Bug("No GCell under %s.",getString(breakPoint).c_str()) << endl; - } - } - } - } else { - ltrace(200) << "No disloggers found @" << DbU::getValueString(segment->getAxis()) << endl; - - Interval freeSpan = Session::getKiteEngine()-> - getTrackByPosition(segment->getLayer(),segment->getAxis())-> - getFreeInterval(segment->getSourceU(),segment->getNet()); - - if ( freeSpan.contains(segment->getCanonicalInterval()) ) { - ltrace(200) << "Disloggers vanished, Segment can be re-inserted." << endl; - success = true; - } - } - - return success; - } - - - bool State::conflictSolve1_v2 () - { - ltrace(200) << "State::conflictSolve1_v2()" << endl; - ltracein(200); - - Interval constraints; - vector candidates; - TrackElement* segment = _event->getSegment(); - - segment->base()->getConstraints ( constraints ); - Interval overlap = segment->getCanonicalInterval(); - RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(segment->getLayer()); - Track* track = plane->getTrackByPosition(constraints.getVMin(),Constant::Superior); - - for ( ; track->getAxis() <= constraints.getVMax() ; track = track->getNext() ) { - candidates.push_back ( track ); - } - - FindPath findPath ( candidates, segment->getNet(), overlap.getVMin(), overlap.getVMax() ); - vector doglegs = findPath.computeDoglegPos( 0 ); - - if ( doglegs.empty() ) { - ltrace(200) << "Cannot find a path." << endl; - - DbU::Unit gap = DbU::lambda(50.0); - FindPath findPath ( candidates, segment->getNet(), overlap.getVMin(), overlap.getVMax() ); - doglegs = findPath.computeDoglegPos(gap); - - if ( doglegs.empty() ) { - ltrace(200) << "Cannot find a path with gap " << DbU::getValueString(gap) << "." << endl; - return false; - } - return false; - } - - - ltrace(200) << "Dogleg positions:" << endl; - for ( size_t ipos=0 ; ipos gcells; - vector doglegGCells; - segment->getGCells ( gcells ); - - Interval uside; - size_t idogleg = 0; - for ( size_t igcell=0 ; igcellgetUSide(segment->getDirection()); - ltrace(200) << "| " << gcells[igcell] << " uside: " << uside << endl; - - if ( uside.contains(doglegs[idogleg]) ) { - ltrace(200) << "> Dogleg: " << idogleg << endl; - doglegGCells.push_back ( gcells[igcell] ); - - idogleg++; - } - } - - for ( size_t igcell=0 ; igcellcanDogLegAt(doglegGCells[igcell]) ) { - ltrace(200) << "Cannot create dogleg " << igcell << "." << endl; - ltraceout(200); - return false; - } - } - - TrackElement* remainder = segment; - remainder->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true ); - - for ( size_t igcell=0 ; igcellmakeDogLeg ( doglegGCells[igcell] ); - dogleg->setAxis ( doglegs[igcell] ); - - remainder = Session::lookup ( Session::getDogLegs()[2] ); - remainder->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true ); - } - - ltraceout(200); - return true; - } - - - bool State::conflictSolve1_v1a () - { - bool success = false; - Interval constraints; - vector candidates; - TrackElement* segment = _event->getSegment(); - bool canMoveUp = (segment->isLocal()) ? segment->canPivotUp(0.5) : segment->canMoveUp(1.0); // MARK 1 - unsigned int relaxFlags = Manipulator::NoDoglegReuse - | ((_data and (_data->getStateCount() < 2)) ? Manipulator::AllowExpand - : Manipulator::NoExpand); - - ltrace(200) << "State::conflictSolve1_v1a()" << endl; - ltrace(200) << "| Candidates Tracks: " << endl; - - segment->base()->getConstraints ( constraints ); - Interval overlap = segment->getCanonicalInterval(); - RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(segment->getLayer()); - Track* track = plane->getTrackByPosition(constraints.getVMin(),Constant::Superior); - - for ( ; track->getAxis() <= constraints.getVMax() ; track = track->getNext() ) { - candidates.push_back ( Cs1Candidate(track) ); - - size_t begin; - size_t end; - TrackElement* other; - Net* otherNet = NULL; - Interval otherOverlap; - - track->getOverlapBounds ( overlap, begin, end ); - candidates.back().setBegin ( begin ); - candidates.back().setEnd ( end ); - - ltrace(200) << "* " << track << " [" << begin << ":" << end << "]" << endl; - - for ( ; (begin < end) ; begin++ ) { - other = track->getSegment(begin); - - if ( other->getNet() == segment->getNet() ) { - ltrace(200) << " | " << begin << " Same net: " << " " << other << endl; - continue; - } - if ( not other->getCanonicalInterval().intersect(overlap) ) { - ltrace(200) << " | " << begin << " No Conflict: " << " " << other << endl; - if ( otherNet == NULL ) candidates.back().setBegin ( begin+1 ); - continue; - } - ltrace(200) << " | " << begin << " Conflict: " << " " << other << endl; - - if ( otherNet != other->getNet() ) { - if ( otherNet != NULL ) { - candidates.back().addConflict ( otherOverlap ); - ltrace(200) << " | Other overlap: " << otherOverlap << endl; - } - otherNet = other->getNet(); - otherOverlap = other->getCanonicalInterval(); - } else { - otherOverlap.merge(other->getCanonicalInterval()); - } - } - if ( not otherOverlap.isEmpty() ) { - candidates.back().addConflict ( otherOverlap ); - ltrace(200) << " | Other overlap: " << otherOverlap << endl; - } - - candidates.back().consolidate(); - } - - sort ( candidates.begin(), candidates.end() ); - - for ( size_t icandidate=0 ; icandidate 2 ) break; - - Interval overlap0 = candidates[icandidate].getConflict(0); - ltrace(200) << "overlap0: " << overlap0 << endl; - - if ( candidates[icandidate].getLength() == 1 ) { - Track* track = candidates[icandidate].getTrack(); - TrackElement* other = track->getSegment(candidates[icandidate].getBegin()); - - // if ( other->isGlobal() and other->canMoveUp(1.0) ) { - // ltrace(200) << "conflictSolve1_v1a() - One conflict, other move up [" - // << candidates[icandidate].getBegin() << "]" << endl; - // if ( (success = other->moveUp()) ) break; - // } - if ( other->isGlobal() ) { - ltrace(200) << "conflictSolve1_v1a() - One conflict, other move up [" - << candidates[icandidate].getBegin() << "]" << endl; - if ( (success = Manipulator(other,*this).moveUp()) ) break; - } - - ltrace(200) << "conflictSolve1_v1a() - One conflict, relaxing self" << endl; - - if ( Manipulator(segment,*this).relax(overlap0,relaxFlags) ) { - success = true; - break; - } else { - if ( not canMoveUp - and (relaxFlags != Manipulator::NoExpand) - and Manipulator(segment,*this).relax(overlap0,Manipulator::NoExpand|Manipulator::NoDoglegReuse) ) { - ltrace(200) << "Cannot move up but successful narrow breaking." << endl; - success = true; - break; - } - } - } - - if ( candidates[icandidate].getLength() == 2 ) { - ltrace(200) << "conflictSolve1_v1a() - Two conflict, relaxing self" << endl; - - Interval overlap1 = candidates[icandidate].getConflict(1); - // Ugly: hard-coded half GCell side. - if ( overlap1.getVMin() - overlap0.getVMax() < DbU::lambda(5.0) ) { - ltrace(200) << "conflictSolve1_v1a() - Too narrow spacing: " - << DbU::getValueString(overlap1.getVMin() - overlap0.getVMax()) << endl; - continue; - } - - if ( Manipulator(segment,*this).relax(overlap0,relaxFlags) ) { - success = true; - break; - } else { - if ( not canMoveUp - and (relaxFlags != Manipulator::NoExpand) - and Manipulator(segment,*this).relax(overlap0,Manipulator::NoExpand) ) { - ltrace(200) << "Cannot move up but successful narrow breaking." << endl; - success = true; - break; - } - } - } - } - - //if ( track && (track->getAxis() < constraints.getVMin()) ) track = track->getNext(); - //for ( ; !success && track && (track->getAxis() <= constraints.getVMax()) ; track = track->getNext() ) - - unsigned int depth = Session::getConfiguration()->getRoutingGauge()->getLayerDepth(segment->getLayer()); - if ( not success ) { - ltrace(200) << "Try to break " - << DbU::getValueString(segment->getLength()) - << " >= " << DbU::getValueString(Session::getConfiguration()->getGlobalMinBreak(depth)) - << endl; - if ( (segment->getLength() >= Session::getConfiguration()->getGlobalMinBreak(depth)) ) { - ltrace(200) << "Long global wire, break in the middle." << endl; - Interval span; - segment->getCanonical ( span ); - - success = Manipulator(segment,*this).makeDogLeg ( span.getCenter() ); - if ( success ) { - TrackElement* segment1 = Session::lookup ( Session::getDogLegs()[2] ); - if ( segment1 ) Manipulator(segment1,*this).pivotDown (); - Manipulator(segment,*this).pivotDown (); - } - } - } - - return success; - } - - - bool State::conflictSolve1_v1b () - { - bool success = false; - Interval constraints; - vector candidates; - TrackElement* segment = _event->getSegment(); - bool canMoveUp = (segment->isLocal()) ? segment->canPivotUp(0.5) : segment->canMoveUp(1.0); // MARK 1 - unsigned int relaxFlags = Manipulator::NoDoglegReuse - | ((_data and (_data->getStateCount() < 2)) ? Manipulator::AllowExpand - : Manipulator::NoExpand); - - ltrace(200) << "State::conflictSolve1_v1b()" << endl; - ltrace(200) << "| Candidates Tracks: " << endl; - - segment->base()->getConstraints ( constraints ); - Interval overlap = segment->getCanonicalInterval(); - RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(segment->getLayer()); - Track* track = plane->getTrackByPosition(constraints.getVMin(),Constant::Superior); - - for ( ; track->getAxis() <= constraints.getVMax() ; track = track->getNext() ) { - candidates.push_back ( Cs1Candidate(track) ); - - size_t begin; - size_t end; - TrackElement* other; - Net* otherNet = NULL; - Interval otherOverlap; - bool otherIsGlobal = false; - - track->getOverlapBounds ( overlap, begin, end ); - candidates.back().setBegin ( begin ); - candidates.back().setEnd ( end ); - - ltrace(200) << "* " << track << " [" << begin << ":" << end << "]" << endl; - - for ( ; (begin < end) ; begin++ ) { - other = track->getSegment(begin); - - if ( other->getNet() == segment->getNet() ) { - ltrace(200) << " | " << begin << " Same net: " << " " << other << endl; - continue; - } - if ( not other->getCanonicalInterval().intersect(overlap) ) { - ltrace(200) << " | " << begin << " No Conflict: " << " " << other << endl; - if ( otherNet == NULL ) candidates.back().setBegin ( begin+1 ); - continue; - } - ltrace(200) << " | " << begin << " Conflict: " << " " << other << endl; - - if ( otherNet != other->getNet() ) { - if ( otherNet ) { - if ( otherIsGlobal ) { - candidates.back().addConflict ( otherOverlap ); - ltrace(200) << " | Other overlap G: " << otherOverlap << endl; - } else { - ltrace(200) << " | Other overlap L: " << otherOverlap << " ignored." << endl; - } - } - otherNet = other->getNet(); - otherOverlap = other->getCanonicalInterval(); - otherIsGlobal = other->isGlobal() or other->isBlockage(); - } else { - otherOverlap.merge(other->getCanonicalInterval()); - otherIsGlobal = otherIsGlobal or other->isGlobal() or other->isBlockage(); - } - } - if ( not otherOverlap.isEmpty() ) { - if ( otherIsGlobal ) { - candidates.back().addConflict ( otherOverlap ); - ltrace(200) << " | Other overlap G: " << otherOverlap << endl; - } else { - ltrace(200) << " | Other overlap L: " << otherOverlap << " ignored." << endl; - } - } - - candidates.back().consolidate(); - } - - sort ( candidates.begin(), candidates.end() ); - - for ( size_t icandidate=0 ; icandidategetSegment(overlap.getCenter()); - if ( not other ) { - cbug << Error("conflictSolve1_v1b(): No segment under overlap center.") << endl; - continue; - } - - if ( other->isGlobal() ) { - ltrace(200) << "conflictSolve1_v1b() - Conflict with global, other move up" << endl; - if ( (success = Manipulator(other,*this).moveUp()) ) break; - } - - ltrace(200) << "conflictSolve1_v1b() - Relaxing self" << endl; - - if ( Manipulator(segment,*this).relax(overlap0,relaxFlags) ) { - success = true; - break; - } else { - if ( not canMoveUp - and (relaxFlags != Manipulator::NoExpand) - and Manipulator(segment,*this).relax(overlap0,Manipulator::NoExpand|Manipulator::NoDoglegReuse) ) { - ltrace(200) << "Cannot move up but successful narrow breaking." << endl; - success = true; - break; - } - } - } - - if ( not success and segment->isGlobal() and (_costs.size() <= 1) ) { - ltrace(200) << "Overconstrained perpandiculars, rip them up. On track:" << endl; - ltrace(200) << " " << track << endl; - Manipulator(segment,*this).ripupPerpandiculars (); - success = true; - } - - return success; - } - - - bool State::solveFullBlockages () - { - bool success = false; - TrackElement* segment = getEvent()->getSegment(); - - ltrace(200) << "State::solveFullBlockages: " << " " << segment << endl; - ltracein(200); - - if ( segment->isLocal() ) { - success = Manipulator(segment,*this).pivotUp(); - if ( not success ) { - ltrace(200) << "Tightly constrained local segment overlapping a blockage, move up." << endl; - ltrace(200) << segment << endl; - success = Manipulator(segment,*this).moveUp - (Manipulator::AllowLocalMoveUp|Manipulator::AllowTerminalMoveUp); - } - } else { - Interval overlap = segment->getCanonicalInterval(); - size_t begin; - size_t end; - - getCost(0).getTrack()->getOverlapBounds ( overlap, begin, end ); - for ( ; begingetSegment(begin); - Interval otherOverlap = other->getCanonicalInterval(); - - if ( other->getNet() == segment->getNet() ) continue; - if ( not otherOverlap.intersect(overlap) ) continue; - - ltrace(200) << "| " << begin << " Blockage conflict: " << " " << other << endl; - if ( (success = Manipulator(segment,*this).relax - (otherOverlap,Manipulator::NoDoglegReuse|Manipulator::NoExpand)) ) { - break; - } - } - } - if ( not success ) { - cerr << "[ERROR] Tighly constrained segment overlapping a blockage." << endl; - ltrace(200) << "Segment is hard blocked, bypass to Unimplemented." << endl; - } - - ltraceout(200); - return success; - } - - - bool State::desaturate () - { - ltrace(200) << "State::desaturate()" << endl; - ltracein(200); - - TrackElement* segment = _event->getSegment(); - size_t itrack = 0; - - for ( ; itrackgetNet(); - Interval toFree (segment->getCanonicalInterval()); - bool success = true; - - for ( size_t i = begin ; success and (i < end) ; i++ ) { - TrackElement* segment2 = track->getSegment(i); - - ltrace(200) << "* Looking // " << segment2 << endl; - - if ( segment2->getNet() == ownerNet ) continue; - if ( not toFree.intersect(segment2->getCanonicalInterval()) ) continue; - if ( segment2->isFixed() or not segment2->isBipoint() ) { - success = false; - continue; - } - - DataNegociate* data2 = segment2->getDataNegociate(); - if ( not data2 ) { - ltrace(200) << "No DataNegociate, ignoring." << endl; - success = false; - continue; - } - - ltrace(200) << "- Forced moveUp " << segment2 << endl; - if ( not (success=Manipulator(segment2,*this).moveUp(Manipulator::AllowTerminalMoveUp)) ) { - continue; - } - } - - if ( success ) { - setState ( State::OtherRipup ); - addAction ( segment, SegmentAction::SelfInsert ); - segment->setAxis ( getCost(itrack).getTrack()->getAxis() ); - break; - } - } - } - - ltraceout(200); - return (itrack < _costs.size()); - -#if DESATURATE_V1 - TrackElement* segment = _event->getSegment(); - unsigned int depth = Session::getRoutingGauge()->getLayerDepth(segment->getLayer()); - - ltrace(200) << "State::desaturate()" << segment << endl; - ltracein(200); - - // if ( segment->getLength() > DbU::lambda(75.0) ) { - // ltraceout(200); - // return false; - // } - - vector gcells; - segment->getGCells ( gcells ); - - AutoSegment::DepthLengthSet globals; - for ( size_t i=0 ; i* gcellGlobals = (segment->isHorizontal()) - ? gcells[i]->getHSegments() : gcells[i]->getVSegments(); - for ( size_t i=0 ; i<(*gcellGlobals).size() ; ++i ) { - size_t gdepth = Session::getRoutingGauge()->getLayerDepth((*gcellGlobals)[i]->getLayer()); - if ( gdepth != depth ) continue; - if ( (*gcellGlobals)[i] == segment->base() ) continue; - - globals.insert ( (*gcellGlobals)[i] ); - } - } - - AutoSegment::DepthLengthSet::iterator iglobal = globals.begin(); - for ( ; iglobal != globals.end() ; ++iglobal ) { - TrackElement* gsegment = Session::lookup ( *iglobal ); - ltrace(200) << "| " << gsegment << endl; - - if ( Manipulator(gsegment,*this).moveUp() ) { - ltraceout(200); - return true; - } - } - - ltraceout(200); - return false; -#endif // DESTURATE_V1 - } - - bool State::slackenTopology ( unsigned int flags ) - { - TrackElement* segment = getEvent()->getSegment(); - bool success = false; - bool blocked = false; - bool repush = true; - DataNegociate* data = segment->getDataNegociate (); - unsigned int nextState = data->getState(); - unsigned int actionFlags = SegmentAction::SelfInsert|SegmentAction::EventLevel5; - - DebugSession::open ( segment->getNet(), 200 ); - ltrace(200) << "Slacken Topology for " << segment->getNet() - << " " << segment << endl; - ltracein(200); - - if ( (not segment) or (not data) ) { ltraceout(200); DebugSession::close(); return false; } - - _event->resetInsertState(); - data->resetRipupCount (); - - // Normal cases. - if ( not blocked and not success ) { - if ( segment->isStrap() ) { - ltrace(200) << "Strap segment FSM." << endl; - switch ( data->getState() ) { - case DataNegociate::RipupPerpandiculars: - nextState = DataNegociate::Desalignate; - success = Manipulator(segment,*this).ripupPerpandiculars(); - if ( success ) break; - case DataNegociate::Desalignate: - case DataNegociate::Minimize: - if ( data->getStateCount() >= 2 ) { - nextState = DataNegociate::MaximumSlack; - } - success = Manipulator(segment,*this).minimize(); - if ( success ) break; - case DataNegociate::DogLeg: - case DataNegociate::Slacken: - case DataNegociate::ConflictSolve1: - case DataNegociate::ConflictSolve2: - case DataNegociate::MoveUp: - case DataNegociate::MaximumSlack: - case DataNegociate::Unimplemented: - nextState = DataNegociate::Unimplemented; - break; - } - - if ( not success and (nextState != DataNegociate::Unimplemented) ) { - success = Manipulator(segment,*this).ripupPerpandiculars(Manipulator::ToRipupLimit); - } - } else if ( segment->isLocal() ) { - // Local TrackElement State Machine. - ltrace(200) << "Local segment FSM." << endl; - switch ( data->getState() ) { - case DataNegociate::RipupPerpandiculars: - nextState = DataNegociate::Desalignate; - success = Manipulator(segment,*this).ripupPerpandiculars(); - if ( success ) break; - case DataNegociate::Desalignate: - nextState = DataNegociate::Minimize; - success = Manipulator(segment,*this).desalignate(); - break; - case DataNegociate::Minimize: - if ( isFullBlocked() and not segment->isTerminal() ) { - ltrace(200) << "Is Fully blocked." << endl; - nextState = DataNegociate::Unimplemented; - break; - } - nextState = DataNegociate::DogLeg; - success = Manipulator(segment,*this).minimize(); - if ( success ) break; - case DataNegociate::DogLeg: - nextState = DataNegociate::Slacken; - success = Manipulator(segment,*this).makeDogLeg(); - if ( success ) break; - case DataNegociate::Slacken: - nextState = DataNegociate::ConflictSolve2; - success = Manipulator(segment,*this).slacken(); - if ( success ) break; - case DataNegociate::ConflictSolve1: - case DataNegociate::ConflictSolve2: - if ( not (flags & NoRecursive) ) { - nextState = DataNegociate::MoveUp; - success = conflictSolve2 (); - break; - } - case DataNegociate::MoveUp: - //if ( (success = desaturate()) ) break; - nextState = DataNegociate::MaximumSlack; - success = Manipulator(segment,*this).moveUp(); - if ( success ) break; - case DataNegociate::MaximumSlack: - if ( segment->isSlackenStrap() ) { - if ( (nextState < DataNegociate::MaximumSlack) or (data->getStateCount() < 2) ) { - nextState = DataNegociate::MaximumSlack; - success = conflictSolve1_v1b (); - if ( success ) break; - } - } - case DataNegociate::Unimplemented: - nextState = DataNegociate::Unimplemented; - break; - } - - if ( not success and (nextState != DataNegociate::Unimplemented) ) { - if ( data->getStateCount() < 6 ) - success = Manipulator(segment,*this).ripupPerpandiculars(Manipulator::ToRipupLimit); - } - - if ( not success - and (nextState == DataNegociate::Unimplemented) - and segment->isSlackened() - and isFullBlocked() ) { - if ( solveFullBlockages () ) nextState = DataNegociate::MoveUp; - } - } else { - // Global TrackElement State Machine. - switch ( data->getState() ) { - ltrace(200) << "Global segment FSM." << endl; - case DataNegociate::RipupPerpandiculars: - ltrace(200) << "Global, State: RipupPerpandiculars." << endl; - // if ( isFullBlocked() ) { - // actionFlags &= ~SegmentAction::EventLevel5; - // success = Manipulator(segment,*this).ripupPerpandiculars(Manipulator::PerpandicularsFirst); - // if ( success ) break; - // } - nextState = DataNegociate::Desalignate; - break; - case DataNegociate::Minimize: - case DataNegociate::DogLeg: - case DataNegociate::Desalignate: - ltrace(200) << "Global, State: Minimize, DogLeg or Desalignate." << endl; - if ( (success = Manipulator(segment,*this).desalignate()) ) { - break; - } - nextState = DataNegociate::Slacken; - case DataNegociate::Slacken: - ltrace(200) << "Global, State: Slacken." << endl; - if ( (success = Manipulator(segment,*this).slacken()) ) { - break; - } - nextState = DataNegociate::MoveUp; - case DataNegociate::MoveUp: - ltrace(200) << "Global, State: MoveUp." << endl; - //if ( (success = desaturate()) ) break; - if ( (success = Manipulator(segment,*this).moveUp(Manipulator::AllowShortPivotUp)) ) { - break; - } - nextState = DataNegociate::ConflictSolve1; - break; - case DataNegociate::ConflictSolve1: - case DataNegociate::ConflictSolve2: - ltrace(200) << "Global, State: ConflictSolve1 or ConflictSolve2." << endl; - if ( not (flags & NoRecursive) ) { - if ( (success = conflictSolve1_v1b()) ) { - if ( segment->canMoveUp(1.0) ) // MARK 1 - nextState = DataNegociate::MoveUp; - else { - if ( data->getStateCount() > 3 ) - nextState = DataNegociate::MaximumSlack; - } - if ( segment->getDataNegociate()->getState() < DataNegociate::ConflictSolve1 ) - nextState = segment->getDataNegociate()->getState(); - break; - } - } - case DataNegociate::MaximumSlack: - if ( (success=Manipulator(segment,*this).forceOverLocals()) ) { - break; - } - case DataNegociate::Unimplemented: - ltrace(200) << "Global, State: MaximumSlack or Unimplemented." << endl; - nextState = DataNegociate::Unimplemented; - break; - } - - if ( not success and (nextState != DataNegociate::Unimplemented) ) { - if ( data->getStateCount() < 6 ) - success = Manipulator(segment,*this).ripupPerpandiculars(Manipulator::ToRipupLimit); - } - - // Special case: all tracks are overlaping a blockage. - if ( not success - and (nextState == DataNegociate::Unimplemented) - and segment->isSlackened() ) { - if ( solveFullBlockages() ) nextState = DataNegociate::MoveUp; - } - } - } - - if ( not (flags&NoTransition) ) { - ltrace(200) << "Incrementing state (before): " << nextState << " count:" << data->getStateCount() << endl; - data->setState ( nextState ); - ltrace(200) << "Incrementing state (after): " << nextState << " count:" << data->getStateCount() << endl; - } - - if ( success ) { - if ( repush ) { - actionFlags |= SegmentAction::ResetRipup; - addAction ( segment, actionFlags ); - } - } else { - clearActions (); - if ( data->getState() == DataNegociate::Unimplemented ) { - cinfo << "[UNSOLVED] " << segment << " unable to slacken topology." << endl; - } - } - - ltraceout(200); - DebugSession::close (); - - return success; - } - - -// ------------------------------------------------------------------- -// Class Definition : "::Manipulator". - - - inline TrackElement* Manipulator::getSegment () const { return _segment; } - inline DataNegociate* Manipulator::getData () const { return _data; } - inline RoutingEvent* Manipulator::getEvent () const { return _event; } - - - Manipulator::Manipulator ( TrackElement* segment, State& S ) - : _segment(segment) - , _data (NULL) - , _event (NULL) - , _S (S) - { - if ( !_segment ) - throw Error("Manipulator::Manipulator(): cannot build upon a NULL TrackElement."); - - DebugSession::open ( _segment->getNet(), 200 ); - - _data = _segment->getDataNegociate(); - if ( _data ) - _event = _data->getRoutingEvent(); - } - - - Manipulator::~Manipulator () - { - DebugSession::close (); - } - - - bool Manipulator::canRipup ( unsigned int flags ) const - { - if ( _data ) { - if ( not _event or _event->isUnimplemented() ) return false; - - unsigned int limit = Session::getKiteEngine()->getRipupLimit(_segment); - unsigned int count = _data->getRipupCount() + ((flags & HasNextRipup) ? 1 : 0); - - return (count < limit); - } - return false; - } - - - bool Manipulator::isCaged ( DbU::Unit axis ) const - { - Track* track = _segment->getTrack(); - if ( not track ) return false; - - TrackElement* neighbor = _segment->getPrevious(); - if ( neighbor and (neighbor->isFixed() or neighbor->isBlockage()) ) { - if ( abs(axis - neighbor->getTargetU()) < DbU::lambda(10.0) ) - return true; - } - - neighbor = _segment->getNext(); - if ( neighbor and (neighbor->isFixed() or neighbor->isBlockage()) ) { - if ( abs(axis - neighbor->getSourceU()) < DbU::lambda(10.0) ) - return true; - } - - return false; - } - - - bool Manipulator::ripup ( DbU::Unit point , unsigned int type, DbU::Unit axisHint ) - { - ltrace(200) << "Manipulator::ripup(DbU::Unit) " << DbU::getValueString(point) << endl; - - Interval overlap = Interval(point); - overlap.inflate ( Session::getExtensionCap() ); // Ugly. - - return ripup ( overlap, type, axisHint ); - } - - - bool Manipulator::ripup ( Interval overlap , unsigned int type, DbU::Unit axisHint, unsigned int toState ) - { - ltrace(200) << "Manipulator::ripup(Interval) " << overlap << endl; - - if ( not canRipup() ) return false; - - if ( _segment->isFixed() ) return false; - if ( _data == NULL ) return true; - - _S.addAction ( _segment, type, axisHint, toState ); - return true; - } - - - bool Manipulator::ripupPerpandiculars ( unsigned int flags ) - { - ltrace(200) << "Manipulator::ripupPerpandiculars() - " << flags << endl; - - bool success = true; - bool cagedPerpandiculars = false; - Interval constraints ( _event->getConstraints() ); - Interval perpandicularConstraints ( constraints ); - size_t placedPerpandiculars = 0; - unsigned int parallelActionFlags = SegmentAction::SelfRipup|SegmentAction::EventLevel4; - unsigned int perpandicularActionFlags = SegmentAction::SelfRipupPerpand; - - if ( flags & Manipulator::PerpandicularsFirst ) { - parallelActionFlags &= ~SegmentAction::EventLevel4; - perpandicularActionFlags |= SegmentAction::EventLevel4; - if ( flags & Manipulator::ToRipupLimit ) - perpandicularActionFlags |= SegmentAction::ToRipupLimit; - } else { - if ( flags & Manipulator::ToRipupLimit ) - parallelActionFlags |= SegmentAction::ToRipupLimit; - } - - ltrace(200) << "Pure constraints: " << constraints << endl; - - Track* track = NULL; - const vector& perpandiculars = _event->getPerpandiculars(); - - for ( size_t i=0 ; i < perpandiculars.size() ; i++ ) { - track = perpandiculars[i]->getTrack(); - if ( not track ) { - if ( flags & Manipulator::PerpandicularsFirst ) { - _S.addAction ( perpandiculars[i], perpandicularActionFlags ); - } - continue; - } - - bool dislodgeCaged = false; - if ( Manipulator(perpandiculars[i],_S).isCaged(_event->getSegment()->getAxis()) ) { - cagedPerpandiculars = true; - dislodgeCaged = true; - //break; - //continue; - } - - placedPerpandiculars++; - - // Try to ripup the perpandicular itself. - DataNegociate* data2 = perpandiculars[i]->getDataNegociate(); - ltrace(200) << "| " << perpandiculars[i] << endl; - - if ( (flags & Manipulator::ToMoveUp) and (data2->getState() < DataNegociate::MoveUp) ) - data2->setState ( DataNegociate::MoveUp ); - - if ( Manipulator(perpandiculars[i],_S).ripup(_event->getSegment()->getAxis() - ,perpandicularActionFlags) ) { - if ( dislodgeCaged ) { - // Ugly: hard-coded uses of pitch. - _event->setAxisHint ( _event->getSegment()->getAxis() + DbU::lambda(5.0) ); - } - continue; - } - - // Cannot ripup the perpandicular, try to ripup it's neigbors. - size_t begin; - size_t end; - track->getOverlapBounds ( constraints, begin, end ); - - for ( ; (begin < end) ; begin++ ) { - TrackElement* other = track->getSegment(begin); - - if ( other->getNet() == _event->getSegment()->getNet() ) continue; - - Interval otherCanonical ( other->getCanonicalInterval() ); - if ( not otherCanonical.intersect(constraints) ) continue; - - // Try to ripup conflicting neighbor. - if ( Manipulator(other,_S).canRipup() ) { - ltrace(200) << " | Ripup: " << begin << " " << other << endl; - _S.addAction ( other, SegmentAction::OtherRipup ); - } else { - ltrace(200) << "Aborted ripup of perpandiculars, fixed or blocked." << endl; - return false; - } - } - } - - if ( cagedPerpandiculars and not placedPerpandiculars ) { - ltrace(200) << "Aborted ripup of perpandiculars, constraints are due to fixed/blockage." << endl; - _S.addAction ( _segment, SegmentAction::SelfRipup ); - return true; - } - - if ( _segment->isLocal() and not placedPerpandiculars ) { - ltrace(200) << "No placed perpandiculars, tight native constraints, place perpandiculars FIRST." << endl; - for ( size_t i=0 ; i < perpandiculars.size() ; i++ ) { - _S.addAction ( perpandiculars[i], perpandicularActionFlags|SegmentAction::EventLevel4 ); - } - _S.addAction ( _segment, parallelActionFlags ); - return true; - } - - RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(_segment->getLayer()); - size_t tracksNb = 0; - - track = plane->getTrackByPosition(constraints.getVMin()); - - if ( track && (track->getAxis() < constraints.getVMin()) ) track = track->getNext(); - for ( ; track && (track->getAxis() <= constraints.getVMax()) - ; track = track->getNext(), tracksNb++ ); - - if ( _segment->isLocal() and (tracksNb < 2) ) success = ripple(); - - _S.addAction ( _segment, parallelActionFlags ); - return success; - } - - - bool Manipulator::relax ( Interval interval, unsigned int flags ) - { - interval.inflate ( - Session::getExtensionCap() /*+ DbU::lambda(5.0)*/ ); // Ugly. - ltrace(200) << "Manipulator::relax() of: " << _segment << " " << interval << endl; - - if ( _segment->isFixed() ) return false; - if ( not interval.intersect(_segment->getCanonicalInterval()) ) return false; - if ( not _data ) return false; - - if ( _segment->isTerminal() - and (_segment->getLayer() == Session::getRoutingGauge()->getRoutingLayer(1)) ) { - if ( interval.contains(_segment->base()->getAutoSource()->getX()) ) return false; - if ( interval.contains(_segment->base()->getAutoTarget()->getX()) ) return false; - } - - ltracein(200); - bool success = true; - - bool expand = _segment->isGlobal() and (flags&AllowExpand); - ltrace(200) << "Expand:" << expand << endl; - - Katabatic::GCellVector gcells; - _segment->getGCells ( gcells ); - - if ( gcells.size() < 2 ) { - cerr << Bug("relax() Cannot break %p:%s,\n only in %s." - ,_segment->base()->base() - ,getString(_segment).c_str() - ,getString(gcells[0]).c_str() - ) << endl; - ltraceout(200); - return false; - } - - unsigned int depth = Session::getRoutingGauge()->getLayerDepth(_segment->getLayer()); - Interval uside; - size_t dogLegCount = 0; - size_t iminconflict = gcells.size(); - size_t imaxconflict = gcells.size(); - size_t igcell; - - // Look for closest enclosing min & max GCells indexes. - for ( igcell=0 ; igcellgetUSide(_segment->getDirection()/*,true*/); - ltrace(200) << "| " << gcells[igcell] << " uside: " << uside << endl; - - if ( uside.contains(interval.getVMin()) ) { - iminconflict = igcell; - ltrace(200) << "> Min conflict: " << iminconflict << endl; - } - if ( uside.contains(interval.getVMax()) ) { - imaxconflict = igcell; - ltrace(200) << "> Max conflict: " << imaxconflict << endl; - } - } - - // Expand min & max to enclose GCells of greatest or equal order - // (i.e. less saturateds) - bool minExpanded = false; - bool maxExpanded = false; - if ( expand ) { - if ( iminconflict < gcells.size() ) { - size_t imindensity = 0; - - for ( size_t iexpand=1 ; iexpand < iminconflict ; iexpand++ ) { - if ( not _segment->canDogLegAt(gcells[iexpand],TrackElement::AllowDoglegReuse) ) continue; - - ltrace(200) << "Density " << Session::getRoutingGauge()->getRoutingLayer(depth)->getName() - << " " << gcells[iexpand]->getDensity(depth) << endl; - - if ( gcells[imindensity]->getDensity(depth) > gcells[iexpand]->getDensity(depth) ) - imindensity = iexpand; - } - - if ( iminconflict != imindensity ) minExpanded = true; - iminconflict = (imindensity>0) ? imindensity : gcells.size(); - } - - if ( imaxconflict < gcells.size() ) { - size_t imindensity = imaxconflict; - for ( size_t iexpand=imaxconflict+1; iexpand < gcells.size() ; iexpand++ ) { - if ( not _segment->canDogLegAt(gcells[iexpand],TrackElement::AllowDoglegReuse) ) continue; - - ltrace(200) << "Density " << Session::getRoutingGauge()->getRoutingLayer(depth)->getName() - << " " << gcells[iexpand]->getDensity(depth) << endl; - - if ( gcells[imindensity]->getDensity(depth) > gcells[iexpand]->getDensity(depth) ) - imindensity = iexpand; - } - - if ( imindensity != imaxconflict ) maxExpanded = true; - imaxconflict = (imindensity < gcells.size()) ? imindensity : gcells.size(); - } - } - ltrace(200) << "minExpanded:" << minExpanded << " (" << iminconflict - << ") maxExpanded:" << maxExpanded << " (" << imaxconflict << ")" << endl; - - // Check for full enclosure. - if ( ( (iminconflict == gcells.size()) and (imaxconflict == gcells.size() ) ) - or ( (iminconflict == 0) and (imaxconflict == gcells.size()-1) )) { - cinfo << "[INFO] Manipulator::relax(): Segment fully enclosed in interval." << endl; - ltraceout(200); - return false; - } - - // Suppress min/max if it's the first/last. - if ( (iminconflict < gcells.size()) and (imaxconflict == gcells.size()-1) ) imaxconflict = gcells.size(); - if ( (imaxconflict < gcells.size()) and (iminconflict == 0) ) iminconflict = gcells.size(); - - // Compute number of doglegs and nature of the *first* dogleg. - // (first can be min or max, second can only be max) - bool firstDogLegIsMin = false; - if ( iminconflict < gcells.size() ) { dogLegCount++; firstDogLegIsMin = true; } - if ( imaxconflict < gcells.size() ) dogLegCount++; - - switch ( dogLegCount ) { - case 2: - // Compact only if the double dogleg is at beginning or end. - if ( iminconflict == imaxconflict ) { - if ( iminconflict == 0 ) { - // First dogleg is max. - dogLegCount--; - } else if ( iminconflict == gcells.size()-1 ) { - dogLegCount--; - firstDogLegIsMin = true; - } - } - break; - case 1: break; - case 0: - cerr << Bug("Manipulator::relax() Can't find a GCell suitable for making dogleg." - ,getString(interval).c_str()) << endl; - ltraceout(200); - return false; - } - - ltrace(200) << "| Has to do " << dogLegCount << " doglegs." << endl; - - // Check of "min is less than one track close the edge" (while not expanded). - // AND we are on the first GCell AND there's one dogleg only. - if ( not minExpanded and (iminconflict == 0) and (imaxconflict == gcells.size()) ) { - ltrace(200) << "Cannot break in first GCell only." << endl; - ltraceout(200); - return false; - } - - // Check of "min is less than one track close the edge" (while not expanded). - if ( /*not minExpanded and*/ (iminconflict > 0) and (iminconflict < gcells.size()) ) { - uside = gcells[iminconflict-1]->getUSide(_segment->getDirection()/*,true*/); - ltrace(200) << "GCell Edge Comparison (min): " << uside - << " vs. " << DbU::getValueString(interval.getVMin()) << endl; - // Ugly: One lambda shrink. - if ( interval.getVMin()-DbU::lambda(1.0) <= uside.getVMax() ) { - ltrace(200) << "Using previous GCell." << endl; - iminconflict--; - } - } - - // Check if there is only one dogleg AND it's the last one. - if ( not maxExpanded and (iminconflict == gcells.size()) and (imaxconflict == gcells.size()-1) ) { - ltrace(200) << "Cannot break in last GCell only." << endl; - ltraceout(200); - return false; - } - - // Check of "max is less than one track close the edge" (while not expanded). - if ( /*not maxExpanded and*/ (imaxconflict < gcells.size()-1) ) { - uside = gcells[imaxconflict+1]->getUSide(_segment->getDirection()/*,true*/); - ltrace(200) << "GCell Edge Comparison (max): " << uside - << " vs. " << DbU::getValueString(interval.getVMax()) << endl; - // Ugly: Direct uses of routing pitch. - if ( interval.getVMax()+DbU::lambda(5.0) >= uside.getVMin() ) { - interval.inflate( 0, DbU::fromLambda(5.0) ); - ltrace(200) << "Using next GCell " << interval << endl; - imaxconflict++; - } - } - - size_t ifirstDogleg = gcells.size(); - size_t isecondDogleg = gcells.size(); - if ( not firstDogLegIsMin ) { - ifirstDogleg = imaxconflict; - } else { - ifirstDogleg = iminconflict; - isecondDogleg = imaxconflict; - } - - // Making first dogleg. - ltrace(200) << "Making FIRST dogleg at " << ifirstDogleg << endl; - TrackElement* segment1 = NULL; - TrackElement* segment2 = NULL; - Track* track = _segment->getTrack(); - Katabatic::GCell* dogLegGCell = gcells[ifirstDogleg]; - TrackElement* dogleg = NULL; - DbU::Unit doglegAxis; - bool doglegReuse1 = false; - bool doglegReuse2 = false; - - // Try to reuse existing dogleg if broken at either end. - if ( ifirstDogleg == 0 ) dogleg = _segment->getSourceDogLeg(); - if ( ifirstDogleg == gcells.size()-1 ) dogleg = _segment->getTargetDogLeg(); - if ( dogleg ) { - ltrace(200) << "Reusing dogleg." << endl; - doglegReuse1 = true; - segment1 = _segment; - } else { - // Try to create a new dogleg. - if ( not _segment->canDogLegAt(dogLegGCell) ) { - ltrace(200) << "Cannot create FIRST dogleg." << endl; - ltraceout(200); - return false; - } - dogleg = _segment->makeDogLeg ( dogLegGCell ); - segment1 = Session::lookup ( Session::getDogLegs()[2] ); - } - - if ( firstDogLegIsMin ) { - if ( minExpanded ) { - //doglegAxis = dogLegGCell->getUSide(_segment->getDirection(),false).getVMax() - DbU::lambda(1.0); - doglegAxis = dogLegGCell->getUSide(_segment->getDirection()/*,false*/).getCenter(); - ltrace(200) << "MARK 1 doglegAxis: " << DbU::getValueString(doglegAxis) << endl; - } else { - // Ugly: hardcoded pitch. - doglegAxis = interval.getVMin() - DbU::lambda(5.0); - ltrace(200) << "MARK 2 doglegAxis: " << DbU::getValueString(doglegAxis) << endl; - } - } else { - if ( maxExpanded ) { - doglegAxis = dogLegGCell->getUSide(_segment->getDirection()/*,false*/).getVMin(); - ltrace(200) << "MARK 3 doglegAxis: " << DbU::getValueString(doglegAxis) << endl; - } else { - // Ugly: hardcoded pitch (5.0 - 1.0). - doglegAxis = interval.getVMax() + DbU::lambda(4.0); - ltrace(200) << "MARK 4 doglegAxis: " << DbU::getValueString(doglegAxis) << endl; - } - } - if ( doglegReuse1 ) _S.addAction ( dogleg, SegmentAction::OtherRipup ); - else dogleg->setAxis ( doglegAxis ); - - // If event is present, the dogleg is in the current RoutingSet. - RoutingEvent* event = dogleg->getDataNegociate()->getRoutingEvent(); - if ( event ) { - ltrace(200) << "Set Axis Hint: @" << DbU::getValueString(doglegAxis) << " " << dogleg << endl; - event->setAxisHint ( doglegAxis ); - } else { - ltrace(200) << "Dogleg has no RoutingEvent yet." << endl; - } - - // if ( (dogLegCount == 2) and not _segment->getTrack() ) { - // Session::addInsertEvent ( _segment, track ); - // } - - // Making second dogleg. - if ( dogLegCount > 1 ) { - ltrace(200) << "Making SECOND dogleg at " << isecondDogleg - << " on " << segment1 << endl; - - dogleg = NULL; - dogLegGCell = gcells[isecondDogleg]; - - if ( ifirstDogleg == isecondDogleg ) { - ltrace(200) << "Double break in same GCell." << endl; - segment1->setSourceDogLeg(false); - } - - if ( isecondDogleg == gcells.size()-1 ) dogleg = segment1->getTargetDogLeg(); - if ( dogleg ) { - ltrace(200) << "Reusing dogleg." << endl; - doglegReuse2 = true; - segment2 = segment1; - } else { - // Try to create a new dogleg. - if ( not segment1->canDogLegAt(dogLegGCell) ) { - ltrace(200) << "Cannot create SECOND dogleg." << endl; - ltraceout(200); - return false; - } - dogleg = segment1->makeDogLeg ( dogLegGCell ); - segment2 = Session::lookup ( Session::getDogLegs()[2] ); - } - - if ( maxExpanded ) { - //doglegAxis = dogLegGCell->getUSide(segment1->getDirection(),false).getVMin(); - doglegAxis = dogLegGCell->getUSide(segment1->getDirection()/*,false*/).getCenter(); - } else { - // Ugly: hardcoded pitch. - doglegAxis = interval.getVMax() + DbU::lambda(5.0); - } - if ( doglegReuse2 ) _S.addAction ( dogleg, SegmentAction::OtherRipup ); - else dogleg->setAxis ( doglegAxis ); - - // If event is present, the dogleg is in the current RoutingSet. - RoutingEvent* event = dogleg->getDataNegociate()->getRoutingEvent(); - if ( event ) { - ltrace(200) << "Set Axis Hint: @" << DbU::getValueString(doglegAxis) << " " << dogleg << endl; - event->setAxisHint ( doglegAxis ); - } else { - ltrace(200) << "Dogleg has no RoutingEvent yet." << endl; - } - - // This cases seems never to occurs. - const vector& doglegs = Session::getDogLegs(); - for ( size_t i=0 ; igetTrack() and track ) { - ltrace(200) << "Direct Track insert of: " << segment << endl; - Session::addInsertEvent ( segment, track ); - } - } - } - - switch ( dogLegCount ) { - case 1: - if ( not doglegReuse1 ) { - if ( firstDogLegIsMin ) - _segment->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true ); - else - segment1->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true ); - } - if ( (flags & NoDoglegReuse) and (doglegReuse1 or doglegReuse2 ) ) - success = false; - break; - case 2: - if ( not doglegReuse1 ) - _segment->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true ); - if ( not doglegReuse2 ) - segment2->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true ); - break; - } - - if ( _segment->isLocal() ) { - ltrace(200) << "Reset state of: " << _segment << endl; - _segment->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true ); - } else { - ltrace(200) << "No state reset: " << _segment << endl; - } - - if ( (not doglegReuse1) and segment1 and segment1->isLocal() ) { - ltrace(200) << "Reset state of: " << segment1 << endl; - segment1->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true ); - } - - if ( (not doglegReuse2) and segment2 and segment2->isLocal() ) { - ltrace(200) << "Reset state of: " << segment2 << endl; - segment2->getDataNegociate()->setState ( DataNegociate::RipupPerpandiculars, true ); - } - - // if ( _segment ) Manipulator(_segment,_S).pivotDown (); - // if ( segment1 ) Manipulator(segment1,_S).pivotDown (); - // if ( segment2 ) Manipulator(segment2,_S).pivotDown (); - - ltraceout(200); - return success; - } - - - bool Manipulator::insertInTrack ( size_t itrack ) - { - Track* track = _S.getTrack(itrack); - size_t begin = _S.getBegin(itrack); - size_t end = _S.getEnd (itrack); - Net* ownerNet = _segment->getNet(); - Interval toFree (_segment->getCanonicalInterval()); - Net* ripupNet = NULL; - set canonicals; - DbU::Unit rightAxisHint = 0; - DbU::Unit leftAxisHint = 0; - bool leftIntrication = false; - bool rightIntrication = false; - bool success = true; - unsigned long maxId = AutoSegment::getMaxId(); - - ltrace(200) << "Manipulator::insertInTrack() - " << toFree << endl; - - for ( size_t i = begin ; success && (i < end) ; i++ ) { - TrackElement* segment2 = track->getSegment(i); - - ltrace(200) << "* Looking // " << segment2 << endl; - - if ( segment2->getNet() == ownerNet ) continue; - if ( not toFree.intersect(segment2->getCanonicalInterval()) ) continue; - if ( segment2->isBlockage() or segment2->isFixed() ) { - success = false; - continue; - } - if ( segment2->getId() >= maxId ) continue; - //if ( (segment2->getNet() != ripupNet ) - // && !toFree.intersect(segment2->getCanonicalInterval()) ) continue; - ripupNet = segment2->getNet(); - - DataNegociate* data2 = segment2->getDataNegociate(); - if ( !data2 ) { - ltrace(200) << "No DataNegociate, ignoring." << endl; - continue; - } - - if ( data2->getState() == DataNegociate::MaximumSlack ) { - ltrace(200) << "At " << DataNegociate::getStateString(data2) - << " for " << segment2 << endl; - success = false; - continue; - } - - bool shrinkLeft = false; - bool shrinkRight = false; - - if ( data2->getCost().getRightMinExtend() < toFree.getVMin() ) { - ltrace(200) << "- Shrink right edge (push left) " << segment2 << endl; - shrinkRight = true; - TrackElement* rightNeighbor2 = track->getSegment(i+1); - if ( rightNeighbor2 && (rightNeighbor2->getNet() == segment2->getNet()) ) { - Interval interval1 = segment2->getCanonicalInterval(); - Interval interval2 = rightNeighbor2->getCanonicalInterval(); - - if ( interval1.intersect(interval2) && (interval2.getVMax() > interval1.getVMax()) ) - shrinkLeft = true; - } - } - - if ( data2->getCost().getLeftMinExtend() > toFree.getVMax() ) { - ltrace(200) << "- Shrink left edge (push right) " << segment2 << endl; - shrinkLeft = true; - if ( i > 0 ) { - TrackElement* leftNeighbor2 = track->getSegment(i-1); - if ( leftNeighbor2 && (leftNeighbor2->getNet() == segment2->getNet()) ) { - Interval interval1 = segment2->getCanonicalInterval(); - Interval interval2 = leftNeighbor2->getCanonicalInterval(); - - if ( interval1.intersect(interval2) && (interval2.getVMin() < interval1.getVMin()) ) - shrinkRight = true; - } - } - } - - if ( _segment->isLocal() and segment2->isLocal() ) { - if ( shrinkLeft and shrinkRight ) { - Interval interval1 = segment2->getCanonicalInterval(); - if ( toFree.getCenter() < interval1.getCenter() ) shrinkRight = false; - else shrinkLeft = false; - } - } - - //if ( not (shrinkLeft xor shrinkRight) ) { - ltrace(200) << "- Hard overlap/enclosure/shrink " << segment2 << endl; - if ( _segment->isStrap() and segment2->isGlobal() ) continue; - if ( not (success = Manipulator(segment2,_S).ripup(toFree,SegmentAction::OtherRipup)) ) - continue; - //} - - canonicals.clear (); - forEach ( TrackElement*, isegment3 - , segment2->getCollapsedPerpandiculars().getSubSet(TrackElements_UniqCanonical(canonicals)) ) { - DataNegociate* data3 = isegment3->getDataNegociate(); - if ( not data3 ) continue; - - RoutingEvent* event3 = data3->getRoutingEvent(); - if ( not event3 ) continue; - - if ( not toFree.intersect(event3->getConstraints()) ) { - ltrace(200) << " . " << *isegment3 << endl; - continue; - } - - ltrace(200) << " | " << *isegment3 << endl; - - if ( shrinkRight xor shrinkLeft ) { - if ( shrinkRight ) { - if ( not (success=Manipulator(*isegment3,_S).ripup ( track->getAxis() - , SegmentAction::OtherPushAside - | SegmentAction::AxisHint - , toFree.getVMin() - DbU::lambda(2.5) - )) ) - break; - - if ( event3->getTracksFree() == 1 ) { - ltrace(200) << "Potential left intrication with other perpandicular." << endl; - if ( isegment3->getAxis() == segment2->getTargetU() - Session::getExtensionCap() ) { - leftIntrication = true; - leftAxisHint = isegment3->getAxis(); - } - } - } - if ( shrinkLeft ) { - if ( not (success=Manipulator(*isegment3,_S).ripup ( track->getAxis() - , SegmentAction::OtherPushAside - | SegmentAction::AxisHint - , toFree.getVMax() + DbU::lambda(2.5) - )) ) - break; - if ( event3->getTracksFree() == 1 ) { - ltrace(200) << "Potential right intrication with other perpandicular." << endl; - if ( isegment3->getAxis() == segment2->getSourceU() + Session::getExtensionCap() ) { - rightIntrication = true; - rightAxisHint = isegment3->getAxis(); - } - } - } - } else { - // DbU::Unit axisHint - // = (event3->getAxisHint() - toFree.getVMin() < toFree.getVMax() - event3->getAxisHint()) - // ? (toFree.getVMin() - DbU::lambda(1.0)) : (toFree.getVMax() + DbU::lambda(1.0)); - if ( not (success=Manipulator(*isegment3,_S).ripup ( track->getAxis() - , SegmentAction::OtherRipup - | SegmentAction::EventLevel3 - //| SegmentAction::AxisHint, axisHint - )) ) - break; - } - } - if ( not success ) break; - } - - if ( success ) { - ltrace(200) << "Manipulator::insertInTrack() success" << endl; - - _S.setState ( State::OtherRipup ); - _S.addAction ( _segment, SegmentAction::SelfInsert|SegmentAction::EventLevel4 ); - _segment->setAxis ( _S.getCost(itrack).getTrack()->getAxis() ); - - unsigned int flags = 0; - if ( rightIntrication ) flags |= RightAxisHint; - if ( leftIntrication ) flags |= LeftAxisHint; - if ( flags ) - Manipulator(_segment,_S).shrinkToTrack(itrack,flags,leftAxisHint,rightAxisHint); - } else - _S.clearActions (); - - return success; - } - - - bool Manipulator::forceToTrack ( size_t itrack ) - { - Track* track = _S.getTrack(itrack); - size_t begin = _S.getBegin(itrack); - size_t end = _S.getEnd (itrack); - Net* ownerNet = _segment->getNet(); - Interval toFree (_segment->getCanonicalInterval()); - Net* ripupNet = NULL; - set canonicals; - bool success = true; - - ltrace(200) << "Manipulator::forceToTrack() - " << toFree << endl; - - for ( size_t i = begin ; success && (i < end) ; i++ ) { - TrackElement* segment2 = track->getSegment(i); - - ltrace(200) << "* Looking // " << segment2 << endl; - - if ( segment2->getNet() == ownerNet ) continue; - if ( !toFree.intersect(segment2->getCanonicalInterval()) ) continue; - if ( segment2->isFixed() ) { - success = false; - continue; - } - //if ( (segment2->getNet() != ripupNet ) - // && !toFree.intersect(segment2->getCanonicalInterval()) ) continue; - ripupNet = segment2->getNet(); - - DataNegociate* data2 = segment2->getDataNegociate(); - if ( !data2 ) { - ltrace(200) << "No DataNegociate, ignoring." << endl; - continue; - } - - ltrace(200) << "- Forced ripup " << segment2 << endl; - if ( not (success=Manipulator(segment2,_S).ripup(toFree,SegmentAction::OtherRipup)) ) - continue; - - canonicals.clear (); - forEach ( TrackElement*, isegment3 - , segment2->getCollapsedPerpandiculars().getSubSet(TrackElements_UniqCanonical(canonicals)) ) { - DataNegociate* data3 = isegment3->getDataNegociate(); - if ( !data3 ) continue; - - RoutingEvent* event3 = data3->getRoutingEvent(); - if ( !event3 ) continue; - - if ( Manipulator(*isegment3,_S).canRipup() ) - _S.addAction ( *isegment3, SegmentAction::OtherRipup ); - } - } - - if ( success ) { - _S.setState ( State::OtherRipup ); - _S.addAction ( _segment, SegmentAction::SelfInsert ); - _segment->setAxis ( _S.getCost(itrack).getTrack()->getAxis() ); - } - - return success; - } - - - bool Manipulator::shrinkToTrack ( size_t i, unsigned int flags, DbU::Unit leftAxisHint, DbU::Unit rightAxisHint ) - { - Track* track = _S.getTrack(i); - size_t begin = _S.getBegin(i); - size_t end = _S.getEnd (i); - Net* ownerNet = _segment->getNet(); - set canonicals; - bool success = true; - DbU::Unit leftExtend = _segment->getSourceU() + Session::getExtensionCap(); - DbU::Unit rightExtend = _segment->getSourceU() - Session::getExtensionCap(); - - ltrace(200) << "Manipulator::shrinkToTrack()" << endl; - - if ( _segment->isLocal() ) return false; - //Interval shrunkFree ( _segment->getSourceConstraints().getVMax() - // , _segment->getTargetConstraints().getVMin() ); - Interval shrunkFree = _segment->base()->getMinSpanU(); - - ltrace(200) << "* " << shrunkFree << endl; - - for ( size_t i = begin ; success && (i < end) ; i++ ) { - TrackElement* segment2 = track->getSegment(i); - - ltrace(200) << "* Looking // " << segment2 << endl; - - if ( segment2->getNet() == ownerNet ) continue; - if ( segment2->isFixed() ) { success = false; continue; } - if ( !shrunkFree.intersect(segment2->getCanonicalInterval()) ) continue; - - success = false; - } - - if ( success ) { - set perpandiculars; - set::iterator iperpand; - - DbU::Unit axisHint; - if ( not (flags & LeftAxisHint ) ) leftAxisHint = shrunkFree.getCenter(); - if ( not (flags & RightAxisHint) ) rightAxisHint = shrunkFree.getCenter(); - - _segment->getPerpandicularsBound ( perpandiculars ); - for ( iperpand = perpandiculars.begin() ; iperpand != perpandiculars.end() ; iperpand++ ) { - DataNegociate* data2 = (*iperpand)->getDataNegociate(); - if ( data2 ) { - ltrace(200) << "| perpandicular bound:" << *iperpand << endl; - success = Manipulator(*iperpand,_S).ripup ( track->getAxis(), SegmentAction::SelfRipupAndAxisHint ); - if ( success ) { - if ( (*iperpand)->getAxis() == leftExtend ) axisHint = leftAxisHint; - else if ( (*iperpand)->getAxis() == rightExtend ) axisHint = rightAxisHint; - else { - cinfo << "[INFO] Bound Axis is neither left nor right\n " - << (*iperpand) << endl; - axisHint = shrunkFree.getCenter(); - } - - _S.getActions()[_S.getActions().size()-1].setAxisHint ( axisHint ); - } - } - } - - _S.addAction ( _segment, SegmentAction::SelfInsert ); - _S.setState ( State::OtherRipup ); - - ltrace(200) << "Successful shrinkToTrack." << endl; - return true; - } - - return false; - } - - - bool Manipulator::forceOverLocals () - { - ltrace(200) << "Manipulator::forceOverLocals()" << endl; - ltracein(200); - - vector& costs = _S.getCosts(); - size_t itrack = 0; - for ( ; itrackgetNet(); - Interval toFree (_segment->getCanonicalInterval()); - - for ( size_t i = begin ; success and (i < end) ; i++ ) { - TrackElement* segment2 = track->getSegment(i); - - ltrace(200) << "* Looking // " << segment2 << endl; - - if ( segment2->getNet() == ownerNet ) continue; - if ( not toFree.intersect(segment2->getCanonicalInterval()) ) continue; - if ( segment2->isFixed() ) { - success = false; - continue; - } - - DataNegociate* data2 = segment2->getDataNegociate(); - if ( not data2 ) { - ltrace(200) << "No DataNegociate, ignoring." << endl; - success = false; - continue; - } - - ltrace(200) << "- Forced ripup " << segment2 << endl; - if ( not (success=Manipulator(segment2,_S).ripup(toFree,SegmentAction::OtherRipup)) ) { - continue; - } - } - - if ( success ) { - _S.setState ( State::OtherRipup ); - _S.addAction ( _segment, SegmentAction::SelfInsert ); - _segment->setAxis ( _S.getCost(itrack).getTrack()->getAxis() ); - break; - } - } - - ltraceout(200); - return (itrack < costs.size()); - } - - - bool Manipulator::desalignate () - { - ltrace(200) << "Manipulator::desalignate() " << _segment << endl; - - if ( _segment->isFixed () ) return false; - if ( !_segment->canDesalignate() ) return false; - - _segment->desalignate (); - return true; - } - - - bool Manipulator::slacken () - { - ltrace(200) << "Manipulator::slacken() " << _segment << endl; - - if ( _segment->isFixed () ) return false; - if ( not _segment->canSlacken() ) return false; - - _segment->slacken (); - return true; - } - - - bool Manipulator::goOutsideGCell () - { - ltrace(200) << "Manipulator::goOutsideGCell() " << _segment << endl; - return false; - -#if 0 - if ( _segment->isFixed () ) return false; - if ( !_segment->canGoOutsideGCell() ) return false; - - GCell* sourceGCell = _segment->getGCell(); - GCell* leftGCell = NULL; - GCell* rightGCell = NULL; - Interval uside; - bool goLeft = false; - bool goRight = false; - - if ( _segment->isHorizontal() ) { - uside = sourceGCell->getUSide ( Constant::Vertical, false ); - leftGCell = sourceGCell->getDown(); - rightGCell = sourceGCell->getUp (); - } else { - uside = sourceGCell->getUSide ( Constant::Horizontal, false ); - leftGCell = sourceGCell->getLeft (); - rightGCell = sourceGCell->getRight(); - } - - Interval constraints; - _segment->base()->getConstraints ( constraints ); - - // Ugly: Must use the right compensator for VMax. - if ( rightGCell and (uside.getVMax() <= constraints.getVMax())+DbU::lambda(1.0) ) goRight = true; - if ( leftGCell and (uside.getVMin() >= constraints.getVMin()) ) goLeft = true; - - if ( goRight and goLeft ) { - DbU::Unit distanceToLeft = _segment->getAxis() - uside.getVMin(); - DbU::Unit distanceToRight = uside.getVMax() - _segment->getAxis(); - if ( distanceToLeft < distanceToRight ) goRight = false; - else goLeft = false; - } - - _segment->moveAside ( goLeft ); - - return true; -#endif - } - - - bool Manipulator::ripple () - { - ltrace(200) << "Manipulator::ripple() from " << _segment << endl; - - //if ( not _segment->canRipple() ) return false; - if ( not _segment->isLocal() ) return false; - - Net* net = _segment->getNet(); - Interval uside = _segment->base()->getAutoSource()->getGCell()->getUSide ( Constant::perpandicular(_segment->getDirection())/*, false*/ ); - RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(_segment->getLayer()); - - ltracein(200); - forEach ( Track*, itrack, Tracks_Range::get(plane,uside)) { - size_t begin; - size_t end; - - itrack->getOverlapBounds ( _segment->getCanonicalInterval(), begin, end ); - for ( ; begin < end ; begin++ ) { - TrackElement* other = itrack->getSegment(begin); - ltrace(200) << "| " << other << endl; - - if ( other->getNet() == net ) continue; - if ( not other->canRipple() ) continue; - - DataNegociate* otherData = other->getDataNegociate(); - if ( not otherData ) continue; - - DbU::Unit shiftedAxisHint; - RoutingEvent* otherEvent = otherData->getRoutingEvent(); - - if ( other->getAxis() < _segment->getAxis() ) { - // Ugly: routing pitch. - shiftedAxisHint = otherEvent->getAxisHint() - DbU::lambda(5.0); - if ( shiftedAxisHint < uside.getVMin() ) - shiftedAxisHint = uside.getVMin(); - } else { - // Ugly: routing pitch. - shiftedAxisHint = otherEvent->getAxisHint() + DbU::lambda(5.0); - if ( shiftedAxisHint > uside.getVMax() ) - shiftedAxisHint = uside.getVMax(); - } - - otherEvent->setAxisHint ( shiftedAxisHint ); - _S.addAction ( other, SegmentAction::OtherRipup ); - } - } - ltraceout(200); - - return true; - } - - - bool Manipulator::pivotUp () - { - ltrace(200) << "Manipulator::pivotUp() " << _segment << endl; - - if ( _segment->isFixed () ) return false; - if ( _segment->isStrap () ) return false; - - float reserve = (_segment->isLocal()) ? 0.5 : 1.0; - if ( not _segment->canMoveUp(reserve) ) return false; - - _segment->moveUp (); - return true; - } - - - bool Manipulator::pivotDown () - { - ltrace(200) << "Manipulator::pivotDown() " << _segment << endl; - - if ( _segment->isFixed () ) return false; - if ( _segment->isStrap () ) return false; - if ( not _segment->canPivotDown(2.0) ) return false; - - _segment->moveDown (); - return true; - } - - - bool Manipulator::moveUp ( unsigned int flags ) - { - ltrace(200) << "Manipulator::moveUp() " << _segment << endl; - - unsigned int kflags = Katabatic::AutoSegment::Propagate|Katabatic::AutoSegment::PerpandicularFrag; - kflags |= (flags & AllowLocalMoveUp ) ? Katabatic::AutoSegment::AllowLocal : 0; - kflags |= (flags & AllowTerminalMoveUp) ? Katabatic::AutoSegment::AllowTerminal : 0; - - if ( _segment->isFixed() ) return false; - if ( not (flags & AllowLocalMoveUp) ) { - if ( _segment->isLocal() ) { - if ( not _segment->canPivotUp(0.5) ) return false; - } else { - if ( _segment->getLength() < DbU::lambda(100.0) ) { - if ( not (flags & AllowShortPivotUp) ) return false; - if ( not _segment->canPivotUp(1.0) ) return false; - } - if ( not _segment->canMoveUp(0.5,kflags) ) return false; // MARK 1 - } - } else { - if ( not _segment->canMoveUp(0.5,kflags) ) return false; // MARK 1 - } - -#if DISABLED - ltrace(200) << "| Repack Tracks: " << endl; - - Interval constraints; - Interval overlap = _segment->getCanonicalInterval(); - RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(_segment->getLayer()); - size_t begin; - size_t end; - TrackElement* other; - - constraints = _segment->getGCell()->getUSide(Constant::perpandicular(_segment->getDirection()),true); - forEach ( Track*, itrack, Tracks_Range::get(plane,constraints)) { - itrack->getOverlapBounds ( overlap, begin, end ); - for ( ; (begin < end) ; begin++ ) { - other = itrack->getSegment(begin); - if ( other->isGlobal() ) continue; - - ltrace(200) << " | Ripup for repack: " << begin << " " << other << endl; - _S.addAction ( other, SegmentAction::OtherRipup ); - } - } -#endif - return _segment->moveUp ( kflags ); - } - - - bool Manipulator::makeDogLeg () - { - ltrace(200) << "Manipulator::makeDogLeg() " << _segment << endl; - - if ( _segment->isFixed() ) return false; - if ( !_segment->isLocal() ) return false; - - if ( _S.getCosts().size() ) { - Track* track = _S.getTrack(0); - size_t begin = _S.getBegin(0); - size_t end = _S.getEnd (0); - Net* ownerNet = _segment->getNet(); - Interval toFree (_segment->getCanonicalInterval()); - Interval overlap; - - for ( size_t i = begin ; i < end ; i++ ) { - TrackElement* segment2 = track->getSegment(i); - - ltrace(200) << "* Looking // " << segment2 << endl; - - if ( segment2->getNet() == ownerNet ) continue; - if ( !toFree.intersect(segment2->getCanonicalInterval()) ) continue; - - if ( overlap.isEmpty() ) - overlap = segment2->getCanonicalInterval(); - else - overlap.merge ( segment2->getCanonicalInterval() ); - } - - if ( !overlap.isEmpty() && makeDogLeg(overlap) ) return true; - } - - if ( !_segment->canDogLeg() ) return false; - _segment->makeDogLeg (); - - return true; - } - - - bool Manipulator::makeDogLeg ( Interval overlap ) - { - ltrace(200) << "Manipulator::makeDogLeg(Interval) " << _segment << endl; - ltrace(200) << overlap << endl; - - //if ( !_segment->isLocal() || !_segment->canDogLeg() ) return false; - - if ( _segment->isFixed () ) return false; - if ( !_segment->canDogLeg(overlap) ) return false; - - bool pushLeft; - bool isTerminal = _segment->isTerminal(); - TrackElement* dogleg = _segment->makeDogLeg(overlap,pushLeft); - if ( dogleg ) { - ltrace(200) << "Manipulator::makeDogLeg(Interval) - Push dogleg to the " - << ((pushLeft)?"left":"right") << endl; - if ( isTerminal ) { - Katabatic::AutoContact* contact = (pushLeft) ? _segment->base()->getAutoSource() - : _segment->base()->getAutoTarget(); - DbU::Unit axisHint = (_segment->isHorizontal()) ? contact->getX() : contact->getY(); - RoutingEvent* event = dogleg->getDataNegociate()->getRoutingEvent(); - if ( event ) { - event->setAxisHint ( axisHint ); - event->setForcedToHint ( true ); - ltrace(200) << "Forced to axis hint @" << DbU::getValueString(axisHint) << endl; - } - } - return true; - } - - return false; - } - - - bool Manipulator::makeDogLeg ( DbU::Unit position ) - { - ltrace(200) << "Manipulator::makeDogLeg(position) " << _segment << endl; - ltrace(200) << "Breaking position: " << DbU::getValueString(position) << endl; - - if ( _segment->isFixed() ) return false; - - Katabatic::GCellVector gcells; - _segment->getGCells ( gcells ); - - size_t igcell = 0; - for ( ; igcellgetUSide(_segment->getDirection()/*,true*/).contains(position) ) - break; - } - if ( igcell == gcells.size() ) return false; - if ( not _segment->canDogLegAt(gcells[igcell]) ) return false; - - TrackElement* dogleg = _segment->makeDogLeg(gcells[igcell]); - return ( dogleg != NULL ); - } - - - bool Manipulator::minimize () - { - ltrace(200) << "Manipulator::minimize() " << _segment << endl; - - if ( _segment->isFixed() ) return false; - if ( not _event->canMinimize() ) return false; - - DbU::Unit minSpan = DbU::Max; - DbU::Unit maxSpan = DbU::Min; - Interval punctualSpan ( false ); - - if ( _segment->base()->getAutoSource()->getAnchor() ) { - ltrace(200) << " | " << _segment->base()->getAutoSource() << endl; - Interval constraints ( _segment->base()->getAutoSource()->getUConstraints - (Constant::perpandicular(_segment->getDirection())) ); - ltrace(200) << " | Constraints: " << constraints << endl; - - minSpan = min ( minSpan, constraints.getVMax() ); - maxSpan = max ( maxSpan, constraints.getVMin() ); - punctualSpan.intersection ( constraints ); - } - - if ( _segment->base()->getAutoTarget()->getAnchor() ) { - ltrace(200) << " | " << _segment->base()->getAutoTarget() << endl; - Interval constraints ( _segment->base()->getAutoTarget()->getUConstraints - (Constant::perpandicular(_segment->getDirection())) ); - ltrace(200) << " | Constraints: " << constraints << endl; - - minSpan = min ( minSpan, constraints.getVMax() ); - maxSpan = max ( maxSpan, constraints.getVMin() ); - punctualSpan.intersection ( constraints ); - } - - const vector& perpandiculars = _event->getPerpandiculars(); - for ( size_t i=0 ; igetDataNegociate(); - if ( not data2 ) continue; - - ltrace(200) << " | " << perpandiculars[i] << endl; - - RoutingEvent* event2 = data2->getRoutingEvent(); - if ( not event2 ) continue; - - ltrace(200) << " | Constraints: " << event2->getConstraints() << endl; - - minSpan = min ( minSpan, event2->getConstraints().getVMax() ); - maxSpan = max ( maxSpan, event2->getConstraints().getVMin() ); - punctualSpan.intersection ( event2->getConstraints() ); - } - if ( minSpan > maxSpan ) swap ( minSpan, maxSpan ); - - ltrace(200) << "punctualSpan: " << punctualSpan - << " min/max span: [" << DbU::getValueString(minSpan) - << ":" << DbU::getValueString(maxSpan) << "]" - << " long: [" << minSpan - << ":" << maxSpan << "]" << endl; - - vector holes; - for ( size_t itrack=0 ; itrack<_S.getCosts().size() ; itrack++ ) { - size_t begin = _S.getBegin(itrack); - size_t end = _S.getEnd (itrack); - Track* track = _S.getTrack(itrack); - - if ( end < track->getSize() ) end++; - - ltrace(200) << "Looking for holes in " << _S.getCost(itrack) << endl; - - TrackElement* otherPrevious = NULL; - // ToDo: Manage disjoint but subsequent segment of a Net. - // (currently, that hole will not be found). - for ( ; begin < end ; begin++ ) { - TrackElement* otherSegment = track->getSegment(begin); - if ( otherSegment->getNet() == _segment->getNet() ) continue; - if ( !otherPrevious ) { - holes.push_back ( Interval(track->getMin() - ,otherSegment->getSourceU()) ); - ltrace(200) << "| First hole: " << holes.back() << " " << otherSegment << endl; - } else { - if ( otherSegment->getNet() == otherPrevious->getNet() ) continue; - - holes.push_back ( Interval(otherPrevious->getTargetU() - ,otherSegment ->getSourceU()) ); - ltrace(200) << "| Found hole: " << holes.back() - << " " << otherPrevious << " <-> " << " " << otherSegment << endl; - } - otherPrevious = otherSegment; - } - } - - if ( holes.empty() ) { - ltrace(200) << "No holes found to minimize into." << endl; - return false; - } - - Interval currentSpan = _segment->getCanonicalInterval(); - Interval biggestHole; - for ( size_t i=0 ; i currentSpan.getIntersection(biggestHole).getSize() ) - biggestHole = holes[i]; - } - - DbU::Unit axisHint = 0; - if ( not punctualSpan.isEmpty() ) { - bool success = false; - - if ( biggestHole.intersect(punctualSpan) ) { - ltrace(200) << "Go as punctual into biggest hole: " << biggestHole << endl; - axisHint = biggestHole.intersection(punctualSpan).getCenter(); - success = true; - } else { - for ( size_t i=0 ; igetDataNegociate(); - if ( !data2 ) continue; - - ltrace(200) << " | " << perpandiculars[i] << endl; - - RoutingEvent* event2 = data2->getRoutingEvent(); - if ( !event2 ) continue; - - _S.addAction ( perpandiculars[i], SegmentAction::SelfRipupAndAxisHint, axisHint ); - } - - _event->setMinimized (); - - return true; - } - - - bool Manipulator::relax ( size_t i ) - { - ltrace(200) << "Manipulator::relax() " << _segment << endl; - - if ( /* _segment->base()->isGlobal() - ||*/ _segment->isFixed() - || ( _segment->getDogLegLevel() > 0 ) - || ( _segment->getLength() < DbU::lambda(10.0) ) - || not _segment->canDogLegAt(_segment->base()->getAutoSource()->getGCell()) ) - return false; - - TrackElement* perpandicular - = _segment->makeDogLeg ( Session::lookup(_segment->base()->getAutoSource()->getGCell()) ); - - if ( perpandicular ) { - RoutingEvent* event = perpandicular->getDataNegociate()->getRoutingEvent(); - if ( event ) { - TrackCost& cost = _S.getCost(i); - Interval optimal = cost.getInterval(); - event->setOptimalAxis ( optimal.inflate( - Session::getExtensionCap() ) ); - } else { - cerr << Bug("New dog leg without active RoutingEvent.\n " - "%s",getString(perpandicular).c_str()) << endl; - } - } - - return true; - } - - - void Manipulator::reprocessPerpandiculars () - { - if ( _event->getAxisHistory() == _event->getAxisHint() ) return; - - bool moveLeft = (_event->getAxisHistory() > _event->getAxisHint()); - - const vector& perpandiculars = _event->getPerpandiculars(); - for ( size_t iperpand=0 ; iperpandgetDataNegociate(); - - if ( perpandicular->isFixed() ) continue; - if ( not data ) continue; - if ( not perpandicular->getTrack() ) continue; - if ( not Manipulator(perpandicular,_S).canRipup() - or (data->getState() >= DataNegociate::MaximumSlack) ) continue; - - // Ugly: ExtensionCap usage. - if ( moveLeft ) { - if ( perpandicular->getTargetU()-Session::getExtensionCap() == _event->getAxisHistory() ) - _S.addAction ( perpandicular, SegmentAction::OtherPacking ); - } else { - if ( perpandicular->getSourceU()+Session::getExtensionCap() == _event->getAxisHistory() ) - _S.addAction ( perpandicular, SegmentAction::OtherPacking ); - } - } - } - - - void Manipulator::repackPerpandiculars ( bool ripInserted ) - { - ltrace(200) << "Manipulator::repackPerpandiculars()" << endl; - - const vector& perpandiculars = _event->getPerpandiculars(); - for ( size_t iperpand=0 ; iperpandgetDataNegociate(); - - if ( perpandicular->isFixed () ) continue; - if ( perpandicular->isGlobal() ) continue; - if ( not data ) continue; - - if ( RoutingEvent::getStage() == RoutingEvent::Repair ) { - if (data->getTrack() and not ripInserted) continue; - - data->setState ( DataNegociate::Repair ); - if (data->getStateCount() > 1) - data->resetStateCount(); - } - _S.addAction ( perpandicular, SegmentAction::SelfRipupPerpand ); - } - _S.addAction ( _segment, SegmentAction::SelfRipup|SegmentAction::EventLevel4 ); - } - - -// ------------------------------------------------------------------- -// Local Functions. - - -} // End of anonymous namespace. +#include +#include +#include +#include +#include "vlsisapd/configuration/Configuration.h" +#include "hurricane/Bug.h" +#include "hurricane/DebugSession.h" +#include "hurricane/Breakpoint.h" +#include "hurricane/Net.h" +#include "hurricane/Layer.h" +#include "katabatic/AutoContact.h" +#include "kite/DataNegociate.h" +#include "kite/TrackSegment.h" +#include "kite/Track.h" +#include "kite/Tracks.h" +#include "kite/RoutingPlane.h" +#include "kite/RoutingEvent.h" +#include "kite/RoutingEventHistory.h" +#include "kite/RoutingEventQueue.h" +#include "kite/RoutingEventLoop.h" +#include "kite/NegociateWindow.h" +#include "kite/Session.h" +#include "kite/KiteEngine.h" +#include "kite/Manipulator.h" +#include "kite/SegmentFsm.h" namespace Kite { - using std::cerr; using std::endl; using std::setw; using std::min; + using std::ostringstream; using Hurricane::tab; using Hurricane::inltrace; using Hurricane::ltracein; using Hurricane::ltraceout; using Hurricane::DebugSession; using Hurricane::Bug; + using Hurricane::Error; using Hurricane::ForEachIterator; using Hurricane::Net; using Hurricane::Layer; using Katabatic::GCell; + using Katabatic::KbPropagate; // ------------------------------------------------------------------- @@ -3514,35 +69,8 @@ namespace Kite { bool RoutingEvent::Compare::operator() ( const RoutingEvent* lhs, const RoutingEvent* rhs ) const { - //if ( !lhs->isValid() ) const_cast(lhs)->revalidate (); - //if ( !rhs->isValid() ) const_cast(rhs)->revalidate (); - - //unsigned int lhsDepth = Session::getRoutingGauge()->getLayerDepth(lhs->getSegment()->getLayer()); - //unsigned int rhsDepth = Session::getRoutingGauge()->getLayerDepth(rhs->getSegment()->getLayer()); - - //if ( lhsDepth > rhsDepth ) return true; - //if ( lhsDepth < rhsDepth ) return false; - - if ( lhs == rhs ) return false; - - return RoutingEvent::Key::Compare() ( lhs->getKey(), rhs->getKey() ); - - // if ( lhs->getEventLevel() < rhs->getEventLevel() ) return true; - // if ( lhs->getEventLevel() > rhs->getEventLevel() ) return false; - - // // Uses static ordering. - // if ( lhs->getTracksNb() < rhs->getTracksNb() ) return false; - // if ( lhs->getTracksNb() > rhs->getTracksNb() ) return true; - - // if ( lhs->getPriority() < rhs->getPriority() ) return false; - // if ( lhs->getPriority() > rhs->getPriority() ) return true; - - // //return false; - // // For debugging purpose only: ensure a reproductible sort. Could be removed. - // //bool segmentCompare = TrackElement::CompareByPosition() ( lhs->getSegment(), rhs->getSegment() ); - - // //return (segmentCompare or ((void*)lhs < (void*)rhs)); - // return ((void*)lhs < (void*)rhs); + if (lhs == rhs) return false; + return RoutingEvent::Key::Compare()( lhs->getKey(), rhs->getKey() ); } @@ -3552,33 +80,29 @@ namespace Kite { bool RoutingEvent::Key::Compare::operator() ( const RoutingEvent::Key& lhs, const RoutingEvent::Key& rhs ) const { - //if ( lhs._ring xor rhs._ring ) return lhs._ring; + if (lhs._eventLevel > rhs._eventLevel) return false; + if (lhs._eventLevel < rhs._eventLevel) return true; - if ( lhs._eventLevel > rhs._eventLevel ) return false; - if ( lhs._eventLevel < rhs._eventLevel ) return true; + // Process all M2 (terminal access) before any others. + if ((lhs._layerDepth == 1) and (rhs._layerDepth != 1)) return false; + if ((lhs._layerDepth != 1) and (rhs._layerDepth == 1)) return true; - if ( lhs._canRipple xor rhs._canRipple ) return rhs._canRipple; - //if ( lhs._slackenStrap xor rhs._slackenStrap ) return lhs._slackenStrap; + if (lhs._priority > rhs._priority) return false; + if (lhs._priority < rhs._priority) return true; - // Uses static ordering. - //if ( lhs._tracksNb > rhs._tracksNb ) return true; - //if ( lhs._tracksNb < rhs._tracksNb ) return false; + if (lhs._length > rhs._length) return false; + if (lhs._length < rhs._length) return true; - if ( lhs._priority > rhs._priority ) return false; - if ( lhs._priority < rhs._priority ) return true; + if ((lhs._segFlags & KbHorizontal) xor (rhs._segFlags & KbHorizontal)) + return (rhs._segFlags & KbHorizontal); - if ( lhs._length > rhs._length ) return false; - if ( lhs._length < rhs._length ) return true; + if (lhs._axis > rhs._axis) return true; + if (lhs._axis < rhs._axis) return false; - if ( lhs._isHorizontal xor rhs._isHorizontal ) return rhs._isHorizontal; + if (lhs._sourceU > rhs._sourceU) return true; + if (lhs._sourceU < rhs._sourceU) return false; - if ( lhs._axis > rhs._axis ) return true; - if ( lhs._axis < rhs._axis ) return false; - - if ( lhs._sourceU > rhs._sourceU ) return true; - if ( lhs._sourceU < rhs._sourceU ) return false; - - if ( lhs._net->getName() != rhs._net->getName() ) + if (lhs._net->getName() != rhs._net->getName()) return lhs._net->getName() < rhs._net->getName(); return lhs._id < rhs._id; @@ -3586,12 +110,11 @@ namespace Kite { RoutingEvent::Key::Key ( const RoutingEvent* event ) - : _slackenStrap(event->getSegment()->isSlackenStrap()) - , _isHorizontal(event->getSegment()->isHorizontal()) - , _canRipple (event->getSegment()->canRipple()) - , _tracksNb (event->getTracksNb()) + : _tracksNb (event->getTracksNb()) , _priority (event->getPriority()) , _eventLevel (event->getEventLevel()) + , _segFlags (event->getSegment()->base()->getFlags()) + , _layerDepth (Session::getRoutingGauge()->getLayerDepth(event->getSegment()->getLayer())) , _length (event->getSegment()->getLength()) , _axis (event->getSegment()->getAxis()) , _sourceU (event->getSegment()->getSourceU()) @@ -3602,13 +125,13 @@ namespace Kite { void RoutingEvent::Key::update ( const RoutingEvent* event ) { - if ( !event ) return; + if (not event) return; - _slackenStrap = event->getSegment()->isSlackenStrap(); - _canRipple = event->getSegment()->canRipple(); _tracksNb = event->getTracksNb(); _priority = event->getPriority(); _eventLevel = event->getEventLevel(); + _segFlags = event->getSegment()->base()->getFlags(); + _layerDepth = Session::getRoutingGauge()->getLayerDepth(event->getSegment()->getLayer()); _length = event->getSegment()->getLength(); _axis = event->getSegment()->getAxis(); _sourceU = event->getSegment()->getSourceU(); @@ -3620,6 +143,7 @@ namespace Kite { // Class : "RoutingEvent". + unsigned int RoutingEvent::_idCounter = 0; unsigned int RoutingEvent::_stage = RoutingEvent::Negociate; size_t RoutingEvent::_allocateds = 0; size_t RoutingEvent::_processeds = 0; @@ -3638,21 +162,17 @@ namespace Kite { : _cloned (false) , _processed (false) , _disabled (false) - , _valid (false) - , _validConstraints (false) - , _validPerpandiculars (false) , _canHandleConstraints(false) , _minimized (false) , _forceToHint (false) , _ripedByLocal (false) + , _id (_idCounter++) , _segment (segment) + , _dataNegociate (segment->getDataNegociate()) , _axisHistory (segment->getAxis()) , _axisHint (segment->getAxis()) - , _optimalAxis (false) , _constraints () , _optimal () - , _perpandicular (false) - , _shearGCell (NULL) , _tracksNb (0) , _tracksFree (0) , _insertState (0) @@ -3660,26 +180,22 @@ namespace Kite { , _rippleState (0) , _eventLevel (0) , _priority (0.0) - , _perpandiculars () , _key (this) { + if (_idCounter == std::numeric_limits::max()) { + throw Error( "RoutingEvent::RoutingEvent(): Identifier counter has reached it's limit (%d bits)." + , std::numeric_limits::digits ); + } + DataNegociate* data = _segment->getDataNegociate(); - if ( data ) - data->setRoutingEvent ( this ); + if (data) data->setRoutingEvent( this ); - // Interval optimal; - // _segment->base()->getOptimal ( optimal ); - // _axisHint = optimal.getCenter(); - - invalidate ( true ); - - ltrace(180) << "create: " << (void*)this << ":" << this << endl; + ltrace(180) << "create: " << this << endl; ltrace(200) << "Initial setAxisHint @" << DbU::getValueString(getAxisHint()) << endl; - if ( _segment->getTrack() ) { - cerr << Bug("RoutingEvent::create() - TrackElement is already inserted in a Track." - "\n %s." - ,getString(_segment).c_str() + if (_segment->getTrack()) { + cerr << Bug( "RoutingEvent::create() - TrackElement is already inserted in a Track." + "\n %s.", getString(_segment).c_str() ) << endl; } } @@ -3687,6 +203,12 @@ namespace Kite { RoutingEvent* RoutingEvent::create ( TrackElement* segment, unsigned int mode ) { + // if (not dynamic_cast(segment)) { + // cerr << Error( "RoutingEvent::create() Can only create event from TrackSegment:\n" + // " %s", getString(segment).c_str() + // ) << endl; + // } + RoutingEvent* event = new RoutingEvent ( segment, mode ); ++_allocateds; @@ -3706,8 +228,8 @@ namespace Kite { clone->_disabled = false; clone->_eventLevel = 0; - ltrace(200) << "RoutingEvent::clone() " << (void*)clone << ":" << clone - << " (from: " << (void*)this << ")" << endl; + ltrace(200) << "RoutingEvent::clone() " << clone + << " (from: " << ")" << endl; return clone; } @@ -3715,18 +237,18 @@ namespace Kite { RoutingEvent::~RoutingEvent () { - ltrace(180) << "~RoutingEvent() " << (void*)this << endl; + ltrace(180) << "~RoutingEvent() " << endl; DataNegociate* data = _segment->getDataNegociate(); - if ( data and ( data->getRoutingEvent() == this ) ) - data->setRoutingEvent ( NULL ); + if ( data and (data->getRoutingEvent() == this) ) + data->setRoutingEvent( NULL ); } void RoutingEvent::destroy () { - ltrace(180) << "RoutingEvent::destroy() " << (void*)this << ":" << this << endl; - if ( _allocateds > 0 ) --_allocateds; + ltrace(180) << "RoutingEvent::destroy() " << this << endl; + if (_allocateds > 0) --_allocateds; delete this; } @@ -3737,37 +259,23 @@ namespace Kite { void RoutingEvent::setMode ( unsigned int mode ) - { - _mode = mode; - // if ( _mode == Repair ) { - // DataNegociate* data = _segment->getDataNegociate(); - // if ( data ) data->setState ( DataNegociate::Repair, true ); - // } - } + { _mode = mode; } unsigned int RoutingEvent::getState () const { DataNegociate* data = _segment->getDataNegociate(); - if ( not data ) return 0; - - return data->getState(); + return (data) ? data->getState() : 0; } void RoutingEvent::setState ( unsigned int state ) { DataNegociate* data = _segment->getDataNegociate(); - if ( not data ) return; - - data->setState ( state ); + if (data) data->setState( state ); } - void RoutingEvent::setEventLevel ( unsigned int level ) - { _eventLevel = level; } - - void RoutingEvent::setAxisHint ( DbU::Unit axis ) { ltrace(200) << "setAxisHint @" << DbU::getValueString(axis) << " " << _segment << endl; @@ -3775,27 +283,26 @@ namespace Kite { } - void RoutingEvent::cacheAxisHint () + void RoutingEvent::setAxisHintFromParent () { - if ( getStage() == Repair ) return; + if (getStage() == Repair) return; TrackElement* parent = _segment->getParent(); - if ( not parent ) return; + if (not parent) return; RoutingEvent* parentEvent = parent->getDataNegociate()->getRoutingEvent(); - if ( parentEvent == this ) { - cbug << Error("RoutingEvent::getAxisHint(): Parentage loop between\n" - " this :%p:%s\n parent:%p:%s" - ,_segment->base(),getString(_segment->base()).c_str() - ,parent ->base(),getString(parent ->base()).c_str() + if (parentEvent == this) { + cbug << Error( "RoutingEvent::setAxisHintFromParent(): Parentage loop between\n" + " this :%p:%s\n parent:%p:%s" + , _segment->base(),getString(_segment->base()).c_str() + , parent ->base(),getString(parent ->base()).c_str() ) << endl; _axisHint = parent->getAxis(); return; } - //_axisHint = (parentEvent) ? parentEvent->getAxisHint() : parent->getAxis (); - _axisHint = parent->getAxis (); + _axisHint = parent->getAxis(); - ltrace(200) << "cacheAxisHint() - hint:" << DbU::getValueString(_axisHint) + ltrace(200) << "setAxisHintFromParent() - hint:" << DbU::getValueString(_axisHint) << " axis:" << DbU::getValueString(parent->getAxis()) << " parent:" << parent << endl; return; } @@ -3804,41 +311,40 @@ namespace Kite { RoutingEvent* RoutingEvent::reschedule ( RoutingEventQueue& queue, unsigned int eventLevel ) { RoutingEvent* active = _segment->getDataNegociate()->getRoutingEvent(); - if ( active != this ) - return active->reschedule ( queue, eventLevel ); + if (active != this) return active->reschedule( queue, eventLevel ); RoutingEvent* fork = NULL; if ( (getStage() != Repair) and isUnimplemented() ) { ltrace(200) << "Reschedule: cancelled (Unimplemented) " - << (void*)this << " -> " << (void*)fork << ":" << fork << endl; + << " -> " << fork << endl; return NULL; } - if ( not isProcessed() ) { + if (not isProcessed()) { fork = this; ltrace(200) << "Reschedule/Self: " - << (void*)this << " -> " - << (void*)fork << ":" << eventLevel << ":" << fork << endl; + << " -> " + << eventLevel << ":" << fork << endl; } else { fork = clone(); fork->_processed = false; - _segment->getDataNegociate()->setRoutingEvent ( fork ); + _segment->getDataNegociate()->setRoutingEvent( fork ); ltrace(200) << "Reschedule/Fork: " - << (void*)this << " -> " << (void*)fork << ":" << fork << endl; + << " -> " << fork << endl; } - if ( fork->_eventLevel < eventLevel ) + if (fork->_eventLevel < eventLevel) fork->_eventLevel = eventLevel; - if ( getStage() == Repair ) { - fork->setMode ( RoutingEvent::Repair ); - _segment->getDataNegociate()->setState ( DataNegociate::Repair ); + if (getStage() == Repair) { + fork->setMode( RoutingEvent::Repair ); + _segment->getDataNegociate()->setState( DataNegociate::Repair ); } - queue.repush ( fork ); + queue.repush( fork ); return fork; } @@ -3846,12 +352,9 @@ namespace Kite { void RoutingEvent::setSegment ( TrackElement* segment ) { - if ( _segment ) - _segment->getDataNegociate()->setRoutingEvent ( NULL ); + if (_segment) _segment->getDataNegociate()->setRoutingEvent( NULL ); _segment = segment; - _segment->getDataNegociate()->setRoutingEvent ( this ); - - invalidate ( true, true ); + _segment->getDataNegociate()->setRoutingEvent( this ); } @@ -3860,30 +363,14 @@ namespace Kite { , RoutingEventLoop& loop ) { - loop.update ( _segment->getId() ); - if ( loop.isLooping() ) { - if ( ltracelevel() > 200 ) { - - cbug << Error("Loop detected: %s.\n Enabling trace (level:200)" - ,_getString().c_str()) << endl; - //ltracelevel ( 200 ); - //Cfg::getParamInt("misc.traceLevel")->setInt ( 200, Cfg::Parameter::CommandLine ); - - //const vector& elements = loop.getElements(); - //for ( size_t i=0 ; igetId() ); + if (loop.isLooping()) { + loop.erase( _segment->getId() ); + setState( DataNegociate::Unimplemented ); #if LOOP_DEBUG - if ( loop.getMaxCount() > 500 ) { + if (loop.getMaxCount() > 500) { cbug << Error("Loop detected, removing event %s.",_getString().c_str()) << endl; - //Cfg::getParamInt("misc.traceLevel")->setInt ( 1000, Cfg::Parameter::CommandLine ); - //ltracelevel ( 1000 ); - - loop.erase ( _segment->getId() ); - setState ( DataNegociate::Unimplemented ); ostringstream message; message << "Kite has detected a loop between the following Segments:\n"; @@ -3895,12 +382,9 @@ namespace Kite { } message << ""; - throw Error(message.str().c_str()); + throw Error( message.str().c_str() ); } #else - loop.erase ( _segment->getId() ); - setState ( DataNegociate::Unimplemented ); - ostringstream message; message << "[BUG] Kite has detected a loop between the following Segments:"; @@ -3912,64 +396,56 @@ namespace Kite { #endif } - DebugSession::open ( _segment->getNet(), 190 ); + DebugSession::open( _segment->getNet(), 148 ); -#if defined(CHECK_DETERMINISM) - cerr << "Order: " - << getProcesseds() - << "," << getEventLevel() - << "," << setw(6) << getPriority() - << " " << setw(6) << DbU::getValueString(_segment->getLength()) - << " " << _segment->isHorizontal() - << " " << setw(6) << DbU::getValueString(_segment->getAxis()) - << " " << setw(6) << DbU::getValueString(_segment->getSourceU()) - << ": " << _segment << endl; -#endif + ltrace(500) << "Deter| Event" + << getProcesseds() + << "," << getEventLevel() + << "," << setw(6) << getPriority() + << ": " << _segment << endl; _processeds++; - ltrace(210) << "Event:" << _processeds << " " << this << endl; ltracein(200); ltrace(200) << "State: *before* " << DataNegociate::getStateString(_segment->getDataNegociate()) << " ripup:" << _segment->getDataNegociate()->getRipupCount() << endl; ltrace(149) << "Level: " << getEventLevel() - << ", area: " << _segment->getArea() << endl; + << ", area: " << _segment->getFreedomDegree() << endl; - _preCheck(_segment); + _preCheck( _segment ); _eventLevel = 0; - history.push ( this ); + history.push( this ); if ( isProcessed() or isDisabled() ) { ltrace(200) << "Already processed or disabled." << endl; } else { - setProcessed (); + setProcessed(); switch ( _mode ) { - case Negociate: _processNegociate ( queue, history ); break; - case Pack: _processPack ( queue, history ); break; - case Repair: _processRepair ( queue, history ); break; + case Negociate: _processNegociate( queue, history ); break; + case Pack: _processPack ( queue, history ); break; + case Repair: _processRepair ( queue, history ); break; default: - cerr << Bug("RoutingEvent::process() - Unknown mode value:%d.",_mode) << endl; + cerr << Bug( "RoutingEvent::process() - Unknown mode value:%d.", _mode ) << endl; break; } } - -#if defined(CHECK_DATABASE) - Session::getKiteEngine()->_check ( _segment->getNet() ); -#endif ltraceout(200); - queue.repushInvalidateds (); - Session::revalidate (); - queue.commit (); + queue.repushInvalidateds(); + Session::revalidate(); + queue.commit(); - _postCheck(_segment); - DebugSession::close (); + //_postCheck( _segment ); +#if defined(CHECK_DATABASE) + Session::getKiteEngine()->_check( _segment->getNet() ); +#endif + DebugSession::close(); - if ( Session::getKiteEngine()->getPostEventCb() != NULL ) - Session::getKiteEngine()->getPostEventCb() (); + if (Session::getKiteEngine()->getPostEventCb() != NULL) + Session::getKiteEngine()->getPostEventCb()(); } @@ -3977,87 +453,65 @@ namespace Kite { { ltrace(200) << "* Mode:Negociation." << endl; - State S ( this, queue, history ); + SegmentFsm fsm ( this, queue, history ); - if ( S.getState() == State::MissingData ) { + if (fsm.getState() == SegmentFsm::MissingData) { cbug << Error("RoutingEvent::process() - Missing datas.") << endl; return; } ltracein(200); - S.getData()->incRipupCount (); + fsm.getData()->incRipupCount(); size_t itrack = 0; - for ( itrack = 0 ; itrack < S.getCosts().size() ; itrack++ ) - ltrace(200) << "| " << S.getCost(itrack) << endl; + for ( itrack = 0 ; itrack < fsm.getCosts().size() ; itrack++ ) + ltrace(200) << "| " << fsm.getCost(itrack) << endl; itrack = 0; - // if ( isForcedToHint() ) { - // // Try to honor the forced axis hint. - // bool hintFound = false; - // for ( ; itrack < S.getCosts().size() ; itrack++ ) { - // if ( S.getCost(itrack).getTrack()->getAxis() == getAxisHint() ) { - // hintFound = true; - // break; - // } - // } - // if ( not hintFound ) itrack = 0; - // ltrace(200) << "Forcing to hint Track: " << itrack << endl; - // } - - if ( Manipulator(_segment,S).canRipup() ) { - if ( S.getCosts().size() and S.getCost(itrack).isFree() ) { - // Track is free: insertion. + if (Manipulator(_segment,fsm).canRipup()) { + if (fsm.getCosts().size() and fsm.getCost(itrack).isFree()) { ltrace(200) << "Insert in free space " << this << endl; - resetInsertState (); + resetInsertState(); _axisHistory = _segment->getAxis(); _eventLevel = 0; - Session::addInsertEvent ( _segment, S.getCost(itrack).getTrack() ); - //Manipulator(_segment,S).reprocessPerpandiculars (); - S.setState ( State::SelfInserted ); - - // if ( _segment->isLocal() - // and _segment->isTerminal() - // and ( S.getData()->getState() >= DataNegociate::MoveUp ) ) { - // ltrace(200) << "Last chance: fixing " << _segment << endl; - // _segment->base()->setFixed ( true ); - // } + ltrace(500) << "Deter| addInsertEvent()" << endl; + ltrace(500) << "Deter| | " << _segment << endl; + ltrace(500) << "Deter| | " << fsm.getCost(itrack).getTrack() << endl; + Session::addInsertEvent( _segment, fsm.getCost(itrack).getTrack() ); + fsm.setState( SegmentFsm::SelfInserted ); } else { // Do ripup. - if ( S.getState() == State::EmptyTrackList ) { - Manipulator(_segment,S).ripupPerpandiculars (); + if (fsm.getState() == SegmentFsm::EmptyTrackList) { + Manipulator(_segment,fsm).ripupPerpandiculars(); } else { - if ( Manipulator(_segment,S).canRipup(Manipulator::HasNextRipup)) { - for ( itrack=0 ; itrackgetAxis()) - << " " << (void*)this << ":" << this << endl; + if (itrack < fsm.getCosts().size()) { + ltrace(200) << "Placed: @" << DbU::getValueString(fsm.getCost(itrack).getTrack()->getAxis()) + << " " << this << endl; } ltraceout(200); @@ -4068,33 +522,29 @@ namespace Kite { { ltrace(200) << "* Mode:Pack." << endl; - if ( _segment->getTrack() != NULL ) { + if (_segment->getTrack() != NULL) { ltrace(200) << "* Cancel: already in Track." << endl; return; } - // if ( !_canHandleConstraints ) { - // ltrace(200) << "* Cancel: cannot handle constraints." << endl; - // return; - // } - State S ( this, queue, history ); - if ( S.getState() == State::MissingData ) return; - if ( S.getState() == State::EmptyTrackList ) return; + SegmentFsm fsm ( this, queue, history ); + if (fsm.getState() == SegmentFsm::MissingData ) return; + if (fsm.getState() == SegmentFsm::EmptyTrackList) return; ltracein(200); - for ( size_t i = 0 ; i < S.getCosts().size() ; i++ ) - ltrace(200) << "| " << S.getCost(i) << endl; + for ( size_t i = 0 ; i < fsm.getCosts().size() ; i++ ) + ltrace(200) << "| " << fsm.getCost(i) << endl; ltraceout(200); - if ( S.getCosts().size() and S.getCost(0).isFree() ) { + if (fsm.getCosts().size() and fsm.getCost(0).isFree()) { ltrace(200) << "Insert in free space." << endl; - Session::addInsertEvent ( _segment, S.getCost(0).getTrack() ); - S.setState ( State::SelfInserted ); + Session::addInsertEvent( _segment, fsm.getCost(0).getTrack() ); + fsm.setState( SegmentFsm::SelfInserted ); } else { ltrace(200) << "Pack failed." << endl; _mode = Negociate; - S.addAction ( _segment, SegmentAction::SelfInsert ); - S.doActions (); + fsm.addAction( _segment, SegmentAction::SelfInsert ); + fsm.doActions(); } } @@ -4107,44 +557,35 @@ namespace Kite { ltrace(200) << "* Cancel: already in Track." << endl; return; } - // if ( !_canHandleConstraints ) { - // ltrace(200) << "* Cancel: cannot handle constraints." << endl; - // return; - // } - State S ( this, queue, history ); - if ( S.getState() == State::MissingData ) return; - if ( S.getState() == State::EmptyTrackList ) return; + SegmentFsm fsm ( this, queue, history ); + if (fsm.getState() == SegmentFsm::MissingData ) return; + if (fsm.getState() == SegmentFsm::EmptyTrackList) return; ltracein(200); - for ( size_t i = 0 ; i < S.getCosts().size() ; i++ ) - ltrace(200) << "| " << S.getCost(i) << endl; + for ( size_t i = 0 ; i < fsm.getCosts().size() ; i++ ) + ltrace(200) << "| " << fsm.getCost(i) << endl; ltraceout(200); - if ( S.getCosts().size() and S.getCost(0).isFree() ) { + if (fsm.getCosts().size() and fsm.getCost(0).isFree()) { ltrace(200) << "Insert in free space." << endl; - Session::addInsertEvent ( _segment, S.getCost(0).getTrack() ); - S.setState ( State::SelfInserted ); - //Manipulator(_segment,S).repackPerpandiculars (false); - //S.doActions (); - //queue.commit (); + Session::addInsertEvent( _segment, fsm.getCost(0).getTrack() ); + fsm.setState( SegmentFsm::SelfInserted ); } else { - switch ( S.getData()->getStateCount() ) { + switch ( fsm.getData()->getStateCount() ) { case 1: // First try: minimize. - //S.getData()->setState ( DataNegociate::Repair ); - Manipulator(_segment,S).minimize (); - S.addAction ( _segment, SegmentAction::SelfInsert ); - S.doActions (); - queue.commit (); + Manipulator(_segment,fsm).minimize (); + fsm.addAction( _segment, SegmentAction::SelfInsert ); + fsm.doActions(); + queue.commit(); break; case 2: // Second try: failed re-inserted first. - //S.getData()->setState ( DataNegociate::Repair ); - Manipulator(_segment,S).repackPerpandiculars (); - S.addAction ( _segment, SegmentAction::SelfInsert ); - S.doActions (); - queue.commit (); + Manipulator(_segment,fsm).repackPerpandiculars (); + fsm.addAction( _segment, SegmentAction::SelfInsert ); + fsm.doActions(); + queue.commit(); break; default: ltrace(200) << "Repair failed." << endl; @@ -4154,120 +595,70 @@ namespace Kite { } - void RoutingEvent::revalidate ( bool force ) + void RoutingEvent::revalidate () { - if ( _valid and not force ) return; + DebugSession::open( _segment->getNet(), 148 ); - DebugSession::open ( _segment->getNet(), 148 ); - - ltrace(200) << "RoutingEvent::revalidate() - " << (void*)this << ":" << this << endl; + ltrace(200) << "RoutingEvent::revalidate() - " << this << endl; ltracein(200); - cacheAxisHint (); + //_dataNegociate->update(); + + setAxisHintFromParent(); ltrace(200) << "axisHint:" << DbU::getValueString(getAxisHint()) << endl; _canHandleConstraints = true; - if ( /*!_validConstraints*/ true ) { - _segment->base()->getConstraints ( _constraints ); - _segment->base()->getOptimal ( _optimal ); + _segment->base()->getConstraints( _constraints ); + _segment->base()->getOptimal ( _optimal ); - ltrace(200) << "Stage:" << RoutingEvent::getStage() << endl; - if ( RoutingEvent::getStage() == RoutingEvent::Repair ) { - if (_segment->isTerminal()) { - ltrace(200) << "Not expanding on Terminals:" << _constraints << endl; - } else { - ltrace(200) << "Expanding:" << _constraints << endl; - // Ugly: direct uses of Cell Gauge. - _constraints.inflate ( DbU::lambda(50.0) ); - ltrace(200) << "Expanding (after):" << _constraints << endl; - } - } - // else if ( _segment->isDogleg() - // and (_segment->getDataNegociate()->getState() >= DataNegociate::MaximumSlack) ) { - // _constraints.inflate ( DbU::lambda(25.0) ); - // } - - ltrace(200) << "| Raw Track Constraint: " << _constraints << endl; - - _validConstraints = true; - } - - if ( not _validPerpandiculars ) { - TrackElement* perpandicular; - Interval canonical; - - _perpandiculars.clear (); - forEach ( AutoSegment*, isegment, _segment->base()->getCollapsedPerpandiculars() ) { - ltrace(200) << "| perpandicular " << *isegment << endl; - perpandicular = Session::lookup ( isegment->getCanonical(canonical)->base() ); - if ( !perpandicular ) continue; - - _perpandiculars.push_back ( perpandicular ); - } - _validPerpandiculars = true; - - if ( not _segment->isTerminal() and (_perpandiculars.size() < 2) ) - cerr << Bug("Less than two perpandiculars on %s.",getString(_segment).c_str()) << endl; - } - - ltrace(200) << "| Track Constraint: " << _constraints << endl; - - _perpandicular = _constraints; - DataNegociate* dataPerpandicular; - - for ( size_t i=0 ; i<_perpandiculars.size() ; i++ ) { - dataPerpandicular = _perpandiculars[i]->getDataNegociate(); - if ( !dataPerpandicular ) { - ltrace(200) << "| No data " << _perpandiculars[i] << endl; - continue; - } - - if ( _perpandiculars[i]->getTrack() ) { - Interval trackFree = _perpandiculars[i]->getFreeInterval(); - ltrace(200) << "| From " << _perpandiculars[i] << endl; - ltrace(200) << "| Track Perpandicular Free: " << trackFree << endl; - - _perpandicular.intersection ( trackFree ); + ltrace(200) << "Stage:" << RoutingEvent::getStage() << endl; + if (RoutingEvent::getStage() == RoutingEvent::Repair) { + if (_segment->isStrongTerminal(KbPropagate)) { + ltrace(200) << "Not expanding on Terminals:" << _constraints << endl; } else { - ltrace(200) << "| Not in any track " << _perpandiculars[i] << endl; + ltrace(200) << "Expanding:" << _constraints << endl; + // Ugly: direct uses of Cell Gauge. + _constraints.inflate( DbU::lambda(50.0) ); + ltrace(200) << "Expanding (after):" << _constraints << endl; } } + ltrace(200) << "| Raw Track Constraint: " << _constraints << endl; + _tracksNb = 0; - ltrace(200) << "| Perpandicular Free: " << _perpandicular << endl; - if ( not _perpandicular.isEmpty() ) { - RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(_segment->getLayer()); - Track* track = plane->getTrackByPosition(_perpandicular.getVMin()); + Interval perpandicular = _constraints; + perpandicular.intersection( getPerpandicularFree()); + ltrace(200) << "| Perpandicular Free: " << perpandicular << endl; - if ( track and (track->getAxis() < _perpandicular.getVMin()) ) track = track->getNext(); - for ( ; track and (track->getAxis() <= _perpandicular.getVMax()) - ; track = track->getNext(), _tracksNb++ ); + if (not perpandicular.isEmpty()) { + RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(_segment->getLayer()); + Track* track = plane->getTrackByPosition(perpandicular.getVMin()); + + if ( track and (track->getAxis() < perpandicular.getVMin()) ) track = track->getNextTrack(); + for ( ; track and (track->getAxis() <= perpandicular.getVMax()) + ; track = track->getNextTrack(), _tracksNb++ ); } - if ( not _tracksNb ) { + if (not _tracksNb) { ltrace(200) << "| Reverting to pure constraints." << endl; RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(_segment->getLayer()); Track* track = plane->getTrackByPosition(_constraints.getVMin()); - if ( track && (track->getAxis() < _constraints.getVMin()) ) track = track->getNext(); + if ( track && (track->getAxis() < _constraints.getVMin()) ) track = track->getNextTrack(); for ( ; track && (track->getAxis() <= _constraints.getVMax()) - ; track = track->getNext(), _tracksNb++ ); + ; track = track->getNextTrack(), _tracksNb++ ); _canHandleConstraints = false; } - if ( not _tracksNb ) { + if (not _tracksNb) { ltrace(200) << "| Pure constraints are too tight." << endl; - //_segment->base()->getConstraints ( _constraints ); _canHandleConstraints = false; } _priority = (DbU::getLambda(_segment->getLength()) + 1.0) * (DbU::getLambda(_segment->base()->getSlack()) + 1.0); - //_priority = (DbU::getLambda(_segment->getLength()) + 1.0) * (float)(_tracksNb+1); - //_priority = (float)_segment->getArea(); - _valid = true; - ltrace(200) << _segment << " has " << _tracksNb << " choices " << _perpandicular << endl; + ltrace(200) << _segment << " has " << _tracksNb << " choices " << perpandicular << endl; ltraceout(200); DebugSession::close(); @@ -4307,4 +698,4 @@ namespace Kite { } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/RoutingEventHistory.cpp b/kite/src/RoutingEventHistory.cpp index d4a3113e..7e2d32ff 100644 --- a/kite/src/RoutingEventHistory.cpp +++ b/kite/src/RoutingEventHistory.cpp @@ -1,15 +1,9 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 | // | | @@ -17,22 +11,17 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./RoutingEventHistory.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#include - -#include "hurricane/Error.h" -#include "kite/RoutingEvent.h" -#include "kite/RoutingEventHistory.h" +#include +#include "hurricane/Error.h" +#include "kite/RoutingEvent.h" +#include "kite/RoutingEventHistory.h" namespace Kite { - using std::cerr; using std::setw; using std::setfill; @@ -113,4 +102,4 @@ namespace Kite { } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/RoutingEventLoop.cpp b/kite/src/RoutingEventLoop.cpp index 8d9d9ba5..bcf95b96 100644 --- a/kite/src/RoutingEventLoop.cpp +++ b/kite/src/RoutingEventLoop.cpp @@ -1,15 +1,9 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 | // | | @@ -17,16 +11,13 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./RoutingEventLoop.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#include -#include -#include "kite/RoutingEvent.h" -#include "kite/RoutingEventLoop.h" +#include +#include +#include "kite/RoutingEvent.h" +#include "kite/RoutingEventLoop.h" namespace Kite { @@ -91,4 +82,4 @@ namespace Kite { } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/RoutingEventQueue.cpp b/kite/src/RoutingEventQueue.cpp index bf9a6535..4cc3ddc6 100644 --- a/kite/src/RoutingEventQueue.cpp +++ b/kite/src/RoutingEventQueue.cpp @@ -1,43 +1,32 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | C O R I O L I S | // | K i t e - D e t a i l e d R o u t e r | // | | // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | -// | C++ Module : "./RoutingEvent.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Module : "./RoutingEventQueue.cpp" | +// +-----------------------------------------------------------------+ -#include -#include -#include -#include - -#include "hurricane/Bug.h" -#include "kite/DataNegociate.h" -#include "kite/TrackElement.h" -#include "kite/RoutingEventQueue.h" -#include "kite/Session.h" +#include +#include +#include +#include +#include "hurricane/Bug.h" +#include "kite/DataNegociate.h" +#include "kite/TrackSegment.h" +#include "kite/RoutingEventQueue.h" +#include "kite/Session.h" namespace Kite { - using std::cerr; using std::endl; using std::setw; @@ -72,39 +61,35 @@ namespace Kite { void RoutingEventQueue::load ( const vector& segments ) { for ( size_t i=0 ; igetDataNegociate()->getRoutingEvent() ) { + if (segments[i]->getDataNegociate()->getRoutingEvent()) { cinfo << "[INFO] Already have a RoutingEvent - " << segments[i] << endl; continue; } - if ( segments[i]->getTrack() ) { + if (segments[i]->getTrack()) { cinfo << "[INFO] Already in Track - " << segments[i] << endl; continue; } RoutingEvent* event = RoutingEvent::create(segments[i]); - event->updateKey (); - _events.insert ( event ); + event->updateKey(); + _events.insert( event ); } } void RoutingEventQueue::add ( TrackElement* segment, unsigned int level ) { - if ( segment->getTrack() ) { + if (segment->getTrack()) { cinfo << "[INFO] Already in Track " << (void*)segment->base()->base() << ":" << segment << endl; return; } RoutingEvent* event = RoutingEvent::create(segment); - event->setEventLevel ( level ); - push ( event ); + event->setEventLevel( level ); + push( event ); } - void RoutingEventQueue::push ( RoutingEvent* event ) - { _pushRequests.insert ( event ); } - - void RoutingEventQueue::commit () { ltrace(200) << "RoutingEventQueue::commit()" << endl; @@ -113,31 +98,25 @@ namespace Kite { size_t addeds = _pushRequests.size(); size_t before = _events.size(); - set::iterator ipushEvent = _pushRequests.begin(); + RoutingEventSet::iterator ipushEvent = _pushRequests.begin(); for ( ; ipushEvent != _pushRequests.end() ; ipushEvent++ ) { - (*ipushEvent)->updateKey (); + (*ipushEvent)->updateKey(); - _topEventLevel = max ( _topEventLevel, (*ipushEvent)->getEventLevel() ); - _events.insert ( (*ipushEvent) ); + _topEventLevel = max( _topEventLevel, (*ipushEvent)->getEventLevel() ); + _events.insert( (*ipushEvent) ); ltrace(200) << "| " << (*ipushEvent) << endl; } - _pushRequests.clear (); + _pushRequests.clear(); #if defined(CHECK_ROUTINGEVENT_QUEUE) - _keyCheck (); + _keyCheck(); #endif size_t after = _events.size(); - if ( after-before != addeds ) { - cerr << Bug("RoutingEventQueue::commit(): less than %d events pusheds (%d)." - ,addeds,(after-before)) << endl; + if (after-before != addeds) { + cerr << Bug( "RoutingEventQueue::commit(): less than %d events pusheds (%d)." + , addeds,(after-before) ) << endl; } - // if ( (RoutingEvent::getProcesseds() > 61246) - // and (RoutingEvent::getProcesseds() < 61256) ) { - // cerr << "RoutingEventQueue::commit()" << endl; - // dump (); - // } - ltraceout(200); } @@ -151,33 +130,20 @@ namespace Kite { _keyCheck (); #endif - if ( !_events.empty() ) { + if (not _events.empty()) { size_t beforeSize = _events.size(); ievent = _events.end(); ievent--; event = (*ievent); - _events.erase ( ievent ); - - // if ( (RoutingEvent::getProcesseds() > 61246) - // and (RoutingEvent::getProcesseds() < 61256) ) { - // cerr << "Popped: " << event << endl; - // dump (); - // } + _events.erase( ievent ); size_t afterSize = _events.size(); - if ( afterSize+1 != beforeSize ) { - cerr << Bug("RoutingEventQueue::pop(): more than one event popped: %d." - ,(beforeSize-afterSize)) << endl; + if (afterSize+1 != beforeSize) { + cerr << Bug( "RoutingEventQueue::pop(): more than one event popped: %d." + , (beforeSize-afterSize) ) << endl; } -// size_t erased = _events.erase ( event ); -// if ( erased != 1 ) { -// cerr << Bug("RoutingEventQueue::pop(): %d events matches key %p.",erased,event) << endl; -// #if defined(CHECK_ROUTINGEVENT_QUEUE) -// _keyCheck (); -// #endif -// } } return event; @@ -192,65 +158,59 @@ namespace Kite { multiset::iterator ievent = _events.find(event); size_t count = _events.count(event); - if ( count > 1 ) { + if (count > 1) { cerr << Bug("RoutingEventQueue::repush(): %d events matches key %p.",count,event) << endl; #if defined(CHECK_ROUTINGEVENT_QUEUE) _keyCheck (); #endif } - if ( ievent != _events.end() ) { - // if ( (RoutingEvent::getProcesseds() > 61246) - // and (RoutingEvent::getProcesseds() < 61256) ) { - // cerr << "Erasing: " << *ievent << endl; - // } - _events.erase ( ievent ); + if (ievent != _events.end()) { + _events.erase( ievent ); } push ( event ); - - // if ( (RoutingEvent::getProcesseds() > 61246) - // and (RoutingEvent::getProcesseds() < 61256) ) { - // cerr << "After repush: " << event << endl; - // dump(); - // } } void RoutingEventQueue::repushInvalidateds () { const vector& invalidateds0 = Session::getInvalidateds(); - set invalidateds1; + TrackSegmentSet invalidateds1; for ( size_t i=0 ; i( Session::lookup(invalidateds0[i]) ); + if (segment) + invalidateds1.insert( segment ); } - set::iterator isegment = invalidateds1.begin(); + TrackSegmentSet::iterator isegment = invalidateds1.begin(); for ( ; isegment != invalidateds1.end() ; isegment++ ) { RoutingEvent* event = (*isegment)->getDataNegociate()->getRoutingEvent(); if ( event and not event->isUnimplemented() and not event->isDisabled () and not event->isProcessed () ) { - repush ( event ); - } else { - // if ( (RoutingEvent::getProcesseds() > 61246) - // and (RoutingEvent::getProcesseds() < 61256) ) { - // cerr << "NOT repushed: " << event << endl; - // } + repush( event ); } } } + void RoutingEventQueue::prepareRepair () + { + multiset::const_iterator ievent = _events.begin (); + for ( ; ievent != _events.end(); ++ievent ) { + (*ievent)->getSegment()->base()->toOptimalAxis(); + } + } + + void RoutingEventQueue::clear () { - if ( not _events.empty() ) { + if (not _events.empty()) { cerr << Bug("RoutingEvent queue is not empty, %d events remains." ,_events.size()) << endl; } - _events.clear (); + _events.clear(); } @@ -316,4 +276,4 @@ namespace Kite { } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/RoutingPlane.cpp b/kite/src/RoutingPlane.cpp index 3a1b4deb..3c45faf0 100644 --- a/kite/src/RoutingPlane.cpp +++ b/kite/src/RoutingPlane.cpp @@ -2,14 +2,9 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 | // | | @@ -17,22 +12,17 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./RoutingPlane.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#include "hurricane/Error.h" -#include "hurricane/Box.h" -#include "hurricane/Cell.h" - -#include "crlcore/RoutingLayerGauge.h" - -#include "kite/HorizontalTrack.h" -#include "kite/VerticalTrack.h" -#include "kite/RoutingPlane.h" -#include "kite/KiteEngine.h" +#include "hurricane/Error.h" +#include "hurricane/Box.h" +#include "hurricane/Cell.h" +#include "crlcore/RoutingLayerGauge.h" +#include "kite/HorizontalTrack.h" +#include "kite/VerticalTrack.h" +#include "kite/RoutingPlane.h" +#include "kite/KiteEngine.h" namespace { @@ -48,7 +38,6 @@ namespace { namespace Kite { - using std::cerr; using std::endl; using Hurricane::tab; @@ -68,8 +57,21 @@ namespace Kite { : _kite (kite) , _layerGauge(kite->getLayerGauge(depth)) , _depth (depth) + , _flags (0) + , _axisMin (0) + , _axisMax (0) + , _trackMin (0) + , _trackMax (0) , _tracks () - { } + { + switch ( _layerGauge->getDirection() ) { + case Constant::Horizontal: _flags |= KbHorizontal; break; + case Constant::Vertical: _flags |= KbVertical; break; + default: + cerr << Error( "RoutingPlane::RoutingPlane() - Unknown plane direction from LayerGauge: %u" + , _layerGauge->getDirection() ) << endl; + } + } RoutingPlane::~RoutingPlane () @@ -82,8 +84,8 @@ namespace Kite { << (void*)this << " " << this << endl; ltracein(90); - for ( size_t index = 0 ; index < _tracks.size() ; index++ ) - _tracks[index]->destroy (); + for ( size_t index=0 ; index<_tracks.size() ; ++index ) + _tracks[index]->destroy(); delete this; @@ -95,40 +97,41 @@ namespace Kite { { RoutingPlane* plane = new RoutingPlane ( kite, depth ); - if ( !plane->_layerGauge ) - throw Error ( badLayerGauge, depth, getString(kite->getRoutingGauge()).c_str() ); + if (not plane->_layerGauge) + throw Error( badLayerGauge, depth, getString(kite->getRoutingGauge()).c_str() ); size_t trackNumber; Box abutmentBox = kite->getCell()->getAbutmentBox(); - if ( plane->getLayerGauge()->getDirection() & Constant::Horizontal ) { - plane->_trackMin = abutmentBox.getXMin () - DbU::lambda (2.0); - plane->_trackMax = abutmentBox.getXMax () + DbU::lambda (2.0); - plane->_axisMin = abutmentBox.getYMin (); - plane->_axisMax = abutmentBox.getYMax (); - trackNumber = plane->computeTracksSize (); + // HARD CODED. + if (plane->getDirection() == KbHorizontal) { + plane->_trackMin = abutmentBox.getXMin() - DbU::lambda(2.0); + plane->_trackMax = abutmentBox.getXMax() + DbU::lambda(2.0); + plane->_axisMin = abutmentBox.getYMin(); + plane->_axisMax = abutmentBox.getYMax(); + trackNumber = plane->computeTracksSize(); } else { - plane->_trackMin = abutmentBox.getYMin () - DbU::lambda (2.0); - plane->_trackMax = abutmentBox.getYMax () + DbU::lambda (2.0); - plane->_axisMin = abutmentBox.getXMin (); - plane->_axisMax = abutmentBox.getXMax (); - trackNumber = plane->computeTracksSize (); + plane->_trackMin = abutmentBox.getYMin() - DbU::lambda(2.0); + plane->_trackMax = abutmentBox.getYMax() + DbU::lambda(2.0); + plane->_axisMin = abutmentBox.getXMin(); + plane->_axisMax = abutmentBox.getXMax(); + trackNumber = plane->computeTracksSize(); } - plane->_tracks.reserve ( trackNumber ); - for ( size_t index = 0 ; index < trackNumber ; index++ ) { - if ( plane->getLayerGauge()->getDirection() & Constant::Horizontal ) { - plane->_tracks.push_back ( HorizontalTrack::create ( plane, index ) ); + plane->_tracks.reserve( trackNumber ); + for ( size_t index=0 ; indexgetDirection() == KbHorizontal) { + plane->_tracks.push_back( HorizontalTrack::create( plane, index ) ); // Ugly: Direct uses of CellGauge (middle tracks 4 & 5 for local use). - if ( depth == 1 ) { - switch ( index % 10 ) { + if (depth == 1) { + switch ( index%10 ) { case 4: case 5: - plane->_tracks.back()->setLocalAssigned ( true ); + plane->_tracks.back()->setLocalAssigned( true ); break; } } } else { - plane->_tracks.push_back ( VerticalTrack::create ( plane, index ) ); + plane->_tracks.push_back( VerticalTrack::create( plane, index ) ); } } @@ -137,30 +140,30 @@ namespace Kite { RoutingPlane* RoutingPlane::getTop () const - { return getKiteEngine()->getRoutingPlaneByIndex ( getDepth()+1 ); } + { return getKiteEngine()->getRoutingPlaneByIndex( getDepth()+1 ); } RoutingPlane* RoutingPlane::getBottom () const { - if ( !getDepth() ) return NULL; - return getKiteEngine()->getRoutingPlaneByIndex ( getDepth()-1 ); + if (not getDepth()) return NULL; + return getKiteEngine()->getRoutingPlaneByIndex( getDepth()-1 ); } Track* RoutingPlane::getTrackByIndex ( size_t index ) const { - if ( index >= getTracksSize() ) return NULL; + if (index >= getTracksSize()) return NULL; return _tracks[index]; } Track* RoutingPlane::getTrackByPosition ( DbU::Unit axis, unsigned int mode ) const { - return getTrackByIndex ( getLayerGauge()->getTrackIndex ( getAxisMin() - , getAxisMax() - , axis - , mode - ) ); + return getTrackByIndex( getLayerGauge()->getTrackIndex( getAxisMin() + , getAxisMax() + , axis + , mode + ) ); } @@ -168,8 +171,8 @@ namespace Kite { { bool coherency = true; - for ( size_t i=0 ; i<_tracks.size() ; i++ ) { - coherency = _tracks[i]->_check(overlaps) and coherency; + for ( size_t i=0 ; i<_tracks.size() ; ++i ) { + coherency = _tracks[i]->check(overlaps) and coherency; } return coherency; @@ -179,7 +182,9 @@ namespace Kite { string RoutingPlane::_getString () const { return "<" + _getTypeName() + " @" - + getString(_depth) + " [" + + getString(_depth) + " " + + getString(getLayer()) + " [ " + + ((getDirection() == KbHorizontal) ? " horizontal [" : " vertical [") + getString(_tracks.size()) + "/" + getString(_tracks.capacity()) + "]>"; @@ -189,17 +194,17 @@ namespace Kite { Record* RoutingPlane::_getRecord () const { Record* record = new Record ( getString(this) ); - record->add ( getSlot ( "_kite" , _kite ) ); - record->add ( getSlot ( "_layerGauge" , _layerGauge ) ); - record->add ( getSlot ( "_depth" , &_depth ) ); - record->add ( DbU::getValueSlot ( "_axisMin" , &_axisMin ) ); - record->add ( DbU::getValueSlot ( "_axisMax" , &_axisMax ) ); - record->add ( DbU::getValueSlot ( "_trackMin" , &_trackMin ) ); - record->add ( DbU::getValueSlot ( "_trackMax" , &_trackMax ) ); - record->add ( getSlot ( "_tracks" , &_tracks ) ); + record->add( getSlot ( "_kite" , _kite ) ); + record->add( getSlot ( "_layerGauge" , _layerGauge ) ); + record->add( getSlot ( "_depth" , &_depth ) ); + record->add( DbU::getValueSlot( "_axisMin" , &_axisMin ) ); + record->add( DbU::getValueSlot( "_axisMax" , &_axisMax ) ); + record->add( DbU::getValueSlot( "_trackMin" , &_trackMin ) ); + record->add( DbU::getValueSlot( "_trackMax" , &_trackMax ) ); + record->add( getSlot ( "_tracks" , &_tracks ) ); return record; } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/SegmentFsm.cpp b/kite/src/SegmentFsm.cpp new file mode 100644 index 00000000..93902fa9 --- /dev/null +++ b/kite/src/SegmentFsm.cpp @@ -0,0 +1,1241 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2013, All Rights Reserved +// +// +-----------------------------------------------------------------+ +// | C O R I O L I S | +// | K i t e - D e t a i l e d R o u t e r | +// | | +// | Author : Jean-Paul CHAPUT | +// | E-mail : Jean-Paul.Chaput@asim.lip6.fr | +// | =============================================================== | +// | C++ Module : "./SegmentFsm.cpp" | +// +-----------------------------------------------------------------+ + + +#include +#include "hurricane/Bug.h" +#include "hurricane/DebugSession.h" +#include "kite/TrackElement.h" +#include "kite/Tracks.h" +#include "kite/RoutingPlane.h" +#include "kite/DataNegociate.h" +#include "kite/RoutingEvent.h" +#include "kite/RoutingEventQueue.h" +#include "kite/RoutingEventHistory.h" +#include "kite/Manipulator.h" +#include "kite/SegmentFsm.h" +#include "kite/KiteEngine.h" + + +namespace { + + using namespace std; + using namespace Hurricane; + using namespace Kite; + + +// ------------------------------------------------------------------- +// Class : "Cs1Candidate". + + class Cs1Candidate { + public: + inline Cs1Candidate ( Track* track=NULL ); + inline Track* getTrack () const; + inline size_t getBegin () const; + inline size_t getEnd () const; + inline size_t getLength () const; + inline Interval getConflict ( size_t ); + inline Interval getLongestConflict () const; + inline DbU::Unit getBreakPos () const; + inline DbU::Unit getConflictLength () const; + inline void setBegin ( size_t ); + inline void setEnd ( size_t ); + inline void addConflict ( const Interval& ); + void consolidate (); + public: + friend inline bool operator< ( const Cs1Candidate&, const Cs1Candidate& ); + private: + Track* _track; + size_t _begin; + size_t _end; + vector _conflicts; + Interval _longestConflict; + DbU::Unit _breakPos; + DbU::Unit _conflictLength; + }; + + + inline Cs1Candidate::Cs1Candidate ( Track* track ) + : _track (track) + , _begin (0) + , _end (0) + , _conflicts () + , _longestConflict() + , _breakPos (0) + , _conflictLength (0) + { } + + inline Track* Cs1Candidate::getTrack () const { return _track; } + inline size_t Cs1Candidate::getBegin () const { return _begin; } + inline size_t Cs1Candidate::getEnd () const { return _end; } + inline size_t Cs1Candidate::getLength () const { return _conflicts.size(); } + inline Interval Cs1Candidate::getLongestConflict () const { return _longestConflict; } + inline DbU::Unit Cs1Candidate::getBreakPos () const { return _breakPos; } + inline void Cs1Candidate::setBegin ( size_t i ) { _begin=i; } + inline void Cs1Candidate::setEnd ( size_t i ) { _end=i; } + + inline void Cs1Candidate::addConflict ( const Interval& conflict ) + { + _conflicts.push_back(conflict); + _conflictLength += conflict.getSize(); + + if (conflict.getSize() > _longestConflict.getSize()) + _longestConflict = conflict; + } + + inline Interval Cs1Candidate::getConflict ( size_t i ) + { + if (i >= _conflicts.size()) return Interval(); + return _conflicts[i]; + } + + inline bool operator< ( const Cs1Candidate& lhs, const Cs1Candidate& rhs ) + { + DbU::Unit delta = lhs._longestConflict.getSize() - rhs._longestConflict.getSize(); + if (delta < 0) return true; + if (delta > 0) return false; + + return lhs._conflictLength < rhs._conflictLength; + } + + + void Cs1Candidate::consolidate () + { + if (_conflicts.size() > 0) { + DbU::Unit halfConflict = 0; + size_t i = 0; + for ( ; i<_conflicts.size()-1 ; ++i ) { + halfConflict += _conflicts[i].getSize(); + if (halfConflict > _conflictLength/2) + break; + } + + // Ugly: hard-coded pitch. + _breakPos = _conflicts[i].getVMin() - DbU::lambda(5.0); + } + } + + +// ------------------------------------------------------------------- +// Class : "UnionItervals". + + class UnionIntervals { + public: + inline UnionIntervals (); + void addInterval ( Interval& ); + inline size_t size () const; + inline bool empty () const; + inline list::const_iterator begin () const; + inline list::const_iterator end () const; + inline DbU::Unit getVMin () const; + inline DbU::Unit getVMax () const; + string _getString (); + private: + list _intervals; + }; + + + inline UnionIntervals::UnionIntervals () : _intervals() { } + inline list::const_iterator UnionIntervals::begin () const { return _intervals.begin(); } + inline list::const_iterator UnionIntervals::end () const { return _intervals.end(); } + inline size_t UnionIntervals::size () const { return _intervals.size(); } + inline bool UnionIntervals::empty () const { return _intervals.empty(); } + inline DbU::Unit UnionIntervals::getVMin () const { return (empty()) ? DbU::Max : (*begin()).getVMin(); } + inline DbU::Unit UnionIntervals::getVMax () const { return (empty()) ? DbU::Min : (*begin()).getVMax(); } + + + void UnionIntervals::addInterval ( Interval& interval ) + { + ltrace(200) << "UnionInterval::addInterval() - " << interval << endl; + + list::iterator iintv = _intervals.begin (); + + bool merged = false; + while ( iintv != _intervals.end() ) { + if (not merged) { + if (interval.getVMax() < (*iintv).getVMin()) { _intervals.insert( iintv, interval ); return; } + if (interval.getVMin() > (*iintv).getVMax()) { ++iintv; continue; } + + merged = true; + interval = (*iintv).merge( interval ); + ++iintv; + } else { + if ((*iintv).intersect( interval )) { + interval = (*iintv).merge( interval ); + iintv = _intervals.erase( iintv ); + continue; + } else + break; + } + } + + if (not merged) _intervals.push_back( interval ); + } + + + string UnionIntervals::_getString () + { + ostringstream s; + + list::iterator iintv = _intervals.begin(); + for ( ; iintv != _intervals.end() ; ++iintv ) { + s << " [" << DbU::getValueString((*iintv).getVMin()) + << ":" << DbU::getValueString((*iintv).getVMax()) << "]"; + } + return s.str(); + } + + +// ------------------------------------------------------------------- +// Class : "RipupHistory". + + class RipupHistory { + public: + RipupHistory ( RoutingEvent* ); + inline bool isDislodger ( RoutingEvent* ) const; + inline size_t size () const; + inline size_t getDislodgersCount () const; + void addAxis ( DbU::Unit ); + void addAxis ( RoutingEvent* ); + bool hasAxis ( DbU::Unit ) const; + UnionIntervals* getUnionIntervals ( DbU::Unit ); + void addDislodger ( RoutingEvent* ); + void addDislodger ( TrackElement* ); + void print ( ostream& ); + private: + RoutingEvent* _masterEvent; + map _dislodgers; + size_t _dislodgersCount; + }; + + + RipupHistory::RipupHistory ( RoutingEvent* event ) + : _masterEvent (event) + , _dislodgers () + , _dislodgersCount(0) + { + const Interval& perpandicular = _masterEvent->getPerpandicularFree(); + RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(_masterEvent->getSegment()->getLayer()); + Track* track; + + if (not perpandicular.isEmpty()) { + track = plane->getTrackByPosition(perpandicular.getVMin()); + + if (track and (track->getAxis() < perpandicular.getVMin())) track = track->getNextTrack(); + for ( ; track && (track->getAxis() <= perpandicular.getVMax()) + ; track = track->getNextTrack() ) + addAxis( track->getAxis() ); + } + + track = plane->getTrackByPosition(_masterEvent->getSegment()->getAxis()); + if (track) { + size_t begin = Track::npos; + size_t end = Track::npos; + Interval interval = _masterEvent->getSegment()->getCanonicalInterval(); + track->getOverlapBounds( interval, begin, end ); + + if (begin != Track::npos) { + for ( ; begin < end ; ++begin ) { + TrackElement* other = track->getSegment(begin); + if (other->getNet() == _masterEvent->getSegment()->getNet() ) continue; + if (not interval.intersect(other->getCanonicalInterval())) continue; + + addDislodger( other ); + } + } + } + } + + + inline bool RipupHistory::isDislodger ( RoutingEvent* event ) const { return hasAxis(event->getSegment()->getAxis()); } + inline size_t RipupHistory::size () const { return _dislodgers.size(); } + inline size_t RipupHistory::getDislodgersCount () const { return _dislodgersCount; } + + + void RipupHistory::addAxis ( DbU::Unit axis ) + { + if (hasAxis(axis)) return; + _dislodgers.insert( make_pair(axis,UnionIntervals()) ); + } + + + void RipupHistory::addAxis ( RoutingEvent* event ) + { addAxis( event->getAxisHistory() ); } + + + bool RipupHistory::hasAxis ( DbU::Unit axis ) const + { return _dislodgers.find(axis) != _dislodgers.end(); } + + + UnionIntervals* RipupHistory::getUnionIntervals ( DbU::Unit axis ) + { + map::iterator iunion = _dislodgers.find ( axis ); + if (iunion == _dislodgers.end()) return NULL; + + return &(iunion->second); + } + + + void RipupHistory::addDislodger ( RoutingEvent* event ) + { + if (event->getSegment() == _masterEvent->getSegment()) return; + if (event->getSegment()->getLayer() != _masterEvent->getSegment()->getLayer()) return; + + UnionIntervals* intervals = getUnionIntervals( event->getAxisHistory() ); + if (not intervals) return; + + Interval canonical = event->getSegment()->getCanonicalInterval(); + intervals->addInterval( canonical ); + + ++_dislodgersCount; + } + + + void RipupHistory::addDislodger ( TrackElement* segment ) + { + if (_masterEvent->getSegment()->getNet() == segment->getNet()) return; + + UnionIntervals* intervals = getUnionIntervals( segment->getAxis() ); + if (not intervals) return; + + Interval canonical = segment->getCanonicalInterval(); + intervals->addInterval( canonical ); + + ++_dislodgersCount; + } + + + void RipupHistory::print ( ostream& o ) + { + o << "[HISTORY] " << _masterEvent << endl; + + map::iterator iunion = _dislodgers.begin(); + for ( ; iunion != _dislodgers.end() ; ++iunion ) + o << " @" << DbU::getValueString(iunion->first) + << " " << (iunion->second)._getString() << endl; + } + + +} // Anonymous namespace. + + +namespace Kite { + + using std::sort; + using Hurricane::tab; + using Hurricane::inltrace; + using Hurricane::ltracein; + using Hurricane::ltraceout; + using Hurricane::DebugSession; + using Hurricane::Bug; + using Hurricane::ForEachIterator; + using Katabatic::KbHalfSlacken; + + +// ------------------------------------------------------------------- +// Class : "SegmentAction". + + SegmentAction::SegmentAction ( TrackElement* segment + , unsigned int type + , DbU::Unit axisHint + , unsigned int toState + ) + : _segment (segment) + , _type (type) + , _axisHint(axisHint) + , _toState (toState) + { } + + + bool SegmentAction::doAction ( RoutingEventQueue& queue ) + { + // Note: + // "_immediate" ripup flags was associated with "perpandicular", as they + // must be re-inserted *before* any parallel. Must look to solve the redundancy. + + DebugSession::open( _segment->getNet(), 200 ); + + if (_type & Perpandicular) { + ltrace(200) << "* Riping Pp " << _segment << endl; + } else { + ltrace(200) << "* Riping // " << _segment << endl; + } + + if (_segment->isFixed()) { DebugSession::close(); return true; } + + DataNegociate* data = _segment->getDataNegociate(); + if (data == NULL) { DebugSession::close(); return true; } + + if (_type & ResetRipup) data->resetRipupCount(); + + if (_type & ToState) { + data->setState ( _toState ); + data->setRipupCount( Session::getKiteEngine()->getRipupLimit(_segment) ); + } + + if (_segment->getTrack()) Session::addRemoveEvent( _segment ); + + RoutingEvent* event = data->getRoutingEvent(); + if (event == NULL) { + cerr << Bug( "Missing Event on %p:%s" + , _segment->base()->base(),getString(_segment).c_str() ) << endl; + DebugSession::close(); + return true; + } + + if ( (_type & AxisHint) /*and not _segment->isSlackenDogleg()*/ ) { + ltrace(200) << "Setting Axis Hint: @" << DbU::getValueString(_axisHint) << endl; + event->setAxisHint( _axisHint ); + } + + // It is possible that this code could be disabled. + // There should be no need to move the axis of the segment to be inserted, + // it will automatically slot into the empty track, if any. + if (_type & MoveToAxis) { + ltrace(200) << "Moving Axis To: @" << DbU::getValueString(_axisHint) << endl; + _segment->setAxis( _axisHint ); + } + + if (_type & ToRipupLimit) { + unsigned int limit = Session::getKiteEngine()->getRipupLimit(_segment); + if (limit > data->getRipupCount()) + data->setRipupCount( limit ); + } + + unsigned int eventLevel = 0; + if (_type & EventLevel1) eventLevel = 1; + if (_type & EventLevel2) eventLevel = 2; + if (_type & EventLevel3) eventLevel = 3; + if (_type & EventLevel4) eventLevel = 4; + if (_type & EventLevel5) eventLevel = 5; + event->setRipedByLocal( _type&RipedByLocal ); + + RoutingEvent* fork = event->reschedule( queue, eventLevel ); + + if (fork) { + unsigned int mode = RoutingEvent::Repair; + if (RoutingEvent::getStage() < RoutingEvent::Repair) + mode = (_type&PackingMode) ? RoutingEvent::Pack : RoutingEvent::Negociate; + fork->setMode( mode ); + } + + DebugSession::close(); + return true; + } + + +// ------------------------------------------------------------------- +// Class : "SegmentFsm". + + + SegmentFsm::SegmentFsm ( RoutingEvent* event, RoutingEventQueue& queue, RoutingEventHistory& history ) + : _event (event) + , _queue (queue) + , _history (history) + , _state (0) + , _data (NULL) + , _constraint () + , _optimal () + , _costs () + , _actions () + , _fullBlocked (true) + { + TrackElement* segment = _event->getSegment(); + unsigned int depth = Session::getRoutingGauge()->getLayerDepth(segment->getLayer()); + _event->setTracksFree ( 0 ); + + _data = segment->getDataNegociate(); + if ( !_data ) { + _state = MissingData; + return; + } + + _data->update(); + _event->revalidate(); + + _constraint = _event->getConstraints(); + _optimal = _event->getOptimal(); + + const Interval& perpandicular = _event->getPerpandicularFree (); + + ltrace(148) << "Katabatic intervals:" << endl; + ltrace(148) << "* Optimal: " << _optimal << endl; + ltrace(148) << "* Constraints: " << _constraint << endl; + ltrace(148) << "* Perpandicular: " << perpandicular << endl; + ltrace(148) << "* AxisHint: " << DbU::getValueString(_event->getAxisHint()) << endl; + + if ( _event->getTracksNb() ) { + if ( _constraint.getIntersection(perpandicular).isEmpty() ) { + ltrace(200) << "Perpandicular free is too tight." << endl; + _state = EmptyTrackList; + } else + _constraint.intersection ( perpandicular ); + } else { + ltrace(200) << "No Track in perpandicular free." << endl; + _state = EmptyTrackList; + } + + if ( _state == EmptyTrackList ) return; + + ltrace(148) << "Negociate intervals:" << endl; + ltrace(148) << "* Optimal: " << _optimal << endl; + ltrace(148) << "* Constraints: " << _constraint << endl; + ltracein(148); + + // if ( segment->isLocal() and (_data->getState() >= DataNegociate::MaximumSlack) ) + // _constraint.inflate ( 0, DbU::lambda(1.0) ); + + bool inLocalDepth = (depth < 3); + bool isOneLocalTrack = (segment->isLocal()) + and (segment->base()->getAutoSource()->getGCell()->getGlobalsCount(depth) >= 9.0); + + RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(segment->getLayer()); + forEach ( Track*, itrack, Tracks_Range::get(plane,_constraint)) { + unsigned int costflags = 0; + costflags |= (segment->isLocal() and (depth >= 3)) ? TrackCost::LocalAndTopDepth : 0; + + _costs.push_back ( itrack->getOverlapCost(segment,costflags) ); + _costs.back().setAxisWeight ( _event->getAxisWeight(itrack->getAxis()) ); + _costs.back().incDeltaPerpand ( _data->getWiringDelta(itrack->getAxis()) ); + if (segment->isGlobal()) _costs.back().setForGlobal(); + + if ( inLocalDepth and (_costs.back().getDataState() == DataNegociate::MaximumSlack) ) + _costs.back().setInfinite (); + + if ( isOneLocalTrack + and _costs.back().isOverlapGlobal() + and (_costs.back().getDataState() >= DataNegociate::ConflictSolveByHistory) ) + _costs.back().setInfinite (); + + _costs.back().consolidate (); + if ( _fullBlocked and (not _costs.back().isBlockage() and not _costs.back().isFixed()) ) + _fullBlocked = false; + + ltrace(149) << "| " << _costs.back() << ((_fullBlocked)?" FB ": " -- ") << (*itrack) << endl; + } + ltraceout(148); + + if ( _costs.empty() ) { + Track* nearest = plane->getTrackByPosition(_constraint.getCenter()); + + if ( (nearest->getAxis() < _constraint.getVMin()) + or (nearest->getAxis() > _constraint.getVMax()) ) { + //setUnimplemented (); + //cerr << "[UNIMPLEMENTED] " << segment << " no Track in constraint interval " + // << _constraint << " " << "." << endl; + } else { + cerr << Bug(" %s Track_Range() failed to find Tracks in %s (they exists)." + ,getString(segment).c_str() + ,getString(_constraint).c_str() + ) << endl; + } + _state = EmptyTrackList; + } + + unsigned int flags = 0; + flags |= (segment->isStrap()) ? TrackCost::IgnoreAxisWeight : 0; + flags |= (segment->isLocal() + and (_data->getState() < DataNegociate::Minimize) + and (_data->getRipupCount() < 5)) + ? TrackCost::DiscardGlobals : 0; + flags |= (RoutingEvent::getStage() == RoutingEvent::Repair) ? TrackCost::IgnoreSharedLength : 0; + + if ( flags & TrackCost::DiscardGlobals ) { + ltrace(200) << "TrackCost::Compare() - DiscardGlobals" << endl; + } + + sort ( _costs.begin(), _costs.end(), TrackCost::Compare(flags) ); + + size_t i=0; + for ( ; (i<_costs.size()) and _costs[i].isFree() ; i++ ); + _event->setTracksFree ( i ); + } + + + void SegmentFsm::addAction ( TrackElement* segment + , unsigned int type + , DbU::Unit axisHint + , unsigned int toSegmentFsm ) + { + if ( not segment->isFixed() ) { + _actions.push_back ( SegmentAction(segment,type,axisHint,toSegmentFsm) ); + ltrace(200) << "SegmentFsm::addAction(): " << segment << endl; + } + } + + + void SegmentFsm::doActions () + { + ltrace(200) << "SegmentFsm::doActions() - " << _actions.size() << endl; + + bool ripupOthersParallel = false; + bool ripedByLocal = getEvent()->getSegment()->isLocal(); + + for ( size_t i=0 ; i<_actions.size() ; i++ ) { + if ( ripedByLocal ) _actions[i].setFlag ( SegmentAction::RipedByLocal ); + if ( _actions[i].getType() & SegmentAction::OtherRipup ) { + ripupOthersParallel = true; + } + } + + for ( size_t i=0 ; i<_actions.size() ; i++ ) { + if ( (_actions[i].getType() & SegmentAction::SelfInsert) and ripupOthersParallel ) + _actions[i].setFlag ( SegmentAction::EventLevel3 ); + + DebugSession::open ( _actions[i].getSegment()->getNet(), 200 ); + if ( not _actions[i].doAction(_queue) ) { + cinfo << "[INFO] Failed action on " << _actions[i].getSegment() << endl; + } + DebugSession::close (); + } + + _actions.clear (); + } + + + bool SegmentFsm::insertInTrack ( size_t i ) + { + ltrace(200) << "SegmentFsm::insertInTrack() istate:" << _event->getInsertState() + << " track:" << i << endl; + + _event->incInsertState(); + switch ( _event->getInsertState() ) { + case 1: + if ( Manipulator(_event->getSegment(),*this).insertInTrack(i) ) return true; + _event->incInsertState(); + case 2: + if ( Manipulator(_event->getSegment(),*this).shrinkToTrack(i) ) return true; + _event->incInsertState(); + case 3: + if ( Manipulator(_event->getSegment(),*this).forceToTrack(i) ) return true; + _event->incInsertState(); + } + return false; + } + + + bool SegmentFsm::conflictSolveByHistory () + { + bool success = false; + RipupHistory ripupHistory ( _event ); + RoutingEvent* event; + TrackElement* segment = _event->getSegment(); + + ltrace(200) << "SegmentFsm::conflictSolveByHistory()" << endl; + + size_t maxDepth = min( getHistory().size(), (size_t)300 ); + size_t depth = 0; + while ( (ripupHistory.getDislodgersCount() < 3) and (depth < maxDepth) ) { + event = getHistory().getRNth(depth++); + if (not event) continue; + if ( (event->getSegment() != segment) and ripupHistory.isDislodger(event) ) + ripupHistory.addDislodger( event ); + } + + //ripupHistory.print ( cout ); + + UnionIntervals* intervals = ripupHistory.getUnionIntervals( segment->getAxis() ); + if (intervals and not intervals->empty()) { + + DbU::Unit minConflict = intervals->getVMin(); + DbU::Unit maxConflict = intervals->getVMax(); + Interval canonical = segment->getCanonicalInterval(); + bool sourceDogleg = canonical.contains(minConflict); + bool targetDogleg = canonical.contains(maxConflict); + Point breakPoint; + + if (sourceDogleg) { + if (segment->isHorizontal()) { + breakPoint = Point( minConflict, segment->getAxis() ); + ltrace(200) << breakPoint << endl; + } else { + breakPoint = Point( segment->getAxis(), minConflict ); + ltrace(200) << breakPoint << endl; + } + + Katabatic::GCell* dogLegGCell = Session::getGCellUnder( breakPoint.getX(), breakPoint.getY() ); + if (dogLegGCell) { + if (segment->canDogleg(dogLegGCell)) + success = segment->makeDogleg(dogLegGCell); + } else { + cerr << Bug( "No GCell under source %s for:\n %s." + , getString(breakPoint).c_str(), getString(segment).c_str() ) << endl; + } + } + + if (not success and targetDogleg) { + if (segment->isHorizontal()) { + breakPoint = Point( maxConflict, segment->getAxis() ); + ltrace(200) << breakPoint << endl; + } else { + breakPoint = Point( segment->getAxis(), maxConflict ); + ltrace(200) << breakPoint << endl; + } + + Katabatic::GCell* dogLegGCell = Session::getGCellUnder( breakPoint.getX(), breakPoint.getY() ); + if (dogLegGCell) { + if (segment->canDogleg(dogLegGCell)) { + success = segment->makeDogleg(dogLegGCell); + } + } else { + cerr << Bug( "No GCell under target %s for:\n %s." + , getString(breakPoint).c_str(), getString(segment).c_str() ) << endl; + } + } + } else { + ltrace(200) << "No disloggers found @" << DbU::getValueString(segment->getAxis()) << endl; + + Interval freeSpan = Session::getKiteEngine()-> + getTrackByPosition(segment->getLayer(),segment->getAxis())-> + getFreeInterval(segment->getSourceU(),segment->getNet()); + + if (freeSpan.contains(segment->getCanonicalInterval())) { + ltrace(200) << "Disloggers vanished, Segment can be re-inserted." << endl; + success = true; + } + } + + return success; + } + + + bool SegmentFsm::conflictSolveByPlaceds () + { + bool success = false; + Interval constraints; + vector candidates; + TrackElement* segment = _event->getSegment(); + bool canMoveUp = (segment->isLocal()) ? segment->canPivotUp(0.5) : segment->canMoveUp(1.0); // MARK 1 + unsigned int relaxFlags = Manipulator::NoDoglegReuse + | ((_data and (_data->getStateCount() < 2)) ? Manipulator::AllowExpand + : Manipulator::NoExpand); + + ltrace(200) << "SegmentFsm::conflictSolveByPlaceds()" << endl; + ltrace(200) << "| Candidates Tracks: " << endl; + + segment->base()->getConstraints( constraints ); + Interval overlap = segment->getCanonicalInterval(); + RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(segment->getLayer()); + Track* track = plane->getTrackByPosition(constraints.getVMin(),Constant::Superior); + + if (not track) { + cerr << Bug( "SegmentFsm::conflictSolveByPlaceds():\n" + " For: %s\n" + " In %s, no Track near %s" + , getString(segment).c_str() + , getString(plane).c_str() + , DbU::getValueString(constraints.getVMin()).c_str() + ) << endl; + return false; + } + + for ( ; track and track->getAxis() <= constraints.getVMax() ; track = track->getNextTrack() ) { + candidates.push_back( Cs1Candidate(track) ); + + size_t begin; + size_t end; + TrackElement* other; + Net* otherNet = NULL; + Interval otherOverlap; + bool otherIsGlobal = false; + + track->getOverlapBounds( overlap, begin, end ); + candidates.back().setBegin( begin ); + candidates.back().setEnd ( end ); + + ltrace(200) << "* " << track << " [" << begin << ":" << end << "]" << endl; + + for ( ; (begin < end) ; ++begin ) { + other = track->getSegment( begin ); + + if (other->getNet() == segment->getNet()) { + ltrace(200) << " | " << begin << " Same net: " << " " << other << endl; + continue; + } + if (not other->getCanonicalInterval().intersect(overlap)) { + ltrace(200) << " | " << begin << " No Conflict: " << " " << other << endl; + if (otherNet == NULL) candidates.back().setBegin( begin+1 ); + continue; + } + ltrace(200) << " | " << begin << " Conflict: " << " " << other << endl; + + if (otherNet != other->getNet()) { + if (otherNet) { + if (otherIsGlobal) { + candidates.back().addConflict( otherOverlap ); + ltrace(200) << " | Other overlap G: " << otherOverlap << endl; + } else { + ltrace(200) << " | Other overlap L: " << otherOverlap << " ignored." << endl; + } + } + otherNet = other->getNet(); + otherOverlap = other->getCanonicalInterval(); + otherIsGlobal = other->isGlobal() or other->isBlockage(); + } else { + otherOverlap.merge(other->getCanonicalInterval()); + otherIsGlobal = otherIsGlobal or other->isGlobal() or other->isBlockage(); + } + } + if (not otherOverlap.isEmpty()) { + if (otherIsGlobal) { + candidates.back().addConflict( otherOverlap ); + ltrace(200) << " | Other overlap G: " << otherOverlap << endl; + } else { + ltrace(200) << " | Other overlap L: " << otherOverlap << " ignored." << endl; + } + } + + candidates.back().consolidate(); + } + + sort( candidates.begin(), candidates.end() ); + + for ( size_t icandidate=0 ; icandidategetSegment( overlap.getCenter() ); + if (not other) { + cbug << Error("conflictSolveByPlaceds(): No segment under overlap center.") << endl; + continue; + } + + if (other->isGlobal()) { + ltrace(200) << "conflictSolveByPlaceds() - Conflict with global, other move up" << endl; + if ((success = Manipulator(other,*this).moveUp())) break; + } + + ltrace(200) << "conflictSolveByPlaceds() - Relaxing self" << endl; + + if (Manipulator(segment,*this).relax(overlap0,relaxFlags)) { + success = true; + break; + } else { + if ( not canMoveUp + and (relaxFlags != Manipulator::NoExpand) + and Manipulator(segment,*this).relax(overlap0,Manipulator::NoExpand|Manipulator::NoDoglegReuse) ) { + ltrace(200) << "Cannot move up but successful narrow breaking." << endl; + success = true; + break; + } + } + } + + if ( not success and segment->isGlobal() and (_costs.size() <= 1) ) { + ltrace(200) << "Overconstrained perpandiculars, rip them up. On track:" << endl; + ltrace(200) << " " << track << endl; + Manipulator(segment,*this).ripupPerpandiculars (); + success = true; + } + + return success; + } + + + bool SegmentFsm::solveTerminalVsGlobal () + { + TrackElement* segment = getEvent()->getSegment(); + ltrace(200) << "SegmentFsm::solveTerminalVsGlobal: " << " " << segment << endl; + + if (not (segment->isTerminal() and segment->isLocal())) return false; + + for ( size_t icost=0 ; icost<_costs.size() ; ++icost ) { + Interval overlap = segment->getCanonicalInterval(); + size_t begin; + size_t end; + getCost(icost).getTrack()->getOverlapBounds( overlap, begin, end ); + + for ( ; begingetSegment(begin); + Interval otherOverlap = other->getCanonicalInterval(); + + if (other->getNet() == segment->getNet()) continue; + if (not other->isGlobal()) continue; + if (not otherOverlap.contains(overlap)) continue; + + ltrace(200) << "| Global candidate:" << other << endl; + if (Manipulator(other,*this).moveUp(Manipulator::AllowTerminalMoveUp)) { + ltrace(200) << "| Global candidate selected." << endl; + return true; + } + } + } + + return false; + } + + + bool SegmentFsm::solveFullBlockages () + { + bool success = false; + TrackElement* segment = getEvent()->getSegment(); + + ltrace(200) << "SegmentFsm::solveFullBlockages: " << " " << segment << endl; + ltracein(200); + + if ( segment->isLocal() ) { + success = Manipulator(segment,*this).pivotUp(); + if ( not success ) { + ltrace(200) << "Tightly constrained local segment overlapping a blockage, move up." << endl; + ltrace(200) << segment << endl; + success = Manipulator(segment,*this).moveUp + (Manipulator::AllowLocalMoveUp|Manipulator::AllowTerminalMoveUp); + } + } else { + Interval overlap = segment->getCanonicalInterval(); + size_t begin; + size_t end; + + getCost(0).getTrack()->getOverlapBounds ( overlap, begin, end ); + for ( ; begingetSegment(begin); + Interval otherOverlap = other->getCanonicalInterval(); + + if ( other->getNet() == segment->getNet() ) continue; + if ( not otherOverlap.intersect(overlap) ) continue; + + ltrace(200) << "| " << begin << " Blockage conflict: " << " " << other << endl; + if ( (success = Manipulator(segment,*this).relax + (otherOverlap,Manipulator::NoDoglegReuse|Manipulator::NoExpand)) ) { + break; + } + } + } + if ( not success ) { + cparanoid << Error( "Tighly constrained segment overlapping a blockage:\n %s" + , getString(segment).c_str() ) << endl; + ltrace(200) << "Segment is hard blocked, bypass to Unimplemented." << endl; + } + + ltraceout(200); + return success; + } + + + bool SegmentFsm::desaturate () + { + ltrace(200) << "SegmentFsm::desaturate()" << endl; + ltracein(200); + + size_t itrack = 0; + +#if THIS_IS_DISABLED + TrackElement* segment = _event->getSegment(); + for ( ; itrackgetNet(); + Interval toFree (segment->getCanonicalInterval()); + bool success = true; + + for ( size_t i = begin ; success and (i < end) ; i++ ) { + TrackElement* segment2 = track->getSegment(i); + + ltrace(200) << "* Looking // " << segment2 << endl; + + if ( segment2->getNet() == ownerNet ) continue; + if ( not toFree.intersect(segment2->getCanonicalInterval()) ) continue; + if ( segment2->isFixed() or not segment2->isBipoint() ) { + success = false; + continue; + } + + DataNegociate* data2 = segment2->getDataNegociate(); + if ( not data2 ) { + ltrace(200) << "No DataNegociate, ignoring." << endl; + success = false; + continue; + } + + ltrace(200) << "- Forced moveUp " << segment2 << endl; + if ( not (success=Manipulator(segment2,*this).moveUp(Manipulator::AllowTerminalMoveUp)) ) { + continue; + } + } + + if ( success ) { + setState ( SegmentFsm::OtherRipup ); + addAction( segment + , SegmentAction::SelfInsert|SegmentAction::MoveToAxis + , getCost(itrack).getTrack()->getAxis() + ); + break; + } + } + } + +#endif + ltraceout(200); + return (itrack < _costs.size()); + } + + + + bool SegmentFsm::_slackenStrap ( TrackElement*& segment, DataNegociate*& data, unsigned int flags ) + { + ltrace(200) << "Strap segment Fsm." << endl; + + bool success = false; + unsigned int nextState = data->getState(); + + switch ( data->getState() ) { + case DataNegociate::RipupPerpandiculars: + nextState = DataNegociate::Minimize; + success = Manipulator(segment,*this).ripupPerpandiculars(); + if (success) break; + case DataNegociate::Minimize: + if (data->getStateCount() >= 2) { + nextState = DataNegociate::MaximumSlack; + } + success = Manipulator(segment,*this).minimize(); + if (success) break; + case DataNegociate::Dogleg: + case DataNegociate::Slacken: + case DataNegociate::ConflictSolveByHistory: + case DataNegociate::ConflictSolveByPlaceds: + case DataNegociate::MoveUp: + case DataNegociate::MaximumSlack: + case DataNegociate::Unimplemented: + nextState = DataNegociate::Unimplemented; + break; + } + + if (not success and (nextState != DataNegociate::Unimplemented)) + success = Manipulator(segment,*this).ripupPerpandiculars(Manipulator::ToRipupLimit); + + if (not (flags&NoTransition)) { + data->setState( nextState ); + ltrace(200) << "Incrementing state (after): " << nextState << " count:" << data->getStateCount() << endl; + } + + return success; + } + + + bool SegmentFsm::_slackenLocal ( TrackElement*& segment, DataNegociate*& data, unsigned int flags ) + { + ltrace(200) << "Local segment Fsm." << endl; + + bool success = false; + unsigned int nextState = data->getState(); + + switch (data->getState()) { + case DataNegociate::RipupPerpandiculars: + nextState = DataNegociate::Minimize; + success = Manipulator(segment,*this).ripupPerpandiculars(); + if (success) break; + case DataNegociate::Minimize: + if (isFullBlocked() and not segment->isTerminal()) { + ltrace(200) << "Is Fully blocked." << endl; + nextState = DataNegociate::Unimplemented; + break; + } + nextState = DataNegociate::Dogleg; + success = Manipulator(segment,*this).minimize(); + if (success) break; + case DataNegociate::Dogleg: + nextState = DataNegociate::Slacken; + success = Manipulator(segment,*this).makeDogleg(); + if (success) break; + case DataNegociate::Slacken: + nextState = DataNegociate::ConflictSolveByPlaceds; + success = Manipulator(segment,*this).slacken(); + if (success) break; + case DataNegociate::ConflictSolveByHistory: + case DataNegociate::ConflictSolveByPlaceds: + nextState = DataNegociate::LocalVsGlobal; + success = conflictSolveByHistory(); + break; + case DataNegociate::LocalVsGlobal: + nextState = DataNegociate::MoveUp; + success = solveTerminalVsGlobal(); + if (success) break; + break; + case DataNegociate::MoveUp: + nextState = DataNegociate::MaximumSlack; + success = Manipulator(segment,*this).moveUp(); + if (success) break; + case DataNegociate::MaximumSlack: + if (segment->isStrap()) { + if ( (nextState < DataNegociate::MaximumSlack) or (data->getStateCount() < 2) ) { + nextState = DataNegociate::MaximumSlack; + success = conflictSolveByPlaceds(); + if (success) break; + } + } + case DataNegociate::Unimplemented: + nextState = DataNegociate::Unimplemented; + break; + } + + if (not success and (nextState != DataNegociate::Unimplemented)) { + if (data->getStateCount() < 6) + success = Manipulator(segment,*this).ripupPerpandiculars(Manipulator::ToRipupLimit); + } + + if (not success + and (nextState == DataNegociate::Unimplemented) + and segment->isSlackened() + and isFullBlocked()) { + if (solveFullBlockages()) nextState = DataNegociate::MoveUp; + } + + if (not (flags&NoTransition)) { + data->setState( nextState ); + ltrace(200) << "Incrementing state (after): " << nextState << " count:" << data->getStateCount() << endl; + } + + return success; + } + + + bool SegmentFsm::_slackenGlobal ( TrackElement*& segment, DataNegociate*& data, unsigned int flags ) + { + bool success = false; + unsigned int nextState = data->getState(); + + switch ( data->getState() ) { + case DataNegociate::RipupPerpandiculars: + case DataNegociate::Minimize: + case DataNegociate::Dogleg: + ltrace(200) << "Global, SegmentFsm: RipupPerpandiculars." << endl; + nextState = DataNegociate::Slacken; + break; + case DataNegociate::Slacken: + ltrace(200) << "Global, SegmentFsm: Slacken." << endl; + if ((success = Manipulator(segment,*this).slacken(KbHalfSlacken))) { + nextState = DataNegociate::RipupPerpandiculars; + break; + } + case DataNegociate::MoveUp: + ltrace(200) << "Global, SegmentFsm: MoveUp." << endl; + if ((success = Manipulator(segment,*this).moveUp(Manipulator::AllowShortPivotUp))) { + break; + } + nextState = DataNegociate::ConflictSolveByHistory; + break; + case DataNegociate::ConflictSolveByHistory: + case DataNegociate::ConflictSolveByPlaceds: + ltrace(200) << "Global, SegmentFsm: ConflictSolveByHistory or ConflictSolveByPlaceds." << endl; + if ((success = conflictSolveByPlaceds())) { + if (segment->canMoveUp(1.0)) + nextState = DataNegociate::MoveUp; + else { + if (data->getStateCount() > 3) + nextState = DataNegociate::MaximumSlack; + } + if (segment->getDataNegociate()->getState() < DataNegociate::ConflictSolveByHistory) + nextState = segment->getDataNegociate()->getState(); + break; + } + case DataNegociate::MaximumSlack: + if ((success=Manipulator(segment,*this).forceOverLocals())) { + break; + } + case DataNegociate::Unimplemented: + ltrace(200) << "Global, SegmentFsm: MaximumSlack or Unimplemented." << endl; + nextState = DataNegociate::Unimplemented; + break; + } + + if (not success and (nextState != DataNegociate::Unimplemented)) { + if (data->getStateCount() < 6) + success = Manipulator(segment,*this).ripupPerpandiculars(Manipulator::ToRipupLimit); + } + + // Special case: all tracks are overlaping a blockage. + if (not success + and (nextState == DataNegociate::Unimplemented) + and segment->isSlackened() ) { + if (solveFullBlockages()) nextState = DataNegociate::MoveUp; + } + + if (not (flags&NoTransition)) { + if (data->getChildSegment()) { + TrackElement* child = segment; + ltrace(200) << "Incrementing state of childs (after): " << endl; + while ( child ) { + ltrace(200) << "| " << child << endl; + if (child->base()->isGlobal()) { + child->getDataNegociate()->setState( nextState ); + ltrace(200) << "| Update:" << nextState << " count:" << child->getDataNegociate()->getStateCount() << endl; + } + TrackElement* parent = child; + child = parent->getDataNegociate()->getChildSegment(); + parent->getDataNegociate()->setChildSegment( NULL ); + } + } else { + data->setState( nextState ); + ltrace(200) << "Incrementing state (after): " << segment << endl; + ltrace(200) << "| " << nextState << " count:" << data->getStateCount() << endl; + } + } + + return success; + } + + + bool SegmentFsm::slackenTopology ( unsigned int flags ) + { + bool success = false; + TrackElement* segment = getEvent()->getSegment(); + DataNegociate* data = segment->getDataNegociate (); + unsigned int actionFlags = SegmentAction::SelfInsert|SegmentAction::EventLevel5; + + DebugSession::open( segment->getNet(), 200 ); + ltrace(200) << "Slacken Topology for " << segment->getNet() + << " " << segment << endl; + ltracein(200); + + if (not segment or not data) { ltraceout(200); DebugSession::close(); return false; } + + _event->resetInsertState(); + data->resetRipupCount(); + + if (segment->isStrap()) { success = _slackenStrap ( segment, data, flags ); } + else if (segment->isLocal()) { success = _slackenLocal ( segment, data, flags ); } + else { success = _slackenGlobal( segment, data, flags ); } + + if (success) { + actionFlags |= SegmentAction::ResetRipup; + addAction( segment, actionFlags ); + } else { + clearActions(); + if (data->getState() == DataNegociate::Unimplemented) { + cinfo << "[UNSOLVED] " << segment << " unable to slacken topology." << endl; + } + } + + ltraceout(200); + DebugSession::close(); + + return success; + } + + +} // Kite namespace. diff --git a/kite/src/Session.cpp b/kite/src/Session.cpp index 17e320d3..b6e6c2ff 100644 --- a/kite/src/Session.cpp +++ b/kite/src/Session.cpp @@ -1,15 +1,9 @@ - -// -*- C++ -*- +// -*- mode: C++; explicit-buffer-name: "Session.cpp" -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 | // | | @@ -17,13 +11,11 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./Session.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ #include "hurricane/Bug.h" +#include "hurricane/Point.h" #include "hurricane/Error.h" #include "katabatic/GCellGrid.h" #include "kite/Session.h" @@ -34,7 +26,6 @@ namespace { - using namespace Kite; @@ -43,12 +34,11 @@ namespace { " Session already open for %s (internal error)."; -} // End of local namespace. +} // Anonymous namespace. namespace Kite { - using std::cerr; using std::endl; using Hurricane::tab; @@ -57,39 +47,32 @@ namespace Kite { using Hurricane::ltraceout; using Hurricane::Error; using Hurricane::Bug; + using Hurricane::Point; // ------------------------------------------------------------------- // Class : "Session". - Session::Session ( KiteEngine* kite ) : Katabatic::Session(kite) , _insertEvents() , _removeEvents() , _sortEvents () - { - //_addCanonizeCb ( _computeCagedConstraints ); - } + { } void Session::_postCreate () - { - Katabatic::Session::_postCreate (); - } + { Katabatic::Session::_postCreate(); } Session::~Session () { } - size_t Session::_preDestroy () + void Session::_preDestroy () { - _isEmpty (); - - size_t count = Katabatic::Session::_preDestroy (); - - return count; + _isEmpty(); + Katabatic::Session::_preDestroy(); } @@ -97,16 +80,16 @@ namespace Kite { { ltrace(110) << "Kite::Session::open()" << endl; - Session* session = Session::get (); - if ( session ) { - if ( session->_getKiteEngine() != kite ) - throw Error ( reopenSession, getString(session->getKiteEngine()).c_str() ); + Session* session = Session::get(); + if (session) { + if (session->_getKiteEngine() != kite) + throw Error( reopenSession, getString(session->getKiteEngine()).c_str() ); return session; } session = new Session ( kite ); - session->_postCreate (); + session->_postCreate(); return session; } @@ -120,14 +103,6 @@ namespace Kite { { return Session::getKiteEngine()->getConfiguration(); } - void Session::link ( TrackElement* trackSegment ) - { Session::get("link(TrackElement*)")->_getKiteEngine()->_link(trackSegment); } - - - void Session::unlink ( TrackElement* trackSegment ) - { Session::get("unlink(TrackElement*)")->_getKiteEngine()->_unlink(trackSegment); } - - TrackElement* Session::lookup ( Segment* segment ) { return Session::get("Session::lookup(Segment*)")->_getKiteEngine()->_lookup(segment); } @@ -136,10 +111,6 @@ namespace Kite { { return Session::get("lookup(AutoSegment*)")->_getKiteEngine()->_lookup ( segment ); } - Katabatic::GCell* Session::lookup ( Katabatic::GCell* gcell ) - { return Session::get("lookup(Katabatic::GCell*)")->_getKiteEngine()->getGCellGrid()->getGCell(gcell->getIndex()); } - - void Session::setInterrupt ( bool state ) { Session::get("setInterrupt()")->_getKiteEngine()->setInterrupt(state); } @@ -166,115 +137,102 @@ namespace Kite { size_t Session::_revalidate () { + ltrace(90) << "Kite::Session::_revalidate()" << endl; + ltracein(90); + set packTracks; - for ( size_t i=0 ; i < _removeEvents.size() ; i++ ) { - if ( !_removeEvents[i]._segment->getTrack() ) continue; + for ( size_t i=0 ; i<_removeEvents.size() ; ++i ) { + if (not _removeEvents[i]._segment->getTrack()) continue; - packTracks.insert ( _removeEvents[i]._segment->getTrack() ); - _removeEvents[i]._segment->detach (); + packTracks.insert( _removeEvents[i]._segment->getTrack() ); + _removeEvents[i]._segment->detach(); } - _removeEvents.clear (); + _removeEvents.clear(); - for ( set::iterator it=packTracks.begin() ; it != packTracks.end() ; it++ ) - (*it)->pack (); + for ( set::iterator it=packTracks.begin() ; it != packTracks.end() ; ++it ) + (*it)->doRemoval(); - for ( size_t i=0 ; i < _insertEvents.size() ; i++ ) { - if ( _insertEvents[i]._segment ) { - _insertEvents[i]._track->insert ( _insertEvents[i]._segment ); + for ( size_t i=0 ; i<_insertEvents.size() ; ++i ) { + if (_insertEvents[i]._segment) { + _insertEvents[i]._track->insert( _insertEvents[i]._segment ); } - if ( _insertEvents[i]._marker ) _insertEvents[i]._track->insert ( _insertEvents[i]._marker ); + if (_insertEvents[i]._marker) _insertEvents[i]._track->insert( _insertEvents[i]._marker ); } - _insertEvents.clear (); + _insertEvents.clear(); // Check if to be destroyeds are not associateds with TrackSegments. const set& destroyeds = getDestroyeds(); set::const_iterator idestroyed = destroyeds.begin(); - for ( ; idestroyed != destroyeds.end() ; idestroyed++ ) { - if ( lookup(*idestroyed) ) { - throw Error("Destroyed AutoSegment is associated with a TrackSegment\n" - " (%s)" - ,getString(*idestroyed).c_str()); + for ( ; idestroyed != destroyeds.end() ; ++idestroyed ) { + if (lookup(*idestroyed)) { + ltraceout(90); + throw Error( "Destroyed AutoSegment is associated with a TrackSegment\n" + " (%s)" + , getString(*idestroyed).c_str()); } } - size_t count = Katabatic::Session::_revalidate (); + size_t count = Katabatic::Session::_revalidate(); Interval span; - vector processeds; - const vector& revalidateds = getRevalidateds (); - const set& netsModificateds = getNetsModificateds (); + const vector& revalidateds = getRevalidateds(); + //const set& netsModificateds = getNetsModificateds(); - for ( size_t i=0 ; ibase() ); + for ( size_t i=0 ; iisCanonical()) continue; + + //Net* currentNet = NULL; + TrackElement* trackSegment = lookup( revalidateds[i] ); - if ( trackSegment && !trackSegment->isRevalidated() ) { - if ( trackSegment->getNet() != currentNet ) { - currentNet = trackSegment->getNet(); - invalidEvent = (netsModificateds.find(currentNet) != netsModificateds.end()); - } - trackSegment->revalidate ( invalidEvent ); - processeds.push_back ( trackSegment ); - - Track* track = trackSegment->getTrack(); - if ( track ) { - track->forceSort (); - _sortEvents.insert ( track ); - } + if (trackSegment and trackSegment->isInvalidated()) { + trackSegment->revalidate(); } } - for ( size_t i=0 ; isetRevalidated ( false ); + _doglegReset(); # if defined(CHECK_DATABASE) unsigned int overlaps = 0; # endif - for ( set::iterator it=_sortEvents.begin() - ; it != _sortEvents.end() - ; it++ - ) { - (*it)->sort (); + for ( set::iterator it=_sortEvents.begin() ; it!=_sortEvents.end() ; ++it ) { + (*it)->doReorder(); # if defined(CHECK_DATABASE) - (*it)->_check ( overlaps, "Session::_revalidate() - track sorting." ); + (*it)->check( overlaps, "Session::_revalidate() - track sorting." ); # endif } - set faileds; - for ( set::iterator inet=netsModificateds.begin() ; inet != netsModificateds.end() ; inet++ ) { - _getKiteEngine()->_computeCagedConstraints ( *inet, faileds ); - } - # if defined(CHECK_DATABASE) - for ( set::iterator it=packTracks.begin() ; it != packTracks.end() ; it++ ) - (*it)->_check ( overlaps, "Session::_revalidate() - on packed track." ); + for ( set::iterator it=packTracks.begin() ; it != packTracks.end() ; ++it ) + (*it)->check( overlaps, "Session::_revalidate() - on packed track." ); //_getKiteEngine()->_showOverlap (); # endif - _sortEvents.clear (); + _sortEvents.clear(); - if ( not faileds.empty() ) { +#if THIS_IS_DISABLED + if (not faileds.empty()) { set::iterator ifailed = faileds.begin(); Katabatic::GCellVector gcells; for ( ; ifailed != faileds.end() ; ++ifailed ) { (*ifailed)->getGCells ( gcells ); - (*ifailed)->makeDogLeg ( gcells[0] ); + (*ifailed)->makeDogLeg( gcells[0] ); } - count += _revalidate (); + count += _revalidate(); } +#endif + ltraceout(90); return count; } bool Session::_isEmpty () const { - if ( !_insertEvents.empty() || !_removeEvents.empty() || !_sortEvents.empty() ) { - cerr << Bug(" Session::checkEmpty() failed :\n" - " %u inserts, %u removes and %u sort events remains." + if ( not _insertEvents.empty() or not _removeEvents.empty() or not _sortEvents.empty() ) { + cerr << Bug( " Session::checkEmpty() failed :\n" + " %u inserts, %u removes and %u sort events remains." , _insertEvents.size() , _removeEvents.size() , _sortEvents .size() ) << endl; @@ -287,17 +245,13 @@ namespace Kite { void Session::_addInsertEvent ( TrackMarker* marker, Track* track ) { - _insertEvents.push_back ( Event(marker,track) ); - _addSortEvent ( track, true ); + _insertEvents.push_back( Event(marker,track) ); + _addSortEvent( track, true ); } void Session::_addInsertEvent ( TrackElement* segment, Track* track ) { -#if defined(CHECK_DETERMINISM) - cerr << "Order: Insert in @" << DbU::getValueString(track->getAxis()) - << " " << segment << endl; -#endif ltrace(200) << "addInsertEvent() " << segment << "\n @" << track << endl; @@ -311,46 +265,46 @@ namespace Kite { return; } - _insertEvents.push_back ( Event(segment,track) ); - _addSortEvent ( track, true ); + _insertEvents.push_back( Event(segment,track) ); + _addSortEvent( track, true ); } void Session::_addRemoveEvent ( TrackElement* segment ) { - if ( not segment->getTrack() ) { - cerr << Bug(" Kite::Session::addRemoveEvent() : %s is not in any Track." - ,getString(segment).c_str()) << endl; + if (not segment->getTrack()) { + cerr << Bug( " Kite::Session::addRemoveEvent() : %s is not in any Track." + , getString(segment).c_str() ) << endl; return; } ltrace(200) << "Ripup: @" << DbU::getValueString(segment->getAxis()) << " " << segment << endl; - _removeEvents.push_back ( Event(segment,segment->getTrack()) ); - _addSortEvent ( segment->getTrack(), true ); + _removeEvents.push_back( Event(segment,segment->getTrack()) ); + _addSortEvent( segment->getTrack(), true ); } void Session::_addMoveEvent ( TrackElement* segment, Track* track ) { - if ( !segment->getTrack() ) { - cerr << Bug(" Kite::Session::addMoveEvent() : %s has no target Track." - ,getString(segment).c_str()) << endl; + if (not segment->getTrack()) { + cerr << Bug( " Kite::Session::addMoveEvent() : %s has no target Track." + , getString(segment).c_str() ) << endl; return; } - _addRemoveEvent ( segment ); - _addInsertEvent ( segment, track ); + _addRemoveEvent( segment ); + _addInsertEvent( segment, track ); } void Session::_addSortEvent ( Track* track, bool forced ) { - if ( !track ) { - cerr << Bug(" Kite::Session::addSortEvent() : no Track to sort.") << endl; + if (not track ) { + cerr << Bug( " Kite::Session::addSortEvent() : no Track to sort." ) << endl; return; } - if ( forced ) track->forceSort (); - _sortEvents.insert ( track ); + if (forced) track->invalidate(); + _sortEvents.insert( track ); } @@ -361,10 +315,10 @@ namespace Kite { Record* Session::_getRecord () const { Record* record = Session::_getRecord (); - record->add ( getSlot ( "_sortEvents" , &_sortEvents ) ); + record->add( getSlot( "_sortEvents" , &_sortEvents ) ); return record; } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/Track.cpp b/kite/src/Track.cpp index 0e64b1f3..24436d37 100644 --- a/kite/src/Track.cpp +++ b/kite/src/Track.cpp @@ -2,14 +2,9 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 | // | | @@ -17,39 +12,32 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./Track.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ - - -#include -#include -#include -#include - -#include "hurricane/Warning.h" -#include "hurricane/Bug.h" -#include "hurricane/Layer.h" -#include "hurricane/Net.h" -#include "kite/RoutingPlane.h" -#include "kite/Track.h" -#include "kite/TrackMarker.h" -#include "kite/DataNegociate.h" +#include +#include +#include +#include +#include "hurricane/Warning.h" +#include "hurricane/Bug.h" +#include "hurricane/Layer.h" +#include "hurricane/Net.h" +#include "kite/RoutingPlane.h" +#include "kite/Track.h" +#include "kite/TrackMarker.h" +#include "kite/DataNegociate.h" namespace { - using namespace std; using namespace CRL; using namespace Kite; struct isDetachedSegment { - bool operator() ( const TrackElement* s ) { return !s->getTrack(); }; + bool operator() ( const TrackElement* s ) { return not s->getTrack(); }; }; @@ -57,12 +45,11 @@ namespace { { return (*(v.begin()+i))->getSourceU(); } -} // End of local namespace. +} // Anonymous namespace. namespace Kite { - using std::lower_bound; using std::remove_if; using std::sort; @@ -81,7 +68,7 @@ namespace Kite { // Class : "Track". - const size_t Track::NPOS = (size_t)-1; + const size_t Track::npos = (size_t)-1; Track::Track ( RoutingPlane* routingPlane, unsigned int index ) @@ -103,9 +90,7 @@ namespace Kite { Track::~Track () - { - ltrace(90) << "Track::~Track() - " << (void*)this << endl; - } + { ltrace(90) << "Track::~Track() - " << (void*)this << endl; } void Track::_preDestroy () @@ -114,10 +99,10 @@ namespace Kite { ltracein(90); for ( size_t i=0 ; i<_segments.size() ; i++ ) - if ( _segments[i] ) _segments[i]->detach(); + if (_segments[i]) _segments[i]->detach(); for ( size_t i=0 ; i<_markers.size() ; i++ ) - if ( _markers[i] ) _markers[i]->destroy(); + if (_markers[i]) _markers[i]->destroy(); ltraceout(90); } @@ -127,7 +112,7 @@ namespace Kite { { ltrace(90) << "Track::destroy() - " << (void*)this << " " << this << endl; - Track::_preDestroy (); + Track::_preDestroy(); delete this; } @@ -148,9 +133,20 @@ namespace Kite { { return _routingPlane->getBlockageLayer(); } + Track* Track::getNextTrack () const + { return getRoutingPlane()->getTrackByIndex( getIndex()+1 ); } + + + Track* Track::getPreviousTrack () const + { + if (not getIndex()) return NULL; + return getRoutingPlane()->getTrackByIndex( getIndex()-1 ); + } + + TrackElement* Track::getSegment ( size_t index ) const { - if ( (index == NPOS) || (index >= getSize()) ) return NULL; + if ( (index == npos) or (index >= getSize()) ) return NULL; return _segments[index]; } @@ -159,12 +155,9 @@ namespace Kite { { unsigned int state; size_t begin; - size_t end; - - getIBounds ( position, begin, end, state ); - - if ( state & (MinTrackMin|MaxTrackMax) ) return NULL; + getBeginIndex( position, begin, state ); + if (state & (BeginIsTrackMin|EndIsTrackMax)) return NULL; return getSegment(begin); } @@ -172,10 +165,10 @@ namespace Kite { TrackElement* Track::getNext ( size_t& index, Net* net ) const { for ( index++ ; index < _segments.size() ; index++ ) { - if ( _segments[index]->getNet() == net ) continue; + if (_segments[index]->getNet() == net) continue; return _segments[index]; } - index = NPOS; + index = npos; return NULL; } @@ -183,15 +176,15 @@ namespace Kite { TrackElement* Track::getPrevious ( size_t& index, Net* net ) const { - for ( index-- ; index != NPOS ; index-- ) { - if ( inltrace(148) ) { + for ( index-- ; index != npos ; index-- ) { + if (inltrace(148)) { cerr << tab << index << ":"; cerr.flush(); cerr << _segments[index] << endl; } - if ( _segments[index]->getNet() == net ) continue; + if (_segments[index]->getNet() == net) continue; return _segments[index]; } - index = NPOS; + index = npos; return NULL; } @@ -208,56 +201,59 @@ namespace Kite { } - void Track::getIBounds ( DbU::Unit position, size_t& begin, size_t& end, unsigned int& state ) const + void Track::getBeginIndex ( DbU::Unit position, size_t& begin, unsigned int& state ) const { - if ( _segments.empty() ) { + if (_segments.empty()) { state = EmptyTrack; - begin = end = 0; + begin = 0; return; } - if ( position < _min ) { - cerr << Warning ( " Position %s inferior to the lower bound of %s. Returning NPOS." - , DbU::getValueString(position).c_str() - , getString(this).c_str() ) << endl; - state = BeforeFirst; - begin = end = 0; + if (position < _min) { + cerr << Warning( " Position %s inferior to the lower bound of %s. Returning npos." + , DbU::getValueString(position).c_str() + , getString(this).c_str() ) << endl; + state = BeforeFirstElement; + begin = 0; return; } - if ( position > _max ) { - cerr << Warning ( " Position %s superior to the upper bound of %s. Returning NPOS." - , DbU::getValueString(position).c_str() - , getString(this).c_str() ) << endl; - state = AfterLast; - begin = end = _segments.size() - 1; + if (position > _max) { + cerr << Warning( " Position %s superior to the upper bound of %s. Returning npos." + , DbU::getValueString(position).c_str() + , getString(this).c_str() ) << endl; + state = AfterLastElement; + begin = _segments.size()-1; return; } vector::const_iterator lowerBound - = lower_bound ( _segments.begin(), _segments.end(), position, SourceCompare() ); - begin = end = lowerBound - _segments.begin(); + = lower_bound( _segments.begin(), _segments.end(), position, SourceCompare() ); + begin = lowerBound - _segments.begin(); - if ( begin < _segments.size() ) - for ( ; (begin > 0) && (_segments[begin-1]->getNet() == _segments[begin]->getNet()) ; --begin ); + // 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? + if (begin < _segments.size()) + for ( ; (begin > 0) and (_segments[begin-1]->getNet() == _segments[begin]->getNet()) ; --begin ); state = 0; - if ( (begin == 0) && (position < _segments[0]->getSourceU()) ) { - state = BeforeFirst; + if ( (begin == 0) and (position < _segments[0]->getSourceU()) ) { + state = BeforeFirstElement; } else { - if ( begin ) end = begin -= 1; + if (begin) begin -= 1; size_t usedBegin = begin; - size_t usedEnd = begin; - Interval usedInterval = expandUsedInterval ( usedBegin, usedEnd ); + Interval usedInterval = getOccupiedInterval( usedBegin ); - if ( position < usedInterval.getVMax() ) - state = Inside; + if (position < usedInterval.getVMax()) + state = InsideElement; else - if ( begin+1 == _segments.size() ) - state = AfterLast; + if (begin+1 == _segments.size()) + state = AfterLastElement; else - state = Outside; + state = OutsideElement; } } @@ -265,22 +261,20 @@ namespace Kite { void Track::getOverlapBounds ( Interval interval, size_t& begin, size_t& end ) const { unsigned int iState; - size_t iBegin; - size_t iEnd; - if ( _segments.empty() - || (interval.getVMax() <= _min) - || (interval.getVMin() >= _max)) { - begin = end = NPOS; + if ( _segments.empty() + or (interval.getVMax() <= _min) + or (interval.getVMin() >= _max)) { + begin = end = npos; return; } - getIBounds ( interval.getVMin(), begin, iEnd, iState ); - expandUsedInterval ( begin, iEnd ); + getBeginIndex ( interval.getVMin(), begin, iState ); + getOccupiedInterval( begin ); - getIBounds ( interval.getVMax(), iBegin, end, iState ); + getBeginIndex( interval.getVMax(), end, iState ); while ( end < _segments.size() ) { - if ( _segments[end++]->getSourceU() >= interval.getVMax() ) break; + if (_segments[end++]->getSourceU() >= interval.getVMax()) break; } } @@ -302,34 +296,32 @@ namespace Kite { ltracein(148); vector::const_iterator lowerBound - = lower_bound ( _markers.begin(), _markers.end(), interval.getVMin(), TrackMarker::Compare() ); + = lower_bound( _markers.begin(), _markers.end(), interval.getVMin(), TrackMarker::Compare() ); size_t mbegin = lowerBound - _markers.begin(); - for ( ; (mbegin < _markers.size()) - && (_markers[mbegin]->getSourceU() <= interval.getVMax()) ; mbegin++ ) { + for ( ; (mbegin < _markers.size()) + and (_markers[mbegin]->getSourceU() <= interval.getVMax()) ; mbegin++ ) { ltrace(148) << "| @" << DbU::getValueString(_axis) << _markers[mbegin] << endl; if ( _markers[mbegin]->getNet() != net ) { ltrace(148) << "* Mark: @" << DbU::getValueString(_axis) << " " << _markers[mbegin] << endl; - cost.incTerminals ( _markers[mbegin]->getWeight(this) ); + cost.incTerminals( _markers[mbegin]->getWeight(this) ); } } - if ( begin == NPOS ) { - ltrace(148) << " begin == NPOS (after last TrackElement)." << endl; + if (begin == npos) { + ltrace(148) << " begin == npos (after last TrackElement)." << endl; ltraceout(148); return cost; } for ( ; begin < end ; begin++ ) { - Interval overlap = interval.getIntersection ( _segments[begin]->getCanonicalInterval() ); - //if ( not overlap.isEmpty() ) { - if ( _segments[begin]->getNet() == net ) { - cost.incDeltaShared ( overlap.getSize() ); - } - ltrace(190) << "| overlap: " << _segments[begin] << endl; - _segments[begin]->incOverlapCost ( net, cost ); - if ( cost.isInfinite() ) break; - //} + Interval overlap = interval.getIntersection( _segments[begin]->getCanonicalInterval() ); + if ( _segments[begin]->getNet() == net ) { + cost.incDeltaShared ( overlap.getSize() ); + } + ltrace(190) << "| overlap: " << _segments[begin] << endl; + _segments[begin]->incOverlapCost( net, cost ); + if (cost.isInfinite()) break; } ltraceout(148); @@ -343,16 +335,14 @@ namespace Kite { size_t begin; size_t end; - getOverlapBounds ( interval, begin, end ); + getOverlapBounds( interval, begin, end ); - return getOverlapCost ( interval, net, begin, end, flags ); + return getOverlapCost( interval, net, begin, end, flags ); } TrackCost Track::getOverlapCost ( TrackElement* segment, unsigned int flags ) const - { - return getOverlapCost ( segment->getCanonicalInterval(), segment->getNet(), flags ); - } + { return getOverlapCost ( segment->getCanonicalInterval(), segment->getNet(), flags ); } void Track::getTerminalWeight ( Interval interval, Net* net, size_t& count, unsigned int& weight ) const @@ -381,39 +371,25 @@ namespace Kite { } - Track* Track::getNext () const - { - return getRoutingPlane()->getTrackByIndex ( getIndex()+1 ); - } - - - Track* Track::getPrevious () const - { - if ( !getIndex() ) return NULL; - - return getRoutingPlane()->getTrackByIndex ( getIndex()-1 ); - } - - size_t Track::find ( const TrackElement* segment ) const { - if ( !_segments.size() ) return NPOS; + if (_segments.empty()) return npos; vector::const_iterator lowerBound - = lower_bound ( _segments.begin() - , _segments.end() - , segment - , SegmentCompare() - ); + = lower_bound( _segments.begin() + , _segments.end() + , segment + , SegmentCompare() + ); - if ( lowerBound != _segments.end() ) { + if (lowerBound != _segments.end()) { while ( segment->getSourceU() == (*lowerBound)->getSourceU() ) { - if ( *lowerBound == segment ) return (size_t)(lowerBound-_segments.begin()); + if (*lowerBound == segment) return (size_t)(lowerBound-_segments.begin()); lowerBound++; } } - return NPOS; + return npos; } @@ -423,13 +399,14 @@ namespace Kite { size_t begin; size_t end; - if ( !_segments.size() ) return Interval(_min,_max); + if (_segments.empty()) return Interval(_min,_max); - getIBounds ( position, begin, end, state ); - if ( (state == Inside) && (_segments[begin]->getNet() != net) ) + getBeginIndex( position, begin, state ); + if ( (state == InsideElement) and (_segments[begin]->getNet() != net) ) return Interval(); - return expandFreeInterval ( begin, end, state, net ); + end = begin; + return expandFreeInterval( begin, end, state, net ); } @@ -437,37 +414,34 @@ namespace Kite { { DbU::Unit minFree = _min; - if ( !(state & MinTrackMin) ) { - if ( _segments[begin]->getNet() == net ) - getPrevious ( begin, net ); + if (not (state & BeginIsTrackMin) ) { + if (_segments[begin]->getNet() == net) + getPrevious( begin, net ); - if ( begin != NPOS ) { - size_t usedEnd; - minFree = expandUsedInterval ( begin, usedEnd ).getVMax(); + if (begin != npos) { + minFree = getOccupiedInterval(begin).getVMax(); } } - if ( !(state & MaxTrackMax) ) { - if ( _segments[end]->getNet() == net ) { - getNext ( end, net ); + if (not (state & EndIsTrackMax) ) { + if (_segments[end]->getNet() == net) { + getNext( end, net ); - if ( end == NPOS ) { + if (end == npos) { end = _segments.size() - 1; - setMaximalFlags ( state, MaxTrackMax ); + setMaximalFlags( state, EndIsTrackMax ); } else { - setMaximalFlags ( state, MaxSegmentMin ); + setMaximalFlags( state, EndIsSegmentMin ); } } } - return Interval ( minFree, getMaximalPosition(end,state) ); + return Interval( minFree, getMaximalPosition(end,state) ); } - void Track::forceSort () - { - _segmentsValid = false; - } + void Track::invalidate () + { _segmentsValid = false; } void Track::insert ( TrackMarker* marker ) @@ -499,54 +473,53 @@ namespace Kite { void Track::setSegment ( TrackElement* segment, size_t index ) { if ( index >= _segments.size() ) return; - _segments[index] = segment; } - bool Track::_check ( unsigned int& overlaps, const char* message ) const + bool Track::check ( unsigned int& overlaps, const char* message ) const { bool coherency = true; bool holes = false; - if ( message ) cerr << " o Checking Track - " << message << endl; - ltrace(90) << "[CHECK] " << (void*)this << ":" << this << endl; + if (message) cerr << " o Checking Track - " << message << endl; + ltrace(90) << (void*)this << ":" << this << endl; for ( size_t i=0 ; i<_segments.size() ; i++ ) { - if ( _segments[i] ) { - if ( i ) { - if ( _segments[i-1] == _segments[i] ) { + if (_segments[i]) { + if (i) { + if (_segments[i-1] == _segments[i]) { cerr << "[CHECK] incoherency at " << i << " " << _segments[i] << " is duplicated. " << endl; coherency = false; } } - if ( !_segments[i]->getTrack() ) { + if (not _segments[i]->getTrack()) { cerr << "[CHECK] incoherency at " << i << " " << _segments[i] << " is detached." << endl; coherency = false; } else { - if ( _segments[i]->getTrack() != this ) { + if (_segments[i]->getTrack() != this) { cerr << "[CHECK] incoherency at " << i << " " << _segments[i] << " is in track " << _segments[i]->getTrack() << endl; coherency = false; } - if ( _segments[i]->getIndex() != i ) { + if (_segments[i]->getIndex() != i) { cerr << "[CHECK] incoherency at " << i << " " << _segments[i] << " has bad index " << _segments[i]->getIndex() << endl; coherency = false; } } - if ( _segments[i]->getAxis() != getAxis() ) { + if (_segments[i]->getAxis() != getAxis()) { cerr << "[CHECK] incoherency at " << i << " " << _segments[i] << " is not on Track axis " << DbU::getValueString(getAxis()) << "." << endl; coherency = false; } - coherency = _segments[i]->_check () and coherency; + coherency = _segments[i]->_check() and coherency; } else { cerr << "[CHECK] Hole at position " << i << "." << endl; holes = true; @@ -554,7 +527,7 @@ namespace Kite { } } - if ( !holes ) + if (not holes) coherency = (checkOverlap(overlaps) == 0) and coherency; return coherency; @@ -563,7 +536,7 @@ namespace Kite { DbU::Unit Track::getSourcePosition ( size_t i ) const { - if ( i == NPOS) return 0; + if ( i == npos) return 0; return _segments[i]->getSourceU(); } @@ -581,14 +554,14 @@ namespace Kite { { Interval canonical; - switch ( state & MinMask ) { - case MinTrackMin: return _min; - case MinSegmentMin: return _segments[index]->getSourceU (); - case MinSegmentMax: return _segments[index]->getTargetU (); + switch ( state & BeginMask ) { + case BeginIsTrackMin: return _min; + case BeginIsSegmentMin: return _segments[index]->getSourceU (); + case BeginIsSegmentMax: return _segments[index]->getTargetU (); } - cerr << Bug ( " Track::getMinimalPosition(size_t,unsigned int) :" - " invalid state value %ud.", state ) << endl; + cerr << Bug( " Track::getMinimalPosition(size_t,unsigned int) :" + " invalid state value %ud.", state ) << endl; return _min; } @@ -598,104 +571,79 @@ namespace Kite { { Interval canonical; - switch ( state & MaxMask ) { - case MaxTrackMax: return _max; - case MaxSegmentMin: return _segments[index ]->getSourceU (); - case MaxNextSegmentMin: if ( index+1 >= getSize() ) return _max; - return _segments[index+1]->getSourceU (); - case MaxSegmentMax: return _segments[index ]->getTargetU (); + switch ( state & EndMask ) { + case EndIsTrackMax: return _max; + case EndIsSegmentMin: return _segments[index ]->getSourceU (); + case EndIsNextSegmentMin: if (index+1 >= getSize()) return _max; + return _segments[index+1]->getSourceU (); + case EndIsSegmentMax: return _segments[index ]->getTargetU (); } - cerr << Bug ( " Track::getMaximalPosition(size_t,unsigned int) :" - " invalid state value %ud.", state ) << endl; + cerr << Bug( " Track::getMaximalPosition(size_t,unsigned int) :" + " invalid state value %ud.", state ) << endl; return _min; } - Interval Track::expandUsedInterval ( size_t& begin, size_t& end ) const + Interval Track::getOccupiedInterval ( size_t& begin ) const { - if ( begin == NPOS ) return Interval(); + if (begin == npos) return Interval(); size_t seed = begin; Net* owner = _segments[seed]->getNet(); - Interval expandInterval; - Interval ownerInterval; - _segments[seed]->getCanonical ( ownerInterval ); + Interval segmentInterval; + Interval mergedInterval; + _segments[seed]->getCanonical( mergedInterval ); size_t i = seed; - while ( --i != NPOS ) { - if ( _segments[i]->getNet() != owner ) break; + while ( --i != npos ) { + if (_segments[i]->getNet() != owner) break; - _segments[i]->getCanonical ( expandInterval ); - if ( expandInterval.getVMax() >= ownerInterval.getVMin() ) { - ownerInterval.merge ( expandInterval ); + _segments[i]->getCanonical ( segmentInterval ); + if (segmentInterval.getVMax() >= mergedInterval.getVMin()) { + mergedInterval.merge( segmentInterval ); begin = i; } } - end = i = seed; + i = seed; while ( ++i < _segments.size() ) { - if ( _segments[i]->getNet() != owner ) break; + if (_segments[i]->getNet() != owner) break; - _segments[i]->getCanonical ( expandInterval ); - if ( expandInterval.getVMin() > ownerInterval.getVMax() ) break; - if ( expandInterval.getVMax() > ownerInterval.getVMax() ) end = i; + _segments[i]->getCanonical( segmentInterval ); + if (segmentInterval.getVMin() > mergedInterval.getVMax()) break; - ownerInterval.merge ( expandInterval ); + mergedInterval.merge( segmentInterval ); } - return ownerInterval; + return mergedInterval; } - size_t Track::pack () + size_t Track::doRemoval () { - ltrace(148) << "Track::pack() - " << this << endl; + ltrace(148) << "Track::doRemoval() - " << this << endl; ltracein(148); size_t size = _segments.size(); vector::iterator beginRemove - = remove_if ( _segments.begin(), _segments.end(), isDetachedSegment() ); + = remove_if( _segments.begin(), _segments.end(), isDetachedSegment() ); - _segments.erase ( beginRemove, _segments.end() ); + _segments.erase( beginRemove, _segments.end() ); -# if 0 - size_t first = 0; - size_t last = 0; - bool erase = false; - - while ( last < _segments.size() ) { - if ( _segments[last] ) { - if ( erase ) { - _segments.erase ( _segments.begin()+first, _segments.begin()+last ); - - erase = false; - last = first; - } else { - first = last; - } - } else { - erase = true; - } - } - - if ( erase ) - _segments.erase ( _segments.begin()+first, _segments.end() ); -# endif - - ltrace(148) << "After packing " << this << endl; + ltrace(148) << "After doRemoval " << this << endl; ltraceout(148); return size - _segments.size(); } - void Track::sort () + void Track::doReorder () { - if ( !_segmentsValid ) { + if (not _segmentsValid ) { std::sort ( _segments.begin(), _segments.end(), SegmentCompare() ); for ( size_t i=0 ; i < _segments.size() ; i++ ) { _segments[i]->setIndex ( i ); @@ -703,7 +651,7 @@ namespace Kite { _segmentsValid = true; } - if ( !_markersValid ) { + if (not _markersValid ) { std::sort ( _markers.begin(), _markers.end(), TrackMarker::Compare() ); _markersValid = true; } @@ -719,10 +667,10 @@ namespace Kite { if ( _segments[i]->getNet() == _segments[i+1]->getNet() ) { if ( _segments[i]->getSourceU() == _segments[i+1]->getSourceU() ) { if ( _segments[i]->getTargetU() < _segments[i+1]->getTargetU() ) { - cerr << Warning(" Invalid sorting length order in %s:\n%s \n%s " - ,getString(this).c_str() - ,getString(_segments[i ]).c_str() - ,getString(_segments[i+1]).c_str()) << endl; + cerr << Error(" Invalid sorting length order in %s:\n%s \n%s " + ,getString(this).c_str() + ,getString(_segments[i ]).c_str() + ,getString(_segments[i+1]).c_str()) << endl; } } for ( j=i+1 ; (j<_segments.size()) && (_segments[i]->getNet() == _segments[j]->getNet()) ; j++ ); @@ -732,10 +680,10 @@ namespace Kite { if ( (j<_segments.size()) && (_segments[i]->getTargetU() > _segments[j]->getSourceU()) ) { - cerr << Warning("Overlap in %s between:\n %s\n %s" - ,getString(this).c_str() - ,getString(_segments[i]).c_str() - ,getString(_segments[j]).c_str()) << endl; + cerr << Error("Overlap in %s between:\n %s\n %s" + ,getString(this).c_str() + ,getString(_segments[i]).c_str() + ,getString(_segments[j]).c_str()) << endl; overlaps++; } } @@ -760,13 +708,13 @@ namespace Kite { Record* Track::_getRecord () const { Record* record = new Record ( _getString() ); - record->add ( getSlot ( "_routingPlane", _routingPlane ) ); - record->add ( getSlot ( "_index" , &_index ) ); + record->add ( getSlot ( "_routingPlane", _routingPlane ) ); + record->add ( getSlot ( "_index" , &_index ) ); record->add ( DbU::getValueSlot ( "_axis" , &_axis ) ); - record->add ( getSlot ( "_segments" , &_segments ) ); + record->add ( getSlot ( "_segments" , &_segments ) ); return record; } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/TrackCost.cpp b/kite/src/TrackCost.cpp index 8b116903..b3eb0a7d 100644 --- a/kite/src/TrackCost.cpp +++ b/kite/src/TrackCost.cpp @@ -2,14 +2,9 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 | // | | @@ -17,28 +12,19 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./TrackCost.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x - - - - -#include -#include -#include - -#include "kite/Track.h" -#include "kite/TrackCost.h" -#include "kite/Session.h" +// +-----------------------------------------------------------------+ +#include +#include +#include +#include "kite/Track.h" +#include "kite/TrackCost.h" +#include "kite/Session.h" namespace Kite { - using std::cerr; using std::endl; @@ -46,7 +32,6 @@ namespace Kite { // ------------------------------------------------------------------- // Class : "TrackCost". - TrackCost::TrackCost ( Track* track , const Interval& interval , size_t begin @@ -79,7 +64,7 @@ namespace Kite { , _ripupCount (0) { TrackElement* neighbor; - if ( _begin != Track::NPOS ) { + if ( _begin != Track::npos ) { neighbor = _track->getSegment(_begin); if ( neighbor and (neighbor->getNet() != net) ) { DbU::Unit distance = interval.getVMin() - neighbor->getTargetU(); @@ -91,7 +76,7 @@ namespace Kite { // _distanceToFixed += interval.getVMin() - neighbor->getTargetU(); // } } - if ( _end != Track::NPOS ) { + if ( _end != Track::npos ) { neighbor = _track->getSegment(_end); if ( neighbor and (neighbor->getNet() != net) ) { DbU::Unit distance = neighbor->getSourceU() - interval.getVMax(); @@ -190,6 +175,7 @@ namespace Kite { s += "+" + getString(_ripupCount); s += ":" + getString((_dataState<<2)+_ripupCount); s += " " + string ( (_blockage )?"b":"-" ); + s += string ( (_blockage )?"f":"-" ); s += string ( (_hardOverlap )?"h":"-" ); s += string ( (_overlap )?"o":"-" ); s += string ( (_overlapGlobal )?"g":"-" ); @@ -210,17 +196,22 @@ namespace Kite { Record* TrackCost::_getRecord () const { Record* record = new Record ( _getString() ); - record->add ( getSlot ( "_track" , _track ) ); - record->add ( getSlot ( "_begin" , &_begin ) ); - record->add ( getSlot ( "_end" , &_end ) ); - record->add ( getSlot ( "_interval" , &_interval ) ); - record->add ( getSlot ( "_infinite" , _infinite ) ); - record->add ( getSlot ( "_overlap" , _overlap ) ); - record->add ( getSlot ( "_terminals", _terminals ) ); - record->add ( getSlot ( "_delta" , &_delta ) ); + record->add( getSlot ( "_track" , _track ) ); + record->add( getSlot ( "_begin" , &_begin ) ); + record->add( getSlot ( "_end" , &_end ) ); + record->add( getSlot ( "_interval" , &_interval ) ); + record->add( getSlot ( "_infinite" , _infinite ) ); + record->add( getSlot ( "_overlap" , _overlap ) ); + record->add( getSlot ( "_terminals" , _terminals ) ); + record->add( DbU::getValueSlot( "_delta" , &_delta ) ); + record->add( DbU::getValueSlot( "_deltaShared" , &_deltaShared ) ); + record->add( DbU::getValueSlot( "_deltaPerpand" , &_deltaPerpand ) ); + record->add( DbU::getValueSlot( "_axisWeight" , &_axisWeight ) ); + record->add( DbU::getValueSlot( "_distanceToFixed", &_distanceToFixed ) ); + record->add( DbU::getValueSlot( "_longuestOverlap", &_longuestOverlap ) ); return record; } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/TrackElement.cpp b/kite/src/TrackElement.cpp index 8aa4ecd1..d16d5097 100644 --- a/kite/src/TrackElement.cpp +++ b/kite/src/TrackElement.cpp @@ -2,14 +2,9 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 | // | | @@ -17,60 +12,51 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./TrackElement.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ - - -#include -#include - -#include "hurricane/Bug.h" -#include "hurricane/Warning.h" -#include "hurricane/Net.h" -#include "hurricane/Name.h" -#include "katabatic/AutoContact.h" -#include "katabatic/GCell.h" -#include "crlcore/RoutingGauge.h" -#include "kite/DataNegociate.h" -#include "kite/TrackElement.h" -#include "kite/TrackCost.h" -#include "kite/Track.h" -#include "kite/Session.h" -#include "kite/RoutingEvent.h" -#include "kite/NegociateWindow.h" - +#include +#include +#include "hurricane/Bug.h" +#include "hurricane/Warning.h" +#include "hurricane/Net.h" +#include "hurricane/Name.h" +#include "katabatic/AutoContact.h" +#include "katabatic/GCell.h" +#include "crlcore/RoutingGauge.h" +#include "kite/DataNegociate.h" +#include "kite/TrackElement.h" +#include "kite/TrackCost.h" +#include "kite/Track.h" +#include "kite/Session.h" +#include "kite/RoutingEvent.h" +#include "kite/NegociateWindow.h" namespace { - using namespace std; using namespace Hurricane; using namespace CRL; using namespace Kite; - // --------------------------------------------------------------- - // Function : "DummyOverlapCost ()". - - - void DummyOverlapCost ( const TrackElement* segment, TrackCost& cost ) + void dummyOverlapCost ( const TrackElement* segment, TrackCost& cost ) { cerr << Warning("No overlapCost callback has been set (%s)." ,getString(segment).c_str()) << endl; } -} // End of local namespace. +} // Anonymous namespace. namespace Kite { - + using Hurricane::inltrace; + using Hurricane::ltracein; + using Hurricane::ltraceout; + using Hurricane::tab; using Hurricane::Bug; using Hurricane::Net; using Hurricane::Name; @@ -78,144 +64,141 @@ namespace Kite { // ------------------------------------------------------------------- -// Class : "TrackElement::Compare". - - - bool TrackElement::Compare::operator() ( TrackElement* lhs, TrackElement* rhs ) - { - return lhs->getArea() > rhs->getArea(); - } - - -// ------------------------------------------------------------------- -// Class : "TrackElement::CompareByPosition". +// Comparison Classes. // // Return: lhs < rhs. - bool TrackElement::CompareByPosition::operator() ( const TrackElement* lhs, const TrackElement* rhs ) const + bool Compare::operator() ( TrackElement* lhs, TrackElement* rhs ) + { return lhs->getFreedomDegree() > rhs->getFreedomDegree(); } + + + bool CompareByPosition::operator() ( const TrackElement* lhs, const TrackElement* rhs ) const { - if ( lhs == rhs ) return false; + if (lhs == rhs) return false; - if ( lhs->isBlockage() xor rhs->isBlockage() ) - return lhs->isBlockage(); + if (lhs->isBlockage() xor rhs->isBlockage()) return lhs->isBlockage(); - if ( lhs->getLength() < rhs->getLength() ) return true; - if ( lhs->getLength() > rhs->getLength() ) return false; + if (lhs->getLength() < rhs->getLength()) return true; + if (lhs->getLength() > rhs->getLength()) return false; - if ( lhs->isHorizontal() xor rhs->isHorizontal() ) - return rhs->isHorizontal(); + if (lhs->isHorizontal() xor rhs->isHorizontal()) return rhs->isHorizontal(); - if ( lhs->getAxis() > rhs->getAxis() ) return true; - if ( lhs->getAxis() < rhs->getAxis() ) return false; + if (lhs->getAxis() > rhs->getAxis()) return true; + if (lhs->getAxis() < rhs->getAxis()) return false; - if ( lhs->getSourceU() > rhs->getSourceU() ) return true; - if ( lhs->getSourceU() < rhs->getSourceU() ) return false; + if (lhs->getSourceU() > rhs->getSourceU()) return true; + if (lhs->getSourceU() < rhs->getSourceU()) return false; - if ( lhs->isBlockage() and rhs->isBlockage() ) return false; + if (lhs->isBlockage() and rhs->isBlockage()) return false; - //return lhs->getNet()->getName() < rhs->getNet()->getName(); return lhs->getId() < rhs->getId(); } +// ------------------------------------------------------------------- +// Class : "SegmentObserver". + + + void SegmentObserver::notify ( unsigned int flags ) + { + TrackElement* segment = getOwner(); + switch ( flags ) { + case AutoSegment::Invalidate: + if (not segment->isInvalidated()) { + ltrace(200) << "::notify() on " << segment << endl; + segment->invalidate(); + } + break; + case AutoSegment::Revalidate: + // Revalidation must be delayed until *all* the AutoSegments have been revalidated. + // if (segment->isInvalidated()) { + // ltrace(200) << "::notify() on " << segment << endl; + // segment->revalidate( true ); + // } + break; + } + } + + // ------------------------------------------------------------------- // Class : "TrackElement". - SegmentOverlapCostCB* TrackElement::_overlapCostCallback = DummyOverlapCost; + SegmentOverlapCostCB* TrackElement::_overlapCostCallback = dummyOverlapCost; SegmentOverlapCostCB* TrackElement::setOverlapCostCB ( SegmentOverlapCostCB* cb ) { SegmentOverlapCostCB* oldCb = _overlapCostCallback; - _overlapCostCallback = cb; - return oldCb; } -// Former inline functions. - AutoSegment* TrackElement::base () const { return NULL; } - bool TrackElement::isBipoint () const { return false; } - bool TrackElement::isCreated () const { return false; } - bool TrackElement::isFixed () const { return false; } - bool TrackElement::isBlockage () const { return false; } - bool TrackElement::isStrap () const { return false; } - bool TrackElement::isSlackenStrap () const { return false; } - bool TrackElement::isLocal () const { return true; } - bool TrackElement::isGlobal () const { return not isLocal(); } - bool TrackElement::isLocked () const { return false; } - bool TrackElement::isTerminal () const { return false; } - bool TrackElement::isDogleg () const { return false; } - bool TrackElement::isRevalidated () const { return false; } - bool TrackElement::isRouted () const { return true; } - bool TrackElement::isSlackened () const { return false; } - bool TrackElement::isSlackenDogLeg () const { return false; } - bool TrackElement::hasSourceDogLeg () const { return false; } - bool TrackElement::hasTargetDogLeg () const { return false; } - bool TrackElement::allowOutsideGCell () const { return false; } - bool TrackElement::canGoOutsideGCell () const { return false; } - bool TrackElement::canRipple () const { return false; } - unsigned long TrackElement::getId () const { return 0; } - unsigned long TrackElement::getArea () const { return 0; } - unsigned int TrackElement::getDogLegLevel () const { return 0; } - unsigned int TrackElement::getDogLegOrder () const { return 0; } - Interval TrackElement::getSourceConstraints () const { return Interval(); } - Interval TrackElement::getTargetConstraints () const { return Interval(); } - DataNegociate* TrackElement::getDataNegociate ( unsigned int ) const { return NULL; } - TrackElements TrackElement::getCollapsedPerpandiculars () { return new TrackElements_CollapsedPerpandicular(NULL); } - void TrackElement::setAllowOutsideGCell ( bool ) { } - void TrackElement::setLock ( bool ) { } - void TrackElement::setRevalidated ( bool ) { } - void TrackElement::invalidate () { } - void TrackElement::setCanRipple ( bool ) { } - void TrackElement::setSourceDogLeg ( bool ) { } - void TrackElement::setTargetDogLeg ( bool ) { } - TrackElement* TrackElement::getCanonical ( Interval& i ) { i=Interval(getSourceU(),getTargetU()); return this; } - bool TrackElement::canSlacken () const { return false; } - - - bool TrackElement::canDesalignate () const { return false; } - bool TrackElement::canPivotUp ( float ) const { return false; }; - bool TrackElement::canPivotDown ( float ) const { return false; }; - bool TrackElement::canMoveUp ( float, unsigned int ) const { return false; }; - float TrackElement::getMaxUnderDensity ( unsigned int ) const { return 0.0; }; - bool TrackElement::canDogLeg () { return false; }; - bool TrackElement::canDogLeg ( Interval ) { return false; }; - bool TrackElement::canDogLegAt ( Katabatic::GCell*, unsigned int ) { return false; }; - TrackElement* TrackElement::getSourceDogLeg () { return NULL; } - TrackElement* TrackElement::getTargetDogLeg () { return NULL; } - TrackElement* TrackElement::getParent () const { return NULL; } - void TrackElement::dataInvalidate () { } - void TrackElement::eventInvalidate () { } - void TrackElement::setArea () { } - void TrackElement::setRouted ( bool ) { } - void TrackElement::setTrack ( Track* track ) { _track = track; } - void TrackElement::setDogLegLevel ( unsigned int ) { } - void TrackElement::setDogLegOrder ( unsigned int ) { } - void TrackElement::swapTrack ( TrackElement* ) { } - void TrackElement::reschedule ( unsigned int ) { } - void TrackElement::detach () { } - void TrackElement::revalidate ( bool invalidEvent ) { } - void TrackElement::setAxis ( DbU::Unit, unsigned int flags ) { } - void TrackElement::slacken () { } - bool TrackElement::moveUp ( unsigned int ) { return false; } - bool TrackElement::moveDown ( unsigned int ) { return false; } - bool TrackElement::moveAside ( bool onLeft ) { return false; } - TrackElement* TrackElement::makeDogLeg () { return NULL; } - TrackElement* TrackElement::makeDogLeg ( Interval, bool& leftDogleg ) { return NULL; } - TrackElement* TrackElement::makeDogLeg ( Katabatic::GCell* ) { return NULL; } - TrackElement* TrackElement::_postDogLeg ( Katabatic::GCell* ) { return NULL; } - void TrackElement::_postModify () { } - void TrackElement::desalignate () { } - bool TrackElement::_check () const { return true; } +// Wrapped AutoSegment Functions. + AutoSegment* TrackElement::base () const { return NULL; } + bool TrackElement::isFixed () const { return false; } + bool TrackElement::isLocal () const { return true; } + bool TrackElement::isGlobal () const { return not isLocal(); } + bool TrackElement::isBipoint () const { return false; } + bool TrackElement::isTerminal () const { return false; } + bool TrackElement::isStrongTerminal ( unsigned int ) const { return false; } + bool TrackElement::isStrap () const { return false; } + bool TrackElement::isSlackened () const { return false; } + bool TrackElement::isDogleg () const { return false; } +// Predicates. + bool TrackElement::canSlacken () const { return false; } + bool TrackElement::canPivotUp ( float ) const { return false; }; + bool TrackElement::canPivotDown ( float ) const { return false; }; + bool TrackElement::canMoveUp ( float, unsigned int ) const { return false; }; + bool TrackElement::canDogleg () { return false; }; + bool TrackElement::canDogleg ( Interval ) { return false; }; + bool TrackElement::canDogleg ( Katabatic::GCell*, unsigned int ) { return false; }; +// Accessors. + unsigned long TrackElement::getId () const { return 0; } + unsigned long TrackElement::getFreedomDegree () const { return 0; } + float TrackElement::getMaxUnderDensity ( unsigned int ) const { return 0.0; }; + unsigned int TrackElement::getDoglegLevel () const { return 0; } + TrackElement* TrackElement::getParent () const { return NULL; } + Interval TrackElement::getSourceConstraints () const { return Interval(); } + Interval TrackElement::getTargetConstraints () const { return Interval(); } + DataNegociate* TrackElement::getDataNegociate ( unsigned int ) const { return NULL; } + TrackElements TrackElement::getPerpandiculars () { return new TrackElements_Perpandiculars(NULL); } + void TrackElement::invalidate () { } + TrackElement* TrackElement::getCanonical ( Interval& i ) { i=Interval(getSourceU(),getTargetU()); return this; } + TrackElement* TrackElement::getSourceDogleg () { return NULL; } + TrackElement* TrackElement::getTargetDogleg () { return NULL; } +// Mutators. + void TrackElement::setTrack ( Track* track ) { _track = track; } + void TrackElement::updateFreedomDegree () { } + void TrackElement::setDoglegLevel ( unsigned int ) { } + void TrackElement::swapTrack ( TrackElement* ) { } + void TrackElement::reschedule ( unsigned int ) { } + void TrackElement::detach () { } + void TrackElement::revalidate () { } + void TrackElement::setAxis ( DbU::Unit, unsigned int flags ) { } + TrackElement* TrackElement::makeDogleg () { return NULL; } + TrackElement* TrackElement::makeDogleg ( Interval, unsigned int& ) { return NULL; } + TrackElement* TrackElement::makeDogleg ( Katabatic::GCell*, TrackElement*&, TrackElement*& ) { return NULL; } + void TrackElement::_postDoglegs ( TrackElement*&, TrackElement*& ) { } + bool TrackElement::moveAside ( unsigned int ) { return false; } + bool TrackElement::slacken ( unsigned int ) { return false; } + bool TrackElement::moveUp ( unsigned int ) { return false; } + bool TrackElement::moveDown ( unsigned int ) { return false; } +#if THIS_IS_DISABLED + void TrackElement::desalignate () { } +#endif + bool TrackElement::_check () const { return true; } TrackElement::TrackElement ( Track* track ) - : _track(track) - , _index((size_t)-1) + : _flags (0) + , _track (track) + , _index ((size_t)-1) + , _sourceU (0) + , _targetU (0) + , _observer(this) { } @@ -241,50 +224,38 @@ namespace Kite { TrackElement* TrackElement::getNext () const { size_t dummy = _index; - return _track->getNext ( dummy, getNet() ); + return _track->getNext( dummy, getNet() ); } TrackElement* TrackElement::getPrevious () const { size_t dummy = _index; - return _track->getPrevious ( dummy, getNet() ); + return _track->getPrevious( dummy, getNet() ); } Interval TrackElement::getFreeInterval () const { - if ( !_track ) return Interval(false); + if (not _track) return Interval(false); size_t begin = _index; size_t end = _index; - return _track->expandFreeInterval ( begin, end, Track::Inside, getNet() ); + return _track->expandFreeInterval( begin, end, Track::InsideElement, getNet() ); } - size_t TrackElement::getGCells ( vector& gcells ) const + size_t TrackElement::getGCells ( Katabatic::GCellVector& gcells ) const { - vector().swap ( gcells ); + vector().swap( gcells ); return gcells.size(); } - size_t TrackElement::getPerpandicularsBound ( set& bounds ) - { - bounds.clear (); - return 0; - } - - - unsigned int TrackElement::getOrder () const - { return numeric_limits::max(); } - - void TrackElement::incOverlapCost ( Net* net, TrackCost& cost ) const { - if ( not _track or (getNet() == net) ) return; - - _overlapCostCallback ( this, cost ); + if (not _track or (getNet() == net)) return; + _overlapCostCallback( this, cost ); } @@ -293,17 +264,20 @@ namespace Kite { string TrackElement::_getString () const - { return "<" + _getTypeName() + ">"; } + { return "<"+_getTypeName()+">"; } Record* TrackElement::_getRecord () const { - Record* record = new Record ( _getString() ); - record->add ( getSlot ( "_track", _track ) ); - record->add ( getSlot ( "_index", _index ) ); + Record* record = new Record( _getString() ); + record->add( getSlot( "_flags", _track ) ); + record->add( getSlot( "_track", _track ) ); + record->add( getSlot( "_index", _index ) ); + record->add( DbU::getValueSlot( "_sourceU", &_sourceU ) ); + record->add( DbU::getValueSlot( "_targetU", &_targetU ) ); return record; } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/TrackElements.cpp b/kite/src/TrackElements.cpp index 297f8f30..3ef8d438 100644 --- a/kite/src/TrackElements.cpp +++ b/kite/src/TrackElements.cpp @@ -2,14 +2,9 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 | // | | @@ -17,10 +12,7 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./TrackElements.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ #include "hurricane/Bug.h" @@ -31,7 +23,6 @@ namespace Kite { - using namespace std; using Hurricane::tab; using Hurricane::inltrace; @@ -43,20 +34,20 @@ namespace Kite { // ------------------------------------------------------------------- -// Class : "TrackElements_CollapsedPerpandicular". +// Class : "TrackElements_Perpandiculars". - TrackElements_CollapsedPerpandicular::Locator::Locator ( TrackElement* segment ) + TrackElements_Perpandiculars::Locator::Locator ( TrackElement* segment ) : TrackElementHL () , _locator (segment->base()) , _element (NULL) { - ltrace(80) << "TrackElements_CollapsedPerpandicular::Locator::Locator()" << endl; + ltrace(80) << "TrackElements_Perpandiculars::Locator::Locator()" << endl; ltrace(80) << " " << segment << endl; Interval bounds; if ( _locator.isValid() ) { - _element = Session::lookup ( _locator.getElement()->getCanonical(bounds)->base() ); + _element = Session::lookup( _locator.getElement()->getCanonical(bounds)->base() ); if ( !_element ) { cerr << Bug("Canonical segment without TrackElement.") << endl; progress (); @@ -65,20 +56,20 @@ namespace Kite { } - TrackElement* TrackElements_CollapsedPerpandicular::Locator::getElement () const + TrackElement* TrackElements_Perpandiculars::Locator::getElement () const { return _element; } - void TrackElements_CollapsedPerpandicular::Locator::progress () + void TrackElements_Perpandiculars::Locator::progress () { - ltrace(80) << "TrackElements_CollapsedPerpandicular::Locator::progress()" << endl; + ltrace(80) << "TrackElements_Perpandiculars::Locator::progress()" << endl; Interval bounds; while ( _locator.isValid() ) { _locator.progress (); if ( _locator.isValid() ) { - _element = Session::lookup ( _locator.getElement()->getCanonical(bounds)->base() ); + _element = Session::lookup( _locator.getElement()->getCanonical(bounds)->base() ); if ( !_element ) { cerr << Bug("Canonical segment whithout TrackElement.") << endl; continue; @@ -90,32 +81,32 @@ namespace Kite { } - TrackElementHL* TrackElements_CollapsedPerpandicular::Locator::getClone () const + TrackElementHL* TrackElements_Perpandiculars::Locator::getClone () const { return new Locator(*this); } - bool TrackElements_CollapsedPerpandicular::Locator::isValid () const + bool TrackElements_Perpandiculars::Locator::isValid () const { return _locator.isValid(); } - TrackElementHC* TrackElements_CollapsedPerpandicular::getClone () const - { return new TrackElements_CollapsedPerpandicular(*this); } + TrackElementHC* TrackElements_Perpandiculars::getClone () const + { return new TrackElements_Perpandiculars(*this); } - TrackElementHL* TrackElements_CollapsedPerpandicular::getLocator () const + TrackElementHL* TrackElements_Perpandiculars::getLocator () const { return new Locator(_segment); } - string TrackElements_CollapsedPerpandicular::Locator::_getString () const + string TrackElements_Perpandiculars::Locator::_getString () const { - string s = ""; + string s = ""; return s; } - string TrackElements_CollapsedPerpandicular::_getString () const + string TrackElements_Perpandiculars::_getString () const { - string s = ""; return s; @@ -132,8 +123,8 @@ namespace Kite { bool TrackElements_UniqCanonical::accept ( TrackElement* segment ) const { - if ( _canonicals.find(segment) == _canonicals.end() ) { - _canonicals.insert ( segment ); + if (_canonicals.find(segment) == _canonicals.end()) { + _canonicals.insert( segment ); return true; } @@ -145,4 +136,4 @@ namespace Kite { { return ""; } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/TrackFixedSegment.cpp b/kite/src/TrackFixedSegment.cpp index 7bf569c1..116536a9 100644 --- a/kite/src/TrackFixedSegment.cpp +++ b/kite/src/TrackFixedSegment.cpp @@ -2,14 +2,9 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 | // | | @@ -17,41 +12,34 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./TrackFixedSegment.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ - - -#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 "katabatic/AutoContact.h" -#include "katabatic/GCellGrid.h" -#include "crlcore/RoutingGauge.h" -#include "kite/DataNegociate.h" -#include "kite/TrackFixedSegment.h" -#include "kite/TrackCost.h" -#include "kite/Track.h" -#include "kite/Session.h" -#include "kite/RoutingEvent.h" -#include "kite/NegociateWindow.h" -#include "kite/KiteEngine.h" +#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 "katabatic/AutoContact.h" +#include "katabatic/GCellGrid.h" +#include "crlcore/RoutingGauge.h" +#include "kite/DataNegociate.h" +#include "kite/TrackFixedSegment.h" +#include "kite/TrackCost.h" +#include "kite/Track.h" +#include "kite/Session.h" +#include "kite/RoutingEvent.h" +#include "kite/NegociateWindow.h" +#include "kite/KiteEngine.h" namespace Kite { - using namespace std; using Hurricane::inltrace; using Hurricane::ltracein; @@ -80,79 +68,81 @@ namespace Kite { TrackFixedSegment::TrackFixedSegment ( Track* track, Segment* segment ) : TrackElement (NULL) , _segment (segment) - , _isBlockage (segment->getNet() == _blockageNet) { Box boundingBox = segment->getBoundingBox(); - if ( track ) { + unsigned int flags = TElemFixed | ((segment->getNet() == _blockageNet) ? TElemBlockage : 0); + setFlags( flags ); + + if (track) { unsigned int depth = track->getDepth(); Technology* technology = DataBase::getDB()->getTechnology(); const Layer* layer1 = track->getLayer()->getBlockageLayer(); RegularLayer* layer2 = dynamic_cast(technology->getLayer(layer1->getMask())); if ( layer2 ) { //DbU::Unit extention = layer2->getExtentionCap(); - if ( track->getDirection() == Constant::Horizontal ) { - Interval uside = track->getKiteEngine()->getGCellGrid()->getUSide ( Constant::Horizontal ); + if (track->getDirection() == KbHorizontal) { + Interval uside = track->getKiteEngine()->getGCellGrid()->getUSide( KbHorizontal ); - _sourceU = max ( boundingBox.getXMin(), uside.getVMin()); - _targetU = min ( boundingBox.getXMax(), uside.getVMax()); + _sourceU = max( boundingBox.getXMin(), uside.getVMin()); + _targetU = min( boundingBox.getXMax(), uside.getVMax()); - Katabatic::GCell* gcell = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(_sourceU,track->getAxis()) ); - Katabatic::GCell* end = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(_targetU,track->getAxis()) ); + Katabatic::GCell* gcell = track->getKiteEngine()->getGCellGrid()->getGCell( Point(_sourceU,track->getAxis()) ); + Katabatic::GCell* end = track->getKiteEngine()->getGCellGrid()->getGCell( Point(_targetU,track->getAxis()) ); Katabatic::GCell* right = NULL; - Interval guside = gcell->getUSide ( Constant::Horizontal /*, true*/ ); + Interval guside = gcell->getSide( KbHorizontal ); Interval segside ( boundingBox.getXMin(), boundingBox.getXMax() ); - if ( gcell ) { + if (gcell) { while ( gcell and (gcell != end) ) { right = gcell->getRight(); - if ( right == NULL ) break; + if (right == NULL) break; - guside = gcell->getUSide ( Constant::Horizontal /*, true*/ ); - Interval usedLength = guside.getIntersection ( segside ); + guside = gcell->getSide( KbHorizontal ); + Interval usedLength = guside.getIntersection( segside ); - gcell->addBlockage ( depth, usedLength.getSize() ); - //gcell->addBlockedAxis ( depth, track->getAxis() ); + gcell->addBlockage ( depth, usedLength.getSize() ); + //gcell->addBlockedAxis( depth, track->getAxis() ); gcell = right; } - if ( end ) { - guside = gcell->getUSide ( Constant::Horizontal /*, true*/ ); - Interval usedLength = guside.getIntersection ( segside ); + if (end) { + guside = gcell->getSide( KbHorizontal ); + Interval usedLength = guside.getIntersection( segside ); - end->addBlockage ( depth, usedLength.getSize() ); - //end->addBlockedAxis ( depth, track->getAxis() ); + end->addBlockage ( depth, usedLength.getSize() ); + //end->addBlockedAxis( depth, track->getAxis() ); } } else cerr << Warning("TrackFixedSegment(): TrackFixedElement outside GCell grid.") << endl; } else { - Interval uside = track->getKiteEngine()->getGCellGrid()->getUSide ( Constant::Vertical ); + Interval uside = track->getKiteEngine()->getGCellGrid()->getUSide( KbVertical ); - _sourceU = max ( boundingBox.getYMin(), uside.getVMin()); - _targetU = min ( boundingBox.getYMax(), uside.getVMax()); + _sourceU = max( boundingBox.getYMin(), uside.getVMin()); + _targetU = min( boundingBox.getYMax(), uside.getVMax()); - Katabatic::GCell* gcell = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(track->getAxis(),_sourceU) ); - Katabatic::GCell* end = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(track->getAxis(),_targetU) ); + Katabatic::GCell* gcell = track->getKiteEngine()->getGCellGrid()->getGCell( Point(track->getAxis(),_sourceU) ); + Katabatic::GCell* end = track->getKiteEngine()->getGCellGrid()->getGCell( Point(track->getAxis(),_targetU) ); Katabatic::GCell* up = NULL; - Interval guside = gcell->getUSide ( Constant::Vertical /*, true*/ ); + Interval guside = gcell->getSide( KbVertical ); Interval segside ( boundingBox.getYMin(), boundingBox.getYMax() ); - if ( gcell ) { + if (gcell) { while ( gcell and (gcell != end) ) { up = gcell->getUp(); - if ( up == NULL ) break; + if (up == NULL) break; - guside = gcell->getUSide ( Constant::Vertical /*, true*/ ); - Interval usedLength = guside.getIntersection ( segside ); + guside = gcell->getSide( KbVertical ); + Interval usedLength = guside.getIntersection( segside ); - gcell->addBlockage ( depth, usedLength.getSize() ); - //gcell->addBlockedAxis ( depth, track->getAxis() ); + gcell->addBlockage ( depth, usedLength.getSize() ); + //gcell->addBlockedAxis( depth, track->getAxis() ); gcell = up; } if ( end ) { - guside = gcell->getUSide ( Constant::Vertical /*, true*/ ); - Interval usedLength = guside.getIntersection ( segside ); + guside = gcell->getSide( KbVertical /*, true*/ ); + Interval usedLength = guside.getIntersection( segside ); - end->addBlockage ( depth, usedLength.getSize() ); - //end->addBlockedAxis ( depth, track->getAxis() ); + end->addBlockage ( depth, usedLength.getSize() ); + //end->addBlockedAxis( depth, track->getAxis() ); } } else cerr << Warning("TrackFixedSegment(): TrackFixedElement outside GCell grid.") << endl; @@ -163,7 +153,7 @@ namespace Kite { void TrackFixedSegment::_postCreate () - { TrackElement::_postCreate (); } + { TrackElement::_postCreate(); } TrackFixedSegment::~TrackFixedSegment () @@ -173,7 +163,7 @@ namespace Kite { void TrackFixedSegment::_preDestroy () { ltrace(90) << "TrackFixedSegment::_preDestroy() - " << (void*)this << endl; - TrackElement::_preDestroy (); + TrackElement::_preDestroy(); } @@ -182,27 +172,28 @@ namespace Kite { if ( not _blockageNet ) _blockageNet = Session::getBlockageNet(); TrackFixedSegment* trackFixedSegment = NULL; - if ( track ) { + if (track) { trackFixedSegment = new TrackFixedSegment ( track, segment ); - trackFixedSegment->_postCreate (); - Session::addInsertEvent ( trackFixedSegment, track ); + trackFixedSegment->_postCreate(); ltrace(190) << "Adding: " << segment << " on " << track << endl; ltrace(200) << "TrackFixedSegment::create(): " << trackFixedSegment << endl; + + Session::addInsertEvent( trackFixedSegment, track ); + } return trackFixedSegment; } AutoSegment* TrackFixedSegment::base () const { return NULL; } - bool TrackFixedSegment::isFixed () const { return true; } - bool TrackFixedSegment::isBlockage () const { return _isBlockage; } DbU::Unit TrackFixedSegment::getAxis () const { return getTrack()->getAxis(); } bool TrackFixedSegment::isHorizontal () const { return getTrack()->isHorizontal(); } bool TrackFixedSegment::isVertical () const { return getTrack()->isVertical(); } + bool TrackFixedSegment::isFixed () const { return true; } unsigned int TrackFixedSegment::getDirection () const { return getTrack()->getDirection(); } const Layer* TrackFixedSegment::getLayer () const { return _segment->getLayer(); } - Interval TrackFixedSegment::getFreeInterval ( bool useOrder ) const { return Interval(); } + Interval TrackFixedSegment::getFreeInterval () const { return Interval(); } unsigned long TrackFixedSegment::getId () const @@ -215,7 +206,7 @@ namespace Kite { Net* TrackFixedSegment::getNet () const { Net* realNet = _segment->getNet(); - if ( realNet->isSupply() or realNet->isClock() ) + if (realNet->isSupply() or realNet->isClock()) return _blockageNet; return realNet; } @@ -224,14 +215,14 @@ namespace Kite { TrackElement* TrackFixedSegment::getNext () const { size_t dummy = _index; - return _track->getNext ( dummy, getNet() ); + return _track->getNext( dummy, getNet() ); } TrackElement* TrackFixedSegment::getPrevious () const { size_t dummy = _index; - return _track->getPrevious ( dummy, getNet() ); + return _track->getPrevious( dummy, getNet() ); } @@ -247,7 +238,7 @@ namespace Kite { + " " + DbU::getValueString(_targetU-_sourceU) + " [" + ((_track) ? getString(_index) : "npos") + "] " + "F" - + ((_isBlockage) ? "B" : "-"); + + ((isBlockage()) ? "B" : "-"); s1.insert ( s1.size()-1, s2 ); return s1; @@ -256,11 +247,10 @@ namespace Kite { Record* TrackFixedSegment::_getRecord () const { - Record* record = TrackElement::_getRecord (); - record->add ( getSlot ( "_segment", _segment ) ); - + Record* record = TrackElement::_getRecord(); + record->add( getSlot( "_segment", _segment ) ); return record; } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/TrackMarker.cpp b/kite/src/TrackMarker.cpp index 1dd421e9..09cf8acf 100644 --- a/kite/src/TrackMarker.cpp +++ b/kite/src/TrackMarker.cpp @@ -2,14 +2,9 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 | // | | @@ -17,35 +12,28 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./TrackMarker.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ - - -#include -#include - -#include "hurricane/Bug.h" -#include "hurricane/Warning.h" -#include "hurricane/RoutingPad.h" -#include "hurricane/Net.h" -#include "hurricane/Name.h" -#include "crlcore/RoutingGauge.h" -#include "katabatic/GCell.h" -#include "kite/TrackMarker.h" -#include "kite/Track.h" -#include "kite/RoutingPlane.h" -#include "kite/Session.h" -#include "kite/RoutingEvent.h" -#include "kite/KiteEngine.h" +#include +#include +#include "hurricane/Bug.h" +#include "hurricane/Warning.h" +#include "hurricane/RoutingPad.h" +#include "hurricane/Net.h" +#include "hurricane/Name.h" +#include "crlcore/RoutingGauge.h" +#include "katabatic/GCell.h" +#include "kite/TrackMarker.h" +#include "kite/Track.h" +#include "kite/RoutingPlane.h" +#include "kite/Session.h" +#include "kite/RoutingEvent.h" +#include "kite/KiteEngine.h" namespace Kite { - using std::cerr; using std::endl; using std::ostringstream; @@ -101,7 +89,7 @@ namespace Kite { Track* track = rp->getTrackByPosition ( trackSpan.getVMin() ); while ( track && (track->getAxis() <= trackSpan.getVMax()) ) { Session::addInsertEvent ( this, track ); - track = track->getNext (); + track = track->getNextTrack(); _refcount++; } } @@ -139,7 +127,6 @@ namespace Kite { return record; } - -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/TrackSegment.cpp b/kite/src/TrackSegment.cpp index 89880a96..729bb58f 100644 --- a/kite/src/TrackSegment.cpp +++ b/kite/src/TrackSegment.cpp @@ -2,7 +2,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -15,31 +15,27 @@ // +-----------------------------------------------------------------+ - - -#include -#include - -#include "hurricane/Bug.h" -#include "hurricane/Warning.h" -#include "hurricane/Net.h" -#include "hurricane/Name.h" -#include "hurricane/RoutingPad.h" -#include "katabatic/AutoContact.h" -#include "katabatic/GCell.h" -#include "crlcore/RoutingGauge.h" -#include "kite/DataNegociate.h" -#include "kite/TrackSegment.h" -#include "kite/Track.h" -#include "kite/Session.h" -#include "kite/RoutingEvent.h" -#include "kite/NegociateWindow.h" -#include "kite/KiteEngine.h" +#include +#include +#include "hurricane/Bug.h" +#include "hurricane/Warning.h" +#include "hurricane/Net.h" +#include "hurricane/Name.h" +#include "hurricane/RoutingPad.h" +#include "katabatic/AutoContact.h" +#include "katabatic/GCell.h" +#include "crlcore/RoutingGauge.h" +#include "kite/DataNegociate.h" +#include "kite/TrackSegment.h" +#include "kite/Track.h" +#include "kite/Session.h" +#include "kite/RoutingEvent.h" +#include "kite/NegociateWindow.h" +#include "kite/KiteEngine.h" namespace Kite { - using namespace std; using Hurricane::inltrace; using Hurricane::ltracein; @@ -51,7 +47,8 @@ namespace Kite { using Hurricane::Net; using Hurricane::Name; using Hurricane::RoutingPad; - + using Katabatic::SegSlackened; + using Katabatic::KbPropagate; // ------------------------------------------------------------------- // Class : "TrackSegment". @@ -60,35 +57,33 @@ namespace Kite { TrackSegment::TrackSegment ( AutoSegment* segment, Track* track ) : TrackElement (track) , _base (segment) - , _created (true) - , _lock (true) - , _revalidated (false) - , _sourceDogLeg (false) - , _targetDogLeg (false) - , _canRipple (false) - , _routed (false) - , _area (0) + , _freedomDegree(0) , _data (NULL) , _dogLegLevel (0) { + ltrace(99) << "CTOR TrackSegment " << (void*)this << ":" << this << endl; + ltrace(99) << " over " << (void*)segment << ":" << segment << endl; + + setFlags( TElemCreated|TElemLocked ); if (segment) { - _data = new DataNegociate ( this ); - _base->getCanonical ( _sourceU, _targetU ); - setArea (); - //update (); + _data = new DataNegociate( this ); + _base->getCanonical( _sourceU, _targetU ); + updateFreedomDegree(); } } void TrackSegment::_postCreate () { - TrackElement::_postCreate (); - Session::link ( this ); + TrackElement::_postCreate(); + base()->addObserver( getObserver() ); } TrackSegment::~TrackSegment () - { if ( _data ) delete _data; } + { + if (_data) delete _data; + } void TrackSegment::_preDestroy () @@ -97,9 +92,8 @@ namespace Kite { << " [" << (void*)_base << ", " << (void*)(_base?_base->base():NULL) << "]" << endl; - Session::unlink ( this ); - - TrackElement::_preDestroy (); + base()->removeObserver( getObserver() ); + TrackElement::_preDestroy(); } @@ -107,13 +101,13 @@ namespace Kite { { created = false; - TrackElement* trackElement = Session::lookup ( segment->base() ); - if ( not trackElement ) { - TrackSegment* trackSegment = new TrackSegment ( segment, track ); - trackSegment->_postCreate (); + TrackElement* trackElement = Session::lookup( segment->base() ); + if (not trackElement) { + TrackSegment* trackSegment = new TrackSegment( segment, track ); + trackSegment->_postCreate(); created = true; - trackSegment->invalidate (); + trackSegment->invalidate(); ltrace(200) << "TrackSegment::create(): " << trackSegment << endl; trackElement = trackSegment; @@ -124,73 +118,39 @@ namespace Kite { // Formerly Inline Functions. - AutoSegment* TrackSegment::base () const { return _base; } - bool TrackSegment::isBipoint () const { return _base->isBipoint(); } - bool TrackSegment::isCreated () const { return _created; } - bool TrackSegment::isFixed () const { return _base->isFixed(); } - bool TrackSegment::isStrap () const { return _base->isCanonicalStrap(); } - bool TrackSegment::isSlackenStrap () const { return _base->isSlackenStrap(); } - bool TrackSegment::isLocal () const { return _base->isCanonicalLocal(); } - bool TrackSegment::isGlobal () const { return !isLocal(); } - bool TrackSegment::isLocked () const { return _lock; } - bool TrackSegment::isTerminal () const { return _base->isTerminal(); } - bool TrackSegment::isDogleg () const { return _base->isDogleg(); } - bool TrackSegment::isRevalidated () const { return _revalidated; } - bool TrackSegment::isRouted () const { return _routed; } - bool TrackSegment::isSlackened () const { return _base->isSlackened(); } - bool TrackSegment::isSlackenDogLeg () const { return isSlackened() and (_dogLegLevel > 0); } - bool TrackSegment::hasSourceDogLeg () const { return _sourceDogLeg; } - bool TrackSegment::hasTargetDogLeg () const { return _targetDogLeg; } - bool TrackSegment::allowOutsideGCell () const { return _base->allowOutsideGCell(); } - bool TrackSegment::canGoOutsideGCell () const { return _base->canGoOutsideGCell(); } - bool TrackSegment::canRipple () const { return _canRipple; } - unsigned long TrackSegment::getId () const { return _base->getId(); } - DbU::Unit TrackSegment::getAxis () const { return _base->getAxis(); } - unsigned long TrackSegment::getArea () const { return _area; } - unsigned int TrackSegment::getDogLegLevel () const { return _dogLegLevel; } - Interval TrackSegment::getSourceConstraints () const { return _base->getSourceConstraints(); } - Interval TrackSegment::getTargetConstraints () const { return _base->getTargetConstraints(); } - TrackElements TrackSegment::getCollapsedPerpandiculars () { return new TrackElements_CollapsedPerpandicular(this); } - void TrackSegment::setAllowOutsideGCell ( bool state ) { _base->setAllowOutsideGCell(state,true); } - void TrackSegment::setLock ( bool state ) { _lock = state; } - void TrackSegment::setRevalidated ( bool state ) { _revalidated = state; } - void TrackSegment::invalidate () { _base->invalidate(); } - void TrackSegment::setCanRipple ( bool state ) { _canRipple = state; } - void TrackSegment::setSourceDogLeg ( bool state ) { _sourceDogLeg = state; } - void TrackSegment::setTargetDogLeg ( bool state ) { _targetDogLeg = state; } - - - TrackElement* TrackSegment::getCanonical ( Interval& i ) - { return Session::lookup ( _base->getCanonical(i)->base() ); } - - - bool TrackSegment::canSlacken () const - { return (not isSlackened())?(_base->canSlacken(true)):false; } - - - bool TrackSegment::isHorizontal () const - { return _base->isHorizontal(); } - - - bool TrackSegment::isVertical () const - { return _base->isVertical(); } - - - unsigned int TrackSegment::getDirection () const - { return _base->getDirection(); } - - - Net* TrackSegment::getNet () const - { return _base->getNet(); } - - - const Layer* TrackSegment::getLayer () const - { return _base->getLayer(); } +// Wrappeds. + AutoSegment* TrackSegment::base () const { return _base; } + bool TrackSegment::isFixed () const { return _base->isFixed(); } + bool TrackSegment::isHorizontal () const { return _base->isHorizontal(); } + bool TrackSegment::isVertical () const { return _base->isVertical(); } + bool TrackSegment::isLocal () const { return not _base->isWeakGlobal() and not _base->isGlobal(); } + bool TrackSegment::isGlobal () const { return _base->isWeakGlobal() or _base->isGlobal(); } + bool TrackSegment::isBipoint () const { return _base->isBipoint(); } + bool TrackSegment::isTerminal () const { return _base->isTerminal(); } + bool TrackSegment::isStrongTerminal ( unsigned int flags ) const { return _base->isStrongTerminal(flags); } + bool TrackSegment::isStrap () const { return _base->isStrap(); } + bool TrackSegment::isSlackened () const { return _base->isSlackened(); } + bool TrackSegment::isDogleg () const { return _base->isDogleg(); } +// Predicates. +// Accessors. + unsigned long TrackSegment::getId () const { return _base->getId(); } + unsigned int TrackSegment::getDirection () const { return _base->getDirection(); } + Net* TrackSegment::getNet () const { return _base->getNet(); } + const Layer* TrackSegment::getLayer () const { return _base->getLayer(); } + DbU::Unit TrackSegment::getAxis () const { return _base->getAxis(); } + unsigned long TrackSegment::getFreedomDegree () const { return _freedomDegree; } + unsigned int TrackSegment::getDoglegLevel () const { return _dogLegLevel; } + Interval TrackSegment::getSourceConstraints () const { return _base->getSourceConstraints(); } + Interval TrackSegment::getTargetConstraints () const { return _base->getTargetConstraints(); } + TrackElement* TrackSegment::getCanonical ( Interval& i ) { return Session::lookup( _base->getCanonical(i)->base() ); } + TrackElements TrackSegment::getPerpandiculars () { return new TrackElements_Perpandiculars(this); } +// Mutators. + void TrackSegment::invalidate () { setFlags( TElemInvalidated ); _base->invalidate(); } DataNegociate* TrackSegment::getDataNegociate ( unsigned int flags ) const { - if ( flags & TrackElement::DataSelf ) return _data; + if (flags & KtDataSelf) return _data; TrackElement* parent = getParent(); return (parent) ? parent->getDataNegociate() : NULL; @@ -200,41 +160,41 @@ namespace Kite { TrackElement* TrackSegment::getNext () const { size_t dummy = _index; - return _track->getNext ( dummy, getNet() ); + return _track->getNext( dummy, getNet() ); } TrackElement* TrackSegment::getPrevious () const { size_t dummy = _index; - return _track->getPrevious ( dummy, getNet() ); + return _track->getPrevious( dummy, getNet() ); } TrackElement* TrackSegment::getParent () const { AutoSegment* baseParent = base()->getParent(); - if ( not baseParent ) return NULL; + if (not baseParent) return NULL; - TrackElement* element = Session::lookup ( baseParent ); + TrackElement* element = Session::lookup( baseParent ); return element; } Interval TrackSegment::getFreeInterval () const { - if ( not _track ) return Interval(false); + if (not _track) return Interval(false); size_t begin = _index; size_t end = _index; - return _track->expandFreeInterval ( begin, end, Track::Inside, getNet() ); + return _track->expandFreeInterval( begin, end, Track::InsideElement, getNet() ); } - size_t TrackSegment::getGCells ( vector& gcells ) const + size_t TrackSegment::getGCells ( Katabatic::GCellVector& gcells ) const { - vector().swap ( gcells ); + Katabatic::GCellVector().swap( gcells ); Katabatic::GCell* sourceGCell = base()->getAutoSource()->getGCell(); Katabatic::GCell* targetGCell = base()->getAutoTarget()->getGCell(); @@ -242,40 +202,41 @@ namespace Kite { ltrace(148) << "getGCells(): sourceGCell: " << sourceGCell << endl; ltrace(148) << "getGCells(): targetGCell: " << targetGCell << endl; - forEach ( AutoSegment*, isegment, base()->getCollapseds() ) { + forEach ( AutoSegment*, isegment, base()->getAligneds() ) { + ltrace(148) << "| " << *isegment << endl; + Katabatic::GCell* gcell = isegment->getAutoSource()->getGCell(); - if ( gcell->getIndex() < sourceGCell->getIndex() ) { + if (gcell->getIndex() < sourceGCell->getIndex()) { sourceGCell = gcell; ltrace(148) << "getGCells(): new sourceGCell: " << sourceGCell << endl; } gcell = isegment->getAutoTarget()->getGCell(); - if ( gcell->getIndex() > targetGCell->getIndex() ) { + if (gcell->getIndex() > targetGCell->getIndex()) { targetGCell = gcell; ltrace(148) << "getGCells(): new targetGCell: " << targetGCell << endl; } } - if ( not sourceGCell or not targetGCell ) return 0; - if ( not sourceGCell ) { gcells.push_back ( targetGCell ); return 1; } - if ( not targetGCell ) { gcells.push_back ( sourceGCell ); return 1; } + if (not sourceGCell or not targetGCell) return 0; + if (not sourceGCell) { gcells.push_back( targetGCell ); return 1; } + if (not targetGCell) { gcells.push_back( sourceGCell ); return 1; } - if ( isHorizontal() ) { - gcells.push_back ( sourceGCell ); + if (isHorizontal()) { + gcells.push_back( sourceGCell ); while ( sourceGCell != targetGCell ) { sourceGCell = sourceGCell->getRight(); - if ( not sourceGCell ) break; + if (not sourceGCell) break; - //cerr << " Pushing: " << sourceGCell << endl; - gcells.push_back ( sourceGCell ); + gcells.push_back( sourceGCell ); } } else { - gcells.push_back ( sourceGCell ); + gcells.push_back( sourceGCell ); while ( sourceGCell != targetGCell ) { sourceGCell = sourceGCell->getUp(); - if ( not sourceGCell ) break; + if (not sourceGCell) break; - gcells.push_back ( sourceGCell ); + gcells.push_back( sourceGCell ); } } @@ -289,95 +250,69 @@ namespace Kite { set baseBounds; set::iterator ibase; - _base->getPerpandicularsBound ( baseBounds ); + _base->getPerpandicularsBound( baseBounds ); - for ( ibase = baseBounds.begin() ; ibase != baseBounds.end() ; ibase++ ) { - TrackElement* segment = Session::lookup ( *ibase ); - if ( segment ) - bounds.insert ( segment ); + for ( ibase=baseBounds.begin() ; ibase!=baseBounds.end() ; ++ibase ) { + TrackElement* segment = Session::lookup( *ibase ); + if (segment) + bounds.insert( segment ); } return bounds.size(); } - void TrackSegment::setDogLegLevel ( unsigned int level ) + void TrackSegment::setDoglegLevel ( unsigned int level ) { - if ( level > 15 ) { + if (level > 15) { cerr << Bug("%s has reached maximum dog leg count (15)." ,_getString().c_str()) << endl; level = 15; } - _dogLegLevel = level; } - void TrackSegment::dataInvalidate () - { if (_data) _data->invalidate(); } - - - void TrackSegment::eventInvalidate () - { - if ( !_data ) return; - - RoutingEvent* event = _data->getRoutingEvent(); - if ( event ) event->invalidate ( true ); - } - - - void TrackSegment::setArea () - { - //float length = getValue ( getTargetU() - getSourceU() ); - //float height = getValue ( getSlack() ); - //_area = (unsigned long)( length * height ); - _area = _base->getSlack(); - } - - - void TrackSegment::setRouted ( bool state ) - { _routed = state; } + void TrackSegment::updateFreedomDegree () + { _freedomDegree = _base->getSlack(); } void TrackSegment::setTrack ( Track* track ) - { TrackElement::setTrack ( track ); } + { TrackElement::setTrack( track ); } void TrackSegment::detach () { ltrace(200) << "TrackSegment::detach() - " << endl; - setTrack ( NULL ); - setIndex ( (size_t)-1 ); - setLock ( true ); + setTrack( NULL ); + setIndex( (size_t)-1 ); + setFlags( TElemLocked ); } - void TrackSegment::revalidate ( bool invalidEvent ) + void TrackSegment::revalidate () { - _created = false; + unsetFlags( TElemCreated ); ltrace(148) << "revalidate() - " << this << endl; - _base->getCanonical ( _sourceU, _targetU ); - _data->update (); - if ( invalidEvent ) - _data->invalidate ( true, true ); + _base->getCanonical( _sourceU, _targetU ); - if ( _track ) Session::addSortEvent ( _track ); - _revalidated = true; + if (_track) Session::addSortEvent( _track, true ); + unsetFlags( TElemInvalidated ); } void TrackSegment::setAxis ( DbU::Unit axis, unsigned int flags ) { - _base->setAxis ( axis, flags ); - invalidate (); + _base->setAxis( axis, flags ); + invalidate(); } void TrackSegment::swapTrack ( TrackElement* other ) { - if ( not other ) return; + if (not other) return; ltrace(200) << "TrackSegment::swapTrack()" << endl; @@ -386,40 +321,31 @@ namespace Kite { size_t otherIndex = other->getIndex (); Track* otherTrack = other->getTrack (); - if ( _track and otherTrack and (_track != otherTrack) ) { - cerr << Error("TrackSegment::swapTrack() - swapping TrackSement from different tracks.") << endl; + if (_track and otherTrack and (_track != otherTrack)) { + cerr << Error("TrackSegment::swapTrack() - swapping TrackSegments from different tracks.") << endl; } - // detach (); - // other->detach (); - // if ( thisTrack ) thisTrack ->insert ( other ); - // if ( otherTrack ) otherTrack->insert ( this ); + setTrack( NULL ); + other->setTrack( NULL ); - setTrack ( NULL ); - other->setTrack ( NULL ); + other->setTrack( thisTrack ); + other->setIndex( thisIndex ); + if (thisTrack) thisTrack->setSegment( other, thisIndex ); - //other->setRouted ( thisRouted ); - other->setTrack ( thisTrack ); - other->setIndex ( thisIndex ); - if ( thisTrack ) thisTrack->setSegment ( other, thisIndex ); - - //setRouted ( otherRouted ); - setTrack ( otherTrack ); - setIndex ( otherIndex ); - if ( _track ) _track->setSegment ( this, _index ); + setTrack( otherTrack ); + setIndex( otherIndex ); + if (_track) _track->setSegment( this, _index ); #if defined(CHECK_DATABASE_DISABLED) - if ( _track ) - _track->_check(); - else if ( other->getTrack() ) - other->getTrack()->_check(); + if (_track) _track->_check(); + else if (other->getTrack()) other->getTrack()->_check(); #endif - RoutingEvent* thisEvent = getDataNegociate(TrackElement::DataSelf)->getRoutingEvent(); + RoutingEvent* thisEvent = getDataNegociate(KtDataSelf)->getRoutingEvent(); RoutingEvent* otherEvent = other->getDataNegociate()->getRoutingEvent(); - if ( thisEvent ) thisEvent ->setSegment ( other ); - if ( otherEvent ) otherEvent->setSegment ( this ); + if (thisEvent ) thisEvent ->setSegment( other ); + if (otherEvent) otherEvent->setSegment( this ); ltrace(200) << "| this: " << this << endl; ltrace(200) << "| other: " << other << endl; @@ -431,35 +357,20 @@ namespace Kite { ltrace(200) << "TrackSegment::reschedule() - " << this << endl; ltracein(200); - if ( not _data or not _data->hasRoutingEvent() ) - Session::getNegociateWindow()->addInsertEvent ( this, level ); + if (not _data or not _data->hasRoutingEvent()) + Session::getNegociateWindow()->addRoutingEvent( this, level ); else { - if ( _track != NULL ) - Session::addRemoveEvent ( this ); - Session::getNegociateWindow()->rescheduleEvent ( _data->getRoutingEvent(), level ); + if (_track != NULL) + Session::addRemoveEvent( this ); + Session::getNegociateWindow()->rescheduleEvent( _data->getRoutingEvent(), level ); } ltraceout(200); } - void TrackSegment::slacken () - { - if ( not isSlackened() ) { - ltrace(200) << "TrackSegment::slacken()" << endl; - ltracein(200); - - base()->slacken ( true ); - _postModify (); - - ltraceout(200); - } else - throw Bug("TrackSegment::slacken(): NULL base or already slackened."); - } - - float TrackSegment::getMaxUnderDensity ( unsigned int flags ) const - { return _base->getMaxUnderDensity ( flags ); } + { return _base->getMaxUnderDensity( flags ); } bool TrackSegment::canPivotUp ( float reserve ) const @@ -467,11 +378,41 @@ namespace Kite { bool TrackSegment::canPivotDown ( float reserve ) const - { return _base->canPivotDown(reserve); } + { return _base->canPivotDown( reserve ); } bool TrackSegment::canMoveUp ( float reserve, unsigned int flags ) const - { return _base->canMoveUp ( reserve, flags ); } + { return _base->canMoveUp( reserve, flags ); } + + + bool TrackSegment::canSlacken () const + { + ltrace(200) << "TrackSegment::canSlacken() doglegLevel:" << getDoglegLevel() << endl; + return (not isSlackened() and (getDoglegLevel() <= 3)) ? _base->canSlacken(KbPropagate) : false; + } + + bool TrackSegment::slacken ( unsigned int flags ) + { + ltrace(200) << "TrackSegment::slacken()" << endl; + + bool success = false; + + if (not isSlackened()) { + TrackElement* perpandicular = NULL; + TrackElement* parallel = NULL; + + ltracein(200); + + success = base()->slacken( flags|KbPropagate ); + _postDoglegs( perpandicular, parallel ); + + ltraceout(200); + return success; + } else + cerr << Bug("TrackSegment::slacken(): NULL base or already slackened.") << endl; + + return success; + } bool TrackSegment::moveUp ( unsigned int flags ) @@ -481,30 +422,14 @@ namespace Kite { ltrace(200) << "TrackSegment::moveUp() " << flags << endl; ltracein(200); - success = base()->moveUp ( flags ); + success = base()->moveUp( flags ); + if (success) { + TrackElement* perpandicular = NULL; + TrackElement* parallel = NULL; - const vector& invalidateds = Session::getInvalidateds(); - if ( not invalidateds.empty() ) { - vector segments; - for ( size_t i=0 ; iaddTrackSegment(invalidateds[i],false); - if ( segment != NULL ) { - ltrace(200) << "moved up: " << invalidateds[i] << endl; - segments.push_back ( segment ); - // if ( (segment->getTrack() == NULL) - // or (segment->getLayer() != segment->getTrack()->getLayer()) ) - segment->reschedule ( 0 ); - } - } - for ( size_t i=0 ; isetState ( DataNegociate::ConflictSolve1, true ); - // _data->resetRipupCount (); - // } ltraceout(200); @@ -519,30 +444,14 @@ namespace Kite { ltrace(200) << "TrackSegment::moveDown() " << flags << endl; ltracein(200); - success = base()->moveDown ( flags ); + success = base()->moveDown( flags ); + if (success) { + TrackElement* perpandicular = NULL; + TrackElement* parallel = NULL; - const vector& invalidateds = Session::getInvalidateds(); - if ( not invalidateds.empty() ) { - vector segments; - for ( size_t i=0 ; iaddTrackSegment(invalidateds[i],false); - if ( segment != NULL ) { - ltrace(200) << "moved down: " << invalidateds[i] << endl; - segments.push_back ( segment ); - // if ( (segment->getTrack() == NULL) - // or (segment->getLayer() != segment->getTrack()->getLayer()) ) - segment->reschedule ( 0 ); - } - } - for ( size_t i=0 ; isetState ( DataNegociate::ConflictSolve1, true ); - // _data->resetRipupCount (); - // } ltraceout(200); @@ -550,45 +459,31 @@ namespace Kite { } - bool TrackSegment::moveAside ( bool onLeft ) + bool TrackSegment::moveAside ( unsigned int flags ) { bool success = true; - ltrace(200) << "TrackSegment::moveAside() - " << (onLeft?"left":"right") << endl; + ltrace(200) << "TrackSegment::moveAside() - " + << ((flags&KtMoveToLeft )?"left" :"") + << ((flags&KtMoveToRight)?"rigth":"") << endl; ltracein(200); - - if ( onLeft ) base()->moveULeft (); - else base()->moveURight (); - - const vector& invalidateds = Session::getInvalidateds(); - if ( not invalidateds.empty() ) { - vector segments; - for ( size_t i=0 ; iaddTrackSegment(invalidateds[i],false) ); - segments.back()->reschedule ( 0 ); - } - - for ( size_t i=0 ; imoveULeft (); + if (flags & KtMoveToRight) base()->moveURight(); ltraceout(200); return success; } - TrackElement* TrackSegment::getSourceDogLeg () + TrackElement* TrackSegment::getSourceDogleg () { - if ( not hasSourceDogLeg() ) return NULL; + if (not hasSourceDogleg()) return NULL; - unsigned int direction = Constant::perpandicular ( getDirection() ); + unsigned int direction = perpandicularTo( getDirection() ); TrackElement* dogleg = NULL; forEach ( Segment*, isegment, base()->getAutoSource()->getSlaveComponents().getSubSet() ) { - dogleg = Session::lookup ( *isegment ); - if ( dogleg and (dogleg->getDirection() == direction) ) { + dogleg = Session::lookup( *isegment ); + if (dogleg and (dogleg->getDirection() == direction)) { ltrace(200) << "Source dogleg: " << dogleg << endl; return dogleg; } @@ -597,15 +492,15 @@ namespace Kite { } - TrackElement* TrackSegment::getTargetDogLeg () + TrackElement* TrackSegment::getTargetDogleg () { - if ( not hasSourceDogLeg() ) return NULL; + if (not hasSourceDogleg()) return NULL; - unsigned int direction = Constant::perpandicular ( getDirection() ); + unsigned int direction = perpandicularTo( getDirection() ); TrackElement* dogleg = NULL; forEach ( Segment*, isegment, base()->getAutoTarget()->getSlaveComponents().getSubSet() ) { - dogleg = Session::lookup ( *isegment ); - if ( dogleg and (dogleg->getDirection() == direction) ) { + dogleg = Session::lookup( *isegment ); + if (dogleg and (dogleg->getDirection() == direction)) { ltrace(200) << "Target dogleg: " << dogleg << endl; return dogleg; } @@ -614,198 +509,244 @@ namespace Kite { } - bool TrackSegment::canDogLeg ( Interval interval ) + bool TrackSegment::canDogleg () { - ltrace(200) << "TrackSegment::canDogLeg(Interval) " << interval << endl; + ltrace(200) << "TrackSegment::canDogleg()" << endl; - if ( isFixed() ) { - ltrace(200) << "Failed: is fixed" << endl; - return false; - } - - if ( not isLocal() ) { - ltrace(200) << "Failed: is not local" << endl; - return false; - } - - if ( hasSourceDogLeg() or hasTargetDogLeg() or isSlackened() ) { - ltrace(200) << "Failed: already has source and/or target dogleg or slackened." << endl; - return false; - } - - return _base->canDogLeg(interval); - } - - - TrackElement* TrackSegment::makeDogLeg ( Interval interval, bool& leftDogleg ) - { - ltrace(200) << "TrackSegment::makeDogLeg(Interval)" << endl; - - bool upLayer = (Session::getRoutingGauge()->getLayerDepth(getLayer()) < 2); - - base()->makeDogLeg ( interval, upLayer, leftDogleg ); - - return _postDogLeg (); - } - - - bool TrackSegment::canDogLeg () - { - ltrace(200) << "TrackSegment::canDogLeg()" << endl; - - if ( not isLocal() ) { + if (not isLocal()) { ltrace(200) << "Failed: is not local." << endl; return false; } - if ( isFixed() ) { + if (isFixed()) { ltrace(200) << "Failed: is fixed." << endl; return false; } - if ( isSlackened() ) { + if (isSlackened()) { ltrace(200) << "Failed: is local & slackened." << endl; return false; } - if ( hasSourceDogLeg() || hasTargetDogLeg() ) return false; + if (hasSourceDogleg() or hasTargetDogleg()) { + ltrace(200) << "Failed: already has source or target dogleg." << endl; + return false; + } + + if (getDoglegLevel() > 3) { + ltrace(200) << "Failed: maximum dogleg level reached (4)." << endl; + return false; + } return true; } - TrackElement* TrackSegment::makeDogLeg () + bool TrackSegment::canDogleg ( Katabatic::GCell* doglegGCell, unsigned int flags ) { - Katabatic::AutoContact* source = _base->getAutoSource(); - Katabatic::AutoContact* target = _base->getAutoTarget(); - Katabatic::GCell* gcell = _base->getAutoSource()->getGCell(); + ltrace(200) << "TrackSegment::canDogleg(GCell*) " << doglegGCell << endl; + ltracein(200); - TrackElement* dogleg = makeDogLeg ( gcell ); - - if ( dogleg ) { - if ( source->isTerminal() xor target->isTerminal() ) { - if ( target->isTerminal() ) - source = target; - - DbU::Unit axis = (_base->isHorizontal()) ? source->getX() : source->getY(); - - ltrace(200) << "Setting dogleg axis @" << DbU::getValueString(axis) << endl; - dogleg->setAxis ( axis ); - } - return _postDogLeg(); - } - - return NULL; - } - - - bool TrackSegment::canDogLegAt ( Katabatic::GCell* dogLegGCell, unsigned int flags ) - { - ltrace(200) << "TrackSegment::canDogLegAt(GCell*) " << dogLegGCell << endl; - - if ( isFixed() ) { - ltrace(200) << "Cannot dogleg a fixed segment." << endl; + if (doglegGCell->isUnderIoPad()) { + ltrace(200) << "false: Cannot dogleg in a GCell under an I/O Pad." << endl; + ltraceout(200); return false; } - if ( isLocal() ) { - if ( hasSourceDogLeg() or hasTargetDogLeg() ) { - ltrace(200) << "Cannot dogleg again a local segment." << endl; + if (isFixed()) { + ltrace(200) << "false: Cannot dogleg a fixed segment." << endl; + ltraceout(200); + return false; + } + + if (isLocal()) { + if (hasSourceDogleg() or hasTargetDogleg()) { + ltrace(200) << "false: Cannot dogleg again a local segment." << endl; + ltraceout(200); return false; } - if ( isSlackened() ) { - ltrace(200) << "Cannot dogleg a local slackened segment." << endl; + if (isSlackened()) { + ltrace(200) << "false: Cannot dogleg a local slackened segment." << endl; + ltraceout(200); return false; } } + if (getDoglegLevel() > 3) { + ltrace(200) << "Failed: maximum dogleg level reached (4)." << endl; + ltraceout(200); + return false; + } + vector gcells; - getGCells ( gcells ); + getGCells( gcells ); ltrace(190) << "Source: " << *gcells.begin () << endl; ltrace(190) << "Target: " << *gcells.rbegin() << endl; bool isGCellInside = false; - for ( size_t igcell=0 ; igcellgetLayerDepth(getLayer()) < 2); + if (isFixed()) { + ltrace(200) << "Failed: is fixed" << endl; + return false; + } - base()->makeDogLeg ( dogLegGCell, upLayer ); + if (not isLocal()) { + ltrace(200) << "Failed: is not local" << endl; + return false; + } - return _postDogLeg (); + if (hasSourceDogleg() or hasTargetDogleg() or isSlackened()) { + ltrace(200) << "Failed: already has source and/or target dogleg or slackened." << endl; + return false; + } + + if (getDoglegLevel() > 3) { + ltrace(200) << "Failed: maximum dogleg level reached (4)." << endl; + return false; + } + + return _base->canDogleg(interval); } - TrackElement* TrackSegment::_postDogLeg () + TrackElement* TrackSegment::makeDogleg () { + Katabatic::AutoContact* source = _base->getAutoSource(); + Katabatic::AutoContact* target = _base->getAutoTarget(); + Katabatic::GCell* gcell = _base->getAutoSource()->getGCell(); + + TrackElement* dogleg = NULL; + TrackElement* parallel = NULL; + makeDogleg( gcell, dogleg, parallel ); + + if (dogleg) { + if (source->isTerminal() xor target->isTerminal()) { + if (target->isTerminal()) + source = target; + + DbU::Unit axis = (_base->isHorizontal()) ? source->getX() : source->getY(); + + ltrace(200) << "Setting dogleg axis @" << DbU::getValueString(axis) << endl; + dogleg->setAxis( axis ); + } + } + return dogleg; + } + + + TrackElement* TrackSegment::makeDogleg ( Katabatic::GCell* dogLegGCell + , TrackElement*& perpandicular + , TrackElement*& parallel + ) + { + ltrace(200) << "TrackSegment::makeDogleg(GCell*)" << endl; + ltrace(200) << "Break in: " << dogLegGCell << endl; + + base()->makeDogleg( dogLegGCell ); + _postDoglegs( perpandicular, parallel ); + + return perpandicular; + } + + + TrackElement* TrackSegment::makeDogleg ( Interval interval, unsigned int& flags ) + { + TrackElement* perpandicular = NULL; + TrackElement* parallel = NULL; + + ltrace(200) << "TrackSegment::makeDogleg(Interval)" << endl; + flags = base()->makeDogleg( interval ); + _postDoglegs( perpandicular, parallel ); + + return perpandicular; + } + + + void TrackSegment::_postDoglegs ( TrackElement*& perpandicular, TrackElement*& parallel ) + { + ltrace(200) << "TrackSegment::_postDoglegs()" << endl; ltracein(200); - TrackElement* perpandicular = NULL; + unsigned int doglegLevel = 0; + const vector& doglegs = Session::getDoglegs(); + vector segments; - const vector& dogLegs = Session::getDogLegs(); - if ( not dogLegs.empty() ) { - vector segments; - for ( size_t i=0 ; iaddTrackSegment(dogLegs[i],false) ); + for ( size_t i=0 ; icreateTrackSegment(doglegs[i],0) ); + segments[i+0]->setFlags( TElemTargetDogleg ); + segments[i+0]->getDataNegociate()->resetRipupCount(); + //segments[i+0]->getDataNegociate()->resetStateCount(); + segments[i+0]->getDataNegociate()->setState( DataNegociate::RipupPerpandiculars ); + doglegLevel = segments[i+0]->getDoglegLevel() + 1; + segments[i+0]->setDoglegLevel( doglegLevel ); - switch ( i ) { - case 0: - segments[i]->setTargetDogLeg(); - segments[i]->getDataNegociate()->resetRipupCount(); + ltrace(200) << "Looking up new perpand: " << doglegs[i+1] << endl; + segments.push_back( Session::getNegociateWindow()->createTrackSegment(doglegs[i+1],0) ); + segments[i+1]->setFlags( TElemSourceDogleg|TElemTargetDogleg ); + segments[i+1]->setDoglegLevel( doglegLevel ); - if ( segments[i] != this ) { - cerr << Error ( "Incoherency in TrackSegment LUT, lookup of %p gives %p instead of %p (this)" - , dogLegs[i], segments[i], this - ) << endl; - } - break; - case 1: - perpandicular = segments[i]; - segments[i]->setSourceDogLeg (); - segments[i]->setTargetDogLeg (); - segments[i]->setDogLegLevel ( getDogLegLevel()+1 ); - break; - case 2: - segments[i]->setSourceDogLeg (); - break; - } + ltrace(200) << "Looking up new parallel: " << doglegs[i+2] << endl; + segments.push_back( Session::getNegociateWindow()->createTrackSegment(doglegs[i+2],0) ); + segments[i+2]->setFlags( TElemSourceDogleg ); + segments[i+2]->getDataNegociate()->resetStateCount(); + segments[i+2]->getDataNegociate()->setState( segments[i+0]->getDataNegociate()->getState() ); + segments[i+2]->setDoglegLevel( doglegLevel ); + + segments[i+0]->getDataNegociate()->setChildSegment( segments[i+2] ); + + perpandicular = segments[i+1]; + parallel = segments[i+2]; } // TO CHECK @@ -813,103 +754,45 @@ namespace Kite { // if the new bit takes it's place or not. //if ( getGCell() != originalGCell ) swapTrack ( segments[2] ); - for ( size_t i=0 ; ireschedule ( ((i==1) ? 0 : 1) ); - } - - ltrace(200) << "original: " << segments[0] << endl; - ltrace(200) << "perpand: " << segments[1] << endl; - ltrace(200) << "new paral: " << segments[2] << endl; - } - - ltraceout(200); - - return perpandicular; - } - - - bool TrackSegment::canDesalignate () const - { - ltrace(200) << "TrackSegment::canDesalignate()" << endl; - - return _base->canDesalignate(); - } - - - void TrackSegment::desalignate () - { - ltrace(200) << "TrackSegment::desalignate()" << endl; - ltracein(200); - - _base->desalignate (); - _postModify (); - - ltraceout(200); - } - - - void TrackSegment::_postModify () - { - ltrace(200) << "TrackSegment::_postModify()" << endl; - ltracein(200); - - unsigned int doglegLevel = getDogLegLevel() + 1; - unsigned int parallelDir = getDirection (); - unsigned int perpandicularDir = Constant::perpandicular ( parallelDir ); - - const vector& invalidateds = Session::getInvalidateds(); - vector segments; - - if ( not invalidateds.empty() ) { - for ( size_t i=0 ; iaddTrackSegment(invalidateds[i],false); - if ( segment != NULL ) - segments.push_back ( segment ); - } - } - - for ( size_t i=0 ; iisCreated() and (segment->getDirection() == perpandicularDir) ) { - ltrace(200) << "Increasing dogleg level to: " << doglegLevel << endl; - segment->setDogLegLevel ( doglegLevel ); - } - - if ( segment->getDirection() == parallelDir ) { - forEach ( TrackElement*, iperpandicular, segment->getCollapsedPerpandiculars() ) { - ltrace(200) << "| pp: " << *iperpandicular << endl; - iperpandicular->reschedule ( 0 ); + for ( size_t i=0 ; ireschedule ( ((i%3==1) ? 0 : 1) ); + const char* segPart = "Unknown"; + switch ( i%3 ) { + case 0: segPart = "original "; break; + case 1: segPart = "perpand "; break; + case 2: segPart = "new paral"; break; } - segment->reschedule ( 0 ); + ltrace(200) << "[" << (i/3) << ":" << i << "] " << segPart << ": " + << segments[i] << endl; } - } + } ltraceout(200); + + Session::doglegReset(); } bool TrackSegment::_check () const { - if ( not base() ) return true; + if (not base()) return true; bool coherency = true; - if ( not base()->isCanonical() ) { + if (not base()->isCanonical()) { cerr << "[CHECK] " << this << " supporting AutoSegment is not canonical." << endl; coherency = false; } DbU::Unit min; DbU::Unit max; - base()->getCanonical ( min, max ); - if ( getSourceU() != min ) { + base()->checkPositions(); + base()->getCanonical( min, max ); + if (getSourceU() != min) { cerr << "[CHECK] " << this << " has bad source position " << DbU::getValueString(min) << "." << endl; coherency = false; } - if ( getTargetU() != max ) { + if (getTargetU() != max) { cerr << "[CHECK] " << this << " has bad target position " << DbU::getValueString(max) << "." << endl; coherency = false; } @@ -932,9 +815,9 @@ namespace Kite { + " [" + ((_track) ? getString(_index) : "npos") + "] " + ((isSlackened() ) ? "S" : "-") + ((_track ) ? "T" : "-") - + ((_canRipple ) ? "r" : "-") - + ((_sourceDogLeg ) ? "s" : "-") - + ((_targetDogLeg ) ? "t" : "-"); + + ((canRipple() ) ? "r" : "-") + + ((hasSourceDogleg()) ? "s" : "-") + + ((hasTargetDogleg()) ? "t" : "-"); s1.insert ( s1.size()-1, s2 ); @@ -944,13 +827,10 @@ namespace Kite { Record* TrackSegment::_getRecord () const { - Record* record = TrackElement::_getRecord (); - record->add ( getSlot ( "_base" , _base ) ); - record->add ( getSlot ( "_lock" , _lock ) ); - record->add ( getSlot ( "_revalidated", _revalidated ) ); - + Record* record = TrackElement::_getRecord(); + record->add( getSlot( "_base", _base ) ); return record; } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/TrackSegmentCost.cpp b/kite/src/TrackSegmentCost.cpp index af35d811..00124a5d 100644 --- a/kite/src/TrackSegmentCost.cpp +++ b/kite/src/TrackSegmentCost.cpp @@ -2,14 +2,9 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 | // | | @@ -17,12 +12,7 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./TrackSegmentCost.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x - - +// +-----------------------------------------------------------------+ #include diff --git a/kite/src/Tracks.cpp b/kite/src/Tracks.cpp index 112f1899..0df2b44b 100644 --- a/kite/src/Tracks.cpp +++ b/kite/src/Tracks.cpp @@ -2,14 +2,9 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 | // | | @@ -17,22 +12,17 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./Tracks.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#include - -#include "kite/Track.h" -#include "kite/Tracks.h" -#include "kite/RoutingPlane.h" +#include +#include "kite/Track.h" +#include "kite/Tracks.h" +#include "kite/RoutingPlane.h" namespace Kite { - using std::cerr; using std::endl; using Hurricane::tab; @@ -56,8 +46,8 @@ namespace Kite { _track = routingPlane->getTrackByPosition ( _constraints.getVMin() ); - if ( _track && (_track->getAxis() < _constraints.getVMin()) ) _track = _track->getNext(); - if ( _track && (_track->getAxis() > _constraints.getVMax()) ) _track = NULL; + if ( _track and (_track->getAxis() < _constraints.getVMin()) ) _track = _track->getNextTrack(); + if ( _track and (_track->getAxis() > _constraints.getVMax()) ) _track = NULL; ltrace(147) << "_track: " << _track << endl;; } @@ -87,8 +77,8 @@ namespace Kite { { if ( !_track ) return; - _track = _track->getNext (); - if ( _track && (_track->getAxis() > _constraints.getVMax()) ) _track = NULL; + _track = _track->getNextTrack(); + if ( _track and (_track->getAxis() > _constraints.getVMax()) ) _track = NULL; } @@ -170,12 +160,12 @@ namespace Kite { if ( _maxTrack->getAxis() > _constraints.getVMax() ) _maxTrack = NULL; if ( _minTrack && !_maxTrack ) { - _minTrack = _minTrack->getPrevious (); - if ( _minTrack->getAxis() < _constraints.getVMin() ) _minTrack = NULL; + _minTrack = _minTrack->getPreviousTrack(); + if (_minTrack->getAxis() < _constraints.getVMin()) _minTrack = NULL; } if ( _maxTrack && !_minTrack ) { - _maxTrack = _maxTrack->getNext (); + _maxTrack = _maxTrack->getNextTrack(); if ( _maxTrack->getAxis() > _constraints.getVMax() ) _maxTrack = NULL; } @@ -237,7 +227,7 @@ namespace Kite { if ( _onMin ) { _onMin = (_maxTrack == NULL); if ( _minTrack ) { - _minTrack = _minTrack->getPrevious(); + _minTrack = _minTrack->getPreviousTrack(); if ( _minTrack ) { if ( _minTrack->getAxis() < _optimal.getVMin() ) _inMinOptimal = false; @@ -248,7 +238,7 @@ namespace Kite { } else { _onMin = (_minTrack != NULL); if ( _maxTrack ) { - _maxTrack = _maxTrack->getNext(); + _maxTrack = _maxTrack->getNextTrack(); if ( _maxTrack ) { if ( _maxTrack->getAxis() > _optimal.getVMax() ) _inMaxOptimal = false; @@ -326,4 +316,4 @@ namespace Kite { } -} // End of Katabatic namespace. +} // Kite namespace. diff --git a/kite/src/VerticalTrack.cpp b/kite/src/VerticalTrack.cpp index e04ad0ba..e3b35678 100644 --- a/kite/src/VerticalTrack.cpp +++ b/kite/src/VerticalTrack.cpp @@ -2,14 +2,9 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 | // | | @@ -17,13 +12,10 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Module : "./VerticalTrack.cpp" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// +-----------------------------------------------------------------+ -#include "kite/VerticalTrack.h" +#include "kite/VerticalTrack.h" namespace Kite { @@ -62,7 +54,7 @@ namespace Kite { bool VerticalTrack::isHorizontal () const { return false; } bool VerticalTrack::isVertical () const { return true; } - unsigned int VerticalTrack::getDirection () const { return Constant::Vertical; } + unsigned int VerticalTrack::getDirection () const { return KbVertical; } Point VerticalTrack::getPosition ( DbU::Unit coordinate ) const @@ -80,4 +72,4 @@ namespace Kite { } -} // End of Kite namespace. +} // Kite namespace. diff --git a/kite/src/kite/Configuration.h b/kite/src/kite/Configuration.h index 808caf19..dc5b33ee 100644 --- a/kite/src/kite/Configuration.h +++ b/kite/src/kite/Configuration.h @@ -1,34 +1,24 @@ - -// -*- C++ -*- +// -*- mode: C++; explicit-buffer-name: "Configuration.h" -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 : "./Configuration.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./kite/Configuration.h" | +// +-----------------------------------------------------------------+ -#ifndef __KITE_CONFIGURATION__ -#define __KITE_CONFIGURATION__ +#ifndef KITE_CONFIGURATION_H +#define KITE_CONFIGURATION_H -#include - -#include "katabatic/Configuration.h" +#include +#include "katabatic/Configuration.h" namespace Kite { @@ -47,7 +37,6 @@ namespace Kite { // ------------------------------------------------------------------- // Class : "Kite::Configuration". - class Configuration : public Katabatic::Configuration { public: typedef boost::function< void(void) > PostEventCb_t; @@ -68,6 +57,7 @@ namespace Kite { ~Configuration (); // Decorateds. virtual bool isGMetal ( const Layer* ) const; + virtual bool isGContact ( const Layer* ) const; virtual size_t getDepth () const; virtual size_t getAllowedDepth () const; virtual size_t getLayerDepth ( const Layer* ) const; @@ -137,10 +127,10 @@ namespace Kite { -} // End of Kite namespace. +} // Kite namespace. INSPECTOR_P_SUPPORT(Kite::Configuration); -#endif // __KITE_CONFIGURATION__ +#endif // KITE_CONFIGURATION_H diff --git a/kite/src/kite/Constants.h b/kite/src/kite/Constants.h new file mode 100644 index 00000000..8d6bfa0f --- /dev/null +++ b/kite/src/kite/Constants.h @@ -0,0 +1,52 @@ +// -*- mode: C++; explicit-buffer-name: "Constants.h" -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2013, 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 : "./kite/Constants.h" | +// +-----------------------------------------------------------------+ + + +#ifndef KITE_CONSTANTS_H +#define KITE_CONSTANTS_H + +#include "katabatic/Constants.h" + +namespace Kite { + + using Katabatic::KbOpenSession; + using Katabatic::KbRealignate; + using Katabatic::KbNativeConstraints; + using Katabatic::KbForceMove; + using Katabatic::KbHorizontal; + using Katabatic::KbVertical; + using Katabatic::KbWithPerpands; + using Katabatic::KbBySource; + using Katabatic::KbByTarget; + using Katabatic::KbWarnOnError; + using Katabatic::perpandicularTo; + + enum FunctionFlags { KtLoadGlobalRouting = 0x00000001 + , KtBuildGlobalRouting = 0x00000002 + , KtAllowDoglegReuse = 0x00000004 + , KtDataSelf = 0x00000008 + , KtNearest = 0x00000010 + , KtForce = 0x00000020 + , KtResetCount = 0x00000040 + , KtWithPerpands = 0x00000080 + , KtWithConstraints = 0x00000100 + , KtMoveToLeft = 0x00000200 + , KtMoveToRight = 0x00000400 + , KtLoadingStage = 0x00000800 + , }; + +} // Kite namespace. + +#endif // KITE_CONSTANTS_H diff --git a/kite/src/kite/DataNegociate.h b/kite/src/kite/DataNegociate.h index 9c71ad40..352671ae 100644 --- a/kite/src/kite/DataNegociate.h +++ b/kite/src/kite/DataNegociate.h @@ -1,8 +1,7 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -11,23 +10,21 @@ // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | -// | C++ Header : "./DataNegociate.h" | +// | C++ Header : "./kite/DataNegociate.h" | // +-----------------------------------------------------------------+ -#ifndef __KITE_DATA_NEGOCIATE__ -#define __KITE_DATA_NEGOCIATE__ +#ifndef KITE_DATA_NEGOCIATE_H +#define KITE_DATA_NEGOCIATE_H -#include -#include +#include +#include namespace Hurricane { class Record; } -#include "kite/TrackSegmentCost.h" #include "kite/TrackElement.h" -#include "kite/RoutingEvent.h" namespace Katabatic { class AutoSegment; } @@ -51,58 +48,66 @@ namespace Kite { class DataNegociate { - public: - enum SlackState { RipupPerpandiculars= 1 - , Desalignate = 2 - , Minimize = 3 - , DogLeg = 4 - , Slacken = 5 - , ConflictSolve1 = 6 - , ConflictSolve2 = 7 - , LocalVsGlobal = 8 - , MoveUp = 9 - , MaximumSlack =10 - , Unimplemented =11 - , Repair =12 + enum SlackState { RipupPerpandiculars = 1 + , Minimize = 2 + , Dogleg = 3 + , Slacken = 4 + , ConflictSolveByHistory = 5 + , ConflictSolveByPlaceds = 6 + , LocalVsGlobal = 7 + , MoveUp = 8 + , MaximumSlack = 9 + , Unimplemented =10 + , Repair =11 }; - public: - DataNegociate ( TrackElement* ); - ~DataNegociate (); - inline bool hasRoutingEvent () const; - inline RoutingEvent* getRoutingEvent () const; - inline TrackElement* getTrackSegment () const; - inline Track* getTrack () const; - inline TrackSegmentCost& getCost (); - //inline unsigned int getZ () const; - inline unsigned int getState () const; - inline unsigned int getStateCount () const; - inline unsigned int getRipupCount () const; - inline unsigned int getStateAndRipupCount () const; - inline void setState ( unsigned int, bool reset=false ); - inline void setRoutingEvent ( RoutingEvent* ); - inline void setRipupCount ( unsigned int ); - inline void incRipupCount (); - inline void decRipupCount (); - inline void resetRipupCount (); - inline void resetStateCount (); - inline void invalidate ( bool withPerpandiculars=false, bool withConstraints=false ); - void update (); - static string getStateString ( DataNegociate* ); - Record* _getRecord () const; - string _getString () const; - inline string _getTypeName () const; - + DataNegociate ( TrackElement* ); + ~DataNegociate (); + inline bool hasRoutingEvent () const; + inline RoutingEvent* getRoutingEvent () const; + inline TrackElement* getTrackSegment () const; + inline TrackElement* getChildSegment () const; + inline Track* getTrack () const; + inline DbU::Unit getLeftMinExtend () const; + inline DbU::Unit getRightMinExtend () const; + inline unsigned int getTerminals () const; + inline Net* getNet () const; + inline unsigned int getState () const; + inline unsigned int getStateCount () const; + inline unsigned int getRipupCount () const; + inline unsigned int getStateAndRipupCount () const; + DbU::Unit getWiringDelta ( DbU::Unit axis ) const; + inline const vector& getPerpandiculars () const; + inline const Interval& getPerpandicularFree () const; + inline void setState ( unsigned int, unsigned int flags=0 ); + inline void setRoutingEvent ( RoutingEvent* ); + inline void setChildSegment ( TrackElement* ); + inline void setRipupCount ( unsigned int ); + inline void incRipupCount (); + inline void decRipupCount (); + inline void resetRipupCount (); + inline void resetStateCount (); + void update (); + static string getStateString ( DataNegociate* ); + Record* _getRecord () const; + string _getString () const; + inline string _getTypeName () const; protected: // Attributes. - RoutingEvent* _routingEvent; - TrackElement* _trackSegment; - TrackSegmentCost _cost; - unsigned int _state :5; - unsigned int _stateCount:5; - //unsigned int _z : 5; - + TrackElement* _trackSegment; + TrackElement* _childSegment; + RoutingEvent* _routingEvent; + Net* _net; + unsigned int _state : 5; + unsigned int _stateCount : 5; + unsigned int _terminals : 5; + unsigned int _ripupCount : 16; + DbU::Unit _leftMinExtend; + DbU::Unit _rightMinExtend; + vector _attractors; + vector _perpandiculars; + Interval _perpandicularFree; private: DataNegociate ( const DataNegociate& ); DataNegociate& operator= ( const DataNegociate& ); @@ -110,29 +115,32 @@ namespace Kite { // Inline Functions. - inline bool DataNegociate::hasRoutingEvent () const { return _routingEvent != NULL; } - inline RoutingEvent* DataNegociate::getRoutingEvent () const { return _routingEvent; } - inline TrackElement* DataNegociate::getTrackSegment () const { return _trackSegment; } - inline Track* DataNegociate::getTrack () const { return _trackSegment->getTrack(); } - inline TrackSegmentCost& DataNegociate::getCost () { return _cost; } - inline unsigned int DataNegociate::getState () const { return _state; } - inline unsigned int DataNegociate::getStateCount () const { return _stateCount; } -//inline unsigned int DataNegociate::getZ () const { return _z; } - inline unsigned int DataNegociate::getRipupCount () const { return _cost.getRipupCount(); } - inline void DataNegociate::setRoutingEvent ( RoutingEvent* event ) { _routingEvent = event; } - inline void DataNegociate::setRipupCount ( unsigned int count ) { _cost.setRipupCount(count); } - inline void DataNegociate::incRipupCount () { _cost.incRipupCount(); } - inline void DataNegociate::decRipupCount () { _cost.decRipupCount(); } - inline void DataNegociate::resetRipupCount () { _cost.resetRipupCount(); } - inline void DataNegociate::resetStateCount () { _stateCount=0; } - inline string DataNegociate::_getTypeName () const { return "DataNegociate"; } + inline bool DataNegociate::hasRoutingEvent () const { return _routingEvent != NULL; } + inline RoutingEvent* DataNegociate::getRoutingEvent () const { return _routingEvent; } + inline TrackElement* DataNegociate::getTrackSegment () const { return _trackSegment; } + inline TrackElement* DataNegociate::getChildSegment () const { return _childSegment; } + inline Track* DataNegociate::getTrack () const { return _trackSegment->getTrack(); } + inline unsigned int DataNegociate::getState () const { return _state; } + inline unsigned int DataNegociate::getTerminals () const { return _terminals; } + inline unsigned int DataNegociate::getRipupCount () const { return _ripupCount; } + inline DbU::Unit DataNegociate::getLeftMinExtend () const { return _leftMinExtend; } + inline DbU::Unit DataNegociate::getRightMinExtend () const { return _rightMinExtend; } + inline Net* DataNegociate::getNet () const { return _net; } + inline const vector& DataNegociate::getPerpandiculars () const { return _perpandiculars; } + inline const Interval& DataNegociate::getPerpandicularFree () const { return _perpandicularFree; } + inline unsigned int DataNegociate::getStateCount () const { return _stateCount; } + inline void DataNegociate::resetStateCount () { _stateCount=0; } + inline void DataNegociate::setRoutingEvent ( RoutingEvent* event ) { _routingEvent = event; } + inline void DataNegociate::setChildSegment ( TrackElement* child ) { _childSegment = child; } + inline void DataNegociate::setRipupCount ( unsigned int count ) { _ripupCount = count; } + inline void DataNegociate::incRipupCount () { _ripupCount++; } + inline void DataNegociate::decRipupCount () { if (_ripupCount) _ripupCount--; } + inline void DataNegociate::resetRipupCount () { _ripupCount = 0; } + inline string DataNegociate::_getTypeName () const { return "DataNegociate"; } - inline void DataNegociate::invalidate ( bool withPerpandiculars, bool withConstraints ) - { if (_routingEvent) _routingEvent->invalidate(withPerpandiculars,withConstraints); } - - inline void DataNegociate::setState ( unsigned int state, bool reset ) + inline void DataNegociate::setState ( unsigned int state, unsigned int flags ) { - if ( (_state != state) or reset ) { + if ( (_state != state) or (flags & KtResetCount) ) { //std::cerr << "Changing state to:" << state << std::endl; _state = state; _stateCount = 1; @@ -141,10 +149,9 @@ namespace Kite { } inline unsigned int DataNegociate::getStateAndRipupCount () const - { return (_state << 4) + getRipupCount(); } + { return (_state << 4) + _ripupCount; } -} // End of Kite namespace. +} // Kite namespace. - -#endif // __KITE_DATA_NEGOCIATE__ +#endif // KITE_DATA_NEGOCIATE_H diff --git a/kite/src/kite/GraphicKiteEngine.h b/kite/src/kite/GraphicKiteEngine.h index 07d72e62..ba38fb27 100644 --- a/kite/src/kite/GraphicKiteEngine.h +++ b/kite/src/kite/GraphicKiteEngine.h @@ -2,32 +2,24 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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++ Header : "./GraphicKiteEngine.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./kite/GraphicKiteEngine.h" | +// +-----------------------------------------------------------------+ -#ifndef __KITE_GRAPHIC_KITE_ENGINE__ -#define __KITE_GRAPHIC_KITE_ENGINE__ +#ifndef KITE_GRAPHIC_KITE_ENGINE_H +#define KITE_GRAPHIC_KITE_ENGINE_H -#include +#include namespace Hurricane { class Go; @@ -37,9 +29,8 @@ namespace Hurricane { class CellViewer; } -#include "crlcore/GraphicToolEngine.h" - -#include "kite/KiteEngine.h" +#include "crlcore/GraphicToolEngine.h" +#include "kite/KiteEngine.h" namespace Kite { @@ -56,7 +47,6 @@ namespace Kite { // ------------------------------------------------------------------- // Class : "Kite::GraphicKiteEngine". - class GraphicKiteEngine : public GraphicTool { Q_OBJECT; @@ -103,7 +93,7 @@ namespace Kite { }; -} // End of Kite namespace. +} // Kite namespace. -#endif // __KITE_GRAPHIC_KITE_ENGINE__ +#endif // KITE_GRAPHIC_KITE_ENGINE_H diff --git a/kite/src/kite/HorizontalTrack.h b/kite/src/kite/HorizontalTrack.h index 9e176f01..061c5c91 100644 --- a/kite/src/kite/HorizontalTrack.h +++ b/kite/src/kite/HorizontalTrack.h @@ -2,33 +2,23 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 : "./HorizontalTrack.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./kite/HorizontalTrack.h" | +// +-----------------------------------------------------------------+ +#ifndef KITE_HORIZONTAL_TRACK_H +#define KITE_HORIZONTAL_TRACK_H - -#ifndef __KITE_HORIZONTAL_TRACK__ -#define __KITE_HORIZONTAL_TRACK__ - -#include "kite/Track.h" +#include "kite/Track.h" namespace Kite { @@ -36,7 +26,6 @@ namespace Kite { // ------------------------------------------------------------------- // Class : "HorizontalTrack". - class HorizontalTrack : public Track { @@ -61,7 +50,7 @@ namespace Kite { }; -} // End of Kite namespace. +} // Kite namespace. -#endif // __KITE_HORIZONTAL_TRACK__ +#endif // KITE_HORIZONTAL_TRACK_H diff --git a/kite/src/kite/KiteEngine.h b/kite/src/kite/KiteEngine.h index 35acf305..ac989057 100644 --- a/kite/src/kite/KiteEngine.h +++ b/kite/src/kite/KiteEngine.h @@ -2,7 +2,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -11,36 +11,36 @@ // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | -// | C++ Header : "./KiteEngine.h" | +// | C++ Header : "./kite/KiteEngine.h" | // +-----------------------------------------------------------------+ -#ifndef __KITE_KITE_ENGINE__ -#define __KITE_KITE_ENGINE__ +#ifndef KITE_KITE_ENGINE_H +#define KITE_KITE_ENGINE_H -#include +#include -#include "hurricane/Name.h" +#include "hurricane/Name.h" namespace Hurricane { class Layer; class Net; class Cell; } -#include "crlcore/RoutingGauge.h" -#include "katabatic/KatabaticEngine.h" +#include "crlcore/RoutingGauge.h" +#include "katabatic/KatabaticEngine.h" namespace Knik { class KnikEngine; } -#include "kite/TrackElement.h" -#include "kite/Configuration.h" +#include "kite/Constants.h" +#include "kite/TrackElement.h" +#include "kite/Configuration.h" namespace Kite { - using Hurricane::Name; using Hurricane::Layer; using Hurricane::Net; @@ -53,19 +53,10 @@ namespace Kite { class NegociateWindow; -// ------------------------------------------------------------------- -// Enumerations - - - enum GlobalFlags { BuildGlobalSolution=1, LoadGlobalSolution }; - // ------------------------------------------------------------------- // Class : "Kite::KiteEngine". - class KiteEngine : public KatabaticEngine { - public: - enum LookupFlags { OnAllCollapseds=1 }; public: static const Name& staticGetName (); @@ -74,8 +65,8 @@ namespace Kite { public: inline KatabaticEngine* base (); inline Configuration* getKiteConfiguration (); - inline Net* getBlockageNet (); virtual Configuration* getConfiguration (); + inline Net* getBlockageNet (); inline bool getToolSuccess () const; inline unsigned long getEventsLimit () const; inline unsigned int getRipupLimit ( unsigned int type ) const; @@ -104,29 +95,25 @@ namespace Kite { inline void setExpandStep ( float ); inline void setEdgeCapacityPercent ( float ); inline void setGlobalMinBreak ( unsigned int depth, DbU::Unit ); - void preProcess (); - void buildBlockages (); void buildPowerRails (); void protectRoutingPads (); + void preProcess (); + void setInterrupt ( bool ); + void buildBlockages (); void createGlobalGraph ( unsigned int mode ); virtual void createDetailedGrid (); void saveGlobalSolution (); void annotateGlobalGraph (); + void runNegociate ( unsigned int slowMotion=0 ); void runGlobalRouter ( unsigned int mode ); virtual void loadGlobalRouting ( unsigned int method, KatabaticEngine::NetSet& ); - void runNegociate ( unsigned int slowMotion=0 ); - void setInterrupt ( bool ); virtual void finalizeLayout (); void _gutKite (); - inline TrackElementLut& _getTrackElementLut (); - void _link ( TrackElement* ); - void _unlink ( TrackElement* ); + void _computeCagedConstraints (); TrackElement* _lookup ( Segment* ) const; inline TrackElement* _lookup ( AutoSegment* ) const; bool _check ( unsigned int& overlap, const char* message=NULL ) const; void _check ( Net* ) const; - void _computeCagedConstraints (); - void _computeCagedConstraints ( Net*, set& ); virtual Record* _getRecord () const; virtual string _getString () const; virtual string _getTypeName () const; @@ -140,7 +127,6 @@ namespace Kite { Configuration* _configuration; vector _routingPlanes; NegociateWindow* _negociateWindow; - TrackElementLut _trackSegmentLut; double _minimumWL; mutable bool _toolSuccess; @@ -179,18 +165,17 @@ namespace Kite { inline void KiteEngine::setMinimumWL ( double minimum ) { _minimumWL = minimum; } inline void KiteEngine::setPostEventCb ( Configuration::PostEventCb_t cb ) { _configuration->setPostEventCb(cb); } inline void KiteEngine::printConfiguration () const { _configuration->print(getCell()); } - inline TrackElementLut& KiteEngine::_getTrackElementLut () { return _trackSegmentLut; } - inline TrackElement* KiteEngine::_lookup ( AutoSegment* as ) const { return _lookup(as->base()); } + inline TrackElement* KiteEngine::_lookup ( AutoSegment* segment ) const { return segment->getObserver(); } // Variables. extern const char* missingRW; -} // End of Kite namespace. +} // Kite namespace. INSPECTOR_P_SUPPORT(Kite::KiteEngine); -#endif // __KITE_KITE_ENGINE__ +#endif // KITE_KITE_ENGINE_H diff --git a/kite/src/kite/Manipulator.h b/kite/src/kite/Manipulator.h new file mode 100644 index 00000000..80dc08bd --- /dev/null +++ b/kite/src/kite/Manipulator.h @@ -0,0 +1,98 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2013, 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 : "./kite/Manipulator.h" | +// +-----------------------------------------------------------------+ + + +#ifndef KITE_MANIPULATOR_H +#define KITE_MANIPULATOR_H + +#include "hurricane/DbU.h" +#include "katabatic/Constants.h" + + +namespace Kite { + + using Hurricane::DbU; + using Katabatic::KbNoFlags; + + class TrackElement; + class DataNegociate; + class RoutingEvent; + class SegmentFsm; + + +// ------------------------------------------------------------------- +// Class Declaration : "::Manipulator". + + class Manipulator { + public: + enum FunctionFlag { ToRipupLimit = 0x0001 + , AllowExpand = 0x0002 + , NoExpand = 0x0004 + , PerpandicularsFirst = 0x0008 + , ToMoveUp = 0x0010 + , AllowLocalMoveUp = 0x0020 + , AllowTerminalMoveUp = 0x0040 + , AllowShortPivotUp = 0x0080 + , NoDoglegReuse = 0x0100 + , LeftAxisHint = 0x0200 + , RightAxisHint = 0x0400 + , NotOnLastRipup = 0x0800 + }; + public: + Manipulator ( TrackElement*, SegmentFsm& ); + ~Manipulator (); + inline TrackElement* getSegment () const; + inline DataNegociate* getData () const; + inline RoutingEvent* getEvent () const; + bool canRipup ( unsigned int flags=0 ) const; + bool isCaged ( DbU::Unit ) const; + bool ripup ( unsigned int type, DbU::Unit axisHint=0 ); + bool ripupPerpandiculars ( unsigned int flags=0 ); + void repackPerpandiculars (); + void reprocessPerpandiculars (); + bool ripple (); + bool minimize (); + bool slacken ( unsigned int flags=KbNoFlags ); + bool pivotUp (); + bool pivotDown (); + bool moveUp ( unsigned int flags=0 ); + bool makeDogleg (); + bool makeDogleg ( DbU::Unit ); + bool makeDogleg ( Interval ); + bool relax ( Interval, unsigned int flags=AllowExpand ); + bool insertInTrack ( size_t ); + bool shrinkToTrack ( size_t + , unsigned int flags=0 + , DbU::Unit leftAxisHint=0 + , DbU::Unit rightAxisHint=0 + ); + bool forceToTrack ( size_t ); + bool forceOverLocals (); + private: + TrackElement* _segment; + DataNegociate* _data; + RoutingEvent* _event; + SegmentFsm& _fsm; + }; + + + inline TrackElement* Manipulator::getSegment () const { return _segment; } + inline DataNegociate* Manipulator::getData () const { return _data; } + inline RoutingEvent* Manipulator::getEvent () const { return _event; } + + +} // Kite namespace. + +#endif // KITE_MANIPULATOR_H diff --git a/kite/src/kite/NegociateWindow.h b/kite/src/kite/NegociateWindow.h index 17f1c5c8..11cd85a7 100644 --- a/kite/src/kite/NegociateWindow.h +++ b/kite/src/kite/NegociateWindow.h @@ -2,7 +2,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2011, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -11,12 +11,12 @@ // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | -// | C++ Header : "./NegociateWindow.h" | +// | C++ Header : "./kite/NegociateWindow.h" | // +-----------------------------------------------------------------+ -#ifndef __KITE_NEGOCIATE_WINDOW__ -#define __KITE_NEGOCIATE_WINDOW__ +#ifndef KITE_NEGOCIATE_WINDOW_H +#define KITE_NEGOCIATE_WINDOW_H #include #include @@ -41,7 +41,6 @@ namespace Kite { // ------------------------------------------------------------------- // Class : "Statistics". - class Statistics { public: inline Statistics (); @@ -90,39 +89,38 @@ namespace Kite { // ------------------------------------------------------------------- // Class : "Kite::NegociateWindow". - class NegociateWindow { public: enum Stage { Negociation = 1 - , Packing + , Packing = 2 }; public: - static NegociateWindow* create ( KiteEngine* ); - void destroy (); - inline bool isInterrupted () const; - inline KiteEngine* getKiteEngine () const; - Hurricane::Cell* getCell () const; - inline const Katabatic::GCellVector& getGCells () const; - inline RoutingEventQueue& getEventQueue (); - inline RoutingEventHistory& getEventHistory (); - inline RoutingEventLoop& getEventLoop (); - inline Stage getStage () const; - void setGCells ( const Katabatic::GCellVector& ); - inline void setInterrupt ( bool ); - inline void setStage ( Stage ); - double computeWirelength (); - TrackElement* addTrackSegment ( AutoSegment*, bool loading ); - void addInsertEvent ( TrackElement*, unsigned int level ); - inline void rescheduleEvent ( RoutingEvent*, unsigned int level ); - void run ( int slowMotion=0 ); - void printStatistics () const; - void _createRouting ( Katabatic::GCell* ); - size_t _negociate (); - Hurricane::Record* _getRecord () const; - std::string _getString () const; - inline std::string _getTypeName () const; + static NegociateWindow* create ( KiteEngine* ); + void destroy (); + inline bool isInterrupted () const; + inline KiteEngine* getKiteEngine () const; + Hurricane::Cell* getCell () const; + inline const Katabatic::GCellVector& getGCells () const; + inline RoutingEventQueue& getEventQueue (); + inline RoutingEventHistory& getEventHistory (); + inline RoutingEventLoop& getEventLoop (); + inline Stage getStage () const; + void setGCells ( const Katabatic::GCellVector& ); + inline void setInterrupt ( bool ); + inline void setStage ( Stage ); + double computeWirelength (); + TrackElement* createTrackSegment ( AutoSegment*, unsigned int flags ); + void addRoutingEvent ( TrackElement*, unsigned int level ); + inline void rescheduleEvent ( RoutingEvent*, unsigned int level ); + void run ( int slowMotion=0 ); + void printStatistics () const; + void _createRouting ( Katabatic::GCell* ); + size_t _negociate (); + Hurricane::Record* _getRecord () const; + std::string _getString () const; + inline std::string _getTypeName () const; private: // Attributes. @@ -157,7 +155,7 @@ namespace Kite { inline std::string NegociateWindow::_getTypeName () const { return "NegociateWindow"; } -} // End of Kite namespace. +} // Kite namespace. -#endif // __KITE_NEGOCIATE_WINDOW__ +#endif // KITE_NEGOCIATE_WINDOW_H diff --git a/kite/src/kite/PyGraphicKiteEngine.h b/kite/src/kite/PyGraphicKiteEngine.h index d7b94208..95b60e2e 100644 --- a/kite/src/kite/PyGraphicKiteEngine.h +++ b/kite/src/kite/PyGraphicKiteEngine.h @@ -2,7 +2,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved +// Copyright (c) UPMC/LIP6 2012-2013, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -15,8 +15,8 @@ // +-----------------------------------------------------------------+ -#ifndef __KITE_PY_GRAPHIC_KITE_ENGINE__ -#define __KITE_PY_GRAPHIC_KITE_ENGINE__ +#ifndef KITE_PY_GRAPHIC_KITE_ENGINE_H +#define KITE_PY_GRAPHIC_KITE_ENGINE_H #include "crlcore/PyGraphicToolEngine.h" #include "kite/GraphicKiteEngine.h" @@ -49,8 +49,8 @@ extern "C" { #define PY_GRAPHIC_KITE_ENGINE_O(v) ( PY_GRAPHIC_KITE_ENGINE(v)->_baseObject._object ) -} // End of extern "C". +} // extern "C". } // Kite namespace. -#endif // __KITE_PYGRAPHICKITEENGINE__ +#endif // KITE_PY_GRAPHIC_KITE_ENGINE_H diff --git a/kite/src/kite/PyKiteEngine.h b/kite/src/kite/PyKiteEngine.h index 25b0568f..00e2f13e 100644 --- a/kite/src/kite/PyKiteEngine.h +++ b/kite/src/kite/PyKiteEngine.h @@ -2,7 +2,7 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2010-2012, All Rights Reserved +// Copyright (c) UPMC/LIP6 2010-2013, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -15,8 +15,8 @@ // +-----------------------------------------------------------------+ -#ifndef __PY_KITE_ENGINE__ -#define __PY_KITE_ENGINE__ +#ifndef PY_KITE_ENGINE_H +#define PY_KITE_ENGINE_H #include "hurricane/isobar/PyHurricane.h" #include "crlcore/PyToolEngine.h" @@ -55,4 +55,4 @@ extern "C" { } // Kite namespace. -#endif // __PY_KITE_ENGINE__ +#endif // PY_KITE_ENGINE_H diff --git a/kite/src/kite/RoutingEvent.h b/kite/src/kite/RoutingEvent.h index 1f8f9b00..b7f1f85f 100644 --- a/kite/src/kite/RoutingEvent.h +++ b/kite/src/kite/RoutingEvent.h @@ -1,33 +1,26 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 : "./RoutingEvent.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./kite/RoutingEvent.h" | +// +-----------------------------------------------------------------+ -#ifndef __KITE_ROUTING_EVENT__ -#define __KITE_ROUTING_EVENT__ +#ifndef KITE_ROUTING_EVENT_H +#define KITE_ROUTING_EVENT_H +#include #include #include +#include #include "hurricane/Interval.h" namespace Hurricane { @@ -36,12 +29,15 @@ namespace Hurricane { #include "kite/TrackCost.h" #include "kite/TrackElement.h" +#include "kite/DataNegociate.h" #include "kite/Session.h" namespace Kite { + using std::set; using std::vector; + using std::binary_function; using Hurricane::DbU; using Hurricane::Interval; using Hurricane::Net; @@ -54,26 +50,26 @@ namespace Kite { // ------------------------------------------------------------------- // Class : "RoutingEvent". - class RoutingEvent { private: class Key { public: - struct Compare { + class Compare : public binary_function { + public: bool operator() ( const Key& lhs, const Key& rhs ) const; }; + public: Key ( const RoutingEvent* ); void update ( const RoutingEvent* ); private: - bool _slackenStrap; - bool _isHorizontal; - bool _canRipple; unsigned int _tracksNb:6; float _priority; unsigned int _eventLevel; + unsigned int _segFlags; + unsigned int _layerDepth; DbU::Unit _length; DbU::Unit _axis; DbU::Unit _sourceU; @@ -83,88 +79,92 @@ namespace Kite { }; public: - // Sub-Class: "Compare". - struct Compare { + // Sub-Class: "Compare". + class Compare : public binary_function { + public: bool operator() ( const RoutingEvent* lhs, const RoutingEvent* rhs ) const; }; + // Sub-Class: "CompareById". + class CompareById : public binary_function { + public: + inline bool operator() ( const RoutingEvent* lhs, const RoutingEvent* rhs ) const; + }; friend class Compare; public: enum Mode { Negociate=1, Pack=2, Repair=3 }; public: - static unsigned int getStage (); - static size_t getAllocateds (); - static size_t getProcesseds (); - static size_t getCloneds (); - static void resetProcesseds (); - static void setStage ( unsigned int ); - public: - static RoutingEvent* create ( TrackElement*, unsigned int mode=Negociate ); - RoutingEvent* clone () const; - void destroy (); - inline bool isCloned () const; - inline bool isValid () const; - bool isUnimplemented () const; - inline bool isProcessed () const; - inline bool isDisabled () const; - inline bool isForcedToHint () const; - inline bool isSheared () const; - inline bool isRipedByLocal () const; - inline bool getMode () const; - inline bool canMinimize () const; - unsigned int getState () const; - inline const Key& getKey () const; - inline TrackElement* getSegment () const; - inline const vector& getPerpandiculars () const; - inline DbU::Unit getAxisHint () const; - inline DbU::Unit getAxisHistory () const; - inline long getAxisWeight ( DbU::Unit ) const; - inline const Interval& getOptimalAxis () const; - inline const Interval& getConstraints () const; - inline const Interval& getOptimal () const; - inline const Interval& getPerpandicular () const; - inline Katabatic::GCell* getShearGCell () const; - inline float getPriority () const; - inline unsigned int getTracksNb () const; - inline unsigned int getTracksFree () const; - inline unsigned int getInsertState () const; - inline unsigned int getEventLevel () const; - inline void invalidate ( bool withPerpandiculars=false, bool withConstraints=false ); - void revalidate ( bool force=false ); - inline void updateKey (); - void process ( RoutingEventQueue& - , RoutingEventHistory& - , RoutingEventLoop& - ); - void setSegment ( TrackElement* ); - RoutingEvent* reschedule ( RoutingEventQueue&, unsigned int eventLevel ); - void setMode ( unsigned int ); - void setState ( unsigned int ); - inline void setProcessed ( bool state=true ); - inline void setDisabled ( bool state=true ); - inline void setMinimized ( bool state=true ); - inline void setRipedByLocal ( bool state=true ); - void setEventLevel ( unsigned int ); - inline void setTracksFree ( unsigned int ); - inline void setForcedToHint ( bool state = true ); - void setAxisHint ( DbU::Unit ); - void cacheAxisHint (); - inline void setOptimalAxis ( Interval ); - inline void incInsertState (); - inline void resetInsertState (); - void _processNegociate ( RoutingEventQueue&, RoutingEventHistory& ); - void _processPack ( RoutingEventQueue&, RoutingEventHistory& ); - void _processRepair ( RoutingEventQueue&, RoutingEventHistory& ); - Record* _getRecord () const; - string _getString () const; - string _getTypeName () const; + static unsigned int getStage (); + static size_t getAllocateds (); + static size_t getProcesseds (); + static size_t getCloneds (); + static void resetProcesseds (); + static void setStage ( unsigned int ); + public: + static RoutingEvent* create ( TrackElement*, unsigned int mode=Negociate ); + RoutingEvent* clone () const; + void destroy (); + inline bool isCloned () const; + inline bool isValid () const; + bool isUnimplemented () const; + inline bool isProcessed () const; + inline bool isDisabled () const; + inline bool isForcedToHint () const; + inline bool isSheared () const; + inline bool isRipedByLocal () const; + inline unsigned int getId () const; + inline bool getMode () const; + inline bool canMinimize () const; + unsigned int getState () const; + inline const Key& getKey () const; + inline TrackElement* getSegment () const; + inline const vector& getPerpandiculars () const; + inline DbU::Unit getAxisHint () const; + inline DbU::Unit getAxisHistory () const; + inline long getAxisWeight ( DbU::Unit ) const; + inline const Interval& getConstraints () const; + inline const Interval& getOptimal () const; + inline const Interval& getPerpandicularFree () const; + inline float getPriority () const; + inline unsigned int getTracksNb () const; + inline unsigned int getTracksFree () const; + inline unsigned int getInsertState () const; + inline unsigned int getEventLevel () const; + void revalidate (); + inline void updateKey (); + void process ( RoutingEventQueue& + , RoutingEventHistory& + , RoutingEventLoop& + ); + void setSegment ( TrackElement* ); + RoutingEvent* reschedule ( RoutingEventQueue&, unsigned int eventLevel ); + void setMode ( unsigned int ); + void setState ( unsigned int ); + inline void setProcessed ( bool state=true ); + inline void setDisabled ( bool state=true ); + inline void setMinimized ( bool state=true ); + inline void setRipedByLocal ( bool state=true ); + inline void setTracksFree ( unsigned int ); + inline void setForcedToHint ( bool state = true ); + void setAxisHint ( DbU::Unit ); + void setAxisHintFromParent (); + inline void incInsertState (); + inline void resetInsertState (); + inline void setEventLevel ( unsigned int ); + void _processNegociate ( RoutingEventQueue&, RoutingEventHistory& ); + void _processPack ( RoutingEventQueue&, RoutingEventHistory& ); + void _processRepair ( RoutingEventQueue&, RoutingEventHistory& ); + Record* _getRecord () const; + string _getString () const; + string _getTypeName () const; private: RoutingEvent ( TrackElement*, unsigned int mode ); ~RoutingEvent (); protected: // Attributes. + static unsigned int _idCounter; static unsigned int _stage; static size_t _allocateds; static size_t _processeds; @@ -172,21 +172,18 @@ namespace Kite { mutable bool _cloned; bool _processed; bool _disabled; - bool _valid; - bool _validConstraints; - bool _validPerpandiculars; bool _canHandleConstraints; bool _minimized; bool _forceToHint; bool _ripedByLocal; + unsigned int _id; TrackElement* _segment; + DataNegociate* _dataNegociate; DbU::Unit _axisHistory; DbU::Unit _axisHint; - Interval _optimalAxis; Interval _constraints; Interval _optimal; - Interval _perpandicular; - Katabatic::GCell* _shearGCell; + //Interval _perpandicular; unsigned int _tracksNb : 6; unsigned int _tracksFree : 4; unsigned int _insertState : 6; @@ -194,54 +191,52 @@ namespace Kite { unsigned int _rippleState : 4; unsigned int _eventLevel; float _priority; - vector _perpandiculars; + //vector _perpandiculars; Key _key; }; // Inline Functions. inline bool RoutingEvent::isCloned () const { return _cloned; } - inline bool RoutingEvent::isValid () const { return _valid; } inline bool RoutingEvent::isProcessed () const { return _processed; } inline bool RoutingEvent::isDisabled () const { return _disabled; } inline bool RoutingEvent::isForcedToHint () const { return _forceToHint; } - inline bool RoutingEvent::isSheared () const { return (_shearGCell != NULL); } inline bool RoutingEvent::isRipedByLocal () const { return _ripedByLocal; } + inline unsigned int RoutingEvent::getId () const { return _id; } inline bool RoutingEvent::getMode () const { return _mode; } inline bool RoutingEvent::canMinimize () const { return !_minimized; } inline const RoutingEvent::Key& RoutingEvent::getKey () const { return _key; } inline TrackElement* RoutingEvent::getSegment () const { return _segment; } - inline const vector& RoutingEvent::getPerpandiculars () const { return _perpandiculars; } + inline const vector& RoutingEvent::getPerpandiculars () const { return _dataNegociate->getPerpandiculars(); } +//inline const vector& RoutingEvent::getPerpandiculars () const { return _perpandiculars; } inline DbU::Unit RoutingEvent::getAxisHistory () const { return _axisHistory; } inline DbU::Unit RoutingEvent::getAxisHint () const { return _axisHint; } inline long RoutingEvent::getAxisWeight ( DbU::Unit axis ) const { return abs(axis - getAxisHint()); } - inline const Interval& RoutingEvent::getOptimalAxis () const { return _optimalAxis; } inline const Interval& RoutingEvent::getConstraints () const { return _constraints; } inline const Interval& RoutingEvent::getOptimal () const { return _optimal; } - inline const Interval& RoutingEvent::getPerpandicular () const { return _perpandicular; } + inline const Interval& RoutingEvent::getPerpandicularFree () const { return _dataNegociate->getPerpandicularFree(); } +//inline const Interval& RoutingEvent::getPerpandicular () const { return _perpandicular; } inline float RoutingEvent::getPriority () const { return _priority; } inline unsigned int RoutingEvent::getEventLevel () const { return _eventLevel; } inline unsigned int RoutingEvent::getTracksNb () const { return _tracksNb; } inline unsigned int RoutingEvent::getTracksFree () const { return _tracksFree; } inline unsigned int RoutingEvent::getInsertState () const { return _insertState; } - inline Katabatic::GCell* RoutingEvent::getShearGCell () const { return _shearGCell; } inline void RoutingEvent::setProcessed ( bool state ) { _processed = state; } inline void RoutingEvent::setDisabled ( bool state ) { _disabled = state; } inline void RoutingEvent::setMinimized ( bool state ) { _minimized = state; } inline void RoutingEvent::setRipedByLocal ( bool state ) { _ripedByLocal = state; } inline void RoutingEvent::setTracksFree ( unsigned int nb ) { _tracksFree = nb; } inline void RoutingEvent::setForcedToHint ( bool state ) { _forceToHint = state; } - inline void RoutingEvent::setOptimalAxis ( Interval i ) { _optimalAxis = i; } inline void RoutingEvent::incInsertState () { _insertState++; } inline void RoutingEvent::resetInsertState () { _insertState = 0; } + inline void RoutingEvent::setEventLevel ( unsigned int level ) { _eventLevel = level; } inline void RoutingEvent::updateKey () { revalidate(); _key.update(this); } - inline void RoutingEvent::invalidate ( bool withPerpandiculars, bool withConstraints ) - { - _valid = false; - _validPerpandiculars = _validPerpandiculars and !withPerpandiculars; - _validConstraints = _validConstraints and !withConstraints; - } + inline bool RoutingEvent::CompareById::operator() ( const RoutingEvent* lhs, const RoutingEvent* rhs ) const + { return lhs->getId() < rhs->getId(); } + + + typedef set RoutingEventSet; // ------------------------------------------------------------------- @@ -275,10 +270,10 @@ namespace Kite { # endif -} // End of Kite namespace. +} // Kite namespace. INSPECTOR_P_SUPPORT(Kite::RoutingEvent); -# endif +#endif // KITE_ROUTING_EVENT_H diff --git a/kite/src/kite/RoutingEventHistory.h b/kite/src/kite/RoutingEventHistory.h index 72528b75..c3f0f087 100644 --- a/kite/src/kite/RoutingEventHistory.h +++ b/kite/src/kite/RoutingEventHistory.h @@ -1,39 +1,28 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 : "./RoutingEventHistory.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./kite/RoutingEventHistory.h" | +// +-----------------------------------------------------------------+ -#ifndef __KITE_ROUTING_EVENT_HISTORY__ -#define __KITE_ROUTING_EVENT_HISTORY__ +#ifndef KITE_ROUTING_EVENT_HISTORY_H +#define KITE_ROUTING_EVENT_HISTORY_H - -#include -#include +#include +#include namespace Kite { - using std::vector; using std::ostream; @@ -42,7 +31,6 @@ namespace Kite { // ------------------------------------------------------------------- // Class : "RoutingEventHistory". - class RoutingEventHistory { @@ -77,7 +65,7 @@ namespace Kite { inline string RoutingEventHistory::_getTypeName () const { return "RoutingEventHistory"; } -} // End of Kite namespace. +} // Kite namespace. -#endif // __KITE_ROUTING_EVENT_HISTORY__ +#endif // KITE_ROUTING_EVENT_HISTORY_H diff --git a/kite/src/kite/RoutingEventLoop.h b/kite/src/kite/RoutingEventLoop.h index 3c64f9ec..d2e32d65 100644 --- a/kite/src/kite/RoutingEventLoop.h +++ b/kite/src/kite/RoutingEventLoop.h @@ -1,32 +1,23 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 : "./kite/RoutingEventLoop.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./kite/RoutingEventLoop.h" | +// +-----------------------------------------------------------------+ -#ifndef __KITE_ROUTING_EVENT_LOOP__ -#define __KITE_ROUTING_EVENT_LOOP__ +#ifndef KITE_ROUTING_EVENT_LOOP_H +#define KITE_ROUTING_EVENT_LOOP_H -#include +#include namespace Kite { @@ -84,10 +75,10 @@ namespace Kite { -} // End of Kite namespace. +} // Kite namespace. //INSPECTOR_P_SUPPORT(Kite::RoutingEvent); -#endif // __KITE_ROUTING_EVENT_LOOP__ +#endif // KITE_ROUTING_EVENT_LOOP_H diff --git a/kite/src/kite/RoutingEventQueue.h b/kite/src/kite/RoutingEventQueue.h index 945b42c7..2bbebeb5 100644 --- a/kite/src/kite/RoutingEventQueue.h +++ b/kite/src/kite/RoutingEventQueue.h @@ -1,40 +1,29 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2011, All Rights Reserved -// -// =================================================================== -// -// $Id$ +// Copyright (c) UPMC 2008-2013, 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 : "./RoutingEventQueue.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | +// | C++ Header : "./kite/RoutingEventQueue.h" | // +-----------------------------------------------------------------+ -#ifndef __KITE_ROUTING_EVENT_QUEUE__ -#define __KITE_ROUTING_EVENT_QUEUE__ +#ifndef KITE_ROUTING_EVENT_QUEUE_H +#define KITE_ROUTING_EVENT_QUEUE_H - -#include -#include -#include "kite/RoutingEvent.h" +#include +#include +#include "kite/RoutingEvent.h" namespace Kite { - using std::set; using std::multiset; using std::vector; @@ -42,23 +31,23 @@ namespace Kite { // ------------------------------------------------------------------- // Class : "RoutingEventQueue". - class RoutingEventQueue { public: RoutingEventQueue (); ~RoutingEventQueue (); - void load ( const vector& ); - void add ( TrackElement*, unsigned int level ); inline bool empty () const; inline size_t size () const; inline unsigned int getTopEventLevel () const; - void push ( RoutingEvent* ); RoutingEvent* pop (); + void load ( const vector& ); + void add ( TrackElement*, unsigned int level ); + inline void push ( RoutingEvent* ); void repush ( RoutingEvent* ); void repushInvalidateds (); void commit (); + void prepareRepair (); void clear (); void dump () const; void _keyCheck () const; @@ -69,7 +58,7 @@ namespace Kite { protected: // Attributes. unsigned int _topEventLevel; - set _pushRequests; + RoutingEventSet _pushRequests; multiset _events; private: @@ -84,9 +73,10 @@ namespace Kite { inline size_t RoutingEventQueue::size () const { return _events.size(); } inline unsigned int RoutingEventQueue::getTopEventLevel () const { return _topEventLevel; } inline string RoutingEventQueue::_getTypeName () const { return "EventQueue"; } + inline void RoutingEventQueue::push ( RoutingEvent* event ) { _pushRequests.insert( event ); } -} // End of Kite namespace. +} // Kite namespace. -#endif // __KITE_ROUTING_EVENT_QUEUE__ +#endif // KITE_ROUTING_EVENT_QUEUE_H diff --git a/kite/src/kite/RoutingPlane.h b/kite/src/kite/RoutingPlane.h index 48f84535..867239d7 100644 --- a/kite/src/kite/RoutingPlane.h +++ b/kite/src/kite/RoutingPlane.h @@ -1,47 +1,36 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 : "./RoutingPlane.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./kite/RoutingPlane.h" | +// +-----------------------------------------------------------------+ -#ifndef __KITE_ROUTING_PLANE__ -#define __KITE_ROUTING_PLANE__ +#ifndef KITE_ROUTING_PLANE_H +#define KITE_ROUTING_PLANE_H - -#include "crlcore/RoutingLayerGauge.h" -#include "kite/Track.h" +#include "crlcore/RoutingLayerGauge.h" +#include "kite/Track.h" namespace Kite { - using CRL::RoutingLayerGauge; + using Katabatic::KbDirectionMask; class KiteEngine; // ------------------------------------------------------------------- // Class : "RoutingPlane". - class RoutingPlane { public: @@ -65,7 +54,7 @@ namespace Kite { inline size_t computeTracksSize () const; inline DbU::Unit getTrackPosition ( size_t index ) const; Track* getTrackByIndex ( size_t index ) const; - Track* getTrackByPosition ( DbU::Unit axis, unsigned int mode=Constant::Nearest ) const; + Track* getTrackByPosition ( DbU::Unit axis, unsigned int mode=KtNearest ) const; bool _check ( unsigned int& overlaps ) const; Record* _getRecord () const; string _getString () const; @@ -82,6 +71,7 @@ namespace Kite { KiteEngine* _kite; RoutingLayerGauge* _layerGauge; size_t _depth; + unsigned int _flags; DbU::Unit _axisMin; DbU::Unit _axisMax; DbU::Unit _trackMin; @@ -104,7 +94,7 @@ namespace Kite { inline KiteEngine* RoutingPlane::getKiteEngine () const { return _kite; } inline RoutingLayerGauge* RoutingPlane::getLayerGauge () const { return _layerGauge; } - inline unsigned int RoutingPlane::getDirection () const { return _layerGauge->getDirection(); } + inline unsigned int RoutingPlane::getDirection () const { return _flags & KbDirectionMask; } inline size_t RoutingPlane::getDepth () const { return _depth; } inline DbU::Unit RoutingPlane::getAxisMin () const { return _axisMin; } inline DbU::Unit RoutingPlane::getAxisMax () const { return _axisMax; } @@ -122,16 +112,16 @@ namespace Kite { { return _layerGauge->getTrackPosition(_axisMin,index); } inline bool RoutingPlane::isHorizontal () const - { return (getDirection() == Constant::Horizontal); } + { return (getDirection() & KbHorizontal); } inline bool RoutingPlane::isVertical () const - { return (getDirection() == Constant::Vertical); } + { return (getDirection() & KbVertical); } -} // End of Kite namespace. +} // Kite namespace. INSPECTOR_P_SUPPORT(Kite::RoutingPlane); -#endif // __KITE_ROUTING_PLANE__ +#endif // KITE_ROUTING_PLANE_H diff --git a/kite/src/kite/SegmentFsm.h b/kite/src/kite/SegmentFsm.h new file mode 100644 index 00000000..7ca62734 --- /dev/null +++ b/kite/src/kite/SegmentFsm.h @@ -0,0 +1,185 @@ +// -*- C++ -*- +// +// This file is part of the Coriolis Software. +// Copyright (c) UPMC 2008-2013, 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 : "./kite/SegmentFsm.h" | +// +-----------------------------------------------------------------+ + + +#ifndef KITE_SEGMENT_FSM_H +#define KITE_SEGMENT_FSM_H + +#include "kite/TrackCost.h" + +namespace Kite { + + class TrackElement; + class DataNegociate; + class RoutingEvent; + class RoutingEventQueue; + class RoutingEventHistory; + + +// ------------------------------------------------------------------- +// Class : "SegmentAction". + + class SegmentAction { + public: + enum Type { Self = (1<< 0) + , Other = (1<< 1) + , Perpandicular = (1<< 2) + , Insert = (1<< 3) + , Ripup = (1<< 4) + , RipedByLocal = (1<< 5) + , ResetRipup = (1<< 6) + , ToRipupLimit = (1<< 7) + , MoveToAxis = (1<< 8) + , AxisHint = (1<< 9) + , PackingMode = (1<<10) + , ToState = (1<<11) + , EventLevel1 = (1<<12) + , EventLevel2 = (1<<13) + , EventLevel3 = (1<<14) + , EventLevel4 = (1<<15) + , EventLevel5 = (1<<16) + , SelfInsert = Self |Insert + , SelfRipup = Self |Ripup + , SelfRipupPerpand = Self |Ripup|Perpandicular + , SelfRipupPerpandWithAxisHint = Self |Ripup|Perpandicular|EventLevel4|AxisHint + , OtherRipup = Other|Ripup + , OtherRipupPerpandAndPushAside = Other|Ripup|Perpandicular|EventLevel3|AxisHint + , OtherRipupPerpandAndPacking = Other|Ripup|Perpandicular|EventLevel4|PackingMode + }; + public: + SegmentAction ( TrackElement* + , unsigned int type + , DbU::Unit axisHint=0 + , unsigned int toState =0 + ); + inline TrackElement* getSegment () const; + inline unsigned int getType () const; + inline void setAxisHint ( DbU::Unit ); + inline unsigned int setFlag ( unsigned int ); + bool doAction ( RoutingEventQueue& ); + private: + TrackElement* _segment; + unsigned int _type; + DbU::Unit _axisHint; + unsigned int _toState; + }; + + + inline TrackElement* SegmentAction::getSegment () const { return _segment; } + inline unsigned int SegmentAction::getType () const { return _type; } + inline void SegmentAction::setAxisHint ( DbU::Unit axis ) { _axisHint = axis; } + inline unsigned int SegmentAction::setFlag ( unsigned int flag ) { _type |= flag; return _type; } + + +// ------------------------------------------------------------------- +// Class : "SegmentFsm". + + class SegmentFsm { + + public: + enum State { MissingData = (1<<0) + , EmptyTrackList = (1<<1) + , Inserted = (1<<2) + , Self = (1<<3) + , Other = (1<<4) + , Ripup = (1<<5) + , MaximumSlack = (1<<6) + , SelfInserted = Self | Inserted + , OtherRipup = Other | Ripup + , SelfMaximumSlack = Self | MaximumSlack + }; + enum SlackenFlags { NoRecursive = (1<<0) + , NoTransition = (1<<1) + }; + + public: + SegmentFsm ( RoutingEvent* + , RoutingEventQueue& + , RoutingEventHistory& + ); + inline bool isFullBlocked () const; + inline RoutingEvent* getEvent () const; + inline RoutingEventQueue& getQueue () const; + inline RoutingEventHistory& getHistory () const; + inline unsigned int getState () const; + inline DataNegociate* getData (); + inline Interval& getConstraint (); + inline Interval& getOptimal (); + inline vector& getCosts (); + inline TrackCost& getCost ( size_t ); + inline Track* getTrack ( size_t ); + inline size_t getBegin ( size_t ); + inline size_t getEnd ( size_t ); + inline vector& getActions (); + inline void setState ( unsigned int ); + void addAction ( TrackElement* + , unsigned int type + , DbU::Unit axisHint=0 + , unsigned int toState =0 + ); + void doActions (); + inline void clearActions (); + bool insertInTrack ( size_t ); + bool conflictSolveByHistory (); + bool conflictSolveByPlaceds (); + bool solveTerminalVsGlobal (); + bool desaturate (); + bool slackenTopology ( unsigned int flags=0 ); + bool solveFullBlockages (); + private: + bool _slackenStrap ( TrackElement*& + , DataNegociate*& + , unsigned int flags ); + bool _slackenLocal ( TrackElement*& + , DataNegociate*& + , unsigned int flags ); + bool _slackenGlobal ( TrackElement*& + , DataNegociate*& + , unsigned int flags ); + private: + RoutingEvent* _event; + RoutingEventQueue& _queue; + RoutingEventHistory& _history; + unsigned int _state; + DataNegociate* _data; + Interval _constraint; + Interval _optimal; + vector _costs; + vector _actions; + bool _fullBlocked; + }; + + + inline bool SegmentFsm::isFullBlocked () const { return _fullBlocked and _costs.size(); } + inline RoutingEvent* SegmentFsm::getEvent () const { return _event; } + inline RoutingEventQueue& SegmentFsm::getQueue () const { return _queue; } + inline RoutingEventHistory& SegmentFsm::getHistory () const { return _history; } + inline unsigned int SegmentFsm::getState () const { return _state; } + inline DataNegociate* SegmentFsm::getData () { return _data; } + inline Interval& SegmentFsm::getConstraint () { return _constraint; } + inline Interval& SegmentFsm::getOptimal () { return _optimal; } + inline vector& SegmentFsm::getCosts () { return _costs; } + inline TrackCost& SegmentFsm::getCost ( size_t i ) { return _costs[i]; } + inline Track* SegmentFsm::getTrack ( size_t i ) { return _costs[i].getTrack(); } + inline size_t SegmentFsm::getBegin ( size_t i ) { return _costs[i].getBegin(); } + inline size_t SegmentFsm::getEnd ( size_t i ) { return _costs[i].getEnd(); } + inline vector& SegmentFsm::getActions () { return _actions; } + inline void SegmentFsm::setState ( unsigned int state ) { _state = state; } + inline void SegmentFsm::clearActions () { _actions.clear(); } + + +} // Kite namespace. + +#endif // KITE_SEGMENT_FSM_H diff --git a/kite/src/kite/Session.h b/kite/src/kite/Session.h index 0ba0d988..232eef66 100644 --- a/kite/src/kite/Session.h +++ b/kite/src/kite/Session.h @@ -1,34 +1,25 @@ - -// -*- C++ -*- +// -*- mode: C++; explicit-buffer-name: "Session.h" -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 : "./Session.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./kite/Session.h" | +// +-----------------------------------------------------------------+ -#ifndef __KITE_SESSION__ -#define __KITE_SESSION__ +#ifndef KITE_SESSION_H +#define KITE_SESSION_H -#include -#include -#include +#include +#include +#include namespace Hurricane { class Record; @@ -36,7 +27,7 @@ namespace Hurricane { class Segment; } -#include "katabatic/Session.h" +#include "katabatic/Session.h" namespace Katabatic { class GCell; class AutoSegment; @@ -64,7 +55,6 @@ namespace Kite { // ------------------------------------------------------------------- // Class : "Session". - class Session : public Katabatic::Session { @@ -72,39 +62,35 @@ namespace Kite { static Session* open ( KiteEngine* ); static Session* get ( const char* message=NULL ); inline static Katabatic::Session* base (); + inline static bool isEmpty (); inline static KiteEngine* getKiteEngine (); static Configuration* getConfiguration (); inline static Net* getBlockageNet (); inline static NegociateWindow* getNegociateWindow (); inline static unsigned int getRipupCost (); inline static Katabatic::GCell* getGCellUnder ( DbU::Unit, DbU::Unit ); + static void setInterrupt ( bool ); inline static void addInsertEvent ( TrackMarker* , Track* ); inline static void addInsertEvent ( TrackElement* , Track* ); inline static void addRemoveEvent ( TrackElement* ); inline static void addMoveEvent ( TrackElement* , Track* ); inline static void addSortEvent ( Track*, bool forced=false ); inline static size_t revalidate (); - inline static bool isEmpty (); - static void setInterrupt ( bool ); - static void link ( TrackElement* ); - static void unlink ( TrackElement* ); static TrackElement* lookup ( Segment* ); static TrackElement* lookup ( AutoSegment* ); - static Katabatic::GCell* lookup ( Katabatic::GCell* ); private: KiteEngine* _getKiteEngine (); Net* _getBlockageNet (); - NegociateWindow* _getNegociateWindow (); unsigned int _getRipupCost (); Katabatic::GCell* _getGCellUnder ( DbU::Unit, DbU::Unit ); - Katabatic::GCell* _lookup ( Katabatic::GCell* ); + virtual size_t _revalidate (); + bool _isEmpty () const; + NegociateWindow* _getNegociateWindow (); void _addInsertEvent ( TrackMarker* , Track* ); void _addInsertEvent ( TrackElement* , Track* ); void _addRemoveEvent ( TrackElement* ); void _addMoveEvent ( TrackElement* , Track* ); void _addSortEvent ( Track*, bool forced ); - virtual size_t _revalidate (); - bool _isEmpty () const; virtual Record* _getRecord () const; virtual string _getTypeName () const; @@ -131,7 +117,7 @@ namespace Kite { Session ( KiteEngine* ); virtual ~Session (); virtual void _postCreate (); - virtual size_t _preDestroy (); + virtual void _preDestroy (); private: Session ( const Session& ); Session& operator= ( const Session& ); @@ -193,7 +179,6 @@ namespace Kite { { return get("isEmpty()")->_isEmpty(); } -} // End of Kite namespace. +} // Kite namespace. - -#endif // __KITE_SESSION__ +#endif // KITE_SESSION_H diff --git a/kite/src/kite/Track.h b/kite/src/kite/Track.h index 009b5728..e3008733 100644 --- a/kite/src/kite/Track.h +++ b/kite/src/kite/Track.h @@ -2,31 +2,21 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 : "./Track.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./kite/Track.h" | +// +-----------------------------------------------------------------+ - - -#ifndef __KITE_TRACK__ -#define __KITE_TRACK__ +#ifndef KITE_TRACK_H +#define KITE_TRACK_H #include "hurricane/Point.h" namespace Hurricane { @@ -39,7 +29,6 @@ namespace Hurricane { namespace Kite { - using Hurricane::Point; using Hurricane::Layer; @@ -50,43 +39,37 @@ namespace Kite { // ------------------------------------------------------------------- // Class : "Track". - class Track { public: - enum IndexState { MinTrackMin = (1<<0) - , MinSegmentMin = (1<<1) - , MinSegmentMax = (1<<2) - , MaxTrackMax = (1<<3) - , MaxSegmentMin = (1<<4) - , MaxNextSegmentMin = (1<<5) - , MaxSegmentMax = (1<<6) - , BeforeFirst = MinTrackMin | MaxSegmentMin - , Inside = MinSegmentMin | MaxSegmentMax - , Outside = MinSegmentMax | MaxNextSegmentMin - , AfterLast = MinSegmentMax | MaxTrackMax - , EmptyTrack = MinTrackMin | MaxTrackMax - , MinMask = MinTrackMin - | MinSegmentMin - | MinSegmentMax - , MaxMask = MaxTrackMax - | MaxSegmentMin - | MaxNextSegmentMin - | MaxSegmentMax + enum IndexState { BeginIsTrackMin = 0x00000001 + , BeginIsSegmentMin = 0x00000002 + , BeginIsSegmentMax = 0x00000004 + , EndIsTrackMax = 0x00000008 + , EndIsSegmentMin = 0x00000010 + , EndIsNextSegmentMin = 0x00000020 + , EndIsSegmentMax = 0x00000040 + , BeforeFirstElement = BeginIsTrackMin |EndIsSegmentMin + , InsideElement = BeginIsSegmentMin|EndIsSegmentMax + , OutsideElement = BeginIsSegmentMax|EndIsNextSegmentMin + , AfterLastElement = BeginIsSegmentMax|EndIsTrackMax + , EmptyTrack = BeginIsTrackMin |EndIsTrackMax + , BeginMask = BeginIsTrackMin |BeginIsSegmentMin|BeginIsSegmentMax + , EndMask = EndIsTrackMax |EndIsSegmentMin |EndIsNextSegmentMin|EndIsSegmentMax }; public: // Static Attributes. - static const size_t NPOS; + static const size_t npos; public: void destroy (); - inline RoutingPlane* getRoutingPlane () const; - KiteEngine* getKiteEngine () const; virtual bool isHorizontal () const = 0; virtual bool isVertical () const = 0; inline bool isLocalAssigned () const; + inline RoutingPlane* getRoutingPlane () const; + KiteEngine* getKiteEngine () const; virtual unsigned int getDirection () const = 0; inline size_t getIndex () const; unsigned int getDepth () const; @@ -95,38 +78,38 @@ namespace Kite { inline DbU::Unit getAxis () const; inline DbU::Unit getMin () const; inline DbU::Unit getMax () const; - Track* getNext () const; - Track* getPrevious () const; + Track* getNextTrack () const; + Track* getPreviousTrack () const; inline size_t getSize () const; + virtual Point getPosition ( DbU::Unit coordinate ) const = 0; + TrackElement* getSegment ( size_t index ) const; + TrackElement* getSegment ( DbU::Unit position ) const; TrackElement* getNext ( size_t& index, Net* ) const; TrackElement* getPrevious ( size_t& index, Net* ) const; TrackElement* getNextFixed ( size_t& index ) const; - TrackElement* getSegment ( size_t index ) const; - TrackElement* getSegment ( DbU::Unit position ) const; - void getIBounds ( DbU::Unit position, size_t& begin, size_t& end, unsigned int& state ) const; + size_t find ( const TrackElement* ) const; + DbU::Unit getSourcePosition ( vector::iterator ) const; + DbU::Unit getMinimalPosition ( size_t index, unsigned int state ) const; + DbU::Unit getMaximalPosition ( size_t index, unsigned int state ) const; + Interval getFreeInterval ( DbU::Unit position, Net* net=NULL ) const; + Interval getOccupiedInterval ( size_t& begin ) const; + Interval expandFreeInterval ( size_t& begin, size_t& end, unsigned int state, Net* ) const; + void getBeginIndex ( DbU::Unit position, size_t& begin, unsigned int& state ) const; void getOverlapBounds ( Interval, size_t& begin, size_t& end ) const; TrackCost getOverlapCost ( Interval, Net*, size_t begin, size_t end, unsigned int flags ) const; TrackCost getOverlapCost ( Interval, Net*, unsigned int flags ) const; TrackCost getOverlapCost ( TrackElement*, unsigned int flags ) const; void getTerminalWeight ( Interval, Net*, size_t& count, unsigned int& weight ) const; DbU::Unit getSourcePosition ( size_t index ) const; - DbU::Unit getSourcePosition ( vector::iterator ) const; - DbU::Unit getMinimalPosition ( size_t index, unsigned int state ) const; - DbU::Unit getMaximalPosition ( size_t index, unsigned int state ) const; - virtual Point getPosition ( DbU::Unit coordinate ) const = 0; - size_t find ( const TrackElement* ) const; - Interval getFreeInterval ( DbU::Unit position, Net* net=NULL ) const; - Interval expandUsedInterval ( size_t& begin, size_t& end ) const; - Interval expandFreeInterval ( size_t& begin, size_t& end, unsigned int state, Net* ) const; + bool check ( unsigned int& overlaps, const char* message=NULL ) const; unsigned int checkOverlap ( unsigned int& overlaps ) const; inline void setLocalAssigned ( bool ); - void forceSort (); + void invalidate (); void insert ( TrackElement* ); void insert ( TrackMarker* ); void setSegment ( TrackElement*, size_t ); - size_t pack (); - void sort (); - bool _check ( unsigned int& overlaps, const char* message=NULL ) const; + size_t doRemoval (); + void doReorder (); virtual Record* _getRecord () const; virtual string _getString () const; virtual string _getTypeName () const = 0; @@ -193,11 +176,11 @@ namespace Kite { inline bool Track::SegmentCompare::operator() ( const TrackElement* lhs, const TrackElement* rhs ) { - if ( lhs->getSourceU() < rhs->getSourceU() ) + if (lhs->getSourceU() < rhs->getSourceU()) return true; else { - if ( ( lhs->getSourceU() == rhs->getSourceU() ) - && ( lhs->getTargetU() > rhs->getTargetU() ) ) + if ( (lhs->getSourceU() == rhs->getSourceU()) + and (lhs->getTargetU() > rhs->getTargetU()) ) return true; } return false; @@ -215,23 +198,22 @@ namespace Kite { inline unsigned int Track::setMinimalFlags ( unsigned int& state, unsigned int flags ) const { - state &= ~MinMask; - state |= (flags & MinMask); + state &= ~BeginMask; + state |= (flags & BeginMask); return state; } inline unsigned int Track::setMaximalFlags ( unsigned int& state, unsigned int flags ) const { - state &= ~MaxMask; - state |= (flags & MaxMask); + state &= ~EndMask; + state |= (flags & EndMask); return state; } -} // End of Kite namespace. +} // Kite namespace. INSPECTOR_P_SUPPORT(Kite::Track); - -#endif // __KITE_TRACK__ +#endif // KITE_TRACK_H diff --git a/kite/src/kite/TrackCost.h b/kite/src/kite/TrackCost.h index 5a6838be..7a116b4c 100644 --- a/kite/src/kite/TrackCost.h +++ b/kite/src/kite/TrackCost.h @@ -2,34 +2,24 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2011, All Rights Reserved -// -// =================================================================== -// -// $Id$ +// Copyright (c) UPMC 2008-2013, 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 : "./TrackCost.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | +// | C++ Header : "./kite/TrackCost.h" | // +-----------------------------------------------------------------+ +#ifndef KITE_TRACK_COST_H +#define KITE_TRACK_COST_H - -#ifndef __KITE_TRACK_COST__ -#define __KITE_TRACK_COST__ - -#include -#include "hurricane/Interval.h" +#include +#include "hurricane/Interval.h" namespace Hurricane { class Net; } @@ -37,7 +27,6 @@ namespace Hurricane { namespace Kite { - using std::string; using Hurricane::Record; using Hurricane::DbU; @@ -80,6 +69,7 @@ namespace Kite { , unsigned int flags ); ~TrackCost (); + inline bool isForGlobal () const; inline bool isBlockage () const; inline bool isFixed () const; inline bool isInfinite () const; @@ -102,6 +92,7 @@ namespace Kite { inline long getAxisWeight () const; inline int getRipupCount () const; inline unsigned int getDataState () const; + inline void setForGlobal (); inline void setBlockage (); inline void setFixed (); inline void setInfinite (); @@ -132,6 +123,7 @@ namespace Kite { size_t _begin; size_t _end; Interval _interval; + bool _forGlobal; bool _blockage; bool _fixed; bool _infinite; @@ -155,6 +147,7 @@ namespace Kite { // Inline Functions. + inline bool TrackCost::isForGlobal () const { return _forGlobal; } inline bool TrackCost::isBlockage () const { return _blockage; } inline bool TrackCost::isFixed () const { return _fixed; } inline bool TrackCost::isInfinite () const { return _infinite; } @@ -175,6 +168,7 @@ namespace Kite { inline long TrackCost::getAxisWeight () const { return _axisWeight; } inline int TrackCost::getRipupCount () const { return _ripupCount; } inline unsigned int TrackCost::getDataState () const { return _dataState; } + inline void TrackCost::setForGlobal () { _forGlobal = true; } inline void TrackCost::setBlockage () { _blockage = true; } inline void TrackCost::setFixed () { _fixed = true; } inline void TrackCost::setInfinite () { _infinite = true; } @@ -197,10 +191,10 @@ namespace Kite { inline TrackCost::Compare::Compare ( unsigned int flags ) : _flags(flags) { } -} // End of Kite namespace. +} // Kite namespace. INSPECTOR_V_SUPPORT(Kite::TrackCost); -#endif // __KITE_TRACK_COST__ +#endif // KITE_TRACK_COST_H diff --git a/kite/src/kite/TrackElement.h b/kite/src/kite/TrackElement.h index dd494ea6..900d6bca 100644 --- a/kite/src/kite/TrackElement.h +++ b/kite/src/kite/TrackElement.h @@ -1,9 +1,8 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | @@ -12,13 +11,12 @@ // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | -// | C++ Header : "./TrackElement.h" | +// | C++ Header : "./kite/TrackElement.h" | // +-----------------------------------------------------------------+ -#ifndef __KITE_TRACK_ELEMENT__ -#define __KITE_TRACK_ELEMENT__ - +#ifndef KITE_TRACK_ELEMENT_H +#define KITE_TRACK_ELEMENT_H #include #include @@ -31,13 +29,13 @@ namespace Hurricane { } #include "katabatic/AutoSegment.h" +#include "kite/Constants.h" #include "kite/Session.h" #include "kite/TrackElements.h" namespace Kite { - using std::string; using std::map; using Hurricane::Record; @@ -47,6 +45,8 @@ namespace Kite { using Hurricane::Net; using Hurricane::Layer; using Katabatic::AutoSegment; + using Katabatic::Observer; + using Katabatic::KbNoFlags; class DataNegociate; class Track; @@ -57,147 +57,152 @@ namespace Kite { typedef void (SegmentOverlapCostCB)( const TrackElement*, TrackCost& ); +// ------------------------------------------------------------------- +// Class : "SegmentObserver". + + class SegmentObserver : public Observer { + public: + inline SegmentObserver ( TrackElement* ); + virtual void notify ( unsigned int flags ); + private: + SegmentObserver ( const SegmentObserver& ); + }; + + + inline SegmentObserver::SegmentObserver ( TrackElement* owner ) + : Observer(owner) + { } + + // ------------------------------------------------------------------- // Class : "TrackElement". - + + enum TrackElementFlags { TElemCreated =0x00000001 + , TElemBlockage =0x00000002 + , TElemFixed =0x00000004 + , TElemLocked =0x00000008 + , TElemRouted =0x00000010 + , TElemSourceDogleg=0x00000020 + , TElemTargetDogleg=0x00000040 + , TElemRipple =0x00000080 + , TElemInvalidated =0x00000100 + }; + + + struct Compare { + bool operator() ( TrackElement* lhs, TrackElement* rhs ); + }; + + struct CompareByPosition { + bool operator() ( const TrackElement* lhs, const TrackElement* rhs ) const; + }; + class TrackElement { public: - enum Flags { AddToGCells =0x01 - , RemoveFromGCells=0x02 - , UnRouted =0x04 - , Routed =0x08 - , AllowDoglegReuse=0x10 - , DataSelf =0x01 - , DataParent =0x02 - }; - - public: - // Sub-Class: "Compare()". - class Compare { - public: - bool operator() ( TrackElement* lhs, TrackElement* rhs ); - }; - public: - // Sub-Class: "CompareByPosition()". - struct CompareByPosition { - bool operator() ( const TrackElement* lhs, const TrackElement* rhs ) const; - }; - - friend class Compare; - - - public: - static SegmentOverlapCostCB* setOverlapCostCB ( SegmentOverlapCostCB* ); - public: - void destroy (); - virtual AutoSegment* base () const = 0; - virtual bool isCreated () const; - virtual bool isBlockage () const; - virtual bool isFixed () const; - virtual bool isStrap () const; - virtual bool isSlackenStrap () const; - virtual bool isLocal () const; - virtual bool isGlobal () const; - virtual bool isLocked () const; - virtual bool isTerminal () const; - virtual bool isDogleg () const; - virtual bool isRevalidated () const; - virtual bool isRouted () const; - virtual bool isSlackened () const; - virtual bool isSlackenDogLeg () const; - virtual bool isHorizontal () const = 0; - virtual bool isVertical () const = 0; - virtual bool isBipoint () const; - virtual bool allowOutsideGCell () const; - virtual bool canDesalignate () const; - virtual bool canGoOutsideGCell () const; - virtual bool canSlacken () const; - virtual bool canPivotUp ( float reserve ) const; - virtual bool canPivotDown ( float reserve ) const; - virtual bool canMoveUp ( float reserve, unsigned int flags=AutoSegment::Propagate|AutoSegment::PerpandicularFrag ) const; - virtual float getMaxUnderDensity ( unsigned int flags=AutoSegment::Propagate ) const; - virtual bool canRipple () const; - virtual bool hasSourceDogLeg () const; - virtual bool hasTargetDogLeg () const; - virtual bool canDogLeg (); - virtual bool canDogLeg ( Interval ); - virtual bool canDogLegAt ( Katabatic::GCell*, unsigned int flags=0 ); - virtual unsigned long getId () const; - virtual unsigned int getDirection () const = 0; - virtual Net* getNet () const = 0; - virtual const Layer* getLayer () const = 0; - inline Track* getTrack () const; - inline size_t getIndex () const; - virtual unsigned long getArea () const; - inline Box getBoundingBox () const; - virtual unsigned int getDogLegLevel () const; - virtual unsigned int getDogLegOrder () const; - virtual TrackElement* getNext () const; - virtual TrackElement* getPrevious () const; - virtual TrackElement* getParent () const; - virtual DbU::Unit getAxis () const = 0; - inline DbU::Unit getSourceU () const; - inline DbU::Unit getTargetU () const; - inline DbU::Unit getLength () const; - virtual Interval getFreeInterval () const; - inline Interval getCanonicalInterval () const; - virtual Interval getSourceConstraints () const; - virtual Interval getTargetConstraints () const; - virtual DataNegociate* getDataNegociate ( unsigned int flags=DataSelf ) const; - virtual TrackElement* getCanonical ( Interval& ); - virtual size_t getGCells ( Katabatic::GCellVector& ) const; - virtual TrackElement* getSourceDogLeg (); - virtual TrackElement* getTargetDogLeg (); - virtual TrackElements getCollapsedPerpandiculars (); - virtual size_t getPerpandicularsBound ( set& ); - virtual unsigned int getOrder () const; - virtual void incOverlapCost ( Net*, TrackCost& ) const; - virtual void dataInvalidate (); - virtual void eventInvalidate (); - inline void setSlackened ( bool ); - virtual void setAllowOutsideGCell ( bool ); - virtual void setRevalidated ( bool ); - virtual void setCanRipple ( bool ); - virtual void setSourceDogLeg ( bool state=true ); - virtual void setTargetDogLeg ( bool state=true ); - virtual void setLock ( bool ); - virtual void setRouted ( bool ); - virtual void setTrack ( Track* ); - inline void setIndex ( size_t ); - virtual void setArea (); - virtual void setDogLegLevel ( unsigned int ); - virtual void setDogLegOrder ( unsigned int ); - virtual void swapTrack ( TrackElement* ); - virtual void reschedule ( unsigned int level ); - virtual void detach (); - virtual void revalidate ( bool invalidEvent=false ); - virtual void invalidate (); - virtual void setAxis ( DbU::Unit, unsigned int flags=Katabatic::AxisSet ); - virtual void slacken (); - virtual bool moveUp ( unsigned int flags=AutoSegment::Propagate ); - virtual bool moveDown ( unsigned int flags=AutoSegment::Propagate ); - virtual bool moveAside ( bool onLeft ); - virtual TrackElement* makeDogLeg (); - virtual TrackElement* makeDogLeg ( Interval, bool& leftDogleg ); - virtual TrackElement* makeDogLeg ( Katabatic::GCell* ); - virtual TrackElement* _postDogLeg ( Katabatic::GCell* ); - virtual void _postModify (); - virtual void desalignate (); - virtual bool _check () const; - virtual Record* _getRecord () const; - virtual string _getString () const; - virtual string _getTypeName () const; + static SegmentOverlapCostCB* setOverlapCostCB ( SegmentOverlapCostCB* ); + public: + void destroy (); + virtual AutoSegment* base () const; + // Wrapped AutoSegment Functions (when applicable). + virtual bool isFixed () const; + virtual bool isHorizontal () const = 0; + virtual bool isVertical () const = 0; + virtual bool isLocal () const; + virtual bool isGlobal () const; + virtual bool isBipoint () const; + virtual bool isTerminal () const; + virtual bool isStrongTerminal ( unsigned int flags=0 ) const; + virtual bool isStrap () const; + virtual bool isSlackened () const; + virtual bool isDogleg () const; + // Predicates. + inline bool isCreated () const; + inline bool isInvalidated () const; + inline bool isBlockage () const; + inline bool isLocked () const; + inline bool isRouted () const; + inline bool hasSourceDogleg () const; + inline bool hasTargetDogleg () const; + inline bool canRipple () const; + virtual bool canSlacken () const; + virtual bool canPivotUp ( float reserve ) const; + virtual bool canPivotDown ( float reserve ) const; + virtual bool canMoveUp ( float reserve, unsigned int flags=KbWithPerpands ) const; + virtual bool canDogleg (); + virtual bool canDogleg ( Interval ); + virtual bool canDogleg ( Katabatic::GCell*, unsigned int flags=0 ); + // Accessors + inline SegmentObserver* getObserver (); + virtual unsigned long getId () const; + virtual unsigned int getDirection () const = 0; + virtual Net* getNet () const = 0; + virtual const Layer* getLayer () const = 0; + inline Track* getTrack () const; + inline size_t getIndex () const; + virtual unsigned long getFreedomDegree () const; + virtual float getMaxUnderDensity ( unsigned int flags=0 ) const; + inline Box getBoundingBox () const; + virtual TrackElement* getNext () const; + virtual TrackElement* getPrevious () const; + virtual DbU::Unit getAxis () const = 0; + inline DbU::Unit getSourceU () const; + inline DbU::Unit getTargetU () const; + inline DbU::Unit getLength () const; + inline Interval getCanonicalInterval () const; + virtual Interval getFreeInterval () const; + virtual Interval getSourceConstraints () const; + virtual Interval getTargetConstraints () const; + virtual DataNegociate* getDataNegociate ( unsigned int flags=KtDataSelf ) const; + virtual TrackElement* getCanonical ( Interval& ); + virtual size_t getGCells ( Katabatic::GCellVector& ) const; + virtual TrackElement* getParent () const; + virtual unsigned int getDoglegLevel () const; + virtual TrackElement* getSourceDogleg (); + virtual TrackElement* getTargetDogleg (); + virtual TrackElements getPerpandiculars (); + // Mutators. + inline void setFlags ( unsigned int ); + inline void unsetFlags ( unsigned int ); + virtual void setTrack ( Track* ); + inline void setIndex ( size_t ); + virtual void updateFreedomDegree (); + virtual void setDoglegLevel ( unsigned int ); + virtual void swapTrack ( TrackElement* ); + virtual void reschedule ( unsigned int level ); + virtual void detach (); + virtual void revalidate (); + virtual void invalidate (); + virtual void incOverlapCost ( Net*, TrackCost& ) const; + virtual void setAxis ( DbU::Unit, unsigned int flags=Katabatic::SegAxisSet ); + virtual TrackElement* makeDogleg (); + inline bool makeDogleg ( Katabatic::GCell* ); + virtual TrackElement* makeDogleg ( Katabatic::GCell*, TrackElement*& perpandicular, TrackElement*& parallel ); + virtual TrackElement* makeDogleg ( Interval, unsigned int& flags ); + virtual void _postDoglegs ( TrackElement*& perpandicular, TrackElement*& parallel ); + virtual bool moveAside ( unsigned int flags ); + virtual bool slacken ( unsigned int flags=KbNoFlags ); + virtual bool moveUp ( unsigned int flags ); + virtual bool moveDown ( unsigned int flags ); +#if THIS_IS_DISABLED + virtual void desalignate (); +#endif + virtual bool _check () const; + virtual Record* _getRecord () const; + virtual string _getString () const; + virtual string _getTypeName () const; protected: // Static Attributes. - static SegmentOverlapCostCB* _overlapCostCallback; - // Attributes. - Track* _track; - size_t _index; - DbU::Unit _sourceU; - DbU::Unit _targetU; + static SegmentOverlapCostCB* _overlapCostCallback; + // Attributes. + unsigned int _flags; + Track* _track; + size_t _index; + DbU::Unit _sourceU; + DbU::Unit _targetU; + SegmentObserver _observer; protected: // Constructors & Destructors. @@ -213,28 +218,46 @@ namespace Kite { // Inline functions. - inline Track* TrackElement::getTrack () const { return _track; } - inline size_t TrackElement::getIndex () const { return _index; } - inline DbU::Unit TrackElement::getLength () const { return getTargetU() - getSourceU(); } - inline DbU::Unit TrackElement::getSourceU () const { return _sourceU; } - inline DbU::Unit TrackElement::getTargetU () const { return _targetU; } - inline Interval TrackElement::getCanonicalInterval () const { return Interval(getSourceU(),getTargetU()); } - inline void TrackElement::setIndex ( size_t index ) { _index = index; } - inline void TrackElement::setSlackened ( bool state ) { if (base()) base()->setSlackened(state); }; + inline SegmentObserver* TrackElement::getObserver () { return &_observer; } + inline void TrackElement::setFlags ( unsigned int flags ) { _flags|= flags; } + inline void TrackElement::unsetFlags ( unsigned int flags ) { _flags&=~flags; } + inline bool TrackElement::isCreated () const { return _flags & TElemCreated; } + inline bool TrackElement::isInvalidated () const { return _flags & TElemInvalidated; } + 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::hasSourceDogleg () const { return _flags & TElemSourceDogleg; } + inline bool TrackElement::hasTargetDogleg () const { return _flags & TElemTargetDogleg; } + inline bool TrackElement::canRipple () const { return _flags & TElemRipple; } + inline Track* TrackElement::getTrack () const { return _track; } + inline size_t TrackElement::getIndex () const { return _index; } + inline DbU::Unit TrackElement::getLength () const { return getTargetU() - getSourceU(); } + inline DbU::Unit TrackElement::getSourceU () const { return _sourceU; } + inline DbU::Unit TrackElement::getTargetU () const { return _targetU; } + inline Interval TrackElement::getCanonicalInterval () const { return Interval(getSourceU(),getTargetU()); } + inline void TrackElement::setIndex ( size_t index ) { _index=index; } inline Box TrackElement::getBoundingBox () const { - if ( getDirection() == Constant::Horizontal ) - return Box ( getSourceU(), getAxis()-DbU::lambda(1.0), getTargetU(), getAxis()+DbU::lambda(1.0) ); + if (getDirection() == KbHorizontal) + return Box( getSourceU(), getAxis()-DbU::lambda(1.0), getTargetU(), getAxis()+DbU::lambda(1.0) ); + return Box( getAxis()-DbU::lambda(1.0), getSourceU(), getAxis()+DbU::lambda(1.0), getTargetU() ); + } - return Box ( getAxis()-DbU::lambda(1.0), getSourceU(), getAxis()+DbU::lambda(1.0), getTargetU() ); + inline bool TrackElement::makeDogleg ( Katabatic::GCell* gcell ) + { + TrackElement* perpandicular = NULL; + TrackElement* parallel = NULL; + + makeDogleg( gcell, perpandicular, parallel ); + + return (perpandicular != NULL); } -} // End of Kite namespace. +} // Kite namespace. INSPECTOR_P_SUPPORT(Kite::TrackElement); - -# endif +#endif diff --git a/kite/src/kite/TrackElements.h b/kite/src/kite/TrackElements.h index 8922af6d..e39e2b2a 100644 --- a/kite/src/kite/TrackElements.h +++ b/kite/src/kite/TrackElements.h @@ -2,36 +2,27 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 : "./TrackElements.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./kite/TrackElements.h" | +// +-----------------------------------------------------------------+ -#ifndef __KITE_TRACKELEMENTS_H__ -#define __KITE_TRACKELEMENTS_H__ +#ifndef KITE_TRACKELEMENTS_H +#define KITE_TRACKELEMENTS_H #include "katabatic/AutoSegments.h" namespace Kite { - using std::string; using std::set; @@ -50,7 +41,7 @@ namespace Kite { using Hurricane::GenericLocator; using Hurricane::GenericCollection; - using Katabatic::AutoSegments_CollapsedPerpandicular; + using Katabatic::AutoSegments_Perpandiculars; class TrackElement; @@ -58,7 +49,6 @@ namespace Kite { // ------------------------------------------------------------------- // Collections. - typedef Hurricane::Filter TrackElementHF; typedef Hurricane::Locator TrackElementHL; typedef Hurricane::Collection TrackElementHC; @@ -68,10 +58,9 @@ namespace Kite { // ------------------------------------------------------------------- -// Class : "TrackElements_CollapsedPerpandicular". +// Class : "TrackElements_Perpandiculars". - - class TrackElements_CollapsedPerpandicular : public TrackElementHC { + class TrackElements_Perpandiculars : public TrackElementHC { public: // Sub-Class: Locator. @@ -85,40 +74,38 @@ namespace Kite { virtual void progress (); virtual string _getString () const; protected: - AutoSegments_CollapsedPerpandicular::Locator _locator; - TrackElement* _element; + AutoSegments_Perpandiculars::Locator _locator; + TrackElement* _element; }; public: - // TrackElements_CollapsedPerpandicular Methods. - inline TrackElements_CollapsedPerpandicular ( TrackElement* segment ); - inline TrackElements_CollapsedPerpandicular ( const TrackElements_CollapsedPerpandicular& ); - virtual TrackElementHC* getClone () const; - virtual TrackElementHL* getLocator () const; - virtual string _getString () const; + // TrackElements_Perpandiculars Methods. + inline TrackElements_Perpandiculars ( TrackElement* segment ); + inline TrackElements_Perpandiculars ( const TrackElements_Perpandiculars& ); + virtual TrackElementHC* getClone () const; + virtual TrackElementHL* getLocator () const; + virtual string _getString () const; protected: - // TrackElements_CollapsedPerpandicular Attributes. + // TrackElements_Perpandiculars Attributes. TrackElement* _segment; }; - inline TrackElements_CollapsedPerpandicular::Locator::Locator ( const Locator& locator ) + inline TrackElements_Perpandiculars::Locator::Locator ( const Locator& locator ) : TrackElementHL() , _locator (locator._locator) , _element (NULL) { } - inline TrackElements_CollapsedPerpandicular::TrackElements_CollapsedPerpandicular - ( TrackElement* segment ) + inline TrackElements_Perpandiculars::TrackElements_Perpandiculars ( TrackElement* segment ) : TrackElementHC() , _segment (segment) { } - inline TrackElements_CollapsedPerpandicular::TrackElements_CollapsedPerpandicular - ( const TrackElements_CollapsedPerpandicular& tracksegments ) + inline TrackElements_Perpandiculars::TrackElements_Perpandiculars ( const TrackElements_Perpandiculars& tracksegments ) : TrackElementHC() , _segment (tracksegments._segment) { } @@ -127,7 +114,6 @@ namespace Kite { // ------------------------------------------------------------------- // Class : "TrackElements_UniqCanonical". - class TrackElements_UniqCanonical : public TrackElementHF { public: inline TrackElements_UniqCanonical ( set& ); @@ -152,7 +138,7 @@ namespace Kite { {} -} // End of Kite namespace. +} // Kite namespace. -#endif // __KITE_TRACKELEMENTS__ +#endif // KITE_TRACKELEMENTS_H diff --git a/kite/src/kite/TrackFixedSegment.h b/kite/src/kite/TrackFixedSegment.h index 92d75547..f5fab66b 100644 --- a/kite/src/kite/TrackFixedSegment.h +++ b/kite/src/kite/TrackFixedSegment.h @@ -3,39 +3,27 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 : "./TrackFixedSegment.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./kite/TrackFixedSegment.h" | +// +-----------------------------------------------------------------+ +#ifndef KITE_TRACK_FIXED_SEGMENT_H +#define KITE_TRACK_FIXED_SEGMENT_H - -#ifndef __KITE_TRACK_FIXED_SEGMENT__ -#define __KITE_TRACK_FIXED_SEGMENT__ - - -#include "kite/TrackElement.h" +#include "kite/TrackElement.h" namespace Kite { - using std::string; using std::map; using Hurricane::Record; @@ -49,17 +37,15 @@ namespace Kite { // ------------------------------------------------------------------- // Class : "TrackFixedSegment". - class TrackFixedSegment : public TrackElement { public: - static TrackElement* create ( Track*, Segment* ); + static TrackElement* create ( Kite::Track* track , Segment* segment ); public: virtual AutoSegment* base () const; - virtual bool isFixed () const; - virtual bool isBlockage () const; virtual bool isHorizontal () const; virtual bool isVertical () const; + virtual bool isFixed () const; virtual unsigned long getId () const; virtual unsigned int getDirection () const; virtual Net* getNet () const; @@ -67,7 +53,7 @@ namespace Kite { virtual TrackElement* getNext () const; virtual TrackElement* getPrevious () const; virtual DbU::Unit getAxis () const; - virtual Interval getFreeInterval ( bool useOrder=false ) const; + virtual Interval getFreeInterval () const; virtual Record* _getRecord () const; virtual string _getString () const; virtual string _getTypeName () const; @@ -76,7 +62,6 @@ namespace Kite { // Attributes. static Net* _blockageNet; Segment* _segment; - bool _isBlockage; protected: // Constructors & Destructors. @@ -91,10 +76,9 @@ namespace Kite { }; -} // End of Kite namespace. +} // Kite namespace. INSPECTOR_P_SUPPORT(Kite::TrackFixedSegment); - -# endif +#endif // KITE_TRACK_FIXED_SEGMENT_H diff --git a/kite/src/kite/TrackMarker.h b/kite/src/kite/TrackMarker.h index 3dae45da..d13c7f60 100644 --- a/kite/src/kite/TrackMarker.h +++ b/kite/src/kite/TrackMarker.h @@ -2,33 +2,25 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 : "./TrackMarker.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./kite/TrackMarker.h" | +// +-----------------------------------------------------------------+ -#ifndef __KITE_TRACK_MARKER__ -#define __KITE_TRACK_MARKER__ +#ifndef KITE_TRACK_MARKER_H +#define KITE_TRACK_MARKER_H -#include "hurricane/DbU.h" +#include "hurricane/DbU.h" namespace Hurricane { class RoutingPad; class Net; @@ -47,7 +39,6 @@ namespace Kite { // ------------------------------------------------------------------- // Class : "TrackMarker". - class TrackMarker { @@ -113,10 +104,10 @@ namespace Kite { { return ( lhsU < rhsU ); } -} // End of Kite namespace. +} // Kite namespace. INSPECTOR_P_SUPPORT(Kite::TrackMarker); -#endif // __KITE_TRACK_MARKER__ +#endif // KITE_TRACK_MARKER_H diff --git a/kite/src/kite/TrackSegment.h b/kite/src/kite/TrackSegment.h index ae042b33..195e4e10 100644 --- a/kite/src/kite/TrackSegment.h +++ b/kite/src/kite/TrackSegment.h @@ -1,43 +1,34 @@ - // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2010, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 : "./TrackSegment.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./kite/TrackSegment.h" | +// +-----------------------------------------------------------------+ +#ifndef KITE_TRACK_SEGMENT_H +#define KITE_TRACK_SEGMENT_H - -#ifndef __KITE_TRACK_SEGMENT__ -#define __KITE_TRACK_SEGMENT__ - - -#include "kite/TrackElement.h" +#include +#include +#include "kite/TrackElement.h" namespace Kite { - using std::string; using std::map; + using std::set; + using std::binary_function; using Hurricane::Record; using Hurricane::Interval; using Hurricane::DbU; @@ -52,109 +43,91 @@ namespace Kite { // ------------------------------------------------------------------- // Class : "TrackSegment". - class TrackSegment : public TrackElement { public: - static TrackElement* create ( AutoSegment*, Track*, bool& created ); - public: - virtual AutoSegment* base () const; - virtual bool isBipoint () const; - virtual bool isCreated () const; - virtual bool isFixed () const; - virtual bool isStrap () const; - virtual bool isSlackenStrap () const; - virtual bool isLocal () const; - virtual bool isGlobal () const; - virtual bool isLocked () const; - virtual bool isTerminal () const; - virtual bool isDogleg () const; - virtual bool isRevalidated () const; - virtual bool isSlackened () const; - virtual bool isSlackenDogLeg () const; - virtual bool isHorizontal () const; - virtual bool isVertical () const; - virtual bool isRouted () const; - virtual bool allowOutsideGCell () const; - virtual bool canDesalignate () const; - virtual bool canGoOutsideGCell () const; - virtual bool canSlacken () const; - virtual bool canPivotUp ( float reserve ) const; - virtual bool canPivotDown ( float reserve ) const; - virtual bool canMoveUp ( float reserve, unsigned int flags ) const; - virtual float getMaxUnderDensity ( unsigned int flags ) const; - virtual bool canRipple () const; - virtual bool hasSourceDogLeg () const; - virtual bool hasTargetDogLeg () const; - virtual bool canDogLeg (); - virtual bool canDogLeg ( Interval ); - virtual bool canDogLegAt ( Katabatic::GCell*, unsigned int flags ); - virtual unsigned long getId () const; - virtual unsigned int getDirection () const; - virtual Net* getNet () const; - virtual const Layer* getLayer () const; - virtual unsigned long getArea () const; - virtual unsigned int getDogLegLevel () const; - virtual TrackElement* getNext () const; - virtual TrackElement* getPrevious () const; - virtual TrackElement* getParent () const; - virtual DbU::Unit getAxis () const; - virtual Interval getFreeInterval () const; - virtual Interval getSourceConstraints () const; - virtual Interval getTargetConstraints () const; - virtual DataNegociate* getDataNegociate ( unsigned int flags ) const; - virtual TrackElement* getCanonical ( Interval& ); - virtual size_t getGCells ( vector& ) const; - virtual TrackElement* getSourceDogLeg (); - virtual TrackElement* getTargetDogLeg (); - virtual TrackElements getCollapsedPerpandiculars (); - virtual size_t getPerpandicularsBound ( set& ); - virtual void dataInvalidate (); - virtual void eventInvalidate (); - virtual void setAllowOutsideGCell ( bool ); - virtual void setRevalidated ( bool ); - virtual void setCanRipple ( bool ); - virtual void setSourceDogLeg ( bool ); - virtual void setTargetDogLeg ( bool ); - virtual void setLock ( bool ); - virtual void setRouted ( bool ); - virtual void setTrack ( Track* ); - virtual void setArea (); - virtual void setDogLegLevel ( unsigned int ); - virtual void swapTrack ( TrackElement* ); - virtual void reschedule ( unsigned int level ); - virtual void detach (); - virtual void revalidate ( bool invalidEvent ); - virtual void invalidate (); - virtual void setAxis ( DbU::Unit, unsigned int flags ); - virtual void slacken (); - virtual bool moveUp ( unsigned int flags ); - virtual bool moveDown ( unsigned int flags ); - virtual bool moveAside ( bool onLeft ); - virtual TrackElement* makeDogLeg (); - virtual TrackElement* makeDogLeg ( Interval, bool& leftDogleg ); - virtual TrackElement* makeDogLeg ( Katabatic::GCell* ); - virtual TrackElement* _postDogLeg (); - virtual void _postModify (); - virtual void desalignate (); - virtual bool _check () const; - virtual Record* _getRecord () const; - virtual string _getString () const; - virtual string _getTypeName () const; + class CompareById : public binary_function { + public: + inline bool operator() ( const TrackSegment* lhs, const TrackSegment* rhs ); + }; + + public: + static TrackElement* create ( AutoSegment*, Track*, bool& created ); + public: + // Wrapped AutoSegment Functions (when applicable). + virtual AutoSegment* base () const; + virtual bool isFixed () const; + virtual bool isHorizontal () const; + virtual bool isVertical () const; + virtual bool isLocal () const; + virtual bool isGlobal () const; + virtual bool isBipoint () const; + virtual bool isTerminal () const; + virtual bool isStrongTerminal ( unsigned int flags=0 ) const; + virtual bool isStrap () const; + virtual bool isSlackened () const; + virtual bool isDogleg () const; + // Predicates. + virtual bool canDogleg (); + virtual bool canDogleg ( Interval ); + virtual bool canDogleg ( Katabatic::GCell*, unsigned int flags=0 ); + virtual bool canPivotUp ( float reserve ) const; + virtual bool canPivotDown ( float reserve ) const; + virtual bool canMoveUp ( float reserve, unsigned int flags ) const; + virtual bool canSlacken () const; + virtual float getMaxUnderDensity ( unsigned int flags ) const; + virtual unsigned long getId () const; + virtual unsigned int getDirection () const; + virtual Net* getNet () const; + virtual const Layer* getLayer () const; + virtual unsigned long getFreedomDegree () const; + virtual unsigned int getDoglegLevel () const; + virtual TrackElement* getNext () const; + virtual TrackElement* getPrevious () const; + virtual TrackElement* getParent () const; + virtual DbU::Unit getAxis () const; + virtual Interval getFreeInterval () const; + virtual Interval getSourceConstraints () const; + virtual Interval getTargetConstraints () const; + virtual DataNegociate* getDataNegociate ( unsigned int flags=KtDataSelf ) const; + virtual TrackElement* getCanonical ( Interval& ); + virtual size_t getGCells ( Katabatic::GCellVector& ) const; + virtual TrackElement* getSourceDogleg (); + virtual TrackElement* getTargetDogleg (); + virtual TrackElements getPerpandiculars (); + virtual size_t getPerpandicularsBound ( set& ); + // Mutators. + virtual void setTrack ( Track* ); + virtual void updateFreedomDegree (); + virtual void setDoglegLevel ( unsigned int ); + virtual void swapTrack ( TrackElement* ); + virtual void reschedule ( unsigned int level ); + virtual void detach (); + virtual void revalidate (); + virtual void invalidate (); + virtual void setAxis ( DbU::Unit, unsigned int flags ); + virtual TrackElement* makeDogleg (); + virtual TrackElement* makeDogleg ( Katabatic::GCell*, TrackElement*& perpandicular, TrackElement*& parallel ); + virtual TrackElement* makeDogleg ( Interval, unsigned int& flags ); + virtual void _postDoglegs ( TrackElement*& perpandicular, TrackElement*& parallel ); + virtual bool moveAside ( unsigned int flags ); + virtual bool slacken ( unsigned int flags=KbNoFlags ); + virtual bool moveUp ( unsigned int flags ); + virtual bool moveDown ( unsigned int flags ); +#if THIS_IS_DISABLED + virtual void desalignate (); +#endif + virtual bool _check () const; + virtual Record* _getRecord () const; + virtual string _getString () const; + virtual string _getTypeName () const; protected: // Attributes. - AutoSegment* _base; - bool _created; - bool _lock; - bool _revalidated; - bool _sourceDogLeg; - bool _targetDogLeg; - bool _canRipple; - bool _routed; - unsigned long _area; - DataNegociate* _data; - unsigned int _dogLegLevel:4; + AutoSegment* _base; + unsigned long _freedomDegree; + DataNegociate* _data; + unsigned int _dogLegLevel:4; protected: // Constructors & Destructors. @@ -169,10 +142,16 @@ namespace Kite { }; -} // End of Kite namespace. + inline bool TrackSegment::CompareById::operator() ( const TrackSegment* lhs, const TrackSegment* rhs ) + { return lhs->getId() < rhs->getId(); } + + + typedef set TrackSegmentSet; + + +} // Kite namespace. INSPECTOR_P_SUPPORT(Kite::TrackSegment); - -# endif +#endif // KITE_TRACK_SEGMENT_H diff --git a/kite/src/kite/TrackSegmentCost.h b/kite/src/kite/TrackSegmentCost.h index 5e554b1d..af280cb1 100644 --- a/kite/src/kite/TrackSegmentCost.h +++ b/kite/src/kite/TrackSegmentCost.h @@ -2,14 +2,9 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC/LIP6 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 | // | | @@ -17,12 +12,7 @@ // | E-mail : Jean-Paul.Chaput@asim.lip6.fr | // | =============================================================== | // | C++ Header : "./TrackSegmentCost.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x - - +// +-----------------------------------------------------------------+ #ifndef __TRACK_SEGMENT_COST__ diff --git a/kite/src/kite/Tracks.h b/kite/src/kite/Tracks.h index 363fd4d5..250401d0 100644 --- a/kite/src/kite/Tracks.h +++ b/kite/src/kite/Tracks.h @@ -2,40 +2,29 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 : "./Tracks.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./kite/Tracks.h" | +// +-----------------------------------------------------------------+ +#ifndef KITE_TRACKS_H +#define KITE_TRACKS_H - -#ifndef __KITE_TRACKS__ -#define __KITE_TRACKS__ - -#include -#include "hurricane/Collection.h" -#include "hurricane/Interval.h" +#include +#include "hurricane/Collection.h" +#include "hurricane/Interval.h" namespace Kite { - using std::string; using Hurricane::_TName; using Hurricane::Locator; @@ -56,7 +45,6 @@ namespace Kite { // ------------------------------------------------------------------- // Class : "Tracks_Range". - class Tracks_Range: public Collection { public: @@ -98,7 +86,6 @@ namespace Kite { // ------------------------------------------------------------------- // Class : "Tracks_Spiral". - class Tracks_Spiral : public Collection { public: @@ -147,7 +134,7 @@ namespace Kite { }; -} // End of Katabatic namespace. +} // Katabatic namespace. -#endif // __KITE_TRACKS__ +#endif // KITE_TRACKS_H diff --git a/kite/src/kite/VerticalTrack.h b/kite/src/kite/VerticalTrack.h index 33e178c6..ff45913b 100644 --- a/kite/src/kite/VerticalTrack.h +++ b/kite/src/kite/VerticalTrack.h @@ -2,29 +2,21 @@ // -*- C++ -*- // // This file is part of the Coriolis Software. -// Copyright (c) UPMC/LIP6 2008-2009, All Rights Reserved +// Copyright (c) UPMC 2008-2013, All Rights Reserved // -// =================================================================== -// -// $Id$ -// -// x-----------------------------------------------------------------x -// | | +// +-----------------------------------------------------------------+ // | 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 : "./VerticalTrack.h" | -// | *************************************************************** | -// | U p d a t e s | -// | | -// x-----------------------------------------------------------------x +// | C++ Header : "./kite/VerticalTrack.h" | +// +-----------------------------------------------------------------+ -#ifndef __KITE_VERTICAL_TRACK__ -#define __KITE_VERTICAL_TRACK__ +#ifndef KITE_VERTICAL_TRACK_H +#define KITE_VERTICAL_TRACK_H #include "kite/Track.h" @@ -34,7 +26,6 @@ namespace Kite { // ------------------------------------------------------------------- // Class : "VerticalTrack". - class VerticalTrack : public Track { @@ -59,7 +50,7 @@ namespace Kite { }; -} // End of Kite namespace. +} // Kite namespace. -#endif // __KITE_VERTICAL_TRACK__ +#endif // KITE_VERTICAL_TRACK_H

    SummaryConceptsSummary NamespacesClass HierarchyClass Hierarchy Classes Member Index