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