Commit Graph

2189 Commits

Author SHA1 Message Date
Jean-Paul Chaput 7e6250d460 Use wide pads (1 P-Pitch) for METAL3 in the cumulus/Macro block wrapper 2021-03-09 10:58:49 +01:00
Jean-Paul Chaput 1205505cf2 Set all segments of external net as external components.
* New: In KatanaEngine::exportExternalnets(), for commercial tools to
    correctly regenerate the external pins from GDSII files it seems
    necessary that all segments needs to have TEXT label. So make them
    external components.
2021-03-05 00:44:15 +01:00
Jean-Paul Chaput aece850a6c Fix bugs in power supply obstacle management.
* Bug: In PowerRailsPlanes::Rail::doLayout(), in case of non-blockage but
    fixed segments (that is, power lines), expand the segment box of one
    picth to put blockage on too close neigboring tracks.
* Change: In Manipulator::avoidBlockage(), more accurate computation of
    the blocked area for pushing aside the terminal & turn of the non-pref
    segment.
2021-03-05 00:43:24 +01:00
Jean-Paul Chaput 7aa0e1321e Bug: Forgot to export Pins in GdsDriver. 2021-03-02 12:47:20 +01:00
Jean-Paul Chaput f4204c52d7 Support for dedicated power plane in Cumulus (vertical stripes).
* New: In cumulus/plugins.chip.powerplane, build the overall power
    grid when there is a dedicated supply layer. Makes vertical
    supply stripes and connect them the *horizontal* power rails
    inside the blocks (could be in *any* layer).
      Stripes positions are determined by the pins createds by
    the pads module.
* New: In cumulus/plugins.chip.chip, use the powerplane builder
    if the RoutingGauge provides a PowerSupply kind.
* New: In cumulus/plugins.block.configuration, add support for
    PowerSupply gauges.
* New: In cumulus/plugins.block.pads, if the gauge provides a
    PowerSupply, create north/south border pins for power & ground
    to direct the corona to make vertical power strips.
      This assume that we are using LibreSOC like I/O pads that
    can be connected straight from everywhere in the corona.
      First and last 2 stripes are "cap end" and narrower.
      Positions and width of the sripes are set through the
    configuration parameters:
    * "chip.supplyRailWidth"
    * "chip.supplyRailPitch"
* Change: In cumulus/plugins.block.spares, now take into account
    the "placeArea" parameter.
* Change: In cumulus/plugins.block.bigvia, now have a per metal layer
    area that *may* be expanded if it is too narrow to put at least
    one cut. Add flags to allow controlled expansion of the metal
    plates.
      As a security, now raise an exception if no cut can be created.
2021-03-02 12:19:18 +01:00
Jean-Paul Chaput 3a68cdf549 Support for "AbstractedSupply" in Katana power rails builder.
* New: In KatanaEngine::PowerRails, now stop the query on
    "AbstractedSupply" master cells. Modification coupled with
    EtesianEngine::flattenPower().
2021-03-02 12:18:45 +01:00
Jean-Paul Chaput ff89f2667d New method EtesianEngine::flattenPower() to build power abstract.
* New: In EtesianEngine::flattenPower(), this is a duplication of the
    KatanaEngine::PowerRails. The new paradigm is that when a Cell
    is placed by etesian it's AbstractedSupply flag is set and the
    creation of the abstract is taken care of at this point.
      Should provide some speedup when Katana process it.
      Note that we still need to keep PowerRails at Katana stage for
    design that are loaded already placed (no Etesian run).
* New: In EtesianEngine::setPlaceArea(), as the slice spin is imposed
    on us by Coloquinte, the bottom slice of the place area *must*
    be on a ID oriented slice, that is an even one, relative to the
    fully placed area.
* Bug: In EtesianEngine, remove the slice spin detection. The spin
    is imposed on us by Coloquinte which always place the bottom
    row in ID orientation.
      Code should be completly removed in the future, along with
    the obsolete AddFeeds (replaced by Placement).
2021-03-02 12:18:11 +01:00
Jean-Paul Chaput 63a03bf11b Add a new RoutingLayerGauge type "PowerSupply".
* New: In CRL::RoutingLayerGauge, add a new kind of gauge "PowerSupply"
    to flag a layer which is dedicated to routing power supplies.
* New: In AllianceFramework, add management of PowerSupply gauge kind.
    Exported in the Python interface.
2021-03-02 12:17:40 +01:00
Jean-Paul Chaput a6492f6edc Allow Hurricane::Query to stop on master cells with designated flags.
* New: In Query & QueryStack, add a new stop criterion "stopCellFlags"
    based on the flags of the instances master cell. The instance will
    still be processed, but not it's childs. Typically used to stop
    exploring on "AbstractedSupply" cells.
      Exported in the Python interface.
* New: In Cell::Flags, new value "AbstractedSupply" to mark Cells from
    which an abstract has been built for supplies & blockages. But *not*
    for common nets. Helps reduce the recursion through the hierarchy
    when building supply line in FlattenPower.
      Export setter/getter in the Python interface.
* New: In Instance, add a "PruneMaster" filter to stop hierarchical
    exploration on instances which master cells have at least one of
    the given flags set.
* Change: In NetExternalcomponents::isInternal(), use "const Component*"
    instead of "Component*".
* Bug: In Cell::Flags, the NoFlags must be *zero*, not *one*! And we
    can reclaim that bit for future use.
* Cleanup: In Hurricane::Cell, remove changeQuadTree() related methods.
    Fusing various Cell's QuadTree is not a viable idea.
* Cleanup: In Hurricane::Instance, remove no longer used "_flags"
    attributes.
2021-03-02 12:17:13 +01:00
Jean-Paul Chaput d00a51029e External block wrapper support added in cumulus/plugins.macro.
* New: In cumulus/plugins.macro.macro.Macro() to encapsulate foreign blocks.
    Round their size to an exact number of GCells and a guard of one GCell.
    External terminal must be on the periphery and will be made to stick out
    in the guard ring. This is sub-optimal for now but provide a workaround
    some Katana bad assumptions.
      A "perpandicular padding" is also added to terminals to limit the
    offgrid related problems. Have to optimize that in conjuction with
    Katana.
2021-02-18 00:07:03 +01:00
Jean-Paul Chaput 7bae6d8bad Partial management of offgrid fixed segments in Katana.
NOTE: To myself, one more bug uncovered in the Track segments management.
      This is really too complex, must find time to re-think and simplify
      the whole thing.

* New: In Katana::NegociateWidow::createTrackSegment(), detect offgrid
    fixed segments and insert them into tracks directly (as *wide* segment
    of two tracks).
* New: In Katana::TrackSegment::create() factory method, check for offgrid
    fixed segment and use a TrackSegmentWide (of 2 tracks) for them.
* New: In Katana::TrackSegmentWide CTOR, check if they are used in the
    context of an offgrid segment and in that case set the track span
    to two. We *do not* manage yet the case for both *wide* and *offgrid*
    segments.
* Change: In Katana::PowerRails::Rails::doLayout(), do not expand blockage
    rectangles over their real size. Add the guard only for real layers
    segments.
* Bug: In Katana::PreProcess::propagateCagedConstraints(), when looking
    for the first track index, check for out of bound value (npos).
* Bug: In Katana::Track::addOverlapCost(), before using the overlap
    segment indexes, check if we are not in a free hole (get the free
    interval from center).
* Bug: In Katana::Track::expandFreeInterval(), the interval was badly
    computed if it was included inside segments of another (same) net.
2021-02-17 23:57:45 +01:00
Jean-Paul Chaput db0ad6bf07 Partial support for offgrid METAL3 RoutingPad in Anabatic::NetBuilderHV.
* New: In Anabatic::NetBuilder::_do_1G_1M3(), RoutingPad in METAL3 from
    blocks are most likely to be offgrid in real mode, we must account
    for that case. When an offgrid METAL3 is found, a strap of METAL2
    is added, as it may be less than one pitch, it will be reduced into
    METAL3 often.
* New: In Anabatic::NetBuilder::doRp_Access(), Support for offgrid METAL2
    is added but not enabled yet. Seems to need more polishing.
2021-02-17 23:34:17 +01:00
Jean-Paul Chaput d942f3cb59 Add support for Rectilinear & Polygon in PyEntity_NEW(). 2021-02-17 23:22:31 +01:00
Jean-Paul Chaput 07b51b10c7 Allow to demote Net external component to "internal", export to Python. 2021-02-17 23:20:24 +01:00
Jean-Paul Chaput 21c269a855 Improved support for foreign block support in Cumulus.
* Change: In cumulus/plugins.block.Block.__init__(), assume that a block
    is already built only if *all* it's instances are placed. Not some
    of them.
* New: In cumulus/plugins/block/configuration, added support for a
    placeArea parameter to restrict the placement area further than the
    abutment box (see Etesian for the new feature).
* Change: In cumulus/plugins/CoreToChip, no longer adds I/O pads for
    core signals that lacks one. Only issue an error message and
    continue. More useful for debugging block support.
2021-02-01 17:01:32 +01:00
Jean-Paul Chaput 14ff6ce78a * Bug: In KatanaEngine::TrackFixedSegment CTOR, for finding the GCells
under the fixed segment, we were using the axis *of the segment*,
    but if it is very wide, this is completly off.
      Now use the axis of the *track* to get the right GCells impacteds.
2021-02-01 16:52:03 +01:00
Jean-Paul Chaput 35d54c3e74 Take account of Rectilinears in KatanaEngine::setupPowerRails()
* New: In QueryPowerRails::addToPowerRail(), now manage Rectilinears,
    *if* they are, in fact, rectangles. For LibreSOCMem block support.
2021-02-01 16:48:36 +01:00
Jean-Paul Chaput e0bae89a81 Bug in KatanaEngine::annotateGlobalGraph(), bad edge capacity computation.
* Bug: In KatanaEngine::annotateGlobalGraph(), overlapping blockages or
    fixed segments where taken into account as separate ones. This was
    making the edge capacity reservation too high. Creating false
    zero-capacity edges at some points.
      Didn't show up until now because we did not have overlaps.
2021-02-01 16:43:42 +01:00
Jean-Paul Chaput 7a7a3b9f1b GoStraight & GCell density sorting bugs.
* Bug: In Anabatic::GCell::updateDensity(), the GoStraight flag is now
    set in this function when the density of blockage is above 40%.
    (should be parametrized in the future). This is linked with the
    Katabatic TrackFixedsegment bug.
* Bug: In Anabatic::GCell::Key::Compare, the densities of the GCell
   where sorted in the *wrong* order, that is *less denser first*.
   This was making the layer assignment working on it's head.
     WTF, how did it ever work.
     Also sort on global saturation.
2021-02-01 16:36:26 +01:00
Jean-Paul Chaput 9df5f5f1b7 Allow to do the placement in a sub-area in Etesian.
* New: In EtesianEngine, add a "placedArea" attribute to restrict the
    placement area to a part only of the whole abutement box. This a
    way to exclude some area containing *big* hard block.
      The placer terribly slow down when tring to "push aside" cells
    from the area taken by the block.
      This will be also used to restrict the clock tree covered area.
      It is far from optimal but will do for now.
    NOTE: The placeArea must be expressed in the coordinate system of
          the sub-block to be placed, if one has been defined.
2021-02-01 16:24:44 +01:00
Jean-Paul Chaput 2ba7bb4fca Better Verilog/VHDL name mixing in the Blif parser.
* Change: In Model::connectSubckts(), when trying to lookup the
    Hurricane Net from it's Blif name, try first as a VHDL one then
    after a Verilog to VHDL translation. Especially useful for bits
    of vectorized names ("signal[X]" --> "signal(X)").
2021-02-01 16:18:25 +01:00
Jean-Paul Chaput 48357c37a9 Added DbU::toCeil() & DbU::toFloor() for rounding on a dedicated step. 2021-02-01 16:13:16 +01:00
Jean-Paul Chaput 95d3ca5344 In CRL::GdsDriver, filter out "CORIOLBLK*" layers (gross hack). 2021-01-27 12:14:29 +01:00
Jean-Paul Chaput a5fbe94705 In cumulus/plugins.block.Block, set the right cell in the editor. 2021-01-27 11:38:27 +01:00
Jean-Paul Chaput 5649a3b984 Second version of the antenna effect protection.
* Change: In EtesianEngine::globalPlace(), disable the call to
    antennaProtect(). First reason is that, after all, Coloquinte
    do not handle so well the resizing of the cells "on the fly",
    it overspill the boundaries sometimes. Second reason is that
    as we cannot know the routing tree at this stage, we will not
    be able to choose the correct points for diode insertions.
    We only have a Steiner tree wich may not be the same as a
    density driven Dijkstra.
* Change: In Etesian::Area, the Occurrence to the Instances where
    not stored in a uniform way. Some where starting from the
    placed sub-block, some where starting from the top level
    (corona), making their processing (and remembering it) tricky.
    Now, they are all expressed from the top cell (corona).
    The coordinate system is now systematically the one of the
    top block (*not* the block).
      Create various overloaded functions EtesianEngine::toCell()
    and EtesianEngine::toBlock() to ease Occurrence & coordinate
    translations.
* New: In Etesian::Slice::createDiodeUnder(), add a X position hint.
    Search is done by going through the whole slice range and
    minimizing the distance to the hint. If it starts to be too
    slow, we may optimize.
* Bug: In EtesianEngine::toColoquinte(), the placement of the top
    level external pins was not taken into account (this at last
    explain their weird positioning).
* New: AnabaticEngine::antennaProtect(), new algorithm to avoid
    antenna effect. This step must be done *after* global routing
    and *before* detailed routing. This way we have access to the
    real routing and can mend it (along with the netlist) to
    insert diodes at the rigth points.
      From the global routing we build clusters (DiodeCluster) of
    RoutingPads connected through a set of wire whose total length
    is below the antenna effect threshold. Long wires connecting the
    clusters are also tagged because we need to put a diode between
    them and the first RoutingPad of the cluster. This is to avoid
    a long METAL2 wire connecting to the RoutingPad before the diode is
    connected through METAL3 (in case of misalignment).
      This protection is not even enough. For *very long* wires, we
    needs to put *more* than one diode (this is to be implemented).
2021-01-27 11:38:00 +01:00
Jean-Paul Chaput b926e02d92 Fix typo in FindETESIAN.cmake in include path searching. 2021-01-27 10:59:58 +01:00
Jean-Paul Chaput 5f6302de44 Added HasAntenna flag to NetRoutingProperty. 2021-01-27 10:58:03 +01:00
Jean-Paul Chaput 88081fae12 Added Path::contains(Instance*) method. 2021-01-27 10:57:35 +01:00
Jean-Paul Chaput 087ef239c2 Add support for Antenna/Diode insertion in Etesian.
* New: In Etesian::Configuration add new parameters for antenna
    effect management:
    * "etesian.diodeName"    : the name of the diode cell.
    * "etesian.antennaMaxwl" : maximum length above which antenna
         effect can occur. Must be the maximum for all the normal
	 routing layers.
    * "etesian.antennaInsertThreshold" : during the placement steps,
         threshold for linear disruption at which we will look for
	 the RSMT and insert diodes.
* New: In EtesianEngine::antennaProtect(), at a designated point
    in the placement iteratives step, when the spreading starts to
    be significant enough estimate the RSMT length and add a diode
    if need be. The diode will be put side by side with the driver
    cell. This is done by enlarging the driver cell of the diode
    width.
* New: In EtesianEngine::_updatePlacement(), in the final stage,
    modify the netlist to connect the diode. The diode will be
    put on the side of the cell closest to the driver. This may
    alow to make the connexion directly in METAL1 in the future.
* Change: In etesian/Placement.cpp, make the whole placement
    structure a persistent attribute of the EtesianEngine so
    it can be used afterwards.
      Add a post-placement diode insertion feature. Finally
    unused as they are added on the fly during placement.
      In the Area, add data about the diode tie in the TieLut.
* Change: Add EtesianEnginea::clearColoquinte(), to keep the
    post-placement structure while purging the Coloquinte one.
* Change: In cumulus/plugins.block.block, keep the Etesian engine
    until the whole P&R is done, so we potentially can exploit
    the post-placement datas.
* Bug: In cumulus/plugins.chip.power.GoCb(), for the METAL1 power
    and ground wires coming from the standard cell, it was assumed
    they where made of Horizontal segments, this is not the case
    in FlexLib... So force to consider the plane as Horizontal when
    we are processing that plane.
      Better solution should be to use Horizontals...
2021-01-13 19:36:20 +01:00
Jean-Paul Chaput 78cbb662e6 Add updators to modify cell sizes on the fly in Coloquinte. 2021-01-13 19:10:31 +01:00
Jean-Paul Chaput 79e47d1ef2 Add net driver detection in Dijkstra (just a check for now). 2021-01-13 19:08:00 +01:00
Jean-Paul Chaput 2b0a2c88b7 More informative error message in Occurrence constructor. 2021-01-13 19:05:20 +01:00
Jean-Paul Chaput 250ef29674 Fix the smart truncate display in DbU::getValueString(). 2021-01-13 19:04:13 +01:00
Jean-Paul Chaput 3b5a0f5bd2 Again, bug fix in the Inspector support, on getSlot<> template.
The policy about how to create slots was not completly clear.
Now, only add *pointers* or *references* to class attributes,
never do a "copy by value". Reflect that change in SlotTemplate<>
various partial specializations.
  Hammer in your head that in C++ functions templates do not allow
for partial specialization. So write only *one* template for
::getSlot<>() (refdefinition simply got ignoreds, at least with gcc).

* Bug: In Slot, only one template for getSlot<> (see above).
    Adjust SlotTemplates<> to provides partial specialization only for:
    * "const Data&".
    * "Data*".
    * "const Data*".
    * "Data* const"
    * "Record*".
* Bug: In Instance::_getRecord(), suppress slot based on transient
    values "XCenter" & "YCenter".
* Bug: In CRL::ToolEngine::_getRecord(), suppress slot "Name" based
    on a transient value.
* Change: In ::getRecord(std::list<Elementt>*) (and variant), pass
    all elements to ::getSlot() as (const Element*).
2021-01-08 12:43:47 +01:00
Jean-Paul Chaput 678631d44f GdsDriver now export correctly I/O pin (for FlexLib).
* In CRL::GdsStream::operator<<(Cell*), when encountering an *external*
    component, try to find a ".pin" layer associated (if not already
    in it). Then drive the BOUNDARY & TEXT in it. This way, Cadence/
    Calibre seems to be able to recognize them as Pin.
2020-12-27 13:49:05 +01:00
Jean-Paul Chaput 405ca8d11b Improved support for LibreSOCIO (real), use IOPadIn & IoPadOut. 2020-12-27 12:46:04 +01:00
Jean-Paul Chaput 57432bbb50 * Bug: In cumulus/plugins.chip.configuration, check that the core
height is a multiple of sliceHeight. Otherwise, in some situations,
    fixed cell may peek out of the placement area, triggering
    Coloquinte assert (which says that the top of the cell is *above*
    the top row).
2020-12-27 12:43:26 +01:00
Jean-Paul Chaput e3803d28d7 Simple HFNS (#4), break the net, regardless of placement.
* New: In cumulus/plugins.block.hfns4.py, perform simple HFNS by breaking
    the net into sub-nets of at most 10 sinks (hard-coded for now).
      As this method is called *after* the netlist as been virtually
    flattened, we have to create the RoutingPad at the top level
    ourselves. Sub-nets are created at the Cell top-level (same
    approach as for clock synthesis, because there is no smart way
    to guess where they should be).
* New: In cumulus/plugins.block.block.py, perform HFNS (#4) *before*
    doing placement. To see the real sink count on each net, we must
    perform the virtual net flattening first (Cell::flattenNets()).
* Change: In cumulus/plugins.block.configuration, allow the creation
    of spare buffer in any cell (instead of only "self.cellPnR").
* Change: In cumulus/plugins.block.spares.Spares.raddTransNet(),
    Check if intermediate masterNet exists in Cells before trying
    to blindly re-create it.
2020-12-27 12:38:01 +01:00
Jean-Paul Chaput b0ae6be652 Export Cell::flattenNets() & revlevant Cell flags. 2020-12-27 12:21:14 +01:00
Jean-Paul Chaput 49ffe1e1ba Added management of tie *inside* cells.
* New: In Etesian/Placement::Area, added support to take into account
    bulk inside cells. Currently only hard-wired configuration for
    FlexLib is available. Should add a front-end to analyse the
    cells of the library to lookup for bulk ties in the future.
2020-12-23 11:22:12 +01:00
Jean-Paul Chaput 70d32528cd Added new utility conversions DbU::toMicrons() & DbU::fromMicrons(). 2020-12-23 11:16:38 +01:00
Jean-Paul Chaput ead11f8b93 Added support for external connectors in GDS parser/driver.
* New: In CRL::GdsDriver, create TEXT record under each external
    Net component. Seems to be the aknoweledged way to signal
    external pins.
* New: In CRL::GdsParser, read TEXT record and create Net and
    external components that are in the same layer and at the
    same position.
2020-12-19 23:04:50 +01:00
Jean-Paul Chaput 8fdaf47f3d Second attempt at tie insertion. Works, but disturb placement.
* New: In Etesian::Configuration, added "etesian.lacthUpDistance" to
    control tie cells insertion (for polarization contacts).
* New: Etesian/Placement as a complete replacement for FeedCells.
    Rebuild the complete slicing structure of the placement to
    serve as a building block for post-placement changes under
    Coriolis. Currently used to regularly insert body ties.
      This is not optimal as we displace cells in each slice in
    a non-coordinated manner.
* New: In cumulus/plugins/block.configuration.FeedsConf, register
    the "etesian.latchUpDistance" parameter. Provides the tie width.
* New: In cumulus/plugins.block.spares, add ties around the buffer
    pool block and "cap ties" at both end of each slice.
2020-12-17 10:22:43 +01:00
Jean-Paul Chaput 2e50ff4724 Compute and display feed insertion statistic per row. 2020-12-09 00:15:54 +01:00
Jean-Paul Chaput 172bdd9240 First attempt at inserting bulks, fail.
* New: In cumulus/plugins.block.spares, added creation of vertical
    stacks of feed cells, for their N/P tie contacts, to ensure
    correct bulk polarization. Fail, because the placer cannot
    cope with such massive obstacles, the vertical columns are
    too close to manage.
* New: In cumulus/plugins.block.configuration, add support to
    FeedsConf so lone instances can be created (for the first
    bulk trial).
2020-12-09 00:15:30 +01:00
Jean-Paul Chaput 945b9a24fa Fix I/O Pad ring 45 degree corners where off the foundry grid.
* New: In CRL/hepers, new function onFGrid() to ensure a DbU is on the
    foundry grid. Rounding is always done to the inferior integer.
* New: In CRL/GdsDriver, added a set of isOnGrid() functions to check
    that all coordinates of various objects are on the foundry grid.
      Use isOnGrid() in most objects processed in
    GdsStream::operator<<(Cell*).
* Bug: In cumulus/plugins.chip.pads.Corner, correctly round the
    coordinates of the 45 degree segments so they are still on the
    foundry grid.
2020-12-09 00:05:52 +01:00
Jean-Paul Chaput 973cc0f3c3 In LibreSOCIO, allow to choose between complete/abstract layout.
* New: In cumulus/plugins.core2chip.libresocio.CoreToChip, use new
    configuration variable "chip.useAbstractpads" to select between the
    abstract version (GPIO, VDD, ...) and the full version (IOPadInOut,
    IOPadVdd, ...) layout.
2020-12-07 16:41:09 +01:00
Jean-Paul Chaput 564714d73e Set a maximum wire with for LibreSOCIO I/O pads to corona wires.
* New: In cumulus/plugins.chip.pads.Corona._createCorewire(), add an
    hard-coded limitation for LibreSOCIO I/O pad to corona wires to
    always be below the maximal threshold.
2020-12-07 16:39:36 +01:00
Jean-Paul Chaput 51028980c9 Modify the chain of "save()" calls in chip/block to pass on flags.
* Change: In cumulus/plugins.block.configuration.BlockConf.save(),
             cumulus/plugins.block.Block.save(),
             cumulus/plugins.chip.Chip.save(),
             cumulus/plugins.core2chip.core2chip.CoreToChip.buildChip(),
    Add a "flags" parameter to control the way logical views (aka "vst")
    are saved. Mainly allowing to pass on the VstUseConcat option in
    order for Alliance tools to be able to read them back (lvx, asimut).
* Change: In cumulus/plugins.core2chip.core2chip.CoreToChip.buildChip(),
    don't stop at the first I/O pad signal missing on the core, but
    display all the missing ones (LKCL proposal).
2020-12-05 11:59:48 +01:00
Jean-Paul Chaput 1411739c0b Make block/chip plugin use the common rsave plugin.
* In cumulus/block.configuration, the rsave method was buggy. It did stop
    it did not save "terminal" master cells (i.e. a cell without instance)
    instead of "netlistTerminal" (explicitely flagged for standard cells).
      The result was that some "empty netlist" in the complete "ls180"
    from LibreSOC went missing. Causing cougar to complain.
2020-12-04 12:20:57 +01:00