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,
}
#[derive(Clone, Copy, Debug)]
pub enum TerminatingScheme {
ExistingFixedDot(FixedDotIndex),
Fanout,
}
#[derive(Clone, Debug)]
pub struct AnterouterPlan {
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)]
@ -70,48 +64,42 @@ impl Anterouter {
let endpoint_indices = ratline.ref_(autorouter).endpoint_indices();
let endpoint_dots = ratline.ref_(autorouter).endpoint_dots();
if let Some(terminating_scheme) = self
.plan
.ratline_terminating_schemes
.get(&(*ratline, endpoint_dots.0))
if let Some(terminating_dot) =
self.plan
.static_terminating_dot_map
.get(&(*ratline, endpoint_dots.0, *layer))
{
match terminating_scheme {
TerminatingScheme::ExistingFixedDot(terminating_dot) => {
terminating_dot_map.insert((*ratline, endpoint_dots.0), *terminating_dot);
}
TerminatingScheme::Fanout => self.anteroute_fanout(
autorouter,
recorder,
endpoint_indices.0,
*ratline,
endpoint_dots.0,
*layer,
options,
&mut terminating_dot_map,
),
}
terminating_dot_map.insert((*ratline, endpoint_dots.0), *terminating_dot);
} else {
self.anteroute_fanout(
autorouter,
recorder,
endpoint_indices.0,
*ratline,
endpoint_dots.0,
*layer,
options,
&mut terminating_dot_map,
);
}
if let Some(terminating_scheme) = self
.plan
.ratline_terminating_schemes
.get(&(*ratline, endpoint_dots.1))
if let Some(terminating_dot) =
self.plan
.static_terminating_dot_map
.get(&(*ratline, endpoint_dots.1, *layer))
{
match terminating_scheme {
TerminatingScheme::ExistingFixedDot(terminating_dot) => {
terminating_dot_map.insert((*ratline, endpoint_dots.1), *terminating_dot);
}
TerminatingScheme::Fanout => self.anteroute_fanout(
autorouter,
recorder,
endpoint_indices.1,
*ratline,
endpoint_dots.1,
*layer,
options,
&mut terminating_dot_map,
),
}
terminating_dot_map.insert((*ratline, endpoint_dots.1), *terminating_dot);
} else {
self.anteroute_fanout(
autorouter,
recorder,
endpoint_indices.1,
*ratline,
endpoint_dots.1,
*layer,
options,
&mut terminating_dot_map,
);
}
}

View File

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

View File

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