diff --git a/src/autorouter/autorouter.rs b/src/autorouter/autorouter.rs index 8e37d55..03b7cf5 100644 --- a/src/autorouter/autorouter.rs +++ b/src/autorouter/autorouter.rs @@ -14,6 +14,7 @@ use crate::{ autorouter::{ multilayer_autoroute::MultilayerAutorouteOptions, multilayer_reconfigurator::MultilayerAutorouteReconfigurator, + planar_autoroute::PlanarAutorouteConfiguration, planar_reconfigurator::PlanarAutorouteReconfigurator, ratsnests::Ratsnests, }, board::{AccessMesadata, Board}, @@ -132,7 +133,9 @@ impl Autorouter { ) -> Result { PlanarAutorouteReconfigurator::new( self, - self.selected_planar_ratlines(selection, options.principal_layer), + PlanarAutorouteConfiguration { + ratlines: self.selected_planar_ratlines(selection, options.principal_layer), + }, options, ) } diff --git a/src/autorouter/multilayer_autoroute.rs b/src/autorouter/multilayer_autoroute.rs index dafbb59..fdba675 100644 --- a/src/autorouter/multilayer_autoroute.rs +++ b/src/autorouter/multilayer_autoroute.rs @@ -11,6 +11,7 @@ use crate::{ autorouter::{ anterouter::{Anterouter, AnterouterOptions, AnterouterPlan}, invoker::GetDebugOverlayData, + planar_autoroute::PlanarAutorouteConfiguration, planar_reconfigurator::{PlanarAutorouteReconfigurator, PlanarReconfiguratorStatus}, ratline::RatlineUid, Autorouter, AutorouterError, PlanarAutorouteOptions, @@ -46,7 +47,11 @@ impl MultilayerAutorouteExecutionStepper { anterouter.anteroute(autorouter, &mut anteroute_edit, &options.anterouter); Ok(Self { - planar: PlanarAutorouteReconfigurator::new(autorouter, ratlines, options.planar)?, + planar: PlanarAutorouteReconfigurator::new( + autorouter, + PlanarAutorouteConfiguration { ratlines }, + options.planar, + )?, anteroute_edit, options: options.clone(), }) diff --git a/src/autorouter/planar_autoroute.rs b/src/autorouter/planar_autoroute.rs index 09cb089..31ce1e1 100644 --- a/src/autorouter/planar_autoroute.rs +++ b/src/autorouter/planar_autoroute.rs @@ -59,8 +59,8 @@ pub enum PlanarAutorouteContinueStatus { /// Manages the autorouting process across multiple ratlines. #[derive(Getters)] pub struct PlanarAutorouteExecutionStepper { - /// The ratlines which we are routing. - ratlines: Vec, + /// The stepper configuration, including the ratlines which we are routing. + configuration: PlanarAutorouteConfiguration, /// Keeps track of the current ratline being routed, if one is active. curr_ratline_index: usize, /// Stores the current route being processed, if any. @@ -74,25 +74,22 @@ pub struct PlanarAutorouteExecutionStepper { } impl PlanarAutorouteExecutionStepper { - /// Initializes a new [`AutorouteExecutionStepper`] instance. - /// - /// This method sets up the routing process by accepting the execution properties. - /// It prepares the first ratline to route - /// and stores the associated data for future routing steps. pub fn new( autorouter: &mut Autorouter, - ratlines: Vec, + configuration: PlanarAutorouteConfiguration, options: PlanarAutorouteOptions, ) -> Result { - if ratlines.is_empty() { + if configuration.ratlines.is_empty() { return Err(AutorouterError::NothingToRoute); }; - let (origin, destination) = ratlines[0].ref_(autorouter).terminating_dots(); + let (origin, destination) = configuration.ratlines[0] + .ref_(autorouter) + .terminating_dots(); let mut router = Router::new(autorouter.board.layout_mut(), options.router); Ok(Self { - ratlines, + configuration, curr_ratline_index: 0, route: Some(router.route( LayoutEdit::new(), @@ -124,7 +121,9 @@ impl PlanarAutorouteExecutionStepper { autorouter.board.apply_edit(&board_edit.reverse()); - let (origin, destination) = self.ratlines[index].ref_(autorouter).terminating_dots(); + let (origin, destination) = self.configuration.ratlines[index] + .ref_(autorouter) + .terminating_dots(); let mut router = Router::new(autorouter.board.layout_mut(), self.options.router); self.route = Some(router.route( @@ -158,7 +157,7 @@ impl Step, Option, PlanarAutorouteCo { // TODO: Use a proper state machine here for better readability? - if self.curr_ratline_index >= self.ratlines.len() { + if self.curr_ratline_index >= self.configuration().ratlines.len() { self.dissolve_route_stepper_and_push_layout_edit(); return Ok(ControlFlow::Break(Some(BoardEdit::new_from_edits( @@ -170,15 +169,15 @@ impl Step, Option, PlanarAutorouteCo )))); } + let (origin, destination) = self.configuration().ratlines[self.curr_ratline_index] + .ref_(autorouter) + .terminating_dots(); + let Some(ref mut route) = self.route else { // May happen if stepper was aborted. return Ok(ControlFlow::Break(None)); }; - let (origin, destination) = self.ratlines[self.curr_ratline_index] - .ref_(autorouter) - .terminating_dots(); - let ret = if let Some(band_termseg) = autorouter.board.band_between_nodes(origin, destination) { @@ -206,7 +205,7 @@ impl Step, Option, PlanarAutorouteCo .ratsnests .on_principal_layer_mut(self.options.principal_layer) .assign_band_termseg_to_ratline( - self.ratlines[self.curr_ratline_index].index, + self.configuration().ratlines[self.curr_ratline_index].index, band_termseg, ); @@ -226,7 +225,7 @@ impl Step, Option, PlanarAutorouteCo self.curr_ratline_index += 1; - if let Some(new_ratline) = self.ratlines.get(self.curr_ratline_index) { + if let Some(new_ratline) = self.configuration.ratlines.get(self.curr_ratline_index) { let (origin, destination) = new_ratline.ref_(autorouter).terminating_dots(); let mut router = Router::new(autorouter.board.layout_mut(), self.options.router); @@ -248,31 +247,30 @@ impl Step, Option, PlanarAutorouteCo impl Abort> for PlanarAutorouteExecutionStepper { fn abort(&mut self, autorouter: &mut Autorouter) { self.backtrace_to_index(autorouter, 0); - self.curr_ratline_index = self.ratlines.len(); + self.curr_ratline_index = self.configuration.ratlines.len(); } } impl Reconfigure> for PlanarAutorouteExecutionStepper { - type Configuration = Vec; + type Configuration = PlanarAutorouteConfiguration; type Output = Result; fn reconfigure( &mut self, autorouter: &mut Autorouter, - permutation: Vec, + new_configuration: PlanarAutorouteConfiguration, ) -> Result { - let Some(new_index) = permutation + let Some(new_index) = new_configuration + .ratlines .iter() - .zip(self.ratlines.iter()) + .zip(self.configuration.ratlines.iter()) .position(|(permuted, original)| *permuted != *original) else { return Err(AutorouterError::NothingToUndoForReconfiguration); }; let result = PlanarAutorouteConfigurationResult { - configuration: PlanarAutorouteConfiguration { - ratlines: std::mem::replace(&mut self.ratlines, permutation), - }, + configuration: std::mem::replace(&mut self.configuration, new_configuration), costs: PlanarAutorouteCosts { lengths: vec![], // TODO. }, @@ -294,7 +292,7 @@ impl EstimateProgress for PlanarAutorouteExecutionStepper { } fn estimate_progress_maximum(&self) -> f64 { - self.ratlines.len() as f64 + self.configuration().ratlines.len() as f64 } } diff --git a/src/autorouter/planar_reconfigurator.rs b/src/autorouter/planar_reconfigurator.rs index f062972..7b2e7c2 100644 --- a/src/autorouter/planar_reconfigurator.rs +++ b/src/autorouter/planar_reconfigurator.rs @@ -10,12 +10,11 @@ use crate::{ autorouter::{ invoker::GetDebugOverlayData, planar_autoroute::{ - PlanarAutorouteConfigurationResult, PlanarAutorouteContinueStatus, - PlanarAutorouteExecutionStepper, + PlanarAutorouteConfiguration, PlanarAutorouteConfigurationResult, + PlanarAutorouteContinueStatus, PlanarAutorouteExecutionStepper, }, planar_reconfigurer::{PermuteRatlines, PlanarReconfigurer}, presorter::{PresortParams, PresortRatlines, SccIntersectionsAndLengthPresorter}, - ratline::RatlineUid, Autorouter, AutorouterError, PlanarAutorouteOptions, }, board::edit::BoardEdit, @@ -36,30 +35,26 @@ pub struct PlanarAutorouteReconfigurator { impl PlanarAutorouteReconfigurator { pub fn new( autorouter: &mut Autorouter, - ratlines: Vec, + input_configuration: PlanarAutorouteConfiguration, options: PlanarAutorouteOptions, ) -> Result { let presorter = SccIntersectionsAndLengthPresorter::new( autorouter, - &ratlines, + &input_configuration.ratlines, &PresortParams { intersector_count_weight: 1.0, length_weight: 0.001, }, &options, ); - let initially_sorted_ratlines = presorter.presort_ratlines(autorouter, &ratlines); - /*let permuter = RatlinesPermuter::SccPermutations(SccPermutationsRatlinePermuter::new( - autorouter, ratlines, presorter, &options, - ));*/ - let reconfigurer = PlanarReconfigurer::new(autorouter, ratlines, presorter, &options); + let preconfiguration = PlanarAutorouteConfiguration { + ratlines: presorter.presort_ratlines(autorouter, &input_configuration.ratlines), + }; + let reconfigurer = + PlanarReconfigurer::new(autorouter, input_configuration, presorter, &options); Ok(Self { - stepper: PlanarAutorouteExecutionStepper::new( - autorouter, - initially_sorted_ratlines, - options, - )?, + stepper: PlanarAutorouteExecutionStepper::new(autorouter, preconfiguration, options)?, // Note: I assume here that the first permutation is the same as the original order. reconfigurer, options, @@ -94,7 +89,12 @@ impl Step, Option, PlanarReconfigura return Ok(ControlFlow::Break(None)); }; - match self.stepper.reconfigure(autorouter, permutation) { + match self.stepper.reconfigure( + autorouter, + PlanarAutorouteConfiguration { + ratlines: permutation, + }, + ) { Ok(result) => { return Ok(ControlFlow::Continue(ReconfiguratorStatus::Reconfigured( result, diff --git a/src/autorouter/planar_reconfigurer.rs b/src/autorouter/planar_reconfigurer.rs index 64f7939..4d12a2f 100644 --- a/src/autorouter/planar_reconfigurer.rs +++ b/src/autorouter/planar_reconfigurer.rs @@ -10,9 +10,11 @@ use specctra_core::mesadata::AccessMesadata; use crate::{ autorouter::{ - planar_autoroute::PlanarAutorouteExecutionStepper, - presorter::SccIntersectionsAndLengthPresorter, ratline::RatlineUid, scc::Scc, Autorouter, - PlanarAutorouteOptions, + planar_autoroute::{PlanarAutorouteConfiguration, PlanarAutorouteExecutionStepper}, + presorter::SccIntersectionsAndLengthPresorter, + ratline::RatlineUid, + scc::Scc, + Autorouter, PlanarAutorouteOptions, }, drawing::graph::MakePrimitiveRef, geometry::{GenericNode, GetLayer}, @@ -37,12 +39,15 @@ pub enum PlanarReconfigurer { impl PlanarReconfigurer { pub fn new( autorouter: &mut Autorouter, - ratlines: Vec, + input_configuration: PlanarAutorouteConfiguration, presorter: SccIntersectionsAndLengthPresorter, options: &PlanarAutorouteOptions, ) -> Self { PlanarReconfigurer::SccPermutations(SccPermutationsPlanarReconfigurer::new( - autorouter, ratlines, presorter, options, + autorouter, + input_configuration, + presorter, + options, )) /*RatlinesPermuter::RatlineCuts(RatlineCutsRatlinePermuter::new( autorouter, ratlines, presorter, options, @@ -52,13 +57,13 @@ impl PlanarReconfigurer { pub struct SccPermutationsPlanarReconfigurer { sccs_permutations_iter: Skip>>, - original_ratlines: Vec, + input_configuration: PlanarAutorouteConfiguration, } impl SccPermutationsPlanarReconfigurer { pub fn new( _autorouter: &mut Autorouter, - ratlines: Vec, + input_configuration: PlanarAutorouteConfiguration, presorter: SccIntersectionsAndLengthPresorter, _options: &PlanarAutorouteOptions, ) -> Self { @@ -69,7 +74,7 @@ impl SccPermutationsPlanarReconfigurer { Self { sccs_permutations_iter: sccs.into_iter().permutations(sccs_len).skip(1), - original_ratlines: ratlines, + input_configuration, } } } @@ -84,7 +89,7 @@ impl PermuteRatlines for SccPermutationsPlanarReconfigurer { let mut ratlines = vec![]; for scc in scc_permutation { - for ratline in self.original_ratlines.iter() { + for ratline in self.input_configuration.ratlines.iter() { if scc.node_indices().contains( &autorouter .ratsnests() @@ -135,7 +140,7 @@ impl PermuteRatlines for RatlineCutsPlanarReconfigurer { autorouter: &mut Autorouter, stepper: &PlanarAutorouteExecutionStepper, ) -> Option> { - let curr_ratline = stepper.ratlines()[*stepper.curr_ratline_index()]; + let curr_ratline = stepper.configuration().ratlines[*stepper.curr_ratline_index()]; let terminating_dots = curr_ratline.ref_(autorouter).terminating_dots(); let bands_cut_by_ratline: Vec<_> = autorouter .board() @@ -152,7 +157,8 @@ impl PermuteRatlines for RatlineCutsPlanarReconfigurer { // Find the first ratline corresponding to a band that is cut. let first_cut_ratline_index = stepper - .ratlines() + .configuration() + .ratlines .iter() .position(|ratline| { for (band_uid, _) in &bands_cut_by_ratline { @@ -169,7 +175,7 @@ impl PermuteRatlines for RatlineCutsPlanarReconfigurer { // Swap the first ratline corresponding to a band that is cut with the // ratline that we have failed routing. - let mut ratlines = stepper.ratlines().clone(); + let mut ratlines = stepper.configuration().ratlines.clone(); ratlines.swap(*stepper.curr_ratline_index(), first_cut_ratline_index); Some(ratlines)