Compare commits

...

89 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
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 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
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 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 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
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
123 changed files with 7260 additions and 302 deletions

4
.gitmodules vendored
View File

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

View File

@ -18,9 +18,9 @@
set_cmake_policies()
setup_boost(program_options)
setup_qt()
setup_python()
find_package(Libexecinfo REQUIRED)
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
find_package(PythonSitePackages REQUIRED)
find_package(LEFDEF REQUIRED)
find_package(FLUTE REQUIRED)

View File

@ -18,8 +18,8 @@
set_cmake_policies()
setup_boost()
setup_qt()
setup_python()
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
find_package(PythonSitePackages REQUIRED)
find_package(FLUTE REQUIRED)
find_package(HURRICANE REQUIRED)

View File

@ -3069,6 +3069,7 @@ namespace Anabatic {
if (wPitch > 1) segment->setFlags( SegWide );
if (source->canDrag() or target->canDrag()) segment->setFlags( SegDrag );
if (dir & Flags::UseNonPref) segment->setFlags( SegNonPref );
if (dir.contains(Flags::UseNonPref|Flags::OnVSmall)) segment->setFlags( SegOnVSmall );
return segment;
}

View File

@ -14,7 +14,6 @@ endif ( CHECK_DETERMINISM )
${QtX_INCLUDE_DIRS}
${Python_INCLUDE_DIRS}
)
find_package (Python3 COMPONENTS Interpreter Development)
set( includes anabatic/Constants.h
anabatic/Configuration.h
anabatic/Matrix.h

View File

@ -132,6 +132,7 @@ namespace Anabatic {
const BaseFlags Flags::NoMinLength = (1L << 37);
const BaseFlags Flags::NoSegExt = (1L << 38);
const BaseFlags Flags::NullLength = (1L << 39);
const BaseFlags Flags::OnVSmall = (1L << 40);
Flags::~Flags ()

View File

@ -277,7 +277,9 @@ namespace Anabatic {
if (flags & (VSmall|UseNonPref)) {
cdebug_log(145,0) << "case: UseNonPref" << endl;
if (flags & VSmall)
useNonPref.reset( Flags::UseNonPref );
AutoContact* subContact1 = AutoContactTurn::create( gcell, rp->getNet(), Session::getBuildContactLayer(rpDepth+1) );
AutoSegment::create( rpSourceContact, subContact1, Flags::Vertical|useNonPref );
rpSourceContact = subContact1;

View File

@ -109,6 +109,7 @@ namespace Anabatic {
static const uint64_t SegNonPref = (1L<<37);
static const uint64_t SegAtMinArea = (1L<<38);
static const uint64_t SegNoMoveUp = (1L<<39);
static const uint64_t SegOnVSmall = (1L<<40);
// Masks.
static const uint64_t SegWeakTerminal = SegStrongTerminal|SegWeakTerminal1|SegWeakTerminal2;
static const uint64_t SegNotAligned = SegNotSourceAligned|SegNotTargetAligned;
@ -202,6 +203,7 @@ namespace Anabatic {
inline bool isTerminal () const;
inline bool isUnbreakable () const;
inline bool isNonPref () const;
inline bool isNonPrefOnVSmall () const;
inline bool isDrag () const;
inline bool isAtMinArea () const;
inline bool isNotSourceAligned () const;
@ -536,6 +538,7 @@ namespace Anabatic {
inline bool AutoSegment::isLocal () const { return not (_flags & SegGlobal); }
inline bool AutoSegment::isUnbreakable () const { return _flags & SegUnbreakable; }
inline bool AutoSegment::isNonPref () const { return _flags & SegNonPref; }
inline bool AutoSegment::isNonPrefOnVSmall () const { return (_flags & SegNonPref) and (_flags & SegOnVSmall); }
inline bool AutoSegment::isBipoint () const { return _flags & SegBipoint; }
inline bool AutoSegment::isWeakTerminal () const { return (_rpDistance < 2); }
inline bool AutoSegment::isWeakTerminal1 () const { return (_rpDistance == 1); }

View File

@ -110,6 +110,7 @@ namespace Anabatic {
static const BaseFlags NoMinLength ;
static const BaseFlags NoSegExt ;
static const BaseFlags NullLength ;
static const BaseFlags OnVSmall ;
public:
inline Flags ( uint64_t flags = NoFlags );
inline Flags ( const Hurricane::BaseFlags& );

View File

@ -11,8 +11,7 @@
list(INSERT CMAKE_MODULE_PATH 0 "${Bootstrap_SOURCE_DIR}/cmake_modules/")
find_package(Bootstrap REQUIRED)
# find_package(Python 3 REQUIRED COMPONENTS Interpreter Development )
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development )
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development.Module )
find_package(PythonSitePackages REQUIRED)
print_cmake_module_path()

View File

@ -20,6 +20,7 @@
srcDir=${HOME}${nightly}/coriolis-2.x/src/alliance/alliance/src
commonRoot=${HOME}${nightly}/coriolis-2.x/${arch}/Release.Shared
#commonRoot=${HOME}${nightly}/coriolis-2.x/${arch}/Debug.Shared
buildDir=${commonRoot}/build
installDir=${commonRoot}/install

View File

@ -24,8 +24,9 @@ projects = [
#, "knik"
#, "katabatic"
#, "kite"
, "equinox"
, "solstice"
#, "equinox"
#, "solstice"
, "tramontana"
, "oroshi"
, "bora"
, "karakaze"

View File

@ -35,6 +35,7 @@ class Builder:
self._noCache = False
self._ninja = False
self._clang = False
self._manylinux = False
self._noSystemBoost = False
self._macports = False
self._devtoolset = 0
@ -62,6 +63,7 @@ class Builder:
elif attribute == "noCache": self._noCache = value
elif attribute == "ninja": self._ninja = value
elif attribute == "clang": self._clang = value
elif attribute == "manylinux": self._manylinux = value
elif attribute == "macports":
self._macports = value
if value: self._noSystemBoost = True
@ -177,6 +179,7 @@ class Builder:
if self._bfd: command += [ "-D", "USE_LIBBFD:STRING=%s" % self._bfd ]
if self._qt4: command += [ "-D", "WITH_QT4:STRING=TRUE" ]
if self._openmp: command += [ "-D", "WITH_OPENMP:STRING=TRUE" ]
if self._manylinux: command += [ "-D", "USE_MANYLINUX:STRING=TRUE" ]
command += [ "-D", "CMAKE_BUILD_TYPE:STRING=%s" % self.buildMode
#, "-D", "BUILD_SHARED_LIBS:STRING=%s" % self.enableShared
, "-D", "CMAKE_INSTALL_PREFIX:STRING=%s" % self.installDir

View File

@ -211,6 +211,7 @@ parser.add_option ( "--bfd" , action="store_true" ,
parser.add_option ( "--openmp" , action="store_true" , dest="openmp" , help="Enable the use of OpenMP in Gcc." )
parser.add_option ( "--ninja" , action="store_true" , dest="ninja" , help="Use Ninja instead of UNIX Makefile." )
parser.add_option ( "--clang" , action="store_true" , dest="clang" , help="Force use of Clang C/C++ compiler instead of system default." )
parser.add_option ( "--manylinux" , action="store_true" , dest="manylinux" , help="Build target is manylinux (PyPY)." )
parser.add_option ( "--make" , action="store" , type="string", dest="makeArguments" , help="Arguments to pass to make (ex: \"-j4 install\")." )
parser.add_option ( "--project" , action="append" , type="string", dest="projects" , help="The name of a project to build (may appears any number of time)." )
parser.add_option ( "-t", "--tool" , action="append" , type="string", dest="tools" , help="The name of a tool to build (may appears any number of time)." )
@ -282,6 +283,7 @@ else:
if options.llvmtoolset: builder.llvmtoolset = options.llvmtoolset
if options.bfd: builder.bfd = "ON"
if options.qt4: builder.qt4 = True
if options.manylinux: builder.manylinux = True
if options.openmp: builder.openmp = True
if options.makeArguments: builder.makeArguments = options.makeArguments
#if options.svnMethod: builder.svnMethod = options.svnMethod

View File

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

View File

@ -223,6 +223,20 @@ endif()
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.
#

View File

@ -0,0 +1,38 @@
# - Find the Coloquinte includes and libraries.
# The following variables are set if Coriolis is found. If COLOQUINTE is not
# found, COLOQUINTE_FOUND is set to false.
# COLOQUINTE_FOUND - True when the Coriolis include directory is found.
# COLOQUINTE_INCLUDE_DIR - the path to where the Coriolis include files are.
# COLOQUINTE_LIBRARIES - The path to where the Coriolis library files are.
SET(COLOQUINTE_INCLUDE_PATH_DESCRIPTION "directory containing the Coloquinte include files. E.g /usr/local/include/coriolis2 or /asim/coriolis/include/coriolis2")
SET(COLOQUINTE_DIR_MESSAGE "Set the COLOQUINTE_INCLUDE_DIR cmake cache entry to the ${COLOQUINTE_INCLUDE_PATH_DESCRIPTION}")
# don't even bother under WIN32
IF(UNIX)
#
# Look for an installation.
#
FIND_PATH(COLOQUINTE_INCLUDE_PATH NAMES coloquinte/coloquinte.hpp PATHS
# Look in other places.
${CORIOLIS_DIR_SEARCH}
PATH_SUFFIXES include/coriolis2
# Help the user find it if we cannot.
DOC "The ${COLOQUINTE_INCLUDE_PATH_DESCRIPTION}"
)
MESSAGE( "COL ${COLOQUINTE_INCLUDE_PATH}" )
FIND_LIBRARY(COLOQUINTE_LIBRARY_PATH
NAMES coloquinte
PATHS ${CORIOLIS_DIR_SEARCH}
PATH_SUFFIXES lib64 lib
# Help the user find it if we cannot.
DOC "The ${COLOQUINTE_INCLUDE_PATH_DESCRIPTION}"
)
SET_LIBRARIES_PATH(COLOQUINTE COLOQUINTE)
HURRICANE_CHECK_LIBRARIES(COLOQUINTE)
ENDIF(UNIX)

View File

@ -284,6 +284,16 @@ class GitRepository ( object ):
Command( [ 'git', 'checkout', branch ], self.fdLog ).execute()
return
def submoduleInit ( self ):
os.chdir( self.localRepoDir )
Command( [ 'git', 'submodule', 'init' ], self.fdLog ).execute()
return
def submoduleUpdate ( self ):
os.chdir( self.localRepoDir )
Command( [ 'git', 'submodule', 'update' ], self.fdLog ).execute()
return
class Configuration ( object ):
@ -303,7 +313,7 @@ class Configuration ( object ):
def __init__ ( self ):
self._sender = 'Jean-Paul.Chaput@soc.lip6.fr'
self._receivers = [ 'Jean-Paul.Chaput@lip6.fr', ]
self._supportRepos = [ 'http://github.com/miloyip/rapidjson' ]
self._supportRepos = [ 'https://github.com/Tencent/rapidjson.git' ]
self._allianceRepo = 'https://gitlab.lip6.fr/jpc/alliance.git'
self._coriolisRepo = 'https://gitlab.lip6.fr/jpc/coriolis.git'
self._benchsRepo = 'https://gitlab.lip6.fr/jpc/alliance-check-toolkit.git'
@ -601,6 +611,8 @@ try:
if conf.rmSource: gitCoriolis.removeLocalRepo()
gitCoriolis.clone ()
gitCoriolis.checkout( 'devel' )
gitCoriolis.submoduleInit()
gitCoriolis.submoduleUpdate()
if conf.rmSource: gitBenchs.removeLocalRepo()
gitBenchs.clone()

View File

@ -18,9 +18,9 @@
setup_boost(program_options)
setup_qt()
setup_qwt()
setup_python()
find_package(Libexecinfo REQUIRED)
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
find_package(PythonSitePackages REQUIRED)
find_package(LEFDEF REQUIRED)
find_package(FLUTE REQUIRED)

View File

@ -21,6 +21,7 @@
setup_sysconfdir("${CMAKE_INSTALL_PREFIX}")
setup_boost(program_options)
setup_qt()
setup_python()
cmake_policy(SET CMP0054 NEW)
@ -28,7 +29,6 @@
find_package(Libbfd)
endif()
find_package(BZip2 REQUIRED)
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
find_package(PythonSitePackages REQUIRED)
find_package(BISON REQUIRED)
find_package(FLEX REQUIRED)

View File

@ -11,6 +11,7 @@ from coriolis.CRL import AllianceFramework, Gds, LefImport, CellGa
RoutingGauge, RoutingLayerGauge
from coriolis.helpers import l, u, n, overlay, io, ndaTopDir
from coriolis.helpers.overlay import CfgCache, UpdateSession
from coriolis.Anabatic import StyleFlags
__all__ = [ "setup" ]
@ -27,7 +28,7 @@ def _routing ():
rg.setSymbolic( False )
rg.addLayerGauge(
RoutingLayerGauge.create( tech.getLayer( 'Metal1' ) # metal
, RoutingLayerGauge.Vertical # preferred routing direction
, RoutingLayerGauge.Horizontal # preferred routing direction
, RoutingLayerGauge.PinOnly # layer usage
, 0 # depth
, 0.0 # density (deprecated)
@ -39,7 +40,7 @@ def _routing ():
, u(0.0 ) )) # obstacle dW
rg.addLayerGauge(
RoutingLayerGauge.create( tech.getLayer( 'Metal2' ) # metal
, RoutingLayerGauge.Horizontal # preferred routing direction
, RoutingLayerGauge.Vertical # preferred routing direction
, RoutingLayerGauge.Default # layer usage
, 1 # depth
, 0.0 # density (deprecated)
@ -48,10 +49,10 @@ def _routing ():
, u(0.28) # wire width
, u(0.28) # perpandicular wire width
, u(0.26) # VIA side
, u(0.0 ) )) # obstacle dW
, u(0.0 ) )) # obstacle dW
rg.addLayerGauge(
RoutingLayerGauge.create( tech.getLayer( 'Metal3' ) # metal
, RoutingLayerGauge.Vertical # preferred routing direction
, RoutingLayerGauge.Horizontal # preferred routing direction
, RoutingLayerGauge.Default # layer usage
, 2 # depth
, 0.0 # density (deprecated)
@ -63,7 +64,7 @@ def _routing ():
, u(0.0 ) )) # obstacle dW
rg.addLayerGauge(
RoutingLayerGauge.create( tech.getLayer( 'Metal4' ) # metal
, RoutingLayerGauge.Horizontal # preferred routing direction
, RoutingLayerGauge.Vertical # preferred routing direction
, RoutingLayerGauge.Default # layer usage
, 3 # depth
, 0.0 # density (deprecated)
@ -75,7 +76,7 @@ def _routing ():
, u(0.0 ) )) # obstacle dW
rg.addLayerGauge(
RoutingLayerGauge.create( tech.getLayer( 'Metal5' ) # metal
, RoutingLayerGauge.Vertical # preferred routing direction
, RoutingLayerGauge.Horizontal # preferred routing direction
, RoutingLayerGauge.Default # layer usage
, 4 # depth
, 0.0 # density (deprecated)
@ -87,7 +88,7 @@ def _routing ():
, u(0.0 ) )) # obstacle dW
rg.addLayerGauge(
RoutingLayerGauge.create( tech.getLayer( 'MetalTop' ) # metal
, RoutingLayerGauge.Horizontal # preferred routing direction
, RoutingLayerGauge.Vertical # preferred routing direction
, RoutingLayerGauge.PowerSupply # layer usage
, 5 # depth
, 0.0 # density (deprecated)
@ -161,7 +162,9 @@ def _routing ():
cfg.anabatic.globalIterations = [ 1, 100 ]
cfg.anabatic.gcell.displayMode = 1
cfg.anabatic.gcell.displayMode = (("Boundary", 1), ("Density", 2))
cfg.katana.disableStackedVias = True
cfg.anabatic.netBuilderStyle = 'VH,3RL+'
cfg.anabatic.routingStyle = StyleFlags.VH
cfg.katana.disableStackedVias = False
cfg.katana.hTracksReservedLocal = 4
cfg.katana.hTracksReservedLocal = [0, 20]
cfg.katana.vTracksReservedLocal = 3

View File

@ -80,20 +80,20 @@ def _setup_techno():
setEnclosures( CONT, Poly2 , u(0.07) )
setEnclosures( CONT, Metal1, u(0.12) )
VIA12 = createVia( tech, 'VIA12', 'Metal1', 'Via1', 'Metal2', u(0.26) )
setEnclosures( VIA12, Metal1, u(0.06) )
setEnclosures( VIA12, Metal2, u(0.06) )
setEnclosures( VIA12, Metal1, (u(0.06), u(0.00)) )
setEnclosures( VIA12, Metal2, (u(0.06), u(0.01)) )
VIA23 = createVia( tech, 'VIA23', 'Metal2', 'Via2', 'Metal3', u(0.26) )
setEnclosures( VIA23, Metal2, u(0.06) )
setEnclosures( VIA23, Metal3, u(0.06) )
setEnclosures( VIA23, Metal2, (u(0.06), u(0.01)) )
setEnclosures( VIA23, Metal3, (u(0.01), u(0.06)) )
VIA34 = createVia( tech, 'VIA34', 'Metal3', 'Via3', 'Metal4', u(0.26) )
setEnclosures( VIA34, Metal3, u(0.06) )
setEnclosures( VIA34, Metal4, u(0.06) )
setEnclosures( VIA34, Metal3, (u(0.01), u(0.06)) )
setEnclosures( VIA34, Metal4, (u(0.06), u(0.01)) )
VIA45 = createVia( tech, 'VIA45', 'Metal4', 'Via4', 'Metal5', u(0.26) )
setEnclosures( VIA45, Metal4, u(0.06) )
setEnclosures( VIA45, Metal5, u(0.06) )
setEnclosures( VIA45, Metal4, (u(0.06), u(0.01)) )
setEnclosures( VIA45, Metal5, (u(0.01), u(0.06)) )
VIA5T = createVia( tech, 'VIA5T', 'Metal5', 'Via5', 'MetalTop', u(0.26) )
setEnclosures( VIA5T, Metal5 , u(0.06) )
setEnclosures( VIA5T, MetalTop, u(0.06) )
setEnclosures( VIA5T, Metal5 , (u(0.01), u(0.06)) )
setEnclosures( VIA5T, MetalTop, (u(0.06), u(0.01)) )
Border = createBL( tech, 'Border', BasicLayer.Material.other, gds2Layer=63 )

View File

@ -0,0 +1,42 @@
# This file is part of the Coriolis Software.
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | Alliance / Hurricane Interface |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./etc/symbolic/lcmos/__init__.py" |
# +-----------------------------------------------------------------+
import coriolis.Cfg as Cfg
from coriolis.helpers import truncPath, tagConfModules
from coriolis.helpers.io import vprint
vprint( 1, ' o Loading "symbolic.lcmos" technology.' )
vprint( 2, ' - "%s".' % truncPath(__file__) )
from coriolis.Hurricane import DataBase
from coriolis.CRL import System
Cfg.Configuration.pushDefaultPriority( Cfg.Parameter.Priority.ConfigurationFile )
if not DataBase.getDB(): DataBase.create()
System.get()
from . import misc
from . import technology
from . import display
from . import analog
from . import alliance
from . import etesian
from . import kite
from . import plugins
from . import stratus1
Cfg.Configuration.popDefaultPriority()
tagConfModules()

View File

@ -0,0 +1,56 @@
# This file is part of the Coriolis Software.
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | Alliance / Hurricane Interface |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./etc/symbolic/lcmos/alliance.py" |
# +-----------------------------------------------------------------+
import os
import os.path
from coriolis.helpers import truncPath
from coriolis.helpers.io import vprint
vprint( 2, ' - "{}".'.format(truncPath(__file__)) )
from coriolis.CRL import Environment, AllianceFramework
allianceTop = None
if 'ALLIANCE_TOP' in os.environ:
allianceTop = os.environ['ALLIANCE_TOP']
if not os.path.isdir(allianceTop):
allianceTop = None
if not allianceTop: allianceTop = '/soc/alliance'
cellsTop = allianceTop+'/cells'
af = AllianceFramework.get()
env = af.getEnvironment()
env.setSCALE_X ( 100 )
env.setCATALOG ( 'CATAL' )
env.setIN_LO ( 'vst' )
env.setIN_PH ( 'ap' )
env.setOUT_LO ( 'vst' )
env.setOUT_PH ( 'ap' )
env.setPOWER ( 'vdd' )
env.setGROUND ( 'vss' )
env.setCLOCK ( '.*ck.*|.*nck.*' )
env.setBLOCKAGE ( 'blockage[Nn]et.*' )
env.setPad ( '.*_px$' )
env.setRegister ( 'sff.*' )
env.setWORKING_LIBRARY( '.' )
env.addSYSTEM_LIBRARY ( library=cellsTop+'/sxlib' , mode=Environment.Append )
env.addSYSTEM_LIBRARY ( library=cellsTop+'/dp_sxlib', mode=Environment.Append )
env.addSYSTEM_LIBRARY ( library=cellsTop+'/ramlib' , mode=Environment.Append )
env.addSYSTEM_LIBRARY ( library=cellsTop+'/romlib' , mode=Environment.Append )
env.addSYSTEM_LIBRARY ( library=cellsTop+'/rflib' , mode=Environment.Append )
env.addSYSTEM_LIBRARY ( library=cellsTop+'/rf2lib' , mode=Environment.Append )
env.addSYSTEM_LIBRARY ( library=cellsTop+'/pxlib' , mode=Environment.Append )
env.addSYSTEM_LIBRARY ( library=cellsTop+'/padlib' , mode=Environment.Append )

View File

@ -0,0 +1,20 @@
# This file is part of the Coriolis Software.
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | Alliance / Hurricane Interface |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./etc/symbolic/lcmos/analog.py" |
# +-----------------------------------------------------------------+
from coriolis.helpers import truncPath
from coriolis.helpers.io import vprint
vprint( 2, ' - "%s".' % truncPath(__file__) )
from ...common import analog

View File

@ -0,0 +1,474 @@
# This file is part of the Coriolis Software.
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | Alliance / Hurricane Interface |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./etc/symbolic/lcmos/display.py" |
# +-----------------------------------------------------------------+
from coriolis.helpers import truncPath
from coriolis.helpers.io import vprint
import coriolis.Cfg as Cfg
import coriolis.Viewer as Viewer
from coriolis.helpers import overlay, l, u, n
from coriolis.technos.common.colors import toRGB
from coriolis.technos.common.patterns import toHexa
vprint( 2, ' - "%s".' % truncPath(__file__) )
def createStyles ( scale=1.0 ):
with overlay.CfgCache(priority=Cfg.Parameter.Priority.UserFile) as cfg:
cfg.viewer.minimumSize = 500
cfg.viewer.pixelThreshold = 5
# ----------------------------------------------------------------------
# Style: Alliance.Coriolis [black].
style = Viewer.DisplayStyle( 'Alliance.Coriolis [black]' )
style.setDescription( 'Alliance Coriolis Look - black background' )
style.setDarkening ( Viewer.DisplayStyle.HSVr(1.0, 3.0, 2.5) )
style.addDrawingStyle( group='Viewer', name='fallback' , color=toRGB('Gray238' ), border=1, pattern='55AA55AA55AA55AA' )
style.addDrawingStyle( group='Viewer', name='background' , color=toRGB('Gray50' ), border=1 )
style.addDrawingStyle( group='Viewer', name='foreground' , color=toRGB('White' ), border=1 )
style.addDrawingStyle( group='Viewer', name='rubber' , color=toRGB('192,0,192' ), border=2, threshold=0.02*scale )
style.addDrawingStyle( group='Viewer', name='phantom' , color=toRGB('Seashell4' ), border=1 )
style.addDrawingStyle( group='Viewer', name='boundaries' , color=toRGB('208,199,192'), border=1, pattern='0000000000000000', threshold=0 )
style.addDrawingStyle( group='Viewer', name='marker' , color=toRGB('80,250,80' ), border=1 )
style.addDrawingStyle( group='Viewer', name='selectionDraw' , color=toRGB('White' ), border=1 )
style.addDrawingStyle( group='Viewer', name='selectionFill' , color=toRGB('White' ), border=1 )
style.addDrawingStyle( group='Viewer', name='grid' , color=toRGB('White' ), border=1, threshold=2.0*scale )
style.addDrawingStyle( group='Viewer', name='spot' , color=toRGB('White' ), border=2, threshold=6.0*scale )
style.addDrawingStyle( group='Viewer', name='ghost' , color=toRGB('White' ), border=1 )
style.addDrawingStyle( group='Viewer', name='text.ruler' , color=toRGB('White' ), border=1, threshold=0.0*scale )
style.addDrawingStyle( group='Viewer', name='text.instance' , color=toRGB('Black' ), border=1, threshold=4.0*scale )
style.addDrawingStyle( group='Viewer', name='text.reference' , color=toRGB('White' ), border=1, threshold=20.0*scale )
style.addDrawingStyle( group='Viewer', name='undef' , color=toRGB('Violet' ), border=0, pattern='2244118822441188' )
style.addDrawingStyle( group='Viewer', name='mauka.container', color=toRGB('Magenta4' ), border=4, pattern='0000000000000000', goMatched=False )
# Group: Active Layer.
style.addDrawingStyle( group='Active Layer', name='nWell' , color=toRGB('Tan' ), pattern='55AA55AA55AA55AA' , threshold=1.5 *scale )
style.addDrawingStyle( group='Active Layer', name='pWell' , color=toRGB('LightYellow'), pattern='55AA55AA55AA55AA' , threshold=1.50*scale )
style.addDrawingStyle( group='Active Layer', name='nImplant', color=toRGB('LawnGreen' ), pattern='55AA55AA55AA55AA' , threshold=1.50*scale )
style.addDrawingStyle( group='Active Layer', name='pImplant', color=toRGB('Yellow' ), pattern='55AA55AA55AA55AA' , threshold=1.50*scale )
style.addDrawingStyle( group='Active Layer', name='active' , color=toRGB('White' ), pattern=toHexa('antihash1.8'), threshold=1.50*scale )
style.addDrawingStyle( group='Active Layer', name='poly' , color=toRGB('Red' ), pattern='55AA55AA55AA55AA' , threshold=1.50*scale )
# Group: Routing Layer.
style.addDrawingStyle( group='Routing Layer', name='metal1' , color=toRGB('Blue' ), pattern=toHexa('poids2.8' ), threshold=0.80*scale )
style.addDrawingStyle( group='Routing Layer', name='metal2' , color=toRGB('Aqua' ), pattern=toHexa('light_antihash0.8'), threshold=0.02*scale )
style.addDrawingStyle( group='Routing Layer', name='metal3' , color=toRGB('LightPink'), pattern=toHexa('light_antihash1.8'), threshold=0.02*scale )
style.addDrawingStyle( group='Routing Layer', name='metal4' , color=toRGB('Green' ), pattern=toHexa('light_antihash2.8'), threshold=0.02*scale )
style.addDrawingStyle( group='Routing Layer', name='metal5' , color=toRGB('Yellow' ), pattern='1144114411441144' , threshold=0.02*scale )
style.addDrawingStyle( group='Routing Layer', name='metal6' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.02*scale )
style.addDrawingStyle( group='Routing Layer', name='metal7' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.02*scale )
style.addDrawingStyle( group='Routing Layer', name='metal8' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.02*scale )
style.addDrawingStyle( group='Routing Layer', name='metal9' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.02*scale )
style.addDrawingStyle( group='Routing Layer', name='metal10', color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.02*scale )
# Group: Cuts (VIA holes).
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut0', color=toRGB('0,150,150'), threshold=1.50*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut1', color=toRGB('Aqua' ), threshold=0.80*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut2', color=toRGB('LightPink'), threshold=0.80*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut3', color=toRGB('Green' ), threshold=0.80*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut4', color=toRGB('Yellow' ), threshold=0.80*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut5', color=toRGB('Violet' ), threshold=0.80*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut6', color=toRGB('Violet' ), threshold=0.80*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut7', color=toRGB('Violet' ), threshold=0.80*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut8', color=toRGB('Violet' ), threshold=0.80*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut9', color=toRGB('Violet' ), threshold=0.80*scale )
# Group: MIM6.
style.addDrawingStyle( group='MIM6', name='metbot_r', color=toRGB('Aqua' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale )
style.addDrawingStyle( group='MIM6', name='cut6' , color=toRGB('LightPink'), pattern=toHexa('light_antihash1.8'), threshold=0.80*scale )
style.addDrawingStyle( group='MIM6', name='metal7' , color=toRGB('Green' ), pattern=toHexa('light_antihash2.8'), threshold=0.80*scale )
# Group: Blockages.
style.addDrawingStyle( group='Blockages', name='blockage1' , color=toRGB('Blue' ), pattern='006070381c0e0703' , threshold=0.80*scale, border=2 )
style.addDrawingStyle( group='Blockages', name='blockage2' , color=toRGB('Aqua' ), pattern='8103060c183060c0' , threshold=0.80*scale, border=2 )
style.addDrawingStyle( group='Blockages', name='blockage3' , color=toRGB('LightPink'), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=2 )
style.addDrawingStyle( group='Blockages', name='blockage4' , color=toRGB('Green' ), pattern=toHexa('light_antihash2.8'), threshold=0.80*scale, border=2 )
style.addDrawingStyle( group='Blockages', name='blockage5' , color=toRGB('Yellow' ), pattern='1144114411441144' , threshold=0.80*scale, border=2 )
style.addDrawingStyle( group='Blockages', name='blockage6' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
style.addDrawingStyle( group='Blockages', name='blockage7' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
style.addDrawingStyle( group='Blockages', name='blockage8' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
style.addDrawingStyle( group='Blockages', name='blockage9' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
style.addDrawingStyle( group='Blockages', name='blockage10', color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
# Group: Knik & Kite.
style.addDrawingStyle( group='Knik & Kite', name='SPL1' , color=toRGB('Red' ) )
style.addDrawingStyle( group='Knik & Kite', name='AutoLayer' , color=toRGB('Magenta' ) )
style.addDrawingStyle( group='Knik & Kite', name='gmetalh' , color=toRGB('128,255,200'), pattern=toHexa('light_antihash0.8'), border=1 )
style.addDrawingStyle( group='Knik & Kite', name='gmetalv' , color=toRGB('200,200,255'), pattern=toHexa('light_antihash1.8'), border=1 )
style.addDrawingStyle( group='Knik & Kite', name='gcut' , color=toRGB('255,255,190'), border=1 )
style.addDrawingStyle( group='Knik & Kite', name='Anabatic::Edge' , color=toRGB('255,255,190'), pattern='0000000000000000', threshold=0.02*scale, border=4 )
style.addDrawingStyle( group='Knik & Kite', name='Anabatic::GCell', color=toRGB('255,0,0' ), pattern='0000000000000000', threshold=0.02*scale, border=4 )
Viewer.Graphics.addStyle( style )
# ----------------------------------------------------------------------
# Style: Alliance.Coriolis [white].
style = Viewer.DisplayStyle( 'Alliance.Coriolis [white]' )
style.inheritFrom( 'Alliance.Coriolis [black]' )
style.setDescription( 'Alliance Coriolis Look - white background' )
style.setDarkening ( Viewer.DisplayStyle.HSVr(1.0, 3.0, 2.5) )
style.addDrawingStyle( group='Viewer', name='fallback' , color=toRGB('Gray238' ), border=1, pattern='55AA55AA55AA55AA' )
style.addDrawingStyle( group='Viewer', name='background' , color=toRGB('Gray50' ), border=1 )
style.addDrawingStyle( group='Viewer', name='foreground' , color=toRGB('White' ), border=1 )
style.addDrawingStyle( group='Viewer', name='rubber' , color=toRGB('192,0,192' ), border=4, threshold=0.02*scale )
style.addDrawingStyle( group='Viewer', name='phantom' , color=toRGB('Seashell4' ), border=1 )
style.addDrawingStyle( group='Viewer', name='boundaries' , color=toRGB('208,199,192'), border=1, pattern='0000000000000000', threshold=0 )
style.addDrawingStyle( group='Viewer', name='marker' , color=toRGB('80,250,80' ), border=1 )
style.addDrawingStyle( group='Viewer', name='selectionDraw' , color=toRGB('White' ), border=1 )
style.addDrawingStyle( group='Viewer', name='selectionFill' , color=toRGB('White' ), border=1 )
style.addDrawingStyle( group='Viewer', name='grid' , color=toRGB('White' ), border=1, threshold=2.0*scale )
style.addDrawingStyle( group='Viewer', name='spot' , color=toRGB('White' ), border=2, threshold=6.0*scale )
style.addDrawingStyle( group='Viewer', name='ghost' , color=toRGB('White' ), border=1 )
style.addDrawingStyle( group='Viewer', name='text.ruler' , color=toRGB('White' ), border=1, threshold=0.0 *scale )
style.addDrawingStyle( group='Viewer', name='text.instance' , color=toRGB('White' ), border=1, threshold=400.0 *scale )
style.addDrawingStyle( group='Viewer', name='text.reference', color=toRGB('White' ), border=1, threshold=200.0*scale )
style.addDrawingStyle( group='Viewer', name='undef' , color=toRGB('Violet' ), border=0, pattern='2244118822441188' )
# Active Layers.
style.addDrawingStyle( group='Active Layer', name='nWell' , color=toRGB('Tan' ), pattern=toHexa('urgo.8' ), border=1, threshold=0*scale )
style.addDrawingStyle( group='Active Layer', name='pWell' , color=toRGB('LightYellow'), pattern=toHexa('urgo.8' ), border=1, threshold=0*scale )
style.addDrawingStyle( group='Active Layer', name='nImplant', color=toRGB('LawnGreen' ), pattern=toHexa('antihash0.8'), border=1, threshold=0*scale )
style.addDrawingStyle( group='Active Layer', name='pImplant', color=toRGB('Yellow' ), pattern=toHexa('antihash0.8'), border=1, threshold=0*scale )
style.addDrawingStyle( group='Active Layer', name='active' , color=toRGB('White' ), pattern=toHexa('antihash1.8'), border=1, threshold=0*scale )
style.addDrawingStyle( group='Active Layer', name='poly' , color=toRGB('Red' ), pattern=toHexa('poids2.8' ), border=1, threshold=0*scale )
style.addDrawingStyle( group='Active Layer', name='poly2' , color=toRGB('Orange' ), pattern=toHexa('poids2.8' ), border=1, threshold=0*scale )
# Routing Layers.
style.addDrawingStyle( group='Routing Layer', name='metal1' , color=toRGB('Blue' ), pattern=toHexa('slash.8' ), border=1, threshold=0.0*scale )
style.addDrawingStyle( group='Routing Layer', name='metal2' , color=toRGB('Aqua' ), pattern=toHexa('poids4.8'), border=1, threshold=0.0*scale )
style.addDrawingStyle( group='Routing Layer', name='metcap' , color=toRGB('DarkTurquoise'), pattern=toHexa('poids2.8'), border=2, threshold=0.0*scale )
style.addDrawingStyle( group='Routing Layer', name='metal3' , color=toRGB('LightPink' ), pattern=toHexa('poids4.8'), border=1, threshold=0.0*scale )
style.addDrawingStyle( group='Routing Layer', name='metal4' , color=toRGB('Green' ), pattern=toHexa('poids4.8'), border=1, threshold=0.0*scale )
style.addDrawingStyle( group='Routing Layer', name='metal5' , color=toRGB('Yellow' ), pattern=toHexa('poids4.8'), border=1, threshold=0.0*scale )
style.addDrawingStyle( group='Routing Layer', name='metal6' , color=toRGB('Violet' ), pattern=toHexa('poids4.8'), border=1, threshold=0.0*scale )
style.addDrawingStyle( group='Routing Layer', name='metal7' , color=toRGB('Red' ), pattern=toHexa('poids4.8'), border=1, threshold=0.0*scale )
style.addDrawingStyle( group='Routing Layer', name='metal8' , color=toRGB('Blue' ), pattern=toHexa('poids4.8'), border=1, threshold=0.0*scale )
style.addDrawingStyle( group='Routing Layer', name='metal9' , color=toRGB('Blue' ), pattern=toHexa('poids4.8'), border=1, threshold=0.0*scale )
style.addDrawingStyle( group='Routing Layer', name='metal10', color=toRGB('Blue' ), pattern=toHexa('poids4.8'), border=1, threshold=0.0*scale )
# Cuts (VIA holes).
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut0', color=toRGB('0,150,150'), threshold=0*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut1', color=toRGB('Aqua' ), threshold=0.0*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut2', color=toRGB('LightPink'), threshold=0.0*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut3', color=toRGB('Green' ), threshold=0.0*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut4', color=toRGB('Yellow' ), threshold=0.0*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut5', color=toRGB('Violet' ), threshold=0.0*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut6', color=toRGB('Red' ), threshold=0.0*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut7', color=toRGB('Blue' ), threshold=0.0*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut8', color=toRGB('Blue' ), threshold=0.0*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut9', color=toRGB('Blue' ), threshold=0.0*scale )
# MIM6.
style.addDrawingStyle( group='MIM6', name='metbot_r', color=toRGB('Aqua' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale )
style.addDrawingStyle( group='MIM6', name='metal7' , color=toRGB('Green'), pattern=toHexa('light_antihash2.8'), threshold=0.80*scale )
# Blockages.
style.addDrawingStyle( group='Blockages', name='blockage1' , color=toRGB('Blue' ), pattern=toHexa('light_antislash0.8'), threshold=0.80*scale, border=4 )
style.addDrawingStyle( group='Blockages', name='blockage2' , color=toRGB('Aqua' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
style.addDrawingStyle( group='Blockages', name='blockage3' , color=toRGB('LightPink'), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
style.addDrawingStyle( group='Blockages', name='blockage4' , color=toRGB('Green' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
style.addDrawingStyle( group='Blockages', name='blockage5' , color=toRGB('Yellow' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
style.addDrawingStyle( group='Blockages', name='blockage6' , color=toRGB('Violet' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
style.addDrawingStyle( group='Blockages', name='blockage7' , color=toRGB('Red' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
style.addDrawingStyle( group='Blockages', name='blockage8' , color=toRGB('Blue' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
style.addDrawingStyle( group='Blockages', name='blockage9' , color=toRGB('Blue' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
style.addDrawingStyle( group='Blockages', name='blockage10', color=toRGB('Blue' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
# Knick & Kite.
style.addDrawingStyle( group='Knik & Kite', name='SPL1' , color=toRGB('Red' ) )
style.addDrawingStyle( group='Knik & Kite', name='AutoLayer' , color=toRGB('Magenta' ) )
style.addDrawingStyle( group='Knik & Kite', name='gmetalh' , color=toRGB('128,255,200'), pattern=toHexa('antislash2.32' ), border=1 )
style.addDrawingStyle( group='Knik & Kite', name='gmetalv' , color=toRGB('200,200,255'), pattern=toHexa('light_antihash1.8'), border=1 )
style.addDrawingStyle( group='Knik & Kite', name='gcut' , color=toRGB('255,255,190'), border=1 )
style.addDrawingStyle( group='Knik & Kite', name='Anabatic::Edge' , color=toRGB('255,255,190'), pattern='0000000000000000', border=4, threshold=0.02*scale )
style.addDrawingStyle( group='Knik & Kite', name='Anabatic::GCell', color=toRGB('255,255,190'), pattern='0000000000000000', border=2, threshold=0.10*scale )
Viewer.Graphics.addStyle( style )
# ----------------------------------------------------------------------
# Style: Alliance.Classic [black]
style = Viewer.DisplayStyle( 'Alliance.Classic [black]' )
style.setDescription( 'Alliance Classic Look - black background' )
style.setDarkening ( Viewer.DisplayStyle.HSVr(1.0, 3.0, 2.5) )
# Viewer.
style.addDrawingStyle( group='Viewer', name='fallback' , color=toRGB('Gray238' ), border=1, pattern='55AA55AA55AA55AA' )
style.addDrawingStyle( group='Viewer', name='background' , color=toRGB('Gray50' ), border=1 )
style.addDrawingStyle( group='Viewer', name='foreground' , color=toRGB('White' ), border=1 )
style.addDrawingStyle( group='Viewer', name='rubber' , color=toRGB('192,0,192' ), border=4, threshold=0.02*scale )
style.addDrawingStyle( group='Viewer', name='phantom' , color=toRGB('Seashell4' ), border=1 )
#style.addDrawingStyle( group='Viewer', name='boundaries' , color=toRGB('208,199,192'), border=2, threshold=0 )
style.addDrawingStyle( group='Viewer', name='boundaries' , color=toRGB('wheat1') , border=2, pattern='0000000000000000', threshold=0 )
style.addDrawingStyle( group='Viewer', name='marker' , color=toRGB('80,250,80' ), border=1 )
style.addDrawingStyle( group='Viewer', name='selectionDraw' , color=toRGB('White' ), border=1 )
style.addDrawingStyle( group='Viewer', name='selectionFill' , color=toRGB('White' ), border=1 )
style.addDrawingStyle( group='Viewer', name='grid' , color=toRGB('White' ), border=1, threshold=8.0*scale )
style.addDrawingStyle( group='Viewer', name='spot' , color=toRGB('White' ), border=2, threshold=6.0*scale )
style.addDrawingStyle( group='Viewer', name='ghost' , color=toRGB('White' ), border=1 )
style.addDrawingStyle( group='Viewer', name='text.ruler' , color=toRGB('White' ), border=1, threshold= 0.0*scale )
style.addDrawingStyle( group='Viewer', name='text.instance' , color=toRGB('White' ), border=1, threshold=400.0*scale )
style.addDrawingStyle( group='Viewer', name='text.reference', color=toRGB('White' ), border=1, threshold=200.0*scale )
style.addDrawingStyle( group='Viewer', name='undef' , color=toRGB('Violet' ), border=0, pattern='2244118822441188' )
# Active Layers.
style.addDrawingStyle( group='Active Layers', name='nWell' , color=toRGB('Tan' ), pattern=toHexa('urgo.8' ), border=1, threshold=0.00*scale )
style.addDrawingStyle( group='Active Layers', name='pWell' , color=toRGB('LightYellow'), pattern=toHexa('urgo.8' ), border=1, threshold=0.00*scale )
style.addDrawingStyle( group='Active Layers', name='nImplant', color=toRGB('LawnGreen' ), pattern=toHexa('antihash0.8'), border=1, threshold=0.00*scale )
style.addDrawingStyle( group='Active Layers', name='pImplant', color=toRGB('Yellow' ), pattern=toHexa('antihash0.8'), border=1, threshold=0.00*scale )
style.addDrawingStyle( group='Active Layers', name='active' , color=toRGB('White' ), pattern='0000000000000000' , border=1, threshold=0.00*scale )
style.addDrawingStyle( group='Active Layers', name='poly' , color=toRGB('Red' ), pattern=toHexa('poids2.8' ), border=1, threshold=0.00*scale )
style.addDrawingStyle( group='Active Layers', name='poly2' , color=toRGB('Orange' ), pattern=toHexa('poids2.8' ), border=1, threshold=0.00*scale )
# Routing Layers.
style.addDrawingStyle( group='Routing Layers', name='metal1' , color=toRGB('Blue' ), pattern=toHexa('slash.8' ), border=1, threshold=0.80*scale )
style.addDrawingStyle( group='Routing Layers', name='metal2' , color=toRGB('Aqua' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
style.addDrawingStyle( group='Routing Layers', name='metcap' , color=toRGB('DarkTurquoise'), pattern=toHexa('poids2.8' ), border=2, threshold=0.00*scale )
style.addDrawingStyle( group='Routing Layers', name='metal3' , color=toRGB('LightPink' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
style.addDrawingStyle( group='Routing Layers', name='metal4' , color=toRGB('Green' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
style.addDrawingStyle( group='Routing Layers', name='metal5' , color=toRGB('Yellow' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
style.addDrawingStyle( group='Routing Layers', name='metal6' , color=toRGB('Violet' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
style.addDrawingStyle( group='Routing Layers', name='metal7' , color=toRGB('Red' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
style.addDrawingStyle( group='Routing Layers', name='metal8' , color=toRGB('Blue' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
style.addDrawingStyle( group='Routing Layers', name='metal9' , color=toRGB('Blue' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
style.addDrawingStyle( group='Routing Layers', name='metal10', color=toRGB('Blue' ), pattern=toHexa('poids4.8' ), border=1, threshold=0.00*scale )
# Cuts (VIA holes).
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut0', color=toRGB('0,150,150'), threshold=0.0*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut1', color=toRGB('Aqua' ), threshold=0.0*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut2', color=toRGB('LightPink'), threshold=0.0*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut3', color=toRGB('Green' ), threshold=0.0*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut4', color=toRGB('Yellow' ), threshold=0.0*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut5', color=toRGB('Violet' ), threshold=0.0*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut6', color=toRGB('Red' ), threshold=0.0*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut7', color=toRGB('Blue' ), threshold=0.0*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut8', color=toRGB('Blue' ), threshold=0.0*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut9', color=toRGB('Blue' ), threshold=0.0*scale )
# MIM6.
style.addDrawingStyle( group='MIMI6', name='metbot_r', color=toRGB('Aqua' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale )
style.addDrawingStyle( group='MIMI6', name='metal7' , color=toRGB('Green'), pattern=toHexa('light_antihash2.8'), threshold=0.80*scale )
# Blockages.
style.addDrawingStyle( group='Blockages', name='blockage1' , color=toRGB('Blue' ), pattern=toHexa('light_antislash0.8'), threshold=0.80*scale, border=4 )
style.addDrawingStyle( group='Blockages', name='blockage2' , color=toRGB('Aqua' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
style.addDrawingStyle( group='Blockages', name='blockage3' , color=toRGB('LightPink'), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
style.addDrawingStyle( group='Blockages', name='blockage4' , color=toRGB('Green' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
style.addDrawingStyle( group='Blockages', name='blockage5' , color=toRGB('Yellow' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
style.addDrawingStyle( group='Blockages', name='blockage6' , color=toRGB('Violet' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
style.addDrawingStyle( group='Blockages', name='blockage7' , color=toRGB('Red' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
style.addDrawingStyle( group='Blockages', name='blockage8' , color=toRGB('Blue' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
style.addDrawingStyle( group='Blockages', name='blockage9' , color=toRGB('Blue' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
style.addDrawingStyle( group='Blockages', name='blockage10', color=toRGB('Blue' ), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=4 )
# Knick & Kite.
style.addDrawingStyle( group='Knik & Kite', name='SPL1' , color=toRGB('Red' ) )
style.addDrawingStyle( group='Knik & Kite', name='AutoLayer' , color=toRGB('Magenta' ) )
style.addDrawingStyle( group='Knik & Kite', name='gmetalh' , color=toRGB('128,255,200'), pattern=toHexa('antislash2.32' ), border=1 )
style.addDrawingStyle( group='Knik & Kite', name='gmetalv' , color=toRGB('200,200,255'), pattern=toHexa('light_antihash1.8'), border=1 )
style.addDrawingStyle( group='Knik & Kite', name='gcut' , color=toRGB('255,255,190'), border=1 )
style.addDrawingStyle( group='Knik & Kite', name='Anabatic::Edge' , color=toRGB('255,255,190'), pattern='0000000000000000' , border=4, threshold=0.02*scale )
style.addDrawingStyle( group='Knik & Kite', name='Anabatic::GCell', color=toRGB('255,255,190'), pattern='0000000000000000' , border=2, threshold=0.10*scale )
Viewer.Graphics.addStyle( style )
# ----------------------------------------------------------------------
# Style: Alliance.Classic [white].
style = Viewer.DisplayStyle( 'Alliance.Classic [white]' )
style.inheritFrom( 'Alliance.Classic [black]' )
style.setDescription( 'Alliance Classic Look - white background' )
style.setDarkening ( Viewer.DisplayStyle.HSVr(1.0, 3.0, 2.5) )
# Group: Viewer.
style.addDrawingStyle( group='Viewer', name='fallback' , color=toRGB('Black'), border=1, pattern='55AA55AA55AA55AA' )
style.addDrawingStyle( group='Viewer', name='background' , color=toRGB('White'), border=1 )
style.addDrawingStyle( group='Viewer', name='foreground' , color=toRGB('Black'), border=1 )
style.addDrawingStyle( group='Viewer', name='selectionDraw' , color=toRGB('Black'), border=1 )
style.addDrawingStyle( group='Viewer', name='selectionFill' , color=toRGB('Black'), border=1 )
style.addDrawingStyle( group='Viewer', name='grid' , color=toRGB('Black'), border=1, threshold=6.0*scale )
style.addDrawingStyle( group='Viewer', name='spot' , color=toRGB('Black'), border=1, threshold=6.0*scale )
style.addDrawingStyle( group='Viewer', name='ghost' , color=toRGB('Black'), border=1 )
style.addDrawingStyle( group='Viewer', name='text.ruler' , color=toRGB('Black'), border=1, threshold=0.0 *scale )
style.addDrawingStyle( group='Viewer', name='text.instance' , color=toRGB('Black'), border=1, threshold=4.0 *scale )
style.addDrawingStyle( group='Viewer', name='text.reference', color=toRGB('Black'), border=1, threshold=20.0*scale )
style.addDrawingStyle( group='Viewer', name='undef' , color=toRGB('Black'), border=0, pattern='2244118822441188' )
Viewer.Graphics.addStyle( style )
# ----------------------------------------------------------------------
# Style: Layout Design [black]
style = Viewer.DisplayStyle( 'Layout Design [black]' )
style.inheritFrom( 'Alliance.Classic [black]' )
style.setDescription( 'Alliance Classic Look - white background' )
style.setDarkening ( Viewer.DisplayStyle.HSVr(1.0, 3.0, 2.5) )
# Active Layers.
style.addDrawingStyle( group='Active Layers', name='nWell' , color=toRGB('Tan' ), pattern='0000000000000000', threshold=1.50*scale, border=2 )
style.addDrawingStyle( group='Active Layers', name='pWell' , color=toRGB('LightYellow'), pattern='0000000000000000', threshold=1.50*scale, border=2 )
style.addDrawingStyle( group='Active Layers', name='nImplant', color=toRGB('LawnGreen' ), pattern='0000000000000000', threshold=1.50*scale, border=2 )
style.addDrawingStyle( group='Active Layers', name='pImplant', color=toRGB('Yellow' ), pattern='0000000000000000', threshold=1.50*scale, border=2 )
style.addDrawingStyle( group='Active Layers', name='active' , color=toRGB('White' ), pattern='0000000000000000', threshold=1.50*scale, border=2 )
style.addDrawingStyle( group='Active Layers', name='poly' , color=toRGB('Red' ), pattern='0000000000000000', threshold=1.50*scale, border=2 )
# Routing Layers.
style.addDrawingStyle( group='Routing Layers', name='metal1' , color=toRGB('Blue' ), pattern='0000000000000000', threshold=0.80*scale, border=2 )
style.addDrawingStyle( group='Routing Layers', name='metal2' , color=toRGB('Aqua' ), pattern='0000000000000000', threshold=0.40*scale, border=2 )
style.addDrawingStyle( group='Routing Layers', name='metal3' , color=toRGB('LightPink'), pattern='0000000000000000', threshold=0.02*scale, border=2 )
style.addDrawingStyle( group='Routing Layers', name='metal4' , color=toRGB('Green' ), pattern='0000000000000000', threshold=0.02*scale, border=2 )
style.addDrawingStyle( group='Routing Layers', name='metal5' , color=toRGB('Yellow' ), pattern='0000000000000000', threshold=0.02*scale, border=2 )
style.addDrawingStyle( group='Routing Layers', name='metal6' , color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.02*scale, border=2 )
style.addDrawingStyle( group='Routing Layers', name='metal7' , color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.02*scale, border=2 )
style.addDrawingStyle( group='Routing Layers', name='metal8' , color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.02*scale, border=2 )
style.addDrawingStyle( group='Routing Layers', name='metal9' , color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.02*scale, border=2 )
style.addDrawingStyle( group='Routing Layers', name='metal10', color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.02*scale, border=2 )
# Cuts (VIA holes).
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut0', color=toRGB('0,150,150'), pattern=toHexa('poids4.8'), threshold=1.50*scale, border=1 )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut1', color=toRGB('Aqua' ), pattern='0000000000000000', threshold=0.80*scale, border=1 )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut2', color=toRGB('LightPink'), pattern='0000000000000000', threshold=0.80*scale, border=1 )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut3', color=toRGB('Green' ), pattern='0000000000000000', threshold=0.80*scale, border=1 )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut4', color=toRGB('Yellow' ), pattern='0000000000000000', threshold=0.80*scale, border=1 )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut5', color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.80*scale, border=1 )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut6', color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.80*scale, border=1 )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut7', color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.80*scale, border=1 )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut8', color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.80*scale, border=1 )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut9', color=toRGB('Violet' ), pattern='0000000000000000', threshold=0.80*scale, border=1 )
Viewer.Graphics.addStyle( style )
# ----------------------------------------------------------------------
# Style: Layout Design [white]
style = Viewer.DisplayStyle( 'Layout Design [white]' )
style.inheritFrom( 'Layout Design [black]' )
style.setDescription( 'Layout Design Look - white background' )
style.setDarkening ( Viewer.DisplayStyle.HSVr(1.0, 3.0, 2.5) )
# Group: Viewer.
style.addDrawingStyle( group='Viewer', name='background' , color=toRGB('White'), border=1 )
style.addDrawingStyle( group='Viewer', name='grid' , color=toRGB('Black'), border=1, threshold=2.0 *scale )
style.addDrawingStyle( group='Viewer', name='spot' , color=toRGB('Black'), border=1, threshold=2.0 *scale )
style.addDrawingStyle( group='Viewer', name='text.ruler' , color=toRGB('Black'), border=1, threshold=0.0 *scale )
style.addDrawingStyle( group='Viewer', name='text.reference', color=toRGB('Black'), border=1, threshold=20.0*scale )
# Group: Active Layers.
style.addDrawingStyle( group='Active Layers', name='active', color=toRGB('175,175,175'), pattern='0000000000000000', threshold=1.50*scale, border=2 )
Viewer.Graphics.addStyle( style )
# ----------------------------------------------------------------------
# Style: For Printers [white]
style = Viewer.DisplayStyle( 'For Printers' )
style.setDescription( 'For Printers' )
style.setDarkening ( Viewer.DisplayStyle.HSVr(1.0, 3.0, 2.5) )
# Group: Viewer.
style.addDrawingStyle( group='Viewer', name='fallback' , color=toRGB('Gray238' ), border=1, pattern='55AA55AA55AA55AA' )
style.addDrawingStyle( group='Viewer', name='background' , color=toRGB('White' ), border=1 )
style.addDrawingStyle( group='Viewer', name='foreground' , color=toRGB('Black' ), border=1 )
style.addDrawingStyle( group='Viewer', name='rubber' , color=toRGB('192,0,192'), border=4, threshold=0.02*scale )
style.addDrawingStyle( group='Viewer', name='phantom' , color=toRGB('Seashell4'), border=1 )
style.addDrawingStyle( group='Viewer', name='boundaries' , color=toRGB('Black' ), border=1, pattern='0000000000000000', threshold=0 )
style.addDrawingStyle( group='Viewer', name='marker' , color=toRGB('80,250,80'), border=1 )
style.addDrawingStyle( group='Viewer', name='selectionDraw' , color=toRGB('Black' ), border=1 )
style.addDrawingStyle( group='Viewer', name='selectionFill' , color=toRGB('Black' ), border=1 )
style.addDrawingStyle( group='Viewer', name='grid' , color=toRGB('Black' ), border=1, threshold=2.0*scale )
style.addDrawingStyle( group='Viewer', name='spot' , color=toRGB('Black' ), border=2, threshold=6.0*scale )
style.addDrawingStyle( group='Viewer', name='ghost' , color=toRGB('Black' ), border=1 )
style.addDrawingStyle( group='Viewer', name='text.ruler' , color=toRGB('Black' ), border=1, threshold=0.0 *scale )
style.addDrawingStyle( group='Viewer', name='text.instance' , color=toRGB('Black' ), border=1, threshold=4.0 *scale )
style.addDrawingStyle( group='Viewer', name='text.reference' , color=toRGB('Black' ), border=1, threshold=20.0*scale )
style.addDrawingStyle( group='Viewer', name='undef' , color=toRGB('Violet' ), border=0, pattern='2244118822441188' )
style.addDrawingStyle( group='Viewer', name='mauka.container', color=toRGB('Magenta4' ), border=4, pattern='0000000000000000', goMatched=False )
# Group: Active Layers.
style.addDrawingStyle( group='Active Layers', name='nWell' , color=toRGB('Tan' ), pattern=toHexa('urgo.32' ), border=1, threshold=0.02*scale )
style.addDrawingStyle( group='Active Layers', name='pWell' , color=toRGB('LightYellow'), pattern=toHexa('antipoids2.32'), border=1, threshold=0.02*scale )
style.addDrawingStyle( group='Active Layers', name='nImplant', color=toRGB('LawnGreen' ), pattern=toHexa('diffusion.32' ), border=0, threshold=0.02*scale )
style.addDrawingStyle( group='Active Layers', name='pImplant', color=toRGB('Yellow' ), pattern=toHexa('diffusion.32' ), border=0, threshold=0.02*scale )
style.addDrawingStyle( group='Active Layers', name='active' , color=toRGB('White' ), pattern=toHexa('active.32' ), border=0, threshold=0.02*scale )
style.addDrawingStyle( group='Active Layers', name='poly' , color=toRGB('Red' ), pattern=toHexa('antipoids2.32'), border=1, threshold=0.02*scale )
style.addDrawingStyle( group='Active Layers', name='poly2' , color=toRGB('Orange' ), pattern=toHexa('antipoids2.32'), border=1, threshold=0.02*scale )
# Group: Routing Layers.
style.addDrawingStyle( group='Routing Layers', name='metal1' , color=toRGB('Blue' ), pattern=toHexa('slash.32' ), border=4, threshold=0.02*scale )
style.addDrawingStyle( group='Routing Layers', name='metal2' , color=toRGB('Aqua' ), pattern=toHexa('antislash2.32'), border=1, threshold=0.02*scale )
style.addDrawingStyle( group='Routing Layers', name='metcap' , color=toRGB('DarkTurquoise'), pattern=toHexa('poids2.32' ), border=2, threshold=0.02*scale )
style.addDrawingStyle( group='Routing Layers', name='metal3' , color=toRGB('LightPink' ), pattern=toHexa('antislash3.32'), border=1, threshold=0.02*scale )
style.addDrawingStyle( group='Routing Layers', name='metal4' , color=toRGB('Green' ), pattern=toHexa('antislash4.32'), border=1, threshold=0.02*scale )
style.addDrawingStyle( group='Routing Layers', name='metal5' , color=toRGB('Yellow' ), pattern=toHexa('antislash5.32'), border=1, threshold=0.02*scale )
style.addDrawingStyle( group='Routing Layers', name='metal6' , color=toRGB('Violet' ), pattern=toHexa('antislash2.32'), border=1, threshold=0.02*scale )
style.addDrawingStyle( group='Routing Layers', name='metal7' , color=toRGB('Violet' ), pattern=toHexa('antislash2.32'), border=1, threshold=0.02*scale )
style.addDrawingStyle( group='Routing Layers', name='metal8' , color=toRGB('Violet' ), pattern=toHexa('antislash2.32'), border=1, threshold=0.02*scale )
style.addDrawingStyle( group='Routing Layers', name='metal9' , color=toRGB('Violet' ), pattern=toHexa('antislash2.32'), border=1, threshold=0.02*scale )
style.addDrawingStyle( group='Routing Layers', name='metal10', color=toRGB('Violet' ), pattern=toHexa('antislash2.32'), border=1, threshold=0.02*scale )
# Group: Cuts (VIA holes)
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut0', color=toRGB('Blue' ), pattern=toHexa('poids2.8' ), border=2, threshold=0.02*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut1', color=toRGB('Aqua' ), pattern=toHexa('antipoids2.8'), border=2, threshold=0.02*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut2', color=toRGB('LightPink'), pattern=toHexa('poids2.8' ), border=2, threshold=0.02*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut3', color=toRGB('Green' ), pattern=toHexa('antipoids2.8'), border=2, threshold=0.02*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut4', color=toRGB('Yellow' ), pattern=toHexa('poids2.8' ), border=2, threshold=0.02*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut5', color=toRGB('Violet' ), pattern=toHexa('antipoids2.8'), border=2, threshold=0.02*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut6', color=toRGB('Violet' ), pattern=toHexa('antipoids2.8'), border=2, threshold=0.02*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut7', color=toRGB('Violet' ), pattern=toHexa('antipoids2.8'), border=2, threshold=0.02*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut8', color=toRGB('Violet' ), pattern=toHexa('antipoids2.8'), border=2, threshold=0.02*scale )
style.addDrawingStyle( group='Cuts (VIA holes)', name='cut9', color=toRGB('Violet' ), pattern=toHexa('antipoids2.8'), border=2, threshold=0.02*scale )
# Group: MIM6.
style.addDrawingStyle( group='MIM6', name='metbot_r', color=toRGB('Aqua' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale )
style.addDrawingStyle( group='MIM6', name='cut6' , color=toRGB('LightPink'), pattern=toHexa('light_antihash1.8'), threshold=0.80*scale )
style.addDrawingStyle( group='MIM6', name='metal7' , color=toRGB('Green' ), pattern=toHexa('light_antihash2.8'), threshold=0.80*scale )
# Group: Blockages.
style.addDrawingStyle( group='Blockages', name='blockage1' , color=toRGB('Blue' ), pattern='006070381c0e0703' , threshold=0.80*scale, border=2 )
style.addDrawingStyle( group='Blockages', name='blockage2' , color=toRGB('Aqua' ), pattern='8103060c183060c0' , threshold=0.80*scale, border=2 )
style.addDrawingStyle( group='Blockages', name='blockage3' , color=toRGB('LightPink'), pattern=toHexa('poids4.8' ), threshold=0.80*scale, border=2 )
style.addDrawingStyle( group='Blockages', name='blockage4' , color=toRGB('Green' ), pattern=toHexa('light_antihash2.8'), threshold=0.80*scale, border=2 )
style.addDrawingStyle( group='Blockages', name='blockage5' , color=toRGB('Yellow' ), pattern='1144114411441144' , threshold=0.80*scale, border=2 )
style.addDrawingStyle( group='Blockages', name='blockage6' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
style.addDrawingStyle( group='Blockages', name='blockage7' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
style.addDrawingStyle( group='Blockages', name='blockage8' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
style.addDrawingStyle( group='Blockages', name='blockage9' , color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
style.addDrawingStyle( group='Blockages', name='blockage10', color=toRGB('Violet' ), pattern=toHexa('light_antihash0.8'), threshold=0.80*scale, border=2 )
# Group: Knik & Kite.
style.addDrawingStyle( group='Knik & Kite', name='SPL1' , color=toRGB('Red' ) )
style.addDrawingStyle( group='Knik & Kite', name='AutoLayer' , color=toRGB('Magenta' ) )
style.addDrawingStyle( group='Knik & Kite', name='gmetalh' , color=toRGB('128,255,200'), pattern=toHexa('light_antihash0.8') , border=1 )
style.addDrawingStyle( group='Knik & Kite', name='gmetalv' , color=toRGB('200,200,255'), pattern=toHexa('light_antihash1.8') , border=1 )
style.addDrawingStyle( group='Knik & Kite', name='gcut' , color=toRGB('255,255,190'), border=1 )
style.addDrawingStyle( group='Knik & Kite', name='Anabatic::Edge' , color=toRGB('255,255,190'), pattern='0000000000000000', border=2 )
style.addDrawingStyle( group='Knik & Kite', name='Anabatic::GCell', color=toRGB('Black' ), pattern='0000000000000000', border=2, threshold=0.80*scale )
Viewer.Graphics.addStyle( style )
Viewer.Graphics.setStyle( 'Alliance.Classic [black]' )
createStyles( scale=1.0 )

View File

@ -0,0 +1,20 @@
# This file is part of the Coriolis Software.
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | Alliance / Hurricane Interface |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./etc/symbolic/lcmos/etesian.py" |
# +-----------------------------------------------------------------+
from coriolis.helpers import truncPath
from coriolis.helpers.io import vprint
vprint( 2, ' - "%s".' % truncPath(__file__) )
from ...common import etesian

View File

@ -0,0 +1,194 @@
# This file is part of the Coriolis Software.
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | Alliance / Hurricane Interface |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./etc/symbolic/lcmos/kite.py" |
# +-----------------------------------------------------------------+
import coriolis.Cfg as Cfg
from coriolis.Hurricane import DataBase
from coriolis.CRL import AllianceFramework, RoutingGauge, \
RoutingLayerGauge, CellGauge
from coriolis.helpers import truncPath, l, u, n
from coriolis.helpers.io import vprint
vprint( 2, ' - "%s".' % truncPath(__file__) )
from ...common import kite
p = Cfg.getParamDouble ( 'lefImport.minTerminalWidth' ).setDouble ( 0.0 )
p = Cfg.getParamString ( 'katabatic.routingGauge' ).setString ( 'sxlib' )
p = Cfg.getParamInt ( "katabatic.globalLengthThreshold" ).setInt ( 1450 )
p = Cfg.getParamPercentage( "katabatic.saturateRatio" ).setPercentage( 80 )
p = Cfg.getParamInt ( "katabatic.saturateRp" ).setInt ( 8 )
p = Cfg.getParamString ( 'katabatic.topRoutingLayer' ).setString ( 'METAL5' )
# Kite parameters.
p = Cfg.getParamInt( "kite.hTracksReservedLocal" ); p.setInt( 3 ); p.setMin( 0 ); p.setMax( 20 )
p = Cfg.getParamInt( "kite.vTracksReservedLocal" ); p.setInt( 3 ); p.setMin( 0 ); p.setMax( 20 )
p = Cfg.getParamInt( "kite.eventsLimit" ); p.setInt( 4000002 )
p = Cfg.getParamInt( "kite.ripupCost" ); p.setInt( 3 ); p.setMin( 0 )
p = Cfg.getParamInt( "kite.strapRipupLimit" ); p.setInt( 16 ); p.setMin( 1 )
p = Cfg.getParamInt( "kite.localRipupLimit" ); p.setInt( 9 ); p.setMin( 1 )
p = Cfg.getParamInt( "kite.globalRipupLimit" ); p.setInt( 5 ); p.setMin( 1 )
p = Cfg.getParamInt( "kite.longGlobalRipupLimit" ); p.setInt( 5 ); p.setMin( 1 )
# Anabatic & Katana parameters are temporarily hosted here.
p = Cfg.getParamString ( 'anabatic.routingGauge' ); p.setString ( 'sxlib' )
p = Cfg.getParamInt ( "anabatic.globalLengthThreshold" ); p.setInt ( 1450 )
p = Cfg.getParamPercentage( "anabatic.saturateRatio" ); p.setPercentage( 80 )
p = Cfg.getParamInt ( "anabatic.saturateRp" ); p.setInt ( 8 )
p = Cfg.getParamString ( 'anabatic.topRoutingLayer' ); p.setString ( 'METAL5' )
p = Cfg.getParamInt ( "anabatic.edgeLength" ); p.setInt ( 24 )
p = Cfg.getParamInt ( "anabatic.edgeWidth" ); p.setInt ( 4 )
p = Cfg.getParamDouble ( "anabatic.edgeCostH" ); p.setDouble ( 19.0 )
p = Cfg.getParamDouble ( "anabatic.edgeCostK" ); p.setDouble ( -60.0 )
p = Cfg.getParamDouble ( "anabatic.edgeHScaling" ); p.setDouble ( 1.0 )
p = Cfg.getParamInt ( "anabatic.globalIterations" ); p.setInt ( 10 ); p.setMin(1); p.setMax(100)
p = Cfg.getParamEnumerate ( "anabatic.gcell.displayMode" ); p.setInt ( 1 )
p.addValue( "Boundary", 1 )
p.addValue( "Density" , 2 )
p = Cfg.getParamBool ( "katana.useGlobalEstimate" ); p.setBool ( False );
p = Cfg.getParamInt ( "katana.hTracksReservedLocal" ); p.setInt ( 3 ); p.setMin(0); p.setMax(20)
p = Cfg.getParamInt ( "katana.vTracksReservedLocal" ); p.setInt ( 3 ); p.setMin(0); p.setMax(20)
p = Cfg.getParamInt ( "katana.hTracksReservedMin" ); p.setInt ( 1 ); p.setMin(0); p.setMax(20)
p = Cfg.getParamInt ( "katana.vTracksReservedMin" ); p.setInt ( 1 ); p.setMin(0); p.setMax(20)
p = Cfg.getParamInt ( "katana.termSatReservedLocal" ); p.setInt ( 8 )
p = Cfg.getParamInt ( "katana.termSatThreshold" ); p.setInt ( 9 )
p = Cfg.getParamInt ( "katana.eventsLimit" ); p.setInt ( 4000002 )
p = Cfg.getParamInt ( "katana.ripupCost" ); p.setInt ( 3 ); p.setMin(0)
p = Cfg.getParamInt ( "katana.strapRipupLimit" ); p.setInt ( 16 ); p.setMin(1)
p = Cfg.getParamInt ( "katana.localRipupLimit" ); p.setInt ( 9 ); p.setMin(1)
p = Cfg.getParamInt ( "katana.globalRipupLimit" ); p.setInt ( 5 ); p.setMin(1)
p = Cfg.getParamInt ( "katana.longGlobalRipupLimit" ); p.setInt ( 5 ); p.setMin(1)
p = Cfg.getParamString( 'chip.padCoreSide' ); p.setString( 'South' )
tech = DataBase.getDB().getTechnology()
af = AllianceFramework.get()
rg = RoutingGauge.create( 'sxlib' )
rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # metal.
, RoutingLayerGauge.Vertical # preferred routing direction.
, RoutingLayerGauge.PinOnly # layer usage.
, 0 # depth.
, 0.0 # density (deprecated).
, l(0) # track offset from AB.
, l(5) # track pitch.
, l(2) # wire width.
, 0 # perpandicular wire width.
, l(1) # VIA side (that is VIA12).
, l(4) # obstacle dW.
) )
rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # metal.
, RoutingLayerGauge.Horizontal # preferred routing direction.
, RoutingLayerGauge.Default # layer usage.
, 1 # depth.
, 0.0 # density (deprecated).
, l(0) # track offset from AB.
, l(5) # track pitch.
, l(2) # wire width.
, 0 # perpandicular wire width.
, l(1) # VIA side (that is VIA23).
, l(4) # obstacle dW.
) )
rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL3') # metal.
, RoutingLayerGauge.Vertical # preferred routing direction.
, RoutingLayerGauge.Default # layer usage.
, 2 # depth.
, 0.0 # density (deprecated).
, l(0) # track offset from AB.
, l(5) # track pitch.
, l(2) # wire width.
, 0 # perpandicular wire width.
, l(1) # VIA side (that is VIA34).
, l(4) # obstacle dW.
) )
rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL4') # metal.
, RoutingLayerGauge.Horizontal # preferred routing direction.
, RoutingLayerGauge.Default # layer usage.
, 3 # depth.
, 0.0 # density (deprecated).
, l(0) # track offset from AB.
, l(5) # track pitch.
, l(2) # wire width.
, 0 # perpandicular wire width.
, l(1) # VIA side (that is VIA23).
, l(4) # obstacle dW.
) )
rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL5') # metal.
, RoutingLayerGauge.Vertical # preferred routing direction.
, RoutingLayerGauge.Default # layer usage.
, 4 # depth.
, 0.0 # density (deprecated).
, l(0) # track offset from AB.
, l(5) # track pitch.
, l(2) # wire width.
, 0 # perpandicular wire width.
, l(1) # VIA side (that is VIA23).
, l(4) # obstacle dW.
) )
af.addRoutingGauge( rg )
rg = RoutingGauge.create( 'sxlib-2M' )
rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL1') # metal.
, RoutingLayerGauge.Vertical # preferred routing direction.
, RoutingLayerGauge.PinOnly # layer usage.
, 0 # depth.
, 0.0 # density (deprecated).
, l(0) # track offset from AB.
, l(5) # track pitch.
, l(2) # wire width.
, 0 # perpandicular wire width.
, l(1) # VIA side (that is VIA12).
, l(4) # obstacle dW.
) )
rg.addLayerGauge( RoutingLayerGauge.create( tech.getLayer('METAL2') # metal.
, RoutingLayerGauge.Horizontal # preferred routing direction.
, RoutingLayerGauge.Default # layer usage.
, 1 # depth.
, 0.0 # density (deprecated).
, l(0) # track offset from AB.
, l(5) # track pitch.
, l(2) # wire width.
, 0 # perpandicular wire width.
, l(1) # VIA side (that is VIA23).
, l(4) # obstacle dW.
) )
af.addRoutingGauge( rg )
af.setRoutingGauge( 'sxlib' )
# Gauge for standard cells.
cg = CellGauge.create( 'sxlib'
, 'metal2' # pin layer name.
, l( 5.0) # pitch.
, l( 50.0) # cell slice height.
, l( 5.0) # cell slice step.
)
af.addCellGauge( cg )
# Gauge for Alliance symbolic I/O pads.
cg = CellGauge.create( 'pxlib'
, 'metal2' # pin layer name.
, l( 5.0) # pitch.
, l(400.0) # cell slice height.
, l(200.0) # cell slice step.
)
af.addCellGauge( cg )

View File

@ -0,0 +1,20 @@
# This file is part of the Coriolis Software.
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | Alliance / Hurricane Interface |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./etc/symbolic/lcmos/misc.py" |
# +-----------------------------------------------------------------+
from coriolis.helpers import truncPath
from coriolis.helpers.io import vprint
vprint( 2, ' - "%s".' % truncPath(__file__) )
from ...common import misc

View File

@ -0,0 +1,20 @@
# This file is part of the Coriolis Software.
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | Alliance / Hurricane Interface |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./etc/symbolic/lcmos/patterns.py" |
# +-----------------------------------------------------------------+
from coriolis.helpers import truncPath
from coriolis.helpers.io import vprint
vprint( 2, ' - "%s".' % truncPath(__file__) )
from ...common import patterns

View File

@ -0,0 +1,32 @@
# This file is part of the Coriolis Software.
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | Alliance / Hurricane Interface |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./etc/symbolic/lcmos/plugins.py" |
# +-----------------------------------------------------------------+
import coriolis.Cfg as Cfg
from coriolis.helpers import truncPath, l, u, n
from coriolis.helpers.io import vprint
vprint( 2, ' - "%s".' % truncPath(__file__) )
Cfg.getParamInt ( "chip.block.rails.count" ).setInt ( 5 )
Cfg.getParamInt ( "chip.block.rails.hWidth" ).setInt ( l( 12) )
Cfg.getParamInt ( "chip.block.rails.vWidth" ).setInt ( l( 12) )
Cfg.getParamInt ( "chip.block.rails.hSpacing" ).setInt ( l( 3) )
Cfg.getParamInt ( "chip.block.rails.vSpacing" ).setInt ( l( 3) )
Cfg.getParamBool ( "chip.useAbstractPads" ).setBool ( True )
Cfg.getParamInt ( 'clockTree.minimumSide' ).setInt ( l(600) )
Cfg.getParamString( 'clockTree.buffer' ).setString( 'buf_x2')
Cfg.getParamString( 'clockTree.placerEngine' ).setString( 'Etesian')
Cfg.getParamInt ( 'block.spareSide' ).setInt ( 10 )
Cfg.getParamString( 'spares.buffer' ).setString( 'buf_x8')
Cfg.getParamInt ( 'spares.maxSinks' ).setInt ( 31 )

View File

@ -0,0 +1,26 @@
# This file is part of the Coriolis Software.
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | Alliance / Hurricane Interface |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./etc/symbolic/lcmos/stratus1.py" |
# +-----------------------------------------------------------------+
import os.path
import coriolis.Cfg as Cfg
from coriolis.helpers import sysConfDir, truncPath
from coriolis.helpers.io import vprint
vprint( 2, ' - "%s".' % truncPath(__file__) )
from ...common import stratus1
Cfg.getParamString( "stratus1.format" ).setString( "vst" )
Cfg.getParamString( "stratus1.simulator" ).setString( "asimut" )
Cfg.getParamString( "stratus1.mappingName" ).setString( os.path.join(sysConfDir,'symbolic/cmos/stratus2sxlib.xml') )

View File

@ -0,0 +1,401 @@
# This file is part of the Coriolis Software.
# Copyright (c) Sorbonne Université 2019-2023, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | Alliance / Hurricane Interface |
# | |
# | Author : Jean-Paul CHAPUT |
# | E-mail : Jean-Paul.Chaput@lip6.fr |
# | =============================================================== |
# | Python : "./etc/symbolic/lcmos/technology.py" |
# +-----------------------------------------------------------------+
from coriolis.helpers import l, u, n, truncPath
from coriolis.helpers.io import WarningMessage, vprint
vprint( 2, ' - "{}".'.format(truncPath(__file__)) )
from coriolis.Hurricane import DbU, DataBase, Technology, Layer, BasicLayer, \
DiffusionLayer, TransistorLayer, \
RegularLayer, ContactLayer, ViaLayer
def createBL ( layerName, material ):
global tech
return BasicLayer.create( tech, layerName, BasicLayer.Material(material) )
tech = DataBase.getDB().getTechnology()
if tech:
print( WarningMessage( 'lcmos.technology: Technology already exists, "{}"'.format(tech.getName()) ))
else:
tech = Technology.create( DataBase.getDB(), 'lcmos' )
DbU.setPrecision ( 2 )
DbU.setPhysicalsPerGrid ( 0.5, DbU.UnitPowerMicro )
DbU.setGridsPerLambda ( 2 )
DbU.setSymbolicSnapGridStep( DbU.fromLambda(1.0) )
DbU.setPolygonStep ( DbU.fromGrid (2.0) )
from ...common import loadGdsLayers
nWell = createBL( 'nWell' , BasicLayer.Material.nWell ) # Non-Routing Layers.
pWell = createBL( 'pWell' , BasicLayer.Material.pWell )
nImplant = createBL( 'nImplant' , BasicLayer.Material.nImplant )
pImplant = createBL( 'pImplant' , BasicLayer.Material.pImplant )
active = createBL( 'active' , BasicLayer.Material.active )
poly = createBL( 'poly' , BasicLayer.Material.poly )
poly2 = createBL( 'poly2' , BasicLayer.Material.poly )
cut0 = createBL( 'cut0' , BasicLayer.Material.cut ) # Routing Layers & VIA Cuts.
metal1 = createBL( 'metal1' , BasicLayer.Material.metal ) # WARNING: order *is* meaningful.
cut1 = createBL( 'cut1' , BasicLayer.Material.cut )
metal2 = createBL( 'metal2' , BasicLayer.Material.metal )
metcap = createBL( 'metcap' , BasicLayer.Material.other )
cut2 = createBL( 'cut2' , BasicLayer.Material.cut )
metal3 = createBL( 'metal3' , BasicLayer.Material.metal )
cut3 = createBL( 'cut3' , BasicLayer.Material.cut )
metal4 = createBL( 'metal4' , BasicLayer.Material.metal )
cut4 = createBL( 'cut4' , BasicLayer.Material.cut )
metal5 = createBL( 'metal5' , BasicLayer.Material.metal )
cut5 = createBL( 'cut5' , BasicLayer.Material.cut )
metal6 = createBL( 'metal6' , BasicLayer.Material.metal )
cut6 = createBL( 'cut6' , BasicLayer.Material.cut )
metal7 = createBL( 'metal7' , BasicLayer.Material.metal )
cut7 = createBL( 'cut7' , BasicLayer.Material.cut )
metal8 = createBL( 'metal8' , BasicLayer.Material.metal )
cut8 = createBL( 'cut8' , BasicLayer.Material.cut )
metal9 = createBL( 'metal9' , BasicLayer.Material.metal )
cut9 = createBL( 'cut9' , BasicLayer.Material.cut )
metal10 = createBL( 'metal10' , BasicLayer.Material.metal )
blockage1 = createBL( 'blockage1' , BasicLayer.Material.blockage )
blockage2 = createBL( 'blockage2' , BasicLayer.Material.blockage )
blockage3 = createBL( 'blockage3' , BasicLayer.Material.blockage )
blockage4 = createBL( 'blockage4' , BasicLayer.Material.blockage )
blockage5 = createBL( 'blockage5' , BasicLayer.Material.blockage )
blockage6 = createBL( 'blockage6' , BasicLayer.Material.blockage )
blockage7 = createBL( 'blockage7' , BasicLayer.Material.blockage )
blockage8 = createBL( 'blockage8' , BasicLayer.Material.blockage )
blockage9 = createBL( 'blockage9' , BasicLayer.Material.blockage )
blockage10 = createBL( 'blockage10', BasicLayer.Material.blockage )
metal1 .setBlockageLayer( blockage1 )
metal2 .setBlockageLayer( blockage2 )
metal3 .setBlockageLayer( blockage3 )
metal4 .setBlockageLayer( blockage4 )
metal5 .setBlockageLayer( blockage5 )
metal6 .setBlockageLayer( blockage6 )
metal7 .setBlockageLayer( blockage7 )
metal8 .setBlockageLayer( blockage8 )
metal9 .setBlockageLayer( blockage9 )
metal10.setBlockageLayer( blockage10 )
textCell = createBL( 'text.cell' , BasicLayer.Material.other ) # Misc. non-physical layers.
textInst = createBL( 'text.instance', BasicLayer.Material.other ) # Used by the software for visualization
SPL1 = createBL( 'SPL1' , BasicLayer.Material.other ) # purposes only.
AutoLayer = createBL( 'AutoLayer' , BasicLayer.Material.other )
gmetalh = createBL( 'gmetalh' , BasicLayer.Material.metal ) # Special BasicLayers for Knik & Kite Routers.
gcut = createBL( 'gcut' , BasicLayer.Material.cut ) # *Must be after all others*
gmetalv = createBL( 'gmetalv' , BasicLayer.Material.metal )
# VIAs for real technologies.
via12 = ViaLayer.create( tech, 'via12' , metal1, cut1, metal2 )
via23 = ViaLayer.create( tech, 'via23' , metal2, cut2, metal3 )
via34 = ViaLayer.create( tech, 'via34' , metal3, cut3, metal4 )
via45 = ViaLayer.create( tech, 'via45' , metal4, cut4, metal5 )
via56 = ViaLayer.create( tech, 'via56' , metal5, cut5, metal6 )
via67 = ViaLayer.create( tech, 'via67' , metal6, cut6, metal7 )
via78 = ViaLayer.create( tech, 'via78' , metal7, cut7, metal8 )
via89 = ViaLayer.create( tech, 'via89' , metal8, cut8, metal9 )
via910 = ViaLayer.create( tech, 'via910', metal9, cut9, metal10 )
# Composite/Symbolic layers.
NWELL = RegularLayer .create( tech, 'NWELL' , nWell )
PWELL = RegularLayer .create( tech, 'PWELL' , pWell )
NTIE = DiffusionLayer .create( tech, 'NTIE' , nImplant , active, nWell)
PTIE = DiffusionLayer .create( tech, 'PTIE' , pImplant , active, pWell)
NDIF = DiffusionLayer .create( tech, 'NDIF' , nImplant , active, None )
PDIF = DiffusionLayer .create( tech, 'PDIF' , pImplant , active, None )
GATE = DiffusionLayer .create( tech, 'GATE' , poly , active, None )
NTRANS = TransistorLayer.create( tech, 'NTRANS' , nImplant , active, poly, None )
PTRANS = TransistorLayer.create( tech, 'PTRANS' , pImplant , active, poly, None )
POLY = RegularLayer .create( tech, 'POLY' , poly )
POLY2 = RegularLayer .create( tech, 'POLY2' , poly2 )
METAL1 = RegularLayer .create( tech, 'METAL1' , metal1 )
METAL2 = RegularLayer .create( tech, 'METAL2' , metal2 )
metcapdum = RegularLayer .create( tech, 'metcapdum' , metcap )
metbot = RegularLayer .create( tech, 'metbot' , metal2 )
METAL3 = RegularLayer .create( tech, 'METAL3' , metal3 )
METAL4 = RegularLayer .create( tech, 'METAL4' , metal4 )
METAL5 = RegularLayer .create( tech, 'METAL5' , metal5 )
METAL6 = RegularLayer .create( tech, 'METAL6' , metal6 )
METAL7 = RegularLayer .create( tech, 'METAL7' , metal7 )
METAL8 = RegularLayer .create( tech, 'METAL8' , metal8 )
METAL9 = RegularLayer .create( tech, 'METAL9' , metal9 )
METAL10 = RegularLayer .create( tech, 'METAL10' , metal10 )
CONT_BODY_N = ContactLayer .create( tech, 'CONT_BODY_N', nImplant , cut0, active, metal1, None )
CONT_BODY_P = ContactLayer .create( tech, 'CONT_BODY_P', pImplant , cut0, active, metal1, None )
CONT_DIF_N = ContactLayer .create( tech, 'CONT_DIF_N' , nImplant , cut0, active, metal1, None )
CONT_DIF_P = ContactLayer .create( tech, 'CONT_DIF_P' , pImplant , cut0, active, metal1, None )
CONT_POLY = ViaLayer .create( tech, 'CONT_POLY' , poly , cut0, metal1 )
# VIAs for symbolic technologies.
VIA12 = ViaLayer .create( tech, 'VIA12' , metal1, cut1, metal2 )
VIA23 = ViaLayer .create( tech, 'VIA23' , metal2, cut2, metal3 )
VIA23cap = ViaLayer .create( tech, 'VIA23cap' , metcap, cut2, metal3 )
VIA34 = ViaLayer .create( tech, 'VIA34' , metal3, cut3, metal4 )
VIA45 = ViaLayer .create( tech, 'VIA45' , metal4, cut4, metal5 )
VIA56 = ViaLayer .create( tech, 'VIA56' , metal5, cut5, metal6 )
VIA67 = ViaLayer .create( tech, 'VIA67' , metal6, cut6, metal7 )
VIA78 = ViaLayer .create( tech, 'VIA78' , metal7, cut7, metal8 )
VIA89 = ViaLayer .create( tech, 'VIA89' , metal8, cut8, metal9 )
VIA910 = ViaLayer .create( tech, 'VIA910' , metal9, cut9, metal10 )
BLOCKAGE1 = RegularLayer.create( tech, 'BLOCKAGE1' , blockage1 )
BLOCKAGE2 = RegularLayer.create( tech, 'BLOCKAGE2' , blockage2 )
BLOCKAGE3 = RegularLayer.create( tech, 'BLOCKAGE3' , blockage3 )
BLOCKAGE4 = RegularLayer.create( tech, 'BLOCKAGE4' , blockage4 )
BLOCKAGE5 = RegularLayer.create( tech, 'BLOCKAGE5' , blockage5 )
BLOCKAGE6 = RegularLayer.create( tech, 'BLOCKAGE6' , blockage6 )
BLOCKAGE7 = RegularLayer.create( tech, 'BLOCKAGE7' , blockage7 )
BLOCKAGE8 = RegularLayer.create( tech, 'BLOCKAGE8' , blockage8 )
BLOCKAGE9 = RegularLayer.create( tech, 'BLOCKAGE9' , blockage9 )
BLOCKAGE10 = RegularLayer.create( tech, 'BLOCKAGE10', blockage10 )
gcontact = ViaLayer .create( tech, 'gcontact' , gmetalh , gcut, gmetalv )
tech.setSymbolicLayer( CONT_BODY_N.getName() )
tech.setSymbolicLayer( CONT_BODY_P.getName() )
tech.setSymbolicLayer( CONT_DIF_N .getName() )
tech.setSymbolicLayer( CONT_DIF_P .getName() )
tech.setSymbolicLayer( CONT_POLY .getName() )
tech.setSymbolicLayer( POLY .getName() )
tech.setSymbolicLayer( POLY2 .getName() )
tech.setSymbolicLayer( METAL1 .getName() )
tech.setSymbolicLayer( METAL2 .getName() )
tech.setSymbolicLayer( METAL3 .getName() )
tech.setSymbolicLayer( METAL4 .getName() )
tech.setSymbolicLayer( METAL5 .getName() )
tech.setSymbolicLayer( METAL6 .getName() )
tech.setSymbolicLayer( METAL7 .getName() )
tech.setSymbolicLayer( METAL8 .getName() )
tech.setSymbolicLayer( METAL9 .getName() )
tech.setSymbolicLayer( METAL10 .getName() )
tech.setSymbolicLayer( BLOCKAGE1 .getName() )
tech.setSymbolicLayer( BLOCKAGE2 .getName() )
tech.setSymbolicLayer( BLOCKAGE3 .getName() )
tech.setSymbolicLayer( BLOCKAGE4 .getName() )
tech.setSymbolicLayer( BLOCKAGE5 .getName() )
tech.setSymbolicLayer( BLOCKAGE6 .getName() )
tech.setSymbolicLayer( BLOCKAGE7 .getName() )
tech.setSymbolicLayer( BLOCKAGE8 .getName() )
tech.setSymbolicLayer( BLOCKAGE9 .getName() )
tech.setSymbolicLayer( BLOCKAGE10 .getName() )
tech.setSymbolicLayer( VIA12 .getName() )
tech.setSymbolicLayer( VIA23 .getName() )
tech.setSymbolicLayer( VIA34 .getName() )
tech.setSymbolicLayer( VIA45 .getName() )
tech.setSymbolicLayer( VIA56 .getName() )
tech.setSymbolicLayer( VIA67 .getName() )
tech.setSymbolicLayer( VIA78 .getName() )
tech.setSymbolicLayer( VIA89 .getName() )
tech.setSymbolicLayer( VIA910 .getName() )
tech.setSymbolicLayer( gcut .getName() )
tech.setSymbolicLayer( gmetalh .getName() )
tech.setSymbolicLayer( gmetalv .getName() )
tech.setSymbolicLayer( gcontact .getName() )
NWELL.setExtentionCap ( nWell, l(2.0) )
NWELL.setExtentionWidth( nWell, l(0.0) )
PWELL.setExtentionCap ( pWell, l(2.0) )
PWELL.setExtentionWidth( nWell, l(0.0) )
NTIE.setMinimalSize ( l(3.0) )
NTIE.setExtentionCap ( nWell , l(2.0) )
NTIE.setExtentionWidth( nWell , l(2.5) )
NTIE.setExtentionCap ( nImplant, l(1.5) )
NTIE.setExtentionWidth( nImplant, l(0.0) )
NTIE.setExtentionCap ( active , l(0.0) )
NTIE.setExtentionWidth( active , l(0.0) )
PTIE.setMinimalSize ( l(3.0) )
PTIE.setExtentionCap ( pWell , l(2.0) )
PTIE.setExtentionWidth( pWell , l(2.5) )
PTIE.setExtentionCap ( pImplant, l(1.5) )
PTIE.setExtentionWidth( pImplant, l(0.0) )
PTIE.setExtentionCap ( active , l(0.0) )
PTIE.setExtentionWidth( active , l(0.0) )
NDIF.setMinimalSize ( l(3.0) )
NDIF.setExtentionCap ( nImplant, l(0.5) )
NDIF.setExtentionWidth( nImplant, l(0.0) )
NDIF.setExtentionCap ( active , l(0.5) )
NDIF.setExtentionWidth( active , l(0.0) )
PDIF.setMinimalSize ( l(3.0) )
PDIF.setExtentionCap ( pImplant, l(0.5) )
PDIF.setExtentionWidth( pImplant, l(0.0) )
PDIF.setExtentionCap ( active , l(0.5) )
PDIF.setExtentionWidth( active , l(0.0) )
GATE.setMinimalSize ( l(1.0) )
GATE.setExtentionCap ( poly , l(1.5) )
NTRANS.setMinimalSize ( l( 1.0) )
NTRANS.setExtentionCap ( nImplant, l(-1.5) )
NTRANS.setExtentionWidth( nImplant, l( 3.0) )
NTRANS.setExtentionCap ( active , l(-1.5) )
NTRANS.setExtentionWidth( active , l( 2.0) )
PTRANS.setMinimalSize ( l( 1.0) )
PTRANS.setExtentionCap ( nWell , l(-1.5) )
PTRANS.setExtentionWidth( nWell , l( 2.5) )
PTRANS.setExtentionCap ( pImplant, l(-1.5) )
PTRANS.setExtentionWidth( pImplant, l( 2.5) )
PTRANS.setExtentionCap ( active , l(-1.5) )
PTRANS.setExtentionWidth( active , l( 2.5) )
POLY .setMinimalSize ( l(1.0) )
POLY .setExtentionCap ( poly , l(0.5) )
POLY2.setMinimalSize ( l(1.0) )
POLY2.setExtentionCap ( poly , l(0.5) )
METAL1 .setMinimalSize ( l(1.0) )
METAL1 .setExtentionCap ( metal1 , l(1.0) )
METAL2 .setMinimalSize ( l(1.0) )
METAL2 .setExtentionCap ( metal2 , l(1.0) )
METAL3 .setMinimalSize ( l(1.0) )
METAL3 .setExtentionCap ( metal3 , l(1.0) )
METAL4 .setMinimalSize ( l(1.0) )
METAL4 .setExtentionCap ( metal4 , l(1.0) )
METAL4 .setMinimalSpacing( l(3.0) )
METAL5 .setMinimalSize ( l(2.0) )
METAL5 .setExtentionCap ( metal5 , l(1.0) )
METAL6 .setMinimalSize ( l(2.0) )
METAL6 .setExtentionCap ( metal6 , l(1.0) )
METAL7 .setMinimalSize ( l(2.0) )
METAL7 .setExtentionCap ( metal7 , l(1.0) )
METAL8 .setMinimalSize ( l(2.0) )
METAL8 .setExtentionCap ( metal8 , l(1.0) )
METAL9 .setMinimalSize ( l(2.0) )
METAL9 .setExtentionCap ( metal9 , l(1.0) )
METAL10.setMinimalSize ( l(2.0) )
METAL10.setExtentionCap ( metal10 , l(1.0) )
# Contacts (i.e. Active <--> Metal) (symbolic).
CONT_BODY_N.setMinimalSize( l( 1.0) )
#CONT_BODY_N.setEnclosure ( nWell , l( 1.5), Layer.EnclosureH|Layer.EnclosureV )
CONT_BODY_N.setEnclosure ( nImplant, l( 1.0), Layer.EnclosureH|Layer.EnclosureV )
CONT_BODY_N.setEnclosure ( cut0 , l( 0.0), Layer.EnclosureH|Layer.EnclosureV )
CONT_BODY_N.setEnclosure ( active , l( 1.0), Layer.EnclosureH|Layer.EnclosureV )
CONT_BODY_N.setEnclosure ( metal1 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
CONT_BODY_P.setMinimalSize( l( 1.0) )
#CONT_BODY_P.setEnclosure ( pWell , l( 1.0), Layer.EnclosureH|Layer.EnclosureV )
CONT_BODY_P.setEnclosure ( pImplant, l( 1.0), Layer.EnclosureH|Layer.EnclosureV )
CONT_BODY_P.setEnclosure ( cut0 , l( 0.0), Layer.EnclosureH|Layer.EnclosureV )
CONT_BODY_P.setEnclosure ( active , l( 1.0), Layer.EnclosureH|Layer.EnclosureV )
CONT_BODY_P.setEnclosure ( metal1 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
CONT_DIF_N.setMinimalSize( l( 1.0) )
CONT_DIF_N.setEnclosure ( nImplant, l( 1.0), Layer.EnclosureH|Layer.EnclosureV )
CONT_DIF_N.setEnclosure ( cut0 , l( 0.0), Layer.EnclosureH|Layer.EnclosureV )
CONT_DIF_N.setEnclosure ( active , l( 1.0), Layer.EnclosureH|Layer.EnclosureV )
CONT_DIF_N.setEnclosure ( metal1 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
CONT_DIF_P.setMinimalSize( l( 1.0) )
CONT_DIF_P.setEnclosure ( pImplant, l( 1.0), Layer.EnclosureH|Layer.EnclosureV )
CONT_DIF_P.setEnclosure ( cut0 , l( 0.0), Layer.EnclosureH|Layer.EnclosureV )
CONT_DIF_P.setEnclosure ( active , l( 1.0), Layer.EnclosureH|Layer.EnclosureV )
CONT_DIF_P.setEnclosure ( metal1 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
CONT_POLY.setMinimalSize( l( 1.0) )
CONT_POLY.setEnclosure ( poly , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
CONT_POLY.setEnclosure ( metal1 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
# VIAs (i.e. Metal <--> Metal) (symbolic).
VIA12 .setMinimalSize ( l( 1.0) )
VIA12 .setEnclosure ( metal1 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
VIA12 .setEnclosure ( metal2 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
VIA12 .setMinimalSpacing( l( 4.0) )
VIA23 .setMinimalSize ( l( 1.0) )
VIA23 .setEnclosure ( metal2 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
VIA23 .setEnclosure ( metal3 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
VIA23 .setMinimalSpacing( l( 4.0) )
VIA34 .setMinimalSize ( l( 1.0) )
VIA34 .setEnclosure ( metal3 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
VIA34 .setEnclosure ( metal4 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
VIA34 .setMinimalSpacing( l( 4.0) )
VIA45 .setMinimalSize ( l( 1.0) )
VIA45 .setEnclosure ( metal4 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
VIA45 .setEnclosure ( metal5 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
VIA45 .setMinimalSpacing( l( 4.0) )
VIA56 .setMinimalSize ( l( 1.0) )
VIA56 .setEnclosure ( metal5 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
VIA56 .setEnclosure ( metal6 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
VIA56 .setMinimalSpacing( l( 4.0) )
VIA67 .setMinimalSize ( l( 1.0) )
VIA67 .setEnclosure ( metal6 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
VIA67 .setEnclosure ( metal7 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
VIA67 .setMinimalSpacing( l( 4.0) )
VIA78 .setMinimalSpacing( l( 4.0) )
VIA78 .setMinimalSize ( l( 1.0) )
VIA78 .setEnclosure ( metal7 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
VIA78 .setEnclosure ( metal8 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
VIA78 .setMinimalSpacing( l( 4.0) )
VIA89 .setMinimalSize ( l( 1.0) )
VIA89 .setEnclosure ( metal8 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
VIA89 .setEnclosure ( metal9 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
VIA89 .setMinimalSpacing( l( 4.0) )
VIA910.setMinimalSize ( l( 1.0) )
VIA910.setEnclosure ( metal9 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
VIA910.setEnclosure ( metal10 , l( 0.5), Layer.EnclosureH|Layer.EnclosureV )
VIA910.setMinimalSpacing( l( 4.0) )
# Blockages (symbolic).
BLOCKAGE1 .setMinimalSize ( l( 1.0) )
BLOCKAGE1 .setExtentionCap( blockage1 , l( 0.5) )
BLOCKAGE2 .setMinimalSize ( l( 2.0) )
BLOCKAGE2 .setExtentionCap( blockage2 , l( 0.5) )
BLOCKAGE3 .setMinimalSize ( l( 2.0) )
BLOCKAGE3 .setExtentionCap( blockage3 , l( 0.5) )
BLOCKAGE4 .setMinimalSize ( l( 2.0) )
BLOCKAGE4 .setExtentionCap( blockage4 , l( 0.5) )
BLOCKAGE5 .setMinimalSize ( l( 2.0) )
BLOCKAGE5 .setExtentionCap( blockage5 , l( 1.0) )
BLOCKAGE6 .setMinimalSize ( l( 2.0) )
BLOCKAGE6 .setExtentionCap( blockage6 , l( 1.0) )
BLOCKAGE7 .setMinimalSize ( l( 2.0) )
BLOCKAGE7 .setExtentionCap( blockage7 , l( 1.0) )
BLOCKAGE8 .setMinimalSize ( l( 2.0) )
BLOCKAGE8 .setExtentionCap( blockage8 , l( 1.0) )
BLOCKAGE9 .setMinimalSize ( l( 2.0) )
BLOCKAGE9 .setExtentionCap( blockage9 , l( 1.0) )
BLOCKAGE10.setMinimalSize ( l( 2.0) )
BLOCKAGE10.setExtentionCap( blockage10, l( 1.0) )
gdsLayersTable = \
[ ("nWell" , "LNWELL" , 1, 0)
, ("nImplant", "LNIF" , 3, 0)
, ("pImplant", "LPDIF" , 4, 0)
, ("active" , "LACTIVE" , 2, 0)
, ("poly" , "LPOLY" , 7, 0)
, ("cut0" , "LCONT" , 10, 0)
, ("metal1" , "LALU1" , 11, 0)
, ("cut1" , "LVIA" , 14, 0)
, ("metal2" , "LALU2" , 16, 0)
, ("cut2" , "LVIA2" , 18, 0)
, ("metal3" , "LALU3" , 19, 0)
, ("cut3" , "LVIA3" , 21, 0)
, ("metal4" , "LALU4" , 22, 0)
, ("cut4" , "LVIA4" , 25, 0)
, ("metal5" , "LALU5" , 26, 0)
, ("cut5" , "LVIA5" , 28, 0)
, ("metal6" , "LALU6" , 29, 0)
]
loadGdsLayers( gdsLayersTable )

View File

@ -191,8 +191,9 @@ namespace CRL {
bool ToolEngine::_inDestroyAll = false;
ToolEngine::ToolEngine ( Cell* cell )
ToolEngine::ToolEngine ( Cell* cell, bool verbose )
: Super()
, _verbose (verbose)
, _cell (cell)
, _placementModificationFlag(0)
, _routingModificationFlag (0)
@ -219,11 +220,13 @@ namespace CRL {
put( enginesRelation );
cmess1 << " o Creating ToolEngine<" << getName() << "> for Cell <"
<< _cell->getName() << ">" << endl;
cmess1 << Dots::asString( " - Initial memory"
, Timer::getStringMemory(Timer::getMemorySize()) ) << endl;
if (_verbose) {
cmess1 << " o Creating ToolEngine<" << getName() << "> for Cell <"
<< _cell->getName() << ">" << endl;
cmess1 << Dots::asString( " - Initial memory"
, Timer::getStringMemory(Timer::getMemorySize()) ) << endl;
}
}

View File

@ -81,13 +81,14 @@ namespace CRL {
protected:
Cell* _cell;
private:
bool _verbose;
unsigned int _placementModificationFlag;
unsigned int _routingModificationFlag;
bool _inRelationDestroy;
Timer _timer;
uint32_t _passNumber;
protected:
ToolEngine ( Cell* cell );
ToolEngine ( Cell* cell, bool verbose=true );
virtual void _postCreate ();
virtual void _preDestroy ();
protected:

View File

@ -110,8 +110,8 @@ namespace {
inline int getNthRouting () const;
inline void incNthRouting ();
inline RoutingGauge* getRoutingGauge () const;
inline void addPinSegment ( string name, Segment* );
inline void clearPinSegments ();
inline void addPinComponent ( string name, Component* );
inline void clearPinComponents ();
private:
static int _unitsCbk ( lefrCallbackType_e, lefiUnits* , lefiUserData );
static int _layerCbk ( lefrCallbackType_e, lefiLayer* , lefiUserData );
@ -131,7 +131,7 @@ namespace {
Net* _net;
string _busBits;
double _unitsMicrons;
map< string, vector<Segment*> > _pinSegments;
map< string, vector<Component*> > _pinComponents;
static map<string,Layer*> _layerLut;
vector<string> _unmatchedLayers;
vector<string> _errors;
@ -173,8 +173,8 @@ namespace {
inline const vector<string>& LefParser::getErrors () const { return _errors; }
inline void LefParser::pushError ( const string& error ) { _errors.push_back(error); }
inline void LefParser::clearErrors () { return _errors.clear(); }
inline void LefParser::addPinSegment ( string name, Segment* s ) { _pinSegments[name].push_back(s); }
inline void LefParser::clearPinSegments () { _pinSegments.clear(); }
inline void LefParser::addPinComponent ( string name, Component* comp ) { _pinComponents[name].push_back(comp); }
inline void LefParser::clearPinComponents () { _pinComponents.clear(); }
Library* LefParser::_mergeLibrary = nullptr;
@ -520,6 +520,8 @@ namespace {
points.push_back( Point( parser->fromUnitsMicrons(polygon->x[ipoint])
, parser->fromUnitsMicrons(polygon->y[ipoint]) ));
}
points.push_back( Point( parser->fromUnitsMicrons(polygon->x[0])
, parser->fromUnitsMicrons(polygon->y[0]) ));
Rectilinear::create( blockageNet, blockageLayer, points );
continue;
}
@ -577,7 +579,7 @@ namespace {
if (not isPad) parser->_pinStdPostProcess();
else parser->_pinPadPostProcess();
parser->clearPinSegments();
parser->clearPinComponents();
cerr << " - " << cellName
<< " " << DbU::getValueString(width) << " " << DbU::getValueString(height)
@ -667,7 +669,7 @@ namespace {
, parser->fromUnitsMicrons( r->yh )
);
}
if (segment) parser->addPinSegment( pin->name(), segment );
if (segment) parser->addPinComponent( pin->name(), segment );
//cerr << " | " << segment << endl;
continue;
}
@ -678,7 +680,10 @@ namespace {
points.push_back( Point( parser->fromUnitsMicrons(polygon->x[ipoint])
, parser->fromUnitsMicrons(polygon->y[ipoint]) ));
}
Rectilinear::create( net, layer, points );
points.push_back( Point( parser->fromUnitsMicrons(polygon->x[0])
, parser->fromUnitsMicrons(polygon->y[0]) ));
Rectilinear* rectilinear = Rectilinear::create( net, layer, points );
if (rectilinear) parser->addPinComponent( pin->name(), rectilinear );
continue;
}
if (geoms->itemType(igeom) == lefiGeomClassE) {
@ -722,20 +727,27 @@ namespace {
const RoutingLayerGauge* gaugeMetal2 = _routingGauge->getLayerGauge( 1 );
Box ab = _cell->getAbutmentBox();
//cerr << " @ _pinStdPostProcess" << endl;
cerr << " @ _pinStdPostProcess" << endl;
for ( auto element : _pinSegments ) {
string pinName = element.first;
vector<Segment*>& segments = element.second;
vector<Segment*> ongrids;
for ( auto element : _pinComponents ) {
string pinName = element.first;
vector<Component*>& components = element.second;
vector<Segment*> ongrids;
for ( Segment* segment : segments ) {
bool isWide = (segment->getWidth() >= getMinTerminalWidth());
for ( Component* component : components ) {
Segment* segment = dynamic_cast<Segment*>( component );
if (segment) {
if (component->getNet()->isSupply()) continue;
bool isWide = (segment->getWidth() >= getMinTerminalWidth());
//cerr << " > " << segment << endl;
cerr << " > " << segment << endl;
if (not isVH())
cerr << "NOT isVH()" << endl;
else
cerr << "isVH()" << endl;
if (not segment->getNet()->isSupply()) {
if (isVH() and (segment->getLayer()->getMask() == metal1->getMask())) {
cerr << "isVH()" << endl;
Vertical* v = dynamic_cast<Vertical*>( segment );
if (v) {
DbU::Unit nearestX = gaugeMetal2->getTrackPosition( ab.getXMin()
@ -746,7 +758,7 @@ namespace {
if (nearestX == v->getX()) {
} else {
DbU::Unit neighbor = nearestX
+ ((nearestX > v->getX()) ? 1 : -1) * gaugeMetal2->getPitch();
+ ((nearestX > v->getX()) ? 1 : -1) * gaugeMetal2->getPitch();
//cerr << " | X:" << DbU::getValueString(v->getX())
// << " nearestX:" << DbU::getValueString(nearestX)
@ -772,16 +784,67 @@ namespace {
}
}
}
}
if (isWide) ongrids.push_back( segment );
if (isWide) ongrids.push_back( segment );
}
Rectilinear* rectilinear = dynamic_cast<Rectilinear*>( component );
if (not (rectilinear->getLayer()->getMask() == metal1->getMask()))
continue;
if (rectilinear) {
cerr << " > " << rectilinear << endl;
vector<Box> boxes;
rectilinear->getAsRectangles( boxes );
if (component->getNet()->isSupply()) {
ongrids.push_back( Horizontal::create( rectilinear->getNet()
, rectilinear->getLayer()
, boxes.front().getYCenter()
, boxes.front().getHeight()
, _cell->getAbutmentBox().getXMin()
, _cell->getAbutmentBox().getXMax()
)
);
} else {
for ( const Box& box : boxes ) {
DbU::Unit nearestX = gaugeMetal2->getTrackPosition( ab.getXMin()
, ab.getXMax()
, box.getXCenter()
, Constant::Nearest );
DbU::Unit xmin = std::min( box.getXMin(), nearestX - gaugeMetal2->getViaWidth()/2 );
DbU::Unit xmax = std::max( box.getXMax(), nearestX + gaugeMetal2->getViaWidth()/2 );
ongrids.push_back( Vertical::create( rectilinear->getNet()
, rectilinear->getLayer()
, (xmax+xmin)/2
, xmax-xmin
, box.getYMin()
, box.getYMax()
)
);
// DbU::Unit neighbor = nearestY
// + ((nearestY > box.getYCenter()) ? 1 : -1) * gaugeMetal2->getPitch();
// if ( (box.getYMin() > neighbor)
// or (box.getYMax() < neighbor) ) {
// ongrids.push_back( Vertical::create( rectilinear->getNet()
// , rectilinear->getLayer()
// , box.getXCenter()
// , box.getWidth()
// , box.getYMin()
// , box.getYMax()
// )
// );
// }
}
}
}
}
if (ongrids.empty()) {
cerr << Warning( "LefParser::_pinStdPostProcess(): Pin \"%s\" has no terminal ongrid."
, pinName.c_str() ) << endl;
for ( Segment* segment : segments ) {
NetExternalComponents::setExternal( segment );
for ( Component* component : components ) {
NetExternalComponents::setExternal( component );
}
} else {
for ( Segment* segment : ongrids ) {
@ -797,10 +860,10 @@ namespace {
Box ab = getCell()->getAbutmentBox();
bool isCornerPad = (_cellGauge) and (_cellGauge->getSliceHeight() == _cellGauge->getSliceStep());
for ( auto element : _pinSegments ) {
string pinName = element.first;
vector<Segment*>& segments = element.second;
vector<Segment*> ongrids;
for ( auto element : _pinComponents ) {
string pinName = element.first;
vector<Component*>& segments = element.second;
vector<Segment*> ongrids;
if (segments.empty()) continue;

View File

@ -1,6 +1,5 @@
# -*- explicit-buffer-name: "CMakeLists.txt<crlcore/src/ccore/cyclop>" -*-
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
include_directories ( ${CRLCORE_SOURCE_DIR}/src/ccore
${HURRICANE_INCLUDE_DIR}
${UTILITIES_INCLUDE_DIR}

View File

@ -32,8 +32,6 @@
-lutil
)
find_package (Python3 COMPONENTS Interpreter Development)
add_definitions( -DCORIOLIS_TOP="${CORIOLIS_TOP}"
-DSYS_CONF_DIR="${SYS_CONF_DIR}"
-DPYTHON_SITE_PACKAGES="${PYTHON_SITE_PACKAGES}"

View File

@ -1,7 +1,6 @@
# -*- explicit-buffer-name: "CMakeLists.txt<crlcore/src/x2y> -*-
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
include_directories ( ${CRLCORE_SOURCE_DIR}/src/ccore
${HURRICANE_INCLUDE_DIR}
${UTILITIES_INCLUDE_DIR}

View File

@ -64,7 +64,7 @@ class PnR ( FlowTask ):
else:
print( 'PnR.doTask() run in interactive CGT mode.' )
PnR.textMode = False
from .. import Etesian, Anabatic, Katana, Bora, Tutorial, Viewer, Unicorn
from .. import Etesian, Anabatic, Katana, Bora, Tramontana, Tutorial, Viewer, Unicorn
ShellEnv().export()
if self.script and not callable(self.script):
@ -80,8 +80,8 @@ class PnR ( FlowTask ):
unicorn = Unicorn.UnicornGui.create()
unicorn.setApplicationName ( 'cgt')
unicorn.registerTool ( Etesian.GraphicEtesianEngine.grab() )
#unicorn.registerTool ( Kite.GraphicKiteEngine.grab() )
unicorn.registerTool ( Katana.GraphicKatanaEngine.grab() )
unicorn.registerTool ( Tramontana.GraphicTramontanaEngine.grab() )
unicorn.registerTool ( Bora.GraphicBoraEngine.grab() )
unicorn.registerTool ( Tutorial.GraphicTutorialEngine.grab() )
#unicorn.setAnonNetSelectable(False)

View File

@ -82,6 +82,46 @@ def setupCMOS ( checkToolkit=None ):
break
def setupLCMOS ( checkToolkit=None ):
Where( checkToolkit )
ShellEnv().export()
from .. import Cfg
from .. import Viewer
from .. import CRL
from ..helpers import overlay, l, u, n
from .yosys import Yosys
import coriolis.technos.symbolic.lcmos
with overlay.CfgCache(priority=Cfg.Parameter.Priority.UserFile) as cfg:
cfg.misc.catchCore = False
cfg.misc.info = False
cfg.misc.paranoid = False
cfg.misc.bug = False
cfg.misc.logMode = True
cfg.misc.verboseLevel1 = True
cfg.misc.verboseLevel2 = True
cfg.misc.minTraceLevel = 1900
cfg.misc.maxTraceLevel = 3000
cfg.katana.eventsLimit = 1000000
cfg.katana.termSatReservedLocal = 6
cfg.katana.termSatThreshold = 9
Viewer.Graphics.setStyle( 'Alliance.Classic [black]' )
af = CRL.AllianceFramework.get()
env = af.getEnvironment()
env.setCLOCK( '^ck$|m_clock|^clk$' )
Yosys.setLiberty( Where.checkToolkit / 'cells' / 'lsxlib' / 'lsxlib.lib' )
ShellEnv.RDS_TECHNO_NAME = (Where.allianceTop / 'etc' / 'cmos.rds').as_posix()
path = None
for pathVar in [ 'PATH', 'path' ]:
if pathVar in os.environ:
path = os.environ[ pathVar ]
os.environ[ pathVar ] = path + ':' + (Where.allianceTop / 'bin').as_posix()
break
def setupCMOS45 ( useNsxlib=False, checkToolkit=None, cellsTop=None ):
from .. import Cfg
from .. import Viewer
@ -190,6 +230,7 @@ def setupSky130_c4m ( checkToolkit=None, pdkMasterTop=None ):
cfg.misc.logMode = True
cfg.misc.verboseLevel1 = False
cfg.misc.verboseLevel2 = False
cfg.viewer.pixelThreshold = 5
cfg.etesian.graphics = 2
cfg.anabatic.topRoutingLayer = 'm4'
cfg.katana.eventsLimit = 4000000

View File

@ -17,8 +17,8 @@
set_cmake_policies()
setup_boost(program_options)
setup_python()
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
find_package(PythonSitePackages REQUIRED)
find_package(HURRICANE REQUIRED)
#find_package(KATABATIC REQUIRED)

View File

@ -10,7 +10,6 @@
${Boost_INCLUDE_DIRS}
${Python_INCLUDE_DIRS}
)
find_package (Python3 COMPONENTS Interpreter Development)
set( includes etesian/Configuration.h
etesian/Placement.h
etesian/FeedCells.h

View File

@ -1205,8 +1205,8 @@ namespace Etesian {
Instance* instance = static_cast<Instance*>(occurrence.getEntity());
string instanceName = occurrence.getCompactString();
// Remove the enclosing brackets...
instanceName.erase( 0, 1 );
instanceName.erase( instanceName.size()-1 );
//instanceName.erase( 0, 1 );
//instanceName.erase( instanceName.size()-1 );
auto iid = _instsToIds.find( instance );
if (iid == _instsToIds.end() ) {

View File

@ -16,8 +16,8 @@
set_cmake_policies()
check_distribution()
setup_sysconfdir( "${CMAKE_INSTALL_PREFIX}" )
setup_python()
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
find_package(PythonSitePackages REQUIRED)
find_package(HURRICANE REQUIRED)
find_package(CORIOLIS REQUIRED)

View File

@ -6,7 +6,6 @@
${CONFIGURATION_INCLUDE_DIR}
${Python_INCLUDE_DIRS}
)
find_package (Python3 COMPONENTS Interpreter Development)
set( includes flute.h
dl.h

View File

@ -18,9 +18,9 @@
set_cmake_policies()
setup_boost(program_options)
setup_qt()
setup_python()
find_package(Libexecinfo REQUIRED)
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
find_package(PythonSitePackages REQUIRED)
find_package(LEFDEF REQUIRED)
find_package(FLUTE REQUIRED)

View File

@ -20,11 +20,11 @@
cmake_policy(SET CMP0054 NEW)
setup_boost(program_options)
setup_qt()
setup_python()
find_package(BZip2 REQUIRED)
find_package(BISON REQUIRED)
find_package(FLEX REQUIRED)
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development )
find_package(PythonSitePackages REQUIRED)
find_package(Libexecinfo REQUIRED)
if (USE_LIBBFD)

View File

@ -36,7 +36,7 @@ namespace Hurricane {
#ifdef HAVE_CXA_DEMANGLE
string demangle ( const char* symbol )
{
{
int status;
size_t length = 4096;
char demangled[length];
@ -49,13 +49,25 @@ string demangle ( const char* symbol )
#else
string demangle ( const char* symbol )
{
return symbol;
}
{ return symbol; }
#endif
string& split ( string& s )
{
size_t i = s.find( "<" );
while ( i != string::npos ) {
if (i+3 > s.size()) break;
//if (s[i+2] != '>') {
s.insert( i, "\\n" );
//}
i = s.find( "<", i+3 );
}
return s;
}
} // End of Hurricane namespace.

View File

@ -118,6 +118,9 @@ Contact::Contact(Net* net, const Layer* layer, DbU::Unit x, DbU::Unit y, DbU::Un
{
if (not _layer)
throw Error("Contact::Contact(): Can't create " + _TName("Contact") + ", NULL layer.");
if ( _width < _layer->getMinimalSize() ) _width = _layer->getMinimalSize();
if ( _height < _layer->getMinimalSize() ) _height = _layer->getMinimalSize();
}
Contact::Contact(Net* net, Component* anchor, const Layer* layer, DbU::Unit dx, DbU::Unit dy, DbU::Unit width, DbU::Unit height)

View File

@ -111,21 +111,21 @@ bool Interval::intersect(const Interval& interval, bool strict) const
if (isEmpty() or interval.isEmpty()) return false;
if ( (_vMax < interval._vMin) or (interval._vMax < _vMin) ) return false;
return not strict or ( (_vMax != interval._vMin) and (interval._vMax != _vMin) );
return not strict or ( (_vMax > interval._vMin) or (interval._vMax > _vMin) );
}
bool Interval::inferior(const Interval& interval, bool strict) const
// *****************************************************************
{
if (_vMax < interval._vMin) return true;
return not strict and (_vMax == interval._vMin);
if (_vMax == interval._vMin) return not strict;
return (_vMax < interval._vMin);
}
bool Interval::superior(const Interval& interval, bool strict) const
// *****************************************************************
{
if (_vMin > interval._vMax) return true;
return !strict && (_vMin == interval._vMax);
return not (strict or (_vMin != interval._vMax));
}
bool Interval::isConstrainedBy(const Interval& interval) const

View File

@ -772,15 +772,23 @@ void Net::_preDestroy()
cdebug_tabw(18,-1);
}
string Net::_getFlagsAsString() const
// **********************************
{
string ds;
ds += ((isDeepNet() ) ? "d" : "-");
ds += ((_isExternal ) ? "e" : "-");
ds += ((_isGlobal ) ? "g" : "-");
ds += ((_isAutomatic) ? "a" : "-");
return ds;
}
string Net::_getString() const
// ***************************
{
string bs = Inherit::_getString();
string ds = "\"" + getString(_name) + "\" ";
ds += ((isDeepNet() ) ? "d" : "-");
ds += ((_isExternal ) ? "e" : "-");
ds += ((_isGlobal ) ? "g" : "-");
ds += ((_isAutomatic) ? "a" : "-");
ds += _getFlagsAsString();
ds += " ";
ds += getString(_type ) + " ";
ds += getString(_direction);

View File

@ -96,16 +96,27 @@ bool Occurrence::operator!=(const Occurrence& occurrence) const
bool Occurrence::operator<(const Occurrence& occurrence) const
// ********************************************************
{
if (not _entity and not occurrence._entity) return false;
if (not _entity) return true;
if (not occurrence._entity) return false;
cdebug_log(0,0) << "Occurrence::operator<()" << endl;
cdebug_log(0,0) << "| lhs=" << *this << endl;
cdebug_log(0,0) << "| rhs=" << occurrence << endl;
if ((not _sharedPath) xor (not occurrence._sharedPath)) return not _sharedPath;
if ((not _entity ) xor (not occurrence._entity )) return not _entity;
if (_entity and (_entity->getId() != occurrence._entity->getId()))
return _entity->getId() < occurrence._entity->getId();
if (not _sharedPath) return false;
if (_entity->getId() < occurrence._entity->getId()) return true;
if (_entity->getId() > occurrence._entity->getId()) return false;
// if (not _sharedPath) return true;
// if (not occurrence._sharedPath) return false;
// if (not _sharedPath and not occurrence._sharedPath) return false;
// if (not _sharedPath) return true;
// if (not occurrence._sharedPath) return false;
if (not _sharedPath and not occurrence._sharedPath) return false;
if (not _sharedPath) return true;
if (not occurrence._sharedPath) return false;
// if (not _entity and not occurrence._entity) return false;
// if (not _entity) return true;
// if (not occurrence._entity) return false;
// if (_entity->getId() < occurrence._entity->getId()) return true;
// if (_entity->getId() > occurrence._entity->getId()) return false;
return _sharedPath->getHash() < occurrence._sharedPath->getHash();
@ -274,11 +285,12 @@ string Occurrence::_getString() const
string Occurrence::getCompactString() const
// ****************************************
{
string s = "<";
string s;
if (_entity) {
s += getString(getOwnerCell()->getName());
s += ":";
if (_sharedPath) s += getString(_sharedPath->getName()) + ":";
if (_sharedPath) s += getString(_sharedPath->getName());
s += ":";
Instance* instance = dynamic_cast<Instance*>(_entity);
if (instance) {
s += "I."+getString(instance->getName());
@ -291,7 +303,6 @@ string Occurrence::getCompactString() const
}
}
}
s += ">";
return s;
}

View File

@ -40,6 +40,284 @@
#include "hurricane/Warning.h"
namespace {
using namespace std;
using Hurricane::DbU;
using Hurricane::Point;
using Hurricane::Box;
using Hurricane::Interval;
using Hurricane::Rectilinear;
class SweepInterval : public Interval {
public:
inline SweepInterval ( DbU::Unit vmin , DbU::Unit vmax, DbU::Unit xmin );
inline SweepInterval ( Interval&, DbU::Unit xmin );
inline SweepInterval& inflate ( DbU::Unit dvMin, DbU::Unit dvMax );
inline SweepInterval& merge ( DbU::Unit v );
inline DbU::Unit getXMin () const;
inline void setXMin ( DbU::Unit );
inline string _getString () const;
private:
DbU::Unit _xMin;
};
inline SweepInterval::SweepInterval ( DbU::Unit vmin , DbU::Unit vmax, DbU::Unit xmin )
: Interval(vmin,vmax)
, _xMin (xmin)
{ }
inline SweepInterval::SweepInterval ( Interval& base, DbU::Unit xmin )
: Interval(base)
, _xMin (xmin)
{ }
inline SweepInterval& SweepInterval::inflate ( DbU::Unit dvMin, DbU::Unit dvMax ) { Interval::inflate(dvMin,dvMax); return *this; }
inline SweepInterval& SweepInterval::merge ( DbU::Unit v ) { Interval::merge(v); return *this; }
inline DbU::Unit SweepInterval::getXMin () const { return _xMin; }
inline void SweepInterval::setXMin ( DbU::Unit xmin ) { _xMin=xmin; }
inline string SweepInterval::_getString () const
{
string s;
s += "@" + DbU::getValueString(_xMin);
s += " [" + DbU::getValueString(getVMin());
s += " " + DbU::getValueString(getVMax()) + "]";
return s;
}
} // Anonymous namespace.
GETSTRING_VALUE_SUPPORT(::SweepInterval);
namespace {
class SweepLine {
public:
SweepLine ( const Rectilinear*, vector<Box>& );
~SweepLine ();
void addVEdge ( DbU::Unit ymin, DbU::Unit ymax, DbU::Unit x );
void loadVEdges ();
void process ( Interval );
void process ( const pair< DbU::Unit, list<Interval> >& );
void toBox ( SweepInterval& );
void asRectangles ();
private:
const Rectilinear* _rectilinear;
vector<Box>& _boxes;
list< pair< DbU::Unit, list<Interval> > > _vedges;
list< SweepInterval > _sweepLine;
DbU::Unit _prevX;
DbU::Unit _currX;
};
SweepLine::SweepLine ( const Rectilinear* r, vector<Box>& boxes )
: _rectilinear(r)
, _boxes (boxes)
, _vedges ()
, _sweepLine ()
, _prevX (0)
, _currX (0)
{
cdebug_log(17,1) << "SweepLine::SweepLine()" << endl;
}
SweepLine::~SweepLine ()
{
cdebug_tabw(17,-1);
}
void SweepLine::addVEdge ( DbU::Unit ymin, DbU::Unit ymax, DbU::Unit x )
{
if (ymin > ymax) std::swap( ymin, ymax );
cdebug_log(17,1) << "SweepLine::addVEdge() @"<< DbU::getValueString(x)
<< " [" << DbU::getValueString(ymin)
<< " " << DbU::getValueString(ymax) << "]" << endl;
bool inserted = false;
for ( auto ix = _vedges.begin() ; ix != _vedges.end() ; ++ix ) {
cdebug_log(17,0) << "| Looking @" << DbU::getValueString(ix->first)
<< " size=" << ix->second.size() << endl;
if (ix->first > x) {
_vedges.insert( ix, make_pair( x, list<Interval>() ));
cdebug_log(17,0) << "+ add new @" << DbU::getValueString(x) << endl;
--ix;
}
if (ix->first == x) {
for ( auto iintv = ix->second.begin() ; iintv != ix->second.end() ; ++iintv ) {
if (iintv->getVMin() >= ymax) {
ix->second.insert( iintv, Interval(ymin,ymax) );
inserted = true;
break;
}
}
if (not inserted) {
ix->second.push_back( Interval(ymin,ymax) );
inserted = true;
}
break;
}
}
if (not inserted) {
cdebug_log(17,0) << "+ add new (back) @" << DbU::getValueString(x) << endl;
_vedges.push_back( make_pair( x, list<Interval>() ));
_vedges.back().second.push_back( Interval(ymin,ymax) );
}
cdebug_tabw(17,-1);
}
void SweepLine::loadVEdges ()
{
const vector<Point>& points = _rectilinear->getPoints();
for ( size_t i=0 ; i<points.size()-1 ; ++i ) {
const Point& source = points[ i ];
const Point& target = points[ (i+1) % points.size() ];
DbU::Unit dx = target.getX() - source.getX();
//DbU::Unit dy = target.getY() - source.getY();
if (dx == 0) {
addVEdge( source.getY(), target.getY(), source.getX() );
}
}
}
void SweepLine::toBox ( SweepInterval& intv )
{
if (intv.getXMin() == _currX) return;
_boxes.push_back( Box( intv.getXMin(), intv.getVMin()
, _currX , intv.getVMax() ));
intv.setXMin( _currX );
}
void SweepLine::process ( Interval v )
{
cdebug_log(17,1) << "SweepLine::process(Interval&) "
<< " [" << DbU::getValueString(v.getVMin())
<< " " << DbU::getValueString(v.getVMax()) << "]" << endl;
bool done = false;
for ( auto iintv = _sweepLine.begin() ; iintv != _sweepLine.end() ; ++iintv ) {
// Extractor p. 9 (a).
if (v.getVMax() < iintv->getVMin()) {
_sweepLine.insert( iintv, SweepInterval(v,_currX) );
done = true;
break;
}
// Extractor p. 9 (f).
if ( (v.getVMin() == iintv->getVMin())
and (v.getVMax() == iintv->getVMax()) ) {
toBox( *iintv );
_sweepLine.erase( iintv );
done = true;
break;
}
// Extractor p. 9 (b).
if (v.getVMax() == iintv->getVMin()) {
toBox( *iintv );
iintv->merge( v.getVMin() );
done = true;
break;
}
// Extractor p. 9 (g).
if (v.getVMax() == iintv->getVMax()) {
toBox( *iintv );
cdebug_log(17,0) << "case (g): carve" << endl;
iintv->inflate( 0, v.getVMin() - iintv->getVMax() );
cdebug_log(17,0) << "| " << (*iintv) << endl;
done = true;
break;
}
// Extractor p. 9 (h).
if (v.getVMin() == iintv->getVMin()) {
toBox( *iintv );
iintv->inflate(iintv->getVMin() - v.getVMax(), 0 );
done = true;
break;
}
// Extractor p. 9 (c).
if ( (v.getVMin() > iintv->getVMin())
and (v.getVMax() < iintv->getVMax()) ) {
toBox( *iintv );
cdebug_log(17,0) << "case (c): carve" << endl;
DbU::Unit wholeVMin = iintv->getVMin();
iintv->inflate( iintv->getVMin() - v.getVMax(), 0 );
cdebug_log(17,0) << "| " << (*iintv) << endl;
_sweepLine.insert( iintv, SweepInterval( wholeVMin, v.getVMin(), _currX ) );
cdebug_log(17,0) << "| " << (*(--iintv)) << endl;
done = true;
break;
}
// Extractor p. 9 (d,e).
if (v.getVMin() == iintv->getVMax()) {
auto iintvNext = iintv;
++iintvNext;
// Extractor p. 9 (d).
if (iintvNext == _sweepLine.end()) {
toBox( *iintv );
iintv->merge( v.getVMax() );
} else {
// Extractor p. 9 (d).
if (v.getVMax() < iintvNext->getVMin()) {
toBox( *iintv );
iintv->merge( v.getVMax() );
} else {
// Extractor p. 9 (e).
toBox( *iintv );
toBox( *iintvNext );
iintv->merge( iintvNext->getVMax() );
_sweepLine.erase( iintvNext );
}
}
done = true;
break;
}
}
if (not done) {
_sweepLine.push_back( SweepInterval(v,_currX) );
}
cdebug_tabw(17,-1);
}
void SweepLine::process ( const pair< DbU::Unit, list<Interval> >& intervals )
{
cdebug_log(17,1) << "SweepLine::process() @"<< DbU::getValueString(intervals.first)
<< " size=" << intervals.second.size() << endl;
_currX = intervals.first;
for ( const Interval& v : intervals.second ) process( v );
cdebug_tabw(17,-1);
}
void SweepLine::asRectangles ()
{
loadVEdges();
for ( auto intervals : _vedges ) {
process( intervals );
}
cdebug_log(17,0) << "SweepLine::asRectangles() size=" << _boxes.size() << endl;
for ( const Box& b : _boxes )
cdebug_log(17,0) << "| " << b << endl;
}
} // Anonymous namespace.
namespace Hurricane {
@ -50,6 +328,7 @@ namespace Hurricane {
: Super (net)
, _layer (layer)
, _points(points)
, _flags (IsRectilinear)
{ }
@ -58,9 +337,21 @@ namespace Hurricane {
if (not layer)
throw Error( "Rectilinear::create(): Can't create, NULL layer" );
if (points.size() > 1000)
throw Error( "Rectilinear::create(): Rectlinear polygons must not exceed 1000 vertexes." );
if (points.size() < 4)
throw Error( "Rectilinear::create(): Rectilinear polygons must at least contains 3 vertexes." );
if (points.size() > 1000)
throw Error( "Rectilinear::create(): Rectilinear polygons must not exceed 1000 vertexes." );
if (points[0] != points[points.size()-1])
throw Error( "Rectilinear::create(): First and last point must be the same.\n"
"0:%s %d:%s"
, getString(points[0]).c_str()
, points.size()-1
, getString(points[points.size()-1]).c_str()
);
bool isRect = true;
DbU::Unit oneGrid = DbU::fromGrid( 1.0 );
for ( size_t i=0 ; i<points.size() ; ++i ) {
size_t j = (i+1) % points.size();
@ -68,9 +359,12 @@ namespace Hurricane {
DbU::Unit dx = std::abs( points[i].getX() - points[j].getX() );
DbU::Unit dy = std::abs( points[i].getY() - points[j].getY() );
if ( (dx != 0) and (dy != 0) and (dx != dy) )
throw Error( "Rectilinear::create(): Can't create, non H/V edge (points %d:%s - %d:%s)."
, i, getString(points[i]).c_str(), j, getString(points[j]).c_str() );
if ((dx != 0) and (dy != 0)) {
isRect = false;
if (dx != dy)
throw Error( "Rectilinear::create(): Can't create, non H/V edge (points %d:%s - %d:%s)."
, i, getString(points[i]).c_str(), j, getString(points[j]).c_str() );
}
if (points[i].getX() % oneGrid)
cerr << Warning( "Rectilinear::create(): In Cell \"%s\", Net \"%s\",\n"
@ -91,7 +385,7 @@ namespace Hurricane {
}
Rectilinear* rectilinear = new Rectilinear ( net, layer, points );
if (not isRect) rectilinear->_flags &= ~IsRectilinear;
rectilinear->_postCreate();
return rectilinear;
@ -176,6 +470,15 @@ namespace Hurricane {
}
bool Rectilinear::getAsRectangles ( std::vector<Box>& rectangles ) const
{
rectangles.clear();
if (not isRectilinear()) return false;
SweepLine( this, rectangles ).asRectangles();
return true;
}
void Rectilinear::_toJson ( JsonWriter* writer ) const
{
Inherit::_toJson( writer );

View File

@ -146,6 +146,9 @@ namespace Hurricane {
}
string& split ( std::string& );
} // End of Hurricane namespace.

View File

@ -21,6 +21,7 @@
#ifndef HURRICANE_COMPONENT_H
#define HURRICANE_COMPONENT_H
#include <set>
#include "hurricane/Points.h"
#include "hurricane/Go.h"
#include "hurricane/Components.h"
@ -170,6 +171,9 @@ namespace Hurricane {
};
typedef std::set<Component*,DBo::CompareById> ComponentSet;
} // Hurricane namespace.

View File

@ -1,6 +1,6 @@
// -*- C++ -*-
//
// Copyright (c) BULL S.A. 2000-2018, All Rights Reserved
// Copyright (c) BULL S.A. 2000-2023, All Rights Reserved
//
// This file is part of Hurricane.
//
@ -29,9 +29,7 @@
// +-----------------------------------------------------------------+
#ifndef HURRICANE_INTERVAL_H
#define HURRICANE_INTERVAL_H
#pragma once
#include "hurricane/DbU.h"
namespace Hurricane {
@ -48,6 +46,11 @@ namespace Hurricane {
inline bool operator() ( const Interval& rhs, const Interval& lhs ) const;
inline bool operator() ( const Interval* rhs, const Interval* lhs ) const;
};
class CompareByMinMax {
public:
inline bool operator() ( const Interval& rhs, const Interval& lhs ) const;
inline bool operator() ( const Interval* rhs, const Interval* lhs ) const;
};
public:
Interval ( bool makeEmpty=true );
Interval ( const DbU::Unit& );
@ -124,6 +127,20 @@ namespace Hurricane {
{ return lhs->getVMin() < rhs->getVMin(); }
inline bool Interval::CompareByMinMax::operator() ( const Interval& lhs, const Interval& rhs ) const
{
if (lhs.getVMin() != rhs.getVMin()) return lhs.getVMin() < rhs.getVMin();
return lhs.getVMax() < rhs.getVMax();
}
inline bool Interval::CompareByMinMax::operator() ( const Interval* lhs, const Interval* rhs ) const
{
if (lhs->getVMin() != rhs->getVMin()) return lhs->getVMin() < rhs->getVMin();
return lhs->getVMax() < rhs->getVMax();
}
} // Hurricane namespace.
@ -136,7 +153,5 @@ inline void jsonWrite ( JsonWriter* w, const std::string& key, const Hurricane:
w->endArray();
}
INSPECTOR_PR_SUPPORT(Hurricane::Interval);
#endif // HURRICANE_INTERVAL_H

View File

@ -1,6 +1,6 @@
// -*- C++ -*-
//
// Copyright (c) BULL S.A. 2018-2018, All Rights Reserved
// Copyright (c) BULL S.A. 2018-2023, All Rights Reserved
//
// This file is part of Hurricane.
//
@ -34,9 +34,7 @@
// Third edition, MIT press, 2011, p. 348.
#ifndef HURRICANE_INTERVAL_TREE_H
#define HURRICANE_INTERVAL_TREE_H
#pragma once
#include "hurricane/Interval.h"
#include "hurricane/RbTree.h"
@ -57,6 +55,7 @@ namespace Hurricane {
inline Data& getData () const;
inline DbU::Unit getChildsVMax () const;
inline DbU::Unit updateChildsVMax ( DbU::Unit lvmax, DbU::Unit rvmax );
inline bool operator== ( const IntervalData& ) const;
string _getString () const;
Record* _getRecord () const;
private:
@ -64,7 +63,7 @@ namespace Hurricane {
Data data_;
};
template< typename Data >
inline IntervalData<Data>::IntervalData ()
: Interval(1,-1)
@ -93,7 +92,17 @@ namespace Hurricane {
template< typename Data >
inline DbU::Unit IntervalData<Data>::updateChildsVMax ( DbU::Unit lvmax, DbU::Unit rvmax )
{ childsVMax_ = std::max( getVMax(), std::max( lvmax, rvmax ) ); return childsVMax_; }
{
cdebug_log(0,0) << "IntervalData::updateChildsVMax() " << DbU::getValueString(lvmax)
<< " " << DbU::getValueString(lvmax)
<< " " << this << endl;
childsVMax_ = std::max( getVMax(), std::max( lvmax, rvmax ) ); return childsVMax_;
}
template< typename Data >
inline bool IntervalData<Data>::operator== ( const IntervalData<Data>& other ) const
{ return Interval::operator==(*this) and (data_ == other.data_); }
template< typename Data >
@ -117,14 +126,35 @@ namespace Hurricane {
return record;
}
// -------------------------------------------------------------------
// Class : "Hurricane::IntervalDataCompare".
template< typename Data, typename DataCompare=std::less<Data> >
class IntervalDataCompare {
public:
inline bool operator() ( const IntervalData<Data>& lhs, const IntervalData<Data>& rhs ) const
{
static Interval::CompareByMinMax compare;
static DataCompare dataCompare;
if ( (lhs.getVMin() == rhs.getVMin())
and (lhs.getVMax() == rhs.getVMax())) {
cdebug_log(0,0) << "IntervalDataCompare::operator<() - Data fallback." << endl;
cdebug_log(0,0) << "| " << lhs.getData() << endl;
return dataCompare( lhs.getData(), rhs.getData() );
}
return compare( lhs, rhs );
}
};
// -------------------------------------------------------------------
// Class : "Hurricane::IntervalTree".
template< typename Data >
class IntervalTree : public RbTree< IntervalData<Data>, Interval::CompareByMin > {
template< typename Data, typename DataCompare=std::less<Data> >
class IntervalTree : public RbTree< IntervalData<Data>, IntervalDataCompare<Data,DataCompare> > {
public:
typedef RbTree< IntervalData<Data>, Interval::CompareByMin > Super;
typedef RbTree< IntervalData<Data>, IntervalDataCompare<Data,DataCompare> > Super;
public:
class overlap_iterator : public Super::iterator {
public:
@ -171,31 +201,39 @@ namespace Hurricane {
size_t getThickness () const;
overlap_iterator beginOverlaps ( const Interval& ) const;
inline OverlapElements getOverlaps ( const Interval& ) const;
void checkVMax () const;
void checkVMax ( typename Super::Node* node ) const;
private:
inline void updateChildsVMax ( typename Super::Node* );
};
template< typename Data >
IntervalTree<Data>::overlap_iterator::overlap_iterator ( const typename Super::Node* node, const Interval& overlap )
template< typename Data, typename DataCompare >
IntervalTree<Data,DataCompare>::overlap_iterator::overlap_iterator ( const typename Super::Node* node, const Interval& overlap )
: Super::iterator(node)
, overlap_(overlap)
{ }
template< typename Data >
typename IntervalTree<Data>::overlap_iterator& IntervalTree<Data>::overlap_iterator::operator++ ()
{
while (this->isValid()) {
cdebug_log(0,0) << "IntervalTree::overlap_iterator CTOR "
<< (node ? ::getString(node->getValue()) : "node=NULL")
<< " " << overlap << endl;
}
template< typename Data, typename DataCompare >
typename IntervalTree<Data,DataCompare>::overlap_iterator&
IntervalTree<Data,DataCompare>::overlap_iterator::operator++ ()
{
cdebug_log(0,0) << "IntervalTree::overlap_iterator::operator++()" << endl;
while ( true ) {
Super::iterator::operator++();
if (not this->isValid()) break;
cdebug_log(0,0) << "IntervalTree::overlap_iterator::operator++() "
<< ::getString(this->getNode()) << std::endl;
cdebug_log(0,0) << " ==> " << ::getString(this->getNode()->getValue()) << std::endl;
if (this->getNode()->getValue().intersect(overlap_,true)) break;
cdebug_log(0,0) << "NO intersections" << endl;
if (overlap_.inferior(this->getNode()->getValue(),true)) {
cdebug_log(0,0) << "Node is inferior, stop here." << endl;
if (this->getNode()->getValue().intersect(overlap_,false)) break;
cdebug_log(0,0) << " NO intersections" << endl;
if (overlap_.inferior(this->getNode()->getValue(),false)) {
cdebug_log(0,0) << " Node is inferior, stop here." << endl;
this->setNode( NULL );
break;
}
@ -208,44 +246,45 @@ namespace Hurricane {
// Class : "Hurricane::IntervalTree::OverlapOverlapElements" (implementation)
template< typename Data >
inline IntervalTree<Data>::OverlapElements::Locator::Locator ( const Locator &locator )
template< typename Data, typename DataCompare >
inline IntervalTree<Data,DataCompare>::OverlapElements::Locator::Locator ( const Locator &locator )
: Hurricane::Locator< IntervalData<Data> >()
, iterator_(locator.iterator_)
{ }
template< typename Data >
IntervalTree<Data>::OverlapElements::Locator::Locator ( const IntervalTree<Data>& tree, const Interval& span )
template< typename Data, typename DataCompare >
IntervalTree<Data,DataCompare>::OverlapElements::Locator::Locator ( const IntervalTree<Data,DataCompare>& tree, const Interval& span )
: Hurricane::Locator< IntervalData<Data> >()
, iterator_(tree.beginOverlaps(span))
{ }
template< typename Data >
typename IntervalTree<Data>::OverlapElements::Locator* IntervalTree<Data>::OverlapElements::Locator::getClone () const
template< typename Data, typename DataCompare >
typename IntervalTree<Data,DataCompare>::OverlapElements::Locator*
IntervalTree<Data,DataCompare>::OverlapElements::Locator::getClone () const
{ return new Locator(*this); }
template< typename Data >
IntervalData<Data> IntervalTree<Data>::OverlapElements::Locator::getElement () const
template< typename Data, typename DataCompare >
IntervalData<Data> IntervalTree<Data,DataCompare>::OverlapElements::Locator::getElement () const
{ return (*iterator_); }
template< typename Data >
bool IntervalTree<Data>::OverlapElements::Locator::isValid () const
template< typename Data, typename DataCompare >
bool IntervalTree<Data,DataCompare>::OverlapElements::Locator::isValid () const
{ return iterator_.isValid(); }
template< typename Data >
void IntervalTree<Data>::OverlapElements::Locator::progress ()
template< typename Data, typename DataCompare >
void IntervalTree<Data,DataCompare>::OverlapElements::Locator::progress ()
{
if (isValid()) ++iterator_;
}
template< typename Data >
std::string IntervalTree<Data>::OverlapElements::Locator::_getString () const
template< typename Data, typename DataCompare >
std::string IntervalTree<Data,DataCompare>::OverlapElements::Locator::_getString () const
{
std::string s = "<" + _TName("OverlapElements::Locator")
+ ">";
@ -253,34 +292,34 @@ namespace Hurricane {
}
template< typename Data >
inline IntervalTree<Data>::OverlapElements::OverlapElements ( const IntervalTree& tree, const Interval& span )
template< typename Data, typename DataCompare >
inline IntervalTree<Data,DataCompare>::OverlapElements::OverlapElements ( const IntervalTree& tree, const Interval& span )
: Collection< IntervalData<Data> >()
, tree_(tree)
, span_(span)
{ }
template< typename Data >
inline IntervalTree<Data>::OverlapElements::OverlapElements ( const OverlapElements& elements )
template< typename Data, typename DataCompare >
inline IntervalTree<Data,DataCompare>::OverlapElements::OverlapElements ( const OverlapElements& elements )
: Collection< IntervalData<Data> >()
, tree_(elements.tree_)
, span_(elements.span_)
{ }
template< typename Data >
Collection< IntervalData<Data> >* IntervalTree<Data>::OverlapElements::getClone () const
template< typename Data, typename DataCompare >
Collection< IntervalData<Data> >* IntervalTree<Data,DataCompare>::OverlapElements::getClone () const
{ return new OverlapElements(*this); }
template< typename Data >
typename IntervalTree<Data>::OverlapElements::Locator* IntervalTree<Data>::OverlapElements::getLocator () const
template< typename Data, typename DataCompare >
typename IntervalTree<Data,DataCompare>::OverlapElements::Locator* IntervalTree<Data,DataCompare>::OverlapElements::getLocator () const
{ return new Locator( tree_, span_ ); }
template< typename Data >
std::string IntervalTree<Data>::OverlapElements::_getString () const
template< typename Data, typename DataCompare >
std::string IntervalTree<Data,DataCompare>::OverlapElements::_getString () const
{
std::string s = "<" + _TName("OverlapElements") + " "
+ getString(tree_)
@ -293,39 +332,45 @@ namespace Hurricane {
// Class : "Hurricane::IntervalTree" (implementation).
template< typename Data >
inline void IntervalTree<Data>::updateChildsVMax ( typename Super::Node* node )
template< typename Data, typename DataCompare >
inline void IntervalTree<Data,DataCompare>::updateChildsVMax ( typename Super::Node* node )
{
cdebug_log(0,1) << "IntervalTree::updateChildsVMax() " << node->getValue() << endl;
DbU::Unit lchildVMax = (node->getLeft ()) ? node->getLeft ()->getValue().getChildsVMax() : node->getValue().getVMax();
DbU::Unit rchildVMax = (node->getRight()) ? node->getRight()->getValue().getChildsVMax() : node->getValue().getVMax();
const_cast< IntervalData<Data>& >( node->getValue() ).updateChildsVMax( lchildVMax, rchildVMax );
cdebug_tabw(0,-1);
}
template< typename Data >
void IntervalTree<Data>::postRotateLeft ( typename Super::Node* node )
template< typename Data, typename DataCompare >
void IntervalTree<Data,DataCompare>::postRotateLeft ( typename Super::Node* node )
{
cdebug_log(0,1) << "IntervalTree::postRotateLeft() " << node->getValue() << endl;
updateChildsVMax( node );
if (node->getParent()) updateChildsVMax( node->getParent() );
cdebug_tabw(0,-1);
}
template< typename Data, typename DataCompare >
void IntervalTree<Data,DataCompare>::postRotateRight ( typename Super::Node* node )
{
cdebug_log(0,0) << "IntervalTree::postRotateRight() " << node->getValue() << endl;
updateChildsVMax( node );
if (node->getParent()) updateChildsVMax( node->getParent() );
}
template< typename Data >
void IntervalTree<Data>::postRotateRight ( typename Super::Node* node )
template< typename Data, typename DataCompare >
void IntervalTree<Data,DataCompare>::postInsert ( typename Super::Node* node )
{
updateChildsVMax( node );
if (node->getParent()) updateChildsVMax( node->getParent() );
}
template< typename Data >
void IntervalTree<Data>::postInsert ( typename Super::Node* node )
{
cdebug_log(0,1) << "IntervalTree::postInsert() " << node << std::endl;
cdebug_log(0,1) << "IntervalTree::postInsert() "
<< ((node) ? ::getString(node->getValue()) : "node=NULL") << std::endl;
while ( node ) {
cdebug_log(0,0) << "| " << node << std::endl;
cdebug_log(0,0) << "| " << node->getValue() << std::endl;
updateChildsVMax( node );
node = node->getParent();
@ -335,26 +380,38 @@ namespace Hurricane {
}
template< typename Data >
void IntervalTree<Data>::postRemove ( typename Super::Node* node )
template< typename Data, typename DataCompare >
void IntervalTree<Data,DataCompare>::postRemove ( typename Super::Node* node )
{
cdebug_log(0,1) << "IntervalTree::postRemove() "
<< ((node) ? ::getString(node->getValue()) : "node=NULL") << std::endl;
if (not node) {
cdebug_tabw(0,-1);
return;
}
typename Super::Node* parent = node->getParent();
if (parent) {
typename Super::Node* child = NULL;
DbU::Unit childsVMax = parent->getValue().getVMax();
typename Super::Node* child1 = parent->getLeft ();
typename Super::Node* child2 = parent->getRight();
if (child1 == node) std::swap( child1, child2 );
if (child1) childsVMax = std::max( childsVMax, child1->getValue().getChildsVMax() );
if (child2->getLeft ()) childsVMax = std::max( childsVMax, child2->getLeft ()->getValue().getChildsVMax() );
if (child2->getRight()) childsVMax = std::max( childsVMax, child2->getRight()->getValue().getChildsVMax() );
if (parent->hasLeftChild(node)) child = parent->getRight();
else child = parent->getLeft ();
DbU::Unit childVMax = (child) ? child->getValue().getChildsVMax() : parent->getValue().getVMax();
const_cast< IntervalData<Data>& >( parent->getValue() ).updateChildsVMax( childVMax, childVMax );
const_cast< IntervalData<Data>& >( parent->getValue() ).updateChildsVMax( childsVMax, childsVMax );
postInsert( parent->getParent() );
}
cdebug_tabw(0,-1);
}
template< typename Data >
size_t IntervalTree<Data>::getThickness () const
template< typename Data, typename DataCompare >
size_t IntervalTree<Data,DataCompare>::getThickness () const
{
cdebug_log(0,0) << "IntervalTree::getThickness() " << std::endl;
@ -382,36 +439,70 @@ namespace Hurricane {
}
template< typename Data >
typename IntervalTree<Data>::overlap_iterator IntervalTree<Data>::beginOverlaps ( const Interval& overlap ) const
template< typename Data, typename DataCompare >
typename IntervalTree<Data,DataCompare>::overlap_iterator
IntervalTree<Data,DataCompare>::beginOverlaps ( const Interval& overlap ) const
{
cdebug_log(0,0) << "IntervalTree::beginOverlaps() " << overlap << std::endl;
const typename Super::Node* current = this->getRoot();
const typename Super::Node* leftMost = NULL;
const typename Super::Node* leftMost = nullptr;
while ( current ) {
cdebug_log(0,0) << "| " << ::getString(current) << endl;
cdebug_log(0,0) << "| " << ::getString(current->getValue()) << endl;
if (current->getValue().intersect(overlap)) leftMost = current;
if (current->getValue().intersect(overlap,false)) {
cdebug_log(0,0) << "* Leftmost candidate." << endl;
leftMost = current;
}
if ( current->getLeft()
and (overlap.getVMin() < current->getLeft()->getValue().getChildsVMax()) )
current = current->getLeft();
else
current = current->getRight();
and (overlap.getVMin() < current->getLeft()->getValue().getChildsVMax()) ) {
current = current->getLeft();
leftMost = nullptr;
} else {
if (not leftMost)
current = current->getRight();
else
current = nullptr;
}
}
return overlap_iterator( leftMost, overlap );
}
template< typename Data >
typename IntervalTree<Data>::OverlapElements IntervalTree<Data>::getOverlaps ( const Interval& overlap ) const
template< typename Data, typename DataCompare >
typename IntervalTree<Data,DataCompare>::OverlapElements
IntervalTree<Data,DataCompare>::getOverlaps ( const Interval& overlap ) const
{
cdebug_log(0,0) << "IntervalTree::getOverlaps() " << overlap << std::endl;
return OverlapElements( *this, overlap );
}
template< typename Data, typename DataCompare >
void IntervalTree<Data,DataCompare>::checkVMax () const
{
checkVMax( this->getRoot() );
}
template< typename Data, typename DataCompare >
void IntervalTree<Data,DataCompare>::checkVMax ( typename Super::Node* node ) const
{
if (not node) return;
DbU::Unit lchildVMax = (node->getLeft ()) ? node->getLeft ()->getValue().getChildsVMax() : node->getValue().getVMax();
DbU::Unit rchildVMax = (node->getRight()) ? node->getRight()->getValue().getChildsVMax() : node->getValue().getVMax();
DbU::Unit childsVMax = std::max( lchildVMax, rchildVMax );
childsVMax = std::max( childsVMax, node->getValue().getVMax() );
if (node->getValue().getChildsVMax() != childsVMax) {
cerr << "ChildVMax discrepency on vmax=" << DbU::getValueString(childsVMax)
<< " " << ::getString(node->getValue()) << endl;
}
checkVMax( node->getLeft() );
checkVMax( node->getRight() );
}
} // HUrricane namespace.
#endif // HURRICANE_INTERVAL_TREE_H

View File

@ -17,9 +17,7 @@
// not, see <http://www.gnu.org/licenses/>.
// ****************************************************************************************************
#ifndef HURRICANE_NET
#define HURRICANE_NET
#pragma once
#include <functional>
#include "hurricane/Entity.h"
#include "hurricane/Nets.h"
@ -253,6 +251,7 @@ class Net : public Entity {
public: virtual void _toJsonSignature(JsonWriter*) const;
public: virtual void _toJsonCollections(JsonWriter*) const;
public: virtual string _getTypeName() const {return _TName("Net");};
public: string _getFlagsAsString() const;
public: virtual string _getString() const;
public: virtual Record* _getRecord() const;
public: NetMainName& _getMainName() { return _mainName; }
@ -445,9 +444,10 @@ namespace Hurricane {
// Because sometimes it didn't happens (?).
const SlotTemplate<Net*> dummyNetSlot ( string("dummyNetSlot"), NULL );
}
#endif // HURRICANE_NET
typedef std::set<Net*,DBo::CompareById> NetSet;
}
// ****************************************************************************************************

View File

@ -121,6 +121,10 @@ class JsonOccurrence : public JsonObject {
public: virtual void toData(JsonStack&);
};
typedef std::set<Occurrence> OccurrenceSet;
} // End of Hurricane namespace.

View File

@ -34,9 +34,7 @@
// Third edition, MIT press, 2011, p. 308.
#ifndef HURRICANE_RBTREE_H
#define HURRICANE_RBTREE_H
#pragma once
#include <functional>
#include <fstream>
#include <sstream>
@ -90,7 +88,7 @@ namespace Hurricane {
inline void copyColor ( Node* );
void updateEdge ( Node* oldChild, Node* newChild );
void clear ();
inline void copy ( const Node* );
inline void swap ( Node* );
virtual std::string _getString () const;
virtual Record* _getRecord () const;
private:
@ -284,8 +282,15 @@ namespace Hurricane {
template< typename Data, typename Compare >
inline void RbTree<Data,Compare>::Node::copy ( const Node* other )
{ value_ = other->value_; }
inline void RbTree<Data,Compare>::Node::swap ( Node* other )
{
cdebug_log(0,0) << "Node::swap()" << endl;
cdebug_log(0,0) << "| " << value_ << endl;
cdebug_log(0,0) << "| " << other->value_ << endl;
Data tmp = value_; value_ = other->value_; other->value_ = tmp;
cdebug_log(0,0) << "| " << value_ << endl;
cdebug_log(0,0) << "| " << other->value_ << endl;
}
template< typename Data, typename Compare >
@ -515,7 +520,7 @@ namespace Hurricane {
template< typename Data, typename Compare >
void RbTree<Data,Compare>::rotateLeft ( typename RbTree<Data,Compare>::Node* node )
{
cdebug_log(0,0) << "RbTree::rotateLeft() " << node << std::endl;
cdebug_log(0,0) << "RbTree::rotateLeft() " << node->getValue() << std::endl;
Node* rchild = node->getRight();
@ -534,7 +539,7 @@ namespace Hurricane {
template< typename Data, typename Compare >
void RbTree<Data,Compare>::rotateRight ( typename RbTree<Data,Compare>::Node* node )
{
cdebug_log(0,0) << "RbTree::rotateRight() " << node << std::endl;
cdebug_log(0,0) << "RbTree::rotateRight() " << node->getValue() << std::endl;
Node* lchild = node->getLeft();
@ -557,15 +562,21 @@ namespace Hurricane {
Node* current = root_;
while ( current ) {
cdebug_log(0,0) << "| " << current << std::endl;
cdebug_log(0,0) << "| " << current->getValue() << std::endl;
if (current->getValue() == value) {
cdebug_log(0,-1) << "> Value found: " << current <<std::endl;
cdebug_log(0,-1) << "> Value found: " << current->getValue() << std::endl;
return iterator(current);
}
if (compare_(value,current->getValue())) current = current->getLeft ();
else current = current->getRight();
if (compare_(value,current->getValue())) {
current = current->getLeft ();
cdebug_log(0,0) << "| Go left " << ((current) ? ::getString(current->getValue()) : "NULL") << std::endl;
}
else {
current = current->getRight();
cdebug_log(0,0) << "| Go right " << ((current) ? ::getString(current->getValue()) : "NULL") << std::endl;
}
}
cdebug_log(0,-1) << "Value not found." << std::endl;
@ -630,21 +641,22 @@ namespace Hurricane {
Node* rmNode = const_cast<Node*>( find( value ).getNode() );
if (not rmNode) {
cdebug_log(0,1) << "No node of value=" << value << std::endl;
cdebug_log(0,-1) << "No node of value=" << value << std::endl;
return;
}
Node* rmLeaf = nullptr;
if (rmNode->getLeft() and rmNode->getRight()) {
Node* rmLeaf = rmNode->getLeft();
Node* rmMax = rmLeaf->getMax();
rmLeaf = rmNode->getLeft();
Node* rmMax = rmLeaf->getMax();
if (rmMax) rmLeaf = rmMax;
rmNode->copy( rmLeaf );
rmNode = rmLeaf;
rmNode->swap( rmLeaf );
std::swap( rmNode, rmLeaf );
}
postRemove ( rmNode );
removeRepair( rmNode, 0 );
postRemove ( rmNode );
Node* parent = rmNode->getParent();
Node* child = (rmNode->getLeft()) ? rmNode->getLeft() : rmNode->getRight();
@ -660,8 +672,9 @@ namespace Hurricane {
}
}
cdebug_log(0,0) << "delete " << rmNode << std::endl;
cdebug_log(0,0) << "delete " << rmNode->getValue() << std::endl;
delete rmNode;
--count_;
cdebug_tabw(0,-1);
@ -671,8 +684,13 @@ namespace Hurricane {
template< typename Data, typename Compare >
void RbTree<Data,Compare>::removeRepair ( typename RbTree<Data,Compare>::Node* rmNode, size_t depth )
{
cdebug_log(0,1) << "RbTree::removeRepair() rmNode:" << rmNode
cdebug_log(0,1) << "RbTree::removeRepair() rmNode:" << rmNode->getValue()
<< " depth:" << depth << std::endl;
if (not rmNode) {
cdebug_tabw(0,-1);
return ;
}
if (rmNode->isBlack()) {
Node* parent = rmNode->getParent();
@ -979,6 +997,7 @@ namespace Hurricane {
void RbTreeToDot<Data,Compare,RbTree>::write ( std::ostream& o ) const
{
o << "digraph RbTree {\n";
o << " ratio=\"1.0\";\n";
toDot( o, tree_->getRoot() );
o << "}";
}
@ -989,8 +1008,9 @@ namespace Hurricane {
{
if (not node) return;
string svalue = ::getString( node->getValue() );
o << " id_" << getId(node) << " "
<< "[label=\"id:" << getId(node) << "\\n" << ::getString(node->getValue())
<< "[label=\"id:" << getId(node) << "\\n" << split( svalue )
<< "\""
<< ",color=" << (node->isRed() ? "red" : "black")
<< ",fontcolor=" << (node->isRed() ? "red" : "black")
@ -1031,6 +1051,3 @@ namespace Hurricane {
} // Hurricane namespace.
#endif // HURRICANE_RBTREE_H

View File

@ -1,6 +1,6 @@
// -*- C++ -*-
//
// Copyright (c) BULL S.A. 2018-2018, All Rights Reserved
// Copyright (c) BULL S.A. 2018-2023, All Rights Reserved
//
// This file is part of Hurricane.
//
@ -28,10 +28,7 @@
// | C++ Header : "./hurricane/Rectilinear.h" |
// +-----------------------------------------------------------------+
#ifndef HURRICANE_RECTILINEAR_H
#define HURRICANE_RECTILINEAR_H
#pragma once
#include "hurricane/Component.h"
@ -46,11 +43,13 @@ namespace Hurricane {
class Rectilinear : public Component {
public:
typedef Component Super;
static const uint32_t IsRectilinear = (1<<0);
public:
static Rectilinear* create ( Net*, const Layer*, const vector<Point>& );
// Accessors.
virtual bool isNonRectangle () const;
inline bool isRectilinear () const;
virtual DbU::Unit getX () const;
virtual DbU::Unit getY () const;
virtual Box getBoundingBox () const;
@ -59,6 +58,7 @@ namespace Hurricane {
virtual Point getPoint ( size_t i ) const;
virtual const Layer* getLayer () const;
inline Points getContour () const;
bool getAsRectangles ( std::vector<Box>& ) const;
inline const vector<Point>& getPoints () const;
// Mutators.
void setLayer ( const Layer* );
@ -75,11 +75,13 @@ namespace Hurricane {
private:
const Layer* _layer;
vector<Point> _points;
uint32_t _flags;
};
inline Points Rectilinear::getContour () const { return new VectorCollection<Point>(_points); }
inline const vector<Point>& Rectilinear::getPoints () const { return _points; }
inline bool Rectilinear::isRectilinear () const { return _flags & IsRectilinear; }
inline Points Rectilinear::getContour () const { return new VectorCollection<Point>(_points); }
inline const vector<Point>& Rectilinear::getPoints () const { return _points; }
// -------------------------------------------------------------------
@ -99,5 +101,3 @@ namespace Hurricane {
INSPECTOR_P_SUPPORT(Hurricane::Rectilinear);
#endif // HURRICANE_RECTILINEAR_H

View File

@ -8,7 +8,6 @@
${Boost_INCLUDE_DIRS}
${Python_INCLUDE_DIRS}
)
find_package (Python3 COMPONENTS Interpreter Development)
set( pyCpps ProxyProperty.cpp
PythonAttributes.cpp
PyBreakpoint.cpp

View File

@ -45,6 +45,24 @@ namespace Isobar {
}
PyObject* VectorToList ( const std::vector<Box>& v )
{
PyObject* pyList = PyList_New( v.size() );
for ( size_t i=0 ; i<v.size() ; ++i ) {
PyBox* pyBox = PyObject_NEW( PyBox, &PyTypeBox );
if (not pyBox) { return NULL; }
HTRY
pyBox->_object = new Box ( v[i] );
HCATCH
PyList_SetItem( pyList, i, (PyObject*)pyBox );
}
return pyList;
}
extern "C" {
@ -168,20 +186,54 @@ extern "C" {
}
static PyObject* PyRectilinear_getAsRectangles ( PyRectilinear *self, PyObject* args )
{
cdebug_log(20,0) << "Rectilinear.getAsRectangles()" << endl;
HTRY
METHOD_HEAD( "Rectilinear.getAsRectangles()" )
PyObject* pyList = NULL;
if (not PyArg_ParseTuple( args, "O:Rectilinear.getAsRectangles", &pyList )) {
PyErr_SetString( ConstructorError, "Rectilinear.getAsRectangles(): Must have exactly one parameter." );
return NULL;
}
if (not PyList_Check(pyList)) {
PyErr_SetString( ConstructorError, "Rectilinear.getAsRectangles(): Argument must be a list." );
return NULL;
}
PyList_SetSlice( pyList, 0, PyList_Size(pyList), NULL );
vector<Box> boxes;
rectilinear->getAsRectangles( boxes );
for ( size_t i=0 ; i<boxes.size() ; ++i ) {
PyBox* pyBox = PyObject_NEW( PyBox, &PyTypeBox );
if (not pyBox) { return NULL; }
pyBox->_object = new Box ( boxes[i] );
PyList_Append( pyList, (PyObject*)pyBox );
}
HCATCH
Py_RETURN_NONE;
}
// ---------------------------------------------------------------
// PyRectilinear Attribute Method table.
PyMethodDef PyRectilinear_Methods[] =
{ { "create" , (PyCFunction)PyRectilinear_create , METH_VARARGS|METH_STATIC
, "Create a new Rectilinear polygon." }
, { "isNonRectangle", (PyCFunction)PyRectilinear_isNonRectangle, METH_NOARGS , "Tells if the shape is not a rectangle." }
, { "getX" , (PyCFunction)PyRectilinear_getX , METH_NOARGS , "Return the Rectilinear X value." }
, { "getY" , (PyCFunction)PyRectilinear_getY , METH_NOARGS , "Return the Rectilinear Y value." }
, { "getBoundingBox", (PyCFunction)PyRectilinear_getBoundingBox, METH_NOARGS , "Return the Rectilinear Bounding Box." }
, { "setPoints" , (PyCFunction)PyRectilinear_setPoints , METH_VARARGS, "Sets the Rectilinear Bounding Box." }
, { "translate" , (PyCFunction)PyRectilinear_translate , METH_VARARGS, "Translates the Rectilinear of dx and dy." }
, { "destroy" , (PyCFunction)PyRectilinear_destroy , METH_NOARGS
, "Destroy associated hurricane object, the python object remains." }
{ { "create" , (PyCFunction)PyRectilinear_create , METH_VARARGS|METH_STATIC
, "Create a new Rectilinear polygon." }
, { "isNonRectangle" , (PyCFunction)PyRectilinear_isNonRectangle , METH_NOARGS , "Tells if the shape is not a rectangle." }
, { "getX" , (PyCFunction)PyRectilinear_getX , METH_NOARGS , "Return the Rectilinear X value." }
, { "getY" , (PyCFunction)PyRectilinear_getY , METH_NOARGS , "Return the Rectilinear Y value." }
, { "getBoundingBox" , (PyCFunction)PyRectilinear_getBoundingBox , METH_NOARGS , "Return the Rectilinear Bounding Box." }
, { "setPoints" , (PyCFunction)PyRectilinear_setPoints , METH_VARARGS, "Sets the Rectilinear Bounding Box." }
, { "translate" , (PyCFunction)PyRectilinear_translate , METH_VARARGS, "Translates the Rectilinear of dx and dy." }
, { "getAsRectangles", (PyCFunction)PyRectilinear_getAsRectangles, METH_VARARGS, "Return the rectangle coverage." }
, { "destroy" , (PyCFunction)PyRectilinear_destroy , METH_NOARGS
, "Destroy associated hurricane object, the python object remains." }
, {NULL, NULL, 0, NULL} /* sentinel */
};

View File

@ -1625,31 +1625,31 @@ extern "C" {
catch ( const Warning& w ) { \
std::string message = getString(w); \
PyErr_Warn ( HurricaneWarning, const_cast<char*>(message.c_str()) ); \
std::cerr << message << std::endl; \
std::cerr << message << std::endl; \
} \
catch ( const Error& e ) { \
std::string message = getString(e); \
if (not e.where().empty()) message += "\n" + e.where(); \
PyErr_SetString ( HurricaneError, message.c_str() ); \
std::cerr << message << std::endl; \
std::cerr << message << std::endl; \
return NULL; \
} \
catch ( const Bug& e ) { \
std::string message = getString(e); \
PyErr_SetString ( HurricaneError, message.c_str() ); \
std::cerr << message << std::endl; \
std::cerr << message << std::endl; \
return NULL; \
} \
catch ( const Exception& e ) { \
std::string message = "Unknown Hurricane::Exception"; \
PyErr_SetString ( HurricaneError, message.c_str() ); \
std::cerr << message << std::endl; \
std::cerr << message << std::endl; \
return NULL; \
} \
catch ( const std::exception& e ) { \
std::string message = std::string(e.what()); \
PyErr_SetString ( HurricaneError, message.c_str() ); \
std::cerr << message << std::endl; \
std::cerr << message << std::endl; \
return NULL; \
} \
catch ( ... ) { \
@ -1657,7 +1657,7 @@ extern "C" {
"Unmanaged exception, neither a Hurricane::Error nor" \
" a std::exception."; \
PyErr_SetString ( HurricaneError, message.c_str() ); \
std::cerr << message << std::endl; \
std::cerr << message << std::endl; \
return NULL; \
} \

View File

@ -157,8 +157,9 @@ namespace Hurricane {
//int scale = 80 * Cfg::getParamEnumerate("viewer.printer.mode")->asInt();
int scale = (Graphics::isHighDpi()) ? 4 : 2;
_drawingWidth = _cellWidget->width () * scale;
_drawingHeight = _cellWidget->height() * scale;
_drawingWidth = _screenCellWidget->geometry().width () * scale;
_drawingHeight = _screenCellWidget->geometry().height() * scale;
_cellWidget->resize( _drawingWidth, _drawingHeight );
_image = new QImage( _drawingWidth
, _drawingHeight + ((_flags&ShowScale) ? 60 : 0)
@ -188,7 +189,7 @@ namespace Hurricane {
setFitOnAbutmentBox( true );
_cellWidget->fitToContents();
} else {
//_cellWidget->reframe( _screenCellWidget->getVisibleArea() );
_cellWidget->reframe( _screenCellWidget->getVisibleArea() );
}
cerr << " After resize CellWidget: " << _cellWidget->geometry().width() << "x" << _cellWidget->geometry().height() << endl;

View File

@ -584,7 +584,7 @@ namespace Hurricane {
void CellViewer::refreshTitle ()
{
QString cellName = "None";
QString cellName = "empty";
if ( getCell() )
cellName = getString(getCell()->getName()).c_str();

View File

@ -2683,7 +2683,86 @@ namespace Hurricane {
} else
selected = false;
if ( (--_delaySelectionChanged == 0) and selected ) emit selectionChanged( _selectors );
if ( (--_delaySelectionChanged == 0) and selected )
emit selectionChanged( _selectors );
}
void CellWidget::selectSet ( const ComponentSet& components )
{
if ( (++_delaySelectionChanged == 1) and not _state->cumulativeSelection() ) {
openRefreshSession();
unselectAll();
closeRefreshSession();
}
bool selected = true;
// SelectorCriterion* criterion = _state->getSelection().add ( selectArea );
// if ( criterion and (not criterion->isEnabled()) ) {
// criterion->enable();
for ( Component* component : components ) {
if (component->getCell() == getCell()) {
select( Occurrence( component ));
}
}
// } else
// selected = false;
if ( (--_delaySelectionChanged == 0) and selected )
emit selectionChanged( _selectors );
}
void CellWidget::selectSet ( const OccurrenceSet& occurrences )
{
if ( (++_delaySelectionChanged == 1) and not _state->cumulativeSelection() ) {
openRefreshSession();
unselectAll();
closeRefreshSession();
}
bool selected = true;
// SelectorCriterion* criterion = _state->getSelection().add ( selectArea );
// if ( criterion and (not criterion->isEnabled()) ) {
// criterion->enable();
for ( const Occurrence& occurrence : occurrences ) {
if (occurrence.getOwnerCell() == getCell()) {
select( occurrence );
}
}
// } else
// selected = false;
if ( (--_delaySelectionChanged == 0) and selected )
emit selectionChanged( _selectors );
}
void CellWidget::select ( Occurrences occurrences )
{
if ( (++_delaySelectionChanged == 1) and not _state->cumulativeSelection() ) {
openRefreshSession();
unselectAll();
closeRefreshSession();
}
bool selected = true;
// SelectorCriterion* criterion = _state->getSelection().add ( selectArea );
// if ( criterion and (not criterion->isEnabled()) ) {
// criterion->enable();
for ( const Occurrence& occurrence : occurrences ) {
if (occurrence.getOwnerCell() == getCell()) {
select( occurrence );
}
}
// } else
// selected = false;
if ( (--_delaySelectionChanged == 0) and selected )
emit selectionChanged( _selectors );
}
@ -2744,7 +2823,7 @@ namespace Hurricane {
if ( (--_delaySelectionChanged == 0) and selected ) {
if ( _state->showSelection() ) _redrawManager.refresh ();
emit selectionChanged(_selectors);
emit selectionChanged(_selectors);
}
}
@ -2782,7 +2861,47 @@ namespace Hurricane {
}
_selectionHasChanged = true;
if ( (_delaySelectionChanged == 0) and unselected ) emit selectionChanged( _selectors );
if ( (_delaySelectionChanged == 0) and unselected )
emit selectionChanged( _selectors );
}
void CellWidget::unselectSet ( const ComponentSet& components )
{
++_delaySelectionChanged;
for ( Component* component : components ) {
if (component->getCell() == getCell()) {
unselect( Occurrence( component ));
}
}
if ( --_delaySelectionChanged == 0 )
emit selectionChanged( _selectors );
}
void CellWidget::unselectSet ( const OccurrenceSet& occurrences )
{
++_delaySelectionChanged;
for ( const Occurrence& occurrence : occurrences ) {
if (occurrence.getOwnerCell() == getCell()) {
unselect( occurrence );
}
}
if ( --_delaySelectionChanged == 0 )
emit selectionChanged( _selectors );
}
void CellWidget::unselect ( Occurrences occurrences )
{
++_delaySelectionChanged;
for ( const Occurrence& occurrence : occurrences ) {
if (occurrence.getOwnerCell() == getCell()) {
unselect( occurrence );
}
}
if ( --_delaySelectionChanged == 0 )
emit selectionChanged( _selectors );
}
@ -2793,7 +2912,8 @@ namespace Hurricane {
_state->getSelection().clear ();
_unselectAll ();
if ( --_delaySelectionChanged == 0 ) emit selectionChanged(_selectors);
if ( --_delaySelectionChanged == 0 )
emit selectionChanged(_selectors);
}

View File

@ -658,6 +658,19 @@ namespace Hurricane {
}
void ControllerWidget::insertTabAfter ( const QString& ref, QWidget* tab, const QString& label )
{
for ( int itab=0 ; true; ++itab ) {
QWidget* refTab = widget( itab );
if (not refTab) break;
if (refTab->objectName() != ref) continue;
insertTab( itab, tab, label );
return;
}
addTab( tab, label );
}
// -------------------------------------------------------------------
// Class : "ControllerWidget::GraphicsObserver".

View File

@ -63,7 +63,7 @@ namespace Hurricane {
int SimpleNetInformations::getColumnCount ()
{ return 3; }
{ return 6; }
QVariant SimpleNetInformations::getColumnName ( int column )
@ -71,7 +71,10 @@ namespace Hurricane {
switch ( column ) {
case 0: return QVariant(QObject::tr("Net"));
case 1: return QVariant(QObject::tr("Plugs"));
case 2: return QVariant(QObject::tr("RoutingPads"));
case 2: return QVariant(QObject::tr("RPs"));
case 3: return QVariant(QObject::tr("Flags"));
case 4: return QVariant(QObject::tr("Type"));
case 5: return QVariant(QObject::tr("Direction"));
}
return QVariant(QObject::tr("Column Out of Bound"));
}
@ -84,11 +87,15 @@ namespace Hurricane {
case 1: return (unsigned int)_plugsCount;
case 2:
if (_net->isGlobal()) {
if (not _rpsCount) return "N/A (global)";
string s = getString(_rpsCount) + " (global)";
if (not _rpsCount) return "N/A";
string s = getString(_rpsCount);
return s.c_str();
}
return (unsigned int)_rpsCount;
case 3: return QString::fromStdString( getString( _net->_getFlagsAsString() ));
case 4: return QString::fromStdString( getString( _net->getType() ));
case 5: return QString::fromStdString( getString( _net->getDirection() ));
}
return QVariant(QObject::tr("Column Out of Bound"));
}

View File

@ -70,7 +70,7 @@ namespace Hurricane {
QHeaderView* horizontalHeader = _view->horizontalHeader();
horizontalHeader->setDefaultAlignment ( Qt::AlignHCenter );
horizontalHeader->setMinimumSectionSize( (Graphics::isHighDpi()) ? 300 : 150 );
horizontalHeader->setMinimumSectionSize( (Graphics::isHighDpi()) ? 150 : 75 );
horizontalHeader->setStretchLastSection( true );
QHeaderView* verticalHeader = _view->verticalHeader();
@ -151,24 +151,18 @@ namespace Hurricane {
_forceReselect = false;
}
SelectedNetSet::iterator remove;
SelectedNetSet::iterator isel = _selecteds.begin ();
SelectedNetSet::iterator isel = _selecteds.begin ();
while ( isel != _selecteds.end() ) {
switch ( isel->getAccesses() ) {
case 1: break;
case 64:
emit netSelected ( Occurrence(isel->getNet()) );
break;
case 0:
emit netUnselected ( Occurrence(isel->getNet()) );
remove = isel;
++isel;
_selecteds.erase ( remove );
continue;
default:
cerr << Bug("NetlistWidget::updateSelecteds(): invalid code %d"
,isel->getAccesses()) << endl;
SelectedNetSet::iterator remove = isel++;
if ( remove->getAccesses() == 0 ) {
emit netUnselected ( Occurrence(remove->getNet()) );
_selecteds.erase ( remove );
}
}
isel = _selecteds.begin ();
while ( isel != _selecteds.end() ) {
if ( isel->getAccesses() == 64 )
emit netSelected ( Occurrence(isel->getNet()) );
++isel;
}

View File

@ -219,6 +219,7 @@ extern "C" {
}
cw->setApplicationName ( name );
cw->refreshTitle ();
HCATCH
Py_RETURN_NONE;

View File

@ -91,8 +91,8 @@ namespace Hurricane {
{
if (not _cellWidget) return;
if (not isCumulative()) clear ();
beginResetModel();
if (not isCumulative()) _selection.clear ();
for ( Selector* selector : selection ) {
if (not selector->isInModel(_cellWidget)) {

View File

@ -87,6 +87,7 @@ namespace Hurricane {
CellViewer ( QWidget* parent=NULL );
virtual ~CellViewer ();
inline bool isToolInterrupted () const;
void refreshTitle ();
QMenu* createDebugMenu ();
bool hasMenu ( const QString& path ) const;
bool hasMenuAction ( const QString& path ) const;
@ -166,7 +167,6 @@ namespace Hurricane {
void cellPostModificated ();
protected:
void createMenus ();
void refreshTitle ();
void refreshHistory ();
void rebuildHistory ();
private:

View File

@ -265,10 +265,16 @@ namespace Hurricane {
inline DrawingPlanes& getDrawingPlanes ();
// void select ( const Net* );
void select ( Occurrence );
void select ( Occurrences );
void selectSet ( const OccurrenceSet& );
void selectSet ( const ComponentSet& );
bool isSelected ( Occurrence );
void selectOccurrencesUnder ( Box selectArea );
// void unselect ( const Net* );
void unselect ( Occurrence );
void unselect ( Occurrences );
void unselectSet ( const ComponentSet& );
void unselectSet ( const OccurrenceSet& );
void unselectAll ();
void toggleSelection ( Occurrence );
void setShowSelection ( bool state );

View File

@ -312,6 +312,7 @@ namespace Hurricane {
inline TabSettings* getSettings ();
void setCellWidget ( CellWidget* );
//inline int addSetting ( QWidget* page, const QString& label );
void insertTabAfter ( const QString& ref, QWidget*, const QString& label );
public slots:
void graphicsUpdated ();
void cellPreModificate ();

View File

@ -14,10 +14,10 @@
set_cmake_policies()
#setup_apple()
setup_boost(program_options)
setup_python()
set(QT_USE_QTXML "true")
find_package(Qt4 REQUIRED)
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
find_package(PythonSitePackages REQUIRED)
find_package(HURRICANE REQUIRED)
find_package(CORIOLIS REQUIRED)

View File

@ -15,7 +15,7 @@
check_distribution()
setup_sysconfdir("${CMAKE_INSTALL_PREFIX}")
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
setup_python()
find_package(PythonSitePackages REQUIRED)
find_package(HURRICANE REQUIRED)
find_package(CORIOLIS REQUIRED)

View File

@ -18,9 +18,9 @@
set_cmake_policies()
setup_boost(program_options)
setup_qt()
setup_python()
find_package(Libexecinfo REQUIRED)
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
find_package(PythonSitePackages REQUIRED)
find_package(LEFDEF REQUIRED)
find_package(FLUTE REQUIRED)

View File

@ -12,7 +12,6 @@
${Boost_INCLUDE_DIRS}
${Python_INCLUDE_DIRS}
)
find_package (Python3 COMPONENTS Interpreter Development)
set( includes katana/Constants.h
katana/Block.h
katana/TrackCost.h

View File

@ -76,6 +76,16 @@ namespace {
cdebug_tabw(159,-1);
return;
}
if (segment->isNonPrefOnVSmall()) {
cdebug_log(159,0) << "Infinite cost from (NonPref on VSmall): " << segment << endl;
cost.setInfinite ();
cost.setOverlap ();
cost.setHardOverlap();
cost.setBlockage ();
cdebug_tabw(159,-1);
return;
}
}
if (cost.getInterval().getVMax() > intersect.getVMax()) cost.setLeftOverlap();

View File

@ -152,6 +152,7 @@ namespace Katana {
bool TrackElement::isAnalog () const { return false; }
bool TrackElement::isWide () const { return false; }
bool TrackElement::isNonPref () const { return false; }
bool TrackElement::isNonPrefOnVSmall () const { return false; }
bool TrackElement::isShortNet () const { return false; }
// Predicates.
bool TrackElement::hasSymmetric () const { return false; }

View File

@ -195,6 +195,7 @@ namespace Katana {
bool TrackSegment::isWide () const { return _base->isWide(); }
bool TrackSegment::isShortNet () const { return _base->isShortNet(); }
bool TrackSegment::isPriorityLocked () const { return _flags & PriorityLocked; }
bool TrackSegment::isNonPrefOnVSmall () const { return _base->isNonPrefOnVSmall(); }
// Predicates.
bool TrackSegment::hasSymmetric () const { return _symmetric != NULL; }
// Accessors.

View File

@ -106,6 +106,7 @@ namespace Katana {
virtual bool isVertical () const = 0;
virtual bool isWide () const;
virtual bool isNonPref () const;
virtual bool isNonPrefOnVSmall () const;
virtual bool isUnbreakable () const;
virtual bool isLocal () const;
virtual bool isGlobal () const;

View File

@ -82,6 +82,7 @@ namespace Katana {
virtual bool isAnalog () const;
virtual bool isWide () const;
virtual bool isShortNet () const;
virtual bool isNonPrefOnVSmall () const;
virtual bool isPriorityLocked () const;
// Predicates.
virtual bool hasSymmetric () const;

View File

@ -14,11 +14,11 @@
set_cmake_policies()
setup_sysconfdir("${CMAKE_INSTALL_PREFIX}")
setup_boost(program_options)
setup_python()
if (USE_LIBBFD)
find_package(Libbfd)
endif()
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
find_package(PythonSitePackages REQUIRED)
find_package(HURRICANE REQUIRED)
find_package(CORIOLIS REQUIRED)

View File

@ -12,6 +12,7 @@
list(INSERT CMAKE_MODULE_PATH 0 "${DESTDIR}$ENV{CORIOLIS_TOP}/share/cmake/Modules/")
find_package(Bootstrap REQUIRED)
setup_project_paths(CORIOLIS)
setup_python()
find_package(Bootstrap REQUIRED)
set_cmake_policies()
@ -19,7 +20,6 @@
cmake_policy(SET CMP0002 OLD)
setup_sysconfdir("${CMAKE_INSTALL_PREFIX}")
find_package(Python 3 REQUIRED COMPONENTS Interpreter Development)
find_package(PythonSitePackages REQUIRED)
find_package(HURRICANE REQUIRED)
find_package(CORIOLIS REQUIRED)

29
tramontana/CMakeLists.txt Normal file
View File

@ -0,0 +1,29 @@
# -*- explicit-buffer-name: "CMakeLists.txt<tramontana>" -*-
set(CMAKE_LEGACY_CYGWIN_WIN32 0)
project(TRAMONTANA)
set(ignoreVariables "${BUILD_DOC} ${CMAKE_INSTALL_DIR}")
option(BUILD_DOC "Build the documentation (doxygen)" OFF)
option(USE_LIBBFD "Link with BFD libraries to print stack traces" OFF)
cmake_minimum_required(VERSION 3.16)
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()
setup_qt()
setup_python()
find_package(PythonSitePackages REQUIRED)
find_package(HURRICANE REQUIRED)
find_package(CORIOLIS REQUIRED)
find_package(Doxygen)
add_subdirectory(src)
#add_subdirectory(cmake_modules)
#add_subdirectory(doc)

View File

@ -0,0 +1,78 @@
# -*- explicit-buffer-name: "CMakeLists.txt<tramontana/src>" -*-
# include( ${QT_USE_FILE} )
include_directories( ${TRAMONTANA_SOURCE_DIR}/src
${CORIOLIS_INCLUDE_DIR}
${HURRICANE_INCLUDE_DIR}
${CONFIGURATION_INCLUDE_DIR}
${QtX_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
${Python_INCLUDE_DIRS}
)
set( includes tramontana/Tile.h
tramontana/QueryTiles.h
tramontana/SweepLine.h
tramontana/Equipotential.h
tramontana/EquipotentialRelation.h
tramontana/EquipotentialComponents.h
tramontana/TramontanaEngine.h
tramontana/GraphicTramontanaEngine.h
)
set( pyIncludes tramontana/PyTramontanaEngine.h
tramontana/PyGraphicTramontanaEngine.h
)
set( mocIncludes tramontana/GraphicTramontanaEngine.h
tramontana/EquipotentialsModel.h
tramontana/EquipotentialsWidget.h
tramontana/TabEquipotentials.h
)
set( cpps Tile.cpp
QueryTiles.cpp
SweepLine.cpp
Equipotential.cpp
EquipotentialRelation.cpp
EquipotentialComponents.cpp
TramontanaEngine.cpp
GraphicTramontanaEngine.cpp
EquipotentialsModel.cpp
EquipotentialsWidget.cpp
TabEquipotentials.cpp
)
set( pyCpps PyTramontana.cpp
PyTramontanaEngine.cpp
PyGraphicTramontanaEngine.cpp
)
qtX_wrap_cpp( mocCpps ${mocIncludes} )
set( depLibs ${CORIOLIS_PYTHON_LIBRARIES}
${CORIOLIS_LIBRARIES}
${HURRICANE_PYTHON_LIBRARIES}
${HURRICANE_GRAPHICAL_LIBRARIES}
${HURRICANE_LIBRARIES}
${CONFIGURATION_LIBRARY}
${UTILITIES_LIBRARY}
${LEFDEF_LIBRARIES}
${QtX_LIBRARIES}
${Boost_LIBRARIES}
${Python3_LIBRARIES}
-lutil
${LIBEXECINFO_LIBRARIES}
)
add_library( tramontana ${cpps} ${mocCpps} ${pyCpps} )
set_target_properties( tramontana PROPERTIES VERSION 1.0 SOVERSION 1 )
target_link_libraries( tramontana ${depLibs} )
add_python_module( "${pyCpps}"
"${pyIncludes}"
"Do_not_generate_C_library"
Tramontana
"tramontana;${depLibs}"
include/coriolis2/tramontana
)
install( TARGETS tramontana DESTINATION lib${LIB_SUFFIX} )
install( FILES ${includes}
${mocIncludes} DESTINATION include/coriolis2/tramontana )

View File

@ -0,0 +1,533 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | T r a m o n t a n a - Extractor & LVX |
// | |
// | Algorithm : Christian MASSON |
// | First impl. : Yifei WU |
// | Second impl. : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./Equipotential.cpp" |
// +-----------------------------------------------------------------+
#include <iomanip>
#include <set>
#include <map>
#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/Breakpoint.h"
#include "hurricane/Timer.h"
#include "hurricane/Layer.h"
#include "hurricane/Net.h"
#include "hurricane/Pad.h"
#include "hurricane/Contact.h"
#include "hurricane/Plug.h"
#include "hurricane/Cell.h"
#include "hurricane/Instance.h"
#include "hurricane/Vertical.h"
#include "hurricane/Horizontal.h"
#include "hurricane/RoutingPad.h"
#include "crlcore/Utilities.h"
#include "tramontana/Equipotential.h"
#include "tramontana/EquipotentialRelation.h"
#include "tramontana/EquipotentialComponents.h"
#include "tramontana/TramontanaEngine.h"
namespace Tramontana {
using std::cout;
using std::cerr;
using std::endl;
using std::dec;
using std::setw;
using std::setfill;
using std::left;
using std::string;
using std::ostream;
using std::ofstream;
using std::ostringstream;
using std::setprecision;
using std::vector;
using std::set;
using std::make_pair;
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::Box;
using Hurricane::Layer;
using Hurricane::Entity;
using Hurricane::Net;
using Hurricane::Plug;
using Hurricane::Contact;
using Hurricane::Horizontal;
using Hurricane::Vertical;
using Hurricane::RoutingPad;
using Hurricane::Cell;
using Hurricane::Instance;
using Hurricane::Path;
bool NetCompareByName::operator() ( const Net* lhs, const Net* rhs ) const
{
if (lhs->isFused () != rhs->isFused ()) return rhs->isFused();
if (lhs->isAutomatic() != rhs->isAutomatic()) return rhs->isAutomatic();
if (lhs->isGlobal () != rhs->isGlobal ()) return rhs->isGlobal();
if (lhs->getName().size() != rhs->getName().size())
return lhs->getName().size() < rhs->getName().size();
return lhs->getName() < rhs->getName();
}
bool OccNetCompareByName::operator() ( const Occurrence& lhs, const Occurrence& rhs ) const
{
static NetCompareByName compareByName;
size_t lhsLength = lhs.getPath().getInstances().getSize();
size_t rhsLength = rhs.getPath().getInstances().getSize();
if (lhsLength != rhsLength) return lhsLength < rhsLength;
return compareByName( static_cast<Net*>(lhs.getEntity()), static_cast<Net*>(rhs.getEntity()) );
}
// -------------------------------------------------------------------
// Class : "Tramontana::Equipotential".
Equipotential* Equipotential::get ( Component* component )
{
EquipotentialRelation* relation = dynamic_cast<EquipotentialRelation*>(
component->getNet()->getProperty( EquipotentialRelation::staticGetName() ));
if (not relation) {
relation = dynamic_cast<EquipotentialRelation*>(
component->getProperty( EquipotentialRelation::staticGetName() ));
}
if (not relation) return nullptr;
return dynamic_cast<Equipotential*>( relation->getMasterOwner() );
}
Equipotential* Equipotential::get ( Occurrence occurrence )
{
EquipotentialRelation* relation = dynamic_cast<EquipotentialRelation*>(
occurrence.getProperty( EquipotentialRelation::staticGetName() ));
if (not relation) return nullptr;
return dynamic_cast<Equipotential*>( relation->getMasterOwner() );
}
Occurrence Equipotential::getChildEqui ( Occurrence flatOccurrence )
{
Component* component = dynamic_cast<Component*>( flatOccurrence.getEntity() );
if (not component) {
cerr << Error( "Equipotential::getChildEqui(): Occurrence must be over a Component.\n"
" (on:%s)"
, getString(flatOccurrence).c_str()
) << endl;
return Occurrence();
}
Equipotential* equi = Equipotential::get( component );
if (not equi) {
cerr << Error( "Equipotential::getChildEqui(): Component not associated to an Equipotential.\n"
" (on:%s)"
, getString(flatOccurrence).c_str()
) << endl;
return Occurrence();
}
if (flatOccurrence.getPath().isEmpty()) return flatOccurrence;
// cerr << "childEqui:" << flatOccurrence << endl;
// cerr << " " << equi << endl;
Instance* tailInst = flatOccurrence.getPath().getTailInstance();
Path headPath = flatOccurrence.getPath().getHeadPath();
Occurrence tailOccurrence;
while ( tailInst ) {
tailOccurrence = Occurrence( equi, tailInst );
equi = Equipotential::get( tailOccurrence );
tailInst = headPath.getTailInstance();
headPath = headPath.getHeadPath();
}
// cerr << " ==> " << tailOccurrence << endl;
// cerr << " " << equi << endl;
return tailOccurrence;
}
Equipotential::Equipotential ( Cell* owner )
: _owner (owner)
, _boundingBox ()
, _components ()
, _childs ()
, _name ()
, _type (Net::Type::UNDEFINED)
, _direction (Net::Direction::DirUndefined)
, _netCount (0)
, _isBuried (false)
, _isExternal (false)
, _isGlobal (false)
, _isAutomatic (false)
, _hasFused (false)
, _shortCircuits()
{
_name = "Unnamed_" + getString( getId() );
}
void Equipotential::_postCreate ()
{
Super::_postCreate();
TramontanaEngine* tramontana = TramontanaEngine::get( _owner );
tramontana->add( this );
}
Equipotential* Equipotential::create ( Cell* owner )
{
Equipotential* equi = new Equipotential ( owner );
equi->_postCreate();
return equi;
}
void Equipotential::_preDestroy ()
{
Super::_preDestroy();
}
Equipotential::~Equipotential ()
{
for ( ShortCircuit* shortCircuit : _shortCircuits ) delete shortCircuit;
}
Cell* Equipotential::getCell () const
{ return _owner; }
Box Equipotential::getBoundingBox () const
{ return _boundingBox; }
Occurrences Equipotential::getFlatComponents () const
{ return EquipotentialComponents( this ); }
void Equipotential::add ( Occurrence occ, const Box& boundingBox )
{
if(occ.getPath().isEmpty()) {
Contact* contact = dynamic_cast<Contact*>( occ.getEntity() );
if ((_components.find(occ) != _components.end())) {
if (not contact)
cdebug_log(160,0) << "Equipotential::add(): Duplicated " << occ.getCompactString() << endl;
return;
}
Component* comp = dynamic_cast<Component*>( occ.getEntity() );
if (not comp) {
cerr << Error( "Equipotential::add(): Occurrences with null Path must be Components.\n"
" (on:%s)"
, getString(occ).c_str()
) << endl;
return;
}
cdebug_log(160,0) << "Equipotential::add(): " << occ << endl;
_components.insert( occ );
NetMap::iterator inet = _nets.find( comp->getNet() );
if (inet != _nets.end()) {
inet->second.first++;
if (inet->second.first > inet->second.second) {
cerr << Error( "Equipotential::add(): Doubly counted component of %s.\n"
" (on:%s)"
, getString(inet->first).c_str()
, getString(occ).c_str()
) << endl;
}
return;
}
uint32_t compCount = 0;
for ( Component* component : comp->getNet()->getComponents() ) {
if (dynamic_cast<Plug*>(component)) continue;
++compCount;
}
_nets.insert( make_pair( comp->getNet(), make_pair(1,compCount) ));
if (comp->getNet()->isFused()) {
_hasFused = true;
return;
}
if (_nets.size() <= 1 + ((_hasFused) ? 1 : 0))
return;
Net* netA = nullptr;
for ( auto item : _nets ) {
if (not item.first->isFused() and (item.first != comp->getNet())) {
netA = item.first;
break;
}
}
_shortCircuits.push_back( new ShortCircuit( netA, comp->getNet(), comp ));
} else {
Equipotential* equi = dynamic_cast<Equipotential*>( occ.getEntity() );
if (not equi) {
cerr << Error( "Equipotential::add(): Occurrence is not an Equipotential.\n"
" (on:%s)"
, getString(occ).c_str()
) << endl;
return;
}
if (not occ.getPath().getTailPath().isEmpty()) {
cerr << Error( "Equipotential::add(): Occurrence is more than one instances deep.\n"
" (on:%s)"
, getString(occ).c_str()
) << endl;
return;
}
_childs.insert( occ );
}
_boundingBox.merge( boundingBox );
}
void Equipotential::merge ( Equipotential* other )
{
if (this == other) {
cerr << Warning( "Equipotential::merge(): Attempt to merge itself (ignored).\n"
" (on: %s)"
, getString(this).c_str()
) << endl;
return;
}
for ( auto otherNetData : other->_nets ) {
NetMap::iterator inet = _nets.find( otherNetData.first );
if (inet != _nets.end()) {
//inet->second.first += otherNetData.second.first;
continue;
}
if (otherNetData.first->isFused()) _hasFused = true;
_nets.insert( make_pair( otherNetData.first, make_pair(0,otherNetData.second.second) ));
if (_nets.size() > 1 + ((_hasFused) ? 1 : 0)) {
cdebug_log(169,0) << "Short by merging equis." << _nets.size() << endl;
for ( auto inet : _nets ) {
cdebug_log(169,0) << "this | " << inet.first << endl;
}
for ( auto inet : other->_nets ) {
cdebug_log(169,0) << "other | " << inet.first << endl;
}
}
}
//cerr << "Equipotential::merge() " << this << endl;
//cerr << " " << other << endl;
for ( const Occurrence& component : other->getComponents () ) add( component );
for ( const Occurrence& child : other->getChilds () ) add( child );
for ( ShortCircuit* shortCircuit : other->getShortCircuits () ) add( shortCircuit );
_boundingBox.merge( other->_boundingBox );
//cerr << "Equipotential::merge() done" << endl;
other->clear();
}
void Equipotential::consolidate ()
{
EquipotentialRelation* relation = EquipotentialRelation::create( this );
for ( const Occurrence& occurrence : getComponents() ) {
Component* component = dynamic_cast<Component*>( occurrence.getEntity() );
if (not component) continue;
if (not occurrence.getPath().isEmpty()) {
//cerr << "Occurrence from a DeepNet " << occurrence << endl;
continue;
}
component->put( relation );
}
if (not _nets.empty()) {
_name = getString( (*_nets.begin()).first->getName() );
}
for ( auto netData : _nets ) {
Net* net = netData.first;
if (net->isFused()) continue;
if (net->isExternal ()) _isExternal = true;
if (net->isGlobal ()) _isGlobal = true;
if (net->isAutomatic()) _isAutomatic = true;
_type = net->getType();
_direction |= net->getDirection();
if (netData.second.first >= netData.second.second) {
for ( Component* component : net->getComponents() ) {
if (dynamic_cast<Plug*>(component)) continue;
component->remove( relation );
}
net->put( relation );
}
cdebug_log(169,0) << netData.first << " [" << netData.second.first
<< " / " << netData.second.second << "]" << endl;
}
for ( Occurrence childEqui : _childs ) {
childEqui.put( relation );
}
if (_components.empty() and _nets.empty()) _isBuried = true;
#if FIRST_IMPLEMENTATION
EquipotentialRelation* relation = EquipotentialRelation::create( this );
map<Net*,uint32_t,NetCompareByName> nets;
set<Occurrence,OccNetCompareByName> deepNets;
for ( const Occurrence& occurrence : getComponents() ) {
Component* component = dynamic_cast<Component*>( occurrence.getEntity() );
if (not component) continue;
if (not occurrence.getPath().isEmpty()) {
deepNets.insert( Occurrence( component->getNet(), occurrence.getPath() ));
continue;
}
component->put( relation );
Net* net = component->getNet();
if (net->isFused()) _hasFused = true;
else {
if (net->isExternal ()) _isExternal = true;
if (net->isGlobal ()) _isGlobal = true;
if (net->isAutomatic()) _isAutomatic = true;
_type = net->getType();
_direction |= net->getDirection();
}
uint32_t accounted = (dynamic_cast<Plug*>(component)) ? 0 : 1;
auto inet = nets.find( component->getNet() );
if (inet != nets.end())
inet->second += accounted;
else
nets.insert( make_pair( component->getNet(), accounted ) );
}
if (not nets.empty()) {
_name = getString( (*nets.begin()).first->getName() );
} else {
if (not deepNets.empty()) {
_name = (*deepNets.begin()).getCompactString();
}
}
_netCount = nets.size();
for ( auto item : nets ) {
Net* net = item.first;
uint32_t count = 0;
for ( Component* component : net->getComponents() ) {
count += (dynamic_cast<Plug*>(component)) ? 0 : 1;
}
if (count > item.second) continue;
if (count < item.second) {
cerr << Error( "Equipotential::consolidate(): On %s, found more components of %s than existing (%d > %d)."
, getString(this).c_str()
, getString(net).c_str()
, item.second
, count ) << endl;
}
for ( Component* component : net->getComponents() ) {
if (dynamic_cast<Plug*>(component)) continue;
component->remove( relation );
}
net->put( relation );
//_nets.insert( net );
}
for ( Occurrence childEqui : _childs ) {
childEqui.put( relation );
}
if (_components.empty() and _nets.empty()) _isBuried = true;
// if (_name == "abc_11873_auto_rtlil_cc_2560_muxgate_11612")
// show();
#endif
}
void Equipotential::clear ()
{
_components .clear();
_childs .clear();
_nets .clear();
_shortCircuits.clear();
}
void Equipotential::show () const
{
cerr << this << endl;
cerr << "+ Components:" << endl;
for ( const Occurrence& component : _components ) {
cerr << "| " << component << endl;
}
cerr << "+ Occurrences:" << endl;
for ( Occurrence occ : _childs ) {
cerr << "| " << occ << endl;
}
}
string Equipotential::getFlagsAsString () const
{
string sflags;
sflags += ((_isExternal ) ? "e" : "-");
sflags += ((_isGlobal ) ? "g" : "-");
sflags += ((_isAutomatic) ? "a" : "-");
sflags += ((_isBuried ) ? "B" : "-");
sflags += " [N:" + getString( _nets.size() - ((_hasFused) ? 1 : 0) );
sflags += "+E:" + getString( _childs.size() );
if (_hasFused)
sflags += "+fused";
sflags += "] ";
return sflags;
}
string Equipotential::_getTypeName () const
{ return "Tramontana::Equipotential"; }
string Equipotential::_getString () const
{
ostringstream os;
os << "<Equipotential id:" << getId() << " "
<< getFlagsAsString()
<< " " << getName()
<< " " << getType()
<< " " << getDirection()
<< ">";
return os.str();
}
Record* Equipotential::_getRecord () const
{
Record* record = Super::_getRecord();
if (record) {
record->add( getSlot( "_name" , &_name ) );
record->add( getSlot( "_boundingBox", &_boundingBox ) );
//record->add( getSlot( "_nets" , &_nets ) );
record->add( getSlot( "_components" , &_components ) );
record->add( getSlot( "_childs" , &_childs ) );
}
return record;
}
} // Tramontana namespace.

View File

@ -0,0 +1,245 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | T r a m o n t a n a - Extractor & LVX |
// | |
// | Algorithm : Christian MASSON |
// | First impl. : Yifei WU |
// | Second impl. : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./EquipotentialComponents.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/Error.h"
#include "tramontana/EquipotentialComponents.h"
#include "tramontana/Equipotential.h"
namespace Tramontana {
using namespace std;
using Hurricane::tab;
using Hurricane::Error;
using Hurricane::Path;
// -------------------------------------------------------------------
// Class : "Tramontana::EquipotentialComponents".
EquipotentialComponents::EquipotentialComponents ()
: Super()
, _equipotential(nullptr)
{ }
EquipotentialComponents::EquipotentialComponents ( const Equipotential* equi )
: Super()
, _equipotential(equi)
{ }
EquipotentialComponents::EquipotentialComponents ( const EquipotentialComponents& other )
: Super()
, _equipotential(other._equipotential)
{ }
EquipotentialComponents& EquipotentialComponents::operator= ( const EquipotentialComponents& other )
{
_equipotential = other._equipotential;
return *this;
}
Collection<Occurrence>* EquipotentialComponents::getClone () const
{ return new EquipotentialComponents( *this ); }
Locator<Occurrence>* EquipotentialComponents::getLocator () const
{ return new Locator ( _equipotential ); }
string EquipotentialComponents::_getString () const
{
string s = "<EquipotentialComponents ";
if (_equipotential) {
s += " " + getString( _equipotential );
} else {
s += " NULL";
}
s += ">";
return s;
}
// -------------------------------------------------------------------
// Class : "Tramontana::EquipotentialComponents::Locator".
EquipotentialComponents::Locator::Locator ()
: Super()
, _equipotential (nullptr)
, _state (Constructed)
, _componentsIterator()
, _netsIterator ()
, _childsIterator ()
, _childCompsLocator (nullptr)
, _componentsLocator (nullptr)
{ }
EquipotentialComponents::Locator::Locator ( const Equipotential* equi )
: Super()
, _equipotential (equi)
, _state (Constructed)
, _componentsIterator(equi->getComponents().end())
, _netsIterator (equi->getNets().end())
, _childsIterator (equi->getChilds().end())
, _childCompsLocator (nullptr)
, _componentsLocator (nullptr)
{
progress();
}
EquipotentialComponents::Locator::Locator ( const Locator& other )
: Super()
, _equipotential (other._equipotential)
, _state (other._state)
, _componentsIterator(other._componentsIterator)
, _netsIterator (other._netsIterator)
, _childsIterator (other._childsIterator)
, _childCompsLocator (nullptr)
, _componentsLocator (nullptr)
{
if (other._childCompsLocator) _childCompsLocator = other._childCompsLocator->getClone();
if (other._componentsLocator) _componentsLocator = other._componentsLocator->getClone();
}
EquipotentialComponents::Locator& EquipotentialComponents::Locator::operator= ( const Locator& other )
{
_equipotential = other._equipotential;
_state = other._state;
_componentsIterator= other._componentsIterator;
_netsIterator = other._netsIterator;
_childsIterator = other._childsIterator;
_componentsLocator = (other._componentsLocator) ? other._componentsLocator->getClone() : nullptr;
_childCompsLocator = (other._childCompsLocator) ? other._childCompsLocator->getClone() : nullptr;
return *this;
}
Occurrence EquipotentialComponents::Locator::getElement () const
{
if (not _equipotential or (_state >= Finished)) return Occurrence();
switch ( _state ) {
case InComponents: return (*_componentsIterator);
case InNets: return Occurrence( _componentsLocator->getElement() );
case InChildEquis: {
Path compPath = (*_childsIterator).getPath();
Path tailPath = _childCompsLocator->getElement().getPath();
while ( not tailPath.isEmpty() ) {
compPath = Path( compPath, tailPath.getHeadInstance() );
tailPath = tailPath.getTailPath();
}
return Occurrence( _childCompsLocator->getElement().getEntity(), compPath );
}
default:
break;
}
return Occurrence();
}
Locator<Occurrence>* EquipotentialComponents::Locator::getClone () const
{ return new Locator( *this ); }
bool EquipotentialComponents::Locator::isValid () const
{ return (_equipotential) and (_state < Finished); }
void EquipotentialComponents::Locator::progress ()
{
while ( isValid() ) {
switch ( _state ) {
case Constructed: {
_state = InComponents;
_componentsIterator = _equipotential->getComponents().begin();
if (_componentsIterator != _equipotential->getComponents().end()) return;
}
case InComponents: {
if (_componentsIterator != _equipotential->getComponents().end()) {
++_componentsIterator;
if (_componentsIterator != _equipotential->getComponents().end()) return;
}
_state = InNets;
_netsIterator = _equipotential->getNets().begin();
}
case InNets: {
if (_netsIterator != _equipotential->getNets().end()) {
if ( not _netsIterator->first->isFused()
and _netsIterator->first->getProperty(EquipotentialRelation::staticGetName())) {
if (not _componentsLocator) {
_componentsLocator = _netsIterator->first->getComponents().getLocator()->getClone();
if (_componentsLocator->isValid()) return;
} else {
_componentsLocator->progress();
if (_componentsLocator->isValid()) return;
}
}
_componentsLocator = nullptr;
++_netsIterator;
if (_netsIterator != _equipotential->getNets().end())
continue;
}
_state = InChildEquis;
_childsIterator = _equipotential->getChilds().begin();
}
case InChildEquis: {
if (_childsIterator != _equipotential->getChilds().end()) {
if (not _childCompsLocator) {
Equipotential* child = dynamic_cast<Equipotential*>( (*_childsIterator).getEntity() );
_childCompsLocator = child->getFlatComponents().getLocator()->getClone();
if (_childCompsLocator->isValid()) return;
} else {
_childCompsLocator->progress();
if (_childCompsLocator->isValid()) return;
}
_childCompsLocator = nullptr;
++_childsIterator;
if (_childsIterator != _equipotential->getChilds().end())
continue;
}
_state = Finished;
}
case Finished:
break;
}
}
}
string EquipotentialComponents::Locator::_getString () const
{
string s = "<EquipotentialComponents::Locator";
if (_equipotential) {
s += " " + getString(_equipotential);
} else {
s += " NULL";
}
s += ">";
return s;
}
} // Tramontana namespace.

View File

@ -0,0 +1,86 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | T r a m o n t a n a - Extractor & LVX |
// | |
// | Algorithm : Christian MASSON |
// | First impl. : Yifei WU |
// | Second impl. : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./EquipotentialRelation.cpp" |
// +-----------------------------------------------------------------+
#include "tramontana/EquipotentialRelation.h"
#include "tramontana/TramontanaEngine.h"
namespace Tramontana {
using std::string;
using Hurricane::Property;
// -------------------------------------------------------------------
// Class : "Tramontana::EquipotentialRelation".
const Name EquipotentialRelationName = "EquipotentialRelation";
EquipotentialRelation::EquipotentialRelation ( Equipotential* owner )
: Super(owner)
{ }
EquipotentialRelation* EquipotentialRelation::create ( Equipotential* owner )
{
EquipotentialRelation* relation = new EquipotentialRelation ( owner );
relation->_postCreate();
return relation;
}
void EquipotentialRelation::_preDestroy ()
{ Super::_preDestroy(); }
Name EquipotentialRelation::staticGetName ()
{ return EquipotentialRelationName; }
Name EquipotentialRelation::getName () const
{ return EquipotentialRelationName; }
string EquipotentialRelation::_getTypeName () const
{ return "EquipotentialRelation"; }
Record* EquipotentialRelation::_getRecord () const
{
Record* record = Super::_getRecord();
return record;
}
EquipotentialRelation* EquipotentialRelation::get ( const Component* component )
{
if (not component) return nullptr;
Property* property = component->getProperty( EquipotentialRelationName );
if (not property) return nullptr;
EquipotentialRelation* relation = dynamic_cast<EquipotentialRelation*>( property );
if (not relation) return nullptr;
return relation;
}
} // Tramontana namespace.

View File

@ -0,0 +1,122 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | T r a m o n t a n a - Extractor & LVX |
// | |
// | Algorithm : Christian MASSON |
// | First impl. : Yifei WU |
// | Second impl. : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./EquipotentialsModel.cpp" |
// +-----------------------------------------------------------------+
#include <QFont>
#include <QApplication>
#include "hurricane/Name.h"
#include "hurricane/Net.h"
#include "hurricane/Cell.h"
#include "hurricane/viewer/Graphics.h"
#include "tramontana/EquipotentialsModel.h"
namespace Tramontana {
using Hurricane::Graphics;
EquipotentialsModel::EquipotentialsModel ( QObject* parent )
: QAbstractTableModel(parent)
, _cell (nullptr)
, _equipotentials ()
{ }
QVariant EquipotentialsModel::data ( const QModelIndex& index, int role ) const
{
static QFont nameFont = Graphics::getFixedFont ( QFont::Bold );
static QFont valueFont = Graphics::getFixedFont ( QFont::Normal, true );
if (role == Qt::FontRole) {
switch (index.column()) {
case 0: return nameFont;
default: return valueFont;
}
return QVariant();
}
if (not index.isValid()) return QVariant ();
if (role == Qt::DisplayRole) {
Equipotential* equi = _equipotentials[ index.row() ];
switch ( index.column() ) {
case 0: return QString::fromStdString( equi->getName() );
case 1: return QString::fromStdString( equi->getFlagsAsString() );
case 2: return QString::fromStdString( getString( equi->getType() ));
case 3: return QString::fromStdString( getString( equi->getDirection() ));
}
}
return QVariant();
}
QVariant EquipotentialsModel::headerData ( int section
, Qt::Orientation orientation
, int role ) const
{
if (orientation == Qt::Vertical) return QVariant();
static QFont headerFont = Graphics::getFixedFont( QFont::Bold, false, false, +0 );
if (role == Qt::FontRole ) return headerFont;
if (role != Qt::DisplayRole) return QVariant();
if (section == 0) return QVariant( "Name" );
if (section == 1) return QVariant( "Flags" );
if (section == 2) return QVariant( "Type" );
if (section == 3) return QVariant( "Direction" );
return QVariant();
}
int EquipotentialsModel::rowCount ( const QModelIndex& parent ) const
{ return _equipotentials.size(); }
int EquipotentialsModel::columnCount ( const QModelIndex& parent ) const
{ return 4; }
const Equipotential* EquipotentialsModel::getEqui ( int row )
{
if (row >= (int)_equipotentials.size()) return nullptr;
return _equipotentials[ row ];
}
void EquipotentialsModel::setCell ( Cell* cell )
{
if (_cell != cell) {
emit layoutAboutToBeChanged ();
if (_cell) _equipotentials.clear();
_cell = cell;
if (_cell) {
TramontanaEngine* tramontana = TramontanaEngine::get( _cell );
if (tramontana) {
for ( Equipotential* equi : tramontana->getEquipotentials() )
_equipotentials.push_back( equi );
}
}
emit layoutChanged ();
}
}
} // Tramontana namespace.

View File

@ -0,0 +1,269 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | T r a m o n t a n a - Extractor & LVX |
// | |
// | Algorithm : Christian MASSON |
// | First impl. : Yifei WU |
// | Second impl. : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Header : "./EquipotentialsWidget.cpp" |
// +-----------------------------------------------------------------+
#include <QFontMetrics>
#include <QLabel>
#include <QLineEdit>
#include <QHeaderView>
#include <QKeyEvent>
#include <QGroupBox>
#include <QVBoxLayout>
#include <QAction>
#include <QModelIndex>
#include "hurricane/Commons.h"
#include "hurricane/viewer/Graphics.h"
#include "tramontana/EquipotentialsModel.h"
#include "tramontana/EquipotentialsWidget.h"
namespace Tramontana {
using std::cerr;
using std::endl;
using Hurricane::Bug;
using Hurricane::Graphics;
// -------------------------------------------------------------------
// Class : "BuriedFilterProxymodel".
EquiFilterProxyModel::EquiFilterProxyModel ( QObject* parent )
: Super (parent)
, _filter(NoFilter)
{ }
void EquiFilterProxyModel::setFilter ( uint32_t filter )
{ _filter = filter; invalidateFilter(); }
bool EquiFilterProxyModel::filterAcceptsRow ( int row, const QModelIndex& index ) const
{
EquipotentialsModel* model = dynamic_cast<EquipotentialsModel*>( sourceModel() );
if (not model) return true;
const Equipotential* equi = model->getEqui( row );
if (not (_filter & ShowBuried) and equi->isBuried()) return false;
return true;
}
// -------------------------------------------------------------------
// Class : "EquipotentialsWidget".
EquipotentialsWidget::EquipotentialsWidget ( QWidget* parent )
: QWidget (parent)
, _cellWidget (NULL)
, _cell (NULL)
, _baseModel (new EquipotentialsModel(this))
, _sortModel (new QSortFilterProxyModel(this))
, _filterModel (new EquiFilterProxyModel(this))
, _view (new QTableView(this))
, _rowHeight (20)
, _selecteds ()
, _forceReselect(false)
{
setAttribute( Qt::WA_DeleteOnClose );
setAttribute( Qt::WA_QuitOnClose, false );
setContextMenuPolicy( Qt::ActionsContextMenu );
_rowHeight = QFontMetrics( Graphics::getFixedFont() ).height() + 4;
_filterModel->setSourceModel ( _baseModel );
//_filterModel->setFilter ( EquiFilterProxyModel::ShowBuried );
_sortModel->setSourceModel ( _filterModel );
_sortModel->setDynamicSortFilter( true );
_sortModel->setFilterKeyColumn ( 0 );
_view->setShowGrid ( false );
_view->setAlternatingRowColors( true );
_view->setSelectionBehavior ( QAbstractItemView::SelectRows );
_view->setSortingEnabled ( true );
_view->setModel ( _sortModel );
QHeaderView* horizontalHeader = _view->horizontalHeader();
horizontalHeader->setDefaultAlignment ( Qt::AlignHCenter );
horizontalHeader->setMinimumSectionSize( (Graphics::isHighDpi()) ? 150 : 75 );
horizontalHeader->setStretchLastSection( true );
QHeaderView* verticalHeader = _view->verticalHeader();
verticalHeader->setVisible( false );
verticalHeader->setDefaultSectionSize( _rowHeight );
// verticalHeader->setStyleSheet( "QHeaderView::section {"
// "padding-bottom: 0px;"
// "padding-top: 0px;"
// "padding-left: 0px;"
// "padding-right: 1px;"
// "margin: 0px;"
// "}"
// );
_filterPatternLineEdit = new QLineEdit( this );
QLabel* filterPatternLabel = new QLabel( tr("&Filter pattern:"), this );
filterPatternLabel->setBuddy( _filterPatternLineEdit );
QGridLayout* gLayout = new QGridLayout();
gLayout->addWidget( _view , 1, 0, 1, 2 );
gLayout->addWidget( filterPatternLabel , 2, 0 );
gLayout->addWidget( _filterPatternLineEdit, 2, 1 );
setLayout( gLayout );
QAction* fitAction = new QAction( tr("&Fit to Equi"), this );
fitAction->setShortcut ( QKeySequence(tr("CTRL+F")) );
fitAction->setStatusTip( tr("Fit the view to the Equipotentials's bounding box") );
addAction( fitAction );
connect( _filterPatternLineEdit , SIGNAL(textChanged(const QString &))
, this , SLOT (textFilterChanged()) );
connect( _view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection&,const QItemSelection&))
, this , SLOT (updateSelecteds (const QItemSelection&,const QItemSelection&)) );
connect( fitAction, SIGNAL(triggered()), this, SLOT(fitToEqui()) );
resize( 300, 300 );
}
QModelIndex EquipotentialsWidget::mapToSource ( QModelIndex viewIndex ) const
{ return _filterModel->mapToSource( _sortModel->mapToSource( viewIndex )); }
void EquipotentialsWidget::setShowBuried ( bool state )
{
_filterModel->setFilter( (state) ? EquiFilterProxyModel::ShowBuried
: EquiFilterProxyModel::NoFilter );
}
void EquipotentialsWidget::goTo ( int delta )
{
if ( delta == 0 ) return;
QModelIndex newIndex = _sortModel->index( _view->currentIndex().row()+delta, 0, QModelIndex() );
if (newIndex.isValid())
_view->selectRow( newIndex.row() );
}
void EquipotentialsWidget::updateSelecteds ()
{
_forceReselect = true;
QItemSelection dummy;
updateSelecteds( dummy, dummy );
}
void EquipotentialsWidget::updateSelecteds ( const QItemSelection& , const QItemSelection& )
{
if (_cellWidget) _cellWidget->openRefreshSession ();
_selecteds.resetAccesses ();
const Equipotential* equi = nullptr;
QModelIndexList iList = _view->selectionModel()->selectedRows();
for ( int i=0 ; i<iList.size() ; i++ ) {
equi = _baseModel->getEqui( mapToSource(iList[i]).row() );
if ( equi )
_selecteds.insert( equi );
}
if (_forceReselect) {
_selecteds.forceInserteds();
_forceReselect = false;
}
SelectedEquiSet::iterator isel = _selecteds.begin ();
while ( isel != _selecteds.end() ) {
SelectedEquiSet::iterator remove = isel++;
if (remove->getAccesses() == 0) {
emit equipotentialUnselect ( remove->getEqui()->getFlatComponents() );
_selecteds.erase( remove );
}
}
isel = _selecteds.begin ();
while ( isel != _selecteds.end() ) {
if (isel->getAccesses() == 64) {
emit equipotentialSelect ( isel->getEqui()->getFlatComponents() );
}
++isel;
}
isel = _selecteds.begin ();
if (_cellWidget) _cellWidget->closeRefreshSession ();
}
void EquipotentialsWidget::textFilterChanged ()
{
_sortModel->setFilterRegExp( _filterPatternLineEdit->text() );
//updateSelecteds ();
}
void EquipotentialsWidget::fitToEqui ()
{
const Equipotential* equi = _baseModel->getEqui( mapToSource(_view->currentIndex()).row() );
if (equi) emit reframe ( equi->getBoundingBox() );
}
void EquipotentialsWidget::setCellWidget ( CellWidget* cw )
{
if (_cellWidget) {
disconnect( this, 0, _cellWidget, 0 );
}
_cellWidget = cw;
if (_cellWidget) {
setCell( _cellWidget->getCell() );
connect( this, SIGNAL( reframe(const Box&) ), _cellWidget, SLOT( reframe(const Box&) ));
} else
setCell( nullptr );
}
void EquipotentialsWidget::setCell ( Cell* cell )
{
_cell = cell;
_view->setVisible( false );
_view->selectionModel()->clear();
_baseModel->setCell( cell );
string windowTitle = "Equis" + getString(cell);
setWindowTitle( tr(windowTitle.c_str()) );
QHeaderView* header = _view->horizontalHeader();
_view->selectRow( 0 );
for ( int i=0 ; i<_baseModel->columnCount() ; ++i ) {
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
header->setSectionResizeMode( i, QHeaderView::Interactive );
#else
header->setResizeMode( i, QHeaderView::Interactive );
#endif
_view->resizeColumnToContents( i );
}
_view->setVisible( true );
}
}

View File

@ -0,0 +1,258 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | T r a m o n t a n a - Extractor & LVX |
// | |
// | Algorithm : Christian MASSON |
// | First impl. : Yifei WU |
// | Second impl. : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./GraphicTramontanaEngine.cpp" |
// +-----------------------------------------------------------------+
#include <boost/bind.hpp>
#include <QAction>
#include <QMenu>
#include <QMenuBar>
#include <QApplication>
#include <hurricane/Warning.h>
#include <hurricane/Error.h>
#include <hurricane/Breakpoint.h>
#include <hurricane/DebugSession.h>
#include <hurricane/Go.h>
#include <hurricane/Net.h>
#include <hurricane/Cell.h>
#include <hurricane/viewer/Graphics.h>
#include <hurricane/viewer/CellWidget.h>
#include <hurricane/viewer/CellViewer.h>
#include <hurricane/viewer/ControllerWidget.h>
#include <hurricane/viewer/ExceptionWidget.h>
#include <crlcore/Utilities.h>
#include <crlcore/AllianceFramework.h>
#include <anabatic/GCell.h>
#include <tramontana/TabEquipotentials.h>
#include <tramontana/GraphicTramontanaEngine.h>
namespace Tramontana {
using namespace std;
using Hurricane::Error;
using Hurricane::Warning;
using Hurricane::Exception;
using Hurricane::Breakpoint;
using Hurricane::DebugSession;
using Hurricane::Point;
using Hurricane::Entity;
using Hurricane::Net;
using Hurricane::Graphics;
using Hurricane::ColorScale;
using Hurricane::DisplayStyle;
using Hurricane::ControllerWidget;
using Hurricane::ExceptionWidget;
using CRL::Catalog;
using CRL::AllianceFramework;
size_t GraphicTramontanaEngine::_references = 0;
GraphicTramontanaEngine* GraphicTramontanaEngine::_singleton = NULL;
#if THIS_IS_DISABLED
void GraphicTramontanaEngine::initGCell ( CellWidget* widget )
{
widget->getDrawingPlanes().setPen( Qt::NoPen );
TramontanaEngine* tramontana = TramontanaEngine::get( widget->getCell() );
if (tramontana) tramontana->setDensityMode( GCell::MaxDensity );
}
void GraphicTramontanaEngine::drawGCell ( CellWidget* widget
, const Go* go
, const BasicLayer* basicLayer
, const Box& box
, const Transformation& transformation
)
{
const GCell* gcell = static_cast<const GCell*>(go);
QPainter& painter = widget->getPainter();
QPen pen = Graphics::getPen ("Anabatic::GCell",widget->getDarkening());
Box bb = gcell->getBoundingBox();
QRect pixelBb = widget->dbuToScreenRect(bb);
if (GCell::getDisplayMode() == GCell::Density) {
uint32_t density = (unsigned int)( 255.0 * gcell->getDensity() );
if (density > 255) density = 255;
painter.setBrush( Graphics::getColorScale( ColorScale::Fire ).getBrush( density, widget->getDarkening() ) );
painter.drawRect( pixelBb );
} else {
int fontScale = 0;
int halfHeight = 20;
int halfWidth = 80;
if (widget->isPrinter()) {
fontScale = -5;
halfHeight = 9;
halfWidth = 39;
}
painter.setPen ( pen );
painter.setBrush( Graphics::getBrush("Anabatic::GCell",widget->getDarkening()) );
painter.drawRect( pixelBb );
if ( (pixelBb.width() > 2*halfWidth) and (pixelBb.height() > 2*halfHeight) ) {
QString text = QString("%1").arg(gcell->getId());
QFont font = Graphics::getFixedFont( QFont::Normal, false, false, fontScale );
painter.setFont(font);
pen.setWidth( 1 );
painter.setPen( pen );
painter.save ();
painter.translate( widget->dbuToScreenPoint(bb.getCenter().getX(), bb.getCenter().getY()) );
painter.drawRect ( QRect( -halfWidth, -halfHeight, 2*halfWidth, 2*halfHeight ) );
painter.drawText ( QRect( -halfWidth, -halfHeight, 2*halfWidth, 2*halfHeight )
, text
, QTextOption(Qt::AlignCenter)
);
painter.restore ();
}
}
}
#endif
TramontanaEngine* GraphicTramontanaEngine::createEngine ()
{
Cell* cell = getCell ();
TramontanaEngine* tramontana = TramontanaEngine::get( cell );
if (not tramontana) {
tramontana = TramontanaEngine::create( cell );
tramontana->setViewer( _viewer );
} else
cerr << Warning( "%s already has a Tramontana engine.", getString(cell).c_str() ) << endl;
return tramontana;
}
TramontanaEngine* GraphicTramontanaEngine::getForFramework ( uint32_t flags )
{
// Currently, only one framework is avalaible: Alliance.
TramontanaEngine* tramontana = TramontanaEngine::get( getCell() );
if (tramontana) return tramontana;
if (flags & CreateEngine) {
tramontana = createEngine();
if (not tramontana)
throw Error( "Failed to create Tramontana engine on %s.", getString(getCell()).c_str() );
} else {
throw Error( "TramontanaEngine not created yet, run the global router first." );
}
return tramontana;
}
void GraphicTramontanaEngine::_extract ()
{
TramontanaEngine* tramontana = getForFramework( CreateEngine );
tramontana->extract();
//Breakpoint::stop( 0, "GraphicTramontanaEngine::_extract() done." );
}
void GraphicTramontanaEngine::addToMenu ( CellViewer* viewer )
{
assert(_viewer == NULL);
_viewer = viewer;
if (_viewer->hasMenuAction("tools.extract")) {
cerr << Warning( "GraphicTramontanaEngine::addToMenu() - Tramontana extractor already hooked in." ) << endl;
return;
}
_viewer->addToMenu( "tools.extract"
, "E&xtract . . . . . [Tramontana]"
, "Run the extractor"
, std::bind(&GraphicTramontanaEngine::_extract,this)
);
ControllerWidget* controller = viewer->getControllerWidget();
if (controller) {
TabEquipotentials* tabEqui = new TabEquipotentials ();
tabEqui->setObjectName( "controller.tabEquipotentials" );
tabEqui->setCellWidget( viewer->getCellWidget() );
controller->insertTabAfter( "controller.tabNetlist", tabEqui, "Equipotentials" );
}
}
const Name& GraphicTramontanaEngine::getName () const
{ return TramontanaEngine::staticGetName(); }
Cell* GraphicTramontanaEngine::getCell ()
{
if (not _viewer) {
throw Error( "<b>Tramontana:</b> GraphicTramontanaEngine not bound to any Viewer." );
return NULL;
}
if (not _viewer->getCell()) {
throw Error( "<b>Tramontana:</b> No Cell is loaded into the Viewer." );
return NULL;
}
return _viewer->getCell();
}
GraphicTramontanaEngine* GraphicTramontanaEngine::grab ()
{
if (not _references) {
_singleton = new GraphicTramontanaEngine ();
}
_references++;
return _singleton;
}
size_t GraphicTramontanaEngine::release ()
{
--_references;
if (not _references) {
delete _singleton;
_singleton = NULL;
}
return _references;
}
GraphicTramontanaEngine::GraphicTramontanaEngine ()
: GraphicTool()
, _viewer (NULL)
{
#if THIS_IS_DISABLED
addDrawGo( "Anabatic::GCell", initGCell, drawGCell );
addDrawGo( "Anabatic::Edge" , initEdge , drawEdge );
#endif
}
GraphicTramontanaEngine::~GraphicTramontanaEngine ()
{ }
} // Tramontana namespace.

View File

@ -0,0 +1,113 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | T r a m o n t a n a - Extractor & LVX |
// | |
// | Algorithm : Christian MASSON |
// | First impl. : Yifei WU |
// | Second impl. : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./PyGraphicTramontanaEngine.cpp" |
// +-----------------------------------------------------------------+
#include "tramontana/PyGraphicTramontanaEngine.h"
#include "hurricane/isobar/PyCell.h"
#include "hurricane/Cell.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(GraphicTramontanaEngine,gtool,function)
namespace Tramontana {
using namespace Hurricane;
using namespace Isobar;
extern "C" {
// +=================================================================+
// | "PyGraphicTramontanaEngine" Python Module Code Part |
// +=================================================================+
#if defined(__PYTHON_MODULE__)
static PyObject* PyGraphicTramontanaEngine_grab ( PyObject* )
{
cdebug_log(40,0) << "PyGraphicTramontanaEngine_grab()" << endl;
PyGraphicTramontanaEngine* pyGraphicTramontanaEngine = NULL;
HTRY
pyGraphicTramontanaEngine = PyObject_NEW ( PyGraphicTramontanaEngine, &PyTypeGraphicTramontanaEngine );
if ( pyGraphicTramontanaEngine == NULL ) return NULL;
pyGraphicTramontanaEngine->ACCESS_OBJECT = GraphicTramontanaEngine::grab();
HCATCH
return (PyObject*)pyGraphicTramontanaEngine;
}
static PyObject* PyGraphicTramontanaEngine_getCell ( PyGraphicTramontanaEngine* self )
{
cdebug_log(40,0) << "PyGraphicTramontanaEngine_getCell ()" << endl;
Cell* cell = NULL;
HTRY
METHOD_HEAD("GraphicTramontanaEngine.getCell()")
cell = gtool->getCell ();
HCATCH
if (cell == NULL) Py_RETURN_NONE;
return PyCell_Link(cell);
}
GetNameMethod(GraphicTramontanaEngine, gtool)
// Standart destroy (Attribute).
PyMethodDef PyGraphicTramontanaEngine_Methods[] =
{ { "grab" , (PyCFunction)PyGraphicTramontanaEngine_grab , METH_NOARGS|METH_STATIC
, "Returns the GraphicTramontanaEngine singleton." }
, { "getName" , (PyCFunction)PyGraphicTramontanaEngine_getName , METH_NOARGS
, "Returns the name of the GraphicTramontanaEngine (class attribute)." }
, { "getCell" , (PyCFunction)PyGraphicTramontanaEngine_getCell , METH_NOARGS
, "Returns the Cell on which this GraphicTramontanaEngine is attached." }
, {NULL, NULL, 0, NULL} /* sentinel */
};
// ---------------------------------------------------------------
// PyGraphicTramontanaEngine Type Methods.
PythonOnlyDeleteMethod(GraphicTramontanaEngine)
PyTypeObjectLinkPyType(GraphicTramontanaEngine)
#else // End of Python Module Code Part.
// +=================================================================+
// | "PyGraphicTramontanaEngine" Shared Library Code Part |
// +=================================================================+
// Link/Creation Method.
LinkCreateMethod(GraphicTramontanaEngine)
PyTypeInheritedObjectDefinitions(GraphicTramontanaEngine,GraphicTool)
#endif // End of Shared Library Code Part.
} // extern "C".
} // CRL namespace.

View File

@ -0,0 +1,107 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | T r a m o n t a n a - Extractor & LVX |
// | |
// | Algorithm : Christian MASSON |
// | First impl. : Yifei WU |
// | Second impl. : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./PyTramontana.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/isobar/PyHurricane.h"
#include "hurricane/isobar/PyCell.h"
#include "tramontana/PyTramontanaEngine.h"
#include "tramontana/PyGraphicTramontanaEngine.h"
namespace Tramontana {
using std::cerr;
using std::endl;
using Hurricane::tab;
using Isobar::getPyHash;
using Isobar::__cs;
using CRL::PyTypeToolEngine;
using CRL::PyTypeGraphicTool;
#if !defined(__PYTHON_MODULE__)
// +=================================================================+
// | "PyTramontana" Shared Library Code Part |
// +=================================================================+
# else // End of PyHurricane Shared Library Code Part.
// +=================================================================+
// | "PyTramontana" Python Module Code Part |
// +=================================================================+
extern "C" {
static PyMethodDef PyTramontana_Methods[] =
{ {NULL, NULL, 0, NULL} /* sentinel */
};
static PyModuleDef PyTramontana_ModuleDef =
{ PyModuleDef_HEAD_INIT
, .m_name = "Tramontana"
, .m_doc = "Layout extractor & LVX."
, .m_size = -1
, .m_methods = PyTramontana_Methods
};
// ---------------------------------------------------------------
// Module Initialization : "PyInit_Tramontana ()"
PyMODINIT_FUNC PyInit_Tramontana ( void )
{
cdebug_log(40,0) << "PyInit_Tramontana()" << endl;
PyTramontanaEngine_LinkPyType();
PyGraphicTramontanaEngine_LinkPyType();
PYTYPE_READY_SUB( TramontanaEngine , ToolEngine );
PYTYPE_READY_SUB( GraphicTramontanaEngine, GraphicTool );
PyObject* module = PyModule_Create( &PyTramontana_ModuleDef );
if (module == NULL) {
cerr << "[ERROR]\n"
<< " Failed to initialize Tramontana module." << endl;
return NULL;
}
Py_INCREF( &PyTypeTramontanaEngine );
PyModule_AddObject( module, "TramontanaEngine", (PyObject*)&PyTypeTramontanaEngine );
Py_INCREF( &PyTypeGraphicTramontanaEngine );
PyModule_AddObject( module, "GraphicTramontanaEngine", (PyObject*)&PyTypeGraphicTramontanaEngine );
//PyTramontanaEngine_postModuleInit();
return module;
}
} // End of extern "C".
#endif // End of Python Module Code Part.
} // End of Tramontana namespace.

View File

@ -0,0 +1,216 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | T r a m o n t a n a - Extractor & LVX |
// | |
// | Algorithm : Christian MASSON |
// | First impl. : Yifei WU |
// | Second impl. : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./PyTramontanaEngine.cpp" |
// +-----------------------------------------------------------------+
#include "hurricane/isobar/PyNet.h"
#include "hurricane/isobar/PyCell.h"
#include "hurricane/viewer/PyCellViewer.h"
#include "hurricane/viewer/ExceptionWidget.h"
#include "hurricane/Cell.h"
#include "crlcore/Utilities.h"
#include "tramontana/PyTramontanaEngine.h"
#include <functional>
# undef ACCESS_OBJECT
# undef ACCESS_CLASS
# define ACCESS_OBJECT _baseObject._object
# define ACCESS_CLASS(_pyObject) &(_pyObject->_baseObject)
#define METHOD_HEAD(function) GENERIC_METHOD_HEAD(TramontanaEngine,tramontana,function)
namespace Tramontana {
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::__cs;
using Isobar::Converter;
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::PyNet;
using Isobar::PyCell;
using Isobar::PyCell_Link;
using Isobar::PyCellViewer;
using Isobar::PyTypeCellViewer;
using CRL::PyToolEngine;
extern "C" {
#if defined(__PYTHON_MODULE__)
#define DirectVoidToolMethod(SELF_TYPE, SELF_OBJECT, FUNC_NAME) \
static PyObject* Py##SELF_TYPE##_##FUNC_NAME(Py##SELF_TYPE* self) \
{ \
cdebug_log(40,0) << "Py" #SELF_TYPE "_" #FUNC_NAME "()" << endl; \
HTRY \
METHOD_HEAD(#SELF_TYPE "." #FUNC_NAME "()") \
if (SELF_OBJECT->getViewer()) { \
if (ExceptionWidget::catchAllWrapper( std::bind(&TramontanaEngine::FUNC_NAME,SELF_OBJECT) )) { \
PyErr_SetString( HurricaneError, #FUNC_NAME "() has thrown an exception (C++)." ); \
return NULL; \
} \
} else { \
SELF_OBJECT->FUNC_NAME(); \
} \
HCATCH \
Py_RETURN_NONE; \
}
// +=================================================================+
// | "PyTramontanaEngine" Python Module Code Part |
// +=================================================================+
static PyObject* PyTramontanaEngine_get ( PyObject*, PyObject* args )
{
cdebug_log(40,0) << "PyTramontanaEngine_get()" << endl;
TramontanaEngine* tramontana = NULL;
HTRY
PyObject* arg0;
if (not ParseOneArg("Tramontana.get", args, CELL_ARG, &arg0)) return NULL;
tramontana = TramontanaEngine::get(PYCELL_O(arg0));
HCATCH
return PyTramontanaEngine_Link(tramontana);
}
static PyObject* PyTramontanaEngine_create ( PyObject*, PyObject* args )
{
cdebug_log(40,0) << "PyTramontanaEngine_create()" << endl;
TramontanaEngine* tramontana = NULL;
HTRY
PyObject* arg0;
if (not ParseOneArg("Tramontana.get", args, CELL_ARG, &arg0)) return NULL;
Cell* cell = PYCELL_O(arg0);
tramontana = TramontanaEngine::get(cell);
if (tramontana == NULL) {
tramontana = TramontanaEngine::create(cell);
} else
cerr << Warning("%s already has a Tramontana engine.",getString(cell).c_str()) << endl;
HCATCH
return PyTramontanaEngine_Link(tramontana);
}
static PyObject* PyTramontanaEngine_setViewer ( PyTramontanaEngine* self, PyObject* args )
{
cdebug_log(40,0) << "PyTramontanaEngine_setViewer ()" << endl;
HTRY
METHOD_HEAD( "TramontanaEngine.setViewer()" )
PyObject* pyViewer = NULL;
if (not PyArg_ParseTuple(args,"O:TramontanaEngine.setViewer()",&pyViewer)) {
PyErr_SetString( ConstructorError, "Bad parameters given to TramontanaEngine.setViewer()." );
return NULL;
}
if (IsPyCellViewer(pyViewer)) {
tramontana->setViewer( PYCELLVIEWER_O(pyViewer) );
}
HCATCH
Py_RETURN_NONE;
}
static PyObject* PyTramontanaEngine_extract ( PyTramontanaEngine* self )
{
cdebug_log(40,0) << "PyTramontanaEngine_extract()" << endl;
HTRY
METHOD_HEAD("TramontanaEngine.extract()")
if (tramontana->getViewer()) {
if (ExceptionWidget::catchAllWrapper( std::bind(&TramontanaEngine::extract,tramontana) )) {
PyErr_SetString( HurricaneError, "TramontanaEngine::extract() has thrown an exception (C++)." );
return NULL;
}
} else {
tramontana->extract();
}
HCATCH
Py_RETURN_NONE;
}
// Standart Accessors (Attributes).
// Standart Destroy (Attribute).
DBoDestroyAttribute(PyTramontanaEngine_destroy,PyTramontanaEngine)
PyMethodDef PyTramontanaEngine_Methods[] =
{ { "get" , (PyCFunction)PyTramontanaEngine_get , METH_VARARGS|METH_STATIC
, "Returns the Tramontana engine attached to the Cell, None if there isnt't." }
, { "create" , (PyCFunction)PyTramontanaEngine_create , METH_VARARGS|METH_STATIC
, "Create a Tramontana engine on this cell." }
, { "destroy" , (PyCFunction)PyTramontanaEngine_destroy , METH_NOARGS
, "Destroy a Tramontana engine." }
, { "setViewer" , (PyCFunction)PyTramontanaEngine_setViewer , METH_VARARGS
, "Associate a Viewer to this TramontanaEngine." }
, { "extract" , (PyCFunction)PyTramontanaEngine_extract , METH_NOARGS
, "Perform the layout extraction." }
, {NULL, NULL, 0, NULL} /* sentinel */
};
DBoDeleteMethod(TramontanaEngine)
PyTypeObjectLinkPyType(TramontanaEngine)
#else // End of Python Module Code Part.
// +=================================================================+
// | "PyTramontanaEngine" Shared Library Code Part |
// +=================================================================+
// Link/Creation Method.
PyTypeInheritedObjectDefinitions(TramontanaEngine,PyToolEngine)
DBoLinkCreateMethod(TramontanaEngine)
// extern void PyTramontanaEngine_postModuleInit ()
// {
// PyTramontanaFlags_postModuleInit();
// PyDict_SetItemString( PyTypeTramontanaEngine.tp_dict, "Flags", (PyObject*)&PyTypeTramontanaFlags );
// PyObject* constant = NULL;
// LoadObjectConstant( PyTypeTramontanaEngine.tp_dict, TramontanaEngine::GlobalRoutingSuccess , "GlobalRoutingSuccess" )
// LoadObjectConstant( PyTypeTramontanaEngine.tp_dict, TramontanaEngine::DetailedRoutingSuccess, "DetailedRoutingSuccess" )
// }
#endif // Shared Library Code Part.
} // extern "C".
} // Tramontana namespace.

View File

@ -0,0 +1,105 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | T r a m o n t a n a - Extractor & LVX |
// | |
// | Algorithm : Christian MASSON |
// | First impl. : Yifei WU |
// | Second impl. : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./QueryTiles.cpp" |
// +-----------------------------------------------------------------+
#include <vector>
#include "tramontana/QueryTiles.h"
#include "tramontana/SweepLine.h"
namespace Tramontana {
using std::cerr;
using std::endl;
using std::vector;
QueryTiles::QueryTiles ( SweepLine* sweepLine )
: Query ()
, _sweepLine (sweepLine)
, _goMatchCount (0)
, _processedLayers(0)
{
setCell ( sweepLine->getCell() );
setArea ( sweepLine->getCell()->getBoundingBox() );
setFilter( Query::DoComponents|Query::DoTerminalCells );
}
void QueryTiles::setBasicLayer ( const BasicLayer* basicLayer )
{
_processedLayers |= basicLayer->getMask();
Query::setBasicLayer ( basicLayer );
}
bool QueryTiles::isProcessed ( Component* component ) const
{
Layer::Mask fullyProcesseds = _processedLayers & ~getBasicLayer()->getMask();
return component->getLayer()->getMask().intersect( fullyProcesseds );
}
void QueryTiles::masterCellCallback ()
{ }
void QueryTiles::rubberCallback ( Rubber* )
{ }
void QueryTiles::extensionGoCallback ( Go* )
{ }
bool QueryTiles::hasGoCallback () const
{ return true; }
void QueryTiles::goCallback ( Go* go )
{
Tile* rootTile = nullptr;
Component* component = dynamic_cast<Component*>( go );
if (not component) return;
if (isProcessed(component)) return;
Occurrence occurrence = Occurrence( go, getPath() );
for ( const BasicLayer* layer : _sweepLine->getExtracteds() ) {
if (not component->getLayer()->getMask().intersect(layer->getMask())) continue;
Tile* tile = Tile::create( occurrence
, layer
, rootTile
, _sweepLine );
if (not rootTile) rootTile = tile;
}
BasicLayer* cutLayer = component->getLayer()->getBasicLayers().getFirst();
if (cutLayer->getMaterial() == BasicLayer::Material::cut) {
const SweepLine::LayerSet& connexSet = _sweepLine->getCutConnexLayers( cutLayer );
for ( const BasicLayer* connexLayer : connexSet ) {
Tile::create( occurrence
, connexLayer
, rootTile
, _sweepLine
, Tile::ForceLayer );
}
}
_goMatchCount++;
}
} // Tramontana namespace.

View File

@ -0,0 +1,382 @@
// -*- C++ -*-
//
// This file is part of the Coriolis Software.
// Copyright (c) Sorbonne Université 2007-2023, All Rights Reserved
//
// +-----------------------------------------------------------------+
// | C O R I O L I S |
// | T r a m o n t a n a - Extractor & LVX |
// | |
// | Algorithm : Christian MASSON |
// | First impl. : Yifei WU |
// | Second impl. : Jean-Paul CHAPUT |
// | E-mail : Jean-Paul.Chaput@lip6.fr |
// | =============================================================== |
// | C++ Module : "./SweepLine.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/Breakpoint.h"
#include "hurricane/Timer.h"
#include "hurricane/DataBase.h"
#include "hurricane/Technology.h"
#include "hurricane/Layer.h"
#include "hurricane/ViaLayer.h"
#include "hurricane/Net.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 "hurricane/RoutingPad.h"
#include "crlcore/Utilities.h"
#include "tramontana/SweepLine.h"
#include "tramontana/QueryTiles.h"
namespace Tramontana {
using std::cout;
using std::cerr;
using std::endl;
using std::dec;
using std::setw;
using std::setfill;
using std::left;
using std::right;
using std::string;
using std::ostream;
using std::ofstream;
using std::ostringstream;
using std::setprecision;
using std::vector;
using std::make_pair;
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::Interval;
using Hurricane::Box;
using Hurricane::DataBase;
using Hurricane::Technology;
using Hurricane::Layer;
using Hurricane::ViaLayer;
using Hurricane::Entity;
using Hurricane::Horizontal;
using Hurricane::Vertical;
using Hurricane::RoutingPad;
using Hurricane::Cell;
using Hurricane::Instance;
// -------------------------------------------------------------------
// Class : "Tramontana::SweepLine".
SweepLine::SweepLine ( TramontanaEngine* tramontana )
: _tramontana (tramontana)
, _extracteds ()
, _extractedsMask()
, _connexityMap ()
, _tiles ()
, _intervalTrees ()
{
for ( const BasicLayer* bl : DataBase::getDB()->getTechnology()->getBasicLayers() ) {
// HARDCODED. Should read the gauge.
if (getString(bl->getName()).substr(0,6) == "gmetal") continue;
if ( (bl->getMaterial() == BasicLayer::Material::metal)
or (bl->getMaterial() == BasicLayer::Material::poly)
or (bl->getMaterial() == BasicLayer::Material::cut)) {
_extracteds.push_back( bl );
_extractedsMask |= bl->getMask();
}
}
_buildCutConnexMap();
// _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal5" ));
// _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal4" ));
// _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal3" ));
// _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal2" ));
// _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "metal1" ));
// _extracteds.push_back( DataBase::getDB()->getTechnology()->getBasicLayer( "poly" ));
}
SweepLine::~SweepLine ()
{ }
void SweepLine::_buildCutConnexMap ()
{
for ( const ViaLayer* viaLayer : DataBase::getDB()->getTechnology()->getViaLayers() ) {
const BasicLayer* cutLayer = nullptr;
for ( const BasicLayer* layer : viaLayer->getBasicLayers() ) {
if (layer->getMaterial() == BasicLayer::Material::cut) {
cutLayer = layer;
break;
}
}
if (not cutLayer) {
cerr << Error( "SweepLine::_buildConnexityMap(): ViaLayer \"%s\" does not contains any *cut* (ignored)."
, getString(viaLayer->getName()).c_str()
) << endl;
continue;
}
auto iCutMap = _connexityMap.find( cutLayer );
if (iCutMap == _connexityMap.end()) {
_connexityMap.insert( make_pair( cutLayer, LayerSet() ));
iCutMap = _connexityMap.find( cutLayer );
}
for ( const BasicLayer* layer : viaLayer->getBasicLayers() ) {
if ( (layer->getMaterial() != BasicLayer::Material::cut)
and (_extractedsMask.intersect(layer->getMask())) ) {
iCutMap->second.insert( layer );
}
}
}
// for ( auto item : _connexityMap ) {
// cerr << "BasicLayers connex to cut: " << item.first << endl;
// for ( const BasicLayer* bl : item.second ) {
// cerr << "| " << bl << endl;
// }
// }
}
const SweepLine::LayerSet& SweepLine::getCutConnexLayers ( const BasicLayer* cutLayer ) const
{
static LayerSet emptySet;
auto iCutMap = _connexityMap.find( cutLayer );
if (iCutMap == _connexityMap.end())
return emptySet;
return iCutMap->second;
}
void SweepLine::run ()
{
//DebugSession::open( 160, 169 );
cdebug_log(160,1) << "SweepLine::run()" << endl;
loadTiles();
//bool debugOn = false;
//bool written = false;
size_t processedTiles = 0;
for ( Element& element : _tiles ) {
processedTiles++;
if (tty::enabled()) {
cmess2 << " <tile:" << tty::bold << right << setw(10) << setfill('0')
<< processedTiles << tty::reset
<< " remains:" << right << setw(10) << setfill('0')
<< (_tiles.size() - processedTiles)
<< setfill(' ') << tty::reset << ">" << tty::cr;
cmess2.flush ();
}
Tile* tile = element.getTile();
TileIntv tileIntv ( tile, tile->getYMin(), tile->getYMax() );
// if (tile->getOccurrence().getEntity()->getId() == 3348) {
// DebugSession::open( 160, 169 );
// }
// if (getString(tile->getNet()->getName()) == "a(13)") {
// cerr << tile << endl;
// }
// if (not debugOn and (element.getX() == DbU::fromLambda(1724.0))) {
// debugOn = true;
// DebugSession::open( 0, 169 );
// }
// if (debugOn and (element.getX() > DbU::fromLambda(1726.0))) {
// debugOn = false;
// DebugSession::close();
// }
cdebug_log(160,1) << "X@ + " << DbU::getValueString(element.getX()) << " " << tile << endl;
auto intvTree = _intervalTrees.find( element.getMask() );
if (intvTree == _intervalTrees.end()) {
cerr << Error( "SweepLine::run(): Missing interval tree for layer(mask) %s."
" (for tile: %s)"
, getString(element.getMask()).c_str()
, getString(element.getTile()).c_str()
) << endl;
cdebug_tabw(160,-1);
continue;
}
if (element.isLeftEdge()) {
// if (tile->getOccurrence().getEntity()->getId() == 3348) {
// //if (not written) intvTree->second.write( "tree-before.gv" );
// cdebug_log(160,0) << " Interval tree *before* insertion." << endl;
// for ( auto elt : intvTree->second.getElements() ) {
// cdebug_log(160,0) << " | in tree:" << elt << endl;
// if (elt.getData()->getBoundingBox().getXMax() < tile->getLeftEdge())
// cdebug_log(160,0) << " * Should have been removed !" << endl;
// }
// }
for ( const TileIntv& overlap : intvTree->second.getOverlaps(
Interval(tile->getYMin(), tile->getYMax() ))) {
cdebug_log(160,0) << " | intersect " << overlap.getData() << endl;
tile->merge( overlap.getData() );
}
cdebug_log(160,0) << " | insert tile" << endl;
// if (tile->getId() == 60117) {
// cerr << " | insert in " << element.getMask() << endl;
// cerr << " | " << tile << endl;
// }
// if (tile->getId() == 46373) {
// cerr << " | insert " << tile << endl;
// }
intvTree->second.insert( tileIntv );
if (tile->getOccurrence().getEntity()->getId() == 3348) {
//if (not written) intvTree->second.write( "tree-after.gv" );
//written = true;
}
} else {
// if (tile->getId() == 289) {
// DebugSession::open( 0, 169 );
// }
// cdebug_log(160,0) << " | remove tile from " << element.getMask() << endl;
// cdebug_log(160,0) << " | " << tile << endl;
// if ((tile->getId() == 289) and not written) {
// cerr << "(before) written is " << written << endl;
// DebugSession::open( 0, 169 );
// intvTree->second.write( "tree-before.gv" );
// //DebugSession::close();
// for ( auto elt : intvTree->second.getElements() ) {
// cerr << " | in tree:" << elt << endl;
// }
// }
cdebug_log(160,0) << " | remove tile" << endl;
intvTree->second.remove( tileIntv );
// DebugSession::open( 0, 169 );
// intvTree->second.checkVMax();
// DebugSession::close();
// if ((tile->getId() == 289) and not written) {
// //DebugSession::open( 0, 169 );
// written = true;
// cerr << "(after) written is " << written << endl;
// intvTree->second.write( "tree-after.gv" );
// DebugSession::close();
// }
// if (intvTree->second.find( tileIntv ) != intvTree->second.end()) {
// cerr << "NOT Removed " << tileIntv << endl;
// }
// if (tile->getId() == 289) {
// cerr << " | removed " << tile << endl;
// intvTree->second.write( "tree.gv" );
// for ( auto elt : intvTree->second.getElements() ) {
// cerr << " | in tree:" << elt << endl;
// }
// DebugSession::close();
// }
// if (tile->getId() == 46055) {
// intvTree->second.write( "we_at_remove.gv" );
// for ( auto tile : intvTree->second.getElements() ) {
// cerr << "| in tree:" << tile << endl;
// }
// }
}
//intvTree->second.checkVMax();
// cdebug_tabw(160,-1);
// if (tile->getOccurrence().getEntity()->getId() == 3348) {
// DebugSession::close();
// }
cdebug_tabw(160,-1);
}
//if (debugOn) DebugSession::close();
cdebug_tabw(160,-1);
//DebugSession::close();
mergeEquipotentials();
deleteTiles();
}
void SweepLine::loadTiles ()
{
//cerr << "SweepLine::loadTiles()" << endl;
for ( const BasicLayer* layer : _extracteds ) {
_intervalTrees.insert( make_pair( layer->getMask(), TileIntvTree() ));
}
QueryTiles query ( this );
for ( const BasicLayer* layer : _extracteds ) {
query.setBasicLayer( layer );
query.doQuery();
}
cmess2 << " - Loaded " << _tiles.size() << " tiles (from "
<< query.getGoMatchCount() << " gos)." << endl;
// for ( Occurrence occurrence : getCell()->getOccurrencesUnder( getCell()->getBoundingBox() ) ) {
// vector<Tile*> tiles;
// Component* component = dynamic_cast<Component*>( occurrence.getEntity() );
// if (occurrence.getPath().getInstances().getSize() > 0) {
// cerr << occurrence << endl;
// }
// if (not component) continue;
// for ( const BasicLayer* layer : extracteds ) {
// if (not component->getLayer()->getMask().intersect(layer->getMask())) continue;
// tiles.push_back( Tile::create( occurrence, layer ));
// _tiles.push_back( Element( tiles.back(), Tile::LeftEdge ) );
// _tiles.push_back( Element( tiles.back(), Tile::RightEdge ) );
// if (tiles.size() > 1)
// tiles.back()->setParent( tiles[0] );
// }
// tiles.clear();
// }
sort( _tiles.begin(), _tiles.end() );
}
void SweepLine::deleteTiles ()
{
Tile::deleteAllTiles();
}
void SweepLine::mergeEquipotentials ()
{
//DebugSession::open( 160, 169 );
cdebug_log(160,1) << "SweepLine::mergeEquipotentials()" << endl;
//cerr << "SweepLine::mergeEquipotentials()" << endl;
Tile::timeTick();
for ( Tile* tile : Tile::getAllTiles() ) {
tile->getRoot( Tile::MergeEqui|Tile::MakeLeafEqui );
}
cdebug_tabw(160,-1);
//DebugSession::close();
}
string SweepLine::_getTypeName () const
{ return "Tramontana::SweepLine"; }
string SweepLine::_getString () const
{
ostringstream os;
os << "<SweepLine \"" << _tramontana->getCell()->getName() << "\">";
return os.str();
}
Record* SweepLine::_getRecord () const
{
Record* record = new Record ( _getString() );
if (record) {
record->add( getSlot( "_tramontana" , &_tramontana ) );
record->add( getSlot( "_tiles" , &_tiles ) );
}
return record;
}
} // Tramontana namespace.

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