Compare commits
446 Commits
devel_gouv
...
devel
Author | SHA1 | Date |
---|---|---|
|
947026cced | |
|
ce084fcf73 | |
|
7b304da14b | |
|
b734d61a00 | |
|
c2750ca127 | |
|
cadae8412b | |
|
d258749373 | |
|
21deed93f1 | |
|
e3d6456ce3 | |
|
fda7054840 | |
|
ffb5e38de2 | |
|
dcf3e7bd77 | |
|
605fa5cdd1 | |
|
508adbd00b | |
|
b06e90d122 | |
|
d8958c3b5a | |
|
9c8e63c11d | |
|
373cbe9835 | |
|
5cd83019db | |
|
d2c2f977f1 | |
|
a110a286d2 | |
|
73cc5c0e76 | |
|
4973d0a181 | |
|
76e9da0b64 | |
|
3243b12abb | |
|
73265c2d68 | |
|
47aadd8ef4 | |
|
30b92ff33a | |
|
ecdcabb8ad | |
|
b7698e7500 | |
|
e084c1e672 | |
|
7b155d1ecf | |
|
06433cc914 | |
|
554aded65b | |
|
9b38590c60 | |
|
014ec72652 | |
|
007677353f | |
|
f8637737a0 | |
|
b77d86c931 | |
|
d019c6aab5 | |
|
b8f15a2c8f | |
|
70fb5cfe3f | |
|
5cdb8b25f0 | |
|
0aa9010b32 | |
|
ee2ed63d35 | |
|
72b906cb68 | |
|
30b69f634a | |
|
73925094f1 | |
|
56da5ebe32 | |
|
0dc33538a7 | |
|
7b7e852f67 | |
|
04410f1cc2 | |
|
a3c05c0f60 | |
|
06ea3d6e09 | |
|
764464911e | |
|
f0c616a5ea | |
|
1df76cdf5a | |
|
4fe1436e1f | |
|
5c75a1ffb7 | |
|
e395069025 | |
|
0743e3bbe4 | |
|
665331252e | |
|
0fdc8f6d3f | |
|
093a4161ef | |
|
011b32d1ed | |
|
238d9dfaba | |
|
fb6979db19 | |
|
3d43a25bb4 | |
|
2bc2e4a988 | |
|
1b41976ca1 | |
|
c178b8c720 | |
|
a9041cbb7c | |
|
495edc6bfe | |
|
d85e7277a4 | |
|
e723a53b69 | |
|
288d89ba93 | |
|
c62383c09f | |
|
7091ac3a77 | |
|
c0b4aad02b | |
|
a9f55021fd | |
|
5d8b994bb6 | |
|
9b87b92eec | |
|
5233d860f4 | |
|
6f793665c2 | |
|
7f0ab625d2 | |
|
e497a4d48f | |
|
052df5d1c8 | |
|
4731e30bb3 | |
|
078e4e0644 | |
|
23975c541d | |
|
0fe1deac94 | |
|
db01b4ff55 | |
|
1f5549d396 | |
|
62e7640a37 | |
|
1beaaf93e4 | |
|
fb694e1c3d | |
|
d873216447 | |
|
49e95115f2 | |
|
2ea099afec | |
|
26184c5016 | |
|
acf6cfe041 | |
|
585489860e | |
|
4f1ce6cfcb | |
|
21eedbcc2b | |
|
393204ba0d | |
|
46c685a7f8 | |
|
1e71b5fb08 | |
|
3830a90482 | |
|
d41e328253 | |
|
7cfd056da2 | |
|
56883db08e | |
|
abee13d669 | |
|
96e6c9dd06 | |
|
c53fc01cb2 | |
|
52fd1c1c40 | |
|
ae5f6ad3de | |
|
a31cf3d334 | |
|
4c7cf227be | |
|
d928a3c7a5 | |
|
c3bed61257 | |
|
57bab117b4 | |
|
31b0c4daf1 | |
|
b9862ecd5e | |
|
4b15396444 | |
|
8bd0a3b0c8 | |
|
e04f6b1cbc | |
|
518a376c01 | |
|
6361ad4ca0 | |
|
e968a5088f | |
|
5afb4cabe9 | |
|
23c0c24c0f | |
|
2568a1a496 | |
|
e22e7f7476 | |
|
a0911be50a | |
|
e5d9c8808b | |
|
7ed41613de | |
|
50a9036d28 | |
|
8f387620cb | |
|
5879a5b581 | |
|
1f4b9450e5 | |
|
090c13663e | |
|
b7f6af8588 | |
|
91e7685921 | |
|
9cfa104836 | |
|
8a23a89f5d | |
|
8353df1ee6 | |
|
03c424f1a1 | |
|
b4fe1a3686 | |
|
87fd1fa7b6 | |
|
7a644c65fb | |
|
1f16642c82 | |
|
79d8461c8f | |
|
881e97bbd3 | |
|
aafec8c64c | |
|
1e8c304ac5 | |
|
842c2dfffc | |
|
461b81bb75 | |
|
d7c9316920 | |
|
3fdef7aa8d | |
|
c7608998ce | |
|
57b5cca27f | |
|
50937d69c7 | |
|
5546c2d89f | |
|
94323f28e0 | |
|
c68932c813 | |
|
800305abc3 | |
|
f404bcc8c0 | |
|
1557d613ae | |
|
c37e6ff953 | |
|
b6961a10c9 | |
|
3d9e86303e | |
|
fabcabe31d | |
|
6b455b66d5 | |
|
d49c76791a | |
|
4aa7b680a7 | |
|
a1bd7cae8a | |
|
3d25c6881d | |
|
3196196642 | |
|
42de4409c5 | |
|
d8e67e5e7d | |
|
f0cd6e602a | |
|
d10b7524ce | |
|
fa1f8e78e0 | |
|
32a6aaf61f | |
|
7a8a3d3434 | |
|
8f8671c8fb | |
|
a02c88a893 | |
|
eb26bb1f87 | |
|
6088ab7b69 | |
|
c22dfe3216 | |
|
095e260e3b | |
|
974473aff7 | |
|
78f4107f36 | |
|
0868283e43 | |
|
4e879b4506 | |
|
412f9bb22d | |
|
e1736fcdba | |
|
7789c6db80 | |
|
52f64bc9d3 | |
|
2b88f8188c | |
|
e7fcfd1a44 | |
|
29add5e898 | |
|
05c0f955c5 | |
|
c6795754a1 | |
|
a3abb567b5 | |
|
424c61d6a4 | |
|
ebabf1e988 | |
|
df78c3ab48 | |
|
5a669c4641 | |
|
b07bf75283 | |
|
ee2e18f801 | |
|
d614e490e7 | |
|
f8afd5bded | |
|
806018b740 | |
|
858a783ddd | |
|
db56681025 | |
|
07f269196b | |
|
77afb7cba4 | |
|
cf92ee9588 | |
|
53af6a2a87 | |
|
0860dffb61 | |
|
8d74ed8110 | |
|
b8d2a0e598 | |
|
4cab713fc9 | |
|
651cf57a13 | |
|
4281370f2e | |
|
d7f6917047 | |
|
64b0fda925 | |
|
aac5b8554b | |
|
b5a669291e | |
|
69bdbd9cd8 | |
|
e8f31aa852 | |
|
56e31c79b7 | |
|
1b9a91cb1c | |
|
05fbfbe7fe | |
|
4da93f3394 | |
|
b2bbaead53 | |
|
56aa1b189c | |
|
deaff0842f | |
|
90c478e8c4 | |
|
4b7973ac84 | |
|
8ccd9618dd | |
|
c1fdf4963b | |
|
842602cdcb | |
|
e72c2b7af1 | |
|
b638f235a7 | |
|
f3186d7ed1 | |
|
06dfdfb52f | |
|
198d5ce035 | |
|
449ee2e81e | |
|
f604351fa2 | |
|
546dfa2f20 | |
|
c0054eb267 | |
|
46acf17e47 | |
|
a0b307b3b4 | |
|
cd4f8560ca | |
|
8dfd522b71 | |
|
d31c489e33 | |
|
80e83d42ed | |
|
57ac01b54a | |
|
c277d9f121 | |
|
c41b92e45f | |
|
f7b2a4f5bb | |
|
38cc00005d | |
|
96fe367cc0 | |
|
047bf14921 | |
|
2116e181de | |
|
c7330041fb | |
|
7598485a4f | |
|
9df5fc838c | |
|
7d88b14334 | |
|
0a69e7d62d | |
|
181b2e1080 | |
|
0e17b91692 | |
|
83ff59817a | |
|
c86d074f06 | |
|
3e921ff07a | |
|
bdb0091043 | |
|
e38e3f46f2 | |
|
0bc7b3203a | |
|
30afe6036b | |
|
d9ebeb4b96 | |
|
d2b40d568b | |
|
2501688dd1 | |
|
da56189d2e | |
|
db54e685f7 | |
|
100342e640 | |
|
e590400ebb | |
|
ae01be3c53 | |
|
36eb9f9121 | |
|
b8cd4264bd | |
|
b65e6f83ff | |
|
c85ad530c4 | |
|
ca41dbd5ef | |
|
49bcdb3195 | |
|
c131e7a948 | |
|
e262c7bd1a | |
|
68a3695780 | |
|
2b870fc609 | |
|
ecda00e154 | |
|
15412317ec | |
|
8c182672dd | |
|
13795bec48 | |
|
a0880da706 | |
|
1253eeeef4 | |
|
11bae679f1 | |
|
3613ce0b5d | |
|
47b26476b7 | |
|
dbfcfae1e8 | |
|
775b6bf1fc | |
|
81920c622e | |
|
5a07033172 | |
|
7c85835c8f | |
|
118b28b5a7 | |
|
60c8bfe75e | |
|
288d1c70b9 | |
|
bba364eecc | |
|
a6f61c1044 | |
|
9594476ab6 | |
|
d294a770c4 | |
|
df1ba66c09 | |
|
82cd53b107 | |
|
757284896c | |
|
7d31d6c457 | |
|
35f73ecec3 | |
|
8980a01dae | |
|
3f1148b105 | |
|
5b88929d23 | |
|
93fbc74f8d | |
|
16428ffaa9 | |
|
440547a1c5 | |
|
d0d0e3aa3d | |
|
bdd78ce44a | |
|
c0b4a73f9e | |
|
56aa978a9b | |
|
fefa47b2dc | |
|
5667797ae6 | |
|
af20ef092c | |
|
2d181a592f | |
|
1e978d5149 | |
|
c8a15a3129 | |
|
1016ae54a6 | |
|
0e9556676a | |
|
d16ec20966 | |
|
dedad34585 | |
|
149b4997fd | |
|
c647a670b1 | |
|
bf181787cb | |
|
555f6ea6a4 | |
|
b65821282c | |
|
a6bfbdf825 | |
|
336b0ad015 | |
|
be1dd12c1a | |
|
34a3ae327c | |
|
78401f5129 | |
|
0cd9cd7ddb | |
|
db0ecb878d | |
|
c737d5bd0c | |
|
f453dbc6f9 | |
|
7267951683 | |
|
d1c0e4882a | |
|
157532af48 | |
|
871622f482 | |
|
d9db42447d | |
|
9b59c50efc | |
|
2c89e5b41a | |
|
e2c27cc039 | |
|
e9147299b0 | |
|
d593683394 | |
|
3bd38f4363 | |
|
0864db6c2f | |
|
801e31f716 | |
|
9d818df5b1 | |
|
33a5cd3b0b | |
|
bbea20b4f6 | |
|
77ecf5523d | |
|
aed63ccdf5 | |
|
33e148440c | |
|
19504ad64f | |
|
5b469e458f | |
|
2efae3507e | |
|
86d539fe5d | |
|
c17c4c3f6e | |
|
c877d7e980 | |
|
a94a290c9b | |
|
ba23a362fb | |
|
53db943d14 | |
|
1babec2e91 | |
|
42bf5d29d4 | |
|
ab13a02eed | |
|
d3b7251eac | |
|
5ff81b59ec | |
|
59c0ab067b | |
|
0a64f3b83d | |
|
921c519bd3 | |
|
cd60032d9c | |
|
908231c4c4 | |
|
4ffd91822f | |
|
fd624f03b6 | |
|
7f936367f8 | |
|
a5d92ecc29 | |
|
6210d312fe | |
|
08b951047c | |
|
b54380e05d | |
|
b6192e78c1 | |
|
1d839711ad | |
|
c805f4d6e4 | |
|
22dd3ddc73 | |
|
c41bd36279 | |
|
762e25adde | |
|
6c66208e0c | |
|
9635cc3311 | |
|
c4ef465c41 | |
|
4250c5bec7 | |
|
a8dd84838b | |
|
ddb684bfe1 | |
|
4884a5d6dc | |
|
2f1caca812 | |
|
e1c5366fef | |
|
0d7deafe81 | |
|
581f557aef | |
|
0c54d109cc | |
|
9aaaf33e6e | |
|
550b087f05 | |
|
084eee3b39 | |
|
5f8a0a944c | |
|
fdce75fdad | |
|
104c043416 | |
|
64056d25ee | |
|
a4ad671739 | |
|
92e5f3fa4d | |
|
3fa8d516bc | |
|
ae1f08f039 | |
|
76d468f6d5 | |
|
4ab6888b94 | |
|
67ca0997c3 | |
|
73296503ad | |
|
fe32916d14 | |
|
2ca9e162ef | |
|
ba2a74e35d | |
|
2f0bf5456d | |
|
be598c9b96 | |
|
3f08b3789f | |
|
f14ef8adc2 | |
|
b4a7d1a6fd | |
|
4e23dff0dc |
|
@ -0,0 +1,54 @@
|
|||
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
|
|
@ -0,0 +1,6 @@
|
|||
[submodule "coloquinte"]
|
||||
path = coloquinte
|
||||
# url = git@github.com:Coloquinte/PlaceRoute.git
|
||||
url = https://github.com/Coloquinte/PlaceRoute.git
|
||||
branch = coriolis-submodule
|
||||
update = merge
|
|
@ -0,0 +1,35 @@
|
|||
#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:]))
|
||||
|
21
README.rst
21
README.rst
|
@ -40,23 +40,20 @@ Building Coriolis
|
|||
|
||||
To build Coriolis, ensure the following prerequisites are met:
|
||||
|
||||
* Python 3.
|
||||
* cmake.
|
||||
* boost.
|
||||
* bison & flex.
|
||||
* Qt 4 or 5.
|
||||
* libxml2.
|
||||
* RapidJSON
|
||||
* Python 3,
|
||||
* 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/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:~$ mkdir -p ~/coriolis-2.x/src/
|
||||
ego@home:~$ cd ~/coriolis-2.x/src
|
||||
ego@home:src$ git clone https://gitlab.lip6.fr/vlsi-eda/coriolis.git
|
||||
ego@home:src$ cd coriolis
|
||||
|
@ -85,7 +82,7 @@ The ``coriolis`` script detects its location and setups the UNIX
|
|||
environment appropriately, then lauches ``cgt`` (or *any* command, with the
|
||||
``--run=<COMMAND>`` option).
|
||||
|
||||
Conversely, you can setup the current shell environement for Coriolis by
|
||||
Conversely, you can setup the current shell environment for Coriolis by
|
||||
using the helper ``coriolisEnv.py``, then run any Coriolis tool: ::
|
||||
|
||||
ego@home:~$ eval `~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py`
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
# -*- 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)
|
|
@ -0,0 +1,27 @@
|
|||
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
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
install( FILES FindSEABREEZE.cmake DESTINATION share/cmake/Modules )
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
# - 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)
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# -*- 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} )
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
|
||||
// -*- 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.
|
||||
*/
|
||||
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
// -*- 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
|
||||
*/
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
// -*- 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.
|
||||
*/
|
|
@ -0,0 +1,65 @@
|
|||
<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>
|
|
@ -0,0 +1,81 @@
|
|||
<!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>
|
|
@ -0,0 +1,276 @@
|
|||
# -*- 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
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<br>
|
||||
<hr>
|
||||
<table class="footer1">
|
||||
<tr>
|
||||
<td class="LFooter"><small>Generated by doxygen $doxygenversion on $date</small></td>
|
||||
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
<table class="footer2">
|
||||
<tr>
|
||||
<td class="LFooter">Seabreeze - Routing Toolbox</td>
|
||||
<td class="RFooter"><small>Copyright © 2008-2020 Sorbonne Universite. All rights reserved</small></td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,26 @@
|
|||
<!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)">
|
|
@ -0,0 +1,73 @@
|
|||
# -*- 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 )
|
||||
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
// -*- 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.
|
|
@ -0,0 +1,71 @@
|
|||
// -*- 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.
|
||||
|
|
@ -0,0 +1,577 @@
|
|||
// -*- 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.
|
|
@ -0,0 +1,86 @@
|
|||
// -*- 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.
|
|
@ -0,0 +1,103 @@
|
|||
|
||||
// -*- 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.
|
|
@ -0,0 +1,215 @@
|
|||
// -*- 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.
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
// -*- 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.
|
|
@ -0,0 +1,207 @@
|
|||
// -*- 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.
|
|
@ -0,0 +1,64 @@
|
|||
// -*- 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);
|
|
@ -0,0 +1,64 @@
|
|||
// -*- 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);
|
|
@ -0,0 +1,149 @@
|
|||
// -*- 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);
|
|
@ -0,0 +1,83 @@
|
|||
// -*- 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);
|
|
@ -0,0 +1,42 @@
|
|||
#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
|
|
@ -0,0 +1,94 @@
|
|||
// -*- 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);
|
|
@ -0,0 +1,77 @@
|
|||
// -*- 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);
|
|
@ -0,0 +1,143 @@
|
|||
#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;
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
R1 0 1 10
|
||||
C1 1 -1 20
|
||||
R2 1 2 30
|
||||
C2 2 -1 10
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
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
|
|
@ -0,0 +1 @@
|
|||
node : not only left and right children, can have multiple children
|
|
@ -9,7 +9,7 @@
|
|||
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 2.8.9)
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}$ENV{CORIOLIS_TOP}/share/cmake/Modules/")
|
||||
find_package(Bootstrap REQUIRED)
|
||||
|
@ -18,8 +18,8 @@
|
|||
set_cmake_policies()
|
||||
setup_boost()
|
||||
setup_qt()
|
||||
setup_python()
|
||||
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
find_package(FLUTE REQUIRED)
|
||||
find_package(HURRICANE REQUIRED)
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
#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"
|
||||
|
@ -243,7 +244,6 @@ namespace Anabatic {
|
|||
cerr << Error( "RawGCellsUnder::commonCtor(): Points are neither horizontally nor vertically aligneds (ignored)."
|
||||
) << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
DebugSession::close();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -251,10 +251,16 @@ namespace Anabatic {
|
|||
or (source.getY() > gcellsArea.getYMax())
|
||||
or (target.getX() <= gcellsArea.getXMin())
|
||||
or (target.getY() <= gcellsArea.getYMin()) ) {
|
||||
cerr << Error( "RawGCellsUnder::commonCtor(): Area is completly outside the GCells area (ignored)."
|
||||
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);
|
||||
DebugSession::close();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -273,21 +279,18 @@ namespace Anabatic {
|
|||
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): Source not under a GCell (ignored)."
|
||||
) << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
DebugSession::close();
|
||||
return;
|
||||
}
|
||||
if (not gtarget) {
|
||||
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): Target not under a GCell (ignored)."
|
||||
) << endl;
|
||||
cdebug_tabw(112,-1);
|
||||
DebugSession::close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (gsource == gtarget) {
|
||||
_elements.push_back( Element(gsource,NULL) );
|
||||
cdebug_tabw(112,-1);
|
||||
DebugSession::close();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -369,31 +372,34 @@ 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" );
|
||||
_blockageNet->setType( Net::Type::BLOCKAGE );
|
||||
}
|
||||
}
|
||||
{ }
|
||||
|
||||
|
||||
void AnabaticEngine::_postCreate ()
|
||||
{
|
||||
Super::_postCreate();
|
||||
|
||||
_diodeCell = DataBase::getDB()->getCell( getConfiguration()->getDiodeName() );;
|
||||
_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."
|
||||
, getConfiguration()->getDiodeName().c_str()
|
||||
, _configuration->getDiodeName().c_str()
|
||||
) << endl;
|
||||
}
|
||||
|
||||
|
@ -404,6 +410,10 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
Configuration* AnabaticEngine::_createConfiguration ()
|
||||
{ return new Configuration(); }
|
||||
|
||||
|
||||
AnabaticEngine* AnabaticEngine::create ( Cell* cell )
|
||||
{
|
||||
if (not cell) throw Error( "AnabaticEngine::create(): NULL cell argument." );
|
||||
|
@ -615,6 +625,7 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
|
||||
RoutingGauge* rg = _configuration->getRoutingGauge();
|
||||
size_t errorCount = 0;
|
||||
ostringstream errors;
|
||||
errors << "AnabaticEngine::checkPlacement():\n";
|
||||
|
@ -626,24 +637,31 @@ namespace Anabatic {
|
|||
|
||||
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 (pin->getLayer() != getConfiguration()->getDVerticalLayer()) {
|
||||
if (not lg->isVertical()) {
|
||||
pinError << " Should be in vertical routing layer, "
|
||||
<< "pin:" << pin->getLayer()->getName()
|
||||
<< " vs gauge:" << getConfiguration()->getDVerticalLayer()->getName()
|
||||
<< " vs gauge:" << lg->getLayer()->getName()
|
||||
<< "\n";
|
||||
valid = false;
|
||||
++errorCount;
|
||||
}
|
||||
if ((pinCenter.getX() - getCell()->getAbutmentBox().getXMin()
|
||||
- getConfiguration()->getDVerticalOffset())
|
||||
% getConfiguration()->getDVerticalPitch()) {
|
||||
if ((pinCenter.getX() - getCell()->getAbutmentBox().getXMin() - lg->getOffset())
|
||||
% lg->getPitch()) {
|
||||
pinError << " Misaligned, "
|
||||
<< "pin:" << DbU::getValueString(pinCenter.getX())
|
||||
<< " vs gauge, pitch:" << DbU::getValueString(getConfiguration()->getDVerticalPitch ())
|
||||
<< ", offset:" << DbU::getValueString(getConfiguration()->getDVerticalOffset())
|
||||
<< " vs gauge, pitch:" << DbU::getValueString(lg->getPitch ())
|
||||
<< ", offset:" << DbU::getValueString(lg->getOffset())
|
||||
<< "\n";
|
||||
valid = false;
|
||||
++errorCount;
|
||||
|
@ -652,21 +670,20 @@ namespace Anabatic {
|
|||
|
||||
if ( (pin->getAccessDirection() == Pin::AccessDirection::EAST)
|
||||
or (pin->getAccessDirection() == Pin::AccessDirection::WEST) ) {
|
||||
if (pin->getLayer() != getConfiguration()->getDHorizontalLayer()) {
|
||||
if (not lg->isHorizontal()) {
|
||||
pinError << " Should be in horizontal routing layer, "
|
||||
<< "pin:" << pin->getLayer()->getName()
|
||||
<< " vs gauge:" << getConfiguration()->getDHorizontalLayer()->getName()
|
||||
<< " vs gauge:" << lg->getLayer()->getName()
|
||||
<< "\n";
|
||||
valid = false;
|
||||
++errorCount;
|
||||
}
|
||||
if ((pinCenter.getY() - getCell()->getAbutmentBox().getYMin()
|
||||
- getConfiguration()->getDHorizontalOffset())
|
||||
% getConfiguration()->getDHorizontalPitch()) {
|
||||
if ((pinCenter.getY() - getCell()->getAbutmentBox().getYMin() - lg->getOffset())
|
||||
% lg->getPitch()) {
|
||||
pinError << " Misaligned, "
|
||||
<< "pin:" << DbU::getValueString(pinCenter.getY())
|
||||
<< " vs gauge, pitch:" << DbU::getValueString(getConfiguration()->getDHorizontalPitch ())
|
||||
<< ", offset:" << DbU::getValueString(getConfiguration()->getDHorizontalOffset())
|
||||
<< " vs gauge, pitch:" << DbU::getValueString(lg->getPitch ())
|
||||
<< ", offset:" << DbU::getValueString(lg->getOffset())
|
||||
<< "\n";
|
||||
valid = false;
|
||||
++errorCount;
|
||||
|
@ -678,6 +695,7 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (errorCount) throw Error( errors.str() );
|
||||
|
||||
return valid;
|
||||
|
@ -836,7 +854,7 @@ namespace Anabatic {
|
|||
if (horizontal) {
|
||||
splitted = Horizontal::create( breakContact
|
||||
, targetContact
|
||||
, getConfiguration()->getGHorizontalLayer()
|
||||
, _configuration->getGHorizontalLayer()
|
||||
, horizontal->getY()
|
||||
, DbU::fromLambda(2.0)
|
||||
);
|
||||
|
@ -845,7 +863,7 @@ namespace Anabatic {
|
|||
if (vertical) {
|
||||
splitted = Vertical::create( breakContact
|
||||
, targetContact
|
||||
, getConfiguration()->getGVerticalLayer()
|
||||
, _configuration->getGVerticalLayer()
|
||||
, vertical->getX()
|
||||
, DbU::fromLambda(2.0)
|
||||
);
|
||||
|
@ -1081,7 +1099,7 @@ namespace Anabatic {
|
|||
|
||||
for ( Net* net : getCell()->getNets() ) {
|
||||
for ( Component* component : net->getComponents() ) {
|
||||
if (getConfiguration()->isGLayer(component->getLayer())) {
|
||||
if (_configuration->isGLayer(component->getLayer())) {
|
||||
cerr << Error( "AnabaticEngine::cleanupGlobal(): Remaining global routing,\n"
|
||||
" %s"
|
||||
, getString(component).c_str()
|
||||
|
@ -1108,7 +1126,7 @@ namespace Anabatic {
|
|||
}
|
||||
cleanupGlobal();
|
||||
|
||||
if (not getConfiguration()->isTwoMetals()) relaxOverConstraineds();
|
||||
if (not _configuration->isTwoMetals()) relaxOverConstraineds();
|
||||
|
||||
_state = EngineActive;
|
||||
}
|
||||
|
@ -1225,6 +1243,64 @@ 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;
|
||||
|
@ -1234,12 +1310,13 @@ namespace Anabatic {
|
|||
startMeasures();
|
||||
openSession();
|
||||
|
||||
int gaugeKind = 3;
|
||||
if (getConfiguration()->isTwoMetals()) gaugeKind = 0;
|
||||
if (getConfiguration()->isHV ()) gaugeKind = 1;
|
||||
if (getConfiguration()->isVH ()) gaugeKind = 2;
|
||||
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 < 3) {
|
||||
if (gaugeKind < 4) {
|
||||
for ( Net* net : getCell()->getNets() ) {
|
||||
if (NetRoutingExtension::isShortNet(net)) {
|
||||
//AutoSegment::setShortNetMode( true );
|
||||
|
@ -1253,9 +1330,10 @@ namespace Anabatic {
|
|||
AutoSegment::setAnalogMode( NetRoutingExtension::isAnalog(net) );
|
||||
|
||||
switch ( gaugeKind ) {
|
||||
case 0: NetBuilder::load<NetBuilderM2>( this, net ); break;
|
||||
case 1: NetBuilder::load<NetBuilderHV>( this, net ); break;
|
||||
case 2: NetBuilder::load<NetBuilderVH>( this, net ); break;
|
||||
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;
|
||||
}
|
||||
|
||||
Session::revalidate();
|
||||
|
@ -1275,11 +1353,6 @@ 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() );
|
||||
|
@ -1610,7 +1683,7 @@ namespace Anabatic {
|
|||
|
||||
EdgeCapacity* AnabaticEngine::_createCapacity ( Flags flags, Interval span )
|
||||
{
|
||||
size_t depth = getConfiguration()->getAllowedDepth();
|
||||
size_t depth = _configuration->getAllowedDepth();
|
||||
EdgeCapacity* edgeCapacity = NULL;
|
||||
|
||||
flags &= Flags::EdgeCapacityMask;
|
||||
|
@ -1652,7 +1725,7 @@ namespace Anabatic {
|
|||
UpdateSession::open();
|
||||
|
||||
for ( auto rp : rps ) {
|
||||
if (not getConfiguration()->selectRpComponent(rp))
|
||||
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();
|
||||
|
|
|
@ -183,19 +183,26 @@ namespace Anabatic {
|
|||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -406,8 +406,8 @@ namespace Anabatic {
|
|||
if (horizontals[1] != NULL) ++count;
|
||||
if (verticals [0] != NULL) ++count;
|
||||
if (verticals [1] != NULL) ++count;
|
||||
if (count > 1) {
|
||||
showTopologyError( "Terminal has more than one segment." );
|
||||
if (count != 1) {
|
||||
showTopologyError( "Terminal has not *exactly* one segment." );
|
||||
}
|
||||
if (horizontals[0] != NULL ) {
|
||||
_segment = Session::lookup( horizontals[0] );
|
||||
|
@ -503,6 +503,9 @@ 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() );
|
||||
|
@ -559,11 +562,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;
|
||||
}
|
||||
else if (delta == 0) setLayerAndWidth( delta, anchorDepth );
|
||||
else if (delta == 1) setLayerAndWidth( delta, std::min(anchorDepth,segmentDepth) );
|
||||
if (delta == 0) setLayerAndWidth( delta, anchorDepth );
|
||||
if (delta == 1) setLayerAndWidth( delta, std::min(anchorDepth,segmentDepth) );
|
||||
}
|
||||
_segment->invalidate( this );
|
||||
|
||||
|
|
|
@ -263,7 +263,9 @@ namespace Anabatic {
|
|||
setFlags( CntBadTopology );
|
||||
} else {
|
||||
if (delta > 1) {
|
||||
if (_horizontal1->isInvalidatedLayer()) {
|
||||
bool updateH1 = (_horizontal1->isInvalidatedLayer() and not _horizontal1->isNonPref())
|
||||
or _vertical1->isNonPref();
|
||||
if (updateH1) {
|
||||
//_horizontal1 = static_cast<AutoHorizontal*>( _horizontal1->makeDogleg(this) );
|
||||
_horizontal1->makeDogleg(this);
|
||||
cdebug_log(145,0) << "Update h1: " << _horizontal1 << endl;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#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"
|
||||
|
@ -33,8 +34,10 @@ namespace Anabatic {
|
|||
|
||||
using std::min;
|
||||
using std::max;
|
||||
using Hurricane::Error;
|
||||
using std::abs;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::DebugSession;
|
||||
using Hurricane::ViaLayer;
|
||||
using Hurricane::RoutingPad;
|
||||
|
@ -52,8 +55,6 @@ namespace Anabatic {
|
|||
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"; }
|
||||
|
||||
|
||||
|
@ -130,6 +131,30 @@ 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) {
|
||||
|
@ -487,17 +512,9 @@ namespace Anabatic {
|
|||
void AutoHorizontal::updateOrient ()
|
||||
{
|
||||
if (_horizontal->getTarget()->getX() < _horizontal->getSource()->getX()) {
|
||||
cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl;
|
||||
if (isAtMinArea()) {
|
||||
DbU::Unit sourceX = _horizontal->getSourceX();
|
||||
DbU::Unit targetX = _horizontal->getTargetX();
|
||||
cdebug_log(149,1) << "updateOrient() " << this << " (before S/T swap)" << endl;
|
||||
_horizontal->invert();
|
||||
setDuSource( sourceX - getSourceU() );
|
||||
setDuTarget( targetX - getTargetU() );
|
||||
} else {
|
||||
_horizontal->invert();
|
||||
}
|
||||
cdebug_log(145,0) << "updateOrient() " << this << " (after S/T swap)" << endl;
|
||||
cdebug_log(149,0) << "updateOrient() " << this << " (after S/T swap)" << endl;
|
||||
|
||||
uint64_t spinFlags = _flags & SegDepthSpin;
|
||||
unsetFlags( SegDepthSpin );
|
||||
|
@ -515,6 +532,7 @@ namespace Anabatic {
|
|||
unsetFlags( SegStrongTerminal );
|
||||
if (terminalFlags & SegSourceTerminal) setFlags( SegTargetTerminal );
|
||||
if (terminalFlags & SegTargetTerminal) setFlags( SegSourceTerminal );
|
||||
cdebug_tabw(149,-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -857,7 +875,7 @@ namespace Anabatic {
|
|||
bool upLayer = true;
|
||||
|
||||
if (Session::getRoutingGauge()->isTwoMetals()) {
|
||||
upLayer = (depth == 0);
|
||||
upLayer = (not Session::getRoutingGauge()->isVH());
|
||||
} else if (Session::getRoutingGauge()->isVH()) {
|
||||
upLayer = (depth < 2);
|
||||
} else {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2008-2018, All Rights Reserved
|
||||
// Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -466,8 +466,10 @@ namespace Anabatic {
|
|||
bool isVertical = (depth == 0) or (Session::getLayerGauge(depth)->isVertical());
|
||||
uint32_t flags = (isVertical) ? Layer::EnclosureV : Layer::EnclosureH ;
|
||||
|
||||
//cerr << depth << ":" << Session::getLayerGauge(depth)->getLayer()->getName()
|
||||
// cerr << depth << ":" << Session::getLayerGauge(depth)->getLayer()->getName()
|
||||
// << " isVertical:" << Session::getLayerGauge(depth)->isVertical() << endl;
|
||||
// cerr << " minimalSpacing: "
|
||||
// << DbU::getValueString( Session::getLayerGauge(depth)->getLayer()->getMinimalSpacing() ) << endl;
|
||||
|
||||
*viaToSameCap = Session::getPWireWidth(depth)/2;
|
||||
|
||||
|
@ -492,12 +494,12 @@ namespace Anabatic {
|
|||
*minimalLength += twoGrid - modulo;
|
||||
}
|
||||
|
||||
//cerr << " viaToTop width: " << DbU::getValueString( Session::getViaWidth(depth) ) << endl;
|
||||
//cerr << " viaToTopCap: " << DbU::getValueString(*viaToTopCap ) << endl;
|
||||
//if (depth > 0)
|
||||
// cerr << " viaToTop width: " << DbU::getValueString( Session::getViaWidth(depth) ) << endl;
|
||||
// cerr << " viaToTopCap: " << DbU::getValueString(*viaToTopCap ) << endl;
|
||||
// if (depth > 0)
|
||||
// cerr << " viaToBottom width:" << DbU::getValueString( Session::getViaWidth(depth-1)/2 ) << endl;
|
||||
//cerr << " viaToBottomCap: " << DbU::getValueString(*viaToBottomCap) << endl;
|
||||
//cerr << " viaToSameCap: " << DbU::getValueString(*viaToSameCap ) << endl;
|
||||
// cerr << " viaToBottomCap: " << DbU::getValueString(*viaToBottomCap) << endl;
|
||||
// cerr << " viaToSameCap: " << DbU::getValueString(*viaToSameCap ) << endl;
|
||||
|
||||
_extensionCaps.push_back( std::array<DbU::Unit*,4>( {{ viaToTopCap
|
||||
, viaToBottomCap
|
||||
|
@ -679,8 +681,12 @@ namespace Anabatic {
|
|||
|
||||
void AutoSegment::revalidate ()
|
||||
{
|
||||
DebugSession::open( getNet(), 159, 160 );
|
||||
cdebug_log(149,0) << "AutoSegment::revalidate() " << this << endl;
|
||||
if (not isInvalidated()) return;
|
||||
if (not isInvalidated()) {
|
||||
DebugSession::close();
|
||||
return;
|
||||
}
|
||||
|
||||
cdebug_tabw(149,1);
|
||||
|
||||
|
@ -715,9 +721,9 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
Interval oldSpan = Interval( _sourcePosition, _targetPosition );
|
||||
if (not expandToMinLength(oldSpan)) {
|
||||
unexpandToMinLength();
|
||||
}
|
||||
if (_flags & SegCreated) oldSpan.makeEmpty();
|
||||
expandToMinLength( oldSpan );
|
||||
if (_flags & SegAtMinArea) unexpandToMinLength();
|
||||
updatePositions();
|
||||
|
||||
unsigned int observerFlags = Revalidate;
|
||||
|
@ -735,6 +741,7 @@ namespace Anabatic {
|
|||
|
||||
cdebug_log(149,0) << "Updated: " << this << endl;
|
||||
cdebug_tabw(149,-1);
|
||||
DebugSession::close();
|
||||
}
|
||||
|
||||
|
||||
|
@ -770,16 +777,16 @@ namespace Anabatic {
|
|||
if (getFlags() & SegSourceTop ) cap = getViaToTopCap (depth);
|
||||
else if (getFlags() & SegSourceBottom) cap = getViaToBottomCap(depth);
|
||||
else cap = getViaToSameCap (depth);
|
||||
cdebug_log(150,0) << "getExtensionCap(): (source) flags:" << getFlags()
|
||||
<< " VIA cap:" << DbU::getValueString(cap)
|
||||
<< " t:" << (getFlags() & SegSourceBottom)
|
||||
<< " b:" << (getFlags() & SegSourceTop)
|
||||
<< endl;
|
||||
// cdebug_log(150,0) << "getExtensionCap(): (source) flags:" << getFlags()
|
||||
// << " VIA cap:" << DbU::getValueString(cap)
|
||||
// << " t:" << (getFlags() & SegSourceBottom)
|
||||
// << " b:" << (getFlags() & SegSourceTop)
|
||||
// << endl;
|
||||
if (not (flags & Flags::NoSegExt)) {
|
||||
cdebug_log(150,0) << "duSource=" << DbU::getValueString(getDuSource()) << endl;
|
||||
// cdebug_log(150,0) << "duSource=" << DbU::getValueString(getDuSource()) << endl;
|
||||
if (-getDuSource() > cap) {
|
||||
cap = -getDuSource();
|
||||
cdebug_log(150,0) << "-> Custom cap (-duSource):" << DbU::getValueString(cap) << endl;
|
||||
// cdebug_log(150,0) << "-> Custom cap (-duSource):" << DbU::getValueString(cap) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -788,16 +795,16 @@ namespace Anabatic {
|
|||
if (getFlags() & SegTargetTop ) cap = getViaToTopCap (depth);
|
||||
else if (getFlags() & SegTargetBottom) cap = getViaToBottomCap(depth);
|
||||
else cap = getViaToSameCap (depth);
|
||||
cdebug_log(150,0) << "getExtensionCap(): (target) flags:" << getFlags()
|
||||
<< " VIA cap:" << DbU::getValueString(cap)
|
||||
<< " t:" << (getFlags() & SegSourceBottom)
|
||||
<< " b:" << (getFlags() & SegSourceTop)
|
||||
<< endl;
|
||||
// cdebug_log(150,0) << "getExtensionCap(): (target) flags:" << getFlags()
|
||||
// << " VIA cap:" << DbU::getValueString(cap)
|
||||
// << " t:" << (getFlags() & SegSourceBottom)
|
||||
// << " b:" << (getFlags() & SegSourceTop)
|
||||
// << endl;
|
||||
if (not (flags & Flags::NoSegExt)) {
|
||||
cdebug_log(150,0) << "duTarget=" << DbU::getValueString(getDuTarget()) << endl;
|
||||
// cdebug_log(150,0) << "duTarget=" << DbU::getValueString(getDuTarget()) << endl;
|
||||
if (getDuTarget() > cap) {
|
||||
cap = getDuTarget();
|
||||
cdebug_log(150,0) << "-> Custom cap (+duTarget):" << DbU::getValueString(cap) << endl;
|
||||
// cdebug_log(150,0) << "-> Custom cap (+duTarget):" << DbU::getValueString(cap) << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -806,7 +813,7 @@ namespace Anabatic {
|
|||
// and not (flags & Flags::NoMinLength)
|
||||
// and (flags & Flags::Target)
|
||||
// and (getMinimalLength(depth) != 0.0)
|
||||
// and isMiddleStack() ) {
|
||||
// and isNearMinArea() ) {
|
||||
// DbU::Unit realLength = getExtensionCap( Flags::Source|Flags::LayerCapOnly|Flags::NoMinLength )
|
||||
// + getAnchoredLength();
|
||||
// if (realLength + cap < getMinimalLength(depth)) {
|
||||
|
@ -901,12 +908,12 @@ namespace Anabatic {
|
|||
sourceAxis = getSourceU();
|
||||
targetAxis = getTargetU();
|
||||
|
||||
if (not isNotAligned()) {
|
||||
//if (not isNotAligned()) {
|
||||
for( AutoSegment* aligned : const_cast<AutoSegment*>(this)->getAligneds() ) {
|
||||
sourceAxis = std::min( sourceAxis, aligned->getSourceU() );
|
||||
targetAxis = std::min( targetAxis, aligned->getTargetU() );
|
||||
}
|
||||
targetAxis = std::max( targetAxis, aligned->getTargetU() );
|
||||
}
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1455,6 +1462,7 @@ namespace Anabatic {
|
|||
AutoSegment* AutoSegment::canonize ( Flags flags )
|
||||
{
|
||||
cdebug_log(149,0) << "canonize() - " << this << endl;
|
||||
if (Session::getAnabatic()->isCanonizeDisabled()) return this;
|
||||
|
||||
// if (isCanonical() and isGlobal()) {
|
||||
// cdebug_log(149,0) << "* " << this << " canonical" << endl;
|
||||
|
@ -1612,52 +1620,15 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
bool AutoSegment::isMiddleStack () const
|
||||
bool AutoSegment::isNearMinArea () const
|
||||
{
|
||||
cdebug_log(149,0) << "AutoSegment::isMiddleStack() - " << this << endl;
|
||||
if (not isCanonical()) return false;
|
||||
cdebug_log(149,0) << "AutoSegment::isNearMinArea() - " << this << endl;
|
||||
if (isNonPref()) return false;
|
||||
if (isGlobal()) {
|
||||
if (getLength() > getPPitch()) return false;
|
||||
cdebug_log(149,0) << "| Considering this global anyway because it is too short. " << endl;
|
||||
}
|
||||
|
||||
AutoContact* source = getAutoSource();
|
||||
AutoContact* target = getAutoTarget();
|
||||
if (not source or not target) {
|
||||
cdebug_log(149,0) << "| false, missing source or target (in creation?). " << endl;
|
||||
return false;
|
||||
}
|
||||
if (isSpinTopOrBottom()) {
|
||||
cdebug_log(149,0) << "| false, neither spin top nor bottom. " << endl;
|
||||
return false;
|
||||
}
|
||||
if (not (source->isTerminal() xor target->isTerminal())) {
|
||||
if (source->isTerminal() and target->isTerminal()) {
|
||||
cdebug_log(149,0) << "| false, source & target are terminals. " << endl;
|
||||
return false;
|
||||
}
|
||||
if (source->isTurn()) {
|
||||
AutoSegment* perpandicular = source->getPerpandicular( this );
|
||||
if (perpandicular->isNonPref() and (perpandicular->getAnchoredLength() != 0)) {
|
||||
cdebug_log(149,0) << "| false, perpandicular is non-pref and non-zero. " << this << endl;
|
||||
return false;
|
||||
}
|
||||
} else if (target->isTurn()) {
|
||||
AutoSegment* perpandicular = target->getPerpandicular( this );
|
||||
if (perpandicular->isNonPref() and (perpandicular->getAnchoredLength() != 0)) {
|
||||
cdebug_log(149,0) << "| false, perpandicular is non-pref and non-zero. " << this << endl;
|
||||
return false;
|
||||
}
|
||||
} else if ((source->isHTee() or target->isHTee()) and isHorizontal()) {
|
||||
cdebug_log(149,0) << "| false, S/T HTee+Terminal and horizontal. " << this << endl;
|
||||
return false;
|
||||
} else if ((source->isVTee() or target->isVTee()) and isVertical()) {
|
||||
cdebug_log(149,0) << "| false, S/T VTee+Terminal and vertical. " << this << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DbU::Unit sourceAxis = 0;
|
||||
DbU::Unit targetAxis = 0;
|
||||
getEndAxes( sourceAxis, targetAxis );
|
||||
|
@ -1665,43 +1636,38 @@ namespace Anabatic {
|
|||
cdebug_log(149,0) << "| Canonical axis length superior to P-Pitch " << this << endl;
|
||||
return false;
|
||||
}
|
||||
cdebug_log(149,0) << " Middle stack or terminal bound." << endl;
|
||||
cdebug_log(149,0) << " Length below P-Pitch." << endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool AutoSegment::isUnderMinLength () const
|
||||
void AutoSegment::expandToMinLength ( Interval span )
|
||||
{
|
||||
return false;
|
||||
// cdebug_log(149,0) << "AutoSegment::isUnderMinLength() - " << this << endl;
|
||||
// if (not isMiddleStack()) return false;
|
||||
// DbU::Unit spanLength = getSpanLength();
|
||||
// DbU::Unit minimalLength = getMinimalLength( Session::getLayerDepth( getLayer() ));
|
||||
// cdebug_log(149,0) << " span=" << DbU::getValueString(spanLength)
|
||||
// << " < min=" << DbU::getValueString(minimalLength)<< endl;
|
||||
// return spanLength < minimalLength;
|
||||
}
|
||||
|
||||
|
||||
bool AutoSegment::expandToMinLength ( Interval span )
|
||||
{
|
||||
if (not isMiddleStack()) return false;
|
||||
if (not isNearMinArea()) return;
|
||||
DebugSession::open( getNet(), 149, 160 );
|
||||
cdebug_log(149,1) << "AutoSegment::expandToMinLength() " << this << endl;
|
||||
cdebug_log(149,0) << "In span=" << span << endl;
|
||||
cdebug_log(149,0) << "Before: [" << DbU::getValueString(getSourceU() - getExtensionCap( Flags::Source|Flags::LayerCapOnly ))
|
||||
<< " " << DbU::getValueString(getTargetU() + getExtensionCap( Flags::Target|Flags::LayerCapOnly ))
|
||||
<< "]" << endl;
|
||||
|
||||
DbU::Unit sourceCap = getExtensionCap( Flags::Source|Flags::NoSegExt|Flags::LayerCapOnly );
|
||||
DbU::Unit targetCap = getExtensionCap( Flags::Target|Flags::NoSegExt|Flags::LayerCapOnly );
|
||||
DbU::Unit halfMinSpacing = getLayer()->getMinimalSpacing() / 2;
|
||||
DbU::Unit sourceCap = getExtensionCap( Flags::Source|Flags::LayerCapOnly );
|
||||
DbU::Unit targetCap = getExtensionCap( Flags::Target|Flags::LayerCapOnly );
|
||||
DbU::Unit segMinLength = getAnchoredLength() + sourceCap + targetCap;
|
||||
DbU::Unit techMinLength = getMinimalLength( Session::getLayerDepth( getLayer() ));
|
||||
if (techMinLength <= segMinLength) {
|
||||
cdebug_log(149,0) << "Above minimal length (" << DbU::getValueString(segMinLength)
|
||||
<< " >= " << DbU::getValueString(techMinLength) << ")" << endl;
|
||||
cdebug_log(149,0) << "Minimal length " << DbU::getValueString(techMinLength)
|
||||
<< " vs. current length " << DbU::getValueString(segMinLength) << endl;
|
||||
if (segMinLength >= techMinLength) {
|
||||
if (segMinLength == techMinLength)
|
||||
setFlags( SegAtMinArea );
|
||||
cdebug_tabw(149,-1);
|
||||
return false;
|
||||
DebugSession::close();
|
||||
return;
|
||||
}
|
||||
sourceCap = getExtensionCap( Flags::Source|Flags::NoSegExt|Flags::LayerCapOnly );
|
||||
targetCap = getExtensionCap( Flags::Target|Flags::NoSegExt|Flags::LayerCapOnly );
|
||||
segMinLength = getAnchoredLength() + sourceCap + targetCap;
|
||||
|
||||
DbU::Unit oneGrid = DbU::fromGrid( 1 );
|
||||
DbU::Unit targetExpand = (techMinLength - segMinLength) / 2 + targetCap;
|
||||
|
@ -1711,11 +1677,20 @@ namespace Anabatic {
|
|||
if (sourceExpand % oneGrid)
|
||||
sourceExpand -= oneGrid + sourceExpand % oneGrid;
|
||||
if (not span.isEmpty()) {
|
||||
DbU::Unit shiftLeft = span.getVMax() - (getTargetU() + targetExpand);
|
||||
DbU::Unit shiftLeft = span.getVMax() - (getTargetU() + targetExpand + halfMinSpacing);
|
||||
if (shiftLeft < 0) {
|
||||
if (targetExpand + shiftLeft < targetCap)
|
||||
shiftLeft = targetCap - targetExpand;
|
||||
targetExpand += shiftLeft;
|
||||
sourceExpand += shiftLeft;
|
||||
}
|
||||
DbU::Unit shiftRight = span.getVMin() - (getSourceU() + sourceExpand - halfMinSpacing);
|
||||
if (shiftRight > 0) {
|
||||
if (sourceExpand + shiftRight < sourceCap)
|
||||
shiftRight = - sourceExpand - sourceCap;
|
||||
targetExpand += shiftRight;
|
||||
sourceExpand += shiftRight;
|
||||
}
|
||||
}
|
||||
setDuSource( sourceExpand );
|
||||
setDuTarget( targetExpand );
|
||||
|
@ -1726,18 +1701,75 @@ namespace Anabatic {
|
|||
<< "] expand:" << DbU::getValueString(techMinLength - segMinLength)<< endl;
|
||||
setFlags( SegAtMinArea );
|
||||
cdebug_tabw(149,-1);
|
||||
return true;
|
||||
DebugSession::close();
|
||||
}
|
||||
|
||||
|
||||
bool AutoSegment::unexpandToMinLength ()
|
||||
void AutoSegment::unexpandToMinLength ()
|
||||
{
|
||||
if (not isAtMinArea()) return false;
|
||||
cdebug_log(149,0) << "AutoSegment::unexpandToMinLength() " << this << endl;
|
||||
// Note: sourceU is a negative number.
|
||||
// targetU is a positive number.
|
||||
// But *both* "cap" are positives.
|
||||
DbU::Unit duSource = getDuSource();
|
||||
DbU::Unit duTarget = getDuTarget();
|
||||
DbU::Unit sourceCap = getExtensionCap( Flags::Source|Flags::NoSegExt|Flags::LayerCapOnly );
|
||||
DbU::Unit targetCap = getExtensionCap( Flags::Target|Flags::NoSegExt|Flags::LayerCapOnly );
|
||||
DbU::Unit segLength = getTargetU() - getSourceU();
|
||||
DbU::Unit segMinLength = getAnchoredLength() + sourceCap + targetCap;
|
||||
DbU::Unit techMinLength = getMinimalLength( Session::getLayerDepth( getLayer() ));
|
||||
|
||||
cdebug_log(149,0) << "* Anchored length " << DbU::getValueString(getAnchoredLength()) << endl;
|
||||
cdebug_log(149,0) << "* Source cap " << DbU::getValueString(sourceCap) << endl;
|
||||
cdebug_log(149,0) << "* Target cap " << DbU::getValueString(targetCap) << endl;
|
||||
cdebug_log(149,0) << "* duSource " << DbU::getValueString(duSource) << endl;
|
||||
cdebug_log(149,0) << "* duTarget " << DbU::getValueString(duTarget) << endl;
|
||||
|
||||
if ((duSource == 0) and (duTarget == 0)) {
|
||||
cdebug_log(149,0) << "Already reset!" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (segLength <= techMinLength) {
|
||||
cdebug_log(149,0) << "Still at min area, do nothing." << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
if (segMinLength > techMinLength) {
|
||||
cdebug_log(149,0) << "Complete reset." << endl;
|
||||
setDuSource( 0 );
|
||||
setDuTarget( 0 );
|
||||
unsetFlags( SegAtMinArea );
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
DbU::Unit shrink = (getAnchoredLength() + duTarget - duSource) - techMinLength;
|
||||
if (shrink < 0) {
|
||||
cerr << Warning( "AutoSegment::unexpandToMinLength(): Negative shrink %s, but forbidden to expand.\n"
|
||||
" On %s"
|
||||
, DbU::getValueString(shrink).c_str()
|
||||
, getString(this).c_str()
|
||||
) << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
DbU::Unit margin = -duSource - sourceCap;
|
||||
if (shrink <= margin) {
|
||||
cdebug_log(149,0) << "Shrink source of " << DbU::getValueString(shrink) << endl;
|
||||
duSource += shrink;
|
||||
setDuSource( duSource );
|
||||
return;
|
||||
}
|
||||
|
||||
setDuSource( 0 );
|
||||
cdebug_log(149,0) << "Shrink target of " << DbU::getValueString(shrink) << endl;
|
||||
margin = duTarget - targetCap;
|
||||
if (margin > shrink)
|
||||
setDuTarget( duTarget - shrink );
|
||||
else {
|
||||
cdebug_log(149,0) << "Target reset" << endl;
|
||||
setDuTarget( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1764,14 +1796,22 @@ namespace Anabatic {
|
|||
DbU::Unit length = getAnchoredLength();
|
||||
if (isGlobal() and (length > getPPitch())) return false;
|
||||
|
||||
if (isDrag() or isFixed()) return false;
|
||||
if (isDrag()) return false;
|
||||
if (not isSpinTopOrBottom()) return false;
|
||||
if ((getDepth() == 1) and isSpinBottom()) return false;
|
||||
if ((flags & Flags::WithPerpands) and _reduceds) return false;
|
||||
|
||||
AutoContact* source = getAutoSource();
|
||||
AutoContact* target = getAutoTarget();
|
||||
|
||||
if (isFixed() and (length < getPPitch())) {
|
||||
if (isSpinTopOrBottom() and source->isTurn() and target->isTurn())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (not Session::getAnabatic()->isChannelStyle()
|
||||
and (getDepth() == 1) and isSpinBottom()) return false;
|
||||
if ((flags & Flags::WithPerpands) and _reduceds) return false;
|
||||
|
||||
cdebug_log(159,0) << " source:" << source->isHTee() << "+" << source->isVTee() << endl;
|
||||
cdebug_log(159,0) << " target:" << target->isHTee() << "+" << target->isVTee() << endl;
|
||||
|
||||
|
@ -2302,6 +2342,8 @@ namespace Anabatic {
|
|||
setWidth( hside );
|
||||
source->setSizes( hside, vside );
|
||||
target->setSizes( hside, vside );
|
||||
setDuSource( 0 );
|
||||
setDuTarget( 0 );
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
@ -2710,6 +2752,7 @@ namespace Anabatic {
|
|||
state += isFixed () ?" F":" -";
|
||||
state += isFixedAxis () ? "X": "-";
|
||||
state += isUnsetAxis () ? "u": "-";
|
||||
state += isAtMinArea () ? "a": "-";
|
||||
state += isStrap () ? "S": "-";
|
||||
state += isUnbreakable () ? "U": "-";
|
||||
state += isCanonical () ? "C": "-";
|
||||
|
@ -2770,10 +2813,23 @@ namespace Anabatic {
|
|||
, Segment* hurricaneSegment
|
||||
)
|
||||
{
|
||||
Horizontal* horizontal = dynamic_cast<Horizontal*>( hurricaneSegment );
|
||||
Vertical* vertical = dynamic_cast<Vertical* >( hurricaneSegment );
|
||||
|
||||
const Layer* horizontalLayer = Session::getDHorizontalLayer();
|
||||
DbU::Unit horizontalWidth = Session::getDHorizontalWidth();
|
||||
const Layer* verticalLayer = Session::getDVerticalLayer();
|
||||
DbU::Unit verticalWidth = Session::getDVerticalWidth();
|
||||
if (not Session::getAnabatic()->getConfiguration()->isGMetal(hurricaneSegment->getLayer())) {
|
||||
size_t depth = Session::getAnabatic()->getConfiguration()->getLayerDepth( hurricaneSegment->getLayer() );
|
||||
if (depth > 2) {
|
||||
horizontalLayer = verticalLayer = hurricaneSegment->getLayer();
|
||||
horizontalWidth = Session::getAnabatic()->getConfiguration()->getWireWidth( depth );
|
||||
verticalWidth = Session::getAnabatic()->getConfiguration()->getPWireWidth( depth );
|
||||
if (vertical)
|
||||
std::swap( horizontalWidth, verticalWidth );
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t wPitch = NetRoutingExtension::getWPitch( source->getNet() );
|
||||
if (wPitch > 1) {
|
||||
|
@ -2788,9 +2844,7 @@ namespace Anabatic {
|
|||
|
||||
bool reattachSource = false;
|
||||
bool reattachTarget = false;
|
||||
AutoSegment* segment;
|
||||
Horizontal* horizontal = dynamic_cast<Horizontal*>( hurricaneSegment );
|
||||
Vertical* vertical = dynamic_cast<Vertical* >( hurricaneSegment );
|
||||
AutoSegment* segment = NULL;
|
||||
AutoContact* reference = NULL;
|
||||
|
||||
cdebug_log(149,0) << "Source:" << source << endl;
|
||||
|
@ -3015,6 +3069,7 @@ namespace Anabatic {
|
|||
if (wPitch > 1) segment->setFlags( SegWide );
|
||||
if (source->canDrag() or target->canDrag()) segment->setFlags( SegDrag );
|
||||
if (dir & Flags::UseNonPref) segment->setFlags( SegNonPref );
|
||||
if (dir.contains(Flags::UseNonPref|Flags::OnVSmall)) segment->setFlags( SegOnVSmall );
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
@ -3162,13 +3217,17 @@ namespace Anabatic {
|
|||
|
||||
void AutoSegment::getTopologicalInfos ( AutoSegment* seed
|
||||
, vector<AutoSegment*>& aligneds
|
||||
, vector<AutoSegment*>& perpandiculars
|
||||
, vector< tuple<AutoSegment*,Flags> >&
|
||||
perpandiculars
|
||||
, DbU::Unit& leftBound
|
||||
, DbU::Unit& rightBound
|
||||
)
|
||||
{
|
||||
cdebug_log(145,1) << "getTopologicalInfos() - " << seed << endl;
|
||||
|
||||
bool isSourceBoundToChannel = false;
|
||||
bool isTargetBoundToChannel = false;
|
||||
|
||||
leftBound = DbU::Max;
|
||||
rightBound = DbU::Min;
|
||||
|
||||
|
@ -3223,10 +3282,21 @@ namespace Anabatic {
|
|||
}
|
||||
} else {
|
||||
cdebug_log(149,0) << "| perpandicular " << currentSegment << endl;
|
||||
perpandiculars.push_back( currentSegment );
|
||||
Flags perpandFlags = (currentSegment->getAutoSource() == sourceContact)
|
||||
? Flags::Source : Flags::Target;
|
||||
perpandiculars.push_back( make_tuple( currentSegment, perpandFlags ));
|
||||
if (Session::getAnabatic()->isChannelStyle()) {
|
||||
if (currentSegment->isNonPref() and currentSegment->isFixed()) {
|
||||
if (perpandFlags & Flags::Source) isSourceBoundToChannel = true;
|
||||
else isTargetBoundToChannel = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isSourceBoundToChannel) leftBound += (rightBound - leftBound)/2;
|
||||
if (isTargetBoundToChannel) rightBound -= (rightBound - leftBound)/2;
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include "hurricane/Bug.h"
|
||||
#include "hurricane/Warning.h"
|
||||
#include "hurricane/ViaLayer.h"
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "crlcore/RoutingGauge.h"
|
||||
|
@ -29,8 +30,10 @@ namespace Anabatic {
|
|||
|
||||
using std::min;
|
||||
using std::max;
|
||||
using Hurricane::Error;
|
||||
using std::abs;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::ViaLayer;
|
||||
|
||||
|
||||
|
@ -46,8 +49,6 @@ namespace Anabatic {
|
|||
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"; }
|
||||
|
||||
|
||||
|
@ -117,6 +118,30 @@ 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) {
|
||||
|
@ -382,10 +407,6 @@ namespace Anabatic {
|
|||
if (_vertical->getTargetY() < _vertical->getSourceY()) {
|
||||
cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl;
|
||||
_vertical->invert();
|
||||
DbU::Unit duSource = getDuSource();
|
||||
DbU::Unit duTarget = getDuTarget();
|
||||
setDuSource( -duTarget );
|
||||
setDuTarget( -duSource );
|
||||
|
||||
unsigned int spinFlags = _flags & SegDepthSpin;
|
||||
unsetFlags( SegDepthSpin );
|
||||
|
@ -715,7 +736,7 @@ namespace Anabatic {
|
|||
bool upLayer = true;
|
||||
|
||||
if (Session::getRoutingGauge()->isTwoMetals()) {
|
||||
upLayer = (depth == 0);
|
||||
upLayer = (Session::getRoutingGauge()->isVH());
|
||||
} else if (Session::getRoutingGauge()->isVH()) {
|
||||
upLayer = (depth < 2);
|
||||
} else {
|
||||
|
|
|
@ -36,9 +36,10 @@ endif ( CHECK_DETERMINISM )
|
|||
anabatic/NetBuilderM2.h
|
||||
anabatic/NetBuilderHV.h
|
||||
anabatic/NetBuilderVH.h
|
||||
anabatic/NetBuilderHybridVH.h
|
||||
anabatic/ChipTools.h
|
||||
)
|
||||
set( pyIncludes )
|
||||
set( pyIncludes anabatic/PyStyleFlags.h )
|
||||
set( cpps Constants.cpp
|
||||
Configuration.cpp
|
||||
Matrix.cpp
|
||||
|
@ -62,13 +63,15 @@ endif ( CHECK_DETERMINISM )
|
|||
NetBuilderM2.cpp
|
||||
NetBuilderHV.cpp
|
||||
NetBuilderVH.cpp
|
||||
NetBuilderHybridVH.cpp
|
||||
ChipTools.cpp
|
||||
LayerAssign.cpp
|
||||
AntennaProtect.cpp
|
||||
PreRouteds.cpp
|
||||
AnabaticEngine.cpp
|
||||
)
|
||||
set( pyCpps PyAnabatic.cpp
|
||||
set( pyCpps PyStyleFlags.cpp
|
||||
PyAnabatic.cpp
|
||||
)
|
||||
|
||||
set( depLibs ${ETESIAN_LIBRARIES}
|
||||
|
@ -87,12 +90,13 @@ endif ( CHECK_DETERMINISM )
|
|||
${QtX_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
${LIBXML2_LIBRARIES}
|
||||
${Python_LIBRARIES} -lutil
|
||||
${Python3_LIBRARIES}
|
||||
-lutil
|
||||
)
|
||||
|
||||
add_library( anabatic ${cpps} )
|
||||
set_target_properties( anabatic PROPERTIES VERSION 1.0 SOVERSION 1 )
|
||||
#target_link_libraries( anabatic ${depLibs} )
|
||||
target_link_libraries( anabatic ${depLibs} )
|
||||
|
||||
add_python_module( "${pyCpps}"
|
||||
"${pyIncludes}"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// -*- mode: C++; explicit-buffer-name: "Configuration.cpp<anabatic>" -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2016-2018, All Rights Reserved
|
||||
// Copyright (c) Sorbonne Université 2016-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -26,6 +26,7 @@
|
|||
#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"
|
||||
|
@ -56,6 +57,7 @@ namespace Anabatic {
|
|||
using Hurricane::BasicLayer;
|
||||
using Hurricane::RegularLayer;
|
||||
using Hurricane::Segment;
|
||||
using Hurricane::Pad;
|
||||
using Hurricane::Pin;
|
||||
using Hurricane::Plug;
|
||||
using Hurricane::Path;
|
||||
|
@ -76,6 +78,8 @@ 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 ()
|
||||
|
@ -97,17 +101,22 @@ namespace Anabatic {
|
|||
GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() );
|
||||
|
||||
string gaugeName = Cfg::getParamString("anabatic.routingGauge","sxlib")->asString();
|
||||
if (cg == NULL) {
|
||||
if (not cg)
|
||||
cg = AllianceFramework::get()->getCellGauge( gaugeName );
|
||||
if (cg == NULL)
|
||||
throw Error( "AnabaticEngine::Configuration(): Unable to find default cell gauge." );
|
||||
if (not cg) {
|
||||
string cellGaugeName = Cfg::getParamString("anabatic.cellGauge","sxlib")->asString();
|
||||
cg = AllianceFramework::get()->getCellGauge( cellGaugeName );
|
||||
}
|
||||
if (not cg)
|
||||
throw Error( "AnabaticEngine::Configuration(): Unable to find cell gauge \"%s\""
|
||||
, gaugeName.c_str() );
|
||||
|
||||
if (rg == NULL) {
|
||||
if (not rg)
|
||||
rg = AllianceFramework::get()->getRoutingGauge( gaugeName );
|
||||
if (rg == NULL)
|
||||
throw Error( "AnabaticEngine::Configuration(): No routing gauge named \"%s\"", gaugeName.c_str() );
|
||||
}
|
||||
if (not rg)
|
||||
throw Error( "AnabaticEngine::Configuration(): Unable to find routing gauge \"%s\""
|
||||
, gaugeName.c_str() );
|
||||
|
||||
_cg = cg->getClone();
|
||||
_rg = rg->getClone();
|
||||
|
||||
|
@ -180,6 +189,8 @@ namespace Anabatic {
|
|||
, _ddepthv (other._ddepthv)
|
||||
, _ddepthh (other._ddepthh)
|
||||
, _ddepthc (other._ddepthc)
|
||||
, _netBuilderStyle (other._netBuilderStyle)
|
||||
, _routingStyle (other._routingStyle)
|
||||
, _cg (NULL)
|
||||
, _rg (NULL)
|
||||
, _extensionCaps (other._extensionCaps)
|
||||
|
@ -218,6 +229,10 @@ namespace Anabatic {
|
|||
{ return _rg->isTwoMetals(); }
|
||||
|
||||
|
||||
bool Configuration::isHybrid () const
|
||||
{ return _routingStyle & StyleFlags::Hybrid; }
|
||||
|
||||
|
||||
bool Configuration::isHV () const
|
||||
{ return _rg->isHV(); }
|
||||
|
||||
|
@ -492,10 +507,12 @@ namespace Anabatic {
|
|||
break;
|
||||
}
|
||||
|
||||
Component* candidate = dynamic_cast<Segment*>(component);
|
||||
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() );
|
||||
|
|
|
@ -14,16 +14,22 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#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);
|
||||
|
@ -53,6 +59,7 @@ 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::GlobalEstimated = (1L << 6);
|
||||
|
@ -125,6 +132,7 @@ namespace Anabatic {
|
|||
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 ()
|
||||
|
@ -210,4 +218,69 @@ 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.
|
||||
|
|
|
@ -265,7 +265,7 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
if (rp) {
|
||||
Vertical* v = dynamic_cast<Vertical*>(rp->_getEntityAsSegment());
|
||||
Vertical* v = dynamic_cast<Vertical*>(rp->_getEntityAs<Segment>());
|
||||
if (v) { return true; }
|
||||
}
|
||||
}
|
||||
|
@ -285,7 +285,7 @@ namespace Anabatic {
|
|||
}
|
||||
}
|
||||
if (rp) {
|
||||
Horizontal* h = dynamic_cast<Horizontal*>(rp->_getEntityAsSegment());
|
||||
Horizontal* h = dynamic_cast<Horizontal*>(rp->_getEntityAs<Segment>());
|
||||
if (h) { return true; }
|
||||
}
|
||||
}
|
||||
|
@ -2873,8 +2873,8 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_log(112,0) << "void Dijkstra::_setSourcesGRAData() : " << seed << endl;
|
||||
GCell* gseed = seed->getGCell();
|
||||
Horizontal* h = dynamic_cast<Horizontal*>(rp->_getEntityAsSegment());
|
||||
Vertical* v = dynamic_cast<Vertical*> (rp->_getEntityAsSegment());
|
||||
Horizontal* h = dynamic_cast<Horizontal*>(rp->_getEntityAs<Segment>());
|
||||
Vertical* v = dynamic_cast<Vertical*> (rp->_getEntityAs<Segment>());
|
||||
if (h) {
|
||||
cdebug_log(112,0) << "case H " << endl;
|
||||
seed->unsetFlags(Vertex::iHorizontal);
|
||||
|
|
|
@ -285,7 +285,7 @@ namespace Anabatic {
|
|||
: Super(anabatic->getCell())
|
||||
, _observable ()
|
||||
, _anabatic (anabatic)
|
||||
, _flags (Flags::HChannelGCell|Flags::Invalidated)
|
||||
, _flags (Flags::Invalidated)
|
||||
, _westEdges ()
|
||||
, _eastEdges ()
|
||||
, _southEdges ()
|
||||
|
@ -1343,6 +1343,26 @@ 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;
|
||||
|
@ -1371,6 +1391,7 @@ 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;
|
||||
|
@ -1404,6 +1425,7 @@ namespace Anabatic {
|
|||
, _getString().c_str(), getString(segment).c_str() ) << endl;
|
||||
|
||||
_hsegments.erase( _hsegments.begin() + end, _hsegments.end() );
|
||||
_flags |= Flags::Invalidated;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1429,6 +1451,7 @@ namespace Anabatic {
|
|||
, getString(segment).c_str() ) << endl;
|
||||
|
||||
_vsegments.erase( _vsegments.begin() + end, _vsegments.end() );
|
||||
_flags |= Flags::Invalidated;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1528,10 +1551,22 @@ 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 (not i) continue;
|
||||
if ((float)(_blockages[i] * Session::getPitch(i)) > 0.40*(float)(width*height)) {
|
||||
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;
|
||||
}
|
||||
|
@ -1880,6 +1915,13 @@ 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -218,10 +218,11 @@ namespace {
|
|||
cdebug_log(149,0) << "Slacken from: " << rp << endl;
|
||||
|
||||
if (rp->getLayer()) {
|
||||
if (_anabatic->getConfiguration()->getLayerDepth(rp->getLayer()) == 1)
|
||||
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) );
|
||||
|
@ -572,9 +573,9 @@ namespace Anabatic {
|
|||
|
||||
for ( AutoSegment* horizontal : horizontals ) {
|
||||
vector<AutoSegment*> collapseds;
|
||||
vector<AutoSegment*> perpandiculars;
|
||||
vector<AutoSegment*> northBounds;
|
||||
vector<AutoSegment*> southBounds;
|
||||
vector< tuple<AutoSegment*,Flags> > perpandicularsDatas;
|
||||
//vector<AutoSegment*> northBounds;
|
||||
//vector<AutoSegment*> southBounds;
|
||||
DbU::Unit leftBound;
|
||||
DbU::Unit rightBound;
|
||||
//bool hasNorth = false;
|
||||
|
@ -582,12 +583,13 @@ namespace Anabatic {
|
|||
|
||||
AutoSegment::getTopologicalInfos( horizontal
|
||||
, collapseds
|
||||
, perpandiculars
|
||||
, perpandicularsDatas
|
||||
, leftBound
|
||||
, rightBound
|
||||
);
|
||||
|
||||
for ( AutoSegment* perpandicular : perpandiculars ) {
|
||||
for ( auto perpandicularDatas : perpandicularsDatas ) {
|
||||
AutoSegment* perpandicular = std::get<0>( perpandicularDatas );
|
||||
if (Session::getLayerDepth(perpandicular->getLayer()) > 2) continue;
|
||||
|
||||
bool hasGlobal = false;
|
||||
|
@ -986,7 +988,7 @@ namespace Anabatic {
|
|||
rps.insert( terminal->getRoutingPad() );
|
||||
}
|
||||
}
|
||||
if (rps.size() > 8) {
|
||||
if (rps.size() > getConfiguration()->getSaturateRp()) {
|
||||
GCellRps* gcellRps = new GCellRps ( gcell, this );
|
||||
gcellRpss.insert( gcellRps );
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#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"
|
||||
|
@ -220,6 +221,7 @@ namespace Anabatic {
|
|||
using Hurricane::Error;
|
||||
using Hurricane::Warning;
|
||||
using Hurricane::Bug;
|
||||
using Hurricane::Rectilinear;
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
|
@ -366,7 +368,9 @@ namespace Anabatic {
|
|||
, _routingPadAutoSegments()
|
||||
, _toFixSegments ()
|
||||
, _degree (0)
|
||||
, _isTwoMetals (false)
|
||||
, _isStrictChannel (false)
|
||||
, _sourceFlags (0)
|
||||
, _flags (0)
|
||||
{ }
|
||||
|
||||
|
||||
|
@ -377,6 +381,8 @@ namespace Anabatic {
|
|||
void NetBuilder::clear ()
|
||||
{
|
||||
_connexity.connexity = 0;
|
||||
_sourceFlags = 0;
|
||||
_flags = 0;
|
||||
_topology = 0;
|
||||
_net = NULL;
|
||||
_netData = NULL;
|
||||
|
@ -390,8 +396,8 @@ namespace Anabatic {
|
|||
_norths .clear();
|
||||
_souths .clear();
|
||||
_routingPads .clear();
|
||||
_toFixSegments .clear();
|
||||
_routingPadAutoSegments.clear();
|
||||
_toFixSegments .clear();
|
||||
}
|
||||
|
||||
|
||||
|
@ -403,17 +409,22 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
NetBuilder& NetBuilder::setStartHook ( AnabaticEngine* anbt, Hook* fromHook, AutoContact* sourceContact )
|
||||
NetBuilder& NetBuilder::setStartHook ( AnabaticEngine* anbt
|
||||
, Hook* fromHook
|
||||
, AutoContact* sourceContact
|
||||
, uint64_t sourceFlags )
|
||||
{
|
||||
clear();
|
||||
|
||||
_isTwoMetals = anbt->getConfiguration()->isTwoMetals();
|
||||
_isStrictChannel = anbt->isChannelStyle() and not anbt->isHybridStyle();
|
||||
_sourceFlags = sourceFlags;
|
||||
_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);
|
||||
|
@ -470,12 +481,18 @@ 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->_getEntityAsComponent()->getCell())) {
|
||||
if (rp and AllianceFramework::get()->isPad(rp->_getEntityAs<Component>()->getCell())) {
|
||||
_connexity.fields.Pad++;
|
||||
} else {
|
||||
const Layer* layer = anchor->getLayer();
|
||||
|
@ -489,11 +506,32 @@ namespace Anabatic {
|
|||
continue;
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
else {
|
||||
cerr << Warning( "Terminal layer \"%s\" of %s is not managed yet (ignored)."
|
||||
, getString(layer->getName()).c_str()
|
||||
|
@ -502,7 +540,7 @@ namespace Anabatic {
|
|||
//continue;
|
||||
}
|
||||
|
||||
if (dynamic_cast<Pin*>(rp->getOccurrence().getEntity())) _connexity.fields.Pin++;
|
||||
if (isPin) _connexity.fields.Pin++;
|
||||
}
|
||||
|
||||
cdebug_log(145,0) << "| Component to connect: " << anchor << endl;
|
||||
|
@ -543,7 +581,6 @@ namespace Anabatic {
|
|||
<< "+" << (int)_connexity.fields.Pad
|
||||
<< "] " << _gcell
|
||||
<< endl;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
@ -553,6 +590,7 @@ 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) {
|
||||
|
@ -571,12 +609,60 @@ 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 );
|
||||
_forks.push( toHookOpposite, contact, getFlags() );
|
||||
|
||||
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;
|
||||
|
@ -589,14 +675,19 @@ namespace Anabatic {
|
|||
<< "+" << (int)_connexity.fields.Pad
|
||||
<< "] " << _gcell
|
||||
<< endl;
|
||||
cdebug_log(145,0) << "getSourceFlags():" << getSourceFlags()
|
||||
<< " getFlags():" << getFlags() << endl;
|
||||
|
||||
if (not isTwoMetals()) {
|
||||
if (not isStrictChannel()) {
|
||||
_southWestContact = NULL;
|
||||
_northEastContact = NULL;
|
||||
}
|
||||
|
||||
if (not _gcell->isAnalog()) {
|
||||
if (isTwoMetals() and not _sourceContact) _fromHook = NULL;
|
||||
if (isStrictChannel() and not _sourceContact) {
|
||||
cdebug_log(145,0) << "No _sourceContact, resetting _fromHook" << endl;
|
||||
_fromHook = NULL;
|
||||
}
|
||||
|
||||
switch ( _connexity.connexity ) {
|
||||
case Conn_1G_1Pad:
|
||||
|
@ -635,7 +726,7 @@ namespace Anabatic {
|
|||
case Conn_2G_6M1:
|
||||
case Conn_2G_7M1:
|
||||
case Conn_2G_8M1:
|
||||
case Conn_2G_9M1:
|
||||
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:
|
||||
|
@ -647,7 +738,7 @@ namespace Anabatic {
|
|||
case Conn_3G_9M1:
|
||||
case Conn_3G_2M3:
|
||||
case Conn_3G_3M3:
|
||||
case Conn_3G_4M3:
|
||||
case Conn_3G_4M3: _do_xG_xM1_xM3(); break;
|
||||
case Conn_4G_1M1: if (_do_xG_1M1()) break;
|
||||
case Conn_4G_2M1:
|
||||
case Conn_4G_3M1:
|
||||
|
@ -688,6 +779,7 @@ namespace Anabatic {
|
|||
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:
|
||||
|
@ -706,7 +798,7 @@ namespace Anabatic {
|
|||
case Conn_1G_1M1_1M3: _do_1G_xM1 (); break;
|
||||
case Conn_2G_1M1_1M2: _do_xG_1M1_1M2 (); break;
|
||||
default:
|
||||
if (not isTwoMetals())
|
||||
//if (not isStrictChannel())
|
||||
throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n"
|
||||
" The global routing seems to be defective."
|
||||
, _connexity.connexity
|
||||
|
@ -722,6 +814,9 @@ 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);
|
||||
|
@ -1062,7 +1157,9 @@ namespace Anabatic {
|
|||
|
||||
bool NetBuilder::_do_xG_1PinM2 ()
|
||||
{
|
||||
throw Error ( "%s::_do_xG_1PinM2() method *not* reimplemented from base class.", getTypeName().c_str() );
|
||||
throw Error( "%s::_do_xG_1PinM2() method *not* reimplemented from base class.\n"
|
||||
" On %s"
|
||||
, getTypeName().c_str(), getString(getNet()).c_str() );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1179,6 +1276,13 @@ namespace Anabatic {
|
|||
}
|
||||
|
||||
|
||||
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() );
|
||||
|
@ -1200,11 +1304,12 @@ namespace Anabatic {
|
|||
vector<RoutingPad*> rpM1s;
|
||||
Component* rpM2 = NULL;
|
||||
|
||||
forEach ( RoutingPad*, irp, net->getRoutingPads() ) {
|
||||
if (Session::getRoutingGauge()->getLayerDepth(irp->getLayer()) == 1)
|
||||
rpM2 = *irp;
|
||||
for ( RoutingPad* rp : net->getRoutingPads() ) {
|
||||
if ( Session::getRoutingGauge()->getLayerDepth(rp->getLayer())
|
||||
== 1 + Session::getRoutingGauge()->getFirstRoutingLayer())
|
||||
rpM2 = rp;
|
||||
else
|
||||
rpM1s.push_back( *irp );
|
||||
rpM1s.push_back( rp );
|
||||
}
|
||||
|
||||
if ((rpM1s.size() < 2) and not rpM2) {
|
||||
|
@ -2374,6 +2479,7 @@ namespace Anabatic {
|
|||
|
||||
Hook* sourceHook = NULL;
|
||||
AutoContact* sourceContact = NULL;
|
||||
uint64_t sourceFlags = NoFlags;
|
||||
RoutingPads routingPads = net->getRoutingPads();
|
||||
size_t degree = routingPads.getSize();
|
||||
|
||||
|
@ -2412,7 +2518,7 @@ namespace Anabatic {
|
|||
++connecteds;
|
||||
segmentFound = true;
|
||||
|
||||
setStartHook( anabatic, hook, NULL );
|
||||
setStartHook( anabatic, hook, NULL, NoFlags );
|
||||
if (getStateG() == 1) {
|
||||
if ( (lowestGCell == NULL) or (*getGCell() < *lowestGCell) ) {
|
||||
cdebug_log(145,0) << "Potential starting GCell " << getGCell() << endl;
|
||||
|
@ -2440,9 +2546,9 @@ namespace Anabatic {
|
|||
}
|
||||
cdebug_tabw(145,-1);
|
||||
|
||||
if (startHook == NULL) { setStartHook(anabatic,NULL,NULL).singleGCell(anabatic,net); cdebug_tabw(145,-1); return; }
|
||||
if (startHook == NULL) { setStartHook(anabatic,NULL,NULL,NoFlags).singleGCell(anabatic,net); cdebug_tabw(145,-1); return; }
|
||||
|
||||
setStartHook( anabatic, startHook, NULL );
|
||||
setStartHook( anabatic, startHook, NULL, NoFlags );
|
||||
cdebug_log(145,0) << endl;
|
||||
cdebug_log(145,0) << "--------~~~~=={o}==~~~~--------" << endl;
|
||||
cdebug_log(145,0) << endl;
|
||||
|
@ -2451,18 +2557,21 @@ namespace Anabatic {
|
|||
|
||||
sourceHook = _forks.getFrom ();
|
||||
sourceContact = _forks.getContact();
|
||||
sourceFlags = _forks.getFlags ();
|
||||
_forks.pop();
|
||||
|
||||
while ( sourceHook ) {
|
||||
setStartHook( anabatic, sourceHook, sourceContact );
|
||||
setStartHook( anabatic, sourceHook, sourceContact, sourceFlags );
|
||||
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();
|
||||
|
@ -2473,10 +2582,11 @@ namespace Anabatic {
|
|||
for ( ; iover != overconstraineds.end() ; ++iover ) {
|
||||
(*iover)->makeDogLeg( (*iover)->getAutoSource()->getGCell(), true );
|
||||
}
|
||||
Session::revalidate();
|
||||
#endif
|
||||
|
||||
Session::revalidate();
|
||||
fixSegments();
|
||||
Session::revalidate();
|
||||
cdebug_tabw(145,-1);
|
||||
|
||||
//DebugSession::close();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,643 @@
|
|||
// -*- 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,6 +62,10 @@ namespace Anabatic {
|
|||
NetBuilderM2::~NetBuilderM2 () { }
|
||||
|
||||
|
||||
string NetBuilderM2::getStyle ()
|
||||
{ return "2RL-"; }
|
||||
|
||||
|
||||
void NetBuilderM2::doRp_AutoContacts ( GCell* gcell
|
||||
, Component* rp
|
||||
, AutoContact*& source
|
||||
|
@ -187,7 +191,7 @@ namespace Anabatic {
|
|||
contact2 ->setFlags( CntFixed );
|
||||
|
||||
AutoSegment* fixed = AutoSegment::create( rpContact, contact1, Flags::Vertical );
|
||||
AutoSegment* dogleg = AutoSegment::create( contact1 , contact2, Flags::Horizontal );
|
||||
AutoSegment* dogleg = AutoSegment::create( contact1 , contact2, Flags::Horizontal|Flags::UseNonPref );
|
||||
fixed ->setFlags( AutoSegment::SegFixed );
|
||||
dogleg->setFlags( AutoSegment::SegFixed );
|
||||
|
||||
|
|
|
@ -67,6 +67,10 @@ namespace Anabatic {
|
|||
NetBuilderVH::~NetBuilderVH () { }
|
||||
|
||||
|
||||
string NetBuilderVH::getStyle ()
|
||||
{ return "VH,3RL+"; }
|
||||
|
||||
|
||||
void NetBuilderVH::doRp_AutoContacts ( GCell* gcell
|
||||
, Component* rp
|
||||
, AutoContact*& source
|
||||
|
@ -85,7 +89,6 @@ 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 );
|
||||
|
||||
|
@ -114,56 +117,8 @@ 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) and (gridPosition == 0)) ) {
|
||||
if ( (rpDepth != 0) or (sourcePosition == targetPosition) ) {
|
||||
map<Component*,AutoSegment*>::iterator irp = getRpLookup().find( rp );
|
||||
if (irp == getRpLookup().end()) {
|
||||
AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell
|
||||
|
@ -205,6 +160,10 @@ 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
|
||||
|
@ -223,31 +182,46 @@ namespace Anabatic {
|
|||
{
|
||||
cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl;
|
||||
|
||||
AutoContact* rpContactSource;
|
||||
AutoContact* rpContactTarget;
|
||||
AutoContact* rpContactSource = NULL;
|
||||
AutoContact* rpContactTarget = NULL;
|
||||
const Layer* rpLayer = rp->getLayer();
|
||||
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
|
||||
|
||||
flags |= checkRoutingPadSize( rp );
|
||||
|
||||
doRp_AutoContacts( gcell, rp, rpContactSource, rpContactTarget, flags );
|
||||
|
||||
if (rpDepth % 2 == 0) { // RP should be vertical (M1, M3).
|
||||
if (not (flags & (HAccess|HAccessEW))) {
|
||||
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical );
|
||||
AutoSegment::create( subContact1, subContact2, Flags::Horizontal );
|
||||
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical , rpDepth+2 );
|
||||
AutoSegment::create( subContact1, subContact2, Flags::Horizontal, rpDepth+1 );
|
||||
rpContactSource = subContact2;
|
||||
} else {
|
||||
if (flags & VSmall) {
|
||||
AutoContact* subContact1 = NULL;
|
||||
if (flags & HAccessEW)
|
||||
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
else
|
||||
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) );
|
||||
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
|
||||
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical );
|
||||
rpContactSource = subContact1;
|
||||
}
|
||||
}
|
||||
} else { // RP should be horizontal (M2).
|
||||
if (flags & (HAccess|HAccessEW)) {
|
||||
AutoContact* subContact1 = NULL;
|
||||
if (flags & HAccessEW)
|
||||
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
else
|
||||
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
|
||||
|
||||
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical, rpDepth+1 );
|
||||
rpContactSource = subContact1;
|
||||
}
|
||||
}
|
||||
|
||||
cdebug_tabw(145,-1);
|
||||
|
||||
|
|
|
@ -83,6 +83,7 @@ namespace Anabatic {
|
|||
if (net->getType() == Net::Type::GROUND) continue;
|
||||
// Don't skip the clock.
|
||||
|
||||
vector<Pin*> pins;
|
||||
vector<Segment*> segments;
|
||||
vector<Contact*> contacts;
|
||||
|
||||
|
@ -92,7 +93,11 @@ namespace Anabatic {
|
|||
size_t rpCount = 0;
|
||||
|
||||
for( Component* component : net->getComponents() ) {
|
||||
if (dynamic_cast<Pin *>(component)) continue;
|
||||
Pin* pin = dynamic_cast<Pin *>( component );
|
||||
if (pin) {
|
||||
pins.push_back( pin );
|
||||
continue;
|
||||
}
|
||||
if (dynamic_cast<Plug*>(component)) continue;
|
||||
|
||||
const RegularLayer* layer = dynamic_cast<const RegularLayer*>(component->getLayer());
|
||||
|
@ -138,6 +143,12 @@ namespace Anabatic {
|
|||
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) {
|
||||
|
@ -168,6 +179,15 @@ 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)
|
||||
|
@ -213,6 +233,10 @@ namespace Anabatic {
|
|||
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/Constants.h"
|
||||
#include "anabatic/PyStyleFlags.h"
|
||||
|
||||
|
||||
namespace Anabatic {
|
||||
|
@ -76,6 +76,10 @@ extern "C" {
|
|||
{
|
||||
cdebug_log(32,0) << "PyInit_Anabatic()" << endl;
|
||||
|
||||
PyStyleFlags_LinkPyType();
|
||||
|
||||
PYTYPE_READY( StyleFlags );
|
||||
|
||||
PyObject* module = PyModule_Create( &PyAnabatic_ModuleDef );
|
||||
if (module == NULL) {
|
||||
cerr << "[ERROR]\n"
|
||||
|
@ -83,6 +87,9 @@ extern "C" {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
Py_INCREF( &PyTypeStyleFlags );
|
||||
PyModule_AddObject( module, "StyleFlags", (PyObject*)&PyTypeStyleFlags );
|
||||
|
||||
PyObject* dictionnary = PyModule_GetDict(module);
|
||||
PyObject* constant;
|
||||
|
||||
|
@ -93,6 +100,7 @@ extern "C" {
|
|||
LoadObjectConstant( dictionnary,EngineLayerAssignNoGlobalM2V,"EngineLayerAssignNoGlobalM2V" );
|
||||
LoadObjectConstant( dictionnary,EngineNoNetLayerAssign ,"EngineNoNetLayerAssign" );
|
||||
|
||||
PyStyleFlags_postModuleInit();
|
||||
return module;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
// -*- 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.
|
||||
|
|
@ -215,6 +215,7 @@ 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 );
|
||||
|
@ -222,6 +223,7 @@ namespace Anabatic {
|
|||
_anabatic->_computeNetOptimals ( net );
|
||||
//_anabatic->_computeNetTerminals ( net );
|
||||
}
|
||||
_anabatic->enableCanonize();
|
||||
_canonize ();
|
||||
|
||||
AutoSegment* segment = NULL;
|
||||
|
@ -410,14 +412,25 @@ 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(); }
|
||||
|
||||
|
|
|
@ -1,646 +0,0 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2008-2018, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
// | A n a b a t i c - Routing Toolbox |
|
||||
// | |
|
||||
// | Author : Jean-Paul CHAPUT |
|
||||
// | E-mail : Jean-Paul.Chaput@lip6.fr |
|
||||
// | =============================================================== |
|
||||
// | C++ 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
|
|
@ -45,6 +45,7 @@ namespace Anabatic {
|
|||
using Hurricane::NetRoutingState;
|
||||
using CRL::ToolEngine;
|
||||
|
||||
class NetBuilder;
|
||||
class AnabaticEngine;
|
||||
|
||||
|
||||
|
@ -191,23 +192,33 @@ namespace Anabatic {
|
|||
|
||||
class AnabaticEngine : public ToolEngine {
|
||||
public:
|
||||
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.
|
||||
};
|
||||
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.
|
||||
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* );
|
||||
|
@ -227,6 +238,8 @@ 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;
|
||||
|
@ -266,6 +279,9 @@ namespace Anabatic {
|
|||
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 );
|
||||
|
@ -331,12 +347,15 @@ 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;
|
||||
|
@ -347,6 +366,7 @@ namespace Anabatic {
|
|||
CellViewer* _viewer;
|
||||
Flags _flags;
|
||||
int _stamp;
|
||||
uint32_t _routingMode;
|
||||
uint64_t _densityMode;
|
||||
AutoSegmentLut _autoSegmentLut;
|
||||
AutoContactLut _autoContactLut;
|
||||
|
@ -356,6 +376,13 @@ namespace Anabatic {
|
|||
};
|
||||
|
||||
|
||||
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; }
|
||||
|
@ -380,10 +407,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 DbU::Unit AnabaticEngine::getAntennaGateMaxWL () const { return getConfiguration()->getAntennaGateMaxWL(); }
|
||||
inline DbU::Unit AnabaticEngine::getAntennaDiodeMaxWL () const { return getConfiguration()->getAntennaDiodeMaxWL(); }
|
||||
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(); }
|
||||
|
@ -399,6 +429,8 @@ 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 )
|
||||
{
|
||||
|
|
|
@ -14,9 +14,7 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef ANABATIC_AUTOHORIZONTAL_H
|
||||
#define ANABATIC_AUTOHORIZONTAL_H
|
||||
|
||||
#pragma once
|
||||
#include "hurricane/Horizontal.h"
|
||||
#include "anabatic/AutoSegment.h"
|
||||
|
||||
|
@ -91,6 +89,3 @@ namespace Anabatic {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::AutoHorizontal);
|
||||
|
||||
|
||||
#endif // ANABATIC_AUTOHORIZONTAL_H
|
||||
|
|
|
@ -14,9 +14,8 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef ANABATIC_AUTOSEGMENT_H
|
||||
#define ANABATIC_AUTOSEGMENT_H
|
||||
|
||||
#pragma once
|
||||
#include <tuple>
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
|
@ -39,6 +38,7 @@ namespace Hurricane {
|
|||
|
||||
namespace Anabatic {
|
||||
|
||||
using std::tuple;
|
||||
using std::array;
|
||||
using std::set;
|
||||
using std::cerr;
|
||||
|
@ -109,6 +109,7 @@ namespace Anabatic {
|
|||
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;
|
||||
|
@ -202,6 +203,7 @@ namespace Anabatic {
|
|||
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;
|
||||
|
@ -216,7 +218,6 @@ namespace Anabatic {
|
|||
inline bool isSpinBottom () const;
|
||||
inline bool isSpinTopOrBottom () const;
|
||||
inline bool isReduced () const;
|
||||
bool isUnderMinLength () const;
|
||||
inline bool isStrap () const;
|
||||
inline bool isDogleg () const;
|
||||
inline bool isUnbound () const;
|
||||
|
@ -227,7 +228,7 @@ namespace Anabatic {
|
|||
inline bool isUnsetAxis () const;
|
||||
inline bool isSlackened () const;
|
||||
inline bool isUserDefined () const;
|
||||
bool isMiddleStack () const;
|
||||
bool isNearMinArea () const;
|
||||
bool isReduceCandidate () const;
|
||||
bool isUTurn () const;
|
||||
inline bool isAnalog () const;
|
||||
|
@ -340,8 +341,8 @@ namespace Anabatic {
|
|||
bool bloatStackedStrap ();
|
||||
bool reduce ( Flags flags=Flags::WithPerpands );
|
||||
bool raise ();
|
||||
bool expandToMinLength ( Interval );
|
||||
bool unexpandToMinLength ();
|
||||
void expandToMinLength ( Interval );
|
||||
void unexpandToMinLength ();
|
||||
// Canonical Modifiers.
|
||||
AutoSegment* canonize ( Flags flags=Flags::NoFlags );
|
||||
virtual void invalidate ( Flags flags=Flags::Propagate );
|
||||
|
@ -468,7 +469,8 @@ namespace Anabatic {
|
|||
);
|
||||
static void getTopologicalInfos ( AutoSegment* seed
|
||||
, vector<AutoSegment*>& collapseds
|
||||
, vector<AutoSegment*>& perpandiculars
|
||||
, vector< tuple<AutoSegment*,Flags> >&
|
||||
perpandiculars
|
||||
, DbU::Unit& leftBound
|
||||
, DbU::Unit& rightBound
|
||||
);
|
||||
|
@ -536,6 +538,7 @@ namespace Anabatic {
|
|||
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); }
|
||||
|
@ -667,7 +670,8 @@ namespace Anabatic {
|
|||
cdebug_log(145,0) << "getTerminalCount() - " << seed << endl;
|
||||
|
||||
vector<AutoSegment*> collapseds;
|
||||
vector<AutoSegment*> perpandiculars;
|
||||
vector< tuple<AutoSegment*,Flags> >
|
||||
perpandiculars;
|
||||
DbU::Unit leftBound;
|
||||
DbU::Unit rightBound;
|
||||
|
||||
|
@ -703,6 +707,3 @@ namespace Anabatic {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::AutoSegment);
|
||||
|
||||
|
||||
# endif // ANABATIC_AUTOSEGMENT_H
|
||||
|
|
|
@ -14,9 +14,7 @@
|
|||
// +-----------------------------------------------------------------+
|
||||
|
||||
|
||||
#ifndef ANABATIC_AUTOVERTICAL_H
|
||||
#define ANABATIC_AUTOVERTICAL_H
|
||||
|
||||
#pragma once
|
||||
#include "hurricane/Vertical.h"
|
||||
#include "anabatic/AutoSegment.h"
|
||||
|
||||
|
@ -91,6 +89,3 @@ namespace Anabatic {
|
|||
|
||||
|
||||
INSPECTOR_P_SUPPORT(Anabatic::AutoVertical);
|
||||
|
||||
|
||||
#endif // ANABATIC_AUTOHORIZONTAL_H
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// -*- mode: C++; explicit-buffer-name: "Configuration.h<anabatic>" -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2016-2018, All Rights Reserved
|
||||
// Copyright (c) Sorbonne Université 2016-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -66,8 +66,11 @@ namespace Anabatic {
|
|||
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;
|
||||
|
@ -132,6 +135,8 @@ 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;
|
||||
|
@ -146,6 +151,8 @@ 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;
|
||||
|
@ -169,6 +176,8 @@ namespace Anabatic {
|
|||
};
|
||||
|
||||
|
||||
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; }
|
||||
|
@ -193,6 +202,8 @@ namespace Anabatic {
|
|||
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.
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
namespace Anabatic {
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Class : "Anabatic::Flags".
|
||||
|
||||
class Flags : public Hurricane::BaseFlags {
|
||||
public:
|
||||
static const BaseFlags NoFlags ; // = 0;
|
||||
|
@ -51,6 +54,7 @@ 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 GlobalEstimated ; // = (1 << 6);
|
||||
|
@ -106,6 +110,7 @@ namespace Anabatic {
|
|||
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& );
|
||||
|
@ -120,6 +125,39 @@ 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
|
||||
};
|
||||
|
||||
|
|
|
@ -259,6 +259,7 @@ namespace Anabatic {
|
|||
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* );
|
||||
|
|
|
@ -47,31 +47,39 @@ namespace Anabatic {
|
|||
|
||||
class ForkStack {
|
||||
public:
|
||||
inline void push ( Hook* from, AutoContact* contact );
|
||||
inline void push ( Hook* from, AutoContact* contact, uint64_t flags );
|
||||
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;
|
||||
inline Element ( Hook* from, AutoContact* contact );
|
||||
uint64_t _flags;
|
||||
inline Element ( Hook* from, AutoContact* contact, uint64_t flags );
|
||||
};
|
||||
private:
|
||||
list<Element> _stack;
|
||||
};
|
||||
|
||||
|
||||
inline ForkStack::Element::Element ( Hook* from, AutoContact* contact ) : _from(from), _contact(contact) {}
|
||||
inline ForkStack::Element::Element ( Hook* from, AutoContact* contact, uint64_t flags ) : _from(from), _contact(contact), _flags(flags) {}
|
||||
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 )
|
||||
inline void ForkStack::push ( Hook* from, AutoContact* contact, uint64_t flags )
|
||||
{
|
||||
cdebug_log(145,0) << " Stacking " << from << " + " << contact << endl;
|
||||
_stack.push_back( Element(from,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) );
|
||||
}
|
||||
|
||||
|
||||
|
@ -99,17 +107,18 @@ namespace Anabatic {
|
|||
, 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 = 0x00000001
|
||||
, Global_Horizontal_End = 0x00000002
|
||||
, Global_Horizontal = 0x00000004
|
||||
, Global_Vertical = 0x00000008
|
||||
, Global_Turn = 0x00000010
|
||||
, Global_Fork = 0x00000020
|
||||
, Global_Fixed = 0x00000040
|
||||
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)
|
||||
, Global_End = Global_Vertical_End | Global_Horizontal_End
|
||||
, Global_Split = Global_Horizontal | Global_Vertical | Global_Fork
|
||||
};
|
||||
|
@ -148,14 +157,16 @@ namespace Anabatic {
|
|||
NetBuilder ();
|
||||
virtual ~NetBuilder ();
|
||||
void clear ();
|
||||
inline bool isTwoMetals () const;
|
||||
inline bool isStrictChannel () const;
|
||||
inline bool isUpperMetalRp () 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 );
|
||||
, AutoContact* sourceContact=NULL
|
||||
, uint64_t sourceFlags=0 );
|
||||
void construct ();
|
||||
inline unsigned int getStateG () const;
|
||||
inline UConnexity getConnexity () const;
|
||||
|
@ -169,6 +180,8 @@ 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 ();
|
||||
|
@ -187,6 +200,7 @@ 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* );
|
||||
|
@ -194,6 +208,7 @@ 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 );
|
||||
|
@ -221,6 +236,7 @@ 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 ();
|
||||
|
@ -329,6 +345,8 @@ namespace Anabatic {
|
|||
, 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 )
|
||||
|
@ -371,14 +389,13 @@ namespace Anabatic {
|
|||
map<Component*,AutoSegment*> _routingPadAutoSegments;
|
||||
vector<AutoSegment*> _toFixSegments;
|
||||
unsigned int _degree;
|
||||
bool _isTwoMetals;
|
||||
|
||||
// Sort classes.
|
||||
public:
|
||||
bool _isStrictChannel;
|
||||
uint64_t _sourceFlags;
|
||||
uint64_t _flags;
|
||||
};
|
||||
|
||||
|
||||
inline bool NetBuilder::isTwoMetals () const { return _isTwoMetals; }
|
||||
inline bool NetBuilder::isStrictChannel () const { return _isStrictChannel; }
|
||||
inline AnabaticEngine* NetBuilder::getAnabatic () const { return _anabatic; }
|
||||
inline unsigned int NetBuilder::getDegree () const { return _degree; }
|
||||
inline NetBuilder::UConnexity NetBuilder::getConnexity () const { return _connexity; }
|
||||
|
@ -394,6 +411,8 @@ namespace Anabatic {
|
|||
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; }
|
||||
|
@ -403,6 +422,7 @@ 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; }
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// -*- C++ -*-
|
||||
//
|
||||
// This file is part of the Coriolis Software.
|
||||
// Copyright (c) UPMC 2008-2018, All Rights Reserved
|
||||
// Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -13,9 +13,7 @@
|
|||
// | C++ Header : "./anabatic/NetBuilderHV.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
#ifndef ANABATIC_NET_BUILDER_HV_H
|
||||
#define ANABATIC_NET_BUILDER_HV_H
|
||||
|
||||
#pragma once
|
||||
#include "anabatic/NetBuilder.h"
|
||||
|
||||
|
||||
|
@ -30,9 +28,10 @@ namespace Anabatic {
|
|||
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_AccessNorthPin ( GCell*, RoutingPad* );
|
||||
AutoContact* doRp_AccessNorthSouthPin ( GCell*, RoutingPad* );
|
||||
AutoContact* doRp_AccessEastWestPin ( GCell*, RoutingPad* );
|
||||
private:
|
||||
virtual bool _do_1G_1M1 ();
|
||||
|
@ -54,6 +53,8 @@ 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 ();
|
||||
|
@ -67,5 +68,3 @@ namespace Anabatic {
|
|||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
||||
#endif // ANABATIC_NET_BUILDER_HV_H
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
// -*- 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) UPMC 2008-2018, All Rights Reserved
|
||||
// Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -13,9 +13,7 @@
|
|||
// | C++ Header : "./anabatic/NetBuilderM2.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
#ifndef ANABATIC_NET_BUILDER_M2_H
|
||||
#define ANABATIC_NET_BUILDER_M2_H
|
||||
|
||||
#pragma once
|
||||
#include "anabatic/NetBuilder.h"
|
||||
|
||||
|
||||
|
@ -29,6 +27,7 @@ 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:
|
||||
|
@ -53,5 +52,3 @@ 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) UPMC 2017-2018, All Rights Reserved
|
||||
// Copyright (c) Sorbonne Université 2017-2022, All Rights Reserved
|
||||
//
|
||||
// +-----------------------------------------------------------------+
|
||||
// | C O R I O L I S |
|
||||
|
@ -13,9 +13,7 @@
|
|||
// | C++ Header : "./anabatic/NetBuilderVH.h" |
|
||||
// +-----------------------------------------------------------------+
|
||||
|
||||
#ifndef ANABATIC_NET_BUILDER_VH_H
|
||||
#define ANABATIC_NET_BUILDER_VH_H
|
||||
|
||||
#pragma once
|
||||
#include "anabatic/NetBuilder.h"
|
||||
|
||||
|
||||
|
@ -29,6 +27,7 @@ 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:
|
||||
|
@ -50,5 +49,3 @@ namespace Anabatic {
|
|||
|
||||
|
||||
} // Anabatic namespace.
|
||||
|
||||
#endif // ANABATIC_NET_BUILDER_VH_H
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
// -*- 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.
|
|
@ -76,10 +76,12 @@ 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 ();
|
||||
|
@ -120,6 +122,8 @@ namespace Anabatic {
|
|||
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 );
|
||||
|
@ -267,6 +271,8 @@ namespace Anabatic {
|
|||
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); }
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
set(CMAKE_LEGACY_CYGWIN_WIN32 0)
|
||||
project(Bootstrap)
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.0)
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(ignoreVariables USE_LIBBFD "${BUILD_DOC} ${CMAKE_INSTALL_DIR}")
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
|||
|
||||
list(INSERT CMAKE_MODULE_PATH 0 "${Bootstrap_SOURCE_DIR}/cmake_modules/")
|
||||
find_package(Bootstrap REQUIRED)
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development )
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development.Module )
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
print_cmake_module_path()
|
||||
|
||||
|
@ -32,3 +32,10 @@
|
|||
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,7 +1,26 @@
|
|||
#!/bin/bash
|
||||
|
||||
srcDir=${HOME}/coriolis-2.x/src/alliance/alliance/src
|
||||
commonRoot=${HOME}/coriolis-2.x/Linux.el7_64/Release.Shared
|
||||
#. /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
|
||||
|
||||
|
|
|
@ -21,11 +21,12 @@ projects = [
|
|||
, "etesian"
|
||||
, "anabatic"
|
||||
, "katana"
|
||||
, "knik"
|
||||
, "katabatic"
|
||||
, "kite"
|
||||
, "equinox"
|
||||
, "solstice"
|
||||
#, "knik"
|
||||
#, "katabatic"
|
||||
#, "kite"
|
||||
#, "equinox"
|
||||
#, "solstice"
|
||||
, "tramontana"
|
||||
, "oroshi"
|
||||
, "bora"
|
||||
, "karakaze"
|
||||
|
|
|
@ -35,12 +35,13 @@ 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._qt5 = False
|
||||
self._qt4 = False
|
||||
self._openmp = False
|
||||
self._enableShared = "ON"
|
||||
self._enableDoc = "OFF"
|
||||
|
@ -62,6 +63,7 @@ class Builder:
|
|||
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
|
||||
|
@ -71,7 +73,7 @@ class Builder:
|
|||
elif attribute == "llvmtoolset":
|
||||
self._llvmtoolset = value
|
||||
elif attribute == "bfd": self._bfd = value
|
||||
elif attribute == "qt5": self._qt5 = value
|
||||
elif attribute == "qt4": self._qt4 = value
|
||||
elif attribute == "openmp": self._openmp = value
|
||||
elif attribute == "enableDoc": self._enableDoc = value
|
||||
elif attribute == "enableShared": self._enableShared = value
|
||||
|
@ -175,8 +177,9 @@ class Builder:
|
|||
#, "-D", "BOOST_LIBRARYDIR:STRING=/usr/lib64/boost169"
|
||||
]
|
||||
if self._bfd: command += [ "-D", "USE_LIBBFD:STRING=%s" % self._bfd ]
|
||||
if self._qt5: command += [ "-D", "WITH_QT5:STRING=TRUE" ]
|
||||
if self._qt4: command += [ "-D", "WITH_QT4: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
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
# -*- mode:Python -*-
|
||||
#
|
||||
# This file is part of the Coriolis Software.
|
||||
# Copyright (c) Sorbonne Université 2012-2021, All Rights Reserved
|
||||
# Copyright (c) Sorbonne Université 2012-2023, All Rights Reserved
|
||||
#
|
||||
# +-----------------------------------------------------------------+
|
||||
# | C O R I O L I S |
|
||||
|
@ -122,7 +122,7 @@ class CompileWidget ( QWidget ):
|
|||
#if self.options.svnStatus: command += [ '--svn-update' ]
|
||||
if self.options.enableDoc: command += [ '--doc' ]
|
||||
if self.options.devtoolset: command += [ '--devtoolset-8' ]
|
||||
if self.options.qt5: command += [ '--qt5' ]
|
||||
if self.options.qt4: command += [ '--qt4' ]
|
||||
if self.options.noCache: command += [ '--no-cache' ]
|
||||
if self.options.rmBuild: command += [ '--rm-build' ]
|
||||
if self.options.verbose: command += [ '--verbose' ]
|
||||
|
|
|
@ -122,6 +122,7 @@ class Configuration ( object ):
|
|||
|
||||
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,7 +146,10 @@ class Configuration ( object ):
|
|||
uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE )
|
||||
lines = uname.stdout.readlines()
|
||||
osLine = lines[0].decode( 'ascii' )
|
||||
if self._osSlsoc7x_64.match(osLine):
|
||||
if self._osEL9.match(osLine):
|
||||
self._osType = "Linux.el9"
|
||||
self._libSuffix = "64"
|
||||
elif self._osSlsoc7x_64.match(osLine):
|
||||
self._osType = "Linux.el7_64"
|
||||
self._libSuffix = "64"
|
||||
elif self._osSlsoc6x_64.match(osLine):
|
||||
|
|
|
@ -57,7 +57,7 @@ class OptionsWidget ( QWidget ):
|
|||
self._make = QCheckBox( 'Build' )
|
||||
self._enableDoc = QCheckBox( 'Build Documentation' )
|
||||
self._devtoolset = QCheckBox( 'Build with devtoolset 8' )
|
||||
self._qt5 = QCheckBox( 'Build with Qt 5 (Qt 4 default)' )
|
||||
self._qt4 = QCheckBox( 'Build with Qt 4 (Qt 5 default)' )
|
||||
self._noCache = QCheckBox( 'Remove previous CMake cache' )
|
||||
self._rmBuild = QCheckBox( 'Cleanup Build Directory' )
|
||||
self._verbose = QCheckBox( 'Display Compiler Commands' )
|
||||
|
@ -83,7 +83,7 @@ class OptionsWidget ( QWidget ):
|
|||
vLayout.addWidget( self._buildMode )
|
||||
vLayout.addWidget( self._enableDoc )
|
||||
vLayout.addWidget( self._devtoolset )
|
||||
vLayout.addWidget( self._qt5 )
|
||||
vLayout.addWidget( self._qt4 )
|
||||
vLayout.addWidget( self._noCache )
|
||||
vLayout.addWidget( self._rmBuild )
|
||||
vLayout.addStretch()
|
||||
|
@ -121,7 +121,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 _getQt5 ( self ): return self._qt5.isChecked()
|
||||
def _getQt4 ( self ): return self._qt4.isChecked()
|
||||
def _getNoCache ( self ): return self._noCache.isChecked()
|
||||
def _getRmBuild ( self ): return self._rmBuild.isChecked()
|
||||
def _getVerbose ( self ): return self._verbose.isChecked()
|
||||
|
@ -134,7 +134,7 @@ class OptionsWidget ( QWidget ):
|
|||
make = property( _getMake )
|
||||
enableDoc = property( _getEnableDoc )
|
||||
devtoolset = property( _getDevtoolset )
|
||||
qt5 = property( _getQt5 )
|
||||
qt4 = property( _getQt4 )
|
||||
noCache = property( _getNoCache )
|
||||
rmBuild = property( _getRmBuild )
|
||||
verbose = property( _getVerbose )
|
||||
|
@ -146,7 +146,7 @@ class OptionsWidget ( QWidget ):
|
|||
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._qt5 .setChecked( bool(settings.value('builder/qt5' )) )
|
||||
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' )) )
|
||||
|
@ -169,7 +169,7 @@ 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/qt5' , self._qt5 .isChecked() )
|
||||
settings.setValue('builder/qt4' , self._qt4 .isChecked() )
|
||||
settings.setValue('builder/buildMode' , self._buildMode .currentText() )
|
||||
settings.setValue('builder/noCache' , self._noCache .isChecked() )
|
||||
settings.setValue('builder/rmBuild' , self._rmBuild .isChecked() )
|
||||
|
|
|
@ -62,6 +62,7 @@ def checkCMake ():
|
|||
|
||||
def guessOs ():
|
||||
libDir = 'lib'
|
||||
osEL9 = re.compile (".*Linux.*(el9|al9).*x86_64.*")
|
||||
osSlsoc7x_64 = re.compile (".*Linux.*(el7|slsoc7).*x86_64.*")
|
||||
osSlsoc6x_64 = re.compile (".*Linux.*(el6|slsoc6).*x86_64.*")
|
||||
osSlsoc6x = re.compile (".*Linux.*(el6|slsoc6).*")
|
||||
|
@ -85,7 +86,10 @@ def guessOs ():
|
|||
uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE )
|
||||
lines = uname.stdout.readlines()
|
||||
line = lines[0].decode( 'ascii' )
|
||||
if osSlsoc7x_64.match(line):
|
||||
if osEL9.match(line):
|
||||
osType = "Linux.el9"
|
||||
libDir = "lib64"
|
||||
elif osSlsoc7x_64.match(line):
|
||||
osType = "Linux.el7_64"
|
||||
libDir = "lib64"
|
||||
elif osSlsoc6x_64.match(line):
|
||||
|
@ -202,11 +206,12 @@ parser.add_option ( "--rm-build" , action="store_true" ,
|
|||
parser.add_option ( "--macports" , action="store_true" , dest="macports" , help="Build against MacPorts." )
|
||||
parser.add_option ( "--devtoolset" , action="store" , type="int" , dest="devtoolset" , help="Build against TUV Dev Toolset N." )
|
||||
parser.add_option ( "--llvm-toolset" , action="store" , type="int" , dest="llvmtoolset" , help="Build against TUV Dev LLVM Toolset N." )
|
||||
parser.add_option ( "--qt5" , action="store_true" , dest="qt5" , help="Build against Qt 5 (default: Qt 4)." )
|
||||
parser.add_option ( "--bfd" , action="store_true" , dest="bfd" , help="Build against Qt 5 (default: Qt 4)." )
|
||||
parser.add_option ( "--qt4" , action="store_true" , dest="qt4" , help="Build against Qt 4 (default: Qt 5)." )
|
||||
parser.add_option ( "--bfd" , action="store_true" , dest="bfd" , help="Link against BFD to enable stack trace display." )
|
||||
parser.add_option ( "--openmp" , action="store_true" , dest="openmp" , help="Enable the use of OpenMP in Gcc." )
|
||||
parser.add_option ( "--ninja" , action="store_true" , dest="ninja" , help="Use Ninja instead of UNIX Makefile." )
|
||||
parser.add_option ( "--clang" , action="store_true" , dest="clang" , help="Force use of Clang C/C++ compiler instead of system default." )
|
||||
parser.add_option ( "--manylinux" , action="store_true" , dest="manylinux" , help="Build target is manylinux (PyPY)." )
|
||||
parser.add_option ( "--make" , action="store" , type="string", dest="makeArguments" , help="Arguments to pass to make (ex: \"-j4 install\")." )
|
||||
parser.add_option ( "--project" , action="append" , type="string", dest="projects" , help="The name of a project to build (may appears any number of time)." )
|
||||
parser.add_option ( "-t", "--tool" , action="append" , type="string", dest="tools" , help="The name of a tool to build (may appears any number of time)." )
|
||||
|
@ -277,7 +282,8 @@ else:
|
|||
if options.devtoolset: builder.devtoolset = options.devtoolset
|
||||
if options.llvmtoolset: builder.llvmtoolset = options.llvmtoolset
|
||||
if options.bfd: builder.bfd = "ON"
|
||||
if options.qt5: builder.qt5 = True
|
||||
if options.qt4: builder.qt4 = True
|
||||
if options.manylinux: builder.manylinux = True
|
||||
if options.openmp: builder.openmp = True
|
||||
if options.makeArguments: builder.makeArguments = options.makeArguments
|
||||
#if options.svnMethod: builder.svnMethod = options.svnMethod
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
FindQwt.cmake
|
||||
FindSphinx.cmake
|
||||
FindPelican.cmake
|
||||
FindCOLOQUINTE.cmake
|
||||
GetGitRevisionDescription.cmake
|
||||
GetGitRevisionDescription.cmake.in
|
||||
)
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
if(COMMAND CMAKE_POLICY)
|
||||
cmake_policy(SET CMP0003 NEW)
|
||||
cmake_policy(SET CMP0005 NEW)
|
||||
cmake_policy(SET CMP0079 NEW)
|
||||
cmake_policy(SET CMP0022 NEW)
|
||||
cmake_policy(SET CMP0060 NEW)
|
||||
cmake_policy(SET CMP0095 NEW)
|
||||
#if(NOT (CMAKE_VERSION VERSION_LESS 2.8.0))
|
||||
# cmake_policy(SET CMP0014 OLD)
|
||||
#endif()
|
||||
|
@ -79,22 +83,27 @@
|
|||
#set(DEBUG_FLAGS "-g -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC")
|
||||
set(DEBUG_FLAGS "-g")
|
||||
if(CYGWIN)
|
||||
set(ADDTIONAL_FLAGS "-D_GLIBCXX_USE_C99")
|
||||
set(CXX_STANDARD "gnu++11")
|
||||
set(ADDITIONAL_FLAGS "-D_GLIBCXX_USE_C99")
|
||||
set(CXX_STANDARD "gnu++17")
|
||||
else()
|
||||
set(ADDTIONAL_FLAGS "")
|
||||
set(CXX_STANDARD "c++11")
|
||||
set(ADDITIONAL_FLAGS "-Wl,--no-undefined")
|
||||
set(CXX_STANDARD "c++17")
|
||||
endif()
|
||||
#set(CMAKE_C_FLAGS_DEBUG " -Wall -fsanitize=address ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C Compiler Debug options." FORCE)
|
||||
set(CMAKE_C_FLAGS_DEBUG " -Wall ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C Compiler Debug options." FORCE)
|
||||
set(CMAKE_C_FLAGS_RELEASE " -Wall -O2 ${ADDTIONAL_FLAGS} -DNDEBUG" CACHE STRING "C Compiler Release options." FORCE)
|
||||
#set(CMAKE_C_FLAGS_RELEASE " -Wall -fsanitize=address ${ADDTIONAL_FLAGS} -DNDEBUG" CACHE STRING "C Compiler Release options." FORCE)
|
||||
#set(CMAKE_CXX_FLAGS_DEBUG "-std=${CXX_STANDARD} -Wall -fsanitize=address ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C++ Compiler Debug options." FORCE)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-std=${CXX_STANDARD} -Wall ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C++ Compiler Debug options." FORCE)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-std=${CXX_STANDARD} -Wall -O2 ${ADDTIONAL_FLAGS} -DNDEBUG" CACHE STRING "C++ Compiler Release options." FORCE)
|
||||
#set(CMAKE_CXX_FLAGS_RELEASE "-std=${CXX_STANDARD} -Wall -fsanitize=address ${ADDTIONAL_FLAGS} -DNDEBUG" CACHE STRING "C++ Compiler Release options." FORCE)
|
||||
#set(CMAKE_C_FLAGS_DEBUG " -Wall -fsanitize=address ${ADDITIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C Compiler Debug options." FORCE)
|
||||
set(CMAKE_C_FLAGS_DEBUG " -Wall ${ADDITIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C Compiler Debug options." FORCE)
|
||||
set(CMAKE_C_FLAGS_RELEASE " -Wall -O2 ${ADDITIONAL_FLAGS} -DNDEBUG" CACHE STRING "C Compiler Release options." FORCE)
|
||||
#set(CMAKE_C_FLAGS_RELEASE " -Wall -fsanitize=address ${ADDITIONAL_FLAGS} -DNDEBUG" CACHE STRING "C Compiler Release options." FORCE)
|
||||
#set(CMAKE_CXX_FLAGS_DEBUG "-std=${CXX_STANDARD} -Wall -fsanitize=address ${ADDITIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C++ Compiler Debug options." FORCE)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "-std=${CXX_STANDARD} -Wall ${ADDITIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C++ Compiler Debug options." FORCE)
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-std=${CXX_STANDARD} -Wall -O2 ${ADDITIONAL_FLAGS} -DNDEBUG" CACHE STRING "C++ Compiler Release options." FORCE)
|
||||
#set(CMAKE_CXX_FLAGS_RELEASE "-std=${CXX_STANDARD} -Wall -fsanitize=address ${ADDITIONAL_FLAGS} -DNDEBUG" CACHE STRING "C++ Compiler Release options." FORCE)
|
||||
|
||||
|
||||
if ( NOT CMAKE_BUILD_TYPE )
|
||||
message( "Build Type not set, defaulting to Debug..." )
|
||||
set( CMAKE_BUILD_TYPE Debug )
|
||||
endif()
|
||||
|
||||
#
|
||||
# Adds to the CMAKE_MODULE_PATH directories guesseds from project
|
||||
# environment variables <PROJECT>_USER_TOP and <PROJECT>_TOP.
|
||||
|
@ -131,7 +140,7 @@
|
|||
# Build <PROJECT>_INCLUDE_DIR & <PROJECT>_LIBRARIES and sets up <PROJECT>_FOUND
|
||||
# Usage: set_library_path(<PROJECT> <library>)
|
||||
#
|
||||
# May be used any number of time on the same <PROJECT> to create a list of
|
||||
#PYTHON_NEW May be used any number of time on the same <PROJECT> to create a list of
|
||||
# <library>.
|
||||
#
|
||||
macro(set_libraries_path configname library)
|
||||
|
@ -148,7 +157,14 @@
|
|||
set(${configname}_FOUND "NOTFOUND")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
#
|
||||
# sets that a library is expected to have unresolved symbols
|
||||
# Usage: set_library_unresolved_symbols(<PROJECT>)
|
||||
#
|
||||
# Should be used before set_libraries_path.
|
||||
macro(set_has_unresolved_symbols configname)
|
||||
set(${configname}_LIBRARIES "-Wl,--unresolved-symbols=ignore-all" ${${configname}_LIBRARIES})
|
||||
endmacro()
|
||||
|
||||
#
|
||||
# Checks if a set of libraries has been found, could be blocking or not.
|
||||
|
@ -207,11 +223,35 @@
|
|||
endmacro(setup_boost)
|
||||
|
||||
|
||||
#
|
||||
# Setup Python, select detection depending on USE_MANYLINUX.
|
||||
#
|
||||
macro(setup_python)
|
||||
set(pydevelArg "Development")
|
||||
|
||||
if (USE_MANYLINUX)
|
||||
message(STATUS "Build for manylinux")
|
||||
set(pydevelArg "Development.Module")
|
||||
endif()
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter ${pydevelArg} )
|
||||
endmacro()
|
||||
|
||||
|
||||
#
|
||||
# Find Qt, the union of all the modules we need for the whole project.
|
||||
#
|
||||
macro(setup_qt)
|
||||
if(WITH_QT5)
|
||||
if(WITH_QT4)
|
||||
message(STATUS "Attempt to find Qt 4...")
|
||||
# For Qt4.
|
||||
#set(QT_USE_QTXML "true")
|
||||
set(QT_USE_QTSVG "true")
|
||||
find_package(Qt4 REQUIRED)
|
||||
include(${QT_USE_FILE})
|
||||
# ${QT_QTSVG_LIBRARY}
|
||||
set(QtX_INCLUDE_DIRS ${QT_INCLUDE_DIR})
|
||||
set(QtX_LIBRARIES ${QT_LIBRARIES})
|
||||
else()
|
||||
message(STATUS "Attempt to find Qt 5...")
|
||||
# For Qt5
|
||||
find_package(Qt5Core REQUIRED)
|
||||
|
@ -231,32 +271,22 @@
|
|||
${Qt5Core_LIBRARIES} )
|
||||
#message(STATUS "QtX_INCLUDE_DIRS: ${QtX_INCLUDE_DIRS}")
|
||||
#message(STATUS "QtX_LIBRARIES: ${QtX_LIBRARIES}")
|
||||
else()
|
||||
message(STATUS "Attempt to find Qt 4...")
|
||||
# For Qt4.
|
||||
#set(QT_USE_QTXML "true")
|
||||
set(QT_USE_QTSVG "true")
|
||||
find_package(Qt4 REQUIRED)
|
||||
include(${QT_USE_FILE})
|
||||
# ${QT_QTSVG_LIBRARY}
|
||||
set(QtX_INCLUDE_DIRS ${QT_INCLUDE_DIR})
|
||||
set(QtX_LIBRARIES ${QT_LIBRARIES})
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(qtX_wrap_cpp variable)
|
||||
if (WITH_QT5)
|
||||
qt5_wrap_cpp(${variable} ${ARGN})
|
||||
else()
|
||||
if (WITH_QT4)
|
||||
qt4_wrap_cpp(${variable} ${ARGN})
|
||||
else()
|
||||
qt5_wrap_cpp(${variable} ${ARGN})
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(qtX_add_resources variable)
|
||||
if (WITH_QT5)
|
||||
qt5_add_resources(${variable} ${ARGN})
|
||||
else()
|
||||
if (WITH_QT4)
|
||||
qt4_add_resources(${variable} ${ARGN})
|
||||
else()
|
||||
qt5_add_resources(${variable} ${ARGN})
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
|
@ -265,15 +295,7 @@
|
|||
# Find Qwt, correlated to the Qt version.
|
||||
#
|
||||
macro(setup_qwt)
|
||||
if(WITH_QT5)
|
||||
find_path(QWT_INCLUDE_DIR NAMES qwt.h
|
||||
PATHS /usr/include/qt5
|
||||
/usr/include
|
||||
PATH_SUFFIXES qwt )
|
||||
find_library(QWT_LIBRARY NAMES qwt-qt5 qwt
|
||||
PATHS /usr/lib64
|
||||
/usr/lib )
|
||||
else()
|
||||
if(WITH_QT4)
|
||||
find_path(QWT_INCLUDE_DIR NAMES qwt.h
|
||||
PATHS /usr/include/qwt-qt4
|
||||
/opt/local/libexec/qt4/include
|
||||
|
@ -284,6 +306,14 @@
|
|||
PATHS /opt/local/libexec/qt4/lib
|
||||
/usr/lib64
|
||||
/usr/lib )
|
||||
else()
|
||||
find_path(QWT_INCLUDE_DIR NAMES qwt.h
|
||||
PATHS /usr/include/qt5
|
||||
/usr/include
|
||||
PATH_SUFFIXES qwt )
|
||||
find_library(QWT_LIBRARY NAMES qwt-qt5 qwt
|
||||
PATHS /usr/lib64
|
||||
/usr/lib )
|
||||
endif()
|
||||
|
||||
if( QWT_INCLUDE_DIR AND QWT_LIBRARY)
|
||||
|
@ -396,9 +426,11 @@
|
|||
set( pyDeplibs ${clib} ${deplibs} )
|
||||
|
||||
add_library( ${clib} ${pyCpps} )
|
||||
set_target_properties( ${clib} PROPERTIES VERSION ${version} SOVERSION ${soversion} )
|
||||
set_target_properties( ${clib} PROPERTIES VERSION ${version} SOVERSION ${soversion})
|
||||
#target_compile_definitions( ${clib} PUBLIC Py_LIMITED_API=1)
|
||||
target_link_libraries( ${clib} ${deplibs} )
|
||||
install( TARGETS ${clib} DESTINATION lib${LIB_SUFFIX} )
|
||||
target_link_options( ${clib} PRIVATE "LINKER:--unresolved-symbols=ignore-all")
|
||||
endif()
|
||||
|
||||
set( pytarget "${pymodule}_target" )
|
||||
|
@ -409,7 +441,9 @@
|
|||
PREFIX ""
|
||||
OUTPUT_NAME ${pymodule}
|
||||
)
|
||||
#target_compile_definitions( ${pytarget} PUBLIC Py_LIMITED_API=1)
|
||||
target_link_libraries( ${pytarget} ${pyDeplibs} )
|
||||
target_link_options( ${pytarget} PRIVATE "LINKER:--unresolved-symbols=ignore-all")
|
||||
|
||||
install( TARGETS ${pytarget} DESTINATION ${Python_CORIOLISARCH} )
|
||||
if( NOT ("${pyIncludes}" STREQUAL "None") )
|
||||
|
@ -432,6 +466,7 @@
|
|||
add_library( ${pymodule} MODULE ${pyCpps} )
|
||||
set_target_properties( ${pymodule} PROPERTIES PREFIX "" )
|
||||
target_link_libraries( ${pymodule} ${deplibs} )
|
||||
#target_compile_definitions( ${pymodule} PUBLIC Py_LIMITED_API=1)
|
||||
|
||||
install( TARGETS ${pymodule} DESTINATION ${Python_CORIOLISARCH} )
|
||||
if( NOT ("${pyIncludes}" STREQUAL "None") )
|
||||
|
|
|
@ -15,13 +15,14 @@ IF(UNIX)
|
|||
#
|
||||
# Look for an installation.
|
||||
#
|
||||
FIND_PATH(COLOQUINTE_INCLUDE_PATH NAMES coloquinte/netlist.hxx PATHS
|
||||
FIND_PATH(COLOQUINTE_INCLUDE_PATH NAMES coloquinte/coloquinte.hpp PATHS
|
||||
# Look in other places.
|
||||
${CORIOLIS_DIR_SEARCH}
|
||||
PATH_SUFFIXES include/coriolis2
|
||||
# Help the user find it if we cannot.
|
||||
DOC "The ${COLOQUINTE_INCLUDE_PATH_DESCRIPTION}"
|
||||
)
|
||||
MESSAGE( "COL ${COLOQUINTE_INCLUDE_PATH}" )
|
||||
|
||||
FIND_LIBRARY(COLOQUINTE_LIBRARY_PATH
|
||||
NAMES coloquinte
|
|
@ -1,5 +1,4 @@
|
|||
|
||||
if(UNIX)
|
||||
if(UNIX AND NOT POETRY)
|
||||
if(NOT Python_FOUND)
|
||||
message(FATAL_ERROR "Python has not been found, maybe forgot to call find_package(Python). ")
|
||||
endif()
|
||||
|
@ -10,7 +9,7 @@ if(UNIX)
|
|||
|
||||
execute_process(COMMAND "${Python_EXECUTABLE}" "-c" "${SCRIPT}"
|
||||
RESULT_VARIABLE RETURN_CODE
|
||||
OUTPUT_VARIABLE Python_CORIOLISARCH
|
||||
OUTPUT_VARIABLE Python_SITEARCH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
|
@ -20,7 +19,7 @@ if(UNIX)
|
|||
|
||||
execute_process(COMMAND "${Python_EXECUTABLE}" "-c" "${SCRIPT}"
|
||||
RESULT_VARIABLE RETURN_CODE
|
||||
OUTPUT_VARIABLE Python_CORIOLISLIB
|
||||
OUTPUT_VARIABLE Python_SITELIB
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
|
@ -30,12 +29,15 @@ if(UNIX)
|
|||
set(FindPythonSitePackages_FOUND FALSE)
|
||||
endif(RETURN_CODE EQUAL 0)
|
||||
|
||||
set(Python_CORIOLISARCH "lib${LIB_SUFFIX}/${Python_CORIOLISARCH}"
|
||||
CACHE STRING "Python platform dependent install directory." FORCE)
|
||||
set(Python_CORIOLISLIB "lib${LIB_SUFFIX}/${Python_CORIOLISLIB}"
|
||||
set(Python_CORIOLISARCH "lib${LIB_SUFFIX}/${Python_SITEARCH}/coriolis"
|
||||
CACHE STRING "Python platform dependent install directory (Coriolis modules)." FORCE)
|
||||
set(Python_SITELIB "lib${LIB_SUFFIX}/${Python_SITELIB}"
|
||||
CACHE STRING "Python platform independent install directory." FORCE)
|
||||
set(Python_CORIOLISLIB "${Python_SITELIB}/coriolis"
|
||||
CACHE STRING "Python platform independent install directory (Coriolis modules)." FORCE)
|
||||
mark_as_advanced(Python_CORIOLISARCH)
|
||||
mark_as_advanced(Python_CORIOLISLIB)
|
||||
mark_as_advanced(Python_SITELIB)
|
||||
|
||||
if(FindPythonSitePackages_FOUND)
|
||||
if(NOT FindPythonSitePackages_FIND_QUIETLY)
|
||||
|
@ -46,4 +48,4 @@ if(UNIX)
|
|||
else(FindPythonSitePackages_FOUND)
|
||||
message ( FATAL_ERROR "Python site packages directory was not found (pythonV.R/site-packages/)." )
|
||||
endif(FindPythonSitePackages_FOUND)
|
||||
endif(UNIX)
|
||||
endif(UNIX AND NOT POETRY)
|
||||
|
|
|
@ -119,7 +119,7 @@ Development files for the Coriolis 2 package.
|
|||
%dir %{coriolisTop}/%{_lib}
|
||||
%dir %{coriolisTop}/%{python_sitedir}
|
||||
%dir %{coriolisTop}/%{python_sitedir}/crlcore
|
||||
%dir %{coriolisTop}/%{python_sitedir}/crlcore/helpers
|
||||
%dir %{coriolisTop}/%{python_sitedir}/helpers
|
||||
%dir %{coriolisTop}/%{python_sitedir}/cumulus
|
||||
%dir %{coriolisTop}/%{python_sitedir}/stratus
|
||||
%{coriolisTop}/bin/*
|
||||
|
@ -130,7 +130,7 @@ Development files for the Coriolis 2 package.
|
|||
%{coriolisTop}/%{python_sitedir}/cumulus/plugins/*/*.py*
|
||||
%{coriolisTop}/%{python_sitedir}/stratus/*.py*
|
||||
%{coriolisTop}/%{python_sitedir}/crlcore/*.py*
|
||||
%{coriolisTop}/%{python_sitedir}/crlcore/helpers/*.py*
|
||||
%{coriolisTop}/%{python_sitedir}/helpers/*.py*
|
||||
%{coriolisTop}/%{python_sitedir}/kite/*.py*
|
||||
%{coriolisTop}/%{python_sitedir}/unicorn/*.py*
|
||||
%{_sysconfdir}/coriolis2/*.py
|
||||
|
@ -180,7 +180,7 @@ Development files for the Coriolis 2 package.
|
|||
%{coriolisTop}/include/vlsisapd/configuration/*.h
|
||||
%{coriolisTop}/include/vlsisapd/dtr/*.h
|
||||
%{coriolisTop}/include/vlsisapd/openChams/*.h
|
||||
%{coriolisTop}/include/coriolis2/coloquinte/*.hxx
|
||||
%{coriolisTop}/include/coriolis2/coloquinte/*.hpp
|
||||
%{coriolisTop}/include/coriolis2/hurricane/*.h
|
||||
%{coriolisTop}/include/coriolis2/hurricane/viewer/*.h
|
||||
%{coriolisTop}/include/coriolis2/hurricane/isobar/*.h
|
||||
|
|
|
@ -17,6 +17,10 @@ reDebugStaticPattern = re.compile( r".*Debug\.Static.*" )
|
|||
|
||||
|
||||
def scrubPath ( pathName ):
|
||||
"""
|
||||
Remove any previous path elements pointing to Coriolis,
|
||||
so we don't get multiple installed versions tangled together.
|
||||
"""
|
||||
pathEnv = os.getenv( pathName )
|
||||
if not pathEnv: return ""
|
||||
pathList = pathEnv.split( ':' )
|
||||
|
@ -36,8 +40,33 @@ def scrubPath ( pathName ):
|
|||
return scrubbedEnv
|
||||
|
||||
|
||||
def readLdconfig ():
|
||||
"""
|
||||
Read the default paths setup by ldconfig.
|
||||
|
||||
.. note:: Disabled now, as it was not the root cause of the
|
||||
linking problem. Keep as a code example...
|
||||
"""
|
||||
ldpath = ''
|
||||
uname = subprocess.Popen ( ["ldconfig", "-vXN"]
|
||||
, stdout=subprocess.PIPE
|
||||
, stderr=subprocess.PIPE )
|
||||
lines = uname.stdout.readlines()
|
||||
for rawline in lines:
|
||||
line = rawline.decode('ascii')
|
||||
if line[0] != '/': continue
|
||||
if len(ldpath) > 0: ldpath += ':'
|
||||
ldpath += line.split(':')[0]
|
||||
return ldpath
|
||||
|
||||
|
||||
def guessOs ():
|
||||
"""
|
||||
Try to guess under which OS we are running by calling uname.
|
||||
Also guess if we are using software collections *devtoolset*.
|
||||
"""
|
||||
useDevtoolset = False
|
||||
osEL9 = re.compile (".*Linux.*el9.*x86_64.*")
|
||||
osSlsoc7x_64 = re.compile (".*Linux.*el7.*x86_64.*")
|
||||
osSlsoc6x_64 = re.compile (".*Linux.*el6.*x86_64.*")
|
||||
osSlsoc6x = re.compile (".*Linux.*(el|slsoc)6.*")
|
||||
|
@ -65,6 +94,7 @@ def guessOs ():
|
|||
|
||||
line = lines[0].decode( 'ascii' )
|
||||
if osSlsoc7x_64.match(line): osType = "Linux.el7_64"
|
||||
elif osEL9.match(line): osType = "Linux.el9"
|
||||
elif osSlsoc6x_64.match(line):
|
||||
osType = "Linux.slsoc6x_64"
|
||||
useDevtoolset = True
|
||||
|
@ -100,7 +130,18 @@ def guessOs ():
|
|||
return ( osType, useDevtoolset )
|
||||
|
||||
|
||||
def guessShell ( forcedShell ):
|
||||
def guessShell ( defaultShell, osType ):
|
||||
"""
|
||||
Try to guess the kind shell we are running under, Bourne-like shells
|
||||
(sh, bash, ksh, zsh) or C-shell likes (csh, tcsh).
|
||||
|
||||
Identifies the parent process we are running into, which should be
|
||||
the shell, and compares to know ones.
|
||||
|
||||
.. note:: The SHELL nvironment variable cannot be trusted, it seems
|
||||
to be set once the user logs in, and if it change afterwards,
|
||||
it's not updated.
|
||||
"""
|
||||
# This environement variable cannot be trusted as it is set once when
|
||||
# the user logs in. If aftewards it changes it that variable is *not*
|
||||
# affected :-(.
|
||||
|
@ -116,14 +157,27 @@ def guessShell ( forcedShell ):
|
|||
, u'/usr/local/bin/csh'
|
||||
]
|
||||
if shellName is None:
|
||||
psCommand = subprocess.Popen ( ['ps', '-p', str(os.getppid()) ], stdout=subprocess.PIPE )
|
||||
shell = psCommand.stdout.readlines()[1].decode('utf8')[:-1].split()[3].lstrip('-')
|
||||
whichCommand = subprocess.Popen ( ['which', shell ], stdout=subprocess.PIPE )
|
||||
shellPath = whichCommand.stdout.readlines()[0][:-1].decode('utf8')
|
||||
#print( 'GUESSED shellPath={}'.format(shellPath) )
|
||||
psCommand = ['ps', '-o', 'comm', '-p', str(os.getppid()) ]
|
||||
cmdField = 0
|
||||
if osType.startswith('Cygwin'):
|
||||
psCommand = ['ps', '-p', str(os.getppid()) ]
|
||||
cmdField = 7
|
||||
try:
|
||||
psResult = subprocess.run( psCommand, capture_output=True, check=True )
|
||||
shell = psResult.stdout.splitlines()[1].decode('utf8').split()[cmdField].lstrip('-')
|
||||
if shell[0] != '/':
|
||||
whichCommand = subprocess.run( ['which', shell ], capture_output=True, check=True )
|
||||
shellPath = whichCommand.stdout.splitlines()[0].decode('utf8')
|
||||
else:
|
||||
shellPath = forcedShell
|
||||
#print( 'FORCED shellPath={}'.format(shellPath) )
|
||||
shellPath = shell
|
||||
if not options.queryISysRoot and not options.queryInstRoot:
|
||||
print( 'echo "[GUESSED] shellPath={}";'.format(shellPath) )
|
||||
except Exception:
|
||||
shellPath = u'/bin/bash'
|
||||
print( 'echo "[ERROR] \\"ps\\" command failure, using {}";'.format(shellPath) )
|
||||
else:
|
||||
shellPath = defaultShell
|
||||
print( 'echo "Defaulting to shell {}";'.format(shellPath) )
|
||||
if shellPath in cshBins:
|
||||
#print( 'Matched C-Shell' )
|
||||
isBourneShell = False
|
||||
|
@ -132,7 +186,6 @@ def guessShell ( forcedShell ):
|
|||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
osType,useDevtoolset = guessOs()
|
||||
buildType = "Release"
|
||||
linkType = "Shared"
|
||||
|
@ -161,7 +214,7 @@ if __name__ == "__main__":
|
|||
if options.shared: linkType = "Shared"
|
||||
if options.rootDir: rootDir = options.rootDir
|
||||
if options.shell: shellName = options.shell
|
||||
shellBin, isBourneShell = guessShell( shellName )
|
||||
shellBin, isBourneShell = guessShell( shellName, osType )
|
||||
|
||||
scriptPath = os.path.abspath( os.path.dirname( sys.argv[0] ))
|
||||
if 'Debug.' in scriptPath: buildType = 'Debug'
|
||||
|
@ -257,7 +310,7 @@ if __name__ == "__main__":
|
|||
shellMessage = "Using script location Coriolis 2 (%s)" % rootDir
|
||||
|
||||
if osType.startswith("Cygwin"):
|
||||
strippedPath = "%s/lib:%s" % ( coriolisTop, libDir, strippedPath )
|
||||
strippedPath = "%s/lib:%s" % ( coriolisTop, strippedPath )
|
||||
if not os.path.exists(coriolisTop):
|
||||
print( 'echo "[ERROR] coriolisEnv.py, top directory "{}" do not exists."'.format( coriolisTop ))
|
||||
sys.exit( 1 )
|
||||
|
@ -267,6 +320,7 @@ if __name__ == "__main__":
|
|||
if os.path.isdir(absLibDir): break
|
||||
libDir = None
|
||||
if libDir is None:
|
||||
if not options.queryISysRoot and not options.queryInstRoot:
|
||||
print( 'echo "[ERROR] coriolisEnv.py, library directory not found."' )
|
||||
sys.exit( 1 )
|
||||
|
||||
|
@ -286,12 +340,12 @@ if __name__ == "__main__":
|
|||
if os.path.isdir(pyPackageDir):
|
||||
sitePackagesDir = pyPackageDir
|
||||
break
|
||||
strippedPythonPath = "%s:" % (sitePackagesDir) + strippedPythonPath
|
||||
strippedPythonPath = "%s/crlcore:" % (sitePackagesDir) + strippedPythonPath
|
||||
strippedPythonPath = "%s/cumulus:" % (sitePackagesDir) + strippedPythonPath
|
||||
strippedPythonPath = "%s/cumulus/plugins:" % (sitePackagesDir) + strippedPythonPath
|
||||
strippedPythonPath = "%s/stratus:" % (sitePackagesDir) + strippedPythonPath
|
||||
strippedPythonPath = "%s:" % (sysconfDir) + strippedPythonPath
|
||||
strippedPythonPath = "%s" % (sitePackagesDir) + strippedPythonPath
|
||||
#strippedPythonPath = "%s/crlcore:" % (sitePackagesDir) + strippedPythonPath
|
||||
#strippedPythonPath = "%s/cumulus:" % (sitePackagesDir) + strippedPythonPath
|
||||
#strippedPythonPath = "%s/cumulus/plugins:" % (sitePackagesDir) + strippedPythonPath
|
||||
#strippedPythonPath = "%s/stratus:" % (sitePackagesDir) + strippedPythonPath
|
||||
#strippedPythonPath = "%s:" % (sysconfDir) + strippedPythonPath
|
||||
shellScriptSh += 'PYTHONPATH="%(PYTHONPATH)s";' \
|
||||
'export PYTHONPATH;'
|
||||
shellScriptCsh += 'setenv PYTHONPATH "%(PYTHONPATH)s";'
|
||||
|
|
|
@ -0,0 +1,275 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
import os
|
||||
import os.path
|
||||
from pathlib import Path
|
||||
import socket
|
||||
import subprocess
|
||||
import re
|
||||
import argparse
|
||||
|
||||
|
||||
reCoriolisPattern = re.compile( r".*coriolis.*" )
|
||||
reReleaseSharedPattern = re.compile( r".*Release\.Shared.*" )
|
||||
reReleaseStaticPattern = re.compile( r".*Release\.Static.*" )
|
||||
reDebugSharedPattern = re.compile( r".*Debug\.Shared.*" )
|
||||
reDebugStaticPattern = re.compile( r".*Debug\.Static.*" )
|
||||
|
||||
|
||||
def scrubPath ( pathName ):
|
||||
"""
|
||||
Remove from the PATH like environment variable ``pathName`` any
|
||||
previous path item referring to a Coriolis location.
|
||||
"""
|
||||
if not pathName in os.environ: return ''
|
||||
value = os.environ[ pathName ]
|
||||
elements = value.split( ':' )
|
||||
scrubbed = []
|
||||
for element in elements:
|
||||
if element == '': continue
|
||||
if reCoriolisPattern .match(element) \
|
||||
or reReleaseSharedPattern.match(element) \
|
||||
or reReleaseStaticPattern.match(element) \
|
||||
or reDebugSharedPattern .match(element) \
|
||||
or reDebugStaticPattern .match(element):
|
||||
continue
|
||||
scrubbed.append( element )
|
||||
if len(scrubbed) == 0: return ''
|
||||
return ':'.join( scrubbed )
|
||||
|
||||
|
||||
def envWriteBack ( pathName, pathValue ):
|
||||
"""
|
||||
Add to the environment PATH like variable ``pathName`` the components
|
||||
given in ``pathValue`` and export it back. To avoid having multiple
|
||||
Coriolis in the path, it is scrubbed beforehand.
|
||||
"""
|
||||
if pathName in os.environ:
|
||||
scrubbed = scrubPath( pathName )
|
||||
if scrubbed != '':
|
||||
pathValue += ':' + scrubbed
|
||||
os.environ[ pathName ] = pathValue
|
||||
return pathValue
|
||||
|
||||
|
||||
def setupPaths ( verbose, debug=False ):
|
||||
"""
|
||||
Guess and setup the main variables to use Coriolis:
|
||||
|
||||
* ``PATH``, to find the binaries.
|
||||
* ``LD_LIBRARY_PATH``, to access the dynamic libraries.
|
||||
* ``DYLD_LIBRARY_PATH``, same as above under MacOS.
|
||||
* ``PYTHONPATH``, to access the various Python modules provided
|
||||
by Coriolis.
|
||||
|
||||
:param verbose: Self explanatory.
|
||||
:param debug: Use the version compiled with debugging support.
|
||||
Be aware that it is roughly 4 times slower...
|
||||
It's the tree rooted at ``Debug.Shared/install``
|
||||
instead of ``Release.Shared/install``.
|
||||
"""
|
||||
# Setup CORIOLIS_TOP.
|
||||
osEL9 = re.compile (".*Linux.*el9.*x86_64.*")
|
||||
osSlsoc7x_64 = re.compile (".*Linux.*el7.*x86_64.*")
|
||||
osSlsoc6x_64 = re.compile (".*Linux.*el6.*x86_64.*")
|
||||
osSlsoc6x = re.compile (".*Linux.*(el|slsoc)6.*")
|
||||
osSLSoC5x_64 = re.compile (".*Linux.*el5.*x86_64.*")
|
||||
osSLSoC5x = re.compile (".*Linux.*(el5|2.6.23.13.*SoC).*")
|
||||
osFedora_64 = re.compile (".*Linux.*fc.*x86_64.*")
|
||||
osFedora = re.compile (".*Linux.*fc.*")
|
||||
osLinux_64 = re.compile (".*Linux.*x86_64.*")
|
||||
osLinux = re.compile (".*Linux.*")
|
||||
osDarwin = re.compile (".*Darwin.*")
|
||||
osUbuntu1004 = re.compile (".*Linux.*ubuntu.*")
|
||||
osUbuntu1004_64 = re.compile (".*Linux.*ubuntu.*x86_64.*")
|
||||
osFreeBSD8x_amd64 = re.compile (".*FreeBSD 8.*amd64.*")
|
||||
osFreeBSD8x_64 = re.compile (".*FreeBSD 8.*x86_64.*")
|
||||
osFreeBSD8x = re.compile (".*FreeBSD 8.*")
|
||||
osCygwinW7_64 = re.compile (".*CYGWIN_NT-6\.1.*x86_64.*")
|
||||
osCygwinW7 = re.compile (".*CYGWIN_NT-6\.1.*i686.*")
|
||||
osCygwinW8_64 = re.compile (".*CYGWIN_NT-6\.[2-3].*x86_64.*")
|
||||
osCygwinW8 = re.compile (".*CYGWIN_NT-6\.[2-3].*i686.*")
|
||||
osCygwinW10_64 = re.compile (".*CYGWIN_NT-10\.[0-3].*x86_64.*")
|
||||
osCygwinW10 = re.compile (".*CYGWIN_NT-10\.[0-3].*i686.*")
|
||||
|
||||
uname = subprocess.Popen( ["uname", "-srm"], stdout=subprocess.PIPE )
|
||||
lines = uname.stdout.readlines()
|
||||
line = lines[0].decode( 'ascii' )
|
||||
if osSlsoc7x_64 .match(line): osDir = "Linux.el7_64"
|
||||
elif osEL9 .match(line): osDir = "Linux.el9"
|
||||
elif osSlsoc6x_64 .match(line): osDir = "Linux.slsoc6x_64"
|
||||
elif osSlsoc6x .match(line): osDir = "Linux.slsoc6x"
|
||||
elif osSLSoC5x_64 .match(line): osDir = "Linux.SLSoC5x_64"
|
||||
elif osSLSoC5x .match(line): osDir = "Linux.SLSoC5x"
|
||||
elif osFedora_64 .match(line): osDir = "Linux.fc_64"
|
||||
elif osFedora .match(line): osDir = "Linux.fc"
|
||||
elif osUbuntu1004 .match(line): osDir = "Linux.Ubuntu1004"
|
||||
elif osUbuntu1004_64 .match(line): osDir = "Linux.Ubuntu1004_64"
|
||||
elif osLinux_64 .match(line): osDir = "Linux.x86_64"
|
||||
elif osLinux .match(line): osDir = "Linux.i386"
|
||||
elif osFreeBSD8x_64 .match(line): osDir = "FreeBSD.8x.x86_64"
|
||||
elif osFreeBSD8x_amd64.match(line): osDir = "FreeBSD.8x.amd64"
|
||||
elif osFreeBSD8x .match(line): osDir = "FreeBSD.8x.i386"
|
||||
elif osDarwin .match(line): osDir = "Darwin"
|
||||
elif osCygwinW7_64 .match(line): osDir = "Cygwin.W7_64"
|
||||
elif osCygwinW7 .match(line): osDir = "Cygwin.W7"
|
||||
elif osCygwinW8_64 .match(line): osDir = "Cygwin.W8_64"
|
||||
elif osCygwinW8 .match(line): osDir = "Cygwin.W8"
|
||||
elif osCygwinW10_64 .match(line): osDir = "Cygwin.W10_64"
|
||||
elif osCygwinW10 .match(line): osDir = "Cygwin.W10"
|
||||
else:
|
||||
uname = subprocess.Popen( ["uname", "-sr"], stdout=subprocess.PIPE )
|
||||
osDir = uname.stdout.readlines()[0][:-1]
|
||||
|
||||
print( '[WARNING] environment.setupPaths(): Unrecognized OS: "{}".'.format( line[:-1] ))
|
||||
print( ' (using: "{}")'.format( osDir ))
|
||||
osDir = Path( osDir )
|
||||
homeDir = Path( os.environ['HOME'] )
|
||||
buildType = Path( 'Debug.Shared' if debug else 'Release.Shared' )
|
||||
scriptPath = Path( __file__ ).resolve()
|
||||
topDirs = []
|
||||
|
||||
topDirs += [ homeDir / 'coriolis-2.x' / osDir / buildType / 'install'
|
||||
, Path( '/soc/coriolis2' )
|
||||
, Path( '/usr' )
|
||||
]
|
||||
if not debug and 'CORIOLIS_TOP' in os.environ:
|
||||
topDirs.insert( 0, Path( os.environ['CORIOLIS_TOP'] ))
|
||||
for part in scriptPath.parts:
|
||||
if part == 'nightly':
|
||||
topDirs.insert( 0, homeDir / 'nightly' / 'coriolis-2.x' / osDir / buildType / 'install' )
|
||||
break
|
||||
if verbose:
|
||||
print( ' o Self locating Coriolis:' )
|
||||
coriolisTop = None
|
||||
for topDir in topDirs:
|
||||
if coriolisTop or not (topDir / 'bin' / 'cgt').is_file():
|
||||
if verbose: print( ' - {}'.format(topDir) )
|
||||
continue
|
||||
if verbose: print( ' - {} *'.format(topDir) )
|
||||
coriolisTop = topDir
|
||||
if not coriolisTop:
|
||||
print( '[ERROR] environment.setupPaths(): Unable to locate Coriolis.' )
|
||||
return False
|
||||
|
||||
os.environ[ 'CORIOLIS_TOP' ] = coriolisTop.as_posix()
|
||||
#if coriolisTop == '/usr': sysconfDir = Path( 'etc', 'coriolis2' )
|
||||
#else: sysconfDir = coriolisTop / 'etc' / 'coriolis2'
|
||||
if coriolisTop == '/usr': sysconfDir = Path( 'etc' )
|
||||
else: sysconfDir = coriolisTop / 'etc'
|
||||
|
||||
# Setup PATH.
|
||||
binPath = envWriteBack( 'PATH', (coriolisTop/'bin').as_posix() )
|
||||
|
||||
# Setup LD_LIBRARY_PATH.
|
||||
libDirs = []
|
||||
for lib in [ Path('lib'), Path('lib64') ]:
|
||||
libDir = lib
|
||||
absLibDir = coriolisTop / lib
|
||||
if absLibDir.is_dir():
|
||||
libDirs.append( absLibDir )
|
||||
libDir = None
|
||||
if not len(libDirs):
|
||||
print( '[ERROR] environment.setupPaths(): Library directory not found.' )
|
||||
return False
|
||||
libraryPath = ''
|
||||
ldPathName = 'LD_LIBRARY_PATH'
|
||||
if osDir.as_posix().startswith( 'Darwin' ):
|
||||
ldPathName = 'DYLD_LIBRARY_PATH'
|
||||
for libDir in libDirs:
|
||||
if len(libraryPath): libraryPath = libraryPath + ':'
|
||||
libraryPath = libraryPath + libDir.as_posix()
|
||||
libraryPath = envWriteBack( ldPathName, libraryPath )
|
||||
|
||||
# Setup PYTHONPATH.
|
||||
v = sys.version_info
|
||||
sitePackagesDir = None
|
||||
for pyPackageDir in [ Path('python{}.{}'.format(v.major,v.minor)) / 'site-packages'
|
||||
, Path('python{}.{}'.format(v.major,v.minor)) / 'dist-packages'
|
||||
, Path('{}.{}'.format(v.major,v.minor)) / 'site-packages'
|
||||
, Path('python{}'.format(v.major)) / 'site-packages'
|
||||
, Path('python{}'.format(v.major)) / 'dist-packages'
|
||||
, Path('{}'.format(v.major)) / 'site-packages'
|
||||
]:
|
||||
sitePackagesDir = libDirs[-1] / pyPackageDir
|
||||
if sitePackagesDir.is_dir():
|
||||
if verbose:
|
||||
print( ' - {} *'.format(sitePackagesDir) )
|
||||
break
|
||||
if verbose:
|
||||
print( ' - {}'.format(sitePackagesDir) )
|
||||
sitePackagesDir = None
|
||||
if sitePackagesDir is None:
|
||||
print( '[ERROR] environment.setupPaths(): Python {site,dist}-packages directory not found.' )
|
||||
return False
|
||||
pythonPath = ''
|
||||
for packageDir in [ sitePackagesDir
|
||||
#, sitePackagesDir / 'crlcore'
|
||||
#, sitePackagesDir / 'cumulus'
|
||||
#, sitePackagesDir / 'cumulus/plugins'
|
||||
#, sitePackagesDir / 'status'
|
||||
#, sysconfDir
|
||||
]:
|
||||
sys.path.append( str(packageDir) )
|
||||
if len(pythonPath): pythonPath += ':'
|
||||
pythonPath += str(packageDir)
|
||||
pythonPath = envWriteBack( 'PYTHONPATH', pythonPath )
|
||||
return True
|
||||
|
||||
|
||||
def printVariable ( name ):
|
||||
if not name in os.environ:
|
||||
print( '{}:'.format( name ))
|
||||
print( '- variable_not_set' )
|
||||
return
|
||||
values = os.environ[ name ].split( ':' )
|
||||
print( '{}:'.format( name ))
|
||||
for value in values:
|
||||
print( '- {}'.format( value ))
|
||||
|
||||
|
||||
def printEnvironment ():
|
||||
"""
|
||||
Display the environment setup, using YAML formatting.
|
||||
"""
|
||||
print( '# crlenv.py: Alliance/Coriolis finder, guessed values.' )
|
||||
print( '---' )
|
||||
for name in ('CORIOLIS_TOP', 'PATH', 'DYLD_LIBRARY_PATH'
|
||||
, 'LD_LIBRARY_PATH', 'PYTHONPATH'):
|
||||
printVariable( name )
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
"""
|
||||
Run any script in a environmnent set for Coriolis.
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
ego@home:~> crlenv.py -- doit clean_flow
|
||||
b2v Run <blif2vst arlet6502 depends=[Arlet6502.blif]>.
|
||||
cgt Run plain CGT (no loaded design)
|
||||
clean_flow Clean all generated (targets) files.
|
||||
gds Run <Alias "gds" for "pnr">.
|
||||
pnr Run <pnr arlet6502_cts_r.gds depends=[arlet6502.vst,Arlet6502.spi]>.
|
||||
yosys Run <yosys Arlet6502.v top=Arlet6502 blackboxes=[] flattens=[]>.
|
||||
ego@home:~> crlenv.py -- bash
|
||||
[ego@home]$ echo $CORIOLIS_TOP
|
||||
/home/ego/coriolis-2.x/Linux.el9/Release.Shared/install
|
||||
[ego@home]$ exit
|
||||
ego@home:~>
|
||||
"""
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument( '-v', '--verbose', action='store_true', dest='verbose' )
|
||||
parser.add_argument( '-d', '--debug' , action='store_true', dest='debug' )
|
||||
parser.add_argument( 'command', nargs='*' )
|
||||
args = parser.parse_args()
|
||||
|
||||
setupPaths( args.verbose, args.debug )
|
||||
if not len(args.command):
|
||||
printEnvironment()
|
||||
sys.exit( 0 )
|
||||
state = subprocess.run( args.command )
|
||||
sys.exit( state.returncode )
|
|
@ -1 +0,0 @@
|
|||
Subproject commit bd6b78003c0cc6579fbad73593e69f2714f3a770
|
|
@ -234,6 +234,13 @@ class BenchsCommand ( CommandArg ):
|
|||
return
|
||||
|
||||
|
||||
class PyBenchsCommand ( CommandArg ):
|
||||
|
||||
def __init__ ( self, benchsDir, fdLog=None ):
|
||||
CommandArg.__init__ ( self, [ '../bin/gopy.sh' ], wd=benchsDir, fdLog=fdLog )
|
||||
return
|
||||
|
||||
|
||||
|
||||
class GitRepository ( object ):
|
||||
|
||||
|
@ -277,6 +284,16 @@ class GitRepository ( object ):
|
|||
Command( [ 'git', 'checkout', branch ], self.fdLog ).execute()
|
||||
return
|
||||
|
||||
def submoduleInit ( self ):
|
||||
os.chdir( self.localRepoDir )
|
||||
Command( [ 'git', 'submodule', 'init' ], self.fdLog ).execute()
|
||||
return
|
||||
|
||||
def submoduleUpdate ( self ):
|
||||
os.chdir( self.localRepoDir )
|
||||
Command( [ 'git', 'submodule', 'update' ], self.fdLog ).execute()
|
||||
return
|
||||
|
||||
|
||||
class Configuration ( object ):
|
||||
|
||||
|
@ -286,7 +303,7 @@ class Configuration ( object ):
|
|||
, 'homeDir' , 'masterHost'
|
||||
, 'debugArg' , 'nightlyMode', 'dockerMode', 'chrootMode'
|
||||
, 'rmSource' , 'rmBuild'
|
||||
, 'doGit' , 'doAlliance' , 'doCoriolis', 'doBenchs', 'doSendReport'
|
||||
, 'doGit' , 'doAlliance' , 'doCoriolis', 'doBenchs', 'doPyBenchs', 'doSendReport'
|
||||
, 'success' , 'rcode'
|
||||
]
|
||||
SecondaryNames = \
|
||||
|
@ -296,7 +313,7 @@ class Configuration ( object ):
|
|||
def __init__ ( self ):
|
||||
self._sender = 'Jean-Paul.Chaput@soc.lip6.fr'
|
||||
self._receivers = [ 'Jean-Paul.Chaput@lip6.fr', ]
|
||||
self._supportRepos = [ 'http://github.com/miloyip/rapidjson' ]
|
||||
self._supportRepos = [ 'https://github.com/Tencent/rapidjson.git' ]
|
||||
self._allianceRepo = 'https://gitlab.lip6.fr/jpc/alliance.git'
|
||||
self._coriolisRepo = 'https://gitlab.lip6.fr/jpc/coriolis.git'
|
||||
self._benchsRepo = 'https://gitlab.lip6.fr/jpc/alliance-check-toolkit.git'
|
||||
|
@ -309,6 +326,7 @@ class Configuration ( object ):
|
|||
self._doAlliance = False
|
||||
self._doCoriolis = False
|
||||
self._doBenchs = False
|
||||
self._doPyBenchs = False
|
||||
self._doSendReport = False
|
||||
self._nightlyMode = False
|
||||
self._dockerMode = False
|
||||
|
@ -434,20 +452,24 @@ class Configuration ( object ):
|
|||
] )
|
||||
otherArgs = []
|
||||
if self.debugArg: otherArgs.append( self.debugArg )
|
||||
if target == 'EL9':
|
||||
#otherArgs.append( '--project=support' )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs , fdLog=self.fds['coriolis'] ) )
|
||||
#commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
|
||||
if target == 'SL7_64':
|
||||
otherArgs.append( '--project=support' )
|
||||
otherArgs += [ '--project=support', '--qt4' ]
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs , fdLog=self.fds['coriolis'] ) )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
|
||||
elif target == 'SL6_64' or target == 'SL6':
|
||||
otherArgs.append( '--project=support' )
|
||||
otherArgs.append( '--devtoolset=8' )
|
||||
otherArgs += [ '--project=support', '--devtoolset=8', '--qt4' ]
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 6, otherArgs , fdLog=self.fds['coriolis'] ) )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
|
||||
elif target == 'Ubuntu18' or target == 'Debian9' or target == 'Debian10':
|
||||
if target == 'Ubuntu18': otherArgs.append( '--qt5' )
|
||||
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs, fdLog=self.fds['coriolis'] ) )
|
||||
if self.doBenchs:
|
||||
commands.append( BenchsCommand( self.benchsDir, fdLog=self.fds['benchs'] ) )
|
||||
if self.doPyBenchs:
|
||||
commands.append( PyBenchsCommand( self.benchsDir, fdLog=self.fds['benchs'] ) )
|
||||
return commands
|
||||
|
||||
|
||||
|
@ -529,7 +551,8 @@ parser.add_option ( "--do-report" , action="store_true" , dest=
|
|||
parser.add_option ( "--nightly" , action="store_true" , dest="nightly" , help="Perform a nighly build." )
|
||||
parser.add_option ( "--docker" , action="store_true" , dest="docker" , help="Perform a build inside a docker container." )
|
||||
parser.add_option ( "--chroot" , action="store_true" , dest="chroot" , help="Perform a build inside a chrooted environment." )
|
||||
parser.add_option ( "--benchs" , action="store_true" , dest="benchs" , help="Run the <alliance-checker-toolkit> sanity benchs." )
|
||||
parser.add_option ( "--benchs" , action="store_true" , dest="benchs" , help="Run the <alliance-checker-toolkit> sanity benchs (make)." )
|
||||
parser.add_option ( "--pybenchs" , action="store_true" , dest="pybenchs" , help="Run the <alliance-checker-toolkit> sanity benchs (doit)." )
|
||||
parser.add_option ( "--rm-build" , action="store_true" , dest="rmBuild" , help="Remove the build/install directories." )
|
||||
parser.add_option ( "--rm-source" , action="store_true" , dest="rmSource" , help="Remove the Git source repositories." )
|
||||
parser.add_option ( "--rm-all" , action="store_true" , dest="rmAll" , help="Remove everything (source+build+install)." )
|
||||
|
@ -550,6 +573,7 @@ try:
|
|||
if options.doAlliance: conf.doAlliance = True
|
||||
if options.doCoriolis: conf.doCoriolis = True
|
||||
if options.benchs: conf.doBenchs = True
|
||||
if options.pybenchs: conf.doPyBenchs = True
|
||||
if options.doReport: conf.doSendReport = True
|
||||
if options.rmSource or options.rmAll: conf.rmSource = True
|
||||
if options.rmBuild or options.rmAll: conf.rmBuild = True
|
||||
|
@ -559,6 +583,7 @@ try:
|
|||
if conf.doAlliance: conf.openLog( 'alliance' )
|
||||
if conf.doCoriolis: conf.openLog( 'coriolis' )
|
||||
if conf.doBenchs: conf.openLog( 'benchs' )
|
||||
if conf.doPyBenchs: conf.openLog( 'benchs' )
|
||||
if conf.dockerMode: os.environ['USER'] = 'root'
|
||||
|
||||
gitSupports = []
|
||||
|
@ -586,6 +611,8 @@ try:
|
|||
if conf.rmSource: gitCoriolis.removeLocalRepo()
|
||||
gitCoriolis.clone ()
|
||||
gitCoriolis.checkout( 'devel' )
|
||||
gitCoriolis.submoduleInit()
|
||||
gitCoriolis.submoduleUpdate()
|
||||
|
||||
if conf.rmSource: gitBenchs.removeLocalRepo()
|
||||
gitBenchs.clone()
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
option(BUILD_DOC "Build the documentation (doxygen)" OFF)
|
||||
option(USE_LIBBFD "Link with BFD libraries to print stack traces" OFF)
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.9)
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
set(ignoreVariables "${BUILD_DOC} ${CMAKE_INSTALL_DIR}")
|
||||
|
||||
|
@ -18,9 +18,9 @@
|
|||
setup_boost(program_options)
|
||||
setup_qt()
|
||||
setup_qwt()
|
||||
setup_python()
|
||||
|
||||
find_package(Libexecinfo REQUIRED)
|
||||
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
|
||||
find_package(PythonSitePackages REQUIRED)
|
||||
find_package(LEFDEF REQUIRED)
|
||||
find_package(FLUTE REQUIRED)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue