refactor(autorouter/anterouter): Represent terminating schemes preservably across reconfigurations

This commit is contained in:
Mikolaj Wielgus 2025-10-26 22:04:30 +01:00
parent bd32885964
commit 8384c15a38
3 changed files with 71 additions and 103 deletions

View File

@ -35,16 +35,10 @@ pub struct AnterouterOptions {
pub fanout_clearance: f64, pub fanout_clearance: f64,
} }
#[derive(Clone, Copy, Debug)]
pub enum TerminatingScheme {
ExistingFixedDot(FixedDotIndex),
Fanout,
}
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct AnterouterPlan { pub struct AnterouterPlan {
pub layer_map: BTreeMap<RatlineUid, usize>, pub layer_map: BTreeMap<RatlineUid, usize>,
pub ratline_terminating_schemes: BTreeMap<(RatlineUid, FixedDotIndex), TerminatingScheme>, pub static_terminating_dot_map: BTreeMap<(RatlineUid, FixedDotIndex, usize), FixedDotIndex>,
} }
#[derive(Getters)] #[derive(Getters)]
@ -70,48 +64,42 @@ impl Anterouter {
let endpoint_indices = ratline.ref_(autorouter).endpoint_indices(); let endpoint_indices = ratline.ref_(autorouter).endpoint_indices();
let endpoint_dots = ratline.ref_(autorouter).endpoint_dots(); let endpoint_dots = ratline.ref_(autorouter).endpoint_dots();
if let Some(terminating_scheme) = self if let Some(terminating_dot) =
.plan self.plan
.ratline_terminating_schemes .static_terminating_dot_map
.get(&(*ratline, endpoint_dots.0)) .get(&(*ratline, endpoint_dots.0, *layer))
{ {
match terminating_scheme { terminating_dot_map.insert((*ratline, endpoint_dots.0), *terminating_dot);
TerminatingScheme::ExistingFixedDot(terminating_dot) => { } else {
terminating_dot_map.insert((*ratline, endpoint_dots.0), *terminating_dot); self.anteroute_fanout(
} autorouter,
TerminatingScheme::Fanout => self.anteroute_fanout( recorder,
autorouter, endpoint_indices.0,
recorder, *ratline,
endpoint_indices.0, endpoint_dots.0,
*ratline, *layer,
endpoint_dots.0, options,
*layer, &mut terminating_dot_map,
options, );
&mut terminating_dot_map,
),
}
} }
if let Some(terminating_scheme) = self if let Some(terminating_dot) =
.plan self.plan
.ratline_terminating_schemes .static_terminating_dot_map
.get(&(*ratline, endpoint_dots.1)) .get(&(*ratline, endpoint_dots.1, *layer))
{ {
match terminating_scheme { terminating_dot_map.insert((*ratline, endpoint_dots.1), *terminating_dot);
TerminatingScheme::ExistingFixedDot(terminating_dot) => { } else {
terminating_dot_map.insert((*ratline, endpoint_dots.1), *terminating_dot); self.anteroute_fanout(
} autorouter,
TerminatingScheme::Fanout => self.anteroute_fanout( recorder,
autorouter, endpoint_indices.1,
recorder, *ratline,
endpoint_indices.1, endpoint_dots.1,
*ratline, *layer,
endpoint_dots.1, options,
*layer, &mut terminating_dot_map,
options, );
&mut terminating_dot_map,
),
}
} }
} }

View File

@ -8,11 +8,7 @@ use derive_getters::Getters;
use specctra_core::mesadata::AccessMesadata; use specctra_core::mesadata::AccessMesadata;
use crate::{ use crate::{
autorouter::{ autorouter::{anterouter::AnterouterPlan, ratline::RatlineUid, Autorouter},
anterouter::{AnterouterPlan, TerminatingScheme},
ratline::RatlineUid,
Autorouter,
},
drawing::{ drawing::{
dot::FixedDotIndex, dot::FixedDotIndex,
graph::{MakePrimitiveRef, PrimitiveIndex}, graph::{MakePrimitiveRef, PrimitiveIndex},
@ -55,74 +51,58 @@ impl MultilayerPreconfigurer {
) -> Self { ) -> Self {
let mut plan = AnterouterPlan { let mut plan = AnterouterPlan {
layer_map, layer_map,
ratline_terminating_schemes: BTreeMap::new(), static_terminating_dot_map: BTreeMap::new(),
}; };
for ratline in ratlines { for ratline in ratlines {
let layer = plan.layer_map[ratline]; for layer in 0..autorouter.board().layout().drawing().layer_count() {
if let Some(static_terminating_dot) = Self::find_static_terminating_dot(
autorouter,
ratline.ref_(autorouter).endpoint_dots().0,
layer,
) {
plan.static_terminating_dot_map.insert(
(*ratline, ratline.ref_(autorouter).endpoint_dots().0, layer),
static_terminating_dot,
);
}
if let Some(terminating_scheme) = Self::determine_terminating_scheme( if let Some(static_terminating_dot) = Self::find_static_terminating_dot(
autorouter, autorouter,
ratline.ref_(autorouter).endpoint_dots().0, ratline.ref_(autorouter).endpoint_dots().1,
layer, layer,
) { ) {
plan.ratline_terminating_schemes.insert( plan.static_terminating_dot_map.insert(
(*ratline, ratline.ref_(autorouter).endpoint_dots().0), (*ratline, ratline.ref_(autorouter).endpoint_dots().1, layer),
terminating_scheme, static_terminating_dot,
); );
} }
if let Some(terminating_scheme) = Self::determine_terminating_scheme(
autorouter,
ratline.ref_(autorouter).endpoint_dots().1,
layer,
) {
plan.ratline_terminating_schemes.insert(
(*ratline, ratline.ref_(autorouter).endpoint_dots().1),
terminating_scheme,
);
} }
} }
Self { plan } Self { plan }
} }
fn determine_terminating_scheme( fn find_static_terminating_dot(
autorouter: &Autorouter<impl AccessMesadata>, autorouter: &Autorouter<impl AccessMesadata>,
ratline_endpoint_dot: FixedDotIndex, ratline_endpoint_dot: FixedDotIndex,
layer: usize, layer: usize,
) -> Option<TerminatingScheme> { ) -> Option<FixedDotIndex> {
if layer
== ratline_endpoint_dot
.primitive_ref(autorouter.board().layout().drawing())
.layer()
{
return None;
}
let pinname = autorouter let pinname = autorouter
.board() .board()
.node_pinname(&GenericNode::Primitive(ratline_endpoint_dot.into())) .node_pinname(&GenericNode::Primitive(ratline_endpoint_dot.into()))
.unwrap(); .unwrap();
Some( autorouter.board().pinname_nodes(pinname).find_map(|node| {
autorouter if let GenericNode::Primitive(PrimitiveIndex::FixedDot(dot)) = node {
.board() (layer
.pinname_nodes(pinname) == dot
.find_map(|node| { .primitive_ref(autorouter.board().layout().drawing())
if let GenericNode::Primitive(PrimitiveIndex::FixedDot(dot)) = node { .layer())
(layer .then_some(dot)
== dot } else {
.primitive_ref(autorouter.board().layout().drawing()) None
.layer()) }
.then_some(dot) })
} else {
None
}
})
.map_or(TerminatingScheme::Fanout, |dot| {
TerminatingScheme::ExistingFixedDot(dot)
}),
)
} }
} }

View File

@ -44,9 +44,9 @@ impl MultilayerAutorouteReconfigurator {
input: MultilayerAutoroutePreconfigurerInput, input: MultilayerAutoroutePreconfigurerInput,
options: MultilayerAutorouteOptions, options: MultilayerAutorouteOptions,
) -> Result<Self, AutorouterError> { ) -> Result<Self, AutorouterError> {
let planner = MultilayerPreconfigurer::new(autorouter, input.clone()); let preconfigurer = MultilayerPreconfigurer::new(autorouter, input.clone());
let preconfiguration = MultilayerAutorouteConfiguration { let preconfiguration = MultilayerAutorouteConfiguration {
plan: planner.plan().clone(), plan: preconfigurer.plan().clone(),
planar: PlanarAutoroutePreconfigurerInput { planar: PlanarAutoroutePreconfigurerInput {
ratlines: input.ratlines.clone(), ratlines: input.ratlines.clone(),
terminating_dot_map: BTreeMap::new(), terminating_dot_map: BTreeMap::new(),