In Anabatic::AntennaProtect, when we cannot insert enough diodes
under a wire cluster. Which makes it likely very long and over an
area where diodes cannot be inserted (chip border close to I/O pads
or over a macro-block). Request extra diode insertion on it's
connecting RoutingPad clusters.
* New: In Anabatic::DiodeCluster, add a "forced diode" counter for
extra diodes inertions. Only used in the DiodeRps derived class.
* New: In Anabatic::DiodeCluster, add support for a cluster to know
it's neighbors. Stored as indexes of the table being built in
Anabatic::antennaProtect(Net*).
* New: In Anabatic::antennaProtect(Net*), when builing the WireCluster,
also find it's neigbors. Store the index of the cluster a segment
belongs to in clusterSegments.
* Change: In cumulus/plugins.Block.getLeafUnder(): formerly, we where
using the cut-lines (x/y) to locate which leaf a point is under.
But in case of incomplete tree, it is difficult to manage.
Now we chosse the leaf according to the distance to the center
of the leaf area. Choose the shorter, of course.
This solve the H-Tree DFF bad assignment around the PLL (top
right corner) in LS180.
* Bug: In Cumulus/plugins.block.Block, re-order Etesian tool creation
and virtual net flattening. Must investigate later why it is so
sensitive to at least warn/stop cleanly.
* Bug: In Katana::GlobalNetTable::getRootNet(), look for all fixed nets,
not only supplies and clocks. There may be some as now H-Trees are
not limited to clocks.
Should solve ao68000 short circuit cases.
* Bug: In Cumulus/plugins.chip.powerplane.Builder._connectHTree(), is was
previously assumed that a net manged by a H-Tree was always coming from
the outside (i.e. a clock or a reset signal).
It is no longer the case, for example with the PLL internally generated
clock.
So prune internal signals in this method.
The H-Tree support is now allowed for any net, not only the clocks and
not only top-level nets. This allow to better management of the LS180
internal clock signal.
* New: In Cell::flattenNets(Instance*,set<string>,uint64_t) new overload
of the function to allow the user to select nets that will *not*
be flattened. This makes the NoClockFlatten flag effectively obsolete,
we keep it for backward compatibility.
The net names can be of non top level ones. In that case, they must
use the name an HyperNet will get (the Occurrence name). For example:
"instance1.instance2.deep_net_name".
* New: In PyCell, update the wrapper for the new parameter of flattenNets(),
new utility function pyListToStringSet() to translate a Python list into
a C++ set of names.
* New: In EtesianEngine, add support for a list of nets to be excluded
from the flattening procedure. Those excluded nets will also be
excludeds from the Coloquinte nets *and* HFNS synthesis, as they
are likely to be manageds by a H-Tree.
* Change: In AnabaticEngine::_loadGrByNet(), now also skip nets that are
flagged as manually detailed route.
* New: In AnabaticEngine::antennaProtect(), do not try to insert diodes
on nets that are already fixed or detaled route. This replace the
clock exclusion.
* New: In cumulus/plugins.{block,htree,chip}, replace the concept
of clock-tree by the more generic H-Tree. That is, we can ask the P&R
to create H-Tree on any net of the design, not only the ones matcheds
as clock. The net does not even need to be top-level.
This is to manage the PLL internal clock generated by the PLL in
the LS180 chip.
Start to change all reference to "clock" into "H-Tree".
* Bug: In cumulus/plugins.chip.powerplanes.Builder._connectHTree(),
there was an inversion of the H & V routing gauges to compute the
track into which put the H-Tree center to corona edge wiring.
This was causing tracks to be used twice, seen in the ao68000 test
bench.
* New: In CRL::GdsStream::xyToPath(), now manage BGNEXTN & ENDEXTN for
PATHTYPE 4.
The begin/end Contact are created to use exactly the area of the
extension. Otherwise there were overspill when the size of the
extension is greater than the width of the path. Also need to do
a sligth shift if the extension is an odd number of foundry grid.
This fix the offgrid problems.
* Bug: In cumulus/plugins.macro.Macro.__init__(), stick out the rigth number
of pitches on North & East sides (never tested before).
* New: In cumulus/plugins.macro.Macro.__init__(), manage layer change
if the terminal is not in the preferred routing direction. Use BigVia
and put at least two cuts.
* New: In Anabatic::DiodeWire, use "antennaDiodeMaxWL" to compute the number
of diodes to insert in a wire only cluster. Use boxes instead of segments
to define the area as segments can be splitted by the diodes inserteds
at the DiodeRps stage.
* New: In DiodeWire::createDiodes(), specific diode insertion method.
Try to instert first in long horizontal wires.
Split "antennaMaxWL" into :
* "etesian.antennaGateMaxWL" : max length *without* any diode.
* "etesian.antennaDiodeMaxWL" : max length that *one* diode can support.
When a long *horizontal* wire connect to a cluster, an antenna effect
may be created *before* the METAL3 is deposited, if the cluster's diode
is not *directly* connected to the gate through *only* METAL2. So, we
add a "forced halo" where the long horizontal connecting wires will be
broken by a diode *near* the gate. This problem do not occur for long
connecting METAL3, as the diode will be connected by then. Note that
we are hard-coding the gauge routing direction in the algorithm.
With that modification, only one antenna effect remains in LibreSOC
LS180. May be corrected by post-treatement.
* New: In Anabatic::DiodeCluster::mergeForcedhalo() add specific secondary
areas where diode must be insterted in addition to the one of the
RroutingPad cluster. To "isolate" the cluster from long horizontal
wires.
* Bug: In cumulus/plugins.chip.Chip.save(), now completely delegate the
saving procedure to the base class (i.e. Block.save() which is
BlockConf.save()).
* Bug/Change: In cumulus/plugins.block.configuration.BlockConf.save(),
Now manage all the configutation, whether it is a simple block or
a whole chip.
In the case of a whole chip we must force the saving on both
chip and corona as the later, being P&R will be seen as a terminal
block and not recursively saved.
Protecting clusters of sinks is not enough. There can be very long
wires that far exceed the protection capacity of one diode. Instead
of putting a bunch of diodes near the sinks, we choose to put them
regularly along the interconncting wires.
With this approach we are down to 7 antenna violations on LibreSOC
LS180 test chip.
This will get less good results on arlet6502 & ao6800 because of the
core being a long way from the I/O pads. Should create jumpers on thoses,
but it is for later.
* Change: In Track::addOverlapCost(), in some configuration, we can
have two overlapping short segments that can *both* be realigned.
But they prevent that because we account their shared length on
the track.
So now, in realign mode only, do not account same-net shared
length if the segment length is less than *two perpandicular pitches*.
This helps the antenna protection by making the diode connected
directly to METAL2 long stripes, and not keeping them isolated.
* In cumulus/plugins.block.Block.{place,doPnr}(), reorder the
feed insertion and spare buffer deletion call. Formerly, we
were :
1. Creating spare buffersa (Python).
2. Placing (C++)
3. Adding feeds (EtesianEngine::toHurricane() call) (C++).
4. Removing unused spare buffers (Python).
So, step 4 was *not* informing the C++ placement data-structure
created at step 3 of the change. Resulting in occurrences using
deleted Entities (Instance).
Now we swap step 3. and 4. so toHurricane() is called *after*
any Python managed change is done.
Ideally, what we should implement is a way for Python to inform
the C++ data-structure. No real problem here, but time...
* In Etesian::Slice::createDiodeUnder(), delete the Instance *after*
removing the tile referring it. This was working, unless we
active the debug mode which tries to print the Tile's instance.
* In EtesianEngine::place(), no longer call toHurricane() at the
end of the placement. Must now be done as a separate step.
Exported to Python interface.
This fix is related to the spare buffer removal memory
corruption
* Change: In Katana::Track::addOverlapCost(), if an overlaping segment
is owned by the net *and* is the one we want to insert, do not take
it into account in the shared length.
This case never occured before we introduced the "realign" stage,
as a to be inserted segment, was, by definition, not already
inserted in a track. But in the realign stage, it is. So we should
not account it when computing the insertion cost in the track it
is already in. This was preventing short segments (less than a
pitch) to be correctly re-aligned.
And, as a side effect, preventing the antenna/diodes to work as
intended (diode connected at METAL3 layer while the antenna occur
at METAL2 layer).
* Change: In cumulus/plugins.block.configuration.Configuration.save()
and cumulus/plugins.chip.Chip.save(), according to the kind of
routing gauge we are using (symbolic or real), either recursively
save all the layouts (AP symbolic files) or only the top-level
GDSII (which embed all the hierarchy) one.
First part of the antenna effect protection : diode insertions.
Anabatic::antennaProtect(Net*) and it's supporting infrastructure
has been rewritten & simplificated. Must be used in conjuction
with the "Flexlib" bloat model of Etesian. A cursory description
of the algorithm has been added in the source file.
* New: GCell::hasNet() to tell if net is going through a GCell,
either as a straigth wire or has a local GContact (turn,
branch, terminal).
* New: Etesian::BloatFlexib class (tagged "Flexlib") suited for
flexlib uses. It is derived from "nsxlib".
To have enough space to insert all the wanted diodes, we
enlarge "mx2_x2" & "mx3_x2" of resp. 1 and 2 pitches.
This is an empiric finding, Yosys seems very fond of thoses
gates and we often see them underneath area where no space
was available to put a diode... May need some more fine grained
analysis.
* Bug: In cumulus/plugins.chip.pads, we were connecting the ground and
power supplies to all the horizontal wires in the corona ring.
But, when there are more than one and especially at the outer
border of the pad, the vertical connecting wire will create
various shorts over the pad.
Now we connect only to the innermost horizontal wire only.
Had to chech if the core side of the pad is north or south.
* New: In CRL::PyCatalog, add the second parameter "add" to getState()
so we can request the creation of the state if needed.
* New: In CRL::PyCatalogState, export setCell() and setInMemory() methods.
* Bug: In CRL::Subckt::createModel(), when a cell has a State entry in
the catalog, also check that it really has a Cell loaded in memory.
If not, throw an exception (and do not crash).
* Change: In SegmentFsm::_slackenLocal(), in the Minimize state, when
the segment is fully blocked *and* has *lot* of candidate tracks,
that means that it is up against a *massive* blockage (i.e. a macro
block). In that case, try to move up (to go *over* it).
Previous behavior was to go straight to Inimplemented state.
* Change: In SegmentFsm::_slackenGlobal(), manage fully blocked
global segments. But finally, this configuration didn't arise.
* Change: In Manipulator::moveUp(), restore the management of the
AllowLocalMoveUp flag, to be able to move up local segments
(needed by SegmentFsm::_slackenLocal()).