feat(autorouter/multilayer_reconfigurator): Finally implement reconfiguration of layer map

This commit is contained in:
Mikolaj Wielgus 2025-10-27 00:09:13 +01:00
parent 8384c15a38
commit 813345863e
4 changed files with 43 additions and 35 deletions

View File

@ -56,7 +56,7 @@ impl MultilayerAutorouteExecutionStepper {
autorouter, autorouter,
PlanarAutoroutePreconfigurerInput { PlanarAutoroutePreconfigurerInput {
terminating_dot_map, terminating_dot_map,
..configuration.planar ratlines: configuration.planar.ratlines,
}, },
options.planar, options.planar,
)?, )?,
@ -96,20 +96,20 @@ impl<M: AccessMesadata> Abort<Autorouter<M>> for MultilayerAutorouteExecutionSte
} }
impl<M: AccessMesadata> Reconfigure<Autorouter<M>> for MultilayerAutorouteExecutionStepper { impl<M: AccessMesadata> Reconfigure<Autorouter<M>> for MultilayerAutorouteExecutionStepper {
type Configuration = AnterouterPlan; type Configuration = MultilayerAutorouteConfiguration;
type Output = Result<(), AutorouterError>; type Output = Result<(), AutorouterError>;
fn reconfigure( fn reconfigure(
&mut self, &mut self,
autorouter: &mut Autorouter<M>, autorouter: &mut Autorouter<M>,
plan: AnterouterPlan, new_configuration: MultilayerAutorouteConfiguration,
) -> Result<(), AutorouterError> { ) -> Result<(), AutorouterError> {
self.planar.abort(autorouter); self.planar.abort(autorouter);
// FIXME: this somehow corrupts internal state.
autorouter.board.apply_edit(&self.anteroute_edit.reverse()); autorouter.board.apply_edit(&self.anteroute_edit.reverse());
let mut anterouter = Anterouter::new(plan); *self = Self::new(autorouter, new_configuration, self.options)?;
let mut anteroute_edit = BoardEdit::new();
anterouter.anteroute(autorouter, &mut anteroute_edit, &self.options.anterouter);
Ok(()) Ok(())
} }
} }

View File

@ -45,6 +45,7 @@ impl MultilayerAutorouteReconfigurator {
options: MultilayerAutorouteOptions, options: MultilayerAutorouteOptions,
) -> Result<Self, AutorouterError> { ) -> Result<Self, AutorouterError> {
let preconfigurer = MultilayerPreconfigurer::new(autorouter, input.clone()); let preconfigurer = MultilayerPreconfigurer::new(autorouter, input.clone());
let preconfiguration = MultilayerAutorouteConfiguration { let preconfiguration = MultilayerAutorouteConfiguration {
plan: preconfigurer.plan().clone(), plan: preconfigurer.plan().clone(),
planar: PlanarAutoroutePreconfigurerInput { planar: PlanarAutoroutePreconfigurerInput {
@ -52,7 +53,8 @@ impl MultilayerAutorouteReconfigurator {
terminating_dot_map: BTreeMap::new(), terminating_dot_map: BTreeMap::new(),
}, },
}; };
let reconfigurer = MultilayerReconfigurer::new(autorouter, input.ratlines, &options); let reconfigurer =
MultilayerReconfigurer::new(autorouter, preconfiguration.clone(), &options);
Ok(Self { Ok(Self {
stepper: MultilayerAutorouteExecutionStepper::new( stepper: MultilayerAutorouteExecutionStepper::new(
@ -72,11 +74,11 @@ impl MultilayerAutorouteReconfigurator {
) -> Result<ControlFlow<Option<BoardEdit>, MultilayerReconfiguratorStatus>, AutorouterError> ) -> Result<ControlFlow<Option<BoardEdit>, MultilayerReconfiguratorStatus>, AutorouterError>
{ {
loop { loop {
let Some(plan) = self.reconfigurer.next_configuration(autorouter) else { let Some(configuration) = self.reconfigurer.next_configuration(autorouter) else {
return Ok(ControlFlow::Break(None)); return Ok(ControlFlow::Break(None));
}; };
match self.stepper.reconfigure(autorouter, plan) { match self.stepper.reconfigure(autorouter, configuration) {
Ok(_) => { Ok(_) => {
return Ok(ControlFlow::Continue( return Ok(ControlFlow::Continue(
ReconfiguratorStatus::Reconfigured(()), ReconfiguratorStatus::Reconfigured(()),

View File

@ -2,45 +2,51 @@
// //
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
use std::{collections::BTreeSet, time::SystemTime}; use std::{collections::BTreeMap, time::SystemTime};
use specctra_core::mesadata::AccessMesadata; use specctra_core::mesadata::AccessMesadata;
use crate::autorouter::{ use crate::autorouter::{
anterouter::AnterouterPlan, multilayer_autoroute::MultilayerAutorouteOptions, multilayer_autoroute::{MultilayerAutorouteConfiguration, MultilayerAutorouteOptions},
multilayer_preconfigurer::MultilayerPreconfigurer, ratline::RatlineUid, Autorouter, planar_preconfigurer::PlanarAutoroutePreconfigurerInput,
Autorouter,
}; };
pub struct MultilayerReconfigurer { pub struct MultilayerReconfigurer {
original_ratlines: BTreeSet<RatlineUid>, preconfiguration: MultilayerAutorouteConfiguration,
} }
impl MultilayerReconfigurer { impl MultilayerReconfigurer {
pub fn new( pub fn new(
autorouter: &Autorouter<impl AccessMesadata>, _autorouter: &Autorouter<impl AccessMesadata>,
ratlines: BTreeSet<RatlineUid>, preconfiguration: MultilayerAutorouteConfiguration,
options: &MultilayerAutorouteOptions, _options: &MultilayerAutorouteOptions,
) -> Self { ) -> Self {
Self { Self { preconfiguration }
original_ratlines: ratlines,
}
} }
pub fn next_configuration( pub fn next_configuration(
&mut self, &mut self,
autorouter: &Autorouter<impl AccessMesadata>, _autorouter: &Autorouter<impl AccessMesadata>,
) -> Option<AnterouterPlan> { ) -> Option<MultilayerAutorouteConfiguration> {
let planner = MultilayerPreconfigurer::new_from_layer_map( let mut new_anterouter_plan = self.preconfiguration.plan.clone();
autorouter, new_anterouter_plan.layer_map = self
&self.original_ratlines, .preconfiguration
self.original_ratlines .planar
.iter() .ratlines
.enumerate() .iter()
.map(|(_, ratline)| (*ratline, Self::crude_random_bit())) .enumerate()
.collect(), //.map(|(i, ratline)| (*ratline, i % 2))
); .map(|(_, ratline)| (*ratline, Self::crude_random_bit()))
.collect();
Some(planner.plan().clone()) Some(MultilayerAutorouteConfiguration {
plan: new_anterouter_plan,
planar: PlanarAutoroutePreconfigurerInput {
ratlines: self.preconfiguration.planar.ratlines.clone(),
terminating_dot_map: BTreeMap::new(),
},
})
} }
fn crude_random_bit() -> usize { fn crude_random_bit() -> usize {

View File

@ -83,16 +83,16 @@ impl<K: Eq + Ord + Clone, V: Eq + Ord + Clone> BiBTreeMapSet<K, V> {
/// Removes a value from the reverse map and the key from the forward map if /// Removes a value from the reverse map and the key from the forward map if
/// it no longer has any values. /// it no longer has any values.
pub fn remove_by_value(&mut self, value: &V) -> Option<K> { pub fn remove_by_value(&mut self, value: &V) -> Option<K> {
if let Some(k) = self.value_to_key.remove(value) { if let Some(key) = self.value_to_key.remove(value) {
// Remove the value from the key's value set. // Remove the value from the key's value set.
if let Some(set) = self.key_to_values.get_mut(&k) { if let Some(set) = self.key_to_values.get_mut(&key) {
set.remove(value); set.remove(value);
// Remove the key if it no longer has any values. // Remove the key if it no longer has any values.
if set.is_empty() { if set.is_empty() {
self.key_to_values.remove(&k); self.key_to_values.remove(&key);
} }
} }
Some(k) Some(key)
} else { } else {
None None
} }