libreda-lefdef 0.0.2

LEF/DEF input/output for libreda-db.
Documentation
/*
 * Copyright (c) 2021-2021 Thomas Kramer.
 *
 * This file is part of LibrEDA
 * (see https://codeberg.org/libreda/libreda-lefdef).
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

//! Implementation of Netlist and Layout views for the LEF data structure.

use libreda_db::traits::{HierarchyBase, NetlistBase, LayoutBase};
use crate::lef_ast::{LEF, Shape};
use std::hash::Hash;
use libreda_db::netlist::direction::Direction;
use crate::common::PinDirection;
use libreda_db::iron_shapes::prelude::{Path, SimplePolygon, Rect, Geometry, SimpleTransform};
use libreda_db::layout::prelude::LayerInfo;
use libreda_db::prelude as db;
use db::{Scale, TryCastCoord};


/// ID of a macro.
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct CellId(pub(crate) String);

/// ID of a component instance.
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct CellInstId(pub(crate) String);

impl HierarchyBase for LEF {
    type NameType = String;
    type CellId = CellId;
    type CellInstId = ();

    fn cell_by_name(&self, name: &str) -> Option<Self::CellId> {
        self.library.macros.get(name)
            .map(|_| CellId(name.into()))
    }

    fn cell_instance_by_name(&self, parent_cell: &Self::CellId, name: &str) -> Option<Self::CellInstId> {
        // There are no instances.
        None
    }

    fn cell_name(&self, CellId(name): &Self::CellId) -> Self::NameType {
        assert!(self.library.macros.contains_key(name), "Cell not found: {}", name);
        name.clone()
    }

    fn cell_instance_name(&self, cell_inst: &Self::CellInstId) -> Option<Self::NameType> {
        panic!("There are no cell instances in a LEF library.")
    }

    fn parent_cell(&self, cell_instance: &Self::CellInstId) -> Self::CellId {
        panic!("There are no cell instances in a LEF library.")
    }

    fn template_cell(&self, cell_instance: &Self::CellInstId) -> Self::CellId {
        unimplemented!()
    }

    fn for_each_cell<F>(&self, f: F) where F: FnMut(Self::CellId) -> () {
        self.library.macros.keys()
            .map(|name| CellId(name.clone()))
            .for_each(f)
    }

    fn for_each_cell_instance<F>(&self, cell: &Self::CellId, f: F) where F: FnMut(Self::CellInstId) -> () {
        // There are no instances.
    }

    fn for_each_cell_dependency<F>(&self, cell: &Self::CellId, f: F) where F: FnMut(Self::CellId) -> () {
        // There are no instances.
    }

    fn for_each_dependent_cell<F>(&self, cell: &Self::CellId, f: F) where F: FnMut(Self::CellId) -> () {
        // There are no instances.
    }

    fn for_each_cell_reference<F>(&self, cell: &Self::CellId, f: F) where F: FnMut(Self::CellInstId) -> () {
        // There are no instances.
    }

    fn num_child_instances(&self, cell: &Self::CellId) -> usize {
        return 0;
    }

    fn num_cells(&self) -> usize {
        self.library.macros.len()
    }
}

impl NetlistBase for LEF {
    type PinId = (Self::CellId, String);
    type PinInstId = ();
    // There are no instances.
    type NetId = ();

    fn template_pin(&self, pin_instance: &Self::PinInstId) -> Self::PinId {
        panic!("LEF does not have any pin instances.")
    }

    fn pin_direction(&self, (cell, pin_name): &Self::PinId) -> Direction {
        // Find the macro pin by its name.
        let macro_pin = self.library.macros.get(&cell.0)
            .expect("Cell not found.")
            .pins.iter()
            .find(|pin| pin.name.as_str() == pin_name)
            .expect("Macro pin not found.");
        match &macro_pin.direction {
            None => Direction::None,
            Some(d) => match d {
                PinDirection::Input => Direction::Input,
                PinDirection::Output(tristate) => Direction::Output,
                PinDirection::Inout => Direction::InOut,
                PinDirection::Feedthru => Direction::InOut
            }
        }
    }

    fn pin_name(&self, (_macro_name, pin_name): &Self::PinId) -> Self::NameType {
        pin_name.clone()
    }

    fn pin_by_name(&self, parent_circuit: &Self::CellId, pin_name: &str) -> Option<Self::PinId> {
        self.library.macros.get(&parent_circuit.0)
            .expect("Macro not found.")
            .pins.iter()
            .find(|pin| pin.name.as_str() == pin_name)
            .map(|pin| (parent_circuit.clone(), pin.name.clone()))
    }

    fn parent_cell_of_pin(&self, (CellId(cell_name), pin_name): &Self::PinId) -> Self::CellId {
        assert!(self.library.macros.contains_key(cell_name), "Parent cell does not exist: {}", cell_name);
        assert!(self.library.macros[cell_name].pins.iter()
                    .find(|pin| pin.name.as_str() == pin_name)
                    .is_some(), "Pin does not exist: {}:{}", cell_name, pin_name);
        CellId(cell_name.clone())
    }

    fn parent_of_pin_instance(&self, pin_inst: &Self::PinInstId) -> Self::CellInstId {
        panic!("LEF has no pin instances.")
    }

    fn parent_cell_of_net(&self, _net: &Self::NetId) -> Self::CellId {
        panic!("LEF macros have no nets.")
    }

    fn net_of_pin(&self, _pin: &Self::PinId) -> Option<Self::NetId> {
        panic!("LEF macros have no nets.")
    }

    fn net_of_pin_instance(&self, _pin_instance: &Self::PinInstId) -> Option<Self::NetId> {
        panic!("LEF macros have no pin instance nor nets.")
    }

    fn net_zero(&self, parent_circuit: &Self::CellId) -> Self::NetId {
        panic!("LEF macros have no nets.")
    }

    fn net_one(&self, parent_circuit: &Self::CellId) -> Self::NetId {
        panic!("LEF macros have no nets.")
    }

    fn net_by_name(&self, parent_circuit: &Self::CellId, name: &str) -> Option<Self::NetId> {
        None
    }

    fn net_name(&self, net: &Self::NetId) -> Option<Self::NameType> {
        panic!("LEF macros have no nets.")
    }

    fn for_each_pin<F>(&self, circuit: &Self::CellId, mut f: F) where F: FnMut(Self::PinId) -> () {
        self.library.macros.get(&circuit.0)
            .expect("Macro not found.")
            .pins.iter()
            .map(|pin| pin.name.clone())
            .for_each(|name| f((circuit.clone(), name)))
    }

    fn for_each_pin_instance<F>(&self, _circuit_inst: &Self::CellInstId, _f: F) where F: FnMut(Self::PinInstId) -> () {
        // No pin instances.
    }

    fn for_each_internal_net<F>(&self, _circuit: &Self::CellId, _f: F) where F: FnMut(Self::NetId) -> () {
        // No nets.
    }

    fn num_pins(&self, CellId(circuit): &Self::CellId) -> usize {
        self.library.macros.get(circuit)
            .expect("Macro not found.")
            .pins.len()
    }

    fn for_each_pin_of_net<F>(&self, net: &Self::NetId, f: F) where F: FnMut(Self::PinId) -> () {
        panic!("LEF has no nets.")
    }

    fn for_each_pin_instance_of_net<F>(&self, net: &Self::NetId, f: F) where F: FnMut(Self::PinInstId) -> () {
        panic!("LEF has no nets.")
    }
}

#[derive(Clone, Hash, Debug, PartialEq, Eq)]
pub enum ShapeId {
    Obstruction {
        cell: CellId,
        layer: String,
        idx: usize,
    },
    Pin {
        cell: CellId,
        pin: String,
        layer: String,
        port: usize,
        idx: usize
    }
}

impl LayoutBase for LEF {
    type Coord = i32;
    type Area = i64;
    type LayerId = String;
    type ShapeId = ShapeId;

    fn dbu(&self) -> Self::Coord {
        unimplemented!()
        // self.technology.units.database_microns
    }

    fn each_layer(&self) -> Box<dyn Iterator<Item=Self::LayerId> + '_> {
        Box::new(self.technology.layers
            .iter()
            .map(|layer| layer.name().clone())
        )
    }

    fn layer_info(&self, layer: &Self::LayerId) -> LayerInfo<Self::NameType> {
        unimplemented!()
    }

    fn find_layer(&self, index: u32, datatype: u32) -> Option<Self::LayerId> {
        unimplemented!()
    }

    fn layer_by_name(&self, name: &str) -> Option<Self::LayerId> {
        unimplemented!()
    }

    fn bounding_box_per_layer(&self, cell: &Self::CellId, layer: &Self::LayerId) -> Option<Rect<Self::Coord>> {
        unimplemented!()
    }

    fn each_shape_id(&self, cell: &Self::CellId, layer: &Self::LayerId) -> Box<dyn Iterator<Item=Self::ShapeId>> {
        unimplemented!()
    }

    fn for_each_shape<F>(&self, CellId(cell_name): &Self::CellId, layer: &Self::LayerId, mut f: F) where F: FnMut(&Self::ShapeId, &Geometry<Self::Coord>) -> () {
        let lef_macro = self.library.macros.get(cell_name)
            .expect("Macro not found.");

        let convert_geometry = |shape: &Shape| -> Geometry<i32> {
            let dbu_per_micron = self.technology.units.database_microns as f64;

            // Convert the LEF geometry into a database geometry.
            let geo: db::Geometry<f64> = match shape {
                Shape::Path(width, points) => {
                    db::Path::new(points, *width)
                        .scale(dbu_per_micron).into()
                }
                Shape::Rect(p1, p2) => {
                    db::Rect::new(p1, p2)
                        .scale(dbu_per_micron).into()
                }
                Shape::Polygon(points) => {
                    db::SimplePolygon::new(points.clone())
                        .scale(dbu_per_micron).into()
                }
            };
            let geo: db::Geometry<i32> = geo.try_cast()
                .expect("Cast from float failed."); // This should actually not fail.
            geo
        };

        // Get iterators over all geometries.
        let geometries = {
            let obstruction_geometries = lef_macro.obs.iter();
            let pin_geometries = lef_macro.pins.iter()
                .flat_map(|pin| pin.ports.iter())
                .flat_map(|port| port.geometries.iter());
            pin_geometries.chain(obstruction_geometries)
        };

        // Iterate over all layer geometries.
        for layer_geometry in &lef_macro.obs {
            let layer = &layer_geometry.layer_name;
            for (i, g) in layer_geometry.geometries.iter().enumerate() {

                let geo = convert_geometry(&g.shape);

                if let Some(repetition) = &g.step_pattern {
                    unimplemented!("Cant handle step patterns for obstructions yet.");
                } else {
                    let id = ShapeId::Obstruction {
                        cell: CellId(cell_name.clone()),
                        layer: layer.clone(),
                        idx: i
                    };
                    f(&id, &geo)
                }
            }
        }

        for pin in &lef_macro.pins {
            for (port_idx, port) in pin.ports.iter().enumerate() {
                for layer_geometries in &port.geometries{
                    for (i, g) in layer_geometries.geometries.iter().enumerate() {
                        let geo = convert_geometry(&g.shape);
                        if let Some(repetition) = &g.step_pattern {
                            unimplemented!("Cant handle step patterns for obstructions yet.");
                        } else {
                            let id = ShapeId::Pin {
                                cell: CellId(cell_name.clone()),
                                layer: layer_geometries.layer_name.clone(),
                                pin: pin.name.clone(),
                                port: port_idx,
                                idx: i
                            };
                            f(&id, &geo)
                        }
                    }
                }
            }
        }
    }

    fn with_shape<F, R>(&self, shape_id: &Self::ShapeId, f: F) -> R where F: FnMut(&Self::LayerId, &Geometry<Self::Coord>) -> R {
        unimplemented!()
    }

    fn parent_of_shape(&self, shape_id: &Self::ShapeId) -> (Self::CellId, Self::LayerId) {
        unimplemented!()
    }

    fn get_transform(&self, _cell_inst: &Self::CellInstId) -> SimpleTransform<Self::Coord> {
        panic!("LEF has no macro instances.")
    }
}