libreda_lefdef/
import.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//! Import LEF and DEF structures by populating data base structures.
7
8use libreda_db::iron_shapes::traits::MapPointwise;
9use libreda_db::prelude::{self as db, NetlistEditUtil};
10use libreda_db::prelude::{Angle, CoordinateType, Direction, Scale, TerminalId, TryCastCoord};
11use libreda_db::traits::*;
12
13use crate::def_ast;
14use crate::def_ast::{NetTerminal, RoutingPoint, DEF};
15use crate::lef_ast::{Layer, RectOrPolygon, Shape, SignalUse, ViaDefinition, ViaShape, LEF};
16
17use crate::common::{Orient, PinDirection};
18use num_traits::{FromPrimitive, NumCast, PrimInt, Zero};
19use std::collections::HashMap;
20use std::fmt::Formatter;
21
22/// Error type returned from LEF/DEF input and output functions.
23#[derive(Debug, Clone)]
24pub enum LefDefImportError {
25    /// The model (aka template or cell type) of a component instance was not found.
26    ComponentModelNotFound {
27        /// Name of the affected component.
28        component_name: String,
29        /// Name of the model which was not found.
30        model_name: String,
31    },
32    /// A component was referenced by name but not found.
33    ComponentNotFound(String),
34    /// A via is referenced by name but cannot be found.
35    ViaNotFound(String),
36    /// The layer could not be found in the target design and the creation of new layers is disabled.
37    LayerNotFound(String),
38    /// Cell of this name is already present in the layout and now being redefined in during the import.
39    CellNameAlreadyExists(String),
40    /// Unspecified error.
41    Other(String),
42}
43
44impl std::fmt::Display for LefDefImportError {
45    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
46        match self {
47            LefDefImportError::ComponentModelNotFound { component_name, model_name } => {
48                write!(f, "Model of component '{}' not found: '{}'", component_name, model_name)
49            }
50            LefDefImportError::LayerNotFound(layer) => write!(f, "the layer '{}' could not be found in the target design and the creation of new layers is disabled", layer),
51            LefDefImportError::ComponentNotFound(component_name) => write!(f, "component was referenced but not found: '{}'", component_name),
52            LefDefImportError::ViaNotFound(via_name) => write!(f, "component is referenced but not found: '{}'", via_name),
53            LefDefImportError::CellNameAlreadyExists(cell_name) => write!(f, "cell '{}' already exists", cell_name),
54            LefDefImportError::Other(msg) => write!(f, "{}", msg)
55        };
56
57        Ok(())
58    }
59}
60
61/// Control the import of a LEF library.
62/// This is inspired of the `LEFDEFReaderConfiguration` of KLayout.
63#[derive(Clone)]
64pub struct LEFImportOptions<C: L2NEdit> {
65    // /// Data-base unit for coordinates.
66    // pub dbu: Option<C::Coord>,
67    /// Enable import of pins.
68    pub import_pins: bool,
69    /// Also import ground and supply pins. This gets overwritten when `import_pins` is false.
70    pub import_power_pins: bool,
71    /// Append this string to layer names of pins. Default is ".PIN".
72    pub pin_suffix: String,
73    /// Enable import of obstruction shapes.
74    pub import_obstructions: bool,
75    /// Append this string to layer names of obstructions. Default is ".OBS".
76    pub obstruction_suffix: String,
77    /// Import via definitions as cells.
78    pub import_via_definitions: bool,
79    /// Import vias 'generated' vias. Only matters with `import_via_definitions = true`.
80    pub import_generated_vias: bool,
81    /// Import 'fixed' vias. Only matters with `import_via_definitions = true`.
82    pub import_fixed_vias: bool,
83    /// Enable import of cell outlines and define on which layer they should be put.
84    pub import_cell_outlines: bool,
85    /// Layer to be used for cell outlines (abutment boxes).
86    pub cell_outline_layer: Option<String>,
87    /// Mapping from LEF layer names to layer IDs.
88    pub layer_mapping: HashMap<String, C::LayerId>,
89    /// Create layers which are missing in the current design.
90    pub create_missing_layers: bool,
91    /// If a cell with the same name as the via already exists, skip it during import instead of failing.
92    pub skip_existing_vias: bool,
93}
94
95impl<C: L2NEdit> Default for LEFImportOptions<C> {
96    fn default() -> Self {
97        Self {
98            // dbu: None,
99            import_pins: true,
100            import_power_pins: true,
101            pin_suffix: ".PIN".to_string(),
102            import_obstructions: true,
103            obstruction_suffix: ".OBS".to_string(),
104            import_via_definitions: true,
105            import_generated_vias: true,
106            import_fixed_vias: true,
107            import_cell_outlines: true,
108            cell_outline_layer: Some("OUTLINE".to_string()),
109            layer_mapping: Default::default(),
110            create_missing_layers: true,
111            skip_existing_vias: false,
112        }
113    }
114}
115
116impl<C: L2NEdit> LEFImportOptions<C> {
117    /// Try to get a layer ID by the layer name or optionally create a new layer.
118    /// Test the layer mapping but also the layout for existing layers.
119    fn get_or_create_layer_by_name(
120        &self,
121        chip: &mut C,
122        layer_name: &String,
123    ) -> Result<C::LayerId, LefDefImportError> {
124        let layer = {
125            // First try to get the layer from the layer map...
126            if let Some(l) = self.layer_mapping.get(layer_name) {
127                Some(l.clone())
128            } else {
129                chip.layer_by_name(layer_name.as_str())
130                    // ... as a last resort try to create the layer but only if creation of layers is enabled.
131                    .or_else(|| {
132                        if self.create_missing_layers {
133                            let next_idx = chip
134                                .each_layer()
135                                .map(|id| chip.layer_info(&id).index)
136                                .max()
137                                .unwrap_or(0)
138                                + 1;
139                            log::debug!("Create layer: {}", layer_name);
140                            let layer_id = chip.create_layer(next_idx, 0);
141                            chip.set_layer_name(&layer_id, Some(layer_name.clone().into()));
142                            Some(layer_id)
143                        } else {
144                            None
145                        }
146                    })
147            }
148        };
149
150        // Return an error when no layer was found.
151        layer.ok_or_else(|| LefDefImportError::LayerNotFound(layer_name.clone()))
152    }
153}
154
155/// Convert a LEF shape into a database shape with the correct units.
156fn convert_geometry<C: CoordinateType + NumCast>(
157    dbu_per_micron: u64,
158    shape: &Shape,
159) -> db::Geometry<C> {
160    let dbu_per_micron = dbu_per_micron as f64;
161    // Convert the LEF geometry into a database geometry.
162    let geo: db::Geometry<f64> = match shape {
163        Shape::Path(width, points) => db::Path::new(points, *width).scale(dbu_per_micron).into(),
164        Shape::Rect(p1, p2) => db::Rect::new(p1, p2).scale(dbu_per_micron).into(),
165        Shape::Polygon(points) => db::SimplePolygon::new(points.clone())
166            .scale(dbu_per_micron)
167            .into(),
168    };
169    let geo: db::Geometry<C> = geo.try_cast().expect("Cast from float failed."); // This should actually not fail.
170    geo
171}
172
173/// Control the import of DEF structures.
174#[derive(Clone)]
175pub struct DEFImportOptions<C: L2NEdit> {
176    /// Options for importing the LEF.
177    pub lef_import_options: LEFImportOptions<C>,
178    /// Enable import of blockage shapes.
179    pub import_blockages: bool,
180    /// Append this string to layer names of blockages. Default is ".BLOCKAGE".
181    pub blockages_suffix: String,
182    /// Enable import of nets.
183    pub import_nets: bool,
184    /// Enable import of routes.
185    pub import_wiring: bool,
186    /// Enable import of fixed via definitions. Vias are imported as cells.
187    pub import_fixed_vias: bool,
188    /// If true: If a via name already exists, don't import it.
189    /// If false: Return an error if the via name already exists.
190    pub skip_existing_vias: bool,
191}
192
193impl<C: L2NEdit> Default for DEFImportOptions<C> {
194    fn default() -> Self {
195        Self {
196            lef_import_options: Default::default(),
197            import_blockages: true,
198            blockages_suffix: ".BLOCKAGE".to_string(),
199            import_nets: true,
200            import_wiring: true,
201            import_fixed_vias: true,
202            skip_existing_vias: false,
203        }
204    }
205}
206
207/// Convert a LEF structure into a `Chip` data structure using default import options.
208/// Use `import_lef_into_db()` for better control over the import strategy.
209pub fn lef_to_db<C, Crd>(lef: &LEF) -> Result<C, LefDefImportError>
210where
211    Crd: NumCast + Ord + CoordinateType,
212    C: L2NEdit<Coord = Crd> + Default,
213{
214    let mut chip = C::default();
215    let options = Default::default();
216    import_lef_into_db(&options, lef, &mut chip).map(|_| chip)
217}
218
219/// Populate `chip` with the contents of the LEF data-structure.
220pub fn import_lef_into_db<C, Crd>(
221    options: &LEFImportOptions<C>,
222    lef: &LEF,
223    chip: &mut C,
224) -> Result<(), LefDefImportError>
225where
226    Crd: NumCast + Ord + CoordinateType,
227    C: L2NEdit<Coord = Crd>,
228{
229    // let dbu_per_micron = lef.technology.units.database_microns;
230    assert!(
231        chip.dbu() > Crd::zero(),
232        "Data-base distance unit (DBU) must be a positive number"
233    );
234    let dbu_per_micron = chip.dbu().to_u64().expect("failed to convert DBU to u64");
235
236    // Setup layers.
237    for (i, layer) in lef.technology.layers.iter().enumerate() {
238        let result = options.get_or_create_layer_by_name(chip, layer.name());
239        if let Err(err) = result {
240            // Dont't abort yet on this error. Could be that the layer is then never used.
241            // Emit a warning instead.
242            log::warn!("Failed to create layer: {} ({})", layer.name(), err)
243        }
244    }
245
246    // Import via definitions.
247    if options.import_via_definitions {
248        import_lef_vias(options, lef, chip)?;
249    }
250
251    // Create macro cells.
252    for (macro_name, lef_macro) in &lef.library.macros {
253        let cell = chip.create_cell(macro_name.to_string().into());
254
255        // Insert pins.
256        if options.import_pins {
257            // Cache for pin names with suffix.
258            let mut pin_layer_name_cache = HashMap::new();
259            for macro_pin in &lef_macro.pins {
260                // Eventually skip power pins.
261                let signal_use = macro_pin.signal_use.unwrap_or(SignalUse::Signal);
262                let is_power_ground_pin =
263                    signal_use == SignalUse::Power || signal_use == SignalUse::Ground;
264                if !options.import_power_pins && is_power_ground_pin {
265                    continue;
266                }
267
268                // Get signal direction.
269                let direction = match &macro_pin.direction {
270                    None => Direction::None,
271                    Some(d) => match d {
272                        PinDirection::Input => Direction::Input,
273                        PinDirection::Output(_tristate) => Direction::Output,
274                        PinDirection::Inout => Direction::InOut,
275                        PinDirection::Feedthru => Direction::InOut,
276                    },
277                };
278
279                // Create electrical pin.
280                let pin = chip.create_pin(&cell, macro_pin.name.clone().into(), direction);
281
282                // Insert pin shapes.
283                for port in &macro_pin.ports {
284                    for layer_geometry in &port.geometries {
285                        // Find the target layer for the pin.
286                        // Append the layer suffix.
287                        let layer_name = pin_layer_name_cache
288                            .entry(&layer_geometry.layer_name)
289                            .or_insert_with(|| {
290                                format!("{}{}", layer_geometry.layer_name, options.pin_suffix)
291                            });
292                        let layer = options.get_or_create_layer_by_name(chip, layer_name)?;
293
294                        for g in &layer_geometry.geometries {
295                            let geo = convert_geometry(dbu_per_micron, &g.shape);
296                            let shape_id = chip.insert_shape(&cell, &layer, geo);
297                            chip.set_pin_of_shape(&shape_id, Some(pin.clone()));
298                        }
299                    }
300                }
301            }
302        }
303
304        // Import cell outline.
305        if options.import_cell_outlines {
306            if let Some((width, height)) = lef_macro.size {
307                if let Some(outline_layer_name) = &options.cell_outline_layer {
308                    // Get the rectangular outline shape.
309                    let shape = Shape::Rect(
310                        lef_macro.origin,
311                        lef_macro.origin + db::Point::new(width, height),
312                    );
313                    // Convert units.
314                    let geo = convert_geometry(dbu_per_micron, &shape);
315
316                    let outline_layer =
317                        options.get_or_create_layer_by_name(chip, outline_layer_name)?;
318
319                    // Insert outline shape on layer.
320                    chip.insert_shape(&cell, &outline_layer, geo);
321                }
322            }
323        }
324
325        // Import obstruction shapes.
326        if options.import_obstructions {
327            let mut obs_layer_name_cache = HashMap::new();
328            for obs in &lef_macro.obs {
329                // Find the target layer for the obstruction.
330                // Append the layer suffix.
331                let layer_name = obs_layer_name_cache
332                    .entry(&obs.layer_name)
333                    .or_insert_with(|| format!("{}{}", obs.layer_name, options.obstruction_suffix));
334                let layer = options.get_or_create_layer_by_name(chip, layer_name)?;
335
336                for g in &obs.geometries {
337                    let geo = convert_geometry(dbu_per_micron, &g.shape);
338                    chip.insert_shape(&cell, &layer, geo);
339                }
340            }
341        }
342    }
343
344    Ok(())
345}
346
347/// Import LEF via definitions as cells into the layout.
348/// On success returns a vector with the IDs of the new via cells.
349pub fn import_lef_vias<C, Crd>(
350    options: &LEFImportOptions<C>,
351    lef: &LEF,
352    chip: &mut C,
353) -> Result<Vec<C::CellId>, LefDefImportError>
354where
355    Crd: NumCast + Ord + CoordinateType,
356    C: L2NEdit<Coord = Crd>,
357{
358    let dbu_per_micron: f64 = chip.dbu().to_f64().unwrap();
359
360    let mut via_cells = vec![];
361
362    for (via_name, via) in &lef.vias {
363        // Check that no cell with this name exists.
364        if chip.cell_by_name(via_name).is_some() {
365            if options.skip_existing_vias {
366                continue;
367            } else {
368                return Err(LefDefImportError::CellNameAlreadyExists(via_name.clone()));
369            }
370        }
371
372        let via_cell = chip.create_cell(via_name.clone().into());
373
374        match via {
375            ViaDefinition::GeneratedVia(via) => {
376                if options.import_generated_vias {
377                    todo!("import of generated vias")
378                }
379            }
380            ViaDefinition::FixedVia(via) => {
381                if options.import_fixed_vias {
382                    for (layer_name, shapes) in &via.geometry {
383                        let layer = options.get_or_create_layer_by_name(chip, layer_name)?;
384
385                        for shape in shapes {
386                            // TODO import mask number
387                            let geometry: db::Geometry<f64> = match &shape.shape {
388                                RectOrPolygon::Rect((p1, p2)) => {
389                                    db::Rect::new(*p1, *p2).scale(dbu_per_micron).into()
390                                }
391                                RectOrPolygon::Polygon(points) => {
392                                    // Create a rectilinear polygon if possible.
393                                    let p = db::SimplePolygon::new(points.to_vec())
394                                        .scale(dbu_per_micron);
395                                    if let Some(p) = db::SimpleRPolygon::try_new(p.points()) {
396                                        p.into()
397                                    } else {
398                                        p.into()
399                                    }
400                                }
401                            };
402
403                            let geo: db::Geometry<C::Coord> =
404                                geometry.try_cast().expect("cast from f64 failed");
405
406                            // Add the shape to the layout.
407                            chip.insert_shape(&via_cell, &layer, geo);
408                        }
409                    }
410                }
411            }
412            _ => {}
413        };
414
415        via_cells.push(via_cell);
416    }
417
418    Ok(via_cells)
419}
420
421/// Convert a LEF and a DEF structure into a `Chip` data structure.
422/// Currently this reads only the placement of the cells. No wires are created.
423pub fn lefdef_to_db<C, Crd>(
424    options: &DEFImportOptions<C>,
425    lef: &LEF,
426    def: &DEF,
427) -> Result<C, LefDefImportError>
428where
429    Crd: NumCast + Ord + CoordinateType + PrimInt + std::fmt::Debug,
430    C: L2NEdit<Coord = Crd> + Default,
431{
432    let mut chip = C::default();
433
434    // First read the library.
435    import_lef_into_db(&options.lef_import_options, lef, &mut chip)?;
436    import_def_into_db(&options, Some(lef), def, &mut chip).map(|_| chip)
437}
438
439/// Import the netlist from the DEF structure into the `top_cell`.
440///
441/// **Caveat**: Adds connections of pins but does not clear the existing netlist before. Existing connections
442/// may be disrupted.
443pub fn import_def_netlist<C, Crd>(
444    options: &DEFImportOptions<C>,
445    def: &DEF,
446    top_cell: &C::CellId,
447    chip: &mut C,
448) -> Result<(), LefDefImportError>
449where
450    Crd: NumCast + Ord + CoordinateType + PrimInt,
451    C: L2NEdit<Coord = Crd>,
452{
453    log::info!(
454        "Import netlist from DEF. Number of nets: {}",
455        def.nets.len()
456    );
457    let mut nets_by_name = HashMap::new();
458
459    // Process each net.
460    for net in &def.nets {
461        if let Some(net_name) = &net.name {
462            // Get or create net ID.
463            let net_id = nets_by_name
464                .entry(net_name)
465                .or_insert_with(|| chip.create_net(&top_cell, Some(net_name.to_string().into())));
466
467            for term in &net.terminals {
468                // Find net terminal based on the given component and pin names.
469                let term_id: TerminalId<C> = match term {
470                    NetTerminal::ComponentPin {
471                        component_name,
472                        pin_name,
473                    } => {
474                        // Pin instance.
475                        let inst = chip
476                            .cell_instance_by_name(&top_cell, component_name.as_str())
477                            .ok_or_else(|| {
478                                LefDefImportError::ComponentNotFound(component_name.to_string())
479                            })?;
480                        let cell = chip.template_cell(&inst);
481                        let pin_id =
482                            chip.pin_by_name(&cell, pin_name.as_str()).ok_or_else(|| {
483                                LefDefImportError::Other(format!(
484                                    "Pin of component not found: {}",
485                                    pin_name
486                                ))
487                            })?;
488                        let pin_inst = chip.pin_instance(&inst, &pin_id);
489
490                        TerminalId::PinInstId(pin_inst)
491                    }
492                    NetTerminal::IoPin(pin_name) => {
493                        // Pin.
494                        let pin_id =
495                            chip.pin_by_name(&top_cell, pin_name.as_str())
496                                .ok_or_else(|| {
497                                    LefDefImportError::Other(format!(
498                                        "Pin of top-level cell not found: {}",
499                                        pin_name
500                                    ))
501                                })?;
502
503                        TerminalId::PinId(pin_id)
504                    }
505                };
506                // Attach the terminal to the net.
507                chip.connect_terminal(&term_id, Some(net_id.clone()));
508            }
509        } else {
510            log::warn!("DEF import of nets without name (MUSTJOIN nets) is not implemented yet.");
511        }
512    }
513    Ok(())
514}
515
516/// Import DEF via definitons as cells into the layout.
517pub fn import_def_vias<C, Crd>(
518    options: &DEFImportOptions<C>,
519    def: &DEF,
520    chip: &mut C,
521) -> Result<(), LefDefImportError>
522where
523    Crd: NumCast + Ord + CoordinateType,
524    C: L2NEdit<Coord = Crd>,
525{
526    log::debug!("import via definitions from DEF");
527
528    for (via_name, via) in &def.vias {
529        log::debug!("import via '{}'", via_name);
530
531        // Check that no cell with this name exists.
532        if chip.cell_by_name(via_name).is_some() {
533            if options.skip_existing_vias {
534                continue;
535            } else {
536                return Err(LefDefImportError::CellNameAlreadyExists(via_name.clone()));
537            }
538        }
539
540        let via_cell = chip.create_cell(via_name.clone().into());
541
542        match via {
543            def_ast::ViaDefinition::ViaGeometry(via_geometry) => {
544                log::debug!("import of via geometry '{}'", via_name);
545                for geometry in via_geometry {
546                    // TODO: For multi-patterning import mask number.
547                    if geometry.mask_num.is_some() {
548                        log::warn!("via mask number is ignored");
549                    }
550
551                    let layer = options
552                        .lef_import_options
553                        .get_or_create_layer_by_name(chip, &geometry.layer)?;
554
555                    let geometry: db::Geometry<db::Coord> = match &geometry.shape {
556                        def_ast::RectOrPolygon::Rect(r) => r.clone().into(),
557                        def_ast::RectOrPolygon::Polygon(p) => p.clone().into(),
558                    };
559
560                    let geo: db::Geometry<C::Coord> = geometry.try_cast().expect("cast failed");
561
562                    // Add the shape to the layout.
563                    chip.insert_shape(&via_cell, &layer, geo);
564                }
565            }
566            def_ast::ViaDefinition::ViaRule => {
567                log::debug!("skip import of via rule '{}'", via_name);
568            }
569        }
570    }
571
572    Ok(())
573}
574
575/// Import routes/wiring from the nets in the DEF structure.
576pub fn import_def_regular_wiring<C, Crd>(
577    options: &DEFImportOptions<C>,
578    lef: &LEF,
579    def: &DEF,
580    top_cell: &C::CellId,
581    chip: &mut C,
582) -> Result<(), LefDefImportError>
583where
584    Crd: NumCast + Ord + CoordinateType + PrimInt,
585    C: L2NEdit<Coord = Crd>,
586{
587    log::info!(
588        "Import wiring from DEF. Number of nets with wiring: {}",
589        def.nets
590            .iter()
591            .filter(|net| !net.regular_wiring.is_empty())
592            .count()
593    );
594
595    // Find default wiring widths from LEF.
596    let default_wiring_widths = {
597        let mut default_wiring_widths = HashMap::new();
598        let units_per_micron: f64 = chip.dbu().to_f64().unwrap();
599
600        for layer in &lef.technology.layers {
601            match layer {
602                Layer::MasterSlice(_) => {
603                    // Ignore
604                }
605                Layer::Cut(_) => {
606                    // Ignore
607                }
608                Layer::Routing(routing_layer) => {
609                    // Find the layer by its name.
610                    if let Some(layer_id) = chip.layer_by_name(routing_layer.name.as_str()) {
611                        // Get wire width and convert to database units.
612                        let default_widths_microns = routing_layer.width;
613                        let default_widths_dbu =
614                            db::Coord::from_f64(default_widths_microns * units_per_micron)
615                                .expect("Failed to cast default path width to database units.");
616
617                        // Store the wiring widths.
618                        default_wiring_widths.insert(layer_id, default_widths_dbu);
619                    } else {
620                        log::warn!("Layer '{}' is not present in the current design. Default wiring width will be ignored during import.", &routing_layer.name);
621                    }
622                }
623            }
624        }
625        default_wiring_widths
626    };
627
628    // Process each net.
629    for net in &def.nets {
630        let net_name = net.name.as_ref().ok_or_else(|| {
631            LefDefImportError::Other("Wiring for unnamed nets is not supported.".into())
632        })?;
633
634        log::debug!("Import wiring for net '{}'", &net_name);
635
636        let net_id = chip
637            .net_by_name(top_cell, net_name.as_str())
638            .ok_or_else(|| LefDefImportError::Other(format!("Net not found: {}", net_name)))?;
639
640        for regular_wiring in &net.regular_wiring {
641            let _wiring_class = regular_wiring.class; // TODO: Wiring class is for now ignored.
642            for wiring in &regular_wiring.wiring {
643                let _style = wiring.style_num; // TODO: Style is ignored for now.
644                let _taper_rule = &wiring.taper_rule; // TODO: Taper rule is ignored for now.
645
646                // Current location of the path.
647                let mut current_layer = options
648                    .lef_import_options
649                    .get_or_create_layer_by_name(chip, &wiring.start_layer_name)?;
650                let mut current_point = None;
651
652                // Find default wiring widths from LEF.
653                let path_width = *default_wiring_widths.get(&current_layer).ok_or_else(|| {
654                    LefDefImportError::Other(format!(
655                        "No default wiring width defined for layer '{}'",
656                        &wiring.start_layer_name
657                    ))
658                })?;
659
660                let _2 = Crd::one() + Crd::one();
661
662                let mut begin_ext = path_width / 2;
663                let mut end_ext = path_width / 2;
664                let mut path: Vec<db::Point<_>> = Vec::new();
665                let mut paths: Vec<db::Path<Crd>> = Vec::new();
666
667                for routing_point in &wiring.routing_points {
668                    match routing_point {
669                        RoutingPoint::Point {
670                            point,
671                            ext_value,
672                            mask_num,
673                        } => {
674                            if let Some(ext_value) = ext_value {
675                                if current_point.is_none() {
676                                    // Extension at beginning of path.
677                                    begin_ext = *ext_value;
678                                }
679                                end_ext = *ext_value;
680                            }
681                            current_point = Some(point.clone());
682                            path.push(point.clone());
683                        }
684                        RoutingPoint::Via {
685                            via_name,
686                            orient,
687                            via_mask_num,
688                        } => {
689                            // Import the via by creating a instance of the via cell with the same name.
690                            if let Some(p) = current_point {
691                                // Place a via cell at the current point.
692                                let via_cell =
693                                    chip.cell_by_name(via_name.as_str()).ok_or_else(|| {
694                                        LefDefImportError::ViaNotFound(via_name.clone())
695                                    })?;
696
697                                // Get the orientation and displacement of the via instance.
698                                let transform = if let Some(orient) = orient {
699                                    def_orient_to_transform(orient)
700                                } else {
701                                    db::SimpleTransform::identity()
702                                }
703                                .then(&db::SimpleTransform::translate(p.v().cast()));
704
705                                // Create the via instance.
706                                let via_instance =
707                                    chip.create_cell_instance(&top_cell, &via_cell, None);
708
709                                // Set the placement of the via instance.
710                                chip.set_transform(&via_instance, transform);
711                            } else {
712                                log::error!("current point in wiring path is not known");
713                            }
714                        }
715                        RoutingPoint::Rect { rect, mask_num } => {
716                            // Insert the rectangle into the layout.
717                            let rect = rect.cast();
718                            let shape_id = chip.insert_shape(top_cell, &current_layer, rect.into());
719                            // Associate with the net.
720                            chip.set_net_of_shape(&shape_id, Some(net_id.clone()));
721                        }
722                        RoutingPoint::Virtual(p) => {
723                            current_point = Some(p.clone());
724                            let finished_path = std::mem::replace(&mut path, vec![]);
725
726                            let finished_path = db::Path::new_extended(
727                                finished_path,
728                                path_width,
729                                begin_ext,
730                                end_ext,
731                            )
732                            .cast();
733                            paths.push(finished_path);
734                        }
735                    }
736                }
737
738                // Store current path.
739                let finished_path =
740                    db::Path::new_extended(path, path_width, begin_ext, end_ext).cast();
741                paths.push(finished_path);
742
743                // Write paths to layout.
744                for path in paths {
745                    if path.len() > 1 {
746                        // Skip paths without segments.
747                        let path = path.cast(); // Cast to correct coordinate type.
748                        let shape_id = chip.insert_shape(top_cell, &current_layer, path.into());
749                        // Associate with the net.
750                        chip.set_net_of_shape(&shape_id, Some(net_id.clone()));
751                    }
752                }
753            }
754        }
755    }
756    Ok(())
757}
758
759/// Convert a LEF and a DEF structure into a `Chip` data structure.
760///
761/// A LEF data structure may be necessary for the definition of default wiring lengths.
762/// An error will be returned if the LEF data structure is omitted but needed.
763pub fn import_def_into_db<C, Crd>(
764    options: &DEFImportOptions<C>,
765    lef: Option<&LEF>,
766    def: &DEF,
767    chip: &mut C,
768) -> Result<(), LefDefImportError>
769where
770    Crd: NumCast + Ord + CoordinateType + PrimInt + std::fmt::Debug,
771    C: L2NEdit<Coord = Crd>,
772{
773    if options.import_fixed_vias {
774        import_def_vias(options, def, chip)?;
775    }
776
777    let top_cell = chip.create_cell(def.design_name.clone().unwrap_or("TOP".to_string()).into());
778    log::info!("Import '{}' from DEF.", chip.cell_name(&top_cell));
779
780    // Create pins.
781    log::info!("Import top-level pins: {}", def.pins.len());
782    for pin in &def.pins {
783        let pin_dir = match &pin.direction {
784            None => Direction::None,
785            Some(d) => match d {
786                PinDirection::Input => Direction::Input,
787                PinDirection::Output(_tristate) => Direction::Output,
788                PinDirection::Inout => Direction::InOut,
789                PinDirection::Feedthru => Direction::InOut,
790            },
791        };
792        chip.create_pin(&top_cell, pin.net_name.to_string().into(), pin_dir);
793    }
794
795    // Import outline of top cell (DIEAREA).
796    if options.lef_import_options.import_cell_outlines {
797        if let Some(die_area) = &def.die_area {
798            if let Some(outline_layer_name) = &options.lef_import_options.cell_outline_layer {
799                let outline_layer = options
800                    .lef_import_options
801                    .get_or_create_layer_by_name(chip, outline_layer_name)?;
802
803                // Insert outline shape on layer.
804                let geometry = die_area.cast().into();
805                chip.insert_shape(&top_cell, &outline_layer, geometry);
806            }
807        }
808    }
809
810    // Create components (instances).
811    log::info!(
812        "Import components from DEF. Number of components: {}",
813        def.components.len()
814    );
815
816    let outline_layer = {
817        let outline_layer_name = options
818            .lef_import_options
819            .cell_outline_layer
820            .as_ref()
821            .ok_or(LefDefImportError::Other(
822                "Outline layer name is not defined.".into(),
823            ))?;
824
825        chip.layer_by_name(outline_layer_name)
826            .ok_or(LefDefImportError::Other(format!(
827                "Outline layer '{}' is not created yet.",
828                outline_layer_name
829            )))?
830    };
831
832    for component in &def.components {
833        // Find template cell.
834        let module = chip.cell_by_name(component.model_name.as_str()).ok_or(
835            LefDefImportError::ComponentModelNotFound {
836                component_name: component.name.clone(),
837                model_name: component.model_name.clone(),
838            },
839        )?;
840
841        // Find bounding box of the cell.
842        let bbox = chip.bounding_box_per_layer(&module, &outline_layer).ok_or(
843            LefDefImportError::Other(format!(
844                "Cell has no defined outline: {}",
845                chip.cell_name(&module)
846            )),
847        )?;
848
849        // Create instance.
850        let inst =
851            chip.create_cell_instance(&top_cell, &module, Some(component.name.clone().into()));
852
853        if let Some((displacement, orientation, is_fixed)) = &component.position {
854            let tf = def_orient_to_transform(orientation);
855
856            let bbox = bbox.transform(|p| tf.transform_point(p));
857
858            // Normalize displacement such that origin of the cell is at `displacement`.
859            let tf = tf.then(&db::SimpleTransform::translate(
860                displacement.cast() - bbox.lower_left(),
861            ));
862            chip.set_transform(&inst, tf);
863        }
864    }
865
866    if options.import_blockages {
867        // TODO: Import blockages.
868    }
869
870    // Import netlist.
871    if options.import_nets {
872        import_def_netlist(options, def, &top_cell, chip)?;
873    }
874
875    // Import routes.
876    if options.import_wiring {
877        let lef = lef.ok_or_else(|| {
878            LefDefImportError::Other(
879                "No LEF data is provided but needed for import of wiring.".into(),
880            )
881        })?;
882        import_def_regular_wiring(options, lef, def, &top_cell, chip)?;
883    }
884
885    Ok(())
886}
887
888/// Convert a DEF `Orient` type into a 90-degree rotation transform.
889pub(crate) fn def_orient_to_transform<Crd>(orient: &Orient) -> db::SimpleTransform<Crd>
890where
891    Crd: CoordinateType,
892{
893    let my = &db::SimpleTransform::mirror_y();
894
895    match orient {
896        Orient::N => db::SimpleTransform::identity(),
897        Orient::S => db::SimpleTransform::rotate90(Angle::R180),
898        Orient::E => db::SimpleTransform::rotate90(Angle::R270),
899        Orient::W => db::SimpleTransform::rotate90(Angle::R90),
900        Orient::FN => db::SimpleTransform::identity().then(my),
901        Orient::FS => db::SimpleTransform::rotate90(Angle::R180).then(my),
902        Orient::FE => db::SimpleTransform::rotate90(Angle::R270).then(my),
903        Orient::FW => db::SimpleTransform::rotate90(Angle::R90).then(my),
904    }
905}
906
907pub(crate) fn transform_to_def_orient<Crd>(tf: &db::SimpleTransform<Crd>) -> Orient
908where
909    Crd: CoordinateType,
910{
911    let (angle, flip_y) = if tf.mirror {
912        // Remove y-flip.
913        let tf_unflipped_y = tf.then(&db::SimpleTransform::mirror_y());
914        (tf_unflipped_y.rotation, true)
915    } else {
916        (tf.rotation, false)
917    };
918
919    let orientation = match angle {
920        Angle::R0 => Orient::N,
921        Angle::R180 => Orient::S,
922        Angle::R270 => Orient::E,
923        Angle::R90 => Orient::W,
924    };
925
926    if flip_y {
927        orientation.flipped()
928    } else {
929        orientation
930    }
931}
932
933#[test]
934fn test_orient_to_transform() {
935    use Orient::*;
936    let orients = [N, S, W, E, FN, FS, FW, FE];
937    for o in orients {
938        assert_eq!(
939            o,
940            transform_to_def_orient(&def_orient_to_transform::<i32>(&o))
941        );
942    }
943}
944
945#[test]
946fn test_lefdef_to_chip() {
947    use crate::def_parser::read_def_chars;
948    use crate::lef_parser::read_lef_chars;
949    let data = r#"
950# Parts from gscl45nm.lef.
951
952VERSION 5.5 ;
953NAMESCASESENSITIVE ON ;
954BUSBITCHARS "[]" ;
955DIVIDERCHAR "/" ;
956
957PROPERTYDEFINITIONS
958  LAYER contactResistance REAL ;
959END PROPERTYDEFINITIONS
960
961UNITS
962  DATABASE MICRONS 2000 ;
963END UNITS
964MANUFACTURINGGRID 0.0025 ;
965LAYER poly
966  TYPE MASTERSLICE ;
967END poly
968
969LAYER contact
970  TYPE CUT ;
971  SPACING 0.075 ;
972  PROPERTY contactResistance 10.5 ;
973END contact
974
975LAYER metal1
976  TYPE ROUTING ;
977  DIRECTION HORIZONTAL ;
978  PITCH 0.19 ;
979  WIDTH 0.065 ;
980  SPACING 0.065 ;
981  RESISTANCE RPERSQ 0.38 ;
982END metal1
983
984LAYER via1
985  TYPE CUT ;
986  SPACING 0.075 ;
987  PROPERTY contactResistance 5.69 ;
988END via1
989
990LAYER metal2
991  TYPE ROUTING ;
992  DIRECTION VERTICAL ;
993  PITCH 0.19 ;
994  WIDTH 0.065 ;
995  SPACING 0.065 ;
996  RESISTANCE RPERSQ 0.38 ;
997END metal2
998
999LAYER OVERLAP
1000  TYPE OVERLAP ;
1001END OVERLAP
1002
1003VIA M2_M1_via DEFAULT
1004  LAYER metal1 ;
1005    RECT -0.0675 -0.0325 0.0675 0.0325 ;
1006  LAYER via1 ;
1007    RECT -0.0325 -0.0325 0.0325 0.0325 ;
1008  LAYER metal2 ;
1009    RECT -0.035 -0.0675 0.035 0.0675 ;
1010END M2_M1_via
1011
1012VIARULE M2_M1 GENERATE
1013  LAYER metal1 ;
1014    ENCLOSURE 0 0.035 ;
1015  LAYER metal2 ;
1016    ENCLOSURE 0 0.035 ;
1017  LAYER via1 ;
1018    RECT -0.0325 -0.0325 0.0325 0.0325 ;
1019    SPACING 0.14 BY 0.14 ;
1020END M2_M1
1021
1022VIARULE M1_POLY GENERATE
1023  LAYER poly ;
1024    ENCLOSURE 0 0 ;
1025  LAYER metal1 ;
1026    ENCLOSURE 0 0.035 ;
1027  LAYER contact ;
1028    RECT -0.0325 -0.0325 0.0325 0.0325 ;
1029    SPACING 0.14 BY 0.14 ;
1030END M1_POLY
1031
1032SPACING
1033  SAMENET metal1 metal1 0.1 ;
1034  SAMENET metal2 metal2 0.1 ;
1035END SPACING
1036
1037SITE CoreSite
1038  CLASS CORE ;
1039  SIZE 0.38 BY 2.47 ;
1040END CoreSite
1041
1042MACRO INVX1
1043  CLASS CORE ;
1044  ORIGIN 0 0 ;
1045  FOREIGN INVX1 0 0 ;
1046  SIZE 0.57 BY 2.47 ;
1047  SYMMETRY X Y ;
1048  SITE CoreSite ;
1049  PIN A
1050    DIRECTION INPUT ;
1051    USE SIGNAL ;
1052    PORT
1053      LAYER metal1 ;
1054        RECT 0.1575 0.4875 0.2575 0.6225 ;
1055    END
1056  END A
1057  PIN Y
1058    DIRECTION OUTPUT ;
1059    USE SIGNAL ;
1060    PORT
1061      LAYER metal1 ;
1062        RECT 0.3475 0.2175 0.4125 1.815 ;
1063        RECT 0.3125 0.2175 0.4475 0.4225 ;
1064    END
1065  END Y
1066  PIN gnd
1067    DIRECTION INOUT ;
1068    USE GROUND ;
1069    SHAPE ABUTMENT ;
1070    PORT
1071      LAYER metal1 ;
1072        RECT 0.1625 -0.065 0.2275 0.4225 ;
1073        RECT 0 -0.065 0.57 0.065 ;
1074    END
1075  END gnd
1076  PIN vdd
1077    DIRECTION INOUT ;
1078    USE POWER ;
1079    SHAPE ABUTMENT ;
1080    PORT
1081      LAYER metal1 ;
1082        RECT 0.1625 1.265 0.2275 2.535 ;
1083        RECT 0 2.405 0.57 2.535 ;
1084    END
1085  END vdd
1086END INVX1
1087
1088
1089MACRO INVX2
1090  CLASS CORE ;
1091  ORIGIN 0 0 ;
1092  FOREIGN INVX1 0 0 ;
1093  SIZE 0.57 BY 2.47 ;
1094  SYMMETRY X Y ;
1095  SITE CoreSite ;
1096  PIN A
1097    DIRECTION INPUT ;
1098    USE SIGNAL ;
1099    PORT
1100      LAYER metal1 ;
1101        RECT 0.1575 0.4875 0.2575 0.6225 ;
1102    END
1103  END A
1104  PIN Y
1105    DIRECTION OUTPUT ;
1106    USE SIGNAL ;
1107    PORT
1108      LAYER metal1 ;
1109        RECT 0.3475 0.2175 0.4125 1.815 ;
1110        RECT 0.3125 0.2175 0.4475 0.4225 ;
1111    END
1112  END Y
1113  PIN gnd
1114    DIRECTION INOUT ;
1115    USE GROUND ;
1116    SHAPE ABUTMENT ;
1117    PORT
1118      LAYER metal1 ;
1119        RECT 0.1625 -0.065 0.2275 0.4225 ;
1120        RECT 0 -0.065 0.57 0.065 ;
1121    END
1122  END gnd
1123  PIN vdd
1124    DIRECTION INOUT ;
1125    USE POWER ;
1126    SHAPE ABUTMENT ;
1127    PORT
1128      LAYER metal1 ;
1129        RECT 0.1625 1.265 0.2275 2.535 ;
1130        RECT 0 2.405 0.57 2.535 ;
1131    END
1132  END vdd
1133END INVX2
1134
1135END LIBRARY
1136
1137    "#;
1138
1139    let result = read_lef_chars(data.chars());
1140    let lef = result.expect("LEF parsing failed.");
1141
1142    let def_data = r#"
1143VERSION 5.7 ;
1144DIVIDERCHAR "/" ;
1145BUSBITCHARS "[]" ;
1146DESIGN test_design ;
1147UNITS DISTANCE MICRONS 2000 ;
1148TECHNOLOGY FreePDK45 ;
1149
1150DIEAREA ( 0 0 ) ( 10000 10000 ) ;
1151
1152PINS 2 ;
1153- IN + NET IN
1154    + DIRECTION INPUT
1155- OUT + NET OUT
1156    + DIRECTION OUTPUT
1157END PINS
1158
1159COMPONENTS 4 ;
1160    - _1_ INVX1
1161        + PLACED ( 0 0 ) N ;
1162    - _2_ INVX2 
1163        + PLACED ( 0 0 ) S ;
1164    - _3_ INVX2 
1165        + PLACED ( 0 0 ) FN ;
1166    - _4_ INVX1 
1167        + PLACED ( 0 0 ) FW ;
1168END COMPONENTS
1169
1170NETS 6 ;
1171- IN ( PIN IN ) ;
1172- OUT ( PIN OUT ) ;
1173- net1 ( _1_ A ) ;
1174END NETS
1175
1176END DESIGN
1177"#;
1178
1179    let result = read_def_chars(def_data.chars());
1180    let def = result.expect("DEF parsing failed.");
1181
1182    let mut chip = db::Chip::new();
1183    chip.set_dbu(1000);
1184    let mut options = DEFImportOptions::default();
1185    options.lef_import_options.import_power_pins = false;
1186    // Import LEF.
1187    {
1188        let result = import_lef_into_db(&options.lef_import_options, &lef, &mut chip);
1189        if result.is_err() {
1190            dbg!(&result);
1191        }
1192    }
1193    // Import DEF.
1194    {
1195        let result = import_def_into_db(&options, Some(&lef), &def, &mut chip);
1196        if result.is_err() {
1197            dbg!(&result);
1198        }
1199    }
1200
1201    assert_eq!(chip.num_cells(), 1 + 2 + 1); // TOP + INVX1 + INVX2 + a via
1202
1203    let top = chip.cell_by_name("test_design").unwrap();
1204    assert_eq!(chip.num_child_instances(&top), 4);
1205
1206    let invx1 = chip.cell_by_name("INVX1").expect("Cell not found.");
1207    assert_eq!(chip.num_pins(&invx1), 2);
1208
1209    assert_eq!(chip.num_internal_nets(&top), 3 + 2); // + HIGH and LOW
1210
1211    // Check if pin A of instance _1_ is indeed connected to net1.
1212    let pin_a = chip.pin_by_name(&invx1, "A").expect("Pin A not found.");
1213
1214    let [inst1, inst2, inst3, inst4] = ["_1_", "_2_", "_3_", "_4_"].map(|n| {
1215        chip.cell_instance_by_name(&top, n)
1216            .expect("Cell instance not found.")
1217    });
1218
1219    let net = chip
1220        .net_of_pin_instance(&chip.pin_instance(&inst1, &pin_a))
1221        .expect("No net connected to _1_:A.");
1222
1223    assert_eq!(chip.net_name(&net), Some("net1".to_string()));
1224
1225    // Check positions of cells.
1226    let outline_layer = chip.layer_by_name("OUTLINE").unwrap();
1227    dbg!(chip.bounding_box_per_layer(&invx1, &outline_layer));
1228
1229    // orient=N
1230    let tf1 = chip.get_transform(&inst1);
1231    assert_eq!(tf1, db::SimpleTransform::translate((0, 0)));
1232
1233    // orient=S
1234    let tf2 = chip.get_transform(&inst2);
1235    assert_eq!(
1236        tf2,
1237        db::SimpleTransform::rotate90(Angle::R180)
1238            .then(&db::SimpleTransform::translate((570, 2470)))
1239    );
1240
1241    // orient=FN
1242    let tf3 = chip.get_transform(&inst3);
1243    assert_eq!(
1244        tf3,
1245        db::SimpleTransform::mirror_y().then(&db::SimpleTransform::translate((570, 0)))
1246    );
1247
1248    // orient=FW
1249    let tf4 = chip.get_transform(&inst4);
1250    assert_eq!(
1251        tf4,
1252        db::SimpleTransform::rotate90(Angle::R90)
1253            .then(&db::SimpleTransform::mirror_y())
1254            .then(&db::SimpleTransform::translate((0, 0)))
1255    );
1256}