Compare commits

..

446 Commits

Author SHA1 Message Date
Jean-Paul Chaput 947026cced Add technology description for the new LSxLib symbolic layout. 2023-07-14 12:33:03 +02:00
Jean-Paul Chaput ce084fcf73 Add a tile counter in verbose time to monitor the progress. 2023-07-14 12:31:38 +02:00
Jean-Paul Chaput 7b304da14b Check for minimal size in non-anchored Contact CTOR. 2023-07-14 12:28:08 +02:00
Jean-Paul Chaput b734d61a00 Update the RapidJSON git URL. 2023-07-14 12:26:51 +02:00
Jean-Paul Chaput c2750ca127 Finally understood how to update the submodule. 2023-07-09 17:43:00 +02:00
Jean-Paul Chaput cadae8412b Make the Coloquinte submodule follow the coriolis-submodule branch automatically. 2023-07-09 17:19:32 +02:00
Jean-Paul Chaput d258749373 Merge branch 'coloquinte_rebase' into devel
Some merge conflicts did occurs as it seems the latests commits
from "devel" where not applied to the rebase.
2023-07-09 13:42:21 +02:00
Gabriel Gouvine 21deed93f1 Update coloquinte version 2023-07-04 11:04:06 +02:00
Gabriel Gouvine e3d6456ce3 Avoid placement issues on small designs by limiting cell bloat based on row size 2023-07-04 10:22:50 +02:00
Gabriel Gouvine fda7054840 Apply density variation on the whole placement area, avoiding reduced free space under huge bloat 2023-07-04 10:22:50 +02:00
Gabriel Gouvine ffb5e38de2 Apply library bloating during free space computation 2023-07-04 10:22:50 +02:00
Gabriel Gouvine dcf3e7bd77 Report slice height in Etesian logs 2023-07-04 10:22:50 +02:00
Jean-Paul Chaput 605fa5cdd1 Using the right cell gauge name in GF180MCU techn o file. 2023-07-04 10:22:50 +02:00
Jean-Paul Chaput 508adbd00b Small beautification of the Coloquinte bloat factor display. 2023-07-04 10:22:50 +02:00
Jean-Paul Chaput b06e90d122 Call runScript() with unicorn only when there *is* a graphic interface. 2023-07-04 10:22:50 +02:00
Jean-Paul Chaput d8958c3b5a In designflow, re-export LD_LIBRARY_PATH only if there is an ALLIANCE_TOP. 2023-07-04 10:22:50 +02:00
Jean-Paul Chaput 9c8e63c11d Set patterns to account the DFF in cmos & cmos 45 technologies. 2023-07-04 10:22:50 +02:00
Jean-Paul Chaput 373cbe9835 Filter new type of RoutingGauge in KatanaEngine::annotateGlobalGraph().
* Change: RoutingGauge in KatanaEngine::annotateGlobalGraph(), when
    accounting for obstacles, skip new types of RoutingGauges that
    are not accounted either when computing initial edge capacity in
    EdgeCapacity CTOR. Now only take into account the "Default" kind.
2023-07-04 10:22:50 +02:00
Jean-Paul Chaput 5cd83019db Fix bug in NetBuilderHV::_do_1G_xM1_1PinM2(), using bad RoutingPad.
* Bug: In NetBuilderHV::_do_1G_xM1_1PinM2(), using the wrong RoutingPad
    table to build the wires between M1. The topology was not connecting
    some M1.
2023-07-04 10:22:50 +02:00
Gabriel Gouvine d2c2f977f1 Automatic slice height adjustment for multi-row cells 2023-07-04 10:22:15 +02:00
Jean-Paul Chaput a110a286d2 Forgot configuration files for GF180MCU. 2023-07-04 10:21:58 +02:00
Gabriel Gouvine 73cc5c0e76 Specify branch in Coloquinte submodule + update 2023-07-04 10:21:27 +02:00
Gabriel Gouvine 4973d0a181 Compute space margin from bounding box (for user-specified bounding box) 2023-07-04 10:20:52 +02:00
Jean-Paul Chaput 76e9da0b64 Added support for GF180MCU, part 1.
* New: In LefImport::LefParser, add support for LEF Polygons that are
    translated into Hurricane Rectilinears.
* Change: In LefImport::setMergeLibrary(), the default behavior for the
    LEF parser is to create a new separate library under LEF/<lib_name>
    for each file. But if the various cells are put each one in it's own
    cell, this is suitable. So we can now set a library beforehand into
    which they will be all put.
* New: in CRL/technos.node180.gf180mcu, configuration files for the
    GF180MCU open PDK.
* New: in cumulus/designflow.technos, added a setupGF180MCU_GF() to
    initialize the GF PDK.
2023-07-04 10:20:41 +02:00
Jean-Paul Chaput 3243b12abb Try VH topologies for G180MCU. Not working either... 2023-07-03 20:02:33 +02:00
Jean-Paul Chaput 73265c2d68 Quick and DRC unclean hack to manage rectilinear in LefImport. 2023-07-03 20:00:58 +02:00
Jean-Paul Chaput 47aadd8ef4 Give priority of non-pref segments anchored on punctuals over regular ones.
Introduce a new kind of flag "NonPrefOnVSmall" to mark non-preferred
segments anchoreds on small terminals (i.e. punctual). They should have
absolute priority over segments in prefered direction.
2023-07-03 19:59:10 +02:00
Jean-Paul Chaput 30b92ff33a Add a flag througout all the build system to manage manylinux (PyPI).
* New: In boostrap/FindBootstrap.cmake, add a macro setup_qt() to
    share Python detection across the various tools.
      This macro takes into account the USE_MANYLINUX variable to
    slightly change the Python detection. On a "normal" system we
    look for "Development" (search for dynamic libraries) while under
    manylinux we look for "Development.Module"(static linking).
* Change: In bootstrap/ccb.py, add a new option --manylinux.
* Change: Cleanup in the various CMakeLists.txt to use setup_qt().
2023-07-03 19:54:01 +02:00
Jean-Paul Chaput ecdcabb8ad Merge branch 'coloquinte2' into devel 2023-06-29 21:20:35 +02:00
Gabriel Gouvine b7698e7500 Avoid placement issues on small designs by limiting cell bloat based on row size 2023-06-29 15:17:02 +02:00
Gabriel Gouvine e084c1e672 Apply density variation on the whole placement area, avoiding reduced free space under huge bloat 2023-06-29 15:11:00 +02:00
Gabriel Gouvine 7b155d1ecf Apply library bloating during free space computation 2023-06-29 14:37:46 +02:00
Gabriel Gouvine 06433cc914 Report slice height in Etesian logs 2023-06-29 12:38:22 +02:00
Jean-Paul Chaput 554aded65b Uses the public https address for Coloquinte submodule. 2023-06-26 19:03:15 +02:00
Jean-Paul Chaput 9b38590c60 Add init & update of submodules for Coloquinte 2. 2023-06-26 14:29:00 +02:00
Jean-Paul Chaput 014ec72652 First merge of coloquinte2 & tramontana branches.
Needed to merge thoses two branches as I needed to to uses features
from each other to implement GF180MCU.
2023-06-25 18:11:18 +02:00
Jean-Paul Chaput 007677353f Using the right cell gauge name in GF180MCU techn o file. 2023-06-25 15:29:35 +02:00
Jean-Paul Chaput f8637737a0 Small beautification of the Coloquinte bloat factor display. 2023-06-25 11:57:04 +02:00
Jean-Paul Chaput b77d86c931 Call runScript() with unicorn only when there *is* a graphic interface. 2023-06-25 11:55:27 +02:00
Jean-Paul Chaput d019c6aab5 In designflow, re-export LD_LIBRARY_PATH only if there is an ALLIANCE_TOP. 2023-06-25 11:53:26 +02:00
Jean-Paul Chaput b8f15a2c8f Set patterns to account the DFF in cmos & cmos 45 technologies. 2023-06-25 11:51:31 +02:00
Jean-Paul Chaput 70fb5cfe3f Filter new type of RoutingGauge in KatanaEngine::annotateGlobalGraph().
* Change: RoutingGauge in KatanaEngine::annotateGlobalGraph(), when
    accounting for obstacles, skip new types of RoutingGauges that
    are not accounted either when computing initial edge capacity in
    EdgeCapacity CTOR. Now only take into account the "Default" kind.
2023-06-25 11:49:06 +02:00
Jean-Paul Chaput 5cdb8b25f0 Fix bug in NetBuilderHV::_do_1G_xM1_1PinM2(), using bad RoutingPad.
* Bug: In NetBuilderHV::_do_1G_xM1_1PinM2(), using the wrong RoutingPad
    table to build the wires between M1. The topology was not connecting
    some M1.
2023-06-25 11:08:16 +02:00
Jean-Paul Chaput 0aa9010b32 Merge branch 'coloquinte2' of gitlab.lip6.fr:vlsi-eda/coriolis into coloquinte2 2023-06-23 15:39:30 +02:00
Gabriel Gouvine ee2ed63d35 Automatic slice height adjustment for multi-row cells 2023-06-22 18:28:48 +02:00
Jean-Paul Chaput 72b906cb68 Forgor configuartion files for GF180MCU. 2023-06-22 17:38:03 +02:00
Jean-Paul Chaput 30b69f634a Merge branch 'coloquinte2' of gitlab.lip6.fr:vlsi-eda/coriolis into coloquinte2 2023-06-22 17:36:11 +02:00
Gabriel Gouvine 73925094f1 Specify branch in Coloquinte submodule + update 2023-06-22 17:11:42 +02:00
Jean-Paul Chaput 56da5ebe32 Merge branch 'coloquinte2' of gitlab.lip6.fr:vlsi-eda/coriolis into coloquinte2 2023-06-22 17:09:39 +02:00
Gabriel Gouvine 0dc33538a7 Specify branch in Coloquinte submodule 2023-06-22 17:07:42 +02:00
Gabriel Gouvine 7b7e852f67 Compute space margin from bounding box (for user-specified bounding box) 2023-06-22 17:07:36 +02:00
Jean-Paul Chaput 04410f1cc2 Added support for GF180MCU, part 1.
* New: In LefImport::LefParser, add support for LEF Polygons that are
    translated into Hurricane Rectilinears.
* Change: In LefImport::setMergeLibrary(), the default behavior for the
    LEF parser is to create a new separate library under LEF/<lib_name>
    for each file. But if the various cells are put each one in it's own
    cell, this is suitable. So we can now set a library beforehand into
    which they will be all put.
* New: in CRL/technos.node180.gf180mcu, configuration files for the
    GF180MCU open PDK.
* New: in cumulus/designflow.technos, added a setupGF180MCU_GF() to
    initialize the GF PDK.
2023-06-22 14:13:19 +02:00
Jean-Paul Chaput a3c05c0f60 Merge branch 'coloquinte2' of gitlab.lip6.fr:vlsi-eda/coriolis into coloquinte2
Seems to have been strange things occuring.
2023-06-22 14:01:25 +02:00
Gabriel Gouvine 06ea3d6e09 Export polarity of multi-row cells 2023-06-20 18:30:30 +02:00
Gabriel Gouvine 764464911e Handle multi-row height better for default abutment box 2023-06-20 18:17:19 +02:00
Gabriel Gouvine f0c616a5ea Remove dead code 2023-06-20 15:33:30 +02:00
Gabriel Gouvine 1df76cdf5a Fix orientation issues across rows: MX/MY are exchanged between Coriolis and Coloquinte 2023-06-20 12:18:06 +02:00
Gabriel Gouvine 4fe1436e1f Remove uniform density option, replaced by densityVariation 2023-06-20 12:18:06 +02:00
Gabriel Gouvine 5c75a1ffb7 New densityVariation option to replace uniformDensity 2023-06-20 12:18:06 +02:00
Gabriel Gouvine e395069025 Rename tabs in CGT 2023-06-20 12:18:06 +02:00
Gabriel Gouvine 0743e3bbe4 Introduce a new parameter to handle uniform density 2023-06-20 12:18:06 +02:00
Gabriel Gouvine 665331252e Fix enum values for placement effort in graphical mode 2023-06-20 12:18:06 +02:00
Gabriel Gouvine 0fdc8f6d3f Little bit more cleanup 2023-06-20 12:18:06 +02:00
Gabriel Gouvine 093a4161ef Remove unused datastructures in EtesianEngine 2023-06-20 12:18:06 +02:00
Gabriel Gouvine 011b32d1ed Remove OpenMP flags in nix build 2023-06-20 12:18:06 +02:00
Gabriel Gouvine 238d9dfaba Remove dead antenna diode insertion code 2023-06-20 12:18:06 +02:00
Gabriel Gouvine fb6979db19 Fix orientation handling 2023-06-20 12:18:06 +02:00
Gabriel Gouvine 3d43a25bb4 Default to only showing final placement (update is slow) 2023-06-20 12:18:06 +02:00
Gabriel Gouvine 2bc2e4a988 Improve callbacks 2023-06-20 12:18:06 +02:00
Gabriel Gouvine 1b41976ca1 Callbacks in EtesianEngine 2023-06-20 12:18:06 +02:00
Gabriel Gouvine c178b8c720 Add feed cells in command line call too 2023-06-20 12:18:05 +02:00
Gabriel Gouvine a9041cbb7c Remove useKatana option in CGT (not used anymore) 2023-06-20 12:18:05 +02:00
Gabriel Gouvine 495edc6bfe Enable P&R command line options in graphic mode 2023-06-20 12:18:05 +02:00
Gabriel Gouvine d85e7277a4 Add missing cleanup. Seems to take care of non-determinism at restart 2023-06-20 12:18:05 +02:00
Gabriel Gouvine e723a53b69 Setup row polarity (single row cells at the moment) 2023-06-20 12:18:05 +02:00
Gabriel Gouvine 288d89ba93 Setup Coloquinte callbacks + start rewriting antenna code 2023-06-20 12:18:05 +02:00
Gabriel Gouvine c62383c09f Rewrite EtesianEngine for new coloquinte 2023-06-20 12:18:05 +02:00
Gabriel Gouvine 7091ac3a77 Completely replace old coloquinte by new one 2023-06-20 12:18:05 +02:00
Gabriel Gouvine c0b4aad02b Rewrite of the Etesian engine to run the new placer 2023-06-20 12:18:05 +02:00
Gabriel Gouvine a9f55021fd Add Coloquinte2 to the build 2023-06-20 12:18:05 +02:00
Gabriel Gouvine 5d8b994bb6 Fix orientation issues across rows: MX/MY are exchanged between Coriolis and Coloquinte 2023-06-20 10:47:25 +02:00
Jean-Paul Chaput 9b87b92eec Groudwork for short localization in Tramontana.
In order to accurately find the rectangles (Components) causing a short
circuit, we need to aggregate the equipotentials as soon as we starts
to merge the tiles. Because tiles being a union set, the tree compression
forbid to know which tile overlap which one afterwards. So the equipotentials
are created early on the fly. We also add an accounting of all the net's
components (Plug excluded) to know if it is fully included in the
equipotential. If not, we have an open.

This is an impacting change from the previous version in which we build
the equipotentials *after* aggregating the tiles only. The added cost
comes from the number of equipotential merging that we have to perform
when we merge tiles. Almost two times slower. May need to have a deep
look on how to optimize it later (efficient merge or keeping the order
tiles where merged).
2023-06-16 13:34:36 +02:00
Jean-Paul Chaput 5233d860f4 Slight change in Occurrence::getCompactString() formatting.
* Change: In Occurrence::getCompactString(), when the path is void,
    still display a double colon (::) instead of just one so we know
    for sure that the it is void.
2023-06-16 13:33:50 +02:00
Gabriel Gouvine 6f793665c2 Remove uniform density option, replaced by densityVariation 2023-06-10 14:45:07 +02:00
Gabriel Gouvine 7f0ab625d2 New densityVariation option to replace uniformDensity 2023-06-10 14:35:55 +02:00
Gabriel Gouvine e497a4d48f Rename tabs in CGT 2023-06-10 13:41:41 +02:00
Gabriel Gouvine 052df5d1c8 Introduce a new parameter to handle uniform density 2023-06-10 13:29:56 +02:00
Gabriel Gouvine 4731e30bb3 Fix enum values for placement effort in graphical mode 2023-06-09 16:12:20 +02:00
Gabriel Gouvine 078e4e0644 Little bit more cleanup 2023-06-09 16:07:19 +02:00
Gabriel Gouvine 23975c541d Remove unused datastructures in EtesianEngine 2023-06-08 18:45:19 +02:00
Gabriel Gouvine 0fe1deac94 Remove OpenMP flags in nix build 2023-06-08 17:11:48 +02:00
Gabriel Gouvine db01b4ff55 Remove dead antenna diode insertion code 2023-06-08 17:11:40 +02:00
Gabriel Gouvine 1f5549d396 Fix orientation handling 2023-06-08 14:21:00 +02:00
Gabriel Gouvine 62e7640a37 Default to only showing final placement (update is slow) 2023-06-08 14:20:56 +02:00
Gabriel Gouvine 1beaaf93e4 Improve callbacks 2023-06-06 15:29:29 +02:00
Gabriel Gouvine fb694e1c3d Callbacks in EtesianEngine 2023-06-06 12:13:07 +02:00
Gabriel Gouvine d873216447 Add feed cells in command line call too 2023-06-04 13:21:42 +02:00
Gabriel Gouvine 49e95115f2 Remove useKatana option in CGT (not used anymore) 2023-06-04 13:19:21 +02:00
Gabriel Gouvine 2ea099afec Enable P&R command line options in graphic mode 2023-06-04 13:18:20 +02:00
Gabriel Gouvine 26184c5016 Add missing cleanup. Seems to take care of non-determinism at restart 2023-06-04 11:01:51 +02:00
Gabriel Gouvine acf6cfe041 Setup row polarity (single row cells at the moment) 2023-06-03 12:41:11 +02:00
Gabriel Gouvine 585489860e Setup Coloquinte callbacks + start rewriting antenna code 2023-06-03 12:00:33 +02:00
Gabriel Gouvine 4f1ce6cfcb Rewrite EtesianEngine for new coloquinte 2023-06-02 14:44:30 +02:00
Jean-Paul Chaput 21eedbcc2b Change in strategy for guessing Alliance top cells directory.
* In cumulus.designflow.technos.setupCMOS(): export back the guessed
    ALLIANCE_TOP *before* importing technos.symbolic.cmos so it is
    used for the CELLS_TOP. This avoid defaulting to /soc/alliance
    which does exists only on LIP6 computers...
2023-05-28 15:31:47 +02:00
Gabriel Gouvine 393204ba0d Completely replace old coloquinte by new one 2023-05-26 15:09:52 +02:00
Jean-Paul Chaput 46c685a7f8 Install Alliance in Release.Shared, not Debug.Shared. 2023-05-25 23:10:49 +02:00
Gabriel Gouvine 1e71b5fb08 Rewrite of the Etesian engine to run the new placer 2023-05-19 17:31:26 +02:00
Gabriel Gouvine 3830a90482 Add Coloquinte2 to the build 2023-05-16 09:20:52 +02:00
Jean-Paul Chaput d41e328253 Added easier access to devices parameters in AnalogDesign. 2023-05-08 20:00:47 +02:00
Jean-Paul Chaput 7cfd056da2 Completed inspector support on analog transitors. 2023-05-08 20:00:29 +02:00
Jean-Paul Chaput 56883db08e Display a window title when the viewer starts empty. 2023-05-07 12:16:18 +02:00
Jean-Paul Chaput abee13d669 Small improvement to the NetlistWidget (more fields). 2023-05-07 11:54:04 +02:00
Jean-Paul Chaput 96e6c9dd06 Fix a sync problem between the EquiWidget and the SelectionWidget. 2023-05-06 18:13:39 +02:00
Jean-Paul Chaput c53fc01cb2 Add Rectilinear & "cut" support to the extractor.
Note about the managment of VIA & cuts: Components using a layer which
  is a ViaLayer, that is one containing more than one BasicLayer,
  multiple tiles are created in QueryTiles::goCallback().
    Components that have a single BasicLayer of "cut" material will
  also have their multiples tiles created in QueryTiles::goCallback().
    Rectilinear components will have their multiples tiles created
  in Tile::create(). Tile::create() return not all the tiles but the
  one used as root (for the union find).

* New: In SweepLine::_buildCutConnexMap(), when using a "cut" layer
    in a standalone way, and not as part of a ViaLayer, we do not
    automatically know to which layer above & below they are connected.
      We build a table for each cut layer, based on the ViaLayer,
    to know all tops & belows layers they connect (this is cumulative,
    in the case of "cut" towards the substrate).
      Then in Tile::create(), we not only create the tile for the "cut"
    but also in thoses connected layers (and link them in the union
    find).
* New: In Tile::create(), when we encounter a Rectilinear, break it
    into rectangles and make as many tiles. All tiles linked to the
    same root in the union find.
* Bug: In Hurricane::Rectilinear, ambiguous specification of the set
    of points defining the shape. I did suppose that the start and and
    point where not the same the last edge being between them.
      But if FlexLib, it uses the GDSII inspired convention where the
    first and last point must be the same, to indicate a closed contour.
      This difference was not causing any difference with the drawing,
    but it was a problem for getAsRectangle(). This was creating a
    "false" extra vertical edge leading to a bigger rectangle.
    And this, in turn, was making "false" intersections in the
    tiling/sweepline of the extractor.
      Add a more thorough checking of the points vector.
2023-05-05 16:22:51 +02:00
Jean-Paul Chaput 52fd1c1c40 Add vertical rectangles partionning to Rectilinear.
* New: Rectilinear::asRectangles(), decompose the Rectilinear into a
    set of non-overlapping rectangles sliced vertically.
      This not a mathematical minimum set. But should be speedier.
      Done using a sweepline processing the vertical edges.
      Specially suited for use in the extractor which basically
    manage only rectangles.
      Simple algorithm described in pp. 9-11 of Extractor notebook.
      Tests done with unitests/python/test_rectilinear.py, the
    Rectilinear here should cover all the sweepline cases.
2023-05-03 17:08:57 +02:00
Jean-Paul Chaput ae5f6ad3de Added some more debug info in capacitors. 2023-04-26 19:34:22 +02:00
Jean-Paul Chaput a31cf3d334 Fix SRAM import hierarchy for new coriolis namespace. 2023-04-26 11:46:53 +02:00
Jean-Paul Chaput 4c7cf227be Add ability to "filter out" buried net in TabEquipotentials.
Definition: A buried net is a net that has no components at the top
Cell level. Typically example is a wire internal to a standard cell.
Those nets, while part of the complete design (flat) are not part
of the top netlist, and we may want not to see it.
  A buried net is slighly different from a deep net. While a deepnet
is also not reaching the top level cell, we created it at top level
to be processed by the router (virtual flatten).
2023-04-14 01:07:40 +02:00
Jean-Paul Chaput d928a3c7a5 Merge branch 'devel' of gitlab.lip6.fr:vlsi-eda/coriolis into tramontana 2023-04-13 14:05:48 +02:00
Jean-Paul Chaput c3bed61257 Full transhierarchical implementation done.
* New: Equipotential elements includes now:
    1. Components at the top level (the cell owning the Equi).
    2. Nets at the top level. If an equi include all the components
       of a Net, own the Net, not all it's individual components.
    3. Other equipotentials from the Instances immediatey below.
       Thoses equis should be equivalents to the Plug of the Net.
       They are stored in the form of Occurrences <Instance,Equi>,
       the relation is stored on that Occurrence.
* New: Equipotential::getFlatComponents(), a collection to recursively
    get all the *component* occurrences of the equi. Transhierarchically.
    Go through components, nets components, and recursively through
    the child equis.
* New: EquipotentialRelation, the master of this relation is the
    Equipotential and the slaves, all its elements.
* Change: In Tile, in case the tile is build on a deep component,
    we trace up the Equipotential it belongs to in the Instance
    level immediately belonging to the Cell under extraction.
    They must exists as we extract from bottom to top all the
    master cells. So we have, for that tile an Occurrence
    <Instance,Equi> that we can store in the current Equi level.
* Change/Bug: In Tile, add an Id to be reliably sort the tiles
    in the IntervalTree. As we replaced the tile component occurrence
    by a <Instance,Equi> we were having multiple tiles with the same
    equi. This was causing havoc again in the IntervalTree.
      Should add a check in the RbTree for elements with the
    exact same key, but that would imply passing a new template
    parameter for the "equal" function.
2023-04-13 14:00:50 +02:00
Jean-Paul Chaput 57bab117b4 Add typedef NetSet, for set of Net* sorted by Ids. 2023-04-13 00:18:10 +02:00
Jean-Paul Chaput 31b0c4daf1 Add selection/unselection by Occurrence collection in CellWidget. 2023-04-13 00:15:38 +02:00
Jean-Paul Chaput b9862ecd5e Fix scaling in CellImage::toImage(), compute size from *screen widget*. 2023-04-13 00:14:12 +02:00
Gabriel Gouvine 4b15396444 Remove old steps from the installation 2023-04-04 16:20:29 +02:00
Gabriel Gouvine 8bd0a3b0c8 Do not show shell guess ofr directory queries 2023-04-04 16:17:13 +02:00
Jean-Paul Chaput e04f6b1cbc Make it work under the bootstrap dir for directories queries. 2023-04-04 16:13:59 +02:00
Jean-Paul Chaput 518a376c01 Transhierarchical/flat extraction work, no netlist rebuild yet.
* Bug: In Interval::intersect(), bad condition check in strict mode.
* Change: In Occurrence::operator<(), change the sorting criterions
    so that the ones with no paths are "lower", then the one with
    no entities, then compare entities Id then Path hashes.
* Change: In Occurrence::getCompactString(), to be more readable,
    suppress leading and ending "<>".
* Change: In IntervalTree, now use an IntervalDataCompare to control
    the ordering of the nodes inside the tree. This may be needed
    when IntervalData is build upon a pointer, we don't want to
    sort on pointer values (non deterministic) .
* Bug: In IntervalTree::postRemove(), there was an incorrect computation
    of the updated childsVMax.
* Bug: In IntervalTree::beginOverlaps(), miscalculated leftmost
    interval overlapping.
* Bug: In RbTree::remove(), when exchanging the removed node for a
    leaf, fully swap the nodes contents, was incompletly copied before.
* New: In CellWidget, add new slots selectSet(OccurrenceSet&) and
    unselectSet(OccurrenceSet&), to be able to select/unselected sets
    of Occurrence (for use by TabEquipotentials).
* Change: In EtesianEngine, no more need to remove leading/ending "<>".
* New: In Tramontana, use a Query to find all the Occurrence under
    an area. Previously we were using Cell::getOccurrencesUnder()
    which *do not* return the components in instances, so we would
    have been unable to find trans-hierarchical shorts circuits.
* New: In tramontana, now use a Relation to tag all the components
    belonging to an Equipotential.
* Change: In Equipotential, store everything under the form of
    Occurrence, instead of Components. Due to the way the Occurrences
    are sorted, the one holding Components should be firts.
2023-04-02 23:02:46 +02:00
Jean-Paul Chaput 6361ad4ca0 Move the Tramontana menu from P&R to Tools. 2023-03-28 16:09:00 +02:00
Jean-Paul Chaput e968a5088f Added recursive extraction of all instances models in Tramontana. 2023-03-28 16:08:11 +02:00
Jean-Paul Chaput 5afb4cabe9 Add a verbose option to ToolEngine, don't always display infos. 2023-03-28 16:06:49 +02:00
Jean-Paul Chaput 23c0c24c0f Non-hierarchical, metal only, rectangle only, extractor is now working.
* New: In Tramontana,
  * Multi-layer support for the swap line. Split VIAs into their
    various metal plates and link the two relevant tiles, ensuring
    connexity between layers.
  * Improved Equipotential information rebuild. Try to rebuild more
    closely the Net characteristics. Improved tab widgets.
2023-03-28 15:13:02 +02:00
Jean-Paul Chaput 2568a1a496 Added deletion tests for RbTree & IntervalTree in unittests. 2023-03-28 15:12:31 +02:00
Jean-Paul Chaput e22e7f7476 IntervalTree is now support multiple intervals with same lower bound.
* New: Interval::CompareByMinMax, lexicographical comparison of
    Intervals, first compare the lower bound (VMin) then the
    upper bound (VMax). Needed for IntervalTree.
* Change: In IntervalTree, the key comparison was only based on
    the lower bound (VMin). That means that the tree would accept
    only one interval for a given VMin. You couldn't store both
    [1:4] and [1:5]. Now use CompareByMinMax that allows it.
2023-03-28 14:52:23 +02:00
Jean-Paul Chaput a0911be50a Add complete support for Equipotential selection in the Controller. 2023-03-26 21:15:15 +02:00
Jean-Paul Chaput e5d9c8808b Reduce the default pixel threshold to 5. 2023-03-26 21:12:49 +02:00
Jean-Paul Chaput 7ed41613de Add ControllerWidget::insertAfterTab() to put a new tab where we want. 2023-03-26 21:12:14 +02:00
Jean-Paul Chaput 50a9036d28 Add support for selection by ComponentSet in CellWidget.
* New: In Component, typedef ComponentSet (set sorted on Ids).
* New: CellWidget::selectSet() & CellWidget::unselectSet() select/unselect
    a whole set of component.
2023-03-26 21:08:58 +02:00
Jean-Paul Chaput 8f387620cb One Layer, one Cell extraction implementation in Tramontana.
* New: Tramontana::Equipotential, implemented.
* Change: Tramontana::Tile, add UnionFind capabilities and Equipotential
    attribute.
* New: Tramontana::SweepLine, build upon Hurricane::IntervalTree,
    can now perform a "one layer only" extraction (checked with "metal1").
2023-03-18 18:17:23 +01:00
Jean-Paul Chaput 5879a5b581 Removing Solstice & Equinox from Unicorn (forgotten bits). 2023-03-18 18:12:24 +01:00
Jean-Paul Chaput 1f4b9450e5 Fix, IntervalTree::overlap_iterator was progressing one step too far. 2023-03-18 18:11:03 +01:00
Jean-Paul Chaput 090c13663e Create stub for Tramontana, reimplementation of the extractor/LVX. 2023-03-16 15:06:11 +01:00
Jean-Paul Chaput b7f6af8588 Add a specific "ps" command under Cygwin in coriolisEnv.py. 2023-03-15 12:06:44 +01:00
Jean-Paul Chaput 91e7685921 Try a more portable call of "ps" in coriolisEnv.py. 2023-03-14 18:29:37 +01:00
Jean-Paul Chaput 9cfa104836 Build against Qt5 by default. Uses --qt4 to force uses of Qt4.
* Change: In bootstrap, FindBootstrap.cmake, ccb (builder) & socInstaller,
    suppress the "--qt5" argument as it the default now. Create a "--qt4"
    to force building against the old one.
2023-03-13 17:37:19 +01:00
Jean-Paul Chaput 8a23a89f5d Rewrite backward compatibility for Qwt 5 (Qt4) for SlicingPlotWidget. 2023-03-13 16:51:16 +01:00
Jean-Paul Chaput 8353df1ee6 Use smaller font for code block in documentation (nest.css). 2023-03-13 16:45:42 +01:00
Jean-Paul Chaput 03c424f1a1 Add bop detection on allianceInstaller.sh. 2023-03-10 22:20:09 +01:00
Jean-Paul Chaput b4fe1a3686 Add a fallback when the "ps" command fail in coriolisEnv.py. 2023-03-09 19:07:22 +01:00
Jean-Paul Chaput 87fd1fa7b6 Fix missing Python link libraries, more of them. 2023-03-09 18:39:48 +01:00
Jean-Paul Chaput 7a644c65fb Add support for the Python benchs (doit) in socInstaller.py. 2023-03-09 15:35:44 +01:00
Jean-Paul Chaput 1f16642c82 Restore alternate support for Qt 4. 2023-03-09 15:30:23 +01:00
Jean-Paul Chaput 79d8461c8f Fix missing libraries in Flute Python wrapper (linking). 2023-03-09 15:25:26 +01:00
Jean-Paul Chaput 881e97bbd3 Fix missing libraries problems (seen on Cygwin).
* Change: In bootstrap/cmake_modules/FindBootstrap.cmake, add a
    "-Wl,--no-undefined" to the C++/ld flags to force checking of
    undefined symbol at link time.
2023-03-07 17:29:40 +01:00
Jean-Paul Chaput aafec8c64c Fix a conflict with predefined macro "_B" in Hurricane::Diagonal. 2023-03-07 17:21:08 +01:00
Jean-Paul Chaput 1e8c304ac5 Fix: designflow/klayout.py rule forgot to add targets. 2023-03-07 11:52:52 +01:00
Jean-Paul Chaput 842c2dfffc Late import of pyosys to not block if N/A in designflow/yosys.py. 2023-03-06 14:58:39 +01:00
Jean-Paul Chaput 461b81bb75 Reverse commit #c7608998 (LD_LIBRARY_PATH), was not the problem. 2023-03-06 14:49:30 +01:00
Jean-Paul Chaput d7c9316920 Forgot to update default techno loading with coriolis namespace. 2023-03-03 16:03:54 +01:00
Jean-Paul Chaput 3fdef7aa8d Remove deprecated Kite reference in designflow/pnr.py. 2023-03-03 15:40:42 +01:00
Jean-Paul Chaput c7608998ce Comprehensive LD_LIBRARY_PATH init in coriolisEnv.py.
* In bootstrap/coriolisEnv.py, under WSL it seems that setting up the
    LD_LIBRARY_PATH makes the linker to ignore /etc/ld.so.conf.
    To avoid that, use ldconfig to import all the known paths into
    LD_LIBRARY_PATH.
2023-03-03 15:39:38 +01:00
Jean-Paul Chaput 57b5cca27f Downgrade CMake requirements to 3.16. Detects correctly Python 3.
Fix courtesy of N. Shimizu.
2023-03-03 15:36:40 +01:00
Jean-Paul Chaput 50937d69c7 Add basic yosys (nopy), klayout scripts and command support to designflow.
* New: In cumulus.designflow: add yosysnp to manage Yosys without
    Python support enabled.
      Add klayout support for running scripts in batch mode.
      Add generic system command support.
* Change: In cumulus.designflow.task.TaskFlow, systematically
    convert pathes (str) into pathlib.Path in targets and depends.
* New: In cumulus.designflow.clean.Clean, add cleaning by glob.
2023-03-01 23:57:55 +01:00
Jean-Paul Chaput 5546c2d89f Fix nightly build path finding in crlenv.py. 2023-03-01 11:42:50 +01:00
Jean-Paul Chaput 94323f28e0 Merge branch 'poetry-cleanup' of gitlab.lip6.fr:vlsi-eda/coriolis into devel 2023-02-28 13:49:20 +01:00
Jean-Paul Chaput c68932c813 Policy change for NDA/third party modules loading ("addons.coriolis").
* Change: In cumulus/plugins/__init__.py, new behavior for loading
    plugins supplied as third party. In order to avoid messing up
    with the "site-packages/coriolis/" main package tree (with
    modules named "coriolis.<MODULE>", they have to be under
    "site-packages/addons/coriolis/" (so modules will be named
    "addons.coriolis.<MODULE>"). This should prevent *overwritting*
    standard modules by third party ones.
      Now uses pathlib for module loading.
      Had a conflict between Hurricane.Path and pathlib.Path, now do
    not import the Hurricane one into the module globals...
2023-02-28 13:32:11 +01:00
Jean-Paul Chaput 800305abc3 Removed long obsoleted XML techno config files. 2023-02-27 23:08:03 +01:00
Jean-Paul Chaput f404bcc8c0 Fix small regression in initHook.py of bora & katana. 2023-02-27 22:34:44 +01:00
Jean-Paul Chaput 1557d613ae Comprehensive reorganisation of the Python part of Coriolis.
* Move all Python stuff under a common Python namespace "coriolis".
* Instead of having a series subtrees for each tool, integrate
  everything in one common tree. So now, all components can be
  located either with an absolute path from "coriolis" or, inside
  cross-reference themselves through relatives imports.
* As a consequence, we only need to add ".../site-packages/coriolis/"
  to the PYTHONPATH, and not a whole bunch of subdirectories.
  And nothing, if installed in-system.
* The tree of free technologies configuration files is also moved
  below "coriolis/technos" instead of "/etc".
* Supressed "cumulus" level for the plugins.
* All python modules are rewritten using relative imports except
  for the configuration files that uses absolute import as they
  can be cloned outside of the tree to serve as templates.

* Change: In boostrap/FindPythonSitePackages, include "/coriolis" in
    Python_CORIOLISARCH and Python_CORIOLISLIB.
      Provide a Python_SITELIB *without* "/coriolis" appended.
* Change: In cumulus/plugins/__init__.loadPlugins(), must prefix modules
    read in the plugins directory by "coriolis.plugins.". No longer need
    to add their path to sys.path.
* Change: In crlcore/python/technos/nodeX/*/devices.py, the scripts of
    the layouts generators must be prefixed by "coriolis.oroshi.".
* Change: In CRL::System CTOR, no longer add the pathes of the various
    plugins to sys.path. Only "site-packages/coriolis/".
* New: In Utilities::Path::toPyModePath(), new method to convert a
    filesystem path into a python module path.
      Examples:
        "coriolis/plugins/block"    --> "coriolis.plugins.block".
        "coriolis/plugins/rsave.py" --> "coriolis.plugins.rsave".
* Change: In katanaEngine::_runKatanaEngine(), rename the hook script
    initHook.py. No longer need to modify sys.path.
* Change: In BoraEngine::_runBoraEngine(), rename the hook script
    initHook.py. No longer need to modify sys.path.
* Change: In UnicornGui::_runUnicornInit(), rename the hook script
    initHook.py. No longer need to modify sys.path.
* Change: In cumulus.plugins.chip.constants, put the constants
    outside __init__.py to avoid a loop at initialization.
2023-02-27 22:14:32 +01:00
Jean-Paul Chaput c37e6ff953 Regenerated documentation, just to check. 2023-02-22 15:02:39 +01:00
Jean-Paul Chaput b6961a10c9 Deprecation of Mauka & hMetis (old simulated annealing placer). 2023-02-21 17:06:16 +01:00
Jean-Paul Chaput 3d9e86303e Final deprecation of Katabatic, Knick & Kite. 2023-02-21 17:04:38 +01:00
Robert Taylor fabcabe31d Add pattern back in for git tag versioning 2023-02-21 16:10:55 +01:00
Robert Taylor 6b455b66d5 Use metadata in version number 2023-02-21 16:10:55 +01:00
Robert Taylor d49c76791a Don't package docs in the wheel 2023-02-21 16:10:55 +01:00
Robert Taylor 4aa7b680a7 Use git tags to version releases 2023-02-21 16:10:55 +01:00
Robert Taylor a1bd7cae8a Add readme to pyproject.toml 2023-02-21 16:10:55 +01:00
Robert Taylor 3d25c6881d Upload wheels in CI 2023-02-21 16:10:55 +01:00
Robert Taylor 3196196642 enable epfl repo 2023-02-21 16:10:55 +01:00
Robert Taylor 42de4409c5 CI: fix architectures 2023-02-21 16:10:55 +01:00
Robert Taylor d8e67e5e7d Reduce debug output 2023-02-21 16:10:55 +01:00
Robert Taylor f0cd6e602a Use ninja for build 2023-02-21 16:10:55 +01:00
Robert Taylor d10b7524ce remove cylop and cx2y from scripts 2023-02-21 16:10:55 +01:00
Robert Taylor fa1f8e78e0 CI: only build cpython >= 3.8 2023-02-21 16:10:55 +01:00
Robert Taylor 32a6aaf61f Ignore missing symbols harder when linking python 2023-02-21 16:10:55 +01:00
Robert Taylor 7a8a3d3434 Always pass build type 2023-02-21 16:10:55 +01:00
Robert Taylor 8f8671c8fb Only build cycop and x2y when in debug build 2023-02-21 16:10:55 +01:00
Robert Taylor a02c88a893 Don't link libpython, it isn't there in manylinux 2023-02-21 16:10:55 +01:00
Robert Taylor eb26bb1f87 fix to build on manylinux 2023-02-21 16:10:55 +01:00
Robert Taylor 6088ab7b69 Split out python versions in CI 2023-02-21 16:10:55 +01:00
Robert Taylor c22dfe3216 Pass in python library path to cmake 2023-02-21 16:10:55 +01:00
Robert Taylor 095e260e3b Use target_link_libraries correctly everywhere to avoid runtime link issues 2023-02-21 16:10:55 +01:00
Robert Taylor 974473aff7 fix rpaths - really didn't need quoting 2023-02-21 16:10:55 +01:00
Robert Taylor 78f4107f36 Update poetry lock 2023-02-21 16:10:55 +01:00
Robert Taylor 0868283e43 Fix runtime linking error 2023-02-21 16:10:55 +01:00
Robert Taylor 4e879b4506 RPATH for libraries to find other coriolis libs 2023-02-21 16:10:55 +01:00
Robert Taylor 412f9bb22d Fixes for cibuildwheel building 2023-02-21 16:10:55 +01:00
Robert Taylor e1736fcdba Support older qwt 2023-02-21 16:10:55 +01:00
Robert Taylor 7789c6db80 update poetry lock 2023-02-21 16:10:55 +01:00
Robert Taylor 52f64bc9d3 Use the running python for cmake 2023-02-21 16:10:55 +01:00
Robert Taylor 2b88f8188c try dropping python dependancy and see what breaks 2023-02-21 16:10:55 +01:00
Robert Taylor e7fcfd1a44 Add gitlab CI using cibuildwheel 2023-02-21 16:10:55 +01:00
Robert Taylor 29add5e898 Fix tutorial for python 3 2023-02-21 16:10:55 +01:00
Robert Taylor 05c0f955c5 Fix up rpath of binaries 2023-02-21 16:10:55 +01:00
Robert Taylor c6795754a1 Move into Corilois namespace 2023-02-21 16:10:55 +01:00
Robert Taylor a3abb567b5 Add version and author to pyproject.toml 2023-02-21 16:10:55 +01:00
Robert Taylor 424c61d6a4 Fix errors when building clean 2023-02-21 16:10:55 +01:00
Robert Taylor ebabf1e988 install helpers at top level 2023-02-21 16:10:55 +01:00
Robert Taylor df78c3ab48 Add bin files as scripts 2023-02-21 16:10:55 +01:00
Robert Taylor 5a669c4641 Fix Python linking issues 2023-02-21 16:10:55 +01:00
Robert Taylor b07bf75283 Give same import semantics for now, fix rpath issue 2023-02-21 16:10:55 +01:00
Robert Taylor ee2e18f801 Add Coriolis dir that poetry needs, along with base __init__.py 2023-02-21 16:10:55 +01:00
Robert Taylor d614e490e7 Poetry package build working for most of coriolis 2023-02-21 16:10:55 +01:00
Robert Taylor f8afd5bded Move to packaging requiring no changes to CMake 2023-02-21 16:10:54 +01:00
Robert Taylor 806018b740 Initial Poetry infrastructure 2023-02-21 16:10:54 +01:00
Robert Taylor 858a783ddd Move decprecated components out of the way, to avoice confusion 2023-02-21 16:10:54 +01:00
Jean-Paul Chaput db56681025 More tweaking in the H-Tree Y offset, to avoid stacked VIAs. 2023-02-15 15:17:28 +01:00
Jean-Paul Chaput 07f269196b Manage new cases of stacked VIAs potential creation.
When placing a vertical M1 (and setting it's axis), the perpandiculars
M2 extremities changes, and they have a VIA. If they are already placed
too, they may silently create a stacked VIAs because the track markers
of the perpendiculars are not taken into account. Now, force to rip them
up so the markers will be re-read. If no stacked VIAs has been created,
the segment will be re-put at it's previous place, otherwise it will be
placed on another track.

* New: Track::hasViaMarker(), check if a marker of a Net is under a
    given interval (so we can know we are about to create a VIA stack).
* New: Manipulator::avoidStackedVias(), ripup perpandiculars to the
    current segment that *may* create stacked VIAs. That is perpandicular
    in the *up* layer which begin or end on the moved vertical.
* New: In SegmentFsm::insertInTrack(), bindTotrack() & moveToTrack(),
    call Manipulator::avoidStackedVias(), if activated.
* Change: In NegociateWidow/loadRoutingPads(), no longer exclude clock
    nets. So the TrackMarkers are created for the root net.
2023-02-14 22:35:56 +01:00
Jean-Paul Chaput 77afb7cba4 Quick for H-Tree driver Y offset (account for root & symmetry). 2023-01-23 14:46:30 +01:00
Robert Taylor cf92ee9588 Add pattern back in for git tag versioning 2023-01-20 16:13:36 +00:00
Robert Taylor 53af6a2a87 Use metadata in version number 2023-01-19 16:04:18 +00:00
Robert Taylor 0860dffb61 Don't package docs in the wheel 2023-01-19 16:04:18 +00:00
Robert Taylor 8d74ed8110 Use git tags to version releases 2023-01-19 16:04:18 +00:00
Robert Taylor b8d2a0e598 Add readme to pyproject.toml 2023-01-19 16:04:18 +00:00
Robert Taylor 4cab713fc9 Upload wheels in CI 2023-01-19 16:04:18 +00:00
Robert Taylor 651cf57a13 enable epfl repo 2023-01-19 16:04:18 +00:00
Robert Taylor 4281370f2e CI: fix architectures 2023-01-19 16:04:18 +00:00
Robert Taylor d7f6917047 Reduce debug output 2023-01-19 16:04:18 +00:00
Robert Taylor 64b0fda925 Use ninja for build 2023-01-19 16:04:18 +00:00
Robert Taylor aac5b8554b remove cylop and cx2y from scripts 2023-01-19 16:04:18 +00:00
Robert Taylor b5a669291e CI: only build cpython >= 3.8 2023-01-19 16:04:18 +00:00
Robert Taylor 69bdbd9cd8 Ignore missing symbols harder when linking python 2023-01-19 16:04:18 +00:00
Robert Taylor e8f31aa852 Always pass build type 2023-01-19 16:04:18 +00:00
Robert Taylor 56e31c79b7 Only build cycop and x2y when in debug build 2023-01-19 16:04:18 +00:00
Robert Taylor 1b9a91cb1c Don't link libpython, it isn't there in manylinux 2023-01-19 16:04:18 +00:00
Robert Taylor 05fbfbe7fe fix to build on manylinux 2023-01-19 16:04:18 +00:00
Robert Taylor 4da93f3394 Split out python versions in CI 2023-01-19 16:04:18 +00:00
Robert Taylor b2bbaead53 Pass in python library path to cmake 2023-01-19 16:04:18 +00:00
Robert Taylor 56aa1b189c Use target_link_libraries correctly everywhere to avoid runtime link issues 2023-01-19 16:04:17 +00:00
Robert Taylor deaff0842f fix rpaths - really didn't need quoting 2023-01-19 16:04:17 +00:00
Robert Taylor 90c478e8c4 Update poetry lock 2023-01-19 16:04:17 +00:00
Robert Taylor 4b7973ac84 Fix runtime linking error 2023-01-19 16:04:17 +00:00
Robert Taylor 8ccd9618dd RPATH for libraries to find other coriolis libs 2023-01-19 16:04:17 +00:00
Robert Taylor c1fdf4963b Fixes for cibuildwheel building 2023-01-19 16:04:17 +00:00
Robert Taylor 842602cdcb Support older qwt 2023-01-19 16:04:17 +00:00
Robert Taylor e72c2b7af1 update poetry lock 2023-01-19 16:04:17 +00:00
Robert Taylor b638f235a7 Use the running python for cmake 2023-01-19 16:04:17 +00:00
Robert Taylor f3186d7ed1 try dropping python dependancy and see what breaks 2023-01-19 16:04:17 +00:00
Robert Taylor 06dfdfb52f Add gitlab CI using cibuildwheel 2023-01-19 16:04:17 +00:00
Robert Taylor 198d5ce035 Fix tutorial for python 3 2023-01-19 16:04:17 +00:00
Robert Taylor 449ee2e81e Fix up rpath of binaries 2023-01-19 16:04:17 +00:00
Robert Taylor f604351fa2 Move into Corilois namespace 2023-01-19 16:04:17 +00:00
Robert Taylor 546dfa2f20 Add version and author to pyproject.toml 2023-01-19 16:04:17 +00:00
Robert Taylor c0054eb267 Fix errors when building clean 2023-01-19 16:04:17 +00:00
Robert Taylor 46acf17e47 install helpers at top level 2023-01-19 16:04:17 +00:00
Robert Taylor a0b307b3b4 Add bin files as scripts 2023-01-19 16:04:17 +00:00
Robert Taylor cd4f8560ca Fix Python linking issues 2023-01-19 16:04:17 +00:00
Robert Taylor 8dfd522b71 Give same import semantics for now, fix rpath issue 2023-01-19 16:04:17 +00:00
Robert Taylor d31c489e33 Add Coriolis dir that poetry needs, along with base __init__.py 2023-01-19 16:04:17 +00:00
Robert Taylor 80e83d42ed Poetry package build working for most of coriolis 2023-01-19 16:04:17 +00:00
Robert Taylor 57ac01b54a Move to packaging requiring no changes to CMake 2023-01-19 16:04:17 +00:00
Robert Taylor c277d9f121 Initial Poetry infrastructure 2023-01-19 16:04:17 +00:00
Robert Taylor c41b92e45f Move decprecated components out of the way, to avoice confusion 2023-01-19 16:04:17 +00:00
Jean-Paul Chaput f7b2a4f5bb The previous fix for low metal tech, must apply only for them in htree. 2023-01-19 14:54:00 +01:00
Jean-Paul Chaput 38cc00005d Fix missing VIA & bad offset in htree for low metal techs. 2023-01-19 13:57:35 +01:00
Jean-Paul Chaput 96fe367cc0 Fix overlap of non-used RoutinPads in VH,2RL styles.
* New: In KatanaEngine::digitalInit(), when using a "VH,2RL" style,
    protect all RoutingPads of each net, because unlike "2RL+" style,
    the standard cell RoutingPads are not in a "below" layer only
    used inside the cell, but on the V layer. So the area of the RP,
    even if not fully used to connect, must be protected.
* Change: In NegociateOverlapCost(), when computing cost from a fixed
    or blockage, do not set the infinite flag if it's the *same* net.
* New: In KatanaEngine::protectRoutingPads(), add a new "flags" argument
    to pass on whether we want to protect the the RP candidates or just
    the non-used ones.
* Change: In protectRoutingpad(), change the formula (again) to compute
    the berth to give to a fixed segment... Should really try to
    summarize all the case.
* Change: In TrackFixedSegment::getNet(), no longer return the blockage
    net if the real net is tagged as clock.
2023-01-18 23:42:38 +01:00
Jean-Paul Chaput 047bf14921 Wrong computation of the up/down dogleg layer for 2 layers gauges.
* Bug: In Anabatic::AutoHorizontal::_makeDogleg(), the up/down flag
    was incorrectly computed when the RoutingGauge RL where not the
    lower one. This was leading to making doglegs in non-routable
    layers (but present in the gauge for other purposes).
2023-01-18 23:42:17 +01:00
Jean-Paul Chaput 2116e181de Add a breakpoint *before* global routing loading in cumulus/block.py. 2023-01-18 23:20:28 +01:00
Jean-Paul Chaput c7330041fb Remove unmatched DebugSession::close() in RawGCellsUnder. 2023-01-18 15:49:51 +01:00
Jean-Paul Chaput 7598485a4f Allow the BigVia to stack the cuts in some cases. 2023-01-14 22:38:36 +01:00
Jean-Paul Chaput 9df5fc838c Support for non-stacked VIAs in Katana.
* New: In Katana::Configuration, added option:
    "cfg.katana.disableStackedVias" (default to false), so the router
    do not stack VIAs on top of each other.
* Bug: In NegociateWindow::loadRoutingPads(), create TrackMarkers using
    the right depth when the gauge starts with non-routable ones.
* New: In Track::addOverlapCost(), when disableStackedVias is active,
    uses the markers from the below terminals to tag the cost as
    "infinite", so the track *cannot* be used by the marker's net
    owner. Can be refined by checking that we are not at a segment's
    end but will do for now.
2023-01-14 22:35:57 +01:00
Jean-Paul Chaput 7d88b14334 Keep Sphinx variant documentation sources, just in case... 2023-01-14 12:45:08 +01:00
Jean-Paul Chaput 0a69e7d62d Correct broken links in Python Tutorial documentation. 2023-01-14 12:41:06 +01:00
Jean-Paul Chaput 181b2e1080 Re-enable and check the building of I/O ring with pad spacers.
* New: In cumulus/block.bigvia, add a getBoundingBox() method.

* New: In cumulus/block.configuration.GaugeConf.rpAccess(),
    add a vertical strap segment in case the RP is not high enough to
    accomodate the potential offset of the contact.
      In case of gauge with only two routing layers, if the RP
    is vertically accessed, do not put a VIA12 but just a METAL2
    contact (there will be *no* turn).

* Change: In cumulus/chip.CoreWire.drawWire(), the wire at *chip level*
    going to the pad was shrunk of 3 pitch when *not* in the preferred
    routing direction. Removing it as it creates gaps in some cases.
      This was likely needed for a specific kind of I/O pad so should
    be re-enabled on targeted cases in the future.

* Change: In cumulus/chip.corona.VerticalRail, manage in a smarter way
    the conflicts when a rail is accessed from both sides overlapping
    on an Y position. That is, from the supply I/O pads *and* from the
    *core* supply lines.
      Formerly, we just didn't connect the core power line, which was
    a mistake potentially leaving power rails unconnected (it it did
    occur on both sides).
      Also checks if the conflict really arise, that is, the power lines
    are both on top or bottom.

* Change: In cumulus/chip.pads.Side._placePad(), manage I/O pads with
    a bottom left corner of abutment box *not* at (0,0). Argh!

* Bug: In cumulus/chip.pads, create the filler pad instances in the
    chip, not in the corona.
2023-01-14 12:39:22 +01:00
Jean-Paul Chaput 0e17b91692 Add at least one pitch to each cell in BloatChannel profile.
* Change: In Etesian::BloatChannel, when two DFFs are side by side, if
    they are not separated by at least one pitch, the track avoid
    mechanism will not be able to work. Hence the minimal one pitch.
2023-01-14 12:09:43 +01:00
Jean-Paul Chaput 83ff59817a Export CellViewer::setPixelThreshold() to the Python interface. 2023-01-14 12:06:15 +01:00
Jean-Paul Chaput c86d074f06 Export Contact::setLayer() to the Python interface. 2023-01-14 12:05:51 +01:00
Jean-Paul Chaput 3e921ff07a More debug information in chip pad & corona generation.
* Change: In cumulus/plugins.chip.configuration, do not add an extra
    slice height to the minHCorona & minVCorona. Now seems a bit overkill
    on small chips.
2023-01-09 09:26:44 +01:00
Jean-Paul Chaput bdb0091043 Just a little indentation for my autistic self. 2023-01-09 09:21:56 +01:00
Jean-Paul Chaput e38e3f46f2 Route ring pad wires, even if there is no pad on that side. 2023-01-07 13:08:10 +01:00
Jean-Paul Chaput 0bc7b3203a Add DesignFlow to the doc generation. New snapshot of the doc. 2023-01-07 13:01:23 +01:00
Jean-Paul Chaput 30afe6036b Add management of unused layers in cumulus/plugins.block.configuration. 2023-01-07 12:57:23 +01:00
Jean-Paul Chaput d9ebeb4b96 Search path reordering in crlenv.py so the debug version can be found. 2023-01-07 12:53:11 +01:00
Jean-Paul Chaput d2b40d568b Extend routing gauge to support non-routing layers at the bottom.
* New: In CRL::RoutingLayerGauge, two new types of gauge are supported:
    - Unusable : just do nothing with it, but the layer is stacked.
    - BottomPowersupply : can be used for supply routing only, and
      is *below* the normal routing layers (instead of on top as
      usual).
    Both new types must be *below* the real routing layers.
* New: In CRL::RoutingGauge, add a new attribute "firstRoutingLayer"
    to give the index (depth) of the first layer usable for routing.
    (not Unusable and not BottomPowerSupply)
* New: In Anabatic::Session & Anabatic::NetBuilder, in order to build
    the initial wiring, provides (Session) and use (NetBuilder) the
    new functions:
      - getBuildRoutingLayer(depth)
      - getBuildContactLayer(depth)
      Thoses functions takes into account (offset) the unusable layers
    so depth 0 is the first usable routing layer, and so on.
2023-01-07 12:51:38 +01:00
Jean-Paul Chaput 2501688dd1 Add support for layers alias names. Bug in _addPhysicalrule().
* New: In Technology, in order to support symbolic technology on top
    of a real technology using non-generic layer names, it comes in
    handy to be able to define layer alias names. Generic *real*
    layer names could be defined as alias over the technology
    specific ones. Then, we can build the symbolic layers upon
    the generic names (so *that* part of the init code can be
    shared between techs).
       Adds Technology::addLayerAlias()
       The semantic of Technology::getLayer() changes a little, it
     return the techno layer associtated to the name *or* the
     aliased name.
* Bug: In Technology::_addPhysicalRule(), in case of a rule redefinition,
    we were using it's name *after* the deletion of the rule object.
    Nasty crash.
      Improve the error message by giving the name of the conflicting
    rule.
* In CRL/helpers.analogtechno, add an addDevice() function to load
    analogic devices descriptors (copied from the old init system).
* In CRL/ApParser, if an exception is catched, tells in which file and
    line it did occur.
* In Oroshi/dtr.Rules, add a translation step to get the rule names
    from the technology. From generic names to actual technology
    layer names.
       Add some documentation.
* In Oroshi/stack.Stack, get the layers names through dtr.Rules to get
    the layers names translated.
2023-01-05 16:58:49 +01:00
Jean-Paul Chaput da56189d2e allianceInstaller.sh also must support nightly builds. 2023-01-02 12:24:19 +01:00
Jean-Paul Chaput db54e685f7 Correct again for nightly build. 2023-01-02 12:06:03 +01:00
Jean-Paul Chaput 100342e640 Support for nightly build in booststrap/crlenv.py. 2023-01-02 11:47:45 +01:00
Jean-Paul Chaput e590400ebb Add DoIt base design flow support. In full replacement of Makefiles. 2022-12-31 15:01:37 +01:00
Jean-Paul Chaput ae01be3c53 Set the initial verbose levels to off. Smarter loadUserSettings(). 2022-12-31 14:50:46 +01:00
Jean-Paul Chaput 36eb9f9121 Export the Alliance library list in AllianceFramework (as a list). 2022-12-31 14:48:25 +01:00
Jean-Paul Chaput b8cd4264bd Bug in topology management switch in NetBuilder::construct().
* Bug: In NetBuilder::construct(), the xG_xM1 topologies where wrongly
    redirected towards xG_1M1, so only one M1 was connected, all others
    left floating.
      Now direct them towards xG_xM1_xM3.
* Bug: In NetBuilderHybridVH, activate topology management for 2G_1M1.
2022-12-16 20:02:11 +01:00
Jean-Paul Chaput b65e6f83ff More clean approach to the verbosity levels in overlay and io. 2022-12-16 17:17:30 +01:00
Jean-Paul Chaput c85ad530c4 Take into account blockages and right shift bug in track avoidance.
* Change: In Etesian::SubSlice::getUsedVTracks(), now take blockages
    into account for used vertical tracks.
* Bug: In Etesian::SubSlice::avoidTrack(), right free interval for
    shifting was wrongly computed, effectively allowing *any* shift.
    This was creating cells overlap!
* New: In Hurricane::BasicLayer & Layer, establish a two way link
    between the blockage layer and routing layer. Now we can access
    the routing layer from the blockage.
2022-12-16 17:17:05 +01:00
Jean-Paul Chaput ca41dbd5ef Support for avoidance of vertical tracks in low metal techs.
* New: In NetBuilderHybridVH::_do_1G_xM1_1PinM1(), added configuration
    to manage pins on the north/south sides for VH,2RL.
* Bug: In NetBuilderHybridVH::doRp_xG_xM1_xM3(), correct misplaced
    vertical creation (buildind invalid topologies).
* New: EtesianEngine::toColoquinte(), display histograms of the cells
    widths (in pitch) before and after bloating to get a better feeling
    of the behavior.
* New: In EtesianEngine, add support for track avoidance. Portions of
    tracks to avoid are specified by a Box, which should flat and on
    the axis of the request track. This feature is used by the H-Tree
    to clear the vertical tracks under the tree from any terminal.
* New: In Etesian::Area, Slice and SubSlice, add support for track
    avoidance. Exported to the Python wrapper.
* New: SubSlice::getUsedVTracks() to get a set of tracks blocked by
    the cell.
* New: SubSlice::trackAvoid(), shift left/rigth the cell under the
    requested vertical track. Try only to move the cell under the
    track and not it's neighbor, so it assume that there is sufficient
    space left or right of the cell.
* Bug: In cumulus/plugins.block.configuration.BlockConf, the Cfg
    parameters may be read too early from the Cfg space into the
    various sub-conf objects (like FeedsConf). Delay the reading
    of the parameters in a _postInit() functions.
      Modify Block and CoreToChip to call _postInit().
* New: In cumulus/plugins.block.configuration.BlockConf._loadRoutingGauge,
    allow the cell gauge name to differ from the routing gauge name.
* New: In cumulus/plugins.block.configuration.FeedsConf, allow to
    select the default feed to be used with 'etesian.defaultFeed'
    parameter.
* New: In cumulus/plugins.block.spares.BufferPool, allow to control
    whether or not we want tie to either side of the pool.
    (for latch up).
* New: In cumulus/plugins.block.HTree._connectLeaf(), add support
    for track avoidance.
* Bug: In cumulus/plugins.block.HTree._connectLeaf(), the TL2 contact,
   the one on the *top* auxiliary buffer seemed to have been badly
   positioned until now (too low, not using tl2Y).
     This is strange because it should have caused disconnections,
   but I didn't see it in the wiring and the regressions tests didn't
   flag anything wrong. Still a bit weird and worrying.
2022-12-13 16:02:23 +01:00
Jean-Paul Chaput 49bcdb3195 One more remains of the previous routing configuration. 2022-11-26 15:05:56 +01:00
Jean-Paul Chaput c131e7a948 Clean parameters for routing topologies. Improved 2RL- support.
Previously, the relevant NetBuilder and routing strategies where
directly guessed from the RoutingGauge traits. This is no longer
doable as the combinations increases. Now to configure both the
global and detailed router we need three "parameters" :

1. The routing gauge itself (tells which layers are in which
   directions) and how to make the VIAs.
2. The NetBuilder to use, they are identified by strings.
   Currently we support:
   * "HV,3RL+", for all SxLib derived standard cells.
   * "VH,2RL", for hybrid routing (over the cell, but terminals
     are also in the first RL).
   * "2RL-", for strict channel routing.
   * "VH,3RL+", an attempt for FreePDK 45, not optimized enough
     to be considered as usable.
3. The routing style, mostly affect the way the GCell grid will be
   built.
   * VH      : first RL is V.
   * HV      : first RL is H.
   * OTH     : Run in full over-the-cell mode (needs at least 3RL).
   * Channel : Run in *strict* channel routing mode (no routing over
               the standard cells).
   * Hybrid  : Create channels, but can use H tracks over the
               standard cells.

Thoses three parameters are partly overlapping and must be sets in
a consistent manner, otherwise strange results may occurs.

* New: CRL::RoutingGauge::getFirstRoutingGauge(), to get the lowest
    layer available for routing (not a PinOnly, not a PowerSupply).
* Change: In CRL::RoutingGauge::isHV() and isVH(), were previously
    always returning false when the gauge was 2RL only. Now, check
    on the first usable RL.
* Bug: In cumulus/plugins.block.configuration._loadRoutingGauge(),
    there was a bad computation of the deep RLs when the top layer
    was not defined. Occured for 2RL gauges only.
* Bug: In Anabatic::RpsInRow::slacken() (LayerAssign), forgotten curly braces
    in the test to skip METAL2 terminals.
* Change: In Etestian::BloatChannel::getDx(), adjust the bloating
    policy to converge on Arlet6502. Always ensure that there is
    a 50% ratio between terminal used V-tracks and free ones.
      If there is more than 80% of terminals, add one more track.
* Bug: In AnabaticEngine & KatanaEngine, KatanaEngine is a derived
    class of AnabaticEngine.  They uses Anabatic::Configuration
    and Katana::Configuration that also derives from each other.
    I though I had made one configuration attribute in the base
    class that was using the right Configuration. But no. I did
    have two configurations attributes, one in AnabaticEngine and
    one in KatanaEngine, the later "shadowing" the former. As a
    results, parameters modified in AnabaticEngine, *after* the
    initial creation of the tool *where never seen* at Katana
    level (due to it's own duplicate). What a mess.
      Now there is only one attribute in the *base* class Anabatic,
    which is created through a new virtual function _createConfiguration()
    called in _postCreate() which allocate the right Configuration
    according to the dynamic type of the tool (KatanaEngine).
      In KatanaEngine, access the configuration through the
    attribute (_configuration) and not the accessor (getConfiguration()).
* Bug: In KatanaEngine, no longer directly use the _configuration attribute
    (which is not accessible anyway) but the getConfiguration() accessor.
    The accessor perform a static_cast from the Super::getConfiguration()
    into Katana::Configuration.
      Complete cleanup of the various configuration accessors.
* New: AnabaticEngine::setupNetBuilder(), perform an early check
    of the requested NetBuilderStyle. The NetBuilderStyle is just a
    string that will be matched against the (hard-coded) supported
    NetBuilders. Then check the topological characteristics against
    the capabilities of the gauge (HV, VH and so on).
      Still a bit too hard-coded for now.
      This function has been split from AnabaticEngine::_loadGrByNet().
* Change: AnabaticEngine::isChannelStyle() renamed from isChannelMode().
* New: In Anabatic::Configuration, two new attributes to select the
    topology and routing style:
      - _netBuilderStyle to explicitely select the NetBuilder to use.
        It's a string, which is provided by each NetBuilder.
      - _routingStyle to define how the overall routing will work.
        It's a set of flags (StyleFlags):
	* VH      : first RL is V.
	* HV      : first RL is H.
	* OTH     : Run in full over-the-cell mode (needs at least 3RL).
	* Channel : Run in *strict* channel routing mode (no routing over
	            the standard cells).
	* Hybrid  : Create channels, but can use H tracks over the
	            standard cells.
* New: In anabatic/Constants, add StyleFlags to define how the router
    should operate (see above).
* Bug: In Anabatic::GCell, in CTOR, no reason to set up the HChannelGCell flag.
* Bug: In Anabatic::GCell::updateDensity(), when computing layers non contiguous
    saturation, do not systematically skip RL 0, but only if it's PinOnly.
* Change: In Anabatic::NetBuilder, rename isTwoMetal by isStrictChannel.
* Change: In Anabatic::NetBuilderHV, rename doRp_AccessNorthPin() in
    doRp_AccessNorthSouthPin(). More accurate.
* Bug: In NetBuilderHV::_do_1G_xM1_1PinM2(), the wires to connect the M1
    terminals where created *twice*. Uterly stupid, there where placed in
    overlap by the router!
* New: In AnabaticEngine, new accessors to the NetBuilderStyle and
    RoutingStyle, proxies towards Configuration.
* Bug: In Manipulator::relax(), if there are two doglegs to be done, but
    they are in the same GCell, only do one (the conflicting interval)
    is short.
* Change: In Katana::Session, rename isChannelMode() into isChannelStyle().
* Change: In TrackSegment::isUnbreakable() and isStrap(), return false
    when the base segment is a *weak global* (aligned with a global one).
* Change: In Katana::Row::createChannel(), correctly distinguish between
    *strict channel* style and *hybrid* style. Tag the GCells as std cells
    row or channels only in the former case.
2022-11-26 13:07:12 +01:00
Jean-Paul Chaput e262c7bd1a Merge branch 'fix-duplicate-case-filenames' into 'devel'
Remove old generated files that clash on case-insensitive file systems

See merge request vlsi-eda/coriolis!15
2022-11-15 23:06:13 +00:00
Robert Taylor 68a3695780 Remove old generated files that clash on case-insensitive file systems 2022-11-15 11:51:43 +00:00
Jean-Paul Chaput 2b870fc609 Remove obsolete dependency towards LibXml2 in CMakeLists.txt. 2022-11-07 17:36:49 +01:00
Jean-Paul Chaput ecda00e154 Adjustments in AutoSegment::canReduce() and TrackSegment::canRealign().
* Change: In AutoSegment::canReduce(), allow reduction, when in channel
    mode, for bottom connected jumpers at depth 1. Forbidden otherwise
    as it may cause problems with the terminals (in OTC).
* Change: In TrackSegment::canRealign(), allow realignement of reduced
    segments. What really needs to be checked is that it do not have
    perpandiculars in reduced state.
2022-11-03 10:36:44 +01:00
Jean-Paul Chaput 15412317ec Add a second repair stage after the realing stage of the router.
* New: In Katana::NegotiateWindow::_negociate(), if the realign stage is
    enabled, perform a second stage of repair after it. To do this we
    need to reverse the state of events marked as FailedRepair to Repair.
      We isolate the repair stage in a new dedicated function,
    NegociateWindow::_negociateRepair(). Maybe should do the same for
    each other negociate stage.
2022-11-03 00:21:51 +01:00
Jean-Paul Chaput 8c182672dd Cleanly get rid of PyQt dependency.
* New: Hurricane::ErrorWidget, new widget exported to Python to replace
    helpers.io.ErrorWidget.
* New: Hurricane::AboutWindow, new window exported to Python to replace
    cumulus/plugins.aboutwindow.AboutWidget.
2022-11-02 00:21:00 +01:00
Jean-Paul Chaput 13795bec48 Add Environement attribute (pattern) to match the FF names. 2022-10-31 16:31:30 +01:00
Jean-Paul Chaput a0880da706 Issue a warning when the blockage net (for OBS) do not exists. 2022-10-31 16:29:07 +01:00
Jean-Paul Chaput 1253eeeef4 Allow the user to choose the name of the SRAM. Placement fix.
* Change: In cumulus/plugins.sram.sram_256x32, add a new parameter to
    __init__() so the user can choose the model name of the generated
    SRAM.
* Change: In cumulus/plugins.sram.sram.BaseSRAM.placeInstance(),
    placement status must be FIXED instead of PLACED so the placer do
    not "unplace" them.
      The Cell.updatePlacedFlag() method must also be called once
    the model if fully built.
2022-10-30 10:36:52 +01:00
Jean-Paul Chaput 11bae679f1 Export the Cell::updatePlacedFlag() to the Python interface. 2022-10-30 10:10:23 +01:00
Jean-Paul Chaput 3613ce0b5d Typo in LefImport, the conf variable name is "lefImport.unmatchedlayers". 2022-10-30 10:08:43 +01:00
Jean-Paul Chaput 47b26476b7 Fixed bad perpand interval computation in AutoSegment::getTopologicalinfos(). 2022-10-27 19:47:44 +02:00
Jean-Paul Chaput dbfcfae1e8 Update of the DefExport (work in progress).
* New: In CRL::DefExport, checkStatus() has a second argument to display
    a more comprehensive error message.
      Applied throughout all the DEF callbacks.
* Bug: In CRL::DefExport, the UNIT statement and associated toDefUnits()
    functions where wrong. Now always use a UNITS of 1000 in microns.
    Then toDefUnits() converts DbU into microns and multiply by 1000.
* Change: In CRL::defExport::_netCbk(), enable the net name renaming
    only when the ProtectNetNames flag is set.
* New: In CRL::PyDefExport, also export the flag values to Python.
2022-10-27 19:47:17 +02:00
Jean-Paul Chaput 775b6bf1fc Better management of discrepencies bewteen LEF & techno layers.
* Change: In CRL::LefImport::LefParser, layers defined in the LEF file
    are matched *in order* to the ones from the technology *in order*
    (not by name matching). But if there is a mismatch, that is more
    layers in the techno than in LEF, we got a shift. Now we can tell
    the parser to ignore a set of layers by setting up the configuration
    variable:
       LefImport.unmatchedLayers = 'DIFFP,POLY2,SMURF'
2022-10-27 19:46:29 +02:00
Jean-Paul Chaput 81920c622e Stricter layer management in the GDS parser.
* In CRL::GdsStream::_staticInit(), all the layers where added to the
    translation table, whether or not they where configured for the
    GDS stream. So the non GDS configured layers got a GDS layer
    id of 0 and were using this case. Either overwriting the legit
    layer or creating a new one while it should have been invalid.
      Now we check for the hasGds() predicate of the layers.
* In CRL::GdsStream, add a new option to tell that, layer id 0,
    if undefined, may be used as the definition of the boudary of
    the cell (abutment box).
* In CRL::PyGds, now also export the flags to the Python interface.
2022-10-27 19:45:20 +02:00
Jean-Paul Chaput 5a07033172 In BasicLayer, change GDS number types from "unsigned int" to "uint32_t". 2022-10-27 19:43:19 +02:00
Jean-Paul Chaput 7c85835c8f Added partial support for Pad (component) in RoutinPad.
* New: In Hurricane::RoutingPad, added support if the supporting component
    is a Pad. The source/target positions are computed according to the
    most likely direction.
      Change the _getEntityAsComponent() function into an inline template
    _getEntityAs<T>().
      Change the flags from an enum to static const uint32_t.
* Change: In Anabatic::Configuration, use _getEntityAs<T>.
* Change: In Anabatic::Dijkstra, use _getEntityAs<T>.
* Change: In Anabatic::NetBuilder, use _getEntityAs<T>.
* Change: In Katabatic::LoadGrByNet, use _getEntityAs<T>.
* Change: In Katana::ProtectRoutingPads, use _getEntityAs<T>.
* Change: In Bora::AnalogDistance, use _getEntityAs<T>.
* Change: In Etesian::EtesianEngine, use _getEntityAs<T>.
2022-10-27 19:42:13 +02:00
Jean-Paul Chaput 118b28b5a7 Prevent the absence of PyQt5 to stop lauching cgt.
* Change: In CRL/helpers.io, the ErrorWidget requires PyQt5 to execute but
    is not mandatory to run Coriolis/cgt. In order to be more portable,
    if it is not availble just evert to text display on the console.
      This widget will be directly supplied by Coriolis in the future
    completely removing the need for PyQt.
*Change: In cumulus/plugins/aboutwindow, same as above.
2022-10-26 16:37:16 +02:00
Jean-Paul Chaput 60c8bfe75e Remove reference to Foehn in SRAM generator (unpublished tool yet). 2022-10-26 16:32:00 +02:00
Jean-Paul Chaput 288d1c70b9 New bloat profile for channel routing (named "channel"). 2022-10-23 17:44:45 +02:00
Jean-Paul Chaput bba364eecc Fix: some AutoSegments where wrongly flagged as reduced.
* Bug: In Anabatic::AutoSegment::canReduce(), when looking at a fixed
    segment we were unconditionally flagging it as reduced if it was
    a "jumper", regardless of it's length.
      It was wrong, now also check for a length below the P-Pitch.
      This was introduced when implementing the channel routing.
2022-10-23 15:23:22 +02:00
Jean-Paul Chaput a6f61c1044 Update the channel routing feature to integrate with the OTC P&R.
* Update: In CRL/node600/phenitec/kite.py, update the routing gauge to
    the new format. So now we can use again SxLib-2M (channel routing
    SxLib for two metal technologies).
* Change: In CRL::BlifParser, if a master cell is not found in the
    AllianceFramework, then try in the Blif supplied libraries.
    This is used to load the zero, one and tie cells.
      Add a Blif::getCell() static function to look into the Blif
    supplied libraries.
* Change: In CRL::LefImport, sometimes there can be discrepencies between
    the LEF ROUTING layers and the Coriolis routing gauge. Now ignore
    routing layers that are *not* presents in the Coriolis gauge.

* Change: In AnabaticEngine, moved routingMode attribute from KatanaEngine,
    as some setup operations needs it.
* Change: In AutoSegment::canReduce(), allow fixed segments to be reduced
    if they are "jumpers" (turn+turn and top+top or bot+bot).
      This case arise on the edge of routing channels for fixed wires
    to connect terminals.
* Change: In AutoSegment::getTopologicalinfos(), compute differently the
    (leftBound,rightBound) interval when in channel mode.
       In over-the-cell mode, this interval is the one of the whole
    GCells under the wire. In channel mode, for fixed wires (that is,
    verticals connecteds to cells) this interval is reduced to half
    the GCell height, on the connected side of said channel.
      This allows Manipulator::_insertToTrack() to issue disantangling
    requests (push left/push right) for fixed segments that are face
    to face in the channel.
* Change: In Anabatic::Configuration CTOR, allow the cellGauge to have a
    different name from the routingGauge. Now if the cell gauge that
    should match the routing gauge is not found, fallback to the
    name set in "anabatic.cellGauge" parameter.
      Case occur when we try to match with CORE sites from LEF files.
* Change: In Etesian::Configuration CTOR, same change as in the
    Anabatic configuration.
* Change: In Anabatic::GCell::updateDensity(), never set the GoStraight
    flag in channel mode. This flag makes sense when there is at least
    4 routing layers (so we have 2 contiguous free of blockages).
* Bug: In Anabatic::Session::_getNearestGridpoint(), sometimes the nearest on
    grid point is outside the constraint box. Now force the point
    to remains inside constraints even if offgrid.

* Change: In Katana::DataNegociate::update(), perpandiculars that are
    either reduced or in non-preferred routing direction should not
    trigger a bug message.
* Change: In KatanaEngine::_check(), do not check for fixed, horizontal
    non-prefs AutoSegments in channel mode (avoid false bug display).
* Bug: In Manipulator::_forceToTrack(), slighty shrink (-1) the interval
    to free. The intersection function of intervals returns true when
    the two intervals *exactly* touches (1.vMax == 2.vMin). But in
    this specific case, they are not *overlapping* and no action
    should be taken...
* Bug: In Manipulator::_insertInTrack(), do not reject the track when
    we are overlapping a fixed vertical segment in channel mode.
    (Hmm, maybe already corrected by the previous one).
* Change: In Katana::NegociateOverlapCost(), in channel mode, do
    not put two overlaping vertical fixed segments into infinite cost.
    This happens when two cell connected verticals are face to face in
    a channel. We want them negociated the track (by shrinking their
    length) instead of excluding it right away.
* Change: In NegociateWindow::createTrackSegment(), in channel mode,
    do not attempt to create a track segment over a fixed and reduced
    AutoSegment.
      Do not attempt to put a non-preferred AutoSegment on a Track
    either.
* Bug: In RoutingEvent::revalidate(), the number of availables tracks
    was badly computed when in the pure constraint case, when there
    was only one it was reporting zero.
* Change: In TrackElements::TrackElements_Perpandicular::Locator,
    do not issue a bug when an non-pref or reduced AutoSegment do not
    have an associated TrackElement.
* Change: In TrackSegmentCost::update(), do not issue a bug when a
    perpandicular is reduded or non-pref and do not have a TrackElement.
2022-10-22 16:39:22 +02:00
Jean-Paul Chaput 9594476ab6 Improved SRAM output multiplexer, using NAND/NOR.
* New: In cumulus/plugins/sram_256x32.py, build the output mux using a
    NAND2/NOR2 binary tree instead of mux2/mux3. Use more, but much
    smaller cells. The reduction of wirelength (from Yosys) goes
    from 4% to 15% for the non-folded variant.
      Uses a specially placed tree to minimize wire length.
* New: In cumulus/plugins/sram.py, extend StdCellConf to convert names
    accross library flavors (FlexLib_TSMC_C180, FlexLib_Sky130 and
    generic SxLib).
2022-10-17 17:18:49 +02:00
Jean-Paul Chaput d294a770c4 Added Standard Cells based SRAM generator (Python).
The generator as been build in two parts:
1. A genereric sram.BaseSRAM class to provides support for all kind of
   SRAM (grouping column tree, headers, folding).
2. The specific SRAM_256x32 (256 words of 32 bits) suited for the
   ethmac.
The sram has been simulated with genpat+asimut and gives identical
results to the Yosys one (at gate level). No timing though.
2022-10-14 10:12:03 +02:00
Jean-Paul Chaput df1ba66c09 Fix a crash in PowerRails when a terminal is not connected.
* Bug: In Katana::GlobalNetTable::getRootNet(), when tracking up the
    net through the plug (to look if it's connected to a top level
    clock), we may encounter an *unconnected* plug.
      We where not checking that case, and went crashing. Now issue
    a warning and return NULL.
      This indicates that, up until now, we didn't encounter any
    unconnected Plug in our netlists. This did show up due to a
    building error in the SRAM Standard Cell generator.
2022-10-14 10:10:43 +02:00
Jean-Paul Chaput 82cd53b107 Display the length units in KatanaEngine::printCompletion() (unambiguous). 2022-10-13 10:54:50 +02:00
Jean-Paul Chaput 757284896c Remove extra debug messages in PythonAttributes. 2022-10-13 10:54:11 +02:00
Jean-Paul Chaput 7d31d6c457 Merge branch 'devel' of gitlab.lip6.fr:vlsi-eda/coriolis into devel 2022-09-22 10:35:21 +02:00
Jean-Paul Chaput 35f73ecec3 Added plugin for placing Yosys generated SRAM (failed experiment). 2022-09-21 17:48:26 +02:00
Jean-Paul Chaput 8980a01dae Added new tool "foehn" to create/manipulate DAG.
Build DAG then create an ordered list of gates from it. DAG starting
points could be Net or Instances (we take the output of the Instance).
Multiple DAG can be created, but once an Instance is part of a DAG,
it connot be part of another and is conidered as "reached" by all
subsequent DAG run. The ordered list build from a DAG contains both
Net and Instances.
   A new property has DagProperty, accessible through DagExtension
has been created to store relevant information of the DAG on each
Instance or Net (work in progress).
2022-09-21 17:46:48 +02:00
Jean-Paul Chaput 3f1148b105 Added support to map vectors of Entity into Python lists of PyEntity. 2022-09-21 17:30:30 +02:00
HoangAnhP 5b88929d23 Merge branch 'devel' of gitlab.lip6.fr:vlsi-eda/coriolis into devel 2022-08-23 14:36:25 +02:00
HoangAnhP 93fbc74f8d Seabreeze : nothing new, just some typos fixed 2022-08-23 14:35:55 +02:00
Jean-Paul Chaput 16428ffaa9 Updated documentation Python/Tutorial to catch up with API improvements. 2022-08-15 13:49:35 +02:00
Jean-Paul Chaput 440547a1c5 PyAttributesHolder, again (2). 2022-08-14 18:35:21 +02:00
Jean-Paul Chaput d0d0e3aa3d Fixing the PyAttributesHolder type definition, again. 2022-08-14 18:28:34 +02:00
Jean-Paul Chaput bdd78ce44a Right preprocess condition in PythonAttribues for old GCC 2022-08-14 18:14:35 +02:00
Jean-Paul Chaput c0b4a73f9e Alternate PyTypeObject inititalization in PythonAttributes for old GCC. 2022-08-14 13:05:35 +02:00
Jean-Paul Chaput 56aa978a9b Added management of Python attributes on DBo.
* New: Isobar::PyAttributesHolder, a PyObject with only a dictionary
    to hold the attributes associated to a DBo.
* New: Isobar::PyHolderProperty, the Property that encapsulate
    PyAttributesholder.
* New: Isobar::PythonAttributes, the extension to simplify the
    management of the PyAttributesholder.
* Change: In PyEntity, now use a dedicated tp_getattro and tp_setattro
    to delegate the Python attribute access towars the PyAttributesholder.
* New: In hurricane/doc & documentation, update docs regarding Python
    attributes managment.
2022-08-13 17:46:47 +02:00
Jean-Paul Chaput fefa47b2dc Remove submodule error that was painful under emacs. 2022-08-05 15:36:10 +02:00
HoangAnhP 5667797ae6 Seabreeze : More than 1 Contact in 1 RoutingPad 2022-08-01 10:58:59 +02:00
HoangAnhP af20ef092c Seabreeze : new case to be considered 2022-07-22 19:13:14 +02:00
HoangAnhP 2d181a592f Seabreeze : Finally fixed conflict 2022-07-22 13:25:17 +02:00
HoangAnhP 1e978d5149 Revert "Seabreeze : fixing conflict"
This reverts commit 0e9556676a.
2022-07-22 13:12:57 +02:00
HoangAnhP c8a15a3129 Revert "Revert "Seabreeze : fixing conflict""
This reverts commit 1016ae54a6.
2022-07-22 13:12:55 +02:00
HoangAnhP 1016ae54a6 Revert "Seabreeze : fixing conflict"
This reverts commit 0e9556676a.
2022-07-22 13:11:04 +02:00
HoangAnhP 0e9556676a Seabreeze : fixing conflict 2022-07-22 13:04:14 +02:00
HoangAnhP d16ec20966 Merge branch 'devel' of gitlab.lip6.fr:vlsi-eda/coriolis into devel
Conflicts:
	Seabreeze/src/Delay.cpp
2022-07-22 12:50:41 +02:00
HoangAnhP dedad34585 Complete fonctions of class Delay 2022-07-22 12:39:08 +02:00
Jean-Paul Chaput 149b4997fd Code reorganisation of Seabreeze consolidating objects. 2022-07-22 01:01:21 +02:00
Jean-Paul Chaput c647a670b1 Add full inspector support (getString/getRecord) to Seabreeze. 2022-07-21 19:24:42 +02:00
HoangAnhP bf181787cb Seabreeze : new class Delay for the result 2022-07-21 12:03:52 +02:00
HoangAnhP 555f6ea6a4 Seabreeze : new class for results 2022-07-21 11:45:18 +02:00
HoangAnhP b65821282c Seabreeze : optimise with new attribute of Node + fix wrong formula of Elmore's delay 2022-07-21 11:44:44 +02:00
HoangAnhP a6bfbdf825 Seabreeze : some changes 2022-07-20 17:49:43 +02:00
Jean-Paul Chaput 336b0ad015 First step in normalizing/rewriting Seabreeze. 2022-07-20 15:14:38 +02:00
Jean-Paul Chaput be1dd12c1a Merge branch 'devel' of gitlab.lip6.fr:vlsi-eda/coriolis into devel 2022-07-14 15:20:40 +02:00
Jean-Paul Chaput 34a3ae327c Revert horizontalAdvance() to width() so it build on old Qt5 versions. 2022-07-14 15:19:24 +02:00
HoangAnhP 78401f5129 Merge branch 'devel' of gitlab.lip6.fr:vlsi-eda/coriolis into devel 2022-07-13 12:30:33 +02:00
HoangAnhP 0cd9cd7ddb Seabreeze : Elmore's delay calculation checked, it should be good (?) 2022-07-13 12:30:10 +02:00
Jean-Paul Chaput db0ecb878d Merge branch 'devel' of gitlab.lip6.fr:vlsi-eda/coriolis into devel 2022-07-13 11:48:48 +02:00
Jean-Paul Chaput c737d5bd0c Port to Python3 capacitors & resistors generators.
Main list of ports:

* Replace deprecated operator '<>' by '!='.
* To check if a list is empty, do not compare to [], but check it's
  length instead.
* Do not make a class inherit indirectly twice from the same base class.
* Hurricane physical object constructors uses DbU::Unit as arguments,
  seen as int in Python, so they will not match float. Unfortunately
  the calculation often gives float. So explicitely cast them into
  int. This is due to a change of behavior in Python. Now, 3/2
  gives 1.5 (float). To get the previous one use: 3/2 -> 1 (int).
* dict.keys()[0] no longer work, instead use list(dict.keys())[0].
2022-07-13 11:20:55 +02:00
Jean-Paul Chaput f453dbc6f9 Correct the selection bug in Net mode in CellWidget.
In SelectorCriterion & SelectorCriterions, when selecting a Net occurrence,
we where storing the Net only. This was fine if the Net was belonging to
the Cell's top level. But when it was an occurrence of a non-top level
net, this was creating the elusive incoherent Occurrence problem.
Now we truly store the occurrence of the Net, to be accurate, the root
of the HyperNet.

* Change: In SelectorCriterions::add(), the Net* argument is replaced
    by a Occurrence of Net. Must be an HyperNet root occurrence.
      Same goes for SelectorCriterions::remove().
* Change: In CellWidget::select(), when called with a Net occurrence,
    select the whole HyperNet components.
* Change: In NetSelectorCriterion, now use a Net occurrence instead
    of directly a Net. Must be an HyperNet root net occurrence.
2022-07-13 11:20:24 +02:00
HoangAnhP 7267951683 Seabreeze : debugged, RC calculated for each node. Testing delay_Elmore 2022-07-12 15:03:33 +02:00
HoangAnhP d1c0e4882a Seabreeze : update on calculating RC; adding explication (brief) of fonctions 2022-07-12 12:39:37 +02:00
HoangAnhP 157532af48 Seabreeze : fixed wrong formula of C. Still not using data, parameters are defined 2022-07-07 09:30:24 +02:00
HoangAnhP 871622f482 Seabreeze : phase 2, add Configuration 2022-07-06 18:20:35 +02:00
HoangAnhP d9db42447d Seabreeze : Step 1 - Building Tree is done. Going to step 2 - Compute RC 2022-06-17 12:05:57 +02:00
HoangAnhP 9b59c50efc Seabreeze : new version of function build_branch(). No more recursivity 2022-06-16 18:14:47 +02:00
HoangAnhP 2c89e5b41a Seabreeze : error while returning the contact from build_branch() 2022-06-15 12:01:32 +02:00
HoangAnhP e2c27cc039 Seabreeze : add fonction build_from_Node(Node*, Segment*) 2022-06-14 12:34:44 +02:00
HoangAnhP e9147299b0 Seabreeze : add fonction build_branch(Contact* ct) to help build a branch and pass all the 'unecessary' contacts 2022-06-13 17:14:58 +02:00
HoangAnhP d593683394 Seabreeze : problem solved, tree created with all the contacts. To improve to a better form of tree. 2022-06-13 14:53:36 +02:00
HoangAnhP 3bd38f4363 Work for Nets with 2 or less RoutingPads. Further analysis for bigger nets 2022-06-09 17:15:06 +02:00
HoangAnhP 0864db6c2f Merge branch 'devel' of gitlab.lip6.fr:vlsi-eda/coriolis into devel 2022-06-09 12:04:10 +02:00
HoangAnhP 801e31f716 Seabreeze : Segmentation fault when acceding vector nodes of tree 2022-06-09 09:54:42 +02:00
Jean-Paul Chaput 9d818df5b1 Computation of the relative area used by the registers in Etesian.
* Change: In EtesianEngine::toColoquinte(), not only compute the ratio
    of DFF versus the total number of gates, but also the ratio in
    term of area. As the DFF are usually very big cells compare to
    combinatorial one, the direct gate ratio could be misleading as
    to the "weight" of those cell in the design.
2022-06-05 20:36:41 +02:00
Jean-Paul Chaput 33a5cd3b0b Nicer looking of the dots in Bora::SlicingPlotWidget (IMHO). 2022-06-05 20:36:01 +02:00
Jean-Paul Chaput bbea20b4f6 Correct, again, the problem of PyLayoutGenerator in Python 3.
* Bug: In PyLayoutGenerator, in the method definition of setVerboselevel(),
    the error was not METH_STATIC but the lack of METH_VARARGS flag.
2022-06-05 20:35:39 +02:00
HoangAnhP 77ecf5523d Merge branch 'devel' of gitlab.lip6.fr:vlsi-eda/coriolis into devel 2022-06-03 17:03:24 +02:00
HoangAnhP aed63ccdf5 Seabreeze, first commit 2022-06-03 16:48:17 +02:00
Jean-Paul Chaput 33e148440c Correct a compliance problem with Python > 3.8 of METH_STATIC.
* Change: In PyLayoutGenerator, in the method definition of the class,
    replace the METH_STATIC flag by METH_CLASS for setVerboseLevel().
      There may be more of it elsewere, but as they didn't seem to
    have been triggered, we will see as it happens.
2022-05-27 18:09:12 +02:00
Jean-Paul Chaput 19504ad64f Correct misaligned contact in heavy load H-Tree.
* Bug: In cumulus/plugins.block.htree.HTree._connectLeaf(), the stacked
    contact to connect the top left buffer amplifier was not forcibly
    aligned on the vertical METAL5. In some configuaration it was
    leading to gaps at METAL5 level.
2022-05-26 23:40:30 +02:00
Jean-Paul Chaput 5b469e458f Bug in AutoSegment::getEndAxis() computation.
* Bug: In AutoSegment::getEndAxes(), as the NonAligned flag may be
    wrong, always loop over the aligneds (if any). Then, the
    target axis computation was wrong, using a min() instead of
    a max().
      This was, in turn, wrongly activating isNearMinArea() and
    causing non-minimal length segment to have their extremeties
    extented. And, in the end, Track overlap.
2022-05-26 17:51:25 +02:00
Jean-Paul Chaput 2efae3507e Remove unconnected part of the nets after HFNS.
This was the reason why we, sometimes got "UNCONNECTED" errors in the
VHDL PORT MAP statements. This was the remnants of the originally
connected driver.

* Bug: In Etesian::BufferTree, as the root driver is disconnected from
    all the sinks, but the top tree buffer, we may end up with
    unconnected signal on instances that were using it.
      So now, call BufferTree::rcleaupNet() to remove the Net in
    the Cell that where used to "transmit" the original driver.
* Bug: In Etesian::BufferTree, no longer use a _isDeepNet attribute
    guessed from the occurrences pathes of the RoutingPad, but
    trust the Net::isDeepNet() method.
2022-05-25 17:09:00 +02:00
Jean-Paul Chaput 86d539fe5d Add a breakoint after perfoming HFNS in cumulus.plugins.block. 2022-05-25 17:08:34 +02:00
Jean-Paul Chaput c17c4c3f6e Add management for very rare segment cross blocking (ripup loop).
* New: In Katana::DataNegociate, add a "sameRipup" counter to keep
    the *consecutive* number of time a segment is put in the same
    track.
* New: In TrackSegment::setAxis(), update/reset the "sameRipup"
    counter of the DataNegociate.
* New: In TrackCost, add new flag "Blacklisted" to mark Tracks that
    have been riped up too much in a consecutive row.
      TrackCost::Compare::operator() will then sort the blacklisted
    track after the non-blacklisted ones.
* New: In SegmentFsm CTOR, raise the Blacklist flag on the TrackCost
    if the "sameRipup" is above 10. This to get away from a state
    well in the ripup.
2022-05-23 17:58:17 +02:00
Jean-Paul Chaput c877d7e980 Forgot to merge the router failure status in chip.chip.doPnR(). 2022-05-21 18:49:55 +02:00
Jean-Paul Chaput a94a290c9b Be a bit more lax for out of bound requests in Track::getBeginIndex(). 2022-05-21 13:19:51 +02:00
Jean-Paul Chaput ba23a362fb Bad protection layer used in NetBuilderHV::doRp_AutoContact().
Bug: In NetBuilderHV::doRp_AutoContact(), when encountering a
  punctual RoutingPad in METAL1, create the protection in the
  METAL2 layer instead of METAL1 (current layer).
2022-05-21 13:19:28 +02:00
Jean-Paul Chaput 53db943d14 Discriminate between I/O pin and block pin in NetBuilder.
* Bug: In NetBuilder::setStartHook(), trigger the "move up" of
    global routing only when encountering RoutingPad of a macro
    block and *not* an I/O pin of the whole block (at the edge).
    Boils down to look if the RoutingPad is anchored on a Pin
    or a Segment (macro block).
2022-05-21 13:03:38 +02:00
Jean-Paul Chaput 1babec2e91 Save VHDL model only once in the rsave Cumulus plugin.
* Bug: In cumulus/plugins/rsave.py, the Cells where saveds each time
    one instance of was encountered. Resulting in multiple saves.
    It was, of course, ineficient, but it also triggers a bug
    that seems to happen after multiple save : the VHDL additional
    property was deleted *before* the full hierarchical dump was
    finished.
      Now, we save each Cell only once so it does not occur, but
    should make a deeper investigation later.
2022-05-21 13:02:58 +02:00
Jean-Paul Chaput 42bf5d29d4 General review & redesign of the "minimum area checking" for segments.
* Change: In AutoHorizontal::setDuSource() & ::setDuTarget() (& AutoVertical),
    check that the requested "du" is less than a pitch (this is not an
    upper bound). Issue a warning if not true.
* Change: In AutoSegment::revalidate(), when passing the previous span
    interval to expandToMinLength(), if we are in creation stage, make
    it empty because it has no sense yet and can lead to a lock in a
    too narrow span.
      Change the coupled behavior of expandToMinLength() vs.
    unexpandToMinLength(), the call to "unexpand" will be done on
    AutoSegments that are flagged with SegAtMinArea, instead of
    using the return value of "expand". This way we control across
    multiple revalidate() if a segment can be "unexpanded".
* Bug: In AutoSegment::expandToMinLength(), not only try to shift left
    if we are beyoond the max bound but also to the right if we are
    below the min bound.
      the span on the target and source were miscalculated, we must
    add the half-minimal distance to get the span inside the Track.
* Change: In AutoSegment::isMiddleStack(), rename into isNearMinArea()
    as we check for any *small length* set of AutoSegments and not
    only the one part of a middle stack. In some rare instances,
    two aligned segments can nevertheless be too short.
* Bug: In AutoSegment::reduceDoglegLayer(), when finding a reduced
    segment also reset it's duSource & duTarget because it will
    no longer be an isolated strip of metal.
* Change: In AutoHorizontal::updateOrient(), when there is a
    source/target swap, no need to exchange the dxSource and
    dxTarget extentions.
* Change: In AutoHorizontal::setDuSource() & ::setDuTarget(), check
    for du bigger than the pitch, which should never occur and
    display a warning.
      Same modification in AutoVertical.
* Change: In Track::repair(), now invalidate the shifted segments
    to ensure cache coherency with the TrackElement.
      Do not take AutoSegment in non-preferred direction into
    account, and especially do not try to resize them.
      Now, invalidate the corrected segments (see below).
* Change: In KatanaEngine::finalizeLayout(), move the track repair
    stage from here into NegociateWidow::run(). This way we avoid
    the false warning about segment overlap in the data-base final
    check. The false warning was because the AutoSegment where
    shifted but not invalidated/revalidated leading to a cache
    incoherency in the TrackElement. Now they *are* invalidated
    and updated.
* Bug: In Track::checkMinArea(), do not check for minimal area when
    a segment is overlapping a same net neighbor. To avoid false
    minimum area violation warnings.
2022-05-18 14:54:14 +02:00
Jean-Paul Chaput ab13a02eed Do not make dogleg on segments in non-preferred routing direction.
* Bug: In AutoContactTurn::updateTopology(), in some case we were making
    doglegs on segments in non-preferred routing direction (mostly M2).
    This must be never be done. As, by construction, at least one segment
    of the turn must be in the preferred routing direction, always use
    this one to make the dogleg.
      This bug is likely to explain the remaining "bad spin" in the
    final self-check of the routing data-structure.
2022-05-12 17:54:05 +02:00
Jean-Paul Chaput d3b7251eac NetRoutingExtension::get() failsafe when net is NULL. 2022-05-12 17:53:21 +02:00
Jean-Paul Chaput 5ff81b59ec Separate count from the list of indexes in configuration.IoPin. 2022-05-12 17:52:55 +02:00
Jean-Paul Chaput 59c0ab067b Mangle the "'" in Verilog to VHDL translator. 2022-05-12 17:52:22 +02:00
Jean-Paul Chaput 0a64f3b83d Create and connect dummy signals for unconnected *outputs* in BLIF parser. 2022-05-12 17:51:56 +02:00
Jean-Paul Chaput 921c519bd3 More detailed error message in case of VHDL PORT MAP discrepency. 2022-05-12 17:51:30 +02:00
Jean-Paul Chaput cd60032d9c Added direct management of macro blocks I/O pins in METAL2 & METAL3.
The decoupling of the cell gauge and the routing gauge implies that
the METAL2 & METAL3 terminals of macro blocks cannot be aligned on
the routing tracks anymore. That is, an horizontal METAL2 terminal
will not be on a track axis, but offgrid, so we no longer can use
a METAL2 horizontal segment to connect to it. Making an adjustement
between the offgrid terminal and the on-grid segment has proven
too complex and generating difficult configuration for the router.
Moreover, METLA2 terminal could be fully inside a METAL2 blockage.
So now, when the gauges are decoupled, we connect the METAL2 and
METAL3 the same way we do for METAL1: *from above* in the perpandicular
direction and using a *sliding* VIA. We assume that those kind of
terminals in upper metals are quite long.

* New: In Hurricane::Rectilinear, export the isNonRectangle() method
    to the Python interface.
* New: In CRL::RoutingGauge, add function isSuperPitched() with the
    associated boolean attribute. Set to true when each pitch of
    each layer is independant (not low fractional multiples).
* New: In AnabaticEngine, add the ability to temporarily disable the
    canonize() operation (mainly used in dogleg creation).
* New: In AutoSegment::canonize(), do nothing if the operation is
    disabled by AnabaticEngine.
* Bug: In Session::_revalidateTopology(), disable the canonization
    during the topology updating of a net. Too early canonization
    was occuring in makeDogleg() leading to incoherencies when
    performing the later canonization stage over the complete net.
    Mostly occured in the initial build stage of the net.
* New: In GCell, add function postGlobalAnnotate(), if a layer
    is fully blocked (above 0.9), typically, under a blockage,
    add a further capacity decrease of 2 on the edges. So we may
    handle a modicum of doglegs.
* Bug; In GCell::addBlockage(), removeContact(), removeHSegment()
    and removeVSegment(), forgot to set the Invalidated flag.
    This may have lead to innacurate densities.
* Change: In GCell::updateDensity(), more complex setting of the
    GoStraight flag. This flag is now set if we don't have two
    *contiguous* below 60% of density. We need free contiguous
    layers to make doglegs.
* New: In NetBuilder, now manage a current state flag along
    with the state flag of the *source* GCell. This flag is used
    to tell if the GCell needs it's *global* routing to be done
    using the upper layers (METAL4 & METAL5) instead of the
    lower ones.
* New: In NetBuilder::setStartHook(), set the state flag of the
    GCell to ToUpperRouting when processing a global routing
    articulation and one of the base layer is obstructed
    above 0.9.
      In GCell with terminals, also set ToUpperRouting when there
    are some in METAL2 / METAL3 and the gauge is not super-pitched.
* New: In NetBuilder, function isInsideBlockage(), to check if a
    terminal is completely or partially enclosed in a blockage.
* Change: In NetBuilderHV::doRp_AutoContact(), remove support for
    trying to put on grid misaligned METAL2/METAL3.
      Instead systematically access them from above.
      Do not cover with fixed protection terminals that are already
    enclosed in blockages.
* Bug: In NetBuilderHV::doRp_AutoContact(), always add the terminal
    contact in the requested GCell and not the target/source one,
    in case the terminal span several GCells.
* Change: In NetBuilderHV::doRp_Access(), create the local wiring
    according to the RoutingPad layer.
* Change: In NetBuilderHV::_do_xG(), _do_2G(),
    create the global wiring in upper layers, according to the
    ToUpperRouting flag.
* Change: In NetBuilderHV::_do_xG_xM3(), now delegate to
    _do_xG_xM3_baseRouting() and _do_xG_xM3_upperRouting() if the
    density at terminal level is above 0.5.
* New: NetBuilderHV::_do_xG_xM3_baseRouting() and
    _do_xG_xM3_upperRouting() separated function to manage the
    local routing.
* Change: In NetBuilder::_do_globalSegment(), if the currently
    processed GCell or it's source is in ToUpperRouting mode,
    move up the global segment. Do *not* use the moveUp() function
    which would create doglegs unwanted at this stage.
* New: In KatanaEngine::annotateGlobalGraph(), call postGlobalAnnotate()
    on the GCell after the blockages have been taken into accound to
    add the penalty.
* Bug: In Track::getPrevious(), correctly manage the 0 value for the
    index argument. Strange it didn't show earlier.
      Same goes for Track::expandFreeInterval().
2022-04-27 21:56:41 +02:00
Jean-Paul Chaput 908231c4c4 Missing BigVia import and some typos. 2022-04-03 13:19:49 +02:00
Jean-Paul Chaput 4ffd91822f Added support for SPICE terminal ordering from .spi files.
After a Cell has been created in memory (by parsers or Python scripts)
we can annotate it with the Spice parser so it will know the right
order with which to create the subcircuit call ('x').

* New: In CRL::Spice::load(), add support to read the ".subckt" card
    and guess the right ordering for generating the 'x' (subcircuit
    card call).
* Bug: In Spice::SpiceBit & Spice::BitExtension, when a Net bit property
    is removed, if it's the currently cached property in BitExtension
    it may lead to a crash. So when a property is destroyed, we must
    also clear the cache (see remove(), clearCache() & onReleasedby()).
      I'm wary that this could also happen on other kind of cached
    extensions...
* New: In CRL::NamingScheme, new method vhdlToVlog() to translate back
    VHDL net name into Verilog. Currently only changes "()" into "[]".
    Used to generate the commented SPICE interface for Alliance compliance.
* Change: In Spice::Entity, previously all the ordering where removed
    between each run of the SPICE parser, but the orders read from
    SPICE file (mostly standard cells) must be kept. So add a flag
    ReferenceCell to prevent the removal by ::destroyAll().
2022-04-03 13:18:42 +02:00
Jean-Paul Chaput fd624f03b6 Forgot emiting "layoutAbouttobechanged" in NetlistModel::setCell().
* Bug: In NetlistModel::setCell() template, forgot to send the
    "layoutAboutToBeChanged" signal before disconnecting the
    netlist datas. This seemed to go unnoticed until ported
    under Qt5. Was generating strange random core dump when
    running the engines with a net kept selected. Disgraceful
    crash during demos...
2022-01-26 19:41:39 +01:00
Jean-Paul Chaput 7f936367f8 Fix deletion bug in Selector::_preDestroy().
* Bug: In Selector::_preDestroy(), *do not* iterate over the _cellWidgets
    map as we destroy it's elements! We end up in destroyed ones...
    Instead destroy the first one until the map is empty.
2022-01-26 19:34:31 +01:00
Jean-Paul Chaput a5d92ecc29 Beautification, display "boundaries" below everything else.
* Change: In CellWidget::_redraw(), the boundaries, that is, instances
    abutment boxes where drawn *after* everything else, so they where
    hiding more interesting informations (especially at low zoom level)
    like routing wires.
      Now draw them *first* so they are *below*.
2022-01-26 19:31:01 +01:00
Jean-Paul Chaput 6210d312fe Correct the image snaphot generation (CellImage).
* Change: In CellImage::setScreenCellWidget, fully copy the display
    settings from the reference widget (not just part of them).
* Bug: In CellImage::toImage(), if the abutment box of the displayed
    cell is not *fully* includer in the viewer area, do *not* try to
    reframe it. The reframe() method seems to be buggy, works OK
    just without calling it.
2022-01-26 19:25:50 +01:00
Jean-Paul Chaput 08b951047c Update to support BFD 2.35.2 to generate file/line in stack traces. 2022-01-26 19:19:01 +01:00
Jean-Paul Chaput b54380e05d Merge branch 'devel' of gitlab.lip6.fr:vlsi-eda/coriolis into devel 2022-01-15 17:28:44 +01:00
Jean-Paul Chaput b6192e78c1 Minor documentation patchs to work with RHEL9. 2022-01-15 17:28:21 +01:00
Jean-Paul Chaput 1d839711ad Merge branch 'lefdef-out' into 'devel'
Bind DEF/LEF export to Python and make it useful for real processes

See merge request vlsi-eda/coriolis!14
2022-01-14 13:42:39 +00:00
Jean-Paul Chaput c805f4d6e4 Fix stupid mistake of "trace" import in core2chip.cmos.py. 2022-01-13 11:16:07 +01:00
Jean-Paul Chaput 22dd3ddc73 Remove bison generated yy.tab.h. Included by mistake. 2022-01-12 16:31:46 +01:00
Jean-Paul Chaput c41bd36279 Small code presentation improvements. 2022-01-12 16:27:47 +01:00
Jean-Paul Chaput 762e25adde More Python 3 corrections.
* Change: In unicorn/python/unicornInit.py, when iterating over all the
    loaded modules, now we have "namespace" that have a __file__
    attribute which is set to None. Skip them.
* Change: In stratus1/st_net.py, "is" must be replaced by "==" when
    doing string comparison.
* Change: In stratus1/st_parser.py, open file in "rb" mode instead
    of "r" (so we get a bytestream as now required by Python).
2022-01-12 16:25:01 +01:00
gatecat 6c66208e0c def: Write route segments
Signed-off-by: gatecat <gatecat@ds0.me>
2022-01-12 14:14:15 +00:00
gatecat 9635cc3311 lef: Fix MANUFACTURINGGRID order
Signed-off-by: gatecat <gatecat@ds0.me>
2022-01-12 13:42:03 +00:00
gatecat c4ef465c41 def: Fix order of instance transforms
Signed-off-by: gatecat <gatecat@ds0.me>
2022-01-10 19:45:24 +00:00
gatecat 4250c5bec7 def: Fix export of pins
Signed-off-by: gatecat <gatecat@ds0.me>
2022-01-10 18:47:13 +00:00
gatecat a8dd84838b def: Fix export units for non-lambda processes
Signed-off-by: gatecat <gatecat@ds0.me>
2022-01-10 16:54:04 +00:00
gatecat ddb684bfe1 defexport: Make it useful for real processes
Signed-off-by: gatecat <gatecat@ds0.me>
2022-01-10 16:54:04 +00:00
gatecat 4884a5d6dc crlcore: Add Python bindings for DEF export
Signed-off-by: gatecat <gatecat@ds0.me>
2022-01-10 16:54:04 +00:00
gatecat 2f1caca812 lefexport: Make it useful for real processes
Signed-off-by: gatecat <gatecat@ds0.me>
2022-01-10 16:54:04 +00:00
gatecat e1c5366fef crlcore: Add Python bindings for LEF export
Signed-off-by: gatecat <gatecat@ds0.me>
2022-01-10 16:54:04 +00:00
Jean-Paul Chaput 0d7deafe81 Remove mistakenly commited backup file. 2022-01-01 17:15:41 +01:00
Jean-Paul Chaput 581f557aef Fix: The SelectionPopup widget was deleted after first use.
* Bug: In Viewer::SelectionPopup(), the window attribute
   Qt::WA_DeleteOnClose was *not* cleared. So the window was deleted
   after first use while it was though staying allocated.
     Again, generating weird crashes.
     Took the occasion to slightly redesign the behavior to select
   and highlight individual components.
2022-01-01 16:47:09 +01:00
Jean-Paul Chaput 0c54d109cc Fix: Do not return transient string in PyTypeManager.
* Bug: In Isobar3::PyTypeManager, the accessors _getCppTypeName() and
    _getPyTypeName() where returning string *by value*, hence, short
    lived copies.
      But, in _setupPyType() and _addToModule(), as we interface with
    the Python/C API, we extract the c_str(). Which where removed as
    we used temporary objects. Leading to memory corruption and weird
    crashes.
      Now returns "const string&" so the c_str() stays allocated.
2022-01-01 16:46:41 +01:00
Jean-Paul Chaput 9aaaf33e6e Manage more interrupt signals in CRL::System::_trapSig(). Display value. 2022-01-01 16:46:15 +01:00
Jean-Paul Chaput 550b087f05 Takes even further appart the HTree buffer input/output. 2021-12-31 16:48:45 +01:00
Jean-Paul Chaput 084eee3b39 Added support for RHEL9. 2021-12-31 16:35:38 +01:00
Jean-Paul Chaput 5f8a0a944c Display bug for non-rectangular components in DrawinQuery::drawGo().
* Bug: In CellWidget::DrawingQuery::drawGo(), the display condition was
    wrong, it was requiring *both* width & height to be above the display
    threshold. Either one is sufficient to activate the display.
      Was causing the selective diseapearance of gates at low zoom level
    and printed version.
* Change: In CellPrinter, force the display threshold to one pixel in it's
    internal CellWidget used for printing.
2021-12-25 15:23:49 +01:00
Jean-Paul Chaput fdce75fdad Fix bad computation of perpandicular free space in DataNegociate, again.
* Bug: In Katana::DataNegociate::update(), when computing the length of
    source & target extension on a perpandicular segment, must use the
    extensions of the *directly* connected AutoSegment (the baseSegment)
    and not the canonical one that may be different, so with unrelated
    extensions.
2021-12-25 15:23:23 +01:00
Jean-Paul Chaput 104c043416 In the H-Tree, shift vertical H wire one pitch to the left.
* Bug: In cumulus/plugins.block.HTree._rrouteHTree(), the RoutingPads
    for the input and output of the buffer where sometimes put too
    close from each others, giving the pitch of the vertical tracks.
    Now shift one pitch left the vertical branchs of the H-Tree.
* Bug: In cumulus/plugins.block.HTree._rrouteHTree(), also shift down
    one pitch the horizontal branch, due to track rounding they *may*
    end up on the same track, generating a short.
2021-12-25 15:22:58 +01:00
Jean-Paul Chaput 64056d25ee Layer assignment step was ignoring the number of RoutingPad threshold.
* Bug: In Anabatic::layerAssign(), during the step of desaturation of
    GCells that contains too much terminals (i.e. lot of *local*
    congestion), the desaturation threshold was har-coded to 8.
    Wich is fine for symbolic cmos but way too low for Flexlib.
      End result was that most straight wires where moved towards
    the upper layers, creating congestion (imbalance of layer
    densities).
      Now the parameter:
        * "anabatic.saturateRp" (default value:8) is correctly taken
	  into account.
2021-12-22 15:52:22 +01:00
Jean-Paul Chaput a4ad671739 Fix too naive obstacle detection on non-prefered metal2 wires.
* Fix: In Manipulator::avoidBlockage(), the dedicated function to check if
    there is an obstacle in the way of a non-prefered routing wire (done
    for metal2 connecting to terminals only) was too naive.
      We were checking the tracks for obstacles crossing exactly the axis
    of the segment. And for near-miss this is not enough. Now check on
    the whole x-span to be used by the segment.
      Code borrowed and simplified from Track::addOverlapcost().
* Change: In Manipulator::moveUp(), the default value for the extra
    reservation allowing a long wire to move up need to be customized
    for Flexlib/StdCellLib (allow successful routing of ChipFlow/MPW4).
      Add two new configuration parameters to katana:
        * "katana.longWireUpThresold1" : the length, expressed in number
	  of *slice height* above which a global wire is considered a
	  *long* wire (not close interconnect).
        * "katana.longWireUpReserve1" : the extra number of free tracks
	  that must remains free in the up layer after the move up,
	  in each GCell traversed by the wire. Expressed in number of
	  tracks, but can be non-integer (float, for instance: 1.5).
2021-12-21 16:13:31 +01:00
Jean-Paul Chaput 92e5f3fa4d Update ad-hoc patch for obstacles for Flexlib & StdCellLib.
* Bug: In Katana::PowerRailsPlane::Rail::doLayout(), to avaid tracks too
    close to an offgrid obstacle in the preferred routing direction, we
    expand the width/height of the segment by one pitch. BUT it seems to
    still be too close for Flexlib and StdCellLib, so there is an ad-hoc
    patch based on the *name* of the cell library. Update it to take
    "StdCellLib" into account.
2021-12-21 16:13:07 +01:00
Jean-Paul Chaput 3fa8d516bc Fix bad computation of perpandicular free space in DataNegociate.
NOTE: This is likely to explain why we still got overlap in the
      track coherency check in very rare occasions.

* Bug: In Katana::DataNegociate::update(), when computing the allowed
    free interval for the segment axis deduced from the perpandicularly
    connex segments, we account for the extension of the connecting
    VIA. Those extension varies according to the kind of VIA and are
    given by getExtensionCap().
      We were accounting for the source & target extension VIA on the
    parallel segments, assuming that source/target would not swap when
    the perpandicular is moved. Which is *not* true.
      Now account for the extension of the *connecting* VIA on all ends.
* Change: In AutoSegment::getTopologicalInfos(), enrich the list of
    perpandicularly connected segment with wether they are connex by
    their *source* or *target* contact. Mainly to be used by
    DataNegociate::update().
2021-12-18 17:45:17 +01:00
Jean-Paul Chaput ae1f08f039 Change SkyWater130 Caravel harness connecting strategy.
* Change: In cumulus/plugins/core2chip, instead of the user providing
    an explicit mapping towards the harness I/O pins, we expect that
    the core block must have I/O pins with names matching thoses of
    the harness. That way, connections are automatically made.
* Change: In cumulus/plugins/block/htree, if the root signal of the
    H-Tree is a bit from a vector (like "io_in(0)"), then remove the
    vector index notation on all the stem name of all the sub-nets.
    Done by the unbitify() function: "io_in(0)" => "io_in_bit0".
2021-12-17 15:58:57 +01:00
Jean-Paul Chaput 76d468f6d5 Change in feed & tie managements to fill the empty row spaces.
* Change: In EtesianEngine::_postCreate(), issue a warning if the list of
    feeds is empy (configuration: "cfg.etesian.feedNames").
* New: Add a FeedCeels::getFeedByWidth() method to get feeds by their
    width in DbU::Unit and not only pitches.
* Change: In Placement::Slice::fillHole(), invert the tie filling and
    feeds filling stage. Now we first try to fill the row hole with
    feeds, using the widest first, and if they are not configured or
    too wide, use the tie.
      As the tie *should* also be integrated in the feed list, we may
    suppress altogether the fallback tie filling step. Keep it for now.
* Change: In Placement::slice::createDiodeUnder(), the inserted diode
    *may* be smaller than the feed it replace. So, in this case, add
    a complementary feed to fill the gap.
    NOTE 1: Out of lazyness, we add only *one* complementary filler
            cell. So there *must* be one of a width wich correspond
	    exactly to the difference between the original feed and
	    the diode. Otherwise, gap will remains.
    NOTE 2: With wider feed cells, they may cross the GCell border.
            But we must insert the diode under the GCell, otherwise
	    the global routing will be defective. So, for now, reject
	    feeds that cross the boundary. Must be done more smartly
	    by inserting the diode over the left or right side of
	    the feed.
2021-12-17 15:58:13 +01:00
Jean-Paul Chaput 4ab6888b94 Fix Pin managment on north & east side of the cell abutment box.
* Change: In AnabaticEngine::setupPrerouteds(), take into account the
    number of Pins. Now consider a net containing multiple Pins and, at most,
    one segment as *non-routed".
      This case may specifically happens for nets with pins on the north
    and east side, which are slightly *inside* the abutment box (to be
    seen by the router) and draw with them their *outside* direct
    connection wire.
* Bug: In cumulus/plugins.chip.CoreWire, no longer put the north or
    east side external Pin *exacyly* on the abutment box but *one pitch*
    inside so they are correctly seens by the P&R (must be *inside*
    the area of a GCell).
2021-12-17 15:56:15 +01:00
Jean-Paul Chaput 67ca0997c3 Merge branch 'fix-blif-zero-one' into 'devel'
blif: Improve detection of zero/one net by requiring it to be external

See merge request vlsi-eda/coriolis!12
2021-12-11 21:07:18 +00:00
Jean-Paul Chaput 73296503ad Merge branch 'devel' of gitlab.lip6.fr:vlsi-eda/coriolis into devel 2021-12-11 22:00:10 +01:00
Jean-Paul Chaput fe32916d14 Add support for the SkyWater130 Caravel harness to "core2chip".
It is now possible to automatically nest a core block inside a harness
frame, like we do for an ordinary chip whith I/O pads. The DEF harness
file "user_project_wrapper.def" must be made available though the block
configuration variable:
   conf.cfg.harness.path = './user_project_wrapper.def'
A first small example is given in:
   alliance-check-toolkit/benchs/counter/sky130_c4m
The harness layout is stripped from it's native power grid (but keep
the power ring). I/O pad information in block/configuration is
slightly "bent* to manage pins instead of complete I/O pads.

* Bug: In cumulus/plugins.block.Block.setupAb(), the routingBb was not
    set up when working in chip mode. Now set (to the corona AB).
* Change: In cumulus/plugins.chip.__init__, move there the CoreWire
    class (from chip/pads.py) so it can be shared with the harness
    version of pads.py.
* Change: In cumulus/plugins.chip.powerplane, compute the intersection
    between the vertical supply stripes and the deep horizontal power
    lines in a smarter fashion, so two (or more) vertically contiguous
    BigVias are merged into one (two BigVia side by side where causing
    mimimal spacing distance violation on the cut in Sky130).
2021-12-11 19:52:31 +01:00
Jean-Paul Chaput 2ca9e162ef Allow the detailed routing to be build from non-bottom P&R layers.
* New: In Anabatic::AutoSegment::create(), allow the created segment to
    be in any supported routing layer, and not only the bottom H & V.
    Modifications impact the *two* overload of the function.
* Change: In Anabatic::NetBuilderHV::doRp_AutoContacts(), for punctual
    METAL1, the protection has to be in METAL2. Bump the layer depth
    to correctly use the updated verstion of AutoSegment::create().
* Change: In AnabaticEngine::checkPlacement(), for the Pin, check that
    it's layer is in the routing gauge before anything else.
* New: In Katana::NegociateWindow::createTrackSegment(), if the track
    nearest the segment axis (refTrack) do not exists, call a
    breakpoint just before crashing.
2021-12-11 19:51:24 +01:00
Jean-Paul Chaput ba2a74e35d Tweaked DEF support to load the Caravel harness.
* Bug: In CRL::BlifParser::Model CTOR, forgot to set the direction
    on auto-generated power supply global nets. So they were put
    in "linkage" in the VST files.
* New: In CRL::DefImport, add specific support for the Sky130/Caravel
    harness "user_project_wrapper".Mainly:
    - Do not fuse together "io_in" and "io_out" as a single net as
      they should (according to the DEF). So we can connect separately
      on each of them. We only allow one port for each net, as in VHDL.
2021-12-11 19:48:57 +01:00
Jean-Paul Chaput 2f0bf5456d Added Etesian to the measurment system.
* Bug: In CRL::MeasureSet::toStringHeaders(), check and issue a warning
    if a measure label ends with a "." (dot).
* Change: In CRL::ToolEngine::getMeasure(), return the data measure
    by pointer instead of by reference (easier to manipulate afterwards).
* New: In EtesianEngine::place(), add the placement runtime (under label
    "placeT") to the measure set.
* New: In KatanaEngine::dumpMeasures(), add the Etesian runtime to the
    set of measures.
2021-12-11 19:47:24 +01:00
Jean-Paul Chaput be598c9b96 Update the Python wrapping of Hurricane::Entity.
* New: In Hurricane::PyEntity, export the getBoundingBox() method.
2021-12-11 19:44:20 +01:00
gatecat 3f08b3789f blif: Improve detection of zero/one net by requiring it to be external
Signed-off-by: gatecat <gatecat@ds0.me>
2021-12-10 19:17:03 +00:00
Jean-Paul Chaput f14ef8adc2 Updated PDFs, December 10, 2021 (15:07). 2021-12-10 15:07:58 +01:00
Gabriel Gouvine b4a7d1a6fd Add SUPPORT.rst file 2021-12-09 22:32:02 +01:00
Gabriel Gouvine 4e23dff0dc Update URL in the README 2021-12-09 22:31:58 +01:00
4768 changed files with 563425 additions and 88146 deletions

54
.gitlab-ci.yml Normal file
View File

@ -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

6
.gitmodules vendored Normal file
View File

@ -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

35
Coriolis/__init__.py Normal file
View File

@ -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:]))

View File

@ -40,23 +40,20 @@ Building Coriolis
To build Coriolis, ensure the following prerequisites are met: To build Coriolis, ensure the following prerequisites are met:
* Python 3. * Python 3,
* cmake. * cmake,
* boost. * boost,
* bison & flex. * bison & flex,
* Qt 4 or 5. * Qt 4 or 5,
* libxml2. * libxml2,
* RapidJSON * RapidJSON,
* A C++11 compliant compiler. * A C++11 compliant compiler.
The build system relies on a fixed directory tree from the root The build system relies on a fixed directory tree from the root
of the user currently building it. Thus first step is to get a clone of of the user currently building it. Thus first step is to get a clone of
the repository in the right place. Proceed as follow: :: the repository in the right place. Proceed as follow: ::
ego@home:~$ mkdir -p ~/coriolis-2.x/src/support ego@home:~$ mkdir -p ~/coriolis-2.x/src/
ego@home:~$ cd ~/coriolis-2.x/src/support
ego@home:~$ git clone http://github.com/miloyip/rapidjson
ego@home:~$ git checkout ec322005072076ef53984462fb4a1075c27c7dfd
ego@home:~$ cd ~/coriolis-2.x/src ego@home:~$ cd ~/coriolis-2.x/src
ego@home:src$ git clone https://gitlab.lip6.fr/vlsi-eda/coriolis.git ego@home:src$ git clone https://gitlab.lip6.fr/vlsi-eda/coriolis.git
ego@home:src$ cd coriolis 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 environment appropriately, then lauches ``cgt`` (or *any* command, with the
``--run=<COMMAND>`` option). ``--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: :: using the helper ``coriolisEnv.py``, then run any Coriolis tool: ::
ego@home:~$ eval `~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py` ego@home:~$ eval `~/coriolis-2.x/src/coriolis/bootstrap/coriolisEnv.py`

44
Seabreeze/CMakeLists.txt Normal file
View File

@ -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)

27
Seabreeze/README.txt Normal file
View File

@ -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
}

View File

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

View File

@ -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)

View File

@ -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} )

49
Seabreeze/doc/Node.dox Normal file
View File

@ -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.
*/

102
Seabreeze/doc/Seabreeze.dox Normal file
View File

@ -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
*/
}

50
Seabreeze/doc/Tree.dox Normal file
View File

@ -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.
*/

View 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>&nbsp;&nbsp;<tt>ClassA</tt> is abstract</b></tr>
<tr><td width="70"><td class="normal"><a href="#pagetop">ClassB</a><td><b>&nbsp;&nbsp;<tt>ClassB</tt> is instanciable</b></tr>
</table>
</pre>
<br>
<h2 class="classHierarchy">Utilities</h2>
<table class="classHierarchy">
<tr><td width="70"><td class="virtual"><a href="classSeabreeze_1_1BaseObserver.html">BaseObserver</a>
</table>
<table class="classHierarchy">
<tr><td width="140"><td class="normal"><a href="classSeabreeze_1_1Observer.html">Observer</a>
</table>
<table class="classHierarchy">
<tr><td width="70"><td class="normal"><a href="classSeabreeze_1_1Observable.html">Observable</a>
</table>
<h2 class="classHierarchy">Seabreeze Engine</h2>
<table class="classHierarchy">
<tr><td width="70"><td class="normal"><a href="namespaceSeabreeze.html">Seabreeze</a>
<tr><td width="70"><td class="normal"><a href="classSeabreeze_1_1ChipTools.html">ChipTools</a>
<tr><td width="70"><td class="normal"><a href="classSeabreeze_1_1SeabreezeEngine.html">SeabreezeEngine</a>
<tr><td width="70"><td class="normal"><a href="classSeabreeze_1_1Session.html">Session</a>
<tr><td width="70"><td class="normal"><a href="classSeabreeze_1_1DataAlgorithm.html">DataAlgorithm</a>
</table>
<h2 class="classHierarchy">Contacts</h2>
<table class="classHierarchy">
<tr><td width="70"><td class="virtual"><a href="classSeabreeze_1_1AutoContact.html">AutoContact</a>
</table>
<table class="classHierarchy">
<tr><td width="140"><td class="normal"><a href="classSeabreeze_1_1AutoContactTerminal.html">AutoContactTerminal</a>
<tr><td width="140"><td class="normal"><a href="classSeabreeze_1_1AutoContactTurn.html">AutoContactTurn</a>
<tr><td width="140"><td class="normal"><a href="classSeabreeze_1_1AutoContactHTee.html">AutoContactHTee</a>
<tr><td width="140"><td class="normal"><a href="classSeabreeze_1_1AutoContactVTee.html">AutoContactVTee</a>
</table>
<h2 class="classHierarchy">Segments</h2>
<table class="classHierarchy">
<tr><td width="70"><td class="virtual"><a href="classSeabreeze_1_1AutoSegment.html">AutoSegment</a>
</table>
<table class="classHierarchy">
<tr><td width="140"><td class="normal"><a href="classSeabreeze_1_1AutoHorizontal.html">AutoHorizontal</a>
<tr><td width="140"><td class="normal"><a href="classSeabreeze_1_1AutoVertical.html">AutoVertical</a>
</table>
<h2 class="classHierarchy">GCell</h2>
<table class="classHierarchy">
<tr><td width="70"><td class="normal"><a href="classSeabreeze_1_1GCell.html">GCell</a>
<tr><td width="70"><td class="normal"><a href="classSeabreeze_1_1BaseGrid_1_1Axis.html">BaseGrid::Axis</a>
<tr><td width="70"><td class="virtual"><a href="classSeabreeze_1_1BaseGrid.html">BaseGrid</a>
</table>
<table class="classHierarchy">
<tr><td width="140"><td class="virtual"><a href="classSeabreeze_1_1Grid.html">Grid</a>
</table>
<table class="classHierarchy">
<tr><td width="210"><td class="normal"><a href="classSeabreeze_1_1GCellGrid.html">GCellGrid</a>
</table>

View File

@ -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 &amp; Canonical.</a>
<br>How to force alignment of AutoSegments.
<li><a class="el" href="group__layerAssign.html">Layer Assignment.</a>
<br>Simple strategy to put long wires on higher routing metals.
<li><a class="el" href="group__NetConstraints.html">Constraints Computations.</a>
<br>Compute the legal range of variation of each wire (note that the
constraints are stored on AutoContacts).
<li><a class="el" href="group__NetOptimals.html">AutoSegment Optimal Placement.</a>
<br>Compute the optimal range of variation of each wire.
<li><a class="el" href="group__katabaticSession.html">Seabreeze Update Session Mechanism.</a>
<br>The Session mechanism for modifying the Seabreeze data-base.
</ol>
-->
<h2>API documentations</h2>
<ul>
<li><b><a href="customHierarchy.html">Synthetic Class Hierarchy.</a></b>
<li><b><a href="hierarchy.html">Complete Class Hierarchy (doxygen).</a></b>
<li><b><a href="annotated.html">Class List (doxygen).</a></b>
<li><b><a href="classes.html">Class Index (doxygen).</a></b>
<li><b><a href="modules.html">Modules (raw concepts).</a></b>
<li><b><a href="functions.html">Member Functions Index (doxygen).</a></b>
<li><b><a href="namespaces.html">Namespaces (doxygen).</a></b>
</ul>
<br>
<hr>
<table class="footer1">
<tr>
<td class="LFooter"><small>Customized Concepts (a.k.a. modules)</small></td>
<td class="RFooter"><a href='#pagetop'><small>Return to top of page</small></a></td>
</tr>
</table>
<table class="footer2">
<tr>
<td class="LFooter">Seabreeze Documentation</td>
<td class="RFooter"><small>Copyright &#169; 2005-2007 LIP6. All rights reserved</small></td>
</tr>
</table>
</body>
</html>

276
Seabreeze/doc/doxyfile Normal file
View File

@ -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

16
Seabreeze/doc/footer.html Normal file
View File

@ -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 &#169; 2008-2020 Sorbonne Universite. All rights reserved</small></td>
</tr>
</table>
</body>
</html>

26
Seabreeze/doc/header.html Normal file
View File

@ -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)">

View File

@ -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 )

View File

@ -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.

71
Seabreeze/src/Delay.cpp Normal file
View File

@ -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.

577
Seabreeze/src/Elmore.cpp Normal file
View File

@ -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.

86
Seabreeze/src/Node.cpp Normal file
View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

207
Seabreeze/src/Tree.cpp Normal file
View File

@ -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.

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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);

143
Seabreeze/src/test.cpp Normal file
View File

@ -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;
}

5
Seabreeze/test/data1.txt Normal file
View File

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

15
Seabreeze/test/data2.txt Normal file
View File

@ -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

1
Seabreeze/test/todo.txt Normal file
View File

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

View File

@ -9,7 +9,7 @@
option(CHECK_DATABASE "Run database in full check mode (very slow)" OFF) option(CHECK_DATABASE "Run database in full check mode (very slow)" OFF)
option(USE_LIBBFD "Link with BFD libraries to print stack traces" OFF) 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/") list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}$ENV{CORIOLIS_TOP}/share/cmake/Modules/")
find_package(Bootstrap REQUIRED) find_package(Bootstrap REQUIRED)
@ -18,8 +18,8 @@
set_cmake_policies() set_cmake_policies()
setup_boost() setup_boost()
setup_qt() setup_qt()
setup_python()
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
find_package(PythonSitePackages REQUIRED) find_package(PythonSitePackages REQUIRED)
find_package(FLUTE REQUIRED) find_package(FLUTE REQUIRED)
find_package(HURRICANE REQUIRED) find_package(HURRICANE REQUIRED)

View File

@ -34,6 +34,7 @@
#include "crlcore/Histogram.h" #include "crlcore/Histogram.h"
#include "anabatic/GCell.h" #include "anabatic/GCell.h"
#include "anabatic/AutoContactTerminal.h" #include "anabatic/AutoContactTerminal.h"
#include "anabatic/NetBuilderHybridVH.h"
#include "anabatic/NetBuilderM2.h" #include "anabatic/NetBuilderM2.h"
#include "anabatic/NetBuilderHV.h" #include "anabatic/NetBuilderHV.h"
#include "anabatic/NetBuilderVH.h" #include "anabatic/NetBuilderVH.h"
@ -243,7 +244,6 @@ namespace Anabatic {
cerr << Error( "RawGCellsUnder::commonCtor(): Points are neither horizontally nor vertically aligneds (ignored)." cerr << Error( "RawGCellsUnder::commonCtor(): Points are neither horizontally nor vertically aligneds (ignored)."
) << endl; ) << endl;
cdebug_tabw(112,-1); cdebug_tabw(112,-1);
DebugSession::close();
return; return;
} }
@ -251,10 +251,16 @@ namespace Anabatic {
or (source.getY() > gcellsArea.getYMax()) or (source.getY() > gcellsArea.getYMax())
or (target.getX() <= gcellsArea.getXMin()) or (target.getX() <= gcellsArea.getXMin())
or (target.getY() <= gcellsArea.getYMin()) ) { 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"
) << endl; " * 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); cdebug_tabw(112,-1);
DebugSession::close();
return; return;
} }
@ -273,21 +279,18 @@ namespace Anabatic {
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): Source not under a GCell (ignored)." cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): Source not under a GCell (ignored)."
) << endl; ) << endl;
cdebug_tabw(112,-1); cdebug_tabw(112,-1);
DebugSession::close();
return; return;
} }
if (not gtarget) { if (not gtarget) {
cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): Target not under a GCell (ignored)." cerr << Bug( "RawGCellsUnder::RawGCellsUnder(): Target not under a GCell (ignored)."
) << endl; ) << endl;
cdebug_tabw(112,-1); cdebug_tabw(112,-1);
DebugSession::close();
return; return;
} }
if (gsource == gtarget) { if (gsource == gtarget) {
_elements.push_back( Element(gsource,NULL) ); _elements.push_back( Element(gsource,NULL) );
cdebug_tabw(112,-1); cdebug_tabw(112,-1);
DebugSession::close();
return; return;
} }
@ -369,31 +372,34 @@ namespace Anabatic {
, _viewer (NULL) , _viewer (NULL)
, _flags (Flags::DestroyBaseContact) , _flags (Flags::DestroyBaseContact)
, _stamp (-1) , _stamp (-1)
, _routingMode (DigitalMode)
, _densityMode (MaxDensity) , _densityMode (MaxDensity)
, _autoSegmentLut () , _autoSegmentLut ()
, _autoContactLut () , _autoContactLut ()
, _edgeCapacitiesLut() , _edgeCapacitiesLut()
, _blockageNet (cell->getNet("blockagenet")) , _blockageNet (cell->getNet("blockagenet"))
, _diodeCell (NULL) , _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 () void AnabaticEngine::_postCreate ()
{ {
Super::_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) { if (not _diodeCell) {
cerr << Warning( "AnabaticEngine::_postCreate() Unable to find \"%s\" diode cell." cerr << Warning( "AnabaticEngine::_postCreate() Unable to find \"%s\" diode cell."
, getConfiguration()->getDiodeName().c_str() , _configuration->getDiodeName().c_str()
) << endl; ) << endl;
} }
@ -404,6 +410,10 @@ namespace Anabatic {
} }
Configuration* AnabaticEngine::_createConfiguration ()
{ return new Configuration(); }
AnabaticEngine* AnabaticEngine::create ( Cell* cell ) AnabaticEngine* AnabaticEngine::create ( Cell* cell )
{ {
if (not cell) throw Error( "AnabaticEngine::create(): NULL cell argument." ); if (not cell) throw Error( "AnabaticEngine::create(): NULL cell argument." );
@ -615,6 +625,7 @@ namespace Anabatic {
} }
} }
RoutingGauge* rg = _configuration->getRoutingGauge();
size_t errorCount = 0; size_t errorCount = 0;
ostringstream errors; ostringstream errors;
errors << "AnabaticEngine::checkPlacement():\n"; errors << "AnabaticEngine::checkPlacement():\n";
@ -626,55 +637,62 @@ namespace Anabatic {
ostringstream pinError; ostringstream pinError;
Point pinCenter = rp->getCenter(); RoutingLayerGauge* lg = rg->getLayerGauge( pin->getLayer() );
if ( (pin->getAccessDirection() == Pin::AccessDirection::NORTH) if (not lg) {
or (pin->getAccessDirection() == Pin::AccessDirection::SOUTH) ) { pinError << " Layer not in the routing gauge, "
if (pin->getLayer() != getConfiguration()->getDVerticalLayer()) { << "pin:" << pin->getLayer()->getName()
pinError << " Should be in vertical routing layer, " << "\n";
<< "pin:" << pin->getLayer()->getName() valid = false;
<< " vs gauge:" << getConfiguration()->getDVerticalLayer()->getName() ++errorCount;
<< "\n"; } else {
valid = false; Point pinCenter = rp->getCenter();
++errorCount; if ( (pin->getAccessDirection() == Pin::AccessDirection::NORTH)
} or (pin->getAccessDirection() == Pin::AccessDirection::SOUTH) ) {
if ((pinCenter.getX() - getCell()->getAbutmentBox().getXMin() if (not lg->isVertical()) {
- getConfiguration()->getDVerticalOffset()) pinError << " Should be in vertical routing layer, "
% getConfiguration()->getDVerticalPitch()) { << "pin:" << pin->getLayer()->getName()
pinError << " Misaligned, " << " vs gauge:" << lg->getLayer()->getName()
<< "pin:" << DbU::getValueString(pinCenter.getX()) << "\n";
<< " vs gauge, pitch:" << DbU::getValueString(getConfiguration()->getDVerticalPitch ()) valid = false;
<< ", offset:" << DbU::getValueString(getConfiguration()->getDVerticalOffset()) ++errorCount;
<< "\n"; }
valid = false; if ((pinCenter.getX() - getCell()->getAbutmentBox().getXMin() - lg->getOffset())
++errorCount; % lg->getPitch()) {
} pinError << " Misaligned, "
} << "pin:" << DbU::getValueString(pinCenter.getX())
<< " vs gauge, pitch:" << DbU::getValueString(lg->getPitch ())
<< ", offset:" << DbU::getValueString(lg->getOffset())
<< "\n";
valid = false;
++errorCount;
}
}
if ( (pin->getAccessDirection() == Pin::AccessDirection::EAST) if ( (pin->getAccessDirection() == Pin::AccessDirection::EAST)
or (pin->getAccessDirection() == Pin::AccessDirection::WEST) ) { or (pin->getAccessDirection() == Pin::AccessDirection::WEST) ) {
if (pin->getLayer() != getConfiguration()->getDHorizontalLayer()) { if (not lg->isHorizontal()) {
pinError << " Should be in horizontal routing layer, " pinError << " Should be in horizontal routing layer, "
<< "pin:" << pin->getLayer()->getName() << "pin:" << pin->getLayer()->getName()
<< " vs gauge:" << getConfiguration()->getDHorizontalLayer()->getName() << " vs gauge:" << lg->getLayer()->getName()
<< "\n"; << "\n";
valid = false; valid = false;
++errorCount; ++errorCount;
} }
if ((pinCenter.getY() - getCell()->getAbutmentBox().getYMin() if ((pinCenter.getY() - getCell()->getAbutmentBox().getYMin() - lg->getOffset())
- getConfiguration()->getDHorizontalOffset()) % lg->getPitch()) {
% getConfiguration()->getDHorizontalPitch()) { pinError << " Misaligned, "
pinError << " Misaligned, " << "pin:" << DbU::getValueString(pinCenter.getY())
<< "pin:" << DbU::getValueString(pinCenter.getY()) << " vs gauge, pitch:" << DbU::getValueString(lg->getPitch ())
<< " vs gauge, pitch:" << DbU::getValueString(getConfiguration()->getDHorizontalPitch ()) << ", offset:" << DbU::getValueString(lg->getOffset())
<< ", offset:" << DbU::getValueString(getConfiguration()->getDHorizontalOffset()) << "\n";
<< "\n"; valid = false;
valid = false; ++errorCount;
++errorCount; }
} }
}
if (not pinError.str().empty()) { if (not pinError.str().empty()) {
errors << "On " << pin << "\n" << pinError.str(); errors << "On " << pin << "\n" << pinError.str();
}
} }
} }
} }
@ -836,7 +854,7 @@ namespace Anabatic {
if (horizontal) { if (horizontal) {
splitted = Horizontal::create( breakContact splitted = Horizontal::create( breakContact
, targetContact , targetContact
, getConfiguration()->getGHorizontalLayer() , _configuration->getGHorizontalLayer()
, horizontal->getY() , horizontal->getY()
, DbU::fromLambda(2.0) , DbU::fromLambda(2.0)
); );
@ -845,7 +863,7 @@ namespace Anabatic {
if (vertical) { if (vertical) {
splitted = Vertical::create( breakContact splitted = Vertical::create( breakContact
, targetContact , targetContact
, getConfiguration()->getGVerticalLayer() , _configuration->getGVerticalLayer()
, vertical->getX() , vertical->getX()
, DbU::fromLambda(2.0) , DbU::fromLambda(2.0)
); );
@ -1081,7 +1099,7 @@ namespace Anabatic {
for ( Net* net : getCell()->getNets() ) { for ( Net* net : getCell()->getNets() ) {
for ( Component* component : net->getComponents() ) { for ( Component* component : net->getComponents() ) {
if (getConfiguration()->isGLayer(component->getLayer())) { if (_configuration->isGLayer(component->getLayer())) {
cerr << Error( "AnabaticEngine::cleanupGlobal(): Remaining global routing,\n" cerr << Error( "AnabaticEngine::cleanupGlobal(): Remaining global routing,\n"
" %s" " %s"
, getString(component).c_str() , getString(component).c_str()
@ -1108,7 +1126,7 @@ namespace Anabatic {
} }
cleanupGlobal(); cleanupGlobal();
if (not getConfiguration()->isTwoMetals()) relaxOverConstraineds(); if (not _configuration->isTwoMetals()) relaxOverConstraineds();
_state = EngineActive; _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 () void AnabaticEngine::_loadGrByNet ()
{ {
cmess1 << " o Building detailed routing from global. " << endl; cmess1 << " o Building detailed routing from global. " << endl;
@ -1234,12 +1310,13 @@ namespace Anabatic {
startMeasures(); startMeasures();
openSession(); openSession();
int gaugeKind = 3; uint32_t gaugeKind = 4;
if (getConfiguration()->isTwoMetals()) gaugeKind = 0; if (NetBuilderHybridVH::getStyle() == getNetBuilderStyle()) gaugeKind = 0;
if (getConfiguration()->isHV ()) gaugeKind = 1; else if (NetBuilderM2 ::getStyle() == getNetBuilderStyle()) gaugeKind = 1;
if (getConfiguration()->isVH ()) gaugeKind = 2; 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() ) { for ( Net* net : getCell()->getNets() ) {
if (NetRoutingExtension::isShortNet(net)) { if (NetRoutingExtension::isShortNet(net)) {
//AutoSegment::setShortNetMode( true ); //AutoSegment::setShortNetMode( true );
@ -1253,9 +1330,10 @@ namespace Anabatic {
AutoSegment::setAnalogMode( NetRoutingExtension::isAnalog(net) ); AutoSegment::setAnalogMode( NetRoutingExtension::isAnalog(net) );
switch ( gaugeKind ) { switch ( gaugeKind ) {
case 0: NetBuilder::load<NetBuilderM2>( this, net ); break; case 0: NetBuilder::load<NetBuilderHybridVH>( this, net ); break;
case 1: NetBuilder::load<NetBuilderHV>( this, net ); break; case 1: NetBuilder::load<NetBuilderM2> ( this, net ); break;
case 2: NetBuilder::load<NetBuilderVH>( this, net ); break; case 2: NetBuilder::load<NetBuilderVH> ( this, net ); break;
case 3: NetBuilder::load<NetBuilderHV> ( this, net ); break;
} }
Session::revalidate(); Session::revalidate();
@ -1274,11 +1352,6 @@ namespace Anabatic {
stopMeasures(); stopMeasures();
cmess2 << Dots::asSizet(" - Short nets",shortNets) << endl; 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" ); printMeasures( "load" );
@ -1610,7 +1683,7 @@ namespace Anabatic {
EdgeCapacity* AnabaticEngine::_createCapacity ( Flags flags, Interval span ) EdgeCapacity* AnabaticEngine::_createCapacity ( Flags flags, Interval span )
{ {
size_t depth = getConfiguration()->getAllowedDepth(); size_t depth = _configuration->getAllowedDepth();
EdgeCapacity* edgeCapacity = NULL; EdgeCapacity* edgeCapacity = NULL;
flags &= Flags::EdgeCapacityMask; flags &= Flags::EdgeCapacityMask;
@ -1652,7 +1725,7 @@ namespace Anabatic {
UpdateSession::open(); UpdateSession::open();
for ( auto rp : rps ) { 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; cerr << Warning( "AnabaticEngine::computeEdgeCapacities(): %s has no components on grid.", getString(rp).c_str() ) << endl;
Point center = rp->getBoundingBox().getCenter(); Point center = rp->getBoundingBox().getCenter();

View File

@ -183,19 +183,26 @@ namespace Anabatic {
void AutoContact::getDepthSpan ( size_t& minDepth, size_t& maxDepth ) const void AutoContact::getDepthSpan ( size_t& minDepth, size_t& maxDepth ) const
{ {
cdebug_log(145,1) << "AutoContact::getDepthSpan() of " << this << endl;
minDepth = (size_t)-1; minDepth = (size_t)-1;
maxDepth = 0; maxDepth = 0;
Component* anchor = getAnchor (); Component* anchor = getAnchor ();
if (anchor) { if (anchor) {
cdebug_log(145,0) << "* Anchor depth: "
<< Session::getRoutingGauge()->getLayerDepth(anchor->getLayer())<< endl;
minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) ); minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) );
maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) ); maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(anchor->getLayer()) );
} }
for ( AutoSegment* segment : const_cast<AutoContact*>(this)->getAutoSegments() ) { for ( AutoSegment* segment : const_cast<AutoContact*>(this)->getAutoSegments() ) {
cdebug_log(145,0) << "* segment depth: "
<< Session::getRoutingGauge()->getLayerDepth(segment->getLayer())<< endl;
minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) ); minDepth = std::min( minDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) );
maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) ); maxDepth = std::max( maxDepth, Session::getRoutingGauge()->getLayerDepth(segment->getLayer()) );
} }
cdebug_tabw(145,-1);
} }

View File

@ -406,8 +406,8 @@ namespace Anabatic {
if (horizontals[1] != NULL) ++count; if (horizontals[1] != NULL) ++count;
if (verticals [0] != NULL) ++count; if (verticals [0] != NULL) ++count;
if (verticals [1] != NULL) ++count; if (verticals [1] != NULL) ++count;
if (count > 1) { if (count != 1) {
showTopologyError( "Terminal has more than one segment." ); showTopologyError( "Terminal has not *exactly* one segment." );
} }
if (horizontals[0] != NULL ) { if (horizontals[0] != NULL ) {
_segment = Session::lookup( horizontals[0] ); _segment = Session::lookup( horizontals[0] );
@ -503,6 +503,9 @@ namespace Anabatic {
AutoContact* opposite = _segment->getOppositeAnchor(this); AutoContact* opposite = _segment->getOppositeAnchor(this);
AutoSegment* perpandicular = opposite->getPerpandicular( _segment ); AutoSegment* perpandicular = opposite->getPerpandicular( _segment );
if (perpandicular) { if (perpandicular) {
cdebug_log(145,0) << "Draging V interval ["
<< DbU::getValueString(getCBYMin()) << " "
<< DbU::getValueString(getCBYMax()) << "]" << endl;
DbU::Unit y = perpandicular->getAxis(); DbU::Unit y = perpandicular->getAxis();
y = std::min( y, getCBYMax() ); y = std::min( y, getCBYMax() );
y = std::max( y, getCBYMin() ); y = std::max( y, getCBYMin() );
@ -559,11 +562,11 @@ namespace Anabatic {
if (delta > 1) { if (delta > 1) {
//_segment = _segment->makeDogleg( this ); //_segment = _segment->makeDogleg( this );
_segment->makeDogleg( this ); _segment->makeDogleg( this );
cdebug_log(145,0) << "Update seg: " << _segment << endl;
delta = abssub( anchorDepth, rg->getLayerDepth( _segment->getLayer() ) ); delta = abssub( anchorDepth, rg->getLayerDepth( _segment->getLayer() ) );
cdebug_log(145,0) << "Delta: " << delta << " Update seg: " << _segment << endl;
} }
else if (delta == 0) setLayerAndWidth( delta, anchorDepth ); if (delta == 0) setLayerAndWidth( delta, anchorDepth );
else if (delta == 1) setLayerAndWidth( delta, std::min(anchorDepth,segmentDepth) ); if (delta == 1) setLayerAndWidth( delta, std::min(anchorDepth,segmentDepth) );
} }
_segment->invalidate( this ); _segment->invalidate( this );

View File

@ -263,7 +263,9 @@ namespace Anabatic {
setFlags( CntBadTopology ); setFlags( CntBadTopology );
} else { } else {
if (delta > 1) { 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 = static_cast<AutoHorizontal*>( _horizontal1->makeDogleg(this) );
_horizontal1->makeDogleg(this); _horizontal1->makeDogleg(this);
cdebug_log(145,0) << "Update h1: " << _horizontal1 << endl; cdebug_log(145,0) << "Update h1: " << _horizontal1 << endl;

View File

@ -14,18 +14,19 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#include <algorithm> #include <algorithm>
#include "hurricane/Bug.h" #include "hurricane/Bug.h"
#include "hurricane/Error.h" #include "hurricane/Error.h"
#include "hurricane/DebugSession.h" #include "hurricane/Warning.h"
#include "hurricane/ViaLayer.h" #include "hurricane/DebugSession.h"
#include "hurricane/RoutingPad.h" #include "hurricane/ViaLayer.h"
#include "crlcore/RoutingGauge.h" #include "hurricane/RoutingPad.h"
#include "anabatic/Configuration.h" #include "crlcore/RoutingGauge.h"
#include "anabatic/AutoContactTerminal.h" #include "anabatic/Configuration.h"
#include "anabatic/AutoContactTurn.h" #include "anabatic/AutoContactTerminal.h"
#include "anabatic/AutoHorizontal.h" #include "anabatic/AutoContactTurn.h"
#include "anabatic/AutoVertical.h" #include "anabatic/AutoHorizontal.h"
#include "anabatic/AutoVertical.h"
namespace Anabatic { namespace Anabatic {
@ -33,8 +34,10 @@ namespace Anabatic {
using std::min; using std::min;
using std::max; using std::max;
using Hurricane::Error; using std::abs;
using Hurricane::Bug; using Hurricane::Bug;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::DebugSession; using Hurricane::DebugSession;
using Hurricane::ViaLayer; using Hurricane::ViaLayer;
using Hurricane::RoutingPad; using Hurricane::RoutingPad;
@ -52,8 +55,6 @@ namespace Anabatic {
DbU::Unit AutoHorizontal::getDuSource () const { return _horizontal->getDxSource(); } DbU::Unit AutoHorizontal::getDuSource () const { return _horizontal->getDxSource(); }
DbU::Unit AutoHorizontal::getDuTarget () const { return _horizontal->getDxTarget(); } DbU::Unit AutoHorizontal::getDuTarget () const { return _horizontal->getDxTarget(); }
Interval AutoHorizontal::getSpanU () const { return Interval(_horizontal->getSourceX(),_horizontal->getTargetX()); } Interval AutoHorizontal::getSpanU () const { return Interval(_horizontal->getSourceX(),_horizontal->getTargetX()); }
void AutoHorizontal::setDuSource ( DbU::Unit du ) { _horizontal->setDxSource(du); }
void AutoHorizontal::setDuTarget ( DbU::Unit du ) { _horizontal->setDxTarget(du); }
string AutoHorizontal::_getTypeName () const { return "AutoHorizontal"; } string AutoHorizontal::_getTypeName () const { return "AutoHorizontal"; }
@ -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 Interval AutoHorizontal::getSourceConstraints ( Flags flags ) const
{ {
if (flags & Flags::NativeConstraints) { if (flags & Flags::NativeConstraints) {
@ -487,17 +512,9 @@ namespace Anabatic {
void AutoHorizontal::updateOrient () void AutoHorizontal::updateOrient ()
{ {
if (_horizontal->getTarget()->getX() < _horizontal->getSource()->getX()) { if (_horizontal->getTarget()->getX() < _horizontal->getSource()->getX()) {
cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl; cdebug_log(149,1) << "updateOrient() " << this << " (before S/T swap)" << endl;
if (isAtMinArea()) { _horizontal->invert();
DbU::Unit sourceX = _horizontal->getSourceX(); cdebug_log(149,0) << "updateOrient() " << this << " (after S/T swap)" << endl;
DbU::Unit targetX = _horizontal->getTargetX();
_horizontal->invert();
setDuSource( sourceX - getSourceU() );
setDuTarget( targetX - getTargetU() );
} else {
_horizontal->invert();
}
cdebug_log(145,0) << "updateOrient() " << this << " (after S/T swap)" << endl;
uint64_t spinFlags = _flags & SegDepthSpin; uint64_t spinFlags = _flags & SegDepthSpin;
unsetFlags( SegDepthSpin ); unsetFlags( SegDepthSpin );
@ -515,6 +532,7 @@ namespace Anabatic {
unsetFlags( SegStrongTerminal ); unsetFlags( SegStrongTerminal );
if (terminalFlags & SegSourceTerminal) setFlags( SegTargetTerminal ); if (terminalFlags & SegSourceTerminal) setFlags( SegTargetTerminal );
if (terminalFlags & SegTargetTerminal) setFlags( SegSourceTerminal ); if (terminalFlags & SegTargetTerminal) setFlags( SegSourceTerminal );
cdebug_tabw(149,-1);
} }
} }
@ -857,7 +875,7 @@ namespace Anabatic {
bool upLayer = true; bool upLayer = true;
if (Session::getRoutingGauge()->isTwoMetals()) { if (Session::getRoutingGauge()->isTwoMetals()) {
upLayer = (depth == 0); upLayer = (not Session::getRoutingGauge()->isVH());
} else if (Session::getRoutingGauge()->isVH()) { } else if (Session::getRoutingGauge()->isVH()) {
upLayer = (depth < 2); upLayer = (depth < 2);
} else { } else {

View File

@ -1,7 +1,7 @@
// -*- C++ -*- // -*- C++ -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2008-2018, All Rights Reserved // Copyright (c) Sorbonne Université 2008-2022, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -466,8 +466,10 @@ namespace Anabatic {
bool isVertical = (depth == 0) or (Session::getLayerGauge(depth)->isVertical()); bool isVertical = (depth == 0) or (Session::getLayerGauge(depth)->isVertical());
uint32_t flags = (isVertical) ? Layer::EnclosureV : Layer::EnclosureH ; 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; // << " isVertical:" << Session::getLayerGauge(depth)->isVertical() << endl;
// cerr << " minimalSpacing: "
// << DbU::getValueString( Session::getLayerGauge(depth)->getLayer()->getMinimalSpacing() ) << endl;
*viaToSameCap = Session::getPWireWidth(depth)/2; *viaToSameCap = Session::getPWireWidth(depth)/2;
@ -492,12 +494,12 @@ namespace Anabatic {
*minimalLength += twoGrid - modulo; *minimalLength += twoGrid - modulo;
} }
//cerr << " viaToTop width: " << DbU::getValueString( Session::getViaWidth(depth) ) << endl; // cerr << " viaToTop width: " << DbU::getValueString( Session::getViaWidth(depth) ) << endl;
//cerr << " viaToTopCap: " << DbU::getValueString(*viaToTopCap ) << endl; // cerr << " viaToTopCap: " << DbU::getValueString(*viaToTopCap ) << endl;
//if (depth > 0) // if (depth > 0)
// cerr << " viaToBottom width:" << DbU::getValueString( Session::getViaWidth(depth-1)/2 ) << endl; // cerr << " viaToBottom width:" << DbU::getValueString( Session::getViaWidth(depth-1)/2 ) << endl;
//cerr << " viaToBottomCap: " << DbU::getValueString(*viaToBottomCap) << endl; // cerr << " viaToBottomCap: " << DbU::getValueString(*viaToBottomCap) << endl;
//cerr << " viaToSameCap: " << DbU::getValueString(*viaToSameCap ) << endl; // cerr << " viaToSameCap: " << DbU::getValueString(*viaToSameCap ) << endl;
_extensionCaps.push_back( std::array<DbU::Unit*,4>( {{ viaToTopCap _extensionCaps.push_back( std::array<DbU::Unit*,4>( {{ viaToTopCap
, viaToBottomCap , viaToBottomCap
@ -679,8 +681,12 @@ namespace Anabatic {
void AutoSegment::revalidate () void AutoSegment::revalidate ()
{ {
DebugSession::open( getNet(), 159, 160 );
cdebug_log(149,0) << "AutoSegment::revalidate() " << this << endl; cdebug_log(149,0) << "AutoSegment::revalidate() " << this << endl;
if (not isInvalidated()) return; if (not isInvalidated()) {
DebugSession::close();
return;
}
cdebug_tabw(149,1); cdebug_tabw(149,1);
@ -715,9 +721,9 @@ namespace Anabatic {
} }
Interval oldSpan = Interval( _sourcePosition, _targetPosition ); Interval oldSpan = Interval( _sourcePosition, _targetPosition );
if (not expandToMinLength(oldSpan)) { if (_flags & SegCreated) oldSpan.makeEmpty();
unexpandToMinLength(); expandToMinLength( oldSpan );
} if (_flags & SegAtMinArea) unexpandToMinLength();
updatePositions(); updatePositions();
unsigned int observerFlags = Revalidate; unsigned int observerFlags = Revalidate;
@ -735,6 +741,7 @@ namespace Anabatic {
cdebug_log(149,0) << "Updated: " << this << endl; cdebug_log(149,0) << "Updated: " << this << endl;
cdebug_tabw(149,-1); cdebug_tabw(149,-1);
DebugSession::close();
} }
@ -770,16 +777,16 @@ namespace Anabatic {
if (getFlags() & SegSourceTop ) cap = getViaToTopCap (depth); if (getFlags() & SegSourceTop ) cap = getViaToTopCap (depth);
else if (getFlags() & SegSourceBottom) cap = getViaToBottomCap(depth); else if (getFlags() & SegSourceBottom) cap = getViaToBottomCap(depth);
else cap = getViaToSameCap (depth); else cap = getViaToSameCap (depth);
cdebug_log(150,0) << "getExtensionCap(): (source) flags:" << getFlags() // cdebug_log(150,0) << "getExtensionCap(): (source) flags:" << getFlags()
<< " VIA cap:" << DbU::getValueString(cap) // << " VIA cap:" << DbU::getValueString(cap)
<< " t:" << (getFlags() & SegSourceBottom) // << " t:" << (getFlags() & SegSourceBottom)
<< " b:" << (getFlags() & SegSourceTop) // << " b:" << (getFlags() & SegSourceTop)
<< endl; // << endl;
if (not (flags & Flags::NoSegExt)) { 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) { if (-getDuSource() > cap) {
cap = -getDuSource(); 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); if (getFlags() & SegTargetTop ) cap = getViaToTopCap (depth);
else if (getFlags() & SegTargetBottom) cap = getViaToBottomCap(depth); else if (getFlags() & SegTargetBottom) cap = getViaToBottomCap(depth);
else cap = getViaToSameCap (depth); else cap = getViaToSameCap (depth);
cdebug_log(150,0) << "getExtensionCap(): (target) flags:" << getFlags() // cdebug_log(150,0) << "getExtensionCap(): (target) flags:" << getFlags()
<< " VIA cap:" << DbU::getValueString(cap) // << " VIA cap:" << DbU::getValueString(cap)
<< " t:" << (getFlags() & SegSourceBottom) // << " t:" << (getFlags() & SegSourceBottom)
<< " b:" << (getFlags() & SegSourceTop) // << " b:" << (getFlags() & SegSourceTop)
<< endl; // << endl;
if (not (flags & Flags::NoSegExt)) { 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) { if (getDuTarget() > cap) {
cap = getDuTarget(); 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 not (flags & Flags::NoMinLength)
// and (flags & Flags::Target) // and (flags & Flags::Target)
// and (getMinimalLength(depth) != 0.0) // and (getMinimalLength(depth) != 0.0)
// and isMiddleStack() ) { // and isNearMinArea() ) {
// DbU::Unit realLength = getExtensionCap( Flags::Source|Flags::LayerCapOnly|Flags::NoMinLength ) // DbU::Unit realLength = getExtensionCap( Flags::Source|Flags::LayerCapOnly|Flags::NoMinLength )
// + getAnchoredLength(); // + getAnchoredLength();
// if (realLength + cap < getMinimalLength(depth)) { // if (realLength + cap < getMinimalLength(depth)) {
@ -901,12 +908,12 @@ namespace Anabatic {
sourceAxis = getSourceU(); sourceAxis = getSourceU();
targetAxis = getTargetU(); targetAxis = getTargetU();
if (not isNotAligned()) { //if (not isNotAligned()) {
for( AutoSegment* aligned : const_cast<AutoSegment*>(this)->getAligneds() ) { for( AutoSegment* aligned : const_cast<AutoSegment*>(this)->getAligneds() ) {
sourceAxis = std::min( sourceAxis, aligned->getSourceU() ); 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 ) AutoSegment* AutoSegment::canonize ( Flags flags )
{ {
cdebug_log(149,0) << "canonize() - " << this << endl; cdebug_log(149,0) << "canonize() - " << this << endl;
if (Session::getAnabatic()->isCanonizeDisabled()) return this;
// if (isCanonical() and isGlobal()) { // if (isCanonical() and isGlobal()) {
// cdebug_log(149,0) << "* " << this << " canonical" << endl; // 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; cdebug_log(149,0) << "AutoSegment::isNearMinArea() - " << this << endl;
if (not isCanonical()) return false;
if (isNonPref()) return false; if (isNonPref()) return false;
if (isGlobal()) { if (isGlobal()) {
if (getLength() > getPPitch()) return false; if (getLength() > getPPitch()) return false;
cdebug_log(149,0) << "| Considering this global anyway because it is too short. " << endl; 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 sourceAxis = 0;
DbU::Unit targetAxis = 0; DbU::Unit targetAxis = 0;
getEndAxes( sourceAxis, targetAxis ); getEndAxes( sourceAxis, targetAxis );
@ -1665,43 +1636,38 @@ namespace Anabatic {
cdebug_log(149,0) << "| Canonical axis length superior to P-Pitch " << this << endl; cdebug_log(149,0) << "| Canonical axis length superior to P-Pitch " << this << endl;
return false; return false;
} }
cdebug_log(149,0) << " Middle stack or terminal bound." << endl; cdebug_log(149,0) << " Length below P-Pitch." << endl;
return true; return true;
} }
bool AutoSegment::isUnderMinLength () const void AutoSegment::expandToMinLength ( Interval span )
{ {
return false; if (not isNearMinArea()) return;
// cdebug_log(149,0) << "AutoSegment::isUnderMinLength() - " << this << endl; DebugSession::open( getNet(), 149, 160 );
// 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;
cdebug_log(149,1) << "AutoSegment::expandToMinLength() " << this << endl; cdebug_log(149,1) << "AutoSegment::expandToMinLength() " << this << endl;
cdebug_log(149,0) << "In span=" << span << endl; cdebug_log(149,0) << "In span=" << span << endl;
cdebug_log(149,0) << "Before: [" << DbU::getValueString(getSourceU() - getExtensionCap( Flags::Source|Flags::LayerCapOnly )) cdebug_log(149,0) << "Before: [" << DbU::getValueString(getSourceU() - getExtensionCap( Flags::Source|Flags::LayerCapOnly ))
<< " " << DbU::getValueString(getTargetU() + getExtensionCap( Flags::Target|Flags::LayerCapOnly )) << " " << DbU::getValueString(getTargetU() + getExtensionCap( Flags::Target|Flags::LayerCapOnly ))
<< "]" << endl; << "]" << endl;
DbU::Unit sourceCap = getExtensionCap( Flags::Source|Flags::NoSegExt|Flags::LayerCapOnly ); DbU::Unit halfMinSpacing = getLayer()->getMinimalSpacing() / 2;
DbU::Unit targetCap = getExtensionCap( Flags::Target|Flags::NoSegExt|Flags::LayerCapOnly ); DbU::Unit sourceCap = getExtensionCap( Flags::Source|Flags::LayerCapOnly );
DbU::Unit segMinLength = getAnchoredLength() + sourceCap + targetCap; DbU::Unit targetCap = getExtensionCap( Flags::Target|Flags::LayerCapOnly );
DbU::Unit techMinLength = getMinimalLength( Session::getLayerDepth( getLayer() )); DbU::Unit segMinLength = getAnchoredLength() + sourceCap + targetCap;
if (techMinLength <= segMinLength) { DbU::Unit techMinLength = getMinimalLength( Session::getLayerDepth( getLayer() ));
cdebug_log(149,0) << "Above minimal length (" << DbU::getValueString(segMinLength) cdebug_log(149,0) << "Minimal length " << DbU::getValueString(techMinLength)
<< " >= " << DbU::getValueString(techMinLength) << ")" << endl; << " vs. current length " << DbU::getValueString(segMinLength) << endl;
if (segMinLength >= techMinLength) {
if (segMinLength == techMinLength)
setFlags( SegAtMinArea );
cdebug_tabw(149,-1); 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 oneGrid = DbU::fromGrid( 1 );
DbU::Unit targetExpand = (techMinLength - segMinLength) / 2 + targetCap; DbU::Unit targetExpand = (techMinLength - segMinLength) / 2 + targetCap;
@ -1711,11 +1677,20 @@ namespace Anabatic {
if (sourceExpand % oneGrid) if (sourceExpand % oneGrid)
sourceExpand -= oneGrid + sourceExpand % oneGrid; sourceExpand -= oneGrid + sourceExpand % oneGrid;
if (not span.isEmpty()) { if (not span.isEmpty()) {
DbU::Unit shiftLeft = span.getVMax() - (getTargetU() + targetExpand); DbU::Unit shiftLeft = span.getVMax() - (getTargetU() + targetExpand + halfMinSpacing);
if (shiftLeft < 0) { if (shiftLeft < 0) {
if (targetExpand + shiftLeft < targetCap)
shiftLeft = targetCap - targetExpand;
targetExpand += shiftLeft; targetExpand += shiftLeft;
sourceExpand += 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 ); setDuSource( sourceExpand );
setDuTarget( targetExpand ); setDuTarget( targetExpand );
@ -1726,18 +1701,75 @@ namespace Anabatic {
<< "] expand:" << DbU::getValueString(techMinLength - segMinLength)<< endl; << "] expand:" << DbU::getValueString(techMinLength - segMinLength)<< endl;
setFlags( SegAtMinArea ); setFlags( SegAtMinArea );
cdebug_tabw(149,-1); 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; 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;
}
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 ); setDuSource( 0 );
setDuTarget( 0 ); cdebug_log(149,0) << "Shrink target of " << DbU::getValueString(shrink) << endl;
unsetFlags( SegAtMinArea ); margin = duTarget - targetCap;
return true; 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(); DbU::Unit length = getAnchoredLength();
if (isGlobal() and (length > getPPitch())) return false; if (isGlobal() and (length > getPPitch())) return false;
if (isDrag() or isFixed()) return false; if (isDrag()) return false;
if (not isSpinTopOrBottom()) 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* source = getAutoSource();
AutoContact* target = getAutoTarget(); 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) << " source:" << source->isHTee() << "+" << source->isVTee() << endl;
cdebug_log(159,0) << " target:" << target->isHTee() << "+" << target->isVTee() << endl; cdebug_log(159,0) << " target:" << target->isHTee() << "+" << target->isVTee() << endl;
@ -2302,6 +2342,8 @@ namespace Anabatic {
setWidth( hside ); setWidth( hside );
source->setSizes( hside, vside ); source->setSizes( hside, vside );
target->setSizes( hside, vside ); target->setSizes( hside, vside );
setDuSource( 0 );
setDuTarget( 0 );
success = true; success = true;
} }
@ -2710,6 +2752,7 @@ namespace Anabatic {
state += isFixed () ?" F":" -"; state += isFixed () ?" F":" -";
state += isFixedAxis () ? "X": "-"; state += isFixedAxis () ? "X": "-";
state += isUnsetAxis () ? "u": "-"; state += isUnsetAxis () ? "u": "-";
state += isAtMinArea () ? "a": "-";
state += isStrap () ? "S": "-"; state += isStrap () ? "S": "-";
state += isUnbreakable () ? "U": "-"; state += isUnbreakable () ? "U": "-";
state += isCanonical () ? "C": "-"; state += isCanonical () ? "C": "-";
@ -2770,10 +2813,23 @@ namespace Anabatic {
, Segment* hurricaneSegment , Segment* hurricaneSegment
) )
{ {
Horizontal* horizontal = dynamic_cast<Horizontal*>( hurricaneSegment );
Vertical* vertical = dynamic_cast<Vertical* >( hurricaneSegment );
const Layer* horizontalLayer = Session::getDHorizontalLayer(); const Layer* horizontalLayer = Session::getDHorizontalLayer();
DbU::Unit horizontalWidth = Session::getDHorizontalWidth(); DbU::Unit horizontalWidth = Session::getDHorizontalWidth();
const Layer* verticalLayer = Session::getDVerticalLayer(); const Layer* verticalLayer = Session::getDVerticalLayer();
DbU::Unit verticalWidth = Session::getDVerticalWidth(); 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() ); uint32_t wPitch = NetRoutingExtension::getWPitch( source->getNet() );
if (wPitch > 1) { if (wPitch > 1) {
@ -2788,9 +2844,7 @@ namespace Anabatic {
bool reattachSource = false; bool reattachSource = false;
bool reattachTarget = false; bool reattachTarget = false;
AutoSegment* segment; AutoSegment* segment = NULL;
Horizontal* horizontal = dynamic_cast<Horizontal*>( hurricaneSegment );
Vertical* vertical = dynamic_cast<Vertical* >( hurricaneSegment );
AutoContact* reference = NULL; AutoContact* reference = NULL;
cdebug_log(149,0) << "Source:" << source << endl; cdebug_log(149,0) << "Source:" << source << endl;
@ -3015,6 +3069,7 @@ namespace Anabatic {
if (wPitch > 1) segment->setFlags( SegWide ); if (wPitch > 1) segment->setFlags( SegWide );
if (source->canDrag() or target->canDrag()) segment->setFlags( SegDrag ); if (source->canDrag() or target->canDrag()) segment->setFlags( SegDrag );
if (dir & Flags::UseNonPref) segment->setFlags( SegNonPref ); if (dir & Flags::UseNonPref) segment->setFlags( SegNonPref );
if (dir.contains(Flags::UseNonPref|Flags::OnVSmall)) segment->setFlags( SegOnVSmall );
return segment; return segment;
} }
@ -3162,13 +3217,17 @@ namespace Anabatic {
void AutoSegment::getTopologicalInfos ( AutoSegment* seed void AutoSegment::getTopologicalInfos ( AutoSegment* seed
, vector<AutoSegment*>& aligneds , vector<AutoSegment*>& aligneds
, vector<AutoSegment*>& perpandiculars , vector< tuple<AutoSegment*,Flags> >&
perpandiculars
, DbU::Unit& leftBound , DbU::Unit& leftBound
, DbU::Unit& rightBound , DbU::Unit& rightBound
) )
{ {
cdebug_log(145,1) << "getTopologicalInfos() - " << seed << endl; cdebug_log(145,1) << "getTopologicalInfos() - " << seed << endl;
bool isSourceBoundToChannel = false;
bool isTargetBoundToChannel = false;
leftBound = DbU::Max; leftBound = DbU::Max;
rightBound = DbU::Min; rightBound = DbU::Min;
@ -3223,11 +3282,22 @@ namespace Anabatic {
} }
} else { } else {
cdebug_log(149,0) << "| perpandicular " << currentSegment << endl; 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); cdebug_tabw(145,-1);
} }

View File

@ -16,6 +16,7 @@
#include <algorithm> #include <algorithm>
#include "hurricane/Bug.h" #include "hurricane/Bug.h"
#include "hurricane/Warning.h"
#include "hurricane/ViaLayer.h" #include "hurricane/ViaLayer.h"
#include "hurricane/Vertical.h" #include "hurricane/Vertical.h"
#include "crlcore/RoutingGauge.h" #include "crlcore/RoutingGauge.h"
@ -29,8 +30,10 @@ namespace Anabatic {
using std::min; using std::min;
using std::max; using std::max;
using Hurricane::Error; using std::abs;
using Hurricane::Bug; using Hurricane::Bug;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::ViaLayer; using Hurricane::ViaLayer;
@ -46,8 +49,6 @@ namespace Anabatic {
DbU::Unit AutoVertical::getDuSource () const { return _vertical->getDySource(); } DbU::Unit AutoVertical::getDuSource () const { return _vertical->getDySource(); }
DbU::Unit AutoVertical::getDuTarget () const { return _vertical->getDyTarget(); } DbU::Unit AutoVertical::getDuTarget () const { return _vertical->getDyTarget(); }
Interval AutoVertical::getSpanU () const { return Interval(_vertical->getSourceY(),_vertical->getTargetY()); } Interval AutoVertical::getSpanU () const { return Interval(_vertical->getSourceY(),_vertical->getTargetY()); }
void AutoVertical::setDuSource ( DbU::Unit du ) { _vertical->setDySource(du); }
void AutoVertical::setDuTarget ( DbU::Unit du ) { _vertical->setDyTarget(du); }
string AutoVertical::_getTypeName () const { return "AutoVertical"; } string AutoVertical::_getTypeName () const { return "AutoVertical"; }
@ -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 Interval AutoVertical::getSourceConstraints ( Flags flags ) const
{ {
if (flags & Flags::NativeConstraints) { if (flags & Flags::NativeConstraints) {
@ -382,10 +407,6 @@ namespace Anabatic {
if (_vertical->getTargetY() < _vertical->getSourceY()) { if (_vertical->getTargetY() < _vertical->getSourceY()) {
cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl; cdebug_log(145,0) << "updateOrient() " << this << " (before S/T swap)" << endl;
_vertical->invert(); _vertical->invert();
DbU::Unit duSource = getDuSource();
DbU::Unit duTarget = getDuTarget();
setDuSource( -duTarget );
setDuTarget( -duSource );
unsigned int spinFlags = _flags & SegDepthSpin; unsigned int spinFlags = _flags & SegDepthSpin;
unsetFlags( SegDepthSpin ); unsetFlags( SegDepthSpin );
@ -715,7 +736,7 @@ namespace Anabatic {
bool upLayer = true; bool upLayer = true;
if (Session::getRoutingGauge()->isTwoMetals()) { if (Session::getRoutingGauge()->isTwoMetals()) {
upLayer = (depth == 0); upLayer = (Session::getRoutingGauge()->isVH());
} else if (Session::getRoutingGauge()->isVH()) { } else if (Session::getRoutingGauge()->isVH()) {
upLayer = (depth < 2); upLayer = (depth < 2);
} else { } else {

View File

@ -36,9 +36,10 @@ endif ( CHECK_DETERMINISM )
anabatic/NetBuilderM2.h anabatic/NetBuilderM2.h
anabatic/NetBuilderHV.h anabatic/NetBuilderHV.h
anabatic/NetBuilderVH.h anabatic/NetBuilderVH.h
anabatic/NetBuilderHybridVH.h
anabatic/ChipTools.h anabatic/ChipTools.h
) )
set( pyIncludes ) set( pyIncludes anabatic/PyStyleFlags.h )
set( cpps Constants.cpp set( cpps Constants.cpp
Configuration.cpp Configuration.cpp
Matrix.cpp Matrix.cpp
@ -62,13 +63,15 @@ endif ( CHECK_DETERMINISM )
NetBuilderM2.cpp NetBuilderM2.cpp
NetBuilderHV.cpp NetBuilderHV.cpp
NetBuilderVH.cpp NetBuilderVH.cpp
NetBuilderHybridVH.cpp
ChipTools.cpp ChipTools.cpp
LayerAssign.cpp LayerAssign.cpp
AntennaProtect.cpp AntennaProtect.cpp
PreRouteds.cpp PreRouteds.cpp
AnabaticEngine.cpp AnabaticEngine.cpp
) )
set( pyCpps PyAnabatic.cpp set( pyCpps PyStyleFlags.cpp
PyAnabatic.cpp
) )
set( depLibs ${ETESIAN_LIBRARIES} set( depLibs ${ETESIAN_LIBRARIES}
@ -87,12 +90,13 @@ endif ( CHECK_DETERMINISM )
${QtX_LIBRARIES} ${QtX_LIBRARIES}
${Boost_LIBRARIES} ${Boost_LIBRARIES}
${LIBXML2_LIBRARIES} ${LIBXML2_LIBRARIES}
${Python_LIBRARIES} -lutil ${Python3_LIBRARIES}
-lutil
) )
add_library( anabatic ${cpps} ) add_library( anabatic ${cpps} )
set_target_properties( anabatic PROPERTIES VERSION 1.0 SOVERSION 1 ) set_target_properties( anabatic PROPERTIES VERSION 1.0 SOVERSION 1 )
#target_link_libraries( anabatic ${depLibs} ) target_link_libraries( anabatic ${depLibs} )
add_python_module( "${pyCpps}" add_python_module( "${pyCpps}"
"${pyIncludes}" "${pyIncludes}"

View File

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "Configuration.cpp<anabatic>" -*- // -*- mode: C++; explicit-buffer-name: "Configuration.cpp<anabatic>" -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2018, All Rights Reserved // Copyright (c) Sorbonne Université 2016-2022, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -26,6 +26,7 @@
#include "hurricane/RegularLayer.h" #include "hurricane/RegularLayer.h"
#include "hurricane/RoutingPad.h" #include "hurricane/RoutingPad.h"
#include "hurricane/Pin.h" #include "hurricane/Pin.h"
#include "hurricane/Pad.h"
#include "hurricane/NetExternalComponents.h" #include "hurricane/NetExternalComponents.h"
#include "hurricane/Cell.h" #include "hurricane/Cell.h"
#include "crlcore/Utilities.h" #include "crlcore/Utilities.h"
@ -56,6 +57,7 @@ namespace Anabatic {
using Hurricane::BasicLayer; using Hurricane::BasicLayer;
using Hurricane::RegularLayer; using Hurricane::RegularLayer;
using Hurricane::Segment; using Hurricane::Segment;
using Hurricane::Pad;
using Hurricane::Pin; using Hurricane::Pin;
using Hurricane::Plug; using Hurricane::Plug;
using Hurricane::Path; using Hurricane::Path;
@ -76,6 +78,8 @@ namespace Anabatic {
, _ddepthv (ndepth) , _ddepthv (ndepth)
, _ddepthh (ndepth) , _ddepthh (ndepth)
, _ddepthc (ndepth) , _ddepthc (ndepth)
, _netBuilderStyle (Cfg::getParamString("anabatic.netBuilderStyle","HV,3RL+")->asString() )
, _routingStyle (Cfg::getParamInt ("anabatic.routingStyle" ,StyleFlags::NoStyle)->asInt() )
, _cg (NULL) , _cg (NULL)
, _rg (NULL) , _rg (NULL)
, _extensionCaps () , _extensionCaps ()
@ -97,17 +101,22 @@ namespace Anabatic {
GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() ); GCell::setDisplayMode( Cfg::getParamEnumerate("anabatic.gcell.displayMode", GCell::Boundary)->asInt() );
string gaugeName = Cfg::getParamString("anabatic.routingGauge","sxlib")->asString(); string gaugeName = Cfg::getParamString("anabatic.routingGauge","sxlib")->asString();
if (cg == NULL) { if (not cg)
cg = AllianceFramework::get()->getCellGauge( gaugeName ); cg = AllianceFramework::get()->getCellGauge( gaugeName );
if (cg == NULL) if (not cg) {
throw Error( "AnabaticEngine::Configuration(): Unable to find default cell gauge." ); 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 ); rg = AllianceFramework::get()->getRoutingGauge( gaugeName );
if (rg == NULL) if (not rg)
throw Error( "AnabaticEngine::Configuration(): No routing gauge named \"%s\"", gaugeName.c_str() ); throw Error( "AnabaticEngine::Configuration(): Unable to find routing gauge \"%s\""
} , gaugeName.c_str() );
_cg = cg->getClone(); _cg = cg->getClone();
_rg = rg->getClone(); _rg = rg->getClone();
@ -180,6 +189,8 @@ namespace Anabatic {
, _ddepthv (other._ddepthv) , _ddepthv (other._ddepthv)
, _ddepthh (other._ddepthh) , _ddepthh (other._ddepthh)
, _ddepthc (other._ddepthc) , _ddepthc (other._ddepthc)
, _netBuilderStyle (other._netBuilderStyle)
, _routingStyle (other._routingStyle)
, _cg (NULL) , _cg (NULL)
, _rg (NULL) , _rg (NULL)
, _extensionCaps (other._extensionCaps) , _extensionCaps (other._extensionCaps)
@ -216,6 +227,10 @@ namespace Anabatic {
bool Configuration::isTwoMetals () const bool Configuration::isTwoMetals () const
{ return _rg->isTwoMetals(); } { return _rg->isTwoMetals(); }
bool Configuration::isHybrid () const
{ return _routingStyle & StyleFlags::Hybrid; }
bool Configuration::isHV () const bool Configuration::isHV () const
@ -492,10 +507,12 @@ namespace Anabatic {
break; break;
} }
Component* candidate = dynamic_cast<Segment*>(component); Component* candidate = dynamic_cast<Segment*>( component );
if (not candidate if (not candidate
or (candidate->getLayer()->getMask() != metal1->getMask()) ) or (candidate->getLayer()->getMask() != metal1->getMask()) )
candidate = dynamic_cast<Pin*>(component); candidate = dynamic_cast<Pin*>(component);
if (not candidate)
candidate = dynamic_cast<Pad*>( component );
if (not candidate) continue; if (not candidate) continue;
Box bb = transformation.getBox( candidate->getBoundingBox() ); Box bb = transformation.getBox( candidate->getBoundingBox() );

View File

@ -14,16 +14,22 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#include "hurricane/Error.h"
#include "anabatic/Constants.h" #include "anabatic/Constants.h"
namespace Anabatic { namespace Anabatic {
using std::hex;
using std::string; using std::string;
using std::ostringstream; using std::ostringstream;
using Hurricane::BaseFlags; using Hurricane::BaseFlags;
using Hurricane::Error;
// -------------------------------------------------------------------
// Class : "Anabatic::Flags".
const BaseFlags Flags::NoFlags = 0; const BaseFlags Flags::NoFlags = 0;
// Flags used for both objects states & functions arguments. // Flags used for both objects states & functions arguments.
const BaseFlags Flags::Horizontal = (1L << 0); const BaseFlags Flags::Horizontal = (1L << 0);
@ -53,6 +59,7 @@ namespace Anabatic {
const BaseFlags Flags::DestroyGCell = (1L << 7); const BaseFlags Flags::DestroyGCell = (1L << 7);
const BaseFlags Flags::DestroyBaseContact = (1L << 8); const BaseFlags Flags::DestroyBaseContact = (1L << 8);
const BaseFlags Flags::DestroyBaseSegment = (1L << 9); const BaseFlags Flags::DestroyBaseSegment = (1L << 9);
const BaseFlags Flags::DisableCanonize = (1L << 10);
// Flags for NetDatas objects states only. // Flags for NetDatas objects states only.
const BaseFlags Flags::GlobalFixed = (1L << 5); const BaseFlags Flags::GlobalFixed = (1L << 5);
const BaseFlags Flags::GlobalEstimated = (1L << 6); const BaseFlags Flags::GlobalEstimated = (1L << 6);
@ -125,6 +132,7 @@ namespace Anabatic {
const BaseFlags Flags::NoMinLength = (1L << 37); const BaseFlags Flags::NoMinLength = (1L << 37);
const BaseFlags Flags::NoSegExt = (1L << 38); const BaseFlags Flags::NoSegExt = (1L << 38);
const BaseFlags Flags::NullLength = (1L << 39); const BaseFlags Flags::NullLength = (1L << 39);
const BaseFlags Flags::OnVSmall = (1L << 40);
Flags::~Flags () 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. } // Anabatic namespace.

View File

@ -265,7 +265,7 @@ namespace Anabatic {
} }
} }
if (rp) { if (rp) {
Vertical* v = dynamic_cast<Vertical*>(rp->_getEntityAsSegment()); Vertical* v = dynamic_cast<Vertical*>(rp->_getEntityAs<Segment>());
if (v) { return true; } if (v) { return true; }
} }
} }
@ -285,7 +285,7 @@ namespace Anabatic {
} }
} }
if (rp) { if (rp) {
Horizontal* h = dynamic_cast<Horizontal*>(rp->_getEntityAsSegment()); Horizontal* h = dynamic_cast<Horizontal*>(rp->_getEntityAs<Segment>());
if (h) { return true; } if (h) { return true; }
} }
} }
@ -2873,8 +2873,8 @@ namespace Anabatic {
{ {
cdebug_log(112,0) << "void Dijkstra::_setSourcesGRAData() : " << seed << endl; cdebug_log(112,0) << "void Dijkstra::_setSourcesGRAData() : " << seed << endl;
GCell* gseed = seed->getGCell(); GCell* gseed = seed->getGCell();
Horizontal* h = dynamic_cast<Horizontal*>(rp->_getEntityAsSegment()); Horizontal* h = dynamic_cast<Horizontal*>(rp->_getEntityAs<Segment>());
Vertical* v = dynamic_cast<Vertical*> (rp->_getEntityAsSegment()); Vertical* v = dynamic_cast<Vertical*> (rp->_getEntityAs<Segment>());
if (h) { if (h) {
cdebug_log(112,0) << "case H " << endl; cdebug_log(112,0) << "case H " << endl;
seed->unsetFlags(Vertex::iHorizontal); seed->unsetFlags(Vertex::iHorizontal);

View File

@ -285,7 +285,7 @@ namespace Anabatic {
: Super(anabatic->getCell()) : Super(anabatic->getCell())
, _observable () , _observable ()
, _anabatic (anabatic) , _anabatic (anabatic)
, _flags (Flags::HChannelGCell|Flags::Invalidated) , _flags (Flags::Invalidated)
, _westEdges () , _westEdges ()
, _eastEdges () , _eastEdges ()
, _southEdges () , _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 ) void GCell::addBlockage ( size_t depth, DbU::Unit length )
{ {
if (depth >= _depth) return; if (depth >= _depth) return;
@ -1371,6 +1391,7 @@ namespace Anabatic {
if (found) { if (found) {
cdebug_log(149,0) << "remove " << ac << " from " << this << endl; cdebug_log(149,0) << "remove " << ac << " from " << this << endl;
_contacts.pop_back(); _contacts.pop_back();
_flags |= Flags::Invalidated;
} else { } else {
cerr << Bug("%p:%s do not belong to %s." cerr << Bug("%p:%s do not belong to %s."
,ac->base(),getString(ac).c_str(),_getString().c_str()) << endl; ,ac->base(),getString(ac).c_str(),_getString().c_str()) << endl;
@ -1404,6 +1425,7 @@ namespace Anabatic {
, _getString().c_str(), getString(segment).c_str() ) << endl; , _getString().c_str(), getString(segment).c_str() ) << endl;
_hsegments.erase( _hsegments.begin() + end, _hsegments.end() ); _hsegments.erase( _hsegments.begin() + end, _hsegments.end() );
_flags |= Flags::Invalidated;
} }
@ -1429,6 +1451,7 @@ namespace Anabatic {
, getString(segment).c_str() ) << endl; , getString(segment).c_str() ) << endl;
_vsegments.erase( _vsegments.begin() + end, _vsegments.end() ); _vsegments.erase( _vsegments.begin() + end, _vsegments.end() );
_flags |= Flags::Invalidated;
} }
@ -1528,10 +1551,22 @@ namespace Anabatic {
} }
// Add the blockages. // Add the blockages.
for ( size_t i=0 ; i<_depth ; i++ ) { if (isStdCellRow() or isChannelRow()) {
uLengths2[i] += _blockages[i]; flags().reset( Flags::GoStraight );
if (not i) continue; } else {
if ((float)(_blockages[i] * Session::getPitch(i)) > 0.40*(float)(width*height)) { int contiguousNonSaturated = 0;
for ( size_t i=0 ; i<_depth ; i++ ) {
uLengths2[i] += _blockages[i];
if (Session::getLayerGauge(i)->getType() & Constant::PinOnly)
continue;
if (Session::getLayerGauge(i)->getType() & Constant::PowerSupply)
continue;
if ((float)(_blockages[i] * Session::getPitch(i)) > 0.60*(float)(width*height))
contiguousNonSaturated = 0;
else
contiguousNonSaturated++;
}
if (contiguousNonSaturated < 2) {
flags() |= Flags::GoStraight; flags() |= Flags::GoStraight;
//cerr << "| Set GoStraight on " << this << endl; //cerr << "| Set GoStraight on " << this << endl;
} }
@ -1880,6 +1915,13 @@ namespace Anabatic {
s << "_densities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]"; s << "_densities[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
record->add( getSlot ( s.str(), &_densities[depth] ) ); record->add( getSlot ( s.str(), &_densities[depth] ) );
} }
for ( size_t depth=0 ; depth<_depth ; ++depth ) {
ostringstream s;
const Layer* layer = rg->getRoutingLayer(depth);
s << "_feedthroughs[" << depth << ":" << ((layer) ? layer->getName() : "None") << "]";
record->add( getSlot ( s.str(), &_feedthroughs[depth] ) );
}
return record; return record;
} }

View File

@ -218,9 +218,10 @@ namespace {
cdebug_log(149,0) << "Slacken from: " << rp << endl; cdebug_log(149,0) << "Slacken from: " << rp << endl;
if (rp->getLayer()) { 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; cdebug_log(149,0) << "In METAL2, skiping" << endl;
continue; continue;
}
} }
for ( Component* component : rp->getSlaveComponents() ) { for ( Component* component : rp->getSlaveComponents() ) {
@ -572,9 +573,9 @@ namespace Anabatic {
for ( AutoSegment* horizontal : horizontals ) { for ( AutoSegment* horizontal : horizontals ) {
vector<AutoSegment*> collapseds; vector<AutoSegment*> collapseds;
vector<AutoSegment*> perpandiculars; vector< tuple<AutoSegment*,Flags> > perpandicularsDatas;
vector<AutoSegment*> northBounds; //vector<AutoSegment*> northBounds;
vector<AutoSegment*> southBounds; //vector<AutoSegment*> southBounds;
DbU::Unit leftBound; DbU::Unit leftBound;
DbU::Unit rightBound; DbU::Unit rightBound;
//bool hasNorth = false; //bool hasNorth = false;
@ -582,12 +583,13 @@ namespace Anabatic {
AutoSegment::getTopologicalInfos( horizontal AutoSegment::getTopologicalInfos( horizontal
, collapseds , collapseds
, perpandiculars , perpandicularsDatas
, leftBound , leftBound
, rightBound , rightBound
); );
for ( AutoSegment* perpandicular : perpandiculars ) { for ( auto perpandicularDatas : perpandicularsDatas ) {
AutoSegment* perpandicular = std::get<0>( perpandicularDatas );
if (Session::getLayerDepth(perpandicular->getLayer()) > 2) continue; if (Session::getLayerDepth(perpandicular->getLayer()) > 2) continue;
bool hasGlobal = false; bool hasGlobal = false;
@ -986,7 +988,7 @@ namespace Anabatic {
rps.insert( terminal->getRoutingPad() ); rps.insert( terminal->getRoutingPad() );
} }
} }
if (rps.size() > 8) { if (rps.size() > getConfiguration()->getSaturateRp()) {
GCellRps* gcellRps = new GCellRps ( gcell, this ); GCellRps* gcellRps = new GCellRps ( gcell, this );
gcellRpss.insert( gcellRps ); gcellRpss.insert( gcellRps );

View File

@ -37,6 +37,7 @@
#include "hurricane/Instance.h" #include "hurricane/Instance.h"
#include "hurricane/Vertical.h" #include "hurricane/Vertical.h"
#include "hurricane/Horizontal.h" #include "hurricane/Horizontal.h"
#include "hurricane/Rectilinear.h"
#include "crlcore/AllianceFramework.h" #include "crlcore/AllianceFramework.h"
#include "crlcore/RoutingGauge.h" #include "crlcore/RoutingGauge.h"
#include "anabatic/AutoContactTerminal.h" #include "anabatic/AutoContactTerminal.h"
@ -220,12 +221,13 @@ namespace Anabatic {
using Hurricane::Error; using Hurricane::Error;
using Hurricane::Warning; using Hurricane::Warning;
using Hurricane::Bug; using Hurricane::Bug;
using Hurricane::Rectilinear;
// ------------------------------------------------------------------- // -------------------------------------------------------------------
// Class : "NetBuilder". // Class : "NetBuilder".
void NetBuilder::getPositions ( Component* anchor, Point& source, Point& target ) void NetBuilder::getPositions ( Component* anchor, Point& source, Point& target )
{ {
Segment* segment = dynamic_cast<Segment*>( anchor ); Segment* segment = dynamic_cast<Segment*>( anchor );
@ -366,7 +368,9 @@ namespace Anabatic {
, _routingPadAutoSegments() , _routingPadAutoSegments()
, _toFixSegments () , _toFixSegments ()
, _degree (0) , _degree (0)
, _isTwoMetals (false) , _isStrictChannel (false)
, _sourceFlags (0)
, _flags (0)
{ } { }
@ -377,6 +381,8 @@ namespace Anabatic {
void NetBuilder::clear () void NetBuilder::clear ()
{ {
_connexity.connexity = 0; _connexity.connexity = 0;
_sourceFlags = 0;
_flags = 0;
_topology = 0; _topology = 0;
_net = NULL; _net = NULL;
_netData = NULL; _netData = NULL;
@ -390,8 +396,8 @@ namespace Anabatic {
_norths .clear(); _norths .clear();
_souths .clear(); _souths .clear();
_routingPads .clear(); _routingPads .clear();
_toFixSegments .clear();
_routingPadAutoSegments.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(); clear();
_isTwoMetals = anbt->getConfiguration()->isTwoMetals(); _isStrictChannel = anbt->isChannelStyle() and not anbt->isHybridStyle();
_sourceContact = sourceContact; _sourceFlags = sourceFlags;
_fromHook = fromHook; _sourceContact = sourceContact;
_fromHook = fromHook;
cdebug_log(145,1) << "NetBuilder::setStartHook()" << endl; cdebug_log(145,1) << "NetBuilder::setStartHook()" << endl;
cdebug_log(145,0) << "* _fromHook: " << fromHook << endl; cdebug_log(145,0) << "* _fromHook: " << fromHook << endl;
cdebug_log(145,0) << "* _sourceContact:" << sourceContact << endl; cdebug_log(145,0) << "* _sourceContact:" << sourceContact << endl;
cdebug_log(145,0) << "_isStrictChannel:" << _isStrictChannel << endl;
if (not _fromHook) { if (not _fromHook) {
cdebug_tabw(145,-1); cdebug_tabw(145,-1);
@ -470,12 +481,18 @@ namespace Anabatic {
throw Error( mismatchGCell ); 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()) { if (not _gcell->isMatrix()) {
cdebug_log(145,0) << "* Non-matrix GCell under: " << contact << endl; cdebug_log(145,0) << "* Non-matrix GCell under: " << contact << endl;
cdebug_log(145,0) << "| " << gcell << endl; cdebug_log(145,0) << "| " << gcell << endl;
} }
} else { } else {
if (rp and AllianceFramework::get()->isPad(rp->_getEntityAsComponent()->getCell())) { if (rp and AllianceFramework::get()->isPad(rp->_getEntityAs<Component>()->getCell())) {
_connexity.fields.Pad++; _connexity.fields.Pad++;
} else { } else {
const Layer* layer = anchor->getLayer(); const Layer* layer = anchor->getLayer();
@ -489,11 +506,32 @@ namespace Anabatic {
continue; continue;
} }
if (layer->getMask() == Session::getRoutingLayer(0)->getMask()) _connexity.fields.M1++; // M1 V bool isPin = (dynamic_cast<Pin*>( rp->getOccurrence().getEntity() ) != nullptr);
else if (layer->getMask() == Session::getRoutingLayer(1)->getMask()) _connexity.fields.M2++; // M2 H size_t rpDepth = 0;
else if (layer->getMask() == Session::getRoutingLayer(2)->getMask()) _connexity.fields.M3++; // M3 V for ( size_t depth=0 ; depth < Session::getRoutingGauge()->getDepth() ; ++depth ) {
else if (layer->getMask() == Session::getRoutingLayer(3)->getMask()) _connexity.fields.M2++; // M4 H if (layer->getMask() == Session::getRoutingLayer(depth)->getMask()) {
else if (layer->getMask() == Session::getRoutingLayer(4)->getMask()) _connexity.fields.M3++; // M5 V 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 { else {
cerr << Warning( "Terminal layer \"%s\" of %s is not managed yet (ignored)." cerr << Warning( "Terminal layer \"%s\" of %s is not managed yet (ignored)."
, getString(layer->getName()).c_str() , getString(layer->getName()).c_str()
@ -502,7 +540,7 @@ namespace Anabatic {
//continue; //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; cdebug_log(145,0) << "| Component to connect: " << anchor << endl;
@ -543,7 +581,6 @@ namespace Anabatic {
<< "+" << (int)_connexity.fields.Pad << "+" << (int)_connexity.fields.Pad
<< "] " << _gcell << "] " << _gcell
<< endl; << endl;
return *this; return *this;
} }
@ -553,6 +590,7 @@ namespace Anabatic {
cdebug_log(145,0) << "NetBuilder::push()" << endl; cdebug_log(145,0) << "NetBuilder::push()" << endl;
cdebug_log(145,0) << "* toHook: " << toHook << endl; cdebug_log(145,0) << "* toHook: " << toHook << endl;
cdebug_log(145,0) << "* _fromHook:" << _fromHook << endl; cdebug_log(145,0) << "* _fromHook:" << _fromHook << endl;
cdebug_log(145,0) << "* flags:" << flags << endl;
if (not toHook or (toHook == _fromHook)) { if (not toHook or (toHook == _fromHook)) {
if (contact) { if (contact) {
@ -571,12 +609,60 @@ namespace Anabatic {
Hook* toHookOpposite = getSegmentOppositeHook( toHook ); Hook* toHookOpposite = getSegmentOppositeHook( toHook );
cdebug_log(145,0) << "Pushing (to) " << getString(toHook) << endl; cdebug_log(145,0) << "Pushing (to) " << getString(toHook) << endl;
cdebug_log(145,0) << "Pushing (from) " << contact << endl; cdebug_log(145,0) << "Pushing (from) " << contact << endl;
_forks.push( toHookOpposite, contact ); _forks.push( toHookOpposite, contact, getFlags() );
return true; 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 () void NetBuilder::construct ()
{ {
cdebug_log(145,1) << "NetBuilder::construct() [" << _connexity.connexity << "] in " << _gcell << endl; cdebug_log(145,1) << "NetBuilder::construct() [" << _connexity.connexity << "] in " << _gcell << endl;
@ -589,14 +675,19 @@ namespace Anabatic {
<< "+" << (int)_connexity.fields.Pad << "+" << (int)_connexity.fields.Pad
<< "] " << _gcell << "] " << _gcell
<< endl; << endl;
cdebug_log(145,0) << "getSourceFlags():" << getSourceFlags()
<< " getFlags():" << getFlags() << endl;
if (not isTwoMetals()) { if (not isStrictChannel()) {
_southWestContact = NULL; _southWestContact = NULL;
_northEastContact = NULL; _northEastContact = NULL;
} }
if (not _gcell->isAnalog()) { 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 ) { switch ( _connexity.connexity ) {
case Conn_1G_1Pad: case Conn_1G_1Pad:
@ -635,7 +726,7 @@ namespace Anabatic {
case Conn_2G_6M1: case Conn_2G_6M1:
case Conn_2G_7M1: case Conn_2G_7M1:
case Conn_2G_8M1: 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_1M1: if (_do_xG_1M1()) break;
case Conn_3G_2M1: case Conn_3G_2M1:
case Conn_3G_3M1: case Conn_3G_3M1:
@ -647,7 +738,7 @@ namespace Anabatic {
case Conn_3G_9M1: case Conn_3G_9M1:
case Conn_3G_2M3: case Conn_3G_2M3:
case Conn_3G_3M3: 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_1M1: if (_do_xG_1M1()) break;
case Conn_4G_2M1: case Conn_4G_2M1:
case Conn_4G_3M1: case Conn_4G_3M1:
@ -688,6 +779,7 @@ namespace Anabatic {
case Conn_1G_1PinM3: _do_1G_1PinM3 (); break; case Conn_1G_1PinM3: _do_1G_1PinM3 (); break;
case Conn_2G_1PinM3: case Conn_2G_1PinM3:
case Conn_3G_1PinM3: _do_xG_1PinM3 (); break; 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_1PinM3: _do_1G_1M1_1PinM3(); break;
case Conn_1G_1M1_1PinM2: case Conn_1G_1M1_1PinM2:
case Conn_1G_2M1_1PinM2: case Conn_1G_2M1_1PinM2:
@ -706,7 +798,7 @@ namespace Anabatic {
case Conn_1G_1M1_1M3: _do_1G_xM1 (); break; case Conn_1G_1M1_1M3: _do_1G_xM1 (); break;
case Conn_2G_1M1_1M2: _do_xG_1M1_1M2 (); break; case Conn_2G_1M1_1M2: _do_xG_1M1_1M2 (); break;
default: default:
if (not isTwoMetals()) //if (not isStrictChannel())
throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n" throw Bug( "Unmanaged Configuration [%d] = [%d+%d+%d+%d,%d+%d] %s in %s\n"
" The global routing seems to be defective." " The global routing seems to be defective."
, _connexity.connexity , _connexity.connexity
@ -722,6 +814,9 @@ namespace Anabatic {
_do_xG(); _do_xG();
} }
cdebug_log(145,0) << "SouthWest: " << _southWestContact << endl;
cdebug_log(145,0) << "NorthEast: " << _northEastContact << endl;
if (not _do_globalSegment()) { if (not _do_globalSegment()) {
cdebug_log(145,0) << "No global generated, finish." << endl; cdebug_log(145,0) << "No global generated, finish." << endl;
cdebug_tabw(145,-1); cdebug_tabw(145,-1);
@ -1062,7 +1157,9 @@ namespace Anabatic {
bool NetBuilder::_do_xG_1PinM2 () 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; 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 () bool NetBuilder::_do_3G_xM1_1PinM3 ()
{ {
throw Error ( "%s::_do_3G_xM1_1PinM3() method *not* reimplemented from base class.", getTypeName().c_str() ); 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; vector<RoutingPad*> rpM1s;
Component* rpM2 = NULL; Component* rpM2 = NULL;
forEach ( RoutingPad*, irp, net->getRoutingPads() ) { for ( RoutingPad* rp : net->getRoutingPads() ) {
if (Session::getRoutingGauge()->getLayerDepth(irp->getLayer()) == 1) if ( Session::getRoutingGauge()->getLayerDepth(rp->getLayer())
rpM2 = *irp; == 1 + Session::getRoutingGauge()->getFirstRoutingLayer())
rpM2 = rp;
else else
rpM1s.push_back( *irp ); rpM1s.push_back( rp );
} }
if ((rpM1s.size() < 2) and not rpM2) { if ((rpM1s.size() < 2) and not rpM2) {
@ -2374,6 +2479,7 @@ namespace Anabatic {
Hook* sourceHook = NULL; Hook* sourceHook = NULL;
AutoContact* sourceContact = NULL; AutoContact* sourceContact = NULL;
uint64_t sourceFlags = NoFlags;
RoutingPads routingPads = net->getRoutingPads(); RoutingPads routingPads = net->getRoutingPads();
size_t degree = routingPads.getSize(); size_t degree = routingPads.getSize();
@ -2412,7 +2518,7 @@ namespace Anabatic {
++connecteds; ++connecteds;
segmentFound = true; segmentFound = true;
setStartHook( anabatic, hook, NULL ); setStartHook( anabatic, hook, NULL, NoFlags );
if (getStateG() == 1) { if (getStateG() == 1) {
if ( (lowestGCell == NULL) or (*getGCell() < *lowestGCell) ) { if ( (lowestGCell == NULL) or (*getGCell() < *lowestGCell) ) {
cdebug_log(145,0) << "Potential starting GCell " << getGCell() << endl; cdebug_log(145,0) << "Potential starting GCell " << getGCell() << endl;
@ -2440,9 +2546,9 @@ namespace Anabatic {
} }
cdebug_tabw(145,-1); 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) << endl;
cdebug_log(145,0) << "--------~~~~=={o}==~~~~--------" << endl; cdebug_log(145,0) << "--------~~~~=={o}==~~~~--------" << endl;
cdebug_log(145,0) << endl; cdebug_log(145,0) << endl;
@ -2451,18 +2557,21 @@ namespace Anabatic {
sourceHook = _forks.getFrom (); sourceHook = _forks.getFrom ();
sourceContact = _forks.getContact(); sourceContact = _forks.getContact();
sourceFlags = _forks.getFlags ();
_forks.pop(); _forks.pop();
while ( sourceHook ) { while ( sourceHook ) {
setStartHook( anabatic, sourceHook, sourceContact ); setStartHook( anabatic, sourceHook, sourceContact, sourceFlags );
construct(); construct();
sourceHook = _forks.getFrom(); sourceHook = _forks.getFrom ();
sourceContact = _forks.getContact(); sourceContact = _forks.getContact();
sourceFlags = _forks.getFlags ();
_forks.pop(); _forks.pop();
cdebug_log(145,0) << "Popping (from) " << sourceHook << endl; cdebug_log(145,0) << "Popping (from) " << sourceHook << endl;
cdebug_log(145,0) << "Popping (to) " << sourceContact << endl; cdebug_log(145,0) << "Popping (to) " << sourceContact << endl;
cdebug_log(145,0) << "Popping (flags) " << sourceFlags << endl;
} }
Session::revalidate(); Session::revalidate();
@ -2473,10 +2582,11 @@ namespace Anabatic {
for ( ; iover != overconstraineds.end() ; ++iover ) { for ( ; iover != overconstraineds.end() ; ++iover ) {
(*iover)->makeDogLeg( (*iover)->getAutoSource()->getGCell(), true ); (*iover)->makeDogLeg( (*iover)->getAutoSource()->getGCell(), true );
} }
Session::revalidate();
#endif #endif
Session::revalidate();
fixSegments(); fixSegments();
Session::revalidate();
cdebug_tabw(145,-1); cdebug_tabw(145,-1);
//DebugSession::close(); //DebugSession::close();

File diff suppressed because it is too large Load Diff

View File

@ -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.

View File

@ -61,6 +61,10 @@ namespace Anabatic {
NetBuilderM2::~NetBuilderM2 () { } NetBuilderM2::~NetBuilderM2 () { }
string NetBuilderM2::getStyle ()
{ return "2RL-"; }
void NetBuilderM2::doRp_AutoContacts ( GCell* gcell void NetBuilderM2::doRp_AutoContacts ( GCell* gcell
, Component* rp , Component* rp
@ -187,7 +191,7 @@ namespace Anabatic {
contact2 ->setFlags( CntFixed ); contact2 ->setFlags( CntFixed );
AutoSegment* fixed = AutoSegment::create( rpContact, contact1, Flags::Vertical ); 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 ); fixed ->setFlags( AutoSegment::SegFixed );
dogleg->setFlags( AutoSegment::SegFixed ); dogleg->setFlags( AutoSegment::SegFixed );

View File

@ -66,6 +66,10 @@ namespace Anabatic {
NetBuilderVH::~NetBuilderVH () { } NetBuilderVH::~NetBuilderVH () { }
string NetBuilderVH::getStyle ()
{ return "VH,3RL+"; }
void NetBuilderVH::doRp_AutoContacts ( GCell* gcell void NetBuilderVH::doRp_AutoContacts ( GCell* gcell
, Component* rp , Component* rp
@ -85,7 +89,6 @@ namespace Anabatic {
size_t rpDepth = Session::getLayerDepth( rp->getLayer() ); size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
Flags direction = Session::getDirection ( rpDepth ); Flags direction = Session::getDirection ( rpDepth );
DbU::Unit viaSide = Session::getViaWidth ( rpDepth ); DbU::Unit viaSide = Session::getViaWidth ( rpDepth );
DbU::Unit gridPosition = 0;
getPositions( rp, sourcePosition, targetPosition ); 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. // 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 ); map<Component*,AutoSegment*>::iterator irp = getRpLookup().find( rp );
if (irp == getRpLookup().end()) { if (irp == getRpLookup().end()) {
AutoContact* sourceProtect = AutoContactTerminal::create( sourceGCell 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) { if (not source and not target) {
source = target = AutoContactTerminal::create( gcell source = target = AutoContactTerminal::create( gcell
, rp , rp
@ -223,28 +182,43 @@ namespace Anabatic {
{ {
cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl; cdebug_log(145,1) << getTypeName() << "::doRp_Access() - flags:" << flags << endl;
AutoContact* rpContactSource; AutoContact* rpContactSource = NULL;
AutoContact* rpContactTarget; AutoContact* rpContactTarget = NULL;
const Layer* rpLayer = rp->getLayer();
size_t rpDepth = Session::getLayerDepth( rp->getLayer() );
flags |= checkRoutingPadSize( rp ); flags |= checkRoutingPadSize( rp );
doRp_AutoContacts( gcell, rp, rpContactSource, rpContactTarget, flags ); doRp_AutoContacts( gcell, rp, rpContactSource, rpContactTarget, flags );
if (not (flags & (HAccess|HAccessEW))) { if (rpDepth % 2 == 0) { // RP should be vertical (M1, M3).
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); if (not (flags & (HAccess|HAccessEW))) {
AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(1) ); AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical ); AutoContact* subContact2 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
AutoSegment::create( subContact1, subContact2, Flags::Horizontal ); AutoSegment::create( rpContactSource, subContact1, Flags::Vertical , rpDepth+2 );
rpContactSource = subContact2; AutoSegment::create( subContact1, subContact2, Flags::Horizontal, rpDepth+1 );
} else { rpContactSource = subContact2;
if (flags & VSmall) { } else {
if (flags & VSmall) {
AutoContact* subContact1 = NULL;
if (flags & HAccessEW)
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
else
subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
AutoSegment::create( rpContactSource, subContact1, Flags::Vertical );
rpContactSource = subContact1;
}
}
} else { // RP should be horizontal (M2).
if (flags & (HAccess|HAccessEW)) {
AutoContact* subContact1 = NULL; AutoContact* subContact1 = NULL;
if (flags & HAccessEW) if (flags & HAccessEW)
subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(1) ); subContact1 = AutoContactHTee::create( gcell, rp->getNet(), Session::getContactLayer(rpDepth+1) );
else 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 ); AutoSegment::create( rpContactSource, subContact1, Flags::Vertical, rpDepth+1 );
rpContactSource = subContact1; rpContactSource = subContact1;
} }
} }

View File

@ -83,6 +83,7 @@ namespace Anabatic {
if (net->getType() == Net::Type::GROUND) continue; if (net->getType() == Net::Type::GROUND) continue;
// Don't skip the clock. // Don't skip the clock.
vector<Pin*> pins;
vector<Segment*> segments; vector<Segment*> segments;
vector<Contact*> contacts; vector<Contact*> contacts;
@ -92,7 +93,11 @@ namespace Anabatic {
size_t rpCount = 0; size_t rpCount = 0;
for( Component* component : net->getComponents() ) { 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; if (dynamic_cast<Plug*>(component)) continue;
const RegularLayer* layer = dynamic_cast<const RegularLayer*>(component->getLayer()); const RegularLayer* layer = dynamic_cast<const RegularLayer*>(component->getLayer());
@ -139,36 +144,51 @@ namespace Anabatic {
isFixed = true; isFixed = true;
} }
} else { } else {
Contact* contact = dynamic_cast<Contact*>(component); Pin* pin = dynamic_cast<Pin*>(component);
if (contact) { if (pin) {
if (not ab.contains(contact->getCenter())) continue; //cerr << "| " << pin << endl;
if (not ab.intersect(pin->getBoundingBox())) continue;
if (Session::isGLayer(component->getLayer())) { pins.push_back( pin );
isManualGlobalRouted = true;
} else {
isManualGlobalRouted = true;
contacts.push_back( contact );
if ( (contact->getWidth () != Session::getViaWidth(contact->getLayer()))
or (contact->getHeight() != Session::getViaWidth(contact->getLayer()))
or (contact->getLayer () == Session::getContactLayer(0)) )
isFixed = true;
}
} else { } else {
RoutingPad* rp = dynamic_cast<RoutingPad*>(component); Contact* contact = dynamic_cast<Contact*>(component);
if (rp) { if (contact) {
++rpCount; if (not ab.contains(contact->getCenter())) continue;
if (Session::isGLayer(component->getLayer())) {
isManualGlobalRouted = true;
} else {
isManualGlobalRouted = true;
contacts.push_back( contact );
if ( (contact->getWidth () != Session::getViaWidth(contact->getLayer()))
or (contact->getHeight() != Session::getViaWidth(contact->getLayer()))
or (contact->getLayer () == Session::getContactLayer(0)) )
isFixed = true;
}
} else { } else {
// Plug* plug = dynamic_cast<Plug*>(component); RoutingPad* rp = dynamic_cast<RoutingPad*>(component);
// if (plug) { if (rp) {
// cerr << "buildPreRouteds(): " << plug << endl; ++rpCount;
// ++rpCount; } else {
// } // Plug* plug = dynamic_cast<Plug*>(component);
// if (plug) {
// cerr << "buildPreRouteds(): " << plug << endl;
// ++rpCount;
// }
}
} }
} }
} }
} }
} }
// cerr << net << " deepNet:" << net->isDeepNet()
// << " pins:" << pins.size()
// << " segments:" << segments.size() << endl;
if (not net->isDeepNet() and (pins.size() >= 1) and (segments.size() < 2)) {
++toBeRouteds;
continue;
}
if ( (not isFixed) if ( (not isFixed)
and (not isManualGlobalRouted) and (not isManualGlobalRouted)
and (not isManualDetailRouted) and (not isManualDetailRouted)
@ -213,6 +233,10 @@ namespace Anabatic {
for ( auto segment : segments ) { for ( auto segment : segments ) {
AutoContact* source = Session::lookup( dynamic_cast<Contact*>( segment->getSource() )); AutoContact* source = Session::lookup( dynamic_cast<Contact*>( segment->getSource() ));
AutoContact* target = Session::lookup( dynamic_cast<Contact*>( segment->getTarget() )); 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* autoSegment = AutoSegment::create( source, target, segment );
autoSegment->setFlags( AutoSegment::SegUserDefined|AutoSegment::SegAxisSet ); autoSegment->setFlags( AutoSegment::SegUserDefined|AutoSegment::SegAxisSet );
} }

View File

@ -16,7 +16,7 @@
#include "hurricane/isobar/PyHurricane.h" #include "hurricane/isobar/PyHurricane.h"
#include "hurricane/isobar/PyCell.h" #include "hurricane/isobar/PyCell.h"
#include "anabatic/Constants.h" #include "anabatic/PyStyleFlags.h"
namespace Anabatic { namespace Anabatic {
@ -76,6 +76,10 @@ extern "C" {
{ {
cdebug_log(32,0) << "PyInit_Anabatic()" << endl; cdebug_log(32,0) << "PyInit_Anabatic()" << endl;
PyStyleFlags_LinkPyType();
PYTYPE_READY( StyleFlags );
PyObject* module = PyModule_Create( &PyAnabatic_ModuleDef ); PyObject* module = PyModule_Create( &PyAnabatic_ModuleDef );
if (module == NULL) { if (module == NULL) {
cerr << "[ERROR]\n" cerr << "[ERROR]\n"
@ -83,6 +87,9 @@ extern "C" {
return NULL; return NULL;
} }
Py_INCREF( &PyTypeStyleFlags );
PyModule_AddObject( module, "StyleFlags", (PyObject*)&PyTypeStyleFlags );
PyObject* dictionnary = PyModule_GetDict(module); PyObject* dictionnary = PyModule_GetDict(module);
PyObject* constant; PyObject* constant;
@ -93,6 +100,7 @@ extern "C" {
LoadObjectConstant( dictionnary,EngineLayerAssignNoGlobalM2V,"EngineLayerAssignNoGlobalM2V" ); LoadObjectConstant( dictionnary,EngineLayerAssignNoGlobalM2V,"EngineLayerAssignNoGlobalM2V" );
LoadObjectConstant( dictionnary,EngineNoNetLayerAssign ,"EngineNoNetLayerAssign" ); LoadObjectConstant( dictionnary,EngineNoNetLayerAssign ,"EngineNoNetLayerAssign" );
PyStyleFlags_postModuleInit();
return module; return module;
} }

View File

@ -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.

View File

@ -215,6 +215,7 @@ namespace Anabatic {
{ {
cdebug_log(145,1) << "Anabatic::Session::_revalidateTopology()" << endl; cdebug_log(145,1) << "Anabatic::Session::_revalidateTopology()" << endl;
_anabatic->disableCanonize();
for ( Net* net : _netInvalidateds ) { for ( Net* net : _netInvalidateds ) {
cdebug_log(145,0) << "Anabatic::Session::_revalidateTopology(Net*)" << net << endl; cdebug_log(145,0) << "Anabatic::Session::_revalidateTopology(Net*)" << net << endl;
_anabatic->updateNetTopology ( net ); _anabatic->updateNetTopology ( net );
@ -222,6 +223,7 @@ namespace Anabatic {
_anabatic->_computeNetOptimals ( net ); _anabatic->_computeNetOptimals ( net );
//_anabatic->_computeNetTerminals ( net ); //_anabatic->_computeNetTerminals ( net );
} }
_anabatic->enableCanonize();
_canonize (); _canonize ();
AutoSegment* segment = NULL; AutoSegment* segment = NULL;
@ -410,14 +412,25 @@ namespace Anabatic {
if (y < constraint.getYMin()) y += lg->getPitch(); if (y < constraint.getYMin()) y += lg->getPitch();
if (y > constraint.getYMax()) y -= lg->getPitch(); if (y > constraint.getYMax()) y -= lg->getPitch();
y = std::max( y, constraint.getYMin() );
y = std::min( y, constraint.getYMax() );
return Point(x,y); return Point(x,y);
} }
StyleFlags Session::getRoutingStyle ()
{ return get("getRoutingStyle()")->_anabatic->getRoutingStyle(); }
bool Session::isInDemoMode () bool Session::isInDemoMode ()
{ return get("isInDemoMode()")->_anabatic->isInDemoMode(); } { return get("isInDemoMode()")->_anabatic->isInDemoMode(); }
bool Session::isChannelStyle ()
{ return get("isChannelStyle()")->_anabatic->isChannelStyle(); }
float Session::getSaturateRatio () float Session::getSaturateRatio ()
{ return get("getSaturateRatio()")->_anabatic->getSaturateRatio(); } { return get("getSaturateRatio()")->_anabatic->getSaturateRatio(); }

View File

@ -1,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

View File

@ -45,6 +45,7 @@ namespace Anabatic {
using Hurricane::NetRoutingState; using Hurricane::NetRoutingState;
using CRL::ToolEngine; using CRL::ToolEngine;
class NetBuilder;
class AnabaticEngine; class AnabaticEngine;
@ -191,23 +192,33 @@ namespace Anabatic {
class AnabaticEngine : public ToolEngine { class AnabaticEngine : public ToolEngine {
public: public:
enum DensityMode { AverageHVDensity=1 // Average between all densities. static const uint32_t DigitalMode = (1 << 0);
, AverageHDensity =2 // Average between all H densities. static const uint32_t AnalogMode = (1 << 1);
, AverageVDensity =3 // Average between all V densities. static const uint32_t MixedMode = (1 << 2);
, MaxHVDensity =4 // Maximum between average H and average V. static const uint32_t AverageHVDensity = 1; // Average between all densities.
, MaxVDensity =5 // Maximum of V densities. static const uint32_t AverageHDensity = 2; // Average between all H densities.
, MaxHDensity =6 // Maximum of H densities. static const uint32_t AverageVDensity = 3; // Average between all V densities.
, MaxDensity =7 // Maximum of H & 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: public:
typedef ToolEngine Super; typedef ToolEngine Super;
public: public:
static AnabaticEngine* create ( Cell* ); static AnabaticEngine* create ( Cell* );
static AnabaticEngine* get ( const Cell* ); static AnabaticEngine* get ( const Cell* );
inline bool isCanonizeDisabled () const;
inline bool isDigitalMode () const;
inline bool isAnalogMode () const;
inline bool isMixedMode () const;
inline bool isChannelStyle () const;
inline bool isHybridStyle () const;
static const Name& staticGetName (); static const Name& staticGetName ();
virtual const Name& getName () const; virtual const Name& getName () const;
virtual Configuration* getConfiguration (); virtual Configuration* getConfiguration ();
virtual const Configuration* getConfiguration () const; virtual const Configuration* getConfiguration () const;
inline std::string getNetBuilderStyle () const;
inline StyleFlags getRoutingStyle () const;
inline uint64_t getDensityMode () const; inline uint64_t getDensityMode () const;
inline CellViewer* getViewer () const; inline CellViewer* getViewer () const;
inline void setViewer ( CellViewer* ); inline void setViewer ( CellViewer* );
@ -227,6 +238,8 @@ namespace Anabatic {
virtual void openSession (); virtual void openSession ();
inline void setState ( EngineState state ); inline void setState ( EngineState state );
inline void setDensityMode ( uint64_t ); inline void setDensityMode ( uint64_t );
inline void disableCanonize ();
inline void enableCanonize ();
inline void addOv ( Edge* ); inline void addOv ( Edge* );
inline void removeOv ( Edge* ); inline void removeOv ( Edge* );
inline const NetDatas& getNetDatas () const; inline const NetDatas& getNetDatas () const;
@ -266,6 +279,9 @@ namespace Anabatic {
void invalidateRoutingPads (); void invalidateRoutingPads ();
void updateDensity (); void updateDensity ();
size_t checkGCellDensities (); size_t checkGCellDensities ();
void setupNetBuilder ();
inline void setRoutingMode ( uint32_t );
inline void resetRoutingMode ( uint32_t );
inline void setGlobalThreshold ( DbU::Unit ); inline void setGlobalThreshold ( DbU::Unit );
inline void setSaturateRatio ( float ); inline void setSaturateRatio ( float );
inline void setSaturateRp ( size_t ); inline void setSaturateRp ( size_t );
@ -331,12 +347,15 @@ namespace Anabatic {
virtual void _postCreate (); virtual void _postCreate ();
virtual void _preDestroy (); virtual void _preDestroy ();
void _gutAnabatic (); void _gutAnabatic ();
virtual Configuration* _createConfiguration ();
private: private:
AnabaticEngine ( const AnabaticEngine& ); AnabaticEngine ( const AnabaticEngine& );
AnabaticEngine& operator= ( const AnabaticEngine& ); AnabaticEngine& operator= ( const AnabaticEngine& );
private: private:
static Name _toolName; static Name _toolName;
protected:
Configuration* _configuration; Configuration* _configuration;
private:
ChipTools _chipTools; ChipTools _chipTools;
EngineState _state; EngineState _state;
Matrix _matrix; Matrix _matrix;
@ -347,6 +366,7 @@ namespace Anabatic {
CellViewer* _viewer; CellViewer* _viewer;
Flags _flags; Flags _flags;
int _stamp; int _stamp;
uint32_t _routingMode;
uint64_t _densityMode; uint64_t _densityMode;
AutoSegmentLut _autoSegmentLut; AutoSegmentLut _autoSegmentLut;
AutoContactLut _autoContactLut; AutoContactLut _autoContactLut;
@ -356,49 +376,61 @@ namespace Anabatic {
}; };
inline EngineState AnabaticEngine::getState () const { return _state; } inline bool AnabaticEngine::isDigitalMode () const { return (_routingMode & DigitalMode); };
inline void AnabaticEngine::setState ( EngineState state ) { _state = state; } inline bool AnabaticEngine::isAnalogMode () const { return (_routingMode & AnalogMode); };
inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; } inline bool AnabaticEngine::isMixedMode () const { return (_routingMode & MixedMode); };
inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; } inline bool AnabaticEngine::isChannelStyle () const { return (_configuration->getRoutingStyle() & StyleFlags::Channel); };
inline const Matrix* AnabaticEngine::getMatrix () const { return &_matrix; } inline bool AnabaticEngine::isHybridStyle () const { return (_configuration->getRoutingStyle() & StyleFlags::Hybrid); };
inline const vector<GCell*>& AnabaticEngine::getGCells () const { return _gcells; } inline void AnabaticEngine::setRoutingMode ( uint32_t mode ) { _routingMode |= mode; };
inline const vector<Edge*>& AnabaticEngine::getOvEdges () const { return _ovEdges; } inline void AnabaticEngine::resetRoutingMode ( uint32_t mode ) { _routingMode &= ~mode; };
inline GCell* AnabaticEngine::getSouthWestGCell () const { return _gcells[0]; } inline EngineState AnabaticEngine::getState () const { return _state; }
inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); } inline void AnabaticEngine::setState ( EngineState state ) { _state = state; }
inline GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); } inline CellViewer* AnabaticEngine::getViewer () const { return _viewer; }
inline GCellsUnder AnabaticEngine::getGCellsUnder ( Segment* s ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,s) ); } inline void AnabaticEngine::setViewer ( CellViewer* viewer ) { _viewer=viewer; }
inline GCellsUnder AnabaticEngine::getGCellsUnder ( Point source, Point target ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,source,target) ); } inline const Matrix* AnabaticEngine::getMatrix () const { return &_matrix; }
inline Edges AnabaticEngine::getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags ) const { return new Path_Edges(source,target,pathFlags); } inline const vector<GCell*>& AnabaticEngine::getGCells () const { return _gcells; }
inline uint64_t AnabaticEngine::getDensityMode () const { return _densityMode; } inline const vector<Edge*>& AnabaticEngine::getOvEdges () const { return _ovEdges; }
inline void AnabaticEngine::setDensityMode ( uint64_t mode ) { _densityMode=mode; } inline GCell* AnabaticEngine::getSouthWestGCell () const { return _gcells[0]; }
inline void AnabaticEngine::setBlockageNet ( Net* net ) { _blockageNet = net; } inline GCell* AnabaticEngine::getGCellUnder ( DbU::Unit x, DbU::Unit y ) const { return _matrix.getUnder(x,y); }
inline const AutoContactLut& AnabaticEngine::_getAutoContactLut () const { return _autoContactLut; } inline GCell* AnabaticEngine::getGCellUnder ( Point p ) const { return _matrix.getUnder(p); }
inline const AutoSegmentLut& AnabaticEngine::_getAutoSegmentLut () const { return _autoSegmentLut; } inline GCellsUnder AnabaticEngine::getGCellsUnder ( Segment* s ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,s) ); }
inline const Flags& AnabaticEngine::flags () const { return _flags; } inline GCellsUnder AnabaticEngine::getGCellsUnder ( Point source, Point target ) const { return std::shared_ptr<RawGCellsUnder>( new RawGCellsUnder(this,source,target) ); }
inline Flags& AnabaticEngine::flags () { return _flags; } inline Edges AnabaticEngine::getEdgesUnderPath ( GCell* source, GCell* target, Flags pathFlags ) const { return new Path_Edges(source,target,pathFlags); }
inline bool AnabaticEngine::doDestroyBaseContact () const { return _flags & Flags::DestroyBaseContact; } inline uint64_t AnabaticEngine::getDensityMode () const { return _densityMode; }
inline bool AnabaticEngine::doDestroyBaseSegment () const { return _flags & Flags::DestroyBaseSegment; } inline void AnabaticEngine::setDensityMode ( uint64_t mode ) { _densityMode=mode; }
inline bool AnabaticEngine::doDestroyTool () const { return _state >= EngineGutted; } inline void AnabaticEngine::setBlockageNet ( Net* net ) { _blockageNet = net; }
inline bool AnabaticEngine::doWarnOnGCellOverload () const { return _flags & Flags::WarnOnGCellOverload; } inline const AutoContactLut& AnabaticEngine::_getAutoContactLut () const { return _autoContactLut; }
inline bool AnabaticEngine::isInDemoMode () const { return _flags & Flags::DemoMode; } inline const AutoSegmentLut& AnabaticEngine::_getAutoSegmentLut () const { return _autoSegmentLut; }
inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); } inline const Flags& AnabaticEngine::flags () const { return _flags; }
inline DbU::Unit AnabaticEngine::getAntennaGateMaxWL () const { return getConfiguration()->getAntennaGateMaxWL(); } inline Flags& AnabaticEngine::flags () { return _flags; }
inline DbU::Unit AnabaticEngine::getAntennaDiodeMaxWL () const { return getConfiguration()->getAntennaDiodeMaxWL(); } inline bool AnabaticEngine::doDestroyBaseContact () const { return _flags & Flags::DestroyBaseContact; }
inline DbU::Unit AnabaticEngine::getGlobalThreshold () const { return _configuration->getGlobalThreshold(); } inline bool AnabaticEngine::doDestroyBaseSegment () const { return _flags & Flags::DestroyBaseSegment; }
inline float AnabaticEngine::getSaturateRatio () const { return _configuration->getSaturateRatio(); } inline bool AnabaticEngine::doDestroyTool () const { return _state >= EngineGutted; }
inline size_t AnabaticEngine::getSaturateRp () const { return _configuration->getSaturateRp(); } inline bool AnabaticEngine::doWarnOnGCellOverload () const { return _flags & Flags::WarnOnGCellOverload; }
inline void AnabaticEngine::setSaturateRatio ( float ratio ) { _configuration->setSaturateRatio(ratio); } inline bool AnabaticEngine::isCanonizeDisabled () const { return _flags & Flags::DisableCanonize; }
inline void AnabaticEngine::setSaturateRp ( size_t threshold ) { _configuration->setSaturateRp(threshold); } inline bool AnabaticEngine::isInDemoMode () const { return _flags & Flags::DemoMode; }
inline Cell* AnabaticEngine::getDiodeCell () const { return _diodeCell; } inline bool AnabaticEngine::isChip () const { return _chipTools.isChip(); }
inline Net* AnabaticEngine::getBlockageNet () const { return _blockageNet; } inline std::string AnabaticEngine::getNetBuilderStyle () const { return _configuration->getNetBuilderStyle(); }
inline const ChipTools& AnabaticEngine::getChipTools () const { return _chipTools; } inline StyleFlags AnabaticEngine::getRoutingStyle () const { return _configuration->getRoutingStyle(); }
inline const vector<NetData*>& AnabaticEngine::getNetOrdering () const { return _netOrdering; } inline DbU::Unit AnabaticEngine::getAntennaGateMaxWL () const { return _configuration->getAntennaGateMaxWL(); }
inline void AnabaticEngine::setGlobalThreshold ( DbU::Unit threshold ) { _configuration->setGlobalThreshold(threshold); } inline DbU::Unit AnabaticEngine::getAntennaDiodeMaxWL () const { return _configuration->getAntennaDiodeMaxWL(); }
inline const NetDatas& AnabaticEngine::getNetDatas () const { return _netDatas; } inline DbU::Unit AnabaticEngine::getGlobalThreshold () const { return _configuration->getGlobalThreshold(); }
inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); } inline float AnabaticEngine::getSaturateRatio () const { return _configuration->getSaturateRatio(); }
inline void AnabaticEngine::_resizeMatrix () { _matrix.resize( getCell(), getGCells() ); } inline size_t AnabaticEngine::getSaturateRp () const { return _configuration->getSaturateRp(); }
inline void AnabaticEngine::_updateGContacts ( Flags flags ) { for ( GCell* gcell : getGCells() ) gcell->updateGContacts(flags); } inline void AnabaticEngine::setSaturateRatio ( float ratio ) { _configuration->setSaturateRatio(ratio); }
inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; } inline void AnabaticEngine::setSaturateRp ( size_t threshold ) { _configuration->setSaturateRp(threshold); }
inline Cell* AnabaticEngine::getDiodeCell () const { return _diodeCell; }
inline Net* AnabaticEngine::getBlockageNet () const { return _blockageNet; }
inline const ChipTools& AnabaticEngine::getChipTools () const { return _chipTools; }
inline const vector<NetData*>& AnabaticEngine::getNetOrdering () const { return _netOrdering; }
inline void AnabaticEngine::setGlobalThreshold ( DbU::Unit threshold ) { _configuration->setGlobalThreshold(threshold); }
inline const NetDatas& AnabaticEngine::getNetDatas () const { return _netDatas; }
inline void AnabaticEngine::_updateLookup ( GCell* gcell ) { _matrix.updateLookup(gcell); }
inline void AnabaticEngine::_resizeMatrix () { _matrix.resize( getCell(), getGCells() ); }
inline void AnabaticEngine::_updateGContacts ( Flags flags ) { for ( GCell* gcell : getGCells() ) gcell->updateGContacts(flags); }
inline bool AnabaticEngine::_inDestroy () const { return _flags & Flags::DestroyMask; }
inline void AnabaticEngine::disableCanonize () { _flags |= Flags::DisableCanonize; }
inline void AnabaticEngine::enableCanonize () { _flags.reset( Flags::DisableCanonize ); }
inline void AnabaticEngine::_add ( GCell* gcell ) inline void AnabaticEngine::_add ( GCell* gcell )
{ {

View File

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

View File

@ -14,9 +14,8 @@
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
#ifndef ANABATIC_AUTOSEGMENT_H #pragma once
#define ANABATIC_AUTOSEGMENT_H #include <tuple>
#include <set> #include <set>
#include <iostream> #include <iostream>
#include <functional> #include <functional>
@ -39,6 +38,7 @@ namespace Hurricane {
namespace Anabatic { namespace Anabatic {
using std::tuple;
using std::array; using std::array;
using std::set; using std::set;
using std::cerr; using std::cerr;
@ -109,6 +109,7 @@ namespace Anabatic {
static const uint64_t SegNonPref = (1L<<37); static const uint64_t SegNonPref = (1L<<37);
static const uint64_t SegAtMinArea = (1L<<38); static const uint64_t SegAtMinArea = (1L<<38);
static const uint64_t SegNoMoveUp = (1L<<39); static const uint64_t SegNoMoveUp = (1L<<39);
static const uint64_t SegOnVSmall = (1L<<40);
// Masks. // Masks.
static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2; static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2;
static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned; static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned;
@ -202,6 +203,7 @@ namespace Anabatic {
inline bool isTerminal () const; inline bool isTerminal () const;
inline bool isUnbreakable () const; inline bool isUnbreakable () const;
inline bool isNonPref () const; inline bool isNonPref () const;
inline bool isNonPrefOnVSmall () const;
inline bool isDrag () const; inline bool isDrag () const;
inline bool isAtMinArea () const; inline bool isAtMinArea () const;
inline bool isNotSourceAligned () const; inline bool isNotSourceAligned () const;
@ -216,7 +218,6 @@ namespace Anabatic {
inline bool isSpinBottom () const; inline bool isSpinBottom () const;
inline bool isSpinTopOrBottom () const; inline bool isSpinTopOrBottom () const;
inline bool isReduced () const; inline bool isReduced () const;
bool isUnderMinLength () const;
inline bool isStrap () const; inline bool isStrap () const;
inline bool isDogleg () const; inline bool isDogleg () const;
inline bool isUnbound () const; inline bool isUnbound () const;
@ -227,7 +228,7 @@ namespace Anabatic {
inline bool isUnsetAxis () const; inline bool isUnsetAxis () const;
inline bool isSlackened () const; inline bool isSlackened () const;
inline bool isUserDefined () const; inline bool isUserDefined () const;
bool isMiddleStack () const; bool isNearMinArea () const;
bool isReduceCandidate () const; bool isReduceCandidate () const;
bool isUTurn () const; bool isUTurn () const;
inline bool isAnalog () const; inline bool isAnalog () const;
@ -340,8 +341,8 @@ namespace Anabatic {
bool bloatStackedStrap (); bool bloatStackedStrap ();
bool reduce ( Flags flags=Flags::WithPerpands ); bool reduce ( Flags flags=Flags::WithPerpands );
bool raise (); bool raise ();
bool expandToMinLength ( Interval ); void expandToMinLength ( Interval );
bool unexpandToMinLength (); void unexpandToMinLength ();
// Canonical Modifiers. // Canonical Modifiers.
AutoSegment* canonize ( Flags flags=Flags::NoFlags ); AutoSegment* canonize ( Flags flags=Flags::NoFlags );
virtual void invalidate ( Flags flags=Flags::Propagate ); virtual void invalidate ( Flags flags=Flags::Propagate );
@ -468,7 +469,8 @@ namespace Anabatic {
); );
static void getTopologicalInfos ( AutoSegment* seed static void getTopologicalInfos ( AutoSegment* seed
, vector<AutoSegment*>& collapseds , vector<AutoSegment*>& collapseds
, vector<AutoSegment*>& perpandiculars , vector< tuple<AutoSegment*,Flags> >&
perpandiculars
, DbU::Unit& leftBound , DbU::Unit& leftBound
, DbU::Unit& rightBound , DbU::Unit& rightBound
); );
@ -536,6 +538,7 @@ namespace Anabatic {
inline bool AutoSegment::isLocal () const { return not (_flags & SegGlobal); } inline bool AutoSegment::isLocal () const { return not (_flags & SegGlobal); }
inline bool AutoSegment::isUnbreakable () const { return _flags & SegUnbreakable; } inline bool AutoSegment::isUnbreakable () const { return _flags & SegUnbreakable; }
inline bool AutoSegment::isNonPref () const { return _flags & SegNonPref; } inline bool AutoSegment::isNonPref () const { return _flags & SegNonPref; }
inline bool AutoSegment::isNonPrefOnVSmall () const { return (_flags & SegNonPref) and (_flags & SegOnVSmall); }
inline bool AutoSegment::isBipoint () const { return _flags & SegBipoint; } inline bool AutoSegment::isBipoint () const { return _flags & SegBipoint; }
inline bool AutoSegment::isWeakTerminal () const { return (_rpDistance < 2); } inline bool AutoSegment::isWeakTerminal () const { return (_rpDistance < 2); }
inline bool AutoSegment::isWeakTerminal1 () const { return (_rpDistance == 1); } inline bool AutoSegment::isWeakTerminal1 () const { return (_rpDistance == 1); }
@ -667,7 +670,8 @@ namespace Anabatic {
cdebug_log(145,0) << "getTerminalCount() - " << seed << endl; cdebug_log(145,0) << "getTerminalCount() - " << seed << endl;
vector<AutoSegment*> collapseds; vector<AutoSegment*> collapseds;
vector<AutoSegment*> perpandiculars; vector< tuple<AutoSegment*,Flags> >
perpandiculars;
DbU::Unit leftBound; DbU::Unit leftBound;
DbU::Unit rightBound; DbU::Unit rightBound;
@ -703,6 +707,3 @@ namespace Anabatic {
INSPECTOR_P_SUPPORT(Anabatic::AutoSegment); INSPECTOR_P_SUPPORT(Anabatic::AutoSegment);
# endif // ANABATIC_AUTOSEGMENT_H

View File

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

View File

@ -1,7 +1,7 @@
// -*- mode: C++; explicit-buffer-name: "Configuration.h<anabatic>" -*- // -*- mode: C++; explicit-buffer-name: "Configuration.h<anabatic>" -*-
// //
// This file is part of the Coriolis Software. // This file is part of the Coriolis Software.
// Copyright (c) UPMC 2016-2018, All Rights Reserved // Copyright (c) Sorbonne Université 2016-2022, All Rights Reserved
// //
// +-----------------------------------------------------------------+ // +-----------------------------------------------------------------+
// | C O R I O L I S | // | C O R I O L I S |
@ -66,8 +66,11 @@ namespace Anabatic {
bool isGMetal ( const Layer* ) const; bool isGMetal ( const Layer* ) const;
bool isGContact ( const Layer* ) const; bool isGContact ( const Layer* ) const;
bool isTwoMetals () const; bool isTwoMetals () const;
bool isHybrid () const;
bool isHV () const; bool isHV () const;
bool isVH () const; bool isVH () const;
inline std::string getNetBuilderStyle () const;
inline StyleFlags getRoutingStyle () const;
const Layer* getGContactLayer () const; const Layer* getGContactLayer () const;
const Layer* getGHorizontalLayer () const; const Layer* getGHorizontalLayer () const;
const Layer* getGVerticalLayer () const; const Layer* getGVerticalLayer () const;
@ -132,6 +135,8 @@ namespace Anabatic {
int getGlobalIterations () const; int getGlobalIterations () const;
DbU::Unit isOnRoutingGrid ( RoutingPad* ) const; DbU::Unit isOnRoutingGrid ( RoutingPad* ) const;
bool selectRpComponent ( RoutingPad* ) const; bool selectRpComponent ( RoutingPad* ) const;
inline void setRoutingStyle ( StyleFlags );
inline void resetRoutingStyle ( StyleFlags );
virtual void print ( Cell* ) const; virtual void print ( Cell* ) const;
virtual Record* _getRecord () const; virtual Record* _getRecord () const;
virtual string _getString () const; virtual string _getString () const;
@ -146,6 +151,8 @@ namespace Anabatic {
size_t _ddepthv; size_t _ddepthv;
size_t _ddepthh; size_t _ddepthh;
size_t _ddepthc; size_t _ddepthc;
std::string _netBuilderStyle;
StyleFlags _routingStyle;
CellGauge* _cg; CellGauge* _cg;
RoutingGauge* _rg; RoutingGauge* _rg;
std::vector<DbU::Unit> _extensionCaps; std::vector<DbU::Unit> _extensionCaps;
@ -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 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::getGHorizontalDepth () const { return _gdepthh; }
inline size_t Configuration::getGVerticalDepth () const { return _gdepthv; } inline size_t Configuration::getGVerticalDepth () const { return _gdepthv; }
@ -193,6 +202,8 @@ namespace Anabatic {
inline std::string Configuration::getDiodeName () const { return _diodeName; } inline std::string Configuration::getDiodeName () const { return _diodeName; }
inline DbU::Unit Configuration::getAntennaGateMaxWL () const { return _antennaGateMaxWL; } inline DbU::Unit Configuration::getAntennaGateMaxWL () const { return _antennaGateMaxWL; }
inline DbU::Unit Configuration::getAntennaDiodeMaxWL () const { return _antennaDiodeMaxWL; } inline DbU::Unit Configuration::getAntennaDiodeMaxWL () const { return _antennaDiodeMaxWL; }
inline void Configuration::setRoutingStyle ( StyleFlags flags ) { _routingStyle = flags; }
inline void Configuration::resetRoutingStyle ( StyleFlags flags ) { _routingStyle &= ~flags; }
} // Anabatic namespace. } // Anabatic namespace.

View File

@ -20,6 +20,9 @@
namespace Anabatic { namespace Anabatic {
// -------------------------------------------------------------------
// Class : "Anabatic::Flags".
class Flags : public Hurricane::BaseFlags { class Flags : public Hurricane::BaseFlags {
public: public:
static const BaseFlags NoFlags ; // = 0; static const BaseFlags NoFlags ; // = 0;
@ -51,6 +54,7 @@ namespace Anabatic {
static const BaseFlags DestroyGCell ; // = (1 << 7); static const BaseFlags DestroyGCell ; // = (1 << 7);
static const BaseFlags DestroyBaseContact ; // = (1 << 8); static const BaseFlags DestroyBaseContact ; // = (1 << 8);
static const BaseFlags DestroyBaseSegment ; // = (1 << 9); static const BaseFlags DestroyBaseSegment ; // = (1 << 9);
static const BaseFlags DisableCanonize ; // = (1 << 10);
// Flags for NetDatas objects states only. // Flags for NetDatas objects states only.
static const BaseFlags GlobalFixed ; // = (1 << 5); static const BaseFlags GlobalFixed ; // = (1 << 5);
static const BaseFlags GlobalEstimated ; // = (1 << 6); static const BaseFlags GlobalEstimated ; // = (1 << 6);
@ -106,6 +110,7 @@ namespace Anabatic {
static const BaseFlags NoMinLength ; static const BaseFlags NoMinLength ;
static const BaseFlags NoSegExt ; static const BaseFlags NoSegExt ;
static const BaseFlags NullLength ; static const BaseFlags NullLength ;
static const BaseFlags OnVSmall ;
public: public:
inline Flags ( uint64_t flags = NoFlags ); inline Flags ( uint64_t flags = NoFlags );
inline Flags ( const Hurricane::BaseFlags& ); inline Flags ( const Hurricane::BaseFlags& );
@ -120,6 +125,39 @@ namespace Anabatic {
Flags::Flags ( const Hurricane::BaseFlags& flags ) : BaseFlags(flags) { } Flags::Flags ( const Hurricane::BaseFlags& flags ) : BaseFlags(flags) { }
// -------------------------------------------------------------------
// Class : "Anabatic::StyleFlags".
class StyleFlags : public Hurricane::BaseFlags {
public:
static const BaseFlags NoStyle; // = 0;
static const BaseFlags HV ; // = (1 << 0);
static const BaseFlags VH ; // = (1 << 1);
static const BaseFlags OTH ; // = (1 << 2);
static const BaseFlags Channel; // = (1 << 3);
static const BaseFlags Hybrid ; // = (1 << 4);
public:
inline StyleFlags ( std::string );
inline StyleFlags ( uint64_t flags = NoStyle );
inline StyleFlags ( const Hurricane::BaseFlags& );
virtual ~StyleFlags ();
static StyleFlags toFlag ( std::string );
StyleFlags from ( std::string );
virtual std::string asString () const;
virtual std::string _getTypeName () const;
virtual std::string _getString () const;
};
StyleFlags::StyleFlags ( std::string textFlags ) : BaseFlags(NoStyle) { from(textFlags); }
StyleFlags::StyleFlags ( uint64_t flags ) : BaseFlags(flags) { }
StyleFlags::StyleFlags ( const Hurricane::BaseFlags& flags ) : BaseFlags(flags) { }
// -------------------------------------------------------------------
// Misc. enums.
enum FlagsMode { FlagsFunction = 1 enum FlagsMode { FlagsFunction = 1
}; };

View File

@ -259,6 +259,7 @@ namespace Anabatic {
bool checkEdgeSaturation ( size_t hreserved, size_t vreserved) const; bool checkEdgeSaturation ( size_t hreserved, size_t vreserved) const;
void setType ( Flags ); void setType ( Flags );
inline void setSatProcessed ( size_t depth ); inline void setSatProcessed ( size_t depth );
void postGlobalAnnotate ();
void addBlockage ( size_t depth, DbU::Unit ); void addBlockage ( size_t depth, DbU::Unit );
inline void addHSegment ( AutoSegment* ); inline void addHSegment ( AutoSegment* );
inline void addVSegment ( AutoSegment* ); inline void addVSegment ( AutoSegment* );

View File

@ -47,31 +47,39 @@ namespace Anabatic {
class ForkStack { class ForkStack {
public: public:
inline void push ( Hook* from, AutoContact* contact ); inline void push ( Hook* from, AutoContact* contact, uint64_t flags );
inline void pop (); inline void pop ();
inline Hook* getFrom () const; inline Hook* getFrom () const;
inline AutoContact* getContact () const; inline AutoContact* getContact () const;
inline uint64_t getFlags () const;
inline void setFlags ( uint64_t );
private: private:
struct Element { struct Element {
Hook* _from; Hook* _from;
AutoContact* _contact; AutoContact* _contact;
inline Element ( Hook* from, AutoContact* contact ); uint64_t _flags;
inline Element ( Hook* from, AutoContact* contact, uint64_t flags );
}; };
private: private:
list<Element> _stack; 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 void ForkStack::pop () { if (not _stack.empty()) _stack.pop_back(); }
inline Hook* ForkStack::getFrom () const { return _stack.empty() ? NULL : _stack.back()._from; } 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 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; cdebug_log(145,0) << " Stacking: " << endl;
_stack.push_back( Element(from,contact) ); 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) , Middle = (1 << 16)
, UseNonPref = (1 << 17) , UseNonPref = (1 << 17)
, NoProtect = (1 << 18) , NoProtect = (1 << 18)
, ToUpperRouting = (1 << 19)
, HBothAccess = HAccess|HAccessEW , HBothAccess = HAccess|HAccessEW
, SouthWest = SouthBound|WestBound , SouthWest = SouthBound|WestBound
, NorthEast = NorthBound|EastBound , NorthEast = NorthBound|EastBound
}; };
enum TopologyFlag { Global_Vertical_End = 0x00000001 enum TopologyFlag { Global_Vertical_End = (1 << 0)
, Global_Horizontal_End = 0x00000002 , Global_Horizontal_End = (1 << 1)
, Global_Horizontal = 0x00000004 , Global_Horizontal = (1 << 2)
, Global_Vertical = 0x00000008 , Global_Vertical = (1 << 3)
, Global_Turn = 0x00000010 , Global_Turn = (1 << 4)
, Global_Fork = 0x00000020 , Global_Fork = (1 << 5)
, Global_Fixed = 0x00000040 , Global_Fixed = (1 << 6)
, Global_End = Global_Vertical_End | Global_Horizontal_End , Global_End = Global_Vertical_End | Global_Horizontal_End
, Global_Split = Global_Horizontal | Global_Vertical | Global_Fork , Global_Split = Global_Horizontal | Global_Vertical | Global_Fork
}; };
@ -148,14 +157,16 @@ namespace Anabatic {
NetBuilder (); NetBuilder ();
virtual ~NetBuilder (); virtual ~NetBuilder ();
void clear (); void clear ();
inline bool isTwoMetals () const; inline bool isStrictChannel () const;
inline bool isUpperMetalRp () const;
inline AnabaticEngine* getAnabatic () const; inline AnabaticEngine* getAnabatic () const;
inline unsigned int getDegree () const; inline unsigned int getDegree () const;
inline void setDegree ( unsigned int degree ); inline void setDegree ( unsigned int degree );
void fixSegments (); void fixSegments ();
NetBuilder& setStartHook ( AnabaticEngine* NetBuilder& setStartHook ( AnabaticEngine*
, Hook* fromHook , Hook* fromHook
, AutoContact* sourceContact=NULL ); , AutoContact* sourceContact=NULL
, uint64_t sourceFlags=0 );
void construct (); void construct ();
inline unsigned int getStateG () const; inline unsigned int getStateG () const;
inline UConnexity getConnexity () const; inline UConnexity getConnexity () const;
@ -169,6 +180,8 @@ namespace Anabatic {
inline AutoContact* getNorthEastContact () const; inline AutoContact* getNorthEastContact () const;
inline AutoContact*& getNorthEastContact (); inline AutoContact*& getNorthEastContact ();
inline Hook* getFromHook () const; inline Hook* getFromHook () const;
inline uint64_t getSourceFlags () const;
inline uint64_t getFlags () const;
inline ForkStack& getForks (); inline ForkStack& getForks ();
inline vector<RoutingPad*>& getRoutingPads (); inline vector<RoutingPad*>& getRoutingPads ();
inline map<Component*,AutoSegment*>& getRpLookup (); inline map<Component*,AutoSegment*>& getRpLookup ();
@ -187,6 +200,7 @@ namespace Anabatic {
inline void clearSouths (); inline void clearSouths ();
inline void clearEasts (); inline void clearEasts ();
inline void clearWests (); inline void clearWests ();
inline void setFlags ( uint64_t );
inline void setFromHook ( Hook* ); inline void setFromHook ( Hook* );
inline void setSouthWestContact ( AutoContact* ); inline void setSouthWestContact ( AutoContact* );
inline void setNorthEastContact ( AutoContact* ); inline void setNorthEastContact ( AutoContact* );
@ -194,6 +208,7 @@ namespace Anabatic {
inline void swapCornerContacts (); inline void swapCornerContacts ();
inline void addToFixSegments ( AutoSegment* ); inline void addToFixSegments ( AutoSegment* );
bool push ( Hook* to, AutoContact* contact, uint64_t flags=0 ); 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 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_Access ( GCell*, Component*, uint64_t flags ) = 0;
virtual AutoContact* doRp_AccessPad ( RoutingPad*, uint64_t flags ); virtual AutoContact* doRp_AccessPad ( RoutingPad*, uint64_t flags );
@ -221,6 +236,7 @@ namespace Anabatic {
virtual bool _do_xG_xM2 (); virtual bool _do_xG_xM2 ();
virtual bool _do_1G_1M3 (); virtual bool _do_1G_1M3 ();
virtual bool _do_xG_xM3 (); virtual bool _do_xG_xM3 ();
virtual bool _do_1G_xM1_1PinM1 ();
virtual bool _do_1G_xM1_1PinM2 (); virtual bool _do_1G_xM1_1PinM2 ();
virtual bool _do_2G_xM1_1PinM2 (); virtual bool _do_2G_xM1_1PinM2 ();
virtual bool _do_1G_1M1_1PinM3 (); virtual bool _do_1G_1M1_1PinM3 ();
@ -329,6 +345,8 @@ namespace Anabatic {
, Conn_1G_1PinM2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 1 ) , Conn_1G_1PinM2 = CONNEXITY_VALUE( 1, 0, 1, 0, 0 , 1 )
, Conn_2G_1PinM2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 1 ) , Conn_2G_1PinM2 = CONNEXITY_VALUE( 2, 0, 1, 0, 0 , 1 )
, Conn_3G_1PinM2 = CONNEXITY_VALUE( 3, 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_1M1_1PinM2 = CONNEXITY_VALUE( 1, 1, 1, 0, 0 , 1 )
, Conn_1G_2M1_1PinM2 = CONNEXITY_VALUE( 1, 2, 1, 0, 0 , 1 ) , Conn_1G_2M1_1PinM2 = CONNEXITY_VALUE( 1, 2, 1, 0, 0 , 1 )
, Conn_1G_3M1_1PinM2 = CONNEXITY_VALUE( 1, 3, 1, 0, 0 , 1 ) , Conn_1G_3M1_1PinM2 = CONNEXITY_VALUE( 1, 3, 1, 0, 0 , 1 )
@ -371,14 +389,13 @@ namespace Anabatic {
map<Component*,AutoSegment*> _routingPadAutoSegments; map<Component*,AutoSegment*> _routingPadAutoSegments;
vector<AutoSegment*> _toFixSegments; vector<AutoSegment*> _toFixSegments;
unsigned int _degree; unsigned int _degree;
bool _isTwoMetals; bool _isStrictChannel;
uint64_t _sourceFlags;
// Sort classes. uint64_t _flags;
public:
}; };
inline bool NetBuilder::isTwoMetals () const { return _isTwoMetals; } inline bool NetBuilder::isStrictChannel () const { return _isStrictChannel; }
inline AnabaticEngine* NetBuilder::getAnabatic () const { return _anabatic; } inline AnabaticEngine* NetBuilder::getAnabatic () const { return _anabatic; }
inline unsigned int NetBuilder::getDegree () const { return _degree; } inline unsigned int NetBuilder::getDegree () const { return _degree; }
inline NetBuilder::UConnexity NetBuilder::getConnexity () const { return _connexity; } 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 () const { return _northEastContact; }
inline AutoContact*& NetBuilder::getNorthEastContact () { return _northEastContact; } inline AutoContact*& NetBuilder::getNorthEastContact () { return _northEastContact; }
inline Hook* NetBuilder::getFromHook () const { return _fromHook; } 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 unsigned int NetBuilder::getTopology () const { return _topology; }
inline vector<RoutingPad*>& NetBuilder::getRoutingPads () { return _routingPads; } inline vector<RoutingPad*>& NetBuilder::getRoutingPads () { return _routingPads; }
inline map<Component*,AutoSegment*>& NetBuilder::getRpLookup () { return _routingPadAutoSegments; } 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::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::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 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::setDegree ( unsigned int degree ) { _degree = degree; }
inline void NetBuilder::setFromHook ( Hook* hook ) { _fromHook = hook; } inline void NetBuilder::setFromHook ( Hook* hook ) { _fromHook = hook; }
inline void NetBuilder::setBothCornerContacts ( AutoContact* ac ) { _southWestContact = _northEastContact = ac; } inline void NetBuilder::setBothCornerContacts ( AutoContact* ac ) { _southWestContact = _northEastContact = ac; }

View File

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

View File

@ -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.

View File

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

View File

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

View File

@ -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.

View File

@ -76,10 +76,12 @@ namespace Anabatic {
static inline bool doDestroyBaseSegment (); static inline bool doDestroyBaseSegment ();
static inline bool doDestroyTool (); static inline bool doDestroyTool ();
static bool isInDemoMode (); static bool isInDemoMode ();
static bool isChannelStyle ();
static bool doWarnGCellOverload (); static bool doWarnGCellOverload ();
static Session* get ( const char* message=NULL ); static Session* get ( const char* message=NULL );
static inline Technology* getTechnology (); static inline Technology* getTechnology ();
static inline AnabaticEngine* getAnabatic (); static inline AnabaticEngine* getAnabatic ();
static StyleFlags getRoutingStyle ();
static inline const Configuration* getConfiguration (); static inline const Configuration* getConfiguration ();
static float getSaturateRatio (); static float getSaturateRatio ();
static size_t getSaturateRp (); static size_t getSaturateRp ();
@ -120,6 +122,8 @@ namespace Anabatic {
static inline size_t getLayerDepth ( const Layer* layer ); static inline size_t getLayerDepth ( const Layer* layer );
static inline const Layer* getRoutingLayer ( size_t ); static inline const Layer* getRoutingLayer ( size_t );
static inline const Layer* getContactLayer ( 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 Flags getDirection ( size_t depth );
static inline DbU::Unit getPitch ( size_t depth, Flags flags ); static inline DbU::Unit getPitch ( size_t depth, Flags flags );
static inline DbU::Unit getOffset ( size_t depth ); 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 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::getRoutingLayer ( size_t depth ) { return getRoutingGauge()->getRoutingLayer(depth); }
inline const Layer* Session::getContactLayer ( size_t depth ) { return getRoutingGauge()->getContactLayer(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::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::getOffset ( size_t depth ) { return getRoutingGauge()->getLayerOffset(depth); }
inline DbU::Unit Session::getWireWidth ( size_t depth ) { return getRoutingGauge()->getLayerWireWidth(depth); } inline DbU::Unit Session::getWireWidth ( size_t depth ) { return getRoutingGauge()->getLayerWireWidth(depth); }

View File

@ -3,7 +3,7 @@
set(CMAKE_LEGACY_CYGWIN_WIN32 0) set(CMAKE_LEGACY_CYGWIN_WIN32 0)
project(Bootstrap) project(Bootstrap)
cmake_minimum_required(VERSION 2.8.0) cmake_minimum_required(VERSION 3.16)
set(ignoreVariables USE_LIBBFD "${BUILD_DOC} ${CMAKE_INSTALL_DIR}") set(ignoreVariables USE_LIBBFD "${BUILD_DOC} ${CMAKE_INSTALL_DIR}")
@ -11,7 +11,7 @@
list(INSERT CMAKE_MODULE_PATH 0 "${Bootstrap_SOURCE_DIR}/cmake_modules/") list(INSERT CMAKE_MODULE_PATH 0 "${Bootstrap_SOURCE_DIR}/cmake_modules/")
find_package(Bootstrap REQUIRED) 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) find_package(PythonSitePackages REQUIRED)
print_cmake_module_path() print_cmake_module_path()
@ -32,3 +32,10 @@
PERMISSIONS OWNER_WRITE PERMISSIONS OWNER_WRITE
OWNER_READ GROUP_READ WORLD_READ OWNER_READ GROUP_READ WORLD_READ
OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE) OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
install(FILES crlenv.py
DESTINATION bin
RENAME crlenv
PERMISSIONS OWNER_WRITE
OWNER_READ GROUP_READ WORLD_READ
OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)

View File

@ -1,7 +1,26 @@
#!/bin/bash #!/bin/bash
srcDir=${HOME}/coriolis-2.x/src/alliance/alliance/src #. /etc/*-release
commonRoot=${HOME}/coriolis-2.x/Linux.el7_64/Release.Shared #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 buildDir=${commonRoot}/build
installDir=${commonRoot}/install installDir=${commonRoot}/install

View File

@ -21,11 +21,12 @@ projects = [
, "etesian" , "etesian"
, "anabatic" , "anabatic"
, "katana" , "katana"
, "knik" #, "knik"
, "katabatic" #, "katabatic"
, "kite" #, "kite"
, "equinox" #, "equinox"
, "solstice" #, "solstice"
, "tramontana"
, "oroshi" , "oroshi"
, "bora" , "bora"
, "karakaze" , "karakaze"

View File

@ -35,12 +35,13 @@ class Builder:
self._noCache = False self._noCache = False
self._ninja = False self._ninja = False
self._clang = False self._clang = False
self._manylinux = False
self._noSystemBoost = False self._noSystemBoost = False
self._macports = False self._macports = False
self._devtoolset = 0 self._devtoolset = 0
self._llvmtoolset = 0 self._llvmtoolset = 0
self._bfd = "OFF" self._bfd = "OFF"
self._qt5 = False self._qt4 = False
self._openmp = False self._openmp = False
self._enableShared = "ON" self._enableShared = "ON"
self._enableDoc = "OFF" self._enableDoc = "OFF"
@ -62,6 +63,7 @@ class Builder:
elif attribute == "noCache": self._noCache = value elif attribute == "noCache": self._noCache = value
elif attribute == "ninja": self._ninja = value elif attribute == "ninja": self._ninja = value
elif attribute == "clang": self._clang = value elif attribute == "clang": self._clang = value
elif attribute == "manylinux": self._manylinux = value
elif attribute == "macports": elif attribute == "macports":
self._macports = value self._macports = value
if value: self._noSystemBoost = True if value: self._noSystemBoost = True
@ -71,7 +73,7 @@ class Builder:
elif attribute == "llvmtoolset": elif attribute == "llvmtoolset":
self._llvmtoolset = value self._llvmtoolset = value
elif attribute == "bfd": self._bfd = 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 == "openmp": self._openmp = value
elif attribute == "enableDoc": self._enableDoc = value elif attribute == "enableDoc": self._enableDoc = value
elif attribute == "enableShared": self._enableShared = value elif attribute == "enableShared": self._enableShared = value
@ -175,8 +177,9 @@ class Builder:
#, "-D", "BOOST_LIBRARYDIR:STRING=/usr/lib64/boost169" #, "-D", "BOOST_LIBRARYDIR:STRING=/usr/lib64/boost169"
] ]
if self._bfd: command += [ "-D", "USE_LIBBFD:STRING=%s" % self._bfd ] 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._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 command += [ "-D", "CMAKE_BUILD_TYPE:STRING=%s" % self.buildMode
#, "-D", "BUILD_SHARED_LIBS:STRING=%s" % self.enableShared #, "-D", "BUILD_SHARED_LIBS:STRING=%s" % self.enableShared
, "-D", "CMAKE_INSTALL_PREFIX:STRING=%s" % self.installDir , "-D", "CMAKE_INSTALL_PREFIX:STRING=%s" % self.installDir

View File

@ -2,7 +2,7 @@
# -*- mode:Python -*- # -*- mode:Python -*-
# #
# This file is part of the Coriolis Software. # 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 | # | 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.svnStatus: command += [ '--svn-update' ]
if self.options.enableDoc: command += [ '--doc' ] if self.options.enableDoc: command += [ '--doc' ]
if self.options.devtoolset: command += [ '--devtoolset-8' ] 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.noCache: command += [ '--no-cache' ]
if self.options.rmBuild: command += [ '--rm-build' ] if self.options.rmBuild: command += [ '--rm-build' ]
if self.options.verbose: command += [ '--verbose' ] if self.options.verbose: command += [ '--verbose' ]

View File

@ -122,6 +122,7 @@ class Configuration ( object ):
def _guessOs ( self ): def _guessOs ( self ):
self._libSuffix = None self._libSuffix = None
self._osEL9 = re.compile (".*Linux.*(el9|al9).*x86_64.*")
self._osSlsoc7x_64 = re.compile (".*Linux.*(el7|slsoc7).*x86_64.*") self._osSlsoc7x_64 = re.compile (".*Linux.*(el7|slsoc7).*x86_64.*")
self._osSlsoc6x_64 = re.compile (".*Linux.*(el6|slsoc6).*x86_64.*") self._osSlsoc6x_64 = re.compile (".*Linux.*(el6|slsoc6).*x86_64.*")
self._osSlsoc6x = re.compile (".*Linux.*(el6|slsoc6).*") self._osSlsoc6x = re.compile (".*Linux.*(el6|slsoc6).*")
@ -145,7 +146,10 @@ class Configuration ( object ):
uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE ) uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE )
lines = uname.stdout.readlines() lines = uname.stdout.readlines()
osLine = lines[0].decode( 'ascii' ) 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._osType = "Linux.el7_64"
self._libSuffix = "64" self._libSuffix = "64"
elif self._osSlsoc6x_64.match(osLine): elif self._osSlsoc6x_64.match(osLine):

View File

@ -57,7 +57,7 @@ class OptionsWidget ( QWidget ):
self._make = QCheckBox( 'Build' ) self._make = QCheckBox( 'Build' )
self._enableDoc = QCheckBox( 'Build Documentation' ) self._enableDoc = QCheckBox( 'Build Documentation' )
self._devtoolset = QCheckBox( 'Build with devtoolset 8' ) 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._noCache = QCheckBox( 'Remove previous CMake cache' )
self._rmBuild = QCheckBox( 'Cleanup Build Directory' ) self._rmBuild = QCheckBox( 'Cleanup Build Directory' )
self._verbose = QCheckBox( 'Display Compiler Commands' ) self._verbose = QCheckBox( 'Display Compiler Commands' )
@ -83,7 +83,7 @@ class OptionsWidget ( QWidget ):
vLayout.addWidget( self._buildMode ) vLayout.addWidget( self._buildMode )
vLayout.addWidget( self._enableDoc ) vLayout.addWidget( self._enableDoc )
vLayout.addWidget( self._devtoolset ) vLayout.addWidget( self._devtoolset )
vLayout.addWidget( self._qt5 ) vLayout.addWidget( self._qt4 )
vLayout.addWidget( self._noCache ) vLayout.addWidget( self._noCache )
vLayout.addWidget( self._rmBuild ) vLayout.addWidget( self._rmBuild )
vLayout.addStretch() vLayout.addStretch()
@ -121,7 +121,7 @@ class OptionsWidget ( QWidget ):
def _getMake ( self ): return self._make.isChecked() def _getMake ( self ): return self._make.isChecked()
def _getEnableDoc ( self ): return self._enableDoc.isChecked() def _getEnableDoc ( self ): return self._enableDoc.isChecked()
def _getDevtoolset ( self ): return self._devtoolset.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 _getNoCache ( self ): return self._noCache.isChecked()
def _getRmBuild ( self ): return self._rmBuild.isChecked() def _getRmBuild ( self ): return self._rmBuild.isChecked()
def _getVerbose ( self ): return self._verbose.isChecked() def _getVerbose ( self ): return self._verbose.isChecked()
@ -134,7 +134,7 @@ class OptionsWidget ( QWidget ):
make = property( _getMake ) make = property( _getMake )
enableDoc = property( _getEnableDoc ) enableDoc = property( _getEnableDoc )
devtoolset = property( _getDevtoolset ) devtoolset = property( _getDevtoolset )
qt5 = property( _getQt5 ) qt4 = property( _getQt4 )
noCache = property( _getNoCache ) noCache = property( _getNoCache )
rmBuild = property( _getRmBuild ) rmBuild = property( _getRmBuild )
verbose = property( _getVerbose ) verbose = property( _getVerbose )
@ -146,7 +146,7 @@ class OptionsWidget ( QWidget ):
self._make .setChecked( bool(settings.value('builder/make' )) ) self._make .setChecked( bool(settings.value('builder/make' )) )
self._enableDoc .setChecked( bool(settings.value('builder/enableDoc' )) ) self._enableDoc .setChecked( bool(settings.value('builder/enableDoc' )) )
self._devtoolset .setChecked( bool(settings.value('builder/devtoolset')) ) 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._noCache .setChecked( bool(settings.value('builder/noCache' )) )
self._rmBuild .setChecked( bool(settings.value('builder/rmBuild' )) ) self._rmBuild .setChecked( bool(settings.value('builder/rmBuild' )) )
self._verbose .setChecked( bool(settings.value('builder/verbose' )) ) 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/make' , self._make .isChecked() )
settings.setValue('builder/enableDoc' , self._enableDoc .isChecked() ) settings.setValue('builder/enableDoc' , self._enableDoc .isChecked() )
settings.setValue('builder/devtoolset', self._devtoolset.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/buildMode' , self._buildMode .currentText() )
settings.setValue('builder/noCache' , self._noCache .isChecked() ) settings.setValue('builder/noCache' , self._noCache .isChecked() )
settings.setValue('builder/rmBuild' , self._rmBuild .isChecked() ) settings.setValue('builder/rmBuild' , self._rmBuild .isChecked() )

View File

@ -62,6 +62,7 @@ def checkCMake ():
def guessOs (): def guessOs ():
libDir = 'lib' libDir = 'lib'
osEL9 = re.compile (".*Linux.*(el9|al9).*x86_64.*")
osSlsoc7x_64 = re.compile (".*Linux.*(el7|slsoc7).*x86_64.*") osSlsoc7x_64 = re.compile (".*Linux.*(el7|slsoc7).*x86_64.*")
osSlsoc6x_64 = re.compile (".*Linux.*(el6|slsoc6).*x86_64.*") osSlsoc6x_64 = re.compile (".*Linux.*(el6|slsoc6).*x86_64.*")
osSlsoc6x = re.compile (".*Linux.*(el6|slsoc6).*") osSlsoc6x = re.compile (".*Linux.*(el6|slsoc6).*")
@ -85,7 +86,10 @@ def guessOs ():
uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE ) uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE )
lines = uname.stdout.readlines() lines = uname.stdout.readlines()
line = lines[0].decode( 'ascii' ) 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" osType = "Linux.el7_64"
libDir = "lib64" libDir = "lib64"
elif osSlsoc6x_64.match(line): 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 ( "--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 ( "--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 ( "--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 ( "--qt4" , action="store_true" , dest="qt4" , help="Build against Qt 4 (default: Qt 5)." )
parser.add_option ( "--bfd" , action="store_true" , dest="bfd" , help="Build against Qt 5 (default: Qt 4)." ) 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 ( "--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 ( "--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 ( "--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 ( "--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 ( "--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)." ) 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.devtoolset: builder.devtoolset = options.devtoolset
if options.llvmtoolset: builder.llvmtoolset = options.llvmtoolset if options.llvmtoolset: builder.llvmtoolset = options.llvmtoolset
if options.bfd: builder.bfd = "ON" 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.openmp: builder.openmp = True
if options.makeArguments: builder.makeArguments = options.makeArguments if options.makeArguments: builder.makeArguments = options.makeArguments
#if options.svnMethod: builder.svnMethod = options.svnMethod #if options.svnMethod: builder.svnMethod = options.svnMethod

View File

@ -9,6 +9,7 @@
FindQwt.cmake FindQwt.cmake
FindSphinx.cmake FindSphinx.cmake
FindPelican.cmake FindPelican.cmake
FindCOLOQUINTE.cmake
GetGitRevisionDescription.cmake GetGitRevisionDescription.cmake
GetGitRevisionDescription.cmake.in GetGitRevisionDescription.cmake.in
) )

View File

@ -7,6 +7,10 @@
if(COMMAND CMAKE_POLICY) if(COMMAND CMAKE_POLICY)
cmake_policy(SET CMP0003 NEW) cmake_policy(SET CMP0003 NEW)
cmake_policy(SET CMP0005 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)) #if(NOT (CMAKE_VERSION VERSION_LESS 2.8.0))
# cmake_policy(SET CMP0014 OLD) # cmake_policy(SET CMP0014 OLD)
#endif() #endif()
@ -79,22 +83,27 @@
#set(DEBUG_FLAGS "-g -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC") #set(DEBUG_FLAGS "-g -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC")
set(DEBUG_FLAGS "-g") set(DEBUG_FLAGS "-g")
if(CYGWIN) if(CYGWIN)
set(ADDTIONAL_FLAGS "-D_GLIBCXX_USE_C99") set(ADDITIONAL_FLAGS "-D_GLIBCXX_USE_C99")
set(CXX_STANDARD "gnu++11") set(CXX_STANDARD "gnu++17")
else() else()
set(ADDTIONAL_FLAGS "") set(ADDITIONAL_FLAGS "-Wl,--no-undefined")
set(CXX_STANDARD "c++11") set(CXX_STANDARD "c++17")
endif() 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 -fsanitize=address ${ADDITIONAL_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_DEBUG " -Wall ${ADDITIONAL_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 -O2 ${ADDITIONAL_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_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 ${ADDTIONAL_FLAGS} ${DEBUG_FLAGS}" CACHE STRING "C++ Compiler Debug 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 ${ADDTIONAL_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 ${ADDTIONAL_FLAGS} -DNDEBUG" CACHE STRING "C++ Compiler Release 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 ${ADDTIONAL_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 # Adds to the CMAKE_MODULE_PATH directories guesseds from project
# environment variables <PROJECT>_USER_TOP and <PROJECT>_TOP. # environment variables <PROJECT>_USER_TOP and <PROJECT>_TOP.
@ -131,7 +140,7 @@
# Build <PROJECT>_INCLUDE_DIR & <PROJECT>_LIBRARIES and sets up <PROJECT>_FOUND # Build <PROJECT>_INCLUDE_DIR & <PROJECT>_LIBRARIES and sets up <PROJECT>_FOUND
# Usage: set_library_path(<PROJECT> <library>) # 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>. # <library>.
# #
macro(set_libraries_path configname library) macro(set_libraries_path configname library)
@ -148,7 +157,14 @@
set(${configname}_FOUND "NOTFOUND") set(${configname}_FOUND "NOTFOUND")
endif() endif()
endmacro() 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. # Checks if a set of libraries has been found, could be blocking or not.
@ -207,11 +223,35 @@
endmacro(setup_boost) 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. # Find Qt, the union of all the modules we need for the whole project.
# #
macro(setup_qt) 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...") message(STATUS "Attempt to find Qt 5...")
# For Qt5 # For Qt5
find_package(Qt5Core REQUIRED) find_package(Qt5Core REQUIRED)
@ -231,32 +271,22 @@
${Qt5Core_LIBRARIES} ) ${Qt5Core_LIBRARIES} )
#message(STATUS "QtX_INCLUDE_DIRS: ${QtX_INCLUDE_DIRS}") #message(STATUS "QtX_INCLUDE_DIRS: ${QtX_INCLUDE_DIRS}")
#message(STATUS "QtX_LIBRARIES: ${QtX_LIBRARIES}") #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() endif()
endmacro() endmacro()
macro(qtX_wrap_cpp variable) macro(qtX_wrap_cpp variable)
if (WITH_QT5) if (WITH_QT4)
qt5_wrap_cpp(${variable} ${ARGN})
else()
qt4_wrap_cpp(${variable} ${ARGN}) qt4_wrap_cpp(${variable} ${ARGN})
else()
qt5_wrap_cpp(${variable} ${ARGN})
endif() endif()
endmacro() endmacro()
macro(qtX_add_resources variable) macro(qtX_add_resources variable)
if (WITH_QT5) if (WITH_QT4)
qt5_add_resources(${variable} ${ARGN})
else()
qt4_add_resources(${variable} ${ARGN}) qt4_add_resources(${variable} ${ARGN})
else()
qt5_add_resources(${variable} ${ARGN})
endif() endif()
endmacro() endmacro()
@ -265,15 +295,7 @@
# Find Qwt, correlated to the Qt version. # Find Qwt, correlated to the Qt version.
# #
macro(setup_qwt) macro(setup_qwt)
if(WITH_QT5) if(WITH_QT4)
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()
find_path(QWT_INCLUDE_DIR NAMES qwt.h find_path(QWT_INCLUDE_DIR NAMES qwt.h
PATHS /usr/include/qwt-qt4 PATHS /usr/include/qwt-qt4
/opt/local/libexec/qt4/include /opt/local/libexec/qt4/include
@ -284,6 +306,14 @@
PATHS /opt/local/libexec/qt4/lib PATHS /opt/local/libexec/qt4/lib
/usr/lib64 /usr/lib64
/usr/lib ) /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() endif()
if( QWT_INCLUDE_DIR AND QWT_LIBRARY) if( QWT_INCLUDE_DIR AND QWT_LIBRARY)
@ -396,9 +426,11 @@
set( pyDeplibs ${clib} ${deplibs} ) set( pyDeplibs ${clib} ${deplibs} )
add_library( ${clib} ${pyCpps} ) 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} ) target_link_libraries( ${clib} ${deplibs} )
install( TARGETS ${clib} DESTINATION lib${LIB_SUFFIX} ) install( TARGETS ${clib} DESTINATION lib${LIB_SUFFIX} )
target_link_options( ${clib} PRIVATE "LINKER:--unresolved-symbols=ignore-all")
endif() endif()
set( pytarget "${pymodule}_target" ) set( pytarget "${pymodule}_target" )
@ -409,7 +441,9 @@
PREFIX "" PREFIX ""
OUTPUT_NAME ${pymodule} OUTPUT_NAME ${pymodule}
) )
#target_compile_definitions( ${pytarget} PUBLIC Py_LIMITED_API=1)
target_link_libraries( ${pytarget} ${pyDeplibs} ) target_link_libraries( ${pytarget} ${pyDeplibs} )
target_link_options( ${pytarget} PRIVATE "LINKER:--unresolved-symbols=ignore-all")
install( TARGETS ${pytarget} DESTINATION ${Python_CORIOLISARCH} ) install( TARGETS ${pytarget} DESTINATION ${Python_CORIOLISARCH} )
if( NOT ("${pyIncludes}" STREQUAL "None") ) if( NOT ("${pyIncludes}" STREQUAL "None") )
@ -432,6 +466,7 @@
add_library( ${pymodule} MODULE ${pyCpps} ) add_library( ${pymodule} MODULE ${pyCpps} )
set_target_properties( ${pymodule} PROPERTIES PREFIX "" ) set_target_properties( ${pymodule} PROPERTIES PREFIX "" )
target_link_libraries( ${pymodule} ${deplibs} ) target_link_libraries( ${pymodule} ${deplibs} )
#target_compile_definitions( ${pymodule} PUBLIC Py_LIMITED_API=1)
install( TARGETS ${pymodule} DESTINATION ${Python_CORIOLISARCH} ) install( TARGETS ${pymodule} DESTINATION ${Python_CORIOLISARCH} )
if( NOT ("${pyIncludes}" STREQUAL "None") ) if( NOT ("${pyIncludes}" STREQUAL "None") )

View File

@ -15,13 +15,14 @@ IF(UNIX)
# #
# Look for an installation. # 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. # Look in other places.
${CORIOLIS_DIR_SEARCH} ${CORIOLIS_DIR_SEARCH}
PATH_SUFFIXES include/coriolis2 PATH_SUFFIXES include/coriolis2
# Help the user find it if we cannot. # Help the user find it if we cannot.
DOC "The ${COLOQUINTE_INCLUDE_PATH_DESCRIPTION}" DOC "The ${COLOQUINTE_INCLUDE_PATH_DESCRIPTION}"
) )
MESSAGE( "COL ${COLOQUINTE_INCLUDE_PATH}" )
FIND_LIBRARY(COLOQUINTE_LIBRARY_PATH FIND_LIBRARY(COLOQUINTE_LIBRARY_PATH
NAMES coloquinte NAMES coloquinte

View File

@ -1,5 +1,4 @@
if(UNIX AND NOT POETRY)
if(UNIX)
if(NOT Python_FOUND) if(NOT Python_FOUND)
message(FATAL_ERROR "Python has not been found, maybe forgot to call find_package(Python). ") message(FATAL_ERROR "Python has not been found, maybe forgot to call find_package(Python). ")
endif() endif()
@ -10,7 +9,7 @@ if(UNIX)
execute_process(COMMAND "${Python_EXECUTABLE}" "-c" "${SCRIPT}" execute_process(COMMAND "${Python_EXECUTABLE}" "-c" "${SCRIPT}"
RESULT_VARIABLE RETURN_CODE RESULT_VARIABLE RETURN_CODE
OUTPUT_VARIABLE Python_CORIOLISARCH OUTPUT_VARIABLE Python_SITEARCH
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_STRIP_TRAILING_WHITESPACE
) )
@ -20,7 +19,7 @@ if(UNIX)
execute_process(COMMAND "${Python_EXECUTABLE}" "-c" "${SCRIPT}" execute_process(COMMAND "${Python_EXECUTABLE}" "-c" "${SCRIPT}"
RESULT_VARIABLE RETURN_CODE RESULT_VARIABLE RETURN_CODE
OUTPUT_VARIABLE Python_CORIOLISLIB OUTPUT_VARIABLE Python_SITELIB
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_STRIP_TRAILING_WHITESPACE
) )
@ -30,12 +29,15 @@ if(UNIX)
set(FindPythonSitePackages_FOUND FALSE) set(FindPythonSitePackages_FOUND FALSE)
endif(RETURN_CODE EQUAL 0) endif(RETURN_CODE EQUAL 0)
set(Python_CORIOLISARCH "lib${LIB_SUFFIX}/${Python_CORIOLISARCH}" set(Python_CORIOLISARCH "lib${LIB_SUFFIX}/${Python_SITEARCH}/coriolis"
CACHE STRING "Python platform dependent install directory." FORCE) CACHE STRING "Python platform dependent install directory (Coriolis modules)." FORCE)
set(Python_CORIOLISLIB "lib${LIB_SUFFIX}/${Python_CORIOLISLIB}" set(Python_SITELIB "lib${LIB_SUFFIX}/${Python_SITELIB}"
CACHE STRING "Python platform independent install directory." FORCE) 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_CORIOLISARCH)
mark_as_advanced(Python_CORIOLISLIB) mark_as_advanced(Python_CORIOLISLIB)
mark_as_advanced(Python_SITELIB)
if(FindPythonSitePackages_FOUND) if(FindPythonSitePackages_FOUND)
if(NOT FindPythonSitePackages_FIND_QUIETLY) if(NOT FindPythonSitePackages_FIND_QUIETLY)
@ -46,4 +48,4 @@ if(UNIX)
else(FindPythonSitePackages_FOUND) else(FindPythonSitePackages_FOUND)
message ( FATAL_ERROR "Python site packages directory was not found (pythonV.R/site-packages/)." ) message ( FATAL_ERROR "Python site packages directory was not found (pythonV.R/site-packages/)." )
endif(FindPythonSitePackages_FOUND) endif(FindPythonSitePackages_FOUND)
endif(UNIX) endif(UNIX AND NOT POETRY)

View File

@ -119,7 +119,7 @@ Development files for the Coriolis 2 package.
%dir %{coriolisTop}/%{_lib} %dir %{coriolisTop}/%{_lib}
%dir %{coriolisTop}/%{python_sitedir} %dir %{coriolisTop}/%{python_sitedir}
%dir %{coriolisTop}/%{python_sitedir}/crlcore %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}/cumulus
%dir %{coriolisTop}/%{python_sitedir}/stratus %dir %{coriolisTop}/%{python_sitedir}/stratus
%{coriolisTop}/bin/* %{coriolisTop}/bin/*
@ -130,7 +130,7 @@ Development files for the Coriolis 2 package.
%{coriolisTop}/%{python_sitedir}/cumulus/plugins/*/*.py* %{coriolisTop}/%{python_sitedir}/cumulus/plugins/*/*.py*
%{coriolisTop}/%{python_sitedir}/stratus/*.py* %{coriolisTop}/%{python_sitedir}/stratus/*.py*
%{coriolisTop}/%{python_sitedir}/crlcore/*.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}/kite/*.py*
%{coriolisTop}/%{python_sitedir}/unicorn/*.py* %{coriolisTop}/%{python_sitedir}/unicorn/*.py*
%{_sysconfdir}/coriolis2/*.py %{_sysconfdir}/coriolis2/*.py
@ -180,7 +180,7 @@ Development files for the Coriolis 2 package.
%{coriolisTop}/include/vlsisapd/configuration/*.h %{coriolisTop}/include/vlsisapd/configuration/*.h
%{coriolisTop}/include/vlsisapd/dtr/*.h %{coriolisTop}/include/vlsisapd/dtr/*.h
%{coriolisTop}/include/vlsisapd/openChams/*.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/*.h
%{coriolisTop}/include/coriolis2/hurricane/viewer/*.h %{coriolisTop}/include/coriolis2/hurricane/viewer/*.h
%{coriolisTop}/include/coriolis2/hurricane/isobar/*.h %{coriolisTop}/include/coriolis2/hurricane/isobar/*.h

View File

@ -17,6 +17,10 @@ reDebugStaticPattern = re.compile( r".*Debug\.Static.*" )
def scrubPath ( pathName ): 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 ) pathEnv = os.getenv( pathName )
if not pathEnv: return "" if not pathEnv: return ""
pathList = pathEnv.split( ':' ) pathList = pathEnv.split( ':' )
@ -36,8 +40,33 @@ def scrubPath ( pathName ):
return scrubbedEnv 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 (): 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 useDevtoolset = False
osEL9 = re.compile (".*Linux.*el9.*x86_64.*")
osSlsoc7x_64 = re.compile (".*Linux.*el7.*x86_64.*") osSlsoc7x_64 = re.compile (".*Linux.*el7.*x86_64.*")
osSlsoc6x_64 = re.compile (".*Linux.*el6.*x86_64.*") osSlsoc6x_64 = re.compile (".*Linux.*el6.*x86_64.*")
osSlsoc6x = re.compile (".*Linux.*(el|slsoc)6.*") osSlsoc6x = re.compile (".*Linux.*(el|slsoc)6.*")
@ -65,6 +94,7 @@ def guessOs ():
line = lines[0].decode( 'ascii' ) line = lines[0].decode( 'ascii' )
if osSlsoc7x_64.match(line): osType = "Linux.el7_64" if osSlsoc7x_64.match(line): osType = "Linux.el7_64"
elif osEL9.match(line): osType = "Linux.el9"
elif osSlsoc6x_64.match(line): elif osSlsoc6x_64.match(line):
osType = "Linux.slsoc6x_64" osType = "Linux.slsoc6x_64"
useDevtoolset = True useDevtoolset = True
@ -100,7 +130,18 @@ def guessOs ():
return ( osType, useDevtoolset ) 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 # 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* # the user logs in. If aftewards it changes it that variable is *not*
# affected :-(. # affected :-(.
@ -116,14 +157,27 @@ def guessShell ( forcedShell ):
, u'/usr/local/bin/csh' , u'/usr/local/bin/csh'
] ]
if shellName is None: if shellName is None:
psCommand = subprocess.Popen ( ['ps', '-p', str(os.getppid()) ], stdout=subprocess.PIPE ) psCommand = ['ps', '-o', 'comm', '-p', str(os.getppid()) ]
shell = psCommand.stdout.readlines()[1].decode('utf8')[:-1].split()[3].lstrip('-') cmdField = 0
whichCommand = subprocess.Popen ( ['which', shell ], stdout=subprocess.PIPE ) if osType.startswith('Cygwin'):
shellPath = whichCommand.stdout.readlines()[0][:-1].decode('utf8') psCommand = ['ps', '-p', str(os.getppid()) ]
#print( 'GUESSED shellPath={}'.format(shellPath) ) 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 = 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: else:
shellPath = forcedShell shellPath = defaultShell
#print( 'FORCED shellPath={}'.format(shellPath) ) print( 'echo "Defaulting to shell {}";'.format(shellPath) )
if shellPath in cshBins: if shellPath in cshBins:
#print( 'Matched C-Shell' ) #print( 'Matched C-Shell' )
isBourneShell = False isBourneShell = False
@ -132,7 +186,6 @@ def guessShell ( forcedShell ):
if __name__ == "__main__": if __name__ == "__main__":
osType,useDevtoolset = guessOs() osType,useDevtoolset = guessOs()
buildType = "Release" buildType = "Release"
linkType = "Shared" linkType = "Shared"
@ -161,7 +214,7 @@ if __name__ == "__main__":
if options.shared: linkType = "Shared" if options.shared: linkType = "Shared"
if options.rootDir: rootDir = options.rootDir if options.rootDir: rootDir = options.rootDir
if options.shell: shellName = options.shell 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] )) scriptPath = os.path.abspath( os.path.dirname( sys.argv[0] ))
if 'Debug.' in scriptPath: buildType = 'Debug' if 'Debug.' in scriptPath: buildType = 'Debug'
@ -257,7 +310,7 @@ if __name__ == "__main__":
shellMessage = "Using script location Coriolis 2 (%s)" % rootDir shellMessage = "Using script location Coriolis 2 (%s)" % rootDir
if osType.startswith("Cygwin"): if osType.startswith("Cygwin"):
strippedPath = "%s/lib:%s" % ( coriolisTop, libDir, strippedPath ) strippedPath = "%s/lib:%s" % ( coriolisTop, strippedPath )
if not os.path.exists(coriolisTop): if not os.path.exists(coriolisTop):
print( 'echo "[ERROR] coriolisEnv.py, top directory "{}" do not exists."'.format( coriolisTop )) print( 'echo "[ERROR] coriolisEnv.py, top directory "{}" do not exists."'.format( coriolisTop ))
sys.exit( 1 ) sys.exit( 1 )
@ -267,11 +320,12 @@ if __name__ == "__main__":
if os.path.isdir(absLibDir): break if os.path.isdir(absLibDir): break
libDir = None libDir = None
if libDir is None: if libDir is None:
print( 'echo "[ERROR] coriolisEnv.py, library directory not found."' ) if not options.queryISysRoot and not options.queryInstRoot:
sys.exit( 1 ) print( 'echo "[ERROR] coriolisEnv.py, library directory not found."' )
sys.exit( 1 )
strippedPath = "%s/bin:%s" % ( coriolisTop, strippedPath ) strippedPath = "%s/bin:%s" % ( coriolisTop, strippedPath )
strippedLibraryPath = "%s:%s" % ( absLibDir , strippedLibraryPath ) strippedLibraryPath = "%s:%s" % ( absLibDir , strippedLibraryPath )
if not options.nopython: if not options.nopython:
pyVersion = sys.version_info pyVersion = sys.version_info
version = "%d.%d" % (pyVersion[0],pyVersion[1]) version = "%d.%d" % (pyVersion[0],pyVersion[1])
@ -286,12 +340,12 @@ if __name__ == "__main__":
if os.path.isdir(pyPackageDir): if os.path.isdir(pyPackageDir):
sitePackagesDir = pyPackageDir sitePackagesDir = pyPackageDir
break break
strippedPythonPath = "%s:" % (sitePackagesDir) + strippedPythonPath strippedPythonPath = "%s" % (sitePackagesDir) + strippedPythonPath
strippedPythonPath = "%s/crlcore:" % (sitePackagesDir) + strippedPythonPath #strippedPythonPath = "%s/crlcore:" % (sitePackagesDir) + strippedPythonPath
strippedPythonPath = "%s/cumulus:" % (sitePackagesDir) + strippedPythonPath #strippedPythonPath = "%s/cumulus:" % (sitePackagesDir) + strippedPythonPath
strippedPythonPath = "%s/cumulus/plugins:" % (sitePackagesDir) + strippedPythonPath #strippedPythonPath = "%s/cumulus/plugins:" % (sitePackagesDir) + strippedPythonPath
strippedPythonPath = "%s/stratus:" % (sitePackagesDir) + strippedPythonPath #strippedPythonPath = "%s/stratus:" % (sitePackagesDir) + strippedPythonPath
strippedPythonPath = "%s:" % (sysconfDir) + strippedPythonPath #strippedPythonPath = "%s:" % (sysconfDir) + strippedPythonPath
shellScriptSh += 'PYTHONPATH="%(PYTHONPATH)s";' \ shellScriptSh += 'PYTHONPATH="%(PYTHONPATH)s";' \
'export PYTHONPATH;' 'export PYTHONPATH;'
shellScriptCsh += 'setenv PYTHONPATH "%(PYTHONPATH)s";' shellScriptCsh += 'setenv PYTHONPATH "%(PYTHONPATH)s";'

275
bootstrap/crlenv.py Executable file
View File

@ -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

View File

@ -232,6 +232,13 @@ class BenchsCommand ( CommandArg ):
def __init__ ( self, benchsDir, fdLog=None ): def __init__ ( self, benchsDir, fdLog=None ):
CommandArg.__init__ ( self, [ '../bin/go.sh' ], wd=benchsDir, fdLog=fdLog ) CommandArg.__init__ ( self, [ '../bin/go.sh' ], wd=benchsDir, fdLog=fdLog )
return return
class PyBenchsCommand ( CommandArg ):
def __init__ ( self, benchsDir, fdLog=None ):
CommandArg.__init__ ( self, [ '../bin/gopy.sh' ], wd=benchsDir, fdLog=fdLog )
return
@ -277,6 +284,16 @@ class GitRepository ( object ):
Command( [ 'git', 'checkout', branch ], self.fdLog ).execute() Command( [ 'git', 'checkout', branch ], self.fdLog ).execute()
return 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 ): class Configuration ( object ):
@ -286,7 +303,7 @@ class Configuration ( object ):
, 'homeDir' , 'masterHost' , 'homeDir' , 'masterHost'
, 'debugArg' , 'nightlyMode', 'dockerMode', 'chrootMode' , 'debugArg' , 'nightlyMode', 'dockerMode', 'chrootMode'
, 'rmSource' , 'rmBuild' , 'rmSource' , 'rmBuild'
, 'doGit' , 'doAlliance' , 'doCoriolis', 'doBenchs', 'doSendReport' , 'doGit' , 'doAlliance' , 'doCoriolis', 'doBenchs', 'doPyBenchs', 'doSendReport'
, 'success' , 'rcode' , 'success' , 'rcode'
] ]
SecondaryNames = \ SecondaryNames = \
@ -296,7 +313,7 @@ class Configuration ( object ):
def __init__ ( self ): def __init__ ( self ):
self._sender = 'Jean-Paul.Chaput@soc.lip6.fr' self._sender = 'Jean-Paul.Chaput@soc.lip6.fr'
self._receivers = [ 'Jean-Paul.Chaput@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._allianceRepo = 'https://gitlab.lip6.fr/jpc/alliance.git'
self._coriolisRepo = 'https://gitlab.lip6.fr/jpc/coriolis.git' self._coriolisRepo = 'https://gitlab.lip6.fr/jpc/coriolis.git'
self._benchsRepo = 'https://gitlab.lip6.fr/jpc/alliance-check-toolkit.git' self._benchsRepo = 'https://gitlab.lip6.fr/jpc/alliance-check-toolkit.git'
@ -309,6 +326,7 @@ class Configuration ( object ):
self._doAlliance = False self._doAlliance = False
self._doCoriolis = False self._doCoriolis = False
self._doBenchs = False self._doBenchs = False
self._doPyBenchs = False
self._doSendReport = False self._doSendReport = False
self._nightlyMode = False self._nightlyMode = False
self._dockerMode = False self._dockerMode = False
@ -434,20 +452,24 @@ class Configuration ( object ):
] ) ] )
otherArgs = [] otherArgs = []
if self.debugArg: otherArgs.append( self.debugArg ) 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': 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, 3, otherArgs , fdLog=self.fds['coriolis'] ) )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], 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': elif target == 'SL6_64' or target == 'SL6':
otherArgs.append( '--project=support' ) otherArgs += [ '--project=support', '--devtoolset=8', '--qt4' ]
otherArgs.append( '--devtoolset=8' )
commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 6, otherArgs , fdLog=self.fds['coriolis'] ) ) 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'] ) ) commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 1, otherArgs+['--doc'], fdLog=self.fds['coriolis'] ) )
elif target == 'Ubuntu18' or target == 'Debian9' or target == 'Debian10': 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'] ) ) commands.append( CoriolisCommand( self.ccbBin, self.rootDir, 3, otherArgs, fdLog=self.fds['coriolis'] ) )
if self.doBenchs: if self.doBenchs:
commands.append( BenchsCommand( self.benchsDir, fdLog=self.fds['benchs'] ) ) commands.append( BenchsCommand( self.benchsDir, fdLog=self.fds['benchs'] ) )
if self.doPyBenchs:
commands.append( PyBenchsCommand( self.benchsDir, fdLog=self.fds['benchs'] ) )
return commands 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 ( "--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 ( "--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 ( "--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-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-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)." ) 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.doAlliance: conf.doAlliance = True
if options.doCoriolis: conf.doCoriolis = True if options.doCoriolis: conf.doCoriolis = True
if options.benchs: conf.doBenchs = True if options.benchs: conf.doBenchs = True
if options.pybenchs: conf.doPyBenchs = True
if options.doReport: conf.doSendReport = True if options.doReport: conf.doSendReport = True
if options.rmSource or options.rmAll: conf.rmSource = True if options.rmSource or options.rmAll: conf.rmSource = True
if options.rmBuild or options.rmAll: conf.rmBuild = True if options.rmBuild or options.rmAll: conf.rmBuild = True
@ -559,6 +583,7 @@ try:
if conf.doAlliance: conf.openLog( 'alliance' ) if conf.doAlliance: conf.openLog( 'alliance' )
if conf.doCoriolis: conf.openLog( 'coriolis' ) if conf.doCoriolis: conf.openLog( 'coriolis' )
if conf.doBenchs: conf.openLog( 'benchs' ) if conf.doBenchs: conf.openLog( 'benchs' )
if conf.doPyBenchs: conf.openLog( 'benchs' )
if conf.dockerMode: os.environ['USER'] = 'root' if conf.dockerMode: os.environ['USER'] = 'root'
gitSupports = [] gitSupports = []
@ -586,6 +611,8 @@ try:
if conf.rmSource: gitCoriolis.removeLocalRepo() if conf.rmSource: gitCoriolis.removeLocalRepo()
gitCoriolis.clone () gitCoriolis.clone ()
gitCoriolis.checkout( 'devel' ) gitCoriolis.checkout( 'devel' )
gitCoriolis.submoduleInit()
gitCoriolis.submoduleUpdate()
if conf.rmSource: gitBenchs.removeLocalRepo() if conf.rmSource: gitBenchs.removeLocalRepo()
gitBenchs.clone() gitBenchs.clone()

View File

@ -6,7 +6,7 @@
option(BUILD_DOC "Build the documentation (doxygen)" OFF) option(BUILD_DOC "Build the documentation (doxygen)" OFF)
option(USE_LIBBFD "Link with BFD libraries to print stack traces" 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}") set(ignoreVariables "${BUILD_DOC} ${CMAKE_INSTALL_DIR}")
@ -18,9 +18,9 @@
setup_boost(program_options) setup_boost(program_options)
setup_qt() setup_qt()
setup_qwt() setup_qwt()
setup_python()
find_package(Libexecinfo REQUIRED) find_package(Libexecinfo REQUIRED)
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
find_package(PythonSitePackages REQUIRED) find_package(PythonSitePackages REQUIRED)
find_package(LEFDEF REQUIRED) find_package(LEFDEF REQUIRED)
find_package(FLUTE REQUIRED) find_package(FLUTE REQUIRED)

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