mirror of https://codeberg.org/topola/topola.git
Optionally assign primitives to pins
This commit is contained in:
parent
3f362d62c3
commit
d77be1b0b3
|
|
@ -7,15 +7,10 @@ use derive_getters::{Dissolve, Getters};
|
||||||
use undoredo::{ApplyDelta, Delta, FlushDelta};
|
use undoredo::{ApplyDelta, Delta, FlushDelta};
|
||||||
|
|
||||||
use crate::layout::{
|
use crate::layout::{
|
||||||
Joint, JointId, Layout, LayoutHalfDelta, NetId, Polygon, PolygonId, Segment, SegmentId, Via,
|
Joint, JointId, Layout, LayoutHalfDelta, NetId, PinId, Polygon, PolygonId, Segment, SegmentId,
|
||||||
ViaId,
|
Via, ViaId,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Layer {
|
|
||||||
name: String,
|
|
||||||
index: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Getters)]
|
#[derive(Clone, Debug, Getters)]
|
||||||
pub struct Board {
|
pub struct Board {
|
||||||
layout: Layout,
|
layout: Layout,
|
||||||
|
|
@ -23,6 +18,8 @@ pub struct Board {
|
||||||
layer_names: BiBTreeMap<usize, String>,
|
layer_names: BiBTreeMap<usize, String>,
|
||||||
#[getter(skip)]
|
#[getter(skip)]
|
||||||
net_names: BiBTreeMap<NetId, String>,
|
net_names: BiBTreeMap<NetId, String>,
|
||||||
|
#[getter(skip)]
|
||||||
|
pin_names: BiBTreeMap<PinId, String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Board {
|
impl Board {
|
||||||
|
|
@ -31,6 +28,7 @@ impl Board {
|
||||||
layout: Layout::new(boundary, layer_count),
|
layout: Layout::new(boundary, layer_count),
|
||||||
layer_names: BiBTreeMap::new(),
|
layer_names: BiBTreeMap::new(),
|
||||||
net_names: BiBTreeMap::new(),
|
net_names: BiBTreeMap::new(),
|
||||||
|
pin_names: BiBTreeMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -44,9 +42,21 @@ impl Board {
|
||||||
layout: Layout::new(boundary, layer_count),
|
layout: Layout::new(boundary, layer_count),
|
||||||
layer_names,
|
layer_names,
|
||||||
net_names,
|
net_names,
|
||||||
|
pin_names: BiBTreeMap::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn ensure_pin(&mut self, pin_name: String) -> PinId {
|
||||||
|
if let Some(pin) = self.pin_names.get_by_right(&pin_name) {
|
||||||
|
return *pin;
|
||||||
|
};
|
||||||
|
|
||||||
|
let pin_id = self.layout.add_pin();
|
||||||
|
self.pin_names.insert(pin_id, pin_name);
|
||||||
|
|
||||||
|
pin_id
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_joint(&mut self, joint: Joint) -> JointId {
|
pub fn add_joint(&mut self, joint: Joint) -> JointId {
|
||||||
self.layout.add_joint(joint)
|
self.layout.add_joint(joint)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,42 @@ use derive_getters::{Dissolve, Getters};
|
||||||
use stable_vec::StableVec;
|
use stable_vec::StableVec;
|
||||||
use undoredo::{ApplyDelta, Delta, FlushDelta, Recorder};
|
use undoredo::{ApplyDelta, Delta, FlushDelta, Recorder};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||||
|
pub struct PinId(usize);
|
||||||
|
|
||||||
|
impl PinId {
|
||||||
|
/// Wrap a pin index in a newtype struct.
|
||||||
|
#[inline]
|
||||||
|
pub fn new(id: usize) -> Self {
|
||||||
|
Self(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the underlying index.
|
||||||
|
#[inline]
|
||||||
|
pub fn id(self) -> usize {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct Pin {
|
||||||
|
joints: Vec<JointId>,
|
||||||
|
segments: Vec<SegmentId>,
|
||||||
|
vias: Vec<ViaId>,
|
||||||
|
polygons: Vec<PolygonId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Pin {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
joints: Vec::new(),
|
||||||
|
segments: Vec::new(),
|
||||||
|
vias: Vec::new(),
|
||||||
|
polygons: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||||
pub struct NetId(usize);
|
pub struct NetId(usize);
|
||||||
|
|
||||||
|
|
@ -48,6 +84,7 @@ pub struct Joint {
|
||||||
pub layer: usize,
|
pub layer: usize,
|
||||||
pub radius: u64,
|
pub radius: u64,
|
||||||
pub net: NetId,
|
pub net: NetId,
|
||||||
|
pub pin: Option<PinId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||||
|
|
@ -73,6 +110,7 @@ pub struct Segment {
|
||||||
pub layer: usize,
|
pub layer: usize,
|
||||||
pub half_width: u64,
|
pub half_width: u64,
|
||||||
pub net: NetId,
|
pub net: NetId,
|
||||||
|
pub pin: Option<PinId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||||
|
|
@ -98,6 +136,7 @@ pub struct Via {
|
||||||
pub layer: usize,
|
pub layer: usize,
|
||||||
pub radius: u64,
|
pub radius: u64,
|
||||||
pub net: NetId,
|
pub net: NetId,
|
||||||
|
pub pin: Option<PinId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||||
|
|
@ -122,6 +161,7 @@ pub struct Polygon {
|
||||||
pub vertices: Vec<[i64; 2]>,
|
pub vertices: Vec<[i64; 2]>,
|
||||||
pub layer: usize,
|
pub layer: usize,
|
||||||
pub net: NetId,
|
pub net: NetId,
|
||||||
|
pub pin: Option<PinId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Getters)]
|
#[derive(Clone, Debug, Getters)]
|
||||||
|
|
@ -130,6 +170,7 @@ pub struct Layout {
|
||||||
place_boundary: Vec<[i64; 2]>,
|
place_boundary: Vec<[i64; 2]>,
|
||||||
layer_count: usize,
|
layer_count: usize,
|
||||||
|
|
||||||
|
pins: StableVec<Pin>,
|
||||||
joints: Recorder<StableVec<Joint>>,
|
joints: Recorder<StableVec<Joint>>,
|
||||||
segments: Recorder<StableVec<Segment>>,
|
segments: Recorder<StableVec<Segment>>,
|
||||||
vias: Recorder<StableVec<Via>>,
|
vias: Recorder<StableVec<Via>>,
|
||||||
|
|
@ -143,6 +184,7 @@ impl Layout {
|
||||||
place_boundary: boundary,
|
place_boundary: boundary,
|
||||||
layer_count,
|
layer_count,
|
||||||
|
|
||||||
|
pins: StableVec::new(),
|
||||||
joints: Recorder::new(StableVec::new()),
|
joints: Recorder::new(StableVec::new()),
|
||||||
segments: Recorder::new(StableVec::new()),
|
segments: Recorder::new(StableVec::new()),
|
||||||
vias: Recorder::new(StableVec::new()),
|
vias: Recorder::new(StableVec::new()),
|
||||||
|
|
@ -150,20 +192,52 @@ impl Layout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_pin(&mut self) -> PinId {
|
||||||
|
PinId::new(self.pins.push(Pin::new()))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_joint(&mut self, joint: Joint) -> JointId {
|
pub fn add_joint(&mut self, joint: Joint) -> JointId {
|
||||||
JointId::new(self.joints.push(joint))
|
let pin_id = joint.pin;
|
||||||
|
let joint_id = JointId::new(self.joints.push(joint));
|
||||||
|
|
||||||
|
if let Some(pin_id) = pin_id {
|
||||||
|
self.pins[pin_id.id()].joints.push(joint_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
joint_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_segment(&mut self, segment: Segment) -> SegmentId {
|
pub fn add_segment(&mut self, segment: Segment) -> SegmentId {
|
||||||
SegmentId::new(self.segments.push(segment))
|
let pin_id = segment.pin;
|
||||||
|
let segment_id = SegmentId::new(self.segments.push(segment));
|
||||||
|
|
||||||
|
if let Some(pin_id) = pin_id {
|
||||||
|
self.pins[pin_id.id()].segments.push(segment_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
segment_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_via(&mut self, via: Via) -> ViaId {
|
pub fn add_via(&mut self, via: Via) -> ViaId {
|
||||||
ViaId::new(self.vias.push(via))
|
let pin_id = via.pin;
|
||||||
|
let via_id = ViaId::new(self.vias.push(via));
|
||||||
|
|
||||||
|
if let Some(pin_id) = pin_id {
|
||||||
|
self.pins[pin_id.id()].vias.push(via_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
via_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_polygon(&mut self, polygon: Polygon) -> PolygonId {
|
pub fn add_polygon(&mut self, polygon: Polygon) -> PolygonId {
|
||||||
PolygonId::new(self.polygons.push(polygon))
|
let pin_id = polygon.pin;
|
||||||
|
let polygon_id = PolygonId::new(self.polygons.push(polygon));
|
||||||
|
|
||||||
|
if let Some(pin_id) = pin_id {
|
||||||
|
self.pins[pin_id.id()].polygons.push(polygon_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
polygon_id
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn segment_endpoints(&self, segment: SegmentId) -> [[i64; 2]; 2] {
|
pub fn segment_endpoints(&self, segment: SegmentId) -> [[i64; 2]; 2] {
|
||||||
|
|
@ -173,6 +247,10 @@ impl Layout {
|
||||||
self.joints.get(&endjoints[1].id()).unwrap().position,
|
self.joints.get(&endjoints[1].id()).unwrap().position,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pin(&self, pin: PinId) -> &Pin {
|
||||||
|
&self.pins[pin.id()]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Dissolve)]
|
#[derive(Clone, Debug, Dissolve)]
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ use specctra::{
|
||||||
use crate::{
|
use crate::{
|
||||||
Segment,
|
Segment,
|
||||||
board::Board,
|
board::Board,
|
||||||
layout::{Joint, NetId, Polygon},
|
layout::{Joint, NetId, PinId, Polygon},
|
||||||
math::Vector2,
|
math::Vector2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -104,6 +104,7 @@ impl Board {
|
||||||
|
|
||||||
for pin in &image.pins {
|
for pin in &image.pins {
|
||||||
let pin_name = format!("{}-{}", place.name, pin.id);
|
let pin_name = format!("{}-{}", place.name, pin.id);
|
||||||
|
let pin_id = board.ensure_pin(pin_name.clone());
|
||||||
let net = pin_nets.get(&pin_name).copied().unwrap();
|
let net = pin_nets.get(&pin_name).copied().unwrap();
|
||||||
let padstack = dsn.pcb.library.find_padstack_by_name(&pin.name).unwrap();
|
let padstack = dsn.pcb.library.find_padstack_by_name(&pin.name).unwrap();
|
||||||
|
|
||||||
|
|
@ -118,6 +119,7 @@ impl Board {
|
||||||
(circle.diameter / 2.0) as u64,
|
(circle.diameter / 2.0) as u64,
|
||||||
layer,
|
layer,
|
||||||
net,
|
net,
|
||||||
|
Some(pin_id),
|
||||||
!place_side_is_front,
|
!place_side_is_front,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -133,6 +135,7 @@ impl Board {
|
||||||
rect.y2,
|
rect.y2,
|
||||||
layer,
|
layer,
|
||||||
net,
|
net,
|
||||||
|
Some(pin_id),
|
||||||
!place_side_is_front,
|
!place_side_is_front,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -146,6 +149,7 @@ impl Board {
|
||||||
path.width,
|
path.width,
|
||||||
layer,
|
layer,
|
||||||
net,
|
net,
|
||||||
|
Some(pin_id),
|
||||||
!place_side_is_front,
|
!place_side_is_front,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -159,6 +163,7 @@ impl Board {
|
||||||
polygon.width,
|
polygon.width,
|
||||||
layer,
|
layer,
|
||||||
net,
|
net,
|
||||||
|
Some(pin_id),
|
||||||
!place_side_is_front,
|
!place_side_is_front,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -187,6 +192,7 @@ impl Board {
|
||||||
(circle.diameter / 2.0) as u64,
|
(circle.diameter / 2.0) as u64,
|
||||||
layer,
|
layer,
|
||||||
net,
|
net,
|
||||||
|
None,
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -202,6 +208,7 @@ impl Board {
|
||||||
rect.y2,
|
rect.y2,
|
||||||
layer,
|
layer,
|
||||||
net,
|
net,
|
||||||
|
None,
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -215,6 +222,7 @@ impl Board {
|
||||||
path.width,
|
path.width,
|
||||||
layer,
|
layer,
|
||||||
net,
|
net,
|
||||||
|
None,
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -228,6 +236,7 @@ impl Board {
|
||||||
polygon.width,
|
polygon.width,
|
||||||
layer,
|
layer,
|
||||||
net,
|
net,
|
||||||
|
None,
|
||||||
false,
|
false,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -247,6 +256,7 @@ impl Board {
|
||||||
wire.path.width,
|
wire.path.width,
|
||||||
layer,
|
layer,
|
||||||
net,
|
net,
|
||||||
|
None,
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -257,16 +267,18 @@ impl Board {
|
||||||
fn place_circle(
|
fn place_circle(
|
||||||
board: &mut Board,
|
board: &mut Board,
|
||||||
place: PointWithRotation,
|
place: PointWithRotation,
|
||||||
pin: PointWithRotation,
|
pin_pos: PointWithRotation,
|
||||||
radius: u64,
|
radius: u64,
|
||||||
layer: usize,
|
layer: usize,
|
||||||
net: NetId,
|
net: NetId,
|
||||||
|
pin: Option<PinId>,
|
||||||
flip: bool,
|
flip: bool,
|
||||||
) {
|
) {
|
||||||
board.add_joint(Joint {
|
board.add_joint(Joint {
|
||||||
position: Self::pos(place, pin, 0.0, 0.0, flip),
|
position: Self::pos(place, pin_pos, 0.0, 0.0, flip),
|
||||||
layer,
|
layer,
|
||||||
net,
|
net,
|
||||||
|
pin,
|
||||||
radius,
|
radius,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -274,49 +286,53 @@ impl Board {
|
||||||
fn place_rect(
|
fn place_rect(
|
||||||
board: &mut Board,
|
board: &mut Board,
|
||||||
place: PointWithRotation,
|
place: PointWithRotation,
|
||||||
pin: PointWithRotation,
|
pin_pos: PointWithRotation,
|
||||||
x1: f64,
|
x1: f64,
|
||||||
y1: f64,
|
y1: f64,
|
||||||
x2: f64,
|
x2: f64,
|
||||||
y2: f64,
|
y2: f64,
|
||||||
layer: usize,
|
layer: usize,
|
||||||
net: NetId,
|
net: NetId,
|
||||||
|
pin: Option<PinId>,
|
||||||
flip: bool,
|
flip: bool,
|
||||||
) {
|
) {
|
||||||
board.add_polygon(Polygon {
|
board.add_polygon(Polygon {
|
||||||
vertices: vec![
|
vertices: vec![
|
||||||
Self::pos(place, pin, x1, y1, flip),
|
Self::pos(place, pin_pos, x1, y1, flip),
|
||||||
Self::pos(place, pin, x2, y1, flip),
|
Self::pos(place, pin_pos, x2, y1, flip),
|
||||||
Self::pos(place, pin, x2, y2, flip),
|
Self::pos(place, pin_pos, x2, y2, flip),
|
||||||
Self::pos(place, pin, x1, y2, flip),
|
Self::pos(place, pin_pos, x1, y2, flip),
|
||||||
],
|
],
|
||||||
layer,
|
layer,
|
||||||
net,
|
net,
|
||||||
|
pin,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn place_path(
|
fn place_path(
|
||||||
board: &mut Board,
|
board: &mut Board,
|
||||||
place: PointWithRotation,
|
place: PointWithRotation,
|
||||||
pin: PointWithRotation,
|
pin_pos: PointWithRotation,
|
||||||
coords: &[Point],
|
coords: &[Point],
|
||||||
width: f64,
|
width: f64,
|
||||||
layer: usize,
|
layer: usize,
|
||||||
net: NetId,
|
net: NetId,
|
||||||
|
pin: Option<PinId>,
|
||||||
flip: bool,
|
flip: bool,
|
||||||
) {
|
) {
|
||||||
// Add the first coordinate in the wire path as a dot and save its index.
|
// Add the first coordinate in the wire path as a dot and save its index.
|
||||||
let mut prev_pos = Self::pos(place, pin, coords[0].x, coords[0].y, flip);
|
let mut prev_pos = Self::pos(place, pin_pos, coords[0].x, coords[0].y, flip);
|
||||||
let mut prev_joint = board.add_joint(Joint {
|
let mut prev_joint = board.add_joint(Joint {
|
||||||
position: prev_pos,
|
position: prev_pos,
|
||||||
layer,
|
layer,
|
||||||
radius: (width / 2.0) as u64,
|
radius: (width / 2.0) as u64,
|
||||||
net,
|
net,
|
||||||
|
pin,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Iterate through path coords starting from the second.
|
// Iterate through path coords starting from the second.
|
||||||
for coord in coords.iter().skip(1) {
|
for coord in coords.iter().skip(1) {
|
||||||
let pos = Self::pos(place, pin, coord.x, coord.y, flip);
|
let pos = Self::pos(place, pin_pos, coord.x, coord.y, flip);
|
||||||
|
|
||||||
if pos == prev_pos {
|
if pos == prev_pos {
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -327,6 +343,7 @@ impl Board {
|
||||||
layer,
|
layer,
|
||||||
radius: (width / 2.0) as u64,
|
radius: (width / 2.0) as u64,
|
||||||
net,
|
net,
|
||||||
|
pin,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add a seg between the current and previous coords.
|
// Add a seg between the current and previous coords.
|
||||||
|
|
@ -335,6 +352,7 @@ impl Board {
|
||||||
layer,
|
layer,
|
||||||
half_width: (width / 2.0) as u64,
|
half_width: (width / 2.0) as u64,
|
||||||
net,
|
net,
|
||||||
|
pin,
|
||||||
});
|
});
|
||||||
|
|
||||||
prev_pos = pos;
|
prev_pos = pos;
|
||||||
|
|
@ -345,21 +363,23 @@ impl Board {
|
||||||
fn place_polygon(
|
fn place_polygon(
|
||||||
board: &mut Board,
|
board: &mut Board,
|
||||||
place: PointWithRotation,
|
place: PointWithRotation,
|
||||||
pin: PointWithRotation,
|
pin_pos: PointWithRotation,
|
||||||
coords: &[Point],
|
coords: &[Point],
|
||||||
width: f64,
|
width: f64,
|
||||||
layer: usize,
|
layer: usize,
|
||||||
net: NetId,
|
net: NetId,
|
||||||
|
pin: Option<PinId>,
|
||||||
flip: bool,
|
flip: bool,
|
||||||
) {
|
) {
|
||||||
let vertices: Vec<[i64; 2]> = coords
|
let vertices: Vec<[i64; 2]> = coords
|
||||||
.iter()
|
.iter()
|
||||||
.map(|coord| Self::pos(place, pin, coord.x, coord.y, flip))
|
.map(|coord| Self::pos(place, pin_pos, coord.x, coord.y, flip))
|
||||||
.collect();
|
.collect();
|
||||||
board.add_polygon(Polygon {
|
board.add_polygon(Polygon {
|
||||||
vertices,
|
vertices,
|
||||||
layer,
|
layer,
|
||||||
net,
|
net,
|
||||||
|
pin,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue