Compare commits

..

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

9013 changed files with 130246 additions and 2112327 deletions

7
.gitignore vendored
View File

@ -8,10 +8,9 @@ TAGS
GTAGS GTAGS
GPATH GPATH
GRTAGS GRTAGS
.dir-locals.el dir-locals.el
.projectile .projectile
lefdef/src/lef/lef/lef.tab.h
man/ man/
rtf/ rtf/
@ -37,7 +36,3 @@ documentation/RDS/RDS.pdf
documentation/RDS/RDS.tex documentation/RDS/RDS.tex
documentation/RDS/RDS.toc 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

@ -1,16 +1,15 @@
UNAME_S = $(shell uname -s) UNAME_S = $(shell uname -s)
UNAME_R = $(shell uname -r) UNAME_R = $(shell uname -r)
DEVTOOLSET_VERSION = 7
# We must use devtoolset only under RHEL6 & clones. # We must use devtoolset-2 only under RHEL6 & clones.
DEVTOOLSET_OPTION = DEVTOOLSET_OPTION =
ifeq ($(UNAME_S),Linux) ifeq ($(UNAME_S),Linux)
ifneq ($(findstring .el7.,$(UNAME_R)),) ifneq ($(findstring .el6.,$(UNAME_R)),)
DEVTOOLSET_OPTION = --devtoolset=$(DEVTOOLSET_VERSION) DEVTOOLSET_OPTION = --devtoolset-2
endif endif
ifneq ($(findstring .slsoc6.,$(UNAME_R)),) ifneq ($(findstring .slsoc6.,$(UNAME_R)),)
DEVTOOLSET_OPTION = --devtoolset=$(DEVTOOLSET_VERSION) DEVTOOLSET_OPTION = --devtoolset-2
endif endif
endif endif
@ -57,6 +56,7 @@ check_dir:
install: check_dir install: check_dir
@./bootstrap/ccb.py $(DEVTOOLSET_OPTION) --project=support --project=coriolis --make="$(SMP_FLAGS) install" @./bootstrap/ccb.py $(DEVTOOLSET_OPTION) --project=support --project=coriolis --make="$(SMP_FLAGS) install"
@./bootstrap/ccb.py $(DEVTOOLSET_OPTION) --project=support --project=coriolis --make="-j1 install" --doc
@echo ""; \ @echo ""; \
echo "============================================================================"; \ echo "============================================================================"; \
echo "Coriolis has been successfully built"; \ echo "Coriolis has been successfully built"; \

View File

@ -5,19 +5,20 @@
Coriolis README 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 Purpose
======= =======
Coriolis provides several tools to perform the layout of VLSI circuits. Its 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 router, but other tools can use the Hurricane database and the parsers
provided. provided.
The user interface <cgt> is the prefered way to use Coriolis, but all 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 Documentation
@ -25,14 +26,14 @@ Documentation
The complete documentation is available here, both in pdf & html: The complete documentation is available here, both in pdf & html:
./documentation/output/html ./documentation/_build/html/index.html
./documentation/UsersGuide/UsersGuide.pdf ./documentation/UsersGuide/UsersGuide.pdf
The documentation of the latest *stable* version is also The documentation of the latest *stable* version is also
available online. It may be quite outdated from the *devel* available online. It may be quite outdated from the *devel*
version. 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 Building Coriolis
@ -40,29 +41,35 @@ Building Coriolis
To build Coriolis, ensure the following prerequisites are met: To build Coriolis, ensure the following prerequisites are met:
* Python 3, * Python 2.7.
* cmake, * cmake.
* boost, * boost.
* bison & flex, * bison & flex.
* Qt 4 or 5, * Qt 4 or 5.
* libxml2, * libxml2.
* RapidJSON, * RapidJSON
* A C++11 compliant compiler. * A C++11 compliant compiler.
The build system relies on a fixed directory tree from the root 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 of the user currently building it. Thus first step is to get a clone of
the repository in the right place. Proceed as follow: :: 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:~$ 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 ego@home:src$ cd coriolis
If you want to use the *devel* branch: ::
ego@home:coriolis$ git checkout devel
Then, build the tool: :: Then, build the tool: ::
ego@home:coriolis$ make install 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 gets installed at the root of the following tree: ::
~/coriolis-2.x/<OS>.<DISTRIB>/Release.Shared/install/ ~/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 ego@home:~: ~/coriolis-2.x/<OS>.<DISTRIB>/Release.Shared/install/bin/coriolis
The ``coriolis`` script detects its location and setups the UNIX The ``coriolis`` script is tasked to guess it's location and setup appropriatly
environment appropriately, then lauches ``cgt`` (or *any* command, with the the UNIX environment, then lauch ``cgt`` (or *any* command, with the
``--run=<COMMAND>`` option). ``--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: :: using the helper ``coriolisEnv.py``, then run any Coriolis tool: ::
ego@home:~$ eval `~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py` 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,558 +0,0 @@
.sm
{
position:relative;
z-index:9999
}
.sm,.sm ul,.sm li
{
display:block;
list-style:none;
margin:0;
padding:2pt 7pt;
line-height:normal;
direction:ltr;
text-align:left;
-webkit-tap-highlight-color:rgba(0,0,0,0)
}
.sm-rtl,.sm-rtl ul,.sm-rtl li
{
direction:rtl;
text-align:right
}
.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6
{
margin:0;
padding:0
}
.sm ul
{
display:none
}
.sm li,.sm a
{
position:relative
}
.sm a
{
display:block
}
.sm a.disabled
{
cursor:not-allowed
}
.sm:after
{
content:"\00a0";
display:block;
height:0;
font:0/0 serif;
clear:both;
visibility:hidden;
overflow:hidden
}
.sm,.sm *,.sm *:before,.sm *:after
{
-moz-box-sizing:border-box;
-webkit-box-sizing:border-box;
box-sizing:border-box
}
#doc-content
{
overflow:auto;
display:block;
padding:0;
margin:0;
-webkit-overflow-scrolling:touch
}
/*
.sm-dox
{
background-image:url("tab_b.png")
}
*/
/*
.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active
{
padding:0 12px;
padding-right:43px;
font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;
font-size:13px;
font-weight:bold;
line-height:36px;
text-decoration:none;
text-shadow:0 1px 1px rgba(255,255,255,0.9);
color:#283a5d;
outline:0
}
*/
/*
.sm-dox a:hover
{
background-image:url("tab_a.png");
background-repeat:repeat-x;
color:white;
text-shadow:0 1px 1px black
}
*/
.sm-dox a.current
{
color:#d23600
}
.sm-dox a.disabled
{
color:#bbb
}
.sm-dox a span.sub-arrow
{
position:absolute;
top:50%;
margin-top:-14px;
left:auto;
right:3px;
width:28px;
height:28px;
overflow:hidden;
font:bold 12px/28px monospace!important;
text-align:center;
text-shadow:none;
background:rgba(255,255,255,0.5);
-moz-border-radius:5px;
-webkit-border-radius:5px;
border-radius:5px
}
.sm-dox a.highlighted span.sub-arrow:before
{
display:block;
content:'-'
}
/*
.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a
{
-moz-border-radius:5px 5px 0 0;
-webkit-border-radius:5px;
border-radius:5px 5px 0 0
}
.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul
{
-moz-border-radius:0 0 5px 5px;
-webkit-border-radius:0;
border-radius:0 0 5px 5px
}
.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted
{
-moz-border-radius:0;
-webkit-border-radius:0;
border-radius:0
}
*/
/*
.sm-dox ul
{
background:rgba(162,162,162,0.1)
}
*/
/*
.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active
{
font-size:12px;
border-left:8px solid transparent;
line-height:36px;
text-shadow:none;
background-color:white;
background-image:none
}
*/
/*
.sm-dox ul a:hover
{
background-image:url("tab_a.png");
background-repeat:repeat-x;
color:white;
text-shadow:0 1px 1px black
}
*/
.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active
{
border-left:16px solid transparent
}
.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active
{
border-left:24px solid transparent
}
.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active
{
border-left:32px solid transparent
}
.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active
{
border-left:40px solid transparent
}
.sm-dox ul
{
position:absolute;
width:12em
}
/*
.sm-dox li
{
float:left
}
.sm-dox.sm-rtl li
{
float:right
}
.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li
{
float:none
}
*/
.sm-dox a
{
white-space:nowrap
}
.sm-dox ul a,.sm-dox.sm-vertical a
{
white-space:normal
}
.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a
{
white-space:nowrap
}
/*
.sm-dox
{
padding:0 10px;
background-image:url("tab_b.png");
line-height:36px
}
*/
.sm-dox a span.sub-arrow
{
top:50%;
margin-top:-2px;
right:12px;
width:0;
height:0;
border-width:4px;
border-style:solid dashed dashed dashed;
border-color:#283a5d transparent transparent transparent;
background:transparent;
-moz-border-radius:0;
-webkit-border-radius:0;
border-radius:0
}
/*
.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted
{
padding:0 12px;
background-image:url("tab_s.png");
background-repeat:no-repeat;
background-position:right;
-moz-border-radius:0!important;
-webkit-border-radius:0;
border-radius:0!important
}
.sm-dox a:hover
{
background-image:url("tab_a.png");
background-repeat:repeat-x;
color:white;
text-shadow:0 1px 1px black
}
*/
.sm-dox a:hover span.sub-arrow
{
border-color:white transparent transparent transparent
}
.sm-dox a.has-submenu
{
padding-right:24px
}
.sm-dox li
{
border-top:0
}
.sm-dox>li>ul:before,.sm-dox>li>ul:after
{
content:'';
position:absolute;
top:-18px;
left:30px;
width:0;
height:0;
overflow:hidden;
border-width:9px;
border-style:dashed dashed solid dashed;
border-color:transparent transparent #bbb transparent
}
.sm-dox>li>ul:after
{
top:-16px;
left:31px;
border-width:8px;
border-color:transparent transparent #fff transparent
}
.sm-dox ul
{
border:1px solid #bbb;
padding:5px 0;
background:#fff;
/*
-moz-border-radius:5px!important;
-webkit-border-radius:5px;
border-radius:5px!important;
*/
-moz-box-shadow:0 5px 9px rgba(0,0,0,0.2);
-webkit-box-shadow:0 5px 9px rgba(0,0,0,0.2);
box-shadow:0 5px 9px rgba(0,0,0,0.2)
}
.sm-dox ul a span.sub-arrow
{
right:8px;
top:50%;
margin-top:-5px;
border-width:5px;
border-color:transparent transparent transparent #555;
border-style:dashed dashed dashed solid
}
.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted
{
color:#555;
background-image:none;
border:0!important;
color:#555;
background-image:none
}
/*
.sm-dox ul a:hover
{
background-image:url("tab_a.png");
background-repeat:repeat-x;
color:white;
text-shadow:0 1px 1px black
}
*/
.sm-dox ul a:hover span.sub-arrow
{
border-color:transparent transparent transparent white
}
.sm-dox span.scroll-up,.sm-dox span.scroll-down
{
position:absolute;
display:none;
visibility:hidden;
overflow:hidden;
background:#fff;
height:36px
}
.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover
{
background:#eee
}
.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow
{
border-color:transparent transparent #d23600 transparent
}
.sm-dox span.scroll-down:hover span.scroll-down-arrow
{
border-color:#d23600 transparent transparent transparent
}
.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow
{
position:absolute;
top:0;
left:50%;
margin-left:-6px;
width:0;
height:0;
overflow:hidden;
border-width:6px;
border-style:dashed dashed solid dashed;
border-color:transparent transparent #555 transparent
}
.sm-dox span.scroll-down-arrow
{
top:8px;
border-style:solid dashed dashed dashed;
border-color:#555 transparent transparent transparent
}
.sm-dox.sm-rtl a.has-submenu
{
padding-right:12px;
padding-left:24px
}
.sm-dox.sm-rtl a span.sub-arrow
{
right:auto;
left:12px
}
.sm-dox.sm-rtl.sm-vertical a.has-submenu
{
padding:10px 20px
}
.sm-dox.sm-rtl.sm-vertical a span.sub-arrow
{
right:auto;
left:8px;
border-style:dashed solid dashed dashed;
border-color:transparent #555 transparent transparent
}
.sm-dox.sm-rtl>li>ul:before
{
left:auto;
right:30px
}
.sm-dox.sm-rtl>li>ul:after
{
left:auto;
right:31px
}
.sm-dox.sm-rtl ul a.has-submenu
{
padding:10px 20px!important
}
.sm-dox.sm-rtl ul a span.sub-arrow
{
right:auto;
left:8px;
border-style:dashed solid dashed dashed;
border-color:transparent #555 transparent transparent
}
.sm-dox.sm-vertical
{
padding:10px 0;
-moz-border-radius:5px;
-webkit-border-radius:5px;
border-radius:5px
}
.sm-dox.sm-vertical a
{
padding:10px 20px
}
.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted
{
background:#fff
}
.sm-dox.sm-vertical a.disabled
{
background-image:url("tab_b.png")
}
.sm-dox.sm-vertical a span.sub-arrow
{
right:8px;
top:50%;
margin-top:-5px;
border-width:5px;
border-style:dashed dashed dashed solid;
border-color:transparent transparent transparent #555
}
.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after
{
display:none
}
.sm-dox.sm-vertical ul a
{
padding:10px 20px
}
.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted
{
background:#eee
}
.sm-dox.sm-vertical ul a.disabled
{
background:#fff
}
/* SoC Customisation. */
div#main-nav {
margin: 0pt;
border: 0pt;
padding: 0pt;
}
div ul#main-menu {
margin: 0pt;
border: 0pt;
padding: 0pt;
}
/*
.sm ul {
visibility: hidden;
overflow: hidden;
height: 0;
width: 0;
}
*/
.sm li {
list-style: none;
}
ul#main-menu {
display: table;
width: 100%;
}
ul#main-menu > li {
display: table-cell;
text-align: center;
/*width: 20%;*/
border-top: 1px solid black;
border-bottom: 1px solid black;
border-left: none;
border-right: 1px solid black;
padding: 2pt;
font-size: 90%;
}
ul#main-menu > li:first-child {
border-left: 1px solid black;
}
ul#main-menu > li > a {
border-bottom: none;
}
ul#main-menu > li:hover, ul#main-menu > li:hover > a, ul#main-menu > li > a:hover {
background-color: black;
color: white;
}
/*
.sm li {
margin: 0pt;
list-style: none;
font-size: 90%;
border-top: 1px solid black;
border-bottom: 1px solid black;
border-left: none;
border-right: 1px solid black;
display: table-cell;
text-align: center;
padding: 2pt;
width: 5%;
}
.sm li:first-child {
border-left: 1px solid black;
}
.sm li a {
border-style: none;
border-bottom: none;
}
.sm li:hover, .sm li:hover a, .sm li a:hover {
background-color: black;
color: white;
}
*/

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,35 +3,36 @@
set(CMAKE_LEGACY_CYGWIN_WIN32 0) set(CMAKE_LEGACY_CYGWIN_WIN32 0)
project(ANABATIC) project(ANABATIC)
set(ignoreVariables "${BUILD_DOC} ${CMAKE_INSTALL_DIR}")
option(BUILD_DOC "Build the documentation (doxygen)" OFF) option(BUILD_DOC "Build the documentation (doxygen)" OFF)
option(CHECK_DATABASE "Run database in full check mode (very slow)" 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/") list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}$ENV{CORIOLIS_TOP}/share/cmake/Modules/")
find_package(Bootstrap REQUIRED) find_package(Bootstrap REQUIRED)
setup_project_paths(CORIOLIS) setup_project_paths(CORIOLIS)
set_cmake_policies() set_cmake_policies()
set_lib_link_mode()
setup_boost() setup_boost()
setup_qt() setup_qt()
setup_python()
find_package(PythonLibs 2 REQUIRED)
find_package(PythonSitePackages REQUIRED) find_package(PythonSitePackages REQUIRED)
find_package(FLUTE REQUIRED) find_package(VLSISAPD REQUIRED)
find_package(HURRICANE REQUIRED) find_package(HURRICANE REQUIRED)
find_package(CORIOLIS REQUIRED) find_package(CORIOLIS REQUIRED)
find_package(ETESIAN REQUIRED)
find_package(COLOQUINTE REQUIRED)
find_package(Doxygen)
add_subdirectory(src) add_subdirectory(src)
add_subdirectory(cmake_modules) add_subdirectory(cmake_modules)
#add_subdirectory(doc)
#if(BUILD_DOC)
# find_package(Doxygen)
# if(DOXYGEN_FOUND)
# add_subdirectory(doc)
# endif()
#endif()
if(CHECK_DATABASE) if(CHECK_DATABASE)
add_definitions(-DCHECK_DATABASE) add_definitions(-DCHECK_DATABASE)
message(STATUS "Checking database enabled (very slow).") message(STATUS "Checking database enabled (very slow).")

View File

@ -6,7 +6,7 @@
# ANABATIC_LIBRARIES - The path to where the Coriolis library files are. # 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}") 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 FIND_PATH(ANABATIC_INCLUDE_PATH NAMES anabatic/AnabaticEngine.h PATHS
# Look in other places. # Look in other places.
${CORIOLIS_DIR_SEARCH} ${CORIOLIS_DIR_SEARCH}
PATH_SUFFIXES include/coriolis2 PATH_SUFFIXES include/coriolis
# Help the user find it if we cannot. # Help the user find it if we cannot.
DOC "The ${ANABATIC_INCLUDE_PATH_DESCRIPTION}" DOC "The ${ANABATIC_INCLUDE_PATH_DESCRIPTION}"
) )
@ -26,7 +26,7 @@ IF(UNIX)
FIND_LIBRARY(ANABATIC_LIBRARY_PATH FIND_LIBRARY(ANABATIC_LIBRARY_PATH
NAMES anabatic NAMES anabatic
PATHS ${CORIOLIS_DIR_SEARCH} PATHS ${CORIOLIS_DIR_SEARCH}
PATH_SUFFIXES lib64 lib PATH_SUFFIXES lib${LIB_SUFFIX}
# Help the user find it if we cannot. # Help the user find it if we cannot.
DOC "The ${ANABATIC_INCLUDE_PATH_DESCRIPTION}" DOC "The ${ANABATIC_INCLUDE_PATH_DESCRIPTION}"
) )

View File

@ -1,346 +0,0 @@
// -*- C++ -*-
namespace Anabatic {
/*! \defgroup LoadGlobalRouting Global Routing Loading
* \brief Translation rules to build detailed routing from global
*
* This module documents how the global routing built by \c Knik is
* loaded into the \c Anabatic data-base. It is intented for developpers
* only.
*/
//! \addtogroup LoadGlobalRouting
//! \{
//! \enum LocalFunctionFlag
//! A set of flags for all functions of the LoadGlobalRouting module.
//! They can be combined to form the \e flags argument of functions.
//! the functions will ignore flags that are not intended to them.
//!
//! For \c HSmall, \c VSmall & \c Punctual see checkRoutingPadSize().
//! \var LocalFunctionFlag::NoFlags
//! A simple alias over zero to explicitly tell that no flag at all is
//! passed to the function.
//! \var LocalFunctionFlag::HAccess
//! The constructed topology will be accessed through an horizontal
//! segment. The absence of this flag tell that the access will be done
//! trough a vertical.
//! \var LocalFunctionFlag::VSmall
//! The RoutingPad vertically covers a very small number of access points,
//! so it is likely overconstrained for direct horizontal connexion.
//! \var LocalFunctionFlag::HSmall
//! The RoutingPad horizontally covers a very small number of access points,
//! so it is likely overconstrained for direct vertical connexion.
//! \var LocalFunctionFlag::Punctual
//! The RoutingPad covers only an access point in either direction.
//! \var LocalFunctionFlag::DoSourceContact
//! When creating Anabatic::AutoContactTerminal on non-punctual RoutingPad, this flag
//! request the creation of a contact <em>on the source point</em>.
//! \var LocalFunctionFlag::DoTargetContact
//! When creating Anabatic::AutoContactTerminal on non-punctual RoutingPad, this flag
//! request the creation of a contact <em>on the target point</em>.
//! \function uint64_t checkRoutingPadSize ( Component* rp );
//!
//! Look at the geometrical size of the Component and assess if
//! it's span is too narrow either horizontally or vertically.
//! Return a combination of flags indicating it's state:
//! - HSmall : less than 3 pitches in horizontal direction.
//! - VSmall : less than 3 pitches in vertical direction.
//! - Punctual : one pitch in either directions.
//!
//! The component can be a RoutingPad, a Vertical or an Horizontal.
//!
//! \image html checkRoutingPadSize.png "checkRoutingPadSize()"
/*! \class NetBuilder
*
* \brief Build the wiring for a Net inside a GCell (\b internal).
*
* As this class is called to initially construct the Anabatic wiring,
* it must build a \b connex wiring. That is without gaps in layer depth,
* because the topology restauration mechanism (AutoContact::updateTopology())
* of the AutoContact cannot work until all AutoSegments are revalidated at
* least once. The topology restauration work by creating doglegs which in turn,
* call the canonization, which needs all the caches to be up to date.
*/
//! \function void NetBuilder::doRp_AutoContacts ( GCell* gcell, Component* rp, AutoContact*& source, AutoContact*& target, uint64_t flags );
//! \param gcell The GCell into which create the AutoContact.
//! \param rp The Component we want to access.
//! \param source The AutoContact created on the \c source (\e returned).
//! \param target The AutoContact created on the \c target (\e returned).
//! \param flags Managed by this function:
//! - LocalFunctionFlag::DoSourceContact
//! - LocalFunctionFlag::DoTargetContact
//!
//! Create the AutoContact directly anchored on the Component (terminal).
//! Three cases are manageds:
//! -# <b>Ordinary (non-punctual) \c METAL1 terminal</b>: an AutoContactTerminal
//! is anchored on the RoutingPad.
//! -# <b>Punctual \c METAL1 terminal</b>, the access must never be blocked
//! by other routing. To ensure it, we create a fixed AutoSegment (anchored
//! on two AutoContactTerminal) to cover it. The \e normal AutoContactTerminal
//! is also created.
//! -# <b>non \c METAL1 terminal</b>, as for the punctual \c METAL1, a
//! fixed protection is added over the RoutingPad. If we access
//! horizontally a vertical RoutingPad or vertically an horizontal
//! one, an extra AutoContactTerminal is added (to allow is displacement
//! along the RoutingPad).
//!
//! To avoid creating a fixed protection over a RoutingPad multiple times,
//! the RoutingPad and it's associated protection is stored in a static
//! \c map : \c __routingPadAutoSegments.
//!
//! Conversely, because an AutoContactTerminal can only be connected to one
//! segment, each time this function is called a new terminal will be created
//! (or maybe two in case of non-punctual terminals). If only one AutoContact
//! is requested, it is created centered on the RoutingPad. The initial
//! position of AutoContact <em>do not prevent them to move afterwards</em>,
//! even those created on source/target on a non-punctual RoutingPad.
//!
//! \remark For clarity we describe the layer management of this function in term
//! of \c METAL, but it is the RoutingGauge depth which is actually used.
//!
//! \image html doRp_AutoContacts.png "doRp_AutoContacts()"
//! \function AutoContact* NetBuilder::doRp_Access ( GCell* gcell, Component* rp, uint64_t flags );
//! \param gcell The GCell into which create the AutoContact.
//! \param rp The Component onto which anchor the access contact.
//! \param flags Relevant flags are:
//! - HAccess, the terminal is to be accessed through an horizontal
//! segment.
//! - VSmall, force the terminal to be considered as small in the
//! vertical direction.
//!
//! If \c HAccess is set, the Component is to be accessed trough an horizontal
//! segment. If unset, the access is done vertically.
//!
//! Create an AutoContact to access a Component (terminal). If the Component
//! is not to be accessed through an horizontal segment, and do not cover a
//! large span in the horizontal direction (flag \c VSmall), a local horizontal
//! AutoSegment is added to slacken the vertical constraints.
//!
//! \image html doRp_Access.png "doRp_Access()"
//! \function AutoContact* NetBuilder::doRp_AccessPad ( RoutingPad* rp, uint64_t flags );
//! \param rp The Component onto which anchor the access contact.
//! \param flags Relevant flags are:
//! - HAccess, the terminal is to be accessed through an horizontal
//! segment.
//! - VSmall, force the terminal to be considered as small in the
//! vertical direction.
//! \return A Anabatic::AutoContactTerminal .
//!
//! The Component \c rp is a RoutingPad which belongs to a pad cell. This case
//! occurs when we are routing a complete chip. This method build, from the
//! \c rp a stack of articulated punctual segments and contacts to reach the
//! default H/V routing layers (usually \c METAL2 & \c METAL3). This may be
//! needed when the pad terminal is in \c METAL5, for instance.
//!
//! The returned AutoContactTerminal is anchored on the last punctual segment
//! build.
//!
//! The GCell into which the AutoContactTerminal is created may be under the
//! pads area. However, it will be right on the border of the GCell.
//! The global router vertexes of GCell under the pad area are marked as
//! blocked so will never be used for routing.
//!
//! \remark The segments and contacts added to ensure the layer connexity are not
//! put into the Anabatic database. They are plain Hurricane objects, invisibles
//! from it.
//! \function void NetBuilder::doRp_StairCaseH ( GCell* gcell, Component* rp1, Component* rp2 );
//!
//! Build the wiring to connect to horizontal Component. Two cases:
//! - The Component are aligneds, then only a straight wire is created.
//! - They are \e not aligned, then a complete dogleg is created.
//!
//! \image html doRp_StairCaseH.png "doRp_StairCaseH()"
//! \function void NetBuilder::doRp_StairCaseV ( GCell* gcell, Component* rp1, Component* rp2 );
//!
//! Build the wiring to connect to vertical Components. Two cases:
//! - The Components are aligneds, then only a straight wire is created.
//! - They are \e not aligned, then a complete dogleg is created.
//!
//! \image html doRp_StairCaseV.png "doRp_StairCaseV()"
//! \function void NetBuilder::_do_xG_1Pad ();
//!
//! Construct the topology, when there is only global wires and one local
//! terminal, but coming from a Pad. As thoses connectors will always be
//! on one border of the GCell they can be considered as a kind of global.
//!
//! So this method mostly calls NetBuilder::doRp_AccessPad() to create
//! the AutoContactTerminal, then calls NetBuilder::_do_xG(), except
//! for straight lines which are managed directly.
//! \function void NetBuilder::_do_xG ();
//!
//! Construct the topology, when there is only global wires (no local terminals).
//!
//! Some topology are not handled because they must not be managed by this
//! function:
//! <ul>
//! <li>One global: nonsensical because there also must be a terminal.
//! <li>Two aligned globals: in that case we do a straight wire whithout
//! any AutoContact (handled by the source/target of the wire).
//! </ul>
//!
//! \image html _do_xG.png "_do_xG()"
//! \function void NetBuilder::_do_1G_1M1 ();
//!
//! Construct a topology where there is \e one global and one RoutingPad
//! in \c METAL1. The \c METAL1 is assumed to be vertical.
//!
//! \remark When accessing the RoutingPad through an horizontal global segment
//! and the vertical extension of the segment is small, the global is
//! still directly attached to the terminal, inducing a high constraint
//! on it. We left to job of slackening it to the router.
//!
//! \image html _do_1G_1M1.png "_do_1G_1M1()"
//! \function void NetBuilder::_do_1G_xM1 ();
//!
//! Construct a topology where there is \e one global and any number of
//! RoutingPad in \c METAL1. The \c METAL1 is assumed to be vertical.
//!
//! The RoutingPads are linked together two by two. If the horizontal
//! segments are not aligned by the router, part of the routage will be
//! done through the RoutingPad itself. The global incoming segment will
//! connected to the leftmost, rightmost or centermost RoutingPad according
//! from wich side it comes from.
//!
//! \image html _do_1G_xM1.png "_do_1G_xM1()"
//! \function void NetBuilder::_do_xG_1M1_1M2 ();
//!
//! Construct a topology where there is at least one global (and up to 4),
//! one \c METAL1 RoutingPad (assumed V) and one \c METAL2 RoutingPad (assumed H).
//!
//! In this topology, we want to try to reuse the \c METAL2 RoutingPad as a
//! feedtrough in the horizontal routage. Thus:
//! - The \c METAL1 and \c METAL2 RoutingPad are connected through a separate wiring.
//! - The south & west global wiring is attached to the leftmost contact of
//! the \c METAL2.
//! - The north & east global wiring is attached to the rightmost contact of
//! the \c METAL2.
//!
//! South/west and north/south can be build independantly. Depending on the number
//! of globals, they can consist of:
//! - Nothing (no south nor west).
//! - An AutoContact (west present).
//! - An horizontal plus a turn (south present).
//! - An horizontal plus a HTee (south & west present).
//!
//! \remark Not all configurations are represented below.
//!
//! \image html _do_xG_1M1_1M2.png "_do_xG_1M1_1M2()"
//! \function void NetBuilder::_do_xG_xM1_xM3 ();
//!
//! Construct a topology where there is at least one global (and up to 4),
//! at least one \c METAL1 RoutingPad (assumed V) and at least one \c METAL3
//! RoutingPad (assumed V).
//!
//! In this topology, we want to try to reuse the \c METAL3 RoutingPad as a
//! feedtrough in the vertical routage. Thus:
//! - The \c METAL1 and \c METAL3 RoutingPad are connected through a separate
//! wiring made of separate horizontals.
//! - The south-west global wiring is attached to the leftmost RoutingPad
//! if there isn't south or to the first \c METAL3 otherwise.
//! - The north-east global wiring is attached to the rightmost RoutingPad
//! if there isn't north or to the first \c METAL3 otherwise.
//!
//! South/west and north/south can be build independantly. Depending on the number
//! of globals, they can consist of:
//! - Nothing (no south nor west).
//! - An AutoContact on the leftmost RoutingPad (west present).
//! - An AutoContact on the first \c METAL3 (only south present).
//! - An AutoContact plus a vertical plus a VTee (south & west present).
//!
//! \image html _do_xG_xM1_xM3.png "_do_xG_xM1_xM3()"
//! \function void NetBuilder::_do_xG_xM2 ();
//!
//! Construct a topology where there is at least one global (and up to 4),
//! and any number of \c METAL2 RoutingPads (assumeds H).
//!
//! In this topology, we want to try to reuse the \c METAL2 RoutingPad as a
//! feedtrough in the horizontal routage. Thus:
//! - The RoutingPad are connecteds trough a separate staircase (or
//! straight wire if aligneds).
//! - The south-west global wiring is attached to the leftmost RoutingPad
//! if there isn't south or to the biggest horizontal RoutingPad otherwise.
//! - The north-east global wiring is attached to the rightmost RoutingPad
//! if there isn't south or to the biggest horizontal RoutingPad otherwise.
//!
//! \image html _do_xG_xM2.png "_do_xG_xM2()"
//! \function void NetBuilder::_do_1G_1M3 ();
//!
//! Construct a topology where there is one global and one \c METAL3 RoutingPad
//! (assumeds V).
//!
//! In this topology, we reuse the \c METAL3 RoutingPad as a feedtrough in the
//! vertical routage. Thus:
//! - If the global is either north or south, we directly connect to the
//! north end or south end of the RoutingPad. \red{The vertical global will}
//! \red{have no slack at all we assume that METAL3 terminals are only from}
//! \red{blocks and are aligneds vertically.}
//! - If the global is east or west \e and the RoutingPad is sufficiently
//! extended in the vertical direction, we connect an horizontal in the
//! normal way.
//! - If the global is not sufficiently extended, we add a turn to give some
//! slack to the global.
//!
//!
//! \image html _do_1G_1M3.png "_do_1G_1M3()"
//! \function void NetBuilder::_do_xG_xM3 ();
//!
//! Construct a topology where there at least one global and two \c METAL3 RoutingPad
//! (assumed V).
//!
//! In this topology, we reuse the \c METAL3 RoutingPad as a feedtrough in the
//! vertical routage. \red{We assume that the most likely relative position}
//! \red{of the RoutingPads is to be aligned vertically}.
//! Thus:
//! - All RoutingPads are linked two by two trough vertical staircases.
//! - The south-west global wiring is attached to the bottommost RoutingPad
//! (without vertical slack). If a misalignment is detected, then a
//! dogleg is added.
//! - The north-east global wiring is attached to the topmost RoutingPad
//! (without vertical slack).
//!
//! South/west and north/south can be build independantly. Depending on the number
//! of globals, they can consist of:
//! - Nothing (no south nor west).
//! - An sliding AutoContact on the bottommost RoutingPad (west present).
//! - An fixed AutoContact on the bottommost RoutingPad (only south present).
//! - An fixed AutoContact plus a vertical plus a VTee (south & west present).
//!
//! \image html _do_xG_xM3.png "_do_xG_xM3()"
//! \function void singleGCell ( AnabaticEngine* anbt, Net* net );
//!
//! All the RoutingPads of the net are concentrated under a single
//! GCell. This function assumes that all the terminals are in
//! \c METAL1 (vertical), and link them two by two by horizontal
//! wires.
//! \}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2018, All Rights Reserved // Copyright (c) UPMC 2008-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -110,7 +110,7 @@ namespace Anabatic {
void AutoContact::_preDestroy () void AutoContact::_preDestroy ()
{ {
DebugSession::open( _contact->getNet(), 145, 150 ); DebugSession::open( _contact->getNet(), 140, 150 );
cdebug_log(145,0) << "AutoContact::_preDestroy() - <AutoContact id:" << _id << ">" << endl; cdebug_log(145,0) << "AutoContact::_preDestroy() - <AutoContact id:" << _id << ">" << endl;
@ -178,45 +178,23 @@ namespace Anabatic {
AutoHorizontal* AutoContact::getHorizontal2 () const { return NULL; } AutoHorizontal* AutoContact::getHorizontal2 () const { return NULL; }
AutoVertical* AutoContact::getVertical1 () const { return NULL; } AutoVertical* AutoContact::getVertical1 () const { return NULL; }
AutoVertical* AutoContact::getVertical2 () 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 void AutoContact::getDepthSpan ( size_t& minDepth, size_t& maxDepth ) const
{ {
cdebug_log(145,1) << "AutoContact::getDepthSpan() of " << this << endl;
minDepth = (size_t)-1; minDepth = (size_t)-1;
maxDepth = 0; maxDepth = 0;
Component* anchor = getAnchor (); Component* anchor = getAnchor ();
if (anchor) { if (anchor) {
cdebug_log(145,0) << "* Anchor depth: "
<< Session::getRoutingGauge()->getLayerDepth(anchor->getLayer())<< endl;
minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) ); minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) );
maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) ); maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) );
} }
for ( AutoSegment* segment : const_cast<AutoContact*>(this)->getAutoSegments() ) { 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()) ); minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) );
maxDepth = std::max( maxDepth, 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()); size_t depth = Session::getRoutingGauge()->getLayerDepth(segment->getLayer());
DbU::Unit length; DbU::Unit length;
if (segment->isLocal()) { if (segment->isLocal()) {
length = segment->getAnchoredLength(); length = segment->getLength();
lengths[depth] += length; lengths[depth] += length;
DbU::Unit sideLength = (segment->isHorizontal()) ? hSideLength : vSideLength; DbU::Unit sideLength = (segment->isHorizontal()) ? hSideLength : vSideLength;
if ( not segment->isUnbound() and (abs(length) > sideLength) ) if ( not segment->isUnbound() and (abs(length) > sideLength) )
cerr << Error( "AutoContact::getLength(): Suspicious length %s (> %s) of %s.\n" cerr << Error("Suspicious length:%.2f of %s."
" (on: %s)" ,DbU::getValueString(length).c_str()
, DbU::getValueString(length).c_str() ,getString(segment).c_str()) << endl;
, DbU::getValueString(sideLength).c_str()
, getString(segment).c_str()
, getString(this).c_str()) << endl;
} else { } else {
if (segment->isHorizontal()) { if (segment->isHorizontal()) {
if (isSourceHook) if (isSourceHook)
@ -299,11 +274,10 @@ namespace Anabatic {
void AutoContact::invalidate ( Flags flags ) void AutoContact::invalidate ( Flags flags )
{ {
if (flags & Flags::Topology ) setFlags( CntInvalidatedCache );
if (not isInvalidated()) { if (not isInvalidated()) {
cdebug_log(145,1) << "AutoContact::invalidate() - " << this << endl; cdebug_log(145,1) << "AutoContact::invalidate() - " << this << endl;
cdebug_log(145,0) << "flags:" << flags.asString(FlagsFunction) << endl;
setFlags( CntInvalidated ); setFlags( CntInvalidated );
if (flags & Flags::Topology ) setFlags( CntInvalidatedCache );
Session::invalidate( this ); Session::invalidate( this );
_invalidate( flags ); _invalidate( flags );
@ -481,13 +455,11 @@ namespace Anabatic {
void AutoContact::setConstraintBox ( const Box& box ) void AutoContact::setConstraintBox ( const Box& box )
{ {
cdebug_log(149,0) << "setConstraintBox() " << this << " " << getConstraintBox()
<< " from:" << box << endl;
setCBXMin ( box.getXMin() ); setCBXMin ( box.getXMin() );
setCBXMax ( box.getXMax() ); setCBXMax ( box.getXMax() );
setCBYMin ( box.getYMin() ); setCBYMin ( box.getYMin() );
setCBYMax ( box.getYMax() ); setCBYMax ( box.getYMax() );
cdebug_log(149,0) << "setConstraintBox() " << this << " " << getConstraintBox() << endl; cdebug_log(149,0) << "setConstraintBox() - " << this << " " << getConstraintBox() << endl;
cdebug_log(149,0) << "* " << _gcell << endl; cdebug_log(149,0) << "* " << _gcell << endl;
} }
@ -578,30 +550,6 @@ 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) );
}
} else {
setLayer( Session::getContactLayer(depth) );
setSizes( Session::getViaWidth (depth)
, Session::getViaWidth (depth) );
}
cdebug_tabw(145,-1);
}
AutoContact* AutoContact::createFrom ( Contact* hurricaneContact ) AutoContact* AutoContact::createFrom ( Contact* hurricaneContact )
{ {
AutoContact* autoContact = NULL; AutoContact* autoContact = NULL;
@ -679,7 +627,6 @@ namespace Anabatic {
//s.insert( 4, getString(_id) ); //s.insert( 4, getString(_id) );
s.insert( s.size()-1, (isFixed ())?" F":" -" ); s.insert( s.size()-1, (isFixed ())?" F":" -" );
s.insert( s.size()-1, (isTerminal ())? "T": "-" ); s.insert( s.size()-1, (isTerminal ())? "T": "-" );
s.insert( s.size()-1, (canDrag ())? "D": "-" );
s.insert( s.size()-1, (isHTee ())? "h": "-" ); s.insert( s.size()-1, (isHTee ())? "h": "-" );
s.insert( s.size()-1, (isVTee ())? "v": "-" ); s.insert( s.size()-1, (isVTee ())? "v": "-" );
s.insert( s.size()-1, (isInvalidated ())? "i": "-" ); s.insert( s.size()-1, (isInvalidated ())? "i": "-" );

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2012-2018, All Rights Reserved // Copyright (c) UPMC 2012-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -91,11 +91,8 @@ namespace Anabatic {
} }
AutoSegment* AutoContactHTee::getPerpandicular ( const AutoSegment* from ) const AutoSegment* AutoContactHTee::getPerpandicular ( const AutoSegment* ) const
{ { return NULL; }
if ( (from == _horizontal1) or (from == _horizontal2) ) return _vertical1;
return NULL;
}
AutoSegment* AutoContactHTee::getSegment ( unsigned int index ) const AutoSegment* AutoContactHTee::getSegment ( unsigned int index ) const
@ -118,15 +115,14 @@ namespace Anabatic {
AutoVertical* AutoContactHTee::getVertical1 () const { return _vertical1; }; AutoVertical* AutoContactHTee::getVertical1 () const { return _vertical1; };
void AutoContactHTee::_invalidate ( Flags flags ) void AutoContactHTee::_invalidate ( Flags )
{ {
flags |= Flags::Propagate; Flags flags = Flags::Propagate;
if (_horizontal1 and _horizontal2) { if (_horizontal1 and _horizontal2) {
if (_horizontal1->isInvalidated() xor _horizontal2->isInvalidated()) if (_horizontal1->isInvalidated() xor _horizontal2->isInvalidated())
flags.reset( Flags::Propagate ); flags = Flags::NoFlags;
} }
cdebug_log(145,0) << "flags:" << flags.asString(FlagsFunction) << endl;
if (_horizontal1) _horizontal1->invalidate( flags ); if (_horizontal1) _horizontal1->invalidate( flags );
if (_horizontal2) _horizontal2->invalidate( flags ); if (_horizontal2) _horizontal2->invalidate( flags );
if (_vertical1 ) _vertical1 ->invalidate(); if (_vertical1 ) _vertical1 ->invalidate();
@ -200,7 +196,7 @@ namespace Anabatic {
void AutoContactHTee::updateCache () void AutoContactHTee::updateCache ()
{ {
DebugSession::open( getNet(), 145, 150 ); DebugSession::open( getNet(), 140, 150 );
cdebug_log(145,1) << _getTypeName() << "::updateCache() " << this << endl; cdebug_log(145,1) << _getTypeName() << "::updateCache() " << this << endl;
@ -249,7 +245,7 @@ namespace Anabatic {
void AutoContactHTee::updateGeometry () void AutoContactHTee::updateGeometry ()
{ {
DebugSession::open( getNet(), 145, 150 ); DebugSession::open( getNet(), 140, 150 );
cdebug_log(145,1) << _getTypeName() << "::updateGeometry() " << this << endl; cdebug_log(145,1) << _getTypeName() << "::updateGeometry() " << this << endl;
@ -277,7 +273,7 @@ namespace Anabatic {
void AutoContactHTee::updateTopology () void AutoContactHTee::updateTopology ()
{ {
DebugSession::open( getNet(), 145, 150 ); DebugSession::open( getNet(), 140, 150 );
cdebug_log(145,1) << _getTypeName() << "::updateTopology() " << this << endl; cdebug_log(145,1) << _getTypeName() << "::updateTopology() " << this << endl;
@ -309,10 +305,10 @@ namespace Anabatic {
if (depthH1 == depthH2) { if (depthH1 == depthH2) {
// Dogleg on the vertical. // Dogleg on the vertical.
switch ( delta ) { switch ( delta ) {
case 0: case 0: setLayer( rg->getRoutingLayer(minDepth) ); break;
case 1: setLayerAndWidth( delta, minDepth ); break; case 1: setLayer( rg->getContactLayer(minDepth) ); break;
default: default:
setLayerAndWidth( delta, depthH1 + ((depthH1==minDepth)?0:-1) ); setLayer( rg->getContactLayer( depthH1 + ((depthH1==minDepth)?0:-1) ) );
_vertical1 = static_cast<AutoVertical*>( _vertical1->makeDogleg(this) ); _vertical1 = static_cast<AutoVertical*>( _vertical1->makeDogleg(this) );
break; break;
} }
@ -322,12 +318,12 @@ namespace Anabatic {
int deltaH2 = (int)depthH2 - (int)depthV1; int deltaH2 = (int)depthH2 - (int)depthV1;
if (std::abs(deltaH1) > std::abs(deltaH2)) { if (std::abs(deltaH1) > std::abs(deltaH2)) {
setLayerAndWidth( 2, depthH2 + ((depthH2<depthV1)?0:-1) ); setLayer( rg->getContactLayer( depthH2 + ((depthH2<depthV1)?0:-1) ) );
//_horizontal1 = static_cast<AutoHorizontal*>( _horizontal1->makeDogleg(this) ); //_horizontal1 = static_cast<AutoHorizontal*>( _horizontal1->makeDogleg(this) );
_horizontal1->makeDogleg(this); _horizontal1->makeDogleg(this);
cdebug_log(145,0) << "New h1:" << _horizontal1 << endl; cdebug_log(145,0) << "New h1:" << _horizontal1 << endl;
} else { } else {
setLayerAndWidth( 2, depthH1 + ((depthH1<depthV1)?0:-1) ); setLayer( rg->getContactLayer( depthH1 + ((depthH1<depthV1)?0:-1) ) );
//_horizontal2 = static_cast<AutoHorizontal*>( _horizontal2->makeDogleg(this) ); //_horizontal2 = static_cast<AutoHorizontal*>( _horizontal2->makeDogleg(this) );
_horizontal2->makeDogleg(this); _horizontal2->makeDogleg(this);
cdebug_log(145,0) << "New h2:" << _horizontal2 << endl; cdebug_log(145,0) << "New h2:" << _horizontal2 << endl;

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2012-2018, All Rights Reserved // Copyright (c) UPMC 2012-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -29,7 +29,6 @@
#include "hurricane/RoutingPad.h" #include "hurricane/RoutingPad.h"
#include "hurricane/Vertical.h" #include "hurricane/Vertical.h"
#include "hurricane/Horizontal.h" #include "hurricane/Horizontal.h"
#include "hurricane/Pin.h"
#include "hurricane/DebugSession.h" #include "hurricane/DebugSession.h"
#include "crlcore/RoutingGauge.h" #include "crlcore/RoutingGauge.h"
#include "anabatic/AutoContactTerminal.h" #include "anabatic/AutoContactTerminal.h"
@ -47,8 +46,6 @@ namespace Anabatic {
using Hurricane::DebugSession; using Hurricane::DebugSession;
using Hurricane::Transformation; using Hurricane::Transformation;
using Hurricane::Entity; using Hurricane::Entity;
using Hurricane::Occurrence;
using Hurricane::Pin;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -63,7 +60,7 @@ namespace Anabatic {
, DbU::Unit height , DbU::Unit height
) )
{ {
cdebug_log(145,1) << "AutoContactTerminal::create(... Point, ...) " << endl; cdebug_log(145,1) << "AutoContactTerminal::create(... Point, ...)" << endl;
cdebug_log(145,0) << "@" << point << endl; cdebug_log(145,0) << "@" << point << endl;
anchor->getBodyHook()->detach(); anchor->getBodyHook()->detach();
@ -88,7 +85,7 @@ namespace Anabatic {
, const DbU::Unit height , const DbU::Unit height
) )
{ {
cdebug_log(145,0) << "AutoContactTerminal::create(... x, y, ...) " << endl; cdebug_log(145,0) << "AutoContactTerminal::create(... x, y, ...)" << endl;
cdebug_log(145,0) << "@ x:" << DbU::getValueString(x) << " y:" << DbU::getValueString(y) << endl; cdebug_log(145,0) << "@ x:" << DbU::getValueString(x) << " y:" << DbU::getValueString(y) << endl;
_preCreate( gcell, anchor->getNet(), layer ); _preCreate( gcell, anchor->getNet(), layer );
@ -131,13 +128,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 AutoSegment* AutoContactTerminal::getOpposite ( const AutoSegment* ) const
{ return NULL; } { return NULL; }
@ -181,36 +171,9 @@ namespace Anabatic {
if (component == NULL) { if (component == NULL) {
cerr << Error( "%s is not anchored.", getString(this).c_str() ) << endl; cerr << Error( "%s is not anchored.", getString(this).c_str() ) << endl;
cdebug_tabw(145,-1); cdebug_tabw(145,-1);
return _gcell->getBoundingBox(); return _gcell->getBoundingBox ();
} }
RoutingLayerGauge* lg = Session::getLayerGauge( Session::getLayerDepth(component->getLayer()) );
DbU::Unit xborder = 0;
DbU::Unit yborder = 0;
const Layer* viaLayer = Session::getContactLayer( lg->getDepth() );
if (viaLayer) {
if (lg->isHorizontal() and (lg->getDepth() != 0)) {
xborder = Session::getViaWidth( lg->getDepth() )/2
+ viaLayer->getBottomEnclosure( Layer::EnclosureH );
} else {
yborder = Session::getViaWidth( lg->getDepth() )/2
+ viaLayer->getBottomEnclosure( Layer::EnclosureV );
xborder = Session::getViaWidth( lg->getDepth() )/2
+ viaLayer->getBottomEnclosure( Layer::EnclosureH );
if (Session::getRoutingGauge()->isSymbolic()) {
// 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")
yborder -= DbU::fromLambda( 1.0 );
else
yborder -= DbU::fromLambda( 0.5 );
}
}
}
DbU::Unit xMin; DbU::Unit xMin;
DbU::Unit xMax; DbU::Unit xMax;
DbU::Unit yMin; DbU::Unit yMin;
@ -232,42 +195,6 @@ namespace Anabatic {
xMin = xMax xMin = xMax
= vertical->getTargetPosition().getX(); = vertical->getTargetPosition().getX();
} else if ( (routingPad = dynamic_cast<RoutingPad*>(component)) ) { } else if ( (routingPad = dynamic_cast<RoutingPad*>(component)) ) {
Occurrence occurrence = routingPad->getOccurrence();
Transformation transformation = occurrence.getPath().getTransformation();
Horizontal* horizontal = dynamic_cast<Horizontal*>( occurrence.getEntity() );
Vertical* vertical = dynamic_cast<Vertical* >( occurrence.getEntity() );
cdebug_log(145,0) << "Anchor: " << occurrence.getEntity() << endl;
cdebug_log(145,0) << "transf: " << transformation << endl;
if (horizontal or vertical) {
Box bb;
// Assume that transformation contains no rotations (for now).
if (horizontal) { bb = horizontal->getBoundingBox(); const_cast<AutoContactTerminal*>(this)->setFlags( CntOnHorizontal ); }
if (vertical) { bb = vertical ->getBoundingBox(); const_cast<AutoContactTerminal*>(this)->setFlags( CntOnVertical ); }
transformation.applyOn( bb );
cdebug_log(145,0) << "Shrink border x:" << DbU::getValueString(xborder)
<< " y:" << DbU::getValueString(yborder)
<< endl;
// HARDCODED.
if ( (Session::getRoutingGauge()->getName() == "sxlib")
and (bb.getWidth() == DbU::fromLambda(1.0)) ) {
bb.inflate( DbU::fromLambda(0.5), 0 );
}
bb.inflate( -xborder, -yborder );
xMin = bb.getXMin();
yMin = bb.getYMin();
xMax = bb.getXMax();
yMax = bb.getYMax();
} else {
xMin = xMax = component->getPosition().getX();
yMin = yMax = component->getPosition().getY();
}
#if FOR_SYMBOLIC_LAYERS
Entity* entity = routingPad->getOccurrence().getEntity(); Entity* entity = routingPad->getOccurrence().getEntity();
Transformation transf = routingPad->getOccurrence().getPath().getTransformation(); Transformation transf = routingPad->getOccurrence().getPath().getTransformation();
cdebug_log(145,0) << "Anchor: " << routingPad << endl; cdebug_log(145,0) << "Anchor: " << routingPad << endl;
@ -311,7 +238,6 @@ namespace Anabatic {
yMin = yMax = routingPad->getPosition().getY(); yMin = yMax = routingPad->getPosition().getY();
break; break;
} }
#endif
} else { } else {
xMin = xMax = component->getPosition().getX(); xMin = xMax = component->getPosition().getX();
yMin = yMax = component->getPosition().getY(); yMin = yMax = component->getPosition().getY();
@ -329,7 +255,7 @@ namespace Anabatic {
cdebug_log(145,0) << "| Using (y): " cdebug_log(145,0) << "| Using (y): "
<< DbU::getValueString(bb.getYMin()) << " " << DbU::getValueString(bb.getYMin()) << " "
<< DbU::getValueString(bb.getYMax()) << " " << bb << endl; << DbU::getValueString(bb.getYMax()) << endl;
cdebug_tabw(145,-1); cdebug_tabw(145,-1);
return bb; return bb;
@ -338,57 +264,36 @@ namespace Anabatic {
void AutoContactTerminal::_invalidate ( Flags flags ) void AutoContactTerminal::_invalidate ( Flags flags )
{ {
cdebug_log(145,0) << "flags:" << flags.asString(FlagsFunction) << endl; if (_segment) _segment->invalidate();
if (_segment) _segment->invalidate( flags|Flags::Propagate );
} }
void AutoContactTerminal::cacheDetach ( AutoSegment* segment ) void AutoContactTerminal::cacheDetach ( AutoSegment* segment )
{ {
if (_segment == segment) { if (_segment == segment) {
//_segment->unsetFlags( AutoSegment::SegAxisSet );
_segment = NULL; _segment = NULL;
setFlags( CntInvalidatedCache ); setFlags( CntInvalidatedCache );
unsetFlags( CntDrag );
} }
} }
void AutoContactTerminal::cacheAttach ( AutoSegment* segment ) void AutoContactTerminal::cacheAttach ( AutoSegment* segment )
{ {
DebugSession::open( getNet(), 145, 150 );
cdebug_log(145,1) << _getTypeName() << "::cacheAttach() " << this << endl;
if (_segment) { if (_segment) {
cerr << Bug( "%s::cacheAttach() On %s,\n" cerr << Bug( "%s::cacheAttach() On %s,\n"
" cache has not been cleared first, cancelled." " cache has not been cleared first, cancelled."
, _getTypeName().c_str(), getString(this).c_str() , _getTypeName().c_str(), getString(this).c_str()
) << endl; ) << endl;
cdebug_tabw(145,-1);
DebugSession::close();
return; return;
} }
_segment = segment; _segment = segment;
unsetFlags( CntInvalidatedCache ); unsetFlags( CntInvalidatedCache );
if ( (dynamic_cast<AutoHorizontal*>(_segment) and (getFlags() & CntOnHorizontal))
or (dynamic_cast<AutoVertical*> (_segment) and (getFlags() & CntOnVertical )) ) {
_segment->setFlags( AutoSegment::SegDrag|AutoSegment::SegAxisSet );
setFlags( CntDrag );
cdebug_log(145,0) << "Drag Contact/Segment set" << endl;
}
cdebug_log(145,0) << "Cached:" << _segment << endl;
cdebug_tabw(145,-1);
DebugSession::close();
} }
void AutoContactTerminal::updateCache () void AutoContactTerminal::updateCache ()
{ {
DebugSession::open( getNet(), 145, 150 ); DebugSession::open( getNet(), 140, 150 );
cdebug_log(145,1) << _getTypeName() << "::updateCache() " << this << endl; cdebug_log(145,1) << _getTypeName() << "::updateCache() " << this << endl;
@ -406,21 +311,13 @@ namespace Anabatic {
if (horizontals[1] != NULL) ++count; if (horizontals[1] != NULL) ++count;
if (verticals [0] != NULL) ++count; if (verticals [0] != NULL) ++count;
if (verticals [1] != NULL) ++count; if (verticals [1] != NULL) ++count;
if (count != 1) { if (count > 1) {
showTopologyError( "Terminal has not *exactly* one segment." ); showTopologyError( "Terminal has more than one segment." );
} }
if (horizontals[0] != NULL ) { if (horizontals[0] != NULL ) {
_segment = Session::lookup( horizontals[0] ); _segment = Session::lookup( horizontals[0] );
if (getFlags() & CntOnHorizontal) {
setFlags( CntDrag );
_segment->setFlags( AutoSegment::SegDrag|AutoSegment::SegFixedAxis );
}
} else { } else {
_segment = Session::lookup( verticals[0] ); _segment = Session::lookup( verticals[0] );
if (getFlags() & CntOnVertical) {
setFlags( CntDrag );
_segment->setFlags( AutoSegment::SegDrag|AutoSegment::SegFixedAxis );
}
} }
if (_segment == NULL) { if (_segment == NULL) {
ostringstream os; ostringstream os;
@ -447,7 +344,7 @@ namespace Anabatic {
void AutoContactTerminal::updateGeometry () void AutoContactTerminal::updateGeometry ()
{ {
DebugSession::open( getNet(), 145, 150 ); DebugSession::open( getNet(), 140, 150 );
cdebug_log(145,1) << _getTypeName() << "::updateGeometry() " << this << endl; cdebug_log(145,1) << _getTypeName() << "::updateGeometry() " << this << endl;
@ -499,27 +396,9 @@ namespace Anabatic {
cdebug_log(145,0) << "Contact for wide segment." << endl; cdebug_log(145,0) << "Contact for wide segment." << endl;
} }
if (canDrag()) {
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;
}
}
if (not getUConstraints(Flags::Horizontal).contains(axis)) { if (not getUConstraints(Flags::Horizontal).contains(axis)) {
cdebug_log(145,0) << "Cached: " << _segment << endl; cdebug_log(145,0) << "Cached: " << _segment << endl;
message << "Terminal vertical segment X " << DbU::getValueString(axis) message << "Terminal vertical segment X" << DbU::getValueString(axis)
<< " axis is outside RoutingPad " << getUConstraints(Flags::Horizontal) << "."; << " axis is outside RoutingPad " << getUConstraints(Flags::Horizontal) << ".";
Flags flags = Flags::NoFlags; Flags flags = Flags::NoFlags;
@ -537,7 +416,7 @@ namespace Anabatic {
void AutoContactTerminal::updateTopology () void AutoContactTerminal::updateTopology ()
{ {
DebugSession::open( getNet(), 145, 150 ); DebugSession::open( getNet(), 140, 150 );
cdebug_log(145,1) << _getTypeName() << "::updateTopology() " << this << endl; cdebug_log(145,1) << _getTypeName() << "::updateTopology() " << this << endl;
@ -562,11 +441,11 @@ namespace Anabatic {
if (delta > 1) { if (delta > 1) {
//_segment = _segment->makeDogleg( this ); //_segment = _segment->makeDogleg( this );
_segment->makeDogleg( this ); _segment->makeDogleg( this );
cdebug_log(145,0) << "Update seg: " << _segment << endl;
delta = abssub( anchorDepth, rg->getLayerDepth( _segment->getLayer() ) ); delta = abssub( anchorDepth, rg->getLayerDepth( _segment->getLayer() ) );
cdebug_log(145,0) << "Delta: " << delta << " Update seg: " << _segment << endl;
} }
if (delta == 0) setLayerAndWidth( delta, anchorDepth ); else if (delta == 0) setLayer( rg->getRoutingLayer(anchorDepth) );
if (delta == 1) setLayerAndWidth( delta, std::min(anchorDepth,segmentDepth) ); else if (delta == 1) setLayer( rg->getContactLayer(std::min(anchorDepth,segmentDepth)) );
} }
_segment->invalidate( this ); _segment->invalidate( this );

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2012-2018, All Rights Reserved // Copyright (c) UPMC 2012-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -88,17 +88,8 @@ namespace Anabatic {
AutoSegment* AutoContactTurn::getPerpandicular ( const AutoSegment* reference ) const 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 == _horizontal1) return _vertical1;
if (reference == _vertical1 ) return _horizontal1; if (reference == _vertical1 ) return _horizontal1;
cdebug_log(149,0) << _getTypeName() << "::getPerpandicular() " << this
<< " to:" << reference << " failed." << endl;
return NULL; return NULL;
} }
@ -119,16 +110,13 @@ namespace Anabatic {
void AutoContactTurn::_invalidate ( Flags flags ) void AutoContactTurn::_invalidate ( Flags flags )
{ {
if (_horizontal1) _horizontal1->invalidate( flags|Flags::Propagate ); if (_horizontal1) _horizontal1->invalidate();
if (_vertical1 ) _vertical1 ->invalidate( flags|Flags::Propagate ); if (_vertical1 ) _vertical1 ->invalidate();
} }
void AutoContactTurn::cacheDetach ( AutoSegment* segment ) void AutoContactTurn::cacheDetach ( AutoSegment* segment )
{ {
cdebug_log(149,0) << _getTypeName() << "::cacheDetach() " << this
<< " from:" << segment << endl;
if (segment == _horizontal1) _horizontal1 = NULL; if (segment == _horizontal1) _horizontal1 = NULL;
else if (segment == _vertical1) _vertical1 = NULL; else if (segment == _vertical1) _vertical1 = NULL;
else return; else return;
@ -139,9 +127,6 @@ namespace Anabatic {
void AutoContactTurn::cacheAttach ( AutoSegment* segment ) void AutoContactTurn::cacheAttach ( AutoSegment* segment )
{ {
cdebug_log(149,0) << _getTypeName() << "::cacheAttach() " << this
<< " to:" << segment << endl;
if (segment->getDirection() == Flags::Horizontal) { if (segment->getDirection() == Flags::Horizontal) {
if (_horizontal1) { if (_horizontal1) {
cerr << Bug( "%s::cacheAttach() On %s,\n" cerr << Bug( "%s::cacheAttach() On %s,\n"
@ -169,7 +154,7 @@ namespace Anabatic {
void AutoContactTurn::updateCache () void AutoContactTurn::updateCache ()
{ {
DebugSession::open( getNet(), 145, 150 ); DebugSession::open( getNet(), 140, 150 );
cdebug_log(145,1) << _getTypeName() << "::updateCache() " << this << endl; cdebug_log(145,1) << _getTypeName() << "::updateCache() " << this << endl;
@ -210,7 +195,7 @@ namespace Anabatic {
void AutoContactTurn::updateGeometry () void AutoContactTurn::updateGeometry ()
{ {
DebugSession::open( getNet(), 145, 150 ); DebugSession::open( getNet(), 140, 150 );
cdebug_log(145,1) << _getTypeName() << "::updateGeometry() " << this << endl; cdebug_log(145,1) << _getTypeName() << "::updateGeometry() " << this << endl;
@ -238,7 +223,7 @@ namespace Anabatic {
void AutoContactTurn::updateTopology () void AutoContactTurn::updateTopology ()
{ {
DebugSession::open ( getNet(), 145, 150 ); DebugSession::open ( getNet(), 140, 150 );
cdebug_log(145,1) << _getTypeName() << "::updateTopology() " << this << endl; cdebug_log(145,1) << _getTypeName() << "::updateTopology() " << this << endl;
@ -254,7 +239,7 @@ namespace Anabatic {
RoutingGauge* rg = Session::getRoutingGauge(); RoutingGauge* rg = Session::getRoutingGauge();
size_t depthH1 = rg->getLayerDepth( getHorizontal1()->getLayer() ); size_t depthH1 = rg->getLayerDepth( getHorizontal1()->getLayer() );
size_t depthV1 = rg->getLayerDepth( getVertical1 ()->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 ); size_t delta = abssub ( depthH1, depthV1 );
unsetFlags( CntWeakTerminal ); unsetFlags( CntWeakTerminal );
@ -262,25 +247,22 @@ namespace Anabatic {
showTopologyError( "Sheared Turn, layer delta exceed 3." ); showTopologyError( "Sheared Turn, layer delta exceed 3." );
setFlags( CntBadTopology ); setFlags( CntBadTopology );
} else { } else {
if (delta > 1) { if (delta == 3) {
bool updateH1 = (_horizontal1->isInvalidatedLayer() and not _horizontal1->isNonPref()) if (_horizontal1->isInvalidatedLayer()) {
or _vertical1->isNonPref();
if (updateH1) {
//_horizontal1 = static_cast<AutoHorizontal*>( _horizontal1->makeDogleg(this) ); //_horizontal1 = static_cast<AutoHorizontal*>( _horizontal1->makeDogleg(this) );
_horizontal1->makeDogleg(this); _horizontal1->makeDogleg(this);
depthH1 = rg->getLayerDepth( _horizontal1->getLayer() );
cdebug_log(145,0) << "Update h1: " << _horizontal1 << endl; cdebug_log(145,0) << "Update h1: " << _horizontal1 << endl;
} else /*if (_vertical1->isInvalidatedLayer())*/ { } else /*if (_vertical1->isInvalidatedLayer())*/ {
//_vertical1 = static_cast<AutoVertical*>( _vertical1->makeDogleg(this) ); //_vertical1 = static_cast<AutoVertical*>( _vertical1->makeDogleg(this) );
_vertical1->makeDogleg(this); _vertical1->makeDogleg(this);
depthV1 = rg->getLayerDepth( _vertical1->getLayer() );
cdebug_log(145,0) << "Update v1: " << _vertical1 << endl; cdebug_log(145,0) << "Update v1: " << _vertical1 << endl;
} }
depthH1 = rg->getLayerDepth( _horizontal1->getLayer() ); delta = abssub ( depthH1, depthV1 );
depthV1 = rg->getLayerDepth( _vertical1->getLayer() );
depthContact = (depthH1 <= depthV1) ? depthH1 : depthH1-1;
delta = abssub ( depthH1, depthV1 );
} }
setLayerAndWidth( delta, depthContact ); setLayer ( (delta == 0) ? rg->getRoutingLayer(depthContact) : rg->getContactLayer(depthContact) );
} }
_horizontal1->invalidate( this ); _horizontal1->invalidate( this );

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2012-2018, All Rights Reserved // Copyright (c) UPMC 2012-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -91,11 +91,8 @@ namespace Anabatic {
} }
AutoSegment* AutoContactVTee::getPerpandicular ( const AutoSegment* from ) const AutoSegment* AutoContactVTee::getPerpandicular ( const AutoSegment* ) const
{ { return NULL; }
if ( (from == _vertical1) or (from == _vertical2) ) return _horizontal1;
return NULL;
}
AutoSegment* AutoContactVTee::getSegment ( unsigned int index ) const AutoSegment* AutoContactVTee::getSegment ( unsigned int index ) const
@ -114,12 +111,12 @@ namespace Anabatic {
AutoVertical* AutoContactVTee::getVertical2 () const { return _vertical2; }; AutoVertical* AutoContactVTee::getVertical2 () const { return _vertical2; };
void AutoContactVTee::_invalidate ( Flags flags ) void AutoContactVTee::_invalidate ( Flags )
{ {
flags |= Flags::Propagate; Flags flags = Flags::Propagate;
if (_vertical1 and _vertical2) { if (_vertical1 and _vertical2) {
if (_vertical1->isInvalidated() xor _vertical2->isInvalidated()) if (_vertical1->isInvalidated() xor _vertical2->isInvalidated())
flags.reset( Flags::NoFlags ); flags = Flags::NoFlags;
} }
if (_vertical1 ) _vertical1 ->invalidate( flags ); if (_vertical1 ) _vertical1 ->invalidate( flags );
@ -169,7 +166,7 @@ namespace Anabatic {
void AutoContactVTee::updateCache () void AutoContactVTee::updateCache ()
{ {
DebugSession::open( getNet(), 145, 150 ); DebugSession::open( getNet(), 140, 150 );
cdebug_log(145,1) << "AutoContactVTee::updateCache() " << this << endl; cdebug_log(145,1) << "AutoContactVTee::updateCache() " << this << endl;
@ -215,7 +212,7 @@ namespace Anabatic {
void AutoContactVTee::updateGeometry () void AutoContactVTee::updateGeometry ()
{ {
DebugSession::open( getNet(), 145, 150 ); DebugSession::open( getNet(), 140, 150 );
cdebug_log(145,1) << "AutoContactVTee::updateGeometry() " << this << endl; cdebug_log(145,1) << "AutoContactVTee::updateGeometry() " << this << endl;
@ -243,7 +240,7 @@ namespace Anabatic {
void AutoContactVTee::updateTopology () void AutoContactVTee::updateTopology ()
{ {
DebugSession::open ( getNet(), 145, 150 ); DebugSession::open ( getNet(), 140, 150 );
cdebug_log(145,1) << "AutoContactVTee::updateTopology() " << this << endl; cdebug_log(145,1) << "AutoContactVTee::updateTopology() " << this << endl;
@ -278,11 +275,11 @@ namespace Anabatic {
cdebug_log(145,0) << "depthV1 == depthV2 (" << depthV1 << ")" << endl; cdebug_log(145,0) << "depthV1 == depthV2 (" << depthV1 << ")" << endl;
// Dogleg on the horizontal. // Dogleg on the horizontal.
switch ( delta ) { switch ( delta ) {
case 0: case 0: setLayer( rg->getRoutingLayer(minDepth) ); break;
case 1: setLayerAndWidth( delta, minDepth ); break; case 1: setLayer( rg->getContactLayer(minDepth) ); break;
default: default:
cdebug_log(145,0) << "Restore connectivity: dogleg on h1." << endl; cdebug_log(145,0) << "Restore connectivity: dogleg on h1." << endl;
setLayerAndWidth( delta, depthV1 + ((depthV1==minDepth)?0:-1) ); setLayer( rg->getContactLayer( depthV1 + ((depthV1==minDepth)?0:-1) ) );
_horizontal1 = static_cast<AutoHorizontal*>( _horizontal1->makeDogleg(this) ); _horizontal1 = static_cast<AutoHorizontal*>( _horizontal1->makeDogleg(this) );
break; break;
} }
@ -292,11 +289,11 @@ namespace Anabatic {
int deltaV2 = (int)depthV2 - (int)depthH1; int deltaV2 = (int)depthV2 - (int)depthH1;
if (std::abs(deltaV1) > std::abs(deltaV2)) { if (std::abs(deltaV1) > std::abs(deltaV2)) {
setLayerAndWidth( 2, depthV2 + ((depthV2<depthH1)?0:-1) ); setLayer( rg->getContactLayer( depthV2 + ((depthV2<depthH1)?0:-1) ) );
//_vertical1 = static_cast<AutoVertical*>( _vertical1->makeDogleg(this) ); //_vertical1 = static_cast<AutoVertical*>( _vertical1->makeDogleg(this) );
_vertical1->makeDogleg(this); _vertical1->makeDogleg(this);
} else { } else {
setLayerAndWidth( 2, depthV1 + ((depthV1<depthH1)?0:-1) ); setLayer( rg->getContactLayer( depthV1 + ((depthV1<depthH1)?0:-1) ) );
//_vertical2 = static_cast<AutoVertical*>( _vertical2->makeDogleg(this) ); //_vertical2 = static_cast<AutoVertical*>( _vertical2->makeDogleg(this) );
_vertical2->makeDogleg(this); _vertical2->makeDogleg(this);
} }

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2018, All Rights Reserved // Copyright (c) UPMC 2008-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -14,19 +14,17 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#include <algorithm> #include <algorithm>
#include "hurricane/Bug.h" #include "hurricane/Bug.h"
#include "hurricane/Error.h" #include "hurricane/Error.h"
#include "hurricane/Warning.h" #include "hurricane/DebugSession.h"
#include "hurricane/DebugSession.h" #include "hurricane/RoutingPad.h"
#include "hurricane/ViaLayer.h" #include "crlcore/RoutingGauge.h"
#include "hurricane/RoutingPad.h" #include "anabatic/Configuration.h"
#include "crlcore/RoutingGauge.h" #include "anabatic/AutoContactTerminal.h"
#include "anabatic/Configuration.h" #include "anabatic/AutoContactTurn.h"
#include "anabatic/AutoContactTerminal.h" #include "anabatic/AutoHorizontal.h"
#include "anabatic/AutoContactTurn.h" #include "anabatic/AutoVertical.h"
#include "anabatic/AutoHorizontal.h"
#include "anabatic/AutoVertical.h"
namespace Anabatic { namespace Anabatic {
@ -34,12 +32,9 @@ namespace Anabatic {
using std::min; using std::min;
using std::max; using std::max;
using std::abs;
using Hurricane::Bug;
using Hurricane::Error; using Hurricane::Error;
using Hurricane::Warning; using Hurricane::Bug;
using Hurricane::DebugSession; using Hurricane::DebugSession;
using Hurricane::ViaLayer;
using Hurricane::RoutingPad; using Hurricane::RoutingPad;
@ -50,11 +45,13 @@ namespace Anabatic {
Segment* AutoHorizontal::base () { return _horizontal; } Segment* AutoHorizontal::base () { return _horizontal; }
Segment* AutoHorizontal::base () const { return _horizontal; } Segment* AutoHorizontal::base () const { return _horizontal; }
Horizontal* AutoHorizontal::getHorizontal () { return _horizontal; } Horizontal* AutoHorizontal::getHorizontal () { return _horizontal; }
DbU::Unit AutoHorizontal::getSourceU () const { return _horizontal->getSource()->getX(); } DbU::Unit AutoHorizontal::getSourceU () const { return _horizontal->getSourceX(); }
DbU::Unit AutoHorizontal::getTargetU () const { return _horizontal->getTarget()->getX(); } DbU::Unit AutoHorizontal::getTargetU () const { return _horizontal->getTargetX(); }
DbU::Unit AutoHorizontal::getDuSource () const { return _horizontal->getDxSource(); } DbU::Unit AutoHorizontal::getDuSource () const { return _horizontal->getDxSource(); }
DbU::Unit AutoHorizontal::getDuTarget () const { return _horizontal->getDxTarget(); } DbU::Unit AutoHorizontal::getDuTarget () const { return _horizontal->getDxTarget(); }
Interval AutoHorizontal::getSpanU () const { return Interval(_horizontal->getSourceX(),_horizontal->getTargetX()); } 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"; } string AutoHorizontal::_getTypeName () const { return "AutoHorizontal"; }
@ -94,14 +91,6 @@ namespace Anabatic {
mergeNativeMax( gcell->getConstraintYMax() ); 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 +120,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 Interval AutoHorizontal::getSourceConstraints ( Flags flags ) const
{ {
if (flags & Flags::NativeConstraints) { if (flags & Flags::NativeConstraints) {
@ -177,58 +142,33 @@ namespace Anabatic {
bool AutoHorizontal::getConstraints ( DbU::Unit& constraintMin, DbU::Unit& constraintMax ) const bool AutoHorizontal::getConstraints ( DbU::Unit& constraintMin, DbU::Unit& constraintMax ) const
{ {
cdebug_log(155,1) << "getConstraints() " << this << endl;
constraintMin = getNativeMin(); constraintMin = getNativeMin();
constraintMax = getNativeMax(); constraintMax = getNativeMax();
cdebug_log(155,0) << "Native constraints: [" cdebug_log(144,0) << "Native constraints: ["
<< DbU::getValueString(constraintMin) << ":" << DbU::getValueString(constraintMin) << ":"
<< DbU::getValueString(constraintMax) << "]" << DbU::getValueString(constraintMax) << "]"
<< endl; << endl;
constraintMin = std::max ( constraintMin, getAutoSource()->getCBYMin() ); constraintMin = std::max ( constraintMin, getAutoSource()->getCBYMin() );
constraintMax = std::min ( constraintMax, getAutoSource()->getCBYMax() ); constraintMax = std::min ( constraintMax, getAutoSource()->getCBYMax() );
cdebug_log(155,0) << "Merge with source constraints: [" cdebug_log(144,0) << "Merge with source constraints: ["
<< DbU::getValueString(getAutoSource()->getCBYMin()) << ":" << DbU::getValueString(getAutoSource()->getCBYMin()) << ":"
<< DbU::getValueString(getAutoSource()->getCBYMax()) << "]" << DbU::getValueString(getAutoSource()->getCBYMax()) << "]"
<< endl; << endl;
constraintMin = std::max ( constraintMin, getAutoTarget()->getCBYMin() ); constraintMin = std::max ( constraintMin, getUserConstraints().getVMin() );
constraintMax = std::min ( constraintMax, getAutoTarget()->getCBYMax() ); constraintMax = std::min ( constraintMax, getUserConstraints().getVMax() );
cdebug_log(155,0) << "Merge with target constraints: [" cdebug_log(144,0) << "Merge with user constraints: ["
<< DbU::getValueString(getAutoTarget()->getCBYMin()) << ":" << DbU::getValueString(getUserConstraints().getVMin()) << ":"
<< DbU::getValueString(getAutoTarget()->getCBYMax()) << "]" << DbU::getValueString(getUserConstraints().getVMax()) << "]"
<< endl; << endl;
Interval userConstraints = getUserConstraints(); cdebug_log(145,0) << "Resulting constraints: " << " ["
if (not userConstraints.isEmpty()) {
constraintMin = std::max ( constraintMin, userConstraints.getVMin() );
constraintMax = std::min ( constraintMax, userConstraints.getVMax() );
cdebug_log(155,0) << "Merge with user constraints: ["
<< DbU::getValueString(userConstraints.getVMin()) << ":"
<< DbU::getValueString(userConstraints.getVMax()) << "]"
<< endl;
} else
cdebug_log(155,0) << "Empty user constraints" << endl;
cdebug_log(155,0) << "Resulting constraints: ["
<< DbU::getValueString(constraintMin) << ":" << DbU::getValueString(constraintMin) << ":"
<< DbU::getValueString(constraintMax) << "]" << DbU::getValueString(constraintMax) << "]"
<< endl; << endl;
if (constraintMin > constraintMax)
cerr << Error( "AutoHorizontal::getConstraints(): Invalid interval [%s : %s] -> [%d : %d]\n"
" on %s"
, DbU::getValueString(constraintMin).c_str()
, DbU::getValueString(constraintMax).c_str()
, constraintMin
, constraintMax
, getString(this).c_str()
) << endl;
cdebug_tabw(155,-1);
return true; return true;
} }
@ -237,14 +177,13 @@ namespace Anabatic {
{ return Flags::Horizontal; } { return Flags::Horizontal; }
bool AutoHorizontal::getGCells ( vector<GCell*>& gcells ) const size_t AutoHorizontal::getGCells ( vector<GCell*>& gcells ) const
{ {
vector<GCell*>().swap( gcells ); vector<GCell*>().swap( gcells );
bool success = true; DbU::Unit yprobe = getY();
DbU::Unit yprobe = getY(); GCell* gcell = getAutoSource()->getGCell();
GCell* gcell = getAutoSource()->getGCell(); GCell* end = getAutoTarget()->getGCell();
GCell* end = getAutoTarget()->getGCell();
cdebug_log(144,0) << "yprobe: " << DbU::getValueString(yprobe) << endl; cdebug_log(144,0) << "yprobe: " << DbU::getValueString(yprobe) << endl;
@ -256,23 +195,20 @@ namespace Anabatic {
while ( gcell != end ) { while ( gcell != end ) {
gcell = gcell->getEast( yprobe ); gcell = gcell->getEast( yprobe );
if (not gcell) { if (not gcell) {
success = false; cerr << Error( "AutoHorizontal::getGCells() : NULL GCell under %s\n"
if (not isCreated()) { " begin:%s\n"
cerr << Error( "AutoHorizontal::getGCells() : NULL GCell under %s\n" " end: %s"
" begin:%s\n" , getString(this).c_str()
" end: %s" , getString(getAutoSource()->getGCell()).c_str()
, getString(this).c_str() , getString(getAutoTarget()->getGCell()).c_str()
, getString(getAutoSource()->getGCell()).c_str() ) << endl;
, getString(getAutoTarget()->getGCell()).c_str()
) << endl;
}
break; break;
} }
gcells.push_back( gcell ); gcells.push_back( gcell );
} }
return success; return gcells.size();
} }
@ -280,35 +216,24 @@ namespace Anabatic {
{ {
cdebug_tabw(149,1); cdebug_tabw(149,1);
AutoContact* source = getAutoSource(); Interval sourceSide = getAutoSource()->getGCell()->getSide( Flags::Vertical );
AutoContact* target = getAutoTarget(); Interval targetSide = getAutoTarget()->getGCell()->getSide( Flags::Vertical );
if (source->isOnPin() or target->isOnPin()) { cdebug_tabw(149,-1); return false; } Interval sourceConstraints = Interval(getAutoSource()->getCBYMin(),getAutoSource()->getCBYMax());
Interval targetConstraints = Interval(getAutoTarget()->getCBYMin(),getAutoTarget()->getCBYMax());
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();
// Expand by a tiny amount for the "contains" to work for sure. // Expand by a tiny amount for the "contains" to work for sure.
sourceConstraints.inflate( 1 ); sourceConstraints.inflate( 1 );
targetConstraints.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 cdebug_log(149,0) << "source constraints: " << sourceConstraints
<< " " << DbU::getValueString(sourceConstraints.getSize()) << endl; << " " << 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 cdebug_log(149,0) << "target constraints: " << targetConstraints
<< " " << DbU::getValueString(targetConstraints.getSize()) << endl; << " " << DbU::getValueString(targetConstraints.getSize()) << endl;
if (not sourceGoStraight and not sourceConstraints.contains(sourceSide)) { cdebug_tabw(149,-1); return true; } if (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 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; }
}
cdebug_tabw(149,-1); cdebug_tabw(149,-1);
return false; return false;
@ -324,52 +249,30 @@ namespace Anabatic {
const Configuration* configuration = Session::getConfiguration(); const Configuration* configuration = Session::getConfiguration();
const Layer* metal2 = configuration->getRoutingLayer( 1 ); const Layer* metal2 = configuration->getRoutingLayer( 1 );
bool success = false; bool success = false;
bool isMetal2Source = false; bool isMetal2Source = false;
bool isMetal2Target = false; bool isMetal2Target = false;
bool isNonPrefSource = false; DbU::Unit height = 0;
bool isNonPrefTarget = false; AutoContact* source = getAutoSource();
DbU::Unit height = 0; AutoContact* target = getAutoTarget();
AutoContact* source = getAutoSource();
AutoContact* target = getAutoTarget();
bool slackenSource = false;
bool slackenTarget = false;
if (source->isTerminal()) { if (source->isTerminal()) {
height = (static_cast<RoutingPad*>(source->getAnchor()))->getBoundingBox().getHeight(); height = (static_cast<RoutingPad*>(source->getAnchor()))->getBoundingBox().getHeight();
isMetal2Source = (source->getLayer() == metal2); isMetal2Source = (source->getLayer() == metal2);
slackenSource = true;
} }
if (target->isTerminal()) { if (target->isTerminal()) {
height = std::min( height, (static_cast<RoutingPad*>(target->getAnchor()))->getBoundingBox().getHeight() ); height = std::min( height, (static_cast<RoutingPad*>(target->getAnchor()))->getBoundingBox().getHeight() );
isMetal2Target = (target->getLayer() == metal2); 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; if (height >= 4*getPitch()) {
cdebug_log(149,0) << "target->getPerpandicular(this):" << target->getPerpandicular(this) << endl; if (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < 5*getPitch()))
if (target->isTurn() and (target->getPerpandicular(this)->getLayer() == getLayer())) { return false;
isNonPrefTarget = true;
slackenTarget = true;
} }
cdebug_tabw(149,1); cdebug_tabw(149,1);
cdebug_log(149,0) << "_flags:" << (_flags & (SegGlobal|SegWeakGlobal)) << endl; cdebug_log(149,0) << "_flags:" << (_flags & (SegGlobal|SegWeakGlobal)) << endl;
cdebug_log(149,0) << "test:" << (getAnchoredLength() < 5*getPitch()) << endl; cdebug_log(149,0) << "test:" << (getLength() < 5*getPitch()) << endl;
cdebug_log(149,0) << "length:" << DbU::getValueString(getAnchoredLength()) << endl; cdebug_log(149,0) << "length:" << DbU::getValueString(getLength()) << 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;
}
}
int lowSlack = (flags & Flags::HalfSlacken) ? 3 : 10; int lowSlack = (flags & Flags::HalfSlacken) ? 3 : 10;
bool sourceSlackened = false; bool sourceSlackened = false;
@ -378,7 +281,7 @@ namespace Anabatic {
DbU::Unit targetPosition = getTargetPosition(); DbU::Unit targetPosition = getTargetPosition();
AutoSegment* parallel = this; AutoSegment* parallel = this;
if (slackenSource) { if (source->isTerminal()) {
Interval perpandConstraints = getAutoTarget()->getUConstraints(Flags::Horizontal); Interval perpandConstraints = getAutoTarget()->getUConstraints(Flags::Horizontal);
Interval constraints = source->getUConstraints (Flags::Vertical|Flags::NoGCellShrink); Interval constraints = source->getUConstraints (Flags::Vertical|Flags::NoGCellShrink);
Interval nativeConstraints = source->getNativeUConstraints(Flags::Vertical|Flags::NoGCellShrink); Interval nativeConstraints = source->getNativeUConstraints(Flags::Vertical|Flags::NoGCellShrink);
@ -390,7 +293,7 @@ namespace Anabatic {
<< " native slack:" << nativeSlack << endl; << " native slack:" << nativeSlack << endl;
cdebug_log(149,0) << "Perpand constraints on target: " << perpandConstraints << endl; cdebug_log(149,0) << "Perpand constraints on target: " << perpandConstraints << endl;
// Ugly: GCell's track number is hardwired. // 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; cdebug_log(149,0) << "Slackening from Source: " << source << endl;
_makeDogleg( source->getGCell(), Flags::NoFlags ); _makeDogleg( source->getGCell(), Flags::NoFlags );
sourceSlackened = true; sourceSlackened = true;
@ -400,7 +303,7 @@ namespace Anabatic {
const vector<AutoSegment*>& doglegs = Session::getDoglegs(); const vector<AutoSegment*>& doglegs = Session::getDoglegs();
if (sourceSlackened and (doglegs.size() >= 2)) { if (sourceSlackened and (doglegs.size() >= 2)) {
cdebug_log(149,0) << "Slackened from source @" << DbU::getValueString(getSourcePosition()) << endl; cdebug_log(149,0) << "AutoHorizontal::_slacken(): Source @" << DbU::getValueString(getSourcePosition()) << endl;
doglegs[doglegs.size()-2]->setAxis( getSourcePosition() ); doglegs[doglegs.size()-2]->setAxis( getSourcePosition() );
success = true; success = true;
@ -418,7 +321,7 @@ namespace Anabatic {
if (parallel) target = parallel->getAutoTarget(); if (parallel) target = parallel->getAutoTarget();
if (slackenTarget) { if (target->isTerminal()) {
Interval constraints = target->getUConstraints (Flags::Vertical|Flags::NoGCellShrink); Interval constraints = target->getUConstraints (Flags::Vertical|Flags::NoGCellShrink);
Interval nativeConstraints = target->getNativeUConstraints(Flags::Vertical|Flags::NoGCellShrink); Interval nativeConstraints = target->getNativeUConstraints(Flags::Vertical|Flags::NoGCellShrink);
int slack = constraints.getSize() / getPitch(); int slack = constraints.getSize() / getPitch();
@ -428,7 +331,7 @@ namespace Anabatic {
cdebug_log(149,0) << "Target constraint: " << constraints cdebug_log(149,0) << "Target constraint: " << constraints
<< " slack:" << slack << " slack:" << slack
<< " native slack:" << nativeSlack << endl; << " 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; cdebug_log(149,0) << "Slackening from Target: " << target << endl;
parallel->_makeDogleg( target->getGCell(), Flags::NoFlags ); parallel->_makeDogleg( target->getGCell(), Flags::NoFlags );
targetSlackened = true; targetSlackened = true;
@ -438,15 +341,7 @@ namespace Anabatic {
const vector<AutoSegment*>& doglegs = Session::getDoglegs(); const vector<AutoSegment*>& doglegs = Session::getDoglegs();
if (targetSlackened and (doglegs.size() >= 2)) { if (targetSlackened and (doglegs.size() >= 2)) {
GCell* targetGCell = target->getGCell(); cdebug_log(149,0) << "AutoHorizontal::_slacken(): Target @" << DbU::getValueString(targetPosition) << endl;
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 );
}
doglegs[doglegs.size()-2]->setAxis( targetPosition ); doglegs[doglegs.size()-2]->setAxis( targetPosition );
success = true; success = true;
@ -454,7 +349,7 @@ namespace Anabatic {
cdebug_log(149,0) << "Fixing on target terminal contact: " cdebug_log(149,0) << "Fixing on target terminal contact: "
<< doglegs[doglegs.size()-2]->getAutoTarget() << endl; << doglegs[doglegs.size()-2]->getAutoTarget() << endl;
//doglegs[doglegs.size()-2]->getAutoTarget()->setFlags( CntFixed ); //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 ); doglegs[doglegs.size()-2]->getAutoTarget()->setFlags( CntUserNativeConstraints );
} }
} }
@ -511,10 +406,9 @@ namespace Anabatic {
void AutoHorizontal::updateOrient () void AutoHorizontal::updateOrient ()
{ {
if (_horizontal->getTarget()->getX() < _horizontal->getSource()->getX()) { if (_horizontal->getTargetX() < _horizontal->getSourceX()) {
cdebug_log(149,1) << "updateOrient() " << this << " (before S/T swap)" << endl; cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl;
_horizontal->invert(); _horizontal->invert();
cdebug_log(149,0) << "updateOrient() " << this << " (after S/T swap)" << endl;
uint64_t spinFlags = _flags & SegDepthSpin; uint64_t spinFlags = _flags & SegDepthSpin;
unsetFlags( SegDepthSpin ); unsetFlags( SegDepthSpin );
@ -532,15 +426,14 @@ namespace Anabatic {
unsetFlags( SegStrongTerminal ); unsetFlags( SegStrongTerminal );
if (terminalFlags & SegSourceTerminal) setFlags( SegTargetTerminal ); if (terminalFlags & SegSourceTerminal) setFlags( SegTargetTerminal );
if (terminalFlags & SegTargetTerminal) setFlags( SegSourceTerminal ); if (terminalFlags & SegTargetTerminal) setFlags( SegSourceTerminal );
cdebug_tabw(149,-1);
} }
} }
void AutoHorizontal::updatePositions () void AutoHorizontal::updatePositions ()
{ {
_sourcePosition = getSourceU() - getExtensionCap(Flags::Source); _sourcePosition = _horizontal->getSourceX() - getExtensionCap();
_targetPosition = getTargetU() + getExtensionCap(Flags::Target); _targetPosition = _horizontal->getTargetX() + getExtensionCap();
} }
@ -560,13 +453,10 @@ namespace Anabatic {
bool AutoHorizontal::checkPositions () const bool AutoHorizontal::checkPositions () const
{ {
bool coherency = true; bool coherency = true;
DbU::Unit sourcePosition = _horizontal->getSource()->getX() - getExtensionCap(Flags::Source); DbU::Unit sourcePosition = _horizontal->getSourceX() - getExtensionCap();
DbU::Unit targetPosition = _horizontal->getTarget()->getX() + getExtensionCap(Flags::Target); DbU::Unit targetPosition = _horizontal->getTargetX() + getExtensionCap();
if ( _sourcePosition != sourcePosition ) { if ( _sourcePosition != sourcePosition ) {
cerr << "extensionCap: " << DbU::getValueString(getExtensionCap(Flags::Source)) << endl;
cerr << "ppitch: " << DbU::getValueString(getPPitch()) << endl;
cerr << "via width: " << DbU::getValueString(Session::getViaWidth(getLayer())) << endl;
cerr << Error ( "%s\n Source position incoherency: " cerr << Error ( "%s\n Source position incoherency: "
"shadow: %s, real: %s." "shadow: %s, real: %s."
, _getString().c_str() , _getString().c_str()
@ -840,18 +730,16 @@ namespace Anabatic {
Flags AutoHorizontal::_makeDogleg ( GCell* doglegGCell, Flags flags ) Flags AutoHorizontal::_makeDogleg ( GCell* doglegGCell, Flags flags )
{ {
DebugSession::open( getNet(), 145, 150 ); DebugSession::open( getNet(), 140, 150 );
cdebug_log(149,0) << "AutoHorizontal::_makeDogleg(GCell*) in " << doglegGCell << endl; cdebug_log(149,0) << "AutoHorizontal::_makeDogleg(GCell*) in " << doglegGCell << endl;
cdebug_tabw(149,1); cdebug_tabw(149,1);
//Session::doglegReset(); //Session::doglegReset();
AutoContact* autoTarget = getAutoTarget(); AutoContact* autoTarget = getAutoTarget();
AutoContact* autoSource = getAutoSource(); AutoContact* autoSource = getAutoSource();
GCell* begin = autoSource->getGCell(); GCell* begin = autoSource->getGCell();
GCell* end = autoTarget->getGCell(); GCell* end = autoTarget->getGCell();
if (not autoSource->canDrag()) unsetFlags( SegDrag );
DbU::Unit doglegAxis = (doglegGCell->getXMax() + doglegGCell->getXMin()) / 2; DbU::Unit doglegAxis = (doglegGCell->getXMax() + doglegGCell->getXMin()) / 2;
if (isLocal()) if (isLocal())
@ -871,19 +759,10 @@ namespace Anabatic {
} while ( gcell and (gcell != end) ); } while ( gcell and (gcell != end) );
} }
size_t depth = Session::getRoutingGauge()->getLayerDepth( _horizontal->getLayer() ); size_t depth = Session::getRoutingGauge()->getLayerDepth( _horizontal->getLayer() );
bool upLayer = true; bool upLayer = (depth+1 <= Session::getConfiguration()->getAllowedDepth());
Layer* contactLayer = Session::getRoutingGauge()->getContactLayer( depth + ((upLayer)?0:-1) );
if (Session::getRoutingGauge()->isTwoMetals()) { const Layer* doglegLayer = Session::getRoutingGauge()->getRoutingLayer( depth + ((upLayer)?1:-1) );
upLayer = (not Session::getRoutingGauge()->isVH());
} 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) );
Session::dogleg( this ); Session::dogleg( this );
targetDetach(); targetDetach();
@ -892,7 +771,7 @@ namespace Anabatic {
AutoContact* dlContact1 = AutoContactTurn::create( doglegGCell, _horizontal->getNet(), contactLayer ); AutoContact* dlContact1 = AutoContactTurn::create( doglegGCell, _horizontal->getNet(), contactLayer );
AutoContact* dlContact2 = AutoContactTurn::create( doglegGCell, _horizontal->getNet(), contactLayer ); AutoContact* dlContact2 = AutoContactTurn::create( doglegGCell, _horizontal->getNet(), contactLayer );
AutoSegment* segment1 = AutoSegment::create( dlContact1 , dlContact2, Flags::Vertical ); AutoSegment* segment1 = AutoSegment::create( dlContact1 , dlContact2, Flags::Vertical );
segment1->setLayer( doglegDepth ); segment1->setLayer( doglegLayer );
segment1->_setAxis( doglegAxis ); segment1->_setAxis( doglegAxis );
segment1->setFlags( SegDogleg|SegSlackened|SegCanonical|SegNotAligned ); segment1->setFlags( SegDogleg|SegSlackened|SegCanonical|SegNotAligned );
@ -903,61 +782,36 @@ namespace Anabatic {
targetAttach( dlContact1 ); targetAttach( dlContact1 );
AutoSegment* segment2 = AutoSegment::create( dlContact2 , autoTarget, Flags::Horizontal ); AutoSegment* segment2 = AutoSegment::create( dlContact2 , autoTarget, Flags::Horizontal );
autoTarget->cacheAttach( segment2 ); autoTarget->cacheAttach( segment2 );
segment2->setLayer( depth ); segment2->setLayer( getLayer() );
segment2->_setAxis( getY() ); segment2->_setAxis( getY() );
segment2->setFlags( (isSlackened()?SegSlackened:0) ); segment2->setFlags( (isSlackened()?SegSlackened:0) );
Session::dogleg( segment2 ); Session::dogleg( segment2 );
if (autoSource->isTerminal() and autoTarget->isTerminal()) { if (autoSource->isTerminal()) {
dlContact1->setFlags ( CntWeakTerminal ); segment1->setFlags( SegWeakTerminal1 );
dlContact2->setFlags ( CntWeakTerminal ); segment2->setFlags( SegWeakTerminal1 );
if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget );
if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource );
} else if (autoSource->isTerminal()) {
autoTarget->unsetFlags( CntWeakTerminal ); autoTarget->unsetFlags( CntWeakTerminal );
dlContact1->setFlags ( CntWeakTerminal ); dlContact1->setFlags ( CntWeakTerminal );
if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget ); if (autoTarget->getGCell() == doglegGCell)
dlContact1->migrateConstraintBox( autoTarget );
} else if (autoTarget->isTerminal()) { } else if (autoTarget->isTerminal()) {
unsetFlags( SegTargetTerminal ); unsetFlags( SegTargetTerminal );
setFlags( SegWeakTerminal1 ); setFlags( SegWeakTerminal1 );
segment1->setFlags( SegWeakTerminal1 );
segment2->setFlags( SegTargetTerminal );
autoSource->unsetFlags( CntWeakTerminal ); autoSource->unsetFlags( CntWeakTerminal );
dlContact2->setFlags ( CntWeakTerminal ); dlContact2->setFlags ( CntWeakTerminal );
if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource ); if (autoSource->getGCell() == doglegGCell)
} else if (isWeakTerminal()) { dlContact2->migrateConstraintBox( autoSource );
} else if (isWeakTerminal()) {
segment1->setFlags( SegWeakTerminal1 ); segment1->setFlags( SegWeakTerminal1 );
segment2->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()) { if (isAnalog()) {
segment1->setFlags( SegAnalog ); segment1->setFlags( SegAnalog );
segment2->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+1] perpand: " << segment1 << endl;
cdebug_log(149,0) << "Session::dogleg[x+2] new paral: " << segment2 << endl; cdebug_log(149,0) << "Session::dogleg[x+2] new paral: " << segment2 << endl;
@ -973,18 +827,6 @@ namespace Anabatic {
updateNativeConstraints(); updateNativeConstraints();
segment2->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())) {
Interval dragConstraints = autoTarget->getNativeUConstraints(Flags::Horizontal);
segment1->mergeUserConstraints( dragConstraints );
cdebug_log(149,0) << "Perpandicular has drag constraints: " << dragConstraints << endl;
}
}
cdebug_tabw(149,-1); cdebug_tabw(149,-1);
DebugSession::close(); DebugSession::close();

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2018, All Rights Reserved // Copyright (c) UPMC 2008-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -93,12 +93,14 @@ namespace Anabatic {
bool AutoSegments_OnContact::Locator::isValid () const bool AutoSegments_OnContact::Locator::isValid () const
{ return _hook; } { return !_hook; }
void AutoSegments_OnContact::Locator::progress () void AutoSegments_OnContact::Locator::progress ()
{ {
while (_hook) { cdebug_log(145,0) << "AutoSegments_OnContact::Locator::progress()" << endl;
while (_hook and not _hook->isMaster()) {
_hook = _hook->getNextHook(); _hook = _hook->getNextHook();
_element = NULL; _element = NULL;
@ -106,6 +108,7 @@ namespace Anabatic {
Segment* segment = dynamic_cast<Segment*>( _hook->getComponent() ); Segment* segment = dynamic_cast<Segment*>( _hook->getComponent() );
if (segment) _element = Session::lookup( segment ); if (segment) _element = Session::lookup( segment );
if (not _element or (_element == _master)) continue; if (not _element or (_element == _master)) continue;
break; break;
@ -144,7 +147,7 @@ namespace Anabatic {
AutoSegments_OnRoutingPad::Locator::Locator ( RoutingPad* rp, const AutoContactTerminal* contact ) AutoSegments_OnRoutingPad::Locator::Locator ( RoutingPad* rp, const AutoContactTerminal* contact )
: AutoSegmentHL() : AutoSegmentHL()
, _elements ({{NULL,NULL,NULL,NULL}}) , _elements ({NULL,NULL,NULL,NULL})
, _index (0) , _index (0)
{ {
if (rp) { if (rp) {

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2018, All Rights Reserved // Copyright (c) UPMC 2008-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -16,8 +16,6 @@
#include <algorithm> #include <algorithm>
#include "hurricane/Bug.h" #include "hurricane/Bug.h"
#include "hurricane/Warning.h"
#include "hurricane/ViaLayer.h"
#include "hurricane/Vertical.h" #include "hurricane/Vertical.h"
#include "crlcore/RoutingGauge.h" #include "crlcore/RoutingGauge.h"
#include "anabatic/Configuration.h" #include "anabatic/Configuration.h"
@ -30,11 +28,8 @@ namespace Anabatic {
using std::min; using std::min;
using std::max; using std::max;
using std::abs;
using Hurricane::Bug;
using Hurricane::Error; using Hurricane::Error;
using Hurricane::Warning; using Hurricane::Bug;
using Hurricane::ViaLayer;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -44,11 +39,13 @@ namespace Anabatic {
Segment* AutoVertical::base () { return _vertical; } Segment* AutoVertical::base () { return _vertical; }
Segment* AutoVertical::base () const { return _vertical; } Segment* AutoVertical::base () const { return _vertical; }
Vertical* AutoVertical::getVertical () { return _vertical; } Vertical* AutoVertical::getVertical () { return _vertical; }
DbU::Unit AutoVertical::getSourceU () const { return _vertical->getSource()->getY(); } DbU::Unit AutoVertical::getSourceU () const { return _vertical->getSourceY(); }
DbU::Unit AutoVertical::getTargetU () const { return _vertical->getTarget()->getY(); } DbU::Unit AutoVertical::getTargetU () const { return _vertical->getTargetY(); }
DbU::Unit AutoVertical::getDuSource () const { return _vertical->getDySource(); } DbU::Unit AutoVertical::getDuSource () const { return _vertical->getDySource(); }
DbU::Unit AutoVertical::getDuTarget () const { return _vertical->getDyTarget(); } DbU::Unit AutoVertical::getDuTarget () const { return _vertical->getDyTarget(); }
Interval AutoVertical::getSpanU () const { return Interval(_vertical->getSourceY(),_vertical->getTargetY()); } 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"; } string AutoVertical::_getTypeName () const { return "AutoVertical"; }
@ -118,30 +115,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 Interval AutoVertical::getSourceConstraints ( Flags flags ) const
{ {
if (flags & Flags::NativeConstraints) { if (flags & Flags::NativeConstraints) {
@ -164,8 +137,6 @@ namespace Anabatic {
bool AutoVertical::getConstraints ( DbU::Unit& constraintMin, DbU::Unit& constraintMax ) const bool AutoVertical::getConstraints ( DbU::Unit& constraintMin, DbU::Unit& constraintMax ) const
{ {
cdebug_log(149,1) << "getConstraints() " << this << endl;
constraintMin = getNativeMin(); constraintMin = getNativeMin();
constraintMax = getNativeMax(); constraintMax = getNativeMax();
@ -181,39 +152,19 @@ namespace Anabatic {
<< DbU::getValueString(getAutoSource()->getCBXMax()) << "]" << DbU::getValueString(getAutoSource()->getCBXMax()) << "]"
<< endl; << endl;
constraintMin = std::max ( constraintMin, getAutoTarget()->getCBXMin() ); constraintMin = max ( constraintMin, getUserConstraints().getVMin() );
constraintMax = std::min ( constraintMax, getAutoTarget()->getCBXMax() ); constraintMax = min ( constraintMax, getUserConstraints().getVMax() );
cdebug_log(149,0) << "Merge with target constraints: ["
<< DbU::getValueString(getAutoTarget()->getCBXMin()) << ":" cdebug_log(149,0) << "Merge with user constraints: ["
<< DbU::getValueString(getAutoTarget()->getCBXMax()) << "]" << DbU::getValueString(getUserConstraints().getVMin()) << ":"
<< DbU::getValueString(getUserConstraints().getVMax()) << "]"
<< endl; << endl;
Interval userConstraints = getUserConstraints(); cdebug_log(149,0) << "Resulting constraints: " << " ["
if (not userConstraints.isEmpty()) {
constraintMin = max ( constraintMin, userConstraints.getVMin() );
constraintMax = min ( constraintMax, userConstraints.getVMax() );
cdebug_log(149,0) << "Merge with user constraints: ["
<< DbU::getValueString(userConstraints.getVMin()) << ":"
<< DbU::getValueString(userConstraints.getVMax()) << "]"
<< endl;
} else
cdebug_log(155,0) << "Empty user constraints" << endl;
cdebug_log(149,0) << "Resulting constraints: ["
<< DbU::getValueString(constraintMin) << ":" << DbU::getValueString(constraintMin) << ":"
<< DbU::getValueString(constraintMax) << "]" << DbU::getValueString(constraintMax) << "]"
<< endl; << endl;
if (constraintMin > constraintMax)
cerr << Error( "AutoVertical::getConstraints(): Invalid interval [%s : %s]\n"
" on %s"
, DbU::getValueString(constraintMin).c_str()
, DbU::getValueString(constraintMax).c_str()
, getString(this).c_str()
) << endl;
cdebug_tabw(149,-1);
return true; return true;
} }
@ -222,14 +173,13 @@ namespace Anabatic {
{ return Flags::Vertical; } { return Flags::Vertical; }
bool AutoVertical::getGCells ( vector<GCell*>& gcells ) const size_t AutoVertical::getGCells ( vector<GCell*>& gcells ) const
{ {
vector<GCell*>().swap( gcells ); vector<GCell*>().swap( gcells );
bool success = true; DbU::Unit xprobe = getX();
DbU::Unit xprobe = getX(); GCell* gcell = getAutoSource()->getGCell();
GCell* gcell = getAutoSource()->getGCell(); GCell* end = getAutoTarget()->getGCell();
GCell* end = getAutoTarget()->getGCell();
cdebug_log(144,0) << "xprobe: " << DbU::getValueString(xprobe) << endl; cdebug_log(144,0) << "xprobe: " << DbU::getValueString(xprobe) << endl;
@ -242,23 +192,20 @@ namespace Anabatic {
gcell = gcell->getNorth( xprobe ); gcell = gcell->getNorth( xprobe );
if (not gcell) { if (not gcell) {
success = false; cerr << Error( "AutoVertical::getGCells() : NULL GCell under %s\n"
if (not isCreated()) { " begin:%s\n"
cerr << Error( "AutoVertical::getGCells() : NULL GCell under %s\n" " end: %s"
" begin:%s\n" , getString(this).c_str()
" end: %s" , getString(getAutoSource()->getGCell()).c_str()
, getString(this).c_str() , getString(getAutoTarget()->getGCell()).c_str()
, getString(getAutoSource()->getGCell()).c_str() ) << endl;
, getString(getAutoTarget()->getGCell()).c_str()
) << endl;
}
break; break;
} }
gcells.push_back( gcell ); gcells.push_back( gcell );
} }
return success; return gcells.size();
} }
@ -266,21 +213,17 @@ namespace Anabatic {
{ {
cdebug_tabw(149,-1); cdebug_tabw(149,-1);
if (getAutoSource()->isOnPin() or getAutoTarget()->isOnPin()) { cdebug_tabw(149,-1); return false; }
Interval sourceSide = getAutoSource()->getGCell()->getSide( Flags::Horizontal ); Interval sourceSide = getAutoSource()->getGCell()->getSide( Flags::Horizontal );
Interval targetSide = getAutoTarget()->getGCell()->getSide( Flags::Horizontal ); Interval targetSide = getAutoTarget()->getGCell()->getSide( Flags::Horizontal );
Interval sourceConstraints = Interval(getAutoSource()->getCBXMin(),getAutoSource()->getCBXMax()); Interval sourceConstraints = Interval(getAutoSource()->getCBXMin(),getAutoSource()->getCBXMax());
Interval targetConstraints = Interval(getAutoTarget()->getCBXMin(),getAutoTarget()->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. // Expand by a tiny amount for the "contains" to work for sure.
sourceConstraints.inflate( 1 ); sourceConstraints.inflate( 1 );
targetConstraints.inflate( 1 ); targetConstraints.inflate( 1 );
if (not sourceGoStraight and not sourceConstraints.contains(sourceSide)) { cdebug_tabw(149,-1); return true; } if (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 targetConstraints.contains(targetSide)) { cdebug_tabw(149,-1); return true; }
cdebug_tabw(149,-1); cdebug_tabw(149,-1);
return false; return false;
@ -291,15 +234,13 @@ namespace Anabatic {
{ {
cdebug_log(149,1) << "AutoVertical::_slacken() " << this << endl; cdebug_log(149,1) << "AutoVertical::_slacken() " << this << endl;
if (not isDrag()) { if ( not isStrongTerminal()
if ( not isStrongTerminal() or (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < getPitch()*5)) )
or (not (_flags & (SegGlobal|SegWeakGlobal)) and (getAnchoredLength() < getPitch()*5)) ) { cdebug_tabw(149,-1); return false; }
{ cdebug_tabw(149,-1); return false; }
}
cdebug_log(149,0) << "_flags:" << (_flags & (SegGlobal|SegWeakGlobal)) << endl; cdebug_log(149,0) << "_flags:" << (_flags & (SegGlobal|SegWeakGlobal)) << endl;
cdebug_log(149,0) << "test:" << (getAnchoredLength() < getPitch()*5) << endl; cdebug_log(149,0) << "test:" << (getLength() < getPitch()*5) << endl;
cdebug_log(149,0) << "length:" << DbU::getValueString(getAnchoredLength()) << endl; cdebug_log(149,0) << "length:" << DbU::getValueString(getLength()) << endl;
bool success = false; bool success = false;
bool sourceSlackened = false; bool sourceSlackened = false;
@ -430,8 +371,8 @@ namespace Anabatic {
void AutoVertical::updatePositions () void AutoVertical::updatePositions ()
{ {
_sourcePosition = getSourceU() - getExtensionCap(Flags::Source); _sourcePosition = _vertical->getSourceY() - getExtensionCap();
_targetPosition = getTargetU() + getExtensionCap(Flags::Target); _targetPosition = _vertical->getTargetY() + getExtensionCap();
} }
@ -451,8 +392,8 @@ namespace Anabatic {
bool AutoVertical::checkPositions () const bool AutoVertical::checkPositions () const
{ {
bool coherency = true; bool coherency = true;
DbU::Unit sourcePosition = _vertical->getSource()->getY() - getExtensionCap(Flags::Source); DbU::Unit sourcePosition = _vertical->getSourceY() - getExtensionCap();
DbU::Unit targetPosition = _vertical->getTarget()->getY() + getExtensionCap(Flags::Target); DbU::Unit targetPosition = _vertical->getTargetY() + getExtensionCap();
if ( _sourcePosition != sourcePosition ) { if ( _sourcePosition != sourcePosition ) {
cerr << Error ( "%s\n Source position incoherency: " cerr << Error ( "%s\n Source position incoherency: "
@ -709,14 +650,12 @@ namespace Anabatic {
{ {
cdebug_log(149,0) << "AutoVertical::_makeDogleg(GCell*)" << endl; cdebug_log(149,0) << "AutoVertical::_makeDogleg(GCell*)" << endl;
//Session::doglegReset();
AutoContact* autoSource = getAutoSource(); AutoContact* autoSource = getAutoSource();
AutoContact* autoTarget = getAutoTarget(); AutoContact* autoTarget = getAutoTarget();
GCell* begin = autoSource->getGCell(); GCell* begin = autoSource->getGCell();
GCell* end = autoTarget->getGCell(); GCell* end = autoTarget->getGCell();
if (not autoSource->canDrag()) unsetFlags( SegDrag ); //Session::doglegReset();
DbU::Unit doglegAxis = (doglegGCell->getYMax() + doglegGCell->getYMin()) / 2; DbU::Unit doglegAxis = (doglegGCell->getYMax() + doglegGCell->getYMin()) / 2;
if (isLocal()) if (isLocal())
@ -732,19 +671,10 @@ namespace Anabatic {
} while ( gcell and (gcell != end) ); } while ( gcell and (gcell != end) );
} }
size_t depth = Session::getRoutingGauge()->getLayerDepth ( _vertical->getLayer() ); size_t depth = Session::getRoutingGauge()->getLayerDepth ( _vertical->getLayer() );
bool upLayer = true; bool upLayer = (depth+1 <= Session::getConfiguration()->getAllowedDepth());
Layer* contactLayer = Session::getRoutingGauge()->getContactLayer ( depth + ((upLayer)?0:-1) );
if (Session::getRoutingGauge()->isTwoMetals()) { const Layer* doglegLayer = Session::getRoutingGauge()->getRoutingLayer ( depth + ((upLayer)?1:-1) );
upLayer = (Session::getRoutingGauge()->isVH());
} 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) );
Session::dogleg( this ); Session::dogleg( this );
targetDetach(); targetDetach();
@ -756,7 +686,7 @@ namespace Anabatic {
cdebug_log(149,0) << dlContact2 << endl; cdebug_log(149,0) << dlContact2 << endl;
AutoSegment* segment1 = AutoSegment::create( dlContact1 , dlContact2, Flags::Horizontal ); AutoSegment* segment1 = AutoSegment::create( dlContact1 , dlContact2, Flags::Horizontal );
cdebug_log(149,0) << segment1 << endl; cdebug_log(149,0) << segment1 << endl;
segment1->setLayer( doglegDepth ); segment1->setLayer( doglegLayer );
segment1->_setAxis( doglegAxis ); segment1->_setAxis( doglegAxis );
segment1->setFlags( SegDogleg|SegSlackened|SegCanonical|SegNotAligned ); segment1->setFlags( SegDogleg|SegSlackened|SegCanonical|SegNotAligned );
cdebug_log(149,0) << "New " << dlContact1->base() << "." << endl; cdebug_log(149,0) << "New " << dlContact1->base() << "." << endl;
@ -766,61 +696,36 @@ namespace Anabatic {
targetAttach( dlContact1 ); targetAttach( dlContact1 );
AutoSegment* segment2 = AutoVertical::create ( dlContact2, autoTarget, Flags::Vertical ); AutoSegment* segment2 = AutoVertical::create ( dlContact2, autoTarget, Flags::Vertical );
autoTarget->cacheAttach( segment2 ); autoTarget->cacheAttach( segment2 );
segment2->setLayer( depth ); segment2->setLayer( getLayer() );
segment2->_setAxis( getX() ); segment2->_setAxis( getX() );
segment2->setFlags( (isSlackened()?SegSlackened:0) ); segment2->setFlags( (isSlackened()?SegSlackened:0) );
Session::dogleg( segment2 ); Session::dogleg( segment2 );
if (autoSource->isTerminal() and autoTarget->isTerminal()) { if (isSourceTerminal()) {
dlContact1->setFlags ( CntWeakTerminal ); segment1->setFlags( SegWeakTerminal1 );
dlContact2->setFlags ( CntWeakTerminal ); segment2->setFlags( SegWeakTerminal1 );
if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget );
if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource );
} else if (autoSource->isTerminal()) {
autoTarget->unsetFlags( CntWeakTerminal ); autoTarget->unsetFlags( CntWeakTerminal );
dlContact1->setFlags ( CntWeakTerminal ); dlContact1->setFlags ( CntWeakTerminal );
if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget ); if (autoTarget->getGCell() == doglegGCell)
} else if (autoTarget->isTerminal()) { dlContact1->migrateConstraintBox( autoTarget );
} else if (isTargetTerminal()) {
unsetFlags( SegTargetTerminal ); unsetFlags( SegTargetTerminal );
setFlags( SegWeakTerminal1 ); setFlags( SegWeakTerminal1 );
segment1->setFlags( SegWeakTerminal1 );
segment2->setFlags( SegTargetTerminal );
autoSource->unsetFlags( CntWeakTerminal ); autoSource->unsetFlags( CntWeakTerminal );
dlContact2->setFlags ( CntWeakTerminal ); dlContact2->setFlags ( CntWeakTerminal );
if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource ); if (autoSource->getGCell() == doglegGCell)
} else if (isWeakTerminal()) { dlContact2->migrateConstraintBox( autoSource );
} else if (isWeakTerminal()) {
segment1->setFlags( SegWeakTerminal1 ); segment1->setFlags( SegWeakTerminal1 );
segment2->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()) { if (isAnalog()) {
segment1->setFlags( SegAnalog ); segment1->setFlags( SegAnalog );
segment2->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+1] perpand: " << segment1 << endl;
cdebug_log(149,0) << "Session::dogleg[x+2] new paral: " << segment2 << endl; cdebug_log(149,0) << "Session::dogleg[x+2] new paral: " << segment2 << endl;
@ -836,18 +741,6 @@ namespace Anabatic {
updateNativeConstraints(); updateNativeConstraints();
segment2->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())) {
Interval dragConstraints = autoTarget->getNativeUConstraints(Flags::Vertical);
segment1->mergeUserConstraints( dragConstraints );
cdebug_log(149,0) << "Perpandicular has drag constraints: " << dragConstraints << endl;
}
}
return (upLayer) ? Flags::AboveLayer : Flags::BelowLayer; return (upLayer) ? Flags::AboveLayer : Flags::BelowLayer;
} }

View File

@ -6,18 +6,15 @@ endif ( CHECK_DETERMINISM )
include_directories( ${ANABATIC_SOURCE_DIR}/src include_directories( ${ANABATIC_SOURCE_DIR}/src
${CORIOLIS_INCLUDE_DIR} ${CORIOLIS_INCLUDE_DIR}
${ETESIAN_INCLUDE_DIR}
${HURRICANE_INCLUDE_DIR} ${HURRICANE_INCLUDE_DIR}
${CONFIGURATION_INCLUDE_DIR} ${CONFIGURATION_INCLUDE_DIR}
${FLUTE_INCLUDE_DIR}
${Boost_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
${QtX_INCLUDE_DIRS} ${QtX_INCLUDE_DIR}
${Python_INCLUDE_DIRS} ${PYTHON_INCLUDE_PATH}
) )
set( includes anabatic/Constants.h set( includes anabatic/Constants.h
anabatic/Configuration.h anabatic/Configuration.h
anabatic/Matrix.h anabatic/Matrix.h
anabatic/EdgeCapacity.h
anabatic/Edge.h anabatic/Edges.h anabatic/Edge.h anabatic/Edges.h
anabatic/GCell.h #anabatic/GCells.h anabatic/GCell.h #anabatic/GCells.h
anabatic/AnabaticEngine.h anabatic/AnabaticEngine.h
@ -32,22 +29,18 @@ endif ( CHECK_DETERMINISM )
anabatic/AutoHorizontal.h anabatic/AutoHorizontal.h
anabatic/AutoVertical.h anabatic/AutoVertical.h
anabatic/Session.h anabatic/Session.h
anabatic/NetBuilder.h
anabatic/NetBuilderM2.h
anabatic/NetBuilderHV.h
anabatic/NetBuilderVH.h
anabatic/NetBuilderHybridVH.h
anabatic/ChipTools.h anabatic/ChipTools.h
) )
set( pyIncludes anabatic/PyStyleFlags.h ) set( pyIncludes )
set( cpps Constants.cpp set( cpps Constants.cpp
Configuration.cpp Configuration.cpp
Matrix.cpp Matrix.cpp
EdgeCapacity.cpp
Edge.cpp Edge.cpp
Edges.cpp Edges.cpp
GCell.cpp GCell.cpp
AnabaticEngine.cpp
Dijkstra.cpp Dijkstra.cpp
AutoContact.cpp AutoContact.cpp
AutoContactTerminal.cpp AutoContactTerminal.cpp
AutoContactTurn.cpp AutoContactTurn.cpp
@ -59,23 +52,15 @@ endif ( CHECK_DETERMINISM )
Session.cpp Session.cpp
NetConstraints.cpp NetConstraints.cpp
NetOptimals.cpp NetOptimals.cpp
NetBuilder.cpp LoadGlobalRouting.cpp
NetBuilderM2.cpp
NetBuilderHV.cpp
NetBuilderVH.cpp
NetBuilderHybridVH.cpp
ChipTools.cpp ChipTools.cpp
LayerAssign.cpp LayerAssign.cpp
AntennaProtect.cpp
PreRouteds.cpp PreRouteds.cpp
AnabaticEngine.cpp
) )
set( pyCpps PyStyleFlags.cpp set( pyCpps PyAnabatic.cpp
PyAnabatic.cpp
) )
set( depLibs ${ETESIAN_LIBRARIES} set( depLibs ${CORIOLIS_PYTHON_LIBRARIES}
${CORIOLIS_PYTHON_LIBRARIES}
${CORIOLIS_LIBRARIES} ${CORIOLIS_LIBRARIES}
${HURRICANE_PYTHON_LIBRARIES} ${HURRICANE_PYTHON_LIBRARIES}
${HURRICANE_GRAPHICAL_LIBRARIES} ${HURRICANE_GRAPHICAL_LIBRARIES}
@ -83,15 +68,12 @@ endif ( CHECK_DETERMINISM )
${CONFIGURATION_LIBRARY} ${CONFIGURATION_LIBRARY}
${CIF_LIBRARY} ${CIF_LIBRARY}
${AGDS_LIBRARY} ${AGDS_LIBRARY}
${COLOQUINTE_LIBRARIES}
${FLUTE_LIBRARIES}
${LEFDEF_LIBRARIES} ${LEFDEF_LIBRARIES}
${OA_LIBRARIES} ${OA_LIBRARIES}
${QtX_LIBRARIES} ${QtX_LIBRARIES}
${Boost_LIBRARIES} ${Boost_LIBRARIES}
${LIBXML2_LIBRARIES} ${LIBXML2_LIBRARIES}
${Python3_LIBRARIES} ${PYTHON_LIBRARIES} -lutil
-lutil
) )
add_library( anabatic ${cpps} ) add_library( anabatic ${cpps} )

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2018, All Rights Reserved // Copyright (c) UPMC 2008-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |

View File

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "Configuration.cpp<anabatic>" -*- // -*- mode: C++; explicit-buffer-name: "Configuration.cpp<anabatic>" -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2016-2022, All Rights Reserved // Copyright (c) UPMC 2016-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -17,17 +17,12 @@
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
#include <vector> #include <vector>
#include "hurricane/configuration/Configuration.h" #include "vlsisapd/configuration/Configuration.h"
#include "hurricane/Warning.h" #include "hurricane/Warning.h"
#include "hurricane/Error.h" #include "hurricane/Error.h"
#include "hurricane/Technology.h" #include "hurricane/Technology.h"
#include "hurricane/DataBase.h" #include "hurricane/DataBase.h"
#include "hurricane/BasicLayer.h"
#include "hurricane/RegularLayer.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 "hurricane/Cell.h"
#include "crlcore/Utilities.h" #include "crlcore/Utilities.h"
#include "crlcore/CellGauge.h" #include "crlcore/CellGauge.h"
@ -51,18 +46,9 @@ namespace Anabatic {
using Hurricane::tab; using Hurricane::tab;
using Hurricane::Warning; using Hurricane::Warning;
using Hurricane::Error; using Hurricane::Error;
using Hurricane::Transformation;
using Hurricane::Technology; using Hurricane::Technology;
using Hurricane::DataBase; using Hurricane::DataBase;
using Hurricane::BasicLayer;
using Hurricane::RegularLayer; using Hurricane::RegularLayer;
using Hurricane::Segment;
using Hurricane::Pad;
using Hurricane::Pin;
using Hurricane::Plug;
using Hurricane::Path;
using Hurricane::Occurrence;
using Hurricane::NetExternalComponents;
using CRL::AllianceFramework; using CRL::AllianceFramework;
using CRL::RoutingGauge; using CRL::RoutingGauge;
using CRL::RoutingLayerGauge; using CRL::RoutingLayerGauge;
@ -73,56 +59,30 @@ namespace Anabatic {
Configuration::Configuration ( const CellGauge* cg, const RoutingGauge* rg ) Configuration::Configuration ( const CellGauge* cg, const RoutingGauge* rg )
: _gdepthv (ndepth) : _cg (NULL)
, _gdepthh (ndepth) , _rg (NULL)
, _ddepthv (ndepth) , _extensionCaps ()
, _ddepthh (ndepth) , _saturateRatio (Cfg::getParamPercentage("katabatic.saturateRatio",80.0)->asDouble())
, _ddepthc (ndepth) , _saturateRp (Cfg::getParamInt ("katabatic.saturateRp" ,8 )->asInt())
, _netBuilderStyle (Cfg::getParamString("anabatic.netBuilderStyle","HV,3RL+")->asString() ) , _globalThreshold(0)
, _routingStyle (Cfg::getParamInt ("anabatic.routingStyle" ,StyleFlags::NoStyle)->asInt() ) , _allowedDepth (0)
, _cg (NULL) , _edgeLength (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeLength",24)->asInt()))
, _rg (NULL) , _edgeWidth (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeWidth" , 4)->asInt()))
, _extensionCaps () , _edgeCostH (Cfg::getParamDouble("anabatic.edgeCostH", 9.0)->asDouble())
, _saturateRatio (Cfg::getParamPercentage("anabatic.saturateRatio",80.0)->asDouble()) , _edgeCostK (Cfg::getParamDouble("anabatic.edgeCostK",-10.0)->asDouble())
, _saturateRp (Cfg::getParamInt ("anabatic.saturateRp" ,8 )->asInt()) , _edgeHInc (Cfg::getParamDouble("anabatic.edgeHInc" , 1.5)->asDouble())
, _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())
{ {
GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() ); GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() );
string gaugeName = Cfg::getParamString("anabatic.routingGauge","sxlib")->asString(); if (cg == NULL) cg = AllianceFramework::get()->getCellGauge();
if (not cg) if (rg == NULL) rg = AllianceFramework::get()->getRoutingGauge();
cg = AllianceFramework::get()->getCellGauge( gaugeName );
if (not cg) {
string cellGaugeName = Cfg::getParamString("anabatic.cellGauge","sxlib")->asString();
cg = AllianceFramework::get()->getCellGauge( cellGaugeName );
}
if (not cg)
throw Error( "AnabaticEngine::Configuration(): Unable to find cell gauge \"%s\""
, gaugeName.c_str() );
if (not rg)
rg = AllianceFramework::get()->getRoutingGauge( gaugeName );
if (not rg)
throw Error( "AnabaticEngine::Configuration(): Unable to find routing gauge \"%s\""
, gaugeName.c_str() );
_cg = cg->getClone(); _cg = cg->getClone();
_rg = rg->getClone(); _rg = rg->getClone();
_allowedDepth = rg->getDepth()-1; if (Cfg::hasParameter("anabatic.topRoutingLayer")) {
if (Cfg::hasParameter("anabatic.topRoutingLayer"))
_setTopRoutingLayer( Cfg::getParamString("anabatic.topRoutingLayer")->asString() ); _setTopRoutingLayer( Cfg::getParamString("anabatic.topRoutingLayer")->asString() );
} else
_allowedDepth = rg->getDepth()-1;
_gmetalh = DataBase::getDB()->getTechnology()->getLayer("gmetalh"); _gmetalh = DataBase::getDB()->getTechnology()->getLayer("gmetalh");
_gmetalv = DataBase::getDB()->getTechnology()->getLayer("gmetalv"); _gmetalv = DataBase::getDB()->getTechnology()->getLayer("gmetalv");
@ -134,77 +94,36 @@ namespace Anabatic {
//DbU::Unit sliceHeight = _cg->getSliceHeight(); //DbU::Unit sliceHeight = _cg->getSliceHeight();
_ddepthc = (_allowedDepth > 1) ? 1 : 0;
const vector<RoutingLayerGauge*>& layerGauges = rg->getLayerGauges(); const vector<RoutingLayerGauge*>& layerGauges = rg->getLayerGauges();
for ( size_t depth=0 ; depth < layerGauges.size() ; ++depth ) { for ( size_t depth=0 ; depth < layerGauges.size() ; ++depth ) {
if ( (_gdepthh == ndepth)
and layerGauges[depth]->isHorizontal()
and (layerGauges[depth]->getType() == Constant::LayerGaugeType::Default) ) {
_gdepthh = depth;
_ddepthh = depth;
}
if ( (_gdepthv == ndepth)
and layerGauges[depth]->isVertical()
and (layerGauges[depth]->getType() == Constant::LayerGaugeType::Default) ) {
_gdepthv = depth;
_ddepthv = depth;
}
const RegularLayer* regularLayer = dynamic_cast<const RegularLayer*>( layerGauges[depth]->getLayer() ); const RegularLayer* regularLayer = dynamic_cast<const RegularLayer*>( layerGauges[depth]->getLayer() );
if (regularLayer) if (regularLayer)
_extensionCaps.push_back( regularLayer->getExtentionCap() ); _extensionCaps.push_back( regularLayer->getExtentionCap() );
else { else {
const BasicLayer* basicLayer = dynamic_cast<const BasicLayer*>( layerGauges[depth]->getLayer() ); _extensionCaps.push_back( 0 );
if (basicLayer) { cerr << Warning( "Routing layer at depth %d is *not* a RegularLayer, cannot guess extension cap.\n"
_extensionCaps.push_back( layerGauges[depth]->getHalfWireWidth() ); " (%s)"
} else { , depth
_extensionCaps.push_back( 0 ); , getString(layerGauges[depth]->getLayer()).c_str()
cerr << Warning( "Routing layer at depth %d is *not* a RegularLayer, cannot guess extension cap.\n" ) << endl;
" (%s)"
, depth
, getString(layerGauges[depth]->getLayer()).c_str()
) << endl;
}
} }
} }
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 ) Configuration::Configuration ( const Configuration& other )
: _gmetalh (other._gmetalh) : _gmetalh (other._gmetalh)
, _gmetalv (other._gmetalv) , _gmetalv (other._gmetalv)
, _gcontact (other._gcontact) , _gcontact (other._gcontact)
, _gdepthv (other._gdepthv) , _cg (NULL)
, _gdepthh (other._gdepthh) , _rg (NULL)
, _ddepthv (other._ddepthv) , _extensionCaps (other._extensionCaps)
, _ddepthh (other._ddepthh) , _saturateRatio (other._saturateRatio)
, _ddepthc (other._ddepthc) , _globalThreshold(other._globalThreshold)
, _netBuilderStyle (other._netBuilderStyle) , _allowedDepth (other._allowedDepth)
, _routingStyle (other._routingStyle) , _edgeCostH (other._edgeCostH)
, _cg (NULL) , _edgeCostK (other._edgeCostK)
, _rg (NULL) , _edgeHInc (other._edgeHInc)
, _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)
{ {
GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() ); GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() );
@ -225,22 +144,6 @@ namespace Anabatic {
{ return new Configuration(*this); } { return new Configuration(*this); }
bool Configuration::isTwoMetals () const
{ return _rg->isTwoMetals(); }
bool Configuration::isHybrid () const
{ return _routingStyle & StyleFlags::Hybrid; }
bool Configuration::isHV () const
{ return _rg->isHV(); }
bool Configuration::isVH () const
{ return _rg->isVH(); }
bool Configuration::isGMetal ( const Layer* layer ) const bool Configuration::isGMetal ( const Layer* layer ) const
{ return (layer and ((layer == _gmetalh) or (layer == _gmetalv))); } { return (layer and ((layer == _gmetalh) or (layer == _gmetalv))); }
@ -248,19 +151,15 @@ namespace Anabatic {
bool Configuration::isGContact ( const Layer* layer ) const bool Configuration::isGContact ( const Layer* layer ) const
{ return (layer and (layer == _gcontact)); } { return (layer and (layer == _gcontact)); }
const Layer* Configuration::getGContactLayer () const const Layer* Configuration::getGContactLayer () const
{ return _gcontact; } { return _gcontact; }
const Layer* Configuration::getGHorizontalLayer () const const Layer* Configuration::getGHorizontalLayer () const
{ return _gmetalh; } { return _gmetalh; }
const Layer* Configuration::getGVerticalLayer () const const Layer* Configuration::getGVerticalLayer () const
{ return _gmetalv; } { return _gmetalv; }
size_t Configuration::getDepth () const size_t Configuration::getDepth () const
{ return _rg->getDepth(); } { return _rg->getDepth(); }
@ -317,10 +216,6 @@ namespace Anabatic {
{ return getWireWidth( getLayerDepth(layer) ); } { return getWireWidth( getLayerDepth(layer) ); }
DbU::Unit Configuration::getPWireWidth ( const Layer* layer ) const
{ return getPWireWidth( getLayerDepth(layer) ); }
Flags Configuration::getDirection ( const Layer* layer ) const Flags Configuration::getDirection ( const Layer* layer ) const
{ return getDirection( getLayerDepth(layer) ); } { return getDirection( getLayerDepth(layer) ); }
@ -372,9 +267,6 @@ namespace Anabatic {
{ return _rg->getLayerWireWidth(depth); } { return _rg->getLayerWireWidth(depth); }
DbU::Unit Configuration::getPWireWidth ( size_t depth ) const
{ return _rg->getLayerPWireWidth(depth); }
DbU::Unit Configuration::getExtensionCap ( size_t depth ) const DbU::Unit Configuration::getExtensionCap ( size_t depth ) const
{ return _extensionCaps[depth]; } { return _extensionCaps[depth]; }
@ -396,7 +288,7 @@ namespace Anabatic {
} }
} }
cerr << Error( "In Configuration::Concrete::_setTopRoutingLayer():\n" cerr << Error( "In Configuration::Concrete::_setTopRoutingLayer():\n"
" The routing gauge <%s> has no layer named <%s>" " The routing gauge <%s> has no layer named <%s>"
, getString(_rg->getName()).c_str() , getString(_rg->getName()).c_str()
, getString(name).c_str() ) << endl; , getString(name).c_str() ) << endl;
} }
@ -434,144 +326,6 @@ namespace Anabatic {
{ return _edgeHInc; } { return _edgeHInc; }
float Configuration::getEdgeHScaling () const
{ return _edgeHScaling; }
int Configuration::getGlobalIterations () const
{ return _globalIterations; }
DbU::Unit Configuration::isOnRoutingGrid ( RoutingPad* rp ) const
{
Box ab = rp->getCell()->getBoundingBox();
Box bb = rp->getBoundingBox();
Point center = rp->getCenter();
RoutingLayerGauge* gauge = getLayerGauge( 1 );
if (gauge->isHorizontal()) return 0;
DbU::Unit nearestX = gauge->getTrackPosition( ab.getXMin(), ab.getXMax(), center.getX(), Constant::Nearest );
if ( (nearestX >= bb.getXMin()) and (nearestX <= bb.getXMax()) ) return 0;
return nearestX;
}
bool Configuration::selectRpComponent ( RoutingPad* rp ) const
{
cdebug_log(112,1) << "selectRpComponent(): " << rp << endl;
if (rp->isAtTopLevel()) {
cdebug_log(112,0) << "> RP is at top level, must not change it." << endl;
cdebug_tabw(112,-1);
return true;
}
#define BETTER_FOR_TSMC 0
#if BETTER_FOR_TSMC
rp->setOnBestComponent( RoutingPad::BiggestArea );
cdebug_tabw(112,-1);
return true;
#else
Box ab = rp->getCell()->getAbutmentBox();
const Layer* metal1 = getLayerGauge( 0 )->getLayer();
RoutingLayerGauge* gauge = getLayerGauge( 1 );
Occurrence occurrence = rp->getPlugOccurrence();
Plug* plug = dynamic_cast<Plug*>( occurrence.getEntity() );
Net* masterNet = plug->getMasterNet();
Path path = Path( occurrence.getPath(), plug->getInstance() );
Transformation transformation = path.getTransformation();
Segment* current = dynamic_cast<Segment*>( rp->getOccurrence().getEntity() );
if (current and (current->getLayer()->getMask() != metal1->getMask())) {
cdebug_log(112,0) << "> using default non-metal1 segment." << endl;
cdebug_tabw(112,-1);
return true;
}
DbU::Unit bestSpan = 0;
Component* bestComponent = NULL;
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 (dynamic_cast<Pin*>(component)) {
cdebug_log(112,0) << " Pins are always considered best candidates:" << component << endl;
bestComponent = component;
break;
}
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() );
DbU::Unit trackPos = 0;
DbU::Unit minPos = DbU::Max;
DbU::Unit maxPos = DbU::Min;
if (gauge->isVertical()) {
trackPos = gauge->getTrackPosition( ab.getXMin()
, ab.getXMax()
, bb.getCenter().getX()
, Constant::Nearest );
minPos = bb.getXMin();
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) << "bb.getCenter(): " << DbU::getValueString(bb.getCenter().getX()) << endl;
} else {
trackPos = gauge->getTrackPosition( ab.getYMin()
, ab.getYMax()
, bb.getCenter().getY()
, Constant::Nearest );
minPos = bb.getYMin();
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) << "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) << "| Nearest Pos: " << DbU::getValueString(trackPos) << endl;
if ( (trackPos >= minPos) and (trackPos <= maxPos) ) {
if (not bestComponent or (bestSpan < maxPos-minPos)) {
bestComponent = component;
bestSpan = maxPos - minPos;
}
}
}
if (bestComponent) {
rp->setExternalComponent( bestComponent );
cdebug_log(112,0) << "Using best candidate:" << bestComponent << endl;
cdebug_tabw(112,-1);
return true;
}
cdebug_tabw(112,-1);
return false;
#endif
}
void Configuration::print ( Cell* cell ) const void Configuration::print ( Cell* cell ) const
{ {
if (not cmess1.enabled()) return; if (not cmess1.enabled()) return;
@ -584,7 +338,6 @@ namespace Anabatic {
cout << " o Configuration of ToolEngine<Anabatic> for Cell <" << cell->getName() << ">" << endl; cout << " o Configuration of ToolEngine<Anabatic> for Cell <" << cell->getName() << ">" << endl;
cout << Dots::asIdentifier(" - Routing Gauge" ,getString(_rg->getName())) << endl; cout << Dots::asIdentifier(" - Routing Gauge" ,getString(_rg->getName())) << endl;
cout << Dots::asString (" - Top routing layer" ,topLayerName) << endl; cout << Dots::asString (" - Top routing layer" ,topLayerName) << endl;
cout << Dots::asUInt (" - Maximum GR iterations" ,_globalIterations) << endl;
} }
@ -607,22 +360,15 @@ namespace Anabatic {
Record* Configuration::_getRecord () const Record* Configuration::_getRecord () const
{ {
Record* record = new Record ( _getString() ); Record* record = new Record ( _getString() );
record->add( getSlot( "_gdepthh" , _gdepthh ) ); record->add ( getSlot( "_rg" , _rg ) );
record->add( getSlot( "_gdepthv" , _gdepthv ) ); record->add ( getSlot( "_gmetalh" , _gmetalh ) );
record->add( getSlot( "_rg" , _rg ) ); record->add ( getSlot( "_gmetalv" , _gmetalv ) );
record->add( getSlot( "_gmetalh" , _gmetalh ) ); record->add ( getSlot( "_gcontact" , _gcontact ) );
record->add( getSlot( "_gmetalv" , _gmetalv ) ); record->add ( getSlot( "_allowedDepth", _allowedDepth ) );
record->add( getSlot( "_gcontact" , _gcontact ) ); record->add ( getSlot( "_edgeCostH" , _edgeCostH ) );
record->add( getSlot( "_allowedDepth" , _allowedDepth ) ); record->add ( getSlot( "_edgeCostK" , _edgeCostK ) );
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 ) );
return record; return ( record );
} }

View File

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "Constants.cpp<anabatic>" -*- // -*- mode: C++; explicit-buffer-name: "Constants.cpp<anabatic>" -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2018, All Rights Reserved // Copyright (c) UPMC 2016-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -14,22 +14,16 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#include "hurricane/Error.h"
#include "anabatic/Constants.h" #include "anabatic/Constants.h"
namespace Anabatic { namespace Anabatic {
using std::hex;
using std::string; using std::string;
using std::ostringstream; using std::ostringstream;
using Hurricane::BaseFlags; using Hurricane::BaseFlags;
using Hurricane::Error;
// -------------------------------------------------------------------
// Class : "Anabatic::Flags".
const BaseFlags Flags::NoFlags = 0; const BaseFlags Flags::NoFlags = 0;
// Flags used for both objects states & functions arguments. // Flags used for both objects states & functions arguments.
const BaseFlags Flags::Horizontal = (1L << 0); const BaseFlags Flags::Horizontal = (1L << 0);
@ -45,27 +39,14 @@ namespace Anabatic {
const BaseFlags Flags::MatrixGCell = (1L << 9); const BaseFlags Flags::MatrixGCell = (1L << 9);
const BaseFlags Flags::IoPadGCell = (1L << 10); const BaseFlags Flags::IoPadGCell = (1L << 10);
const BaseFlags Flags::Saturated = (1L << 11); const BaseFlags Flags::Saturated = (1L << 11);
const BaseFlags Flags::StdCellRow = (1L << 12);
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);
// Flags for Anabatic objects states only. // Flags for Anabatic objects states only.
const BaseFlags Flags::DemoMode = (1L << 5); const BaseFlags Flags::DemoMode = (1L << 5);
const BaseFlags Flags::WarnOnGCellOverload = (1L << 6); const BaseFlags Flags::WarnOnGCellOverload = (1L << 6);
const BaseFlags Flags::DestroyGCell = (1L << 7); const BaseFlags Flags::DestroyGCell = (1L << 7);
const BaseFlags Flags::DestroyBaseContact = (1L << 8); const BaseFlags Flags::DestroyBaseContact = (1L << 8);
const BaseFlags Flags::DestroyBaseSegment = (1L << 9); const BaseFlags Flags::DestroyBaseSegment = (1L << 9);
const BaseFlags Flags::DisableCanonize = (1L << 10);
// Flags for NetDatas objects states only. // 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);
// Masks. // Masks.
const BaseFlags Flags::WestSide = Horizontal|Target; const BaseFlags Flags::WestSide = Horizontal|Target;
const BaseFlags Flags::EastSide = Horizontal|Source; const BaseFlags Flags::EastSide = Horizontal|Source;
@ -75,27 +56,7 @@ namespace Anabatic {
const BaseFlags Flags::EndsMask = Source|Target; const BaseFlags Flags::EndsMask = Source|Target;
const BaseFlags Flags::DirectionMask = Horizontal|Vertical; const BaseFlags Flags::DirectionMask = Horizontal|Vertical;
const BaseFlags Flags::DestroyMask = DestroyGCell|DestroyBaseContact|DestroyBaseSegment; const BaseFlags Flags::DestroyMask = DestroyGCell|DestroyBaseContact|DestroyBaseSegment;
const BaseFlags Flags::GCellTypeMask = DeviceGCell const BaseFlags Flags::GCellTypeMask = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell;
| HChannelGCell
| VChannelGCell
| StrutGCell
| MatrixGCell
| IoPadGCell
| StdCellRow
| ChannelRow
| HRailGCell
| VRailGCell;
const BaseFlags Flags::RowGCellMask = StdCellRow|ChannelRow;
const BaseFlags Flags::AnalogGCellMask = DeviceGCell
| HChannelGCell
| VChannelGCell
| StrutGCell
| HRailGCell
| VRailGCell;
const BaseFlags Flags::EdgeCapacityMask = Horizontal
| Vertical
| NullCapacity
| InfiniteCapacity ;
// Flags for functions arguments only. // Flags for functions arguments only.
const BaseFlags Flags::Create = (1L << 5); const BaseFlags Flags::Create = (1L << 5);
const BaseFlags Flags::WithPerpands = (1L << 6); const BaseFlags Flags::WithPerpands = (1L << 6);
@ -125,14 +86,6 @@ namespace Anabatic {
const BaseFlags Flags::CheckLowDensity = (1L << 30); const BaseFlags Flags::CheckLowDensity = (1L << 30);
const BaseFlags Flags::CheckLowUpDensity = (1L << 31); const BaseFlags Flags::CheckLowUpDensity = (1L << 31);
const BaseFlags Flags::NoUpdate = (1L << 32); 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 () Flags::~Flags ()
@ -186,7 +139,6 @@ namespace Anabatic {
return s.str(); return s.str();
} }
string Flags::_getTypeName () const string Flags::_getTypeName () const
{ return "Anabatic::Flags"; } { return "Anabatic::Flags"; }
@ -194,93 +146,23 @@ namespace Anabatic {
string Flags::_getString () const string Flags::_getString () const
{ {
string s = ""; string s = "";
s += (_flags & (uint64_t)Horizontal ) ? 'h' : '-'; s += (_flags & (uint64_t)Horizontal ) ? 'h' : '-';
s += (_flags & (uint64_t)Vertical ) ? 'v' : '-'; s += (_flags & (uint64_t)Vertical ) ? 'v' : '-';
s += (_flags & (uint64_t)Source ) ? 'S' : '-'; s += (_flags & (uint64_t)Source ) ? 'S' : '-';
s += (_flags & (uint64_t)Target ) ? 'T' : '-'; s += (_flags & (uint64_t)Target ) ? 'T' : '-';
s += (_flags & (uint64_t)DeviceGCell ) ? 'd' : '-'; s += (_flags & (uint64_t)DeviceGCell ) ? 'd' : '-';
s += (_flags & (uint64_t)HChannelGCell) ? 'c' : '-'; s += (_flags & (uint64_t)HChannelGCell) ? 'c' : '-';
s += (_flags & (uint64_t)VChannelGCell) ? 'c' : '-'; s += (_flags & (uint64_t)VChannelGCell) ? 'c' : '-';
s += (_flags & (uint64_t)HRailGCell ) ? 'H' : '-'; s += (_flags & (uint64_t)StrutGCell ) ? 's' : '-';
s += (_flags & (uint64_t)VRailGCell ) ? 'V' : '-'; s += (_flags & (uint64_t)MatrixGCell ) ? 'm' : '-';
s += (_flags & (uint64_t)StrutGCell ) ? 'S' : '-';
s += (_flags & (uint64_t)MatrixGCell ) ? 'M' : '-';
s += (_flags & (uint64_t)StdCellRow ) ? 'R' : '-';
s += (_flags & (uint64_t)ChannelRow ) ? 'C' : '-';
s += (_flags & (uint64_t)GoStraight ) ? 'g' : '-';
s += ","; s += ",";
s += (_flags & (uint64_t)Invalidated ) ? 'i' : '-'; s += (_flags & (uint64_t)Invalidated ) ? 'i' : '-';
s += (_flags & (uint64_t)DestroyGCell ) ? 'D' : '-'; s += (_flags & (uint64_t)DestroyGCell ) ? 'D' : '-';
s += (_flags & (uint64_t)AboveLayer ) ? 'A' : '-'; s += (_flags & (uint64_t)AboveLayer ) ? 'A' : '-';
s += (_flags & (uint64_t)BelowLayer ) ? 'B' : '-'; s += (_flags & (uint64_t)BelowLayer ) ? 'B' : '-';
return s; return s;
} }
// -------------------------------------------------------------------
// 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. } // Anabatic namespace.

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "Edge.cpp<anabatic>" -*- // -*- mode: C++; explicit-buffer-name: "Edge.cpp<anabatic>" -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2018, All Rights Reserved // Copyright (c) UPMC 2016-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -17,7 +17,6 @@
#include <iostream> #include <iostream>
#include "hurricane/Error.h" #include "hurricane/Error.h"
#include "hurricane/Segment.h" #include "hurricane/Segment.h"
#include "hurricane/RoutingPad.h"
#include "hurricane/DataBase.h" #include "hurricane/DataBase.h"
#include "hurricane/Technology.h" #include "hurricane/Technology.h"
#include "anabatic/Edge.h" #include "anabatic/Edge.h"
@ -25,51 +24,11 @@
#include "anabatic/AnabaticEngine.h" #include "anabatic/AnabaticEngine.h"
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 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;
return (lhs->getId() < rhs->getId());
}
} // Anonymous namespace.
namespace Anabatic { namespace Anabatic {
using std::cerr; using std::cerr;
using std::endl; using std::endl;
using Hurricane::Error; using Hurricane::Error;
using Hurricane::RoutingPad;
Name Edge::_extensionName = "Anabatic::Edge"; Name Edge::_extensionName = "Anabatic::Edge";
@ -79,8 +38,7 @@ namespace Anabatic {
Edge::Edge ( GCell* source, GCell* target, Flags flags ) Edge::Edge ( GCell* source, GCell* target, Flags flags )
: Super(source->getCell()) : Super(source->getCell())
, _flags (flags|Flags::Invalidated) , _flags (flags|Flags::Invalidated)
, _capacities (NULL) , _capacity (0)
, _reservedCapacity (0)
, _realOccupancy (0) , _realOccupancy (0)
, _estimateOccupancy(0.0) , _estimateOccupancy(0.0)
, _historicCost (0.0) , _historicCost (0.0)
@ -146,7 +104,6 @@ namespace Anabatic {
void Edge::_preDestroy () void Edge::_preDestroy ()
{ {
_source->getAnabatic()->_unrefCapacity( _capacities );
_source->_remove( this, _flags|Flags::Source ); _source->_remove( this, _flags|Flags::Source );
_target->_remove( this, _flags|Flags::Target ); _target->_remove( this, _flags|Flags::Target );
@ -212,7 +169,7 @@ namespace Anabatic {
DbU::Unit dy = targetCenter.getY() - sourceCenter.getY(); DbU::Unit dy = targetCenter.getY() - sourceCenter.getY();
if (dx < 0) dx = -dx; if (dx < 0) dx = -dx;
//if (dx) dx += DbU::fromLambda( 0.1 ); if (dx) dx += DbU::fromLambda( 0.1 );
return dx + ((dy > 0) ? dy : -dy); return dx + ((dy > 0) ? dy : -dy);
} }
@ -222,18 +179,16 @@ namespace Anabatic {
{ {
unsigned int occupancy = 0; unsigned int occupancy = 0;
if ((int)_realOccupancy + delta > 0) occupancy = _realOccupancy + delta; if ((int)_realOccupancy + delta > 0) occupancy = _realOccupancy + delta;
if ((_realOccupancy <= getCapacity()) and (occupancy > getCapacity())) getAnabatic()->addOv ( this ); if ((_realOccupancy <= _capacity) and (occupancy > _capacity)) getAnabatic()->addOv ( this );
if ((_realOccupancy > getCapacity()) and (occupancy <= getCapacity())) getAnabatic()->removeOv( this ); if ((_realOccupancy > _capacity) and (occupancy <= _capacity)) getAnabatic()->removeOv( this );
_realOccupancy = occupancy; _realOccupancy = occupancy;
} }
void Edge::incRealOccupancy2 ( int value ) void Edge::incRealOccupancy2 ( int value )
{ {
_realOccupancy += value; _realOccupancy += value;
} }
Segment* Edge::getSegment ( const Net* owner ) const Segment* Edge::getSegment ( const Net* owner ) const
{ {
for ( Segment* segment : _segments ) { for ( Segment* segment : _segments ) {
@ -243,81 +198,16 @@ namespace Anabatic {
} }
bool Edge::isEnding ( Segment* segment ) const
{
cdebug_log(112,0) << "Edge::isEnding() " << this << endl;
cdebug_log(112,0) << "| Sbb " << _source->getBoundingBox() << endl;
cdebug_log(112,0) << "| Tbb " << _target->getBoundingBox() << endl;
cdebug_log(112,0) << "| " << segment << endl;
if (Session::getRoutingGauge()->isTwoMetals()) {
Contact* contact = dynamic_cast<Contact*>( segment->getSource() );
cdebug_log(112,0) << "| source" << contact << endl;
if (contact) {
if ( (_source->isStdCellRow() and _source->getBoundingBox().contains(contact->getCenter()))
or (_target->isStdCellRow() and _target->getBoundingBox().contains(contact->getCenter())) )
return true;
}
contact = dynamic_cast<Contact*>( segment->getTarget() );
cdebug_log(112,0) << "| target" << contact << endl;
if (contact) {
if ( (_source->isStdCellRow() and _source->getBoundingBox().contains(contact->getCenter()))
or (_target->isStdCellRow() and _target->getBoundingBox().contains(contact->getCenter())) )
return true;
}
} else {
// This part is not used (yet). We don't call isEnding() when running
// in over-the-cell mode.
Contact* contact = dynamic_cast<Contact*>( segment->getSource() );
cdebug_log(112,0) << "| source" << contact << endl;
if (contact) {
for ( Hook* hook : contact->getBodyHook()->getHooks() ) {
if (dynamic_cast<RoutingPad*>(hook->getComponent())) {
if ( _source->getBoundingBox().contains(contact->getCenter())
or _target->getBoundingBox().contains(contact->getCenter()) )
return true;
break;
}
}
}
contact = dynamic_cast<Contact*>( segment->getTarget() );
cdebug_log(112,0) << "| target" << contact << endl;
if (contact) {
for ( Hook* hook : contact->getBodyHook()->getHooks() ) {
if (dynamic_cast<RoutingPad*>(hook->getComponent())) {
if ( _source->getBoundingBox().contains(contact->getCenter())
or _target->getBoundingBox().contains(contact->getCenter()) )
return true;
break;
}
}
}
}
return false;
}
void Edge::add ( Segment* segment ) void Edge::add ( Segment* segment )
{ {
_segments.push_back( segment ); _segments.push_back( segment );
Horizontal* h = dynamic_cast<Horizontal*>(segment); Horizontal* h = dynamic_cast<Horizontal*>(segment);
Vertical* v = dynamic_cast<Vertical*>(segment); Vertical* v = dynamic_cast<Vertical*>(segment);
DbU::Unit pitch = 0; DbU::Unit pitch = 0;
if (h) pitch = Session::getGHorizontalPitch(); if (h) pitch = Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL2"));
if (v) pitch = Session::getGVerticalPitch(); if (v) pitch = Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL3"));
int deltaOccupancy = 0;
if (not Session::getRoutingGauge()->isTwoMetals()) deltaOccupancy = segment->getWidth()/pitch; incRealOccupancy( segment->getWidth()/pitch ); // Need to take the wire width into account.
else {
// In channel routing, do not increase edge occupancy on terminals,
// because the capacity has already been decreased in annotedGlobalGraph (Katana).
if (not isEnding(segment)) deltaOccupancy = segment->getWidth()/pitch;
}
incRealOccupancy( deltaOccupancy );
} }
@ -325,35 +215,12 @@ namespace Anabatic {
{ {
for ( size_t i=0 ; i<_segments.size() ; ++i ) { for ( size_t i=0 ; i<_segments.size() ; ++i ) {
if (_segments[i] == segment) { if (_segments[i] == segment) {
cdebug_log(110,0) << "On " << this << endl;
cdebug_log(110,0) << "| remove:" << segment << endl;
std::swap( _segments[i], _segments[_segments.size()-1] ); std::swap( _segments[i], _segments[_segments.size()-1] );
_segments.pop_back(); _segments.pop_back();
incRealOccupancy( -1 ); // Need to take the wire width into account.
Horizontal* h = dynamic_cast<Horizontal*>(segment);
Vertical* v = dynamic_cast<Vertical*>(segment);
DbU::Unit pitch = 0;
if (h) pitch = Session::getGHorizontalPitch();
if (v) pitch = Session::getGVerticalPitch();
int deltaOccupancy = 0;
if (not Session::getRoutingGauge()->isTwoMetals()) deltaOccupancy = segment->getWidth()/pitch;
else {
// In channel routing, do not increase edge occupancy on terminals,
// because the capacity has already been decreased in annotedGlobalGraph (Katana).
if (not isEnding(segment)) deltaOccupancy = segment->getWidth()/pitch;
}
incRealOccupancy( -deltaOccupancy );
return; return;
} }
} }
cerr << Error( "On %s,\n segment doesn't belong: %s"
, getString(this).c_str()
, getString(segment).c_str() ) << endl;
} }
@ -370,43 +237,19 @@ namespace Anabatic {
size_t Edge::ripup () size_t Edge::ripup ()
{ {
AnabaticEngine* anabatic = getAnabatic(); AnabaticEngine* anabatic = getAnabatic();
size_t netCount = 0; DbU::Unit globalThreshold = Session::getSliceHeight()*3;
size_t netCount = 0;
sort( _segments.begin(), _segments.end(), SortSegmentByLength(anabatic) ); for ( size_t i=0 ; i<_segments.size(); ) {
if (_segments[i]->getLength() >= globalThreshold) {
if (Session::getRoutingGauge()->isTwoMetals()) { NetData* netData = anabatic->getNetData( _segments[i]->getNet() );
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;
}
++i;
}
} else {
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; 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() );
// if (netData->isGlobalRouted()) ++netCount;
// anabatic->ripup( _segments[i], Flags::Propagate );
// } else {
// ++i;
// }
// }
}
anabatic->ripup( _segments[i], Flags::Propagate );
} else
++i;
}
return netCount; return netCount;
} }
@ -416,7 +259,7 @@ namespace Anabatic {
if (source == _target) if (source == _target)
throw Error("Edge::_setSource(): Source & target are the same (%s).", getString(source).c_str() ); throw Error("Edge::_setSource(): Source & target are the same (%s).", getString(source).c_str() );
invalidate( false ); _invalidate();
_source=source; _source=source;
} }
@ -426,41 +269,26 @@ namespace Anabatic {
if (_source == target) if (_source == target)
throw Error("Edge::_setTarget(): Source & target are the same (%s).", getString(target).c_str() ); throw Error("Edge::_setTarget(): Source & target are the same (%s).", getString(target).c_str() );
invalidate( false ); _invalidate();
_target=target; _target=target;
} }
void Edge::invalidate ( bool ) void Edge::_invalidate ()
{ {
cdebug_log(110,1) << "Edge::invalidate() " << this << endl;
_flags |= Flags::Invalidated; _flags |= Flags::Invalidated;
Super::invalidate( false ); Super::invalidate( false );
cdebug_tabw(110,-1);
} }
void Edge::materialize () void Edge::_revalidate ()
{ {
cdebug_log(110,1) << "Edge::materialize() " << this << endl; Interval side = getSide();
_axis = side.getCenter();
Flags flags = _flags; _capacity = getAnabatic()->getCapacity( side, _flags );
Interval side = getSide();
_axis = side.getCenter();
if (getSource()->isStdCellRow() and getTarget()->isStdCellRow()) flags |= Flags::NullCapacity;
else if (getSource()->isChannelRow() and getTarget()->isChannelRow()) flags |= Flags::InfiniteCapacity;
_capacities = getAnabatic()->_createCapacity( _flags, side );
_flags.reset( Flags::Invalidated ); _flags.reset( Flags::Invalidated );
cdebug_log(110,0) << "Edge::materialize() " << this << endl; cdebug_log(110,0) << "Edge::_revalidate() " << this << endl;
Super::materialize();
cdebug_tabw(110,-1);
} }
@ -473,31 +301,28 @@ namespace Anabatic {
static DbU::Unit halfThickness = getAnabatic()->getConfiguration()->getEdgeWidth () / 2; static DbU::Unit halfThickness = getAnabatic()->getConfiguration()->getEdgeWidth () / 2;
static DbU::Unit halfLength = getAnabatic()->getConfiguration()->getEdgeLength() / 2; static DbU::Unit halfLength = getAnabatic()->getConfiguration()->getEdgeLength() / 2;
Box bb;
if (_flags.isset(Flags::Horizontal)) if (_flags.isset(Flags::Horizontal))
bb = Box( _target->getXMin() - halfLength, _axis - halfThickness return Box( _target->getXMin() - halfLength, _axis - halfThickness
, _target->getXMin() + halfLength, _axis + halfThickness , _target->getXMin() + halfLength, _axis + halfThickness
); );
else
bb = Box( _axis - halfThickness, _target->getYMin() - halfLength return Box( _axis - halfThickness, _target->getYMin() - halfLength
, _axis + halfThickness, _target->getYMin() + halfLength , _axis + halfThickness, _target->getYMin() + halfLength
); );
return bb;
} }
bool Edge::isMaxCapacity ( Net* net ) const bool Edge::isMaxCapacity ( Net* net ) const
{ {
unsigned int wpitch = 0; if (net){
if (net) {
cdebug_log(112,0) << "_capacity:" << getCapacity() << endl;
Hurricane::NetRoutingState* state = Hurricane::NetRoutingExtension::get( net ); Hurricane::NetRoutingState* state = Hurricane::NetRoutingExtension::get( net );
wpitch = (state) ? state->getWPitch()-1 : 0; //cerr << "bool Edge::isMaxCapacity ( Net* net ) const: " << net << endl;
//cerr << "WPitch: " << state->getWPitch() << endl;
return ( (_realOccupancy +state->getWPitch()) > _capacity ) ? true : false;
} else {
return ( _realOccupancy >= _capacity ) ? true : false;
} }
return (_realOccupancy + wpitch >= getCapacity());
} }
@ -523,7 +348,7 @@ namespace Anabatic {
s.insert( s.size()-1, " " +DbU::getValueString(center.getY()) ); s.insert( s.size()-1, " " +DbU::getValueString(center.getY()) );
s.insert( s.size()-1, "] " +DbU::getValueString(_axis) ); s.insert( s.size()-1, "] " +DbU::getValueString(_axis) );
s.insert( s.size()-1, " " +getString(_realOccupancy) ); s.insert( s.size()-1, " " +getString(_realOccupancy) );
s.insert( s.size()-1, "/" +getString(getCapacity()) ); s.insert( s.size()-1, "/" +getString(_capacity) );
s.insert( s.size()-1, " h:" +getString(_historicCost) ); s.insert( s.size()-1, " h:" +getString(_historicCost) );
s.insert( s.size()-1, " " +getString(_flags) ); s.insert( s.size()-1, " " +getString(_flags) );
return s; return s;
@ -534,8 +359,7 @@ namespace Anabatic {
{ {
Record* record = Super::_getRecord(); Record* record = Super::_getRecord();
record->add( getSlot("_flags" , _flags ) ); record->add( getSlot("_flags" , _flags ) );
record->add( getSlot("_capacities" , _capacities ) ); record->add( getSlot("_capacity" , _capacity ) );
record->add( getSlot("_reservedCapacity" , _reservedCapacity ) );
record->add( getSlot("_realOccupancy" , _realOccupancy ) ); record->add( getSlot("_realOccupancy" , _realOccupancy ) );
record->add( getSlot("_estimateOccupancy", _estimateOccupancy) ); record->add( getSlot("_estimateOccupancy", _estimateOccupancy) );
record->add( getSlot("_source" , _source ) ); record->add( getSlot("_source" , _source ) );

View File

@ -1,123 +0,0 @@
// -*- mode: C++; explicit-buffer-name: "EdgeCapacity.cpp<anabatic>" -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2018-2018, 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 : "./EdgeCapacity.cpp" |
// +-----------------------------------------------------------------+
#include <sstream>
#include "anabatic/EdgeCapacity.h"
#include "anabatic/AnabaticEngine.h"
namespace Anabatic {
using std::ostringstream;
EdgeCapacity::EdgeCapacity ( AnabaticEngine* anabatic, Flags direction, Interval span, size_t depth )
: _anabatic (anabatic)
, _refCount (0)
, _flags (direction)
, _depth (depth+1)
, _span (span)
, _capacities()
{
int defcap = (_flags & Flags::InfiniteCapacity) ? 100 : 0;
_capacities.reserve( _depth );
for ( size_t i=0 ; i<_depth ; ++i ) _capacities.push_back( defcap );
if (_flags & (Flags::NullCapacity|Flags::InfiniteCapacity)) return;
Box ab = _anabatic->getCell()->getAbutmentBox();
RoutingGauge* rg = _anabatic->getConfiguration()->getRoutingGauge();
span = _span;
span.inflate( 0, -1 );
if (span.isEmpty()) return;
const vector<RoutingLayerGauge*>& layerGauges = rg->getLayerGauges();
for ( size_t depth=0 ; depth < _depth ; ++depth ) {
if (layerGauges[depth]->getType() != Constant::Default) continue;
if (_flags & Flags::Horizontal) {
if (layerGauges[depth]->getDirection() != Constant::Horizontal) continue;
_capacities[depth] = layerGauges[depth]->getTrackNumber( span.getVMin() - ab.getYMin()
, span.getVMax() - ab.getYMin() );
//cdebug_log(110,0) << "Horizontal edge capacity:" << capacity << endl;
}
if (_flags & Flags::Vertical) {
if (layerGauges[depth]->getDirection() != Constant::Vertical) continue;
_capacities[depth] = layerGauges[depth]->getTrackNumber( span.getVMin() - ab.getXMin()
, span.getVMax() - ab.getXMin() );
//cdebug_log(110,0) << "Vertical edge capacity:" << capacity << endl;
}
}
}
void EdgeCapacity::forceCapacity ( unsigned int capacity )
{
bool forced = false;
RoutingGauge* rg = _anabatic->getConfiguration()->getRoutingGauge();
const vector<RoutingLayerGauge*>& layerGauges = rg->getLayerGauges();
for ( size_t i=0 ; i<_depth ; ++i ) {
if (layerGauges[i]->getType() != Constant::Default) continue;
if ( (_flags & Flags::Horizontal) xor layerGauges[i]->isHorizontal() ) continue;
if (forced) _capacities[i] = 0;
else {
_capacities[i] = capacity;
forced = true;
}
}
}
string EdgeCapacity::_getString () const
{
ostringstream os;
os << "<EdgeCapacity ";
if (_flags & Flags::Horizontal) os << "Horizontal ";
else if (_flags & Flags::Vertical ) os << "Vertical ";
else os << "Unknown ";
os << "[" << DbU::getValueString(_span.getVMin())
<< " : " << DbU::getValueString(_span.getVMax())
<< "] " << getCapacity()
<< " refs:" << _refCount
<< ">";
return os.str();
}
Record* EdgeCapacity::_getRecord () const
{
Record* record = new Record( getString(this) );
record->add( getSlot( "_anabatic", _anabatic ) );
record->add( getSlot( "_refCount", _refCount ) );
record->add( getSlot( "_flags" , &_flags ) );
record->add( getSlot( "_span" , &_span ) );
RoutingGauge* rg = getAnabatic()->getConfiguration()->getRoutingGauge();
for ( size_t depth=0 ; depth<_depth ; ++depth ) {
ostringstream s;
const Layer* layer = rg->getRoutingLayer(depth);
s << "_capacities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
record->add( getSlot ( s.str(), _capacities[depth] ) );
}
return record;
}
} // Anabatic namespace.

View File

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "Edges.cpp<anabatic>" -*- // -*- mode: C++; explicit-buffer-name: "Edges.cpp<anabatic>" -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2018, All Rights Reserved // Copyright (c) UPMC 2016-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -20,7 +20,6 @@
namespace Anabatic { namespace Anabatic {
using std::cerr;
using std::endl; using std::endl;
@ -64,10 +63,10 @@ namespace Anabatic {
{ {
cdebug_log(110,0) << "GCell_Edges::Locator::progress() [from] " << _stateFlags << " iedge:" << _iedge << endl; cdebug_log(110,0) << "GCell_Edges::Locator::progress() [from] " << _stateFlags << " iedge:" << _iedge << endl;
cdebug_log(110,0) << " _filterFlags:" << _filterFlags << endl; cdebug_log(110,0) << " _filterFlags:" << _filterFlags << endl;
cdebug_log(110,0) << " East:" << _gcell->getEastEdges ().size() cdebug_log(110,0) << " East:" << _gcell->getEastEdges().size()
<< " North:" << _gcell->getNorthEdges().size() << " North:" << _gcell->getNorthEdges().size()
<< " West:" << _gcell->getWestEdges ().size() << " West:" << _gcell->getWestEdges().size()
<< " South:" << _gcell->getSouthEdges().size() << endl; << " South:" << _gcell->getSouthEdges().size() << endl;
cdebug_log(110,0) << this << endl; cdebug_log(110,0) << this << endl;
++_iedge; ++_iedge;
@ -75,7 +74,7 @@ namespace Anabatic {
if (_stateFlags.contains(Flags::EastSide)) { if (_stateFlags.contains(Flags::EastSide)) {
if ( (_iedge < _gcell->getEastEdges().size()) if ( (_iedge < _gcell->getEastEdges().size())
and _filterFlags.contains(Flags::EastSide)) break; and _filterFlags.contains(Flags::EastSide)) break;
//cdebug_log(110,0) << "Switching to North side." << endl; // cdebug_log(110,0) << "Switching to North side." << endl;
_stateFlags = Flags::NorthSide; _stateFlags = Flags::NorthSide;
_iedge = 0; _iedge = 0;
// cdebug_log(110,0) << this << endl; // cdebug_log(110,0) << this << endl;
@ -84,7 +83,7 @@ namespace Anabatic {
if (_stateFlags.contains(Flags::NorthSide)) { if (_stateFlags.contains(Flags::NorthSide)) {
if ( (_iedge < _gcell->getNorthEdges().size()) if ( (_iedge < _gcell->getNorthEdges().size())
and _filterFlags.contains(Flags::NorthSide)) break; and _filterFlags.contains(Flags::NorthSide)) break;
//cdebug_log(110,0) << "Switching to West side." << endl; // cdebug_log(110,0) << "Switching to West side." << endl;
_stateFlags = Flags::WestSide; _stateFlags = Flags::WestSide;
_iedge = 0; _iedge = 0;
// cdebug_log(110,0) << this << endl; // cdebug_log(110,0) << this << endl;
@ -93,7 +92,7 @@ namespace Anabatic {
if (_stateFlags.contains(Flags::WestSide)) { if (_stateFlags.contains(Flags::WestSide)) {
if ( (_iedge < _gcell->getWestEdges().size()) if ( (_iedge < _gcell->getWestEdges().size())
and _filterFlags.contains(Flags::WestSide)) break; and _filterFlags.contains(Flags::WestSide)) break;
//cdebug_log(110,0) << "Switching to South side." << endl; // cdebug_log(110,0) << "Switching to South side." << endl;
_stateFlags = Flags::SouthSide; _stateFlags = Flags::SouthSide;
_iedge = 0; _iedge = 0;
continue; continue;
@ -101,7 +100,7 @@ namespace Anabatic {
if (_stateFlags.contains(Flags::SouthSide)) { if (_stateFlags.contains(Flags::SouthSide)) {
if ( (_iedge < _gcell->getSouthEdges().size()) if ( (_iedge < _gcell->getSouthEdges().size())
and _filterFlags.contains(Flags::SouthSide)) break; and _filterFlags.contains(Flags::SouthSide)) break;
//cdebug_log(110,0) << "All edges done." << endl; // cdebug_log(110,0) << "All edges done." << endl;
_stateFlags = 0; _stateFlags = 0;
_iedge = 0; _iedge = 0;
break;; break;;
@ -142,144 +141,4 @@ namespace Anabatic {
} }
// -------------------------------------------------------------------
// Class : "Anabatic::Path_Edges".
Path_Edges::Locator::Locator ( const GCell* source, const GCell* target, Flags pathFlags )
: EdgesHL()
, _source (source)
, _target (target)
, _stateFlags(Flags::NoFlags)
, _uprobe (0)
, _edge (NULL)
{
if (_source == _target) return;
Interval hoverlap = _source->getHSide().getIntersection( _target->getHSide() );
Interval voverlap = _source->getVSide().getIntersection( _target->getVSide() );
if (not voverlap.isEmpty()) {
if (_source->getXMin() > _target->getXMin()) std::swap( _source, _target );
_stateFlags |= Flags::EastSide;
_uprobe = voverlap.getCenter();
} else if (not hoverlap.isEmpty()) {
if (_source->getYMin() > _target->getYMin()) std::swap( _source, _target );
_stateFlags |= Flags::NorthSide;
_uprobe = hoverlap.getCenter();
} else {
if (_source->getXMin() > _target->getXMin()) {
std::swap( _source, _target );
}
if (_source->getYMin() < _target->getYMin()) {
if (pathFlags & Flags::NorthPath) {
_stateFlags |= Flags::NorthSide;
_uprobe = _source->getXCenter();
} else {
_stateFlags |= Flags::EastSide;
_uprobe = _source->getYCenter();
}
} else {
if (pathFlags & Flags::NorthPath) {
_stateFlags |= Flags::EastSide;
_uprobe = _source->getYCenter();
} else {
_stateFlags |= Flags::SouthSide;
_uprobe = _source->getXCenter();
}
}
}
_edge = _source->getEdgeAt( _stateFlags, _uprobe );
}
EdgesHL* Path_Edges::Locator::getClone () const
{ return new Locator (*this); }
Edge* Path_Edges::Locator::getElement () const
{ return _edge; }
bool Path_Edges::Locator::isValid () const
{ return (_edge != NULL); }
void Path_Edges::Locator::progress ()
{
if (not _edge) return;
GCell* neighbor = NULL;
if (_stateFlags.contains(Flags::SouthSide) or _stateFlags.contains(Flags::WestSide)) neighbor = _edge->getSource();
if (_stateFlags.contains(Flags::NorthSide) or _stateFlags.contains(Flags::EastSide)) neighbor = _edge->getTarget();
if (neighbor == _target) { _edge = NULL; return; }
if (_stateFlags.contains(Flags::EastSide)) {
Interval overlap = neighbor->getHSide().getIntersection( _target->getHSide() );
if (not overlap.isEmpty()) {
overlap = neighbor->getVSide().getIntersection( _target->getVSide() );
if (not overlap.isEmpty()) { _edge = NULL; return; }
_stateFlags.reset( Flags::EastSide );
_stateFlags |= (_target->getYMin() < _source->getYMin()) ? Flags::SouthSide
: Flags::NorthSide;
_uprobe = overlap.getCenter();
}
} else if (_stateFlags.contains(Flags::SouthSide)) {
Interval overlap = neighbor->getVSide().getIntersection( _target->getVSide() );
if (not overlap.isEmpty()) {
overlap = neighbor->getHSide().getIntersection( _target->getHSide() );
if (not overlap.isEmpty()) {
_edge = NULL; return; }
_stateFlags.reset( Flags::SouthSide );
_stateFlags |= Flags::EastSide;
_uprobe = overlap.getCenter();
}
} else if (_stateFlags.contains(Flags::NorthSide)) {
Interval overlap = neighbor->getVSide().getIntersection( _target->getVSide() );
if (not overlap.isEmpty()) {
overlap = neighbor->getHSide().getIntersection( _target->getHSide() );
if (not overlap.isEmpty()) { _edge = NULL; return; }
_stateFlags.reset( Flags::NorthSide );
_stateFlags |= Flags::EastSide;
_uprobe = overlap.getCenter();
}
}
_edge = neighbor->getEdgeAt( _stateFlags, _uprobe );
}
string Path_Edges::Locator::_getString () const
{
string s = "<Path_Edges::Locator @" + getString(_edge) + ">";
return s;
}
EdgesHC* Path_Edges::getClone () const
{ return new Path_Edges( *this ); }
EdgesHL* Path_Edges::getLocator () const
{ return new Locator (_source,_target,_pathFlags); }
string Path_Edges::_getString () const
{
string s = "<Path_Edges from:"
+ getString(_source) + "to:"
+ getString(_target)
+ ">";
return s;
}
} // Anabatic namespace. } // Anabatic namespace.

View File

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "GCell.cpp<anabatic>" -*- // -*- mode: C++; explicit-buffer-name: "GCell.cpp<anabatic>" -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2018, All Rights Reserved // Copyright (c) UPMC 2016-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -55,7 +55,7 @@ namespace {
private: private:
class AxisCompare { class AxisCompare {
public: 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> { 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; if (lhs->getAxis () < rhs->getAxis ()) return true;
return false; 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); float difference = lhs->getDensity(_depth) - rhs->getDensity(_depth);
if (difference != 0.0) return (difference > 0.0); if (difference != 0.0) return (difference > 0.0);
@ -273,8 +273,6 @@ namespace Anabatic {
Name GCell::_extensionName = "Anabatic::GCell"; Name GCell::_extensionName = "Anabatic::GCell";
uint32_t GCell::_displayMode = GCell::Boundary; uint32_t GCell::_displayMode = GCell::Boundary;
DbU::Unit GCell::_matrixHSide = 0;
DbU::Unit GCell::_matrixVSide = 0;
uint32_t GCell::getDisplayMode () { return _displayMode; } uint32_t GCell::getDisplayMode () { return _displayMode; }
@ -285,7 +283,7 @@ namespace Anabatic {
: Super(anabatic->getCell()) : Super(anabatic->getCell())
, _observable () , _observable ()
, _anabatic (anabatic) , _anabatic (anabatic)
, _flags (Flags::Invalidated) , _flags (Flags::HChannelGCell|Flags::Invalidated)
, _westEdges () , _westEdges ()
, _eastEdges () , _eastEdges ()
, _southEdges () , _southEdges ()
@ -298,8 +296,6 @@ namespace Anabatic {
, _contacts () , _contacts ()
, _depth (Session::getRoutingGauge()->getDepth()) , _depth (Session::getRoutingGauge()->getDepth())
, _pinDepth (0) , _pinDepth (0)
, _satProcessed (0)
, _rpCount (0)
, _blockages (new DbU::Unit [_depth]) , _blockages (new DbU::Unit [_depth])
, _cDensity (0.0) , _cDensity (0.0)
, _densities (new float [_depth]) , _densities (new float [_depth])
@ -307,16 +303,7 @@ namespace Anabatic {
, _fragmentations(new float [_depth]) , _fragmentations(new float [_depth])
, _globalsCount (new float [_depth]) , _globalsCount (new float [_depth])
, _key (this,1) , _key (this,1)
, _lastClonedKey (NULL)
{ {
if (not _matrixHSide) {
_matrixVSide = Session::getSliceHeight();
_matrixHSide = Session::getSliceHeight();
if (_matrixHSide % Session::getSliceStep())
_matrixHSide += Session::getSliceStep() - _matrixHSide % Session::getSliceStep();
}
for ( size_t i=0 ; i<_depth ; i++ ) { for ( size_t i=0 ; i<_depth ; i++ ) {
_blockages [i] = 0; _blockages [i] = 0;
_densities [i] = 0.0; _densities [i] = 0.0;
@ -344,13 +331,13 @@ namespace Anabatic {
if (not anabatic) throw Error( "GCell::create(): NULL anabatic argument." ); if (not anabatic) throw Error( "GCell::create(): NULL anabatic argument." );
if (not anabatic->getCell()) throw Error( "GCell::create(): AnabaticEngine has no Cell loaded." ); if (not anabatic->getCell()) throw Error( "GCell::create(): AnabaticEngine has no Cell loaded." );
bool reUseSession = Session::isOpen(); anabatic->openSession();
if (not reUseSession) anabatic->openSession();
GCell* gcell = new GCell ( anabatic GCell* gcell = new GCell ( anabatic
, anabatic->getCell()->getAbutmentBox().getXMin() , anabatic->getCell()->getAbutmentBox().getXMin()
, anabatic->getCell()->getAbutmentBox().getYMin() ); , anabatic->getCell()->getAbutmentBox().getYMin() );
gcell->_postCreate(); gcell->_postCreate();
if (not reUseSession) Session::close(); gcell->_revalidate();
Session::close();
return gcell; return gcell;
} }
@ -460,14 +447,6 @@ namespace Anabatic {
} }
bool GCell::isHorizontalPlane ( size_t depth ) const
{ return _anabatic->getConfiguration()->getLayerGauge(depth)->isHorizontal(); }
bool GCell::isVerticalPlane ( size_t depth ) const
{ return _anabatic->getConfiguration()->getLayerGauge(depth)->isVertical(); }
Contact* GCell::hasGContact ( const Net* net ) const Contact* GCell::hasGContact ( const Net* net ) const
{ {
for ( Contact* contact : _gcontacts ) { for ( Contact* contact : _gcontacts ) {
@ -477,26 +456,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 Contact* GCell::hasGContact ( const Contact* owned ) const
{ {
for ( Contact* contact : _gcontacts ) { for ( Contact* contact : _gcontacts ) {
@ -508,9 +467,6 @@ namespace Anabatic {
Contact* GCell::breakGoThrough ( Net* net ) Contact* GCell::breakGoThrough ( Net* net )
{ {
Contact* gcontact = hasGContact( net );
if (gcontact) return gcontact;
for ( Edge* edge : _eastEdges ) { for ( Edge* edge : _eastEdges ) {
for ( Segment* segment : edge->getSegments() ) { for ( Segment* segment : edge->getSegments() ) {
if (segment->getNet() == net) if (segment->getNet() == net)
@ -525,22 +481,6 @@ namespace Anabatic {
} }
} }
return getGContact( net );
}
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; return NULL;
} }
@ -558,49 +498,13 @@ namespace Anabatic {
{ {
for ( Edge* edge : getEdges(sideHint) ) { for ( Edge* edge : getEdges(sideHint) ) {
GCell* side = edge->getOpposite(this); GCell* side = edge->getOpposite(this);
if ( (sideHint.contains(Flags::WestSide) or sideHint.contains(Flags::EastSide )) if ( (sideHint & (Flags::WestSide |Flags::EastSide )) and (u < side->getYMax()) ) return edge;
and (u < side->getYMax()) ) { if ( (sideHint & (Flags::SouthSide|Flags::NorthSide)) and (u < side->getXMax()) ) return edge;
cdebug_log(112,0) << "H Opposite @" << DbU::getValueString(u) << " is: " << side << endl;
return edge;
}
if ( (sideHint.contains(Flags::SouthSide) or sideHint.contains(Flags::NorthSide))
and (u < side->getXMax()) ) {
cdebug_log(112,0) << "V Opposite @" << DbU::getValueString(u) << " is: " << side << endl;
return edge;
}
} }
return NULL; return NULL;
} }
GCell* GCell::getEastNMatrix() const
{
if (!this->getEast()->isMatrix()) return this->getEast();
else {
GCell* gcell = this->getEast();
while(gcell->getEast()){
if (!gcell->getEast()->isMatrix()) break;
else gcell = gcell->getEast();
}
return gcell->getEast();
}
}
GCell* GCell::getNorthNMatrix() const
{
if (!this->getNorth()->isMatrix()) return this->getNorth();
else {
GCell* gcell = this->getNorth();
while(gcell->getNorth()){
if (!gcell->getNorth()->isMatrix()) break;
else gcell = gcell->getNorth();
}
return gcell->getNorth();
}
}
GCell* GCell::getWest ( DbU::Unit y ) const GCell* GCell::getWest ( DbU::Unit y ) const
{ {
for ( Edge* edge : _westEdges ) { for ( Edge* edge : _westEdges ) {
@ -655,6 +559,8 @@ namespace Anabatic {
{ {
const GCell* current = this; const GCell* current = this;
if (not this) cerr << Error("*this* is NULL!") << endl;
while ( current ) { while ( current ) {
if (not current->isFlat() and current->getBoundingBox().contains(x,y)) break; if (not current->isFlat() and current->getBoundingBox().contains(x,y)) break;
@ -727,17 +633,15 @@ namespace Anabatic {
size_t iedge = 0; size_t iedge = 0;
for ( ; (iedge < _southEdges.size()) ; ++iedge ) { for ( ; (iedge < _southEdges.size()) ; ++iedge ) {
cdebug_log(110,0) << "[" << iedge << "] xmax of:" cdebug_log(110,0) << "[" << iedge << "] xmax of:"
<< _southEdges[iedge]->getOpposite(this) << _southEdges[iedge]->getOpposite(this)
<< " " << _southEdges[iedge] << endl; << " " << _southEdges[iedge] << endl;
if (x <= _southEdges[iedge]->getOpposite(this)->getXMax()) break; if (x <= _southEdges[iedge]->getOpposite(this)->getXMax()) break;
} }
if ( (x < _southEdges[iedge]->getOpposite(this)->getXMax()) if ( (x < _southEdges[iedge]->getOpposite(this)->getXMax())
or ( (x == _southEdges[iedge]->getOpposite(this)->getXMax()) or ( (x == _southEdges[iedge]->getOpposite(this)->getXMax())
and (chunk->getXMax() == getXMax())) ) { and (chunk->getXMax() == getXMax())) )
Edge::create( _southEdges[iedge]->getOpposite(this), chunk, Flags::Vertical ); Edge::create( _southEdges[iedge]->getOpposite(this), chunk, Flags::Vertical );
_southEdges[iedge]->invalidate( false );
}
_moveEdges( chunk, iedge+1, Flags::SouthSide ); _moveEdges( chunk, iedge+1, Flags::SouthSide );
} }
@ -751,14 +655,15 @@ namespace Anabatic {
if ( (x < _northEdges[iedge]->getOpposite(this)->getXMax()) if ( (x < _northEdges[iedge]->getOpposite(this)->getXMax())
or ( (x == _northEdges[iedge]->getOpposite(this)->getXMax()) or ( (x == _northEdges[iedge]->getOpposite(this)->getXMax())
and (chunk->getXMax() == getXMax())) ) { and (chunk->getXMax() == getXMax())) )
Edge::create( chunk, _northEdges[iedge]->getOpposite(this), Flags::Vertical ); Edge::create( chunk, _northEdges[iedge]->getOpposite(this), Flags::Vertical );
_northEdges[iedge]->invalidate( false );
}
_moveEdges( chunk, iedge+1, Flags::NorthSide ); _moveEdges( chunk, iedge+1, Flags::NorthSide );
} }
_revalidate();
chunk->_revalidate();
cdebug_tabw(110,-1); cdebug_tabw(110,-1);
return chunk; return chunk;
@ -789,10 +694,8 @@ namespace Anabatic {
if ( (y < _westEdges[iedge]->getOpposite(this)->getYMax()) if ( (y < _westEdges[iedge]->getOpposite(this)->getYMax())
or ( (y == _westEdges[iedge]->getOpposite(this)->getYMax()) or ( (y == _westEdges[iedge]->getOpposite(this)->getYMax())
and (chunk->getYMax() == getYMax())) ) { and (chunk->getYMax() == getYMax())) )
Edge::create( _westEdges[iedge]->getOpposite(this), chunk, Flags::Horizontal ); Edge::create( _westEdges[iedge]->getOpposite(this), chunk, Flags::Horizontal );
_westEdges[iedge]->invalidate( false );
}
_moveEdges( chunk, iedge+1, Flags::WestSide ); _moveEdges( chunk, iedge+1, Flags::WestSide );
} }
@ -804,14 +707,15 @@ namespace Anabatic {
if ( (y < _eastEdges[iedge]->getOpposite(this)->getYMax()) if ( (y < _eastEdges[iedge]->getOpposite(this)->getYMax())
or ( (y == _eastEdges[iedge]->getOpposite(this)->getYMax()) or ( (y == _eastEdges[iedge]->getOpposite(this)->getYMax())
and (chunk->getYMax() == getYMax())) ) { and (chunk->getYMax() == getYMax())) )
Edge::create( chunk, _eastEdges[iedge]->getOpposite(this), Flags::Horizontal ); Edge::create( chunk, _eastEdges[iedge]->getOpposite(this), Flags::Horizontal );
_eastEdges[iedge]->invalidate( false );
}
_moveEdges( chunk, iedge+1, Flags::EastSide ); _moveEdges( chunk, iedge+1, Flags::EastSide );
} }
_revalidate();
chunk->_revalidate();
cdebug_tabw(110,-1); cdebug_tabw(110,-1);
return chunk; return chunk;
@ -820,49 +724,47 @@ namespace Anabatic {
bool GCell::doGrid () bool GCell::doGrid ()
{ {
bool openSession = Session::isOpen(); getAnabatic()->openSession();
if (not openSession) getAnabatic()->openSession();
DbU::Unit vside = getMatrixVSide(); DbU::Unit side = Session::getSliceHeight();
DbU::Unit hside = getMatrixHSide();
Interval hspan = getSide( Flags::Horizontal ); Interval hspan = getSide( Flags::Horizontal );
Interval vspan = getSide( Flags::Vertical ); Interval vspan = getSide( Flags::Vertical );
// if (hspan.getSize() < 2*hside) { if (hspan.getSize() < 3*side) {
// cerr << Error( "GCell::doGrid(): GCell is too narrow (dx:%s) to build a grid.\n" cerr << Error( "GCell::doGrid(): GCell is too narrow (dx:%s) to build a grid.\n"
// " (%s)" " (%s)"
// , DbU::getValueString(hspan.getSize()).c_str() , DbU::getValueString(hspan.getSize()).c_str()
// , getString(this).c_str() , getString(this).c_str()
// ) << endl; ) << endl;
// Session::close(); Session::close();
// return false; return false;
// } }
// if (vspan.getSize() < 2*vside) { if (vspan.getSize() < 3*side) {
// cerr << Error( "GCell::doGrid(): GCell is too narrow (dy:%s) to build a grid.\n" cerr << Error( "GCell::doGrid(): GCell is too narrow (dy:%s) to build a grid.\n"
// " (%s)" " (%s)"
// , DbU::getValueString(vspan.getSize()).c_str() , DbU::getValueString(vspan.getSize()).c_str()
// , getString(this).c_str() , getString(this).c_str()
// ) << endl; ) << endl;
// return false; return false;
// } }
GCell* row = this; GCell* row = this;
GCell* column = NULL; GCell* column = NULL;
DbU::Unit ycut = vspan.getVMin()+vside; DbU::Unit ycut = vspan.getVMin()+side;
for ( ; ycut < vspan.getVMax() ; ycut += vside ) { for ( ; ycut < vspan.getVMax() ; ycut += side ) {
column = row; column = row;
row = row->hcut( ycut ); row = row->hcut( ycut );
row->setType( Flags::MatrixGCell ); row->setType( Flags::MatrixGCell );
for ( DbU::Unit xcut = hspan.getVMin()+hside ; xcut < hspan.getVMax() ; xcut += hside ) { for ( DbU::Unit xcut = hspan.getVMin()+side ; xcut < hspan.getVMax() ; xcut += side ) {
column = column->vcut( xcut ); column = column->vcut( xcut );
column->setType( Flags::MatrixGCell ); column->setType( Flags::MatrixGCell );
} }
} }
column = row; column = row;
for ( DbU::Unit xcut = hspan.getVMin()+hside ; xcut < hspan.getVMax() ; xcut += hside ) { for ( DbU::Unit xcut = hspan.getVMin()+side ; xcut < hspan.getVMax() ; xcut += side ) {
column = column->vcut( xcut ); column = column->vcut( xcut );
column->setType( Flags::MatrixGCell ); column->setType( Flags::MatrixGCell );
} }
@ -880,39 +782,26 @@ namespace Anabatic {
// } // }
//} //}
if (not openSession) Session::close(); Session::close();
return true; return true;
} }
void GCell::invalidate ( bool propagateFlag ) void GCell::_revalidate ()
{ {
cdebug_log(110,1) << "GCell::invalidate() " << this << endl; cdebug_log(110,1) << "GCell::revalidate() " << this << endl;
Super::invalidate( propagateFlag ); cdebug_log(110,1) << "West side." << endl; for ( Edge* edge : _westEdges ) edge->revalidate(); cdebug_tabw(110,-1);
_flags |= Flags::Invalidated; cdebug_log(110,1) << "East side." << endl; for ( Edge* edge : _eastEdges ) edge->revalidate(); cdebug_tabw(110,-1);
cdebug_log(110,1) << "South side." << endl; for ( Edge* edge : _southEdges ) edge->revalidate(); cdebug_tabw(110,-1);
cdebug_log(110,1) << "West side." << endl; for ( Edge* edge : _westEdges ) edge->invalidate(); cdebug_tabw(110,-1); cdebug_log(110,1) << "North side." << endl; for ( Edge* edge : _northEdges ) edge->revalidate(); cdebug_tabw(110,-1);
cdebug_log(110,1) << "East side." << endl; for ( Edge* edge : _eastEdges ) edge->invalidate(); cdebug_tabw(110,-1);
cdebug_log(110,1) << "South side." << endl; for ( Edge* edge : _southEdges ) edge->invalidate(); cdebug_tabw(110,-1);
cdebug_log(110,1) << "North side." << endl; for ( Edge* edge : _northEdges ) edge->invalidate(); cdebug_tabw(110,-1);
cdebug_tabw(110,-1);
}
void GCell::materialize ()
{
cdebug_log(110,1) << "GCell::materialize() " << this << endl;
if (_xmin > getXMax()+1) if (_xmin > getXMax()+1)
cerr << Error( "GCell::materialize(): %s, X Min is greater than Max.", getString(this).c_str() ); cerr << Error( "GCell::_revalidate(): %s, X Min is greater than Max.", getString(this).c_str() );
if (_ymin > getYMax()+1) if (_ymin > getYMax()+1)
cerr << Error( "GCell::materialize(): %s, Y Min is greater than Max.", getString(this).c_str() ); cerr << Error( "GCell::_revalidate(): %s, Y Min is greater than Max.", getString(this).c_str() );
_anabatic->_updateLookup( this ); _anabatic->_updateLookup( this );
//_anabatic->getMatrix()->show(); //_anabatic->getMatrix()->show();
Super::materialize();
cdebug_tabw(110,-1); cdebug_tabw(110,-1);
} }
@ -1009,52 +898,36 @@ namespace Anabatic {
} }
void GCell::setSouthWestCorner ( DbU::Unit x, DbU::Unit y ) void GCell::setXY ( DbU::Unit x, DbU::Unit y )
{ {
//DbU::Unit dx = x - _xmin; UpdateSession::open();
//DbU::Unit dy = y - _ymin;
/*for ( Contact* contact : _gcontacts ) {
Point position = contact->getPosition().translate( dx, dy );
for ( Component* component : contact->getSlaveComponents() ) {
Horizontal* horizontal = dynamic_cast<Horizontal*>( component );
if (horizontal) {
horizontal->setY( position.getY() );
} else {
Vertical* vertical = dynamic_cast<Vertical*>( component );
vertical->setX( position.getX() );
}
}
if (not contact->getAnchor()) contact->setPosition( Point(x,y) );
}*/
_xmin = x; _xmin = x;
_ymin = y; _ymin = y;
UpdateSession::close();
invalidate( false );
} }
void GCell::updateGContacts ( Flags flags ) void GCell::updateContactsPosition ()
{ {
Point center ( _xmin+getWidth()/2, _ymin+getHeight()/2 ); UpdateSession::open();
DbU::Unit xc = (getXMax() + getXMin())/2;
for ( Contact* contact : _gcontacts ) { DbU::Unit yc = (getYMax() + getYMin())/2;
for ( Component* component : contact->getSlaveComponents() ) { for (vector<Contact*>::iterator it = _gcontacts.begin(); it != _gcontacts.end(); it++){
Horizontal* horizontal = dynamic_cast<Horizontal*>( component ); for ( Component* c : (*it)->getSlaveComponents() ){
if (horizontal and (flags & Flags::Vertical)) { Horizontal* h = dynamic_cast<Horizontal*>(c);
horizontal->setY( center.getY() ); Vertical* v = dynamic_cast<Vertical*> (c);
} else { if (h){
Vertical* vertical = dynamic_cast<Vertical*>( component ); //if (h->getY() == (*it)->getY()) h->setY(yc);
if (vertical and (flags & Flags::Horizontal)) { h->setY(yc);
vertical->setX( center.getX() ); } else if (v) {
} //if (v->getX() == (*it)->getX()) v->setX(xc);
v->setX(xc);
} }
} }
if (not contact->getAnchor()) contact->setPosition( center ); (*it)->setX(xc);
(*it)->setY(yc);
} }
UpdateSession::close();
} }
@ -1091,7 +964,7 @@ namespace Anabatic {
if (_gcontacts[i] == unref) { if (_gcontacts[i] == unref) {
if (_gcontacts[i]->getSlaveComponents().getLocator()->isValid()) return false; if (_gcontacts[i]->getSlaveComponents().getLocator()->isValid()) return false;
cdebug_log(112,0) << " Effective destroy " << (void*)unref << endl; cdebug_log(112,0) << " Effective destroy." << endl;
std::swap( _gcontacts[i], _gcontacts[_gcontacts.size()-1] ); std::swap( _gcontacts[i], _gcontacts[_gcontacts.size()-1] );
_gcontacts[ _gcontacts.size()-1 ]->destroy(); _gcontacts[ _gcontacts.size()-1 ]->destroy();
_gcontacts.pop_back(); _gcontacts.pop_back();
@ -1227,7 +1100,7 @@ namespace Anabatic {
} }
int GCell::getHCapacity () const float GCell::getHCapacity () const
{ {
int capacity = 0; int capacity = 0;
if (not _eastEdges.empty()) { if (not _eastEdges.empty()) {
@ -1235,11 +1108,11 @@ namespace Anabatic {
} else { } else {
for ( Edge* edge : _westEdges ) capacity += edge->getCapacity(); for ( Edge* edge : _westEdges ) capacity += edge->getCapacity();
} }
return capacity; return (float)capacity;
} }
int GCell::getVCapacity () const float GCell::getVCapacity () const
{ {
int capacity = 0; int capacity = 0;
if (not _northEdges.empty()) { if (not _northEdges.empty()) {
@ -1247,20 +1120,7 @@ namespace Anabatic {
} else { } else {
for ( Edge* edge : _southEdges ) capacity += edge->getCapacity(); for ( Edge* edge : _southEdges ) capacity += edge->getCapacity();
} }
return capacity; return (float)capacity;
}
int GCell::getCapacity ( size_t depth ) const
{
const vector<Edge*>* edges = NULL;
if (isHorizontalPlane(depth)) edges = (_eastEdges .empty()) ? &_westEdges : &_eastEdges;
else edges = (_northEdges.empty()) ? &_southEdges : &_northEdges;
int capacity = 0;
for ( Edge* edge : *edges ) capacity += edge->getCapacity(depth);
return capacity;
} }
@ -1283,8 +1143,8 @@ namespace Anabatic {
float vdensity = 0.0; float vdensity = 0.0;
for ( size_t i=_pinDepth ; i<_depth ; i++ ) { for ( size_t i=_pinDepth ; i<_depth ; i++ ) {
if (isHorizontalPlane(i)) { hdensity += _densities[i]; ++hplanes; } if ( i%2 ) { hdensity += _densities[i]; ++hplanes; }
else { vdensity += _densities[i]; ++vplanes; } else { vdensity += _densities[i]; ++vplanes; }
} }
if (hplanes) hdensity /= hplanes; if (hplanes) hdensity /= hplanes;
@ -1309,7 +1169,7 @@ namespace Anabatic {
float hdensity = 0.0; float hdensity = 0.0;
for ( size_t i=_pinDepth ; i<_depth ; i++ ) { for ( size_t i=_pinDepth ; i<_depth ; i++ ) {
if (isHorizontalPlane(i)) { hdensity += _densities[i]; ++hplanes; } if (i%2) { hdensity += _densities[i]; ++hplanes; }
} }
if (hplanes) hdensity /= hplanes; if (hplanes) hdensity /= hplanes;
@ -1319,7 +1179,7 @@ namespace Anabatic {
float vdensity = 0.0; float vdensity = 0.0;
for ( size_t i=_pinDepth ; i<_depth ; i++ ) { for ( size_t i=_pinDepth ; i<_depth ; i++ ) {
if (isVerticalPlane(i)) { vdensity += _densities[i]; ++vplanes; } if (i%2 == 0) { vdensity += _densities[i]; ++vplanes; }
} }
if (vplanes) vdensity /= vplanes; if (vplanes) vdensity /= vplanes;
@ -1331,11 +1191,11 @@ namespace Anabatic {
} }
} else if (getAnabatic()->getDensityMode() == MaxHDensity) { } else if (getAnabatic()->getDensityMode() == MaxHDensity) {
for ( size_t i=_pinDepth ; i<_depth ; i++ ) { for ( size_t i=_pinDepth ; i<_depth ; i++ ) {
if (isHorizontalPlane(i) and (_densities[i] > density)) density = _densities[i]; if ((i%2) and (_densities[i] > density)) density = _densities[i];
} }
} else if (getAnabatic()->getDensityMode() == MaxVDensity) { } else if (getAnabatic()->getDensityMode() == MaxVDensity) {
for ( size_t i=_pinDepth ; i<_depth ; i++ ) { for ( size_t i=_pinDepth ; i<_depth ; i++ ) {
if (isVerticalPlane(i) and (_densities[i] > density)) density = _densities[i]; if ((i%2 == 0) and (_densities[i] > density)) density = _densities[i];
} }
} }
@ -1343,26 +1203,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 ) void GCell::addBlockage ( size_t depth, DbU::Unit length )
{ {
if (depth >= _depth) return; if (depth >= _depth) return;
@ -1370,7 +1210,7 @@ namespace Anabatic {
_blockages[depth] += length; _blockages[depth] += length;
_flags |= Flags::Invalidated; _flags |= Flags::Invalidated;
cdebug_log(149,0) << "GCell::addBlockage() " << this << " " cdebug_log(149,0) << "GCell:addBlockage() " << this << " "
<< depth << ":" << DbU::getValueString(_blockages[depth]) << endl; << depth << ":" << DbU::getValueString(_blockages[depth]) << endl;
} }
@ -1391,7 +1231,6 @@ namespace Anabatic {
if (found) { if (found) {
cdebug_log(149,0) << "remove " << ac << " from " << this << endl; cdebug_log(149,0) << "remove " << ac << " from " << this << endl;
_contacts.pop_back(); _contacts.pop_back();
_flags |= Flags::Invalidated;
} else { } else {
cerr << Bug("%p:%s do not belong to %s." cerr << Bug("%p:%s do not belong to %s."
,ac->base(),getString(ac).c_str(),_getString().c_str()) << endl; ,ac->base(),getString(ac).c_str(),_getString().c_str()) << endl;
@ -1405,17 +1244,11 @@ namespace Anabatic {
size_t begin = 0; size_t begin = 0;
for ( ; begin < end ; begin++ ) { 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] ); 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) { 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; , getString(segment).c_str(), _getString().c_str() ) << endl;
return; return;
} }
@ -1425,7 +1258,6 @@ namespace Anabatic {
, _getString().c_str(), getString(segment).c_str() ) << endl; , _getString().c_str(), getString(segment).c_str() ) << endl;
_hsegments.erase( _hsegments.begin() + end, _hsegments.end() ); _hsegments.erase( _hsegments.begin() + end, _hsegments.end() );
_flags |= Flags::Invalidated;
} }
@ -1451,7 +1283,6 @@ namespace Anabatic {
, getString(segment).c_str() ) << endl; , getString(segment).c_str() ) << endl;
_vsegments.erase( _vsegments.begin() + end, _vsegments.end() ); _vsegments.erase( _vsegments.begin() + end, _vsegments.end() );
_flags |= Flags::Invalidated;
} }
@ -1465,45 +1296,57 @@ namespace Anabatic {
_flags.reset( Flags::Saturated ); _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( _hsegments.begin(), _hsegments.end(), AutoSegment::CompareByDepthLength() );
sort( _vsegments.begin(), _vsegments.end(), AutoSegment::CompareByDepthLength() ); sort( _vsegments.begin(), _vsegments.end(), AutoSegment::CompareByDepthLength() );
float ccapacity = getHCapacity() * getVCapacity() * (_depth-_pinDepth); float hcapacity = getHCapacity ();
DbU::Unit width = getXMax() - getXMin(); float vcapacity = getVCapacity ();
DbU::Unit height = getYMax() - getYMin(); float ccapacity = hcapacity * vcapacity * 4;
DbU::Unit hpenalty = 0 /*_box.getWidth () / 3*/; DbU::Unit width = getXMax() - getXMin();
DbU::Unit vpenalty = 0 /*_box.getHeight() / 3*/; DbU::Unit height = getYMax() - getYMin();
DbU::Unit uLengths1 [ _depth ]; DbU::Unit hpenalty = 0 /*_box.getWidth () / 3*/;
DbU::Unit uLengths2 [ _depth ]; DbU::Unit vpenalty = 0 /*_box.getHeight() / 3*/;
float localCounts [ _depth ]; DbU::Unit uLengths1 [ _depth ];
vector<UsedFragments> ufragments ( _depth ); DbU::Unit uLengths2 [ _depth ];
float localCounts [ _depth ];
vector<UsedFragments> ufragments ( _depth );
for ( size_t i=0 ; i<_depth ; i++ ) { for ( size_t i=0 ; i<_depth ; i++ ) {
ufragments[i].setPitch ( Session::getPitch(i) ); ufragments[i].setPitch ( Session::getPitch(i) );
_feedthroughs[i] = 0.0; _feedthroughs[i] = 0.0;
uLengths1 [i] = 0;
uLengths2 [i] = 0; uLengths2 [i] = 0;
localCounts [i] = 0.0; localCounts [i] = 0.0;
_globalsCount[i] = 0.0; _globalsCount[i] = 0.0;
ufragments[i].setCapacity( (size_t)getCapacity(i) ); if (Session::getDirection(i) & Flags::Horizontal) {
if (isHorizontalPlane(i)) ufragments[i].setSpan( getXMin(), getXMax() ); ufragments[i].setSpan ( getXMin(), getXMax() );
else ufragments[i].setSpan( getYMin(), getYMax() ); ufragments[i].setCapacity( (size_t)hcapacity );
} else {
ufragments[i].setSpan ( getYMin(), getYMax() );
ufragments[i].setCapacity( (size_t)vcapacity );
}
} }
// Compute wirelength associated to contacts (in DbU::Unit converted to float). // Compute wirelength associated to contacts (in DbU::Unit converted to float).
AutoSegment::DepthLengthSet processeds; AutoSegment::DepthLengthSet processeds;
for ( AutoContact* contact : _contacts ) { for ( AutoContact* contact : _contacts ) {
for ( size_t i=0 ; i<_depth ; i++ ) uLengths1[i] = 0; for ( size_t i=0 ; i<_depth ; i++ ) uLengths1[i] = 0;
contact->getLengths( uLengths1, processeds ); contact->getLengths ( uLengths1, processeds );
for ( size_t i=0 ; i<_depth ; i++ ) { for ( size_t i=0 ; i<_depth ; i++ ) {
if (isHorizontalPlane(i)) uLengths2[i] += uLengths1[i]+hpenalty; if (Session::getDirection(i) & Flags::Horizontal)
else uLengths2[i] += uLengths1[i]+vpenalty; uLengths2[i] += uLengths1[i]+hpenalty;
else
uLengths2[i] += uLengths1[i]+vpenalty; break;
} }
} }
// Add the "pass through" horizontal segments. // Add the "pass through" horizontal segments.
if (not _hsegments.empty()) { if ( _hsegments.size() ) {
const Layer* layer = _hsegments[0]->getLayer(); const Layer* layer = _hsegments[0]->getLayer();
size_t depth = Session::getRoutingGauge()->getLayerDepth(layer); size_t depth = Session::getRoutingGauge()->getLayerDepth(layer);
size_t count = 0; size_t count = 0;
@ -1527,7 +1370,7 @@ namespace Anabatic {
} }
// Add the "pass through" vertical segments. // Add the "pass through" vertical segments.
if (not _vsegments.empty()) { if ( _vsegments.size() ) {
const Layer* layer = _vsegments[0]->getLayer(); const Layer* layer = _vsegments[0]->getLayer();
size_t depth = Session::getRoutingGauge()->getLayerDepth(layer); size_t depth = Session::getRoutingGauge()->getLayerDepth(layer);
size_t count = 0; size_t count = 0;
@ -1535,7 +1378,7 @@ namespace Anabatic {
_globalsCount[depth] += 1.0; _globalsCount[depth] += 1.0;
ufragments[depth].incGlobals(); ufragments[depth].incGlobals();
if (layer != _vsegments[i]->getLayer()) { if ( layer != _vsegments[i]->getLayer() ) {
uLengths2[depth] += count * height; uLengths2[depth] += count * height;
count = 0; count = 0;
@ -1545,43 +1388,25 @@ namespace Anabatic {
count++; count++;
_feedthroughs[depth] += 1.0; _feedthroughs[depth] += 1.0;
} }
if (count) { if ( count ) {
uLengths2[depth] += count * height; uLengths2[depth] += count * height;
} }
} }
// Add the blockages. // Add the blockages.
if (isStdCellRow() or isChannelRow()) { for ( size_t i=0 ; i<_depth ; i++ ) {
flags().reset( Flags::GoStraight ); uLengths2[i] += _blockages[i];
} 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;
}
} }
// Compute the number of non pass-through tracks. // Compute the number of non pass-through tracks.
if (not processeds.empty()) { if (processeds.size()) {
AutoSegment::DepthLengthSet::iterator isegment = processeds.begin(); AutoSegment::DepthLengthSet::iterator isegment = processeds.begin();
const Layer* layer = (*isegment)->getLayer(); const Layer* layer = (*isegment)->getLayer();
DbU::Unit axis = (*isegment)->getAxis(); DbU::Unit axis = (*isegment)->getAxis();
size_t depth = Session::getRoutingGauge()->getLayerDepth(layer); size_t depth = Session::getRoutingGauge()->getLayerDepth(layer);
size_t count = 0; size_t count = 0;
for ( ; isegment != processeds.end(); ++isegment ) { for ( ; isegment != processeds.end(); ++isegment ) {
//_feedthroughs[depth] += ((*isegment)->isGlobal()) ? 0.50 : 0.33; _feedthroughs[depth] += ((*isegment)->isGlobal()) ? 0.50 : 0.33;
_feedthroughs[depth] += 0.50;
localCounts [depth] += 1.0; localCounts [depth] += 1.0;
if ( (*isegment)->isGlobal() ) _globalsCount[depth] += 1.0; if ( (*isegment)->isGlobal() ) _globalsCount[depth] += 1.0;
@ -1598,11 +1423,9 @@ namespace Anabatic {
// Normalize: 0 < d < 1.0 (divide by H/V capacity). // Normalize: 0 < d < 1.0 (divide by H/V capacity).
for ( size_t i=0 ; i<_depth ; i++ ) { for ( size_t i=0 ; i<_depth ; i++ ) {
int capacity = getCapacity(i);
if (Session::getDirection(i) & Flags::Horizontal) { if (Session::getDirection(i) & Flags::Horizontal) {
if (width and capacity) { if (width) {
_densities [i] = ((float)uLengths2[i]) / (float)( capacity * width ); _densities [i] = ((float)uLengths2[i]) / ( hcapacity * (float)width );
_feedthroughs [i] += (float)(_blockages[i] / width); _feedthroughs [i] += (float)(_blockages[i] / width);
_fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)width; _fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)width;
} else { } else {
@ -1611,8 +1434,8 @@ namespace Anabatic {
_fragmentations[i] = 0; _fragmentations[i] = 0;
} }
} else { } else {
if (height and capacity) { if (height) {
_densities [i] = ((float)uLengths2[i]) / (float)( capacity * height ); _densities [i] = ((float)uLengths2[i]) / ( vcapacity * (float)height );
_feedthroughs [i] += (float)(_blockages[i] / height); _feedthroughs [i] += (float)(_blockages[i] / height);
_fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)height; _fragmentations[i] = (float)ufragments[i].getMaxFree().getSize() / (float)height;
} else { } else {
@ -1625,8 +1448,10 @@ namespace Anabatic {
if (_densities[i] >= 1.0) _flags |= Flags::Saturated; if (_densities[i] >= 1.0) _flags |= Flags::Saturated;
} }
if (ccapacity) _cDensity = ( (float)_contacts.size() ) / ccapacity; if (ccapacity)
else _cDensity = 0; _cDensity = ( (float)_contacts.size() ) / ccapacity;
else
_cDensity = 0;
_flags.reset( Flags::Invalidated ); _flags.reset( Flags::Invalidated );
checkDensity(); checkDensity();
@ -1637,16 +1462,17 @@ namespace Anabatic {
void GCell::truncDensities () void GCell::truncDensities ()
{ {
Box bBox = getBoundingBox(); int hcapacity = (int)getHCapacity();
int vcapacity = (int)getVCapacity();
Box bBox = getBoundingBox();
for ( size_t i=0 ; i<_depth ; i++ ) { for ( size_t i=0 ; i<_depth ; i++ ) {
int capacity = getCapacity(i); if (Session::getDirection(i) & Flags::Horizontal) {
if (isHorizontalPlane(i)) { if (_blockages[i] > hcapacity * bBox.getWidth())
if (_blockages[i] > capacity * bBox.getWidth()) _blockages[i] = hcapacity * bBox.getWidth();
_blockages[i] = capacity * bBox.getWidth();
} else { } else {
if (_blockages[i] > capacity * bBox.getHeight()) if (_blockages[i] > vcapacity * bBox.getHeight())
_blockages[i] = capacity * bBox.getHeight(); _blockages[i] = vcapacity * bBox.getHeight();
} }
} }
_flags &= ~Flags::Saturated; _flags &= ~Flags::Saturated;
@ -1682,31 +1508,20 @@ namespace Anabatic {
{ {
if (isInvalidated()) const_cast<GCell*>(this)->updateDensity(); if (isInvalidated()) const_cast<GCell*>(this)->updateDensity();
float capacity = getCapacity(depth); float capacity = 0.0;
if (Session::getDirection(depth) & Flags::Horizontal) capacity = getHCapacity();
else capacity = getVCapacity();
cdebug_log(149,0) << " | hasFreeTrack [" << getId() << "] depth:" << depth << " " cdebug_log(149,0) << " | hasFreeTrack [" << getId() << "] depth:" << depth << " "
<< Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << Session::getRoutingGauge()->getRoutingLayer(depth)->getName()
//<< " " << (_densities[depth]*capacity) << " vs. " << capacity //<< " " << (_densities[depth]*capacity) << " vs. " << capacity
<< " " << _feedthroughs[depth] << " vs. " << capacity << " " << _feedthroughs[depth] << " vs. " << capacity
<< " " << this << endl; << " " << this << endl;
return (_feedthroughs[depth] + 0.99 + reserve <= capacity); return (_feedthroughs[depth] + 0.99 + reserve <= capacity);
} }
size_t GCell::getNetCount () const
{
set<Net*> nets;
for ( Edge* edge : _westEdges ) for ( Segment* segment : edge->getSegments() ) nets.insert( segment->getNet() );
for ( Edge* edge : _eastEdges ) for ( Segment* segment : edge->getSegments() ) nets.insert( segment->getNet() );
for ( Edge* edge : _northEdges ) for ( Segment* segment : edge->getSegments() ) nets.insert( segment->getNet() );
for ( Edge* edge : _southEdges ) for ( Segment* segment : edge->getSegments() ) nets.insert( segment->getNet() );
return nets.size();
}
void GCell::rpDesaturate ( set<Net*>& globalNets ) void GCell::rpDesaturate ( set<Net*>& globalNets )
{ {
set<RoutingPad*> rps; set<RoutingPad*> rps;
@ -1819,7 +1634,7 @@ namespace Anabatic {
bool GCell::stepNetDesaturate ( size_t depth, set<Net*>& globalNets, GCell::Set& invalidateds ) 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; cdebug_log(9000,0) << "Deter| " << this << endl;
updateDensity(); updateDensity();
@ -1841,7 +1656,7 @@ namespace Anabatic {
if (segmentDepth < depth) continue; if (segmentDepth < depth) continue;
if (segmentDepth > depth) break; 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)) if (getAnabatic()->moveUpNetTrunk(*isegment,globalNets,invalidateds))
return true; return true;
@ -1849,18 +1664,18 @@ namespace Anabatic {
return false; return false;
} }
void GCell::forceEdgesCapacities ( unsigned int hcapacity, unsigned int vcapacity )
void GCell::setEdgesOccupancy ( unsigned int width, unsigned int height )
{ {
if (getEastEdge() ) getEastEdge ()->forceCapacity( hcapacity ); getEastEdge()->setCapacity(width);
if (getWestEdge() ) getWestEdge ()->forceCapacity( hcapacity ); getWestEdge()->setCapacity(width);
if (getNorthEdge()) getNorthEdge()->forceCapacity( vcapacity ); getNorthEdge()->setCapacity(height);
if (getSouthEdge()) getSouthEdge()->forceCapacity( vcapacity ); getSouthEdge()->setCapacity(height);
if (getEastEdge() ) getEastEdge ()->setRealOccupancy(0); getEastEdge()->setRealOccupancy(0);
if (getWestEdge() ) getWestEdge ()->setRealOccupancy(0); getWestEdge()->setRealOccupancy(0);
if (getNorthEdge()) getNorthEdge()->setRealOccupancy(0); getNorthEdge()->setRealOccupancy(0);
if (getSouthEdge()) getSouthEdge()->setRealOccupancy(0); getSouthEdge()->setRealOccupancy(0);
} }
@ -1873,13 +1688,6 @@ namespace Anabatic {
string s = Super::_getString(); string s = Super::_getString();
s.insert( s.size()-1, " "+getString(getBoundingBox()) ); s.insert( s.size()-1, " "+getString(getBoundingBox()) );
s.insert( s.size()-1, " "+getString(_flags) ); 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())
+ "-" + DbU::getValueString(getYMax())
+ "-" + DbU::getValueString(getHeight())
+ "-" + DbU::getValueString(getWidth()) + ")";*/
return s; return s;
} }
@ -1894,7 +1702,6 @@ namespace Anabatic {
record->add( getSlot("_northEdges" , &_northEdges) ); record->add( getSlot("_northEdges" , &_northEdges) );
record->add( DbU::getValueSlot("_xmin", &_xmin) ); record->add( DbU::getValueSlot("_xmin", &_xmin) );
record->add( DbU::getValueSlot("_ymin", &_ymin) ); record->add( DbU::getValueSlot("_ymin", &_ymin) );
record->add( getSlot ( "_gcontacts", &_gcontacts ) );
record->add( getSlot ( "_vsegments", &_vsegments ) ); record->add( getSlot ( "_vsegments", &_vsegments ) );
record->add( getSlot ( "_hsegments", &_hsegments ) ); record->add( getSlot ( "_hsegments", &_hsegments ) );
record->add( getSlot ( "_contacts" , &_contacts ) ); record->add( getSlot ( "_contacts" , &_contacts ) );
@ -1906,7 +1713,7 @@ namespace Anabatic {
ostringstream s; ostringstream s;
const Layer* layer = rg->getRoutingLayer(depth)->getBlockageLayer(); const Layer* layer = rg->getRoutingLayer(depth)->getBlockageLayer();
s << "_blockages[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]"; 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 ) { for ( size_t depth=0 ; depth<_depth ; ++depth ) {
@ -1915,13 +1722,6 @@ namespace Anabatic {
s << "_densities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]"; s << "_densities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
record->add( getSlot ( s.str(), &_densities[depth] ) ); 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; return record;
} }

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2018, All Rights Reserved // Copyright (c) UPMC 2008-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -31,288 +31,11 @@
#include "hurricane/Horizontal.h" #include "hurricane/Horizontal.h"
#include "hurricane/Cell.h" #include "hurricane/Cell.h"
#include "crlcore/RoutingGauge.h" #include "crlcore/RoutingGauge.h"
#include "anabatic/AutoContactTerminal.h" #include "anabatic/AutoContact.h"
#include "anabatic/AutoSegment.h" #include "anabatic/AutoSegment.h"
#include "anabatic/AnabaticEngine.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 { namespace Anabatic {
using Hurricane::DebugSession; using Hurricane::DebugSession;
@ -336,58 +59,9 @@ namespace Anabatic {
cmess1 << " o Desaturate layer " cmess1 << " o Desaturate layer "
<< Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << endl; << 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() ); GCellDensitySet queue ( depth, getGCells() );
GCell::Set invalidateds; GCell::Set invalidateds;
bool optimized = true; bool optimized = true;
while ( optimized ) { while ( optimized ) {
@ -399,7 +73,7 @@ namespace Anabatic {
size_t i = 0; size_t i = 0;
for ( ; igcell!=queue.getGCells().end() ; ++igcell, ++i ) { for ( ; igcell!=queue.getGCells().end() ; ++igcell, ++i ) {
cdebug_log(149,0) << "_desaturate: [" << depth << "]:" cdebug_log(149,0) << "_desaturate: [" << depth << "]:"
<< (*igcell)->getDensity(depth) << " " << *igcell << endl; << (*igcell)->getDensity(depth) << " " << *igcell << endl;
if (not (*igcell)->isSaturated(depth)) { if (not (*igcell)->isSaturated(depth)) {
cdebug_log(149,0) << "STOP desaturated: @" << i << " " << *igcell << endl; cdebug_log(149,0) << "STOP desaturated: @" << i << " " << *igcell << endl;
@ -421,7 +95,6 @@ namespace Anabatic {
} }
} }
} }
#endif
} }
@ -444,14 +117,8 @@ namespace Anabatic {
} }
global++; global++;
if ((*isegment)->getLayer() == Session::getRoutingLayer(1)) { if ((*isegment)->getLayer() == Session::getRoutingLayer(1)) (*isegment)->setLayer( Session::getRoutingLayer(3) );
(*isegment)->setLayer( Session::getRoutingLayer(3) ); if ((*isegment)->getLayer() == Session::getRoutingLayer(2)) (*isegment)->setLayer( Session::getRoutingLayer(4) );
(*isegment)->setWidth( Session::getWireWidth (3) );
}
if ((*isegment)->getLayer() == Session::getRoutingLayer(2)) {
(*isegment)->setLayer( Session::getRoutingLayer(4) );
(*isegment)->setWidth( Session::getWireWidth (4) );
}
} }
} }
@ -475,7 +142,7 @@ namespace Anabatic {
void AnabaticEngine::_layerAssignByTrunk ( Net* net, set<Net*>& globalNets, unsigned long& total, unsigned long& global ) void AnabaticEngine::_layerAssignByTrunk ( Net* net, set<Net*>& globalNets, unsigned long& total, unsigned long& global )
{ {
DebugSession::open( net, 145, 150 ); DebugSession::open( net, 140, 150 );
cdebug_log(149,0) << "Anabatic::_layerAssignByTrunk ( " << net << " )" << endl; cdebug_log(149,0) << "Anabatic::_layerAssignByTrunk ( " << net << " )" << endl;
cdebug_tabw(145,1); cdebug_tabw(145,1);
@ -505,14 +172,8 @@ namespace Anabatic {
netGlobal++; netGlobal++;
cdebug_log(145,0) << "Migrate to M4/M5: " << autoSegment << endl; cdebug_log(145,0) << "Migrate to M4/M5: " << autoSegment << endl;
if (autoSegment->isHorizontal()) { if (autoSegment->isHorizontal()) autoSegment->setLayer( Session::getRoutingLayer(3) );
autoSegment->setLayer( Session::getRoutingLayer(3) ); if (autoSegment->isVertical ()) autoSegment->setLayer( Session::getRoutingLayer(4) );
autoSegment->setWidth( Session::getWireWidth (3) );
}
if (autoSegment->isVertical()) {
autoSegment->setLayer( Session::getRoutingLayer(4) );
autoSegment->setWidth( Session::getWireWidth (4) );
}
} }
} }
} }
@ -538,125 +199,11 @@ namespace Anabatic {
} }
void AnabaticEngine::_layerAssignNoGlobalM2V ( Net* net, set<Net*>& globalNets, unsigned long& total, unsigned long& global )
{
cdebug_log(149,0) << "Anabatic::_layerAssignNoGlobalM2V ( " << net << " )" << endl;
cdebug_tabw(145,1);
bool isGlobalNet = false;
unsigned long netGlobal = 0;
unsigned long netTotal = 0;
set<AutoContact*> globalContacts;
for ( Segment* baseSegment : net->getSegments() ) {
++netTotal;
AutoSegment* segment = Session::lookup( baseSegment );
if (not segment or segment->isLocal()) continue;
isGlobalNet = true;
netTotal = 0;
globalNets.insert( net );
break;
}
if (isGlobalNet) {
vector<AutoSegment*> horizontals;
for ( Segment* baseSegment : net->getSegments() ) {
AutoSegment* segment = Session::lookup( baseSegment );
if (not segment or not segment->isCanonical()) continue;
if (segment->isHorizontal()) horizontals.push_back( segment );
}
for ( AutoSegment* horizontal : horizontals ) {
vector<AutoSegment*> collapseds;
vector< tuple<AutoSegment*,Flags> > perpandicularsDatas;
//vector<AutoSegment*> northBounds;
//vector<AutoSegment*> southBounds;
DbU::Unit leftBound;
DbU::Unit rightBound;
//bool hasNorth = false;
//bool hasSouth = false;
AutoSegment::getTopologicalInfos( horizontal
, collapseds
, perpandicularsDatas
, leftBound
, rightBound
);
for ( auto perpandicularDatas : perpandicularsDatas ) {
AutoSegment* perpandicular = std::get<0>( perpandicularDatas );
if (Session::getLayerDepth(perpandicular->getLayer()) > 2) continue;
bool hasGlobal = false;
for ( AutoSegment* aligned : perpandicular->getAligneds(Flags::NoCheckLayer|Flags::WithSelf) ) {
if (aligned->isGlobal()) { hasGlobal = true; break; }
}
if (not hasGlobal) continue;
// if (perpandicular->getSourceY() == horizontal->getAxis()) {
// hasNorth = true;
// if (hasGlobal) northBounds.push_back( perpandicular );
// } else {
// hasSouth = true;
// if (hasGlobal) southBounds.push_back( perpandicular );
// }
if ( perpandicular->getAutoSource()->getGCell()->getNorth()
!= perpandicular->getAutoTarget()->getGCell()) {
perpandicular->changeDepth( 3, Flags::Propagate );
++netGlobal;
continue;
}
}
// if (hasSouth and hasNorth) {
// if (not northBounds.empty()) {
// for ( AutoSegment* perpandicular : northBounds )
// perpandicular->changeDepth( 3, Flags::Propagate );
// } else {
// for ( AutoSegment* perpandicular : southBounds )
// perpandicular->changeDepth( 3, Flags::Propagate );
// }
// }
}
}
total += netTotal;
global += netGlobal;
cdebug_tabw(145,-1);
}
void AnabaticEngine::_layerAssignNoGlobalM2V ( unsigned long& total, unsigned long& global, set<Net*>& globalNets )
{
cmess1 << " o Assign Layer (no global vertical metal2)." << endl;
for ( Net* net : getCell()->getNets() ) {
DebugSession::open( net, 145, 150 );
NetRoutingState* state = NetRoutingExtension::get( net );
if (not state or state->isAutomaticGlobalRoute()) {
_layerAssignNoGlobalM2V( net, globalNets, total, global );
} else {
cdebug_log(145,0) << net << " is not automatic routed, skipped." << endl;
}
DebugSession::close();
}
}
#if THIS_IS_DISABLED #if THIS_IS_DISABLED
void AnabaticEngine::moveULeft ( AutoSegment* seed, set<Net*>& globalNets, GCell::Set& invalidateds ) void AnabaticEngine::moveULeft ( AutoSegment* seed, set<Net*>& globalNets, GCell::Set& invalidateds )
{ {
Net* net = seed->getNet(); Net* net = seed->getNet();
DebugSession::open( net, 145, 150 ); DebugSession::open( net, 140, 150 );
cdebug_log(9000,0) << "Deter| Move left: " << seed << endl; cdebug_log(9000,0) << "Deter| Move left: " << seed << endl;
@ -693,7 +240,7 @@ namespace Anabatic {
void AnabaticEngine::moveURight ( AutoSegment* seed, set<Net*>& globalNets, GCell::Set& invalidateds ) void AnabaticEngine::moveURight ( AutoSegment* seed, set<Net*>& globalNets, GCell::Set& invalidateds )
{ {
Net* net = seed->getNet(); Net* net = seed->getNet();
DebugSession::open( net, 145, 150 ); DebugSession::open( net, 140, 150 );
cdebug_log(9000,0) << "Deter| Move right: " << seed << endl; cdebug_log(9000,0) << "Deter| Move right: " << seed << endl;
@ -733,7 +280,7 @@ namespace Anabatic {
Net* net = seed->getNet(); Net* net = seed->getNet();
unsigned int seedDepth = Session::getRoutingGauge()->getLayerDepth(seed->getLayer()); unsigned int seedDepth = Session::getRoutingGauge()->getLayerDepth(seed->getLayer());
DebugSession::open( net, 145, 150 ); DebugSession::open( net, 140, 150 );
cdebug_log(9000,0) << "Deter| moveUpNetTrunk() depth:" << seedDepth << " " << seed << endl; cdebug_log(9000,0) << "Deter| moveUpNetTrunk() depth:" << seedDepth << " " << seed << endl;
if (not seed->canMoveUp( 1.0, Flags::Propagate|Flags::AllowTerminal|Flags::NoCheckLayer) ) { if (not seed->canMoveUp( 1.0, Flags::Propagate|Flags::AllowTerminal|Flags::NoCheckLayer) ) {
@ -759,7 +306,7 @@ namespace Anabatic {
if (not segment->isStrongTerminal()) locals.push_back( segment ); if (not segment->isStrongTerminal()) locals.push_back( segment );
continue; continue;
} }
if ( (segment->getAnchoredLength() < 3*Session::getSliceHeight()) and (segment != seed) ) { if ( (segment->getLength() < 3*Session::getSliceHeight()) and (segment != seed) ) {
locals.push_back( segment ); locals.push_back( segment );
continue; continue;
} }
@ -835,7 +382,7 @@ namespace Anabatic {
cmess1 << " o Balance Global Density " cmess1 << " o Balance Global Density "
<< Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << endl; << Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << endl;
GCellDensitySet queue ( depth, getGCells() ); GCellDensitySet queue ( depth, getGCells()) );
GCell::Set invalidateds; GCell::Set invalidateds;
bool optimized = true; bool optimized = true;
@ -927,8 +474,6 @@ namespace Anabatic {
void AnabaticEngine::layerAssign ( uint32_t method ) void AnabaticEngine::layerAssign ( uint32_t method )
{ {
//DebugSession::open( 145, 150 );
cdebug_log(9000,0) << "Deter| Layer Assignment" << endl; cdebug_log(9000,0) << "Deter| Layer Assignment" << endl;
set<Net*> globalNets; set<Net*> globalNets;
@ -941,9 +486,8 @@ namespace Anabatic {
if (Session::getAllowedDepth() >= 3) { if (Session::getAllowedDepth() >= 3) {
switch ( method ) { switch ( method ) {
case EngineLayerAssignByLength: _layerAssignByLength ( total, global, globalNets ); break; case EngineLayerAssignByLength: _layerAssignByLength( total, global, globalNets ); break;
case EngineLayerAssignByTrunk: _layerAssignByTrunk ( total, global, globalNets ); break; case EngineLayerAssignByTrunk: _layerAssignByTrunk ( total, global, globalNets ); break;
case EngineLayerAssignNoGlobalM2V: _layerAssignNoGlobalM2V ( total, global, globalNets ); break;
case EngineNoNetLayerAssign: break; case EngineNoNetLayerAssign: break;
default: default:
stopMeasures(); stopMeasures();
@ -958,13 +502,12 @@ namespace Anabatic {
globalNets.clear(); globalNets.clear();
Session::revalidate(); Session::revalidate();
if ( (method != EngineLayerAssignNoGlobalM2V) if (getConfiguration()->getAllowedDepth() > 2) {
and (getConfiguration()->getAllowedDepth() > 2) ) {
for ( size_t depth=1 ; depth <= getConfiguration()->getAllowedDepth()-2; ++depth ) { for ( size_t depth=1 ; depth <= getConfiguration()->getAllowedDepth()-2; ++depth ) {
_desaturate( depth, globalNets, total, global ); _desaturate( depth, globalNets, total, global );
if ( (depth > 1) and ((depth-1)%2 == 1) ) Session::revalidate(); if ( (depth > 1) and ((depth-1)%2 == 1) ) Session::revalidate();
} }
globalNets.clear (); globalNets.clear ();
Session::revalidate(); Session::revalidate();
} }
@ -975,54 +518,6 @@ namespace Anabatic {
Session::setAnabaticFlags( Flags::WarnOnGCellOverload ); 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(); checkGCellDensities();
Session::close(); Session::close();
@ -1034,8 +529,6 @@ namespace Anabatic {
// cmess2 << " - Global segments : " << global << endl; // cmess2 << " - Global segments : " << global << endl;
// cmess2 << " - Ratio : " // cmess2 << " - Ratio : "
// << ((float)global/(float)total)*100.0 << "%." << endl; // << ((float)global/(float)total)*100.0 << "%." << endl;
//DebugSession::close();
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "Matrix.cpp<anabatic>" -*- // -*- mode: C++; explicit-buffer-name: "Matrix.cpp<anabatic>" -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2018, All Rights Reserved // Copyright (c) UPMC 2016-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -78,10 +78,8 @@ namespace Anabatic {
int index = xy2maxIndex(x,y); int index = xy2maxIndex(x,y);
cdebug_log(110,0) << "Matrix::getUnder() (" cdebug_log(110,0) << "Matrix::getUnder() ("
<< DbU::getValueString(x) << " " << DbU::getValueString(x) << " "
<< DbU::getValueString(y) << ") index:" << index << DbU::getValueString(y) << ") index:" << index << endl;
<< " " << ((index < 0) ? NULL : _gcells[index]->getUnder(x,y)) << endl;
return (index < 0) ? NULL : _gcells[index]->getUnder(x,y); return (index < 0) ? NULL : _gcells[index]->getUnder(x,y);
} }
@ -119,7 +117,7 @@ namespace Anabatic {
DbU::Unit dy = updateArea.getYMin() - _area.getYMin(); DbU::Unit dy = updateArea.getYMin() - _area.getYMin();
cdebug_log(110,0) << "raw_i:" << (dx / _side + ((dx%_side) ? 1 : 0)) cdebug_log(110,0) << "raw_i:" << (dx / _side + ((dx%_side) ? 1 : 0))
<< " raw_j:" << (dy / _side + ((dy%_side) ? 1 : 0)) << endl; << " raw_j:" << (dy / _side + ((dy%_side) ? 1 : 0)) << endl;
cdebug_log(110,0) << "indexMin:" << indexMin << endl; cdebug_log(110,0) << "indexMin:" << indexMin << endl;
cdebug_log(110,0) << "indexMax:" << indexMax << endl; cdebug_log(110,0) << "indexMax:" << indexMax << endl;
cdebug_log(110,0) << "xspan: " << xspan << endl; cdebug_log(110,0) << "xspan: " << xspan << endl;
@ -140,13 +138,6 @@ namespace Anabatic {
} }
void Matrix::resize ( Cell* cell, const vector<GCell*>& gcells )
{
setCell( cell, _side );
for ( GCell* gcell : gcells ) updateLookup( gcell );
}
void Matrix::show () const void Matrix::show () const
{ {
cdebug_log(111,0) << this << endl; cdebug_log(111,0) << this << endl;

File diff suppressed because it is too large Load Diff

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

@ -1,356 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2018, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | A n a b a t i c - Routing Toolbox |
// | |
// | Author : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./NetBuilderM2.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/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/NetBuilderM2.h"
#include "anabatic/AnabaticEngine.h"
namespace Anabatic {
using std::swap;
NetBuilderM2::NetBuilderM2 ()
: NetBuilder()
{ }
NetBuilderM2::~NetBuilderM2 () { }
string NetBuilderM2::getStyle ()
{ return "2RL-"; }
void NetBuilderM2::doRp_AutoContacts ( GCell* gcell
, Component* rp
, AutoContact*& source
, AutoContact*& target
, uint64_t flags
)
{
cdebug_log(145,1) << "NetBuilderM2::doRp_AutoContacts()" << endl;
cdebug_log(145,0) << rp << endl;
source = target = NULL;
Point sourcePosition;
Point targetPosition;
const Layer* rpLayer = rp->getLayer();
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
Flags direction = Session::getDirection ( rpDepth );
DbU::Unit viaSide = Session::getViaWidth ( rpDepth );
getPositions( rp, sourcePosition, targetPosition );
if (sourcePosition.getX() > targetPosition.getX()) swap( sourcePosition, targetPosition );
if (sourcePosition.getY() > targetPosition.getY()) swap( sourcePosition, targetPosition );
GCell* sourceGCell = Session::getAnabatic()->getGCellUnder( sourcePosition );
GCell* targetGCell = Session::getAnabatic()->getGCellUnder( targetPosition );
if (rpDepth == 0) {
rpLayer = Session::getContactLayer(0);
direction = Flags::Horizontal;
viaSide = Session::getViaWidth( rpDepth );
}
// Non-M1 terminal or punctual M1 protections.
if ((rpDepth != 0) or (sourcePosition == targetPosition)) {
map<Component*,AutoSegment*>::iterator irp = getRpLookup().find( rp );
if (irp == getRpLookup().end()) {
AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell
, rp
, rpLayer
, sourcePosition
, viaSide, viaSide
);
AutoContact* targetProtect = AutoContactTerminal::create( targetGCell
, rp
, rpLayer
, targetPosition
, viaSide, viaSide
);
sourceProtect->setFlags( CntFixed );
targetProtect->setFlags( CntFixed );
AutoSegment* segment = AutoSegment::create( sourceProtect, targetProtect, direction );
segment->setFlags( AutoSegment::SegFixed );
getRpLookup().insert( make_pair(rp,segment) );
}
}
if (sourcePosition != targetPosition) {
if (flags & DoSourceContact)
source = AutoContactTerminal::create( sourceGCell
, rp
, rpLayer
, sourcePosition
, viaSide, viaSide
);
if (flags & DoTargetContact)
target = AutoContactTerminal::create( targetGCell
, rp
, rpLayer
, targetPosition
, viaSide, viaSide
);
}
if (not source and not target) {
source = target = AutoContactTerminal::create( gcell
, rp
, rpLayer
, rp->getCenter()
, viaSide, viaSide
);
}
cdebug_tabw(145,-1);
return;
}
AutoContact* NetBuilderM2::doRp_Access ( GCell* gcell, Component* rp, uint64_t flags )
{
cdebug_log(145,1) << getTypeName() << "::doRp_Access()" << endl;
cdebug_log(145,0) << rp << endl;
Point sourcePosition;
Point targetPosition;
const Layer* rpLayer = rp->getLayer();
const Layer* viaLayer = Session::getDContactLayer();
DbU::Unit viaSide = Session::getDContactWidth();
DbU::Unit ypitch = Session::getDVerticalPitch();
getPositions( rp, sourcePosition, targetPosition );
if (sourcePosition.getX() > targetPosition.getX()) swap( sourcePosition, targetPosition );
if (sourcePosition.getY() > targetPosition.getY()) swap( sourcePosition, targetPosition );
Point position = rp->getCenter();
if (not (flags & Middle)) {
if (flags & NorthBound) position = targetPosition;
if (flags & SouthBound) position = sourcePosition;
}
DbU::Unit ycontact = (flags & SouthBound) ? gcell->getYMin() : gcell->getYMax()-ypitch;
AutoContact* rpContact = AutoContactTerminal::create( gcell, rp, rpLayer, position, viaSide, viaSide );
AutoContact* contact1 = AutoContactTurn::create( gcell, getNet(), viaLayer );
AutoContact* contact2 = AutoContactTurn::create( gcell, getNet(), viaLayer );
contact1->setPosition( position.getX(), ycontact );
contact2->setPosition( position.getX(), ycontact );
rpContact->setFlags( CntFixed );
contact1 ->setFlags( CntFixed );
contact2 ->setFlags( CntFixed );
AutoSegment* fixed = AutoSegment::create( rpContact, contact1, Flags::Vertical );
AutoSegment* dogleg = AutoSegment::create( contact1 , contact2, Flags::Horizontal|Flags::UseNonPref );
fixed ->setFlags( AutoSegment::SegFixed );
dogleg->setFlags( AutoSegment::SegFixed );
cdebug_tabw(145,-1);
return contact2;
}
bool NetBuilderM2::_do_1G_1M1 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1()" << endl;
uint64_t flags = NoFlags;
if (north()) flags |= NorthBound;
else if (south()) flags |= SouthBound;
AutoContact* contact = NULL;
contact = doRp_Access( getGCell(), getRoutingPads()[0], flags );
setNorthEastContact( contact );
push( north(), contact, SouthWest );
push( south(), contact, SouthWest );
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderM2::_do_2G_1M1 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_2G_1M1()" << endl;
AutoContact* contact = NULL;
contact = doRp_Access( getGCell(), getRoutingPads()[0], SouthBound|NorthBound );
push( north(), contact, SouthWest|Middle );
contact = doRp_Access( getGCell(), getRoutingPads()[0], SouthBound|NorthBound );
push( south(), contact, SouthWest|Middle );
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderM2::_do_xG ()
{
cdebug_log(145,1) << getTypeName() << "::_do_xG()" << endl;
vector<Hook*> hooksNS = getNorths();
hooksNS.insert( hooksNS.end(), getSouths().begin(), getSouths().end() );
sortHookByX( hooksNS, NoFlags );
const Layer* viaLayer = Session::getDContactLayer();
AutoContact* contactW = NULL;
AutoContact* contactE = NULL;
// Simple turn.
if ( (west() and not east() and (hooksNS.size() == 1))
or (east() and not west() and (hooksNS.size() == 1)) ) {
contactW = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
push( west() , contactW, SouthWest );
push( east() , contactW, SouthWest );
push( hooksNS[0], contactW, SouthWest );
cdebug_tabw(145,-1);
return true;
}
// Simple HTee.
if (west() and east() and (hooksNS.size() == 1)) {
contactW = AutoContactHTee::create( getGCell(), getNet(), viaLayer );
push( west() , contactW, SouthWest );
push( east() , contactW, SouthWest );
push( hooksNS[0], contactW, SouthWest );
cdebug_tabw(145,-1);
return true;
}
cdebug_log(145,0) << "West side processing." << endl;
// West side processing.
if (west()) {
contactW = AutoContactHTee::create( getGCell(), getNet(), viaLayer );
push( west() , contactW, SouthWest );
push( hooksNS[0], contactW, SouthWest );
} else {
contactW = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
push( hooksNS[0], contactW, SouthWest );
}
cdebug_log(145,0) << "Middle processing." << endl;
// Middle (North & South) processing.
if (hooksNS.size() > 2) {
for ( size_t i=1 ; i<hooksNS.size()-1 ; ++i ) {
AutoContact* current = AutoContactHTee::create( getGCell(), getNet(), viaLayer );
AutoSegment::create( contactW, current, Flags::Horizontal );
push( hooksNS[i], current, SouthWest );
contactW = current;
}
}
cdebug_log(145,0) << "East side processing." << endl;
// East side processing.
if (east()) {
contactE = AutoContactHTee::create( getGCell(), getNet(), viaLayer );
push( east(), contactE, SouthWest );
if (hooksNS.size() > 1)
push( hooksNS[hooksNS.size()-1], contactE, SouthWest );
} else {
contactE = AutoContactTurn::create( getGCell(), getNet(), viaLayer );
push( hooksNS[hooksNS.size()-1], contactE, SouthWest );
}
AutoSegment::create( contactW, contactE, Flags::Horizontal );
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderM2::_do_globalSegment ()
{
cdebug_log(145,1) << getTypeName() << "::_do_globalSegment()" << endl;
if (getSourceContact()) {
Segment* segment = static_cast <Segment*> ( getFromHook()->getComponent() );
AutoSegment* globalSegment = AutoSegment::create( getSourceContact(), getSouthWestContact(), segment );
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 );
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderM2::_do_1G_xM1 () { return false; }
bool NetBuilderM2::_do_xG_1Pad () { return false; }
bool NetBuilderM2::_do_1G_1PinM2 () { return false; }
bool NetBuilderM2::_do_xG_xM2 () { return false; }
bool NetBuilderM2::_do_1G_1M3 () { return false; }
bool NetBuilderM2::_do_xG_xM3 () { return false; }
bool NetBuilderM2::_do_xG_1M1_1M2 () { return false; }
bool NetBuilderM2::_do_xG_xM1_xM3 () { return false; }
bool NetBuilderM2::_do_4G_1M2 () { return false; }
bool NetBuilderM2::_do_2G () { return false; }
string NetBuilderM2::getTypeName () const
{ return "NetBuilderM2"; }
} // Anabatic namespace.

View File

@ -1,650 +0,0 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2018-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++ Module : "./NetBuilderVH.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/Pad.h"
#include "hurricane/Pin.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/NetBuilderVH.h"
#include "anabatic/AnabaticEngine.h"
namespace Anabatic {
using std::swap;
using Hurricane::Transformation;
using Hurricane::Warning;
using Hurricane::Error;
using Hurricane::Pin;
NetBuilderVH::NetBuilderVH ()
: NetBuilder()
{ }
NetBuilderVH::~NetBuilderVH () { }
string NetBuilderVH::getStyle ()
{ return "VH,3RL+"; }
void NetBuilderVH::doRp_AutoContacts ( GCell* gcell
, Component* rp
, AutoContact*& source
, AutoContact*& target
, uint64_t flags
)
{
cdebug_log(145,1) << getTypeName() << "::doRp_AutoContacts()" << endl;
cdebug_log(145,0) << rp << endl;
source = target = NULL;
Point sourcePosition;
Point targetPosition;
const Layer* rpLayer = rp->getLayer();
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
Flags direction = Session::getDirection ( rpDepth );
DbU::Unit viaSide = Session::getViaWidth ( rpDepth );
getPositions( rp, sourcePosition, targetPosition );
if (sourcePosition.getX() > targetPosition.getX()) swap( sourcePosition, targetPosition );
if (sourcePosition.getY() > targetPosition.getY()) swap( sourcePosition, targetPosition );
GCell* sourceGCell = Session::getAnabatic()->getGCellUnder( sourcePosition );
GCell* targetGCell = Session::getAnabatic()->getGCellUnder( targetPosition );
if (rpDepth == 0) {
rpLayer = Session::getContactLayer(0);
direction = Flags::Vertical;
viaSide = Session::getViaWidth( rpDepth );
RoutingPad* rrp = dynamic_cast<RoutingPad*>( rp );
if (rrp) {
// if (not getAnabatic()->getConfiguration()->selectRpComponent(rrp)) {
// cerr << Warning( "%s::doRp_AutoContacts(): %s has no components on grid."
// , getTypeName().c_str()
// , getString(rp).c_str() ) << endl;
// }
} else {
cerr << Warning( "%s::doRp_AutoContacts(): %s is *not* a RoutingPad."
, getTypeName().c_str()
, getString(rp).c_str() ) << endl;
}
}
// Non-M1 terminal or punctual M1 protections.
if ( (rpDepth != 0) or (sourcePosition == targetPosition) ) {
map<Component*,AutoSegment*>::iterator irp = getRpLookup().find( rp );
if (irp == getRpLookup().end()) {
AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell
, rp
, rpLayer
, sourcePosition
, viaSide, viaSide
);
AutoContact* targetProtect = AutoContactTerminal::create( targetGCell
, rp
, rpLayer
, targetPosition
, viaSide, viaSide
);
sourceProtect->setFlags( CntFixed );
targetProtect->setFlags( CntFixed );
AutoSegment* segment = AutoSegment::create( sourceProtect, targetProtect, direction );
segment->setFlags( AutoSegment::SegFixed );
getRpLookup().insert( make_pair(rp,segment) );
}
}
if (sourcePosition != targetPosition) {
if (flags & DoSourceContact)
source = AutoContactTerminal::create( sourceGCell
, rp
, rpLayer
, sourcePosition
, viaSide, viaSide
);
if (flags & DoTargetContact)
target = AutoContactTerminal::create( targetGCell
, rp
, rpLayer
, targetPosition
, viaSide, viaSide
);
}
if ( (rpDepth > 0) and not Session::getRoutingGauge()->isSuperPitched() ) {
rpLayer = Session::getContactLayer( rpDepth );
}
if (not source and not target) {
source = target = AutoContactTerminal::create( gcell
, rp
, rpLayer
, rp->getCenter()
, viaSide, viaSide
);
}
cdebug_tabw(145,-1);
return;
}
AutoContact* NetBuilderVH::doRp_Access ( GCell* gcell, Component* rp, uint64_t flags )
{
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() );
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)) {
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, rpDepth+1 );
rpContactSource = subContact1;
}
}
cdebug_tabw(145,-1);
return rpContactSource;
}
bool NetBuilderVH::_do_1G_1PinM2 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_1G_1PinM2() [Managed Configuration - Optimized] " << getTopology() << endl;
Pin* pin = dynamic_cast<Pin*>( getRoutingPads()[0]->getOccurrence().getEntity() );
if ( (pin->getAccessDirection() != Pin::AccessDirection::SOUTH)
and (pin->getAccessDirection() != Pin::AccessDirection::NORTH) ) {
cerr << Error( "%s::do_1G_1PinM2(): %s *must* be north or south."
, getTypeName().c_str()
, getString(pin).c_str() ) << endl;
}
uint64_t flags = NoFlags;
if (east()) { flags |= HAccess|VSmall; }
else if (west()) { flags |= HAccess|VSmall; }
setBothCornerContacts( doRp_Access(getGCell(),getRoutingPads()[0],flags) );
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderVH::_do_xG_1PinM2 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_xG_1PinM2() [Managed Configuration] " << getTopology() << endl;
Pin* pin = dynamic_cast<Pin*>( getRoutingPads()[0]->getOccurrence().getEntity() );
if ( (pin->getAccessDirection() != Pin::AccessDirection::SOUTH)
and (pin->getAccessDirection() != Pin::AccessDirection::NORTH) ) {
cerr << Error( "%s::do_xG_1PinM2(): %s *must* be north or south."
, getTypeName().c_str()
, getString(pin).c_str() ) << endl;
}
RoutingPad* rp = getRoutingPads()[0];
AutoContact* pinContact = NULL;
doRp_AutoContacts( getGCell(), rp, pinContact, pinContact, HSmall|VSmall );
if (not north() and not south()) {
AutoContact* subContact1 = AutoContactHTee::create( getGCell(), rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( pinContact, subContact1, Flags::Vertical );
setBothCornerContacts( subContact1 );
} else {
AutoContact* subContact1 = AutoContactVTee::create( getGCell(), rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( pinContact, subContact1, Flags::Vertical );
if (east() and west()) {
AutoContact* subContact2 = AutoContactVTee::create( getGCell(), rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( subContact1, subContact2, Flags::Vertical );
setSouthWestContact( (south()) ? subContact1 : subContact2 );
setNorthEastContact( (south()) ? subContact2 : subContact1 );
} else
setBothCornerContacts( subContact1 );
}
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderVH::_do_1G_1PinM3 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_1G_1PinM3() [Managed Configuration - Optimized] " << getTopology() << endl;
Pin* pin = dynamic_cast<Pin*>( getRoutingPads()[0]->getOccurrence().getEntity() );
if ( (pin->getAccessDirection() != Pin::AccessDirection::EAST)
and (pin->getAccessDirection() != Pin::AccessDirection::WEST) ) {
cerr << Error( "%s::do_1G_1PinM2(): %s *must* be east or west."
, getTypeName().c_str()
, getString(pin).c_str() ) << endl;
}
AutoContact* pinContact = NULL;
doRp_AutoContacts( getGCell(), getRoutingPads()[0], pinContact, pinContact, HSmall|VSmall );
if (east() or west()) {
AutoContact* subContact1 = AutoContactTurn::create( getGCell(), getRoutingPads()[0]->getNet(), Session::getContactLayer(1) );
AutoContact* subContact2 = AutoContactTurn::create( getGCell(), getRoutingPads()[0]->getNet(), Session::getContactLayer(1) );
AutoSegment::create( pinContact , subContact1, Flags::Horizontal );
AutoSegment::create( subContact1, subContact2, Flags::Vertical );
pinContact = subContact2;
} else {
AutoContact* subContact1 = NULL;
subContact1 = AutoContactTurn::create( getGCell(), getRoutingPads()[0]->getNet(), Session::getContactLayer(1) );
AutoSegment::create( pinContact, subContact1, Flags::Horizontal );
pinContact = subContact1;
}
setBothCornerContacts( pinContact );
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderVH::_do_xG_1PinM3 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_xG_1PinM3() [Managed Configuration] " << getTopology() << endl;
RoutingPad* rp = getRoutingPads()[0];
Pin* pin = dynamic_cast<Pin*>( rp->getOccurrence().getEntity() );
if ( (pin->getAccessDirection() != Pin::AccessDirection::EAST)
and (pin->getAccessDirection() != Pin::AccessDirection::WEST) ) {
cerr << Error( "%s::do_xG_1PinM3(): %s *must* be east or west."
, getTypeName().c_str()
, getString(pin).c_str() ) << endl;
}
AutoContact* pinContact = NULL;
doRp_AutoContacts( getGCell(), rp, pinContact, pinContact, HSmall|VSmall );
if (not east() and not west()) {
AutoContact* subContact1 = AutoContactVTee::create( getGCell(), rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( pinContact, subContact1, Flags::Horizontal );
setBothCornerContacts( subContact1 );
} else {
AutoContact* subContact1 = AutoContactHTee::create( getGCell(), rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( pinContact, subContact1, Flags::Horizontal );
if (north() and south()) {
AutoContact* subContact2 = AutoContactHTee::create( getGCell(), rp->getNet(), Session::getContactLayer(1) );
AutoSegment::create( subContact1, subContact2, Flags::Horizontal );
setSouthWestContact( (west()) ? subContact1 : subContact2 );
setNorthEastContact( (west()) ? subContact2 : subContact1 );
} else
setBothCornerContacts( subContact1 );
}
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderVH::_do_1G_1M1 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_1G_1M1() [Managed Configuration - Optimized] " << getTopology() << endl;
uint64_t flags = NoFlags;
if (east()) { flags |= HAccess|VSmall; }
else if (west()) { flags |= HAccess|VSmall; }
setBothCornerContacts( doRp_Access(getGCell(),getRoutingPads()[0],flags) );
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderVH::_do_1G_xM1 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_1G_" << (int)getConnexity().fields.M1 << "M1() [Defered Configuration]" << endl;
_do_xG_xM1_xM3();
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderVH::_do_2G_1M1 ()
{
cdebug_log(145,1) << getTypeName() << "::_do_2G_1M1 [Managed Configuration]" << endl;
cdebug_log(145,0) << "north: " << north() << endl;
cdebug_log(145,0) << "south: " << south() << endl;
cdebug_log(145,0) << "east: " << east() << endl;
cdebug_log(145,0) << "west: " << west() << endl;
AutoContact* tee = NULL;
if (east() and west()) {
tee = doRp_Access( getGCell(), getRoutingPads()[0], HAccessEW|VSmall );
} else {
AutoContact* turn = doRp_Access( getGCell(), getRoutingPads()[0], HAccess|VSmall );
if (east() or west())
tee = AutoContactHTee::create( getGCell(), getNet(), Session::getDContactLayer() );
else
tee = AutoContactVTee::create( getGCell(), getNet(), Session::getDContactLayer() );
AutoSegment::create( turn, tee, Flags::Horizontal );
}
setBothCornerContacts( tee );
cdebug_tabw(145,-1);
return true;
}
bool NetBuilderVH::_do_xG_xM1_xM3 ()
{
// Implicit hypothesis : we have at least two globals and at least one terminal.
cdebug_log(145,1) << getTypeName()
<< "::_do_xG_" << (int)getConnexity().fields.M1
<< "M1_" << (int)getConnexity().fields.M3
<< "M3() [G:" << (int)getConnexity().fields.globals << " Managed Configuration]" << endl;
cdebug_log(145,0) << "getConnexity(): " << getConnexity().connexity << endl;
cdebug_log(145,0) << "north: " << north() << endl;
cdebug_log(145,0) << "south: " << south() << endl;
cdebug_log(145,0) << "east: " << east() << endl;
cdebug_log(145,0) << "west: " << west() << endl;
sortRpByX( getRoutingPads(), NoFlags ); // increasing X.
size_t iLast = getRoutingPads().size()-1;
AutoContact* leftContact = NULL;
AutoContact* rightContact = NULL;
if (south() or west()) {
leftContact = doRp_Access( getGCell(), getRoutingPads()[0], HAccessEW|VSmall );
if (south() and west()) {
setSouthWestContact( AutoContactHTee::create( getGCell(), getNet(), Session::getDContactLayer() ) );
AutoSegment::create( getSouthWestContact(), leftContact, Flags::Horizontal );
} else {
if (west())
setSouthWestContact( leftContact );
else {
setSouthWestContact( AutoContactTurn::create( getGCell(), getNet(), Session::getDContactLayer() ) );
AutoSegment::create( leftContact, getSouthWestContact(), Flags::Horizontal );
}
}
} else {
leftContact = doRp_Access( getGCell(), getRoutingPads()[0], HAccess|VSmall );
}
for ( size_t i=1 ; i<getRoutingPads().size()-1 ; ++i ) {
rightContact = doRp_Access( getGCell(), getRoutingPads()[i], HAccessEW|VSmall );
AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
leftContact = rightContact;
}
if (north() or east()) {
if (getRoutingPads().size() > 1) {
rightContact = doRp_Access( getGCell(), getRoutingPads()[iLast], HAccessEW|VSmall );
AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
} else {
rightContact = leftContact;
}
if (north() and east()) {
setNorthEastContact( AutoContactHTee::create( getGCell(), getNet(), Session::getDContactLayer() ) );
AutoSegment::create( rightContact, getNorthEastContact(), Flags::Horizontal );
} else {
if (east())
setNorthEastContact( rightContact );
else {
setNorthEastContact( AutoContactTurn::create( getGCell(), getNet(), Session::getDContactLayer() ) );
AutoSegment::create( rightContact, getNorthEastContact(), Flags::Horizontal );
}
}
} else {
rightContact = doRp_Access( getGCell(), getRoutingPads()[iLast], HAccess|VSmall );
AutoSegment::create( leftContact, rightContact, Flags::Horizontal );
}
cdebug_tabw(145,-1);
return true;
}
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;
const Layer* viaLayer = Session::getDContactLayer();
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 NetBuilderVH::_do_globalSegment ()
{
cdebug_log(145,1) << getTypeName() << "::_do_globalSegment()" << endl;
if (getSourceContact()) {
AutoContact* targetContact
= ( getSegmentHookType(getFromHook()) & (NorthBound|EastBound) )
? getNorthEastContact() : getSouthWestContact() ;
AutoSegment* globalSegment = AutoSegment::create( getSourceContact()
, targetContact
, static_cast<Segment*>( getFromHook()->getComponent() )
);
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 NetBuilderVH::singleGCell ( AnabaticEngine* anbt, Net* net )
{
cdebug_log(145,1) << getTypeName() << "::singleGCell() " << net << endl;
vector<RoutingPad*> rps;
for ( RoutingPad* rp : net->getRoutingPads() ) {
if (Session::getRoutingGauge()->getLayerDepth(rp->getLayer()) == 0) {
rps.push_back( rp );
continue;
}
cerr << Error( "%s::singleGCell(): Non metal1 terminals are not managed yet.\n"
" (%s)"
, getTypeName().c_str()
, getString(rp).c_str()
) << endl;
cdebug_tabw(145,-1);
return;
}
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;
}
if (rps.empty()) {
cerr << Error( "%s::singleGCell(): No terminals for Net \"%s\"."
, getTypeName().c_str()
, getString(net->getName()).c_str() ) << endl;
cdebug_tabw(145,-1);
return;
}
sortRpByX( rps, NetBuilder::NoFlags ); // increasing X.
GCell* gcell1 = anbt->getGCellUnder( (*rps.begin ())->getCenter() );
GCell* gcell2 = anbt->getGCellUnder( (*rps.rbegin())->getCenter() );
if (not gcell1) {
cerr << Error( "%s::singleGCell(): No GCell under %s."
, getTypeName().c_str()
, getString(*(rps.begin())).c_str() ) << endl;
cdebug_tabw(145,-1);
return;
}
if (gcell1 != gcell2) {
cerr << Error( "%s::singleGCell(): Not under a single GCell %s."
, getTypeName().c_str()
, getString(*(rps.rbegin())).c_str() ) << endl;
cdebug_tabw(145,-1);
return;
}
cdebug_log(145,0) << "singleGCell " << gcell1 << endl;
AutoContact* source = NULL;
AutoContact* target = NULL;
for ( size_t irp=1 ; irp<rps.size() ; ++irp ) {
source = doRp_Access( gcell1, rps[irp-1], HAccess|VSmall );
target = doRp_Access( gcell1, rps[irp ], HAccess|VSmall );
AutoSegment::create( source, target, Flags::Horizontal );
}
cdebug_tabw(145,-1);
}
string NetBuilderVH::getTypeName () const
{ return "NetBuilderVH"; }
} // Anabatic namespace.

View File

@ -61,55 +61,55 @@ namespace {
void propagateConstraintFromRp ( RoutingPad* rp ) void propagateConstraintFromRp ( RoutingPad* rp )
{ {
cdebug_log(146,1) << "propagateConstraintFromRp() - " << rp << endl; cdebug_log(145,1) << "propagateConstraintFromRp() - " << rp << endl;
for ( Component* component : rp->getSlaveComponents() ) { 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) ); AutoContact* sourceContact = Session::lookup( dynamic_cast<Contact*>(component) );
if (sourceContact) { if (sourceContact) {
Box constraintBox = sourceContact->getConstraintBox(); cdebug_log(145,0) << "Start slave: " << sourceContact << endl;
cdebug_log(146,0) << "Start slave: " << sourceContact << endl;
cdebug_log(146,0) << "Constraint: " << constraintBox << endl;
set<AutoSegment*> verticalSegments; set<AutoSegment*> verticalSegments;
set<AutoSegment*> horizontalSegments; set<AutoSegment*> horizontalSegments;
for ( AutoSegment* segment : sourceContact->getAutoSegments() ) { for ( AutoSegment* segment : sourceContact->getAutoSegments() ) {
cdebug_log(146,0) << "Examining: " << segment << endl; cdebug_log(145,0) << "Examining: " << segment << endl;
AutoContact* targetContact = segment->getOppositeAnchor(sourceContact); AutoContact* targetContact = segment->getOppositeAnchor(sourceContact);
if (targetContact) { if (targetContact) {
if (segment->isHorizontal()) { if (segment->isHorizontal()) {
cdebug_log(146,0) << "On horizontal stack " << segment << endl; cdebug_log(145,0) << "On horizontal stack " << segment << endl;
horizontalSegments.insert( segment ); horizontalSegments.insert( segment );
} else { } else {
cdebug_log(146,0) << "On vertical stack " << segment << endl; cdebug_log(145,0) << "On vertical stack " << segment << endl;
verticalSegments.insert( segment ); verticalSegments.insert( segment );
} }
} }
} }
Box constraintBox = sourceContact->getConstraintBox();
cdebug_log(145,0) << "Contraint: " << constraintBox << endl;
// Propagate constraint through horizontally aligned segments. // 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 ) { for ( AutoSegment* horizontal : horizontalSegments ) {
AutoContact* contact = NULL; AutoContact* contact = NULL;
for ( AutoSegment* aligned : horizontal->getAligneds(Flags::WithSelf) ) { 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(); contact = aligned->getAutoTarget();
cdebug_log(146,0) << "contact: " << contact << endl; cdebug_log(145,0) << "contact: " << contact << endl;
if (contact) { if (contact) {
cdebug_log(146,0) << "Apply to (target): " << contact << endl; cdebug_log(145,0) << "Apply to (target): " << contact << endl;
contact->restrictConstraintBox( constraintBox.getYMin() contact->restrictConstraintBox( constraintBox.getYMin()
, constraintBox.getYMax() , constraintBox.getYMax()
, Flags::Horizontal|Flags::WarnOnError ); , Flags::Horizontal|Flags::WarnOnError );
} }
contact = aligned->getAutoSource(); contact = aligned->getAutoSource();
cdebug_log(146,0) << "contact: " << contact << endl; cdebug_log(145,0) << "contact: " << contact << endl;
if (contact) { if (contact) {
cdebug_log(146,0) << "Apply to (source): " << contact << endl; cdebug_log(145,0) << "Apply to (source): " << contact << endl;
contact->restrictConstraintBox( constraintBox.getYMin() contact->restrictConstraintBox( constraintBox.getYMin()
, constraintBox.getYMax() , constraintBox.getYMax()
, Flags::Horizontal|Flags::WarnOnError ); , Flags::Horizontal|Flags::WarnOnError );
@ -118,23 +118,23 @@ namespace {
} }
// Propagate constraint through vertically aligned segments. // 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 ) { for ( AutoSegment* vertical : verticalSegments ) {
AutoContact* contact = NULL; AutoContact* contact = NULL;
for ( AutoSegment* aligned : vertical->getAligneds(Flags::WithSelf) ) { 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(); contact = aligned->getAutoTarget();
if (contact) { if (contact) {
cdebug_log(146,0) << "Apply to (target): " << contact << endl; cdebug_log(145,0) << "Apply to (target): " << contact << endl;
contact->restrictConstraintBox( constraintBox.getXMin() contact->restrictConstraintBox( constraintBox.getXMin()
, constraintBox.getXMax() , constraintBox.getXMax()
, Flags::Vertical|Flags::WarnOnError ); , Flags::Vertical|Flags::WarnOnError );
} }
contact = aligned->getAutoSource(); contact = aligned->getAutoSource();
if (contact) { if (contact) {
cdebug_log(146,0) << "Apply to (source): " << contact << endl; cdebug_log(145,0) << "Apply to (source): " << contact << endl;
contact->restrictConstraintBox( constraintBox.getXMin() contact->restrictConstraintBox( constraintBox.getXMin()
, constraintBox.getXMax() , constraintBox.getXMax()
, Flags::Vertical|Flags::WarnOnError ); , Flags::Vertical|Flags::WarnOnError );
@ -144,8 +144,8 @@ namespace {
} }
} }
cdebug_log(146,0) << "propagateConstraintFromRp() - Exit" << endl; cdebug_log(145,0) << "propagateConstraintFromRp() - Exit" << endl;
cdebug_tabw(146,-1); cdebug_tabw(145,-1);
} }
@ -159,128 +159,35 @@ namespace Anabatic {
using Hurricane::Cell; 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 ) void AnabaticEngine::computeNetConstraints ( Net* net )
{ {
DebugSession::open( net, 146, 150); DebugSession::open( net, 140, 150);
cdebug_log(149,0) << "Anabatic::computeNetConstraints( " << net << " )" << endl; cdebug_log(149,0) << "Anabatic::computeNetConstraints( " << net << " )" << endl;
cdebug_tabw(146,1); cdebug_tabw(145,1);
vector<RoutingPad*> routingPads; vector<RoutingPad*> routingPads;
for ( Component* component : net->getComponents() ) { forEach ( Component*, icomponent, net->getComponents() ) {
Contact* contact = dynamic_cast<Contact*>( component ); Contact* contact = dynamic_cast<Contact*>( *icomponent );
if (contact) { if (contact) {
AutoContact* autoContact = Session::lookup( contact ); AutoContact* autoContact = Session::lookup( contact );
if (autoContact) if (autoContact)
autoContact->restoreNativeConstraintBox(); autoContact->restoreNativeConstraintBox();
} else { } else {
Segment* segment = dynamic_cast<Segment*>( component ); RoutingPad* routingPad = dynamic_cast<RoutingPad*>( *icomponent );
if (segment) { if (routingPad) routingPads.push_back( routingPad );
AutoSegment* autoSegment = Session::lookup( segment );
if (autoSegment)
autoSegment->setRpDistance( 15 );
} else {
RoutingPad* routingPad = dynamic_cast<RoutingPad*>( component );
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] ); 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() ) { // forEach ( Segment*, isegment, net->getSegments() ) {
// AutoSegment* autoSegment = Session::lookup( *isegment ); // AutoSegment* autoSegment = Session::lookup( *isegment );
// if (autoSegment) autoSegment->toConstraintAxis(); // if (autoSegment) autoSegment->toConstraintAxis();
// } // }
cdebug_tabw(146,-1); cdebug_tabw(145,-1);
DebugSession::close(); DebugSession::close();
} }

View File

@ -2,7 +2,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2018, All Rights Reserved // Copyright (c) UPMC 2008-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -61,7 +61,7 @@ namespace Anabatic {
void AnabaticEngine::toOptimals ( Net* net ) void AnabaticEngine::toOptimals ( Net* net )
{ {
DebugSession::open( net, 145, 150 ); DebugSession::open( net, 140, 150 );
cdebug_log(149,0) << "Anabatic::_toOptimals( " << net << " )" << endl; cdebug_log(149,0) << "Anabatic::_toOptimals( " << net << " )" << endl;
cdebug_tabw(145,1); cdebug_tabw(145,1);

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2014-2018, All Rights Reserved // Copyright (c) UPMC 2014-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -35,7 +35,6 @@ namespace Anabatic {
using Hurricane::RegularLayer; using Hurricane::RegularLayer;
using Hurricane::Component; using Hurricane::Component;
using Hurricane::Pin; using Hurricane::Pin;
using Hurricane::Plug;
using Hurricane::DeepNet; using Hurricane::DeepNet;
using Hurricane::Cell; using Hurricane::Cell;
using Hurricane::NetRoutingExtension; using Hurricane::NetRoutingExtension;
@ -67,103 +66,64 @@ namespace Anabatic {
size_t AnabaticEngine::setupPreRouteds () void AnabaticEngine::setupPreRouteds ()
{ {
cmess1 << " o Looking for fixed or manually global routed nets." << endl; cmess1 << " o Looking for fixed or manually global routed nets." << endl;
openSession(); openSession();
size_t toBeRouteds = 0;
Box ab = getCell()->getAbutmentBox();
ab.inflate( -1 );
for ( Net* net : getCell()->getNets() ) { for ( Net* net : getCell()->getNets() ) {
if (net == _blockageNet) continue; if (net == _blockageNet) continue;
if (net->getType() == Net::Type::POWER ) continue; if (net->getType() == Net::Type::POWER ) continue;
if (net->getType() == Net::Type::GROUND) continue; if (net->getType() == Net::Type::GROUND) continue;
// Don't skip the clock. // Don't skip the clock.
vector<Pin*> pins;
vector<Segment*> segments; vector<Segment*> segments;
vector<Contact*> contacts; vector<Contact*> contacts;
bool isManualGlobalRouted = false; bool isPreRouted = false;
bool isManualDetailRouted = false; bool isFixed = false;
bool isFixed = false; size_t rpCount = 0;
size_t rpCount = 0;
for( Component* component : net->getComponents() ) { if (net->isDeepNet()) {
Pin* pin = dynamic_cast<Pin *>( component ); rpCount = 2;
if (pin) {
pins.push_back( pin ); Net* rootNet = dynamic_cast<Net*>(
continue; dynamic_cast<DeepNet*>(net)->getRootNetOccurrence().getEntity() );
for( Component* component : rootNet->getComponents() ) {
if (dynamic_cast<Horizontal*>(component)) { isFixed = true; break; }
if (dynamic_cast<Vertical*> (component)) { isFixed = true; break; }
if (dynamic_cast<Contact*> (component)) { isFixed = true; break; }
} }
if (dynamic_cast<Plug*>(component)) continue; } else {
for( Component* component : net->getComponents() ) {
if (dynamic_cast<Pin*>(component)) continue;
const RegularLayer* layer = dynamic_cast<const RegularLayer*>(component->getLayer()); const RegularLayer* layer = dynamic_cast<const RegularLayer*>(component->getLayer());
if (layer and (layer->getBasicLayer()->getMaterial() == BasicLayer::Material::blockage)) if (layer and (layer->getBasicLayer()->getMaterial() == BasicLayer::Material::blockage))
continue; continue;
if ( not Session::isGaugeLayer(component->getLayer()) Horizontal* horizontal = dynamic_cast<Horizontal*>(component);
and not Session::isGLayer (component->getLayer())) { if (horizontal) {
const BasicLayer* basicLayer = dynamic_cast<const BasicLayer*>( component->getLayer() ); segments.push_back( horizontal );
if (basicLayer and (basicLayer->getMaterial() == BasicLayer::Material::cut)) isPreRouted = true;
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()
);
}
Horizontal* horizontal = dynamic_cast<Horizontal*>(component);
if (horizontal) {
if ( not ab.contains(horizontal->getSourcePosition())
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())) if (horizontal->getWidth() != Session::getWireWidth(horizontal->getLayer()))
isFixed = true; isFixed = true;
} } else {
} else { Vertical* vertical = dynamic_cast<Vertical*>(component);
Vertical* vertical = dynamic_cast<Vertical*>(component); if (vertical) {
if (vertical) { isPreRouted = true;
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 ); segments.push_back( vertical );
if (vertical->getWidth() != Session::getWireWidth(vertical->getLayer())) if (vertical->getWidth() != Session::getWireWidth(vertical->getLayer()))
isFixed = true; 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 );
} else { } else {
Contact* contact = dynamic_cast<Contact*>(component); Contact* contact = dynamic_cast<Contact*>(component);
if (contact) { if (contact) {
if (not ab.contains(contact->getCenter())) continue; isPreRouted = true;
contacts.push_back( contact );
if (Session::isGLayer(component->getLayer())) { if ( (contact->getWidth () != Session::getViaWidth(contact->getLayer()))
isManualGlobalRouted = true; or (contact->getHeight() != Session::getViaWidth(contact->getLayer())) )
} else { isFixed = true;
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;
}
} else { } else {
RoutingPad* rp = dynamic_cast<RoutingPad*>(component); RoutingPad* rp = dynamic_cast<RoutingPad*>(component);
if (rp) { if (rp) {
@ -181,75 +141,38 @@ namespace Anabatic {
} }
} }
// cerr << net << " deepNet:" << net->isDeepNet() if (isFixed or isPreRouted or (rpCount < 2)) {
// << " 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()) {
Net* rootNet = dynamic_cast<Net*>(
dynamic_cast<DeepNet*>(net)->getRootNetOccurrence().getEntity() );
for( Component* component : rootNet->getComponents() ) {
if (dynamic_cast<Horizontal*>(component)) { isFixed = true; break; }
if (dynamic_cast<Vertical*> (component)) { isFixed = true; break; }
if (dynamic_cast<Contact*> (component)) { isFixed = true; break; }
}
}
if (isFixed or isManualDetailRouted or isManualGlobalRouted or (rpCount < 2)) {
NetData* ndata = getNetData( net, Flags::Create ); NetData* ndata = getNetData( net, Flags::Create );
NetRoutingState* state = ndata->getNetRoutingState(); NetRoutingState* state = ndata->getNetRoutingState();
state->unsetFlags( NetRoutingState::AutomaticGlobalRoute ); state->unsetFlags( NetRoutingState::AutomaticGlobalRoute );
if (isManualGlobalRouted) { state->setFlags ( NetRoutingState::ManualGlobalRoute );
state->setFlags( NetRoutingState::ManualGlobalRoute );
ndata->setGlobalFixed( true );
}
if (isManualDetailRouted)
state->setFlags( NetRoutingState::ManualDetailRoute );
ndata->setGlobalRouted( true ); ndata->setGlobalRouted( true );
if (rpCount < 2) if (rpCount < 2)
state->setFlags( NetRoutingState::Unconnected ); state->setFlags ( NetRoutingState::Unconnected );
if (isFixed) { if (isFixed) {
if (rpCount > 1) cmess2 << " - <" << net->getName() << "> is fixed." << endl;
cmess2 << " - <" << net->getName() << "> is fixed." << endl; state->unsetFlags( NetRoutingState::ManualGlobalRoute );
state->unsetFlags( NetRoutingState::ManualGlobalRoute|NetRoutingState::ManualDetailRoute );
state->setFlags ( NetRoutingState::Fixed ); state->setFlags ( NetRoutingState::Fixed );
} else if (isManualGlobalRouted) { } else {
cmess2 << " - <" << net->getName() << "> is manually global routed." << endl;
} else if (isManualDetailRouted) {
if (rpCount > 1) { if (rpCount > 1) {
++toBeRouteds; cmess2 << " - <" << net->getName() << "> is manually global routed." << endl;
cmess2 << " - <" << net->getName() << "> is manually detail routed." << endl; for ( auto icontact : contacts ) {
for ( auto contact : contacts ) { AutoContact::createFrom( icontact );
AutoContact::createFrom( contact );
} }
for ( auto segment : segments ) {
AutoContact* source = Session::lookup( dynamic_cast<Contact*>( segment->getSource() )); for ( auto isegment : segments ) {
AutoContact* target = Session::lookup( dynamic_cast<Contact*>( segment->getTarget() )); AutoContact* source = Session::lookup( dynamic_cast<Contact*>( isegment->getSource() ));
if (not source or not target) { AutoContact* target = Session::lookup( dynamic_cast<Contact*>( isegment->getTarget() ));
cerr << Error( "Unable to protect %s", getString(segment).c_str() ) << endl; AutoSegment* autoSegment = AutoSegment::create( source, target, isegment );
continue;
}
AutoSegment* autoSegment = AutoSegment::create( source, target, segment );
autoSegment->setFlags( AutoSegment::SegUserDefined|AutoSegment::SegAxisSet ); autoSegment->setFlags( AutoSegment::SegUserDefined|AutoSegment::SegAxisSet );
} }
} }
} }
} else {
++toBeRouteds;
} }
} }
Session::close(); Session::close();
return toBeRouteds;
} }

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2018, All Rights Reserved // Copyright (c) UPMC 2016-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -16,7 +16,7 @@
#include "hurricane/isobar/PyHurricane.h" #include "hurricane/isobar/PyHurricane.h"
#include "hurricane/isobar/PyCell.h" #include "hurricane/isobar/PyCell.h"
#include "anabatic/PyStyleFlags.h" #include "anabatic/Constants.h"
namespace Anabatic { namespace Anabatic {
@ -55,53 +55,27 @@ 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 ()" // Module Initialization : "initAnabatic ()"
PyMODINIT_FUNC PyInit_Anabatic ( void ) DL_EXPORT(void) initAnabatic () {
{ cdebug_log(32,0) << "initAnabatic()" << endl;
cdebug_log(32,0) << "PyInit_Anabatic()" << endl;
PyStyleFlags_LinkPyType(); PyObject* module = Py_InitModule( "Anabatic", PyAnabatic_Methods );
PYTYPE_READY( StyleFlags );
PyObject* module = PyModule_Create( &PyAnabatic_ModuleDef );
if (module == NULL) { if (module == NULL) {
cerr << "[ERROR]\n" cerr << "[ERROR]\n"
<< " Failed to initialize Anabatic module." << endl; << " Failed to initialize Anabatic module." << endl;
return NULL; return;
} }
Py_INCREF( &PyTypeStyleFlags );
PyModule_AddObject( module, "StyleFlags", (PyObject*)&PyTypeStyleFlags );
PyObject* dictionnary = PyModule_GetDict(module); PyObject* dictionnary = PyModule_GetDict(module);
PyObject* constant; PyObject* constant;
LoadObjectConstant( dictionnary,EngineLoadGrByNet ,"EngineLoadGrByNet" ); LoadObjectConstant( dictionnary,EngineLoadGrByNet ,"EngineLoadGrByNet" );
LoadObjectConstant( dictionnary,EngineLoadGrByGCell ,"EngineLoadGrByGCell" ); LoadObjectConstant( dictionnary,EngineLoadGrByGCell ,"EngineLoadGrByGCell" );
LoadObjectConstant( dictionnary,EngineLayerAssignByLength ,"EngineLayerAssignByLength" ); LoadObjectConstant( dictionnary,EngineLayerAssignByLength,"EngineLayerAssignByLength" );
LoadObjectConstant( dictionnary,EngineLayerAssignByTrunk ,"EngineLayerAssignByTrunk" ); LoadObjectConstant( dictionnary,EngineLayerAssignByTrunk ,"EngineLayerAssignByTrunk" );
LoadObjectConstant( dictionnary,EngineLayerAssignNoGlobalM2V,"EngineLayerAssignNoGlobalM2V" ); LoadObjectConstant( dictionnary,EngineNoNetLayerAssign ,"EngineNoNetLayerAssign" );
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

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "Session.cpp<anabatic>" -*- // -*- mode: C++; explicit-buffer-name: "Session.cpp<anabatic>" -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2018, All Rights Reserved // Copyright (c) UPMC 2008-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -17,7 +17,6 @@
#include <cstdlib> #include <cstdlib>
#include <sstream> #include <sstream>
#include "hurricane/Error.h" #include "hurricane/Error.h"
#include "hurricane/Warning.h"
#include "hurricane/Horizontal.h" #include "hurricane/Horizontal.h"
#include "hurricane/Vertical.h" #include "hurricane/Vertical.h"
#include "hurricane/Cell.h" #include "hurricane/Cell.h"
@ -48,7 +47,6 @@ namespace Anabatic {
using namespace std; using namespace std;
using Hurricane::tab; using Hurricane::tab;
using Hurricane::Error; using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::ForEachIterator; using Hurricane::ForEachIterator;
using Hurricane::UpdateSession; using Hurricane::UpdateSession;
using Hurricane::Horizontal; using Hurricane::Horizontal;
@ -82,12 +80,7 @@ namespace Anabatic {
, _segmentRevalidateds() , _segmentRevalidateds()
, _netInvalidateds () , _netInvalidateds ()
, _netRevalidateds () , _netRevalidateds ()
{ { }
_autoContacts .reserve( 1024 );
_doglegs .reserve( 1024 );
_segmentInvalidateds.reserve( 1024 );
_segmentRevalidateds.reserve( 1024 );
}
void Session::_postCreate () void Session::_postCreate ()
@ -165,7 +158,6 @@ namespace Anabatic {
canonical->setFlags( AutoSegment::SegCanonical ); canonical->setFlags( AutoSegment::SegCanonical );
cdebug_log(145,0) << "Canonical: " << canonical << endl; cdebug_log(145,0) << "Canonical: " << canonical << endl;
Interval userConstraints = canonical->getUserConstraints();
for ( size_t j=0 ; j<aligneds.size() ; j++ ) { for ( size_t j=0 ; j<aligneds.size() ; j++ ) {
if (isWeakGlobal and not aligneds[j]->isGlobal()) aligneds[j]->setFlags ( AutoSegment::SegWeakGlobal ); if (isWeakGlobal and not aligneds[j]->isGlobal()) aligneds[j]->setFlags ( AutoSegment::SegWeakGlobal );
@ -179,29 +171,14 @@ namespace Anabatic {
} }
aligneds[j]->unsetFlags( AutoSegment::SegCanonical ); aligneds[j]->unsetFlags( AutoSegment::SegCanonical );
cdebug_log(145,0) << "Secondary: " << aligneds[j] << endl; cdebug_log(145,0) << "Secondary: " << aligneds[j] << endl;
userConstraints.intersection( aligneds[j]->getUserConstraints() );
} }
if (aligneds.empty()) canonical->setFlags( AutoSegment::SegNotAligned ); if (aligneds.empty()) canonical->setFlags( AutoSegment::SegNotAligned );
if (not getRoutingGauge()->isSymbolic()
and (userConstraints.getSize() < Session::getPitch(1)*2) ) {
cerr << Warning( "Session::_canonize(): On %s\n"
" Combined user constraints are too tight [%s : %s]."
, getString(canonical).c_str()
, DbU::getValueString(userConstraints.getVMin()).c_str()
, DbU::getValueString(userConstraints.getVMax()).c_str()
) << endl;
}
cdebug_log(149,0) << "Align on canonical:" << canonical << endl; cdebug_log(149,0) << "Align on canonical:" << canonical << endl;
cdebug_log(145,0) << "Combined user constraints: " << userConstraints << endl;
//canonical->setAxis( canonical->getAxis(), Flags::Realignate ); //canonical->setAxis( canonical->getAxis(), Flags::Realignate );
if (canonical->isUnsetAxis() and not canonical->isFixed()) if (canonical->isUnsetAxis()) canonical->toOptimalAxis( Flags::Realignate|Flags::Propagate );
canonical->toOptimalAxis( Flags::Realignate|Flags::Propagate ); else canonical->setAxis( canonical->getAxis(), Flags::Realignate|Flags::Propagate );
else
canonical->setAxis( canonical->getAxis(), Flags::Realignate|Flags::Propagate );
aligneds.clear(); aligneds.clear();
cdebug_tabw(145,-1); cdebug_tabw(145,-1);
} }
@ -215,23 +192,21 @@ namespace Anabatic {
{ {
cdebug_log(145,1) << "Anabatic::Session::_revalidateTopology()" << endl; cdebug_log(145,1) << "Anabatic::Session::_revalidateTopology()" << endl;
_anabatic->disableCanonize(); set<Net*>::iterator inet = _netInvalidateds.begin();
for ( Net* net : _netInvalidateds ) {
cdebug_log(145,0) << "Anabatic::Session::_revalidateTopology(Net*)" << net << endl; for ( ; inet != _netInvalidateds.end() ; inet++ ) {
_anabatic->updateNetTopology ( net ); cdebug_log(145,0) << "Anabatic::Session::_revalidateTopology(Net*)" << *inet << endl;
_anabatic->computeNetConstraints( net ); _anabatic->updateNetTopology ( *inet );
_anabatic->_computeNetOptimals ( net ); _anabatic->computeNetConstraints( *inet );
//_anabatic->_computeNetTerminals ( net ); _anabatic->_computeNetOptimals ( *inet );
_anabatic->_computeNetTerminals ( *inet );
} }
_anabatic->enableCanonize();
_canonize (); _canonize ();
AutoSegment* segment = NULL;
for ( size_t i=0 ; i<_segmentInvalidateds.size() ; ++i ) { for ( size_t i=0 ; i<_segmentInvalidateds.size() ; ++i ) {
segment = _segmentInvalidateds[i]; if (_segmentInvalidateds[i]->isCanonical()) {
if (segment->isCanonical()) { if (_segmentInvalidateds[i]->isUnsetAxis()) _segmentInvalidateds[i]->toOptimalAxis();
if (segment->isUnsetAxis()) segment->toOptimalAxis(); else _segmentInvalidateds[i]->toConstraintAxis();
else segment->toConstraintAxis();
} }
} }
@ -261,8 +236,6 @@ namespace Anabatic {
cdebug_log(145,0) << "_segmentInvalidateds.size(): " << _segmentInvalidateds.size() << endl; cdebug_log(145,0) << "_segmentInvalidateds.size(): " << _segmentInvalidateds.size() << endl;
_segmentRevalidateds.clear(); _segmentRevalidateds.clear();
std::sort( _segmentInvalidateds.begin(), _segmentInvalidateds.end()
, AutoSegment::CompareByRevalidate() );
for ( size_t i=0 ; i < _segmentInvalidateds.size() ; ++i, ++count ) { for ( size_t i=0 ; i < _segmentInvalidateds.size() ; ++i, ++count ) {
_segmentInvalidateds[i]->revalidate(); _segmentInvalidateds[i]->revalidate();
if ( not _destroyedSegments.empty() if ( not _destroyedSegments.empty()
@ -364,46 +337,20 @@ 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 ) Point Session::_getNearestGridPoint ( Point p, Box constraint )
{ {
Box ab = _anabatic->getCell()->getAbutmentBox(); Box ab = _anabatic->getCell()->getAbutmentBox();
RoutingLayerGauge* lg = _routingGauge->getVerticalGauge(); RoutingLayerGauge* lg = _routingGauge->getLayerGauge( 1 );
DbU::Unit x = lg->getTrackPosition( ab.getXMin() DbU::Unit x = lg->getTrackPosition( ab.getXMin()
, lg->getTrackIndex( ab.getXMin() , lg->getTrackIndex( ab.getXMin()
, ab.getXMax() , ab.getXMax()
, p.getX() , p.getX()
, Constant::Nearest ) ); , Constant::Nearest ) );
if (x < constraint.getXMin()) x += lg->getPitch(); if (x < constraint.getXMin()) x += lg->getPitch();
if (x > constraint.getXMax()) x -= lg->getPitch(); if (x > constraint.getXMax()) x -= lg->getPitch();
lg = _routingGauge->getHorizontalGauge(); lg = _routingGauge->getLayerGauge( 2 );
DbU::Unit y = lg->getTrackPosition( ab.getYMin() DbU::Unit y = lg->getTrackPosition( ab.getYMin()
, lg->getTrackIndex( ab.getYMin() , lg->getTrackIndex( ab.getYMin()
, ab.getYMax() , ab.getYMax()
@ -412,25 +359,14 @@ namespace Anabatic {
if (y < constraint.getYMin()) y += lg->getPitch(); if (y < constraint.getYMin()) y += lg->getPitch();
if (y > constraint.getYMax()) 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); return Point(x,y);
} }
StyleFlags Session::getRoutingStyle ()
{ return get("getRoutingStyle()")->_anabatic->getRoutingStyle(); }
bool Session::isInDemoMode () bool Session::isInDemoMode ()
{ return get("isInDemoMode()")->_anabatic->isInDemoMode(); } { return get("isInDemoMode()")->_anabatic->isInDemoMode(); }
bool Session::isChannelStyle ()
{ return get("isChannelStyle()")->_anabatic->isChannelStyle(); }
float Session::getSaturateRatio () float Session::getSaturateRatio ()
{ return get("getSaturateRatio()")->_anabatic->getSaturateRatio(); } { return get("getSaturateRatio()")->_anabatic->getSaturateRatio(); }

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2018, All Rights Reserved // Copyright (c) UPMC 2016-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -14,16 +14,20 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#pragma once #ifndef ANABATIC_ANABATIC_ENGINE_H
#define ANABATIC_ANABATIC_ENGINE_H
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#include <set> #include <set>
#include "hurricane/NetRoutingProperty.h" #include "hurricane/NetRoutingProperty.h"
namespace Hurricane { namespace Hurricane {
class Instance; class Instance;
class CellViewer; class CellViewer;
} }
#include "crlcore/ToolEngine.h" #include "crlcore/ToolEngine.h"
#include "anabatic/Configuration.h" #include "anabatic/Configuration.h"
#include "anabatic/Matrix.h" #include "anabatic/Matrix.h"
@ -45,7 +49,6 @@ namespace Anabatic {
using Hurricane::NetRoutingState; using Hurricane::NetRoutingState;
using CRL::ToolEngine; using CRL::ToolEngine;
class NetBuilder;
class AnabaticEngine; class AnabaticEngine;
@ -65,8 +68,6 @@ namespace Anabatic {
}; };
public: public:
RawGCellsUnder ( const AnabaticEngine*, Segment* ); RawGCellsUnder ( const AnabaticEngine*, Segment* );
RawGCellsUnder ( const AnabaticEngine*, Point source, Point target );
void commonCtor ( const AnabaticEngine*, Point source, Point target );
inline bool empty () const; inline bool empty () const;
inline size_t size () const; inline size_t size () const;
inline GCell* gcellAt ( size_t ) const; inline GCell* gcellAt ( size_t ) const;
@ -101,66 +102,46 @@ namespace Anabatic {
class NetData { class NetData {
public: public:
NetData ( Net*, AnabaticEngine* ); NetData ( Net* );
inline bool isGlobalEstimated () const;
inline bool isGlobalRouted () const; inline bool isGlobalRouted () const;
inline bool isGlobalFixed () const;
inline bool isMixedPreRoute () const; inline bool isMixedPreRoute () const;
inline bool isFixed () const; inline bool isFixed () const;
inline bool isExcluded () const;
inline bool isNoMoveUp ( Segment* ) const;
inline Net* getNet () const; inline Net* getNet () const;
inline NetRoutingState* getNetRoutingState () const; inline NetRoutingState* getNetRoutingState () const;
inline const Box& getSearchArea () const; inline const Box& getSearchArea () const;
inline DbU::Unit getHalfPerimeter () const; inline DbU::Unit getHalfPerimeter () const;
inline size_t getRpCount () const; inline size_t getRpCount () const;
inline size_t getDiodeRpCount () const;
inline DbU::Unit getSparsity () const; inline DbU::Unit getSparsity () const;
inline void setNetRoutingState ( NetRoutingState* ); inline void setNetRoutingState ( NetRoutingState* );
inline void setSearchArea ( Box ); inline void setSearchArea ( Box );
inline void setGlobalEstimated ( bool );
inline void setGlobalRouted ( bool ); inline void setGlobalRouted ( bool );
inline void setGlobalFixed ( bool );
inline void setExcluded ( bool );
inline void setRpCount ( size_t ); inline void setRpCount ( size_t );
inline void setNoMoveUp ( Segment* );
private: private:
NetData ( const NetData& ); NetData ( const NetData& );
NetData& operator= ( const NetData& ); NetData& operator= ( const NetData& );
inline void _update (); inline void _update ();
private: private:
Net* _net; Net* _net;
NetRoutingState* _state; NetRoutingState* _state;
Box _searchArea; Box _searchArea;
size_t _rpCount; size_t _rpCount;
size_t _diodeCount; DbU::Unit _sparsity;
DbU::Unit _sparsity; Flags _flags;
Flags _flags;
std::set<Segment*,DBo::CompareById> _noMoveUp;
}; };
inline bool NetData::isGlobalEstimated () const { return _flags & Flags::GlobalEstimated; }
inline bool NetData::isGlobalRouted () const { return _flags & Flags::GlobalRouted; } 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::isMixedPreRoute () const { return (_state) ? _state->isMixedPreRoute() : false; }
inline bool NetData::isFixed () const { return (_state) ? _state->isFixed () : 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 Net* NetData::getNet () const { return _net; }
inline NetRoutingState* NetData::getNetRoutingState () const { return _state; } inline NetRoutingState* NetData::getNetRoutingState () const { return _state; }
inline const Box& NetData::getSearchArea () const { return _searchArea; } inline const Box& NetData::getSearchArea () const { return _searchArea; }
inline DbU::Unit NetData::getHalfPerimeter () const { return (_searchArea.isEmpty()) ? 0.0 : (_searchArea.getWidth()+_searchArea.getHeight()); } 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::getRpCount () const { return _rpCount; }
inline size_t NetData::getDiodeRpCount () const { return _diodeCount; }
inline void NetData::setNetRoutingState ( NetRoutingState* state ) { _state=state; } inline void NetData::setNetRoutingState ( NetRoutingState* state ) { _state=state; }
inline DbU::Unit NetData::getSparsity () const { return _sparsity; } 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::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::setRpCount ( size_t count ) { _rpCount=count; _update(); }
inline void NetData::setNoMoveUp ( Segment* segment ) { _noMoveUp.insert(segment); }
inline void NetData::_update () inline void NetData::_update ()
@ -172,12 +153,7 @@ namespace Anabatic {
inline bool operator() ( const NetData* lhs, const NetData* rhs ) const inline bool operator() ( const NetData* lhs, const NetData* rhs ) const
{ {
if (lhs->isMixedPreRoute() != rhs->isMixedPreRoute()) return lhs->isMixedPreRoute(); if (lhs->isMixedPreRoute() != rhs->isMixedPreRoute()) return lhs->isMixedPreRoute();
if ((lhs->getRpCount() > 10) or (rhs->getRpCount() > 10)) { if (lhs->getSparsity() != rhs->getSparsity() ) return lhs->getSparsity() < rhs->getSparsity();
if (lhs->getRpCount() != rhs->getRpCount())
return lhs->getRpCount() > rhs->getRpCount();
}
if (lhs->getSparsity() != rhs->getSparsity()) return lhs->getSparsity() < rhs->getSparsity();
return lhs->getNet()->getId() < rhs->getNet()->getId(); return lhs->getNet()->getId() < rhs->getNet()->getId();
} }
}; };
@ -192,245 +168,185 @@ namespace Anabatic {
class AnabaticEngine : public ToolEngine { class AnabaticEngine : public ToolEngine {
public: public:
static const uint32_t DigitalMode = (1 << 0); enum DensityMode { AverageHVDensity=1 // Average between all densities.
static const uint32_t AnalogMode = (1 << 1); , AverageHDensity =2 // Average between all H densities.
static const uint32_t MixedMode = (1 << 2); , AverageVDensity =3 // Average between all V densities.
static const uint32_t AverageHVDensity = 1; // Average between all densities. , MaxHVDensity =4 // Maximum between average H and average V.
static const uint32_t AverageHDensity = 2; // Average between all H densities. , MaxVDensity =5 // Maximum of V densities.
static const uint32_t AverageVDensity = 3; // Average between all V densities. , MaxHDensity =6 // Maximum of H densities.
static const uint32_t MaxHVDensity = 4; // Maximum between average H and average V. , MaxDensity =7 // Maximum of H & V densities.
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.
public: public:
typedef ToolEngine Super; typedef ToolEngine Super;
public: public:
static AnabaticEngine* create ( Cell* ); static AnabaticEngine* create ( Cell* );
static AnabaticEngine* get ( const Cell* ); static AnabaticEngine* get ( const Cell* );
inline bool isCanonizeDisabled () const; static const Name& staticGetName ();
inline bool isDigitalMode () const; virtual const Name& getName () const;
inline bool isAnalogMode () const; virtual Configuration* getConfiguration ();
inline bool isMixedMode () const; inline uint64_t getDensityMode () const;
inline bool isChannelStyle () const; inline CellViewer* getViewer () const;
inline bool isHybridStyle () const; inline void setViewer ( CellViewer* );
static const Name& staticGetName (); inline EngineState getState () const;
virtual const Name& getName () const; inline const Matrix* getMatrix () const;
virtual Configuration* getConfiguration (); inline const vector<GCell*>& getGCells () const;
virtual const Configuration* getConfiguration () const; inline const vector<Edge*>& getOvEdges () const;
inline std::string getNetBuilderStyle () const; inline GCell* getSouthWestGCell () const;
inline StyleFlags getRoutingStyle () const; inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const;
inline uint64_t getDensityMode () const; inline GCell* getGCellUnder ( Point ) const;
inline CellViewer* getViewer () const; inline GCellsUnder getGCellsUnder ( Segment* ) const;
inline void setViewer ( CellViewer* ); Interval getUSide ( Flags direction ) const;
inline EngineState getState () const; int getCapacity ( Interval, Flags ) const;
inline const Matrix* getMatrix () const; size_t getNetsFromEdge ( const Edge*, NetSet& );
inline const vector<GCell*>& getGCells () const; virtual void openSession ();
inline const vector<Edge*>& getOvEdges () const; inline void setState ( EngineState state );
inline GCell* getSouthWestGCell () const; inline void setDensityMode ( uint64_t );
inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const; inline void addOv ( Edge* );
inline GCell* getGCellUnder ( Point ) const; inline void removeOv ( Edge* );
inline GCellsUnder getGCellsUnder ( Segment* ) const; inline const NetDatas& getNetDatas () const;
inline GCellsUnder getGCellsUnder ( Point source, Point target ) const; NetData* getNetData ( Net*, Flags flags=Flags::NoFlags );
inline Edges getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags=Flags::NorthPath ) const; void setupNetDatas ();
Interval getUSide ( Flags direction ) const; void updateMatrix ();
int getCapacity ( Interval, Flags ) const; // Dijkstra related functions.
size_t getNetsFromEdge ( const Edge*, NetSet& ); inline int getStamp () const;
virtual void openSession (); inline int incStamp ();
inline void setState ( EngineState state ); Contact* breakAt ( Segment*, GCell* );
inline void setDensityMode ( uint64_t ); void ripup ( Segment*, Flags );
inline void disableCanonize (); bool unify ( Contact* );
inline void enableCanonize (); // Global routing related functions.
inline void addOv ( Edge* ); void globalRoute ();
inline void removeOv ( Edge* ); void cleanupGlobal ();
inline const NetDatas& getNetDatas () const; // Detailed routing related functions.
NetData* getNetData ( Net*, Flags flags=Flags::NoFlags ); inline bool isInDemoMode () const;
void setupNetDatas (); inline bool isChip () const;
void exclude ( const Name& netName ); inline bool doWarnOnGCellOverload () const;
void exclude ( Net* ); inline bool doDestroyBaseContact () const;
void updateMatrix (); inline bool doDestroyBaseSegment () const;
bool checkPlacement () const; inline bool doDestroyTool () const;
// Dijkstra related functions. inline DbU::Unit getGlobalThreshold () const;
inline int getStamp () const; inline float getSaturateRatio () const;
inline int incStamp (); inline size_t getSaturateRp () const;
Contact* breakAt ( Segment*, GCell* ); inline DbU::Unit getExtensionCap () const;
void ripup ( Segment*, Flags ); inline Net* getBlockageNet () const;
bool unify ( Contact* ); inline const ChipTools& getChipTools () const;
// Global routing related functions. inline const vector<NetData*>& getNetOrdering () const;
void globalRoute (); void updateDensity ();
void cleanupGlobal (); size_t checkGCellDensities ();
void relaxOverConstraineds (); inline void setGlobalThreshold ( DbU::Unit );
// Detailed routing related functions. inline void setSaturateRatio ( float );
inline bool isInDemoMode () const; inline void setSaturateRp ( size_t );
inline bool isChip () const; inline void setBlockageNet ( Net* );
inline bool doWarnOnGCellOverload () const; void chipPrep ();
inline bool doDestroyBaseContact () const; void setupSpecialNets ();
inline bool doDestroyBaseSegment () const; void setupPreRouteds ();
inline bool doDestroyTool () const; void loadGlobalRouting ( uint32_t method );
inline DbU::Unit getAntennaGateMaxWL () const; void computeNetConstraints ( Net* );
inline DbU::Unit getAntennaDiodeMaxWL () const; void toOptimals ( Net* );
inline DbU::Unit getGlobalThreshold () const; void updateNetTopology ( Net* );
inline float getSaturateRatio () const; bool moveUpNetTrunk ( AutoSegment*, set<Net*>& globalNets, GCell::Set& invalidateds );
inline size_t getSaturateRp () const; void layerAssign ( uint32_t method );
inline DbU::Unit getExtensionCap () const; void finalizeLayout ();
inline Cell* getDiodeCell () const; inline const AutoContactLut& _getAutoContactLut () const;
inline Net* getBlockageNet () const; inline const AutoSegmentLut& _getAutoSegmentLut () const;
inline const ChipTools& getChipTools () const; void _link ( AutoContact* );
inline const vector<NetData*>& getNetOrdering () const; void _link ( AutoSegment* );
void invalidateRoutingPads (); void _unlink ( AutoContact* );
void updateDensity (); void _unlink ( AutoSegment* );
size_t checkGCellDensities (); AutoContact* _lookup ( Contact* ) const;
void setupNetBuilder (); AutoSegment* _lookup ( Segment* ) const;
inline void setRoutingMode ( uint32_t ); void _loadGrByNet ();
inline void resetRoutingMode ( uint32_t ); void _loadNetGlobalRouting ( Net* );
inline void setGlobalThreshold ( DbU::Unit ); void _computeNetOptimals ( Net* );
inline void setSaturateRatio ( float ); void _computeNetTerminals ( Net* );
inline void setSaturateRp ( size_t ); void _alignate ( Net* );
inline void setBlockageNet ( Net* ); void _desaturate ( unsigned int depth, set<Net*>&, unsigned long& total, unsigned long& globals );
void chipPrep (); void _layerAssignByLength ( unsigned long& total, unsigned long& global, set<Net*>& );
void computeEdgeCapacities ( int maxHCap, int maxVCap, int termSatThreshold, int maxTermSat ); void _layerAssignByLength ( Net*, unsigned long& total, unsigned long& global, set<Net*>& );
void antennaProtect ( Net*, uint32_t& failed, uint32_t& total ); void _layerAssignByTrunk ( unsigned long& total, unsigned long& global, set<Net*>& );
void antennaProtect (); void _layerAssignByTrunk ( Net*, set<Net*>&, unsigned long& total, unsigned long& global );
void setupSpecialNets (); void _saveNet ( Net* );
size_t setupPreRouteds (); void _destroyAutoContacts ();
void loadGlobalRouting ( uint32_t method ); void _destroyAutoSegments ();
void computeNetConstraints ( Net* ); void _check ( Net* net ) const;
void toOptimals ( Net* ); bool _check ( const char* message ) const;
void updateNetTopology ( Net* ); void printMeasures ( const string& tag ) const;
bool moveUpNetTrunk ( AutoSegment*, set<Net*>& globalNets, GCell::Set& invalidateds ); // Misc. functions.
void layerAssign ( uint32_t method ); inline const Flags& flags () const;
void finalizeLayout (); inline Flags& flags ();
void exportExternalNets (); void reset ();
inline const AutoContactLut& _getAutoContactLut () const; inline void _add ( GCell* );
inline const AutoSegmentLut& _getAutoSegmentLut () const; inline void _remove ( GCell* );
void _link ( AutoContact* ); inline void _updateLookup ( GCell* );
void _link ( AutoSegment* ); inline bool _inDestroy () const;
void _unlink ( AutoContact* ); // Inspector support.
void _unlink ( AutoSegment* ); virtual Record* _getRecord () const;
AutoContact* _lookup ( Contact* ) const; virtual string _getString () const;
AutoSegment* _lookup ( Segment* ) const; virtual string _getTypeName () const;
EdgeCapacity* _createCapacity ( Flags, Interval ); protected:
size_t _unrefCapacity ( EdgeCapacity* ); AnabaticEngine ( Cell* );
void _loadGrByNet (); virtual ~AnabaticEngine ();
void _computeNetOptimals ( Net* ); virtual void _postCreate ();
void _computeNetTerminals ( Net* ); virtual void _preDestroy ();
void _alignate ( Net* ); void _gutAnabatic ();
void _desaturate ( unsigned int depth, set<Net*>&, unsigned long& total, unsigned long& globals ); private:
void _layerAssignByLength ( unsigned long& total, unsigned long& global, set<Net*>& ); AnabaticEngine ( const AnabaticEngine& );
void _layerAssignByLength ( Net*, unsigned long& total, unsigned long& global, set<Net*>& ); AnabaticEngine& operator= ( const AnabaticEngine& );
void _layerAssignByTrunk ( unsigned long& total, unsigned long& global, set<Net*>& );
void _layerAssignByTrunk ( Net*, set<Net*>&, unsigned long& total, unsigned long& global );
void _layerAssignNoGlobalM2V ( unsigned long& total, unsigned long& global, set<Net*>& );
void _layerAssignNoGlobalM2V ( Net*, set<Net*>&, unsigned long& total, unsigned long& global );
void _saveNet ( Net* );
void _destroyAutoContacts ();
void _destroyAutoSegments ();
void _check ( Net* net ) const;
bool _check ( const char* message ) const;
void printMeasures ( const string& tag ) const;
// Misc. functions.
inline const Flags& flags () const;
inline Flags& flags ();
void reset ();
inline void _add ( GCell* );
inline void _remove ( GCell* );
inline void _updateLookup ( GCell* );
inline void _updateGContacts ( Flags flags=Flags::Horizontal|Flags::Vertical );
inline void _resizeMatrix ();
inline bool _inDestroy () const;
// Inspector support.
virtual Record* _getRecord () const;
virtual string _getString () const;
virtual string _getTypeName () const;
protected:
AnabaticEngine ( Cell* );
virtual ~AnabaticEngine ();
virtual void _postCreate ();
virtual void _preDestroy ();
void _gutAnabatic ();
virtual Configuration* _createConfiguration ();
private:
AnabaticEngine ( const AnabaticEngine& );
AnabaticEngine& operator= ( const AnabaticEngine& );
private: private:
static Name _toolName; static Name _toolName;
protected: Configuration* _configuration;
Configuration* _configuration; ChipTools _chipTools;
private: EngineState _state;
ChipTools _chipTools; Matrix _matrix;
EngineState _state; vector<GCell*> _gcells;
Matrix _matrix; vector<Edge*> _ovEdges;
vector<GCell*> _gcells; vector<NetData*> _netOrdering;
vector<Edge*> _ovEdges; NetDatas _netDatas;
vector<NetData*> _netOrdering; CellViewer* _viewer;
NetDatas _netDatas; Flags _flags;
CellViewer* _viewer; int _stamp;
Flags _flags; uint64_t _densityMode;
int _stamp; AutoSegmentLut _autoSegmentLut;
uint32_t _routingMode; AutoContactLut _autoContactLut;
uint64_t _densityMode; Net* _blockageNet;
AutoSegmentLut _autoSegmentLut;
AutoContactLut _autoContactLut;
EdgeCapacityLut _edgeCapacitiesLut;
Net* _blockageNet;
Cell* _diodeCell;
}; };
inline bool AnabaticEngine::isDigitalMode () const { return (_routingMode & DigitalMode); }; inline EngineState AnabaticEngine::getState () const { return _state; }
inline bool AnabaticEngine::isAnalogMode () const { return (_routingMode & AnalogMode); }; inline void AnabaticEngine::setState ( EngineState state ) { _state = state; }
inline bool AnabaticEngine::isMixedMode () const { return (_routingMode & MixedMode); }; inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; }
inline bool AnabaticEngine::isChannelStyle () const { return (_configuration->getRoutingStyle() & StyleFlags::Channel); }; inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; }
inline bool AnabaticEngine::isHybridStyle () const { return (_configuration->getRoutingStyle() & StyleFlags::Hybrid); }; inline const Matrix* AnabaticEngine::getMatrix () const { return &_matrix; }
inline void AnabaticEngine::setRoutingMode ( uint32_t mode ) { _routingMode |= mode; }; inline const vector<GCell*>& AnabaticEngine::getGCells () const { return _gcells; }
inline void AnabaticEngine::resetRoutingMode ( uint32_t mode ) { _routingMode &= ~mode; }; inline const vector<Edge*>& AnabaticEngine::getOvEdges () const { return _ovEdges; }
inline EngineState AnabaticEngine::getState () const { return _state; } inline GCell* AnabaticEngine::getSouthWestGCell () const { return _gcells[0]; }
inline void AnabaticEngine::setState ( EngineState state ) { _state = state; } inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); }
inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; } inline GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); }
inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; } inline GCellsUnder AnabaticEngine::getGCellsUnder ( Segment* s ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,s) ); }
inline const Matrix* AnabaticEngine::getMatrix () const { return &_matrix; } inline uint64_t AnabaticEngine::getDensityMode () const { return _densityMode; }
inline const vector<GCell*>& AnabaticEngine::getGCells () const { return _gcells; } inline void AnabaticEngine::setDensityMode ( uint64_t mode ) { _densityMode=mode; }
inline const vector<Edge*>& AnabaticEngine::getOvEdges () const { return _ovEdges; } inline void AnabaticEngine::setBlockageNet ( Net* net ) { _blockageNet = net; }
inline GCell* AnabaticEngine::getSouthWestGCell () const { return _gcells[0]; } inline const AutoContactLut& AnabaticEngine::_getAutoContactLut () const { return _autoContactLut; }
inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); } inline const AutoSegmentLut& AnabaticEngine::_getAutoSegmentLut () const { return _autoSegmentLut; }
inline GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); } inline const Flags& AnabaticEngine::flags () const { return _flags; }
inline GCellsUnder AnabaticEngine::getGCellsUnder ( Segment* s ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,s) ); } inline Flags& AnabaticEngine::flags () { return _flags; }
inline GCellsUnder AnabaticEngine::getGCellsUnder ( Point source, Point target ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,source,target) ); } inline bool AnabaticEngine::doDestroyBaseContact () const { return _flags & Flags::DestroyBaseContact; }
inline Edges AnabaticEngine::getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags ) const { return new Path_Edges(source,target,pathFlags); } inline bool AnabaticEngine::doDestroyBaseSegment () const { return _flags & Flags::DestroyBaseSegment; }
inline uint64_t AnabaticEngine::getDensityMode () const { return _densityMode; } inline bool AnabaticEngine::doDestroyTool () const { return _state >= EngineGutted; }
inline void AnabaticEngine::setDensityMode ( uint64_t mode ) { _densityMode=mode; } inline bool AnabaticEngine::doWarnOnGCellOverload () const { return _flags & Flags::WarnOnGCellOverload; }
inline void AnabaticEngine::setBlockageNet ( Net* net ) { _blockageNet = net; } inline bool AnabaticEngine::isInDemoMode () const { return _flags & Flags::DemoMode; }
inline const AutoContactLut& AnabaticEngine::_getAutoContactLut () const { return _autoContactLut; } inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); }
inline const AutoSegmentLut& AnabaticEngine::_getAutoSegmentLut () const { return _autoSegmentLut; } inline DbU::Unit AnabaticEngine::getGlobalThreshold () const { return _configuration->getGlobalThreshold(); }
inline const Flags& AnabaticEngine::flags () const { return _flags; } inline float AnabaticEngine::getSaturateRatio () const { return _configuration->getSaturateRatio(); }
inline Flags& AnabaticEngine::flags () { return _flags; } inline size_t AnabaticEngine::getSaturateRp () const { return _configuration->getSaturateRp(); }
inline bool AnabaticEngine::doDestroyBaseContact () const { return _flags & Flags::DestroyBaseContact; } inline void AnabaticEngine::setSaturateRatio ( float ratio ) { _configuration->setSaturateRatio(ratio); }
inline bool AnabaticEngine::doDestroyBaseSegment () const { return _flags & Flags::DestroyBaseSegment; } inline void AnabaticEngine::setSaturateRp ( size_t threshold ) { _configuration->setSaturateRp(threshold); }
inline bool AnabaticEngine::doDestroyTool () const { return _state >= EngineGutted; } inline Net* AnabaticEngine::getBlockageNet () const { return _blockageNet; }
inline bool AnabaticEngine::doWarnOnGCellOverload () const { return _flags & Flags::WarnOnGCellOverload; } inline const ChipTools& AnabaticEngine::getChipTools () const { return _chipTools; }
inline bool AnabaticEngine::isCanonizeDisabled () const { return _flags & Flags::DisableCanonize; } inline const vector<NetData*>& AnabaticEngine::getNetOrdering () const { return _netOrdering; }
inline bool AnabaticEngine::isInDemoMode () const { return _flags & Flags::DemoMode; } inline void AnabaticEngine::setGlobalThreshold ( DbU::Unit threshold ) { _configuration->setGlobalThreshold(threshold); }
inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); } inline const NetDatas& AnabaticEngine::getNetDatas () const { return _netDatas; }
inline std::string AnabaticEngine::getNetBuilderStyle () const { return _configuration->getNetBuilderStyle(); } inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); }
inline StyleFlags AnabaticEngine::getRoutingStyle () const { return _configuration->getRoutingStyle(); } inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; }
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 void AnabaticEngine::_add ( GCell* gcell ) inline void AnabaticEngine::_add ( GCell* gcell )
{ {
@ -451,15 +367,12 @@ namespace Anabatic {
inline int AnabaticEngine::getStamp () const { return _stamp; } inline int AnabaticEngine::getStamp () const { return _stamp; }
inline int AnabaticEngine::incStamp () { return ++_stamp; } inline int AnabaticEngine::incStamp () { return ++_stamp; }
inline void AnabaticEngine::addOv ( Edge* edge ) { inline void AnabaticEngine::addOv ( Edge* edge ) { _ovEdges.push_back(edge); }
_ovEdges.push_back(edge);
}
inline void AnabaticEngine::removeOv ( Edge* edge ) inline void AnabaticEngine::removeOv ( Edge* edge )
{ {
for ( auto iedge = _ovEdges.begin() ; iedge != _ovEdges.end() ; ++iedge ) { for ( auto iedge = _ovEdges.begin() ; iedge != _ovEdges.end() ; ++iedge )
if (*iedge == edge) { _ovEdges.erase(iedge); return; } if (*iedge == edge) { _ovEdges.erase(iedge); break; }
}
} }
@ -469,3 +382,5 @@ namespace Anabatic {
INSPECTOR_P_SUPPORT(Anabatic::AnabaticEngine); INSPECTOR_P_SUPPORT(Anabatic::AnabaticEngine);
#endif // ANABATIC_ANABATIC_ENGINE_H

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2018, All Rights Reserved // Copyright (c) UPMC 2008-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -35,7 +35,6 @@ namespace Anabatic {
using Hurricane::setInBound; using Hurricane::setInBound;
using Hurricane::tab; using Hurricane::tab;
using Hurricane::Name; using Hurricane::Name;
using Hurricane::Entity;
using Hurricane::Net; using Hurricane::Net;
using Hurricane::Component; using Hurricane::Component;
using Hurricane::Components; using Hurricane::Components;
@ -49,7 +48,7 @@ namespace Anabatic {
class AutoContact; class AutoContact;
typedef std::map<Contact*,AutoContact*,Entity::CompareById> AutoContactLut; typedef std::map<Contact*,AutoContact*> AutoContactLut;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -68,11 +67,6 @@ namespace Anabatic {
, CntIgnoreAnchor = (1 << 11) , CntIgnoreAnchor = (1 << 11)
, CntWeakTerminal = (1 << 12) , CntWeakTerminal = (1 << 12)
, CntUserNativeConstraints = (1 << 13) , CntUserNativeConstraints = (1 << 13)
, CntOnVertical = (1 << 14)
, CntOnHorizontal = (1 << 15)
, CntDrag = (1 << 16)
, CntHDogleg = (1 << 17)
, CntVDogleg = (1 << 18)
}; };
class AutoContact { class AutoContact {
@ -103,7 +97,7 @@ namespace Anabatic {
inline void setSizes ( DbU::Unit width, DbU::Unit height ); inline void setSizes ( DbU::Unit width, DbU::Unit height );
inline void setX ( DbU::Unit ); inline void setX ( DbU::Unit );
inline void setY ( DbU::Unit ); inline void setY ( DbU::Unit );
inline void setPosition ( DbU::Unit x, DbU::Unit y ); inline void setPosition ( DbU::Unit width, DbU::Unit height );
inline void setPosition ( const Point& ); inline void setPosition ( const Point& );
inline void setDx ( DbU::Unit ); inline void setDx ( DbU::Unit );
inline void setDy ( DbU::Unit ); inline void setDy ( DbU::Unit );
@ -121,20 +115,15 @@ namespace Anabatic {
inline bool isVTee () const; inline bool isVTee () const;
inline bool isFixed () const; inline bool isFixed () const;
inline bool isUserNativeConstraints () const; inline bool isUserNativeConstraints () const;
inline bool isHDogleg () const;
inline bool isVDogleg () const;
virtual bool isOnPin () const;
inline bool hasBadTopology () const; inline bool hasBadTopology () const;
bool canDestroy ( Flags flags=Flags::NoFlags ) const; bool canDestroy ( Flags flags=Flags::NoFlags ) const;
bool canMoveUp ( const AutoSegment* moved ) const; bool canMoveUp ( const AutoSegment* moved ) const;
inline bool canDrag () const;
// Accessors. // Accessors.
inline Contact* base () const; inline Contact* base () const;
static size_t getAllocateds (); static size_t getAllocateds ();
static const Name& getStaticName (); static const Name& getStaticName ();
virtual const Name& getName () const; virtual const Name& getName () const;
inline size_t getId () const; inline size_t getId () const;
inline Flags getFlags () const;
virtual Box getBoundingBox () const; virtual Box getBoundingBox () const;
inline GCell* getGCell () const; inline GCell* getGCell () const;
virtual AutoSegment* getOpposite ( const AutoSegment* ) const = 0; virtual AutoSegment* getOpposite ( const AutoSegment* ) const = 0;
@ -164,7 +153,6 @@ namespace Anabatic {
virtual void cacheDetach ( AutoSegment* ) = 0; virtual void cacheDetach ( AutoSegment* ) = 0;
virtual void cacheAttach ( AutoSegment* ) = 0; virtual void cacheAttach ( AutoSegment* ) = 0;
virtual void updateCache () = 0; virtual void updateCache () = 0;
void updateLayer ();
void updateSize (); void updateSize ();
virtual void updateGeometry () = 0; virtual void updateGeometry () = 0;
virtual void updateTopology () = 0; virtual void updateTopology () = 0;
@ -184,7 +172,6 @@ namespace Anabatic {
, Flags flags=Flags::WarnOnError ); , Flags flags=Flags::WarnOnError );
void restoreNativeConstraintBox (); void restoreNativeConstraintBox ();
void migrateConstraintBox ( AutoContact* other ); void migrateConstraintBox ( AutoContact* other );
void setLayerAndWidth ( size_t delta, size_t depth );
void destroy (); void destroy ();
// Inspector Management. // Inspector Management.
Record* _getRecord () const; Record* _getRecord () const;
@ -265,12 +252,8 @@ namespace Anabatic {
inline bool AutoContact::isTerminal () const { return _flags&CntTerminal; } inline bool AutoContact::isTerminal () const { return _flags&CntTerminal; }
inline bool AutoContact::isHTee () const { return _flags&CntHTee; } inline bool AutoContact::isHTee () const { return _flags&CntHTee; }
inline bool AutoContact::isVTee () const { return _flags&CntVTee; } 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::hasBadTopology () const { return _flags&CntBadTopology; }
inline bool AutoContact::canDrag () const { return _flags&CntDrag; }
inline size_t AutoContact::getId () const { return _id; } inline size_t AutoContact::getId () const { return _id; }
inline Flags AutoContact::getFlags () const { return _flags; }
inline Contact* AutoContact::base () const { return _contact; } inline Contact* AutoContact::base () const { return _contact; }
inline GCell* AutoContact::getGCell () const { return _gcell; } inline GCell* AutoContact::getGCell () const { return _gcell; }
inline Box AutoContact::getConstraintBox () const { return Box(getCBXMin(),getCBYMin(),getCBXMax(),getCBYMax()); } inline Box AutoContact::getConstraintBox () const { return Box(getCBXMin(),getCBYMin(),getCBXMax(),getCBYMax()); }

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2012-2018, All Rights Reserved // Copyright (c) UPMC 2012-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved // Copyright (c) UPMC/LIP6 2012-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -60,7 +60,6 @@ namespace Anabatic {
virtual void _invalidate ( Flags flags ); virtual void _invalidate ( Flags flags );
public: public:
bool isEndPoint () const; bool isEndPoint () const;
virtual bool isOnPin () const;
virtual Box getNativeConstraintBox () const; virtual Box getNativeConstraintBox () const;
RoutingPad* getRoutingPad () const; RoutingPad* getRoutingPad () const;
inline AutoSegment* getSegment () const; inline AutoSegment* getSegment () const;

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2012-2018, All Rights Reserved // Copyright (c) UPMC 2012-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2012-2018, All Rights Reserved // Copyright (c) UPMC 2012-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |

View File

@ -14,9 +14,11 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#pragma once #ifndef ANABATIC_AUTOHORIZONTAL_H
#include "hurricane/Horizontal.h" #define ANABATIC_AUTOHORIZONTAL_H
#include "anabatic/AutoSegment.h"
#include "hurricane/Horizontal.h"
#include "anabatic/AutoSegment.h"
namespace Anabatic { namespace Anabatic {
@ -47,7 +49,7 @@ namespace Anabatic {
virtual Interval getSourceConstraints ( Flags flags=0 ) const; virtual Interval getSourceConstraints ( Flags flags=0 ) const;
virtual Interval getTargetConstraints ( Flags flags=0 ) const; virtual Interval getTargetConstraints ( Flags flags=0 ) const;
virtual Flags getDirection () const; virtual Flags getDirection () const;
virtual bool getGCells ( vector<GCell*>& ) const; virtual size_t getGCells ( vector<GCell*>& ) const;
// Modifiers. // Modifiers.
virtual void setDuSource ( DbU::Unit ); virtual void setDuSource ( DbU::Unit );
virtual void setDuTarget ( DbU::Unit ); virtual void setDuTarget ( DbU::Unit );
@ -89,3 +91,6 @@ namespace Anabatic {
INSPECTOR_P_SUPPORT(Anabatic::AutoHorizontal); INSPECTOR_P_SUPPORT(Anabatic::AutoHorizontal);
#endif // ANABATIC_AUTOHORIZONTAL_H

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2018, All Rights Reserved // Copyright (c) UPMC 2008-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -14,8 +14,9 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#pragma once #ifndef ANABATIC_AUTOSEGMENT_H
#include <tuple> #define ANABATIC_AUTOSEGMENT_H
#include <set> #include <set>
#include <iostream> #include <iostream>
#include <functional> #include <functional>
@ -38,8 +39,6 @@ namespace Hurricane {
namespace Anabatic { namespace Anabatic {
using std::tuple;
using std::array;
using std::set; using std::set;
using std::cerr; using std::cerr;
using std::endl; using std::endl;
@ -58,10 +57,11 @@ namespace Anabatic {
class AutoHorizontal; class AutoHorizontal;
class AutoVertical; class AutoVertical;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Class : "AutoSegment". // Class : "AutoSegment".
class AutoSegment { class AutoSegment {
friend class AutoHorizontal; friend class AutoHorizontal;
friend class AutoVertical; friend class AutoVertical;
@ -70,46 +70,38 @@ namespace Anabatic {
static const uint64_t SegNoFlags = 0L; static const uint64_t SegNoFlags = 0L;
static const uint64_t SegHorizontal = (1L<< 0); static const uint64_t SegHorizontal = (1L<< 0);
static const uint64_t SegFixed = (1L<< 1); static const uint64_t SegFixed = (1L<< 1);
static const uint64_t SegFixedAxis = (1L<< 2); static const uint64_t SegGlobal = (1L<< 2);
static const uint64_t SegGlobal = (1L<< 3); static const uint64_t SegWeakGlobal = (1L<< 3);
static const uint64_t SegWeakGlobal = (1L<< 4); static const uint64_t SegLongLocal = (1L<< 4);
static const uint64_t SegLongLocal = (1L<< 5); static const uint64_t SegCanonical = (1L<< 5);
static const uint64_t SegCanonical = (1L<< 6); static const uint64_t SegBipoint = (1L<< 6);
static const uint64_t SegBipoint = (1L<< 7); static const uint64_t SegDogleg = (1L<< 7);
static const uint64_t SegDogleg = (1L<< 8); static const uint64_t SegStrap = (1L<< 8);
static const uint64_t SegStrap = (1L<< 9); static const uint64_t SegSourceTop = (1L<< 9);
static const uint64_t SegSourceTop = (1L<<10); static const uint64_t SegSourceBottom = (1L<<10);
static const uint64_t SegSourceBottom = (1L<<11); static const uint64_t SegTargetTop = (1L<<11);
static const uint64_t SegTargetTop = (1L<<12); static const uint64_t SegTargetBottom = (1L<<12);
static const uint64_t SegTargetBottom = (1L<<13); static const uint64_t SegIsReduced = (1L<<13);
static const uint64_t SegIsReduced = (1L<<14); static const uint64_t SegLayerChange = (1L<<14);
static const uint64_t SegDrag = (1L<<15); static const uint64_t SegSourceTerminal = (1L<<15); // Replace Terminal.
static const uint64_t SegLayerChange = (1L<<16); static const uint64_t SegTargetTerminal = (1L<<16); // Replace Terminal.
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 SegStrongTerminal = SegSourceTerminal|SegTargetTerminal;
static const uint64_t SegWeakTerminal1 = (1L<<19); // Replace TopologicalEnd. static const uint64_t SegWeakTerminal1 = (1L<<17); // Replace TopologicalEnd.
static const uint64_t SegWeakTerminal2 = (1L<<20); // Replace TopologicalEnd. static const uint64_t SegWeakTerminal2 = (1L<<18); // Replace TopologicalEnd.
static const uint64_t SegNotSourceAligned = (1L<<21); static const uint64_t SegNotSourceAligned = (1L<<19);
static const uint64_t SegNotTargetAligned = (1L<<22); static const uint64_t SegNotTargetAligned = (1L<<20);
static const uint64_t SegUnbound = (1L<<23); static const uint64_t SegUnbound = (1L<<21);
static const uint64_t SegHalfSlackened = (1L<<24); static const uint64_t SegHalfSlackened = (1L<<22);
static const uint64_t SegSlackened = (1L<<25); static const uint64_t SegSlackened = (1L<<23);
static const uint64_t SegAxisSet = (1L<<26); static const uint64_t SegAxisSet = (1L<<24);
static const uint64_t SegInvalidated = (1L<<27); static const uint64_t SegInvalidated = (1L<<25);
static const uint64_t SegInvalidatedSource = (1L<<28); static const uint64_t SegInvalidatedSource = (1L<<26);
static const uint64_t SegInvalidatedTarget = (1L<<29); static const uint64_t SegInvalidatedTarget = (1L<<27);
static const uint64_t SegInvalidatedLayer = (1L<<30); static const uint64_t SegInvalidatedLayer = (1L<<28);
static const uint64_t SegCreated = (1L<<31); static const uint64_t SegCreated = (1L<<29);
static const uint64_t SegUserDefined = (1L<<32); static const uint64_t SegUserDefined = (1L<<30);
static const uint64_t SegAnalog = (1L<<33); static const uint64_t SegAnalog = (1L<<31);
static const uint64_t SegWide = (1L<<34); static const uint64_t SegWide = (1L<<32);
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. // Masks.
static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2; static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2;
static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned; static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned;
@ -138,287 +130,252 @@ namespace Anabatic {
public: public:
typedef std::function< void(AutoSegment*) > RevalidateCb_t; typedef std::function< void(AutoSegment*) > RevalidateCb_t;
public: public:
static void setAnalogMode ( bool ); static void setAnalogMode ( bool );
static bool getAnalogMode (); static bool getAnalogMode ();
static void setShortNetMode ( bool ); static AutoSegment* create ( AutoContact* source
inline static DbU::Unit getViaToTopCap ( size_t depth ); , AutoContact* target
inline static DbU::Unit getViaToBottomCap ( size_t depth ); , Segment* hurricaneSegment
inline static DbU::Unit getViaToSameCap ( size_t depth ); );
inline static DbU::Unit getMinimalLength ( size_t depth ); static AutoSegment* create ( AutoContact* source
static AutoSegment* create ( AutoContact* source , AutoContact* target
, AutoContact* target , Flags dir
, Segment* hurricaneSegment , size_t depth=RoutingGauge::nlayerdepth
); );
static AutoSegment* create ( AutoContact* source void destroy ();
, AutoContact* target
, Flags dir
, size_t depth=RoutingGauge::nlayerdepth
);
void destroy ();
// Wrapped Segment Functions. // Wrapped Segment Functions.
virtual Segment* base () const = 0; virtual Segment* base () const = 0;
virtual Segment* base () = 0; virtual Segment* base () = 0;
virtual Horizontal* getHorizontal () { return NULL; }; virtual Horizontal* getHorizontal () { return NULL; };
virtual Vertical* getVertical () { return NULL; }; virtual Vertical* getVertical () { return NULL; };
inline Cell* getCell () const; inline Cell* getCell () const;
inline Net* getNet () const; inline Net* getNet () const;
inline const Layer* getLayer () const; inline const Layer* getLayer () const;
inline Box getBoundingBox () const; inline Box getBoundingBox () const;
inline Hook* getSourceHook (); inline Hook* getSourceHook ();
inline Hook* getTargetHook (); inline Hook* getTargetHook ();
inline Contact* getSource () const; inline Contact* getSource () const;
inline Contact* getTarget () const; inline Contact* getTarget () const;
inline Component* getOppositeAnchor ( Component* ) const; inline Component* getOppositeAnchor ( Component* ) const;
inline Components getAnchors () const; inline Components getAnchors () const;
virtual DbU::Unit getX () const; virtual DbU::Unit getX () const;
virtual DbU::Unit getY () const; virtual DbU::Unit getY () const;
inline DbU::Unit getWidth () const; inline DbU::Unit getWidth () const;
inline DbU::Unit getContactWidth () const; inline DbU::Unit getContactWidth () const;
inline DbU::Unit getLength () const; inline DbU::Unit getLength () const;
inline DbU::Unit getSpanLength () const; inline DbU::Unit getSourcePosition () const;
inline DbU::Unit getAnchoredLength () const; inline DbU::Unit getTargetPosition () const;
inline DbU::Unit getSourcePosition () const; inline DbU::Unit getSourceX () const;
inline DbU::Unit getTargetPosition () const; inline DbU::Unit getSourceY () const;
inline DbU::Unit getSourceX () const; inline DbU::Unit getTargetX () const;
inline DbU::Unit getSourceY () const; inline DbU::Unit getTargetY () const;
inline DbU::Unit getTargetX () const; inline void invert ();
inline DbU::Unit getTargetY () const; inline void setLayer ( const Layer* );
inline void invert ();
inline void setLayer ( const Layer* );
inline void setLayer ( size_t depth );
inline void setWidth ( DbU::Unit );
// Predicates. // Predicates.
inline bool isHorizontal () const; inline bool isHorizontal () const;
inline bool isVertical () const; inline bool isVertical () const;
inline bool isGlobal () const; inline bool isGlobal () const;
inline bool isWeakGlobal () const; inline bool isWeakGlobal () const;
inline bool isLongLocal () const; inline bool isLongLocal () const;
inline bool isLocal () const; inline bool isLocal () const;
inline bool isFixed () const; inline bool isFixed () const;
inline bool isFixedAxis () const; inline bool isBipoint () const;
inline bool isBipoint () const; inline bool isWeakTerminal () const;
inline bool isWeakTerminal () const; inline bool isWeakTerminal1 () const;
inline bool isWeakTerminal1 () const; inline bool isWeakTerminal2 () const;
inline bool isWeakTerminal2 () const; inline bool isTerminal () const;
inline bool isTerminal () const; inline bool isNotSourceAligned () const;
inline bool isUnbreakable () const; inline bool isNotTargetAligned () const;
inline bool isNonPref () const; inline bool isNotAligned () const;
inline bool isNonPrefOnVSmall () const; bool isStrongTerminal ( Flags flags=Flags::NoFlags ) const;
inline bool isDrag () const; inline bool isSourceTerminal () const;
inline bool isAtMinArea () const; inline bool isTargetTerminal () const;
inline bool isNotSourceAligned () const; inline bool isLayerChange () const;
inline bool isNotTargetAligned () const; inline bool isSpinTop () const;
inline bool isNotAligned () const; inline bool isSpinBottom () const;
bool isStrongTerminal ( Flags flags=Flags::NoFlags ) const; inline bool isSpinTopOrBottom () const;
inline bool isSourceTerminal () const; inline bool isReduced () const;
inline bool isTargetTerminal () const; inline bool isStrap () const;
inline bool isLayerChange () const; inline bool isDogleg () const;
inline bool isStackedStrap () const; inline bool isUnbound () const;
inline bool isSpinTop () const; inline bool isInvalidated () const;
inline bool isSpinBottom () const; inline bool isInvalidatedLayer () const;
inline bool isSpinTopOrBottom () const; inline bool isCreated () const;
inline bool isReduced () const; inline bool isCanonical () const;
inline bool isStrap () const; inline bool isUnsetAxis () const;
inline bool isDogleg () const; inline bool isSlackened () const;
inline bool isUnbound () const; inline bool isUserDefined () const;
inline bool isInvalidated () const; bool isReduceCandidate () const;
inline bool isInvalidatedLayer () const; bool isUTurn () const;
inline bool isCreated () const; inline bool isAnalog () const;
inline bool isCanonical () const; inline bool isWide () const;
inline bool isUnsetAxis () const; virtual bool _canSlacken () const = 0;
inline bool isSlackened () const; bool canReduce () const;
inline bool isUserDefined () const; bool mustRaise () const;
bool isNearMinArea () const; Flags canDogleg ( Interval );
bool isReduceCandidate () const; virtual bool canMoveULeft ( float reserve=0.0 ) const = 0;
bool isUTurn () const; virtual bool canMoveURight ( float reserve=0.0 ) const = 0;
inline bool isAnalog () const; bool canMoveUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
inline bool isWide () const; bool canPivotUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
inline bool isShortNet () const; bool canPivotDown ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
inline bool isNoMoveUp () const; bool canSlacken ( Flags flags=Flags::NoFlags ) const;
virtual bool _canSlacken () const = 0; virtual bool checkPositions () const = 0;
bool canReduce ( Flags flags=Flags::WithPerpands ) const; virtual bool checkConstraints () const = 0;
bool mustRaise () const; bool checkDepthSpin () 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. // Accessors.
inline unsigned long getId () const; inline unsigned long getId () const;
inline uint64_t getFlags () const; inline uint64_t getFlags () const;
virtual Flags getDirection () const = 0; virtual Flags getDirection () const = 0;
inline GCell* getGCell () const; inline GCell* getGCell () const;
virtual bool getGCells ( vector<GCell*>& ) const = 0; virtual size_t getGCells ( vector<GCell*>& ) const = 0;
inline AutoContact* getAutoSource () const; inline AutoContact* getAutoSource () const;
inline AutoContact* getAutoTarget () const; inline AutoContact* getAutoTarget () const;
AutoContact* getOppositeAnchor ( AutoContact* ) const; AutoContact* getOppositeAnchor ( AutoContact* ) const;
size_t getPerpandicularsBound ( set<AutoSegment*>& ); size_t getPerpandicularsBound ( set<AutoSegment*>& );
inline AutoSegment* getParent () const; inline AutoSegment* getParent () const;
inline unsigned int getRpDistance () const; inline unsigned int getDepth () const;
inline unsigned int getDepth () const; inline DbU::Unit getPitch () const;
inline DbU::Unit getPitch () const; DbU::Unit getPPitch () const;
DbU::Unit getPPitch () const; DbU::Unit getExtensionCap () const;
#if DISABLED inline DbU::Unit getAxis () const;
DbU::Unit getExtensionCap () const; virtual DbU::Unit getSourceU () const = 0;
#endif virtual DbU::Unit getTargetU () const = 0;
DbU::Unit getExtensionCap ( Flags ) const; virtual DbU::Unit getDuSource () const = 0;
inline DbU::Unit getAxis () const; virtual DbU::Unit getDuTarget () const = 0;
void getEndAxes ( DbU::Unit& sourceAxis, DbU::Unit& targetAxis ) const; inline DbU::Unit getOrigin () const;
virtual DbU::Unit getSourceU () const = 0; inline DbU::Unit getExtremity () const;
virtual DbU::Unit getTargetU () const = 0; virtual Interval getSpanU () const = 0;
virtual DbU::Unit getDuSource () const = 0; Interval getMinSpanU () const;
virtual DbU::Unit getDuTarget () const = 0; virtual Interval getSourceConstraints ( Flags flags=Flags::NoFlags ) const = 0;
inline DbU::Unit getOrigin () const; virtual Interval getTargetConstraints ( Flags flags=Flags::NoFlags ) const = 0;
inline DbU::Unit getExtremity () const; virtual bool getConstraints ( DbU::Unit& min, DbU::Unit& max ) const = 0;
virtual Interval getSpanU () const = 0; inline bool getConstraints ( Interval& i ) const;
Interval getMinSpanU () const; inline const Interval& getUserConstraints () const;
virtual Interval getSourceConstraints ( Flags flags=Flags::NoFlags ) const = 0; inline const Interval& getNativeConstraints () const;
virtual Interval getTargetConstraints ( Flags flags=Flags::NoFlags ) const = 0; virtual DbU::Unit getSlack () const;
virtual bool getConstraints ( DbU::Unit& min, DbU::Unit& max ) const = 0; inline DbU::Unit getOptimalMin () const;
inline bool getConstraints ( Interval& i ) const; inline DbU::Unit getOptimalMax () const;
inline const Interval& getUserConstraints () const; inline DbU::Unit getNativeMin () const;
inline const Interval& getNativeConstraints () const; inline DbU::Unit getNativeMax () const;
virtual DbU::Unit getSlack () const; Interval& getOptimal ( Interval& i ) const;
inline DbU::Unit getOptimalMin () const; virtual DbU::Unit getCost ( DbU::Unit axis ) const;
inline DbU::Unit getOptimalMax () const; virtual AutoSegment* getCanonical ( DbU::Unit& min , DbU::Unit& max );
inline DbU::Unit getNativeMin () const; inline AutoSegment* getCanonical ( Interval& i );
inline DbU::Unit getNativeMax () const; float getMaxUnderDensity ( Flags flags );
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 );
inline uint32_t getReduceds () const;
uint32_t getNonReduceds ( Flags flags=Flags::WithPerpands ) const;
// Modifiers. // Modifiers.
inline void unsetFlags ( uint64_t ); inline void unsetFlags ( uint64_t );
inline void setFlags ( uint64_t ); inline void setFlags ( uint64_t );
void setFlagsOnAligneds ( uint64_t ); void setFlagsOnAligneds ( uint64_t );
inline void setRpDistance ( unsigned int ); inline void incReduceds ();
inline void incReduceds (); inline void decReduceds ();
inline void decReduceds (); virtual void setDuSource ( DbU::Unit du ) = 0;
virtual void setDuSource ( DbU::Unit du ) = 0; virtual void setDuTarget ( DbU::Unit du ) = 0;
virtual void setDuTarget ( DbU::Unit du ) = 0; void computeTerminal ();
void computeTerminal (); virtual void updateOrient () = 0;
virtual void updateOrient () = 0; virtual void updatePositions () = 0;
virtual void updatePositions () = 0; virtual void updateNativeConstraints () = 0;
virtual void updateNativeConstraints () = 0; void updateSourceSpin ();
void updateSourceSpin (); void updateTargetSpin ();
void updateTargetSpin (); void sourceDetach ();
void sourceDetach (); void targetDetach ();
void targetDetach (); void sourceAttach ( AutoContact* );
void sourceAttach ( AutoContact* ); void targetAttach ( AutoContact* );
void targetAttach ( AutoContact* ); //inline void mergeUserConstraints ( const Interval& );
//inline void mergeUserConstraints ( const Interval& ); void mergeUserConstraints ( const Interval& );
void mergeUserConstraints ( const Interval& ); inline void resetUserConstraints ();
inline void resetUserConstraints (); inline void setOptimalMin ( DbU::Unit min );
inline void setOptimalMin ( DbU::Unit min ); inline void setOptimalMax ( DbU::Unit max );
inline void setOptimalMax ( DbU::Unit max ); inline void mergeNativeMin ( DbU::Unit min );
inline void mergeNativeMin ( DbU::Unit min ); inline void mergeNativeMax ( DbU::Unit max );
inline void mergeNativeMax ( DbU::Unit max ); inline void resetNativeConstraints ( DbU::Unit min, DbU::Unit max );
inline void resetNativeConstraints ( DbU::Unit min, DbU::Unit max ); bool checkNotInvalidated () const;
bool checkNotInvalidated () const; inline void setParent ( AutoSegment* );
inline void setParent ( AutoSegment* ); void revalidate ();
void revalidate (); AutoSegment* makeDogleg ( AutoContact* );
AutoSegment* makeDogleg ( AutoContact* ); Flags makeDogleg ( Interval, Flags flags=Flags::NoFlags );
Flags makeDogleg ( Interval, Flags flags=Flags::NoFlags ); Flags makeDogleg ( GCell* , Flags flags=Flags::NoFlags );
Flags makeDogleg ( GCell* , Flags flags=Flags::NoFlags ); virtual Flags _makeDogleg ( GCell* , Flags flags ) = 0;
virtual Flags _makeDogleg ( GCell* , Flags flags ) = 0; virtual bool moveULeft () = 0;
virtual bool moveULeft () = 0; virtual bool moveURight () = 0;
virtual bool moveURight () = 0; bool slacken ( Flags flags );
bool slacken ( Flags flags ); virtual bool _slacken ( Flags flags ) = 0;
virtual bool _slacken ( Flags flags ) = 0; void _changeDepth ( unsigned int depth, Flags flags );
void _changeDepth ( unsigned int depth, Flags flags ); void changeDepth ( unsigned int depth, Flags flags );
void changeDepth ( unsigned int depth, Flags flags ); bool moveUp ( Flags flags=Flags::NoFlags );
bool moveUp ( Flags flags=Flags::NoFlags ); bool moveDown ( Flags flags=Flags::NoFlags );
bool moveDown ( Flags flags=Flags::NoFlags ); bool reduceDoglegLayer ();
bool reduceDoglegLayer (); bool reduce ();
bool bloatStackedStrap (); bool raise ();
bool reduce ( Flags flags=Flags::WithPerpands );
bool raise ();
void expandToMinLength ( Interval );
void unexpandToMinLength ();
// Canonical Modifiers. // Canonical Modifiers.
AutoSegment* canonize ( Flags flags=Flags::NoFlags ); AutoSegment* canonize ( Flags flags=Flags::NoFlags );
virtual void invalidate ( Flags flags=Flags::Propagate ); virtual void invalidate ( Flags flags=Flags::Propagate );
void invalidate ( AutoContact* ); void invalidate ( AutoContact* );
void computeOptimal ( set<AutoSegment*>& processeds ); void computeOptimal ( set<AutoSegment*>& processeds );
void setAxis ( DbU::Unit, Flags flags=Flags::NoFlags ); void setAxis ( DbU::Unit, Flags flags=Flags::NoFlags );
bool toConstraintAxis ( Flags flags=Flags::Realignate ); bool toConstraintAxis ( Flags flags=Flags::Realignate );
bool toOptimalAxis ( Flags flags=Flags::Realignate ); bool toOptimalAxis ( Flags flags=Flags::Realignate );
// Collections & Filters. // Collections & Filters.
AutoSegments getOnSourceContact ( Flags direction ); AutoSegments getOnSourceContact ( Flags direction );
AutoSegments getOnTargetContact ( Flags direction ); AutoSegments getOnTargetContact ( Flags direction );
AutoSegments getCachedOnSourceContact ( Flags direction ); AutoSegments getCachedOnSourceContact ( Flags direction );
AutoSegments getCachedOnTargetContact ( Flags direction ); AutoSegments getCachedOnTargetContact ( Flags direction );
AutoSegments getAligneds ( Flags flags=Flags::NoFlags ); AutoSegments getAligneds ( Flags flags=Flags::NoFlags );
AutoSegments getConnecteds ( Flags flags=Flags::NoFlags ); AutoSegments getConnecteds ( Flags flags=Flags::NoFlags );
AutoSegments getPerpandiculars ( Flags flags=Flags::NoFlags ); AutoSegments getPerpandiculars ( Flags flags=Flags::NoFlags );
size_t getAlignedContacts ( map<AutoContact*,int>& ) const ; size_t getAlignedContacts ( map<AutoContact*,int>& ) const ;
// Observers. // Observers.
template< typename OwnerT > template< typename OwnerT >
inline OwnerT* getObserver ( size_t slot ); inline OwnerT* getObserver ( size_t slot );
inline void setObserver ( size_t slot, BaseObserver* ); inline void setObserver ( size_t slot, BaseObserver* );
inline void notify ( unsigned int flags ); inline void notify ( unsigned int flags );
// Inspector Management. // Inspector Management.
virtual Record* _getRecord () const = 0; virtual Record* _getRecord () const = 0;
virtual string _getString () const = 0; virtual string _getString () const = 0;
virtual string _getTypeName () const = 0; virtual string _getTypeName () const = 0;
// Non-reviewed atomic modifiers. // Non-reviewed atomic modifiers.
bool _check () const; bool _check () const;
#if THIS_IS_DISABLED #if THIS_IS_DISABLED
virtual void desalignate ( AutoContact* ) = 0; virtual void desalignate ( AutoContact* ) = 0;
bool shearUp ( GCell* bool shearUp ( GCell*
, AutoSegment*& movedUp , AutoSegment*& movedUp
, float reserve , float reserve
, Flags flags ); , Flags flags );
#endif #endif
protected: protected:
// Internal: Static Attributes. // Internal: Static Attributes.
static size_t _allocateds; static size_t _allocateds;
static size_t _globalsCount; static size_t _globalsCount;
static bool _analogMode; static bool _analogMode;
static bool _shortNetMode;
static bool _initialized;
static vector< array<DbU::Unit*,4> > _extensionCaps;
// Internal: Attributes. // Internal: Attributes.
const unsigned long _id; const unsigned long _id;
GCell* _gcell; GCell* _gcell;
uint64_t _flags; uint64_t _flags;
unsigned int _depth : 8; unsigned int _depth : 8;
unsigned int _optimalMin :16; unsigned int _optimalMin :16;
unsigned int _optimalMax :16; unsigned int _optimalMax :16;
unsigned int _reduceds : 2; unsigned int _reduceds : 2;
unsigned int _rpDistance : 4; DbU::Unit _sourcePosition;
DbU::Unit _sourcePosition; DbU::Unit _targetPosition;
DbU::Unit _targetPosition; Interval _userConstraints;
Interval _userConstraints; Interval _nativeConstraints;
Interval _nativeConstraints; AutoSegment* _parent;
AutoSegment* _parent; Observable _observers;
Observable _observers;
// Internal: Constructors & Destructors. // Internal: Constructors & Destructors.
protected: protected:
AutoSegment ( Segment* segment ); AutoSegment ( Segment* segment );
virtual ~AutoSegment (); virtual ~AutoSegment ();
static void _preCreate ( AutoContact* source, AutoContact* target ); static void _preCreate ( AutoContact* source, AutoContact* target );
virtual void _postCreate (); virtual void _postCreate ();
virtual void _preDestroy (); virtual void _preDestroy ();
static void _initialize ();
private: private:
AutoSegment ( const AutoSegment& ); AutoSegment ( const AutoSegment& );
AutoSegment& operator= ( const AutoSegment& ); AutoSegment& operator= ( const AutoSegment& );
protected: protected:
void _invalidate (); void _invalidate ();
inline uint64_t _getFlags () const; inline uint64_t _getFlags () const;
std::string _getStringFlags () const; std::string _getStringFlags () const;
virtual void _setAxis ( DbU::Unit ) = 0; virtual void _setAxis ( DbU::Unit ) = 0;
public: public:
struct CompareId : public binary_function<AutoSegment*,AutoSegment*,bool> { struct CompareId : public binary_function<AutoSegment*,AutoSegment*,bool> {
@ -432,20 +389,8 @@ namespace Anabatic {
struct CompareByDepthAxis : public binary_function<AutoSegment*,AutoSegment*,bool> { struct CompareByDepthAxis : public binary_function<AutoSegment*,AutoSegment*,bool> {
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const; bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
}; };
public:
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: public:
typedef std::set<AutoSegment*,CompareByDepthLength> DepthLengthSet; typedef std::set<AutoSegment*,CompareByDepthLength> DepthLengthSet;
typedef std::set<AutoSegment*,CompareId> IdSet;
// Static Utilities. // Static Utilities.
public: public:
@ -469,8 +414,7 @@ namespace Anabatic {
); );
static void getTopologicalInfos ( AutoSegment* seed static void getTopologicalInfos ( AutoSegment* seed
, vector<AutoSegment*>& collapseds , vector<AutoSegment*>& collapseds
, vector< tuple<AutoSegment*,Flags> >& , vector<AutoSegment*>& perpandiculars
perpandiculars
, DbU::Unit& leftBound , DbU::Unit& leftBound
, DbU::Unit& rightBound , DbU::Unit& rightBound
); );
@ -485,10 +429,6 @@ namespace Anabatic {
// Inline Functions. // 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 DbU::Unit AutoSegment::getMinimalLength ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][3]) : 0; }
inline unsigned long AutoSegment::getId () const { return _id; } inline unsigned long AutoSegment::getId () const { return _id; }
inline Cell* AutoSegment::getCell () const { return base()->getCell(); } inline Cell* AutoSegment::getCell () const { return base()->getCell(); }
inline Net* AutoSegment::getNet () const { return base()->getNet(); } inline Net* AutoSegment::getNet () const { return base()->getNet(); }
@ -515,7 +455,6 @@ namespace Anabatic {
inline bool AutoSegment::getConstraints ( Interval& i ) const { return getConstraints(i.getVMin(),i.getVMax()); } 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 AutoSegment* AutoSegment::getCanonical ( Interval& i ) { return getCanonical(i.getVMin(),i.getVMax()); }
inline unsigned int AutoSegment::getDepth () const { return _depth; } 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::getPitch () const { return Session::getPitch(getDepth(),Flags::NoFlags); }
inline DbU::Unit AutoSegment::getAxis () const { return isHorizontal()?base()->getY():base()->getX(); } 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::getOrigin () const { return isHorizontal()?_gcell->getYMin():_gcell->getXMin(); }
@ -526,28 +465,21 @@ namespace Anabatic {
inline DbU::Unit AutoSegment::getNativeMax () const { return _nativeConstraints.getVMax(); } inline DbU::Unit AutoSegment::getNativeMax () const { return _nativeConstraints.getVMax(); }
inline const Interval& AutoSegment::getUserConstraints () const { return _userConstraints; } inline const Interval& AutoSegment::getUserConstraints () const { return _userConstraints; }
inline const Interval& AutoSegment::getNativeConstraints () const { return _nativeConstraints; } 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::isHorizontal () const { return _flags & SegHorizontal; }
inline bool AutoSegment::isVertical () const { return not (_flags & SegHorizontal); } inline bool AutoSegment::isVertical () const { return not (_flags & SegHorizontal); }
inline bool AutoSegment::isFixed () const { return _flags & SegFixed; } 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::isGlobal () const { return _flags & SegGlobal; }
inline bool AutoSegment::isWeakGlobal () const { return _flags & SegWeakGlobal; } inline bool AutoSegment::isWeakGlobal () const { return _flags & SegWeakGlobal; }
inline bool AutoSegment::isLongLocal () const { return _flags & SegLongLocal; } inline bool AutoSegment::isLongLocal () const { return _flags & SegLongLocal; }
inline bool AutoSegment::isLocal () const { return not (_flags & SegGlobal); } 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::isBipoint () const { return _flags & SegBipoint; }
inline bool AutoSegment::isWeakTerminal () const { return (_rpDistance < 2); } inline bool AutoSegment::isWeakTerminal () const { return _flags & SegWeakTerminal; }
inline bool AutoSegment::isWeakTerminal1 () const { return (_rpDistance == 1); } inline bool AutoSegment::isWeakTerminal1 () const { return _flags & SegWeakTerminal1; }
inline bool AutoSegment::isWeakTerminal2 () const { return (_rpDistance == 2); } inline bool AutoSegment::isWeakTerminal2 () const { return _flags & SegWeakTerminal2; }
inline bool AutoSegment::isSourceTerminal () const { return _flags & SegSourceTerminal; } inline bool AutoSegment::isSourceTerminal () const { return _flags & SegSourceTerminal; }
inline bool AutoSegment::isTargetTerminal () const { return _flags & SegTargetTerminal; } 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::isNotSourceAligned () const { return _flags & SegNotSourceAligned; }
inline bool AutoSegment::isNotTargetAligned () const { return _flags & SegNotTargetAligned; } inline bool AutoSegment::isNotTargetAligned () const { return _flags & SegNotTargetAligned; }
inline bool AutoSegment::isNotAligned () const { return (_flags & SegNotAligned) == SegNotAligned; } inline bool AutoSegment::isNotAligned () const { return (_flags & SegNotAligned) == SegNotAligned; }
@ -568,18 +500,14 @@ namespace Anabatic {
inline bool AutoSegment::isUserDefined () const { return _flags & SegUserDefined; } inline bool AutoSegment::isUserDefined () const { return _flags & SegUserDefined; }
inline bool AutoSegment::isAnalog () const { return _flags & SegAnalog; } inline bool AutoSegment::isAnalog () const { return _flags & SegAnalog; }
inline bool AutoSegment::isWide () const { return _flags & SegWide; } 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::setFlags ( uint64_t flags ) { _flags |= flags; }
inline void AutoSegment::unsetFlags ( 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 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::incReduceds () { if (_reduceds<3) ++_reduceds; }
inline void AutoSegment::decReduceds () { if (_reduceds>0) --_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::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); }
inline void AutoSegment::setWidth ( DbU::Unit width ) { base()->setWidth(width); }
inline void AutoSegment::setOptimalMin ( DbU::Unit min ) { _optimalMin = (unsigned int)DbU::getLambda(min-getOrigin()); } 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::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::mergeNativeMin ( DbU::Unit min ) { _nativeConstraints.getVMin() = std::max( min, _nativeConstraints.getVMin() ); }
@ -587,25 +515,11 @@ namespace Anabatic {
inline void AutoSegment::resetNativeConstraints ( DbU::Unit min, DbU::Unit max ) { _nativeConstraints = Interval( min, max ); } 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::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); }
inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); } 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 )
{
RoutingLayerGauge* layerGauge = Session::getLayerGauge( depth );
base()->setLayer( layerGauge->getLayer () );
base()->setWidth( layerGauge->getWireWidth() );
_depth = depth;
_flags|=SegInvalidatedLayer;
}
inline DbU::Unit AutoSegment::getContactWidth () const inline DbU::Unit AutoSegment::getContactWidth () const
{ return getWidth() + Session::getViaWidth(getLayer()) - Session::getWireWidth(getLayer()); } { 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 ) inline void AutoSegment::setParent ( AutoSegment* parent )
{ {
@ -615,6 +529,7 @@ namespace Anabatic {
_parent = parent; _parent = parent;
} }
inline bool AutoSegment::CompareId::operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const inline bool AutoSegment::CompareId::operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const
{ return lhs->getId() < rhs->getId(); } { return lhs->getId() < rhs->getId(); }
@ -670,8 +585,7 @@ namespace Anabatic {
cdebug_log(145,0) << "getTerminalCount() - " << seed << endl; cdebug_log(145,0) << "getTerminalCount() - " << seed << endl;
vector<AutoSegment*> collapseds; vector<AutoSegment*> collapseds;
vector< tuple<AutoSegment*,Flags> > vector<AutoSegment*> perpandiculars;
perpandiculars;
DbU::Unit leftBound; DbU::Unit leftBound;
DbU::Unit rightBound; DbU::Unit rightBound;
@ -707,3 +621,6 @@ namespace Anabatic {
INSPECTOR_P_SUPPORT(Anabatic::AutoSegment); INSPECTOR_P_SUPPORT(Anabatic::AutoSegment);
# endif // ANABATIC_AUTOSEGMENT_H

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2018, All Rights Reserved // Copyright (c) UPMC/LIP6 2008-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -48,7 +48,6 @@ namespace Anabatic {
using Hurricane::DbU; using Hurricane::DbU;
using Hurricane::Box; using Hurricane::Box;
using Hurricane::Hook; using Hurricane::Hook;
using Hurricane::Entity;
using Hurricane::Component; using Hurricane::Component;
using Hurricane::Contact; using Hurricane::Contact;
using Hurricane::Segment; using Hurricane::Segment;
@ -71,13 +70,13 @@ namespace Anabatic {
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Collections. // Collections.
typedef Hurricane::Filter<AutoSegment*> AutoSegmentHF; typedef Hurricane::Filter<AutoSegment*> AutoSegmentHF;
typedef Hurricane::Locator<AutoSegment*> AutoSegmentHL; typedef Hurricane::Locator<AutoSegment*> AutoSegmentHL;
typedef Hurricane::Collection<AutoSegment*> AutoSegmentHC; typedef Hurricane::Collection<AutoSegment*> AutoSegmentHC;
typedef GenericCollection<AutoSegment*> AutoSegments; typedef GenericCollection<AutoSegment*> AutoSegments;
typedef GenericLocator<AutoSegment*> AutoSegmentLocator; typedef GenericLocator<AutoSegment*> AutoSegmentLocator;
typedef GenericFilter<AutoSegment*> AutoSegmentFilter; typedef GenericFilter<AutoSegment*> AutoSegmentFilter;
typedef map<Segment*,AutoSegment*,Entity::CompareById> AutoSegmentLut; typedef map<Segment*,AutoSegment*> AutoSegmentLut;
// ------------------------------------------------------------------- // -------------------------------------------------------------------

View File

@ -14,9 +14,11 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#pragma once #ifndef ANABATIC_AUTOVERTICAL_H
#include "hurricane/Vertical.h" #define ANABATIC_AUTOVERTICAL_H
#include "anabatic/AutoSegment.h"
#include "hurricane/Vertical.h"
#include "anabatic/AutoSegment.h"
namespace Anabatic { namespace Anabatic {
@ -47,7 +49,7 @@ namespace Anabatic {
virtual Interval getSourceConstraints ( Flags flags=0 ) const; virtual Interval getSourceConstraints ( Flags flags=0 ) const;
virtual Interval getTargetConstraints ( Flags flags=0 ) const; virtual Interval getTargetConstraints ( Flags flags=0 ) const;
virtual Flags getDirection () const; virtual Flags getDirection () const;
virtual bool getGCells ( vector<GCell*>& ) const; virtual size_t getGCells ( vector<GCell*>& ) const;
// Modifiers. // Modifiers.
virtual void setDuSource ( DbU::Unit ); virtual void setDuSource ( DbU::Unit );
virtual void setDuTarget ( DbU::Unit ); virtual void setDuTarget ( DbU::Unit );
@ -89,3 +91,6 @@ namespace Anabatic {
INSPECTOR_P_SUPPORT(Anabatic::AutoVertical); INSPECTOR_P_SUPPORT(Anabatic::AutoVertical);
#endif // ANABATIC_AUTOHORIZONTAL_H

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC/LIP6 2008-2018, All Rights Reserved // Copyright (c) UPMC/LIP6 2008-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -14,7 +14,9 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#pragma once #ifndef ANABATIC_CHIP_TOOLS_H
#define ANABATIC_CHIP_TOOLS_H
#include <string> #include <string>
#include "hurricane/DbU.h" #include "hurricane/DbU.h"
#include "hurricane/Torus.h" #include "hurricane/Torus.h"
@ -111,4 +113,6 @@ namespace Anabatic {
} // Anabatic namespace. } // 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>" -*- // -*- mode: C++; explicit-buffer-name: "Configuration.h<anabatic>" -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2016-2022, All Rights Reserved // Copyright (c) UPMC 2016-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | 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 <string>
#include <vector> #include <vector>
@ -22,7 +24,6 @@
namespace Hurricane { namespace Hurricane {
class Layer; class Layer;
class Cell; class Cell;
class RoutingPad;
} }
namespace CRL { namespace CRL {
@ -42,7 +43,6 @@ namespace Anabatic {
using Hurricane::Name; using Hurricane::Name;
using Hurricane::Layer; using Hurricane::Layer;
using Hurricane::DbU; using Hurricane::DbU;
using Hurricane::RoutingPad;
using Hurricane::Cell; using Hurricane::Cell;
using CRL::CellGauge; using CRL::CellGauge;
using CRL::RoutingGauge; using CRL::RoutingGauge;
@ -53,106 +53,59 @@ namespace Anabatic {
// Class : "Anabatic::Configuration". // Class : "Anabatic::Configuration".
class Configuration { class Configuration {
public:
static const size_t ndepth = (size_t)-1;
public: public:
// Constructor & Destructor. // Constructor & Destructor.
Configuration ( const CellGauge* cg=NULL, const RoutingGauge* rg=NULL ); Configuration ( const CellGauge* cg=NULL, const RoutingGauge* rg=NULL );
Configuration ( const Configuration& ); Configuration ( const Configuration& );
virtual ~Configuration (); virtual ~Configuration ();
virtual Configuration* clone () const; virtual Configuration* clone () const;
// Methods. // Methods.
inline bool isGLayer ( const Layer* ) const; bool isGMetal ( const Layer* ) const;
bool isGMetal ( const Layer* ) const; bool isGContact ( const Layer* ) const;
bool isGContact ( const Layer* ) const; const Layer* getGContactLayer () const;
bool isTwoMetals () const; const Layer* getGHorizontalLayer () const;
bool isHybrid () const; const Layer* getGVerticalLayer () const;
bool isHV () const; size_t getDepth () const;
bool isVH () const; size_t getAllowedDepth () const;
inline std::string getNetBuilderStyle () const; size_t getLayerDepth ( const Layer* ) const;
inline StyleFlags getRoutingStyle () const; CellGauge* getCellGauge () const;
const Layer* getGContactLayer () const; RoutingGauge* getRoutingGauge () const;
const Layer* getGHorizontalLayer () const; RoutingLayerGauge* getLayerGauge ( size_t depth ) const;
const Layer* getGVerticalLayer () const; const Layer* getRoutingLayer ( size_t depth ) const;
inline size_t getGVerticalDepth () const; Layer* getContactLayer ( size_t depth ) const;
inline DbU::Unit getGVerticalPitch () const; DbU::Unit getSliceHeight () const;
inline size_t getGHorizontalDepth () const; DbU::Unit getSliceStep () const;
inline DbU::Unit getGHorizontalPitch () const; DbU::Unit getPitch ( size_t depth, Flags flags ) const;
inline size_t getDVerticalDepth () const; DbU::Unit getOffset ( size_t depth ) const;
inline const Layer* getDVerticalLayer () const; DbU::Unit getWireWidth ( size_t depth ) const;
inline DbU::Unit getDVerticalWidth () const; DbU::Unit getExtensionCap ( size_t depth ) const;
inline DbU::Unit getDPVerticalWidth () const; Flags getDirection ( size_t depth ) const;
inline DbU::Unit getDVerticalPitch () const; DbU::Unit getPitch ( const Layer*, Flags flags ) const;
inline DbU::Unit getDVerticalOffset () const; DbU::Unit getOffset ( const Layer* ) const;
inline size_t getDHorizontalDepth () const; DbU::Unit getWireWidth ( const Layer* ) const;
inline const Layer* getDHorizontalLayer () const; DbU::Unit getExtensionCap ( const Layer* ) const;
inline DbU::Unit getDHorizontalWidth () const; Flags getDirection ( const Layer* ) const;
inline DbU::Unit getDPHorizontalWidth () const; float getSaturateRatio () const;
inline DbU::Unit getDHorizontalPitch () const; size_t getSaturateRp () const;
inline DbU::Unit getDHorizontalOffset () const; DbU::Unit getGlobalThreshold () const;
inline size_t getDContactDepth () const; void setAllowedDepth ( size_t );
inline const Layer* getDContactLayer () const; void setSaturateRatio ( float );
inline DbU::Unit getDContactWidth () const; void setSaturateRp ( size_t );
inline DbU::Unit getDContactPitch () const; void setGlobalThreshold ( DbU::Unit );
size_t getDepth () const; DbU::Unit getEdgeLength () const;
size_t getAllowedDepth () const; DbU::Unit getEdgeWidth () const;
size_t getLayerDepth ( const Layer* ) const; float getEdgeCostH () const;
CellGauge* getCellGauge () const; float getEdgeCostK () const;
RoutingGauge* getRoutingGauge () const; float getEdgeHInc () const;
RoutingLayerGauge* getLayerGauge ( size_t depth ) const; virtual void print ( Cell* ) const;
const Layer* getRoutingLayer ( size_t depth ) const; virtual Record* _getRecord () const;
Layer* getContactLayer ( size_t depth ) const; virtual string _getString () const;
DbU::Unit getSliceHeight () const; virtual string _getTypeName () const;
DbU::Unit getSliceStep () const;
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 );
void setSaturateRp ( size_t );
void setGlobalThreshold ( DbU::Unit );
DbU::Unit getEdgeLength () const;
DbU::Unit getEdgeWidth () const;
float getEdgeCostH () const;
float getEdgeCostK () const;
float getEdgeHInc () const;
float getEdgeHScaling () const;
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;
virtual string _getTypeName () const;
protected: protected:
// Attributes. // Attributes.
const Layer* _gmetalh; const Layer* _gmetalh;
const Layer* _gmetalv; const Layer* _gmetalv;
const Layer* _gcontact; const Layer* _gcontact;
size_t _gdepthv;
size_t _gdepthh;
size_t _ddepthv;
size_t _ddepthh;
size_t _ddepthc;
std::string _netBuilderStyle;
StyleFlags _routingStyle;
CellGauge* _cg; CellGauge* _cg;
RoutingGauge* _rg; RoutingGauge* _rg;
std::vector<DbU::Unit> _extensionCaps; std::vector<DbU::Unit> _extensionCaps;
@ -165,48 +118,15 @@ namespace Anabatic {
float _edgeCostH; float _edgeCostH;
float _edgeCostK; float _edgeCostK;
float _edgeHInc; float _edgeHInc;
float _edgeHScaling;
int _globalIterations;
std::string _diodeName;
DbU::Unit _antennaGateMaxWL;
DbU::Unit _antennaDiodeMaxWL;
private: private:
Configuration& operator= ( const Configuration& ) = delete; Configuration& operator= ( const Configuration& ) = delete;
void _setTopRoutingLayer ( Name name ); 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 ); }
inline DbU::Unit Configuration::getGVerticalPitch () const { return getPitch( getGVerticalDepth (), Flags::NoFlags ); }
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. } // Anabatic namespace.
INSPECTOR_P_SUPPORT(Anabatic::Configuration); INSPECTOR_P_SUPPORT(Anabatic::Configuration);
#endif // ANABATIC_CONFIGURATION_H

View File

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "Constants.h<anabatic>" -*- // -*- mode: C++; explicit-buffer-name: "Constants.h<anabatic>" -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2018, All Rights Reserved // Copyright (c) UPMC 2016-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -14,15 +14,14 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#pragma once #ifndef ANABATIC_CONSTANTS_H
#define ANABATIC_CONSTANTS_H
#include "hurricane/Flags.h" #include "hurricane/Flags.h"
namespace Anabatic { namespace Anabatic {
// -------------------------------------------------------------------
// Class : "Anabatic::Flags".
class Flags : public Hurricane::BaseFlags { class Flags : public Hurricane::BaseFlags {
public: public:
static const BaseFlags NoFlags ; // = 0; static const BaseFlags NoFlags ; // = 0;
@ -40,27 +39,14 @@ namespace Anabatic {
static const BaseFlags MatrixGCell ; // = (1 << 9); static const BaseFlags MatrixGCell ; // = (1 << 9);
static const BaseFlags IoPadGCell ; // = (1 << 10); static const BaseFlags IoPadGCell ; // = (1 << 10);
static const BaseFlags Saturated ; // = (1 << 11); static const BaseFlags Saturated ; // = (1 << 11);
static const BaseFlags StdCellRow ; // = (1 << 12);
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);
// Flags for Anabatic objects states only. // Flags for Anabatic objects states only.
static const BaseFlags DemoMode ; // = (1 << 5); static const BaseFlags DemoMode ; // = (1 << 5);
static const BaseFlags WarnOnGCellOverload ; // = (1 << 6); static const BaseFlags WarnOnGCellOverload ; // = (1 << 6);
static const BaseFlags DestroyGCell ; // = (1 << 7); static const BaseFlags DestroyGCell ; // = (1 << 7);
static const BaseFlags DestroyBaseContact ; // = (1 << 8); static const BaseFlags DestroyBaseContact ; // = (1 << 8);
static const BaseFlags DestroyBaseSegment ; // = (1 << 9); static const BaseFlags DestroyBaseSegment ; // = (1 << 9);
static const BaseFlags DisableCanonize ; // = (1 << 10);
// Flags for NetDatas objects states only. // 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);
// Masks. // Masks.
static const BaseFlags WestSide ; // = Horizontal|Target; static const BaseFlags WestSide ; // = Horizontal|Target;
static const BaseFlags EastSide ; // = Horizontal|Source; static const BaseFlags EastSide ; // = Horizontal|Source;
@ -70,10 +56,7 @@ namespace Anabatic {
static const BaseFlags EndsMask ; // = Source|Target; static const BaseFlags EndsMask ; // = Source|Target;
static const BaseFlags DirectionMask ; // = Horizontal|Vertical; static const BaseFlags DirectionMask ; // = Horizontal|Vertical;
static const BaseFlags DestroyMask ; // = DestroyGCell|DestroyBaseContact|DestroyBaseSegment; static const BaseFlags DestroyMask ; // = DestroyGCell|DestroyBaseContact|DestroyBaseSegment;
static const BaseFlags GCellTypeMask ; // = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell|HRailGCell|VRailGCell; static const BaseFlags GCellTypeMask ; // = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|MatrixGCell|IoPadGCell;
static const BaseFlags RowGCellMask ; // = StdCellRow|ChannelRow;
static const BaseFlags AnalogGCellMask ; // = DeviceGCell|HChannelGCell|VChannelGCell|StrutGCell|HRailGCell|VRailGCell;
static const BaseFlags EdgeCapacityMask ; // = Horizontal|Vertical|NullCapacity|InfiniteCapacity ;
// Flags for functions arguments only. // Flags for functions arguments only.
static const BaseFlags Create ; // = (1 << 5); static const BaseFlags Create ; // = (1 << 5);
static const BaseFlags WithPerpands ; static const BaseFlags WithPerpands ;
@ -103,14 +86,6 @@ namespace Anabatic {
static const BaseFlags CheckLowDensity ; static const BaseFlags CheckLowDensity ;
static const BaseFlags CheckLowUpDensity ; static const BaseFlags CheckLowUpDensity ;
static const BaseFlags NoUpdate ; 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: public:
inline Flags ( uint64_t flags = NoFlags ); inline Flags ( uint64_t flags = NoFlags );
inline Flags ( const Hurricane::BaseFlags& ); inline Flags ( const Hurricane::BaseFlags& );
@ -125,39 +100,6 @@ namespace Anabatic {
Flags::Flags ( const Hurricane::BaseFlags& flags ) : BaseFlags(flags) { } 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 enum FlagsMode { FlagsFunction = 1
}; };
@ -170,12 +112,11 @@ namespace Anabatic {
, EngineGutted = 6 , EngineGutted = 6
}; };
enum EngineAlgorithm { EngineLoadGrByNet = (1 << 0) enum EngineAlgorithm { EngineLoadGrByNet = (1 << 0)
, EngineLoadGrByGCell = (1 << 1) , EngineLoadGrByGCell = (1 << 1)
, EngineLayerAssignByLength = (1 << 2) , EngineLayerAssignByLength = (1 << 2)
, EngineLayerAssignByTrunk = (1 << 3) , EngineLayerAssignByTrunk = (1 << 3)
, EngineLayerAssignNoGlobalM2V = (1 << 4) , EngineNoNetLayerAssign = (1 << 4)
, EngineNoNetLayerAssign = (1 << 5)
}; };
@ -190,4 +131,6 @@ namespace Anabatic {
} // Anabatic namespace. } // Anabatic namespace.
INSPECTOR_PR_SUPPORT(Anabatic::Flags); INSPECTOR_PV_SUPPORT(Anabatic::Flags)
#endif // ANABATIC_CONSTANTS_H

View File

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "Dijkstra.h<anabatic>" -*- // -*- mode: C++; explicit-buffer-name: "Dijkstra.h<anabatic>" -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2018, All Rights Reserved // Copyright (c) UPMC 2016-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -14,7 +14,9 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#pragma once #ifndef ANABATIC_DIJKSTRA_H
#define ANABATIC_DIJKSTRA_H
#include <set> #include <set>
#include <iomanip> #include <iomanip>
#include "hurricane/Observer.h" #include "hurricane/Observer.h"
@ -42,17 +44,16 @@ namespace Anabatic {
class IntervalC class IntervalC
{ {
public: public:
enum iFlag { None = 0 enum iFlag { None = 0
, iFHorizontal = (1<<0) , iHorizontal = (1<<0)
, iFVertical = (1<<1) , iVertical = (1<<1)
, iSet = (1<<2) , iSet = (1<<2)
}; };
public: public:
IntervalC(); IntervalC();
IntervalC(const IntervalC&); IntervalC(const IntervalC&);
IntervalC(IntervalC&); IntervalC(IntervalC&);
IntervalC( DbU::Unit, DbU::Unit, DbU::Unit );
~IntervalC(); ~IntervalC();
void set ( DbU::Unit, DbU::Unit, DbU::Unit ); void set ( DbU::Unit, DbU::Unit, DbU::Unit );
void setRange ( DbU::Unit, DbU::Unit ); void setRange ( DbU::Unit, DbU::Unit );
@ -82,8 +83,8 @@ namespace Anabatic {
DbU::Unit _axis; DbU::Unit _axis;
}; };
inline void IntervalC::setAsH () { _flags = ((_flags & ~(0x3)) | iFHorizontal); } inline void IntervalC::setAsH () { _flags = ((_flags & ~(0x3)) | iHorizontal); }
inline void IntervalC::setAsV () { _flags = ((_flags & ~(0x3)) | iFVertical ); } inline void IntervalC::setAsV () { _flags = ((_flags & ~(0x3)) | iVertical ); }
inline void IntervalC::setAxis ( DbU::Unit axis ) { _axis = axis; } inline void IntervalC::setAxis ( DbU::Unit axis ) { _axis = axis; }
inline DbU::Unit IntervalC::getAxis () const { return _axis; } inline DbU::Unit IntervalC::getAxis () const { return _axis; }
inline DbU::Unit IntervalC::getCenter() const { return getMin()+getMax(); } inline DbU::Unit IntervalC::getCenter() const { return getMin()+getMax(); }
@ -91,8 +92,8 @@ namespace Anabatic {
inline DbU::Unit IntervalC::getMax () const { return _max; } inline DbU::Unit IntervalC::getMax () const { return _max; }
inline void IntervalC::setiSet () { _flags |= iSet; } inline void IntervalC::setiSet () { _flags |= iSet; }
inline bool IntervalC::isiSet () const { return _flags & iSet; } inline bool IntervalC::isiSet () const { return _flags & iSet; }
inline bool IntervalC::isH () const { return _flags & iFHorizontal; } inline bool IntervalC::isH () const { return _flags & iHorizontal; }
inline bool IntervalC::isV () const { return _flags & iFVertical ; } inline bool IntervalC::isV () const { return _flags & iVertical ; }
inline void IntervalC::setFlags ( Flags flags ) { _flags = flags; } inline void IntervalC::setFlags ( Flags flags ) { _flags = flags; }
inline Flags IntervalC::getFlags () const { return _flags; } inline Flags IntervalC::getFlags () const { return _flags; }
@ -163,13 +164,10 @@ namespace Anabatic {
inline void GRAData::printInterv () const { _interv.print() ; } inline void GRAData::printInterv () const { _interv.print() ; }
inline void GRAData::printIntervfrom () const { _intervfrom.print(); } inline void GRAData::printIntervfrom () const { _intervfrom.print(); }
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Class : "Anabatic::Vertex". // Class : "Anabatic::Vertex".
class Vertex { class Vertex {
public:
static inline std::string getValueString ( DbU::Unit );
public: public:
class CompareById { class CompareById {
public: public:
@ -187,87 +185,84 @@ namespace Anabatic {
, iHorizontal = (1<<7) , iHorizontal = (1<<7)
, iVertical = (1<<8) , iVertical = (1<<8)
, iSet = (1<<9) , iSet = (1<<9)
, Driver = (1<<10)
}; };
public: public:
static DbU::Unit unreached; static DbU::Unit unreached;
static DbU::Unit unreachable; static DbU::Unit unreachable;
public: public:
static void notify ( Vertex*, unsigned flags ); static void notify ( Vertex*, unsigned flags );
static inline Vertex* lookup ( GCell* ); public:
public: inline Vertex ( GCell* );
inline Vertex ( GCell* ); //inline Vertex ( size_t id );
//inline Vertex ( size_t id ); inline ~Vertex ();
inline ~Vertex (); inline bool hasDoneAllRps () const;
inline bool isDriver () const; inline Contact* hasGContact ( Net* ) const;
inline bool isAnalog () const; inline unsigned int getId () const;
inline bool hasDoneAllRps () const; inline GCell* getGCell () const;
inline Contact* hasGContact ( Net* ) const; inline AnabaticEngine* getAnabatic () const;
inline unsigned int getId () const; inline Contact* getGContact ( Net* );
inline GCell* getGCell () const; bool hasValidStamp () const;
inline Box getBoundingBox () const; inline Point getCenter () const;
inline Edges getEdges ( Flags sides=Flags::AllSides ) const; inline DbU::Unit getDistance () const;
inline AnabaticEngine* getAnabatic () const; inline int getStamp () const;
inline Contact* getGContact ( Net* ); inline int getBranchId () const;
bool hasValidStamp () const; inline int getConnexId () const;
inline Point getCenter () const; inline int getDegree () const;
inline DbU::Unit getDistance () const; inline int getRpCount () const;
inline int getStamp () const; inline Edge* getFrom () const;
inline int getBranchId () const; inline Vertex* getPredecessor () const;
inline int getConnexId () const; inline void setDistance ( DbU::Unit );
inline int getDegree () const; inline void setStamp ( int );
inline int getRpCount () const; inline void setConnexId ( int );
Edge* getFrom () const; inline void setBranchId ( int );
inline Vertex* getPredecessor () const; inline void setDegree ( int );
inline Vertex* getNeighbor ( Edge* ) const; inline void incDegree ( int delta=1 );
inline void setDriver ( bool state ); inline void setRpCount ( int );
inline void setDistance ( DbU::Unit ); inline void incRpCount ( int delta=1 );
inline void setStamp ( int ); inline void setFrom ( Edge* );
inline void setConnexId ( int ); inline void add ( RoutingPad* );
inline void setBranchId ( int ); inline void clearRps ();
inline void setDegree ( int ); inline Contact* breakGoThrough ( Net* );
inline void incDegree ( int delta=1 );
inline void setRpCount ( int ); //////////////////////////////////////// Analog
inline void incRpCount ( int delta=1 ); inline bool isNorth ( const Vertex* ) const;
inline void setFrom ( Edge* ); inline bool isSouth ( const Vertex* ) const;
inline void add ( RoutingPad* ); inline bool isEast ( const Vertex* ) const;
inline void clearRps (); inline bool isWest ( const Vertex* ) const;
inline Contact* breakGoThrough ( Net* ); inline bool isNRestricted () const;
// Analog related methods. inline bool isSRestricted () const;
inline bool isNorth ( const Vertex* ) const; inline bool isERestricted () const;
inline bool isSouth ( const Vertex* ) const; inline bool isWRestricted () const;
inline bool isEast ( const Vertex* ) const; inline bool hasRestrictions() const;
inline bool isWest ( const Vertex* ) const;
inline bool isNRestricted () const; inline void setRestricted ();
inline bool isSRestricted () const; inline void clearRestriction ();
inline bool isERestricted () const; inline void setNRestricted ();
inline bool isWRestricted () const; inline void setSRestricted ();
inline bool hasRestrictions () const; inline void setERestricted ();
void setRestricted (); inline void setWRestricted ();
void clearRestriction (); bool hasRP ( Net* ) const;
inline void setNRestricted (); bool hasVRP ( Net* ) const;
inline void setSRestricted (); bool hasHRP ( Net* ) const;
inline void setERestricted (); static bool isRestricted ( const Vertex* v1, const Vertex* v2, const Edge* e, DbU::Unit hpitch = 0, DbU::Unit vpitch = 0, Net* net = NULL);
inline void setWRestricted (); bool areSameSide ( const Vertex*, const Vertex* ) const;
bool hasRP ( Net* ) const;
bool hasVRP ( Net* ) const; inline bool isFromFrom2 () const;
bool hasHRP ( Net* ) const; inline bool isFrom2Mode () const;
static bool isRestricted ( const Vertex* v1, const Vertex* v2, const Edge* e, DbU::Unit hpitch = 0, DbU::Unit vpitch = 0, Net* net = NULL); inline bool isAxisTarget () const;
bool areSameSide ( const Vertex*, const Vertex* ) const; inline bool isiHorizontal() const;
inline bool isFromFrom2 () const; inline bool isiVertical () const;
inline bool isFrom2Mode () const; inline void setFlags ( uint32_t );
inline bool isAxisTarget () const; inline void unsetFlags ( uint32_t );
inline bool isiHorizontal () const; bool isH () const;
inline bool isiVertical () const; bool isV () const;
inline void setFlags ( uint32_t ); inline void createAData ();
inline void unsetFlags ( uint32_t ); ////////////////////////////////////
bool isH () const;
bool isV () const;
inline void createAData ();
Point getStartPathPoint ( const Vertex* next ) const; Point getStartPathPoint ( const Vertex* next ) const;
Point getNextPathPoint ( Point, const Vertex* ) const; Point getNextPathPoint ( Point, const Vertex* ) const;
//////////////////////////////////////// GRDATA
void setIntervals ( Vertex* ); void setIntervals ( Vertex* );
inline bool hasAData () const;
bool isiSet () const; bool isiSet () const;
DbU::Unit getIAxis () const; DbU::Unit getIAxis () const;
DbU::Unit getIMax () const; DbU::Unit getIMax () const;
@ -282,6 +277,7 @@ namespace Anabatic {
void clearFrom2 (); void clearFrom2 ();
Edge* getFrom2 () const; Edge* getFrom2 () const;
void setFrom2 ( Edge* ); void setFrom2 ( Edge* );
void createIntervFrom2 ();
DbU::Unit getPIMax2 () const; DbU::Unit getPIMax2 () const;
DbU::Unit getPIMin2 () const; DbU::Unit getPIMin2 () const;
DbU::Unit getPIAxis2 () const; DbU::Unit getPIAxis2 () const;
@ -293,10 +289,10 @@ namespace Anabatic {
GCell* getGPrev ( uint32_t criteria=0 ) const; GCell* getGPrev ( uint32_t criteria=0 ) const;
// Inspector support. // Inspector support.
string _getString () const; string _getString () const;
private: private:
Vertex ( const Vertex& ); Vertex ( const Vertex& );
Vertex& operator= ( const Vertex& ); Vertex& operator= ( const Vertex& );
private: private:
size_t _id; size_t _id;
GCell* _gcell; GCell* _gcell;
@ -332,12 +328,7 @@ 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 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); }
inline Contact* Vertex::hasGContact ( Net* net ) const { return _gcell->hasGContact(net); } inline Contact* Vertex::hasGContact ( Net* net ) const { return _gcell->hasGContact(net); }
inline unsigned int Vertex::getId () const { return _id; } inline unsigned int Vertex::getId () const { return _id; }
inline GCell* Vertex::getGCell () const { return _gcell; } inline GCell* Vertex::getGCell () const { return _gcell; }
@ -350,7 +341,7 @@ namespace Anabatic {
inline int Vertex::getBranchId () const { return hasValidStamp() ? _branchId : 0; } inline int Vertex::getBranchId () const { return hasValidStamp() ? _branchId : 0; }
inline int Vertex::getDegree () const { return hasValidStamp() ? _degree : 0; } inline int Vertex::getDegree () const { return hasValidStamp() ? _degree : 0; }
inline int Vertex::getRpCount () const { return hasValidStamp() ? _rpCount : 0; } inline int Vertex::getRpCount () const { return hasValidStamp() ? _rpCount : 0; }
//inline Edge* Vertex::getFrom () const { return _from; } inline Edge* Vertex::getFrom () const { return _from; }
inline void Vertex::setDistance ( DbU::Unit distance ) { _distance=distance; } inline void Vertex::setDistance ( DbU::Unit distance ) { _distance=distance; }
inline void Vertex::setFrom ( Edge* from ) { _from=from; } inline void Vertex::setFrom ( Edge* from ) { _from=from; }
inline void Vertex::setStamp ( int stamp ) { _stamp=stamp; } inline void Vertex::setStamp ( int stamp ) { _stamp=stamp; }
@ -365,18 +356,6 @@ namespace Anabatic {
inline Vertex* Vertex::getPredecessor () const inline Vertex* Vertex::getPredecessor () const
{ return (hasValidStamp() and _from) ? _from->getOpposite(_gcell)->getObserver<Vertex>(GCell::Observable::Vertex) : NULL; } { return (hasValidStamp() and _from) ? _from->getOpposite(_gcell)->getObserver<Vertex>(GCell::Observable::Vertex) : NULL; }
inline Vertex* Vertex::getNeighbor ( Edge* edge ) const
{
GCell* gcell = edge->getOpposite( getGCell() );
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 inline bool Vertex::CompareById::operator() ( const Vertex* lhs, const Vertex* rhs ) const
{ return lhs->getId() < rhs->getId(); } { return lhs->getId() < rhs->getId(); }
@ -393,9 +372,8 @@ namespace Anabatic {
inline bool Vertex::isWRestricted () const { return (_flags & WRestricted); } inline bool Vertex::isWRestricted () const { return (_flags & WRestricted); }
inline bool Vertex::hasRestrictions () const { return ( isNRestricted()||isSRestricted()||isERestricted()||isWRestricted()) ; } inline bool Vertex::hasRestrictions () const { return ( isNRestricted()||isSRestricted()||isERestricted()||isWRestricted()) ; }
inline bool Vertex::hasAData () const { return (_adata !=NULL)? true : false; } inline void Vertex::setRestricted () { _flags |= 0xF; }
//inline void Vertex::setRestricted () { _flags |= 0xF; } inline void Vertex::clearRestriction () { _flags &= ~(0xF); }
//inline void Vertex::clearRestriction () { _flags &= ~(0xF); }
inline void Vertex::setNRestricted () { _flags |= NRestricted; } inline void Vertex::setNRestricted () { _flags |= NRestricted; }
inline void Vertex::setSRestricted () { _flags |= SRestricted; } inline void Vertex::setSRestricted () { _flags |= SRestricted; }
inline void Vertex::setERestricted () { _flags |= ERestricted; } inline void Vertex::setERestricted () { _flags |= ERestricted; }
@ -409,63 +387,45 @@ namespace Anabatic {
inline void Vertex::setFlags ( uint32_t mask ) { _flags |= mask ; } inline void Vertex::setFlags ( uint32_t mask ) { _flags |= mask ; }
inline void Vertex::unsetFlags ( uint32_t mask ) { _flags &= ~mask; } inline void Vertex::unsetFlags ( uint32_t mask ) { _flags &= ~mask; }
inline std::string Vertex::getValueString ( DbU::Unit distance )
{
if (distance == Vertex::unreachable) return "unreachable";
if (distance == Vertex::unreached ) return "unreached";
return DbU::getValueString( distance );
}
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Class : "Anabatic::PriorityQueue". // Class : "Anabatic::PriorityQueue".
class PriorityQueue { class PriorityQueue {
public: public:
inline PriorityQueue (); inline PriorityQueue ();
inline ~PriorityQueue (); inline ~PriorityQueue ();
inline bool empty () const; inline bool empty () const;
inline size_t size () const; inline size_t size () const;
inline void push ( Vertex* ); inline void push ( Vertex* );
inline void erase ( Vertex* ); inline void erase ( Vertex* );
inline Vertex* top (); inline Vertex* top ();
inline void pop (); inline void pop ();
inline void clear (); inline void clear ();
inline void dump () const; inline void dump () const;
inline void setAttractor ( const Point& );
inline const Point& getAttractor () const;
inline bool hasAttractor () const;
private: private:
class CompareByDistance { class CompareByDistance {
public: public:
inline CompareByDistance (); inline bool operator() ( const Vertex* lhs, const Vertex* rhs );
bool operator() ( const Vertex* lhs, const Vertex* rhs ) const;
static inline void setQueue ( PriorityQueue* );
private:
static PriorityQueue* _pqueue;
}; };
private: private:
bool _hasAttractor;
Point _attractor;
multiset<Vertex*,CompareByDistance> _queue; multiset<Vertex*,CompareByDistance> _queue;
}; };
inline PriorityQueue::CompareByDistance::CompareByDistance () { } inline bool PriorityQueue::CompareByDistance::operator() ( const Vertex* lhs, const Vertex* rhs )
{
inline void PriorityQueue::CompareByDistance::setQueue ( PriorityQueue* pqueue ) { _pqueue = pqueue; } if (lhs->getDistance() == rhs->getDistance()) return lhs->getBranchId() > rhs->getBranchId();
return lhs->getDistance() < rhs->getDistance();
}
inline PriorityQueue::PriorityQueue () : _hasAttractor(false), _attractor(), _queue() { PriorityQueue::CompareByDistance::setQueue(this); } inline PriorityQueue::PriorityQueue () : _queue() { }
inline PriorityQueue::~PriorityQueue () { } inline PriorityQueue::~PriorityQueue () { }
inline bool PriorityQueue::empty () const { return _queue.empty(); } inline bool PriorityQueue::empty () const { return _queue.empty(); }
inline size_t PriorityQueue::size () const { return _queue.size(); } inline size_t PriorityQueue::size () const { return _queue.size(); }
inline void PriorityQueue::push ( Vertex* v ) { _queue.insert(v); } inline void PriorityQueue::push ( Vertex* v ) { _queue.insert(v); }
inline Vertex* PriorityQueue::top () { return _queue.empty() ? NULL : *_queue.begin(); } inline Vertex* PriorityQueue::top () { return _queue.empty() ? NULL : *_queue.begin(); }
inline void PriorityQueue::clear () { _queue.clear(); _hasAttractor=false; } inline void PriorityQueue::clear () { _queue.clear(); }
inline void PriorityQueue::setAttractor ( const Point& p ) { _attractor=p; _hasAttractor=true; }
inline bool PriorityQueue::hasAttractor () const { return _hasAttractor; }
inline const Point& PriorityQueue::getAttractor () const { return _attractor; }
inline void PriorityQueue::pop () inline void PriorityQueue::pop ()
{ {
@ -515,54 +475,51 @@ namespace Anabatic {
public: public:
typedef std::function<DbU::Unit(const Vertex*,const Vertex*,const Edge*)> distance_t; typedef std::function<DbU::Unit(const Vertex*,const Vertex*,const Edge*)> distance_t;
public: public:
Dijkstra ( AnabaticEngine* ); Dijkstra ( AnabaticEngine* );
~Dijkstra (); ~Dijkstra ();
public: public:
inline bool isBipoint () const; inline bool isBipoint () const;
inline bool isSourceVertex ( Vertex* ) const; inline bool isSourceVertex ( Vertex* ) const;
inline Net* getNet () const; inline bool isTargetVertex ( Vertex* ) const;
inline bool isTargetVertex ( Vertex* ) const; inline DbU::Unit getSearchAreaHalo () const;
DbU::Unit getAntennaGateMaxWL () const; template<typename DistanceT>
inline DbU::Unit getSearchAreaHalo () const; inline DistanceT* setDistance ( DistanceT );
template<typename DistanceT> inline void setSearchAreaHalo ( DbU::Unit );
inline DistanceT* setDistance ( DistanceT ); void load ( Net* net );
inline void setSearchAreaHalo ( DbU::Unit ); void run ( Mode mode=Mode::Standart );
void load ( Net* net ); private:
void loadFixedGlobal ( Net* net ); Dijkstra ( const Dijkstra& );
void run ( Mode mode=Mode::Standart ); Dijkstra& operator= ( const Dijkstra& );
inline const VertexSet& getSources () const; static DbU::Unit _distance ( const Vertex*, const Vertex*, const Edge* );
private: Point _getPonderedPoint () const;
Dijkstra ( const Dijkstra& ); void _cleanup ();
Dijkstra& operator= ( const Dijkstra& ); bool _propagate ( Flags enabledSides );
static DbU::Unit _distance ( const Vertex*, const Vertex*, const Edge* ); void _traceback ( Vertex* );
Point _getPonderedPoint () const; void _materialize ();
void _cleanup (); void _selectFirstSource ();
bool _propagate ( Flags enabledSides ); void _toSources ( Vertex*, int connexId );
void _traceback ( Vertex* ); void _getConnecteds ( Vertex*, VertexSet& );
void _materialize (); void _checkEdges () const;
void _selectFirstSource (); void _createSelfSymSeg ( Segment* );
void _toSources ( Vertex*, int connexId );
void _getConnecteds ( Vertex*, VertexSet& ); inline void setAxisTarget ();
void _checkEdges () const; inline bool needAxisTarget () const;
void _createSelfSymSeg ( Segment* ); inline void setFlags ( Flags );
inline void unsetFlags ( Flags );
inline void setAxisTarget (); void setAxisTargets ();
inline bool needAxisTarget () const; void unsetAxisTargets ();
inline void setFlags ( Flags );
inline void unsetFlags ( Flags ); bool _attachSymContactsHook ( RoutingPad* );
void setAxisTargets (); void _limitSymSearchArea ( RoutingPad* rp );
void unsetAxisTargets (); void _setSourcesGRAData ( Vertex*, RoutingPad*);
bool _checkFrom2 ( Edge*, Vertex* );
bool _attachSymContactsHook ( RoutingPad* ); bool _isDistance2Shorter ( DbU::Unit&, Vertex*, Vertex*, Edge* );
void _limitSymSearchArea ( RoutingPad* rp ); void _pushEqualDistance ( DbU::Unit, bool, Vertex*, Vertex*, Edge* );
void _setSourcesGRAData ( Vertex*, RoutingPad*); void _updateGRAData ( Vertex*, bool, Vertex* );
bool _checkFrom2 ( Edge*, Vertex* ); void _initiateUpdateIntervals ( Vertex* );
bool _isDistance2Shorter ( DbU::Unit&, Vertex*, Vertex*, Edge* ); bool _updateIntervals ( bool&, Vertex*, bool&, int&, Edge* );
void _pushEqualDistance ( DbU::Unit, bool, Vertex*, Vertex*, Edge* ); void _updateRealOccupancy ( Vertex* );
void _updateGRAData ( Vertex*, bool, Vertex* );
void _initiateUpdateIntervals ( Vertex* );
bool _updateIntervals ( bool&, Vertex*, bool&, int&, Edge* );
void _updateRealOccupancy ( Vertex* );
private: private:
AnabaticEngine* _anabatic; AnabaticEngine* _anabatic;
vector<Vertex*> _vertexes; vector<Vertex*> _vertexes;
@ -586,7 +543,6 @@ namespace Anabatic {
inline bool Dijkstra::isBipoint () const { return _net and (_targets.size()+_sources.size() == 2); } inline bool Dijkstra::isBipoint () const { return _net and (_targets.size()+_sources.size() == 2); }
inline bool Dijkstra::isSourceVertex ( Vertex* v ) const { return (_sources.find(v) != _sources.end()); } inline bool Dijkstra::isSourceVertex ( Vertex* v ) const { return (_sources.find(v) != _sources.end()); }
inline bool Dijkstra::isTargetVertex ( Vertex* v ) const { return (_targets.find(v) != _targets.end()); } inline bool Dijkstra::isTargetVertex ( Vertex* v ) const { return (_targets.find(v) != _targets.end()); }
inline Net* Dijkstra::getNet () const { return _net; }
inline DbU::Unit Dijkstra::getSearchAreaHalo () const { return _searchAreaHalo; } inline DbU::Unit Dijkstra::getSearchAreaHalo () const { return _searchAreaHalo; }
inline void Dijkstra::setSearchAreaHalo ( DbU::Unit halo ) { _searchAreaHalo = halo; } inline void Dijkstra::setSearchAreaHalo ( DbU::Unit halo ) { _searchAreaHalo = halo; }
@ -596,11 +552,12 @@ namespace Anabatic {
inline void Dijkstra::setFlags ( Flags mask ) { _flags |= mask; } inline void Dijkstra::setFlags ( Flags mask ) { _flags |= mask; }
inline bool Dijkstra::needAxisTarget () const { return (_flags & Mode::AxisTarget); } inline bool Dijkstra::needAxisTarget () const { return (_flags & Mode::AxisTarget); }
inline void Dijkstra::unsetFlags ( Flags mask ) { _flags &= ~mask; } inline void Dijkstra::unsetFlags ( Flags mask ) { _flags &= ~mask; }
inline const VertexSet& Dijkstra::getSources () const { return _sources; }
} // Anabatic namespace. } // Anabatic namespace.
GETSTRING_POINTER_SUPPORT(Anabatic::Vertex); GETSTRING_POINTER_SUPPORT(Anabatic::Vertex);
IOSTREAM_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

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "Edge.h<anabatic>" -*- // -*- mode: C++; explicit-buffer-name: "Edge.h<anabatic>" -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2018, All Rights Reserved // Copyright (c) UPMC 2016-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -14,7 +14,9 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#pragma once #ifndef ANABATIC_EDGE_H
#define ANABATIC_EDGE_H
#include <string> #include <string>
#include "hurricane/Name.h" #include "hurricane/Name.h"
#include "hurricane/Interval.h" #include "hurricane/Interval.h"
@ -24,10 +26,10 @@ namespace Hurricane {
class Segment; class Segment;
} }
#include "anabatic/Constants.h" #include "anabatic/Constants.h"
#include "anabatic/EdgeCapacity.h"
#include "anabatic/Edges.h" #include "anabatic/Edges.h"
namespace Anabatic { namespace Anabatic {
using std::string; using std::string;
@ -58,11 +60,8 @@ namespace Anabatic {
inline bool isHorizontal () const; inline bool isHorizontal () const;
inline bool hasNet ( const Net* ) const; inline bool hasNet ( const Net* ) const;
inline unsigned int getCapacity () 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; inline unsigned int getRealOccupancy () const;
inline float getEstimateOccupancy () const; inline unsigned int getEstimateOccupancy () const;
inline float getHistoricCost () const; inline float getHistoricCost () const;
DbU::Unit getDistance () const; DbU::Unit getDistance () const;
inline GCell* getSource () const; inline GCell* getSource () const;
@ -74,16 +73,12 @@ namespace Anabatic {
Interval getSide () const; Interval getSide () const;
Segment* getSegment ( const Net* ) const; Segment* getSegment ( const Net* ) const;
inline const vector<Segment*>& getSegments () const; inline const vector<Segment*>& getSegments () const;
//inline void setCapacity ( int ); inline void setCapacity ( int );
//inline void incCapacity ( int ); inline void incCapacity ( int );
inline void forceCapacity ( int );
inline void reserveCapacity ( int );
inline void setRealOccupancy ( int ); inline void setRealOccupancy ( int );
void incRealOccupancy ( int ); void incRealOccupancy ( int );
void incRealOccupancy2 ( int ); void incRealOccupancy2 ( int );
inline void incEstimateOccupancy ( float );
inline void setHistoricCost ( float ); inline void setHistoricCost ( float );
bool isEnding ( Segment* ) const;
void add ( Segment* ); void add ( Segment* );
void remove ( Segment* ); void remove ( Segment* );
void replace ( Segment* orig, Segment* repl ); void replace ( Segment* orig, Segment* repl );
@ -91,18 +86,19 @@ namespace Anabatic {
inline const Flags& flags () const; inline const Flags& flags () const;
inline Flags& flags (); inline Flags& flags ();
inline void revalidate () const; inline void revalidate () const;
bool isMaxCapacity ( Net* net = NULL ) const; bool isMaxCapacity ( Net* net = NULL ) const;
inline Flags& setFlags ( Flags mask );
void _setSource ( GCell* ); void _setSource ( GCell* );
void _setTarget ( GCell* ); void _setTarget ( GCell* );
private:
void _invalidate ();
void _revalidate ();
public: public:
// ExtensionGo support. // ExtensionGo support.
inline const Name& staticGetName (); inline const Name& staticGetName ();
virtual const Name& getName () const; virtual const Name& getName () const;
virtual void translate ( const DbU::Unit&, const DbU::Unit& ); virtual void translate ( const DbU::Unit&, const DbU::Unit& );
virtual Box getBoundingBox () const; virtual Box getBoundingBox () const;
virtual void invalidate ( bool propagateFlag=true );
virtual void materialize ();
public: public:
// Inspector support. // Inspector support.
virtual string _getTypeName () const; virtual string _getTypeName () const;
@ -119,8 +115,7 @@ namespace Anabatic {
private: private:
static Name _extensionName; static Name _extensionName;
Flags _flags; Flags _flags;
EdgeCapacity* _capacities; unsigned int _capacity;
unsigned int _reservedCapacity;
unsigned int _realOccupancy; unsigned int _realOccupancy;
float _estimateOccupancy; float _estimateOccupancy;
float _historicCost; float _historicCost;
@ -135,34 +130,25 @@ namespace Anabatic {
inline bool Edge::isVertical () const { return _flags.isset(Flags::Vertical); } inline bool Edge::isVertical () const { return _flags.isset(Flags::Vertical); }
inline bool Edge::isHorizontal () const { return _flags.isset(Flags::Horizontal); } inline bool Edge::isHorizontal () const { return _flags.isset(Flags::Horizontal); }
inline bool Edge::hasNet ( const Net* owner ) const { return getSegment(owner); } inline bool Edge::hasNet ( const Net* owner ) const { return getSegment(owner); }
inline unsigned int Edge::getCapacity ( size_t depth ) const { return (_capacities) ? _capacities->getCapacity(depth) : 0; } inline unsigned int Edge::getCapacity () const { return _capacity; }
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 unsigned int Edge::getRealOccupancy () const { return _realOccupancy; }
inline float Edge::getEstimateOccupancy () const { return _estimateOccupancy; } inline unsigned int Edge::getEstimateOccupancy () const { return _estimateOccupancy; }
inline float Edge::getHistoricCost () const { return _historicCost; } inline float Edge::getHistoricCost () const { return _historicCost; }
inline GCell* Edge::getSource () const { return _source; } inline GCell* Edge::getSource () const { return _source; }
inline GCell* Edge::getTarget () const { return _target; } inline GCell* Edge::getTarget () const { return _target; }
inline DbU::Unit Edge::getAxis () const { return _axis; } inline DbU::Unit Edge::getAxis () const { return _axis; }
inline const vector<Segment*>& Edge::getSegments () const { return _segments; } inline const vector<Segment*>& Edge::getSegments () const { return _segments; }
inline void Edge::forceCapacity ( int capacity ) { if (_capacities) _capacities->forceCapacity(capacity); } inline void Edge::incCapacity ( int delta ) { _capacity = ((int)_capacity+delta > 0) ? _capacity+delta : 0; }
//inline void Edge::incCapacity ( int delta ) { _capacity = ((int)_capacity+delta > 0) ? _capacity+delta : 0; } inline void Edge::setCapacity ( int c ) { _capacity = ((int) c > 0) ? c : 0; }
//inline void Edge::setCapacity ( int c ) { _capacity = ((int) c > 0) ? c : 0; }
inline void Edge::setRealOccupancy ( int c ) { _realOccupancy = ((int) c > 0) ? c : 0; } inline void Edge::setRealOccupancy ( int c ) { _realOccupancy = ((int) c > 0) ? c : 0; }
inline void Edge::setHistoricCost ( float hcost ) { _historicCost = hcost; } inline void Edge::setHistoricCost ( float hcost ) { _historicCost = hcost; }
inline void Edge::incEstimateOccupancy ( float delta ) { _estimateOccupancy += delta; }
inline const Flags& Edge::flags () const { return _flags; } inline const Flags& Edge::flags () const { return _flags; }
inline Flags& Edge::flags () { return _flags; } inline Flags& Edge::flags () { return _flags; }
inline Flags& Edge::setFlags ( Flags mask ) { _flags |= mask; return _flags; } inline void Edge::revalidate () const { /*if (_flags&Flags::Invalidated)*/ const_cast<Edge*>(this)->_revalidate(); }
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. } // Anabatic namespace.
INSPECTOR_P_SUPPORT(Anabatic::Edge); INSPECTOR_P_SUPPORT(Anabatic::Edge);
#endif // ANABATIC_EDGE_H

View File

@ -1,99 +0,0 @@
// -*- mode: C++; explicit-buffer-name: "EdgeCapacity.h<anabatic>" -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) UPMC 2018-2018, 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 : "./anabatic/EdgeCapacity.h" |
// +-----------------------------------------------------------------+
#ifndef ANABATIC_EDGE_CAPACITY_H
#define ANABATIC_EDGE_CAPACITY_H
#include <string>
#include <set>
#include "hurricane/Interval.h"
#include "anabatic/Constants.h"
namespace Anabatic {
using Hurricane::Record;
using Hurricane::DbU;
using Hurricane::Interval;
class AnabaticEngine;
// -------------------------------------------------------------------
// Class : "EdgeCapacity".
class EdgeCapacity {
public:
class Compare {
public:
inline bool operator() ( const EdgeCapacity*, const EdgeCapacity* ) const;
};
public:
EdgeCapacity ( AnabaticEngine*, Flags, Interval, size_t depth );
inline size_t incref ();
inline size_t decref ();
inline size_t getref () const;
inline AnabaticEngine* getAnabatic () const;
inline const Interval& getSpan () const;
inline int getCapacity () const;
inline int getCapacity ( size_t depth ) const;
void forceCapacity ( unsigned int );
std::string _getString () const;
Record* _getRecord () const;
private:
private:
AnabaticEngine* _anabatic;
size_t _refCount;
Flags _flags;
size_t _depth;
Interval _span;
std::vector<int> _capacities;
};
inline size_t EdgeCapacity::incref () { return ++_refCount; }
inline size_t EdgeCapacity::decref () { if (_refCount < 2) { delete this; return 0; } return --_refCount; }
inline size_t EdgeCapacity::getref () const { return _refCount; }
inline AnabaticEngine* EdgeCapacity::getAnabatic () const { return _anabatic; }
inline const Interval& EdgeCapacity::getSpan () const { return _span; }
inline int EdgeCapacity::getCapacity ( size_t depth ) const { return (depth<_depth) ? _capacities[depth] : 0; }
inline int EdgeCapacity::getCapacity () const
{
int full = 0;
for ( size_t depth=0; depth<_depth ; ++depth ) full += _capacities[depth];
return full;
}
inline bool EdgeCapacity::Compare::operator() ( const EdgeCapacity* lhs, const EdgeCapacity* rhs ) const
{
if ( (lhs->_flags & Flags::Horizontal) and not (rhs->_flags & Flags::Horizontal)) return true;
if (not (lhs->_flags & Flags::Horizontal) and (rhs->_flags & Flags::Horizontal)) return false;
DbU::Unit dmin = lhs->getSpan().getVMin() - rhs->getSpan().getVMin();
if (dmin < 0) return true;
if (dmin > 0) return false;
return lhs->getSpan().getVMax() < rhs->getSpan().getVMax();
}
typedef std::set<EdgeCapacity*,EdgeCapacity::Compare> EdgeCapacityLut;
} // Anabatic namespace.
INSPECTOR_P_SUPPORT(Anabatic::EdgeCapacity);
#endif // ANABATIC_EDGE_CAPACITY_H

View File

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "Edges.h<anabatic>" -*- // -*- mode: C++; explicit-buffer-name: "Edges.h<anabatic>" -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2018, All Rights Reserved // Copyright (c) UPMC 2016-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -19,7 +19,6 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "hurricane/DbU.h"
#include "hurricane/Collection.h" #include "hurricane/Collection.h"
#include "anabatic/Constants.h" #include "anabatic/Constants.h"
@ -28,7 +27,6 @@ namespace Anabatic {
using std::string; using std::string;
using std::vector; using std::vector;
using Hurricane::DbU;
using Hurricane::Record; using Hurricane::Record;
using Hurricane::Filter; using Hurricane::Filter;
using Hurricane::Locator; using Hurricane::Locator;
@ -112,82 +110,12 @@ namespace Anabatic {
{ } { }
// -------------------------------------------------------------------
// Class : "Path_Edges".
class Path_Edges : public EdgesHC {
public:
// Sub-Class: Locator.
class Locator : public EdgesHL {
public:
Locator ( const GCell* source, const GCell* target, Flags pathFlags );
inline Locator ( const Locator& );
virtual Edge* getElement () const;
virtual EdgesHL* getClone () const;
virtual bool isValid () const;
virtual void progress ();
virtual string _getString () const;
protected:
const GCell* _source;
const GCell* _target;
Flags _stateFlags;
DbU::Unit _uprobe;
Edge* _edge;
};
// GCell_Edges.
public:
inline Path_Edges ( const GCell* source, const GCell* target, Flags pathFlags=Flags::NorthPath );
inline Path_Edges ( const Path_Edges& );
virtual EdgesHC* getClone () const;
virtual EdgesHL* getLocator () const;
virtual string _getString () const;
protected:
const GCell* _source;
const GCell* _target;
Flags _pathFlags;
};
inline Path_Edges::Locator::Locator ( const Locator &locator )
: EdgesHL()
, _source (locator._source)
, _target (locator._target)
, _stateFlags(locator._stateFlags)
, _uprobe (locator._uprobe)
, _edge (locator._edge)
{
// cdebug_log(110,0) << "GCell_Edges::Locator::Locator(const Locator&)" << std::endl;
}
inline Path_Edges::Path_Edges ( const GCell* source, const GCell* target, Flags pathFlags )
: EdgesHC()
, _source (source)
, _target (target)
, _pathFlags(pathFlags)
{ }
inline Path_Edges::Path_Edges ( const Path_Edges& path )
: EdgesHC()
, _source (path._source)
, _target (path._target)
, _pathFlags(path._pathFlags)
{ }
} // Anabatic namespace. } // Anabatic namespace.
GETSTRING_POINTER_SUPPORT(Anabatic::GCell_Edges); GETSTRING_POINTER_SUPPORT(Anabatic::GCell_Edges);
GETSTRING_POINTER_SUPPORT(Anabatic::GCell_Edges::Locator); GETSTRING_POINTER_SUPPORT(Anabatic::GCell_Edges::Locator);
GETSTRING_POINTER_SUPPORT(Anabatic::Path_Edges);
GETSTRING_POINTER_SUPPORT(Anabatic::Path_Edges::Locator);
IOSTREAM_POINTER_SUPPORT(Anabatic::GCell_Edges); IOSTREAM_POINTER_SUPPORT(Anabatic::GCell_Edges);
IOSTREAM_POINTER_SUPPORT(Anabatic::GCell_Edges::Locator); IOSTREAM_POINTER_SUPPORT(Anabatic::GCell_Edges::Locator);
IOSTREAM_POINTER_SUPPORT(Anabatic::Path_Edges);
IOSTREAM_POINTER_SUPPORT(Anabatic::Path_Edges::Locator);
#endif // ANABATIC_EDGES_H #endif // ANABATIC_EDGES_H

View File

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "GCell.h<anabatic>" -*- // -*- mode: C++; explicit-buffer-name: "GCell.h<anabatic>" -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2018, All Rights Reserved // Copyright (c) UPMC 2016-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -14,9 +14,10 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#pragma once #ifndef ANABATIC_GCELL_H
#define ANABATIC_GCELL_H
#include <vector> #include <vector>
#include <queue>
#include <string> #include <string>
#include <set> #include <set>
#include <functional> #include <functional>
@ -63,8 +64,6 @@ namespace Anabatic {
class AnabaticEngine; class AnabaticEngine;
class GCell; class GCell;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
@ -103,225 +102,186 @@ namespace Anabatic {
class CompareByDensity : public binary_function<GCell*,GCell*,bool> { class CompareByDensity : public binary_function<GCell*,GCell*,bool> {
public: public:
CompareByDensity ( size_t depth ); CompareByDensity ( size_t depth );
inline bool operator() ( GCell* lhs, GCell* rhs ) const; inline bool operator() ( GCell* lhs, GCell* rhs );
private: private:
size_t _depth; size_t _depth;
}; };
class CompareByKey : public binary_function<const GCell*,const GCell*,bool> { class CompareByKey : public binary_function<const GCell*,const GCell*,bool> {
public: public:
inline bool operator() ( const GCell* lhs, const GCell* rhs ) const; inline bool operator() ( const GCell* lhs, const GCell* rhs );
}; };
public: public:
class Key { class Key {
public: public:
inline Key ( const GCell*, size_t depth ); inline Key ( GCell*, size_t depth );
inline ~Key (); inline float getDensity () const;
inline float getDensity () const; inline GCell* getGCell () const;
inline const GCell* getGCell () const; inline void update ( size_t depth );
inline bool isActive () const; friend bool operator< ( const Key&, const Key& );
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;
};
private: private:
const GCell* _gcell; GCell* _gcell;
float _density; float _density;
}; };
public: public:
static uint32_t getDisplayMode (); static uint32_t getDisplayMode ();
static void setDisplayMode ( uint32_t ); static void setDisplayMode ( uint32_t );
static Box getBorder ( const GCell*, const GCell* ); static Box getBorder ( const GCell*, const GCell* );
static inline DbU::Unit getMatrixHSide (); public:
static inline DbU::Unit getMatrixVSide (); static GCell* create ( AnabaticEngine* );
public: public:
static GCell* create ( AnabaticEngine* ); inline bool isSaturated () const;
public: bool isSaturated ( size_t depth ) const;
inline bool isSatProcessed ( size_t depth ) const; inline bool isInvalidated () const;
inline bool isSaturated () const; inline bool isHFlat () const;
bool isSaturated ( size_t depth ) const; inline bool isVFlat () const;
inline bool isInvalidated () const; inline bool isFlat () const;
inline bool isHFlat () const; inline bool isDevice () const;
inline bool isVFlat () const; inline bool isHChannel () const;
inline bool isFlat () const; inline bool isVChannel () const;
inline bool isDevice () const; inline bool isStrut () const;
inline bool isHChannel () const; inline bool isMatrix () const;
inline bool isVChannel () const; inline bool isIoPad () const;
inline bool isStrut () const; bool isWest ( GCell* ) const;
inline bool isAnalog () const; bool isEast ( GCell* ) const;
inline bool isMatrix () const; bool isNorth ( GCell* ) const;
inline bool isRow () const; bool isSouth ( GCell* ) const;
inline bool isIoPad () const; Contact* hasGContact ( const Contact* ) const;
inline bool isGoStraight () const; Contact* hasGContact ( const Net* ) const;
inline bool isHRail () const; inline AnabaticEngine* getAnabatic () const;
inline bool isVRail () const; inline Flags getType () const;
inline bool isStdCellRow () const; inline DbU::Unit getXMin () const;
inline bool isChannelRow () const; inline DbU::Unit getYMin () const;
bool isWest ( GCell* ) const; inline DbU::Unit getXMax ( int shrink=0 ) const;
bool isEast ( GCell* ) const; inline DbU::Unit getYMax ( int shrink=0 ) const;
bool isNorth ( GCell* ) const; inline DbU::Unit getXCenter () const;
bool isSouth ( GCell* ) const; inline DbU::Unit getYCenter () const;
bool hasNet ( const Net* ) const; inline DbU::Unit getConstraintXMax ( int shrink=0 ) const;
Contact* hasGContact ( const Contact* ) const; inline DbU::Unit getConstraintYMax ( int shrink=0 ) const;
Contact* hasGContact ( const Net* ) const; inline Interval getSide ( Flags direction, int shrink=0 ) const;
bool isHorizontalPlane ( size_t depth ) const; inline Point getCenter () const;
bool isVerticalPlane ( size_t depth ) const; inline Box getConstraintBox () const;
inline AnabaticEngine* getAnabatic () const; inline const vector<Edge*>& getWestEdges () const;
inline Flags getType () const; inline const vector<Edge*>& getEastEdges () const;
inline DbU::Unit getXMin () const; inline const vector<Edge*>& getNorthEdges () const;
inline DbU::Unit getYMin () const; inline const vector<Edge*>& getSouthEdges () const;
inline DbU::Unit getXMax ( int shrink=0 ) const; Edge* getEdgeTo ( GCell*, Flags sideHint=Flags::AllSides ) const;
inline DbU::Unit getYMax ( int shrink=0 ) const; Edge* getEdgeAt ( Flags sideHint, DbU::Unit u ) const;
inline DbU::Unit getXCenter () const; inline Edges getEdges ( Flags sides=Flags::AllSides ) const;
inline DbU::Unit getYCenter () const; inline GCell* getWest () const;
inline DbU::Unit getConstraintXMax ( int shrink=0 ) const; inline GCell* getEast () const;
inline DbU::Unit getConstraintYMax ( int shrink=0 ) const; inline GCell* getSouth () const;
inline Interval getSide ( Flags direction, int shrink=0 ) const; inline GCell* getNorth () const;
inline Interval getHSide ( int shrink=0 ) const;
inline Interval getVSide ( int shrink=0 ) const; inline Edge* getWestEdge () const;
inline Point getCenter () const; inline Edge* getEastEdge () const;
inline Box getConstraintBox () const; inline Edge* getSouthEdge () const;
inline const vector<Edge*>& getWestEdges () const; inline Edge* getNorthEdge () const;
inline const vector<Edge*>& getEastEdges () const;
inline const vector<Edge*>& getNorthEdges () const; GCell* getWest ( DbU::Unit y ) const;
inline const vector<Edge*>& getSouthEdges () const; GCell* getEast ( DbU::Unit y ) const;
Edge* getEdgeTo ( GCell*, Flags sideHint=Flags::AllSides ) const; GCell* getSouth ( DbU::Unit x ) const;
Edge* getEdgeAt ( Flags sideHint, DbU::Unit u ) const; GCell* getNorth ( DbU::Unit x ) const;
inline Edges getEdges ( Flags sides=Flags::AllSides ) const; GCell* getNeighborAt ( Flags side, DbU::Unit axis ) const;
inline GCell* getWest () const; GCell* getUnder ( DbU::Unit x, DbU::Unit y ) const;
inline GCell* getEast () const; inline GCell* getUnder ( Point p ) const;
inline GCell* getSouth () const; GCell* hcut ( DbU::Unit y );
inline GCell* getNorth () const; GCell* vcut ( DbU::Unit x );
bool doGrid ();
GCell* getEastNMatrix () const; Contact* getGContact ( Net* );
GCell* getNorthNMatrix () const; inline const vector<Contact*>& getGContacts () const;
Contact* breakGoThrough ( Net* net );
inline Edge* getWestEdge () const; bool unrefContact ( Contact* );
inline Edge* getEastEdge () const; void setXY ( DbU::Unit x, DbU::Unit y );
inline Edge* getSouthEdge () const; void updateContactsPosition ();
inline Edge* getNorthEdge () const; void cleanupGlobal ();
inline DbU::Unit getWidth () const;
GCell* getWest ( DbU::Unit y ) const; inline DbU::Unit getHeight () const;
GCell* getEast ( DbU::Unit y ) const; // Detailed routing functions.
GCell* getSouth ( DbU::Unit x ) const; bool hasFreeTrack ( size_t depth, float reserve ) const;
GCell* getNorth ( DbU::Unit x ) const; inline size_t getDepth () const;
GCell* getNeighborAt ( Flags side, DbU::Unit axis ) const; float getHCapacity () const;
GCell* getUnder ( DbU::Unit x, DbU::Unit y ) const; float getVCapacity () const;
inline GCell* getUnder ( Point p ) const; float getDensity ( Flags flags=Flags::NoFlags ) const;
GCell* hcut ( DbU::Unit y ); float getAverageHVDensity () const;
GCell* vcut ( DbU::Unit x ); float getMaxHVDensity () const;
bool doGrid (); inline float getCDensity ( Flags flags=Flags::NoFlags ) const;
Contact* getGContact ( Net* ); inline float getWDensity ( size_t depth, Flags flags=Flags::NoFlags ) const;
inline const vector<Contact*>& getGContacts () const; inline DbU::Unit getBlockage ( size_t depth ) const;
Segment* hasGoThrough ( Net* ) const; inline float getFragmentation ( size_t depth ) const;
Contact* breakGoThrough ( Net* ); inline float getFeedthroughs ( size_t depth ) const;
bool unrefContact ( Contact* ); inline float getGlobalsCount ( size_t depth ) const;
void setSouthWestCorner ( DbU::Unit x, DbU::Unit y ); inline const vector<AutoSegment*>& getHSegments () const;
void cleanupGlobal (); inline const vector<AutoSegment*>& getVSegments () const;
inline DbU::Unit getWidth () const; inline const vector<AutoContact*>& getContacts () const;
inline DbU::Unit getHeight () const; AutoSegments getHStartSegments ();
// Detailed routing functions. AutoSegments getVStartSegments ();
bool hasFreeTrack ( size_t depth, float reserve ) const; AutoSegments getHStopSegments ();
inline size_t getDepth () const; AutoSegments getVStopSegments ();
size_t getNetCount () const; inline AutoSegments getStartSegments ( Flags direction );
inline int getRpCount () const; inline AutoSegments getStopSegments ( Flags direction );
int getHCapacity () const; size_t getRoutingPads ( set<RoutingPad*>& );
int getVCapacity () const; inline const Key& getKey () const;
int getCapacity ( size_t depth ) const; size_t checkDensity () const;
float getDensity ( Flags flags=Flags::NoFlags ) const; bool checkEdgeSaturation ( size_t hreserved, size_t vreserved) const;
float getDensity ( size_t depth ) const; void setType ( Flags );
float getAverageHVDensity () const; void addBlockage ( size_t depth, DbU::Unit );
float getMaxHVDensity () const; inline void addHSegment ( AutoSegment* );
inline float getCDensity ( Flags flags=Flags::NoFlags ) const; inline void addVSegment ( AutoSegment* );
inline float getWDensity ( size_t depth, Flags flags=Flags::NoFlags ) const; inline void addContact ( AutoContact* );
inline DbU::Unit getBlockage ( size_t depth ) const; void removeVSegment ( AutoSegment* );
inline float getFragmentation ( size_t depth ) const; void removeHSegment ( AutoSegment* );
inline float getFeedthroughs ( size_t depth ) const; void removeContact ( AutoContact* );
inline float getGlobalsCount ( size_t depth ) const; void updateContacts ();
inline const vector<AutoSegment*>& getHSegments () const; size_t updateDensity ();
inline const vector<AutoSegment*>& getVSegments () const; inline void updateKey ( size_t depth );
inline const vector<AutoContact*>& getContacts () const; void truncDensities ();
AutoSegments getHStartSegments (); bool stepBalance ( size_t depth, Set& invalidateds );
AutoSegments getVStartSegments (); void rpDesaturate ( set<Net*>& );
AutoSegments getHStopSegments (); bool stepDesaturate ( size_t depth
AutoSegments getVStopSegments (); , set<Net*>&, AutoSegment*& moved
inline AutoSegments getStartSegments ( Flags direction ); , Flags flags=Flags::NoFlags );
inline AutoSegments getStopSegments ( Flags direction ); bool stepNetDesaturate ( size_t depth
size_t getRoutingPads ( set<RoutingPad*>& ); , set<Net*>& globalNets
inline const Key& getKey () const; , Set& invalidateds );
inline Key* cloneKey ( size_t depth ) const;
inline Key* getLastClonedKey () const; void setEdgesOccupancy (unsigned int, unsigned int);
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* );
inline void addContact ( AutoContact* );
void removeVSegment ( AutoSegment* );
void removeHSegment ( AutoSegment* );
void removeContact ( AutoContact* );
void updateGContacts ( Flags flags );
void updateContacts ();
size_t updateDensity ();
inline void updateKey ( size_t depth );
void truncDensities ();
bool stepBalance ( size_t depth, Set& invalidateds );
void rpDesaturate ( set<Net*>& );
bool stepDesaturate ( size_t depth
, set<Net*>&, AutoSegment*& moved
, Flags flags=Flags::NoFlags );
bool stepNetDesaturate ( size_t depth
, set<Net*>& globalNets
, Set& invalidateds );
inline void incRpCount ( int );
void forceEdgesCapacities ( unsigned int hcapacities, unsigned int vcapacities );
// Misc. functions. // Misc. functions.
inline const Flags& flags () const; inline const Flags& flags () const;
inline Flags& flags (); inline Flags& flags ();
void _add ( Edge* edge, Flags side ); void _add ( Edge* edge, Flags side );
void _remove ( Edge* edge, Flags side=Flags::AllSides ); void _remove ( Edge* edge, Flags side=Flags::AllSides );
void _destroyEdges (); void _destroyEdges ();
private: void _revalidate ();
void _moveEdges ( GCell* dest, size_t ibegin, Flags flags ); private:
public: void _moveEdges ( GCell* dest, size_t ibegin, Flags flags );
// Observers. public:
template<typename OwnerT> // Observers.
inline OwnerT* getObserver ( size_t slot ); template<typename OwnerT>
inline void setObserver ( size_t slot, BaseObserver* ); inline OwnerT* getObserver ( size_t slot );
inline void notify ( unsigned int flags ); inline void setObserver ( size_t slot, BaseObserver* );
// ExtensionGo support. inline void notify ( unsigned int flags );
inline const Name& staticGetName (); // ExtensionGo support.
virtual const Name& getName () const; inline const Name& staticGetName ();
virtual void translate ( const DbU::Unit&, const DbU::Unit& ); virtual const Name& getName () const;
virtual Box getBoundingBox () const; virtual void translate ( const DbU::Unit&, const DbU::Unit& );
virtual void invalidate ( bool propagateFlag=true ); virtual Box getBoundingBox () const;
virtual void materialize (); public:
public: // Inspector support.
// Inspector support. virtual string _getTypeName () const;
virtual string _getTypeName () const; virtual string _getString () const;
virtual string _getString () const; virtual Record* _getRecord () const;
virtual Record* _getRecord () const; protected:
protected: GCell ( AnabaticEngine*, DbU::Unit xmin, DbU::Unit ymin );
GCell ( AnabaticEngine*, DbU::Unit xmin, DbU::Unit ymin ); virtual ~GCell ();
virtual ~GCell (); GCell* _create ( DbU::Unit xmin, DbU::Unit ymin );
GCell* _create ( DbU::Unit xmin, DbU::Unit ymin ); virtual void _postCreate ();
virtual void _postCreate (); virtual void _preDestroy ();
virtual void _preDestroy (); private:
private: GCell ( const GCell& );
GCell ( const GCell& ); GCell& operator= ( const GCell& );
GCell& operator= ( const GCell& );
private: private:
static Name _extensionName; static Name _extensionName;
static uint32_t _displayMode; static uint32_t _displayMode;
static DbU::Unit _matrixHSide;
static DbU::Unit _matrixVSide;
Observable _observable; Observable _observable;
AnabaticEngine* _anabatic; AnabaticEngine* _anabatic;
Flags _flags; Flags _flags;
@ -337,8 +297,6 @@ namespace Anabatic {
vector<AutoContact*> _contacts; vector<AutoContact*> _contacts;
size_t _depth; size_t _depth;
size_t _pinDepth; size_t _pinDepth;
uint32_t _satProcessed;
int _rpCount;
DbU::Unit* _blockages; DbU::Unit* _blockages;
float _cDensity; float _cDensity;
float* _densities; float* _densities;
@ -346,71 +304,54 @@ namespace Anabatic {
float* _fragmentations; float* _fragmentations;
float* _globalsCount; float* _globalsCount;
Key _key; Key _key;
mutable Key* _lastClonedKey;
}; };
inline bool GCell::isHFlat () const { return getYMin() == getYMax(); } inline bool GCell::isHFlat () const { return getYMin() == getYMax(); }
inline bool GCell::isVFlat () const { return getXMin() == getXMax(); } inline bool GCell::isVFlat () const { return getXMin() == getXMax(); }
inline bool GCell::isFlat () const { return isHFlat() or isVFlat(); } inline bool GCell::isFlat () const { return isHFlat() or isVFlat(); }
inline bool GCell::isDevice () const { return _flags & Flags::DeviceGCell; } inline bool GCell::isDevice () const { return _flags & Flags::DeviceGCell; }
inline bool GCell::isHChannel () const { return _flags & Flags::HChannelGCell; } inline bool GCell::isHChannel () const { return _flags & Flags::HChannelGCell; }
inline bool GCell::isVChannel () const { return _flags & Flags::VChannelGCell; } inline bool GCell::isVChannel () const { return _flags & Flags::VChannelGCell; }
inline bool GCell::isStrut () const { return _flags & Flags::StrutGCell; } 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::isMatrix () const { return _flags & Flags::MatrixGCell; } inline bool GCell::isIoPad () const { return _flags & Flags::IoPadGCell; }
inline bool GCell::isRow () const { return _flags & Flags::RowGCellMask; } inline bool GCell::isSaturated () const { return _flags & Flags::Saturated; }
inline bool GCell::isIoPad () const { return _flags & Flags::IoPadGCell; } inline bool GCell::isInvalidated () const { return _flags & Flags::Invalidated; }
inline bool GCell::isGoStraight () const { return _flags & Flags::GoStraight; } inline Flags GCell::getType () const { return _flags & Flags::GCellTypeMask; }
inline bool GCell::isHRail () const { return _flags & Flags::HRailGCell; } inline AnabaticEngine* GCell::getAnabatic () const { return _anabatic; }
inline bool GCell::isVRail () const { return _flags & Flags::VRailGCell; } inline DbU::Unit GCell::getXMin () const { return _xmin; }
inline bool GCell::isStdCellRow () const { return _flags & Flags::StdCellRow; } inline DbU::Unit GCell::getYMin () const { return _ymin; }
inline bool GCell::isChannelRow () const { return _flags & Flags::ChannelRow; } inline Edges GCell::getEdges ( Flags sides ) const { return new GCell_Edges(this,sides); }
inline bool GCell::isSaturated () const { return _flags & Flags::Saturated; } inline const vector<Edge*>& GCell::getWestEdges () const { return _westEdges; }
inline bool GCell::isInvalidated () const { return _flags & Flags::Invalidated; } inline const vector<Edge*>& GCell::getEastEdges () const { return _eastEdges; }
inline DbU::Unit GCell::getMatrixHSide () { return _matrixHSide; } inline const vector<Edge*>& GCell::getNorthEdges () const { return _northEdges; }
inline DbU::Unit GCell::getMatrixVSide () { return _matrixVSide; } inline const vector<Edge*>& GCell::getSouthEdges () const { return _southEdges; }
inline Flags GCell::getType () const { return _flags & Flags::GCellTypeMask; } inline GCell* GCell::getWest () const { return _westEdges.empty() ? NULL : _westEdges[0]->getOpposite(this); }
inline AnabaticEngine* GCell::getAnabatic () const { return _anabatic; } inline GCell* GCell::getEast () const { return _eastEdges.empty() ? NULL : _eastEdges[0]->getOpposite(this); }
inline DbU::Unit GCell::getXMin () const { return _xmin; } inline GCell* GCell::getSouth () const { return _southEdges.empty() ? NULL : _southEdges[0]->getOpposite(this); }
inline DbU::Unit GCell::getYMin () const { return _ymin; } inline GCell* GCell::getNorth () const { return _northEdges.empty() ? NULL : _northEdges[0]->getOpposite(this); }
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 Edge* GCell::getWestEdge () const { return _westEdges.empty() ? NULL : _westEdges[0]; }
inline Edges GCell::getEdges ( Flags sides ) const { return new GCell_Edges(this,sides); } inline Edge* GCell::getEastEdge () const { return _eastEdges.empty() ? NULL : _eastEdges[0]; }
inline const vector<Edge*>& GCell::getWestEdges () const { return _westEdges; } inline Edge* GCell::getSouthEdge () const { return _southEdges.empty() ? NULL : _southEdges[0]; }
inline const vector<Edge*>& GCell::getEastEdges () const { return _eastEdges; } inline Edge* GCell::getNorthEdge () const { return _northEdges.empty() ? NULL : _northEdges[0]; }
inline const vector<Edge*>& GCell::getNorthEdges () const { return _northEdges; }
inline const vector<Edge*>& GCell::getSouthEdges () const { return _southEdges; } inline GCell* GCell::getUnder ( Point p ) const { return getUnder(p.getX(),p.getY()); }
inline GCell* GCell::getWest () const { return _westEdges.empty() ? NULL : _westEdges[0]->getOpposite(this); } inline const vector<Contact*>& GCell::getGContacts () const { return _gcontacts; }
inline GCell* GCell::getEast () const { return _eastEdges.empty() ? NULL : _eastEdges[0]->getOpposite(this); } inline size_t GCell::getDepth () const { return _depth; }
inline GCell* GCell::getSouth () const { return _southEdges.empty() ? NULL : _southEdges[0]->getOpposite(this); } inline const vector<AutoSegment*>& GCell::getVSegments () const { return _vsegments; }
inline GCell* GCell::getNorth () const { return _northEdges.empty() ? NULL : _northEdges[0]->getOpposite(this); } inline const vector<AutoSegment*>& GCell::getHSegments () const { return _hsegments; }
inline const vector<AutoContact*>& GCell::getContacts () const { return _contacts; }
inline Edge* GCell::getWestEdge () const { return _westEdges.empty() ? NULL : _westEdges[0]; }
inline Edge* GCell::getEastEdge () const { return _eastEdges.empty() ? NULL : _eastEdges[0]; } inline DbU::Unit GCell::getWidth () const { return (getXMax()-getXMin()); }
inline Edge* GCell::getSouthEdge () const { return _southEdges.empty() ? NULL : _southEdges[0]; } inline DbU::Unit GCell::getHeight () const { return (getYMax()-getYMin()); }
inline Edge* GCell::getNorthEdge () const { return _northEdges.empty() ? NULL : _northEdges[0]; }
inline const GCell::Key& GCell::getKey () const { return _key; }
inline GCell* GCell::getUnder ( Point p ) const { return getUnder(p.getX(),p.getY()); } inline void GCell::setType ( Flags type ) { _flags.reset(Flags::GCellTypeMask); _flags |= (type&Flags::GCellTypeMask); };
inline const vector<Contact*>& GCell::getGContacts () const { return _gcontacts; } inline void GCell::updateKey ( size_t depth ) { _key.update(depth); }
inline size_t GCell::getDepth () const { return _depth; } inline const Flags& GCell::flags () const { return _flags; }
inline int GCell::getRpCount () const { return _rpCount; } inline Flags& GCell::flags () { return _flags; }
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 DbU::Unit GCell::getXMax ( int shrink ) const inline DbU::Unit GCell::getXMax ( int shrink ) const
{ return _eastEdges.empty() ? getCell()->getAbutmentBox().getXMax() - shrink { return _eastEdges.empty() ? getCell()->getAbutmentBox().getXMax() - shrink
@ -441,10 +382,6 @@ namespace Anabatic {
return Interval( getXMin(), getConstraintXMax(shrink) ); 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 ) inline void GCell::setObserver ( size_t slot, BaseObserver* observer )
{ _observable.setObserver( slot, observer ); } { _observable.setObserver( slot, observer ); }
@ -481,21 +418,15 @@ namespace Anabatic {
inline DbU::Unit GCell::getBlockage ( size_t depth ) const inline DbU::Unit GCell::getBlockage ( size_t depth ) const
{ return (depth<_depth) ? _blockages[depth] : 0; } { return (depth<_depth) ? _blockages[depth] : 0; }
inline void GCell::addVSegment ( AutoSegment* segment )
{ _flags |= Flags::Invalidated; _vsegments.push_back(segment); }
inline void GCell::addHSegment ( AutoSegment* segment ) inline void GCell::addHSegment ( AutoSegment* segment )
{ _flags |= Flags::Invalidated; _hsegments.push_back(segment); } { _flags |= Flags::Invalidated; _hsegments.push_back(segment); }
inline void GCell::addVSegment ( AutoSegment* segment )
{ _flags |= Flags::Invalidated; _vsegments.push_back(segment); }
inline void GCell::addContact ( AutoContact* contact ) inline void GCell::addContact ( AutoContact* contact )
{ _flags |= Flags::Invalidated; _contacts.push_back(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 ) inline bool operator< ( const GCell& lhs, const GCell& rhs )
{ {
@ -504,25 +435,17 @@ namespace Anabatic {
return lhs.getId() < rhs.getId(); return lhs.getId() < rhs.getId();
} }
// GCell::CompareByKey Inline Functions. // 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(); } { return lhs->getKey() < rhs->getKey(); }
// GCell::Key Inline Functions. // GCell::Key Inline Functions.
inline GCell::Key::Key ( const GCell* owner, size_t depth ) inline GCell::Key::Key ( GCell* owner, size_t depth ) : _gcell(owner), _density(owner->getWDensity(depth,Flags::NoUpdate)) {}
: _gcell(owner) inline float GCell::Key::getDensity () const { return _density; }
, _density(owner->getWDensity(depth,Flags::NoUpdate)) inline GCell* GCell::Key::getGCell () const { return _gcell; }
{ } inline void GCell::Key::update ( size_t depth ) { _density=_gcell->getWDensity(depth); }
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 bool operator< ( const GCell::Key& lhs, const GCell::Key& rhs ) inline bool operator< ( const GCell::Key& lhs, const GCell::Key& rhs )
{ {
@ -532,22 +455,6 @@ namespace Anabatic {
return lhs._gcell->getId() < rhs._gcell->getId(); 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". // Class : "GCellDensitySet".
@ -592,3 +499,5 @@ namespace Anabatic {
INSPECTOR_P_SUPPORT(Anabatic::GCell); INSPECTOR_P_SUPPORT(Anabatic::GCell);
#endif // ANABATIC_GCELL_H

View File

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "Matrix.h<anabatic>" -*- // -*- mode: C++; explicit-buffer-name: "Matrix.h<anabatic>" -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2018, All Rights Reserved // Copyright (c) UPMC 2016-2016, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -94,7 +94,7 @@ namespace Anabatic {
inline GCell* getUnder ( Point ) const; inline GCell* getUnder ( Point ) const;
void setCell ( Cell*, DbU::Unit side ); void setCell ( Cell*, DbU::Unit side );
void updateLookup ( GCell* ); void updateLookup ( GCell* );
void resize ( Cell*, const vector<GCell*>& ); void resize ( Box area, DbU::Unit side );
void show () const; void show () const;
// Inspector support. // Inspector support.
virtual Record* _getRecord () const; virtual Record* _getRecord () const;

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