Skip to content

Commit

Permalink
Merge pull request dan-fritchman#16 from colepoirier/main
Browse files Browse the repository at this point in the history
Add some derives, implemetn import_abstact, use Polygon instead of Element in a few places
  • Loading branch information
dan-fritchman authored Jul 14, 2022
2 parents d7f5fe2 + d97c2d3 commit 404abfb
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 70 deletions.
45 changes: 34 additions & 11 deletions layout21raw/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use slotmap::{new_key_type, SlotMap};
use crate::{
bbox::{BoundBox, BoundBoxTrait},
error::{LayoutError, LayoutResult},
geom::{Point, Shape, Transform, TransformTrait},
geom::{Point, Polygon, Shape, Transform, TransformTrait},
utils::{Ptr, PtrList},
};

Expand Down Expand Up @@ -115,7 +115,7 @@ impl SiUnits {
}

/// Instance of another Cell
#[derive(Debug, Clone)]
#[derive(Debug, Clone, PartialEq)]
pub struct Instance {
/// Instance Name
pub inst_name: String,
Expand All @@ -136,7 +136,7 @@ pub struct Instance {
///
/// Keep track of active layers, and index them by name and number.
///
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[derive(Debug, Default, Clone, Serialize, Deserialize)]
pub struct Layers {
pub slots: SlotMap<LayerKey, Layer>,
pub nums: HashMap<i16, LayerKey>,
Expand Down Expand Up @@ -243,9 +243,16 @@ pub enum LayerPurpose {
/// Other purpose, not first-class supported nor named
Other(i16),
}

impl Default for LayerPurpose {
fn default() -> Self {
Self::Drawing
}
}

/// # Layer Specification
/// As in seemingly every layout system, this uses two numbers to identify each layer.
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct LayerSpec(i16, i16);
impl LayerSpec {
pub fn new(n1: i16, n2: i16) -> Self {
Expand All @@ -265,6 +272,19 @@ pub struct Layer {
/// Purpose => Number Lookup
nums: HashMap<LayerPurpose, i16>,
}

impl PartialOrd for Layer {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(&other))
}
}

impl Ord for Layer {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.layernum.cmp(&other.layernum)
}
}

impl Layer {
/// Create a new [Layer] with the given `layernum` and `name`
pub fn new(layernum: i16, name: impl Into<String>) -> Self {
Expand Down Expand Up @@ -324,20 +344,21 @@ impl Layer {
/// Raw Abstract-Layout
/// Contains geometric [Element]s generally representing pins and blockages
/// Does not contain instances, arrays, or layout-implementation details
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Abstract {
/// Cell Name
pub name: String,
/// Outline
pub outline: Element,
pub outline: Polygon,
/// Ports
pub ports: Vec<AbstractPort>,
/// Blockages
pub blockages: HashMap<LayerKey, Vec<Shape>>,
}
impl Abstract {
/// Create a new [Abstract] with the given `name`
pub fn new(name: impl Into<String>, outline: Element) -> Self {
pub fn new(name: impl Into<String>, outline: Polygon) -> Self {
let name = name.into();
Self {
name,
Expand All @@ -348,7 +369,7 @@ impl Abstract {
}
}
/// # Port Element for [Abstract]s
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct AbstractPort {
/// Net Name
pub net: String,
Expand Down Expand Up @@ -429,7 +450,7 @@ impl<'lib> DepOrder<'lib> {
}

/// Collection of the Views describing a Cell
#[derive(Debug, Default, Clone)]
#[derive(Debug, Default, Clone, PartialEq)]
pub struct Cell {
// Cell Name
pub name: String,
Expand Down Expand Up @@ -472,7 +493,7 @@ impl From<Layout> for Cell {
/// The geometric-level layout-definition of a [Cell].
/// Comprised of geometric [Element]s and instances of other [Cell] [Layout]s.
///
#[derive(Debug, Clone, Default)]
#[derive(Debug, Clone, Default, PartialEq)]
pub struct Layout {
/// Cell Name
pub name: String,
Expand Down Expand Up @@ -553,7 +574,7 @@ pub struct TextElement {
/// Combines a geometric [Shape] with a z-axis [Layer],
/// and optional net connectivity annotation.
///
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Element {
/// Net Name
pub net: Option<String>,
Expand All @@ -568,6 +589,8 @@ pub struct Element {
/// Location, orientation, and angular rotation for an [Instance]
/// Note these fields exist "flat" in [Instance] as well,
/// and are grouped here for convenience.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct InstancePlace {
/// Location of `cell` origin
/// regardless of rotation or reflection
Expand Down
30 changes: 23 additions & 7 deletions layout21raw/src/gds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::collections::{HashMap, HashSet};
use std::convert::{TryFrom, TryInto};
use std::hash::Hash;

use gds21::GdsElement;
// Crates.io
use slotmap::{new_key_type, SlotMap};

Expand Down Expand Up @@ -118,20 +119,35 @@ impl<'lib> GdsExporter<'lib> {

let mut elems = Vec::with_capacity(1 + abs.ports.len());

// Flatten our points-vec, converting to 32-bit along the way
let mut xy = abs
.outline
.points
.iter()
.map(|p| self.export_point(p))
.collect::<Result<Vec<_>, _>>()?;
// Add the origin a second time, to "close" the polygon
xy.push(self.export_point(&abs.outline.points[0])?);
let outline = GdsElement::GdsBoundary(gds21::GdsBoundary {
layer: i16::MAX,
datatype: i16::MAX,
xy,
..Default::default()
});
// Blockages do not map to GDSII elements.
// Conversion includes the abstract's name, outline and ports.
elems.extend(self.export_element(&abs.outline)?);
elems.push(outline);

// Convert each [AbstractPort]
for port in abs.ports.iter() {
elems.extend(self.export_abstract_port(&port)?);
}

// Create and return a [GdsStruct]
let mut strukt = gds21::GdsStruct::new(&abs.name);
strukt.elems = elems;
let mut gds_struct = gds21::GdsStruct::new(&abs.name);
gds_struct.elems = elems;
self.ctx.pop();
Ok(strukt)
Ok(gds_struct)
}
/// Export an [AbstractPort]
pub fn export_abstract_port(
Expand Down Expand Up @@ -354,9 +370,9 @@ impl ErrorHelper for GdsExporter<'_> {
///
/// Trait for calculating the location of text-labels, generally per [Shape].
///
/// Sole function `label_location` calculates an appropriate location,
/// or returns a [LayoutError] if one cannot be found.
///
/// Sole function `label_location` calculates an appropriate location,
/// or returns a [LayoutError] if one cannot be found.
///
/// While Layout21 formats do not include "placed text", GDSII relies on it for connectivity annotations.
/// How to place these labels varies by shape type.
///
Expand Down
9 changes: 8 additions & 1 deletion layout21raw/src/geom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,13 @@ pub enum Shape {
Polygon(Polygon),
Path(Path),
}

impl Default for Shape {
fn default() -> Self {
Self::Rect(Rect::default())
}
}

impl Shape {
/// Boolean indication of whether we intersect with [Shape] `other`.
pub fn intersects(&self, other: &Shape) -> bool {
Expand Down Expand Up @@ -345,7 +352,7 @@ impl ShapeTrait for Path {
/// 2x2 rotation-matrix and two-entry translation vector,
/// used for relative movement of [Point]s and [Shape]s.
///
#[derive(Debug, Default, Clone)]
#[derive(Debug, Default, Clone, Copy, PartialEq)]
pub struct Transform {
/// Rotation / Transformation Matrix
/// Represented in row-major order
Expand Down
35 changes: 17 additions & 18 deletions layout21raw/src/lef.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::convert::{TryFrom, TryInto};
use crate::utils::{ErrorContext, ErrorHelper, Ptr};
use crate::{
Abstract, AbstractPort, Cell, Element, Int, Layer, LayerKey, LayerPurpose, Layers, LayoutError,
LayoutResult, Library, Path, Point, Polygon, Rect, Shape, Units,
LayoutResult, Library, Path, Point, Polygon, Rect, Shape, Units,
};
use lef21;

Expand Down Expand Up @@ -256,7 +256,7 @@ impl LefImporter {
// Grab a [Point] from the `size` field
let lefsize = self.unwrap(lefmacro.size.as_ref(), "Missing LEF size")?;
let lefsize = lef21::LefPoint::new(lefsize.0, lefsize.1);
let lefsize = self.import_point(&lefsize)?;
let Point { x, y } = self.import_point(&lefsize)?;

// FIXME: what layer this goes on.
// Grab one named `boundary`.
Expand All @@ -271,14 +271,14 @@ impl LefImporter {
}
}
};
Element {
net: None,
layer,
purpose: LayerPurpose::Outline,
inner: Shape::Rect(Rect {
p0: Point::new(0, 0),
p1: lefsize,
}),

Polygon {
points: vec![
Point::new(0, 0),
Point::new(x, 0),
Point::new(x, y),
Point::new(0, y),
],
}
};
// Create the [Abstract] to be returned
Expand Down Expand Up @@ -483,14 +483,13 @@ mod tests {
let layers = crate::tests::layers()?;
let a = Abstract {
name: "to_lef1".into(),
outline: Element {
net: None,
layer: layers.keyname("boundary").unwrap(),
purpose: LayerPurpose::Outline,
inner: Shape::Rect(Rect {
p0: Point::new(0, 0),
p1: Point::new(11, 11),
}),
outline: Polygon {
points: vec![
Point::new(0, 0),
Point::new(11, 0),
Point::new(11, 11),
Point::new(0, 11),
],
},
ports: vec![AbstractPort {
net: "port1".into(),
Expand Down
Loading

0 comments on commit 404abfb

Please sign in to comment.