mirror of https://codeberg.org/topola/topola.git
feat(autorouter/multilayer_reconfigurator): Finally implement reconfiguration of layer map
This commit is contained in:
parent
8384c15a38
commit
813345863e
|
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(()),
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue