use crate::common::PinDirection;
use crate::lef_ast::{Shape, LEF};
use db::{Scale, TryCastCoord};
use libreda_db::iron_shapes::prelude::{Geometry, Path, Rect, SimplePolygon, SimpleTransform};
use libreda_db::layout::prelude::LayerInfo;
use libreda_db::netlist::direction::Direction;
use libreda_db::prelude as db;
use libreda_db::traits::{
HierarchyBase, HierarchyIds, LayoutBase, LayoutIds, NetlistBase, NetlistIds,
};
use std::hash::Hash;
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct CellId(pub(crate) String);
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
pub struct CellInstId(pub(crate) String);
impl HierarchyIds for LEF {
type CellId = CellId;
type CellInstId = ();
}
impl HierarchyBase for LEF {
type NameType = String;
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> {
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) -> (),
{
}
fn for_each_cell_dependency<F>(&self, cell: &Self::CellId, f: F)
where
F: FnMut(Self::CellId) -> (),
{
}
fn for_each_dependent_cell<F>(&self, cell: &Self::CellId, f: F)
where
F: FnMut(Self::CellId) -> (),
{
}
fn for_each_cell_reference<F>(&self, cell: &Self::CellId, f: F)
where
F: FnMut(Self::CellInstId) -> (),
{
}
fn num_child_instances(&self, cell: &Self::CellId) -> usize {
return 0;
}
fn num_cells(&self) -> usize {
self.library.macros.len()
}
}
impl NetlistIds for LEF {
type PinId = (Self::CellId, String);
type PinInstId = ();
type NetId = ();
}
impl NetlistBase for LEF {
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 {
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 ¯o_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) -> (),
{
}
fn for_each_internal_net<F>(&self, _circuit: &Self::CellId, _f: F)
where
F: FnMut(Self::NetId) -> (),
{
}
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 LayoutIds for LEF {
type Coord = i32;
type Area = i64;
type LayerId = String;
type ShapeId = ShapeId;
}
impl LayoutBase for LEF {
fn dbu(&self) -> Self::Coord {
unimplemented!()
}
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;
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."); geo
};
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)
};
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.")
}
}