refactor(autorouter/autorouter): Put ratsnest in wrapper, mostly transparent for now

This commit is contained in:
Mikolaj Wielgus 2025-10-13 00:32:53 +02:00
parent 60cf00e014
commit 4c1a72dc1d
10 changed files with 118 additions and 60 deletions

View File

@ -167,7 +167,8 @@ impl<'a> Displayer<'a> {
.interactor
.invoker()
.autorouter()
.ratsnest()
.ratsnests()
.on_principal_layer(0)
.graph();
for edge in graph.edge_references() {
if edge.weight().band_termseg.is_some() {

View File

@ -66,7 +66,8 @@ impl Anterouter {
let endpoint_dots = ratline.ref_(autorouter).endpoint_dots();
autorouter
.ratsnest
.ratsnests
.on_principal_layer_mut(0)
.assign_layer_to_ratline(*ratline, *layer);
if let Some(terminating_scheme) = self
@ -75,13 +76,14 @@ impl Anterouter {
.get(&endpoint_dots.0)
{
match terminating_scheme {
TerminatingScheme::ExistingFixedDot(terminating_dot) => {
autorouter.ratsnest.assign_terminating_dot_to_ratvertex(
TerminatingScheme::ExistingFixedDot(terminating_dot) => autorouter
.ratsnests
.on_principal_layer_mut(0)
.assign_terminating_dot_to_ratvertex(
endpoint_indices.0,
*layer,
*terminating_dot,
)
}
),
TerminatingScheme::Fanout => self.anteroute_fanout(
autorouter,
endpoint_indices.0,
@ -99,13 +101,14 @@ impl Anterouter {
.get(&endpoint_dots.1)
{
match terminating_scheme {
TerminatingScheme::ExistingFixedDot(terminating_dot) => {
autorouter.ratsnest.assign_terminating_dot_to_ratvertex(
TerminatingScheme::ExistingFixedDot(terminating_dot) => autorouter
.ratsnests
.on_principal_layer_mut(0)
.assign_terminating_dot_to_ratvertex(
endpoint_indices.1,
*layer,
*terminating_dot,
)
}
),
TerminatingScheme::Fanout => self.anteroute_fanout(
autorouter,
endpoint_indices.1,
@ -430,11 +433,10 @@ impl Anterouter {
.layer()
})
.unwrap();
autorouter.ratsnest.assign_terminating_dot_to_ratvertex(
ratvertex,
target_layer,
*terminating_dot,
);
autorouter
.ratsnests
.on_principal_layer_mut(0)
.assign_terminating_dot_to_ratvertex(ratvertex, target_layer, *terminating_dot);
Ok((via, dots))
} else {
Err(())

View File

@ -15,6 +15,7 @@ use crate::{
multilayer_autoroute::{MultilayerAutorouteExecutionStepper, MultilayerAutorouterOptions},
permutator::PlanarAutorouteExecutionPermutator,
planner::Planner,
ratsnests::Ratsnests,
},
board::{AccessMesadata, Board},
drawing::band::BandTermsegIndex,
@ -31,7 +32,7 @@ use super::{
planar_autoroute::PlanarAutorouteExecutionStepper,
pointroute::PointrouteExecutionStepper,
ratline::RatlineIndex,
ratsnest::{Ratsnest, RatvertexNodeIndex},
ratsnest::RatvertexNodeIndex,
remove_bands::RemoveBandsExecutionStepper,
selection::{BandSelection, PinSelection},
};
@ -72,13 +73,13 @@ pub enum AutorouterError {
#[derive(Getters)]
pub struct Autorouter<M> {
pub(super) board: Board<M>,
pub(super) ratsnest: Ratsnest,
pub(super) ratsnests: Ratsnests,
}
impl<M: AccessMesadata> Autorouter<M> {
pub fn new(board: Board<M>) -> Result<Self, InsertionError> {
let ratsnest = Ratsnest::new(&board)?;
Ok(Self { board, ratsnest })
let ratsnests = Ratsnests::new(&board)?;
Ok(Self { board, ratsnests })
}
pub fn pointroute(
@ -89,7 +90,8 @@ impl<M: AccessMesadata> Autorouter<M> {
) -> Result<PointrouteExecutionStepper, AutorouterError> {
let ratvertex = self.find_selected_ratvertex(selection).unwrap();
let origin_dot = match self
.ratsnest
.ratsnests
.on_principal_layer_mut(0)
.graph()
.node_weight(ratvertex)
.unwrap()
@ -302,20 +304,28 @@ impl<M: AccessMesadata> Autorouter<M> {
}
pub(super) fn selected_ratlines(&self, selection: &PinSelection) -> Vec<RatlineIndex> {
self.ratsnest
self.ratsnests()
.on_principal_layer(0)
.graph()
.edge_indices()
.filter(|ratline| {
let (source, target) = self.ratsnest.graph().edge_endpoints(*ratline).unwrap();
let (source, target) = self
.ratsnests()
.on_principal_layer(0)
.graph()
.edge_endpoints(*ratline)
.unwrap();
let source_ratvertex = self
.ratsnest
.ratsnests()
.on_principal_layer(0)
.graph()
.node_weight(source)
.unwrap()
.node_index();
let to_ratvertex = self
.ratsnest
.ratsnests()
.on_principal_layer(0)
.graph()
.node_weight(target)
.unwrap()
@ -328,10 +338,15 @@ impl<M: AccessMesadata> Autorouter<M> {
}
fn find_selected_ratvertex(&self, selection: &PinSelection) -> Option<NodeIndex<usize>> {
self.ratsnest.graph().node_indices().find(|ratvertex| {
self.ratsnests()
.on_principal_layer(0)
.graph()
.node_indices()
.find(|ratvertex| {
selection.contains_node(
&self.board,
self.ratsnest
self.ratsnests()
.on_principal_layer(0)
.graph()
.node_weight(*ratvertex)
.unwrap()

View File

@ -21,6 +21,7 @@ pub mod pointroute;
pub mod presorter;
pub mod ratline;
pub mod ratsnest;
pub mod ratsnests;
pub mod remove_bands;
pub mod scc;
pub mod selection;

View File

@ -87,14 +87,16 @@ impl PermuteRatlines for SccPermutationsRatlinePermuter {
for ratline in self.original_ratlines.iter() {
if scc.node_indices().contains(
&autorouter
.ratsnest()
.ratsnests()
.on_principal_layer(0)
.graph()
.edge_endpoints(*ratline)
.unwrap()
.0,
) && scc.node_indices().contains(
&autorouter
.ratsnest()
.ratsnests()
.on_principal_layer(0)
.graph()
.edge_endpoints(*ratline)
.unwrap()

View File

@ -185,7 +185,10 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, PlanarAutorouteCo
.find_loose_band_uid(band_termseg.into())
.expect("a completely routed band should've Seg's as ends");
autorouter.ratsnest.assign_band_termseg_to_ratline(
autorouter
.ratsnests
.on_principal_layer_mut(0)
.assign_band_termseg_to_ratline(
self.ratlines[self.curr_ratline_index],
band_termseg,
);

View File

@ -40,7 +40,7 @@ impl SccIntersectionsAndLengthPresorter {
params: &PresortParams,
) -> Self {
// FIXME: Unnecessary copy.
let mut filtered_ratsnest = autorouter.ratsnest().graph().clone();
let mut filtered_ratsnest = autorouter.ratsnests().on_principal_layer(0).graph().clone();
filtered_ratsnest.retain_edges(|_g, i| ratlines.contains(&i));
let mut sccs: Vec<_> = tarjan_scc(&filtered_ratsnest)

View File

@ -46,7 +46,8 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
pub fn band_termseg(&self) -> BandTermsegIndex {
self.autorouter
.ratsnest()
.ratsnests()
.on_principal_layer(0)
.graph()
.edge_weight(self.index)
.unwrap()
@ -57,14 +58,16 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
pub fn endpoint_dots(&self) -> (FixedDotIndex, FixedDotIndex) {
let (source, target) = self
.autorouter
.ratsnest
.ratsnests()
.on_principal_layer(0)
.graph()
.edge_endpoints(self.index)
.unwrap();
let source_dot = match self
.autorouter
.ratsnest
.ratsnests()
.on_principal_layer(0)
.graph()
.node_weight(source)
.unwrap()
@ -76,7 +79,8 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
let target_dot = match self
.autorouter
.ratsnest
.ratsnests()
.on_principal_layer(0)
.graph()
.node_weight(target)
.unwrap()
@ -92,14 +96,16 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
pub fn terminating_dots(&self) -> (FixedDotIndex, FixedDotIndex) {
let (source, target) = self
.autorouter
.ratsnest
.ratsnests()
.on_principal_layer(0)
.graph()
.edge_endpoints(self.index)
.unwrap();
let source_dot = self
.autorouter
.ratsnest
.ratsnests()
.on_principal_layer(0)
.graph()
.node_weight(source)
.unwrap()
@ -109,7 +115,8 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
.unwrap_or(self.endpoint_dots().0);
let target_dot = self
.autorouter
.ratsnest
.ratsnests()
.on_principal_layer(0)
.graph()
.node_weight(target)
.unwrap()
@ -123,15 +130,12 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
pub fn layer(&self) -> usize {
self.autorouter
.ratsnest()
.ratsnests()
.on_principal_layer(0)
.graph()
.edge_weight(self.index)
.unwrap()
.layer
/*self.endpoint_dots()
.0
.primitive_ref(self.autorouter.board().layout().drawing())
.layer()*/
}
pub fn net(&self) -> usize {
@ -164,7 +168,8 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
let self_line_segment = self.line_segment();
self.autorouter
.ratsnest()
.ratsnests()
.on_principal_layer(0)
.graph()
.edge_indices()
.filter(move |other| {
@ -195,14 +200,16 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
let (source, target) = self.endpoint_indices();
let source_pos = self
.autorouter
.ratsnest
.ratsnests()
.on_principal_layer(0)
.graph()
.node_weight(source)
.unwrap()
.pos;
let target_pos = self
.autorouter
.ratsnest
.ratsnests()
.on_principal_layer(0)
.graph()
.node_weight(target)
.unwrap()
@ -213,7 +220,8 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
pub fn endpoint_indices(&self) -> (NodeIndex<usize>, NodeIndex<usize>) {
self.autorouter
.ratsnest
.ratsnests()
.on_principal_layer(0)
.graph()
.edge_endpoints(self.index)
.unwrap()

View File

@ -0,0 +1,24 @@
// SPDX-FileCopyrightText: 2025 Topola contributors
//
// SPDX-License-Identifier: MIT
use spade::InsertionError;
use specctra_core::mesadata::AccessMesadata;
use crate::{autorouter::ratsnest::Ratsnest, board::Board};
pub struct Ratsnests(Box<[Ratsnest]>);
impl Ratsnests {
pub fn new(board: &Board<impl AccessMesadata>) -> Result<Self, InsertionError> {
Ok(Self(Box::new([Ratsnest::new(board)?])))
}
pub fn on_principal_layer(&self, principal_layer: usize) -> &Ratsnest {
&self.0[principal_layer]
}
pub fn on_principal_layer_mut(&mut self, principal_layer: usize) -> &mut Ratsnest {
&mut self.0[principal_layer]
}
}

View File

@ -78,7 +78,8 @@ impl<'a, M: AccessMesadata> SccRef<'a, M> {
self.scc.node_indices().contains(
&self
.autorouter
.ratsnest()
.ratsnests()
.on_principal_layer(0)
.graph()
.edge_endpoints(ratline)
.unwrap()
@ -86,7 +87,8 @@ impl<'a, M: AccessMesadata> SccRef<'a, M> {
) && self.scc.node_indices().contains(
&self
.autorouter
.ratsnest()
.ratsnests()
.on_principal_layer(0)
.graph()
.edge_endpoints(ratline)
.unwrap()