#![allow(unused_variables)]
use iron_shapes::prelude::{Geometry, Rect};
use iron_shapes::transform::SimpleTransform;
use iron_shapes::CoordinateType;
use crate::index::*;
use crate::prelude::{
HierarchyBase, HierarchyEdit, HierarchyIds, L2NBase, L2NEdit, LayoutBase, LayoutEdit,
MapPointwise, NetlistBase, NetlistEdit,
};
use crate::traits::{LayoutIds, NetlistIds};
use itertools::Itertools;
use std::borrow::{Borrow, BorrowMut};
use std::collections::HashMap;
use std::hash::Hash;
use crate::netlist::direction::Direction;
use std::fmt::Debug;
use crate::layout::types::LayerInfo;
use crate::property_storage::{PropertyStore, PropertyValue};
use fnv::{FnvHashMap, FnvHashSet};
use crate::prelude::TryBoundingBox;
use num_traits::One;
type NameT = String;
type IntHashMap<K, V> = FnvHashMap<K, V>;
type IntHashSet<V> = FnvHashSet<V>;
pub type UInt = u32;
pub type SInt = i32;
pub type Coord = i32;
pub type Area = i64;
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct CellId(u32);
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct CellInstId(usize);
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct PinId(u32);
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct PinInstId(usize);
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum TerminalId {
Pin(PinId),
PinInst(PinInstId),
}
impl From<PinId> for TerminalId {
fn from(id: PinId) -> Self {
TerminalId::Pin(id)
}
}
impl From<PinInstId> for TerminalId {
fn from(id: PinInstId) -> Self {
TerminalId::PinInst(id)
}
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct NetId(usize);
pub type ShapeId = Index<Shape<Coord>, u32>;
pub type LayerId = Index<LayerInfo<NameT>, u16>;
macro_rules! impl_from_for_id {
($t:tt, $i:ty) => {
impl From<$i> for $t {
fn from(id: $i) -> Self {
$t(id)
}
}
};
}
impl_from_for_id!(CellId, u32);
impl_from_for_id!(CellInstId, usize);
impl_from_for_id!(PinId, u32);
impl_from_for_id!(PinInstId, usize);
impl_from_for_id!(NetId, usize);
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Circuit<C = Coord, U = ()>
where
C: CoordinateType,
U: Default,
{
id: CellId,
name: NameT,
instances: IntHashSet<CellInstId>,
instances_by_name: HashMap<NameT, CellInstId>,
references: IntHashSet<CellInstId>,
dependencies: IntHashMap<CellId, usize>,
dependent_circuits: IntHashMap<CellId, usize>,
#[allow(unused)]
instance_properties: IntHashMap<CellInstId, PropertyStore<NameT>>,
properties: PropertyStore<NameT>,
#[allow(unused)]
user_data: U,
pins: Vec<PinId>,
nets: IntHashSet<NetId>,
nets_by_name: HashMap<NameT, NetId>,
net_low: NetId,
net_high: NetId,
shapes_map: IntHashMap<LayerId, Shapes<C>>,
}
impl Circuit {
fn id(&self) -> CellId {
self.id
}
fn shapes(&self, layer_id: &LayerId) -> Option<&Shapes<Coord>> {
self.shapes_map.get(layer_id)
}
fn shapes_mut(&mut self, layer_id: &LayerId) -> Option<&mut Shapes<Coord>> {
self.shapes_map.get_mut(layer_id)
}
fn get_or_create_shapes_mut(&mut self, layer_id: &LayerId) -> &mut Shapes<Coord> {
let self_id = self.id();
self.shapes_map
.entry(*layer_id)
.or_insert_with(Shapes::new)
.borrow_mut()
}
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct CircuitInst<C = Coord, U = ()>
where
C: CoordinateType,
{
name: Option<NameT>,
template_circuit_id: CellId,
parent_circuit_id: CellId,
properties: PropertyStore<NameT>,
#[allow(unused)]
user_data: U,
pins: Vec<PinInstId>,
transform: SimpleTransform<C>,
}
impl CircuitInst {
fn get_transform(&self) -> &SimpleTransform<Coord> {
&self.transform
}
fn set_transform(&mut self, tf: SimpleTransform<Coord>) {
self.transform = tf;
}
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Pin {
name: NameT,
direction: Direction,
circuit: CellId,
net: Option<NetId>,
pin_shapes: IntHashSet<ShapeId>,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct PinInst {
pub template_pin_id: PinId,
pub circuit_inst: CellInstId,
net: Option<NetId>,
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Net {
pub name: Option<NameT>,
pub parent_id: CellId,
pub pins: IntHashSet<PinId>,
pub pin_instances: IntHashSet<PinInstId>,
pub net_shapes: IntHashSet<ShapeId>,
}
impl Net {}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Chip<C: CoordinateType = Coord> {
circuits: IntHashMap<CellId, Circuit<C>>,
circuits_by_name: HashMap<NameT, CellId>,
circuit_instances: IntHashMap<CellInstId, CircuitInst>,
nets: IntHashMap<NetId, Net>,
pins: IntHashMap<PinId, Pin>,
pin_instances: IntHashMap<PinInstId, PinInst>,
properties: PropertyStore<NameT>,
id_counter_circuit: u32,
id_counter_circuit_inst: usize,
id_counter_pin: u32,
id_counter_pin_inst: usize,
id_counter_net: usize,
dbu: C,
layer_index_generator: IndexGenerator<LayerInfo<NameT>, u16>,
layers_by_name: HashMap<NameT, LayerId>,
layers_by_index_datatype: IntHashMap<(UInt, UInt), LayerId>,
layer_info: IntHashMap<LayerId, LayerInfo<NameT>>,
shape_index_generator: IndexGenerator<Shape<C>>,
shape_parents: IntHashMap<ShapeId, (CellId, LayerId)>,
net_shapes: IntHashMap<NetId, IntHashSet<ShapeId>>,
}
impl<C: CoordinateType + One> Default for Chip<C> {
fn default() -> Self {
Self {
circuits: Default::default(),
circuits_by_name: Default::default(),
circuit_instances: Default::default(),
nets: Default::default(),
pins: Default::default(),
pin_instances: Default::default(),
properties: Default::default(),
id_counter_circuit: 0,
id_counter_circuit_inst: 0,
id_counter_pin: 0,
id_counter_pin_inst: 0,
id_counter_net: 0,
dbu: C::one(),
layer_index_generator: Default::default(),
layers_by_name: Default::default(),
layers_by_index_datatype: Default::default(),
layer_info: Default::default(),
shape_index_generator: Default::default(),
shape_parents: Default::default(),
net_shapes: Default::default(),
}
}
}
impl Chip<Coord> {
pub fn new() -> Self {
Chip::default()
}
fn circuit_by_name<S: ?Sized + Eq + Hash>(&self, name: &S) -> Option<CellId>
where
NameT: Borrow<S>,
{
self.circuits_by_name.get(name).copied()
}
fn rename_cell(&mut self, cell: &CellId, name: NameT) {
assert!(
!self.circuits_by_name.contains_key(&name),
"Cell with this name already exists: {}",
&name
);
let old_name = &self.circuits[cell].name;
let id = self.circuits_by_name.remove(old_name);
debug_assert_eq!(id.as_ref(), Some(cell));
self.circuit_mut(cell).name.clone_from(&name);
self.circuits_by_name.insert(name, *cell);
}
fn rename_cell_instance(&mut self, inst: &CellInstId, name: Option<NameT>) {
let parent = self.parent_cell(inst);
if let Some(name) = &name {
assert!(
!self.circuit(&parent).instances_by_name.contains_key(name),
"Cell with this name already exists: {}",
name
);
}
let old_name = self.circuit_inst_mut(inst).name.take();
if let Some(old_name) = old_name {
self.circuit_mut(&parent)
.instances_by_name
.remove(&old_name);
}
self.circuit_inst_mut(inst).name.clone_from(&name);
if let Some(name) = name {
self.circuit_mut(&parent)
.instances_by_name
.insert(name, *inst);
}
}
fn create_circuit(&mut self, name: NameT, pins: Vec<(NameT, Direction)>) -> CellId {
assert!(
!self.circuits_by_name.contains_key(&name),
"Circuit with this name already exists: {}",
&name
);
let id = CellId(Self::next_id_counter_u32(&mut self.id_counter_circuit));
let circuit = Circuit {
id,
name: name.clone(),
pins: Default::default(),
instances: Default::default(),
instances_by_name: Default::default(),
references: Default::default(),
nets: Default::default(),
nets_by_name: Default::default(),
net_low: NetId(0),
net_high: NetId(0),
dependent_circuits: Default::default(),
instance_properties: Default::default(),
dependencies: Default::default(),
user_data: Default::default(),
shapes_map: Default::default(),
properties: Default::default(),
};
self.circuits.insert(id, circuit);
self.circuits_by_name.insert(name, id);
let net_low = self.create_net(&id, Some("__LOW__".into()));
let net_high = self.create_net(&id, Some("__HIGH__".into()));
let c = self.circuit_mut(&id);
c.net_low = net_low;
c.net_high = net_high;
pins.into_iter().for_each(|(name, direction)| {
self.create_pin(id, name, direction);
});
id
}
fn remove_circuit(&mut self, circuit_id: &CellId) {
let instances = self
.circuit(circuit_id)
.instances
.iter()
.copied()
.collect_vec();
for inst in instances {
self.remove_circuit_instance(&inst);
}
for shape_id in self.circuits[circuit_id]
.shapes_map
.iter()
.flat_map(|(layer, shapes)| shapes.shapes.keys())
{
self.shape_parents.remove(shape_id);
}
let references = self
.circuit(circuit_id)
.references
.iter()
.copied()
.collect_vec();
for inst in references {
self.remove_circuit_instance(&inst);
}
let pins = self.circuit(circuit_id).pins.clone();
for pin in pins {
self.pins.remove(&pin).unwrap();
}
let name = self.circuit(circuit_id).name.clone();
self.circuits_by_name.remove(&name).unwrap();
self.circuits.remove(circuit_id).unwrap();
}
fn create_circuit_instance(
&mut self,
parent: &CellId,
circuit_template: &CellId,
name: Option<NameT>,
) -> CellInstId {
let id = CellInstId(Self::next_id_counter_usize(
&mut self.id_counter_circuit_inst,
));
{
let mut stack: Vec<CellId> = vec![*parent];
while let Some(c) = stack.pop() {
if &c == circuit_template {
panic!("Cannot create recursive instances.");
}
stack.extend(self.circuit(&c).dependent_circuits.keys().copied())
}
}
let pins = self
.circuit(circuit_template)
.pins
.clone()
.iter()
.map(|&p| self.create_pin_inst(id, p))
.collect();
let inst = CircuitInst {
name: name.clone(),
template_circuit_id: *circuit_template,
parent_circuit_id: *parent,
properties: Default::default(),
user_data: (),
pins,
transform: Default::default(),
};
self.circuit_instances.insert(id, inst);
self.circuit_mut(parent).instances.insert(id);
self.circuit_mut(circuit_template).references.insert(id);
if let Some(name) = name {
debug_assert!(
!self.circuit(parent).instances_by_name.contains_key(&name),
"Circuit instance name already exists."
);
self.circuit_mut(parent).instances_by_name.insert(name, id);
}
{
self.circuit_mut(parent)
.dependencies
.entry(*circuit_template)
.and_modify(|c| *c += 1)
.or_insert(1);
}
{
self.circuit_mut(circuit_template)
.dependent_circuits
.entry(*parent)
.and_modify(|c| *c += 1)
.or_insert(1);
}
id
}
fn remove_circuit_instance(&mut self, circuit_inst_id: &CellInstId) {
self.rename_cell_instance(circuit_inst_id, None);
for pin in self.circuit_inst(circuit_inst_id).pins.clone() {
self.disconnect_pin_instance(&pin);
}
let parent = self.circuit_inst(circuit_inst_id).parent_circuit_id;
let template = self.circuit_inst(circuit_inst_id).template_circuit_id;
{
let count = self
.circuit_mut(&parent)
.dependencies
.entry(template)
.or_insert(0); *count -= 1;
if *count == 0 {
self.circuit_mut(&parent).dependencies.remove(&template);
}
}
{
let count = self
.circuit_mut(&template)
.dependent_circuits
.entry(parent)
.or_insert(0); *count -= 1;
if *count == 0 {
self.circuit_mut(&template)
.dependent_circuits
.remove(&parent);
}
}
self.circuit_instances.remove(circuit_inst_id).unwrap();
self.circuit_mut(&parent).instances.remove(circuit_inst_id);
self.circuit_mut(&template)
.references
.remove(circuit_inst_id);
}
fn create_net(&mut self, parent: &CellId, name: Option<NameT>) -> NetId {
assert!(self.circuits.contains_key(parent));
let id = NetId(Self::next_id_counter_usize(&mut self.id_counter_net));
let net = Net {
name: name.clone(),
parent_id: *parent,
pins: Default::default(),
pin_instances: Default::default(),
net_shapes: Default::default(),
};
self.nets.insert(id, net);
let circuit = self.circuit_mut(parent);
circuit.nets.insert(id);
if let Some(name) = name {
debug_assert!(
!circuit.nets_by_name.contains_key(&name),
"Net name already exists."
);
circuit.nets_by_name.insert(name, id);
}
id
}
fn rename_net(&mut self, net_id: &NetId, new_name: Option<NameT>) -> Option<NameT> {
let parent_circuit = self.parent_cell_of_net(net_id);
if let Some(name) = &new_name {
if let Some(other) = self.circuit(&parent_circuit).nets_by_name.get(name) {
if other != net_id {
panic!("Net name already exists.")
} else {
return new_name;
}
}
}
let maybe_old_name = self.net_mut(net_id).name.take();
if let Some(old_name) = &maybe_old_name {
self.circuit_mut(&parent_circuit)
.nets_by_name
.remove(old_name);
}
if let Some(new_name) = new_name {
self.nets
.get_mut(net_id)
.expect("Net not found.")
.name
.replace(new_name.clone());
self.circuit_mut(&parent_circuit)
.nets_by_name
.insert(new_name, *net_id);
}
maybe_old_name
}
fn remove_net(&mut self, net: &NetId) {
let parent_circuit = self.net(net).parent_id;
assert_ne!(
net,
&self.net_zero(&parent_circuit),
"Cannot remove constant LOW net."
);
assert_ne!(
net,
&self.net_one(&parent_circuit),
"Cannot remove constant HIGH net."
);
let net_shapes = self
.net_shapes
.get(net)
.iter()
.flat_map(|shape_ids| shape_ids.iter().cloned())
.collect_vec();
for net_shape in &net_shapes {
self.set_net_of_shape(net_shape, None);
}
let pins = self.pins_for_net(net).collect_vec();
let pin_insts = self.pins_instances_for_net(net).collect_vec();
for p in pins {
self.disconnect_pin(&p);
}
for p in pin_insts {
self.disconnect_pin_instance(&p);
}
let name = self.net(net).name.clone();
let circuit = self.circuit_mut(&parent_circuit);
circuit.nets.remove(net);
if let Some(name) = &name {
circuit.nets_by_name.remove(name).unwrap();
}
self.nets.remove(net).unwrap();
}
fn disconnect_pin(&mut self, pin: &PinId) -> Option<NetId> {
self.connect_pin(pin, None)
}
fn connect_pin(&mut self, pin: &PinId, net: Option<NetId>) -> Option<NetId> {
if let Some(net) = net {
assert_eq!(
self.pin(pin).circuit,
self.net(&net).parent_id,
"Pin and net do not live in the same circuit."
);
}
let old_net = if let Some(net) = net {
self.pin_mut(pin).net.replace(net)
} else {
self.pin_mut(pin).net.take()
};
if let Some(net) = old_net {
self.net_mut(&net).pins.remove(pin);
}
if let Some(net) = net {
self.net_mut(&net).pins.insert(*pin);
}
old_net
}
fn disconnect_pin_instance(&mut self, pin: &PinInstId) -> Option<NetId> {
self.connect_pin_instance(pin, None)
}
fn connect_pin_instance(&mut self, pin: &PinInstId, net: Option<NetId>) -> Option<NetId> {
if let Some(net) = net {
assert_eq!(
self.circuit_inst(&self.pin_inst(pin).circuit_inst)
.parent_circuit_id,
self.net(&net).parent_id,
"Pin and net do not live in the same circuit."
);
}
let old_net = if let Some(net) = net {
self.pin_inst_mut(pin).net.replace(net)
} else {
self.pin_inst_mut(pin).net.take()
};
if let Some(net) = old_net {
self.net_mut(&net).pin_instances.remove(pin);
}
if let Some(net) = net {
self.net_mut(&net).pin_instances.insert(*pin);
}
old_net
}
fn circuit(&self, id: &CellId) -> &Circuit {
&self.circuits[id]
}
fn circuit_mut(&mut self, id: &CellId) -> &mut Circuit {
self.circuits.get_mut(id).expect("Cell ID not found.")
}
fn circuit_inst(&self, id: &CellInstId) -> &CircuitInst {
&self.circuit_instances[id]
}
fn circuit_inst_mut(&mut self, id: &CellInstId) -> &mut CircuitInst {
self.circuit_instances.get_mut(id).unwrap()
}
fn net(&self, id: &NetId) -> &Net {
self.nets
.get(id)
.expect("Net ID does not exist in this netlist.")
}
fn net_mut(&mut self, id: &NetId) -> &mut Net {
self.nets.get_mut(id).unwrap()
}
fn pin(&self, id: &PinId) -> &Pin {
&self.pins[id]
}
fn pin_mut(&mut self, id: &PinId) -> &mut Pin {
self.pins.get_mut(id).unwrap()
}
fn pin_inst(&self, id: &PinInstId) -> &PinInst {
&self.pin_instances[id]
}
fn pin_inst_mut(&mut self, id: &PinInstId) -> &mut PinInst {
self.pin_instances.get_mut(id).unwrap()
}
fn next_id_counter_usize(ctr: &mut usize) -> usize {
let c = *ctr;
*ctr += 1;
c
}
fn next_id_counter_u32(ctr: &mut u32) -> u32 {
let c = *ctr;
*ctr += 1;
c
}
fn create_pin(&mut self, parent: CellId, name: NameT, direction: Direction) -> PinId {
let pin_id = PinId(Self::next_id_counter_u32(&mut self.id_counter_pin));
let pin = Pin {
name,
direction,
circuit: parent,
net: Default::default(),
pin_shapes: Default::default(),
};
self.pins.insert(pin_id, pin);
self.circuits.get_mut(&parent).unwrap().pins.push(pin_id);
for inst in &self.circuits[&parent].references {
let pin_inst_id = PinInstId(Self::next_id_counter_usize(&mut self.id_counter_pin_inst));
let pin = PinInst {
template_pin_id: pin_id,
circuit_inst: *inst,
net: None,
};
self.pin_instances.insert(pin_inst_id, pin);
self.circuit_instances
.get_mut(inst)
.unwrap()
.pins
.push(pin_inst_id);
}
pin_id
}
fn create_pin_inst(&mut self, circuit: CellInstId, pin: PinId) -> PinInstId {
let id = PinInstId(Self::next_id_counter_usize(&mut self.id_counter_pin_inst));
let pin = PinInst {
template_pin_id: pin,
circuit_inst: circuit,
net: None,
};
self.pin_instances.insert(id, pin);
id
}
fn pins_for_net(&self, net: &NetId) -> impl Iterator<Item = PinId> + '_ {
self.net(net).pins.iter().copied()
}
fn pins_instances_for_net(&self, net: &NetId) -> impl Iterator<Item = PinInstId> + '_ {
self.net(net).pin_instances.iter().copied()
}
fn shape_mut(&mut self, shape_id: &ShapeId) -> &mut Shape<Coord> {
let (cell, layer) = *self.shape_parents.get(shape_id).expect("Shape not found.");
self.circuit_mut(&cell)
.shapes_mut(&layer)
.expect("Layer not found.")
.shapes
.get_mut(shape_id)
.expect("Shape not found.")
}
fn shape(&self, shape_id: &ShapeId) -> &Shape<Coord> {
let (cell, layer) = self.shape_parents.get(shape_id).expect("Shape not found.");
self.circuit(cell)
.shapes(layer)
.expect("Layer not found.")
.shapes
.get(shape_id)
.expect("Shape not found.")
}
}
impl NetlistIds for Chip {
type PinId = PinId;
type PinInstId = PinInstId;
type NetId = NetId;
}
impl NetlistBase for Chip {
fn template_pin(&self, pin_instance: &Self::PinInstId) -> Self::PinId {
self.pin_inst(pin_instance).template_pin_id
}
fn pin_direction(&self, pin: &Self::PinId) -> Direction {
self.pin(pin).direction
}
fn pin_name(&self, pin: &Self::PinId) -> Self::NameType {
self.pin(pin).name.clone()
}
fn pin_by_name(&self, parent_circuit: &Self::CellId, name: &str) -> Option<Self::PinId> {
self.circuit(parent_circuit)
.pins
.iter()
.find(|p| self.pin(p).name.as_str() == name)
.copied()
}
fn parent_cell_of_pin(&self, pin: &Self::PinId) -> Self::CellId {
self.pin(pin).circuit
}
fn parent_of_pin_instance(&self, pin_inst: &Self::PinInstId) -> Self::CellInstId {
self.pin_inst(pin_inst).circuit_inst
}
fn parent_cell_of_net(&self, net: &Self::NetId) -> Self::CellId {
self.nets[net].parent_id
}
fn net_of_pin(&self, pin: &Self::PinId) -> Option<Self::NetId> {
self.pin(pin).net
}
fn net_of_pin_instance(&self, pin_inst: &Self::PinInstId) -> Option<Self::NetId> {
self.pin_inst(pin_inst).net
}
fn net_zero(&self, parent_circuit: &Self::CellId) -> Self::NetId {
self.circuit(parent_circuit).net_low
}
fn net_one(&self, parent_circuit: &Self::CellId) -> Self::NetId {
self.circuit(parent_circuit).net_high
}
fn net_by_name(&self, parent_circuit: &Self::CellId, name: &str) -> Option<Self::NetId> {
self.circuit(parent_circuit).nets_by_name.get(name).copied()
}
fn net_name(&self, net: &Self::NetId) -> Option<Self::NameType> {
self.net(net).name.clone()
}
fn for_each_pin<F>(&self, circuit: &Self::CellId, f: F)
where
F: FnMut(Self::PinId),
{
self.circuit(circuit).pins.iter().copied().for_each(f)
}
fn each_pin(&self, circuit_id: &CellId) -> Box<dyn Iterator<Item = PinId> + '_> {
Box::new(self.circuit(circuit_id).pins.iter().copied())
}
fn for_each_pin_instance<F>(&self, circuit_inst: &Self::CellInstId, f: F)
where
F: FnMut(Self::PinInstId),
{
self.circuit_inst(circuit_inst)
.pins
.iter()
.copied()
.for_each(f)
}
fn each_pin_instance<'a>(
&'a self,
circuit_inst: &Self::CellInstId,
) -> Box<dyn Iterator<Item = Self::PinInstId> + 'a> {
Box::new(self.circuit_inst(circuit_inst).pins.iter().copied())
}
fn for_each_internal_net<F>(&self, circuit: &Self::CellId, f: F)
where
F: FnMut(Self::NetId),
{
self.circuit(circuit).nets.iter().copied().for_each(f)
}
fn each_internal_net(
&self,
circuit: &Self::CellId,
) -> Box<dyn Iterator<Item = Self::NetId> + '_> {
Box::new(self.circuit(circuit).nets.iter().copied())
}
fn num_internal_nets(&self, circuit: &Self::CellId) -> usize {
self.circuit(circuit).nets.len()
}
fn num_pins(&self, circuit: &Self::CellId) -> usize {
self.circuit(circuit).pins.len()
}
fn for_each_pin_of_net<F>(&self, net: &Self::NetId, f: F)
where
F: FnMut(Self::PinId),
{
self.net(net).pins.iter().copied().for_each(f)
}
fn each_pin_of_net<'a>(
&'a self,
net: &Self::NetId,
) -> Box<dyn Iterator<Item = Self::PinId> + 'a> {
Box::new(self.net(net).pins.iter().copied())
}
fn for_each_pin_instance_of_net<F>(&self, net: &Self::NetId, f: F)
where
F: FnMut(Self::PinInstId),
{
self.net(net).pin_instances.iter().copied().for_each(f)
}
fn each_pin_instance_of_net<'a>(
&'a self,
net: &Self::NetId,
) -> Box<dyn Iterator<Item = Self::PinInstId> + 'a> {
Box::new(self.net(net).pin_instances.iter().copied())
}
}
impl NetlistEdit for Chip {
fn create_pin(
&mut self,
circuit: &Self::CellId,
name: Self::NameType,
direction: Direction,
) -> Self::PinId {
Chip::create_pin(self, *circuit, name, direction)
}
fn remove_pin(&mut self, id: &Self::PinId) {
let pin_shapes = self.pin(id).pin_shapes.iter().cloned().collect_vec();
for pin_shape in &pin_shapes {
self.set_pin_of_shape(pin_shape, None);
}
let cell = self.parent_cell_of_pin(id);
for inst in self.each_cell_instance_vec(&cell) {
let pin_inst = self.pin_instance(&inst, id);
self.disconnect_pin_instance(&pin_inst);
self.circuit_inst_mut(&inst).pins.retain(|p| p != &pin_inst);
self.pin_instances.remove(&pin_inst);
}
self.disconnect_pin(id);
self.circuit_mut(&cell).pins.retain(|p| p != id);
self.pins.remove(id);
}
fn rename_pin(&mut self, pin: &Self::PinId, new_name: Self::NameType) -> Self::NameType {
let cell = self.parent_cell_of_pin(pin);
let existing = self.pin_by_name(&cell, &new_name);
if existing.is_some() {
panic!(
"Pin name already exists in cell '{}': '{}'",
self.cell_name(&cell),
new_name
)
}
let old_name = std::mem::replace(&mut self.pin_mut(pin).name, new_name);
old_name
}
fn create_net(&mut self, parent: &CellId, name: Option<Self::NameType>) -> NetId {
Chip::create_net(self, parent, name)
}
fn rename_net(
&mut self,
net_id: &Self::NetId,
new_name: Option<Self::NameType>,
) -> Option<Self::NameType> {
Chip::rename_net(self, net_id, new_name)
}
fn remove_net(&mut self, net: &NetId) {
Chip::remove_net(self, net)
}
fn connect_pin(&mut self, pin: &PinId, net: Option<NetId>) -> Option<NetId> {
Chip::connect_pin(self, pin, net)
}
fn connect_pin_instance(&mut self, pin: &PinInstId, net: Option<NetId>) -> Option<Self::NetId> {
Chip::connect_pin_instance(self, pin, net)
}
}
#[test]
fn test_create_populated_netlist() {
let mut netlist = Chip::default();
let top = netlist.create_circuit("TOP".into(), vec![("A".into(), Direction::Input)]);
netlist.create_pin(top, "B".into(), Direction::Output);
assert_eq!(Some(top), netlist.circuit_by_name("TOP"));
let sub_a = netlist.create_circuit(
"SUB_A".into(),
vec![
("A".into(), Direction::Input),
("B".into(), Direction::Output),
],
);
let sub_b = netlist.create_circuit(
"SUB_B".into(),
vec![
("A".into(), Direction::Input),
("B".into(), Direction::Output),
],
);
let inst_a = netlist.create_circuit_instance(&top, &sub_a, None);
let _inst_b = netlist.create_circuit_instance(&top, &sub_b, None);
let net_a = netlist.create_net(&top, Some("NetA".into()));
let net_b = netlist.create_net(&top, Some("NetB".into()));
let pins_a = netlist.each_pin_instance(&inst_a).collect_vec();
let pins_top = netlist.each_pin(&top).collect_vec();
netlist.connect_pin_instance(&pins_a[0], Some(net_a));
netlist.connect_pin_instance(&pins_a[1], Some(net_b));
netlist.connect_pin(&pins_top[0], Some(net_a));
netlist.connect_pin(&pins_top[1], Some(net_b));
assert_eq!(netlist.num_net_terminals(&net_a), 2);
assert_eq!(netlist.num_net_terminals(&net_b), 2);
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Shape<C, U = ()> {
index: Index<Shape<C, U>>,
pub geometry: Geometry<C>,
net: Option<NetId>,
pin: Option<PinId>,
#[allow(unused)]
user_data: U,
}
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Shapes<C>
where
C: CoordinateType,
{
shapes: IntHashMap<ShapeId, Shape<C>>,
shape_properties: IntHashMap<ShapeId, PropertyStore<NameT>>,
}
impl<C: CoordinateType> Shapes<C> {
fn new() -> Self {
Self {
shapes: Default::default(),
shape_properties: Default::default(),
}
}
fn each_shape(&self) -> impl Iterator<Item = &Shape<C>> {
self.shapes.values()
}
}
impl<C: CoordinateType> TryBoundingBox<C> for Shapes<C> {
fn try_bounding_box(&self) -> Option<Rect<C>> {
self.each_shape().fold(None, |bbox, shape| {
let bbox_new = shape.geometry.try_bounding_box();
match bbox {
None => bbox_new,
Some(bbox1) => {
Some(
match bbox_new {
None => bbox1,
Some(bbox2) => bbox1.add_rect(&bbox2),
},
)
}
}
})
}
}
impl HierarchyIds for Chip<Coord> {
type CellId = CellId;
type CellInstId = CellInstId;
}
impl HierarchyBase for Chip<Coord> {
type NameType = NameT;
fn cell_by_name(&self, name: &str) -> Option<CellId> {
Chip::circuit_by_name(self, name)
}
fn cell_instance_by_name(
&self,
parent_circuit: &Self::CellId,
name: &str,
) -> Option<Self::CellInstId> {
self.circuit(parent_circuit)
.instances_by_name
.get(name)
.copied()
}
fn cell_name(&self, circuit: &Self::CellId) -> Self::NameType {
self.circuit(circuit).name.clone()
}
fn cell_instance_name(&self, circuit_inst: &Self::CellInstId) -> Option<Self::NameType> {
self.circuit_inst(circuit_inst).name.clone()
}
fn parent_cell(&self, circuit_instance: &Self::CellInstId) -> Self::CellId {
self.circuit_inst(circuit_instance).parent_circuit_id
}
fn template_cell(&self, circuit_instance: &Self::CellInstId) -> Self::CellId {
self.circuit_inst(circuit_instance).template_circuit_id
}
fn for_each_cell<F>(&self, f: F)
where
F: FnMut(Self::CellId),
{
self.circuits.keys().copied().for_each(f)
}
fn each_cell(&self) -> Box<dyn Iterator<Item = CellId> + '_> {
Box::new(self.circuits.keys().copied())
}
fn for_each_cell_instance<F>(&self, circuit: &Self::CellId, f: F)
where
F: FnMut(Self::CellInstId),
{
self.circuit(circuit).instances.iter().copied().for_each(f)
}
fn each_cell_instance(
&self,
circuit: &Self::CellId,
) -> Box<dyn Iterator<Item = Self::CellInstId> + '_> {
Box::new(self.circuit(circuit).instances.iter().copied())
}
fn for_each_cell_dependency<F>(&self, circuit: &Self::CellId, f: F)
where
F: FnMut(Self::CellId),
{
self.circuit(circuit)
.dependencies
.keys()
.copied()
.for_each(f);
}
fn each_cell_dependency(
&self,
circuit: &Self::CellId,
) -> Box<dyn Iterator<Item = Self::CellId> + '_> {
Box::new(self.circuit(circuit).dependencies.keys().copied())
}
fn num_cell_dependencies(&self, cell: &Self::CellId) -> usize {
self.circuit(cell).dependencies.len()
}
fn for_each_dependent_cell<F>(&self, circuit: &Self::CellId, f: F)
where
F: FnMut(Self::CellId),
{
self.circuit(circuit)
.dependent_circuits
.keys()
.copied()
.for_each(f);
}
fn each_dependent_cell(
&self,
circuit: &Self::CellId,
) -> Box<dyn Iterator<Item = Self::CellId> + '_> {
Box::new(self.circuit(circuit).dependent_circuits.keys().copied())
}
fn num_dependent_cells(&self, cell: &Self::CellId) -> usize {
self.circuit(cell).dependent_circuits.len()
}
fn for_each_cell_reference<F>(&self, circuit: &Self::CellId, f: F)
where
F: FnMut(Self::CellInstId),
{
self.circuit(circuit).references.iter().copied().for_each(f)
}
fn each_cell_reference(
&self,
circuit: &Self::CellId,
) -> Box<dyn Iterator<Item = Self::CellInstId> + '_> {
Box::new(self.circuit(circuit).references.iter().copied())
}
fn num_cell_references(&self, cell: &Self::CellId) -> usize {
self.circuit(cell).references.len()
}
fn num_child_instances(&self, cell: &Self::CellId) -> usize {
self.circuit(cell).instances.len()
}
fn num_cells(&self) -> usize {
self.circuits.len()
}
fn get_chip_property(&self, key: &Self::NameType) -> Option<PropertyValue> {
self.properties.get(key).cloned()
}
fn get_cell_property(
&self,
cell: &Self::CellId,
key: &Self::NameType,
) -> Option<PropertyValue> {
self.circuit(cell).properties.get(key).cloned()
}
fn get_cell_instance_property(
&self,
inst: &Self::CellInstId,
key: &Self::NameType,
) -> Option<PropertyValue> {
self.circuit_inst(inst).properties.get(key).cloned()
}
}
impl LayoutIds for Chip<Coord> {
type Coord = Coord;
type Area = Area;
type LayerId = LayerId;
type ShapeId = ShapeId;
}
impl LayoutBase for Chip<Coord> {
fn dbu(&self) -> Self::Coord {
self.dbu
}
fn each_layer(&self) -> Box<dyn Iterator<Item = Self::LayerId> + '_> {
Box::new(self.layer_info.keys().copied())
}
fn layer_info(&self, layer: &Self::LayerId) -> LayerInfo<Self::NameType> {
self.layer_info[layer].clone()
}
fn find_layer(&self, index: u32, datatype: u32) -> Option<Self::LayerId> {
self.layers_by_index_datatype
.get(&(index, datatype))
.copied()
}
fn layer_by_name(&self, name: &str) -> Option<Self::LayerId> {
self.layers_by_name.get(name).cloned()
}
fn bounding_box_per_layer(
&self,
cell: &Self::CellId,
layer: &Self::LayerId,
) -> Option<Rect<Coord>> {
let mut bbox = self
.circuit(cell)
.shapes(layer)
.and_then(|shapes| shapes.try_bounding_box());
self.for_each_cell_instance(cell, |i| {
let template = self.template_cell(&i);
let tf = self.get_transform(&i);
let child_bbox = self
.bounding_box_per_layer(&template, layer)
.map(|b| b.transform(|p| tf.transform_point(p)));
bbox = match (bbox, child_bbox) {
(None, None) => None,
(Some(b), None) | (None, Some(b)) => Some(b),
(Some(a), Some(b)) => Some(a.add_rect(&b)),
}
});
bbox
}
fn each_shape_id(
&self,
cell: &Self::CellId,
layer: &Self::LayerId,
) -> Box<dyn Iterator<Item = Self::ShapeId> + '_> {
if let Some(shapes) = self.circuit(cell).shapes(layer) {
Box::new(shapes.each_shape().map(|s| s.index))
} else {
Box::new(None.into_iter()) }
}
fn for_each_shape<F>(&self, cell_id: &Self::CellId, layer: &Self::LayerId, mut f: F)
where
F: FnMut(&Self::ShapeId, &Geometry<Self::Coord>),
{
self.circuits[cell_id]
.shapes_map
.get(layer)
.into_iter()
.for_each(|s| {
s.shapes.values().for_each(|s| f(&s.index, &s.geometry));
});
}
fn with_shape<F, R>(&self, shape_id: &Self::ShapeId, mut f: F) -> R
where
F: FnMut(&Self::LayerId, &Geometry<Self::Coord>) -> R,
{
let shape = self.shape(shape_id);
let (_, layer) = &self.shape_parents[shape_id];
f(layer, &shape.geometry)
}
fn parent_of_shape(&self, shape_id: &Self::ShapeId) -> (Self::CellId, Self::LayerId) {
*self
.shape_parents
.get(shape_id)
.expect("Shape ID not found.")
}
fn get_transform(&self, cell_inst: &Self::CellInstId) -> SimpleTransform<Self::Coord> {
*self.circuit_inst(cell_inst).get_transform()
}
fn get_shape_property(
&self,
shape: &Self::ShapeId,
key: &Self::NameType,
) -> Option<PropertyValue> {
let (cell, layer) = self.shape_parents[shape];
self.circuit(&cell).shapes_map[&layer]
.shape_properties
.get(shape)
.and_then(|props| props.get(key))
.cloned()
}
}
impl HierarchyEdit for Chip<Coord> {
fn create_cell(&mut self, name: Self::NameType) -> Self::CellId {
self.create_circuit(name, vec![])
}
fn remove_cell(&mut self, cell_id: &Self::CellId) {
self.remove_circuit(cell_id)
}
fn create_cell_instance(
&mut self,
parent_cell: &Self::CellId,
template_cell: &Self::CellId,
name: Option<Self::NameType>,
) -> Self::CellInstId {
self.create_circuit_instance(parent_cell, template_cell, name)
}
fn remove_cell_instance(&mut self, id: &Self::CellInstId) {
<Chip<Coord>>::remove_circuit_instance(self, id)
}
fn rename_cell_instance(&mut self, inst: &Self::CellInstId, new_name: Option<Self::NameType>) {
<Chip<Coord>>::rename_cell_instance(self, inst, new_name)
}
fn rename_cell(&mut self, cell: &Self::CellId, new_name: Self::NameType) {
<Chip<Coord>>::rename_cell(self, cell, new_name)
}
fn set_chip_property(&mut self, key: Self::NameType, value: PropertyValue) {
self.properties.insert(key, value);
}
fn set_cell_property(
&mut self,
cell: &Self::CellId,
key: Self::NameType,
value: PropertyValue,
) {
self.circuit_mut(cell).properties.insert(key, value);
}
fn set_cell_instance_property(
&mut self,
inst: &Self::CellInstId,
key: Self::NameType,
value: PropertyValue,
) {
self.circuit_inst_mut(inst).properties.insert(key, value);
}
}
impl LayoutEdit for Chip<Coord> {
fn set_dbu(&mut self, dbu: Self::Coord) {
self.dbu = dbu;
}
fn create_layer(&mut self, index: u32, datatype: u32) -> Self::LayerId {
let layer_index = loop {
let id = self.layer_index_generator.next();
if !self.layer_info.contains_key(&id) {
break id;
}
};
self.create_layer_with_id(layer_index, index, datatype)
.unwrap(); layer_index
}
fn create_layer_with_id(
&mut self,
layer_id: Self::LayerId,
index: u32,
datatype: u32,
) -> Result<(), ()> {
if self.layer_info.contains_key(&layer_id) {
return Err(());
}
self.layers_by_index_datatype
.insert((index, datatype), layer_id);
let info = LayerInfo {
index,
datatype,
name: None,
};
self.layer_info.insert(layer_id, info);
Ok(())
}
fn set_layer_name(
&mut self,
layer: &Self::LayerId,
name: Option<Self::NameType>,
) -> Option<Self::NameType> {
if let Some(name) = &name {
let existing = self.layers_by_name.get(name);
if existing == Some(layer) {
return Some(name.clone());
}
if existing.is_some() {
panic!("Layer name already exists: '{}'", name)
}
}
let previous_name = self
.layer_info
.get_mut(layer)
.expect("Layer ID not found.")
.name
.take();
if let Some(prev_name) = &previous_name {
self.layers_by_name.remove(prev_name);
}
if let Some(name) = name {
self.layers_by_name.insert(name.clone(), *layer);
self.layer_info
.get_mut(layer)
.expect("Layer ID not found.")
.name = Some(name);
}
previous_name
}
fn insert_shape(
&mut self,
parent_cell: &Self::CellId,
layer: &Self::LayerId,
geometry: Geometry<Self::Coord>,
) -> Self::ShapeId {
let shape_id = self.shape_index_generator.next();
let shape = Shape {
index: shape_id,
geometry,
net: None,
pin: None,
user_data: Default::default(),
};
self.shape_parents.insert(shape_id, (*parent_cell, *layer));
self.circuit_mut(parent_cell)
.get_or_create_shapes_mut(layer)
.shapes
.insert(shape_id, shape);
shape_id
}
fn remove_shape(&mut self, shape_id: &Self::ShapeId) -> Option<Geometry<Self::Coord>> {
if let Some(net) = self.get_net_of_shape(shape_id) {
self.net_mut(&net).net_shapes.remove(shape_id);
}
if let Some(pin) = self.get_pin_of_shape(shape_id) {
self.pin_mut(&pin).pin_shapes.remove(shape_id);
}
let (parent_cell, layer) = self.shape_parents[shape_id];
self.shape_parents.remove(shape_id);
self.circuit_mut(&parent_cell)
.shapes_mut(&layer)
.expect("Layer not found.")
.shapes
.remove(shape_id)
.map(|s| s.geometry)
}
fn replace_shape(
&mut self,
shape_id: &Self::ShapeId,
geometry: Geometry<Self::Coord>,
) -> Geometry<Self::Coord> {
let (parent_cell, layer) = self.shape_parents[shape_id];
let shape_id = *shape_id;
let g = &mut self
.circuit_mut(&parent_cell)
.shapes_mut(&layer)
.expect("Layer not found.")
.shapes
.get_mut(&shape_id)
.expect("Shape not found.")
.geometry;
let mut new_g = geometry;
std::mem::swap(g, &mut new_g);
new_g
}
fn set_transform(&mut self, cell_inst: &Self::CellInstId, tf: SimpleTransform<Self::Coord>) {
self.circuit_inst_mut(cell_inst).set_transform(tf)
}
fn set_shape_property(
&mut self,
shape: &Self::ShapeId,
key: Self::NameType,
value: PropertyValue,
) {
let (cell, layer) = self.shape_parents[shape];
self.circuit_mut(&cell)
.shapes_map
.get_mut(&layer)
.expect("Layer not found.")
.shape_properties
.entry(*shape)
.or_default()
.insert(key, value);
}
}
impl L2NBase for Chip<Coord> {
fn shapes_of_net(&self, net_id: &Self::NetId) -> Box<dyn Iterator<Item = Self::ShapeId> + '_> {
Box::new(self.net(net_id).net_shapes.iter().copied())
}
fn shapes_of_pin(&self, pin_id: &Self::PinId) -> Box<dyn Iterator<Item = Self::ShapeId> + '_> {
Box::new(self.pin(pin_id).pin_shapes.iter().cloned())
}
fn get_net_of_shape(&self, shape_id: &Self::ShapeId) -> Option<Self::NetId> {
self.shape(shape_id).net
}
fn get_pin_of_shape(&self, shape_id: &Self::ShapeId) -> Option<Self::PinId> {
self.shape(shape_id).pin
}
}
impl L2NEdit for Chip<Coord> {
fn set_pin_of_shape(
&mut self,
shape_id: &Self::ShapeId,
pin: Option<Self::PinId>,
) -> Option<Self::PinId> {
if let Some(pin) = &pin {
let not_yet_present = self.pin_mut(pin).pin_shapes.insert(*shape_id);
if !not_yet_present {
return Some(*pin);
}
}
let mut pin = pin;
std::mem::swap(&mut self.shape_mut(shape_id).pin, &mut pin);
let previous_pin = pin;
if let Some(previous_pin) = &previous_pin {
assert!(
self.pin_mut(previous_pin).pin_shapes.remove(shape_id),
"Pin was not linked to the shape."
);
}
previous_pin
}
fn set_net_of_shape(
&mut self,
shape_id: &Self::ShapeId,
net: Option<Self::NetId>,
) -> Option<Self::NetId> {
if let Some(net) = &net {
let not_yet_present = self.net_mut(net).net_shapes.insert(*shape_id);
if !not_yet_present {
return Some(*net);
}
}
let mut net = net;
std::mem::swap(&mut self.shape_mut(shape_id).net, &mut net);
let previous_net = net;
if let Some(previous_net) = &previous_net {
assert!(
self.net_mut(previous_net).net_shapes.remove(shape_id),
"Net was not linked to the shape."
);
}
previous_net
}
}