Compare commits
No commits in common. "devel" and "devel_anabatic" have entirely different histories.
devel
...
devel_anab
|
@ -40,4 +40,3 @@ documentation/RDS/RDS.toc
|
|||
cumulus/src/plugins/CoreToChip_c35b4.py
|
||||
cumulus/src/plugins/core2chip/c35b4.py
|
||||
|
||||
/result*
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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:]))
|
||||
|
376
LICENSE.rst
376
LICENSE.rst
|
@ -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.
|
43
README.rst
43
README.rst
|
@ -5,19 +5,20 @@
|
|||
Coriolis README
|
||||
===============
|
||||
|
||||
Coriolis is a free database, placement tool and routing tool for VLSI design.
|
||||
|
||||
Coriolis is a free database, placement tool and routing tool for VLSI designs.
|
||||
|
||||
|
||||
Purpose
|
||||
=======
|
||||
|
||||
Coriolis provides several tools to perform the layout of VLSI circuits. Its
|
||||
main components are the Hurricane database, the Etesian placer and the Katana
|
||||
main components are the Hurricane database, the Etesian placer and the Kite
|
||||
router, but other tools can use the Hurricane database and the parsers
|
||||
provided.
|
||||
|
||||
The user interface <cgt> is the prefered way to use Coriolis, but all
|
||||
Coriolis tools are Python modules and thus scriptable.
|
||||
Coriolis tools are Python modules and thus scriptables.
|
||||
|
||||
|
||||
Documentation
|
||||
|
@ -25,14 +26,14 @@ Documentation
|
|||
|
||||
The complete documentation is available here, both in pdf & html:
|
||||
|
||||
./documentation/output/html
|
||||
./documentation/_build/html/index.html
|
||||
./documentation/UsersGuide/UsersGuide.pdf
|
||||
|
||||
The documentation of the latest *stable* version is also
|
||||
available online. It may be quite outdated from the *devel*
|
||||
version.
|
||||
|
||||
https://www-soc.lip6.fr/sesi-docs/coriolis2-docs/coriolis2/en/latex/users-guide/UsersGuide.pdf
|
||||
https://soc-extras.lip6.fr/en/coriolis/coriolis2-users-guide/
|
||||
|
||||
|
||||
Building Coriolis
|
||||
|
@ -40,29 +41,35 @@ Building Coriolis
|
|||
|
||||
To build Coriolis, ensure the following prerequisites are met:
|
||||
|
||||
* Python 3,
|
||||
* cmake,
|
||||
* boost,
|
||||
* bison & flex,
|
||||
* Qt 4 or 5,
|
||||
* libxml2,
|
||||
* RapidJSON,
|
||||
* Python 2.7.
|
||||
* cmake.
|
||||
* boost.
|
||||
* bison & flex.
|
||||
* Qt 4 or 5.
|
||||
* libxml2.
|
||||
* RapidJSON
|
||||
* A C++11 compliant compiler.
|
||||
|
||||
The build system relies on a fixed directory tree from the root
|
||||
of the user currently building it. Thus first step is to get a clone of
|
||||
the repository in the right place. Proceed as follow: ::
|
||||
|
||||
ego@home:~$ mkdir -p ~/coriolis-2.x/src/
|
||||
ego@home:~$ mkdir -p ~/coriolis-2.x/src/support
|
||||
ego@home:~$ cd ~/coriolis-2.x/src/support
|
||||
ego@home:~$ git clone http://github.com/miloyip/rapidjson
|
||||
ego@home:~$ git checkout ec322005072076ef53984462fb4a1075c27c7dfd
|
||||
ego@home:~$ cd ~/coriolis-2.x/src
|
||||
ego@home:src$ git clone https://gitlab.lip6.fr/vlsi-eda/coriolis.git
|
||||
ego@home:src$ git clone https://www-soc.lip6.fr/git/coriolis.git
|
||||
ego@home:src$ cd coriolis
|
||||
|
||||
If you want to use the *devel* branch: ::
|
||||
|
||||
ego@home:coriolis$ git checkout devel
|
||||
|
||||
Then, build the tool: ::
|
||||
|
||||
ego@home:coriolis$ make install
|
||||
|
||||
If you encounter issues, please consult SUPPORT.rst for tips.
|
||||
Coriolis gets installed at the root of the following tree: ::
|
||||
|
||||
~/coriolis-2.x/<OS>.<DISTRIB>/Release.Shared/install/
|
||||
|
@ -78,11 +85,11 @@ The Coriolis main interface can be launched with the command: ::
|
|||
|
||||
ego@home:~: ~/coriolis-2.x/<OS>.<DISTRIB>/Release.Shared/install/bin/coriolis
|
||||
|
||||
The ``coriolis`` script detects its location and setups the UNIX
|
||||
environment appropriately, then lauches ``cgt`` (or *any* command, with the
|
||||
The ``coriolis`` script is tasked to guess it's location and setup appropriatly
|
||||
the UNIX environment, then lauch ``cgt`` (or *any* command, with the
|
||||
``--run=<COMMAND>`` option).
|
||||
|
||||
Conversely, you can setup the current shell environment for Coriolis by
|
||||
Conversely, you can setup the current shell environement for Coriolis by
|
||||
using the helper ``coriolisEnv.py``, then run any Coriolis tool: ::
|
||||
|
||||
ego@home:~$ eval `~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py`
|
||||
|
|
27
SUPPORT.rst
27
SUPPORT.rst
|
@ -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)
|
||||
|
|
@ -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)
|
|
@ -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
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
install( FILES FindSEABREEZE.cmake DESTINATION share/cmake/Modules )
|
||||
|
|
@ -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)
|
||||
|
|
@ -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} )
|
||||
|
|
@ -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.
|
||||
*/
|
||||
|
||||
|
|
@ -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
|
||||
*/
|
||||
}
|
|
@ -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%;
|
||||
}
|
|
@ -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.
|
||||
*/
|
|
@ -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> <tt>ClassA</tt> is abstract</b></tr>
|
||||
<tr><td width="70"><td class="normal"><a href="#pagetop">ClassB</a><td><b> <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>
|
|
@ -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 & 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 © 2005-2007 LIP6. All rights reserved</small></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
|
@ -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
|
||||
|
|
@ -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 © 2008-2020 Sorbonne Universite. All rights reserved</small></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
|
@ -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)">
|
|
@ -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 )
|
||||
|
||||
|
|
@ -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.
|
|
@ -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.
|
||||
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
|
@ -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.
|
||||
|
|
@ -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.
|
|
@ -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.
|
|
@ -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);
|
|
@ -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);
|
|
@ -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);
|
|
@ -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);
|
|
@ -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
|
|
@ -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);
|
|
@ -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);
|
|
@ -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;
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
|
||||
R1 0 1 10
|
||||
C1 1 -1 20
|
||||
R2 1 2 30
|
||||
C2 2 -1 10
|
|
@ -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
|
|
@ -1 +0,0 @@
|
|||
node : not only left and right children, can have multiple children
|
|
@ -3,13 +3,12 @@
|
|||
set(CMAKE_LEGACY_CYGWIN_WIN32 0)
|
||||
project(ANABATIC)
|
||||
|
||||
set(ignoreVariables "${BUILD_DOC} ${CMAKE_INSTALL_DIR}")
|
||||
set(ignoreVariables "${BUILD_DOC}")
|
||||
|
||||
option(BUILD_DOC "Build the documentation (doxygen)" OFF)
|
||||
option(CHECK_DATABASE "Run database in full check mode (very slow)" OFF)
|
||||
option(USE_LIBBFD "Link with BFD libraries to print stack traces" OFF)
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
cmake_minimum_required(VERSION 2.8.9)
|
||||
|
||||
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}$ENV{CORIOLIS_TOP}/share/cmake/Modules/")
|
||||
find_package(Bootstrap REQUIRED)
|
||||
|
@ -18,14 +17,13 @@
|
|||
set_cmake_policies()
|
||||
setup_boost()
|
||||
setup_qt()
|
||||
setup_python()
|
||||
|
||||
find_package(PythonLibs 2 REQUIRED)
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
find_package(FLUTE REQUIRED)
|
||||
find_package(VLSISAPD REQUIRED)
|
||||
find_package(HURRICANE REQUIRED)
|
||||
find_package(CORIOLIS REQUIRED)
|
||||
find_package(ETESIAN REQUIRED)
|
||||
find_package(COLOQUINTE REQUIRED)
|
||||
find_package(Doxygen)
|
||||
|
||||
add_subdirectory(src)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# ANABATIC_LIBRARIES - The path to where the Coriolis library files are.
|
||||
|
||||
|
||||
SET(ANABATIC_INCLUDE_PATH_DESCRIPTION "directory containing the Katabatic include files. E.g /usr/local/include/coriolis2 or /asim/coriolis/include/coriolis2")
|
||||
SET(ANABATIC_INCLUDE_PATH_DESCRIPTION "directory containing the Katabatic include files. E.g /usr/local/include/coriolis or /asim/coriolis/include/coriolis")
|
||||
|
||||
SET(ANABATIC_DIR_MESSAGE "Set the ANABATIC_INCLUDE_DIR cmake cache entry to the ${ANABATIC_INCLUDE_PATH_DESCRIPTION}")
|
||||
|
||||
|
@ -18,7 +18,7 @@ IF(UNIX)
|
|||
FIND_PATH(ANABATIC_INCLUDE_PATH NAMES anabatic/AnabaticEngine.h PATHS
|
||||
# Look in other places.
|
||||
${CORIOLIS_DIR_SEARCH}
|
||||
PATH_SUFFIXES include/coriolis2
|
||||
PATH_SUFFIXES include/coriolis
|
||||
# Help the user find it if we cannot.
|
||||
DOC "The ${ANABATIC_INCLUDE_PATH_DESCRIPTION}"
|
||||
)
|
||||
|
@ -26,7 +26,7 @@ IF(UNIX)
|
|||
FIND_LIBRARY(ANABATIC_LIBRARY_PATH
|
||||
NAMES anabatic
|
||||
PATHS ${CORIOLIS_DIR_SEARCH}
|
||||
PATH_SUFFIXES lib64 lib
|
||||
PATH_SUFFIXES lib${LIB_SUFFIX}
|
||||
# Help the user find it if we cannot.
|
||||
DOC "The ${ANABATIC_INCLUDE_PATH_DESCRIPTION}"
|
||||
)
|
||||
|
|
|
@ -20,21 +20,17 @@
|
|||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/Breakpoint.h"
|
||||
#include "hurricane/DataBase.h"
|
||||
#include "hurricane/RegularLayer.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "hurricane/NetExternalComponents.h"
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "hurricane/UpdateSession.h"
|
||||
#include "crlcore/RoutingGauge.h"
|
||||
#include "crlcore/Measures.h"
|
||||
#include "crlcore/Histogram.h"
|
||||
#include "anabatic/GCell.h"
|
||||
#include "anabatic/AutoContactTerminal.h"
|
||||
#include "anabatic/NetBuilderHybridVH.h"
|
||||
#include "anabatic/NetBuilderM2.h"
|
||||
#include "anabatic/NetBuilderHV.h"
|
||||
#include "anabatic/NetBuilderVH.h"
|
||||
|
@ -49,11 +45,11 @@ namespace {
|
|||
|
||||
class SortAcByXY {
|
||||
public:
|
||||
inline bool operator() ( AutoContactTerminal* contact1, AutoContactTerminal* contact2 ) const;
|
||||
inline bool operator() ( AutoContactTerminal* contact1, AutoContactTerminal* contact2 );
|
||||
};
|
||||
|
||||
|
||||
inline bool SortAcByXY::operator() ( AutoContactTerminal* contact1, AutoContactTerminal* contact2 ) const
|
||||
inline bool SortAcByXY::operator() ( AutoContactTerminal* contact1, AutoContactTerminal* contact2 )
|
||||
{
|
||||
DbU::Unit x1 = contact1->getX();
|
||||
DbU::Unit x2 = contact2->getX();
|
||||
|
@ -123,33 +119,6 @@ namespace {
|
|||
}
|
||||
|
||||
|
||||
class NonReducedItem {
|
||||
public:
|
||||
inline NonReducedItem ( AutoSegment* segment=NULL, uint32_t nonReduceds=0 );
|
||||
inline AutoSegment* segment () const;
|
||||
inline uint32_t nonReduceds () const;
|
||||
private:
|
||||
AutoSegment* _segment;
|
||||
uint32_t _nonReduceds;
|
||||
};
|
||||
|
||||
|
||||
inline NonReducedItem::NonReducedItem ( AutoSegment* segment, uint32_t nonReduceds )
|
||||
: _segment (segment)
|
||||
, _nonReduceds(nonReduceds)
|
||||
{ }
|
||||
|
||||
inline AutoSegment* NonReducedItem::segment () const { return _segment; }
|
||||
inline uint32_t NonReducedItem::nonReduceds () const { return _nonReduceds; }
|
||||
|
||||
bool operator< ( const NonReducedItem& lhs, const NonReducedItem& rhs )
|
||||
{
|
||||
int32_t deltaReduceds = (int32_t)lhs.nonReduceds() - (int32_t)rhs.nonReduceds();
|
||||
if (deltaReduceds > 0) return true; // Most connected first.
|
||||
if (deltaReduceds < 0) return false;
|
||||
return lhs.segment()->getId() < rhs.segment()->getId(); // Smallest Id first.
|
||||
}
|
||||
|
||||
} // Anonymous namespace.
|
||||
|
||||
|
||||
|
@ -164,13 +133,11 @@ namespace Anabatic {
|
|||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Breakpoint;
|
||||
using Hurricane::DataBase;
|
||||
using Hurricane::RegularLayer;
|
||||
using Hurricane::Component;
|
||||
using Hurricane::Horizontal;
|
||||
using Hurricane::Vertical;
|
||||
using Hurricane::NetRoutingExtension;
|
||||
using Hurricane::NetExternalComponents;
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::DebugSession;
|
||||
using Hurricane::UpdateSession;
|
||||
|
@ -178,7 +145,6 @@ namespace Anabatic {
|
|||
using CRL::RoutingLayerGauge;
|
||||
using CRL::addMeasure;
|
||||
using CRL::getMeasure;
|
||||
using CRL::Histogram;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -202,72 +168,28 @@ namespace Anabatic {
|
|||
|
||||
RawGCellsUnder::RawGCellsUnder ( const AnabaticEngine* engine, Segment* segment )
|
||||
{
|
||||
cdebug_log(112,1) << "RawGCellsUnder::RawGCellsUnder(Segment*): " << segment << endl;
|
||||
|
||||
commonCtor( engine, segment->getSourcePosition(), segment->getTargetPosition() );
|
||||
|
||||
cdebug_tabw(112,-1);
|
||||
}
|
||||
|
||||
|
||||
RawGCellsUnder::RawGCellsUnder ( const AnabaticEngine* engine, Point source, Point target )
|
||||
{
|
||||
cdebug_log(112,1) << "RawGCellsUnder::RawGCellsUnder(Point,Point): s:"
|
||||
<< source << " t:" << target << endl;
|
||||
|
||||
commonCtor( engine, source, target );
|
||||
|
||||
cdebug_tabw(112,-1);
|
||||
}
|
||||
|
||||
|
||||
void RawGCellsUnder::commonCtor ( const AnabaticEngine* engine, Point source, Point target )
|
||||
{
|
||||
cdebug_log(112,1) << "RawGCellsUnder::commontCtor(): s:" << source << " t:" << target << endl;
|
||||
cdebug_log(112,1) << "RawGCellsUnder::RawGCellsUnder(): " << segment << endl;
|
||||
|
||||
Box gcellsArea = engine->getCell()->getAbutmentBox();
|
||||
DbU::Unit axis = 0;
|
||||
Flags side = Flags::NoFlags;
|
||||
Point sourcePosition = segment->getSourcePosition();
|
||||
Point targetPosition = segment->getTargetPosition();
|
||||
|
||||
if (source.getY() == target.getY()) {
|
||||
side = Flags::EastSide;
|
||||
axis = source.getY();
|
||||
if (source.getX() > target.getX()) std::swap( source, target );
|
||||
}
|
||||
if (source.getX() == target.getX()) {
|
||||
side = Flags::NorthSide;
|
||||
axis = source.getX();
|
||||
if (source.getY() > target.getY()) std::swap( source, target );
|
||||
}
|
||||
|
||||
if (side == Flags::NoFlags) {
|
||||
cerr << Error( "RawGCellsUnder::commonCtor(): Points are neither horizontally nor vertically aligneds (ignored)."
|
||||
if ( (sourcePosition.getX() > gcellsArea.getXMax())
|
||||
or (sourcePosition.getY() > gcellsArea.getYMax())
|
||||
or (targetPosition.getX() <= gcellsArea.getXMin())
|
||||
or (targetPosition.getY() <= gcellsArea.getYMin()) ) {
|
||||
cerr << Error( "RawGCellsUnder::RawGCellsUnder(): %s is completly outside the GCells area (ignored)."
|
||||
, getString(segment).c_str()
|
||||
) << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
DebugSession::close();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( (source.getX() > gcellsArea.getXMax())
|
||||
or (source.getY() > gcellsArea.getYMax())
|
||||
or (target.getX() <= gcellsArea.getXMin())
|
||||
or (target.getY() <= gcellsArea.getYMin()) ) {
|
||||
cerr << Warning( "RawGCellsUnder::commonCtor(): Area is completly outside the GCells area (ignored).\n"
|
||||
" * GCells area: %s\n"
|
||||
" * Obstacle area: [%s %s %s %s]"
|
||||
, getString(gcellsArea).c_str()
|
||||
, DbU::getValueString(source.getX()).c_str()
|
||||
, DbU::getValueString(source.getY()).c_str()
|
||||
, DbU::getValueString(target.getX()).c_str()
|
||||
, DbU::getValueString(target.getY()).c_str()
|
||||
) << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
DbU::Unit xsource = std::max( source.getX(), gcellsArea.getXMin() );
|
||||
DbU::Unit ysource = std::max( source.getY(), gcellsArea.getYMin() );
|
||||
DbU::Unit xtarget = std::min( target.getX(), gcellsArea.getXMax() );
|
||||
DbU::Unit ytarget = std::min( target.getY(), gcellsArea.getYMax() );
|
||||
DbU::Unit xsource = std::max( sourcePosition.getX(), gcellsArea.getXMin() );
|
||||
DbU::Unit ysource = std::max( sourcePosition.getY(), gcellsArea.getYMin() );
|
||||
DbU::Unit xtarget = std::min( targetPosition.getX(), gcellsArea.getXMax() );
|
||||
DbU::Unit ytarget = std::min( targetPosition.getY(), gcellsArea.getYMax() );
|
||||
|
||||
if (xtarget == gcellsArea.getXMax()) --xtarget;
|
||||
if (ytarget == gcellsArea.getYMax()) --ytarget;
|
||||
|
@ -276,24 +198,47 @@ namespace Anabatic {
|
|||
GCell* gtarget = engine->getGCellUnder( xtarget, ytarget );
|
||||
|
||||
if (not gsource) {
|
||||
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): Source not under a GCell (ignored)."
|
||||
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): %s source not under a GCell (ignored)."
|
||||
, getString(segment).c_str()
|
||||
) << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
DebugSession::close();
|
||||
return;
|
||||
}
|
||||
if (not gtarget) {
|
||||
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): Target not under a GCell (ignored)."
|
||||
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): %s target not under a GCell (ignored)."
|
||||
, getString(segment).c_str()
|
||||
) << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
DebugSession::close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (gsource == gtarget) {
|
||||
_elements.push_back( Element(gsource,NULL) );
|
||||
cdebug_tabw(112,-1);
|
||||
DebugSession::close();
|
||||
return;
|
||||
}
|
||||
|
||||
Flags side = Flags::NoFlags;
|
||||
DbU::Unit axis = 0;
|
||||
Horizontal* horizontal = dynamic_cast<Horizontal*>( segment );
|
||||
if (horizontal) {
|
||||
side = Flags::EastSide;
|
||||
axis = horizontal->getY();
|
||||
|
||||
if (horizontal->getSourceX() > horizontal->getTargetX())
|
||||
std::swap( gsource, gtarget );
|
||||
} else {
|
||||
Vertical* vertical = dynamic_cast<Vertical*>( segment );
|
||||
side = Flags::NorthSide;
|
||||
axis = vertical->getX();
|
||||
|
||||
if (vertical->getSourceY() > vertical->getTargetY())
|
||||
std::swap( gsource, gtarget );
|
||||
}
|
||||
|
||||
cdebug_log(112,0) << "flags:" << side << " axis:" << DbU::getValueString(axis) << endl;
|
||||
|
||||
Edge* edge = gsource->getEdgeAt( side, axis );
|
||||
|
@ -314,28 +259,19 @@ namespace Anabatic {
|
|||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::NetData".
|
||||
|
||||
NetData::NetData ( Net* net, AnabaticEngine* anabatic )
|
||||
NetData::NetData ( Net* net )
|
||||
: _net (net)
|
||||
, _state (NetRoutingExtension::get(net))
|
||||
, _searchArea()
|
||||
, _rpCount (0)
|
||||
, _diodeCount(0)
|
||||
, _sparsity (0)
|
||||
, _flags ()
|
||||
, _noMoveUp ()
|
||||
{
|
||||
if (_state and _state->isMixedPreRoute()) return;
|
||||
|
||||
Cell* diodeCell = anabatic->getDiodeCell();
|
||||
for ( RoutingPad* rp : _net->getRoutingPads() ) {
|
||||
_searchArea.merge( rp->getBoundingBox() );
|
||||
++_rpCount;
|
||||
|
||||
if (diodeCell) {
|
||||
Plug* plug = dynamic_cast<Plug*>( rp->getPlugOccurrence().getEntity() );
|
||||
if (plug and (plug->getInstance()->getMasterCell() == diodeCell))
|
||||
++_diodeCount;
|
||||
}
|
||||
}
|
||||
_update();
|
||||
}
|
||||
|
@ -372,48 +308,29 @@ namespace Anabatic {
|
|||
, _viewer (NULL)
|
||||
, _flags (Flags::DestroyBaseContact)
|
||||
, _stamp (-1)
|
||||
, _routingMode (DigitalMode)
|
||||
, _densityMode (MaxDensity)
|
||||
, _autoSegmentLut ()
|
||||
, _autoContactLut ()
|
||||
, _edgeCapacitiesLut()
|
||||
, _blockageNet (cell->getNet("blockagenet"))
|
||||
, _diodeCell (NULL)
|
||||
{ }
|
||||
{
|
||||
_matrix.setCell( cell, _configuration->getSliceHeight() );
|
||||
Edge::unity = _configuration->getSliceHeight();
|
||||
|
||||
if (not _blockageNet) _blockageNet = Net::create( cell, "blockagenet" );
|
||||
}
|
||||
|
||||
|
||||
void AnabaticEngine::_postCreate ()
|
||||
{
|
||||
Super::_postCreate();
|
||||
|
||||
_configuration = _createConfiguration();
|
||||
setupNetBuilder();
|
||||
_matrix.setCell( getCell(), _configuration->getSliceHeight() );
|
||||
Edge::unity = _configuration->getSliceHeight();
|
||||
|
||||
if (not _blockageNet) {
|
||||
_blockageNet = Net::create( getCell(), "blockagenet" );
|
||||
_blockageNet->setType( Net::Type::BLOCKAGE );
|
||||
}
|
||||
|
||||
_diodeCell = DataBase::getDB()->getCell( _configuration->getDiodeName() );;
|
||||
if (not _diodeCell) {
|
||||
cerr << Warning( "AnabaticEngine::_postCreate() Unable to find \"%s\" diode cell."
|
||||
, _configuration->getDiodeName().c_str()
|
||||
) << endl;
|
||||
}
|
||||
|
||||
UpdateSession::open();
|
||||
GCell::create( this );
|
||||
UpdateSession::close();
|
||||
checkPlacement();
|
||||
}
|
||||
|
||||
|
||||
Configuration* AnabaticEngine::_createConfiguration ()
|
||||
{ return new Configuration(); }
|
||||
|
||||
|
||||
AnabaticEngine* AnabaticEngine::create ( Cell* cell )
|
||||
{
|
||||
if (not cell) throw Error( "AnabaticEngine::create(): NULL cell argument." );
|
||||
|
@ -457,7 +374,6 @@ namespace Anabatic {
|
|||
|
||||
void AnabaticEngine::_gutAnabatic ()
|
||||
{
|
||||
//DebugSession::open( 159, 160 );
|
||||
openSession();
|
||||
|
||||
_flags.reset( Flags::DestroyBaseContact|Flags::DestroyBaseSegment );
|
||||
|
@ -465,40 +381,19 @@ namespace Anabatic {
|
|||
if (_state == EngineDriving) {
|
||||
cdebug_log(145,1) << "Saving AutoContacts/AutoSegments." << endl;
|
||||
|
||||
vector<NonReducedItem> reduceds;
|
||||
size_t fixedSegments = 0;
|
||||
size_t sameLayerDoglegs = 0;
|
||||
size_t bloatedStraps = 0;
|
||||
for ( auto isegment : _autoSegmentLut ) {
|
||||
if (isegment.second->isFixed()) ++fixedSegments;
|
||||
if (isegment.second->canReduce( Flags::NullLength )) {
|
||||
//cerr << "push_back() " << (void*)isegment.second << ":" << isegment.second << endl;
|
||||
reduceds.push_back( NonReducedItem( isegment.second
|
||||
, isegment.second->getNonReduceds( Flags::NoFlags ) ));
|
||||
} else {
|
||||
if (isegment.second->reduceDoglegLayer()) ++sameLayerDoglegs;
|
||||
}
|
||||
//if (isegment.second->bloatStackedStrap()) ++bloatedStraps;
|
||||
}
|
||||
sort( reduceds.begin(), reduceds.end() );
|
||||
// cerr << "Reduced segment queue:" << endl;
|
||||
// for ( size_t i=0 ; i<reduceds.size() ; ++i ) {
|
||||
// cerr << "| " << setw(3) << i
|
||||
// << " " << reduceds[i].nonReduceds()
|
||||
// << " " << reduceds[i].segment() << endl;
|
||||
// }
|
||||
for ( auto& item : reduceds ) {
|
||||
item.segment()->reduce( Flags::NoFlags );
|
||||
if (item.segment()->reduceDoglegLayer()) ++sameLayerDoglegs;
|
||||
}
|
||||
|
||||
cmess1 << " o Driving Hurricane data-base." << endl;
|
||||
cmess1 << Dots::asSizet(" - Active AutoSegments" ,AutoSegment::getAllocateds()-fixedSegments) << endl;
|
||||
cmess1 << Dots::asSizet(" - Active AutoContacts" ,AutoContact::getAllocateds()-fixedSegments*2) << endl;
|
||||
cmess1 << Dots::asSizet(" - Active AutoSegments",AutoSegment::getAllocateds()-fixedSegments) << endl;
|
||||
cmess1 << Dots::asSizet(" - Active AutoContacts",AutoContact::getAllocateds()-fixedSegments*2) << endl;
|
||||
cmess1 << Dots::asSizet(" - AutoSegments" ,AutoSegment::getAllocateds()) << endl;
|
||||
cmess1 << Dots::asSizet(" - AutoContacts" ,AutoContact::getAllocateds()) << endl;
|
||||
cmess1 << Dots::asSizet(" - Same Layer doglegs" ,sameLayerDoglegs) << endl;
|
||||
cmess1 << Dots::asSizet(" - Bloated straps (< minArea)",bloatedStraps ) << endl;
|
||||
|
||||
//for ( Net* net : _cell->getNets() ) _saveNet( net );
|
||||
|
||||
|
@ -521,22 +416,7 @@ namespace Anabatic {
|
|||
_ovEdges.clear();
|
||||
}
|
||||
|
||||
exportExternalNets();
|
||||
Session::close();
|
||||
//DebugSession::close();
|
||||
}
|
||||
|
||||
|
||||
void AnabaticEngine::exportExternalNets ()
|
||||
{
|
||||
for ( Net* net : getCell()->getNets() ) {
|
||||
if (not net->isExternal()) continue;
|
||||
if (net->isSupply()) continue;
|
||||
|
||||
for ( Segment* segment : net->getSegments() ) {
|
||||
NetExternalComponents::setExternal( segment );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -544,10 +424,6 @@ namespace Anabatic {
|
|||
{ return _configuration; }
|
||||
|
||||
|
||||
const Configuration* AnabaticEngine::getConfiguration () const
|
||||
{ return _configuration; }
|
||||
|
||||
|
||||
Interval AnabaticEngine::getUSide ( Flags direction ) const
|
||||
{
|
||||
Interval side;
|
||||
|
@ -595,113 +471,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
bool AnabaticEngine::checkPlacement () const
|
||||
{
|
||||
bool valid = true;
|
||||
Box cellAb = getCell()->getAbutmentBox();
|
||||
|
||||
for ( Occurrence occurrence : getCell()->getTerminalNetlistInstanceOccurrences() ) {
|
||||
Instance* instance = static_cast<Instance*>(occurrence.getEntity());
|
||||
Cell* masterCell = instance->getMasterCell();
|
||||
string instanceName = occurrence.getCompactString();
|
||||
|
||||
instanceName.erase( 0, 1 );
|
||||
instanceName.erase( instanceName.size()-1 );
|
||||
|
||||
Box instanceAb = masterCell->getAbutmentBox();
|
||||
|
||||
Transformation instanceTransf = instance->getTransformation();
|
||||
occurrence.getPath().getTransformation().applyOn( instanceTransf );
|
||||
instanceTransf.applyOn( instanceAb );
|
||||
|
||||
if (not cellAb.contains(instanceAb)) {
|
||||
valid = false;
|
||||
cerr << Error( "AnabaticEngine::checkPlacement(): Instance %s is outside top cell abutment box, routing will be incomplete.\n"
|
||||
" (cell:%s vs instance:%s)"
|
||||
, instanceName.c_str()
|
||||
, getString(cellAb ).c_str()
|
||||
, getString(instanceAb).c_str()
|
||||
) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
RoutingGauge* rg = _configuration->getRoutingGauge();
|
||||
size_t errorCount = 0;
|
||||
ostringstream errors;
|
||||
errors << "AnabaticEngine::checkPlacement():\n";
|
||||
|
||||
for ( Net* net: getCell()->getNets() ) {
|
||||
for ( RoutingPad* rp : net->getRoutingPads() ) {
|
||||
Pin* pin = dynamic_cast<Pin*>( rp->getOccurrence().getEntity() );
|
||||
if (not pin) continue;
|
||||
|
||||
ostringstream pinError;
|
||||
|
||||
RoutingLayerGauge* lg = rg->getLayerGauge( pin->getLayer() );
|
||||
if (not lg) {
|
||||
pinError << " Layer not in the routing gauge, "
|
||||
<< "pin:" << pin->getLayer()->getName()
|
||||
<< "\n";
|
||||
valid = false;
|
||||
++errorCount;
|
||||
} else {
|
||||
Point pinCenter = rp->getCenter();
|
||||
if ( (pin->getAccessDirection() == Pin::AccessDirection::NORTH)
|
||||
or (pin->getAccessDirection() == Pin::AccessDirection::SOUTH) ) {
|
||||
if (not lg->isVertical()) {
|
||||
pinError << " Should be in vertical routing layer, "
|
||||
<< "pin:" << pin->getLayer()->getName()
|
||||
<< " vs gauge:" << lg->getLayer()->getName()
|
||||
<< "\n";
|
||||
valid = false;
|
||||
++errorCount;
|
||||
}
|
||||
if ((pinCenter.getX() - getCell()->getAbutmentBox().getXMin() - lg->getOffset())
|
||||
% lg->getPitch()) {
|
||||
pinError << " Misaligned, "
|
||||
<< "pin:" << DbU::getValueString(pinCenter.getX())
|
||||
<< " vs gauge, pitch:" << DbU::getValueString(lg->getPitch ())
|
||||
<< ", offset:" << DbU::getValueString(lg->getOffset())
|
||||
<< "\n";
|
||||
valid = false;
|
||||
++errorCount;
|
||||
}
|
||||
}
|
||||
|
||||
if ( (pin->getAccessDirection() == Pin::AccessDirection::EAST)
|
||||
or (pin->getAccessDirection() == Pin::AccessDirection::WEST) ) {
|
||||
if (not lg->isHorizontal()) {
|
||||
pinError << " Should be in horizontal routing layer, "
|
||||
<< "pin:" << pin->getLayer()->getName()
|
||||
<< " vs gauge:" << lg->getLayer()->getName()
|
||||
<< "\n";
|
||||
valid = false;
|
||||
++errorCount;
|
||||
}
|
||||
if ((pinCenter.getY() - getCell()->getAbutmentBox().getYMin() - lg->getOffset())
|
||||
% lg->getPitch()) {
|
||||
pinError << " Misaligned, "
|
||||
<< "pin:" << DbU::getValueString(pinCenter.getY())
|
||||
<< " vs gauge, pitch:" << DbU::getValueString(lg->getPitch ())
|
||||
<< ", offset:" << DbU::getValueString(lg->getOffset())
|
||||
<< "\n";
|
||||
valid = false;
|
||||
++errorCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (not pinError.str().empty()) {
|
||||
errors << "On " << pin << "\n" << pinError.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (errorCount) throw Error( errors.str() );
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
|
||||
void AnabaticEngine::openSession ()
|
||||
{ Session::_open(this); }
|
||||
|
||||
|
@ -720,18 +489,10 @@ namespace Anabatic {
|
|||
|
||||
void AnabaticEngine::setupNetDatas ()
|
||||
{
|
||||
Histogram netHistogram ( 0.0, 1.0, 1 );
|
||||
netHistogram.setTitle ( "RoutingPads", 0 );
|
||||
netHistogram.setColor ( "green" , 0 );
|
||||
netHistogram.setIndent( " " , 0 );
|
||||
|
||||
size_t oindex = _netOrdering.size();
|
||||
for ( Net* net : _cell->getNets() ) {
|
||||
if (_netDatas.find(net->getId()) != _netDatas.end()) continue;
|
||||
NetData* data = new NetData( net, this );
|
||||
_netOrdering.push_back( data );
|
||||
|
||||
netHistogram.addSample( (float)(data->getRpCount() - data->getDiodeRpCount()), 0 );
|
||||
_netOrdering.push_back( new NetData(net) );
|
||||
}
|
||||
|
||||
for ( ; oindex < _netOrdering.size() ; ++oindex ) {
|
||||
|
@ -740,9 +501,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
sort( _netOrdering.begin(), _netOrdering.end(), SparsityOrder() );
|
||||
|
||||
cmess2 << " o Nets Histogram." << endl;
|
||||
cmess2 << netHistogram.toString(0) << endl;
|
||||
}
|
||||
|
||||
|
||||
|
@ -809,7 +567,7 @@ namespace Anabatic {
|
|||
NetData* data = NULL;
|
||||
NetDatas::iterator idata = _netDatas.find( net->getId() );
|
||||
if (idata == _netDatas.end()) {
|
||||
data = new NetData( net, this );
|
||||
data = new NetData( net );
|
||||
_netDatas.insert( make_pair(net->getId(),data) );
|
||||
_netOrdering.push_back( data );
|
||||
// cerr << Bug( "AnabaticEngine::getNetData() - %s is missing in NetDatas table."
|
||||
|
@ -854,7 +612,7 @@ namespace Anabatic {
|
|||
if (horizontal) {
|
||||
splitted = Horizontal::create( breakContact
|
||||
, targetContact
|
||||
, _configuration->getGHorizontalLayer()
|
||||
, getConfiguration()->getGHorizontalLayer()
|
||||
, horizontal->getY()
|
||||
, DbU::fromLambda(2.0)
|
||||
);
|
||||
|
@ -863,7 +621,7 @@ namespace Anabatic {
|
|||
if (vertical) {
|
||||
splitted = Vertical::create( breakContact
|
||||
, targetContact
|
||||
, _configuration->getGVerticalLayer()
|
||||
, getConfiguration()->getGVerticalLayer()
|
||||
, vertical->getX()
|
||||
, DbU::fromLambda(2.0)
|
||||
);
|
||||
|
@ -871,9 +629,6 @@ namespace Anabatic {
|
|||
return breakContact;
|
||||
}
|
||||
|
||||
NetData* netData = getNetData( segment->getNet() );
|
||||
if (netData and netData->isNoMoveUp(segment))
|
||||
netData->setNoMoveUp( splitted );
|
||||
for ( ; i<gcells->size()-1 ; ++i ) gcells->edgeAt(i)->replace( segment, splitted );
|
||||
|
||||
return breakContact;
|
||||
|
@ -1096,17 +851,6 @@ namespace Anabatic {
|
|||
UpdateSession::open();
|
||||
for ( GCell* gcell : _gcells ) gcell->cleanupGlobal();
|
||||
UpdateSession::close();
|
||||
|
||||
for ( Net* net : getCell()->getNets() ) {
|
||||
for ( Component* component : net->getComponents() ) {
|
||||
if (_configuration->isGLayer(component->getLayer())) {
|
||||
cerr << Error( "AnabaticEngine::cleanupGlobal(): Remaining global routing,\n"
|
||||
" %s"
|
||||
, getString(component).c_str()
|
||||
) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1118,15 +862,13 @@ namespace Anabatic {
|
|||
if (_state > EngineGlobalLoaded)
|
||||
throw Error ("AnabaticEngine::loadGlobalRouting() : global routing already loaded.");
|
||||
|
||||
antennaProtect();
|
||||
|
||||
if (method == EngineLoadGrByNet ) { _loadGrByNet(); }
|
||||
else {
|
||||
throw Error( badMethod, "Anabatic::loadGlobalRouting()", method, getString(_cell).c_str() );
|
||||
}
|
||||
cleanupGlobal();
|
||||
|
||||
if (not _configuration->isTwoMetals()) relaxOverConstraineds();
|
||||
if (not getConfiguration()->isTwoMetals()) relaxOverConstraineds();
|
||||
|
||||
_state = EngineActive;
|
||||
}
|
||||
|
@ -1136,7 +878,7 @@ namespace Anabatic {
|
|||
{
|
||||
openSession();
|
||||
|
||||
//DbU::Unit pitch3 = Session::getPitch( 2 );
|
||||
DbU::Unit pitch3 = Session::getPitch( 2 );
|
||||
AutoSegment::IdSet constraineds;
|
||||
AutoSegment::IdSet processeds;
|
||||
|
||||
|
@ -1243,64 +985,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
void AnabaticEngine::setupNetBuilder ()
|
||||
{
|
||||
uint32_t gaugeKind = 4;
|
||||
if (NetBuilderHybridVH::getStyle() == getNetBuilderStyle()) gaugeKind = 0;
|
||||
else if (NetBuilderM2 ::getStyle() == getNetBuilderStyle()) gaugeKind = 1;
|
||||
else if (NetBuilderVH ::getStyle() == getNetBuilderStyle()) gaugeKind = 2;
|
||||
else if (NetBuilderHV ::getStyle() == getNetBuilderStyle()) gaugeKind = 3;
|
||||
|
||||
if (gaugeKind == 0) {
|
||||
if (not _configuration->isVH())
|
||||
throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"."
|
||||
, getString(_configuration->getRoutingGauge()->getName()).c_str()
|
||||
, getNetBuilderStyle().c_str() );
|
||||
if (getRoutingStyle() == StyleFlags::NoStyle) {
|
||||
_configuration->setRoutingStyle( StyleFlags::VH
|
||||
| StyleFlags::Channel
|
||||
| StyleFlags::Hybrid );
|
||||
}
|
||||
}
|
||||
else if (gaugeKind == 1) {
|
||||
if (getRoutingStyle() == StyleFlags::NoStyle) {
|
||||
_configuration->setRoutingStyle( StyleFlags::Channel );
|
||||
}
|
||||
}
|
||||
else if (gaugeKind == 2) {
|
||||
if (not _configuration->isVH())
|
||||
throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"."
|
||||
, getString(_configuration->getRoutingGauge()->getName()).c_str()
|
||||
, getNetBuilderStyle().c_str() );
|
||||
if (_configuration->getRoutingGauge()->getUsableLayers() < 3)
|
||||
throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"."
|
||||
, getString(_configuration->getRoutingGauge()->getName()).c_str()
|
||||
, getNetBuilderStyle().c_str() );
|
||||
if (getRoutingStyle() == StyleFlags::NoStyle) {
|
||||
_configuration->setRoutingStyle( StyleFlags::VH
|
||||
| StyleFlags::OTH );
|
||||
}
|
||||
}
|
||||
else if (gaugeKind == 3) {
|
||||
if (not _configuration->isHV())
|
||||
throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"."
|
||||
, getString(_configuration->getRoutingGauge()->getName()).c_str()
|
||||
, getNetBuilderStyle().c_str() );
|
||||
if (_configuration->getRoutingGauge()->getUsableLayers() < 3)
|
||||
throw Error( "AnabaticEngine::_loadGrByNet(): Incoherency between routing gauge \"%s\" and NetBuilder style \"%s\"."
|
||||
, getString(_configuration->getRoutingGauge()->getName()).c_str()
|
||||
, getNetBuilderStyle().c_str() );
|
||||
if (getRoutingStyle() == StyleFlags::NoStyle) {
|
||||
_configuration->setRoutingStyle( StyleFlags::HV
|
||||
| StyleFlags::OTH );
|
||||
}
|
||||
}
|
||||
if (gaugeKind == 4) {
|
||||
throw Error( "AnabaticEngine::_loadGrByNet(): Unsupported kind of routing auge style \"%s\"."
|
||||
, getNetBuilderStyle().c_str() );
|
||||
}
|
||||
}
|
||||
|
||||
void AnabaticEngine::_loadGrByNet ()
|
||||
{
|
||||
cmess1 << " o Building detailed routing from global. " << endl;
|
||||
|
@ -1310,30 +994,25 @@ namespace Anabatic {
|
|||
startMeasures();
|
||||
openSession();
|
||||
|
||||
uint32_t gaugeKind = 4;
|
||||
if (NetBuilderHybridVH::getStyle() == getNetBuilderStyle()) gaugeKind = 0;
|
||||
else if (NetBuilderM2 ::getStyle() == getNetBuilderStyle()) gaugeKind = 1;
|
||||
else if (NetBuilderVH ::getStyle() == getNetBuilderStyle()) gaugeKind = 2;
|
||||
else if (NetBuilderHV ::getStyle() == getNetBuilderStyle()) gaugeKind = 3;
|
||||
int gaugeKind = 3;
|
||||
if (getConfiguration()->isTwoMetals()) gaugeKind = 0;
|
||||
if (getConfiguration()->isHV ()) gaugeKind = 1;
|
||||
if (getConfiguration()->isVH ()) gaugeKind = 2;
|
||||
|
||||
if (gaugeKind < 4) {
|
||||
if (gaugeKind < 3) {
|
||||
for ( Net* net : getCell()->getNets() ) {
|
||||
if (NetRoutingExtension::isShortNet(net)) {
|
||||
//AutoSegment::setShortNetMode( true );
|
||||
++shortNets;
|
||||
}
|
||||
if (NetRoutingExtension::isManualDetailRoute(net))
|
||||
continue;
|
||||
if ( NetRoutingExtension::isManualGlobalRoute(net)
|
||||
or NetRoutingExtension::isAutomaticGlobalRoute(net)) {
|
||||
if (NetRoutingExtension::isAutomaticGlobalRoute(net)) {
|
||||
DebugSession::open( net, 145, 150 );
|
||||
AutoSegment::setAnalogMode( NetRoutingExtension::isAnalog(net) );
|
||||
|
||||
switch ( gaugeKind ) {
|
||||
case 0: NetBuilder::load<NetBuilderHybridVH>( this, net ); break;
|
||||
case 1: NetBuilder::load<NetBuilderM2> ( this, net ); break;
|
||||
case 2: NetBuilder::load<NetBuilderVH> ( this, net ); break;
|
||||
case 3: NetBuilder::load<NetBuilderHV> ( this, net ); break;
|
||||
case 0: NetBuilder::load<NetBuilderM2>( this, net ); break;
|
||||
case 1: NetBuilder::load<NetBuilderHV>( this, net ); break;
|
||||
case 2: NetBuilder::load<NetBuilderVH>( this, net ); break;
|
||||
}
|
||||
|
||||
Session::revalidate();
|
||||
|
@ -1353,10 +1032,15 @@ namespace Anabatic {
|
|||
|
||||
cmess2 << Dots::asSizet(" - Short nets",shortNets) << endl;
|
||||
|
||||
if (gaugeKind > 2) {
|
||||
throw Error( "AnabaticEngine::_loadGrByNet(): Unsupported kind of routing gauge \"%s\"."
|
||||
, getString(getConfiguration()->getRoutingGauge()->getName()).c_str() );
|
||||
}
|
||||
|
||||
printMeasures( "load" );
|
||||
|
||||
addMeasure<size_t>( "Globals", AutoSegment::getGlobalsCount() );
|
||||
addMeasure<size_t>( "Edges" , AutoSegment::getAllocateds() );
|
||||
addMeasure<size_t>( getCell(), "Globals", AutoSegment::getGlobalsCount() );
|
||||
addMeasure<size_t>( getCell(), "Edges" , AutoSegment::getAllocateds() );
|
||||
}
|
||||
|
||||
|
||||
|
@ -1492,7 +1176,7 @@ namespace Anabatic {
|
|||
set<const Layer*> connectedLayers;
|
||||
|
||||
forEach ( Segment*, segment, net->getSegments() ) {
|
||||
if (segment->getAnchoredLength()) {
|
||||
if (segment->getLength()) {
|
||||
if (net->isExternal()) {
|
||||
NetExternalComponents::setExternal( *segment );
|
||||
}
|
||||
|
@ -1683,7 +1367,7 @@ namespace Anabatic {
|
|||
|
||||
EdgeCapacity* AnabaticEngine::_createCapacity ( Flags flags, Interval span )
|
||||
{
|
||||
size_t depth = _configuration->getAllowedDepth();
|
||||
size_t depth = getConfiguration()->getAllowedDepth();
|
||||
EdgeCapacity* edgeCapacity = NULL;
|
||||
|
||||
flags &= Flags::EdgeCapacityMask;
|
||||
|
@ -1709,83 +1393,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
void AnabaticEngine::computeEdgeCapacities ( int maxHCap, int maxVCap, int termSatThreshold, int maxTermSat )
|
||||
{
|
||||
vector<RoutingPad*> rps;
|
||||
vector<GCell*> saturateds;
|
||||
const vector<NetData*>& netDatas = getNetOrdering();
|
||||
|
||||
for ( NetData* netData : netDatas ) {
|
||||
for ( Component* component : netData->getNet()->getComponents() ) {
|
||||
RoutingPad* rp = dynamic_cast<RoutingPad*>( component );
|
||||
if (rp) rps.push_back( rp );
|
||||
}
|
||||
}
|
||||
|
||||
UpdateSession::open();
|
||||
|
||||
for ( auto rp : rps ) {
|
||||
if (not _configuration->selectRpComponent(rp))
|
||||
cerr << Warning( "AnabaticEngine::computeEdgeCapacities(): %s has no components on grid.", getString(rp).c_str() ) << endl;
|
||||
|
||||
Point center = rp->getBoundingBox().getCenter();
|
||||
GCell* gcell = getGCellUnder( center );
|
||||
|
||||
if (not gcell) {
|
||||
cerr << Error( "AnabaticEngine::computeEdgeCapacities(): %s\n"
|
||||
" @%s of %s is not under any GCell.\n"
|
||||
" It will be ignored so the edge capacity estimate may be wrong."
|
||||
, getString(rp).c_str()
|
||||
, getString(center).c_str()
|
||||
, getString(rp->getNet()).c_str()
|
||||
) << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
gcell->incRpCount( 1 );
|
||||
if (gcell->getRpCount() == termSatThreshold) saturateds.push_back( gcell );
|
||||
}
|
||||
|
||||
for ( GCell* gcell : getGCells() ) {
|
||||
if (not gcell->isMatrix()) continue;
|
||||
|
||||
for ( Edge* edge : gcell->getEdges(Flags::EastSide|Flags::NorthSide) ) {
|
||||
GCell* opposite = edge->getOpposite( gcell );
|
||||
int maxReserved = maxHCap;
|
||||
int reserved = std::max( gcell->getRpCount(), opposite->getRpCount() );
|
||||
|
||||
if (edge->isVertical()) maxReserved = maxVCap;
|
||||
edge->reserveCapacity( std::min( maxReserved, reserved ) );
|
||||
}
|
||||
}
|
||||
|
||||
for ( GCell* gcell : saturateds ) {
|
||||
GCell* neighbor = gcell;
|
||||
for ( size_t i=0 ; i<2; ++i ) {
|
||||
Edge* edge = neighbor->getWestEdge();
|
||||
if (not edge) break;
|
||||
|
||||
if (edge->getReservedCapacity() < (uint32_t)maxTermSat)
|
||||
edge->reserveCapacity( maxTermSat - edge->getReservedCapacity() );
|
||||
neighbor = neighbor->getWest();
|
||||
}
|
||||
neighbor = gcell;
|
||||
for ( size_t i=0 ; i<2; ++i ) {
|
||||
Edge* edge = neighbor->getEastEdge();
|
||||
if (not edge) break;
|
||||
|
||||
if (edge->getReservedCapacity() < (uint32_t)maxTermSat)
|
||||
edge->reserveCapacity( maxTermSat - edge->getReservedCapacity() );
|
||||
neighbor = neighbor->getEast();
|
||||
}
|
||||
}
|
||||
|
||||
UpdateSession::close();
|
||||
|
||||
//Breakpoint::stop( 1, "Edge capacities computeds." );
|
||||
}
|
||||
|
||||
|
||||
void AnabaticEngine::_check ( Net* net ) const
|
||||
{
|
||||
cdebug_log(149,1) << "Checking " << net << endl;
|
||||
|
@ -1830,10 +1437,10 @@ namespace Anabatic {
|
|||
{
|
||||
Super::printMeasures();
|
||||
|
||||
if (not tag.empty()) {
|
||||
addMeasure<double>( tag+"T", getTimer().getCombTime () );
|
||||
addMeasure<size_t>( tag+"S", (getTimer().getMemorySize() >> 20) );
|
||||
}
|
||||
// if (not tag.empty()) {
|
||||
// addMeasure<double>( getCell(), tag+"T", getTimer().getCombTime () );
|
||||
// addMeasure<size_t>( getCell(), tag+"S", (getTimer().getMemorySize() >> 20) );
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -178,45 +178,23 @@ namespace Anabatic {
|
|||
AutoHorizontal* AutoContact::getHorizontal2 () const { return NULL; }
|
||||
AutoVertical* AutoContact::getVertical1 () const { return NULL; }
|
||||
AutoVertical* AutoContact::getVertical2 () const { return NULL; }
|
||||
bool AutoContact::isOnPin () const { return false; }
|
||||
|
||||
|
||||
void AutoContact::getDepthSpan ( size_t& minDepth, size_t& maxDepth ) const
|
||||
{
|
||||
cdebug_log(145,1) << "AutoContact::getDepthSpan() of " << this << endl;
|
||||
minDepth = (size_t)-1;
|
||||
maxDepth = 0;
|
||||
|
||||
Component* anchor = getAnchor ();
|
||||
if (anchor) {
|
||||
cdebug_log(145,0) << "* Anchor depth: "
|
||||
<< Session::getRoutingGauge()->getLayerDepth(anchor->getLayer())<< endl;
|
||||
minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) );
|
||||
maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) );
|
||||
}
|
||||
|
||||
for ( AutoSegment* segment : const_cast<AutoContact*>(this)->getAutoSegments() ) {
|
||||
cdebug_log(145,0) << "* segment depth: "
|
||||
<< Session::getRoutingGauge()->getLayerDepth(segment->getLayer())<< endl;
|
||||
minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) );
|
||||
maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
}
|
||||
|
||||
|
||||
void AutoContact::updateLayer ()
|
||||
{
|
||||
size_t minDepth = (size_t)-1;
|
||||
size_t maxDepth = 0;
|
||||
|
||||
getDepthSpan( minDepth, maxDepth );
|
||||
setLayerAndWidth( maxDepth-minDepth, minDepth );
|
||||
// if (minDepth == maxDepth)
|
||||
// setLayer( Session::getRoutingGauge()->getRoutingLayer(minDepth) );
|
||||
// else
|
||||
// setLayer( Session::getRoutingGauge()->getContactLayer(minDepth) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -234,17 +212,14 @@ namespace Anabatic {
|
|||
size_t depth = Session::getRoutingGauge()->getLayerDepth(segment->getLayer());
|
||||
DbU::Unit length;
|
||||
if (segment->isLocal()) {
|
||||
length = segment->getAnchoredLength();
|
||||
length = segment->getLength();
|
||||
lengths[depth] += length;
|
||||
|
||||
DbU::Unit sideLength = (segment->isHorizontal()) ? hSideLength : vSideLength;
|
||||
if ( not segment->isUnbound() and (abs(length) > sideLength) )
|
||||
cerr << Error( "AutoContact::getLength(): Suspicious length %s (> %s) of %s.\n"
|
||||
" (on: %s)"
|
||||
, DbU::getValueString(length).c_str()
|
||||
, DbU::getValueString(sideLength).c_str()
|
||||
, getString(segment).c_str()
|
||||
, getString(this).c_str()) << endl;
|
||||
cerr << Error("Suspicious length:%.2f of %s."
|
||||
,DbU::getValueString(length).c_str()
|
||||
,getString(segment).c_str()) << endl;
|
||||
} else {
|
||||
if (segment->isHorizontal()) {
|
||||
if (isSourceHook)
|
||||
|
@ -299,11 +274,11 @@ namespace Anabatic {
|
|||
|
||||
void AutoContact::invalidate ( Flags flags )
|
||||
{
|
||||
if (flags & Flags::Topology ) setFlags( CntInvalidatedCache );
|
||||
if (not isInvalidated()) {
|
||||
cdebug_log(145,1) << "AutoContact::invalidate() - " << this << endl;
|
||||
cdebug_log(145,0) << "flags:" << flags.asString(FlagsFunction) << endl;
|
||||
setFlags( CntInvalidated );
|
||||
if (flags & Flags::Topology ) setFlags( CntInvalidatedCache );
|
||||
Session::invalidate( this );
|
||||
|
||||
_invalidate( flags );
|
||||
|
@ -481,13 +456,12 @@ namespace Anabatic {
|
|||
|
||||
void AutoContact::setConstraintBox ( const Box& box )
|
||||
{
|
||||
cdebug_log(149,0) << "setConstraintBox() " << this << " " << getConstraintBox()
|
||||
<< " from:" << box << endl;
|
||||
setCBXMin ( box.getXMin() );
|
||||
setCBXMax ( box.getXMax() );
|
||||
setCBYMin ( box.getYMin() );
|
||||
setCBYMax ( box.getYMax() );
|
||||
cdebug_log(149,0) << "setConstraintBox() " << this << " " << getConstraintBox() << endl;
|
||||
cdebug_log(149,0) << "setConstraintBox() - " << this << " " << getConstraintBox()
|
||||
<< " from:" << box << endl;
|
||||
cdebug_log(149,0) << "* " << _gcell << endl;
|
||||
}
|
||||
|
||||
|
@ -580,25 +554,15 @@ namespace Anabatic {
|
|||
|
||||
void AutoContact::setLayerAndWidth ( size_t delta, size_t depth )
|
||||
{
|
||||
cdebug_log(145,1) << "AutoContact::setLayerAndWidth() " << this << endl;
|
||||
cdebug_log(145,0) << "delta:" << delta << " depth:" << depth << endl;
|
||||
|
||||
if (delta == 0) {
|
||||
setLayer( Session::getRoutingLayer(depth) );
|
||||
if (Session::getDirection(depth) & Flags::Horizontal) {
|
||||
setSizes( Session::getPWireWidth(depth)
|
||||
, Session::getWireWidth (depth) );
|
||||
} else {
|
||||
setSizes( Session::getWireWidth (depth)
|
||||
, Session::getPWireWidth(depth) );
|
||||
}
|
||||
, Session::getWireWidth (depth) );
|
||||
} else {
|
||||
setLayer( Session::getContactLayer(depth) );
|
||||
setSizes( Session::getViaWidth (depth)
|
||||
, Session::getViaWidth (depth) );
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include "hurricane/RoutingPad.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "hurricane/Pin.h"
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "crlcore/RoutingGauge.h"
|
||||
#include "anabatic/AutoContactTerminal.h"
|
||||
|
@ -48,7 +47,6 @@ namespace Anabatic {
|
|||
using Hurricane::Transformation;
|
||||
using Hurricane::Entity;
|
||||
using Hurricane::Occurrence;
|
||||
using Hurricane::Pin;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -131,13 +129,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
bool AutoContactTerminal::isOnPin () const
|
||||
{
|
||||
RoutingPad* rp = dynamic_cast<RoutingPad*>( getAnchor() );
|
||||
return (dynamic_cast<Pin*>(rp->getOccurrence().getEntity()) != NULL);
|
||||
}
|
||||
|
||||
|
||||
AutoSegment* AutoContactTerminal::getOpposite ( const AutoSegment* ) const
|
||||
{ return NULL; }
|
||||
|
||||
|
@ -203,7 +194,7 @@ namespace Anabatic {
|
|||
// SxLib bug: METAL1 terminal segments are 0.5 lambdas too shorts on
|
||||
// their extremities. Should modificate all the standard cells layout...
|
||||
// HARDCODED.
|
||||
if (getString(Session::getRoutingGauge()->getName()).substr(0,6) == "msxlib")
|
||||
if (Session::getRoutingGauge()->getName() == "msxlib")
|
||||
yborder -= DbU::fromLambda( 1.0 );
|
||||
else
|
||||
yborder -= DbU::fromLambda( 0.5 );
|
||||
|
@ -346,7 +337,7 @@ namespace Anabatic {
|
|||
void AutoContactTerminal::cacheDetach ( AutoSegment* segment )
|
||||
{
|
||||
if (_segment == segment) {
|
||||
//_segment->unsetFlags( AutoSegment::SegAxisSet );
|
||||
_segment->unsetFlags( AutoSegment::SegAxisSet );
|
||||
_segment = NULL;
|
||||
setFlags( CntInvalidatedCache );
|
||||
unsetFlags( CntDrag );
|
||||
|
@ -406,8 +397,8 @@ namespace Anabatic {
|
|||
if (horizontals[1] != NULL) ++count;
|
||||
if (verticals [0] != NULL) ++count;
|
||||
if (verticals [1] != NULL) ++count;
|
||||
if (count != 1) {
|
||||
showTopologyError( "Terminal has not *exactly* one segment." );
|
||||
if (count > 1) {
|
||||
showTopologyError( "Terminal has more than one segment." );
|
||||
}
|
||||
if (horizontals[0] != NULL ) {
|
||||
_segment = Session::lookup( horizontals[0] );
|
||||
|
@ -503,17 +494,11 @@ namespace Anabatic {
|
|||
AutoContact* opposite = _segment->getOppositeAnchor(this);
|
||||
AutoSegment* perpandicular = opposite->getPerpandicular( _segment );
|
||||
if (perpandicular) {
|
||||
cdebug_log(145,0) << "Draging V interval ["
|
||||
<< DbU::getValueString(getCBYMin()) << " "
|
||||
<< DbU::getValueString(getCBYMax()) << "]" << endl;
|
||||
DbU::Unit y = perpandicular->getAxis();
|
||||
y = std::min( y, getCBYMax() );
|
||||
y = std::max( y, getCBYMin() );
|
||||
Point onGrid = Session::getNearestGridPoint( Point(getX(),y), getConstraintBox() );
|
||||
setY( onGrid.getY() );
|
||||
cdebug_log(145,0) << "Draging to Y @" << DbU::getValueString(y)
|
||||
<< " pitched:" << DbU::getValueString(onGrid.getY())
|
||||
<< " " << getConstraintBox() << endl;
|
||||
setY( y );
|
||||
cdebug_log(145,0) << "Draging to Y @" << DbU::getValueString(y) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -562,11 +547,11 @@ namespace Anabatic {
|
|||
if (delta > 1) {
|
||||
//_segment = _segment->makeDogleg( this );
|
||||
_segment->makeDogleg( this );
|
||||
cdebug_log(145,0) << "Update seg: " << _segment << endl;
|
||||
delta = abssub( anchorDepth, rg->getLayerDepth( _segment->getLayer() ) );
|
||||
cdebug_log(145,0) << "Delta: " << delta << " Update seg: " << _segment << endl;
|
||||
}
|
||||
if (delta == 0) setLayerAndWidth( delta, anchorDepth );
|
||||
if (delta == 1) setLayerAndWidth( delta, std::min(anchorDepth,segmentDepth) );
|
||||
else if (delta == 0) setLayerAndWidth( delta, anchorDepth );
|
||||
else if (delta == 1) setLayerAndWidth( delta, std::min(anchorDepth,segmentDepth) );
|
||||
}
|
||||
_segment->invalidate( this );
|
||||
|
||||
|
|
|
@ -88,17 +88,8 @@ namespace Anabatic {
|
|||
|
||||
AutoSegment* AutoContactTurn::getPerpandicular ( const AutoSegment* reference ) const
|
||||
{
|
||||
cdebug_log(149,0) << _getTypeName() << "::getPerpandicular() " << this
|
||||
<< " to:" << reference << endl;
|
||||
cdebug_log(149,0) << "| _horizontal1:" << _horizontal1 << endl;
|
||||
cdebug_log(149,0) << "| _vertical1 :" << _vertical1 << endl;
|
||||
|
||||
if (reference == _horizontal1) return _vertical1;
|
||||
if (reference == _vertical1 ) return _horizontal1;
|
||||
|
||||
cdebug_log(149,0) << _getTypeName() << "::getPerpandicular() " << this
|
||||
<< " to:" << reference << " failed." << endl;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -126,9 +117,6 @@ namespace Anabatic {
|
|||
|
||||
void AutoContactTurn::cacheDetach ( AutoSegment* segment )
|
||||
{
|
||||
cdebug_log(149,0) << _getTypeName() << "::cacheDetach() " << this
|
||||
<< " from:" << segment << endl;
|
||||
|
||||
if (segment == _horizontal1) _horizontal1 = NULL;
|
||||
else if (segment == _vertical1) _vertical1 = NULL;
|
||||
else return;
|
||||
|
@ -139,9 +127,6 @@ namespace Anabatic {
|
|||
|
||||
void AutoContactTurn::cacheAttach ( AutoSegment* segment )
|
||||
{
|
||||
cdebug_log(149,0) << _getTypeName() << "::cacheAttach() " << this
|
||||
<< " to:" << segment << endl;
|
||||
|
||||
if (segment->getDirection() == Flags::Horizontal) {
|
||||
if (_horizontal1) {
|
||||
cerr << Bug( "%s::cacheAttach() On %s,\n"
|
||||
|
@ -254,7 +239,7 @@ namespace Anabatic {
|
|||
RoutingGauge* rg = Session::getRoutingGauge();
|
||||
size_t depthH1 = rg->getLayerDepth( getHorizontal1()->getLayer() );
|
||||
size_t depthV1 = rg->getLayerDepth( getVertical1 ()->getLayer() );
|
||||
size_t depthContact = (depthH1 <= depthV1) ? depthH1 : depthH1-1;
|
||||
size_t depthContact = (depthH1 < depthV1) ? depthH1 : depthH1-1;
|
||||
size_t delta = abssub ( depthH1, depthV1 );
|
||||
|
||||
unsetFlags( CntWeakTerminal );
|
||||
|
@ -262,10 +247,8 @@ namespace Anabatic {
|
|||
showTopologyError( "Sheared Turn, layer delta exceed 3." );
|
||||
setFlags( CntBadTopology );
|
||||
} else {
|
||||
if (delta > 1) {
|
||||
bool updateH1 = (_horizontal1->isInvalidatedLayer() and not _horizontal1->isNonPref())
|
||||
or _vertical1->isNonPref();
|
||||
if (updateH1) {
|
||||
if (delta == 3) {
|
||||
if (_horizontal1->isInvalidatedLayer()) {
|
||||
//_horizontal1 = static_cast<AutoHorizontal*>( _horizontal1->makeDogleg(this) );
|
||||
_horizontal1->makeDogleg(this);
|
||||
cdebug_log(145,0) << "Update h1: " << _horizontal1 << endl;
|
||||
|
@ -276,7 +259,7 @@ namespace Anabatic {
|
|||
}
|
||||
depthH1 = rg->getLayerDepth( _horizontal1->getLayer() );
|
||||
depthV1 = rg->getLayerDepth( _vertical1->getLayer() );
|
||||
depthContact = (depthH1 <= depthV1) ? depthH1 : depthH1-1;
|
||||
depthContact = (depthH1 < depthV1) ? depthH1 : depthH1-1;
|
||||
delta = abssub ( depthH1, depthV1 );
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
#include <algorithm>
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/DebugSession.h"
|
||||
#include "hurricane/ViaLayer.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
|
@ -34,10 +33,8 @@ namespace Anabatic {
|
|||
|
||||
using std::min;
|
||||
using std::max;
|
||||
using std::abs;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::DebugSession;
|
||||
using Hurricane::ViaLayer;
|
||||
using Hurricane::RoutingPad;
|
||||
|
@ -50,11 +47,13 @@ namespace Anabatic {
|
|||
Segment* AutoHorizontal::base () { return _horizontal; }
|
||||
Segment* AutoHorizontal::base () const { return _horizontal; }
|
||||
Horizontal* AutoHorizontal::getHorizontal () { return _horizontal; }
|
||||
DbU::Unit AutoHorizontal::getSourceU () const { return _horizontal->getSource()->getX(); }
|
||||
DbU::Unit AutoHorizontal::getTargetU () const { return _horizontal->getTarget()->getX(); }
|
||||
DbU::Unit AutoHorizontal::getSourceU () const { return _horizontal->getSourceX(); }
|
||||
DbU::Unit AutoHorizontal::getTargetU () const { return _horizontal->getTargetX(); }
|
||||
DbU::Unit AutoHorizontal::getDuSource () const { return _horizontal->getDxSource(); }
|
||||
DbU::Unit AutoHorizontal::getDuTarget () const { return _horizontal->getDxTarget(); }
|
||||
Interval AutoHorizontal::getSpanU () const { return Interval(_horizontal->getSourceX(),_horizontal->getTargetX()); }
|
||||
void AutoHorizontal::setDuSource ( DbU::Unit du ) { _horizontal->setDxSource(du); }
|
||||
void AutoHorizontal::setDuTarget ( DbU::Unit du ) { _horizontal->setDxTarget(du); }
|
||||
string AutoHorizontal::_getTypeName () const { return "AutoHorizontal"; }
|
||||
|
||||
|
||||
|
@ -94,14 +93,6 @@ namespace Anabatic {
|
|||
mergeNativeMax( gcell->getConstraintYMax() );
|
||||
}
|
||||
}
|
||||
|
||||
// if (getId() == 1518590) {
|
||||
// cerr << "AutoHorizontal::_postCreate(): " << this << endl;
|
||||
// cerr << "| Source contact:" << source << endl;
|
||||
// cerr << "| Source GCell: " << getGCell() << endl;
|
||||
// cerr << "| Target contact:" << target << endl;
|
||||
// cerr << "| Target GCell: " << target->getGCell() << endl;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
@ -131,30 +122,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
void AutoHorizontal::setDuSource ( DbU::Unit du )
|
||||
{
|
||||
_horizontal->setDxSource(du);
|
||||
if (abs(du) > getPitch())
|
||||
cerr << Warning( "AutoHorizontal::setDuSource(): Suspiciously big du=%s (should not exceed routing pitch %s)\n"
|
||||
" On %s"
|
||||
, DbU::getValueString(du).c_str()
|
||||
, DbU::getValueString(getPitch()).c_str()
|
||||
, getString(this).c_str() ) << endl;
|
||||
}
|
||||
|
||||
|
||||
void AutoHorizontal::setDuTarget ( DbU::Unit du )
|
||||
{
|
||||
_horizontal->setDxTarget(du);
|
||||
if (abs(du) > getPitch())
|
||||
cerr << Warning( "AutoHorizontal::setDuTarget(): Suspiciously big du=%s (should not exceed routing pitch %s)\n"
|
||||
" On %s"
|
||||
, DbU::getValueString(du).c_str()
|
||||
, DbU::getValueString(getPitch()).c_str()
|
||||
, getString(this).c_str() ) << endl;
|
||||
}
|
||||
|
||||
|
||||
Interval AutoHorizontal::getSourceConstraints ( Flags flags ) const
|
||||
{
|
||||
if (flags & Flags::NativeConstraints) {
|
||||
|
@ -257,7 +224,6 @@ namespace Anabatic {
|
|||
gcell = gcell->getEast( yprobe );
|
||||
if (not gcell) {
|
||||
success = false;
|
||||
if (not isCreated()) {
|
||||
cerr << Error( "AutoHorizontal::getGCells() : NULL GCell under %s\n"
|
||||
" begin:%s\n"
|
||||
" end: %s"
|
||||
|
@ -265,7 +231,6 @@ namespace Anabatic {
|
|||
, getString(getAutoSource()->getGCell()).c_str()
|
||||
, getString(getAutoTarget()->getGCell()).c_str()
|
||||
) << endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -280,35 +245,24 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_tabw(149,1);
|
||||
|
||||
AutoContact* source = getAutoSource();
|
||||
AutoContact* target = getAutoTarget();
|
||||
if (source->isOnPin() or target->isOnPin()) { cdebug_tabw(149,-1); return false; }
|
||||
|
||||
Interval sourceSide = source->getGCell()->getSide( Flags::Vertical );
|
||||
Interval targetSide = target->getGCell()->getSide( Flags::Vertical );
|
||||
Interval sourceConstraints = Interval(source->getCBYMin(),source->getCBYMax());
|
||||
Interval targetConstraints = Interval(target->getCBYMin(),target->getCBYMax());
|
||||
bool sourceGoStraight = source->getGCell()->isGoStraight();
|
||||
bool targetGoStraight = target->getGCell()->isGoStraight();
|
||||
Interval sourceSide = getAutoSource()->getGCell()->getSide( Flags::Vertical );
|
||||
Interval targetSide = getAutoTarget()->getGCell()->getSide( Flags::Vertical );
|
||||
Interval sourceConstraints = Interval(getAutoSource()->getCBYMin(),getAutoSource()->getCBYMax());
|
||||
Interval targetConstraints = Interval(getAutoTarget()->getCBYMin(),getAutoTarget()->getCBYMax());
|
||||
|
||||
// Expand by a tiny amount for the "contains" to work for sure.
|
||||
sourceConstraints.inflate( 1 );
|
||||
targetConstraints.inflate( 1 );
|
||||
|
||||
cdebug_log(149,0) << "source " << source << endl;
|
||||
cdebug_log(149,0) << "source " << getAutoSource() << endl;
|
||||
cdebug_log(149,0) << "source constraints: " << sourceConstraints
|
||||
<< " " << DbU::getValueString(sourceConstraints.getSize()) << endl;
|
||||
cdebug_log(149,0) << "target " << target << endl;
|
||||
cdebug_log(149,0) << "target " << getAutoTarget() << endl;
|
||||
cdebug_log(149,0) << "target constraints: " << targetConstraints
|
||||
<< " " << DbU::getValueString(targetConstraints.getSize()) << endl;
|
||||
|
||||
if (not sourceGoStraight and not sourceConstraints.contains(sourceSide)) { cdebug_tabw(149,-1); return true; }
|
||||
if (not targetGoStraight and not targetConstraints.contains(targetSide)) { cdebug_tabw(149,-1); return true; }
|
||||
|
||||
if (not isUnbreakable()) {
|
||||
if (source->isTurn() and (source->getPerpandicular(this)->getLayer() == getLayer())) { cdebug_tabw(149,-1); return true; }
|
||||
if (target->isTurn() and (target->getPerpandicular(this)->getLayer() == getLayer())) { cdebug_tabw(149,-1); return true; }
|
||||
}
|
||||
if (not sourceConstraints.contains(sourceSide)) { cdebug_tabw(149,-1); return true; }
|
||||
if (not targetConstraints.contains(targetSide)) { cdebug_tabw(149,-1); return true; }
|
||||
|
||||
cdebug_tabw(149,-1);
|
||||
return false;
|
||||
|
@ -327,49 +281,27 @@ namespace Anabatic {
|
|||
bool success = false;
|
||||
bool isMetal2Source = false;
|
||||
bool isMetal2Target = false;
|
||||
bool isNonPrefSource = false;
|
||||
bool isNonPrefTarget = false;
|
||||
DbU::Unit height = 0;
|
||||
AutoContact* source = getAutoSource();
|
||||
AutoContact* target = getAutoTarget();
|
||||
bool slackenSource = false;
|
||||
bool slackenTarget = false;
|
||||
|
||||
|
||||
if (source->isTerminal()) {
|
||||
height = (static_cast<RoutingPad*>(source->getAnchor()))->getBoundingBox().getHeight();
|
||||
isMetal2Source = (source->getLayer() == metal2);
|
||||
slackenSource = true;
|
||||
}
|
||||
if (target->isTerminal()) {
|
||||
height = std::min( height, (static_cast<RoutingPad*>(target->getAnchor()))->getBoundingBox().getHeight() );
|
||||
isMetal2Target = (target->getLayer() == metal2);
|
||||
slackenTarget = true;
|
||||
}
|
||||
if (source->isTurn() and (source->getPerpandicular(this)->getLayer() == getLayer())) {
|
||||
isNonPrefSource = true;
|
||||
slackenSource = true;
|
||||
}
|
||||
|
||||
cdebug_log(149,0) << "target:" << target << endl;
|
||||
cdebug_log(149,0) << "target->getPerpandicular(this):" << target->getPerpandicular(this) << endl;
|
||||
if (target->isTurn() and (target->getPerpandicular(this)->getLayer() == getLayer())) {
|
||||
isNonPrefTarget = true;
|
||||
slackenTarget = true;
|
||||
if (height >= 4*getPitch()) {
|
||||
if (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < 5*getPitch()))
|
||||
return false;
|
||||
}
|
||||
|
||||
cdebug_tabw(149,1);
|
||||
cdebug_log(149,0) << "_flags:" << (_flags & (SegGlobal|SegWeakGlobal)) << endl;
|
||||
cdebug_log(149,0) << "test:" << (getAnchoredLength() < 5*getPitch()) << endl;
|
||||
cdebug_log(149,0) << "length:" << DbU::getValueString(getAnchoredLength()) << endl;
|
||||
|
||||
if (height >= 4*getPitch()) {
|
||||
if (not (_flags & (SegGlobal|SegWeakGlobal)) and (getAnchoredLength() < 5*getPitch())) {
|
||||
cdebug_log(149,0) << "Too short terminal segment to slacken." << endl;
|
||||
cdebug_tabw(149,-1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
cdebug_log(149,0) << "test:" << (getLength() < 5*getPitch()) << endl;
|
||||
cdebug_log(149,0) << "length:" << DbU::getValueString(getLength()) << endl;
|
||||
|
||||
int lowSlack = (flags & Flags::HalfSlacken) ? 3 : 10;
|
||||
bool sourceSlackened = false;
|
||||
|
@ -378,7 +310,7 @@ namespace Anabatic {
|
|||
DbU::Unit targetPosition = getTargetPosition();
|
||||
AutoSegment* parallel = this;
|
||||
|
||||
if (slackenSource) {
|
||||
if (source->isTerminal()) {
|
||||
Interval perpandConstraints = getAutoTarget()->getUConstraints(Flags::Horizontal);
|
||||
Interval constraints = source->getUConstraints (Flags::Vertical|Flags::NoGCellShrink);
|
||||
Interval nativeConstraints = source->getNativeUConstraints(Flags::Vertical|Flags::NoGCellShrink);
|
||||
|
@ -390,7 +322,7 @@ namespace Anabatic {
|
|||
<< " native slack:" << nativeSlack << endl;
|
||||
cdebug_log(149,0) << "Perpand constraints on target: " << perpandConstraints << endl;
|
||||
// Ugly: GCell's track number is hardwired.
|
||||
if (isNonPrefSource or (nativeSlack < lowSlack) or (nativeSlack - slack < 3)) {
|
||||
if ((nativeSlack < lowSlack) or (nativeSlack - slack < 3)) {
|
||||
cdebug_log(149,0) << "Slackening from Source: " << source << endl;
|
||||
_makeDogleg( source->getGCell(), Flags::NoFlags );
|
||||
sourceSlackened = true;
|
||||
|
@ -418,7 +350,7 @@ namespace Anabatic {
|
|||
|
||||
if (parallel) target = parallel->getAutoTarget();
|
||||
|
||||
if (slackenTarget) {
|
||||
if (target->isTerminal()) {
|
||||
Interval constraints = target->getUConstraints (Flags::Vertical|Flags::NoGCellShrink);
|
||||
Interval nativeConstraints = target->getNativeUConstraints(Flags::Vertical|Flags::NoGCellShrink);
|
||||
int slack = constraints.getSize() / getPitch();
|
||||
|
@ -428,7 +360,7 @@ namespace Anabatic {
|
|||
cdebug_log(149,0) << "Target constraint: " << constraints
|
||||
<< " slack:" << slack
|
||||
<< " native slack:" << nativeSlack << endl;
|
||||
if (isNonPrefTarget or (nativeSlack < lowSlack) or (nativeSlack - slack < 3)) {
|
||||
if ((nativeSlack < lowSlack) or (nativeSlack - slack < 3)) {
|
||||
cdebug_log(149,0) << "Slackening from Target: " << target << endl;
|
||||
parallel->_makeDogleg( target->getGCell(), Flags::NoFlags );
|
||||
targetSlackened = true;
|
||||
|
@ -438,15 +370,7 @@ namespace Anabatic {
|
|||
|
||||
const vector<AutoSegment*>& doglegs = Session::getDoglegs();
|
||||
if (targetSlackened and (doglegs.size() >= 2)) {
|
||||
GCell* targetGCell = target->getGCell();
|
||||
Box constraintBox = target->getConstraintBox();
|
||||
cdebug_log(149,0) << "slacken from Target @" << DbU::getValueString(targetPosition) << endl;
|
||||
|
||||
if (targetPosition >= targetGCell->getXMax()) {
|
||||
cdebug_log(149,0) << "On the rigthmost track, adjust of one P-pitch to the left." << endl;
|
||||
targetPosition -= getPPitch();
|
||||
constraintBox.inflate( getPPitch(), 0, 0, 0 );
|
||||
}
|
||||
cdebug_log(149,0) << "AutoHorizontal::_slacken(): Target @" << DbU::getValueString(targetPosition) << endl;
|
||||
doglegs[doglegs.size()-2]->setAxis( targetPosition );
|
||||
success = true;
|
||||
|
||||
|
@ -454,7 +378,7 @@ namespace Anabatic {
|
|||
cdebug_log(149,0) << "Fixing on target terminal contact: "
|
||||
<< doglegs[doglegs.size()-2]->getAutoTarget() << endl;
|
||||
//doglegs[doglegs.size()-2]->getAutoTarget()->setFlags( CntFixed );
|
||||
doglegs[doglegs.size()-2]->getAutoTarget()->setConstraintBox( constraintBox );
|
||||
doglegs[doglegs.size()-2]->getAutoTarget()->setConstraintBox( target->getConstraintBox() );
|
||||
doglegs[doglegs.size()-2]->getAutoTarget()->setFlags( CntUserNativeConstraints );
|
||||
}
|
||||
}
|
||||
|
@ -511,10 +435,9 @@ namespace Anabatic {
|
|||
|
||||
void AutoHorizontal::updateOrient ()
|
||||
{
|
||||
if (_horizontal->getTarget()->getX() < _horizontal->getSource()->getX()) {
|
||||
cdebug_log(149,1) << "updateOrient() " << this << " (before S/T swap)" << endl;
|
||||
if (_horizontal->getTargetX() < _horizontal->getSourceX()) {
|
||||
cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl;
|
||||
_horizontal->invert();
|
||||
cdebug_log(149,0) << "updateOrient() " << this << " (after S/T swap)" << endl;
|
||||
|
||||
uint64_t spinFlags = _flags & SegDepthSpin;
|
||||
unsetFlags( SegDepthSpin );
|
||||
|
@ -532,15 +455,14 @@ namespace Anabatic {
|
|||
unsetFlags( SegStrongTerminal );
|
||||
if (terminalFlags & SegSourceTerminal) setFlags( SegTargetTerminal );
|
||||
if (terminalFlags & SegTargetTerminal) setFlags( SegSourceTerminal );
|
||||
cdebug_tabw(149,-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AutoHorizontal::updatePositions ()
|
||||
{
|
||||
_sourcePosition = getSourceU() - getExtensionCap(Flags::Source);
|
||||
_targetPosition = getTargetU() + getExtensionCap(Flags::Target);
|
||||
_sourcePosition = _horizontal->getSourceX() - getExtensionCap(Flags::Source);
|
||||
_targetPosition = _horizontal->getTargetX() + getExtensionCap(Flags::Target);
|
||||
}
|
||||
|
||||
|
||||
|
@ -560,8 +482,8 @@ namespace Anabatic {
|
|||
bool AutoHorizontal::checkPositions () const
|
||||
{
|
||||
bool coherency = true;
|
||||
DbU::Unit sourcePosition = _horizontal->getSource()->getX() - getExtensionCap(Flags::Source);
|
||||
DbU::Unit targetPosition = _horizontal->getTarget()->getX() + getExtensionCap(Flags::Target);
|
||||
DbU::Unit sourcePosition = _horizontal->getSourceX() - getExtensionCap(Flags::Source);
|
||||
DbU::Unit targetPosition = _horizontal->getTargetX() + getExtensionCap(Flags::Target);
|
||||
|
||||
if ( _sourcePosition != sourcePosition ) {
|
||||
cerr << "extensionCap: " << DbU::getValueString(getExtensionCap(Flags::Source)) << endl;
|
||||
|
@ -875,7 +797,7 @@ namespace Anabatic {
|
|||
bool upLayer = true;
|
||||
|
||||
if (Session::getRoutingGauge()->isTwoMetals()) {
|
||||
upLayer = (not Session::getRoutingGauge()->isVH());
|
||||
upLayer = (depth == 0);
|
||||
} else if (Session::getRoutingGauge()->isVH()) {
|
||||
upLayer = (depth < 2);
|
||||
} else {
|
||||
|
@ -884,6 +806,7 @@ namespace Anabatic {
|
|||
|
||||
size_t doglegDepth = depth + ((upLayer)?1:-1);
|
||||
Layer* contactLayer = Session::getRoutingGauge()->getContactLayer( depth + ((upLayer)?0:-1) );
|
||||
const Layer* doglegLayer = Session::getRoutingGauge()->getRoutingLayer( doglegDepth );
|
||||
|
||||
Session::dogleg( this );
|
||||
targetDetach();
|
||||
|
@ -908,56 +831,31 @@ namespace Anabatic {
|
|||
segment2->setFlags( (isSlackened()?SegSlackened:0) );
|
||||
Session::dogleg( segment2 );
|
||||
|
||||
if (autoSource->isTerminal() and autoTarget->isTerminal()) {
|
||||
dlContact1->setFlags ( CntWeakTerminal );
|
||||
dlContact2->setFlags ( CntWeakTerminal );
|
||||
|
||||
if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget );
|
||||
if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource );
|
||||
} else if (autoSource->isTerminal()) {
|
||||
if (autoSource->isTerminal()) {
|
||||
segment1->setFlags( SegWeakTerminal1 );
|
||||
segment2->setFlags( SegWeakTerminal1 );
|
||||
autoTarget->unsetFlags( CntWeakTerminal );
|
||||
dlContact1->setFlags ( CntWeakTerminal );
|
||||
if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget );
|
||||
if (autoTarget->getGCell() == doglegGCell)
|
||||
dlContact1->migrateConstraintBox( autoTarget );
|
||||
} else if (autoTarget->isTerminal()) {
|
||||
unsetFlags( SegTargetTerminal );
|
||||
setFlags( SegWeakTerminal1 );
|
||||
segment1->setFlags( SegWeakTerminal1 );
|
||||
segment2->setFlags( SegTargetTerminal );
|
||||
autoSource->unsetFlags( CntWeakTerminal );
|
||||
dlContact2->setFlags ( CntWeakTerminal );
|
||||
if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource );
|
||||
if (autoSource->getGCell() == doglegGCell)
|
||||
dlContact2->migrateConstraintBox( autoSource );
|
||||
} else if (isWeakTerminal()) {
|
||||
segment1->setFlags( SegWeakTerminal1 );
|
||||
segment2->setFlags( SegWeakTerminal1 );
|
||||
}
|
||||
|
||||
// if (autoSource->isTerminal()) {
|
||||
// segment1->setFlags( SegWeakTerminal1 );
|
||||
// segment2->setFlags( SegWeakTerminal1 );
|
||||
// autoTarget->unsetFlags( CntWeakTerminal );
|
||||
// dlContact1->setFlags ( CntWeakTerminal );
|
||||
// if (autoTarget->getGCell() == doglegGCell)
|
||||
// dlContact1->migrateConstraintBox( autoTarget );
|
||||
// } else if (autoTarget->isTerminal()) {
|
||||
// unsetFlags( SegTargetTerminal );
|
||||
// setFlags( SegWeakTerminal1 );
|
||||
// segment1->setFlags( SegWeakTerminal1 );
|
||||
// segment2->setFlags( SegTargetTerminal );
|
||||
// autoSource->unsetFlags( CntWeakTerminal );
|
||||
// dlContact2->setFlags ( CntWeakTerminal );
|
||||
// if (autoSource->getGCell() == doglegGCell)
|
||||
// dlContact2->migrateConstraintBox( autoSource );
|
||||
// } else if (isWeakTerminal()) {
|
||||
// segment1->setFlags( SegWeakTerminal1 );
|
||||
// segment2->setFlags( SegWeakTerminal1 );
|
||||
// }
|
||||
|
||||
if (isAnalog()) {
|
||||
segment1->setFlags( SegAnalog );
|
||||
segment2->setFlags( SegAnalog );
|
||||
}
|
||||
if (isNoMoveUp()) {
|
||||
segment1->setFlags( SegNoMoveUp );
|
||||
segment2->setFlags( SegNoMoveUp );
|
||||
}
|
||||
|
||||
cdebug_log(149,0) << "Session::dogleg[x+1] perpand: " << segment1 << endl;
|
||||
cdebug_log(149,0) << "Session::dogleg[x+2] new paral: " << segment2 << endl;
|
||||
|
@ -973,15 +871,12 @@ namespace Anabatic {
|
|||
updateNativeConstraints();
|
||||
segment2->updateNativeConstraints();
|
||||
|
||||
if ( isLocal()) autoSource->setFlags( AutoContactFlag::CntVDogleg );
|
||||
if (segment2->isLocal()) autoTarget->setFlags( AutoContactFlag::CntVDogleg );
|
||||
|
||||
if (autoTarget->canDrag() and not autoSource->canDrag()) {
|
||||
if (not autoTarget->getGCell()->isDevice() and (segment1->getGCell() == autoTarget->getGCell())) {
|
||||
if (not autoTarget->getGCell()->isDevice()) {
|
||||
Interval dragConstraints = autoTarget->getNativeUConstraints(Flags::Horizontal);
|
||||
segment1->mergeUserConstraints( dragConstraints );
|
||||
|
||||
cdebug_log(149,0) << "Perpandicular has drag constraints: " << dragConstraints << endl;
|
||||
cdebug_log(149,0) << "Perpandical has drag constraints: " << dragConstraints << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -16,7 +16,6 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/ViaLayer.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "crlcore/RoutingGauge.h"
|
||||
|
@ -30,10 +29,8 @@ namespace Anabatic {
|
|||
|
||||
using std::min;
|
||||
using std::max;
|
||||
using std::abs;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::ViaLayer;
|
||||
|
||||
|
||||
|
@ -44,11 +41,13 @@ namespace Anabatic {
|
|||
Segment* AutoVertical::base () { return _vertical; }
|
||||
Segment* AutoVertical::base () const { return _vertical; }
|
||||
Vertical* AutoVertical::getVertical () { return _vertical; }
|
||||
DbU::Unit AutoVertical::getSourceU () const { return _vertical->getSource()->getY(); }
|
||||
DbU::Unit AutoVertical::getTargetU () const { return _vertical->getTarget()->getY(); }
|
||||
DbU::Unit AutoVertical::getSourceU () const { return _vertical->getSourceY(); }
|
||||
DbU::Unit AutoVertical::getTargetU () const { return _vertical->getTargetY(); }
|
||||
DbU::Unit AutoVertical::getDuSource () const { return _vertical->getDySource(); }
|
||||
DbU::Unit AutoVertical::getDuTarget () const { return _vertical->getDyTarget(); }
|
||||
Interval AutoVertical::getSpanU () const { return Interval(_vertical->getSourceY(),_vertical->getTargetY()); }
|
||||
void AutoVertical::setDuSource ( DbU::Unit du ) { _vertical->setDySource(du); }
|
||||
void AutoVertical::setDuTarget ( DbU::Unit du ) { _vertical->setDyTarget(du); }
|
||||
string AutoVertical::_getTypeName () const { return "AutoVertical"; }
|
||||
|
||||
|
||||
|
@ -118,30 +117,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
void AutoVertical::setDuSource ( DbU::Unit du )
|
||||
{
|
||||
_vertical->setDySource(du);
|
||||
if (abs(du) > getPitch())
|
||||
cerr << Warning( "AutoVertical::setDuSource(): Suspiciously big du=%s (should not exceed routing pitch %s)\n"
|
||||
" On %s"
|
||||
, DbU::getValueString(du).c_str()
|
||||
, DbU::getValueString(getPitch()).c_str()
|
||||
, getString(this).c_str() ) << endl;
|
||||
}
|
||||
|
||||
|
||||
void AutoVertical::setDuTarget ( DbU::Unit du )
|
||||
{
|
||||
_vertical->setDyTarget(du);
|
||||
if (abs(du) > getPitch())
|
||||
cerr << Warning( "AutoVertical::setDuTarget(): Suspiciously big du=%s (should not exceed routing pitch %s)\n"
|
||||
" On %s"
|
||||
, DbU::getValueString(du).c_str()
|
||||
, DbU::getValueString(getPitch()).c_str()
|
||||
, getString(this).c_str() ) << endl;
|
||||
}
|
||||
|
||||
|
||||
Interval AutoVertical::getSourceConstraints ( Flags flags ) const
|
||||
{
|
||||
if (flags & Flags::NativeConstraints) {
|
||||
|
@ -243,7 +218,6 @@ namespace Anabatic {
|
|||
|
||||
if (not gcell) {
|
||||
success = false;
|
||||
if (not isCreated()) {
|
||||
cerr << Error( "AutoVertical::getGCells() : NULL GCell under %s\n"
|
||||
" begin:%s\n"
|
||||
" end: %s"
|
||||
|
@ -251,7 +225,6 @@ namespace Anabatic {
|
|||
, getString(getAutoSource()->getGCell()).c_str()
|
||||
, getString(getAutoTarget()->getGCell()).c_str()
|
||||
) << endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -266,21 +239,17 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_tabw(149,-1);
|
||||
|
||||
if (getAutoSource()->isOnPin() or getAutoTarget()->isOnPin()) { cdebug_tabw(149,-1); return false; }
|
||||
|
||||
Interval sourceSide = getAutoSource()->getGCell()->getSide( Flags::Horizontal );
|
||||
Interval targetSide = getAutoTarget()->getGCell()->getSide( Flags::Horizontal );
|
||||
Interval sourceConstraints = Interval(getAutoSource()->getCBXMin(),getAutoSource()->getCBXMax());
|
||||
Interval targetConstraints = Interval(getAutoTarget()->getCBXMin(),getAutoTarget()->getCBXMax());
|
||||
bool sourceGoStraight = getAutoSource()->getGCell()->isGoStraight();
|
||||
bool targetGoStraight = getAutoTarget()->getGCell()->isGoStraight();
|
||||
|
||||
// Expand by a tiny amount for the "contains" to work for sure.
|
||||
sourceConstraints.inflate( 1 );
|
||||
targetConstraints.inflate( 1 );
|
||||
|
||||
if (not sourceGoStraight and not sourceConstraints.contains(sourceSide)) { cdebug_tabw(149,-1); return true; }
|
||||
if (not targetGoStraight and not targetConstraints.contains(targetSide)) { cdebug_tabw(149,-1); return true; }
|
||||
if (not sourceConstraints.contains(sourceSide)) { cdebug_tabw(149,-1); return true; }
|
||||
if (not targetConstraints.contains(targetSide)) { cdebug_tabw(149,-1); return true; }
|
||||
|
||||
cdebug_tabw(149,-1);
|
||||
return false;
|
||||
|
@ -293,13 +262,13 @@ namespace Anabatic {
|
|||
|
||||
if (not isDrag()) {
|
||||
if ( not isStrongTerminal()
|
||||
or (not (_flags & (SegGlobal|SegWeakGlobal)) and (getAnchoredLength() < getPitch()*5)) )
|
||||
or (not (_flags & (SegGlobal|SegWeakGlobal)) and (getLength() < getPitch()*5)) )
|
||||
{ cdebug_tabw(149,-1); return false; }
|
||||
}
|
||||
|
||||
cdebug_log(149,0) << "_flags:" << (_flags & (SegGlobal|SegWeakGlobal)) << endl;
|
||||
cdebug_log(149,0) << "test:" << (getAnchoredLength() < getPitch()*5) << endl;
|
||||
cdebug_log(149,0) << "length:" << DbU::getValueString(getAnchoredLength()) << endl;
|
||||
cdebug_log(149,0) << "test:" << (getLength() < getPitch()*5) << endl;
|
||||
cdebug_log(149,0) << "length:" << DbU::getValueString(getLength()) << endl;
|
||||
|
||||
bool success = false;
|
||||
bool sourceSlackened = false;
|
||||
|
@ -430,8 +399,8 @@ namespace Anabatic {
|
|||
|
||||
void AutoVertical::updatePositions ()
|
||||
{
|
||||
_sourcePosition = getSourceU() - getExtensionCap(Flags::Source);
|
||||
_targetPosition = getTargetU() + getExtensionCap(Flags::Target);
|
||||
_sourcePosition = _vertical->getSourceY() - getExtensionCap(Flags::Source);
|
||||
_targetPosition = _vertical->getTargetY() + getExtensionCap(Flags::Target);
|
||||
}
|
||||
|
||||
|
||||
|
@ -451,8 +420,8 @@ namespace Anabatic {
|
|||
bool AutoVertical::checkPositions () const
|
||||
{
|
||||
bool coherency = true;
|
||||
DbU::Unit sourcePosition = _vertical->getSource()->getY() - getExtensionCap(Flags::Source);
|
||||
DbU::Unit targetPosition = _vertical->getTarget()->getY() + getExtensionCap(Flags::Target);
|
||||
DbU::Unit sourcePosition = _vertical->getSourceY() - getExtensionCap(Flags::Source);
|
||||
DbU::Unit targetPosition = _vertical->getTargetY() + getExtensionCap(Flags::Target);
|
||||
|
||||
if ( _sourcePosition != sourcePosition ) {
|
||||
cerr << Error ( "%s\n Source position incoherency: "
|
||||
|
@ -736,7 +705,7 @@ namespace Anabatic {
|
|||
bool upLayer = true;
|
||||
|
||||
if (Session::getRoutingGauge()->isTwoMetals()) {
|
||||
upLayer = (Session::getRoutingGauge()->isVH());
|
||||
upLayer = (depth == 0);
|
||||
} else if (Session::getRoutingGauge()->isVH()) {
|
||||
upLayer = (depth < 2);
|
||||
} else {
|
||||
|
@ -745,6 +714,7 @@ namespace Anabatic {
|
|||
|
||||
size_t doglegDepth = depth + ((upLayer)?1:-1);
|
||||
Layer* contactLayer = Session::getRoutingGauge()->getContactLayer ( depth + ((upLayer)?0:-1) );
|
||||
const Layer* doglegLayer = Session::getRoutingGauge()->getRoutingLayer ( doglegDepth );
|
||||
|
||||
Session::dogleg( this );
|
||||
targetDetach();
|
||||
|
@ -771,56 +741,31 @@ namespace Anabatic {
|
|||
segment2->setFlags( (isSlackened()?SegSlackened:0) );
|
||||
Session::dogleg( segment2 );
|
||||
|
||||
if (autoSource->isTerminal() and autoTarget->isTerminal()) {
|
||||
dlContact1->setFlags ( CntWeakTerminal );
|
||||
dlContact2->setFlags ( CntWeakTerminal );
|
||||
|
||||
if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget );
|
||||
if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource );
|
||||
} else if (autoSource->isTerminal()) {
|
||||
if (isSourceTerminal()) {
|
||||
segment1->setFlags( SegWeakTerminal1 );
|
||||
segment2->setFlags( SegWeakTerminal1 );
|
||||
autoTarget->unsetFlags( CntWeakTerminal );
|
||||
dlContact1->setFlags ( CntWeakTerminal );
|
||||
if (autoTarget->getGCell() == doglegGCell) dlContact1->migrateConstraintBox( autoTarget );
|
||||
} else if (autoTarget->isTerminal()) {
|
||||
if (autoTarget->getGCell() == doglegGCell)
|
||||
dlContact1->migrateConstraintBox( autoTarget );
|
||||
} else if (isTargetTerminal()) {
|
||||
unsetFlags( SegTargetTerminal );
|
||||
setFlags( SegWeakTerminal1 );
|
||||
segment1->setFlags( SegWeakTerminal1 );
|
||||
segment2->setFlags( SegTargetTerminal );
|
||||
autoSource->unsetFlags( CntWeakTerminal );
|
||||
dlContact2->setFlags ( CntWeakTerminal );
|
||||
if (autoSource->getGCell() == doglegGCell) dlContact2->migrateConstraintBox( autoSource );
|
||||
if (autoSource->getGCell() == doglegGCell)
|
||||
dlContact2->migrateConstraintBox( autoSource );
|
||||
} else if (isWeakTerminal()) {
|
||||
segment1->setFlags( SegWeakTerminal1 );
|
||||
segment2->setFlags( SegWeakTerminal1 );
|
||||
}
|
||||
|
||||
// if (isSourceTerminal()) {
|
||||
// segment1->setFlags( SegWeakTerminal1 );
|
||||
// segment2->setFlags( SegWeakTerminal1 );
|
||||
// autoTarget->unsetFlags( CntWeakTerminal );
|
||||
// dlContact1->setFlags ( CntWeakTerminal );
|
||||
// if (autoTarget->getGCell() == doglegGCell)
|
||||
// dlContact1->migrateConstraintBox( autoTarget );
|
||||
// } else if (isTargetTerminal()) {
|
||||
// unsetFlags( SegTargetTerminal );
|
||||
// setFlags( SegWeakTerminal1 );
|
||||
// segment1->setFlags( SegWeakTerminal1 );
|
||||
// segment2->setFlags( SegTargetTerminal );
|
||||
// autoSource->unsetFlags( CntWeakTerminal );
|
||||
// dlContact2->setFlags ( CntWeakTerminal );
|
||||
// if (autoSource->getGCell() == doglegGCell)
|
||||
// dlContact2->migrateConstraintBox( autoSource );
|
||||
// } else if (isWeakTerminal()) {
|
||||
// segment1->setFlags( SegWeakTerminal1 );
|
||||
// segment2->setFlags( SegWeakTerminal1 );
|
||||
// }
|
||||
|
||||
if (isAnalog()) {
|
||||
segment1->setFlags( SegAnalog );
|
||||
segment2->setFlags( SegAnalog );
|
||||
}
|
||||
if (isNoMoveUp()) {
|
||||
segment1->setFlags( SegNoMoveUp );
|
||||
segment2->setFlags( SegNoMoveUp );
|
||||
}
|
||||
|
||||
cdebug_log(149,0) << "Session::dogleg[x+1] perpand: " << segment1 << endl;
|
||||
cdebug_log(149,0) << "Session::dogleg[x+2] new paral: " << segment2 << endl;
|
||||
|
@ -836,15 +781,12 @@ namespace Anabatic {
|
|||
updateNativeConstraints();
|
||||
segment2->updateNativeConstraints();
|
||||
|
||||
if ( isLocal()) autoSource->setFlags( AutoContactFlag::CntHDogleg );
|
||||
if (segment2->isLocal()) autoTarget->setFlags( AutoContactFlag::CntHDogleg );
|
||||
|
||||
if (autoTarget->canDrag() and not autoSource->canDrag()) {
|
||||
if (not autoTarget->getGCell()->isDevice() and (segment1->getGCell() == autoTarget->getGCell())) {
|
||||
if (not autoTarget->getGCell()->isDevice()) {
|
||||
Interval dragConstraints = autoTarget->getNativeUConstraints(Flags::Vertical);
|
||||
segment1->mergeUserConstraints( dragConstraints );
|
||||
|
||||
cdebug_log(149,0) << "Perpandicular has drag constraints: " << dragConstraints << endl;
|
||||
cdebug_log(149,0) << "Perpandical has drag constraints: " << dragConstraints << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,13 +6,12 @@ endif ( CHECK_DETERMINISM )
|
|||
|
||||
include_directories( ${ANABATIC_SOURCE_DIR}/src
|
||||
${CORIOLIS_INCLUDE_DIR}
|
||||
${ETESIAN_INCLUDE_DIR}
|
||||
${HURRICANE_INCLUDE_DIR}
|
||||
${CONFIGURATION_INCLUDE_DIR}
|
||||
${FLUTE_INCLUDE_DIR}
|
||||
${Boost_INCLUDE_DIRS}
|
||||
${QtX_INCLUDE_DIRS}
|
||||
${Python_INCLUDE_DIRS}
|
||||
${QtX_INCLUDE_DIR}
|
||||
${PYTHON_INCLUDE_PATH}
|
||||
)
|
||||
set( includes anabatic/Constants.h
|
||||
anabatic/Configuration.h
|
||||
|
@ -36,10 +35,9 @@ endif ( CHECK_DETERMINISM )
|
|||
anabatic/NetBuilderM2.h
|
||||
anabatic/NetBuilderHV.h
|
||||
anabatic/NetBuilderVH.h
|
||||
anabatic/NetBuilderHybridVH.h
|
||||
anabatic/ChipTools.h
|
||||
)
|
||||
set( pyIncludes anabatic/PyStyleFlags.h )
|
||||
set( pyIncludes )
|
||||
set( cpps Constants.cpp
|
||||
Configuration.cpp
|
||||
Matrix.cpp
|
||||
|
@ -63,19 +61,15 @@ endif ( CHECK_DETERMINISM )
|
|||
NetBuilderM2.cpp
|
||||
NetBuilderHV.cpp
|
||||
NetBuilderVH.cpp
|
||||
NetBuilderHybridVH.cpp
|
||||
ChipTools.cpp
|
||||
LayerAssign.cpp
|
||||
AntennaProtect.cpp
|
||||
PreRouteds.cpp
|
||||
AnabaticEngine.cpp
|
||||
)
|
||||
set( pyCpps PyStyleFlags.cpp
|
||||
PyAnabatic.cpp
|
||||
set( pyCpps PyAnabatic.cpp
|
||||
)
|
||||
|
||||
set( depLibs ${ETESIAN_LIBRARIES}
|
||||
${CORIOLIS_PYTHON_LIBRARIES}
|
||||
set( depLibs ${CORIOLIS_PYTHON_LIBRARIES}
|
||||
${CORIOLIS_LIBRARIES}
|
||||
${HURRICANE_PYTHON_LIBRARIES}
|
||||
${HURRICANE_GRAPHICAL_LIBRARIES}
|
||||
|
@ -83,15 +77,13 @@ endif ( CHECK_DETERMINISM )
|
|||
${CONFIGURATION_LIBRARY}
|
||||
${CIF_LIBRARY}
|
||||
${AGDS_LIBRARY}
|
||||
${COLOQUINTE_LIBRARIES}
|
||||
${FLUTE_LIBRARIES}
|
||||
${LEFDEF_LIBRARIES}
|
||||
${OA_LIBRARIES}
|
||||
${QtX_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
${LIBXML2_LIBRARIES}
|
||||
${Python3_LIBRARIES}
|
||||
-lutil
|
||||
${PYTHON_LIBRARIES} -lutil
|
||||
)
|
||||
|
||||
add_library( anabatic ${cpps} )
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// -*- mode: C++; explicit-buffer-name: "Configuration.cpp<anabatic>" -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2016-2022, All Rights Reserved
|
||||
// Copyright (c) UPMC 2016-2018, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -17,7 +17,7 @@
|
|||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
#include "hurricane/configuration/Configuration.h"
|
||||
#include "vlsisapd/configuration/Configuration.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Technology.h"
|
||||
|
@ -25,8 +25,6 @@
|
|||
#include "hurricane/BasicLayer.h"
|
||||
#include "hurricane/RegularLayer.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "hurricane/Pin.h"
|
||||
#include "hurricane/Pad.h"
|
||||
#include "hurricane/NetExternalComponents.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "crlcore/Utilities.h"
|
||||
|
@ -57,8 +55,6 @@ namespace Anabatic {
|
|||
using Hurricane::BasicLayer;
|
||||
using Hurricane::RegularLayer;
|
||||
using Hurricane::Segment;
|
||||
using Hurricane::Pad;
|
||||
using Hurricane::Pin;
|
||||
using Hurricane::Plug;
|
||||
using Hurricane::Path;
|
||||
using Hurricane::Occurrence;
|
||||
|
@ -78,45 +74,35 @@ namespace Anabatic {
|
|||
, _ddepthv (ndepth)
|
||||
, _ddepthh (ndepth)
|
||||
, _ddepthc (ndepth)
|
||||
, _netBuilderStyle (Cfg::getParamString("anabatic.netBuilderStyle","HV,3RL+")->asString() )
|
||||
, _routingStyle (Cfg::getParamInt ("anabatic.routingStyle" ,StyleFlags::NoStyle)->asInt() )
|
||||
, _cg (NULL)
|
||||
, _rg (NULL)
|
||||
, _extensionCaps ()
|
||||
, _saturateRatio (Cfg::getParamPercentage("anabatic.saturateRatio",80.0)->asDouble())
|
||||
, _saturateRp (Cfg::getParamInt ("anabatic.saturateRp" ,8 )->asInt())
|
||||
, _saturateRatio (Cfg::getParamPercentage("katabatic.saturateRatio",80.0)->asDouble())
|
||||
, _saturateRp (Cfg::getParamInt ("katabatic.saturateRp" ,8 )->asInt())
|
||||
, _globalThreshold (0)
|
||||
, _allowedDepth (0)
|
||||
, _edgeLength (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeLength",24)->asInt()))
|
||||
, _edgeWidth (DbU::fromLambda(Cfg::getParamInt("anabatic.edgeWidth" , 4)->asInt()))
|
||||
, _edgeCostH (Cfg::getParamDouble("anabatic.edgeCostH" , 9.0)->asDouble())
|
||||
, _edgeCostK (Cfg::getParamDouble("anabatic.edgeCostK" , -10.0)->asDouble())
|
||||
, _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())
|
||||
, _globalIterations(Cfg::getParamInt ("anabatic.globalIterations", 10 )->asInt())
|
||||
{
|
||||
GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() );
|
||||
|
||||
string gaugeName = Cfg::getParamString("anabatic.routingGauge","sxlib")->asString();
|
||||
if (not cg)
|
||||
if (cg == NULL) {
|
||||
cg = AllianceFramework::get()->getCellGauge( gaugeName );
|
||||
if (not cg) {
|
||||
string cellGaugeName = Cfg::getParamString("anabatic.cellGauge","sxlib")->asString();
|
||||
cg = AllianceFramework::get()->getCellGauge( cellGaugeName );
|
||||
if (cg == NULL)
|
||||
throw Error( "AnabaticEngine::Configuration(): Unable to find default cell gauge." );
|
||||
}
|
||||
if (not cg)
|
||||
throw Error( "AnabaticEngine::Configuration(): Unable to find cell gauge \"%s\""
|
||||
, gaugeName.c_str() );
|
||||
|
||||
if (not rg)
|
||||
if (rg == NULL) {
|
||||
rg = AllianceFramework::get()->getRoutingGauge( gaugeName );
|
||||
if (not rg)
|
||||
throw Error( "AnabaticEngine::Configuration(): Unable to find routing gauge \"%s\""
|
||||
, gaugeName.c_str() );
|
||||
|
||||
if (rg == NULL)
|
||||
throw Error( "AnabaticEngine::Configuration(): No routing gauge named \"%s\"", gaugeName.c_str() );
|
||||
}
|
||||
_cg = cg->getClone();
|
||||
_rg = rg->getClone();
|
||||
|
||||
|
@ -169,14 +155,6 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_antennaGateMaxWL and not _antennaDiodeMaxWL) {
|
||||
_antennaDiodeMaxWL = _antennaGateMaxWL;
|
||||
cerr << Warning( "Anabatic::Configuration(): \"etesian.antennaGateMaxWL\" is defined but not \"etesian.antennaDiodeMaxWL\".\n"
|
||||
" Setting both to %s"
|
||||
, DbU::getValueString(_antennaGateMaxWL).c_str()
|
||||
) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -189,8 +167,6 @@ namespace Anabatic {
|
|||
, _ddepthv (other._ddepthv)
|
||||
, _ddepthh (other._ddepthh)
|
||||
, _ddepthc (other._ddepthc)
|
||||
, _netBuilderStyle (other._netBuilderStyle)
|
||||
, _routingStyle (other._routingStyle)
|
||||
, _cg (NULL)
|
||||
, _rg (NULL)
|
||||
, _extensionCaps (other._extensionCaps)
|
||||
|
@ -201,10 +177,7 @@ namespace Anabatic {
|
|||
, _edgeCostK (other._edgeCostK)
|
||||
, _edgeHInc (other._edgeHInc)
|
||||
, _edgeHScaling (other._edgeHScaling)
|
||||
, _globalIterations (other._globalIterations)
|
||||
, _diodeName (other._diodeName)
|
||||
, _antennaGateMaxWL (other._antennaGateMaxWL)
|
||||
, _antennaDiodeMaxWL(other._antennaDiodeMaxWL)
|
||||
, _globalIterations(other._globalIterations)
|
||||
{
|
||||
GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() );
|
||||
|
||||
|
@ -229,10 +202,6 @@ namespace Anabatic {
|
|||
{ return _rg->isTwoMetals(); }
|
||||
|
||||
|
||||
bool Configuration::isHybrid () const
|
||||
{ return _routingStyle & StyleFlags::Hybrid; }
|
||||
|
||||
|
||||
bool Configuration::isHV () const
|
||||
{ return _rg->isHV(); }
|
||||
|
||||
|
@ -317,10 +286,6 @@ namespace Anabatic {
|
|||
{ return getWireWidth( getLayerDepth(layer) ); }
|
||||
|
||||
|
||||
DbU::Unit Configuration::getPWireWidth ( const Layer* layer ) const
|
||||
{ return getPWireWidth( getLayerDepth(layer) ); }
|
||||
|
||||
|
||||
Flags Configuration::getDirection ( const Layer* layer ) const
|
||||
{ return getDirection( getLayerDepth(layer) ); }
|
||||
|
||||
|
@ -372,9 +337,6 @@ namespace Anabatic {
|
|||
{ return _rg->getLayerWireWidth(depth); }
|
||||
|
||||
|
||||
DbU::Unit Configuration::getPWireWidth ( size_t depth ) const
|
||||
{ return _rg->getLayerPWireWidth(depth); }
|
||||
|
||||
DbU::Unit Configuration::getExtensionCap ( size_t depth ) const
|
||||
{ return _extensionCaps[depth]; }
|
||||
|
||||
|
@ -496,26 +458,13 @@ namespace Anabatic {
|
|||
cdebug_log(112,0) << "Looking into: " << masterNet->getCell() << endl;
|
||||
for ( Component* component : masterNet->getComponents() ) {
|
||||
cdebug_log(112,0) << "@ " << component << endl;
|
||||
if (not NetExternalComponents::isExternal(component)) {
|
||||
cdebug_log(112,0) << " Not an external component, skip." << endl;
|
||||
continue;
|
||||
}
|
||||
if (not NetExternalComponents::isExternal(component)) continue;
|
||||
|
||||
if (dynamic_cast<Pin*>(component)) {
|
||||
cdebug_log(112,0) << " Pins are always considered best candidates:" << component << endl;
|
||||
bestComponent = component;
|
||||
break;
|
||||
}
|
||||
Segment* segment = dynamic_cast<Segment*>(component);
|
||||
if (not segment) continue;
|
||||
if (segment->getLayer()->getMask() != metal1->getMask()) continue;
|
||||
|
||||
Component* candidate = dynamic_cast<Segment*>( component );
|
||||
if (not candidate
|
||||
or (candidate->getLayer()->getMask() != metal1->getMask()) )
|
||||
candidate = dynamic_cast<Pin*>(component);
|
||||
if (not candidate)
|
||||
candidate = dynamic_cast<Pad*>( component );
|
||||
if (not candidate) continue;
|
||||
|
||||
Box bb = transformation.getBox( candidate->getBoundingBox() );
|
||||
Box bb = transformation.getBox( component->getBoundingBox() );
|
||||
DbU::Unit trackPos = 0;
|
||||
DbU::Unit minPos = DbU::Max;
|
||||
DbU::Unit maxPos = DbU::Min;
|
||||
|
@ -529,8 +478,8 @@ namespace Anabatic {
|
|||
maxPos = bb.getXMax();
|
||||
|
||||
cdebug_log(112,0) << "Vertical gauge: " << gauge << endl;
|
||||
cdebug_log(112,0) << "ab.getXMin(): " << DbU::getValueString(bb.getXMin()) << endl;
|
||||
cdebug_log(112,0) << "ab.getXMax(): " << DbU::getValueString(bb.getXMax()) << endl;
|
||||
cdebug_log(112,0) << "ab.getXMin(): " << DbU::getValueString(ab.getXMin()) << endl;
|
||||
cdebug_log(112,0) << "ab.getXMax(): " << DbU::getValueString(ab.getXMax()) << endl;
|
||||
cdebug_log(112,0) << "bb.getCenter(): " << DbU::getValueString(bb.getCenter().getX()) << endl;
|
||||
} else {
|
||||
trackPos = gauge->getTrackPosition( ab.getYMin()
|
||||
|
@ -541,18 +490,18 @@ namespace Anabatic {
|
|||
maxPos = bb.getYMax();
|
||||
|
||||
cdebug_log(112,0) << "Horizontal gauge: " << gauge << endl;
|
||||
cdebug_log(112,0) << "ab.getYMin(): " << DbU::getValueString(bb.getYMin()) << endl;
|
||||
cdebug_log(112,0) << "ab.getYMax(): " << DbU::getValueString(bb.getYMax()) << endl;
|
||||
cdebug_log(112,0) << "ab.getYMin(): " << DbU::getValueString(ab.getYMin()) << endl;
|
||||
cdebug_log(112,0) << "ab.getYMax(): " << DbU::getValueString(ab.getYMax()) << endl;
|
||||
cdebug_log(112,0) << "bb.getCenter(): " << DbU::getValueString(bb.getCenter().getY()) << endl;
|
||||
}
|
||||
|
||||
cdebug_log(112,0) << "| " << occurrence.getPath() << endl;
|
||||
cdebug_log(112,0) << "| " << transformation << endl;
|
||||
cdebug_log(112,0) << "| " << bb << " of:" << candidate << endl;
|
||||
cdebug_log(112,0) << "| " << bb << " of:" << segment << endl;
|
||||
cdebug_log(112,0) << "| Nearest Pos: " << DbU::getValueString(trackPos) << endl;
|
||||
|
||||
if ( (trackPos >= minPos) and (trackPos <= maxPos) ) {
|
||||
if (not bestComponent or (bestSpan < maxPos-minPos)) {
|
||||
if (not bestComponent or (bestSpan > maxPos-minPos)) {
|
||||
bestComponent = component;
|
||||
bestSpan = maxPos - minPos;
|
||||
}
|
||||
|
@ -584,7 +533,6 @@ namespace Anabatic {
|
|||
cout << " o Configuration of ToolEngine<Anabatic> for Cell <" << cell->getName() << ">" << endl;
|
||||
cout << Dots::asIdentifier(" - Routing Gauge" ,getString(_rg->getName())) << endl;
|
||||
cout << Dots::asString (" - Top routing layer" ,topLayerName) << endl;
|
||||
cout << Dots::asUInt (" - Maximum GR iterations" ,_globalIterations) << endl;
|
||||
}
|
||||
|
||||
|
||||
|
@ -607,22 +555,17 @@ namespace Anabatic {
|
|||
Record* Configuration::_getRecord () const
|
||||
{
|
||||
Record* record = new Record ( _getString() );
|
||||
record->add( getSlot( "_gdepthh" , _gdepthh ) );
|
||||
record->add( getSlot( "_gdepthv" , _gdepthv ) );
|
||||
record->add( getSlot( "_rg" , _rg ) );
|
||||
record->add( getSlot( "_gmetalh" , _gmetalh ) );
|
||||
record->add( getSlot( "_gmetalv" , _gmetalv ) );
|
||||
record->add( getSlot( "_gcontact" , _gcontact ) );
|
||||
record->add( getSlot( "_allowedDepth" , _allowedDepth ) );
|
||||
record->add( getSlot( "_edgeCostH" , _edgeCostH ) );
|
||||
record->add( getSlot( "_edgeCostK" , _edgeCostK ) );
|
||||
record->add( getSlot( "_edgeHInc" , _edgeHInc ) );
|
||||
record->add( getSlot( "_edgeHScaling" , _edgeHScaling ) );
|
||||
record->add( getSlot( "_globalIterations", _globalIterations ) );
|
||||
record->add( DbU::getValueSlot( "_antennaGateMaxWL" , &_antennaGateMaxWL ) );
|
||||
record->add( DbU::getValueSlot( "_antennaDiodeMaxWL", &_antennaDiodeMaxWL ) );
|
||||
record->add ( getSlot( "_gdepthh" , _gdepthh ) );
|
||||
record->add ( getSlot( "_gdepthv" , _gdepthv ) );
|
||||
record->add ( getSlot( "_rg" , _rg ) );
|
||||
record->add ( getSlot( "_gmetalh" , _gmetalh ) );
|
||||
record->add ( getSlot( "_gmetalv" , _gmetalv ) );
|
||||
record->add ( getSlot( "_gcontact" , _gcontact ) );
|
||||
record->add ( getSlot( "_allowedDepth", _allowedDepth ) );
|
||||
record->add ( getSlot( "_edgeCostH" , _edgeCostH ) );
|
||||
record->add ( getSlot( "_edgeCostK" , _edgeCostK ) );
|
||||
|
||||
return record;
|
||||
return ( record );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -14,22 +14,16 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#include "hurricane/Error.h"
|
||||
#include "anabatic/Constants.h"
|
||||
|
||||
|
||||
namespace Anabatic {
|
||||
|
||||
using std::hex;
|
||||
using std::string;
|
||||
using std::ostringstream;
|
||||
using Hurricane::BaseFlags;
|
||||
using Hurricane::Error;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::Flags".
|
||||
|
||||
const BaseFlags Flags::NoFlags = 0;
|
||||
// Flags used for both objects states & functions arguments.
|
||||
const BaseFlags Flags::Horizontal = (1L << 0);
|
||||
|
@ -49,7 +43,6 @@ namespace Anabatic {
|
|||
const BaseFlags Flags::ChannelRow = (1L << 13);
|
||||
const BaseFlags Flags::HRailGCell = (1L << 14);
|
||||
const BaseFlags Flags::VRailGCell = (1L << 15);
|
||||
const BaseFlags Flags::GoStraight = (1L << 16);
|
||||
// Flags for Edge objects states only.
|
||||
const BaseFlags Flags::NullCapacity = (1L << 5);
|
||||
const BaseFlags Flags::InfiniteCapacity = (1L << 6);
|
||||
|
@ -59,13 +52,10 @@ namespace Anabatic {
|
|||
const BaseFlags Flags::DestroyGCell = (1L << 7);
|
||||
const BaseFlags Flags::DestroyBaseContact = (1L << 8);
|
||||
const BaseFlags Flags::DestroyBaseSegment = (1L << 9);
|
||||
const BaseFlags Flags::DisableCanonize = (1L << 10);
|
||||
// Flags for NetDatas objects states only.
|
||||
const BaseFlags Flags::GlobalFixed = (1L << 5);
|
||||
const BaseFlags Flags::GlobalRouted = (1L << 5);
|
||||
const BaseFlags Flags::GlobalEstimated = (1L << 6);
|
||||
const BaseFlags Flags::GlobalRouted = (1L << 7);
|
||||
const BaseFlags Flags::DetailRouted = (1L << 8);
|
||||
const BaseFlags Flags::ExcludeRoute = (1L << 9);
|
||||
const BaseFlags Flags::ExcludeRoute = (1L << 7);
|
||||
// Masks.
|
||||
const BaseFlags Flags::WestSide = Horizontal|Target;
|
||||
const BaseFlags Flags::EastSide = Horizontal|Source;
|
||||
|
@ -126,13 +116,6 @@ namespace Anabatic {
|
|||
const BaseFlags Flags::CheckLowUpDensity = (1L << 31);
|
||||
const BaseFlags Flags::NoUpdate = (1L << 32);
|
||||
const BaseFlags Flags::NorthPath = (1L << 33);
|
||||
const BaseFlags Flags::UseNonPref = (1L << 34);
|
||||
const BaseFlags Flags::Force = (1L << 35);
|
||||
const BaseFlags Flags::LayerCapOnly = (1L << 36);
|
||||
const BaseFlags Flags::NoMinLength = (1L << 37);
|
||||
const BaseFlags Flags::NoSegExt = (1L << 38);
|
||||
const BaseFlags Flags::NullLength = (1L << 39);
|
||||
const BaseFlags Flags::OnVSmall = (1L << 40);
|
||||
|
||||
|
||||
Flags::~Flags ()
|
||||
|
@ -186,7 +169,6 @@ namespace Anabatic {
|
|||
return s.str();
|
||||
}
|
||||
|
||||
|
||||
string Flags::_getTypeName () const
|
||||
{ return "Anabatic::Flags"; }
|
||||
|
||||
|
@ -201,13 +183,12 @@ namespace Anabatic {
|
|||
s += (_flags & (uint64_t)DeviceGCell ) ? 'd' : '-';
|
||||
s += (_flags & (uint64_t)HChannelGCell) ? 'c' : '-';
|
||||
s += (_flags & (uint64_t)VChannelGCell) ? 'c' : '-';
|
||||
s += (_flags & (uint64_t)HRailGCell ) ? 'H' : '-';
|
||||
s += (_flags & (uint64_t)VRailGCell ) ? 'V' : '-';
|
||||
s += (_flags & (uint64_t)StrutGCell ) ? 'S' : '-';
|
||||
s += (_flags & (uint64_t)MatrixGCell ) ? 'M' : '-';
|
||||
s += (_flags & (uint64_t)StdCellRow ) ? 'R' : '-';
|
||||
s += (_flags & (uint64_t)HRailGCell ) ? 'r' : '-';
|
||||
s += (_flags & (uint64_t)VRailGCell ) ? 'r' : '-';
|
||||
s += (_flags & (uint64_t)StrutGCell ) ? 's' : '-';
|
||||
s += (_flags & (uint64_t)MatrixGCell ) ? 'm' : '-';
|
||||
s += (_flags & (uint64_t)StdCellRow ) ? 'S' : '-';
|
||||
s += (_flags & (uint64_t)ChannelRow ) ? 'C' : '-';
|
||||
s += (_flags & (uint64_t)GoStraight ) ? 'g' : '-';
|
||||
s += ",";
|
||||
s += (_flags & (uint64_t)Invalidated ) ? 'i' : '-';
|
||||
s += (_flags & (uint64_t)DestroyGCell ) ? 'D' : '-';
|
||||
|
@ -218,69 +199,4 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::StyleFlags".
|
||||
|
||||
|
||||
const BaseFlags StyleFlags::NoStyle = 0;
|
||||
const BaseFlags StyleFlags::HV = (1L << 0);
|
||||
const BaseFlags StyleFlags::VH = (1L << 1);
|
||||
const BaseFlags StyleFlags::OTH = (1L << 2);
|
||||
const BaseFlags StyleFlags::Channel = (1L << 3);
|
||||
const BaseFlags StyleFlags::Hybrid = (1L << 4);
|
||||
|
||||
|
||||
StyleFlags::~StyleFlags ()
|
||||
{ }
|
||||
|
||||
|
||||
StyleFlags StyleFlags::toFlag ( std::string textFlag )
|
||||
{
|
||||
if (textFlag == "HV") return HV;
|
||||
if (textFlag == "VH") return VH;
|
||||
if (textFlag == "OTH") return OTH;
|
||||
if (textFlag == "Channel") return Channel;
|
||||
if (textFlag == "Hybrid") return Hybrid;
|
||||
if (textFlag == "NoStyle") return NoStyle;
|
||||
std::cerr << Error( "StyleFlags::toFlag(): Unknown flag value \"%s\"", textFlag.c_str() ) << std::endl;
|
||||
return NoStyle;
|
||||
}
|
||||
|
||||
|
||||
StyleFlags StyleFlags::from ( std::string textFlags )
|
||||
{
|
||||
size_t start = 0;
|
||||
size_t stop = textFlags.find( '|' );
|
||||
while ( stop != string::npos ) {
|
||||
*this |= toFlag( textFlags.substr( start, stop-start-1 ));
|
||||
start = stop + 1;
|
||||
stop = textFlags.find( '|', start );
|
||||
}
|
||||
*this |= toFlag( textFlags.substr( stop+1 ));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
string StyleFlags::asString () const
|
||||
{
|
||||
ostringstream s;
|
||||
|
||||
if (_flags & (uint64_t)HV) { s << (s.tellp() ? "|" : "") << "HV"; }
|
||||
if (_flags & (uint64_t)VH) { s << (s.tellp() ? "|" : "") << "VH"; }
|
||||
if (_flags & (uint64_t)OTH) { s << (s.tellp() ? "|" : "") << "OTH"; }
|
||||
if (_flags & (uint64_t)Channel) { s << (s.tellp() ? "|" : "") << "Channel"; }
|
||||
if (_flags & (uint64_t)Hybrid ) { s << (s.tellp() ? "|" : "") << "Hybrid"; }
|
||||
s << " (0x" << hex << _flags << ")";
|
||||
return s.str();
|
||||
}
|
||||
|
||||
|
||||
string StyleFlags::_getTypeName () const
|
||||
{ return "Anabatic::StyleFlags"; }
|
||||
|
||||
|
||||
string StyleFlags::_getString () const
|
||||
{ return asString(); }
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#include "hurricane/Error.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/Net.h"
|
||||
#include "hurricane/Pin.h"
|
||||
#include "hurricane/RoutingPad.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
|
@ -43,7 +42,6 @@ namespace Anabatic {
|
|||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Component;
|
||||
using Hurricane::Pin;
|
||||
using Hurricane::Segment;
|
||||
using Hurricane::Horizontal;
|
||||
using Hurricane::Vertical;
|
||||
|
@ -265,7 +263,7 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
if (rp) {
|
||||
Vertical* v = dynamic_cast<Vertical*>(rp->_getEntityAs<Segment>());
|
||||
Vertical* v = dynamic_cast<Vertical*>(rp->_getEntityAsSegment());
|
||||
if (v) { return true; }
|
||||
}
|
||||
}
|
||||
|
@ -285,7 +283,7 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
if (rp) {
|
||||
Horizontal* h = dynamic_cast<Horizontal*>(rp->_getEntityAs<Segment>());
|
||||
Horizontal* h = dynamic_cast<Horizontal*>(rp->_getEntityAsSegment());
|
||||
if (h) { return true; }
|
||||
}
|
||||
}
|
||||
|
@ -300,68 +298,52 @@ namespace Anabatic {
|
|||
GCell* c2 = v2->getGCell();
|
||||
|
||||
// Check from GCell 1
|
||||
if ( c1->isNorth(c2) and not v1->isNRestricted() ) restricted = false;
|
||||
else if ( c1->isSouth(c2) and not v1->isSRestricted() ) restricted = false;
|
||||
else if ( c1->isEast (c2) and not v1->isERestricted() ) restricted = false;
|
||||
else if ( c1->isWest (c2) and not v1->isWRestricted() ) restricted = false;
|
||||
// else {
|
||||
// cerr << Error( "Vertex::isRestricted(): Vertexes/GCells v1 & v2 do not share a side.\n"
|
||||
// " v1:%s\n"
|
||||
// " v2:%s"
|
||||
// , getString(v1).c_str()
|
||||
// , getString(v2).c_str()
|
||||
// ) << endl;
|
||||
// return true;
|
||||
// }
|
||||
|
||||
if (restricted) {
|
||||
cdebug_log(112,0) << "v1 -> v2 edge is restricted." << endl;
|
||||
return true;
|
||||
}
|
||||
if ( e->isVertical() and (c1->getWidth() < hpitch) ) {
|
||||
cdebug_log(112,0) << "GCell 1 is too narrow for V edges." << endl;
|
||||
return true;
|
||||
}
|
||||
if ( e->isHorizontal() and (c1->getHeight() < vpitch) ) {
|
||||
cdebug_log(112,0) << "GCell 1 is too narrow for H edges." << endl;
|
||||
if ( c1->isNorth(c2) ) {
|
||||
if ( !v1->isNRestricted() ) restricted = false;
|
||||
} else if ( c1->isSouth(c2) ) {
|
||||
if ( !v1->isSRestricted() ) restricted = false;
|
||||
} else if ( c1->isEast (c2) ) {
|
||||
if ( !v1->isERestricted() ) restricted = false;
|
||||
} else if ( c1->isWest (c2) ) {
|
||||
if ( !v1->isWRestricted() ) restricted = false;
|
||||
} else {
|
||||
cerr << Error( "GCells are not side by side." ) << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( (c1->getWidth() < hpitch)
|
||||
||(c1->getHeight() < vpitch)
|
||||
||(restricted)
|
||||
) return true;
|
||||
else {
|
||||
restricted = true;
|
||||
// Check from GCell 2
|
||||
if ( c2->isNorth(c1) and not v2->isNRestricted() ) restricted = false;
|
||||
else if ( c2->isSouth(c1) and not v2->isSRestricted() ) restricted = false;
|
||||
else if ( c2->isEast (c1) and not v2->isERestricted() ) restricted = false;
|
||||
else if ( c2->isWest (c1) and not v2->isWRestricted() ) restricted = false;
|
||||
// else {
|
||||
// cerr << Error( "Vertex::isRestricted(): Vertexes/GCells v1 & v2 do not share a side.\n"
|
||||
// " v1:%s\n"
|
||||
// " v2:%s"
|
||||
// , getString(v1).c_str()
|
||||
// , getString(v2).c_str()
|
||||
// ) << endl;
|
||||
// return true;
|
||||
// }
|
||||
|
||||
if (restricted) {
|
||||
cdebug_log(112,0) << "v2 -> v1 edge is restricted." << endl;
|
||||
if ( c2->isNorth(c1) ) {
|
||||
if ( !v2->isNRestricted() ) restricted = false;
|
||||
} else if ( c2->isSouth(c1) ) {
|
||||
if ( !v2->isSRestricted() ) restricted = false;
|
||||
} else if ( c2->isEast (c1) ) {
|
||||
if ( !v2->isERestricted() ) restricted = false;
|
||||
} else if ( c2->isWest (c1) ) {
|
||||
if ( !v2->isWRestricted() ) restricted = false;
|
||||
} else {
|
||||
cerr << Error( "GCells are not side by side." ) << endl;
|
||||
return true;
|
||||
}
|
||||
if ( e->isVertical() and (c2->getWidth() < hpitch) ) {
|
||||
cdebug_log(112,0) << "GCell 2 is too narrow for V edges." << endl;
|
||||
return true;
|
||||
}
|
||||
if ( e->isHorizontal() and (c2->getHeight() < vpitch) ) {
|
||||
cdebug_log(112,0) << "GCell 2 is too narrow for H edges." << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( v2->getGCell()->isStrut() and e->isMaxCapacity(net) ) {
|
||||
if ( (c2->getWidth() < hpitch)
|
||||
||(c2->getHeight() < vpitch)
|
||||
||(restricted)
|
||||
) return true;
|
||||
else {
|
||||
if ((v2->getGCell()->isStrut())){
|
||||
if (e->isMaxCapacity(net)) {
|
||||
cdebug_log(112,0) << "Overcapacity:" << e << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
else return false;
|
||||
} else return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1359,7 +1341,7 @@ namespace Anabatic {
|
|||
PriorityQueue* PriorityQueue::CompareByDistance::_pqueue = NULL;
|
||||
|
||||
|
||||
bool PriorityQueue::CompareByDistance::operator() ( const Vertex* lhs, const Vertex* rhs ) const
|
||||
bool PriorityQueue::CompareByDistance::operator() ( const Vertex* lhs, const Vertex* rhs )
|
||||
{
|
||||
if (lhs->getDistance() == rhs->getDistance()) {
|
||||
if (_pqueue and _pqueue->hasAttractor()) {
|
||||
|
@ -1459,10 +1441,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
DbU::Unit Dijkstra::getAntennaGateMaxWL () const
|
||||
{ return _anabatic->getAntennaGateMaxWL(); }
|
||||
|
||||
|
||||
Point Dijkstra::_getPonderedPoint() const
|
||||
{
|
||||
vector<RoutingPad*> rps;
|
||||
|
@ -1484,48 +1462,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
void Dijkstra::loadFixedGlobal ( Net* net )
|
||||
{
|
||||
NetData* netData = _anabatic->getNetData( net );
|
||||
netData->setGlobalRouted( true );
|
||||
netData->setGlobalFixed ( true );
|
||||
|
||||
for ( Component* component : net->getComponents() ) {
|
||||
Horizontal* horizontal = dynamic_cast<Horizontal*>( component );
|
||||
if (horizontal) {
|
||||
if (not Session::isGLayer(horizontal->getLayer())) {
|
||||
cerr << Error( "Dijsktra::loadFixedGlobal(): A component of \"%s\" has not a global layer.\n"
|
||||
" (%s)"
|
||||
, getString(net->getName()).c_str()
|
||||
, getString(component).c_str()
|
||||
) << endl;
|
||||
continue;
|
||||
}
|
||||
GCell* begin = _anabatic->getGCellUnder( horizontal->getSource()->getPosition() );
|
||||
GCell* end = _anabatic->getGCellUnder( horizontal->getTarget()->getPosition() );
|
||||
for ( Edge* edge : _anabatic->getEdgesUnderPath(begin,end) )
|
||||
edge->add( horizontal );
|
||||
}
|
||||
|
||||
Vertical* vertical = dynamic_cast<Vertical*>( component );
|
||||
if (vertical) {
|
||||
if (not Session::isGLayer(vertical->getLayer())) {
|
||||
cerr << Error( "Dijsktra::loadFixedGlobal(): A component of \"%s\" has not a global layer.\n"
|
||||
" (%s)"
|
||||
, getString(net->getName()).c_str()
|
||||
, getString(component).c_str()
|
||||
) << endl;
|
||||
continue;
|
||||
}
|
||||
GCell* begin = _anabatic->getGCellUnder( vertical->getSource()->getPosition() );
|
||||
GCell* end = _anabatic->getGCellUnder( vertical->getTarget()->getPosition() );
|
||||
for ( Edge* edge : _anabatic->getEdgesUnderPath(begin,end,Flags::NorthPath) )
|
||||
edge->add( vertical );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Dijkstra::load ( Net* net )
|
||||
{
|
||||
_cleanup();
|
||||
|
@ -1543,7 +1479,6 @@ namespace Anabatic {
|
|||
if (state->isSelfSym()) {
|
||||
cdebug_log(112,0) << "Dijkstra::SELF SYMMETRY CASE " << DbU::getValueString(state->getSymAxis()) << endl;
|
||||
}
|
||||
state->unsetFlags( NetRoutingState::HasAntenna );
|
||||
}
|
||||
|
||||
for ( Component* component : _net->getComponents() ) {
|
||||
|
@ -1553,15 +1488,12 @@ namespace Anabatic {
|
|||
|
||||
cdebug_log(112,0) << "@ frp:" << rp << endl;
|
||||
rps.push_back( rp );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (rps.size() < 2) {
|
||||
cdebug_tabw(112,-1);
|
||||
return;
|
||||
}
|
||||
if (rps.size() < 2) return;
|
||||
|
||||
uint32_t driverCount = 0;
|
||||
for ( auto rp : rps ) {
|
||||
if (not _anabatic->getConfiguration()->selectRpComponent(rp))
|
||||
cerr << Warning( "Dijktra::load(): %s has no components on grid.", getString(rp).c_str() ) << endl;
|
||||
|
@ -1570,12 +1502,11 @@ namespace Anabatic {
|
|||
Point center = rp->getBoundingBox().getCenter();
|
||||
GCell* gcell = _anabatic->getGCellUnder( center );
|
||||
Box bb = rp->getBoundingBox();
|
||||
bool isDriver = false;
|
||||
|
||||
cdebug_log(112,0) << bb.getXMin() << " " << bb.getXMax() << endl;
|
||||
cdebug_log(112,0) << "center X:" << center.getX() << " gcell Xmax:" << gcell->getXMax() << endl;
|
||||
|
||||
if (state and state->isSymmetric()) _limitSymSearchArea( rp );
|
||||
_limitSymSearchArea(rp); // ANALOG
|
||||
|
||||
if (not gcell) {
|
||||
cerr << Error( "Dijkstra::load(): %s\n"
|
||||
|
@ -1588,29 +1519,6 @@ namespace Anabatic {
|
|||
continue;
|
||||
}
|
||||
|
||||
Net* rpNet = NULL;
|
||||
Plug* plug = dynamic_cast<Plug*>( rp->getPlugOccurrence().getEntity() );
|
||||
if (plug) {
|
||||
rpNet = plug->getMasterNet();
|
||||
if (rpNet->getDirection() & Net::Direction::DirOut) {
|
||||
cdebug_log(112,0) << "Driver/cell: " << rp << endl;
|
||||
cdebug_log(112,0) << "masterNet: " << rpNet << endl;
|
||||
++driverCount;
|
||||
isDriver = true;
|
||||
}
|
||||
} else {
|
||||
Pin* pin = dynamic_cast<Pin*>( rp->getPlugOccurrence().getEntity() );
|
||||
if (pin) {
|
||||
rpNet = pin->getNet();
|
||||
if (rpNet->getDirection() & Net::Direction::DirIn) {
|
||||
cdebug_log(112,0) << "Driver/pin: " << rp << endl;
|
||||
cdebug_log(112,0) << "masterNet: " << rpNet << endl;
|
||||
++driverCount;
|
||||
isDriver = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_searchArea.merge( gcell->getBoundingBox() ); // TO CHANGE
|
||||
cdebug_log(112,0) << "| Merged search area: " << _searchArea << ", gcell: " << gcell << endl;
|
||||
|
||||
|
@ -1627,7 +1535,6 @@ namespace Anabatic {
|
|||
|
||||
++_connectedsId;
|
||||
for ( Vertex* vertex : connecteds ) {
|
||||
vertex->getGCell()->flags().reset( Flags::GoStraight );
|
||||
vertex->setDistance ( Vertex::unreached );
|
||||
vertex->setStamp ( _stamp );
|
||||
vertex->setConnexId ( _connectedsId );
|
||||
|
@ -1635,8 +1542,6 @@ namespace Anabatic {
|
|||
vertex->setDegree ( 0 );
|
||||
vertex->setRpCount ( 0 );
|
||||
vertex->setFrom ( NULL );
|
||||
if (isDriver)
|
||||
vertex->setDriver( true );
|
||||
|
||||
vertex->setFrom2 ( NULL);
|
||||
vertex->unsetFlags ( Vertex::UseFromFrom2 );
|
||||
|
@ -1662,45 +1567,6 @@ namespace Anabatic {
|
|||
rp->getBodyHook()->attach( vcontact->getBodyHook() );
|
||||
}
|
||||
|
||||
if (driverCount == 0) {
|
||||
cerr << Error( "Diskstra::load(): Net \"%s\" do not have a driver.\n"
|
||||
, getString(_net->getName()).c_str()
|
||||
) << endl;
|
||||
}
|
||||
if (driverCount > 1) {
|
||||
cerr << Error( "Diskstra::load(): Net \"%s\" have multiple drivers (%u).\n"
|
||||
, getString(_net->getName()).c_str(), driverCount
|
||||
) << endl;
|
||||
}
|
||||
|
||||
if (state and state->isSymmetric() and not state->isSelfSym() and state->isSymMaster()) {
|
||||
if (state->isSymVertical()) {
|
||||
if ( (_searchArea.getXMin() < state->getSymAxis())
|
||||
and (_searchArea.getXMax() > state->getSymAxis()) ) {
|
||||
cerr << Error( "Diskstra::load(): For net \"%s\" (paired with \"%s\"),\n"
|
||||
" Vertical symmetry axis @%s is inside the net area %s."
|
||||
, getString(_net->getName()).c_str()
|
||||
, getString(state->getSymNet()->getName()).c_str()
|
||||
, DbU::getValueString(state->getSymAxis()).c_str()
|
||||
, getString(_searchArea).c_str()
|
||||
) << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (state->isSymHorizontal()) {
|
||||
if ( (_searchArea.getYMin() < state->getSymAxis())
|
||||
and (_searchArea.getYMax() > state->getSymAxis()) ) {
|
||||
cerr << Error( "Diskstra::load(): For net \"%s\" (paired with \"%s\"),\n"
|
||||
" Horizontal symmetry axis @%s is inside the net area %s."
|
||||
, getString(_net->getName()).c_str()
|
||||
, getString(state->getSymNet()->getName()).c_str()
|
||||
, DbU::getValueString(state->getSymAxis()).c_str()
|
||||
, getString(_searchArea).c_str()
|
||||
) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_searchArea.inflate( _searchAreaHalo );
|
||||
cdebug_log(112,0) << "Search halo: " << DbU::getValueString(_searchAreaHalo) << endl;
|
||||
cdebug_log(112,0) << "Search area: " << _searchArea << endl;
|
||||
|
@ -1850,14 +1716,7 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
Vertex* firstSource = NULL;
|
||||
VertexSet drivers;
|
||||
|
||||
for ( Vertex* vertex : _targets ) {
|
||||
if (vertex->isDriver()) drivers.insert( vertex );
|
||||
}
|
||||
if (drivers.empty()) drivers = _targets;
|
||||
|
||||
#if THIS_IS_DISABLED
|
||||
if (_mode & Mode::Monotonic) {
|
||||
if (_targets.size() == 2) {
|
||||
auto ivertex = _targets.begin();
|
||||
|
@ -1874,25 +1733,24 @@ namespace Anabatic {
|
|||
_mode = Mode::Standart;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (not firstSource) {
|
||||
// Standart routing.
|
||||
bool hasDevice = false;
|
||||
for ( Vertex* vertex : drivers ) {
|
||||
if (vertex->getGCell()->isDevice()) hasDevice = true;
|
||||
for ( Vertex* ivertex : _targets ) {
|
||||
if (ivertex->getGCell()->isDevice()) hasDevice = true;
|
||||
}
|
||||
|
||||
Point areaCenter;
|
||||
if (hasDevice) areaCenter = _getPonderedPoint();
|
||||
else areaCenter = _searchArea.getCenter();
|
||||
|
||||
auto ivertex = drivers.begin();
|
||||
auto ivertex = _targets.begin();
|
||||
|
||||
firstSource = *ivertex++;
|
||||
DbU::Unit minDistance = areaCenter.manhattanDistance( firstSource->getCenter() );
|
||||
|
||||
for ( ; ivertex != drivers.end() ; ++ivertex ) {
|
||||
for ( ; ivertex != _targets.end() ; ++ivertex ) {
|
||||
DbU::Unit distance = areaCenter.manhattanDistance( (*ivertex)->getCenter() );
|
||||
if (distance < minDistance) {
|
||||
minDistance = distance;
|
||||
|
@ -2201,7 +2059,6 @@ namespace Anabatic {
|
|||
|
||||
if (_sources.size() < 2) { cdebug_tabw(112,-1); return; }
|
||||
|
||||
DbU::Unit gWL = 0;
|
||||
NetRoutingState* state = NetRoutingExtension::get( _net );
|
||||
//cerr << "state: " << state << endl;
|
||||
|
||||
|
@ -2292,8 +2149,6 @@ namespace Anabatic {
|
|||
, constraint.getCenter()
|
||||
, width
|
||||
);
|
||||
gWL += segment->getLength();
|
||||
cdebug_log(112,0) << "| ref: " << segment << endl;
|
||||
|
||||
for ( Edge* through : aligneds ) through->add( segment );
|
||||
if (state) {
|
||||
|
@ -2312,8 +2167,6 @@ namespace Anabatic {
|
|||
, constraint.getCenter()
|
||||
, width
|
||||
);
|
||||
gWL += segment->getLength();
|
||||
cdebug_log(112,0) << "| ref: " << segment << endl;
|
||||
|
||||
for ( Edge* through : aligneds ) through->add( segment );
|
||||
if (state) {
|
||||
|
@ -2330,14 +2183,6 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
|
||||
if (gWL > getAntennaGateMaxWL()) {
|
||||
cdebug_log(113,0) << "| \"" << _net->getName() << "\" may have antenna effect, "
|
||||
<< DbU::getValueString(gWL)
|
||||
<< endl;
|
||||
if (state)
|
||||
state->setFlags( NetRoutingState::HasAntenna );
|
||||
}
|
||||
|
||||
cdebug_tabw(112,-1);
|
||||
}
|
||||
|
||||
|
@ -2484,66 +2329,51 @@ namespace Anabatic {
|
|||
|
||||
void Dijkstra::_createSelfSymSeg ( Segment* segment )
|
||||
{
|
||||
cdebug_log(112,1) << "Dijkstra::_createSelfSymSeg(): " << segment << endl;
|
||||
|
||||
cdebug_log(112,0) << "void Dijkstra::_createSelfSymSeg ( Segment* segment ): " << _net << ", seg: " << segment << endl;
|
||||
NetRoutingState* state = NetRoutingExtension::get( _net );
|
||||
if (state and segment) {
|
||||
//cdebug_log(112,0) << "state: " << state << endl;
|
||||
if ((state != NULL)&&(segment!=NULL)){
|
||||
Horizontal* h = dynamic_cast<Horizontal*>(segment);
|
||||
Vertical* v = dynamic_cast<Vertical *>(segment);
|
||||
Point sp;
|
||||
Point tp;
|
||||
Vertical* v = dynamic_cast<Vertical*>(segment);
|
||||
Point sp, tp;
|
||||
DbU::Unit axis;
|
||||
Component* sourceContact = segment->getSource();
|
||||
Component* targetContact = segment->getTarget();
|
||||
|
||||
cdebug_log(112,0) << "source: " << sourceContact << endl;
|
||||
cdebug_log(112,0) << "target: " << targetContact << endl;
|
||||
cdebug_log(112,0) << "sym axis: " << DbU::getValueString(state->getSymAxis()) << endl;
|
||||
|
||||
if (h) {
|
||||
if (state->isSymHorizontal()) {
|
||||
cdebug_log(112,0) << "Horizontal + Horizontal symmetry." << endl;
|
||||
|
||||
sp = Point( sourceContact->getX(), state->getSymValue(sourceContact->getY()) );
|
||||
tp = Point( targetContact->getX(), state->getSymValue(targetContact->getY()) );
|
||||
axis = state->getSymValue( segment->getY() );
|
||||
} else if (state->isSymVertical()) {
|
||||
cdebug_log(112,0) << "Horizontal + Vertical symmetry." << endl;
|
||||
|
||||
if (h){
|
||||
if (state->isSymHorizontal()){
|
||||
cdebug_log(112,0) << "H case Horizontal" << endl;
|
||||
sp = Point(sourceContact->getX(), state->getSymValue(sourceContact->getY()) );
|
||||
tp = Point(targetContact->getX(), state->getSymValue(targetContact->getY()) );
|
||||
axis = state->getSymValue(segment->getY());
|
||||
} else if (state->isSymVertical()){
|
||||
cdebug_log(112,0) << "H case Vertical" << endl;
|
||||
sp = Point( state->getSymValue(targetContact->getX()), targetContact->getY() );
|
||||
tp = Point( state->getSymValue(sourceContact->getX()), sourceContact->getY() );
|
||||
axis = segment->getY();
|
||||
} else {
|
||||
cdebug_log(112,0) << "Dijkstra::_materialize(): Horizontal + Unknown symmetry. " << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
cdebug_log(112,0) << "Dijkstra::_materialize(): Something is wrong here. " << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
cdebug_log(112,0) << "sp: " << sp << endl;
|
||||
cdebug_log(112,0) << "tp: " << tp << endl;
|
||||
|
||||
//cerr << "sp: " << sp << endl;
|
||||
//cerr << "tp: " << tp << endl;
|
||||
GCell* sgcell = _anabatic->getGCellUnder( sp );
|
||||
GCell* tgcell = _anabatic->getGCellUnder( tp );
|
||||
|
||||
cdebug_log(112,0) << "GCell: " << sgcell << endl;
|
||||
cdebug_log(112,0) << "GCell: " << tgcell << endl;
|
||||
|
||||
//cerr << "Gcell: " << sgcell << endl;
|
||||
//cerr << "Gcell: " << tgcell << endl;
|
||||
Vertex* svertex = sgcell->getObserver<Vertex>(GCell::Observable::Vertex);
|
||||
Vertex* tvertex = tgcell->getObserver<Vertex>(GCell::Observable::Vertex);
|
||||
|
||||
Contact* sourceSym = NULL;
|
||||
Contact* targetSym = NULL;
|
||||
if (state->isSelfSym()) {
|
||||
cdebug_log(112,0) << "Symmetrical to myself (isSelfSym)." << endl;
|
||||
if (state->isSelfSym()){
|
||||
cdebug_log(112,0) << "isSelfSym" << endl;
|
||||
sourceSym = svertex->getGContact( _net );
|
||||
targetSym = tvertex->getGContact( _net );
|
||||
} else if (state->isSymMaster()){
|
||||
cdebug_log(112,0) << "Symmetrical to (isSymPair): " << state->getSymNet() << endl;
|
||||
cdebug_log(112,0) << "isSymPair: " << state->getSymNet() << endl;
|
||||
sourceSym = svertex->getGContact( state->getSymNet() );
|
||||
targetSym = tvertex->getGContact( state->getSymNet() );
|
||||
} else {
|
||||
cdebug_log(112,0) << "Dijkstra::_materialize(): Unknown Net pairing symmetry. " << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
cdebug_log(112,0) << "Dijkstra::_materialize(): Something is wrong with the symmetry. " << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2555,7 +2385,7 @@ namespace Anabatic {
|
|||
, axis
|
||||
, state->getWPitch()*Session::getPitch(Hurricane::DataBase::getDB()->getTechnology()->getLayer("METAL2"))
|
||||
);
|
||||
cdebug_log(112,0) << "| dup:" << segment2 << endl;
|
||||
cdebug_log(112,0) << "|| " << segment2 << endl;
|
||||
} else if (v) {
|
||||
if (state->isSymVertical()){
|
||||
//cerr << "V case Vertical" << endl;
|
||||
|
@ -2569,7 +2399,6 @@ namespace Anabatic {
|
|||
axis = segment->getX();
|
||||
} else {
|
||||
cdebug_log(112,0) << "Dijkstra::_materialize(): Something is wrong here. " << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
return;
|
||||
}
|
||||
GCell* sgcell = _anabatic->getGCellUnder( sp );
|
||||
|
@ -2586,7 +2415,6 @@ namespace Anabatic {
|
|||
targetSym = tvertex->getGContact( state->getSymNet() );
|
||||
} else {
|
||||
cdebug_log(112,0) << "Dijkstra::_materialize(): Something is wrong with the symmetry. " << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2601,7 +2429,6 @@ namespace Anabatic {
|
|||
cdebug_log(112,0) << "|| " << segment2 << endl;
|
||||
}
|
||||
}
|
||||
cdebug_tabw(112,-1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2873,8 +2700,8 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_log(112,0) << "void Dijkstra::_setSourcesGRAData() : " << seed << endl;
|
||||
GCell* gseed = seed->getGCell();
|
||||
Horizontal* h = dynamic_cast<Horizontal*>(rp->_getEntityAs<Segment>());
|
||||
Vertical* v = dynamic_cast<Vertical*> (rp->_getEntityAs<Segment>());
|
||||
Horizontal* h = dynamic_cast<Horizontal*>(rp->_getEntityAsSegment());
|
||||
Vertical* v = dynamic_cast<Vertical*> (rp->_getEntityAsSegment());
|
||||
if (h) {
|
||||
cdebug_log(112,0) << "case H " << endl;
|
||||
seed->unsetFlags(Vertex::iHorizontal);
|
||||
|
|
|
@ -29,31 +29,16 @@ namespace {
|
|||
|
||||
using namespace std;
|
||||
using namespace Hurricane;
|
||||
using Anabatic::NetData;
|
||||
using Anabatic::AnabaticEngine;
|
||||
|
||||
|
||||
class SortSegmentByLength {
|
||||
public:
|
||||
inline SortSegmentByLength ( AnabaticEngine* );
|
||||
inline bool operator() ( const Segment*, const Segment* );
|
||||
private:
|
||||
AnabaticEngine* _anabatic;
|
||||
};
|
||||
|
||||
|
||||
inline 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;
|
||||
|
@ -371,15 +356,15 @@ namespace Anabatic {
|
|||
size_t Edge::ripup ()
|
||||
{
|
||||
AnabaticEngine* anabatic = getAnabatic();
|
||||
DbU::Unit globalThreshold = Session::getSliceHeight()*3;
|
||||
size_t netCount = 0;
|
||||
|
||||
sort( _segments.begin(), _segments.end(), SortSegmentByLength(anabatic) );
|
||||
sort( _segments.begin(), _segments.end(), SortSegmentByLength() );
|
||||
|
||||
if (Session::getRoutingGauge()->isTwoMetals()) {
|
||||
for ( size_t i=0 ; i<_segments.size() ; ) {
|
||||
if (not isEnding(_segments[i])) {
|
||||
NetData* netData = anabatic->getNetData( _segments[i]->getNet() );
|
||||
if (netData->isGlobalFixed ()) break;
|
||||
if (netData->isGlobalRouted()) ++netCount;
|
||||
anabatic->ripup( _segments[i], Flags::Propagate );
|
||||
continue;
|
||||
|
@ -390,12 +375,10 @@ namespace Anabatic {
|
|||
size_t truncate = (size_t)( (getCapacity()*2) / 3 );
|
||||
while ( _segments.size() > truncate ) {
|
||||
NetData* netData = anabatic->getNetData( _segments[truncate]->getNet() );
|
||||
if (netData->isGlobalFixed ()) break;
|
||||
if (netData->isGlobalRouted()) ++netCount;
|
||||
anabatic->ripup( _segments[truncate], Flags::Propagate );
|
||||
}
|
||||
|
||||
// DbU::Unit globalThreshold = Session::getSliceHeight()*3;
|
||||
// for ( size_t i=0 ; i<_segments.size() ; ) {
|
||||
// if (_segments[i]->getLength() >= globalThreshold) {
|
||||
// NetData* netData = anabatic->getNetData( _segments[i]->getNet() );
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace {
|
|||
private:
|
||||
class AxisCompare {
|
||||
public:
|
||||
bool operator() ( const Axis* lhs, const Axis* rhs ) const;
|
||||
bool operator() ( const Axis* lhs, const Axis* rhs );
|
||||
};
|
||||
|
||||
class AxisMatch : public unary_function<Axis*,bool> {
|
||||
|
@ -155,7 +155,7 @@ namespace {
|
|||
}
|
||||
|
||||
|
||||
inline bool UsedFragments::AxisCompare::operator() ( const Axis* lhs, const Axis* rhs ) const
|
||||
inline bool UsedFragments::AxisCompare::operator() ( const Axis* lhs, const Axis* rhs )
|
||||
{
|
||||
if (lhs->getAxis () < rhs->getAxis ()) return true;
|
||||
return false;
|
||||
|
@ -259,7 +259,7 @@ namespace Anabatic {
|
|||
{ }
|
||||
|
||||
|
||||
bool GCell::CompareByDensity::operator() ( GCell* lhs, GCell* rhs ) const
|
||||
bool GCell::CompareByDensity::operator() ( GCell* lhs, GCell* rhs )
|
||||
{
|
||||
float difference = lhs->getDensity(_depth) - rhs->getDensity(_depth);
|
||||
if (difference != 0.0) return (difference > 0.0);
|
||||
|
@ -285,7 +285,7 @@ namespace Anabatic {
|
|||
: Super(anabatic->getCell())
|
||||
, _observable ()
|
||||
, _anabatic (anabatic)
|
||||
, _flags (Flags::Invalidated)
|
||||
, _flags (Flags::HChannelGCell|Flags::Invalidated)
|
||||
, _westEdges ()
|
||||
, _eastEdges ()
|
||||
, _southEdges ()
|
||||
|
@ -298,8 +298,6 @@ namespace Anabatic {
|
|||
, _contacts ()
|
||||
, _depth (Session::getRoutingGauge()->getDepth())
|
||||
, _pinDepth (0)
|
||||
, _satProcessed (0)
|
||||
, _rpCount (0)
|
||||
, _blockages (new DbU::Unit [_depth])
|
||||
, _cDensity (0.0)
|
||||
, _densities (new float [_depth])
|
||||
|
@ -307,7 +305,6 @@ namespace Anabatic {
|
|||
, _fragmentations(new float [_depth])
|
||||
, _globalsCount (new float [_depth])
|
||||
, _key (this,1)
|
||||
, _lastClonedKey (NULL)
|
||||
{
|
||||
if (not _matrixHSide) {
|
||||
_matrixVSide = Session::getSliceHeight();
|
||||
|
@ -477,26 +474,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
bool GCell::hasNet ( const Net* net ) const
|
||||
{
|
||||
if (hasGContact(net)) return true;
|
||||
|
||||
for ( Edge* edge : _eastEdges ) {
|
||||
for ( Segment* segment : edge->getSegments() ) {
|
||||
if (segment->getNet() == net) return true;
|
||||
}
|
||||
}
|
||||
|
||||
for ( Edge* edge : _northEdges ) {
|
||||
for ( Segment* segment : edge->getSegments() ) {
|
||||
if (segment->getNet() == net) return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Contact* GCell::hasGContact ( const Contact* owned ) const
|
||||
{
|
||||
for ( Contact* contact : _gcontacts ) {
|
||||
|
@ -529,22 +506,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
Segment* GCell::hasGoThrough ( Net* net ) const
|
||||
{
|
||||
for ( Edge* edge : _eastEdges ) {
|
||||
for ( Segment* segment : edge->getSegments() ) {
|
||||
if (segment->getNet() == net) return segment;
|
||||
}
|
||||
}
|
||||
for ( Edge* edge : _northEdges ) {
|
||||
for ( Segment* segment : edge->getSegments() ) {
|
||||
if (segment->getNet() == net) return segment;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
Edge* GCell::getEdgeTo ( GCell* neighbor, Flags sideHint ) const
|
||||
{
|
||||
for ( Edge* edge : getEdges(sideHint) ) {
|
||||
|
@ -1254,7 +1215,7 @@ namespace Anabatic {
|
|||
int GCell::getCapacity ( size_t depth ) const
|
||||
{
|
||||
const vector<Edge*>* edges = NULL;
|
||||
if (isHorizontalPlane(depth)) edges = (_eastEdges .empty()) ? &_westEdges : &_eastEdges;
|
||||
if (isHorizontalPlane(depth)) edges = (_eastEdges .empty()) ? &_westEdges : &_westEdges;
|
||||
else edges = (_northEdges.empty()) ? &_southEdges : &_northEdges;
|
||||
|
||||
int capacity = 0;
|
||||
|
@ -1343,26 +1304,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
void GCell::postGlobalAnnotate ()
|
||||
{
|
||||
if (isInvalidated()) updateDensity();
|
||||
|
||||
for ( size_t depth=0 ; depth<_depth ; ++depth ) {
|
||||
RoutingLayerGauge* rlg = Session::getLayerGauge( depth );
|
||||
if (rlg->getType() & Constant::PinOnly) continue;
|
||||
if (_densities[depth] >= 0.9) {
|
||||
if (depth+2 < _depth) {
|
||||
Edge* edge = (rlg->getDirection() == Constant::Vertical) ? getNorthEdge()
|
||||
: getEastEdge();
|
||||
if (edge) {
|
||||
edge->reserveCapacity( 2 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GCell::addBlockage ( size_t depth, DbU::Unit length )
|
||||
{
|
||||
if (depth >= _depth) return;
|
||||
|
@ -1370,7 +1311,7 @@ namespace Anabatic {
|
|||
_blockages[depth] += length;
|
||||
_flags |= Flags::Invalidated;
|
||||
|
||||
cdebug_log(149,0) << "GCell::addBlockage() " << this << " "
|
||||
cdebug_log(149,0) << "GCell:addBlockage() " << this << " "
|
||||
<< depth << ":" << DbU::getValueString(_blockages[depth]) << endl;
|
||||
}
|
||||
|
||||
|
@ -1391,7 +1332,6 @@ namespace Anabatic {
|
|||
if (found) {
|
||||
cdebug_log(149,0) << "remove " << ac << " from " << this << endl;
|
||||
_contacts.pop_back();
|
||||
_flags |= Flags::Invalidated;
|
||||
} else {
|
||||
cerr << Bug("%p:%s do not belong to %s."
|
||||
,ac->base(),getString(ac).c_str(),_getString().c_str()) << endl;
|
||||
|
@ -1405,17 +1345,11 @@ namespace Anabatic {
|
|||
size_t begin = 0;
|
||||
|
||||
for ( ; begin < end ; begin++ ) {
|
||||
if (not _hsegments[begin])
|
||||
cerr << Bug( "GCell::removeHSegment(): In %s, NULL segment at [%u/%u]."
|
||||
, _getString().c_str(), begin, _hsegments.size() ) << endl;
|
||||
|
||||
if (_hsegments[begin] == segment) std::swap( _hsegments[begin], _hsegments[--end] );
|
||||
cdebug_log(9000,0) << "GCell::removeHSegment() " << this << endl;
|
||||
cdebug_log(9000,0) << " " << segment << endl;
|
||||
}
|
||||
|
||||
if (_hsegments.size() == end) {
|
||||
cerr << Bug( "GCell::removeHSegment(): %s do not go through %s."
|
||||
cerr << Bug( "%s do not go through %s."
|
||||
, getString(segment).c_str(), _getString().c_str() ) << endl;
|
||||
return;
|
||||
}
|
||||
|
@ -1425,7 +1359,6 @@ namespace Anabatic {
|
|||
, _getString().c_str(), getString(segment).c_str() ) << endl;
|
||||
|
||||
_hsegments.erase( _hsegments.begin() + end, _hsegments.end() );
|
||||
_flags |= Flags::Invalidated;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1451,7 +1384,6 @@ namespace Anabatic {
|
|||
, getString(segment).c_str() ) << endl;
|
||||
|
||||
_vsegments.erase( _vsegments.begin() + end, _vsegments.end() );
|
||||
_flags |= Flags::Invalidated;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1465,6 +1397,11 @@ namespace Anabatic {
|
|||
|
||||
_flags.reset( Flags::Saturated );
|
||||
|
||||
for ( size_t i=0 ; i<_vsegments.size() ; i++ ) {
|
||||
if ( _vsegments[i] == NULL )
|
||||
cerr << "NULL Autosegment at index " << i << endl;
|
||||
}
|
||||
|
||||
sort( _hsegments.begin(), _hsegments.end(), AutoSegment::CompareByDepthLength() );
|
||||
sort( _vsegments.begin(), _vsegments.end(), AutoSegment::CompareByDepthLength() );
|
||||
|
||||
|
@ -1551,26 +1488,7 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
// Add the blockages.
|
||||
if (isStdCellRow() or isChannelRow()) {
|
||||
flags().reset( Flags::GoStraight );
|
||||
} else {
|
||||
int contiguousNonSaturated = 0;
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) {
|
||||
uLengths2[i] += _blockages[i];
|
||||
if (Session::getLayerGauge(i)->getType() & Constant::PinOnly)
|
||||
continue;
|
||||
if (Session::getLayerGauge(i)->getType() & Constant::PowerSupply)
|
||||
continue;
|
||||
if ((float)(_blockages[i] * Session::getPitch(i)) > 0.60*(float)(width*height))
|
||||
contiguousNonSaturated = 0;
|
||||
else
|
||||
contiguousNonSaturated++;
|
||||
}
|
||||
if (contiguousNonSaturated < 2) {
|
||||
flags() |= Flags::GoStraight;
|
||||
//cerr << "| Set GoStraight on " << this << endl;
|
||||
}
|
||||
}
|
||||
for ( size_t i=0 ; i<_depth ; i++ ) uLengths2[i] += _blockages[i];
|
||||
|
||||
// Compute the number of non pass-through tracks.
|
||||
if (not processeds.empty()) {
|
||||
|
@ -1580,8 +1498,7 @@ namespace Anabatic {
|
|||
size_t depth = Session::getRoutingGauge()->getLayerDepth(layer);
|
||||
size_t count = 0;
|
||||
for ( ; isegment != processeds.end(); ++isegment ) {
|
||||
//_feedthroughs[depth] += ((*isegment)->isGlobal()) ? 0.50 : 0.33;
|
||||
_feedthroughs[depth] += 0.50;
|
||||
_feedthroughs[depth] += ((*isegment)->isGlobal()) ? 0.50 : 0.33;
|
||||
localCounts [depth] += 1.0;
|
||||
if ( (*isegment)->isGlobal() ) _globalsCount[depth] += 1.0;
|
||||
|
||||
|
@ -1819,7 +1736,7 @@ namespace Anabatic {
|
|||
|
||||
bool GCell::stepNetDesaturate ( size_t depth, set<Net*>& globalNets, GCell::Set& invalidateds )
|
||||
{
|
||||
cdebug_log(149,0) << "GCell::stepNetDesaturate() depth:" << depth << endl;
|
||||
cdebug_log(9000,0) << "Deter| GCell::stepNetDesaturate() depth:" << depth << endl;
|
||||
cdebug_log(9000,0) << "Deter| " << this << endl;
|
||||
|
||||
updateDensity();
|
||||
|
@ -1841,7 +1758,7 @@ namespace Anabatic {
|
|||
if (segmentDepth < depth) continue;
|
||||
if (segmentDepth > depth) break;
|
||||
|
||||
cdebug_log(149,0) << "Move up " << (*isegment) << endl;
|
||||
cdebug_log(9000,0) << "Deter| Move up " << (*isegment) << endl;
|
||||
|
||||
if (getAnabatic()->moveUpNetTrunk(*isegment,globalNets,invalidateds))
|
||||
return true;
|
||||
|
@ -1873,7 +1790,6 @@ namespace Anabatic {
|
|||
string s = Super::_getString();
|
||||
s.insert( s.size()-1, " "+getString(getBoundingBox()) );
|
||||
s.insert( s.size()-1, " "+getString(_flags) );
|
||||
s.insert( s.size()-1, " "+getString(_rpCount) );
|
||||
/* string s = "<GCell at(" + DbU::getValueString(getXMin())
|
||||
+ "-" + DbU::getValueString(getYMin())
|
||||
+ "-" + DbU::getValueString(getXMax())
|
||||
|
@ -1906,7 +1822,7 @@ namespace Anabatic {
|
|||
ostringstream s;
|
||||
const Layer* layer = rg->getRoutingLayer(depth)->getBlockageLayer();
|
||||
s << "_blockages[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
|
||||
record->add( DbU::getValueSlot( s.str(), &_blockages[depth] ) );
|
||||
record->add( getSlot ( s.str(), &_blockages[depth] ) );
|
||||
}
|
||||
|
||||
for ( size_t depth=0 ; depth<_depth ; ++depth ) {
|
||||
|
@ -1915,13 +1831,6 @@ namespace Anabatic {
|
|||
s << "_densities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
|
||||
record->add( getSlot ( s.str(), &_densities[depth] ) );
|
||||
}
|
||||
|
||||
for ( size_t depth=0 ; depth<_depth ; ++depth ) {
|
||||
ostringstream s;
|
||||
const Layer* layer = rg->getRoutingLayer(depth);
|
||||
s << "_feedthroughs[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
|
||||
record->add( getSlot ( s.str(), &_feedthroughs[depth] ) );
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,288 +31,11 @@
|
|||
#include "hurricane/Horizontal.h"
|
||||
#include "hurricane/Cell.h"
|
||||
#include "crlcore/RoutingGauge.h"
|
||||
#include "anabatic/AutoContactTerminal.h"
|
||||
#include "anabatic/AutoContact.h"
|
||||
#include "anabatic/AutoSegment.h"
|
||||
#include "anabatic/AnabaticEngine.h"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
|
||||
using namespace std;
|
||||
using namespace CRL;
|
||||
using namespace Hurricane;
|
||||
using namespace Anabatic;
|
||||
|
||||
|
||||
class SortRpByX {
|
||||
public:
|
||||
inline SortRpByX ();
|
||||
inline bool operator() ( RoutingPad* rp1, RoutingPad* rp2 );
|
||||
};
|
||||
|
||||
|
||||
inline SortRpByX::SortRpByX ()
|
||||
{ }
|
||||
|
||||
|
||||
inline bool SortRpByX::operator() ( RoutingPad* rp1, RoutingPad* rp2 )
|
||||
{
|
||||
DbU::Unit x1 = rp1->getCenter().getX();
|
||||
DbU::Unit x2 = rp2->getCenter().getX();
|
||||
|
||||
if (x1 == x2) return false;
|
||||
return (x1 < x2);
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// Class : "RpsInRow".
|
||||
|
||||
class RpsInRow {
|
||||
public:
|
||||
class Compare {
|
||||
public:
|
||||
bool operator() ( const RpsInRow* lhs, const RpsInRow* rhs ) const;
|
||||
};
|
||||
public:
|
||||
inline RpsInRow ( RoutingPad*, AnabaticEngine* );
|
||||
inline const vector<RoutingPad*>& getRps () const;
|
||||
inline size_t getSouth () const;
|
||||
inline size_t getNorth () const;
|
||||
inline const Interval& getRpsHSpan () const;
|
||||
inline const Interval& getRpsVSpan () const;
|
||||
void slacken ();
|
||||
private:
|
||||
void _findTopology ();
|
||||
inline void _merge ( RoutingPad* );
|
||||
private:
|
||||
AnabaticEngine* _anabatic;
|
||||
vector<RoutingPad*> _rps;
|
||||
size_t _north;
|
||||
size_t _south;
|
||||
Interval _hSpan;
|
||||
Interval _vSpan;
|
||||
};
|
||||
|
||||
|
||||
inline RpsInRow::RpsInRow ( RoutingPad* seed, AnabaticEngine* anabatic )
|
||||
: _anabatic(anabatic)
|
||||
, _rps ()
|
||||
, _north (0)
|
||||
, _south (0)
|
||||
, _hSpan ()
|
||||
, _vSpan ( false )
|
||||
{
|
||||
_rps.push_back( seed );
|
||||
_findTopology();
|
||||
}
|
||||
|
||||
|
||||
inline const vector<RoutingPad*>& RpsInRow::getRps () const { return _rps; }
|
||||
inline size_t RpsInRow::getSouth () const { return _south; }
|
||||
inline size_t RpsInRow::getNorth () const { return _north; }
|
||||
inline const Interval& RpsInRow::getRpsHSpan () const { return _hSpan; }
|
||||
inline const Interval& RpsInRow::getRpsVSpan () const { return _vSpan; }
|
||||
|
||||
|
||||
bool RpsInRow::Compare::operator() ( const RpsInRow* lhs, const RpsInRow* rhs ) const
|
||||
{
|
||||
if ( (lhs->_rps.size() == 2) and (rhs->_rps.size() != 2) ) return true;
|
||||
if ( (lhs->_rps.size() != 2) and (rhs->_rps.size() == 2) ) return false;
|
||||
if ( lhs->_rps.size() != rhs->_rps.size() ) return lhs->_rps.size() < rhs->_rps.size();
|
||||
|
||||
size_t lhsNs = lhs->_south + lhs->_north;
|
||||
size_t rhsNs = rhs->_south + rhs->_north;
|
||||
if (lhsNs != rhsNs) return lhsNs < rhsNs;
|
||||
|
||||
if (lhs->_vSpan != rhs->_vSpan) return lhs->_vSpan.getSize() < rhs->_vSpan.getSize();
|
||||
if (lhs->_hSpan != rhs->_hSpan) return lhs->_hSpan.getSize() < rhs->_hSpan.getSize();
|
||||
|
||||
return lhs->_rps[0]->getId() < rhs->_rps[0]->getId();
|
||||
}
|
||||
|
||||
|
||||
inline void RpsInRow::_merge ( RoutingPad* rp )
|
||||
{
|
||||
if (rp != _rps[0]) _rps.push_back( rp );
|
||||
|
||||
Box bb ( _rps.back()->getBoundingBox() );
|
||||
_hSpan.merge( bb.getCenter().getX() );
|
||||
_vSpan.intersection( bb.getYMin(), bb.getYMax() );
|
||||
}
|
||||
|
||||
|
||||
void RpsInRow::_findTopology ()
|
||||
{
|
||||
cdebug_log(146,1) << "RpsInRow::findTopology() - " << _rps[0] << endl;
|
||||
|
||||
_merge( _rps[0] );
|
||||
|
||||
AutoSegmentStack stack;
|
||||
|
||||
for ( Component* component : _rps[0]->getSlaveComponents() ) {
|
||||
cdebug_log(146,0) << "slave component: " << component << endl;
|
||||
AutoContact* rpContact = Session::lookup( dynamic_cast<Contact*>(component) );
|
||||
if (rpContact) {
|
||||
cdebug_log(146,0) << "Start rp: " << rpContact << endl;
|
||||
|
||||
for ( AutoSegment* segment : rpContact->getAutoSegments() ) {
|
||||
cdebug_log(146,0) << "Examining: " << segment << endl;
|
||||
AutoContact* target = segment->getOppositeAnchor(rpContact);
|
||||
|
||||
if (target) {
|
||||
if (segment->isHorizontal()) {
|
||||
stack.push( target, segment );
|
||||
} else {
|
||||
if (segment->isLocal()) {
|
||||
stack.push( target, segment );
|
||||
} else {
|
||||
if (segment->getAutoSource() == rpContact) ++_north;
|
||||
else ++_south;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find Rps in same horizontal GCell range.
|
||||
cdebug_log(146,0) << "Find Rps in same horizontal GCell range" << endl;
|
||||
|
||||
while ( not stack.isEmpty() ) {
|
||||
AutoSegment* from = stack.getAutoSegment();
|
||||
AutoContact* contact = stack.getAutoContact();
|
||||
stack.pop();
|
||||
|
||||
for ( AutoSegment* segment : contact->getAutoSegments() ) {
|
||||
if (segment == from) continue;
|
||||
if (segment->isVertical() and not segment->isLocal()) {
|
||||
if (segment->getAutoSource() == contact) ++_north;
|
||||
else ++_south;
|
||||
continue;
|
||||
}
|
||||
|
||||
AutoContact* target = segment->getOppositeAnchor( contact );
|
||||
AutoContactTerminal* terminal = dynamic_cast<AutoContactTerminal*>( target );
|
||||
if (terminal) {
|
||||
_merge( terminal->getRoutingPad() );
|
||||
}
|
||||
|
||||
stack.push( target, segment );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sort( _rps.begin(), _rps.end(), SortRpByX() );
|
||||
|
||||
cdebug_log(146,0) << "findHAlignedsRps() - Exit" << endl;
|
||||
cdebug_tabw(146,-1);
|
||||
}
|
||||
|
||||
|
||||
void RpsInRow::slacken ()
|
||||
{
|
||||
cdebug_log(149,1) << "RpsInRow::slacken()" << endl;
|
||||
|
||||
for ( RoutingPad* rp : _rps ) {
|
||||
cdebug_log(149,0) << "Slacken from: " << rp << endl;
|
||||
|
||||
if (rp->getLayer()) {
|
||||
if (_anabatic->getConfiguration()->getLayerDepth(rp->getLayer()) == 1) {
|
||||
cdebug_log(149,0) << "In METAL2, skiping" << endl;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for ( Component* component : rp->getSlaveComponents() ) {
|
||||
AutoContact* rpContact = Session::lookup( dynamic_cast<Contact*>(component) );
|
||||
if (rpContact) {
|
||||
cdebug_log(149,0) << "+ " << rpContact << endl;
|
||||
for ( AutoSegment* segment : rpContact->getAutoSegments() ) {
|
||||
cdebug_log(149,0) << "| " << segment << endl;
|
||||
|
||||
if (segment->isVertical()) {
|
||||
if (segment->getDepth() == 1) {
|
||||
cdebug_log(149,0) << "| Slacken: " << segment << endl;
|
||||
segment->changeDepth( 2, Flags::NoFlags );
|
||||
cdebug_log(149,0) << "| After Slacken: " << segment << endl;
|
||||
}
|
||||
} else {
|
||||
segment->makeDogleg( rpContact->getGCell() );
|
||||
cdebug_log(149,0) << "| Make dogleg: " << segment << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
cdebug_tabw(149,-1);
|
||||
}
|
||||
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// Class : "GCellRps".
|
||||
|
||||
class GCellRps {
|
||||
public:
|
||||
class Compare {
|
||||
public:
|
||||
bool operator() ( const GCellRps* lhs, const GCellRps* rhs ) const;
|
||||
};
|
||||
public:
|
||||
GCellRps ( GCell*, AnabaticEngine* );
|
||||
~GCellRps ();
|
||||
inline GCell* getGCell () const;
|
||||
inline size_t add ( RoutingPad* );
|
||||
inline void consolidate ();
|
||||
inline RpsInRow* getRpsInRow ( size_t i );
|
||||
inline const vector<RpsInRow*>& getRpsInRows () const;
|
||||
private:
|
||||
AnabaticEngine* _anabatic;
|
||||
GCell* _gcell;
|
||||
vector<RpsInRow*> _rpsInRows;
|
||||
};
|
||||
|
||||
|
||||
GCellRps::GCellRps ( GCell* gcell, AnabaticEngine* anabatic )
|
||||
: _anabatic (anabatic)
|
||||
, _gcell (gcell)
|
||||
, _rpsInRows()
|
||||
{ }
|
||||
|
||||
|
||||
GCellRps::~GCellRps ()
|
||||
{
|
||||
for ( RpsInRow* elem : _rpsInRows ) delete elem;
|
||||
}
|
||||
|
||||
|
||||
inline GCell* GCellRps::getGCell () const { return _gcell; }
|
||||
|
||||
|
||||
inline size_t GCellRps::add ( RoutingPad* rp )
|
||||
{
|
||||
_rpsInRows.push_back( new RpsInRow(rp,_anabatic) );
|
||||
return _rpsInRows.size() - 1;
|
||||
}
|
||||
|
||||
|
||||
inline void GCellRps::consolidate ()
|
||||
{
|
||||
sort( _rpsInRows.begin(), _rpsInRows.end(), RpsInRow::Compare() );
|
||||
}
|
||||
|
||||
|
||||
inline RpsInRow* GCellRps::getRpsInRow ( size_t i ) { return _rpsInRows[i]; }
|
||||
inline const vector<RpsInRow*>& GCellRps::getRpsInRows () const { return _rpsInRows; }
|
||||
|
||||
|
||||
bool GCellRps::Compare::operator() ( const GCellRps* lhs, const GCellRps* rhs ) const
|
||||
{ return lhs->getGCell()->getId() < rhs->getGCell()->getId(); }
|
||||
|
||||
|
||||
} // Anonymous namespace.
|
||||
|
||||
|
||||
namespace Anabatic {
|
||||
|
||||
using Hurricane::DebugSession;
|
||||
|
@ -336,56 +59,7 @@ namespace Anabatic {
|
|||
|
||||
cmess1 << " o Desaturate layer "
|
||||
<< Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << endl;
|
||||
cdebug_log(149,0) << "Session::getSaturateRatio()=" << Session::getSaturateRatio() << endl;
|
||||
|
||||
GCellKeyQueue queue;
|
||||
GCell::Set invalidateds;
|
||||
|
||||
for ( GCell* gcell : getGCells() ) queue.push( gcell->cloneKey(depth) );
|
||||
|
||||
bool optimized = true;
|
||||
bool finished = false;
|
||||
while ( optimized ) {
|
||||
Session::revalidate ();
|
||||
optimized = false;
|
||||
|
||||
while ( not queue.empty() ) {
|
||||
GCell::Key* topKey = queue.top();
|
||||
GCell* gcell = const_cast<GCell*>( topKey->getGCell() );
|
||||
queue.pop();
|
||||
|
||||
if (topKey->isActive()) {
|
||||
cdebug_log(149,0) << "_desaturate: [" << depth << "]:"
|
||||
<< gcell->getDensity(depth) << " " << gcell << endl;
|
||||
|
||||
if (not gcell->isSaturated(depth)) {
|
||||
cdebug_log(149,0) << "STOP desaturated: " << gcell << endl;
|
||||
finished = true;
|
||||
} else {
|
||||
if (finished) {
|
||||
cparanoid << "[ERROR] Still saturated: " << gcell << endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (not finished) {
|
||||
optimized = gcell->stepNetDesaturate( depth, globalNets, invalidateds );
|
||||
gcell->setSatProcessed( depth );
|
||||
if (optimized) {
|
||||
for ( GCell* gcell : invalidateds ) {
|
||||
if (not gcell->isSatProcessed(depth))
|
||||
queue.push( gcell->cloneKey(depth) );
|
||||
}
|
||||
invalidateds.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete topKey;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if OLD_QUEUE_DISABLED
|
||||
GCellDensitySet queue ( depth, getGCells() );
|
||||
GCell::Set invalidateds;
|
||||
|
||||
|
@ -421,7 +95,6 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -573,23 +246,22 @@ namespace Anabatic {
|
|||
|
||||
for ( AutoSegment* horizontal : horizontals ) {
|
||||
vector<AutoSegment*> collapseds;
|
||||
vector< tuple<AutoSegment*,Flags> > perpandicularsDatas;
|
||||
//vector<AutoSegment*> northBounds;
|
||||
//vector<AutoSegment*> southBounds;
|
||||
vector<AutoSegment*> perpandiculars;
|
||||
vector<AutoSegment*> northBounds;
|
||||
vector<AutoSegment*> southBounds;
|
||||
DbU::Unit leftBound;
|
||||
DbU::Unit rightBound;
|
||||
//bool hasNorth = false;
|
||||
//bool hasSouth = false;
|
||||
bool hasNorth = false;
|
||||
bool hasSouth = false;
|
||||
|
||||
AutoSegment::getTopologicalInfos( horizontal
|
||||
, collapseds
|
||||
, perpandicularsDatas
|
||||
, perpandiculars
|
||||
, leftBound
|
||||
, rightBound
|
||||
);
|
||||
|
||||
for ( auto perpandicularDatas : perpandicularsDatas ) {
|
||||
AutoSegment* perpandicular = std::get<0>( perpandicularDatas );
|
||||
for ( AutoSegment* perpandicular : perpandiculars ) {
|
||||
if (Session::getLayerDepth(perpandicular->getLayer()) > 2) continue;
|
||||
|
||||
bool hasGlobal = false;
|
||||
|
@ -759,7 +431,7 @@ namespace Anabatic {
|
|||
if (not segment->isStrongTerminal()) locals.push_back( segment );
|
||||
continue;
|
||||
}
|
||||
if ( (segment->getAnchoredLength() < 3*Session::getSliceHeight()) and (segment != seed) ) {
|
||||
if ( (segment->getLength() < 3*Session::getSliceHeight()) and (segment != seed) ) {
|
||||
locals.push_back( segment );
|
||||
continue;
|
||||
}
|
||||
|
@ -835,7 +507,7 @@ namespace Anabatic {
|
|||
cmess1 << " o Balance Global Density "
|
||||
<< Session::getRoutingGauge()->getRoutingLayer(depth)->getName() << endl;
|
||||
|
||||
GCellDensitySet queue ( depth, getGCells() );
|
||||
GCellDensitySet queue ( depth, getGCells()) );
|
||||
GCell::Set invalidateds;
|
||||
|
||||
bool optimized = true;
|
||||
|
@ -927,8 +599,6 @@ namespace Anabatic {
|
|||
|
||||
void AnabaticEngine::layerAssign ( uint32_t method )
|
||||
{
|
||||
//DebugSession::open( 145, 150 );
|
||||
|
||||
cdebug_log(9000,0) << "Deter| Layer Assignment" << endl;
|
||||
|
||||
set<Net*> globalNets;
|
||||
|
@ -976,54 +646,6 @@ namespace Anabatic {
|
|||
Session::setAnabaticFlags( Flags::WarnOnGCellOverload );
|
||||
}
|
||||
|
||||
set<GCellRps*,GCellRps::Compare> gcellRpss;
|
||||
|
||||
for ( GCell* gcell : getGCells() ) {
|
||||
set<RoutingPad*,Entity::CompareById> rps;
|
||||
|
||||
const vector<AutoContact*> contacts = gcell->getContacts();
|
||||
for ( AutoContact* contact : contacts ) {
|
||||
AutoContactTerminal* terminal = dynamic_cast<AutoContactTerminal*>( contact );
|
||||
if (terminal) {
|
||||
rps.insert( terminal->getRoutingPad() );
|
||||
}
|
||||
}
|
||||
if (rps.size() > getConfiguration()->getSaturateRp()) {
|
||||
GCellRps* gcellRps = new GCellRps ( gcell, this );
|
||||
gcellRpss.insert( gcellRps );
|
||||
|
||||
for ( RoutingPad* rp : rps ) gcellRps->add( rp );
|
||||
}
|
||||
}
|
||||
|
||||
for ( GCellRps* gcellRps : gcellRpss ) {
|
||||
gcellRps->consolidate();
|
||||
|
||||
const vector<RpsInRow*>& rpsInRows = gcellRps->getRpsInRows();
|
||||
cdebug_log(149,0) << gcellRps->getGCell() << " has " << rpsInRows.size() << " terminals." << endl;
|
||||
|
||||
size_t count = 0;
|
||||
for ( RpsInRow* rpsInRow : rpsInRows ) {
|
||||
cdebug_log(149,0) << "North:" << rpsInRow->getNorth() << " South:"
|
||||
<< rpsInRow->getSouth() << " net:"
|
||||
<< rpsInRow->getRps()[0]->getNet()->getName() << endl;
|
||||
cdebug_log(149,0) << "H-Span:" << rpsInRow->getRpsHSpan() << " V-Span:" << rpsInRow->getRpsVSpan() << endl;
|
||||
for ( RoutingPad* arp : rpsInRow->getRps() ) {
|
||||
cdebug_log(149,0) << "| " << arp << endl;
|
||||
}
|
||||
if (++count < 2) rpsInRow->slacken();
|
||||
}
|
||||
|
||||
for ( AutoSegment* segment : gcellRps->getGCell()->getHSegments() ) {
|
||||
if (segment->canPivotUp()) {
|
||||
cdebug_log(149,0) << "Move up horizontal: " << segment << endl;
|
||||
segment->moveUp( Flags::Propagate );
|
||||
}
|
||||
}
|
||||
|
||||
delete gcellRps;
|
||||
}
|
||||
|
||||
checkGCellDensities();
|
||||
Session::close();
|
||||
|
||||
|
@ -1034,8 +656,6 @@ namespace Anabatic {
|
|||
// cmess2 << " - Global segments : " << global << endl;
|
||||
// cmess2 << " - Ratio : "
|
||||
// << ((float)global/(float)total)*100.0 << "%." << endl;
|
||||
|
||||
//DebugSession::close();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
#include "hurricane/Instance.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "hurricane/Rectilinear.h"
|
||||
#include "crlcore/AllianceFramework.h"
|
||||
#include "crlcore/RoutingGauge.h"
|
||||
#include "anabatic/AutoContactTerminal.h"
|
||||
|
@ -221,7 +220,6 @@ namespace Anabatic {
|
|||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Rectilinear;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -234,40 +232,18 @@ namespace Anabatic {
|
|||
if (segment) {
|
||||
source = segment->getSourcePosition();
|
||||
target = segment->getTargetPosition();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
RoutingPad* rp = dynamic_cast<RoutingPad*>( anchor );
|
||||
if (rp) {
|
||||
source = rp->getSourcePosition();
|
||||
target = rp->getTargetPosition();
|
||||
} else {
|
||||
source = anchor->getPosition();
|
||||
target = anchor->getPosition();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (source == target) return;
|
||||
if (source.getX() > target.getX()) swap( source, target );
|
||||
if (source.getY() > target.getY()) swap( source, target );
|
||||
|
||||
if (not Session::getRoutingGauge()->isSymbolic()) {
|
||||
size_t rpDepth = Session::getLayerDepth( anchor->getLayer() );
|
||||
Flags direction = Session::getDirection ( rpDepth );
|
||||
DbU::Unit wwidth = Session::getWireWidth (rpDepth) / 2;
|
||||
cdebug_log(145,0) << "Not a symbolic gauge, shrink positions of " << DbU::getValueString(wwidth) << endl;
|
||||
if (rpDepth == 0) return;
|
||||
if (direction.contains(Flags::Horizontal)) {
|
||||
cdebug_log(145,0) << "H shrink" << endl;
|
||||
source.translate( wwidth, 0 );
|
||||
target.translate( -wwidth, 0 );
|
||||
} else {
|
||||
cdebug_log(145,0) << "V shrink" << endl;
|
||||
source.translate( 0, wwidth );
|
||||
target.translate( 0, -wwidth );
|
||||
}
|
||||
} else {
|
||||
cdebug_log(145,0) << "Symbolic gauge, no shrink" << endl;
|
||||
}
|
||||
source = anchor->getPosition();
|
||||
target = anchor->getPosition();
|
||||
}
|
||||
|
||||
|
||||
|
@ -353,8 +329,6 @@ namespace Anabatic {
|
|||
, _forks ()
|
||||
, _connexity ()
|
||||
, _topology (0)
|
||||
, _net (NULL)
|
||||
, _netData (NULL)
|
||||
, _gcell (NULL)
|
||||
, _sourceContact (NULL)
|
||||
, _southWestContact (NULL)
|
||||
|
@ -368,9 +342,7 @@ namespace Anabatic {
|
|||
, _routingPadAutoSegments()
|
||||
, _toFixSegments ()
|
||||
, _degree (0)
|
||||
, _isStrictChannel (false)
|
||||
, _sourceFlags (0)
|
||||
, _flags (0)
|
||||
, _isTwoMetals (false)
|
||||
{ }
|
||||
|
||||
|
||||
|
@ -381,11 +353,7 @@ namespace Anabatic {
|
|||
void NetBuilder::clear ()
|
||||
{
|
||||
_connexity.connexity = 0;
|
||||
_sourceFlags = 0;
|
||||
_flags = 0;
|
||||
_topology = 0;
|
||||
_net = NULL;
|
||||
_netData = NULL;
|
||||
_gcell = NULL;
|
||||
_sourceContact = NULL;
|
||||
_southWestContact = NULL;
|
||||
|
@ -396,8 +364,8 @@ namespace Anabatic {
|
|||
_norths .clear();
|
||||
_souths .clear();
|
||||
_routingPads .clear();
|
||||
_routingPadAutoSegments.clear();
|
||||
_toFixSegments .clear();
|
||||
_routingPadAutoSegments.clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -409,22 +377,17 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
NetBuilder& NetBuilder::setStartHook ( AnabaticEngine* anbt
|
||||
, Hook* fromHook
|
||||
, AutoContact* sourceContact
|
||||
, uint64_t sourceFlags )
|
||||
NetBuilder& NetBuilder::setStartHook ( AnabaticEngine* anbt, Hook* fromHook, AutoContact* sourceContact )
|
||||
{
|
||||
clear();
|
||||
|
||||
_isStrictChannel = anbt->isChannelStyle() and not anbt->isHybridStyle();
|
||||
_sourceFlags = sourceFlags;
|
||||
_isTwoMetals = anbt->getConfiguration()->isTwoMetals();
|
||||
_sourceContact = sourceContact;
|
||||
_fromHook = fromHook;
|
||||
|
||||
cdebug_log(145,1) << "NetBuilder::setStartHook()" << endl;
|
||||
cdebug_log(145,0) << "* _fromHook: " << fromHook << endl;
|
||||
cdebug_log(145,0) << "* _sourceContact:" << sourceContact << endl;
|
||||
cdebug_log(145,0) << "_isStrictChannel:" << _isStrictChannel << endl;
|
||||
|
||||
if (not _fromHook) {
|
||||
cdebug_tabw(145,-1);
|
||||
|
@ -433,7 +396,6 @@ namespace Anabatic {
|
|||
|
||||
Segment* fromSegment = static_cast<Segment*>( _fromHook->getComponent() );
|
||||
_net = fromSegment->getNet();
|
||||
_netData = anbt->getNetData( _net );
|
||||
|
||||
cdebug_log(145,0) << "For Hooks from fromHook" << endl;
|
||||
for ( Hook* hook : fromHook->getHooks() ) {
|
||||
|
@ -481,18 +443,12 @@ namespace Anabatic {
|
|||
throw Error( mismatchGCell );
|
||||
}
|
||||
|
||||
if ( (_gcell->getDensity( Session::getDHorizontalDepth() ) > 0.9)
|
||||
or (_gcell->getDensity( Session::getDVerticalDepth () ) > 0.9)) {
|
||||
cdebug_log(145,0) << "Base layers blockeds, moving up" << endl;
|
||||
_flags |= ToUpperRouting;
|
||||
}
|
||||
|
||||
if (not _gcell->isMatrix()) {
|
||||
cdebug_log(145,0) << "* Non-matrix GCell under: " << contact << endl;
|
||||
cdebug_log(145,0) << "| " << gcell << endl;
|
||||
}
|
||||
} else {
|
||||
if (rp and AllianceFramework::get()->isPad(rp->_getEntityAs<Component>()->getCell())) {
|
||||
if (rp and AllianceFramework::get()->isPad(rp->_getEntityAsComponent()->getCell())) {
|
||||
_connexity.fields.Pad++;
|
||||
} else {
|
||||
const Layer* layer = anchor->getLayer();
|
||||
|
@ -506,32 +462,11 @@ namespace Anabatic {
|
|||
continue;
|
||||
}
|
||||
|
||||
bool isPin = (dynamic_cast<Pin*>( rp->getOccurrence().getEntity() ) != nullptr);
|
||||
size_t rpDepth = 0;
|
||||
for ( size_t depth=0 ; depth < Session::getRoutingGauge()->getDepth() ; ++depth ) {
|
||||
if (layer->getMask() == Session::getRoutingLayer(depth)->getMask()) {
|
||||
rpDepth = depth;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rpDepth >= Session::getRoutingGauge()->getFirstRoutingLayer())
|
||||
rpDepth -= Session::getRoutingGauge()->getFirstRoutingLayer();
|
||||
else
|
||||
cerr << Error( "Terminal layer \"%s\" of %s is below first usable routing layer."
|
||||
, getString(layer->getName()).c_str()
|
||||
, getString(anchor).c_str() )
|
||||
<< endl;
|
||||
if ((rpDepth > 0) and not isPin
|
||||
and not Session::getRoutingGauge()->isSuperPitched()) {
|
||||
_flags |= ToUpperRouting;
|
||||
cdebug_log(145,0) << "ToUpperRouting set, getFlags():" << getFlags() << endl;
|
||||
}
|
||||
|
||||
if (rpDepth == 0) _connexity.fields.M1++; // M1 V
|
||||
else if (rpDepth == 1) _connexity.fields.M2++; // M2 H
|
||||
else if (rpDepth == 2) _connexity.fields.M3++; // M3 V
|
||||
else if (rpDepth == 3) _connexity.fields.M2++; // M4 H
|
||||
else if (rpDepth == 4) _connexity.fields.M3++; // M5 V
|
||||
if (layer->getMask() == Session::getRoutingLayer(0)->getMask()) _connexity.fields.M1++; // M1 V
|
||||
else if (layer->getMask() == Session::getRoutingLayer(1)->getMask()) _connexity.fields.M2++; // M2 H
|
||||
else if (layer->getMask() == Session::getRoutingLayer(2)->getMask()) _connexity.fields.M3++; // M3 V
|
||||
else if (layer->getMask() == Session::getRoutingLayer(3)->getMask()) _connexity.fields.M2++; // M4 H
|
||||
else if (layer->getMask() == Session::getRoutingLayer(4)->getMask()) _connexity.fields.M3++; // M5 V
|
||||
else {
|
||||
cerr << Warning( "Terminal layer \"%s\" of %s is not managed yet (ignored)."
|
||||
, getString(layer->getName()).c_str()
|
||||
|
@ -540,7 +475,7 @@ namespace Anabatic {
|
|||
//continue;
|
||||
}
|
||||
|
||||
if (isPin) _connexity.fields.Pin++;
|
||||
if (dynamic_cast<Pin*>(rp->getOccurrence().getEntity())) _connexity.fields.Pin++;
|
||||
}
|
||||
|
||||
cdebug_log(145,0) << "| Component to connect: " << anchor << endl;
|
||||
|
@ -572,15 +507,6 @@ namespace Anabatic {
|
|||
|
||||
if (_gcell == NULL) throw Error( missingGCell );
|
||||
|
||||
cdebug_log(145,0) << "Topology [" << _connexity.connexity << "] = "
|
||||
<< "[" << (int)_connexity.fields.globals
|
||||
<< "+" << (int)_connexity.fields.M1
|
||||
<< "+" << (int)_connexity.fields.M2
|
||||
<< "+" << (int)_connexity.fields.M3
|
||||
<< "+" << (int)_connexity.fields.Pin
|
||||
<< "+" << (int)_connexity.fields.Pad
|
||||
<< "] " << _gcell
|
||||
<< endl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -590,7 +516,6 @@ namespace Anabatic {
|
|||
cdebug_log(145,0) << "NetBuilder::push()" << endl;
|
||||
cdebug_log(145,0) << "* toHook: " << toHook << endl;
|
||||
cdebug_log(145,0) << "* _fromHook:" << _fromHook << endl;
|
||||
cdebug_log(145,0) << "* flags:" << flags << endl;
|
||||
|
||||
if (not toHook or (toHook == _fromHook)) {
|
||||
if (contact) {
|
||||
|
@ -609,85 +534,23 @@ namespace Anabatic {
|
|||
Hook* toHookOpposite = getSegmentOppositeHook( toHook );
|
||||
cdebug_log(145,0) << "Pushing (to) " << getString(toHook) << endl;
|
||||
cdebug_log(145,0) << "Pushing (from) " << contact << endl;
|
||||
_forks.push( toHookOpposite, contact, getFlags() );
|
||||
_forks.push( toHookOpposite, contact );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::isInsideBlockage ( GCell* gcell, Component* rp ) const
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::isInsideBlockage() " << endl;
|
||||
cdebug_log(145,0) << rp << endl;
|
||||
cdebug_log(145,0) << rp->getLayer()->getMask() << endl;
|
||||
|
||||
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
|
||||
if (gcell->getDensity(rpDepth) < 0.5) {
|
||||
cdebug_tabw(145,-1);
|
||||
return false;
|
||||
}
|
||||
|
||||
Box rpBb = rp->getBoundingBox();
|
||||
Layer::Mask rpMask = rp->getLayer()->getBlockageLayer()->getMask();
|
||||
cdebug_log(145,0) << "rpBb: " << rpBb << endl;
|
||||
for ( Occurrence occurrence : getAnabatic()->getCell()->getOccurrencesUnder(rpBb) ) {
|
||||
cdebug_log(145,0) << "| " << occurrence.getEntity() << endl;
|
||||
Component* component = dynamic_cast<Component*>( occurrence.getEntity() );
|
||||
if (not component) continue;
|
||||
|
||||
const Layer* blockageLayer = component->getLayer();
|
||||
Box blockageBb = component->getBoundingBox();
|
||||
cdebug_log(145,0) << " Mask: " << blockageLayer->getMask() << endl;
|
||||
if ( blockageLayer->isBlockage()
|
||||
and (blockageLayer->getMask() == rpMask)) {
|
||||
occurrence.getPath().getTransformation().applyOn( blockageBb );
|
||||
cdebug_log(145,0) << " Bb: " << blockageBb << endl;
|
||||
if (blockageBb.contains(rpBb)) {
|
||||
cdebug_log(145,-1) << "* Inside " << component << endl;
|
||||
return true;
|
||||
}
|
||||
if (blockageBb.intersect(rpBb)) {
|
||||
cerr << Warning( "NetBuilder::isInsideBlockage(): RoutingPad is only partially inside blocked area.\n"
|
||||
" * %s\n"
|
||||
" * %s"
|
||||
, getString(rp).c_str()
|
||||
, getString(component).c_str()
|
||||
) << endl;
|
||||
cdebug_log(145,-1) << "* Partially inside " << component << endl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
cdebug_tabw(145,-1);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void NetBuilder::construct ()
|
||||
{
|
||||
cdebug_log(145,1) << "NetBuilder::construct() [" << _connexity.connexity << "] in " << _gcell << endl;
|
||||
cdebug_log(145,0) << "Topology [" << _connexity.connexity << "] = "
|
||||
<< "[" << (int)_connexity.fields.globals
|
||||
<< "+" << (int)_connexity.fields.M1
|
||||
<< "+" << (int)_connexity.fields.M2
|
||||
<< "+" << (int)_connexity.fields.M3
|
||||
<< "+" << (int)_connexity.fields.Pin
|
||||
<< "+" << (int)_connexity.fields.Pad
|
||||
<< "] " << _gcell
|
||||
<< endl;
|
||||
cdebug_log(145,0) << "getSourceFlags():" << getSourceFlags()
|
||||
<< " getFlags():" << getFlags() << endl;
|
||||
|
||||
if (not isStrictChannel()) {
|
||||
if (not isTwoMetals()) {
|
||||
_southWestContact = NULL;
|
||||
_northEastContact = NULL;
|
||||
}
|
||||
|
||||
if (not _gcell->isAnalog()) {
|
||||
if (isStrictChannel() and not _sourceContact) {
|
||||
cdebug_log(145,0) << "No _sourceContact, resetting _fromHook" << endl;
|
||||
_fromHook = NULL;
|
||||
}
|
||||
if (isTwoMetals() and not _sourceContact) _fromHook = NULL;
|
||||
|
||||
switch ( _connexity.connexity ) {
|
||||
case Conn_1G_1Pad:
|
||||
|
@ -699,11 +562,7 @@ namespace Anabatic {
|
|||
case Conn_1G_2M1:
|
||||
case Conn_1G_3M1:
|
||||
case Conn_1G_4M1:
|
||||
case Conn_1G_5M1:
|
||||
case Conn_1G_6M1:
|
||||
case Conn_1G_7M1:
|
||||
case Conn_1G_8M1:
|
||||
case Conn_1G_9M1: _do_1G_xM1(); break;
|
||||
case Conn_1G_5M1: _do_1G_xM1(); break;
|
||||
// End 1G_xM1 cascaded cases.
|
||||
|
||||
case Conn_1G_1M2:
|
||||
|
@ -723,31 +582,17 @@ namespace Anabatic {
|
|||
case Conn_2G_3M1:
|
||||
case Conn_2G_4M1:
|
||||
case Conn_2G_5M1:
|
||||
case Conn_2G_6M1:
|
||||
case Conn_2G_7M1:
|
||||
case Conn_2G_8M1:
|
||||
case Conn_2G_9M1: _do_xG_xM1_xM3(); break;
|
||||
case Conn_3G_1M1: if (_do_xG_1M1()) break;
|
||||
case Conn_3G_2M1:
|
||||
case Conn_3G_3M1:
|
||||
case Conn_3G_4M1:
|
||||
case Conn_3G_5M1:
|
||||
case Conn_3G_6M1:
|
||||
case Conn_3G_7M1:
|
||||
case Conn_3G_8M1:
|
||||
case Conn_3G_9M1:
|
||||
case Conn_3G_2M3:
|
||||
case Conn_3G_3M3:
|
||||
case Conn_3G_4M3: _do_xG_xM1_xM3(); break;
|
||||
case Conn_3G_4M3:
|
||||
case Conn_4G_1M1: if (_do_xG_1M1()) break;
|
||||
case Conn_4G_2M1:
|
||||
case Conn_4G_3M1:
|
||||
case Conn_4G_4M1:
|
||||
case Conn_4G_5M1:
|
||||
case Conn_4G_6M1:
|
||||
case Conn_4G_7M1:
|
||||
case Conn_4G_8M1:
|
||||
case Conn_4G_9M1: _do_xG_xM1_xM3(); break;
|
||||
case Conn_4G_4M1: _do_xG_xM1_xM3(); break;
|
||||
// End xG_xM1_xM3 cascaded cases.
|
||||
|
||||
case Conn_4G_1M2: if (_do_4G_1M2()) break;
|
||||
|
@ -771,34 +616,17 @@ namespace Anabatic {
|
|||
case Conn_4G: _do_xG(); break;
|
||||
// End xG cascaded cases.
|
||||
// Optimized specific cases.
|
||||
case Conn_1G_1PinM1: _do_1G_1PinM1 (); break;
|
||||
case Conn_2G_1PinM1: _do_2G_1PinM1 (); break;
|
||||
case Conn_1G_1PinM2: _do_1G_1PinM2 (); break;
|
||||
case Conn_2G_1PinM2:
|
||||
case Conn_3G_1PinM2: _do_xG_1PinM2 (); break;
|
||||
case Conn_1G_1PinM3: _do_1G_1PinM3 (); break;
|
||||
case Conn_2G_1PinM3:
|
||||
case Conn_3G_1PinM3: _do_xG_1PinM3 (); break;
|
||||
case Conn_1G_2M1_1PinM1: _do_1G_xM1_1PinM1(); break;
|
||||
case Conn_1G_1M1_1PinM3: _do_1G_1M1_1PinM3(); break;
|
||||
case Conn_1G_1M1_1PinM2:
|
||||
case Conn_1G_2M1_1PinM2:
|
||||
case Conn_1G_3M1_1PinM2:
|
||||
case Conn_1G_4M1_1PinM2:
|
||||
case Conn_1G_5M1_1PinM2: _do_1G_xM1_1PinM2(); break;
|
||||
case Conn_2G_1M1_1PinM2:
|
||||
case Conn_2G_2M1_1PinM2: _do_2G_xM1_1PinM2(); break;
|
||||
case Conn_2G_1M1_1PinM3:
|
||||
case Conn_2G_2M1_1PinM3:
|
||||
case Conn_2G_3M1_1PinM3: _do_2G_xM1_1PinM3(); break;
|
||||
case Conn_3G_1M1_1PinM3:
|
||||
case Conn_3G_2M1_1PinM3:
|
||||
case Conn_3G_3M1_1PinM3: _do_3G_xM1_1PinM3(); break;
|
||||
case Conn_1G_1M1_1M2: _do_xG_1M1_1M2 (); break;
|
||||
case Conn_1G_1M1_1M2: _do_xG_1M1_1M2(); break;
|
||||
case Conn_1G_1M1_1M3: _do_1G_xM1 (); break;
|
||||
case Conn_2G_1M1_1M2: _do_xG_1M1_1M2 (); break;
|
||||
case Conn_2G_1M1_1M2: _do_xG_1M1_1M2(); break;
|
||||
default:
|
||||
//if (not isStrictChannel())
|
||||
if (not isTwoMetals())
|
||||
throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n"
|
||||
" The global routing seems to be defective."
|
||||
, _connexity.connexity
|
||||
|
@ -814,9 +642,6 @@ namespace Anabatic {
|
|||
_do_xG();
|
||||
}
|
||||
|
||||
cdebug_log(145,0) << "SouthWest: " << _southWestContact << endl;
|
||||
cdebug_log(145,0) << "NorthEast: " << _northEastContact << endl;
|
||||
|
||||
if (not _do_globalSegment()) {
|
||||
cdebug_log(145,0) << "No global generated, finish." << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
|
@ -841,15 +666,11 @@ namespace Anabatic {
|
|||
, getString(_net).c_str()
|
||||
);
|
||||
|
||||
if ( (_sourceContact) and (targetContact) ){
|
||||
Segment* baseSegment = static_cast<Segment*>( _fromHook->getComponent() );
|
||||
if ( (_sourceContact) && (targetContact) ){
|
||||
AutoSegment* globalSegment = AutoSegment::create( _sourceContact
|
||||
, targetContact
|
||||
, baseSegment
|
||||
, static_cast<Segment*>( _fromHook->getComponent() )
|
||||
);
|
||||
if (_netData and _netData->isNoMoveUp(baseSegment)) {
|
||||
globalSegment->setFlags( AutoSegment::SegNoMoveUp );
|
||||
}
|
||||
cdebug_log(145,0) << "[Create global segment (1)]: " << globalSegment << endl;
|
||||
}
|
||||
}
|
||||
|
@ -1141,25 +962,9 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_1G_1PinM1 ()
|
||||
{
|
||||
throw Error ( "%s::_do_1G_1PinM1() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_2G_1PinM1 ()
|
||||
{
|
||||
throw Error ( "%s::_do_2G_1PinM1() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_xG_1PinM2 ()
|
||||
{
|
||||
throw Error( "%s::_do_xG_1PinM2() method *not* reimplemented from base class.\n"
|
||||
" On %s"
|
||||
, getTypeName().c_str(), getString(getNet()).c_str() );
|
||||
throw Error ( "%s::_do_xG_1PinM2() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1248,48 +1053,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_1G_1M1_1PinM3 ()
|
||||
{
|
||||
throw Error ( "%s::_do_1G_1M1_1PinM3() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_1G_xM1_1PinM2 ()
|
||||
{
|
||||
throw Error ( "%s::_do_1G_xM1_1PinM2() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_2G_xM1_1PinM2 ()
|
||||
{
|
||||
throw Error ( "%s::_do_2G_xM1_1PinM2() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_2G_xM1_1PinM3 ()
|
||||
{
|
||||
throw Error ( "%s::_do_2G_xM1_1PinM3() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_1G_xM1_1PinM1 ()
|
||||
{
|
||||
throw Error ( "%s::_do_1G_xM1_1PinM1() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_3G_xM1_1PinM3 ()
|
||||
{
|
||||
throw Error ( "%s::_do_3G_xM1_1PinM3() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool NetBuilder::_do_globalSegment ()
|
||||
{
|
||||
throw Error ( "%s::_do_globalSegment() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||
|
@ -1304,12 +1067,11 @@ namespace Anabatic {
|
|||
vector<RoutingPad*> rpM1s;
|
||||
Component* rpM2 = NULL;
|
||||
|
||||
for ( RoutingPad* rp : net->getRoutingPads() ) {
|
||||
if ( Session::getRoutingGauge()->getLayerDepth(rp->getLayer())
|
||||
== 1 + Session::getRoutingGauge()->getFirstRoutingLayer())
|
||||
rpM2 = rp;
|
||||
forEach ( RoutingPad*, irp, net->getRoutingPads() ) {
|
||||
if (Session::getRoutingGauge()->getLayerDepth(irp->getLayer()) == 1)
|
||||
rpM2 = *irp;
|
||||
else
|
||||
rpM1s.push_back( rp );
|
||||
rpM1s.push_back( *irp );
|
||||
}
|
||||
|
||||
if ((rpM1s.size() < 2) and not rpM2) {
|
||||
|
@ -2479,15 +2241,12 @@ namespace Anabatic {
|
|||
|
||||
Hook* sourceHook = NULL;
|
||||
AutoContact* sourceContact = NULL;
|
||||
uint64_t sourceFlags = NoFlags;
|
||||
RoutingPads routingPads = net->getRoutingPads();
|
||||
size_t degree = routingPads.getSize();
|
||||
|
||||
if (degree == 0) {
|
||||
if (not net->isBlockage()) {
|
||||
cmess2 << Warning( "Net \"%s\" do not have any RoutingPad (ignored)."
|
||||
, getString(net->getName()).c_str() ) << endl;
|
||||
}
|
||||
cmess2 << Warning("Net \"%s\" do not have any RoutingPad (ignored)."
|
||||
,getString(net->getName()).c_str()) << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
return;
|
||||
}
|
||||
|
@ -2518,7 +2277,7 @@ namespace Anabatic {
|
|||
++connecteds;
|
||||
segmentFound = true;
|
||||
|
||||
setStartHook( anabatic, hook, NULL, NoFlags );
|
||||
setStartHook( anabatic, hook, NULL );
|
||||
if (getStateG() == 1) {
|
||||
if ( (lowestGCell == NULL) or (*getGCell() < *lowestGCell) ) {
|
||||
cdebug_log(145,0) << "Potential starting GCell " << getGCell() << endl;
|
||||
|
@ -2546,9 +2305,9 @@ namespace Anabatic {
|
|||
}
|
||||
cdebug_tabw(145,-1);
|
||||
|
||||
if (startHook == NULL) { setStartHook(anabatic,NULL,NULL,NoFlags).singleGCell(anabatic,net); cdebug_tabw(145,-1); return; }
|
||||
if (startHook == NULL) { setStartHook(anabatic,NULL,NULL).singleGCell(anabatic,net); cdebug_tabw(145,-1); return; }
|
||||
|
||||
setStartHook( anabatic, startHook, NULL, NoFlags );
|
||||
setStartHook( anabatic, startHook, NULL );
|
||||
cdebug_log(145,0) << endl;
|
||||
cdebug_log(145,0) << "--------~~~~=={o}==~~~~--------" << endl;
|
||||
cdebug_log(145,0) << endl;
|
||||
|
@ -2557,21 +2316,18 @@ namespace Anabatic {
|
|||
|
||||
sourceHook = _forks.getFrom ();
|
||||
sourceContact = _forks.getContact();
|
||||
sourceFlags = _forks.getFlags ();
|
||||
_forks.pop();
|
||||
|
||||
while ( sourceHook ) {
|
||||
setStartHook( anabatic, sourceHook, sourceContact, sourceFlags );
|
||||
setStartHook( anabatic, sourceHook, sourceContact );
|
||||
construct();
|
||||
|
||||
sourceHook = _forks.getFrom ();
|
||||
sourceHook = _forks.getFrom();
|
||||
sourceContact = _forks.getContact();
|
||||
sourceFlags = _forks.getFlags ();
|
||||
_forks.pop();
|
||||
|
||||
cdebug_log(145,0) << "Popping (from) " << sourceHook << endl;
|
||||
cdebug_log(145,0) << "Popping (to) " << sourceContact << endl;
|
||||
cdebug_log(145,0) << "Popping (flags) " << sourceFlags << endl;
|
||||
}
|
||||
|
||||
Session::revalidate();
|
||||
|
@ -2582,11 +2338,10 @@ namespace Anabatic {
|
|||
for ( ; iover != overconstraineds.end() ; ++iover ) {
|
||||
(*iover)->makeDogLeg( (*iover)->getAutoSource()->getGCell(), true );
|
||||
}
|
||||
Session::revalidate();
|
||||
#endif
|
||||
|
||||
fixSegments();
|
||||
Session::revalidate();
|
||||
fixSegments();
|
||||
cdebug_tabw(145,-1);
|
||||
|
||||
//DebugSession::close();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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.
|
|
@ -62,10 +62,6 @@ namespace Anabatic {
|
|||
NetBuilderM2::~NetBuilderM2 () { }
|
||||
|
||||
|
||||
string NetBuilderM2::getStyle ()
|
||||
{ return "2RL-"; }
|
||||
|
||||
|
||||
void NetBuilderM2::doRp_AutoContacts ( GCell* gcell
|
||||
, Component* rp
|
||||
, AutoContact*& source
|
||||
|
@ -191,7 +187,7 @@ namespace Anabatic {
|
|||
contact2 ->setFlags( CntFixed );
|
||||
|
||||
AutoSegment* fixed = AutoSegment::create( rpContact, contact1, Flags::Vertical );
|
||||
AutoSegment* dogleg = AutoSegment::create( contact1 , contact2, Flags::Horizontal|Flags::UseNonPref );
|
||||
AutoSegment* dogleg = AutoSegment::create( contact1 , contact2, Flags::Horizontal );
|
||||
fixed ->setFlags( AutoSegment::SegFixed );
|
||||
dogleg->setFlags( AutoSegment::SegFixed );
|
||||
|
||||
|
@ -322,7 +318,7 @@ namespace Anabatic {
|
|||
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
|
||||
|
||||
// HARDCODED VALUE.
|
||||
if ( (getTopology() & Global_Fixed) and (globalSegment->getAnchoredLength() < 2*Session::getSliceHeight()) )
|
||||
if ( (getTopology() & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) )
|
||||
addToFixSegments( globalSegment );
|
||||
|
||||
if (getConnexity().fields.globals < 2) {
|
||||
|
|
|
@ -67,10 +67,6 @@ namespace Anabatic {
|
|||
NetBuilderVH::~NetBuilderVH () { }
|
||||
|
||||
|
||||
string NetBuilderVH::getStyle ()
|
||||
{ return "VH,3RL+"; }
|
||||
|
||||
|
||||
void NetBuilderVH::doRp_AutoContacts ( GCell* gcell
|
||||
, Component* rp
|
||||
, AutoContact*& source
|
||||
|
@ -89,6 +85,7 @@ namespace Anabatic {
|
|||
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
|
||||
Flags direction = Session::getDirection ( rpDepth );
|
||||
DbU::Unit viaSide = Session::getViaWidth ( rpDepth );
|
||||
DbU::Unit gridPosition = 0;
|
||||
|
||||
getPositions( rp, sourcePosition, targetPosition );
|
||||
|
||||
|
@ -117,8 +114,56 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Quasi-punctual M1 terminal.
|
||||
if (flags & VSmall) {
|
||||
Box ab = rp->getCell()->getBoundingBox();
|
||||
RoutingLayerGauge* gaugeMetal3 = Session::getLayerGauge( 2 );
|
||||
DbU::Unit metal3axis = gaugeMetal3->getTrackPosition( ab.getYMin()
|
||||
, ab.getYMax()
|
||||
, sourcePosition.getY()
|
||||
, Constant::Nearest );
|
||||
DbU::Unit viaSideProtect = Session::getViaWidth((size_t)0);
|
||||
|
||||
AutoContact* sourceVia12 = AutoContactTerminal::create( sourceGCell
|
||||
, rp
|
||||
, Session::getContactLayer(0)
|
||||
, sourcePosition
|
||||
, viaSideProtect, viaSideProtect
|
||||
);
|
||||
AutoContact* targetVia12 = AutoContactTerminal::create( targetGCell
|
||||
, rp
|
||||
, Session::getContactLayer(0)
|
||||
, targetPosition
|
||||
, viaSideProtect, viaSideProtect
|
||||
);
|
||||
AutoContact* sourceVia23 = AutoContactTurn::create( sourceGCell, net, Session::getContactLayer(1) );
|
||||
AutoContact* targetVia23 = AutoContactTurn::create( targetGCell, net, Session::getContactLayer(1) );
|
||||
sourceVia23->setY( metal3axis );
|
||||
targetVia23->setY( metal3axis );
|
||||
sourceVia23->setX( sourcePosition.getX() );
|
||||
targetVia23->setX( targetPosition.getX() );
|
||||
|
||||
AutoSegment* segmentS = AutoSegment::create( sourceVia12, sourceVia23, Flags::Vertical );
|
||||
AutoSegment* segmentT = AutoSegment::create( targetVia12, targetVia23, Flags::Vertical );
|
||||
AutoSegment* segmentM = AutoSegment::create( sourceVia23, targetVia23, Flags::Horizontal );
|
||||
|
||||
sourceVia12->setFlags( CntFixed );
|
||||
sourceVia23->setFlags( CntFixed );
|
||||
targetVia12->setFlags( CntFixed );
|
||||
targetVia23->setFlags( CntFixed );
|
||||
segmentS->setFlags( AutoSegment::SegFixed );
|
||||
segmentT->setFlags( AutoSegment::SegFixed );
|
||||
segmentM->setFlags( AutoSegment::SegFixed );
|
||||
|
||||
cdebug_log(145,0) << "Hard protect: " << rp << endl;
|
||||
cdebug_log(145,0) << "X:" << DbU::getValueString(sourcePosition.getX())
|
||||
<< " Metal3 Track Y:" << DbU::getValueString(metal3axis) << endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Non-M1 terminal or punctual M1 protections.
|
||||
if ( (rpDepth != 0) or (sourcePosition == targetPosition) ) {
|
||||
if ( (rpDepth != 0) or ((sourcePosition == targetPosition) and (gridPosition == 0)) ) {
|
||||
map<Component*,AutoSegment*>::iterator irp = getRpLookup().find( rp );
|
||||
if (irp == getRpLookup().end()) {
|
||||
AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell
|
||||
|
@ -160,10 +205,6 @@ namespace Anabatic {
|
|||
);
|
||||
}
|
||||
|
||||
if ( (rpDepth > 0) and not Session::getRoutingGauge()->isSuperPitched() ) {
|
||||
rpLayer = Session::getContactLayer( rpDepth );
|
||||
}
|
||||
|
||||
if (not source and not target) {
|
||||
source = target = AutoContactTerminal::create( gcell
|
||||
, rp
|
||||
|
@ -182,46 +223,31 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl;
|
||||
|
||||
AutoContact* rpContactSource = NULL;
|
||||
AutoContact* rpContactTarget = NULL;
|
||||
const Layer* rpLayer = rp->getLayer();
|
||||
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
|
||||
AutoContact* rpContactSource;
|
||||
AutoContact* rpContactTarget;
|
||||
|
||||
flags |= checkRoutingPadSize( rp );
|
||||
|
||||
doRp_AutoContacts( gcell, rp, rpContactSource, rpContactTarget, flags );
|
||||
|
||||
if (rpDepth % 2 == 0) { // RP should be vertical (M1, M3).
|
||||
if (not (flags & (HAccess|HAccessEW))) {
|
||||
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical , rpDepth+2 );
|
||||
AutoSegment::create( subContact1, subContact2, Flags::Horizontal, rpDepth+1 );
|
||||
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical );
|
||||
AutoSegment::create( subContact1, subContact2, Flags::Horizontal );
|
||||
rpContactSource = subContact2;
|
||||
} else {
|
||||
if (flags & VSmall) {
|
||||
AutoContact* subContact1 = NULL;
|
||||
if (flags & HAccessEW)
|
||||
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
else
|
||||
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(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);
|
||||
|
||||
|
@ -495,12 +521,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
bool NetBuilderVH::_do_2G ()
|
||||
{
|
||||
cdebug_log(145,0) << getTypeName() << "::_do_2G()" << endl;
|
||||
return _do_xG();
|
||||
}
|
||||
|
||||
bool NetBuilderVH::_do_xG ()
|
||||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::_do_xG()" << endl;
|
||||
|
@ -551,7 +571,7 @@ namespace Anabatic {
|
|||
cdebug_log(145,0) << "Create global segment: " << globalSegment << endl;
|
||||
|
||||
// HARDCODED VALUE.
|
||||
if ( (getTopology() & Global_Fixed) and (globalSegment->getAnchoredLength() < 2*Session::getSliceHeight()) )
|
||||
if ( (getTopology() & Global_Fixed) and (globalSegment->getLength() < 2*Session::getSliceHeight()) )
|
||||
addToFixSegments( globalSegment );
|
||||
|
||||
if (getConnexity().fields.globals < 2) {
|
||||
|
|
|
@ -61,55 +61,55 @@ namespace {
|
|||
|
||||
void propagateConstraintFromRp ( RoutingPad* rp )
|
||||
{
|
||||
cdebug_log(146,1) << "propagateConstraintFromRp() - " << rp << endl;
|
||||
cdebug_log(145,1) << "propagateConstraintFromRp() - " << rp << endl;
|
||||
|
||||
for ( Component* component : rp->getSlaveComponents() ) {
|
||||
cdebug_log(146,0) << "slave component: " << component << endl;
|
||||
cdebug_log(145,0) << "slave component: " << component << endl;
|
||||
AutoContact* sourceContact = Session::lookup( dynamic_cast<Contact*>(component) );
|
||||
if (sourceContact) {
|
||||
Box constraintBox = sourceContact->getConstraintBox();
|
||||
|
||||
cdebug_log(146,0) << "Start slave: " << sourceContact << endl;
|
||||
cdebug_log(146,0) << "Constraint: " << constraintBox << endl;
|
||||
cdebug_log(145,0) << "Start slave: " << sourceContact << endl;
|
||||
cdebug_log(145,0) << "Constraint: " << constraintBox << endl;
|
||||
|
||||
set<AutoSegment*> verticalSegments;
|
||||
set<AutoSegment*> horizontalSegments;
|
||||
|
||||
for ( AutoSegment* segment : sourceContact->getAutoSegments() ) {
|
||||
cdebug_log(146,0) << "Examining: " << segment << endl;
|
||||
cdebug_log(145,0) << "Examining: " << segment << endl;
|
||||
AutoContact* targetContact = segment->getOppositeAnchor(sourceContact);
|
||||
|
||||
if (targetContact) {
|
||||
if (segment->isHorizontal()) {
|
||||
cdebug_log(146,0) << "On horizontal stack " << segment << endl;
|
||||
cdebug_log(145,0) << "On horizontal stack " << segment << endl;
|
||||
horizontalSegments.insert( segment );
|
||||
} else {
|
||||
cdebug_log(146,0) << "On vertical stack " << segment << endl;
|
||||
cdebug_log(145,0) << "On vertical stack " << segment << endl;
|
||||
verticalSegments.insert( segment );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Propagate constraint through horizontally aligned segments.
|
||||
cdebug_log(146,0) << "Propagate constraint on horizontal segments" << endl;
|
||||
cdebug_log(145,0) << "Propagate constraint on horizontal segments" << endl;
|
||||
|
||||
for ( AutoSegment* horizontal : horizontalSegments ) {
|
||||
AutoContact* contact = NULL;
|
||||
for ( AutoSegment* aligned : horizontal->getAligneds(Flags::WithSelf) ) {
|
||||
cdebug_log(146,0) << "aligned horizontal: " << aligned << endl;
|
||||
cdebug_log(145,0) << "aligned horizontal: " << aligned << endl;
|
||||
|
||||
contact = aligned->getAutoTarget();
|
||||
cdebug_log(146,0) << "contact: " << contact << endl;
|
||||
cdebug_log(145,0) << "contact: " << contact << endl;
|
||||
if (contact) {
|
||||
cdebug_log(146,0) << "Apply to (target): " << contact << endl;
|
||||
cdebug_log(145,0) << "Apply to (target): " << contact << endl;
|
||||
contact->restrictConstraintBox( constraintBox.getYMin()
|
||||
, constraintBox.getYMax()
|
||||
, Flags::Horizontal|Flags::WarnOnError );
|
||||
}
|
||||
contact = aligned->getAutoSource();
|
||||
cdebug_log(146,0) << "contact: " << contact << endl;
|
||||
cdebug_log(145,0) << "contact: " << contact << endl;
|
||||
if (contact) {
|
||||
cdebug_log(146,0) << "Apply to (source): " << contact << endl;
|
||||
cdebug_log(145,0) << "Apply to (source): " << contact << endl;
|
||||
contact->restrictConstraintBox( constraintBox.getYMin()
|
||||
, constraintBox.getYMax()
|
||||
, Flags::Horizontal|Flags::WarnOnError );
|
||||
|
@ -118,23 +118,23 @@ namespace {
|
|||
}
|
||||
|
||||
// Propagate constraint through vertically aligned segments.
|
||||
cdebug_log(146,0) << "Propagate constraint on vertical segments" << endl;
|
||||
cdebug_log(145,0) << "Propagate constraint on vertical segments" << endl;
|
||||
|
||||
for ( AutoSegment* vertical : verticalSegments ) {
|
||||
AutoContact* contact = NULL;
|
||||
for ( AutoSegment* aligned : vertical->getAligneds(Flags::WithSelf) ) {
|
||||
cdebug_log(146,0) << "aligned vertical: " << aligned << endl;
|
||||
cdebug_log(145,0) << "aligned vertical: " << aligned << endl;
|
||||
|
||||
contact = aligned->getAutoTarget();
|
||||
if (contact) {
|
||||
cdebug_log(146,0) << "Apply to (target): " << contact << endl;
|
||||
cdebug_log(145,0) << "Apply to (target): " << contact << endl;
|
||||
contact->restrictConstraintBox( constraintBox.getXMin()
|
||||
, constraintBox.getXMax()
|
||||
, Flags::Vertical|Flags::WarnOnError );
|
||||
}
|
||||
contact = aligned->getAutoSource();
|
||||
if (contact) {
|
||||
cdebug_log(146,0) << "Apply to (source): " << contact << endl;
|
||||
cdebug_log(145,0) << "Apply to (source): " << contact << endl;
|
||||
contact->restrictConstraintBox( constraintBox.getXMin()
|
||||
, constraintBox.getXMax()
|
||||
, Flags::Vertical|Flags::WarnOnError );
|
||||
|
@ -144,8 +144,8 @@ namespace {
|
|||
}
|
||||
}
|
||||
|
||||
cdebug_log(146,0) << "propagateConstraintFromRp() - Exit" << endl;
|
||||
cdebug_tabw(146,-1);
|
||||
cdebug_log(145,0) << "propagateConstraintFromRp() - Exit" << endl;
|
||||
cdebug_tabw(145,-1);
|
||||
}
|
||||
|
||||
|
||||
|
@ -159,128 +159,35 @@ namespace Anabatic {
|
|||
using Hurricane::Cell;
|
||||
|
||||
|
||||
void propagateDistanceFromRp ( RoutingPad* rp )
|
||||
{
|
||||
cdebug_log(146,1) << "propagateDistanceFromRp() - " << rp << endl;
|
||||
|
||||
unsigned int distance = 0;
|
||||
vector< pair<AutoContact*,AutoSegment*> > currents;
|
||||
vector< pair<AutoContact*,AutoSegment*> > successors;
|
||||
|
||||
for ( Component* component : rp->getSlaveComponents() ) {
|
||||
cdebug_log(146,0) << "slave component: " << component << endl;
|
||||
|
||||
AutoContact* sourceContact = Session::lookup( dynamic_cast<Contact*>(component) );
|
||||
if (sourceContact) {
|
||||
cdebug_log(146,0) << "Start slave: " << sourceContact << endl;
|
||||
|
||||
for ( AutoSegment* segment : sourceContact->getAutoSegments() ) {
|
||||
cdebug_log(146,0) << "Pushing: " << segment << endl;
|
||||
currents.push_back( make_pair(sourceContact,segment) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while ( not currents.empty() ) {
|
||||
for ( size_t i = 0 ; i<currents.size() ; ++i ) {
|
||||
AutoContact* source = currents[i].first;
|
||||
AutoSegment* segment = currents[i].second;
|
||||
|
||||
if ( (distance == 1) and (segment->getRpDistance() == 1) ) {
|
||||
vector<GCell*> gcells;
|
||||
segment->getGCells( gcells );
|
||||
|
||||
if (gcells.size() < 3)
|
||||
segment->setFlags( AutoSegment::SegUnbreakable );
|
||||
}
|
||||
|
||||
if (distance >= segment->getRpDistance()) continue;
|
||||
segment->setRpDistance( distance );
|
||||
cdebug_log(146,0) << "Popped: " << segment << endl;
|
||||
|
||||
AutoContact* target = segment->getOppositeAnchor( source );
|
||||
if (target) {
|
||||
for ( AutoSegment* successor : target->getAutoSegments() ) {
|
||||
if (successor == segment) continue;
|
||||
|
||||
// if (successor->isNonPref()) {
|
||||
// cdebug_log(146,0) << "Pushing (non-pref): " << successor << endl;
|
||||
// currents.push_back( make_pair(target,successor) );
|
||||
// } else {
|
||||
cdebug_log(146,0) << "Pushing: " << successor << endl;
|
||||
successors.push_back( make_pair(target,successor) );
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (++distance > 15) break;
|
||||
|
||||
currents.clear();
|
||||
currents.swap( successors );
|
||||
}
|
||||
|
||||
cdebug_log(146,0) << "propagateDistanceFromRp() - Exit" << endl;
|
||||
cdebug_tabw(146,-1);
|
||||
}
|
||||
|
||||
|
||||
void AnabaticEngine::computeNetConstraints ( Net* net )
|
||||
{
|
||||
DebugSession::open( net, 146, 150);
|
||||
DebugSession::open( net, 145, 150);
|
||||
|
||||
cdebug_log(149,0) << "Anabatic::computeNetConstraints( " << net << " )" << endl;
|
||||
cdebug_tabw(146,1);
|
||||
cdebug_tabw(145,1);
|
||||
|
||||
vector<RoutingPad*> routingPads;
|
||||
for ( Component* component : net->getComponents() ) {
|
||||
Contact* contact = dynamic_cast<Contact*>( component );
|
||||
forEach ( Component*, icomponent, net->getComponents() ) {
|
||||
Contact* contact = dynamic_cast<Contact*>( *icomponent );
|
||||
if (contact) {
|
||||
AutoContact* autoContact = Session::lookup( contact );
|
||||
if (autoContact)
|
||||
autoContact->restoreNativeConstraintBox();
|
||||
} else {
|
||||
Segment* segment = dynamic_cast<Segment*>( component );
|
||||
if (segment) {
|
||||
AutoSegment* autoSegment = Session::lookup( segment );
|
||||
if (autoSegment)
|
||||
autoSegment->setRpDistance( 15 );
|
||||
} else {
|
||||
RoutingPad* routingPad = dynamic_cast<RoutingPad*>( component );
|
||||
RoutingPad* routingPad = dynamic_cast<RoutingPad*>( *icomponent );
|
||||
if (routingPad) routingPads.push_back( routingPad );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( size_t i=0 ; i<routingPads.size() ; i++ ) {
|
||||
for ( size_t i=0 ; i<routingPads.size() ; i++ )
|
||||
propagateConstraintFromRp( routingPads[i] );
|
||||
propagateDistanceFromRp ( routingPads[i] );
|
||||
}
|
||||
|
||||
for ( Segment* segment : net->getSegments() ) {
|
||||
AutoSegment* autoSegment = Session::lookup( segment );
|
||||
if (not autoSegment) continue;
|
||||
if (autoSegment->isUnbreakable()) continue;
|
||||
if (autoSegment->getRpDistance() >= 2) continue;
|
||||
if (autoSegment->getRpDistance() == 1) continue;
|
||||
|
||||
vector<GCell*> gcells;
|
||||
autoSegment->getGCells( gcells );
|
||||
|
||||
if (gcells.size() > 2) continue;
|
||||
//if ( (gcells.size() == 2)
|
||||
// and ( not autoSegment->getAutoSource()->isTerminal()
|
||||
// or not autoSegment->getAutoTarget()->isTerminal()) ) continue;
|
||||
|
||||
autoSegment->setFlags( AutoSegment::SegUnbreakable );
|
||||
}
|
||||
|
||||
// forEach ( Segment*, isegment, net->getSegments() ) {
|
||||
// AutoSegment* autoSegment = Session::lookup( *isegment );
|
||||
// if (autoSegment) autoSegment->toConstraintAxis();
|
||||
// }
|
||||
|
||||
cdebug_tabw(146,-1);
|
||||
cdebug_tabw(145,-1);
|
||||
DebugSession::close();
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,6 @@ namespace Anabatic {
|
|||
using Hurricane::RegularLayer;
|
||||
using Hurricane::Component;
|
||||
using Hurricane::Pin;
|
||||
using Hurricane::Plug;
|
||||
using Hurricane::DeepNet;
|
||||
using Hurricane::Cell;
|
||||
using Hurricane::NetRoutingExtension;
|
||||
|
@ -83,87 +82,50 @@ namespace Anabatic {
|
|||
if (net->getType() == Net::Type::GROUND) continue;
|
||||
// Don't skip the clock.
|
||||
|
||||
vector<Pin*> pins;
|
||||
vector<Segment*> segments;
|
||||
vector<Contact*> contacts;
|
||||
|
||||
bool isManualGlobalRouted = false;
|
||||
bool isManualDetailRouted = false;
|
||||
bool isPreRouted = false;
|
||||
bool isFixed = false;
|
||||
size_t rpCount = 0;
|
||||
|
||||
for( Component* component : net->getComponents() ) {
|
||||
Pin* pin = dynamic_cast<Pin *>( component );
|
||||
if (pin) {
|
||||
pins.push_back( pin );
|
||||
continue;
|
||||
}
|
||||
if (dynamic_cast<Plug*>(component)) continue;
|
||||
if (dynamic_cast<Pin*>(component)) continue;
|
||||
|
||||
const RegularLayer* layer = dynamic_cast<const RegularLayer*>(component->getLayer());
|
||||
if (layer and (layer->getBasicLayer()->getMaterial() == BasicLayer::Material::blockage))
|
||||
continue;
|
||||
|
||||
if ( not Session::isGaugeLayer(component->getLayer())
|
||||
and not Session::isGLayer (component->getLayer())) {
|
||||
const BasicLayer* basicLayer = dynamic_cast<const BasicLayer*>( component->getLayer() );
|
||||
if (basicLayer and (basicLayer->getMaterial() == BasicLayer::Material::cut))
|
||||
continue;
|
||||
throw Error( "AnabaticEngine::setupPreRouted(): A component of \"%s\" has a routing gauge umanaged layer.\n"
|
||||
" (%s)"
|
||||
, getString(net->getName()).c_str()
|
||||
, getString(component).c_str()
|
||||
);
|
||||
}
|
||||
|
||||
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;
|
||||
isPreRouted = true;
|
||||
if (horizontal->getWidth() != Session::getWireWidth(horizontal->getLayer()))
|
||||
isFixed = true;
|
||||
}
|
||||
} else {
|
||||
Vertical* vertical = dynamic_cast<Vertical*>(component);
|
||||
if (vertical) {
|
||||
if ( not ab.contains(vertical->getSourcePosition())
|
||||
and not ab.contains(vertical->getTargetPosition()) ) continue;
|
||||
|
||||
if (Session::isGLayer(component->getLayer())) {
|
||||
isManualGlobalRouted = true;
|
||||
} else {
|
||||
isManualDetailRouted = true;
|
||||
isPreRouted = true;
|
||||
segments.push_back( vertical );
|
||||
if (vertical->getWidth() != Session::getWireWidth(vertical->getLayer()))
|
||||
isFixed = true;
|
||||
}
|
||||
} else {
|
||||
Pin* pin = dynamic_cast<Pin*>(component);
|
||||
if (pin) {
|
||||
//cerr << "| " << pin << endl;
|
||||
if (not ab.intersect(pin->getBoundingBox())) continue;
|
||||
pins.push_back( pin );
|
||||
} else {
|
||||
Contact* contact = dynamic_cast<Contact*>(component);
|
||||
if (contact) {
|
||||
if (not ab.contains(contact->getCenter())) continue;
|
||||
|
||||
if (Session::isGLayer(component->getLayer())) {
|
||||
isManualGlobalRouted = true;
|
||||
} else {
|
||||
isManualGlobalRouted = true;
|
||||
isPreRouted = true;
|
||||
contacts.push_back( contact );
|
||||
if ( (contact->getWidth () != Session::getViaWidth(contact->getLayer()))
|
||||
or (contact->getHeight() != Session::getViaWidth(contact->getLayer()))
|
||||
or (contact->getLayer () == Session::getContactLayer(0)) )
|
||||
isFixed = true;
|
||||
}
|
||||
} else {
|
||||
RoutingPad* rp = dynamic_cast<RoutingPad*>(component);
|
||||
if (rp) {
|
||||
|
@ -179,20 +141,8 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cerr << net << " deepNet:" << net->isDeepNet()
|
||||
// << " pins:" << pins.size()
|
||||
// << " segments:" << segments.size() << endl;
|
||||
if (not net->isDeepNet() and (pins.size() >= 1) and (segments.size() < 2)) {
|
||||
++toBeRouteds;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( (not isFixed)
|
||||
and (not isManualGlobalRouted)
|
||||
and (not isManualDetailRouted)
|
||||
and net->isDeepNet()) {
|
||||
if ((not isFixed and not isPreRouted) and net->isDeepNet()) {
|
||||
Net* rootNet = dynamic_cast<Net*>(
|
||||
dynamic_cast<DeepNet*>(net)->getRootNetOccurrence().getEntity() );
|
||||
for( Component* component : rootNet->getComponents() ) {
|
||||
|
@ -202,41 +152,32 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
|
||||
if (isFixed or isManualDetailRouted or isManualGlobalRouted or (rpCount < 2)) {
|
||||
if (isFixed or isPreRouted or (rpCount < 2)) {
|
||||
NetData* ndata = getNetData( net, Flags::Create );
|
||||
NetRoutingState* state = ndata->getNetRoutingState();
|
||||
state->unsetFlags( NetRoutingState::AutomaticGlobalRoute );
|
||||
if (isManualGlobalRouted) {
|
||||
state->setFlags( NetRoutingState::ManualGlobalRoute );
|
||||
ndata->setGlobalFixed( true );
|
||||
}
|
||||
if (isManualDetailRouted)
|
||||
state->setFlags( NetRoutingState::ManualDetailRoute );
|
||||
state->setFlags ( NetRoutingState::ManualGlobalRoute );
|
||||
ndata->setGlobalRouted( true );
|
||||
if (rpCount < 2)
|
||||
state->setFlags( NetRoutingState::Unconnected );
|
||||
state->setFlags ( NetRoutingState::Unconnected );
|
||||
|
||||
if (isFixed) {
|
||||
if (rpCount > 1)
|
||||
cmess2 << " - <" << net->getName() << "> is fixed." << endl;
|
||||
state->unsetFlags( NetRoutingState::ManualGlobalRoute|NetRoutingState::ManualDetailRoute );
|
||||
state->unsetFlags( NetRoutingState::ManualGlobalRoute );
|
||||
state->setFlags ( NetRoutingState::Fixed );
|
||||
} else if (isManualGlobalRouted) {
|
||||
cmess2 << " - <" << net->getName() << "> is manually global routed." << endl;
|
||||
} else if (isManualDetailRouted) {
|
||||
} else {
|
||||
if (rpCount > 1) {
|
||||
++toBeRouteds;
|
||||
cmess2 << " - <" << net->getName() << "> is manually detail routed." << endl;
|
||||
for ( auto contact : contacts ) {
|
||||
AutoContact::createFrom( contact );
|
||||
|
||||
cmess2 << " - <" << net->getName() << "> is manually global routed." << endl;
|
||||
for ( auto icontact : contacts ) {
|
||||
AutoContact::createFrom( icontact );
|
||||
}
|
||||
|
||||
for ( auto segment : segments ) {
|
||||
AutoContact* source = Session::lookup( dynamic_cast<Contact*>( segment->getSource() ));
|
||||
AutoContact* target = Session::lookup( dynamic_cast<Contact*>( segment->getTarget() ));
|
||||
if (not source or not target) {
|
||||
cerr << Error( "Unable to protect %s", getString(segment).c_str() ) << endl;
|
||||
continue;
|
||||
}
|
||||
AutoSegment* autoSegment = AutoSegment::create( source, target, segment );
|
||||
autoSegment->setFlags( AutoSegment::SegUserDefined|AutoSegment::SegAxisSet );
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "hurricane/isobar/PyHurricane.h"
|
||||
#include "hurricane/isobar/PyCell.h"
|
||||
#include "anabatic/PyStyleFlags.h"
|
||||
#include "anabatic/Constants.h"
|
||||
|
||||
|
||||
namespace Anabatic {
|
||||
|
@ -55,41 +55,19 @@ extern "C" {
|
|||
};
|
||||
|
||||
|
||||
static PyModuleDef PyAnabatic_ModuleDef =
|
||||
{ PyModuleDef_HEAD_INIT
|
||||
, "Anabatic" /* m_name */
|
||||
, "Low level database for global & detailed routing."
|
||||
/* m_doc */
|
||||
, -1 /* m_size */
|
||||
, PyAnabatic_Methods /* m_methods */
|
||||
, NULL /* m_reload */
|
||||
, NULL /* m_traverse */
|
||||
, NULL /* m_clear */
|
||||
, NULL /* m_free */
|
||||
};
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
// Module Initialization : "initAnabatic ()"
|
||||
|
||||
PyMODINIT_FUNC PyInit_Anabatic ( void )
|
||||
{
|
||||
cdebug_log(32,0) << "PyInit_Anabatic()" << endl;
|
||||
DL_EXPORT(void) initAnabatic () {
|
||||
cdebug_log(32,0) << "initAnabatic()" << endl;
|
||||
|
||||
PyStyleFlags_LinkPyType();
|
||||
|
||||
PYTYPE_READY( StyleFlags );
|
||||
|
||||
PyObject* module = PyModule_Create( &PyAnabatic_ModuleDef );
|
||||
PyObject* module = Py_InitModule( "Anabatic", PyAnabatic_Methods );
|
||||
if (module == NULL) {
|
||||
cerr << "[ERROR]\n"
|
||||
<< " Failed to initialize Anabatic module." << endl;
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
Py_INCREF( &PyTypeStyleFlags );
|
||||
PyModule_AddObject( module, "StyleFlags", (PyObject*)&PyTypeStyleFlags );
|
||||
|
||||
PyObject* dictionnary = PyModule_GetDict(module);
|
||||
PyObject* constant;
|
||||
|
||||
|
@ -99,9 +77,6 @@ extern "C" {
|
|||
LoadObjectConstant( dictionnary,EngineLayerAssignByTrunk ,"EngineLayerAssignByTrunk" );
|
||||
LoadObjectConstant( dictionnary,EngineLayerAssignNoGlobalM2V,"EngineLayerAssignNoGlobalM2V" );
|
||||
LoadObjectConstant( dictionnary,EngineNoNetLayerAssign ,"EngineNoNetLayerAssign" );
|
||||
|
||||
PyStyleFlags_postModuleInit();
|
||||
return module;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
@ -82,12 +82,7 @@ namespace Anabatic {
|
|||
, _segmentRevalidateds()
|
||||
, _netInvalidateds ()
|
||||
, _netRevalidateds ()
|
||||
{
|
||||
_autoContacts .reserve( 1024 );
|
||||
_doglegs .reserve( 1024 );
|
||||
_segmentInvalidateds.reserve( 1024 );
|
||||
_segmentRevalidateds.reserve( 1024 );
|
||||
}
|
||||
{ }
|
||||
|
||||
|
||||
void Session::_postCreate ()
|
||||
|
@ -215,20 +210,16 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_log(145,1) << "Anabatic::Session::_revalidateTopology()" << endl;
|
||||
|
||||
_anabatic->disableCanonize();
|
||||
for ( Net* net : _netInvalidateds ) {
|
||||
cdebug_log(145,0) << "Anabatic::Session::_revalidateTopology(Net*)" << net << endl;
|
||||
_anabatic->updateNetTopology ( net );
|
||||
_anabatic->computeNetConstraints( net );
|
||||
_anabatic->_computeNetOptimals ( net );
|
||||
//_anabatic->_computeNetTerminals ( net );
|
||||
_anabatic->_computeNetTerminals ( net );
|
||||
}
|
||||
_anabatic->enableCanonize();
|
||||
_canonize ();
|
||||
|
||||
AutoSegment* segment = NULL;
|
||||
for ( size_t i=0 ; i<_segmentInvalidateds.size() ; ++i ) {
|
||||
segment = _segmentInvalidateds[i];
|
||||
for ( AutoSegment* segment : _segmentInvalidateds ) {
|
||||
if (segment->isCanonical()) {
|
||||
if (segment->isUnsetAxis()) segment->toOptimalAxis();
|
||||
else segment->toConstraintAxis();
|
||||
|
@ -261,8 +252,6 @@ namespace Anabatic {
|
|||
cdebug_log(145,0) << "_segmentInvalidateds.size(): " << _segmentInvalidateds.size() << endl;
|
||||
|
||||
_segmentRevalidateds.clear();
|
||||
std::sort( _segmentInvalidateds.begin(), _segmentInvalidateds.end()
|
||||
, AutoSegment::CompareByRevalidate() );
|
||||
for ( size_t i=0 ; i < _segmentInvalidateds.size() ; ++i, ++count ) {
|
||||
_segmentInvalidateds[i]->revalidate();
|
||||
if ( not _destroyedSegments.empty()
|
||||
|
@ -364,31 +353,6 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
DbU::Unit Session::_getNearestTrackAxis ( const Layer* layer, DbU::Unit axis, uint32_t mode )
|
||||
{
|
||||
Box ab = _anabatic->getCell()->getAbutmentBox();
|
||||
|
||||
RoutingLayerGauge* lg = _routingGauge->getLayerGauge( layer );
|
||||
if (not lg) return axis;
|
||||
|
||||
DbU::Unit minAxis = 0;
|
||||
DbU::Unit maxAxis = 0;
|
||||
if (lg->getDirection() == Constant::Horizontal) {
|
||||
minAxis = ab.getYMin();
|
||||
maxAxis = ab.getYMax();
|
||||
} else {
|
||||
minAxis = ab.getXMin();
|
||||
maxAxis = ab.getXMax();
|
||||
}
|
||||
DbU::Unit trackAxis = lg->getTrackPosition( minAxis
|
||||
, lg->getTrackIndex( minAxis
|
||||
, maxAxis
|
||||
, axis
|
||||
, mode ) );
|
||||
return trackAxis;
|
||||
}
|
||||
|
||||
|
||||
Point Session::_getNearestGridPoint ( Point p, Box constraint )
|
||||
{
|
||||
Box ab = _anabatic->getCell()->getAbutmentBox();
|
||||
|
@ -412,25 +376,14 @@ namespace Anabatic {
|
|||
if (y < constraint.getYMin()) y += lg->getPitch();
|
||||
if (y > constraint.getYMax()) y -= lg->getPitch();
|
||||
|
||||
y = std::max( y, constraint.getYMin() );
|
||||
y = std::min( y, constraint.getYMax() );
|
||||
|
||||
return Point(x,y);
|
||||
}
|
||||
|
||||
|
||||
StyleFlags Session::getRoutingStyle ()
|
||||
{ return get("getRoutingStyle()")->_anabatic->getRoutingStyle(); }
|
||||
|
||||
|
||||
bool Session::isInDemoMode ()
|
||||
{ return get("isInDemoMode()")->_anabatic->isInDemoMode(); }
|
||||
|
||||
|
||||
bool Session::isChannelStyle ()
|
||||
{ return get("isChannelStyle()")->_anabatic->isChannelStyle(); }
|
||||
|
||||
|
||||
float Session::getSaturateRatio ()
|
||||
{ return get("getSaturateRatio()")->_anabatic->getSaturateRatio(); }
|
||||
|
||||
|
|
|
@ -0,0 +1,646 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2008-2018, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | A n a b a t i c - Routing Toolbox |
|
||||
// | |
|
||||
// | Author : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Header : "./anabatic/AutoSegment.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef ANABATIC_AUTOSEGMENT_H
|
||||
#define ANABATIC_AUTOSEGMENT_H
|
||||
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
#include "hurricane/Interval.h"
|
||||
#include "hurricane/Segment.h"
|
||||
#include "hurricane/Components.h"
|
||||
#include "hurricane/Contact.h"
|
||||
namespace Hurricane {
|
||||
class Layer;
|
||||
class Horizontal;
|
||||
class Vertical;
|
||||
class Cell;
|
||||
}
|
||||
#include "crlcore/RoutingGauge.h"
|
||||
#include "anabatic/Constants.h"
|
||||
#include "anabatic/GCell.h"
|
||||
#include "anabatic/AutoSegments.h"
|
||||
#include "anabatic/Session.h"
|
||||
|
||||
|
||||
namespace Anabatic {
|
||||
|
||||
using std::array;
|
||||
using std::set;
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
using std::binary_function;
|
||||
using Hurricane::StaticObservable;
|
||||
using Hurricane::BaseObserver;
|
||||
using Hurricane::tab;
|
||||
using Hurricane::Interval;
|
||||
using Hurricane::Layer;
|
||||
using Hurricane::Components;
|
||||
using Hurricane::Horizontal;
|
||||
using Hurricane::Vertical;
|
||||
using Hurricane::Cell;
|
||||
using CRL::RoutingGauge;
|
||||
|
||||
class AutoHorizontal;
|
||||
class AutoVertical;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "AutoSegment".
|
||||
|
||||
|
||||
|
||||
class AutoSegment {
|
||||
friend class AutoHorizontal;
|
||||
friend class AutoVertical;
|
||||
|
||||
public:
|
||||
static const uint64_t SegNoFlags = 0L;
|
||||
static const uint64_t SegHorizontal = (1L<< 0);
|
||||
static const uint64_t SegFixed = (1L<< 1);
|
||||
static const uint64_t SegFixedAxis = (1L<< 2);
|
||||
static const uint64_t SegGlobal = (1L<< 3);
|
||||
static const uint64_t SegWeakGlobal = (1L<< 4);
|
||||
static const uint64_t SegLongLocal = (1L<< 5);
|
||||
static const uint64_t SegCanonical = (1L<< 6);
|
||||
static const uint64_t SegBipoint = (1L<< 7);
|
||||
static const uint64_t SegDogleg = (1L<< 8);
|
||||
static const uint64_t SegStrap = (1L<< 9);
|
||||
static const uint64_t SegSourceTop = (1L<<10);
|
||||
static const uint64_t SegSourceBottom = (1L<<11);
|
||||
static const uint64_t SegTargetTop = (1L<<12);
|
||||
static const uint64_t SegTargetBottom = (1L<<13);
|
||||
static const uint64_t SegIsReduced = (1L<<14);
|
||||
static const uint64_t SegDrag = (1L<<15);
|
||||
static const uint64_t SegLayerChange = (1L<<16);
|
||||
static const uint64_t SegSourceTerminal = (1L<<17); // Replace Terminal.
|
||||
static const uint64_t SegTargetTerminal = (1L<<18); // Replace Terminal.
|
||||
static const uint64_t SegStrongTerminal = SegSourceTerminal|SegTargetTerminal;
|
||||
static const uint64_t SegWeakTerminal1 = (1L<<19); // Replace TopologicalEnd.
|
||||
static const uint64_t SegWeakTerminal2 = (1L<<20); // Replace TopologicalEnd.
|
||||
static const uint64_t SegNotSourceAligned = (1L<<21);
|
||||
static const uint64_t SegNotTargetAligned = (1L<<22);
|
||||
static const uint64_t SegUnbound = (1L<<23);
|
||||
static const uint64_t SegHalfSlackened = (1L<<24);
|
||||
static const uint64_t SegSlackened = (1L<<25);
|
||||
static const uint64_t SegAxisSet = (1L<<26);
|
||||
static const uint64_t SegInvalidated = (1L<<27);
|
||||
static const uint64_t SegInvalidatedSource = (1L<<28);
|
||||
static const uint64_t SegInvalidatedTarget = (1L<<29);
|
||||
static const uint64_t SegInvalidatedLayer = (1L<<30);
|
||||
static const uint64_t SegCreated = (1L<<31);
|
||||
static const uint64_t SegUserDefined = (1L<<32);
|
||||
static const uint64_t SegAnalog = (1L<<33);
|
||||
static const uint64_t SegWide = (1L<<34);
|
||||
// Masks.
|
||||
static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2;
|
||||
static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned;
|
||||
static const uint64_t SegSpinTop = SegSourceTop |SegTargetTop;
|
||||
static const uint64_t SegSpinBottom = SegSourceBottom |SegTargetBottom;
|
||||
static const uint64_t SegDepthSpin = SegSpinTop |SegSpinBottom;
|
||||
|
||||
public:
|
||||
class Observable : public StaticObservable<1> {
|
||||
public:
|
||||
enum Indexes { TrackSegment = 0
|
||||
};
|
||||
public:
|
||||
inline Observable ();
|
||||
private:
|
||||
Observable ( const StaticObservable& );
|
||||
Observable& operator= ( const StaticObservable& );
|
||||
};
|
||||
public:
|
||||
enum ObserverFlag { Create = (1 << 0)
|
||||
, Destroy = (1 << 1)
|
||||
, Invalidate = (1 << 2)
|
||||
, Revalidate = (1 << 3)
|
||||
, RevalidatePPitch = (1 << 4)
|
||||
};
|
||||
public:
|
||||
typedef std::function< void(AutoSegment*) > RevalidateCb_t;
|
||||
public:
|
||||
static void setAnalogMode ( bool );
|
||||
static bool getAnalogMode ();
|
||||
inline static DbU::Unit getViaToTopCap ( size_t depth );
|
||||
inline static DbU::Unit getViaToBottomCap ( size_t depth );
|
||||
inline static DbU::Unit getViaToSameCap ( size_t depth );
|
||||
static AutoSegment* create ( AutoContact* source
|
||||
, AutoContact* target
|
||||
, Segment* hurricaneSegment
|
||||
);
|
||||
static AutoSegment* create ( AutoContact* source
|
||||
, AutoContact* target
|
||||
, Flags dir
|
||||
, size_t depth=RoutingGauge::nlayerdepth
|
||||
);
|
||||
void destroy ();
|
||||
// Wrapped Segment Functions.
|
||||
virtual Segment* base () const = 0;
|
||||
virtual Segment* base () = 0;
|
||||
virtual Horizontal* getHorizontal () { return NULL; };
|
||||
virtual Vertical* getVertical () { return NULL; };
|
||||
inline Cell* getCell () const;
|
||||
inline Net* getNet () const;
|
||||
inline const Layer* getLayer () const;
|
||||
inline Box getBoundingBox () const;
|
||||
inline Hook* getSourceHook ();
|
||||
inline Hook* getTargetHook ();
|
||||
inline Contact* getSource () const;
|
||||
inline Contact* getTarget () const;
|
||||
inline Component* getOppositeAnchor ( Component* ) const;
|
||||
inline Components getAnchors () const;
|
||||
virtual DbU::Unit getX () const;
|
||||
virtual DbU::Unit getY () const;
|
||||
inline DbU::Unit getWidth () const;
|
||||
inline DbU::Unit getContactWidth () const;
|
||||
inline DbU::Unit getLength () const;
|
||||
inline DbU::Unit getSourcePosition () const;
|
||||
inline DbU::Unit getTargetPosition () const;
|
||||
inline DbU::Unit getSourceX () const;
|
||||
inline DbU::Unit getSourceY () const;
|
||||
inline DbU::Unit getTargetX () const;
|
||||
inline DbU::Unit getTargetY () const;
|
||||
inline void invert ();
|
||||
inline void setLayer ( const Layer* );
|
||||
// Predicates.
|
||||
inline bool isHorizontal () const;
|
||||
inline bool isVertical () const;
|
||||
inline bool isGlobal () const;
|
||||
inline bool isWeakGlobal () const;
|
||||
inline bool isLongLocal () const;
|
||||
inline bool isLocal () const;
|
||||
inline bool isFixed () const;
|
||||
inline bool isFixedAxis () const;
|
||||
inline bool isBipoint () const;
|
||||
inline bool isWeakTerminal () const;
|
||||
inline bool isWeakTerminal1 () const;
|
||||
inline bool isWeakTerminal2 () const;
|
||||
inline bool isTerminal () const;
|
||||
inline bool isDrag () const;
|
||||
inline bool isNotSourceAligned () const;
|
||||
inline bool isNotTargetAligned () const;
|
||||
inline bool isNotAligned () const;
|
||||
bool isStrongTerminal ( Flags flags=Flags::NoFlags ) const;
|
||||
inline bool isSourceTerminal () const;
|
||||
inline bool isTargetTerminal () const;
|
||||
inline bool isLayerChange () const;
|
||||
inline bool isSpinTop () const;
|
||||
inline bool isSpinBottom () const;
|
||||
inline bool isSpinTopOrBottom () const;
|
||||
inline bool isReduced () const;
|
||||
inline bool isStrap () const;
|
||||
inline bool isDogleg () const;
|
||||
inline bool isUnbound () const;
|
||||
inline bool isInvalidated () const;
|
||||
inline bool isInvalidatedLayer () const;
|
||||
inline bool isCreated () const;
|
||||
inline bool isCanonical () const;
|
||||
inline bool isUnsetAxis () const;
|
||||
inline bool isSlackened () const;
|
||||
inline bool isUserDefined () const;
|
||||
bool isReduceCandidate () const;
|
||||
bool isUTurn () const;
|
||||
inline bool isAnalog () const;
|
||||
inline bool isWide () const;
|
||||
virtual bool _canSlacken () const = 0;
|
||||
bool canReduce () const;
|
||||
bool mustRaise () const;
|
||||
Flags canDogleg ( Interval );
|
||||
virtual bool canMoveULeft ( float reserve=0.0 ) const = 0;
|
||||
virtual bool canMoveURight ( float reserve=0.0 ) const = 0;
|
||||
bool canMoveUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
|
||||
bool canPivotUp ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
|
||||
bool canPivotDown ( float reserve=0.0, Flags flags=Flags::NoFlags ) const;
|
||||
bool canSlacken ( Flags flags=Flags::NoFlags ) const;
|
||||
virtual bool checkPositions () const = 0;
|
||||
virtual bool checkConstraints () const = 0;
|
||||
bool checkDepthSpin () const;
|
||||
// Accessors.
|
||||
inline unsigned long getId () const;
|
||||
inline uint64_t getFlags () const;
|
||||
virtual Flags getDirection () const = 0;
|
||||
inline GCell* getGCell () const;
|
||||
virtual bool getGCells ( vector<GCell*>& ) const = 0;
|
||||
inline AutoContact* getAutoSource () const;
|
||||
inline AutoContact* getAutoTarget () const;
|
||||
AutoContact* getOppositeAnchor ( AutoContact* ) const;
|
||||
size_t getPerpandicularsBound ( set<AutoSegment*>& );
|
||||
inline AutoSegment* getParent () const;
|
||||
inline unsigned int getDepth () const;
|
||||
inline DbU::Unit getPitch () const;
|
||||
DbU::Unit getPPitch () const;
|
||||
#if DISABLED
|
||||
DbU::Unit getExtensionCap () const;
|
||||
#endif
|
||||
DbU::Unit getExtensionCap ( Flags ) const;
|
||||
inline DbU::Unit getAxis () const;
|
||||
void getEndAxes ( DbU::Unit& sourceAxis, DbU::Unit& targetAxis ) const;
|
||||
virtual DbU::Unit getSourceU () const = 0;
|
||||
virtual DbU::Unit getTargetU () const = 0;
|
||||
virtual DbU::Unit getDuSource () const = 0;
|
||||
virtual DbU::Unit getDuTarget () const = 0;
|
||||
inline DbU::Unit getOrigin () const;
|
||||
inline DbU::Unit getExtremity () const;
|
||||
virtual Interval getSpanU () const = 0;
|
||||
Interval getMinSpanU () const;
|
||||
virtual Interval getSourceConstraints ( Flags flags=Flags::NoFlags ) const = 0;
|
||||
virtual Interval getTargetConstraints ( Flags flags=Flags::NoFlags ) const = 0;
|
||||
virtual bool getConstraints ( DbU::Unit& min, DbU::Unit& max ) const = 0;
|
||||
inline bool getConstraints ( Interval& i ) const;
|
||||
inline const Interval& getUserConstraints () const;
|
||||
inline const Interval& getNativeConstraints () const;
|
||||
virtual DbU::Unit getSlack () const;
|
||||
inline DbU::Unit getOptimalMin () const;
|
||||
inline DbU::Unit getOptimalMax () const;
|
||||
inline DbU::Unit getNativeMin () const;
|
||||
inline DbU::Unit getNativeMax () const;
|
||||
Interval& getOptimal ( Interval& i ) const;
|
||||
virtual DbU::Unit getCost ( DbU::Unit axis ) const;
|
||||
virtual AutoSegment* getCanonical ( DbU::Unit& min , DbU::Unit& max );
|
||||
inline AutoSegment* getCanonical ( Interval& i );
|
||||
float getMaxUnderDensity ( Flags flags );
|
||||
// Modifiers.
|
||||
inline void unsetFlags ( uint64_t );
|
||||
inline void setFlags ( uint64_t );
|
||||
void setFlagsOnAligneds ( uint64_t );
|
||||
inline void incReduceds ();
|
||||
inline void decReduceds ();
|
||||
virtual void setDuSource ( DbU::Unit du ) = 0;
|
||||
virtual void setDuTarget ( DbU::Unit du ) = 0;
|
||||
void computeTerminal ();
|
||||
virtual void updateOrient () = 0;
|
||||
virtual void updatePositions () = 0;
|
||||
virtual void updateNativeConstraints () = 0;
|
||||
void updateSourceSpin ();
|
||||
void updateTargetSpin ();
|
||||
void sourceDetach ();
|
||||
void targetDetach ();
|
||||
void sourceAttach ( AutoContact* );
|
||||
void targetAttach ( AutoContact* );
|
||||
//inline void mergeUserConstraints ( const Interval& );
|
||||
void mergeUserConstraints ( const Interval& );
|
||||
inline void resetUserConstraints ();
|
||||
inline void setOptimalMin ( DbU::Unit min );
|
||||
inline void setOptimalMax ( DbU::Unit max );
|
||||
inline void mergeNativeMin ( DbU::Unit min );
|
||||
inline void mergeNativeMax ( DbU::Unit max );
|
||||
inline void resetNativeConstraints ( DbU::Unit min, DbU::Unit max );
|
||||
bool checkNotInvalidated () const;
|
||||
inline void setParent ( AutoSegment* );
|
||||
void revalidate ();
|
||||
AutoSegment* makeDogleg ( AutoContact* );
|
||||
Flags makeDogleg ( Interval, Flags flags=Flags::NoFlags );
|
||||
Flags makeDogleg ( GCell* , Flags flags=Flags::NoFlags );
|
||||
virtual Flags _makeDogleg ( GCell* , Flags flags ) = 0;
|
||||
virtual bool moveULeft () = 0;
|
||||
virtual bool moveURight () = 0;
|
||||
bool slacken ( Flags flags );
|
||||
virtual bool _slacken ( Flags flags ) = 0;
|
||||
void _changeDepth ( unsigned int depth, Flags flags );
|
||||
void changeDepth ( unsigned int depth, Flags flags );
|
||||
bool moveUp ( Flags flags=Flags::NoFlags );
|
||||
bool moveDown ( Flags flags=Flags::NoFlags );
|
||||
bool reduceDoglegLayer ();
|
||||
bool reduce ();
|
||||
bool raise ();
|
||||
// Canonical Modifiers.
|
||||
AutoSegment* canonize ( Flags flags=Flags::NoFlags );
|
||||
virtual void invalidate ( Flags flags=Flags::Propagate );
|
||||
void invalidate ( AutoContact* );
|
||||
void computeOptimal ( set<AutoSegment*>& processeds );
|
||||
void setAxis ( DbU::Unit, Flags flags=Flags::NoFlags );
|
||||
bool toConstraintAxis ( Flags flags=Flags::Realignate );
|
||||
bool toOptimalAxis ( Flags flags=Flags::Realignate );
|
||||
// Collections & Filters.
|
||||
AutoSegments getOnSourceContact ( Flags direction );
|
||||
AutoSegments getOnTargetContact ( Flags direction );
|
||||
AutoSegments getCachedOnSourceContact ( Flags direction );
|
||||
AutoSegments getCachedOnTargetContact ( Flags direction );
|
||||
AutoSegments getAligneds ( Flags flags=Flags::NoFlags );
|
||||
AutoSegments getConnecteds ( Flags flags=Flags::NoFlags );
|
||||
AutoSegments getPerpandiculars ( Flags flags=Flags::NoFlags );
|
||||
size_t getAlignedContacts ( map<AutoContact*,int>& ) const ;
|
||||
// Observers.
|
||||
template< typename OwnerT >
|
||||
inline OwnerT* getObserver ( size_t slot );
|
||||
inline void setObserver ( size_t slot, BaseObserver* );
|
||||
inline void notify ( unsigned int flags );
|
||||
// Inspector Management.
|
||||
virtual Record* _getRecord () const = 0;
|
||||
virtual string _getString () const = 0;
|
||||
virtual string _getTypeName () const = 0;
|
||||
// Non-reviewed atomic modifiers.
|
||||
bool _check () const;
|
||||
#if THIS_IS_DISABLED
|
||||
virtual void desalignate ( AutoContact* ) = 0;
|
||||
bool shearUp ( GCell*
|
||||
, AutoSegment*& movedUp
|
||||
, float reserve
|
||||
, Flags flags );
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// Internal: Static Attributes.
|
||||
static size_t _allocateds;
|
||||
static size_t _globalsCount;
|
||||
static bool _analogMode;
|
||||
static bool _initialized;
|
||||
static vector< array<DbU::Unit*,3> > _extensionCaps;
|
||||
// Internal: Attributes.
|
||||
const unsigned long _id;
|
||||
GCell* _gcell;
|
||||
uint64_t _flags;
|
||||
unsigned int _depth : 8;
|
||||
unsigned int _optimalMin :16;
|
||||
unsigned int _optimalMax :16;
|
||||
unsigned int _reduceds : 2;
|
||||
DbU::Unit _sourcePosition;
|
||||
DbU::Unit _targetPosition;
|
||||
Interval _userConstraints;
|
||||
Interval _nativeConstraints;
|
||||
AutoSegment* _parent;
|
||||
Observable _observers;
|
||||
|
||||
// Internal: Constructors & Destructors.
|
||||
protected:
|
||||
AutoSegment ( Segment* segment );
|
||||
virtual ~AutoSegment ();
|
||||
static void _preCreate ( AutoContact* source, AutoContact* target );
|
||||
virtual void _postCreate ();
|
||||
virtual void _preDestroy ();
|
||||
static void _initialize ();
|
||||
private:
|
||||
AutoSegment ( const AutoSegment& );
|
||||
AutoSegment& operator= ( const AutoSegment& );
|
||||
protected:
|
||||
void _invalidate ();
|
||||
inline uint64_t _getFlags () const;
|
||||
std::string _getStringFlags () const;
|
||||
virtual void _setAxis ( DbU::Unit ) = 0;
|
||||
|
||||
public:
|
||||
struct CompareId : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||
inline bool operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const;
|
||||
};
|
||||
public:
|
||||
struct CompareByDepthLength : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
|
||||
};
|
||||
public:
|
||||
struct CompareByDepthAxis : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
|
||||
};
|
||||
public:
|
||||
typedef std::set<AutoSegment*,CompareByDepthLength> DepthLengthSet;
|
||||
typedef std::set<AutoSegment*,CompareId> IdSet;
|
||||
|
||||
// Static Utilities.
|
||||
public:
|
||||
static inline uint64_t swapSourceTargetFlags ( AutoSegment* );
|
||||
static inline bool areAlignedsAndDiffLayer ( AutoSegment*, AutoSegment* );
|
||||
static AutoSegment* getGlobalThroughDogleg ( AutoSegment* dogleg, AutoContact* from );
|
||||
static bool isTopologicalBound ( AutoSegment* seed, Flags flags );
|
||||
static inline bool arePerpandiculars ( AutoSegment* a, AutoSegment* b );
|
||||
static inline bool arePerpandiculars ( bool isHorizontalA, AutoSegment* b );
|
||||
static inline bool areAligneds ( AutoSegment* a, AutoSegment* b );
|
||||
static Flags getPerpandicularState ( AutoContact* contact
|
||||
, AutoSegment* source
|
||||
, AutoSegment* current
|
||||
, bool isHorizontalMaster
|
||||
, const Layer* masterLayer=NULL
|
||||
);
|
||||
static inline Flags getPerpandicularState ( AutoContact* contact
|
||||
, AutoSegment* source
|
||||
, AutoSegment* current
|
||||
, AutoSegment* master
|
||||
);
|
||||
static void getTopologicalInfos ( AutoSegment* seed
|
||||
, vector<AutoSegment*>& collapseds
|
||||
, vector<AutoSegment*>& perpandiculars
|
||||
, DbU::Unit& leftBound
|
||||
, DbU::Unit& rightBound
|
||||
);
|
||||
static int getTerminalCount ( AutoSegment* seed
|
||||
, vector<AutoSegment*>& collapseds
|
||||
);
|
||||
static inline int getTerminalCount ( AutoSegment* seed );
|
||||
static inline size_t getGlobalsCount ();
|
||||
static inline size_t getAllocateds ();
|
||||
static inline unsigned long getMaxId ();
|
||||
};
|
||||
|
||||
|
||||
// Inline Functions.
|
||||
inline DbU::Unit AutoSegment::getViaToTopCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][0]) : 0; }
|
||||
inline DbU::Unit AutoSegment::getViaToBottomCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][1]) : 0; }
|
||||
inline DbU::Unit AutoSegment::getViaToSameCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][2]) : 0; }
|
||||
inline unsigned long AutoSegment::getId () const { return _id; }
|
||||
inline Cell* AutoSegment::getCell () const { return base()->getCell(); }
|
||||
inline Net* AutoSegment::getNet () const { return base()->getNet(); }
|
||||
inline const Layer* AutoSegment::getLayer () const { return base()->getLayer(); }
|
||||
inline Box AutoSegment::getBoundingBox () const { return base()->getBoundingBox(); }
|
||||
inline Hook* AutoSegment::getSourceHook () { return base()->getSourceHook(); }
|
||||
inline Hook* AutoSegment::getTargetHook () { return base()->getTargetHook(); }
|
||||
inline Contact* AutoSegment::getSource () const { return static_cast<Contact*>(base()->getSource()); }
|
||||
inline Contact* AutoSegment::getTarget () const { return static_cast<Contact*>(base()->getTarget()); }
|
||||
inline Component* AutoSegment::getOppositeAnchor ( Component* anchor ) const { return base()->getOppositeAnchor(anchor); };
|
||||
inline AutoSegment* AutoSegment::getParent () const { return _parent; }
|
||||
inline DbU::Unit AutoSegment::getSourcePosition () const { return _sourcePosition; }
|
||||
inline DbU::Unit AutoSegment::getTargetPosition () const { return _targetPosition; }
|
||||
inline DbU::Unit AutoSegment::getSourceX () const { return base()->getSourceX(); }
|
||||
inline DbU::Unit AutoSegment::getSourceY () const { return base()->getSourceY(); }
|
||||
inline DbU::Unit AutoSegment::getTargetX () const { return base()->getTargetX(); }
|
||||
inline DbU::Unit AutoSegment::getTargetY () const { return base()->getTargetY(); }
|
||||
inline DbU::Unit AutoSegment::getWidth () const { return base()->getWidth(); }
|
||||
inline DbU::Unit AutoSegment::getLength () const { return base()->getLength(); }
|
||||
inline void AutoSegment::invert () { base()->invert(); }
|
||||
inline GCell* AutoSegment::getGCell () const { return _gcell; }
|
||||
inline AutoContact* AutoSegment::getAutoSource () const { return Session::lookup(getSource()); }
|
||||
inline AutoContact* AutoSegment::getAutoTarget () const { return Session::lookup(getTarget()); }
|
||||
inline bool AutoSegment::getConstraints ( Interval& i ) const { return getConstraints(i.getVMin(),i.getVMax()); }
|
||||
inline AutoSegment* AutoSegment::getCanonical ( Interval& i ) { return getCanonical(i.getVMin(),i.getVMax()); }
|
||||
inline unsigned int AutoSegment::getDepth () const { return _depth; }
|
||||
inline DbU::Unit AutoSegment::getPitch () const { return Session::getPitch(getDepth(),Flags::NoFlags); }
|
||||
inline DbU::Unit AutoSegment::getAxis () const { return isHorizontal()?base()->getY():base()->getX(); }
|
||||
inline DbU::Unit AutoSegment::getOrigin () const { return isHorizontal()?_gcell->getYMin():_gcell->getXMin(); }
|
||||
inline DbU::Unit AutoSegment::getExtremity () const { return isHorizontal()?_gcell->getYMax():_gcell->getXMax(); }
|
||||
inline DbU::Unit AutoSegment::getOptimalMin () const { return DbU::lambda(_optimalMin) + getOrigin(); }
|
||||
inline DbU::Unit AutoSegment::getOptimalMax () const { return DbU::lambda(_optimalMax) + getOrigin(); }
|
||||
inline DbU::Unit AutoSegment::getNativeMin () const { return _nativeConstraints.getVMin(); }
|
||||
inline DbU::Unit AutoSegment::getNativeMax () const { return _nativeConstraints.getVMax(); }
|
||||
inline const Interval& AutoSegment::getUserConstraints () const { return _userConstraints; }
|
||||
inline const Interval& AutoSegment::getNativeConstraints () const { return _nativeConstraints; }
|
||||
|
||||
inline bool AutoSegment::isHorizontal () const { return _flags & SegHorizontal; }
|
||||
inline bool AutoSegment::isVertical () const { return not (_flags & SegHorizontal); }
|
||||
inline bool AutoSegment::isFixed () const { return _flags & SegFixed; }
|
||||
inline bool AutoSegment::isFixedAxis () const { return _flags & SegFixedAxis; }
|
||||
inline bool AutoSegment::isGlobal () const { return _flags & SegGlobal; }
|
||||
inline bool AutoSegment::isWeakGlobal () const { return _flags & SegWeakGlobal; }
|
||||
inline bool AutoSegment::isLongLocal () const { return _flags & SegLongLocal; }
|
||||
inline bool AutoSegment::isLocal () const { return not (_flags & SegGlobal); }
|
||||
inline bool AutoSegment::isBipoint () const { return _flags & SegBipoint; }
|
||||
inline bool AutoSegment::isWeakTerminal () const { return _flags & SegWeakTerminal; }
|
||||
inline bool AutoSegment::isWeakTerminal1 () const { return _flags & SegWeakTerminal1; }
|
||||
inline bool AutoSegment::isWeakTerminal2 () const { return _flags & SegWeakTerminal2; }
|
||||
inline bool AutoSegment::isSourceTerminal () const { return _flags & SegSourceTerminal; }
|
||||
inline bool AutoSegment::isTargetTerminal () const { return _flags & SegTargetTerminal; }
|
||||
inline bool AutoSegment::isTerminal () const { return _flags & SegStrongTerminal; }
|
||||
inline bool AutoSegment::isDrag () const { return _flags & SegDrag; }
|
||||
inline bool AutoSegment::isNotSourceAligned () const { return _flags & SegNotSourceAligned; }
|
||||
inline bool AutoSegment::isNotTargetAligned () const { return _flags & SegNotTargetAligned; }
|
||||
inline bool AutoSegment::isNotAligned () const { return (_flags & SegNotAligned) == SegNotAligned; }
|
||||
inline bool AutoSegment::isDogleg () const { return _flags & SegDogleg ; }
|
||||
inline bool AutoSegment::isUnbound () const { return _flags & SegUnbound ; }
|
||||
inline bool AutoSegment::isStrap () const { return _flags & SegStrap; }
|
||||
inline bool AutoSegment::isLayerChange () const { return _flags & SegLayerChange; }
|
||||
inline bool AutoSegment::isSpinTop () const { return ((_flags & SegSpinTop ) == SegSpinTop); }
|
||||
inline bool AutoSegment::isSpinBottom () const { return ((_flags & SegSpinBottom) == SegSpinBottom); }
|
||||
inline bool AutoSegment::isSpinTopOrBottom () const { return isSpinTop() or isSpinBottom(); }
|
||||
inline bool AutoSegment::isReduced () const { return _flags & SegIsReduced; }
|
||||
inline bool AutoSegment::isSlackened () const { return _flags & SegSlackened; }
|
||||
inline bool AutoSegment::isCanonical () const { return _flags & SegCanonical; }
|
||||
inline bool AutoSegment::isUnsetAxis () const { return not (_flags & SegAxisSet); }
|
||||
inline bool AutoSegment::isInvalidated () const { return _flags & SegInvalidated; }
|
||||
inline bool AutoSegment::isInvalidatedLayer () const { return _flags & SegInvalidatedLayer; }
|
||||
inline bool AutoSegment::isCreated () const { return _flags & SegCreated; }
|
||||
inline bool AutoSegment::isUserDefined () const { return _flags & SegUserDefined; }
|
||||
inline bool AutoSegment::isAnalog () const { return _flags & SegAnalog; }
|
||||
inline bool AutoSegment::isWide () const { return _flags & SegWide; }
|
||||
inline void AutoSegment::setFlags ( uint64_t flags ) { _flags |= flags; }
|
||||
inline void AutoSegment::unsetFlags ( uint64_t flags ) { _flags &= ~flags; }
|
||||
|
||||
inline uint64_t AutoSegment::getFlags () const { return _flags; }
|
||||
inline uint64_t AutoSegment::_getFlags () const { return _flags; }
|
||||
inline void AutoSegment::incReduceds () { if (_reduceds<3) ++_reduceds; }
|
||||
inline void AutoSegment::decReduceds () { if (_reduceds>0) --_reduceds; }
|
||||
inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); _flags|=SegInvalidatedLayer; }
|
||||
inline void AutoSegment::setOptimalMin ( DbU::Unit min ) { _optimalMin = (unsigned int)DbU::getLambda(min-getOrigin()); }
|
||||
inline void AutoSegment::setOptimalMax ( DbU::Unit max ) { _optimalMax = (unsigned int)DbU::getLambda(max-getOrigin()); }
|
||||
inline void AutoSegment::mergeNativeMin ( DbU::Unit min ) { _nativeConstraints.getVMin() = std::max( min, _nativeConstraints.getVMin() ); }
|
||||
inline void AutoSegment::mergeNativeMax ( DbU::Unit max ) { _nativeConstraints.getVMax() = std::min( max, _nativeConstraints.getVMax() ); }
|
||||
inline void AutoSegment::resetNativeConstraints ( DbU::Unit min, DbU::Unit max ) { _nativeConstraints = Interval( min, max ); }
|
||||
//inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); }
|
||||
inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); }
|
||||
|
||||
|
||||
inline DbU::Unit AutoSegment::getContactWidth () const
|
||||
{ return getWidth() + Session::getViaWidth(getLayer()) - Session::getWireWidth(getLayer()); }
|
||||
|
||||
|
||||
inline void AutoSegment::setParent ( AutoSegment* parent )
|
||||
{
|
||||
if ( parent == this ) {
|
||||
cerr << "Parentage Looping: " << parent->_getString() << endl;
|
||||
}
|
||||
_parent = parent;
|
||||
}
|
||||
|
||||
inline bool AutoSegment::CompareId::operator() ( const AutoSegment* lhs, const AutoSegment* rhs ) const
|
||||
{ return lhs->getId() < rhs->getId(); }
|
||||
|
||||
inline uint64_t AutoSegment::swapSourceTargetFlags ( AutoSegment* segment )
|
||||
{
|
||||
uint64_t segFlags = segment->getFlags();
|
||||
uint64_t swapFlags = segment->getFlags() & ~(SegSourceTop |SegTargetTop
|
||||
|SegSourceBottom |SegTargetBottom
|
||||
|SegSourceTerminal |SegTargetTerminal
|
||||
|SegNotSourceAligned |SegNotTargetAligned
|
||||
|SegInvalidatedSource|SegInvalidatedTarget
|
||||
);
|
||||
|
||||
swapFlags |= (segFlags & SegSourceTop ) ? SegTargetTop : SegNoFlags;
|
||||
swapFlags |= (segFlags & SegSourceBottom ) ? SegTargetBottom : SegNoFlags;
|
||||
swapFlags |= (segFlags & SegSourceTerminal ) ? SegTargetTerminal : SegNoFlags;
|
||||
swapFlags |= (segFlags & SegNotSourceAligned ) ? SegNotTargetAligned : SegNoFlags;
|
||||
swapFlags |= (segFlags & SegInvalidatedSource) ? SegInvalidatedTarget : SegNoFlags;
|
||||
|
||||
swapFlags |= (segFlags & SegTargetTop ) ? SegSourceTop : SegNoFlags;
|
||||
swapFlags |= (segFlags & SegTargetBottom ) ? SegSourceBottom : SegNoFlags;
|
||||
swapFlags |= (segFlags & SegTargetTerminal ) ? SegSourceTerminal : SegNoFlags;
|
||||
swapFlags |= (segFlags & SegNotTargetAligned ) ? SegNotSourceAligned : SegNoFlags;
|
||||
swapFlags |= (segFlags & SegInvalidatedTarget) ? SegInvalidatedSource : SegNoFlags;
|
||||
return swapFlags;
|
||||
}
|
||||
|
||||
inline bool AutoSegment::areAlignedsAndDiffLayer ( AutoSegment* s1, AutoSegment* s2 )
|
||||
{ return s1 and s2
|
||||
and (s1->isHorizontal() == s2->isHorizontal())
|
||||
and (s1->getLayer() != s2->getLayer()); }
|
||||
|
||||
inline bool AutoSegment::arePerpandiculars ( AutoSegment* a, AutoSegment* b )
|
||||
{ return a and b and (a->isHorizontal() != b->isHorizontal()); }
|
||||
|
||||
inline bool AutoSegment::arePerpandiculars ( bool isHorizontalA, AutoSegment* b )
|
||||
{ return b and (isHorizontalA != b->isHorizontal()); }
|
||||
|
||||
inline bool AutoSegment::areAligneds ( AutoSegment* a, AutoSegment* b )
|
||||
{ return a and b and (a->isHorizontal() == b->isHorizontal()); }
|
||||
|
||||
inline Flags AutoSegment::getPerpandicularState ( AutoContact* contact
|
||||
, AutoSegment* source
|
||||
, AutoSegment* current
|
||||
, AutoSegment* master )
|
||||
{
|
||||
return getPerpandicularState ( contact, source, current, master->isHorizontal(), master->getLayer() );
|
||||
}
|
||||
|
||||
|
||||
inline int AutoSegment::getTerminalCount ( AutoSegment* seed )
|
||||
{
|
||||
cdebug_log(145,0) << "getTerminalCount() - " << seed << endl;
|
||||
|
||||
vector<AutoSegment*> collapseds;
|
||||
vector<AutoSegment*> perpandiculars;
|
||||
DbU::Unit leftBound;
|
||||
DbU::Unit rightBound;
|
||||
|
||||
getTopologicalInfos ( seed
|
||||
, collapseds
|
||||
, perpandiculars
|
||||
, leftBound
|
||||
, rightBound
|
||||
);
|
||||
|
||||
return getTerminalCount ( seed, collapseds );
|
||||
}
|
||||
|
||||
|
||||
inline size_t AutoSegment::getGlobalsCount () { return _globalsCount; }
|
||||
inline size_t AutoSegment::getAllocateds () { return _allocateds; }
|
||||
|
||||
|
||||
inline void AutoSegment::setObserver ( size_t slot, BaseObserver* observer )
|
||||
{ _observers.setObserver( slot, observer ); }
|
||||
|
||||
template<typename OwnerT>
|
||||
inline OwnerT* AutoSegment::getObserver ( size_t slot )
|
||||
{ return _observers.getObserver<OwnerT>(slot); }
|
||||
|
||||
inline void AutoSegment::notify ( unsigned int flags )
|
||||
{ _observers.notify( flags ); }
|
||||
|
||||
inline AutoSegment::Observable::Observable () : StaticObservable<1>() { }
|
||||
|
||||
|
||||
} // End of Anabatic namespace.
|
||||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::AutoSegment);
|
||||
|
||||
|
||||
# endif // ANABATIC_AUTOSEGMENT_H
|
|
@ -14,16 +14,20 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_ANABATIC_ENGINE_H
|
||||
#define ANABATIC_ANABATIC_ENGINE_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include "hurricane/NetRoutingProperty.h"
|
||||
namespace Hurricane {
|
||||
class Instance;
|
||||
class CellViewer;
|
||||
}
|
||||
|
||||
#include "crlcore/ToolEngine.h"
|
||||
#include "anabatic/Configuration.h"
|
||||
#include "anabatic/Matrix.h"
|
||||
|
@ -45,7 +49,6 @@ namespace Anabatic {
|
|||
using Hurricane::NetRoutingState;
|
||||
using CRL::ToolEngine;
|
||||
|
||||
class NetBuilder;
|
||||
class AnabaticEngine;
|
||||
|
||||
|
||||
|
@ -65,8 +68,6 @@ namespace Anabatic {
|
|||
};
|
||||
public:
|
||||
RawGCellsUnder ( const AnabaticEngine*, Segment* );
|
||||
RawGCellsUnder ( const AnabaticEngine*, Point source, Point target );
|
||||
void commonCtor ( const AnabaticEngine*, Point source, Point target );
|
||||
inline bool empty () const;
|
||||
inline size_t size () const;
|
||||
inline GCell* gcellAt ( size_t ) const;
|
||||
|
@ -101,29 +102,24 @@ namespace Anabatic {
|
|||
|
||||
class NetData {
|
||||
public:
|
||||
NetData ( Net*, AnabaticEngine* );
|
||||
NetData ( Net* );
|
||||
inline bool isGlobalEstimated () const;
|
||||
inline bool isGlobalRouted () const;
|
||||
inline bool isGlobalFixed () const;
|
||||
inline bool isMixedPreRoute () const;
|
||||
inline bool isFixed () const;
|
||||
inline bool isExcluded () const;
|
||||
inline bool isNoMoveUp ( Segment* ) const;
|
||||
inline Net* getNet () const;
|
||||
inline NetRoutingState* getNetRoutingState () const;
|
||||
inline const Box& getSearchArea () const;
|
||||
inline DbU::Unit getHalfPerimeter () const;
|
||||
inline size_t getRpCount () const;
|
||||
inline size_t getDiodeRpCount () const;
|
||||
inline DbU::Unit getSparsity () const;
|
||||
inline void setNetRoutingState ( NetRoutingState* );
|
||||
inline void setSearchArea ( Box );
|
||||
inline void setGlobalEstimated ( bool );
|
||||
inline void setGlobalRouted ( bool );
|
||||
inline void setGlobalFixed ( bool );
|
||||
inline void setExcluded ( bool );
|
||||
inline void setRpCount ( size_t );
|
||||
inline void setNoMoveUp ( Segment* );
|
||||
private:
|
||||
NetData ( const NetData& );
|
||||
NetData& operator= ( const NetData& );
|
||||
|
@ -133,34 +129,27 @@ namespace Anabatic {
|
|||
NetRoutingState* _state;
|
||||
Box _searchArea;
|
||||
size_t _rpCount;
|
||||
size_t _diodeCount;
|
||||
DbU::Unit _sparsity;
|
||||
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::isGlobalFixed () const { return _flags & Flags::GlobalFixed; }
|
||||
inline bool NetData::isMixedPreRoute () const { return (_state) ? _state->isMixedPreRoute() : false; }
|
||||
inline bool NetData::isFixed () const { return (_state) ? _state->isFixed () : false; }
|
||||
inline bool NetData::isExcluded () const { return _flags & Flags::ExcludeRoute; }
|
||||
inline bool NetData::isNoMoveUp ( Segment* segment ) const { return (_noMoveUp.find(segment) != _noMoveUp.end()); }
|
||||
inline Net* NetData::getNet () const { return _net; }
|
||||
inline NetRoutingState* NetData::getNetRoutingState () const { return _state; }
|
||||
inline const Box& NetData::getSearchArea () const { return _searchArea; }
|
||||
inline DbU::Unit NetData::getHalfPerimeter () const { return (_searchArea.isEmpty()) ? 0.0 : (_searchArea.getWidth()+_searchArea.getHeight()); }
|
||||
inline size_t NetData::getRpCount () const { return _rpCount; }
|
||||
inline size_t NetData::getDiodeRpCount () const { return _diodeCount; }
|
||||
inline void NetData::setNetRoutingState ( NetRoutingState* state ) { _state=state; }
|
||||
inline DbU::Unit NetData::getSparsity () const { return _sparsity; }
|
||||
inline void NetData::setGlobalEstimated ( bool state ) { _flags.set(Flags::GlobalEstimated,state); }
|
||||
inline void NetData::setGlobalRouted ( bool state ) { _flags.set(Flags::GlobalRouted ,state); }
|
||||
inline void NetData::setGlobalFixed ( bool state ) { _flags.set(Flags::GlobalFixed ,state); }
|
||||
inline void NetData::setExcluded ( bool state ) { _flags.set(Flags::ExcludeRoute ,state); }
|
||||
inline void NetData::setRpCount ( size_t count ) { _rpCount=count; _update(); }
|
||||
inline void NetData::setNoMoveUp ( Segment* segment ) { _noMoveUp.insert(segment); }
|
||||
|
||||
|
||||
inline void NetData::_update ()
|
||||
|
@ -172,12 +161,7 @@ namespace Anabatic {
|
|||
inline bool operator() ( const NetData* lhs, const NetData* rhs ) const
|
||||
{
|
||||
if (lhs->isMixedPreRoute() != rhs->isMixedPreRoute()) return lhs->isMixedPreRoute();
|
||||
if ((lhs->getRpCount() > 10) or (rhs->getRpCount() > 10)) {
|
||||
if (lhs->getRpCount() != rhs->getRpCount())
|
||||
return lhs->getRpCount() > rhs->getRpCount();
|
||||
}
|
||||
|
||||
if (lhs->getSparsity() != rhs->getSparsity()) return lhs->getSparsity() < rhs->getSparsity();
|
||||
if (lhs->getSparsity() != rhs->getSparsity() ) return lhs->getSparsity() < rhs->getSparsity();
|
||||
return lhs->getNet()->getId() < rhs->getNet()->getId();
|
||||
}
|
||||
};
|
||||
|
@ -192,33 +176,22 @@ namespace Anabatic {
|
|||
|
||||
class AnabaticEngine : public ToolEngine {
|
||||
public:
|
||||
static const uint32_t DigitalMode = (1 << 0);
|
||||
static const uint32_t AnalogMode = (1 << 1);
|
||||
static const uint32_t MixedMode = (1 << 2);
|
||||
static const uint32_t AverageHVDensity = 1; // Average between all densities.
|
||||
static const uint32_t AverageHDensity = 2; // Average between all H densities.
|
||||
static const uint32_t AverageVDensity = 3; // Average between all V densities.
|
||||
static const uint32_t MaxHVDensity = 4; // Maximum between average H and average V.
|
||||
static const uint32_t MaxVDensity = 5; // Maximum of V densities.
|
||||
static const uint32_t MaxHDensity = 6; // Maximum of H densities.
|
||||
static const uint32_t MaxDensity = 7; // Maximum of H & V densities.
|
||||
enum DensityMode { AverageHVDensity=1 // Average between all densities.
|
||||
, AverageHDensity =2 // Average between all H densities.
|
||||
, AverageVDensity =3 // Average between all V densities.
|
||||
, MaxHVDensity =4 // Maximum between average H and average V.
|
||||
, MaxVDensity =5 // Maximum of V densities.
|
||||
, MaxHDensity =6 // Maximum of H densities.
|
||||
, MaxDensity =7 // Maximum of H & V densities.
|
||||
};
|
||||
public:
|
||||
typedef ToolEngine Super;
|
||||
public:
|
||||
static AnabaticEngine* create ( Cell* );
|
||||
static AnabaticEngine* get ( const Cell* );
|
||||
inline bool isCanonizeDisabled () const;
|
||||
inline bool isDigitalMode () const;
|
||||
inline bool isAnalogMode () const;
|
||||
inline bool isMixedMode () const;
|
||||
inline bool isChannelStyle () const;
|
||||
inline bool isHybridStyle () const;
|
||||
static const Name& staticGetName ();
|
||||
virtual const Name& getName () const;
|
||||
virtual Configuration* getConfiguration ();
|
||||
virtual const Configuration* getConfiguration () const;
|
||||
inline std::string getNetBuilderStyle () const;
|
||||
inline StyleFlags getRoutingStyle () const;
|
||||
inline uint64_t getDensityMode () const;
|
||||
inline CellViewer* getViewer () const;
|
||||
inline void setViewer ( CellViewer* );
|
||||
|
@ -230,7 +203,6 @@ namespace Anabatic {
|
|||
inline GCell* getGCellUnder ( DbU::Unit x, DbU::Unit y ) const;
|
||||
inline GCell* getGCellUnder ( Point ) const;
|
||||
inline GCellsUnder getGCellsUnder ( Segment* ) const;
|
||||
inline GCellsUnder getGCellsUnder ( Point source, Point target ) const;
|
||||
inline Edges getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags=Flags::NorthPath ) const;
|
||||
Interval getUSide ( Flags direction ) const;
|
||||
int getCapacity ( Interval, Flags ) const;
|
||||
|
@ -238,8 +210,6 @@ namespace Anabatic {
|
|||
virtual void openSession ();
|
||||
inline void setState ( EngineState state );
|
||||
inline void setDensityMode ( uint64_t );
|
||||
inline void disableCanonize ();
|
||||
inline void enableCanonize ();
|
||||
inline void addOv ( Edge* );
|
||||
inline void removeOv ( Edge* );
|
||||
inline const NetDatas& getNetDatas () const;
|
||||
|
@ -248,7 +218,6 @@ namespace Anabatic {
|
|||
void exclude ( const Name& netName );
|
||||
void exclude ( Net* );
|
||||
void updateMatrix ();
|
||||
bool checkPlacement () const;
|
||||
// Dijkstra related functions.
|
||||
inline int getStamp () const;
|
||||
inline int incStamp ();
|
||||
|
@ -266,30 +235,21 @@ namespace Anabatic {
|
|||
inline bool doDestroyBaseContact () const;
|
||||
inline bool doDestroyBaseSegment () const;
|
||||
inline bool doDestroyTool () const;
|
||||
inline DbU::Unit getAntennaGateMaxWL () const;
|
||||
inline DbU::Unit getAntennaDiodeMaxWL () const;
|
||||
inline DbU::Unit getGlobalThreshold () const;
|
||||
inline float getSaturateRatio () const;
|
||||
inline size_t getSaturateRp () const;
|
||||
inline DbU::Unit getExtensionCap () const;
|
||||
inline Cell* getDiodeCell () const;
|
||||
inline Net* getBlockageNet () const;
|
||||
inline const ChipTools& getChipTools () const;
|
||||
inline const vector<NetData*>& getNetOrdering () const;
|
||||
void invalidateRoutingPads ();
|
||||
void updateDensity ();
|
||||
size_t checkGCellDensities ();
|
||||
void setupNetBuilder ();
|
||||
inline void setRoutingMode ( uint32_t );
|
||||
inline void resetRoutingMode ( uint32_t );
|
||||
inline void setGlobalThreshold ( DbU::Unit );
|
||||
inline void setSaturateRatio ( float );
|
||||
inline void setSaturateRp ( size_t );
|
||||
inline void setBlockageNet ( Net* );
|
||||
void chipPrep ();
|
||||
void computeEdgeCapacities ( int maxHCap, int maxVCap, int termSatThreshold, int maxTermSat );
|
||||
void antennaProtect ( Net*, uint32_t& failed, uint32_t& total );
|
||||
void antennaProtect ();
|
||||
void setupSpecialNets ();
|
||||
size_t setupPreRouteds ();
|
||||
void loadGlobalRouting ( uint32_t method );
|
||||
|
@ -299,7 +259,6 @@ namespace Anabatic {
|
|||
bool moveUpNetTrunk ( AutoSegment*, set<Net*>& globalNets, GCell::Set& invalidateds );
|
||||
void layerAssign ( uint32_t method );
|
||||
void finalizeLayout ();
|
||||
void exportExternalNets ();
|
||||
inline const AutoContactLut& _getAutoContactLut () const;
|
||||
inline const AutoSegmentLut& _getAutoSegmentLut () const;
|
||||
void _link ( AutoContact* );
|
||||
|
@ -347,15 +306,12 @@ namespace Anabatic {
|
|||
virtual void _postCreate ();
|
||||
virtual void _preDestroy ();
|
||||
void _gutAnabatic ();
|
||||
virtual Configuration* _createConfiguration ();
|
||||
private:
|
||||
AnabaticEngine ( const AnabaticEngine& );
|
||||
AnabaticEngine& operator= ( const AnabaticEngine& );
|
||||
private:
|
||||
static Name _toolName;
|
||||
protected:
|
||||
Configuration* _configuration;
|
||||
private:
|
||||
ChipTools _chipTools;
|
||||
EngineState _state;
|
||||
Matrix _matrix;
|
||||
|
@ -366,23 +322,14 @@ namespace Anabatic {
|
|||
CellViewer* _viewer;
|
||||
Flags _flags;
|
||||
int _stamp;
|
||||
uint32_t _routingMode;
|
||||
uint64_t _densityMode;
|
||||
AutoSegmentLut _autoSegmentLut;
|
||||
AutoContactLut _autoContactLut;
|
||||
EdgeCapacityLut _edgeCapacitiesLut;
|
||||
Net* _blockageNet;
|
||||
Cell* _diodeCell;
|
||||
};
|
||||
|
||||
|
||||
inline bool AnabaticEngine::isDigitalMode () const { return (_routingMode & DigitalMode); };
|
||||
inline bool AnabaticEngine::isAnalogMode () const { return (_routingMode & AnalogMode); };
|
||||
inline bool AnabaticEngine::isMixedMode () const { return (_routingMode & MixedMode); };
|
||||
inline bool AnabaticEngine::isChannelStyle () const { return (_configuration->getRoutingStyle() & StyleFlags::Channel); };
|
||||
inline bool AnabaticEngine::isHybridStyle () const { return (_configuration->getRoutingStyle() & StyleFlags::Hybrid); };
|
||||
inline void AnabaticEngine::setRoutingMode ( uint32_t mode ) { _routingMode |= mode; };
|
||||
inline void AnabaticEngine::resetRoutingMode ( uint32_t mode ) { _routingMode &= ~mode; };
|
||||
inline EngineState AnabaticEngine::getState () const { return _state; }
|
||||
inline void AnabaticEngine::setState ( EngineState state ) { _state = state; }
|
||||
inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; }
|
||||
|
@ -394,7 +341,6 @@ namespace Anabatic {
|
|||
inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); }
|
||||
inline GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); }
|
||||
inline GCellsUnder AnabaticEngine::getGCellsUnder ( Segment* s ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,s) ); }
|
||||
inline GCellsUnder AnabaticEngine::getGCellsUnder ( Point source, Point target ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,source,target) ); }
|
||||
inline Edges AnabaticEngine::getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags ) const { return new Path_Edges(source,target,pathFlags); }
|
||||
inline uint64_t AnabaticEngine::getDensityMode () const { return _densityMode; }
|
||||
inline void AnabaticEngine::setDensityMode ( uint64_t mode ) { _densityMode=mode; }
|
||||
|
@ -407,19 +353,13 @@ namespace Anabatic {
|
|||
inline bool AnabaticEngine::doDestroyBaseSegment () const { return _flags & Flags::DestroyBaseSegment; }
|
||||
inline bool AnabaticEngine::doDestroyTool () const { return _state >= EngineGutted; }
|
||||
inline bool AnabaticEngine::doWarnOnGCellOverload () const { return _flags & Flags::WarnOnGCellOverload; }
|
||||
inline bool AnabaticEngine::isCanonizeDisabled () const { return _flags & Flags::DisableCanonize; }
|
||||
inline bool AnabaticEngine::isInDemoMode () const { return _flags & Flags::DemoMode; }
|
||||
inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); }
|
||||
inline std::string AnabaticEngine::getNetBuilderStyle () const { return _configuration->getNetBuilderStyle(); }
|
||||
inline StyleFlags AnabaticEngine::getRoutingStyle () const { return _configuration->getRoutingStyle(); }
|
||||
inline DbU::Unit AnabaticEngine::getAntennaGateMaxWL () const { return _configuration->getAntennaGateMaxWL(); }
|
||||
inline DbU::Unit AnabaticEngine::getAntennaDiodeMaxWL () const { return _configuration->getAntennaDiodeMaxWL(); }
|
||||
inline DbU::Unit AnabaticEngine::getGlobalThreshold () const { return _configuration->getGlobalThreshold(); }
|
||||
inline float AnabaticEngine::getSaturateRatio () const { return _configuration->getSaturateRatio(); }
|
||||
inline size_t AnabaticEngine::getSaturateRp () const { return _configuration->getSaturateRp(); }
|
||||
inline void AnabaticEngine::setSaturateRatio ( float ratio ) { _configuration->setSaturateRatio(ratio); }
|
||||
inline void AnabaticEngine::setSaturateRp ( size_t threshold ) { _configuration->setSaturateRp(threshold); }
|
||||
inline Cell* AnabaticEngine::getDiodeCell () const { return _diodeCell; }
|
||||
inline Net* AnabaticEngine::getBlockageNet () const { return _blockageNet; }
|
||||
inline const ChipTools& AnabaticEngine::getChipTools () const { return _chipTools; }
|
||||
inline const vector<NetData*>& AnabaticEngine::getNetOrdering () const { return _netOrdering; }
|
||||
|
@ -429,8 +369,6 @@ namespace Anabatic {
|
|||
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 )
|
||||
{
|
||||
|
@ -469,3 +407,5 @@ namespace Anabatic {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::AnabaticEngine);
|
||||
|
||||
#endif // ANABATIC_ANABATIC_ENGINE_H
|
||||
|
|
|
@ -71,8 +71,6 @@ namespace Anabatic {
|
|||
, CntOnVertical = (1 << 14)
|
||||
, CntOnHorizontal = (1 << 15)
|
||||
, CntDrag = (1 << 16)
|
||||
, CntHDogleg = (1 << 17)
|
||||
, CntVDogleg = (1 << 18)
|
||||
};
|
||||
|
||||
class AutoContact {
|
||||
|
@ -121,9 +119,6 @@ namespace Anabatic {
|
|||
inline bool isVTee () const;
|
||||
inline bool isFixed () const;
|
||||
inline bool isUserNativeConstraints () const;
|
||||
inline bool isHDogleg () const;
|
||||
inline bool isVDogleg () const;
|
||||
virtual bool isOnPin () const;
|
||||
inline bool hasBadTopology () const;
|
||||
bool canDestroy ( Flags flags=Flags::NoFlags ) const;
|
||||
bool canMoveUp ( const AutoSegment* moved ) const;
|
||||
|
@ -164,7 +159,6 @@ namespace Anabatic {
|
|||
virtual void cacheDetach ( AutoSegment* ) = 0;
|
||||
virtual void cacheAttach ( AutoSegment* ) = 0;
|
||||
virtual void updateCache () = 0;
|
||||
void updateLayer ();
|
||||
void updateSize ();
|
||||
virtual void updateGeometry () = 0;
|
||||
virtual void updateTopology () = 0;
|
||||
|
@ -265,8 +259,6 @@ namespace Anabatic {
|
|||
inline bool AutoContact::isTerminal () const { return _flags&CntTerminal; }
|
||||
inline bool AutoContact::isHTee () const { return _flags&CntHTee; }
|
||||
inline bool AutoContact::isVTee () const { return _flags&CntVTee; }
|
||||
inline bool AutoContact::isHDogleg () const { return _flags&CntHDogleg; }
|
||||
inline bool AutoContact::isVDogleg () const { return _flags&CntVDogleg; }
|
||||
inline bool AutoContact::hasBadTopology () const { return _flags&CntBadTopology; }
|
||||
inline bool AutoContact::canDrag () const { return _flags&CntDrag; }
|
||||
inline size_t AutoContact::getId () const { return _id; }
|
||||
|
|
|
@ -60,7 +60,6 @@ namespace Anabatic {
|
|||
virtual void _invalidate ( Flags flags );
|
||||
public:
|
||||
bool isEndPoint () const;
|
||||
virtual bool isOnPin () const;
|
||||
virtual Box getNativeConstraintBox () const;
|
||||
RoutingPad* getRoutingPad () const;
|
||||
inline AutoSegment* getSegment () const;
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_AUTOHORIZONTAL_H
|
||||
#define ANABATIC_AUTOHORIZONTAL_H
|
||||
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "anabatic/AutoSegment.h"
|
||||
|
||||
|
@ -89,3 +91,6 @@ namespace Anabatic {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::AutoHorizontal);
|
||||
|
||||
|
||||
#endif // ANABATIC_AUTOHORIZONTAL_H
|
||||
|
|
|
@ -14,8 +14,9 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#include <tuple>
|
||||
#ifndef ANABATIC_AUTOSEGMENT_H
|
||||
#define ANABATIC_AUTOSEGMENT_H
|
||||
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
|
@ -38,7 +39,6 @@ namespace Hurricane {
|
|||
|
||||
namespace Anabatic {
|
||||
|
||||
using std::tuple;
|
||||
using std::array;
|
||||
using std::set;
|
||||
using std::cerr;
|
||||
|
@ -58,10 +58,11 @@ namespace Anabatic {
|
|||
class AutoHorizontal;
|
||||
class AutoVertical;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "AutoSegment".
|
||||
|
||||
|
||||
|
||||
class AutoSegment {
|
||||
friend class AutoHorizontal;
|
||||
friend class AutoVertical;
|
||||
|
@ -105,11 +106,6 @@ namespace Anabatic {
|
|||
static const uint64_t SegAnalog = (1L<<33);
|
||||
static const uint64_t SegWide = (1L<<34);
|
||||
static const uint64_t SegShortNet = (1L<<35);
|
||||
static const uint64_t SegUnbreakable = (1L<<36);
|
||||
static const uint64_t SegNonPref = (1L<<37);
|
||||
static const uint64_t SegAtMinArea = (1L<<38);
|
||||
static const uint64_t SegNoMoveUp = (1L<<39);
|
||||
static const uint64_t SegOnVSmall = (1L<<40);
|
||||
// Masks.
|
||||
static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2;
|
||||
static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned;
|
||||
|
@ -144,7 +140,6 @@ namespace Anabatic {
|
|||
inline static DbU::Unit getViaToTopCap ( size_t depth );
|
||||
inline static DbU::Unit getViaToBottomCap ( size_t depth );
|
||||
inline static DbU::Unit getViaToSameCap ( size_t depth );
|
||||
inline static DbU::Unit getMinimalLength ( size_t depth );
|
||||
static AutoSegment* create ( AutoContact* source
|
||||
, AutoContact* target
|
||||
, Segment* hurricaneSegment
|
||||
|
@ -175,8 +170,6 @@ namespace Anabatic {
|
|||
inline DbU::Unit getWidth () const;
|
||||
inline DbU::Unit getContactWidth () const;
|
||||
inline DbU::Unit getLength () const;
|
||||
inline DbU::Unit getSpanLength () const;
|
||||
inline DbU::Unit getAnchoredLength () const;
|
||||
inline DbU::Unit getSourcePosition () const;
|
||||
inline DbU::Unit getTargetPosition () const;
|
||||
inline DbU::Unit getSourceX () const;
|
||||
|
@ -201,11 +194,7 @@ namespace Anabatic {
|
|||
inline bool isWeakTerminal1 () const;
|
||||
inline bool isWeakTerminal2 () const;
|
||||
inline bool isTerminal () const;
|
||||
inline bool isUnbreakable () const;
|
||||
inline bool isNonPref () const;
|
||||
inline bool isNonPrefOnVSmall () const;
|
||||
inline bool isDrag () const;
|
||||
inline bool isAtMinArea () const;
|
||||
inline bool isNotSourceAligned () const;
|
||||
inline bool isNotTargetAligned () const;
|
||||
inline bool isNotAligned () const;
|
||||
|
@ -213,7 +202,6 @@ namespace Anabatic {
|
|||
inline bool isSourceTerminal () const;
|
||||
inline bool isTargetTerminal () const;
|
||||
inline bool isLayerChange () const;
|
||||
inline bool isStackedStrap () const;
|
||||
inline bool isSpinTop () const;
|
||||
inline bool isSpinBottom () const;
|
||||
inline bool isSpinTopOrBottom () const;
|
||||
|
@ -228,15 +216,13 @@ namespace Anabatic {
|
|||
inline bool isUnsetAxis () const;
|
||||
inline bool isSlackened () const;
|
||||
inline bool isUserDefined () const;
|
||||
bool isNearMinArea () const;
|
||||
bool isReduceCandidate () const;
|
||||
bool isUTurn () const;
|
||||
inline bool isAnalog () const;
|
||||
inline bool isWide () const;
|
||||
inline bool isShortNet () const;
|
||||
inline bool isNoMoveUp () const;
|
||||
virtual bool _canSlacken () const = 0;
|
||||
bool canReduce ( Flags flags=Flags::WithPerpands ) const;
|
||||
bool canReduce () const;
|
||||
bool mustRaise () const;
|
||||
Flags canDogleg ( Interval );
|
||||
virtual bool canMoveULeft ( float reserve=0.0 ) const = 0;
|
||||
|
@ -259,7 +245,6 @@ namespace Anabatic {
|
|||
AutoContact* getOppositeAnchor ( AutoContact* ) const;
|
||||
size_t getPerpandicularsBound ( set<AutoSegment*>& );
|
||||
inline AutoSegment* getParent () const;
|
||||
inline unsigned int getRpDistance () const;
|
||||
inline unsigned int getDepth () const;
|
||||
inline DbU::Unit getPitch () const;
|
||||
DbU::Unit getPPitch () const;
|
||||
|
@ -293,13 +278,10 @@ namespace Anabatic {
|
|||
virtual AutoSegment* getCanonical ( DbU::Unit& min , DbU::Unit& max );
|
||||
inline AutoSegment* getCanonical ( Interval& i );
|
||||
float getMaxUnderDensity ( Flags flags );
|
||||
inline uint32_t getReduceds () const;
|
||||
uint32_t getNonReduceds ( Flags flags=Flags::WithPerpands ) const;
|
||||
// Modifiers.
|
||||
inline void unsetFlags ( uint64_t );
|
||||
inline void setFlags ( uint64_t );
|
||||
void setFlagsOnAligneds ( uint64_t );
|
||||
inline void setRpDistance ( unsigned int );
|
||||
inline void incReduceds ();
|
||||
inline void decReduceds ();
|
||||
virtual void setDuSource ( DbU::Unit du ) = 0;
|
||||
|
@ -338,11 +320,8 @@ namespace Anabatic {
|
|||
bool moveUp ( Flags flags=Flags::NoFlags );
|
||||
bool moveDown ( Flags flags=Flags::NoFlags );
|
||||
bool reduceDoglegLayer ();
|
||||
bool bloatStackedStrap ();
|
||||
bool reduce ( Flags flags=Flags::WithPerpands );
|
||||
bool reduce ();
|
||||
bool raise ();
|
||||
void expandToMinLength ( Interval );
|
||||
void unexpandToMinLength ();
|
||||
// Canonical Modifiers.
|
||||
AutoSegment* canonize ( Flags flags=Flags::NoFlags );
|
||||
virtual void invalidate ( Flags flags=Flags::Propagate );
|
||||
|
@ -386,7 +365,7 @@ namespace Anabatic {
|
|||
static bool _analogMode;
|
||||
static bool _shortNetMode;
|
||||
static bool _initialized;
|
||||
static vector< array<DbU::Unit*,4> > _extensionCaps;
|
||||
static vector< array<DbU::Unit*,3> > _extensionCaps;
|
||||
// Internal: Attributes.
|
||||
const unsigned long _id;
|
||||
GCell* _gcell;
|
||||
|
@ -395,7 +374,6 @@ namespace Anabatic {
|
|||
unsigned int _optimalMin :16;
|
||||
unsigned int _optimalMax :16;
|
||||
unsigned int _reduceds : 2;
|
||||
unsigned int _rpDistance : 4;
|
||||
DbU::Unit _sourcePosition;
|
||||
DbU::Unit _targetPosition;
|
||||
Interval _userConstraints;
|
||||
|
@ -436,13 +414,6 @@ namespace Anabatic {
|
|||
struct CompareBySourceU : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
|
||||
};
|
||||
public:
|
||||
struct CompareByRevalidate : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
|
||||
};
|
||||
struct CompareByReduceds : public binary_function<AutoSegment*,AutoSegment*,bool> {
|
||||
bool operator() ( AutoSegment* lhs, AutoSegment* rhs ) const;
|
||||
};
|
||||
public:
|
||||
typedef std::set<AutoSegment*,CompareByDepthLength> DepthLengthSet;
|
||||
typedef std::set<AutoSegment*,CompareId> IdSet;
|
||||
|
@ -469,8 +440,7 @@ namespace Anabatic {
|
|||
);
|
||||
static void getTopologicalInfos ( AutoSegment* seed
|
||||
, vector<AutoSegment*>& collapseds
|
||||
, vector< tuple<AutoSegment*,Flags> >&
|
||||
perpandiculars
|
||||
, vector<AutoSegment*>& perpandiculars
|
||||
, DbU::Unit& leftBound
|
||||
, DbU::Unit& rightBound
|
||||
);
|
||||
|
@ -488,7 +458,6 @@ namespace Anabatic {
|
|||
inline DbU::Unit AutoSegment::getViaToTopCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][0]) : 0; }
|
||||
inline DbU::Unit AutoSegment::getViaToBottomCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][1]) : 0; }
|
||||
inline DbU::Unit AutoSegment::getViaToSameCap ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][2]) : 0; }
|
||||
inline DbU::Unit AutoSegment::getMinimalLength ( size_t depth ) { return (depth < _extensionCaps.size()) ? *(_extensionCaps[depth][3]) : 0; }
|
||||
inline unsigned long AutoSegment::getId () const { return _id; }
|
||||
inline Cell* AutoSegment::getCell () const { return base()->getCell(); }
|
||||
inline Net* AutoSegment::getNet () const { return base()->getNet(); }
|
||||
|
@ -515,7 +484,6 @@ namespace Anabatic {
|
|||
inline bool AutoSegment::getConstraints ( Interval& i ) const { return getConstraints(i.getVMin(),i.getVMax()); }
|
||||
inline AutoSegment* AutoSegment::getCanonical ( Interval& i ) { return getCanonical(i.getVMin(),i.getVMax()); }
|
||||
inline unsigned int AutoSegment::getDepth () const { return _depth; }
|
||||
inline unsigned int AutoSegment::getRpDistance () const { return _rpDistance; }
|
||||
inline DbU::Unit AutoSegment::getPitch () const { return Session::getPitch(getDepth(),Flags::NoFlags); }
|
||||
inline DbU::Unit AutoSegment::getAxis () const { return isHorizontal()?base()->getY():base()->getX(); }
|
||||
inline DbU::Unit AutoSegment::getOrigin () const { return isHorizontal()?_gcell->getYMin():_gcell->getXMin(); }
|
||||
|
@ -526,7 +494,6 @@ namespace Anabatic {
|
|||
inline DbU::Unit AutoSegment::getNativeMax () const { return _nativeConstraints.getVMax(); }
|
||||
inline const Interval& AutoSegment::getUserConstraints () const { return _userConstraints; }
|
||||
inline const Interval& AutoSegment::getNativeConstraints () const { return _nativeConstraints; }
|
||||
inline uint32_t AutoSegment::getReduceds () const { return _reduceds; }
|
||||
|
||||
inline bool AutoSegment::isHorizontal () const { return _flags & SegHorizontal; }
|
||||
inline bool AutoSegment::isVertical () const { return not (_flags & SegHorizontal); }
|
||||
|
@ -536,18 +503,14 @@ namespace Anabatic {
|
|||
inline bool AutoSegment::isWeakGlobal () const { return _flags & SegWeakGlobal; }
|
||||
inline bool AutoSegment::isLongLocal () const { return _flags & SegLongLocal; }
|
||||
inline bool AutoSegment::isLocal () const { return not (_flags & SegGlobal); }
|
||||
inline bool AutoSegment::isUnbreakable () const { return _flags & SegUnbreakable; }
|
||||
inline bool AutoSegment::isNonPref () const { return _flags & SegNonPref; }
|
||||
inline bool AutoSegment::isNonPrefOnVSmall () const { return (_flags & SegNonPref) and (_flags & SegOnVSmall); }
|
||||
inline bool AutoSegment::isBipoint () const { return _flags & SegBipoint; }
|
||||
inline bool AutoSegment::isWeakTerminal () const { return (_rpDistance < 2); }
|
||||
inline bool AutoSegment::isWeakTerminal1 () const { return (_rpDistance == 1); }
|
||||
inline bool AutoSegment::isWeakTerminal2 () const { return (_rpDistance == 2); }
|
||||
inline bool AutoSegment::isWeakTerminal () const { return _flags & SegWeakTerminal; }
|
||||
inline bool AutoSegment::isWeakTerminal1 () const { return _flags & SegWeakTerminal1; }
|
||||
inline bool AutoSegment::isWeakTerminal2 () const { return _flags & SegWeakTerminal2; }
|
||||
inline bool AutoSegment::isSourceTerminal () const { return _flags & SegSourceTerminal; }
|
||||
inline bool AutoSegment::isTargetTerminal () const { return _flags & SegTargetTerminal; }
|
||||
inline bool AutoSegment::isTerminal () const { return (_rpDistance == 0); }
|
||||
inline bool AutoSegment::isTerminal () const { return _flags & SegStrongTerminal; }
|
||||
inline bool AutoSegment::isDrag () const { return _flags & SegDrag; }
|
||||
inline bool AutoSegment::isAtMinArea () const { return _flags & SegAtMinArea; }
|
||||
inline bool AutoSegment::isNotSourceAligned () const { return _flags & SegNotSourceAligned; }
|
||||
inline bool AutoSegment::isNotTargetAligned () const { return _flags & SegNotTargetAligned; }
|
||||
inline bool AutoSegment::isNotAligned () const { return (_flags & SegNotAligned) == SegNotAligned; }
|
||||
|
@ -569,13 +532,11 @@ namespace Anabatic {
|
|||
inline bool AutoSegment::isAnalog () const { return _flags & SegAnalog; }
|
||||
inline bool AutoSegment::isWide () const { return _flags & SegWide; }
|
||||
inline bool AutoSegment::isShortNet () const { return _flags & SegShortNet; }
|
||||
inline bool AutoSegment::isNoMoveUp () const { return _flags & SegNoMoveUp; }
|
||||
inline void AutoSegment::setFlags ( uint64_t flags ) { _flags |= flags; }
|
||||
inline void AutoSegment::unsetFlags ( uint64_t flags ) { _flags &= ~flags; }
|
||||
|
||||
inline uint64_t AutoSegment::getFlags () const { return _flags; }
|
||||
inline uint64_t AutoSegment::_getFlags () const { return _flags; }
|
||||
inline void AutoSegment::setRpDistance ( unsigned int distance ) { _rpDistance=distance; }
|
||||
inline void AutoSegment::incReduceds () { if (_reduceds<3) ++_reduceds; }
|
||||
inline void AutoSegment::decReduceds () { if (_reduceds>0) --_reduceds; }
|
||||
inline void AutoSegment::setLayer ( const Layer* layer ) { base()->setLayer(layer); _depth=Session::getLayerDepth(layer); _flags|=SegInvalidatedLayer; }
|
||||
|
@ -587,7 +548,7 @@ namespace Anabatic {
|
|||
inline void AutoSegment::resetNativeConstraints ( DbU::Unit min, DbU::Unit max ) { _nativeConstraints = Interval( min, max ); }
|
||||
//inline void AutoSegment::mergeUserConstraints ( const Interval& constraints ) { _userConstraints.intersection(constraints); }
|
||||
inline void AutoSegment::resetUserConstraints () { _userConstraints = Interval(false); }
|
||||
inline DbU::Unit AutoSegment::getAnchoredLength () const { return std::abs(getTargetU() - getSourceU()); }
|
||||
|
||||
|
||||
inline void AutoSegment::setLayer ( size_t depth )
|
||||
{
|
||||
|
@ -599,13 +560,10 @@ namespace Anabatic {
|
|||
_flags|=SegInvalidatedLayer;
|
||||
}
|
||||
|
||||
|
||||
inline DbU::Unit AutoSegment::getContactWidth () const
|
||||
{ return getWidth() + Session::getViaWidth(getLayer()) - Session::getWireWidth(getLayer()); }
|
||||
|
||||
inline DbU::Unit AutoSegment::getSpanLength () const
|
||||
{ return getAnchoredLength() + getExtensionCap( Flags::Source|Flags::LayerCapOnly|Flags::NoMinLength )
|
||||
+ getExtensionCap( Flags::Target|Flags::LayerCapOnly|Flags::NoMinLength );
|
||||
}
|
||||
|
||||
inline void AutoSegment::setParent ( AutoSegment* parent )
|
||||
{
|
||||
|
@ -670,8 +628,7 @@ namespace Anabatic {
|
|||
cdebug_log(145,0) << "getTerminalCount() - " << seed << endl;
|
||||
|
||||
vector<AutoSegment*> collapseds;
|
||||
vector< tuple<AutoSegment*,Flags> >
|
||||
perpandiculars;
|
||||
vector<AutoSegment*> perpandiculars;
|
||||
DbU::Unit leftBound;
|
||||
DbU::Unit rightBound;
|
||||
|
||||
|
@ -707,3 +664,6 @@ namespace Anabatic {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::AutoSegment);
|
||||
|
||||
|
||||
# endif // ANABATIC_AUTOSEGMENT_H
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_AUTOVERTICAL_H
|
||||
#define ANABATIC_AUTOVERTICAL_H
|
||||
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "anabatic/AutoSegment.h"
|
||||
|
||||
|
@ -89,3 +91,6 @@ namespace Anabatic {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::AutoVertical);
|
||||
|
||||
|
||||
#endif // ANABATIC_AUTOHORIZONTAL_H
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_CHIP_TOOLS_H
|
||||
#define ANABATIC_CHIP_TOOLS_H
|
||||
|
||||
#include <string>
|
||||
#include "hurricane/DbU.h"
|
||||
#include "hurricane/Torus.h"
|
||||
|
@ -111,4 +113,6 @@ namespace Anabatic {
|
|||
|
||||
} // Anabatic namespace.
|
||||
|
||||
INSPECTOR_PR_SUPPORT(Anabatic::ChipTools);
|
||||
INSPECTOR_PV_SUPPORT(Anabatic::ChipTools);
|
||||
|
||||
#endif // ANABATIC_CHIP_TOOLS_H
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// -*- mode: C++; explicit-buffer-name: "Configuration.h<anabatic>" -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2016-2022, All Rights Reserved
|
||||
// Copyright (c) UPMC 2016-2018, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -14,7 +14,9 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_CONFIGURATION_H
|
||||
#define ANABATIC_CONFIGURATION_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -62,15 +64,11 @@ namespace Anabatic {
|
|||
virtual ~Configuration ();
|
||||
virtual Configuration* clone () const;
|
||||
// Methods.
|
||||
inline bool isGLayer ( const Layer* ) const;
|
||||
bool isGMetal ( const Layer* ) const;
|
||||
bool isGContact ( const Layer* ) const;
|
||||
bool isTwoMetals () const;
|
||||
bool isHybrid () const;
|
||||
bool isHV () const;
|
||||
bool isVH () const;
|
||||
inline std::string getNetBuilderStyle () const;
|
||||
inline StyleFlags getRoutingStyle () const;
|
||||
const Layer* getGContactLayer () const;
|
||||
const Layer* getGHorizontalLayer () const;
|
||||
const Layer* getGVerticalLayer () const;
|
||||
|
@ -81,13 +79,11 @@ namespace Anabatic {
|
|||
inline size_t getDVerticalDepth () const;
|
||||
inline const Layer* getDVerticalLayer () const;
|
||||
inline DbU::Unit getDVerticalWidth () const;
|
||||
inline DbU::Unit getDPVerticalWidth () const;
|
||||
inline DbU::Unit getDVerticalPitch () const;
|
||||
inline DbU::Unit getDVerticalOffset () const;
|
||||
inline size_t getDHorizontalDepth () const;
|
||||
inline const Layer* getDHorizontalLayer () const;
|
||||
inline DbU::Unit getDHorizontalWidth () const;
|
||||
inline DbU::Unit getDPHorizontalWidth () const;
|
||||
inline DbU::Unit getDHorizontalPitch () const;
|
||||
inline DbU::Unit getDHorizontalOffset () const;
|
||||
inline size_t getDContactDepth () const;
|
||||
|
@ -107,20 +103,15 @@ namespace Anabatic {
|
|||
DbU::Unit getPitch ( size_t depth, Flags flags ) const;
|
||||
DbU::Unit getOffset ( size_t depth ) const;
|
||||
DbU::Unit getWireWidth ( size_t depth ) const;
|
||||
DbU::Unit getPWireWidth ( size_t depth ) const;
|
||||
DbU::Unit getExtensionCap ( size_t depth ) const;
|
||||
Flags getDirection ( size_t depth ) const;
|
||||
DbU::Unit getPitch ( const Layer*, Flags flags ) const;
|
||||
DbU::Unit getOffset ( const Layer* ) const;
|
||||
DbU::Unit getWireWidth ( const Layer* ) const;
|
||||
DbU::Unit getPWireWidth ( const Layer* ) const;
|
||||
DbU::Unit getExtensionCap ( const Layer* ) const;
|
||||
Flags getDirection ( const Layer* ) const;
|
||||
float getSaturateRatio () const;
|
||||
size_t getSaturateRp () const;
|
||||
inline std::string getDiodeName () const;
|
||||
inline DbU::Unit getAntennaGateMaxWL () const;
|
||||
inline DbU::Unit getAntennaDiodeMaxWL () const;
|
||||
DbU::Unit getGlobalThreshold () const;
|
||||
void setAllowedDepth ( size_t );
|
||||
void setSaturateRatio ( float );
|
||||
|
@ -135,8 +126,6 @@ namespace Anabatic {
|
|||
int getGlobalIterations () const;
|
||||
DbU::Unit isOnRoutingGrid ( RoutingPad* ) const;
|
||||
bool selectRpComponent ( RoutingPad* ) const;
|
||||
inline void setRoutingStyle ( StyleFlags );
|
||||
inline void resetRoutingStyle ( StyleFlags );
|
||||
virtual void print ( Cell* ) const;
|
||||
virtual Record* _getRecord () const;
|
||||
virtual string _getString () const;
|
||||
|
@ -151,8 +140,6 @@ namespace Anabatic {
|
|||
size_t _ddepthv;
|
||||
size_t _ddepthh;
|
||||
size_t _ddepthc;
|
||||
std::string _netBuilderStyle;
|
||||
StyleFlags _routingStyle;
|
||||
CellGauge* _cg;
|
||||
RoutingGauge* _rg;
|
||||
std::vector<DbU::Unit> _extensionCaps;
|
||||
|
@ -167,18 +154,12 @@ namespace Anabatic {
|
|||
float _edgeHInc;
|
||||
float _edgeHScaling;
|
||||
int _globalIterations;
|
||||
std::string _diodeName;
|
||||
DbU::Unit _antennaGateMaxWL;
|
||||
DbU::Unit _antennaDiodeMaxWL;
|
||||
private:
|
||||
Configuration& operator= ( const Configuration& ) = delete;
|
||||
void _setTopRoutingLayer ( Name name );
|
||||
};
|
||||
|
||||
|
||||
inline std::string Configuration::getNetBuilderStyle () const { return _netBuilderStyle; }
|
||||
inline StyleFlags Configuration::getRoutingStyle () const { return _routingStyle; }
|
||||
inline bool Configuration::isGLayer ( const Layer* layer ) const { return isGMetal(layer) or isGContact(layer); }
|
||||
inline size_t Configuration::getGHorizontalDepth () const { return _gdepthh; }
|
||||
inline size_t Configuration::getGVerticalDepth () const { return _gdepthv; }
|
||||
inline DbU::Unit Configuration::getGHorizontalPitch () const { return getPitch( getGHorizontalDepth(), Flags::NoFlags ); }
|
||||
|
@ -186,27 +167,22 @@ namespace Anabatic {
|
|||
inline size_t Configuration::getDVerticalDepth () const { return _ddepthv; }
|
||||
inline const Layer* Configuration::getDVerticalLayer () const { return getRoutingLayer( getDVerticalDepth() ); }
|
||||
inline DbU::Unit Configuration::getDVerticalWidth () const { return getWireWidth ( getDVerticalDepth() ); }
|
||||
inline DbU::Unit Configuration::getDPVerticalWidth () const { return getPWireWidth ( getDVerticalDepth() ); }
|
||||
inline DbU::Unit Configuration::getDVerticalPitch () const { return getPitch ( getDVerticalDepth(), Flags::NoFlags ); }
|
||||
inline DbU::Unit Configuration::getDVerticalOffset () const { return getOffset ( getDVerticalDepth() ); }
|
||||
inline size_t Configuration::getDHorizontalDepth () const { return _ddepthh; }
|
||||
inline const Layer* Configuration::getDHorizontalLayer () const { return getRoutingLayer( getDHorizontalDepth() ); }
|
||||
inline DbU::Unit Configuration::getDHorizontalWidth () const { return getWireWidth ( getDHorizontalDepth() ); }
|
||||
inline DbU::Unit Configuration::getDPHorizontalWidth () const { return getPWireWidth ( getDHorizontalDepth() ); }
|
||||
inline DbU::Unit Configuration::getDHorizontalPitch () const { return getPitch ( getDHorizontalDepth(), Flags::NoFlags ); }
|
||||
inline DbU::Unit Configuration::getDHorizontalOffset () const { return getOffset ( getDHorizontalDepth() ); }
|
||||
inline size_t Configuration::getDContactDepth () const { return _ddepthc; }
|
||||
inline const Layer* Configuration::getDContactLayer () const { return getContactLayer( getDContactDepth() ); }
|
||||
inline DbU::Unit Configuration::getDContactWidth () const { return getWireWidth ( getDContactDepth() ); }
|
||||
inline DbU::Unit Configuration::getDContactPitch () const { return getPitch ( getDContactDepth(), Flags::NoFlags ); }
|
||||
inline std::string Configuration::getDiodeName () const { return _diodeName; }
|
||||
inline DbU::Unit Configuration::getAntennaGateMaxWL () const { return _antennaGateMaxWL; }
|
||||
inline DbU::Unit Configuration::getAntennaDiodeMaxWL () const { return _antennaDiodeMaxWL; }
|
||||
inline void Configuration::setRoutingStyle ( StyleFlags flags ) { _routingStyle = flags; }
|
||||
inline void Configuration::resetRoutingStyle ( StyleFlags flags ) { _routingStyle &= ~flags; }
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::Configuration);
|
||||
|
||||
#endif // ANABATIC_CONFIGURATION_H
|
||||
|
|
|
@ -14,15 +14,14 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_CONSTANTS_H
|
||||
#define ANABATIC_CONSTANTS_H
|
||||
|
||||
#include "hurricane/Flags.h"
|
||||
|
||||
namespace Anabatic {
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::Flags".
|
||||
|
||||
class Flags : public Hurricane::BaseFlags {
|
||||
public:
|
||||
static const BaseFlags NoFlags ; // = 0;
|
||||
|
@ -44,7 +43,6 @@ namespace Anabatic {
|
|||
static const BaseFlags ChannelRow ; // = (1 << 13);
|
||||
static const BaseFlags HRailGCell ; // = (1 << 14);
|
||||
static const BaseFlags VRailGCell ; // = (1 << 15);
|
||||
static const BaseFlags GoStraight ; // = (1 << 16);
|
||||
// Flags for Edge objects states only.
|
||||
static const BaseFlags NullCapacity ; // = (1 << 5);
|
||||
static const BaseFlags InfiniteCapacity ; // = (1 << 6);
|
||||
|
@ -54,13 +52,10 @@ namespace Anabatic {
|
|||
static const BaseFlags DestroyGCell ; // = (1 << 7);
|
||||
static const BaseFlags DestroyBaseContact ; // = (1 << 8);
|
||||
static const BaseFlags DestroyBaseSegment ; // = (1 << 9);
|
||||
static const BaseFlags DisableCanonize ; // = (1 << 10);
|
||||
// Flags for NetDatas objects states only.
|
||||
static const BaseFlags GlobalFixed ; // = (1 << 5);
|
||||
static const BaseFlags GlobalRouted ; // = (1 << 5);
|
||||
static const BaseFlags GlobalEstimated ; // = (1 << 6);
|
||||
static const BaseFlags GlobalRouted ; // = (1 << 7);
|
||||
static const BaseFlags DetailRouted ; // = (1 << 8);
|
||||
static const BaseFlags ExcludeRoute ; // = (1 << 9);
|
||||
static const BaseFlags ExcludeRoute ; // = (1 << 7);
|
||||
// Masks.
|
||||
static const BaseFlags WestSide ; // = Horizontal|Target;
|
||||
static const BaseFlags EastSide ; // = Horizontal|Source;
|
||||
|
@ -104,13 +99,6 @@ namespace Anabatic {
|
|||
static const BaseFlags CheckLowUpDensity ;
|
||||
static const BaseFlags NoUpdate ;
|
||||
static const BaseFlags NorthPath ;
|
||||
static const BaseFlags UseNonPref ;
|
||||
static const BaseFlags Force ;
|
||||
static const BaseFlags LayerCapOnly ;
|
||||
static const BaseFlags NoMinLength ;
|
||||
static const BaseFlags NoSegExt ;
|
||||
static const BaseFlags NullLength ;
|
||||
static const BaseFlags OnVSmall ;
|
||||
public:
|
||||
inline Flags ( uint64_t flags = NoFlags );
|
||||
inline Flags ( const Hurricane::BaseFlags& );
|
||||
|
@ -125,39 +113,6 @@ namespace Anabatic {
|
|||
Flags::Flags ( const Hurricane::BaseFlags& flags ) : BaseFlags(flags) { }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::StyleFlags".
|
||||
|
||||
class StyleFlags : public Hurricane::BaseFlags {
|
||||
public:
|
||||
static const BaseFlags NoStyle; // = 0;
|
||||
static const BaseFlags HV ; // = (1 << 0);
|
||||
static const BaseFlags VH ; // = (1 << 1);
|
||||
static const BaseFlags OTH ; // = (1 << 2);
|
||||
static const BaseFlags Channel; // = (1 << 3);
|
||||
static const BaseFlags Hybrid ; // = (1 << 4);
|
||||
public:
|
||||
inline StyleFlags ( std::string );
|
||||
inline StyleFlags ( uint64_t flags = NoStyle );
|
||||
inline StyleFlags ( const Hurricane::BaseFlags& );
|
||||
virtual ~StyleFlags ();
|
||||
static StyleFlags toFlag ( std::string );
|
||||
StyleFlags from ( std::string );
|
||||
virtual std::string asString () const;
|
||||
virtual std::string _getTypeName () const;
|
||||
virtual std::string _getString () const;
|
||||
};
|
||||
|
||||
|
||||
StyleFlags::StyleFlags ( std::string textFlags ) : BaseFlags(NoStyle) { from(textFlags); }
|
||||
StyleFlags::StyleFlags ( uint64_t flags ) : BaseFlags(flags) { }
|
||||
StyleFlags::StyleFlags ( const Hurricane::BaseFlags& flags ) : BaseFlags(flags) { }
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Misc. enums.
|
||||
|
||||
|
||||
enum FlagsMode { FlagsFunction = 1
|
||||
};
|
||||
|
||||
|
@ -190,4 +145,6 @@ namespace Anabatic {
|
|||
} // Anabatic namespace.
|
||||
|
||||
|
||||
INSPECTOR_PR_SUPPORT(Anabatic::Flags);
|
||||
INSPECTOR_PV_SUPPORT(Anabatic::Flags)
|
||||
|
||||
#endif // ANABATIC_CONSTANTS_H
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_DIJKSTRA_H
|
||||
#define ANABATIC_DIJKSTRA_H
|
||||
|
||||
#include <set>
|
||||
#include <iomanip>
|
||||
#include "hurricane/Observer.h"
|
||||
|
@ -187,7 +189,6 @@ namespace Anabatic {
|
|||
, iHorizontal = (1<<7)
|
||||
, iVertical = (1<<8)
|
||||
, iSet = (1<<9)
|
||||
, Driver = (1<<10)
|
||||
};
|
||||
public:
|
||||
static DbU::Unit unreached;
|
||||
|
@ -199,7 +200,6 @@ namespace Anabatic {
|
|||
inline Vertex ( GCell* );
|
||||
//inline Vertex ( size_t id );
|
||||
inline ~Vertex ();
|
||||
inline bool isDriver () const;
|
||||
inline bool isAnalog () const;
|
||||
inline bool hasDoneAllRps () const;
|
||||
inline Contact* hasGContact ( Net* ) const;
|
||||
|
@ -220,7 +220,6 @@ namespace Anabatic {
|
|||
Edge* getFrom () const;
|
||||
inline Vertex* getPredecessor () const;
|
||||
inline Vertex* getNeighbor ( Edge* ) const;
|
||||
inline void setDriver ( bool state );
|
||||
inline void setDistance ( DbU::Unit );
|
||||
inline void setStamp ( int );
|
||||
inline void setConnexId ( int );
|
||||
|
@ -334,7 +333,6 @@ namespace Anabatic {
|
|||
|
||||
inline Vertex* Vertex::lookup ( GCell* gcell ) { return gcell->getObserver<Vertex>(GCell::Observable::Vertex); }
|
||||
inline Vertex::~Vertex () { _gcell->setObserver( GCell::Observable::Vertex, NULL ); }
|
||||
inline bool Vertex::isDriver () const { return _flags & Driver; }
|
||||
inline bool Vertex::isAnalog () const { return _gcell->isAnalog(); }
|
||||
inline Box Vertex::getBoundingBox () const { return _gcell->getBoundingBox(); }
|
||||
inline Edges Vertex::getEdges ( Flags sides ) const { return _gcell->getEdges(sides); }
|
||||
|
@ -371,12 +369,6 @@ namespace Anabatic {
|
|||
return (gcell) ? gcell->getObserver<Vertex>(GCell::Observable::Vertex) : NULL;
|
||||
}
|
||||
|
||||
inline void Vertex::setDriver ( bool state )
|
||||
{
|
||||
if (state) _flags |= Driver;
|
||||
else _flags &= ~Driver;
|
||||
}
|
||||
|
||||
inline bool Vertex::CompareById::operator() ( const Vertex* lhs, const Vertex* rhs ) const
|
||||
{ return lhs->getId() < rhs->getId(); }
|
||||
|
||||
|
@ -439,7 +431,7 @@ namespace Anabatic {
|
|||
class CompareByDistance {
|
||||
public:
|
||||
inline CompareByDistance ();
|
||||
bool operator() ( const Vertex* lhs, const Vertex* rhs ) const;
|
||||
bool operator() ( const Vertex* lhs, const Vertex* rhs );
|
||||
static inline void setQueue ( PriorityQueue* );
|
||||
private:
|
||||
static PriorityQueue* _pqueue;
|
||||
|
@ -522,13 +514,11 @@ namespace Anabatic {
|
|||
inline bool isSourceVertex ( Vertex* ) const;
|
||||
inline Net* getNet () const;
|
||||
inline bool isTargetVertex ( Vertex* ) const;
|
||||
DbU::Unit getAntennaGateMaxWL () const;
|
||||
inline DbU::Unit getSearchAreaHalo () const;
|
||||
template<typename DistanceT>
|
||||
inline DistanceT* setDistance ( DistanceT );
|
||||
inline void setSearchAreaHalo ( DbU::Unit );
|
||||
void load ( Net* net );
|
||||
void loadFixedGlobal ( Net* net );
|
||||
void run ( Mode mode=Mode::Standart );
|
||||
inline const VertexSet& getSources () const;
|
||||
private:
|
||||
|
@ -603,4 +593,6 @@ namespace Anabatic {
|
|||
|
||||
GETSTRING_POINTER_SUPPORT(Anabatic::Vertex);
|
||||
IOSTREAM_POINTER_SUPPORT(Anabatic::Vertex);
|
||||
INSPECTOR_PR_SUPPORT(Anabatic::Dijkstra::Mode);
|
||||
INSPECTOR_PV_SUPPORT(Anabatic::Dijkstra::Mode);
|
||||
|
||||
#endif // ANABATIC_DIJKSTRA_H
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_EDGE_H
|
||||
#define ANABATIC_EDGE_H
|
||||
|
||||
#include <string>
|
||||
#include "hurricane/Name.h"
|
||||
#include "hurricane/Interval.h"
|
||||
|
@ -58,7 +60,6 @@ namespace Anabatic {
|
|||
inline bool isHorizontal () const;
|
||||
inline bool hasNet ( const Net* ) const;
|
||||
inline unsigned int getCapacity () const;
|
||||
inline unsigned int getRawCapacity () const;
|
||||
inline unsigned int getReservedCapacity () const;
|
||||
inline unsigned int getCapacity ( size_t depth ) const;
|
||||
inline unsigned int getRealOccupancy () const;
|
||||
|
@ -135,8 +136,8 @@ namespace Anabatic {
|
|||
inline bool Edge::isVertical () const { return _flags.isset(Flags::Vertical); }
|
||||
inline bool Edge::isHorizontal () const { return _flags.isset(Flags::Horizontal); }
|
||||
inline bool Edge::hasNet ( const Net* owner ) const { return getSegment(owner); }
|
||||
inline unsigned int Edge::getCapacity () const { return (_capacities) ? _capacities->getCapacity()-_reservedCapacity : 0; }
|
||||
inline unsigned int Edge::getCapacity ( size_t depth ) const { return (_capacities) ? _capacities->getCapacity(depth) : 0; }
|
||||
inline unsigned int Edge::getRawCapacity () const { return (_capacities) ? _capacities->getCapacity() : 0; }
|
||||
inline unsigned int Edge::getReservedCapacity () const { return _reservedCapacity; }
|
||||
inline unsigned int Edge::getRealOccupancy () const { return _realOccupancy; }
|
||||
inline float Edge::getEstimateOccupancy () const { return _estimateOccupancy; }
|
||||
|
@ -156,13 +157,9 @@ namespace Anabatic {
|
|||
inline Flags& Edge::setFlags ( Flags mask ) { _flags |= mask; return _flags; }
|
||||
inline void Edge::reserveCapacity ( int delta ) { _reservedCapacity = ((int)_reservedCapacity+delta > 0) ? _reservedCapacity+delta : 0; }
|
||||
|
||||
inline unsigned int Edge::getCapacity () const
|
||||
{
|
||||
if (not _capacities) return 0;
|
||||
return (_capacities->getCapacity() > (int)_reservedCapacity) ? _capacities->getCapacity()-_reservedCapacity : 0;
|
||||
}
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::Edge);
|
||||
|
||||
#endif // ANABATIC_EDGE_H
|
||||
|
|
|
@ -14,9 +14,10 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_GCELL_H
|
||||
#define ANABATIC_GCELL_H
|
||||
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <functional>
|
||||
|
@ -103,32 +104,24 @@ namespace Anabatic {
|
|||
class CompareByDensity : public binary_function<GCell*,GCell*,bool> {
|
||||
public:
|
||||
CompareByDensity ( size_t depth );
|
||||
inline bool operator() ( GCell* lhs, GCell* rhs ) const;
|
||||
inline bool operator() ( GCell* lhs, GCell* rhs );
|
||||
private:
|
||||
size_t _depth;
|
||||
};
|
||||
class CompareByKey : public binary_function<const GCell*,const GCell*,bool> {
|
||||
public:
|
||||
inline bool operator() ( const GCell* lhs, const GCell* rhs ) const;
|
||||
inline bool operator() ( const GCell* lhs, const GCell* rhs );
|
||||
};
|
||||
public:
|
||||
class Key {
|
||||
public:
|
||||
inline Key ( const GCell*, size_t depth );
|
||||
inline ~Key ();
|
||||
inline Key ( GCell*, size_t depth );
|
||||
inline float getDensity () const;
|
||||
inline const GCell* getGCell () const;
|
||||
inline bool isActive () const;
|
||||
inline bool isSaturated () const;
|
||||
inline GCell* getGCell () 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:
|
||||
const GCell* _gcell;
|
||||
GCell* _gcell;
|
||||
float _density;
|
||||
};
|
||||
public:
|
||||
|
@ -140,7 +133,6 @@ namespace Anabatic {
|
|||
public:
|
||||
static GCell* create ( AnabaticEngine* );
|
||||
public:
|
||||
inline bool isSatProcessed ( size_t depth ) const;
|
||||
inline bool isSaturated () const;
|
||||
bool isSaturated ( size_t depth ) const;
|
||||
inline bool isInvalidated () const;
|
||||
|
@ -155,7 +147,6 @@ namespace Anabatic {
|
|||
inline bool isMatrix () const;
|
||||
inline bool isRow () const;
|
||||
inline bool isIoPad () const;
|
||||
inline bool isGoStraight () const;
|
||||
inline bool isHRail () const;
|
||||
inline bool isVRail () const;
|
||||
inline bool isStdCellRow () const;
|
||||
|
@ -164,7 +155,6 @@ namespace Anabatic {
|
|||
bool isEast ( GCell* ) const;
|
||||
bool isNorth ( GCell* ) const;
|
||||
bool isSouth ( GCell* ) const;
|
||||
bool hasNet ( const Net* ) const;
|
||||
Contact* hasGContact ( const Contact* ) const;
|
||||
Contact* hasGContact ( const Net* ) const;
|
||||
bool isHorizontalPlane ( size_t depth ) const;
|
||||
|
@ -216,8 +206,7 @@ namespace Anabatic {
|
|||
bool doGrid ();
|
||||
Contact* getGContact ( Net* );
|
||||
inline const vector<Contact*>& getGContacts () const;
|
||||
Segment* hasGoThrough ( Net* ) const;
|
||||
Contact* breakGoThrough ( Net* );
|
||||
Contact* breakGoThrough ( Net* net );
|
||||
bool unrefContact ( Contact* );
|
||||
void setSouthWestCorner ( DbU::Unit x, DbU::Unit y );
|
||||
void cleanupGlobal ();
|
||||
|
@ -227,7 +216,6 @@ namespace Anabatic {
|
|||
bool hasFreeTrack ( size_t depth, float reserve ) const;
|
||||
inline size_t getDepth () const;
|
||||
size_t getNetCount () const;
|
||||
inline int getRpCount () const;
|
||||
int getHCapacity () const;
|
||||
int getVCapacity () const;
|
||||
int getCapacity ( size_t depth ) const;
|
||||
|
@ -252,14 +240,9 @@ namespace Anabatic {
|
|||
inline AutoSegments getStopSegments ( Flags direction );
|
||||
size_t getRoutingPads ( set<RoutingPad*>& );
|
||||
inline const Key& getKey () const;
|
||||
inline Key* cloneKey ( size_t depth ) const;
|
||||
inline Key* getLastClonedKey () const;
|
||||
inline void clearClonedKey () const;
|
||||
size_t checkDensity () const;
|
||||
bool checkEdgeSaturation ( size_t hreserved, size_t vreserved) const;
|
||||
void setType ( Flags );
|
||||
inline void setSatProcessed ( size_t depth );
|
||||
void postGlobalAnnotate ();
|
||||
void addBlockage ( size_t depth, DbU::Unit );
|
||||
inline void addHSegment ( AutoSegment* );
|
||||
inline void addVSegment ( AutoSegment* );
|
||||
|
@ -280,7 +263,7 @@ namespace Anabatic {
|
|||
bool stepNetDesaturate ( size_t depth
|
||||
, set<Net*>& globalNets
|
||||
, Set& invalidateds );
|
||||
inline void incRpCount ( int );
|
||||
|
||||
void forceEdgesCapacities ( unsigned int hcapacities, unsigned int vcapacities );
|
||||
// Misc. functions.
|
||||
inline const Flags& flags () const;
|
||||
|
@ -337,8 +320,6 @@ namespace Anabatic {
|
|||
vector<AutoContact*> _contacts;
|
||||
size_t _depth;
|
||||
size_t _pinDepth;
|
||||
uint32_t _satProcessed;
|
||||
int _rpCount;
|
||||
DbU::Unit* _blockages;
|
||||
float _cDensity;
|
||||
float* _densities;
|
||||
|
@ -346,7 +327,6 @@ namespace Anabatic {
|
|||
float* _fragmentations;
|
||||
float* _globalsCount;
|
||||
Key _key;
|
||||
mutable Key* _lastClonedKey;
|
||||
};
|
||||
|
||||
|
||||
|
@ -361,7 +341,6 @@ namespace Anabatic {
|
|||
inline bool GCell::isMatrix () const { return _flags & Flags::MatrixGCell; }
|
||||
inline bool GCell::isRow () const { return _flags & Flags::RowGCellMask; }
|
||||
inline bool GCell::isIoPad () const { return _flags & Flags::IoPadGCell; }
|
||||
inline bool GCell::isGoStraight () const { return _flags & Flags::GoStraight; }
|
||||
inline bool GCell::isHRail () const { return _flags & Flags::HRailGCell; }
|
||||
inline bool GCell::isVRail () const { return _flags & Flags::VRailGCell; }
|
||||
inline bool GCell::isStdCellRow () const { return _flags & Flags::StdCellRow; }
|
||||
|
@ -394,7 +373,6 @@ namespace Anabatic {
|
|||
inline GCell* GCell::getUnder ( Point p ) const { return getUnder(p.getX(),p.getY()); }
|
||||
inline const vector<Contact*>& GCell::getGContacts () const { return _gcontacts; }
|
||||
inline size_t GCell::getDepth () const { return _depth; }
|
||||
inline int GCell::getRpCount () const { return _rpCount; }
|
||||
const vector<AutoSegment*>& GCell::getVSegments () const { return _vsegments; }
|
||||
inline const vector<AutoSegment*>& GCell::getHSegments () const { return _hsegments; }
|
||||
inline const vector<AutoContact*>& GCell::getContacts () const { return _contacts; }
|
||||
|
@ -404,9 +382,6 @@ namespace Anabatic {
|
|||
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; }
|
||||
|
@ -441,10 +416,6 @@ namespace Anabatic {
|
|||
return Interval( getXMin(), getConstraintXMax(shrink) );
|
||||
}
|
||||
|
||||
inline void GCell::incRpCount ( int delta )
|
||||
{ _rpCount = (_rpCount + delta > 0) ? (_rpCount + delta) : 0; }
|
||||
|
||||
|
||||
inline void GCell::setObserver ( size_t slot, BaseObserver* observer )
|
||||
{ _observable.setObserver( slot, observer ); }
|
||||
|
||||
|
@ -490,12 +461,6 @@ namespace Anabatic {
|
|||
inline void GCell::addContact ( AutoContact* contact )
|
||||
{ _flags |= Flags::Invalidated; _contacts.push_back(contact); }
|
||||
|
||||
inline bool GCell::isSatProcessed ( size_t depth ) const
|
||||
{ return (_satProcessed & (1 << depth)); }
|
||||
|
||||
inline void GCell::setSatProcessed ( size_t depth )
|
||||
{ _satProcessed |= (1 << depth); }
|
||||
|
||||
|
||||
inline bool operator< ( const GCell& lhs, const GCell& rhs )
|
||||
{
|
||||
|
@ -504,25 +469,17 @@ namespace Anabatic {
|
|||
return lhs.getId() < rhs.getId();
|
||||
}
|
||||
|
||||
|
||||
// GCell::CompareByKey Inline Functions.
|
||||
inline bool GCell::CompareByKey::operator() ( const GCell* lhs, const GCell* rhs ) const
|
||||
inline bool GCell::CompareByKey::operator() ( const GCell* lhs, const GCell* rhs )
|
||||
{ return lhs->getKey() < rhs->getKey(); }
|
||||
|
||||
|
||||
// GCell::Key Inline Functions.
|
||||
inline GCell::Key::Key ( const GCell* owner, size_t depth )
|
||||
: _gcell(owner)
|
||||
, _density(owner->getWDensity(depth,Flags::NoUpdate))
|
||||
{ }
|
||||
|
||||
inline GCell::Key::~Key ()
|
||||
{ if (isActive()) _gcell->clearClonedKey(); }
|
||||
|
||||
inline GCell::Key::Key ( GCell* owner, size_t depth ) : _gcell(owner), _density(owner->getWDensity(depth,Flags::NoUpdate)) {}
|
||||
inline float GCell::Key::getDensity () const { return _density; }
|
||||
inline const GCell* GCell::Key::getGCell () const { return _gcell; }
|
||||
inline 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 )
|
||||
{
|
||||
|
@ -532,22 +489,6 @@ namespace Anabatic {
|
|||
return lhs._gcell->getId() < rhs._gcell->getId();
|
||||
}
|
||||
|
||||
inline bool GCell::Key::Compare::operator() ( const GCell::Key* lhs, const GCell::Key* rhs ) const
|
||||
{
|
||||
//if (lhs->isSaturated() xor rhs->isSaturated()) return lhs->isSaturated();
|
||||
|
||||
float difference = lhs->_density - rhs->_density;
|
||||
if (difference != 0.0) return (difference < 0.0);
|
||||
|
||||
return lhs->_gcell->getId() < rhs->_gcell->getId();
|
||||
}
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "GCellKeyQueue".
|
||||
|
||||
typedef std::priority_queue< GCell::Key*, std::vector<GCell::Key*>, GCell::Key::Compare > GCellKeyQueue;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "GCellDensitySet".
|
||||
|
@ -592,3 +533,5 @@ namespace Anabatic {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::GCell);
|
||||
|
||||
#endif // ANABATIC_GCELL_H
|
||||
|
|
|
@ -13,7 +13,9 @@
|
|||
// | C++ Header : "./anabatic/NetBuilder.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_NET_BUILDER_H
|
||||
#define ANABATIC_NET_BUILDER_H
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
|
@ -39,7 +41,6 @@ namespace Anabatic {
|
|||
class AutoContact;
|
||||
class AutoSegment;
|
||||
class AnabaticEngine;
|
||||
class NetData;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -47,39 +48,31 @@ namespace Anabatic {
|
|||
|
||||
class ForkStack {
|
||||
public:
|
||||
inline void push ( Hook* from, AutoContact* contact, uint64_t flags );
|
||||
inline void push ( Hook* from, AutoContact* contact );
|
||||
inline void pop ();
|
||||
inline Hook* getFrom () const;
|
||||
inline AutoContact* getContact () const;
|
||||
inline uint64_t getFlags () const;
|
||||
inline void setFlags ( uint64_t );
|
||||
private:
|
||||
struct Element {
|
||||
Hook* _from;
|
||||
AutoContact* _contact;
|
||||
uint64_t _flags;
|
||||
inline Element ( Hook* from, AutoContact* contact, uint64_t flags );
|
||||
inline Element ( Hook* from, AutoContact* contact );
|
||||
};
|
||||
private:
|
||||
list<Element> _stack;
|
||||
};
|
||||
|
||||
|
||||
inline ForkStack::Element::Element ( Hook* from, AutoContact* contact, uint64_t flags ) : _from(from), _contact(contact), _flags(flags) {}
|
||||
inline ForkStack::Element::Element ( Hook* from, AutoContact* contact ) : _from(from), _contact(contact) {}
|
||||
inline void ForkStack::pop () { if (not _stack.empty()) _stack.pop_back(); }
|
||||
inline Hook* ForkStack::getFrom () const { return _stack.empty() ? NULL : _stack.back()._from; }
|
||||
inline AutoContact* ForkStack::getContact () const { return _stack.empty() ? NULL : _stack.back()._contact; }
|
||||
inline uint64_t ForkStack::getFlags () const { return _stack.empty() ? 0 : _stack.back()._flags; }
|
||||
inline void ForkStack::setFlags ( uint64_t flags ) { if (not _stack.empty()) _stack.back()._flags |= flags; }
|
||||
|
||||
|
||||
inline void ForkStack::push ( Hook* from, AutoContact* contact, uint64_t flags )
|
||||
inline void ForkStack::push ( Hook* from, AutoContact* contact )
|
||||
{
|
||||
cdebug_log(145,0) << " Stacking: " << endl;
|
||||
cdebug_log(145,0) << " + " << from << endl;
|
||||
cdebug_log(145,0) << " + " << contact << endl;
|
||||
cdebug_log(145,0) << " + " << flags << endl;
|
||||
_stack.push_back( Element(from,contact,flags) );
|
||||
cdebug_log(145,0) << " Stacking " << from << " + " << contact << endl;
|
||||
_stack.push_back( Element(from,contact) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -105,20 +98,16 @@ namespace Anabatic {
|
|||
, WestBound = (1 << 14)
|
||||
, EastBound = (1 << 15)
|
||||
, Middle = (1 << 16)
|
||||
, UseNonPref = (1 << 17)
|
||||
, NoProtect = (1 << 18)
|
||||
, ToUpperRouting = (1 << 19)
|
||||
, HBothAccess = HAccess|HAccessEW
|
||||
, SouthWest = SouthBound|WestBound
|
||||
, NorthEast = NorthBound|EastBound
|
||||
};
|
||||
enum TopologyFlag { Global_Vertical_End = (1 << 0)
|
||||
, Global_Horizontal_End = (1 << 1)
|
||||
, Global_Horizontal = (1 << 2)
|
||||
, Global_Vertical = (1 << 3)
|
||||
, Global_Turn = (1 << 4)
|
||||
, Global_Fork = (1 << 5)
|
||||
, Global_Fixed = (1 << 6)
|
||||
enum TopologyFlag { Global_Vertical_End = 0x00000001
|
||||
, Global_Horizontal_End = 0x00000002
|
||||
, Global_Horizontal = 0x00000004
|
||||
, Global_Vertical = 0x00000008
|
||||
, Global_Turn = 0x00000010
|
||||
, Global_Fork = 0x00000020
|
||||
, Global_Fixed = 0x00000040
|
||||
, Global_End = Global_Vertical_End | Global_Horizontal_End
|
||||
, Global_Split = Global_Horizontal | Global_Vertical | Global_Fork
|
||||
};
|
||||
|
@ -157,22 +146,19 @@ namespace Anabatic {
|
|||
NetBuilder ();
|
||||
virtual ~NetBuilder ();
|
||||
void clear ();
|
||||
inline bool isStrictChannel () const;
|
||||
inline bool isUpperMetalRp () const;
|
||||
inline bool isTwoMetals () const;
|
||||
inline AnabaticEngine* getAnabatic () const;
|
||||
inline unsigned int getDegree () const;
|
||||
inline void setDegree ( unsigned int degree );
|
||||
void fixSegments ();
|
||||
NetBuilder& setStartHook ( AnabaticEngine*
|
||||
, Hook* fromHook
|
||||
, AutoContact* sourceContact=NULL
|
||||
, uint64_t sourceFlags=0 );
|
||||
, AutoContact* sourceContact=NULL );
|
||||
void construct ();
|
||||
inline unsigned int getStateG () const;
|
||||
inline UConnexity getConnexity () const;
|
||||
inline UConnexity& getConnexity ();
|
||||
inline Net* getNet () const;
|
||||
inline NetData* getNetData () const;
|
||||
inline GCell* getGCell () const;
|
||||
inline AutoContact* getSourceContact () const;
|
||||
inline AutoContact* getSouthWestContact () const;
|
||||
|
@ -180,8 +166,6 @@ namespace Anabatic {
|
|||
inline AutoContact* getNorthEastContact () const;
|
||||
inline AutoContact*& getNorthEastContact ();
|
||||
inline Hook* getFromHook () const;
|
||||
inline uint64_t getSourceFlags () const;
|
||||
inline uint64_t getFlags () const;
|
||||
inline ForkStack& getForks ();
|
||||
inline vector<RoutingPad*>& getRoutingPads ();
|
||||
inline map<Component*,AutoSegment*>& getRpLookup ();
|
||||
|
@ -200,7 +184,6 @@ namespace Anabatic {
|
|||
inline void clearSouths ();
|
||||
inline void clearEasts ();
|
||||
inline void clearWests ();
|
||||
inline void setFlags ( uint64_t );
|
||||
inline void setFromHook ( Hook* );
|
||||
inline void setSouthWestContact ( AutoContact* );
|
||||
inline void setNorthEastContact ( AutoContact* );
|
||||
|
@ -208,7 +191,6 @@ namespace Anabatic {
|
|||
inline void swapCornerContacts ();
|
||||
inline void addToFixSegments ( AutoSegment* );
|
||||
bool push ( Hook* to, AutoContact* contact, uint64_t flags=0 );
|
||||
bool isInsideBlockage ( GCell*, Component* ) const;
|
||||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags ) = 0;
|
||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags ) = 0;
|
||||
virtual AutoContact* doRp_AccessPad ( RoutingPad*, uint64_t flags );
|
||||
|
@ -220,8 +202,6 @@ namespace Anabatic {
|
|||
virtual bool _do_xG ();
|
||||
virtual bool _do_2G ();
|
||||
virtual bool _do_xG_1Pad ();
|
||||
virtual bool _do_1G_1PinM1 ();
|
||||
virtual bool _do_2G_1PinM1 ();
|
||||
virtual bool _do_1G_1PinM2 ();
|
||||
virtual bool _do_xG_1PinM2 ();
|
||||
virtual bool _do_1G_1PinM3 ();
|
||||
|
@ -236,12 +216,6 @@ namespace Anabatic {
|
|||
virtual bool _do_xG_xM2 ();
|
||||
virtual bool _do_1G_1M3 ();
|
||||
virtual bool _do_xG_xM3 ();
|
||||
virtual bool _do_1G_xM1_1PinM1 ();
|
||||
virtual bool _do_1G_xM1_1PinM2 ();
|
||||
virtual bool _do_2G_xM1_1PinM2 ();
|
||||
virtual bool _do_1G_1M1_1PinM3 ();
|
||||
virtual bool _do_2G_xM1_1PinM3 ();
|
||||
virtual bool _do_3G_xM1_1PinM3 ();
|
||||
virtual bool _do_globalSegment ();
|
||||
virtual void singleGCell ( AnabaticEngine*, Net* );
|
||||
AutoContact* _doHChannel ();
|
||||
|
@ -276,10 +250,6 @@ namespace Anabatic {
|
|||
, Conn_1G_3M1 = CONNEXITY_VALUE( 1, 3, 0, 0, 0 , 0 )
|
||||
, Conn_1G_4M1 = CONNEXITY_VALUE( 1, 4, 0, 0, 0 , 0 )
|
||||
, Conn_1G_5M1 = CONNEXITY_VALUE( 1, 5, 0, 0, 0 , 0 )
|
||||
, Conn_1G_6M1 = CONNEXITY_VALUE( 1, 6, 0, 0, 0 , 0 )
|
||||
, Conn_1G_7M1 = CONNEXITY_VALUE( 1, 7, 0, 0, 0 , 0 )
|
||||
, Conn_1G_8M1 = CONNEXITY_VALUE( 1, 8, 0, 0, 0 , 0 )
|
||||
, Conn_1G_9M1 = CONNEXITY_VALUE( 1, 9, 0, 0, 0 , 0 )
|
||||
, Conn_1G_1M2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 0 )
|
||||
, Conn_1G_2M2 = CONNEXITY_VALUE( 1, 0, 2, 0, 0 , 0 )
|
||||
, Conn_1G_3M2 = CONNEXITY_VALUE( 1, 0, 3, 0, 0 , 0 )
|
||||
|
@ -296,10 +266,6 @@ namespace Anabatic {
|
|||
, Conn_2G_3M1 = CONNEXITY_VALUE( 2, 3, 0, 0, 0 , 0 )
|
||||
, Conn_2G_4M1 = CONNEXITY_VALUE( 2, 4, 0, 0, 0 , 0 )
|
||||
, Conn_2G_5M1 = CONNEXITY_VALUE( 2, 5, 0, 0, 0 , 0 )
|
||||
, Conn_2G_6M1 = CONNEXITY_VALUE( 2, 6, 0, 0, 0 , 0 )
|
||||
, Conn_2G_7M1 = CONNEXITY_VALUE( 2, 7, 0, 0, 0 , 0 )
|
||||
, Conn_2G_8M1 = CONNEXITY_VALUE( 2, 8, 0, 0, 0 , 0 )
|
||||
, Conn_2G_9M1 = CONNEXITY_VALUE( 2, 9, 0, 0, 0 , 0 )
|
||||
, Conn_2G_1M2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 0 )
|
||||
, Conn_2G_2M2 = CONNEXITY_VALUE( 2, 0, 2, 0, 0 , 0 )
|
||||
, Conn_2G_3M2 = CONNEXITY_VALUE( 2, 0, 3, 0, 0 , 0 )
|
||||
|
@ -314,11 +280,6 @@ namespace Anabatic {
|
|||
, Conn_3G_2M1 = CONNEXITY_VALUE( 3, 2, 0, 0, 0 , 0 )
|
||||
, Conn_3G_3M1 = CONNEXITY_VALUE( 3, 3, 0, 0, 0 , 0 )
|
||||
, Conn_3G_4M1 = CONNEXITY_VALUE( 3, 4, 0, 0, 0 , 0 )
|
||||
, Conn_3G_5M1 = CONNEXITY_VALUE( 3, 5, 0, 0, 0 , 0 )
|
||||
, Conn_3G_6M1 = CONNEXITY_VALUE( 3, 6, 0, 0, 0 , 0 )
|
||||
, Conn_3G_7M1 = CONNEXITY_VALUE( 3, 7, 0, 0, 0 , 0 )
|
||||
, Conn_3G_8M1 = CONNEXITY_VALUE( 3, 8, 0, 0, 0 , 0 )
|
||||
, Conn_3G_9M1 = CONNEXITY_VALUE( 3, 9, 0, 0, 0 , 0 )
|
||||
, Conn_3G_1M2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 0 )
|
||||
, Conn_3G_2M2 = CONNEXITY_VALUE( 3, 0, 2, 0, 0 , 0 )
|
||||
, Conn_3G_1M3 = CONNEXITY_VALUE( 3, 0, 0, 1, 0 , 0 )
|
||||
|
@ -330,40 +291,17 @@ namespace Anabatic {
|
|||
, Conn_4G_2M1 = CONNEXITY_VALUE( 4, 2, 0, 0, 0 , 0 )
|
||||
, Conn_4G_3M1 = CONNEXITY_VALUE( 4, 3, 0, 0, 0 , 0 )
|
||||
, Conn_4G_4M1 = CONNEXITY_VALUE( 4, 4, 0, 0, 0 , 0 )
|
||||
, Conn_4G_5M1 = CONNEXITY_VALUE( 4, 5, 0, 0, 0 , 0 )
|
||||
, Conn_4G_6M1 = CONNEXITY_VALUE( 4, 6, 0, 0, 0 , 0 )
|
||||
, Conn_4G_7M1 = CONNEXITY_VALUE( 4, 7, 0, 0, 0 , 0 )
|
||||
, Conn_4G_8M1 = CONNEXITY_VALUE( 4, 8, 0, 0, 0 , 0 )
|
||||
, Conn_4G_9M1 = CONNEXITY_VALUE( 4, 9, 0, 0, 0 , 0 )
|
||||
, Conn_4G_1M2 = CONNEXITY_VALUE( 4, 0, 1, 0, 0 , 0 )
|
||||
, Conn_4G_1M3 = CONNEXITY_VALUE( 4, 0, 0, 1, 0 , 0 )
|
||||
, Conn_1G_1Pad = CONNEXITY_VALUE( 1, 0, 0, 0, 1 , 0 )
|
||||
, Conn_2G_1Pad = CONNEXITY_VALUE( 2, 0, 0, 0, 1 , 0 )
|
||||
, Conn_3G_1Pad = CONNEXITY_VALUE( 3, 0, 0, 0, 1 , 0 )
|
||||
, Conn_1G_1PinM1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 1 )
|
||||
, Conn_2G_1PinM1 = CONNEXITY_VALUE( 2, 1, 0, 0, 0 , 1 )
|
||||
, Conn_1G_1PinM2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 1 )
|
||||
, Conn_2G_1PinM2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 1 )
|
||||
, Conn_3G_1PinM2 = CONNEXITY_VALUE( 3, 0, 1, 0, 0 , 1 )
|
||||
, Conn_1G_1M1_1PinM1 = CONNEXITY_VALUE( 1, 1, 0, 0, 0 , 1 )
|
||||
, Conn_1G_2M1_1PinM1 = CONNEXITY_VALUE( 1, 2, 0, 0, 0 , 1 )
|
||||
, Conn_1G_1M1_1PinM2 = CONNEXITY_VALUE( 1, 1, 1, 0, 0 , 1 )
|
||||
, Conn_1G_2M1_1PinM2 = CONNEXITY_VALUE( 1, 2, 1, 0, 0 , 1 )
|
||||
, Conn_1G_3M1_1PinM2 = CONNEXITY_VALUE( 1, 3, 1, 0, 0 , 1 )
|
||||
, Conn_1G_4M1_1PinM2 = CONNEXITY_VALUE( 1, 4, 1, 0, 0 , 1 )
|
||||
, Conn_1G_5M1_1PinM2 = CONNEXITY_VALUE( 1, 5, 1, 0, 0 , 1 )
|
||||
, Conn_2G_1M1_1PinM2 = CONNEXITY_VALUE( 2, 1, 1, 0, 0 , 1 )
|
||||
, Conn_2G_2M1_1PinM2 = CONNEXITY_VALUE( 2, 2, 1, 0, 0 , 1 )
|
||||
, Conn_1G_1PinM3 = CONNEXITY_VALUE( 1, 0, 0, 1, 0 , 1 )
|
||||
, Conn_2G_1PinM3 = CONNEXITY_VALUE( 2, 0, 0, 1, 0 , 1 )
|
||||
, Conn_3G_1PinM3 = CONNEXITY_VALUE( 3, 0, 0, 1, 0 , 1 )
|
||||
, Conn_1G_1M1_1PinM3 = CONNEXITY_VALUE( 1, 1, 0, 1, 0 , 1 )
|
||||
, Conn_2G_1M1_1PinM3 = CONNEXITY_VALUE( 2, 1, 0, 1, 0 , 1 )
|
||||
, Conn_2G_2M1_1PinM3 = CONNEXITY_VALUE( 2, 2, 0, 1, 0 , 1 )
|
||||
, Conn_2G_3M1_1PinM3 = CONNEXITY_VALUE( 2, 3, 0, 1, 0 , 1 )
|
||||
, Conn_3G_1M1_1PinM3 = CONNEXITY_VALUE( 3, 1, 0, 1, 0 , 1 )
|
||||
, Conn_3G_2M1_1PinM3 = CONNEXITY_VALUE( 3, 2, 0, 1, 0 , 1 )
|
||||
, Conn_3G_3M1_1PinM3 = CONNEXITY_VALUE( 3, 3, 0, 1, 0 , 1 )
|
||||
};
|
||||
|
||||
#undef CONNEXITY_VALUE
|
||||
|
@ -375,7 +313,6 @@ namespace Anabatic {
|
|||
UConnexity _connexity;
|
||||
unsigned int _topology;
|
||||
Net* _net;
|
||||
NetData* _netData;
|
||||
GCell* _gcell;
|
||||
AutoContact* _sourceContact;
|
||||
AutoContact* _southWestContact;
|
||||
|
@ -389,13 +326,14 @@ namespace Anabatic {
|
|||
map<Component*,AutoSegment*> _routingPadAutoSegments;
|
||||
vector<AutoSegment*> _toFixSegments;
|
||||
unsigned int _degree;
|
||||
bool _isStrictChannel;
|
||||
uint64_t _sourceFlags;
|
||||
uint64_t _flags;
|
||||
bool _isTwoMetals;
|
||||
|
||||
// Sort classes.
|
||||
public:
|
||||
};
|
||||
|
||||
|
||||
inline bool NetBuilder::isStrictChannel () const { return _isStrictChannel; }
|
||||
inline bool NetBuilder::isTwoMetals () const { return _isTwoMetals; }
|
||||
inline AnabaticEngine* NetBuilder::getAnabatic () const { return _anabatic; }
|
||||
inline unsigned int NetBuilder::getDegree () const { return _degree; }
|
||||
inline NetBuilder::UConnexity NetBuilder::getConnexity () const { return _connexity; }
|
||||
|
@ -404,15 +342,12 @@ namespace Anabatic {
|
|||
inline unsigned int NetBuilder::getStateG () const { return _connexity.fields.globals; }
|
||||
inline GCell* NetBuilder::getGCell () const { return _gcell; }
|
||||
inline Net* NetBuilder::getNet () const { return _net; }
|
||||
inline NetData* NetBuilder::getNetData () const { return _netData; }
|
||||
inline AutoContact* NetBuilder::getSourceContact () const { return _sourceContact; }
|
||||
inline AutoContact* NetBuilder::getSouthWestContact () const { return _southWestContact; }
|
||||
inline AutoContact*& NetBuilder::getSouthWestContact () { return _southWestContact; }
|
||||
inline AutoContact* NetBuilder::getNorthEastContact () const { return _northEastContact; }
|
||||
inline AutoContact*& NetBuilder::getNorthEastContact () { return _northEastContact; }
|
||||
inline Hook* NetBuilder::getFromHook () const { return _fromHook; }
|
||||
inline uint64_t NetBuilder::getSourceFlags () const { return _sourceFlags; }
|
||||
inline uint64_t NetBuilder::getFlags () const { return _flags; }
|
||||
inline unsigned int NetBuilder::getTopology () const { return _topology; }
|
||||
inline vector<RoutingPad*>& NetBuilder::getRoutingPads () { return _routingPads; }
|
||||
inline map<Component*,AutoSegment*>& NetBuilder::getRpLookup () { return _routingPadAutoSegments; }
|
||||
|
@ -422,7 +357,6 @@ namespace Anabatic {
|
|||
inline Hook* NetBuilder::south ( size_t i ) const { return (i<_souths.size()) ? _souths[i] : NULL; }
|
||||
inline Hook* NetBuilder::east ( size_t i ) const { return (i<_easts .size()) ? _easts [i] : NULL; }
|
||||
inline Hook* NetBuilder::west ( size_t i ) const { return (i<_wests .size()) ? _wests [i] : NULL; }
|
||||
inline void NetBuilder::setFlags ( uint64_t flags ) { _flags |= flags; }
|
||||
inline void NetBuilder::setDegree ( unsigned int degree ) { _degree = degree; }
|
||||
inline void NetBuilder::setFromHook ( Hook* hook ) { _fromHook = hook; }
|
||||
inline void NetBuilder::setBothCornerContacts ( AutoContact* ac ) { _southWestContact = _northEastContact = ac; }
|
||||
|
@ -443,3 +377,5 @@ namespace Anabatic {
|
|||
void NetBuilder::load ( AnabaticEngine* engine, Net* net ) { BuilderT()._load(engine,net); }
|
||||
|
||||
}
|
||||
|
||||
#endif // ANABATIC_NET_BUILDER_H
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved
|
||||
// Copyright (c) UPMC 2008-2018, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -13,7 +13,9 @@
|
|||
// | C++ Header : "./anabatic/NetBuilderHV.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_NET_BUILDER_HV_H
|
||||
#define ANABATIC_NET_BUILDER_HV_H
|
||||
|
||||
#include "anabatic/NetBuilder.h"
|
||||
|
||||
|
||||
|
@ -23,16 +25,12 @@ namespace Anabatic {
|
|||
// -----------------------------------------------------------------
|
||||
// Class : "NetBuilderHV".
|
||||
|
||||
|
||||
class NetBuilderHV : public NetBuilder {
|
||||
public:
|
||||
NetBuilderHV ();
|
||||
virtual ~NetBuilderHV ();
|
||||
static std::string getStyle ();
|
||||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
|
||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
|
||||
AutoContact* doRp_AccessNorthSouthPin ( GCell*, RoutingPad* );
|
||||
AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* );
|
||||
private:
|
||||
virtual bool _do_1G_1M1 ();
|
||||
virtual bool _do_1G_xM1 ();
|
||||
|
@ -40,8 +38,6 @@ namespace Anabatic {
|
|||
virtual bool _do_2G ();
|
||||
virtual bool _do_2G_1M1 ();
|
||||
virtual bool _do_xG_1Pad ();
|
||||
virtual bool _do_1G_1PinM1 ();
|
||||
virtual bool _do_2G_1PinM1 ();
|
||||
virtual bool _do_1G_1PinM2 ();
|
||||
virtual bool _do_xG_1PinM2 ();
|
||||
virtual bool _do_1G_1PinM3 ();
|
||||
|
@ -53,18 +49,12 @@ namespace Anabatic {
|
|||
virtual bool _do_xG_xM2 ();
|
||||
virtual bool _do_1G_1M3 ();
|
||||
virtual bool _do_xG_xM3 ();
|
||||
bool _do_xG_xM3_baseRouting ();
|
||||
bool _do_xG_xM3_upperRouting ();
|
||||
virtual bool _do_1G_xM1_1PinM2 ();
|
||||
virtual bool _do_2G_xM1_1PinM2 ();
|
||||
virtual bool _do_1G_1M1_1PinM3 ();
|
||||
virtual bool _do_2G_xM1_1PinM3 ();
|
||||
virtual bool _do_3G_xM1_1PinM3 ();
|
||||
virtual bool _do_globalSegment ();
|
||||
virtual void singleGCell ( AnabaticEngine*, Net* );
|
||||
public:
|
||||
virtual string getTypeName () const;
|
||||
};
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
||||
#endif // ANABATIC_NET_BUILDER_HV_H
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | A n a b a t i c - Routing Toolbox |
|
||||
// | |
|
||||
// | Author : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Header : "./anabatic/NetBuilderHybridVH.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
#pragma once
|
||||
#include "anabatic/NetBuilder.h"
|
||||
|
||||
|
||||
namespace Anabatic {
|
||||
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// Class : "NetBuilderHybridVH".
|
||||
|
||||
class NetBuilderHybridVH : public NetBuilder {
|
||||
public:
|
||||
NetBuilderHybridVH ();
|
||||
virtual ~NetBuilderHybridVH ();
|
||||
static std::string getStyle ();
|
||||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
|
||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
|
||||
AutoContact* doRp_AccessEastWestPin ( GCell* , RoutingPad* );
|
||||
AutoContact* doRp_AccessNorthSouthPin ( GCell* , RoutingPad* );
|
||||
private:
|
||||
bool doRp_xG_1M1 ( RoutingPad* );
|
||||
bool doRp_1G_1PinM2 ( RoutingPad* );
|
||||
bool doRp_xG_xM1_xM3 ( const std::vector<RoutingPad*>& );
|
||||
virtual bool _do_1G_1M1 ();
|
||||
virtual bool _do_2G_1M1 ();
|
||||
virtual bool _do_xG_1M1 ();
|
||||
virtual bool _do_xG ();
|
||||
bool _do_xG_xM1 ();
|
||||
virtual bool _do_globalSegment ();
|
||||
// Should never occur, so just return false.
|
||||
// virtual bool _do_xG_1Pad ();
|
||||
// virtual bool _do_1G_1PinM2 ();
|
||||
virtual bool _do_1G_xM1 ();
|
||||
// virtual bool _do_xG_xM2 ();
|
||||
// virtual bool _do_1G_1M3 ();
|
||||
// virtual bool _do_xG_xM3 ();
|
||||
// virtual bool _do_xG_1M1_1M2 ();
|
||||
virtual bool _do_xG_xM1_xM3 ();
|
||||
virtual bool _do_1G_xM1_1PinM1 ();
|
||||
virtual bool _do_1G_xM1_1PinM2 ();
|
||||
// virtual bool _do_4G_1M2 ();
|
||||
virtual bool _do_2G ();
|
||||
virtual bool _do_2G_1PinM1 ();
|
||||
virtual bool _do_1G_1PinM1 ();
|
||||
virtual bool _do_1G_1PinM2 ();
|
||||
virtual bool _do_xG_1PinM2 ();
|
||||
virtual void singleGCell ( AnabaticEngine*, Net* );
|
||||
public:
|
||||
virtual string getTypeName () const;
|
||||
};
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
|
@ -1,7 +1,7 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved
|
||||
// Copyright (c) UPMC 2008-2018, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -13,7 +13,9 @@
|
|||
// | C++ Header : "./anabatic/NetBuilderM2.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_NET_BUILDER_M2_H
|
||||
#define ANABATIC_NET_BUILDER_M2_H
|
||||
|
||||
#include "anabatic/NetBuilder.h"
|
||||
|
||||
|
||||
|
@ -27,7 +29,6 @@ namespace Anabatic {
|
|||
public:
|
||||
NetBuilderM2 ();
|
||||
virtual ~NetBuilderM2 ();
|
||||
static std::string getStyle ();
|
||||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
|
||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
|
||||
private:
|
||||
|
@ -52,3 +53,5 @@ namespace Anabatic {
|
|||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
||||
#endif // ANABATIC_NET_BUILDER_M2_H
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2017-2022, All Rights Reserved
|
||||
// Copyright (c) UPMC 2017-2018, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -13,7 +13,9 @@
|
|||
// | C++ Header : "./anabatic/NetBuilderVH.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_NET_BUILDER_VH_H
|
||||
#define ANABATIC_NET_BUILDER_VH_H
|
||||
|
||||
#include "anabatic/NetBuilder.h"
|
||||
|
||||
|
||||
|
@ -27,7 +29,6 @@ namespace Anabatic {
|
|||
public:
|
||||
NetBuilderVH ();
|
||||
virtual ~NetBuilderVH ();
|
||||
static std::string getStyle ();
|
||||
virtual void doRp_AutoContacts ( GCell*, Component*, AutoContact*& source, AutoContact*& target, uint64_t flags );
|
||||
virtual AutoContact* doRp_Access ( GCell*, Component*, uint64_t flags );
|
||||
private:
|
||||
|
@ -40,7 +41,6 @@ namespace Anabatic {
|
|||
virtual bool _do_2G_1M1 ();
|
||||
virtual bool _do_xG_xM1_xM3 ();
|
||||
virtual bool _do_xG ();
|
||||
virtual bool _do_2G ();
|
||||
virtual bool _do_globalSegment ();
|
||||
virtual void singleGCell ( AnabaticEngine*, Net* );
|
||||
public:
|
||||
|
@ -49,3 +49,5 @@ namespace Anabatic {
|
|||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
||||
#endif // ANABATIC_NET_BUILDER_VH_H
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) Sorbonne Université 2022-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | A n a b a t i c - Global Routing Toolbox |
|
||||
// | |
|
||||
// | Author : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ Header : "./hurricane/isobar/PyStyleFlags.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#include "hurricane/isobar/PyHurricane.h"
|
||||
#include "anabatic/Constants.h"
|
||||
|
||||
|
||||
namespace Anabatic {
|
||||
|
||||
extern "C" {
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Python Object : "PyStyleFlags".
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
StyleFlags* _object;
|
||||
} PyStyleFlags;
|
||||
|
||||
|
||||
extern PyTypeObject PyTypeStyleFlags;
|
||||
extern PyMethodDef PyStyleFlags_Methods[];
|
||||
|
||||
extern PyObject* PyStyleFlags_Link ( StyleFlags* );
|
||||
extern void PyStyleFlags_LinkPyType ();
|
||||
extern void PyStyleFlags_postModuleInit ();
|
||||
|
||||
#define IsPyStyleFlags(v) ( (v)->ob_type == &PyTypeStyleFlags )
|
||||
#define PYSTYLEFLAGS(v) ( (PyStyleFlags*)(v) )
|
||||
#define PYSTYLEFLAGS_O(v) ( PYSTYLEFLAGS(v)->_object )
|
||||
|
||||
} // extern "C".
|
||||
|
||||
|
||||
extern Anabatic::StyleFlags PyInt_AsStyleFlags ( PyObject* );
|
||||
|
||||
|
||||
} // Anabatic namespace.
|
|
@ -14,7 +14,9 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#pragma once
|
||||
#ifndef ANABATIC_SESSION_H
|
||||
#define ANABATIC_SESSION_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
@ -22,7 +24,6 @@
|
|||
#include <boost/function.hpp>
|
||||
#include "hurricane/Commons.h"
|
||||
#include "hurricane/Box.h"
|
||||
#include "hurricane/DBo.h"
|
||||
#include "crlcore/CellGauge.h"
|
||||
#include "crlcore/RoutingGauge.h"
|
||||
#include "anabatic/Constants.h"
|
||||
|
@ -54,7 +55,6 @@ namespace Anabatic {
|
|||
using Hurricane::DbU;
|
||||
using Hurricane::Point;
|
||||
using Hurricane::Box;
|
||||
using Hurricane::DBo;
|
||||
using Hurricane::Net;
|
||||
using Hurricane::Contact;
|
||||
using Hurricane::Segment;
|
||||
|
@ -76,12 +76,10 @@ namespace Anabatic {
|
|||
static inline bool doDestroyBaseSegment ();
|
||||
static inline bool doDestroyTool ();
|
||||
static bool isInDemoMode ();
|
||||
static bool isChannelStyle ();
|
||||
static bool doWarnGCellOverload ();
|
||||
static Session* get ( const char* message=NULL );
|
||||
static inline Technology* getTechnology ();
|
||||
static inline AnabaticEngine* getAnabatic ();
|
||||
static StyleFlags getRoutingStyle ();
|
||||
static inline const Configuration* getConfiguration ();
|
||||
static float getSaturateRatio ();
|
||||
static size_t getSaturateRp ();
|
||||
|
@ -97,13 +95,11 @@ namespace Anabatic {
|
|||
static inline size_t getDVerticalDepth ();
|
||||
static inline const Layer* getDVerticalLayer ();
|
||||
static inline DbU::Unit getDVerticalWidth ();
|
||||
static inline DbU::Unit getDPVerticalWidth ();
|
||||
static inline DbU::Unit getDVerticalPitch ();
|
||||
static inline DbU::Unit getDVerticalOffset ();
|
||||
static inline size_t getDHorizontalDepth ();
|
||||
static inline const Layer* getDHorizontalLayer ();
|
||||
static inline DbU::Unit getDHorizontalWidth ();
|
||||
static inline DbU::Unit getDPHorizontalWidth ();
|
||||
static inline DbU::Unit getDHorizontalPitch ();
|
||||
static inline DbU::Unit getDHorizontalOffset ();
|
||||
static inline size_t getDContactDepth ();
|
||||
|
@ -111,24 +107,16 @@ namespace Anabatic {
|
|||
static inline DbU::Unit getDContactWidth ();
|
||||
static inline DbU::Unit getDContactPitch ();
|
||||
static inline RoutingGauge* getRoutingGauge ();
|
||||
static inline bool isGLayer ( const Layer* );
|
||||
static inline bool isGMetal ( const Layer* );
|
||||
static inline bool isGContact ( const Layer* );
|
||||
static inline bool isGaugeLayer ( const Layer* );
|
||||
static inline RoutingLayerGauge* getLayerGauge ( const Layer* );
|
||||
static inline RoutingLayerGauge* getLayerGauge ( size_t depth );
|
||||
static inline size_t getDepth ();
|
||||
static inline size_t getViaDepth ( const Layer* layer );
|
||||
static inline size_t getLayerDepth ( const Layer* layer );
|
||||
static inline const Layer* getRoutingLayer ( size_t );
|
||||
static inline const Layer* getContactLayer ( size_t );
|
||||
static inline const Layer* getBuildRoutingLayer ( size_t );
|
||||
static inline const Layer* getBuildContactLayer ( size_t );
|
||||
static Flags getDirection ( size_t depth );
|
||||
static inline DbU::Unit getPitch ( size_t depth, Flags flags );
|
||||
static inline DbU::Unit getOffset ( size_t depth );
|
||||
static inline DbU::Unit getWireWidth ( size_t depth );
|
||||
static inline DbU::Unit getPWireWidth ( size_t depth );
|
||||
static inline DbU::Unit getViaWidth ( size_t depth );
|
||||
static inline Flags getDirection ( const Layer* );
|
||||
static inline DbU::Unit getPitch ( const Layer*, Flags flags );
|
||||
|
@ -136,7 +124,6 @@ namespace Anabatic {
|
|||
static inline DbU::Unit getWireWidth ( const Layer* );
|
||||
static inline DbU::Unit getViaWidth ( const Layer* );
|
||||
static inline DbU::Unit getExtensionCap ( const Layer* );
|
||||
static inline DbU::Unit getNearestTrackAxis ( const Layer*, DbU::Unit, uint32_t mode );
|
||||
static inline Point getNearestGridPoint ( Point, Box constraints );
|
||||
static inline size_t getSegmentStackSize ();
|
||||
static inline size_t getContactStackSize ();
|
||||
|
@ -144,7 +131,7 @@ namespace Anabatic {
|
|||
static inline const vector<AutoSegment*>& getRevalidateds ();
|
||||
static inline const set<AutoSegment*>& getDestroyeds ();
|
||||
static inline const vector<AutoSegment*>& getDoglegs ();
|
||||
static inline const set<Net*,DBo::CompareById>& getNetsModificateds ();
|
||||
static inline const set<Net*>& getNetsModificateds ();
|
||||
static void close ();
|
||||
static void setAnabaticFlags ( Flags );
|
||||
static inline void dogleg ( AutoSegment* );
|
||||
|
@ -178,7 +165,6 @@ namespace Anabatic {
|
|||
void _revalidateTopology ();
|
||||
virtual size_t _revalidate ();
|
||||
DbU::Unit _getPitch ( size_t depth, Flags flags ) const;
|
||||
DbU::Unit _getNearestTrackAxis ( const Layer*, DbU::Unit, uint32_t mode );
|
||||
Point _getNearestGridPoint ( Point, Box constraints );
|
||||
Record* _getRecord () const;
|
||||
string _getString () const;
|
||||
|
@ -194,8 +180,8 @@ namespace Anabatic {
|
|||
vector<AutoSegment*> _doglegs;
|
||||
vector<AutoSegment*> _segmentInvalidateds;
|
||||
vector<AutoSegment*> _segmentRevalidateds;
|
||||
set<Net*,DBo::CompareById> _netInvalidateds;
|
||||
set<Net*,DBo::CompareById> _netRevalidateds;
|
||||
set<Net*> _netInvalidateds;
|
||||
set<Net*> _netRevalidateds;
|
||||
set<AutoSegment*> _destroyedSegments;
|
||||
|
||||
// Constructors.
|
||||
|
@ -228,7 +214,7 @@ namespace Anabatic {
|
|||
inline const vector<AutoSegment*>& Session::getRevalidateds () { return get("getRevalidateds()")->_segmentRevalidateds; }
|
||||
inline const set<AutoSegment*>& Session::getDestroyeds () { return get("getDestroyeds()")->_destroyedSegments; }
|
||||
inline const vector<AutoSegment*>& Session::getDoglegs () { return get("getDoglegs()")->_doglegs; }
|
||||
inline const set<Net*,DBo::CompareById>& Session::getNetsModificateds () { return get("getNetsModificateds()")->_netRevalidateds; }
|
||||
inline const set<Net*>& Session::getNetsModificateds () { return get("getNetsModificateds()")->_netRevalidateds; }
|
||||
inline void Session::doglegReset () { return get("doglegReset()")->_doglegReset (); }
|
||||
inline void Session::invalidate ( Net* net ) { return get("invalidate(Net*)")->_invalidate(net); }
|
||||
inline void Session::invalidate ( AutoContact* autoContact ) { return get("invalidate(AutoContact*)")->_invalidate(autoContact); }
|
||||
|
@ -247,36 +233,26 @@ namespace Anabatic {
|
|||
inline size_t Session::getDVerticalDepth () { return getConfiguration()->getDVerticalDepth(); }
|
||||
inline const Layer* Session::getDVerticalLayer () { return getConfiguration()->getDVerticalLayer(); }
|
||||
inline DbU::Unit Session::getDVerticalWidth () { return getConfiguration()->getDVerticalWidth(); }
|
||||
inline DbU::Unit Session::getDPVerticalWidth () { return getConfiguration()->getDPVerticalWidth(); }
|
||||
inline DbU::Unit Session::getDVerticalPitch () { return getConfiguration()->getDVerticalPitch(); }
|
||||
inline DbU::Unit Session::getDVerticalOffset () { return getConfiguration()->getDVerticalOffset(); }
|
||||
inline size_t Session::getDHorizontalDepth () { return getConfiguration()->getDHorizontalDepth(); }
|
||||
inline const Layer* Session::getDHorizontalLayer () { return getConfiguration()->getDHorizontalLayer(); }
|
||||
inline DbU::Unit Session::getDHorizontalWidth () { return getConfiguration()->getDHorizontalWidth(); }
|
||||
inline DbU::Unit Session::getDPHorizontalWidth () { return getConfiguration()->getDPHorizontalWidth(); }
|
||||
inline DbU::Unit Session::getDHorizontalPitch () { return getConfiguration()->getDHorizontalPitch(); }
|
||||
inline DbU::Unit Session::getDHorizontalOffset () { return getConfiguration()->getDHorizontalOffset(); }
|
||||
inline size_t Session::getDContactDepth () { return getConfiguration()->getDContactDepth(); }
|
||||
inline const Layer* Session::getDContactLayer () { return getConfiguration()->getDContactLayer(); }
|
||||
inline DbU::Unit Session::getDContactWidth () { return getConfiguration()->getDContactWidth(); }
|
||||
inline DbU::Unit Session::getDContactPitch () { return getConfiguration()->getDContactPitch(); }
|
||||
inline bool Session::isGLayer ( const Layer* layer ) { return getConfiguration()->isGLayer(layer); }
|
||||
inline bool Session::isGMetal ( const Layer* layer ) { return getConfiguration()->isGMetal(layer); }
|
||||
inline bool Session::isGContact ( const Layer* layer ) { return getConfiguration()->isGContact(layer); }
|
||||
inline bool Session::isGaugeLayer ( const Layer* layer ) { return getRoutingGauge()->hasLayer(layer); }
|
||||
inline RoutingLayerGauge* Session::getLayerGauge ( const Layer* layer ) { return getRoutingGauge()->getLayerGauge(layer); }
|
||||
inline RoutingLayerGauge* Session::getLayerGauge ( size_t depth ) { return getRoutingGauge()->getLayerGauge(depth); }
|
||||
inline size_t Session::getDepth () { return getRoutingGauge()->getDepth(); }
|
||||
inline size_t Session::getViaDepth ( const Layer* layer ) { return getRoutingGauge()->getViaDepth(layer); }
|
||||
inline size_t Session::getLayerDepth ( const Layer* layer ) { return getRoutingGauge()->getLayerDepth(layer); }
|
||||
inline const Layer* Session::getRoutingLayer ( size_t depth ) { return getRoutingGauge()->getRoutingLayer(depth); }
|
||||
inline const Layer* Session::getContactLayer ( size_t depth ) { return getRoutingGauge()->getContactLayer(depth); }
|
||||
inline const Layer* Session::getBuildRoutingLayer ( size_t depth ) { return getRoutingGauge()->getRoutingLayer(depth+getRoutingGauge()->getFirstRoutingLayer()); }
|
||||
inline const Layer* Session::getBuildContactLayer ( size_t depth ) { return getRoutingGauge()->getContactLayer(depth+getRoutingGauge()->getFirstRoutingLayer()); }
|
||||
inline DbU::Unit Session::getPitch ( size_t depth, Flags flags=Flags::NoFlags ) { return get("getPitch(depth,flags)")->_getPitch( depth, flags ); }
|
||||
inline DbU::Unit Session::getOffset ( size_t depth ) { return getRoutingGauge()->getLayerOffset(depth); }
|
||||
inline DbU::Unit Session::getWireWidth ( size_t depth ) { return getRoutingGauge()->getLayerWireWidth(depth); }
|
||||
inline DbU::Unit Session::getPWireWidth ( size_t depth ) { return getRoutingGauge()->getLayerPWireWidth(depth); }
|
||||
inline DbU::Unit Session::getViaWidth ( size_t depth ) { return getRoutingGauge()->getViaWidth(depth); }
|
||||
inline DbU::Unit Session::getPitch ( const Layer* layer, Flags flags=Flags::NoFlags ) { return getPitch( getLayerDepth(layer), flags ); }
|
||||
inline DbU::Unit Session::getOffset ( const Layer* layer ) { return getOffset ( getLayerDepth(layer) ); }
|
||||
|
@ -285,7 +261,6 @@ namespace Anabatic {
|
|||
inline DbU::Unit Session::getExtensionCap ( const Layer* layer ) { return getConfiguration()->getExtensionCap(layer); }
|
||||
inline Flags Session::getDirection ( const Layer* layer ) { return getDirection( getLayerDepth(layer) ); }
|
||||
inline Point Session::getNearestGridPoint ( Point p, Box b ) { return get("getNearestGridPoint()")->_getNearestGridPoint(p,b); }
|
||||
inline DbU::Unit Session::getNearestTrackAxis ( const Layer* layer, DbU::Unit axis, uint32_t mode ) { return get("getNearestTrackAxis()")->_getNearestTrackAxis(layer,axis,mode); }
|
||||
|
||||
inline void Session::_dogleg ( AutoSegment* segment ) { _doglegs.push_back(segment); }
|
||||
inline void Session::_doglegReset () { _doglegs.clear(); }
|
||||
|
@ -299,3 +274,6 @@ namespace Anabatic {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::Session);
|
||||
|
||||
|
||||
#endif // ANABATIC_SESSION_H
|
||||
|
|
|
@ -3,15 +3,14 @@
|
|||
set(CMAKE_LEGACY_CYGWIN_WIN32 0)
|
||||
project(Bootstrap)
|
||||
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
cmake_minimum_required(VERSION 2.4.0)
|
||||
|
||||
set(ignoreVariables USE_LIBBFD "${BUILD_DOC} ${CMAKE_INSTALL_DIR}")
|
||||
set(ignoreVariables "${BUILD_DOC}")
|
||||
|
||||
add_subdirectory(cmake_modules)
|
||||
|
||||
list(INSERT CMAKE_MODULE_PATH 0 "${Bootstrap_SOURCE_DIR}/cmake_modules/")
|
||||
find_package(Bootstrap REQUIRED)
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development.Module )
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
print_cmake_module_path()
|
||||
|
||||
|
@ -24,7 +23,7 @@
|
|||
OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
|
||||
|
||||
install(DIRECTORY builder
|
||||
DESTINATION ${Python_CORIOLISLIB} )
|
||||
DESTINATION ${PYTHON_SITE_PACKAGES} )
|
||||
|
||||
install(FILES ccb.py
|
||||
DESTINATION bin
|
||||
|
@ -32,10 +31,3 @@
|
|||
PERMISSIONS OWNER_WRITE
|
||||
OWNER_READ GROUP_READ WORLD_READ
|
||||
OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
|
||||
|
||||
install(FILES crlenv.py
|
||||
DESTINATION bin
|
||||
RENAME crlenv
|
||||
PERMISSIONS OWNER_WRITE
|
||||
OWNER_READ GROUP_READ WORLD_READ
|
||||
OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
#. /etc/*-release
|
||||
#arch="Linux.el9"
|
||||
#if [ "`echo ${VERSION} | cut -c 1`" == "7" ]; then
|
||||
# echo "Building for RHEL 7"
|
||||
# arch="Linux.el7_64"
|
||||
#fi
|
||||
|
||||
arch="Linux.el9"
|
||||
if [ "`hostname -s`" == "bop" ]; then
|
||||
echo "Building for RHEL 7"
|
||||
arch="Linux.el7_64"
|
||||
fi
|
||||
|
||||
nightly=""
|
||||
if [[ "`pwd`" =~ /nightly/ ]]; then
|
||||
nightly="/nightly"
|
||||
fi
|
||||
|
||||
srcDir=${HOME}${nightly}/coriolis-2.x/src/alliance/alliance/src
|
||||
commonRoot=${HOME}${nightly}/coriolis-2.x/${arch}/Release.Shared
|
||||
#commonRoot=${HOME}${nightly}/coriolis-2.x/${arch}/Debug.Shared
|
||||
buildDir=${commonRoot}/build
|
||||
installDir=${commonRoot}/install
|
||||
|
||||
export ALLIANCE_TOP=${installDir}
|
||||
export LD_LIBRARY_PATH=${installDir}/lib:${LD_LIBRARY_PATH}
|
||||
|
||||
cd ${srcDir}
|
||||
# Skip doc generation to avoid pulling TeXLive in docker images.
|
||||
sed -i 's,dirs="\$newdirs documentation",dirs="$newdirs",' ./autostuff
|
||||
./autostuff clean
|
||||
./autostuff
|
||||
mkdir -p ${buildDir}
|
||||
cd ${buildDir}
|
||||
${srcDir}/configure --prefix=${ALLIANCE_TOP} --enable-alc-shared
|
||||
make -j1 install
|
|
@ -14,19 +14,19 @@ projects = [
|
|||
, { 'name' : "coriolis"
|
||||
, 'tools' : [ "bootstrap"
|
||||
, "lefdef"
|
||||
, "coloquinte"
|
||||
, "flute"
|
||||
, "vlsisapd"
|
||||
, "hurricane"
|
||||
, "crlcore"
|
||||
, "flute"
|
||||
, "etesian"
|
||||
, "anabatic"
|
||||
, "katana"
|
||||
#, "knik"
|
||||
#, "katabatic"
|
||||
#, "kite"
|
||||
#, "equinox"
|
||||
#, "solstice"
|
||||
, "tramontana"
|
||||
, "knik"
|
||||
, "katabatic"
|
||||
, "kite"
|
||||
, "coloquinte"
|
||||
, "etesian"
|
||||
, "equinox"
|
||||
, "solstice"
|
||||
, "oroshi"
|
||||
, "bora"
|
||||
, "karakaze"
|
||||
|
|
|
@ -2,23 +2,30 @@
|
|||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
|
||||
# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | T o o l c h a i n B u i l d e r |
|
||||
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||
# | |
|
||||
# | Author : Jean-Paul Chaput |
|
||||
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./builder/AboutWidget.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
from PyQt4.QtCore import Qt
|
||||
from PyQt4.QtGui import QPalette, QColor, QFont, QWidget, \
|
||||
QFrame, QLabel, QVBoxLayout, QAction, \
|
||||
QKeySequence, QApplication
|
||||
from PyQt4.QtGui import QPalette
|
||||
from PyQt4.QtGui import QColor
|
||||
from PyQt4.QtGui import QFont
|
||||
from PyQt4.QtGui import QWidget
|
||||
from PyQt4.QtGui import QFrame
|
||||
from PyQt4.QtGui import QLabel
|
||||
from PyQt4.QtGui import QVBoxLayout
|
||||
from PyQt4.QtGui import QAction
|
||||
from PyQt4.QtGui import QKeySequence
|
||||
from PyQt4.QtGui import QApplication
|
||||
|
||||
|
||||
class AboutWidget ( QWidget ):
|
||||
|
@ -42,11 +49,12 @@ class AboutWidget ( QWidget ):
|
|||
font.setWeight ( QFont.Bold )
|
||||
title.setFont( font )
|
||||
|
||||
subTitle = QLabel( 'Coriolis Toolchain Builder for the Dummies' )
|
||||
subTitle = QLabel( 'Coriolis & Chams Builder for the Dummies' )
|
||||
subTitle.setAlignment( Qt.AlignCenter )
|
||||
subTitle.setFont( QFont('Courier',10,QFont.Bold) )
|
||||
authors = QLabel( 'Coriolis CAD System 3.0 . . . . . . . . ccb 1.0\n'
|
||||
'Copyright (c) 2008-2021 . . Sorbonne Universite\n'
|
||||
|
||||
authors = QLabel( 'Coriolis CAD System 1.0 . . . . . . . . ccb 1.0\n'
|
||||
'Copyright (c) 2008-2016 . . . . . . . . . . UPMC\n'
|
||||
'Authors . . . . . . . . . . . . . Damien Dupuis\n'
|
||||
' . . . . . . . . . . . . Jean-Paul Chaput\n'
|
||||
'E-Mail . . . . . . . . Jean-Paul.Chaput@lip6.fr'
|
||||
|
@ -73,6 +81,7 @@ class AboutWidget ( QWidget ):
|
|||
|
||||
vLayout = QVBoxLayout()
|
||||
vLayout.addWidget( frame )
|
||||
|
||||
self.setLayout( vLayout )
|
||||
|
||||
self._exitAction = QAction( '&Exit', self )
|
||||
|
@ -86,4 +95,5 @@ class AboutWidget ( QWidget ):
|
|||
self._closeAction.setShortcut ( QKeySequence('CTRL+A') )
|
||||
self._closeAction.triggered.connect( self.close )
|
||||
self.addAction( self._closeAction )
|
||||
|
||||
return
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2008-2021, All Rights Reserved
|
||||
# Copyright (c) UPMC/LIP6 2008-2018, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | T o o l c h a i n B u i l d e r |
|
||||
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||
# | |
|
||||
# | Author : Jean-Paul Chaput |
|
||||
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./builder/Builder.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
@ -21,8 +21,8 @@ import os.path
|
|||
import datetime
|
||||
import subprocess
|
||||
from . import ErrorMessage
|
||||
from .Project import Project
|
||||
from .Configuration import Configuration
|
||||
from Project import Project
|
||||
from Configuration import Configuration
|
||||
|
||||
|
||||
class Builder:
|
||||
|
@ -35,13 +35,10 @@ class Builder:
|
|||
self._noCache = False
|
||||
self._ninja = False
|
||||
self._clang = False
|
||||
self._manylinux = False
|
||||
self._noSystemBoost = False
|
||||
self._macports = False
|
||||
self._devtoolset = 0
|
||||
self._llvmtoolset = 0
|
||||
self._bfd = "OFF"
|
||||
self._qt4 = False
|
||||
self._qt5 = False
|
||||
self._openmp = False
|
||||
self._enableShared = "ON"
|
||||
self._enableDoc = "OFF"
|
||||
|
@ -52,28 +49,27 @@ class Builder:
|
|||
self._environment = os.environ
|
||||
return
|
||||
|
||||
|
||||
def __setattr__ ( self, attribute, value ):
|
||||
if attribute[0] == "_":
|
||||
self.__dict__[attribute] = value
|
||||
return
|
||||
|
||||
if attribute in self._conf.getAllIds(): setattr( self._conf, attribute, value )
|
||||
|
||||
if attribute == "quiet": self._quiet = value
|
||||
elif attribute == "rmBuild": self._rmBuild = value
|
||||
elif attribute == "doBuild": self._doBuild = value
|
||||
elif attribute == "noCache": self._noCache = value
|
||||
elif attribute == "ninja": self._ninja = value
|
||||
elif attribute == "clang": self._clang = value
|
||||
elif attribute == "manylinux": self._manylinux = value
|
||||
elif attribute == "macports":
|
||||
self._macports = value
|
||||
if value: self._noSystemBoost = True
|
||||
elif attribute == "devtoolset":
|
||||
self._devtoolset = value
|
||||
if value: self._noSystemBoost = True
|
||||
elif attribute == "llvmtoolset":
|
||||
self._llvmtoolset = value
|
||||
elif attribute == "bfd": self._bfd = value
|
||||
elif attribute == "qt4": self._qt4 = value
|
||||
elif attribute == "qt5": self._qt5 = value
|
||||
elif attribute == "openmp": self._openmp = value
|
||||
elif attribute == "enableDoc": self._enableDoc = value
|
||||
elif attribute == "enableShared": self._enableShared = value
|
||||
|
@ -83,15 +79,18 @@ class Builder:
|
|||
elif attribute == "makeArguments": self._makeArguments = value.split ()
|
||||
return
|
||||
|
||||
|
||||
def __getattr__ ( self, attribute ):
|
||||
if attribute[0] != "_":
|
||||
if attribute == 'conf': return self._conf
|
||||
if attribute in self._conf.getAllIds():
|
||||
return getattr( self._conf, attribute )
|
||||
if not attribute in self.__dict__:
|
||||
|
||||
if not self.__dict__.has_key(attribute):
|
||||
raise ErrorMessage( 1, 'Builder has no attribute <%s>.'%attribute )
|
||||
return self.__dict__[attribute]
|
||||
|
||||
|
||||
def _guessGitHash ( self, project ):
|
||||
self.gitHash = 'x'
|
||||
os.chdir ( self.sourceDir+'/'+project.getName() )
|
||||
|
@ -99,48 +98,51 @@ class Builder:
|
|||
self.gitHash = subprocess.Popen ( command, stdout=subprocess.PIPE ).stdout.readlines()[0]
|
||||
return
|
||||
|
||||
|
||||
def _configure ( self, fileIn, fileOut ):
|
||||
fdFileIn = open ( fileIn , "r" )
|
||||
fdFileOut = open ( fileOut, "w" )
|
||||
|
||||
for line in fdFileIn.readlines():
|
||||
stable = False
|
||||
substituted0 = line
|
||||
|
||||
while not stable:
|
||||
substituted1 = re.sub ( r"@revdate@" , self.revDate, substituted0 )
|
||||
substituted1 = re.sub ( r"@githash@" , self.gitHash, substituted1 )
|
||||
substituted1 = re.sub ( r"@coriolisTop@", "/usr" , substituted1 )
|
||||
if substituted0 == substituted1: stable = True
|
||||
else: substituted0 = substituted1
|
||||
|
||||
fdFileOut.write ( substituted0 )
|
||||
|
||||
fdFileIn.close ()
|
||||
fdFileOut.close ()
|
||||
return
|
||||
|
||||
|
||||
def _doSpec ( self ):
|
||||
self._configure ( self.specFileIn, self.specFile )
|
||||
return
|
||||
|
||||
|
||||
def _doDebChangelog ( self ):
|
||||
self._configure ( self.debChangelogIn, self.debChangelog )
|
||||
return
|
||||
|
||||
|
||||
def _execute ( self, command, error ):
|
||||
collections = []
|
||||
if self._devtoolset:
|
||||
collections.append( 'devtoolset-{}'.format(self._devtoolset) )
|
||||
print( 'Using devtoolset-{0} (scl enable devtoolset-{0} ...)'.format(self._devtoolset) )
|
||||
if self._llvmtoolset:
|
||||
collections.append( 'llvm-toolset-{}'.format(self._llvmtoolset) )
|
||||
print( 'Using llvm-toolset-{0} (scl enable llvm-toolset-{v} ...)'.format(self._llvmtoolset) )
|
||||
if collections:
|
||||
print 'Using devtoolset-%(v)d (scl enable devtoolset-%(v)d ...)' % {'v':self._devtoolset}
|
||||
commandAsString = ''
|
||||
for i in range(len(command)):
|
||||
if i: commandAsString += ' '
|
||||
if ' ' in command[i]: commandAsString += '"'+command[i]+'"'
|
||||
else: commandAsString += command[i]
|
||||
command = [ 'scl', 'enable' ]
|
||||
command += collections
|
||||
command.append( commandAsString )
|
||||
command = [ 'scl', 'enable', 'devtoolset-%d' % self._devtoolset
|
||||
, commandAsString ]
|
||||
|
||||
#print command
|
||||
sys.stdout.flush ()
|
||||
sys.stderr.flush ()
|
||||
child = subprocess.Popen ( command, env=self._environment, stdout=None )
|
||||
|
@ -150,49 +152,49 @@ class Builder:
|
|||
ErrorMessage( status, "%s (status:%d)."%(error,status) ).terminate()
|
||||
return
|
||||
|
||||
|
||||
def _enableTool ( self, tool ):
|
||||
return
|
||||
|
||||
|
||||
def _build ( self, tool ):
|
||||
toolSourceDir = os.path.join ( self.sourceDir, tool.getToolDir() )
|
||||
toolBuildDir = os.path.join ( self.buildDir , tool.name )
|
||||
cmakeInstallDir = os.path.join ( self.installDir, "share", "cmake", "Modules" )
|
||||
# Supplied directly in the CMakeLists.txt.
|
||||
#cmakeModules = os.path.join ( self.installDir, "share", "cmake", "Modules" )
|
||||
|
||||
if not os.path.isdir(toolSourceDir):
|
||||
print( ErrorMessage( 0, 'Missing tool source directory: "{}" (skipped).' \
|
||||
.format(toolSourceDir) ))
|
||||
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir )
|
||||
return
|
||||
|
||||
if self._rmBuild:
|
||||
print( 'Removing tool build directory: "{}".'.format(toolBuildDir) )
|
||||
print "Removing tool build directory: \"%s\"." % toolBuildDir
|
||||
command = [ "/bin/rm", "-rf", toolBuildDir ]
|
||||
self._execute ( command, "Removing tool build directory" )
|
||||
|
||||
command = [ 'cmake' ]
|
||||
if self.libSuffix: command += [ "-D", "LIB_SUFFIX:STRING=%s" % self.libSuffix ]
|
||||
if self._ninja: command += [ "-G", "Ninja" ]
|
||||
if self._macports: command += [ "-D", "WITH_MACPORTS:STRING=TRUE" ]
|
||||
if self._noSystemBoost: command += [ "-D", "Boost_NO_SYSTEM_PATHS:STRING=TRUE"
|
||||
#, "-D", "BOOST_INCLUDEDIR:STRING=/usr/include/boost169"
|
||||
#, "-D", "BOOST_LIBRARYDIR:STRING=/usr/lib64/boost169"
|
||||
, "-D", "BOOST_INCLUDEDIR:STRING=/usr/include/boost157"
|
||||
, "-D", "BOOST_LIBRARYDIR:STRING=/usr/lib/boost157"
|
||||
]
|
||||
if self._bfd: command += [ "-D", "USE_LIBBFD:STRING=%s" % self._bfd ]
|
||||
if self._qt4: command += [ "-D", "WITH_QT4:STRING=TRUE" ]
|
||||
if self._qt5: command += [ "-D", "WITH_QT5:STRING=TRUE" ]
|
||||
if self._openmp: command += [ "-D", "WITH_OPENMP:STRING=TRUE" ]
|
||||
if self._manylinux: command += [ "-D", "USE_MANYLINUX:STRING=TRUE" ]
|
||||
|
||||
command += [ "-D", "CMAKE_BUILD_TYPE:STRING=%s" % self.buildMode
|
||||
#, "-D", "BUILD_SHARED_LIBS:STRING=%s" % self.enableShared
|
||||
, "-D", "CMAKE_INSTALL_PREFIX:STRING=%s" % self.installDir
|
||||
, "-D", "CMAKE_INSTALL_DIR:STRING=%s" % cmakeInstallDir
|
||||
#, "-D", "CMAKE_MODULE_PATH:STRING=%s" % cmakeModules
|
||||
#, "-D", "Boost_DEBUG:STRING=TRUE"
|
||||
, toolSourceDir ]
|
||||
|
||||
if not os.path.isdir(toolBuildDir):
|
||||
print( 'Creating tool build directory: "{}".'.format(toolBuildDir) )
|
||||
print "Creating tool build directory: \"%s\"." % toolBuildDir
|
||||
os.makedirs ( toolBuildDir )
|
||||
os.chdir ( toolBuildDir )
|
||||
self._execute ( command, "First CMake failed" )
|
||||
|
||||
os.chdir ( toolBuildDir )
|
||||
if self._noCache:
|
||||
cmakeCache = os.path.join(toolBuildDir,"CMakeCache.txt")
|
||||
|
@ -208,20 +210,25 @@ class Builder:
|
|||
if self._checkDeterminism == 'ON': command += [ "-D", "CHECK_DETERMINISM:STRING=ON" ]
|
||||
command += [ toolSourceDir ]
|
||||
|
||||
print self._noSystemBoost
|
||||
print command
|
||||
self._execute ( command, "Second CMake failed" )
|
||||
|
||||
if self._doBuild:
|
||||
command = [ "make" ]
|
||||
if self._ninja:
|
||||
command = [ "ninja-build" ]
|
||||
#command += [ "DESTDIR=%s" % self.installDir ]
|
||||
command += self._makeArguments
|
||||
print( "Make/Ninja command:", command )
|
||||
print "Make/Ninja command:", command
|
||||
sys.stdout.flush ()
|
||||
self._execute ( command, "Build failed" )
|
||||
return
|
||||
|
||||
|
||||
def gitArchive ( self, projectName ):
|
||||
rawArchive = self.tarballDir+'/'+projectName+'.tar'
|
||||
|
||||
os.chdir ( self.sourceDir+'/'+projectName )
|
||||
command = [ 'git'
|
||||
, 'archive'
|
||||
|
@ -230,10 +237,11 @@ class Builder:
|
|||
, 'devel'
|
||||
]
|
||||
self._execute ( command, "git archive of project %s" % projectName )
|
||||
|
||||
if not os.path.isdir ( self.archiveDir ):
|
||||
os.mkdir ( self.archiveDir )
|
||||
os.chdir ( self.archiveDir )
|
||||
|
||||
os.chdir ( self.archiveDir )
|
||||
command = [ 'tar', 'xf', rawArchive ]
|
||||
self._execute ( command, "unpacking raw archive %s" % rawArchive )
|
||||
|
||||
|
@ -263,101 +271,123 @@ class Builder:
|
|||
# , "--no-backup-if-mismatch"
|
||||
# , "-p0", "-i", self.distribPatch ]
|
||||
# self._execute ( command, "patch for distribution command failed" )
|
||||
|
||||
absSourceTarBz2 = '%s/%s' % (self.tarballDir,self.sourceTarBz2)
|
||||
os.chdir ( self.tarballDir )
|
||||
command = [ 'tar', 'jcf', absSourceTarBz2, os.path.basename(self.archiveDir) ]
|
||||
self._execute ( command, "Creating composite archive %s" % absSourceTarBz2 )
|
||||
|
||||
return
|
||||
|
||||
|
||||
def _setEnvironment ( self, systemVariable, userVariable ):
|
||||
if not systemVariable in self._environment or self._environment[systemVariable] == "":
|
||||
if not userVariable in self._environment or self._environment[userVariable] == "" :
|
||||
if not self._environment.has_key(systemVariable) or self._environment[systemVariable] == "":
|
||||
if not self._environment.has_key(userVariable) or self._environment[userVariable] == "" :
|
||||
self._environment[ systemVariable ] = self.installDir
|
||||
print( '[WARNING] Neither "{0}" nor "{1}" environment variables are sets.' \
|
||||
.format(systemVariable,userVariable) )
|
||||
print( ' Setting "{0}" to "{1}".'.format(systemVariable,self.installDir) )
|
||||
print "[WARNING] Neither <%s> nor <%s> environment variables are sets." \
|
||||
% (systemVariable,userVariable)
|
||||
print " Setting <%s> to <%s>." % (systemVariable,self.installDir)
|
||||
else:
|
||||
self._environment[ systemVariable ] = self._environment[ userVariable ]
|
||||
|
||||
if not self._quiet:
|
||||
print( 'Setting "{0}" to "{1}".'.format(systemVariable,self._environment[systemVariable]) )
|
||||
if userVariable in self._environment:
|
||||
print( 'Transmitting "{0}" as "{1}".'.format(userVariable,self._environment[userVariable]) )
|
||||
print "Setting <%s> to <%s>." % (systemVariable,self._environment[systemVariable])
|
||||
if self._environment.has_key(userVariable):
|
||||
print "Transmitting <%s> as <%s>." % (userVariable,self._environment[userVariable])
|
||||
return
|
||||
|
||||
|
||||
def _commandTemplate ( self, tools, projects, command ):
|
||||
if self._clang:
|
||||
self._environment[ 'CC' ] = 'clang'
|
||||
self._environment[ 'CXX' ] = 'clang++'
|
||||
self._environment[ 'CC' ] = '/usr/bin/clang'
|
||||
self._environment[ 'CXX' ] = '/usr/bin/clang++'
|
||||
if self._devtoolset:
|
||||
self._environment[ 'BOOST_INCLUDEDIR' ] = '/opt/rh/devtoolset-%d/root/usr/include' % self._devtoolset
|
||||
self._environment[ 'BOOST_LIBRARYDIR' ] = '/opt/rh/devtoolset-%d/root/usr/lib' % self._devtoolset
|
||||
if self._macports:
|
||||
self._environment[ 'BOOST_INCLUDEDIR' ] = '/opt/local/include'
|
||||
self._environment[ 'BOOST_LIBRARYDIR' ] = '/opt/local/lib'
|
||||
|
||||
# Set or guess the various projects TOP environment variables.
|
||||
for project in self.projects:
|
||||
topVariable = "%s_TOP" % project.getName().upper()
|
||||
topUserVariable = "%s_USER_TOP" % project.getName().upper()
|
||||
self._setEnvironment ( topVariable, topUserVariable )
|
||||
|
||||
if tools:
|
||||
# Checks if the requested tools are in the various projects.
|
||||
self.standalones = tools
|
||||
for project in self.projects:
|
||||
self.standalones = project.activate ( self.standalones )
|
||||
for tool in self.standalones:
|
||||
print( '[WARNING] Tool "{}" is not part of any project.'.format(tool) )
|
||||
print "[WARNING] Tool \"%s\" is not part of any project." % tool
|
||||
|
||||
if projects:
|
||||
for projectName in projects:
|
||||
project = self.getProject ( projectName )
|
||||
if not project:
|
||||
ErrorMessage( 1, "No project of name \"%s\"."%projectName ).terminate()
|
||||
project.activateAll()
|
||||
|
||||
if not tools and not projects:
|
||||
for project in self.projects:
|
||||
project.activateAll ()
|
||||
|
||||
for project in self.projects:
|
||||
for tool in project.getActives():
|
||||
print( '\nProcessing tool: "{}".'.format(tool.name) )
|
||||
print "\nProcessing tool: \"%s\"." % tool.name
|
||||
getattr(self,command) ( tool )
|
||||
return
|
||||
|
||||
|
||||
def enable ( self, tools, projects ):
|
||||
self._commandTemplate ( tools, projects, "_enableTool" )
|
||||
return
|
||||
|
||||
|
||||
def enabledTools ( self ):
|
||||
tools = []
|
||||
for project in self.projects:
|
||||
tools += project.getActives()
|
||||
return tools
|
||||
|
||||
|
||||
def build ( self, tools, projects ):
|
||||
self._commandTemplate ( tools, projects, "_build" )
|
||||
return
|
||||
|
||||
|
||||
def gitTarball ( self, tools, projects ):
|
||||
if self.gitHash == "x":
|
||||
self._guessGitHash ( self.getProject(projects[0]) )
|
||||
|
||||
self._doSpec ()
|
||||
# self._doDebChangelog ()
|
||||
|
||||
if os.path.isdir(self.tarballDir):
|
||||
print( 'Removing previous tarball directory: "{}".'.format(self.tarballDir) )
|
||||
print "Removing previous tarball directory: \"%s\"." % self.tarballDir
|
||||
command = [ "/bin/rm", "-rf", self.tarballDir ]
|
||||
self._execute ( command, "Removing top export (tarball) directory" )
|
||||
print( 'Creating tarball directory: "{}".'.format(self.tarballDir) )
|
||||
|
||||
print "Creating tarball directory: \"%s\"." % self.tarballDir
|
||||
os.makedirs ( self.tarballDir )
|
||||
self.gitArchive ( projects[0] )
|
||||
|
||||
return
|
||||
|
||||
|
||||
def userTarball ( self, tools, projects ):
|
||||
self.enable( tools, projects )
|
||||
|
||||
userSourceTarBz2 = os.path.join ( self.tarballDir
|
||||
, datetime.date.today().strftime('%s-%s-%%Y%%m%%d.tar.bz2'%
|
||||
(self.packageName
|
||||
,self.packageVersion)) )
|
||||
|
||||
excludes = []
|
||||
for exclude in self.packageExcludes:
|
||||
excludes += [ '--exclude='+exclude ]
|
||||
|
||||
os.chdir ( self.sourceDir )
|
||||
command = [ "/bin/tar"
|
||||
, "--exclude-backups"
|
||||
|
@ -367,10 +397,13 @@ class Builder:
|
|||
+ [ "-jcvf", userSourceTarBz2 ] \
|
||||
+ self.enabledTools()
|
||||
self._execute ( command, "tar command failed" )
|
||||
|
||||
return
|
||||
|
||||
|
||||
def doRpm ( self ):
|
||||
self.gitTarball ( [], self.packageProjects )
|
||||
|
||||
for rpmDir in [ "SOURCES", "SPECS", "BUILD", "tmp"
|
||||
, "SRPMS", "RPMS/i386", "RPMS/i686", "RPMS/x86_64" ]:
|
||||
rpmFullDir = os.path.join ( self.rpmbuildDir, rpmDir )
|
||||
|
@ -382,8 +415,9 @@ class Builder:
|
|||
if os.path.islink(path):
|
||||
realpath = os.path.realpath( os.readlink(path) )
|
||||
if not os.path.isfile(realpath):
|
||||
print( 'Remove obsolete link: "{}".'.format(path) )
|
||||
print 'Remove obsolete link: <%s>.' % path
|
||||
os.unlink( path )
|
||||
|
||||
rpmSpecFile = os.path.join ( self.rpmbuildDir, "SPECS" , "coriolis2.spec" )
|
||||
rpmSourceFile = os.path.join ( self.rpmbuildDir, "SOURCES", self.sourceTarBz2 )
|
||||
sourceFile = os.path.join ( self.tarballDir , self.sourceTarBz2 )
|
||||
|
@ -391,10 +425,12 @@ class Builder:
|
|||
if os.path.isfile ( rpmSpecFile ):
|
||||
os.unlink ( rpmSpecFile )
|
||||
os.symlink ( self.specFile, rpmSpecFile )
|
||||
|
||||
if not os.path.islink ( rpmSourceFile ):
|
||||
os.symlink ( sourceFile, rpmSourceFile )
|
||||
|
||||
os.chdir ( self.rpmbuildDir )
|
||||
|
||||
command = [ "/usr/bin/rpmbuild"
|
||||
, "--define", "_topdir %s" % self.rpmbuildDir
|
||||
, "--define", "_tmppath %s" % self.tmppathDir
|
||||
|
@ -403,13 +439,18 @@ class Builder:
|
|||
if self._devtoolset:
|
||||
command += [ "--define", "scl devtoolset-%d"%self._devtoolset ]
|
||||
command += [ "-ba", "--clean", rpmSpecFile ]
|
||||
|
||||
self._execute ( command, "Rebuild rpm packages" )
|
||||
|
||||
return
|
||||
|
||||
|
||||
def doDeb ( self ):
|
||||
self.svnTarball ( [], self.packageProjects )
|
||||
|
||||
if not os.path.isdir(self.debbuildDir):
|
||||
os.makedirs ( self.debbuildDir )
|
||||
|
||||
os.chdir ( self.debbuildDir )
|
||||
sourceFile = os.path.join ( self.tarballDir , self.sourceTarBz2 )
|
||||
debOrigFile = os.path.join ( self.debbuildDir, "coriolis2_1.0.%s.orig.tar.bz2" % self.gitHash )
|
||||
|
@ -424,12 +465,17 @@ class Builder:
|
|||
|
||||
packageDir = os.path.join ( self.debbuildDir, "coriolis2-1.0.%s" % self.gitHash )
|
||||
os.chdir ( packageDir )
|
||||
|
||||
self._environment["CFLAGS" ] = "-O2"
|
||||
self._environment["CXXFLAGS"] = "-O2"
|
||||
command = [ "/usr/bin/debuild", "-us", "-uc" ]
|
||||
self._execute ( command, "Rebuild Debian packages" )
|
||||
|
||||
return
|
||||
|
||||
|
||||
def getProject ( self, name ): return self._conf.getProject(name)
|
||||
def loadConfiguration ( self, confFile ): self._conf.load( confFile )
|
||||
def showConfiguration ( self ): self._conf.show()
|
||||
|
||||
|
||||
|
|
|
@ -2,32 +2,35 @@
|
|||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
|
||||
# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | T o o l c h a i n B u i l d e r |
|
||||
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||
# | |
|
||||
# | Author : Damien Dupuis |
|
||||
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./builder/BuilderGui.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
from PyQt4.QtGui import QTabWidget, QApplication, QMainWindow, \
|
||||
QAction , QKeySequence
|
||||
from .OptionsWidget import OptionsWidget
|
||||
from .CompileWidget import CompileWidget
|
||||
from .ConfigureWidget import ConfigureWidget
|
||||
from .AboutWidget import AboutWidget
|
||||
from PyQt4.QtGui import QTabWidget
|
||||
from PyQt4.QtGui import QApplication
|
||||
from PyQt4.QtGui import QMainWindow
|
||||
from PyQt4.QtGui import QAction
|
||||
from PyQt4.QtGui import QKeySequence
|
||||
from OptionsWidget import OptionsWidget
|
||||
from CompileWidget import CompileWidget
|
||||
from ConfigureWidget import ConfigureWidget
|
||||
from AboutWidget import AboutWidget
|
||||
|
||||
|
||||
class BuilderGui ( QMainWindow ):
|
||||
|
||||
def __init__ ( self, confFile, parent=None ):
|
||||
QMainWindow.__init__( self, parent )
|
||||
self.setWindowTitle( 'Coriolis Toolchain Builder' )
|
||||
self.setWindowTitle( 'Coriolis/Chams Builder' )
|
||||
self._tabWidget = QTabWidget()
|
||||
self._configureWidget = ConfigureWidget(confFile)
|
||||
self._optionsWidget = OptionsWidget(self._configureWidget.conf)
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2012-2023, All Rights Reserved
|
||||
# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | T o o l c h a i n B u i l d e r |
|
||||
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||
# | |
|
||||
# | Author : Damien Dupuis |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
|
@ -17,14 +17,30 @@
|
|||
|
||||
import re
|
||||
import subprocess
|
||||
from PyQt4.QtCore import Qt, pyqtSignal, QSettings
|
||||
from PyQt4.QtGui import QFont, QColor, QPalette, QTextCharFormat, \
|
||||
QWidget, QLabel, QPushButton, QCheckBox, \
|
||||
QGroupBox, QButtonGroup, QVBoxLayout, \
|
||||
QHBoxLayout, QGridLayout, QScrollArea, \
|
||||
QComboBox, QLineEdit, QTextEdit, \
|
||||
QFileDialog, QProgressBar, QApplication
|
||||
from .Highlighter import Highlighter
|
||||
from PyQt4.QtCore import Qt
|
||||
from PyQt4.QtCore import pyqtSignal
|
||||
from PyQt4.QtCore import QSettings
|
||||
from PyQt4.QtGui import QFont
|
||||
from PyQt4.QtGui import QColor
|
||||
from PyQt4.QtGui import QPalette
|
||||
from PyQt4.QtGui import QTextCharFormat
|
||||
from PyQt4.QtGui import QWidget
|
||||
from PyQt4.QtGui import QLabel
|
||||
from PyQt4.QtGui import QPushButton
|
||||
from PyQt4.QtGui import QCheckBox
|
||||
from PyQt4.QtGui import QGroupBox
|
||||
from PyQt4.QtGui import QButtonGroup
|
||||
from PyQt4.QtGui import QVBoxLayout
|
||||
from PyQt4.QtGui import QHBoxLayout
|
||||
from PyQt4.QtGui import QGridLayout
|
||||
from PyQt4.QtGui import QScrollArea
|
||||
from PyQt4.QtGui import QComboBox
|
||||
from PyQt4.QtGui import QLineEdit
|
||||
from PyQt4.QtGui import QTextEdit
|
||||
from PyQt4.QtGui import QFileDialog
|
||||
from PyQt4.QtGui import QProgressBar
|
||||
from PyQt4.QtGui import QApplication
|
||||
from builder.Highlighter import Highlighter
|
||||
|
||||
|
||||
class CompileWidget ( QWidget ):
|
||||
|
@ -89,6 +105,7 @@ class CompileWidget ( QWidget ):
|
|||
self.readSettings()
|
||||
return
|
||||
|
||||
|
||||
def _setOptions ( self, options ): self._options = options
|
||||
def _setConf ( self, conf ): self._conf = conf
|
||||
def _getOptions ( self ): return self._options
|
||||
|
@ -97,11 +114,12 @@ class CompileWidget ( QWidget ):
|
|||
options = property( _getOptions, _setOptions )
|
||||
conf = property( _getConf , _setConf )
|
||||
|
||||
|
||||
def browseSaveLog ( self ):
|
||||
self._saveLogEdit.setText( QFileDialog.getSaveFileName( self
|
||||
, 'Select Log File Report'
|
||||
, self._saveLogEdit.text()
|
||||
, 'Report Files (*.log *.txt)' ) )
|
||||
self._saveLogEdit.setText( QFileDialog.getSaveFileName(self
|
||||
,'Select Log File Report'
|
||||
,self._saveLogEdit.text()
|
||||
,'Report Files (*.log *.txt)') )
|
||||
return
|
||||
|
||||
def saveLog ( self ):
|
||||
|
@ -111,34 +129,42 @@ class CompileWidget ( QWidget ):
|
|||
fd.close()
|
||||
return
|
||||
|
||||
|
||||
def shellCommand ( self ):
|
||||
command = [ self.conf.bootstrapDir+'/ccb.py' ]
|
||||
for project in self.options.projects:
|
||||
for tool in project.actives:
|
||||
command += [ '--tool='+tool ]
|
||||
toolsCount = len(command) - 1
|
||||
|
||||
if self.conf.rootDir: command += [ '--root=%s'%self.conf.rootDir ]
|
||||
|
||||
#if self.options.svnUpdate: command += [ '--svn-update' ]
|
||||
#if self.options.svnStatus: command += [ '--svn-update' ]
|
||||
if self.options.enableDoc: command += [ '--doc' ]
|
||||
if self.options.devtoolset: command += [ '--devtoolset-8' ]
|
||||
if self.options.qt4: command += [ '--qt4' ]
|
||||
if self.options.qt5: command += [ '--qt5' ]
|
||||
if self.options.noCache: command += [ '--no-cache' ]
|
||||
if self.options.rmBuild: command += [ '--rm-build' ]
|
||||
if self.options.verbose: command += [ '--verbose' ]
|
||||
if self.options.make:
|
||||
makeArguments='install '+self.options.threads
|
||||
command += [ '--make=%s'%makeArguments ]
|
||||
|
||||
if self.options.buildMode == 'Debug':
|
||||
command += [ '--debug' ]
|
||||
return toolsCount, command
|
||||
|
||||
|
||||
def go ( self ):
|
||||
rePercentage = re.compile(r'^\[\s*(?P<percent>\d+)%\].*')
|
||||
reProcessTool = re.compile(r'^Processing tool:\s*"(?P<tool>.+)"')
|
||||
|
||||
if not self.options or not self.conf: return
|
||||
|
||||
toolsCount, command = self.shellCommand()
|
||||
if not toolsCount: return
|
||||
|
||||
self._progressBar.reset()
|
||||
self._progressBar.setRange( 0, toolsCount*100 )
|
||||
|
||||
|
@ -155,6 +181,7 @@ class CompileWidget ( QWidget ):
|
|||
while True:
|
||||
line = builderProcess.stdout.readline()
|
||||
if line == '': break
|
||||
|
||||
m = rePercentage.match( line )
|
||||
if m:
|
||||
self.progress.emit( toolsDone*100+int(m.group('percent')) )
|
||||
|
@ -162,7 +189,9 @@ class CompileWidget ( QWidget ):
|
|||
m = reProcessTool.match( line )
|
||||
if m:
|
||||
toolsDone += 1
|
||||
|
||||
self._console.insertPlainText( line )
|
||||
|
||||
scrollBar = self._console.verticalScrollBar()
|
||||
scrollBar.setValue( scrollBar.maximum() )
|
||||
QApplication.processEvents()
|
||||
|
@ -173,7 +202,7 @@ class CompileWidget ( QWidget ):
|
|||
|
||||
def readSettings ( self ):
|
||||
settings = QSettings()
|
||||
self._saveLogEdit.setText( settings.value('compile/saveLog') )
|
||||
self._saveLogEdit.setText( settings.value('compile/saveLog').toString() )
|
||||
return
|
||||
|
||||
def saveSettings ( self ):
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2008-2021, All Rights Reserved
|
||||
# Copyright (c) UPMC 2008-2018, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | T o o l c h a i n B u i l d e r |
|
||||
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||
# | |
|
||||
# | Author : Jean-Paul Chaput |
|
||||
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./builder/Configuration.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
@ -22,7 +22,7 @@ import os.path
|
|||
import datetime
|
||||
import subprocess
|
||||
from . import ErrorMessage
|
||||
from .Project import Project
|
||||
from Project import Project
|
||||
|
||||
|
||||
class Configuration ( object ):
|
||||
|
@ -64,26 +64,31 @@ class Configuration ( object ):
|
|||
self._updateSecondary()
|
||||
return
|
||||
|
||||
|
||||
def __setattr__ ( self, attribute, value ):
|
||||
if attribute in Configuration.SecondaryNames:
|
||||
print( ErrorMessage( 1, 'Attempt to write in read-only attribute "{}" in Configuration.' \
|
||||
.format(attribute) ))
|
||||
print ErrorMessage( 1, 'Attempt to write in read-only attribute <%s> in Configuration.'%attribute )
|
||||
return
|
||||
|
||||
if attribute[0] == '_':
|
||||
self.__dict__[attribute] = value
|
||||
return
|
||||
|
||||
if attribute == 'rootDir': value = os.path.expanduser(value)
|
||||
elif attribute == 'enableShared' and value != 'ON': value = 'OFF'
|
||||
|
||||
self.__dict__['_'+attribute] = value
|
||||
self._updateSecondary()
|
||||
return
|
||||
|
||||
|
||||
def __getattr__ ( self, attribute ):
|
||||
if attribute[0] != '_': attribute = '_'+attribute
|
||||
if not attribute in self.__dict__:
|
||||
if not self.__dict__.has_key(attribute):
|
||||
raise ErrorMessage( 1, 'Configuration has no attribute <%s>.'%attribute )
|
||||
return self.__dict__[attribute]
|
||||
|
||||
|
||||
def _updateSecondary ( self ):
|
||||
if self._enableShared == "ON": self._libMode = "Shared"
|
||||
else: self._libMode = "Static"
|
||||
|
@ -104,6 +109,7 @@ class Configuration ( object ):
|
|||
, "%s.%s" % (self._buildMode,self._libMode) )
|
||||
self._buildDir = os.path.join ( self._osDir, "build" )
|
||||
self._installDir = os.path.join ( self._osDir, "install" )
|
||||
|
||||
self._specFileIn = os.path.join ( self._bootstrapDir, "%s.spec.in"%self._packageName )
|
||||
self._specFile = os.path.join ( self._bootstrapDir, "%s.spec" %self._packageName )
|
||||
self._debianDir = os.path.join ( self._bootstrapDir, "debian" )
|
||||
|
@ -120,9 +126,9 @@ class Configuration ( object ):
|
|||
self._distribPatch = os.path.join ( self._sourceDir, "bootstrap", "%s-for-distribution.patch"%self._packageName )
|
||||
return
|
||||
|
||||
|
||||
def _guessOs ( self ):
|
||||
self._libSuffix = None
|
||||
self._osEL9 = re.compile (".*Linux.*(el9|al9).*x86_64.*")
|
||||
self._osSlsoc7x_64 = re.compile (".*Linux.*(el7|slsoc7).*x86_64.*")
|
||||
self._osSlsoc6x_64 = re.compile (".*Linux.*(el6|slsoc6).*x86_64.*")
|
||||
self._osSlsoc6x = re.compile (".*Linux.*(el6|slsoc6).*")
|
||||
|
@ -145,90 +151,93 @@ class Configuration ( object ):
|
|||
|
||||
uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE )
|
||||
lines = uname.stdout.readlines()
|
||||
osLine = lines[0].decode( 'ascii' )
|
||||
if self._osEL9.match(osLine):
|
||||
self._osType = "Linux.el9"
|
||||
self._libSuffix = "64"
|
||||
elif self._osSlsoc7x_64.match(osLine):
|
||||
|
||||
if self._osSlsoc7x_64.match(lines[0]):
|
||||
self._osType = "Linux.el7_64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osSlsoc6x_64.match(osLine):
|
||||
elif self._osSlsoc6x_64.match(lines[0]):
|
||||
self._osType = "Linux.slsoc6x_64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osSlsoc6x .match(osLine): self._osType = "Linux.slsoc6x"
|
||||
elif self._osSLSoC5x_64.match(osLine):
|
||||
elif self._osSlsoc6x .match(lines[0]): self._osType = "Linux.slsoc6x"
|
||||
elif self._osSLSoC5x_64.match(lines[0]):
|
||||
self._osType = "Linux.SLSoC5x_64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osSLSoC5x .match(osLine): self._osType = "Linux.SLSoC5x"
|
||||
elif self._osFedora_64 .match(osLine):
|
||||
elif self._osSLSoC5x .match(lines[0]): self._osType = "Linux.SLSoC5x"
|
||||
elif self._osFedora_64 .match(lines[0]):
|
||||
self._osType = "Linux.fc_64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osFedora .match(osLine): self._osType = "Linux.fc"
|
||||
elif self._osLinux_64 .match(osLine):
|
||||
elif self._osFedora .match(lines[0]): self._osType = "Linux.fc"
|
||||
elif self._osLinux_64 .match(lines[0]):
|
||||
self._osType = "Linux.x86_64"
|
||||
if os.path.exists("/usr/lib64/"):
|
||||
self._libSuffix = "64"
|
||||
elif self._osLinux .match(osLine): self._osType = "Linux.i386"
|
||||
elif self._osDarwin .match(osLine): self._osType = "Darwin"
|
||||
elif self._osFreeBSD8x_amd64.match(osLine):
|
||||
elif self._osLinux .match(lines[0]): self._osType = "Linux.i386"
|
||||
elif self._osDarwin .match(lines[0]): self._osType = "Darwin"
|
||||
elif self._osFreeBSD8x_amd64.match(lines[0]):
|
||||
self._osType = "FreeBSD.8x.amd64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osFreeBSD8x_64.match(osLine):
|
||||
elif self._osFreeBSD8x_64.match(lines[0]):
|
||||
self._osType = "FreeBSD.8x.x86_64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osFreeBSD8x .match(osLine): self._osType = "FreeBSD.8x.i386"
|
||||
elif self._osCygwinW7_64.match(osLine):
|
||||
elif self._osFreeBSD8x .match(lines[0]): self._osType = "FreeBSD.8x.i386"
|
||||
elif self._osCygwinW7_64.match(lines[0]):
|
||||
self._osType = "Cygwin.W7_64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osCygwinW7.match(osLine): self._osType = "Cygwin.W7"
|
||||
elif self._osCygwinW8_64.match(osLine):
|
||||
elif self._osCygwinW7.match(lines[0]): self._osType = "Cygwin.W7"
|
||||
elif self._osCygwinW8_64.match(lines[0]):
|
||||
self._osType = "Cygwin.W8_64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osCygwinW8.match(osLine): self._osType = "Cygwin.W8"
|
||||
elif self._osCygwinW10_64.match(osLine):
|
||||
elif self._osCygwinW8.match(lines[0]): self._osType = "Cygwin.W8"
|
||||
elif self._osCygwinW10_64.match(lines[0]):
|
||||
self._osType = "Cygwin.W10_64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osCygwinW10.match(osLine): self._osType = "Cygwin.W10"
|
||||
elif self._osCygwinW10.match(lines[0]): self._osType = "Cygwin.W10"
|
||||
else:
|
||||
uname = subprocess.Popen ( ["uname", "-sr"], stdout=subprocess.PIPE )
|
||||
self._osType = uname.stdout.readlines()[0][:-1]
|
||||
|
||||
print( '[WARNING] Unrecognized OS: "{}."'.format(osLine[:-1]) )
|
||||
print( ' (using: "{}")'.format(self._osType) )
|
||||
print "[WARNING] Unrecognized OS: \"%s\"." % lines[0][:-1]
|
||||
print " (using: \"%s\")" % self._osType
|
||||
|
||||
if self._libSuffix == '64' and not os.path.exists('/usr/lib64'):
|
||||
self._libSuffix = None
|
||||
|
||||
return
|
||||
|
||||
|
||||
def getPrimaryIds ( self ): return Configuration.PrimaryNames
|
||||
def getSecondaryIds ( self ): return Configuration.SecondaryNames
|
||||
def getAllIds ( self ): return Configuration.PrimaryNames + Configuration.SecondaryNames
|
||||
|
||||
|
||||
def register ( self, project ):
|
||||
for registered in self._projects:
|
||||
if registered.getName() == project.getName():
|
||||
print( ErrorMessage( 0, 'Project "{}" is already registered (ignored).'.format(project.getName()) ))
|
||||
print ErrorMessage( 0, "Project \"%s\" is already registered (ignored)." )
|
||||
return
|
||||
self._projects += [ project ]
|
||||
return
|
||||
|
||||
|
||||
def getProject ( self, name ):
|
||||
for project in self._projects:
|
||||
if project.getName() == name:
|
||||
return project
|
||||
return None
|
||||
|
||||
|
||||
def getToolProject ( self, name ):
|
||||
for project in self._projects:
|
||||
if project.hasTool(name):
|
||||
return project
|
||||
return None
|
||||
|
||||
|
||||
def load ( self, confFile ):
|
||||
moduleGlobals = globals()
|
||||
|
||||
if not confFile:
|
||||
print( 'Making an educated guess to locate the configuration file:' )
|
||||
print 'Making an educated guess to locate the configuration file:'
|
||||
locations = [ os.path.abspath(os.path.dirname(sys.argv[0]))
|
||||
, os.environ['HOME']+'/coriolis-2.x/src/coriolis/bootstrap'
|
||||
, os.environ['HOME']+'/coriolis/src/coriolis/bootstrap'
|
||||
|
@ -238,82 +247,86 @@ class Configuration ( object ):
|
|||
|
||||
for location in locations:
|
||||
self._confFile = location + '/build.conf'
|
||||
print( ' "{}"'.format(self._confFile) )
|
||||
print ' <%s>' % self._confFile
|
||||
|
||||
if os.path.isfile(self._confFile): break
|
||||
if not self._confFile:
|
||||
ErrorMessage( 1, 'Cannot locate any configuration file.' ).terminate()
|
||||
else:
|
||||
print( 'Using user-supplied configuration file:' )
|
||||
print( ' "{}"'.format(confFile) )
|
||||
print 'Using user-supplied configuration file:'
|
||||
print ' <%s>' % confFile
|
||||
|
||||
self._confFile = confFile
|
||||
if not os.path.isfile(self._confFile):
|
||||
ErrorMessage( 1, 'Missing configuration file:', '<%s>'%self._confFile ).terminate()
|
||||
|
||||
print( 'Reading configuration from:' )
|
||||
print( ' "{}"'.format(self._confFile) )
|
||||
print 'Reading configuration from:'
|
||||
print ' <%s>' % self._confFile
|
||||
|
||||
try:
|
||||
exec( open(self._confFile).read(), globals() )
|
||||
except Exception as e:
|
||||
execfile( self._confFile, moduleGlobals )
|
||||
except Exception, e:
|
||||
ErrorMessage( 1, 'An exception occured while loading the configuration file:'
|
||||
, '<%s>\n' % (self._confFile)
|
||||
, 'You should check for simple python errors in this file.'
|
||||
, 'Error was:'
|
||||
, '%s\n' % e ).terminate()
|
||||
|
||||
if 'projects' in moduleGlobals:
|
||||
if moduleGlobals.has_key('projects'):
|
||||
entryNb = 0
|
||||
for entry in moduleGlobals['projects']:
|
||||
entryNb += 1
|
||||
if not 'name' in entry:
|
||||
if not entry.has_key('name'):
|
||||
raise ErrorMessage( 1, 'Missing project name in project entry #%d.' % entryNb )
|
||||
if not 'tools' in entry:
|
||||
if not entry.has_key('tools'):
|
||||
raise ErrorMessage( 1, 'Missing tools list in project entry #%d (<%s>).' \
|
||||
% (entryNb,entry['name']) )
|
||||
if not isinstance(entry['tools'],list):
|
||||
raise ErrorMessage( 1, 'Tools item of project entry #%d (<%s>) is not a list.' \
|
||||
% (entryNb,entry['name']) )
|
||||
if not 'repository' in entry:
|
||||
if not entry.has_key('repository'):
|
||||
raise ErrorMessage( 1, 'Missing project repository in project entry #%d.' \
|
||||
% entryNb )
|
||||
|
||||
self.register( Project(entry['name'],entry['tools'],entry['repository']) )
|
||||
else:
|
||||
ErrorMessage( 1, 'Configuration file is missing the "project" symbol.'
|
||||
, '"{}"'.format(self._confFile) ).terminate()
|
||||
ErrorMessage( 1, 'Configuration file is missing the \'project\' symbol.'
|
||||
, '<%s>'%self._confFile ).terminate()
|
||||
|
||||
if 'projectdir' in moduleGlobals:
|
||||
if moduleGlobals.has_key('projectdir'):
|
||||
self.projectDir = moduleGlobals['projectdir']
|
||||
if 'svnconfig' in moduleGlobals:
|
||||
|
||||
if moduleGlobals.has_key('svnconfig'):
|
||||
svnconfig = moduleGlobals['svnconfig']
|
||||
if 'method' in svnconfig: self._svnMethod = svnconfig['method']
|
||||
if 'package' in moduleGlobals:
|
||||
if svnconfig.has_key('method'): self._svnMethod = svnconfig['method']
|
||||
|
||||
if moduleGlobals.has_key('package'):
|
||||
package = moduleGlobals['package']
|
||||
if 'name' in package: self.packageName = package['name']
|
||||
if 'version' in package: self.packageVersion = package['version']
|
||||
if 'excludes' in package:
|
||||
if package.has_key('name' ): self.packageName = package['name']
|
||||
if package.has_key('version' ): self.packageVersion = package['version']
|
||||
if package.has_key('excludes'):
|
||||
if not isinstance(package['excludes'],list):
|
||||
raise ErrorMessage( 1, 'Excludes of package configuration is not a list.')
|
||||
self._packageExcludes = package['excludes']
|
||||
if 'projects' in package:
|
||||
if package.has_key('projects'):
|
||||
if not isinstance(package['projects'],list):
|
||||
raise ErrorMessage( 1, 'Projects to package is not a list.')
|
||||
self._packageProjects = package['projects']
|
||||
return
|
||||
|
||||
|
||||
def show ( self ):
|
||||
print( 'CCB Configuration:' )
|
||||
print 'CCB Configuration:'
|
||||
if self._gitMethod:
|
||||
print( ' Git Method: "{}"'.format(self._gitMethod) )
|
||||
print ' Git Method: <%s>' % self._gitMethod
|
||||
else:
|
||||
print( ' Git Method not defined, will not be able to push/pull.' )
|
||||
print ' Git Method not defined, will not be able to push/pull.'
|
||||
|
||||
for project in self._projects:
|
||||
print( ' project:{0:>15} repository:"{1}"' \
|
||||
.format( '"{}"'.format(project.getName()), project.getRepository() ))
|
||||
print ' project:%-15s repository:<%s>' % ( ('<%s>'%project.getName()), project.getRepository() )
|
||||
toolOrder = 1
|
||||
for tool in project.getTools():
|
||||
print( '{0}{1:02}:"{2}"'.format( ' '*26, toolOrder, tool ))
|
||||
print '%s%02d:<%s>' % (' '*26,toolOrder,tool)
|
||||
toolOrder += 1
|
||||
print
|
||||
return
|
||||
|
|
|
@ -2,27 +2,40 @@
|
|||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
|
||||
# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | T o o l c h a i n B u i l d e r |
|
||||
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||
# | |
|
||||
# | Author : Damien Dupuis |
|
||||
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./builder/ConfigureWidget.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
from PyQt4.QtCore import Qt, QVariant, pyqtSignal, QSettings, \
|
||||
QModelIndex, QAbstractTableModel
|
||||
from PyQt4.QtGui import QFont, QWidget, QGridLayout, QHBoxLayout, \
|
||||
QVBoxLayout, QLabel, QPushButton, \
|
||||
QLineEdit, QAbstractItemView, QHeaderView, \
|
||||
QTableView, QGroupBox, QFileDialog, \
|
||||
QApplication
|
||||
from .Configuration import Configuration
|
||||
from PyQt4.QtCore import Qt
|
||||
from PyQt4.QtCore import QVariant
|
||||
from PyQt4.QtCore import pyqtSignal
|
||||
from PyQt4.QtCore import QSettings
|
||||
from PyQt4.QtGui import QFont
|
||||
from PyQt4.QtGui import QWidget
|
||||
from PyQt4.QtGui import QGridLayout
|
||||
from PyQt4.QtGui import QHBoxLayout
|
||||
from PyQt4.QtGui import QVBoxLayout
|
||||
from PyQt4.QtGui import QLabel
|
||||
from PyQt4.QtGui import QPushButton
|
||||
from PyQt4.QtGui import QLineEdit
|
||||
from PyQt4.QtCore import QModelIndex
|
||||
from PyQt4.QtCore import QAbstractTableModel
|
||||
from PyQt4.QtGui import QAbstractItemView
|
||||
from PyQt4.QtGui import QHeaderView
|
||||
from PyQt4.QtGui import QTableView
|
||||
from PyQt4.QtGui import QGroupBox
|
||||
from PyQt4.QtGui import QFileDialog
|
||||
from PyQt4.QtGui import QApplication
|
||||
from Configuration import Configuration
|
||||
|
||||
|
||||
class ConfSettingsModel ( QAbstractTableModel ):
|
||||
|
@ -35,6 +48,7 @@ class ConfSettingsModel ( QAbstractTableModel ):
|
|||
def __init__ ( self, conf, parent=None ):
|
||||
ConfSettingsModel.HeaderFont.setBold( True )
|
||||
ConfSettingsModel.SecondaryFont.setItalic( True )
|
||||
|
||||
QAbstractTableModel.__init__( self, parent )
|
||||
self._conf = conf
|
||||
self._ids = self._conf.getAllIds()
|
||||
|
@ -56,15 +70,20 @@ class ConfSettingsModel ( QAbstractTableModel ):
|
|||
if row < self.rowCount():
|
||||
if index.column() == 0: return self._ids[row]
|
||||
elif index.column() == 1: return getattr( self._conf, self._ids[row] )
|
||||
return None
|
||||
|
||||
return QVariant()
|
||||
|
||||
|
||||
def headerData ( self, section, orientation, role ):
|
||||
if orientation == Qt.Vertical: return None
|
||||
if orientation == Qt.Vertical: return QVariant()
|
||||
if role == Qt.FontRole: return ConfSettingsModel.HeaderFont
|
||||
if role != Qt.DisplayRole: return None
|
||||
if role != Qt.DisplayRole: return QVariant()
|
||||
|
||||
if section == 0: return 'Setting'
|
||||
elif section == 1: return 'Value'
|
||||
return '?'
|
||||
|
||||
return QVariant('?')
|
||||
|
||||
|
||||
def rowCount ( self, index=QModelIndex() ): return len(self._ids)
|
||||
def columnCount ( self, index=QModelIndex() ): return 2
|
||||
|
@ -100,6 +119,7 @@ class ConfSettingsWidget ( QWidget ):
|
|||
|
||||
peanoDataLayout = QGridLayout();
|
||||
peanoDataLayout.addWidget( self._view, 0, 0, 1, 1 );
|
||||
|
||||
self.setLayout ( peanoDataLayout );
|
||||
return
|
||||
|
||||
|
@ -124,6 +144,7 @@ class ConfigureWidget ( QWidget ):
|
|||
gLayout.addWidget( rootDirBrowse , 0, 7, 1, 1 )
|
||||
groupDirs = QGroupBox( 'Directories' )
|
||||
groupDirs.setLayout( gLayout )
|
||||
|
||||
gLayout = QGridLayout()
|
||||
groupConf = QGroupBox( 'Configuration' )
|
||||
groupConf.setLayout( gLayout )
|
||||
|
@ -134,13 +155,16 @@ class ConfigureWidget ( QWidget ):
|
|||
#vLayout.addStretch()
|
||||
|
||||
self.setLayout( vLayout )
|
||||
|
||||
self._rootDirEdit.textChanged.connect( self.rootDirChanged )
|
||||
|
||||
self.readSettings()
|
||||
|
||||
noteLabel = QLabel( 'Those settings can be changed only by editing build.conf' )
|
||||
gLayout.addWidget( noteLabel , 0, 0, 1, 1 )
|
||||
gLayout.addWidget( ConfSettingsWidget(self._conf), 1, 0, 1, 1 )
|
||||
|
||||
|
||||
def _getConf ( self ): return self._conf
|
||||
def _getRootDir ( self ): return self._rootDir
|
||||
def _getBootstrapDir ( self ): return self._getConf().bootstrapDir
|
||||
|
@ -149,6 +173,7 @@ class ConfigureWidget ( QWidget ):
|
|||
rootDir = property( _getRootDir )
|
||||
bootstrapDir = property( _getBootstrapDir )
|
||||
|
||||
|
||||
def rootDirChanged ( self, rootDir ):
|
||||
self._rootDir = rootDir
|
||||
return
|
||||
|
@ -159,9 +184,9 @@ class ConfigureWidget ( QWidget ):
|
|||
|
||||
def readSettings ( self ):
|
||||
settings = QSettings()
|
||||
self._rootDirEdit.setText( settings.value('conf/rootDir') )
|
||||
self._rootDirEdit.setText( settings.value('conf/rootDir').toString() )
|
||||
if not self._confFile and settings.value('conf/confFile'):
|
||||
self._confFile = str( settings.value('conf/confFile') )
|
||||
self._confFile = str( settings.value('conf/confFile').toString() )
|
||||
self._conf.load( self._confFile )
|
||||
return
|
||||
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
|
||||
# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | T o o l c h a i n B u i l d e r |
|
||||
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||
# | |
|
||||
# | Author : Damien Dupuis |
|
||||
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./builder/Highlighter.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
@ -17,7 +17,10 @@
|
|||
|
||||
import re
|
||||
from PyQt4.QtCore import Qt
|
||||
from PyQt4.QtGui import QFont, QColor, QTextCharFormat, QSyntaxHighlighter
|
||||
from PyQt4.QtGui import QFont
|
||||
from PyQt4.QtGui import QColor
|
||||
from PyQt4.QtGui import QTextCharFormat
|
||||
from PyQt4.QtGui import QSyntaxHighlighter
|
||||
|
||||
|
||||
class Highlighter ( QSyntaxHighlighter ):
|
||||
|
@ -70,7 +73,7 @@ class Highlighter ( QSyntaxHighlighter ):
|
|||
for rule in Highlighter.Rules:
|
||||
m = rule[2].match(line)
|
||||
if m:
|
||||
if 'percent' in m.groupdict():
|
||||
if m.groupdict().has_key('percent'):
|
||||
self.setFormat( 7, len(line), rule[3] )
|
||||
else:
|
||||
self.setFormat( 0, len(line), rule[3] )
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
|
||||
# Copyright (c) UPMC/LIP6 2012-2018, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
# | T o o l c h a i n B u i l d e r |
|
||||
# | C o r i o l i s / C h a m s B u i l d e r |
|
||||
# | |
|
||||
# | Author : Damien Dupuis |
|
||||
# | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
|
||||
# | =============================================================== |
|
||||
# | Python : "./builder/OptionsWidget.py" |
|
||||
# +-----------------------------------------------------------------+
|
||||
|
@ -17,14 +17,23 @@
|
|||
|
||||
import re
|
||||
import subprocess
|
||||
from PyQt4.QtCore import Qt, pyqtSignal, QSettings
|
||||
from PyQt4.QtGui import QColor, QWidget, QPushButton, \
|
||||
QCheckBox, QGroupBox, QButtonGroup, \
|
||||
QVBoxLayout, QHBoxLayout, QGridLayout, \
|
||||
QScrollArea, QComboBox
|
||||
from .Project import Project
|
||||
from .ConfigureWidget import ConfigureWidget
|
||||
from .ProjectWidgets import ProjectWidgets
|
||||
from PyQt4.QtCore import Qt
|
||||
from PyQt4.QtCore import pyqtSignal
|
||||
from PyQt4.QtCore import QSettings
|
||||
from PyQt4.QtGui import QColor
|
||||
from PyQt4.QtGui import QWidget
|
||||
from PyQt4.QtGui import QPushButton
|
||||
from PyQt4.QtGui import QCheckBox
|
||||
from PyQt4.QtGui import QGroupBox
|
||||
from PyQt4.QtGui import QButtonGroup
|
||||
from PyQt4.QtGui import QVBoxLayout
|
||||
from PyQt4.QtGui import QHBoxLayout
|
||||
from PyQt4.QtGui import QGridLayout
|
||||
from PyQt4.QtGui import QScrollArea
|
||||
from PyQt4.QtGui import QComboBox
|
||||
from builder.Project import Project
|
||||
from builder.ConfigureWidget import ConfigureWidget
|
||||
from builder.ProjectWidgets import ProjectWidgets
|
||||
|
||||
|
||||
class OptionsWidget ( QWidget ):
|
||||
|
@ -57,7 +66,7 @@ class OptionsWidget ( QWidget ):
|
|||
self._make = QCheckBox( 'Build' )
|
||||
self._enableDoc = QCheckBox( 'Build Documentation' )
|
||||
self._devtoolset = QCheckBox( 'Build with devtoolset 8' )
|
||||
self._qt4 = QCheckBox( 'Build with Qt 4 (Qt 5 default)' )
|
||||
self._qt5 = QCheckBox( 'Build with Qt 5 (Qt 4 default)' )
|
||||
self._noCache = QCheckBox( 'Remove previous CMake cache' )
|
||||
self._rmBuild = QCheckBox( 'Cleanup Build Directory' )
|
||||
self._verbose = QCheckBox( 'Display Compiler Commands' )
|
||||
|
@ -83,7 +92,7 @@ class OptionsWidget ( QWidget ):
|
|||
vLayout.addWidget( self._buildMode )
|
||||
vLayout.addWidget( self._enableDoc )
|
||||
vLayout.addWidget( self._devtoolset )
|
||||
vLayout.addWidget( self._qt4 )
|
||||
vLayout.addWidget( self._qt5 )
|
||||
vLayout.addWidget( self._noCache )
|
||||
vLayout.addWidget( self._rmBuild )
|
||||
vLayout.addStretch()
|
||||
|
@ -113,6 +122,7 @@ class OptionsWidget ( QWidget ):
|
|||
self.readSettings()
|
||||
return
|
||||
|
||||
|
||||
def _getProjects ( self ): return self._projects
|
||||
def _getBuildMode ( self ): return self._buildMode.currentText()
|
||||
def _getThreads ( self ): return self._threads.currentText()
|
||||
|
@ -121,7 +131,7 @@ class OptionsWidget ( QWidget ):
|
|||
def _getMake ( self ): return self._make.isChecked()
|
||||
def _getEnableDoc ( self ): return self._enableDoc.isChecked()
|
||||
def _getDevtoolset ( self ): return self._devtoolset.isChecked()
|
||||
def _getQt4 ( self ): return self._qt4.isChecked()
|
||||
def _getQt5 ( self ): return self._qt5.isChecked()
|
||||
def _getNoCache ( self ): return self._noCache.isChecked()
|
||||
def _getRmBuild ( self ): return self._rmBuild.isChecked()
|
||||
def _getVerbose ( self ): return self._verbose.isChecked()
|
||||
|
@ -134,34 +144,36 @@ class OptionsWidget ( QWidget ):
|
|||
make = property( _getMake )
|
||||
enableDoc = property( _getEnableDoc )
|
||||
devtoolset = property( _getDevtoolset )
|
||||
qt4 = property( _getQt4 )
|
||||
qt5 = property( _getQt5 )
|
||||
noCache = property( _getNoCache )
|
||||
rmBuild = property( _getRmBuild )
|
||||
verbose = property( _getVerbose )
|
||||
|
||||
|
||||
def readSettings ( self ):
|
||||
settings = QSettings()
|
||||
#self._svnUpdate .setChecked( bool(settings.value('builder/svnUpdate' )) )
|
||||
#self._svnStatus .setChecked( bool(settings.value('builder/svnStatus' )) )
|
||||
self._make .setChecked( bool(settings.value('builder/make' )) )
|
||||
self._enableDoc .setChecked( bool(settings.value('builder/enableDoc' )) )
|
||||
self._devtoolset .setChecked( bool(settings.value('builder/devtoolset')) )
|
||||
self._qt4 .setChecked( bool(settings.value('builder/qt4' )) )
|
||||
self._noCache .setChecked( bool(settings.value('builder/noCache' )) )
|
||||
self._rmBuild .setChecked( bool(settings.value('builder/rmBuild' )) )
|
||||
self._verbose .setChecked( bool(settings.value('builder/verbose' )) )
|
||||
#self._svnUpdate .setChecked( settings.value('builder/svnUpdate').toBool() )
|
||||
#self._svnStatus .setChecked( settings.value('builder/svnStatus').toBool() )
|
||||
self._make .setChecked( settings.value('builder/make' ).toBool() )
|
||||
self._enableDoc .setChecked( settings.value('builder/enableDoc').toBool() )
|
||||
self._devtoolset .setChecked( settings.value('builder/devtoolset').toBool() )
|
||||
self._qt5 .setChecked( settings.value('builder/qt5').toBool() )
|
||||
self._noCache .setChecked( settings.value('builder/noCache' ).toBool() )
|
||||
self._rmBuild .setChecked( settings.value('builder/rmBuild' ).toBool() )
|
||||
self._verbose .setChecked( settings.value('builder/verbose' ).toBool() )
|
||||
|
||||
buildModeName = settings.value('builder/buildMode')
|
||||
buildModeName = settings.value('builder/buildMode').toString()
|
||||
index = self._buildMode.findText( buildModeName )
|
||||
if index >= 0: self._buildMode.setCurrentIndex( index )
|
||||
|
||||
threads = settings.value('builder/threads')
|
||||
threads = settings.value('builder/threads').toString()
|
||||
index = self._threads.findText( threads )
|
||||
if index >= 0: self._threads.setCurrentIndex( index )
|
||||
|
||||
for project in self._projects: project.readFromSettings()
|
||||
return
|
||||
|
||||
|
||||
def saveSettings ( self ):
|
||||
settings = QSettings()
|
||||
#settings.setValue('builder/svnUpdate' , self._svnUpdate .isChecked() )
|
||||
|
@ -169,11 +181,12 @@ class OptionsWidget ( QWidget ):
|
|||
settings.setValue('builder/make' , self._make .isChecked() )
|
||||
settings.setValue('builder/enableDoc' , self._enableDoc .isChecked() )
|
||||
settings.setValue('builder/devtoolset', self._devtoolset.isChecked() )
|
||||
settings.setValue('builder/qt4' , self._qt4 .isChecked() )
|
||||
settings.setValue('builder/qt5' , self._qt5 .isChecked() )
|
||||
settings.setValue('builder/buildMode' , self._buildMode .currentText() )
|
||||
settings.setValue('builder/noCache' , self._noCache .isChecked() )
|
||||
settings.setValue('builder/rmBuild' , self._rmBuild .isChecked() )
|
||||
settings.setValue('builder/verbose' , self._verbose .isChecked() )
|
||||
settings.setValue('builder/threads' , self._threads .currentText() )
|
||||
|
||||
for project in self._projects: project.saveToSettings()
|
||||
return
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue