Compare commits

..

No commits in common. "devel" and "devel_anabatic" have entirely different histories.

6826 changed files with 223980 additions and 1123677 deletions

1
.gitignore vendored
View File

@ -40,4 +40,3 @@ documentation/RDS/RDS.toc
cumulus/src/plugins/CoreToChip_c35b4.py
cumulus/src/plugins/core2chip/c35b4.py
/result*

View File

@ -1,54 +0,0 @@
linux:
image: python:3.8
# make a docker daemon available for cibuildwheel to use
services:
- name: docker:dind
entrypoint: ["env", "-u", "DOCKER_HOST"]
command: ["dockerd-entrypoint.sh"]
variables:
DOCKER_HOST: tcp://docker:2375/
DOCKER_DRIVER: overlay2
# See https://github.com/docker-library/docker/pull/166
DOCKER_TLS_CERTDIR: ""
script:
- curl -sSL https://get.docker.com/ | sh
- python -m pip install cibuildwheel==2.11.3
- cibuildwheel --output-dir wheelhouse
parallel:
matrix:
- CIBW_BUILD: [cp38-manylinux*, cp39-manylinux*, cp310-manylinux*, cp311-manylinux*]
CIBW_ARCHS_LINUX: [auto64]
artifacts:
paths:
- wheelhouse/
dist:
image: python:3.8
needs:
- job: linux
artifacts: true
except:
- merge_requests
variables:
TWINE_PASSWORD: '${CI_JOB_TOKEN}'
TWINE_USERNAME: 'gitlab-ci-token'
TWINE_REPOSITORY_URL: 'https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/packages/pypi'
script:
- python -m pip install --upgrade build twine
- python -m twine check --strict wheelhouse/*
- python -m twine upload --verbose wheelhouse/*
#windows:
# image: mcr.microsoft.com/windows/servercore:1809
# before_script:
# - choco install python -y --version 3.8.6
# - choco install git.install -y
# - py -m pip install cibuildwheel==2.11.3
# script:
# - py -m cibuildwheel --output-dir wheelhouse --platform windows
# artifacts:
# paths:
# - wheelhouse/
# tags:
# - windows

6
.gitmodules vendored
View File

@ -1,6 +0,0 @@
[submodule "coloquinte"]
path = coloquinte
# url = git@github.com:Coloquinte/PlaceRoute.git
url = https://github.com/Coloquinte/PlaceRoute.git
branch = coriolis-submodule
update = merge

View File

@ -1,28 +0,0 @@
=========
COPYRIGHT
=========
* The **LEF/DEF** components of Coriolis are copyrighted by: ::
Cadence Design Systems 2012-2017
And released under the Apache 2.0 license
* The **flute** component of Coriolis is copyrighted by: ::
Dr. Chris C. N. Chu 2004
Iowa State University
http://home.engineering.iastate.edu/~cnchu/
And released under it's own license (derived from BSD)
* The **Hurricane** component of Coriolis is copyrighted by: ::
Bull S.A. 2000-2021 (now ATOS)
And released under the LGPL license
* **All other components** of Coriolis are copyrighted by: ::
Sorbonne Université 2000-2021 (formerly UPMC)
And released under the GPLv2 license

View File

@ -1,35 +0,0 @@
#This is needed for poetry to recognise the top level module
import os
import sys
import subprocess
__version__ = "0.0.0"
#TODO not PEP302 complient -probably a big porting job
coriolis_package_dir = os.path.abspath(os.path.dirname(__file__))
os.environ["CORIOLIS_TOP"] = coriolis_package_dir
CORIOLIS_DATA = os.path.join(os.path.dirname(__file__), 'data')
CORIOLIS_BIN = os.path.join(CORIOLIS_DATA,"bin")
def _program(name, args):
return subprocess.call([os.path.join(CORIOLIS_BIN, name)] + args, close_fds=False)
def blif2vst():
raise SystemExit(_program("blif2vst.py", sys.argv[1:]))
def cx2y():
raise SystemExit(_program("cx2y", sys.argv[1:]))
def cyclop():
raise SystemExit(_program("cyclop", sys.argv[1:]))
def tutorial():
raise SystemExit(_program("tutorial", sys.argv[1:]))
def unittests():
raise SystemExit(_program("unittests", sys.argv[1:]))
def yosys_coriolis():
raise SystemExit(_program("yosys.py", sys.argv[1:]))

View File

@ -1,376 +0,0 @@
==========================
GNU GENERAL PUBLIC LICENSE
==========================
**Version 2, June 1991**
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
========
The licenses for most software are designed to take away your freedom
to share and change it. By contrast, the GNU General Public License
is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit
to using it. (Some other Free Software Foundation software is covered
by the GNU Lesser General Public License instead.) You can apply it
to your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge
for this service if you wish), that you receive source code or can
get it if you want it, that you can change the software or use pieces
of it in new free programs; and that you know you can do these
things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software,
and (2) offer you this license which gives you legal permission to
copy, distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on,
we want its recipients to know that what they have is not the
original, so that any problems introduced by others will not reflect
on the original authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making
the program proprietary. To prevent this, we have made it clear that
any patent must be licensed for everyone's free use or not licensed
at all.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
===============================================================
0. This License applies to any program or other work which contains a
notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program",
below, refers to any such program or work, and a "work based on
the Program" means either the Program or any derivative work under
copyright law: that is to say, a work containing the Program or a
portion of it, either verbatim or with modifications and/or
translated into another language. (Hereinafter, translation is
included without limitation in the term "modification".) Each
licensee is addressed as "you".
Activities other than copying, distribution and modification are
not covered by this License; they are outside its scope. The act
of running the Program is not restricted, and the output from the
Program is covered only if its contents constitute a work based on
the Program (independent of having been made by running the
Program). Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep
intact all the notices that refer to this License and to the
absence of any warranty; and give any other recipients of the
Program a copy of this License along with the Program.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange
for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all
third parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display
an announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you
provide a warranty) and that users may redistribute the program
under these conditions, and telling the user how to view a copy
of this License. (Exception: if the Program itself is
interactive but does not normally print such an announcement,
your work based on the Program is not required to print an
announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the
Program, and can be reasonably considered independent and separate
works in themselves, then this License, and its terms, do not
apply to those sections when you distribute them as separate
works. But when you distribute the same sections as part of a
whole which is a work based on the Program, the distribution of
the whole must be on the terms of this License, whose permissions
for other licensees extend to the entire whole, and thus to each
and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or
contest your rights to work written entirely by you; rather, the
intent is to exercise the right to control the distribution of
derivative or collective works based on the Program.
In addition, mere aggregation of another work not based on the
Program with the Program (or with a work based on the Program) on
a volume of a storage or distribution medium does not bring the
other work under the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms
of Sections 1 and 2 above provided that you also do one of the
following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of
Sections 1 and 2 above on a medium customarily used for
software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with
such an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work
for making modifications to it. For an executable work, complete
source code means all the source code for all modules it contains,
plus any associated interface definition files, plus the scripts
used to control compilation and installation of the
executable. However, as a special exception, the source code
distributed need not include anything that is normally distributed
(in either source or binary form) with the major components
(compiler, kernel, and so on) of the operating system on which the
executable runs, unless that component itself accompanies the
executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this
License. However, parties who have received copies, or rights,
from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify
or distribute the Program or its derivative works. These actions
are prohibited by law if you do not accept this
License. Therefore, by modifying or distributing the Program (or
any work based on the Program), you indicate your acceptance of
this License to do so, and all its terms and conditions for
copying, distributing or modifying the Program or works based on
it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program
subject to these terms and conditions. You may not impose any
further restrictions on the recipients' exercise of the rights
granted herein. You are not responsible for enforcing compliance
by third parties to this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent
issues), conditions are imposed on you (whether by court order,
agreement or otherwise) that contradict the conditions of this
License, they do not excuse you from the conditions of this
License. If you cannot distribute so as to satisfy simultaneously
your obligations under this License and any other pertinent
obligations, then as a consequence you may not distribute the
Program at all. For example, if a patent license would not permit
royalty-free redistribution of the Program by all those who
receive copies directly or indirectly through you, then the only
way you could satisfy both it and this License would be to refrain
entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable
under any particular circumstance, the balance of the section is
intended to apply and the section as a whole is intended to apply
in other circumstances.
It is not the purpose of this section to induce you to infringe
any patents or other property right claims or to contest validity
of any such claims; this section has the sole purpose of
protecting the integrity of the free software distribution system,
which is implemented by public license practices. Many people have
made generous contributions to the wide range of software
distributed through that system in reliance on consistent
application of that system; it is up to the author/donor to decide
if he or she is willing to distribute software through any other
system and a licensee cannot impose that choice.
This section is intended to make thoroughly clear what is believed
to be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces,
the original copyright holder who places the Program under this
License may add an explicit geographical distribution limitation
excluding those countries, so that distribution is permitted only
in or among countries not thus excluded. In such case, this
License incorporates the limitation as if written in the body of
this License.
9. The Free Software Foundation may publish revised and/or new
versions of the General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies a version number of this License which applies
to it and "any later version", you have the option of following
the terms and conditions either of that version or of any later
version published by the Free Software Foundation. If the Program
does not specify a version number of this License, you may choose
any version ever published by the Free Software Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to
the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free
status of all derivatives of our free software and of promoting
the sharing and reuse of software generally.
**NO WARRANTY**
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT
WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE
QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
SERVICING, REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY
MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE
LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL,
INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS
OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH
ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN
ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
===========================
How to Apply These Terms to Your New Programs
=============================================
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make
it free software which everyone can redistribute and change under
these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
one line to give the program's name and an idea of what it does.
Copyright (C) yyyy name of author
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of
the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
Also add information on how to contact you by electronic and paper
mail.
If the program is interactive, make it output a short notice like
this when it starts in an interactive mode: ::
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type
"show w". This is free software, and you are welcome to
redistribute it under certain conditions; "type show c" for
details.
The hypothetical commands ``"show w"`` and ``"show c"`` should show
the appropriate parts of the General Public License. Of course, the
commands you use may be called something other than ``"show w"`` and
``"show c"``; they could even be mouse-clicks or menu items--whatever
suits your program.
You should also get your employer (if you work as a programmer) or
your school, if any, to sign a "copyright disclaimer" for the
program, if necessary. Here is a sample; alter the names: ::
Yoyodyne, Inc., hereby disclaims all copyright
interest in the program `Gnomovision`
(which makes passes at compilers) written
by James Hacker.
signature of Ty Coon, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your
program into proprietary programs. If your program is a subroutine
library, you may consider it more useful to permit linking
proprietary applications with the library. If this is what you want
to do, use the [GNU Lesser General Public
License](https://www.gnu.org/licenses/lgpl.html) instead of this
License.

View File

@ -5,19 +5,20 @@
Coriolis README
===============
Coriolis is a free database, placement tool and routing tool for VLSI design.
Coriolis is a free database, placement tool and routing tool for VLSI designs.
Purpose
=======
Coriolis provides several tools to perform the layout of VLSI circuits. Its
main components are the Hurricane database, the Etesian placer and the Katana
main components are the Hurricane database, the Etesian placer and the Kite
router, but other tools can use the Hurricane database and the parsers
provided.
The user interface <cgt> is the prefered way to use Coriolis, but all
Coriolis tools are Python modules and thus scriptable.
Coriolis tools are Python modules and thus scriptables.
Documentation
@ -25,14 +26,14 @@ Documentation
The complete documentation is available here, both in pdf & html:
./documentation/output/html
./documentation/_build/html/index.html
./documentation/UsersGuide/UsersGuide.pdf
The documentation of the latest *stable* version is also
available online. It may be quite outdated from the *devel*
version.
https://www-soc.lip6.fr/sesi-docs/coriolis2-docs/coriolis2/en/latex/users-guide/UsersGuide.pdf
https://soc-extras.lip6.fr/en/coriolis/coriolis2-users-guide/
Building Coriolis
@ -40,29 +41,35 @@ Building Coriolis
To build Coriolis, ensure the following prerequisites are met:
* Python 3,
* cmake,
* boost,
* bison & flex,
* Qt 4 or 5,
* libxml2,
* RapidJSON,
* Python 2.7.
* cmake.
* boost.
* bison & flex.
* Qt 4 or 5.
* libxml2.
* RapidJSON
* A C++11 compliant compiler.
The build system relies on a fixed directory tree from the root
of the user currently building it. Thus first step is to get a clone of
the repository in the right place. Proceed as follow: ::
ego@home:~$ mkdir -p ~/coriolis-2.x/src/
ego@home:~$ mkdir -p ~/coriolis-2.x/src/support
ego@home:~$ cd ~/coriolis-2.x/src/support
ego@home:~$ git clone http://github.com/miloyip/rapidjson
ego@home:~$ git checkout ec322005072076ef53984462fb4a1075c27c7dfd
ego@home:~$ cd ~/coriolis-2.x/src
ego@home:src$ git clone https://gitlab.lip6.fr/vlsi-eda/coriolis.git
ego@home:src$ git clone https://www-soc.lip6.fr/git/coriolis.git
ego@home:src$ cd coriolis
If you want to use the *devel* branch: ::
ego@home:coriolis$ git checkout devel
Then, build the tool: ::
ego@home:coriolis$ make install
If you encounter issues, please consult SUPPORT.rst for tips.
Coriolis gets installed at the root of the following tree: ::
~/coriolis-2.x/<OS>.<DISTRIB>/Release.Shared/install/
@ -78,11 +85,11 @@ The Coriolis main interface can be launched with the command: ::
ego@home:~: ~/coriolis-2.x/<OS>.<DISTRIB>/Release.Shared/install/bin/coriolis
The ``coriolis`` script detects its location and setups the UNIX
environment appropriately, then lauches ``cgt`` (or *any* command, with the
The ``coriolis`` script is tasked to guess it's location and setup appropriatly
the UNIX environment, then lauch ``cgt`` (or *any* command, with the
``--run=<COMMAND>`` option).
Conversely, you can setup the current shell environment for Coriolis by
Conversely, you can setup the current shell environement for Coriolis by
using the helper ``coriolisEnv.py``, then run any Coriolis tool: ::
ego@home:~$ eval `~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py`

View File

@ -1,27 +0,0 @@
=================
Help and tooltips
=================
Compilation errors
==================
This section is here to help you with the build process, and help you fix dependency issues or workaround compilation errors if it happens on your distribution.
RapidJson
---------
Some versions of RapidJson do not build with newer compilers, while others build only with newer ones.
The version provided in README.rst should work for older compilers. Otherwise, consider pulling a newer version.
Qt5
---
To use Qt5, you should add the --qt5 option to the ccb.py line in Makefile.
On some distributions, you may need to replace the lines in bootstrap/cmake_modules/FindBootstrap.cmake from ::
find_package(Qt5Core REQUIRED)
to ::
find_package(Qt5 COMPONENTS REQUIRED Core)

View File

@ -1,44 +0,0 @@
# -*- explicit-buffer-name: "CMakeLists.txt<Seabreeze>" -*-
set(CMAKE_LEGACY_CYGWIN_WIN32 0)
project(SEABREEZE)
option(BUILD_DOC "Build the documentation (doxygen)" OFF)
option(CHECK_DATABASE "Run database in full check mode (very slow)" OFF)
option(USE_LIBBFD "Link with BFD libraries to print stack traces" OFF)
cmake_minimum_required(VERSION 3.16)
set(ignoreVariables "${BUILD_DOC} ${CMAKE_INSTALL_DIR}")
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}$ENV{CORIOLIS_TOP}/share/cmake/Modules/")
find_package(Bootstrap REQUIRED)
setup_project_paths(CORIOLIS)
set_cmake_policies()
setup_boost(program_options)
setup_qt()
setup_python()
find_package(Libexecinfo REQUIRED)
find_package(PythonSitePackages REQUIRED)
find_package(LEFDEF REQUIRED)
find_package(FLUTE REQUIRED)
find_package(HURRICANE REQUIRED)
find_package(CORIOLIS REQUIRED)
#find_package(ANABATIC REQUIRED)
#find_package(ETESIAN REQUIRED)
#find_package(COLOQUINTE REQUIRED)
find_package(Doxygen)
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(test)
add_subdirectory(cmake_modules)
#add_subdirectory(doc)

View File

@ -1,27 +0,0 @@
Fonctions dans Seabreeze.cpp :
---------------------------------------------------------------------
contFromNet ( Net* net )
{
ajouter les contacts dans net au set<Contact*> _conts;
}
buildTree ( RoutingPad* rp )
{
Construire l'arbre de rp, ça veux dire le contact trouvé dans rp sera la racine de l'arbre
}
build_from_Node ( Node* source, Segment* seg )
{
Après avoir crée le premier node / la racine dans buildTree, on va l'utiliser pour construire l'arbre.
}
build_branch ( double* R, double* C, Contact* contact )
{
Parcourir la branche et trouver le Node suivant de l'arbre
}
Set_RC ( double* R, double* C, Contact* ct, Segment* sm )
{
Calculer le RC de la branche ct-sm et ajouter la valeur dans R et C
}

View File

@ -1,2 +0,0 @@
install( FILES FindSEABREEZE.cmake DESTINATION share/cmake/Modules )

View File

@ -1,38 +0,0 @@
# - Find the Seabreeze includes and libraries.
# The following variables are set if Coriolis is found. If KATABATIC is not
# found, KATABATIC_FOUND is set to false.
# KATABATIC_FOUND - True when the Coriolis include directory is found.
# KATABATIC_INCLUDE_DIR - the path to where the Coriolis include files are.
# KATABATIC_LIBRARIES - The path to where the Coriolis library files are.
SET(SEABREEZE_INCLUDE_PATH_DESCRIPTION "directory containing the Katabatic include files. E.g /usr/local/include/coriolis2 or /asim/coriolis/include/coriolis2")
SET(SEABREEZE_DIR_MESSAGE "Set the SEABREEZE_INCLUDE_DIR cmake cache entry to the ${SEABREEZE_INCLUDE_PATH_DESCRIPTION}")
# don't even bother under WIN32
IF(UNIX)
#
# Look for an installation.
#
FIND_PATH(SEABREEZE_INCLUDE_PATH NAMES katabatic/KatabaticEngine.h PATHS
# Look in other places.
${CORIOLIS_DIR_SEARCH}
PATH_SUFFIXES include/coriolis2
# Help the user find it if we cannot.
DOC "The ${SEABREEZE_INCLUDE_PATH_DESCRIPTION}"
)
FIND_LIBRARY(SEABREEZE_LIBRARY_PATH
NAMES seabreeze
PATHS ${CORIOLIS_DIR_SEARCH}
PATH_SUFFIXES lib64 lib
# Help the user find it if we cannot.
DOC "The ${SEABREEZE_INCLUDE_PATH_DESCRIPTION}"
)
SET_LIBRARIES_PATH(SEABREEZE SEABREEZE)
HURRICANE_CHECK_LIBRARIES(SEABREEZE)
ENDIF(UNIX)

View File

@ -1,22 +0,0 @@
# -*- mode: CMAKE; explicit-buffer-name: # "CMakeLists.txt<Seabreeze/doc>" -*-
set ( htmlInstallDir share/doc/coriolis2/en/html/doc/Seabreeze )
set ( latexInstallDir share/doc/coriolis2/en/latex/Seabreeze )
set ( doxExtras customHierarchy.html
closed.png
open.png
tabs.css
)
if(BUILD_DOC AND DOXYGEN_FOUND)
add_custom_target ( doc ALL
cd ${SEABREEZE_SOURCE_DIR}/doc
&& ${DOXYGEN_EXECUTABLE} doxyfile
&& cp -f ${doxExtras} html
)
endif()
install ( DIRECTORY html/ DESTINATION ${htmlInstallDir} )
install ( DIRECTORY latex/ DESTINATION ${latexInstallDir} )
install ( FILES asimbook.cls DESTINATION ${latexInstallDir} )

View File

@ -1,49 +0,0 @@
// -*- C++ -*-
/*! \class Node
*! \brief Node description(\b API)
*
*/
/*! \var int Node::R
* The Resistor of a point in the circuit / node in the tree.
*/
/*! \var int Node::Rt
* The Resister "total" - the value of resistor that is used
* to compute the Elmore's delay.
*/
/*! \var int Node::C
* The Capacitor of a point in the circuit / node in the tree.
*/
/*! \var Node* Node::Np
* The parent node of current node
*/
/* \var std::vector<Node*> Node::Ne
* A list of children nodes of current node
*/
/*! \var int Node::label
* The label / Id of current node
*/
/*! \var int Node::ap
* A boolean variable to determine whether the current node
* is after or before node i at where we need to compute the
* Elmore's delay.
*/
/*! \function Node::Node();
* Default constructor.
*/
/*! \function Node::~Node();
* Default destructor.
*/

View File

@ -1,102 +0,0 @@
// -*- C++ -*-
namespace Seabreeze {
/*! \class Elmore
* \brief Main class for computing the Elmore's delay
*/
/*! \var vector<Contact*> Elmore::_conts
* The list of Contacts contained in the considered Net
*/
/*! \var vector<Contact*> Elmore::checker
* The list of Contacts that we have treated. It serves as a checker
* of circles. If a circle exists in the Net, Elmore's delay cannot be
* computed.
*/
/*! \var Tree Elmore::_tree
* The tree necessary to run the algorithm to compute Elmore's delay
*/
/*! \function Elmore::Elmore( Net* net = NULL )
* Constructor
*/
/*! \function Elmore::~Elmore()
* Default destructor
*/
/*! \function void Elmore::contFromNet( Net* net )
* Build the list _const from net
*/
/*! \function void Elmore::buildTree( Contact* ct )
* Build the _tree with ct as the root
*/
/*! \function void Elmore::clearTree()
* Clean the _tree and the list checker
*/
/*! \function Tree* Elmore::getTree()
* \Return the _tree
*/
/*! \function int Elmore::delayElmore()
* \Return the value of Elmore's delay
*/
/*! \function void Elmore::toTree( ostream& )
* Print the _tree to an output file
*/
/*! \class ElmoreProperty
*
*/
/*! \var Name ElmorerProperty::_name
*
*/
/*! \var Elmore ElmoreProperty::_elmore
*
*/
/*! \function ElmoreProperty::ElmoreProperty( Net* )
* Constructor
*/
/*! \function ElmoreProperty* ElmoreProperty::create( Net* net )
* \Return the ElmoreProperty created from the net
*/
/*! \function Name ElmoreProperty::getName()
* \Return the name of the property
*/
/*! \class ElmoreExtension
* \brief Useful to access to functions of Elmore class without having to calling it
*/
/*! \var Net* ElmoreExtension::Nets
*
*/
/*! \function void ElmoreExtension::destroyAll()
*
*/
/*! \function void ElmoreExtension::destroy()
*
*/
/*! \function Tree ElmoreExtension::getTree( Elmore* elmore )
* \Return the _tree of elmore
*/
/*! \function void ElmoreExtension::toTree( Elmore* elmore, std::ostream& out )
* Print the _tree of elmore to the output file out
*/
}

View File

@ -1,882 +0,0 @@
/*
* +-----------------------------------------------------------------+
* | HTML Standart Tags |
* +-----------------------------------------------------------------+
*/
html, body, th, td, tr, p, li, h1, h2, h3, h4, h5, h6 {
font-size: 11pt;
/* The Open Sans font family is supplied by TexLive. */
font-family: "Roboto", "Open Sans", Verdana, sans-serif;;
}
html {
background: #dddddd;
}
body {
color: black;
background: white;
background-color: white;
background-position: top left;
background-attachment: fixed;
background-repeat: no-repeat;
margin-top: 2em;
width: 600pt;
margin-right: auto;
margin-left: auto;
padding: 30pt;
/*
margin-right: 12%;
margin-left: 12%;
*/
}
hr {
height: 1px;
border: 0;
color: #004400;
background-color: #004400;
}
h1, h2, h3, h4, h5, h6 {
/*font-family: "URW Bookman L", "Liberation Serif", sans-serif;*/
font-family: "URW Bookman L";
}
h1.header { text-align: center; }
h1 { text-align: left; }
h2, h3, h4, h5, h6 { text-align: left;
padding-top: 11pt;
}
h1, h2, h3 { /*font-family: "Liberation Serif", sans-serif; */
/*color: #09550B;*/
}
h1 { font-weight: bold; font-size: 170%; /*letter-spacing:0.2em; word-spacing:0.4em;*/ }
h2 { font-weight: bold; font-size: 140%; /*letter-spacing:0.2em; word-spacing:0.4em;*/ }
h3 { font-weight: bold; font-size: 118%; /*letter-spacing:0.2em; word-spacing:0.4em;*/ }
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: 1px;
border-top-style: dotted;
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: normal; }
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 {
color: black;
border-bottom: 1px solid black;
text-decoration: none;
}
a:link, a:active, a:visited {
/*color: #09550B;*/
/*text-decoration: none;*/
}
a:hover, a:focus {
/*color: #FF9900; */
border-bottom: 2px solid black;
}
/*
* +-----------------------------------------------------------------+
* | Doxygen Specific Classes |
* +-----------------------------------------------------------------+
*/
/* -------------------------------------------------------------------
* Header & Footer Classes (customized top page navigation bar).
*/
h1.header {
font-size: 200%;
/*font-family: times, verdana, sans-serif;*/
}
h2.memtitle {
display: none;
}
center.header {
background-color: #CCE6CA;
}
table.header {
/*width: 100%;*/
/*background-color: #EEEEEE;*/
background-color: #CCE6CA;
}
div.header {
text-align: center;
margin: 14pt 0pt 0pt 0pt;
}
div.summary {
color: white;
background-color: black;
border: 4px solid black;
}
div.summary a {
font-size: 90%;
color: white;
padding: 2px 0px;
text-align: center;
background-color: black;
border-bottom: none;
}
table.header td {
padding: 2px 14px;
text-align: center;
font-weight: bold;
/*font-family: verdana, sans-serif;*/
font-size: 110%;
}
table.UserDefined {
border: 1px solid;
}
table.UserDefined th {
border: 1px solid;
}
table.UserDefined td {
padding: 0px 5px;
}
table.DoxUser td, table.DoxUser th {
padding: 0px 5px;
border: 0px;
}
table.DoxUser th {
background-color: #CCE6CA;
}
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 a {
border-style: none;
border-bottom: none;
}
table.classHierarchy tr {
border: 1px solid blue;
}
table.classHierarchy td.normal {
border: 1px solid #dddddd;
width: 140pt;
text-align: center;
font-weight: bold;
background-color: #dddddd;
}
table.classHierarchy td.virtual {
border: 1px solid black;
width: 140pt;
text-align: center;
font-weight: bold;
}
table.classHierarchy td.wnormal {
border: 1px solid #dddddd;
width: 240pt;
text-align: center;
font-weight: bold;
background-color: #dddddd;
}
table.classHierarchy td.wvirtual {
border: 1px solid black;
width: 240pt;
text-align: center;
font-weight: bold;
}
div.ah, span.ah {
font-family: Times;
font-size: 300%;
font-weight: bold;
padding: 20px;
}
div.title {
text-align: center;
font-size: 200%;
font-weight: bold;
padding: 20px;
border: 2px solid black;
}
div.center, div.image {
text-align: center;
}
/* -------------------------------------------------------------------
* Top navigation lists.
*/
span.mlabels {
font-size: 90%;
font-style: italic;
padding-left: 10pt;
margin: 10pt;
border-left: 1px solid black
}
div.contents {
padding-top: 20pt;
}
div.tabs {
border-top: 1px solid black;
}
div.tabs, div.tabs1, div.tabs2, div.tabs3, div.tabs4 {
border-left: 1px solid black;
}
ul.tablist {
/*
padding: 5pt;
background-color: red;
*/
margin: 0pt;
padding: 0pt;
border-top: none;
border-bottom: none;
border-left: none;
border-right: none;
}
ul.tablist li {
/*
margin-left: auto;
margin-right: auto;
overflow: auto;
display: inline;
background-color: yellow;
*/
font-size: 90%;
border-top: none;
border-bottom: 1px solid black;
border-left: none;
border-right: 1px solid black;
display: table-cell;
text-align: center;
padding: 2pt;
width: 5%;
}
ul.tablist li:hover {
background-color: black;
color: white;
}
ul.tablist li:hover a {
background-color: black;
color: white;
}
ul.tablist * a { border-bottom: none; }
ul.tablist * a:link img, ul.tablist * a:visited img { border-style: none; border-bottom: none; }
ul.tablist * a:link, ul.tablist * a:visited {
color: black;
text-decoration: none;
}
ul.tablist * a:hover, ul.tablist * a:focus, ul.tablist * a:active {
color: white;
text-decoration: underline;
}
div.navpath {
padding: 5pt 0pt 0pt 0pt;
}
.navpath ul {
text-align: center;
}
.navpath ul li {
display: inline;
list-style-type: none;
padding-left: 20px;
padding-right: 10px;
background-image: url('closed.png');
background-repeat: no-repeat;
background-position: left;
color: #364D7C;
}
.navpath ul li a {
border: 2px solid black;
padding-left: 10px;
padding-right: 10px;
font-weight: bold;
color: black;
}
/* -------------------------------------------------------------------
* Quick Index Class (top page navigation bar).
*/
div.qindex, div.nav {
width: 100%-4px;
/*background-color: #DADAEF;*/
/*background-color: #eeeeff;*/
background-color: #cccccc;
/*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-family: Courier;*/
font-weight: normal;
/*font-size: 110%;*/
}
a.qindex, a.qindex:visited {
/*color: #09550B;*/
color: black;
border: 2px solid #cccccc;
padding: 2px 2px;
border-bottom: none;
}
a.qindex:hover {
/*background-color: #ddddff;*/
font-weight: bold;
padding: 2px 2px;
border: 2px solid black;
}
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"]
h3 a[id="index__"],
h3 a#index_a,
h3 a#index_b,
h3 a#index_c,
h3 a#index_d,
h3 a#index_e,
h3 a#index_f,
h3 a#index_g,
h3 a#index_h,
h3 a#index_i,
h3 a#index_j,
h3 a#index_k,
h3 a#index_l,
h3 a#index_m,
h3 a#index_n,
h3 a#index_o,
h3 a#index_p,
h3 a#index_q,
h3 a#index_r,
h3 a#index_s,
h3 a#index_t,
h3 a#index_u,
h3 a#index_v,
h3 a#index_w,
h3 a#index_x,
h3 a#index_y,
h3 a#index_z,
h3 a#index_0,
h3 a#index_1,
h3 a#index_2,
h3 a#index_3,
h3 a#index_4,
h3 a#index_5,
h3 a#index_6,
h3 a#index_7,
h3 a#index_8,
h3 a#index_9,
h3 a#index_0x7e
{
font-family: time;
font-size: 250%;
text-align: center;
}
/* -------------------------------------------------------------------
* Verbatim Source Code / Examples.
*/
div.fragment {
font-family: "Roboto Mono", "Monospace";
font-size: 80%;
border: none;
/*border-width: thin; */
/*border-color: #003300;*/
/*background-color: #FCFCE1;*/
background-color: #fefefe;
padding: 0.5em;
margin-left: 5%;
margin-right: 5%
}
div.fragment a.code:link,
div.fragment a.code:visited,
div.fragment a.codeRef:link,
div.fragment a.codeRef:visited {
text-decoration: none;
font-weight: bold;
color: black;
border: none;
}
div.line {
white-space: pre;
padding: 0pt;
margin: 0pt;
}
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 }
span.red { color: red }
/* -------------------------------------------------------------------
* Attributes Listing.
*/
a.el, a.elRef {
font-family: "Roboto Mono", Courier;
font-weight: bold;
font-size: 110%;
color: black;
border-bottom: none;
}
p.formulaDsp {
text-align: center;
}
.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;*/
background-color: #cccccc;
border-left-width: 4px;
border-left-style: solid;
/*border-color: #008500;*/
border-color: black;
}
.memname {
white-space: nowrap;
padding-left: 5px;
font-size: 105%;
}
table.memname * {
font-family: "Roboto Mono", "Monospace";
}
.memdoc{
padding-left: 5px;
/*margin-top: -8px;*/
border-left-width: 1px;
border-left-style: solid;
/*border-color: #008500;*/
border-color: black;
}
div.contents * table tr {
padding: 3px 3px 3px 8px;
}
.memSeparator {
font-size: 1pt;
}
.memItemLeft, .memItemRight, .memTemplItemLeft, .memTemplItemRight {
vertical-align: top;
/*padding: 1px 0px 0px 8px;*/
padding: 3px 3px 3px 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: none;
border-right-style: none;
/*
border-bottom-style: dotted;
*/
border-left-style: none;
/*background-color: #DADAEF;*/
/*background-color: #eeeeff;*/
/*background-color: #EEEEEE;*/
/*background-color: #CCE6CA;*/
font-family: "Roboto Mono", "Monospace";
}
.memTemplItemLeft, .memTemplItemRight {
border-bottom-width: 2px;
border-bottom-style: solid;
font-weight: bold;
}
.memItemLeft { font-size: 11px; width: 100pt; }
.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;
font-size: 130%;
font-weight: bold;
margin-top: 15px;
}
.groupHeader {
margin-bottom: -30pt;
}
.inherit {
display: none;
}
/* -------------------------------------------------------------------
* General Classes Index.
*/
span.icona {
margin-right: 10pt;
}
div.toc li.level1 {
margin-left: 0px;
}
div.toc li.level2 {
margin-left: 15px;
display: none;
}
div.toc li.level3 {
margin-left: 30px;
display: none;
}
div.toc li.level4 {
margin-left: 45px;
display: none;
}
.directory .levels {
white-space: nowrap;
width: 100%;
text-align: right;
font-size: 9pt;
}
.directory .levels span {
cursor: pointer;
padding-left: 2px;
padding-right: 2px;
color: #3D578C;
}
div.directory {
margin: 10px 0px;
border-top: 2px solid black;
border-bottom: 2px solid black;
width: 100%;
}
.directory table {
border-collapse: collapse;
}
.directory td {
margin: 0px;
padding: 0px;
vertical-align: top;
}
.directory td.entry {
white-space: nowrap;
padding-right: 6px;
padding-top: 3px;
}
.directory td.entry a {
outline: none;
}
.directory td.entry a img {
border: none;
}
.directory td.desc {
width: 100%;
padding-left: 6px;
padding-right: 6px;
padding-top: 3px;
border-left: 1px solid rgba(0,0,0,0.05);
}
.directory tr.even {
padding-left: 6px;
background-color: #F7F8FB;
}
.directory img {
vertical-align: -30%;
}

View File

@ -1,50 +0,0 @@
// -*- C++ -*-
/*! \class Tree
* \brief The tree contains all points of the circuit as its' nodes.
*/
/*! \var vector<Node*> Tree::nodes
* The list of nodes contained in the tree
*/
/*! \function Tree::Tree()
* Default constructor
*/
/*! \function Tree:~Tree()
* Default destructor
*/
/*! \function int Tree::get_N()
* Returns the number of nodes in the tree / points in the circuit
*/
/*! \function Node* Tree::get_node( int i )
* Returns node at index i in the tree
*/
/*! \function vector<Node*> get_node_list()
* Returns the list of nodes contained in the tree
*/
/*! \function void Tree::new_node()
* Create and add a new node to the tree
*/
/*! \function void Tree::After_i( Node* node_i )
* For each node in the tree, determine if they are after or before node_i.
* In other words, change the value of ap of each node to 0 or 1 accordingly.
*/
/*! \function set<int> Tree::Branch_i( int i )
* Returns a set of indexes of nodes who are on the same branch as node i.
*/
/*! \function int Tree::Delay_Elmore( int i)
* Computes the Elmore's delay and returns the result.
*/
/*! \function void Tree::print( ostream& out )
* Prints the tree to the output file.
*/

View File

@ -1,65 +0,0 @@
<br>
<p><b>The complete class hierarchy could be accessed <a href="hierarchy.html">here</a>.</b></p>
<p>All the classes below are in the <a href="namespaceSeabreeze.html">Seabreeze</a> namespace.</p>
<p>The inheritance tree has been splitted/simplificated.</p>
<b>Legend :</b><br>
<pre class="fragment">
<table class="classHierarchy">
<tr><td width="70"><td class="virtual"><a href="#pagetop">ClassA</a><td><b>&nbsp;&nbsp;<tt>ClassA</tt> is abstract</b></tr>
<tr><td width="70"><td class="normal"><a href="#pagetop">ClassB</a><td><b>&nbsp;&nbsp;<tt>ClassB</tt> is instanciable</b></tr>
</table>
</pre>
<br>
<h2 class="classHierarchy">Utilities</h2>
<table class="classHierarchy">
<tr><td width="70"><td class="virtual"><a href="classSeabreeze_1_1BaseObserver.html">BaseObserver</a>
</table>
<table class="classHierarchy">
<tr><td width="140"><td class="normal"><a href="classSeabreeze_1_1Observer.html">Observer</a>
</table>
<table class="classHierarchy">
<tr><td width="70"><td class="normal"><a href="classSeabreeze_1_1Observable.html">Observable</a>
</table>
<h2 class="classHierarchy">Seabreeze Engine</h2>
<table class="classHierarchy">
<tr><td width="70"><td class="normal"><a href="namespaceSeabreeze.html">Seabreeze</a>
<tr><td width="70"><td class="normal"><a href="classSeabreeze_1_1ChipTools.html">ChipTools</a>
<tr><td width="70"><td class="normal"><a href="classSeabreeze_1_1SeabreezeEngine.html">SeabreezeEngine</a>
<tr><td width="70"><td class="normal"><a href="classSeabreeze_1_1Session.html">Session</a>
<tr><td width="70"><td class="normal"><a href="classSeabreeze_1_1DataAlgorithm.html">DataAlgorithm</a>
</table>
<h2 class="classHierarchy">Contacts</h2>
<table class="classHierarchy">
<tr><td width="70"><td class="virtual"><a href="classSeabreeze_1_1AutoContact.html">AutoContact</a>
</table>
<table class="classHierarchy">
<tr><td width="140"><td class="normal"><a href="classSeabreeze_1_1AutoContactTerminal.html">AutoContactTerminal</a>
<tr><td width="140"><td class="normal"><a href="classSeabreeze_1_1AutoContactTurn.html">AutoContactTurn</a>
<tr><td width="140"><td class="normal"><a href="classSeabreeze_1_1AutoContactHTee.html">AutoContactHTee</a>
<tr><td width="140"><td class="normal"><a href="classSeabreeze_1_1AutoContactVTee.html">AutoContactVTee</a>
</table>
<h2 class="classHierarchy">Segments</h2>
<table class="classHierarchy">
<tr><td width="70"><td class="virtual"><a href="classSeabreeze_1_1AutoSegment.html">AutoSegment</a>
</table>
<table class="classHierarchy">
<tr><td width="140"><td class="normal"><a href="classSeabreeze_1_1AutoHorizontal.html">AutoHorizontal</a>
<tr><td width="140"><td class="normal"><a href="classSeabreeze_1_1AutoVertical.html">AutoVertical</a>
</table>
<h2 class="classHierarchy">GCell</h2>
<table class="classHierarchy">
<tr><td width="70"><td class="normal"><a href="classSeabreeze_1_1GCell.html">GCell</a>
<tr><td width="70"><td class="normal"><a href="classSeabreeze_1_1BaseGrid_1_1Axis.html">BaseGrid::Axis</a>
<tr><td width="70"><td class="virtual"><a href="classSeabreeze_1_1BaseGrid.html">BaseGrid</a>
</table>
<table class="classHierarchy">
<tr><td width="140"><td class="virtual"><a href="classSeabreeze_1_1Grid.html">Grid</a>
</table>
<table class="classHierarchy">
<tr><td width="210"><td class="normal"><a href="classSeabreeze_1_1GCellGrid.html">GCellGrid</a>
</table>

View File

@ -1,81 +0,0 @@
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
<!-- $Id: customSummary.html,v 1.1 2007/09/15 13:10:13 jpc Exp $ -->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>Seabreeze Documentation</title>
<link href="SoC.css" rel="stylesheet" type="text/css">
</head>
<h1 class="header">Seabreeze Documentation</h1>
<center class="header">
<table class="header">
<tr>
<td><a href="customSummary.html">Summary</a></td>
<td><a href="namespaces.html">Namespaces</a></td>
<td><a href="customHierarchy.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>
<h1>Seabreeze Documentation Summary</h1>
<br>
<p><b>The classical Doxygen module documentation could be accessed <a href="modules.html">here</a>.</b></p>
<!--
<h2>Seabreeze Concepts (internal)</h2>
<ol>
<li><a class="el" href="group__buildRules.html">Rules for building wires.</a>
<br>Rules for building AutoContacts. Global/Locals AutoSegments.
<li><a class="el" href="group__loadGlobalRouting.html">Global Routing Loading.</a>
<br>How the Knik global routing is loaded into Seabreeze data-base.
Details the wiring topologies used to complete the routing to the
terminals.
<li><a class="el" href="group__collapseCanonical.html">AutoSegment Collapse &amp; Canonical.</a>
<br>How to force alignment of AutoSegments.
<li><a class="el" href="group__layerAssign.html">Layer Assignment.</a>
<br>Simple strategy to put long wires on higher routing metals.
<li><a class="el" href="group__NetConstraints.html">Constraints Computations.</a>
<br>Compute the legal range of variation of each wire (note that the
constraints are stored on AutoContacts).
<li><a class="el" href="group__NetOptimals.html">AutoSegment Optimal Placement.</a>
<br>Compute the optimal range of variation of each wire.
<li><a class="el" href="group__katabaticSession.html">Seabreeze Update Session Mechanism.</a>
<br>The Session mechanism for modifying the Seabreeze data-base.
</ol>
-->
<h2>API documentations</h2>
<ul>
<li><b><a href="customHierarchy.html">Synthetic Class Hierarchy.</a></b>
<li><b><a href="hierarchy.html">Complete Class Hierarchy (doxygen).</a></b>
<li><b><a href="annotated.html">Class List (doxygen).</a></b>
<li><b><a href="classes.html">Class Index (doxygen).</a></b>
<li><b><a href="modules.html">Modules (raw concepts).</a></b>
<li><b><a href="functions.html">Member Functions Index (doxygen).</a></b>
<li><b><a href="namespaces.html">Namespaces (doxygen).</a></b>
</ul>
<br>
<hr>
<table class="footer1">
<tr>
<td class="LFooter"><small>Customized Concepts (a.k.a. modules)</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">Seabreeze Documentation</td>
<td class="RFooter"><small>Copyright &#169; 2005-2007 LIP6. All rights reserved</small></td>
</tr>
</table>
</body>
</html>

View File

@ -1,276 +0,0 @@
# -*- explicit-buffer-name: "doxyfile<Seabreeze/doc>" -*-
# Doxyfile 1.3.4
# --------------------------------------------------------------------
# Project related configuration options
PROJECT_NAME = "Seabreeze - Routing Toolbox"
PROJECT_NUMBER = 1.0
OUTPUT_DIRECTORY = .
OUTPUT_LANGUAGE = English
MARKDOWN_SUPPORT = NO
#USE_WINDOWS_ENCODING = NO
LAYOUT_FILE = DoxygenLayout.xml
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"\
"sreturn=\b Returns:"\
"True=\b True"\
"true=\b true"\
"False=\b False"\
"false=\b false"\
"VERTICAL=\b VERTICAL"\
"HORIZONTAL=\b HORIZONTAL"\
"NULL=\c NULL"\
"vector=\c vector"\
"Collection=\c Collection"\
"Collections=\c Collections"\
"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"\
"ToolEngine=\c ToolEngine"\
"ToolEngines=\c ToolEngines"\
"GCell=\c GCell"\
"GCells=\c GCells"\
"Splitter=\c Splitter"\
"Splitters=\c Splitters"\
"SplitterContact=\c SplitterContact"\
"SplitterContacts=\c SplitterContacts"\
"Hurricane=<a href='../hurricane/Index.html'>Hurricane</a>"\
"STL=<a href='http://www.sgi.com/tech/stl/'>STL</a>"\
"red{1}=<span class=\"red\">\1</span>"
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 = YES
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 = \
Seabreeze.dox \
../src/Seabreeze/Node.h ../src/Node.cpp Node.dox \
../src/Seabreeze/Tree.h ../src/Tree.cpp Tree.dox \
../src/Seabreeze/Seabreeze.h ../src/Seabreeze.cpp Seabreeze.dox \
../src/katabatic/SeabreezeEngine.h ../src/SeabreezeEngine.cpp SeabreezeEngine.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 = YES
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_DYNAMIC_SECTIONS = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER = header.html
HTML_FOOTER = footer.html
HTML_STYLESHEET = SoC.css
GENERATE_HTMLHELP = NO
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
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 = NO
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__
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
# --------------------------------------------------------------------
# Configuration::addtions related to external references
TAGFILES = ../../hurricane/doc/hurricane/html/hurricane.tag=../hurricane \
../../hurricane/doc/viewer/html/viewer.tag=../viewer \
../../crlcore/doc/crlcore/html/crlcore.tag=../crlcore
GENERATE_TAGFILE = html/Seabreeze.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

View File

@ -1,16 +0,0 @@
<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">Seabreeze - Routing Toolbox</td>
<td class="RFooter"><small>Copyright &#169; 2008-2020 Sorbonne Universite. All rights reserved</small></td>
</tr>
</table>
</body>
</html>

View File

@ -1,26 +0,0 @@
<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.0//EN'>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>Katabatic Documentation</title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="SoC.css" rel="stylesheet" type="text/css">
<link href="tabs.css" rel="stylesheet" type="text/css">
</head>
<h1 id="pagetop" class="header">Seabreeze - Routing Toolbox</h1>
<!--
<center class="header">
<table class="header">
<tr>
<td><a href="customSummary.html">Summary</a></td>
<td><a href="namespaces.html">Namespaces</a></td>
<td><a href="customHierarchy.html">Class Hierarchy</a></td>
<td><a href="annotated.html">Classes</a></td>
<td><a href="functions.html">Member Index</a></td>
</tr>
</table>
</center>
-->
<br>
<body onload="javascript:toggleLevel(1)">

View File

@ -1,73 +0,0 @@
# -*- explicit-buffer-name: "CMakeLists.txt<Seabreeze/src>" -*-
# include( ${QT_USE_FILE} )
include_directories( ${SEABREEZE_SOURCE_DIR}/src
${CORIOLIS_INCLUDE_DIR}
${HURRICANE_INCLUDE_DIR}
${CONFIGURATION_INCLUDE_DIR}
${QtX_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
${Python_INCLUDE_DIRS}
)
set( includes seabreeze/SeabreezeEngine.h
#seabreeze/GraphicSeabreezeEngine.h
)
set( pyIncludes seabreeze/Configuration.h
seabreeze/Delay.h
seabreeze/Node.h
seabreeze/Tree.h
seabreeze/Elmore.h
seabreeze/PySeabreezeEngine.h
#seabreeze/PyGraphicSeabreezeEngine.h
)
#set( mocIncludes seabreeze/GraphicSeabreezeEngine.h )
set( cpps Configuration.cpp
Delay.cpp
Node.cpp
Tree.cpp
Elmore.cpp
SeabreezeEngine.cpp
#GraphicSeabreezeEngine.cpp
)
set( pyCpps PySeabreeze.cpp
PySeabreezeEngine.cpp
#PyGraphicSeabreezeEngine.cpp
)
#qtX_wrap_cpp( mocCpps ${mocIncludes} )
set( depLibs ${CORIOLIS_PYTHON_LIBRARIES}
${CORIOLIS_LIBRARIES}
${HURRICANE_PYTHON_LIBRARIES}
${HURRICANE_GRAPHICAL_LIBRARIES}
${HURRICANE_LIBRARIES}
${CONFIGURATION_LIBRARY}
${BOOKSHELF_LIBRARY}
${CIF_LIBRARY}
${AGDS_LIBRARY}
${UTILITIES_LIBRARY}
${LEFDEF_LIBRARIES}
${OA_LIBRARIES}
${QtX_LIBRARIES}
${Boost_LIBRARIES}
${LIBXML2_LIBRARIES}
-lutil
${LIBEXECINFO_LIBRARIES}
)
add_library( Seabreeze ${cpps} ${mocCpps} ${pyCpps} )
set_target_properties( Seabreeze PROPERTIES VERSION 1.0 SOVERSION 1 )
target_link_libraries( Seabreeze ${depLibs} )
add_python_module( "${pyCpps}"
"${pyIncludes}"
"Do_not_generate_C_library"
Seabreeze
"Seabreeze;${depLibs}"
include/coriolis2/seabreeze
)
install( TARGETS Seabreeze DESTINATION lib${LIB_SUFFIX} )
install( FILES ${includes}
${mocIncludes} DESTINATION include/coriolis2/seabreeze )

View File

@ -1,102 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) SU 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | S e a b r e e z e - Timing Analysis |
// | |
// | Author : Vu Hoang Anh PHAM |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./Configuration.cpp" |
// +-----------------------------------------------------------------+
#include <iostream>
#include <sstream>
#include <iomanip>
#include "hurricane/configuration/Configuration.h"
#include "hurricane/Warning.h"
#include "hurricane/Error.h"
#include "hurricane/Technology.h"
#include "hurricane/DataBase.h"
#include "hurricane/RoutingPad.h"
#include "hurricane/Contact.h"
#include "hurricane/Net.h"
#include "hurricane/Segment.h"
#include "hurricane/Cell.h"
#include "crlcore/Utilities.h"
#include "seabreeze/Configuration.h"
namespace Seabreeze {
using std::string;
using std::ostringstream;
using Hurricane::Warning;
using Hurricane::Error;
using Hurricane::Technology;
using Hurricane::RoutingPad;
using Hurricane::Contact;
using Hurricane::Segment;
using Hurricane::Cell;
using Hurricane::Net;
using Hurricane::DataBase;
using Hurricane::Record;
using Hurricane::Name;
using Hurricane::Layer;
using Hurricane::DbU;
//------------------------------------------------------------------------
// Class : "Seabreeze::Configuration"
Configuration::Configuration ()
: _Rct (1)
, _Rsm (1)
, _Csm (1)
{}
Configuration::~Configuration ()
{}
Configuration::Configuration ( const Configuration& other )
: _Rct (other._Rct)
, _Rsm (other._Rsm)
, _Csm (other._Csm)
{}
Configuration* Configuration::clone () const
{ return new Configuration( *this ); }
string Configuration::_getTypeName () const
{ return "Seabreeze::Configuration"; }
string Configuration::_getString () const
{
ostringstream os;
os << "<" << _getTypeName() << ">";
return os.str();
}
Record* Configuration::_getRecord () const
{
Record* record = new Record ( _getString() );
if (record != nullptr) {
record->add( getSlot("_Rct", _Rct) );
record->add( getSlot("_Rsm", _Rsm) );
record->add( getSlot("_Csm", _Csm) );
}
return record;
}
} // Seabreeze namespace.

View File

@ -1,71 +0,0 @@
// -*- C++ -*-
// //
// // This file is part of the Coriolis Software.
// // Copyright (c) SU 2022-2022, All Rights Reserved
// //
// // +-----------------------------------------------------------------+
// // | C O R I O L I S |
// // | S e a b r e e z e - Timing Analysis |
// // | |
// // | Author : Vu Hoang Anh PHAM |
// // | E-mail : Jean-Paul.Chaput@lip6.fr |
// // | =============================================================== |
// // | C++ Header : "./seabreeze/Delay.h" |
// // +-----------------------------------------------------------------+
#include <map>
#include <iostream>
#include "hurricane/RoutingPad.h"
#include "seabreeze/Delay.h"
#include "seabreeze/Elmore.h"
using namespace std;
namespace Seabreeze {
using Hurricane::RoutingPad;
//---------------------------------------------------------
// Class : Seabreeze::Delay
Delay::Delay ( Elmore* elmore, RoutingPad* sink )
: _elmore(elmore)
, _sink (sink)
, _delay (0.0)
{ }
Delay::~Delay ()
{ }
string Delay::_getTypeName () const
{ return "Seabreeze::Delay"; }
string Delay::_getString () const
{
string s = "<Delay ";
s += getString( _sink );
s += " d=" + getString( _delay );
s += ">";
return s;
}
Record* Delay::_getRecord () const
{
Record* record = new Record ( _getString() );
if (record != nullptr) {
record->add( getSlot("_elmore" , _elmore) );
record->add( getSlot("_sink" , _sink ) );
record->add( getSlot("_delay" , _delay ) );
}
return record;
}
} // Seabreeze namespace.

View File

@ -1,577 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) SU 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | S e a b r e e z e - Timing Analysis |
// | |
// | Author : Vu Hoang Anh PHAM |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./Elmore.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/DebugSession.h"
#include "hurricane/Error.h"
#include "hurricane/Segment.h"
#include "hurricane/Plug.h"
#include "hurricane/Net.h"
#include "hurricane/Hook.h"
#include "seabreeze/Elmore.h"
#include "seabreeze/Node.h"
#include "seabreeze/SeabreezeEngine.h"
namespace Seabreeze {
using namespace std;
using Hurricane::Error;
using Hurricane::DBo;
using Hurricane::DbU;
using Hurricane::Plug;
using Hurricane::Net;
using Hurricane::Cell;
using Hurricane::Hook;
using Hurricane::Instance;
using Hurricane::Property;
using Hurricane::PrivateProperty;
using Hurricane::Component;
using Hurricane::Segment;
using Hurricane::DebugSession;
//---------------------------------------------------------
// Class : "Elmore"
Elmore::Elmore ( Net* net )
: _seabreeze(nullptr)
, _net (net)
, _driver (nullptr)
, _tree (new Tree(this))
, _delays ()
{}
Elmore::~Elmore ()
{
cdebug_log(199,0) << "Elmore::~Elmore() " << endl;
delete _tree;
for ( Delay* delay : _delays ) delete delay;
}
void Elmore::setup ()
{
cdebug_log(199,1) << "Elmore::findDriver()" << endl;
for ( RoutingPad* rp : _net->getRoutingPads() ) {
Plug* plug = static_cast<Plug*>( rp->getPlugOccurrence().getEntity() );
if (plug->getMasterNet()->getDirection() & Net::Direction::DirOut) {
if (_driver) {
cerr << Error( "Elmore::setup(): %s has more than one driver:\n"
" * Using: %s\n"
" * Ignoring: %s"
, getString(_net).c_str()
, getString(_driver).c_str()
, getString(rp).c_str()
) << endl;
continue;
}
_driver = rp;
} else {
_delays.push_back( new Delay(this,rp) );
}
}
cdebug_log(199,0) << "Found " << _delays.size() << " sink points:" << endl;
for ( Delay* delay : _delays ) {
cdebug_log(199,0) << "| " << delay << endl;
}
if (not _driver) {
cerr << Error( "Elmore::_postCreate(): No driver found on %s, aborting."
, getString(_net).c_str() ) << endl;
cdebug_tabw(199,-1);
return;
}
cdebug_tabw(199,-1);
}
const Configuration* Elmore::getConfiguration () const
{ return _seabreeze->getConfiguration(); }
Delay* Elmore::getDelay ( RoutingPad* rp ) const
{
for ( Delay* delay : _delays ) {
if (delay->getSink() == rp) return delay;
}
return nullptr;
}
void Elmore::buildTree ()
{
if (not _driver) {
cerr << Error( "Elmore::buildTree(): Net has no driver, aborting." ) << endl;
return;
}
Contact* rootContact = nullptr;
for ( Component* component : _driver->getSlaveComponents() ) {
Contact* contact = dynamic_cast<Contact*>(component);
if (contact) {
rootContact = contact;
break;
}
}
if (not rootContact) {
cerr << Error( "Elmore::buildTree(): No Contact anchored on %s."
, getString(_driver).c_str() ) << endl;
return;
}
cdebug_log(199,1) << "Elmore::buildTree()" << endl;
cdebug_log(199,0) << "Root contact " << rootContact << endl;
Node* rootNode = new Node( nullptr, rootContact );
double R = 0;
double C = 0;
setRC( &R, &C, rootContact, nullptr );
rootNode->setR( R );
rootNode->setC( (C == 0.0) ? 0.0 : 1/C );
Segment* segment = nullptr;
size_t count = 0;
for ( Component* component : rootContact->getSlaveComponents() ) {
segment = dynamic_cast<Segment*>( component );
if (not segment) continue;
++count;
}
if (count != 1) {
cerr << Error( "Elmore::buildTree(): Terminal contact has more than one segment (%d), aborting.\n"
" (on %s)"
, count
, getString(rootContact).c_str()
) << endl;
cdebug_tabw(199,-1);
return;
}
buildFromNode( rootNode, segment );
//---------- More than 1 Contact in main RoutingPad ------- ( 1 )
for ( Component* component : _driver->getSlaveComponents() ) {
Contact* sideContact = dynamic_cast<Contact*>(component);
if (sideContact && sideContact != rootContact) {
Node* sideNode = new Node( rootNode, sideContact );
double sR = 0;
double sC = 0;
setRC ( &sR, &sC, sideContact, nullptr );
sideNode->setR( sR );
sideNode->setC( (sC == 0.0 ) ? 0.0: 1/sC );
Segment* sideSegment = nullptr;
size_t count = 0;
for ( Component* component : sideContact->getSlaveComponents() ) {
sideSegment = dynamic_cast<Segment*>( component );
if (not sideSegment) continue;
++count;
}
if (count != 1) {
cerr << Error( "Elmore::buildTree(): Terminal contact has more than one segment (%d), aborting.\n"
" (on %s)"
, count
, getString(sideContact).c_str()
) << endl;
cdebug_tabw(199,-1);
return;
}
buildFromNode( sideNode, sideSegment );
}
}
//---------------------------------------------------------------
/*
//---------- More than 1 Contact in 1 RoutingPad ---------- ( 2 )
for ( RoutingPad* rp : getNet()->getRoutingPads() ) {
Node* mainNode = nullptr;
for ( Component* rpComp : rp->getSlaveComponents() ) {
Contact* mainContact = dynamic_cast<Contact*>(rpComp);
if ( not mainContact ) continue;
mainNode = _tree->getNode( mainContact );
if ( mainNode ) break;
}
if ( mainNode == nullptr ) {
cerr << "No mainNode found!" << endl;
break;
}
for ( Component* rpComp : rp->getSlaveComponents() ) {
Contact* sideContact = dynamic_cast<Contact*>(rpComp);
if ( not sideContact || sideContact == mainNode->contact() ) continue;
Node* sideNode = new Node( mainNode, sideContact );
double sR = 0;
double sC = 0;
setRC( &sR, &sC, sideContact, nullptr );
sideNode->setR( sR );
sideNode->setC( (sC == 0.0) ? 0.0 : 1/sC );
Segment* sideSegment = nullptr;
size_t sideCount = 0;
for ( Component* component : sideContact->getSlaveComponents() ) {
sideSegment = dynamic_cast<Segment*>( component );
if (not sideSegment) continue;
++sideCount;
}
if (sideCount != 1) {
cerr << Error( "Elmore::buildTree(): Terminal side contact has to have one segment (%d), aborting.\n"
" (on %s)"
, sideCount
, getString(sideContact).c_str()
) << endl;
cdebug_tabw(199,-1);
return;
}
buildFromNode( sideNode, sideSegment );
}
}
//---------------------------------------------------------
*/
cdebug_log(199,0) << "Elmore::buildTree() - Finished" << endl;
cdebug_tabw(199,-1);
_tree->print( cerr );
}
void Elmore::buildFromNode ( Node* rootNode, Segment* toSegment )
{
if (not rootNode->contact()) {
cerr << Error( "Elmore::buildFromNode(): rootNode has no contact, aborting." ) << endl;
return;
}
_tree->addNode( rootNode );
cdebug_log(199,1) << "Elmore::buildFromNode()" << endl;
cdebug_log(199,0) << "rootNode->_contact=" << rootNode->contact() << endl;
cdebug_log(199,0) << "toSegment=" << toSegment << endl;
Contact* opposite = dynamic_cast<Contact*>( toSegment->getOppositeAnchor( rootNode->contact()) );
if (not opposite or (rootNode->parent() and (opposite == rootNode->parent()->contact())) ) {
cdebug_tabw(199,-1);
return;
}
cdebug_log(199,0) << "opposite=" << opposite << endl;
double Rb = 0;
double Cb = 0;
opposite = buildBranch( &Rb, &Cb, opposite );
if (not opposite) {
cerr << Error( "Elmore::buildFromNode(): Branch end up on NULL Contact, pruned." ) << endl;
cdebug_tabw(199,-1);
return;
}
cdebug_log(199,0) << "Reached fork " << opposite << endl;
Node* node = new Node( rootNode, opposite);
node->setR( Rb );
node->setC( (Cb == 0.0) ? 0.0 : 1/Cb );
cdebug_log(199,0) << "R=" << Rb << " C=" << Cb << endl;
int count = 0;
for ( Component* component : opposite->getSlaveComponents() ) {
count += (dynamic_cast<Segment*>(component)) ? 1 : 0;
}
cdebug_log(199,0) << "Node's contact has : " << count << " segments" << endl;
if (count == 1) {
_tree->addNode( node );
} else if (count > 2) {
for ( Component* component : opposite->getSlaveComponents() ) {
Segment* segment = dynamic_cast<Segment*>( component );
if (not segment) continue;
cdebug_log(199,0) << "| " << segment << endl;
Contact* target = dynamic_cast<Contact*>( segment->getOppositeAnchor(opposite) );
if (not target) {
cerr << Error( "Elmore::buildFromNode(): Segment missing opposite anchor. pruned." ) << endl;
continue;
}
cdebug_log(199,0) << "target=" << target << endl;
if (not _tree->isReached(target)) {
buildFromNode( node, segment);
}
}
}
//---------- More than 1 Contact in this RoutingPad ------- ( 1 )
Hook* masterHook = opposite->getAnchorHook()->getMasterHook();
RoutingPad* currentRP = nullptr;
if ( masterHook ) {
currentRP = dynamic_cast<RoutingPad*>( masterHook->getComponent() );
cdebug_log(199,0) << " Look back = " <<currentRP << endl;
}
if ( currentRP ) {
for ( Component* component : currentRP->getSlaveComponents() ) {
Contact* sideContact = dynamic_cast<Contact*>(component);
if (sideContact && sideContact != opposite) {
Node* sideNode = new Node( node, sideContact );
double sR = 0;
double sC = 0;
setRC ( &sR, &sC, sideContact, nullptr );
sideNode->setR( sR );
sideNode->setC( (sC == 0.0 ) ? 0.0: 1/sC );
Segment* sideSegment = nullptr;
size_t count = 0;
for ( Component* component : sideContact->getSlaveComponents() ) {
sideSegment = dynamic_cast<Segment*>( component );
if (not sideSegment) continue;
++count;
}
if (count != 1) {
cerr << Error( "Elmore::buildTree(): Terminal contact has more than one segment (%d), aborting.\n"
" (on %s)"
, count
, getString(sideContact).c_str()
) << endl;
cdebug_tabw(199,-1);
return;
}
buildFromNode( sideNode, sideSegment );
}
}
}
//---------------------------------------------------------------
cdebug_tabw(199,-1);
}
Contact* Elmore::buildBranch ( double* R, double* C, Contact* current )
{
cdebug_log(199,1) << "Elmore::buildBranch()" << endl;
cdebug_log(199,0) << "current=" << current << endl;
while ( true ) {
_tree->setReached( current );
int count = 0;
Segment* segment = nullptr;
for ( Component* component : current->getSlaveComponents() ) {
segment = dynamic_cast<Segment*>( component );
if (not segment) continue;
Contact* opposite = dynamic_cast<Contact*>( segment->getOppositeAnchor(current) );
if (opposite and _tree->isReached(opposite)) {
setRC( R, C, current, segment );
cdebug_log(199,0) << "current=" << current << endl;
cdebug_log(199,0) << "segment=" << segment << endl;
cdebug_log(199,0) << "R=" << *R << endl;
cdebug_log(199,0) << "C=" << *C << endl;
}
++count;
}
if (not count) {
cerr << Error( "Elmore::buildBranch(): Contact seems to be a dead end, pruning.\n"
" (on %s)"
, getString(current).c_str() ) << endl;
cdebug_tabw(199,-1);
return nullptr;
}
else if (count != 2) {
break;
}
Contact* next = nullptr;
for ( Component* component : current->getSlaveComponents() ) {
segment = dynamic_cast<Segment*>( component );
if (not segment) continue;
cdebug_log(199,0) << "| " << segment << endl;
Contact* opposite = dynamic_cast<Contact*>( segment->getOppositeAnchor(current) );
cdebug_log(199,0) << "opposite=" << opposite << endl;
if (opposite and not _tree->isReached(opposite))
next = opposite;
}
if (not next) {
cerr << Error( "Elmore::buildBranch(): Wire loop detected.\n"
" (on %s)"
, getString(current).c_str() ) << endl;
cdebug_tabw(199,-1);
return nullptr;
}
current = next;
}
cdebug_tabw(199,-1);
return current;
}
void Elmore::setRC ( double* R, double* C, Contact* contact, Segment* segment )
{
double Rcont = getConfiguration()->getRct();
//double Hcont = DbU::toPhysical( contact->getHeight(), DbU::UnitPower::Nano );
//double Wcont = DbU::toPhysical( contact->getWidth (), DbU::UnitPower::Nano );
double Wcont = DbU::toLambda( contact->getWidth () );
double Acont = Wcont * Wcont;
*R += Rcont * Acont;
if (not segment) {
*C = 0;
} else {
double Rseg = getConfiguration()->getRsm();
double Cseg = getConfiguration()->getCsm();
//double Lseg = DbU::toPhysical( segment->getLength(), DbU::UnitPower::Nano );
//double Wseg = DbU::toPhysical( segment->getWidth (), DbU::UnitPower::Nano );
double Lseg = DbU::toLambda( segment->getLength() );
double Wseg = DbU::toLambda( segment->getWidth () );
double Aseg = Lseg * Wseg;
cdebug_log(199,0) << "Elmore::setRC() on " << segment << endl;
cdebug_log(199,0) << " Lseg=" << Lseg << " Wseg=" << Wseg << " Aseg=" << Aseg << endl;
*R += Rseg * Aseg;
*C += (Aseg) ? 1/(Cseg*Aseg) : 0.0;
}
}
Delay* Elmore::delayElmore ( RoutingPad* rp )
{ return _tree->computeElmoreDelay( rp ); }
void Elmore::toTree ( ostream& os ) const
{ _tree->print( os ); }
string Elmore::_getTypeName () const
{ return "Seabreeze::Elmore"; }
string Elmore::_getString () const
{
string s = "<" + _getTypeName() + ">";
return s;
}
Record* Elmore::_getRecord () const
{
Record* record = new Record ( _getString() );
if (record != nullptr) {
record->add( getSlot("_seabreeze", _seabreeze) );
record->add( getSlot("_net" , _net ) );
record->add( getSlot("_driver" , _driver ) );
record->add( getSlot("_tree" , _tree ) );
record->add( getSlot("_delays" , &_delays ) );
}
return record;
}
//---------------------------------------------------------
// Class : "ElmoreProperty"
Name ElmoreProperty::_name = "Seabreeze::Elmore";
ElmoreProperty::ElmoreProperty ( Net* net )
: PrivateProperty()
, _elmore (net)
{
if (net) {
SeabreezeEngine* seabreeze
= dynamic_cast<SeabreezeEngine*>( ToolEngine::get( net->getCell(), "Seabreeze" ));
if (not seabreeze) {
cerr << Error( "ElmoreProperty::ElmoreProperty(): Cannot find SeabreezeEngine on %s."
, getString(net->getCell()).c_str()) << endl;
}
_elmore.setSeabreeze( seabreeze );
_elmore.setup();
}
cdebug_log(199,0) << "ElmoreProperty::ElmoreProperty() on " << net << endl;
}
ElmoreProperty* ElmoreProperty::create ( Net* net )
{
ElmoreProperty* property = new ElmoreProperty( net );
property->_postCreate();
return property;
}
Name ElmoreProperty::staticGetName ()
{ return _name; }
Name ElmoreProperty::getName () const
{ return _name; }
string ElmoreProperty::_getTypeName () const
{ return "ElmoreProperty"; }
string ElmoreProperty::_getString () const
{
string s = PrivateProperty::_getString ();
s.insert ( s.length() - 1 , " " + getString(&_elmore) );
return s;
}
Record* ElmoreProperty::_getRecord () const
{
Record* record = PrivateProperty::_getRecord();
if ( record ) {
record->add( getSlot( "_name" , _name ) );
record->add( getSlot( "_elmore", &_elmore ) );
}
return record;
}
//---------------------------------------------------------
// Class : "ElmoreExtension"
Elmore* ElmoreExtension::create ( Net* net )
{
cdebug_log(199,1) << "ElmoreExtension::create() " << net << endl;
Elmore* elmore = get( net );
if (not elmore) {
ElmoreProperty* property = new ElmoreProperty( net );
net->put( property );
elmore = property->getElmore();
}
cdebug_tabw(199,-1);
return elmore;
}
void ElmoreExtension::destroy ( Net* net )
{
cdebug_log(199,1) << "ElmoreExtension::destroy() " << net << endl;
Property* property = net->getProperty( ElmoreProperty::staticGetName() );
if (property) net->remove( property );
cdebug_tabw(199,-1);
}
Elmore* ElmoreExtension::get ( Net* net )
{
Elmore* elmore = nullptr;
Property* property = net->getProperty( ElmoreProperty::staticGetName() );
if (property) elmore = static_cast<ElmoreProperty*>( property )->getElmore();
return elmore;
}
} // Seabreeze namespace.

View File

@ -1,86 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) SU 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | S e a b r e e z e - Timing Analysis |
// | |
// | Author : Vu Hoang Anh PHAM |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./Node.cpp" |
// +-----------------------------------------------------------------+
#include <iostream>
#include "seabreeze/Node.h"
namespace Seabreeze {
using std::string;
Node::Node ()
: _R (0.0)
, _Rt (0.0)
, _C (0.0)
, _parent (nullptr)
, _childs ()
, _contact(nullptr)
, _label (0)
, _ap (0)
{ }
Node::Node ( Node* parent, Contact* contact )
: _R (0.0)
, _Rt (0.0)
, _C (0.0)
, _parent (parent)
, _childs ()
, _contact(contact)
, _label (0)
, _ap (0)
{
if (parent) parent->addChild( this );
}
Node::~Node ()
{ }
string Node::_getTypeName () const
{ return "Seabreeze::Node"; }
string Node::_getString () const
{
string s = "<Node ";
s += getString( _contact );
s += " R=" + getString( _R );
s += " C=" + getString( _C );
s += ">";
return s;
}
Record* Node::_getRecord () const
{
Record* record = new Record ( _getString() );
if (record != nullptr) {
record->add( getSlot("_R" , _R ) );
record->add( getSlot("_Rt" , _Rt ) );
record->add( getSlot("_C" , _C ) );
record->add( getSlot("_parent" , _parent ) );
record->add( getSlot("_childs" , &_childs ) );
record->add( getSlot("_contact", _contact) );
record->add( getSlot("_label" , _label ) );
record->add( getSlot("_ap" , _ap ) );
}
return record;
}
} // Seabreeze namespace.

View File

@ -1,103 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2017-2021, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | T o o l E n g i n e T u t o r i a l |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./PySeabreeze.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/isobar/PyHurricane.h"
#include "hurricane/isobar/PyCell.h"
#include "seabreeze/PySeabreezeEngine.h"
namespace Seabreeze {
using std::cerr;
using std::endl;
using Hurricane::tab;
using Isobar::__cs;
using Isobar::getPyHash;
using CRL::PyTypeToolEngine;
// using CRL::PyTypeGraphicTool;
#if !defined(__PYTHON_MODULE__)
// +=================================================================+
// | "PySeabreeze" Shared Library Code Part |
// +=================================================================+
# else // End of PyHurricane Shared Library Code Part.
// +=================================================================+
// | "PySeabreeze" Python Module Code Part |
// +=================================================================+
extern "C" {
// +-------------------------------------------------------------+
// | "PySeabreeze" Module Methods |
// +-------------------------------------------------------------+
static PyMethodDef PySeabreeze_Methods[] =
{ {NULL, NULL, 0, NULL} /* sentinel */
};
static PyModuleDef PySeabreeze_ModuleDef =
{ PyModuleDef_HEAD_INIT
, .m_name = "Seabreeze"
, .m_doc = "Show how to interface Coriolis/C++ to Python."
, .m_size = -1
, .m_methods = PySeabreeze_Methods
};
// ---------------------------------------------------------------
// Module Initialization : "PyInit_Seabreeze ()"
PyMODINIT_FUNC PyInit_Seabreeze ( void )
{
cdebug_log(40,0) << "PyInit_Seabreeze()" << endl;
PySeabreezeEngine_LinkPyType();
//PyGraphicSeabreezeEngine_LinkPyType();
PYTYPE_READY_SUB( SeabreezeEngine , ToolEngine );
//PYTYPE_READY_SUB( GraphicSeabreezeEngine, GraphicTool );
PyObject* module = PyModule_Create( &PySeabreeze_ModuleDef );
if (module == NULL) {
cerr << "[ERROR]\n"
<< " Failed to initialize Seabreeze module." << endl;
return NULL;
}
Py_INCREF( &PyTypeSeabreezeEngine );
PyModule_AddObject( module, "SeabreezeEngine", (PyObject*)&PyTypeSeabreezeEngine );
//Py_INCREF( &PyTypeGraphicSeabreezeEngine );
//PyModule_AddObject( module, "GraphicSeabreezeEngine", (PyObject*)&PyTypeGraphicSeabreezeEngine );
return module;
}
} // End of extern "C".
#endif // Python Module Code Part.
} // Seabreeze namespace.

View File

@ -1,215 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2017-2018, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | T o o l E n g i n e T u t o r i a l |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./PySeabreezeEngine.cpp" |
// +-----------------------------------------------------------------+
#include <functional>
#include "hurricane/isobar/PyCell.h"
#include "hurricane/viewer/PyCellViewer.h"
#include "hurricane/isobar/PyNet.h"
#include "hurricane/viewer/ExceptionWidget.h"
#include "hurricane/Cell.h"
#include "crlcore/Utilities.h"
#include "seabreeze/PySeabreezeEngine.h"
# undef ACCESS_OBJECT
# undef ACCESS_CLASS
# define ACCESS_OBJECT _baseObject._object
# define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject)
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(SeabreezeEngine,seabreeze,function)
namespace Seabreeze {
using std::cerr;
using std::endl;
using std::hex;
using std::ostringstream;
using Hurricane::tab;
using Hurricane::Exception;
using Hurricane::Bug;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::ExceptionWidget;
using Isobar::ProxyProperty;
using Isobar::ProxyError;
using Isobar::ConstructorError;
using Isobar::HurricaneError;
using Isobar::HurricaneWarning;
using Isobar::getPyHash;
using Isobar::ParseOneArg;
using Isobar::ParseTwoArg;
using Isobar::PyCell;
using Isobar::PyCell_Link;
using Isobar::PyCellViewer;
using Isobar::PyTypeCellViewer;
using Isobar::PyNet;
using CRL::PyToolEngine;
extern "C" {
#if defined(__PYTHON_MODULE__)
// +=================================================================+
// | "PySeabreezeEngine" Python Module Code Part |
// +=================================================================+
static PyObject* PySeabreezeEngine_get ( PyObject*, PyObject* args )
{
cdebug_log(40,0) << "PySeabreezeEngine_get()" << endl;
SeabreezeEngine* seabreeze = NULL;
HTRY
PyObject* arg0;
if (not ParseOneArg("Seabreeze.get", args, CELL_ARG, &arg0)) return NULL;
seabreeze = SeabreezeEngine::get(PYCELL_O(arg0));
HCATCH
return PySeabreezeEngine_Link(seabreeze);
}
static PyObject* PySeabreezeEngine_create ( PyObject*, PyObject* args )
{
cdebug_log(40,0) << "PySeabreezeEngine_create()" << endl;
SeabreezeEngine* seabreeze = NULL;
HTRY
PyObject* arg0;
if (not ParseOneArg("Seabreeze.get", args, CELL_ARG, &arg0)) return NULL;
Cell* cell = PYCELL_O(arg0);
seabreeze = SeabreezeEngine::get(cell);
if (seabreeze == NULL) {
seabreeze = SeabreezeEngine::create(cell);
} else
cerr << Warning("%s already has a Seabreeze engine.",getString(cell).c_str()) << endl;
HCATCH
return PySeabreezeEngine_Link(seabreeze);
}
static PyObject* PySeabreezeEngine_setViewer ( PySeabreezeEngine* self, PyObject* args )
{
cdebug_log(40,0) << "PySeabreezeEngine_setViewer ()" << endl;
HTRY
METHOD_HEAD( "SeabreezeEngine.setViewer()" )
PyObject* pyViewer = NULL;
if (not PyArg_ParseTuple(args,"O:EtesianEngine.setViewer()",&pyViewer)) {
PyErr_SetString( ConstructorError, "Bad parameters given to EtesianEngine.setViewer()." );
return NULL;
}
if (IsPyCellViewer(pyViewer)) {
seabreeze->setViewer( PYCELLVIEWER_O(pyViewer) );
}
HCATCH
Py_RETURN_NONE;
}
/*
PyObject* PySeabreezeEngine_runTool ( PySeabreezeEngine* self )
{
cdebug_log(40,0) << "PySeabreezeEngine_runTool()" << endl;
Cell* cell = NULL;
HTRY
METHOD_HEAD("SeabreezeEngine.runTool()")
if (seabreeze->getViewer()) {
if (ExceptionWidget::catchAllWrapper( std::bind(&SeabreezeEngine::runTool,seabreeze) )) {
PyErr_SetString( HurricaneError, "SeabreezeEngine::runTool() has thrown an exception (C++)." );
return NULL;
}
cell = seabreeze->getCell();
} else {
cell = seabreeze->runTool();
}
HCATCH
return PyCell_Link( cell );
}
*/
static PyObject* PySeabreezeEngine_buildElmore ( PySeabreezeEngine* self, PyObject* args )
{
cdebug_log(40,0) << "PySeabreezeEngine_buildElmore()" << endl;
HTRY
PyObject* arg0 = NULL;
METHOD_HEAD("SeabreezeEngine.buildElmore()")
if (not ParseOneArg("Seabreeze.buildElmore()", args, NET_ARG, &arg0)) return NULL;
seabreeze->buildElmore(PYNET_O(arg0));
HCATCH
Py_RETURN_NONE;
}
// Standart Accessors (Attributes).
// Standart Destroy (Attribute).
DBoDestroyAttribute(PySeabreezeEngine_destroy,PySeabreezeEngine)
PyMethodDef PySeabreezeEngine_Methods[] =
{ { "get" , (PyCFunction)PySeabreezeEngine_get , METH_VARARGS|METH_STATIC
, "Returns the Seabreeze engine attached to the Cell, None if there isnt't." }
, { "create" , (PyCFunction)PySeabreezeEngine_create , METH_VARARGS|METH_STATIC
, "Create a Seabreeze engine on this cell." }
, { "setViewer" , (PyCFunction)PySeabreezeEngine_setViewer , METH_VARARGS
, "Associate a Viewer to this SeabreezeEngine." }
//, { "runDemoPart1" , (PyCFunction)PySeabreezeEngine_runDemoPart1 , METH_NOARGS
// , "Run the first part of the demo." }
, { "buildElmore" , (PyCFunction)PySeabreezeEngine_buildElmore , METH_VARARGS
, "Run the Seabreeze tool." }
, { "destroy" , (PyCFunction)PySeabreezeEngine_destroy , METH_NOARGS
, "Destroy the associated hurricane object. The python object remains." }
, {NULL, NULL, 0, NULL} /* sentinel */
};
DBoDeleteMethod(SeabreezeEngine)
PyTypeObjectLinkPyType(SeabreezeEngine)
#else // End of Python Module Code Part.
// +=================================================================+
// | "PySeabreezeEngine" Shared Library Code Part |
// +=================================================================+
// Link/Creation Method.
PyTypeInheritedObjectDefinitions(SeabreezeEngine,PyToolEngine)
DBoLinkCreateMethod(SeabreezeEngine)
#endif // Shared Library Code Part.
} // extern "C".
} // Seabreeze namespace.

View File

@ -1,158 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) SU 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | S e a b r e e z e - Timing Analysis |
// | |
// | Author : Vu Hoang Anh PHAM |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./SeabreezeEngine.cpp" |
// +-----------------------------------------------------------------+
#include <iomanip>
#include "hurricane/utilities/Path.h"
#include "hurricane/DebugSession.h"
#include "hurricane/UpdateSession.h"
#include "hurricane/Bug.h"
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/DataBase.h"
#include "hurricane/Technology.h"
#include "hurricane/Breakpoint.h"
#include "hurricane/Layer.h"
#include "hurricane/Net.h"
#include "hurricane/RoutingPad.h"
#include "hurricane/Plug.h"
#include "hurricane/Cell.h"
#include "hurricane/Instance.h"
#include "hurricane/Vertical.h"
#include "hurricane/Horizontal.h"
#include "crlcore/AllianceFramework.h"
#include "seabreeze/SeabreezeEngine.h"
#include "seabreeze/Elmore.h"
namespace Seabreeze {
using namespace std;
using Hurricane::dbo_ptr;
using Hurricane::UpdateSession;
using Hurricane::DebugSession;
using Hurricane::tab;
using Hurricane::Bug;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::Breakpoint;
using Hurricane::Timer;
using Hurricane::DbU;
using Hurricane::Box;
using Hurricane::Layer;
using Hurricane::DataBase;
using Hurricane::Technology;
using Hurricane::Component;
using Hurricane::Contact;
using Hurricane::Horizontal;
using Hurricane::Vertical;
using Hurricane::RoutingPad;
using Hurricane::Cell;
using Hurricane::Plug;
using Hurricane::Instance;
using Hurricane::Transformation;
using Hurricane::Occurrence;
//---------------------------------------------------------
// Class : "Seabreeze::SeabreezeEngine".
Name SeabreezeEngine::_toolName = "Seabreeze";
const Name& SeabreezeEngine::staticGetName ()
{ return _toolName; }
SeabreezeEngine* SeabreezeEngine::create ( Cell* cell )
{
SeabreezeEngine* seabreeze = new SeabreezeEngine ( cell );
seabreeze->_postCreate();
return seabreeze;
}
SeabreezeEngine* SeabreezeEngine::get ( const Cell* cell )
{ return static_cast<SeabreezeEngine*>(ToolEngine::get(cell, staticGetName())); }
const Name& SeabreezeEngine::getName () const
{ return _toolName; };
string SeabreezeEngine::_getTypeName () const
{ return getString(_toolName); }
string SeabreezeEngine::_getString () const
{
ostringstream os;
os << "<" << _toolName << " " << _cell->getName() << ">";
return os.str();
}
Record* SeabreezeEngine::_getRecord () const
{
Record* record = Super::_getRecord();
record->add( getSlot("_configuration", _configuration) );
return record;
}
void SeabreezeEngine::buildElmore ( Net* net )
{
DebugSession::open( net, 190, 200 );
cdebug_log(199,1) << "SeabreezeEngine::buildElmore()" << endl;
cdebug_log(199,0) << "Run on " << net << endl;
Elmore* elmore = ElmoreExtension::create( net );
elmore->buildTree();
cerr << "Net has " << elmore->getDelays().size() << " sink(s)." << endl;
for ( RoutingPad* rp : net->getRoutingPads() ) {
Plug* plug = static_cast<Plug*>( rp->getPlugOccurrence().getEntity() );
if (plug->getMasterNet()->getDirection() & Net::Direction::DirOut) {
continue;
}
cerr << "| Elmore's delay: " << elmore->delayElmore(rp) << endl;
}
cdebug_tabw(199,-1);
DebugSession::close();
}
SeabreezeEngine::SeabreezeEngine ( Cell* cell )
: Super (cell)
, _configuration(new Configuration())
, _viewer (NULL)
{}
SeabreezeEngine::~SeabreezeEngine ()
{
delete _configuration;
}
void SeabreezeEngine::_postCreate()
{
Super::_postCreate ();
}
void SeabreezeEngine::_preDestroy ()
{}
} // Seabreeze namespace.

View File

@ -1,207 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) SU 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | S e a b r e e z e - Timing Analysis |
// | |
// | Author : Vu Hoang Anh PHAM |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./Tree.cpp" |
// +-----------------------------------------------------------------+
#include <string>
#include <iostream>
#include <algorithm>
#include "hurricane/Error.h"
#include "hurricane/RoutingPad.h"
#include "hurricane/Net.h"
#include "seabreeze/Elmore.h"
#include "seabreeze/Tree.h"
#include "seabreeze/Node.h"
#include "seabreeze/Delay.h"
namespace Seabreeze {
using std::string;
using std::find;
using std::set;
using std::cerr;
using std::endl;
using std::ostream;
using Hurricane::Error;
using Hurricane::Hook;
using Hurricane::Component;
Tree::Tree ( Elmore* elmore )
: _elmore (elmore)
, _nodes ()
, _reacheds()
{}
Tree::~Tree ()
{
for( Node* n : _nodes) delete n;
}
Node* Tree::getNode ( Contact* contact )
{
for ( Node* n : _nodes ) {
if (n->contact() == contact) return n;
}
return nullptr;
}
void Tree::addNode ( Node* node )
{
if (find(_nodes.begin(), _nodes.end(), node) == _nodes.end()) {
setReached( node->contact() );
_nodes.push_back( node );
}
}
void Tree::markNodeAfter ( Node *ni )
{
if (not ni) return;
ni->setAp( 1 );
for ( Node* child : ni->childs() ) {
markNodeAfter( child );
}
}
void Tree::getBranch ( Contact* contact )
{
for ( Node* n : _nodes ) {
n->setLabel(0);
}
Node *ni = getNode( contact );
ni->setLabel(1);
while ( ni->parent() ) {
ni->parent()->setLabel(1);
ni = ni->parent();
}
}
Delay* Tree::computeElmoreDelay ( RoutingPad* rp )
{
if (not rp) {
cerr << Error( "Tree::computeDelay(): Sink RoutingPad argument is NULL." ) << endl;
return nullptr;
}
Delay* delay = _elmore->getDelay( rp );
if (not delay) {
cerr << Error( "Tree::computeDelay(): No delay for %s, aborting."
, getString(rp).c_str() ) << endl;
return nullptr;
}
Contact* sink = nullptr;
for ( Component* component : rp->getSlaveComponents() ) {
Contact* contact = dynamic_cast<Contact*>( component );
if (contact) {
sink = contact;
break;
}
}
if (not sink) {
cerr << Error( "Tree::computeDelay(): No Contact anchored on RoutingPad, aborting.\n"
" (on %s)"
, getString(rp).c_str()
) << endl;
return nullptr;
}
Hook* masterHook = sink->getAnchorHook()->getMasterHook();
if (masterHook) {
RoutingPad* myrp = dynamic_cast<RoutingPad*>( masterHook->getComponent() );
cdebug_log(199,0) << " Look back=" << myrp << endl;
}
cdebug_log(199,1) << "Tree::computeDelay()" << endl;
cdebug_log(199,0) << " rp=" << rp << endl;
cdebug_log(199,0) << " sink=" << sink << endl;
getBranch( sink );
Node* ni = getNode( sink );
markNodeAfter( ni );
ni->setAp( 0 );
// Compute Rt of all nodes
for ( size_t k = 0; k < _nodes.size(); k++ ) {
if (k == 0)
_nodes[k]->setRt( _nodes[k]->R() );
else {
if (_nodes[k]->ap() == 0) {
if (_nodes[k]->label() == 1) {
_nodes[k]->setRt( _nodes[k]->parent()->Rt() + _nodes[k]->R() );
} else {
_nodes[k]->setRt( _nodes[k]->parent()->Rt() );
}
} else {
_nodes[k]->setRt( ni->Rt() );
}
}
}
// Compute Elmore delay time
delay->setDelay( 0.0 );
for ( size_t k = 0; k < _nodes.size(); k++ ) {
delay->incDelay( (_nodes[k]->Rt()) * (_nodes[k]->C()) );
}
return delay;
}
void Tree::printNode ( ostream& os, Node* node, size_t depth )
{
string indent ( depth*2, ' ');
os << indent << node->contact() << " R=" << node->R() << " C=" << node->C() << endl;
for ( Node* child : node->childs() ) {
printNode( os, child, depth+1 );
}
}
void Tree::print ( ostream& os )
{
os << "Elmore Tree of " << _nodes[0]->contact()->getNet() << endl;
os << " Tree has " << _nodes.size() << " nodes :" << endl;
printNode( os, _nodes[0], 0 );
}
string Tree::_getTypeName () const
{ return "Seabreeze::Tree"; }
string Tree::_getString () const
{
string s = "<" + _getTypeName() + ">";
return s;
}
Record* Tree::_getRecord () const
{
Record* record = new Record ( _getString() );
if (record != nullptr) {
record->add( getSlot("_nodes" , &_nodes ) );
record->add( getSlot("_reacheds", &_reacheds) );
}
return record;
}
} // Seabreeze namespace.

View File

@ -1,64 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) SU 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | S e a b r e e z e - Timing Analysis |
// | |
// | Author : Vu Hoang Anh PHAM |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./seabreeze/Configuration.h" |
// +-----------------------------------------------------------------+
#pragma once
#include <string>
#include <vector>
#include <hurricane/DbU.h>
namespace Seabreeze {
using std::string;
using Hurricane::Record;
using Hurricane::Name;
using Hurricane::Layer;
using Hurricane::DbU;
using Hurricane::Contact;
using Hurricane::Segment;
//------------------------------------------------------------------------
// Class : "Seabreeze::Configuration"
class Configuration {
public :
Configuration ();
Configuration ( const Configuration& );
virtual ~Configuration ();
virtual Configuration* clone () const;
inline double getRct () const;
inline double getRsm () const;
inline double getCsm () const;
string _getTypeName () const;
string _getString () const;
Record* _getRecord () const;
protected :
// Attributes
double _Rct;
double _Rsm;
double _Csm;
private :
Configuration& operator= ( const Configuration& ) = delete;
};
inline double Configuration::getRct () const { return _Rct; }
inline double Configuration::getRsm () const { return _Rsm; }
inline double Configuration::getCsm () const { return _Csm; }
} // Seabreeze namespace.
INSPECTOR_P_SUPPORT(Seabreeze::Configuration);

View File

@ -1,64 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) SU 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | S e a b r e e z e - Timing Analysis |
// | |
// | Author : Vu Hoang Anh PHAM |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./seabreeze/Delay.h" |
// +-----------------------------------------------------------------+
#pragma once
#include <map>
#include <iostream>
#include "hurricane/RoutingPad.h"
namespace Seabreeze {
using Hurricane::Record;
using Hurricane::DBo;
using Hurricane::RoutingPad;
class Elmore;
//---------------------------------------------------------
// Class : Seabreeze::Delay
class Delay {
public:
Delay ( Elmore*, RoutingPad* );
~Delay ();
inline Elmore* getElmore () const;
inline RoutingPad* getSink () const;
inline double getDelay () const;
inline void setDelay ( double );
inline void incDelay ( double );
std::string _getTypeName () const;
std::string _getString () const;
Record* _getRecord () const;
private:
Elmore* _elmore;
RoutingPad* _sink;
double _delay;
};
inline Elmore* Delay::getElmore () const { return _elmore; }
inline RoutingPad* Delay::getSink () const { return _sink; }
inline double Delay::getDelay () const { return _delay; }
inline void Delay::setDelay ( double delay ) { _delay = delay; }
inline void Delay::incDelay ( double delay ) { _delay += delay; }
} // Seabreeze namespace.
INSPECTOR_P_SUPPORT(Seabreeze::Delay);

View File

@ -1,149 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) SU 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | S e a b r e e z e - Timing Analysis |
// | |
// | Author : Vu Hoang Anh PHAM |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./seabreeze/Elmore.cpp" |
// +-----------------------------------------------------------------+
#include <string>
#include <vector>
#include <set>
#include "hurricane/Property.h"
#include "hurricane/RoutingPad.h"
#include "hurricane/Contact.h"
#include "hurricane/Segment.h"
#include "Configuration.h"
#include "Tree.h"
#include "Delay.h"
namespace Hurricane {
class Net;
class Instance;
}
namespace Seabreeze {
using Hurricane::Name;
using Hurricane::DBo;
using Hurricane::Net;
using Hurricane::Cell;
using Hurricane::RoutingPad;
using Hurricane::Contact;
using Hurricane::Instance;
using Hurricane::Segment;
using Hurricane::PrivateProperty;
class SeabreezeEngine;
class ElmoreProperty;
//----------------------------------------------------------
// Class : Seabreeze::Elmore
class Elmore {
friend class ElmoreProperty;
public:
Elmore ( Net* );
~Elmore ();
inline SeabreezeEngine* getSeabreeze () const;
const Configuration* getConfiguration () const;
inline Net* getNet () const;
inline RoutingPad* getDriver () const;
Delay* getDelay ( RoutingPad* ) const;
inline const std::vector<Delay*>&
getDelays () const;
void buildTree ();
void buildFromNode ( Node* source, Segment* );
Contact* buildBranch ( double* R, double* C, Contact* contact );
void setRC ( double* R, double* C, Contact* , Segment* );
inline Tree* getTree ();
void setup ();
Delay* delayElmore ( RoutingPad* );
void toTree ( std::ostream& ) const;
inline void setSeabreeze ( SeabreezeEngine* );
Record* _getRecord () const;
std::string _getString () const;
std::string _getTypeName () const;
private:
private:
SeabreezeEngine* _seabreeze;
Net* _net;
RoutingPad* _driver;
Tree* _tree;
std::vector<Delay*> _delays;
};
inline SeabreezeEngine* Elmore::getSeabreeze () const { return _seabreeze; }
inline Net* Elmore::getNet () const { return _net; }
inline RoutingPad* Elmore::getDriver () const { return _driver; }
inline Tree* Elmore::getTree () { return _tree; }
inline void Elmore::setSeabreeze ( SeabreezeEngine* seabreeze ) { _seabreeze = seabreeze; }
inline const std::vector<Delay*>& Elmore::getDelays () const { return _delays; }
//---------------------------------------------------------
// Class : Seabreeze::ElmoreProperty
class ElmoreProperty : public Hurricane::PrivateProperty {
friend class ElmoreExtension;
private:
static Name _name;
public:
static ElmoreProperty* create ( Net* net );
static Name staticGetName ();
Name getName () const;
inline Elmore* getElmore ();
virtual string _getTypeName () const;
virtual Record* _getRecord () const;
virtual std::string _getString () const;
protected:
Elmore _elmore;
protected:
ElmoreProperty ( Net* );
};
inline Elmore* ElmoreProperty::getElmore ()
{ return &_elmore; }
//---------------------------------------------------------
// Class : Seabreeze::ElmoreExtension
class ElmoreExtension {
public:
static Elmore* create ( Net* );
static Elmore* get ( Net* );
static inline Tree* getTree ( Net* );
static inline void toTree ( Net*, std::ostream& );
static void destroy ( Net* );
};
inline Tree* ElmoreExtension::getTree ( Net* net )
{
Elmore* elmore = get( net );
return (elmore) ? elmore->getTree() : nullptr;
}
inline void ElmoreExtension::toTree ( Net* net, std::ostream& os )
{
Elmore* elmore = get( net );
if (elmore) elmore->toTree( os );
}
} // Seabreeze Namespace
INSPECTOR_P_SUPPORT(Seabreeze::Elmore);
INSPECTOR_P_SUPPORT(Seabreeze::ElmoreProperty);

View File

@ -1,83 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) SU 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | S e a b r e e z e - Timing Analysis |
// | |
// | Author : Vu Hoang Anh PHAM |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./seabreeze/Node.h" |
// +-----------------------------------------------------------------+
#pragma once
#include <vector>
#include "hurricane/Contact.h"
namespace Seabreeze {
using Hurricane::Record;
using Hurricane::Contact;
//----------------------------------------------------------
// Class : Seabreeze::Node.
class Node {
public:
Node ();
Node ( Node* parent, Contact* );
~Node ();
inline double R () const;
inline double Rt () const;
inline double C () const;
inline int label () const;
inline int ap () const;
inline Contact* contact () const;
inline Node* parent () const;
inline const std::vector<Node*>& childs () const;
inline void addChild ( Node* );
inline void setLabel ( int );
inline void setAp ( int );
inline void setRt ( double );
inline void setR ( double );
inline void setC ( double );
Record* _getRecord () const;
std::string _getString () const;
std::string _getTypeName () const;
private :
double _R;
double _Rt;
double _C;
Node* _parent;
std::vector<Node*> _childs;
Contact* _contact;
int _label;
int _ap;
};
inline double Node::R () const { return _R; }
inline double Node::Rt () const { return _Rt; }
inline double Node::C () const { return _C; }
inline int Node::label () const { return _label; }
inline int Node::ap () const { return _ap; }
inline Contact* Node::contact () const { return _contact; }
inline Node* Node::parent () const { return _parent; }
inline const std::vector<Node*>& Node::childs () const { return _childs; }
inline void Node::addChild ( Node* child ) { _childs.push_back( child ); }
inline void Node::setLabel ( int label ) { _label = label; }
inline void Node::setAp ( int ap ) { _ap = ap; }
inline void Node::setRt ( double rt ) { _Rt = rt; }
inline void Node::setR ( double r ) { _R = r; }
inline void Node::setC ( double c ) { _C = c; }
} // Seabreeze namespace;
INSPECTOR_P_SUPPORT(Seabreeze::Node);

View File

@ -1,42 +0,0 @@
#ifndef PY_SEABREEZE_ENGINE_H
#define PY_SEABREEZE_ENGINE_H
#include "hurricane/isobar/PyHurricane.h"
#include "crlcore/PyToolEngine.h"
#include "seabreeze/SeabreezeEngine.h"
namespace Seabreeze {
extern "C" {
// -------------------------------------------------------------------
// Python Object : "PySeabreezeEngine".
typedef struct {
CRL::PyToolEngine _baseObject;
} PySeabreezeEngine;
// -------------------------------------------------------------------
// Functions & Types exported to "PySeabreeze.ccp".
extern PyTypeObject PyTypeSeabreezeEngine;
extern PyMethodDef PySeabreezeEngine_Methods[];
extern PyObject* PySeabreezeEngine_Link ( Seabreeze::SeabreezeEngine* );
extern void PySeabreezeEngine_LinkPyType ();
extern void PySeabreezeEngine_postModuleInit ();
#define IsPySeabreezeEngine(v) ( (v)->ob_type == &PyTypeSeabreezeEngine )
#define PYSEABREEZEENGINE(v) ( (PySeabreezeEngine*)(v) )
#define PYSEABREEZEENGINE_O(v) ( PYSEABREEZEENGINE(v)->_baseObject._object )
} // extern "C".
} // Tutorial namespace.
#endif // PY_SEABREEZE_ENGINE_H

View File

@ -1,94 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) SU 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | S e a b r e e z e - Timing Analysis |
// | |
// | Author : Vu Hoang Anh PHAM |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./seabreeze/SeabreezeEngine.h" |
// +-----------------------------------------------------------------+
#pragma once
#include <string>
#include <iostream>
#include "hurricane/Name.h"
#include "hurricane/viewer/CellViewer.h"
#include "hurricane/RoutingPad.h"
namespace Hurricane {
class Net;
class Cell;
}
#include "crlcore/ToolEngine.h"
#include "seabreeze/Configuration.h"
namespace Seabreeze {
using Hurricane::Record;
using Hurricane::Name;
using Hurricane::Net;
using Hurricane::Cell;
using Hurricane::CellViewer;
using Hurricane::RoutingPad;
using CRL::ToolEngine;
//----------------------------------------------------------
// Class : "Seabreeze::SeabreezeEngine"
class SeabreezeEngine : public ToolEngine {
public :
typedef ToolEngine Super;
public :
static const Name& staticGetName ();
static SeabreezeEngine* create ( Cell* );
static SeabreezeEngine* get ( const Cell* );
public :
inline CellViewer* getViewer () const;
inline ToolEngine* base ();
virtual const Name& getName () const;
inline const Configuration* getConfiguration () const;
inline double getRct () const;
inline double getRsm () const;
inline double getCsm () const;
inline void setViewer ( CellViewer* );
virtual Record* _getRecord () const;
virtual std::string _getString () const;
virtual std::string _getTypeName () const;
virtual void buildElmore ( Net* net );
protected :
SeabreezeEngine ( Cell* );
virtual ~SeabreezeEngine ();
virtual void _postCreate ();
virtual void _preDestroy ();
private :
SeabreezeEngine ( const SeabreezeEngine& ) = delete;
SeabreezeEngine& operator= ( const SeabreezeEngine& ) = delete;
private :
// Attributes.
static Name _toolName;
protected :
Configuration* _configuration;
CellViewer* _viewer;
};
// Inline Functions.
inline ToolEngine* SeabreezeEngine::base () { return static_cast<ToolEngine*>(this); }
inline const Configuration* SeabreezeEngine::getConfiguration () const { return _configuration; }
inline double SeabreezeEngine::getRct () const { return getConfiguration()->getRct(); }
inline double SeabreezeEngine::getRsm () const { return getConfiguration()->getRsm(); }
inline double SeabreezeEngine::getCsm () const { return getConfiguration()->getCsm(); }
inline CellViewer* SeabreezeEngine::getViewer () const { return _viewer; }
inline void SeabreezeEngine::setViewer ( CellViewer* viewer ) { _viewer = viewer; }
} // Seabreeze namespace.
INSPECTOR_P_SUPPORT(Seabreeze::SeabreezeEngine);

View File

@ -1,77 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) SU 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | S e a b r e e z e - Timing Analysis |
// | |
// | Author : Vu Hoang Anh PHAM |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./seabreeze/Tree.h" |
// +-----------------------------------------------------------------+
#pragma once
#include <set>
#include <vector>
#include <iostream>
#include "hurricane/RoutingPad.h"
namespace Seabreeze {
using Hurricane::Record;
using Hurricane::DBo;
using Hurricane::Contact;
using Hurricane::RoutingPad;
class Node;
class Delay;
class Elmore;
//---------------------------------------------------------
// Class : Seabreeze::Tree.
class Tree {
public:
typedef std::set<Contact*,DBo::CompareById> ContactSet;
public:
Tree ( Elmore* );
~Tree ();
inline bool isReached ( Contact* ) const;
inline Elmore* getElmore () const;
inline size_t getN ();
Node* getNode ( Contact* );
inline const std::vector<Node*>& getNodeList () const;
inline void setReached ( Contact* );
void addNode ( Node* );
void markNodeAfter ( Node* );
void getBranch ( Contact* );
Delay* computeElmoreDelay ( RoutingPad* );
void printNode ( std::ostream& , Node* , size_t depth );
void print ( std::ostream& );
Record* _getRecord () const;
std::string _getString () const;
std::string _getTypeName () const;
private:
Elmore* _elmore;
std::vector<Node*> _nodes;
ContactSet _reacheds;
};
inline Elmore* Tree::getElmore () const { return _elmore; }
inline size_t Tree::getN () { return _nodes.size(); }
inline const std::vector<Node*>& Tree::getNodeList () const { return _nodes; }
inline void Tree::setReached ( Contact* contact ) { _reacheds.insert( contact ); }
inline bool Tree::isReached ( Contact* contact ) const { return _reacheds.count( contact ); }
} // Seabreeze namespace.
INSPECTOR_P_SUPPORT(Seabreeze::Tree);

View File

@ -1,143 +0,0 @@
#include <iostream>
#include <cassert>
#include <fstream>
#include <string>
#include <sstream>
#include <stdlib.h>
#include <map>
#include <vector>
#include "Seabreeze/Node.h"
#include "Seabreeze/Tree.h"
using namespace std;
void build_tree(std::ifstream &file, Tree &t){
if(file.is_open()){
string line;
getline(file, line);
char RoC;
int lb1, lb2, vl; // possible labels of current node (can be parrent - current or current - child), value of R(or C)
vector<string> infos; // memoriser of infos taken from line
// Read file, line by line, get infomations
while(getline(file, line)){
stringstream tmp(line);
string word;
while(tmp >> word){
infos.push_back(word);
}
// Format is :
// infos[0] = RoC
// infos[1] = lb1 = label of current node
// infos[2] = lb2 = label of child node
// infos[3] = vl = value of RoC
char RoC = infos[0].at(0);
// infos[i>0] has type of string, so we need to turn it into integer using strtol
lb1 = strtol(infos[1].c_str(), NULL, 10);
lb2 = strtol(infos[2].c_str(), NULL, 10);
vl = strtol(infos[3].c_str(), NULL, 10);
infos.clear();
if(lb1 < 0 || lb2 == 0 || lb2 < -1){
// No node can have the root as a child
// A parent node cannot have label < 0 (<0 means -1, which is the ground)
cout << "Please check your configuration !" << endl;
cout << RoC << "\t" << lb1 << "\t" << lb2 << "\t" << vl << endl;
return;
}
else if(lb1 >= 0 && lb2 == -1){
// In this case, the branch is connected to "the ground"
// lb1 is the label of current node
// Check if current node is already created
if(RoC == 'R'){
cout << "Please check your configuration !" << endl;
cout << RoC << "\t" << lb1 << "\t" << lb2 << "\t" << vl << endl;
return;
}
//----------------------------------------------------------------------------------
// cout << "Node label : " << lb1 << " " << lb2 << " " << RoC << " " << vl << endl;
//----------------------------------------------------------------------------------
if(t.get_node(lb1)->label == -1)
t.get_node(lb1)->label = lb1;
if(RoC == 'C')
t.get_node(lb1)->C = vl;
//----------------------------------------------------------------------------------
// cout << "Node " << t.get_node(lb1).label << " -> " << lb2 << " C = " << t.get_node(lb1).C << endl << endl;
//----------------------------------------------------------------------------------
}
else if(lb1 >= 0 && lb2 > 0){
// lb1 is the label of parent node
// lb2 is the label of current node
//----------------------------------------------------------------------------------
// cout << "Node label : " << lb1 << " " << lb2 << " " << RoC << " " << vl << endl;
// cout << "Exist ? " << " n1 : " << t.get_node(lb1).label+1 << " n2 : " << t.get_node(lb2).label+1 << endl;
//----------------------------------------------------------------------------------
if(t.get_node(lb1)->label == -1)
t.get_node(lb1)->label = lb1;
if(t.get_node(lb2)->label == -1)
t.get_node(lb2)->label = lb2;
// Get the nodes
if(RoC == 'R')
t.get_node(lb2)->R = vl;
else if(RoC == 'C')
t.get_node(lb2)->C = vl;
//-----------------------------------------------------------------------------------
// cout << "Node : " << t.get_node(lb1).label << " -> " << t.get_node(lb2).label << " R = " << t.get_node(lb2).R << " C = " << t.get_node(lb2).C << endl;
//-----------------------------------------------------------------------------------
((t.get_node(lb1))->Ne).push_back(t.get_node(lb2));
((t.get_node(lb2))->Np) = t.get_node(lb1);
//-----------------------------------------------------------------------------------
// cout << "Check : " << t.get_node(lb2).Np->label << " -> " << t.get_node(lb2).label << " R = " << t.get_node(lb2).R << " C = " << t.get_node(lb2).C << endl;
//-----------------------------------------------------------------------------------
}
}
//-----------------------------------------------------------------------------------
// cout << "Double check !" << endl;
// for(int i = 1; i < t.get_N(); i++){
// cout << t.get_node(i).Np->label << " -> " << t.get_node(i).label << " R = " << t.get_node(i).R << " C = " << t.get_node(i).C << endl;
// }
//-----------------------------------------------------------------------------------
}
}
int main(int argc, char *argv[]){
if(argc < 4){
cout << "Usage : ./test <file name> <nodes number> <point index>" << endl
<< "Example : " << argv[0] << " data.txt 10 3" << endl;
return 0;
}
cout << "Testing with data from : " << argv[1] << endl;
ifstream f(argv[1]);
assert(f.is_open());
int num = strtol(argv[2], NULL, 10);
Tree t;
for(int i = 0; i < num; i++){
t.new_node();
}
build_tree(f, t);
filebuf fb;
fb.open ( "output.txt", ios::out );
ostream fout(&fb);
t.print(fout);
int idx = strtol(argv[3], NULL, 10);
int time = t.Delay_Elmore(idx);
cout << "Elmore delay time : " << time << endl;
fb.close();
return 0;
}

View File

@ -1,5 +0,0 @@
R1 0 1 10
C1 1 -1 20
R2 1 2 30
C2 2 -1 10

View File

@ -1,15 +0,0 @@
R1 0 1 10
C1 1 -1 15
R2 1 2 20
C2 2 -1 25
R3 1 3 30
C3 3 -1 35
R4 3 4 40
C4 4 -1 45
R5 3 5 50
C5 5 -1 55
R6 3 6 60
C6 6 -1 65
R7 5 7 70
C7 7 -1 75

View File

@ -1 +0,0 @@
node : not only left and right children, can have multiple children

View File

@ -3,13 +3,12 @@
set(CMAKE_LEGACY_CYGWIN_WIN32 0)
project(ANABATIC)
set(ignoreVariables "${BUILD_DOC} ${CMAKE_INSTALL_DIR}")
set(ignoreVariables "${BUILD_DOC}")
option(BUILD_DOC "Build the documentation (doxygen)" OFF)
option(CHECK_DATABASE "Run database in full check mode (very slow)" OFF)
option(USE_LIBBFD "Link with BFD libraries to print stack traces" OFF)
cmake_minimum_required(VERSION 3.16)
cmake_minimum_required(VERSION 2.8.9)
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}$ENV{CORIOLIS_TOP}/share/cmake/Modules/")
find_package(Bootstrap REQUIRED)
@ -18,14 +17,13 @@
set_cmake_policies()
setup_boost()
setup_qt()
setup_python()
find_package(PythonLibs 2 REQUIRED)
find_package(PythonSitePackages REQUIRED)
find_package(FLUTE REQUIRED)
find_package(VLSISAPD REQUIRED)
find_package(HURRICANE REQUIRED)
find_package(CORIOLIS REQUIRED)
find_package(ETESIAN REQUIRED)
find_package(COLOQUINTE REQUIRED)
find_package(Doxygen)
add_subdirectory(src)

View File

@ -6,7 +6,7 @@
# ANABATIC_LIBRARIES - The path to where the Coriolis library files are.
SET(ANABATIC_INCLUDE_PATH_DESCRIPTION "directory containing the Katabatic include files. E.g /usr/local/include/coriolis2 or /asim/coriolis/include/coriolis2")
SET(ANABATIC_INCLUDE_PATH_DESCRIPTION "directory containing the Katabatic include files. E.g /usr/local/include/coriolis or /asim/coriolis/include/coriolis")
SET(ANABATIC_DIR_MESSAGE "Set the ANABATIC_INCLUDE_DIR cmake cache entry to the ${ANABATIC_INCLUDE_PATH_DESCRIPTION}")
@ -18,7 +18,7 @@ IF(UNIX)
FIND_PATH(ANABATIC_INCLUDE_PATH NAMES anabatic/AnabaticEngine.h PATHS
# Look in other places.
${CORIOLIS_DIR_SEARCH}
PATH_SUFFIXES include/coriolis2
PATH_SUFFIXES include/coriolis
# Help the user find it if we cannot.
DOC "The ${ANABATIC_INCLUDE_PATH_DESCRIPTION}"
)
@ -26,7 +26,7 @@ IF(UNIX)
FIND_LIBRARY(ANABATIC_LIBRARY_PATH
NAMES anabatic
PATHS ${CORIOLIS_DIR_SEARCH}
PATH_SUFFIXES lib64 lib
PATH_SUFFIXES lib${LIB_SUFFIX}
# Help the user find it if we cannot.
DOC "The ${ANABATIC_INCLUDE_PATH_DESCRIPTION}"
)

View File

@ -20,21 +20,17 @@
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/Breakpoint.h"
#include "hurricane/DataBase.h"
#include "hurricane/RegularLayer.h"
#include "hurricane/Horizontal.h"
#include "hurricane/RoutingPad.h"
#include "hurricane/Vertical.h"
#include "hurricane/Cell.h"
#include "hurricane/NetExternalComponents.h"
#include "hurricane/DebugSession.h"
#include "hurricane/UpdateSession.h"
#include "crlcore/RoutingGauge.h"
#include "crlcore/Measures.h"
#include "crlcore/Histogram.h"
#include "anabatic/GCell.h"
#include "anabatic/AutoContactTerminal.h"
#include "anabatic/NetBuilderHybridVH.h"
#include "anabatic/NetBuilderM2.h"
#include "anabatic/NetBuilderHV.h"
#include "anabatic/NetBuilderVH.h"
@ -49,11 +45,11 @@ namespace {
class SortAcByXY {
public:
inline bool operator() ( AutoContactTerminal* contact1, AutoContactTerminal* contact2 ) const;
inline bool operator() ( AutoContactTerminal* contact1, AutoContactTerminal* contact2 );
};
inline bool SortAcByXY::operator() ( AutoContactTerminal* contact1, AutoContactTerminal* contact2 ) const
inline bool SortAcByXY::operator() ( AutoContactTerminal* contact1, AutoContactTerminal* contact2 )
{
DbU::Unit x1 = contact1->getX();
DbU::Unit x2 = contact2->getX();
@ -123,33 +119,6 @@ namespace {
}
class NonReducedItem {
public:
inline NonReducedItem ( AutoSegment* segment=NULL, uint32_t nonReduceds=0 );
inline AutoSegment* segment () const;
inline uint32_t nonReduceds () const;
private:
AutoSegment* _segment;
uint32_t _nonReduceds;
};
inline NonReducedItem::NonReducedItem ( AutoSegment* segment, uint32_t nonReduceds )
: _segment (segment)
, _nonReduceds(nonReduceds)
{ }
inline AutoSegment* NonReducedItem::segment () const { return _segment; }
inline uint32_t NonReducedItem::nonReduceds () const { return _nonReduceds; }
bool operator< ( const NonReducedItem& lhs, const NonReducedItem& rhs )
{
int32_t deltaReduceds = (int32_t)lhs.nonReduceds() - (int32_t)rhs.nonReduceds();
if (deltaReduceds > 0) return true; // Most connected first.
if (deltaReduceds < 0) return false;
return lhs.segment()->getId() < rhs.segment()->getId(); // Smallest Id first.
}
} // Anonymous namespace.
@ -164,13 +133,11 @@ namespace Anabatic {
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::Breakpoint;
using Hurricane::DataBase;
using Hurricane::RegularLayer;
using Hurricane::Component;
using Hurricane::Horizontal;
using Hurricane::Vertical;
using Hurricane::NetRoutingExtension;
using Hurricane::NetExternalComponents;
using Hurricane::Cell;
using Hurricane::DebugSession;
using Hurricane::UpdateSession;
@ -178,7 +145,6 @@ namespace Anabatic {
using CRL::RoutingLayerGauge;
using CRL::addMeasure;
using CRL::getMeasure;
using CRL::Histogram;
// -------------------------------------------------------------------
@ -202,72 +168,28 @@ namespace Anabatic {
RawGCellsUnder::RawGCellsUnder ( const AnabaticEngine* engine, Segment* segment )
{
cdebug_log(112,1) << "RawGCellsUnder::RawGCellsUnder(Segment*): " << segment << endl;
cdebug_log(112,1) << "RawGCellsUnder::RawGCellsUnder(): " << segment << endl;
commonCtor( engine, segment->getSourcePosition(), segment->getTargetPosition() );
Box gcellsArea = engine->getCell()->getAbutmentBox();
Point sourcePosition = segment->getSourcePosition();
Point targetPosition = segment->getTargetPosition();
cdebug_tabw(112,-1);
}
RawGCellsUnder::RawGCellsUnder ( const AnabaticEngine* engine, Point source, Point target )
{
cdebug_log(112,1) << "RawGCellsUnder::RawGCellsUnder(Point,Point): s:"
<< source << " t:" << target << endl;
commonCtor( engine, source, target );
cdebug_tabw(112,-1);
}
void RawGCellsUnder::commonCtor ( const AnabaticEngine* engine, Point source, Point target )
{
cdebug_log(112,1) << "RawGCellsUnder::commontCtor(): s:" << source << " t:" << target << endl;
Box gcellsArea = engine->getCell()->getAbutmentBox();
DbU::Unit axis = 0;
Flags side = Flags::NoFlags;
if (source.getY() == target.getY()) {
side = Flags::EastSide;
axis = source.getY();
if (source.getX() > target.getX()) std::swap( source, target );
}
if (source.getX() == target.getX()) {
side = Flags::NorthSide;
axis = source.getX();
if (source.getY() > target.getY()) std::swap( source, target );
}
if (side == Flags::NoFlags) {
cerr << Error( "RawGCellsUnder::commonCtor(): Points are neither horizontally nor vertically aligneds (ignored)."
if ( (sourcePosition.getX() > gcellsArea.getXMax())
or (sourcePosition.getY() > gcellsArea.getYMax())
or (targetPosition.getX() <= gcellsArea.getXMin())
or (targetPosition.getY() <= gcellsArea.getYMin()) ) {
cerr << Error( "RawGCellsUnder::RawGCellsUnder(): %s is completly outside the GCells area (ignored)."
, getString(segment).c_str()
) << endl;
cdebug_tabw(112,-1);
DebugSession::close();
return;
}
if ( (source.getX() > gcellsArea.getXMax())
or (source.getY() > gcellsArea.getYMax())
or (target.getX() <= gcellsArea.getXMin())
or (target.getY() <= gcellsArea.getYMin()) ) {
cerr << Warning( "RawGCellsUnder::commonCtor(): Area is completly outside the GCells area (ignored).\n"
" * GCells area: %s\n"
" * Obstacle area: [%s %s %s %s]"
, getString(gcellsArea).c_str()
, DbU::getValueString(source.getX()).c_str()
, DbU::getValueString(source.getY()).c_str()
, DbU::getValueString(target.getX()).c_str()
, DbU::getValueString(target.getY()).c_str()
) << endl;
cdebug_tabw(112,-1);
return;
}
DbU::Unit xsource = std::max( source.getX(), gcellsArea.getXMin() );
DbU::Unit ysource = std::max( source.getY(), gcellsArea.getYMin() );
DbU::Unit xtarget = std::min( target.getX(), gcellsArea.getXMax() );
DbU::Unit ytarget = std::min( target.getY(), gcellsArea.getYMax() );
DbU::Unit xsource = std::max( sourcePosition.getX(), gcellsArea.getXMin() );
DbU::Unit ysource = std::max( sourcePosition.getY(), gcellsArea.getYMin() );
DbU::Unit xtarget = std::min( targetPosition.getX(), gcellsArea.getXMax() );
DbU::Unit ytarget = std::min( targetPosition.getY(), gcellsArea.getYMax() );
if (xtarget == gcellsArea.getXMax()) --xtarget;
if (ytarget == gcellsArea.getYMax()) --ytarget;
@ -276,24 +198,47 @@ namespace Anabatic {
GCell* gtarget = engine->getGCellUnder( xtarget, ytarget );
if (not gsource) {
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): Source not under a GCell (ignored)."
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): %s source not under a GCell (ignored)."
, getString(segment).c_str()
) << endl;
cdebug_tabw(112,-1);
DebugSession::close();
return;
}
if (not gtarget) {
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): Target not under a GCell (ignored)."
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): %s target not under a GCell (ignored)."
, getString(segment).c_str()
) << endl;
cdebug_tabw(112,-1);
DebugSession::close();
return;
}
if (gsource == gtarget) {
_elements.push_back( Element(gsource,NULL) );
cdebug_tabw(112,-1);
DebugSession::close();
return;
}
Flags side = Flags::NoFlags;
DbU::Unit axis = 0;
Horizontal* horizontal = dynamic_cast<Horizontal*>( segment );
if (horizontal) {
side = Flags::EastSide;
axis = horizontal->getY();
if (horizontal->getSourceX() > horizontal->getTargetX())
std::swap( gsource, gtarget );
} else {
Vertical* vertical = dynamic_cast<Vertical*>( segment );
side = Flags::NorthSide;
axis = vertical->getX();
if (vertical->getSourceY() > vertical->getTargetY())
std::swap( gsource, gtarget );
}
cdebug_log(112,0) << "flags:" << side << " axis:" << DbU::getValueString(axis) << endl;
Edge* edge = gsource->getEdgeAt( side, axis );
@ -314,28 +259,19 @@ namespace Anabatic {
// -------------------------------------------------------------------
// Class : "Anabatic::NetData".
NetData::NetData ( Net* net, AnabaticEngine* anabatic )
NetData::NetData ( Net* net )
: _net (net)
, _state (NetRoutingExtension::get(net))
, _searchArea()
, _rpCount (0)
, _diodeCount(0)
, _sparsity (0)
, _flags ()
, _noMoveUp ()
{
if (_state and _state->isMixedPreRoute()) return;
Cell* diodeCell = anabatic->getDiodeCell();
for ( RoutingPad* rp : _net->getRoutingPads() ) {
_searchArea.merge( rp->getBoundingBox() );
++_rpCount;
if (diodeCell) {
Plug* plug = dynamic_cast<Plug*>( rp->getPlugOccurrence().getEntity() );
if (plug and (plug->getInstance()->getMasterCell() == diodeCell))
++_diodeCount;
}
}
_update();
}
@ -372,48 +308,29 @@ namespace Anabatic {
, _viewer (NULL)
, _flags (Flags::DestroyBaseContact)
, _stamp (-1)
, _routingMode (DigitalMode)
, _densityMode (MaxDensity)
, _autoSegmentLut ()
, _autoContactLut ()
, _edgeCapacitiesLut()
, _blockageNet (cell->getNet("blockagenet"))
, _diodeCell (NULL)
{ }
{
_matrix.setCell( cell, _configuration->getSliceHeight() );
Edge::unity = _configuration->getSliceHeight();
if (not _blockageNet) _blockageNet = Net::create( cell, "blockagenet" );
}
void AnabaticEngine::_postCreate ()
{
Super::_postCreate();
_configuration = _createConfiguration();
setupNetBuilder();
_matrix.setCell( getCell(), _configuration->getSliceHeight() );
Edge::unity = _configuration->getSliceHeight();
if (not _blockageNet) {
_blockageNet = Net::create( getCell(), "blockagenet" );
_blockageNet->setType( Net::Type::BLOCKAGE );
}
_diodeCell = DataBase::getDB()->getCell( _configuration->getDiodeName() );;
if (not _diodeCell) {
cerr << Warning( "AnabaticEngine::_postCreate() Unable to find \"%s\" diode cell."
, _configuration->getDiodeName().c_str()
) << endl;
}
UpdateSession::open();
GCell::create( this );
UpdateSession::close();
checkPlacement();
}
Configuration* AnabaticEngine::_createConfiguration ()
{ return new Configuration(); }
AnabaticEngine* AnabaticEngine::create ( Cell* cell )
{
if (not cell) throw Error( "AnabaticEngine::create(): NULL cell argument." );
@ -457,7 +374,6 @@ namespace Anabatic {
void AnabaticEngine::_gutAnabatic ()
{
//DebugSession::open( 159, 160 );
openSession();
_flags.reset( Flags::DestroyBaseContact|Flags::DestroyBaseSegment );
@ -465,40 +381,19 @@ namespace Anabatic {
if (_state == EngineDriving) {
cdebug_log(145,1) << "Saving AutoContacts/AutoSegments." << endl;
vector<NonReducedItem> reduceds;
size_t fixedSegments = 0;
size_t sameLayerDoglegs = 0;
size_t bloatedStraps = 0;
for ( auto isegment : _autoSegmentLut ) {
if (isegment.second->isFixed()) ++fixedSegments;
if (isegment.second->canReduce( Flags::NullLength )) {
//cerr << "push_back() " << (void*)isegment.second << ":" << isegment.second << endl;
reduceds.push_back( NonReducedItem( isegment.second
, isegment.second->getNonReduceds( Flags::NoFlags ) ));
} else {
if (isegment.second->reduceDoglegLayer()) ++sameLayerDoglegs;
}
//if (isegment.second->bloatStackedStrap()) ++bloatedStraps;
}
sort( reduceds.begin(), reduceds.end() );
// cerr << "Reduced segment queue:" << endl;
// for ( size_t i=0 ; i<reduceds.size() ; ++i ) {
// cerr << "| " << setw(3) << i
// << " " << reduceds[i].nonReduceds()
// << " " << reduceds[i].segment() << endl;
// }
for ( auto& item : reduceds ) {
item.segment()->reduce( Flags::NoFlags );
if (item.segment()->reduceDoglegLayer()) ++sameLayerDoglegs;
if (isegment.second->reduceDoglegLayer()) ++sameLayerDoglegs;
}
cmess1 << " o Driving Hurricane data-base." << endl;
cmess1 << Dots::asSizet(" - Active AutoSegments" ,AutoSegment::getAllocateds()-fixedSegments) << endl;
cmess1 << Dots::asSizet(" - Active AutoContacts" ,AutoContact::getAllocateds()-fixedSegments*2) << endl;
cmess1 << Dots::asSizet(" - AutoSegments" ,AutoSegment::getAllocateds()) << endl;
cmess1 << Dots::asSizet(" - AutoContacts" ,AutoContact::getAllocateds()) << endl;
cmess1 << Dots::asSizet(" - Same Layer doglegs" ,sameLayerDoglegs) << endl;
cmess1 << Dots::asSizet(" - Bloated straps (< minArea)",bloatedStraps ) << endl;
cmess1 << Dots::asSizet(" - Active AutoSegments",AutoSegment::getAllocateds()-fixedSegments) << endl;
cmess1 << Dots::asSizet(" - Active AutoContacts",AutoContact::getAllocateds()-fixedSegments*2) << endl;
cmess1 << Dots::asSizet(" - AutoSegments" ,AutoSegment::getAllocateds()) << endl;
cmess1 << Dots::asSizet(" - AutoContacts" ,AutoContact::getAllocateds()) << endl;
cmess1 << Dots::asSizet(" - Same Layer doglegs" ,sameLayerDoglegs) << endl;
//for ( Net* net : _cell->getNets() ) _saveNet( net );
@ -521,33 +416,14 @@ namespace Anabatic {
_ovEdges.clear();
}
exportExternalNets();
Session::close();
//DebugSession::close();
}
void AnabaticEngine::exportExternalNets ()
{
for ( Net* net : getCell()->getNets() ) {
if (not net->isExternal()) continue;
if (net->isSupply()) continue;
for ( Segment* segment : net->getSegments() ) {
NetExternalComponents::setExternal( segment );
}
}
}
Configuration* AnabaticEngine::getConfiguration ()
{ return _configuration; }
const Configuration* AnabaticEngine::getConfiguration () const
{ return _configuration; }
Interval AnabaticEngine::getUSide ( Flags direction ) const
{
Interval side;
@ -595,113 +471,6 @@ namespace Anabatic {
}
bool AnabaticEngine::checkPlacement () const
{
bool valid = true;
Box cellAb = getCell()->getAbutmentBox();
for ( Occurrence occurrence : getCell()->getTerminalNetlistInstanceOccurrences() ) {
Instance* instance = static_cast<Instance*>(occurrence.getEntity());
Cell* masterCell = instance->getMasterCell();
string instanceName = occurrence.getCompactString();
instanceName.erase( 0, 1 );
instanceName.erase( instanceName.size()-1 );
Box instanceAb = masterCell->getAbutmentBox();
Transformation instanceTransf = instance->getTransformation();
occurrence.getPath().getTransformation().applyOn( instanceTransf );
instanceTransf.applyOn( instanceAb );
if (not cellAb.contains(instanceAb)) {
valid = false;
cerr << Error( "AnabaticEngine::checkPlacement(): Instance %s is outside top cell abutment box, routing will be incomplete.\n"
" (cell:%s vs instance:%s)"
, instanceName.c_str()
, getString(cellAb ).c_str()
, getString(instanceAb).c_str()
) << endl;
}
}
RoutingGauge* rg = _configuration->getRoutingGauge();
size_t errorCount = 0;
ostringstream errors;
errors << "AnabaticEngine::checkPlacement():\n";
for ( Net* net: getCell()->getNets() ) {
for ( RoutingPad* rp : net->getRoutingPads() ) {
Pin* pin = dynamic_cast<Pin*>( rp->getOccurrence().getEntity() );
if (not pin) continue;
ostringstream pinError;
RoutingLayerGauge* lg = rg->getLayerGauge( pin->getLayer() );
if (not lg) {
pinError << " Layer not in the routing gauge, "
<< "pin:" << pin->getLayer()->getName()
<< "\n";
valid = false;
++errorCount;
} else {
Point pinCenter = rp->getCenter();
if ( (pin->getAccessDirection() == Pin::AccessDirection::NORTH)
or (pin->getAccessDirection() == Pin::AccessDirection::SOUTH) ) {
if (not lg->isVertical()) {
pinError << " Should be in vertical routing layer, "
<< "pin:" << pin->getLayer()->getName()
<< " vs gauge:" << lg->getLayer()->getName()
<< "\n";
valid = false;
++errorCount;
}
if ((pinCenter.getX() - getCell()->getAbutmentBox().getXMin() - lg->getOffset())
% lg->getPitch()) {
pinError << " Misaligned, "
<< "pin:" << DbU::getValueString(pinCenter.getX())
<< " vs gauge, pitch:" << DbU::getValueString(lg->getPitch ())
<< ", offset:" << DbU::getValueString(lg->getOffset())
<< "\n";
valid = false;
++errorCount;
}
}
if ( (pin->getAccessDirection() == Pin::AccessDirection::EAST)
or (pin->getAccessDirection() == Pin::AccessDirection::WEST) ) {
if (not lg->isHorizontal()) {
pinError << " Should be in horizontal routing layer, "
<< "pin:" << pin->getLayer()->getName()
<< " vs gauge:" << lg->getLayer()->getName()
<< "\n";
valid = false;
++errorCount;
}
if ((pinCenter.getY() - getCell()->getAbutmentBox().getYMin() - lg->getOffset())
% lg->getPitch()) {
pinError << " Misaligned, "
<< "pin:" << DbU::getValueString(pinCenter.getY())
<< " vs gauge, pitch:" << DbU::getValueString(lg->getPitch ())
<< ", offset:" << DbU::getValueString(lg->getOffset())
<< "\n";
valid = false;
++errorCount;
}
}
if (not pinError.str().empty()) {
errors << "On " << pin << "\n" << pinError.str();
}
}
}
}
if (errorCount) throw Error( errors.str() );
return valid;
}
void AnabaticEngine::openSession ()
{ Session::_open(this); }
@ -720,18 +489,10 @@ namespace Anabatic {
void AnabaticEngine::setupNetDatas ()
{
Histogram netHistogram ( 0.0, 1.0, 1 );
netHistogram.setTitle ( "RoutingPads", 0 );
netHistogram.setColor ( "green" , 0 );
netHistogram.setIndent( " " , 0 );
size_t oindex = _netOrdering.size();
for ( Net* net : _cell->getNets() ) {
if (_netDatas.find(net->getId()) != _netDatas.end()) continue;
NetData* data = new NetData( net, this );
_netOrdering.push_back( data );
netHistogram.addSample( (float)(data->getRpCount() - data->getDiodeRpCount()), 0 );
_netOrdering.push_back( new NetData(net) );
}
for ( ; oindex < _netOrdering.size() ; ++oindex ) {
@ -740,9 +501,6 @@ namespace Anabatic {
}
sort( _netOrdering.begin(), _netOrdering.end(), SparsityOrder() );
cmess2 << " o Nets Histogram." << endl;
cmess2 << netHistogram.toString(0) << endl;
}
@ -809,7 +567,7 @@ namespace Anabatic {
NetData* data = NULL;
NetDatas::iterator idata = _netDatas.find( net->getId() );
if (idata == _netDatas.end()) {
data = new NetData( net, this );
data = new NetData( net );
_netDatas.insert( make_pair(net->getId(),data) );
_netOrdering.push_back( data );
// cerr << Bug( "AnabaticEngine::getNetData() - %s is missing in NetDatas table."
@ -829,8 +587,8 @@ namespace Anabatic {
Contact* AnabaticEngine::breakAt ( Segment* segment, GCell* breakGCell )
{
size_t i = 0;
GCellsUnder gcells ( new RawGCellsUnder(this,segment) );
size_t i = 0;
GCellsUnder gcells ( new RawGCellsUnder(this,segment) );
for ( ; i<gcells->size() ; ++i ) {
if (gcells->gcellAt(i) == breakGCell) break;
}
@ -854,7 +612,7 @@ namespace Anabatic {
if (horizontal) {
splitted = Horizontal::create( breakContact
, targetContact
, _configuration->getGHorizontalLayer()
, getConfiguration()->getGHorizontalLayer()
, horizontal->getY()
, DbU::fromLambda(2.0)
);
@ -863,7 +621,7 @@ namespace Anabatic {
if (vertical) {
splitted = Vertical::create( breakContact
, targetContact
, _configuration->getGVerticalLayer()
, getConfiguration()->getGVerticalLayer()
, vertical->getX()
, DbU::fromLambda(2.0)
);
@ -871,9 +629,6 @@ namespace Anabatic {
return breakContact;
}
NetData* netData = getNetData( segment->getNet() );
if (netData and netData->isNoMoveUp(segment))
netData->setNoMoveUp( splitted );
for ( ; i<gcells->size()-1 ; ++i ) gcells->edgeAt(i)->replace( segment, splitted );
return breakContact;
@ -1096,17 +851,6 @@ namespace Anabatic {
UpdateSession::open();
for ( GCell* gcell : _gcells ) gcell->cleanupGlobal();
UpdateSession::close();
for ( Net* net : getCell()->getNets() ) {
for ( Component* component : net->getComponents() ) {
if (_configuration->isGLayer(component->getLayer())) {
cerr << Error( "AnabaticEngine::cleanupGlobal(): Remaining global routing,\n"
" %s"
, getString(component).c_str()
) << endl;
}
}
}
}
@ -1118,15 +862,13 @@ namespace Anabatic {
if (_state > EngineGlobalLoaded)
throw Error ("AnabaticEngine::loadGlobalRouting() : global routing already loaded.");
antennaProtect();
if (method == EngineLoadGrByNet ) { _loadGrByNet(); }
else {
throw Error( badMethod, "Anabatic::loadGlobalRouting()", method, getString(_cell).c_str() );
}
cleanupGlobal();
if (not _configuration->isTwoMetals()) relaxOverConstraineds();
if (not getConfiguration()->isTwoMetals()) relaxOverConstraineds();
_state = EngineActive;
}
@ -1136,7 +878,7 @@ namespace Anabatic {
{
openSession();
//DbU::Unit pitch3 = Session::getPitch( 2 );
DbU::Unit pitch3 = Session::getPitch( 2 );
AutoSegment::IdSet constraineds;
AutoSegment::IdSet processeds;
@ -1243,64 +985,6 @@ namespace Anabatic {
}
void AnabaticEngine::setupNetBuilder ()
{
uint32_t gaugeKind = 4;
if (NetBuilderHybridVH::getStyle() == getNetBuilderStyle()) gaugeKind = 0;
else if (NetBuilderM2 ::getStyle() == getNetBuilderStyle()) gaugeKind = 1;
else if (NetBuilderVH ::getStyle() == getNetBuilderStyle()) gaugeKind = 2;
else if (NetBuilderHV ::getStyle() == getNetBuilderStyle()) gaugeKind = 3;
if (gaugeKind == 0) {
if (not _configuration->isVH())
throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"."
, getString(_configuration->getRoutingGauge()->getName()).c_str()
, getNetBuilderStyle().c_str() );
if (getRoutingStyle() == StyleFlags::NoStyle) {
_configuration->setRoutingStyle( StyleFlags::VH
| StyleFlags::Channel
| StyleFlags::Hybrid );
}
}
else if (gaugeKind == 1) {
if (getRoutingStyle() == StyleFlags::NoStyle) {
_configuration->setRoutingStyle( StyleFlags::Channel );
}
}
else if (gaugeKind == 2) {
if (not _configuration->isVH())
throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"."
, getString(_configuration->getRoutingGauge()->getName()).c_str()
, getNetBuilderStyle().c_str() );
if (_configuration->getRoutingGauge()->getUsableLayers() < 3)
throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"."
, getString(_configuration->getRoutingGauge()->getName()).c_str()
, getNetBuilderStyle().c_str() );
if (getRoutingStyle() == StyleFlags::NoStyle) {
_configuration->setRoutingStyle( StyleFlags::VH
| StyleFlags::OTH );
}
}
else if (gaugeKind == 3) {
if (not _configuration->isHV())
throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"."
, getString(_configuration->getRoutingGauge()->getName()).c_str()
, getNetBuilderStyle().c_str() );
if (_configuration->getRoutingGauge()->getUsableLayers() < 3)
throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"."
, getString(_configuration->getRoutingGauge()->getName()).c_str()
, getNetBuilderStyle().c_str() );
if (getRoutingStyle() == StyleFlags::NoStyle) {
_configuration->setRoutingStyle( StyleFlags::HV
| StyleFlags::OTH );
}
}
if (gaugeKind == 4) {
throw Error( "AnabaticEngine::_loadGrByNet(): Unsupported kind of routing auge style \"%s\"."
, getNetBuilderStyle().c_str() );
}
}
void AnabaticEngine::_loadGrByNet ()
{
cmess1 << " o Building detailed routing from global. " << endl;
@ -1310,30 +994,25 @@ namespace Anabatic {
startMeasures();
openSession();
uint32_t gaugeKind = 4;
if (NetBuilderHybridVH::getStyle() == getNetBuilderStyle()) gaugeKind = 0;
else if (NetBuilderM2 ::getStyle() == getNetBuilderStyle()) gaugeKind = 1;
else if (NetBuilderVH ::getStyle() == getNetBuilderStyle()) gaugeKind = 2;
else if (NetBuilderHV ::getStyle() == getNetBuilderStyle()) gaugeKind = 3;
int gaugeKind = 3;
if (getConfiguration()->isTwoMetals()) gaugeKind = 0;
if (getConfiguration()->isHV ()) gaugeKind = 1;
if (getConfiguration()->isVH ()) gaugeKind = 2;
if (gaugeKind < 4) {
if (gaugeKind < 3) {
for ( Net* net : getCell()->getNets() ) {
if (NetRoutingExtension::isShortNet(net)) {
//AutoSegment::setShortNetMode( true );
++shortNets;
}
if (NetRoutingExtension::isManualDetailRoute(net))
continue;
if ( NetRoutingExtension::isManualGlobalRoute(net)
or NetRoutingExtension::isAutomaticGlobalRoute(net)) {
if (NetRoutingExtension::isAutomaticGlobalRoute(net)) {
DebugSession::open( net, 145, 150 );
AutoSegment::setAnalogMode( NetRoutingExtension::isAnalog(net) );
switch ( gaugeKind ) {
case 0: NetBuilder::load<NetBuilderHybridVH>( this, net ); break;
case 1: NetBuilder::load<NetBuilderM2> ( this, net ); break;
case 2: NetBuilder::load<NetBuilderVH> ( this, net ); break;
case 3: NetBuilder::load<NetBuilderHV> ( this, net ); break;
case 0: NetBuilder::load<NetBuilderM2>( this, net ); break;
case 1: NetBuilder::load<NetBuilderHV>( this, net ); break;
case 2: NetBuilder::load<NetBuilderVH>( this, net ); break;
}
Session::revalidate();
@ -1352,11 +1031,16 @@ namespace Anabatic {
stopMeasures();
cmess2 << Dots::asSizet(" - Short nets",shortNets) << endl;
if (gaugeKind > 2) {
throw Error( "AnabaticEngine::_loadGrByNet(): Unsupported kind of routing gauge \"%s\"."
, getString(getConfiguration()->getRoutingGauge()->getName()).c_str() );
}
printMeasures( "load" );
addMeasure<size_t>( "Globals", AutoSegment::getGlobalsCount() );
addMeasure<size_t>( "Edges" , AutoSegment::getAllocateds() );
addMeasure<size_t>( getCell(), "Globals", AutoSegment::getGlobalsCount() );
addMeasure<size_t>( getCell(), "Edges" , AutoSegment::getAllocateds() );
}
@ -1492,7 +1176,7 @@ namespace Anabatic {
set<const Layer*> connectedLayers;
forEach ( Segment*, segment, net->getSegments() ) {
if (segment->getAnchoredLength()) {
if (segment->getLength()) {
if (net->isExternal()) {
NetExternalComponents::setExternal( *segment );
}
@ -1683,7 +1367,7 @@ namespace Anabatic {
EdgeCapacity* AnabaticEngine::_createCapacity ( Flags flags, Interval span )
{
size_t depth = _configuration->getAllowedDepth();
size_t depth = getConfiguration()->getAllowedDepth();
EdgeCapacity* edgeCapacity = NULL;
flags &= Flags::EdgeCapacityMask;
@ -1709,83 +1393,6 @@ namespace Anabatic {
}
void AnabaticEngine::computeEdgeCapacities ( int maxHCap, int maxVCap, int termSatThreshold, int maxTermSat )
{
vector<RoutingPad*> rps;
vector<GCell*> saturateds;
const vector<NetData*>& netDatas = getNetOrdering();
for ( NetData* netData : netDatas ) {
for ( Component* component : netData->getNet()->getComponents() ) {
RoutingPad* rp = dynamic_cast<RoutingPad*>( component );
if (rp) rps.push_back( rp );
}
}
UpdateSession::open();
for ( auto rp : rps ) {
if (not _configuration->selectRpComponent(rp))
cerr << Warning( "AnabaticEngine::computeEdgeCapacities(): %s has no components on grid.", getString(rp).c_str() ) << endl;
Point center = rp->getBoundingBox().getCenter();
GCell* gcell = getGCellUnder( center );
if (not gcell) {
cerr << Error( "AnabaticEngine::computeEdgeCapacities(): %s\n"
" @%s of %s is not under any GCell.\n"
" It will be ignored so the edge capacity estimate may be wrong."
, getString(rp).c_str()
, getString(center).c_str()
, getString(rp->getNet()).c_str()
) << endl;
continue;
}
gcell->incRpCount( 1 );
if (gcell->getRpCount() == termSatThreshold) saturateds.push_back( gcell );
}
for ( GCell* gcell : getGCells() ) {
if (not gcell->isMatrix()) continue;
for ( Edge* edge : gcell->getEdges(Flags::EastSide|Flags::NorthSide) ) {
GCell* opposite = edge->getOpposite( gcell );
int maxReserved = maxHCap;
int reserved = std::max( gcell->getRpCount(), opposite->getRpCount() );
if (edge->isVertical()) maxReserved = maxVCap;
edge->reserveCapacity( std::min( maxReserved, reserved ) );
}
}
for ( GCell* gcell : saturateds ) {
GCell* neighbor = gcell;
for ( size_t i=0 ; i<2; ++i ) {
Edge* edge = neighbor->getWestEdge();
if (not edge) break;
if (edge->getReservedCapacity() < (uint32_t)maxTermSat)
edge->reserveCapacity( maxTermSat - edge->getReservedCapacity() );
neighbor = neighbor->getWest();
}
neighbor = gcell;
for ( size_t i=0 ; i<2; ++i ) {
Edge* edge = neighbor->getEastEdge();
if (not edge) break;
if (edge->getReservedCapacity() < (uint32_t)maxTermSat)
edge->reserveCapacity( maxTermSat - edge->getReservedCapacity() );
neighbor = neighbor->getEast();
}
}
UpdateSession::close();
//Breakpoint::stop( 1, "Edge capacities computeds." );
}
void AnabaticEngine::_check ( Net* net ) const
{
cdebug_log(149,1) << "Checking " << net << endl;
@ -1830,10 +1437,10 @@ namespace Anabatic {
{
Super::printMeasures();
if (not tag.empty()) {
addMeasure<double>( tag+"T", getTimer().getCombTime () );
addMeasure<size_t>( tag+"S", (getTimer().getMemorySize() >> 20) );
}
// if (not tag.empty()) {
// addMeasure<double>( getCell(), tag+"T", getTimer().getCombTime () );
// addMeasure<size_t>( getCell(), tag+"S", (getTimer().getMemorySize() >> 20) );
// }
}

File diff suppressed because it is too large Load Diff

View File

@ -178,45 +178,23 @@ namespace Anabatic {
AutoHorizontal* AutoContact::getHorizontal2 () const { return NULL; }
AutoVertical* AutoContact::getVertical1 () const { return NULL; }
AutoVertical* AutoContact::getVertical2 () const { return NULL; }
bool AutoContact::isOnPin () const { return false; }
void AutoContact::getDepthSpan ( size_t& minDepth, size_t& maxDepth ) const
{
cdebug_log(145,1) << "AutoContact::getDepthSpan() of " << this << endl;
minDepth = (size_t)-1;
maxDepth = 0;
Component* anchor = getAnchor ();
if (anchor) {
cdebug_log(145,0) << "* Anchor depth: "
<< Session::getRoutingGauge()->getLayerDepth(anchor->getLayer())<< endl;
minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) );
maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) );
}
for ( AutoSegment* segment : const_cast<AutoContact*>(this)->getAutoSegments() ) {
cdebug_log(145,0) << "* segment depth: "
<< Session::getRoutingGauge()->getLayerDepth(segment->getLayer())<< endl;
minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) );
maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) );
}
cdebug_tabw(145,-1);
}
void AutoContact::updateLayer ()
{
size_t minDepth = (size_t)-1;
size_t maxDepth = 0;
getDepthSpan( minDepth, maxDepth );
setLayerAndWidth( maxDepth-minDepth, minDepth );
// if (minDepth == maxDepth)
// setLayer( Session::getRoutingGauge()->getRoutingLayer(minDepth) );
// else
// setLayer( Session::getRoutingGauge()->getContactLayer(minDepth) );
}
@ -234,17 +212,14 @@ namespace Anabatic {
size_t depth = Session::getRoutingGauge()->getLayerDepth(segment->getLayer());
DbU::Unit length;
if (segment->isLocal()) {
length = segment->getAnchoredLength();
length = segment->getLength();
lengths[depth] += length;
DbU::Unit sideLength = (segment->isHorizontal()) ? hSideLength : vSideLength;
if ( not segment->isUnbound() and (abs(length) > sideLength) )
cerr << Error( "AutoContact::getLength(): Suspicious length %s (> %s) of %s.\n"
" (on: %s)"
, DbU::getValueString(length).c_str()
, DbU::getValueString(sideLength).c_str()
, getString(segment).c_str()
, getString(this).c_str()) << endl;
cerr << Error("Suspicious length:%.2f of %s."
,DbU::getValueString(length).c_str()
,getString(segment).c_str()) << endl;
} else {
if (segment->isHorizontal()) {
if (isSourceHook)
@ -299,11 +274,11 @@ namespace Anabatic {
void AutoContact::invalidate ( Flags flags )
{
if (flags & Flags::Topology ) setFlags( CntInvalidatedCache );
if (not isInvalidated()) {
cdebug_log(145,1) << "AutoContact::invalidate() - " << this << endl;
cdebug_log(145,0) << "flags:" << flags.asString(FlagsFunction) << endl;
setFlags( CntInvalidated );
if (flags & Flags::Topology ) setFlags( CntInvalidatedCache );
Session::invalidate( this );
_invalidate( flags );
@ -481,13 +456,12 @@ namespace Anabatic {
void AutoContact::setConstraintBox ( const Box& box )
{
cdebug_log(149,0) << "setConstraintBox() " << this << " " << getConstraintBox()
<< " from:" << box << endl;
setCBXMin ( box.getXMin() );
setCBXMax ( box.getXMax() );
setCBYMin ( box.getYMin() );
setCBYMax ( box.getYMax() );
cdebug_log(149,0) << "setConstraintBox() " << this << " " << getConstraintBox() << endl;
cdebug_log(149,0) << "setConstraintBox() - " << this << " " << getConstraintBox()
<< " from:" << box << endl;
cdebug_log(149,0) << "* " << _gcell << endl;
}
@ -580,25 +554,15 @@ namespace Anabatic {
void AutoContact::setLayerAndWidth ( size_t delta, size_t depth )
{
cdebug_log(145,1) << "AutoContact::setLayerAndWidth() " << this << endl;
cdebug_log(145,0) << "delta:" << delta << " depth:" << depth << endl;
if (delta == 0) {
setLayer( Session::getRoutingLayer(depth) );
if (Session::getDirection(depth) & Flags::Horizontal) {
setSizes( Session::getPWireWidth(depth)
, Session::getWireWidth (depth) );
} else {
setSizes( Session::getWireWidth (depth)
, Session::getPWireWidth(depth) );
}
setSizes( Session::getWireWidth (depth)
, Session::getWireWidth (depth) );
} else {
setLayer( Session::getContactLayer(depth) );
setSizes( Session::getViaWidth (depth)
, Session::getViaWidth (depth) );
}
cdebug_tabw(145,-1);
}

View File

@ -29,7 +29,6 @@
#include "hurricane/RoutingPad.h"
#include "hurricane/Vertical.h"
#include "hurricane/Horizontal.h"
#include "hurricane/Pin.h"
#include "hurricane/DebugSession.h"
#include "crlcore/RoutingGauge.h"
#include "anabatic/AutoContactTerminal.h"
@ -48,7 +47,6 @@ namespace Anabatic {
using Hurricane::Transformation;
using Hurricane::Entity;
using Hurricane::Occurrence;
using Hurricane::Pin;
// -------------------------------------------------------------------
@ -131,13 +129,6 @@ namespace Anabatic {
}
bool AutoContactTerminal::isOnPin () const
{
RoutingPad* rp = dynamic_cast<RoutingPad*>( getAnchor() );
return (dynamic_cast<Pin*>(rp->getOccurrence().getEntity()) != NULL);
}
AutoSegment* AutoContactTerminal::getOpposite ( const AutoSegment* ) const
{ return NULL; }
@ -203,7 +194,7 @@ namespace Anabatic {
// SxLib bug: METAL1 terminal segments are 0.5 lambdas too shorts on
// their extremities. Should modificate all the standard cells layout...
// HARDCODED.
if (getString(Session::getRoutingGauge()->getName()).substr(0,6) == "msxlib")
if (Session::getRoutingGauge()->getName() == "msxlib")
yborder -= DbU::fromLambda( 1.0 );
else
yborder -= DbU::fromLambda( 0.5 );
@ -346,7 +337,7 @@ namespace Anabatic {
void AutoContactTerminal::cacheDetach ( AutoSegment* segment )
{
if (_segment == segment) {
//_segment->unsetFlags( AutoSegment::SegAxisSet );
_segment->unsetFlags( AutoSegment::SegAxisSet );
_segment = NULL;
setFlags( CntInvalidatedCache );
unsetFlags( CntDrag );
@ -406,8 +397,8 @@ namespace Anabatic {
if (horizontals[1] != NULL) ++count;
if (verticals [0] != NULL) ++count;
if (verticals [1] != NULL) ++count;
if (count != 1) {
showTopologyError( "Terminal has not *exactly* one segment." );
if (count > 1) {
showTopologyError( "Terminal has more than one segment." );
}
if (horizontals[0] != NULL ) {
_segment = Session::lookup( horizontals[0] );
@ -503,17 +494,11 @@ namespace Anabatic {
AutoContact* opposite = _segment->getOppositeAnchor(this);
AutoSegment* perpandicular = opposite->getPerpandicular( _segment );
if (perpandicular) {
cdebug_log(145,0) << "Draging V interval ["
<< DbU::getValueString(getCBYMin()) << " "
<< DbU::getValueString(getCBYMax()) << "]" << endl;
DbU::Unit y = perpandicular->getAxis();
y = std::min( y, getCBYMax() );
y = std::max( y, getCBYMin() );
Point onGrid = Session::getNearestGridPoint( Point(getX(),y), getConstraintBox() );
setY( onGrid.getY() );
cdebug_log(145,0) << "Draging to Y @" << DbU::getValueString(y)
<< " pitched:" << DbU::getValueString(onGrid.getY())
<< " " << getConstraintBox() << endl;
setY( y );
cdebug_log(145,0) << "Draging to Y @" << DbU::getValueString(y) << endl;
}
}
@ -562,11 +547,11 @@ namespace Anabatic {
if (delta > 1) {
//_segment = _segment->makeDogleg( this );
_segment->makeDogleg( this );
cdebug_log(145,0) << "Update seg: " << _segment << endl;
delta = abssub( anchorDepth, rg->getLayerDepth( _segment->getLayer() ) );
cdebug_log(145,0) << "Delta: " << delta << " Update seg: " << _segment << endl;
}
if (delta == 0) setLayerAndWidth( delta, anchorDepth );
if (delta == 1) setLayerAndWidth( delta, std::min(anchorDepth,segmentDepth) );
else if (delta == 0) setLayerAndWidth( delta, anchorDepth );
else if (delta == 1) setLayerAndWidth( delta, std::min(anchorDepth,segmentDepth) );
}
_segment->invalidate( this );

View File

@ -88,17 +88,8 @@ namespace Anabatic {
AutoSegment* AutoContactTurn::getPerpandicular ( const AutoSegment* reference ) const
{
cdebug_log(149,0) << _getTypeName() << "::getPerpandicular() " << this
<< " to:" << reference << endl;
cdebug_log(149,0) << "| _horizontal1:" << _horizontal1 << endl;
cdebug_log(149,0) << "| _vertical1 :" << _vertical1 << endl;
if (reference == _horizontal1) return _vertical1;
if (reference == _vertical1 ) return _horizontal1;
cdebug_log(149,0) << _getTypeName() << "::getPerpandicular() " << this
<< " to:" << reference << " failed." << endl;
return NULL;
}
@ -126,9 +117,6 @@ namespace Anabatic {
void AutoContactTurn::cacheDetach ( AutoSegment* segment )
{
cdebug_log(149,0) << _getTypeName() << "::cacheDetach() " << this
<< " from:" << segment << endl;
if (segment == _horizontal1) _horizontal1 = NULL;
else if (segment == _vertical1) _vertical1 = NULL;
else return;
@ -139,9 +127,6 @@ namespace Anabatic {
void AutoContactTurn::cacheAttach ( AutoSegment* segment )
{
cdebug_log(149,0) << _getTypeName() << "::cacheAttach() " << this
<< " to:" << segment << endl;
if (segment->getDirection() == Flags::Horizontal) {
if (_horizontal1) {
cerr << Bug( "%s::cacheAttach() On %s,\n"
@ -254,7 +239,7 @@ namespace Anabatic {
RoutingGauge* rg = Session::getRoutingGauge();
size_t depthH1 = rg->getLayerDepth( getHorizontal1()->getLayer() );
size_t depthV1 = rg->getLayerDepth( getVertical1 ()->getLayer() );
size_t depthContact = (depthH1 <= depthV1) ? depthH1 : depthH1-1;
size_t depthContact = (depthH1 < depthV1) ? depthH1 : depthH1-1;
size_t delta = abssub ( depthH1, depthV1 );
unsetFlags( CntWeakTerminal );
@ -262,10 +247,8 @@ namespace Anabatic {
showTopologyError( "Sheared Turn, layer delta exceed 3." );
setFlags( CntBadTopology );
} else {
if (delta > 1) {
bool updateH1 = (_horizontal1->isInvalidatedLayer() and not _horizontal1->isNonPref())
or _vertical1->isNonPref();
if (updateH1) {
if (delta == 3) {
if (_horizontal1->isInvalidatedLayer()) {
//_horizontal1 = static_cast<AutoHorizontal*>( _horizontal1->makeDogleg(this) );
_horizontal1->makeDogleg(this);
cdebug_log(145,0) << "Update h1: " << _horizontal1 << endl;
@ -276,7 +259,7 @@ namespace Anabatic {
}
depthH1 = rg->getLayerDepth( _horizontal1->getLayer() );
depthV1 = rg->getLayerDepth( _vertical1->getLayer() );
depthContact = (depthH1 <= depthV1) ? depthH1 : depthH1-1;
depthContact = (depthH1 < depthV1) ? depthH1 : depthH1-1;
delta = abssub ( depthH1, depthV1 );
}

View File

@ -14,19 +14,18 @@
// +-----------------------------------------------------------------+
#include <algorithm>
#include "hurricane/Bug.h"
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/DebugSession.h"
#include "hurricane/ViaLayer.h"
#include "hurricane/RoutingPad.h"
#include "crlcore/RoutingGauge.h"
#include "anabatic/Configuration.h"
#include "anabatic/AutoContactTerminal.h"
#include "anabatic/AutoContactTurn.h"
#include "anabatic/AutoHorizontal.h"
#include "anabatic/AutoVertical.h"
#include <algorithm>
#include "hurricane/Bug.h"
#include "hurricane/Error.h"
#include "hurricane/DebugSession.h"
#include "hurricane/ViaLayer.h"
#include "hurricane/RoutingPad.h"
#include "crlcore/RoutingGauge.h"
#include "anabatic/Configuration.h"
#include "anabatic/AutoContactTerminal.h"
#include "anabatic/AutoContactTurn.h"
#include "anabatic/AutoHorizontal.h"
#include "anabatic/AutoVertical.h"
namespace Anabatic {
@ -34,10 +33,8 @@ namespace Anabatic {
using std::min;
using std::max;
using std::abs;
using Hurricane::Bug;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::Bug;
using Hurricane::DebugSession;
using Hurricane::ViaLayer;
using Hurricane::RoutingPad;
@ -50,11 +47,13 @@ namespace Anabatic {
Segment* AutoHorizontal::base () { return _horizontal; }
Segment* AutoHorizontal::base () const { return _horizontal; }
Horizontal* AutoHorizontal::getHorizontal () { return _horizontal; }
DbU::Unit AutoHorizontal::getSourceU () const { return _horizontal->getSource()->getX(); }
DbU::Unit AutoHorizontal::getTargetU () const { return _horizontal->getTarget()->getX(); }
DbU::Unit AutoHorizontal::getSourceU () const { return _horizontal->getSourceX(); }
DbU::Unit AutoHorizontal::getTargetU () const { return _horizontal->getTargetX(); }
DbU::Unit AutoHorizontal::getDuSource () const { return _horizontal->getDxSource(); }
DbU::Unit AutoHorizontal::getDuTarget () const { return _horizontal->getDxTarget(); }
Interval AutoHorizontal::getSpanU () const { return Interval(_horizontal->getSourceX(),_horizontal->getTargetX()); }
void AutoHorizontal::setDuSource ( DbU::Unit du ) { _horizontal->setDxSource(du); }
void AutoHorizontal::setDuTarget ( DbU::Unit du ) { _horizontal->setDxTarget(du); }
string AutoHorizontal::_getTypeName () const { return "AutoHorizontal"; }
@ -94,14 +93,6 @@ namespace Anabatic {
mergeNativeMax( gcell->getConstraintYMax() );
}
}
// if (getId() == 1518590) {
// cerr << "AutoHorizontal::_postCreate(): " << this << endl;
// cerr << "| Source contact:" << source << endl;
// cerr << "| Source GCell: " << getGCell() << endl;
// cerr << "| Target contact:" << target << endl;
// cerr << "| Target GCell: " << target->getGCell() << endl;
// }
}
@ -131,30 +122,6 @@ namespace Anabatic {
}
void AutoHorizontal::setDuSource ( DbU::Unit du )
{
_horizontal->setDxSource(du);
if (abs(du) > getPitch())
cerr << Warning( "AutoHorizontal::setDuSource(): Suspiciously big du=%s (should not exceed routing pitch %s)\n"
" On %s"
, DbU::getValueString(du).c_str()
, DbU::getValueString(getPitch()).c_str()
, getString(this).c_str() ) << endl;
}
void AutoHorizontal::setDuTarget ( DbU::Unit du )
{
_horizontal->setDxTarget(du);
if (abs(du) > getPitch())
cerr << Warning( "AutoHorizontal::setDuTarget(): Suspiciously big du=%s (should not exceed routing pitch %s)\n"
" On %s"
, DbU::getValueString(du).c_str()
, DbU::getValueString(getPitch()).c_str()
, getString(this).c_str() ) << endl;
}
Interval AutoHorizontal::getSourceConstraints ( Flags flags ) const
{
if (flags & Flags::NativeConstraints) {
@ -257,15 +224,13 @@ namespace Anabatic {
gcell = gcell->getEast( yprobe );
if (not gcell) {
success = false;
if (not isCreated()) {
cerr << Error( "AutoHorizontal::getGCells() : NULL GCell under %s\n"
" begin:%s\n"
" end: %s"
, getString(this).c_str()
, getString(getAutoSource()->getGCell()).c_str()
, getString(getAutoTarget()->getGCell()).c_str()
) << endl;
}
cerr << Error( "AutoHorizontal::getGCells() : NULL GCell under %s\n"
" begin:%s\n"
" end: %s"
, getString(this).c_str()
, getString(getAutoSource()->getGCell()).c_str()
, getString(getAutoTarget()->getGCell()).c_str()
) << endl;
break;
}
@ -280,35 +245,24 @@ namespace Anabatic {
{
cdebug_tabw(149,1);
AutoContact* source = getAutoSource();
AutoContact* target = getAutoTarget();
if (source->isOnPin() or target->isOnPin()) { cdebug_tabw(149,-1); return false; }
Interval sourceSide = source->getGCell()->getSide( Flags::Vertical );
Interval targetSide = target->getGCell()->getSide( Flags::Vertical );
Interval sourceConstraints = Interval(source->getCBYMin(),source->getCBYMax());
Interval targetConstraints = Interval(target->getCBYMin(),target->getCBYMax());
bool sourceGoStraight = source->getGCell()->isGoStraight();
bool targetGoStraight = target->getGCell()->isGoStraight();
Interval sourceSide = getAutoSource()->getGCell()->getSide( Flags::Vertical );
Interval targetSide = getAutoTarget()->getGCell()->getSide( Flags::Vertical );
Interval sourceConstraints = Interval(getAutoSource()->getCBYMin(),getAutoSource()->getCBYMax());
Interval targetConstraints = Interval(getAutoTarget()->getCBYMin(),getAutoTarget()->getCBYMax());
// Expand by a tiny amount for the "contains" to work for sure.
sourceConstraints.inflate( 1 );
targetConstraints.inflate( 1 );
cdebug_log(149,0) << "source " << source << endl;
cdebug_log(149,0) << "source " << getAutoSource() << endl;
cdebug_log(149,0) << "source constraints: " << sourceConstraints
<< " " << DbU::getValueString(sourceConstraints.getSize()) << endl;
cdebug_log(149,0) << "target " << target << endl;
cdebug_log(149,0) << "target " << getAutoTarget() << endl;
cdebug_log(149,0) << "target constraints: " << targetConstraints
<< " " << DbU::getValueString(targetConstraints.getSize()) << endl;
if (not sourceGoStraight and not sourceConstraints.contains(sourceSide)) { cdebug_tabw(149,-1); return true; }
if (not targetGoStraight and not targetConstraints.contains(targetSide)) { cdebug_tabw(149,-1); return true; }
if (not isUnbreakable()) {
if (source->isTurn() and (source->getPerpandicular(this)->getLayer() == getLayer())) { cdebug_tabw(149,-1); return true; }
if (target->isTurn() and (target->getPerpandicular(this)->getLayer() == getLayer())) { cdebug_tabw(149,-1); return true; }
}
if (not sourceConstraints.contains(sourceSide)) { cdebug_tabw(149,-1); return true; }
if (not targetConstraints.contains(targetSide)) { cdebug_tabw(149,-1); return true; }
cdebug_tabw(149,-1);
return false;
@ -324,52 +278,30 @@ namespace Anabatic {
const Configuration* configuration = Session::getConfiguration();
const Layer* metal2 = configuration->getRoutingLayer( 1 );
bool success = false;
bool isMetal2Source = false;
bool isMetal2Target = false;
bool isNonPrefSource = false;
bool isNonPrefTarget = false;
DbU::Unit height = 0;
AutoContact* source = getAutoSource();
AutoContact* target = getAutoTarget();
bool slackenSource = false;
bool slackenTarget = false;
bool success = false;
bool isMetal2Source = false;
bool isMetal2Target = false;
DbU::Unit height = 0;
AutoContact* source = getAutoSource();
AutoContact* target = getAutoTarget();
if (source->isTerminal()) {
height = (static_cast<RoutingPad*>(source->getAnchor()))->getBoundingBox().getHeight();
isMetal2Source = (source->getLayer() == metal2);
slackenSource = true;
}
if (target->isTerminal()) {
height = std::min( height, (static_cast<RoutingPad*>(target->getAnchor()))->getBoundingBox().getHeight() );
isMetal2Target = (target->getLayer() == metal2);
slackenTarget = true;
}
if (source->isTurn() and (source->getPerpandicular(this)->getLayer() == getLayer())) {
isNonPrefSource = true;
slackenSource = true;
}
cdebug_log(149,0) << "target:" << target << endl;
cdebug_log(149,0) << "target->getPerpandicular(this):" << target->getPerpandicular(this) << endl;
if (target->isTurn() and (target->getPerpandicular(this)->getLayer() == getLayer())) {
isNonPrefTarget = true;
slackenTarget = true;
if (height >= 4*getPitch()) {
if (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < 5*getPitch()))
return false;
}
cdebug_tabw(149,1);
cdebug_log(149,0) << "_flags:" << (_flags & (SegGlobal|SegWeakGlobal)) << endl;
cdebug_log(149,0) << "test:" << (getAnchoredLength() < 5*getPitch()) << endl;
cdebug_log(149,0) << "length:" << DbU::getValueString(getAnchoredLength()) << endl;
if (height >= 4*getPitch()) {
if (not (_flags & (SegGlobal|SegWeakGlobal)) and (getAnchoredLength() < 5*getPitch())) {
cdebug_log(149,0) << "Too short terminal segment to slacken." << endl;
cdebug_tabw(149,-1);
return false;
}
}
cdebug_log(149,0) << "test:" << (getLength() < 5*getPitch()) << endl;
cdebug_log(149,0) << "length:" << DbU::getValueString(getLength()) << endl;
int lowSlack = (flags & Flags::HalfSlacken) ? 3 : 10;
bool sourceSlackened = false;
@ -378,7 +310,7 @@ namespace Anabatic {
DbU::Unit targetPosition = getTargetPosition();
AutoSegment* parallel = this;
if (slackenSource) {
if (source->isTerminal()) {
Interval perpandConstraints = getAutoTarget()->getUConstraints(Flags::Horizontal);
Interval constraints = source->getUConstraints (Flags::Vertical|Flags::NoGCellShrink);
Interval nativeConstraints = source->getNativeUConstraints(Flags::Vertical|Flags::NoGCellShrink);
@ -390,7 +322,7 @@ namespace Anabatic {
<< " native slack:" << nativeSlack << endl;
cdebug_log(149,0) << "Perpand constraints on target: " << perpandConstraints << endl;
// Ugly: GCell's track number is hardwired.
if (isNonPrefSource or (nativeSlack < lowSlack) or (nativeSlack - slack < 3)) {
if ((nativeSlack < lowSlack) or (nativeSlack - slack < 3)) {
cdebug_log(149,0) << "Slackening from Source: " << source << endl;
_makeDogleg( source->getGCell(), Flags::NoFlags );
sourceSlackened = true;
@ -418,7 +350,7 @@ namespace Anabatic {
if (parallel) target = parallel->getAutoTarget();
if (slackenTarget) {
if (target->isTerminal()) {
Interval constraints = target->getUConstraints (Flags::Vertical|Flags::NoGCellShrink);
Interval nativeConstraints = target->getNativeUConstraints(Flags::Vertical|Flags::NoGCellShrink);
int slack = constraints.getSize() / getPitch();
@ -428,7 +360,7 @@ namespace Anabatic {
cdebug_log(149,0) << "Target constraint: " << constraints
<< " slack:" << slack
<< " native slack:" << nativeSlack << endl;
if (isNonPrefTarget or (nativeSlack < lowSlack) or (nativeSlack - slack < 3)) {
if ((nativeSlack < lowSlack) or (nativeSlack - slack < 3)) {
cdebug_log(149,0) << "Slackening from Target: " << target << endl;
parallel->_makeDogleg( target->getGCell(), Flags::NoFlags );
targetSlackened = true;
@ -438,15 +370,7 @@ namespace Anabatic {
const vector<AutoSegment*>& doglegs = Session::getDoglegs();
if (targetSlackened and (doglegs.size() >= 2)) {
GCell* targetGCell = target->getGCell();
Box constraintBox = target->getConstraintBox();
cdebug_log(149,0) << "slacken from Target @" << DbU::getValueString(targetPosition) << endl;
if (targetPosition >= targetGCell->getXMax()) {
cdebug_log(149,0) << "On the rigthmost track, adjust of one P-pitch to the left." << endl;
targetPosition -= getPPitch();
constraintBox.inflate( getPPitch(), 0, 0, 0 );
}
cdebug_log(149,0) << "AutoHorizontal::_slacken(): Target @" << DbU::getValueString(targetPosition) << endl;
doglegs[doglegs.size()-2]->setAxis( targetPosition );
success = true;
@ -454,7 +378,7 @@ namespace Anabatic {
cdebug_log(149,0) << "Fixing on target terminal contact: "
<< doglegs[doglegs.size()-2]->getAutoTarget() << endl;
//doglegs[doglegs.size()-2]->getAutoTarget()->setFlags( CntFixed );
doglegs[doglegs.size()-2]->getAutoTarget()->setConstraintBox( constraintBox );
doglegs[doglegs.size()-2]->getAutoTarget()->setConstraintBox( target->getConstraintBox() );
doglegs[doglegs.size()-2]->getAutoTarget()->setFlags( CntUserNativeConstraints );
}
}
@ -511,10 +435,9 @@ namespace Anabatic {
void AutoHorizontal::updateOrient ()
{
if (_horizontal->getTarget()->getX() < _horizontal->getSource()->getX()) {
cdebug_log(149,1) << "updateOrient() " << this << " (before S/T swap)" << endl;
if (_horizontal->getTargetX() < _horizontal->getSourceX()) {
cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl;
_horizontal->invert();
cdebug_log(149,0) << "updateOrient() " << this << " (after S/T swap)" << endl;
uint64_t spinFlags = _flags & SegDepthSpin;
unsetFlags( SegDepthSpin );
@ -532,15 +455,14 @@ namespace Anabatic {
unsetFlags( SegStrongTerminal );
if (terminalFlags & SegSourceTerminal) setFlags( SegTargetTerminal );
if (terminalFlags & SegTargetTerminal) setFlags( SegSourceTerminal );
cdebug_tabw(149,-1);
}
}
void AutoHorizontal::updatePositions ()
{
_sourcePosition = getSourceU() - getExtensionCap(Flags::Source);
_targetPosition = getTargetU() + getExtensionCap(Flags::Target);
_sourcePosition = _horizontal->getSourceX() - getExtensionCap(Flags::Source);
_targetPosition = _horizontal->getTargetX() + getExtensionCap(Flags::Target);
}
@ -560,8 +482,8 @@ namespace Anabatic {
bool AutoHorizontal::checkPositions () const
{
bool coherency = true;
DbU::Unit sourcePosition = _horizontal->getSource()->getX() - getExtensionCap(Flags::Source);
DbU::Unit targetPosition = _horizontal->getTarget()->getX() + getExtensionCap(Flags::Target);
DbU::Unit sourcePosition = _horizontal->getSourceX() - getExtensionCap(Flags::Source);
DbU::Unit targetPosition = _horizontal->getTargetX() + getExtensionCap(Flags::Target);
if ( _sourcePosition != sourcePosition ) {
cerr << "extensionCap: " << DbU::getValueString(getExtensionCap(Flags::Source)) << endl;
@ -846,10 +768,10 @@ namespace Anabatic {
//Session::doglegReset();
AutoContact* autoTarget = getAutoTarget();
AutoContact* autoSource = getAutoSource();
GCell* begin = autoSource->getGCell();
GCell* end = autoTarget->getGCell();
AutoContact* autoTarget = getAutoTarget();
AutoContact* autoSource = getAutoSource();
GCell* begin = autoSource->getGCell();
GCell* end = autoTarget->getGCell();
if (not autoSource->canDrag()) unsetFlags( SegDrag );
@ -875,15 +797,16 @@ namespace Anabatic {
bool upLayer = true;
if (Session::getRoutingGauge()->isTwoMetals()) {
upLayer = (not Session::getRoutingGauge()->isVH());
upLayer = (depth == 0);
} else if (Session::getRoutingGauge()->isVH()) {
upLayer = (depth < 2);
} else {
upLayer = (depth+1 <= Session::getConfiguration()->getAllowedDepth());
}
size_t doglegDepth = depth + ((upLayer)?1:-1);
Layer* contactLayer = Session::getRoutingGauge()->getContactLayer( depth + ((upLayer)?0:-1) );
size_t doglegDepth = depth + ((upLayer)?1:-1);
Layer* contactLayer = Session::getRoutingGauge()->getContactLayer( depth + ((upLayer)?0:-1) );
const Layer* doglegLayer = Session::getRoutingGauge()->getRoutingLayer( doglegDepth );
Session::dogleg( this );
targetDetach();
@ -908,56 +831,31 @@ namespace Anabatic {
segment2->setFlags( (isSlackened()?SegSlackened:0) );
Session::dogleg( segment2 );
if (autoSource->isTerminal() and autoTarget->isTerminal()) {
dlContact1->setFlags ( CntWeakTerminal );
dlContact2->setFlags ( CntWeakTerminal );
if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget );
if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource );
} else if (autoSource->isTerminal()) {
if (autoSource->isTerminal()) {
segment1->setFlags( SegWeakTerminal1 );
segment2->setFlags( SegWeakTerminal1 );
autoTarget->unsetFlags( CntWeakTerminal );
dlContact1->setFlags ( CntWeakTerminal );
if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget );
if (autoTarget->getGCell() == doglegGCell)
dlContact1->migrateConstraintBox( autoTarget );
} else if (autoTarget->isTerminal()) {
unsetFlags( SegTargetTerminal );
setFlags( SegWeakTerminal1 );
segment1->setFlags( SegWeakTerminal1 );
segment2->setFlags( SegTargetTerminal );
autoSource->unsetFlags( CntWeakTerminal );
dlContact2->setFlags ( CntWeakTerminal );
if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource );
} else if (isWeakTerminal()) {
if (autoSource->getGCell() == doglegGCell)
dlContact2->migrateConstraintBox( autoSource );
} else if (isWeakTerminal()) {
segment1->setFlags( SegWeakTerminal1 );
segment2->setFlags( SegWeakTerminal1 );
}
// if (autoSource->isTerminal()) {
// segment1->setFlags( SegWeakTerminal1 );
// segment2->setFlags( SegWeakTerminal1 );
// autoTarget->unsetFlags( CntWeakTerminal );
// dlContact1->setFlags ( CntWeakTerminal );
// if (autoTarget->getGCell() == doglegGCell)
// dlContact1->migrateConstraintBox( autoTarget );
// } else if (autoTarget->isTerminal()) {
// unsetFlags( SegTargetTerminal );
// setFlags( SegWeakTerminal1 );
// segment1->setFlags( SegWeakTerminal1 );
// segment2->setFlags( SegTargetTerminal );
// autoSource->unsetFlags( CntWeakTerminal );
// dlContact2->setFlags ( CntWeakTerminal );
// if (autoSource->getGCell() == doglegGCell)
// dlContact2->migrateConstraintBox( autoSource );
// } else if (isWeakTerminal()) {
// segment1->setFlags( SegWeakTerminal1 );
// segment2->setFlags( SegWeakTerminal1 );
// }
if (isAnalog()) {
segment1->setFlags( SegAnalog );
segment2->setFlags( SegAnalog );
}
if (isNoMoveUp()) {
segment1->setFlags( SegNoMoveUp );
segment2->setFlags( SegNoMoveUp );
}
cdebug_log(149,0) << "Session::dogleg[x+1] perpand: " << segment1 << endl;
cdebug_log(149,0) << "Session::dogleg[x+2] new paral: " << segment2 << endl;
@ -973,15 +871,12 @@ namespace Anabatic {
updateNativeConstraints();
segment2->updateNativeConstraints();
if ( isLocal()) autoSource->setFlags( AutoContactFlag::CntVDogleg );
if (segment2->isLocal()) autoTarget->setFlags( AutoContactFlag::CntVDogleg );
if (autoTarget->canDrag() and not autoSource->canDrag()) {
if (not autoTarget->getGCell()->isDevice() and (segment1->getGCell() == autoTarget->getGCell())) {
if (not autoTarget->getGCell()->isDevice()) {
Interval dragConstraints = autoTarget->getNativeUConstraints(Flags::Horizontal);
segment1->mergeUserConstraints( dragConstraints );
cdebug_log(149,0) << "Perpandicular has drag constraints: " << dragConstraints << endl;
cdebug_log(149,0) << "Perpandical has drag constraints: " << dragConstraints << endl;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,6 @@
#include <algorithm>
#include "hurricane/Bug.h"
#include "hurricane/Warning.h"
#include "hurricane/ViaLayer.h"
#include "hurricane/Vertical.h"
#include "crlcore/RoutingGauge.h"
@ -30,10 +29,8 @@ namespace Anabatic {
using std::min;
using std::max;
using std::abs;
using Hurricane::Bug;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::Bug;
using Hurricane::ViaLayer;
@ -44,11 +41,13 @@ namespace Anabatic {
Segment* AutoVertical::base () { return _vertical; }
Segment* AutoVertical::base () const { return _vertical; }
Vertical* AutoVertical::getVertical () { return _vertical; }
DbU::Unit AutoVertical::getSourceU () const { return _vertical->getSource()->getY(); }
DbU::Unit AutoVertical::getTargetU () const { return _vertical->getTarget()->getY(); }
DbU::Unit AutoVertical::getSourceU () const { return _vertical->getSourceY(); }
DbU::Unit AutoVertical::getTargetU () const { return _vertical->getTargetY(); }
DbU::Unit AutoVertical::getDuSource () const { return _vertical->getDySource(); }
DbU::Unit AutoVertical::getDuTarget () const { return _vertical->getDyTarget(); }
Interval AutoVertical::getSpanU () const { return Interval(_vertical->getSourceY(),_vertical->getTargetY()); }
void AutoVertical::setDuSource ( DbU::Unit du ) { _vertical->setDySource(du); }
void AutoVertical::setDuTarget ( DbU::Unit du ) { _vertical->setDyTarget(du); }
string AutoVertical::_getTypeName () const { return "AutoVertical"; }
@ -118,30 +117,6 @@ namespace Anabatic {
}
void AutoVertical::setDuSource ( DbU::Unit du )
{
_vertical->setDySource(du);
if (abs(du) > getPitch())
cerr << Warning( "AutoVertical::setDuSource(): Suspiciously big du=%s (should not exceed routing pitch %s)\n"
" On %s"
, DbU::getValueString(du).c_str()
, DbU::getValueString(getPitch()).c_str()
, getString(this).c_str() ) << endl;
}
void AutoVertical::setDuTarget ( DbU::Unit du )
{
_vertical->setDyTarget(du);
if (abs(du) > getPitch())
cerr << Warning( "AutoVertical::setDuTarget(): Suspiciously big du=%s (should not exceed routing pitch %s)\n"
" On %s"
, DbU::getValueString(du).c_str()
, DbU::getValueString(getPitch()).c_str()
, getString(this).c_str() ) << endl;
}
Interval AutoVertical::getSourceConstraints ( Flags flags ) const
{
if (flags & Flags::NativeConstraints) {
@ -243,15 +218,13 @@ namespace Anabatic {
if (not gcell) {
success = false;
if (not isCreated()) {
cerr << Error( "AutoVertical::getGCells() : NULL GCell under %s\n"
" begin:%s\n"
" end: %s"
, getString(this).c_str()
, getString(getAutoSource()->getGCell()).c_str()
, getString(getAutoTarget()->getGCell()).c_str()
) << endl;
}
cerr << Error( "AutoVertical::getGCells() : NULL GCell under %s\n"
" begin:%s\n"
" end: %s"
, getString(this).c_str()
, getString(getAutoSource()->getGCell()).c_str()
, getString(getAutoTarget()->getGCell()).c_str()
) << endl;
break;
}
@ -266,21 +239,17 @@ namespace Anabatic {
{
cdebug_tabw(149,-1);
if (getAutoSource()->isOnPin() or getAutoTarget()->isOnPin()) { cdebug_tabw(149,-1); return false; }
Interval sourceSide = getAutoSource()->getGCell()->getSide( Flags::Horizontal );
Interval targetSide = getAutoTarget()->getGCell()->getSide( Flags::Horizontal );
Interval sourceConstraints = Interval(getAutoSource()->getCBXMin(),getAutoSource()->getCBXMax());
Interval targetConstraints = Interval(getAutoTarget()->getCBXMin(),getAutoTarget()->getCBXMax());
bool sourceGoStraight = getAutoSource()->getGCell()->isGoStraight();
bool targetGoStraight = getAutoTarget()->getGCell()->isGoStraight();
// Expand by a tiny amount for the "contains" to work for sure.
sourceConstraints.inflate( 1 );
targetConstraints.inflate( 1 );
if (not sourceGoStraight and not sourceConstraints.contains(sourceSide)) { cdebug_tabw(149,-1); return true; }
if (not targetGoStraight and not targetConstraints.contains(targetSide)) { cdebug_tabw(149,-1); return true; }
if (not sourceConstraints.contains(sourceSide)) { cdebug_tabw(149,-1); return true; }
if (not targetConstraints.contains(targetSide)) { cdebug_tabw(149,-1); return true; }
cdebug_tabw(149,-1);
return false;
@ -293,13 +262,13 @@ namespace Anabatic {
if (not isDrag()) {
if ( not isStrongTerminal()
or (not (_flags & (SegGlobal|SegWeakGlobal)) and (getAnchoredLength() < getPitch()*5)) )
or (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < getPitch()*5)) )
{ cdebug_tabw(149,-1); return false; }
}
cdebug_log(149,0) << "_flags:" << (_flags & (SegGlobal|SegWeakGlobal)) << endl;
cdebug_log(149,0) << "test:" << (getAnchoredLength() < getPitch()*5) << endl;
cdebug_log(149,0) << "length:" << DbU::getValueString(getAnchoredLength()) << endl;
cdebug_log(149,0) << "test:" << (getLength() < getPitch()*5) << endl;
cdebug_log(149,0) << "length:" << DbU::getValueString(getLength()) << endl;
bool success = false;
bool sourceSlackened = false;
@ -430,8 +399,8 @@ namespace Anabatic {
void AutoVertical::updatePositions ()
{
_sourcePosition = getSourceU() - getExtensionCap(Flags::Source);
_targetPosition = getTargetU() + getExtensionCap(Flags::Target);
_sourcePosition = _vertical->getSourceY() - getExtensionCap(Flags::Source);
_targetPosition = _vertical->getTargetY() + getExtensionCap(Flags::Target);
}
@ -451,8 +420,8 @@ namespace Anabatic {
bool AutoVertical::checkPositions () const
{
bool coherency = true;
DbU::Unit sourcePosition = _vertical->getSource()->getY() - getExtensionCap(Flags::Source);
DbU::Unit targetPosition = _vertical->getTarget()->getY() + getExtensionCap(Flags::Target);
DbU::Unit sourcePosition = _vertical->getSourceY() - getExtensionCap(Flags::Source);
DbU::Unit targetPosition = _vertical->getTargetY() + getExtensionCap(Flags::Target);
if ( _sourcePosition != sourcePosition ) {
cerr << Error ( "%s\n Source position incoherency: "
@ -736,15 +705,16 @@ namespace Anabatic {
bool upLayer = true;
if (Session::getRoutingGauge()->isTwoMetals()) {
upLayer = (Session::getRoutingGauge()->isVH());
upLayer = (depth == 0);
} else if (Session::getRoutingGauge()->isVH()) {
upLayer = (depth < 2);
} else {
upLayer = (depth+1 <= Session::getConfiguration()->getAllowedDepth());
}
size_t doglegDepth = depth + ((upLayer)?1:-1);
Layer* contactLayer = Session::getRoutingGauge()->getContactLayer ( depth + ((upLayer)?0:-1) );
size_t doglegDepth = depth + ((upLayer)?1:-1);
Layer* contactLayer = Session::getRoutingGauge()->getContactLayer ( depth + ((upLayer)?0:-1) );
const Layer* doglegLayer = Session::getRoutingGauge()->getRoutingLayer ( doglegDepth );
Session::dogleg( this );
targetDetach();
@ -771,56 +741,31 @@ namespace Anabatic {
segment2->setFlags( (isSlackened()?SegSlackened:0) );
Session::dogleg( segment2 );
if (autoSource->isTerminal() and autoTarget->isTerminal()) {
dlContact1->setFlags ( CntWeakTerminal );
dlContact2->setFlags ( CntWeakTerminal );
if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget );
if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource );
} else if (autoSource->isTerminal()) {
if (isSourceTerminal()) {
segment1->setFlags( SegWeakTerminal1 );
segment2->setFlags( SegWeakTerminal1 );
autoTarget->unsetFlags( CntWeakTerminal );
dlContact1->setFlags ( CntWeakTerminal );
if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget );
} else if (autoTarget->isTerminal()) {
if (autoTarget->getGCell() == doglegGCell)
dlContact1->migrateConstraintBox( autoTarget );
} else if (isTargetTerminal()) {
unsetFlags( SegTargetTerminal );
setFlags( SegWeakTerminal1 );
segment1->setFlags( SegWeakTerminal1 );
segment2->setFlags( SegTargetTerminal );
autoSource->unsetFlags( CntWeakTerminal );
dlContact2->setFlags ( CntWeakTerminal );
if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource );
} else if (isWeakTerminal()) {
if (autoSource->getGCell() == doglegGCell)
dlContact2->migrateConstraintBox( autoSource );
} else if (isWeakTerminal()) {
segment1->setFlags( SegWeakTerminal1 );
segment2->setFlags( SegWeakTerminal1 );
}
// if (isSourceTerminal()) {
// segment1->setFlags( SegWeakTerminal1 );
// segment2->setFlags( SegWeakTerminal1 );
// autoTarget->unsetFlags( CntWeakTerminal );
// dlContact1->setFlags ( CntWeakTerminal );
// if (autoTarget->getGCell() == doglegGCell)
// dlContact1->migrateConstraintBox( autoTarget );
// } else if (isTargetTerminal()) {
// unsetFlags( SegTargetTerminal );
// setFlags( SegWeakTerminal1 );
// segment1->setFlags( SegWeakTerminal1 );
// segment2->setFlags( SegTargetTerminal );
// autoSource->unsetFlags( CntWeakTerminal );
// dlContact2->setFlags ( CntWeakTerminal );
// if (autoSource->getGCell() == doglegGCell)
// dlContact2->migrateConstraintBox( autoSource );
// } else if (isWeakTerminal()) {
// segment1->setFlags( SegWeakTerminal1 );
// segment2->setFlags( SegWeakTerminal1 );
// }
if (isAnalog()) {
segment1->setFlags( SegAnalog );
segment2->setFlags( SegAnalog );
}
if (isNoMoveUp()) {
segment1->setFlags( SegNoMoveUp );
segment2->setFlags( SegNoMoveUp );
}
cdebug_log(149,0) << "Session::dogleg[x+1] perpand: " << segment1 << endl;
cdebug_log(149,0) << "Session::dogleg[x+2] new paral: " << segment2 << endl;
@ -836,15 +781,12 @@ namespace Anabatic {
updateNativeConstraints();
segment2->updateNativeConstraints();
if ( isLocal()) autoSource->setFlags( AutoContactFlag::CntHDogleg );
if (segment2->isLocal()) autoTarget->setFlags( AutoContactFlag::CntHDogleg );
if (autoTarget->canDrag() and not autoSource->canDrag()) {
if (not autoTarget->getGCell()->isDevice() and (segment1->getGCell() == autoTarget->getGCell())) {
if (not autoTarget->getGCell()->isDevice()) {
Interval dragConstraints = autoTarget->getNativeUConstraints(Flags::Vertical);
segment1->mergeUserConstraints( dragConstraints );
cdebug_log(149,0) << "Perpandicular has drag constraints: " << dragConstraints << endl;
cdebug_log(149,0) << "Perpandical has drag constraints: " << dragConstraints << endl;
}
}

View File

@ -6,13 +6,12 @@ endif ( CHECK_DETERMINISM )
include_directories( ${ANABATIC_SOURCE_DIR}/src
${CORIOLIS_INCLUDE_DIR}
${ETESIAN_INCLUDE_DIR}
${HURRICANE_INCLUDE_DIR}
${CONFIGURATION_INCLUDE_DIR}
${FLUTE_INCLUDE_DIR}
${Boost_INCLUDE_DIRS}
${QtX_INCLUDE_DIRS}
${Python_INCLUDE_DIRS}
${QtX_INCLUDE_DIR}
${PYTHON_INCLUDE_PATH}
)
set( includes anabatic/Constants.h
anabatic/Configuration.h
@ -36,10 +35,9 @@ endif ( CHECK_DETERMINISM )
anabatic/NetBuilderM2.h
anabatic/NetBuilderHV.h
anabatic/NetBuilderVH.h
anabatic/NetBuilderHybridVH.h
anabatic/ChipTools.h
)
set( pyIncludes anabatic/PyStyleFlags.h )
set( pyIncludes )
set( cpps Constants.cpp
Configuration.cpp
Matrix.cpp
@ -63,19 +61,15 @@ endif ( CHECK_DETERMINISM )
NetBuilderM2.cpp
NetBuilderHV.cpp
NetBuilderVH.cpp
NetBuilderHybridVH.cpp
ChipTools.cpp
LayerAssign.cpp
AntennaProtect.cpp
PreRouteds.cpp
AnabaticEngine.cpp
)
set( pyCpps PyStyleFlags.cpp
PyAnabatic.cpp
set( pyCpps PyAnabatic.cpp
)
set( depLibs ${ETESIAN_LIBRARIES}
${CORIOLIS_PYTHON_LIBRARIES}
set( depLibs ${CORIOLIS_PYTHON_LIBRARIES}
${CORIOLIS_LIBRARIES}
${HURRICANE_PYTHON_LIBRARIES}
${HURRICANE_GRAPHICAL_LIBRARIES}
@ -83,15 +77,13 @@ endif ( CHECK_DETERMINISM )
${CONFIGURATION_LIBRARY}
${CIF_LIBRARY}
${AGDS_LIBRARY}
${COLOQUINTE_LIBRARIES}
${FLUTE_LIBRARIES}
${LEFDEF_LIBRARIES}
${OA_LIBRARIES}
${QtX_LIBRARIES}
${Boost_LIBRARIES}
${LIBXML2_LIBRARIES}
${Python3_LIBRARIES}
-lutil
${PYTHON_LIBRARIES} -lutil
)
add_library( anabatic ${cpps} )

View File

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "Configuration.cpp<anabatic>" -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2016-2022, All Rights Reserved
// Copyright (c) UPMC 2016-2018, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
@ -17,7 +17,7 @@
#include <iostream>
#include <iomanip>
#include <vector>
#include "hurricane/configuration/Configuration.h"
#include "vlsisapd/configuration/Configuration.h"
#include "hurricane/Warning.h"
#include "hurricane/Error.h"
#include "hurricane/Technology.h"
@ -25,8 +25,6 @@
#include "hurricane/BasicLayer.h"
#include "hurricane/RegularLayer.h"
#include "hurricane/RoutingPad.h"
#include "hurricane/Pin.h"
#include "hurricane/Pad.h"
#include "hurricane/NetExternalComponents.h"
#include "hurricane/Cell.h"
#include "crlcore/Utilities.h"
@ -57,8 +55,6 @@ namespace Anabatic {
using Hurricane::BasicLayer;
using Hurricane::RegularLayer;
using Hurricane::Segment;
using Hurricane::Pad;
using Hurricane::Pin;
using Hurricane::Plug;
using Hurricane::Path;
using Hurricane::Occurrence;
@ -73,50 +69,40 @@ namespace Anabatic {
Configuration::Configuration ( const CellGauge* cg, const RoutingGauge* rg )
: _gdepthv (ndepth)
, _gdepthh (ndepth)
, _ddepthv (ndepth)
, _ddepthh (ndepth)
, _ddepthc (ndepth)
, _netBuilderStyle (Cfg::getParamString("anabatic.netBuilderStyle","HV,3RL+")->asString() )
, _routingStyle (Cfg::getParamInt ("anabatic.routingStyle" ,StyleFlags::NoStyle)->asInt() )
, _cg (NULL)
, _rg (NULL)
, _extensionCaps ()
, _saturateRatio (Cfg::getParamPercentage("anabatic.saturateRatio",80.0)->asDouble())
, _saturateRp (Cfg::getParamInt ("anabatic.saturateRp" ,8 )->asInt())
, _globalThreshold (0)
, _allowedDepth (0)
, _edgeLength (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeLength",24)->asInt()))
, _edgeWidth (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeWidth" , 4)->asInt()))
, _edgeCostH (Cfg::getParamDouble("anabatic.edgeCostH" , 9.0)->asDouble())
, _edgeCostK (Cfg::getParamDouble("anabatic.edgeCostK" , -10.0)->asDouble())
, _edgeHInc (Cfg::getParamDouble("anabatic.edgeHInc" , 1.5)->asDouble())
, _edgeHScaling (Cfg::getParamDouble("anabatic.edgeHScaling" , 1.0)->asDouble())
, _globalIterations (Cfg::getParamInt ("anabatic.globalIterations", 10 )->asInt())
, _diodeName (Cfg::getParamString("etesian.diodeName" , "dio_x0")->asString() )
, _antennaGateMaxWL (Cfg::getParamInt ("etesian.antennaGateMaxWL" , 0 )->asInt())
, _antennaDiodeMaxWL(Cfg::getParamInt ("etesian.antennaDiodeMaxWL", 0 )->asInt())
: _gdepthv (ndepth)
, _gdepthh (ndepth)
, _ddepthv (ndepth)
, _ddepthh (ndepth)
, _ddepthc (ndepth)
, _cg (NULL)
, _rg (NULL)
, _extensionCaps ()
, _saturateRatio (Cfg::getParamPercentage("katabatic.saturateRatio",80.0)->asDouble())
, _saturateRp (Cfg::getParamInt ("katabatic.saturateRp" ,8 )->asInt())
, _globalThreshold (0)
, _allowedDepth (0)
, _edgeLength (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeLength",24)->asInt()))
, _edgeWidth (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeWidth" , 4)->asInt()))
, _edgeCostH (Cfg::getParamDouble("anabatic.edgeCostH" , 9.0)->asDouble())
, _edgeCostK (Cfg::getParamDouble("anabatic.edgeCostK" ,-10.0)->asDouble())
, _edgeHInc (Cfg::getParamDouble("anabatic.edgeHInc" , 1.5)->asDouble())
, _edgeHScaling (Cfg::getParamDouble("anabatic.edgeHScaling" , 1.0)->asDouble())
, _globalIterations(Cfg::getParamInt ("anabatic.globalIterations", 10 )->asInt())
{
GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() );
string gaugeName = Cfg::getParamString("anabatic.routingGauge","sxlib")->asString();
if (not cg)
if (cg == NULL) {
cg = AllianceFramework::get()->getCellGauge( gaugeName );
if (not cg) {
string cellGaugeName = Cfg::getParamString("anabatic.cellGauge","sxlib")->asString();
cg = AllianceFramework::get()->getCellGauge( cellGaugeName );
if (cg == NULL)
throw Error( "AnabaticEngine::Configuration(): Unable to find default cell gauge." );
}
if (not cg)
throw Error( "AnabaticEngine::Configuration(): Unable to find cell gauge \"%s\""
, gaugeName.c_str() );
if (not rg)
if (rg == NULL) {
rg = AllianceFramework::get()->getRoutingGauge( gaugeName );
if (not rg)
throw Error( "AnabaticEngine::Configuration(): Unable to find routing gauge \"%s\""
, gaugeName.c_str() );
if (rg == NULL)
throw Error( "AnabaticEngine::Configuration(): No routing gauge named \"%s\"", gaugeName.c_str() );
}
_cg = cg->getClone();
_rg = rg->getClone();
@ -169,42 +155,29 @@ namespace Anabatic {
}
}
}
if (_antennaGateMaxWL and not _antennaDiodeMaxWL) {
_antennaDiodeMaxWL = _antennaGateMaxWL;
cerr << Warning( "Anabatic::Configuration(): \"etesian.antennaGateMaxWL\" is defined but not \"etesian.antennaDiodeMaxWL\".\n"
" Setting both to %s"
, DbU::getValueString(_antennaGateMaxWL).c_str()
) << endl;
}
}
Configuration::Configuration ( const Configuration& other )
: _gmetalh (other._gmetalh)
, _gmetalv (other._gmetalv)
, _gcontact (other._gcontact)
, _gdepthv (other._gdepthv)
, _gdepthh (other._gdepthh)
, _ddepthv (other._ddepthv)
, _ddepthh (other._ddepthh)
, _ddepthc (other._ddepthc)
, _netBuilderStyle (other._netBuilderStyle)
, _routingStyle (other._routingStyle)
, _cg (NULL)
, _rg (NULL)
, _extensionCaps (other._extensionCaps)
, _saturateRatio (other._saturateRatio)
, _globalThreshold (other._globalThreshold)
, _allowedDepth (other._allowedDepth)
, _edgeCostH (other._edgeCostH)
, _edgeCostK (other._edgeCostK)
, _edgeHInc (other._edgeHInc)
, _edgeHScaling (other._edgeHScaling)
, _globalIterations (other._globalIterations)
, _diodeName (other._diodeName)
, _antennaGateMaxWL (other._antennaGateMaxWL)
, _antennaDiodeMaxWL(other._antennaDiodeMaxWL)
: _gmetalh (other._gmetalh)
, _gmetalv (other._gmetalv)
, _gcontact (other._gcontact)
, _gdepthv (other._gdepthv)
, _gdepthh (other._gdepthh)
, _ddepthv (other._ddepthv)
, _ddepthh (other._ddepthh)
, _ddepthc (other._ddepthc)
, _cg (NULL)
, _rg (NULL)
, _extensionCaps (other._extensionCaps)
, _saturateRatio (other._saturateRatio)
, _globalThreshold (other._globalThreshold)
, _allowedDepth (other._allowedDepth)
, _edgeCostH (other._edgeCostH)
, _edgeCostK (other._edgeCostK)
, _edgeHInc (other._edgeHInc)
, _edgeHScaling (other._edgeHScaling)
, _globalIterations(other._globalIterations)
{
GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() );
@ -227,10 +200,6 @@ namespace Anabatic {
bool Configuration::isTwoMetals () const
{ return _rg->isTwoMetals(); }
bool Configuration::isHybrid () const
{ return _routingStyle & StyleFlags::Hybrid; }
bool Configuration::isHV () const
@ -317,10 +286,6 @@ namespace Anabatic {
{ return getWireWidth( getLayerDepth(layer) ); }
DbU::Unit Configuration::getPWireWidth ( const Layer* layer ) const
{ return getPWireWidth( getLayerDepth(layer) ); }
Flags Configuration::getDirection ( const Layer* layer ) const
{ return getDirection( getLayerDepth(layer) ); }
@ -372,9 +337,6 @@ namespace Anabatic {
{ return _rg->getLayerWireWidth(depth); }
DbU::Unit Configuration::getPWireWidth ( size_t depth ) const
{ return _rg->getLayerPWireWidth(depth); }
DbU::Unit Configuration::getExtensionCap ( size_t depth ) const
{ return _extensionCaps[depth]; }
@ -496,26 +458,13 @@ namespace Anabatic {
cdebug_log(112,0) << "Looking into: " << masterNet->getCell() << endl;
for ( Component* component : masterNet->getComponents() ) {
cdebug_log(112,0) << "@ " << component << endl;
if (not NetExternalComponents::isExternal(component)) {
cdebug_log(112,0) << " Not an external component, skip." << endl;
continue;
}
if (not NetExternalComponents::isExternal(component)) continue;
if (dynamic_cast<Pin*>(component)) {
cdebug_log(112,0) << " Pins are always considered best candidates:" << component << endl;
bestComponent = component;
break;
}
Segment* segment = dynamic_cast<Segment*>(component);
if (not segment) continue;
if (segment->getLayer()->getMask() != metal1->getMask()) continue;
Component* candidate = dynamic_cast<Segment*>( component );
if (not candidate
or (candidate->getLayer()->getMask() != metal1->getMask()) )
candidate = dynamic_cast<Pin*>(component);
if (not candidate)
candidate = dynamic_cast<Pad*>( component );
if (not candidate) continue;
Box bb = transformation.getBox( candidate->getBoundingBox() );
Box bb = transformation.getBox( component->getBoundingBox() );
DbU::Unit trackPos = 0;
DbU::Unit minPos = DbU::Max;
DbU::Unit maxPos = DbU::Min;
@ -529,8 +478,8 @@ namespace Anabatic {
maxPos = bb.getXMax();
cdebug_log(112,0) << "Vertical gauge: " << gauge << endl;
cdebug_log(112,0) << "ab.getXMin(): " << DbU::getValueString(bb.getXMin()) << endl;
cdebug_log(112,0) << "ab.getXMax(): " << DbU::getValueString(bb.getXMax()) << endl;
cdebug_log(112,0) << "ab.getXMin(): " << DbU::getValueString(ab.getXMin()) << endl;
cdebug_log(112,0) << "ab.getXMax(): " << DbU::getValueString(ab.getXMax()) << endl;
cdebug_log(112,0) << "bb.getCenter(): " << DbU::getValueString(bb.getCenter().getX()) << endl;
} else {
trackPos = gauge->getTrackPosition( ab.getYMin()
@ -541,18 +490,18 @@ namespace Anabatic {
maxPos = bb.getYMax();
cdebug_log(112,0) << "Horizontal gauge: " << gauge << endl;
cdebug_log(112,0) << "ab.getYMin(): " << DbU::getValueString(bb.getYMin()) << endl;
cdebug_log(112,0) << "ab.getYMax(): " << DbU::getValueString(bb.getYMax()) << endl;
cdebug_log(112,0) << "ab.getYMin(): " << DbU::getValueString(ab.getYMin()) << endl;
cdebug_log(112,0) << "ab.getYMax(): " << DbU::getValueString(ab.getYMax()) << endl;
cdebug_log(112,0) << "bb.getCenter(): " << DbU::getValueString(bb.getCenter().getY()) << endl;
}
cdebug_log(112,0) << "| " << occurrence.getPath() << endl;
cdebug_log(112,0) << "| " << transformation << endl;
cdebug_log(112,0) << "| " << bb << " of:" << candidate << endl;
cdebug_log(112,0) << "| " << bb << " of:" << segment << endl;
cdebug_log(112,0) << "| Nearest Pos: " << DbU::getValueString(trackPos) << endl;
if ( (trackPos >= minPos) and (trackPos <= maxPos) ) {
if (not bestComponent or (bestSpan < maxPos-minPos)) {
if (not bestComponent or (bestSpan > maxPos-minPos)) {
bestComponent = component;
bestSpan = maxPos - minPos;
}
@ -584,7 +533,6 @@ namespace Anabatic {
cout << " o Configuration of ToolEngine<Anabatic> for Cell <" << cell->getName() << ">" << endl;
cout << Dots::asIdentifier(" - Routing Gauge" ,getString(_rg->getName())) << endl;
cout << Dots::asString (" - Top routing layer" ,topLayerName) << endl;
cout << Dots::asUInt (" - Maximum GR iterations" ,_globalIterations) << endl;
}
@ -607,22 +555,17 @@ namespace Anabatic {
Record* Configuration::_getRecord () const
{
Record* record = new Record ( _getString() );
record->add( getSlot( "_gdepthh" , _gdepthh ) );
record->add( getSlot( "_gdepthv" , _gdepthv ) );
record->add( getSlot( "_rg" , _rg ) );
record->add( getSlot( "_gmetalh" , _gmetalh ) );
record->add( getSlot( "_gmetalv" , _gmetalv ) );
record->add( getSlot( "_gcontact" , _gcontact ) );
record->add( getSlot( "_allowedDepth" , _allowedDepth ) );
record->add( getSlot( "_edgeCostH" , _edgeCostH ) );
record->add( getSlot( "_edgeCostK" , _edgeCostK ) );
record->add( getSlot( "_edgeHInc" , _edgeHInc ) );
record->add( getSlot( "_edgeHScaling" , _edgeHScaling ) );
record->add( getSlot( "_globalIterations", _globalIterations ) );
record->add( DbU::getValueSlot( "_antennaGateMaxWL" , &_antennaGateMaxWL ) );
record->add( DbU::getValueSlot( "_antennaDiodeMaxWL", &_antennaDiodeMaxWL ) );
record->add ( getSlot( "_gdepthh" , _gdepthh ) );
record->add ( getSlot( "_gdepthv" , _gdepthv ) );
record->add ( getSlot( "_rg" , _rg ) );
record->add ( getSlot( "_gmetalh" , _gmetalh ) );
record->add ( getSlot( "_gmetalv" , _gmetalv ) );
record->add ( getSlot( "_gcontact" , _gcontact ) );
record->add ( getSlot( "_allowedDepth", _allowedDepth ) );
record->add ( getSlot( "_edgeCostH" , _edgeCostH ) );
record->add ( getSlot( "_edgeCostK" , _edgeCostK ) );
return record;
return ( record );
}

View File

@ -14,22 +14,16 @@
// +-----------------------------------------------------------------+
#include "hurricane/Error.h"
#include "anabatic/Constants.h"
namespace Anabatic {
using std::hex;
using std::string;
using std::ostringstream;
using Hurricane::BaseFlags;
using Hurricane::Error;
// -------------------------------------------------------------------
// Class : "Anabatic::Flags".
const BaseFlags Flags::NoFlags = 0;
// Flags used for both objects states & functions arguments.
const BaseFlags Flags::Horizontal = (1L << 0);
@ -49,7 +43,6 @@ namespace Anabatic {
const BaseFlags Flags::ChannelRow = (1L << 13);
const BaseFlags Flags::HRailGCell = (1L << 14);
const BaseFlags Flags::VRailGCell = (1L << 15);
const BaseFlags Flags::GoStraight = (1L << 16);
// Flags for Edge objects states only.
const BaseFlags Flags::NullCapacity = (1L << 5);
const BaseFlags Flags::InfiniteCapacity = (1L << 6);
@ -59,13 +52,10 @@ namespace Anabatic {
const BaseFlags Flags::DestroyGCell = (1L << 7);
const BaseFlags Flags::DestroyBaseContact = (1L << 8);
const BaseFlags Flags::DestroyBaseSegment = (1L << 9);
const BaseFlags Flags::DisableCanonize = (1L << 10);
// Flags for NetDatas objects states only.
const BaseFlags Flags::GlobalFixed = (1L << 5);
const BaseFlags Flags::GlobalRouted = (1L << 5);
const BaseFlags Flags::GlobalEstimated = (1L << 6);
const BaseFlags Flags::GlobalRouted = (1L << 7);
const BaseFlags Flags::DetailRouted = (1L << 8);
const BaseFlags Flags::ExcludeRoute = (1L << 9);
const BaseFlags Flags::ExcludeRoute = (1L << 7);
// Masks.
const BaseFlags Flags::WestSide = Horizontal|Target;
const BaseFlags Flags::EastSide = Horizontal|Source;
@ -126,13 +116,6 @@ namespace Anabatic {
const BaseFlags Flags::CheckLowUpDensity = (1L << 31);
const BaseFlags Flags::NoUpdate = (1L << 32);
const BaseFlags Flags::NorthPath = (1L << 33);
const BaseFlags Flags::UseNonPref = (1L << 34);
const BaseFlags Flags::Force = (1L << 35);
const BaseFlags Flags::LayerCapOnly = (1L << 36);
const BaseFlags Flags::NoMinLength = (1L << 37);
const BaseFlags Flags::NoSegExt = (1L << 38);
const BaseFlags Flags::NullLength = (1L << 39);
const BaseFlags Flags::OnVSmall = (1L << 40);
Flags::~Flags ()
@ -186,7 +169,6 @@ namespace Anabatic {
return s.str();
}
string Flags::_getTypeName () const
{ return "Anabatic::Flags"; }
@ -201,13 +183,12 @@ namespace Anabatic {
s += (_flags & (uint64_t)DeviceGCell ) ? 'd' : '-';
s += (_flags & (uint64_t)HChannelGCell) ? 'c' : '-';
s += (_flags & (uint64_t)VChannelGCell) ? 'c' : '-';
s += (_flags & (uint64_t)HRailGCell ) ? 'H' : '-';
s += (_flags & (uint64_t)VRailGCell ) ? 'V' : '-';
s += (_flags & (uint64_t)StrutGCell ) ? 'S' : '-';
s += (_flags & (uint64_t)MatrixGCell ) ? 'M' : '-';
s += (_flags & (uint64_t)StdCellRow ) ? 'R' : '-';
s += (_flags & (uint64_t)HRailGCell ) ? 'r' : '-';
s += (_flags & (uint64_t)VRailGCell ) ? 'r' : '-';
s += (_flags & (uint64_t)StrutGCell ) ? 's' : '-';
s += (_flags & (uint64_t)MatrixGCell ) ? 'm' : '-';
s += (_flags & (uint64_t)StdCellRow ) ? 'S' : '-';
s += (_flags & (uint64_t)ChannelRow ) ? 'C' : '-';
s += (_flags & (uint64_t)GoStraight ) ? 'g' : '-';
s += ",";
s += (_flags & (uint64_t)Invalidated ) ? 'i' : '-';
s += (_flags & (uint64_t)DestroyGCell ) ? 'D' : '-';
@ -218,69 +199,4 @@ namespace Anabatic {
}
// -------------------------------------------------------------------
// Class : "Anabatic::StyleFlags".
const BaseFlags StyleFlags::NoStyle = 0;
const BaseFlags StyleFlags::HV = (1L << 0);
const BaseFlags StyleFlags::VH = (1L << 1);
const BaseFlags StyleFlags::OTH = (1L << 2);
const BaseFlags StyleFlags::Channel = (1L << 3);
const BaseFlags StyleFlags::Hybrid = (1L << 4);
StyleFlags::~StyleFlags ()
{ }
StyleFlags StyleFlags::toFlag ( std::string textFlag )
{
if (textFlag == "HV") return HV;
if (textFlag == "VH") return VH;
if (textFlag == "OTH") return OTH;
if (textFlag == "Channel") return Channel;
if (textFlag == "Hybrid") return Hybrid;
if (textFlag == "NoStyle") return NoStyle;
std::cerr << Error( "StyleFlags::toFlag(): Unknown flag value \"%s\"", textFlag.c_str() ) << std::endl;
return NoStyle;
}
StyleFlags StyleFlags::from ( std::string textFlags )
{
size_t start = 0;
size_t stop = textFlags.find( '|' );
while ( stop != string::npos ) {
*this |= toFlag( textFlags.substr( start, stop-start-1 ));
start = stop + 1;
stop = textFlags.find( '|', start );
}
*this |= toFlag( textFlags.substr( stop+1 ));
return *this;
}
string StyleFlags::asString () const
{
ostringstream s;
if (_flags & (uint64_t)HV) { s << (s.tellp() ? "|" : "") << "HV"; }
if (_flags & (uint64_t)VH) { s << (s.tellp() ? "|" : "") << "VH"; }
if (_flags & (uint64_t)OTH) { s << (s.tellp() ? "|" : "") << "OTH"; }
if (_flags & (uint64_t)Channel) { s << (s.tellp() ? "|" : "") << "Channel"; }
if (_flags & (uint64_t)Hybrid ) { s << (s.tellp() ? "|" : "") << "Hybrid"; }
s << " (0x" << hex << _flags << ")";
return s.str();
}
string StyleFlags::_getTypeName () const
{ return "Anabatic::StyleFlags"; }
string StyleFlags::_getString () const
{ return asString(); }
} // Anabatic namespace.

View File

@ -19,7 +19,6 @@
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/Net.h"
#include "hurricane/Pin.h"
#include "hurricane/RoutingPad.h"
#include "hurricane/Horizontal.h"
#include "hurricane/Vertical.h"
@ -43,7 +42,6 @@ namespace Anabatic {
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::Component;
using Hurricane::Pin;
using Hurricane::Segment;
using Hurricane::Horizontal;
using Hurricane::Vertical;
@ -265,7 +263,7 @@ namespace Anabatic {
}
}
if (rp) {
Vertical* v = dynamic_cast<Vertical*>(rp->_getEntityAs<Segment>());
Vertical* v = dynamic_cast<Vertical*>(rp->_getEntityAsSegment());
if (v) { return true; }
}
}
@ -285,7 +283,7 @@ namespace Anabatic {
}
}
if (rp) {
Horizontal* h = dynamic_cast<Horizontal*>(rp->_getEntityAs<Segment>());
Horizontal* h = dynamic_cast<Horizontal*>(rp->_getEntityAsSegment());
if (h) { return true; }
}
}
@ -300,68 +298,52 @@ namespace Anabatic {
GCell* c2 = v2->getGCell();
// Check from GCell 1
if ( c1->isNorth(c2) and not v1->isNRestricted() ) restricted = false;
else if ( c1->isSouth(c2) and not v1->isSRestricted() ) restricted = false;
else if ( c1->isEast (c2) and not v1->isERestricted() ) restricted = false;
else if ( c1->isWest (c2) and not v1->isWRestricted() ) restricted = false;
// else {
// cerr << Error( "Vertex::isRestricted(): Vertexes/GCells v1 & v2 do not share a side.\n"
// " v1:%s\n"
// " v2:%s"
// , getString(v1).c_str()
// , getString(v2).c_str()
// ) << endl;
// return true;
// }
if (restricted) {
cdebug_log(112,0) << "v1 -> v2 edge is restricted." << endl;
return true;
}
if ( e->isVertical() and (c1->getWidth() < hpitch) ) {
cdebug_log(112,0) << "GCell 1 is too narrow for V edges." << endl;
return true;
}
if ( e->isHorizontal() and (c1->getHeight() < vpitch) ) {
cdebug_log(112,0) << "GCell 1 is too narrow for H edges." << endl;
if ( c1->isNorth(c2) ) {
if ( !v1->isNRestricted() ) restricted = false;
} else if ( c1->isSouth(c2) ) {
if ( !v1->isSRestricted() ) restricted = false;
} else if ( c1->isEast (c2) ) {
if ( !v1->isERestricted() ) restricted = false;
} else if ( c1->isWest (c2) ) {
if ( !v1->isWRestricted() ) restricted = false;
} else {
cerr << Error( "GCells are not side by side." ) << endl;
return true;
}
restricted = true;
// Check from GCell 2
if ( c2->isNorth(c1) and not v2->isNRestricted() ) restricted = false;
else if ( c2->isSouth(c1) and not v2->isSRestricted() ) restricted = false;
else if ( c2->isEast (c1) and not v2->isERestricted() ) restricted = false;
else if ( c2->isWest (c1) and not v2->isWRestricted() ) restricted = false;
// else {
// cerr << Error( "Vertex::isRestricted(): Vertexes/GCells v1 & v2 do not share a side.\n"
// " v1:%s\n"
// " v2:%s"
// , getString(v1).c_str()
// , getString(v2).c_str()
// ) << endl;
// return true;
// }
if (restricted) {
cdebug_log(112,0) << "v2 -> v1 edge is restricted." << endl;
return true;
if ( (c1->getWidth() < hpitch)
||(c1->getHeight() < vpitch)
||(restricted)
) return true;
else {
restricted = true;
// Check from GCell 2
if ( c2->isNorth(c1) ) {
if ( !v2->isNRestricted() ) restricted = false;
} else if ( c2->isSouth(c1) ) {
if ( !v2->isSRestricted() ) restricted = false;
} else if ( c2->isEast (c1) ) {
if ( !v2->isERestricted() ) restricted = false;
} else if ( c2->isWest (c1) ) {
if ( !v2->isWRestricted() ) restricted = false;
} else {
cerr << Error( "GCells are not side by side." ) << endl;
return true;
}
if ( (c2->getWidth() < hpitch)
||(c2->getHeight() < vpitch)
||(restricted)
) return true;
else {
if ((v2->getGCell()->isStrut())){
if (e->isMaxCapacity(net)) {
cdebug_log(112,0) << "Overcapacity:" << e << endl;
return true;
}
else return false;
} else return false;
}
}
if ( e->isVertical() and (c2->getWidth() < hpitch) ) {
cdebug_log(112,0) << "GCell 2 is too narrow for V edges." << endl;
return true;
}
if ( e->isHorizontal() and (c2->getHeight() < vpitch) ) {
cdebug_log(112,0) << "GCell 2 is too narrow for H edges." << endl;
return true;
}
if ( v2->getGCell()->isStrut() and e->isMaxCapacity(net) ) {
cdebug_log(112,0) << "Overcapacity:" << e << endl;
return true;
}
return false;
}
@ -1359,7 +1341,7 @@ namespace Anabatic {
PriorityQueue* PriorityQueue::CompareByDistance::_pqueue = NULL;
bool PriorityQueue::CompareByDistance::operator() ( const Vertex* lhs, const Vertex* rhs ) const
bool PriorityQueue::CompareByDistance::operator() ( const Vertex* lhs, const Vertex* rhs )
{
if (lhs->getDistance() == rhs->getDistance()) {
if (_pqueue and _pqueue->hasAttractor()) {
@ -1459,10 +1441,6 @@ namespace Anabatic {
}
DbU::Unit Dijkstra::getAntennaGateMaxWL () const
{ return _anabatic->getAntennaGateMaxWL(); }
Point Dijkstra::_getPonderedPoint() const
{
vector<RoutingPad*> rps;
@ -1484,48 +1462,6 @@ namespace Anabatic {
}
void Dijkstra::loadFixedGlobal ( Net* net )
{
NetData* netData = _anabatic->getNetData( net );
netData->setGlobalRouted( true );
netData->setGlobalFixed ( true );
for ( Component* component : net->getComponents() ) {
Horizontal* horizontal = dynamic_cast<Horizontal*>( component );
if (horizontal) {
if (not Session::isGLayer(horizontal->getLayer())) {
cerr << Error( "Dijsktra::loadFixedGlobal(): A component of \"%s\" has not a global layer.\n"
" (%s)"
, getString(net->getName()).c_str()
, getString(component).c_str()
) << endl;
continue;
}
GCell* begin = _anabatic->getGCellUnder( horizontal->getSource()->getPosition() );
GCell* end = _anabatic->getGCellUnder( horizontal->getTarget()->getPosition() );
for ( Edge* edge : _anabatic->getEdgesUnderPath(begin,end) )
edge->add( horizontal );
}
Vertical* vertical = dynamic_cast<Vertical*>( component );
if (vertical) {
if (not Session::isGLayer(vertical->getLayer())) {
cerr << Error( "Dijsktra::loadFixedGlobal(): A component of \"%s\" has not a global layer.\n"
" (%s)"
, getString(net->getName()).c_str()
, getString(component).c_str()
) << endl;
continue;
}
GCell* begin = _anabatic->getGCellUnder( vertical->getSource()->getPosition() );
GCell* end = _anabatic->getGCellUnder( vertical->getTarget()->getPosition() );
for ( Edge* edge : _anabatic->getEdgesUnderPath(begin,end,Flags::NorthPath) )
edge->add( vertical );
}
}
}
void Dijkstra::load ( Net* net )
{
_cleanup();
@ -1537,13 +1473,12 @@ namespace Anabatic {
cdebug_log(112,1) << "Dijkstra::load() " << _net << endl;
vector<RoutingPad*> rps;
NetRoutingState* state = NetRoutingExtension::get( _net );
NetRoutingState* state = NetRoutingExtension::get( _net );
if (state) {
if (state->isSelfSym()) {
cdebug_log(112,0) << "Dijkstra::SELF SYMMETRY CASE " << DbU::getValueString(state->getSymAxis()) << endl;
}
state->unsetFlags( NetRoutingState::HasAntenna );
}
for ( Component* component : _net->getComponents() ) {
@ -1553,29 +1488,25 @@ namespace Anabatic {
cdebug_log(112,0) << "@ frp:" << rp << endl;
rps.push_back( rp );
continue;
}
}
if (rps.size() < 2) {
cdebug_tabw(112,-1);
return;
}
if (rps.size() < 2) return;
uint32_t driverCount = 0;
for ( auto rp : rps ) {
if (not _anabatic->getConfiguration()->selectRpComponent(rp))
cerr << Warning( "Dijktra::load(): %s has no components on grid.", getString(rp).c_str() ) << endl;
cdebug_log(112,0) << "@ rp: " << rp << ", getCenter(): " << rp->getBoundingBox().getCenter() << endl;
Point center = rp->getBoundingBox().getCenter();
GCell* gcell = _anabatic->getGCellUnder( center );
Box bb = rp->getBoundingBox();
bool isDriver = false;
Point center = rp->getBoundingBox().getCenter();
GCell* gcell = _anabatic->getGCellUnder( center );
Box bb = rp->getBoundingBox();
cdebug_log(112,0) << bb.getXMin() << " " << bb.getXMax() << endl;
cdebug_log(112,0) << "center X:" << center.getX() << " gcell Xmax:" << gcell->getXMax() << endl;
if (state and state->isSymmetric()) _limitSymSearchArea( rp );
_limitSymSearchArea(rp); // ANALOG
if (not gcell) {
cerr << Error( "Dijkstra::load(): %s\n"
@ -1588,29 +1519,6 @@ namespace Anabatic {
continue;
}
Net* rpNet = NULL;
Plug* plug = dynamic_cast<Plug*>( rp->getPlugOccurrence().getEntity() );
if (plug) {
rpNet = plug->getMasterNet();
if (rpNet->getDirection() & Net::Direction::DirOut) {
cdebug_log(112,0) << "Driver/cell: " << rp << endl;
cdebug_log(112,0) << "masterNet: " << rpNet << endl;
++driverCount;
isDriver = true;
}
} else {
Pin* pin = dynamic_cast<Pin*>( rp->getPlugOccurrence().getEntity() );
if (pin) {
rpNet = pin->getNet();
if (rpNet->getDirection() & Net::Direction::DirIn) {
cdebug_log(112,0) << "Driver/pin: " << rp << endl;
cdebug_log(112,0) << "masterNet: " << rpNet << endl;
++driverCount;
isDriver = true;
}
}
}
_searchArea.merge( gcell->getBoundingBox() ); // TO CHANGE
cdebug_log(112,0) << "| Merged search area: " << _searchArea << ", gcell: " << gcell << endl;
@ -1627,7 +1535,6 @@ namespace Anabatic {
++_connectedsId;
for ( Vertex* vertex : connecteds ) {
vertex->getGCell()->flags().reset( Flags::GoStraight );
vertex->setDistance ( Vertex::unreached );
vertex->setStamp ( _stamp );
vertex->setConnexId ( _connectedsId );
@ -1635,8 +1542,6 @@ namespace Anabatic {
vertex->setDegree ( 0 );
vertex->setRpCount ( 0 );
vertex->setFrom ( NULL );
if (isDriver)
vertex->setDriver( true );
vertex->setFrom2 ( NULL);
vertex->unsetFlags ( Vertex::UseFromFrom2 );
@ -1662,45 +1567,6 @@ namespace Anabatic {
rp->getBodyHook()->attach( vcontact->getBodyHook() );
}
if (driverCount == 0) {
cerr << Error( "Diskstra::load(): Net \"%s\" do not have a driver.\n"
, getString(_net->getName()).c_str()
) << endl;
}
if (driverCount > 1) {
cerr << Error( "Diskstra::load(): Net \"%s\" have multiple drivers (%u).\n"
, getString(_net->getName()).c_str(), driverCount
) << endl;
}
if (state and state->isSymmetric() and not state->isSelfSym() and state->isSymMaster()) {
if (state->isSymVertical()) {
if ( (_searchArea.getXMin() < state->getSymAxis())
and (_searchArea.getXMax() > state->getSymAxis()) ) {
cerr << Error( "Diskstra::load(): For net \"%s\" (paired with \"%s\"),\n"
" Vertical symmetry axis @%s is inside the net area %s."
, getString(_net->getName()).c_str()
, getString(state->getSymNet()->getName()).c_str()
, DbU::getValueString(state->getSymAxis()).c_str()
, getString(_searchArea).c_str()
) << endl;
}
}
if (state->isSymHorizontal()) {
if ( (_searchArea.getYMin() < state->getSymAxis())
and (_searchArea.getYMax() > state->getSymAxis()) ) {
cerr << Error( "Diskstra::load(): For net \"%s\" (paired with \"%s\"),\n"
" Horizontal symmetry axis @%s is inside the net area %s."
, getString(_net->getName()).c_str()
, getString(state->getSymNet()->getName()).c_str()
, DbU::getValueString(state->getSymAxis()).c_str()
, getString(_searchArea).c_str()
) << endl;
}
}
}
_searchArea.inflate( _searchAreaHalo );
cdebug_log(112,0) << "Search halo: " << DbU::getValueString(_searchAreaHalo) << endl;
cdebug_log(112,0) << "Search area: " << _searchArea << endl;
@ -1849,15 +1715,8 @@ namespace Anabatic {
return;
}
Vertex* firstSource = NULL;
VertexSet drivers;
Vertex* firstSource = NULL;
for ( Vertex* vertex : _targets ) {
if (vertex->isDriver()) drivers.insert( vertex );
}
if (drivers.empty()) drivers = _targets;
#if THIS_IS_DISABLED
if (_mode & Mode::Monotonic) {
if (_targets.size() == 2) {
auto ivertex = _targets.begin();
@ -1874,25 +1733,24 @@ namespace Anabatic {
_mode = Mode::Standart;
}
}
#endif
if (not firstSource) {
// Standart routing.
bool hasDevice = false;
for ( Vertex* vertex : drivers ) {
if (vertex->getGCell()->isDevice()) hasDevice = true;
for ( Vertex* ivertex : _targets ) {
if (ivertex->getGCell()->isDevice()) hasDevice = true;
}
Point areaCenter;
if (hasDevice) areaCenter = _getPonderedPoint();
else areaCenter = _searchArea.getCenter();
auto ivertex = drivers.begin();
auto ivertex = _targets.begin();
firstSource = *ivertex++;
DbU::Unit minDistance = areaCenter.manhattanDistance( firstSource->getCenter() );
for ( ; ivertex != drivers.end() ; ++ivertex ) {
for ( ; ivertex != _targets.end() ; ++ivertex ) {
DbU::Unit distance = areaCenter.manhattanDistance( (*ivertex)->getCenter() );
if (distance < minDistance) {
minDistance = distance;
@ -2201,7 +2059,6 @@ namespace Anabatic {
if (_sources.size() < 2) { cdebug_tabw(112,-1); return; }
DbU::Unit gWL = 0;
NetRoutingState* state = NetRoutingExtension::get( _net );
//cerr << "state: " << state << endl;
@ -2232,8 +2089,8 @@ namespace Anabatic {
vector<Edge*> aligneds;
aligneds.push_back( from );
Vertex* target = source->getPredecessor();
Interval constraint = from->getSide();
Vertex* target = source->getPredecessor();
Interval constraint = from->getSide();
source->setFrom( NULL );
cdebug_log(112,0) << "| " << target << endl;
@ -2292,8 +2149,6 @@ namespace Anabatic {
, constraint.getCenter()
, width
);
gWL += segment->getLength();
cdebug_log(112,0) << "| ref: " << segment << endl;
for ( Edge* through : aligneds ) through->add( segment );
if (state) {
@ -2312,8 +2167,6 @@ namespace Anabatic {
, constraint.getCenter()
, width
);
gWL += segment->getLength();
cdebug_log(112,0) << "| ref: " << segment << endl;
for ( Edge* through : aligneds ) through->add( segment );
if (state) {
@ -2330,14 +2183,6 @@ namespace Anabatic {
}
}
if (gWL > getAntennaGateMaxWL()) {
cdebug_log(113,0) << "| \"" << _net->getName() << "\" may have antenna effect, "
<< DbU::getValueString(gWL)
<< endl;
if (state)
state->setFlags( NetRoutingState::HasAntenna );
}
cdebug_tabw(112,-1);
}
@ -2484,66 +2329,51 @@ namespace Anabatic {
void Dijkstra::_createSelfSymSeg ( Segment* segment )
{
cdebug_log(112,1) << "Dijkstra::_createSelfSymSeg(): " << segment << endl;
cdebug_log(112,0) << "void Dijkstra::_createSelfSymSeg ( Segment* segment ): " << _net << ", seg: " << segment << endl;
NetRoutingState* state = NetRoutingExtension::get( _net );
if (state and segment) {
//cdebug_log(112,0) << "state: " << state << endl;
if ((state != NULL)&&(segment!=NULL)){
Horizontal* h = dynamic_cast<Horizontal*>(segment);
Vertical* v = dynamic_cast<Vertical *>(segment);
Point sp;
Point tp;
DbU::Unit axis;
Component* sourceContact = segment->getSource();
Component* targetContact = segment->getTarget();
cdebug_log(112,0) << "source: " << sourceContact << endl;
cdebug_log(112,0) << "target: " << targetContact << endl;
cdebug_log(112,0) << "sym axis: " << DbU::getValueString(state->getSymAxis()) << endl;
if (h) {
if (state->isSymHorizontal()) {
cdebug_log(112,0) << "Horizontal + Horizontal symmetry." << endl;
sp = Point( sourceContact->getX(), state->getSymValue(sourceContact->getY()) );
tp = Point( targetContact->getX(), state->getSymValue(targetContact->getY()) );
axis = state->getSymValue( segment->getY() );
} else if (state->isSymVertical()) {
cdebug_log(112,0) << "Horizontal + Vertical symmetry." << endl;
sp = Point( state->getSymValue(targetContact->getX()), targetContact->getY() );
tp = Point( state->getSymValue(sourceContact->getX()), sourceContact->getY() );
Vertical* v = dynamic_cast<Vertical*>(segment);
Point sp, tp;
DbU::Unit axis;
Component* sourceContact = segment->getSource();
Component* targetContact = segment->getTarget();
if (h){
if (state->isSymHorizontal()){
cdebug_log(112,0) << "H case Horizontal" << endl;
sp = Point(sourceContact->getX(), state->getSymValue(sourceContact->getY()) );
tp = Point(targetContact->getX(), state->getSymValue(targetContact->getY()) );
axis = state->getSymValue(segment->getY());
} else if (state->isSymVertical()){
cdebug_log(112,0) << "H case Vertical" << endl;
sp = Point( state->getSymValue(targetContact->getX()), targetContact->getY() );
tp = Point( state->getSymValue(sourceContact->getX()), sourceContact->getY() );
axis = segment->getY();
} else {
cdebug_log(112,0) << "Dijkstra::_materialize(): Horizontal + Unknown symmetry. " << endl;
cdebug_tabw(112,-1);
cdebug_log(112,0) << "Dijkstra::_materialize(): Something is wrong here. " << endl;
return;
}
cdebug_log(112,0) << "sp: " << sp << endl;
cdebug_log(112,0) << "tp: " << tp << endl;
//cerr << "sp: " << sp << endl;
//cerr << "tp: " << tp << endl;
GCell* sgcell = _anabatic->getGCellUnder( sp );
GCell* tgcell = _anabatic->getGCellUnder( tp );
cdebug_log(112,0) << "GCell: " << sgcell << endl;
cdebug_log(112,0) << "GCell: " << tgcell << endl;
//cerr << "Gcell: " << sgcell << endl;
//cerr << "Gcell: " << tgcell << endl;
Vertex* svertex = sgcell->getObserver<Vertex>(GCell::Observable::Vertex);
Vertex* tvertex = tgcell->getObserver<Vertex>(GCell::Observable::Vertex);
Contact* sourceSym = NULL;
Contact* targetSym = NULL;
if (state->isSelfSym()) {
cdebug_log(112,0) << "Symmetrical to myself (isSelfSym)." << endl;
if (state->isSelfSym()){
cdebug_log(112,0) << "isSelfSym" << endl;
sourceSym = svertex->getGContact( _net );
targetSym = tvertex->getGContact( _net );
} else if (state->isSymMaster()){
cdebug_log(112,0) << "Symmetrical to (isSymPair): " << state->getSymNet() << endl;
cdebug_log(112,0) << "isSymPair: " << state->getSymNet() << endl;
sourceSym = svertex->getGContact( state->getSymNet() );
targetSym = tvertex->getGContact( state->getSymNet() );
} else {
cdebug_log(112,0) << "Dijkstra::_materialize(): Unknown Net pairing symmetry. " << endl;
cdebug_tabw(112,-1);
cdebug_log(112,0) << "Dijkstra::_materialize(): Something is wrong with the symmetry. " << endl;
return;
}
@ -2555,7 +2385,7 @@ namespace Anabatic {
, axis
, state->getWPitch()*Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL2"))
);
cdebug_log(112,0) << "| dup:" << segment2 << endl;
cdebug_log(112,0) << "|| " << segment2 << endl;
} else if (v) {
if (state->isSymVertical()){
//cerr << "V case Vertical" << endl;
@ -2569,7 +2399,6 @@ namespace Anabatic {
axis = segment->getX();
} else {
cdebug_log(112,0) << "Dijkstra::_materialize(): Something is wrong here. " << endl;
cdebug_tabw(112,-1);
return;
}
GCell* sgcell = _anabatic->getGCellUnder( sp );
@ -2586,7 +2415,6 @@ namespace Anabatic {
targetSym = tvertex->getGContact( state->getSymNet() );
} else {
cdebug_log(112,0) << "Dijkstra::_materialize(): Something is wrong with the symmetry. " << endl;
cdebug_tabw(112,-1);
return;
}
@ -2601,7 +2429,6 @@ namespace Anabatic {
cdebug_log(112,0) << "|| " << segment2 << endl;
}
}
cdebug_tabw(112,-1);
}
@ -2873,8 +2700,8 @@ namespace Anabatic {
{
cdebug_log(112,0) << "void Dijkstra::_setSourcesGRAData() : " << seed << endl;
GCell* gseed = seed->getGCell();
Horizontal* h = dynamic_cast<Horizontal*>(rp->_getEntityAs<Segment>());
Vertical* v = dynamic_cast<Vertical*> (rp->_getEntityAs<Segment>());
Horizontal* h = dynamic_cast<Horizontal*>(rp->_getEntityAsSegment());
Vertical* v = dynamic_cast<Vertical*> (rp->_getEntityAsSegment());
if (h) {
cdebug_log(112,0) << "case H " << endl;
seed->unsetFlags(Vertex::iHorizontal);

View File

@ -29,31 +29,16 @@ namespace {
using namespace std;
using namespace Hurricane;
using Anabatic::NetData;
using Anabatic::AnabaticEngine;
class SortSegmentByLength {
public:
inline SortSegmentByLength ( AnabaticEngine* );
inline bool operator() ( const Segment*, const Segment* );
private:
AnabaticEngine* _anabatic;
inline bool operator() ( const Segment*, const Segment* );
};
inline SortSegmentByLength::SortSegmentByLength ( AnabaticEngine* anabatic )
: _anabatic(anabatic)
{ }
inline bool SortSegmentByLength::operator() ( const Segment* lhs, const Segment* rhs )
{
NetData* lhsNData = _anabatic->getNetData( lhs->getNet() );
NetData* rhsNData = _anabatic->getNetData( rhs->getNet() );
if (lhsNData->isGlobalFixed() and not rhsNData->isGlobalFixed()) return true;
if (rhsNData->isGlobalFixed() and not lhsNData->isGlobalFixed()) return false;
DbU::Unit delta = rhs->getLength() - lhs->getLength();
if (delta > 0) return true;
if (delta < 0) return false;
@ -370,16 +355,16 @@ namespace Anabatic {
size_t Edge::ripup ()
{
AnabaticEngine* anabatic = getAnabatic();
size_t netCount = 0;
AnabaticEngine* anabatic = getAnabatic();
DbU::Unit globalThreshold = Session::getSliceHeight()*3;
size_t netCount = 0;
sort( _segments.begin(), _segments.end(), SortSegmentByLength(anabatic) );
sort( _segments.begin(), _segments.end(), SortSegmentByLength() );
if (Session::getRoutingGauge()->isTwoMetals()) {
for ( size_t i=0 ; i<_segments.size() ; ) {
if (not isEnding(_segments[i])) {
NetData* netData = anabatic->getNetData( _segments[i]->getNet() );
if (netData->isGlobalFixed ()) break;
if (netData->isGlobalRouted()) ++netCount;
anabatic->ripup( _segments[i], Flags::Propagate );
continue;
@ -390,12 +375,10 @@ namespace Anabatic {
size_t truncate = (size_t)( (getCapacity()*2) / 3 );
while ( _segments.size() > truncate ) {
NetData* netData = anabatic->getNetData( _segments[truncate]->getNet() );
if (netData->isGlobalFixed ()) break;
if (netData->isGlobalRouted()) ++netCount;
anabatic->ripup( _segments[truncate], Flags::Propagate );
}
// DbU::Unit globalThreshold = Session::getSliceHeight()*3;
// for ( size_t i=0 ; i<_segments.size() ; ) {
// if (_segments[i]->getLength() >= globalThreshold) {
// NetData* netData = anabatic->getNetData( _segments[i]->getNet() );

View File

@ -55,7 +55,7 @@ namespace {
private:
class AxisCompare {
public:
bool operator() ( const Axis* lhs, const Axis* rhs ) const;
bool operator() ( const Axis* lhs, const Axis* rhs );
};
class AxisMatch : public unary_function<Axis*,bool> {
@ -155,7 +155,7 @@ namespace {
}
inline bool UsedFragments::AxisCompare::operator() ( const Axis* lhs, const Axis* rhs ) const
inline bool UsedFragments::AxisCompare::operator() ( const Axis* lhs, const Axis* rhs )
{
if (lhs->getAxis () < rhs->getAxis ()) return true;
return false;
@ -259,7 +259,7 @@ namespace Anabatic {
{ }
bool GCell::CompareByDensity::operator() ( GCell* lhs, GCell* rhs ) const
bool GCell::CompareByDensity::operator() ( GCell* lhs, GCell* rhs )
{
float difference = lhs->getDensity(_depth) - rhs->getDensity(_depth);
if (difference != 0.0) return (difference > 0.0);
@ -285,7 +285,7 @@ namespace Anabatic {
: Super(anabatic->getCell())
, _observable ()
, _anabatic (anabatic)
, _flags (Flags::Invalidated)
, _flags (Flags::HChannelGCell|Flags::Invalidated)
, _westEdges ()
, _eastEdges ()
, _southEdges ()
@ -298,8 +298,6 @@ namespace Anabatic {
, _contacts ()
, _depth (Session::getRoutingGauge()->getDepth())
, _pinDepth (0)
, _satProcessed (0)
, _rpCount (0)
, _blockages (new DbU::Unit [_depth])
, _cDensity (0.0)
, _densities (new float [_depth])
@ -307,7 +305,6 @@ namespace Anabatic {
, _fragmentations(new float [_depth])
, _globalsCount (new float [_depth])
, _key (this,1)
, _lastClonedKey (NULL)
{
if (not _matrixHSide) {
_matrixVSide = Session::getSliceHeight();
@ -477,26 +474,6 @@ namespace Anabatic {
}
bool GCell::hasNet ( const Net* net ) const
{
if (hasGContact(net)) return true;
for ( Edge* edge : _eastEdges ) {
for ( Segment* segment : edge->getSegments() ) {
if (segment->getNet() == net) return true;
}
}
for ( Edge* edge : _northEdges ) {
for ( Segment* segment : edge->getSegments() ) {
if (segment->getNet() == net) return true;
}
}
return false;
}
Contact* GCell::hasGContact ( const Contact* owned ) const
{
for ( Contact* contact : _gcontacts ) {
@ -529,22 +506,6 @@ namespace Anabatic {
}
Segment* GCell::hasGoThrough ( Net* net ) const
{
for ( Edge* edge : _eastEdges ) {
for ( Segment* segment : edge->getSegments() ) {
if (segment->getNet() == net) return segment;
}
}
for ( Edge* edge : _northEdges ) {
for ( Segment* segment : edge->getSegments() ) {
if (segment->getNet() == net) return segment;
}
}
return NULL;
}
Edge* GCell::getEdgeTo ( GCell* neighbor, Flags sideHint ) const
{
for ( Edge* edge : getEdges(sideHint) ) {
@ -1254,7 +1215,7 @@ namespace Anabatic {
int GCell::getCapacity ( size_t depth ) const
{
const vector<Edge*>* edges = NULL;
if (isHorizontalPlane(depth)) edges = (_eastEdges .empty()) ? &_westEdges : &_eastEdges;
if (isHorizontalPlane(depth)) edges = (_eastEdges .empty()) ? &_westEdges : &_westEdges;
else edges = (_northEdges.empty()) ? &_southEdges : &_northEdges;
int capacity = 0;
@ -1343,26 +1304,6 @@ namespace Anabatic {
}
void GCell::postGlobalAnnotate ()
{
if (isInvalidated()) updateDensity();
for ( size_t depth=0 ; depth<_depth ; ++depth ) {
RoutingLayerGauge* rlg = Session::getLayerGauge( depth );
if (rlg->getType() & Constant::PinOnly) continue;
if (_densities[depth] >= 0.9) {
if (depth+2 < _depth) {
Edge* edge = (rlg->getDirection() == Constant::Vertical) ? getNorthEdge()
: getEastEdge();
if (edge) {
edge->reserveCapacity( 2 );
}
}
}
}
}
void GCell::addBlockage ( size_t depth, DbU::Unit length )
{
if (depth >= _depth) return;
@ -1370,7 +1311,7 @@ namespace Anabatic {
_blockages[depth] += length;
_flags |= Flags::Invalidated;
cdebug_log(149,0) << "GCell::addBlockage() " << this << " "
cdebug_log(149,0) << "GCell:addBlockage() " << this << " "
<< depth << ":" << DbU::getValueString(_blockages[depth]) << endl;
}
@ -1391,7 +1332,6 @@ namespace Anabatic {
if (found) {
cdebug_log(149,0) << "remove " << ac << " from " << this << endl;
_contacts.pop_back();
_flags |= Flags::Invalidated;
} else {
cerr << Bug("%p:%s do not belong to %s."
,ac->base(),getString(ac).c_str(),_getString().c_str()) << endl;
@ -1405,17 +1345,11 @@ namespace Anabatic {
size_t begin = 0;
for ( ; begin < end ; begin++ ) {
if (not _hsegments[begin])
cerr << Bug( "GCell::removeHSegment(): In %s, NULL segment at [%u/%u]."
, _getString().c_str(), begin, _hsegments.size() ) << endl;
if (_hsegments[begin] == segment) std::swap( _hsegments[begin], _hsegments[--end] );
cdebug_log(9000,0) << "GCell::removeHSegment() " << this << endl;
cdebug_log(9000,0) << " " << segment << endl;
}
if (_hsegments.size() == end) {
cerr << Bug( "GCell::removeHSegment(): %s do not go through %s."
cerr << Bug( "%s do not go through %s."
, getString(segment).c_str(), _getString().c_str() ) << endl;
return;
}
@ -1425,7 +1359,6 @@ namespace Anabatic {
, _getString().c_str(), getString(segment).c_str() ) << endl;
_hsegments.erase( _hsegments.begin() + end, _hsegments.end() );
_flags |= Flags::Invalidated;
}
@ -1451,7 +1384,6 @@ namespace Anabatic {
, getString(segment).c_str() ) << endl;
_vsegments.erase( _vsegments.begin() + end, _vsegments.end() );
_flags |= Flags::Invalidated;
}
@ -1465,6 +1397,11 @@ namespace Anabatic {
_flags.reset( Flags::Saturated );
for ( size_t i=0 ; i<_vsegments.size() ; i++ ) {
if ( _vsegments[i] == NULL )
cerr << "NULL Autosegment at index " << i << endl;
}
sort( _hsegments.begin(), _hsegments.end(), AutoSegment::CompareByDepthLength() );
sort( _vsegments.begin(), _vsegments.end(), AutoSegment::CompareByDepthLength() );
@ -1551,26 +1488,7 @@ namespace Anabatic {
}
// Add the blockages.
if (isStdCellRow() or isChannelRow()) {
flags().reset( Flags::GoStraight );
} else {
int contiguousNonSaturated = 0;
for ( size_t i=0 ; i<_depth ; i++ ) {
uLengths2[i] += _blockages[i];
if (Session::getLayerGauge(i)->getType() & Constant::PinOnly)
continue;
if (Session::getLayerGauge(i)->getType() & Constant::PowerSupply)
continue;
if ((float)(_blockages[i] * Session::getPitch(i)) > 0.60*(float)(width*height))
contiguousNonSaturated = 0;
else
contiguousNonSaturated++;
}
if (contiguousNonSaturated < 2) {
flags() |= Flags::GoStraight;
//cerr << "| Set GoStraight on " << this << endl;
}
}
for ( size_t i=0 ; i<_depth ; i++ ) uLengths2[i] += _blockages[i];
// Compute the number of non pass-through tracks.
if (not processeds.empty()) {
@ -1580,8 +1498,7 @@ namespace Anabatic {
size_t depth = Session::getRoutingGauge()->getLayerDepth(layer);
size_t count = 0;
for ( ; isegment != processeds.end(); ++isegment ) {
//_feedthroughs[depth] += ((*isegment)->isGlobal()) ? 0.50 : 0.33;
_feedthroughs[depth] += 0.50;
_feedthroughs[depth] += ((*isegment)->isGlobal()) ? 0.50 : 0.33;
localCounts [depth] += 1.0;
if ( (*isegment)->isGlobal() ) _globalsCount[depth] += 1.0;
@ -1819,7 +1736,7 @@ namespace Anabatic {
bool GCell::stepNetDesaturate ( size_t depth, set<Net*>& globalNets, GCell::Set& invalidateds )
{
cdebug_log(149,0) << "GCell::stepNetDesaturate() depth:" << depth << endl;
cdebug_log(9000,0) << "Deter| GCell::stepNetDesaturate() depth:" << depth << endl;
cdebug_log(9000,0) << "Deter| " << this << endl;
updateDensity();
@ -1841,7 +1758,7 @@ namespace Anabatic {
if (segmentDepth < depth) continue;
if (segmentDepth > depth) break;
cdebug_log(149,0) << "Move up " << (*isegment) << endl;
cdebug_log(9000,0) << "Deter| Move up " << (*isegment) << endl;
if (getAnabatic()->moveUpNetTrunk(*isegment,globalNets,invalidateds))
return true;
@ -1873,7 +1790,6 @@ namespace Anabatic {
string s = Super::_getString();
s.insert( s.size()-1, " "+getString(getBoundingBox()) );
s.insert( s.size()-1, " "+getString(_flags) );
s.insert( s.size()-1, " "+getString(_rpCount) );
/* string s = "<GCell at(" + DbU::getValueString(getXMin())
+ "-" + DbU::getValueString(getYMin())
+ "-" + DbU::getValueString(getXMax())
@ -1906,7 +1822,7 @@ namespace Anabatic {
ostringstream s;
const Layer* layer = rg->getRoutingLayer(depth)->getBlockageLayer();
s << "_blockages[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
record->add( DbU::getValueSlot( s.str(), &_blockages[depth] ) );
record->add( getSlot ( s.str(), &_blockages[depth] ) );
}
for ( size_t depth=0 ; depth<_depth ; ++depth ) {
@ -1915,13 +1831,6 @@ namespace Anabatic {
s << "_densities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
record->add( getSlot ( s.str(), &_densities[depth] ) );
}
for ( size_t depth=0 ; depth<_depth ; ++depth ) {
ostringstream s;
const Layer* layer = rg->getRoutingLayer(depth);
s << "_feedthroughs[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
record->add( getSlot ( s.str(), &_feedthroughs[depth] ) );
}
return record;
}

View File

@ -31,288 +31,11 @@
#include "hurricane/Horizontal.h"
#include "hurricane/Cell.h"
#include "crlcore/RoutingGauge.h"
#include "anabatic/AutoContactTerminal.h"
#include "anabatic/AutoContact.h"
#include "anabatic/AutoSegment.h"
#include "anabatic/AnabaticEngine.h"
namespace {
using namespace std;
using namespace CRL;
using namespace Hurricane;
using namespace Anabatic;
class SortRpByX {
public:
inline SortRpByX ();
inline bool operator() ( RoutingPad* rp1, RoutingPad* rp2 );
};
inline SortRpByX::SortRpByX ()
{ }
inline bool SortRpByX::operator() ( RoutingPad* rp1, RoutingPad* rp2 )
{
DbU::Unit x1 = rp1->getCenter().getX();
DbU::Unit x2 = rp2->getCenter().getX();
if (x1 == x2) return false;
return (x1 < x2);
}
// -----------------------------------------------------------------
// Class : "RpsInRow".
class RpsInRow {
public:
class Compare {
public:
bool operator() ( const RpsInRow* lhs, const RpsInRow* rhs ) const;
};
public:
inline RpsInRow ( RoutingPad*, AnabaticEngine* );
inline const vector<RoutingPad*>& getRps () const;
inline size_t getSouth () const;
inline size_t getNorth () const;
inline const Interval& getRpsHSpan () const;
inline const Interval& getRpsVSpan () const;
void slacken ();
private:
void _findTopology ();
inline void _merge ( RoutingPad* );
private:
AnabaticEngine* _anabatic;
vector<RoutingPad*> _rps;
size_t _north;
size_t _south;
Interval _hSpan;
Interval _vSpan;
};
inline RpsInRow::RpsInRow ( RoutingPad* seed, AnabaticEngine* anabatic )
: _anabatic(anabatic)
, _rps ()
, _north (0)
, _south (0)
, _hSpan ()
, _vSpan ( false )
{
_rps.push_back( seed );
_findTopology();
}
inline const vector<RoutingPad*>& RpsInRow::getRps () const { return _rps; }
inline size_t RpsInRow::getSouth () const { return _south; }
inline size_t RpsInRow::getNorth () const { return _north; }
inline const Interval& RpsInRow::getRpsHSpan () const { return _hSpan; }
inline const Interval& RpsInRow::getRpsVSpan () const { return _vSpan; }
bool RpsInRow::Compare::operator() ( const RpsInRow* lhs, const RpsInRow* rhs ) const
{
if ( (lhs->_rps.size() == 2) and (rhs->_rps.size() != 2) ) return true;
if ( (lhs->_rps.size() != 2) and (rhs->_rps.size() == 2) ) return false;
if ( lhs->_rps.size() != rhs->_rps.size() ) return lhs->_rps.size() < rhs->_rps.size();
size_t lhsNs = lhs->_south + lhs->_north;
size_t rhsNs = rhs->_south + rhs->_north;
if (lhsNs != rhsNs) return lhsNs < rhsNs;
if (lhs->_vSpan != rhs->_vSpan) return lhs->_vSpan.getSize() < rhs->_vSpan.getSize();
if (lhs->_hSpan != rhs->_hSpan) return lhs->_hSpan.getSize() < rhs->_hSpan.getSize();
return lhs->_rps[0]->getId() < rhs->_rps[0]->getId();
}
inline void RpsInRow::_merge ( RoutingPad* rp )
{
if (rp != _rps[0]) _rps.push_back( rp );
Box bb ( _rps.back()->getBoundingBox() );
_hSpan.merge( bb.getCenter().getX() );
_vSpan.intersection( bb.getYMin(), bb.getYMax() );
}
void RpsInRow::_findTopology ()
{
cdebug_log(146,1) << "RpsInRow::findTopology() - " << _rps[0] << endl;
_merge( _rps[0] );
AutoSegmentStack stack;
for ( Component* component : _rps[0]->getSlaveComponents() ) {
cdebug_log(146,0) << "slave component: " << component << endl;
AutoContact* rpContact = Session::lookup( dynamic_cast<Contact*>(component) );
if (rpContact) {
cdebug_log(146,0) << "Start rp: " << rpContact << endl;
for ( AutoSegment* segment : rpContact->getAutoSegments() ) {
cdebug_log(146,0) << "Examining: " << segment << endl;
AutoContact* target = segment->getOppositeAnchor(rpContact);
if (target) {
if (segment->isHorizontal()) {
stack.push( target, segment );
} else {
if (segment->isLocal()) {
stack.push( target, segment );
} else {
if (segment->getAutoSource() == rpContact) ++_north;
else ++_south;
}
}
}
}
// Find Rps in same horizontal GCell range.
cdebug_log(146,0) << "Find Rps in same horizontal GCell range" << endl;
while ( not stack.isEmpty() ) {
AutoSegment* from = stack.getAutoSegment();
AutoContact* contact = stack.getAutoContact();
stack.pop();
for ( AutoSegment* segment : contact->getAutoSegments() ) {
if (segment == from) continue;
if (segment->isVertical() and not segment->isLocal()) {
if (segment->getAutoSource() == contact) ++_north;
else ++_south;
continue;
}
AutoContact* target = segment->getOppositeAnchor( contact );
AutoContactTerminal* terminal = dynamic_cast<AutoContactTerminal*>( target );
if (terminal) {
_merge( terminal->getRoutingPad() );
}
stack.push( target, segment );
}
}
}
}
sort( _rps.begin(), _rps.end(), SortRpByX() );
cdebug_log(146,0) << "findHAlignedsRps() - Exit" << endl;
cdebug_tabw(146,-1);
}
void RpsInRow::slacken ()
{
cdebug_log(149,1) << "RpsInRow::slacken()" << endl;
for ( RoutingPad* rp : _rps ) {
cdebug_log(149,0) << "Slacken from: " << rp << endl;
if (rp->getLayer()) {
if (_anabatic->getConfiguration()->getLayerDepth(rp->getLayer()) == 1) {
cdebug_log(149,0) << "In METAL2, skiping" << endl;
continue;
}
}
for ( Component* component : rp->getSlaveComponents() ) {
AutoContact* rpContact = Session::lookup( dynamic_cast<Contact*>(component) );
if (rpContact) {
cdebug_log(149,0) << "+ " << rpContact << endl;
for ( AutoSegment* segment : rpContact->getAutoSegments() ) {
cdebug_log(149,0) << "| " << segment << endl;
if (segment->isVertical()) {
if (segment->getDepth() == 1) {
cdebug_log(149,0) << "| Slacken: " << segment << endl;
segment->changeDepth( 2, Flags::NoFlags );
cdebug_log(149,0) << "| After Slacken: " << segment << endl;
}
} else {
segment->makeDogleg( rpContact->getGCell() );
cdebug_log(149,0) << "| Make dogleg: " << segment << endl;
}
}
}
}
}
cdebug_tabw(149,-1);
}
// -----------------------------------------------------------------
// Class : "GCellRps".
class GCellRps {
public:
class Compare {
public:
bool operator() ( const GCellRps* lhs, const GCellRps* rhs ) const;
};
public:
GCellRps ( GCell*, AnabaticEngine* );
~GCellRps ();
inline GCell* getGCell () const;
inline size_t add ( RoutingPad* );
inline void consolidate ();
inline RpsInRow* getRpsInRow ( size_t i );
inline const vector<RpsInRow*>& getRpsInRows () const;
private:
AnabaticEngine* _anabatic;
GCell* _gcell;
vector<RpsInRow*> _rpsInRows;
};
GCellRps::GCellRps ( GCell* gcell, AnabaticEngine* anabatic )
: _anabatic (anabatic)
, _gcell (gcell)
, _rpsInRows()
{ }
GCellRps::~GCellRps ()
{
for ( RpsInRow* elem : _rpsInRows ) delete elem;
}
inline GCell* GCellRps::getGCell () const { return _gcell; }
inline size_t GCellRps::add ( RoutingPad* rp )
{
_rpsInRows.push_back( new RpsInRow(rp,_anabatic) );
return _rpsInRows.size() - 1;
}
inline void GCellRps::consolidate ()
{
sort( _rpsInRows.begin(), _rpsInRows.end(), RpsInRow::Compare() );
}
inline RpsInRow* GCellRps::getRpsInRow ( size_t i ) { return _rpsInRows[i]; }
inline const vector<RpsInRow*>& GCellRps::getRpsInRows () const { return _rpsInRows; }
bool GCellRps::Compare::operator() ( const GCellRps* lhs, const GCellRps* rhs ) const
{ return lhs->getGCell()->getId() < rhs->getGCell()->getId(); }
} // Anonymous namespace.
namespace Anabatic {
using Hurricane::DebugSession;
@ -336,58 +59,9 @@ namespace Anabatic {
cmess1 << " o Desaturate layer "
<< Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << endl;
cdebug_log(149,0) << "Session::getSaturateRatio()=" << Session::getSaturateRatio() << endl;
GCellKeyQueue queue;
GCell::Set invalidateds;
for ( GCell* gcell : getGCells() ) queue.push( gcell->cloneKey(depth) );
bool optimized = true;
bool finished = false;
while ( optimized ) {
Session::revalidate ();
optimized = false;
while ( not queue.empty() ) {
GCell::Key* topKey = queue.top();
GCell* gcell = const_cast<GCell*>( topKey->getGCell() );
queue.pop();
if (topKey->isActive()) {
cdebug_log(149,0) << "_desaturate: [" << depth << "]:"
<< gcell->getDensity(depth) << " " << gcell << endl;
if (not gcell->isSaturated(depth)) {
cdebug_log(149,0) << "STOP desaturated: " << gcell << endl;
finished = true;
} else {
if (finished) {
cparanoid << "[ERROR] Still saturated: " << gcell << endl;
}
}
if (not finished) {
optimized = gcell->stepNetDesaturate( depth, globalNets, invalidateds );
gcell->setSatProcessed( depth );
if (optimized) {
for ( GCell* gcell : invalidateds ) {
if (not gcell->isSatProcessed(depth))
queue.push( gcell->cloneKey(depth) );
}
invalidateds.clear();
}
}
}
delete topKey;
}
}
#if OLD_QUEUE_DISABLED
GCellDensitySet queue ( depth, getGCells() );
GCell::Set invalidateds;
GCell::Set invalidateds;
bool optimized = true;
while ( optimized ) {
@ -399,7 +73,7 @@ namespace Anabatic {
size_t i = 0;
for ( ; igcell!=queue.getGCells().end() ; ++igcell, ++i ) {
cdebug_log(149,0) << "_desaturate: [" << depth << "]:"
<< (*igcell)->getDensity(depth) << " " << *igcell << endl;
<< (*igcell)->getDensity(depth) << " " << *igcell << endl;
if (not (*igcell)->isSaturated(depth)) {
cdebug_log(149,0) << "STOP desaturated: @" << i << " " << *igcell << endl;
@ -421,7 +95,6 @@ namespace Anabatic {
}
}
}
#endif
}
@ -573,23 +246,22 @@ namespace Anabatic {
for ( AutoSegment* horizontal : horizontals ) {
vector<AutoSegment*> collapseds;
vector< tuple<AutoSegment*,Flags> > perpandicularsDatas;
//vector<AutoSegment*> northBounds;
//vector<AutoSegment*> southBounds;
vector<AutoSegment*> perpandiculars;
vector<AutoSegment*> northBounds;
vector<AutoSegment*> southBounds;
DbU::Unit leftBound;
DbU::Unit rightBound;
//bool hasNorth = false;
//bool hasSouth = false;
bool hasNorth = false;
bool hasSouth = false;
AutoSegment::getTopologicalInfos( horizontal
, collapseds
, perpandicularsDatas
, perpandiculars
, leftBound
, rightBound
);
for ( auto perpandicularDatas : perpandicularsDatas ) {
AutoSegment* perpandicular = std::get<0>( perpandicularDatas );
for ( AutoSegment* perpandicular : perpandiculars ) {
if (Session::getLayerDepth(perpandicular->getLayer()) > 2) continue;
bool hasGlobal = false;
@ -759,7 +431,7 @@ namespace Anabatic {
if (not segment->isStrongTerminal()) locals.push_back( segment );
continue;
}
if ( (segment->getAnchoredLength() < 3*Session::getSliceHeight()) and (segment != seed) ) {
if ( (segment->getLength() < 3*Session::getSliceHeight()) and (segment != seed) ) {
locals.push_back( segment );
continue;
}
@ -835,7 +507,7 @@ namespace Anabatic {
cmess1 << " o Balance Global Density "
<< Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << endl;
GCellDensitySet queue ( depth, getGCells() );
GCellDensitySet queue ( depth, getGCells()) );
GCell::Set invalidateds;
bool optimized = true;
@ -927,8 +599,6 @@ namespace Anabatic {
void AnabaticEngine::layerAssign ( uint32_t method )
{
//DebugSession::open( 145, 150 );
cdebug_log(9000,0) << "Deter| Layer Assignment" << endl;
set<Net*> globalNets;
@ -975,54 +645,6 @@ namespace Anabatic {
Session::setAnabaticFlags( Flags::WarnOnGCellOverload );
}
set<GCellRps*,GCellRps::Compare> gcellRpss;
for ( GCell* gcell : getGCells() ) {
set<RoutingPad*,Entity::CompareById> rps;
const vector<AutoContact*> contacts = gcell->getContacts();
for ( AutoContact* contact : contacts ) {
AutoContactTerminal* terminal = dynamic_cast<AutoContactTerminal*>( contact );
if (terminal) {
rps.insert( terminal->getRoutingPad() );
}
}
if (rps.size() > getConfiguration()->getSaturateRp()) {
GCellRps* gcellRps = new GCellRps ( gcell, this );
gcellRpss.insert( gcellRps );
for ( RoutingPad* rp : rps ) gcellRps->add( rp );
}
}
for ( GCellRps* gcellRps : gcellRpss ) {
gcellRps->consolidate();
const vector<RpsInRow*>& rpsInRows = gcellRps->getRpsInRows();
cdebug_log(149,0) << gcellRps->getGCell() << " has " << rpsInRows.size() << " terminals." << endl;
size_t count = 0;
for ( RpsInRow* rpsInRow : rpsInRows ) {
cdebug_log(149,0) << "North:" << rpsInRow->getNorth() << " South:"
<< rpsInRow->getSouth() << " net:"
<< rpsInRow->getRps()[0]->getNet()->getName() << endl;
cdebug_log(149,0) << "H-Span:" << rpsInRow->getRpsHSpan() << " V-Span:" << rpsInRow->getRpsVSpan() << endl;
for ( RoutingPad* arp : rpsInRow->getRps() ) {
cdebug_log(149,0) << "| " << arp << endl;
}
if (++count < 2) rpsInRow->slacken();
}
for ( AutoSegment* segment : gcellRps->getGCell()->getHSegments() ) {
if (segment->canPivotUp()) {
cdebug_log(149,0) << "Move up horizontal: " << segment << endl;
segment->moveUp( Flags::Propagate );
}
}
delete gcellRps;
}
checkGCellDensities();
Session::close();
@ -1034,8 +656,6 @@ namespace Anabatic {
// cmess2 << " - Global segments : " << global << endl;
// cmess2 << " - Ratio : "
// << ((float)global/(float)total)*100.0 << "%." << endl;
//DebugSession::close();
}

View File

@ -37,7 +37,6 @@
#include "hurricane/Instance.h"
#include "hurricane/Vertical.h"
#include "hurricane/Horizontal.h"
#include "hurricane/Rectilinear.h"
#include "crlcore/AllianceFramework.h"
#include "crlcore/RoutingGauge.h"
#include "anabatic/AutoContactTerminal.h"
@ -221,53 +220,30 @@ namespace Anabatic {
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::Bug;
using Hurricane::Rectilinear;
// -------------------------------------------------------------------
// Class : "NetBuilder".
void NetBuilder::getPositions ( Component* anchor, Point& source, Point& target )
{
Segment* segment = dynamic_cast<Segment*>( anchor );
Segment* segment = dynamic_cast<Segment*>( anchor );
if (segment) {
source = segment->getSourcePosition();
target = segment->getTargetPosition();
} else {
RoutingPad* rp = dynamic_cast<RoutingPad*>( anchor );
if (rp) {
source = rp->getSourcePosition();
target = rp->getTargetPosition();
} else {
source = anchor->getPosition();
target = anchor->getPosition();
return;
}
return;
}
if (source == target) return;
if (source.getX() > target.getX()) swap( source, target );
if (source.getY() > target.getY()) swap( source, target );
if (not Session::getRoutingGauge()->isSymbolic()) {
size_t rpDepth = Session::getLayerDepth( anchor->getLayer() );
Flags direction = Session::getDirection ( rpDepth );
DbU::Unit wwidth = Session::getWireWidth (rpDepth) / 2;
cdebug_log(145,0) << "Not a symbolic gauge, shrink positions of " << DbU::getValueString(wwidth) << endl;
if (rpDepth == 0) return;
if (direction.contains(Flags::Horizontal)) {
cdebug_log(145,0) << "H shrink" << endl;
source.translate( wwidth, 0 );
target.translate( -wwidth, 0 );
} else {
cdebug_log(145,0) << "V shrink" << endl;
source.translate( 0, wwidth );
target.translate( 0, -wwidth );
}
} else {
cdebug_log(145,0) << "Symbolic gauge, no shrink" << endl;
RoutingPad* rp = dynamic_cast<RoutingPad*>( anchor );
if (rp) {
source = rp->getSourcePosition();
target = rp->getTargetPosition();
return;
}
source = anchor->getPosition();
target = anchor->getPosition();
}
@ -353,8 +329,6 @@ namespace Anabatic {
, _forks ()
, _connexity ()
, _topology (0)
, _net (NULL)
, _netData (NULL)
, _gcell (NULL)
, _sourceContact (NULL)
, _southWestContact (NULL)
@ -368,9 +342,7 @@ namespace Anabatic {
, _routingPadAutoSegments()
, _toFixSegments ()
, _degree (0)
, _isStrictChannel (false)
, _sourceFlags (0)
, _flags (0)
, _isTwoMetals (false)
{ }
@ -381,11 +353,7 @@ namespace Anabatic {
void NetBuilder::clear ()
{
_connexity.connexity = 0;
_sourceFlags = 0;
_flags = 0;
_topology = 0;
_net = NULL;
_netData = NULL;
_gcell = NULL;
_sourceContact = NULL;
_southWestContact = NULL;
@ -396,8 +364,8 @@ namespace Anabatic {
_norths .clear();
_souths .clear();
_routingPads .clear();
_routingPadAutoSegments.clear();
_toFixSegments .clear();
_routingPadAutoSegments.clear();
}
@ -409,22 +377,17 @@ namespace Anabatic {
}
NetBuilder& NetBuilder::setStartHook ( AnabaticEngine* anbt
, Hook* fromHook
, AutoContact* sourceContact
, uint64_t sourceFlags )
NetBuilder& NetBuilder::setStartHook ( AnabaticEngine* anbt, Hook* fromHook, AutoContact* sourceContact )
{
clear();
_isStrictChannel = anbt->isChannelStyle() and not anbt->isHybridStyle();
_sourceFlags = sourceFlags;
_sourceContact = sourceContact;
_fromHook = fromHook;
_isTwoMetals = anbt->getConfiguration()->isTwoMetals();
_sourceContact = sourceContact;
_fromHook = fromHook;
cdebug_log(145,1) << "NetBuilder::setStartHook()" << endl;
cdebug_log(145,0) << "* _fromHook: " << fromHook << endl;
cdebug_log(145,0) << "* _sourceContact:" << sourceContact << endl;
cdebug_log(145,0) << "_isStrictChannel:" << _isStrictChannel << endl;
if (not _fromHook) {
cdebug_tabw(145,-1);
@ -432,21 +395,20 @@ namespace Anabatic {
}
Segment* fromSegment = static_cast<Segment*>( _fromHook->getComponent() );
_net = fromSegment->getNet();
_netData = anbt->getNetData( _net );
_net = fromSegment->getNet();
cdebug_log(145,0) << "For Hooks from fromHook" << endl;
for ( Hook* hook : fromHook->getHooks() ) {
cdebug_log(145,0) << "Hook: " << hook << endl;
cdebug_log(145,0) << "Topology [" << _connexity.connexity << "] = "
<< "[" << (int)_connexity.fields.globals
<< "+" << (int)_connexity.fields.M1
<< "+" << (int)_connexity.fields.M2
<< "+" << (int)_connexity.fields.M3
<< "+" << (int)_connexity.fields.Pin
<< "+" << (int)_connexity.fields.Pad
<< "] " << _gcell
<< endl;
<< "[" << (int)_connexity.fields.globals
<< "+" << (int)_connexity.fields.M1
<< "+" << (int)_connexity.fields.M2
<< "+" << (int)_connexity.fields.M3
<< "+" << (int)_connexity.fields.Pin
<< "+" << (int)_connexity.fields.Pad
<< "] " << _gcell
<< endl;
Segment* toSegment = dynamic_cast<Segment*>( hook->getComponent() );
if (toSegment) {
@ -481,18 +443,12 @@ namespace Anabatic {
throw Error( mismatchGCell );
}
if ( (_gcell->getDensity( Session::getDHorizontalDepth() ) > 0.9)
or (_gcell->getDensity( Session::getDVerticalDepth () ) > 0.9)) {
cdebug_log(145,0) << "Base layers blockeds, moving up" << endl;
_flags |= ToUpperRouting;
}
if (not _gcell->isMatrix()) {
cdebug_log(145,0) << "* Non-matrix GCell under: " << contact << endl;
cdebug_log(145,0) << "| " << gcell << endl;
}
} else {
if (rp and AllianceFramework::get()->isPad(rp->_getEntityAs<Component>()->getCell())) {
if (rp and AllianceFramework::get()->isPad(rp->_getEntityAsComponent()->getCell())) {
_connexity.fields.Pad++;
} else {
const Layer* layer = anchor->getLayer();
@ -506,32 +462,11 @@ namespace Anabatic {
continue;
}
bool isPin = (dynamic_cast<Pin*>( rp->getOccurrence().getEntity() ) != nullptr);
size_t rpDepth = 0;
for ( size_t depth=0 ; depth < Session::getRoutingGauge()->getDepth() ; ++depth ) {
if (layer->getMask() == Session::getRoutingLayer(depth)->getMask()) {
rpDepth = depth;
break;
}
}
if (rpDepth >= Session::getRoutingGauge()->getFirstRoutingLayer())
rpDepth -= Session::getRoutingGauge()->getFirstRoutingLayer();
else
cerr << Error( "Terminal layer \"%s\" of %s is below first usable routing layer."
, getString(layer->getName()).c_str()
, getString(anchor).c_str() )
<< endl;
if ((rpDepth > 0) and not isPin
and not Session::getRoutingGauge()->isSuperPitched()) {
_flags |= ToUpperRouting;
cdebug_log(145,0) << "ToUpperRouting set, getFlags():" << getFlags() << endl;
}
if (rpDepth == 0) _connexity.fields.M1++; // M1 V
else if (rpDepth == 1) _connexity.fields.M2++; // M2 H
else if (rpDepth == 2) _connexity.fields.M3++; // M3 V
else if (rpDepth == 3) _connexity.fields.M2++; // M4 H
else if (rpDepth == 4) _connexity.fields.M3++; // M5 V
if (layer->getMask() == Session::getRoutingLayer(0)->getMask()) _connexity.fields.M1++; // M1 V
else if (layer->getMask() == Session::getRoutingLayer(1)->getMask()) _connexity.fields.M2++; // M2 H
else if (layer->getMask() == Session::getRoutingLayer(2)->getMask()) _connexity.fields.M3++; // M3 V
else if (layer->getMask() == Session::getRoutingLayer(3)->getMask()) _connexity.fields.M2++; // M4 H
else if (layer->getMask() == Session::getRoutingLayer(4)->getMask()) _connexity.fields.M3++; // M5 V
else {
cerr << Warning( "Terminal layer \"%s\" of %s is not managed yet (ignored)."
, getString(layer->getName()).c_str()
@ -540,7 +475,7 @@ namespace Anabatic {
//continue;
}
if (isPin) _connexity.fields.Pin++;
if (dynamic_cast<Pin*>(rp->getOccurrence().getEntity())) _connexity.fields.Pin++;
}
cdebug_log(145,0) << "| Component to connect: " << anchor << endl;
@ -572,15 +507,6 @@ namespace Anabatic {
if (_gcell == NULL) throw Error( missingGCell );
cdebug_log(145,0) << "Topology [" << _connexity.connexity << "] = "
<< "[" << (int)_connexity.fields.globals
<< "+" << (int)_connexity.fields.M1
<< "+" << (int)_connexity.fields.M2
<< "+" << (int)_connexity.fields.M3
<< "+" << (int)_connexity.fields.Pin
<< "+" << (int)_connexity.fields.Pad
<< "] " << _gcell
<< endl;
return *this;
}
@ -590,7 +516,6 @@ namespace Anabatic {
cdebug_log(145,0) << "NetBuilder::push()" << endl;
cdebug_log(145,0) << "* toHook: " << toHook << endl;
cdebug_log(145,0) << "* _fromHook:" << _fromHook << endl;
cdebug_log(145,0) << "* flags:" << flags << endl;
if (not toHook or (toHook == _fromHook)) {
if (contact) {
@ -609,85 +534,23 @@ namespace Anabatic {
Hook* toHookOpposite = getSegmentOppositeHook( toHook );
cdebug_log(145,0) << "Pushing (to) " << getString(toHook) << endl;
cdebug_log(145,0) << "Pushing (from) " << contact << endl;
_forks.push( toHookOpposite, contact, getFlags() );
_forks.push( toHookOpposite, contact );
return true;
}
bool NetBuilder::isInsideBlockage ( GCell* gcell, Component* rp ) const
{
cdebug_log(145,1) << getTypeName() << "::isInsideBlockage() " << endl;
cdebug_log(145,0) << rp << endl;
cdebug_log(145,0) << rp->getLayer()->getMask() << endl;
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
if (gcell->getDensity(rpDepth) < 0.5) {
cdebug_tabw(145,-1);
return false;
}
Box rpBb = rp->getBoundingBox();
Layer::Mask rpMask = rp->getLayer()->getBlockageLayer()->getMask();
cdebug_log(145,0) << "rpBb: " << rpBb << endl;
for ( Occurrence occurrence : getAnabatic()->getCell()->getOccurrencesUnder(rpBb) ) {
cdebug_log(145,0) << "| " << occurrence.getEntity() << endl;
Component* component = dynamic_cast<Component*>( occurrence.getEntity() );
if (not component) continue;
const Layer* blockageLayer = component->getLayer();
Box blockageBb = component->getBoundingBox();
cdebug_log(145,0) << " Mask: " << blockageLayer->getMask() << endl;
if ( blockageLayer->isBlockage()
and (blockageLayer->getMask() == rpMask)) {
occurrence.getPath().getTransformation().applyOn( blockageBb );
cdebug_log(145,0) << " Bb: " << blockageBb << endl;
if (blockageBb.contains(rpBb)) {
cdebug_log(145,-1) << "* Inside " << component << endl;
return true;
}
if (blockageBb.intersect(rpBb)) {
cerr << Warning( "NetBuilder::isInsideBlockage(): RoutingPad is only partially inside blocked area.\n"
" * %s\n"
" * %s"
, getString(rp).c_str()
, getString(component).c_str()
) << endl;
cdebug_log(145,-1) << "* Partially inside " << component << endl;
return true;
}
}
}
cdebug_tabw(145,-1);
return false;
}
void NetBuilder::construct ()
{
cdebug_log(145,1) << "NetBuilder::construct() [" << _connexity.connexity << "] in " << _gcell << endl;
cdebug_log(145,0) << "Topology [" << _connexity.connexity << "] = "
<< "[" << (int)_connexity.fields.globals
<< "+" << (int)_connexity.fields.M1
<< "+" << (int)_connexity.fields.M2
<< "+" << (int)_connexity.fields.M3
<< "+" << (int)_connexity.fields.Pin
<< "+" << (int)_connexity.fields.Pad
<< "] " << _gcell
<< endl;
cdebug_log(145,0) << "getSourceFlags():" << getSourceFlags()
<< " getFlags():" << getFlags() << endl;
if (not isStrictChannel()) {
if (not isTwoMetals()) {
_southWestContact = NULL;
_northEastContact = NULL;
}
if (not _gcell->isAnalog()) {
if (isStrictChannel() and not _sourceContact) {
cdebug_log(145,0) << "No _sourceContact, resetting _fromHook" << endl;
_fromHook = NULL;
}
if (isTwoMetals() and not _sourceContact) _fromHook = NULL;
switch ( _connexity.connexity ) {
case Conn_1G_1Pad:
@ -699,11 +562,7 @@ namespace Anabatic {
case Conn_1G_2M1:
case Conn_1G_3M1:
case Conn_1G_4M1:
case Conn_1G_5M1:
case Conn_1G_6M1:
case Conn_1G_7M1:
case Conn_1G_8M1:
case Conn_1G_9M1: _do_1G_xM1(); break;
case Conn_1G_5M1: _do_1G_xM1(); break;
// End 1G_xM1 cascaded cases.
case Conn_1G_1M2:
@ -723,31 +582,17 @@ namespace Anabatic {
case Conn_2G_3M1:
case Conn_2G_4M1:
case Conn_2G_5M1:
case Conn_2G_6M1:
case Conn_2G_7M1:
case Conn_2G_8M1:
case Conn_2G_9M1: _do_xG_xM1_xM3(); break;
case Conn_3G_1M1: if (_do_xG_1M1()) break;
case Conn_3G_2M1:
case Conn_3G_3M1:
case Conn_3G_4M1:
case Conn_3G_5M1:
case Conn_3G_6M1:
case Conn_3G_7M1:
case Conn_3G_8M1:
case Conn_3G_9M1:
case Conn_3G_2M3:
case Conn_3G_3M3:
case Conn_3G_4M3: _do_xG_xM1_xM3(); break;
case Conn_3G_4M3:
case Conn_4G_1M1: if (_do_xG_1M1()) break;
case Conn_4G_2M1:
case Conn_4G_3M1:
case Conn_4G_4M1:
case Conn_4G_5M1:
case Conn_4G_6M1:
case Conn_4G_7M1:
case Conn_4G_8M1:
case Conn_4G_9M1: _do_xG_xM1_xM3(); break;
case Conn_4G_4M1: _do_xG_xM1_xM3(); break;
// End xG_xM1_xM3 cascaded cases.
case Conn_4G_1M2: if (_do_4G_1M2()) break;
@ -771,36 +616,19 @@ namespace Anabatic {
case Conn_4G: _do_xG(); break;
// End xG cascaded cases.
// Optimized specific cases.
case Conn_1G_1PinM1: _do_1G_1PinM1 (); break;
case Conn_2G_1PinM1: _do_2G_1PinM1 (); break;
case Conn_1G_1PinM2: _do_1G_1PinM2 (); break;
case Conn_2G_1PinM2:
case Conn_3G_1PinM2: _do_xG_1PinM2 (); break;
case Conn_1G_1PinM3: _do_1G_1PinM3 (); break;
case Conn_2G_1PinM3:
case Conn_3G_1PinM3: _do_xG_1PinM3 (); break;
case Conn_1G_2M1_1PinM1: _do_1G_xM1_1PinM1(); break;
case Conn_1G_1M1_1PinM3: _do_1G_1M1_1PinM3(); break;
case Conn_1G_1M1_1PinM2:
case Conn_1G_2M1_1PinM2:
case Conn_1G_3M1_1PinM2:
case Conn_1G_4M1_1PinM2:
case Conn_1G_5M1_1PinM2: _do_1G_xM1_1PinM2(); break;
case Conn_2G_1M1_1PinM2:
case Conn_2G_2M1_1PinM2: _do_2G_xM1_1PinM2(); break;
case Conn_2G_1M1_1PinM3:
case Conn_2G_2M1_1PinM3:
case Conn_2G_3M1_1PinM3: _do_2G_xM1_1PinM3(); break;
case Conn_3G_1M1_1PinM3:
case Conn_3G_2M1_1PinM3:
case Conn_3G_3M1_1PinM3: _do_3G_xM1_1PinM3(); break;
case Conn_1G_1M1_1M2: _do_xG_1M1_1M2 (); break;
case Conn_1G_1M1_1M3: _do_1G_xM1 (); break;
case Conn_2G_1M1_1M2: _do_xG_1M1_1M2 (); break;
case Conn_1G_1PinM2: _do_1G_1PinM2 (); break;
case Conn_2G_1PinM2:
case Conn_3G_1PinM2: _do_xG_1PinM2 (); break;
case Conn_1G_1PinM3: _do_1G_1PinM3 (); break;
case Conn_2G_1PinM3:
case Conn_3G_1PinM3: _do_xG_1PinM3 (); break;
case Conn_1G_1M1_1M2: _do_xG_1M1_1M2(); break;
case Conn_1G_1M1_1M3: _do_1G_xM1 (); break;
case Conn_2G_1M1_1M2: _do_xG_1M1_1M2(); break;
default:
//if (not isStrictChannel())
if (not isTwoMetals())
throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n"
" The global routing seems to be defective."
" The global routing seems to be defective."
, _connexity.connexity
, _connexity.fields.globals
, _connexity.fields.M1
@ -814,9 +642,6 @@ namespace Anabatic {
_do_xG();
}
cdebug_log(145,0) << "SouthWest: " << _southWestContact << endl;
cdebug_log(145,0) << "NorthEast: " << _northEastContact << endl;
if (not _do_globalSegment()) {
cdebug_log(145,0) << "No global generated, finish." << endl;
cdebug_tabw(145,-1);
@ -841,15 +666,11 @@ namespace Anabatic {
, getString(_net).c_str()
);
if ( (_sourceContact) and (targetContact) ){
Segment* baseSegment = static_cast<Segment*>( _fromHook->getComponent() );
if ( (_sourceContact) && (targetContact) ){
AutoSegment* globalSegment = AutoSegment::create( _sourceContact
, targetContact
, baseSegment
, static_cast<Segment*>( _fromHook->getComponent() )
);
if (_netData and _netData->isNoMoveUp(baseSegment)) {
globalSegment->setFlags( AutoSegment::SegNoMoveUp );
}
cdebug_log(145,0) << "[Create global segment (1)]: " << globalSegment << endl;
}
}
@ -1141,25 +962,9 @@ namespace Anabatic {
}
bool NetBuilder::_do_1G_1PinM1 ()
{
throw Error ( "%s::_do_1G_1PinM1() method *not* reimplemented from base class.", getTypeName().c_str() );
return false;
}
bool NetBuilder::_do_2G_1PinM1 ()
{
throw Error ( "%s::_do_2G_1PinM1() method *not* reimplemented from base class.", getTypeName().c_str() );
return false;
}
bool NetBuilder::_do_xG_1PinM2 ()
{
throw Error( "%s::_do_xG_1PinM2() method *not* reimplemented from base class.\n"
" On %s"
, getTypeName().c_str(), getString(getNet()).c_str() );
throw Error ( "%s::_do_xG_1PinM2() method *not* reimplemented from base class.", getTypeName().c_str() );
return false;
}
@ -1247,49 +1052,7 @@ namespace Anabatic {
return false;
}
bool NetBuilder::_do_1G_1M1_1PinM3 ()
{
throw Error ( "%s::_do_1G_1M1_1PinM3() method *not* reimplemented from base class.", getTypeName().c_str() );
return false;
}
bool NetBuilder::_do_1G_xM1_1PinM2 ()
{
throw Error ( "%s::_do_1G_xM1_1PinM2() method *not* reimplemented from base class.", getTypeName().c_str() );
return false;
}
bool NetBuilder::_do_2G_xM1_1PinM2 ()
{
throw Error ( "%s::_do_2G_xM1_1PinM2() method *not* reimplemented from base class.", getTypeName().c_str() );
return false;
}
bool NetBuilder::_do_2G_xM1_1PinM3 ()
{
throw Error ( "%s::_do_2G_xM1_1PinM3() method *not* reimplemented from base class.", getTypeName().c_str() );
return false;
}
bool NetBuilder::_do_1G_xM1_1PinM1 ()
{
throw Error ( "%s::_do_1G_xM1_1PinM1() method *not* reimplemented from base class.", getTypeName().c_str() );
return false;
}
bool NetBuilder::_do_3G_xM1_1PinM3 ()
{
throw Error ( "%s::_do_3G_xM1_1PinM3() method *not* reimplemented from base class.", getTypeName().c_str() );
return false;
}
bool NetBuilder::_do_globalSegment ()
{
throw Error ( "%s::_do_globalSegment() method *not* reimplemented from base class.", getTypeName().c_str() );
@ -1304,12 +1067,11 @@ namespace Anabatic {
vector<RoutingPad*> rpM1s;
Component* rpM2 = NULL;
for ( RoutingPad* rp : net->getRoutingPads() ) {
if ( Session::getRoutingGauge()->getLayerDepth(rp->getLayer())
== 1 + Session::getRoutingGauge()->getFirstRoutingLayer())
rpM2 = rp;
forEach ( RoutingPad*, irp, net->getRoutingPads() ) {
if (Session::getRoutingGauge()->getLayerDepth(irp->getLayer()) == 1)
rpM2 = *irp;
else
rpM1s.push_back( rp );
rpM1s.push_back( *irp );
}
if ((rpM1s.size() < 2) and not rpM2) {
@ -2479,15 +2241,12 @@ namespace Anabatic {
Hook* sourceHook = NULL;
AutoContact* sourceContact = NULL;
uint64_t sourceFlags = NoFlags;
RoutingPads routingPads = net->getRoutingPads();
size_t degree = routingPads.getSize();
if (degree == 0) {
if (not net->isBlockage()) {
cmess2 << Warning( "Net \"%s\" do not have any RoutingPad (ignored)."
, getString(net->getName()).c_str() ) << endl;
}
cmess2 << Warning("Net \"%s\" do not have any RoutingPad (ignored)."
,getString(net->getName()).c_str()) << endl;
cdebug_tabw(145,-1);
return;
}
@ -2518,7 +2277,7 @@ namespace Anabatic {
++connecteds;
segmentFound = true;
setStartHook( anabatic, hook, NULL, NoFlags );
setStartHook( anabatic, hook, NULL );
if (getStateG() == 1) {
if ( (lowestGCell == NULL) or (*getGCell() < *lowestGCell) ) {
cdebug_log(145,0) << "Potential starting GCell " << getGCell() << endl;
@ -2546,9 +2305,9 @@ namespace Anabatic {
}
cdebug_tabw(145,-1);
if (startHook == NULL) { setStartHook(anabatic,NULL,NULL,NoFlags).singleGCell(anabatic,net); cdebug_tabw(145,-1); return; }
if (startHook == NULL) { setStartHook(anabatic,NULL,NULL).singleGCell(anabatic,net); cdebug_tabw(145,-1); return; }
setStartHook( anabatic, startHook, NULL, NoFlags );
setStartHook( anabatic, startHook, NULL );
cdebug_log(145,0) << endl;
cdebug_log(145,0) << "--------~~~~=={o}==~~~~--------" << endl;
cdebug_log(145,0) << endl;
@ -2557,21 +2316,18 @@ namespace Anabatic {
sourceHook = _forks.getFrom ();
sourceContact = _forks.getContact();
sourceFlags = _forks.getFlags ();
_forks.pop();
while ( sourceHook ) {
setStartHook( anabatic, sourceHook, sourceContact, sourceFlags );
setStartHook( anabatic, sourceHook, sourceContact );
construct();
sourceHook = _forks.getFrom ();
sourceHook = _forks.getFrom();
sourceContact = _forks.getContact();
sourceFlags = _forks.getFlags ();
_forks.pop();
cdebug_log(145,0) << "Popping (from) " << sourceHook << endl;
cdebug_log(145,0) << "Popping (to) " << sourceContact << endl;
cdebug_log(145,0) << "Popping (flags) " << sourceFlags << endl;
cdebug_log(145,0) << "Popping (from) " << sourceHook << endl;
cdebug_log(145,0) << "Popping (to) " << sourceContact << endl;
}
Session::revalidate();
@ -2582,11 +2338,10 @@ namespace Anabatic {
for ( ; iover != overconstraineds.end() ; ++iover ) {
(*iover)->makeDogLeg( (*iover)->getAutoSource()->getGCell(), true );
}
Session::revalidate();
#endif
fixSegments();
Session::revalidate();
fixSegments();
cdebug_tabw(145,-1);
//DebugSession::close();

File diff suppressed because it is too large Load Diff

View File

@ -1,643 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./NetBuilderHybridVH.cpp" |
// +-----------------------------------------------------------------+
#include <cstdlib>
#include <sstream>
#include "hurricane/Bug.h"
#include "hurricane/Breakpoint.h"
#include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/DebugSession.h"
#include "hurricane/Layer.h"
#include "hurricane/BasicLayer.h"
#include "hurricane/RegularLayer.h"
#include "hurricane/Technology.h"
#include "hurricane/DataBase.h"
#include "hurricane/Net.h"
#include "hurricane/NetExternalComponents.h"
#include "hurricane/NetRoutingProperty.h"
#include "hurricane/RoutingPad.h"
#include "hurricane/RoutingPads.h"
#include "hurricane/Pin.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 "crlcore/AllianceFramework.h"
#include "crlcore/RoutingGauge.h"
#include "crlcore/Measures.h"
#include "anabatic/AutoContactTerminal.h"
#include "anabatic/AutoContactTurn.h"
#include "anabatic/AutoContactHTee.h"
#include "anabatic/AutoContactVTee.h"
#include "anabatic/AutoSegment.h"
#include "anabatic/NetBuilderHybridVH.h"
#include "anabatic/AnabaticEngine.h"
namespace Anabatic {
using std::swap;
using Hurricane::Error;
using Hurricane::Pin;
NetBuilderHybridVH::NetBuilderHybridVH ()
: NetBuilder()
{ }
NetBuilderHybridVH::~NetBuilderHybridVH () { }
string NetBuilderHybridVH::getStyle ()
{ return "VH,2RL"; }
void NetBuilderHybridVH::doRp_AutoContacts ( GCell* gcell
, Component* rp
, AutoContact*& source
, AutoContact*& target
, uint64_t flags
)
{
throw Error ( "%s::dpRp_AutoContacts() method must never be called.", getTypeName().c_str() );
}
AutoContact* NetBuilderHybridVH::doRp_Access ( GCell* gcell, Component* rp, uint64_t flags )
{
cdebug_log(145,1) << getTypeName() << "::doRp_Access()" << endl;
cdebug_log(145,0) << rp << endl;
const Layer* rpLayer = rp->getLayer();
//const Layer* viaLayer = Session::getDContactLayer();
DbU::Unit viaSide = Session::getDContactWidth();
Point position = rp->getCenter();
AutoContact* rpContact = AutoContactTerminal::create( gcell, rp, rpLayer, position, viaSide, viaSide );
cdebug_tabw(145,-1);
return rpContact;
}
AutoContact* NetBuilderHybridVH::doRp_AccessNorthSouthPin ( GCell* gcell, RoutingPad* rp )
{
cdebug_log(145,1) << getTypeName() << "::doRp_AccessNorthSouthPin() " << rp << endl;
AutoContact* rpContact = doRp_Access( gcell, rp, NoFlags );
AutoContact* turn = NULL;
Net* net = rp->getNet();
Pin* pin = dynamic_cast<Pin*>( rp->getOccurrence().getEntity() );
Pin::AccessDirection pinDir = pin->getAccessDirection();
if (pinDir == Pin::AccessDirection::NORTH) {
turn = AutoContactTurn::create( gcell, net, Session::getBuildRoutingLayer(0) );
AutoSegment* segment = AutoSegment::create( rpContact, turn, Flags::Vertical );
segment->setAxis( rp->getX(), Flags::Force );
segment->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis );
rpContact = turn;
turn = AutoContactTurn::create( gcell, net, Session::getBuildContactLayer(0) );
segment = AutoSegment::create( rpContact, turn, Flags::Horizontal );
rpContact = turn;
DbU::Unit axis = gcell->getYMax() - Session::getDHorizontalPitch();
cdebug_log(145,0) << "axis:" << DbU::getValueString(axis) << endl;
segment->setAxis( axis, Flags::Force );
//segment->setFlags( AutoSegment::SegFixed|AutoSegment::SegFixedAxis );
cdebug_log(145,0) << segment << endl;
} else {
turn = rpContact;
}
cdebug_tabw(145,-1);
return turn;
}
AutoContact* NetBuilderHybridVH::doRp_AccessEastWestPin ( GCell* gcell, RoutingPad* rp )
{
cdebug_log(145,1) << getTypeName() << "::doRp_AccessEastWestPin() " << rp << endl;
Net* net = rp->getNet();
Pin* pin = dynamic_cast<Pin*>( rp->getOccurrence().getEntity() );
Pin::AccessDirection pinDir = pin->getAccessDirection();
AutoContact* rpContact = doRp_Access( gcell, rp, NoFlags );
AutoContact* turn = NULL;
AutoSegment* segment = NULL;
turn = AutoContactTurn::create( gcell, net, Session::getBuildContactLayer(0) );
segment = AutoSegment::create( rpContact, turn, Flags::Horizontal );
segment->setAxis( pin->getCenter().getY(), Flags::Force );
rpContact = turn;
turn = AutoContactTurn::create( gcell, net, Session::getBuildContactLayer(0) );
segment = AutoSegment::create( rpContact, turn, Flags::Vertical );
DbU::Unit axis = 0;
if (pinDir == Pin::AccessDirection::EAST)
axis = gcell->getXMax() - Session::getDVerticalPitch();
else
axis = gcell->getXMin() + Session::getDVerticalPitch();
segment->setAxis( axis );
cdebug_tabw(145,-1);
return turn;
}
bool NetBuilderHybridVH::doRp_xG_1M1 ( RoutingPad* rp )
{
cdebug_log(145,1) << getTypeName() << "::doRp_xG_1M1()" << endl;
AutoContact* swContact = nullptr;
if (west() or south()) {
AutoContact* termContact = doRp_Access( getGCell(), rp, NoFlags );
if (west() and south()) {
swContact = AutoContactVTee::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
AutoSegment::create( termContact, swContact, Flags::Vertical );
} else {
if (west()) {
swContact = AutoContactTurn::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
AutoSegment::create( termContact, swContact, Flags::Vertical );
} else
swContact = termContact;
}
setSouthWestContact( swContact );
}
AutoContact* neContact = nullptr;
if (east() or north()) {
AutoContact* termContact = doRp_Access( getGCell(), rp, NoFlags );
if (east() and north()) {
neContact = AutoContactVTee::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
AutoSegment::create( termContact, neContact, Flags::Vertical );
} else {
if (east()) {
neContact = AutoContactTurn::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
AutoSegment::create( termContact, neContact, Flags::Vertical );
} else
neContact = termContact;
}
setNorthEastContact( neContact );
}
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHybridVH::_do_xG_1M1 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_xG_1M1()" << endl;
doRp_xG_1M1( getRoutingPads()[0] );
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHybridVH::_do_2G_1M1 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_2G_1M1()" << endl;
doRp_xG_1M1( getRoutingPads()[0] );
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHybridVH::doRp_xG_xM1_xM3 ( const vector<RoutingPad*>& rps )
{
cdebug_log(145,1) << getTypeName() << "::doRp_xG_xM1()" << endl;
AutoContact* prevContact = nullptr;
AutoContact* currContact = nullptr;
for ( size_t i=0 ; i<rps.size() ; ++i ) {
prevContact = currContact;
AutoContact* currTerm = doRp_Access( getGCell(), rps[i], NoFlags );
if (i == 0) {
if (west() or south()) {
AutoContact* swContact = nullptr;
currContact = AutoContactVTee::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
if (west() and south()) {
swContact = AutoContactVTee::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
} else {
if (west())
swContact = AutoContactTurn::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
else
swContact = currContact;
}
if (swContact != currContact)
AutoSegment::create( currContact, swContact, Flags::Vertical );
setSouthWestContact( swContact );
} else {
currContact = AutoContactTurn::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
}
AutoSegment::create( currTerm, currContact, Flags::Vertical );
continue;
}
if (i+1 == rps.size()) {
if (east() or north()) {
AutoContact* neContact = nullptr;
currContact = AutoContactVTee::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
if (east() and north()) {
neContact = AutoContactVTee::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
} else {
if (east())
neContact = AutoContactTurn::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
else
neContact = currContact;
}
if (neContact != currContact)
AutoSegment::create( currContact, neContact, Flags::Vertical );
setNorthEastContact( neContact );
} else {
currContact = AutoContactTurn::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
}
} else {
currContact = AutoContactHTee::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
}
AutoSegment::create( currTerm , currContact, Flags::Vertical );
AutoSegment::create( prevContact, currContact, Flags::Horizontal );
}
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHybridVH::_do_xG_xM1_xM3 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_xG_xM1()" << endl;
sortRpByX( getRoutingPads(), NoFlags ); // increasing X.
doRp_xG_xM1_xM3( getRoutingPads() );
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHybridVH::_do_1G_xM1 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_1G_xM1()" << endl;
if (getConnexity().fields.M1 == 1)
_do_xG_1M1();
else
_do_xG_xM1_xM3();
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHybridVH::_do_xG ()
{
cdebug_log(145,1) << getTypeName() << "::_do_xG()" << endl;
const Layer* viaLayer = Session::getBuildContactLayer( 0 );
if (getConnexity().fields.globals == 2) {
setBothCornerContacts( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
} else if (getConnexity().fields.globals == 3) {
if (east() and west()) {
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
if (south()) swapCornerContacts();
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Vertical );
} else {
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), viaLayer ) );
setNorthEastContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer ) );
if (west()) swapCornerContacts();
AutoSegment::create( getSouthWestContact(), getNorthEastContact(), Flags::Horizontal );
}
} else { // fields.globals == 4.
AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
setSouthWestContact( AutoContactHTee::create( getGCell(), getNet(), viaLayer ) );
setNorthEastContact( AutoContactVTee::create( getGCell(), getNet(), viaLayer ) );
AutoSegment::create( getSouthWestContact(), turn, Flags::Horizontal );
AutoSegment::create( turn, getNorthEastContact(), Flags::Vertical );
}
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHybridVH::_do_1G_1PinM1 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_1G_1PinM1() [Managed Configuration - Optimized] " << getTopology() << endl;
AutoContact* rpContact = doRp_AccessNorthSouthPin( getGCell(), getRoutingPads()[0] );
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
AutoSegment::create( rpContact, turn1, Flags::Vertical );
if (north() or south()) {
AutoContact* turn2 = AutoContactTurn::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
AutoSegment::create( turn1, turn2, Flags::Horizontal );
turn1 = turn2;
}
setBothCornerContacts( turn1 );
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHybridVH::_do_2G_1PinM1 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_2G_1PinM1() [Managed Configuration - Optimized] " << getTopology() << endl;
AutoContact* rpContact = doRp_AccessNorthSouthPin( getGCell(), getRoutingPads()[0] );
AutoContact* tee = nullptr;
if (east() and west()) {
tee = AutoContactHTee::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
} else {
tee = AutoContactVTee::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
}
AutoSegment::create( rpContact, tee, Flags::Vertical );
setBothCornerContacts( tee );
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHybridVH::_do_1G_xM1_1PinM1 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_1G_xM1_1PinM1() [Managed Configuration - Optimized] " << getTopology() << endl;
sortRpByX( getRoutingPads(), NoFlags ); // increasing X.
vector<RoutingPad*> rpsM1;
RoutingPad* rpM2 = nullptr;
for ( RoutingPad* rp : getRoutingPads() ) {
if (dynamic_cast<Pin*>(rp->getOccurrence().getEntity())) rpM2 = rp;
else rpsM1.push_back( rp );
}
if (rpsM1.size() > 1)
doRp_xG_xM1_xM3( rpsM1 );
else
doRp_xG_1M1( rpsM1[0] );
AutoContact* rpContact = doRp_AccessNorthSouthPin( getGCell(), rpM2 );
AutoContact* rpM1Contact = doRp_Access( getGCell(), rpsM1.front(), NoFlags );
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
AutoContact* turn2 = AutoContactTurn::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
AutoSegment::create( rpM1Contact, turn1, Flags::Vertical );
AutoSegment::create( rpContact , turn2, Flags::Vertical );
AutoSegment::create( turn1 , turn2, Flags::Horizontal );
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHybridVH::doRp_1G_1PinM2 ( RoutingPad* rp )
{
cdebug_log(145,1) << getTypeName() << "::doRp_1G_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl;
AutoContact* rpContact = doRp_AccessEastWestPin( getGCell(), rp );
AutoContact* turn1 = AutoContactTurn::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
AutoSegment::create( rpContact, turn1, Flags::Horizontal );
if (east() or west()) {
AutoContact* turn2 = AutoContactTurn::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
AutoSegment::create( turn1, turn2, Flags::Vertical );
turn1 = turn2;
}
setBothCornerContacts( turn1 );
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHybridVH::_do_1G_1PinM2 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_1G_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl;
doRp_1G_1PinM2( getRoutingPads()[0] );
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHybridVH::_do_xG_1PinM2 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_xG_1PinM2()" << endl;
AutoContact* rpContact = doRp_AccessEastWestPin( getGCell(), getRoutingPads()[0] );
AutoContact* neContact = nullptr;
AutoContact* swContact = nullptr;
const Layer* viaLayer = Session::getBuildContactLayer( 0 );
if (getConnexity().fields.globals == 2) {
if (north() and south())
neContact = AutoContactVTee::create( getGCell(), getNet(), viaLayer );
else
neContact = AutoContactHTee::create( getGCell(), getNet(), viaLayer );
AutoSegment::create( rpContact, neContact, Flags::Horizontal );
setBothCornerContacts( neContact );
} else if (getConnexity().fields.globals == 3) {
swContact = AutoContactVTee::create( getGCell(), getNet(), viaLayer );
neContact = AutoContactVTee::create( getGCell(), getNet(), viaLayer );
if (west())
AutoSegment::create( rpContact, neContact, Flags::Horizontal );
else
AutoSegment::create( rpContact, swContact, Flags::Horizontal );
AutoSegment::create( swContact, neContact, Flags::Vertical );
setNorthEastContact( neContact );
setSouthWestContact( swContact );
}
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHybridVH::_do_1G_xM1_1PinM2 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_1G_xM1_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl;
sortRpByX( getRoutingPads(), NoFlags ); // increasing X.
vector<RoutingPad*> rpsM1;
RoutingPad* rpM2 = nullptr;
for ( RoutingPad* rp : getRoutingPads() ) {
if (dynamic_cast<Pin*>(rp->getOccurrence().getEntity())) rpM2 = rp;
else rpsM1.push_back( rp );
}
if (rpsM1.size() > 1)
doRp_xG_xM1_xM3( rpsM1 );
else
doRp_xG_1M1( rpsM1[0] );
Pin* pin = dynamic_cast<Pin*>( rpM2->getOccurrence().getEntity() );
Pin::AccessDirection pinDir = pin->getAccessDirection();
AutoContact* rpContact = doRp_AccessEastWestPin( getGCell(), rpM2 );
AutoContact* rpM1Contact = nullptr;
if (pinDir == Pin::AccessDirection::EAST)
rpM1Contact = doRp_Access( getGCell(), rpsM1.back(), NoFlags );
else
rpM1Contact = doRp_Access( getGCell(), rpsM1.front(), NoFlags );
AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
AutoSegment::create( rpM1Contact, turn, Flags::Vertical );
AutoSegment::create( rpContact , turn, Flags::Horizontal );
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderHybridVH::_do_1G_1M1 () { return false; }
// bool NetBuilderHybridVH::_do_xG_1Pad () { return false; }
// bool NetBuilderHybridVH::_do_xG_xM2 () { return false; }
// bool NetBuilderHybridVH::_do_1G_1M3 () { return false; }
// bool NetBuilderHybridVH::_do_xG_xM3 () { return false; }
// bool NetBuilderHybridVH::_do_xG_1M1_1M2 () { return false; }
// bool NetBuilderHybridVH::_do_4G_1M2 () { return false; }
bool NetBuilderHybridVH::_do_2G () { return false; }
bool NetBuilderHybridVH::_do_globalSegment ()
{
cdebug_log(145,1) << getTypeName() << "::_do_globalSegment()" << endl;
cdebug_log(145,0) << "getSourceFlags():" << getSourceFlags()
<< " getFlags():" << getFlags() << endl;
if (getSourceContact()) {
uint64_t segmentBound = getSegmentHookType( getFromHook() );
AutoContact* targetContact
= (segmentBound & (NorthBound|EastBound)) ? getNorthEastContact() : getSouthWestContact() ;
if (not getFromHook()) cerr << "getFromHook() is NULL !" << endl;
AutoContact* sourceContact = getSourceContact();
if (segmentBound & (NorthBound|SouthBound)) {
AutoContact* turn = AutoContactTurn::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
AutoSegment::create( sourceContact, turn, Flags::Vertical );
sourceContact = AutoContactTurn::create( getGCell(), getNet(), Session::getBuildContactLayer(0) );
AutoSegment::create( sourceContact, turn, Flags::Horizontal );
}
Segment* baseSegment = static_cast<Segment*>( getFromHook()->getComponent() );
AutoSegment* globalSegment = AutoSegment::create( sourceContact
, targetContact
, baseSegment
);
globalSegment->setFlags( (getDegree() == 2) ? AutoSegment::SegBipoint : 0 );
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
// HARDCODED VALUE.
if ( (getTopology() & Global_Fixed) and (globalSegment->getAnchoredLength() < 2*Session::getSliceHeight()) )
addToFixSegments( globalSegment );
if (getConnexity().fields.globals < 2) {
cdebug_tabw(145,-1);
return false;
}
} else
setFromHook( NULL );
push( east (), getNorthEastContact() );
push( west (), getSouthWestContact() );
push( north(), getNorthEastContact() );
push( south(), getSouthWestContact() );
cdebug_tabw(145,-1);
return true;
}
void NetBuilderHybridVH::singleGCell ( AnabaticEngine* anbt, Net* net )
{
cdebug_log(145,1) << getTypeName() << "::singleGCell() " << net << endl;
vector<RoutingPad*> rps;
for ( RoutingPad* irp : net->getRoutingPads() )
rps.push_back( irp );
if (rps.size() < 2) {
cerr << Error( "%s::singleGCell(): For %s, less than two Plugs/Pins (%d)."
, getTypeName().c_str()
, getString(net).c_str()
, rps.size() ) << endl;
cdebug_tabw(145,-1);
return;
}
sortRpByX( rps, NetBuilder::NoFlags ); // increasing X.
GCell* gcell1 = anbt->getGCellUnder( rps.front()->getCenter() );
GCell* gcell2 = anbt->getGCellUnder( rps.back ()->getCenter() );
if (not gcell1) {
cerr << Error( "No GCell under %s.", getString(rps.front()).c_str() ) << endl;
cdebug_tabw(145,-1);
return;
}
if (gcell1 != gcell2) {
cerr << Error( "Not under a single GCell %s.", getString(rps.back()).c_str() ) << endl;
cdebug_tabw(145,-1);
return;
}
AutoContact* prevContact = nullptr;
AutoContact* currContact = nullptr;
for ( size_t i=0 ; i<rps.size() ; ++i ) {
prevContact = currContact;
AutoContact* currTerm = doRp_Access( gcell1, rps[i], NoFlags );
if (i == 0) {
currContact = AutoContactTurn::create( gcell1, net, Session::getBuildContactLayer(0) );
AutoSegment::create( currTerm, currContact, Flags::Vertical );
continue;
}
if (i+1 == rps.size()) {
currContact = AutoContactTurn::create( gcell1, net, Session::getBuildContactLayer(0) );
} else {
currContact = AutoContactHTee::create( gcell1, net, Session::getBuildContactLayer(0) );
}
AutoSegment::create( currTerm , currContact, Flags::Vertical );
AutoSegment::create( prevContact, currContact, Flags::Horizontal );
}
cdebug_tabw(145,-1);
}
string NetBuilderHybridVH::getTypeName () const
{ return "NetBuilderHybridVH"; }
} // Anabatic namespace.

View File

@ -61,10 +61,6 @@ namespace Anabatic {
NetBuilderM2::~NetBuilderM2 () { }
string NetBuilderM2::getStyle ()
{ return "2RL-"; }
void NetBuilderM2::doRp_AutoContacts ( GCell* gcell
, Component* rp
@ -191,7 +187,7 @@ namespace Anabatic {
contact2 ->setFlags( CntFixed );
AutoSegment* fixed = AutoSegment::create( rpContact, contact1, Flags::Vertical );
AutoSegment* dogleg = AutoSegment::create( contact1 , contact2, Flags::Horizontal|Flags::UseNonPref );
AutoSegment* dogleg = AutoSegment::create( contact1 , contact2, Flags::Horizontal );
fixed ->setFlags( AutoSegment::SegFixed );
dogleg->setFlags( AutoSegment::SegFixed );
@ -322,7 +318,7 @@ namespace Anabatic {
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
// HARDCODED VALUE.
if ( (getTopology() & Global_Fixed) and (globalSegment->getAnchoredLength() < 2*Session::getSliceHeight()) )
if ( (getTopology() & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) )
addToFixSegments( globalSegment );
if (getConnexity().fields.globals < 2) {

View File

@ -66,10 +66,6 @@ namespace Anabatic {
NetBuilderVH::~NetBuilderVH () { }
string NetBuilderVH::getStyle ()
{ return "VH,3RL+"; }
void NetBuilderVH::doRp_AutoContacts ( GCell* gcell
, Component* rp
@ -89,6 +85,7 @@ namespace Anabatic {
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
Flags direction = Session::getDirection ( rpDepth );
DbU::Unit viaSide = Session::getViaWidth ( rpDepth );
DbU::Unit gridPosition = 0;
getPositions( rp, sourcePosition, targetPosition );
@ -117,8 +114,56 @@ namespace Anabatic {
}
}
#if 0
// Quasi-punctual M1 terminal.
if (flags & VSmall) {
Box ab = rp->getCell()->getBoundingBox();
RoutingLayerGauge* gaugeMetal3 = Session::getLayerGauge( 2 );
DbU::Unit metal3axis = gaugeMetal3->getTrackPosition( ab.getYMin()
, ab.getYMax()
, sourcePosition.getY()
, Constant::Nearest );
DbU::Unit viaSideProtect = Session::getViaWidth((size_t)0);
AutoContact* sourceVia12 = AutoContactTerminal::create( sourceGCell
, rp
, Session::getContactLayer(0)
, sourcePosition
, viaSideProtect, viaSideProtect
);
AutoContact* targetVia12 = AutoContactTerminal::create( targetGCell
, rp
, Session::getContactLayer(0)
, targetPosition
, viaSideProtect, viaSideProtect
);
AutoContact* sourceVia23 = AutoContactTurn::create( sourceGCell, net, Session::getContactLayer(1) );
AutoContact* targetVia23 = AutoContactTurn::create( targetGCell, net, Session::getContactLayer(1) );
sourceVia23->setY( metal3axis );
targetVia23->setY( metal3axis );
sourceVia23->setX( sourcePosition.getX() );
targetVia23->setX( targetPosition.getX() );
AutoSegment* segmentS = AutoSegment::create( sourceVia12, sourceVia23, Flags::Vertical );
AutoSegment* segmentT = AutoSegment::create( targetVia12, targetVia23, Flags::Vertical );
AutoSegment* segmentM = AutoSegment::create( sourceVia23, targetVia23, Flags::Horizontal );
sourceVia12->setFlags( CntFixed );
sourceVia23->setFlags( CntFixed );
targetVia12->setFlags( CntFixed );
targetVia23->setFlags( CntFixed );
segmentS->setFlags( AutoSegment::SegFixed );
segmentT->setFlags( AutoSegment::SegFixed );
segmentM->setFlags( AutoSegment::SegFixed );
cdebug_log(145,0) << "Hard protect: " << rp << endl;
cdebug_log(145,0) << "X:" << DbU::getValueString(sourcePosition.getX())
<< " Metal3 Track Y:" << DbU::getValueString(metal3axis) << endl;
}
#endif
// Non-M1 terminal or punctual M1 protections.
if ( (rpDepth != 0) or (sourcePosition == targetPosition) ) {
if ( (rpDepth != 0) or ((sourcePosition == targetPosition) and (gridPosition == 0)) ) {
map<Component*,AutoSegment*>::iterator irp = getRpLookup().find( rp );
if (irp == getRpLookup().end()) {
AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell
@ -160,10 +205,6 @@ namespace Anabatic {
);
}
if ( (rpDepth > 0) and not Session::getRoutingGauge()->isSuperPitched() ) {
rpLayer = Session::getContactLayer( rpDepth );
}
if (not source and not target) {
source = target = AutoContactTerminal::create( gcell
, rp
@ -182,43 +223,28 @@ namespace Anabatic {
{
cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl;
AutoContact* rpContactSource = NULL;
AutoContact* rpContactTarget = NULL;
const Layer* rpLayer = rp->getLayer();
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
AutoContact* rpContactSource;
AutoContact* rpContactTarget;
flags |= checkRoutingPadSize( rp );
doRp_AutoContacts( gcell, rp, rpContactSource, rpContactTarget, flags );
if (rpDepth % 2 == 0) { // RP should be vertical (M1, M3).
if (not (flags & (HAccess|HAccessEW))) {
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical , rpDepth+2 );
AutoSegment::create( subContact1, subContact2, Flags::Horizontal, rpDepth+1 );
rpContactSource = subContact2;
} else {
if (flags & VSmall) {
AutoContact* subContact1 = NULL;
if (flags & HAccessEW)
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
else
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical );
rpContactSource = subContact1;
}
}
} else { // RP should be horizontal (M2).
if (flags & (HAccess|HAccessEW)) {
if (not (flags & (HAccess|HAccessEW))) {
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical );
AutoSegment::create( subContact1, subContact2, Flags::Horizontal );
rpContactSource = subContact2;
} else {
if (flags & VSmall) {
AutoContact* subContact1 = NULL;
if (flags & HAccessEW)
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(1) );
else
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical, rpDepth+1 );
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical );
rpContactSource = subContact1;
}
}
@ -495,12 +521,6 @@ namespace Anabatic {
}
bool NetBuilderVH::_do_2G ()
{
cdebug_log(145,0) << getTypeName() << "::_do_2G()" << endl;
return _do_xG();
}
bool NetBuilderVH::_do_xG ()
{
cdebug_log(145,1) << getTypeName() << "::_do_xG()" << endl;
@ -551,7 +571,7 @@ namespace Anabatic {
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
// HARDCODED VALUE.
if ( (getTopology() & Global_Fixed) and (globalSegment->getAnchoredLength() < 2*Session::getSliceHeight()) )
if ( (getTopology() & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) )
addToFixSegments( globalSegment );
if (getConnexity().fields.globals < 2) {

View File

@ -61,55 +61,55 @@ namespace {
void propagateConstraintFromRp ( RoutingPad* rp )
{
cdebug_log(146,1) << "propagateConstraintFromRp() - " << rp << endl;
cdebug_log(145,1) << "propagateConstraintFromRp() - " << rp << endl;
for ( Component* component : rp->getSlaveComponents() ) {
cdebug_log(146,0) << "slave component: " << component << endl;
cdebug_log(145,0) << "slave component: " << component << endl;
AutoContact* sourceContact = Session::lookup( dynamic_cast<Contact*>(component) );
if (sourceContact) {
Box constraintBox = sourceContact->getConstraintBox();
cdebug_log(146,0) << "Start slave: " << sourceContact << endl;
cdebug_log(146,0) << "Constraint: " << constraintBox << endl;
cdebug_log(145,0) << "Start slave: " << sourceContact << endl;
cdebug_log(145,0) << "Constraint: " << constraintBox << endl;
set<AutoSegment*> verticalSegments;
set<AutoSegment*> horizontalSegments;
for ( AutoSegment* segment : sourceContact->getAutoSegments() ) {
cdebug_log(146,0) << "Examining: " << segment << endl;
cdebug_log(145,0) << "Examining: " << segment << endl;
AutoContact* targetContact = segment->getOppositeAnchor(sourceContact);
if (targetContact) {
if (segment->isHorizontal()) {
cdebug_log(146,0) << "On horizontal stack " << segment << endl;
cdebug_log(145,0) << "On horizontal stack " << segment << endl;
horizontalSegments.insert( segment );
} else {
cdebug_log(146,0) << "On vertical stack " << segment << endl;
cdebug_log(145,0) << "On vertical stack " << segment << endl;
verticalSegments.insert( segment );
}
}
}
// Propagate constraint through horizontally aligned segments.
cdebug_log(146,0) << "Propagate constraint on horizontal segments" << endl;
cdebug_log(145,0) << "Propagate constraint on horizontal segments" << endl;
for ( AutoSegment* horizontal : horizontalSegments ) {
AutoContact* contact = NULL;
for ( AutoSegment* aligned : horizontal->getAligneds(Flags::WithSelf) ) {
cdebug_log(146,0) << "aligned horizontal: " << aligned << endl;
cdebug_log(145,0) << "aligned horizontal: " << aligned << endl;
contact = aligned->getAutoTarget();
cdebug_log(146,0) << "contact: " << contact << endl;
cdebug_log(145,0) << "contact: " << contact << endl;
if (contact) {
cdebug_log(146,0) << "Apply to (target): " << contact << endl;
cdebug_log(145,0) << "Apply to (target): " << contact << endl;
contact->restrictConstraintBox( constraintBox.getYMin()
, constraintBox.getYMax()
, Flags::Horizontal|Flags::WarnOnError );
}
contact = aligned->getAutoSource();
cdebug_log(146,0) << "contact: " << contact << endl;
cdebug_log(145,0) << "contact: " << contact << endl;
if (contact) {
cdebug_log(146,0) << "Apply to (source): " << contact << endl;
cdebug_log(145,0) << "Apply to (source): " << contact << endl;
contact->restrictConstraintBox( constraintBox.getYMin()
, constraintBox.getYMax()
, Flags::Horizontal|Flags::WarnOnError );
@ -118,23 +118,23 @@ namespace {
}
// Propagate constraint through vertically aligned segments.
cdebug_log(146,0) << "Propagate constraint on vertical segments" << endl;
cdebug_log(145,0) << "Propagate constraint on vertical segments" << endl;
for ( AutoSegment* vertical : verticalSegments ) {
AutoContact* contact = NULL;
for ( AutoSegment* aligned : vertical->getAligneds(Flags::WithSelf) ) {
cdebug_log(146,0) << "aligned vertical: " << aligned << endl;
cdebug_log(145,0) << "aligned vertical: " << aligned << endl;
contact = aligned->getAutoTarget();
if (contact) {
cdebug_log(146,0) << "Apply to (target): " << contact << endl;
cdebug_log(145,0) << "Apply to (target): " << contact << endl;
contact->restrictConstraintBox( constraintBox.getXMin()
, constraintBox.getXMax()
, Flags::Vertical|Flags::WarnOnError );
}
contact = aligned->getAutoSource();
if (contact) {
cdebug_log(146,0) << "Apply to (source): " << contact << endl;
cdebug_log(145,0) << "Apply to (source): " << contact << endl;
contact->restrictConstraintBox( constraintBox.getXMin()
, constraintBox.getXMax()
, Flags::Vertical|Flags::WarnOnError );
@ -144,8 +144,8 @@ namespace {
}
}
cdebug_log(146,0) << "propagateConstraintFromRp() - Exit" << endl;
cdebug_tabw(146,-1);
cdebug_log(145,0) << "propagateConstraintFromRp() - Exit" << endl;
cdebug_tabw(145,-1);
}
@ -159,128 +159,35 @@ namespace Anabatic {
using Hurricane::Cell;
void propagateDistanceFromRp ( RoutingPad* rp )
{
cdebug_log(146,1) << "propagateDistanceFromRp() - " << rp << endl;
unsigned int distance = 0;
vector< pair<AutoContact*,AutoSegment*> > currents;
vector< pair<AutoContact*,AutoSegment*> > successors;
for ( Component* component : rp->getSlaveComponents() ) {
cdebug_log(146,0) << "slave component: " << component << endl;
AutoContact* sourceContact = Session::lookup( dynamic_cast<Contact*>(component) );
if (sourceContact) {
cdebug_log(146,0) << "Start slave: " << sourceContact << endl;
for ( AutoSegment* segment : sourceContact->getAutoSegments() ) {
cdebug_log(146,0) << "Pushing: " << segment << endl;
currents.push_back( make_pair(sourceContact,segment) );
}
}
}
while ( not currents.empty() ) {
for ( size_t i = 0 ; i<currents.size() ; ++i ) {
AutoContact* source = currents[i].first;
AutoSegment* segment = currents[i].second;
if ( (distance == 1) and (segment->getRpDistance() == 1) ) {
vector<GCell*> gcells;
segment->getGCells( gcells );
if (gcells.size() < 3)
segment->setFlags( AutoSegment::SegUnbreakable );
}
if (distance >= segment->getRpDistance()) continue;
segment->setRpDistance( distance );
cdebug_log(146,0) << "Popped: " << segment << endl;
AutoContact* target = segment->getOppositeAnchor( source );
if (target) {
for ( AutoSegment* successor : target->getAutoSegments() ) {
if (successor == segment) continue;
// if (successor->isNonPref()) {
// cdebug_log(146,0) << "Pushing (non-pref): " << successor << endl;
// currents.push_back( make_pair(target,successor) );
// } else {
cdebug_log(146,0) << "Pushing: " << successor << endl;
successors.push_back( make_pair(target,successor) );
// }
}
}
}
if (++distance > 15) break;
currents.clear();
currents.swap( successors );
}
cdebug_log(146,0) << "propagateDistanceFromRp() - Exit" << endl;
cdebug_tabw(146,-1);
}
void AnabaticEngine::computeNetConstraints ( Net* net )
{
DebugSession::open( net, 146, 150);
DebugSession::open( net, 145, 150);
cdebug_log(149,0) << "Anabatic::computeNetConstraints( " << net << " )" << endl;
cdebug_tabw(146,1);
cdebug_tabw(145,1);
vector<RoutingPad*> routingPads;
for ( Component* component : net->getComponents() ) {
Contact* contact = dynamic_cast<Contact*>( component );
forEach ( Component*, icomponent, net->getComponents() ) {
Contact* contact = dynamic_cast<Contact*>( *icomponent );
if (contact) {
AutoContact* autoContact = Session::lookup( contact );
if (autoContact)
autoContact->restoreNativeConstraintBox();
} else {
Segment* segment = dynamic_cast<Segment*>( component );
if (segment) {
AutoSegment* autoSegment = Session::lookup( segment );
if (autoSegment)
autoSegment->setRpDistance( 15 );
} else {
RoutingPad* routingPad = dynamic_cast<RoutingPad*>( component );
if (routingPad) routingPads.push_back( routingPad );
}
RoutingPad* routingPad = dynamic_cast<RoutingPad*>( *icomponent );
if (routingPad) routingPads.push_back( routingPad );
}
}
for ( size_t i=0 ; i<routingPads.size() ; i++ ) {
for ( size_t i=0 ; i<routingPads.size() ; i++ )
propagateConstraintFromRp( routingPads[i] );
propagateDistanceFromRp ( routingPads[i] );
}
for ( Segment* segment : net->getSegments() ) {
AutoSegment* autoSegment = Session::lookup( segment );
if (not autoSegment) continue;
if (autoSegment->isUnbreakable()) continue;
if (autoSegment->getRpDistance() >= 2) continue;
if (autoSegment->getRpDistance() == 1) continue;
vector<GCell*> gcells;
autoSegment->getGCells( gcells );
if (gcells.size() > 2) continue;
//if ( (gcells.size() == 2)
// and ( not autoSegment->getAutoSource()->isTerminal()
// or not autoSegment->getAutoTarget()->isTerminal()) ) continue;
autoSegment->setFlags( AutoSegment::SegUnbreakable );
}
// forEach ( Segment*, isegment, net->getSegments() ) {
// AutoSegment* autoSegment = Session::lookup( *isegment );
// if (autoSegment) autoSegment->toConstraintAxis();
// }
cdebug_tabw(146,-1);
cdebug_tabw(145,-1);
DebugSession::close();
}

View File

@ -35,7 +35,6 @@ namespace Anabatic {
using Hurricane::RegularLayer;
using Hurricane::Component;
using Hurricane::Pin;
using Hurricane::Plug;
using Hurricane::DeepNet;
using Hurricane::Cell;
using Hurricane::NetRoutingExtension;
@ -83,38 +82,19 @@ namespace Anabatic {
if (net->getType() == Net::Type::GROUND) continue;
// Don't skip the clock.
vector<Pin*> pins;
vector<Segment*> segments;
vector<Contact*> contacts;
bool isManualGlobalRouted = false;
bool isManualDetailRouted = false;
bool isFixed = false;
size_t rpCount = 0;
bool isPreRouted = false;
bool isFixed = false;
size_t rpCount = 0;
for( Component* component : net->getComponents() ) {
Pin* pin = dynamic_cast<Pin *>( component );
if (pin) {
pins.push_back( pin );
continue;
}
if (dynamic_cast<Plug*>(component)) continue;
if (dynamic_cast<Pin*>(component)) continue;
const RegularLayer* layer = dynamic_cast<const RegularLayer*>(component->getLayer());
if (layer and (layer->getBasicLayer()->getMaterial() == BasicLayer::Material::blockage))
continue;
if ( not Session::isGaugeLayer(component->getLayer())
and not Session::isGLayer (component->getLayer())) {
const BasicLayer* basicLayer = dynamic_cast<const BasicLayer*>( component->getLayer() );
if (basicLayer and (basicLayer->getMaterial() == BasicLayer::Material::cut))
continue;
throw Error( "AnabaticEngine::setupPreRouted(): A component of \"%s\" has a routing gauge umanaged layer.\n"
" (%s)"
, getString(net->getName()).c_str()
, getString(component).c_str()
);
}
continue;
Horizontal* horizontal = dynamic_cast<Horizontal*>(component);
if (horizontal) {
@ -122,77 +102,47 @@ namespace Anabatic {
and not ab.contains(horizontal->getTargetPosition()) ) continue;
segments.push_back( horizontal );
if (Session::isGLayer(component->getLayer())) {
isManualGlobalRouted = true;
} else {
isManualDetailRouted = true;
if (horizontal->getWidth() != Session::getWireWidth(horizontal->getLayer()))
isFixed = true;
}
isPreRouted = true;
if (horizontal->getWidth() != Session::getWireWidth(horizontal->getLayer()))
isFixed = true;
} else {
Vertical* vertical = dynamic_cast<Vertical*>(component);
if (vertical) {
if ( not ab.contains(vertical->getSourcePosition())
and not ab.contains(vertical->getTargetPosition()) ) continue;
if (Session::isGLayer(component->getLayer())) {
isManualGlobalRouted = true;
} else {
isManualDetailRouted = true;
segments.push_back( vertical );
if (vertical->getWidth() != Session::getWireWidth(vertical->getLayer()))
isFixed = true;
}
isPreRouted = true;
segments.push_back( vertical );
if (vertical->getWidth() != Session::getWireWidth(vertical->getLayer()))
isFixed = true;
} else {
Pin* pin = dynamic_cast<Pin*>(component);
if (pin) {
//cerr << "| " << pin << endl;
if (not ab.intersect(pin->getBoundingBox())) continue;
pins.push_back( pin );
Contact* contact = dynamic_cast<Contact*>(component);
if (contact) {
if (not ab.contains(contact->getCenter())) continue;
isPreRouted = true;
contacts.push_back( contact );
if ( (contact->getWidth () != Session::getViaWidth(contact->getLayer()))
or (contact->getHeight() != Session::getViaWidth(contact->getLayer()))
or (contact->getLayer () == Session::getContactLayer(0)) )
isFixed = true;
} else {
Contact* contact = dynamic_cast<Contact*>(component);
if (contact) {
if (not ab.contains(contact->getCenter())) continue;
if (Session::isGLayer(component->getLayer())) {
isManualGlobalRouted = true;
} else {
isManualGlobalRouted = true;
contacts.push_back( contact );
if ( (contact->getWidth () != Session::getViaWidth(contact->getLayer()))
or (contact->getHeight() != Session::getViaWidth(contact->getLayer()))
or (contact->getLayer () == Session::getContactLayer(0)) )
isFixed = true;
}
RoutingPad* rp = dynamic_cast<RoutingPad*>(component);
if (rp) {
++rpCount;
} else {
RoutingPad* rp = dynamic_cast<RoutingPad*>(component);
if (rp) {
++rpCount;
} else {
// Plug* plug = dynamic_cast<Plug*>(component);
// if (plug) {
// cerr << "buildPreRouteds(): " << plug << endl;
// ++rpCount;
// }
}
// Plug* plug = dynamic_cast<Plug*>(component);
// if (plug) {
// cerr << "buildPreRouteds(): " << plug << endl;
// ++rpCount;
// }
}
}
}
}
}
// cerr << net << " deepNet:" << net->isDeepNet()
// << " pins:" << pins.size()
// << " segments:" << segments.size() << endl;
if (not net->isDeepNet() and (pins.size() >= 1) and (segments.size() < 2)) {
++toBeRouteds;
continue;
}
if ( (not isFixed)
and (not isManualGlobalRouted)
and (not isManualDetailRouted)
and net->isDeepNet()) {
if ((not isFixed and not isPreRouted) and net->isDeepNet()) {
Net* rootNet = dynamic_cast<Net*>(
dynamic_cast<DeepNet*>(net)->getRootNetOccurrence().getEntity() );
for( Component* component : rootNet->getComponents() ) {
@ -202,41 +152,32 @@ namespace Anabatic {
}
}
if (isFixed or isManualDetailRouted or isManualGlobalRouted or (rpCount < 2)) {
if (isFixed or isPreRouted or (rpCount < 2)) {
NetData* ndata = getNetData( net, Flags::Create );
NetRoutingState* state = ndata->getNetRoutingState();
state->unsetFlags( NetRoutingState::AutomaticGlobalRoute );
if (isManualGlobalRouted) {
state->setFlags( NetRoutingState::ManualGlobalRoute );
ndata->setGlobalFixed( true );
}
if (isManualDetailRouted)
state->setFlags( NetRoutingState::ManualDetailRoute );
state->setFlags ( NetRoutingState::ManualGlobalRoute );
ndata->setGlobalRouted( true );
if (rpCount < 2)
state->setFlags( NetRoutingState::Unconnected );
state->setFlags ( NetRoutingState::Unconnected );
if (isFixed) {
if (rpCount > 1)
cmess2 << " - <" << net->getName() << "> is fixed." << endl;
state->unsetFlags( NetRoutingState::ManualGlobalRoute|NetRoutingState::ManualDetailRoute );
state->unsetFlags( NetRoutingState::ManualGlobalRoute );
state->setFlags ( NetRoutingState::Fixed );
} else if (isManualGlobalRouted) {
cmess2 << " - <" << net->getName() << "> is manually global routed." << endl;
} else if (isManualDetailRouted) {
} else {
if (rpCount > 1) {
++toBeRouteds;
cmess2 << " - <" << net->getName() << "> is manually detail routed." << endl;
for ( auto contact : contacts ) {
AutoContact::createFrom( contact );
cmess2 << " - <" << net->getName() << "> is manually global routed." << endl;
for ( auto icontact : contacts ) {
AutoContact::createFrom( icontact );
}
for ( auto segment : segments ) {
AutoContact* source = Session::lookup( dynamic_cast<Contact*>( segment->getSource() ));
AutoContact* target = Session::lookup( dynamic_cast<Contact*>( segment->getTarget() ));
if (not source or not target) {
cerr << Error( "Unable to protect %s", getString(segment).c_str() ) << endl;
continue;
}
AutoSegment* autoSegment = AutoSegment::create( source, target, segment );
autoSegment->setFlags( AutoSegment::SegUserDefined|AutoSegment::SegAxisSet );
}

View File

@ -16,7 +16,7 @@
#include "hurricane/isobar/PyHurricane.h"
#include "hurricane/isobar/PyCell.h"
#include "anabatic/PyStyleFlags.h"
#include "anabatic/Constants.h"
namespace Anabatic {
@ -55,41 +55,19 @@ extern "C" {
};
static PyModuleDef PyAnabatic_ModuleDef =
{ PyModuleDef_HEAD_INIT
, "Anabatic" /* m_name */
, "Low level database for global & detailed routing."
/* m_doc */
, -1 /* m_size */
, PyAnabatic_Methods /* m_methods */
, NULL /* m_reload */
, NULL /* m_traverse */
, NULL /* m_clear */
, NULL /* m_free */
};
// ---------------------------------------------------------------
// Module Initialization : "initAnabatic ()"
PyMODINIT_FUNC PyInit_Anabatic ( void )
{
cdebug_log(32,0) << "PyInit_Anabatic()" << endl;
DL_EXPORT(void) initAnabatic () {
cdebug_log(32,0) << "initAnabatic()" << endl;
PyStyleFlags_LinkPyType();
PYTYPE_READY( StyleFlags );
PyObject* module = PyModule_Create( &PyAnabatic_ModuleDef );
PyObject* module = Py_InitModule( "Anabatic", PyAnabatic_Methods );
if (module == NULL) {
cerr << "[ERROR]\n"
<< " Failed to initialize Anabatic module." << endl;
return NULL;
return;
}
Py_INCREF( &PyTypeStyleFlags );
PyModule_AddObject( module, "StyleFlags", (PyObject*)&PyTypeStyleFlags );
PyObject* dictionnary = PyModule_GetDict(module);
PyObject* constant;
@ -99,9 +77,6 @@ extern "C" {
LoadObjectConstant( dictionnary,EngineLayerAssignByTrunk ,"EngineLayerAssignByTrunk" );
LoadObjectConstant( dictionnary,EngineLayerAssignNoGlobalM2V,"EngineLayerAssignNoGlobalM2V" );
LoadObjectConstant( dictionnary,EngineNoNetLayerAssign ,"EngineNoNetLayerAssign" );
PyStyleFlags_postModuleInit();
return module;
}

View File

@ -1,123 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./PyStyleFlags.h" |
// +-----------------------------------------------------------------+
#include "anabatic/PyStyleFlags.h"
namespace Anabatic {
using std::cerr;
using std::endl;
using std::hex;
using std::ostringstream;
using Hurricane::tab;
using Hurricane::Error;
using Hurricane::Warning;
using Isobar::ProxyProperty;
using Isobar::ProxyError;
using Isobar::ConstructorError;
using Isobar::HurricaneError;
using Isobar::HurricaneWarning;
using Isobar::ParseOneArg;
using Isobar::ParseTwoArg;
using Isobar::getPyHash;
extern "C" {
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(StyleFlags,status,function)
// +=================================================================+
// | "PyStyleFlags" Python Module Code Part |
// +=================================================================+
#if defined(__PYTHON_MODULE__)
PyMethodDef PyStyleFlags_Methods[] =
{ {NULL, NULL, 0, NULL} /* sentinel */
};
PythonOnlyDeleteMethod(StyleFlags)
DirectReprMethod (PyStyleFlags_Repr, PyStyleFlags, StyleFlags)
DirectStrMethod (PyStyleFlags_Str, PyStyleFlags, StyleFlags)
DirectCmpByValueMethod(PyStyleFlags_Cmp, IsPyStyleFlags, PyStyleFlags)
DirectHashMethod (PyStyleFlags_Hash, StyleFlags)
extern void PyStyleFlags_LinkPyType() {
cdebug_log(20,0) << "PyStyleFlags_LinkType()" << endl;
PyTypeStyleFlags.tp_dealloc = (destructor) PyStyleFlags_DeAlloc;
PyTypeStyleFlags.tp_richcompare = (richcmpfunc)PyStyleFlags_Cmp;
PyTypeStyleFlags.tp_repr = (reprfunc) PyStyleFlags_Repr;
PyTypeStyleFlags.tp_str = (reprfunc) PyStyleFlags_Str;
PyTypeStyleFlags.tp_hash = (hashfunc) PyStyleFlags_Hash;
PyTypeStyleFlags.tp_methods = PyStyleFlags_Methods;
}
#else // End of Python Module Code Part.
// +=================================================================+
// | "PyStyleFlags" Shared Library Code Part |
// +=================================================================+
// Link/Creation Method.
PyTypeObjectDefinitions(StyleFlags)
extern void PyStyleFlags_postModuleInit ()
{
PyObject* constant = NULL;
LoadObjectConstant( PyTypeStyleFlags.tp_dict, (uint64_t)StyleFlags::NoStyle, "NoStyle" );
LoadObjectConstant( PyTypeStyleFlags.tp_dict, (uint64_t)StyleFlags::HV , "HV" );
LoadObjectConstant( PyTypeStyleFlags.tp_dict, (uint64_t)StyleFlags::VH , "VH" );
LoadObjectConstant( PyTypeStyleFlags.tp_dict, (uint64_t)StyleFlags::OTH , "OTH" );
LoadObjectConstant( PyTypeStyleFlags.tp_dict, (uint64_t)StyleFlags::Channel, "Channel" );
LoadObjectConstant( PyTypeStyleFlags.tp_dict, (uint64_t)StyleFlags::Hybrid , "Hybrid" );
}
#endif // Shared Library Code Part.
} // extern "C".
#if !defined(__PYTHON_MODULE__)
extern StyleFlags PyInt_AsStyleFlags ( PyObject* object )
{
uint64_t value = (uint64_t)Isobar::PyAny_AsLong( object );
if ( (value == (uint64_t)StyleFlags::NoStyle)
or (value == (uint64_t)StyleFlags::HV)
or (value == (uint64_t)StyleFlags::VH)
or (value == (uint64_t)StyleFlags::OTH)
or (value == (uint64_t)StyleFlags::Channel)
or (value == (uint64_t)StyleFlags::Hybrid))
return value;
return StyleFlags::NoStyle;
}
#endif
} // Isobar namespace.

View File

@ -82,12 +82,7 @@ namespace Anabatic {
, _segmentRevalidateds()
, _netInvalidateds ()
, _netRevalidateds ()
{
_autoContacts .reserve( 1024 );
_doglegs .reserve( 1024 );
_segmentInvalidateds.reserve( 1024 );
_segmentRevalidateds.reserve( 1024 );
}
{ }
void Session::_postCreate ()
@ -215,20 +210,16 @@ namespace Anabatic {
{
cdebug_log(145,1) << "Anabatic::Session::_revalidateTopology()" << endl;
_anabatic->disableCanonize();
for ( Net* net : _netInvalidateds ) {
cdebug_log(145,0) << "Anabatic::Session::_revalidateTopology(Net*)" << net << endl;
_anabatic->updateNetTopology ( net );
_anabatic->computeNetConstraints( net );
_anabatic->_computeNetOptimals ( net );
//_anabatic->_computeNetTerminals ( net );
_anabatic->_computeNetTerminals ( net );
}
_anabatic->enableCanonize();
_canonize ();
AutoSegment* segment = NULL;
for ( size_t i=0 ; i<_segmentInvalidateds.size() ; ++i ) {
segment = _segmentInvalidateds[i];
for ( AutoSegment* segment : _segmentInvalidateds ) {
if (segment->isCanonical()) {
if (segment->isUnsetAxis()) segment->toOptimalAxis();
else segment->toConstraintAxis();
@ -261,8 +252,6 @@ namespace Anabatic {
cdebug_log(145,0) << "_segmentInvalidateds.size(): " << _segmentInvalidateds.size() << endl;
_segmentRevalidateds.clear();
std::sort( _segmentInvalidateds.begin(), _segmentInvalidateds.end()
, AutoSegment::CompareByRevalidate() );
for ( size_t i=0 ; i < _segmentInvalidateds.size() ; ++i, ++count ) {
_segmentInvalidateds[i]->revalidate();
if ( not _destroyedSegments.empty()
@ -364,31 +353,6 @@ namespace Anabatic {
}
DbU::Unit Session::_getNearestTrackAxis ( const Layer* layer, DbU::Unit axis, uint32_t mode )
{
Box ab = _anabatic->getCell()->getAbutmentBox();
RoutingLayerGauge* lg = _routingGauge->getLayerGauge( layer );
if (not lg) return axis;
DbU::Unit minAxis = 0;
DbU::Unit maxAxis = 0;
if (lg->getDirection() == Constant::Horizontal) {
minAxis = ab.getYMin();
maxAxis = ab.getYMax();
} else {
minAxis = ab.getXMin();
maxAxis = ab.getXMax();
}
DbU::Unit trackAxis = lg->getTrackPosition( minAxis
, lg->getTrackIndex( minAxis
, maxAxis
, axis
, mode ) );
return trackAxis;
}
Point Session::_getNearestGridPoint ( Point p, Box constraint )
{
Box ab = _anabatic->getCell()->getAbutmentBox();
@ -412,25 +376,14 @@ namespace Anabatic {
if (y < constraint.getYMin()) y += lg->getPitch();
if (y > constraint.getYMax()) y -= lg->getPitch();
y = std::max( y, constraint.getYMin() );
y = std::min( y, constraint.getYMax() );
return Point(x,y);
}
StyleFlags Session::getRoutingStyle ()
{ return get("getRoutingStyle()")->_anabatic->getRoutingStyle(); }
bool Session::isInDemoMode ()
{ return get("isInDemoMode()")->_anabatic->isInDemoMode(); }
bool Session::isChannelStyle ()
{ return get("isChannelStyle()")->_anabatic->isChannelStyle(); }
float Session::getSaturateRatio ()
{ return get("getSaturateRatio()")->_anabatic->getSaturateRatio(); }

646
anabatic/src/anabatic/: Normal file
View File

@ -0,0 +1,646 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2018, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./anabatic/AutoSegment.h" |
// +-----------------------------------------------------------------+
#ifndef ANABATIC_AUTOSEGMENT_H
#define ANABATIC_AUTOSEGMENT_H
#include <set>
#include <iostream>
#include <functional>
#include "hurricane/Interval.h"
#include "hurricane/Segment.h"
#include "hurricane/Components.h"
#include "hurricane/Contact.h"
namespace Hurricane {
class Layer;
class Horizontal;
class Vertical;
class Cell;
}
#include "crlcore/RoutingGauge.h"
#include "anabatic/Constants.h"
#include "anabatic/GCell.h"
#include "anabatic/AutoSegments.h"
#include "anabatic/Session.h"
namespace Anabatic {
using std::array;
using std::set;
using std::cerr;
using std::endl;
using std::binary_function;
using Hurricane::StaticObservable;
using Hurricane::BaseObserver;
using Hurricane::tab;
using Hurricane::Interval;
using Hurricane::Layer;
using Hurricane::Components;
using Hurricane::Horizontal;
using Hurricane::Vertical;
using Hurricane::Cell;
using CRL::RoutingGauge;
class AutoHorizontal;
class AutoVertical;
// -------------------------------------------------------------------
// Class : "AutoSegment".
class AutoSegment {
friend class AutoHorizontal;
friend class AutoVertical;
public:
static const uint64_t SegNoFlags = 0L;
static const uint64_t SegHorizontal = (1L<< 0);
static const uint64_t SegFixed = (1L<< 1);
static const uint64_t SegFixedAxis = (1L<< 2);
static const uint64_t SegGlobal = (1L<< 3);
static const uint64_t SegWeakGlobal = (1L<< 4);
static const uint64_t SegLongLocal = (1L<< 5);
static const uint64_t SegCanonical = (1L<< 6);
static const uint64_t SegBipoint = (1L<< 7);
static const uint64_t SegDogleg = (1L<< 8);
static const uint64_t SegStrap = (1L<< 9);
static const uint64_t SegSourceTop = (1L<<10);
static const uint64_t SegSourceBottom = (1L<<11);
static const uint64_t SegTargetTop = (1L<<12);
static const uint64_t SegTargetBottom = (1L<<13);
static const uint64_t SegIsReduced = (1L<<14);
static const uint64_t SegDrag = (1L<<15);
static const uint64_t SegLayerChange = (1L<<16);
static const uint64_t SegSourceTerminal = (1L<<17); // Replace Terminal.
static const uint64_t SegTargetTerminal = (1L<<18); // Replace Terminal.
static const uint64_t SegStrongTerminal = SegSourceTerminal|SegTargetTerminal;
static const uint64_t SegWeakTerminal1 = (1L<<19); // Replace TopologicalEnd.
static const uint64_t SegWeakTerminal2 = (1L<<20); // Replace TopologicalEnd.
static const uint64_t SegNotSourceAligned = (1L<<21);
static const uint64_t SegNotTargetAligned = (1L<<22);
static const uint64_t SegUnbound = (1L<<23);
static const uint64_t SegHalfSlackened = (1L<<24);
static const uint64_t SegSlackened = (1L<<25);
static const uint64_t SegAxisSet = (1L<<26);
static const uint64_t SegInvalidated = (1L<<27);
static const uint64_t SegInvalidatedSource = (1L<<28);
static const uint64_t SegInvalidatedTarget = (1L<<29);
static const uint64_t SegInvalidatedLayer = (1L<<30);
static const uint64_t SegCreated = (1L<<31);
static const uint64_t SegUserDefined = (1L<<32);
static const uint64_t SegAnalog = (1L<<33);
static const uint64_t SegWide = (1L<<34);
// Masks.
static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2;
static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned;
static const uint64_t SegSpinTop = SegSourceTop |SegTargetTop;
static const uint64_t SegSpinBottom = SegSourceBottom |SegTargetBottom;
static const uint64_t SegDepthSpin = SegSpinTop |SegSpinBottom;
public:
class Observable : public StaticObservable<1> {
public:
enum Indexes { TrackSegment = 0
};
public:
inline Observable ();
private:
Observable ( const StaticObservable& );
Observable& operator= ( const StaticObservable& );
};
public:
enum ObserverFlag { Create = (1 << 0)
, Destroy = (1 << 1)
, Invalidate = (1 << 2)
, Revalidate = (1 << 3)
, RevalidatePPitch = (1 << 4)
};
public:
typedef std::function< void(AutoSegment*) > RevalidateCb_t;
public:
static void setAnalogMode ( bool );
static bool getAnalogMode ();
inline static DbU::Unit getViaToTopCap ( size_t depth );
inline static DbU::Unit getViaToBottomCap ( size_t depth );
inline static DbU::Unit getViaToSameCap ( size_t depth );
static AutoSegment* create ( AutoContact* source
, AutoContact* target
, Segment* hurricaneSegment
);
static AutoSegment* create ( AutoContact* source
, AutoContact* target
, Flags dir
, size_t depth=RoutingGauge::nlayerdepth
);
void destroy ();
// Wrapped Segment Functions.
virtual Segment* base () const = 0;
virtual Segment* base () = 0;
virtual Horizontal* getHorizontal () { return NULL; };
virtual Vertical* getVertical () { return NULL; };
inline Cell* getCell () const;
inline Net* getNet () const;
inline const Layer* getLayer () const;
inline Box getBoundingBox () const;
inline Hook* getSourceHook ();
inline Hook* getTargetHook ();
inline Contact* getSource () const;
inline Contact* getTarget () const;
inline Component* getOppositeAnchor ( Component* ) const;
inline Components getAnchors () const;
virtual DbU::Unit getX () const;
virtual DbU::Unit getY () const;
inline DbU::Unit getWidth () const;
inline DbU::Unit getContactWidth () const;
inline DbU::Unit getLength () const;
inline DbU::Unit getSourcePosition () const;
inline DbU::Unit getTargetPosition () const;
inline DbU::Unit getSourceX () const;
inline DbU::Unit getSourceY () const;
inline DbU::Unit getTargetX () const;
inline DbU::Unit getTargetY () const;
inline void invert ();
inline void setLayer ( const Layer* );
// Predicates.
inline bool isHorizontal () const;
inline bool isVertical () const;
inline bool isGlobal () const;
inline bool isWeakGlobal () const;
inline bool isLongLocal () const;
inline bool isLocal () const;
inline bool isFixed () const;
inline bool isFixedAxis () const;
inline bool isBipoint () const;
inline bool isWeakTerminal () const;
inline bool isWeakTerminal1 () const;
inline bool isWeakTerminal2 () const;
inline bool isTerminal () const;
inline bool isDrag () const;
inline bool isNotSourceAligned () const;
inline bool isNotTargetAligned () const;
inline bool isNotAligned () const;
bool isStrongTerminal ( Flags flags=Flags::NoFlags ) const;
inline bool isSourceTerminal () const;
inline bool isTargetTerminal () const;
inline bool isLayerChange () const;
inline bool isSpinTop () const;
inline bool isSpinBottom () const;
inline bool isSpinTopOrBottom () const;
inline bool isReduced () const;
inline bool isStrap () const;
inline bool isDogleg () const;
inline bool isUnbound () const;
inline bool isInvalidated () const;
inline bool isInvalidatedLayer () const;
inline bool isCreated () const;
inline bool isCanonical () const;
inline bool isUnsetAxis () const;
inline bool isSlackened () const;
inline bool isUserDefined () const;
bool isReduceCandidate () const;
bool isUTurn () const;
inline bool isAnalog () const;
inline bool isWide () const;
virtual bool _canSlacken () const = 0;
bool canReduce () const;
bool mustRaise () const;
Flags canDogleg ( Interval );
virtual bool canMoveULeft ( float reserve=0.0 ) const = 0;
virtual bool canMoveURight ( float reserve=0.0 ) const = 0;
bool canMoveUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
bool canPivotUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
bool canPivotDown ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
bool canSlacken ( Flags flags=Flags::NoFlags ) const;
virtual bool checkPositions () const = 0;
virtual bool checkConstraints () const = 0;
bool checkDepthSpin () const;
// Accessors.
inline unsigned long getId () const;
inline uint64_t getFlags () const;
virtual Flags getDirection () const = 0;
inline GCell* getGCell () const;
virtual bool getGCells ( vector<GCell*>& ) const = 0;
inline AutoContact* getAutoSource () const;
inline AutoContact* getAutoTarget () const;
AutoContact* getOppositeAnchor ( AutoContact* ) const;
size_t getPerpandicularsBound ( set<AutoSegment*>& );
inline AutoSegment* getParent () const;
inline unsigned int getDepth () const;
inline DbU::Unit getPitch () const;
DbU::Unit getPPitch () const;
#if DISABLED
DbU::Unit getExtensionCap () const;
#endif
DbU::Unit getExtensionCap ( Flags ) const;
inline DbU::Unit getAxis () const;
void getEndAxes ( DbU::Unit& sourceAxis, DbU::Unit& targetAxis ) const;
virtual DbU::Unit getSourceU () const = 0;
virtual DbU::Unit getTargetU () const = 0;
virtual DbU::Unit getDuSource () const = 0;
virtual DbU::Unit getDuTarget () const = 0;
inline DbU::Unit getOrigin () const;
inline DbU::Unit getExtremity () const;
virtual Interval getSpanU () const = 0;
Interval getMinSpanU () const;
virtual Interval getSourceConstraints ( Flags flags=Flags::NoFlags ) const = 0;
virtual Interval getTargetConstraints ( Flags flags=Flags::NoFlags ) const = 0;
virtual bool getConstraints ( DbU::Unit& min, DbU::Unit& max ) const = 0;
inline bool getConstraints ( Interval& i ) const;
inline const Interval& getUserConstraints () const;
inline const Interval& getNativeConstraints () const;
virtual DbU::Unit getSlack () const;
inline DbU::Unit getOptimalMin () const;
inline DbU::Unit getOptimalMax () const;
inline DbU::Unit getNativeMin () const;
inline DbU::Unit getNativeMax () const;
Interval& getOptimal ( Interval& i ) const;
virtual DbU::Unit getCost ( DbU::Unit axis ) const;
virtual AutoSegment* getCanonical ( DbU::Unit& min , DbU::Unit& max );
inline AutoSegment* getCanonical ( Interval& i );
float getMaxUnderDensity ( Flags flags );
// Modifiers.
inline void unsetFlags ( uint64_t );
inline void setFlags ( uint64_t );
void setFlagsOnAligneds ( uint64_t );
inline void incReduceds ();
inline void decReduceds ();
virtual void setDuSource ( DbU::Unit du ) = 0;
virtual void setDuTarget ( DbU::Unit du ) = 0;
void computeTerminal ();
virtual void updateOrient () = 0;
virtual void updatePositions () = 0;
virtual void updateNativeConstraints () = 0;
void updateSourceSpin ();
void updateTargetSpin ();
void sourceDetach ();
void targetDetach ();
void sourceAttach ( AutoContact* );
void targetAttach ( AutoContact* );
//inline void mergeUserConstraints ( const Interval& );
void mergeUserConstraints ( const Interval& );
inline void resetUserConstraints ();
inline void setOptimalMin ( DbU::Unit min );
inline void setOptimalMax ( DbU::Unit max );
inline void mergeNativeMin ( DbU::Unit min );
inline void mergeNativeMax ( DbU::Unit max );
inline void resetNativeConstraints ( DbU::Unit min, DbU::Unit max );
bool checkNotInvalidated () const;
inline void setParent ( AutoSegment* );
void revalidate ();
AutoSegment* makeDogleg ( AutoContact* );
Flags makeDogleg ( Interval, Flags flags=Flags::NoFlags );
Flags makeDogleg ( GCell* , Flags flags=Flags::NoFlags );
virtual Flags _makeDogleg ( GCell* , Flags flags ) = 0;
virtual bool moveULeft () = 0;
virtual bool moveURight () = 0;
bool slacken ( Flags flags );
virtual bool _slacken ( Flags flags ) = 0;
void _changeDepth ( unsigned int depth, Flags flags );
void changeDepth ( unsigned int depth, Flags flags );
bool moveUp ( Flags flags=Flags::NoFlags );
bool moveDown ( Flags flags=Flags::NoFlags );
bool reduceDoglegLayer ();
bool reduce ();
bool raise ();
// Canonical Modifiers.
AutoSegment* canonize ( Flags flags=Flags::NoFlags );
virtual void invalidate ( Flags flags=Flags::Propagate );
void invalidate ( AutoContact* );
void computeOptimal ( set<AutoSegment*>& processeds );
void setAxis ( DbU::Unit, Flags flags=Flags::NoFlags );
bool toConstraintAxis ( Flags flags=Flags::Realignate );
bool toOptimalAxis ( Flags flags=Flags::Realignate );
// Collections & Filters.
AutoSegments getOnSourceContact ( Flags direction );
AutoSegments getOnTargetContact ( Flags direction );
AutoSegments getCachedOnSourceContact ( Flags direction );
AutoSegments getCachedOnTargetContact ( Flags direction );
AutoSegments getAligneds ( Flags flags=Flags::NoFlags );
AutoSegments getConnecteds ( Flags flags=Flags::NoFlags );
AutoSegments getPerpandiculars ( Flags flags=Flags::NoFlags );
size_t getAlignedContacts ( map<AutoContact*,int>& ) const ;
// Observers.
template< typename OwnerT >
inline OwnerT* getObserver ( size_t slot );
inline void setObserver ( size_t slot, BaseObserver* );
inline void notify ( unsigned int flags );
// Inspector Management.
virtual Record* _getRecord () const = 0;
virtual string _getString () const = 0;
virtual string _getTypeName () const = 0;
// Non-reviewed atomic modifiers.
bool _check () const;
#if THIS_IS_DISABLED
virtual void desalignate ( AutoContact* ) = 0;
bool shearUp ( GCell*
, AutoSegment*& movedUp
, float reserve
, Flags flags );
#endif
protected:
// Internal: Static Attributes.
static size_t _allocateds;
static size_t _globalsCount;
static bool _analogMode;
static bool _initialized;
static vector< array<DbU::Unit*,3> > _extensionCaps;
// Internal: Attributes.
const unsigned long _id;
GCell* _gcell;
uint64_t _flags;
unsigned int _depth : 8;
unsigned int _optimalMin :16;
unsigned int _optimalMax :16;
unsigned int _reduceds : 2;
DbU::Unit _sourcePosition;
DbU::Unit _targetPosition;
Interval _userConstraints;
Interval _nativeConstraints;
AutoSegment* _parent;
Observable _observers;
// Internal: Constructors & Destructors.
protected:
AutoSegment ( Segment* segment );
virtual ~AutoSegment ();
static void _preCreate ( AutoContact* source, AutoContact* target );
virtual void _postCreate ();
virtual void _preDestroy ();
static void _initialize ();
private:
AutoSegment ( const AutoSegment& );
AutoSegment& operator= ( const AutoSegment& );
protected:
void _invalidate ();
inline uint64_t _getFlags () const;
std::string _getStringFlags () const;
virtual void _setAxis ( DbU::Unit ) = 0;
public:
struct CompareId : public binary_function<AutoSegment*,AutoSegment*,bool> {
inline bool operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const;
};
public:
struct CompareByDepthLength : public binary_function<AutoSegment*,AutoSegment*,bool> {
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
};
public:
struct CompareByDepthAxis : public binary_function<AutoSegment*,AutoSegment*,bool> {
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
};
public:
typedef std::set<AutoSegment*,CompareByDepthLength> DepthLengthSet;
typedef std::set<AutoSegment*,CompareId> IdSet;
// Static Utilities.
public:
static inline uint64_t swapSourceTargetFlags ( AutoSegment* );
static inline bool areAlignedsAndDiffLayer ( AutoSegment*, AutoSegment* );
static AutoSegment* getGlobalThroughDogleg ( AutoSegment* dogleg, AutoContact* from );
static bool isTopologicalBound ( AutoSegment* seed, Flags flags );
static inline bool arePerpandiculars ( AutoSegment* a, AutoSegment* b );
static inline bool arePerpandiculars ( bool isHorizontalA, AutoSegment* b );
static inline bool areAligneds ( AutoSegment* a, AutoSegment* b );
static Flags getPerpandicularState ( AutoContact* contact
, AutoSegment* source
, AutoSegment* current
, bool isHorizontalMaster
, const Layer* masterLayer=NULL
);
static inline Flags getPerpandicularState ( AutoContact* contact
, AutoSegment* source
, AutoSegment* current
, AutoSegment* master
);
static void getTopologicalInfos ( AutoSegment* seed
, vector<AutoSegment*>& collapseds
, vector<AutoSegment*>& perpandiculars
, DbU::Unit& leftBound
, DbU::Unit& rightBound
);
static int getTerminalCount ( AutoSegment* seed
, vector<AutoSegment*>& collapseds
);
static inline int getTerminalCount ( AutoSegment* seed );
static inline size_t getGlobalsCount ();
static inline size_t getAllocateds ();
static inline unsigned long getMaxId ();
};
// Inline Functions.
inline DbU::Unit AutoSegment::getViaToTopCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][0]) : 0; }
inline DbU::Unit AutoSegment::getViaToBottomCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][1]) : 0; }
inline DbU::Unit AutoSegment::getViaToSameCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][2]) : 0; }
inline unsigned long AutoSegment::getId () const { return _id; }
inline Cell* AutoSegment::getCell () const { return base()->getCell(); }
inline Net* AutoSegment::getNet () const { return base()->getNet(); }
inline const Layer* AutoSegment::getLayer () const { return base()->getLayer(); }
inline Box AutoSegment::getBoundingBox () const { return base()->getBoundingBox(); }
inline Hook* AutoSegment::getSourceHook () { return base()->getSourceHook(); }
inline Hook* AutoSegment::getTargetHook () { return base()->getTargetHook(); }
inline Contact* AutoSegment::getSource () const { return static_cast<Contact*>(base()->getSource()); }
inline Contact* AutoSegment::getTarget () const { return static_cast<Contact*>(base()->getTarget()); }
inline Component* AutoSegment::getOppositeAnchor ( Component* anchor ) const { return base()->getOppositeAnchor(anchor); };
inline AutoSegment* AutoSegment::getParent () const { return _parent; }
inline DbU::Unit AutoSegment::getSourcePosition () const { return _sourcePosition; }
inline DbU::Unit AutoSegment::getTargetPosition () const { return _targetPosition; }
inline DbU::Unit AutoSegment::getSourceX () const { return base()->getSourceX(); }
inline DbU::Unit AutoSegment::getSourceY () const { return base()->getSourceY(); }
inline DbU::Unit AutoSegment::getTargetX () const { return base()->getTargetX(); }
inline DbU::Unit AutoSegment::getTargetY () const { return base()->getTargetY(); }
inline DbU::Unit AutoSegment::getWidth () const { return base()->getWidth(); }
inline DbU::Unit AutoSegment::getLength () const { return base()->getLength(); }
inline void AutoSegment::invert () { base()->invert(); }
inline GCell* AutoSegment::getGCell () const { return _gcell; }
inline AutoContact* AutoSegment::getAutoSource () const { return Session::lookup(getSource()); }
inline AutoContact* AutoSegment::getAutoTarget () const { return Session::lookup(getTarget()); }
inline bool AutoSegment::getConstraints ( Interval& i ) const { return getConstraints(i.getVMin(),i.getVMax()); }
inline AutoSegment* AutoSegment::getCanonical ( Interval& i ) { return getCanonical(i.getVMin(),i.getVMax()); }
inline unsigned int AutoSegment::getDepth () const { return _depth; }
inline DbU::Unit AutoSegment::getPitch () const { return Session::getPitch(getDepth(),Flags::NoFlags); }
inline DbU::Unit AutoSegment::getAxis () const { return isHorizontal()?base()->getY():base()->getX(); }
inline DbU::Unit AutoSegment::getOrigin () const { return isHorizontal()?_gcell->getYMin():_gcell->getXMin(); }
inline DbU::Unit AutoSegment::getExtremity () const { return isHorizontal()?_gcell->getYMax():_gcell->getXMax(); }
inline DbU::Unit AutoSegment::getOptimalMin () const { return DbU::lambda(_optimalMin) + getOrigin(); }
inline DbU::Unit AutoSegment::getOptimalMax () const { return DbU::lambda(_optimalMax) + getOrigin(); }
inline DbU::Unit AutoSegment::getNativeMin () const { return _nativeConstraints.getVMin(); }
inline DbU::Unit AutoSegment::getNativeMax () const { return _nativeConstraints.getVMax(); }
inline const Interval& AutoSegment::getUserConstraints () const { return _userConstraints; }
inline const Interval& AutoSegment::getNativeConstraints () const { return _nativeConstraints; }
inline bool AutoSegment::isHorizontal () const { return _flags & SegHorizontal; }
inline bool AutoSegment::isVertical () const { return not (_flags & SegHorizontal); }
inline bool AutoSegment::isFixed () const { return _flags & SegFixed; }
inline bool AutoSegment::isFixedAxis () const { return _flags & SegFixedAxis; }
inline bool AutoSegment::isGlobal () const { return _flags & SegGlobal; }
inline bool AutoSegment::isWeakGlobal () const { return _flags & SegWeakGlobal; }
inline bool AutoSegment::isLongLocal () const { return _flags & SegLongLocal; }
inline bool AutoSegment::isLocal () const { return not (_flags & SegGlobal); }
inline bool AutoSegment::isBipoint () const { return _flags & SegBipoint; }
inline bool AutoSegment::isWeakTerminal () const { return _flags & SegWeakTerminal; }
inline bool AutoSegment::isWeakTerminal1 () const { return _flags & SegWeakTerminal1; }
inline bool AutoSegment::isWeakTerminal2 () const { return _flags & SegWeakTerminal2; }
inline bool AutoSegment::isSourceTerminal () const { return _flags & SegSourceTerminal; }
inline bool AutoSegment::isTargetTerminal () const { return _flags & SegTargetTerminal; }
inline bool AutoSegment::isTerminal () const { return _flags & SegStrongTerminal; }
inline bool AutoSegment::isDrag () const { return _flags & SegDrag; }
inline bool AutoSegment::isNotSourceAligned () const { return _flags & SegNotSourceAligned; }
inline bool AutoSegment::isNotTargetAligned () const { return _flags & SegNotTargetAligned; }
inline bool AutoSegment::isNotAligned () const { return (_flags & SegNotAligned) == SegNotAligned; }
inline bool AutoSegment::isDogleg () const { return _flags & SegDogleg ; }
inline bool AutoSegment::isUnbound () const { return _flags & SegUnbound ; }
inline bool AutoSegment::isStrap () const { return _flags & SegStrap; }
inline bool AutoSegment::isLayerChange () const { return _flags & SegLayerChange; }
inline bool AutoSegment::isSpinTop () const { return ((_flags & SegSpinTop ) == SegSpinTop); }
inline bool AutoSegment::isSpinBottom () const { return ((_flags & SegSpinBottom) == SegSpinBottom); }
inline bool AutoSegment::isSpinTopOrBottom () const { return isSpinTop() or isSpinBottom(); }
inline bool AutoSegment::isReduced () const { return _flags & SegIsReduced; }
inline bool AutoSegment::isSlackened () const { return _flags & SegSlackened; }
inline bool AutoSegment::isCanonical () const { return _flags & SegCanonical; }
inline bool AutoSegment::isUnsetAxis () const { return not (_flags & SegAxisSet); }
inline bool AutoSegment::isInvalidated () const { return _flags & SegInvalidated; }
inline bool AutoSegment::isInvalidatedLayer () const { return _flags & SegInvalidatedLayer; }
inline bool AutoSegment::isCreated () const { return _flags & SegCreated; }
inline bool AutoSegment::isUserDefined () const { return _flags & SegUserDefined; }
inline bool AutoSegment::isAnalog () const { return _flags & SegAnalog; }
inline bool AutoSegment::isWide () const { return _flags & SegWide; }
inline void AutoSegment::setFlags ( uint64_t flags ) { _flags |= flags; }
inline void AutoSegment::unsetFlags ( uint64_t flags ) { _flags &= ~flags; }
inline uint64_t AutoSegment::getFlags () const { return _flags; }
inline uint64_t AutoSegment::_getFlags () const { return _flags; }
inline void AutoSegment::incReduceds () { if (_reduceds<3) ++_reduceds; }
inline void AutoSegment::decReduceds () { if (_reduceds>0) --_reduceds; }
inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); _flags|=SegInvalidatedLayer; }
inline void AutoSegment::setOptimalMin ( DbU::Unit min ) { _optimalMin = (unsigned int)DbU::getLambda(min-getOrigin()); }
inline void AutoSegment::setOptimalMax ( DbU::Unit max ) { _optimalMax = (unsigned int)DbU::getLambda(max-getOrigin()); }
inline void AutoSegment::mergeNativeMin ( DbU::Unit min ) { _nativeConstraints.getVMin() = std::max( min, _nativeConstraints.getVMin() ); }
inline void AutoSegment::mergeNativeMax ( DbU::Unit max ) { _nativeConstraints.getVMax() = std::min( max, _nativeConstraints.getVMax() ); }
inline void AutoSegment::resetNativeConstraints ( DbU::Unit min, DbU::Unit max ) { _nativeConstraints = Interval( min, max ); }
//inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); }
inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); }
inline DbU::Unit AutoSegment::getContactWidth () const
{ return getWidth() + Session::getViaWidth(getLayer()) - Session::getWireWidth(getLayer()); }
inline void AutoSegment::setParent ( AutoSegment* parent )
{
if ( parent == this ) {
cerr << "Parentage Looping: " << parent->_getString() << endl;
}
_parent = parent;
}
inline bool AutoSegment::CompareId::operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const
{ return lhs->getId() < rhs->getId(); }
inline uint64_t AutoSegment::swapSourceTargetFlags ( AutoSegment* segment )
{
uint64_t segFlags = segment->getFlags();
uint64_t swapFlags = segment->getFlags() & ~(SegSourceTop |SegTargetTop
|SegSourceBottom |SegTargetBottom
|SegSourceTerminal |SegTargetTerminal
|SegNotSourceAligned |SegNotTargetAligned
|SegInvalidatedSource|SegInvalidatedTarget
);
swapFlags |= (segFlags & SegSourceTop ) ? SegTargetTop : SegNoFlags;
swapFlags |= (segFlags & SegSourceBottom ) ? SegTargetBottom : SegNoFlags;
swapFlags |= (segFlags & SegSourceTerminal ) ? SegTargetTerminal : SegNoFlags;
swapFlags |= (segFlags & SegNotSourceAligned ) ? SegNotTargetAligned : SegNoFlags;
swapFlags |= (segFlags & SegInvalidatedSource) ? SegInvalidatedTarget : SegNoFlags;
swapFlags |= (segFlags & SegTargetTop ) ? SegSourceTop : SegNoFlags;
swapFlags |= (segFlags & SegTargetBottom ) ? SegSourceBottom : SegNoFlags;
swapFlags |= (segFlags & SegTargetTerminal ) ? SegSourceTerminal : SegNoFlags;
swapFlags |= (segFlags & SegNotTargetAligned ) ? SegNotSourceAligned : SegNoFlags;
swapFlags |= (segFlags & SegInvalidatedTarget) ? SegInvalidatedSource : SegNoFlags;
return swapFlags;
}
inline bool AutoSegment::areAlignedsAndDiffLayer ( AutoSegment* s1, AutoSegment* s2 )
{ return s1 and s2
and (s1->isHorizontal() == s2->isHorizontal())
and (s1->getLayer() != s2->getLayer()); }
inline bool AutoSegment::arePerpandiculars ( AutoSegment* a, AutoSegment* b )
{ return a and b and (a->isHorizontal() != b->isHorizontal()); }
inline bool AutoSegment::arePerpandiculars ( bool isHorizontalA, AutoSegment* b )
{ return b and (isHorizontalA != b->isHorizontal()); }
inline bool AutoSegment::areAligneds ( AutoSegment* a, AutoSegment* b )
{ return a and b and (a->isHorizontal() == b->isHorizontal()); }
inline Flags AutoSegment::getPerpandicularState ( AutoContact* contact
, AutoSegment* source
, AutoSegment* current
, AutoSegment* master )
{
return getPerpandicularState ( contact, source, current, master->isHorizontal(), master->getLayer() );
}
inline int AutoSegment::getTerminalCount ( AutoSegment* seed )
{
cdebug_log(145,0) << "getTerminalCount() - " << seed << endl;
vector<AutoSegment*> collapseds;
vector<AutoSegment*> perpandiculars;
DbU::Unit leftBound;
DbU::Unit rightBound;
getTopologicalInfos ( seed
, collapseds
, perpandiculars
, leftBound
, rightBound
);
return getTerminalCount ( seed, collapseds );
}
inline size_t AutoSegment::getGlobalsCount () { return _globalsCount; }
inline size_t AutoSegment::getAllocateds () { return _allocateds; }
inline void AutoSegment::setObserver ( size_t slot, BaseObserver* observer )
{ _observers.setObserver( slot, observer ); }
template<typename OwnerT>
inline OwnerT* AutoSegment::getObserver ( size_t slot )
{ return _observers.getObserver<OwnerT>(slot); }
inline void AutoSegment::notify ( unsigned int flags )
{ _observers.notify( flags ); }
inline AutoSegment::Observable::Observable () : StaticObservable<1>() { }
} // End of Anabatic namespace.
INSPECTOR_P_SUPPORT(Anabatic::AutoSegment);
# endif // ANABATIC_AUTOSEGMENT_H

View File

@ -14,16 +14,20 @@
// +-----------------------------------------------------------------+
#pragma once
#ifndef ANABATIC_ANABATIC_ENGINE_H
#define ANABATIC_ANABATIC_ENGINE_H
#include <memory>
#include <string>
#include <vector>
#include <set>
#include "hurricane/NetRoutingProperty.h"
namespace Hurricane {
class Instance;
class CellViewer;
}
#include "crlcore/ToolEngine.h"
#include "anabatic/Configuration.h"
#include "anabatic/Matrix.h"
@ -45,7 +49,6 @@ namespace Anabatic {
using Hurricane::NetRoutingState;
using CRL::ToolEngine;
class NetBuilder;
class AnabaticEngine;
@ -65,8 +68,6 @@ namespace Anabatic {
};
public:
RawGCellsUnder ( const AnabaticEngine*, Segment* );
RawGCellsUnder ( const AnabaticEngine*, Point source, Point target );
void commonCtor ( const AnabaticEngine*, Point source, Point target );
inline bool empty () const;
inline size_t size () const;
inline GCell* gcellAt ( size_t ) const;
@ -101,66 +102,54 @@ namespace Anabatic {
class NetData {
public:
NetData ( Net*, AnabaticEngine* );
NetData ( Net* );
inline bool isGlobalEstimated () const;
inline bool isGlobalRouted () const;
inline bool isGlobalFixed () const;
inline bool isMixedPreRoute () const;
inline bool isFixed () const;
inline bool isExcluded () const;
inline bool isNoMoveUp ( Segment* ) const;
inline Net* getNet () const;
inline NetRoutingState* getNetRoutingState () const;
inline const Box& getSearchArea () const;
inline DbU::Unit getHalfPerimeter () const;
inline size_t getRpCount () const;
inline size_t getDiodeRpCount () const;
inline DbU::Unit getSparsity () const;
inline void setNetRoutingState ( NetRoutingState* );
inline void setSearchArea ( Box );
inline void setGlobalEstimated ( bool );
inline void setGlobalRouted ( bool );
inline void setGlobalFixed ( bool );
inline void setExcluded ( bool );
inline void setRpCount ( size_t );
inline void setNoMoveUp ( Segment* );
private:
NetData ( const NetData& );
NetData& operator= ( const NetData& );
inline void _update ();
private:
Net* _net;
NetRoutingState* _state;
Box _searchArea;
size_t _rpCount;
size_t _diodeCount;
DbU::Unit _sparsity;
Flags _flags;
std::set<Segment*,DBo::CompareById> _noMoveUp;
Net* _net;
NetRoutingState* _state;
Box _searchArea;
size_t _rpCount;
DbU::Unit _sparsity;
Flags _flags;
};
inline bool NetData::isGlobalEstimated () const { return _flags & Flags::GlobalEstimated; }
inline bool NetData::isGlobalRouted () const { return _flags & Flags::GlobalRouted; }
inline bool NetData::isGlobalFixed () const { return _flags & Flags::GlobalFixed; }
inline bool NetData::isMixedPreRoute () const { return (_state) ? _state->isMixedPreRoute() : false; }
inline bool NetData::isFixed () const { return (_state) ? _state->isFixed () : false; }
inline bool NetData::isExcluded () const { return _flags & Flags::ExcludeRoute; }
inline bool NetData::isNoMoveUp ( Segment* segment ) const { return (_noMoveUp.find(segment) != _noMoveUp.end()); }
inline Net* NetData::getNet () const { return _net; }
inline NetRoutingState* NetData::getNetRoutingState () const { return _state; }
inline const Box& NetData::getSearchArea () const { return _searchArea; }
inline DbU::Unit NetData::getHalfPerimeter () const { return (_searchArea.isEmpty()) ? 0.0 : (_searchArea.getWidth()+_searchArea.getHeight()); }
inline size_t NetData::getRpCount () const { return _rpCount; }
inline size_t NetData::getDiodeRpCount () const { return _diodeCount; }
inline void NetData::setNetRoutingState ( NetRoutingState* state ) { _state=state; }
inline DbU::Unit NetData::getSparsity () const { return _sparsity; }
inline void NetData::setGlobalEstimated ( bool state ) { _flags.set(Flags::GlobalEstimated,state); }
inline void NetData::setGlobalRouted ( bool state ) { _flags.set(Flags::GlobalRouted ,state); }
inline void NetData::setGlobalFixed ( bool state ) { _flags.set(Flags::GlobalFixed ,state); }
inline void NetData::setExcluded ( bool state ) { _flags.set(Flags::ExcludeRoute ,state); }
inline void NetData::setRpCount ( size_t count ) { _rpCount=count; _update(); }
inline void NetData::setNoMoveUp ( Segment* segment ) { _noMoveUp.insert(segment); }
inline void NetData::_update ()
@ -172,12 +161,7 @@ namespace Anabatic {
inline bool operator() ( const NetData* lhs, const NetData* rhs ) const
{
if (lhs->isMixedPreRoute() != rhs->isMixedPreRoute()) return lhs->isMixedPreRoute();
if ((lhs->getRpCount() > 10) or (rhs->getRpCount() > 10)) {
if (lhs->getRpCount() != rhs->getRpCount())
return lhs->getRpCount() > rhs->getRpCount();
}
if (lhs->getSparsity() != rhs->getSparsity()) return lhs->getSparsity() < rhs->getSparsity();
if (lhs->getSparsity() != rhs->getSparsity() ) return lhs->getSparsity() < rhs->getSparsity();
return lhs->getNet()->getId() < rhs->getNet()->getId();
}
};
@ -192,33 +176,22 @@ namespace Anabatic {
class AnabaticEngine : public ToolEngine {
public:
static const uint32_t DigitalMode = (1 << 0);
static const uint32_t AnalogMode = (1 << 1);
static const uint32_t MixedMode = (1 << 2);
static const uint32_t AverageHVDensity = 1; // Average between all densities.
static const uint32_t AverageHDensity = 2; // Average between all H densities.
static const uint32_t AverageVDensity = 3; // Average between all V densities.
static const uint32_t MaxHVDensity = 4; // Maximum between average H and average V.
static const uint32_t MaxVDensity = 5; // Maximum of V densities.
static const uint32_t MaxHDensity = 6; // Maximum of H densities.
static const uint32_t MaxDensity = 7; // Maximum of H & V densities.
enum DensityMode { AverageHVDensity=1 // Average between all densities.
, AverageHDensity =2 // Average between all H densities.
, AverageVDensity =3 // Average between all V densities.
, MaxHVDensity =4 // Maximum between average H and average V.
, MaxVDensity =5 // Maximum of V densities.
, MaxHDensity =6 // Maximum of H densities.
, MaxDensity =7 // Maximum of H & V densities.
};
public:
typedef ToolEngine Super;
public:
static AnabaticEngine* create ( Cell* );
static AnabaticEngine* get ( const Cell* );
inline bool isCanonizeDisabled () const;
inline bool isDigitalMode () const;
inline bool isAnalogMode () const;
inline bool isMixedMode () const;
inline bool isChannelStyle () const;
inline bool isHybridStyle () const;
static const Name& staticGetName ();
virtual const Name& getName () const;
virtual Configuration* getConfiguration ();
virtual const Configuration* getConfiguration () const;
inline std::string getNetBuilderStyle () const;
inline StyleFlags getRoutingStyle () const;
inline uint64_t getDensityMode () const;
inline CellViewer* getViewer () const;
inline void setViewer ( CellViewer* );
@ -230,7 +203,6 @@ namespace Anabatic {
inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const;
inline GCell* getGCellUnder ( Point ) const;
inline GCellsUnder getGCellsUnder ( Segment* ) const;
inline GCellsUnder getGCellsUnder ( Point source, Point target ) const;
inline Edges getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags=Flags::NorthPath ) const;
Interval getUSide ( Flags direction ) const;
int getCapacity ( Interval, Flags ) const;
@ -238,8 +210,6 @@ namespace Anabatic {
virtual void openSession ();
inline void setState ( EngineState state );
inline void setDensityMode ( uint64_t );
inline void disableCanonize ();
inline void enableCanonize ();
inline void addOv ( Edge* );
inline void removeOv ( Edge* );
inline const NetDatas& getNetDatas () const;
@ -248,7 +218,6 @@ namespace Anabatic {
void exclude ( const Name& netName );
void exclude ( Net* );
void updateMatrix ();
bool checkPlacement () const;
// Dijkstra related functions.
inline int getStamp () const;
inline int incStamp ();
@ -266,30 +235,21 @@ namespace Anabatic {
inline bool doDestroyBaseContact () const;
inline bool doDestroyBaseSegment () const;
inline bool doDestroyTool () const;
inline DbU::Unit getAntennaGateMaxWL () const;
inline DbU::Unit getAntennaDiodeMaxWL () const;
inline DbU::Unit getGlobalThreshold () const;
inline float getSaturateRatio () const;
inline size_t getSaturateRp () const;
inline DbU::Unit getExtensionCap () const;
inline Cell* getDiodeCell () const;
inline Net* getBlockageNet () const;
inline const ChipTools& getChipTools () const;
inline const vector<NetData*>& getNetOrdering () const;
void invalidateRoutingPads ();
void updateDensity ();
size_t checkGCellDensities ();
void setupNetBuilder ();
inline void setRoutingMode ( uint32_t );
inline void resetRoutingMode ( uint32_t );
inline void setGlobalThreshold ( DbU::Unit );
inline void setSaturateRatio ( float );
inline void setSaturateRp ( size_t );
inline void setBlockageNet ( Net* );
void chipPrep ();
void computeEdgeCapacities ( int maxHCap, int maxVCap, int termSatThreshold, int maxTermSat );
void antennaProtect ( Net*, uint32_t& failed, uint32_t& total );
void antennaProtect ();
void setupSpecialNets ();
size_t setupPreRouteds ();
void loadGlobalRouting ( uint32_t method );
@ -299,7 +259,6 @@ namespace Anabatic {
bool moveUpNetTrunk ( AutoSegment*, set<Net*>& globalNets, GCell::Set& invalidateds );
void layerAssign ( uint32_t method );
void finalizeLayout ();
void exportExternalNets ();
inline const AutoContactLut& _getAutoContactLut () const;
inline const AutoSegmentLut& _getAutoSegmentLut () const;
void _link ( AutoContact* );
@ -347,15 +306,12 @@ namespace Anabatic {
virtual void _postCreate ();
virtual void _preDestroy ();
void _gutAnabatic ();
virtual Configuration* _createConfiguration ();
private:
AnabaticEngine ( const AnabaticEngine& );
AnabaticEngine& operator= ( const AnabaticEngine& );
private:
static Name _toolName;
protected:
Configuration* _configuration;
private:
ChipTools _chipTools;
EngineState _state;
Matrix _matrix;
@ -366,71 +322,53 @@ namespace Anabatic {
CellViewer* _viewer;
Flags _flags;
int _stamp;
uint32_t _routingMode;
uint64_t _densityMode;
AutoSegmentLut _autoSegmentLut;
AutoContactLut _autoContactLut;
EdgeCapacityLut _edgeCapacitiesLut;
Net* _blockageNet;
Cell* _diodeCell;
};
inline bool AnabaticEngine::isDigitalMode () const { return (_routingMode & DigitalMode); };
inline bool AnabaticEngine::isAnalogMode () const { return (_routingMode & AnalogMode); };
inline bool AnabaticEngine::isMixedMode () const { return (_routingMode & MixedMode); };
inline bool AnabaticEngine::isChannelStyle () const { return (_configuration->getRoutingStyle() & StyleFlags::Channel); };
inline bool AnabaticEngine::isHybridStyle () const { return (_configuration->getRoutingStyle() & StyleFlags::Hybrid); };
inline void AnabaticEngine::setRoutingMode ( uint32_t mode ) { _routingMode |= mode; };
inline void AnabaticEngine::resetRoutingMode ( uint32_t mode ) { _routingMode &= ~mode; };
inline EngineState AnabaticEngine::getState () const { return _state; }
inline void AnabaticEngine::setState ( EngineState state ) { _state = state; }
inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; }
inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; }
inline const Matrix* AnabaticEngine::getMatrix () const { return &_matrix; }
inline const vector<GCell*>& AnabaticEngine::getGCells () const { return _gcells; }
inline const vector<Edge*>& AnabaticEngine::getOvEdges () const { return _ovEdges; }
inline GCell* AnabaticEngine::getSouthWestGCell () const { return _gcells[0]; }
inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); }
inline GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); }
inline GCellsUnder AnabaticEngine::getGCellsUnder ( Segment* s ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,s) ); }
inline GCellsUnder AnabaticEngine::getGCellsUnder ( Point source, Point target ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,source,target) ); }
inline Edges AnabaticEngine::getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags ) const { return new Path_Edges(source,target,pathFlags); }
inline uint64_t AnabaticEngine::getDensityMode () const { return _densityMode; }
inline void AnabaticEngine::setDensityMode ( uint64_t mode ) { _densityMode=mode; }
inline void AnabaticEngine::setBlockageNet ( Net* net ) { _blockageNet = net; }
inline const AutoContactLut& AnabaticEngine::_getAutoContactLut () const { return _autoContactLut; }
inline const AutoSegmentLut& AnabaticEngine::_getAutoSegmentLut () const { return _autoSegmentLut; }
inline const Flags& AnabaticEngine::flags () const { return _flags; }
inline Flags& AnabaticEngine::flags () { return _flags; }
inline bool AnabaticEngine::doDestroyBaseContact () const { return _flags & Flags::DestroyBaseContact; }
inline bool AnabaticEngine::doDestroyBaseSegment () const { return _flags & Flags::DestroyBaseSegment; }
inline bool AnabaticEngine::doDestroyTool () const { return _state >= EngineGutted; }
inline bool AnabaticEngine::doWarnOnGCellOverload () const { return _flags & Flags::WarnOnGCellOverload; }
inline bool AnabaticEngine::isCanonizeDisabled () const { return _flags & Flags::DisableCanonize; }
inline bool AnabaticEngine::isInDemoMode () const { return _flags & Flags::DemoMode; }
inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); }
inline std::string AnabaticEngine::getNetBuilderStyle () const { return _configuration->getNetBuilderStyle(); }
inline StyleFlags AnabaticEngine::getRoutingStyle () const { return _configuration->getRoutingStyle(); }
inline DbU::Unit AnabaticEngine::getAntennaGateMaxWL () const { return _configuration->getAntennaGateMaxWL(); }
inline DbU::Unit AnabaticEngine::getAntennaDiodeMaxWL () const { return _configuration->getAntennaDiodeMaxWL(); }
inline DbU::Unit AnabaticEngine::getGlobalThreshold () const { return _configuration->getGlobalThreshold(); }
inline float AnabaticEngine::getSaturateRatio () const { return _configuration->getSaturateRatio(); }
inline size_t AnabaticEngine::getSaturateRp () const { return _configuration->getSaturateRp(); }
inline void AnabaticEngine::setSaturateRatio ( float ratio ) { _configuration->setSaturateRatio(ratio); }
inline void AnabaticEngine::setSaturateRp ( size_t threshold ) { _configuration->setSaturateRp(threshold); }
inline Cell* AnabaticEngine::getDiodeCell () const { return _diodeCell; }
inline Net* AnabaticEngine::getBlockageNet () const { return _blockageNet; }
inline const ChipTools& AnabaticEngine::getChipTools () const { return _chipTools; }
inline const vector<NetData*>& AnabaticEngine::getNetOrdering () const { return _netOrdering; }
inline void AnabaticEngine::setGlobalThreshold ( DbU::Unit threshold ) { _configuration->setGlobalThreshold(threshold); }
inline const NetDatas& AnabaticEngine::getNetDatas () const { return _netDatas; }
inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); }
inline void AnabaticEngine::_resizeMatrix () { _matrix.resize( getCell(), getGCells() ); }
inline void AnabaticEngine::_updateGContacts ( Flags flags ) { for ( GCell* gcell : getGCells() ) gcell->updateGContacts(flags); }
inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; }
inline void AnabaticEngine::disableCanonize () { _flags |= Flags::DisableCanonize; }
inline void AnabaticEngine::enableCanonize () { _flags.reset( Flags::DisableCanonize ); }
inline EngineState AnabaticEngine::getState () const { return _state; }
inline void AnabaticEngine::setState ( EngineState state ) { _state = state; }
inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; }
inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; }
inline const Matrix* AnabaticEngine::getMatrix () const { return &_matrix; }
inline const vector<GCell*>& AnabaticEngine::getGCells () const { return _gcells; }
inline const vector<Edge*>& AnabaticEngine::getOvEdges () const { return _ovEdges; }
inline GCell* AnabaticEngine::getSouthWestGCell () const { return _gcells[0]; }
inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); }
inline GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); }
inline GCellsUnder AnabaticEngine::getGCellsUnder ( Segment* s ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,s) ); }
inline Edges AnabaticEngine::getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags ) const { return new Path_Edges(source,target,pathFlags); }
inline uint64_t AnabaticEngine::getDensityMode () const { return _densityMode; }
inline void AnabaticEngine::setDensityMode ( uint64_t mode ) { _densityMode=mode; }
inline void AnabaticEngine::setBlockageNet ( Net* net ) { _blockageNet = net; }
inline const AutoContactLut& AnabaticEngine::_getAutoContactLut () const { return _autoContactLut; }
inline const AutoSegmentLut& AnabaticEngine::_getAutoSegmentLut () const { return _autoSegmentLut; }
inline const Flags& AnabaticEngine::flags () const { return _flags; }
inline Flags& AnabaticEngine::flags () { return _flags; }
inline bool AnabaticEngine::doDestroyBaseContact () const { return _flags & Flags::DestroyBaseContact; }
inline bool AnabaticEngine::doDestroyBaseSegment () const { return _flags & Flags::DestroyBaseSegment; }
inline bool AnabaticEngine::doDestroyTool () const { return _state >= EngineGutted; }
inline bool AnabaticEngine::doWarnOnGCellOverload () const { return _flags & Flags::WarnOnGCellOverload; }
inline bool AnabaticEngine::isInDemoMode () const { return _flags & Flags::DemoMode; }
inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); }
inline DbU::Unit AnabaticEngine::getGlobalThreshold () const { return _configuration->getGlobalThreshold(); }
inline float AnabaticEngine::getSaturateRatio () const { return _configuration->getSaturateRatio(); }
inline size_t AnabaticEngine::getSaturateRp () const { return _configuration->getSaturateRp(); }
inline void AnabaticEngine::setSaturateRatio ( float ratio ) { _configuration->setSaturateRatio(ratio); }
inline void AnabaticEngine::setSaturateRp ( size_t threshold ) { _configuration->setSaturateRp(threshold); }
inline Net* AnabaticEngine::getBlockageNet () const { return _blockageNet; }
inline const ChipTools& AnabaticEngine::getChipTools () const { return _chipTools; }
inline const vector<NetData*>& AnabaticEngine::getNetOrdering () const { return _netOrdering; }
inline void AnabaticEngine::setGlobalThreshold ( DbU::Unit threshold ) { _configuration->setGlobalThreshold(threshold); }
inline const NetDatas& AnabaticEngine::getNetDatas () const { return _netDatas; }
inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); }
inline void AnabaticEngine::_resizeMatrix () { _matrix.resize( getCell(), getGCells() ); }
inline void AnabaticEngine::_updateGContacts ( Flags flags ) { for ( GCell* gcell : getGCells() ) gcell->updateGContacts(flags); }
inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; }
inline void AnabaticEngine::_add ( GCell* gcell )
{
@ -469,3 +407,5 @@ namespace Anabatic {
INSPECTOR_P_SUPPORT(Anabatic::AnabaticEngine);
#endif // ANABATIC_ANABATIC_ENGINE_H

View File

@ -71,8 +71,6 @@ namespace Anabatic {
, CntOnVertical = (1 << 14)
, CntOnHorizontal = (1 << 15)
, CntDrag = (1 << 16)
, CntHDogleg = (1 << 17)
, CntVDogleg = (1 << 18)
};
class AutoContact {
@ -121,9 +119,6 @@ namespace Anabatic {
inline bool isVTee () const;
inline bool isFixed () const;
inline bool isUserNativeConstraints () const;
inline bool isHDogleg () const;
inline bool isVDogleg () const;
virtual bool isOnPin () const;
inline bool hasBadTopology () const;
bool canDestroy ( Flags flags=Flags::NoFlags ) const;
bool canMoveUp ( const AutoSegment* moved ) const;
@ -164,7 +159,6 @@ namespace Anabatic {
virtual void cacheDetach ( AutoSegment* ) = 0;
virtual void cacheAttach ( AutoSegment* ) = 0;
virtual void updateCache () = 0;
void updateLayer ();
void updateSize ();
virtual void updateGeometry () = 0;
virtual void updateTopology () = 0;
@ -265,8 +259,6 @@ namespace Anabatic {
inline bool AutoContact::isTerminal () const { return _flags&CntTerminal; }
inline bool AutoContact::isHTee () const { return _flags&CntHTee; }
inline bool AutoContact::isVTee () const { return _flags&CntVTee; }
inline bool AutoContact::isHDogleg () const { return _flags&CntHDogleg; }
inline bool AutoContact::isVDogleg () const { return _flags&CntVDogleg; }
inline bool AutoContact::hasBadTopology () const { return _flags&CntBadTopology; }
inline bool AutoContact::canDrag () const { return _flags&CntDrag; }
inline size_t AutoContact::getId () const { return _id; }

View File

@ -60,7 +60,6 @@ namespace Anabatic {
virtual void _invalidate ( Flags flags );
public:
bool isEndPoint () const;
virtual bool isOnPin () const;
virtual Box getNativeConstraintBox () const;
RoutingPad* getRoutingPad () const;
inline AutoSegment* getSegment () const;

View File

@ -14,9 +14,11 @@
// +-----------------------------------------------------------------+
#pragma once
#include "hurricane/Horizontal.h"
#include "anabatic/AutoSegment.h"
#ifndef ANABATIC_AUTOHORIZONTAL_H
#define ANABATIC_AUTOHORIZONTAL_H
#include "hurricane/Horizontal.h"
#include "anabatic/AutoSegment.h"
namespace Anabatic {
@ -89,3 +91,6 @@ namespace Anabatic {
INSPECTOR_P_SUPPORT(Anabatic::AutoHorizontal);
#endif // ANABATIC_AUTOHORIZONTAL_H

View File

@ -14,8 +14,9 @@
// +-----------------------------------------------------------------+
#pragma once
#include <tuple>
#ifndef ANABATIC_AUTOSEGMENT_H
#define ANABATIC_AUTOSEGMENT_H
#include <set>
#include <iostream>
#include <functional>
@ -38,7 +39,6 @@ namespace Hurricane {
namespace Anabatic {
using std::tuple;
using std::array;
using std::set;
using std::cerr;
@ -58,10 +58,11 @@ namespace Anabatic {
class AutoHorizontal;
class AutoVertical;
// -------------------------------------------------------------------
// Class : "AutoSegment".
class AutoSegment {
friend class AutoHorizontal;
friend class AutoVertical;
@ -105,11 +106,6 @@ namespace Anabatic {
static const uint64_t SegAnalog = (1L<<33);
static const uint64_t SegWide = (1L<<34);
static const uint64_t SegShortNet = (1L<<35);
static const uint64_t SegUnbreakable = (1L<<36);
static const uint64_t SegNonPref = (1L<<37);
static const uint64_t SegAtMinArea = (1L<<38);
static const uint64_t SegNoMoveUp = (1L<<39);
static const uint64_t SegOnVSmall = (1L<<40);
// Masks.
static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2;
static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned;
@ -144,7 +140,6 @@ namespace Anabatic {
inline static DbU::Unit getViaToTopCap ( size_t depth );
inline static DbU::Unit getViaToBottomCap ( size_t depth );
inline static DbU::Unit getViaToSameCap ( size_t depth );
inline static DbU::Unit getMinimalLength ( size_t depth );
static AutoSegment* create ( AutoContact* source
, AutoContact* target
, Segment* hurricaneSegment
@ -175,8 +170,6 @@ namespace Anabatic {
inline DbU::Unit getWidth () const;
inline DbU::Unit getContactWidth () const;
inline DbU::Unit getLength () const;
inline DbU::Unit getSpanLength () const;
inline DbU::Unit getAnchoredLength () const;
inline DbU::Unit getSourcePosition () const;
inline DbU::Unit getTargetPosition () const;
inline DbU::Unit getSourceX () const;
@ -201,11 +194,7 @@ namespace Anabatic {
inline bool isWeakTerminal1 () const;
inline bool isWeakTerminal2 () const;
inline bool isTerminal () const;
inline bool isUnbreakable () const;
inline bool isNonPref () const;
inline bool isNonPrefOnVSmall () const;
inline bool isDrag () const;
inline bool isAtMinArea () const;
inline bool isNotSourceAligned () const;
inline bool isNotTargetAligned () const;
inline bool isNotAligned () const;
@ -213,7 +202,6 @@ namespace Anabatic {
inline bool isSourceTerminal () const;
inline bool isTargetTerminal () const;
inline bool isLayerChange () const;
inline bool isStackedStrap () const;
inline bool isSpinTop () const;
inline bool isSpinBottom () const;
inline bool isSpinTopOrBottom () const;
@ -228,15 +216,13 @@ namespace Anabatic {
inline bool isUnsetAxis () const;
inline bool isSlackened () const;
inline bool isUserDefined () const;
bool isNearMinArea () const;
bool isReduceCandidate () const;
bool isUTurn () const;
inline bool isAnalog () const;
inline bool isWide () const;
inline bool isShortNet () const;
inline bool isNoMoveUp () const;
virtual bool _canSlacken () const = 0;
bool canReduce ( Flags flags=Flags::WithPerpands ) const;
bool canReduce () const;
bool mustRaise () const;
Flags canDogleg ( Interval );
virtual bool canMoveULeft ( float reserve=0.0 ) const = 0;
@ -259,7 +245,6 @@ namespace Anabatic {
AutoContact* getOppositeAnchor ( AutoContact* ) const;
size_t getPerpandicularsBound ( set<AutoSegment*>& );
inline AutoSegment* getParent () const;
inline unsigned int getRpDistance () const;
inline unsigned int getDepth () const;
inline DbU::Unit getPitch () const;
DbU::Unit getPPitch () const;
@ -293,13 +278,10 @@ namespace Anabatic {
virtual AutoSegment* getCanonical ( DbU::Unit& min , DbU::Unit& max );
inline AutoSegment* getCanonical ( Interval& i );
float getMaxUnderDensity ( Flags flags );
inline uint32_t getReduceds () const;
uint32_t getNonReduceds ( Flags flags=Flags::WithPerpands ) const;
// Modifiers.
inline void unsetFlags ( uint64_t );
inline void setFlags ( uint64_t );
void setFlagsOnAligneds ( uint64_t );
inline void setRpDistance ( unsigned int );
inline void incReduceds ();
inline void decReduceds ();
virtual void setDuSource ( DbU::Unit du ) = 0;
@ -338,11 +320,8 @@ namespace Anabatic {
bool moveUp ( Flags flags=Flags::NoFlags );
bool moveDown ( Flags flags=Flags::NoFlags );
bool reduceDoglegLayer ();
bool bloatStackedStrap ();
bool reduce ( Flags flags=Flags::WithPerpands );
bool reduce ();
bool raise ();
void expandToMinLength ( Interval );
void unexpandToMinLength ();
// Canonical Modifiers.
AutoSegment* canonize ( Flags flags=Flags::NoFlags );
virtual void invalidate ( Flags flags=Flags::Propagate );
@ -386,16 +365,15 @@ namespace Anabatic {
static bool _analogMode;
static bool _shortNetMode;
static bool _initialized;
static vector< array<DbU::Unit*,4> > _extensionCaps;
static vector< array<DbU::Unit*,3> > _extensionCaps;
// Internal: Attributes.
const unsigned long _id;
GCell* _gcell;
uint64_t _flags;
unsigned int _depth : 8;
unsigned int _optimalMin :16;
unsigned int _optimalMax :16;
unsigned int _reduceds : 2;
unsigned int _rpDistance : 4;
unsigned int _depth : 8;
unsigned int _optimalMin :16;
unsigned int _optimalMax :16;
unsigned int _reduceds : 2;
DbU::Unit _sourcePosition;
DbU::Unit _targetPosition;
Interval _userConstraints;
@ -436,13 +414,6 @@ namespace Anabatic {
struct CompareBySourceU : public binary_function<AutoSegment*,AutoSegment*,bool> {
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
};
public:
struct CompareByRevalidate : public binary_function<AutoSegment*,AutoSegment*,bool> {
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
};
struct CompareByReduceds : public binary_function<AutoSegment*,AutoSegment*,bool> {
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
};
public:
typedef std::set<AutoSegment*,CompareByDepthLength> DepthLengthSet;
typedef std::set<AutoSegment*,CompareId> IdSet;
@ -469,8 +440,7 @@ namespace Anabatic {
);
static void getTopologicalInfos ( AutoSegment* seed
, vector<AutoSegment*>& collapseds
, vector< tuple<AutoSegment*,Flags> >&
perpandiculars
, vector<AutoSegment*>& perpandiculars
, DbU::Unit& leftBound
, DbU::Unit& rightBound
);
@ -488,7 +458,6 @@ namespace Anabatic {
inline DbU::Unit AutoSegment::getViaToTopCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][0]) : 0; }
inline DbU::Unit AutoSegment::getViaToBottomCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][1]) : 0; }
inline DbU::Unit AutoSegment::getViaToSameCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][2]) : 0; }
inline DbU::Unit AutoSegment::getMinimalLength ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][3]) : 0; }
inline unsigned long AutoSegment::getId () const { return _id; }
inline Cell* AutoSegment::getCell () const { return base()->getCell(); }
inline Net* AutoSegment::getNet () const { return base()->getNet(); }
@ -515,7 +484,6 @@ namespace Anabatic {
inline bool AutoSegment::getConstraints ( Interval& i ) const { return getConstraints(i.getVMin(),i.getVMax()); }
inline AutoSegment* AutoSegment::getCanonical ( Interval& i ) { return getCanonical(i.getVMin(),i.getVMax()); }
inline unsigned int AutoSegment::getDepth () const { return _depth; }
inline unsigned int AutoSegment::getRpDistance () const { return _rpDistance; }
inline DbU::Unit AutoSegment::getPitch () const { return Session::getPitch(getDepth(),Flags::NoFlags); }
inline DbU::Unit AutoSegment::getAxis () const { return isHorizontal()?base()->getY():base()->getX(); }
inline DbU::Unit AutoSegment::getOrigin () const { return isHorizontal()?_gcell->getYMin():_gcell->getXMin(); }
@ -526,7 +494,6 @@ namespace Anabatic {
inline DbU::Unit AutoSegment::getNativeMax () const { return _nativeConstraints.getVMax(); }
inline const Interval& AutoSegment::getUserConstraints () const { return _userConstraints; }
inline const Interval& AutoSegment::getNativeConstraints () const { return _nativeConstraints; }
inline uint32_t AutoSegment::getReduceds () const { return _reduceds; }
inline bool AutoSegment::isHorizontal () const { return _flags & SegHorizontal; }
inline bool AutoSegment::isVertical () const { return not (_flags & SegHorizontal); }
@ -536,18 +503,14 @@ namespace Anabatic {
inline bool AutoSegment::isWeakGlobal () const { return _flags & SegWeakGlobal; }
inline bool AutoSegment::isLongLocal () const { return _flags & SegLongLocal; }
inline bool AutoSegment::isLocal () const { return not (_flags & SegGlobal); }
inline bool AutoSegment::isUnbreakable () const { return _flags & SegUnbreakable; }
inline bool AutoSegment::isNonPref () const { return _flags & SegNonPref; }
inline bool AutoSegment::isNonPrefOnVSmall () const { return (_flags & SegNonPref) and (_flags & SegOnVSmall); }
inline bool AutoSegment::isBipoint () const { return _flags & SegBipoint; }
inline bool AutoSegment::isWeakTerminal () const { return (_rpDistance < 2); }
inline bool AutoSegment::isWeakTerminal1 () const { return (_rpDistance == 1); }
inline bool AutoSegment::isWeakTerminal2 () const { return (_rpDistance == 2); }
inline bool AutoSegment::isWeakTerminal () const { return _flags & SegWeakTerminal; }
inline bool AutoSegment::isWeakTerminal1 () const { return _flags & SegWeakTerminal1; }
inline bool AutoSegment::isWeakTerminal2 () const { return _flags & SegWeakTerminal2; }
inline bool AutoSegment::isSourceTerminal () const { return _flags & SegSourceTerminal; }
inline bool AutoSegment::isTargetTerminal () const { return _flags & SegTargetTerminal; }
inline bool AutoSegment::isTerminal () const { return (_rpDistance == 0); }
inline bool AutoSegment::isTerminal () const { return _flags & SegStrongTerminal; }
inline bool AutoSegment::isDrag () const { return _flags & SegDrag; }
inline bool AutoSegment::isAtMinArea () const { return _flags & SegAtMinArea; }
inline bool AutoSegment::isNotSourceAligned () const { return _flags & SegNotSourceAligned; }
inline bool AutoSegment::isNotTargetAligned () const { return _flags & SegNotTargetAligned; }
inline bool AutoSegment::isNotAligned () const { return (_flags & SegNotAligned) == SegNotAligned; }
@ -569,13 +532,11 @@ namespace Anabatic {
inline bool AutoSegment::isAnalog () const { return _flags & SegAnalog; }
inline bool AutoSegment::isWide () const { return _flags & SegWide; }
inline bool AutoSegment::isShortNet () const { return _flags & SegShortNet; }
inline bool AutoSegment::isNoMoveUp () const { return _flags & SegNoMoveUp; }
inline void AutoSegment::setFlags ( uint64_t flags ) { _flags |= flags; }
inline void AutoSegment::unsetFlags ( uint64_t flags ) { _flags &= ~flags; }
inline uint64_t AutoSegment::getFlags () const { return _flags; }
inline uint64_t AutoSegment::_getFlags () const { return _flags; }
inline void AutoSegment::setRpDistance ( unsigned int distance ) { _rpDistance=distance; }
inline void AutoSegment::incReduceds () { if (_reduceds<3) ++_reduceds; }
inline void AutoSegment::decReduceds () { if (_reduceds>0) --_reduceds; }
inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); _flags|=SegInvalidatedLayer; }
@ -587,7 +548,7 @@ namespace Anabatic {
inline void AutoSegment::resetNativeConstraints ( DbU::Unit min, DbU::Unit max ) { _nativeConstraints = Interval( min, max ); }
//inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); }
inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); }
inline DbU::Unit AutoSegment::getAnchoredLength () const { return std::abs(getTargetU() - getSourceU()); }
inline void AutoSegment::setLayer ( size_t depth )
{
@ -599,13 +560,10 @@ namespace Anabatic {
_flags|=SegInvalidatedLayer;
}
inline DbU::Unit AutoSegment::getContactWidth () const
{ return getWidth() + Session::getViaWidth(getLayer()) - Session::getWireWidth(getLayer()); }
inline DbU::Unit AutoSegment::getSpanLength () const
{ return getAnchoredLength() + getExtensionCap( Flags::Source|Flags::LayerCapOnly|Flags::NoMinLength )
+ getExtensionCap( Flags::Target|Flags::LayerCapOnly|Flags::NoMinLength );
}
inline void AutoSegment::setParent ( AutoSegment* parent )
{
@ -670,8 +628,7 @@ namespace Anabatic {
cdebug_log(145,0) << "getTerminalCount() - " << seed << endl;
vector<AutoSegment*> collapseds;
vector< tuple<AutoSegment*,Flags> >
perpandiculars;
vector<AutoSegment*> perpandiculars;
DbU::Unit leftBound;
DbU::Unit rightBound;
@ -707,3 +664,6 @@ namespace Anabatic {
INSPECTOR_P_SUPPORT(Anabatic::AutoSegment);
# endif // ANABATIC_AUTOSEGMENT_H

View File

@ -14,9 +14,11 @@
// +-----------------------------------------------------------------+
#pragma once
#include "hurricane/Vertical.h"
#include "anabatic/AutoSegment.h"
#ifndef ANABATIC_AUTOVERTICAL_H
#define ANABATIC_AUTOVERTICAL_H
#include "hurricane/Vertical.h"
#include "anabatic/AutoSegment.h"
namespace Anabatic {
@ -89,3 +91,6 @@ namespace Anabatic {
INSPECTOR_P_SUPPORT(Anabatic::AutoVertical);
#endif // ANABATIC_AUTOHORIZONTAL_H

View File

@ -14,7 +14,9 @@
// +-----------------------------------------------------------------+
#pragma once
#ifndef ANABATIC_CHIP_TOOLS_H
#define ANABATIC_CHIP_TOOLS_H
#include <string>
#include "hurricane/DbU.h"
#include "hurricane/Torus.h"
@ -111,4 +113,6 @@ namespace Anabatic {
} // Anabatic namespace.
INSPECTOR_PR_SUPPORT(Anabatic::ChipTools);
INSPECTOR_PV_SUPPORT(Anabatic::ChipTools);
#endif // ANABATIC_CHIP_TOOLS_H

View File

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "Configuration.h<anabatic>" -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2016-2022, All Rights Reserved
// Copyright (c) UPMC 2016-2018, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
@ -14,7 +14,9 @@
// +-----------------------------------------------------------------+
#pragma once
#ifndef ANABATIC_CONFIGURATION_H
#define ANABATIC_CONFIGURATION_H
#include <string>
#include <vector>
@ -62,15 +64,11 @@ namespace Anabatic {
virtual ~Configuration ();
virtual Configuration* clone () const;
// Methods.
inline bool isGLayer ( const Layer* ) const;
bool isGMetal ( const Layer* ) const;
bool isGContact ( const Layer* ) const;
bool isTwoMetals () const;
bool isHybrid () const;
bool isHV () const;
bool isVH () const;
inline std::string getNetBuilderStyle () const;
inline StyleFlags getRoutingStyle () const;
const Layer* getGContactLayer () const;
const Layer* getGHorizontalLayer () const;
const Layer* getGVerticalLayer () const;
@ -81,13 +79,11 @@ namespace Anabatic {
inline size_t getDVerticalDepth () const;
inline const Layer* getDVerticalLayer () const;
inline DbU::Unit getDVerticalWidth () const;
inline DbU::Unit getDPVerticalWidth () const;
inline DbU::Unit getDVerticalPitch () const;
inline DbU::Unit getDVerticalOffset () const;
inline size_t getDHorizontalDepth () const;
inline const Layer* getDHorizontalLayer () const;
inline DbU::Unit getDHorizontalWidth () const;
inline DbU::Unit getDPHorizontalWidth () const;
inline DbU::Unit getDHorizontalPitch () const;
inline DbU::Unit getDHorizontalOffset () const;
inline size_t getDContactDepth () const;
@ -107,20 +103,15 @@ namespace Anabatic {
DbU::Unit getPitch ( size_t depth, Flags flags ) const;
DbU::Unit getOffset ( size_t depth ) const;
DbU::Unit getWireWidth ( size_t depth ) const;
DbU::Unit getPWireWidth ( size_t depth ) const;
DbU::Unit getExtensionCap ( size_t depth ) const;
Flags getDirection ( size_t depth ) const;
DbU::Unit getPitch ( const Layer*, Flags flags ) const;
DbU::Unit getOffset ( const Layer* ) const;
DbU::Unit getWireWidth ( const Layer* ) const;
DbU::Unit getPWireWidth ( const Layer* ) const;
DbU::Unit getExtensionCap ( const Layer* ) const;
Flags getDirection ( const Layer* ) const;
float getSaturateRatio () const;
size_t getSaturateRp () const;
inline std::string getDiodeName () const;
inline DbU::Unit getAntennaGateMaxWL () const;
inline DbU::Unit getAntennaDiodeMaxWL () const;
DbU::Unit getGlobalThreshold () const;
void setAllowedDepth ( size_t );
void setSaturateRatio ( float );
@ -135,8 +126,6 @@ namespace Anabatic {
int getGlobalIterations () const;
DbU::Unit isOnRoutingGrid ( RoutingPad* ) const;
bool selectRpComponent ( RoutingPad* ) const;
inline void setRoutingStyle ( StyleFlags );
inline void resetRoutingStyle ( StyleFlags );
virtual void print ( Cell* ) const;
virtual Record* _getRecord () const;
virtual string _getString () const;
@ -151,8 +140,6 @@ namespace Anabatic {
size_t _ddepthv;
size_t _ddepthh;
size_t _ddepthc;
std::string _netBuilderStyle;
StyleFlags _routingStyle;
CellGauge* _cg;
RoutingGauge* _rg;
std::vector<DbU::Unit> _extensionCaps;
@ -167,18 +154,12 @@ namespace Anabatic {
float _edgeHInc;
float _edgeHScaling;
int _globalIterations;
std::string _diodeName;
DbU::Unit _antennaGateMaxWL;
DbU::Unit _antennaDiodeMaxWL;
private:
Configuration& operator= ( const Configuration& ) = delete;
void _setTopRoutingLayer ( Name name );
};
inline std::string Configuration::getNetBuilderStyle () const { return _netBuilderStyle; }
inline StyleFlags Configuration::getRoutingStyle () const { return _routingStyle; }
inline bool Configuration::isGLayer ( const Layer* layer ) const { return isGMetal(layer) or isGContact(layer); }
inline size_t Configuration::getGHorizontalDepth () const { return _gdepthh; }
inline size_t Configuration::getGVerticalDepth () const { return _gdepthv; }
inline DbU::Unit Configuration::getGHorizontalPitch () const { return getPitch( getGHorizontalDepth(), Flags::NoFlags ); }
@ -186,27 +167,22 @@ namespace Anabatic {
inline size_t Configuration::getDVerticalDepth () const { return _ddepthv; }
inline const Layer* Configuration::getDVerticalLayer () const { return getRoutingLayer( getDVerticalDepth() ); }
inline DbU::Unit Configuration::getDVerticalWidth () const { return getWireWidth ( getDVerticalDepth() ); }
inline DbU::Unit Configuration::getDPVerticalWidth () const { return getPWireWidth ( getDVerticalDepth() ); }
inline DbU::Unit Configuration::getDVerticalPitch () const { return getPitch ( getDVerticalDepth(), Flags::NoFlags ); }
inline DbU::Unit Configuration::getDVerticalOffset () const { return getOffset ( getDVerticalDepth() ); }
inline size_t Configuration::getDHorizontalDepth () const { return _ddepthh; }
inline const Layer* Configuration::getDHorizontalLayer () const { return getRoutingLayer( getDHorizontalDepth() ); }
inline DbU::Unit Configuration::getDHorizontalWidth () const { return getWireWidth ( getDHorizontalDepth() ); }
inline DbU::Unit Configuration::getDPHorizontalWidth () const { return getPWireWidth ( getDHorizontalDepth() ); }
inline DbU::Unit Configuration::getDHorizontalPitch () const { return getPitch ( getDHorizontalDepth(), Flags::NoFlags ); }
inline DbU::Unit Configuration::getDHorizontalOffset () const { return getOffset ( getDHorizontalDepth() ); }
inline size_t Configuration::getDContactDepth () const { return _ddepthc; }
inline const Layer* Configuration::getDContactLayer () const { return getContactLayer( getDContactDepth() ); }
inline DbU::Unit Configuration::getDContactWidth () const { return getWireWidth ( getDContactDepth() ); }
inline DbU::Unit Configuration::getDContactPitch () const { return getPitch ( getDContactDepth(), Flags::NoFlags ); }
inline std::string Configuration::getDiodeName () const { return _diodeName; }
inline DbU::Unit Configuration::getAntennaGateMaxWL () const { return _antennaGateMaxWL; }
inline DbU::Unit Configuration::getAntennaDiodeMaxWL () const { return _antennaDiodeMaxWL; }
inline void Configuration::setRoutingStyle ( StyleFlags flags ) { _routingStyle = flags; }
inline void Configuration::resetRoutingStyle ( StyleFlags flags ) { _routingStyle &= ~flags; }
} // Anabatic namespace.
INSPECTOR_P_SUPPORT(Anabatic::Configuration);
#endif // ANABATIC_CONFIGURATION_H

View File

@ -14,15 +14,14 @@
// +-----------------------------------------------------------------+
#pragma once
#ifndef ANABATIC_CONSTANTS_H
#define ANABATIC_CONSTANTS_H
#include "hurricane/Flags.h"
namespace Anabatic {
// -------------------------------------------------------------------
// Class : "Anabatic::Flags".
class Flags : public Hurricane::BaseFlags {
public:
static const BaseFlags NoFlags ; // = 0;
@ -44,7 +43,6 @@ namespace Anabatic {
static const BaseFlags ChannelRow ; // = (1 << 13);
static const BaseFlags HRailGCell ; // = (1 << 14);
static const BaseFlags VRailGCell ; // = (1 << 15);
static const BaseFlags GoStraight ; // = (1 << 16);
// Flags for Edge objects states only.
static const BaseFlags NullCapacity ; // = (1 << 5);
static const BaseFlags InfiniteCapacity ; // = (1 << 6);
@ -54,13 +52,10 @@ namespace Anabatic {
static const BaseFlags DestroyGCell ; // = (1 << 7);
static const BaseFlags DestroyBaseContact ; // = (1 << 8);
static const BaseFlags DestroyBaseSegment ; // = (1 << 9);
static const BaseFlags DisableCanonize ; // = (1 << 10);
// Flags for NetDatas objects states only.
static const BaseFlags GlobalFixed ; // = (1 << 5);
static const BaseFlags GlobalRouted ; // = (1 << 5);
static const BaseFlags GlobalEstimated ; // = (1 << 6);
static const BaseFlags GlobalRouted ; // = (1 << 7);
static const BaseFlags DetailRouted ; // = (1 << 8);
static const BaseFlags ExcludeRoute ; // = (1 << 9);
static const BaseFlags ExcludeRoute ; // = (1 << 7);
// Masks.
static const BaseFlags WestSide ; // = Horizontal|Target;
static const BaseFlags EastSide ; // = Horizontal|Source;
@ -104,13 +99,6 @@ namespace Anabatic {
static const BaseFlags CheckLowUpDensity ;
static const BaseFlags NoUpdate ;
static const BaseFlags NorthPath ;
static const BaseFlags UseNonPref ;
static const BaseFlags Force ;
static const BaseFlags LayerCapOnly ;
static const BaseFlags NoMinLength ;
static const BaseFlags NoSegExt ;
static const BaseFlags NullLength ;
static const BaseFlags OnVSmall ;
public:
inline Flags ( uint64_t flags = NoFlags );
inline Flags ( const Hurricane::BaseFlags& );
@ -125,39 +113,6 @@ namespace Anabatic {
Flags::Flags ( const Hurricane::BaseFlags& flags ) : BaseFlags(flags) { }
// -------------------------------------------------------------------
// Class : "Anabatic::StyleFlags".
class StyleFlags : public Hurricane::BaseFlags {
public:
static const BaseFlags NoStyle; // = 0;
static const BaseFlags HV ; // = (1 << 0);
static const BaseFlags VH ; // = (1 << 1);
static const BaseFlags OTH ; // = (1 << 2);
static const BaseFlags Channel; // = (1 << 3);
static const BaseFlags Hybrid ; // = (1 << 4);
public:
inline StyleFlags ( std::string );
inline StyleFlags ( uint64_t flags = NoStyle );
inline StyleFlags ( const Hurricane::BaseFlags& );
virtual ~StyleFlags ();
static StyleFlags toFlag ( std::string );
StyleFlags from ( std::string );
virtual std::string asString () const;
virtual std::string _getTypeName () const;
virtual std::string _getString () const;
};
StyleFlags::StyleFlags ( std::string textFlags ) : BaseFlags(NoStyle) { from(textFlags); }
StyleFlags::StyleFlags ( uint64_t flags ) : BaseFlags(flags) { }
StyleFlags::StyleFlags ( const Hurricane::BaseFlags& flags ) : BaseFlags(flags) { }
// -------------------------------------------------------------------
// Misc. enums.
enum FlagsMode { FlagsFunction = 1
};
@ -190,4 +145,6 @@ namespace Anabatic {
} // Anabatic namespace.
INSPECTOR_PR_SUPPORT(Anabatic::Flags);
INSPECTOR_PV_SUPPORT(Anabatic::Flags)
#endif // ANABATIC_CONSTANTS_H

View File

@ -14,7 +14,9 @@
// +-----------------------------------------------------------------+
#pragma once
#ifndef ANABATIC_DIJKSTRA_H
#define ANABATIC_DIJKSTRA_H
#include <set>
#include <iomanip>
#include "hurricane/Observer.h"
@ -187,7 +189,6 @@ namespace Anabatic {
, iHorizontal = (1<<7)
, iVertical = (1<<8)
, iSet = (1<<9)
, Driver = (1<<10)
};
public:
static DbU::Unit unreached;
@ -199,7 +200,6 @@ namespace Anabatic {
inline Vertex ( GCell* );
//inline Vertex ( size_t id );
inline ~Vertex ();
inline bool isDriver () const;
inline bool isAnalog () const;
inline bool hasDoneAllRps () const;
inline Contact* hasGContact ( Net* ) const;
@ -220,7 +220,6 @@ namespace Anabatic {
Edge* getFrom () const;
inline Vertex* getPredecessor () const;
inline Vertex* getNeighbor ( Edge* ) const;
inline void setDriver ( bool state );
inline void setDistance ( DbU::Unit );
inline void setStamp ( int );
inline void setConnexId ( int );
@ -334,7 +333,6 @@ namespace Anabatic {
inline Vertex* Vertex::lookup ( GCell* gcell ) { return gcell->getObserver<Vertex>(GCell::Observable::Vertex); }
inline Vertex::~Vertex () { _gcell->setObserver( GCell::Observable::Vertex, NULL ); }
inline bool Vertex::isDriver () const { return _flags & Driver; }
inline bool Vertex::isAnalog () const { return _gcell->isAnalog(); }
inline Box Vertex::getBoundingBox () const { return _gcell->getBoundingBox(); }
inline Edges Vertex::getEdges ( Flags sides ) const { return _gcell->getEdges(sides); }
@ -371,12 +369,6 @@ namespace Anabatic {
return (gcell) ? gcell->getObserver<Vertex>(GCell::Observable::Vertex) : NULL;
}
inline void Vertex::setDriver ( bool state )
{
if (state) _flags |= Driver;
else _flags &= ~Driver;
}
inline bool Vertex::CompareById::operator() ( const Vertex* lhs, const Vertex* rhs ) const
{ return lhs->getId() < rhs->getId(); }
@ -439,7 +431,7 @@ namespace Anabatic {
class CompareByDistance {
public:
inline CompareByDistance ();
bool operator() ( const Vertex* lhs, const Vertex* rhs ) const;
bool operator() ( const Vertex* lhs, const Vertex* rhs );
static inline void setQueue ( PriorityQueue* );
private:
static PriorityQueue* _pqueue;
@ -522,13 +514,11 @@ namespace Anabatic {
inline bool isSourceVertex ( Vertex* ) const;
inline Net* getNet () const;
inline bool isTargetVertex ( Vertex* ) const;
DbU::Unit getAntennaGateMaxWL () const;
inline DbU::Unit getSearchAreaHalo () const;
template<typename DistanceT>
inline DistanceT* setDistance ( DistanceT );
inline void setSearchAreaHalo ( DbU::Unit );
void load ( Net* net );
void loadFixedGlobal ( Net* net );
void run ( Mode mode=Mode::Standart );
inline const VertexSet& getSources () const;
private:
@ -603,4 +593,6 @@ namespace Anabatic {
GETSTRING_POINTER_SUPPORT(Anabatic::Vertex);
IOSTREAM_POINTER_SUPPORT(Anabatic::Vertex);
INSPECTOR_PR_SUPPORT(Anabatic::Dijkstra::Mode);
INSPECTOR_PV_SUPPORT(Anabatic::Dijkstra::Mode);
#endif // ANABATIC_DIJKSTRA_H

View File

@ -14,7 +14,9 @@
// +-----------------------------------------------------------------+
#pragma once
#ifndef ANABATIC_EDGE_H
#define ANABATIC_EDGE_H
#include <string>
#include "hurricane/Name.h"
#include "hurricane/Interval.h"
@ -58,7 +60,6 @@ namespace Anabatic {
inline bool isHorizontal () const;
inline bool hasNet ( const Net* ) const;
inline unsigned int getCapacity () const;
inline unsigned int getRawCapacity () const;
inline unsigned int getReservedCapacity () const;
inline unsigned int getCapacity ( size_t depth ) const;
inline unsigned int getRealOccupancy () const;
@ -135,8 +136,8 @@ namespace Anabatic {
inline bool Edge::isVertical () const { return _flags.isset(Flags::Vertical); }
inline bool Edge::isHorizontal () const { return _flags.isset(Flags::Horizontal); }
inline bool Edge::hasNet ( const Net* owner ) const { return getSegment(owner); }
inline unsigned int Edge::getCapacity () const { return (_capacities) ? _capacities->getCapacity()-_reservedCapacity : 0; }
inline unsigned int Edge::getCapacity ( size_t depth ) const { return (_capacities) ? _capacities->getCapacity(depth) : 0; }
inline unsigned int Edge::getRawCapacity () const { return (_capacities) ? _capacities->getCapacity() : 0; }
inline unsigned int Edge::getReservedCapacity () const { return _reservedCapacity; }
inline unsigned int Edge::getRealOccupancy () const { return _realOccupancy; }
inline float Edge::getEstimateOccupancy () const { return _estimateOccupancy; }
@ -155,14 +156,10 @@ namespace Anabatic {
inline Flags& Edge::flags () { return _flags; }
inline Flags& Edge::setFlags ( Flags mask ) { _flags |= mask; return _flags; }
inline void Edge::reserveCapacity ( int delta ) { _reservedCapacity = ((int)_reservedCapacity+delta > 0) ? _reservedCapacity+delta : 0; }
inline unsigned int Edge::getCapacity () const
{
if (not _capacities) return 0;
return (_capacities->getCapacity() > (int)_reservedCapacity) ? _capacities->getCapacity()-_reservedCapacity : 0;
}
} // Anabatic namespace.
INSPECTOR_P_SUPPORT(Anabatic::Edge);
#endif // ANABATIC_EDGE_H

View File

@ -14,9 +14,10 @@
// +-----------------------------------------------------------------+
#pragma once
#ifndef ANABATIC_GCELL_H
#define ANABATIC_GCELL_H
#include <vector>
#include <queue>
#include <string>
#include <set>
#include <functional>
@ -103,33 +104,25 @@ namespace Anabatic {
class CompareByDensity : public binary_function<GCell*,GCell*,bool> {
public:
CompareByDensity ( size_t depth );
inline bool operator() ( GCell* lhs, GCell* rhs ) const;
inline bool operator() ( GCell* lhs, GCell* rhs );
private:
size_t _depth;
};
class CompareByKey : public binary_function<const GCell*,const GCell*,bool> {
public:
inline bool operator() ( const GCell* lhs, const GCell* rhs ) const;
inline bool operator() ( const GCell* lhs, const GCell* rhs );
};
public:
class Key {
public:
inline Key ( const GCell*, size_t depth );
inline ~Key ();
inline float getDensity () const;
inline const GCell* getGCell () const;
inline bool isActive () const;
inline bool isSaturated () const;
inline void update ( size_t depth );
friend bool operator< ( const Key&, const Key& );
public:
class Compare {
public:
inline bool operator() ( const Key*, const Key* ) const;
};
inline Key ( GCell*, size_t depth );
inline float getDensity () const;
inline GCell* getGCell () const;
inline void update ( size_t depth );
friend bool operator< ( const Key&, const Key& );
private:
const GCell* _gcell;
float _density;
GCell* _gcell;
float _density;
};
public:
static uint32_t getDisplayMode ();
@ -140,7 +133,6 @@ namespace Anabatic {
public:
static GCell* create ( AnabaticEngine* );
public:
inline bool isSatProcessed ( size_t depth ) const;
inline bool isSaturated () const;
bool isSaturated ( size_t depth ) const;
inline bool isInvalidated () const;
@ -155,7 +147,6 @@ namespace Anabatic {
inline bool isMatrix () const;
inline bool isRow () const;
inline bool isIoPad () const;
inline bool isGoStraight () const;
inline bool isHRail () const;
inline bool isVRail () const;
inline bool isStdCellRow () const;
@ -164,7 +155,6 @@ namespace Anabatic {
bool isEast ( GCell* ) const;
bool isNorth ( GCell* ) const;
bool isSouth ( GCell* ) const;
bool hasNet ( const Net* ) const;
Contact* hasGContact ( const Contact* ) const;
Contact* hasGContact ( const Net* ) const;
bool isHorizontalPlane ( size_t depth ) const;
@ -216,8 +206,7 @@ namespace Anabatic {
bool doGrid ();
Contact* getGContact ( Net* );
inline const vector<Contact*>& getGContacts () const;
Segment* hasGoThrough ( Net* ) const;
Contact* breakGoThrough ( Net* );
Contact* breakGoThrough ( Net* net );
bool unrefContact ( Contact* );
void setSouthWestCorner ( DbU::Unit x, DbU::Unit y );
void cleanupGlobal ();
@ -227,7 +216,6 @@ namespace Anabatic {
bool hasFreeTrack ( size_t depth, float reserve ) const;
inline size_t getDepth () const;
size_t getNetCount () const;
inline int getRpCount () const;
int getHCapacity () const;
int getVCapacity () const;
int getCapacity ( size_t depth ) const;
@ -252,14 +240,9 @@ namespace Anabatic {
inline AutoSegments getStopSegments ( Flags direction );
size_t getRoutingPads ( set<RoutingPad*>& );
inline const Key& getKey () const;
inline Key* cloneKey ( size_t depth ) const;
inline Key* getLastClonedKey () const;
inline void clearClonedKey () const;
size_t checkDensity () const;
bool checkEdgeSaturation ( size_t hreserved, size_t vreserved) const;
void setType ( Flags );
inline void setSatProcessed ( size_t depth );
void postGlobalAnnotate ();
void addBlockage ( size_t depth, DbU::Unit );
inline void addHSegment ( AutoSegment* );
inline void addVSegment ( AutoSegment* );
@ -280,7 +263,7 @@ namespace Anabatic {
bool stepNetDesaturate ( size_t depth
, set<Net*>& globalNets
, Set& invalidateds );
inline void incRpCount ( int );
void forceEdgesCapacities ( unsigned int hcapacities, unsigned int vcapacities );
// Misc. functions.
inline const Flags& flags () const;
@ -337,8 +320,6 @@ namespace Anabatic {
vector<AutoContact*> _contacts;
size_t _depth;
size_t _pinDepth;
uint32_t _satProcessed;
int _rpCount;
DbU::Unit* _blockages;
float _cDensity;
float* _densities;
@ -346,71 +327,65 @@ namespace Anabatic {
float* _fragmentations;
float* _globalsCount;
Key _key;
mutable Key* _lastClonedKey;
};
inline bool GCell::isHFlat () const { return getYMin() == getYMax(); }
inline bool GCell::isVFlat () const { return getXMin() == getXMax(); }
inline bool GCell::isFlat () const { return isHFlat() or isVFlat(); }
inline bool GCell::isDevice () const { return _flags & Flags::DeviceGCell; }
inline bool GCell::isHChannel () const { return _flags & Flags::HChannelGCell; }
inline bool GCell::isVChannel () const { return _flags & Flags::VChannelGCell; }
inline bool GCell::isStrut () const { return _flags & Flags::StrutGCell; }
inline bool GCell::isAnalog () const { return _flags & Flags::AnalogGCellMask; }
inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; }
inline bool GCell::isRow () const { return _flags & Flags::RowGCellMask; }
inline bool GCell::isIoPad () const { return _flags & Flags::IoPadGCell; }
inline bool GCell::isGoStraight () const { return _flags & Flags::GoStraight; }
inline bool GCell::isHRail () const { return _flags & Flags::HRailGCell; }
inline bool GCell::isVRail () const { return _flags & Flags::VRailGCell; }
inline bool GCell::isStdCellRow () const { return _flags & Flags::StdCellRow; }
inline bool GCell::isChannelRow () const { return _flags & Flags::ChannelRow; }
inline bool GCell::isSaturated () const { return _flags & Flags::Saturated; }
inline bool GCell::isInvalidated () const { return _flags & Flags::Invalidated; }
inline DbU::Unit GCell::getMatrixHSide () { return _matrixHSide; }
inline DbU::Unit GCell::getMatrixVSide () { return _matrixVSide; }
inline Flags GCell::getType () const { return _flags & Flags::GCellTypeMask; }
inline AnabaticEngine* GCell::getAnabatic () const { return _anabatic; }
inline DbU::Unit GCell::getXMin () const { return _xmin; }
inline DbU::Unit GCell::getYMin () const { return _ymin; }
inline Interval GCell::getHSide ( int shrink ) const { return getSide(Flags::Horizontal,shrink); }
inline Interval GCell::getVSide ( int shrink ) const { return getSide(Flags::Vertical ,shrink); }
inline Edges GCell::getEdges ( Flags sides ) const { return new GCell_Edges(this,sides); }
inline const vector<Edge*>& GCell::getWestEdges () const { return _westEdges; }
inline const vector<Edge*>& GCell::getEastEdges () const { return _eastEdges; }
inline const vector<Edge*>& GCell::getNorthEdges () const { return _northEdges; }
inline const vector<Edge*>& GCell::getSouthEdges () const { return _southEdges; }
inline GCell* GCell::getWest () const { return _westEdges.empty() ? NULL : _westEdges[0]->getOpposite(this); }
inline GCell* GCell::getEast () const { return _eastEdges.empty() ? NULL : _eastEdges[0]->getOpposite(this); }
inline GCell* GCell::getSouth () const { return _southEdges.empty() ? NULL : _southEdges[0]->getOpposite(this); }
inline GCell* GCell::getNorth () const { return _northEdges.empty() ? NULL : _northEdges[0]->getOpposite(this); }
inline Edge* GCell::getWestEdge () const { return _westEdges.empty() ? NULL : _westEdges[0]; }
inline Edge* GCell::getEastEdge () const { return _eastEdges.empty() ? NULL : _eastEdges[0]; }
inline Edge* GCell::getSouthEdge () const { return _southEdges.empty() ? NULL : _southEdges[0]; }
inline Edge* GCell::getNorthEdge () const { return _northEdges.empty() ? NULL : _northEdges[0]; }
inline GCell* GCell::getUnder ( Point p ) const { return getUnder(p.getX(),p.getY()); }
inline const vector<Contact*>& GCell::getGContacts () const { return _gcontacts; }
inline size_t GCell::getDepth () const { return _depth; }
inline int GCell::getRpCount () const { return _rpCount; }
const vector<AutoSegment*>& GCell::getVSegments () const { return _vsegments; }
inline const vector<AutoSegment*>& GCell::getHSegments () const { return _hsegments; }
inline const vector<AutoContact*>& GCell::getContacts () const { return _contacts; }
inline DbU::Unit GCell::getWidth () const { return (getXMax()-getXMin()); }
inline DbU::Unit GCell::getHeight () const { return (getYMax()-getYMin()); }
inline float GCell::getDensity ( size_t depth ) const { return (depth<_depth) ? _densities[depth] : 0.0; }
inline const GCell::Key& GCell::getKey () const { return _key; }
inline GCell::Key* GCell::cloneKey ( size_t depth ) const { _lastClonedKey = new Key(this,depth); return _lastClonedKey; }
inline void GCell::clearClonedKey () const { _lastClonedKey=NULL; }
inline GCell::Key* GCell::getLastClonedKey () const { return _lastClonedKey; }
inline void GCell::setType ( Flags type ) { _flags.reset(Flags::GCellTypeMask); _flags |= (type&Flags::GCellTypeMask); };
inline void GCell::updateKey ( size_t depth ) { _key.update(depth); }
inline const Flags& GCell::flags () const { return _flags; }
inline Flags& GCell::flags () { return _flags; }
inline bool GCell::isHFlat () const { return getYMin() == getYMax(); }
inline bool GCell::isVFlat () const { return getXMin() == getXMax(); }
inline bool GCell::isFlat () const { return isHFlat() or isVFlat(); }
inline bool GCell::isDevice () const { return _flags & Flags::DeviceGCell; }
inline bool GCell::isHChannel () const { return _flags & Flags::HChannelGCell; }
inline bool GCell::isVChannel () const { return _flags & Flags::VChannelGCell; }
inline bool GCell::isStrut () const { return _flags & Flags::StrutGCell; }
inline bool GCell::isAnalog () const { return _flags & Flags::AnalogGCellMask; }
inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; }
inline bool GCell::isRow () const { return _flags & Flags::RowGCellMask; }
inline bool GCell::isIoPad () const { return _flags & Flags::IoPadGCell; }
inline bool GCell::isHRail () const { return _flags & Flags::HRailGCell; }
inline bool GCell::isVRail () const { return _flags & Flags::VRailGCell; }
inline bool GCell::isStdCellRow () const { return _flags & Flags::StdCellRow; }
inline bool GCell::isChannelRow () const { return _flags & Flags::ChannelRow; }
inline bool GCell::isSaturated () const { return _flags & Flags::Saturated; }
inline bool GCell::isInvalidated () const { return _flags & Flags::Invalidated; }
inline DbU::Unit GCell::getMatrixHSide () { return _matrixHSide; }
inline DbU::Unit GCell::getMatrixVSide () { return _matrixVSide; }
inline Flags GCell::getType () const { return _flags & Flags::GCellTypeMask; }
inline AnabaticEngine* GCell::getAnabatic () const { return _anabatic; }
inline DbU::Unit GCell::getXMin () const { return _xmin; }
inline DbU::Unit GCell::getYMin () const { return _ymin; }
inline Interval GCell::getHSide ( int shrink ) const { return getSide(Flags::Horizontal,shrink); }
inline Interval GCell::getVSide ( int shrink ) const { return getSide(Flags::Vertical ,shrink); }
inline Edges GCell::getEdges ( Flags sides ) const { return new GCell_Edges(this,sides); }
inline const vector<Edge*>& GCell::getWestEdges () const { return _westEdges; }
inline const vector<Edge*>& GCell::getEastEdges () const { return _eastEdges; }
inline const vector<Edge*>& GCell::getNorthEdges () const { return _northEdges; }
inline const vector<Edge*>& GCell::getSouthEdges () const { return _southEdges; }
inline GCell* GCell::getWest () const { return _westEdges.empty() ? NULL : _westEdges[0]->getOpposite(this); }
inline GCell* GCell::getEast () const { return _eastEdges.empty() ? NULL : _eastEdges[0]->getOpposite(this); }
inline GCell* GCell::getSouth () const { return _southEdges.empty() ? NULL : _southEdges[0]->getOpposite(this); }
inline GCell* GCell::getNorth () const { return _northEdges.empty() ? NULL : _northEdges[0]->getOpposite(this); }
inline Edge* GCell::getWestEdge () const { return _westEdges.empty() ? NULL : _westEdges[0]; }
inline Edge* GCell::getEastEdge () const { return _eastEdges.empty() ? NULL : _eastEdges[0]; }
inline Edge* GCell::getSouthEdge () const { return _southEdges.empty() ? NULL : _southEdges[0]; }
inline Edge* GCell::getNorthEdge () const { return _northEdges.empty() ? NULL : _northEdges[0]; }
inline GCell* GCell::getUnder ( Point p ) const { return getUnder(p.getX(),p.getY()); }
inline const vector<Contact*>& GCell::getGContacts () const { return _gcontacts; }
inline size_t GCell::getDepth () const { return _depth; }
const vector<AutoSegment*>& GCell::getVSegments () const { return _vsegments; }
inline const vector<AutoSegment*>& GCell::getHSegments () const { return _hsegments; }
inline const vector<AutoContact*>& GCell::getContacts () const { return _contacts; }
inline DbU::Unit GCell::getWidth () const { return (getXMax()-getXMin()); }
inline DbU::Unit GCell::getHeight () const { return (getYMax()-getYMin()); }
inline float GCell::getDensity ( size_t depth ) const { return (depth<_depth) ? _densities[depth] : 0.0; }
inline const GCell::Key& GCell::getKey () const { return _key; }
inline void GCell::setType ( Flags type ) { _flags.reset(Flags::GCellTypeMask); _flags |= (type&Flags::GCellTypeMask); };
inline void GCell::updateKey ( size_t depth ) { _key.update(depth); }
inline const Flags& GCell::flags () const { return _flags; }
inline Flags& GCell::flags () { return _flags; }
inline DbU::Unit GCell::getXMax ( int shrink ) const
{ return _eastEdges.empty() ? getCell()->getAbutmentBox().getXMax() - shrink
@ -441,10 +416,6 @@ namespace Anabatic {
return Interval( getXMin(), getConstraintXMax(shrink) );
}
inline void GCell::incRpCount ( int delta )
{ _rpCount = (_rpCount + delta > 0) ? (_rpCount + delta) : 0; }
inline void GCell::setObserver ( size_t slot, BaseObserver* observer )
{ _observable.setObserver( slot, observer ); }
@ -490,12 +461,6 @@ namespace Anabatic {
inline void GCell::addContact ( AutoContact* contact )
{ _flags |= Flags::Invalidated; _contacts.push_back(contact); }
inline bool GCell::isSatProcessed ( size_t depth ) const
{ return (_satProcessed & (1 << depth)); }
inline void GCell::setSatProcessed ( size_t depth )
{ _satProcessed |= (1 << depth); }
inline bool operator< ( const GCell& lhs, const GCell& rhs )
{
@ -504,25 +469,17 @@ namespace Anabatic {
return lhs.getId() < rhs.getId();
}
// GCell::CompareByKey Inline Functions.
inline bool GCell::CompareByKey::operator() ( const GCell* lhs, const GCell* rhs ) const
inline bool GCell::CompareByKey::operator() ( const GCell* lhs, const GCell* rhs )
{ return lhs->getKey() < rhs->getKey(); }
// GCell::Key Inline Functions.
inline GCell::Key::Key ( const GCell* owner, size_t depth )
: _gcell(owner)
, _density(owner->getWDensity(depth,Flags::NoUpdate))
{ }
inline GCell::Key::~Key ()
{ if (isActive()) _gcell->clearClonedKey(); }
inline float GCell::Key::getDensity () const { return _density; }
inline const GCell* GCell::Key::getGCell () const { return _gcell; }
inline void GCell::Key::update ( size_t depth ) { _density=_gcell->getWDensity(depth); }
inline bool GCell::Key::isActive () const { return (this == _gcell->getLastClonedKey()); }
inline bool GCell::Key::isSaturated () const { return _gcell->isSaturated(); }
inline GCell::Key::Key ( GCell* owner, size_t depth ) : _gcell(owner), _density(owner->getWDensity(depth,Flags::NoUpdate)) {}
inline float GCell::Key::getDensity () const { return _density; }
inline GCell* GCell::Key::getGCell () const { return _gcell; }
inline void GCell::Key::update ( size_t depth ) { _density=_gcell->getWDensity(depth); }
inline bool operator< ( const GCell::Key& lhs, const GCell::Key& rhs )
{
@ -532,22 +489,6 @@ namespace Anabatic {
return lhs._gcell->getId() < rhs._gcell->getId();
}
inline bool GCell::Key::Compare::operator() ( const GCell::Key* lhs, const GCell::Key* rhs ) const
{
//if (lhs->isSaturated() xor rhs->isSaturated()) return lhs->isSaturated();
float difference = lhs->_density - rhs->_density;
if (difference != 0.0) return (difference < 0.0);
return lhs->_gcell->getId() < rhs->_gcell->getId();
}
// -------------------------------------------------------------------
// Class : "GCellKeyQueue".
typedef std::priority_queue< GCell::Key*, std::vector<GCell::Key*>, GCell::Key::Compare > GCellKeyQueue;
// -------------------------------------------------------------------
// Class : "GCellDensitySet".
@ -592,3 +533,5 @@ namespace Anabatic {
INSPECTOR_P_SUPPORT(Anabatic::GCell);
#endif // ANABATIC_GCELL_H

View File

@ -13,7 +13,9 @@
// | C++ Header : "./anabatic/NetBuilder.h" |
// +-----------------------------------------------------------------+
#pragma once
#ifndef ANABATIC_NET_BUILDER_H
#define ANABATIC_NET_BUILDER_H
#include <vector>
#include <map>
@ -39,7 +41,6 @@ namespace Anabatic {
class AutoContact;
class AutoSegment;
class AnabaticEngine;
class NetData;
// -------------------------------------------------------------------
@ -47,39 +48,31 @@ namespace Anabatic {
class ForkStack {
public:
inline void push ( Hook* from, AutoContact* contact, uint64_t flags );
inline void push ( Hook* from, AutoContact* contact );
inline void pop ();
inline Hook* getFrom () const;
inline AutoContact* getContact () const;
inline uint64_t getFlags () const;
inline void setFlags ( uint64_t );
private:
struct Element {
Hook* _from;
AutoContact* _contact;
uint64_t _flags;
inline Element ( Hook* from, AutoContact* contact, uint64_t flags );
inline Element ( Hook* from, AutoContact* contact );
};
private:
list<Element> _stack;
};
inline ForkStack::Element::Element ( Hook* from, AutoContact* contact, uint64_t flags ) : _from(from), _contact(contact), _flags(flags) {}
inline ForkStack::Element::Element ( Hook* from, AutoContact* contact ) : _from(from), _contact(contact) {}
inline void ForkStack::pop () { if (not _stack.empty()) _stack.pop_back(); }
inline Hook* ForkStack::getFrom () const { return _stack.empty() ? NULL : _stack.back()._from; }
inline AutoContact* ForkStack::getContact () const { return _stack.empty() ? NULL : _stack.back()._contact; }
inline uint64_t ForkStack::getFlags () const { return _stack.empty() ? 0 : _stack.back()._flags; }
inline void ForkStack::setFlags ( uint64_t flags ) { if (not _stack.empty()) _stack.back()._flags |= flags; }
inline void ForkStack::push ( Hook* from, AutoContact* contact, uint64_t flags )
inline void ForkStack::push ( Hook* from, AutoContact* contact )
{
cdebug_log(145,0) << " Stacking: " << endl;
cdebug_log(145,0) << " + " << from << endl;
cdebug_log(145,0) << " + " << contact << endl;
cdebug_log(145,0) << " + " << flags << endl;
_stack.push_back( Element(from,contact,flags) );
cdebug_log(145,0) << " Stacking " << from << " + " << contact << endl;
_stack.push_back( Element(from,contact) );
}
@ -105,20 +98,16 @@ namespace Anabatic {
, WestBound = (1 << 14)
, EastBound = (1 << 15)
, Middle = (1 << 16)
, UseNonPref = (1 << 17)
, NoProtect = (1 << 18)
, ToUpperRouting = (1 << 19)
, HBothAccess = HAccess|HAccessEW
, SouthWest = SouthBound|WestBound
, NorthEast = NorthBound|EastBound
};
enum TopologyFlag { Global_Vertical_End = (1 << 0)
, Global_Horizontal_End = (1 << 1)
, Global_Horizontal = (1 << 2)
, Global_Vertical = (1 << 3)
, Global_Turn = (1 << 4)
, Global_Fork = (1 << 5)
, Global_Fixed = (1 << 6)
enum TopologyFlag { Global_Vertical_End = 0x00000001
, Global_Horizontal_End = 0x00000002
, Global_Horizontal = 0x00000004
, Global_Vertical = 0x00000008
, Global_Turn = 0x00000010
, Global_Fork = 0x00000020
, Global_Fixed = 0x00000040
, Global_End = Global_Vertical_End | Global_Horizontal_End
, Global_Split = Global_Horizontal | Global_Vertical | Global_Fork
};
@ -157,22 +146,19 @@ namespace Anabatic {
NetBuilder ();
virtual ~NetBuilder ();
void clear ();
inline bool isStrictChannel () const;
inline bool isUpperMetalRp () const;
inline bool isTwoMetals () const;
inline AnabaticEngine* getAnabatic () const;
inline unsigned int getDegree () const;
inline void setDegree ( unsigned int degree );
void fixSegments ();
NetBuilder& setStartHook ( AnabaticEngine*
, Hook* fromHook
, AutoContact* sourceContact=NULL
, uint64_t sourceFlags=0 );
, AutoContact* sourceContact=NULL );
void construct ();
inline unsigned int getStateG () const;
inline UConnexity getConnexity () const;
inline UConnexity& getConnexity ();
inline Net* getNet () const;
inline NetData* getNetData () const;
inline GCell* getGCell () const;
inline AutoContact* getSourceContact () const;
inline AutoContact* getSouthWestContact () const;
@ -180,8 +166,6 @@ namespace Anabatic {
inline AutoContact* getNorthEastContact () const;
inline AutoContact*& getNorthEastContact ();
inline Hook* getFromHook () const;
inline uint64_t getSourceFlags () const;
inline uint64_t getFlags () const;
inline ForkStack& getForks ();
inline vector<RoutingPad*>& getRoutingPads ();
inline map<Component*,AutoSegment*>& getRpLookup ();
@ -200,7 +184,6 @@ namespace Anabatic {
inline void clearSouths ();
inline void clearEasts ();
inline void clearWests ();
inline void setFlags ( uint64_t );
inline void setFromHook ( Hook* );
inline void setSouthWestContact ( AutoContact* );
inline void setNorthEastContact ( AutoContact* );
@ -208,7 +191,6 @@ namespace Anabatic {
inline void swapCornerContacts ();
inline void addToFixSegments ( AutoSegment* );
bool push ( Hook* to, AutoContact* contact, uint64_t flags=0 );
bool isInsideBlockage ( GCell*, Component* ) const;
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags ) = 0;
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags ) = 0;
virtual AutoContact* doRp_AccessPad ( RoutingPad*, uint64_t flags );
@ -220,8 +202,6 @@ namespace Anabatic {
virtual bool _do_xG ();
virtual bool _do_2G ();
virtual bool _do_xG_1Pad ();
virtual bool _do_1G_1PinM1 ();
virtual bool _do_2G_1PinM1 ();
virtual bool _do_1G_1PinM2 ();
virtual bool _do_xG_1PinM2 ();
virtual bool _do_1G_1PinM3 ();
@ -236,12 +216,6 @@ namespace Anabatic {
virtual bool _do_xG_xM2 ();
virtual bool _do_1G_1M3 ();
virtual bool _do_xG_xM3 ();
virtual bool _do_1G_xM1_1PinM1 ();
virtual bool _do_1G_xM1_1PinM2 ();
virtual bool _do_2G_xM1_1PinM2 ();
virtual bool _do_1G_1M1_1PinM3 ();
virtual bool _do_2G_xM1_1PinM3 ();
virtual bool _do_3G_xM1_1PinM3 ();
virtual bool _do_globalSegment ();
virtual void singleGCell ( AnabaticEngine*, Net* );
AutoContact* _doHChannel ();
@ -263,107 +237,71 @@ namespace Anabatic {
+ ((pads) << (GlobalBSize+Metal1BSize+Metal2BSize+Metal3BSize)) \
+ ((pins) << (GlobalBSize+Metal1BSize+Metal2BSize+Metal3BSize+PadsBSize))
// Connexity Name | G|M1|M2|M3|Pad|Pin|
enum ConnexityFlag { Conn_0G = CONNEXITY_VALUE( 0, 0, 0, 0, 0 , 0 )
, Conn_2G = CONNEXITY_VALUE( 2, 0, 0, 0, 0 , 0 )
, Conn_3G = CONNEXITY_VALUE( 3, 0, 0, 0, 0 , 0 )
, Conn_4G = CONNEXITY_VALUE( 4, 0, 0, 0, 0 , 0 )
, Conn_5G = CONNEXITY_VALUE( 5, 0, 0, 0, 0 , 0 )
, Conn_6G = CONNEXITY_VALUE( 6, 0, 0, 0, 0 , 0 )
, Conn_0G_2M1 = CONNEXITY_VALUE( 0, 2, 0, 0, 0 , 0 )
, Conn_1G_1M1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 0 )
, Conn_1G_2M1 = CONNEXITY_VALUE( 1, 2, 0, 0, 0 , 0 )
, Conn_1G_3M1 = CONNEXITY_VALUE( 1, 3, 0, 0, 0 , 0 )
, Conn_1G_4M1 = CONNEXITY_VALUE( 1, 4, 0, 0, 0 , 0 )
, Conn_1G_5M1 = CONNEXITY_VALUE( 1, 5, 0, 0, 0 , 0 )
, Conn_1G_6M1 = CONNEXITY_VALUE( 1, 6, 0, 0, 0 , 0 )
, Conn_1G_7M1 = CONNEXITY_VALUE( 1, 7, 0, 0, 0 , 0 )
, Conn_1G_8M1 = CONNEXITY_VALUE( 1, 8, 0, 0, 0 , 0 )
, Conn_1G_9M1 = CONNEXITY_VALUE( 1, 9, 0, 0, 0 , 0 )
, Conn_1G_1M2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 0 )
, Conn_1G_2M2 = CONNEXITY_VALUE( 1, 0, 2, 0, 0 , 0 )
, Conn_1G_3M2 = CONNEXITY_VALUE( 1, 0, 3, 0, 0 , 0 )
, Conn_1G_4M2 = CONNEXITY_VALUE( 1, 0, 4, 0, 0 , 0 )
, Conn_1G_1M3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 0 )
, Conn_1G_2M3 = CONNEXITY_VALUE( 1, 0, 0, 2, 0 , 0 )
, Conn_1G_3M3 = CONNEXITY_VALUE( 1, 0, 0, 3, 0 , 0 )
, Conn_1G_4M3 = CONNEXITY_VALUE( 1, 0, 0, 4, 0 , 0 )
, Conn_1G_1M1_1M2 = CONNEXITY_VALUE( 1, 1, 1, 0, 0 , 0 )
, Conn_1G_1M1_1M3 = CONNEXITY_VALUE( 1, 1, 0, 1, 0 , 0 )
// Connexity Name | G|M1|M2|M3|Pad|Pin|
, Conn_2G_1M1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 0 )
, Conn_2G_2M1 = CONNEXITY_VALUE( 2, 2, 0, 0, 0 , 0 )
, Conn_2G_3M1 = CONNEXITY_VALUE( 2, 3, 0, 0, 0 , 0 )
, Conn_2G_4M1 = CONNEXITY_VALUE( 2, 4, 0, 0, 0 , 0 )
, Conn_2G_5M1 = CONNEXITY_VALUE( 2, 5, 0, 0, 0 , 0 )
, Conn_2G_6M1 = CONNEXITY_VALUE( 2, 6, 0, 0, 0 , 0 )
, Conn_2G_7M1 = CONNEXITY_VALUE( 2, 7, 0, 0, 0 , 0 )
, Conn_2G_8M1 = CONNEXITY_VALUE( 2, 8, 0, 0, 0 , 0 )
, Conn_2G_9M1 = CONNEXITY_VALUE( 2, 9, 0, 0, 0 , 0 )
, Conn_2G_1M2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 0 )
, Conn_2G_2M2 = CONNEXITY_VALUE( 2, 0, 2, 0, 0 , 0 )
, Conn_2G_3M2 = CONNEXITY_VALUE( 2, 0, 3, 0, 0 , 0 )
, Conn_2G_4M2 = CONNEXITY_VALUE( 2, 0, 4, 0, 0 , 0 )
, Conn_2G_1M3 = CONNEXITY_VALUE( 2, 0, 0, 1, 0 , 0 )
, Conn_2G_2M3 = CONNEXITY_VALUE( 2, 0, 0, 2, 0 , 0 )
, Conn_2G_3M3 = CONNEXITY_VALUE( 2, 0, 0, 3, 0 , 0 )
, Conn_2G_4M3 = CONNEXITY_VALUE( 2, 0, 0, 4, 0 , 0 )
, Conn_2G_1M1_1M2 = CONNEXITY_VALUE( 2, 1, 1, 0, 0 , 0 )
// Connexity Name | G|M1|M2|M3|Pad|Pin|
, Conn_3G_1M1 = CONNEXITY_VALUE( 3, 1, 0, 0, 0 , 0 )
, Conn_3G_2M1 = CONNEXITY_VALUE( 3, 2, 0, 0, 0 , 0 )
, Conn_3G_3M1 = CONNEXITY_VALUE( 3, 3, 0, 0, 0 , 0 )
, Conn_3G_4M1 = CONNEXITY_VALUE( 3, 4, 0, 0, 0 , 0 )
, Conn_3G_5M1 = CONNEXITY_VALUE( 3, 5, 0, 0, 0 , 0 )
, Conn_3G_6M1 = CONNEXITY_VALUE( 3, 6, 0, 0, 0 , 0 )
, Conn_3G_7M1 = CONNEXITY_VALUE( 3, 7, 0, 0, 0 , 0 )
, Conn_3G_8M1 = CONNEXITY_VALUE( 3, 8, 0, 0, 0 , 0 )
, Conn_3G_9M1 = CONNEXITY_VALUE( 3, 9, 0, 0, 0 , 0 )
, Conn_3G_1M2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 0 )
, Conn_3G_2M2 = CONNEXITY_VALUE( 3, 0, 2, 0, 0 , 0 )
, Conn_3G_1M3 = CONNEXITY_VALUE( 3, 0, 0, 1, 0 , 0 )
, Conn_3G_2M3 = CONNEXITY_VALUE( 3, 0, 0, 2, 0 , 0 )
, Conn_3G_3M3 = CONNEXITY_VALUE( 3, 0, 0, 3, 0 , 0 )
, Conn_3G_4M3 = CONNEXITY_VALUE( 3, 0, 0, 4, 0 , 0 )
// Connexity Name | G|M1|M2|M3|Pad|Pin|
, Conn_4G_1M1 = CONNEXITY_VALUE( 4, 1, 0, 0, 0 , 0 )
, Conn_4G_2M1 = CONNEXITY_VALUE( 4, 2, 0, 0, 0 , 0 )
, Conn_4G_3M1 = CONNEXITY_VALUE( 4, 3, 0, 0, 0 , 0 )
, Conn_4G_4M1 = CONNEXITY_VALUE( 4, 4, 0, 0, 0 , 0 )
, Conn_4G_5M1 = CONNEXITY_VALUE( 4, 5, 0, 0, 0 , 0 )
, Conn_4G_6M1 = CONNEXITY_VALUE( 4, 6, 0, 0, 0 , 0 )
, Conn_4G_7M1 = CONNEXITY_VALUE( 4, 7, 0, 0, 0 , 0 )
, Conn_4G_8M1 = CONNEXITY_VALUE( 4, 8, 0, 0, 0 , 0 )
, Conn_4G_9M1 = CONNEXITY_VALUE( 4, 9, 0, 0, 0 , 0 )
, Conn_4G_1M2 = CONNEXITY_VALUE( 4, 0, 1, 0, 0 , 0 )
, Conn_4G_1M3 = CONNEXITY_VALUE( 4, 0, 0, 1, 0 , 0 )
, Conn_1G_1Pad = CONNEXITY_VALUE( 1, 0, 0, 0, 1 , 0 )
, Conn_2G_1Pad = CONNEXITY_VALUE( 2, 0, 0, 0, 1 , 0 )
, Conn_3G_1Pad = CONNEXITY_VALUE( 3, 0, 0, 0, 1 , 0 )
, Conn_1G_1PinM1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 1 )
, Conn_2G_1PinM1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 1 )
, Conn_1G_1PinM2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 1 )
, Conn_2G_1PinM2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 1 )
, Conn_3G_1PinM2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 1 )
, Conn_1G_1M1_1PinM1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 1 )
, Conn_1G_2M1_1PinM1 = CONNEXITY_VALUE( 1, 2, 0, 0, 0 , 1 )
, Conn_1G_1M1_1PinM2 = CONNEXITY_VALUE( 1, 1, 1, 0, 0 , 1 )
, Conn_1G_2M1_1PinM2 = CONNEXITY_VALUE( 1, 2, 1, 0, 0 , 1 )
, Conn_1G_3M1_1PinM2 = CONNEXITY_VALUE( 1, 3, 1, 0, 0 , 1 )
, Conn_1G_4M1_1PinM2 = CONNEXITY_VALUE( 1, 4, 1, 0, 0 , 1 )
, Conn_1G_5M1_1PinM2 = CONNEXITY_VALUE( 1, 5, 1, 0, 0 , 1 )
, Conn_2G_1M1_1PinM2 = CONNEXITY_VALUE( 2, 1, 1, 0, 0 , 1 )
, Conn_2G_2M1_1PinM2 = CONNEXITY_VALUE( 2, 2, 1, 0, 0 , 1 )
, Conn_1G_1PinM3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 1 )
, Conn_2G_1PinM3 = CONNEXITY_VALUE( 2, 0, 0, 1, 0 , 1 )
, Conn_3G_1PinM3 = CONNEXITY_VALUE( 3, 0, 0, 1, 0 , 1 )
, Conn_1G_1M1_1PinM3 = CONNEXITY_VALUE( 1, 1, 0, 1, 0 , 1 )
, Conn_2G_1M1_1PinM3 = CONNEXITY_VALUE( 2, 1, 0, 1, 0 , 1 )
, Conn_2G_2M1_1PinM3 = CONNEXITY_VALUE( 2, 2, 0, 1, 0 , 1 )
, Conn_2G_3M1_1PinM3 = CONNEXITY_VALUE( 2, 3, 0, 1, 0 , 1 )
, Conn_3G_1M1_1PinM3 = CONNEXITY_VALUE( 3, 1, 0, 1, 0 , 1 )
, Conn_3G_2M1_1PinM3 = CONNEXITY_VALUE( 3, 2, 0, 1, 0 , 1 )
, Conn_3G_3M1_1PinM3 = CONNEXITY_VALUE( 3, 3, 0, 1, 0 , 1 )
// Connexity Name | G|M1|M2|M3|Pad|Pin|
enum ConnexityFlag { Conn_0G = CONNEXITY_VALUE( 0, 0, 0, 0, 0 , 0 )
, Conn_2G = CONNEXITY_VALUE( 2, 0, 0, 0, 0 , 0 )
, Conn_3G = CONNEXITY_VALUE( 3, 0, 0, 0, 0 , 0 )
, Conn_4G = CONNEXITY_VALUE( 4, 0, 0, 0, 0 , 0 )
, Conn_5G = CONNEXITY_VALUE( 5, 0, 0, 0, 0 , 0 )
, Conn_6G = CONNEXITY_VALUE( 6, 0, 0, 0, 0 , 0 )
, Conn_0G_2M1 = CONNEXITY_VALUE( 0, 2, 0, 0, 0 , 0 )
, Conn_1G_1M1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 0 )
, Conn_1G_2M1 = CONNEXITY_VALUE( 1, 2, 0, 0, 0 , 0 )
, Conn_1G_3M1 = CONNEXITY_VALUE( 1, 3, 0, 0, 0 , 0 )
, Conn_1G_4M1 = CONNEXITY_VALUE( 1, 4, 0, 0, 0 , 0 )
, Conn_1G_5M1 = CONNEXITY_VALUE( 1, 5, 0, 0, 0 , 0 )
, Conn_1G_1M2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 0 )
, Conn_1G_2M2 = CONNEXITY_VALUE( 1, 0, 2, 0, 0 , 0 )
, Conn_1G_3M2 = CONNEXITY_VALUE( 1, 0, 3, 0, 0 , 0 )
, Conn_1G_4M2 = CONNEXITY_VALUE( 1, 0, 4, 0, 0 , 0 )
, Conn_1G_1M3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 0 )
, Conn_1G_2M3 = CONNEXITY_VALUE( 1, 0, 0, 2, 0 , 0 )
, Conn_1G_3M3 = CONNEXITY_VALUE( 1, 0, 0, 3, 0 , 0 )
, Conn_1G_4M3 = CONNEXITY_VALUE( 1, 0, 0, 4, 0 , 0 )
, Conn_1G_1M1_1M2 = CONNEXITY_VALUE( 1, 1, 1, 0, 0 , 0 )
, Conn_1G_1M1_1M3 = CONNEXITY_VALUE( 1, 1, 0, 1, 0 , 0 )
// Connexity Name | G|M1|M2|M3|Pad|Pin|
, Conn_2G_1M1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 0 )
, Conn_2G_2M1 = CONNEXITY_VALUE( 2, 2, 0, 0, 0 , 0 )
, Conn_2G_3M1 = CONNEXITY_VALUE( 2, 3, 0, 0, 0 , 0 )
, Conn_2G_4M1 = CONNEXITY_VALUE( 2, 4, 0, 0, 0 , 0 )
, Conn_2G_5M1 = CONNEXITY_VALUE( 2, 5, 0, 0, 0 , 0 )
, Conn_2G_1M2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 0 )
, Conn_2G_2M2 = CONNEXITY_VALUE( 2, 0, 2, 0, 0 , 0 )
, Conn_2G_3M2 = CONNEXITY_VALUE( 2, 0, 3, 0, 0 , 0 )
, Conn_2G_4M2 = CONNEXITY_VALUE( 2, 0, 4, 0, 0 , 0 )
, Conn_2G_1M3 = CONNEXITY_VALUE( 2, 0, 0, 1, 0 , 0 )
, Conn_2G_2M3 = CONNEXITY_VALUE( 2, 0, 0, 2, 0 , 0 )
, Conn_2G_3M3 = CONNEXITY_VALUE( 2, 0, 0, 3, 0 , 0 )
, Conn_2G_4M3 = CONNEXITY_VALUE( 2, 0, 0, 4, 0 , 0 )
, Conn_2G_1M1_1M2 = CONNEXITY_VALUE( 2, 1, 1, 0, 0 , 0 )
// Connexity Name | G|M1|M2|M3|Pad|Pin|
, Conn_3G_1M1 = CONNEXITY_VALUE( 3, 1, 0, 0, 0 , 0 )
, Conn_3G_2M1 = CONNEXITY_VALUE( 3, 2, 0, 0, 0 , 0 )
, Conn_3G_3M1 = CONNEXITY_VALUE( 3, 3, 0, 0, 0 , 0 )
, Conn_3G_4M1 = CONNEXITY_VALUE( 3, 4, 0, 0, 0 , 0 )
, Conn_3G_1M2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 0 )
, Conn_3G_2M2 = CONNEXITY_VALUE( 3, 0, 2, 0, 0 , 0 )
, Conn_3G_1M3 = CONNEXITY_VALUE( 3, 0, 0, 1, 0 , 0 )
, Conn_3G_2M3 = CONNEXITY_VALUE( 3, 0, 0, 2, 0 , 0 )
, Conn_3G_3M3 = CONNEXITY_VALUE( 3, 0, 0, 3, 0 , 0 )
, Conn_3G_4M3 = CONNEXITY_VALUE( 3, 0, 0, 4, 0 , 0 )
// Connexity Name | G|M1|M2|M3|Pad|Pin|
, Conn_4G_1M1 = CONNEXITY_VALUE( 4, 1, 0, 0, 0 , 0 )
, Conn_4G_2M1 = CONNEXITY_VALUE( 4, 2, 0, 0, 0 , 0 )
, Conn_4G_3M1 = CONNEXITY_VALUE( 4, 3, 0, 0, 0 , 0 )
, Conn_4G_4M1 = CONNEXITY_VALUE( 4, 4, 0, 0, 0 , 0 )
, Conn_4G_1M2 = CONNEXITY_VALUE( 4, 0, 1, 0, 0 , 0 )
, Conn_4G_1M3 = CONNEXITY_VALUE( 4, 0, 0, 1, 0 , 0 )
, Conn_1G_1Pad = CONNEXITY_VALUE( 1, 0, 0, 0, 1 , 0 )
, Conn_2G_1Pad = CONNEXITY_VALUE( 2, 0, 0, 0, 1 , 0 )
, Conn_3G_1Pad = CONNEXITY_VALUE( 3, 0, 0, 0, 1 , 0 )
, Conn_1G_1PinM2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 1 )
, Conn_2G_1PinM2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 1 )
, Conn_3G_1PinM2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 1 )
, Conn_1G_1PinM3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 1 )
, Conn_2G_1PinM3 = CONNEXITY_VALUE( 2, 0, 0, 1, 0 , 1 )
, Conn_3G_1PinM3 = CONNEXITY_VALUE( 3, 0, 0, 1, 0 , 1 )
};
#undef CONNEXITY_VALUE
@ -375,7 +313,6 @@ namespace Anabatic {
UConnexity _connexity;
unsigned int _topology;
Net* _net;
NetData* _netData;
GCell* _gcell;
AutoContact* _sourceContact;
AutoContact* _southWestContact;
@ -389,13 +326,14 @@ namespace Anabatic {
map<Component*,AutoSegment*> _routingPadAutoSegments;
vector<AutoSegment*> _toFixSegments;
unsigned int _degree;
bool _isStrictChannel;
uint64_t _sourceFlags;
uint64_t _flags;
bool _isTwoMetals;
// Sort classes.
public:
};
inline bool NetBuilder::isStrictChannel () const { return _isStrictChannel; }
inline bool NetBuilder::isTwoMetals () const { return _isTwoMetals; }
inline AnabaticEngine* NetBuilder::getAnabatic () const { return _anabatic; }
inline unsigned int NetBuilder::getDegree () const { return _degree; }
inline NetBuilder::UConnexity NetBuilder::getConnexity () const { return _connexity; }
@ -404,15 +342,12 @@ namespace Anabatic {
inline unsigned int NetBuilder::getStateG () const { return _connexity.fields.globals; }
inline GCell* NetBuilder::getGCell () const { return _gcell; }
inline Net* NetBuilder::getNet () const { return _net; }
inline NetData* NetBuilder::getNetData () const { return _netData; }
inline AutoContact* NetBuilder::getSourceContact () const { return _sourceContact; }
inline AutoContact* NetBuilder::getSouthWestContact () const { return _southWestContact; }
inline AutoContact*& NetBuilder::getSouthWestContact () { return _southWestContact; }
inline AutoContact* NetBuilder::getNorthEastContact () const { return _northEastContact; }
inline AutoContact*& NetBuilder::getNorthEastContact () { return _northEastContact; }
inline Hook* NetBuilder::getFromHook () const { return _fromHook; }
inline uint64_t NetBuilder::getSourceFlags () const { return _sourceFlags; }
inline uint64_t NetBuilder::getFlags () const { return _flags; }
inline unsigned int NetBuilder::getTopology () const { return _topology; }
inline vector<RoutingPad*>& NetBuilder::getRoutingPads () { return _routingPads; }
inline map<Component*,AutoSegment*>& NetBuilder::getRpLookup () { return _routingPadAutoSegments; }
@ -422,7 +357,6 @@ namespace Anabatic {
inline Hook* NetBuilder::south ( size_t i ) const { return (i<_souths.size()) ? _souths[i] : NULL; }
inline Hook* NetBuilder::east ( size_t i ) const { return (i<_easts .size()) ? _easts [i] : NULL; }
inline Hook* NetBuilder::west ( size_t i ) const { return (i<_wests .size()) ? _wests [i] : NULL; }
inline void NetBuilder::setFlags ( uint64_t flags ) { _flags |= flags; }
inline void NetBuilder::setDegree ( unsigned int degree ) { _degree = degree; }
inline void NetBuilder::setFromHook ( Hook* hook ) { _fromHook = hook; }
inline void NetBuilder::setBothCornerContacts ( AutoContact* ac ) { _southWestContact = _northEastContact = ac; }
@ -443,3 +377,5 @@ namespace Anabatic {
void NetBuilder::load ( AnabaticEngine* engine, Net* net ) { BuilderT()._load(engine,net); }
}
#endif // ANABATIC_NET_BUILDER_H

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved
// Copyright (c) UPMC 2008-2018, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
@ -13,7 +13,9 @@
// | C++ Header : "./anabatic/NetBuilderHV.h" |
// +-----------------------------------------------------------------+
#pragma once
#ifndef ANABATIC_NET_BUILDER_HV_H
#define ANABATIC_NET_BUILDER_HV_H
#include "anabatic/NetBuilder.h"
@ -23,48 +25,36 @@ namespace Anabatic {
// -----------------------------------------------------------------
// Class : "NetBuilderHV".
class NetBuilderHV : public NetBuilder {
public:
NetBuilderHV ();
virtual ~NetBuilderHV ();
static std::string getStyle ();
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
AutoContact* doRp_AccessNorthSouthPin ( GCell*, RoutingPad* );
AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* );
private:
virtual bool _do_1G_1M1 ();
virtual bool _do_1G_xM1 ();
virtual bool _do_xG ();
virtual bool _do_2G ();
virtual bool _do_2G_1M1 ();
virtual bool _do_xG_1Pad ();
virtual bool _do_1G_1PinM1 ();
virtual bool _do_2G_1PinM1 ();
virtual bool _do_1G_1PinM2 ();
virtual bool _do_xG_1PinM2 ();
virtual bool _do_1G_1PinM3 ();
virtual bool _do_xG_1PinM3 ();
virtual bool _do_xG_1M1 ();
virtual bool _do_xG_1M1_1M2 ();
virtual bool _do_xG_xM1_xM3 ();
virtual bool _do_4G_1M2 ();
virtual bool _do_xG_xM2 ();
virtual bool _do_1G_1M3 ();
virtual bool _do_xG_xM3 ();
bool _do_xG_xM3_baseRouting ();
bool _do_xG_xM3_upperRouting ();
virtual bool _do_1G_xM1_1PinM2 ();
virtual bool _do_2G_xM1_1PinM2 ();
virtual bool _do_1G_1M1_1PinM3 ();
virtual bool _do_2G_xM1_1PinM3 ();
virtual bool _do_3G_xM1_1PinM3 ();
virtual bool _do_globalSegment ();
virtual void singleGCell ( AnabaticEngine*, Net* );
public:
virtual string getTypeName () const;
NetBuilderHV ();
virtual ~NetBuilderHV ();
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
private:
virtual bool _do_1G_1M1 ();
virtual bool _do_1G_xM1 ();
virtual bool _do_xG ();
virtual bool _do_2G ();
virtual bool _do_2G_1M1 ();
virtual bool _do_xG_1Pad ();
virtual bool _do_1G_1PinM2 ();
virtual bool _do_xG_1PinM2 ();
virtual bool _do_1G_1PinM3 ();
virtual bool _do_xG_1PinM3 ();
virtual bool _do_xG_1M1 ();
virtual bool _do_xG_1M1_1M2 ();
virtual bool _do_xG_xM1_xM3 ();
virtual bool _do_4G_1M2 ();
virtual bool _do_xG_xM2 ();
virtual bool _do_1G_1M3 ();
virtual bool _do_xG_xM3 ();
virtual bool _do_globalSegment ();
public:
virtual string getTypeName () const;
};
} // Anabatic namespace.
#endif // ANABATIC_NET_BUILDER_HV_H

View File

@ -1,68 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./anabatic/NetBuilderHybridVH.h" |
// +-----------------------------------------------------------------+
#pragma once
#include "anabatic/NetBuilder.h"
namespace Anabatic {
// -----------------------------------------------------------------
// Class : "NetBuilderHybridVH".
class NetBuilderHybridVH : public NetBuilder {
public:
NetBuilderHybridVH ();
virtual ~NetBuilderHybridVH ();
static std::string getStyle ();
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
AutoContact* doRp_AccessEastWestPin ( GCell* , RoutingPad* );
AutoContact* doRp_AccessNorthSouthPin ( GCell* , RoutingPad* );
private:
bool doRp_xG_1M1 ( RoutingPad* );
bool doRp_1G_1PinM2 ( RoutingPad* );
bool doRp_xG_xM1_xM3 ( const std::vector<RoutingPad*>& );
virtual bool _do_1G_1M1 ();
virtual bool _do_2G_1M1 ();
virtual bool _do_xG_1M1 ();
virtual bool _do_xG ();
bool _do_xG_xM1 ();
virtual bool _do_globalSegment ();
// Should never occur, so just return false.
// virtual bool _do_xG_1Pad ();
// virtual bool _do_1G_1PinM2 ();
virtual bool _do_1G_xM1 ();
// virtual bool _do_xG_xM2 ();
// virtual bool _do_1G_1M3 ();
// virtual bool _do_xG_xM3 ();
// virtual bool _do_xG_1M1_1M2 ();
virtual bool _do_xG_xM1_xM3 ();
virtual bool _do_1G_xM1_1PinM1 ();
virtual bool _do_1G_xM1_1PinM2 ();
// virtual bool _do_4G_1M2 ();
virtual bool _do_2G ();
virtual bool _do_2G_1PinM1 ();
virtual bool _do_1G_1PinM1 ();
virtual bool _do_1G_1PinM2 ();
virtual bool _do_xG_1PinM2 ();
virtual void singleGCell ( AnabaticEngine*, Net* );
public:
virtual string getTypeName () const;
};
} // Anabatic namespace.

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved
// Copyright (c) UPMC 2008-2018, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
@ -13,7 +13,9 @@
// | C++ Header : "./anabatic/NetBuilderM2.h" |
// +-----------------------------------------------------------------+
#pragma once
#ifndef ANABATIC_NET_BUILDER_M2_H
#define ANABATIC_NET_BUILDER_M2_H
#include "anabatic/NetBuilder.h"
@ -27,7 +29,6 @@ namespace Anabatic {
public:
NetBuilderM2 ();
virtual ~NetBuilderM2 ();
static std::string getStyle ();
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
private:
@ -52,3 +53,5 @@ namespace Anabatic {
} // Anabatic namespace.
#endif // ANABATIC_NET_BUILDER_M2_H

View File

@ -1,7 +1,7 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2017-2022, All Rights Reserved
// Copyright (c) UPMC 2017-2018, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
@ -13,7 +13,9 @@
// | C++ Header : "./anabatic/NetBuilderVH.h" |
// +-----------------------------------------------------------------+
#pragma once
#ifndef ANABATIC_NET_BUILDER_VH_H
#define ANABATIC_NET_BUILDER_VH_H
#include "anabatic/NetBuilder.h"
@ -27,7 +29,6 @@ namespace Anabatic {
public:
NetBuilderVH ();
virtual ~NetBuilderVH ();
static std::string getStyle ();
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
private:
@ -40,7 +41,6 @@ namespace Anabatic {
virtual bool _do_2G_1M1 ();
virtual bool _do_xG_xM1_xM3 ();
virtual bool _do_xG ();
virtual bool _do_2G ();
virtual bool _do_globalSegment ();
virtual void singleGCell ( AnabaticEngine*, Net* );
public:
@ -49,3 +49,5 @@ namespace Anabatic {
} // Anabatic namespace.
#endif // ANABATIC_NET_BUILDER_VH_H

View File

@ -1,52 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Global Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./hurricane/isobar/PyStyleFlags.h" |
// +-----------------------------------------------------------------+
#pragma once
#include "hurricane/isobar/PyHurricane.h"
#include "anabatic/Constants.h"
namespace Anabatic {
extern "C" {
// -------------------------------------------------------------------
// Python Object : "PyStyleFlags".
typedef struct {
PyObject_HEAD
StyleFlags* _object;
} PyStyleFlags;
extern PyTypeObject PyTypeStyleFlags;
extern PyMethodDef PyStyleFlags_Methods[];
extern PyObject* PyStyleFlags_Link ( StyleFlags* );
extern void PyStyleFlags_LinkPyType ();
extern void PyStyleFlags_postModuleInit ();
#define IsPyStyleFlags(v) ( (v)->ob_type == &PyTypeStyleFlags )
#define PYSTYLEFLAGS(v) ( (PyStyleFlags*)(v) )
#define PYSTYLEFLAGS_O(v) ( PYSTYLEFLAGS(v)->_object )
} // extern "C".
extern Anabatic::StyleFlags PyInt_AsStyleFlags ( PyObject* );
} // Anabatic namespace.

View File

@ -14,7 +14,9 @@
// +-----------------------------------------------------------------+
#pragma once
#ifndef ANABATIC_SESSION_H
#define ANABATIC_SESSION_H
#include <string>
#include <vector>
#include <set>
@ -22,7 +24,6 @@
#include <boost/function.hpp>
#include "hurricane/Commons.h"
#include "hurricane/Box.h"
#include "hurricane/DBo.h"
#include "crlcore/CellGauge.h"
#include "crlcore/RoutingGauge.h"
#include "anabatic/Constants.h"
@ -54,7 +55,6 @@ namespace Anabatic {
using Hurricane::DbU;
using Hurricane::Point;
using Hurricane::Box;
using Hurricane::DBo;
using Hurricane::Net;
using Hurricane::Contact;
using Hurricane::Segment;
@ -71,132 +71,118 @@ namespace Anabatic {
class Session {
public:
// Static Methods.
static inline bool isOpen ();
static inline bool doDestroyBaseContact ();
static inline bool doDestroyBaseSegment ();
static inline bool doDestroyTool ();
static bool isInDemoMode ();
static bool isChannelStyle ();
static bool doWarnGCellOverload ();
static Session* get ( const char* message=NULL );
static inline Technology* getTechnology ();
static inline AnabaticEngine* getAnabatic ();
static StyleFlags getRoutingStyle ();
static inline const Configuration* getConfiguration ();
static float getSaturateRatio ();
static size_t getSaturateRp ();
static inline size_t getAllowedDepth ();
static DbU::Unit getExtensionCap ();
static inline CellGauge* getCellGauge ();
static inline DbU::Unit getSliceHeight ();
static inline DbU::Unit getSliceStep ();
static inline size_t getGVerticalDepth ();
static inline size_t getGHorizontalDepth ();
static inline DbU::Unit getGHorizontalPitch ();
static inline DbU::Unit getGVerticalPitch ();
static inline size_t getDVerticalDepth ();
static inline const Layer* getDVerticalLayer ();
static inline DbU::Unit getDVerticalWidth ();
static inline DbU::Unit getDPVerticalWidth ();
static inline DbU::Unit getDVerticalPitch ();
static inline DbU::Unit getDVerticalOffset ();
static inline size_t getDHorizontalDepth ();
static inline const Layer* getDHorizontalLayer ();
static inline DbU::Unit getDHorizontalWidth ();
static inline DbU::Unit getDPHorizontalWidth ();
static inline DbU::Unit getDHorizontalPitch ();
static inline DbU::Unit getDHorizontalOffset ();
static inline size_t getDContactDepth ();
static inline const Layer* getDContactLayer ();
static inline DbU::Unit getDContactWidth ();
static inline DbU::Unit getDContactPitch ();
static inline RoutingGauge* getRoutingGauge ();
static inline bool isGLayer ( const Layer* );
static inline bool isGMetal ( const Layer* );
static inline bool isGContact ( const Layer* );
static inline bool isGaugeLayer ( const Layer* );
static inline RoutingLayerGauge* getLayerGauge ( const Layer* );
static inline RoutingLayerGauge* getLayerGauge ( size_t depth );
static inline size_t getDepth ();
static inline size_t getViaDepth ( const Layer* layer );
static inline size_t getLayerDepth ( const Layer* layer );
static inline const Layer* getRoutingLayer ( size_t );
static inline const Layer* getContactLayer ( size_t );
static inline const Layer* getBuildRoutingLayer ( size_t );
static inline const Layer* getBuildContactLayer ( size_t );
static Flags getDirection ( size_t depth );
static inline DbU::Unit getPitch ( size_t depth, Flags flags );
static inline DbU::Unit getOffset ( size_t depth );
static inline DbU::Unit getWireWidth ( size_t depth );
static inline DbU::Unit getPWireWidth ( size_t depth );
static inline DbU::Unit getViaWidth ( size_t depth );
static inline Flags getDirection ( const Layer* );
static inline DbU::Unit getPitch ( const Layer*, Flags flags );
static inline DbU::Unit getOffset ( const Layer* );
static inline DbU::Unit getWireWidth ( const Layer* );
static inline DbU::Unit getViaWidth ( const Layer* );
static inline DbU::Unit getExtensionCap ( const Layer* );
static inline DbU::Unit getNearestTrackAxis ( const Layer*, DbU::Unit, uint32_t mode );
static inline Point getNearestGridPoint ( Point, Box constraints );
static inline size_t getSegmentStackSize ();
static inline size_t getContactStackSize ();
static inline const vector<AutoSegment*>& getInvalidateds ();
static inline const vector<AutoSegment*>& getRevalidateds ();
static inline const set<AutoSegment*>& getDestroyeds ();
static inline const vector<AutoSegment*>& getDoglegs ();
static inline const set<Net*,DBo::CompareById>& getNetsModificateds ();
static void close ();
static void setAnabaticFlags ( Flags );
static inline void dogleg ( AutoSegment* );
static inline void doglegReset ();
static inline void revalidateTopology ();
static inline void setInvalidateMask ( Flags );
static inline void invalidate ( Net* );
static inline void invalidate ( AutoContact* );
static inline void invalidate ( AutoSegment* );
static inline size_t revalidate ();
static void link ( AutoContact* );
static void link ( AutoSegment* );
static void unlink ( AutoContact* );
static void unlink ( AutoSegment* );
static AutoContact* lookup ( Contact* );
static AutoSegment* lookup ( Segment* );
static inline void destroyRequest ( AutoSegment* );
static inline bool isOpen ();
static inline bool doDestroyBaseContact ();
static inline bool doDestroyBaseSegment ();
static inline bool doDestroyTool ();
static bool isInDemoMode ();
static bool doWarnGCellOverload ();
static Session* get ( const char* message=NULL );
static inline Technology* getTechnology ();
static inline AnabaticEngine* getAnabatic ();
static inline const Configuration* getConfiguration ();
static float getSaturateRatio ();
static size_t getSaturateRp ();
static inline size_t getAllowedDepth ();
static DbU::Unit getExtensionCap ();
static inline CellGauge* getCellGauge ();
static inline DbU::Unit getSliceHeight ();
static inline DbU::Unit getSliceStep ();
static inline size_t getGVerticalDepth ();
static inline size_t getGHorizontalDepth ();
static inline DbU::Unit getGHorizontalPitch ();
static inline DbU::Unit getGVerticalPitch ();
static inline size_t getDVerticalDepth ();
static inline const Layer* getDVerticalLayer ();
static inline DbU::Unit getDVerticalWidth ();
static inline DbU::Unit getDVerticalPitch ();
static inline DbU::Unit getDVerticalOffset ();
static inline size_t getDHorizontalDepth ();
static inline const Layer* getDHorizontalLayer ();
static inline DbU::Unit getDHorizontalWidth ();
static inline DbU::Unit getDHorizontalPitch ();
static inline DbU::Unit getDHorizontalOffset ();
static inline size_t getDContactDepth ();
static inline const Layer* getDContactLayer ();
static inline DbU::Unit getDContactWidth ();
static inline DbU::Unit getDContactPitch ();
static inline RoutingGauge* getRoutingGauge ();
static inline RoutingLayerGauge* getLayerGauge ( size_t depth );
static inline size_t getDepth ();
static inline size_t getViaDepth ( const Layer* layer );
static inline size_t getLayerDepth ( const Layer* layer );
static inline const Layer* getRoutingLayer ( size_t );
static inline const Layer* getContactLayer ( size_t );
static Flags getDirection ( size_t depth );
static inline DbU::Unit getPitch ( size_t depth, Flags flags );
static inline DbU::Unit getOffset ( size_t depth );
static inline DbU::Unit getWireWidth ( size_t depth );
static inline DbU::Unit getViaWidth ( size_t depth );
static inline Flags getDirection ( const Layer* );
static inline DbU::Unit getPitch ( const Layer*, Flags flags );
static inline DbU::Unit getOffset ( const Layer* );
static inline DbU::Unit getWireWidth ( const Layer* );
static inline DbU::Unit getViaWidth ( const Layer* );
static inline DbU::Unit getExtensionCap ( const Layer* );
static inline Point getNearestGridPoint ( Point, Box constraints );
static inline size_t getSegmentStackSize ();
static inline size_t getContactStackSize ();
static inline const vector<AutoSegment*>& getInvalidateds ();
static inline const vector<AutoSegment*>& getRevalidateds ();
static inline const set<AutoSegment*>& getDestroyeds ();
static inline const vector<AutoSegment*>& getDoglegs ();
static inline const set<Net*>& getNetsModificateds ();
static void close ();
static void setAnabaticFlags ( Flags );
static inline void dogleg ( AutoSegment* );
static inline void doglegReset ();
static inline void revalidateTopology ();
static inline void setInvalidateMask ( Flags );
static inline void invalidate ( Net* );
static inline void invalidate ( AutoContact* );
static inline void invalidate ( AutoSegment* );
static inline size_t revalidate ();
static void link ( AutoContact* );
static void link ( AutoSegment* );
static void unlink ( AutoContact* );
static void unlink ( AutoSegment* );
static AutoContact* lookup ( Contact* );
static AutoSegment* lookup ( Segment* );
static inline void destroyRequest ( AutoSegment* );
// Methods.
static Session* _open ( AnabaticEngine* );
bool _doDestroyBaseContact ();
bool _doDestroyBaseSegment ();
bool _doDestroyTool ();
virtual Configuration* _getConfiguration ();
inline void _dogleg ( AutoSegment* );
inline void _doglegReset ();
void _invalidate ( Net* );
inline void _invalidate ( AutoContact* );
inline void _invalidate ( AutoSegment* );
inline void _destroyRequest ( AutoSegment* );
void _canonize ();
void _revalidateTopology ();
virtual size_t _revalidate ();
DbU::Unit _getPitch ( size_t depth, Flags flags ) const;
DbU::Unit _getNearestTrackAxis ( const Layer*, DbU::Unit, uint32_t mode );
Point _getNearestGridPoint ( Point, Box constraints );
Record* _getRecord () const;
string _getString () const;
inline string _getTypeName () const;
static Session* _open ( AnabaticEngine* );
bool _doDestroyBaseContact ();
bool _doDestroyBaseSegment ();
bool _doDestroyTool ();
virtual Configuration* _getConfiguration ();
inline void _dogleg ( AutoSegment* );
inline void _doglegReset ();
void _invalidate ( Net* );
inline void _invalidate ( AutoContact* );
inline void _invalidate ( AutoSegment* );
inline void _destroyRequest ( AutoSegment* );
void _canonize ();
void _revalidateTopology ();
virtual size_t _revalidate ();
DbU::Unit _getPitch ( size_t depth, Flags flags ) const;
Point _getNearestGridPoint ( Point, Box constraints );
Record* _getRecord () const;
string _getString () const;
inline string _getTypeName () const;
protected:
static Session* _session;
AnabaticEngine* _anabatic;
Technology* _technology;
CellGauge* _cellGauge;
RoutingGauge* _routingGauge;
vector<AutoContact*> _autoContacts;
vector<AutoSegment*> _doglegs;
vector<AutoSegment*> _segmentInvalidateds;
vector<AutoSegment*> _segmentRevalidateds;
set<Net*,DBo::CompareById> _netInvalidateds;
set<Net*,DBo::CompareById> _netRevalidateds;
set<AutoSegment*> _destroyedSegments;
static Session* _session;
AnabaticEngine* _anabatic;
Technology* _technology;
CellGauge* _cellGauge;
RoutingGauge* _routingGauge;
vector<AutoContact*> _autoContacts;
vector<AutoSegment*> _doglegs;
vector<AutoSegment*> _segmentInvalidateds;
vector<AutoSegment*> _segmentRevalidateds;
set<Net*> _netInvalidateds;
set<Net*> _netRevalidateds;
set<AutoSegment*> _destroyedSegments;
// Constructors.
protected:
@ -211,91 +197,83 @@ namespace Anabatic {
// Inline Functions.
inline bool Session::isOpen () { return get() != NULL; }
inline Technology* Session::getTechnology () { return get("getTechnology()")->_technology; }
inline CellGauge* Session::getCellGauge () { return get("getCellGauge()")->_cellGauge; }
inline RoutingGauge* Session::getRoutingGauge () { return get("getRoutingGauge()")->_routingGauge; }
inline bool Session::doDestroyBaseContact () { return get("doDestroyBaseContact()")->_doDestroyBaseContact(); }
inline bool Session::doDestroyBaseSegment () { return get("doDestroyBaseSegment()")->_doDestroyBaseSegment(); }
inline bool Session::doDestroyTool () { return get("doDestroyTool()")->_doDestroyTool(); }
inline const Configuration* Session::getConfiguration () { return get("getConfiguration()")->_getConfiguration(); }
inline AnabaticEngine* Session::getAnabatic () { return get("getAnabatic()")->_anabatic; }
inline void Session::revalidateTopology () { return get("revalidateTopology()")->_revalidateTopology(); }
inline size_t Session::revalidate () { return get("revalidate()")->_revalidate(); }
inline size_t Session::getSegmentStackSize () { return get("getSegmentStackSize()")->_segmentInvalidateds.size(); }
inline size_t Session::getContactStackSize () { return get("getContactStackSize()")->_autoContacts.size(); }
inline const vector<AutoSegment*>& Session::getInvalidateds () { return get("getInvalidateds()")->_segmentInvalidateds; }
inline const vector<AutoSegment*>& Session::getRevalidateds () { return get("getRevalidateds()")->_segmentRevalidateds; }
inline const set<AutoSegment*>& Session::getDestroyeds () { return get("getDestroyeds()")->_destroyedSegments; }
inline const vector<AutoSegment*>& Session::getDoglegs () { return get("getDoglegs()")->_doglegs; }
inline const set<Net*,DBo::CompareById>& Session::getNetsModificateds () { return get("getNetsModificateds()")->_netRevalidateds; }
inline void Session::doglegReset () { return get("doglegReset()")->_doglegReset (); }
inline void Session::invalidate ( Net* net ) { return get("invalidate(Net*)")->_invalidate(net); }
inline void Session::invalidate ( AutoContact* autoContact ) { return get("invalidate(AutoContact*)")->_invalidate(autoContact); }
inline void Session::invalidate ( AutoSegment* autoSegment ) { return get("invalidate(AutoSegment*)")->_invalidate(autoSegment); }
inline void Session::dogleg ( AutoSegment* autoSegment ) { return get("dogleg(AutoSegment*)")->_dogleg(autoSegment); }
inline void Session::destroyRequest ( AutoSegment* autoSegment ) { return get("destroyRequest(AutoSegment*)")->_destroyRequest(autoSegment); }
inline size_t Session::getAllowedDepth () { return getConfiguration()->getAllowedDepth(); }
inline DbU::Unit Session::getSliceHeight () { return getCellGauge()->getSliceHeight(); }
inline DbU::Unit Session::getSliceStep () { return getCellGauge()->getSliceStep(); }
inline size_t Session::getGVerticalDepth () { return getConfiguration()->getGVerticalDepth(); }
inline size_t Session::getGHorizontalDepth () { return getConfiguration()->getGHorizontalDepth(); }
inline DbU::Unit Session::getGVerticalPitch () { return getConfiguration()->getGVerticalPitch(); }
inline DbU::Unit Session::getGHorizontalPitch () { return getConfiguration()->getGHorizontalPitch(); }
inline size_t Session::getDVerticalDepth () { return getConfiguration()->getDVerticalDepth(); }
inline const Layer* Session::getDVerticalLayer () { return getConfiguration()->getDVerticalLayer(); }
inline DbU::Unit Session::getDVerticalWidth () { return getConfiguration()->getDVerticalWidth(); }
inline DbU::Unit Session::getDPVerticalWidth () { return getConfiguration()->getDPVerticalWidth(); }
inline DbU::Unit Session::getDVerticalPitch () { return getConfiguration()->getDVerticalPitch(); }
inline DbU::Unit Session::getDVerticalOffset () { return getConfiguration()->getDVerticalOffset(); }
inline size_t Session::getDHorizontalDepth () { return getConfiguration()->getDHorizontalDepth(); }
inline const Layer* Session::getDHorizontalLayer () { return getConfiguration()->getDHorizontalLayer(); }
inline DbU::Unit Session::getDHorizontalWidth () { return getConfiguration()->getDHorizontalWidth(); }
inline DbU::Unit Session::getDPHorizontalWidth () { return getConfiguration()->getDPHorizontalWidth(); }
inline DbU::Unit Session::getDHorizontalPitch () { return getConfiguration()->getDHorizontalPitch(); }
inline DbU::Unit Session::getDHorizontalOffset () { return getConfiguration()->getDHorizontalOffset(); }
inline size_t Session::getDContactDepth () { return getConfiguration()->getDContactDepth(); }
inline const Layer* Session::getDContactLayer () { return getConfiguration()->getDContactLayer(); }
inline DbU::Unit Session::getDContactWidth () { return getConfiguration()->getDContactWidth(); }
inline DbU::Unit Session::getDContactPitch () { return getConfiguration()->getDContactPitch(); }
inline bool Session::isGLayer ( const Layer* layer ) { return getConfiguration()->isGLayer(layer); }
inline bool Session::isGMetal ( const Layer* layer ) { return getConfiguration()->isGMetal(layer); }
inline bool Session::isGContact ( const Layer* layer ) { return getConfiguration()->isGContact(layer); }
inline bool Session::isGaugeLayer ( const Layer* layer ) { return getRoutingGauge()->hasLayer(layer); }
inline RoutingLayerGauge* Session::getLayerGauge ( const Layer* layer ) { return getRoutingGauge()->getLayerGauge(layer); }
inline RoutingLayerGauge* Session::getLayerGauge ( size_t depth ) { return getRoutingGauge()->getLayerGauge(depth); }
inline size_t Session::getDepth () { return getRoutingGauge()->getDepth(); }
inline size_t Session::getViaDepth ( const Layer* layer ) { return getRoutingGauge()->getViaDepth(layer); }
inline size_t Session::getLayerDepth ( const Layer* layer ) { return getRoutingGauge()->getLayerDepth(layer); }
inline const Layer* Session::getRoutingLayer ( size_t depth ) { return getRoutingGauge()->getRoutingLayer(depth); }
inline const Layer* Session::getContactLayer ( size_t depth ) { return getRoutingGauge()->getContactLayer(depth); }
inline const Layer* Session::getBuildRoutingLayer ( size_t depth ) { return getRoutingGauge()->getRoutingLayer(depth+getRoutingGauge()->getFirstRoutingLayer()); }
inline const Layer* Session::getBuildContactLayer ( size_t depth ) { return getRoutingGauge()->getContactLayer(depth+getRoutingGauge()->getFirstRoutingLayer()); }
inline DbU::Unit Session::getPitch ( size_t depth, Flags flags=Flags::NoFlags ) { return get("getPitch(depth,flags)")->_getPitch( depth, flags ); }
inline DbU::Unit Session::getOffset ( size_t depth ) { return getRoutingGauge()->getLayerOffset(depth); }
inline DbU::Unit Session::getWireWidth ( size_t depth ) { return getRoutingGauge()->getLayerWireWidth(depth); }
inline DbU::Unit Session::getPWireWidth ( size_t depth ) { return getRoutingGauge()->getLayerPWireWidth(depth); }
inline DbU::Unit Session::getViaWidth ( size_t depth ) { return getRoutingGauge()->getViaWidth(depth); }
inline DbU::Unit Session::getPitch ( const Layer* layer, Flags flags=Flags::NoFlags ) { return getPitch( getLayerDepth(layer), flags ); }
inline DbU::Unit Session::getOffset ( const Layer* layer ) { return getOffset ( getLayerDepth(layer) ); }
inline DbU::Unit Session::getWireWidth ( const Layer* layer ) { return getWireWidth( getLayerDepth(layer) ); }
inline DbU::Unit Session::getViaWidth ( const Layer* layer ) { return getViaWidth ( getViaDepth(layer) ); }
inline DbU::Unit Session::getExtensionCap ( const Layer* layer ) { return getConfiguration()->getExtensionCap(layer); }
inline Flags Session::getDirection ( const Layer* layer ) { return getDirection( getLayerDepth(layer) ); }
inline Point Session::getNearestGridPoint ( Point p, Box b ) { return get("getNearestGridPoint()")->_getNearestGridPoint(p,b); }
inline DbU::Unit Session::getNearestTrackAxis ( const Layer* layer, DbU::Unit axis, uint32_t mode ) { return get("getNearestTrackAxis()")->_getNearestTrackAxis(layer,axis,mode); }
inline void Session::_dogleg ( AutoSegment* segment ) { _doglegs.push_back(segment); }
inline void Session::_doglegReset () { _doglegs.clear(); }
inline void Session::_invalidate ( AutoContact* contact ) { _autoContacts.push_back(contact); }
inline void Session::_invalidate ( AutoSegment* segment ) { _segmentInvalidateds.push_back(segment); }
inline void Session::_destroyRequest ( AutoSegment* segment ) { _destroyedSegments.insert(segment); }
inline string Session::_getTypeName () const { return _TName("Session"); }
inline bool Session::isOpen () { return get() != NULL; }
inline Technology* Session::getTechnology () { return get("getTechnology()")->_technology; }
inline CellGauge* Session::getCellGauge () { return get("getCellGauge()")->_cellGauge; }
inline RoutingGauge* Session::getRoutingGauge () { return get("getRoutingGauge()")->_routingGauge; }
inline bool Session::doDestroyBaseContact () { return get("doDestroyBaseContact()")->_doDestroyBaseContact(); }
inline bool Session::doDestroyBaseSegment () { return get("doDestroyBaseSegment()")->_doDestroyBaseSegment(); }
inline bool Session::doDestroyTool () { return get("doDestroyTool()")->_doDestroyTool(); }
inline const Configuration* Session::getConfiguration () { return get("getConfiguration()")->_getConfiguration(); }
inline AnabaticEngine* Session::getAnabatic () { return get("getAnabatic()")->_anabatic; }
inline void Session::revalidateTopology () { return get("revalidateTopology()")->_revalidateTopology(); }
inline size_t Session::revalidate () { return get("revalidate()")->_revalidate(); }
inline size_t Session::getSegmentStackSize () { return get("getSegmentStackSize()")->_segmentInvalidateds.size(); }
inline size_t Session::getContactStackSize () { return get("getContactStackSize()")->_autoContacts.size(); }
inline const vector<AutoSegment*>& Session::getInvalidateds () { return get("getInvalidateds()")->_segmentInvalidateds; }
inline const vector<AutoSegment*>& Session::getRevalidateds () { return get("getRevalidateds()")->_segmentRevalidateds; }
inline const set<AutoSegment*>& Session::getDestroyeds () { return get("getDestroyeds()")->_destroyedSegments; }
inline const vector<AutoSegment*>& Session::getDoglegs () { return get("getDoglegs()")->_doglegs; }
inline const set<Net*>& Session::getNetsModificateds () { return get("getNetsModificateds()")->_netRevalidateds; }
inline void Session::doglegReset () { return get("doglegReset()")->_doglegReset (); }
inline void Session::invalidate ( Net* net ) { return get("invalidate(Net*)")->_invalidate(net); }
inline void Session::invalidate ( AutoContact* autoContact ) { return get("invalidate(AutoContact*)")->_invalidate(autoContact); }
inline void Session::invalidate ( AutoSegment* autoSegment ) { return get("invalidate(AutoSegment*)")->_invalidate(autoSegment); }
inline void Session::dogleg ( AutoSegment* autoSegment ) { return get("dogleg(AutoSegment*)")->_dogleg(autoSegment); }
inline void Session::destroyRequest ( AutoSegment* autoSegment ) { return get("destroyRequest(AutoSegment*)")->_destroyRequest(autoSegment); }
inline size_t Session::getAllowedDepth () { return getConfiguration()->getAllowedDepth(); }
inline DbU::Unit Session::getSliceHeight () { return getCellGauge()->getSliceHeight(); }
inline DbU::Unit Session::getSliceStep () { return getCellGauge()->getSliceStep(); }
inline size_t Session::getGVerticalDepth () { return getConfiguration()->getGVerticalDepth(); }
inline size_t Session::getGHorizontalDepth () { return getConfiguration()->getGHorizontalDepth(); }
inline DbU::Unit Session::getGVerticalPitch () { return getConfiguration()->getGVerticalPitch(); }
inline DbU::Unit Session::getGHorizontalPitch () { return getConfiguration()->getGHorizontalPitch(); }
inline size_t Session::getDVerticalDepth () { return getConfiguration()->getDVerticalDepth(); }
inline const Layer* Session::getDVerticalLayer () { return getConfiguration()->getDVerticalLayer(); }
inline DbU::Unit Session::getDVerticalWidth () { return getConfiguration()->getDVerticalWidth(); }
inline DbU::Unit Session::getDVerticalPitch () { return getConfiguration()->getDVerticalPitch(); }
inline DbU::Unit Session::getDVerticalOffset () { return getConfiguration()->getDVerticalOffset(); }
inline size_t Session::getDHorizontalDepth () { return getConfiguration()->getDHorizontalDepth(); }
inline const Layer* Session::getDHorizontalLayer () { return getConfiguration()->getDHorizontalLayer(); }
inline DbU::Unit Session::getDHorizontalWidth () { return getConfiguration()->getDHorizontalWidth(); }
inline DbU::Unit Session::getDHorizontalPitch () { return getConfiguration()->getDHorizontalPitch(); }
inline DbU::Unit Session::getDHorizontalOffset () { return getConfiguration()->getDHorizontalOffset(); }
inline size_t Session::getDContactDepth () { return getConfiguration()->getDContactDepth(); }
inline const Layer* Session::getDContactLayer () { return getConfiguration()->getDContactLayer(); }
inline DbU::Unit Session::getDContactWidth () { return getConfiguration()->getDContactWidth(); }
inline DbU::Unit Session::getDContactPitch () { return getConfiguration()->getDContactPitch(); }
inline RoutingLayerGauge* Session::getLayerGauge ( size_t depth ) { return getRoutingGauge()->getLayerGauge(depth); }
inline size_t Session::getDepth () { return getRoutingGauge()->getDepth(); }
inline size_t Session::getViaDepth ( const Layer* layer ) { return getRoutingGauge()->getViaDepth(layer); }
inline size_t Session::getLayerDepth ( const Layer* layer ) { return getRoutingGauge()->getLayerDepth(layer); }
inline const Layer* Session::getRoutingLayer ( size_t depth ) { return getRoutingGauge()->getRoutingLayer(depth); }
inline const Layer* Session::getContactLayer ( size_t depth ) { return getRoutingGauge()->getContactLayer(depth); }
inline DbU::Unit Session::getPitch ( size_t depth, Flags flags=Flags::NoFlags ) { return get("getPitch(depth,flags)")->_getPitch( depth, flags ); }
inline DbU::Unit Session::getOffset ( size_t depth ) { return getRoutingGauge()->getLayerOffset(depth); }
inline DbU::Unit Session::getWireWidth ( size_t depth ) { return getRoutingGauge()->getLayerWireWidth(depth); }
inline DbU::Unit Session::getViaWidth ( size_t depth ) { return getRoutingGauge()->getViaWidth(depth); }
inline DbU::Unit Session::getPitch ( const Layer* layer, Flags flags=Flags::NoFlags ) { return getPitch( getLayerDepth(layer), flags ); }
inline DbU::Unit Session::getOffset ( const Layer* layer ) { return getOffset ( getLayerDepth(layer) ); }
inline DbU::Unit Session::getWireWidth ( const Layer* layer ) { return getWireWidth( getLayerDepth(layer) ); }
inline DbU::Unit Session::getViaWidth ( const Layer* layer ) { return getViaWidth ( getViaDepth(layer) ); }
inline DbU::Unit Session::getExtensionCap ( const Layer* layer ) { return getConfiguration()->getExtensionCap(layer); }
inline Flags Session::getDirection ( const Layer* layer ) { return getDirection( getLayerDepth(layer) ); }
inline Point Session::getNearestGridPoint ( Point p, Box b ) { return get("getNearestGridPoint()")->_getNearestGridPoint(p,b); }
inline void Session::_dogleg ( AutoSegment* segment ) { _doglegs.push_back(segment); }
inline void Session::_doglegReset () { _doglegs.clear(); }
inline void Session::_invalidate ( AutoContact* contact ) { _autoContacts.push_back(contact); }
inline void Session::_invalidate ( AutoSegment* segment ) { _segmentInvalidateds.push_back(segment); }
inline void Session::_destroyRequest ( AutoSegment* segment ) { _destroyedSegments.insert(segment); }
inline string Session::_getTypeName () const { return _TName("Session"); }
} // Anabatic namespace.
INSPECTOR_P_SUPPORT(Anabatic::Session);
#endif // ANABATIC_SESSION_H

View File

@ -3,15 +3,14 @@
set(CMAKE_LEGACY_CYGWIN_WIN32 0)
project(Bootstrap)
cmake_minimum_required(VERSION 3.16)
cmake_minimum_required(VERSION 2.4.0)
set(ignoreVariables USE_LIBBFD "${BUILD_DOC} ${CMAKE_INSTALL_DIR}")
set(ignoreVariables "${BUILD_DOC}")
add_subdirectory(cmake_modules)
list(INSERT CMAKE_MODULE_PATH 0 "${Bootstrap_SOURCE_DIR}/cmake_modules/")
find_package(Bootstrap REQUIRED)
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development.Module )
find_package(Bootstrap REQUIRED)
find_package(PythonSitePackages REQUIRED)
print_cmake_module_path()
@ -24,7 +23,7 @@
OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
install(DIRECTORY builder
DESTINATION ${Python_CORIOLISLIB} )
DESTINATION ${PYTHON_SITE_PACKAGES} )
install(FILES ccb.py
DESTINATION bin
@ -32,10 +31,3 @@
PERMISSIONS OWNER_WRITE
OWNER_READ GROUP_READ WORLD_READ
OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
install(FILES crlenv.py
DESTINATION bin
RENAME crlenv
PERMISSIONS OWNER_WRITE
OWNER_READ GROUP_READ WORLD_READ
OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)

View File

@ -1,38 +0,0 @@
#!/bin/bash
#. /etc/*-release
#arch="Linux.el9"
#if [ "`echo ${VERSION} | cut -c 1`" == "7" ]; then
# echo "Building for RHEL 7"
# arch="Linux.el7_64"
#fi
arch="Linux.el9"
if [ "`hostname -s`" == "bop" ]; then
echo "Building for RHEL 7"
arch="Linux.el7_64"
fi
nightly=""
if [[ "`pwd`" =~ /nightly/ ]]; then
nightly="/nightly"
fi
srcDir=${HOME}${nightly}/coriolis-2.x/src/alliance/alliance/src
commonRoot=${HOME}${nightly}/coriolis-2.x/${arch}/Release.Shared
#commonRoot=${HOME}${nightly}/coriolis-2.x/${arch}/Debug.Shared
buildDir=${commonRoot}/build
installDir=${commonRoot}/install
export ALLIANCE_TOP=${installDir}
export LD_LIBRARY_PATH=${installDir}/lib:${LD_LIBRARY_PATH}
cd ${srcDir}
# Skip doc generation to avoid pulling TeXLive in docker images.
sed -i 's,dirs="\$newdirs documentation",dirs="$newdirs",' ./autostuff
./autostuff clean
./autostuff
mkdir -p ${buildDir}
cd ${buildDir}
${srcDir}/configure --prefix=${ALLIANCE_TOP} --enable-alc-shared
make -j1 install

View File

@ -14,19 +14,19 @@ projects = [
, { 'name' : "coriolis"
, 'tools' : [ "bootstrap"
, "lefdef"
, "coloquinte"
, "flute"
, "vlsisapd"
, "hurricane"
, "crlcore"
, "flute"
, "etesian"
, "anabatic"
, "katana"
#, "knik"
#, "katabatic"
#, "kite"
#, "equinox"
#, "solstice"
, "tramontana"
, "knik"
, "katabatic"
, "kite"
, "coloquinte"
, "etesian"
, "equinox"
, "solstice"
, "oroshi"
, "bora"
, "karakaze"

View File

@ -2,88 +2,98 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | T o o l c h a i n B u i l d e r |
# | C o r i o l i s / C h a m s B u i l d e r |
# | |
# | Author : Jean-Paul Chaput |
# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./builder/AboutWidget.py" |
# +-----------------------------------------------------------------+
from PyQt4.QtCore import Qt
from PyQt4.QtGui import QPalette, QColor, QFont, QWidget, \
QFrame, QLabel, QVBoxLayout, QAction, \
QKeySequence, QApplication
from PyQt4.QtCore import Qt
from PyQt4.QtGui import QPalette
from PyQt4.QtGui import QColor
from PyQt4.QtGui import QFont
from PyQt4.QtGui import QWidget
from PyQt4.QtGui import QFrame
from PyQt4.QtGui import QLabel
from PyQt4.QtGui import QVBoxLayout
from PyQt4.QtGui import QAction
from PyQt4.QtGui import QKeySequence
from PyQt4.QtGui import QApplication
class AboutWidget ( QWidget ):
def __init__ ( self, parent=None ):
QWidget.__init__ ( self, parent )
self.setFixedSize( 500, 400 )
self.setStyleSheet( 'background-color: #ffffdd;' )
def __init__ ( self, parent=None ):
QWidget.__init__ ( self, parent )
self.setFixedSize( 500, 400 )
self.setStyleSheet( 'background-color: #ffffdd;' )
topLine = QFrame()
topLine.setFrameShape( QFrame.HLine )
topLine.setLineWidth ( 2 )
botLine = QFrame()
botLine.setFrameShape( QFrame.HLine )
botLine.setLineWidth ( 2 )
topLine = QFrame()
topLine.setFrameShape( QFrame.HLine )
topLine.setLineWidth ( 2 )
botLine = QFrame()
botLine.setFrameShape( QFrame.HLine )
botLine.setLineWidth ( 2 )
title = QLabel( 'CCB' )
title.setAlignment( Qt.AlignCenter )
font = title.font()
font.setPointSize( 72 )
font.setWeight ( QFont.Bold )
title.setFont( font )
title = QLabel( 'CCB' )
title.setAlignment( Qt.AlignCenter )
font = title.font()
font.setPointSize( 72 )
font.setWeight ( QFont.Bold )
title.setFont( font )
subTitle = QLabel( 'Coriolis Toolchain Builder for the Dummies' )
subTitle.setAlignment( Qt.AlignCenter )
subTitle.setFont( QFont('Courier',10,QFont.Bold) )
authors = QLabel( 'Coriolis CAD System 3.0 . . . . . . . . ccb 1.0\n'
'Copyright (c) 2008-2021 . . Sorbonne Universite\n'
'Authors . . . . . . . . . . . . . Damien Dupuis\n'
' . . . . . . . . . . . . Jean-Paul Chaput\n'
'E-Mail . . . . . . . . Jean-Paul.Chaput@lip6.fr'
)
authors.setAlignment( Qt.AlignCenter )
authors.setFont( QFont('Courier',10,QFont.Bold) )
subTitle = QLabel( 'Coriolis & Chams Builder for the Dummies' )
subTitle.setAlignment( Qt.AlignCenter )
subTitle.setFont( QFont('Courier',10,QFont.Bold) )
authors = QLabel( 'Coriolis CAD System 1.0 . . . . . . . . ccb 1.0\n'
'Copyright (c) 2008-2016 . . . . . . . . . . UPMC\n'
'Authors . . . . . . . . . . . . . Damien Dupuis\n'
' . . . . . . . . . . . . Jean-Paul Chaput\n'
'E-Mail . . . . . . . . Jean-Paul.Chaput@lip6.fr'
)
authors.setAlignment( Qt.AlignCenter )
authors.setFont( QFont('Courier',10,QFont.Bold) )
vLayout = QVBoxLayout()
vLayout.addStretch(10)
vLayout.addWidget( topLine )
vLayout.addWidget( title )
vLayout.addStretch(1)
vLayout.addWidget( subTitle )
vLayout.addWidget( authors )
vLayout.addStretch(1)
vLayout.addWidget( botLine )
vLayout.addStretch(10)
frame = QFrame()
frame.setFrameShape ( QFrame.Box )
frame.setFrameShadow( QFrame.Sunken )
frame.setLayout ( vLayout )
frame.setLineWidth ( 1 )
vLayout = QVBoxLayout()
vLayout.addWidget( frame )
vLayout = QVBoxLayout()
vLayout.addStretch(10)
vLayout.addWidget( topLine )
vLayout.addWidget( title )
vLayout.addStretch(1)
vLayout.addWidget( subTitle )
vLayout.addWidget( authors )
vLayout.addStretch(1)
vLayout.addWidget( botLine )
vLayout.addStretch(10)
self.setLayout( vLayout )
self._exitAction = QAction( '&Exit', self )
self._exitAction.setStatusTip( 'Exit CCB (settings are saved)' )
self._exitAction.setShortcut ( QKeySequence('CTRL+Q') )
self._exitAction.triggered.connect( QApplication.closeAllWindows )
self.addAction( self._exitAction )
self._closeAction = QAction( '&Close', self )
self._closeAction.setStatusTip( 'Close the About Window' )
self._closeAction.setShortcut ( QKeySequence('CTRL+A') )
self._closeAction.triggered.connect( self.close )
self.addAction( self._closeAction )
frame = QFrame()
frame.setFrameShape ( QFrame.Box )
frame.setFrameShadow( QFrame.Sunken )
frame.setLayout ( vLayout )
frame.setLineWidth ( 1 )
vLayout = QVBoxLayout()
vLayout.addWidget( frame )
self.setLayout( vLayout )
self._exitAction = QAction( '&Exit', self )
self._exitAction.setStatusTip( 'Exit CCB (settings are saved)' )
self._exitAction.setShortcut ( QKeySequence('CTRL+Q') )
self._exitAction.triggered.connect( QApplication.closeAllWindows )
self.addAction( self._exitAction )
self._closeAction = QAction( '&Close', self )
self._closeAction.setStatusTip( 'Close the About Window' )
self._closeAction.setShortcut ( QKeySequence('CTRL+A') )
self._closeAction.triggered.connect( self.close )
self.addAction( self._closeAction )
return
return

View File

@ -1,14 +1,14 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) Sorbonne Université 2008-2021, All Rights Reserved
# Copyright (c) UPMC/LIP6 2008-2018, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | T o o l c h a i n B u i l d e r |
# | C o r i o l i s / C h a m s B u i l d e r |
# | |
# | Author : Jean-Paul Chaput |
# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./builder/Builder.py" |
# +-----------------------------------------------------------------+
@ -20,9 +20,9 @@ import os
import os.path
import datetime
import subprocess
from . import ErrorMessage
from .Project import Project
from .Configuration import Configuration
from . import ErrorMessage
from Project import Project
from Configuration import Configuration
class Builder:
@ -35,13 +35,10 @@ class Builder:
self._noCache = False
self._ninja = False
self._clang = False
self._manylinux = False
self._noSystemBoost = False
self._macports = False
self._devtoolset = 0
self._llvmtoolset = 0
self._bfd = "OFF"
self._qt4 = False
self._qt5 = False
self._openmp = False
self._enableShared = "ON"
self._enableDoc = "OFF"
@ -52,28 +49,27 @@ class Builder:
self._environment = os.environ
return
def __setattr__ ( self, attribute, value ):
if attribute[0] == "_":
self.__dict__[attribute] = value
return
if attribute in self._conf.getAllIds(): setattr( self._conf, attribute, value )
if attribute == "quiet": self._quiet = value
elif attribute == "rmBuild": self._rmBuild = value
elif attribute == "doBuild": self._doBuild = value
elif attribute == "noCache": self._noCache = value
elif attribute == "ninja": self._ninja = value
elif attribute == "clang": self._clang = value
elif attribute == "manylinux": self._manylinux = value
elif attribute == "macports":
self._macports = value
if value: self._noSystemBoost = True
elif attribute == "devtoolset":
self._devtoolset = value
if value: self._noSystemBoost = True
elif attribute == "llvmtoolset":
self._llvmtoolset = value
elif attribute == "bfd": self._bfd = value
elif attribute == "qt4": self._qt4 = value
elif attribute == "qt5": self._qt5 = value
elif attribute == "openmp": self._openmp = value
elif attribute == "enableDoc": self._enableDoc = value
elif attribute == "enableShared": self._enableShared = value
@ -83,15 +79,18 @@ class Builder:
elif attribute == "makeArguments": self._makeArguments = value.split ()
return
def __getattr__ ( self, attribute ):
if attribute[0] != "_":
if attribute == 'conf': return self._conf
if attribute in self._conf.getAllIds():
return getattr( self._conf, attribute )
if not attribute in self.__dict__:
if not self.__dict__.has_key(attribute):
raise ErrorMessage( 1, 'Builder has no attribute <%s>.'%attribute )
return self.__dict__[attribute]
def _guessGitHash ( self, project ):
self.gitHash = 'x'
os.chdir ( self.sourceDir+'/'+project.getName() )
@ -99,48 +98,51 @@ class Builder:
self.gitHash = subprocess.Popen ( command, stdout=subprocess.PIPE ).stdout.readlines()[0]
return
def _configure ( self, fileIn, fileOut ):
fdFileIn = open ( fileIn , "r" )
fdFileOut = open ( fileOut, "w" )
for line in fdFileIn.readlines():
stable = False
substituted0 = line
while not stable:
substituted1 = re.sub ( r"@revdate@" , self.revDate, substituted0 )
substituted1 = re.sub ( r"@githash@" , self.gitHash, substituted1 )
substituted1 = re.sub ( r"@coriolisTop@", "/usr" , substituted1 )
if substituted0 == substituted1: stable = True
else: substituted0 = substituted1
fdFileOut.write ( substituted0 )
fdFileIn.close ()
fdFileOut.close ()
return
def _doSpec ( self ):
self._configure ( self.specFileIn, self.specFile )
return
def _doDebChangelog ( self ):
self._configure ( self.debChangelogIn, self.debChangelog )
return
def _execute ( self, command, error ):
collections = []
if self._devtoolset:
collections.append( 'devtoolset-{}'.format(self._devtoolset) )
print( 'Using devtoolset-{0} (scl enable devtoolset-{0} ...)'.format(self._devtoolset) )
if self._llvmtoolset:
collections.append( 'llvm-toolset-{}'.format(self._llvmtoolset) )
print( 'Using llvm-toolset-{0} (scl enable llvm-toolset-{v} ...)'.format(self._llvmtoolset) )
if collections:
print 'Using devtoolset-%(v)d (scl enable devtoolset-%(v)d ...)' % {'v':self._devtoolset}
commandAsString = ''
for i in range(len(command)):
if i: commandAsString += ' '
if ' ' in command[i]: commandAsString += '"'+command[i]+'"'
else: commandAsString += command[i]
command = [ 'scl', 'enable' ]
command += collections
command.append( commandAsString )
command = [ 'scl', 'enable', 'devtoolset-%d' % self._devtoolset
, commandAsString ]
#print command
sys.stdout.flush ()
sys.stderr.flush ()
child = subprocess.Popen ( command, env=self._environment, stdout=None )
@ -150,49 +152,49 @@ class Builder:
ErrorMessage( status, "%s (status:%d)."%(error,status) ).terminate()
return
def _enableTool ( self, tool ):
return
def _build ( self, tool ):
toolSourceDir = os.path.join ( self.sourceDir, tool.getToolDir() )
toolBuildDir = os.path.join ( self.buildDir , tool.name )
cmakeInstallDir = os.path.join ( self.installDir, "share", "cmake", "Modules" )
# Supplied directly in the CMakeLists.txt.
#cmakeModules = os.path.join ( self.installDir, "share", "cmake", "Modules" )
if not os.path.isdir(toolSourceDir):
print( ErrorMessage( 0, 'Missing tool source directory: "{}" (skipped).' \
.format(toolSourceDir) ))
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir )
return
if self._rmBuild:
print( 'Removing tool build directory: "{}".'.format(toolBuildDir) )
print "Removing tool build directory: \"%s\"." % toolBuildDir
command = [ "/bin/rm", "-rf", toolBuildDir ]
self._execute ( command, "Removing tool build directory" )
command = [ 'cmake' ]
if self.libSuffix: command += [ "-D", "LIB_SUFFIX:STRING=%s" % self.libSuffix ]
if self._ninja: command += [ "-G", "Ninja" ]
if self._macports: command += [ "-D", "WITH_MACPORTS:STRING=TRUE" ]
if self._noSystemBoost: command += [ "-D", "Boost_NO_SYSTEM_PATHS:STRING=TRUE"
#, "-D", "BOOST_INCLUDEDIR:STRING=/usr/include/boost169"
#, "-D", "BOOST_LIBRARYDIR:STRING=/usr/lib64/boost169"
, "-D", "BOOST_INCLUDEDIR:STRING=/usr/include/boost157"
, "-D", "BOOST_LIBRARYDIR:STRING=/usr/lib/boost157"
]
if self._bfd: command += [ "-D", "USE_LIBBFD:STRING=%s" % self._bfd ]
if self._qt4: command += [ "-D", "WITH_QT4:STRING=TRUE" ]
if self._qt5: command += [ "-D", "WITH_QT5:STRING=TRUE" ]
if self._openmp: command += [ "-D", "WITH_OPENMP:STRING=TRUE" ]
if self._manylinux: command += [ "-D", "USE_MANYLINUX:STRING=TRUE" ]
command += [ "-D", "CMAKE_BUILD_TYPE:STRING=%s" % self.buildMode
#, "-D", "BUILD_SHARED_LIBS:STRING=%s" % self.enableShared
, "-D", "CMAKE_INSTALL_PREFIX:STRING=%s" % self.installDir
, "-D", "CMAKE_INSTALL_DIR:STRING=%s" % cmakeInstallDir
#, "-D", "CMAKE_MODULE_PATH:STRING=%s" % cmakeModules
#, "-D", "Boost_DEBUG:STRING=TRUE"
, toolSourceDir ]
if not os.path.isdir(toolBuildDir):
print( 'Creating tool build directory: "{}".'.format(toolBuildDir) )
print "Creating tool build directory: \"%s\"." % toolBuildDir
os.makedirs ( toolBuildDir )
os.chdir ( toolBuildDir )
self._execute ( command, "First CMake failed" )
os.chdir ( toolBuildDir )
if self._noCache:
cmakeCache = os.path.join(toolBuildDir,"CMakeCache.txt")
@ -208,20 +210,25 @@ class Builder:
if self._checkDeterminism == 'ON': command += [ "-D", "CHECK_DETERMINISM:STRING=ON" ]
command += [ toolSourceDir ]
print self._noSystemBoost
print command
self._execute ( command, "Second CMake failed" )
if self._doBuild:
command = [ "make" ]
if self._ninja:
command = [ "ninja-build" ]
#command += [ "DESTDIR=%s" % self.installDir ]
command += self._makeArguments
print( "Make/Ninja command:", command )
print "Make/Ninja command:", command
sys.stdout.flush ()
self._execute ( command, "Build failed" )
return
def gitArchive ( self, projectName ):
rawArchive = self.tarballDir+'/'+projectName+'.tar'
os.chdir ( self.sourceDir+'/'+projectName )
command = [ 'git'
, 'archive'
@ -230,10 +237,11 @@ class Builder:
, 'devel'
]
self._execute ( command, "git archive of project %s" % projectName )
if not os.path.isdir ( self.archiveDir ):
os.mkdir ( self.archiveDir )
os.chdir ( self.archiveDir )
os.chdir ( self.archiveDir )
command = [ 'tar', 'xf', rawArchive ]
self._execute ( command, "unpacking raw archive %s" % rawArchive )
@ -244,7 +252,7 @@ class Builder:
command = [ "/bin/ln", "-s", "./coriolis/bootstrap/Makefile.package"
, self.archiveDir+"/Makefile" ]
self._execute ( command, "link of %s failed" % "coriolis/boostrap/Makefile.package")
command = [ "/bin/ln", "-s", "./coriolis/bootstrap/debian", self.archiveDir ]
self._execute ( command, "Copying Debian/Ubuntu package control files" )
@ -263,101 +271,123 @@ class Builder:
# , "--no-backup-if-mismatch"
# , "-p0", "-i", self.distribPatch ]
# self._execute ( command, "patch for distribution command failed" )
absSourceTarBz2 = '%s/%s' % (self.tarballDir,self.sourceTarBz2)
os.chdir ( self.tarballDir )
command = [ 'tar', 'jcf', absSourceTarBz2, os.path.basename(self.archiveDir) ]
self._execute ( command, "Creating composite archive %s" % absSourceTarBz2 )
return
def _setEnvironment ( self, systemVariable, userVariable ):
if not systemVariable in self._environment or self._environment[systemVariable] == "":
if not userVariable in self._environment or self._environment[userVariable] == "" :
if not self._environment.has_key(systemVariable) or self._environment[systemVariable] == "":
if not self._environment.has_key(userVariable) or self._environment[userVariable] == "" :
self._environment[ systemVariable ] = self.installDir
print( '[WARNING] Neither "{0}" nor "{1}" environment variables are sets.' \
.format(systemVariable,userVariable) )
print( ' Setting "{0}" to "{1}".'.format(systemVariable,self.installDir) )
print "[WARNING] Neither <%s> nor <%s> environment variables are sets." \
% (systemVariable,userVariable)
print " Setting <%s> to <%s>." % (systemVariable,self.installDir)
else:
self._environment[ systemVariable ] = self._environment[ userVariable ]
if not self._quiet:
print( 'Setting "{0}" to "{1}".'.format(systemVariable,self._environment[systemVariable]) )
if userVariable in self._environment:
print( 'Transmitting "{0}" as "{1}".'.format(userVariable,self._environment[userVariable]) )
print "Setting <%s> to <%s>." % (systemVariable,self._environment[systemVariable])
if self._environment.has_key(userVariable):
print "Transmitting <%s> as <%s>." % (userVariable,self._environment[userVariable])
return
def _commandTemplate ( self, tools, projects, command ):
if self._clang:
self._environment[ 'CC' ] = 'clang'
self._environment[ 'CXX' ] = 'clang++'
self._environment[ 'CC' ] = '/usr/bin/clang'
self._environment[ 'CXX' ] = '/usr/bin/clang++'
if self._devtoolset:
self._environment[ 'BOOST_INCLUDEDIR' ] = '/opt/rh/devtoolset-%d/root/usr/include' % self._devtoolset
self._environment[ 'BOOST_LIBRARYDIR' ] = '/opt/rh/devtoolset-%d/root/usr/lib' % self._devtoolset
if self._macports:
self._environment[ 'BOOST_INCLUDEDIR' ] = '/opt/local/include'
self._environment[ 'BOOST_LIBRARYDIR' ] = '/opt/local/lib'
# Set or guess the various projects TOP environment variables.
for project in self.projects:
topVariable = "%s_TOP" % project.getName().upper()
topUserVariable = "%s_USER_TOP" % project.getName().upper()
self._setEnvironment ( topVariable, topUserVariable )
if tools:
# Checks if the requested tools are in the various projects.
self.standalones = tools
for project in self.projects:
self.standalones = project.activate ( self.standalones )
for tool in self.standalones:
print( '[WARNING] Tool "{}" is not part of any project.'.format(tool) )
print "[WARNING] Tool \"%s\" is not part of any project." % tool
if projects:
for projectName in projects:
project = self.getProject ( projectName )
if not project:
ErrorMessage( 1, "No project of name \"%s\"."%projectName ).terminate()
project.activateAll()
if not tools and not projects:
for project in self.projects:
project.activateAll ()
for project in self.projects:
for tool in project.getActives():
print( '\nProcessing tool: "{}".'.format(tool.name) )
print "\nProcessing tool: \"%s\"." % tool.name
getattr(self,command) ( tool )
return
def enable ( self, tools, projects ):
self._commandTemplate ( tools, projects, "_enableTool" )
return
def enabledTools ( self ):
tools = []
for project in self.projects:
tools += project.getActives()
return tools
def build ( self, tools, projects ):
self._commandTemplate ( tools, projects, "_build" )
return
def gitTarball ( self, tools, projects ):
if self.gitHash == "x":
self._guessGitHash ( self.getProject(projects[0]) )
self._doSpec ()
# self._doDebChangelog ()
if os.path.isdir(self.tarballDir):
print( 'Removing previous tarball directory: "{}".'.format(self.tarballDir) )
print "Removing previous tarball directory: \"%s\"." % self.tarballDir
command = [ "/bin/rm", "-rf", self.tarballDir ]
self._execute ( command, "Removing top export (tarball) directory" )
print( 'Creating tarball directory: "{}".'.format(self.tarballDir) )
print "Creating tarball directory: \"%s\"." % self.tarballDir
os.makedirs ( self.tarballDir )
self.gitArchive ( projects[0] )
return
def userTarball ( self, tools, projects ):
self.enable( tools, projects )
userSourceTarBz2 = os.path.join ( self.tarballDir
, datetime.date.today().strftime('%s-%s-%%Y%%m%%d.tar.bz2'%
(self.packageName
,self.packageVersion)) )
excludes = []
for exclude in self.packageExcludes:
excludes += [ '--exclude='+exclude ]
os.chdir ( self.sourceDir )
command = [ "/bin/tar"
, "--exclude-backups"
@ -367,34 +397,40 @@ class Builder:
+ [ "-jcvf", userSourceTarBz2 ] \
+ self.enabledTools()
self._execute ( command, "tar command failed" )
return
def doRpm ( self ):
self.gitTarball ( [], self.packageProjects )
for rpmDir in [ "SOURCES", "SPECS", "BUILD", "tmp"
, "SRPMS", "RPMS/i386", "RPMS/i686", "RPMS/x86_64" ]:
rpmFullDir = os.path.join ( self.rpmbuildDir, rpmDir )
if not os.path.isdir(rpmFullDir):
os.makedirs ( rpmFullDir )
else:
for entry in os.listdir(rpmFullDir):
path = os.path.join( rpmFullDir, entry )
if os.path.islink(path):
realpath = os.path.realpath( os.readlink(path) )
if not os.path.isfile(realpath):
print( 'Remove obsolete link: "{}".'.format(path) )
os.unlink( path )
rpmFullDir = os.path.join ( self.rpmbuildDir, rpmDir )
if not os.path.isdir(rpmFullDir):
os.makedirs ( rpmFullDir )
else:
for entry in os.listdir(rpmFullDir):
path = os.path.join( rpmFullDir, entry )
if os.path.islink(path):
realpath = os.path.realpath( os.readlink(path) )
if not os.path.isfile(realpath):
print 'Remove obsolete link: <%s>.' % path
os.unlink( path )
rpmSpecFile = os.path.join ( self.rpmbuildDir, "SPECS" , "coriolis2.spec" )
rpmSourceFile = os.path.join ( self.rpmbuildDir, "SOURCES", self.sourceTarBz2 )
sourceFile = os.path.join ( self.tarballDir , self.sourceTarBz2 )
if os.path.isfile ( rpmSpecFile ):
os.unlink ( rpmSpecFile )
os.symlink ( self.specFile, rpmSpecFile )
if not os.path.islink ( rpmSourceFile ):
os.symlink ( sourceFile, rpmSourceFile )
os.chdir ( self.rpmbuildDir )
command = [ "/usr/bin/rpmbuild"
, "--define", "_topdir %s" % self.rpmbuildDir
, "--define", "_tmppath %s" % self.tmppathDir
@ -403,13 +439,18 @@ class Builder:
if self._devtoolset:
command += [ "--define", "scl devtoolset-%d"%self._devtoolset ]
command += [ "-ba", "--clean", rpmSpecFile ]
self._execute ( command, "Rebuild rpm packages" )
return
def doDeb ( self ):
self.svnTarball ( [], self.packageProjects )
if not os.path.isdir(self.debbuildDir):
os.makedirs ( self.debbuildDir )
os.chdir ( self.debbuildDir )
sourceFile = os.path.join ( self.tarballDir , self.sourceTarBz2 )
debOrigFile = os.path.join ( self.debbuildDir, "coriolis2_1.0.%s.orig.tar.bz2" % self.gitHash )
@ -424,12 +465,17 @@ class Builder:
packageDir = os.path.join ( self.debbuildDir, "coriolis2-1.0.%s" % self.gitHash )
os.chdir ( packageDir )
self._environment["CFLAGS" ] = "-O2"
self._environment["CXXFLAGS"] = "-O2"
command = [ "/usr/bin/debuild", "-us", "-uc" ]
self._execute ( command, "Rebuild Debian packages" )
return
def getProject ( self, name ): return self._conf.getProject(name)
def loadConfiguration ( self, confFile ): self._conf.load( confFile )
def showConfiguration ( self ): self._conf.show()

View File

@ -2,72 +2,75 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | T o o l c h a i n B u i l d e r |
# | C o r i o l i s / C h a m s B u i l d e r |
# | |
# | Author : Damien Dupuis |
# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./builder/BuilderGui.py" |
# +-----------------------------------------------------------------+
from PyQt4.QtGui import QTabWidget, QApplication, QMainWindow, \
QAction , QKeySequence
from .OptionsWidget import OptionsWidget
from .CompileWidget import CompileWidget
from .ConfigureWidget import ConfigureWidget
from .AboutWidget import AboutWidget
from PyQt4.QtGui import QTabWidget
from PyQt4.QtGui import QApplication
from PyQt4.QtGui import QMainWindow
from PyQt4.QtGui import QAction
from PyQt4.QtGui import QKeySequence
from OptionsWidget import OptionsWidget
from CompileWidget import CompileWidget
from ConfigureWidget import ConfigureWidget
from AboutWidget import AboutWidget
class BuilderGui ( QMainWindow ):
def __init__ ( self, confFile, parent=None ):
QMainWindow.__init__( self, parent )
self.setWindowTitle( 'Coriolis Toolchain Builder' )
self._tabWidget = QTabWidget()
self._configureWidget = ConfigureWidget(confFile)
self._optionsWidget = OptionsWidget(self._configureWidget.conf)
self._compileWidget = CompileWidget()
self._aboutWidget = AboutWidget()
self._tabWidget.addTab( self._optionsWidget , 'Options' )
self._tabWidget.addTab( self._compileWidget , 'Compile' )
self._tabWidget.addTab( self._configureWidget, 'Configure' )
self.setCentralWidget( self._tabWidget )
self._compileWidget.conf = self._configureWidget
self._compileWidget.options = self._optionsWidget
self._exitAction = QAction( '&Exit', self )
self._exitAction.setStatusTip( 'Exit CCB (settings are saved)' )
self._exitAction.setShortcut ( QKeySequence('CTRL+Q') )
self._exitAction.triggered.connect( QApplication.closeAllWindows )
self._saveAction = QAction( '&Save Settings', self )
self._saveAction.setStatusTip( 'Save Settings' )
self._saveAction.setShortcut ( QKeySequence('CTRL+S') )
self._saveAction.triggered.connect( self._configureWidget.saveSettings )
self._saveAction.triggered.connect( self._optionsWidget.saveSettings )
self._saveAction.triggered.connect( self._compileWidget.saveSettings )
self._aboutAction = QAction( '&About', self )
self._aboutAction.setStatusTip( 'A Word About Who\'s Responsible for This Thing' )
self._aboutAction.setShortcut ( QKeySequence('CTRL+A') )
self._aboutAction.triggered.connect( self._aboutWidget.show )
fileMenu = self.menuBar().addMenu( 'File' )
fileMenu.addAction( self._exitAction )
fileMenu.addAction( self._saveAction )
fileMenu.addAction( self._aboutAction )
return
def closeEvent ( self, event ):
self._configureWidget.saveSettings()
self._optionsWidget .saveSettings()
self._compileWidget .saveSettings()
event.accept()
return
def __init__ ( self, confFile, parent=None ):
QMainWindow.__init__( self, parent )
self.setWindowTitle( 'Coriolis/Chams Builder' )
self._tabWidget = QTabWidget()
self._configureWidget = ConfigureWidget(confFile)
self._optionsWidget = OptionsWidget(self._configureWidget.conf)
self._compileWidget = CompileWidget()
self._aboutWidget = AboutWidget()
self._tabWidget.addTab( self._optionsWidget , 'Options' )
self._tabWidget.addTab( self._compileWidget , 'Compile' )
self._tabWidget.addTab( self._configureWidget, 'Configure' )
self.setCentralWidget( self._tabWidget )
self._compileWidget.conf = self._configureWidget
self._compileWidget.options = self._optionsWidget
self._exitAction = QAction( '&Exit', self )
self._exitAction.setStatusTip( 'Exit CCB (settings are saved)' )
self._exitAction.setShortcut ( QKeySequence('CTRL+Q') )
self._exitAction.triggered.connect( QApplication.closeAllWindows )
self._saveAction = QAction( '&Save Settings', self )
self._saveAction.setStatusTip( 'Save Settings' )
self._saveAction.setShortcut ( QKeySequence('CTRL+S') )
self._saveAction.triggered.connect( self._configureWidget.saveSettings )
self._saveAction.triggered.connect( self._optionsWidget.saveSettings )
self._saveAction.triggered.connect( self._compileWidget.saveSettings )
self._aboutAction = QAction( '&About', self )
self._aboutAction.setStatusTip( 'A Word About Who\'s Responsible for This Thing' )
self._aboutAction.setShortcut ( QKeySequence('CTRL+A') )
self._aboutAction.triggered.connect( self._aboutWidget.show )
fileMenu = self.menuBar().addMenu( 'File' )
fileMenu.addAction( self._exitAction )
fileMenu.addAction( self._saveAction )
fileMenu.addAction( self._aboutAction )
return
def closeEvent ( self, event ):
self._configureWidget.saveSettings()
self._optionsWidget .saveSettings()
self._compileWidget .saveSettings()
event.accept()
return

View File

@ -2,11 +2,11 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) Sorbonne Université 2012-2023, All Rights Reserved
# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | T o o l c h a i n B u i l d e r |
# | C o r i o l i s / C h a m s B u i l d e r |
# | |
# | Author : Damien Dupuis |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
@ -17,166 +17,195 @@
import re
import subprocess
from PyQt4.QtCore import Qt, pyqtSignal, QSettings
from PyQt4.QtGui import QFont, QColor, QPalette, QTextCharFormat, \
QWidget, QLabel, QPushButton, QCheckBox, \
QGroupBox, QButtonGroup, QVBoxLayout, \
QHBoxLayout, QGridLayout, QScrollArea, \
QComboBox, QLineEdit, QTextEdit, \
QFileDialog, QProgressBar, QApplication
from .Highlighter import Highlighter
from PyQt4.QtCore import Qt
from PyQt4.QtCore import pyqtSignal
from PyQt4.QtCore import QSettings
from PyQt4.QtGui import QFont
from PyQt4.QtGui import QColor
from PyQt4.QtGui import QPalette
from PyQt4.QtGui import QTextCharFormat
from PyQt4.QtGui import QWidget
from PyQt4.QtGui import QLabel
from PyQt4.QtGui import QPushButton
from PyQt4.QtGui import QCheckBox
from PyQt4.QtGui import QGroupBox
from PyQt4.QtGui import QButtonGroup
from PyQt4.QtGui import QVBoxLayout
from PyQt4.QtGui import QHBoxLayout
from PyQt4.QtGui import QGridLayout
from PyQt4.QtGui import QScrollArea
from PyQt4.QtGui import QComboBox
from PyQt4.QtGui import QLineEdit
from PyQt4.QtGui import QTextEdit
from PyQt4.QtGui import QFileDialog
from PyQt4.QtGui import QProgressBar
from PyQt4.QtGui import QApplication
from builder.Highlighter import Highlighter
class CompileWidget ( QWidget ):
progress = pyqtSignal(int)
def __init__ ( self, parent=None ):
QWidget.__init__ ( self, parent )
self._options = None
self._conf = None
progress = pyqtSignal(int)
def __init__ ( self, parent=None ):
QWidget.__init__ ( self, parent )
self._options = None
self._conf = None
self._go = QPushButton( 'Go' )
self._go.setMaximumWidth( 100 )
font = self._go.font()
font.setPointSizeF( font.pointSizeF()*2.0 )
font.setWeight ( QFont.Bold )
self._go.setFont( font )
self._go.clicked.connect( self.go )
self._saveLog = QPushButton( 'Save' )
saveLogLabel = QLabel( 'Log File:' )
saveLogBrowse = QPushButton( '&Browse' )
saveLogBrowse.clicked.connect( self.browseSaveLog )
self._saveLogEdit = QLineEdit( '' )
gLayout = QGridLayout()
gLayout.addWidget( saveLogLabel , 0, 0, 1, 1, Qt.AlignRight )
gLayout.addWidget( self._saveLogEdit, 0, 1, 1, 6 )
gLayout.addWidget( saveLogBrowse , 0, 7, 1, 1 )
self._console = QTextEdit()
self._console.setLineWrapMode( QTextEdit.NoWrap )
self._console.setMinimumSize ( 800, 400 )
palette = self._console.palette()
palette.setColor( QPalette.Base, QColor.fromRgb(255,255,221) ) # ffffdd.
self._console.setPalette( palette )
font = QFont( 'Bitstream Vera Sans Mono', self._console.font().pointSize() )
self._console.setFont( font )
self._highlighter = Highlighter( self._console.document() )
self._progressBar = QProgressBar()
self._progressBar.setRange ( 0, 100 )
self._progressBar.setTextVisible( True )
hLayout = QHBoxLayout()
hLayout.addStretch()
hLayout.addWidget( self._go )
hLayout.addStretch()
hLayout.addWidget( self._saveLog )
hLayout.addStretch()
vLayout = QVBoxLayout()
vLayout.addLayout( hLayout )
vLayout.addLayout( gLayout )
vLayout.addWidget( self._progressBar )
vLayout.addWidget( self._console )
self.setLayout( vLayout )
self.progress.connect( self._progressBar.setValue )
self._saveLog.clicked.connect( self.saveLog )
self.readSettings()
return
def _setOptions ( self, options ): self._options = options
def _setConf ( self, conf ): self._conf = conf
def _getOptions ( self ): return self._options
def _getConf ( self ): return self._conf
options = property( _getOptions, _setOptions )
conf = property( _getConf , _setConf )
def browseSaveLog ( self ):
self._saveLogEdit.setText( QFileDialog.getSaveFileName(self
,'Select Log File Report'
,self._saveLogEdit.text()
,'Report Files (*.log *.txt)') )
return
def saveLog ( self ):
if self._saveLogEdit.text():
fd = open( self._saveLogEdit.text(), 'w+' )
fd.write( self._console.toPlainText() )
fd.close()
return
def shellCommand ( self ):
command = [ self.conf.bootstrapDir+'/ccb.py' ]
for project in self.options.projects:
for tool in project.actives:
command += [ '--tool='+tool ]
toolsCount = len(command) - 1
if self.conf.rootDir: command += [ '--root=%s'%self.conf.rootDir ]
#if self.options.svnUpdate: command += [ '--svn-update' ]
#if self.options.svnStatus: command += [ '--svn-update' ]
if self.options.enableDoc: command += [ '--doc' ]
if self.options.devtoolset: command += [ '--devtoolset-8' ]
if self.options.qt5: command += [ '--qt5' ]
if self.options.noCache: command += [ '--no-cache' ]
if self.options.rmBuild: command += [ '--rm-build' ]
if self.options.verbose: command += [ '--verbose' ]
if self.options.make:
makeArguments='install '+self.options.threads
command += [ '--make=%s'%makeArguments ]
self._go = QPushButton( 'Go' )
self._go.setMaximumWidth( 100 )
font = self._go.font()
font.setPointSizeF( font.pointSizeF()*2.0 )
font.setWeight ( QFont.Bold )
self._go.setFont( font )
self._go.clicked.connect( self.go )
self._saveLog = QPushButton( 'Save' )
saveLogLabel = QLabel( 'Log File:' )
saveLogBrowse = QPushButton( '&Browse' )
saveLogBrowse.clicked.connect( self.browseSaveLog )
self._saveLogEdit = QLineEdit( '' )
gLayout = QGridLayout()
gLayout.addWidget( saveLogLabel , 0, 0, 1, 1, Qt.AlignRight )
gLayout.addWidget( self._saveLogEdit, 0, 1, 1, 6 )
gLayout.addWidget( saveLogBrowse , 0, 7, 1, 1 )
self._console = QTextEdit()
self._console.setLineWrapMode( QTextEdit.NoWrap )
self._console.setMinimumSize ( 800, 400 )
palette = self._console.palette()
palette.setColor( QPalette.Base, QColor.fromRgb(255,255,221) ) # ffffdd.
self._console.setPalette( palette )
font = QFont( 'Bitstream Vera Sans Mono', self._console.font().pointSize() )
self._console.setFont( font )
self._highlighter = Highlighter( self._console.document() )
self._progressBar = QProgressBar()
self._progressBar.setRange ( 0, 100 )
self._progressBar.setTextVisible( True )
hLayout = QHBoxLayout()
hLayout.addStretch()
hLayout.addWidget( self._go )
hLayout.addStretch()
hLayout.addWidget( self._saveLog )
hLayout.addStretch()
vLayout = QVBoxLayout()
vLayout.addLayout( hLayout )
vLayout.addLayout( gLayout )
vLayout.addWidget( self._progressBar )
vLayout.addWidget( self._console )
self.setLayout( vLayout )
self.progress.connect( self._progressBar.setValue )
self._saveLog.clicked.connect( self.saveLog )
self.readSettings()
return
def _setOptions ( self, options ): self._options = options
def _setConf ( self, conf ): self._conf = conf
def _getOptions ( self ): return self._options
def _getConf ( self ): return self._conf
options = property( _getOptions, _setOptions )
conf = property( _getConf , _setConf )
def browseSaveLog ( self ):
self._saveLogEdit.setText( QFileDialog.getSaveFileName( self
, 'Select Log File Report'
, self._saveLogEdit.text()
, 'Report Files (*.log *.txt)' ) )
return
def saveLog ( self ):
if self._saveLogEdit.text():
fd = open( self._saveLogEdit.text(), 'w+' )
fd.write( self._console.toPlainText() )
fd.close()
return
def shellCommand ( self ):
command = [ self.conf.bootstrapDir+'/ccb.py' ]
for project in self.options.projects:
for tool in project.actives:
command += [ '--tool='+tool ]
toolsCount = len(command) - 1
if self.conf.rootDir: command += [ '--root=%s'%self.conf.rootDir ]
#if self.options.svnUpdate: command += [ '--svn-update' ]
#if self.options.svnStatus: command += [ '--svn-update' ]
if self.options.enableDoc: command += [ '--doc' ]
if self.options.devtoolset: command += [ '--devtoolset-8' ]
if self.options.qt4: command += [ '--qt4' ]
if self.options.noCache: command += [ '--no-cache' ]
if self.options.rmBuild: command += [ '--rm-build' ]
if self.options.verbose: command += [ '--verbose' ]
if self.options.make:
makeArguments='install '+self.options.threads
command += [ '--make=%s'%makeArguments ]
if self.options.buildMode == 'Debug':
command += [ '--debug' ]
return toolsCount, command
def go ( self ):
rePercentage = re.compile(r'^\[\s*(?P<percent>\d+)%\].*')
reProcessTool = re.compile(r'^Processing tool:\s*"(?P<tool>.+)"')
if not self.options or not self.conf: return
toolsCount, command = self.shellCommand()
if not toolsCount: return
self._progressBar.reset()
self._progressBar.setRange( 0, toolsCount*100 )
strCommand = command[0]
for arg in command[1:]:
strCommand += ' ' + arg
strCommand += '\n\n'
self._console.setFontItalic( True )
self._console.insertPlainText( strCommand )
self._console.setFontItalic( False )
toolsDone = -1
builderProcess = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
while True:
line = builderProcess.stdout.readline()
if line == '': break
m = rePercentage.match( line )
if m:
self.progress.emit( toolsDone*100+int(m.group('percent')) )
else:
m = reProcessTool.match( line )
if m:
toolsDone += 1
self._console.insertPlainText( line )
scrollBar = self._console.verticalScrollBar()
scrollBar.setValue( scrollBar.maximum() )
QApplication.processEvents()
builderProcess.wait()
if builderProcess.returncode == None:
pass
return
def readSettings ( self ):
settings = QSettings()
self._saveLogEdit.setText( settings.value('compile/saveLog') )
return
def saveSettings ( self ):
settings = QSettings()
settings.setValue( 'compile/saveLog', self._saveLogEdit.text() )
return
if self.options.buildMode == 'Debug':
command += [ '--debug' ]
return toolsCount, command
def go ( self ):
rePercentage = re.compile(r'^\[\s*(?P<percent>\d+)%\].*')
reProcessTool = re.compile(r'^Processing tool:\s*"(?P<tool>.+)"')
if not self.options or not self.conf: return
toolsCount, command = self.shellCommand()
if not toolsCount: return
self._progressBar.reset()
self._progressBar.setRange( 0, toolsCount*100 )
strCommand = command[0]
for arg in command[1:]:
strCommand += ' ' + arg
strCommand += '\n\n'
self._console.setFontItalic( True )
self._console.insertPlainText( strCommand )
self._console.setFontItalic( False )
toolsDone = -1
builderProcess = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
while True:
line = builderProcess.stdout.readline()
if line == '': break
m = rePercentage.match( line )
if m:
self.progress.emit( toolsDone*100+int(m.group('percent')) )
else:
m = reProcessTool.match( line )
if m:
toolsDone += 1
self._console.insertPlainText( line )
scrollBar = self._console.verticalScrollBar()
scrollBar.setValue( scrollBar.maximum() )
QApplication.processEvents()
builderProcess.wait()
if builderProcess.returncode == None:
pass
return
def readSettings ( self ):
settings = QSettings()
self._saveLogEdit.setText( settings.value('compile/saveLog').toString() )
return
def saveSettings ( self ):
settings = QSettings()
settings.setValue( 'compile/saveLog', self._saveLogEdit.text() )
return

View File

@ -2,14 +2,14 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) Sorbonne Université 2008-2021, All Rights Reserved
# Copyright (c) UPMC 2008-2018, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | T o o l c h a i n B u i l d e r |
# | C o r i o l i s / C h a m s B u i l d e r |
# | |
# | Author : Jean-Paul Chaput |
# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./builder/Configuration.py" |
# +-----------------------------------------------------------------+
@ -21,8 +21,8 @@ import os
import os.path
import datetime
import subprocess
from . import ErrorMessage
from .Project import Project
from . import ErrorMessage
from Project import Project
class Configuration ( object ):
@ -64,26 +64,31 @@ class Configuration ( object ):
self._updateSecondary()
return
def __setattr__ ( self, attribute, value ):
if attribute in Configuration.SecondaryNames:
print( ErrorMessage( 1, 'Attempt to write in read-only attribute "{}" in Configuration.' \
.format(attribute) ))
print ErrorMessage( 1, 'Attempt to write in read-only attribute <%s> in Configuration.'%attribute )
return
if attribute[0] == '_':
self.__dict__[attribute] = value
return
if attribute == 'rootDir': value = os.path.expanduser(value)
elif attribute == 'enableShared' and value != 'ON': value = 'OFF'
self.__dict__['_'+attribute] = value
self._updateSecondary()
return
def __getattr__ ( self, attribute ):
if attribute[0] != '_': attribute = '_'+attribute
if not attribute in self.__dict__:
if not self.__dict__.has_key(attribute):
raise ErrorMessage( 1, 'Configuration has no attribute <%s>.'%attribute )
return self.__dict__[attribute]
def _updateSecondary ( self ):
if self._enableShared == "ON": self._libMode = "Shared"
else: self._libMode = "Static"
@ -104,6 +109,7 @@ class Configuration ( object ):
, "%s.%s" % (self._buildMode,self._libMode) )
self._buildDir = os.path.join ( self._osDir, "build" )
self._installDir = os.path.join ( self._osDir, "install" )
self._specFileIn = os.path.join ( self._bootstrapDir, "%s.spec.in"%self._packageName )
self._specFile = os.path.join ( self._bootstrapDir, "%s.spec" %self._packageName )
self._debianDir = os.path.join ( self._bootstrapDir, "debian" )
@ -120,9 +126,9 @@ class Configuration ( object ):
self._distribPatch = os.path.join ( self._sourceDir, "bootstrap", "%s-for-distribution.patch"%self._packageName )
return
def _guessOs ( self ):
self._libSuffix = None
self._osEL9 = re.compile (".*Linux.*(el9|al9).*x86_64.*")
self._osSlsoc7x_64 = re.compile (".*Linux.*(el7|slsoc7).*x86_64.*")
self._osSlsoc6x_64 = re.compile (".*Linux.*(el6|slsoc6).*x86_64.*")
self._osSlsoc6x = re.compile (".*Linux.*(el6|slsoc6).*")
@ -143,92 +149,95 @@ class Configuration ( object ):
self._osCygwinW10_64 = re.compile (".*CYGWIN_NT-10\.[0-3].*x86_64.*")
self._osCygwinW10 = re.compile (".*CYGWIN_NT-10\.[0-3].*i686.*")
uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE )
lines = uname.stdout.readlines()
osLine = lines[0].decode( 'ascii' )
if self._osEL9.match(osLine):
self._osType = "Linux.el9"
self._libSuffix = "64"
elif self._osSlsoc7x_64.match(osLine):
uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE )
lines = uname.stdout.readlines()
if self._osSlsoc7x_64.match(lines[0]):
self._osType = "Linux.el7_64"
self._libSuffix = "64"
elif self._osSlsoc6x_64.match(osLine):
elif self._osSlsoc6x_64.match(lines[0]):
self._osType = "Linux.slsoc6x_64"
self._libSuffix = "64"
elif self._osSlsoc6x .match(osLine): self._osType = "Linux.slsoc6x"
elif self._osSLSoC5x_64.match(osLine):
elif self._osSlsoc6x .match(lines[0]): self._osType = "Linux.slsoc6x"
elif self._osSLSoC5x_64.match(lines[0]):
self._osType = "Linux.SLSoC5x_64"
self._libSuffix = "64"
elif self._osSLSoC5x .match(osLine): self._osType = "Linux.SLSoC5x"
elif self._osFedora_64 .match(osLine):
elif self._osSLSoC5x .match(lines[0]): self._osType = "Linux.SLSoC5x"
elif self._osFedora_64 .match(lines[0]):
self._osType = "Linux.fc_64"
self._libSuffix = "64"
elif self._osFedora .match(osLine): self._osType = "Linux.fc"
elif self._osLinux_64 .match(osLine):
elif self._osFedora .match(lines[0]): self._osType = "Linux.fc"
elif self._osLinux_64 .match(lines[0]):
self._osType = "Linux.x86_64"
if os.path.exists("/usr/lib64/"):
self._libSuffix = "64"
elif self._osLinux .match(osLine): self._osType = "Linux.i386"
elif self._osDarwin .match(osLine): self._osType = "Darwin"
elif self._osFreeBSD8x_amd64.match(osLine):
elif self._osLinux .match(lines[0]): self._osType = "Linux.i386"
elif self._osDarwin .match(lines[0]): self._osType = "Darwin"
elif self._osFreeBSD8x_amd64.match(lines[0]):
self._osType = "FreeBSD.8x.amd64"
self._libSuffix = "64"
elif self._osFreeBSD8x_64.match(osLine):
elif self._osFreeBSD8x_64.match(lines[0]):
self._osType = "FreeBSD.8x.x86_64"
self._libSuffix = "64"
elif self._osFreeBSD8x .match(osLine): self._osType = "FreeBSD.8x.i386"
elif self._osCygwinW7_64.match(osLine):
elif self._osFreeBSD8x .match(lines[0]): self._osType = "FreeBSD.8x.i386"
elif self._osCygwinW7_64.match(lines[0]):
self._osType = "Cygwin.W7_64"
self._libSuffix = "64"
elif self._osCygwinW7.match(osLine): self._osType = "Cygwin.W7"
elif self._osCygwinW8_64.match(osLine):
elif self._osCygwinW7.match(lines[0]): self._osType = "Cygwin.W7"
elif self._osCygwinW8_64.match(lines[0]):
self._osType = "Cygwin.W8_64"
self._libSuffix = "64"
elif self._osCygwinW8.match(osLine): self._osType = "Cygwin.W8"
elif self._osCygwinW10_64.match(osLine):
elif self._osCygwinW8.match(lines[0]): self._osType = "Cygwin.W8"
elif self._osCygwinW10_64.match(lines[0]):
self._osType = "Cygwin.W10_64"
self._libSuffix = "64"
elif self._osCygwinW10.match(osLine): self._osType = "Cygwin.W10"
elif self._osCygwinW10.match(lines[0]): self._osType = "Cygwin.W10"
else:
uname = subprocess.Popen ( ["uname", "-sr"], stdout=subprocess.PIPE )
self._osType = uname.stdout.readlines()[0][:-1]
print( '[WARNING] Unrecognized OS: "{}."'.format(osLine[:-1]) )
print( ' (using: "{}")'.format(self._osType) )
print "[WARNING] Unrecognized OS: \"%s\"." % lines[0][:-1]
print " (using: \"%s\")" % self._osType
if self._libSuffix == '64' and not os.path.exists('/usr/lib64'):
self._libSuffix = None
return
def getPrimaryIds ( self ): return Configuration.PrimaryNames
def getSecondaryIds ( self ): return Configuration.SecondaryNames
def getAllIds ( self ): return Configuration.PrimaryNames + Configuration.SecondaryNames
def register ( self, project ):
for registered in self._projects:
if registered.getName() == project.getName():
print( ErrorMessage( 0, 'Project "{}" is already registered (ignored).'.format(project.getName()) ))
print ErrorMessage( 0, "Project \"%s\" is already registered (ignored)." )
return
self._projects += [ project ]
return
def getProject ( self, name ):
for project in self._projects:
if project.getName() == name:
return project
return None
def getToolProject ( self, name ):
for project in self._projects:
if project.hasTool(name):
return project
return None
def load ( self, confFile ):
moduleGlobals = globals()
if not confFile:
print( 'Making an educated guess to locate the configuration file:' )
print 'Making an educated guess to locate the configuration file:'
locations = [ os.path.abspath(os.path.dirname(sys.argv[0]))
, os.environ['HOME']+'/coriolis-2.x/src/coriolis/bootstrap'
, os.environ['HOME']+'/coriolis/src/coriolis/bootstrap'
@ -238,82 +247,86 @@ class Configuration ( object ):
for location in locations:
self._confFile = location + '/build.conf'
print( ' "{}"'.format(self._confFile) )
print ' <%s>' % self._confFile
if os.path.isfile(self._confFile): break
if not self._confFile:
ErrorMessage( 1, 'Cannot locate any configuration file.' ).terminate()
else:
print( 'Using user-supplied configuration file:' )
print( ' "{}"'.format(confFile) )
print 'Using user-supplied configuration file:'
print ' <%s>' % confFile
self._confFile = confFile
if not os.path.isfile(self._confFile):
ErrorMessage( 1, 'Missing configuration file:', '<%s>'%self._confFile ).terminate()
print( 'Reading configuration from:' )
print( ' "{}"'.format(self._confFile) )
print 'Reading configuration from:'
print ' <%s>' % self._confFile
try:
exec( open(self._confFile).read(), globals() )
except Exception as e:
execfile( self._confFile, moduleGlobals )
except Exception, e:
ErrorMessage( 1, 'An exception occured while loading the configuration file:'
, '<%s>\n' % (self._confFile)
, 'You should check for simple python errors in this file.'
, 'Error was:'
, '%s\n' % e ).terminate()
if 'projects' in moduleGlobals:
if moduleGlobals.has_key('projects'):
entryNb = 0
for entry in moduleGlobals['projects']:
entryNb += 1
if not 'name' in entry:
if not entry.has_key('name'):
raise ErrorMessage( 1, 'Missing project name in project entry #%d.' % entryNb )
if not 'tools' in entry:
if not entry.has_key('tools'):
raise ErrorMessage( 1, 'Missing tools list in project entry #%d (<%s>).' \
% (entryNb,entry['name']) )
if not isinstance(entry['tools'],list):
raise ErrorMessage( 1, 'Tools item of project entry #%d (<%s>) is not a list.' \
% (entryNb,entry['name']) )
if not 'repository' in entry:
if not entry.has_key('repository'):
raise ErrorMessage( 1, 'Missing project repository in project entry #%d.' \
% entryNb )
self.register( Project(entry['name'],entry['tools'],entry['repository']) )
else:
ErrorMessage( 1, 'Configuration file is missing the "project" symbol.'
, '"{}"'.format(self._confFile) ).terminate()
ErrorMessage( 1, 'Configuration file is missing the \'project\' symbol.'
, '<%s>'%self._confFile ).terminate()
if 'projectdir' in moduleGlobals:
if moduleGlobals.has_key('projectdir'):
self.projectDir = moduleGlobals['projectdir']
if 'svnconfig' in moduleGlobals:
if moduleGlobals.has_key('svnconfig'):
svnconfig = moduleGlobals['svnconfig']
if 'method' in svnconfig: self._svnMethod = svnconfig['method']
if 'package' in moduleGlobals:
if svnconfig.has_key('method'): self._svnMethod = svnconfig['method']
if moduleGlobals.has_key('package'):
package = moduleGlobals['package']
if 'name' in package: self.packageName = package['name']
if 'version' in package: self.packageVersion = package['version']
if 'excludes' in package:
if package.has_key('name' ): self.packageName = package['name']
if package.has_key('version' ): self.packageVersion = package['version']
if package.has_key('excludes'):
if not isinstance(package['excludes'],list):
raise ErrorMessage( 1, 'Excludes of package configuration is not a list.')
self._packageExcludes = package['excludes']
if 'projects' in package:
if package.has_key('projects'):
if not isinstance(package['projects'],list):
raise ErrorMessage( 1, 'Projects to package is not a list.')
self._packageProjects = package['projects']
return
def show ( self ):
print( 'CCB Configuration:' )
print 'CCB Configuration:'
if self._gitMethod:
print( ' Git Method: "{}"'.format(self._gitMethod) )
print ' Git Method: <%s>' % self._gitMethod
else:
print( ' Git Method not defined, will not be able to push/pull.' )
print ' Git Method not defined, will not be able to push/pull.'
for project in self._projects:
print( ' project:{0:>15} repository:"{1}"' \
.format( '"{}"'.format(project.getName()), project.getRepository() ))
print ' project:%-15s repository:<%s>' % ( ('<%s>'%project.getName()), project.getRepository() )
toolOrder = 1
for tool in project.getTools():
print( '{0}{1:02}:"{2}"'.format( ' '*26, toolOrder, tool ))
print '%s%02d:<%s>' % (' '*26,toolOrder,tool)
toolOrder += 1
print
return

View File

@ -2,32 +2,45 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | T o o l c h a i n B u i l d e r |
# | C o r i o l i s / C h a m s B u i l d e r |
# | |
# | Author : Damien Dupuis |
# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./builder/ConfigureWidget.py" |
# +-----------------------------------------------------------------+
from PyQt4.QtCore import Qt, QVariant, pyqtSignal, QSettings, \
QModelIndex, QAbstractTableModel
from PyQt4.QtGui import QFont, QWidget, QGridLayout, QHBoxLayout, \
QVBoxLayout, QLabel, QPushButton, \
QLineEdit, QAbstractItemView, QHeaderView, \
QTableView, QGroupBox, QFileDialog, \
QApplication
from .Configuration import Configuration
from PyQt4.QtCore import Qt
from PyQt4.QtCore import QVariant
from PyQt4.QtCore import pyqtSignal
from PyQt4.QtCore import QSettings
from PyQt4.QtGui import QFont
from PyQt4.QtGui import QWidget
from PyQt4.QtGui import QGridLayout
from PyQt4.QtGui import QHBoxLayout
from PyQt4.QtGui import QVBoxLayout
from PyQt4.QtGui import QLabel
from PyQt4.QtGui import QPushButton
from PyQt4.QtGui import QLineEdit
from PyQt4.QtCore import QModelIndex
from PyQt4.QtCore import QAbstractTableModel
from PyQt4.QtGui import QAbstractItemView
from PyQt4.QtGui import QHeaderView
from PyQt4.QtGui import QTableView
from PyQt4.QtGui import QGroupBox
from PyQt4.QtGui import QFileDialog
from PyQt4.QtGui import QApplication
from Configuration import Configuration
class ConfSettingsModel ( QAbstractTableModel ):
HeaderFont = QApplication.font()
HeaderFont = QApplication.font()
PrimaryFont = QFont('Courier',HeaderFont.pointSize()-2,QFont.Normal)
SecondaryFont = QFont('Courier',HeaderFont.pointSize()-2,QFont.Normal)
ValueFont = QFont('Courier',HeaderFont.pointSize()-2,QFont.Bold)
@ -35,6 +48,7 @@ class ConfSettingsModel ( QAbstractTableModel ):
def __init__ ( self, conf, parent=None ):
ConfSettingsModel.HeaderFont.setBold( True )
ConfSettingsModel.SecondaryFont.setItalic( True )
QAbstractTableModel.__init__( self, parent )
self._conf = conf
self._ids = self._conf.getAllIds()
@ -56,15 +70,20 @@ class ConfSettingsModel ( QAbstractTableModel ):
if row < self.rowCount():
if index.column() == 0: return self._ids[row]
elif index.column() == 1: return getattr( self._conf, self._ids[row] )
return None
return QVariant()
def headerData ( self, section, orientation, role ):
if orientation == Qt.Vertical: return None
if orientation == Qt.Vertical: return QVariant()
if role == Qt.FontRole: return ConfSettingsModel.HeaderFont
if role != Qt.DisplayRole: return None
if role != Qt.DisplayRole: return QVariant()
if section == 0: return 'Setting'
elif section == 1: return 'Value'
return '?'
return QVariant('?')
def rowCount ( self, index=QModelIndex() ): return len(self._ids)
def columnCount ( self, index=QModelIndex() ): return 2
@ -100,73 +119,79 @@ class ConfSettingsWidget ( QWidget ):
peanoDataLayout = QGridLayout();
peanoDataLayout.addWidget( self._view, 0, 0, 1, 1 );
self.setLayout ( peanoDataLayout );
return
class ConfigureWidget ( QWidget ):
def __init__ ( self, confFile, parent=None ):
QWidget.__init__ ( self, parent )
self._confFile = confFile
self._conf = Configuration()
self._rootDir = ''
rootDirLabel = QLabel( 'Root Directory' )
rootDirBrowse = QPushButton( '&Browse' )
rootDirBrowse.clicked.connect( self.browseRootDir )
self._rootDirEdit = QLineEdit( '' )
#self._rootDirEdit.setFixedWidth( 600 )
gLayout = QGridLayout()
gLayout.addWidget( rootDirLabel , 0, 0, 1, 1 )
gLayout.addWidget( self._rootDirEdit, 0, 1, 1, 6 )
gLayout.addWidget( rootDirBrowse , 0, 7, 1, 1 )
groupDirs = QGroupBox( 'Directories' )
groupDirs.setLayout( gLayout )
gLayout = QGridLayout()
groupConf = QGroupBox( 'Configuration' )
groupConf.setLayout( gLayout )
vLayout = QVBoxLayout()
vLayout.addWidget ( groupDirs )
vLayout.addWidget ( groupConf )
#vLayout.addStretch()
self.setLayout( vLayout )
self._rootDirEdit.textChanged.connect( self.rootDirChanged )
self.readSettings()
noteLabel = QLabel( 'Those settings can be changed only by editing build.conf' )
gLayout.addWidget( noteLabel , 0, 0, 1, 1 )
gLayout.addWidget( ConfSettingsWidget(self._conf), 1, 0, 1, 1 )
def _getConf ( self ): return self._conf
def _getRootDir ( self ): return self._rootDir
def _getBootstrapDir ( self ): return self._getConf().bootstrapDir
conf = property( _getConf )
rootDir = property( _getRootDir )
bootstrapDir = property( _getBootstrapDir )
def rootDirChanged ( self, rootDir ):
self._rootDir = rootDir
return
def browseRootDir ( self ):
self._rootDirEdit.setText( QFileDialog.getExistingDirectory(self,'Select the Building Root Directory') )
return
def readSettings ( self ):
settings = QSettings()
self._rootDirEdit.setText( settings.value('conf/rootDir') )
if not self._confFile and settings.value('conf/confFile'):
self._confFile = str( settings.value('conf/confFile') )
self._conf.load( self._confFile )
return
def saveSettings ( self ):
settings = QSettings()
settings.setValue( 'conf/rootDir' , self._rootDirEdit.text() )
settings.setValue( 'conf/confFile', self._confFile )
return
def __init__ ( self, confFile, parent=None ):
QWidget.__init__ ( self, parent )
self._confFile = confFile
self._conf = Configuration()
self._rootDir = ''
rootDirLabel = QLabel( 'Root Directory' )
rootDirBrowse = QPushButton( '&Browse' )
rootDirBrowse.clicked.connect( self.browseRootDir )
self._rootDirEdit = QLineEdit( '' )
#self._rootDirEdit.setFixedWidth( 600 )
gLayout = QGridLayout()
gLayout.addWidget( rootDirLabel , 0, 0, 1, 1 )
gLayout.addWidget( self._rootDirEdit, 0, 1, 1, 6 )
gLayout.addWidget( rootDirBrowse , 0, 7, 1, 1 )
groupDirs = QGroupBox( 'Directories' )
groupDirs.setLayout( gLayout )
gLayout = QGridLayout()
groupConf = QGroupBox( 'Configuration' )
groupConf.setLayout( gLayout )
vLayout = QVBoxLayout()
vLayout.addWidget ( groupDirs )
vLayout.addWidget ( groupConf )
#vLayout.addStretch()
self.setLayout( vLayout )
self._rootDirEdit.textChanged.connect( self.rootDirChanged )
self.readSettings()
noteLabel = QLabel( 'Those settings can be changed only by editing build.conf' )
gLayout.addWidget( noteLabel , 0, 0, 1, 1 )
gLayout.addWidget( ConfSettingsWidget(self._conf), 1, 0, 1, 1 )
def _getConf ( self ): return self._conf
def _getRootDir ( self ): return self._rootDir
def _getBootstrapDir ( self ): return self._getConf().bootstrapDir
conf = property( _getConf )
rootDir = property( _getRootDir )
bootstrapDir = property( _getBootstrapDir )
def rootDirChanged ( self, rootDir ):
self._rootDir = rootDir
return
def browseRootDir ( self ):
self._rootDirEdit.setText( QFileDialog.getExistingDirectory(self,'Select the Building Root Directory') )
return
def readSettings ( self ):
settings = QSettings()
self._rootDirEdit.setText( settings.value('conf/rootDir').toString() )
if not self._confFile and settings.value('conf/confFile'):
self._confFile = str( settings.value('conf/confFile').toString() )
self._conf.load( self._confFile )
return
def saveSettings ( self ):
settings = QSettings()
settings.setValue( 'conf/rootDir' , self._rootDirEdit.text() )
settings.setValue( 'conf/confFile', self._confFile )
return

View File

@ -2,14 +2,14 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | T o o l c h a i n B u i l d e r |
# | C o r i o l i s / C h a m s B u i l d e r |
# | |
# | Author : Damien Dupuis |
# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./builder/Highlighter.py" |
# +-----------------------------------------------------------------+
@ -17,61 +17,64 @@
import re
from PyQt4.QtCore import Qt
from PyQt4.QtGui import QFont, QColor, QTextCharFormat, QSyntaxHighlighter
from PyQt4.QtGui import QFont
from PyQt4.QtGui import QColor
from PyQt4.QtGui import QTextCharFormat
from PyQt4.QtGui import QSyntaxHighlighter
class Highlighter ( QSyntaxHighlighter ):
Normal = 0x0001
Bold = 0x0002
Italic = 0x0004
ttyBackground = QColor.fromRgb( 255, 255, 221 ) # #ffffdd
ttyBlack = QColor.fromRgb( 46, 52, 54 ) # #2e3436
ttyRed = QColor.fromRgb( 204, 0, 0 ) # #cc0000
ttyGreen = QColor.fromRgb( 78, 154, 6 ) # #4e9a06
ttyYellow = QColor.fromRgb( 196, 160, 0 ) # #c4a000
ttyBlue = QColor.fromRgb( 52, 101, 164 ) # #3465a4
ttyViolet = QColor.fromRgb( 117, 80, 123 ) # #75507b
ttyCyan = QColor.fromRgb( 6, 152, 154 ) # #06989a
ttyGrey = QColor.fromRgb( 211, 215, 207 ) # #d3d7cf
ttyLightBlack = QColor.fromRgb( 85, 87, 83 ) # #555753
ttyLightRed = QColor.fromRgb( 239, 41, 41 ) # #ef2929
ttyLightGreen = QColor.fromRgb( 138, 226, 52 ) # #8ae234
ttyLightYellow = QColor.fromRgb( 252, 233, 79 ) # #fce94f
ttyLightBlue = QColor.fromRgb( 114, 159, 207 ) # #729fcf
ttyLightViolet = QColor.fromRgb( 173, 127, 168 ) # #ad7fa8
ttyLightCyan = QColor.fromRgb( 52, 226, 226 ) # #34e2e2
ttyLightGrey = QColor.fromRgb( 238, 238, 236 ) # #eeeeec
Rules = [ [ttyLightViolet, Bold , re.compile(r'^Scanning.*'), None]
, [ttyLightRed , Bold , re.compile(r'^Linking.*'), None]
, [ttyLightGreen , Normal , re.compile(r'^\[(?P<percent>\s*\d+)%\]\s*(?P<message>Building.*)'), None]
, [ttyLightGreen , Bold , re.compile(r'^\[(?P<percent>\s*\d+)%\]\s*(?P<message>Built target.*)'), None]
, [ttyLightBlue , Normal , re.compile(r'^\[(?P<percent>\s*\d+)%\]\s*(?P<message>Generating.*moc_.*)'), None]
, [ttyLightBlue , Bold , re.compile(r'^Generating.*'), None]
, [ttyLightCyan , Normal , re.compile(r'^Install the project.*'), None]
, [ttyCyan , Bold , re.compile(r'^-- Install.*'), None]
, [ttyCyan , Bold|Italic, re.compile(r'^-- Up-to-date.*'), None]
]
def __init__ ( self, parent=None ):
QSyntaxHighlighter.__init__ ( self, parent )
for rule in Highlighter.Rules:
if not rule[3]:
rule[3] = QTextCharFormat()
rule[3].setForeground( rule[0] )
if rule[1] & Highlighter.Normal: rule[3].setFontWeight( QFont.Normal )
if rule[1] & Highlighter.Bold: rule[3].setFontWeight( QFont.Bold )
if rule[1] & Highlighter.Italic: rule[3].setFontItalic( True )
return
def highlightBlock ( self, line ):
for rule in Highlighter.Rules:
m = rule[2].match(line)
if m:
if 'percent' in m.groupdict():
self.setFormat( 7, len(line), rule[3] )
else:
self.setFormat( 0, len(line), rule[3] )
return
Normal = 0x0001
Bold = 0x0002
Italic = 0x0004
ttyBackground = QColor.fromRgb( 255, 255, 221 ) # #ffffdd
ttyBlack = QColor.fromRgb( 46, 52, 54 ) # #2e3436
ttyRed = QColor.fromRgb( 204, 0, 0 ) # #cc0000
ttyGreen = QColor.fromRgb( 78, 154, 6 ) # #4e9a06
ttyYellow = QColor.fromRgb( 196, 160, 0 ) # #c4a000
ttyBlue = QColor.fromRgb( 52, 101, 164 ) # #3465a4
ttyViolet = QColor.fromRgb( 117, 80, 123 ) # #75507b
ttyCyan = QColor.fromRgb( 6, 152, 154 ) # #06989a
ttyGrey = QColor.fromRgb( 211, 215, 207 ) # #d3d7cf
ttyLightBlack = QColor.fromRgb( 85, 87, 83 ) # #555753
ttyLightRed = QColor.fromRgb( 239, 41, 41 ) # #ef2929
ttyLightGreen = QColor.fromRgb( 138, 226, 52 ) # #8ae234
ttyLightYellow = QColor.fromRgb( 252, 233, 79 ) # #fce94f
ttyLightBlue = QColor.fromRgb( 114, 159, 207 ) # #729fcf
ttyLightViolet = QColor.fromRgb( 173, 127, 168 ) # #ad7fa8
ttyLightCyan = QColor.fromRgb( 52, 226, 226 ) # #34e2e2
ttyLightGrey = QColor.fromRgb( 238, 238, 236 ) # #eeeeec
Rules = [ [ttyLightViolet, Bold , re.compile(r'^Scanning.*'), None]
, [ttyLightRed , Bold , re.compile(r'^Linking.*'), None]
, [ttyLightGreen , Normal , re.compile(r'^\[(?P<percent>\s*\d+)%\]\s*(?P<message>Building.*)'), None]
, [ttyLightGreen , Bold , re.compile(r'^\[(?P<percent>\s*\d+)%\]\s*(?P<message>Built target.*)'), None]
, [ttyLightBlue , Normal , re.compile(r'^\[(?P<percent>\s*\d+)%\]\s*(?P<message>Generating.*moc_.*)'), None]
, [ttyLightBlue , Bold , re.compile(r'^Generating.*'), None]
, [ttyLightCyan , Normal , re.compile(r'^Install the project.*'), None]
, [ttyCyan , Bold , re.compile(r'^-- Install.*'), None]
, [ttyCyan , Bold|Italic, re.compile(r'^-- Up-to-date.*'), None]
]
def __init__ ( self, parent=None ):
QSyntaxHighlighter.__init__ ( self, parent )
for rule in Highlighter.Rules:
if not rule[3]:
rule[3] = QTextCharFormat()
rule[3].setForeground( rule[0] )
if rule[1] & Highlighter.Normal: rule[3].setFontWeight( QFont.Normal )
if rule[1] & Highlighter.Bold: rule[3].setFontWeight( QFont.Bold )
if rule[1] & Highlighter.Italic: rule[3].setFontItalic( True )
return
def highlightBlock ( self, line ):
for rule in Highlighter.Rules:
m = rule[2].match(line)
if m:
if m.groupdict().has_key('percent'):
self.setFormat( 7, len(line), rule[3] )
else:
self.setFormat( 0, len(line), rule[3] )
return

View File

@ -2,14 +2,14 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | T o o l c h a i n B u i l d e r |
# | C o r i o l i s / C h a m s B u i l d e r |
# | |
# | Author : Damien Dupuis |
# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./builder/OptionsWidget.py" |
# +-----------------------------------------------------------------+
@ -17,163 +17,176 @@
import re
import subprocess
from PyQt4.QtCore import Qt, pyqtSignal, QSettings
from PyQt4.QtGui import QColor, QWidget, QPushButton, \
QCheckBox, QGroupBox, QButtonGroup, \
QVBoxLayout, QHBoxLayout, QGridLayout, \
QScrollArea, QComboBox
from .Project import Project
from .ConfigureWidget import ConfigureWidget
from .ProjectWidgets import ProjectWidgets
from PyQt4.QtCore import Qt
from PyQt4.QtCore import pyqtSignal
from PyQt4.QtCore import QSettings
from PyQt4.QtGui import QColor
from PyQt4.QtGui import QWidget
from PyQt4.QtGui import QPushButton
from PyQt4.QtGui import QCheckBox
from PyQt4.QtGui import QGroupBox
from PyQt4.QtGui import QButtonGroup
from PyQt4.QtGui import QVBoxLayout
from PyQt4.QtGui import QHBoxLayout
from PyQt4.QtGui import QGridLayout
from PyQt4.QtGui import QScrollArea
from PyQt4.QtGui import QComboBox
from builder.Project import Project
from builder.ConfigureWidget import ConfigureWidget
from builder.ProjectWidgets import ProjectWidgets
class OptionsWidget ( QWidget ):
progress = pyqtSignal(int)
def __init__ ( self, conf, parent=None ):
QWidget.__init__ ( self, parent )
self._conf = conf
self._projects = []
for project in self._conf.projects:
self._projects += [ ProjectWidgets(project) ]
gLayout = QGridLayout()
column = 0
for iproject in range(len(self._projects)):
column += self._projects[iproject].addToLayout( column, gLayout )
toolsGroup = QGroupBox( 'Projects && Tools' )
toolsGroup.setLayout( gLayout )
progress = pyqtSignal(int)
def __init__ ( self, conf, parent=None ):
QWidget.__init__ ( self, parent )
self._conf = conf
self._projects = []
for project in self._conf.projects:
self._projects += [ ProjectWidgets(project) ]
scrollToolsGroup = QScrollArea()
scrollToolsGroup.setMinimumHeight( 350 )
#scrollToolsGroup.setVerticalScrollBarPolicy( Qt.ScrollBarAlwaysOn )
scrollToolsGroup.setWidget( toolsGroup )
self._buildMode = QComboBox()
self._buildMode.addItems( ('Release', 'Debug') )
#self._svnUpdate = QCheckBox( 'SVN Update' )
#self._svnStatus = QCheckBox( 'SVN Status' )
self._make = QCheckBox( 'Build' )
self._enableDoc = QCheckBox( 'Build Documentation' )
self._devtoolset = QCheckBox( 'Build with devtoolset 8' )
self._qt4 = QCheckBox( 'Build with Qt 4 (Qt 5 default)' )
self._noCache = QCheckBox( 'Remove previous CMake cache' )
self._rmBuild = QCheckBox( 'Cleanup Build Directory' )
self._verbose = QCheckBox( 'Display Compiler Commands' )
self._threads = QComboBox()
for j in range(16):
self._threads.addItem( '-j%d'%(j+1), j+1 )
self._commandGroup = QButtonGroup()
self._commandGroup.setExclusive( True )
#self._commandGroup.addButton( self._svnUpdate )
#self._commandGroup.addButton( self._svnStatus )
self._commandGroup.addButton( self._make )
vLayout = QVBoxLayout()
#vLayout.addWidget( self._svnUpdate )
#vLayout.addWidget( self._svnStatus )
vLayout.addWidget( self._make )
vLayout.addStretch()
commandGroup = QGroupBox( 'Command' )
commandGroup.setLayout( vLayout )
vLayout = QVBoxLayout()
vLayout.addWidget( self._buildMode )
vLayout.addWidget( self._enableDoc )
vLayout.addWidget( self._devtoolset )
vLayout.addWidget( self._qt4 )
vLayout.addWidget( self._noCache )
vLayout.addWidget( self._rmBuild )
vLayout.addStretch()
optionsGroup = QGroupBox( 'Command Options' )
optionsGroup.setLayout( vLayout )
vLayout = QVBoxLayout()
vLayout.addWidget( self._threads )
vLayout.addWidget( self._verbose )
vLayout.addStretch()
miscGroup = QGroupBox( 'Misc. Options' )
miscGroup.setLayout( vLayout )
hLayout = QHBoxLayout()
hLayout.addWidget( commandGroup )
hLayout.addWidget( optionsGroup )
hLayout.addWidget( miscGroup )
commands = QWidget()
commands.setLayout( hLayout )
vLayout = QVBoxLayout()
vLayout.addWidget( commands )
vLayout.addWidget( scrollToolsGroup )
vLayout.addStretch()
self.setLayout( vLayout )
self.readSettings()
return
def _getProjects ( self ): return self._projects
def _getBuildMode ( self ): return self._buildMode.currentText()
def _getThreads ( self ): return self._threads.currentText()
#def _getSvnUpdate ( self ): return self._svnUpdate.isChecked()
#def _getSvnStatus ( self ): return self._svnStatus.isChecked()
def _getMake ( self ): return self._make.isChecked()
def _getEnableDoc ( self ): return self._enableDoc.isChecked()
def _getDevtoolset ( self ): return self._devtoolset.isChecked()
def _getQt4 ( self ): return self._qt4.isChecked()
def _getNoCache ( self ): return self._noCache.isChecked()
def _getRmBuild ( self ): return self._rmBuild.isChecked()
def _getVerbose ( self ): return self._verbose.isChecked()
projects = property( _getProjects )
buildMode = property( _getBuildMode )
threads = property( _getThreads )
#svnUpdate = property( _getSvnUpdate )
#svnStatus = property( _getSvnStatus )
make = property( _getMake )
enableDoc = property( _getEnableDoc )
devtoolset = property( _getDevtoolset )
qt4 = property( _getQt4 )
noCache = property( _getNoCache )
rmBuild = property( _getRmBuild )
verbose = property( _getVerbose )
def readSettings ( self ):
settings = QSettings()
#self._svnUpdate .setChecked( bool(settings.value('builder/svnUpdate' )) )
#self._svnStatus .setChecked( bool(settings.value('builder/svnStatus' )) )
self._make .setChecked( bool(settings.value('builder/make' )) )
self._enableDoc .setChecked( bool(settings.value('builder/enableDoc' )) )
self._devtoolset .setChecked( bool(settings.value('builder/devtoolset')) )
self._qt4 .setChecked( bool(settings.value('builder/qt4' )) )
self._noCache .setChecked( bool(settings.value('builder/noCache' )) )
self._rmBuild .setChecked( bool(settings.value('builder/rmBuild' )) )
self._verbose .setChecked( bool(settings.value('builder/verbose' )) )
buildModeName = settings.value('builder/buildMode')
index = self._buildMode.findText( buildModeName )
if index >= 0: self._buildMode.setCurrentIndex( index )
threads = settings.value('builder/threads')
index = self._threads.findText( threads )
if index >= 0: self._threads.setCurrentIndex( index )
for project in self._projects: project.readFromSettings()
return
def saveSettings ( self ):
settings = QSettings()
#settings.setValue('builder/svnUpdate' , self._svnUpdate .isChecked() )
#settings.setValue('builder/svnStatus' , self._svnStatus .isChecked() )
settings.setValue('builder/make' , self._make .isChecked() )
settings.setValue('builder/enableDoc' , self._enableDoc .isChecked() )
settings.setValue('builder/devtoolset', self._devtoolset.isChecked() )
settings.setValue('builder/qt4' , self._qt4 .isChecked() )
settings.setValue('builder/buildMode' , self._buildMode .currentText() )
settings.setValue('builder/noCache' , self._noCache .isChecked() )
settings.setValue('builder/rmBuild' , self._rmBuild .isChecked() )
settings.setValue('builder/verbose' , self._verbose .isChecked() )
settings.setValue('builder/threads' , self._threads .currentText() )
for project in self._projects: project.saveToSettings()
return
gLayout = QGridLayout()
column = 0
for iproject in range(len(self._projects)):
column += self._projects[iproject].addToLayout( column, gLayout )
toolsGroup = QGroupBox( 'Projects && Tools' )
toolsGroup.setLayout( gLayout )
scrollToolsGroup = QScrollArea()
scrollToolsGroup.setMinimumHeight( 350 )
#scrollToolsGroup.setVerticalScrollBarPolicy( Qt.ScrollBarAlwaysOn )
scrollToolsGroup.setWidget( toolsGroup )
self._buildMode = QComboBox()
self._buildMode.addItems( ('Release', 'Debug') )
#self._svnUpdate = QCheckBox( 'SVN Update' )
#self._svnStatus = QCheckBox( 'SVN Status' )
self._make = QCheckBox( 'Build' )
self._enableDoc = QCheckBox( 'Build Documentation' )
self._devtoolset = QCheckBox( 'Build with devtoolset 8' )
self._qt5 = QCheckBox( 'Build with Qt 5 (Qt 4 default)' )
self._noCache = QCheckBox( 'Remove previous CMake cache' )
self._rmBuild = QCheckBox( 'Cleanup Build Directory' )
self._verbose = QCheckBox( 'Display Compiler Commands' )
self._threads = QComboBox()
for j in range(16):
self._threads.addItem( '-j%d'%(j+1), j+1 )
self._commandGroup = QButtonGroup()
self._commandGroup.setExclusive( True )
#self._commandGroup.addButton( self._svnUpdate )
#self._commandGroup.addButton( self._svnStatus )
self._commandGroup.addButton( self._make )
vLayout = QVBoxLayout()
#vLayout.addWidget( self._svnUpdate )
#vLayout.addWidget( self._svnStatus )
vLayout.addWidget( self._make )
vLayout.addStretch()
commandGroup = QGroupBox( 'Command' )
commandGroup.setLayout( vLayout )
vLayout = QVBoxLayout()
vLayout.addWidget( self._buildMode )
vLayout.addWidget( self._enableDoc )
vLayout.addWidget( self._devtoolset )
vLayout.addWidget( self._qt5 )
vLayout.addWidget( self._noCache )
vLayout.addWidget( self._rmBuild )
vLayout.addStretch()
optionsGroup = QGroupBox( 'Command Options' )
optionsGroup.setLayout( vLayout )
vLayout = QVBoxLayout()
vLayout.addWidget( self._threads )
vLayout.addWidget( self._verbose )
vLayout.addStretch()
miscGroup = QGroupBox( 'Misc. Options' )
miscGroup.setLayout( vLayout )
hLayout = QHBoxLayout()
hLayout.addWidget( commandGroup )
hLayout.addWidget( optionsGroup )
hLayout.addWidget( miscGroup )
commands = QWidget()
commands.setLayout( hLayout )
vLayout = QVBoxLayout()
vLayout.addWidget( commands )
vLayout.addWidget( scrollToolsGroup )
vLayout.addStretch()
self.setLayout( vLayout )
self.readSettings()
return
def _getProjects ( self ): return self._projects
def _getBuildMode ( self ): return self._buildMode.currentText()
def _getThreads ( self ): return self._threads.currentText()
#def _getSvnUpdate ( self ): return self._svnUpdate.isChecked()
#def _getSvnStatus ( self ): return self._svnStatus.isChecked()
def _getMake ( self ): return self._make.isChecked()
def _getEnableDoc ( self ): return self._enableDoc.isChecked()
def _getDevtoolset ( self ): return self._devtoolset.isChecked()
def _getQt5 ( self ): return self._qt5.isChecked()
def _getNoCache ( self ): return self._noCache.isChecked()
def _getRmBuild ( self ): return self._rmBuild.isChecked()
def _getVerbose ( self ): return self._verbose.isChecked()
projects = property( _getProjects )
buildMode = property( _getBuildMode )
threads = property( _getThreads )
#svnUpdate = property( _getSvnUpdate )
#svnStatus = property( _getSvnStatus )
make = property( _getMake )
enableDoc = property( _getEnableDoc )
devtoolset = property( _getDevtoolset )
qt5 = property( _getQt5 )
noCache = property( _getNoCache )
rmBuild = property( _getRmBuild )
verbose = property( _getVerbose )
def readSettings ( self ):
settings = QSettings()
#self._svnUpdate .setChecked( settings.value('builder/svnUpdate').toBool() )
#self._svnStatus .setChecked( settings.value('builder/svnStatus').toBool() )
self._make .setChecked( settings.value('builder/make' ).toBool() )
self._enableDoc .setChecked( settings.value('builder/enableDoc').toBool() )
self._devtoolset .setChecked( settings.value('builder/devtoolset').toBool() )
self._qt5 .setChecked( settings.value('builder/qt5').toBool() )
self._noCache .setChecked( settings.value('builder/noCache' ).toBool() )
self._rmBuild .setChecked( settings.value('builder/rmBuild' ).toBool() )
self._verbose .setChecked( settings.value('builder/verbose' ).toBool() )
buildModeName = settings.value('builder/buildMode').toString()
index = self._buildMode.findText( buildModeName )
if index >= 0: self._buildMode.setCurrentIndex( index )
threads = settings.value('builder/threads').toString()
index = self._threads.findText( threads )
if index >= 0: self._threads.setCurrentIndex( index )
for project in self._projects: project.readFromSettings()
return
def saveSettings ( self ):
settings = QSettings()
#settings.setValue('builder/svnUpdate' , self._svnUpdate .isChecked() )
#settings.setValue('builder/svnStatus' , self._svnStatus .isChecked() )
settings.setValue('builder/make' , self._make .isChecked() )
settings.setValue('builder/enableDoc' , self._enableDoc .isChecked() )
settings.setValue('builder/devtoolset', self._devtoolset.isChecked() )
settings.setValue('builder/qt5' , self._qt5 .isChecked() )
settings.setValue('builder/buildMode' , self._buildMode .currentText() )
settings.setValue('builder/noCache' , self._noCache .isChecked() )
settings.setValue('builder/rmBuild' , self._rmBuild .isChecked() )
settings.setValue('builder/verbose' , self._verbose .isChecked() )
settings.setValue('builder/threads' , self._threads .currentText() )
for project in self._projects: project.saveToSettings()
return

Some files were not shown because too many files have changed in this diff Show More