From 26ed61ad4d05ef442381c7d5440dcb8e3daa28e7 Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Fri, 3 Oct 2025 15:55:58 +0200 Subject: [PATCH] feat(autorouter/anterouter): Anteroute fanout segs to fanout vias --- src/autorouter/anterouter.rs | 52 +++++++++++++++++++++++++++++------- src/layout/poly.rs | 5 ++++ 2 files changed, 47 insertions(+), 10 deletions(-) diff --git a/src/autorouter/anterouter.rs b/src/autorouter/anterouter.rs index 11dda98..78109fa 100644 --- a/src/autorouter/anterouter.rs +++ b/src/autorouter/anterouter.rs @@ -16,10 +16,11 @@ use crate::{ dot::FixedDotIndex, graph::{GetMaybeNet, MakePrimitiveRef}, primitive::MakePrimitiveShape, + seg::{FixedSegWeight, GeneralSegWeight}, }, geometry::{GenericNode, GetLayer}, - graph::MakeRef, - layout::{poly::MakePolygon, via::ViaWeight}, + graph::{GenericIndex, MakeRef}, + layout::{poly::MakePolygon, via::ViaWeight, LayoutEdit}, math::Circle, }; @@ -124,7 +125,7 @@ impl Anterouter { ratvertex, source_dot, target_layer, - Point::from(cardinal_direction) * 1.4, + Point::from(cardinal_direction) * 1.5, ) .is_ok() { @@ -143,7 +144,7 @@ impl Anterouter { ratvertex, source_dot, target_layer, - Point::from(counterclockwise_turning) * 1.4, + Point::from(counterclockwise_turning) * 1.5, ) .is_ok() { @@ -158,7 +159,7 @@ impl Anterouter { ratvertex, source_dot, target_layer, - Point::from(clockwise_turning) * 1.4, + Point::from(clockwise_turning) * 1.5, ) .is_ok() { @@ -182,13 +183,44 @@ impl Anterouter { target_layer: usize, bbox_to_anchor: Point, ) -> Result<(), ()> { - self.place_fanout_via_on_anchor( + let (_, dots) = self.place_fanout_via_on_anchor( autorouter, ratvertex, source_dot, target_layer, bbox_to_anchor, - ) + )?; + + let layer = source_dot + .primitive_ref(autorouter.board().layout().drawing()) + .layer(); + let maybe_net = source_dot + .primitive_ref(autorouter.board().layout().drawing()) + .maybe_net(); + let fanout_dot = *dots + .iter() + .find(|dot| { + source_dot + .primitive_ref(autorouter.board().layout().drawing()) + .layer() + == dot + .primitive_ref(autorouter.board().layout().drawing()) + .layer() + }) + .unwrap(); + + autorouter.board.layout_mut().add_fixed_seg( + &mut LayoutEdit::new(), + source_dot, + fanout_dot, + FixedSegWeight(GeneralSegWeight { + width: 100.0, + layer, + maybe_net, + }), + ); + + Ok(()) } fn place_fanout_via_on_anchor( @@ -198,7 +230,7 @@ impl Anterouter { dot: FixedDotIndex, target_layer: usize, endpoint_dot_bbox_to_anchor: Point, - ) -> Result<(), ()> { + ) -> Result<(GenericIndex, Vec), ()> { let source_layer = autorouter.board().layout().drawing().primitive(dot).layer(); let pin_maybe_net = autorouter .board() @@ -233,7 +265,7 @@ impl Anterouter { let mut board_edit = BoardEdit::new(); - if let Ok((.., dots)) = autorouter.board.add_via( + if let Ok((via, dots)) = autorouter.board.add_via( &mut board_edit, ViaWeight { from_layer: std::cmp::min(source_layer, target_layer), @@ -263,7 +295,7 @@ impl Anterouter { target_layer, *terminating_dot, ); - Ok(()) + Ok((via, dots)) } else { Err(()) } diff --git a/src/layout/poly.rs b/src/layout/poly.rs index 0a1c615..b4b7c8b 100644 --- a/src/layout/poly.rs +++ b/src/layout/poly.rs @@ -155,6 +155,11 @@ fn is_apex( .iter() .any(|seg| matches!(seg, SegIndex::Fixed(..))) && drawing.primitive(dot).bends().is_empty() + // FIXME: Only the following should be needed to make sure dot is an apex. + // But for some reason I had to keep the above part. + || drawing + .compounds(dot) + .any(|(cel, _)| cel == CompoundEntryLabel::Apex) } impl<'a, R> PolyRef<'a, R> {