pub enum AntennaStrategy {
DiodesAndJog,
JogOnly,
HeuristicDiodesAndJog,
}Expand description
How antenna violations are to be closed. These are NOT interchangeable, and choosing wrongly costs slew.
MEASURED on coproc_core: its max-slew stuck at exactly 126 whether the resizer margin was 30
or 45 — the lever could not reach the cause. Half the slew violators were ANTENNA_*/DIODE
pins. A diode is extra CAPACITANCE on its net, and the diode passes run AFTER the resizer, so
slew repair never sees the load they add. Diode-based antenna closure and slew closure fight.
The SAT jog-router fixes antenna with METAL instead — it bridges a segment one layer up, adding no cell and no capacitance — so on a block where slew is tight it is strictly the better tool. It only became safe to rely on alone once its free-window search was taught the layer spacing rule; before that it placed bridges flush against foreign metal (359 Magic violations on the Caravel wrapper, while TritonRoute reported 0).
Variants§
DiodesAndJog
OpenLane’s diode passes plus the jog ECO. The default: it closed gpu_simt and
fabric_soc outright, and diodes are cheap when slew has headroom.
JogOnly
Jog-router only — no diode is inserted anywhere. For a block whose slew is tight, where the diodes’ added load is the thing keeping slew from closing.
HeuristicDiodesAndJog
The PRE-ROUTE heuristic diode pass plus the jog ECO, with OpenLane’s POST-route
GRT_REPAIR_ANTENNAS off.
This exists because the other two variants are not the only choices, and treating them as
such hid the best one. OpenLane runs TWO independent diode passes — a pre-route heuristic
pass driven by HEURISTIC_ANTENNA_THRESHOLD, and the global router’s own post-route repair
— and an enum with only “both” and “neither” cannot express the third combination. Every
coproc_core experiment for two sessions moved them together:
| heuristic | GRT repair | result |
|---|---|---|
| on | on | 17,716 diodes, max-slew 126-282 |
| off | off | antenna 538-770 violating nets |
| on | off | slew 120, antenna 27, and it ROUTES |
That third row is this variant: DRC 0, LVS 0, XOR 0, routing 0, setup +32.54, hold +0.27 on a block previously recorded as a dead end needing an emitter-side rewrite. What made the difference is not the diode COUNT — that is essentially unchanged at 17,548 — but that GRT’s repair RE-ROUTES as well as inserting, and it was that re-route, not the diodes, that hit GRT-0119 congestion at every utilisation and die size tried.
It also corrected a wrong attribution: the diodes were believed to come from GRT because
they “survived” a threshold of 300. Surviving a threshold does not identify a source. With
GRT off there are still 17,548 of them, so they come from the heuristic pass — which makes
heuristic_antenna_threshold the live lever rather than an exhausted one. (Though not a
wide one: at 1500 the count drops far enough that antenna explodes back to 510 nets. It is
a cliff, not a gradient.)
Trait Implementations§
Source§impl Clone for AntennaStrategy
impl Clone for AntennaStrategy
Source§fn clone(&self) -> AntennaStrategy
fn clone(&self) -> AntennaStrategy
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for AntennaStrategy
impl Debug for AntennaStrategy
Source§impl PartialEq for AntennaStrategy
impl PartialEq for AntennaStrategy
impl Copy for AntennaStrategy
impl Eq for AntennaStrategy
impl StructuralPartialEq for AntennaStrategy
Auto Trait Implementations§
impl Freeze for AntennaStrategy
impl RefUnwindSafe for AntennaStrategy
impl Send for AntennaStrategy
impl Sync for AntennaStrategy
impl Unpin for AntennaStrategy
impl UnsafeUnpin for AntennaStrategy
impl UnwindSafe for AntennaStrategy
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.