libreda_lefdef/lef_ast.rs
1// Copyright (c) 2021-2021 Thomas Kramer.
2// SPDX-FileCopyrightText: 2022 Thomas Kramer <code@tkramer.ch>
3//
4// SPDX-License-Identifier: AGPL-3.0-or-later
5
6//! Data types that are used to populate the LEF data structure.
7
8use crate::common::*;
9use libreda_db::prelude::Point;
10use std::collections::BTreeMap;
11use std::fmt;
12use std::str::FromStr;
13
14/* Generate LEF enums:
15
16```python
17def gen_lef_enum(name, values):
18
19 #values = [v.capitalize() for v in values]
20
21 match_statements = [f'"{v.upper()}" => Ok(Self::{v})' for v in values]
22
23 format_statements = [f'Self::{v} => f.write_str("{v.upper()}")' for v in values]
24
25 return f"""
26///
27#[derive(Copy, Clone, Debug, PartialEq, Eq)]
28pub enum {name} {{
29 {", ".join(values)}
30}}
31
32impl FromStr for {name} {{
33 type Err = ();
34
35 fn from_str(input: &str) -> Result<Self, Self::Err> {{
36 match input {{
37 {", ".join(match_statements)},
38 _ => Err(()),
39 }}
40 }}
41}}
42
43impl fmt::Display for {name} {{
44 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {{
45 match self {{
46 {", ".join(format_statements)}
47 }}
48 }}
49}}
50
51"""
52
53print(gen_lef_enum("ClearanceMeasure", ["MAXXY", "EUCLIDEAN"]))
54print(gen_lef_enum("RoutingDirection", ["Vertical", "Horizontal"]))
55print(gen_lef_enum("SignalUse", ["SIGNAL", "ANALOG", "POWER", "GROUND", "CLOCK"]))
56print(gen_lef_enum("DEFSignalUse", ["SIGNAL", "POWER", "GROUND", "CLOCK", "TIEOFF", "ANALOG", "SCAN", "RESET"]))
57print(gen_lef_enum("PortClass", ["NONE", "CORE", "BUMP"]))
58print(gen_lef_enum("PinShape", ["ABUTMENT", "RING", "FEEDTHRU"]))
59print(gen_lef_enum("PinDirection", ["INPUT", "OUTPUT", "INOUT", "FEEDTHRU"]))
60print(gen_lef_enum("Orient", ["N", "S", "E", "W", "FN", "FS", "FE", "FW"]))
61print(gen_lef_enum("PropertyType", ["Integer", "Real", "String"]))
62print(gen_lef_enum("PropertyObjectType", ["Component", "ComponentPin", "Design", "Group", "Net", "NonDefaultRule", "Region", "Row", "SpecialNet"]))
63
64print(gen_lef_enum("MacroClass", ["COVER", "RING", "BLOCK", "PAD", "CORE", "ENDCAP"]))
65print(gen_lef_enum("MacroClassBlockType", ["BLACKBOX", "SOFT"]))
66print(gen_lef_enum("MacroClassPadType", ["INPUT", "OUTPUT", "INOUT", "POWER", "SPACER", "AREAIO"]))
67print(gen_lef_enum("MacroClassCoreType", ["FEEDTHRU", "TIEHIGH", "TIELOW", "SPACER", "ANTENNACELL", "WELLTAP"]))
68print(gen_lef_enum("MacroClassEndcapType", ["PRE", "POST", "TOPLEFT", "TOPRIGHT", "BOTTOMLEFT", "BOTTOMRIGHT"]))
69
70# Common
71print(gen_lef_enum("Symmetry", ["X", "Y", "R90"]))
72
73# DEF
74print(gen_lef_enum("ComponentSource", ["Netlist", "Dist", "User", "Timing"]))
75print(gen_lef_enum("RegionType", ["Fence", "Guide"]))
76
77
78```
79*/
80
81/// Top-level structure of a LEF library.
82#[derive(Clone, Debug)]
83pub struct LEF {
84 /// LEF version.
85 pub version: Option<String>,
86 /// Characters used to indicate bus bits. Default is `[` and `]`.
87 pub busbitchars: (char, char),
88 /// Character used as path separator. Default is `/`.
89 pub dividerchar: char,
90
91 /// Definitions of fixed VIAs by name.
92 pub vias: BTreeMap<String, ViaDefinition>,
93 /// All SITE definitions by name.
94 pub sites: BTreeMap<String, SiteDefinition>,
95
96 /// Technology information of the design.
97 pub technology: TechnologyLef,
98 /// Cell and macro information.
99 pub library: LibraryLef,
100
101 /// Extensions as defined by BEGINEXT blocks.
102 pub extensions: BTreeMap<String, ()>,
103}
104
105impl Default for LEF {
106 fn default() -> Self {
107 LEF {
108 version: None,
109 busbitchars: ('[', ']'),
110 dividerchar: '/',
111 vias: Default::default(),
112 sites: Default::default(),
113 technology: Default::default(),
114 library: Default::default(),
115 extensions: Default::default(),
116 }
117 }
118}
119
120/// Library LEF containing macro and standard cell information.
121#[derive(Clone, Debug, Default)]
122pub struct LibraryLef {
123 /// All MACRO definitions of the library.
124 pub macros: BTreeMap<String, Macro>,
125}
126
127/// Technology LEF containing technology information.
128#[derive(Clone, Debug, Default)]
129pub struct TechnologyLef {
130 /// Units used in this library.
131 pub units: Units,
132 /// Grid for geometrical alignment. Cells and shapes snap to locations on this grid.
133 pub manufacturing_grid: Option<f64>,
134 ///
135 pub use_min_spacing: Option<()>,
136 /// Type of distance measure (Euclidean: `dx^2 + dy^2`, MaxXY: `max(dx, dy)`)
137 pub clearance_measure: ClearanceMeasure,
138 /// Definitions of custom properties.
139 pub property_definitions: BTreeMap<String, ()>,
140 /// Disable shifting of masks.
141 /// When set, shifting of macro pin mask assignments to other masks is not allowed.
142 /// Used for technologies that use multi-mask patterning.
143 pub fixed_mask: bool,
144 /// Layer definitions (masterslice, cut, routing, ...).
145 /// Layers are defined in their process order from bottom to top.
146 pub layers: Vec<Layer>,
147 /// Maximum number of single-cut vias stacked on top of each other.
148 /// Optionally defines a range of (bottom layer, top layer) where the rule applies. Otherwise
149 /// the rule applies to all layers.
150 pub max_via_stack: Option<(u64, Option<(String, String)>)>,
151 // /// Fixed vias by name.
152 // pub vias: BTreeMap<String, ()>,
153 /// VIA GENERATE rules by name.
154 pub via_rules_generate: BTreeMap<String, ()>,
155 /// NONDEFAULTRULEs by name.
156 pub non_default_rule: (),
157 // /// All SITE definitions by name.
158 // pub sites: BTreeMap<String, ()>,
159}
160
161/// Units used in the library.
162#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
163pub struct Units {
164 /// Time in nano seconds.
165 pub time_ns: u64,
166 /// Capacitance in pico farads.
167 pub capacitance_pf: u64,
168 /// Resistance in ohms.
169 pub resistance_ohms: u64,
170 /// Power in milli watts.
171 pub power_mw: u64,
172 /// Current in milli amperes.
173 pub current_ma: u64,
174 /// Voltage in volts.
175 pub voltage_v: u64,
176 /// Length in micro meters.
177 pub database_microns: u64,
178 /// Frequency in mega hertz.
179 pub frequency_mega_hz: u64,
180}
181
182/// Macro SITE declaration.
183#[derive(Clone, Debug, Default, PartialEq)]
184pub struct Site {
185 /// Name of the site.
186 pub name: String,
187 /// Origin of the site within the macro. Unit is microns.
188 pub origin: (f64, f64),
189 /// Orientation of the site.
190 pub site_orient: Orient,
191 /// Optional repetition pattern.
192 pub step_pattern: Option<StepPattern>,
193}
194
195/// SITE definition.
196#[derive(Clone, Debug, PartialEq)]
197pub struct SiteDefinition {
198 /// Name of the site.
199 pub name: String,
200 /// Dimensions of the site.
201 pub size: (f64, f64),
202 /// Define orientations of the site that are considered equivalent.
203 /// This is used for example to specify whether cell flipping inside
204 /// a row is allowed.
205 pub symmetry: Symmetry,
206 /// Specify site type (IO or CORE).
207 pub class: SiteClass,
208 /// Construct this site as a composition of previously defined sites.
209 /// List of tuples: (previous site, orientation)
210 pub row_pattern: Vec<(String, Orient)>,
211}
212
213/// Array-like repetition of an element.
214///
215/// Use `each_offset()` to iterate through all offsets described by this pattern.
216#[derive(Copy, Clone, Debug, PartialEq)]
217pub struct StepPattern {
218 /// Number of repetitions in x-direction.
219 pub num_x: u64,
220 /// Number of repetitions in y-direction.
221 pub num_y: u64,
222 /// Spacing in x-direction.
223 pub space_x: f64,
224 /// Spacing in y-direction.
225 pub space_y: f64,
226}
227
228impl StepPattern {
229 /// Return an iterator over each offset of the step pattern.
230 /// The origin is at (0.0, 0.0).
231 pub fn each_offset(&self) -> impl Iterator<Item = (f64, f64)> + '_ {
232 (0..self.num_x)
233 .flat_map(move |x| (0..self.num_y).map(move |y| (x, y)))
234 .map(move |(x, y)| (x as f64 * self.space_x, y as f64 * self.space_y))
235 }
236}
237
238impl Default for StepPattern {
239 fn default() -> Self {
240 StepPattern {
241 num_x: 1,
242 num_y: 1,
243 space_x: 0.0,
244 space_y: 0.0,
245 }
246 }
247}
248
249/// Holds either the value of the SPACING argument or DESIGNRULEWIDTH argument of a geometrical
250/// layer as used in the LAYER definition in PIN or OBS.
251#[derive(Clone, Debug)]
252pub enum SpacingOrDesignRuleWidth {
253 /// Minimal allowed spacing between this shape and other shapes.
254 MinSpacing(f64),
255 /// Effective design rule width.
256 DesignRuleWidth(f64),
257}
258
259/// Either a path, rectangle or polygon.
260#[derive(Clone, Debug)]
261pub enum Shape {
262 /// Width and path.
263 Path(f64, Vec<Point<f64>>),
264 /// Corner points of a rectangle.
265 Rect(Point<f64>, Point<f64>),
266 /// Vertices of a polygon.
267 Polygon(Vec<Point<f64>>),
268}
269
270/// Shape with an optional array step pattern.
271#[derive(Clone, Debug)]
272pub struct Geometry {
273 /// Array-like repetition of the shape.
274 pub step_pattern: Option<StepPattern>,
275 /// Geometric primitive.
276 pub shape: Shape,
277}
278
279/// A LEF via definition.
280#[derive(Clone, Debug)]
281pub enum ViaDefinition {
282 /// Via has been generated with according to a via rule.
283 GeneratedVia(GeneratedVia),
284 /// Via is defined explicitly with shapes on layers.
285 FixedVia(FixedVia),
286}
287
288/// A generated via.
289#[derive(Clone, Debug, Default)]
290pub struct GeneratedVia {
291 /// Default via to be used for routing between the adjacent layers.
292 pub is_default: bool,
293 /// Via generate rule which was used to generate this via.
294 pub rule_name: String,
295 /// Width and height of the via cut.
296 pub cut_size: (f64, f64),
297 /// Bottom, cut and top layer.
298 pub layers: (String, String, String),
299 /// Spacing in x and y directions.
300 pub cut_spacing: (f64, f64),
301 /// bottom-x, bottom-y, top-x, top-y enclosure
302 pub enclosure: (f64, f64, f64, f64),
303 /// Number of rows and columns.
304 pub num_rows_cols: Option<(u32, u32)>,
305 /// Coordinate of the origin.
306 pub origin: Option<(f64, f64)>,
307 /// Offsets of bottom-x, bottom-y, top-x, top-y
308 pub offset: Option<(f64, f64, f64, f64)>,
309 /// ASCII string which encodes the pattern of repeated vias.
310 pub cut_pattern: Option<String>,
311}
312
313/// Either a rectangle or a polygon.
314#[derive(Clone, Debug)]
315pub enum RectOrPolygon {
316 /// Axis-aligned rectangle.
317 Rect((Point<f64>, Point<f64>)),
318 /// Polygon.
319 Polygon(Vec<Point<f64>>),
320}
321
322/// Single shape used in the definition of a fixed via.
323#[derive(Clone, Debug)]
324pub struct ViaShape {
325 /// Optional mask number for multi-patterning.
326 pub mask_num: Option<u8>,
327 /// A rectangle or a polygon shape.
328 pub shape: RectOrPolygon,
329}
330
331/// An explicitly defined via.
332#[derive(Clone, Debug, Default)]
333pub struct FixedVia {
334 /// Default via to be used for routing between the adjacent layers.
335 pub is_default: bool,
336 /// Electrical resistance of the via.
337 pub resistance: Option<f64>,
338 /// Layers and shapes of the via geometry.
339 pub geometry: BTreeMap<String, Vec<ViaShape>>,
340}
341
342/// MACRO definition.
343#[derive(Clone, Debug, Default)]
344pub struct Macro {
345 /// Name of the macro.
346 pub name: String,
347 /// Class of the macro.
348 pub class: Option<MacroClass>,
349 /// Disable shifting of masks.
350 /// When set, shifting of macro pin mask assignments to other masks is not allowed.
351 /// Used for technologies that use multi-mask patterning.
352 pub fixed_mask: bool,
353 /// Name of the corresponding cell layout in the GDS/OASIS file.
354 /// Associated with an offset and orientation.
355 pub foreign: Vec<(String, Point<f64>, Orient)>,
356 /// Coordinate of the origin of the macro. Default is (0, 0).
357 /// A placement of a cell in DEF is given by the location of the origin.
358 pub origin: Point<f64>,
359 /// Name of electrically equivalent macro.
360 pub eeq: Option<String>,
361 /// Width and height of the macro.
362 pub size: Option<(f64, f64)>,
363 /// Symmetry of the macro. Tells how the macro can be mirrored and rotated.
364 pub symmetry: Symmetry,
365
366 /// SITES associated with the macro. Normal macros have only one associated site.
367 pub sites: Vec<Site>,
368
369 /// Definitions of the electrical pins of the macro.
370 pub pins: Vec<MacroPin>,
371 /// Obstructions (blockages).
372 pub obs: Vec<LayerGeometries>,
373 /// Density specifications.
374 pub density: Vec<()>,
375
376 /// Additional properties of the macro.
377 pub properties: BTreeMap<String, ()>,
378}
379
380/// PIN definition of a MACRO.
381#[derive(Clone, Debug, Default)]
382pub struct MacroPin {
383 /// Name of the pin.
384 pub name: String,
385 /// Name of the NONDEFAULTRULE to be used when tapering wires to this pin.
386 pub taper_rule: Option<String>,
387 /// Signal direction.
388 pub direction: Option<PinDirection>,
389 /// Type of the signal for this pin.
390 pub signal_use: Option<SignalUse>,
391
392 /// Net name where this pin should be connected if it is tied HIGH (constant logical 1).
393 pub supply_sensitivity: Option<String>,
394 /// Net name where this pin should be connected if it is tied LOW (constant logical 0).
395 pub ground_sensitivity: Option<String>,
396
397 /// Specify special connection requirements of the pin.
398 pub shape_type: Option<PinShape>,
399
400 /// Name of another pin that must be connected to this pin.
401 pub must_join: Option<String>,
402 ///
403 pub ports: Vec<MacroPinPort>,
404}
405
406/// PORT definition of a MACRO PIN.
407/// A port describes where a pin is geometrically located.
408/// A pin can have multiple ports. They are electrically equivalent.
409#[derive(Clone, Debug, Default)]
410pub struct MacroPinPort {
411 /// Type of the port.
412 pub class: Option<PortClass>,
413 /// Geometrical shapes and vias that make this port.
414 pub geometries: Vec<LayerGeometries>,
415}
416
417/// Geometrical shapes on a named layer as used in MACRO PIN and OBS definitions.
418#[derive(Clone, Debug, Default)]
419pub struct LayerGeometries {
420 /// Name of the layer.
421 pub layer_name: String,
422 /// Obstruction blocks signal routing but not power or ground routing.
423 pub except_pg_net: bool,
424 /// Either minimal allowed spacing or an effective width.
425 pub spacing_or_designrule_width: Option<SpacingOrDesignRuleWidth>,
426 /// Specify the width to be used for PATH. If not specified the default with for this layer is used.
427 pub width: Option<f64>,
428 /// Geometrical shapes (PATH, RECT, POLYGON). Together with a repetition pattern.
429 pub geometries: Vec<Geometry>,
430 /// Specify vias to be placed with their locations.
431 pub vias: Vec<()>,
432}
433
434/// Type of distance measurement
435#[derive(Clone, Debug, PartialEq, Eq)]
436pub enum ClearanceMeasure {
437 /// Take maximum of x or y distance.
438 Maxxy,
439 /// `sqrt(x^2 + y^2)`
440 Euclidean,
441}
442
443impl Default for ClearanceMeasure {
444 fn default() -> Self {
445 Self::Euclidean
446 }
447}
448
449impl FromStr for ClearanceMeasure {
450 type Err = ();
451
452 fn from_str(input: &str) -> Result<Self, Self::Err> {
453 match input {
454 "MAXXY" => Ok(Self::Maxxy),
455 "EUCLIDEAN" => Ok(Self::Euclidean),
456 _ => Err(()),
457 }
458 }
459}
460
461impl fmt::Display for ClearanceMeasure {
462 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
463 match self {
464 Self::Maxxy => f.write_str("MAXXY"),
465 Self::Euclidean => f.write_str("EUCLIDEAN"),
466 }
467 }
468}
469
470/// Preferred routing direction on a routing layer.
471#[derive(Clone, Debug, PartialEq, Eq)]
472pub enum RoutingDirection {
473 /// Vertical routing direction.
474 Vertical,
475 /// Horizontal routing direction.
476 Horizontal,
477 /// 45 degree routing direction.
478 Diag45,
479 /// 135 degree routing direction.
480 Diag135,
481}
482
483impl FromStr for RoutingDirection {
484 type Err = ();
485
486 fn from_str(input: &str) -> Result<Self, Self::Err> {
487 match input {
488 "VERTICAL" => Ok(Self::Vertical),
489 "HORIZONTAL" => Ok(Self::Horizontal),
490 "DIAG45" => Ok(Self::Diag45),
491 "DIAG135" => Ok(Self::Diag135),
492 _ => Err(()),
493 }
494 }
495}
496
497impl fmt::Display for RoutingDirection {
498 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
499 match self {
500 Self::Vertical => f.write_str("VERTICAL"),
501 Self::Horizontal => f.write_str("HORIZONTAL"),
502 Self::Diag45 => f.write_str("DIAG45"),
503 Self::Diag135 => f.write_str("DIAG135"),
504 }
505 }
506}
507
508/// Type of the signal.
509#[derive(Copy, Clone, Debug, PartialEq, Eq)]
510pub enum SignalUse {
511 /// Data signal.
512 Signal,
513 /// Analog signal.
514 Analog,
515 /// Power supply.
516 Power,
517 /// Ground.
518 Ground,
519 /// Clock signal.
520 Clock,
521}
522
523impl FromStr for SignalUse {
524 type Err = ();
525
526 fn from_str(input: &str) -> Result<Self, Self::Err> {
527 match input {
528 "SIGNAL" => Ok(Self::Signal),
529 "ANALOG" => Ok(Self::Analog),
530 "POWER" => Ok(Self::Power),
531 "GROUND" => Ok(Self::Ground),
532 "CLOCK" => Ok(Self::Clock),
533 _ => Err(()),
534 }
535 }
536}
537
538impl fmt::Display for SignalUse {
539 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
540 match self {
541 Self::Signal => f.write_str("SIGNAL"),
542 Self::Analog => f.write_str("ANALOG"),
543 Self::Power => f.write_str("POWER"),
544 Self::Ground => f.write_str("GROUND"),
545 Self::Clock => f.write_str("CLOCK"),
546 }
547 }
548}
549
550/// TODO: Document.
551#[derive(Clone, Debug, PartialEq, Eq)]
552pub enum PortClass {
553 ///
554 None,
555 ///
556 Core,
557 ///
558 Bump,
559}
560
561impl FromStr for PortClass {
562 type Err = ();
563
564 fn from_str(input: &str) -> Result<Self, Self::Err> {
565 match input {
566 "NONE" => Ok(Self::None),
567 "CORE" => Ok(Self::Core),
568 "BUMP" => Ok(Self::Bump),
569 _ => Err(()),
570 }
571 }
572}
573
574impl fmt::Display for PortClass {
575 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
576 match self {
577 Self::None => f.write_str("NONE"),
578 Self::Core => f.write_str("CORE"),
579 Self::Bump => f.write_str("BUMP"),
580 }
581 }
582}
583
584/// Type of the pin shape.
585#[derive(Clone, Debug, PartialEq, Eq)]
586pub enum PinShape {
587 ///
588 Abutment,
589 ///
590 Ring,
591 ///
592 Feedthru,
593}
594
595impl FromStr for PinShape {
596 type Err = ();
597
598 fn from_str(input: &str) -> Result<Self, Self::Err> {
599 match input {
600 "ABUTMENT" => Ok(Self::Abutment),
601 "RING" => Ok(Self::Ring),
602 "FEEDTHRU" => Ok(Self::Feedthru),
603 _ => Err(()),
604 }
605 }
606}
607
608impl fmt::Display for PinShape {
609 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
610 match self {
611 Self::Abutment => f.write_str("ABUTMENT"),
612 Self::Ring => f.write_str("RING"),
613 Self::Feedthru => f.write_str("FEEDTHRU"),
614 }
615 }
616}
617
618/// Spacing rules for a routing layer.
619#[allow(missing_docs)]
620#[derive(Clone, Debug, Default)]
621pub struct SpacingRules {
622 pub min_spacing: f64,
623 pub spacing_type: Option<SpacingType>,
624}
625
626#[allow(missing_docs)]
627#[derive(Clone, Debug)]
628pub enum SpacingType {
629 Range {
630 min_width: f64,
631 max_width: f64,
632 spacing_range_type: Option<SpacingRangeType>,
633 },
634 EndOfLine {
635 eol_width: f64,
636 eol_widthing: f64,
637 },
638 /// Rule applies only for two shapes of the same net.
639 SameNet {
640 /// PGONLY, same-net rule applies for power and ground nets only.
641 power_ground_only: bool,
642 },
643 NotchLength {
644 min_notch_length: bool,
645 },
646 EndOfNotchWidth {
647 end_of_notch_width: f64,
648 min_notch_spacing: f64,
649 min_notch_length: f64,
650 },
651}
652
653#[allow(missing_docs)]
654#[derive(Clone, Debug)]
655pub enum SpacingRangeType {
656 UseLengthThreshold,
657 Influence { influence_length: f64 },
658}
659
660/// SPACINGTABLE, spacing rules for a routing layer.
661#[derive(Clone, Debug, Default)]
662pub struct SpacingTable {
663 /// Indices of the table columns.
664 pub parallel_run_lengths: Vec<f64>,
665 /// Indices of the table rows.
666 pub widths: Vec<f64>,
667 /// Table values
668 pub spacings: Vec<Vec<f64>>,
669}
670
671/// Layer definition.
672/// A layer can have different types:
673///
674/// * MasterSlice: This is usually the first layer in the stack.
675/// * Cut: Via layer that connects the previous and next layer.
676/// * Routing: Metal wires.
677#[derive(Clone, Debug)]
678pub enum Layer {
679 /// MASTERSLICE (poly) layer.
680 MasterSlice(MasterSliceLayer),
681 // /// Implant layer.
682 // Implant(()),
683 /// CUT layer.
684 Cut(CutLayer),
685 /// ROUTING layer.
686 Routing(RoutingLayer),
687}
688
689impl Layer {
690 /// Get the name of the layer.
691 pub fn name(&self) -> &String {
692 match self {
693 Layer::MasterSlice(l) => &l.name,
694 Layer::Cut(l) => &l.name,
695 Layer::Routing(l) => &l.name,
696 }
697 }
698}
699
700/// Design rules for a MASTERSLICE or OVERLAP layer.
701/// Master slice layers are usually polysilicon layers and are typically used when a MACRO has
702/// pins on the poly layer.
703#[derive(Clone, Debug, Default)]
704pub struct MasterSliceLayer {
705 /// Name of the masterslice layer.
706 pub name: String,
707 /// Number of masks used for double- or triple-patterning.
708 pub mask_num: Option<u32>,
709
710 /// Custom properties.
711 pub properties: BTreeMap<String, PropertyValue>,
712 // TODO: PROPERTY_LEF58_TYPE, PROPERTY_LEF58_TRIMMEDMETAL
713}
714
715/// Design rules for a CUT (via) layer.
716#[derive(Clone, Debug, Default)]
717pub struct CutLayer {
718 /// Name of the cut layer.
719 pub name: String,
720 /// Number of masks used for double- or triple-patterning.
721 pub mask_num: Option<u32>,
722 /// Minimum spacing rules between cuts of same or different nets.
723 pub spacing: Vec<CutSpacingRule>,
724 /// Spacing table to be used on this cut layer.
725 pub spacing_table: Option<()>,
726 /// TODO
727 pub array_spacing: Option<()>,
728 /// Minimum width of a cut in microns.
729 /// Usually this is the only allowed size of a cut.
730 pub width: Option<f64>,
731 /// Enclosure rules that must be met.
732 pub enclosure: Vec<EnclosureRule>,
733 /// Preferred enclosure rules that can be used to improve yield but must not necessarily
734 /// be met.
735 pub prefer_enclosure: Vec<EnclosureRule>,
736 /// Resistance per cut.
737 pub resistance: Option<f64>,
738 /// Custom properties.
739 pub properties: BTreeMap<String, PropertyValue>,
740 // TODO: Antenna rule definitions.
741}
742
743/// ENCLOSURE rules for a CUT (via) layer.
744#[derive(Clone, Debug)]
745pub struct EnclosureRule {
746 /// Rule applies for the routing layer above.
747 pub above: bool,
748 /// Rule applies for the routing layer below.
749 pub below: bool,
750 /// Adjacent routing layers must overhang on the two opposing sides (in x-direction (?)).
751 pub overhang1: f64,
752 /// Adjacent routing layers must overhang on the two opposing sides (in y-direction (?)).
753 pub overhang2: f64,
754 /// Rule only applies if the width of the adjacent shape of the routing layer is greater or equal
755 /// than `min_width`.
756 /// Default is 0.
757 pub min_width: f64,
758 /// TODO
759 /// Don't use the WIDTH rule when another via is present to the current via within this distance.
760 pub except_extracut_within: f64,
761 /// Rule only applies if the total length of the longest overhangs is greater or equal
762 /// to `min_length`.
763 /// The overhang length is measured from the via cut center.
764 /// Default is 0.
765 pub min_length: f64,
766}
767
768impl Default for EnclosureRule {
769 fn default() -> Self {
770 Self {
771 above: true,
772 below: true,
773 overhang1: 0.0,
774 overhang2: 0.0,
775 min_width: 0.0,
776 except_extracut_within: 0.0,
777 min_length: 0.0,
778 }
779 }
780}
781
782/// SPACING rules for a CUT (via) layer.
783#[derive(Clone, Debug)]
784pub struct CutSpacingRule {
785 /// Spacing between cuts.
786 pub spacing: f64,
787 /// Measure the spacing from center of the cut to the center of another cut
788 /// instead of from edge to edge.
789 /// This is enabled by default.
790 pub center_to_center: bool,
791 /// Tell if this spacing rule applies for same-net cuts.
792 pub same_net: bool,
793}
794
795impl Default for CutSpacingRule {
796 fn default() -> Self {
797 Self {
798 spacing: 0.0,
799 center_to_center: true,
800 same_net: false,
801 }
802 }
803}
804
805/// Design rules for a routing layer.
806#[derive(Clone, Debug)]
807pub struct RoutingLayer {
808 /// Name of the routing layer.
809 pub name: String,
810 /// Number of masks used for double- or triple-patterning.
811 pub mask_num: Option<u32>,
812 /// Preferred routing direction.
813 pub direction: RoutingDirection,
814 /// Routing pitch in x and y direction in microns.
815 pub pitch: (f64, f64),
816 /// Routing pitch for diagonal directions in microns.
817 pub diag_pitch: Option<(f64, f64)>,
818 /// Default wire width in microns.
819 pub width: f64,
820 ///
821 pub offset: Option<(f64, f64)>,
822 /// Default width for diagonal wires in microns.
823 pub diag_width: Option<f64>,
824 /// Default spacing for diagonal wires in microns.
825 pub diag_spacing: Option<f64>,
826 /// Minimum edge length for diagonal wires in microns.
827 pub diag_min_edge_length: Option<f64>,
828 /// Minimum area for shapes on this layer.
829 pub min_area: Option<f64>,
830 /// Minimal rectangles that must fit in each shape on this layer.
831 /// At least one needs to fit for each shape.
832 /// Tuples of `(minimal width, minimal length)`.
833 pub min_size: Vec<(f64, f64)>,
834 /// Minimal edge length for shapes.
835 pub min_step: (),
836 /// Spacing rules.
837 pub spacing: Vec<SpacingRules>,
838 /// Spacing tables for spacing between wires.
839 pub spacing_table: Option<SpacingTable>,
840 /// Length of extension of a wire over a via. The extension must be at least half of the
841 /// wire width.
842 pub wire_extension: Option<f64>,
843 /// Minimal number of cuts of a via depending on the width of the wire.
844 pub minimum_cut: (),
845 /// Maximum wire width in microns.
846 pub max_width: Option<f64>,
847 /// Minimum wire width in microns.
848 pub min_width: Option<f64>,
849 /// Minimum area of holes in metal shapes.
850 /// `(min area [um^2], width [um])` tuples.
851 /// If a width is specified the rule only applies if at least one of the wires around the hole
852 /// has a larger width.
853 pub min_enclosed_area: Vec<(f64, Option<f64>)>,
854 /// Width of a protrusion.
855 pub protrusion_width: (),
856 /// Sheet resistance `[Ohm/square]`.
857 pub resistance: Option<f64>,
858 /// Specify wire-to-ground capacitance per square unit in `[pF/um^2]`.
859 pub capacitance: Option<f64>,
860 /// Distance from top of ground plane to bottom of this interconnect layer.
861 pub height: Option<f64>,
862 /// Thickness of the layer in microns.
863 pub thickness: Option<f64>,
864 /// Amount of loss in width of wires caused by the etching process.
865 pub shrinkage: Option<f64>,
866 /// Account for increase in capacitance caused by close wires.
867 /// Default is 1.
868 pub cap_multiplier: u32,
869 /// `[pF/um]`.
870 pub edge_capacitance: Option<f64>,
871 /// Maximum allowed metal density in percent.
872 pub minimum_density: Option<f64>,
873 /// Minimum allowed metal density in percent.
874 pub maximum_density: Option<f64>,
875 /// Length and width of the density check window.
876 pub density_check_window: Option<(f64, f64)>,
877 /// Stepping distance for metal density checks.
878 pub density_check_step: Option<f64>,
879 /// Spacing between metal fills and active geometries.
880 pub fill_active_spacing: Option<f64>,
881
882 /// Antenna rule definitions.
883 pub antenna_rules: AntennaRules,
884
885 /// AC current density information.
886 pub ac_current_density: Option<()>,
887 /// Average DC current density information.
888 /// Stored as a `(wire width, current density)` table.
889 /// If only a default value is specified for all widths
890 /// it is stored as a single entry for wire width `0`: `(0, default_current_density)`.
891 /// Unit: `[mA/um]`
892 pub dc_current_density: Vec<(f64, f64)>,
893
894 /// Custom properties.
895 pub properties: BTreeMap<String, PropertyValue>,
896}
897
898impl Default for RoutingLayer {
899 /// Custom implementation of the `Default` trait for `RoutingLayer.
900 fn default() -> Self {
901 Self {
902 name: Default::default(),
903 mask_num: Default::default(),
904 direction: RoutingDirection::Vertical,
905 pitch: (0.0, 0.0),
906 diag_pitch: Default::default(),
907 width: 0.0,
908 offset: Default::default(),
909 diag_width: Default::default(),
910 diag_spacing: Default::default(),
911 diag_min_edge_length: Default::default(),
912 min_area: Default::default(),
913 min_size: Default::default(),
914 min_step: Default::default(),
915 spacing: Default::default(),
916 spacing_table: Default::default(),
917 wire_extension: Default::default(),
918 minimum_cut: Default::default(),
919 max_width: Default::default(),
920 min_width: Default::default(),
921 min_enclosed_area: Default::default(),
922 protrusion_width: Default::default(),
923 resistance: Default::default(),
924 capacitance: Default::default(),
925 height: Default::default(),
926 thickness: Default::default(),
927 shrinkage: Default::default(),
928 // Take multiplicative identity as default for the capacitance multiplier.
929 cap_multiplier: 1,
930 edge_capacitance: Default::default(),
931 minimum_density: Default::default(),
932 maximum_density: Default::default(),
933 density_check_window: Default::default(),
934 density_check_step: Default::default(),
935 fill_active_spacing: Default::default(),
936 antenna_rules: AntennaRules::default(),
937 ac_current_density: Default::default(),
938 dc_current_density: Default::default(),
939 properties: Default::default(),
940 }
941 }
942}
943
944///
945#[derive(Copy, Clone, Debug, PartialEq, Eq)]
946pub enum MacroClass {
947 /// Macro with fixed position.
948 /// Commonly used for power routing. COVER does not contain active devices.
949 /// A COVER class can have the sub-class BUMP. Typically BUMP cells have
950 /// geometries only on the topmost 'bump' layer.
951 COVER(bool),
952 /// Big macro with internal power mesh.
953 RING,
954 /// Predefined macro.
955 BLOCK(Option<MacroClassBlockType>),
956 /// I/O pad.
957 PAD(Option<MacroClassPadType>),
958 /// Standard-cell macro used inside the core area.
959 CORE(Option<MacroClassCoreType>),
960 /// Start or end of core rows. Typically used to connect to the power grid.
961 ENDCAP(Option<MacroClassEndcapType>),
962}
963
964impl FromStr for MacroClass {
965 type Err = ();
966
967 fn from_str(input: &str) -> Result<Self, Self::Err> {
968 match input {
969 "COVER" => Ok(Self::COVER(false)),
970 "RING" => Ok(Self::RING),
971 "BLOCK" => Ok(Self::BLOCK(Default::default())),
972 "PAD" => Ok(Self::PAD(Default::default())),
973 "CORE" => Ok(Self::CORE(Default::default())),
974 "ENDCAP" => Ok(Self::ENDCAP(Default::default())),
975 _ => Err(()),
976 }
977 }
978}
979
980impl fmt::Display for MacroClass {
981 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
982 match self {
983 Self::COVER(bump) => {
984 f.write_str("COVER")?;
985 if *bump {
986 f.write_str("BUMP")?;
987 }
988 }
989 Self::RING => f.write_str("RING")?,
990 Self::BLOCK(sub_class) => {
991 f.write_str("BLOCK")?;
992 if let Some(sub_class) = sub_class {
993 sub_class.fmt(f)?;
994 }
995 }
996 Self::PAD(sub_class) => {
997 f.write_str("PAD")?;
998 if let Some(sub_class) = sub_class {
999 sub_class.fmt(f)?;
1000 }
1001 }
1002 Self::CORE(sub_class) => {
1003 f.write_str("CORE")?;
1004 if let Some(sub_class) = sub_class {
1005 sub_class.fmt(f)?;
1006 }
1007 }
1008 Self::ENDCAP(sub_class) => {
1009 f.write_str("ENDCAP")?;
1010 if let Some(sub_class) = sub_class {
1011 sub_class.fmt(f)?;
1012 }
1013 }
1014 }
1015 Ok(())
1016 }
1017}
1018
1019/// Specify the type of a site: Either IO site (PAD) or core site (CORE).
1020#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1021pub enum SiteClass {
1022 /// A core site.
1023 CORE,
1024 /// An IO site.
1025 PAD,
1026}
1027
1028impl FromStr for SiteClass {
1029 type Err = ();
1030
1031 fn from_str(input: &str) -> Result<Self, Self::Err> {
1032 match input {
1033 "CORE" => Ok(Self::CORE),
1034 "PAD" => Ok(Self::PAD),
1035 _ => Err(()),
1036 }
1037 }
1038}
1039
1040impl fmt::Display for SiteClass {
1041 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1042 match self {
1043 Self::CORE => f.write_str("CORE")?,
1044 Self::PAD => f.write_str("PAD")?,
1045 };
1046 Ok(())
1047 }
1048}
1049
1050/// Subclass of the BLOCK macro class.
1051#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1052pub enum MacroClassBlockType {
1053 ///
1054 BLACKBOX,
1055 ///
1056 SOFT,
1057}
1058
1059impl FromStr for MacroClassBlockType {
1060 type Err = ();
1061
1062 fn from_str(input: &str) -> Result<Self, Self::Err> {
1063 match input {
1064 "BLACKBOX" => Ok(Self::BLACKBOX),
1065 "SOFT" => Ok(Self::SOFT),
1066 _ => Err(()),
1067 }
1068 }
1069}
1070
1071impl fmt::Display for MacroClassBlockType {
1072 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1073 match self {
1074 Self::BLACKBOX => f.write_str("BLACKBOX"),
1075 Self::SOFT => f.write_str("SOFT"),
1076 }
1077 }
1078}
1079
1080/// Subclass of the PAD macro class.
1081#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1082pub enum MacroClassPadType {
1083 /// Input pad.
1084 INPUT,
1085 /// Output pad.
1086 OUTPUT,
1087 /// Inout pad.
1088 INOUT,
1089 /// Power pad.
1090 POWER,
1091 /// Spacer in the pad ring.
1092 SPACER,
1093 /// Area for I/O drivers with out connection to a bump. They need routing to a
1094 /// CLASS COVER BUMP macro for proper connection with the IC package.
1095 AREAIO,
1096}
1097
1098impl FromStr for MacroClassPadType {
1099 type Err = ();
1100
1101 fn from_str(input: &str) -> Result<Self, Self::Err> {
1102 match input {
1103 "INPUT" => Ok(Self::INPUT),
1104 "OUTPUT" => Ok(Self::OUTPUT),
1105 "INOUT" => Ok(Self::INOUT),
1106 "POWER" => Ok(Self::POWER),
1107 "SPACER" => Ok(Self::SPACER),
1108 "AREAIO" => Ok(Self::AREAIO),
1109 _ => Err(()),
1110 }
1111 }
1112}
1113
1114impl fmt::Display for MacroClassPadType {
1115 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1116 match self {
1117 Self::INPUT => f.write_str("INPUT"),
1118 Self::OUTPUT => f.write_str("OUTPUT"),
1119 Self::INOUT => f.write_str("INOUT"),
1120 Self::POWER => f.write_str("POWER"),
1121 Self::SPACER => f.write_str("SPACER"),
1122 Self::AREAIO => f.write_str("AREAIO"),
1123 }
1124 }
1125}
1126
1127/// Subclass of the CORE macro class.
1128#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1129pub enum MacroClassCoreType {
1130 /// Connect to another cell.
1131 FEEDTHRU,
1132 /// Logical one.
1133 TIEHIGH,
1134 /// Logical zero.
1135 TIELOW,
1136 /// Spacer/fill cell.
1137 SPACER,
1138 /// Antenna diode.
1139 ANTENNACELL,
1140 /// Well-tap cell.
1141 WELLTAP,
1142}
1143
1144impl FromStr for MacroClassCoreType {
1145 type Err = ();
1146
1147 fn from_str(input: &str) -> Result<Self, Self::Err> {
1148 match input {
1149 "FEEDTHRU" => Ok(Self::FEEDTHRU),
1150 "TIEHIGH" => Ok(Self::TIEHIGH),
1151 "TIELOW" => Ok(Self::TIELOW),
1152 "SPACER" => Ok(Self::SPACER),
1153 "ANTENNACELL" => Ok(Self::ANTENNACELL),
1154 "WELLTAP" => Ok(Self::WELLTAP),
1155 _ => Err(()),
1156 }
1157 }
1158}
1159
1160impl fmt::Display for MacroClassCoreType {
1161 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1162 match self {
1163 Self::FEEDTHRU => f.write_str("FEEDTHRU"),
1164 Self::TIEHIGH => f.write_str("TIEHIGH"),
1165 Self::TIELOW => f.write_str("TIELOW"),
1166 Self::SPACER => f.write_str("SPACER"),
1167 Self::ANTENNACELL => f.write_str("ANTENNACELL"),
1168 Self::WELLTAP => f.write_str("WELLTAP"),
1169 }
1170 }
1171}
1172
1173/// Subclass of the ENDCAP macro class.
1174#[derive(Copy, Clone, Debug, PartialEq, Eq)]
1175pub enum MacroClassEndcapType {
1176 /// Start of the row (left).
1177 PRE,
1178 /// End of the row (right)
1179 POST,
1180 /// I/O corner cell on top left.
1181 TOPLEFT,
1182 /// I/O corner cell on top right.
1183 TOPRIGHT,
1184 /// I/O corner cell on bottom left.
1185 BOTTOMLEFT,
1186 /// I/O corner cell on bottom right.
1187 BOTTOMRIGHT,
1188}
1189
1190impl FromStr for MacroClassEndcapType {
1191 type Err = ();
1192
1193 fn from_str(input: &str) -> Result<Self, Self::Err> {
1194 match input {
1195 "PRE" => Ok(Self::PRE),
1196 "POST" => Ok(Self::POST),
1197 "TOPLEFT" => Ok(Self::TOPLEFT),
1198 "TOPRIGHT" => Ok(Self::TOPRIGHT),
1199 "BOTTOMLEFT" => Ok(Self::BOTTOMLEFT),
1200 "BOTTOMRIGHT" => Ok(Self::BOTTOMRIGHT),
1201 _ => Err(()),
1202 }
1203 }
1204}
1205
1206impl fmt::Display for MacroClassEndcapType {
1207 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1208 match self {
1209 Self::PRE => f.write_str("PRE"),
1210 Self::POST => f.write_str("POST"),
1211 Self::TOPLEFT => f.write_str("TOPLEFT"),
1212 Self::TOPRIGHT => f.write_str("TOPRIGHT"),
1213 Self::BOTTOMLEFT => f.write_str("BOTTOMLEFT"),
1214 Self::BOTTOMRIGHT => f.write_str("BOTTOMRIGHT"),
1215 }
1216 }
1217}