mirror of https://codeberg.org/topola/topola.git
108 lines
3.1 KiB
Rust
108 lines
3.1 KiB
Rust
// SPDX-FileCopyrightText: 2025 Topola contributors
|
|
//
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
use std::collections::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,
|
|
};
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct PlanarAutoroutePreconfigurerInput {
|
|
pub ratlines: BTreeSet<RatlineUid>,
|
|
}
|
|
|
|
pub struct PresortParams {
|
|
pub intersector_count_weight: f64,
|
|
pub length_weight: f64,
|
|
}
|
|
|
|
#[enum_dispatch]
|
|
pub trait PreconfigurePlanarAutoroute {
|
|
fn preconfigure(
|
|
&self,
|
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
|
input: PlanarAutoroutePreconfigurerInput,
|
|
) -> PlanarAutorouteConfiguration;
|
|
}
|
|
|
|
#[enum_dispatch(PresortRatlines)]
|
|
pub enum PlanarAutoroutePreconfigurer {
|
|
SccIntersectionsLength(SccIntersectionsAndLengthRatlinePlanarAutoroutePreconfigurer),
|
|
}
|
|
|
|
#[derive(Getters, Dissolve)]
|
|
pub struct SccIntersectionsAndLengthRatlinePlanarAutoroutePreconfigurer {
|
|
sccs: Vec<Scc>,
|
|
}
|
|
|
|
impl SccIntersectionsAndLengthRatlinePlanarAutoroutePreconfigurer {
|
|
pub fn new(
|
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
|
input: PlanarAutoroutePreconfigurerInput,
|
|
params: &PresortParams,
|
|
options: &PlanarAutorouteOptions,
|
|
) -> Self {
|
|
// FIXME: Unnecessary copy.
|
|
let mut filtered_ratsnest = autorouter
|
|
.ratsnests()
|
|
.on_principal_layer(options.principal_layer)
|
|
.graph()
|
|
.clone();
|
|
filtered_ratsnest
|
|
.retain_edges(|_g, i| input.ratlines.iter().any(|ratline| ratline.index == i));
|
|
|
|
let mut sccs: Vec<_> = tarjan_scc(&filtered_ratsnest)
|
|
.into_iter()
|
|
.map(|node_indices| {
|
|
Scc::new(
|
|
autorouter,
|
|
&input.ratlines,
|
|
&filtered_ratsnest,
|
|
node_indices,
|
|
)
|
|
})
|
|
.collect();
|
|
|
|
sccs.sort_unstable_by(|a, b| {
|
|
Self::scc_score(params, a).total_cmp(&Self::scc_score(params, b))
|
|
});
|
|
|
|
Self { sccs }
|
|
}
|
|
|
|
fn scc_score(params: &PresortParams, scc: &Scc) -> f64 {
|
|
params.intersector_count_weight * *scc.intersector_count() as f64
|
|
+ params.length_weight * scc.length()
|
|
}
|
|
}
|
|
|
|
impl PreconfigurePlanarAutoroute for SccIntersectionsAndLengthRatlinePlanarAutoroutePreconfigurer {
|
|
fn preconfigure(
|
|
&self,
|
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
|
input: PlanarAutoroutePreconfigurerInput,
|
|
) -> PlanarAutorouteConfiguration {
|
|
let mut presorted_ratlines = vec![];
|
|
|
|
for scc in self.sccs.iter() {
|
|
for ratline in input.ratlines.iter() {
|
|
if scc.scc_ref(autorouter).contains(*ratline) {
|
|
presorted_ratlines.push(*ratline);
|
|
}
|
|
}
|
|
}
|
|
|
|
PlanarAutorouteConfiguration {
|
|
ratlines: presorted_ratlines,
|
|
}
|
|
}
|
|
}
|