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,
|
Running,
|
||||||
/// A specific segment has been successfully routed.
|
/// A specific segment has been successfully routed.
|
||||||
Routed(BandTermsegIndex),
|
Routed(BandTermsegIndex),
|
||||||
|
/// A specific segment was already routed and has been skipped.
|
||||||
|
Skipped(BandTermsegIndex),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Manages the autorouting process across multiple ratlines.
|
/// Manages the autorouting process across multiple ratlines.
|
||||||
|
|
@ -106,30 +108,36 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<LayoutEdit>, AutorouteContinu
|
||||||
|
|
||||||
let (source, target) = autorouter.ratline_endpoints(curr_ratline);
|
let (source, target) = autorouter.ratline_endpoints(curr_ratline);
|
||||||
|
|
||||||
let band_termseg = {
|
let ret = if let Some(band_termseg) = autorouter.board.band_between_nodes(source, target) {
|
||||||
let mut router =
|
AutorouteContinueStatus::Skipped(band_termseg[false])
|
||||||
Router::new(autorouter.board.layout_mut(), self.options.router_options);
|
} else {
|
||||||
|
let band_termseg = {
|
||||||
|
let mut router =
|
||||||
|
Router::new(autorouter.board.layout_mut(), self.options.router_options);
|
||||||
|
|
||||||
let ControlFlow::Break(band_termseg) = route.step(&mut router)? else {
|
let ControlFlow::Break(band_termseg) = route.step(&mut router)? else {
|
||||||
return Ok(ControlFlow::Continue(AutorouteContinueStatus::Running));
|
return Ok(ControlFlow::Continue(AutorouteContinueStatus::Running));
|
||||||
|
};
|
||||||
|
band_termseg
|
||||||
};
|
};
|
||||||
band_termseg
|
|
||||||
|
let band = autorouter
|
||||||
|
.board
|
||||||
|
.layout()
|
||||||
|
.drawing()
|
||||||
|
.loose_band_uid(band_termseg.into());
|
||||||
|
|
||||||
|
autorouter
|
||||||
|
.ratsnest
|
||||||
|
.assign_band_termseg_to_ratline(self.curr_ratline.unwrap(), band_termseg);
|
||||||
|
|
||||||
|
autorouter
|
||||||
|
.board
|
||||||
|
.try_set_band_between_nodes(source, target, band);
|
||||||
|
|
||||||
|
AutorouteContinueStatus::Routed(band_termseg)
|
||||||
};
|
};
|
||||||
|
|
||||||
let band = autorouter
|
|
||||||
.board
|
|
||||||
.layout()
|
|
||||||
.drawing()
|
|
||||||
.loose_band_uid(band_termseg.into());
|
|
||||||
|
|
||||||
autorouter
|
|
||||||
.ratsnest
|
|
||||||
.assign_band_termseg_to_ratline(self.curr_ratline.unwrap(), band_termseg);
|
|
||||||
|
|
||||||
autorouter
|
|
||||||
.board
|
|
||||||
.try_set_band_between_nodes(source, target, band);
|
|
||||||
|
|
||||||
if let Some(new_ratline) = self.ratlines_iter.next() {
|
if let Some(new_ratline) = self.ratlines_iter.next() {
|
||||||
let (source, target) = autorouter.ratline_endpoints(new_ratline);
|
let (source, target) = autorouter.ratline_endpoints(new_ratline);
|
||||||
let mut router =
|
let mut router =
|
||||||
|
|
@ -154,9 +162,7 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<LayoutEdit>, AutorouteContinu
|
||||||
self.curr_ratline = None;
|
self.curr_ratline = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ControlFlow::Continue(AutorouteContinueStatus::Routed(
|
Ok(ControlFlow::Continue(ret))
|
||||||
band_termseg,
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,9 +69,9 @@ impl<M: AccessMesadata> Step<Autorouter<M>, (f64, f64)> for CompareDetoursExecut
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.autoroute.step(autorouter)? {
|
match self.autoroute.step(autorouter)? {
|
||||||
ControlFlow::Continue(AutorouteContinueStatus::Running) => {
|
ControlFlow::Continue(
|
||||||
Ok(ControlFlow::Continue(()))
|
AutorouteContinueStatus::Running | AutorouteContinueStatus::Skipped(_),
|
||||||
}
|
) => Ok(ControlFlow::Continue(())),
|
||||||
ControlFlow::Continue(AutorouteContinueStatus::Routed(band_termseg)) => {
|
ControlFlow::Continue(AutorouteContinueStatus::Routed(band_termseg)) => {
|
||||||
let length = band_termseg
|
let length = band_termseg
|
||||||
.ref_(autorouter.board.layout().drawing())
|
.ref_(autorouter.board.layout().drawing())
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@ impl<M: AccessMesadata> Board<M> {
|
||||||
source: FixedDotIndex,
|
source: FixedDotIndex,
|
||||||
target: FixedDotIndex,
|
target: FixedDotIndex,
|
||||||
band: BandUid,
|
band: BandUid,
|
||||||
) {
|
) -> bool {
|
||||||
let source_pinname = self
|
let source_pinname = self
|
||||||
.node_pinname(&GenericNode::Primitive(source.into()))
|
.node_pinname(&GenericNode::Primitive(source.into()))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
@ -198,8 +198,27 @@ impl<M: AccessMesadata> Board<M> {
|
||||||
.node_pinname(&GenericNode::Primitive(target.into()))
|
.node_pinname(&GenericNode::Primitive(target.into()))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.to_string();
|
.to_string();
|
||||||
self.band_bandname
|
let bandname = BandName::from((source_pinname, target_pinname));
|
||||||
.insert(band, 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.
|
/// Finds a band between two pin names.
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use enum_dispatch::enum_dispatch;
|
||||||
use petgraph::stable_graph::NodeIndex;
|
use petgraph::stable_graph::NodeIndex;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
geometry::shape::MeasureLength,
|
geometry::{shape::MeasureLength, GetLayer},
|
||||||
graph::{GetPetgraphIndex, MakeRef},
|
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> {
|
impl<CW: Clone, Cel: Copy, R: AccessRules> MeasureLength for BandRef<'_, CW, Cel, R> {
|
||||||
fn length(&self) -> f64 {
|
fn length(&self) -> f64 {
|
||||||
match self.first_seg {
|
match self.first_seg {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue