mirror of https://codeberg.org/topola/topola.git
refactor(autorouter/planar_autoroute): Wrap ratline vec in new "configuration" struct
This will be useful later.
This commit is contained in:
parent
58e366ab0f
commit
630c3f0202
|
|
@ -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<M: AccessMesadata> Autorouter<M> {
|
|||
) -> Result<PlanarAutorouteReconfigurator, AutorouterError> {
|
||||
PlanarAutorouteReconfigurator::new(
|
||||
self,
|
||||
self.selected_planar_ratlines(selection, options.principal_layer),
|
||||
PlanarAutorouteConfiguration {
|
||||
ratlines: self.selected_planar_ratlines(selection, options.principal_layer),
|
||||
},
|
||||
options,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(),
|
||||
})
|
||||
|
|
|
|||
|
|
@ -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<RatlineUid>,
|
||||
/// 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<impl AccessMesadata>,
|
||||
ratlines: Vec<RatlineUid>,
|
||||
configuration: PlanarAutorouteConfiguration,
|
||||
options: PlanarAutorouteOptions,
|
||||
) -> Result<Self, AutorouterError> {
|
||||
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<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, 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<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, 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<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, 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<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, 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<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, PlanarAutorouteCo
|
|||
impl<M: AccessMesadata> Abort<Autorouter<M>> for PlanarAutorouteExecutionStepper {
|
||||
fn abort(&mut self, autorouter: &mut Autorouter<M>) {
|
||||
self.backtrace_to_index(autorouter, 0);
|
||||
self.curr_ratline_index = self.ratlines.len();
|
||||
self.curr_ratline_index = self.configuration.ratlines.len();
|
||||
}
|
||||
}
|
||||
|
||||
impl<M: AccessMesadata> Reconfigure<Autorouter<M>> for PlanarAutorouteExecutionStepper {
|
||||
type Configuration = Vec<RatlineUid>;
|
||||
type Configuration = PlanarAutorouteConfiguration;
|
||||
type Output = Result<PlanarAutorouteConfigurationResult, AutorouterError>;
|
||||
|
||||
fn reconfigure(
|
||||
&mut self,
|
||||
autorouter: &mut Autorouter<M>,
|
||||
permutation: Vec<RatlineUid>,
|
||||
new_configuration: PlanarAutorouteConfiguration,
|
||||
) -> Result<PlanarAutorouteConfigurationResult, AutorouterError> {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<impl AccessMesadata>,
|
||||
ratlines: Vec<RatlineUid>,
|
||||
input_configuration: PlanarAutorouteConfiguration,
|
||||
options: PlanarAutorouteOptions,
|
||||
) -> Result<Self, AutorouterError> {
|
||||
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<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, 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,
|
||||
|
|
|
|||
|
|
@ -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<impl AccessMesadata>,
|
||||
ratlines: Vec<RatlineUid>,
|
||||
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<Permutations<std::vec::IntoIter<Scc>>>,
|
||||
original_ratlines: Vec<RatlineUid>,
|
||||
input_configuration: PlanarAutorouteConfiguration,
|
||||
}
|
||||
|
||||
impl SccPermutationsPlanarReconfigurer {
|
||||
pub fn new(
|
||||
_autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||
ratlines: Vec<RatlineUid>,
|
||||
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<impl AccessMesadata>,
|
||||
stepper: &PlanarAutorouteExecutionStepper,
|
||||
) -> Option<Vec<RatlineUid>> {
|
||||
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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue