mirror of https://codeberg.org/topola/topola.git
fix(autorouter/autoroute): Only route each pin-pin connection at most once
Fixes #219.
This commit is contained in:
parent
8647df026d
commit
56cc737b82
|
|
@ -31,6 +31,8 @@ pub enum AutorouteContinueStatus {
|
|||
Running,
|
||||
/// A specific segment has been successfully routed.
|
||||
Routed(BandTermsegIndex),
|
||||
/// A specific segment was already routed and has been skipped.
|
||||
Skipped(BandTermsegIndex),
|
||||
}
|
||||
|
||||
/// Manages the autorouting process across multiple ratlines.
|
||||
|
|
@ -106,6 +108,9 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<LayoutEdit>, AutorouteContinu
|
|||
|
||||
let (source, target) = autorouter.ratline_endpoints(curr_ratline);
|
||||
|
||||
let ret = if let Some(band_termseg) = autorouter.board.band_between_nodes(source, target) {
|
||||
AutorouteContinueStatus::Skipped(band_termseg[false])
|
||||
} else {
|
||||
let band_termseg = {
|
||||
let mut router =
|
||||
Router::new(autorouter.board.layout_mut(), self.options.router_options);
|
||||
|
|
@ -130,6 +135,9 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<LayoutEdit>, AutorouteContinu
|
|||
.board
|
||||
.try_set_band_between_nodes(source, target, band);
|
||||
|
||||
AutorouteContinueStatus::Routed(band_termseg)
|
||||
};
|
||||
|
||||
if let Some(new_ratline) = self.ratlines_iter.next() {
|
||||
let (source, target) = autorouter.ratline_endpoints(new_ratline);
|
||||
let mut router =
|
||||
|
|
@ -154,9 +162,7 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<LayoutEdit>, AutorouteContinu
|
|||
self.curr_ratline = None;
|
||||
}
|
||||
|
||||
Ok(ControlFlow::Continue(AutorouteContinueStatus::Routed(
|
||||
band_termseg,
|
||||
)))
|
||||
Ok(ControlFlow::Continue(ret))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -69,9 +69,9 @@ impl<M: AccessMesadata> Step<Autorouter<M>, (f64, f64)> for CompareDetoursExecut
|
|||
}
|
||||
|
||||
match self.autoroute.step(autorouter)? {
|
||||
ControlFlow::Continue(AutorouteContinueStatus::Running) => {
|
||||
Ok(ControlFlow::Continue(()))
|
||||
}
|
||||
ControlFlow::Continue(
|
||||
AutorouteContinueStatus::Running | AutorouteContinueStatus::Skipped(_),
|
||||
) => Ok(ControlFlow::Continue(())),
|
||||
ControlFlow::Continue(AutorouteContinueStatus::Routed(band_termseg)) => {
|
||||
let length = band_termseg
|
||||
.ref_(autorouter.board.layout().drawing())
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ impl<M: AccessMesadata> Board<M> {
|
|||
source: FixedDotIndex,
|
||||
target: FixedDotIndex,
|
||||
band: BandUid,
|
||||
) {
|
||||
) -> bool {
|
||||
let source_pinname = self
|
||||
.node_pinname(&GenericNode::Primitive(source.into()))
|
||||
.unwrap()
|
||||
|
|
@ -198,8 +198,27 @@ impl<M: AccessMesadata> Board<M> {
|
|||
.node_pinname(&GenericNode::Primitive(target.into()))
|
||||
.unwrap()
|
||||
.to_string();
|
||||
self.band_bandname
|
||||
.insert(band, BandName::from((source_pinname, target_pinname)));
|
||||
let bandname = BandName::from((source_pinname, target_pinname));
|
||||
if self.band_bandname.get_by_right(&bandname).is_some() {
|
||||
false
|
||||
} else {
|
||||
self.band_bandname.insert(band, bandname);
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
pub fn band_between_nodes(
|
||||
&self,
|
||||
source: FixedDotIndex,
|
||||
target: FixedDotIndex,
|
||||
) -> Option<BandUid> {
|
||||
let source_pinname = self
|
||||
.node_pinname(&GenericNode::Primitive(source.into()))
|
||||
.unwrap();
|
||||
let target_pinname = self
|
||||
.node_pinname(&GenericNode::Primitive(target.into()))
|
||||
.unwrap();
|
||||
self.band_between_pins(source_pinname, target_pinname)
|
||||
}
|
||||
|
||||
/// Finds a band between two pin names.
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use enum_dispatch::enum_dispatch;
|
|||
use petgraph::stable_graph::NodeIndex;
|
||||
|
||||
use crate::{
|
||||
geometry::shape::MeasureLength,
|
||||
geometry::{shape::MeasureLength, GetLayer},
|
||||
graph::{GetPetgraphIndex, MakeRef},
|
||||
};
|
||||
|
||||
|
|
@ -67,6 +67,16 @@ impl<'a, CW: 'a, Cel: 'a, R: 'a> BandRef<'a, CW, Cel, R> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<CW: Clone, Cel: Copy, R: AccessRules> GetLayer for BandRef<'_, CW, Cel, R> {
|
||||
fn layer(&self) -> usize {
|
||||
match self.first_seg {
|
||||
BandTermsegIndex::Straight(seg) => seg.primitive(self.drawing),
|
||||
BandTermsegIndex::Bended(seg) => seg.primitive(self.drawing),
|
||||
}
|
||||
.layer()
|
||||
}
|
||||
}
|
||||
|
||||
impl<CW: Clone, Cel: Copy, R: AccessRules> MeasureLength for BandRef<'_, CW, Cel, R> {
|
||||
fn length(&self) -> f64 {
|
||||
match self.first_seg {
|
||||
|
|
|
|||
Loading…
Reference in New Issue