diff --git a/src/autorouter/anterouter.rs b/src/autorouter/anterouter.rs index cf3df72..ae958d7 100644 --- a/src/autorouter/anterouter.rs +++ b/src/autorouter/anterouter.rs @@ -4,6 +4,7 @@ use std::collections::BTreeMap; +use derive_getters::Getters; use geo::{point, Distance, Euclidean, Point}; use petgraph::graph::NodeIndex; use rstar::{Envelope, RTreeObject, AABB}; @@ -46,6 +47,7 @@ pub struct AnterouterPlan { pub ratline_terminating_schemes: BTreeMap<(RatlineUid, FixedDotIndex), TerminatingScheme>, } +#[derive(Getters)] pub struct Anterouter { plan: AnterouterPlan, } @@ -60,7 +62,9 @@ impl Anterouter { autorouter: &mut Autorouter, recorder: &mut BoardEdit, options: &AnterouterOptions, - ) { + ) -> BTreeMap<(RatlineUid, FixedDotIndex, usize), FixedDotIndex> { + let mut terminating_dot_map = BTreeMap::new(); + // PERF: Unnecessary clone. for (ratline, layer) in self.plan.layer_map.clone().iter() { let endpoint_indices = ratline.ref_(autorouter).endpoint_indices(); @@ -77,14 +81,10 @@ impl Anterouter { .get(&(*ratline, endpoint_dots.0)) { match terminating_scheme { - TerminatingScheme::ExistingFixedDot(terminating_dot) => autorouter - .ratsnests - .on_principal_layer_mut(ratline.principal_layer) - .assign_terminating_dot_to_ratvertex( - endpoint_indices.0, - *layer, - *terminating_dot, - ), + TerminatingScheme::ExistingFixedDot(terminating_dot) => { + terminating_dot_map + .insert((*ratline, endpoint_dots.0, *layer), *terminating_dot); + } TerminatingScheme::Fanout => self.anteroute_fanout( autorouter, recorder, @@ -93,6 +93,7 @@ impl Anterouter { endpoint_dots.0, *layer, options, + &mut terminating_dot_map, ), } } @@ -103,14 +104,10 @@ impl Anterouter { .get(&(*ratline, endpoint_dots.1)) { match terminating_scheme { - TerminatingScheme::ExistingFixedDot(terminating_dot) => autorouter - .ratsnests - .on_principal_layer_mut(ratline.principal_layer) - .assign_terminating_dot_to_ratvertex( - endpoint_indices.1, - *layer, - *terminating_dot, - ), + TerminatingScheme::ExistingFixedDot(terminating_dot) => { + terminating_dot_map + .insert((*ratline, endpoint_dots.1, *layer), *terminating_dot); + } TerminatingScheme::Fanout => self.anteroute_fanout( autorouter, recorder, @@ -119,10 +116,13 @@ impl Anterouter { endpoint_dots.1, *layer, options, + &mut terminating_dot_map, ), } } } + + terminating_dot_map } fn anteroute_fanout( @@ -134,6 +134,7 @@ impl Anterouter { source_dot: FixedDotIndex, target_layer: usize, options: &AnterouterOptions, + terminating_dot_map: &mut BTreeMap<(RatlineUid, FixedDotIndex, usize), FixedDotIndex>, ) { let mut ratline_delta: Point = ratline.ref_(autorouter).line_segment().delta().into(); @@ -172,6 +173,7 @@ impl Anterouter { target_layer, CardinalDirection::nearest_from_vector(ratline_delta), options, + terminating_dot_map, ) .is_ok() { @@ -207,6 +209,7 @@ impl Anterouter { target_layer, CardinalDirection::nearest_from_vector(ratline_delta), options, + terminating_dot_map, ) .is_ok() { @@ -224,6 +227,7 @@ impl Anterouter { target_layer, OrdinalDirection::nearest_from_vector(ratline_delta), options, + terminating_dot_map, ) .is_ok() { @@ -241,6 +245,7 @@ impl Anterouter { target_layer, OrdinalDirection::nearest_from_vector(ratline_delta), options, + terminating_dot_map, ) .is_ok() { @@ -261,6 +266,7 @@ impl Anterouter { target_layer: usize, preferred_compass_direction: impl CompassDirection, options: &AnterouterOptions, + terminating_dot_map: &mut BTreeMap<(RatlineUid, FixedDotIndex, usize), FixedDotIndex>, ) -> Result<(), ()> { if self .anteroute_fanout_on_bbox_in_direction( @@ -273,6 +279,7 @@ impl Anterouter { target_layer, preferred_compass_direction, options, + terminating_dot_map, ) .is_ok() { @@ -297,6 +304,7 @@ impl Anterouter { target_layer, counterclockwise_turning_cardinal_direction, options, + terminating_dot_map, ) .is_ok() { @@ -317,6 +325,7 @@ impl Anterouter { target_layer, clockwise_turning_cardinal_direction, options, + terminating_dot_map, ) .is_ok() { @@ -342,6 +351,7 @@ impl Anterouter { target_layer: usize, direction: impl Into, options: &AnterouterOptions, + terminating_dot_map: &mut BTreeMap<(RatlineUid, FixedDotIndex, usize), FixedDotIndex>, ) -> Result<(), ()> { let (via, dots) = self.place_fanout_via_on_bbox_in_direction( autorouter, @@ -353,6 +363,7 @@ impl Anterouter { target_layer, direction, options, + terminating_dot_map, )?; let layer = source_dot @@ -401,6 +412,7 @@ impl Anterouter { target_layer: usize, direction: impl Into, options: &AnterouterOptions, + terminating_dot_map: &mut BTreeMap<(RatlineUid, FixedDotIndex, usize), FixedDotIndex>, ) -> Result<(GenericIndex, Vec), ()> { let source_layer = autorouter .board() @@ -460,10 +472,7 @@ impl Anterouter { .layer() }) .unwrap(); - autorouter - .ratsnests - .on_principal_layer_mut(ratline.principal_layer) - .assign_terminating_dot_to_ratvertex(ratvertex, target_layer, *terminating_dot); + terminating_dot_map.insert((ratline, source_dot, target_layer), *terminating_dot); Ok((via, dots)) } else { Err(()) diff --git a/src/autorouter/autorouter.rs b/src/autorouter/autorouter.rs index b0e041b..8dcc8f9 100644 --- a/src/autorouter/autorouter.rs +++ b/src/autorouter/autorouter.rs @@ -7,7 +7,7 @@ use geo::Point; use petgraph::graph::NodeIndex; use serde::{Deserialize, Serialize}; use spade::InsertionError; -use std::collections::BTreeSet; +use std::collections::{BTreeMap, BTreeSet}; use thiserror::Error; use crate::{ @@ -137,6 +137,7 @@ impl Autorouter { self, PlanarAutoroutePreconfigurerInput { ratlines: self.selected_planar_ratlines(selection, options.principal_layer), + terminating_dot_map: BTreeMap::new(), }, options, ) @@ -196,7 +197,7 @@ impl Autorouter { active_layer, allowed_edges, ratlines.into_iter().filter_map(|ratline| { - let (origin, destination) = ratline.ref_(self).terminating_dots(); + let (origin, destination) = ratline.ref_(self).endpoint_dots(); if navmesh .as_ref() diff --git a/src/autorouter/multilayer_autoroute.rs b/src/autorouter/multilayer_autoroute.rs index 4f1a643..fba4534 100644 --- a/src/autorouter/multilayer_autoroute.rs +++ b/src/autorouter/multilayer_autoroute.rs @@ -48,12 +48,16 @@ impl MultilayerAutorouteExecutionStepper { ) -> Result { let mut anterouter = Anterouter::new(configuration.plan); let mut anteroute_edit = BoardEdit::new(); - anterouter.anteroute(autorouter, &mut anteroute_edit, &options.anterouter); + let terminating_dot_map = + anterouter.anteroute(autorouter, &mut anteroute_edit, &options.anterouter); Ok(Self { planar: PlanarAutorouteReconfigurator::new( autorouter, - configuration.planar, + PlanarAutoroutePreconfigurerInput { + terminating_dot_map, + ..configuration.planar + }, options.planar, )?, anteroute_edit, diff --git a/src/autorouter/multilayer_reconfigurator.rs b/src/autorouter/multilayer_reconfigurator.rs index 94469de..ce7ec9f 100644 --- a/src/autorouter/multilayer_reconfigurator.rs +++ b/src/autorouter/multilayer_reconfigurator.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: MIT -use std::ops::ControlFlow; +use std::{collections::BTreeMap, ops::ControlFlow}; use specctra_core::mesadata::AccessMesadata; @@ -49,6 +49,7 @@ impl MultilayerAutorouteReconfigurator { plan: planner.plan().clone(), planar: PlanarAutoroutePreconfigurerInput { ratlines: input.ratlines.clone(), + terminating_dot_map: BTreeMap::new(), }, }; let reconfigurer = MultilayerReconfigurer::new(autorouter, input.ratlines, &options); diff --git a/src/autorouter/planar_autoroute.rs b/src/autorouter/planar_autoroute.rs index 31ce1e1..dc04f67 100644 --- a/src/autorouter/planar_autoroute.rs +++ b/src/autorouter/planar_autoroute.rs @@ -5,7 +5,7 @@ //! Manages autorouting of ratlines in a layout, tracking status and processed //! routing steps. -use std::ops::ControlFlow; +use std::{collections::BTreeMap, ops::ControlFlow}; use derive_getters::Getters; @@ -14,7 +14,7 @@ use crate::{ edit::{BoardDataEdit, BoardEdit}, AccessMesadata, }, - drawing::{band::BandTermsegIndex, graph::PrimitiveIndex}, + drawing::{band::BandTermsegIndex, dot::FixedDotIndex, graph::PrimitiveIndex}, geometry::{edit::Edit, primitive::PrimitiveShape}, graph::MakeRef, layout::LayoutEdit, @@ -32,6 +32,30 @@ use super::{ #[derive(Clone, Debug)] pub struct PlanarAutorouteConfiguration { pub ratlines: Vec, + pub terminating_dot_map: BTreeMap<(RatlineUid, FixedDotIndex, usize), FixedDotIndex>, +} + +impl PlanarAutorouteConfiguration { + pub fn ratline_terminating_dots( + &self, + autorouter: &Autorouter, + ratline_index: usize, + ) -> (FixedDotIndex, FixedDotIndex) { + let ratline = self.ratlines[ratline_index]; + let endpoint_dots = ratline.ref_(autorouter).endpoint_dots(); + let layer = ratline.ref_(autorouter).layer(); + + ( + *self + .terminating_dot_map + .get(&(ratline, endpoint_dots.0, layer)) + .unwrap_or(&endpoint_dots.0), + *self + .terminating_dot_map + .get(&(ratline, endpoint_dots.1, layer)) + .unwrap_or(&endpoint_dots.1), + ) + } } #[derive(Clone, Debug)] @@ -83,9 +107,7 @@ impl PlanarAutorouteExecutionStepper { return Err(AutorouterError::NothingToRoute); }; - let (origin, destination) = configuration.ratlines[0] - .ref_(autorouter) - .terminating_dots(); + let (origin, destination) = configuration.ratline_terminating_dots(autorouter, 0); let mut router = Router::new(autorouter.board.layout_mut(), options.router); Ok(Self { @@ -121,9 +143,9 @@ impl PlanarAutorouteExecutionStepper { autorouter.board.apply_edit(&board_edit.reverse()); - let (origin, destination) = self.configuration.ratlines[index] - .ref_(autorouter) - .terminating_dots(); + let (origin, destination) = self + .configuration + .ratline_terminating_dots(autorouter, index); let mut router = Router::new(autorouter.board.layout_mut(), self.options.router); self.route = Some(router.route( @@ -169,9 +191,9 @@ impl Step, Option, PlanarAutorouteCo )))); } - let (origin, destination) = self.configuration().ratlines[self.curr_ratline_index] - .ref_(autorouter) - .terminating_dots(); + let (origin, destination) = self + .configuration + .ratline_terminating_dots(autorouter, self.curr_ratline_index); let Some(ref mut route) = self.route else { // May happen if stepper was aborted. @@ -226,7 +248,9 @@ impl Step, Option, PlanarAutorouteCo self.curr_ratline_index += 1; if let Some(new_ratline) = self.configuration.ratlines.get(self.curr_ratline_index) { - let (origin, destination) = new_ratline.ref_(autorouter).terminating_dots(); + let (origin, destination) = self + .configuration + .ratline_terminating_dots(autorouter, self.curr_ratline_index); let mut router = Router::new(autorouter.board.layout_mut(), self.options.router); self.dissolve_route_stepper_and_push_layout_edit(); diff --git a/src/autorouter/planar_preconfigurer.rs b/src/autorouter/planar_preconfigurer.rs index a2dfce5..564f374 100644 --- a/src/autorouter/planar_preconfigurer.rs +++ b/src/autorouter/planar_preconfigurer.rs @@ -2,21 +2,25 @@ // // SPDX-License-Identifier: MIT -use std::collections::BTreeSet; +use std::collections::{BTreeMap, BTreeSet}; use derive_getters::{Dissolve, Getters}; use enum_dispatch::enum_dispatch; use petgraph::algo::tarjan_scc; use specctra_core::mesadata::AccessMesadata; -use crate::autorouter::{ - planar_autoroute::PlanarAutorouteConfiguration, ratline::RatlineUid, scc::Scc, Autorouter, - PlanarAutorouteOptions, +use crate::{ + autorouter::{ + planar_autoroute::PlanarAutorouteConfiguration, ratline::RatlineUid, scc::Scc, Autorouter, + PlanarAutorouteOptions, + }, + drawing::dot::FixedDotIndex, }; #[derive(Clone, Debug)] pub struct PlanarAutoroutePreconfigurerInput { pub ratlines: BTreeSet, + pub terminating_dot_map: BTreeMap<(RatlineUid, FixedDotIndex, usize), FixedDotIndex>, } pub struct PresortParams { @@ -102,6 +106,7 @@ impl PreconfigurePlanarAutoroute for SccIntersectionsAndLengthRatlinePlanarAutor PlanarAutorouteConfiguration { ratlines: presorted_ratlines, + terminating_dot_map: input.terminating_dot_map, } } } diff --git a/src/autorouter/planar_reconfigurator.rs b/src/autorouter/planar_reconfigurator.rs index 271b1f4..a88f058 100644 --- a/src/autorouter/planar_reconfigurator.rs +++ b/src/autorouter/planar_reconfigurator.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: MIT -use std::ops::ControlFlow; +use std::{collections::BTreeMap, ops::ControlFlow}; use specctra_core::mesadata::AccessMesadata; @@ -95,12 +95,7 @@ impl Step, Option, PlanarReconfigura return Ok(ControlFlow::Break(None)); }; - match self.stepper.reconfigure( - autorouter, - PlanarAutorouteConfiguration { - ratlines: configuration, - }, - ) { + match self.stepper.reconfigure(autorouter, configuration) { Ok(result) => { return Ok(ControlFlow::Continue(ReconfiguratorStatus::Reconfigured( result, diff --git a/src/autorouter/planar_reconfigurer.rs b/src/autorouter/planar_reconfigurer.rs index b9e5215..3e396d7 100644 --- a/src/autorouter/planar_reconfigurer.rs +++ b/src/autorouter/planar_reconfigurer.rs @@ -8,17 +8,12 @@ use enum_dispatch::enum_dispatch; use itertools::{Itertools, Permutations}; use specctra_core::mesadata::AccessMesadata; -use crate::{ - autorouter::{ - planar_autoroute::{PlanarAutorouteConfiguration, PlanarAutorouteExecutionStepper}, - planar_preconfigurer::SccIntersectionsAndLengthRatlinePlanarAutoroutePreconfigurer, - ratline::RatlineUid, - scc::Scc, - Autorouter, PlanarAutorouteOptions, - }, - drawing::graph::MakePrimitiveRef, - geometry::{GenericNode, GetLayer}, - graph::MakeRef, +use crate::autorouter::{ + planar_autoroute::{PlanarAutorouteConfiguration, PlanarAutorouteExecutionStepper}, + planar_preconfigurer::SccIntersectionsAndLengthRatlinePlanarAutoroutePreconfigurer, + ratline::RatlineUid, + scc::Scc, + Autorouter, PlanarAutorouteOptions, }; #[enum_dispatch] @@ -27,12 +22,12 @@ pub trait MakeNextPlanarAutorouteConfiguration { &mut self, autorouter: &mut Autorouter, stepper: &PlanarAutorouteExecutionStepper, - ) -> Option>; + ) -> Option; } #[enum_dispatch(MakeNextPlanarAutorouteConfiguration)] pub enum PlanarAutorouteReconfigurer { - RatlineCuts(RatlineCutsPlanarAutorouteReconfigurer), + //RatlineCuts(RatlineCutsPlanarAutorouteReconfigurer), SccPermutations(SccPermutationsPlanarAutorouteReconfigurer), } @@ -59,7 +54,7 @@ impl PlanarAutorouteReconfigurer { pub struct SccPermutationsPlanarAutorouteReconfigurer { sccs_permutations_iter: Skip>>, - initial_configuration: PlanarAutorouteConfiguration, + preconfiguration: PlanarAutorouteConfiguration, } impl SccPermutationsPlanarAutorouteReconfigurer { @@ -76,7 +71,7 @@ impl SccPermutationsPlanarAutorouteReconfigurer { Self { sccs_permutations_iter: sccs.into_iter().permutations(sccs_len).skip(1), - initial_configuration: preconfiguration, + preconfiguration, } } } @@ -86,12 +81,12 @@ impl MakeNextPlanarAutorouteConfiguration for SccPermutationsPlanarAutorouteReco &mut self, autorouter: &mut Autorouter, _stepper: &PlanarAutorouteExecutionStepper, - ) -> Option> { + ) -> Option { let scc_permutation = self.sccs_permutations_iter.next()?; let mut ratlines = vec![]; for scc in scc_permutation { - for ratline in self.initial_configuration.ratlines.iter() { + for ratline in self.preconfiguration.ratlines.iter() { if scc.node_indices().contains( &autorouter .ratsnests() @@ -114,7 +109,10 @@ impl MakeNextPlanarAutorouteConfiguration for SccPermutationsPlanarAutorouteReco } } - Some(ratlines) + Some(PlanarAutorouteConfiguration { + ratlines, + ..self.preconfiguration.clone() + }) } } @@ -122,7 +120,7 @@ pub struct RatlineCutsPlanarAutorouteReconfigurer { //sccs: Vec>>, } -impl RatlineCutsPlanarAutorouteReconfigurer { +/*impl RatlineCutsPlanarAutorouteReconfigurer { pub fn new( _autorouter: &mut Autorouter, _ratlines: Vec, @@ -134,16 +132,19 @@ impl RatlineCutsPlanarAutorouteReconfigurer { }*/ Self {} } -} +}*/ -impl MakeNextPlanarAutorouteConfiguration for RatlineCutsPlanarAutorouteReconfigurer { +/*impl MakeNextPlanarAutorouteConfiguration for RatlineCutsPlanarAutorouteReconfigurer { fn next_configuration( &mut self, autorouter: &mut Autorouter, stepper: &PlanarAutorouteExecutionStepper, ) -> Option> { let curr_ratline = stepper.configuration().ratlines[*stepper.curr_ratline_index()]; - let terminating_dots = curr_ratline.ref_(autorouter).terminating_dots(); + let terminating_dots = stepper + .configuration() + .terminating_dots + .get(&(curr_ratline,)); let bands_cut_by_ratline: Vec<_> = autorouter .board() .layout() @@ -182,4 +183,4 @@ impl MakeNextPlanarAutorouteConfiguration for RatlineCutsPlanarAutorouteReconfig Some(ratlines) } -} +}*/ diff --git a/src/autorouter/ratline.rs b/src/autorouter/ratline.rs index d680d28..e50e03d 100644 --- a/src/autorouter/ratline.rs +++ b/src/autorouter/ratline.rs @@ -99,41 +99,6 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> { (source_dot, target_dot) } - pub fn terminating_dots(&self) -> (FixedDotIndex, FixedDotIndex) { - let (source, target) = self - .autorouter - .ratsnests() - .on_principal_layer(self.uid.principal_layer) - .graph() - .edge_endpoints(self.uid.index) - .unwrap(); - - let source_dot = self - .autorouter - .ratsnests() - .on_principal_layer(self.uid.principal_layer) - .graph() - .node_weight(source) - .unwrap() - .layer_terminating_dots - .get(&self.layer()) - .copied() - .unwrap_or(self.endpoint_dots().0); - let target_dot = self - .autorouter - .ratsnests() - .on_principal_layer(self.uid.principal_layer) - .graph() - .node_weight(target) - .unwrap() - .layer_terminating_dots - .get(&self.layer()) - .copied() - .unwrap_or(self.endpoint_dots().1); - - (source_dot, target_dot) - } - pub fn layer(&self) -> usize { self.autorouter .ratsnests() diff --git a/src/autorouter/ratsnest.rs b/src/autorouter/ratsnest.rs index 0285592..6796524 100644 --- a/src/autorouter/ratsnest.rs +++ b/src/autorouter/ratsnest.rs @@ -9,11 +9,7 @@ use std::{ use enum_dispatch::enum_dispatch; use geo::Point; -use petgraph::{ - data::Element, - graph::{EdgeIndex, NodeIndex}, - prelude::StableUnGraph, -}; +use petgraph::{data::Element, graph::EdgeIndex, prelude::StableUnGraph}; use spade::{handles::FixedVertexHandle, HasPosition, InsertionError, Point2}; use specctra_core::mesadata::AccessMesadata; @@ -54,7 +50,6 @@ impl From for crate::layout::NodeIndex { pub struct RatvertexWeight { vertex: RatvertexNodeIndex, pub pos: Point, - pub layer_terminating_dots: BTreeMap, } impl GetTrianvertexNodeIndex for RatvertexWeight { @@ -191,11 +186,7 @@ impl Ratsnest { return Ok(()); } - triangulation.add_vertex(RatvertexWeight { - vertex, - pos, - layer_terminating_dots: BTreeMap::new(), - })?; + triangulation.add_vertex(RatvertexWeight { vertex, pos })?; Ok(()) }; @@ -230,19 +221,6 @@ impl Ratsnest { Ok(()) } - pub fn assign_terminating_dot_to_ratvertex( - &mut self, - node_index: NodeIndex, - layer: usize, - terminating_dot: FixedDotIndex, - ) { - self.graph - .node_weight_mut(node_index) - .unwrap() - .layer_terminating_dots - .insert(layer, terminating_dot); - } - pub fn assign_layer_to_ratline(&mut self, ratline_index: EdgeIndex, layer: usize) { self.graph.edge_weight_mut(ratline_index).unwrap().layer = layer; } diff --git a/tests/common/mod.rs b/tests/common/mod.rs index 18c59b6..f2713c0 100644 --- a/tests/common/mod.rs +++ b/tests/common/mod.rs @@ -17,7 +17,7 @@ use topola::{ graph::{GetMaybeNet, MakePrimitiveRef, PrimitiveIndex}, primitive::MakePrimitiveShape, }, - geometry::{shape::MeasureLength, GenericNode, GetLayer}, + geometry::{shape::MeasureLength, GenericNode}, graph::{GetIndex, MakeRef}, router::{navmesh::Navmesh, RouterOptions}, specctra::{design::SpecctraDesign, mesadata::SpecctraMesadata},