mirror of https://codeberg.org/topola/topola.git
Compare commits
2 Commits
066f9b82df
...
3208d55272
| Author | SHA1 | Date |
|---|---|---|
|
|
3208d55272 | |
|
|
64669d5d0b |
|
|
@ -51,17 +51,17 @@ tr-menu-route-options-squeeze-through-under-bends = 弯曲处挤线
|
|||
tr-menu-view-kdb-scroll-delta-factor = 键盘滚动增量因子
|
||||
tr-menu-debug-show-pathfinding-scores = 显示路径查找分数
|
||||
tr-menu-place-place-route-plan = 放置布线规划
|
||||
tr-menu-route-topo-autoroute = 拓扑平面自动布线
|
||||
tr-menu-route-topo-autoroute = 拓扑平面自动布线
|
||||
tr-menu-debug-show-triangulation = 显示三角剖分
|
||||
tr-menu-debug-show-triangulation-constraints = 显示三角剖分约束条件
|
||||
tr-menu-route-options-presort-by = 预排序依据
|
||||
tr-menu-route-options-presort-by-ratline-intersection-count-and-length = 交叉点数量及长度
|
||||
tr-menu-route-options-presort-by-ratline-intersection-count-and-length = 交叉点数量及长度
|
||||
tr-menu-route-options-permutate = 排列组合
|
||||
tr-menu-debug-show-guide-circles = 显示辅助圆
|
||||
tr-menu-debug-show-guide-bitangents = 显示双切线
|
||||
tr-menu-debug-show-primitive-indices = 显示图元索引
|
||||
tr-menu-debug-show-primitive-indices = 显示图元索引
|
||||
tr-menu-route-planar-autoroute = 平面自动布线
|
||||
tr-menu-route-fanout-clearance = 扇出间距
|
||||
tr-menu-route-fanout-clearance = 扇出间距
|
||||
tr-menu-debug = 调试
|
||||
tr-menu-debug-fix-step-rate = 固定步进速率
|
||||
tr-menu-debug-highlight-obstacles = 高亮障碍物
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ pub struct AnterouterOptions {
|
|||
pub fanout_clearance: f64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||
pub struct AnterouterPlan {
|
||||
pub layer_map: BTreeMap<RatlineUid, usize>,
|
||||
pub static_terminating_dot_map: BTreeMap<(RatlineUid, FixedDotIndex, usize), FixedDotIndex>,
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ use crate::{
|
|||
},
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||
pub struct MultilayerAutorouteConfiguration {
|
||||
pub plan: AnterouterPlan,
|
||||
pub planar: PlanarAutoroutePreconfigurerInput,
|
||||
|
|
|
|||
|
|
@ -2,16 +2,21 @@
|
|||
//
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
use std::{cmp::Ordering, collections::BTreeMap};
|
||||
|
||||
use derive_getters::Getters;
|
||||
use enum_dispatch::enum_dispatch;
|
||||
use specctra_core::mesadata::AccessMesadata;
|
||||
|
||||
use crate::autorouter::{
|
||||
multilayer_autoroute::{MultilayerAutorouteConfiguration, MultilayerAutorouteOptions},
|
||||
planar_autoroute::PlanarAutorouteConfigurationStatus,
|
||||
planar_preconfigurer::PlanarAutoroutePreconfigurerInput,
|
||||
Autorouter, AutorouterError,
|
||||
use crate::{
|
||||
astar::Astar,
|
||||
autorouter::{
|
||||
multilayer_autoroute::{MultilayerAutorouteConfiguration, MultilayerAutorouteOptions},
|
||||
planar_autoroute::PlanarAutorouteConfigurationStatus,
|
||||
planar_preconfigurer::PlanarAutoroutePreconfigurerInput,
|
||||
ratline::RatlineUid,
|
||||
Autorouter, AutorouterError,
|
||||
},
|
||||
};
|
||||
|
||||
#[enum_dispatch]
|
||||
|
|
@ -33,10 +38,56 @@ pub enum MultilayerAutorouteReconfigurer {
|
|||
UniformRandomLayers(IncrementFailedRatlineLayersMultilayerAutorouteReconfigurer),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Getters)]
|
||||
struct SearchNode {
|
||||
configuration: MultilayerAutorouteConfiguration,
|
||||
}
|
||||
|
||||
impl Ord for SearchNode {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.configuration.cmp(&other.configuration)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialOrd for SearchNode {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for SearchNode {}
|
||||
|
||||
impl PartialEq for SearchNode {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.configuration == other.configuration
|
||||
}
|
||||
}
|
||||
|
||||
impl SearchNode {
|
||||
pub fn new(configuration: MultilayerAutorouteConfiguration) -> Self {
|
||||
Self { configuration }
|
||||
}
|
||||
|
||||
pub fn revise_ratline(self, ratline_uid: RatlineUid, layer_count: usize) -> Self {
|
||||
let mut new_anterouter_plan = self.configuration.plan.clone();
|
||||
|
||||
*new_anterouter_plan.layer_map.get_mut(&ratline_uid).unwrap() += 1;
|
||||
*new_anterouter_plan.layer_map.get_mut(&ratline_uid).unwrap() %= layer_count;
|
||||
|
||||
Self {
|
||||
configuration: MultilayerAutorouteConfiguration {
|
||||
plan: new_anterouter_plan,
|
||||
planar: PlanarAutoroutePreconfigurerInput {
|
||||
ratlines: self.configuration.planar.ratlines.clone(),
|
||||
terminating_dot_map: BTreeMap::new(),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IncrementFailedRatlineLayersMultilayerAutorouteReconfigurer {
|
||||
last_configuration: MultilayerAutorouteConfiguration,
|
||||
maybe_last_planar_status: Option<PlanarAutorouteConfigurationStatus>,
|
||||
maybe_best_planar_status: Option<PlanarAutorouteConfigurationStatus>,
|
||||
configuration_search: Astar<SearchNode, f64>,
|
||||
}
|
||||
|
||||
impl IncrementFailedRatlineLayersMultilayerAutorouteReconfigurer {
|
||||
|
|
@ -46,9 +97,7 @@ impl IncrementFailedRatlineLayersMultilayerAutorouteReconfigurer {
|
|||
_options: &MultilayerAutorouteOptions,
|
||||
) -> Self {
|
||||
Self {
|
||||
last_configuration: preconfiguration,
|
||||
maybe_last_planar_status: None,
|
||||
maybe_best_planar_status: None,
|
||||
configuration_search: Astar::new(SearchNode::new(preconfiguration)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -58,57 +107,32 @@ impl MakeNextMultilayerAutorouteConfiguration
|
|||
{
|
||||
fn process_planar_result(
|
||||
&mut self,
|
||||
_autorouter: &Autorouter<impl AccessMesadata>,
|
||||
autorouter: &Autorouter<impl AccessMesadata>,
|
||||
planar_result: Result<PlanarAutorouteConfigurationStatus, AutorouterError>,
|
||||
) {
|
||||
let Ok(planar_status) = planar_result else {
|
||||
return;
|
||||
};
|
||||
|
||||
self.maybe_last_planar_status = Some(planar_status.clone());
|
||||
|
||||
if self
|
||||
.maybe_best_planar_status
|
||||
.as_ref()
|
||||
.is_none_or(|status| status.costs.lengths.len() < planar_status.costs.lengths.len())
|
||||
{
|
||||
self.maybe_best_planar_status = Some(planar_status.clone());
|
||||
}
|
||||
self.configuration_search.push((
|
||||
0.1,
|
||||
(planar_status.configuration.ratlines.len() - planar_status.costs.lengths.len()) as f64,
|
||||
self.configuration_search
|
||||
.curr_node()
|
||||
.clone()
|
||||
.revise_ratline(
|
||||
planar_status.configuration.ratlines[planar_status.costs.lengths.len()],
|
||||
autorouter.board().layout().drawing().layer_count(),
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
fn next_configuration(
|
||||
&mut self,
|
||||
autorouter: &Autorouter<impl AccessMesadata>,
|
||||
_autorouter: &Autorouter<impl AccessMesadata>,
|
||||
) -> Option<MultilayerAutorouteConfiguration> {
|
||||
let mut new_anterouter_plan = self.last_configuration.plan.clone();
|
||||
|
||||
let Some(ref last_planar_status) = self.maybe_last_planar_status else {
|
||||
return None;
|
||||
};
|
||||
|
||||
if let Some(ref best_planar_status) = self.maybe_best_planar_status {
|
||||
for ratline_index in best_planar_status.costs.lengths.len()
|
||||
..last_planar_status.configuration.ratlines.len()
|
||||
{
|
||||
*new_anterouter_plan
|
||||
.layer_map
|
||||
.get_mut(&last_planar_status.configuration.ratlines[ratline_index])
|
||||
.unwrap() += 1;
|
||||
*new_anterouter_plan
|
||||
.layer_map
|
||||
.get_mut(&last_planar_status.configuration.ratlines[ratline_index])
|
||||
.unwrap() %= autorouter.board().layout().drawing().layer_count();
|
||||
}
|
||||
}
|
||||
|
||||
self.last_configuration = MultilayerAutorouteConfiguration {
|
||||
plan: new_anterouter_plan,
|
||||
planar: PlanarAutoroutePreconfigurerInput {
|
||||
ratlines: self.last_configuration.planar.ratlines.clone(),
|
||||
terminating_dot_map: BTreeMap::new(),
|
||||
},
|
||||
};
|
||||
|
||||
Some(self.last_configuration.clone())
|
||||
self.configuration_search
|
||||
.pop()
|
||||
.map(|node| node.configuration().clone())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use crate::{
|
|||
drawing::dot::FixedDotIndex,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||
pub struct PlanarAutoroutePreconfigurerInput {
|
||||
pub ratlines: BTreeSet<RatlineUid>,
|
||||
pub terminating_dot_map: BTreeMap<(RatlineUid, FixedDotIndex), FixedDotIndex>,
|
||||
|
|
|
|||
|
|
@ -60,17 +60,17 @@ impl PlanarAutorouteReconfigurer {
|
|||
|
||||
#[derive(Clone, Debug, Getters)]
|
||||
struct SccSearchNode {
|
||||
curr_permutation: Vec<Scc>,
|
||||
permutation: Vec<Scc>,
|
||||
#[getter(skip)]
|
||||
permutations: Skip<Permutations<Take<std::vec::IntoIter<Scc>>>>,
|
||||
permutations_iter: Skip<Permutations<Take<std::vec::IntoIter<Scc>>>>,
|
||||
#[getter(skip)]
|
||||
length: usize,
|
||||
}
|
||||
|
||||
impl Ord for SccSearchNode {
|
||||
fn cmp(&self, other: &Self) -> Ordering {
|
||||
self.curr_permutation
|
||||
.cmp(&other.curr_permutation)
|
||||
self.permutation
|
||||
.cmp(&other.permutation)
|
||||
.then(self.length.cmp(&other.length))
|
||||
}
|
||||
}
|
||||
|
|
@ -85,7 +85,7 @@ impl Eq for SccSearchNode {}
|
|||
|
||||
impl PartialEq for SccSearchNode {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.curr_permutation == other.curr_permutation && self.length == other.length
|
||||
self.permutation == other.permutation && self.length == other.length
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -94,8 +94,8 @@ impl SccSearchNode {
|
|||
let len = sccs.len();
|
||||
|
||||
Self {
|
||||
curr_permutation: sccs.clone(),
|
||||
permutations: sccs.into_iter().take(len).permutations(0).skip(0),
|
||||
permutation: sccs.clone(),
|
||||
permutations_iter: sccs.into_iter().take(len).permutations(0).skip(0),
|
||||
length: 0,
|
||||
}
|
||||
}
|
||||
|
|
@ -107,7 +107,7 @@ impl SccSearchNode {
|
|||
if let Some((permuted_resized, changed_count)) = resized.permute() {
|
||||
expanded_nodes.push((
|
||||
changed_count as f64 / 100.0,
|
||||
(self.curr_permutation.len() - permuted_resized.length) as f64,
|
||||
(self.permutation.len() - permuted_resized.length) as f64,
|
||||
permuted_resized,
|
||||
));
|
||||
}
|
||||
|
|
@ -116,7 +116,7 @@ impl SccSearchNode {
|
|||
if let Some((permuted, changed_count)) = self.clone().permute() {
|
||||
expanded_nodes.push((
|
||||
changed_count as f64 / 100.0,
|
||||
(self.curr_permutation.len() - permuted.length) as f64,
|
||||
(self.permutation.len() - permuted.length) as f64,
|
||||
permuted,
|
||||
));
|
||||
}
|
||||
|
|
@ -130,9 +130,9 @@ impl SccSearchNode {
|
|||
}
|
||||
|
||||
Some(Self {
|
||||
curr_permutation: self.curr_permutation.clone(),
|
||||
permutations: self
|
||||
.curr_permutation
|
||||
permutation: self.permutation.clone(),
|
||||
permutations_iter: self
|
||||
.permutation
|
||||
.into_iter()
|
||||
.take(length)
|
||||
.permutations(length)
|
||||
|
|
@ -144,11 +144,9 @@ impl SccSearchNode {
|
|||
fn permute(mut self) -> Option<(Self, usize)> {
|
||||
let mut changed_count = 0;
|
||||
|
||||
for (i, element) in self.permutations.next()?.iter().enumerate() {
|
||||
if self.curr_permutation[i] != *element {
|
||||
self.curr_permutation[i] = element.clone();
|
||||
|
||||
// FIXME: Uncommenting this breaks the 4x4_1206_led_matrix test.
|
||||
for (i, element) in self.permutations_iter.next()?.iter().enumerate() {
|
||||
if self.permutation[i] != *element {
|
||||
self.permutation[i] = element.clone();
|
||||
changed_count += 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -158,7 +156,7 @@ impl SccSearchNode {
|
|||
}
|
||||
|
||||
pub struct SccPermutationsPlanarAutorouteReconfigurer {
|
||||
sccs_search: Astar<SccSearchNode, f64>,
|
||||
configuration_search: Astar<SccSearchNode, f64>,
|
||||
preconfiguration: PlanarAutorouteConfiguration,
|
||||
}
|
||||
|
||||
|
|
@ -174,7 +172,7 @@ impl SccPermutationsPlanarAutorouteReconfigurer {
|
|||
let sccs = presorter.dissolve();
|
||||
|
||||
Self {
|
||||
sccs_search: Astar::new(SccSearchNode::new(sccs)),
|
||||
configuration_search: Astar::new(SccSearchNode::new(sccs)),
|
||||
preconfiguration,
|
||||
}
|
||||
}
|
||||
|
|
@ -187,9 +185,9 @@ impl MakeNextPlanarAutorouteConfiguration for SccPermutationsPlanarAutorouteReco
|
|||
stepper: &PlanarAutorouteExecutionStepper,
|
||||
) -> Option<PlanarAutorouteConfiguration> {
|
||||
let scc_index = self
|
||||
.sccs_search
|
||||
.configuration_search
|
||||
.curr_node()
|
||||
.curr_permutation()
|
||||
.permutation()
|
||||
.iter()
|
||||
.position(|scc| {
|
||||
scc.scc_ref(autorouter)
|
||||
|
|
@ -198,9 +196,9 @@ impl MakeNextPlanarAutorouteConfiguration for SccPermutationsPlanarAutorouteReco
|
|||
.unwrap();
|
||||
|
||||
let next_search_node = self
|
||||
.sccs_search
|
||||
.expand(&self.sccs_search.curr_node().expand(scc_index + 1))?;
|
||||
let next_permutation = next_search_node.curr_permutation();
|
||||
.configuration_search
|
||||
.expand(&self.configuration_search.curr_node().expand(scc_index + 1))?;
|
||||
let next_permutation = next_search_node.permutation();
|
||||
let mut ratlines = vec![];
|
||||
|
||||
for scc in next_permutation {
|
||||
|
|
|
|||
Loading…
Reference in New Issue