mirror of https://codeberg.org/topola/topola.git
feat(autorouter/autorouter): Have separate ratsnest for each (principal) layer
This commit is contained in:
parent
1b578f3063
commit
8f59319902
|
|
@ -36,6 +36,7 @@ allowed_scopes = [
|
||||||
"autorouter/pointroute",
|
"autorouter/pointroute",
|
||||||
"autorouter/presorter",
|
"autorouter/presorter",
|
||||||
"autorouter/ratsnest",
|
"autorouter/ratsnest",
|
||||||
|
"autorouter/ratsnests",
|
||||||
"autorouter/ratline",
|
"autorouter/ratline",
|
||||||
"autorouter/remove_bands",
|
"autorouter/remove_bands",
|
||||||
"autorouter/selection",
|
"autorouter/selection",
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,15 @@ pub trait AccessMesadata: AccessRules + std::panic::RefUnwindSafe {
|
||||||
/// Renames a layer based on its index.
|
/// Renames a layer based on its index.
|
||||||
fn bename_layer(&mut self, layer: usize, layername: String);
|
fn bename_layer(&mut self, layer: usize, layername: String);
|
||||||
|
|
||||||
/// Retrieves the name of a layer by its index.
|
/// Retrieves the name of a layer from its index.
|
||||||
fn layer_layername(&self, layer: usize) -> Option<&str>;
|
fn layer_layername(&self, layer: usize) -> Option<&str>;
|
||||||
|
|
||||||
/// Retrieves the index of a layer by its name.
|
/// Retrieves the index of a layer from its name.
|
||||||
fn layername_layer(&self, layername: &str) -> Option<usize>;
|
fn layername_layer(&self, layername: &str) -> Option<usize>;
|
||||||
|
|
||||||
|
/// Return the number of the layers.
|
||||||
|
fn layer_count(&self) -> usize;
|
||||||
|
|
||||||
/// Renames a net based on its index.
|
/// Renames a net based on its index.
|
||||||
fn bename_net(&mut self, net: usize, netname: String);
|
fn bename_net(&mut self, net: usize, netname: String);
|
||||||
|
|
||||||
|
|
@ -76,15 +79,18 @@ pub struct SpecctraMesadata {
|
||||||
/// These rules are applied to all nets belonging to the respective net clas
|
/// These rules are applied to all nets belonging to the respective net clas
|
||||||
class_rules: BTreeMap<String, SpecctraRule>,
|
class_rules: BTreeMap<String, SpecctraRule>,
|
||||||
|
|
||||||
|
/// Number of layers.
|
||||||
|
layer_count: usize,
|
||||||
|
|
||||||
// layername <-> layer for Layout
|
// layername <-> layer for Layout
|
||||||
/// A bidirectional map between layer indices and layer names, allowing translation
|
/// A bidirectional map between layer indices and layer names, allowing translation
|
||||||
/// between index-based layers in the layout and user-defined layer names.
|
/// between index-based layers in the layout and user-defined layer names.
|
||||||
pub layer_layername: BiBTreeMap<usize, String>,
|
layer_layername: BiBTreeMap<usize, String>,
|
||||||
|
|
||||||
// netname <-> net for Layout
|
// netname <-> net for Layout
|
||||||
/// A bidirectional map between network indices and network names in the PCB layout,
|
/// A bidirectional map between network indices and network names in the PCB layout,
|
||||||
/// providing an easy way to reference nets by name or index.
|
/// providing an easy way to reference nets by name or index.
|
||||||
pub net_netname: BiBTreeMap<usize, String>,
|
net_netname: BiBTreeMap<usize, String>,
|
||||||
|
|
||||||
// net -> netclass
|
// net -> netclass
|
||||||
/// A map that associates network indices with their respective net class names.
|
/// A map that associates network indices with their respective net class names.
|
||||||
|
|
@ -105,6 +111,7 @@ impl SpecctraMesadata {
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(index, layer)| (index, layer.name.clone())),
|
.map(|(index, layer)| (index, layer.name.clone())),
|
||||||
);
|
);
|
||||||
|
let layer_count = pcb.structure.layers.len();
|
||||||
|
|
||||||
// assign IDs to all nets named in pcb.network
|
// assign IDs to all nets named in pcb.network
|
||||||
let net_netname = {
|
let net_netname = {
|
||||||
|
|
@ -157,6 +164,7 @@ impl SpecctraMesadata {
|
||||||
structure_rule: SpecctraRule::from_dsn(&structure_rule),
|
structure_rule: SpecctraRule::from_dsn(&structure_rule),
|
||||||
class_rules,
|
class_rules,
|
||||||
layer_layername,
|
layer_layername,
|
||||||
|
layer_count,
|
||||||
net_netname,
|
net_netname,
|
||||||
net_netclass,
|
net_netclass,
|
||||||
}
|
}
|
||||||
|
|
@ -204,6 +212,10 @@ impl AccessMesadata for SpecctraMesadata {
|
||||||
self.layer_layername.get_by_right(layername).copied()
|
self.layer_layername.get_by_right(layername).copied()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn layer_count(&self) -> usize {
|
||||||
|
self.layer_count
|
||||||
|
}
|
||||||
|
|
||||||
fn bename_net(&mut self, net: usize, netname: String) {
|
fn bename_net(&mut self, net: usize, netname: String) {
|
||||||
self.net_netname.insert(net, netname);
|
self.net_netname.insert(net, netname);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ impl<'a> Displayer<'a> {
|
||||||
self.display_layout(ctx);
|
self.display_layout(ctx);
|
||||||
|
|
||||||
if menu_bar.show_ratsnest {
|
if menu_bar.show_ratsnest {
|
||||||
self.display_ratsnest();
|
self.display_ratsnest(menu_bar);
|
||||||
}
|
}
|
||||||
|
|
||||||
if menu_bar.show_navmesh || menu_bar.show_guide_circles || menu_bar.show_guide_bitangents {
|
if menu_bar.show_navmesh || menu_bar.show_guide_circles || menu_bar.show_guide_bitangents {
|
||||||
|
|
@ -161,14 +161,14 @@ impl<'a> Displayer<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn display_ratsnest(&mut self) {
|
fn display_ratsnest(&mut self, menu_bar: &MenuBar) {
|
||||||
let graph = self
|
let graph = self
|
||||||
.workspace
|
.workspace
|
||||||
.interactor
|
.interactor
|
||||||
.invoker()
|
.invoker()
|
||||||
.autorouter()
|
.autorouter()
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(menu_bar.multilayer_autoroute_options.planar.principal_layer)
|
||||||
.graph();
|
.graph();
|
||||||
for edge in graph.edge_references() {
|
for edge in graph.edge_references() {
|
||||||
if edge.weight().band_termseg.is_some() {
|
if edge.weight().band_termseg.is_some() {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use geo::{point, Distance, Euclidean, Point};
|
use geo::{point, Distance, Euclidean, Point};
|
||||||
use petgraph::graph::{EdgeIndex, NodeIndex};
|
use petgraph::graph::NodeIndex;
|
||||||
use rstar::{Envelope, RTreeObject, AABB};
|
use rstar::{Envelope, RTreeObject, AABB};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use specctra_core::mesadata::AccessMesadata;
|
use specctra_core::mesadata::AccessMesadata;
|
||||||
|
|
@ -13,7 +13,7 @@ use specctra_core::mesadata::AccessMesadata;
|
||||||
use crate::{
|
use crate::{
|
||||||
autorouter::{
|
autorouter::{
|
||||||
compass_direction::{CardinalDirection, CompassDirection, OrdinalDirection},
|
compass_direction::{CardinalDirection, CompassDirection, OrdinalDirection},
|
||||||
ratline::RatlineIndex,
|
ratline::RatlineUid,
|
||||||
Autorouter,
|
Autorouter,
|
||||||
},
|
},
|
||||||
board::edit::BoardEdit,
|
board::edit::BoardEdit,
|
||||||
|
|
@ -42,7 +42,7 @@ pub enum TerminatingScheme {
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct AnterouterPlan {
|
pub struct AnterouterPlan {
|
||||||
pub layer_map: BTreeMap<RatlineIndex, usize>,
|
pub layer_map: BTreeMap<RatlineUid, usize>,
|
||||||
pub ratline_endpoint_dot_to_terminating_scheme: BTreeMap<FixedDotIndex, TerminatingScheme>,
|
pub ratline_endpoint_dot_to_terminating_scheme: BTreeMap<FixedDotIndex, TerminatingScheme>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,8 +67,8 @@ impl Anterouter {
|
||||||
|
|
||||||
autorouter
|
autorouter
|
||||||
.ratsnests
|
.ratsnests
|
||||||
.on_principal_layer_mut(0)
|
.on_principal_layer_mut(ratline.principal_layer)
|
||||||
.assign_layer_to_ratline(*ratline, *layer);
|
.assign_layer_to_ratline(ratline.index, *layer);
|
||||||
|
|
||||||
if let Some(terminating_scheme) = self
|
if let Some(terminating_scheme) = self
|
||||||
.plan
|
.plan
|
||||||
|
|
@ -126,7 +126,7 @@ impl Anterouter {
|
||||||
&mut self,
|
&mut self,
|
||||||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
ratvertex: NodeIndex<usize>,
|
ratvertex: NodeIndex<usize>,
|
||||||
ratline: EdgeIndex<usize>,
|
ratline: RatlineUid,
|
||||||
source_dot: FixedDotIndex,
|
source_dot: FixedDotIndex,
|
||||||
target_layer: usize,
|
target_layer: usize,
|
||||||
options: &AnterouterOptions,
|
options: &AnterouterOptions,
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ use super::{
|
||||||
place_via::PlaceViaExecutionStepper,
|
place_via::PlaceViaExecutionStepper,
|
||||||
planar_autoroute::PlanarAutorouteExecutionStepper,
|
planar_autoroute::PlanarAutorouteExecutionStepper,
|
||||||
pointroute::PointrouteExecutionStepper,
|
pointroute::PointrouteExecutionStepper,
|
||||||
ratline::RatlineIndex,
|
ratline::RatlineUid,
|
||||||
ratsnest::RatvertexNodeIndex,
|
ratsnest::RatvertexNodeIndex,
|
||||||
remove_bands::RemoveBandsExecutionStepper,
|
remove_bands::RemoveBandsExecutionStepper,
|
||||||
selection::{BandSelection, PinSelection},
|
selection::{BandSelection, PinSelection},
|
||||||
|
|
@ -89,7 +89,9 @@ impl<M: AccessMesadata> Autorouter<M> {
|
||||||
point: Point,
|
point: Point,
|
||||||
options: PlanarAutorouteOptions,
|
options: PlanarAutorouteOptions,
|
||||||
) -> Result<PointrouteExecutionStepper, AutorouterError> {
|
) -> Result<PointrouteExecutionStepper, AutorouterError> {
|
||||||
let ratvertex = self.find_selected_ratvertex(selection).unwrap();
|
let ratvertex = self
|
||||||
|
.find_selected_ratvertex(selection, options.principal_layer)
|
||||||
|
.unwrap();
|
||||||
let origin_dot = match self
|
let origin_dot = match self
|
||||||
.ratsnests
|
.ratsnests
|
||||||
.on_principal_layer_mut(0)
|
.on_principal_layer_mut(0)
|
||||||
|
|
@ -117,11 +119,14 @@ impl<M: AccessMesadata> Autorouter<M> {
|
||||||
selection: &PinSelection,
|
selection: &PinSelection,
|
||||||
options: MultilayerAutorouteOptions,
|
options: MultilayerAutorouteOptions,
|
||||||
) -> Result<MultilayerAutorouteExecutionStepper, AutorouterError> {
|
) -> Result<MultilayerAutorouteExecutionStepper, AutorouterError> {
|
||||||
let planner = Planner::new(self, &self.selected_ratlines(selection));
|
let planner = Planner::new(
|
||||||
|
self,
|
||||||
|
&self.selected_ratlines(selection, options.planar.principal_layer),
|
||||||
|
);
|
||||||
|
|
||||||
MultilayerAutorouteExecutionStepper::new(
|
MultilayerAutorouteExecutionStepper::new(
|
||||||
self,
|
self,
|
||||||
self.selected_ratlines(selection),
|
self.selected_ratlines(selection, options.planar.principal_layer),
|
||||||
planner.plan().clone(),
|
planner.plan().clone(),
|
||||||
options,
|
options,
|
||||||
)
|
)
|
||||||
|
|
@ -132,27 +137,24 @@ impl<M: AccessMesadata> Autorouter<M> {
|
||||||
selection: &PinSelection,
|
selection: &PinSelection,
|
||||||
options: PlanarAutorouteOptions,
|
options: PlanarAutorouteOptions,
|
||||||
) -> Result<PlanarAutorouteExecutionPermutator, AutorouterError> {
|
) -> Result<PlanarAutorouteExecutionPermutator, AutorouterError> {
|
||||||
PlanarAutorouteExecutionPermutator::new(self, self.selected_ratlines(selection), options)
|
PlanarAutorouteExecutionPermutator::new(
|
||||||
|
self,
|
||||||
|
self.selected_ratlines(selection, options.principal_layer),
|
||||||
|
options,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn planar_autoroute_ratlines(
|
pub(super) fn planar_autoroute_ratlines(
|
||||||
&mut self,
|
&mut self,
|
||||||
ratlines: Vec<RatlineIndex>,
|
ratlines: Vec<RatlineUid>,
|
||||||
options: PlanarAutorouteOptions,
|
options: PlanarAutorouteOptions,
|
||||||
) -> Result<PlanarAutorouteExecutionStepper, AutorouterError> {
|
) -> Result<PlanarAutorouteExecutionStepper, AutorouterError> {
|
||||||
PlanarAutorouteExecutionStepper::new(self, ratlines, options)
|
PlanarAutorouteExecutionStepper::new(self, ratlines, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn undo_planar_autoroute(
|
|
||||||
&mut self,
|
|
||||||
selection: &PinSelection,
|
|
||||||
) -> Result<(), AutorouterError> {
|
|
||||||
self.undo_planar_autoroute_ratlines(self.selected_ratlines(selection))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn undo_planar_autoroute_ratlines(
|
pub(super) fn undo_planar_autoroute_ratlines(
|
||||||
&mut self,
|
&mut self,
|
||||||
ratlines: Vec<RatlineIndex>,
|
ratlines: Vec<RatlineUid>,
|
||||||
) -> Result<(), AutorouterError> {
|
) -> Result<(), AutorouterError> {
|
||||||
for ratline in ratlines.iter() {
|
for ratline in ratlines.iter() {
|
||||||
let band = ratline.ref_(self).band_termseg();
|
let band = ratline.ref_(self).band_termseg();
|
||||||
|
|
@ -177,7 +179,7 @@ impl<M: AccessMesadata> Autorouter<M> {
|
||||||
M: Clone,
|
M: Clone,
|
||||||
{
|
{
|
||||||
self.topo_autoroute_ratlines(
|
self.topo_autoroute_ratlines(
|
||||||
self.selected_ratlines(selection),
|
self.selected_ratlines(selection, active_layer),
|
||||||
allowed_edges,
|
allowed_edges,
|
||||||
active_layer,
|
active_layer,
|
||||||
width,
|
width,
|
||||||
|
|
@ -187,7 +189,7 @@ impl<M: AccessMesadata> Autorouter<M> {
|
||||||
|
|
||||||
pub(super) fn topo_autoroute_ratlines(
|
pub(super) fn topo_autoroute_ratlines(
|
||||||
&mut self,
|
&mut self,
|
||||||
ratlines: Vec<RatlineIndex>,
|
ratlines: Vec<RatlineUid>,
|
||||||
allowed_edges: BTreeSet<ng::PieEdgeIndex>,
|
allowed_edges: BTreeSet<ng::PieEdgeIndex>,
|
||||||
active_layer: usize,
|
active_layer: usize,
|
||||||
width: f64,
|
width: f64,
|
||||||
|
|
@ -281,7 +283,7 @@ impl<M: AccessMesadata> Autorouter<M> {
|
||||||
selection: &PinSelection,
|
selection: &PinSelection,
|
||||||
options: PlanarAutorouteOptions,
|
options: PlanarAutorouteOptions,
|
||||||
) -> Result<CompareDetoursExecutionStepper, AutorouterError> {
|
) -> Result<CompareDetoursExecutionStepper, AutorouterError> {
|
||||||
let ratlines = self.selected_ratlines(selection);
|
let ratlines = self.selected_ratlines(selection, options.principal_layer);
|
||||||
if ratlines.len() < 2 {
|
if ratlines.len() < 2 {
|
||||||
return Err(AutorouterError::NeedExactlyTwoRatlines);
|
return Err(AutorouterError::NeedExactlyTwoRatlines);
|
||||||
}
|
}
|
||||||
|
|
@ -290,8 +292,8 @@ impl<M: AccessMesadata> Autorouter<M> {
|
||||||
|
|
||||||
pub(super) fn compare_detours_ratlines(
|
pub(super) fn compare_detours_ratlines(
|
||||||
&mut self,
|
&mut self,
|
||||||
ratline1: RatlineIndex,
|
ratline1: RatlineUid,
|
||||||
ratline2: RatlineIndex,
|
ratline2: RatlineUid,
|
||||||
options: PlanarAutorouteOptions,
|
options: PlanarAutorouteOptions,
|
||||||
) -> Result<CompareDetoursExecutionStepper, AutorouterError> {
|
) -> Result<CompareDetoursExecutionStepper, AutorouterError> {
|
||||||
CompareDetoursExecutionStepper::new(self, ratline1, ratline2, options)
|
CompareDetoursExecutionStepper::new(self, ratline1, ratline2, options)
|
||||||
|
|
@ -304,29 +306,33 @@ impl<M: AccessMesadata> Autorouter<M> {
|
||||||
MeasureLengthExecutionStepper::new(selection)
|
MeasureLengthExecutionStepper::new(selection)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn selected_ratlines(&self, selection: &PinSelection) -> Vec<RatlineIndex> {
|
pub(super) fn selected_ratlines(
|
||||||
|
&self,
|
||||||
|
selection: &PinSelection,
|
||||||
|
principal_layer: usize,
|
||||||
|
) -> Vec<RatlineUid> {
|
||||||
self.ratsnests()
|
self.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.edge_indices()
|
.edge_indices()
|
||||||
.filter(|ratline| {
|
.filter(|index| {
|
||||||
let (source, target) = self
|
let (source, target) = self
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.edge_endpoints(*ratline)
|
.edge_endpoints(*index)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let source_ratvertex = self
|
let source_ratvertex = self
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.node_weight(source)
|
.node_weight(source)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.node_index();
|
.node_index();
|
||||||
let to_ratvertex = self
|
let to_ratvertex = self
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.node_weight(target)
|
.node_weight(target)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
@ -335,19 +341,27 @@ impl<M: AccessMesadata> Autorouter<M> {
|
||||||
selection.contains_node(&self.board, source_ratvertex.into())
|
selection.contains_node(&self.board, source_ratvertex.into())
|
||||||
&& selection.contains_node(&self.board, to_ratvertex.into())
|
&& selection.contains_node(&self.board, to_ratvertex.into())
|
||||||
})
|
})
|
||||||
|
.map(|index| RatlineUid {
|
||||||
|
principal_layer,
|
||||||
|
index,
|
||||||
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_selected_ratvertex(&self, selection: &PinSelection) -> Option<NodeIndex<usize>> {
|
fn find_selected_ratvertex(
|
||||||
|
&self,
|
||||||
|
selection: &PinSelection,
|
||||||
|
principal_layer: usize,
|
||||||
|
) -> Option<NodeIndex<usize>> {
|
||||||
self.ratsnests()
|
self.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.node_indices()
|
.node_indices()
|
||||||
.find(|ratvertex| {
|
.find(|ratvertex| {
|
||||||
selection.contains_node(
|
selection.contains_node(
|
||||||
&self.board,
|
&self.board,
|
||||||
self.ratsnests()
|
self.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.node_weight(*ratvertex)
|
.node_weight(*ratvertex)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
|
||||||
|
|
@ -19,15 +19,15 @@ use crate::{
|
||||||
use super::{
|
use super::{
|
||||||
invoker::GetDebugOverlayData,
|
invoker::GetDebugOverlayData,
|
||||||
planar_autoroute::{PlanarAutorouteContinueStatus, PlanarAutorouteExecutionStepper},
|
planar_autoroute::{PlanarAutorouteContinueStatus, PlanarAutorouteExecutionStepper},
|
||||||
ratline::RatlineIndex,
|
ratline::RatlineUid,
|
||||||
Autorouter, AutorouterError, PlanarAutorouteOptions,
|
Autorouter, AutorouterError, PlanarAutorouteOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct CompareDetoursExecutionStepper {
|
pub struct CompareDetoursExecutionStepper {
|
||||||
autoroute: PlanarAutorouteExecutionStepper,
|
autoroute: PlanarAutorouteExecutionStepper,
|
||||||
next_autoroute: Option<PlanarAutorouteExecutionStepper>,
|
next_autoroute: Option<PlanarAutorouteExecutionStepper>,
|
||||||
ratline1: RatlineIndex,
|
ratline1: RatlineUid,
|
||||||
ratline2: RatlineIndex,
|
ratline2: RatlineUid,
|
||||||
total_length1: f64,
|
total_length1: f64,
|
||||||
total_length2: f64,
|
total_length2: f64,
|
||||||
done: bool,
|
done: bool,
|
||||||
|
|
@ -36,8 +36,8 @@ pub struct CompareDetoursExecutionStepper {
|
||||||
impl CompareDetoursExecutionStepper {
|
impl CompareDetoursExecutionStepper {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
ratline1: RatlineIndex,
|
ratline1: RatlineUid,
|
||||||
ratline2: RatlineIndex,
|
ratline2: RatlineUid,
|
||||||
options: PlanarAutorouteOptions,
|
options: PlanarAutorouteOptions,
|
||||||
) -> Result<Self, AutorouterError> {
|
) -> Result<Self, AutorouterError> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
|
|
||||||
|
|
@ -178,27 +178,27 @@ impl<M: AccessMesadata + Clone> Invoker<M> {
|
||||||
Command::TopoAutoroute {
|
Command::TopoAutoroute {
|
||||||
selection,
|
selection,
|
||||||
allowed_edges,
|
allowed_edges,
|
||||||
active_layer,
|
active_layer: active_layer_name,
|
||||||
routed_band_width,
|
routed_band_width,
|
||||||
} => {
|
} => {
|
||||||
let ratlines = self.autorouter.selected_ratlines(selection);
|
let active_layer = self
|
||||||
|
.autorouter
|
||||||
|
.board
|
||||||
|
.layout()
|
||||||
|
.rules()
|
||||||
|
.layername_layer(active_layer_name)
|
||||||
|
.unwrap();
|
||||||
|
let ratlines = self.autorouter.selected_ratlines(selection, active_layer);
|
||||||
|
|
||||||
// TODO: consider "presort by pairwise detours"
|
// TODO: consider "presort by pairwise detours"
|
||||||
|
|
||||||
ExecutionStepper::TopoAutoroute(
|
ExecutionStepper::TopoAutoroute(self.autorouter.topo_autoroute_ratlines(
|
||||||
self.autorouter.topo_autoroute_ratlines(
|
ratlines,
|
||||||
ratlines,
|
allowed_edges.clone(),
|
||||||
allowed_edges.clone(),
|
active_layer,
|
||||||
self.autorouter
|
*routed_band_width,
|
||||||
.board
|
None,
|
||||||
.layout()
|
)?)
|
||||||
.rules()
|
|
||||||
.layername_layer(active_layer)
|
|
||||||
.unwrap(),
|
|
||||||
*routed_band_width,
|
|
||||||
None,
|
|
||||||
)?,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Command::PlaceVia(weight) => {
|
Command::PlaceVia(weight) => {
|
||||||
ExecutionStepper::PlaceVia(self.autorouter.place_via(*weight)?)
|
ExecutionStepper::PlaceVia(self.autorouter.place_via(*weight)?)
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use crate::{
|
||||||
invoker::GetDebugOverlayData,
|
invoker::GetDebugOverlayData,
|
||||||
permutator::PlanarAutorouteExecutionPermutator,
|
permutator::PlanarAutorouteExecutionPermutator,
|
||||||
planar_autoroute::PlanarAutorouteContinueStatus,
|
planar_autoroute::PlanarAutorouteContinueStatus,
|
||||||
ratline::RatlineIndex,
|
ratline::RatlineUid,
|
||||||
Autorouter, AutorouterError, PlanarAutorouteOptions,
|
Autorouter, AutorouterError, PlanarAutorouteOptions,
|
||||||
},
|
},
|
||||||
board::edit::BoardEdit,
|
board::edit::BoardEdit,
|
||||||
|
|
@ -36,7 +36,7 @@ pub struct MultilayerAutorouteExecutionStepper {
|
||||||
impl MultilayerAutorouteExecutionStepper {
|
impl MultilayerAutorouteExecutionStepper {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
ratlines: Vec<RatlineIndex>,
|
ratlines: Vec<RatlineUid>,
|
||||||
plan: AnterouterPlan,
|
plan: AnterouterPlan,
|
||||||
options: MultilayerAutorouteOptions,
|
options: MultilayerAutorouteOptions,
|
||||||
) -> Result<Self, AutorouterError> {
|
) -> Result<Self, AutorouterError> {
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use crate::{
|
||||||
permuter::{PermuteRatlines, RatlinesPermuter},
|
permuter::{PermuteRatlines, RatlinesPermuter},
|
||||||
planar_autoroute::{PlanarAutorouteContinueStatus, PlanarAutorouteExecutionStepper},
|
planar_autoroute::{PlanarAutorouteContinueStatus, PlanarAutorouteExecutionStepper},
|
||||||
presorter::{PresortParams, PresortRatlines, SccIntersectionsAndLengthPresorter},
|
presorter::{PresortParams, PresortRatlines, SccIntersectionsAndLengthPresorter},
|
||||||
ratline::RatlineIndex,
|
ratline::RatlineUid,
|
||||||
Autorouter, AutorouterError, PlanarAutorouteOptions,
|
Autorouter, AutorouterError, PlanarAutorouteOptions,
|
||||||
},
|
},
|
||||||
board::edit::BoardEdit,
|
board::edit::BoardEdit,
|
||||||
|
|
@ -31,7 +31,7 @@ pub struct PlanarAutorouteExecutionPermutator {
|
||||||
impl PlanarAutorouteExecutionPermutator {
|
impl PlanarAutorouteExecutionPermutator {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
ratlines: Vec<RatlineIndex>,
|
ratlines: Vec<RatlineUid>,
|
||||||
options: PlanarAutorouteOptions,
|
options: PlanarAutorouteOptions,
|
||||||
) -> Result<Self, AutorouterError> {
|
) -> Result<Self, AutorouterError> {
|
||||||
let presorter = SccIntersectionsAndLengthPresorter::new(
|
let presorter = SccIntersectionsAndLengthPresorter::new(
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use specctra_core::mesadata::AccessMesadata;
|
||||||
use crate::{
|
use crate::{
|
||||||
autorouter::{
|
autorouter::{
|
||||||
planar_autoroute::PlanarAutorouteExecutionStepper,
|
planar_autoroute::PlanarAutorouteExecutionStepper,
|
||||||
presorter::SccIntersectionsAndLengthPresorter, ratline::RatlineIndex, scc::Scc, Autorouter,
|
presorter::SccIntersectionsAndLengthPresorter, ratline::RatlineUid, scc::Scc, Autorouter,
|
||||||
PlanarAutorouteOptions,
|
PlanarAutorouteOptions,
|
||||||
},
|
},
|
||||||
drawing::graph::MakePrimitiveRef,
|
drawing::graph::MakePrimitiveRef,
|
||||||
|
|
@ -25,7 +25,7 @@ pub trait PermuteRatlines {
|
||||||
&mut self,
|
&mut self,
|
||||||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
stepper: &PlanarAutorouteExecutionStepper,
|
stepper: &PlanarAutorouteExecutionStepper,
|
||||||
) -> Option<Vec<RatlineIndex>>;
|
) -> Option<Vec<RatlineUid>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch(PermuteRatlines)]
|
#[enum_dispatch(PermuteRatlines)]
|
||||||
|
|
@ -37,7 +37,7 @@ pub enum RatlinesPermuter {
|
||||||
impl RatlinesPermuter {
|
impl RatlinesPermuter {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
ratlines: Vec<RatlineIndex>,
|
ratlines: Vec<RatlineUid>,
|
||||||
presorter: SccIntersectionsAndLengthPresorter,
|
presorter: SccIntersectionsAndLengthPresorter,
|
||||||
options: &PlanarAutorouteOptions,
|
options: &PlanarAutorouteOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
@ -52,13 +52,13 @@ impl RatlinesPermuter {
|
||||||
|
|
||||||
pub struct SccPermutationsRatlinePermuter {
|
pub struct SccPermutationsRatlinePermuter {
|
||||||
sccs_permutations_iter: Skip<Permutations<std::vec::IntoIter<Scc>>>,
|
sccs_permutations_iter: Skip<Permutations<std::vec::IntoIter<Scc>>>,
|
||||||
original_ratlines: Vec<RatlineIndex>,
|
original_ratlines: Vec<RatlineUid>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SccPermutationsRatlinePermuter {
|
impl SccPermutationsRatlinePermuter {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
_autorouter: &mut Autorouter<impl AccessMesadata>,
|
_autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
ratlines: Vec<RatlineIndex>,
|
ratlines: Vec<RatlineUid>,
|
||||||
presorter: SccIntersectionsAndLengthPresorter,
|
presorter: SccIntersectionsAndLengthPresorter,
|
||||||
_options: &PlanarAutorouteOptions,
|
_options: &PlanarAutorouteOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
@ -79,7 +79,7 @@ impl PermuteRatlines for SccPermutationsRatlinePermuter {
|
||||||
&mut self,
|
&mut self,
|
||||||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
_stepper: &PlanarAutorouteExecutionStepper,
|
_stepper: &PlanarAutorouteExecutionStepper,
|
||||||
) -> Option<Vec<RatlineIndex>> {
|
) -> Option<Vec<RatlineUid>> {
|
||||||
let scc_permutation = self.sccs_permutations_iter.next()?;
|
let scc_permutation = self.sccs_permutations_iter.next()?;
|
||||||
let mut ratlines = vec![];
|
let mut ratlines = vec![];
|
||||||
|
|
||||||
|
|
@ -88,17 +88,17 @@ impl PermuteRatlines for SccPermutationsRatlinePermuter {
|
||||||
if scc.node_indices().contains(
|
if scc.node_indices().contains(
|
||||||
&autorouter
|
&autorouter
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(ratline.principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.edge_endpoints(*ratline)
|
.edge_endpoints(ratline.index)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0,
|
.0,
|
||||||
) && scc.node_indices().contains(
|
) && scc.node_indices().contains(
|
||||||
&autorouter
|
&autorouter
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(ratline.principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.edge_endpoints(*ratline)
|
.edge_endpoints(ratline.index)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.1,
|
.1,
|
||||||
) {
|
) {
|
||||||
|
|
@ -118,7 +118,7 @@ pub struct RatlineCutsRatlinePermuter {
|
||||||
impl RatlineCutsRatlinePermuter {
|
impl RatlineCutsRatlinePermuter {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
_autorouter: &mut Autorouter<impl AccessMesadata>,
|
_autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
_ratlines: Vec<RatlineIndex>,
|
_ratlines: Vec<RatlineUid>,
|
||||||
_presorter: SccIntersectionsAndLengthPresorter,
|
_presorter: SccIntersectionsAndLengthPresorter,
|
||||||
_options: &PlanarAutorouteOptions,
|
_options: &PlanarAutorouteOptions,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
@ -134,7 +134,7 @@ impl PermuteRatlines for RatlineCutsRatlinePermuter {
|
||||||
&mut self,
|
&mut self,
|
||||||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
stepper: &PlanarAutorouteExecutionStepper,
|
stepper: &PlanarAutorouteExecutionStepper,
|
||||||
) -> Option<Vec<RatlineIndex>> {
|
) -> Option<Vec<RatlineUid>> {
|
||||||
let curr_ratline = stepper.ratlines()[*stepper.curr_ratline_index()];
|
let curr_ratline = stepper.ratlines()[*stepper.curr_ratline_index()];
|
||||||
let terminating_dots = curr_ratline.ref_(autorouter).terminating_dots();
|
let terminating_dots = curr_ratline.ref_(autorouter).terminating_dots();
|
||||||
let bands_cut_by_ratline: Vec<_> = autorouter
|
let bands_cut_by_ratline: Vec<_> = autorouter
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ use crate::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
invoker::GetDebugOverlayData, ratline::RatlineIndex, Autorouter, AutorouterError,
|
invoker::GetDebugOverlayData, ratline::RatlineUid, Autorouter, AutorouterError,
|
||||||
PlanarAutorouteOptions,
|
PlanarAutorouteOptions,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -43,7 +43,7 @@ pub enum PlanarAutorouteContinueStatus {
|
||||||
#[derive(Getters)]
|
#[derive(Getters)]
|
||||||
pub struct PlanarAutorouteExecutionStepper {
|
pub struct PlanarAutorouteExecutionStepper {
|
||||||
/// The ratlines which we are routing.
|
/// The ratlines which we are routing.
|
||||||
ratlines: Vec<RatlineIndex>,
|
ratlines: Vec<RatlineUid>,
|
||||||
/// Keeps track of the current ratline being routed, if one is active.
|
/// Keeps track of the current ratline being routed, if one is active.
|
||||||
curr_ratline_index: usize,
|
curr_ratline_index: usize,
|
||||||
/// Stores the current route being processed, if any.
|
/// Stores the current route being processed, if any.
|
||||||
|
|
@ -64,7 +64,7 @@ impl PlanarAutorouteExecutionStepper {
|
||||||
/// and stores the associated data for future routing steps.
|
/// and stores the associated data for future routing steps.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
ratlines: Vec<RatlineIndex>,
|
ratlines: Vec<RatlineUid>,
|
||||||
options: PlanarAutorouteOptions,
|
options: PlanarAutorouteOptions,
|
||||||
) -> Result<Self, AutorouterError> {
|
) -> Result<Self, AutorouterError> {
|
||||||
if ratlines.is_empty() {
|
if ratlines.is_empty() {
|
||||||
|
|
@ -187,9 +187,9 @@ impl<M: AccessMesadata> Step<Autorouter<M>, Option<BoardEdit>, PlanarAutorouteCo
|
||||||
|
|
||||||
autorouter
|
autorouter
|
||||||
.ratsnests
|
.ratsnests
|
||||||
.on_principal_layer_mut(0)
|
.on_principal_layer_mut(self.options.principal_layer)
|
||||||
.assign_band_termseg_to_ratline(
|
.assign_band_termseg_to_ratline(
|
||||||
self.ratlines[self.curr_ratline_index],
|
self.ratlines[self.curr_ratline_index].index,
|
||||||
band_termseg,
|
band_termseg,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -236,13 +236,13 @@ impl<M: AccessMesadata> Abort<Autorouter<M>> for PlanarAutorouteExecutionStepper
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<M: AccessMesadata> Permutate<Autorouter<M>> for PlanarAutorouteExecutionStepper {
|
impl<M: AccessMesadata> Permutate<Autorouter<M>> for PlanarAutorouteExecutionStepper {
|
||||||
type Index = RatlineIndex;
|
type Index = RatlineUid;
|
||||||
type Output = Result<(), AutorouterError>;
|
type Output = Result<(), AutorouterError>;
|
||||||
|
|
||||||
fn permutate(
|
fn permutate(
|
||||||
&mut self,
|
&mut self,
|
||||||
autorouter: &mut Autorouter<M>,
|
autorouter: &mut Autorouter<M>,
|
||||||
permutation: Vec<RatlineIndex>,
|
permutation: Vec<RatlineUid>,
|
||||||
) -> Result<(), AutorouterError> {
|
) -> Result<(), AutorouterError> {
|
||||||
let Some(new_index) = permutation
|
let Some(new_index) = permutation
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ use specctra_core::mesadata::AccessMesadata;
|
||||||
use crate::{
|
use crate::{
|
||||||
autorouter::{
|
autorouter::{
|
||||||
anterouter::{AnterouterPlan, TerminatingScheme},
|
anterouter::{AnterouterPlan, TerminatingScheme},
|
||||||
ratline::RatlineIndex,
|
ratline::RatlineUid,
|
||||||
Autorouter,
|
Autorouter,
|
||||||
},
|
},
|
||||||
drawing::{
|
drawing::{
|
||||||
|
|
@ -27,7 +27,7 @@ pub struct Planner {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Planner {
|
impl Planner {
|
||||||
pub fn new(autorouter: &Autorouter<impl AccessMesadata>, ratlines: &[RatlineIndex]) -> Self {
|
pub fn new(autorouter: &Autorouter<impl AccessMesadata>, ratlines: &[RatlineUid]) -> Self {
|
||||||
let mut plan = AnterouterPlan {
|
let mut plan = AnterouterPlan {
|
||||||
layer_map: ratlines
|
layer_map: ratlines
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use enum_dispatch::enum_dispatch;
|
||||||
use petgraph::algo::tarjan_scc;
|
use petgraph::algo::tarjan_scc;
|
||||||
use specctra_core::mesadata::AccessMesadata;
|
use specctra_core::mesadata::AccessMesadata;
|
||||||
|
|
||||||
use crate::autorouter::{ratline::RatlineIndex, scc::Scc, Autorouter};
|
use crate::autorouter::{ratline::RatlineUid, scc::Scc, Autorouter};
|
||||||
|
|
||||||
pub struct PresortParams {
|
pub struct PresortParams {
|
||||||
pub intersector_count_weight: f64,
|
pub intersector_count_weight: f64,
|
||||||
|
|
@ -19,8 +19,8 @@ pub trait PresortRatlines {
|
||||||
fn presort_ratlines(
|
fn presort_ratlines(
|
||||||
&self,
|
&self,
|
||||||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
ratlines: &[RatlineIndex],
|
ratlines: &[RatlineUid],
|
||||||
) -> Vec<RatlineIndex>;
|
) -> Vec<RatlineUid>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch(PresortRatlines)]
|
#[enum_dispatch(PresortRatlines)]
|
||||||
|
|
@ -36,12 +36,16 @@ pub struct SccIntersectionsAndLengthPresorter {
|
||||||
impl SccIntersectionsAndLengthPresorter {
|
impl SccIntersectionsAndLengthPresorter {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
ratlines: &[RatlineIndex],
|
ratlines: &[RatlineUid],
|
||||||
params: &PresortParams,
|
params: &PresortParams,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
// FIXME: Unnecessary copy.
|
// FIXME: Unnecessary copy.
|
||||||
let mut filtered_ratsnest = autorouter.ratsnests().on_principal_layer(0).graph().clone();
|
let mut filtered_ratsnest = autorouter
|
||||||
filtered_ratsnest.retain_edges(|_g, i| ratlines.contains(&i));
|
.ratsnests()
|
||||||
|
.on_principal_layer(ratlines[0].principal_layer)
|
||||||
|
.graph()
|
||||||
|
.clone();
|
||||||
|
filtered_ratsnest.retain_edges(|_g, i| ratlines.iter().any(|ratline| ratline.index == i));
|
||||||
|
|
||||||
let mut sccs: Vec<_> = tarjan_scc(&filtered_ratsnest)
|
let mut sccs: Vec<_> = tarjan_scc(&filtered_ratsnest)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
@ -65,8 +69,8 @@ impl PresortRatlines for SccIntersectionsAndLengthPresorter {
|
||||||
fn presort_ratlines(
|
fn presort_ratlines(
|
||||||
&self,
|
&self,
|
||||||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
ratlines: &[RatlineIndex],
|
ratlines: &[RatlineUid],
|
||||||
) -> Vec<RatlineIndex> {
|
) -> Vec<RatlineUid> {
|
||||||
let mut presorted_ratlines = vec![];
|
let mut presorted_ratlines = vec![];
|
||||||
|
|
||||||
for scc in self.sccs.iter() {
|
for scc in self.sccs.iter() {
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,11 @@ use crate::{
|
||||||
|
|
||||||
use super::{ratsnest::RatvertexNodeIndex, Autorouter};
|
use super::{ratsnest::RatvertexNodeIndex, Autorouter};
|
||||||
|
|
||||||
pub type RatlineIndex = EdgeIndex<usize>;
|
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||||
|
pub struct RatlineUid {
|
||||||
|
pub principal_layer: usize,
|
||||||
|
pub index: EdgeIndex<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Copy)]
|
#[derive(Debug, Default, Clone, Copy)]
|
||||||
pub struct RatlineWeight {
|
pub struct RatlineWeight {
|
||||||
|
|
@ -27,7 +31,7 @@ pub struct RatlineWeight {
|
||||||
pub band_termseg: Option<BandTermsegIndex>,
|
pub band_termseg: Option<BandTermsegIndex>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, M: AccessMesadata + 'a> MakeRef<'a, Autorouter<M>> for RatlineIndex {
|
impl<'a, M: AccessMesadata + 'a> MakeRef<'a, Autorouter<M>> for RatlineUid {
|
||||||
type Output = RatlineRef<'a, M>;
|
type Output = RatlineRef<'a, M>;
|
||||||
fn ref_(&self, autorouter: &'a Autorouter<M>) -> RatlineRef<'a, M> {
|
fn ref_(&self, autorouter: &'a Autorouter<M>) -> RatlineRef<'a, M> {
|
||||||
RatlineRef::new(*self, autorouter)
|
RatlineRef::new(*self, autorouter)
|
||||||
|
|
@ -35,21 +39,24 @@ impl<'a, M: AccessMesadata + 'a> MakeRef<'a, Autorouter<M>> for RatlineIndex {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RatlineRef<'a, M: AccessMesadata> {
|
pub struct RatlineRef<'a, M: AccessMesadata> {
|
||||||
index: RatlineIndex,
|
uid: RatlineUid,
|
||||||
autorouter: &'a Autorouter<M>,
|
autorouter: &'a Autorouter<M>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
|
impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
|
||||||
pub fn new(index: RatlineIndex, autorouter: &'a Autorouter<M>) -> Self {
|
pub fn new(index: RatlineUid, autorouter: &'a Autorouter<M>) -> Self {
|
||||||
Self { index, autorouter }
|
Self {
|
||||||
|
uid: index,
|
||||||
|
autorouter,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn band_termseg(&self) -> BandTermsegIndex {
|
pub fn band_termseg(&self) -> BandTermsegIndex {
|
||||||
self.autorouter
|
self.autorouter
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(self.uid.principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.edge_weight(self.index)
|
.edge_weight(self.uid.index)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.band_termseg
|
.band_termseg
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
@ -59,15 +66,15 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
|
||||||
let (source, target) = self
|
let (source, target) = self
|
||||||
.autorouter
|
.autorouter
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(self.uid.principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.edge_endpoints(self.index)
|
.edge_endpoints(self.uid.index)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let source_dot = match self
|
let source_dot = match self
|
||||||
.autorouter
|
.autorouter
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(self.uid.principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.node_weight(source)
|
.node_weight(source)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
@ -80,7 +87,7 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
|
||||||
let target_dot = match self
|
let target_dot = match self
|
||||||
.autorouter
|
.autorouter
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(self.uid.principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.node_weight(target)
|
.node_weight(target)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
@ -97,15 +104,15 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
|
||||||
let (source, target) = self
|
let (source, target) = self
|
||||||
.autorouter
|
.autorouter
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(self.uid.principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.edge_endpoints(self.index)
|
.edge_endpoints(self.uid.index)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let source_dot = self
|
let source_dot = self
|
||||||
.autorouter
|
.autorouter
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(self.uid.principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.node_weight(source)
|
.node_weight(source)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
@ -116,7 +123,7 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
|
||||||
let target_dot = self
|
let target_dot = self
|
||||||
.autorouter
|
.autorouter
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(self.uid.principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.node_weight(target)
|
.node_weight(target)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
@ -131,9 +138,9 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
|
||||||
pub fn layer(&self) -> usize {
|
pub fn layer(&self) -> usize {
|
||||||
self.autorouter
|
self.autorouter
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(self.uid.principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.edge_weight(self.index)
|
.edge_weight(self.uid.index)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.layer
|
.layer
|
||||||
}
|
}
|
||||||
|
|
@ -164,14 +171,18 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn interiorly_cut_ratlines(&self) -> impl Iterator<Item = RatlineIndex> + '_ {
|
pub fn interiorly_cut_ratlines(&self) -> impl Iterator<Item = RatlineUid> + '_ {
|
||||||
let self_line_segment = self.line_segment();
|
let self_line_segment = self.line_segment();
|
||||||
|
|
||||||
self.autorouter
|
self.autorouter
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(self.uid.principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.edge_indices()
|
.edge_indices()
|
||||||
|
.map(|index| RatlineUid {
|
||||||
|
principal_layer: self.uid.principal_layer,
|
||||||
|
index,
|
||||||
|
})
|
||||||
.filter(move |other| {
|
.filter(move |other| {
|
||||||
let (self_source, self_target) = self.endpoint_indices();
|
let (self_source, self_target) = self.endpoint_indices();
|
||||||
let (other_source, other_target) = other.ref_(self.autorouter).endpoint_indices();
|
let (other_source, other_target) = other.ref_(self.autorouter).endpoint_indices();
|
||||||
|
|
@ -201,7 +212,7 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
|
||||||
let source_pos = self
|
let source_pos = self
|
||||||
.autorouter
|
.autorouter
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(self.uid.principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.node_weight(source)
|
.node_weight(source)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
@ -209,7 +220,7 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
|
||||||
let target_pos = self
|
let target_pos = self
|
||||||
.autorouter
|
.autorouter
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(self.uid.principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.node_weight(target)
|
.node_weight(target)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
|
@ -221,9 +232,9 @@ impl<'a, M: AccessMesadata> RatlineRef<'a, M> {
|
||||||
pub fn endpoint_indices(&self) -> (NodeIndex<usize>, NodeIndex<usize>) {
|
pub fn endpoint_indices(&self) -> (NodeIndex<usize>, NodeIndex<usize>) {
|
||||||
self.autorouter
|
self.autorouter
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(self.uid.principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.edge_endpoints(self.index)
|
.edge_endpoints(self.uid.index)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,11 @@ use std::{
|
||||||
|
|
||||||
use enum_dispatch::enum_dispatch;
|
use enum_dispatch::enum_dispatch;
|
||||||
use geo::Point;
|
use geo::Point;
|
||||||
use petgraph::{data::Element, graph::NodeIndex, prelude::StableUnGraph};
|
use petgraph::{
|
||||||
|
data::Element,
|
||||||
|
graph::{EdgeIndex, NodeIndex},
|
||||||
|
prelude::StableUnGraph,
|
||||||
|
};
|
||||||
use spade::{handles::FixedVertexHandle, HasPosition, InsertionError, Point2};
|
use spade::{handles::FixedVertexHandle, HasPosition, InsertionError, Point2};
|
||||||
use specctra_core::mesadata::AccessMesadata;
|
use specctra_core::mesadata::AccessMesadata;
|
||||||
|
|
||||||
|
|
@ -27,10 +31,7 @@ use crate::{
|
||||||
triangulation::{GetTrianvertexNodeIndex, Triangulation},
|
triangulation::{GetTrianvertexNodeIndex, Triangulation},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{conncomps::ConncompsWithPrincipalLayer, ratline::RatlineWeight};
|
||||||
conncomps::ConncompsWithPrincipalLayer,
|
|
||||||
ratline::{RatlineIndex, RatlineWeight},
|
|
||||||
};
|
|
||||||
|
|
||||||
#[enum_dispatch(GetIndex)]
|
#[enum_dispatch(GetIndex)]
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
|
|
@ -108,8 +109,10 @@ pub struct Ratsnest {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Ratsnest {
|
impl Ratsnest {
|
||||||
pub fn new(board: &Board<impl AccessMesadata>) -> Result<Self, InsertionError> {
|
pub fn new(
|
||||||
let principal_layer = 0;
|
board: &Board<impl AccessMesadata>,
|
||||||
|
principal_layer: usize,
|
||||||
|
) -> Result<Self, InsertionError> {
|
||||||
let conncomps = ConncompsWithPrincipalLayer::new(board, principal_layer);
|
let conncomps = ConncompsWithPrincipalLayer::new(board, principal_layer);
|
||||||
|
|
||||||
let mut this = Self {
|
let mut this = Self {
|
||||||
|
|
@ -239,16 +242,19 @@ impl Ratsnest {
|
||||||
.insert(layer, terminating_dot);
|
.insert(layer, terminating_dot);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assign_layer_to_ratline(&mut self, ratline: RatlineIndex, layer: usize) {
|
pub fn assign_layer_to_ratline(&mut self, ratline_index: EdgeIndex<usize>, layer: usize) {
|
||||||
self.graph.edge_weight_mut(ratline).unwrap().layer = layer;
|
self.graph.edge_weight_mut(ratline_index).unwrap().layer = layer;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assign_band_termseg_to_ratline(
|
pub fn assign_band_termseg_to_ratline(
|
||||||
&mut self,
|
&mut self,
|
||||||
ratline: RatlineIndex,
|
ratline_index: EdgeIndex<usize>,
|
||||||
termseg: BandTermsegIndex,
|
termseg: BandTermsegIndex,
|
||||||
) {
|
) {
|
||||||
self.graph.edge_weight_mut(ratline).unwrap().band_termseg = Some(termseg);
|
self.graph
|
||||||
|
.edge_weight_mut(ratline_index)
|
||||||
|
.unwrap()
|
||||||
|
.band_termseg = Some(termseg);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn graph(&self) -> &StableUnGraph<RatvertexWeight, RatlineWeight, usize> {
|
pub fn graph(&self) -> &StableUnGraph<RatvertexWeight, RatlineWeight, usize> {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,12 @@ pub struct Ratsnests(Box<[Ratsnest]>);
|
||||||
|
|
||||||
impl Ratsnests {
|
impl Ratsnests {
|
||||||
pub fn new(board: &Board<impl AccessMesadata>) -> Result<Self, InsertionError> {
|
pub fn new(board: &Board<impl AccessMesadata>) -> Result<Self, InsertionError> {
|
||||||
Ok(Self(Box::new([Ratsnest::new(board)?])))
|
Ok(Self(
|
||||||
|
(0..board.mesadata().layer_count())
|
||||||
|
.map(|principal_layer| Ratsnest::new(board, principal_layer))
|
||||||
|
.collect::<Result<Vec<_>, _>>()
|
||||||
|
.map(Vec::into_boxed_slice)?,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_principal_layer(&self, principal_layer: usize) -> &Ratsnest {
|
pub fn on_principal_layer(&self, principal_layer: usize) -> &Ratsnest {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ use specctra_core::mesadata::AccessMesadata;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
autorouter::{
|
autorouter::{
|
||||||
ratline::{RatlineIndex, RatlineWeight},
|
ratline::{RatlineUid, RatlineWeight},
|
||||||
ratsnest::RatvertexWeight,
|
ratsnest::RatvertexWeight,
|
||||||
Autorouter,
|
Autorouter,
|
||||||
},
|
},
|
||||||
|
|
@ -27,7 +27,7 @@ pub struct Scc {
|
||||||
impl Scc {
|
impl Scc {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
ratlines: &[RatlineIndex],
|
ratlines: &[RatlineUid],
|
||||||
filtered_ratsnest: &StableUnGraph<RatvertexWeight, RatlineWeight, usize>,
|
filtered_ratsnest: &StableUnGraph<RatvertexWeight, RatlineWeight, usize>,
|
||||||
node_indices: Vec<NodeIndex<usize>>,
|
node_indices: Vec<NodeIndex<usize>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
@ -40,10 +40,10 @@ impl Scc {
|
||||||
for ratline in ratlines.iter() {
|
for ratline in ratlines.iter() {
|
||||||
if this
|
if this
|
||||||
.node_indices
|
.node_indices
|
||||||
.contains(&filtered_ratsnest.edge_endpoints(*ratline).unwrap().0)
|
.contains(&filtered_ratsnest.edge_endpoints(ratline.index).unwrap().0)
|
||||||
&& this
|
&& this
|
||||||
.node_indices
|
.node_indices
|
||||||
.contains(&filtered_ratsnest.edge_endpoints(*ratline).unwrap().1)
|
.contains(&filtered_ratsnest.edge_endpoints(ratline.index).unwrap().1)
|
||||||
{
|
{
|
||||||
this.length += ratline.ref_(autorouter).length();
|
this.length += ratline.ref_(autorouter).length();
|
||||||
this.intersector_count +=
|
this.intersector_count +=
|
||||||
|
|
@ -74,23 +74,23 @@ impl<'a, M: AccessMesadata> SccRef<'a, M> {
|
||||||
Self { scc, autorouter }
|
Self { scc, autorouter }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn contains(&self, ratline: RatlineIndex) -> bool {
|
pub fn contains(&self, ratline: RatlineUid) -> bool {
|
||||||
self.scc.node_indices().contains(
|
self.scc.node_indices().contains(
|
||||||
&self
|
&self
|
||||||
.autorouter
|
.autorouter
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(ratline.principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.edge_endpoints(ratline)
|
.edge_endpoints(ratline.index)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.0,
|
.0,
|
||||||
) && self.scc.node_indices().contains(
|
) && self.scc.node_indices().contains(
|
||||||
&self
|
&self
|
||||||
.autorouter
|
.autorouter
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(ratline.principal_layer)
|
||||||
.graph()
|
.graph()
|
||||||
.edge_endpoints(ratline)
|
.edge_endpoints(ratline.index)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.1,
|
.1,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ use topola::{
|
||||||
conncomps::ConncompsWithPrincipalLayer,
|
conncomps::ConncompsWithPrincipalLayer,
|
||||||
history::{History, HistoryError},
|
history::{History, HistoryError},
|
||||||
invoker::{Invoker, InvokerError},
|
invoker::{Invoker, InvokerError},
|
||||||
|
ratline::RatlineUid,
|
||||||
Autorouter,
|
Autorouter,
|
||||||
},
|
},
|
||||||
board::{edit::BoardEdit, AccessMesadata, Board},
|
board::{edit::BoardEdit, AccessMesadata, Board},
|
||||||
|
|
@ -125,7 +126,7 @@ pub fn assert_no_loose_nodes(autorouter: &Autorouter<impl AccessMesadata>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assert_navnode_count(
|
pub fn assert_layer_0_navnode_count(
|
||||||
autorouter: &mut Autorouter<SpecctraMesadata>,
|
autorouter: &mut Autorouter<SpecctraMesadata>,
|
||||||
origin_pin: &str,
|
origin_pin: &str,
|
||||||
destination_pin: &str,
|
destination_pin: &str,
|
||||||
|
|
@ -136,6 +137,10 @@ pub fn assert_navnode_count(
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(0)
|
||||||
.graph()
|
.graph()
|
||||||
.edge_indices()
|
.edge_indices()
|
||||||
|
.map(|index| RatlineUid {
|
||||||
|
principal_layer: 0,
|
||||||
|
index,
|
||||||
|
})
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.iter()
|
.iter()
|
||||||
.find_map(|ratline| {
|
.find_map(|ratline| {
|
||||||
|
|
@ -175,13 +180,23 @@ pub fn assert_that_all_single_layer_groundless_ratlines_are_autorouted(
|
||||||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||||
layername: &str,
|
layername: &str,
|
||||||
) {
|
) {
|
||||||
let conncomps = ConncompsWithPrincipalLayer::new(autorouter.board(), 0);
|
let layer = autorouter
|
||||||
|
.board()
|
||||||
|
.layout()
|
||||||
|
.rules()
|
||||||
|
.layername_layer(layername)
|
||||||
|
.unwrap();
|
||||||
|
let conncomps = ConncompsWithPrincipalLayer::new(autorouter.board(), layer);
|
||||||
|
|
||||||
for ratline in autorouter
|
for ratline in autorouter
|
||||||
.ratsnests()
|
.ratsnests()
|
||||||
.on_principal_layer(0)
|
.on_principal_layer(layer)
|
||||||
.graph()
|
.graph()
|
||||||
.edge_indices()
|
.edge_indices()
|
||||||
|
.map(|index| RatlineUid {
|
||||||
|
principal_layer: 0,
|
||||||
|
index,
|
||||||
|
})
|
||||||
{
|
{
|
||||||
let (origin_dot, destination_dot) = ratline.ref_(autorouter).endpoint_dots();
|
let (origin_dot, destination_dot) = ratline.ref_(autorouter).endpoint_dots();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ fn autoroute_tht_de9_to_tht_de9_in_predefined_order(variant: &str) {
|
||||||
#[apply(test_master)]
|
#[apply(test_master)]
|
||||||
fn autoroute_0603_breakout(variant: &str) {
|
fn autoroute_0603_breakout(variant: &str) {
|
||||||
let mut autorouter = common::load_design("tests/single_layer/0603_breakout/0603_breakout.dsn");
|
let mut autorouter = common::load_design("tests/single_layer/0603_breakout/0603_breakout.dsn");
|
||||||
common::assert_navnode_count(&mut autorouter, "R1-2", "J1-2", 22);
|
common::assert_layer_0_navnode_count(&mut autorouter, "R1-2", "J1-2", 22);
|
||||||
let mut invoker = common::create_invoker_and_assert(autorouter);
|
let mut invoker = common::create_invoker_and_assert(autorouter);
|
||||||
common::replay_and_assert_and_report(
|
common::replay_and_assert_and_report(
|
||||||
&mut invoker,
|
&mut invoker,
|
||||||
|
|
@ -122,7 +122,7 @@ fn autoroute_tht_diode_bridge_rectifier(variant: &str) {
|
||||||
let mut autorouter = common::load_design(
|
let mut autorouter = common::load_design(
|
||||||
"tests/single_layer/tht_diode_bridge_rectifier/tht_diode_bridge_rectifier.dsn",
|
"tests/single_layer/tht_diode_bridge_rectifier/tht_diode_bridge_rectifier.dsn",
|
||||||
);
|
);
|
||||||
common::assert_navnode_count(&mut autorouter, "J2-2", "D4-2", 68);
|
common::assert_layer_0_navnode_count(&mut autorouter, "J2-2", "D4-2", 68);
|
||||||
let mut invoker = common::create_invoker_and_assert(autorouter);
|
let mut invoker = common::create_invoker_and_assert(autorouter);
|
||||||
common::replay_and_assert_and_report(
|
common::replay_and_assert_and_report(
|
||||||
&mut invoker,
|
&mut invoker,
|
||||||
|
|
@ -162,7 +162,7 @@ fn autoroute_4x_3rd_order_smd_lc_filters(variant: &str) {
|
||||||
let mut autorouter = common::load_design(
|
let mut autorouter = common::load_design(
|
||||||
"tests/single_layer/4x_3rd_order_smd_lc_filters/4x_3rd_order_smd_lc_filters.dsn",
|
"tests/single_layer/4x_3rd_order_smd_lc_filters/4x_3rd_order_smd_lc_filters.dsn",
|
||||||
);
|
);
|
||||||
common::assert_navnode_count(&mut autorouter, "J1-1", "L1-1", 558);
|
common::assert_layer_0_navnode_count(&mut autorouter, "J1-1", "L1-1", 558);
|
||||||
let mut invoker = common::create_invoker_and_assert(autorouter);
|
let mut invoker = common::create_invoker_and_assert(autorouter);
|
||||||
common::replay_and_assert_and_report(
|
common::replay_and_assert_and_report(
|
||||||
&mut invoker,
|
&mut invoker,
|
||||||
|
|
@ -206,7 +206,7 @@ fn test_tht_3pin_xlr_to_tht_3pin_xlr(#[case] variant: &str) {
|
||||||
fn autoroute_vga_dac_breakout(variant: &str) {
|
fn autoroute_vga_dac_breakout(variant: &str) {
|
||||||
let mut autorouter =
|
let mut autorouter =
|
||||||
common::load_design("tests/single_layer/vga_dac_breakout/vga_dac_breakout.dsn");
|
common::load_design("tests/single_layer/vga_dac_breakout/vga_dac_breakout.dsn");
|
||||||
common::assert_navnode_count(&mut autorouter, "J1-2", "R4-1", 272);
|
common::assert_layer_0_navnode_count(&mut autorouter, "J1-2", "R4-1", 272);
|
||||||
let mut invoker = common::create_invoker_and_assert(autorouter);
|
let mut invoker = common::create_invoker_and_assert(autorouter);
|
||||||
common::replay_and_assert_and_report(
|
common::replay_and_assert_and_report(
|
||||||
&mut invoker,
|
&mut invoker,
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue