use std::sync::RwLock;
use std::{
any::{Any, TypeId},
collections::HashMap,
sync::Arc,
};
use crate::pdk::Pdk;
use arcstr::ArcStr;
pub use codegen::{DerivedLayerFamily, DerivedLayers, Layer, LayerFamily, Layers};
use serde::{Deserialize, Serialize};
use slotmap::{new_key_type, SlotMap};
use tracing::Level;
#[derive(
Default, Debug, Copy, Clone, Serialize, Deserialize, Hash, PartialEq, Eq, PartialOrd, Ord,
)]
pub struct LayerId(u64);
impl LayerId {
fn increment(&mut self) {
*self = LayerId(self.0 + 1);
}
}
impl AsRef<LayerId> for LayerId {
#[inline]
fn as_ref(&self) -> &LayerId {
self
}
}
new_key_type! {
pub(crate) struct LayerFamilyKey;
}
pub(crate) struct InstalledLayers<PDK: Pdk> {
pub(crate) layers: Arc<PDK::Layers>,
pub(crate) ctx: Arc<RwLock<LayerContext>>,
}
#[derive(Default, Debug, Clone)]
pub struct LayerContext {
next_id: LayerId,
installed_layers: HashMap<TypeId, Arc<dyn Any + Send + Sync>>,
layers_gds_to_info: HashMap<GdsLayerSpec, LayerInfo>,
layers_id_to_info: HashMap<LayerId, LayerInfo>,
layer_id_to_family_key: HashMap<LayerId, LayerFamilyKey>,
layer_families: SlotMap<LayerFamilyKey, LayerFamilyInfo>,
}
impl LayerContext {
pub fn new_layer(&mut self) -> LayerId {
self.next_id.increment();
self.next_id
}
pub(crate) fn new_layer_with_id<F>(&mut self, f: F) -> LayerId
where
F: FnOnce(LayerId) -> LayerInfo,
{
let id = self.new_layer();
let info = f(id);
self.layers_id_to_info.insert(id, info.clone());
if let Some(gds) = info.gds {
self.layers_gds_to_info.insert(gds, info);
}
id
}
pub(crate) fn install_layers<L: Layers>(&mut self) -> Arc<L> {
let layers = L::new(self);
let id = TypeId::of::<L>();
for layer_family in layers.flatten() {
let family_key = self.layer_families.insert(layer_family);
let layer_family = &self.layer_families[family_key];
for layer in layer_family.layers.iter() {
if let Some(gds) = layer.gds {
if self.layers_gds_to_info.insert(gds, layer.clone()).is_some() {
tracing::event!(
Level::WARN,
"installing previously installed GDS layer {:?} again",
gds
);
}
}
self.layers_id_to_info.insert(layer.id, layer.clone());
self.layer_id_to_family_key.insert(layer.id, family_key);
}
}
self.installed_layers
.entry(id)
.or_insert(Arc::new(layers))
.clone()
.downcast::<L>()
.unwrap()
}
pub(crate) fn get_gds_layer(&self, spec: GdsLayerSpec) -> Option<LayerId> {
self.layers_gds_to_info.get(&spec).map(|info| info.id)
}
pub(crate) fn get_gds_layer_from_id(&self, id: LayerId) -> Option<GdsLayerSpec> {
self.layers_id_to_info.get(&id).unwrap().gds
}
pub(crate) fn layer_family_for_layer_id(&self, id: LayerId) -> Option<&LayerFamilyInfo> {
let fkey = *self.layer_id_to_family_key.get(&id)?;
self.layer_families.get(fkey)
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub struct GdsLayerSpec(pub u16, pub u16);
#[derive(Debug, Clone)]
pub struct LayerFamilyInfo {
pub layers: Vec<LayerInfo>,
pub primary: LayerId,
pub pin: Option<LayerId>,
pub label: Option<LayerId>,
}
impl AsRef<LayerId> for LayerFamilyInfo {
#[inline]
fn as_ref(&self) -> &LayerId {
&self.primary
}
}
#[derive(Debug, Clone)]
pub struct LayerInfo {
pub id: LayerId,
pub name: ArcStr,
pub gds: Option<GdsLayerSpec>,
}
impl AsRef<LayerId> for LayerInfo {
#[inline]
fn as_ref(&self) -> &LayerId {
&self.id
}
}
pub trait Layer: Copy {
fn new(ctx: &mut LayerContext) -> Self;
fn info(&self) -> LayerInfo;
fn id(&self) -> LayerId {
self.info().id
}
}
pub trait LayerFamily: Copy {
fn new(ctx: &mut LayerContext) -> Self;
fn info(&self) -> LayerFamilyInfo;
}
pub trait HasPin {
fn drawing(&self) -> LayerId;
fn pin(&self) -> LayerId;
fn label(&self) -> LayerId;
}
pub trait Layers: Any + Send + Sync {
fn new(ctx: &mut LayerContext) -> Self;
fn flatten(&self) -> Vec<LayerFamilyInfo>;
}
impl TryFrom<gds::GdsLayerSpec> for GdsLayerSpec {
type Error = std::num::TryFromIntError;
fn try_from(value: gds::GdsLayerSpec) -> Result<Self, Self::Error> {
let layer = u16::try_from(value.layer)?;
let xtype = u16::try_from(value.xtype)?;
Ok(Self(layer, xtype))
}
}