use crate::NotNan;
use crate::{
ast::{AttributeList, ComplexAttri, GroupComments, GroupFn, SimpleAttri},
ArcStr, GroupSet,
};
#[derive(Debug, Default, Clone)]
#[derive(liberty_macros::Group)]
#[mut_set::derive::item(
sort,
macro(derive(Debug, Clone,Default);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct TableLookUpMultiSegment {
#[liberty(name)]
#[id]
name: Option<ArcStr>,
#[liberty(comments)]
pub comments: GroupComments<Self>,
#[liberty(undefined)]
pub undefined: AttributeList,
#[liberty(simple)]
#[id]
segment: usize,
#[liberty(complex)]
pub index_1: Vec<NotNan<f64>>,
#[liberty(complex)]
pub index_2: Vec<NotNan<f64>>,
#[liberty(complex)]
pub index_3: Vec<NotNan<f64>>,
#[liberty(complex)]
pub index_4: Vec<NotNan<f64>>,
#[liberty(complex)]
pub values: Values,
}
#[derive(Debug, Default, Clone)]
#[derive(liberty_macros::Group)]
#[mut_set::derive::item(
sort,
macro(derive(Debug, Clone,Default);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct DriverWaveform {
#[id]
#[liberty(name)]
pub name: Option<ArcStr>,
#[id]
#[liberty(simple(type=Option))]
pub driver_waveform_name: Option<ArcStr>,
#[liberty(comments)]
pub comments: GroupComments<Self>,
#[liberty(undefined)]
pub undefined: AttributeList,
#[liberty(complex)]
pub index_1: Vec<NotNan<f64>>,
#[liberty(complex)]
pub index_2: Vec<NotNan<f64>>,
#[liberty(complex)]
pub index_3: Vec<NotNan<f64>>,
#[liberty(complex)]
pub index_4: Vec<NotNan<f64>>,
#[liberty(complex)]
pub values: Values,
}
#[derive(Debug, Default, Clone)]
#[derive(liberty_macros::Group)]
#[mut_set::derive::item(
sort,
macro(derive(Debug, Clone,Default);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct TableLookUp2D {
#[id]
#[liberty(name)]
name: Option<ArcStr>,
#[liberty(comments)]
pub comments: GroupComments<Self>,
#[liberty(undefined)]
pub undefined: AttributeList,
#[liberty(complex)]
pub index_1: Vec<NotNan<f64>>,
#[liberty(complex)]
pub index_2: Vec<NotNan<f64>>,
#[liberty(complex)]
pub values: Values,
}
#[derive(Debug, Default, Clone)]
#[derive(liberty_macros::Group)]
#[mut_set::derive::item(
sort,
macro(derive(Debug, Clone,Default);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct Vector3D {
#[id]
#[liberty(name)]
name: Option<ArcStr>,
#[liberty(comments)]
pub comments: GroupComments<Self>,
#[liberty(undefined)]
pub undefined: AttributeList,
#[id]
#[liberty(complex)]
pub index_1: NotNan<f64>,
#[id]
#[liberty(complex)]
pub index_2: NotNan<f64>,
#[liberty(complex)]
pub index_3: Vec<NotNan<f64>>,
#[liberty(complex)]
pub values: Vec<NotNan<f64>>,
}
#[derive(Debug, Default, Clone)]
#[derive(liberty_macros::Group)]
#[mut_set::derive::item(
sort,
macro(derive(Debug, Clone,Default);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct ReferenceTimeVector3D {
#[id]
#[liberty(name)]
name: Option<ArcStr>,
#[liberty(comments)]
pub comments: GroupComments<Self>,
#[liberty(undefined)]
pub undefined: AttributeList,
#[id]
#[liberty(simple)]
pub reference_time: NotNan<f64>,
#[id]
#[liberty(complex)]
pub index_1: NotNan<f64>,
#[id]
#[liberty(complex)]
pub index_2: NotNan<f64>,
#[liberty(complex)]
pub index_3: Vec<NotNan<f64>>,
#[liberty(complex)]
pub values: Vec<NotNan<f64>>,
}
#[derive(Debug, Default, Clone)]
#[derive(liberty_macros::Group)]
#[mut_set::derive::item(
sort,
macro(derive(Debug, Clone,Default);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct Vector4D {
#[id]
#[liberty(name)]
name: Option<ArcStr>,
#[liberty(comments)]
pub comments: GroupComments<Self>,
#[liberty(undefined)]
pub undefined: AttributeList,
#[id]
#[liberty(complex)]
pub index_1: NotNan<f64>,
#[id]
#[liberty(complex)]
pub index_2: NotNan<f64>,
#[id]
#[liberty(complex)]
pub index_3: NotNan<f64>,
#[liberty(complex)]
pub index_4: Vec<NotNan<f64>>,
#[liberty(complex)]
pub values: Vec<NotNan<f64>>,
}
#[derive(Debug, Default, Clone)]
#[derive(liberty_macros::Group)]
#[mut_set::derive::item(
sort,
macro(derive(Debug, Clone,Default);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct Vector3DGrpup {
#[id]
#[liberty(name)]
name: Option<ArcStr>,
#[liberty(comments)]
pub comments: GroupComments<Self>,
#[liberty(undefined)]
pub undefined: AttributeList,
#[liberty(group(type = Set))]
pub vector: GroupSet<Vector3D>,
}
#[derive(Debug, Default, Clone)]
#[derive(liberty_macros::Group)]
#[mut_set::derive::item(
sort,
macro(derive(Debug, Clone,Default);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct ReferenceTimeVector3DGrpup {
#[id]
#[liberty(name)]
name: Option<ArcStr>,
#[liberty(comments)]
pub comments: GroupComments<Self>,
#[liberty(undefined)]
pub undefined: AttributeList,
#[liberty(group(type = Set))]
pub vector: GroupSet<ReferenceTimeVector3D>,
}
#[derive(Debug, Default, Clone)]
#[derive(liberty_macros::Group)]
#[mut_set::derive::item(
sort,
macro(derive(Debug, Clone,Default);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct Vector4DGrpup {
#[id]
#[liberty(name)]
name: Option<ArcStr>,
#[liberty(comments)]
pub comments: GroupComments<Self>,
#[liberty(undefined)]
pub undefined: AttributeList,
#[liberty(group(type = Set))]
pub vector: GroupSet<Vector4D>,
}
impl GroupFn for Vector3DGrpup {}
impl GroupFn for Vector4DGrpup {}
impl GroupFn for ReferenceTimeVector3D {}
impl GroupFn for ReferenceTimeVector3DGrpup {}
#[derive(Debug, Default, Clone)]
#[derive(liberty_macros::Group)]
#[mut_set::derive::item(
sort,
macro(derive(Debug, Clone,Default);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct TableLookUp3D {
#[id]
#[liberty(name)]
name: Option<ArcStr>,
#[liberty(comments)]
pub comments: GroupComments<Self>,
#[liberty(undefined)]
pub undefined: AttributeList,
#[liberty(complex)]
pub index_1: Vec<NotNan<f64>>,
#[liberty(complex)]
pub index_2: Vec<NotNan<f64>>,
#[liberty(complex)]
pub index_3: Vec<NotNan<f64>>,
#[liberty(complex)]
pub values: Values,
}
#[derive(Debug, Default, Clone)]
#[derive(liberty_macros::Group)]
#[mut_set::derive::item(
sort,
macro(derive(Debug, Clone,Default);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct TableLookUp1D {
unit: (),
#[id]
#[liberty(name)]
name: Option<ArcStr>,
#[liberty(comments)]
pub comments: GroupComments<Self>,
#[liberty(undefined)]
pub undefined: AttributeList,
#[liberty(complex)]
pub index_1: Vec<NotNan<f64>>,
#[liberty(complex)]
pub values: Vec<NotNan<f64>>,
}
impl GroupFn for TableLookUp1D {}
#[derive(Debug, Default, Clone)]
#[derive(liberty_macros::Group)]
#[mut_set::derive::item(
sort,
macro(derive(Debug, Clone,Default);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct TableLookUp {
unit: (),
#[id]
#[liberty(name)]
name: Option<ArcStr>,
#[liberty(comments)]
pub comments: GroupComments<Self>,
#[liberty(undefined)]
pub undefined: AttributeList,
#[liberty(complex)]
pub index_1: Vec<NotNan<f64>>,
#[liberty(complex)]
pub index_2: Vec<NotNan<f64>>,
#[liberty(complex)]
pub index_3: Vec<NotNan<f64>>,
#[liberty(complex)]
pub index_4: Vec<NotNan<f64>>,
#[liberty(complex)]
pub values: Values,
}
#[duplicate::duplicate_item(
AllTypes;
[TableLookUp];
[TableLookUpMultiSegment];
[TableLookUp2D];
[TableLookUp3D];
[DriverWaveform];
)]
impl GroupFn for AllTypes {
#[inline]
fn post_process(&mut self) {
match (self.index_1.len(), self.index_2.len()) {
(0, 0) => {
self.values.size1 = self.values.inner.len();
}
(l1, 0) => {
self.values.size1 = l1;
self.values.size2 = 1;
}
(l1, l2) => {
self.values.size1 = l2;
self.values.size2 = l1;
}
}
}
}
impl GroupFn for Vector3D {}
impl GroupFn for Vector4D {}
#[derive(Debug, Default, Clone)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct Values {
pub size1: usize,
pub size2: usize,
pub inner: Vec<NotNan<f64>>,
}
impl ComplexAttri for Values {
#[inline]
fn parse(v: &[&str]) -> Result<Self, crate::ast::ComplexParseError> {
Ok(Self {
size1: 0,
size2: 0,
inner: <Vec<NotNan<f64>> as ComplexAttri>::parse(v)?,
})
}
#[inline]
fn to_wrapper(&self) -> crate::ast::ComplexWrapper {
let mut buffer = ryu::Buffer::new();
self
.inner
.chunks(self.size1)
.map(|v| {
vec![itertools::Itertools::join(
&mut v.iter().map(|f| buffer.format(f.into_inner()).to_owned()),
", ",
)
.into()]
})
.collect()
}
}
#[derive(Debug, Default, Clone)]
#[derive(liberty_macros::Group)]
#[mut_set::derive::item(
sort,
macro(derive(Debug, Clone, Default);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct TableTemple {
#[id]
#[liberty(name)]
pub name: ArcStr,
#[liberty(comments)]
pub comments: GroupComments<Self>,
#[liberty(undefined)]
pub undefined: AttributeList,
#[liberty(simple(type=Option))]
pub variable_1: Option<Variable>,
#[liberty(simple(type=Option))]
pub variable_2: Option<Variable>,
#[liberty(simple(type=Option))]
pub variable_3: Option<Variable>,
#[liberty(simple(type=Option))]
pub variable_4: Option<Variable>,
#[liberty(complex(type=Option))]
pub index_1: Option<Vec<NotNan<f64>>>,
#[liberty(complex(type=Option))]
pub index_2: Option<Vec<NotNan<f64>>>,
#[liberty(complex(type=Option))]
pub index_3: Option<Vec<NotNan<f64>>>,
#[liberty(complex(type=Option))]
pub index_4: Option<Vec<NotNan<f64>>>,
}
impl GroupFn for TableTemple {}
#[derive(Debug, Clone, Copy)]
#[derive(Hash, PartialEq, Eq)]
#[derive(Ord, PartialOrd)]
#[derive(serde::Serialize, serde::Deserialize)]
pub enum Variable {
Time(TimeVariable),
Voltage(VoltageVariable),
Capacitance(CapacitanceVariable),
RcProduct,
Length(LengthVariable),
Scalar(ScalarVariable),
}
impl SimpleAttri for Variable {}
impl core::str::FromStr for Variable {
type Err = strum::ParseError;
#[inline]
fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(match s {
"input_voltage" => Self::Voltage(VoltageVariable::InputVoltage),
"output_voltage" => Self::Voltage(VoltageVariable::OutputVoltage),
"input_noise_height" => Self::Voltage(VoltageVariable::InputNoiseHeight),
"input_transition_time" => Self::Time(TimeVariable::InputTransitionTime),
"input_net_transition" => Self::Time(TimeVariable::InputNetTransition),
"constrained_pin_transition" => Self::Time(TimeVariable::ConstrainedPinTransition),
"related_pin_transition" => Self::Time(TimeVariable::RelatedPinTransition),
"driver_slew" => Self::Time(TimeVariable::DriverSlew),
"output_transition" => Self::Time(TimeVariable::OutputTransition),
"output_pin_transition" => Self::Time(TimeVariable::OutputPinTransition),
"connect_delay" => Self::Time(TimeVariable::ConnectDelay),
"input_noise_width" => Self::Time(TimeVariable::InputNoiseWidth),
"time" => Self::Time(TimeVariable::Time),
"total_output_net_capacitance" => {
Self::Capacitance(CapacitanceVariable::TotalOutputNetCapacitance)
}
"output_net_wire_cap" => Self::Capacitance(CapacitanceVariable::OutputNetWireCap),
"output_net_pin_cap" => Self::Capacitance(CapacitanceVariable::OutputNetPinCap),
"related_out_total_output_net_capaci" => {
Self::Capacitance(CapacitanceVariable::RelatedOutTotalOutputNetCapacitance)
}
"related_out_output_net_wire_cap" => {
Self::Capacitance(CapacitanceVariable::RelatedOutOutputNetWireCap)
}
"related_out_output_net_pin_cap" => {
Self::Capacitance(CapacitanceVariable::RelatedOutOutputNetPinCap)
}
"fanout_pin_capacitance" => {
Self::Capacitance(CapacitanceVariable::FanoutPinCapacitance)
}
"output_net_length" => Self::Length(LengthVariable::OutputNetLength),
"related_out_output_net_length" => {
Self::Length(LengthVariable::RelatedOutOutputNetLength)
}
"fanout_number" => Self::Scalar(ScalarVariable::FanoutNumber),
"normalized_voltage" => Self::Scalar(ScalarVariable::NormalizedVoltage),
"rc_product" => Self::RcProduct,
_ => {
return Err(strum::ParseError::VariantNotFound);
}
})
}
}
impl core::fmt::Display for Variable {
#[inline]
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Time(v) => v.fmt(f),
Self::Voltage(v) => v.fmt(f),
Self::Capacitance(v) => v.fmt(f),
Self::Length(v) => v.fmt(f),
Self::Scalar(v) => v.fmt(f),
Self::RcProduct => write!(f, "rc_product"),
}
}
}
#[derive(Debug, Clone, Copy)]
#[derive(Hash, PartialEq, Eq)]
#[derive(Ord, PartialOrd)]
#[derive(strum_macros::EnumString, strum_macros::EnumIter, strum_macros::Display)]
#[derive(serde::Serialize, serde::Deserialize)]
pub enum TimeVariable {
#[strum(serialize = "input_transition_time")]
InputTransitionTime,
#[strum(serialize = "input_net_transition")]
InputNetTransition,
#[strum(serialize = "constrained_pin_transition")]
ConstrainedPinTransition,
#[strum(serialize = "related_pin_transition")]
RelatedPinTransition,
#[strum(serialize = "driver_slew")]
DriverSlew,
#[strum(serialize = "output_transition")]
OutputTransition,
#[strum(serialize = "output_pin_transition")]
OutputPinTransition,
#[strum(serialize = "connect_delay")]
ConnectDelay,
#[strum(serialize = "input_noise_width")]
InputNoiseWidth,
#[strum(serialize = "time")]
Time,
}
#[derive(Debug, Clone, Copy)]
#[derive(Hash, PartialEq, Eq)]
#[derive(Ord, PartialOrd)]
#[derive(strum_macros::EnumString, strum_macros::EnumIter, strum_macros::Display)]
#[derive(serde::Serialize, serde::Deserialize)]
pub enum VoltageVariable {
#[strum(serialize = "input_voltage")]
InputVoltage,
#[strum(serialize = "output_voltage")]
OutputVoltage,
#[strum(serialize = "input_noise_height")]
InputNoiseHeight,
}
#[derive(Debug, Clone, Copy)]
#[derive(Hash, PartialEq, Eq)]
#[derive(Ord, PartialOrd)]
#[derive(strum_macros::EnumString, strum_macros::EnumIter, strum_macros::Display)]
#[derive(serde::Serialize, serde::Deserialize)]
pub enum CapacitanceVariable {
#[strum(serialize = "total_output_net_capacitance")]
TotalOutputNetCapacitance,
#[strum(serialize = "output_net_wire_cap")]
OutputNetWireCap,
#[strum(serialize = "output_net_pin_cap")]
OutputNetPinCap,
#[strum(serialize = "related_out_total_output_net_capaci")]
RelatedOutTotalOutputNetCapacitance,
#[strum(serialize = "related_out_output_net_wire_cap")]
RelatedOutOutputNetWireCap,
#[strum(serialize = "related_out_output_net_pin_cap")]
RelatedOutOutputNetPinCap,
#[strum(serialize = "fanout_pin_capacitance")]
FanoutPinCapacitance,
}
#[derive(Debug, Clone, Copy)]
#[derive(Hash, PartialEq, Eq)]
#[derive(Ord, PartialOrd)]
#[derive(strum_macros::EnumString, strum_macros::EnumIter, strum_macros::Display)]
#[derive(serde::Serialize, serde::Deserialize)]
pub enum LengthVariable {
#[strum(serialize = "output_net_length")]
OutputNetLength,
#[strum(serialize = "related_out_output_net_length")]
RelatedOutOutputNetLength,
}
#[derive(Debug, Clone, Copy)]
#[derive(Hash, PartialEq, Eq)]
#[derive(Ord, PartialOrd)]
#[derive(strum_macros::EnumString, strum_macros::EnumIter, strum_macros::Display)]
#[derive(serde::Serialize, serde::Deserialize)]
pub enum ScalarVariable {
#[strum(serialize = "fanout_number")]
FanoutNumber,
#[strum(serialize = "normalized_voltage")]
NormalizedVoltage,
}