substrate/layout/
element.rs

1//! Basic layout elements.
2//!
3//! Substrate layouts consist of cells, instances, geometric shapes, and text annotations.
4
5use std::{collections::HashMap, sync::Arc};
6
7use arcstr::ArcStr;
8use geometry::{
9    prelude::{Bbox, Point},
10    rect::Rect,
11    transform::{
12        Transform, TransformMut, TransformRef, Transformation, Translate, TranslateMut,
13        TranslateRef,
14    },
15};
16use indexmap::IndexMap;
17use layir::{LayerBbox, Shape, Text};
18use serde::{Deserialize, Serialize};
19
20use crate::types::layout::PortGeometry;
21use crate::{
22    error::{Error, Result},
23    types::NameBuf,
24};
25
26use super::{Draw, DrawReceiver, Instance, Layout, schema::Schema};
27
28/// A context-wide unique identifier for a cell.
29#[derive(
30    Default, Debug, Copy, Clone, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord,
31)]
32pub struct CellId(u64);
33
34impl CellId {
35    pub(crate) fn increment(&mut self) {
36        *self = CellId(self.0 + 1)
37    }
38}
39
40/// A mapping from names to ports.
41pub type NamedPorts<L> = IndexMap<NameBuf, PortGeometry<L>>;
42
43/// A raw layout cell.
44#[derive(Default, Debug, Clone, PartialEq)]
45pub struct RawCell<L> {
46    pub(crate) id: CellId,
47    pub(crate) name: ArcStr,
48    pub(crate) elements: Vec<Element<L>>,
49    ports: NamedPorts<L>,
50    port_names: HashMap<String, NameBuf>,
51}
52
53impl<L> RawCell<L> {
54    pub(crate) fn new(id: CellId, name: impl Into<ArcStr>) -> Self {
55        Self {
56            id,
57            name: name.into(),
58            elements: Vec::new(),
59            ports: IndexMap::new(),
60            port_names: HashMap::new(),
61        }
62    }
63
64    pub(crate) fn with_ports(self, ports: NamedPorts<L>) -> Self {
65        let port_names = ports.keys().map(|k| (k.to_string(), k.clone())).collect();
66        Self {
67            ports,
68            port_names,
69            ..self
70        }
71    }
72
73    #[doc(hidden)]
74    pub fn port_map(&self) -> &NamedPorts<L> {
75        &self.ports
76    }
77
78    #[allow(dead_code)]
79    pub(crate) fn add_element(&mut self, elem: impl Into<Element<L>>) {
80        self.elements.push(elem.into());
81    }
82
83    #[allow(dead_code)]
84    pub(crate) fn add_elements(&mut self, elems: impl IntoIterator<Item = impl Into<Element<L>>>) {
85        self.elements.extend(elems.into_iter().map(|x| x.into()));
86    }
87
88    /// The ID of this cell.
89    pub fn id(&self) -> CellId {
90        self.id
91    }
92
93    /// Returns an iterator over the elements of this cell.
94    pub fn elements(&self) -> impl Iterator<Item = &Element<L>> {
95        self.elements.iter()
96    }
97
98    /// Returns an iterator over the ports of this cell, as `(name, geometry)` pairs.
99    pub fn ports(&self) -> impl Iterator<Item = (&NameBuf, &PortGeometry<L>)> {
100        self.ports.iter()
101    }
102
103    /// Returns a reference to the port with the given name, if it exists.
104    pub fn port_named(&self, name: &str) -> Option<&PortGeometry<L>> {
105        let name_buf = self.port_names.get(name)?;
106        self.ports.get(name_buf)
107    }
108}
109
110impl<L> Bbox for RawCell<L> {
111    fn bbox(&self) -> Option<geometry::rect::Rect> {
112        self.elements.bbox()
113    }
114}
115
116impl<L: PartialEq> LayerBbox<L> for RawCell<L> {
117    fn layer_bbox(&self, layer: &L) -> Option<Rect> {
118        self.elements.layer_bbox(layer)
119    }
120}
121
122impl<L: Clone> TranslateRef for RawCell<L> {
123    fn translate_ref(&self, p: Point) -> Self {
124        Self {
125            id: self.id,
126            name: self.name.clone(),
127            elements: self.elements.translate_ref(p),
128            ports: self
129                .ports
130                .iter()
131                .map(|(k, v)| (k.clone(), v.translate_ref(p)))
132                .collect(),
133            port_names: self.port_names.clone(),
134        }
135    }
136}
137
138impl<L: Clone> TransformRef for RawCell<L> {
139    fn transform_ref(&self, trans: Transformation) -> Self {
140        Self {
141            id: self.id,
142            name: self.name.clone(),
143            elements: self.elements.transform_ref(trans),
144            ports: self
145                .ports
146                .iter()
147                .map(|(k, v)| (k.clone(), v.transform_ref(trans)))
148                .collect(),
149            port_names: self.port_names.clone(),
150        }
151    }
152}
153
154/// A raw layout instance.
155///
156/// Consists of a pointer to an underlying cell and its instantiated transformation.
157#[derive(Default, Debug, Clone, PartialEq)]
158#[allow(dead_code)]
159pub struct RawInstance<L> {
160    pub(crate) cell: Arc<RawCell<L>>,
161    pub(crate) trans: Transformation,
162}
163
164impl<L> RawInstance<L> {
165    /// Create a new raw instance of the given cell.
166    pub fn new(cell: impl Into<Arc<RawCell<L>>>, trans: Transformation) -> Self {
167        Self {
168            cell: cell.into(),
169            trans,
170        }
171    }
172
173    /// Returns a raw reference to the child cell.
174    ///
175    /// The returned cell does not store any information related
176    /// to this instance's transformation.
177    /// Consider using [`RawInstance::cell`] instead.
178    #[inline]
179    pub fn raw_cell(&self) -> &RawCell<L> {
180        &self.cell
181    }
182}
183
184impl<L: Clone> RawInstance<L> {
185    /// Returns a reference to the child cell.
186    ///
187    /// The returned object provides coordinates in the parent cell's coordinate system.
188    /// If you want coordinates in the child cell's coordinate system,
189    /// consider using [`RawInstance::raw_cell`] instead.
190    #[inline]
191    pub fn cell(&self) -> RawCell<L> {
192        self.cell.transform_ref(self.trans)
193    }
194}
195
196impl<L> Bbox for RawInstance<L> {
197    fn bbox(&self) -> Option<Rect> {
198        self.cell.bbox().map(|rect| rect.transform(self.trans))
199    }
200}
201
202impl<L: PartialEq> LayerBbox<L> for RawInstance<L> {
203    fn layer_bbox(&self, layer: &L) -> Option<Rect> {
204        self.cell
205            .layer_bbox(layer)
206            .map(|rect| rect.transform(self.trans))
207    }
208}
209
210impl<T: Layout> TryFrom<Instance<T>> for RawInstance<<T::Schema as Schema>::Layer> {
211    type Error = Error;
212
213    fn try_from(value: Instance<T>) -> Result<Self> {
214        Ok(Self {
215            cell: value.try_cell()?.raw,
216            trans: value.trans,
217        })
218    }
219}
220
221impl<S: Schema> Draw<S> for RawInstance<S::Layer> {
222    fn draw(self, recv: &mut DrawReceiver<S>) -> Result<()> {
223        recv.draw_element(self);
224        Ok(())
225    }
226}
227
228impl<L> TranslateMut for RawInstance<L> {
229    fn translate_mut(&mut self, p: Point) {
230        self.transform_mut(Transformation::from_offset(p));
231    }
232}
233
234impl<L> TransformMut for RawInstance<L> {
235    fn transform_mut(&mut self, trans: Transformation) {
236        self.trans = Transformation::cascade(trans, self.trans);
237    }
238}
239
240impl<L: Clone> TranslateRef for RawInstance<L> {
241    fn translate_ref(&self, p: Point) -> Self {
242        self.clone().translate(p)
243    }
244}
245
246impl<L: Clone> TransformRef for RawInstance<L> {
247    fn transform_ref(&self, trans: Transformation) -> Self {
248        self.clone().transform(trans)
249    }
250}
251
252impl<S: Schema> Draw<S> for Shape<S::Layer> {
253    fn draw(self, recv: &mut DrawReceiver<S>) -> Result<()> {
254        recv.draw_element(self);
255        Ok(())
256    }
257}
258
259impl<S: Schema> Draw<S> for Text<S::Layer> {
260    fn draw(self, recv: &mut DrawReceiver<S>) -> Result<()> {
261        recv.draw_element(self);
262        Ok(())
263    }
264}
265
266/// A primitive layout element.
267#[derive(Debug, Clone, PartialEq)]
268pub enum Element<L> {
269    /// A raw layout instance.
270    Instance(RawInstance<L>),
271    /// A primitive layout shape.
272    Shape(Shape<L>),
273    /// A primitive text annotation.
274    Text(Text<L>),
275}
276
277/// A pointer to a primitive layout element.
278#[derive(Debug, Clone, Copy, PartialEq)]
279pub enum ElementRef<'a, L> {
280    /// A raw layout instance.
281    Instance(&'a RawInstance<L>),
282    /// A primitive layout shape.
283    Shape(&'a Shape<L>),
284    /// A primitive text annotation.
285    Text(&'a Text<L>),
286}
287
288impl<L> Element<L> {
289    /// Converts from `&Element` to `ElementRef`.
290    ///
291    /// Produces a new `ElementRef` containing a reference into
292    /// the original element, but leaves the original in place.
293    pub fn as_ref(&self) -> ElementRef<'_, L> {
294        match self {
295            Self::Instance(x) => ElementRef::Instance(x),
296            Self::Shape(x) => ElementRef::Shape(x),
297            Self::Text(x) => ElementRef::Text(x),
298        }
299    }
300
301    /// If this is an `Instance` variant, returns the contained instance.
302    /// Otherwise, returns [`None`].
303    pub fn instance(self) -> Option<RawInstance<L>> {
304        match self {
305            Self::Instance(x) => Some(x),
306            _ => None,
307        }
308    }
309
310    /// If this is a `Shape` variant, returns the contained shape.
311    /// Otherwise, returns [`None`].
312    pub fn shape(self) -> Option<Shape<L>> {
313        match self {
314            Self::Shape(x) => Some(x),
315            _ => None,
316        }
317    }
318
319    /// If this is a `Text` variant, returns the contained text.
320    /// Otherwise, returns [`None`].
321    pub fn text(self) -> Option<Text<L>> {
322        match self {
323            Self::Text(x) => Some(x),
324            _ => None,
325        }
326    }
327}
328
329impl<L> From<layir::Element<L>> for Element<L> {
330    fn from(value: layir::Element<L>) -> Self {
331        match value {
332            layir::Element::Text(t) => Self::Text(t),
333            layir::Element::Shape(s) => Self::Shape(s),
334        }
335    }
336}
337
338impl<'a, L> ElementRef<'a, L> {
339    /// If this is an `Instance` variant, returns the contained instance.
340    /// Otherwise, returns [`None`].
341    pub fn instance(self) -> Option<&'a RawInstance<L>> {
342        match self {
343            Self::Instance(x) => Some(x),
344            _ => None,
345        }
346    }
347
348    /// If this is a `Shape` variant, returns the contained shape.
349    /// Otherwise, returns [`None`].
350    pub fn shape(self) -> Option<&'a Shape<L>> {
351        match self {
352            Self::Shape(x) => Some(x),
353            _ => None,
354        }
355    }
356
357    /// If this is a `Text` variant, returns the contained text.
358    /// Otherwise, returns [`None`].
359    pub fn text(self) -> Option<&'a Text<L>> {
360        match self {
361            Self::Text(x) => Some(x),
362            _ => None,
363        }
364    }
365}
366
367impl<L> Bbox for Element<L> {
368    fn bbox(&self) -> Option<geometry::rect::Rect> {
369        match self {
370            Element::Instance(inst) => inst.bbox(),
371            Element::Shape(shape) => shape.bbox(),
372            Element::Text(_) => None,
373        }
374    }
375}
376
377impl<L: PartialEq> LayerBbox<L> for Element<L> {
378    fn layer_bbox(&self, layer: &L) -> Option<geometry::rect::Rect> {
379        match self {
380            Element::Instance(inst) => inst.layer_bbox(layer),
381            Element::Shape(shape) => shape.layer_bbox(layer),
382            Element::Text(_) => None,
383        }
384    }
385}
386
387impl<L> From<RawInstance<L>> for Element<L> {
388    fn from(value: RawInstance<L>) -> Self {
389        Self::Instance(value)
390    }
391}
392
393impl<L> From<Shape<L>> for Element<L> {
394    fn from(value: Shape<L>) -> Self {
395        Self::Shape(value)
396    }
397}
398
399impl<L> From<Text<L>> for Element<L> {
400    fn from(value: Text<L>) -> Self {
401        Self::Text(value)
402    }
403}
404
405impl<L: Clone> TranslateRef for Element<L> {
406    fn translate_ref(&self, p: Point) -> Self {
407        self.clone().translate(p)
408    }
409}
410
411impl<L: Clone> TransformRef for Element<L> {
412    fn transform_ref(&self, trans: Transformation) -> Self {
413        self.clone().transform(trans)
414    }
415}
416
417impl<L> TranslateMut for Element<L> {
418    fn translate_mut(&mut self, p: Point) {
419        match self {
420            Element::Instance(inst) => inst.translate_mut(p),
421            Element::Shape(shape) => shape.translate_mut(p),
422            Element::Text(text) => text.translate_mut(p),
423        }
424    }
425}
426
427impl<L> TransformMut for Element<L> {
428    fn transform_mut(&mut self, trans: Transformation) {
429        match self {
430            Element::Instance(inst) => inst.transform_mut(trans),
431            Element::Shape(shape) => shape.transform_mut(trans),
432            Element::Text(text) => text.transform_mut(trans),
433        }
434    }
435}
436
437impl<S: Schema> Draw<S> for Element<S::Layer> {
438    fn draw(self, cell: &mut DrawReceiver<S>) -> Result<()> {
439        cell.draw_element(self);
440        Ok(())
441    }
442}
443
444impl<L> Bbox for ElementRef<'_, L> {
445    fn bbox(&self) -> Option<geometry::rect::Rect> {
446        match self {
447            ElementRef::Instance(inst) => inst.bbox(),
448            ElementRef::Shape(shape) => shape.bbox(),
449            ElementRef::Text(_) => None,
450        }
451    }
452}
453
454impl<L: PartialEq> LayerBbox<L> for ElementRef<'_, L> {
455    fn layer_bbox(&self, layer: &L) -> Option<Rect> {
456        match self {
457            ElementRef::Instance(inst) => inst.layer_bbox(layer),
458            ElementRef::Shape(shape) => shape.layer_bbox(layer),
459            ElementRef::Text(_) => None,
460        }
461    }
462}
463
464impl<'a, L> From<&'a RawInstance<L>> for ElementRef<'a, L> {
465    fn from(value: &'a RawInstance<L>) -> Self {
466        Self::Instance(value)
467    }
468}
469
470impl<'a, L> From<&'a Shape<L>> for ElementRef<'a, L> {
471    fn from(value: &'a Shape<L>) -> Self {
472        Self::Shape(value)
473    }
474}
475
476impl<'a, L> From<&'a Text<L>> for ElementRef<'a, L> {
477    fn from(value: &'a Text<L>) -> Self {
478        Self::Text(value)
479    }
480}