* ./hurricane/src/hviewer,
./coriolis/src/crlcore, ./coriolis/src/knik, ./coriolis/src/katabatic, ./coriolis/src/kite, ./coriolis/src/equinox, ./coriolis/src/solstice, ./coriolis/src/ispd: - SVN MOVE: Source tree simplification & uniformisation. Now all tools are at the same level, directly under the root of the repository. No more "coriolis/src".
|
@ -0,0 +1,50 @@
|
|||
PROJECT(KITE)
|
||||
|
||||
OPTION(BUILD_DOC "Build the documentation (doxygen)" OFF)
|
||||
OPTION(CHECK_DATABASE "Run database in full check mode (very slow)" OFF)
|
||||
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.4.0)
|
||||
|
||||
SET(CMAKE_C_FLAGS_DEBUG "-g -Wall" CACHE STRING "Debug options." FORCE)
|
||||
SET(CMAKE_CXX_FLAGS_DEBUG "-g -Wall" CACHE STRING "Debug options." FORCE)
|
||||
#SET(CMAKE_LINKER_FLAGS_DEBUG "-pg" CACHE STRING "Debug options." FORCE)
|
||||
#SET(CMAKE_SHARED_LINKER_FLAGS_DEBUG "-pg" CACHE STRING "Debug options." FORCE)
|
||||
#SET(CMAKE_MODULE_LINKER_FLAGS_DEBUG "-pg" CACHE STRING "Debug options." FORCE)
|
||||
#SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "-pg" CACHE STRING "Debug options." FORCE)
|
||||
SET(CMAKE_C_FLAGS_RELEASE "-O3 -DNDEBUG -Wall" CACHE STRING "Release options." FORCE)
|
||||
SET(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -Wall" CACHE STRING "Release options." FORCE)
|
||||
|
||||
IF(COMMAND CMAKE_POLICY)
|
||||
CMAKE_POLICY(SET CMP0003 NEW)
|
||||
ENDIF(COMMAND CMAKE_POLICY)
|
||||
|
||||
SET(CMAKE_MODULE_PATH "$ENV{HURRICANE_TOP}/share/cmake_modules/")
|
||||
|
||||
SET(QT_USE_QTXML "true")
|
||||
|
||||
IF(BUILD_DOC)
|
||||
FIND_PACKAGE(Doxygen)
|
||||
ENDIF(BUILD_DOC)
|
||||
FIND_PACKAGE(Boost 1.33.1 COMPONENTS program_options REQUIRED)
|
||||
FIND_PACKAGE(Qt4 REQUIRED) # find and setup Qt4 for this project
|
||||
FIND_PACKAGE(Boost 1.33.1 REQUIRED)
|
||||
FIND_PACKAGE(LEFDEF REQUIRED)
|
||||
FIND_PACKAGE(HURRICANE REQUIRED)
|
||||
FIND_PACKAGE(CORIOLIS REQUIRED)
|
||||
FIND_PACKAGE(KNIK REQUIRED)
|
||||
FIND_PACKAGE(KATABATIC REQUIRED)
|
||||
|
||||
SET_LIB_LINK_MODE()
|
||||
|
||||
IF(CHECK_DATABASE)
|
||||
ADD_DEFINITIONS(-DCHECK_DATABASE)
|
||||
ENDIF(CHECK_DATABASE)
|
||||
IF(CHECK_DETERMINISM)
|
||||
ADD_DEFINITIONS(-DCHECK_DETERMINISM)
|
||||
ENDIF(CHECK_DETERMINISM)
|
||||
|
||||
ADD_SUBDIRECTORY(src)
|
||||
ADD_SUBDIRECTORY(cmake_modules)
|
||||
IF(BUILD_DOC AND DOXYGEN_FOUND)
|
||||
ADD_SUBDIRECTORY(doc)
|
||||
ENDIF(BUILD_DOC AND DOXYGEN_FOUND)
|
|
@ -0,0 +1 @@
|
|||
install ( FILES FindKITE.cmake DESTINATION /share/cmake_modules )
|
|
@ -0,0 +1,47 @@
|
|||
# - Find the Kite includes and libraries.
|
||||
# The following variables are set if Coriolis is found. If KITE is not
|
||||
# found, KITE_FOUND is set to false.
|
||||
# KITE_FOUND - True when the Coriolis include directory is found.
|
||||
# KITE_INCLUDE_DIR - the path to where the Coriolis include files are.
|
||||
# KITE_LIBRARIES - The path to where the Coriolis library files are.
|
||||
|
||||
|
||||
SET(KITE_INCLUDE_PATH_DESCRIPTION "directory containing the Kite include files. E.g /usr/local/include/coriolis or /asim/coriolis/include/coriolis")
|
||||
|
||||
SET(KITE_DIR_MESSAGE "Set the KITE_INCLUDE_DIR cmake cache entry to the ${KITE_INCLUDE_PATH_DESCRIPTION}")
|
||||
|
||||
# don't even bother under WIN32
|
||||
IF(UNIX)
|
||||
|
||||
SET(KITE_DIR_SEARCH $ENV{CORIOLIS_TOP} $ENV{HURRICANE_TOP})
|
||||
#
|
||||
# Look for an installation.
|
||||
#
|
||||
FIND_PATH(KITE_INCLUDE_PATH NAMES kite/KiteEngine.h PATHS
|
||||
# Look in other places.
|
||||
${KITE_DIR_SEARCH}
|
||||
PATH_SUFFIXES include/coriolis
|
||||
# Help the user find it if we cannot.
|
||||
DOC "The ${KITE_INCLUDE_PATH_DESCRIPTION}"
|
||||
)
|
||||
|
||||
FIND_LIBRARY(KITE_LIBRARY_PATH
|
||||
NAMES kite
|
||||
PATHS ${KITE_DIR_SEARCH}
|
||||
PATH_SUFFIXES lib
|
||||
# Help the user find it if we cannot.
|
||||
DOC "The ${KITE_INCLUDE_PATH_DESCRIPTION}"
|
||||
)
|
||||
|
||||
FIND_LIBRARY(KITE_STATIC_LIBRARY_PATH
|
||||
NAMES kite-static
|
||||
PATHS ${KITE_DIR_SEARCH}
|
||||
PATH_SUFFIXES lib
|
||||
# Help the user find it if we cannot.
|
||||
DOC "The ${KITE_INCLUDE_PATH_DESCRIPTION}"
|
||||
)
|
||||
|
||||
SET_LIBRARIES_PATH(KITE KITE)
|
||||
HURRICANE_CHECK_LIBRARIES(KITE)
|
||||
|
||||
ENDIF(UNIX)
|
|
@ -0,0 +1,353 @@
|
|||
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,485 @@
|
|||
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
set ( htmlInstallDir /share/doc/en/html/kite )
|
||||
set ( latexInstallDir /share/doc/en/latex/kite )
|
||||
|
||||
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 ( DIRECTORY latex/ DESTINATION ${latexInstallDir} )
|
||||
install ( FILES asimbook.cls DESTINATION ${latexInstallDir} )
|
|
@ -0,0 +1,97 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
/*! \mainpage Detailed Router Documentation
|
||||
*
|
||||
* This documentation adresses two level of explanations :
|
||||
*
|
||||
* <ul>
|
||||
* <li>The \b API description which explains how to use Kite,
|
||||
* thoses parts as flagged as \b API.
|
||||
* <li>The internal description which details how Kite do
|
||||
* things. It's mostly intended for myself to help me not to
|
||||
* forget how I've done things when debug time will come...
|
||||
* It may also be valuable to people who may want to use
|
||||
* or patch Kite for their own purpose (my secret hope).
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* \defgroup AlgorithmOverview Algorithm Overview (internal)
|
||||
*
|
||||
* The algorithm top-level is implemented in the \c NegociateWindow.
|
||||
*
|
||||
* <b>First step :</b> NegociateWindow::_loadRouting()
|
||||
* <ol>
|
||||
* <li>Load routing wires (\c AutoSegment) from \c KatabaticEngine
|
||||
* inside the Kite \c GCell's. Then update the \c GCell's density.
|
||||
* <li>Sort the \c GCell's according to decreasing density (denser
|
||||
* \c GCell's are to be routed first).
|
||||
* <li>Agglomerate clusters of contiguous GCell's whose density
|
||||
* is superior to 0.7 to the seed GCell. See \c GCellRoutingSet
|
||||
* for the mechanism.
|
||||
*
|
||||
* GCellRoutingSet receive an increasing order number. The higher
|
||||
* the order the lower the density. This order is transmitted
|
||||
* to the \c TrackSegment of the \c GCellRoutingSet to be taken into
|
||||
* account by the track cost function.
|
||||
* </ol>
|
||||
*
|
||||
* <b>Second step :</b> \c NegociateWindow::_runOnGCellRoutingSet()
|
||||
*
|
||||
* For each \c GCellRoutingSet in decreasing density, negociate the
|
||||
* set of associated \c TrackSegment.
|
||||
* <ol>
|
||||
* <li>Build a \c RoutingEventQueue from the list of \c TrackSegment.
|
||||
* The queue is responsible for allocating the \c RoutingEvent
|
||||
* associated to each \c TrackSegment.
|
||||
* <li>The queue is sorted according to the "event level" then
|
||||
* to the priority, which is for now the slack of the \c TrackSegment.
|
||||
* That is, constrained \c TrackSegment are routed first.
|
||||
* <li>The queue is processed till it's empty (no unprocessed \c RoutingEvent
|
||||
* remains).
|
||||
*
|
||||
* Processing a \c RoutingEvent is trying to insert a \c TrackSegment in
|
||||
* a suitable Track. We proceed as follow :
|
||||
* <ul>
|
||||
* <li>The maximum ripup count for the to be inserted segment has
|
||||
* been reached. Issue a severe warning and left unrouted
|
||||
* this \c TrackSegment (for now).
|
||||
* <li>Compute the Tracks in which the \c TrackSegment can be inserted,
|
||||
* then compute the insertion cost in each one. The candidates
|
||||
* are ordered by the insertion cost.
|
||||
* <li>Now consider the lower cost \c Track. If there is a free interval
|
||||
* for the \c TrackSegment. Issue a \c Session::addInsertEvent() then
|
||||
* finish.
|
||||
*
|
||||
* If there is a <i>"soft overlap"</i>, that is the overlaping
|
||||
* \c TrackSegment already in the \c Track could be shrunk either to
|
||||
* the left or the right so the new \c TrackSegment can be inserted.
|
||||
* This is managed by \c RoutingEvent::_setAside(), for each soft
|
||||
* overlaping \c TrackSegment, gets its perpandiculars and issue
|
||||
* a displacement request for all of them. That is, re-post a
|
||||
* \c RoutingEvent with updated constraints and remove the
|
||||
* perpandicular from it's Track if it has already been routed.
|
||||
* Note that no request is issued for the overlaping \c TrackSegment
|
||||
* itself has it do not change of Track.
|
||||
*
|
||||
* If there is a <i>"hard overlap"</i>, that is the two \c TrackSegment
|
||||
* cannot share the same \c Track, remove the previous one from
|
||||
* the \c Track and re-post a \c RoutingEvent. Note that, the
|
||||
* cost object should have selected a \c TrackSegment which could
|
||||
* be ripped-up. Otherwise the \c Track would'nt even be a candidate.
|
||||
* </ul>
|
||||
*
|
||||
* When a TrackSegment is riped up, it is re-routed immediately
|
||||
* afterward. This is done by increasing his event level.
|
||||
* </ol>
|
||||
*/
|
||||
|
||||
|
||||
/*! \namespace Kite
|
||||
* \brief The namespace dedicated to Kite.
|
||||
*/
|
||||
|
||||
}
|
|
@ -0,0 +1,597 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
/*! \class RoutingEvent
|
||||
* \brief Manage TrackSegment routing requests.
|
||||
*
|
||||
* 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).
|
||||
*
|
||||
* \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<candidates.size() ; i++ ) {
|
||||
if ( candidates[0].insertInTrack ( _segment ) ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Case -B- "Infinite Cost".
|
||||
// Attention: meaning's changed, *infinite* only in case of
|
||||
// conflict with a *fixed* other segment.
|
||||
modifyTopology ( _segment );
|
||||
}
|
||||
}
|
||||
|
||||
// Restore Track coherency before processing any other event.
|
||||
Session::revalidate ();
|
||||
}
|
||||
\endcode
|
||||
* \section secRoutingIntervalToDo ToDo
|
||||
*
|
||||
* <ul>
|
||||
* <li>New \c isLocal() method on \TrackSegment. Tells if the \TrackSegment
|
||||
* is associated only to local AutoSegment.
|
||||
* <li>Increase the overlap cost of a \TrackSegment from an already routed
|
||||
* GCell routing set.
|
||||
* </ul>
|
||||
*
|
||||
*
|
||||
* \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.
|
||||
* <ul>
|
||||
* <li>The <i>optimal</i> interval : where the \Net wirelength will be
|
||||
* minimal (comes from \c Katabatic::AutoSegment).
|
||||
* <li>The <i>constraint</i> 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).
|
||||
* <li>The <i>perpandicular</i> 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.
|
||||
* </ul>
|
||||
* The perpandicular interval comes from perpandicular constraints on \TrackSegment
|
||||
* of the <i>same</i> \c Net. The left/right axis weights comes from requests of
|
||||
* <i>other</i> \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:
|
||||
* <ul>
|
||||
* <li>A \TrackSegment can only be displaced by it's associated \RoutingEvent.
|
||||
* <li>Corollary: the only \TrackSegment displaced while processing a
|
||||
* \RoutingEvent is the one associated to the event.
|
||||
* <li>Conflicts occurs between the \RoutingEvent \TrackSegment and already
|
||||
* placed others \TrackSegment.
|
||||
*
|
||||
* The conflict can be solved by displacing/modifying <i>others</i>
|
||||
* \TrackSegment or by modifying the to be inserted one. In the later
|
||||
* case, the newly created or modified \TrackSegment are (re)scheduleds
|
||||
* <i>before</i> the would be inserted.
|
||||
* <li>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.
|
||||
* <li>\TrackSegment are inserted only, and only if there is enough free space.
|
||||
* That is, if any kind of overlap occurs, it is <i>not</i> inserted
|
||||
* but <i>rescheduled</i>. The blocking \TrackSegments are then
|
||||
* rescheduled <i>after</i> the current one.
|
||||
* <li>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).
|
||||
* </ul>
|
||||
*
|
||||
* \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:
|
||||
* <ol>
|
||||
* <li>In normal mode, that is, no maximum ripup has been reached, the
|
||||
* blocking <i>other</i> \TrackSegment are removed and the current
|
||||
* is rescheduled <i>before</i> them.
|
||||
* <li>In maximum ripup mode, some \TrackSegment has to give way.
|
||||
* <ul>
|
||||
* <li>If the current one is modified, it must be rescheduled <i>after</i>
|
||||
* it's modified bits are rescheduleds.
|
||||
* <li>If <i>others</i> are modifieds they must be rescheduled <i>after</i>
|
||||
* the current one (so it will grabs the place).
|
||||
* </ul>
|
||||
* </ol>
|
||||
*
|
||||
*
|
||||
* \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.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td align="center"> \b Id </td>
|
||||
* <td align="center">\b Type</td>
|
||||
* <td align="center"> \b Local </td>
|
||||
* <td align="center"> \b Global </td>
|
||||
* <td align="center">\b Action</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td align="center">\e 1</td>
|
||||
* <td align="center">\c Minimize</td>
|
||||
* <td align="center">\e yes</td>
|
||||
* <td align="center">\e no</td>
|
||||
* <td>try to fit into a hole</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td align="center">\e 2</td>
|
||||
* <td align="center">\c DogLeg</td>
|
||||
* <td align="center">\e yes</td>
|
||||
* <td align="center">\e no</td>
|
||||
* <td>Dogleg : analyse overlap and try to solve it by breaking (self)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td align="center">\e 3</td>
|
||||
* <td align="center">\c Desalignate</td>
|
||||
* <td align="center">\e yes</td>
|
||||
* <td align="center">\e yes</td>
|
||||
* <td>on a set of alignated \TrackSegment, suppress the
|
||||
* alignment constraints, thus making then independants
|
||||
* </td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td align="center">\e 4</td>
|
||||
* <td align="center">\c Slacken</td>
|
||||
* <td align="center">\e yes</td>
|
||||
* <td align="center">\e yes</td>
|
||||
* <td>if the target/source constraint is less than the
|
||||
* GCell, adds perpandicular straps to free the \TrackSegment.
|
||||
* This occurs to free from terminal constraints
|
||||
* </td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td align="center">\e 5</td>
|
||||
* <td align="center">\c ConflictSolve1</td>
|
||||
* <td align="center">\e yes</td>
|
||||
* <td align="center">\e yes</td>
|
||||
* <td>try to find in the history a reccurent dislodger,
|
||||
* and break (self) to accomodate it
|
||||
* </td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td align="center">\e 6</td>
|
||||
* <td align="center">\c ConflictSolve2</td>
|
||||
* <td align="center">\e no</td>
|
||||
* <td align="center">\e yes</td>
|
||||
* <td>try to find a Track on which we can dislodge
|
||||
* an other \TrackSegment
|
||||
* </td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td align="center">\e 7</td>
|
||||
* <td align="center">\c MoveUp</td>
|
||||
* <td align="center">\e no</td>
|
||||
* <td align="center">\e yes</td>
|
||||
* <td>try to go on upper layer.
|
||||
* </td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td align="center">\e 8</td>
|
||||
* <td align="center">\c Unimplemented</td>
|
||||
* <td align="center">\e no</td>
|
||||
* <td align="center">\e yes</td>
|
||||
* <td>we failed to place this \TrackSegment
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
*
|
||||
* \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<candidates.size() ; i++ ) {
|
||||
others = otherSegmentsConflicts(candidates[i]);
|
||||
|
||||
// Select Track with only one conflicting other.
|
||||
if ( others.size() == 1 ) {
|
||||
// Local vs. Local => 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.
|
||||
* <ol>
|
||||
* <li>The scheduler try to place the \TrackSegment on top of the
|
||||
* event queue, calling process().
|
||||
* <li>There is a soft overlap on the best candidate track, a set
|
||||
* aside is issued.
|
||||
* <li>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().
|
||||
* <li>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).
|
||||
* <li>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...
|
||||
* </ol>
|
||||
*
|
||||
* \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 :
|
||||
* <ul>
|
||||
* <li>\RoutingEvent are used to store algorithmic informations that
|
||||
* must persist until the negociation algorithm have fully
|
||||
* completed (<i>bound</i> interval in particular).
|
||||
* <li>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.
|
||||
* </ul>
|
||||
*
|
||||
* \important This is the history queue which is responsible for freeing all the
|
||||
* \RoutingEvent in his destructor.
|
||||
*
|
||||
*
|
||||
* \section secRoutingEventCase Routing Event actions
|
||||
*
|
||||
* <ul>
|
||||
* <li><b>Free Track Case</b>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*
|
||||
* <li><b>Soft Overlap Case</b>
|
||||
*
|
||||
* Already inserted \TrackSegment <b>a</b> & <b>b</b> could be shrunk
|
||||
* to make place for \TrackSegment <b>c</b>. Parallel overlaping \TrackSegment
|
||||
* are not removed, their perpandiculars are with updated left/right axis weight.
|
||||
*
|
||||
* The <b>a</b> perpandicular belongs the same GCell routing set so it
|
||||
* is removed from is \Track to be displaced.
|
||||
*
|
||||
* The <b>b</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
|
||||
*
|
||||
*
|
||||
* <li><b>Hard Overlap Case</b>
|
||||
*
|
||||
* No way to shrunk overlaping \TrackSegment to make place for <b>c</b>.
|
||||
* All parallel overlaping \TrackSegments must be removeds to be displaced
|
||||
* on other \Tracks.
|
||||
*
|
||||
* The <b>a</b> parallel belongs to a more prioritary GCell routing set
|
||||
* so it can be removed, it is therefore broken.
|
||||
*
|
||||
* The <b>b</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
|
||||
*
|
||||
*
|
||||
* <li><b>Self Relax</b>
|
||||
*
|
||||
* Instead of trying to displace overlaping \TrackSegments we break the
|
||||
* current one.
|
||||
*
|
||||
* \image html RoutingEvent-13.png
|
||||
* \image latex RoutingEvent-13.pdf
|
||||
*
|
||||
*
|
||||
* <li><b>Self Desalignate</b>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*
|
||||
* <li><b>Self Slacken</b>
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
/*! \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.
|
||||
*/
|
||||
|
||||
/*! \function TrackSegment* RoutingEvent::getSegment () const;
|
||||
* \Return The associated and unique \TrackSegment.
|
||||
*/
|
||||
|
||||
/*! \function unsigned long RoutingEvent::getPriority () const;
|
||||
* \Return The second criterion used to sort \RoutingEvents in the negociation queue.
|
||||
* Currently, it is the <i>area</i> of the associated \TrackSegment, which in
|
||||
* turn return the <i>slack</i> (not a very fortunate choice of name...).
|
||||
*/
|
||||
|
||||
/*! \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 <i>before</i> the original one, which is marked as
|
||||
* <i>processed</i> to be ignored.
|
||||
*
|
||||
* \see setEventLevel().
|
||||
*/
|
||||
|
||||
/*! \function RoutingEvent* RoutingEvent::getClone () const;
|
||||
* \Return An exact copy of the current \RoutingEvent.
|
||||
*/
|
||||
|
||||
/*! \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::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 :
|
||||
* <ul>
|
||||
* <li>The event has really been processed by the process() member
|
||||
* function.
|
||||
* <li>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.
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
/*! \function void RoutingEvent::setEventLevel ( unsigned int level );
|
||||
* \param level The new event level.
|
||||
*
|
||||
* \see getEventLevel().
|
||||
*/
|
||||
|
||||
/*! \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 :
|
||||
* <ol>
|
||||
* <li>Invalidating all perpandicular \TrackSegments.
|
||||
* <li>Computing the free interval allowed by the free intervals
|
||||
* in perpandicular \Tracks holding the perpandicular \TrackSegments.
|
||||
* <li>Merging in the various constraints intervals : from the
|
||||
* \TrackSegment itself, from the free intervals in the
|
||||
* perpandicular \Tracks and from the \RoutingEvent bound
|
||||
* constraints.
|
||||
* <li>Finding the candidate \Tracks for the \RoutingEvent,
|
||||
* using \c Track_Spiral \Collection.
|
||||
* </ol>
|
||||
* The results of the shared operation are passed to derived classes
|
||||
* trough the \c State internal structure.
|
||||
*/
|
||||
|
||||
/* \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 <i>soft overlap</i>. Create or enlarge a free space
|
||||
* in \c track so it can contain the requested \interval. <code>[begin:end]</code> defines
|
||||
* the range of indexes of overlaping \TrackSegment in \c track.
|
||||
* Displace TrackSegment that are <b>perpandicular</b> 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 <em>not</em> removed from the \c track.
|
||||
*
|
||||
* A note on implementation :
|
||||
* <ul>
|
||||
* <li>\c data1 : the DataNegociate of the to be inserted \TrackSegment.
|
||||
* <li>\c segment2 : the current overlaping \TrackSegment (from \c begin
|
||||
* to \c end).
|
||||
* <li>\c data2 : the DataNegociate of the overlaping \TrackSegment.
|
||||
* <li>\c segment3 : a \TrackSegment perpandicular to \c segment2.
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
/* \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 <i>hard overlap</i>, 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.
|
||||
*/
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,133 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
/*! \class Session
|
||||
* \brief Kite update Session (\b API).
|
||||
*
|
||||
* Session extend the Katabatic update session to the Kite
|
||||
* router level. Mainly by managing Track update.
|
||||
*
|
||||
* For details on how Katabatic Sessions works, have a look to
|
||||
* \ref katabaticSession.
|
||||
*
|
||||
*
|
||||
* \section secSessionMechanism The Session Mechanism.
|
||||
*
|
||||
* Delayed modification procedure :
|
||||
* <ol>
|
||||
* <li>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.
|
||||
* <li>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.
|
||||
* </ol>
|
||||
*
|
||||
*
|
||||
* \section secKiteSessionRevalidate The Revalidate Algorithm.
|
||||
*
|
||||
* Revalidation steps :
|
||||
* <ol>
|
||||
* <li>process all remove events. detach TrackSegment from
|
||||
* their Track, but do not remove the pointer from the
|
||||
* internal \vector.
|
||||
* <li>Pack all Track in which removal have took place.
|
||||
* <li>process all insert events. This is the time TrackSegment
|
||||
* are moved into their new Track (physical displacement).
|
||||
* <li>Call the Katabatic::Session::revalidate() method.
|
||||
* <li>Recompute the canonical position of source and target
|
||||
* of all invalidateds TrackSegment (take account of
|
||||
* extention modifications).
|
||||
* <li>Perform a sort() on all Track that have been modifieds.
|
||||
* </ol>
|
||||
*/
|
||||
|
||||
|
||||
/*! \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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* add \e segment to the \vector of TrackSegment for which we
|
||||
* have to recompute the canonical size (i.e. extentions may
|
||||
* have moved).
|
||||
*/
|
||||
|
||||
/*! \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 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 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 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().
|
||||
*/
|
||||
|
||||
// \}
|
||||
|
||||
}
|
|
@ -0,0 +1,397 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
/*! \class Track
|
||||
* \brief Structure managing one routing track.
|
||||
*
|
||||
* \section secTrackImplementation Track Implementation
|
||||
*
|
||||
* Basically a Track is a sorted vector of TrackSegment, TrackSegment
|
||||
* beeing a decoration of the Katabatic::AutoSegment. Managment rules :
|
||||
* <ul>
|
||||
* <li><b>Rule 1 :</b> the vector of TrackSegment is sorted by
|
||||
* increasing source positions.
|
||||
* <li><b>Rule 2 :</b> two consecutives segments TrackSegment do
|
||||
* not overlap, except in case of <b>rule 3</b>.
|
||||
* <li><b>Rule 3 :</b> if they belongs to the same \Net, two
|
||||
* consecutive segments can overlap, see Track::getNetUsedInterval().
|
||||
* </ul>
|
||||
*
|
||||
* \image html Track-1.png "Track Structure"
|
||||
* \image latex Track-1.pdf "Track Structure" width=0.7\textwidth
|
||||
*
|
||||
*
|
||||
* <b>updates procedures</b>
|
||||
*
|
||||
* Kite extend the Katabatic::Session mechanism to manage Track
|
||||
* modifications.
|
||||
*
|
||||
* <b>Indexes vs. Iterators</b>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* <b>Looking up free/used zones</b>
|
||||
*
|
||||
* 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()).
|
||||
*
|
||||
* \image html Track-2.png "Track Zones - First Approach"
|
||||
* \image latex Track-2.pdf "Track Zones - First Approach" width=0.7\textwidth
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* \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.
|
||||
*
|
||||
* \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).
|
||||
*
|
||||
* 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 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 :
|
||||
* <ul>
|
||||
* <li>\e index is outside the sorted zone.
|
||||
* <li>\e index points to a hole in the Track.
|
||||
* <li>\e index is equal to Track::NPOS.
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
/*! \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.
|
||||
*
|
||||
* The relation between the returned \e index and the position is
|
||||
* given through the \e state parameter.
|
||||
*
|
||||
* \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<TrackSegment*>::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.
|
||||
*
|
||||
* \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.
|
||||
*
|
||||
* \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.
|
||||
*
|
||||
* \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[ .
|
||||
*
|
||||
* \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.
|
||||
*
|
||||
* Perform a complete Track check. Looks for the following incoherencies :
|
||||
* <ul>
|
||||
* <li>TrackSegment do not refers this Track.
|
||||
* <li>TrackSegment is detached (TrackSegment::getTrack() is \NULL).
|
||||
* <li>TrackSegment is hollow, this one is very unlikely as hollow
|
||||
* TrackSegment are only created for the \lower_bound.
|
||||
* <li>\NULL pointers (should never occurs, nevertheless...)
|
||||
* <li>And finally, call checkOverlap().
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
/*! \function void Track::checkOverlap () const;
|
||||
* \return the number of overlaping TrackSegment.
|
||||
*
|
||||
* Perform the following checks :
|
||||
* <ul>
|
||||
* <li>Two consecutive TrackSegment from different \Net must not
|
||||
* overlap.
|
||||
* <li>For TrackSegment starting from the same position, the
|
||||
* longuest must be first.
|
||||
* </ul>
|
||||
*/
|
||||
|
||||
/*! \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 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.
|
||||
*/
|
||||
|
||||
/*! \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.
|
||||
*/
|
||||
|
||||
// \}
|
||||
|
||||
|
||||
/*! \name Updators
|
||||
*/
|
||||
// \{
|
||||
|
||||
/*! \function void Track::insert ( TrackSegment* segment );
|
||||
* adds \e segment to the Track. Must only be used inside a
|
||||
* TrackSession.
|
||||
*
|
||||
* \see TrackSession.
|
||||
*/
|
||||
|
||||
/*! \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).
|
||||
*/
|
||||
|
||||
/*! \function void Track::sort ();
|
||||
*
|
||||
* sort the the vector. Must be called \e after the Pack() method,
|
||||
* so no detached TrackSegment are presents.
|
||||
*/
|
||||
|
||||
// \}
|
||||
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
/*! \class TrackCost
|
||||
* \brief Insertion cost of a \TrackSegment in a \Track.
|
||||
*
|
||||
*
|
||||
* The \TrackCost is not computed by itself. It has to be build by
|
||||
* whoever has created it. For example Track::getOverlapCost().
|
||||
*
|
||||
*
|
||||
* \section secTrackCostOrdering Sorting Track costs
|
||||
*
|
||||
* The \TrackCost is composed of the following criterions :
|
||||
* <ol>
|
||||
* <li>boolean \c _infinite : infinite.
|
||||
* <li>count \c _terminals : number of terminals.
|
||||
* <li>length \c _delta : overlap between requested interval and
|
||||
* \TrackSegment of the \Track.
|
||||
* <li>length \c _deltaPerpand : length of perpandicular wiring needed to
|
||||
* connect to this \Track.
|
||||
* </ol>
|
||||
* Criterions are listed above in decreasing lexicographical weigh order.
|
||||
*
|
||||
* There is also special partial ordering functor : TrackCost::CompareByDelta.
|
||||
*/
|
||||
|
||||
/*! \function TrackCost::TrackCost ( Track* track, const Interval& interval, size_t begin, size_t end );
|
||||
* \param track The track on which the cost is performed.
|
||||
* \param interval The interval for which we want a cost.
|
||||
* \param begin The index of the first overlaping \TrackSegment in the \Track.
|
||||
* \param end The index of the last overlaping \TrackSegment in the \Track.
|
||||
*
|
||||
* Create a \TrackCost object. Constructor parameters cannot be changed
|
||||
* after creation.
|
||||
*
|
||||
* \remark The cost is not computed by the constructor. It is computed afterward
|
||||
* by any flavor of Track::getOverlapCost().
|
||||
*/
|
||||
|
||||
/*! \function bool TrackCost::isInfinite () const;
|
||||
* \Return The overlap include a \TrackSegment from a \GCellRoutingSet of
|
||||
* higher priority, must'nt be overlaped.
|
||||
*/
|
||||
|
||||
/*! \function bool TrackCost::isHardOverlap () const;
|
||||
* \Return The overlaped \TrackSegment cannot be shrunk to create a sufficent
|
||||
* free space. See the bound interval of \TrackSegmentCost.
|
||||
*/
|
||||
|
||||
/*! \function bool TrackCost::isOverlap () const;
|
||||
* \Return The overlaped \TrackSegment could be shrunk to create a suitable
|
||||
* free space.
|
||||
*/
|
||||
|
||||
/*! \function bool TrackCost::isFree () const;
|
||||
* \Return There is enough free space to insert the \TrackSegment.
|
||||
*/
|
||||
|
||||
/*! \function Track* TrackCost::getTrack () const;
|
||||
* \Return The associated \Track.
|
||||
*/
|
||||
|
||||
/*! \function const Interval& TrackCost::getInterval () const;
|
||||
* \Return The interval for which we want to compute a cost.
|
||||
*/
|
||||
|
||||
/*! \function size_t TrackCost::getBegin () const;
|
||||
* \Return The index of the first overlaping \TrackSegment in \Track.
|
||||
*/
|
||||
|
||||
/*! \function size_t TrackCost::getEnd () const;
|
||||
* \Return The index of the last overlaping \TrackSegment in \Track.
|
||||
*/
|
||||
|
||||
/*! \function unsigned int TrackCost::getTerminals () const;
|
||||
* \Return The number of terminal in the interval, see TrackSegmentCost::getTerminals().
|
||||
*/
|
||||
|
||||
/*! \function DbU::Unit TrackCost::getDelta () const;
|
||||
* \Return The amount of overlaping between the interval and the \TrackSegments
|
||||
* already in the \Track.
|
||||
*/
|
||||
|
||||
/*! \function DbU::Unit TrackCost::getDeltaPerpand () const;
|
||||
* \Return The amount of perpandicular wirelength needed to put the to be
|
||||
* inserted \TrackSegment in this \Track.
|
||||
*/
|
||||
|
||||
/*! \function void TrackCost::setInfinite ();
|
||||
* Raise the infinite flag.
|
||||
*/
|
||||
|
||||
/*! \function void TrackCost::setHardOverlap ();
|
||||
* Raise the hard overlap flag.
|
||||
*/
|
||||
|
||||
/*! \function void TrackCost::setOverlap ();
|
||||
* Raise the soft overlap flag.
|
||||
*/
|
||||
|
||||
/*! \function void TrackCost::incTerminals ( unsigned int number );
|
||||
* \param number The number of terminal to adds.
|
||||
*/
|
||||
|
||||
/*! \function void TrackCost::incDelta ( DbU::Unit delta );
|
||||
* \param delta The amount of length to add to the overlap.
|
||||
*/
|
||||
|
||||
/*! \function void TrackCost::incDeltaPerpand ( DbU::Unit delta );
|
||||
* \param delta Increments the perpandicular delta.
|
||||
*/
|
||||
|
||||
/*! \function bool operator< ( const TrackCost& lhs, const TrackCost& rhs );
|
||||
* \param lhs the left hand side operand.
|
||||
* \param rhs the right hand side operand.
|
||||
* \return \true if <code>lhs < rhs</code>, see \ref secTrackCostOrdering.
|
||||
*/
|
||||
|
||||
|
||||
/*! \class TrackCost::CompareByDelta
|
||||
* \brief Partial compare function for \TrackCost.
|
||||
*
|
||||
* Allow \TrackCost sorting on the \c _delta criterion alone.
|
||||
*/
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,170 @@
|
|||
|
||||
// -*- 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.
|
||||
*
|
||||
* We create one TrackSegment per aligned Katabatic::AutoSegment set,
|
||||
* the TrackSegment is associated to the canonical one of the set.
|
||||
*
|
||||
* To provide some speedup, the full extention of the aligned segment
|
||||
* set is computed once and stored in the TrackSegment itself.
|
||||
* 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).
|
||||
*
|
||||
* \see Track::getNext().
|
||||
*/
|
||||
|
||||
/*! \function TrackSegment* TrackSegment::getPrevious () const;
|
||||
* \Return The previous TrackSegment in the Track (can be \NULL).
|
||||
*
|
||||
* \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.
|
||||
*
|
||||
* \important This function <em>do not</em> update the Track itself. The
|
||||
* program must take care of it under penalty of introducing
|
||||
* incoherencies.
|
||||
*
|
||||
* \see Track::detach().
|
||||
*/
|
||||
|
||||
/* \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 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.
|
||||
*
|
||||
*/
|
||||
|
||||
// \}
|
||||
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
/*! \class TrackSegmentCost
|
||||
* \brief The cost calculator of a TrackSegment.
|
||||
*
|
||||
* \section secMiscAttributes Miscellaneous attributes
|
||||
*
|
||||
* Net instead of \TrackSegment : what we will access the most is the
|
||||
* \TrackSegment owner, so it's it we keep as an attribute. The consequence
|
||||
* beeing that the update member function should be given the \TrackSegment
|
||||
* as argument.
|
||||
*
|
||||
*
|
||||
* \section secBoundInterval Bound interval cost component
|
||||
*
|
||||
* This is the minimal interval to which the \TrackSegment can be
|
||||
* shrunk without breaking the net's connexity. The interval is
|
||||
* computed by AutoSegment::getTopologicalInfos(). And the computation
|
||||
* is as follow :
|
||||
* <ol>
|
||||
* <li>Each AutoContact has a <em>constraint box</em> which defines
|
||||
* the legal area where the AutoContact could be positionned.
|
||||
* <li>The <em>left bound</em> is the minimum of all constraints
|
||||
* boxes max.
|
||||
* <li>Conversely, the <em>right bound</em> is the maximum of all
|
||||
* constraints boxes min.
|
||||
* </ol>
|
||||
* \image html TrackSegmentCost-1.png "Left bound & right bound"
|
||||
* \image latex TrackSegmentCost-1.pdf "Left bound & right bound" width=0.6\textwidth
|
||||
*
|
||||
* \image html TrackSegmentCost-2.png "Maximal shrink example"
|
||||
* \image latex TrackSegmentCost-2.pdf "Maximal shrink example" width=0.6\textwidth
|
||||
*
|
||||
*
|
||||
* \section secCostAttractors Attractors and differential wirelength cost component
|
||||
*
|
||||
* The goal of attractors is to compute the wirelength variation whenever
|
||||
* the \TrackSegment changes of supporting \Track.
|
||||
*
|
||||
* The \TrackSegment is connected to perpandicular \TrackSegment, attractors
|
||||
* are the extremity position of those perpandicular <em>which are not</em>
|
||||
* connected to the reference \TrackSegment. The true rule is more complex
|
||||
* an is computed by AutoSegment::isTopologicalBound().
|
||||
*
|
||||
* \image html TrackSegmentCost-3.png "Attractors example"
|
||||
* \image latex TrackSegmentCost-3.pdf "Attractors example" width=0.6\textwidth
|
||||
*
|
||||
* In the attractor example, the reference horizontal \TrackSegment (in
|
||||
* black) which is made of (at least) three \c AutoSegments, is connected
|
||||
* to five vertical canonical \TrackSegment (labelled \e A through \e E).
|
||||
*
|
||||
* \e Left attractors are below the horizontal \TrackSegment axis,
|
||||
* \e right ones are above. Punctual attractors are exactly on the axis.
|
||||
*
|
||||
* As both \TrackSegment and \c AutoSegment are orienteds, source is always
|
||||
* the minimum and target always the maximum.
|
||||
*
|
||||
* The attractors are deduced as follow :
|
||||
* <ul>
|
||||
* <li>\e A : source is on the axis and move with it, so it is not took
|
||||
* into account. Target <code>\@2:19</code> is a right attractor.
|
||||
* <li>\e B : not aligned due to constraints on \e A, fully included in
|
||||
* \e A, do not generate attractor.
|
||||
* <li>\e C : canonical is accross the reference horizontal, both source
|
||||
* and target generate attractors : <code>left \@7:6</code> and
|
||||
* <code>right \@7:16</code>.
|
||||
* <li>\e D : punctual, that is null-length canonical exactly on the
|
||||
* axis. Generate only one attractor : <code>punctual \@14:10</code>
|
||||
* (i.e. not one for each extremity).
|
||||
* <li>\e E : target is on the axis and move with it, so it is not took
|
||||
* into account. Target <code>\@23:4</code> is a left attractor.
|
||||
* </ul>
|
||||
* The concept of left/right and punctual flavor for attractors are only
|
||||
* used dured construction. Once built only the coordinate remains.
|
||||
*
|
||||
* The extremity of perpandicular canonical \TrackSegment connected to
|
||||
* the reference segment do not generate attractors because they move
|
||||
* with it. But there are exception to this behavior : one is that
|
||||
* the extremity is in fact anchored to a terminal and will not move.
|
||||
* This is the work of the AutoSegment::isTopologicalBound() function
|
||||
* to check for thoses exceptions, in which case an attractor will be
|
||||
* created.
|
||||
*
|
||||
*
|
||||
* \section secTerminalCount The terminal count cost component
|
||||
*
|
||||
* The number of terminals directly connected to this \TrackSegment.
|
||||
* Computation relies on AutoSegment::getTerminalCount().
|
||||
*/
|
||||
|
||||
/*! \function Net* TrackSegmentCost::getNet () const;
|
||||
* \Return The Net owning this TrackSegment.
|
||||
*/
|
||||
|
||||
/*! \function unsigned int TrackSegmentCost::getTerminals () const;
|
||||
* \Return The number of terminal directly connected to this \TrackSegment.
|
||||
*/
|
||||
|
||||
/*! \function DbU::Unit TrackSegmentCost::getWiringDelta ( DbU::Unit axis ) const;
|
||||
* \param axis The axis where to put the TrackSegment.
|
||||
*
|
||||
* \return The total wirelengh needed for perpandicular TrackSegment to connect
|
||||
* with this one sets on <em>axis</em>. The sum of distance to all the
|
||||
* attractors.
|
||||
*/
|
||||
|
||||
/*! \function void TrackSegmentCost::update ( TrackSegment* trackSegment );
|
||||
* \param trackSegment the associated \TrackSegment, must be the same as used
|
||||
* in the construction.
|
||||
*
|
||||
* Update the cost calculator after a relative position change.
|
||||
*/
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,798 @@
|
|||
%%
|
||||
%% 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'.
|
|
@ -0,0 +1,286 @@
|
|||
# Doxyfile 1.3.4
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
|
||||
PROJECT_NAME = "Kite - Detailed Router"
|
||||
PROJECT_NUMBER = 1.0
|
||||
OUTPUT_DIRECTORY = .
|
||||
OUTPUT_LANGUAGE = English
|
||||
#USE_WINDOWS_ENCODING = NO
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = NO
|
||||
STRIP_FROM_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = NO
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
#DETAILS_AT_TOP = YES
|
||||
INHERIT_DOCS = YES
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
TAB_SIZE = 2
|
||||
ALIASES = "function=\fn"\
|
||||
"important=\par Important:\n"\
|
||||
"remark=\par Remark:\n"\
|
||||
"Return=<b>Returns:</b>"\
|
||||
"True=\b True"\
|
||||
"true=\b true"\
|
||||
"False=\b False"\
|
||||
"false=\b false"\
|
||||
"VERTICAL=\b VERTICAL"\
|
||||
"HORIZONTAL=\b HORIZONTAL"\
|
||||
"NULL=\c NULL"\
|
||||
"vector=\c vector"\
|
||||
"lower_bound=\c lower_bound"\
|
||||
"Collection=\c Collection"\
|
||||
"Collections=\c Collections"\
|
||||
"Interval=\c Interval"\
|
||||
"interval=\c interval"\
|
||||
"Box=\c Box"\
|
||||
"box=\c box"\
|
||||
"Layer=\c Layer"\
|
||||
"Layers=\c Layers"\
|
||||
"Net=\c Net"\
|
||||
"Nets=\c Nets"\
|
||||
"Pin=\c Pin"\
|
||||
"Pins=\c Pins"\
|
||||
"Plug=\c Plug"\
|
||||
"Plugs=\c Plugs"\
|
||||
"RoutingPad=\c RoutingPad"\
|
||||
"RoutingPads=\c RoutingPads"\
|
||||
"Cell=\c Cell"\
|
||||
"Cells=\c Cells"\
|
||||
"CEngine=\c CEngine"\
|
||||
"CEngines=\c CEngines"\
|
||||
"GCell=\c GCell"\
|
||||
"GCells=\c GCells"\
|
||||
"GCellRoutingSet=\c GCellRoutingSet"\
|
||||
"RoutingPlane=\c RoutingPlane"\
|
||||
"RoutingPlanes=\c RoutingPlanes"\
|
||||
"TrackSegment=\c TrackSegment"\
|
||||
"TrackSegments=\c TrackSegments"\
|
||||
"TrackSegmentCost=\c TrackSegmentCost"\
|
||||
"TrackSegmentCosts=\c TrackSegmentCosts"\
|
||||
"RoutingEvent=\c RoutingEvent"\
|
||||
"RoutingEvents=\c RoutingEvents"\
|
||||
"Track=\c Track"\
|
||||
"Tracks=\c Tracks"\
|
||||
"TrackCost=\c TrackCost"\
|
||||
"TrackCosts=\c TrackCosts"\
|
||||
"Session=\c Session"\
|
||||
"Sessions=\c Sessions"\
|
||||
"Hurricane=<a href='../hurricane/Index.html'>Hurricane</a>"\
|
||||
"STL=<a href='http://www.sgi.com/tech/stl/'>STL</a>"
|
||||
OPTIMIZE_OUTPUT_FOR_C = NO
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
SUBGROUPING = YES
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = YES
|
||||
EXTRACT_STATIC = YES
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
EXTRACT_ANON_NSPACES = YES
|
||||
HIDE_UNDOC_MEMBERS = YES
|
||||
HIDE_UNDOC_CLASSES = YES
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = NO
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 1
|
||||
SHOW_USED_FILES = YES
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to warning and progress messages
|
||||
|
||||
QUIET = YES
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = NO
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
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
|
||||
|
||||
FILE_PATTERNS = *.h \
|
||||
*.cpp \
|
||||
*.dox
|
||||
|
||||
RECURSIVE = YES
|
||||
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS =
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH = images
|
||||
INPUT_FILTER =
|
||||
FILTER_SOURCE_FILES = YES
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to source browsing
|
||||
|
||||
SOURCE_BROWSER = NO
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
REFERENCED_BY_RELATION = YES
|
||||
REFERENCES_RELATION = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to the alphabetical class index
|
||||
|
||||
ALPHABETICAL_INDEX = YES
|
||||
COLS_IN_ALPHA_INDEX = 2
|
||||
IGNORE_PREFIX =
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to the HTML output
|
||||
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER = header.html
|
||||
HTML_FOOTER = footer.html
|
||||
HTML_STYLESHEET = ASIM.css
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
GENERATE_HTMLHELP = NO
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = YES
|
||||
ENUM_VALUES_PER_LINE = 1
|
||||
GENERATE_TREEVIEW = NO
|
||||
TREEVIEW_WIDTH = 250
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to the LaTeX output
|
||||
|
||||
GENERATE_LATEX = YES
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = YES
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER = header.tex
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = YES
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to the RTF output
|
||||
|
||||
GENERATE_RTF = YES
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to the man page output
|
||||
|
||||
GENERATE_MAN = YES
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = NO
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to the XML output
|
||||
|
||||
GENERATE_XML = NO
|
||||
XML_OUTPUT = xml
|
||||
XML_SCHEMA =
|
||||
XML_DTD =
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options for the AutoGen Definitions output
|
||||
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to the Perl module output
|
||||
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED = __DOXYGEN_PROCESSOR__
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to external references
|
||||
|
||||
TAGFILES = ../../../../hurricane/doc/hurricane/html/hurricane.tag=../hurricane \
|
||||
../../katabatic/doc/html/katabatic.tag=../katabatic
|
||||
GENERATE_TAGFILE = html/kite.tag
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
|
||||
CLASS_DIAGRAMS = NO
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = YES
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = NO
|
||||
UML_LOOK = NO
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
CALL_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = NO
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
#MAX_DOT_GRAPH_WIDTH = 512
|
||||
#MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
MAX_DOT_GRAPH_DEPTH = 0
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
|
||||
# --------------------------------------------------------------------
|
||||
# Configuration::addtions related to the search engine
|
||||
|
||||
SEARCHENGINE = NO
|
|
@ -0,0 +1,16 @@
|
|||
<br>
|
||||
<hr>
|
||||
<table class="footer1">
|
||||
<tr>
|
||||
<td class="LFooter"><small>Generated by doxygen $doxygenversion on $date</small></td>
|
||||
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="footer2">
|
||||
<tr>
|
||||
<td class="LFooter">Kite - Detailed Router</td>
|
||||
<td class="RFooter"><small>Copyright © 2008-2009 LIP6. All rights reserved</small></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,23 @@
|
|||
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
|
||||
<title>Kite - Detailed Router: Router Documentation</title>
|
||||
<link href="ASIM.css" rel="stylesheet" type="text/css">
|
||||
</head>
|
||||
<h1 class="header">Kite - Detailed Router</h1>
|
||||
<center class="header">
|
||||
<table class="header">
|
||||
<tr>
|
||||
<td><a href="index.html">Summary</a></td>
|
||||
<td><a href="modules.html">Concepts</a></td>
|
||||
<td><a href="namespaces.html">Namespaces</a></td>
|
||||
<td><a href="hierarchy.html">Class Hierarchy</a></td>
|
||||
<td><a href="annotated.html">Classes</a></td>
|
||||
<td><a href="functions.html">Member Index</a></td>
|
||||
<!-- <td><a href="classes.html">Index2</a></td> -->
|
||||
</tr>
|
||||
</table>
|
||||
</center>
|
||||
<br>
|
||||
<hr>
|
||||
<body>
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
|
||||
\documentclass[a4paper]{asimbook}
|
||||
|
||||
\usepackage{a4wide}
|
||||
\usepackage{makeidx}
|
||||
\usepackage{fancyhdr}
|
||||
\usepackage{graphicx}
|
||||
\usepackage{multicol}
|
||||
\usepackage{float}
|
||||
\usepackage{textcomp}
|
||||
\usepackage{alltt}
|
||||
\usepackage{times}
|
||||
\ifx\pdfoutput\undefined
|
||||
\usepackage[ps2pdf,pagebackref=true,colorlinks=true,linkcolor=blue]{hyperref}
|
||||
\usepackage{pspicture}
|
||||
\else
|
||||
\usepackage[pdftex,pagebackref=true,colorlinks=true,linkcolor=blue]{hyperref}
|
||||
\fi
|
||||
\usepackage{doxygen}
|
||||
|
||||
\makeindex
|
||||
\setcounter{tocdepth}{1}
|
||||
\renewcommand{\footrulewidth}{0.4pt}
|
||||
\raggedbottom
|
||||
|
||||
|
||||
\begin{document}
|
||||
|
||||
\begin{titlepage}
|
||||
\vspace*{7cm}
|
||||
\begin{center}
|
||||
{\Large $projectname Reference Manual\\[1ex]\large $projectnumber }\\
|
||||
\vspace*{1cm}
|
||||
{\large Generated by Doxygen $doxygenversion}\\
|
||||
\vspace*{0.5cm}
|
||||
{\small $datetime}\\
|
||||
\end{center}
|
||||
\end{titlepage}
|
||||
|
||||
\clearemptydoublepage
|
||||
\pagenumbering{roman}
|
||||
|
||||
\tableofcontents
|
||||
\clearemptydoublepage
|
||||
|
||||
\pagenumbering{arabic}
|
|
@ -0,0 +1 @@
|
|||
<li><a class="entry" href="kite/index.html">Kite</a><br>Detailed Router<br><br>
|
|
@ -0,0 +1,66 @@
|
|||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 900 0 2700 4800
|
||||
2 2 0 0 4 7 60 -1 45 0.000 0 0 7 0 0 5
|
||||
1650 0 1950 0 1950 1800 1650 1800 1650 0
|
||||
2 2 0 0 4 7 60 -1 45 0.000 0 0 7 0 0 5
|
||||
1650 3000 1950 3000 1950 4800 1650 4800 1650 3000
|
||||
2 2 0 0 7 4 60 -1 38 2.000 0 0 -1 0 0 5
|
||||
1650 1800 1950 1800 1950 3000 1650 3000 1650 1800
|
||||
4 1 4 50 -1 14 12 0.0000 4 180 1785 1800 1725 right axis weight\001
|
||||
4 1 4 50 -1 14 12 0.0000 4 180 1680 1800 3225 left axis weight\001
|
||||
-6
|
||||
6 375 0 675 4800
|
||||
2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
3 1 1.00 60.00 120.00
|
||||
600 4800 600 3000
|
||||
2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
3 1 1.00 60.00 120.00
|
||||
600 0 600 1800
|
||||
2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
600 1800 600 3000
|
||||
4 1 4 50 -1 14 12 1.5708 4 180 1470 525 4050 _perpandicular\001
|
||||
-6
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
3000 2400 6900 2400
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
3000 900 6900 900
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
3000 3300 6900 3300
|
||||
2 2 0 0 0 7 60 -1 15 0.000 0 0 -1 0 0 5
|
||||
3000 900 6900 900 6900 3300 3000 3300 3000 900
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7050 3300 8400 3300
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7050 900 8400 900
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7050 1500 7800 1500
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7125 2700 7800 2700
|
||||
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
|
||||
7725 1500 7725 2700
|
||||
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
|
||||
8325 900 8325 3300
|
||||
2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
6900 3000 300 3000
|
||||
2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
6900 1800 300 1800
|
||||
2 2 0 0 0 7 55 -1 10 0.000 0 0 -1 0 0 5
|
||||
3000 1500 6900 1500 6900 2700 3000 2700 3000 1500
|
||||
2 2 0 4 0 7 50 -1 -1 10.000 0 0 -1 0 0 5
|
||||
2925 2325 3075 2325 3075 2475 2925 2475 2925 2325
|
||||
2 2 0 4 0 7 50 -1 -1 10.000 0 0 -1 0 0 5
|
||||
6825 2325 6975 2325 6975 2475 6825 2475 6825 2325
|
||||
4 1 0 50 -1 14 12 1.5708 4 180 840 7950 2100 _optimal\001
|
||||
4 1 0 50 -1 14 12 1.5708 4 165 1155 8550 2100 _constraint\001
|
After Width: | Height: | Size: 5.4 KiB |
|
@ -0,0 +1,46 @@
|
|||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
2 1 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 2
|
||||
600 3600 6600 3600
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
900 3600 2400 3600 2400 6300
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
6300 3600 4800 3600 4800 900
|
||||
2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 4
|
||||
2700 900 2700 3600 4500 3600 4500 6300
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
900 3300 1200 3300 1200 3600 900 3600 900 3300
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6000 3300 6300 3300 6300 3600 6000 3600 6000 3300
|
||||
2 2 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
2700 900 3000 900 3000 1200 2700 1200 2700 900
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
0 0 525 0 525 525 0 525 0 0
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
525 0 3150 0 3150 525 525 525 525 0
|
||||
2 1 0 1 4 7 60 -1 -1 0.000 0 0 -1 0 0 2
|
||||
2700 600 2700 6600
|
||||
2 1 0 1 4 7 60 -1 -1 0.000 0 0 -1 0 0 2
|
||||
4500 600 4500 6600
|
||||
2 1 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 2
|
||||
4800 600 4800 6600
|
||||
2 1 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 2
|
||||
2400 600 2400 6600
|
||||
2 2 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 5
|
||||
0 0 7200 0 7200 7200 0 7200 0 0
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1200 2400 3600 2400 3600 4800 1200 4800 1200 2400
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3600 2400 6000 2400 6000 4800 3600 4800 3600 2400
|
||||
4 1 0 50 -1 14 18 0.0000 4 135 165 1050 3525 a\001
|
||||
4 1 0 50 -1 14 18 0.0000 4 180 165 6150 3525 b\001
|
||||
4 1 4 50 -1 14 18 0.0000 4 135 165 2850 1125 c\001
|
||||
4 1 0 50 -1 14 24 0.0000 4 240 225 300 375 1\001
|
||||
4 0 0 50 -1 14 24 0.0000 4 240 2250 675 375 Free Track\001
|
After Width: | Height: | Size: 2.9 KiB |
|
@ -0,0 +1,124 @@
|
|||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
60.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 8925 825 9375 1275
|
||||
2 2 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
9000 900 9300 900 9300 1200 9000 1200 9000 900
|
||||
4 1 4 50 -1 14 18 0.0000 4 135 165 9150 1125 c\001
|
||||
-6
|
||||
6 825 3525 1275 3975
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
900 3600 1200 3600 1200 3900 900 3900 900 3600
|
||||
4 1 0 50 -1 14 18 0.0000 4 135 165 1050 3825 a\001
|
||||
-6
|
||||
6 5925 3525 6375 3975
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6000 3600 6300 3600 6300 3900 6000 3900 6000 3600
|
||||
4 1 0 50 -1 14 18 0.0000 4 180 165 6150 3825 b\001
|
||||
-6
|
||||
6 8025 3525 8475 3975
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8100 3600 8400 3600 8400 3900 8100 3900 8100 3600
|
||||
4 1 0 50 -1 14 18 0.0000 4 135 165 8250 3825 a\001
|
||||
-6
|
||||
6 13125 3525 13575 3975
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
13200 3600 13500 3600 13500 3900 13200 3900 13200 3600
|
||||
4 1 0 50 -1 14 18 0.0000 4 180 165 13350 3825 b\001
|
||||
-6
|
||||
6 1725 825 2175 1275
|
||||
2 2 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1800 900 2100 900 2100 1200 1800 1200 1800 900
|
||||
4 1 4 50 -1 14 18 0.0000 4 135 165 1950 1125 c\001
|
||||
-6
|
||||
6 4425 2475 5175 2925
|
||||
1 4 0 2 0 7 45 -1 20 0.000 1 0.0000 4800 2700 75 75 4725 2700 4875 2700
|
||||
2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
4500 2550 5100 2850
|
||||
2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5100 2550 4500 2850
|
||||
-6
|
||||
1 4 0 2 0 7 45 -1 20 0.000 1 0.0000 2400 4800 75 75 2325 4800 2475 4800
|
||||
2 1 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7800 3600 13800 3600
|
||||
2 1 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 2
|
||||
600 3600 6600 3600
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
900 3600 2400 3600 2400 6300
|
||||
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 4800 1500 4800
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
12600 600 12600 6600
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
12300 600 12300 6600
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
9300 6600 9300 600
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
5100 600 5100 6600
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
2100 600 2100 6600
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
4800 600 4800 6600
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
2400 600 2400 6600
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
0 0 525 0 525 525 0 525 0 0
|
||||
2 1 0 4 0 7 60 -1 -1 0.000 0 0 -1 0 0 2
|
||||
12000 2775 12000 900
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
9600 600 9600 6600
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
12000 600 12000 6600
|
||||
2 2 0 2 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
0 0 14400 0 14400 7800 0 7800 0 0
|
||||
2 2 0 2 0 7 45 -1 -1 0.000 0 0 -1 0 0 5
|
||||
525 0 3525 0 3525 525 525 525 525 0
|
||||
2 1 1 4 0 7 50 -1 -1 10.000 0 0 -1 0 0 3
|
||||
12525 3600 12525 2775 12000 2775
|
||||
2 1 1 4 0 7 50 -1 -1 10.000 0 0 -1 0 0 2
|
||||
9525 3600 9525 6300
|
||||
2 1 0 4 0 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
8100 3600 9525 3600
|
||||
2 1 0 4 0 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
12525 3600 13500 3600
|
||||
2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
9300 900 9300 3675
|
||||
2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
5100 3675 5100 6300
|
||||
2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
12300 3675 12300 6300
|
||||
2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
2100 900 2100 3675
|
||||
2 1 1 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
2100 3675 5100 3675
|
||||
2 1 1 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
9300 3675 12300 3675
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
6300 3600 4800 3600
|
||||
2 1 0 4 0 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
4800 3600 4800 900
|
||||
2 1 0 4 0 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
4725 900 4725 3600
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8400 2400 10800 2400 10800 4800 8400 4800 8400 2400
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
10800 2400 13200 2400 13200 4800 10800 4800 10800 2400
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1200 2400 3600 2400 3600 4800 1200 4800 1200 2400
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3600 2400 6000 2400 6000 4800 3600 4800 3600 2400
|
||||
2 1 0 4 0 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
11925 900 11925 2775
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
7800 2700 13800 2700
|
||||
4 1 0 50 -1 14 24 0.0000 4 240 225 300 375 2\001
|
||||
4 0 0 45 -1 14 24 0.0000 4 315 2700 675 375 Soft Overlap\001
|
||||
4 0 0 50 -1 14 20 0.0000 4 255 5775 8400 6900 (a/vertical) is pushed to the left.\001
|
||||
4 0 0 50 -1 14 20 0.0000 4 240 3795 8400 7200 (b/vertical) is broken.\001
|
After Width: | Height: | Size: 5.8 KiB |
|
@ -0,0 +1,127 @@
|
|||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
60.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 5925 3225 6375 3675
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6000 3300 6300 3300 6300 3600 6000 3600 6000 3300
|
||||
4 1 0 50 -1 14 18 0.0000 4 180 165 6150 3525 b\001
|
||||
-6
|
||||
6 13125 3600 13575 4050
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
13200 3675 13500 3675 13500 3975 13200 3975 13200 3675
|
||||
4 1 0 50 -1 14 18 0.0000 4 180 165 13350 3900 b\001
|
||||
-6
|
||||
6 1725 825 2175 1275
|
||||
2 2 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1800 900 2100 900 2100 1200 1800 1200 1800 900
|
||||
4 1 4 50 -1 14 18 0.0000 4 135 165 1950 1125 c\001
|
||||
-6
|
||||
6 8925 825 9375 1275
|
||||
2 2 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
9000 900 9300 900 9300 1200 9000 1200 9000 900
|
||||
4 1 4 50 -1 14 18 0.0000 4 135 165 9150 1125 c\001
|
||||
-6
|
||||
6 825 3150 1275 3600
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
900 3225 1200 3225 1200 3525 900 3525 900 3225
|
||||
4 1 0 50 -1 14 18 0.0000 4 135 165 1050 3450 a\001
|
||||
-6
|
||||
6 1425 3225 1875 3975
|
||||
1 4 0 2 0 7 45 -1 20 0.000 1 0.0000 1650 3600 75 75 1575 3600 1725 3600
|
||||
2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
1500 3300 1800 3900
|
||||
2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
1500 3900 1800 3300
|
||||
-6
|
||||
6 8025 3150 8475 3600
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8100 3225 8400 3225 8400 3525 8100 3525 8100 3225
|
||||
4 1 0 50 -1 14 18 0.0000 4 135 165 8250 3450 a\001
|
||||
-6
|
||||
1 4 0 2 0 7 45 -1 20 0.000 1 0.0000 5400 3600 75 75 5325 3600 5475 3600
|
||||
2 1 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7800 3600 13800 3600
|
||||
2 1 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 2
|
||||
600 3600 6600 3600
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
6300 3600 4800 3600 4800 900
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
12300 600 12300 6600
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
9300 6600 9300 600
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
5100 600 5100 6600
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
2100 600 2100 6600
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
4800 600 4800 6600
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
2400 600 2400 6600
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
0 0 525 0 525 525 0 525 0 0
|
||||
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 3300 5400 4200
|
||||
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 3900 5400 3000
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
9600 600 9600 6600
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
9000 600 9000 6600
|
||||
2 1 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7800 4500 13500 4500
|
||||
2 2 0 2 0 7 45 -1 -1 0.000 0 0 -1 0 0 5
|
||||
525 0 3525 0 3525 525 525 525 525 0
|
||||
2 2 0 2 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
0 0 14400 0 14400 7500 0 7500 0 0
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
12000 3675 12000 900
|
||||
2 1 1 4 0 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
12000 3675 13500 3675
|
||||
2 1 0 4 0 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
8925 3600 8100 3600
|
||||
2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
2100 900 2100 3675
|
||||
2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
9300 900 9300 3750
|
||||
2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
5100 3675 5100 6300
|
||||
2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
12300 3750 12300 6300
|
||||
2 1 1 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
2100 3675 5100 3675
|
||||
2 1 1 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
9300 3750 12300 3750
|
||||
2 1 0 4 0 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
9600 4575 9600 6300
|
||||
2 1 0 4 0 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
900 3525 2400 3525
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
900 3600 2400 3600
|
||||
2 1 0 4 0 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
2400 3600 2400 6300
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
12000 600 12000 6600
|
||||
2 1 0 4 0 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
8100 3525 8925 3525
|
||||
2 1 1 4 0 7 50 -1 -1 10.000 0 0 -1 0 0 3
|
||||
8925 3600 8925 4575 9600 4575
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1200 2100 3600 2100 3600 4800 1200 4800 1200 2100
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3600 2100 6000 2100 6000 4800 3600 4800 3600 2100
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8400 2100 10800 2100 10800 4800 8400 4800 8400 2100
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
10800 2100 13200 2100 13200 4800 10800 4800 10800 2100
|
||||
4 1 0 50 -1 14 24 0.0000 4 240 225 300 375 3\001
|
||||
4 0 0 45 -1 14 24 0.0000 4 315 2700 675 375 Hard Overlap\001
|
||||
4 0 0 50 -1 14 20 0.0000 4 240 4125 8400 6900 (a/horizontal) is broken.\001
|
||||
4 0 0 50 -1 14 20 0.0000 4 255 4620 8400 7200 (b/horizontal) is dislodged.\001
|
After Width: | Height: | Size: 5.6 KiB |
|
@ -0,0 +1,108 @@
|
|||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 825 3825 1275 4275
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
900 3900 1200 3900 1200 4200 900 4200 900 3900
|
||||
4 1 0 50 -1 14 18 0.0000 4 135 165 1050 4125 a\001
|
||||
-6
|
||||
6 5925 3825 6375 4275
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6000 3900 6300 3900 6300 4200 6000 4200 6000 3900
|
||||
4 1 0 50 -1 14 18 0.0000 4 180 165 6150 4125 b\001
|
||||
-6
|
||||
6 13125 3825 13575 4275
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
13200 3900 13500 3900 13500 4200 13200 4200 13200 3900
|
||||
4 1 0 50 -1 14 18 0.0000 4 180 165 13350 4125 b\001
|
||||
-6
|
||||
6 4125 1425 4575 1875
|
||||
2 2 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4200 1500 4500 1500 4500 1800 4200 1800 4200 1500
|
||||
4 1 4 50 -1 14 18 0.0000 4 135 165 4350 1725 c\001
|
||||
-6
|
||||
6 4425 3900 4875 4650
|
||||
1 4 0 2 4 7 45 -1 20 0.000 1 0.0000 4650 4275 75 75 4575 4275 4725 4275
|
||||
2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
4500 3975 4800 4575
|
||||
2 1 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
4500 4575 4800 3975
|
||||
-6
|
||||
6 8025 3825 8475 4275
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8100 3900 8400 3900 8400 4200 8100 4200 8100 3900
|
||||
4 1 0 50 -1 14 18 0.0000 4 135 165 8250 4125 a\001
|
||||
-6
|
||||
6 11325 1425 11775 1875
|
||||
2 2 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
11400 1500 11700 1500 11700 1800 11400 1800 11400 1500
|
||||
4 1 4 50 -1 14 18 0.0000 4 135 165 11550 1725 c\001
|
||||
-6
|
||||
2 1 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7800 4200 13800 4200
|
||||
2 1 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 2
|
||||
600 4200 6600 4200
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
900 4200 3900 4200 3900 6900
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
6300 4200 5100 4200 5100 1500
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
13575 4200 12300 4200 12300 1500
|
||||
2 2 0 2 0 7 45 -1 -1 0.000 0 0 -1 0 0 5
|
||||
525 0 3525 0 3525 825 525 825 525 0
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
0 0 525 0 525 825 0 825 0 0
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
8100 4200 11100 4200 11100 6900
|
||||
2 2 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 5
|
||||
0 0 14400 0 14400 8100 0 8100 0 0
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1200 3000 3600 3000 3600 5400 1200 5400 1200 3000
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3600 3000 6000 3000 6000 5400 3600 5400 3600 3000
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8400 3000 10800 3000 10800 5400 8400 5400 8400 3000
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
10800 3000 13200 3000 13200 5400 10800 5400 10800 3000
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
5400 1200 5400 7200
|
||||
2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5400 4275 5400 6900
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
5100 1200 5100 7200
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
4200 1200 4200 7200
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
3900 1200 3900 7200
|
||||
2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
4200 1500 4200 4275
|
||||
2 1 1 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
4200 4275 5400 4275
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
12600 1200 12600 7200
|
||||
2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
12600 5175 12600 6900
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
11400 4500 11400 1200
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
12000 1200 12000 7200
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
11100 1200 11100 7200
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
12300 1200 12300 7200
|
||||
2 1 1 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 4
|
||||
11400 4275 11925 4275 11925 5175 12525 5175
|
||||
2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
11400 1500 11400 4275
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
7800 5100 13725 5100
|
||||
4 1 0 50 -1 14 24 0.0000 4 240 225 300 375 4\001
|
||||
4 0 0 45 -1 14 24 0.0000 4 240 2250 675 375 Self Relax\001
|
||||
4 0 0 60 -1 12 18 0.0000 4 240 1650 675 675 Local only\001
|
||||
4 0 0 50 -1 14 20 0.0000 4 240 4125 8700 7800 (c/horizontal) is broken.\001
|
|
@ -0,0 +1,108 @@
|
|||
%PDF-1.4
|
||||
%Çì<C387>¢
|
||||
5 0 obj
|
||||
<</Length 6 0 R/Filter /FlateDecode>>
|
||||
stream
|
||||
xœÍUÉnÛ0½ó+xt
|
||||
D—ár-PôÒK,sqT;I+ÛˆS Ë×w8Q²#!ÒC!@zÒpö7£'YWJÖéâg»Ë•—÷ÏÂV
|
||||
’ÉÕg¡êh$Ô`¤¡Î·ÓV4Bƒ1Ò:”î3q‡RñfZÃø¢`¢g™®Ó½Ð’&Ù´Æ0îÄîƒP}@sgš,1µ/¤='jDŠSé”WŒIgF’UtˆE@˜TJÕfŽpŒÊB „ðㄈ•ÀÑ”&DMö‘Ì¥p^”rú;ta…ðàpBÔ£“ÄQ(„™¨4'j†Še€xBþæG»—×HÎ •«´\ïð¨’×) «ª<C2AB>oë½X|9¶›NÝï«õ7ñi-nDD&ç
|
||||
¥Ò"UÏÅ9/ñ¥mz€X9,yÚ™WN½×ºq<C2BA>Ì“õ»‘õˆùÿë`*œÒ¨Šõ!öBƒHäÖáÜ‹z!îTm1”J±»¶¸+<2B>ÎÍEV¯`¶x>ú‰â<E280B0>¥GÌþGéAŒÅÝ<C385>žöãIû
¬:e«`<Öy”·D/Œ—]J‡}ȸËØÔ„É<ãæ"˜ ô~¼V½†
<0A>Jò<4A>ØÒ(—‰º†\$í´ÒÐ-<2D>¼h`<60>ЩAr^ÏlæxUQÔem½lÍˉ°uÊÑhô6Æü+ ‹å·ðö¥ÆA9g˜I„6U
>Ͼ¬ÿk¥d´sT_Wë*@~ÕNc'<27>õù½àC•JV!3冧<E280A0>@t 3#za[³“^…Ü—¸Ú´„©ÃgÍøÏc~7Ù`<60>؉œ8ÃoßÓ-?<3F>fÛíäjÛm~¥¾.W¨ß<C2A8>½Å5ò:?Ö_ÅâvÑ.Ž§Ç?ÇÃ<C387>Mw{%ŸåÝéø}{¨
|
||||
)nÄ_#1ÛÍendstream
|
||||
endobj
|
||||
6 0 obj
|
||||
676
|
||||
endobj
|
||||
4 0 obj
|
||||
<</Type/Page/MediaBox [0 0 456 831]
|
||||
/Parent 3 0 R
|
||||
/Resources<</ProcSet[/PDF /Text]
|
||||
/ExtGState 11 0 R
|
||||
/Font 12 0 R
|
||||
>>
|
||||
/Contents 5 0 R
|
||||
>>
|
||||
endobj
|
||||
3 0 obj
|
||||
<< /Type /Pages /Kids [
|
||||
4 0 R
|
||||
] /Count 1
|
||||
>>
|
||||
endobj
|
||||
1 0 obj
|
||||
<</Type /Catalog /Pages 3 0 R
|
||||
/Metadata 13 0 R
|
||||
>>
|
||||
endobj
|
||||
7 0 obj
|
||||
<</Type/ExtGState
|
||||
/OPM 1>>endobj
|
||||
11 0 obj
|
||||
<</R7
|
||||
7 0 R>>
|
||||
endobj
|
||||
12 0 obj
|
||||
<</R8
|
||||
8 0 R/R9
|
||||
9 0 R/R10
|
||||
10 0 R>>
|
||||
endobj
|
||||
8 0 obj
|
||||
<</BaseFont/Courier/Type/Font
|
||||
/Subtype/Type1>>
|
||||
endobj
|
||||
9 0 obj
|
||||
<</BaseFont/Courier-Bold/Type/Font
|
||||
/Subtype/Type1>>
|
||||
endobj
|
||||
10 0 obj
|
||||
<</BaseFont/Times-Roman/Type/Font
|
||||
/Subtype/Type1>>
|
||||
endobj
|
||||
13 0 obj
|
||||
<</Type/Metadata
|
||||
/Subtype/XML/Length 1393>>stream
|
||||
<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?>
|
||||
<?adobe-xap-filters esc="CRLF"?>
|
||||
<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='XMP toolkit 2.9.1-13, framework 1.6'>
|
||||
<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:iX='http://ns.adobe.com/iX/1.0/'>
|
||||
<rdf:Description rdf:about='78660a4e-a41d-11e9-0000-bbde8729f7a5' xmlns:pdf='http://ns.adobe.com/pdf/1.3/' pdf:Producer='GPL Ghostscript 8.60'/>
|
||||
<rdf:Description rdf:about='78660a4e-a41d-11e9-0000-bbde8729f7a5' xmlns:xap='http://ns.adobe.com/xap/1.0/' xap:ModifyDate='2009-07-08T20:50:08Z' xap:CreateDate='2009-07-08T20:50:08Z'><xap:CreatorTool>fig2dev Version 3.2 Patchlevel 4</xap:CreatorTool></rdf:Description>
|
||||
<rdf:Description rdf:about='78660a4e-a41d-11e9-0000-bbde8729f7a5' xmlns:xapMM='http://ns.adobe.com/xap/1.0/mm/' xapMM:DocumentID='78660a4e-a41d-11e9-0000-bbde8729f7a5'/>
|
||||
<rdf:Description rdf:about='78660a4e-a41d-11e9-0000-bbde8729f7a5' xmlns:dc='http://purl.org/dc/elements/1.1/' dc:format='application/pdf'><dc:title><rdf:Alt><rdf:li xml:lang='x-default'>RoutingEvent-13.fig</rdf:li></rdf:Alt></dc:title><dc:creator><rdf:Seq><rdf:li>jpc@lepka \(Jean-Paul Chaput\)</rdf:li></rdf:Seq></dc:creator></rdf:Description>
|
||||
</rdf:RDF>
|
||||
</x:xmpmeta>
|
||||
|
||||
|
||||
<?xpacket end='w'?>
|
||||
endstream
|
||||
endobj
|
||||
2 0 obj
|
||||
<</Producer(GPL Ghostscript 8.60)
|
||||
/CreationDate(D:20090708205008Z)
|
||||
/ModDate(D:20090708205008Z)
|
||||
/Title(RoutingEvent-13.fig)
|
||||
/Creator(fig2dev Version 3.2 Patchlevel 4)
|
||||
/Author(jpc@lepka \(Jean-Paul Chaput\))>>endobj
|
||||
xref
|
||||
0 14
|
||||
0000000000 65535 f
|
||||
0000000990 00000 n
|
||||
0000002842 00000 n
|
||||
0000000931 00000 n
|
||||
0000000780 00000 n
|
||||
0000000015 00000 n
|
||||
0000000761 00000 n
|
||||
0000001055 00000 n
|
||||
0000001176 00000 n
|
||||
0000001238 00000 n
|
||||
0000001305 00000 n
|
||||
0000001096 00000 n
|
||||
0000001126 00000 n
|
||||
0000001372 00000 n
|
||||
trailer
|
||||
<< /Size 14 /Root 1 0 R /Info 2 0 R
|
||||
/ID [<0EA112F20693973E4390FF82218EF626><0EA112F20693973E4390FF82218EF626>]
|
||||
>>
|
||||
startxref
|
||||
3064
|
||||
%%EOF
|
After Width: | Height: | Size: 5.1 KiB |
|
@ -0,0 +1,110 @@
|
|||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
60.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 825 3825 1275 4275
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
900 3900 1200 3900 1200 4200 900 4200 900 3900
|
||||
4 1 0 50 -1 14 18 0.0000 4 135 165 1050 4125 a\001
|
||||
-6
|
||||
6 5925 3825 6375 4275
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6000 3900 6300 3900 6300 4200 6000 4200 6000 3900
|
||||
4 1 0 50 -1 14 18 0.0000 4 180 165 6150 4125 b\001
|
||||
-6
|
||||
6 13125 3825 13575 4275
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
13200 3900 13500 3900 13500 4200 13200 4200 13200 3900
|
||||
4 1 0 50 -1 14 18 0.0000 4 180 165 13350 4125 b\001
|
||||
-6
|
||||
6 8025 3825 8475 4275
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8100 3900 8400 3900 8400 4200 8100 4200 8100 3900
|
||||
4 1 0 50 -1 14 18 0.0000 4 135 165 8250 4125 a\001
|
||||
-6
|
||||
6 1725 1425 2175 1875
|
||||
2 2 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1800 1500 2100 1500 2100 1800 1800 1800 1800 1500
|
||||
4 1 4 50 -1 14 18 0.0000 4 135 165 1950 1725 c\001
|
||||
-6
|
||||
6 8925 1425 9375 1875
|
||||
2 2 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
9000 1500 9300 1500 9300 1800 9000 1800 9000 1500
|
||||
4 1 4 50 -1 14 18 0.0000 4 135 165 9150 1725 c\001
|
||||
-6
|
||||
2 1 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7800 4200 13800 4200
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
900 4200 3900 4200 3900 6900
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
6300 4200 5100 4200 5100 1500
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
13575 4200 12300 4200 12300 1500
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
8100 4200 11100 4200 11100 6900
|
||||
2 2 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 5
|
||||
0 0 14400 0 14400 8100 0 8100 0 0
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1200 3000 3600 3000 3600 5400 1200 5400 1200 3000
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3600 3000 6000 3000 6000 5400 3600 5400 3600 3000
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8400 3000 10800 3000 10800 5400 8400 5400 8400 3000
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
10800 3000 13200 3000 13200 5400 10800 5400 10800 3000
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
5100 1200 5100 7200
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
11100 1200 11100 7200
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
12300 1200 12300 7200
|
||||
2 2 0 2 0 7 45 -1 -1 0.000 0 0 -1 0 0 5
|
||||
525 0 4500 0 4500 600 525 600 525 0
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
0 0 525 0 525 600 0 600 0 0
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
3900 1200 3900 7200
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
1800 1200 1800 7200
|
||||
2 1 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 2
|
||||
600 4200 6600 4200
|
||||
2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
1800 1500 1800 4275
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
4800 1200 4800 7200
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
4200 1200 4200 7200
|
||||
2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
4800 4275 4800 6900
|
||||
2 1 1 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
1800 4275 4800 4275
|
||||
2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
4200 1500 4200 4275
|
||||
2 2 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 5
|
||||
4125 4200 4275 4200 4275 4350 4125 4350 4125 4200
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
9000 7200 9000 1200
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
11400 1200 11400 7200
|
||||
2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
11400 1500 11400 4275
|
||||
2 1 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
9000 1500 9000 3975
|
||||
2 1 0 1 4 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
12000 1200 12000 7200
|
||||
2 1 0 4 4 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
12000 4275 12000 6900
|
||||
2 1 1 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
11400 4275 12000 4275
|
||||
2 1 1 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
9000 3975 11325 3975
|
||||
2 2 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 5
|
||||
11325 3825 11475 3825 11475 4350 11325 4350 11325 3825
|
||||
4 1 0 50 -1 14 24 0.0000 4 240 225 300 375 5\001
|
||||
4 0 0 45 -1 14 24 0.0000 4 315 3600 675 375 Self Desalignate\001
|
||||
4 0 0 50 -1 14 20 0.0000 4 255 4950 8400 7800 (c/horizontal) is desalignate.\001
|
After Width: | Height: | Size: 4.9 KiB |
|
@ -0,0 +1,96 @@
|
|||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
60.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 825 3825 1275 4275
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
900 3900 1200 3900 1200 4200 900 4200 900 3900
|
||||
4 1 0 50 -1 14 18 0.0000 4 135 165 1050 4125 a\001
|
||||
-6
|
||||
6 5925 3825 6375 4275
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6000 3900 6300 3900 6300 4200 6000 4200 6000 3900
|
||||
4 1 0 50 -1 14 18 0.0000 4 180 165 6150 4125 b\001
|
||||
-6
|
||||
6 13125 3825 13575 4275
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
13200 3900 13500 3900 13500 4200 13200 4200 13200 3900
|
||||
4 1 0 50 -1 14 18 0.0000 4 180 165 13350 4125 b\001
|
||||
-6
|
||||
6 8025 3825 8475 4275
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8100 3900 8400 3900 8400 4200 8100 4200 8100 3900
|
||||
4 1 0 50 -1 14 18 0.0000 4 135 165 8250 4125 a\001
|
||||
-6
|
||||
6 1575 2325 2025 2775
|
||||
2 2 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1650 2400 1950 2400 1950 2700 1650 2700 1650 2400
|
||||
4 1 4 50 -1 14 18 0.0000 4 135 165 1800 2625 c\001
|
||||
-6
|
||||
6 8925 2325 9375 2775
|
||||
2 2 0 2 4 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
9000 2400 9300 2400 9300 2700 9000 2700 9000 2400
|
||||
4 1 4 50 -1 14 18 0.0000 4 135 165 9150 2625 c\001
|
||||
-6
|
||||
2 1 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7800 4200 13800 4200
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
900 4200 3900 4200 3900 6900
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
6300 4200 5100 4200 5100 1500
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
13575 4200 12300 4200 12300 1500
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
8100 4200 11100 4200 11100 6900
|
||||
2 2 0 2 0 7 60 -1 -1 6.000 0 0 -1 0 0 5
|
||||
0 0 14400 0 14400 8100 0 8100 0 0
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1200 3000 3600 3000 3600 5400 1200 5400 1200 3000
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3600 3000 6000 3000 6000 5400 3600 5400 3600 3000
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8400 3000 10800 3000 10800 5400 8400 5400 8400 3000
|
||||
2 2 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 5
|
||||
10800 3000 13200 3000 13200 5400 10800 5400 10800 3000
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
5100 1200 5100 7200
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
11100 1200 11100 7200
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
12300 1200 12300 7200
|
||||
2 2 0 2 0 7 45 -1 -1 0.000 0 0 -1 0 0 5
|
||||
525 0 4500 0 4500 600 525 600 525 0
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
0 0 525 0 525 600 0 600 0 0
|
||||
2 1 0 1 0 7 60 -1 20 0.000 0 0 -1 0 0 2
|
||||
3900 1200 3900 7200
|
||||
2 1 0 1 0 7 60 -1 -1 0.000 0 0 -1 0 0 2
|
||||
600 4200 6600 4200
|
||||
2 1 1 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
1800 4275 4800 4275
|
||||
2 2 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 5
|
||||
4725 4125 4875 4125 4875 4875 4725 4875 4725 4125
|
||||
2 2 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 5
|
||||
1725 3225 1875 3225 1875 4350 1725 4350 1725 3225
|
||||
2 2 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 5
|
||||
8925 3225 9075 3225 9075 4350 8925 4350 8925 3225
|
||||
2 2 0 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 5
|
||||
11925 4125 12075 4125 12075 4875 11925 4875 11925 4125
|
||||
2 1 1 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 6
|
||||
9000 3675 9525 3675 9525 4275 11325 4275 11325 4575 12000 4575
|
||||
2 1 0 1 4 7 60 -1 -1 4.000 0 0 -1 0 0 2
|
||||
9600 1200 9600 7200
|
||||
2 1 0 1 4 7 60 -1 -1 4.000 0 0 -1 0 0 2
|
||||
11400 1200 11400 7200
|
||||
2 1 0 1 4 7 60 -1 -1 4.000 0 0 -1 0 0 2
|
||||
7800 3600 13800 3600
|
||||
2 1 0 1 4 7 60 -1 -1 4.000 0 0 -1 0 0 2
|
||||
7800 4500 13800 4500
|
||||
4 1 0 50 -1 14 24 0.0000 4 240 225 300 375 6\001
|
||||
4 0 0 45 -1 14 24 0.0000 4 240 2700 675 375 Self Slacken\001
|
||||
4 0 0 45 -1 14 20 0.0000 4 240 4620 9000 7800 [c/horizontal] is slackened.\001
|
|
@ -0,0 +1,93 @@
|
|||
%PDF-1.4
|
||||
%Çì<C387>¢
|
||||
5 0 obj
|
||||
<</Length 6 0 R/Filter /FlateDecode>>
|
||||
stream
|
||||
xœ¥TMoÛ0½ëWðØ
¨+ê[×ÃÎm|+zÈòÑuuZ40`¿~$åHqëb['öƒŸø(“Ô{Ý!h¾Æçj§.®#Ü”ë<üRÂÁõWe¼µàB¶°+8ƒZ¨LËÐý\
|
||||
Rpö"Š&b" #BnÂÊ{ƒqžðÚÏÁå×ðµ¿SœÆêÈ{töˆµýü³"„F®!3L ‰6WBp
™aJˆ±¾‚kȳ(E¶±ÖÛæ1ý
d
·Ô•µ2‘ÜZ [Dؤ|×»Äo]ç5Ë”òeÇqtÑOßz¦oE!b˜*œnÉ …9”MŽ&Ñ&dC§8$-8ú)Ž§›.cÄuò±uCpm`j,äÙ:N,ã:±&bcOf¹<66><·Âó&-ùÖBÓ°=+,x|¬vpÙÓé¡Z†Î@¿¥¥çܪZG_Ÿ»€ÉA¿SgËOýõ¥WW%‹
ø"Í«ÛàY^Ô¿MÕc¶U<>9¾¥îRü¨ºËXÕ[eê`£ã&hý"
¾£è9
{Í·jù8<C3B9>Œî{¿¦¨{çgÔå¬NíÔûzºÇcïп¶€æ¹£ke<1°bÆ”ù¸h4<68>Œ'þSÜ;57ÍLòUckNnÉÈ-úžxCý›öÕr™m§},Z™IÞ$Ialò+ò¼´Ã®x±¶°–«‡Í#§<>¾$p9“sœ;ꆇ~ÎnVߟö÷¿Ÿ.‡[¸?À¡ÄmÖ]ÝÝ•ú$mFendstream
|
||||
endobj
|
||||
6 0 obj
|
||||
562
|
||||
endobj
|
||||
4 0 obj
|
||||
<</Type/Page/MediaBox [0 0 489 867]
|
||||
/Parent 3 0 R
|
||||
/Resources<</ProcSet[/PDF /Text]
|
||||
/ExtGState 9 0 R
|
||||
/Font 10 0 R
|
||||
>>
|
||||
/Contents 5 0 R
|
||||
>>
|
||||
endobj
|
||||
3 0 obj
|
||||
<< /Type /Pages /Kids [
|
||||
4 0 R
|
||||
] /Count 1
|
||||
>>
|
||||
endobj
|
||||
1 0 obj
|
||||
<</Type /Catalog /Pages 3 0 R
|
||||
/Metadata 11 0 R
|
||||
>>
|
||||
endobj
|
||||
7 0 obj
|
||||
<</Type/ExtGState
|
||||
/OPM 1>>endobj
|
||||
9 0 obj
|
||||
<</R7
|
||||
7 0 R>>
|
||||
endobj
|
||||
10 0 obj
|
||||
<</R8
|
||||
8 0 R>>
|
||||
endobj
|
||||
8 0 obj
|
||||
<</BaseFont/Courier-Bold/Type/Font
|
||||
/Subtype/Type1>>
|
||||
endobj
|
||||
11 0 obj
|
||||
<</Type/Metadata
|
||||
/Subtype/XML/Length 1393>>stream
|
||||
<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?>
|
||||
<?adobe-xap-filters esc="CRLF"?>
|
||||
<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='XMP toolkit 2.9.1-13, framework 1.6'>
|
||||
<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:iX='http://ns.adobe.com/iX/1.0/'>
|
||||
<rdf:Description rdf:about='3e5fb70f-b207-11e9-0000-2d6d30e43fd7' xmlns:pdf='http://ns.adobe.com/pdf/1.3/' pdf:Producer='GPL Ghostscript 8.60'/>
|
||||
<rdf:Description rdf:about='3e5fb70f-b207-11e9-0000-2d6d30e43fd7' xmlns:xap='http://ns.adobe.com/xap/1.0/' xap:ModifyDate='2009-07-26T13:46:18Z' xap:CreateDate='2009-07-26T13:46:18Z'><xap:CreatorTool>fig2dev Version 3.2 Patchlevel 4</xap:CreatorTool></rdf:Description>
|
||||
<rdf:Description rdf:about='3e5fb70f-b207-11e9-0000-2d6d30e43fd7' xmlns:xapMM='http://ns.adobe.com/xap/1.0/mm/' xapMM:DocumentID='3e5fb70f-b207-11e9-0000-2d6d30e43fd7'/>
|
||||
<rdf:Description rdf:about='3e5fb70f-b207-11e9-0000-2d6d30e43fd7' xmlns:dc='http://purl.org/dc/elements/1.1/' dc:format='application/pdf'><dc:title><rdf:Alt><rdf:li xml:lang='x-default'>RoutingEvent-15.fig</rdf:li></rdf:Alt></dc:title><dc:creator><rdf:Seq><rdf:li>jpc@lepka \(Jean-Paul Chaput\)</rdf:li></rdf:Seq></dc:creator></rdf:Description>
|
||||
</rdf:RDF>
|
||||
</x:xmpmeta>
|
||||
|
||||
|
||||
<?xpacket end='w'?>
|
||||
endstream
|
||||
endobj
|
||||
2 0 obj
|
||||
<</Producer(GPL Ghostscript 8.60)
|
||||
/CreationDate(D:20090726134618Z)
|
||||
/ModDate(D:20090726134618Z)
|
||||
/Title(RoutingEvent-15.fig)
|
||||
/Creator(fig2dev Version 3.2 Patchlevel 4)
|
||||
/Author(jpc@lepka \(Jean-Paul Chaput\))>>endobj
|
||||
xref
|
||||
0 12
|
||||
0000000000 65535 f
|
||||
0000000875 00000 n
|
||||
0000002577 00000 n
|
||||
0000000816 00000 n
|
||||
0000000666 00000 n
|
||||
0000000015 00000 n
|
||||
0000000647 00000 n
|
||||
0000000940 00000 n
|
||||
0000001040 00000 n
|
||||
0000000981 00000 n
|
||||
0000001010 00000 n
|
||||
0000001107 00000 n
|
||||
trailer
|
||||
<< /Size 12 /Root 1 0 R /Info 2 0 R
|
||||
/ID [<78D2C3B92E435ABC4DEAFD28D69952A8><78D2C3B92E435ABC4DEAFD28D69952A8>]
|
||||
>>
|
||||
startxref
|
||||
2799
|
||||
%%EOF
|
After Width: | Height: | Size: 5.0 KiB |
|
@ -0,0 +1,82 @@
|
|||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 2100 7350 2325 8100
|
||||
4 1 4 50 -1 15 18 1.5708 4 165 660 2325 7725 Free\001
|
||||
-6
|
||||
6 7500 3600 7725 4350
|
||||
4 1 4 50 -1 15 18 1.5708 4 165 660 7725 3975 Free\001
|
||||
-6
|
||||
2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
8400 6600 1125 6600
|
||||
2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
6900 5400 1125 5400
|
||||
2 1 0 2 4 7 60 -1 -1 0.000 0 0 -1 0 0 2
|
||||
1800 1575 1800 9900
|
||||
2 1 1 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
1800 1575 1800 5400
|
||||
2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
3 1 1.00 60.00 120.00
|
||||
1200 4200 1200 5400
|
||||
2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
1200 5400 1200 6600
|
||||
2 1 0 1 4 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
3 1 1.00 60.00 120.00
|
||||
1200 8400 1200 6600
|
||||
2 4 0 2 0 7 45 -1 -1 6.000 0 0 7 0 0 5
|
||||
3150 6150 3150 5850 1650 5850 1650 6150 3150 6150
|
||||
2 4 0 2 0 7 45 -1 -1 6.000 0 0 7 0 0 5
|
||||
8325 6150 8325 5850 6750 5850 6750 6150 8325 6150
|
||||
2 2 1 0 4 7 60 -1 45 2.000 0 0 -1 0 0 5
|
||||
2100 1500 2400 1500 2400 5400 2100 5400 2100 1500
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
8100 6000 8100 2700
|
||||
2 1 0 2 4 7 60 -1 -1 0.000 0 0 -1 0 0 2
|
||||
8100 1500 8100 9900
|
||||
2 1 1 4 4 7 60 -1 -1 10.000 0 0 -1 0 0 2
|
||||
8100 6675 8100 9900
|
||||
2 1 0 4 4 7 50 -1 -1 10.000 0 0 -1 0 0 4
|
||||
1650 5325 1650 5400 1950 5400 1950 5325
|
||||
2 1 0 4 4 7 50 -1 -1 10.000 0 0 -1 0 0 4
|
||||
7950 6675 7950 6600 8250 6600 8250 6675
|
||||
2 2 0 0 7 4 60 -1 38 2.000 0 0 -1 0 0 5
|
||||
2100 5400 2400 5400 2400 9900 2100 9900 2100 5400
|
||||
2 2 0 0 7 4 60 -1 38 2.000 0 0 -1 0 0 5
|
||||
7500 1500 7800 1500 7800 6600 7500 6600 7500 1500
|
||||
2 2 1 0 4 7 60 -1 45 2.000 0 0 -1 0 0 5
|
||||
7500 6600 7800 6600 7800 9900 7500 9900 7500 6600
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
3000 6000 6900 6000
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
3000 4500 6900 4500
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
3000 6900 6900 6900
|
||||
2 2 0 0 0 7 60 -1 15 0.000 0 0 -1 0 0 5
|
||||
3000 4500 6900 4500 6900 6900 3000 6900 3000 4500
|
||||
2 2 0 0 0 7 55 -1 10 0.000 0 0 -1 0 0 5
|
||||
3000 5100 6900 5100 6900 6300 3000 6300 3000 5100
|
||||
2 1 0 4 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
1800 9300 1800 6000
|
||||
2 2 0 4 0 7 50 -1 -1 10.000 0 0 -1 0 0 5
|
||||
2925 5925 3075 5925 3075 6075 2925 6075 2925 5925
|
||||
2 2 0 4 0 7 50 -1 -1 10.000 0 0 -1 0 0 5
|
||||
1725 5925 1875 5925 1875 6075 1725 6075 1725 5925
|
||||
2 2 0 4 0 7 50 -1 -1 10.000 0 0 -1 0 0 5
|
||||
1725 9225 1875 9225 1875 9375 1725 9375 1725 9225
|
||||
2 2 0 4 0 7 50 -1 -1 10.000 0 0 -1 0 0 5
|
||||
6825 5925 6975 5925 6975 6075 6825 6075 6825 5925
|
||||
2 2 0 4 0 7 50 -1 -1 10.000 0 0 -1 0 0 5
|
||||
8025 5925 8175 5925 8175 6075 8025 6075 8025 5925
|
||||
2 2 0 4 0 7 50 -1 -1 10.000 0 0 -1 0 0 5
|
||||
8025 2625 8175 2625 8175 2775 8025 2775 8025 2625
|
||||
4 1 4 50 -1 14 12 1.5708 4 180 1470 1125 7575 _perpandicular\001
|
||||
4 1 0 45 -1 14 14 0.0000 4 135 270 7500 6075 AC\001
|
||||
4 1 0 45 -1 14 14 0.0000 4 135 270 2400 6075 AC\001
|
||||
4 1 4 45 -1 14 18 1.5708 4 180 825 1725 1950 Track\001
|
||||
4 1 4 45 -1 14 18 1.5708 4 180 825 8025 1950 Track\001
|
After Width: | Height: | Size: 7.6 KiB |
|
@ -0,0 +1,98 @@
|
|||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Inches
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 1125 1425 1875 2175
|
||||
2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
1200 1500 1800 1500 1800 2100 1200 2100 1200 1500
|
||||
4 1 0 50 -1 14 18 0.0000 4 165 330 1500 1875 RE\001
|
||||
-6
|
||||
6 1800 1425 2550 2175
|
||||
2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
1875 1500 2475 1500 2475 2100 1875 2100 1875 1500
|
||||
4 1 0 50 -1 14 18 0.0000 4 165 330 2175 1875 RE\001
|
||||
-6
|
||||
6 2475 1425 3225 2175
|
||||
2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
2550 1500 3150 1500 3150 2100 2550 2100 2550 1500
|
||||
4 1 0 50 -1 14 18 0.0000 4 165 330 2850 1875 RE\001
|
||||
-6
|
||||
6 3150 1425 3900 2175
|
||||
2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
3225 1500 3825 1500 3825 2100 3225 2100 3225 1500
|
||||
4 1 0 50 -1 14 18 0.0000 4 165 330 3525 1875 RE\001
|
||||
-6
|
||||
6 5025 1425 5775 2175
|
||||
2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
5100 1500 5700 1500 5700 2100 5100 2100 5100 1500
|
||||
4 1 0 50 -1 14 18 0.0000 4 165 330 5400 1875 RE\001
|
||||
-6
|
||||
6 5700 1425 6450 2175
|
||||
2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
5775 1500 6375 1500 6375 2100 5775 2100 5775 1500
|
||||
4 1 0 50 -1 14 18 0.0000 4 165 330 6075 1875 RE\001
|
||||
-6
|
||||
6 6375 1425 7125 2175
|
||||
2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
6450 1500 7050 1500 7050 2100 6450 2100 6450 1500
|
||||
4 1 0 50 -1 14 18 0.0000 4 165 330 6750 1875 RE\001
|
||||
-6
|
||||
6 7050 1425 7800 2175
|
||||
2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
7125 1500 7725 1500 7725 2100 7125 2100 7125 1500
|
||||
4 1 0 50 -1 14 18 0.0000 4 165 330 7425 1875 RE\001
|
||||
-6
|
||||
6 7725 1425 8475 2175
|
||||
2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
7800 1500 8400 1500 8400 2100 7800 2100 7800 1500
|
||||
4 1 0 50 -1 14 18 0.0000 4 165 330 8100 1875 RE\001
|
||||
-6
|
||||
6 8400 1425 9150 2175
|
||||
2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
8475 1500 9075 1500 9075 2100 8475 2100 8475 1500
|
||||
4 1 0 50 -1 14 18 0.0000 4 165 330 8775 1875 RE\001
|
||||
-6
|
||||
6 9075 1425 9825 2175
|
||||
2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
9150 1500 9750 1500 9750 2100 9150 2100 9150 1500
|
||||
4 1 0 50 -1 14 18 0.0000 4 165 330 9450 1875 RE\001
|
||||
-6
|
||||
2 1 0 2 0 7 50 -1 -1 6.000 0 0 -1 1 0 2
|
||||
3 1 2.00 120.00 240.00
|
||||
5400 2100 5400 3900
|
||||
2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
4425 3900 6375 3900 6375 4800 4425 4800 4425 3900
|
||||
2 1 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 7
|
||||
975 150 1125 0 2325 0 2475 -150 2625 0 3825 0
|
||||
3975 150
|
||||
2 1 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 7
|
||||
4950 150 5100 0 7200 0 7350 -150 7500 0 9600 0
|
||||
9750 150
|
||||
2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
300 -900 10500 -900 10500 5100 300 5100 300 -900
|
||||
3 0 0 2 4 7 50 -1 -1 6.000 0 1 0 4
|
||||
3 1 2.00 120.00 240.00
|
||||
4425 4650 3300 4650 2100 3600 2100 2100
|
||||
0.000 1.000 1.000 0.000
|
||||
3 0 0 2 4 7 50 -1 -1 6.000 0 1 0 4
|
||||
3 1 2.00 120.00 240.00
|
||||
6393 4502 6618 4502 6768 3302 6768 2102
|
||||
0.000 1.000 1.000 0.000
|
||||
3 0 0 2 4 7 50 -1 -1 6.000 0 1 0 6
|
||||
3 1 2.00 120.00 240.00
|
||||
2100 1500 2100 1200 2700 600 5100 600 5700 1200 5700 1425
|
||||
0.000 1.000 1.000 1.000 1.000 0.000
|
||||
4 1 0 50 -1 14 18 0.0000 4 240 1485 5475 4200 process()\001
|
||||
4 1 4 50 -1 14 18 0.0000 4 240 1815 5400 4650 _setAside()\001
|
||||
4 1 4 50 -1 14 12 0.0000 4 165 1470 2475 3900 setLeftBound()\001
|
||||
4 1 4 50 -1 14 12 0.0000 4 180 1575 6750 3450 setRightBound()\001
|
||||
4 1 4 50 -1 14 12 0.0000 4 165 2625 2475 4125 Session::addRemoveEvent()\001
|
||||
4 1 0 50 -1 18 18 0.0000 4 270 900 2550 -300 history\001
|
||||
4 1 0 50 -1 18 18 0.0000 4 210 840 7350 -300 queue\001
|
||||
4 1 4 50 -1 14 12 0.0000 4 165 1575 2175 1200 setEventLevel()\001
|
||||
4 1 4 50 -1 14 12 0.0000 4 180 945 2175 975 getFork()\001
|
After Width: | Height: | Size: 7.3 KiB |
|
@ -0,0 +1,87 @@
|
|||
#FIG 3.2
|
||||
Landscape
|
||||
Center
|
||||
Metric
|
||||
Letter
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
6 495 405 4320 6120
|
||||
1 4 0 1 0 7 50 -1 -1 4.000 1 0.0000 1800 585 45 45 1755 585 1845 585
|
||||
1 4 0 1 0 7 50 -1 -1 4.000 1 0.0000 2250 585 45 45 2205 585 2295 585
|
||||
1 4 0 1 0 7 50 -1 -1 4.000 1 0.0000 2700 585 45 45 2655 585 2745 585
|
||||
1 4 0 1 0 7 50 -1 -1 4.000 1 0.0000 3150 585 45 45 3105 585 3195 585
|
||||
1 4 0 1 0 7 50 -1 -1 4.000 1 0.0000 3600 585 45 45 3555 585 3645 585
|
||||
1 4 0 1 0 7 50 -1 -1 4.000 1 0.0000 4050 585 45 45 4005 585 4095 585
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
2025 450 2025 675
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
2475 450 2475 675
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
2925 450 2925 675
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
3375 450 3375 675
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
3825 450 3825 675
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
|
||||
3 0 1.00 60.00 120.00
|
||||
3600 630 3600 1755
|
||||
2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
3375 1755 3825 1755 3825 4680 3375 4680 3375 1755
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
|
||||
3 0 1.00 60.00 120.00
|
||||
3150 630 3150 1710
|
||||
2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
2925 1710 3375 1710 3375 4635 2925 4635 2925 1710
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
|
||||
3 0 1.00 60.00 120.00
|
||||
2700 630 2700 1665
|
||||
2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
2475 1665 2925 1665 2925 4590 2475 4590 2475 1665
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
|
||||
3 0 1.00 60.00 120.00
|
||||
2250 630 2250 1620
|
||||
2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
2025 1620 2475 1620 2475 4545 2025 4545 2025 1620
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
|
||||
3 0 1.00 60.00 120.00
|
||||
1800 630 1800 1575
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
|
||||
3 0 1.00 60.00 120.00
|
||||
3375 5175 3150 4680
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
|
||||
3 0 1.00 60.00 120.00
|
||||
3375 5175 3600 4725
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1575 1575 2025 1575 2025 4500 1575 4500 1575 1575
|
||||
2 1 0 3 0 7 60 -1 10 0.000 0 0 -1 1 0 2
|
||||
3 1 2.00 120.00 240.00
|
||||
1575 5850 4275 5850
|
||||
2 1 0 3 0 7 60 -1 10 0.000 0 0 -1 0 0 2
|
||||
1575 5805 1575 5895
|
||||
2 1 0 1 0 7 50 -1 -1 4.000 0 0 -1 1 0 2
|
||||
3 0 1.00 60.00 120.00
|
||||
4050 630 4050 1800
|
||||
2 2 0 2 0 7 50 -1 -1 6.000 0 0 -1 0 0 5
|
||||
3825 1800 4275 1800 4275 4725 3825 4725 3825 1800
|
||||
2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
1575 450 4275 450 4275 675 1575 675 1575 450
|
||||
4 2 0 50 -1 14 12 0.0000 4 165 945 1440 630 _segments\001
|
||||
4 0 0 50 -1 14 12 1.5708 4 180 1260 3555 4590 TrackSegment\001
|
||||
4 0 0 50 -1 14 14 1.5708 4 180 945 3645 3105 [32,35[\001
|
||||
4 0 0 50 -1 14 12 1.5708 4 180 1260 3105 4545 TrackSegment\001
|
||||
4 0 0 50 -1 14 14 1.5708 4 180 945 3195 3060 [31,38[\001
|
||||
4 0 0 50 -1 14 12 1.5708 4 180 1260 2655 4500 TrackSegment\001
|
||||
4 0 0 50 -1 14 14 1.5708 4 180 945 2745 3015 [12,30[\001
|
||||
4 0 0 50 -1 14 12 1.5708 4 180 1260 2205 4455 TrackSegment\001
|
||||
4 0 0 50 -1 14 14 1.5708 4 180 810 2295 2970 [8,10[\001
|
||||
4 0 0 50 -1 14 12 1.5708 4 180 1260 1755 4410 TrackSegment\001
|
||||
4 0 0 50 -1 14 14 1.5708 4 180 675 1845 2925 [5,8[\001
|
||||
4 1 0 50 -1 18 12 0.0000 4 135 825 3375 5400 same net\001
|
||||
4 0 0 50 -1 14 12 1.5708 4 180 1260 4005 4635 TrackSegment\001
|
||||
4 0 0 50 -1 14 14 1.5708 4 180 945 4095 3150 [40,45[\001
|
||||
4 1 0 50 -1 19 12 0.0000 4 180 1140 2925 6075 sorting order\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
|
After Width: | Height: | Size: 6.1 KiB |
|
@ -0,0 +1,150 @@
|
|||
#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
|
||||
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
|
After Width: | Height: | Size: 8.1 KiB |
|
@ -0,0 +1,165 @@
|
|||
#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
|
After Width: | Height: | Size: 7.5 KiB |
|
@ -0,0 +1,83 @@
|
|||
#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
|
After Width: | Height: | Size: 4.1 KiB |
|
@ -0,0 +1,74 @@
|
|||
#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
|
After Width: | Height: | Size: 4.0 KiB |
|
@ -0,0 +1,57 @@
|
|||
#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
|
After Width: | Height: | Size: 3.6 KiB |
|
@ -0,0 +1,51 @@
|
|||
#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
|
After Width: | Height: | Size: 3.2 KiB |
|
@ -0,0 +1,105 @@
|
|||
#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
|
After Width: | Height: | Size: 5.3 KiB |
|
@ -0,0 +1,439 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./QueryBlockages.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
||||
#include "hurricane/DataBase.h"
|
||||
#include "hurricane/Technology.h"
|
||||
#include "hurricane/BasicLayer.h"
|
||||
#include "hurricane/RegularLayer.h"
|
||||
#include "hurricane/Query.h"
|
||||
#include "kite/RoutingPlane.h"
|
||||
#include "kite/TrackBlockage.h"
|
||||
#include "kite/Track.h"
|
||||
#include "kite/KiteEngine.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace std;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::inltrace;
|
||||
using Hurricane::DbU;
|
||||
using Hurricane::Box;
|
||||
using Hurricane::Interval;
|
||||
using Hurricane::Query;
|
||||
using Hurricane::Go;
|
||||
using Hurricane::Rubber;
|
||||
using Hurricane::Layer;
|
||||
using Hurricane::BasicLayer;
|
||||
using Hurricane::RegularLayer;
|
||||
using Hurricane::Transformation;
|
||||
using namespace Kite;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "::BlockagesPlanes".
|
||||
|
||||
|
||||
class BlockagesPlanes {
|
||||
private:
|
||||
class Track {
|
||||
public:
|
||||
Track ( Kite::Track* );
|
||||
void add ( Interval );
|
||||
inline DbU::Unit getAxis () const;
|
||||
void dump ( DbU::Unit width );
|
||||
private:
|
||||
Kite::Track* _ktrack;
|
||||
list<Interval> _blockages;
|
||||
};
|
||||
private:
|
||||
class Plane {
|
||||
public:
|
||||
Plane ( RoutingPlane* );
|
||||
~Plane ();
|
||||
void merge ( Box boundingBox );
|
||||
inline unsigned int getDirection () const;
|
||||
inline const Layer* getLayer () const;
|
||||
inline DbU::Unit getHalfWireWidth () const;
|
||||
inline DbU::Unit getPitch () const;
|
||||
void dump ();
|
||||
private:
|
||||
RoutingPlane* _routingPlane;
|
||||
Interval _axisSpan;
|
||||
vector<Track*> _tracks;
|
||||
};
|
||||
public:
|
||||
static Track* createTrack ( Kite::Track* );
|
||||
public:
|
||||
BlockagesPlanes ( KiteEngine* );
|
||||
~BlockagesPlanes ();
|
||||
bool hasPlane ( const BasicLayer* );
|
||||
bool setActivePlane ( const BasicLayer* );
|
||||
inline Plane* getActivePlane () const;
|
||||
void add ( Box boundingBox );
|
||||
void dump ();
|
||||
private:
|
||||
KiteEngine* _kite;
|
||||
map<const BasicLayer*,Plane*> _planes;
|
||||
Plane* _activePlane;
|
||||
};
|
||||
|
||||
|
||||
BlockagesPlanes::Track::Track ( Kite::Track* ktrack )
|
||||
: _ktrack(ktrack)
|
||||
, _blockages()
|
||||
{ }
|
||||
|
||||
|
||||
inline DbU::Unit BlockagesPlanes::Track::getAxis () const { return _ktrack->getAxis(); }
|
||||
|
||||
|
||||
void BlockagesPlanes::Track::add ( Interval obstacle )
|
||||
{
|
||||
if ( (obstacle.getVMax() <= _ktrack->getMin())
|
||||
or (obstacle.getVMin() >= _ktrack->getMax()) ) return;
|
||||
|
||||
list<Interval>::iterator imerge = _blockages.end();
|
||||
list<Interval>::iterator iblockage = _blockages.begin();
|
||||
|
||||
while ( iblockage != _blockages.end() ) {
|
||||
if ( obstacle.getVMax() < (*iblockage).getVMin() ) break;
|
||||
|
||||
if ( obstacle.intersect(*iblockage) ) {
|
||||
if ( imerge == _blockages.end() ) {
|
||||
imerge = iblockage;
|
||||
(*imerge).merge ( obstacle );
|
||||
} else {
|
||||
(*imerge).merge ( *iblockage );
|
||||
iblockage = _blockages.erase ( iblockage );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
iblockage++;
|
||||
}
|
||||
|
||||
if ( imerge == _blockages.end() ) {
|
||||
_blockages.insert ( iblockage, obstacle );
|
||||
ltrace(190) << "| Add on " << DbU::getValueString(_ktrack->getAxis()) << " " << obstacle << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockagesPlanes::Track::dump ( DbU::Unit width )
|
||||
{
|
||||
list<Interval>::iterator iinterval = _blockages.begin();
|
||||
|
||||
if ( _ktrack->getDirection() == Constant::Horizontal ) {
|
||||
DbU::Unit ymin = _ktrack->getAxis() - width/2;
|
||||
DbU::Unit ymax = _ktrack->getAxis() + width/2;
|
||||
|
||||
for ( ; iinterval != _blockages.end() ; iinterval++ ) {
|
||||
Box bb ( (*iinterval).getVMin(), ymin, (*iinterval).getVMax(), ymax );
|
||||
TrackBlockage::create ( _ktrack, bb );
|
||||
}
|
||||
} else {
|
||||
DbU::Unit xmin = _ktrack->getAxis() - width/2;
|
||||
DbU::Unit xmax = _ktrack->getAxis() + width/2;
|
||||
|
||||
for ( ; iinterval != _blockages.end() ; iinterval++ ) {
|
||||
Box bb ( xmin, (*iinterval).getVMin(), xmax, (*iinterval).getVMax() );
|
||||
TrackBlockage::create ( _ktrack, bb );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BlockagesPlanes::Plane::Plane ( RoutingPlane* plane )
|
||||
: _routingPlane(plane)
|
||||
, _axisSpan (plane->getAxisMin(),plane->getAxisMax())
|
||||
, _tracks ()
|
||||
{
|
||||
Kite::Track* ktrack = plane->getTrackByIndex(0);
|
||||
|
||||
for ( ; ktrack != NULL ; ktrack=ktrack->getNext() ) {
|
||||
_tracks.push_back ( BlockagesPlanes::createTrack(ktrack) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BlockagesPlanes::Plane::~Plane ()
|
||||
{
|
||||
for ( size_t i=0 ; i<_tracks.size() ; i++ ) delete _tracks[i];
|
||||
}
|
||||
|
||||
|
||||
inline unsigned int BlockagesPlanes::Plane::getDirection () const { return _routingPlane->getDirection(); }
|
||||
inline const Layer* BlockagesPlanes::Plane::getLayer () const { return _routingPlane->getLayer(); }
|
||||
inline DbU::Unit BlockagesPlanes::Plane::getHalfWireWidth () const { return _routingPlane->getLayerGauge()->getHalfWireWidth(); }
|
||||
inline DbU::Unit BlockagesPlanes::Plane::getPitch () const { return _routingPlane->getLayerGauge()->getPitch(); }
|
||||
|
||||
|
||||
void BlockagesPlanes::Plane::merge ( Box boundingBox )
|
||||
{
|
||||
ltrace(190) << "| Add on plane " << _routingPlane->getLayer() << " " << boundingBox << endl;
|
||||
|
||||
DbU::Unit delta = getPitch() - getHalfWireWidth() - 1;
|
||||
|
||||
if ( getDirection() == Constant::Horizontal ) {
|
||||
boundingBox.inflate ( 0, delta, 0, delta );
|
||||
|
||||
ltrace(190) << "Track range: " << DbU::getValueString(boundingBox.getYMin())
|
||||
<< ":" << DbU::getValueString(boundingBox.getYMax()) << endl;
|
||||
for ( size_t i=0 ; (i<_tracks.size()) and (_tracks[i]->getAxis() < boundingBox.getYMax()) ; i++ ) {
|
||||
if ( _tracks[i]->getAxis() < boundingBox.getYMin() ) continue;
|
||||
|
||||
_tracks[i]->add ( Interval(boundingBox.getXMin(),boundingBox.getXMax()) );
|
||||
}
|
||||
} else {
|
||||
boundingBox.inflate ( delta, 0, delta, 0 );
|
||||
for ( size_t i=0 ; (i<_tracks.size()) and (_tracks[i]->getAxis() < boundingBox.getXMax()) ; i++ ) {
|
||||
if ( _tracks[i]->getAxis() < boundingBox.getXMin() ) continue;
|
||||
|
||||
_tracks[i]->add ( Interval(boundingBox.getYMin(),boundingBox.getYMax()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BlockagesPlanes::Plane::dump ()
|
||||
{
|
||||
for ( size_t i=0 ; i<_tracks.size() ; i++ ) _tracks[i]->dump(DbU::lambda(2.0));
|
||||
}
|
||||
|
||||
|
||||
BlockagesPlanes::Track* BlockagesPlanes::createTrack ( Kite::Track* ktrack )
|
||||
{ return new Track ( ktrack ); }
|
||||
|
||||
|
||||
BlockagesPlanes::BlockagesPlanes ( KiteEngine* kite )
|
||||
: _kite (kite)
|
||||
, _planes ()
|
||||
, _activePlane(NULL)
|
||||
{
|
||||
RoutingGauge* rg = _kite->getConfiguration()->getRoutingGauge();
|
||||
size_t gaugeDepth = rg->getDepth ();
|
||||
|
||||
for ( size_t depth=0 ; depth<gaugeDepth ; depth++ ) {
|
||||
const RegularLayer* routingLayer = dynamic_cast<const RegularLayer*>(rg->getRoutingLayer(depth));
|
||||
if ( not routingLayer ) continue;
|
||||
|
||||
const BasicLayer* blockageLayer = routingLayer->getBasicLayer()->getBlockageLayer();
|
||||
if ( not blockageLayer ) continue;
|
||||
|
||||
_planes.insert ( make_pair(blockageLayer,new Plane(_kite->getRoutingPlaneByIndex(depth))) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BlockagesPlanes::~BlockagesPlanes ()
|
||||
{
|
||||
while ( not _planes.empty() ) {
|
||||
delete _planes.begin()->second;
|
||||
_planes.erase ( _planes.begin() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool BlockagesPlanes::hasPlane ( const BasicLayer* basicLayer )
|
||||
{ return (_planes.find(basicLayer) != _planes.end()); }
|
||||
|
||||
|
||||
bool BlockagesPlanes::setActivePlane ( const BasicLayer* basicLayer )
|
||||
{
|
||||
map<const BasicLayer*,Plane*>::iterator iplane = _planes.find(basicLayer);
|
||||
if ( iplane == _planes.end() ) return false;
|
||||
|
||||
_activePlane = iplane->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline BlockagesPlanes::Plane* BlockagesPlanes::getActivePlane () const
|
||||
{ return _activePlane; }
|
||||
|
||||
|
||||
void BlockagesPlanes::add ( Box boundingBox )
|
||||
{
|
||||
if ( not _activePlane ) return;
|
||||
_activePlane->merge ( boundingBox );
|
||||
}
|
||||
|
||||
|
||||
void BlockagesPlanes::dump ()
|
||||
{
|
||||
map<const BasicLayer*,Plane*>::iterator iplane = _planes.begin();
|
||||
for ( ; iplane != _planes.end() ; iplane++ ) {
|
||||
iplane->second->dump();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "::QueryBlockages".
|
||||
|
||||
|
||||
class QueryBlockages : public Query {
|
||||
public:
|
||||
QueryBlockages ( KiteEngine* );
|
||||
virtual bool hasGoCallback () const;
|
||||
virtual void setBasicLayer ( const BasicLayer* );
|
||||
virtual void goCallback ( Go* );
|
||||
virtual void rubberCallback ( Rubber* );
|
||||
virtual void extensionGoCallback ( Go* );
|
||||
virtual void masterCellCallback ();
|
||||
void addBlockage ( const Go* go
|
||||
, const BasicLayer* basicLayer
|
||||
, const Box& area
|
||||
, const Transformation& transformation
|
||||
);
|
||||
virtual void doQuery ();
|
||||
inline void dump ();
|
||||
inline unsigned int getBlockagesCount () const;
|
||||
private:
|
||||
KiteEngine* _kite;
|
||||
BlockagesPlanes _blockagesPlanes;
|
||||
unsigned int _blockagesCount;
|
||||
};
|
||||
|
||||
|
||||
QueryBlockages::QueryBlockages ( KiteEngine* kite )
|
||||
: Query ()
|
||||
, _kite (kite)
|
||||
, _blockagesPlanes(kite)
|
||||
, _blockagesCount (0)
|
||||
{
|
||||
setCell ( kite->getCell() );
|
||||
setArea ( kite->getCell()->getBoundingBox() );
|
||||
setBasicLayer ( NULL );
|
||||
setFilter ( Query::DoTerminalCells|Query::DoComponents );
|
||||
}
|
||||
|
||||
|
||||
inline unsigned int QueryBlockages::getBlockagesCount () const
|
||||
{ return _blockagesCount; }
|
||||
|
||||
|
||||
inline void QueryBlockages::dump ()
|
||||
{ return _blockagesPlanes.dump(); }
|
||||
|
||||
|
||||
void QueryBlockages::setBasicLayer ( const BasicLayer* basicLayer )
|
||||
{
|
||||
_blockagesPlanes.setActivePlane ( basicLayer );
|
||||
Query::setBasicLayer ( basicLayer );
|
||||
}
|
||||
|
||||
|
||||
void QueryBlockages::doQuery ()
|
||||
{
|
||||
if ( not _blockagesPlanes.getActivePlane() ) return;
|
||||
Query::doQuery ();
|
||||
}
|
||||
|
||||
|
||||
void QueryBlockages::masterCellCallback ()
|
||||
{ }
|
||||
|
||||
|
||||
bool QueryBlockages::hasGoCallback () const
|
||||
{ return true; }
|
||||
|
||||
|
||||
void QueryBlockages::goCallback ( Go* go )
|
||||
{
|
||||
addBlockage ( go, getBasicLayer(), getArea(), getTransformation() );
|
||||
}
|
||||
|
||||
|
||||
void QueryBlockages::addBlockage ( const Go* go
|
||||
, const BasicLayer* basicLayer
|
||||
, const Box& area
|
||||
, const Transformation& transformation
|
||||
)
|
||||
{
|
||||
const Component* component = dynamic_cast<const Component*>(go);
|
||||
if ( component ) {
|
||||
_blockagesCount++;
|
||||
Box bb ( transformation.getBox(component->getBoundingBox(basicLayer)) );
|
||||
ltrace(190) << "Blockage: " << bb << " in " << basicLayer->getName() << endl;
|
||||
|
||||
_blockagesPlanes.add ( bb );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QueryBlockages::rubberCallback ( Rubber* )
|
||||
{ }
|
||||
|
||||
|
||||
void QueryBlockages::extensionGoCallback ( Go* )
|
||||
{ }
|
||||
|
||||
|
||||
} // End of anonymous namespace.
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using Hurricane::DataBase;
|
||||
using Hurricane::Technology;
|
||||
using Hurricane::BasicLayer;
|
||||
using Hurricane::ForEachIterator;
|
||||
|
||||
|
||||
void KiteEngine::buildBlockages ()
|
||||
{
|
||||
cmess1 << " o Building blockages." << endl;
|
||||
|
||||
if ( not _obstacleNet ) {
|
||||
_obstacleNet = getCell()->getNet("obstaclenet");
|
||||
if ( not _obstacleNet )
|
||||
_obstacleNet = Net::create ( getCell(), "obstaclenet" );
|
||||
}
|
||||
|
||||
QueryBlockages query ( this );
|
||||
Technology* technology = DataBase::getDB()->getTechnology();
|
||||
|
||||
forEach ( BasicLayer*, iLayer, technology->getBasicLayers() ) {
|
||||
if ( iLayer->getMaterial() != BasicLayer::Material::blockage ) continue;
|
||||
|
||||
cmess1 << " - Blockages in " << iLayer->getName() << " ..." << endl;
|
||||
|
||||
query.setBasicLayer ( *iLayer );
|
||||
query.doQuery ();
|
||||
}
|
||||
query.dump ();
|
||||
cmess1 << " - " << query.getBlockagesCount() << " blockages found." << endl;
|
||||
|
||||
Session::revalidate ();
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,595 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2010, 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 : "./BuildPowerRails.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
||||
#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/Query.h"
|
||||
#include "kite/RoutingPlane.h"
|
||||
#include "kite/TrackFixedSegment.h"
|
||||
#include "kite/Track.h"
|
||||
#include "kite/KiteEngine.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace std;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::inltrace;
|
||||
using Hurricane::ForEachIterator;
|
||||
using Hurricane::DbU;
|
||||
using Hurricane::Box;
|
||||
using Hurricane::Interval;
|
||||
using Hurricane::Horizontal;
|
||||
using Hurricane::Vertical;
|
||||
using Hurricane::NetExternalComponents;
|
||||
using Hurricane::Query;
|
||||
using Hurricane::Go;
|
||||
using Hurricane::Rubber;
|
||||
using Hurricane::Layer;
|
||||
using Hurricane::BasicLayer;
|
||||
using Hurricane::RegularLayer;
|
||||
using Hurricane::Transformation;
|
||||
using Hurricane::Technology;
|
||||
using Hurricane::DataBase;
|
||||
using namespace Kite;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "::PowerRailsPlanes".
|
||||
|
||||
|
||||
class PowerRailsPlanes {
|
||||
private:
|
||||
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::Type getType () const;
|
||||
void merge ( DbU::Unit source, DbU::Unit target );
|
||||
void doLayout ( const Layer*, Net* );
|
||||
private:
|
||||
Rails* _rails;
|
||||
DbU::Unit _axis;
|
||||
DbU::Unit _width;
|
||||
list<Interval> _chunks;
|
||||
};
|
||||
private:
|
||||
class RailCompare {
|
||||
public:
|
||||
bool operator() ( const Rail* lhs, const Rail* rhs );
|
||||
};
|
||||
class RailMatch : public unary_function<Rail*,bool> {
|
||||
public:
|
||||
inline RailMatch ( DbU::Unit axis, DbU::Unit width );
|
||||
inline bool operator() ( const Rail* );
|
||||
private:
|
||||
DbU::Unit _axis;
|
||||
DbU::Unit _width;
|
||||
};
|
||||
private:
|
||||
class Rails {
|
||||
public:
|
||||
Rails ( Plane*, Constant::Direction, Net::Type );
|
||||
~Rails ();
|
||||
inline Plane* getPlane ();
|
||||
inline RoutingPlane* getRoutingPlane ();
|
||||
inline Constant::Direction getDirection () const;
|
||||
inline Net::Type getType () const;
|
||||
void merge ( Point& source, Point& target, DbU::Unit width );
|
||||
void doLayout ( const Layer*, Net* );
|
||||
private:
|
||||
Plane* _plane;
|
||||
Constant::Direction _direction;
|
||||
Net::Type _type;
|
||||
vector<Rail*> _rails;
|
||||
};
|
||||
private:
|
||||
class Plane {
|
||||
public:
|
||||
Plane ( const RegularLayer*, RoutingPlane* );
|
||||
~Plane ();
|
||||
inline RoutingPlane* getRoutingPlane ();
|
||||
void merge ( Point& source, Point& target, DbU::Unit width, Net::Type );
|
||||
void doLayout ( Net* powerNet, Net* groundNet );
|
||||
private:
|
||||
const RegularLayer* _layer;
|
||||
RoutingPlane* _routingPlane;
|
||||
Rails _railsPowerHorizontal;
|
||||
Rails _railsPowerVertical;
|
||||
Rails _railsGroundHorizontal;
|
||||
Rails _railsGroundVertical;
|
||||
};
|
||||
public:
|
||||
PowerRailsPlanes ( KiteEngine* );
|
||||
~PowerRailsPlanes ();
|
||||
bool hasPlane ( const BasicLayer* );
|
||||
bool setActivePlane ( const BasicLayer* );
|
||||
inline Plane* getActivePlane () const;
|
||||
void merge ( Point& source, Point& target, DbU::Unit width, Net::Type );
|
||||
void doLayout ();
|
||||
private:
|
||||
KiteEngine* _kite;
|
||||
map<const BasicLayer*,Plane*> _planes;
|
||||
Plane* _activePlane;
|
||||
};
|
||||
|
||||
|
||||
PowerRailsPlanes::Rail::Rail ( Rails* rails, DbU::Unit axis, DbU::Unit width )
|
||||
: _rails (rails)
|
||||
, _axis (axis)
|
||||
, _width (width)
|
||||
, _chunks()
|
||||
{
|
||||
cinfo << " New rail @" << DbU::getValueString(axis)
|
||||
<< " " << getRoutingPlane()->getLayer()->getName()
|
||||
<< " " << getRails()->getType() << 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::Type PowerRailsPlanes::Rail::getType () const { return _rails->getType(); }
|
||||
|
||||
|
||||
void PowerRailsPlanes::Rail::merge ( DbU::Unit source, DbU::Unit target )
|
||||
{
|
||||
Interval chunkMerge ( source, target );
|
||||
|
||||
list<Interval>::iterator imerge = _chunks.end();
|
||||
list<Interval>::iterator ichunk = _chunks.begin();
|
||||
|
||||
while ( ichunk != _chunks.end() ) {
|
||||
if ( chunkMerge.getVMax() < (*ichunk).getVMin() ) 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 ( imerge == _chunks.end() ) {
|
||||
_chunks.insert ( ichunk, chunkMerge );
|
||||
ltrace(190) << "| Add on " << DbU::getValueString(_axis) << " " << chunkMerge << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PowerRailsPlanes::Rail::doLayout ( const Layer* layer, Net* net )
|
||||
{
|
||||
cinfo << "Doing layout of rail: " << layer->getName() << " @" << DbU::getValueString(_axis) << endl;
|
||||
|
||||
RoutingPlane* plane = getRoutingPlane();
|
||||
Segment* segment = NULL;
|
||||
DbU::Unit delta = plane->getLayerGauge()->getPitch() - plane->getLayerGauge()->getHalfWireWidth() - 1;
|
||||
unsigned int type = plane->getLayerGauge()->getType();
|
||||
|
||||
if ( getDirection() == Constant::Horizontal ) {
|
||||
list<Interval>::iterator ichunk = _chunks.begin();
|
||||
for ( ; ichunk != _chunks.end() ; ichunk++ ) {
|
||||
segment = Horizontal::create ( net, layer, _axis, _width, (*ichunk).getVMin(), (*ichunk).getVMax() );
|
||||
if ( segment )
|
||||
NetExternalComponents::setExternal ( segment );
|
||||
|
||||
if ( type == Constant::PinOnly ) continue;
|
||||
|
||||
DbU::Unit axisMin = _axis - _width/2 - delta;
|
||||
DbU::Unit axisMax = _axis + _width/2 + delta;
|
||||
|
||||
Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior );
|
||||
for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) {
|
||||
TrackFixedSegment::create ( track, segment );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
list<Interval>::iterator ichunk = _chunks.begin();
|
||||
for ( ; ichunk != _chunks.end() ; ichunk++ ) {
|
||||
segment = Vertical::create ( net, layer, _axis, _width, (*ichunk).getVMin(), (*ichunk).getVMax() );
|
||||
if ( segment )
|
||||
NetExternalComponents::setExternal ( segment );
|
||||
|
||||
if ( type == Constant::PinOnly ) continue;
|
||||
|
||||
DbU::Unit axisMin = _axis - _width/2 - delta;
|
||||
DbU::Unit axisMax = _axis + _width/2 + delta;
|
||||
|
||||
Track* track = plane->getTrackByPosition ( axisMin, Constant::Superior );
|
||||
for ( ; track and (track->getAxis() <= axisMax) ; track = track->getNext() ) {
|
||||
TrackFixedSegment::create ( track, segment );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline bool PowerRailsPlanes::RailCompare::operator() ( const Rail* lhs, const Rail* rhs )
|
||||
{
|
||||
if ( lhs->getAxis () < rhs->getAxis () ) return true;
|
||||
if ( lhs->getWidth() < rhs->getWidth() ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
inline PowerRailsPlanes::RailMatch::RailMatch ( DbU::Unit axis, DbU::Unit width )
|
||||
: _axis(axis)
|
||||
, _width(width)
|
||||
{ }
|
||||
|
||||
|
||||
inline bool PowerRailsPlanes::RailMatch::operator() ( const Rail* rail )
|
||||
{ return (rail->getAxis() == _axis) and (rail->getWidth() == _width); }
|
||||
|
||||
|
||||
PowerRailsPlanes::Rails::Rails ( PowerRailsPlanes::Plane* plane, Constant::Direction direction, Net::Type type )
|
||||
: _plane (plane)
|
||||
, _direction(direction)
|
||||
, _type (type)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
PowerRailsPlanes::Rails::~Rails ()
|
||||
{
|
||||
while ( not _rails.empty() ) {
|
||||
delete (*_rails.begin());
|
||||
_rails.erase ( _rails.begin() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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::Type PowerRailsPlanes::Rails::getType () const { return _type; }
|
||||
|
||||
|
||||
void PowerRailsPlanes::Rails::merge ( Point& source, Point& target, DbU::Unit width )
|
||||
{
|
||||
DbU::Unit axis = (_direction == Constant::Horizontal) ? source.getY() : source.getX();
|
||||
vector<Rail*>::iterator irail = find_if ( _rails.begin(), _rails.end(), RailMatch(axis,width) );
|
||||
|
||||
Rail* rail = NULL;
|
||||
if ( irail == _rails.end() ) {
|
||||
rail = new Rail(this,axis,width);
|
||||
_rails.push_back ( rail );
|
||||
sort ( _rails.begin(), _rails.end(), RailCompare() );
|
||||
} else {
|
||||
rail = *irail;
|
||||
}
|
||||
|
||||
if ( _direction == Constant::Horizontal )
|
||||
rail->merge ( source.getX(), target.getX() );
|
||||
else
|
||||
rail->merge ( source.getY(), target.getY() );
|
||||
}
|
||||
|
||||
|
||||
void PowerRailsPlanes::Rails::doLayout ( const Layer* layer, Net* net )
|
||||
{
|
||||
cinfo << "Doing layout of plane: " << layer->getName() << " " << net->getName() << endl;
|
||||
|
||||
for ( size_t irail=0 ; irail<_rails.size() ; irail++ )
|
||||
_rails[irail]->doLayout ( layer, net );
|
||||
}
|
||||
|
||||
|
||||
PowerRailsPlanes::Plane::Plane ( const RegularLayer* layer, RoutingPlane* routingPlane )
|
||||
: _layer (layer)
|
||||
, _routingPlane (routingPlane)
|
||||
, _railsPowerHorizontal (this,Constant::Horizontal,Net::Type::POWER)
|
||||
, _railsPowerVertical (this,Constant::Vertical ,Net::Type::POWER)
|
||||
, _railsGroundHorizontal(this,Constant::Horizontal,Net::Type::GROUND)
|
||||
, _railsGroundVertical (this,Constant::Vertical ,Net::Type::GROUND)
|
||||
{
|
||||
cinfo << "New Plane " << _layer->getName() << " " << _routingPlane << endl;
|
||||
}
|
||||
|
||||
|
||||
PowerRailsPlanes::Plane::~Plane ()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
inline RoutingPlane* PowerRailsPlanes::Plane::getRoutingPlane () { return _routingPlane; }
|
||||
|
||||
|
||||
void PowerRailsPlanes::Plane::merge ( Point& source, Point& target, DbU::Unit width, Net::Type type )
|
||||
{
|
||||
if ( source.getY() == target.getY() ) {
|
||||
switch ( type ) {
|
||||
case Net::Type::POWER: _railsPowerHorizontal .merge(source,target,width); break;
|
||||
case Net::Type::GROUND: _railsGroundHorizontal.merge(source,target,width); break;
|
||||
default: break;
|
||||
}
|
||||
} else {
|
||||
switch ( type ) {
|
||||
case Net::Type::POWER: _railsPowerVertical .merge(source,target,width); break;
|
||||
case Net::Type::GROUND: _railsGroundVertical.merge(source,target,width); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PowerRailsPlanes::Plane::doLayout ( Net* powerNet, Net* groundNet )
|
||||
{
|
||||
_railsPowerHorizontal .doLayout ( _layer, powerNet );
|
||||
_railsPowerVertical .doLayout ( _layer, powerNet );
|
||||
_railsGroundHorizontal.doLayout ( _layer, groundNet );
|
||||
_railsGroundVertical .doLayout ( _layer, groundNet );
|
||||
}
|
||||
|
||||
|
||||
PowerRailsPlanes::PowerRailsPlanes ( KiteEngine* kite )
|
||||
: _kite (kite)
|
||||
, _planes ()
|
||||
, _activePlane(NULL)
|
||||
{
|
||||
Technology* technology = DataBase::getDB()->getTechnology();
|
||||
RoutingGauge* rg = _kite->getConfiguration()->getRoutingGauge();
|
||||
|
||||
forEach ( Layer*, iLayer, technology->getLayers() ) {
|
||||
RegularLayer* regular = dynamic_cast<RegularLayer*>(*iLayer);
|
||||
if ( not regular
|
||||
or (regular->getBasicLayer()->getMaterial() != BasicLayer::Material::metal) ) continue;
|
||||
|
||||
RoutingLayerGauge* lg = rg->getLayerGauge(regular);
|
||||
if ( not lg ) continue;
|
||||
|
||||
cinfo << "Gauge: [" << lg->getDepth() << "] " << lg << endl;
|
||||
|
||||
RoutingPlane* rp = _kite->getRoutingPlaneByIndex(lg->getDepth());
|
||||
cinfo << "Plane:" << rp << endl;
|
||||
|
||||
_planes.insert ( make_pair(regular->getBasicLayer(),new Plane(regular,rp)) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PowerRailsPlanes::~PowerRailsPlanes ()
|
||||
{
|
||||
while ( not _planes.empty() ) {
|
||||
delete _planes.begin()->second;
|
||||
_planes.erase ( _planes.begin() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool PowerRailsPlanes::hasPlane ( const BasicLayer* layer )
|
||||
{ return (_planes.find(layer) != _planes.end()); }
|
||||
|
||||
|
||||
bool PowerRailsPlanes::setActivePlane ( const BasicLayer* layer )
|
||||
{
|
||||
map<const BasicLayer*,Plane*>::iterator iplane = _planes.find(layer);
|
||||
if ( iplane == _planes.end() ) return false;
|
||||
|
||||
_activePlane = iplane->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline PowerRailsPlanes::Plane* PowerRailsPlanes::getActivePlane () const
|
||||
{ return _activePlane; }
|
||||
|
||||
|
||||
void PowerRailsPlanes::merge ( Point& source, Point& target, DbU::Unit width, Net::Type type )
|
||||
{
|
||||
if ( not _activePlane ) return;
|
||||
_activePlane->merge ( source, target, width, type );
|
||||
}
|
||||
|
||||
|
||||
void PowerRailsPlanes::doLayout ()
|
||||
{
|
||||
Net* powerNet = NULL;
|
||||
Net* groundNet = NULL;
|
||||
|
||||
forEach ( Net*, inet, _kite->getCell()->getNets() ) {
|
||||
if ( not powerNet and (inet->getType() == Net::Type::POWER)) powerNet = *inet;
|
||||
if ( not groundNet and (inet->getType() == Net::Type::GROUND)) groundNet = *inet;
|
||||
if ( powerNet and groundNet ) break;
|
||||
}
|
||||
|
||||
cinfo << "Doing power/ground layout " << powerNet->getName()
|
||||
<< "/" << groundNet->getName() << endl;
|
||||
|
||||
map<const BasicLayer*,Plane*>::iterator iplane = _planes.begin();
|
||||
for ( ; iplane != _planes.end() ; iplane++ )
|
||||
iplane->second->doLayout ( powerNet, groundNet );
|
||||
}
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "::QueryPowerRails".
|
||||
|
||||
|
||||
class QueryPowerRails : public Query {
|
||||
public:
|
||||
QueryPowerRails ( KiteEngine* );
|
||||
virtual bool hasGoCallback () const;
|
||||
virtual void setBasicLayer ( const BasicLayer* );
|
||||
virtual void goCallback ( Go* );
|
||||
virtual void rubberCallback ( Rubber* );
|
||||
virtual void extensionGoCallback ( Go* );
|
||||
virtual void masterCellCallback ();
|
||||
void addToPowerRail ( const Go* go
|
||||
, const BasicLayer* basicLayer
|
||||
, const Box& area
|
||||
, const Transformation& transformation
|
||||
);
|
||||
virtual void doQuery ();
|
||||
inline void doLayout ();
|
||||
inline unsigned int getGoMatchCount () const;
|
||||
private:
|
||||
KiteEngine* _kite;
|
||||
PowerRailsPlanes _powerRailsPlanes;
|
||||
unsigned int _goMatchCount;
|
||||
};
|
||||
|
||||
|
||||
QueryPowerRails::QueryPowerRails ( KiteEngine* kite )
|
||||
: Query ()
|
||||
, _kite (kite)
|
||||
, _powerRailsPlanes(kite)
|
||||
, _goMatchCount (0)
|
||||
{
|
||||
setCell ( kite->getCell() );
|
||||
setArea ( kite->getCell()->getBoundingBox() );
|
||||
setBasicLayer ( NULL );
|
||||
setFilter ( Query::DoTerminalCells|Query::DoComponents );
|
||||
}
|
||||
|
||||
|
||||
inline unsigned int QueryPowerRails::getGoMatchCount () const
|
||||
{ return _goMatchCount; }
|
||||
|
||||
|
||||
inline void QueryPowerRails::doLayout ()
|
||||
{ return _powerRailsPlanes.doLayout(); }
|
||||
|
||||
|
||||
void QueryPowerRails::setBasicLayer ( const BasicLayer* basicLayer )
|
||||
{
|
||||
_powerRailsPlanes.setActivePlane ( basicLayer );
|
||||
Query::setBasicLayer ( basicLayer );
|
||||
}
|
||||
|
||||
|
||||
void QueryPowerRails::doQuery ()
|
||||
{
|
||||
if ( not _powerRailsPlanes.getActivePlane() ) return;
|
||||
Query::doQuery ();
|
||||
}
|
||||
|
||||
|
||||
void QueryPowerRails::masterCellCallback ()
|
||||
{ }
|
||||
|
||||
|
||||
bool QueryPowerRails::hasGoCallback () const
|
||||
{ return true; }
|
||||
|
||||
|
||||
void QueryPowerRails::goCallback ( Go* go )
|
||||
{
|
||||
addToPowerRail ( go, getBasicLayer(), getArea(), getTransformation() );
|
||||
}
|
||||
|
||||
|
||||
void QueryPowerRails::addToPowerRail ( const Go* go
|
||||
, const BasicLayer* basicLayer
|
||||
, const Box& area
|
||||
, const Transformation& transformation
|
||||
)
|
||||
{
|
||||
const Component* component = dynamic_cast<const Component*>(go);
|
||||
if ( component ) {
|
||||
Net::Type netType = component->getNet()->getType();
|
||||
if ( (netType != Net::Type::POWER) and (netType != Net::Type::GROUND) ) return;
|
||||
|
||||
const Segment* segment = dynamic_cast<const Segment*>(component);
|
||||
if ( not segment ) return;
|
||||
|
||||
_goMatchCount++;
|
||||
cinfo << " Merging PowerRail element: " << segment << endl;
|
||||
|
||||
Point source = segment->getSourcePosition();
|
||||
Point target = segment->getTargetPosition();
|
||||
|
||||
transformation.applyOn ( source );
|
||||
transformation.applyOn ( target );
|
||||
|
||||
_powerRailsPlanes.merge ( source, target, segment->getWidth(), netType );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QueryPowerRails::rubberCallback ( Rubber* )
|
||||
{ }
|
||||
|
||||
|
||||
void QueryPowerRails::extensionGoCallback ( Go* )
|
||||
{ }
|
||||
|
||||
|
||||
} // End of anonymous namespace.
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using Hurricane::DataBase;
|
||||
using Hurricane::Technology;
|
||||
using Hurricane::BasicLayer;
|
||||
using Hurricane::ForEachIterator;
|
||||
|
||||
|
||||
void KiteEngine::buildPowerRails ()
|
||||
{
|
||||
cmess1 << " o Building power rails." << endl;
|
||||
|
||||
QueryPowerRails query ( this );
|
||||
Technology* technology = DataBase::getDB()->getTechnology();
|
||||
|
||||
forEach ( BasicLayer*, iLayer, technology->getBasicLayers() ) {
|
||||
if ( iLayer->getMaterial() != BasicLayer::Material::metal ) continue;
|
||||
|
||||
cmess1 << " - PowerRails in " << iLayer->getName() << " ..." << endl;
|
||||
|
||||
query.setBasicLayer ( *iLayer );
|
||||
query.doQuery ();
|
||||
}
|
||||
query.doLayout ();
|
||||
cmess1 << " - " << query.getGoMatchCount() << " power rails elements found." << endl;
|
||||
|
||||
Session::revalidate ();
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,95 @@
|
|||
|
||||
include ( ${QT_USE_FILE} )
|
||||
|
||||
include_directories ( ${Boost_INCLUDE_DIRS}
|
||||
${KITE_SOURCE_DIR}/src
|
||||
${HURRICANE_INCLUDE_DIR}
|
||||
${CORIOLIS_INCLUDE_DIR}
|
||||
)
|
||||
set ( includes kite/TrackSegmentCost.h
|
||||
kite/TrackCost.h
|
||||
kite/DataNegociate.h
|
||||
kite/TrackElement.h kite/TrackElements.h
|
||||
kite/TrackSegment.h
|
||||
kite/TrackBlockage.h
|
||||
kite/TrackFixedSegment.h
|
||||
kite/TrackMarker.h
|
||||
kite/Track.h
|
||||
kite/Tracks.h
|
||||
kite/HorizontalTrack.h
|
||||
kite/VerticalTrack.h
|
||||
kite/Session.h
|
||||
kite/RoutingEvent.h
|
||||
kite/RoutingEventQueue.h
|
||||
kite/RoutingEventHistory.h
|
||||
kite/GCell.h
|
||||
kite/GCellGrid.h
|
||||
kite/GCellRoutingSet.h
|
||||
kite/RoutingPlane.h
|
||||
kite/NegociateWindow.h
|
||||
kite/Configuration.h
|
||||
kite/KiteEngine.h
|
||||
kite/GraphicKiteEngine.h
|
||||
)
|
||||
set ( mocIncludes kite/GraphicKiteEngine.h )
|
||||
set ( cpps TrackSegmentCost.cpp
|
||||
TrackCost.cpp
|
||||
DataNegociate.cpp
|
||||
TrackElement.cpp
|
||||
TrackElements.cpp
|
||||
TrackSegment.cpp
|
||||
TrackBlockage.cpp
|
||||
TrackFixedSegment.cpp
|
||||
TrackMarker.cpp
|
||||
Track.cpp
|
||||
Tracks.cpp
|
||||
HorizontalTrack.cpp
|
||||
VerticalTrack.cpp
|
||||
Session.cpp
|
||||
RoutingEvent.cpp
|
||||
RoutingEventQueue.cpp
|
||||
RoutingEventHistory.cpp
|
||||
GCell.cpp
|
||||
GCellGrid.cpp
|
||||
GCellRoutingSet.cpp
|
||||
RoutingPlane.cpp
|
||||
BuildBlockages.cpp
|
||||
BuildPowerRails.cpp
|
||||
PreProcess.cpp
|
||||
NegociateWindow.cpp
|
||||
Configuration.cpp
|
||||
KiteEngine.cpp
|
||||
GraphicKiteEngine.cpp
|
||||
)
|
||||
set ( kitecpps KiteMain.cpp )
|
||||
qt4_wrap_cpp ( mocCpps ${mocIncludes} )
|
||||
|
||||
|
||||
add_library ( kite ${cpps} ${mocCpps} )
|
||||
target_link_libraries ( kite ${KATABATIC_LIBRARIES}
|
||||
${KNIK_LIBRARIES}
|
||||
${CORIOLIS_LIBRARIES}
|
||||
${HURRICANE_LIBRARIES}
|
||||
${HURRICANE_GRAPHICAL_LIBRARIES}
|
||||
${QT_LIBRARIES}
|
||||
${LEFDEF_LIBRARIES}
|
||||
${OA_LIBRARIES}
|
||||
)
|
||||
add_executable ( kite-text ${kitecpps} )
|
||||
target_link_libraries ( kite-text kite
|
||||
${KATABATIC_LIBRARIES}
|
||||
${KNIK_LIBRARIES}
|
||||
${CORIOLIS_LIBRARIES}
|
||||
${HURRICANE_LIBRARIES}
|
||||
${HURRICANE_GRAPHICAL_LIBRARIES}
|
||||
${QT_LIBRARIES}
|
||||
${LEFDEF_LIBRARIES}
|
||||
${OA_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
)
|
||||
install ( TARGETS kite DESTINATION /lib )
|
||||
install ( TARGETS kite-text DESTINATION /bin )
|
||||
|
||||
install ( FILES ${includes}
|
||||
${mocIncludes} DESTINATION /include/coriolis/kite )
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./Configuartion.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#include "kite/Configuration.h"
|
||||
#include "kite/KiteEngine.h"
|
||||
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::ostringstream;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::inltrace;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Technology;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Kite::Configuration".
|
||||
|
||||
|
||||
float Configuration::_defaultEdgeCapacity = 0.80;
|
||||
|
||||
|
||||
void Configuration::setDefaultEdgeCapacity ( float percent )
|
||||
{
|
||||
if ( percent > 1.0 )
|
||||
throw Error("Configuration::setDefaultEdgeCapacity(): edge capacity ratio greater than 1.0 (%.1f)."
|
||||
,percent);
|
||||
|
||||
_defaultEdgeCapacity = percent;
|
||||
}
|
||||
|
||||
|
||||
Configuration::Configuration ( Katabatic::Configuration* base )
|
||||
: Katabatic::Configuration()
|
||||
, _base (base)
|
||||
, _postEventCb ()
|
||||
, _edgeCapacityPercent(_defaultEdgeCapacity)
|
||||
, _expandStep (0.30)
|
||||
, _ripupLimits ()
|
||||
, _ripupCost (3)
|
||||
{
|
||||
_ripupLimits[BorderRipupLimit] = 26;
|
||||
_ripupLimits[StrapRipupLimit] = 16;
|
||||
_ripupLimits[LocalRipupLimit] = 7;
|
||||
_ripupLimits[GlobalRipupLimit] = 7;
|
||||
_ripupLimits[LongGlobalRipupLimit] = 7;
|
||||
}
|
||||
|
||||
|
||||
Configuration::~Configuration ()
|
||||
{ }
|
||||
|
||||
|
||||
bool Configuration::isGMetal ( const Layer* layer ) const
|
||||
{ return _base->isGMetal(layer); }
|
||||
|
||||
|
||||
size_t Configuration::getDepth () const
|
||||
{ return _base->getDepth(); }
|
||||
|
||||
|
||||
size_t Configuration::getLayerDepth ( const Layer* layer ) const
|
||||
{ return _base->getLayerDepth(layer); }
|
||||
|
||||
|
||||
RoutingGauge* Configuration::getRoutingGauge () const
|
||||
{ return _base->getRoutingGauge(); }
|
||||
|
||||
|
||||
RoutingLayerGauge* Configuration::getLayerGauge ( size_t depth ) const
|
||||
{ return _base->getLayerGauge(depth); }
|
||||
|
||||
|
||||
const Layer* Configuration::getRoutingLayer ( size_t depth ) const
|
||||
{ return _base->getRoutingLayer(depth); }
|
||||
|
||||
|
||||
Layer* Configuration::getContactLayer ( size_t depth ) const
|
||||
{ return _base->getContactLayer(depth); }
|
||||
|
||||
|
||||
DbU::Unit Configuration::getExtensionCap () const
|
||||
{ return _base->getExtensionCap(); }
|
||||
|
||||
|
||||
float Configuration::getSaturateRatio () const
|
||||
{ return _base->getSaturateRatio(); }
|
||||
|
||||
|
||||
DbU::Unit Configuration::getGlobalThreshold () const
|
||||
{ return _base->getGlobalThreshold(); }
|
||||
|
||||
|
||||
void Configuration::setSaturateRatio ( float ratio )
|
||||
{ _base->setSaturateRatio(ratio); }
|
||||
|
||||
|
||||
void Configuration::setGlobalThreshold ( DbU::Unit threshold )
|
||||
{ _base->setGlobalThreshold(threshold); }
|
||||
|
||||
|
||||
void Configuration::setRipupLimit ( unsigned int limit, unsigned int type )
|
||||
{
|
||||
if ( type >= RipupLimitsTableSize ) {
|
||||
cerr << Error("setRipupLimit(): Bad ripup limit index: %ud (> %ud)."
|
||||
,type,RipupLimitsTableSize) << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
_ripupLimits [ type ] = limit;
|
||||
}
|
||||
|
||||
|
||||
unsigned int Configuration::getRipupLimit ( unsigned int type ) const
|
||||
{
|
||||
if ( type >= RipupLimitsTableSize ) {
|
||||
cerr << Error("getRipupLimit(): Bad ripup limit index: %ud (> %ud)."
|
||||
,type,RipupLimitsTableSize) << endl;
|
||||
return 0;
|
||||
}
|
||||
return _ripupLimits[type];
|
||||
}
|
||||
|
||||
|
||||
string Configuration::_getTypeName () const
|
||||
{
|
||||
return "Configuration";
|
||||
}
|
||||
|
||||
|
||||
string Configuration::_getString () const
|
||||
{
|
||||
ostringstream os;
|
||||
|
||||
os << "<" << _getTypeName() << " " << getRoutingGauge()->getName() << ">";
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
|
||||
Record* Configuration::_getRecord () const
|
||||
{
|
||||
Record* record = _base->_getRecord();
|
||||
//record->add ( getSlot ( "_rg" , _rg ) );
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,111 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./DataNegociate.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
|
||||
#include "kite/DataNegociate.h"
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
using std::ostringstream;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "DataNegociate".
|
||||
|
||||
|
||||
DataNegociate::DataNegociate ( TrackElement* trackSegment )
|
||||
: _routingEvent(NULL)
|
||||
, _trackSegment(trackSegment)
|
||||
, _cost (trackSegment)
|
||||
, _gcellOrder ((unsigned int)-1)
|
||||
, _state (RipupPerpandiculars)
|
||||
, _stateCount (1)
|
||||
, _leftBorder (false)
|
||||
, _rightBorder (false)
|
||||
, _ring (false)
|
||||
//, _z (RoutingGauge::getLayerDepth(trackSegment->getLayer()))
|
||||
{ }
|
||||
|
||||
|
||||
DataNegociate::~DataNegociate ()
|
||||
{ }
|
||||
|
||||
|
||||
void DataNegociate::update ()
|
||||
{
|
||||
_cost.update ( _trackSegment );
|
||||
}
|
||||
|
||||
|
||||
string DataNegociate::_getString () const
|
||||
{
|
||||
return "<" + _getTypeName() + " "
|
||||
+ getString(_trackSegment)
|
||||
+ ">";
|
||||
}
|
||||
|
||||
|
||||
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 ( "_gcellOrder" , _gcellOrder ) );
|
||||
//record->add ( getSlot ( "_z" , _z ) );
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
string DataNegociate::getStateString ( DataNegociate* data )
|
||||
{
|
||||
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;
|
||||
default:
|
||||
s << "Unknown(" << data->_state << ")"; break;
|
||||
}
|
||||
s << ":" << data->_stateCount;
|
||||
return s.str();
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,569 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./GCell.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Component.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "katabatic/AutoSegment.h"
|
||||
#include "katabatic/AutoContact.h"
|
||||
#include "kite/DataNegociate.h"
|
||||
#include "kite/TrackSegment.h"
|
||||
#include "kite/RoutingPlane.h"
|
||||
#include "kite/GCell.h"
|
||||
#include "kite/GCellGrid.h"
|
||||
#include "kite/NegociateWindow.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
using namespace Hurricane;
|
||||
using namespace Kite;
|
||||
|
||||
|
||||
TrackElement* getCandidate ( RoutingPad* rp, Box bb )
|
||||
{
|
||||
size_t depth = Session::getConfiguration()->getLayerDepth ( rp->getLayer() );
|
||||
if ( depth > 2 ) return NULL;
|
||||
|
||||
DebugSession::open ( rp->getNet() );
|
||||
|
||||
//if ( (depth != 0) and (depth != 2) ) return NULL;
|
||||
|
||||
ltrace(200) << "depth: " << depth << " " << rp->getSourcePosition() << " " << rp << endl;
|
||||
|
||||
if ( depth%2 == 0 ) {
|
||||
// Propagate from vertical Terminals.
|
||||
forEach ( Contact*, icontact, rp->getSlaveComponents().getSubSet<Contact*>() ) {
|
||||
if ( not bb.contains(icontact->getCenter()) ) continue;
|
||||
|
||||
forEach ( Segment*, isegment, icontact->getSlaveComponents().getSubSet<Segment*>() ) {
|
||||
TrackElement* autoSegment = Session::lookup(*isegment);
|
||||
if ( not autoSegment or autoSegment->isFixed() ) continue;
|
||||
|
||||
DebugSession::close ();
|
||||
return autoSegment;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#if DISABLED
|
||||
// Propage from Horizontal Terminals.
|
||||
bool hasM3protect = false;
|
||||
AutoContact* toContact = NULL;
|
||||
|
||||
forEach ( Contact*, icontact, rp->getSlaveComponents().getSubSet<Contact*>() ) {
|
||||
if ( not bb.contains(icontact->getCenter()) ) continue;
|
||||
|
||||
forEach ( Segment*, isegment, icontact->getSlaveComponents().getSubSet<Segment*>() ) {
|
||||
TrackElement* autoSegment = Session::lookup(*isegment);
|
||||
if ( not autoSegment ) continue;
|
||||
if ( autoSegment->isFixed() ) {
|
||||
if ( Session::getConfiguration()->getLayerDepth(autoSegment->getLayer()) == 2 ) {
|
||||
ltrace(200) << "M3 protection found for " << rp << endl;
|
||||
hasM3protect = true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
toContact = autoSegment->base()->getAutoSource();
|
||||
if ( toContact->base() == *icontact )
|
||||
toContact = autoSegment->base()->getAutoTarget();
|
||||
}
|
||||
}
|
||||
|
||||
// Find M3 associated to this terminal.
|
||||
if ( hasM3protect ) {
|
||||
if ( toContact ) {
|
||||
ltrace(200) << "toContact: " << toContact << endl;
|
||||
forEach ( Segment*, isegment, toContact->base()->getSlaveComponents().getSubSet<Segment*>() ) {
|
||||
ltrace(200) << "| slave: " << *isegment << endl;
|
||||
if ( Session::getConfiguration()->getLayerDepth(isegment->getLayer()) == 2 ) {
|
||||
TrackElement* autoSegment = Session::lookup(*isegment);
|
||||
ltrace(200) << "M3 candidate: " << autoSegment << endl;
|
||||
DebugSession::close ();
|
||||
return autoSegment;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
DebugSession::close ();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::swap;
|
||||
using std::numeric_limits;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::inltrace;
|
||||
using Hurricane::ltracein;
|
||||
using Hurricane::ltraceout;
|
||||
using Hurricane::roundfp;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::ForEachIterator;
|
||||
using Hurricane::Component;
|
||||
using Hurricane::RoutingPad;
|
||||
|
||||
using Katabatic::AutoContact;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Kite::GCell::CompareByDensity".
|
||||
//
|
||||
// lhs < rhs --> true
|
||||
|
||||
|
||||
bool GCell::CompareByDensity::operator() ( GCell* lhs, GCell* rhs )
|
||||
{
|
||||
//int difference = floatCompare ( lhs->base()->getDensity(), rhs->base()->getDensity() );
|
||||
//if ( abs(difference) > 1000 ) return difference > 0;
|
||||
|
||||
float difference = roundfp ( lhs->base()->getDensity() - rhs->base()->getDensity() );
|
||||
if ( difference != 0.0 ) return (difference > 0.0);
|
||||
|
||||
if ( lhs->getIndex() < rhs->getIndex() ) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Kite::GCell::CompareByStiffness".
|
||||
//
|
||||
// lhs < rhs --> true
|
||||
|
||||
|
||||
bool GCell::CompareByStiffness::operator() ( GCell* lhs, GCell* rhs )
|
||||
{
|
||||
if ( lhs->isRouted() xor rhs->isRouted() ) return rhs->isRouted();
|
||||
|
||||
float difference = roundfp ( lhs->getStiffness() - rhs->getStiffness() );
|
||||
if ( difference != 0.0 ) return (difference > 0.0);
|
||||
|
||||
return lhs->getIndex() < rhs->getIndex();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Kite::GCell".
|
||||
|
||||
|
||||
GCell::GCell ( GCellGrid* grid, Katabatic::GCell* gcell )
|
||||
: _gcellGrid (grid)
|
||||
, _base (gcell)
|
||||
, _segments ()
|
||||
, _order (numeric_limits<unsigned int>::max())
|
||||
, _isInRoutingSet (false)
|
||||
, _isRouted (false)
|
||||
{
|
||||
if ( !gcell )
|
||||
cerr << Bug("GCell:GCell() - NULL base.") << endl;
|
||||
|
||||
_leftSegments [0] = NULL;
|
||||
_leftSegments [1] = NULL;
|
||||
_rightSegments[0] = NULL;
|
||||
_rightSegments[1] = NULL;
|
||||
}
|
||||
|
||||
|
||||
GCell* GCell::create ( GCellGrid* grid, Katabatic::GCell* gcell )
|
||||
{
|
||||
GCell* kiteGCell = new GCell ( grid, gcell );
|
||||
|
||||
ltrace(90) << "Kite::GCell::create() - " << (void*)kiteGCell << " " << kiteGCell << endl;
|
||||
|
||||
return kiteGCell;
|
||||
}
|
||||
|
||||
|
||||
GCell::~GCell ()
|
||||
{ }
|
||||
|
||||
|
||||
void GCell::destroy ()
|
||||
{
|
||||
ltrace(90) << "Kite::GCell::destroy() - " << (void*)this << " " << this << endl;
|
||||
ltracein(90);
|
||||
|
||||
for ( size_t i=0 ; i < _segments.size() ; i++ ) {
|
||||
if ( !_segments[i]->getTrack() )
|
||||
_segments[i]->destroy ();
|
||||
else {
|
||||
cerr << Error("%s still bound to a track!\n"
|
||||
" (not deleted: let's get the memory leak)"
|
||||
,getString(_segments[i]).c_str()
|
||||
) << endl;
|
||||
}
|
||||
}
|
||||
delete this;
|
||||
|
||||
ltraceout(90);
|
||||
}
|
||||
|
||||
|
||||
GCell* GCell::getLeft () const
|
||||
{
|
||||
return _gcellGrid->getGCellLeft(this);
|
||||
}
|
||||
|
||||
|
||||
GCell* GCell::getRight () const
|
||||
{
|
||||
return _gcellGrid->getGCellRight(this);
|
||||
}
|
||||
|
||||
|
||||
GCell* GCell::getUp () const
|
||||
{
|
||||
return _gcellGrid->getGCellUp(this);
|
||||
}
|
||||
|
||||
|
||||
GCell* GCell::getDown () const
|
||||
{
|
||||
return _gcellGrid->getGCellDown(this);
|
||||
}
|
||||
|
||||
|
||||
bool GCell::areDensityConnex ( GCell* a, GCell* b )
|
||||
{ return Katabatic::GCell::areDensityConnex ( a->base(), b->base() ); }
|
||||
|
||||
|
||||
GCell* GCell::getLowestOrder ( TrackElement* trackSegment )
|
||||
{
|
||||
vector<GCell*> gcells;
|
||||
trackSegment->getGCells ( gcells );
|
||||
|
||||
if ( gcells.empty() ) return NULL;
|
||||
|
||||
size_t ilower = 0;
|
||||
for ( size_t i=0 ; i<gcells.size() ; i++ )
|
||||
if ( gcells[i]->getOrder() < gcells[ilower]->getOrder() )
|
||||
ilower = i;
|
||||
|
||||
return gcells[ilower];
|
||||
}
|
||||
|
||||
|
||||
void GCell::loadRouting ( unsigned int order )
|
||||
{
|
||||
_segments.clear ();
|
||||
_order = order;
|
||||
|
||||
ltrace(200) << "GCell::loadRouting() - " << this << " Session:" << Session::getOrder() << endl;
|
||||
ltracein(200);
|
||||
|
||||
Segment* segment;
|
||||
AutoSegment* autoSegment;
|
||||
|
||||
ltrace(149) << "AutoSegments from AutoContacts" << endl;
|
||||
vector<AutoContact*>* contacts = getContacts();
|
||||
for ( size_t i=0 ; i<contacts->size() ; i++ ) {
|
||||
forEach ( Component*, component, (*contacts)[i]->getSlaveComponents() ) {
|
||||
segment = dynamic_cast<Segment*>(*component);
|
||||
autoSegment = Session::base()->lookup ( segment );
|
||||
ltrace(149) << autoSegment << endl;
|
||||
if ( autoSegment ) {
|
||||
addTrackSegment ( this, autoSegment, true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// // Effective deletion of rejecteds.
|
||||
// set<AutoSegment*>::iterator ireject = rejecteds.begin();
|
||||
// for ( ; ireject != rejecteds.end() ; ireject++ ) {
|
||||
// }
|
||||
|
||||
ltrace(149) << "Horizontal overcell AutoSegments" << endl;
|
||||
vector<AutoSegment*>* segments = getHSegments();
|
||||
for ( size_t i=0 ; i<segments->size() ; i++ ) {
|
||||
addTrackSegment ( this, (*segments)[i], true );
|
||||
}
|
||||
|
||||
ltrace(149) << "Vertical overcell AutoSegments" << endl;
|
||||
segments = getVSegments();
|
||||
for ( size_t i=0 ; i<segments->size() ; i++ ) {
|
||||
addTrackSegment ( this, (*segments)[i], true );
|
||||
}
|
||||
|
||||
ltrace(149) << "_segments.size():" << _segments.size() << endl;
|
||||
ltraceout(200);
|
||||
}
|
||||
|
||||
|
||||
void GCell::computeBorder ()
|
||||
{
|
||||
ltrace(200) << "GCell::computeBorder() " << this << endl;
|
||||
ltracein(200);
|
||||
|
||||
vector<AutoContact*>* contacts = _base->getContacts();
|
||||
TrackElement* candidate;
|
||||
DataNegociate* data;
|
||||
Box bb = getBoundingBox();
|
||||
size_t iLeft = 0;
|
||||
size_t iRight = 0;
|
||||
|
||||
for ( size_t icontact=0 ; icontact < contacts->size() ; icontact++ ) {
|
||||
Component* anchor = (*contacts)[icontact]->getAnchor();
|
||||
RoutingPad* rp = dynamic_cast<RoutingPad*>(anchor);
|
||||
|
||||
if ( not rp ) continue;
|
||||
|
||||
// size_t depth = Session::getConfiguration()->getLayerDepth ( rp->getLayer() );
|
||||
// if ( (depth != 0) and (depth != 2) ) continue;
|
||||
|
||||
// ltrace(200) << "depth: " << depth << " " << rp << endl;
|
||||
|
||||
candidate = getCandidate ( rp, bb );
|
||||
if ( not candidate ) continue;
|
||||
|
||||
data = candidate->getDataNegociate();
|
||||
if ( not data ) continue;
|
||||
|
||||
// Ugly: hardwired pitch usage.
|
||||
if ( (rp->getX() - getX() < DbU::lambda(11.0)) and (iLeft < 2) ) {
|
||||
//data->setLeftBorder(true);
|
||||
ltrace(200) << "Left Segments[" << iLeft << "]: " << candidate << endl;
|
||||
_leftSegments[iLeft++] = candidate;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( (getXMax() - rp->getX() < DbU::lambda(11.0)) and (iRight < 2) ) {
|
||||
//data->setRightBorder(true);
|
||||
ltrace(200) << "Right Segment[" << iRight << "]: " << candidate << endl;
|
||||
_rightSegments[iRight++] = candidate;
|
||||
}
|
||||
}
|
||||
|
||||
ltraceout(200);
|
||||
}
|
||||
|
||||
|
||||
TrackElement* GCell::addTrackSegment ( GCell* gcell, AutoSegment* autoSegment, bool loading )
|
||||
{
|
||||
ltrace(200) << "GCell::addTrackSegment() - " << autoSegment << endl;
|
||||
ltracein(159);
|
||||
|
||||
// Special case: fixed AutoSegments must not interfere with blockages.
|
||||
// Ugly: uses of getExtensionCap().
|
||||
if ( autoSegment->isFixed() ) {
|
||||
RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(autoSegment->getLayer());
|
||||
Track* track = plane->getTrackByPosition ( autoSegment->getAxis() );
|
||||
size_t begin;
|
||||
size_t end;
|
||||
Interval fixedSpan;
|
||||
Interval blockageSpan;
|
||||
|
||||
autoSegment->getCanonical ( fixedSpan );
|
||||
fixedSpan.inflate ( Session::getExtensionCap() );
|
||||
|
||||
track->getOverlapBounds ( fixedSpan, begin, end );
|
||||
for ( ; (begin < end) ; begin++ ) {
|
||||
|
||||
TrackElement* other = track->getSegment(begin);
|
||||
ltrace(200) << "| overlap: " << other << endl;
|
||||
|
||||
if ( not other->isBlockage() ) continue;
|
||||
|
||||
other->getCanonical ( blockageSpan );
|
||||
blockageSpan.inflate(Session::getExtensionCap());
|
||||
|
||||
ltrace(200) << " fixed:" << fixedSpan << " vs. blockage:" << blockageSpan << endl;
|
||||
|
||||
if ( not fixedSpan.intersect(blockageSpan) ) continue;
|
||||
|
||||
// Overlap between fixed & blockage.
|
||||
ltrace(200) << "* Blockage overlap: " << autoSegment << endl;
|
||||
Session::destroyRequest ( autoSegment );
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Interval span;
|
||||
autoSegment = autoSegment->getCanonical ( span );
|
||||
|
||||
bool created;
|
||||
TrackElement* trackSegment = TrackSegment::create ( autoSegment, NULL, created );
|
||||
DataNegociate* data = trackSegment->getDataNegociate ();
|
||||
GCell* previousGCell = trackSegment->getGCell();
|
||||
|
||||
if ( not loading )
|
||||
ltrace(159) << "* lookup: " << autoSegment << endl;
|
||||
|
||||
if ( created )
|
||||
ltrace(159) << "* " << trackSegment << endl;
|
||||
|
||||
if ( not created and not loading ) {
|
||||
ltrace(200) << "TrackSegment already exists (and not in loading stage)." << endl;
|
||||
ltrace(200) << "Previous owning GCell: " << previousGCell << endl;
|
||||
if ( previousGCell != gcell ) {
|
||||
previousGCell->removeTrackSegment ( trackSegment );
|
||||
trackSegment->setGCell ( NULL );
|
||||
}
|
||||
}
|
||||
|
||||
vector<GCell*> gcells;
|
||||
trackSegment->getGCells ( gcells );
|
||||
GCell* lowest = gcells[0];
|
||||
bool validPrevious = false;
|
||||
|
||||
for ( size_t igcell=0 ; igcell<gcells.size() ; igcell++ ) {
|
||||
ltrace(200) << "| " << igcell << ":" << gcells[igcell] << endl;
|
||||
if ( gcells[igcell]->getOrder() < lowest->getOrder()) {
|
||||
lowest = gcells[igcell];
|
||||
}
|
||||
if ( gcells[igcell] == previousGCell ) validPrevious = true;
|
||||
}
|
||||
if ( not validPrevious ) previousGCell = NULL;
|
||||
|
||||
if ( not gcell ) {
|
||||
gcell = lowest;
|
||||
if ( previousGCell and (gcell->getOrder() == previousGCell->getOrder()) )
|
||||
gcell = previousGCell;
|
||||
ltrace(200) << "New owner: " << gcell << endl;
|
||||
} else if ( created ) {
|
||||
if ( (lowest != gcell) && (lowest->getOrder() != gcell->getOrder() ) ) {
|
||||
cerr << Bug("Not the right lowest: %s",getString(lowest).c_str()) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if ( (gcell->getOrder() > Session::getOrder()) and not (data->isRing() or data->isBorder()) ) {
|
||||
cinfo << "[INFO] GCell::addTrackSegment() - Owning GCell is not in active set ("
|
||||
<< gcell->getOrder() << " > Session:" << Session::getOrder() << ")."
|
||||
<< "\n " << trackSegment
|
||||
<< endl;
|
||||
}
|
||||
|
||||
if ( not trackSegment->getGCell() ) {
|
||||
trackSegment->setGCell ( gcell );
|
||||
gcell->addTrackSegment ( trackSegment );
|
||||
|
||||
if ( loading ) {
|
||||
RoutingPlane* plane = Session::getKiteEngine()->getRoutingPlaneByLayer(autoSegment->getLayer());
|
||||
Track* track = plane->getTrackByPosition ( autoSegment->getAxis() );
|
||||
Interval uside = gcell->getUSide ( Constant::perpandicular(autoSegment->getDirection()), false );
|
||||
|
||||
if ( track->getAxis() > uside.getVMax() ) track = track->getPrevious();
|
||||
if ( track->getAxis() < uside.getVMin() ) track = track->getNext();
|
||||
|
||||
trackSegment->setAxis ( track->getAxis(), Katabatic::Realignate|Katabatic::AxisSet );
|
||||
trackSegment->invalidate ();
|
||||
|
||||
if ( created and trackSegment->isFixed() ) {
|
||||
Session::addInsertEvent ( trackSegment, track );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ltraceout(159);
|
||||
|
||||
return trackSegment;
|
||||
}
|
||||
|
||||
|
||||
void GCell::addTrackSegment ( TrackElement* trackSegment )
|
||||
{
|
||||
_segments.push_back ( trackSegment );
|
||||
}
|
||||
|
||||
|
||||
void GCell::removeTrackSegment ( TrackElement* trackSegment )
|
||||
{
|
||||
if ( _segments.empty() ) return;
|
||||
|
||||
size_t i = 0;
|
||||
for ( ; i<_segments.size() ; i++ )
|
||||
if ( _segments[i] == trackSegment ) {
|
||||
swap ( _segments[i], _segments[_segments.size()-1] );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( i < _segments.size() ) _segments.pop_back ();
|
||||
}
|
||||
|
||||
|
||||
double GCell::getOwnedWireLength () const
|
||||
{
|
||||
double ownedWL = 0;
|
||||
|
||||
for ( size_t i=0 ; i<_segments.size() ; i++ ) {
|
||||
ownedWL += DbU::getLambda ( _segments[i]->getLength() );
|
||||
}
|
||||
|
||||
return ownedWL;
|
||||
}
|
||||
|
||||
|
||||
void GCell::anticipateRouting ( unsigned int order )
|
||||
{
|
||||
if ( order < _order ) {
|
||||
setRouted ( true );
|
||||
loadRouting ( order );
|
||||
// _order = order;
|
||||
// for ( size_t isegment=0 ; isegment<_segments.size() ; ++isegment ) {
|
||||
// DataNegociate* data = _segments[isegment]->getDataNegociate();
|
||||
// data->setGCellOrder ( order );
|
||||
// data->resetBorder ();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
string GCell::_getTypeName() const
|
||||
{ return "Kite::GCell"; }
|
||||
|
||||
|
||||
string GCell::_getString () const
|
||||
{
|
||||
string s = _base->_getString();
|
||||
s.erase ( s.size()-1 );
|
||||
s += " o:";
|
||||
s += ((_order == numeric_limits<unsigned int>::max()) ? "-" : getString(_order));
|
||||
s += " ";
|
||||
s += ((_isRouted) ? "R" : "-");
|
||||
s += ">";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
Record* GCell::_getRecord () const
|
||||
{ return _base->_getRecord(); }
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,154 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./GCellGrid.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "hurricane/Cell.h"
|
||||
#include "katabatic/GCellGrid.h"
|
||||
#include "kite/GCell.h"
|
||||
#include "kite/GCellGrid.h"
|
||||
#include "kite/KiteEngine.h"
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
using Hurricane::tab;
|
||||
using Hurricane::inltrace;
|
||||
using Hurricane::ltracein;
|
||||
using Hurricane::ltraceout;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "GCellGrid".
|
||||
|
||||
|
||||
GCellGrid::GCellGrid ( KiteEngine* kite )
|
||||
: Katabatic::Grid<GCell>()
|
||||
, _kite(kite)
|
||||
{ }
|
||||
|
||||
|
||||
void GCellGrid::_postCreate ()
|
||||
{
|
||||
// Clone the grid from Katabatic Here.
|
||||
Katabatic::GCellGrid* base = _kite->base()->getGCellGrid();
|
||||
vector<Katabatic::GCell*>* baseGCells = base->getGCellVector();
|
||||
|
||||
ltrace(80) << "Kite GCell Matrix [" << baseGCells->size() << "]" << endl;
|
||||
|
||||
for ( size_t i=0 ; i<baseGCells->size() ; i++ )
|
||||
_gcells.push_back ( GCell::create(this,(*baseGCells)[i]) );
|
||||
|
||||
_rows = base->getRows();
|
||||
_columns = base->getColumns();
|
||||
_rawSize = base->getRawSize();
|
||||
_xGraduations = base->getXGrads();
|
||||
_yGraduations = base->getYGrads();
|
||||
}
|
||||
|
||||
|
||||
GCellGrid::~GCellGrid ()
|
||||
{ }
|
||||
|
||||
|
||||
void GCellGrid::_preDestroy ()
|
||||
{
|
||||
ltrace(90) << "Kite::GCellGrid::_preDestroy()" << endl;
|
||||
ltracein(90);
|
||||
|
||||
vector<GCell*>::iterator it = _gcells.begin();
|
||||
vector<GCell*>::iterator end = _gcells.end ();
|
||||
for ( ; it != end ; it++ ) (*it)->destroy ();
|
||||
|
||||
ltraceout(90);
|
||||
}
|
||||
|
||||
|
||||
Cell* GCellGrid::getCell () const
|
||||
{
|
||||
return _kite->getCell();
|
||||
}
|
||||
|
||||
|
||||
GCellGrid* GCellGrid::create ( KiteEngine* kite )
|
||||
{
|
||||
GCellGrid* subFCellGrid = new Kite::GCellGrid ( kite );
|
||||
|
||||
subFCellGrid->_postCreate ();
|
||||
|
||||
return subFCellGrid;
|
||||
}
|
||||
|
||||
|
||||
double GCellGrid::getTotalWireLength () const
|
||||
{
|
||||
double totalWL = 0;
|
||||
for ( size_t i=0 ; i < _gcells.size() ; i++ ) {
|
||||
totalWL += _gcells[i]->getOwnedWireLength ();
|
||||
}
|
||||
return totalWL;
|
||||
}
|
||||
|
||||
|
||||
void GCellGrid::_check () const
|
||||
{
|
||||
cerr << " o Checking Kite GCell Grid." << endl;
|
||||
for ( size_t i=0 ; i < _gcells.size() ; i++ ) {
|
||||
if ( _gcells[i]->base() == NULL ) {
|
||||
cerr << "[CHECK] _gcells[" << i << "]: " << (void*)_gcells[i] << " has NULL base." << endl;
|
||||
}
|
||||
}
|
||||
cerr << " - Successful." << endl;
|
||||
}
|
||||
|
||||
|
||||
string GCellGrid::_getTypeName () const
|
||||
{
|
||||
return "Kite::GCellGrid";
|
||||
}
|
||||
|
||||
|
||||
string GCellGrid::_getString () const
|
||||
{
|
||||
return "<" + _getTypeName() + " "
|
||||
+ getString(getRows()) + "x" + getString(getColumns()) + ">";
|
||||
}
|
||||
|
||||
|
||||
Record* GCellGrid::_getRecord () const
|
||||
{
|
||||
Record* record = Katabatic::Grid<GCell>::_getRecord ();
|
||||
record->add ( getSlot ( "_kite", _kite ) );
|
||||
return record;
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,402 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./GCellRoutingSet.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#include <limits>
|
||||
#include <queue>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Contact.h"
|
||||
#include "hurricane/Segment.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "katabatic/AutoSegment.h"
|
||||
#include "kite/GCell.h"
|
||||
#include "kite/GCellGrid.h"
|
||||
#include "kite/GCellRoutingSet.h"
|
||||
#include "kite/DataNegociate.h"
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using std::numeric_limits;
|
||||
using std::queue;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::ostringstream;
|
||||
using std::setprecision;
|
||||
using Hurricane::roundfp;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::inltrace;
|
||||
using Hurricane::ltracein;
|
||||
using Hurricane::ltraceout;
|
||||
using Hurricane::Error;
|
||||
using Katabatic::getVectorString;
|
||||
|
||||
|
||||
const char* usedGCellSeed =
|
||||
"GCellRoutingSet::create() : %s is already in a GCellRoutingSet.\n";
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "GCellRoutingSet".
|
||||
|
||||
|
||||
GCellRoutingSet::GCellRoutingSet ( GCell* gcell, float expandStep, float minDensity )
|
||||
: _order (numeric_limits<unsigned int>::max())
|
||||
, _minDensity (minDensity)
|
||||
, _minDensities (new float [gcell->getDepth()])
|
||||
, _gcells (1,gcell)
|
||||
, _borderSegments()
|
||||
, _statistics ()
|
||||
{
|
||||
gcell->setInRoutingSet ( true );
|
||||
|
||||
if ( _minDensity > expandStep ) _minDensity -= expandStep;
|
||||
else _minDensity = 0.0;
|
||||
_minDensity = roundfp ( _minDensity );
|
||||
for ( unsigned int i=0 ; i < gcell->getDepth() ; i++ ) {
|
||||
_minDensities[i] = gcell->getDensity(i) * expandStep;
|
||||
_minDensities[i] = roundfp ( _minDensities[i] );
|
||||
}
|
||||
ltrace(200) << getVectorString(_minDensities,gcell->getDepth()) << endl;
|
||||
}
|
||||
|
||||
|
||||
void GCellRoutingSet::_postCreate ()
|
||||
{
|
||||
ltrace(90) << "Kite::GCellRoutingSet::_postCreate() - " << (void*)this << " " << this << endl;
|
||||
ltracein(90);
|
||||
|
||||
ltraceout(90);
|
||||
}
|
||||
|
||||
|
||||
GCellRoutingSet::~GCellRoutingSet ()
|
||||
{
|
||||
delete [] _minDensities;
|
||||
}
|
||||
|
||||
|
||||
void GCellRoutingSet::_preDestroy ()
|
||||
{ }
|
||||
|
||||
|
||||
void GCellRoutingSet::destroy ()
|
||||
{
|
||||
_preDestroy ();
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
GCellRoutingSet* GCellRoutingSet::create ( GCell* gcell, float expandStep )
|
||||
{
|
||||
if ( gcell->isInRoutingSet() )
|
||||
throw Error ( usedGCellSeed, getString(gcell).c_str() );
|
||||
|
||||
GCellRoutingSet* rs = new GCellRoutingSet ( gcell
|
||||
, expandStep
|
||||
, gcell->getDensity()
|
||||
);
|
||||
rs->_postCreate ();
|
||||
|
||||
return rs;
|
||||
}
|
||||
|
||||
|
||||
void GCellRoutingSet::setRouted ( bool state )
|
||||
{
|
||||
for ( size_t igcell=0 ; igcell<_gcells.size() ; ++igcell )
|
||||
_gcells[igcell]->setRouted ( true );
|
||||
}
|
||||
|
||||
|
||||
vector<TrackElement*>& GCellRoutingSet::getOwnedSegments ( vector<TrackElement*>& segments ) const
|
||||
{
|
||||
for ( size_t i=0 ; i<_gcells.size() ; i++ ) {
|
||||
if ( _gcells[i]->isRouted() ) continue;
|
||||
|
||||
const vector<TrackElement*>& gcellSegments = _gcells[i]->getOwnedSegments();
|
||||
for ( size_t j=0 ; j<gcellSegments.size() ; j++ ) {
|
||||
if ( !gcellSegments[j]->isFixed() )
|
||||
segments.push_back ( gcellSegments[j] );
|
||||
}
|
||||
// segments.insert ( segments.end()
|
||||
// , _gcells[i]->getOwnedSegments().begin()
|
||||
// , _gcells[i]->getOwnedSegments().end()
|
||||
// );
|
||||
}
|
||||
|
||||
for ( size_t i=0 ; i<_borderSegments.size() ; i++ ) {
|
||||
TrackElement* segment = _borderSegments[i]._segment;
|
||||
DataNegociate* data = segment->getDataNegociate();
|
||||
data->setGCellOrder ( _order );
|
||||
segments.push_back ( segment );
|
||||
}
|
||||
|
||||
return segments;
|
||||
}
|
||||
|
||||
|
||||
void GCellRoutingSet::expand ( GCellGrid* grid )
|
||||
{
|
||||
#if defined(CHECK_DETERMINISM)
|
||||
cerr << "Order: Expanding " << this << endl;
|
||||
#endif
|
||||
|
||||
ltrace(200) << "Expanding: " << this << endl;
|
||||
ltracein(200);
|
||||
ltrace(200) << getVectorString(_minDensities,_gcells.front()->getDepth()) << endl;
|
||||
|
||||
queue<GCell*> densityQueue;
|
||||
densityQueue.push ( _gcells.front() );
|
||||
|
||||
while ( !densityQueue.empty() ) {
|
||||
GCell* current = densityQueue.front ();
|
||||
GCell* neighbor = NULL;
|
||||
densityQueue.pop ();
|
||||
|
||||
ltrace(200) << "Popping Density: " << current << endl;
|
||||
|
||||
for ( size_t i=0 ; i<4 ; i++ ) {
|
||||
switch ( i ) {
|
||||
case 0: neighbor = grid->getGCellLeft (current); break;
|
||||
case 1: neighbor = grid->getGCellRight(current); break;
|
||||
case 2: neighbor = grid->getGCellUp (current); break;
|
||||
case 3: neighbor = grid->getGCellDown (current); break;
|
||||
}
|
||||
|
||||
if ( neighbor ) {
|
||||
#if defined(CHECK_DETERMINISM)
|
||||
cerr << "Order: Looking at neighbor " << neighbor << endl;
|
||||
#endif
|
||||
float densities[32];
|
||||
neighbor->base()->getDensities ( densities );
|
||||
ltrace(200) << "Neighbor: " << neighbor << " " << getVectorString(densities,5) << endl;
|
||||
}
|
||||
|
||||
if ( neighbor and !neighbor->isInRoutingSet() ) {
|
||||
if ( not neighbor->isAboveDensity(_minDensity)
|
||||
and not GCell::areDensityConnex(current,neighbor) )
|
||||
continue;
|
||||
|
||||
#if defined(CHECK_DETERMINISM)
|
||||
cerr << "Order: Agglomerate " << neighbor << endl;
|
||||
#endif
|
||||
ltrace(200) << "Agglomerating: " << neighbor << endl;
|
||||
|
||||
neighbor->setInRoutingSet ( true );
|
||||
_gcells.push_back ( neighbor );
|
||||
densityQueue.push ( neighbor );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// De-notching pass.
|
||||
for ( size_t i=0 ; i<_gcells.size() ; i++ ) densityQueue.push ( _gcells[i] );
|
||||
|
||||
while ( not densityQueue.empty() ) {
|
||||
GCell* current = densityQueue.front();
|
||||
GCell* neighbor = NULL;
|
||||
|
||||
densityQueue.pop();
|
||||
|
||||
for ( size_t i=0 ; i<4 ; i++ ) {
|
||||
switch ( i ) {
|
||||
case 0: neighbor = grid->getGCellLeft (current); break;
|
||||
case 1: neighbor = grid->getGCellRight(current); break;
|
||||
case 2: neighbor = grid->getGCellUp (current); break;
|
||||
case 3: neighbor = grid->getGCellDown (current); break;
|
||||
}
|
||||
|
||||
if ( not neighbor ) continue;
|
||||
|
||||
#if defined(CHECK_DETERMINISM)
|
||||
cerr << "Order: Denotching, looking at neighbor " << neighbor << endl;
|
||||
#endif
|
||||
if ( neighbor->isInRoutingSet() ) continue;
|
||||
|
||||
GCell* left = grid->getGCellLeft (neighbor);
|
||||
GCell* right = grid->getGCellRight(neighbor);
|
||||
GCell* up = grid->getGCellUp (neighbor);
|
||||
GCell* down = grid->getGCellDown (neighbor);
|
||||
|
||||
bool hasLeft = (left) ? left ->isInRoutingSet() : true;
|
||||
bool hasRight = (right) ? right->isInRoutingSet() : true;
|
||||
bool hasUp = (up) ? up ->isInRoutingSet() : true;
|
||||
bool hasDown = (down) ? down ->isInRoutingSet() : true;
|
||||
|
||||
if ( (not (hasLeft and hasRight)) and (not (hasUp and hasDown)) ) continue;
|
||||
|
||||
#if defined(CHECK_DETERMINISM)
|
||||
cerr << "Order: Denotching, Agglomerate " << neighbor << endl;
|
||||
#endif
|
||||
ltrace(200) << "Denotching, Agglomerating: " << neighbor << endl;
|
||||
|
||||
neighbor->setInRoutingSet ( true );
|
||||
_gcells.push_back ( neighbor );
|
||||
densityQueue.push ( neighbor );
|
||||
}
|
||||
}
|
||||
|
||||
ltrace(200) << "GCellRoutingSet (final): " << this << endl;
|
||||
for ( size_t i=0 ; i<_gcells.size() ; i++ )
|
||||
ltrace(200) << "| " << _gcells[i] << endl;
|
||||
|
||||
_statistics.setGCellsCount ( _gcells.size() );
|
||||
_statistics.setSegmentsCount ( 0 );
|
||||
for ( size_t i=0 ; i<_gcells.size() ; i++ ) {
|
||||
const vector<TrackElement*>& gcellSegments = _gcells[i]->getOwnedSegments();
|
||||
_statistics.incSegmentsCount ( gcellSegments.size() );
|
||||
}
|
||||
|
||||
ltraceout(200);
|
||||
}
|
||||
|
||||
|
||||
void GCellRoutingSet::loadBorder ( GCellGrid* grid )
|
||||
{
|
||||
ltrace(200) << "loadBorder() " << this << endl;
|
||||
unsigned int order = _order;
|
||||
TrackElement* segment = NULL;
|
||||
DataNegociate* data;
|
||||
|
||||
for ( size_t igcell=0 ; igcell<_gcells.size() ; igcell++ ) {
|
||||
if ( _gcells[igcell]->getOrder() < order ) continue;
|
||||
|
||||
GCell* neighbor = NULL;
|
||||
|
||||
for ( size_t i=0 ; i<2 ; i++ ) {
|
||||
switch ( i ) {
|
||||
case 0: neighbor = grid->getGCellLeft (_gcells[igcell]); break;
|
||||
case 1: neighbor = grid->getGCellRight(_gcells[igcell]); break;
|
||||
}
|
||||
if ( not neighbor or (neighbor->getOrder() <= order) ) continue;
|
||||
|
||||
neighbor->computeBorder ();
|
||||
|
||||
for ( size_t iRight=0 ; iRight<2 ; iRight++ ) {
|
||||
segment = neighbor->getRightRp(iRight);
|
||||
if ( segment == NULL ) break;
|
||||
|
||||
data = (segment) ? segment->getDataNegociate() : NULL;
|
||||
if ( data ) {
|
||||
if ( (i == 0) and (data->getGCellOrder() > order) and not data->isRing() ) {
|
||||
ltrace(200) << "| border: [" << data->getGCellOrder()
|
||||
<< " > " << order << "] " << segment << endl;
|
||||
data->setRightBorder ( true );
|
||||
_borderSegments.push_back ( BorderSegment(segment,data->getGCellOrder()) );
|
||||
} else
|
||||
data->resetBorder();
|
||||
}
|
||||
}
|
||||
|
||||
for ( size_t iLeft=0 ; iLeft<2 ; iLeft++ ) {
|
||||
segment = neighbor->getLeftRp(iLeft);
|
||||
if ( segment == NULL ) break;
|
||||
|
||||
data = (segment) ? segment->getDataNegociate() : NULL;
|
||||
if ( data ) {
|
||||
if ( (i == 1) and (data->getGCellOrder() > order) and not data->isRing() ) {
|
||||
ltrace(200) << "| border: [" << data->getGCellOrder()
|
||||
<< " > " << order << "] " << segment << endl;
|
||||
data->setLeftBorder ( true );
|
||||
_borderSegments.push_back ( BorderSegment(segment,data->getGCellOrder()) );
|
||||
} else
|
||||
data->resetBorder();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GCellRoutingSet::freeBorder ()
|
||||
{
|
||||
for ( size_t j=0 ; j<_borderSegments.size() ; j++ ) {
|
||||
DataNegociate* data = _borderSegments[j]._segment->getDataNegociate();
|
||||
if ( not data->isBorder() ) continue;
|
||||
|
||||
data->resetBorder ();
|
||||
data->setGCellOrder ( _borderSegments[j]._order );
|
||||
Session::addRemoveEvent ( _borderSegments[j]._segment );
|
||||
//_borderSegments[j]._segment->base()->setFixed(true);
|
||||
}
|
||||
Session::revalidate ();
|
||||
|
||||
vector<BorderSegment>().swap ( _borderSegments );
|
||||
}
|
||||
|
||||
|
||||
unsigned int& GCellRoutingSet::loadRouting ( unsigned int& order )
|
||||
{
|
||||
_order = order;
|
||||
//cerr << "RoutingSet order:" << order << endl;
|
||||
|
||||
for ( size_t i=0 ; i<_gcells.size() ; i++ )
|
||||
_gcells[i]->loadRouting ( order );
|
||||
|
||||
return ++order;
|
||||
}
|
||||
|
||||
|
||||
string GCellRoutingSet::_getTypeName () const
|
||||
{ return "GCellRoutingSet"; }
|
||||
|
||||
|
||||
string GCellRoutingSet::_getString () const
|
||||
{
|
||||
ostringstream s;
|
||||
|
||||
s << "<o:" << ((_order!=numeric_limits<unsigned int>::max()) ? getString(_order) : "-")
|
||||
<< " " << _gcells.front() << setprecision(9)
|
||||
<< " [" << ":" << _minDensity
|
||||
<< "] " << _gcells.size()
|
||||
<< ">";
|
||||
return s.str();
|
||||
|
||||
//return "<o:" + ((_order!=numeric_limits<unsigned int>::max()) ? getString(_order) : "-")
|
||||
// + " " + getString(_gcells.front())
|
||||
// + " [" + /*getString(_minDensity)*/ + ":" + getString(_minDensity)
|
||||
// + "] " + getString(_gcells.size())
|
||||
// + ">";
|
||||
}
|
||||
|
||||
|
||||
Record* GCellRoutingSet::_getRecord () const
|
||||
{
|
||||
Record* record = new Record ( getString(this) );
|
||||
record->add ( getSlot ( "_gcells" , &_gcells ) );
|
||||
record->add ( getSlot ( "_order" , _order ) );
|
||||
record->add ( getSlot ( "_minDensity", _minDensity ) );
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,395 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#include <functional>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <QAction>
|
||||
#include <QMenu>
|
||||
#include <QMenuBar>
|
||||
#include <QApplication>
|
||||
#include <hurricane/Warning.h>
|
||||
#include <hurricane/Error.h>
|
||||
#include <hurricane/Breakpoint.h>
|
||||
#include <hurricane/DebugSession.h>
|
||||
#include <hurricane/Go.h>
|
||||
#include <hurricane/Net.h>
|
||||
#include <hurricane/Cell.h>
|
||||
#include <hurricane/UpdateSession.h>
|
||||
#include <hurricane/viewer/Graphics.h>
|
||||
#include <hurricane/viewer/CellWidget.h>
|
||||
#include <hurricane/viewer/CellViewer.h>
|
||||
#include <crlcore/AllianceFramework.h>
|
||||
#include <katabatic/GCell.h>
|
||||
#include <knik/KnikEngine.h>
|
||||
#include <kite/GraphicKiteEngine.h>
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using namespace std;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Breakpoint;
|
||||
using Hurricane::DebugSession;
|
||||
using Hurricane::UpdateSession;
|
||||
using Hurricane::Net;
|
||||
using Hurricane::Graphics;
|
||||
using Hurricane::ColorScale;
|
||||
using CRL::Catalog;
|
||||
using CRL::AllianceFramework;
|
||||
using Knik::KnikEngine;
|
||||
|
||||
|
||||
size_t GraphicKiteEngine::_references = 0;
|
||||
GraphicKiteEngine* GraphicKiteEngine::_singleton = NULL;
|
||||
|
||||
|
||||
void GraphicKiteEngine::initKatabaticAc ( CellWidget* widget )
|
||||
{
|
||||
//cerr << "GraphicKatabaticEngine::initKatabaticGo()" << endl;
|
||||
}
|
||||
|
||||
|
||||
void GraphicKiteEngine::drawKatabaticAc ( CellWidget* widget
|
||||
, const Go* go
|
||||
, const BasicLayer* basicLayer
|
||||
, const Box& box
|
||||
, const Transformation& transformation
|
||||
)
|
||||
{ }
|
||||
|
||||
|
||||
void GraphicKiteEngine::initKatabaticGCell ( CellWidget* widget )
|
||||
{
|
||||
widget->getDrawingPlanes().setPen ( Qt::NoPen );
|
||||
}
|
||||
|
||||
|
||||
void GraphicKiteEngine::drawKatabaticGCell ( CellWidget* widget
|
||||
, const Go* go
|
||||
, const BasicLayer* basicLayer
|
||||
, const Box& box
|
||||
, const Transformation& transformation
|
||||
)
|
||||
{
|
||||
const Katabatic::GCell* gcell = static_cast<const Katabatic::GCell*>(go);
|
||||
|
||||
QPainter& painter = widget->getPainter();
|
||||
size_t density = (size_t)( gcell->getMaxHVDensity() * 255.0 );
|
||||
if ( density > 255 ) density = 255;
|
||||
|
||||
painter.setBrush
|
||||
( Graphics::getColorScale(ColorScale::Fire).getBrush(density,widget->getDarkening()) );
|
||||
painter.drawRect
|
||||
( widget->dbuToDisplayRect(gcell->getBoundingBox().inflate(0
|
||||
,0
|
||||
,gcell->getTopRightShrink()
|
||||
,gcell->getTopRightShrink())) );
|
||||
}
|
||||
|
||||
|
||||
KiteEngine* GraphicKiteEngine::createEngine ( const RoutingGauge* rg )
|
||||
{
|
||||
Cell* cell = getCell ();
|
||||
|
||||
KiteEngine* kite = KiteEngine::get ( cell );
|
||||
if ( not kite ) {
|
||||
kite = KiteEngine::create ( rg, cell );
|
||||
kite->setPostEventCb ( boost::bind(&GraphicKiteEngine::postEvent,this) );
|
||||
} else
|
||||
cerr << Warning("%s already has a Kite engine.",getString(cell).c_str()) << endl;
|
||||
|
||||
return kite;
|
||||
}
|
||||
|
||||
|
||||
KiteEngine* GraphicKiteEngine::getForFramework ()
|
||||
{
|
||||
// Currently, only one framework is avalaible: Alliance.
|
||||
|
||||
KiteEngine* kite = KiteEngine::get ( getCell() );
|
||||
if ( kite ) return kite;
|
||||
|
||||
AllianceFramework* af = AllianceFramework::get ();
|
||||
kite = createEngine ( af->getRoutingGauge() );
|
||||
|
||||
if ( not kite )
|
||||
throw Error("Failed to create Kite engine on %s.",getString(getCell()).c_str());
|
||||
|
||||
return kite;
|
||||
}
|
||||
|
||||
|
||||
void GraphicKiteEngine::saveGlobalSolution ()
|
||||
{
|
||||
KiteEngine* kite = KiteEngine::get ( getCell() );
|
||||
if ( kite ) kite->saveGlobalSolution ();
|
||||
}
|
||||
|
||||
|
||||
void GraphicKiteEngine::loadGlobalSolution ()
|
||||
{
|
||||
|
||||
KiteEngine* kite = getForFramework ();
|
||||
|
||||
emit cellPreModificated ();
|
||||
kite->runGlobalRouter ( LoadGlobalSolution );
|
||||
emit cellPostModificated ();
|
||||
}
|
||||
|
||||
|
||||
void GraphicKiteEngine::runGlobal ()
|
||||
{
|
||||
|
||||
KiteEngine* kite = getForFramework ();
|
||||
|
||||
emit cellPreModificated ();
|
||||
kite->runGlobalRouter ( BuildGlobalSolution );
|
||||
emit cellPostModificated ();
|
||||
}
|
||||
|
||||
|
||||
void GraphicKiteEngine::runDetailed ()
|
||||
{
|
||||
static vector<Net*> routingNets;
|
||||
|
||||
KiteEngine* kite = KiteEngine::get ( getCell() );
|
||||
if ( not kite ) {
|
||||
throw Error("KiteEngine not created yet, run the global router first.");
|
||||
}
|
||||
|
||||
emit cellPreModificated ();
|
||||
|
||||
_viewer->clearToolInterrupt ();
|
||||
|
||||
// kite->setSaturateRatio ( 0.85 );
|
||||
// kite->setExpandStep ( 0.20 );
|
||||
// kite->setRipupLimit ( 25, Configuration::BorderRipupLimit );
|
||||
// kite->setRipupLimit ( 15, Configuration::StrapRipupLimit );
|
||||
// kite->setRipupLimit ( 5, Configuration::LocalRipupLimit );
|
||||
// kite->setRipupLimit ( 5, Configuration::GlobalRipupLimit );
|
||||
// kite->setRipupLimit ( 5, Configuration::LongGlobalRipupLimit );
|
||||
// kite->setRipupCost ( 3 );
|
||||
kite->loadGlobalRouting ( Katabatic::LoadGrByNet, routingNets );
|
||||
emit cellPostModificated ();
|
||||
|
||||
//Breakpoint::stop ( 0, "Point d'arret:<br> <b>LayerAssingByTrunk()</b><br>"
|
||||
// "Assignment des layers, methode globale." );
|
||||
emit cellPreModificated ();
|
||||
kite->layerAssign ( Katabatic::NoNetLayerAssign );
|
||||
emit cellPostModificated ();
|
||||
|
||||
//Breakpoint::stop ( 0, "Point d'arret:<br> <b>runNegociate()</b><br>"
|
||||
// "Routage par Negociation." );
|
||||
emit cellPreModificated ();
|
||||
kite->runNegociate ();
|
||||
emit cellPostModificated ();
|
||||
}
|
||||
|
||||
|
||||
void GraphicKiteEngine::finalize ()
|
||||
{
|
||||
emit cellPreModificated ();
|
||||
KiteEngine* kite = KiteEngine::get ( getCell() );
|
||||
if ( kite ) {
|
||||
kite->finalizeLayout ();
|
||||
kite->destroy ();
|
||||
}
|
||||
emit cellPostModificated ();
|
||||
}
|
||||
|
||||
|
||||
void GraphicKiteEngine::save ()
|
||||
{
|
||||
//KiteEngine* kite = KiteEngine::get ( getCell() );
|
||||
//if ( kite ) {
|
||||
Cell* cell = getCell();
|
||||
AllianceFramework* af = AllianceFramework::get ();
|
||||
|
||||
string name = getString(cell->getName()) + "_kite";
|
||||
cell->setName ( name );
|
||||
af->saveCell ( cell, Catalog::State::Physical );
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
void GraphicKiteEngine::postEvent ()
|
||||
{
|
||||
static unsigned int count = 0;
|
||||
|
||||
if ( not (count++ % 500) ) {
|
||||
//UpdateSession::close ();
|
||||
|
||||
//_viewer->getCellWidget()->refresh ();
|
||||
QApplication::processEvents ();
|
||||
|
||||
//UpdateSession::open ();
|
||||
|
||||
if ( _viewer->isToolInterrupted() ) {
|
||||
KiteEngine* kite = KiteEngine::get ( getCell() );
|
||||
if ( kite ) kite->setInterrupt ( true );
|
||||
|
||||
_viewer->clearToolInterrupt ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GraphicKiteEngine::addToMenu ( CellViewer* viewer )
|
||||
{
|
||||
assert ( _viewer == NULL );
|
||||
|
||||
_viewer = viewer;
|
||||
|
||||
QMenu* prMenu = _viewer->findChild<QMenu*>("viewer.menuBar.placeAndRoute");
|
||||
QMenu* stepMenu = _viewer->findChild<QMenu*>("viewer.menuBar.placeAndRoute.stepByStep");
|
||||
if ( !prMenu ) {
|
||||
QMenuBar* menuBar = _viewer->findChild<QMenuBar*>("viewer.menuBar");
|
||||
if ( !menuBar ) {
|
||||
cerr << Warning("GraphicKiteEngine::addToMenu() - No MenuBar in parent widget.") << endl;
|
||||
return;
|
||||
}
|
||||
prMenu = menuBar->addMenu ( tr("P&&R") );
|
||||
prMenu->setObjectName ( "viewer.menuBar.placeAndRoute" );
|
||||
|
||||
stepMenu = prMenu->addMenu ( tr("&Step by Step") );
|
||||
stepMenu->setObjectName ( "viewer.menuBar.placeAndRoute.stepByStep" );
|
||||
|
||||
prMenu->addSeparator ();
|
||||
}
|
||||
|
||||
QAction* dRouteAction = _viewer->findChild<QAction*>("viewer.menuBar.placeAndRoute.detailedRoute");
|
||||
if ( dRouteAction )
|
||||
cerr << Warning("GraphicKiteEngine::addToMenu() - Kite detailed router already hooked in.") << endl;
|
||||
else {
|
||||
QAction* gLoadSolutionAction = new QAction ( tr("Kite - &Load Global Solution"), _viewer );
|
||||
gLoadSolutionAction->setObjectName ( "viewer.menuBar.placeAndRoute.stepByStep.loadSolution" );
|
||||
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 Solution"), _viewer );
|
||||
gSaveSolutionAction->setObjectName ( "viewer.menuBar.placeAndRoute.stepByStep.saveSolution" );
|
||||
gSaveSolutionAction->setStatusTip ( tr("Save a global router solution (.kgr)") );
|
||||
gSaveSolutionAction->setVisible ( true );
|
||||
stepMenu->addAction ( gSaveSolutionAction );
|
||||
|
||||
QAction* gRouteAction = new QAction ( tr("Kite - &Global Route"), _viewer );
|
||||
gRouteAction->setObjectName ( "viewer.menuBar.placeAndRoute.globalRoute" );
|
||||
gRouteAction->setStatusTip ( tr("Run the <b>Knik</b> global router") );
|
||||
gRouteAction->setVisible ( true );
|
||||
prMenu->addAction ( gRouteAction );
|
||||
|
||||
dRouteAction = new QAction ( tr("Kite - &Detailed Route"), _viewer );
|
||||
dRouteAction->setObjectName ( "viewer.menuBar.placeAndRoute.detailedRoute" );
|
||||
dRouteAction->setStatusTip ( tr("Run the <b>Kite</b> detailed router") );
|
||||
dRouteAction->setVisible ( true );
|
||||
prMenu->addAction ( dRouteAction );
|
||||
|
||||
QAction* dFinalizeAction = new QAction ( tr("Kite - &Finalize Routing"), _viewer );
|
||||
dFinalizeAction->setObjectName ( "viewer.menuBar.placeAndRoute.finalize" );
|
||||
dFinalizeAction->setStatusTip ( tr("Closing Routing") );
|
||||
dFinalizeAction->setVisible ( true );
|
||||
prMenu->addAction ( dFinalizeAction );
|
||||
|
||||
QAction* dSaveAction = new QAction ( tr("Kite - &Save Design"), _viewer );
|
||||
dSaveAction->setObjectName ( "viewer.menuBar.placeAndRoute.save" );
|
||||
dSaveAction->setStatusTip ( tr("Save routed design (temporary hack)") );
|
||||
dSaveAction->setVisible ( true );
|
||||
prMenu->addAction ( dSaveAction );
|
||||
|
||||
connect ( gLoadSolutionAction, SIGNAL(triggered()), this, SLOT(loadGlobalSolution()) );
|
||||
connect ( gSaveSolutionAction, SIGNAL(triggered()), this, SLOT(saveGlobalSolution()) );
|
||||
connect ( gRouteAction , SIGNAL(triggered()), this, SLOT(runGlobal ()) );
|
||||
connect ( dRouteAction , SIGNAL(triggered()), this, SLOT(runDetailed ()) );
|
||||
connect ( dFinalizeAction , SIGNAL(triggered()), this, SLOT(finalize ()) );
|
||||
connect ( dSaveAction , SIGNAL(triggered()), this, SLOT(save ()) );
|
||||
}
|
||||
|
||||
connect ( this, SIGNAL(cellPreModificated ()), _viewer->getCellWidget(), SLOT(cellPreModificate ()) );
|
||||
connect ( this, SIGNAL(cellPostModificated()), _viewer->getCellWidget(), SLOT(cellPostModificate()) );
|
||||
}
|
||||
|
||||
|
||||
const Name& GraphicKiteEngine::getName () const
|
||||
{
|
||||
return KiteEngine::staticGetName ();
|
||||
}
|
||||
|
||||
|
||||
Cell* GraphicKiteEngine::getCell ()
|
||||
{
|
||||
if ( !_viewer ) {
|
||||
throw Error ( "<b>Kite:</b> GraphicKiteEngine not bound to any Viewer." );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ( !_viewer->getCell() ) {
|
||||
throw Error ( "<b>Kite:</b> No Cell is loaded into the Viewer." );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return _viewer->getCell();
|
||||
}
|
||||
|
||||
|
||||
GraphicKiteEngine* GraphicKiteEngine::grab ()
|
||||
{
|
||||
if ( !_references ) {
|
||||
_singleton = new GraphicKiteEngine ();
|
||||
}
|
||||
_references++;
|
||||
|
||||
return _singleton;
|
||||
}
|
||||
|
||||
|
||||
size_t GraphicKiteEngine::release ()
|
||||
{
|
||||
_references--;
|
||||
if ( !_references ) {
|
||||
delete _singleton;
|
||||
_singleton = NULL;
|
||||
}
|
||||
return _references;
|
||||
}
|
||||
|
||||
|
||||
GraphicKiteEngine::GraphicKiteEngine ()
|
||||
: GraphicTool()
|
||||
, _viewer(NULL)
|
||||
{
|
||||
addDrawGo ( "Katabatic::Ac" , initKatabaticAc , drawKatabaticAc );
|
||||
addDrawGo ( "Katabatic::GCell", initKatabaticGCell, drawKatabaticGCell );
|
||||
}
|
||||
|
||||
|
||||
GraphicKiteEngine::~GraphicKiteEngine ()
|
||||
{ }
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,84 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./HorizontalTrack.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#include "kite/HorizontalTrack.h"
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "HorizontalTrack".
|
||||
|
||||
|
||||
HorizontalTrack::HorizontalTrack ( RoutingPlane* routingPlane, unsigned int index )
|
||||
: Track(routingPlane,index)
|
||||
{ }
|
||||
|
||||
|
||||
void HorizontalTrack::_postCreate ()
|
||||
{ }
|
||||
|
||||
|
||||
HorizontalTrack* HorizontalTrack::create ( RoutingPlane* routingPlane, unsigned int index )
|
||||
{
|
||||
HorizontalTrack* track = new HorizontalTrack ( routingPlane, index );
|
||||
|
||||
track->_postCreate ();
|
||||
return track;
|
||||
}
|
||||
|
||||
|
||||
HorizontalTrack::~HorizontalTrack ()
|
||||
{ }
|
||||
|
||||
|
||||
void HorizontalTrack::_preDestroy ()
|
||||
{ }
|
||||
|
||||
|
||||
bool HorizontalTrack::isHorizontal () const { return true; }
|
||||
bool HorizontalTrack::isVertical () const { return false; }
|
||||
unsigned int HorizontalTrack::getDirection () const { return Constant::Horizontal; }
|
||||
|
||||
|
||||
Point HorizontalTrack::getPosition ( DbU::Unit coordinate ) const
|
||||
{
|
||||
return Point ( coordinate, getAxis() );
|
||||
}
|
||||
|
||||
|
||||
string HorizontalTrack::_getTypeName () const
|
||||
{ return "HorizontalTrack"; }
|
||||
|
||||
|
||||
Record* HorizontalTrack::_getRecord () const
|
||||
{
|
||||
Record* record = Track::_getRecord ();
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,652 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./KiteEngine.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Warning.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 "knik/KnikEngine.h"
|
||||
#include "katabatic/AutoContact.h"
|
||||
#include "kite/DataNegociate.h"
|
||||
#include "kite/GCellGrid.h"
|
||||
#include "kite/RoutingPlane.h"
|
||||
#include "kite/Session.h"
|
||||
#include "kite/GCellRoutingSet.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::ostringstream;
|
||||
using std::setprecision;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::inltrace;
|
||||
using Hurricane::ltracein;
|
||||
using Hurricane::ltraceout;
|
||||
using Hurricane::ForEachIterator;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Layer;
|
||||
using Hurricane::Cell;
|
||||
using Knik::KnikEngine;
|
||||
|
||||
|
||||
const char* missingRW =
|
||||
"%s :\n\n"
|
||||
" Cell %s do not have any KiteEngine (or not yet created).\n";
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Kite::KiteEngine".
|
||||
|
||||
|
||||
Name KiteEngine::_toolName = "Kite";
|
||||
|
||||
|
||||
const Name& KiteEngine::staticGetName ()
|
||||
{ return _toolName; }
|
||||
|
||||
|
||||
KiteEngine* KiteEngine::get ( const Cell* cell )
|
||||
{
|
||||
return static_cast<KiteEngine*>(ToolEngine::get(cell,staticGetName()));
|
||||
}
|
||||
|
||||
|
||||
KiteEngine::KiteEngine ( const RoutingGauge* gauge, Cell* cell )
|
||||
: KatabaticEngine (gauge,cell)
|
||||
, _knik (NULL)
|
||||
, _obstacleNet (NULL)
|
||||
, _configuration (getKatabaticConfiguration())
|
||||
, _routingPlanes ()
|
||||
, _kiteGrid (NULL)
|
||||
, _negociateWindow (NULL)
|
||||
, _trackSegmentLut ()
|
||||
, _minimumWL (0.0)
|
||||
, _toolSuccess (false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void KiteEngine::_postCreate ()
|
||||
{
|
||||
KatabaticEngine::_postCreate ();
|
||||
|
||||
#ifdef KNIK_NOT_EMBEDDED
|
||||
size_t maxDepth = getRoutingGauge()->getDepth();
|
||||
|
||||
_kiteGrid = GCellGrid::create ( this );
|
||||
|
||||
_routingPlanes.reserve ( maxDepth );
|
||||
for ( size_t depth=0 ; depth < maxDepth ; depth++ ) {
|
||||
_routingPlanes.push_back ( RoutingPlane::create ( this, depth ) );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
KiteEngine* KiteEngine::create ( const RoutingGauge* gauge, Cell* cell )
|
||||
{
|
||||
KiteEngine* kite = new KiteEngine ( gauge, cell );
|
||||
|
||||
kite->_postCreate ();
|
||||
return kite;
|
||||
}
|
||||
|
||||
|
||||
void KiteEngine::_preDestroy ()
|
||||
{
|
||||
ltrace(90) << "KiteEngine::_preDestroy ()" << endl;
|
||||
ltracein(90);
|
||||
|
||||
cmess1 << " o Deleting ToolEngine<" << getName() << "> from Cell <"
|
||||
<< _cell->getName() << ">" << endl;
|
||||
|
||||
if ( getState() < Katabatic::StateGutted )
|
||||
setState ( Katabatic::StatePreDestroying );
|
||||
|
||||
_gutKite ();
|
||||
KatabaticEngine::_preDestroy ();
|
||||
|
||||
cmess2 << " - RoutingEvents := " << RoutingEvent::getAllocateds() << endl;
|
||||
|
||||
//_knik->destroy ();
|
||||
|
||||
ltraceout(90);
|
||||
}
|
||||
|
||||
|
||||
KiteEngine::~KiteEngine ()
|
||||
{ }
|
||||
|
||||
|
||||
const Name& KiteEngine::getName () const
|
||||
{ return _toolName; }
|
||||
|
||||
|
||||
Configuration* KiteEngine::getConfiguration ()
|
||||
{ return &_configuration; }
|
||||
|
||||
|
||||
unsigned int KiteEngine::getRipupLimit ( const TrackElement* segment ) const
|
||||
{
|
||||
if ( segment->isBlockage() ) return 0;
|
||||
|
||||
if ( segment->getDataNegociate() ) {
|
||||
if ( segment->getDataNegociate()->isBorder() )
|
||||
return _configuration.getRipupLimit(Configuration::BorderRipupLimit);
|
||||
|
||||
if ( segment->getDataNegociate()->isRing() )
|
||||
return _configuration.getRipupLimit(Configuration::GlobalRipupLimit);
|
||||
}
|
||||
|
||||
if ( segment->isStrap () ) return _configuration.getRipupLimit(Configuration::StrapRipupLimit);
|
||||
if ( segment->isGlobal() ) {
|
||||
vector<GCell*> gcells;
|
||||
segment->getGCells(gcells);
|
||||
if ( gcells.size() > 2 )
|
||||
return _configuration.getRipupLimit(Configuration::LongGlobalRipupLimit);
|
||||
return _configuration.getRipupLimit(Configuration::GlobalRipupLimit);
|
||||
}
|
||||
return _configuration.getRipupLimit(Configuration::LocalRipupLimit);
|
||||
}
|
||||
|
||||
|
||||
RoutingPlane* KiteEngine::getRoutingPlaneByIndex ( size_t index ) const
|
||||
{
|
||||
if ( index >= getRoutingPlanesSize() ) return NULL;
|
||||
|
||||
return _routingPlanes[index];
|
||||
}
|
||||
|
||||
|
||||
RoutingPlane* KiteEngine::getRoutingPlaneByLayer ( const Layer* layer ) const
|
||||
{
|
||||
for ( size_t index=0 ; index < getRoutingPlanesSize() ; index++ ) {
|
||||
if ( _routingPlanes[index]->getLayer() == layer )
|
||||
return _routingPlanes[index];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Track* KiteEngine::getTrackByPosition ( const Layer* layer, DbU::Unit axis, unsigned int mode ) const
|
||||
{
|
||||
RoutingPlane* plane = getRoutingPlaneByLayer ( layer );
|
||||
if ( !plane ) return NULL;
|
||||
|
||||
return plane->getTrackByPosition ( axis, mode );
|
||||
}
|
||||
|
||||
|
||||
void KiteEngine::setInterrupt ( bool state )
|
||||
{
|
||||
if ( _negociateWindow ) {
|
||||
_negociateWindow->setInterrupt ( state );
|
||||
cerr << "Interrupt [CRTL+C] of " << this << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KiteEngine::createGlobalGraph ( unsigned int mode )
|
||||
{
|
||||
Cell* cell = getCell();
|
||||
if ( not _knik ) {
|
||||
if ( cell->getRubbers().getFirst() == NULL )
|
||||
cell->flattenNets ( (mode==BuildGlobalSolution) );
|
||||
KnikEngine::setEdgeCapacityPercent ( getEdgeCapacityPercent() );
|
||||
_knik = KnikEngine::create ( cell
|
||||
, 1 // _congestion
|
||||
, 2 // _preCongestion
|
||||
, false // _benchMode
|
||||
, true // _useSegments
|
||||
, 2.5 // _edgeCost
|
||||
);
|
||||
//if ( mode == LoadGlobalSolution )
|
||||
_knik->createRoutingGraph ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KiteEngine::createDetailedGrid ()
|
||||
{
|
||||
KatabaticEngine::createDetailedGrid ();
|
||||
_kiteGrid = GCellGrid::create ( this );
|
||||
|
||||
size_t maxDepth = getRoutingGauge()->getDepth();
|
||||
|
||||
_routingPlanes.reserve ( maxDepth );
|
||||
for ( size_t depth=0 ; depth < maxDepth ; 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::StateGlobalLoaded )
|
||||
throw Error ("KiteEngine::saveGlobalSolution() : cannot save after detailed routing.");
|
||||
|
||||
_knik->saveSolution ();
|
||||
}
|
||||
|
||||
|
||||
void KiteEngine::annotateGlobalGraph ()
|
||||
{
|
||||
cmess1 << " o Back annotate global routing graph." << endl;
|
||||
|
||||
for ( size_t depth=0 ; depth<_routingPlanes.size() ; ++depth ) {
|
||||
RoutingPlane* rp = _routingPlanes[depth];
|
||||
if ( rp->getLayerGauge()->getType() == Constant::PinOnly ) continue;
|
||||
|
||||
size_t tracksSize = rp->getTracksSize();
|
||||
for ( size_t itrack=0 ; itrack<tracksSize ; ++itrack ) {
|
||||
Track* track = rp->getTrackByIndex ( itrack );
|
||||
TrackElement* element = track->getSegment ( (size_t)0 );
|
||||
|
||||
if ( element == NULL ) continue;
|
||||
if ( element->getNet() == NULL ) continue;
|
||||
if ( not element->getNet()->isSupply() ) continue;
|
||||
|
||||
cinfo << "Capacity from: " << element << endl;
|
||||
|
||||
if ( track->getDirection() == Constant::Horizontal ) {
|
||||
for ( ; element != NULL ; element = element->getNext() ) {
|
||||
GCell* gcell = _kiteGrid->getGCell ( Point(element->getSourceU(),track->getAxis()) );
|
||||
GCell* end = _kiteGrid->getGCell ( Point(element->getTargetU(),track->getAxis()) );
|
||||
GCell* right = NULL;
|
||||
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()
|
||||
, -1 );
|
||||
gcell = right;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for ( ; element != NULL ; element = element->getNext() ) {
|
||||
GCell* gcell = _kiteGrid->getGCell ( Point(track->getAxis(),element->getSourceU()) );
|
||||
GCell* end = _kiteGrid->getGCell ( Point(track->getAxis(),element->getTargetU()) );
|
||||
GCell* up = NULL;
|
||||
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()
|
||||
, -1 );
|
||||
|
||||
gcell = up;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KiteEngine::runGlobalRouter ( unsigned int mode )
|
||||
{
|
||||
if ( getState() >= Katabatic::StateGlobalLoaded )
|
||||
throw Error ("KiteEngine::runGlobalRouter() : global routing already done or loaded.");
|
||||
|
||||
Session::open ( this );
|
||||
|
||||
createGlobalGraph ( mode );
|
||||
createDetailedGrid ();
|
||||
buildBlockages ();
|
||||
buildPowerRails ();
|
||||
|
||||
if ( mode == LoadGlobalSolution ) {
|
||||
_knik->loadSolution ();
|
||||
} else {
|
||||
annotateGlobalGraph ();
|
||||
_knik->run ();
|
||||
}
|
||||
|
||||
setState ( Katabatic::StateGlobalLoaded );
|
||||
|
||||
Session::close ();
|
||||
}
|
||||
|
||||
|
||||
void KiteEngine::loadGlobalRouting ( unsigned int method, vector<Net*>& nets )
|
||||
{
|
||||
KatabaticEngine::loadGlobalRouting ( method, nets );
|
||||
|
||||
Session::open ( this );
|
||||
getGCellGrid()->checkEdgeSaturation ( getEdgeCapacityPercent() );
|
||||
Session::close ();
|
||||
}
|
||||
|
||||
|
||||
void KiteEngine::runNegociate ( unsigned int slowMotion )
|
||||
{
|
||||
if ( _negociateWindow ) return;
|
||||
|
||||
unsigned int rows = _kiteGrid->getRows();
|
||||
unsigned int columns = _kiteGrid->getColumns();
|
||||
|
||||
startMeasures ();
|
||||
|
||||
Session::open ( this );
|
||||
|
||||
cmess1 << " o Running Negociate Algorithm" << endl;
|
||||
|
||||
_negociateWindow = NegociateWindow::create ( this, 0, 0, columns, rows );
|
||||
_negociateWindow->loadRouting ();
|
||||
preProcess ();
|
||||
_computeCagedConstraints ();
|
||||
_negociateWindow->run ( slowMotion );
|
||||
_negociateWindow->printStatistics ();
|
||||
_negociateWindow->destroy ();
|
||||
_negociateWindow = NULL;
|
||||
|
||||
Session::close ();
|
||||
//if ( _editor ) _editor->refresh ();
|
||||
|
||||
stopMeasures ();
|
||||
printMeasures ();
|
||||
printCompletion ();
|
||||
|
||||
Session::open ( this );
|
||||
unsigned int overlaps = 0;
|
||||
float edgeCapacity = 1.0;
|
||||
KnikEngine* knik = KnikEngine::get ( getCell() );
|
||||
|
||||
if ( knik )
|
||||
edgeCapacity = knik->getEdgeCapacityPercent();
|
||||
|
||||
cmess2 << " o Post-checking Knik capacity overload " << (edgeCapacity*100.0) << "%." << endl;
|
||||
|
||||
_kiteGrid->base()->checkEdgeSaturation ( edgeCapacity );
|
||||
_check ( overlaps );
|
||||
Session::close ();
|
||||
|
||||
_toolSuccess = _toolSuccess and (overlaps == 0);
|
||||
}
|
||||
|
||||
|
||||
void KiteEngine::printCompletion () const
|
||||
{
|
||||
cout << " o Computing Completion ratios." << endl;
|
||||
cout << " - Unrouted segments :" << endl;
|
||||
|
||||
size_t routeds = 0;
|
||||
size_t unrouteds = 0;
|
||||
unsigned long long totalWireLength = 0;
|
||||
unsigned long long routedWireLength = 0;
|
||||
|
||||
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 ) {
|
||||
cerr << Error("KiteEngine::printCompletion(): Suspiciously long wire: %llu for %p:%s"
|
||||
,wl,ilut->first,getString(ilut->second).c_str()) << endl;
|
||||
continue;
|
||||
}
|
||||
totalWireLength += wl;
|
||||
if ( ilut->second->getTrack() != NULL ) {
|
||||
routeds++;
|
||||
routedWireLength += wl;
|
||||
} else {
|
||||
cout << " " << setw(4) << ++unrouteds << "| " << ilut->second << endl;
|
||||
}
|
||||
}
|
||||
|
||||
float segmentRatio = (float)(routeds) / (float)(_trackSegmentLut.size()) * 100.0;
|
||||
float wireLengthRatio = (float)(routedWireLength) / (float)(totalWireLength) * 100.0;
|
||||
|
||||
cout << " - Track Segment Completion Ratio := "
|
||||
<< setprecision(4) << segmentRatio
|
||||
<< "% [" << routeds << "/" << _trackSegmentLut.size() << "] "
|
||||
<< (_trackSegmentLut.size() - routeds) << " remains." << endl;
|
||||
cout << " - Wire Length Completion Ratio := "
|
||||
<< setprecision(4) << wireLengthRatio
|
||||
<< "% [" << totalWireLength << "] "
|
||||
<< (totalWireLength - routedWireLength) << " remains." << endl;
|
||||
|
||||
if ( _minimumWL != 0.0 ) {
|
||||
float expandRatio = totalWireLength / _minimumWL;
|
||||
cout << " - Wire Length Expand Ratio := "
|
||||
<< setprecision(4) << expandRatio
|
||||
<< "% [min:" << setprecision(9) << _minimumWL << "] "
|
||||
<< endl;
|
||||
}
|
||||
|
||||
_toolSuccess = (unrouteds == 0);
|
||||
}
|
||||
|
||||
|
||||
bool KiteEngine::_check ( unsigned int& overlap, const char* message ) const
|
||||
{
|
||||
cmess1 << " o Checking Kite Database coherency." << endl;
|
||||
|
||||
bool coherency = true;
|
||||
coherency = coherency && KatabaticEngine::_check ( message );
|
||||
for ( size_t i=0 ; i<_routingPlanes.size() ; i++ )
|
||||
coherency = _routingPlanes[i]->_check(overlap) && coherency;
|
||||
|
||||
Katabatic::Session* ktbtSession = Session::base ();
|
||||
forEach ( Net*, inet, getCell()->getNets() ) {
|
||||
forEach ( Segment*, isegment, inet->getComponents().getSubSet<Segment*>() ) {
|
||||
AutoSegment* autoSegment = ktbtSession->lookup ( *isegment );
|
||||
if ( !autoSegment ) continue;
|
||||
if ( !autoSegment->isCanonical() ) continue;
|
||||
|
||||
TrackElement* trackSegment = Session::lookup ( *isegment );
|
||||
if ( !trackSegment ) {
|
||||
coherency = false;
|
||||
cerr << Bug("%p %s whithout Track Segment"
|
||||
,autoSegment
|
||||
,getString(autoSegment).c_str()
|
||||
) << endl;
|
||||
} else
|
||||
trackSegment->_check ();
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(CHECK_DATABASE)
|
||||
//Session::getKiteEngine()->setInterrupt ( !coherency );
|
||||
#endif
|
||||
|
||||
return coherency;
|
||||
}
|
||||
|
||||
|
||||
void KiteEngine::finalizeLayout ()
|
||||
{
|
||||
ltrace(90) << "KiteEngine::finalizeLayout()" << endl;
|
||||
if ( getState() > Katabatic::StateDriving ) return;
|
||||
|
||||
ltracein(90);
|
||||
|
||||
setState ( Katabatic::StateDriving );
|
||||
_gutKite ();
|
||||
|
||||
KatabaticEngine::finalizeLayout ();
|
||||
ltrace(90) << "State: " << getState() << endl;
|
||||
|
||||
ltraceout(90);
|
||||
}
|
||||
|
||||
|
||||
void KiteEngine::_gutKite ()
|
||||
{
|
||||
ltrace(90) << "KiteEngine::_gutKite()" << endl;
|
||||
ltracein(90);
|
||||
ltrace(90) << "State: " << getState() << endl;
|
||||
|
||||
if ( getState() < Katabatic::StateGutted ) {
|
||||
Session::open ( this );
|
||||
|
||||
size_t maxDepth = getRoutingGauge()->getDepth();
|
||||
for ( size_t depth=0 ; depth < maxDepth ; depth++ ) {
|
||||
_routingPlanes[depth]->destroy ();
|
||||
}
|
||||
|
||||
_kiteGrid->destroy ();
|
||||
_kiteGrid = NULL;
|
||||
Session::close ();
|
||||
}
|
||||
|
||||
ltraceout(90);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
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 );
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
void KiteEngine::_check ( Net* net ) const
|
||||
{
|
||||
cerr << " o Checking " << net << endl;
|
||||
|
||||
forEach ( Segment*, isegment, net->getComponents().getSubSet<Segment*>() ) {
|
||||
TrackElement* trackSegment = _lookup ( *isegment );
|
||||
if ( trackSegment ) {
|
||||
trackSegment->_check ();
|
||||
|
||||
AutoContact* autoContact = trackSegment->base()->getAutoSource();
|
||||
if ( autoContact ) autoContact->checkTopology ();
|
||||
|
||||
autoContact = trackSegment->base()->getAutoTarget();
|
||||
if ( autoContact ) autoContact->checkTopology ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
string KiteEngine::_getTypeName () const
|
||||
{ return "Kite::KiteEngine"; }
|
||||
|
||||
|
||||
string KiteEngine::_getString () const
|
||||
{
|
||||
ostringstream os;
|
||||
|
||||
os << "<" << "KiteEngine "
|
||||
<< _cell->getName () << " "
|
||||
// << getString(_rg->getName())
|
||||
<< ">";
|
||||
|
||||
return os.str();
|
||||
}
|
||||
|
||||
|
||||
Record* KiteEngine::_getRecord () const
|
||||
{
|
||||
Record* record = KatabaticEngine::_getRecord ();
|
||||
|
||||
record->add ( getSlot ( "_routingPlanes", &_routingPlanes ) );
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,218 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./KiteMain.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#include <memory>
|
||||
using namespace std;
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
namespace poptions = boost::program_options;
|
||||
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "hurricane/DataBase.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/UpdateSession.h"
|
||||
#include "hurricane/viewer/HApplication.h"
|
||||
#include "hurricane/viewer/Graphics.h"
|
||||
using namespace Hurricane;
|
||||
|
||||
#include "crlcore/Utilities.h"
|
||||
#include "crlcore/AllianceFramework.h"
|
||||
#include "crlcore/Hierarchy.h"
|
||||
#include "crlcore/ToolBox.h"
|
||||
using namespace CRL;
|
||||
|
||||
#include "knik/KnikEngine.h"
|
||||
using namespace Knik;
|
||||
|
||||
#include "kite/KiteEngine.h"
|
||||
using namespace Kite;
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Function : "printHelp()".
|
||||
|
||||
void printHelp ()
|
||||
{
|
||||
cout << endl;
|
||||
cout << "Usage: kite [-v|--verbose] [-V|--very-verbose] [-D|--core-dump] \\\n"
|
||||
<< " [-l|--trace-level <traceLevel>] [-c|--cell <cellName>] \\\n"
|
||||
<< endl;
|
||||
cout << "Options:\n"
|
||||
<< " o [-v|--verbose] : First level of verbosity.\n"
|
||||
<< " o [-V|--very-verbose] : Second level of verbosity (very talkative).\n"
|
||||
<< " o [-D|--core-dump] : Enable core dumping.\n"
|
||||
<< " o [-l|--trace-level <traceLevel>] :\n"
|
||||
<< " Sets the level of trace, trace messages with a level superior to\n"
|
||||
<< " <traceLevel> will be printed on <stderr>.\n"
|
||||
<< " o [-c|--cell <cellName>] :\n"
|
||||
<< " The name of the Cell to load, without extention.\n"
|
||||
<< endl;
|
||||
}
|
||||
|
||||
|
||||
} // End of anonymous namespace.
|
||||
|
||||
|
||||
|
||||
|
||||
// x-----------------------------------------------------------------x
|
||||
// | Fonctions Definitions |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Function : "main()".
|
||||
|
||||
int main ( int argc, char *argv[] )
|
||||
{
|
||||
int returnCode = 0;
|
||||
bool kiteSuccess = false;
|
||||
|
||||
try {
|
||||
float edgeCapacity;
|
||||
unsigned int traceLevel;
|
||||
bool verbose1;
|
||||
bool verbose2;
|
||||
bool info;
|
||||
bool coreDump;
|
||||
bool logMode;
|
||||
bool loadGlobal;
|
||||
bool saveDesign;
|
||||
|
||||
poptions::options_description options ("Command line arguments & options");
|
||||
options.add_options()
|
||||
( "help,h" , "Print this help." )
|
||||
( "verbose,v" , poptions::bool_switch(&verbose1)->default_value(false)
|
||||
, "First level of verbosity.")
|
||||
( "very-verbose,V", poptions::bool_switch(&verbose2)->default_value(false)
|
||||
, "Second level of verbosity.")
|
||||
( "info,i" , poptions::bool_switch(&info)->default_value(false)
|
||||
, "Lots of informational messages.")
|
||||
( "core-dump,D" , poptions::bool_switch(&coreDump)->default_value(false)
|
||||
, "Enable core dumping.")
|
||||
( "log-mode,L" , poptions::bool_switch(&logMode)->default_value(false)
|
||||
, "Disable ANSI escape sequences displaying.")
|
||||
( "global,g" , poptions::bool_switch(&loadGlobal)->default_value(false)
|
||||
, "Reload the global routing from disk.")
|
||||
( "trace-level,l" , poptions::value<unsigned int>(&traceLevel)->default_value(1000)
|
||||
, "Set the level of trace, trace messages with a level superior to "
|
||||
"<arg> will be printed on <stderr>." )
|
||||
( "edge,e" , poptions::value<float>(&edgeCapacity)->default_value(65.0)
|
||||
, "The egde density ratio applied on global router's edges." )
|
||||
( "cell,c" , poptions::value<string>()
|
||||
, "The name of the cell to load, whithout extension." )
|
||||
( "save,s" , poptions::bool_switch(&saveDesign)->default_value(false)
|
||||
, "Save the routed design.");
|
||||
|
||||
poptions::variables_map arguments;
|
||||
poptions::store ( poptions::parse_command_line(argc,argv,options), arguments );
|
||||
poptions::notify ( arguments );
|
||||
|
||||
if ( arguments.count("help") or not arguments.count("cell") ) {
|
||||
cout << options << endl;
|
||||
exit ( 0 );
|
||||
}
|
||||
|
||||
System::getSystem()->setCatchCore ( not coreDump );
|
||||
|
||||
if ( verbose1 ) mstream::enable ( mstream::VerboseLevel1 );
|
||||
if ( verbose2 ) mstream::enable ( mstream::VerboseLevel2 );
|
||||
if ( info ) mstream::enable ( mstream::Info );
|
||||
if ( logMode ) tty::disable ();
|
||||
|
||||
ltracelevel ( traceLevel );
|
||||
|
||||
dbo_ptr<DataBase> db ( DataBase::create() );
|
||||
dbo_ptr<AllianceFramework> af ( AllianceFramework::create() );
|
||||
Cell* cell = NULL;
|
||||
|
||||
if ( arguments.count("cell") ) {
|
||||
cell = af->getCell (arguments["cell"].as<string>().c_str(), Catalog::State::Views );
|
||||
if (!cell) {
|
||||
cerr << af->getPrint() << endl;
|
||||
cerr << "[ERROR] Cell not found: " << arguments["cell"].as<string>() << endl;
|
||||
exit ( 2 );
|
||||
}
|
||||
}
|
||||
|
||||
//KnikEngine::setEdgeCapacityPercent ( edgeCapacity );
|
||||
Kite::Configuration::setDefaultEdgeCapacity ( edgeCapacity );
|
||||
|
||||
cell->flattenNets ( not arguments.count("global") );
|
||||
|
||||
KnikEngine* knik = KnikEngine::create ( cell );
|
||||
if ( not loadGlobal ) {
|
||||
knik->run ();
|
||||
} else {
|
||||
knik->createRoutingGraph ();
|
||||
knik->loadSolution ();
|
||||
}
|
||||
|
||||
static vector<Net*> routingNets;
|
||||
KiteEngine* kite = KiteEngine::create ( af->getRoutingGauge(), cell );
|
||||
// kite->setSaturateRatio ( 0.85 );
|
||||
// kite->setExpandStep ( 0.20 );
|
||||
// kite->setRipupCost ( 3 );
|
||||
// kite->setRipupLimit ( 25, Configuration::BorderRipupLimit );
|
||||
// kite->setRipupLimit ( 15, Configuration::StrapRipupLimit );
|
||||
// kite->setRipupLimit ( 5, Configuration::LocalRipupLimit );
|
||||
// kite->setRipupLimit ( 5, Configuration::GlobalRipupLimit );
|
||||
// kite->setRipupLimit ( 5, Configuration::LongGlobalRipupLimit );
|
||||
kite->runGlobalRouter ( Kite::LoadGlobalSolution );
|
||||
kite->loadGlobalRouting ( Katabatic::LoadGrByNet, routingNets );
|
||||
kite->layerAssign ( Katabatic::NoNetLayerAssign );
|
||||
kite->runNegociate ();
|
||||
kiteSuccess = kite->getToolSuccess ();
|
||||
kite->finalizeLayout ();
|
||||
kite->destroy ();
|
||||
knik->destroy ();
|
||||
|
||||
if ( saveDesign ) {
|
||||
string name = getString(cell->getName()) + "_kite";
|
||||
cell->setName ( name );
|
||||
af->saveCell ( cell, Catalog::State::Physical );
|
||||
}
|
||||
|
||||
returnCode = (kiteSuccess) ? 0 : 1;
|
||||
}
|
||||
catch ( poptions::error& e ) {
|
||||
cerr << "[ERROR] " << e.what() << endl;
|
||||
exit ( 1 );
|
||||
}
|
||||
catch ( Error& e ) {
|
||||
cerr << e.what() << endl;
|
||||
exit ( 1 );
|
||||
}
|
||||
catch ( ... ) {
|
||||
cout << "[ERROR] Abnormal termination: unmanaged exception.\n" << endl;
|
||||
exit ( 2 );
|
||||
}
|
||||
|
||||
return returnCode;
|
||||
}
|
|
@ -0,0 +1,560 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./NegociateWindow.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "crlcore/AllianceFramework.h"
|
||||
|
||||
#include "kite/DataNegociate.h"
|
||||
#include "kite/TrackElement.h"
|
||||
#include "kite/TrackMarker.h"
|
||||
#include "kite/TrackCost.h"
|
||||
#include "kite/Track.h"
|
||||
#include "kite/RoutingPlane.h"
|
||||
#include "kite/GCellGrid.h"
|
||||
#include "kite/GCellRoutingSet.h"
|
||||
#include "kite/RoutingEventQueue.h"
|
||||
#include "kite/RoutingEventHistory.h"
|
||||
#include "kite/NegociateWindow.h"
|
||||
#include "kite/KiteEngine.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace Hurricane;
|
||||
using namespace CRL;
|
||||
using namespace Kite;
|
||||
|
||||
|
||||
void NegociateOverlapCost ( const TrackElement* segment, TrackCost& cost )
|
||||
{
|
||||
Interval intersect = segment->getCanonicalInterval();
|
||||
|
||||
if ( not intersect.intersect ( cost.getInterval() ) ) return;
|
||||
|
||||
if ( segment->isBlockage() ) {
|
||||
//ltrace(200) << "Infinite cost from: " << segment << endl;
|
||||
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 ( not intersect.contains(cost.getInterval()) )
|
||||
intersect.intersection ( cost.getInterval() );
|
||||
|
||||
DataNegociate* data = segment->getDataNegociate ();
|
||||
if ( not data ) return;
|
||||
|
||||
if ( data->getGCellOrder() >= Session::getOrder() ) {
|
||||
cost.mergeRipupCount ( data->getRipupCount() );
|
||||
if ( segment->isLocal() ) {
|
||||
cost.mergeDataState ( data->getState() );
|
||||
if ( data->getState() >= DataNegociate::LocalVsGlobal ) {
|
||||
ltrace(200) << "MaximumSlack/LocalVsGlobal for " << segment << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( /*(data->getGCellOrder() < Session::getOrder()) ||*/ segment->isFixed() ) {
|
||||
ltrace(200) << "Infinite cost from: " << segment << endl;
|
||||
cost.setFixed ();
|
||||
cost.setInfinite ();
|
||||
cost.setOverlap ();
|
||||
cost.setHardOverlap ();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ( data->getGCellOrder() < Session::getOrder() )
|
||||
or ( ( data->getCost().getRightMinExtend() >= cost.getInterval().getVMin() )
|
||||
and ( data->getCost().getLeftMinExtend () <= cost.getInterval().getVMax() ) ) )
|
||||
cost.setHardOverlap ();
|
||||
|
||||
cost.setOverlap ();
|
||||
cost.incTerminals ( data->getCost().getTerminals()*100 );
|
||||
cost.incDelta ( intersect.getSize() );
|
||||
}
|
||||
|
||||
|
||||
void loadRoutingPads ( NegociateWindow* nw )
|
||||
{
|
||||
AllianceFramework* af = AllianceFramework::get ();
|
||||
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->isOBSTACLE(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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // End of local namespace.
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::setw;
|
||||
using std::left;
|
||||
using std::right;
|
||||
using std::setprecision;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::inltrace;
|
||||
using Hurricane::ltracein;
|
||||
using Hurricane::ltraceout;
|
||||
using Hurricane::ForEachIterator;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "NegociateWindow::RingSegment".
|
||||
|
||||
|
||||
bool NegociateWindow::RingSegment::orderReached ( const NegociateWindow::RingSegment& segment )
|
||||
{
|
||||
return ( segment.getOrder() <= Session::getOrder() );
|
||||
}
|
||||
|
||||
|
||||
|
||||
NegociateWindow::RingSegment::RingSegment ( TrackElement* segment )
|
||||
: _segment(segment), _order(0)
|
||||
{
|
||||
DataNegociate* data = segment->getDataNegociate ();
|
||||
if ( data ) _order = data->getGCellOrder ();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "NegociateWindow".
|
||||
|
||||
|
||||
NegociateWindow::NegociateWindow ( KiteEngine* kite
|
||||
, unsigned int columnMin
|
||||
, unsigned int rowMin
|
||||
, unsigned int columnMax
|
||||
, unsigned int rowMax
|
||||
)
|
||||
: _slowMotion (0)
|
||||
, _interrupt (false)
|
||||
, _kite (kite)
|
||||
, _gridBox (NULL)
|
||||
, _criticalGCells ()
|
||||
, _gcellOrder (0)
|
||||
, _gcellRoutingSets()
|
||||
, _eventQueue ()
|
||||
, _eventHistory ()
|
||||
, _ring ()
|
||||
{
|
||||
_gridBox = GridBox<GCell>::create ( _kite->getGCellGrid()
|
||||
, columnMin
|
||||
, rowMin
|
||||
, columnMax
|
||||
, rowMax
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
NegociateWindow* NegociateWindow::create ( KiteEngine* kite
|
||||
, unsigned int columnMin
|
||||
, unsigned int rowMin
|
||||
, unsigned int columnMax
|
||||
, unsigned int rowMax
|
||||
)
|
||||
{
|
||||
NegociateWindow* negociateWindow = new NegociateWindow ( kite
|
||||
, columnMin
|
||||
, rowMin
|
||||
, columnMax
|
||||
, rowMax
|
||||
);
|
||||
return negociateWindow;
|
||||
}
|
||||
|
||||
|
||||
NegociateWindow::~NegociateWindow ()
|
||||
{
|
||||
for ( size_t i=0 ; i<_gcellRoutingSets.size() ; i++ )
|
||||
_gcellRoutingSets[i]->destroy ();
|
||||
|
||||
if ( _gridBox ) delete _gridBox;
|
||||
}
|
||||
|
||||
|
||||
void NegociateWindow::destroy ()
|
||||
{ delete this; }
|
||||
|
||||
|
||||
Cell* NegociateWindow::getCell () const
|
||||
{ return _kite->getCell(); }
|
||||
|
||||
|
||||
void NegociateWindow::addToRing ( TrackElement* segment )
|
||||
{
|
||||
ltrace(200) << "addToRing: " << segment << endl;
|
||||
|
||||
_ring.push_back ( RingSegment(segment) );
|
||||
|
||||
DataNegociate* data = segment->getDataNegociate ();
|
||||
data->setRing ( true );
|
||||
data->setGCellOrder ( Session::getOrder() );
|
||||
|
||||
_eventQueue.add ( segment, 0 );
|
||||
}
|
||||
|
||||
|
||||
void NegociateWindow::loadRouting ()
|
||||
{
|
||||
vector<GCell*> gcells;
|
||||
GCellGrid* grid = getKiteEngine()->getGCellGrid();
|
||||
|
||||
forEach ( GCell*, igcell, grid->getGCells() ) {
|
||||
gcells.push_back ( *igcell );
|
||||
igcell->updateDensity ();
|
||||
}
|
||||
|
||||
sort ( gcells.begin(), gcells.end(), GCell::CompareByDensity() );
|
||||
|
||||
#if defined(CHECK_DETERMINISM)
|
||||
cerr << "Order: After sort<>" << endl;
|
||||
for ( size_t i=0 ; i < gcells.size() ; i++ ) {
|
||||
cerr << "Order: "
|
||||
<< setw(9) << left << setprecision(6) << gcells[i]->base()->getDensity()
|
||||
<< setw(5) << right << gcells[i]->getIndex()
|
||||
<< " " << gcells[i] << endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned int order = 0;
|
||||
for ( size_t i=0 ; i < gcells.size() ; i++ ) {
|
||||
if ( !gcells[i]->isInRoutingSet() ) {
|
||||
Session::setOrder ( order );
|
||||
GCellRoutingSet* rs = GCellRoutingSet::create ( gcells[i], _kite->getExpandStep() );
|
||||
rs->expand ( grid );
|
||||
rs->loadRouting ( order );
|
||||
|
||||
_gcellRoutingSets.push_back ( rs );
|
||||
}
|
||||
}
|
||||
|
||||
loadRoutingPads ( this );
|
||||
Session::revalidate ();
|
||||
|
||||
TrackElement* segment;
|
||||
TrackElementLut lut = Session::getKiteEngine()->_getTrackElementLut();
|
||||
TrackElementLut::iterator it = lut.begin ();
|
||||
for ( ; it != lut.end() ; it++ ) {
|
||||
segment = it->second;
|
||||
segment->getDataNegociate()->update();
|
||||
}
|
||||
|
||||
getKiteEngine()->setMinimumWL ( grid->getTotalWireLength() );
|
||||
|
||||
#if defined(CHECK_DATABASE)
|
||||
unsigned int overlaps = 0;
|
||||
Session::getKiteEngine()->_check(overlaps,"after LoadRouting");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void NegociateWindow::addInsertEvent ( TrackElement* segment, unsigned int level )
|
||||
{
|
||||
DataNegociate* data = segment->getDataNegociate();
|
||||
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()
|
||||
) << endl;
|
||||
}
|
||||
|
||||
|
||||
void NegociateWindow::_unloadRing ()
|
||||
{
|
||||
_ring.erase ( remove_if(_ring.begin(),_ring.end(),RingSegment::orderReached), _ring.end() );
|
||||
for ( size_t i=0 ; i<_ring.size() ; ++i ) {
|
||||
if ( _ring[i].getSegment()->getTrack() != NULL )
|
||||
Session::addRemoveEvent ( _ring[i].getSegment() );
|
||||
}
|
||||
|
||||
Session::revalidate ();
|
||||
}
|
||||
|
||||
|
||||
void NegociateWindow::_loadRing ()
|
||||
{
|
||||
unsigned int order = Session::getOrder ();
|
||||
for ( size_t i=0 ; i<_ring.size() ; i++ ) {
|
||||
TrackElement* segment = _ring[i].getSegment();
|
||||
DataNegociate* data = segment->getDataNegociate ();
|
||||
|
||||
data->resetRipupCount ();
|
||||
data->setGCellOrder ( order );
|
||||
if ( _ring[i].getOrder() == order ) {
|
||||
ltrace(200) << "Removing from ring: " << segment << endl;
|
||||
data->setRing ( false );
|
||||
}
|
||||
|
||||
_eventQueue.add ( segment, 0 );
|
||||
}
|
||||
_eventQueue.commit ();
|
||||
}
|
||||
|
||||
|
||||
size_t NegociateWindow::_negociate ( const vector<TrackElement*>& segments )
|
||||
{
|
||||
ltrace(150) << "NegociateWindow::_negociate() - " << segments.size() << endl;
|
||||
ltracein(149);
|
||||
|
||||
_eventHistory.clear();
|
||||
_eventQueue.load ( segments );
|
||||
_loadRing ();
|
||||
|
||||
size_t count = 0;
|
||||
while ( not _eventQueue.empty() and not isInterrupted() ) {
|
||||
RoutingEvent* event = _eventQueue.pop ();
|
||||
|
||||
event->process ( _eventQueue, _eventHistory );
|
||||
if (tty::enabled()) {
|
||||
cmess1 << " <FirstPass:Negociation - event:" << tty::bold << setw(7) << setfill('0')
|
||||
<< RoutingEvent::getProcesseds() << setfill(' ') << tty::reset << ">" << tty::cr;
|
||||
cmess1.flush ();
|
||||
} else {
|
||||
cmess2 << " <FirstPass:Negociation - event:" << setw(7) << setfill('0')
|
||||
<< RoutingEvent::getProcesseds() << setfill(' ') << "> "
|
||||
<< event->getSegment()->getNet()->getName()
|
||||
<< endl;
|
||||
cmess2.flush();
|
||||
}
|
||||
|
||||
if ( RoutingEvent::getProcesseds() >= /*10471*/ 1000000 ) setInterrupt ( true );
|
||||
count++;
|
||||
|
||||
#if ENABLE_STIFFNESS
|
||||
if ( not (RoutingEvent::getProcesseds() % 1000) ) {
|
||||
sort ( _criticalGCells.begin(), _criticalGCells.end(), GCell::CompareByStiffness() );
|
||||
for ( size_t igcell=0 ; igcell<_criticalGCells.size() ; ++igcell ) {
|
||||
if ( _criticalGCells[igcell]->getStiffness () < 0.7 ) break;
|
||||
if ( _criticalGCells[igcell]->getSegmentCount() < 20 ) continue;
|
||||
|
||||
cerr << " - Anticipate: " << _criticalGCells[igcell]
|
||||
<< ":" << _criticalGCells[igcell]->getStiffness() << endl;
|
||||
|
||||
_criticalGCells[igcell]->anticipateRouting ( Session::getOrder() );
|
||||
_eventQueue.load ( _criticalGCells[igcell]->getOwnedSegments() );
|
||||
_criticalGCells[igcell]->setRouted ( true );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if (count and tty::enabled()) cmess1 << endl;
|
||||
count = 0;
|
||||
|
||||
ltrace(200) << "Dumping history." << endl;
|
||||
for ( size_t i=0 ; (i<_eventHistory.size()) && !isInterrupted() ; i++ ) {
|
||||
RoutingEvent* event = _eventHistory.getNth(i);
|
||||
ltrace(200) << (void*)event << " ["
|
||||
<< (event->isCloned ()?"C":"-")
|
||||
<< (event->isDisabled ()?"d":"-")
|
||||
<< (event->isUnimplemented()?"u":"-") << "] "
|
||||
<< event->getSegment() << endl;
|
||||
if ( !event->isCloned() and event->isUnimplemented() ) {
|
||||
count++;
|
||||
event->setProcessed ( false );
|
||||
event->setMode ( RoutingEvent::PostPack );
|
||||
event->process ( _eventQueue, _eventHistory );
|
||||
|
||||
if (tty::enabled()) {
|
||||
cmess1 << " <SecondPass:Packing - event:" << tty::fgcolor(tty::Red) << setw(7) << setfill('0')
|
||||
<< RoutingEvent::getProcesseds() << setfill(' ') << tty::reset << ">" << tty::cr;
|
||||
cmess1.flush ();
|
||||
} else {
|
||||
cmess1 << " <SecondPass:Packing - event:" << setw(7) << setfill('0')
|
||||
<< RoutingEvent::getProcesseds() << setfill(' ') << ">" << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (count and tty::enabled()) cmess1 << endl;
|
||||
|
||||
size_t eventsCount = _eventHistory.size();
|
||||
|
||||
_unloadRing ();
|
||||
_eventHistory.clear();
|
||||
_eventQueue.clear();
|
||||
|
||||
if ( RoutingEvent::getAllocateds() > 0 ) {
|
||||
cerr << Bug("%d events remains after clear.",RoutingEvent::getAllocateds()) << endl;
|
||||
}
|
||||
|
||||
// if ( _slowMotion && getCellWidget() ) {
|
||||
// Session::close ();
|
||||
// getCellWidget()->refresh();
|
||||
// Session::open ( _kiteEngine );
|
||||
// }
|
||||
|
||||
ltraceout(149);
|
||||
|
||||
return eventsCount;
|
||||
}
|
||||
|
||||
|
||||
void NegociateWindow::_runOnGCellRoutingSet ( GCellRoutingSet* rs )
|
||||
{
|
||||
#if defined(CHECK_DETERMINISM)
|
||||
cerr << "Order: Routing set: " << rs << endl;
|
||||
#endif
|
||||
|
||||
ltrace(200) << "Routing " << rs << endl;
|
||||
ltracein(200);
|
||||
|
||||
cmess1 << " - Routing " << rs << endl;
|
||||
|
||||
vector<GCell*> gcells = rs->getGCells ();
|
||||
for ( size_t i=0 ; i<gcells.size() ; i++ ) {
|
||||
ltrace(200) << gcells[i] << endl;
|
||||
#if defined(CHECK_DETERMINISM)
|
||||
cerr << "Order: GCell: " << gcells[i] << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
Session::setOrder ( rs->getOrder() );
|
||||
|
||||
vector<TrackElement*> segments;
|
||||
rs->loadBorder ( getKiteEngine()->getGCellGrid() );
|
||||
rs->getOwnedSegments ( segments );
|
||||
rs->setRouted ( true );
|
||||
rs->getStatistics ().setEventsCount ( _negociate(segments) );
|
||||
rs->freeBorder ();
|
||||
|
||||
ltraceout(200);
|
||||
}
|
||||
|
||||
|
||||
void NegociateWindow::run ( int slowMotion )
|
||||
{
|
||||
ltrace(150) << "NegociateWindow::run()" << endl;
|
||||
ltracein(149);
|
||||
|
||||
_criticalGCells = *(getKiteEngine()->getGCellGrid()->getGCellVector());
|
||||
|
||||
TrackElement::setOverlapCostCB ( NegociateOverlapCost );
|
||||
RoutingEvent::resetProcesseds ();
|
||||
|
||||
// sort ( gcells.begin(), gcells.end(), GCell::CompareByStiffness() );
|
||||
// for ( size_t j=0 ; j<gcells.size() ; ++j ) {
|
||||
// cerr << " INITIAL stiff: " << gcells[j] << ":" << gcells[j]->getStiffness() << endl;
|
||||
// }
|
||||
|
||||
_slowMotion = slowMotion;
|
||||
_gcellOrder = 0;
|
||||
for ( size_t i=0 ; (i<_gcellRoutingSets.size()) && !isInterrupted() ; i++ ) {
|
||||
_runOnGCellRoutingSet ( _gcellRoutingSets[i] );
|
||||
|
||||
// sort ( gcells.begin(), gcells.end(), GCell::CompareByStiffness() );
|
||||
// for ( size_t j=0 ; j<gcells.size() ; ++j ) {
|
||||
// cerr << " stiff: " << gcells[j] << ":" << gcells[j]->getStiffness() << endl;
|
||||
// }
|
||||
}
|
||||
|
||||
Session::get()->isEmpty();
|
||||
|
||||
# if defined(CHECK_DATABASE)
|
||||
unsigned int overlaps = 0;
|
||||
_kite->_check ( overlaps, "after negociation" );
|
||||
# endif
|
||||
|
||||
ltraceout(149);
|
||||
}
|
||||
|
||||
|
||||
void NegociateWindow::printStatistics () const
|
||||
{
|
||||
cout << " o Computing statistics." << endl;
|
||||
|
||||
Statistics globalStatistics;
|
||||
size_t biggestEventsCount = 0;
|
||||
size_t biggestRSsize = 0;
|
||||
for ( size_t i=0; i<_gcellRoutingSets.size() ; i++ ) {
|
||||
Statistics& statistics = _gcellRoutingSets[i]->getStatistics();
|
||||
globalStatistics += statistics;
|
||||
|
||||
if ( statistics.getEventsCount() > biggestEventsCount )
|
||||
biggestEventsCount = statistics.getEventsCount();
|
||||
|
||||
if ( _gcellRoutingSets[i]->getGCells().size() > biggestRSsize )
|
||||
biggestRSsize = _gcellRoutingSets[i]->getGCells().size();
|
||||
}
|
||||
|
||||
cout << " - Processeds Events Total := " << RoutingEvent::getProcesseds() << endl;
|
||||
cout << " - Unique Events Total := " << (RoutingEvent::getProcesseds() - RoutingEvent::getCloneds()) << endl;
|
||||
cout << " - Biggest Events Chunk := " << biggestEventsCount << endl;
|
||||
cout << " - Biggest Routing Set := " << biggestRSsize << endl;
|
||||
}
|
||||
|
||||
|
||||
string NegociateWindow::_getString () const
|
||||
{
|
||||
ostringstream os;
|
||||
|
||||
os << "<" << _getTypeName() << _gridBox << ">";
|
||||
return ( os.str() );
|
||||
}
|
||||
|
||||
|
||||
Record* NegociateWindow::_getRecord () const
|
||||
{
|
||||
Record* record = new Record ( _getString() );
|
||||
|
||||
record->add ( getSlot ( "_gridBox" , _gridBox ) );
|
||||
return ( record );
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,319 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./PreProcess.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#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/GCell.h"
|
||||
#include "kite/DataNegociate.h"
|
||||
#include "kite/TrackElement.h"
|
||||
#include "kite/Track.h"
|
||||
#include "kite/RoutingPlane.h"
|
||||
#include "kite/Session.h"
|
||||
#include "kite/KiteEngine.h"
|
||||
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace Hurricane;
|
||||
using namespace CRL;
|
||||
using namespace Kite;
|
||||
|
||||
|
||||
void getPerpandiculars ( TrackElement* segment
|
||||
, AutoContact* from
|
||||
, unsigned int direction
|
||||
, vector<TrackElement*>& perpandiculars
|
||||
)
|
||||
{
|
||||
//AutoContact* to = segment->base()->getAutoSource();
|
||||
//to = (to != from) ? to : segment->base()->getAutoTarget();
|
||||
|
||||
TrackElement* perpandicular;
|
||||
forEach ( Segment*, isegment, segment->base()->getAutoSource()->getSlaveComponents().getSubSet<Segment*>() ) {
|
||||
perpandicular = Session::lookup ( *isegment );
|
||||
ltrace(200) << "S " << perpandicular << endl;
|
||||
|
||||
if ( not perpandicular or (perpandicular->getDirection() == direction) ) continue;
|
||||
|
||||
perpandiculars.push_back ( perpandicular );
|
||||
}
|
||||
|
||||
forEach ( Segment*, isegment, segment->base()->getAutoTarget()->getSlaveComponents().getSubSet<Segment*>() ) {
|
||||
perpandicular = Session::lookup ( *isegment );
|
||||
ltrace(200) << "T " << perpandicular << endl;
|
||||
|
||||
if ( not perpandicular or (perpandicular->getDirection() == direction) ) continue;
|
||||
|
||||
perpandiculars.push_back ( perpandicular );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void propagateCagedConstraints ( TrackElement* segment )
|
||||
{
|
||||
if ( not segment->isFixed() ) return;
|
||||
|
||||
ltrace(200) << "Propagate caging: " << segment << endl;
|
||||
|
||||
Track* track = segment->getTrack();
|
||||
unsigned int direction = Session::getRoutingGauge()->getLayerDirection(segment->getLayer());
|
||||
AutoContact* source = segment->base()->getAutoSource();
|
||||
Interval uside = source->getGCell()->getUSide(direction);
|
||||
DbU::Unit minConstraint = DbU::Min;
|
||||
DbU::Unit maxConstraint = DbU::Max;
|
||||
vector<TrackElement*> perpandiculars;
|
||||
|
||||
if ( not track ) {
|
||||
cerr << Bug("%s is not inserted in a <Track>",getString(segment).c_str()) << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Computing constraints from fixed only TrackElements (caging).
|
||||
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;
|
||||
|
||||
ltrace(200) << "Min Constraint from: " << parallel << endl;
|
||||
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;
|
||||
|
||||
ltrace(200) << "Max Constraint from: " << parallel << endl;
|
||||
maxConstraint = min ( maxConstraint, parallel->getSourceU() );
|
||||
}
|
||||
|
||||
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()) ) {
|
||||
ltrace(200) << "No constraints [" << DbU::getValueString(minConstraint)
|
||||
<< ":" << DbU::getValueString(maxConstraint)
|
||||
<< " vs. " << uside << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Finding perpandiculars, by way of the source & target RoutingPad.
|
||||
if ( source->getAnchor() ) {
|
||||
RoutingPad* rp = dynamic_cast<RoutingPad*>(source->getAnchor());
|
||||
if ( rp ) {
|
||||
TrackElement* parallel;
|
||||
forEach ( Segment*, isegment, rp->getSlaveComponents().getSubSet<Segment*>() ) {
|
||||
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 );
|
||||
}
|
||||
} else {
|
||||
cerr << Bug("%s is not anchored on a <RoutingPad>\n (%s)"
|
||||
,getString(source).c_str()
|
||||
,getString(source->getAnchor()).c_str()) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply caging constraints to perpandiculars.
|
||||
ltracein(200);
|
||||
if ( perpandiculars.size() == 0 ) {
|
||||
ltrace(200) << "No perpandiculars to " << segment << endl;
|
||||
}
|
||||
|
||||
Interval constraints ( minConstraint, maxConstraint );
|
||||
for ( size_t iperpand=0 ; iperpand<perpandiculars.size() ; iperpand++ ) {
|
||||
ltrace(200) << "Caged: " << constraints << " " << perpandiculars[iperpand] << endl;
|
||||
perpandiculars[iperpand]->base()->mergeUserConstraints ( constraints );
|
||||
}
|
||||
ltraceout(200);
|
||||
}
|
||||
|
||||
|
||||
void freeCagedTerminals ( Track* track )
|
||||
{
|
||||
Configuration* configuration = Session::getConfiguration ();
|
||||
const Layer* metal2 = configuration->getRoutingLayer ( 1 );
|
||||
const Layer* metal3 = configuration->getRoutingLayer ( 2 );
|
||||
|
||||
for ( size_t i=0 ; i<track->getSize() ; i++ ) {
|
||||
TrackElement* segment = track->getSegment ( i );
|
||||
if ( segment and segment->isFixed() and segment->isTerminal() ) {
|
||||
Interval freeInterval = track->getFreeInterval ( segment->getSourceU(), segment->getNet() );
|
||||
|
||||
if ( freeInterval.getSize() < DbU::lambda(30.0) ) {
|
||||
cinfo << "Caged terminal: " << segment << endl;
|
||||
if ( segment->getLayer() != metal2 ) continue;
|
||||
if ( segment->getLength() >= DbU::lambda(5.0) ) continue;
|
||||
|
||||
AutoContact* support = segment->base()->getAutoSource();
|
||||
RoutingPad* rp = dynamic_cast<RoutingPad*>(support->getAnchor());
|
||||
GCell* gcell = Session::lookup ( support->getGCell() );
|
||||
|
||||
#if 0
|
||||
Point point ( segment->base()->getSourceU(), track->getAxis() );
|
||||
GCell* gcell = Session::lookup ( segment->base()->getAutoSource()->getGCell() );
|
||||
AutoContact* source = AutoContact::create ( gcell->base(), segment->getNet(), metal3 );
|
||||
AutoContact* target = AutoContact::create ( gcell->base(), segment->getNet(), metal3 );
|
||||
source->setPosition ( point );
|
||||
target->setPosition ( point );
|
||||
#endif
|
||||
|
||||
AutoContact* source = AutoContact::fromRp ( gcell->base()
|
||||
, rp
|
||||
, metal3
|
||||
, rp->getSourcePosition()
|
||||
, DbU::lambda(1.0), DbU::lambda(1.0)
|
||||
, true
|
||||
);
|
||||
|
||||
AutoContact* target = AutoContact::fromRp ( gcell->base()
|
||||
, 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 );
|
||||
GCell::addTrackSegment ( gcell, segment, true );
|
||||
|
||||
#if DISABLED
|
||||
// Force slackening.
|
||||
bool breakFlag = false;
|
||||
forEach ( Contact*, icontact, rp->getSlaveComponents().getSubSet<Contact*>() ) {
|
||||
forEach ( Segment*, isegment, icontact->getSlaveComponents().getSubSet<Segment*>() ) {
|
||||
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<AutoSegment*>& 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // End of local namespace.
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Net;
|
||||
using Hurricane::Name;
|
||||
|
||||
|
||||
void KiteEngine::preProcess ()
|
||||
{
|
||||
for ( size_t i=0 ; i<_routingPlanes.size() ; i++ ) {
|
||||
RoutingPlane* plane = _routingPlanes[i];
|
||||
|
||||
Track* track = plane->getTrackByIndex ( 0 );
|
||||
while ( track ) {
|
||||
freeCagedTerminals ( track );
|
||||
track = track->getNext ();
|
||||
}
|
||||
}
|
||||
Session::revalidate ();
|
||||
}
|
||||
|
||||
|
||||
void KiteEngine::_computeCagedConstraints ()
|
||||
{
|
||||
TrackElementLut::iterator isegment = _trackSegmentLut.begin();
|
||||
for ( ; isegment != _trackSegmentLut.end() ; isegment++ ) {
|
||||
if ( not isegment->second->isFixed() ) continue;
|
||||
propagateCagedConstraints ( isegment->second );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void KiteEngine::_computeCagedConstraints ( Net* net )
|
||||
{
|
||||
TrackElement* segment = NULL;
|
||||
|
||||
forEach ( Segment*, isegment, net->getComponents().getSubSet<Segment*>() ) {
|
||||
segment = Session::lookup ( *isegment );
|
||||
if ( not segment ) continue;
|
||||
|
||||
segment->base()->resetUserConstraints();
|
||||
}
|
||||
|
||||
forEach ( Segment*, isegment, net->getComponents().getSubSet<Segment*>() ) {
|
||||
segment = Session::lookup ( *isegment );
|
||||
if ( not segment ) continue;
|
||||
|
||||
propagateCagedConstraints ( segment );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,130 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./RoutingEventHistory.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
#include "hurricane/Error.h"
|
||||
#include "kite/RoutingEvent.h"
|
||||
#include "kite/RoutingEventHistory.h"
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using std::cerr;
|
||||
using std::setw;
|
||||
using std::setfill;
|
||||
using std::endl;
|
||||
using Hurricane::Error;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "RoutingEventHistory".
|
||||
|
||||
|
||||
RoutingEventHistory::RoutingEventHistory ()
|
||||
: _events ()
|
||||
, _identicals(0)
|
||||
{ }
|
||||
|
||||
|
||||
RoutingEventHistory::~RoutingEventHistory ()
|
||||
{ clear (); }
|
||||
|
||||
|
||||
RoutingEvent* RoutingEventHistory::getNth ( size_t index ) const
|
||||
{
|
||||
if ( index < size() ) return _events[index];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
RoutingEvent* RoutingEventHistory::getRNth ( size_t index ) const
|
||||
{
|
||||
if ( index < size() ) return _events[size()-index-1];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void RoutingEventHistory::dump ( ostream& o, size_t depth ) const
|
||||
{
|
||||
o << " o Event History top stack:" << endl;
|
||||
if ( _events.empty() ) return;
|
||||
|
||||
size_t stop = (_events.size() > depth) ? (_events.size()-depth-1) : 0;
|
||||
size_t i = _events.size()-1;
|
||||
do {
|
||||
o << " - [" << setfill('0') << setw(3) << i << "]: " << _events[i] << endl;
|
||||
o << setfill(' ');
|
||||
} while ( i && (i-- >= stop) );
|
||||
}
|
||||
|
||||
|
||||
void RoutingEventHistory::push ( RoutingEvent* event )
|
||||
{
|
||||
if ( _events.size() && (event->getSegment() == _events.back()->getSegment()) )
|
||||
_identicals++;
|
||||
else
|
||||
_identicals = 0;
|
||||
|
||||
_events.push_back(event);
|
||||
|
||||
// if ( _identicals > 30 ) {
|
||||
// dump ( cerr, 40 );
|
||||
// throw Error("RoutingEventHistory::push(): More than 30 identicals events, we are looping.");
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
void RoutingEventHistory::clear ()
|
||||
{
|
||||
for ( size_t i=0 ; i < _events.size() ; i++ )
|
||||
_events[i]->destroy();
|
||||
_events.clear ();
|
||||
_identicals = 0;
|
||||
}
|
||||
|
||||
|
||||
string RoutingEventHistory::_getString () const
|
||||
{
|
||||
string s = "<" + _getTypeName();
|
||||
|
||||
s += ":" + getString(size());
|
||||
s += ">";
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
Record* RoutingEventHistory::_getRecord () const
|
||||
{
|
||||
Record* record = new Record ( getString(this) );
|
||||
record->add ( getSlot ( "_events", &_events ) );
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,321 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
|
||||
#include "hurricane/Bug.h"
|
||||
#include "kite/DataNegociate.h"
|
||||
#include "kite/TrackElement.h"
|
||||
#include "kite/RoutingEventQueue.h"
|
||||
#include "kite/Session.h"
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::setw;
|
||||
using std::max;
|
||||
using std::make_heap;
|
||||
using std::push_heap;
|
||||
using std::pop_heap;
|
||||
|
||||
using Hurricane::tab;
|
||||
using Hurricane::inltrace;
|
||||
using Hurricane::ltracein;
|
||||
using Hurricane::ltraceout;
|
||||
using Hurricane::Bug;
|
||||
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "RoutingEventQueue".
|
||||
|
||||
|
||||
RoutingEventQueue::RoutingEventQueue ()
|
||||
: _topEventLevel (0)
|
||||
, _pushRequests ()
|
||||
, _events ()
|
||||
{ }
|
||||
|
||||
|
||||
RoutingEventQueue::~RoutingEventQueue ()
|
||||
{ clear (); }
|
||||
|
||||
|
||||
void RoutingEventQueue::load ( const vector<TrackElement*>& segments )
|
||||
{
|
||||
for ( size_t i=0 ; i<segments.size() ; i++ ) {
|
||||
if ( segments[i]->getDataNegociate()->getGCellOrder() >= Session::getOrder() ) {
|
||||
if ( segments[i]->getDataNegociate()->getRoutingEvent() ) {
|
||||
cinfo << "[INFO] Already have a RoutingEvent - " << segments[i] << endl;
|
||||
continue;
|
||||
}
|
||||
if ( segments[i]->getTrack() ) {
|
||||
cinfo << "[INFO] Already in Track - " << segments[i] << endl;
|
||||
continue;
|
||||
}
|
||||
RoutingEvent* event = RoutingEvent::create(segments[i]);
|
||||
event->updateKey ();
|
||||
_events.insert ( event );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RoutingEventQueue::add ( TrackElement* segment, unsigned int level )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
|
||||
|
||||
void RoutingEventQueue::push ( RoutingEvent* event )
|
||||
{ _pushRequests.insert ( event ); }
|
||||
|
||||
|
||||
void RoutingEventQueue::commit ()
|
||||
{
|
||||
ltrace(200) << "RoutingEventQueue::commit()" << endl;
|
||||
ltracein(200);
|
||||
|
||||
size_t addeds = _pushRequests.size();
|
||||
size_t before = _events.size();
|
||||
|
||||
set<RoutingEvent*>::iterator ipushEvent = _pushRequests.begin();
|
||||
for ( ; ipushEvent != _pushRequests.end() ; ipushEvent++ ) {
|
||||
(*ipushEvent)->updateKey ();
|
||||
|
||||
_topEventLevel = max ( _topEventLevel, (*ipushEvent)->getEventLevel() );
|
||||
_events.insert ( (*ipushEvent) );
|
||||
|
||||
ltrace(200) << "| " << (*ipushEvent) << endl;
|
||||
}
|
||||
_pushRequests.clear ();
|
||||
#if defined(CHECK_ROUTINGEVENT_QUEUE)
|
||||
_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 ( (RoutingEvent::getProcesseds() > 61246)
|
||||
// and (RoutingEvent::getProcesseds() < 61256) ) {
|
||||
// cerr << "RoutingEventQueue::commit()" << endl;
|
||||
// dump ();
|
||||
// }
|
||||
|
||||
ltraceout(200);
|
||||
}
|
||||
|
||||
|
||||
RoutingEvent* RoutingEventQueue::pop ()
|
||||
{
|
||||
multiset<RoutingEvent*,RoutingEvent::Compare>::iterator ievent;
|
||||
RoutingEvent* event = NULL;
|
||||
|
||||
#if defined(CHECK_ROUTINGEVENT_QUEUE)
|
||||
_keyCheck ();
|
||||
#endif
|
||||
|
||||
if ( !_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 ();
|
||||
// }
|
||||
|
||||
size_t afterSize = _events.size();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
void RoutingEventQueue::repush ( RoutingEvent* event )
|
||||
{
|
||||
#if defined(CHECK_ROUTINGEVENT_QUEUE)
|
||||
_keyCheck ();
|
||||
#endif
|
||||
|
||||
multiset<RoutingEvent*,RoutingEvent::Compare>::iterator ievent = _events.find(event);
|
||||
size_t count = _events.count(event);
|
||||
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 );
|
||||
}
|
||||
push ( event );
|
||||
|
||||
// if ( (RoutingEvent::getProcesseds() > 61246)
|
||||
// and (RoutingEvent::getProcesseds() < 61256) ) {
|
||||
// cerr << "After repush: " << event << endl;
|
||||
// dump();
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
void RoutingEventQueue::repushInvalidateds ()
|
||||
{
|
||||
const vector<AutoSegment*>& invalidateds0 = Session::getInvalidateds();
|
||||
set<TrackElement*> invalidateds1;
|
||||
for ( size_t i=0 ; i<invalidateds0.size() ; i++ ) {
|
||||
TrackElement* segment = Session::lookup ( invalidateds0[i] );
|
||||
if ( segment )
|
||||
invalidateds1.insert ( segment );
|
||||
}
|
||||
|
||||
set<TrackElement*>::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;
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RoutingEventQueue::clear ()
|
||||
{
|
||||
if ( not _events.empty() ) {
|
||||
cerr << Bug("RoutingEvent queue is not empty, %d events remains."
|
||||
,_events.size()) << endl;
|
||||
}
|
||||
_events.clear ();
|
||||
}
|
||||
|
||||
|
||||
void RoutingEventQueue::dump () const
|
||||
{
|
||||
multiset<RoutingEvent*,RoutingEvent::Compare>::const_iterator ievent = _events.begin ();
|
||||
for ( ; ievent != _events.end(); ievent++ ) {
|
||||
cerr << "Order: Queue:"
|
||||
<< (*ievent)->getEventLevel()
|
||||
<< "," << setw(6) << (*ievent)->getPriority()
|
||||
<< " " << setw(6) << DbU::getValueString((*ievent)->getSegment()->getLength())
|
||||
<< " " << (*ievent)->getSegment()->isHorizontal()
|
||||
<< " " << setw(6) << DbU::getValueString((*ievent)->getSegment()->getAxis())
|
||||
<< " " << setw(6) << DbU::getValueString((*ievent)->getSegment()->getSourceU())
|
||||
<< ": " << (*ievent)->getSegment() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RoutingEventQueue::_keyCheck () const
|
||||
{
|
||||
multiset<RoutingEvent*,RoutingEvent::Compare>::const_iterator ievent = _events.begin ();
|
||||
for ( ; ievent != _events.end(); ievent++ ) {
|
||||
multiset<RoutingEvent*,RoutingEvent::Compare>::const_iterator ieventByKey
|
||||
= _events.find ( *ievent );
|
||||
|
||||
if ( ieventByKey != ievent ) {
|
||||
if ( ieventByKey == _events.end() ) {
|
||||
cerr << Bug("Key mismatch in RoutingEvent Queue:\n"
|
||||
" %p:%s wasn't found by key."
|
||||
,*ievent,getString(*ievent).c_str()
|
||||
) << endl;
|
||||
} else {
|
||||
cerr << Bug("Key mismatch in RoutingEvent Queue:\n"
|
||||
" %p:%s has same key of\n"
|
||||
" %p:%s"
|
||||
,*ievent,getString(*ievent).c_str()
|
||||
,*ieventByKey,getString(*ieventByKey).c_str()
|
||||
) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
string RoutingEventQueue::_getString () const
|
||||
{
|
||||
string s = "<" + _getTypeName();
|
||||
|
||||
s += ":" + getString(size());
|
||||
s += ">";
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
Record* RoutingEventQueue::_getRecord () const
|
||||
{
|
||||
Record* record = new Record ( getString(this) );
|
||||
record->add ( getSlot ( "_events", &_events ) );
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,196 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./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"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
const char* badLayerGauge =
|
||||
"RoutingPlane::create() :\n\n"
|
||||
" No plane at depth %u in %s.";
|
||||
|
||||
|
||||
} // End of local namespace.
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::inltrace;
|
||||
using Hurricane::ltracein;
|
||||
using Hurricane::ltraceout;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Box;
|
||||
using Hurricane::Cell;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "RoutingPlane".
|
||||
|
||||
|
||||
RoutingPlane::RoutingPlane ( KiteEngine* kite, size_t depth )
|
||||
: _kite (kite)
|
||||
, _layerGauge(kite->getLayerGauge(depth))
|
||||
, _depth (depth)
|
||||
, _tracks ()
|
||||
{ }
|
||||
|
||||
|
||||
RoutingPlane::~RoutingPlane ()
|
||||
{ }
|
||||
|
||||
|
||||
void RoutingPlane::destroy ()
|
||||
{
|
||||
ltrace(90) << "RoutingPlane::destroy() - "
|
||||
<< (void*)this << " " << this << endl;
|
||||
ltracein(90);
|
||||
|
||||
for ( size_t index = 0 ; index < _tracks.size() ; index++ )
|
||||
_tracks[index]->destroy ();
|
||||
|
||||
delete this;
|
||||
|
||||
ltraceout(90);
|
||||
}
|
||||
|
||||
|
||||
RoutingPlane* RoutingPlane::create ( KiteEngine* kite, size_t depth )
|
||||
{
|
||||
RoutingPlane* plane = new RoutingPlane ( kite, depth );
|
||||
|
||||
if ( !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 ();
|
||||
} 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->_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 ) );
|
||||
} else {
|
||||
plane->_tracks.push_back ( VerticalTrack::create ( plane, index ) );
|
||||
}
|
||||
}
|
||||
|
||||
return plane;
|
||||
}
|
||||
|
||||
|
||||
RoutingPlane* RoutingPlane::getTop () const
|
||||
{ return getKiteEngine()->getRoutingPlaneByIndex ( getDepth()+1 ); }
|
||||
|
||||
|
||||
RoutingPlane* RoutingPlane::getBottom () const
|
||||
{
|
||||
if ( !getDepth() ) return NULL;
|
||||
return getKiteEngine()->getRoutingPlaneByIndex ( getDepth()-1 );
|
||||
}
|
||||
|
||||
|
||||
Track* RoutingPlane::getTrackByIndex ( size_t index ) const
|
||||
{
|
||||
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
|
||||
) );
|
||||
}
|
||||
|
||||
|
||||
bool RoutingPlane::_check ( unsigned int& overlaps ) const
|
||||
{
|
||||
bool coherency = true;
|
||||
|
||||
for ( size_t i=0 ; i<_tracks.size() ; i++ ) {
|
||||
coherency = _tracks[i]->_check(overlaps) && coherency;
|
||||
}
|
||||
|
||||
return coherency;
|
||||
}
|
||||
|
||||
|
||||
string RoutingPlane::_getString () const
|
||||
{
|
||||
return "<" + _getTypeName() + " @"
|
||||
+ getString(_depth) + " ["
|
||||
+ getString(_tracks.size()) + "/"
|
||||
+ getString(_tracks.capacity())
|
||||
+ "]>";
|
||||
}
|
||||
|
||||
|
||||
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 ) );
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,364 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./Session.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/Error.h"
|
||||
#include "kite/Session.h"
|
||||
#include "kite/Track.h"
|
||||
#include "kite/TrackElement.h"
|
||||
#include "kite/GCellGrid.h"
|
||||
#include "kite/KiteEngine.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
using namespace Kite;
|
||||
|
||||
|
||||
const char* reopenSession =
|
||||
"Kite::Session::open() :\n\n"
|
||||
" Session already open for %s (internal error).";
|
||||
|
||||
|
||||
} // End of local namespace.
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::inltrace;
|
||||
using Hurricane::ltracein;
|
||||
using Hurricane::ltraceout;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Bug;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Session".
|
||||
|
||||
|
||||
Session::Session ( KiteEngine* kite )
|
||||
: Katabatic::Session(kite)
|
||||
, _order (0)
|
||||
, _insertEvents()
|
||||
, _removeEvents()
|
||||
, _sortEvents ()
|
||||
{ }
|
||||
|
||||
|
||||
void Session::_postCreate ()
|
||||
{
|
||||
Katabatic::Session::_postCreate ();
|
||||
}
|
||||
|
||||
|
||||
Session::~Session ()
|
||||
{ }
|
||||
|
||||
|
||||
size_t Session::_preDestroy ()
|
||||
{
|
||||
_isEmpty ();
|
||||
|
||||
size_t count = Katabatic::Session::_preDestroy ();
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
Session* Session::open ( KiteEngine* 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() );
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
session = new Session ( kite );
|
||||
session->_postCreate ();
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
|
||||
Session* Session::get ( const char* message )
|
||||
{ return dynamic_cast<Session*>( Katabatic::Session::get(message) ); }
|
||||
|
||||
|
||||
Configuration* Session::getConfiguration ()
|
||||
{ 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); }
|
||||
|
||||
|
||||
TrackElement* Session::lookup ( AutoSegment* segment )
|
||||
{ return Session::get("lookup(AutoSegment*)")->_getKiteEngine()->_lookup ( segment ); }
|
||||
|
||||
|
||||
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); }
|
||||
|
||||
|
||||
KiteEngine* Session::_getKiteEngine ()
|
||||
{ return static_cast<KiteEngine*>(_katabatic); }
|
||||
|
||||
|
||||
Net* Session::_getBlockageNet ()
|
||||
{ return _getKiteEngine()->getBlockageNet(); };
|
||||
|
||||
|
||||
NegociateWindow* Session::_getNegociateWindow ()
|
||||
{ return _getKiteEngine()->getNegociateWindow(); };
|
||||
|
||||
|
||||
unsigned int Session::_getRipupCost ()
|
||||
{ return _getKiteEngine()->getRipupCost(); };
|
||||
|
||||
|
||||
GCell* Session::_getGCellUnder ( DbU::Unit x, DbU::Unit y )
|
||||
{ return _getKiteEngine()->getGCellGrid()->getGCell(Point(x,y)); };
|
||||
|
||||
|
||||
unsigned int Session::_getOrder () const
|
||||
{ return _order; }
|
||||
|
||||
|
||||
void Session::_setOrder ( unsigned int order )
|
||||
{ _order = order; }
|
||||
|
||||
|
||||
size_t Session::_revalidate ()
|
||||
{
|
||||
set<Track*> packTracks;
|
||||
|
||||
for ( size_t i=0 ; i < _removeEvents.size() ; i++ ) {
|
||||
if ( !_removeEvents[i]._segment->getTrack() ) continue;
|
||||
|
||||
packTracks.insert ( _removeEvents[i]._segment->getTrack() );
|
||||
_removeEvents[i]._segment->detach ();
|
||||
}
|
||||
_removeEvents.clear ();
|
||||
|
||||
for ( set<Track*>::iterator it=packTracks.begin() ; it != packTracks.end() ; it++ )
|
||||
(*it)->pack ();
|
||||
|
||||
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 );
|
||||
}
|
||||
_insertEvents.clear ();
|
||||
|
||||
// Check if to be destroyeds are not associateds with TrackSegments.
|
||||
const set<AutoSegment*>& destroyeds = getDestroyeds();
|
||||
set<AutoSegment*>::const_iterator idestroyed = destroyeds.begin();
|
||||
for ( ; idestroyed != destroyeds.end() ; idestroyed++ ) {
|
||||
if ( lookup(*idestroyed) ) {
|
||||
cerr << Error("Destroyed AutoSegment is associated with a TrackSegment\n"
|
||||
" (%s)"
|
||||
,getString(*idestroyed).c_str()) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
size_t count = Katabatic::Session::_revalidate ();
|
||||
|
||||
Interval span;
|
||||
vector<TrackElement*> processeds;
|
||||
const vector<AutoSegment*>& revalidateds = getRevalidateds ();
|
||||
const set<Net*>& netsModificateds = getNetsModificateds ();
|
||||
|
||||
for ( size_t i=0 ; i<revalidateds.size() ; i++ ) {
|
||||
Net* currentNet = NULL;
|
||||
bool invalidEvent = false;
|
||||
TrackElement* trackSegment = lookup ( revalidateds[i]->base() );
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( size_t i=0 ; i<processeds.size() ; i++ )
|
||||
processeds[i]->setRevalidated ( false );
|
||||
|
||||
# if defined(CHECK_DATABASE)
|
||||
unsigned int overlaps = 0;
|
||||
# endif
|
||||
for ( set<Track*>::iterator it=_sortEvents.begin()
|
||||
; it != _sortEvents.end()
|
||||
; it++
|
||||
) {
|
||||
(*it)->sort ();
|
||||
# if defined(CHECK_DATABASE)
|
||||
(*it)->_check ( overlaps, "Session::_revalidate() - track sorting." );
|
||||
# endif
|
||||
}
|
||||
|
||||
for ( set<Net*>::iterator inet=netsModificateds.begin() ; inet != netsModificateds.end() ; inet++ ) {
|
||||
_getKiteEngine()->_computeCagedConstraints ( *inet );
|
||||
}
|
||||
|
||||
# if defined(CHECK_DATABASE)
|
||||
for ( set<Track*>::iterator it=packTracks.begin() ; it != packTracks.end() ; it++ )
|
||||
(*it)->_check ( overlaps, "Session::_revalidate() - on packed track." );
|
||||
|
||||
//_getKiteEngine()->_showOverlap ();
|
||||
# endif
|
||||
|
||||
_sortEvents.clear ();
|
||||
|
||||
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."
|
||||
, _insertEvents.size()
|
||||
, _removeEvents.size()
|
||||
, _sortEvents .size() ) << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Session::_addInsertEvent ( TrackMarker* marker, Track* track )
|
||||
{
|
||||
_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 << endl;
|
||||
|
||||
if ( segment->getTrack() != NULL ) {
|
||||
cerr << Bug("Session::addInsertEvent(): Segment already in Track."
|
||||
"\n %s."
|
||||
"\n to %s."
|
||||
,getString(segment).c_str()
|
||||
,getString(track).c_str()
|
||||
) << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
_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;
|
||||
return;
|
||||
}
|
||||
|
||||
ltrace(200) << "Ripup: @" << DbU::getValueString(segment->getAxis()) << " " << segment << endl;
|
||||
_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;
|
||||
return;
|
||||
}
|
||||
|
||||
_addRemoveEvent ( segment );
|
||||
_addInsertEvent ( segment, track );
|
||||
}
|
||||
|
||||
|
||||
void Session::_addSortEvent ( Track* track, bool forced )
|
||||
{
|
||||
if ( !track ) {
|
||||
cerr << Bug(" Kite::Session::addSortEvent() : no Track to sort.") << endl;
|
||||
return;
|
||||
}
|
||||
if ( forced ) track->forceSort ();
|
||||
_sortEvents.insert ( track );
|
||||
}
|
||||
|
||||
|
||||
string Session::_getTypeName () const
|
||||
{ return "Kite::Session"; }
|
||||
|
||||
|
||||
Record* Session::_getRecord () const
|
||||
{
|
||||
Record* record = Session::_getRecord ();
|
||||
record->add ( getSlot ( "_sortEvents" , &_sortEvents ) );
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,774 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./Track.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
|
||||
#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(); };
|
||||
};
|
||||
|
||||
|
||||
DbU::Unit getPositionByIterator ( const vector<TrackElement*>& v, size_t i )
|
||||
{ return (*(v.begin()+i))->getSourceU(); }
|
||||
|
||||
|
||||
} // End of local namespace.
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using std::lower_bound;
|
||||
using std::remove_if;
|
||||
using std::sort;
|
||||
using Hurricane::dbo_ptr;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::inltrace;
|
||||
using Hurricane::ltracein;
|
||||
using Hurricane::ltraceout;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Layer;
|
||||
using Hurricane::Net;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Track".
|
||||
|
||||
|
||||
const size_t Track::NPOS = (size_t)-1;
|
||||
|
||||
|
||||
Track::Track ( RoutingPlane* routingPlane, unsigned int index )
|
||||
: _routingPlane (routingPlane)
|
||||
, _index (index)
|
||||
, _axis (routingPlane->getTrackPosition(index))
|
||||
, _min (routingPlane->getTrackMin())
|
||||
, _max (routingPlane->getTrackMax())
|
||||
, _segments ()
|
||||
, _markers ()
|
||||
, _segmentsValid(false)
|
||||
, _markersValid (false)
|
||||
{ }
|
||||
|
||||
|
||||
void Track::_postCreate ()
|
||||
{ }
|
||||
|
||||
|
||||
Track::~Track ()
|
||||
{
|
||||
ltrace(90) << "Track::~Track() - " << (void*)this << endl;
|
||||
}
|
||||
|
||||
|
||||
void Track::_preDestroy ()
|
||||
{
|
||||
ltrace(90) << "Track::_preDestroy() - " << (void*)this << " " << this << endl;
|
||||
ltracein(90);
|
||||
|
||||
for ( size_t i=0 ; i<_segments.size() ; i++ )
|
||||
if ( _segments[i] ) _segments[i]->detach();
|
||||
|
||||
for ( size_t i=0 ; i<_markers.size() ; i++ )
|
||||
if ( _markers[i] ) _markers[i]->destroy();
|
||||
|
||||
ltraceout(90);
|
||||
}
|
||||
|
||||
|
||||
void Track::destroy ()
|
||||
{
|
||||
ltrace(90) << "Track::destroy() - " << (void*)this << " " << this << endl;
|
||||
|
||||
Track::_preDestroy ();
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
KiteEngine* Track::getKiteEngine () const
|
||||
{ return _routingPlane->getKiteEngine(); }
|
||||
|
||||
|
||||
unsigned int Track::getDepth () const
|
||||
{ return _routingPlane->getDepth(); }
|
||||
|
||||
|
||||
const Layer* Track::getLayer () const
|
||||
{ return _routingPlane->getLayer(); }
|
||||
|
||||
|
||||
const Layer* Track::getBlockageLayer () const
|
||||
{ return _routingPlane->getBlockageLayer(); }
|
||||
|
||||
|
||||
TrackElement* Track::getSegment ( size_t index ) const
|
||||
{
|
||||
if ( (index == NPOS) || (index >= getSize()) ) return NULL;
|
||||
return _segments[index];
|
||||
}
|
||||
|
||||
|
||||
TrackElement* Track::getSegment ( DbU::Unit position ) const
|
||||
{
|
||||
unsigned int state;
|
||||
size_t begin;
|
||||
size_t end;
|
||||
|
||||
getIBounds ( position, begin, end, state );
|
||||
|
||||
if ( state & (MinTrackMin|MaxTrackMax) ) return NULL;
|
||||
|
||||
return getSegment(begin);
|
||||
}
|
||||
|
||||
|
||||
TrackElement* Track::getNext ( size_t& index, Net* net, bool useOrder ) const
|
||||
{
|
||||
for ( index++ ; index < _segments.size() ; index++ ) {
|
||||
if ( _segments[index]->getNet() == net ) continue;
|
||||
if ( useOrder
|
||||
and _segments[index]->getDataNegociate()
|
||||
and (_segments[index]->getDataNegociate()->getGCellOrder() >= Session::getOrder()) )
|
||||
continue;
|
||||
return _segments[index];
|
||||
}
|
||||
index = NPOS;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
TrackElement* Track::getPrevious ( size_t& index, Net* net, bool useOrder ) const
|
||||
{
|
||||
for ( index-- ; index != NPOS ; index-- ) {
|
||||
if ( inltrace(148) ) {
|
||||
cerr << tab << index << ":"; cerr.flush();
|
||||
cerr << _segments[index] << endl;
|
||||
}
|
||||
if ( _segments[index]->getNet() == net ) continue;
|
||||
if ( useOrder
|
||||
and _segments[index]->getDataNegociate()
|
||||
and (_segments[index]->getDataNegociate()->getGCellOrder() >= Session::getOrder()) )
|
||||
continue;
|
||||
return _segments[index];
|
||||
}
|
||||
index = NPOS;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
TrackElement* Track::getNextFixed ( size_t& index ) const
|
||||
{
|
||||
TrackElement* nextFixed = getNext ( index, NULL );
|
||||
for ( ; nextFixed ; nextFixed = getNext(index,NULL) ) {
|
||||
if ( nextFixed->base()->isFixed() ) return nextFixed;
|
||||
}
|
||||
|
||||
return nextFixed;
|
||||
}
|
||||
|
||||
|
||||
void Track::getIBounds ( DbU::Unit position, size_t& begin, size_t& end, unsigned int& state ) const
|
||||
{
|
||||
if ( _segments.empty() ) {
|
||||
state = EmptyTrack;
|
||||
begin = end = 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;
|
||||
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;
|
||||
return;
|
||||
}
|
||||
|
||||
vector<TrackElement*>::const_iterator lowerBound
|
||||
= lower_bound ( _segments.begin(), _segments.end(), position, SourceCompare() );
|
||||
begin = end = lowerBound - _segments.begin();
|
||||
|
||||
if ( begin < _segments.size() )
|
||||
for ( ; (begin > 0) && (_segments[begin-1]->getNet() == _segments[begin]->getNet()) ; --begin );
|
||||
|
||||
state = 0;
|
||||
if ( (begin == 0) && (position < _segments[0]->getSourceU()) ) {
|
||||
state = BeforeFirst;
|
||||
} else {
|
||||
if ( begin ) end = begin -= 1;
|
||||
|
||||
size_t usedBegin = begin;
|
||||
size_t usedEnd = begin;
|
||||
Interval usedInterval = expandUsedInterval ( usedBegin, usedEnd );
|
||||
|
||||
if ( position < usedInterval.getVMax() )
|
||||
state = Inside;
|
||||
else
|
||||
if ( begin+1 == _segments.size() )
|
||||
state = AfterLast;
|
||||
else
|
||||
state = Outside;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
return;
|
||||
}
|
||||
|
||||
getIBounds ( interval.getVMin(), begin, iEnd, iState );
|
||||
expandUsedInterval ( begin, iEnd );
|
||||
|
||||
getIBounds ( interval.getVMax(), iBegin, end, iState );
|
||||
while ( end < _segments.size() ) {
|
||||
if ( _segments[end++]->getSourceU() >= interval.getVMax() ) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TrackCost Track::getOverlapCost ( Interval interval, Net* net, size_t begin, size_t end ) const
|
||||
{
|
||||
TrackCost cost ( const_cast<Track*>(this), interval, begin, end );
|
||||
|
||||
ltrace(148) << "getOverlapCost() @" << DbU::getValueString(_axis)
|
||||
<< " [" << interval.getVMin() << " " << interval.getVMax() << "]" << endl;
|
||||
|
||||
ltracein(148);
|
||||
|
||||
vector<TrackMarker*>::const_iterator lowerBound
|
||||
= 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++ ) {
|
||||
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) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( begin == NPOS ) {
|
||||
ltrace(148) << " begin == NPOS (after last TrackElement)." << endl;
|
||||
ltraceout(148);
|
||||
return cost;
|
||||
}
|
||||
|
||||
for ( ; begin < end ; begin++ ) {
|
||||
if ( _segments[begin]->getNet() == net ) {
|
||||
cost.incDeltaShared ( _segments[begin]->getCanonicalInterval().intersection(interval).getSize() );
|
||||
}
|
||||
ltrace(190) << "| overlap: " << _segments[begin] << endl;
|
||||
_segments[begin]->incOverlapCost ( net, cost );
|
||||
if ( cost.isInfinite() ) break;
|
||||
}
|
||||
|
||||
ltraceout(148);
|
||||
|
||||
return cost;
|
||||
}
|
||||
|
||||
|
||||
TrackCost Track::getOverlapCost ( Interval interval, Net* net ) const
|
||||
{
|
||||
size_t begin;
|
||||
size_t end;
|
||||
|
||||
getOverlapBounds ( interval, begin, end );
|
||||
|
||||
return getOverlapCost ( interval, net, begin, end );
|
||||
}
|
||||
|
||||
|
||||
TrackCost Track::getOverlapCost ( TrackElement* segment ) const
|
||||
{
|
||||
return getOverlapCost ( segment->getCanonicalInterval(), segment->getNet() );
|
||||
}
|
||||
|
||||
|
||||
void Track::getTerminalWeight ( Interval interval, Net* net, size_t& count, unsigned int& weight ) const
|
||||
{
|
||||
ltrace(148) << "getTerminalWeight() @" << DbU::getValueString(_axis)
|
||||
<< " [" << interval.getVMin() << " " << interval.getVMax() << "]" << endl;
|
||||
ltracein(148);
|
||||
|
||||
//count = 0;
|
||||
//weight = 0;
|
||||
|
||||
vector<TrackMarker*>::const_iterator lowerBound
|
||||
= 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++ ) {
|
||||
ltrace(148) << "| @" << DbU::getValueString(_axis) << _markers[mbegin] << endl;
|
||||
if ( _markers[mbegin]->getNet() == net ) {
|
||||
ltrace(200) << "* Mark: @" << DbU::getValueString(_axis) << " " << _markers[mbegin] << endl;
|
||||
weight += _markers[mbegin]->getWeight(this);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
ltraceout(148);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
vector<TrackElement*>::const_iterator lowerBound
|
||||
= lower_bound ( _segments.begin()
|
||||
, _segments.end()
|
||||
, segment
|
||||
, SegmentCompare()
|
||||
);
|
||||
|
||||
if ( lowerBound != _segments.end() ) {
|
||||
while ( segment->getSourceU() == (*lowerBound)->getSourceU() ) {
|
||||
if ( *lowerBound == segment ) return (size_t)(lowerBound-_segments.begin());
|
||||
lowerBound++;
|
||||
}
|
||||
}
|
||||
|
||||
return NPOS;
|
||||
}
|
||||
|
||||
|
||||
Interval Track::getFreeInterval ( DbU::Unit position, Net* net ) const
|
||||
{
|
||||
unsigned int state;
|
||||
size_t begin;
|
||||
size_t end;
|
||||
|
||||
if ( !_segments.size() ) return Interval(_min,_max);
|
||||
|
||||
getIBounds ( position, begin, end, state );
|
||||
if ( (state == Inside) && (_segments[begin]->getNet() != net) )
|
||||
return Interval();
|
||||
|
||||
return expandFreeInterval ( begin, end, state, net );
|
||||
}
|
||||
|
||||
|
||||
Interval Track::expandFreeInterval ( size_t& begin, size_t& end, unsigned int state, Net* net, bool useOrder ) const
|
||||
{
|
||||
DbU::Unit minFree = _min;
|
||||
|
||||
if ( !(state & MinTrackMin) ) {
|
||||
if ( _segments[begin]->getNet() == net )
|
||||
getPrevious ( begin, net, useOrder );
|
||||
|
||||
if ( begin != NPOS ) {
|
||||
size_t usedEnd;
|
||||
minFree = expandUsedInterval ( begin, usedEnd, useOrder ).getVMax();
|
||||
}
|
||||
}
|
||||
|
||||
if ( !(state & MaxTrackMax) ) {
|
||||
if ( _segments[end]->getNet() == net ) {
|
||||
getNext ( end, net, useOrder );
|
||||
|
||||
if ( end == NPOS ) {
|
||||
end = _segments.size() - 1;
|
||||
setMaximalFlags ( state, MaxTrackMax );
|
||||
} else {
|
||||
setMaximalFlags ( state, MaxSegmentMin );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Interval ( minFree, getMaximalPosition(end,state) );
|
||||
}
|
||||
|
||||
|
||||
void Track::forceSort ()
|
||||
{
|
||||
_segmentsValid = false;
|
||||
}
|
||||
|
||||
|
||||
void Track::insert ( TrackMarker* marker )
|
||||
{
|
||||
_markers.push_back ( marker );
|
||||
_markersValid = false;
|
||||
}
|
||||
|
||||
|
||||
void Track::insert ( TrackElement* segment )
|
||||
{
|
||||
ltrace(200) << "Track::insert() " << getLayer()->getName()
|
||||
<< " @" << DbU::getValueString(getAxis()) << " " << segment << endl;
|
||||
|
||||
if ( (getLayer()->getMask() != segment->getLayer()->getMask())
|
||||
and (getBlockageLayer()->getMask() != segment->getLayer()->getMask()) ) {
|
||||
cerr << Bug("Track::insert(), segment %s has not the right layer."
|
||||
,getString(segment).c_str()) << endl;
|
||||
}
|
||||
|
||||
segment->setAxis ( getAxis() );
|
||||
_segments.push_back ( segment );
|
||||
_segmentsValid = false;
|
||||
|
||||
segment->setTrack ( this );
|
||||
}
|
||||
|
||||
|
||||
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 coherency = true;
|
||||
bool holes = false;
|
||||
|
||||
if ( message ) cerr << " o Checking Track - " << message << endl;
|
||||
ltrace(90) << "[CHECK] " << (void*)this << ":" << this << endl;
|
||||
|
||||
for ( size_t i=0 ; i<_segments.size() ; 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() ) {
|
||||
cerr << "[CHECK] incoherency at " << i << " "
|
||||
<< _segments[i] << " is detached." << endl;
|
||||
coherency = false;
|
||||
} else {
|
||||
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 ) {
|
||||
cerr << "[CHECK] incoherency at " << i << " "
|
||||
<< _segments[i] << " has bad index "
|
||||
<< _segments[i]->getIndex() << endl;
|
||||
coherency = false;
|
||||
}
|
||||
}
|
||||
if ( _segments[i]->getAxis() != getAxis() ) {
|
||||
cerr << "[CHECK] incoherency at " << i << " "
|
||||
<< _segments[i] << " is not on Track axis "
|
||||
<< DbU::getValueString(getAxis()) << "." << endl;
|
||||
coherency = false;
|
||||
}
|
||||
|
||||
coherency = coherency && _segments[i]->_check ();
|
||||
} else {
|
||||
cerr << "[CHECK] Hole at position " << i << "." << endl;
|
||||
holes = true;
|
||||
coherency = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !holes )
|
||||
coherency = coherency && (checkOverlap(overlaps) == 0);
|
||||
|
||||
return coherency;
|
||||
}
|
||||
|
||||
|
||||
DbU::Unit Track::getSourcePosition ( size_t i ) const
|
||||
{
|
||||
if ( i == NPOS) return 0;
|
||||
|
||||
return _segments[i]->getSourceU();
|
||||
}
|
||||
|
||||
|
||||
DbU::Unit Track::getSourcePosition ( vector<TrackElement*>::iterator isegment ) const
|
||||
{
|
||||
if ( isegment == _segments.end() ) return 0;
|
||||
|
||||
return (*isegment)->getSourceU();
|
||||
}
|
||||
|
||||
|
||||
DbU::Unit Track::getMinimalPosition ( size_t index, unsigned int state ) const
|
||||
{
|
||||
Interval canonical;
|
||||
|
||||
switch ( state & MinMask ) {
|
||||
case MinTrackMin: return _min;
|
||||
case MinSegmentMin: return _segments[index]->getSourceU ();
|
||||
case MinSegmentMax: return _segments[index]->getTargetU ();
|
||||
}
|
||||
|
||||
cerr << Bug ( " Track::getMinimalPosition(size_t,unsigned int) :"
|
||||
" invalid state value %ud.", state ) << endl;
|
||||
|
||||
return _min;
|
||||
}
|
||||
|
||||
|
||||
DbU::Unit Track::getMaximalPosition ( size_t index, unsigned int state ) const
|
||||
{
|
||||
Interval canonical;
|
||||
|
||||
switch ( state & MaxMask ) {
|
||||
case MaxTrackMax: return _max;
|
||||
case MaxSegmentMin: return _segments[index ]->getSourceU ();
|
||||
case MaxNextSegmentMin: return _segments[index+1]->getSourceU ();
|
||||
case MaxSegmentMax: return _segments[index ]->getTargetU ();
|
||||
}
|
||||
|
||||
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, bool useOrder ) const
|
||||
{
|
||||
if ( begin == NPOS ) return Interval();
|
||||
|
||||
size_t seed = begin;
|
||||
Net* owner = _segments[seed]->getNet();
|
||||
|
||||
Interval expandInterval;
|
||||
Interval ownerInterval;
|
||||
_segments[seed]->getCanonical ( ownerInterval );
|
||||
|
||||
size_t i = seed;
|
||||
while ( --i != NPOS ) {
|
||||
if ( _segments[i]->getNet() != owner ) break;
|
||||
if ( useOrder
|
||||
and _segments[i]->getDataNegociate()
|
||||
and (_segments[i]->getDataNegociate()->getGCellOrder() >= Session::getOrder()) )
|
||||
continue;
|
||||
|
||||
_segments[i]->getCanonical ( expandInterval );
|
||||
if ( expandInterval.getVMax() >= ownerInterval.getVMin() ) {
|
||||
ownerInterval.merge ( expandInterval );
|
||||
begin = i;
|
||||
}
|
||||
}
|
||||
|
||||
end = i = seed;
|
||||
while ( ++i < _segments.size() ) {
|
||||
if ( _segments[i]->getNet() != owner ) break;
|
||||
if ( useOrder
|
||||
and _segments[i]->getDataNegociate()
|
||||
and (_segments[i]->getDataNegociate()->getGCellOrder() >= Session::getOrder()) )
|
||||
continue;
|
||||
|
||||
_segments[i]->getCanonical ( expandInterval );
|
||||
if ( expandInterval.getVMin() > ownerInterval.getVMax() ) break;
|
||||
if ( expandInterval.getVMax() > ownerInterval.getVMax() ) end = i;
|
||||
|
||||
ownerInterval.merge ( expandInterval );
|
||||
}
|
||||
|
||||
return ownerInterval;
|
||||
}
|
||||
|
||||
|
||||
size_t Track::pack ()
|
||||
{
|
||||
ltrace(148) << "Track::pack() - " << this << endl;
|
||||
ltracein(148);
|
||||
|
||||
size_t size = _segments.size();
|
||||
|
||||
vector<TrackElement*>::iterator beginRemove
|
||||
= remove_if ( _segments.begin(), _segments.end(), isDetachedSegment() );
|
||||
|
||||
_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;
|
||||
ltraceout(148);
|
||||
|
||||
return size - _segments.size();
|
||||
}
|
||||
|
||||
|
||||
void Track::sort ()
|
||||
{
|
||||
if ( !_segmentsValid ) {
|
||||
std::sort ( _segments.begin(), _segments.end(), SegmentCompare() );
|
||||
for ( size_t i=0 ; i < _segments.size() ; i++ ) {
|
||||
_segments[i]->setIndex ( i );
|
||||
}
|
||||
_segmentsValid = true;
|
||||
}
|
||||
|
||||
if ( !_markersValid ) {
|
||||
std::sort ( _markers.begin(), _markers.end(), TrackMarker::Compare() );
|
||||
_markersValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned int Track::checkOverlap ( unsigned int& overlaps ) const
|
||||
{
|
||||
if ( !_segments.size() ) return 0;
|
||||
|
||||
size_t j = 0;
|
||||
for ( size_t i=0 ; i<_segments.size()-1 ; i++ ) {
|
||||
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:\n%s \n%s "
|
||||
,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++ );
|
||||
} else {
|
||||
j = i+1;
|
||||
}
|
||||
|
||||
if ( (j<_segments.size())
|
||||
&& (_segments[i]->getTargetU() > _segments[j]->getSourceU()) ) {
|
||||
cerr << Warning("Overlap between:\n %s\n %s"
|
||||
,getString(_segments[i]).c_str()
|
||||
,getString(_segments[j]).c_str()) << endl;
|
||||
overlaps++;
|
||||
}
|
||||
}
|
||||
|
||||
return overlaps;
|
||||
}
|
||||
|
||||
|
||||
string Track::_getString () const
|
||||
{
|
||||
return "<" + _getTypeName() + " "
|
||||
+ getString(getLayer()) + " @"
|
||||
+ DbU::getValueString(_axis) + " ["
|
||||
+ DbU::getValueString(_min) + ":"
|
||||
+ DbU::getValueString(_max) + "] ["
|
||||
+ getString(_segments.size()) + "/"
|
||||
+ getString(_segments.capacity())
|
||||
+ "]>";
|
||||
}
|
||||
|
||||
|
||||
Record* Track::_getRecord () const
|
||||
{
|
||||
Record* record = new Record ( _getString() );
|
||||
record->add ( getSlot ( "_routingPlane", _routingPlane ) );
|
||||
record->add ( getSlot ( "_index" , &_index ) );
|
||||
record->add ( DbU::getValueSlot ( "_axis" , &_axis ) );
|
||||
record->add ( getSlot ( "_segments" , &_segments ) );
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,204 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2010, 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 : "./TrackBlockage.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#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 "crlcore/RoutingGauge.h"
|
||||
#include "kite/GCell.h"
|
||||
#include "kite/DataNegociate.h"
|
||||
#include "kite/TrackBlockage.h"
|
||||
#include "kite/TrackCost.h"
|
||||
#include "kite/Track.h"
|
||||
#include "kite/Session.h"
|
||||
#include "kite/RoutingEvent.h"
|
||||
#include "kite/NegociateWindow.h"
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using namespace std;
|
||||
using Hurricane::inltrace;
|
||||
using Hurricane::ltracein;
|
||||
using Hurricane::ltraceout;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::ForEachIterator;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Net;
|
||||
using Hurricane::Name;
|
||||
using Hurricane::RegularLayer;
|
||||
using Hurricane::Technology;
|
||||
using Hurricane::DataBase;
|
||||
using Hurricane::Horizontal;
|
||||
using Hurricane::Vertical;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "TrackBlockage".
|
||||
|
||||
|
||||
TrackBlockage::TrackBlockage ( Track* track, Box& boundingBox )
|
||||
: TrackElement (NULL)
|
||||
, _segment (NULL)
|
||||
{
|
||||
if ( track ) {
|
||||
Technology* technology = DataBase::getDB()->getTechnology();
|
||||
const Layer* layer1 = track->getLayer()->getBlockageLayer();
|
||||
RegularLayer* layer2 = dynamic_cast<RegularLayer*>(technology->getLayer(layer1->getMask()));
|
||||
ltrace(190) << "Blockage layer: " << layer2 << endl;
|
||||
if ( layer2 ) {
|
||||
DbU::Unit extention = layer2->getExtentionCap();
|
||||
if ( track->getDirection() == Constant::Horizontal ) {
|
||||
_sourceU = boundingBox.getXMin();
|
||||
_targetU = boundingBox.getXMax();
|
||||
|
||||
_segment = Horizontal::create ( Session::getBlockageNet()
|
||||
, layer2
|
||||
, track->getAxis()
|
||||
, layer2->getMinimalSize()
|
||||
, _sourceU + extention
|
||||
, _targetU - extention
|
||||
);
|
||||
} else {
|
||||
_sourceU = boundingBox.getYMin();
|
||||
_targetU = boundingBox.getYMax();
|
||||
|
||||
_segment = Vertical::create ( Session::getBlockageNet()
|
||||
, layer2
|
||||
, track->getAxis()
|
||||
, layer2->getMinimalSize()
|
||||
, _sourceU + extention
|
||||
, _targetU - extention
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TrackBlockage::_postCreate ()
|
||||
{ TrackElement::_postCreate (); }
|
||||
|
||||
|
||||
TrackBlockage::~TrackBlockage ()
|
||||
{ }
|
||||
|
||||
|
||||
void TrackBlockage::_preDestroy ()
|
||||
{
|
||||
ltrace(90) << "TrackBlockage::_preDestroy() - " << (void*)this << endl;
|
||||
TrackElement::_preDestroy ();
|
||||
}
|
||||
|
||||
|
||||
TrackElement* TrackBlockage::create ( Track* track, Box& boundingBox )
|
||||
{
|
||||
TrackBlockage* trackBlockage = NULL;
|
||||
if ( track ) {
|
||||
trackBlockage = new TrackBlockage ( track, boundingBox );
|
||||
trackBlockage->_postCreate ();
|
||||
Session::addInsertEvent ( trackBlockage, track );
|
||||
|
||||
ltrace(190) << "Adding: " << boundingBox << " on " << track << endl;
|
||||
|
||||
ltrace(200) << "TrackBlockage::create(): " << trackBlockage << endl;
|
||||
}
|
||||
return trackBlockage;
|
||||
}
|
||||
|
||||
|
||||
AutoSegment* TrackBlockage::base () const { return NULL; }
|
||||
bool TrackBlockage::isFixed () const { return true; }
|
||||
bool TrackBlockage::isBlockage () const { return true; }
|
||||
DbU::Unit TrackBlockage::getAxis () const { return getTrack()->getAxis(); }
|
||||
bool TrackBlockage::isHorizontal () const { return getTrack()->isHorizontal(); }
|
||||
bool TrackBlockage::isVertical () const { return getTrack()->isVertical(); }
|
||||
unsigned int TrackBlockage::getDirection () const { return getTrack()->getDirection(); }
|
||||
Net* TrackBlockage::getNet () const { return _segment->getNet(); }
|
||||
const Layer* TrackBlockage::getLayer () const { return _segment->getLayer(); }
|
||||
Interval TrackBlockage::getFreeInterval ( bool useOrder ) const { return Interval(); }
|
||||
|
||||
|
||||
unsigned long TrackBlockage::getId () const
|
||||
{
|
||||
cerr << Error("::getId() called on %s.",_getString().c_str()) << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TrackElement* TrackBlockage::getNext () const
|
||||
{
|
||||
size_t dummy = _index;
|
||||
return _track->getNext ( dummy, getNet() );
|
||||
}
|
||||
|
||||
|
||||
TrackElement* TrackBlockage::getPrevious () const
|
||||
{
|
||||
size_t dummy = _index;
|
||||
return _track->getPrevious ( dummy, getNet() );
|
||||
}
|
||||
|
||||
|
||||
string TrackBlockage::_getTypeName () const
|
||||
{ return "TrackBlockage"; }
|
||||
|
||||
|
||||
string TrackBlockage::_getString () const
|
||||
{
|
||||
string s1 = _segment->_getString();
|
||||
string s2 = " [" + DbU::getValueString(_sourceU)
|
||||
+ ":" + DbU::getValueString(_targetU) + "]"
|
||||
+ " " + DbU::getValueString(_targetU-_sourceU)
|
||||
+ " [" + ((_track) ? getString(_index) : "npos") + "]";
|
||||
s1.insert ( s1.size()-1, s2 );
|
||||
|
||||
return s1;
|
||||
}
|
||||
|
||||
|
||||
Record* TrackBlockage::_getRecord () const
|
||||
{
|
||||
Record* record = TrackElement::_getRecord ();
|
||||
record->add ( getSlot ( "_segment", _segment ) );
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,191 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./TrackCost.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
|
||||
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
#include "kite/Track.h"
|
||||
#include "kite/TrackCost.h"
|
||||
#include "kite/Session.h"
|
||||
|
||||
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "TrackCost".
|
||||
|
||||
|
||||
TrackCost::TrackCost ( Track* track
|
||||
, const Interval& interval
|
||||
, size_t begin
|
||||
, size_t end
|
||||
)
|
||||
: _track (track)
|
||||
, _begin (begin)
|
||||
, _end (end)
|
||||
, _interval (interval)
|
||||
, _blockage (false)
|
||||
, _fixed (false)
|
||||
, _infinite (false)
|
||||
, _hardOverlap (false)
|
||||
, _overlap (false)
|
||||
, _leftOverlap (false)
|
||||
, _rightOverlap (false)
|
||||
, _terminals (0)
|
||||
, _delta (-interval.getSize())
|
||||
, _deltaShared (0)
|
||||
, _deltaPerpand (0)
|
||||
, _axisWeight (0)
|
||||
, _distanceToFixed(DbU::Max)
|
||||
, _dataState (0)
|
||||
, _ripupCount (0)
|
||||
{
|
||||
TrackElement* neighbor;
|
||||
if ( _begin != Track::NPOS ) {
|
||||
neighbor = _track->getSegment(_begin);
|
||||
if ( neighbor && neighbor->isFixed() ) {
|
||||
if ( _distanceToFixed == DbU::Max ) _distanceToFixed = 0;
|
||||
_distanceToFixed += interval.getVMin() - neighbor->getTargetU();
|
||||
}
|
||||
}
|
||||
if ( _end != Track::NPOS ) {
|
||||
neighbor = _track->getSegment(_end);
|
||||
if ( neighbor && neighbor->isFixed() ) {
|
||||
if ( _distanceToFixed == DbU::Max ) _distanceToFixed = 0;
|
||||
_distanceToFixed += neighbor->getSourceU() - interval.getVMax();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TrackCost::~TrackCost ()
|
||||
{ }
|
||||
|
||||
|
||||
bool TrackCost::isFree () const
|
||||
{
|
||||
return /*(_terminals == 0) &&*/ (!_overlap) && (!_infinite);
|
||||
}
|
||||
|
||||
|
||||
bool operator< ( const TrackCost& lhs, const TrackCost& rhs )
|
||||
{
|
||||
if ( lhs._infinite xor rhs._infinite ) return rhs._infinite;
|
||||
if ( lhs._hardOverlap xor rhs._hardOverlap ) return rhs._hardOverlap;
|
||||
|
||||
if ( lhs._ripupCount + (int)Session::getRipupCost() < rhs._ripupCount ) return true;
|
||||
if ( lhs._ripupCount > rhs._ripupCount + (int)Session::getRipupCost() ) return false;
|
||||
|
||||
if ( lhs._overlap xor rhs._overlap ) return rhs._overlap;
|
||||
|
||||
//std::cerr << "lhs:" << lhs._ripupCount
|
||||
// << " rhs:" << rhs._ripupCount
|
||||
// << " " << rhs._ripupCount - lhs._ripupCount << " > " << Session::getRipupCost()
|
||||
// << std::endl;
|
||||
//if ( lhs._ripupCount - rhs._ripupCount > (int)Session::getRipupCost() ) return false;
|
||||
|
||||
if ( lhs._terminals < rhs._terminals ) return true;
|
||||
if ( lhs._terminals > rhs._terminals ) return false;
|
||||
|
||||
if ( lhs._delta < rhs._delta ) return true;
|
||||
if ( lhs._delta > rhs._delta ) return false;
|
||||
|
||||
if ( lhs._axisWeight < rhs._axisWeight ) return true;
|
||||
if ( lhs._axisWeight > rhs._axisWeight ) return false;
|
||||
|
||||
if ( lhs._deltaPerpand < rhs._deltaPerpand ) return true;
|
||||
if ( lhs._deltaPerpand > rhs._deltaPerpand ) return false;
|
||||
|
||||
if ( lhs._distanceToFixed > rhs._distanceToFixed ) return true;
|
||||
if ( lhs._distanceToFixed < rhs._distanceToFixed ) return false;
|
||||
|
||||
return lhs.getTrack()->getAxis() < rhs.getTrack()->getAxis();
|
||||
}
|
||||
|
||||
|
||||
bool TrackCost::CompareByDelta::operator() ( const TrackCost& lhs, const TrackCost& rhs )
|
||||
{
|
||||
return lhs.getDelta() < rhs.getDelta();
|
||||
}
|
||||
|
||||
|
||||
void TrackCost::consolidate ()
|
||||
{
|
||||
if ( !_infinite && !_hardOverlap ) {
|
||||
//_deltaPerpand += - (_deltaShared << 1);
|
||||
_delta += - _deltaShared;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
string TrackCost::_getString () const
|
||||
{
|
||||
string s = "<" + _getTypeName();
|
||||
|
||||
s += " " + getString(_track);
|
||||
s += " " + getString(_ripupCount);
|
||||
s += " " + getString(_ripupCount);
|
||||
s += " " + string ( (_blockage )?"b":"-" );
|
||||
s += string ( (_hardOverlap)?"h":"-" );
|
||||
s += string ( (_overlap )?"o":"-" );
|
||||
s += " " + getString(_terminals);
|
||||
s += "/" + DbU::getValueString(_delta);
|
||||
s += "/" + DbU::getValueString(_axisWeight);
|
||||
s += "/" + DbU::getValueString(_deltaPerpand);
|
||||
s += "/" + DbU::getValueString(_distanceToFixed);
|
||||
s += " " + getString(_dataState);
|
||||
s += ">";
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
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 ) );
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,305 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./TrackElement.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
|
||||
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/Name.h"
|
||||
#include "katabatic/AutoContact.h"
|
||||
#include "crlcore/RoutingGauge.h"
|
||||
#include "kite/GCell.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 )
|
||||
{
|
||||
cerr << Warning("No overlapCost callback has been set (%s)."
|
||||
,getString(segment).c_str()) << endl;
|
||||
}
|
||||
|
||||
|
||||
} // End of local namespace.
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Net;
|
||||
using Hurricane::Name;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "TrackElement::Compare".
|
||||
|
||||
|
||||
bool TrackElement::Compare::operator() ( TrackElement* lhs, TrackElement* rhs )
|
||||
{
|
||||
return lhs->getArea() > rhs->getArea();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "TrackElement::CompareByPosition".
|
||||
//
|
||||
// Return: lhs < rhs.
|
||||
|
||||
|
||||
bool TrackElement::CompareByPosition::operator() ( const TrackElement* lhs, const TrackElement* rhs ) const
|
||||
{
|
||||
if ( lhs == rhs ) return false;
|
||||
|
||||
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->isHorizontal() xor rhs->isHorizontal() )
|
||||
return rhs->isHorizontal();
|
||||
|
||||
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->isBlockage() and rhs->isBlockage() ) return false;
|
||||
|
||||
//return lhs->getNet()->getName() < rhs->getNet()->getName();
|
||||
return lhs->getId() < rhs->getId();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "TrackElement".
|
||||
|
||||
|
||||
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::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::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; }
|
||||
GCell* TrackElement::getGCell () const { return NULL; }
|
||||
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 () 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 () const { return false; };
|
||||
bool TrackElement::canMoveUp () const { return false; };
|
||||
bool TrackElement::canDogLeg () { return false; };
|
||||
bool TrackElement::canDogLeg ( Interval ) { return false; };
|
||||
bool TrackElement::canDogLegAt ( GCell*, bool allowReuse ) { return false; };
|
||||
TrackElement* TrackElement::getSourceDogLeg () { return NULL; }
|
||||
TrackElement* TrackElement::getTargetDogLeg () { return NULL; }
|
||||
void TrackElement::dataInvalidate () { }
|
||||
void TrackElement::eventInvalidate () { }
|
||||
void TrackElement::setGCell ( GCell* ) { }
|
||||
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::updateGCellsStiffness ( 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 () { 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 ( GCell* ) { return NULL; }
|
||||
TrackElement* TrackElement::_postDogLeg ( GCell* ) { return NULL; }
|
||||
void TrackElement::_postModify () { }
|
||||
void TrackElement::desalignate () { }
|
||||
bool TrackElement::_check () const { return true; }
|
||||
|
||||
|
||||
TrackElement::TrackElement ( Track* track )
|
||||
: _track(track)
|
||||
, _index((size_t)-1)
|
||||
{ }
|
||||
|
||||
|
||||
void TrackElement::_postCreate ()
|
||||
{ }
|
||||
|
||||
|
||||
TrackElement::~TrackElement ()
|
||||
{ }
|
||||
|
||||
|
||||
void TrackElement::_preDestroy ()
|
||||
{ }
|
||||
|
||||
|
||||
void TrackElement::destroy ()
|
||||
{
|
||||
_preDestroy ();
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
||||
TrackElement* TrackElement::getNext () const
|
||||
{
|
||||
size_t dummy = _index;
|
||||
return _track->getNext ( dummy, getNet() );
|
||||
}
|
||||
|
||||
|
||||
TrackElement* TrackElement::getPrevious () const
|
||||
{
|
||||
size_t dummy = _index;
|
||||
return _track->getPrevious ( dummy, getNet() );
|
||||
}
|
||||
|
||||
|
||||
Interval TrackElement::getFreeInterval ( bool useOrder ) const
|
||||
{
|
||||
if ( !_track ) return Interval(false);
|
||||
|
||||
size_t begin = _index;
|
||||
size_t end = _index;
|
||||
return _track->expandFreeInterval ( begin, end, Track::Inside, getNet(), useOrder );
|
||||
}
|
||||
|
||||
|
||||
size_t TrackElement::getGCells ( vector<GCell*>& gcells ) const
|
||||
{
|
||||
vector<GCell*>().swap ( gcells );
|
||||
return gcells.size();
|
||||
}
|
||||
|
||||
|
||||
size_t TrackElement::getPerpandicularsBound ( set<TrackElement*>& bounds )
|
||||
{
|
||||
bounds.clear ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned int TrackElement::getOrder () const
|
||||
{ return numeric_limits<unsigned int>::max(); }
|
||||
|
||||
|
||||
void TrackElement::incOverlapCost ( Net* net, TrackCost& cost ) const
|
||||
{
|
||||
if ( not _track or (getNet() == net) ) return;
|
||||
|
||||
_overlapCostCallback ( this, cost );
|
||||
}
|
||||
|
||||
|
||||
string TrackElement::_getTypeName () const
|
||||
{ return "TrackElement"; }
|
||||
|
||||
|
||||
string TrackElement::_getString () const
|
||||
{ return "<" + _getTypeName() + ">"; }
|
||||
|
||||
|
||||
Record* TrackElement::_getRecord () const
|
||||
{
|
||||
Record* record = new Record ( _getString() );
|
||||
record->add ( getSlot ( "_track", _track ) );
|
||||
record->add ( getSlot ( "_index", _index ) );
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,148 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./TrackElements.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/Interval.h"
|
||||
#include "kite/Session.h"
|
||||
#include "kite/TrackElement.h"
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using namespace std;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::inltrace;
|
||||
using Hurricane::ltracein;
|
||||
using Hurricane::ltraceout;
|
||||
using Hurricane::ForEachIterator;
|
||||
using Hurricane::Interval;
|
||||
using Hurricane::Bug;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "TrackElements_CollapsedPerpandicular".
|
||||
|
||||
|
||||
TrackElements_CollapsedPerpandicular::Locator::Locator ( TrackElement* segment )
|
||||
: TrackElementHL ()
|
||||
, _locator (segment->base())
|
||||
, _element (NULL)
|
||||
{
|
||||
ltrace(80) << "TrackElements_CollapsedPerpandicular::Locator::Locator()" << endl;
|
||||
ltrace(80) << " " << segment << endl;
|
||||
|
||||
Interval bounds;
|
||||
if ( _locator.isValid() ) {
|
||||
_element = Session::lookup ( _locator.getElement()->getCanonical(bounds)->base() );
|
||||
if ( !_element ) {
|
||||
cerr << Bug("Canonical segment whithout TrackElement.") << endl;
|
||||
progress ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TrackElement* TrackElements_CollapsedPerpandicular::Locator::getElement () const
|
||||
{ return _element; }
|
||||
|
||||
|
||||
void TrackElements_CollapsedPerpandicular::Locator::progress ()
|
||||
{
|
||||
ltrace(80) << "TrackElements_CollapsedPerpandicular::Locator::progress()" << endl;
|
||||
|
||||
Interval bounds;
|
||||
while ( _locator.isValid() ) {
|
||||
_locator.progress ();
|
||||
|
||||
if ( _locator.isValid() ) {
|
||||
_element = Session::lookup ( _locator.getElement()->getCanonical(bounds)->base() );
|
||||
if ( !_element ) {
|
||||
cerr << Bug("Canonical segment whithout TrackElement.") << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TrackElementHL* TrackElements_CollapsedPerpandicular::Locator::getClone () const
|
||||
{ return new Locator(*this); }
|
||||
|
||||
|
||||
bool TrackElements_CollapsedPerpandicular::Locator::isValid () const
|
||||
{ return _locator.isValid(); }
|
||||
|
||||
|
||||
TrackElementHC* TrackElements_CollapsedPerpandicular::getClone () const
|
||||
{ return new TrackElements_CollapsedPerpandicular(*this); }
|
||||
|
||||
|
||||
TrackElementHL* TrackElements_CollapsedPerpandicular::getLocator () const
|
||||
{ return new Locator(_segment); }
|
||||
|
||||
|
||||
string TrackElements_CollapsedPerpandicular::Locator::_getString () const
|
||||
{
|
||||
string s = "<TrackElements_CollapsedPerpandicular::Locator>";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
string TrackElements_CollapsedPerpandicular::_getString () const
|
||||
{
|
||||
string s = "<TrackElements_CollapsedPerpandicular "
|
||||
+ getString(_segment)
|
||||
+ ">";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "TrackElements_UniqCanonical".
|
||||
|
||||
|
||||
TrackElementHF* TrackElements_UniqCanonical::getClone () const
|
||||
{ return new TrackElements_UniqCanonical(_canonicals); }
|
||||
|
||||
|
||||
bool TrackElements_UniqCanonical::accept ( TrackElement* segment ) const
|
||||
{
|
||||
if ( _canonicals.find(segment) == _canonicals.end() ) {
|
||||
_canonicals.insert ( segment );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
string TrackElements_UniqCanonical::_getString () const
|
||||
{ return "<TrackElements_UniqCanonical>"; }
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,220 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2010, 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 : "./TrackFixedSegment.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#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 "crlcore/RoutingGauge.h"
|
||||
#include "kite/GCell.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/GCellGrid.h"
|
||||
#include "kite/KiteEngine.h"
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using namespace std;
|
||||
using Hurricane::inltrace;
|
||||
using Hurricane::ltracein;
|
||||
using Hurricane::ltraceout;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::ForEachIterator;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Net;
|
||||
using Hurricane::Name;
|
||||
using Hurricane::RegularLayer;
|
||||
using Hurricane::Technology;
|
||||
using Hurricane::DataBase;
|
||||
using Hurricane::Horizontal;
|
||||
using Hurricane::Vertical;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "TrackFixedSegment".
|
||||
|
||||
|
||||
TrackFixedSegment::TrackFixedSegment ( Track* track, Segment* segment )
|
||||
: TrackElement (NULL)
|
||||
, _segment (segment)
|
||||
{
|
||||
Box boundingBox = segment->getBoundingBox();
|
||||
|
||||
if ( track ) {
|
||||
unsigned int depth = track->getDepth();
|
||||
Technology* technology = DataBase::getDB()->getTechnology();
|
||||
const Layer* layer1 = track->getLayer()->getBlockageLayer();
|
||||
RegularLayer* layer2 = dynamic_cast<RegularLayer*>(technology->getLayer(layer1->getMask()));
|
||||
if ( layer2 ) {
|
||||
DbU::Unit extention = layer2->getExtentionCap();
|
||||
if ( track->getDirection() == Constant::Horizontal ) {
|
||||
_sourceU = boundingBox.getXMin()-extention;
|
||||
_targetU = boundingBox.getXMax()+extention;
|
||||
|
||||
GCell* gcell = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(_sourceU,track->getAxis()) );
|
||||
GCell* end = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(_targetU,track->getAxis()) );
|
||||
GCell* right = NULL;
|
||||
if ( gcell ) {
|
||||
while ( gcell and (gcell != end) ) {
|
||||
right = gcell->getRight();
|
||||
if ( right == NULL ) break;
|
||||
gcell->addBlockage ( depth, 1.0 );
|
||||
gcell = right;
|
||||
}
|
||||
if ( end ) end->addBlockage ( depth, 1.0 );
|
||||
} else
|
||||
cerr << Warning("TrackFixedSegment(): TrackFixedElement outside GCell grid.") << endl;
|
||||
} else {
|
||||
_sourceU = boundingBox.getYMin()-extention;
|
||||
_targetU = boundingBox.getYMax()+extention;
|
||||
|
||||
GCell* gcell = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(track->getAxis(),_sourceU) );
|
||||
GCell* end = track->getKiteEngine()->getGCellGrid()->getGCell ( Point(track->getAxis(),_targetU) );
|
||||
GCell* up = NULL;
|
||||
if ( gcell ) {
|
||||
while ( gcell and (gcell != end) ) {
|
||||
up = gcell->getUp();
|
||||
if ( up == NULL ) break;
|
||||
gcell->addBlockage ( depth, 1.0 );
|
||||
gcell = up;
|
||||
}
|
||||
if ( end ) end->addBlockage ( depth, 1.0 );
|
||||
} else
|
||||
cerr << Warning("TrackFixedSegment(): TrackFixedElement outside GCell grid.") << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TrackFixedSegment::_postCreate ()
|
||||
{ TrackElement::_postCreate (); }
|
||||
|
||||
|
||||
TrackFixedSegment::~TrackFixedSegment ()
|
||||
{ }
|
||||
|
||||
|
||||
void TrackFixedSegment::_preDestroy ()
|
||||
{
|
||||
ltrace(90) << "TrackFixedSegment::_preDestroy() - " << (void*)this << endl;
|
||||
TrackElement::_preDestroy ();
|
||||
}
|
||||
|
||||
|
||||
TrackElement* TrackFixedSegment::create ( Track* track, Segment* segment )
|
||||
{
|
||||
TrackFixedSegment* trackFixedSegment = NULL;
|
||||
if ( track ) {
|
||||
trackFixedSegment = new TrackFixedSegment ( track, segment );
|
||||
trackFixedSegment->_postCreate ();
|
||||
Session::addInsertEvent ( trackFixedSegment, track );
|
||||
|
||||
ltrace(190) << "Adding: " << segment << " on " << track << endl;
|
||||
ltrace(200) << "TrackFixedSegment::create(): " << trackFixedSegment << endl;
|
||||
}
|
||||
return trackFixedSegment;
|
||||
}
|
||||
|
||||
|
||||
AutoSegment* TrackFixedSegment::base () const { return NULL; }
|
||||
bool TrackFixedSegment::isFixed () const { return true; }
|
||||
bool TrackFixedSegment::isBlockage () const { return true; }
|
||||
DbU::Unit TrackFixedSegment::getAxis () const { return getTrack()->getAxis(); }
|
||||
bool TrackFixedSegment::isHorizontal () const { return getTrack()->isHorizontal(); }
|
||||
bool TrackFixedSegment::isVertical () const { return getTrack()->isVertical(); }
|
||||
unsigned int TrackFixedSegment::getDirection () const { return getTrack()->getDirection(); }
|
||||
Net* TrackFixedSegment::getNet () const { return _segment->getNet(); }
|
||||
const Layer* TrackFixedSegment::getLayer () const { return _segment->getLayer(); }
|
||||
Interval TrackFixedSegment::getFreeInterval ( bool useOrder ) const { return Interval(); }
|
||||
|
||||
|
||||
unsigned long TrackFixedSegment::getId () const
|
||||
{
|
||||
cerr << Error("::getId() called on %s.",_getString().c_str()) << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TrackElement* TrackFixedSegment::getNext () const
|
||||
{
|
||||
size_t dummy = _index;
|
||||
return _track->getNext ( dummy, getNet() );
|
||||
}
|
||||
|
||||
|
||||
TrackElement* TrackFixedSegment::getPrevious () const
|
||||
{
|
||||
size_t dummy = _index;
|
||||
return _track->getPrevious ( dummy, getNet() );
|
||||
}
|
||||
|
||||
|
||||
string TrackFixedSegment::_getTypeName () const
|
||||
{ return "TrackFixedSegment"; }
|
||||
|
||||
|
||||
string TrackFixedSegment::_getString () const
|
||||
{
|
||||
string s1 = _segment->_getString();
|
||||
string s2 = " [" + DbU::getValueString(_sourceU)
|
||||
+ ":" + DbU::getValueString(_targetU) + "]"
|
||||
+ " " + DbU::getValueString(_targetU-_sourceU)
|
||||
+ " [" + ((_track) ? getString(_index) : "npos") + "]";
|
||||
s1.insert ( s1.size()-1, s2 );
|
||||
|
||||
return s1;
|
||||
}
|
||||
|
||||
|
||||
Record* TrackFixedSegment::_getRecord () const
|
||||
{
|
||||
Record* record = TrackElement::_getRecord ();
|
||||
record->add ( getSlot ( "_segment", _segment ) );
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,145 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./TrackMarker.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#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 "kite/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;
|
||||
using std::setprecision;
|
||||
using Hurricane::Bug;
|
||||
using CRL::RoutingGauge;
|
||||
|
||||
|
||||
TrackMarker* TrackMarker::create ( RoutingPad* rp, size_t depth )
|
||||
{
|
||||
TrackMarker* segment = new TrackMarker ( rp, depth );
|
||||
return segment;
|
||||
}
|
||||
|
||||
|
||||
void TrackMarker::destroy ()
|
||||
{
|
||||
if ( !--_refcount ) delete this;
|
||||
}
|
||||
|
||||
|
||||
TrackMarker::TrackMarker ( RoutingPad* pad, size_t depth )
|
||||
: _routingPad (pad)
|
||||
, _sourcePosition(0)
|
||||
, _targetPosition(0)
|
||||
, _track (NULL)
|
||||
, _weight (0)
|
||||
, _refcount (0)
|
||||
{
|
||||
Point sourcePoint = pad->getSourcePosition();
|
||||
Point targetPoint = pad->getTargetPosition();
|
||||
RoutingGauge* rg = Session::getKiteEngine()->getRoutingGauge();
|
||||
RoutingPlane* rp = Session::getKiteEngine()->getRoutingPlaneByIndex(depth);
|
||||
unsigned int rpDirection = rg->getLayerDirection(depth);
|
||||
Interval trackSpan;
|
||||
|
||||
if ( rpDirection == Constant::Horizontal ) {
|
||||
_sourcePosition = sourcePoint.getX();
|
||||
_targetPosition = targetPoint.getX();
|
||||
trackSpan = Interval ( sourcePoint.getY(), targetPoint.getY() );
|
||||
} else {
|
||||
_sourcePosition = sourcePoint.getY();
|
||||
_targetPosition = targetPoint.getY();
|
||||
trackSpan = Interval ( sourcePoint.getX(), targetPoint.getX() );
|
||||
}
|
||||
|
||||
if ( rpDirection xor rg->getLayerDirection(rg->getLayerDepth(pad->getLayer())) ) {
|
||||
_weight = (unsigned int)(( 5.0 / (5.0+DbU::getLambda(trackSpan.getSize())) ) * 100.0) ;
|
||||
} else {
|
||||
_weight = (unsigned int)( (5.0 + DbU::getLambda(trackSpan.getSize())) * 20.0 );
|
||||
}
|
||||
|
||||
Track* track = rp->getTrackByPosition ( trackSpan.getVMin() );
|
||||
while ( track && (track->getAxis() <= trackSpan.getVMax()) ) {
|
||||
Session::addInsertEvent ( this, track );
|
||||
track = track->getNext ();
|
||||
_refcount++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Net* TrackMarker::getNet () const
|
||||
{ return _routingPad->getNet(); }
|
||||
|
||||
|
||||
string TrackMarker::_getTypeName () const
|
||||
{ return "TrackMarker"; }
|
||||
|
||||
|
||||
string TrackMarker::_getString () const
|
||||
{
|
||||
ostringstream s;
|
||||
s << "<" << _getTypeName()
|
||||
<< " " << getNet()->getName()
|
||||
<< " [" << DbU::getValueString(_sourcePosition)
|
||||
<< ":" << DbU::getValueString(_targetPosition)
|
||||
<< " " << setprecision(3) << ((double)_weight)/100.0
|
||||
<< ">";
|
||||
return s.str();
|
||||
}
|
||||
|
||||
|
||||
Record* TrackMarker::_getRecord () const
|
||||
{
|
||||
Record* record = new Record ( _getString() );
|
||||
record->add ( getSlot ( "_routingPad" , _routingPad ) );
|
||||
record->add ( getSlot ( "_sourcePosition", _sourcePosition ) );
|
||||
record->add ( getSlot ( "_targetPosition", _targetPosition ) );
|
||||
record->add ( getSlot ( "_track" , _track ) );
|
||||
record->add ( getSlot ( "_weight" , _weight ) );
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,219 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./TrackSegmentCost.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
|
||||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "katabatic/AutoSegment.h"
|
||||
#include "kite/TrackElement.h"
|
||||
#include "kite/TrackSegmentCost.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;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "TrackSegmentCost".
|
||||
|
||||
|
||||
TrackSegmentCost::TrackSegmentCost ( TrackElement* trackSegment )
|
||||
: _terminals (0)
|
||||
, _ripupCount (0)
|
||||
, _leftMinExtend (DbU::Max)
|
||||
, _rightMinExtend(DbU::Min)
|
||||
, _net (trackSegment->getNet())
|
||||
, _attractors ()
|
||||
{
|
||||
//update ( trackSegment );
|
||||
}
|
||||
|
||||
|
||||
TrackSegmentCost::~TrackSegmentCost ()
|
||||
{ }
|
||||
|
||||
|
||||
DbU::Unit TrackSegmentCost::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 TrackSegmentCost::update ( TrackElement* trackSegment )
|
||||
{
|
||||
DebugSession::open ( trackSegment->getNet(), 148 );
|
||||
|
||||
ltrace(148) << "TrackSegmentCost::update() - " << trackSegment << endl;
|
||||
ltracein(148);
|
||||
|
||||
vector<AutoSegment*> collapseds;
|
||||
vector<AutoSegment*> perpandiculars;
|
||||
map<DbU::Unit,int> attractorSpins;
|
||||
|
||||
AutoSegment::getTopologicalInfos ( trackSegment->base()
|
||||
, collapseds
|
||||
, perpandiculars
|
||||
, _leftMinExtend
|
||||
, _rightMinExtend
|
||||
);
|
||||
|
||||
_terminals = AutoSegment::getTerminalCount ( trackSegment->base(), collapseds );
|
||||
_attractors.clear ();
|
||||
|
||||
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 ( !perpandicular ) {
|
||||
cerr << Bug("Not a TrackSegment: %s:%s\n (perpandicular: %s:%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;
|
||||
}
|
||||
interval.inflate ( DbU::lambda(-1.5) );
|
||||
|
||||
ltrace(148) << "| perpandicular: " << perpandiculars[i] << endl;
|
||||
ltrace(148) << "| canonical: " << perpandicular << endl;
|
||||
ltracein(148);
|
||||
ltrace(148) << "interval: " << interval << 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() )
|
||||
|| AutoSegment::isTopologicalBound(perpandiculars[i]
|
||||
,false
|
||||
,perpandicular->isHorizontal()
|
||||
) ) {
|
||||
map<DbU::Unit,int>::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() )
|
||||
|| AutoSegment::isTopologicalBound(perpandiculars[i]
|
||||
,true
|
||||
,perpandicular->isHorizontal()
|
||||
) ) {
|
||||
map<DbU::Unit,int>::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);
|
||||
}
|
||||
|
||||
map<DbU::Unit,int>::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;
|
||||
|
||||
|
||||
ltraceout(148);
|
||||
DebugSession::close ();
|
||||
}
|
||||
|
||||
|
||||
string TrackSegmentCost::_getString () const
|
||||
{
|
||||
return "<" + _getTypeName() + " "
|
||||
+ getString(_terminals)
|
||||
+ " [" + DbU::getValueString(_leftMinExtend)
|
||||
+ ":" + DbU::getValueString(_rightMinExtend)
|
||||
+ "]>";
|
||||
}
|
||||
|
||||
|
||||
Record* TrackSegmentCost::_getRecord () const
|
||||
{
|
||||
Record* record = new Record ( getString(this) );
|
||||
record->add ( getSlot ( "_terminals" , _terminals ) );
|
||||
record->add ( getSlot ( "_ripupCount" , _ripupCount ) );
|
||||
record->add ( getSlot ( "_leftMinExtend" , &_leftMinExtend ) );
|
||||
record->add ( getSlot ( "_rightMinExtend", &_rightMinExtend ) );
|
||||
record->add ( getSlot ( "_net" , _net ) );
|
||||
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|
|
@ -0,0 +1,329 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./Tracks.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "kite/Track.h"
|
||||
#include "kite/Tracks.h"
|
||||
#include "kite/RoutingPlane.h"
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::inltrace;
|
||||
using Hurricane::ltracein;
|
||||
using Hurricane::ltraceout;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Tracks_Range::Locator".
|
||||
|
||||
|
||||
Tracks_Range::Locator::Locator ( const RoutingPlane* routingPlane
|
||||
, const Interval& constraints
|
||||
)
|
||||
: Hurricane::Locator<Track*>()
|
||||
, _constraints (constraints)
|
||||
{
|
||||
ltrace(147) << "Tracks_Range::Locator()" << endl;
|
||||
ltrace(147) << "* Constraints: " << _constraints << endl;
|
||||
|
||||
_track = routingPlane->getTrackByPosition ( _constraints.getVMin() );
|
||||
|
||||
if ( _track && (_track->getAxis() < _constraints.getVMin()) ) _track = _track->getNext();
|
||||
if ( _track && (_track->getAxis() > _constraints.getVMax()) ) _track = NULL;
|
||||
|
||||
ltrace(147) << "_track: " << _track << endl;;
|
||||
}
|
||||
|
||||
|
||||
Tracks_Range::Locator::Locator ( const Locator& locator )
|
||||
: Hurricane::Locator<Track*>()
|
||||
, _constraints(locator._constraints)
|
||||
, _track (locator._track)
|
||||
{ }
|
||||
|
||||
|
||||
Hurricane::Locator<Track*>* Tracks_Range::Locator::getClone () const
|
||||
{ return new Locator(*this); }
|
||||
|
||||
|
||||
bool Tracks_Range::Locator::isValid () const
|
||||
{ return (_track != NULL); }
|
||||
|
||||
|
||||
Track* Tracks_Range::Locator::getElement () const
|
||||
{ return _track; }
|
||||
|
||||
|
||||
|
||||
void Tracks_Range::Locator::progress ()
|
||||
{
|
||||
if ( !_track ) return;
|
||||
|
||||
_track = _track->getNext ();
|
||||
if ( _track && (_track->getAxis() > _constraints.getVMax()) ) _track = NULL;
|
||||
}
|
||||
|
||||
|
||||
string Tracks_Range::Locator::_getString () const
|
||||
{
|
||||
string s = "<Tracks_Range::Locator ["
|
||||
+ DbU::getValueString(_constraints.getVMin()) + ":"
|
||||
+ DbU::getValueString(_constraints.getVMax()) + "] "
|
||||
+ getString(_track) + ">";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Tracks_Range".
|
||||
|
||||
|
||||
Tracks Tracks_Range::get ( RoutingPlane* routingPlane
|
||||
, Interval& constraints )
|
||||
{ return new Tracks_Range ( routingPlane, constraints ); }
|
||||
|
||||
|
||||
Tracks_Range::Tracks_Range ( const RoutingPlane* routingPlane
|
||||
, const Interval& constraints )
|
||||
: Collection<Track*>()
|
||||
, _routingPlane(routingPlane)
|
||||
, _constraints (constraints)
|
||||
{ }
|
||||
|
||||
|
||||
Tracks_Range::Tracks_Range ( const Tracks_Range& tracks )
|
||||
: Collection<Track*>()
|
||||
, _routingPlane(tracks._routingPlane)
|
||||
, _constraints (tracks._constraints)
|
||||
{ }
|
||||
|
||||
|
||||
Collection<Track*>* Tracks_Range::getClone () const
|
||||
{ return new Tracks_Range(*this); }
|
||||
|
||||
|
||||
Hurricane::Locator<Track*>* Tracks_Range::getLocator () const
|
||||
{ return new Locator(_routingPlane,_constraints); }
|
||||
|
||||
|
||||
string Tracks_Range::_getString () const
|
||||
{
|
||||
string s = "<" + _TName("Tracks_Range") + " "
|
||||
+ getString(_routingPlane->getLayer()) + " ["
|
||||
+ getString(_constraints.getVMin()) + ":"
|
||||
+ getString(_constraints.getVMax()) + "]"
|
||||
+ ">";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Tracks_Spiral::Locator".
|
||||
|
||||
|
||||
Tracks_Spiral::Locator::Locator ( const RoutingPlane* routingPlane
|
||||
, const Interval& optimal
|
||||
, const Interval& constraints
|
||||
)
|
||||
: Hurricane::Locator<Track*>()
|
||||
, _optimal (optimal)
|
||||
, _constraints (constraints)
|
||||
, _onMin (false)
|
||||
, _inMinOptimal(true)
|
||||
, _inMaxOptimal(true)
|
||||
{
|
||||
ltrace(147) << "Tracks_Spiral::Locator()" << endl;
|
||||
ltrace(147) << "* Optimal: " << _optimal << endl;
|
||||
ltrace(147) << "* Constraints: " << _constraints << endl;
|
||||
|
||||
_minTrack = _maxTrack = routingPlane->getTrackByPosition ( _optimal.getCenter() );
|
||||
|
||||
if ( _minTrack->getAxis() < _constraints.getVMin() ) _minTrack = NULL;
|
||||
if ( _maxTrack->getAxis() > _constraints.getVMax() ) _maxTrack = NULL;
|
||||
|
||||
if ( _minTrack && !_maxTrack ) {
|
||||
_minTrack = _minTrack->getPrevious ();
|
||||
if ( _minTrack->getAxis() < _constraints.getVMin() ) _minTrack = NULL;
|
||||
}
|
||||
|
||||
if ( _maxTrack && !_minTrack ) {
|
||||
_maxTrack = _maxTrack->getNext ();
|
||||
if ( _maxTrack->getAxis() > _constraints.getVMax() ) _maxTrack = NULL;
|
||||
}
|
||||
|
||||
if ( _minTrack && (_minTrack->getAxis() < _optimal.getVMin()) ) _inMinOptimal = false;
|
||||
if ( _maxTrack && (_maxTrack->getAxis() > _optimal.getVMax()) ) _inMaxOptimal = false;
|
||||
|
||||
ltrace(147) << "_minTrack: " << _minTrack << endl;;
|
||||
ltrace(147) << "_maxTrack: " << _maxTrack << endl;;
|
||||
}
|
||||
|
||||
|
||||
Tracks_Spiral::Locator::Locator ( const Locator& locator )
|
||||
: Hurricane::Locator<Track*>()
|
||||
, _optimal (locator._optimal)
|
||||
, _constraints (locator._constraints)
|
||||
, _minTrack (locator._minTrack)
|
||||
, _maxTrack (locator._maxTrack)
|
||||
, _onMin (locator._onMin)
|
||||
, _inMinOptimal(locator._inMinOptimal)
|
||||
, _inMaxOptimal(locator._inMaxOptimal)
|
||||
{ }
|
||||
|
||||
|
||||
Hurricane::Locator<Track*>* Tracks_Spiral::Locator::getClone () const
|
||||
{ return new Locator(*this); }
|
||||
|
||||
|
||||
bool Tracks_Spiral::Locator::isValid () const
|
||||
{ return _minTrack||_maxTrack; }
|
||||
|
||||
|
||||
Track* Tracks_Spiral::Locator::getElement () const
|
||||
{
|
||||
if ( !_minTrack ) return _maxTrack;
|
||||
if ( !_maxTrack ) return _minTrack;
|
||||
|
||||
return (_onMin) ? _maxTrack : _minTrack;
|
||||
}
|
||||
|
||||
|
||||
bool Tracks_Spiral::Locator::InOptimal () const
|
||||
{ return _inMinOptimal&&_inMaxOptimal; }
|
||||
|
||||
|
||||
|
||||
void Tracks_Spiral::Locator::progress ()
|
||||
{
|
||||
ltrace(147) << "Track_Spiral::progress() - State:" << endl;
|
||||
ltracein(147);
|
||||
ltrace(147) << _onMin
|
||||
<< " " << _minTrack
|
||||
<< " " << _maxTrack << endl;
|
||||
|
||||
if ( !isValid() ) {
|
||||
ltraceout(147);
|
||||
return;
|
||||
}
|
||||
|
||||
if ( _onMin ) {
|
||||
_onMin = (_maxTrack == NULL);
|
||||
if ( _minTrack ) {
|
||||
_minTrack = _minTrack->getPrevious();
|
||||
|
||||
if ( _minTrack ) {
|
||||
if ( _minTrack->getAxis() < _optimal.getVMin() ) _inMinOptimal = false;
|
||||
if ( _minTrack->getAxis() < _constraints.getVMin() ) _minTrack = NULL;
|
||||
}
|
||||
if ( !_minTrack && _maxTrack ) progress();
|
||||
}
|
||||
} else {
|
||||
_onMin = (_minTrack != NULL);
|
||||
if ( _maxTrack ) {
|
||||
_maxTrack = _maxTrack->getNext();
|
||||
|
||||
if ( _maxTrack ) {
|
||||
if ( _maxTrack->getAxis() > _optimal.getVMax() ) _inMaxOptimal = false;
|
||||
if ( _maxTrack->getAxis() > _constraints.getVMax() ) _maxTrack = NULL;
|
||||
}
|
||||
|
||||
if ( !_maxTrack && _minTrack ) progress();
|
||||
}
|
||||
}
|
||||
|
||||
ltrace(147) << _onMin
|
||||
<< " " << _minTrack
|
||||
<< " " << _maxTrack << endl;
|
||||
ltraceout(147);
|
||||
}
|
||||
|
||||
|
||||
string Tracks_Spiral::Locator::_getString () const
|
||||
{
|
||||
string s = "<Tracks_Spiral::Locator ["
|
||||
+ getString(_minTrack) + ":"
|
||||
+ getString(_maxTrack) + "]"
|
||||
+ getString(_onMin)
|
||||
+ ">";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Tracks_Spiral".
|
||||
|
||||
|
||||
Tracks Tracks_Spiral::get ( RoutingPlane* routingPlane
|
||||
, Interval& optimal
|
||||
, Interval& constraints )
|
||||
{ return new Tracks_Spiral ( routingPlane, optimal, constraints ); }
|
||||
|
||||
|
||||
Tracks_Spiral::Tracks_Spiral ( const RoutingPlane* routingPlane
|
||||
, const Interval& optimal
|
||||
, const Interval& constraints )
|
||||
: Collection<Track*>()
|
||||
, _routingPlane(routingPlane)
|
||||
, _optimal (optimal)
|
||||
, _constraints (constraints)
|
||||
{ }
|
||||
|
||||
|
||||
Tracks_Spiral::Tracks_Spiral ( const Tracks_Spiral& tracks )
|
||||
: Collection<Track*>()
|
||||
, _routingPlane(tracks._routingPlane)
|
||||
, _optimal (tracks._optimal)
|
||||
, _constraints (tracks._constraints)
|
||||
{ }
|
||||
|
||||
|
||||
Collection<Track*>* Tracks_Spiral::getClone () const
|
||||
{ return new Tracks_Spiral(*this); }
|
||||
|
||||
|
||||
Hurricane::Locator<Track*>* Tracks_Spiral::getLocator () const
|
||||
{ return new Locator(_routingPlane,_optimal,_constraints); }
|
||||
|
||||
|
||||
string Tracks_Spiral::_getString () const
|
||||
{
|
||||
string s = "<" + _TName("Tracks_Spiral") + " "
|
||||
+ getString(_routingPlane->getLayer()) + " ["
|
||||
+ getString(_constraints.getVMin()) + " ("
|
||||
+ getString(_optimal.getVMin()) + ":"
|
||||
+ getString(_optimal.getVMax()) + ") "
|
||||
+ getString(_constraints.getVMax()) + "]"
|
||||
+ ">";
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
} // End of Katabatic namespace.
|
|
@ -0,0 +1,83 @@
|
|||
|
||||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC/LIP6 2008-2009, 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 : "./VerticalTrack.cpp" |
|
||||
// | *************************************************************** |
|
||||
// | U p d a t e s |
|
||||
// | |
|
||||
// x-----------------------------------------------------------------x
|
||||
|
||||
|
||||
#include "kite/VerticalTrack.h"
|
||||
|
||||
|
||||
namespace Kite {
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "VerticalTrack".
|
||||
|
||||
|
||||
VerticalTrack::VerticalTrack ( RoutingPlane* routingPlane, unsigned int index )
|
||||
: Track(routingPlane,index)
|
||||
{ }
|
||||
|
||||
|
||||
void VerticalTrack::_postCreate ()
|
||||
{ }
|
||||
|
||||
|
||||
VerticalTrack* VerticalTrack::create ( RoutingPlane* routingPlane, unsigned int index )
|
||||
{
|
||||
VerticalTrack* track = new VerticalTrack ( routingPlane, index );
|
||||
|
||||
track->_postCreate ();
|
||||
|
||||
return track;
|
||||
}
|
||||
|
||||
|
||||
VerticalTrack::~VerticalTrack ()
|
||||
{ }
|
||||
|
||||
|
||||
void VerticalTrack::_preDestroy ()
|
||||
{ }
|
||||
|
||||
|
||||
bool VerticalTrack::isHorizontal () const { return false; }
|
||||
bool VerticalTrack::isVertical () const { return true; }
|
||||
unsigned int VerticalTrack::getDirection () const { return Constant::Vertical; }
|
||||
|
||||
|
||||
Point VerticalTrack::getPosition ( DbU::Unit coordinate ) const
|
||||
{ return Point ( getAxis(), coordinate ); }
|
||||
|
||||
|
||||
string VerticalTrack::_getTypeName () const
|
||||
{ return "VerticalTrack"; }
|
||||
|
||||
|
||||
Record* VerticalTrack::_getRecord () const
|
||||
{
|
||||
Record* record = Track::_getRecord ();
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
} // End of Kite namespace.
|