mirror of https://codeberg.org/topola/topola.git
autorouter: add option to disable presorting by pairwise detours
This commit is contained in:
parent
f7f2e8ea49
commit
a52515f6d3
|
|
@ -10,7 +10,7 @@ use crate::{
|
|||
|
||||
use super::{
|
||||
invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles},
|
||||
Autorouter, AutorouterError,
|
||||
Autorouter, AutorouterError, AutorouterOptions,
|
||||
};
|
||||
|
||||
pub enum AutorouteStatus {
|
||||
|
|
@ -32,6 +32,7 @@ impl TryInto<()> for AutorouteStatus {
|
|||
|
||||
pub struct Autoroute {
|
||||
ratlines_iter: Box<dyn Iterator<Item = EdgeIndex<usize>>>,
|
||||
options: AutorouterOptions,
|
||||
route: Option<Route>,
|
||||
curr_ratline: Option<EdgeIndex<usize>>,
|
||||
}
|
||||
|
|
@ -40,6 +41,7 @@ impl Autoroute {
|
|||
pub fn new(
|
||||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||
ratlines: impl IntoIterator<Item = EdgeIndex<usize>> + 'static,
|
||||
options: AutorouterOptions,
|
||||
) -> Result<Self, AutorouterError> {
|
||||
let mut ratlines_iter = Box::new(ratlines.into_iter());
|
||||
|
||||
|
|
@ -52,8 +54,9 @@ impl Autoroute {
|
|||
|
||||
let this = Self {
|
||||
ratlines_iter,
|
||||
curr_ratline: Some(curr_ratline),
|
||||
options,
|
||||
route: Some(router.route(source, target, 100.0)?),
|
||||
curr_ratline: Some(curr_ratline),
|
||||
};
|
||||
|
||||
Ok(this)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use petgraph::graph::EdgeIndex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use spade::InsertionError;
|
||||
use thiserror::Error;
|
||||
|
||||
|
|
@ -24,6 +25,23 @@ use super::{
|
|||
selection::{BandSelection, PinSelection},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
|
||||
pub struct AutorouterOptions {
|
||||
pub presort_by_pairwise_detours: bool,
|
||||
//pub wrap_around_bands: bool,
|
||||
//pub squeeze_under_bands: bool,
|
||||
}
|
||||
|
||||
impl AutorouterOptions {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
presort_by_pairwise_detours: false,
|
||||
//wrap_around_bands: true,
|
||||
//squeeze_under_bands: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Error, Debug, Clone)]
|
||||
pub enum AutorouterError {
|
||||
#[error("nothing to route")]
|
||||
|
|
@ -51,15 +69,20 @@ impl<M: AccessMesadata> Autorouter<M> {
|
|||
Ok(Self { board, ratsnest })
|
||||
}
|
||||
|
||||
pub fn autoroute(&mut self, selection: &PinSelection) -> Result<Autoroute, AutorouterError> {
|
||||
self.autoroute_ratlines(self.selected_ratlines(selection))
|
||||
pub fn autoroute(
|
||||
&mut self,
|
||||
selection: &PinSelection,
|
||||
options: AutorouterOptions,
|
||||
) -> Result<Autoroute, AutorouterError> {
|
||||
self.autoroute_ratlines(self.selected_ratlines(selection), options)
|
||||
}
|
||||
|
||||
pub(super) fn autoroute_ratlines(
|
||||
&mut self,
|
||||
ratlines: Vec<EdgeIndex<usize>>,
|
||||
options: AutorouterOptions,
|
||||
) -> Result<Autoroute, AutorouterError> {
|
||||
Autoroute::new(self, ratlines)
|
||||
Autoroute::new(self, ratlines, options)
|
||||
}
|
||||
|
||||
pub fn undo_autoroute(&mut self, selection: &PinSelection) -> Result<(), AutorouterError> {
|
||||
|
|
@ -106,6 +129,7 @@ impl<M: AccessMesadata> Autorouter<M> {
|
|||
pub fn compare_detours(
|
||||
&mut self,
|
||||
selection: &PinSelection,
|
||||
options: AutorouterOptions,
|
||||
) -> Result<CompareDetours, AutorouterError> {
|
||||
let ratlines = self.selected_ratlines(selection);
|
||||
let ratline1 = *ratlines
|
||||
|
|
@ -114,15 +138,16 @@ impl<M: AccessMesadata> Autorouter<M> {
|
|||
let ratline2 = *ratlines
|
||||
.get(1)
|
||||
.ok_or(AutorouterError::NeedExactlyTwoRatlines)?;
|
||||
self.compare_detours_ratlines(ratline1, ratline2)
|
||||
self.compare_detours_ratlines(ratline1, ratline2, options)
|
||||
}
|
||||
|
||||
pub(super) fn compare_detours_ratlines(
|
||||
&mut self,
|
||||
ratline1: EdgeIndex<usize>,
|
||||
ratline2: EdgeIndex<usize>,
|
||||
options: AutorouterOptions,
|
||||
) -> Result<CompareDetours, AutorouterError> {
|
||||
CompareDetours::new(self, ratline1, ratline2)
|
||||
CompareDetours::new(self, ratline1, ratline2, options)
|
||||
}
|
||||
|
||||
pub fn measure_length(
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use crate::{
|
|||
use super::{
|
||||
autoroute::{Autoroute, AutorouteStatus},
|
||||
invoker::{GetGhosts, GetMaybeNavmesh, GetMaybeTrace, GetObstacles},
|
||||
Autorouter, AutorouterError,
|
||||
Autorouter, AutorouterError, AutorouterOptions,
|
||||
};
|
||||
|
||||
pub enum CompareDetoursStatus {
|
||||
|
|
@ -47,10 +47,11 @@ impl CompareDetours {
|
|||
autorouter: &mut Autorouter<impl AccessMesadata>,
|
||||
ratline1: EdgeIndex<usize>,
|
||||
ratline2: EdgeIndex<usize>,
|
||||
options: AutorouterOptions,
|
||||
) -> Result<Self, AutorouterError> {
|
||||
Ok(Self {
|
||||
autoroute: autorouter.autoroute_ratlines(vec![ratline1, ratline2])?,
|
||||
next_autoroute: Some(autorouter.autoroute_ratlines(vec![ratline2, ratline1])?),
|
||||
autoroute: autorouter.autoroute_ratlines(vec![ratline1, ratline2], options)?,
|
||||
next_autoroute: Some(autorouter.autoroute_ratlines(vec![ratline2, ratline1], options)?),
|
||||
ratline1,
|
||||
ratline2,
|
||||
total_length1: 0.0,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ use super::{
|
|||
place_via::PlaceVia,
|
||||
remove_bands::RemoveBands,
|
||||
selection::{BandSelection, PinSelection},
|
||||
Autorouter, AutorouterError,
|
||||
Autorouter, AutorouterError, AutorouterOptions,
|
||||
};
|
||||
|
||||
#[enum_dispatch]
|
||||
|
|
@ -71,10 +71,10 @@ impl TryInto<()> for InvokerStatus {
|
|||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub enum Command {
|
||||
Autoroute(PinSelection),
|
||||
Autoroute(PinSelection, AutorouterOptions),
|
||||
PlaceVia(ViaWeight),
|
||||
RemoveBands(BandSelection),
|
||||
CompareDetours(PinSelection),
|
||||
CompareDetours(PinSelection, AutorouterOptions),
|
||||
MeasureLength(BandSelection),
|
||||
}
|
||||
|
||||
|
|
@ -254,19 +254,25 @@ impl<M: AccessMesadata> Invoker<M> {
|
|||
#[debug_requires(self.ongoing_command.is_none())]
|
||||
fn dispatch_command(&mut self, command: &Command) -> Result<Execute, InvokerError> {
|
||||
match command {
|
||||
Command::Autoroute(selection) => {
|
||||
Command::Autoroute(selection, options) => {
|
||||
let mut ratlines = self.autorouter.selected_ratlines(selection);
|
||||
|
||||
if options.presort_by_pairwise_detours {
|
||||
ratlines.sort_unstable_by(|a, b| {
|
||||
let mut compare_detours =
|
||||
self.autorouter.compare_detours_ratlines(*a, *b).unwrap();
|
||||
let mut compare_detours = self
|
||||
.autorouter
|
||||
.compare_detours_ratlines(*a, *b, *options)
|
||||
.unwrap();
|
||||
if let Ok((al, bl)) = compare_detours.finish(&mut self.autorouter) {
|
||||
PartialOrd::partial_cmp(&al, &bl).unwrap()
|
||||
} else {
|
||||
Ordering::Equal
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Ok::<Execute, InvokerError>(Execute::Autoroute(
|
||||
self.autorouter.autoroute_ratlines(ratlines)?,
|
||||
self.autorouter.autoroute_ratlines(ratlines, *options)?,
|
||||
))
|
||||
}
|
||||
Command::PlaceVia(weight) => {
|
||||
|
|
@ -275,8 +281,8 @@ impl<M: AccessMesadata> Invoker<M> {
|
|||
Command::RemoveBands(selection) => Ok::<Execute, InvokerError>(Execute::RemoveBands(
|
||||
self.autorouter.remove_bands(selection)?,
|
||||
)),
|
||||
Command::CompareDetours(selection) => Ok::<Execute, InvokerError>(
|
||||
Execute::CompareDetours(self.autorouter.compare_detours(selection)?),
|
||||
Command::CompareDetours(selection, options) => Ok::<Execute, InvokerError>(
|
||||
Execute::CompareDetours(self.autorouter.compare_detours(selection, *options)?),
|
||||
),
|
||||
Command::MeasureLength(selection) => Ok::<Execute, InvokerError>(
|
||||
Execute::MeasureLength(self.autorouter.measure_length(selection)?),
|
||||
|
|
@ -289,8 +295,8 @@ impl<M: AccessMesadata> Invoker<M> {
|
|||
let command = self.history.last_done()?;
|
||||
|
||||
match command {
|
||||
Command::Autoroute(ref selection) => {
|
||||
self.autorouter.undo_autoroute(selection);
|
||||
Command::Autoroute(ref selection, ..) => {
|
||||
self.autorouter.undo_autoroute(selection)?;
|
||||
}
|
||||
Command::PlaceVia(weight) => {
|
||||
self.autorouter.undo_place_via(*weight);
|
||||
|
|
|
|||
|
|
@ -5,8 +5,9 @@ use std::{
|
|||
};
|
||||
|
||||
use topola::{
|
||||
autorouter::invoker::{
|
||||
Command, Execute, ExecuteWithStatus, Invoker, InvokerError, InvokerStatus,
|
||||
autorouter::{
|
||||
invoker::{Command, Execute, ExecuteWithStatus, Invoker, InvokerError, InvokerStatus},
|
||||
AutorouterOptions,
|
||||
},
|
||||
specctra::{design::SpecctraDesign, mesadata::SpecctraMesadata},
|
||||
};
|
||||
|
|
@ -248,9 +249,11 @@ impl Top {
|
|||
) {
|
||||
let selection = overlay.selection().clone();
|
||||
overlay.clear_selection();
|
||||
maybe_execute
|
||||
.insert(ExecuteWithStatus::new(invoker.execute_stepper(
|
||||
Command::Autoroute(selection.pin_selection),
|
||||
maybe_execute.insert(ExecuteWithStatus::new(invoker.execute_stepper(
|
||||
Command::Autoroute(
|
||||
selection.pin_selection,
|
||||
AutorouterOptions::new(),
|
||||
),
|
||||
)?));
|
||||
}
|
||||
}
|
||||
|
|
@ -304,7 +307,10 @@ impl Top {
|
|||
let selection = overlay.selection().clone();
|
||||
overlay.clear_selection();
|
||||
maybe_execute.insert(ExecuteWithStatus::new(invoker.execute_stepper(
|
||||
Command::CompareDetours(selection.pin_selection),
|
||||
Command::CompareDetours(
|
||||
selection.pin_selection,
|
||||
AutorouterOptions::new(),
|
||||
),
|
||||
)?));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue