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

View File

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

View File

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

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
/// it no longer has any values.
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.
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);
// Remove the key if it no longer has any values.
if set.is_empty() {
self.key_to_values.remove(&k);
self.key_to_values.remove(&key);
}
}
Some(k)
Some(key)
} else {
None
}