From 530f81557a08c301aee8484b1a12ed5125ebdd0f Mon Sep 17 00:00:00 2001 From: Mikolaj Wielgus Date: Fri, 17 May 2024 02:22:48 +0200 Subject: [PATCH] layout: keep track of node pins For the time being we're storing pin names in a hashmap with nodes as keys. We need to know which node belongs to which pin because pins provide stable identifiers for continents (connected components) that we need for replayable command files. --- src/autorouter/ratsnest.rs | 2 +- src/dsn/design.rs | 67 ++++++++++++++++++++++++++------------ src/layout/layout.rs | 63 +++++++++++++++++++++++++++++++---- 3 files changed, 103 insertions(+), 29 deletions(-) diff --git a/src/autorouter/ratsnest.rs b/src/autorouter/ratsnest.rs index 2549158..12f3f27 100644 --- a/src/autorouter/ratsnest.rs +++ b/src/autorouter/ratsnest.rs @@ -89,7 +89,7 @@ impl Ratsnest { for node in layout.drawing().layer_primitive_nodes(layer) { match node { PrimitiveIndex::FixedDot(dot) => { - if layout.compounds(dot).next().is_none() { + if layout.zones(dot).next().is_none() { if let Some(net) = layout.drawing().primitive(dot).maybe_net() { if !triangulations.contains_key(&(layer, net)) { triangulations.insert( diff --git a/src/dsn/design.rs b/src/dsn/design.rs index fe08960..f3acc47 100644 --- a/src/dsn/design.rs +++ b/src/dsn/design.rs @@ -106,6 +106,7 @@ impl DsnDesign { circle.diameter as f64 / 2.0, layer as u64, *net_id, + Some(pin_name.clone()), ) } Shape::Rect(rect) => { @@ -127,6 +128,7 @@ impl DsnDesign { rect.y2 as f64, layer as u64, *net_id, + Some(pin_name.clone()), ) } Shape::Path(path) => { @@ -146,6 +148,7 @@ impl DsnDesign { path.width as f64, layer as u64, *net_id, + Some(pin_name.clone()), ) } Shape::Polygon(polygon) => { @@ -165,6 +168,7 @@ impl DsnDesign { polygon.width as f64, layer as u64, *net_id, + Some(pin_name.clone()), ) } }; @@ -203,6 +207,7 @@ impl DsnDesign { circle.diameter as f64 / 2.0, layer as u64, net_id, + None, ) } Shape::Rect(rect) => { @@ -224,6 +229,7 @@ impl DsnDesign { rect.y2 as f64, layer as u64, net_id, + None, ) } Shape::Path(path) => { @@ -243,6 +249,7 @@ impl DsnDesign { path.width as f64, layer as u64, net_id, + None, ) } Shape::Polygon(polygon) => { @@ -262,6 +269,7 @@ impl DsnDesign { polygon.width as f64, layer as u64, net_id, + None, ) } }; @@ -287,6 +295,7 @@ impl DsnDesign { wire.path.width as f64, layer_id as u64, net_id, + None, ); } @@ -317,6 +326,7 @@ impl DsnDesign { r: f64, layer: u64, net: usize, + maybe_pin: Option, ) { let circle = Circle { pos: Self::pos(place_pos, place_rot, pin_pos, pin_rot, 0.0, 0.0), @@ -324,11 +334,14 @@ impl DsnDesign { }; layout - .add_fixed_dot(FixedDotWeight { - circle, - layer, - maybe_net: Some(net), - }) + .add_fixed_dot( + FixedDotWeight { + circle, + layer, + maybe_net: Some(net), + }, + maybe_pin.clone(), + ) .unwrap(); } @@ -344,13 +357,15 @@ impl DsnDesign { y2: f64, layer: u64, net: usize, + maybe_pin: Option, ) { - let zone = layout.add_compound( + let zone = layout.add_zone( SolidZoneWeight { layer, maybe_net: Some(net), } .into(), + maybe_pin.clone(), ); // Corners. @@ -467,6 +482,7 @@ impl DsnDesign { width: f64, layer: u64, net: usize, + maybe_pin: Option, ) { // add the first coordinate in the wire path as a dot and save its index let mut prev_pos = Self::pos( @@ -478,14 +494,17 @@ impl DsnDesign { coords[0].y as f64, ); let mut prev_index = layout - .add_fixed_dot(FixedDotWeight { - circle: Circle { - pos: prev_pos, - r: width / 2.0, + .add_fixed_dot( + FixedDotWeight { + circle: Circle { + pos: prev_pos, + r: width / 2.0, + }, + layer, + maybe_net: Some(net), }, - layer, - maybe_net: Some(net), - }) + maybe_pin.clone(), + ) .unwrap(); // iterate through path coords starting from the second @@ -504,14 +523,17 @@ impl DsnDesign { } let index = layout - .add_fixed_dot(FixedDotWeight { - circle: Circle { - pos, - r: width / 2.0, + .add_fixed_dot( + FixedDotWeight { + circle: Circle { + pos, + r: width / 2.0, + }, + layer, + maybe_net: Some(net), }, - layer, - maybe_net: Some(net), - }) + maybe_pin.clone(), + ) .unwrap(); // add a seg between the current and previous coords @@ -524,6 +546,7 @@ impl DsnDesign { layer, maybe_net: Some(net), }, + maybe_pin.clone(), ) .unwrap(); @@ -542,13 +565,15 @@ impl DsnDesign { width: f64, layer: u64, net: usize, + maybe_pin: Option, ) { - let zone = layout.add_compound( + let zone = layout.add_zone( SolidZoneWeight { layer, maybe_net: Some(net), } .into(), + maybe_pin.clone(), ); // add the first coordinate in the wire path as a dot and save its index diff --git a/src/layout/layout.rs b/src/layout/layout.rs index 0ddbcb0..bea5ae3 100644 --- a/src/layout/layout.rs +++ b/src/layout/layout.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use geo::Point; use petgraph::stable_graph::StableDiGraph; use rstar::AABB; @@ -31,11 +33,15 @@ pub type NodeIndex = GenericNode>; #[derive(Debug)] pub struct Layout { drawing: Drawing, + node_to_pin: HashMap, } impl Layout { pub fn new(drawing: Drawing) -> Self { - Self { drawing } + Self { + drawing, + node_to_pin: HashMap::new(), + } } pub fn remove_band(&mut self, band: BandIndex) { @@ -59,8 +65,19 @@ impl Layout { .insert_segbend(from, around, dot_weight, seg_weight, bend_weight, cw) } - pub fn add_fixed_dot(&mut self, weight: FixedDotWeight) -> Result { - self.drawing.add_fixed_dot(weight) + pub fn add_fixed_dot( + &mut self, + weight: FixedDotWeight, + maybe_pin: Option, + ) -> Result { + let dot = self.drawing.add_fixed_dot(weight)?; + + if let Some(pin) = maybe_pin { + self.node_to_pin + .insert(GenericNode::Primitive(dot.into()), pin); + } + + Ok(dot) } pub fn add_zone_fixed_dot( @@ -68,6 +85,7 @@ impl Layout { weight: FixedDotWeight, zone: GenericIndex, ) -> Result { + let pin = self.node_to_pin.get(&GenericNode::Compound(zone)); let maybe_dot = self.drawing.add_fixed_dot(weight); if let Ok(dot) = maybe_dot { @@ -82,8 +100,16 @@ impl Layout { from: FixedDotIndex, to: FixedDotIndex, weight: FixedSegWeight, + maybe_pin: Option, ) -> Result { - self.drawing.add_fixed_seg(from, to, weight) + let seg = self.drawing.add_fixed_seg(from, to, weight)?; + + if let Some(pin) = maybe_pin { + self.node_to_pin + .insert(GenericNode::Primitive(seg.into()), pin); + } + + Ok(seg) } pub fn add_zone_fixed_seg( @@ -93,7 +119,8 @@ impl Layout { weight: FixedSegWeight, zone: GenericIndex, ) -> Result { - let maybe_seg = self.add_fixed_seg(from, to, weight); + let pin = self.node_to_pin.get(&GenericNode::Compound(zone)); + let maybe_seg = self.add_fixed_seg(from, to, weight, pin.cloned()); if let Ok(seg) = maybe_seg { self.drawing.add_to_compound(seg, zone); @@ -124,6 +151,28 @@ impl Layout { self.drawing.move_dot(dot, to) } + pub fn add_zone( + &mut self, + weight: ZoneWeight, + maybe_pin: Option, + ) -> GenericIndex { + let zone = self.drawing.add_compound(weight); + + if let Some(pin) = maybe_pin { + self.node_to_pin + .insert(GenericNode::Compound(zone.into()), pin); + } + + zone + } + + pub fn zones( + &self, + node: GenericIndex, + ) -> impl Iterator> + '_ { + self.drawing.compounds(node) + } + pub fn band_length(&self, face: DotIndex) -> f64 { // TODO. 0.0 @@ -195,7 +244,7 @@ impl Layout { } } -impl CompoundManagerTrait> for Layout { +/*impl CompoundManagerTrait> for Layout { fn add_compound(&mut self, weight: ZoneWeight) -> GenericIndex { self.drawing.add_compound(weight) } @@ -222,4 +271,4 @@ impl CompoundManagerTrait> f ) -> impl Iterator> { self.drawing.compounds(node) } -} +}*/