#![allow(missing_docs)]
use super::prelude::*;
pub use super::util::{NetlistEditUtil, NetlistUtil};
pub use crate::traits::{HierarchyBase, HierarchyEdit};
use crate::traits::{HierarchyBaseMT, HierarchyIds, IdType, IdTypeMT};
#[portrait::make]
pub trait NetlistIds: HierarchyIds {
type PinId: IdType;
type PinInstId: IdType;
type NetId: IdType;
}
#[portrait::make]
pub trait NetlistBaseMT:
NetlistBase<PinId = Self::PinIdMT, PinInstId = Self::PinInstIdMT, NetId = Self::NetIdMT>
+ HierarchyBaseMT
{
type PinIdMT: IdTypeMT;
type PinInstIdMT: IdTypeMT;
type NetIdMT: IdTypeMT;
}
impl<N> NetlistBaseMT for N
where
N: NetlistBase + HierarchyBaseMT,
N::PinId: Send + Sync,
N::PinInstId: Send + Sync,
N::NetId: Send + Sync,
{
type PinIdMT = N::PinId;
type PinInstIdMT = N::PinInstId;
type NetIdMT = N::NetId;
}
#[portrait::make(import(crate::prelude::Direction))]
pub trait NetlistBase: HierarchyBase + NetlistIds {
fn template_pin(&self, pin_instance: &Self::PinInstId) -> Self::PinId;
fn pin_direction(&self, pin: &Self::PinId) -> Direction;
fn pin_name(&self, pin: &Self::PinId) -> Self::NameType;
fn pin_by_name(&self, parent_circuit: &Self::CellId, name: &str) -> Option<Self::PinId>;
fn parent_cell_of_pin(&self, pin: &Self::PinId) -> Self::CellId;
fn parent_of_pin_instance(&self, pin_inst: &Self::PinInstId) -> Self::CellInstId;
fn pin_instance(&self, cell_inst: &Self::CellInstId, pin: &Self::PinId) -> Self::PinInstId {
self.each_pin_instance(cell_inst)
.find(|inst| &self.template_pin(inst) == pin)
.expect("No such pin found in this cell.")
}
fn parent_cell_of_net(&self, net: &Self::NetId) -> Self::CellId;
fn net_of_pin(&self, pin: &Self::PinId) -> Option<Self::NetId>;
fn net_of_pin_instance(&self, pin_instance: &Self::PinInstId) -> Option<Self::NetId>;
fn net_zero(&self, parent_circuit: &Self::CellId) -> Self::NetId;
fn net_one(&self, parent_circuit: &Self::CellId) -> Self::NetId;
fn net_by_name(&self, parent_circuit: &Self::CellId, name: &str) -> Option<Self::NetId>;
fn net_name(&self, net: &Self::NetId) -> Option<Self::NameType>;
fn for_each_pin<F>(&self, circuit: &Self::CellId, f: F)
where
F: FnMut(Self::PinId);
fn each_pin_vec(&self, circuit: &Self::CellId) -> Vec<Self::PinId> {
let mut v = Vec::new();
self.for_each_pin(circuit, |c| v.push(c));
v
}
fn each_pin<'a>(
&'a self,
circuit: &Self::CellId,
) -> Box<dyn Iterator<Item = Self::PinId> + 'a> {
Box::new(self.each_pin_vec(circuit).into_iter())
}
fn for_each_pin_instance<F>(&self, circuit_inst: &Self::CellInstId, f: F)
where
F: FnMut(Self::PinInstId);
fn each_pin_instance_vec(&self, circuit_instance: &Self::CellInstId) -> Vec<Self::PinInstId> {
let mut v = Vec::new();
self.for_each_pin_instance(circuit_instance, |c| v.push(c));
v
}
fn each_pin_instance<'a>(
&'a self,
circuit_instance: &Self::CellInstId,
) -> Box<dyn Iterator<Item = Self::PinInstId> + 'a> {
Box::new(self.each_pin_instance_vec(circuit_instance).into_iter())
}
fn each_external_net<'a>(
&'a self,
circuit_instance: &Self::CellInstId,
) -> Box<dyn Iterator<Item = Self::NetId> + 'a> {
Box::new(
self.each_pin_instance(circuit_instance)
.flat_map(move |pin_id| self.net_of_pin_instance(&pin_id)),
)
}
fn for_each_external_net<F>(&self, circuit_instance: &Self::CellInstId, mut f: F)
where
F: FnMut(Self::NetId),
{
self.for_each_pin_instance(circuit_instance, |i| {
self.net_of_pin_instance(&i)
.iter()
.cloned()
.for_each(|n| f(n))
});
}
fn each_external_net_vec(&self, circuit_instance: &Self::CellInstId) -> Vec<Self::NetId> {
let mut v = Vec::new();
self.for_each_external_net(circuit_instance, |n| v.push(n));
v
}
fn for_each_internal_net<F>(&self, circuit: &Self::CellId, f: F)
where
F: FnMut(Self::NetId);
fn each_internal_net_vec(&self, circuit: &Self::CellId) -> Vec<Self::NetId> {
let mut v = Vec::new();
self.for_each_internal_net(circuit, |c| v.push(c));
v
}
fn each_internal_net<'a>(
&'a self,
circuit: &Self::CellId,
) -> Box<dyn Iterator<Item = Self::NetId> + 'a> {
Box::new(self.each_internal_net_vec(circuit).into_iter())
}
fn num_internal_nets(&self, circuit: &Self::CellId) -> usize {
let mut counter = 0;
self.for_each_internal_net(circuit, |_| counter += 1);
counter
}
fn num_net_pins(&self, net: &Self::NetId) -> usize {
let mut n = 0;
self.for_each_pin_of_net(net, |_| n += 1);
n
}
fn num_net_pin_instances(&self, net: &Self::NetId) -> usize {
let mut n = 0;
self.for_each_pin_instance_of_net(net, |_| n += 1);
n
}
fn num_net_terminals(&self, net: &Self::NetId) -> usize {
self.num_net_pins(net) + self.num_net_pin_instances(net)
}
fn num_pins(&self, circuit: &Self::CellId) -> usize;
fn for_each_pin_of_net<F>(&self, net: &Self::NetId, f: F)
where
F: FnMut(Self::PinId);
fn each_pin_of_net_vec(&self, net: &Self::NetId) -> Vec<Self::PinId> {
let mut v = Vec::new();
self.for_each_pin_of_net(net, |c| v.push(c));
v
}
fn each_pin_of_net<'a>(
&'a self,
net: &Self::NetId,
) -> Box<dyn Iterator<Item = Self::PinId> + 'a> {
Box::new(self.each_pin_of_net_vec(net).into_iter())
}
fn for_each_pin_instance_of_net<F>(&self, net: &Self::NetId, f: F)
where
F: FnMut(Self::PinInstId);
fn each_pin_instance_of_net_vec(&self, net: &Self::NetId) -> Vec<Self::PinInstId> {
let mut v = Vec::new();
self.for_each_pin_instance_of_net(net, |c| v.push(c));
v
}
fn each_pin_instance_of_net<'a>(
&'a self,
net: &Self::NetId,
) -> Box<dyn Iterator<Item = Self::PinInstId> + 'a> {
Box::new(self.each_pin_instance_of_net_vec(net).into_iter())
}
}
#[portrait::make(import(crate::prelude::Direction))]
pub trait NetlistEdit: NetlistBase + HierarchyEdit {
fn create_pin(
&mut self,
cell: &Self::CellId,
name: Self::NameType,
direction: Direction,
) -> Self::PinId;
fn remove_pin(&mut self, id: &Self::PinId);
fn rename_pin(&mut self, pin: &Self::PinId, new_name: Self::NameType) -> Self::NameType;
fn create_net(&mut self, parent: &Self::CellId, name: Option<Self::NameType>) -> Self::NetId;
fn rename_net(
&mut self,
net_id: &Self::NetId,
new_name: Option<Self::NameType>,
) -> Option<Self::NameType>;
fn remove_net(&mut self, net: &Self::NetId);
fn connect_pin(&mut self, pin: &Self::PinId, net: Option<Self::NetId>) -> Option<Self::NetId>;
fn disconnect_pin(&mut self, pin: &Self::PinId) -> Option<Self::NetId> {
self.connect_pin(pin, None)
}
fn connect_pin_instance(
&mut self,
pin: &Self::PinInstId,
net: Option<Self::NetId>,
) -> Option<Self::NetId>;
fn disconnect_pin_instance(&mut self, pin_instance: &Self::PinInstId) -> Option<Self::NetId> {
self.connect_pin_instance(pin_instance, None)
}
}