libreda_lefdef/
def_ast.rs

1// SPDX-FileCopyrightText: 2022 Thomas Kramer <code@tkramer.ch>
2//
3// SPDX-License-Identifier: AGPL-3.0-or-later
4
5//! Data types specific to DEF.
6
7use crate::common::{Orient, PinDirection, PropertyType, PropertyValue};
8use crate::stream_parser::LefDefParseError;
9use libreda_db::prelude as db;
10use std::collections::BTreeMap;
11use std::fmt;
12use std::str::FromStr;
13
14/// Integer type used for mask numbers.
15pub type MaskNum = u8;
16/// Integer coordinate type.
17pub type Coord = db::Coord;
18
19/// Representation of a design as defined in DEF.
20#[derive(Clone, Debug)]
21pub struct DEF {
22    /// Version of the DEF syntax.
23    pub version: Option<String>,
24    /// Characters that are used to mark bus bit indices. Default are `[` and `]`.
25    pub busbitchars: (char, char),
26    /// Character used as path separator. Default is `/`.
27    pub dividerchar: char,
28    /// Name of the design.
29    pub design_name: Option<String>,
30    // DESIGN
31    /// Name of the technology.
32    pub technology: Option<String>,
33    /// Distance units per micron.
34    /// Values supported by LEF are: 100, 200, 1000, 2000, 10000, 20000
35    /// The database unit value in LEF must be greater or equal to the one in DEF to avoid round-off errors.
36    pub units: u32,
37    /// Arbitrary text.
38    pub history: Vec<String>,
39    /// Definitions of custom properties used in the design.
40    pub property_definitions: BTreeMap<String, DEFPropertyDefinition>,
41    /// Shape of the die.
42    pub die_area: Option<db::SimpleRPolygon<Coord>>,
43    /// Rows stored by their name.
44    pub rows: BTreeMap<String, Row>,
45    /// Routing grid for standard-cell based designs.
46    pub tracks: Vec<Tracks>,
47    /// TODO
48    pub gcell_grid: Vec<()>,
49    /// Geometry definitions of the vias used in the design.
50    pub vias: BTreeMap<String, ViaDefinition>,
51    /// Styles of wire ends.
52    pub styles: Vec<()>,
53    /// TODO
54    pub nondefault_rules: (),
55    /// Regions are named geometrical locations that can be used to place components.
56    pub regions: BTreeMap<String, Region>,
57    /// Components of the design. This includes placed and unplaced cells and macros.
58    pub components: Vec<Component>,
59    /// Definitions of external pins of the design. Associates external pin names with internal nets and
60    /// pin geometries.
61    pub pins: Vec<Pin>,
62    /// Definitions of pin properties.
63    /// TODO
64    pub pin_properties: (),
65    /// Placement and routing blockages.
66    pub blockages: Vec<Blockage>,
67    /// TODO
68    pub slots: (),
69    ///  TODO
70    pub fills: (),
71    /// Definitions of special nets.
72    /// Special nets include nets like include power, clock, RF, and analog signals.
73    /// They should not be touched by the signal router.
74    pub special_nets: BTreeMap<String, ()>,
75    /// Definitions of normal signal nets.
76    pub nets: Vec<Net>,
77    /// Scan-chain definitions.
78    pub scan_chains: (),
79    /// Groups of components.
80    pub groups: BTreeMap<String, Vec<Group>>,
81    /// BEGINEXT blocks with non-standard extensions of the DEF format.
82    pub extensions: (),
83}
84
85impl Default for DEF {
86    fn default() -> Self {
87        DEF {
88            version: Some("5.8".into()),
89            busbitchars: ('[', ']'),
90            dividerchar: '/',
91            design_name: None,
92            technology: None,
93            units: 0,
94            history: Default::default(),
95            property_definitions: Default::default(),
96            die_area: Default::default(),
97            rows: Default::default(),
98            tracks: Default::default(),
99            gcell_grid: Default::default(),
100            vias: Default::default(),
101            styles: Default::default(),
102            nondefault_rules: Default::default(),
103            regions: Default::default(),
104            components: Default::default(),
105            pins: Default::default(),
106            pin_properties: Default::default(),
107            blockages: Default::default(),
108            slots: Default::default(),
109            fills: Default::default(),
110            special_nets: Default::default(),
111            nets: Default::default(),
112            scan_chains: Default::default(),
113            groups: Default::default(),
114            extensions: Default::default(),
115        }
116    }
117}
118
119/// Holds either the value of the SPACING argument or DESIGNRULEWIDTH argument of a geometrical
120/// layer as used in the LAYER definition in PIN or OBS.
121#[derive(Clone, Debug)]
122pub enum SpacingOrDesignRuleWidth {
123    /// Minimal allowed spacing between this shape and other shapes.
124    MinSpacing(Coord),
125    /// Effective design rule width.
126    DesignRuleWidth(Coord),
127}
128
129/// Either a metal/via blockage or a component placement blockage..
130#[derive(Clone, Debug)]
131pub enum Blockage {
132    /// Block component placement.
133    PlacementBlockage(PlacementBlockage),
134    /// Metal or via blockage.
135    LayerBlockage(LayerBlockage),
136}
137
138/// Either a rectangle or a polygon.
139#[derive(Clone, Debug)]
140pub enum RectOrPolygon {
141    /// Axis-aligned rectangle.
142    Rect(db::Rect<Coord>),
143    /// Polygon.
144    Polygon(db::SimplePolygon<Coord>),
145}
146
147/// Define a region on a layer that is blocked from being used.
148#[derive(Clone, Debug, Default)]
149pub struct LayerBlockage {
150    /// Layer of the blockage.
151    pub layer: String,
152    /// Block insertion of slots.
153    pub slots: bool,
154    /// Block insertion of metal fills.
155    pub fills: bool,
156    /// TBD
157    pub pushdown: bool,
158    /// Blockage does not concern power and ground nets, only signals.
159    pub except_pg_net: bool,
160    /// TBD
161    pub component: Option<String>,
162    /// TBD
163    pub spacing: Option<Coord>,
164    /// Either minimal allowed spacing or an effective width.
165    pub spacing_or_designrule_width: Option<SpacingOrDesignRuleWidth>,
166    /// Mask number.
167    pub mask_num: Option<MaskNum>,
168    /// Geometry of the blockage area.
169    pub blockage_shapes: Vec<RectOrPolygon>,
170}
171
172/// Specify the type of a soft blockage.
173#[derive(Clone, Debug)]
174pub enum PlacementBlockageType {
175    /// Initial placement shall not use the blocked area, but later stages can use it.
176    Soft,
177    /// Give a maximal usage density for the initial placement in this area.
178    /// The density is given in percent and must have a value in the range `[0.0, ..., 100.0]`.
179    Partial(f64),
180}
181
182/// Define a region where placement of components is not allowed.
183#[derive(Clone, Debug, Default)]
184pub struct PlacementBlockage {
185    /// Type of the blockage (placement blockage or routing/metal/via blockage).
186    pub blockage_type: Option<PlacementBlockageType>,
187    /// Blockage was pushed down through hierarchy from a component on a higher level.
188    pub pushdown: bool,
189    /// Name of the associated component.
190    pub component: Option<String>,
191    /// Rectangles that cover the blocked region.
192    pub rects: Vec<db::Rect<Coord>>,
193}
194
195/// Property definition used in DEF.
196#[derive(Clone, Debug)]
197pub struct DEFPropertyDefinition {
198    /// DEF object type associated with this property.
199    pub object_type: DEFPropertyObjectType,
200    /// Data type of the property value.
201    pub property_type: PropertyType,
202    /// Optional min and max values.
203    pub range: Option<(PropertyValue, PropertyValue)>,
204    /// Default value of such a property.
205    pub default_value: Option<PropertyValue>,
206}
207
208/// Type of parent object of the property.
209#[derive(Copy, Clone, Debug, PartialEq, Eq)]
210pub enum DEFPropertyObjectType {
211    /// Property belongs to a component.
212    Component,
213    /// Property belongs to a pin of a component.
214    ComponentPin,
215    /// Property belongs to the design.
216    Design,
217    /// Property belongs to a group.
218    Group,
219    /// Property belongs to a net.
220    Net,
221    /// Property belongs to a 'non-default-rule'.
222    NonDefaultRule,
223    /// Property belongs to a region.
224    Region,
225    /// Property belongs to a row.
226    Row,
227    /// Property belongs to a special net.
228    SpecialNet,
229}
230
231impl FromStr for DEFPropertyObjectType {
232    type Err = ();
233
234    fn from_str(input: &str) -> Result<Self, Self::Err> {
235        match input {
236            "COMPONENT" => Ok(Self::Component),
237            "COMPONENTPIN" => Ok(Self::ComponentPin),
238            "DESIGN" => Ok(Self::Design),
239            "GROUP" => Ok(Self::Group),
240            "NET" => Ok(Self::Net),
241            "NONDEFAULTRULE" => Ok(Self::NonDefaultRule),
242            "REGION" => Ok(Self::Region),
243            "ROW" => Ok(Self::Row),
244            "SPECIALNET" => Ok(Self::SpecialNet),
245            _ => Err(()),
246        }
247    }
248}
249
250impl fmt::Display for DEFPropertyObjectType {
251    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
252        match self {
253            Self::Component => f.write_str("COMPONENT"),
254            Self::ComponentPin => f.write_str("COMPONENTPIN"),
255            Self::Design => f.write_str("DESIGN"),
256            Self::Group => f.write_str("GROUP"),
257            Self::Net => f.write_str("NET"),
258            Self::NonDefaultRule => f.write_str("NONDEFAULTRULE"),
259            Self::Region => f.write_str("REGION"),
260            Self::Row => f.write_str("ROW"),
261            Self::SpecialNet => f.write_str("SPECIALNET"),
262        }
263    }
264}
265
266/// Instantiation of a component in DEF.
267#[derive(Clone, Debug, Default)]
268pub struct Component {
269    /// Name of the component instance.
270    pub name: String,
271    /// Name of the component template/model.
272    pub model_name: String,
273    /// Name of the electrically equivalent master.
274    pub eeq_master: Option<String>,
275    /// Tells where this component has been created.
276    pub source: ComponentSource,
277    /// Placement location of the component.
278    /// `(location, orientation, is fixed)`
279    pub position: Option<(db::Point<i32>, Orient, bool)>,
280    /// Placement halo. Defines a placement blockage around the component.
281    /// If `is_soft` is set, then the blockage does not need to be respected after the initial placement.
282    /// `(is_soft, left, bottom, right, top)`.
283    pub halo: Option<(bool, i32, i32, i32, i32)>,
284    /// Routing halo. TODO.
285    /// Structure is `(haloDist, minLayer, maxLayer)`.
286    pub route_halo: Option<(i32, String, String)>,
287    /// Weight of the component placement. Tells how costly a relocation of the component is.
288    pub weight: u32,
289    /// Name of the region where this component should be placed.
290    pub region: Option<String>,
291    /// Custom properties.
292    pub properties: BTreeMap<String, PropertyValue>,
293}
294
295/// Source of a component.
296#[derive(Copy, Clone, Debug, PartialEq, Eq)]
297pub enum ComponentSource {
298    /// Component comes from the original netlist. This is the default value.
299    Netlist,
300    /// Physical component that connects only to power and ground nets.
301    /// (Filler cells, well-taps, decoupling capacitors).
302    Dist,
303    /// Component generated by the user for some other reason.
304    User,
305    /// Component was inserted to meet timing constraints.
306    Timing,
307}
308
309impl Default for ComponentSource {
310    fn default() -> Self {
311        Self::Netlist
312    }
313}
314
315impl FromStr for ComponentSource {
316    type Err = ();
317
318    fn from_str(input: &str) -> Result<Self, Self::Err> {
319        match input {
320            "NETLIST" => Ok(Self::Netlist),
321            "DIST" => Ok(Self::Dist),
322            "USER" => Ok(Self::User),
323            "TIMING" => Ok(Self::Timing),
324            _ => Err(()),
325        }
326    }
327}
328
329impl fmt::Display for ComponentSource {
330    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
331        match self {
332            Self::Netlist => f.write_str("NETLIST"),
333            Self::Dist => f.write_str("DIST"),
334            Self::User => f.write_str("USER"),
335            Self::Timing => f.write_str("TIMING"),
336        }
337    }
338}
339
340/// Source of a net.
341#[derive(Copy, Clone, Debug, PartialEq, Eq)]
342pub enum NetSource {
343    /// Physical component that connects only to power and ground nets.
344    /// (Filler cells, well-taps, decoupling capacitors).
345    Dist,
346    /// Physical component that connects only to power and ground nets.
347    /// (Filler cells, well-taps, decoupling capacitors).
348    Netlist,
349    /// Net belongs to a scan-chain.
350    Test,
351    /// Component was inserted to meet timing constraints.
352    Timing,
353    /// Component generated by the user for some other reason.
354    User,
355}
356
357impl Default for NetSource {
358    fn default() -> Self {
359        Self::Netlist
360    }
361}
362
363impl FromStr for NetSource {
364    type Err = ();
365
366    fn from_str(input: &str) -> Result<Self, Self::Err> {
367        match input {
368            "DIST" => Ok(Self::Dist),
369            "NETLIST" => Ok(Self::Netlist),
370            "TEST" => Ok(Self::Test),
371            "TIMING" => Ok(Self::Timing),
372            "USER" => Ok(Self::User),
373            _ => Err(()),
374        }
375    }
376}
377
378impl fmt::Display for NetSource {
379    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
380        match self {
381            Self::Dist => f.write_str("DIST"),
382            Self::Netlist => f.write_str("NETLIST"),
383            Self::Test => f.write_str("TEST"),
384            Self::Timing => f.write_str("TIMING"),
385            Self::User => f.write_str("USER"),
386        }
387    }
388}
389
390/// Routing pattern of a net.
391/// Default: `Steiner`
392#[derive(Copy, Clone, Debug, PartialEq, Eq)]
393pub enum NetPattern {
394    /// Minimize skews in timing delays for clock nets.
395    Balanced,
396    /// Minimize net length.
397    Steiner,
398    /// Minimize delays for global nets.
399    Trunk,
400    /// For ECL designs.
401    WiredLogic,
402}
403
404impl Default for NetPattern {
405    fn default() -> Self {
406        Self::Steiner
407    }
408}
409
410impl FromStr for NetPattern {
411    type Err = ();
412
413    fn from_str(input: &str) -> Result<Self, Self::Err> {
414        match input {
415            "BALANCED" => Ok(Self::Balanced),
416            "STEINER" => Ok(Self::Steiner),
417            "TRUNK" => Ok(Self::Trunk),
418            "WIREDLOGIC" => Ok(Self::WiredLogic),
419            _ => Err(()),
420        }
421    }
422}
423
424impl fmt::Display for NetPattern {
425    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
426        match self {
427            Self::Balanced => f.write_str("BALANCED"),
428            Self::Steiner => f.write_str("STEINER"),
429            Self::Trunk => f.write_str("TRUNK"),
430            Self::WiredLogic => f.write_str("WIREDLOGIC"),
431        }
432    }
433}
434
435/// An internal pin or external pin of another component where a net can be attached.
436#[derive(Clone, Debug)]
437pub enum NetTerminal {
438    /// Pin of a component instance.
439    ComponentPin {
440        // TODO: Use string interning here.
441        /// Name of the component instance.
442        component_name: String,
443        /// Name of the pin.
444        pin_name: String,
445    },
446    /// Name of an IO pin of the design.
447    IoPin(String),
448}
449
450/// TBD
451#[derive(Clone, Debug)]
452pub struct Mustjoin {
453    /// Name of the component.
454    pub component_name: String,
455    /// Name of a pin that belongs to the MUSTJOIN net.
456    pub pin_name: String,
457}
458
459// /// A net either has a name or it is declared as MUSTJOIN.
460// #[derive(Clone, Debug)]
461// pub enum NameOrMustjoin {
462//     /// Name of the net.
463//     Name(String),
464//     Mustjoin {
465//         /// Name of the component.
466//         component_name: String,
467//         /// Name of a pin that belongs to the MUSTJOIN net.
468//         pin_name: String,
469//     }
470// }
471
472/// Wiring class. Tells whether a wiring can be changed by tools, manually or not at all.
473#[derive(Copy, Clone, Debug, PartialEq, Eq)]
474pub enum WiringClass {
475    /// Route cannot be changed at all.
476    COVER,
477    /// Route cannot be changed by automatic tools, only by interactive commands.
478    FIXED,
479    /// Route can be changed by automatic tool.
480    /// A net that is routed must also specify the layer name.
481    ROUTED,
482    /// Last wide segment is not shielded.
483    NOSHIELD,
484}
485
486impl FromStr for WiringClass {
487    type Err = ();
488
489    fn from_str(input: &str) -> Result<Self, Self::Err> {
490        match input {
491            "COVER" => Ok(Self::COVER),
492            "FIXED" => Ok(Self::FIXED),
493            "ROUTED" => Ok(Self::ROUTED),
494            "NOSHIELD" => Ok(Self::NOSHIELD),
495            _ => Err(()),
496        }
497    }
498}
499
500impl fmt::Display for WiringClass {
501    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
502        match self {
503            Self::COVER => f.write_str("COVER"),
504            Self::FIXED => f.write_str("FIXED"),
505            Self::ROUTED => f.write_str("ROUTED"),
506            Self::NOSHIELD => f.write_str("NOSHIELD"),
507        }
508    }
509}
510
511/// Represent an element of regular (non-special) wiring.
512#[derive(Clone, Debug)]
513pub enum RegularWiringElement {
514    /// A point in the euclidean plane.
515    Point {
516        /// x-coordinate
517        x: Coord,
518        /// y-coordinate
519        y: Coord,
520        /// Optional extension.
521        ext_value: Option<Coord>,
522    },
523    /// Via.
524    Via {
525        /// Name of the via.
526        via_name: String,
527    },
528    /// Mask number.
529    MaskNum(u32),
530    /// Via-mask number.
531    ViaMaskNum(ViaMaskNum),
532    /// Virtual wiring element. A point in the euclidean plane.
533    Virtual {
534        /// x-coordinate
535        x: Coord,
536        /// y-coordinate
537        y: Coord,
538    },
539    /// An axis aligned rectangle. TODO
540    Rect(),
541}
542
543/// 'Vertex' in the routing path.
544#[derive(Clone, Debug)]
545pub enum RoutingPoint {
546    /// A simple vertex of a path.
547    Point {
548        /// Location of the path vertex.
549        point: db::Point<Coord>,
550        /// Extension of the wire past the endpoint. Default is half the wire width.
551        ext_value: Option<Coord>,
552        /// Mask-number of the following path segment.
553        mask_num: Option<MaskNum>,
554    },
555    /// A via, placed at the location of the last path vertex.
556    Via {
557        /// Name of the via to be used.
558        via_name: String,
559        /// Rotation of the via.
560        orient: Option<Orient>,
561        /// Mask-number of the via geometries.
562        via_mask_num: Option<ViaMaskNum>,
563    },
564    /// A rectangular shape with absolute coordinates.
565    Rect {
566        /// Rectangle. Absolute coordinates.
567        /// DEF stores coordinates relative to the last path point, but here the coordinates are already resolved.
568        rect: db::Rect<Coord>,
569        /// Mask-number of the rectangle.
570        mask_num: Option<MaskNum>,
571    },
572    /// A 'virtual' path vertex. The path segment leading to the virtual vertex is not materialized.
573    /// This is equal to ending the path at the last point and starting a new path at the virtual vertex, hence
574    /// allows to create discontinuous paths.
575    Virtual(db::Point<Coord>),
576}
577
578/// Wiring statement which makes up the [`RegularWiring`].
579#[derive(Clone, Debug)]
580pub struct RegularWiringStatement {
581    /// Layer where the wire starts.
582    pub start_layer_name: String,
583    /// Name of the taper rule to be used.
584    pub taper_rule: Option<String>,
585    /// Routing style number.
586    pub style_num: u32,
587    // TODO: Check this.
588    /// Routing path.
589    pub routing_points: Vec<RoutingPoint>,
590}
591
592/// Representation of regular wiring.
593#[derive(Clone, Debug)]
594pub struct RegularWiring {
595    /// Wiring class.
596    pub class: WiringClass,
597    /// The wiring segments which make this wiring.
598    pub wiring: Vec<RegularWiringStatement>,
599}
600
601/// Definition of a net and possibly its routes.
602#[derive(Clone, Debug)]
603pub struct Net {
604    /// Name of the net.
605    /// Must be generated for MUSTJOIN nets.
606    /// 'MUSTJOIN' is an invalid net name.
607    pub name: Option<String>,
608    /// Net name is generated for MUSTJOIN nets.
609    pub mustjoin: Option<Mustjoin>,
610    /// Terminals connected to the net.
611    pub terminals: Vec<NetTerminal>,
612    /// Names of special nets that are used to shield this net.
613    /// The shield nets must be defined earlier in 'SPECIALNETS'.
614    pub shield_nets: Vec<String>,
615    vpin: BTreeMap<String, ()>,
616    subnets: BTreeMap<String, ()>,
617    /// Crosstalk class number.
618    /// Default is `0` which will not be written to DEF.
619    /// Should be a value from 0 to 200.
620    pub xtalk_class: u16,
621    /// Use another width rule than the default rule defined in the LEF WIDTH statement for the routing layer.
622    pub non_default_rule: Option<String>,
623    /// Specify the physical wiring.
624    pub regular_wiring: Vec<RegularWiring>,
625    /// Source from where the net was created.
626    pub source: NetSource,
627    /// Fixed bump: TBD
628    pub fixed_bump: bool,
629    /// Frequency of the net.
630    /// Used as a hint for the router.
631    pub frequency: Option<f64>,
632    /// If this net results from partitioning another net, then
633    /// this refers to the original net.
634    pub original: Option<String>,
635    /// Usage type of the net.
636    pub net_use: DEFSignalUse,
637    /// Desired routing pattern for the net.
638    pub pattern: NetPattern,
639    /// Estimated wire capacitance of this net.
640    pub est_cap: Option<f64>,
641    /// Weight of the net. Nets with high weight should be tried to keep short by routing tools.
642    /// Default = 1.
643    pub weight: u32,
644    /// Additional properties.
645    pub properties: BTreeMap<String, PropertyValue>,
646}
647
648/// Custom implementation of default because `weight` deviates from the default of `u32`.
649impl Default for Net {
650    fn default() -> Self {
651        Net {
652            name: Default::default(),
653            mustjoin: Default::default(),
654            terminals: Default::default(),
655            shield_nets: Default::default(),
656            vpin: Default::default(),
657            subnets: Default::default(),
658            xtalk_class: Default::default(),
659            non_default_rule: Default::default(),
660            regular_wiring: Default::default(),
661            source: Default::default(),
662            fixed_bump: Default::default(),
663            frequency: Default::default(),
664            original: Default::default(),
665            net_use: Default::default(),
666            pattern: Default::default(),
667            est_cap: Default::default(),
668            weight: 1,
669            properties: Default::default(),
670        }
671    }
672}
673
674/// Definiton of a special net and possibly its routes.
675#[derive(Clone, Debug, Default)]
676pub struct SpecialNet {}
677
678/// External pin definition in DEF.
679/// Associates an external pin name with the internal net name.
680#[derive(Clone, Debug, Default)]
681pub struct Pin {
682    /// Name of the external pin.
683    pub pin_name: String,
684    /// Name of the internal net.
685    pub net_name: String,
686    /// Mark the pin as 'special'. Special pins are to be routed with a special router with special wiring.
687    pub special: bool,
688    /// Signal direction of the pin. Typically this is specified in the timing library, not in DEF.
689    pub direction: Option<PinDirection>,
690    /// TBD
691    pub net_expr: Option<String>,
692    /// Net name where this pin should be connected if it is tied HIGH (constant logical 1).
693    pub supply_sensitivity: Option<String>,
694    /// Net name where this pin should be connected if it is tied LOW (constant logical 0).
695    pub ground_sensitivity: Option<String>,
696    /// Type of the signal for this pin. Default is 'SIGNAL'.
697    pub signal_use: DEFSignalUse,
698
699    /// Anntenna rules. TODO
700    pub antenna_rules: (),
701
702    /// Definitions of physical shapes of the pin.
703    pub ports: Vec<PinPort>,
704}
705
706/// Definition of the port of a pin.
707#[derive(Clone, Debug, Default)]
708pub struct PinPort {
709    /// Shapes of this port.
710    pub port_statements: Vec<PinPortStatement>,
711}
712
713/// Definition of the shapes of a pin port.
714#[derive(Clone, Debug)]
715pub enum PinPortStatement {
716    /// Rectangular shape of the pin port.
717    Layer {
718        /// Name of the layer.
719        layer_name: String,
720        /// Mask number.
721        mask_num: Option<MaskNum>,
722        /// SPACING: minimum spacing between other routing shapes an this pin.
723        /// DESIGNRULEWIDTH: effective width of this pin used for calculating spacing.
724        spacing_or_width: Option<SpacingOrDesignRuleWidth>,
725        /// Rectangular shape on this port.
726        rect: db::Rect<Coord>,
727    },
728    /// Polygon shape of the pin port.
729    Polygon {
730        /// Name of the layer.
731        layer_name: String,
732        /// Mask number.
733        mask_num: Option<MaskNum>,
734        /// SPACING: minimum spacing between other routing shapes an this pin.
735        /// DESIGNRULEWIDTH: effective width of this pin used for calculating spacing.
736        spacing_or_width: Option<SpacingOrDesignRuleWidth>,
737        /// Polygon shape on this port.
738        polygon: db::SimplePolygon<Coord>,
739    },
740    /// Via which is part of the pin port.
741    Via {
742        /// Name of the via.
743        via_name: String,
744        /// Mask number.
745        mask_num: Option<ViaMaskNum>,
746        /// Location of the via.
747        location: db::Point<Coord>,
748    },
749}
750
751/// Signal usage type of a pin in DEF.
752#[derive(Copy, Clone, Debug, PartialEq, Eq)]
753pub enum DEFSignalUse {
754    /// Digital data signal.
755    SIGNAL,
756    /// Supply net.
757    POWER,
758    /// Ground net.
759    GROUND,
760    /// Clock signal.
761    CLOCK,
762    /// Tie-signal.
763    TIEOFF,
764    /// Analog signal.
765    ANALOG,
766    /// Scan chain signal.
767    SCAN,
768    /// Reset signal.
769    RESET,
770}
771
772impl Default for DEFSignalUse {
773    fn default() -> Self {
774        Self::SIGNAL
775    }
776}
777
778impl FromStr for DEFSignalUse {
779    type Err = ();
780
781    fn from_str(input: &str) -> Result<Self, Self::Err> {
782        match input {
783            "SIGNAL" => Ok(Self::SIGNAL),
784            "POWER" => Ok(Self::POWER),
785            "GROUND" => Ok(Self::GROUND),
786            "CLOCK" => Ok(Self::CLOCK),
787            "TIEOFF" => Ok(Self::TIEOFF),
788            "ANALOG" => Ok(Self::ANALOG),
789            "SCAN" => Ok(Self::SCAN),
790            "RESET" => Ok(Self::RESET),
791            _ => Err(()),
792        }
793    }
794}
795
796impl fmt::Display for DEFSignalUse {
797    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
798        match self {
799            Self::SIGNAL => f.write_str("SIGNAL"),
800            Self::POWER => f.write_str("POWER"),
801            Self::GROUND => f.write_str("GROUND"),
802            Self::CLOCK => f.write_str("CLOCK"),
803            Self::TIEOFF => f.write_str("TIEOFF"),
804            Self::ANALOG => f.write_str("ANALOG"),
805            Self::SCAN => f.write_str("SCAN"),
806            Self::RESET => f.write_str("RESET"),
807        }
808    }
809}
810
811/// Mask number of a via for multi patterning.
812#[derive(Copy, Clone, Debug, PartialEq, Eq)]
813pub struct ViaMaskNum {
814    /// Mask number of top layer.
815    pub top_mask_num: MaskNum,
816    /// Mask number of cut layer.
817    pub cut_mask_num: MaskNum,
818    /// Mask number of bottom layer.
819    pub bottom_mask_num: MaskNum,
820}
821
822impl FromStr for ViaMaskNum {
823    type Err = LefDefParseError;
824
825    fn from_str(input: &str) -> Result<Self, Self::Err> {
826        if input.len() != 3 {
827            Err(LefDefParseError::InvalidLiteral(input.to_string()))
828        } else {
829            Ok(Self {
830                top_mask_num: MaskNum::from_str_radix(&input[0..1], 16)?,
831                cut_mask_num: MaskNum::from_str_radix(&input[1..2], 16)?,
832                bottom_mask_num: MaskNum::from_str_radix(&input[2..3], 16)?,
833            })
834        }
835    }
836}
837
838impl fmt::Display for ViaMaskNum {
839    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
840        write!(
841            f,
842            "{:#0x}{:#0x}{:#0x}",
843            self.top_mask_num, self.cut_mask_num, self.bottom_mask_num
844        )
845    }
846}
847
848/// Defines a physical area that can be used to place components or groups.
849#[derive(Clone, Debug, Default)]
850pub struct Region {
851    /// Physical region defined as a set of rectangles.
852    pub regions: Vec<db::Rect<Coord>>,
853    /// Type of the region constraint.
854    /// Default: Assigned cells are placed in the region. Other cells can be placed in the region as well.
855    pub region_type: Option<RegionType>,
856    /// Properties of the region.
857    pub properties: (),
858}
859
860/// Type of the region. A region defines a physical are where components should be placed.
861/// Fence regions force components to be placed inside, guides are not hard constraints.
862#[derive(Copy, Clone, Debug, PartialEq, Eq)]
863pub enum RegionType {
864    /// Hard constraint. Only components assigned to this region are allowed to be placed here.
865    Fence,
866    /// Soft constraint (can be violated if necessary).
867    Guide,
868}
869
870impl FromStr for RegionType {
871    type Err = ();
872
873    fn from_str(input: &str) -> Result<Self, Self::Err> {
874        match input {
875            "FENCE" => Ok(Self::Fence),
876            "GUIDE" => Ok(Self::Guide),
877            _ => Err(()),
878        }
879    }
880}
881
882impl fmt::Display for RegionType {
883    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
884        match self {
885            Self::Fence => f.write_str("FENCE"),
886            Self::Guide => f.write_str("GUIDE"),
887        }
888    }
889}
890
891/// Define a group of components.
892/// Optionally restrict the component locations to a region.
893#[derive(Clone, Debug, Default)]
894pub struct Group {
895    /// Names or name patterns of the components that belong to this group.
896    pub component_names: Vec<String>,
897    /// Name of the region in which the group must lie.
898    /// Region restrictions defined by the component overwrite the restrictions defined by its group.
899    pub region_name: Option<String>,
900    /// User defined properties.
901    pub properties: BTreeMap<String, PropertyValue>,
902}
903
904/// Definition of a standard-cell row.
905#[derive(Clone, Debug, Default)]
906pub struct Row {
907    /// Name of the site where this row is located.
908    pub site_name: String,
909    /// Origin of the row.
910    pub orig: (Coord, Coord),
911    /// Orientation of all sites in the row.
912    pub site_orient: Orient,
913    /// Specify the repetition pattern of the referenced site.
914    pub step_pattern: RowStepPattern,
915    /// Properties associated with the row.
916    pub properties: BTreeMap<String, PropertyValue>,
917}
918
919/// Repetition pattern for rows.
920#[derive(Clone, Debug)]
921pub struct RowStepPattern {
922    /// Number of repetitions in x-direction. At least one of `num_x` or `num_y` must be `1`.
923    pub num_x: u32,
924    /// Number of repetitions in y-direction. At least one of `num_x` or `num_y` must be `1`.
925    pub num_y: u32,
926    /// Step size for x and y direction. By default
927    /// the step size equals the size of the referenced site
928    /// such that sites are arranged without overlap nor gap between.
929    pub step: Option<(Coord, Coord)>,
930}
931
932impl Default for RowStepPattern {
933    fn default() -> Self {
934        Self {
935            num_x: 1,
936            num_y: 1,
937            step: None,
938        }
939    }
940}
941
942/// Definition routing tracks as a grid of equally spaced lines.
943#[derive(Clone, Debug, Default)]
944pub struct Tracks {
945    /// Direction of the track. Can be horizontal when 'Y' is defined in DEF (true) or vertical with 'X' in DEF (false).
946    pub is_horizontal: bool,
947    /// Distance of the track line to the origin.
948    /// For horizontal tracks this is the vertical offset (y coordinate),
949    /// for vertical tracks this is the horizontal offset (y coordinate).
950    pub start: Coord,
951    /// Number of tracks for the grid. Must be larger than 0.
952    pub num_tracks: u32,
953    /// Spacing between tracks.
954    pub step: Coord,
955    /// An optional tuple `( mask number, SAMEMASK )`.
956    /// mask number: Mask of the first track as used for double or triple patterning.
957    /// Usually the mask is cycled for all subsequent tracks.
958    /// SAMEMASK: Use the same mask number for all tracks.
959    pub mask: Option<(MaskNum, bool)>,
960    /// Routing layers to be used for this track. Possibly more than one.
961    pub layers: Vec<String>,
962}
963
964/// Definition of via geometries or rules to generate a via.
965#[derive(Clone, Debug)]
966pub enum ViaDefinition {
967    /// Explicit definition of the via by a set of geometrical shapes.
968    ViaGeometry(Vec<ViaGeometry>),
969    /// Implicit definition by design rules for the via.
970    ViaRule,
971}
972
973/// Geometrical shapes of a via.
974#[derive(Clone, Debug)]
975pub struct ViaGeometry {
976    /// Name of the
977    pub layer: String,
978    /// Mask number.
979    pub mask_num: Option<MaskNum>,
980    /// Rectangle or polygon shape.
981    pub shape: RectOrPolygon,
982}
983
984/// Rule for via creation.
985#[derive(Clone, Debug)]
986pub struct ViaRule {
987    /// Width and height of the via cut.
988    pub cut_size: (Coord, Coord),
989    /// Bottom metal layer of the via.
990    pub bot_metal_layer: String,
991    /// Layer of the via cut.
992    pub cut_layer: String,
993    /// Top metal layer of the via.
994    pub top_metal_layer: String,
995    /// Spacing in x and y directions.
996    pub cut_spacing: (Coord, Coord),
997    /// Via enclosure: bottom x, bottom y, top x, top y.
998    pub enclosure: (Coord, Coord, Coord, Coord),
999    num_cut_rows: u32,
1000    num_cut_cols: u32,
1001    origin: db::Point<Coord>,
1002    offset: (),
1003    cut_pattern: (),
1004}