use crate::{
ast::{
AttributeList, ComplexAttri, ComplexParseError, GroupComments, GroupFn, SimpleAttri,
},
ArcStr, GroupSet,
};
#[derive(Debug, Clone, Default)]
#[derive(liberty_macros::Group)]
#[mut_set_derive::item(
sort,
macro(derive(Debug, Clone,Default);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct Sensitization {
#[id]
#[liberty(name)]
pub name: ArcStr,
#[liberty(comments)]
pub comments: GroupComments<Self>,
#[liberty(undefined)]
pub undefined: AttributeList,
pub pin_names: Vec<ArcStr>,
#[liberty(complex)]
pub vector: (usize, ArcStr),
}
impl GroupFn for Sensitization {}
#[derive(Debug, Clone, Default)]
#[mut_set_derive::item(
sort,
macro(derive(Debug, Clone,Default);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct VoltageMap {
#[id]
pub name: ArcStr,
pub voltage: f64,
}
impl ComplexAttri for VoltageMap {
#[inline]
fn parse(v: Vec<&str>) -> Result<Self, ComplexParseError> {
let mut i = v.into_iter();
let name = match i.next() {
Some(s) => ArcStr::from(s),
None => return Err(ComplexParseError::LengthDismatch),
};
let voltage = match i.next() {
Some(s) => match s.parse() {
Ok(f) => f,
Err(e) => {
return Err(ComplexParseError::Float(
ordered_float::ParseNotNanError::ParseFloatError(e),
))
}
},
None => return Err(ComplexParseError::LengthDismatch),
};
if let Some(_) = i.next() {
return Err(ComplexParseError::LengthDismatch);
}
Ok(Self { name, voltage })
}
#[inline]
fn to_wrapper(&self) -> crate::ast::ComplexWrapper {
let mut buffer = ryu::Buffer::new();
vec![vec![self.name.clone(), ArcStr::from(buffer.format(self.voltage))]]
}
}
#[derive(Debug, Clone, Default)]
#[derive(liberty_macros::Group)]
#[mut_set_derive::item(
sort,
macro(derive(Debug, Clone,Default);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct InputVoltage {
#[id]
#[liberty(name)]
pub name: ArcStr,
#[liberty(comments)]
pub comments: GroupComments<Self>,
#[liberty(undefined)]
pub undefined: AttributeList,
#[liberty(simple)]
pub vil: ArcStr,
#[liberty(simple)]
pub vih: ArcStr,
#[liberty(simple)]
pub vimin: ArcStr,
#[liberty(simple)]
pub vimax: ArcStr,
}
impl GroupFn for InputVoltage {}
#[derive(Debug, Clone, Default)]
#[derive(liberty_macros::Group)]
#[mut_set_derive::item(
sort,
macro(derive(Debug, Clone,Default);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct OutputVoltage {
#[id]
#[liberty(name)]
pub name: ArcStr,
#[liberty(comments)]
pub comments: GroupComments<Self>,
#[liberty(undefined)]
pub undefined: AttributeList,
#[liberty(simple)]
pub vol: ArcStr,
#[liberty(simple)]
pub voh: ArcStr,
#[liberty(simple)]
pub vomin: ArcStr,
#[liberty(simple)]
pub vomax: ArcStr,
}
impl GroupFn for OutputVoltage {}
#[derive(Debug, Clone, Copy)]
#[derive(Hash, PartialEq, Eq, Default)]
#[derive(Ord, PartialOrd)]
#[derive(strum_macros::EnumString, strum_macros::EnumIter, strum_macros::Display)]
#[derive(serde::Serialize, serde::Deserialize)]
pub enum DelayModel {
#[default]
#[strum(serialize = "table_lookup")]
TableLookup,
}
impl SimpleAttri for DelayModel {}
#[derive(Debug, Clone, derivative::Derivative)]
#[derivative(Default)]
#[derive(liberty_macros::Group)]
#[mut_set_derive::item(
sort,
macro(derive(Debug, Clone);
derive(derivative::Derivative);
derivative(Default);),
attr_filter(derivative;)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct OperatingConditions {
#[id]
#[liberty(name)]
pub name: ArcStr,
#[liberty(comments)]
pub comments: GroupComments<Self>,
#[liberty(undefined)]
pub undefined: AttributeList,
#[liberty(simple(type = Option))]
pub calc_mode: Option<ArcStr>,
#[liberty(simple(type = Option))]
pub parameteri: Option<f64>,
#[liberty(simple)]
pub process: f64,
#[liberty(simple(type = Option))]
pub process_label: Option<ArcStr>,
#[liberty(simple)]
pub temperature: f64,
#[liberty(simple(type = Option))]
pub tree_type: Option<TreeType>,
#[liberty(simple)]
#[derivative(Default(value = "5.0"))]
pub voltage: f64,
}
impl GroupFn for OperatingConditions {}
#[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 TreeType {
#[strum(serialize = "best_case_tree")]
BestCaseTree,
#[strum(serialize = "balanced_tree")]
BalancedTree,
#[strum(serialize = "worst_case_tree")]
WorstCaseTree,
}
impl SimpleAttri for TreeType {}
#[derive(Debug, Clone)]
#[mut_set_derive::item(
sort,
macro(derive(Debug, Clone);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct Define {
#[id]
pub attribute_name: ArcStr,
#[id]
pub group_name: ArcStr,
pub attribute_type: AttributeType,
}
#[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 AttributeType {
#[strum(serialize = "Boolean", serialize = "boolean")]
Boolean,
#[strum(serialize = "string")]
String,
#[strum(serialize = "integer")]
Integer,
#[strum(serialize = "float")]
Float,
}
impl ComplexAttri for Define {
#[inline]
fn parse(v: Vec<&str>) -> Result<Self, ComplexParseError> {
let mut i = v.into_iter();
let attribute_name = match i.next() {
Some(s) => ArcStr::from(s),
None => return Err(ComplexParseError::LengthDismatch),
};
let group_name = match i.next() {
Some(s) => ArcStr::from(s),
None => return Err(ComplexParseError::LengthDismatch),
};
let attribute_type = match i.next() {
Some(s) => match s.parse() {
Ok(f) => f,
Err(_) => return Err(ComplexParseError::UnsupportedWord),
},
None => return Err(ComplexParseError::LengthDismatch),
};
if let Some(_) = i.next() {
return Err(ComplexParseError::LengthDismatch);
}
Ok(Self { attribute_name, group_name, attribute_type })
}
#[inline]
fn to_wrapper(&self) -> crate::ast::ComplexWrapper {
vec![vec![
self.attribute_name.clone(),
self.group_name.clone(),
self.attribute_type.to_string().into(),
]]
}
}
#[derive(Debug, Clone)]
#[mut_set_derive::item(
sort,
macro(derive(Debug, Clone);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct DefineCellArea {
#[id]
pub area_name: ArcStr,
pub resource_type: ResourceType,
}
#[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 ResourceType {
#[strum(serialize = "pad_slots")]
PadSlots,
#[strum(serialize = "pad_input_driver_sites")]
PadInputDriverSites,
#[strum(serialize = "pad_output_driver_sites")]
PadOutputDriverSites,
#[strum(serialize = "pad_driver_sites")]
PadDriverSites,
}
impl ComplexAttri for DefineCellArea {
#[inline]
fn parse(v: Vec<&str>) -> Result<Self, ComplexParseError> {
let mut i = v.into_iter();
let area_name = match i.next() {
Some(s) => ArcStr::from(s),
None => return Err(ComplexParseError::LengthDismatch),
};
let resource_type = match i.next() {
Some(s) => match s.parse() {
Ok(f) => f,
Err(_) => return Err(ComplexParseError::UnsupportedWord),
},
None => return Err(ComplexParseError::LengthDismatch),
};
if let Some(_) = i.next() {
return Err(ComplexParseError::LengthDismatch);
}
Ok(Self { area_name, resource_type })
}
#[inline]
fn to_wrapper(&self) -> crate::ast::ComplexWrapper {
vec![vec![self.area_name.clone(), self.resource_type.to_string().into()]]
}
}
#[derive(Debug, Clone)]
#[mut_set_derive::item(
sort,
macro(derive(Debug, Clone);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct DefineGroup {
#[id]
pub group: ArcStr,
#[id]
pub parent_name: ArcStr,
}
impl ComplexAttri for DefineGroup {
#[inline]
fn parse(v: Vec<&str>) -> Result<Self, ComplexParseError> {
let mut i = v.into_iter();
let group = match i.next() {
Some(s) => ArcStr::from(s),
None => return Err(ComplexParseError::LengthDismatch),
};
let parent_name = match i.next() {
Some(s) => ArcStr::from(s),
None => return Err(ComplexParseError::LengthDismatch),
};
if let Some(_) = i.next() {
return Err(ComplexParseError::LengthDismatch);
}
Ok(Self { group, parent_name })
}
#[inline]
fn to_wrapper(&self) -> crate::ast::ComplexWrapper {
vec![vec![self.group.clone(), self.parent_name.clone()]]
}
}
#[derive(Debug, Clone, Default)]
#[derive(liberty_macros::Group)]
#[mut_set_derive::item(
sort,
macro(derive(Debug, Clone,Default);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct WireLoad {
#[id]
#[liberty(name)]
pub name: ArcStr,
#[liberty(comments)]
pub comments: GroupComments<Self>,
#[liberty(undefined)]
pub undefined: AttributeList,
#[liberty(simple)]
pub area: f64,
#[liberty(simple)]
pub capacitance: f64,
#[liberty(simple)]
pub resistance: f64,
#[liberty(simple)]
pub slope: f64,
#[liberty(complex(type = Set))]
pub fanout_length: GroupSet<FanoutLength>,
}
impl GroupFn for WireLoad {}
#[derive(Debug, Clone, Default, Copy)]
#[mut_set_derive::item(
sort,
macro(derive(Debug, Clone, Default, Copy);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct FanoutLength {
#[id]
pub fanout: u32,
pub length: f64,
pub average_capacitance: Option<f64>,
pub standard_deviation: Option<f64>,
pub number_of_nets: Option<u32>,
}
impl ComplexAttri for FanoutLength {
#[inline]
fn parse(v: Vec<&str>) -> Result<Self, ComplexParseError> {
let mut i = v.into_iter();
let fanout = match i.next() {
Some(s) => match s.parse() {
Ok(f) => f,
Err(e) => return Err(ComplexParseError::Int(e)),
},
None => return Err(ComplexParseError::LengthDismatch),
};
let length = match i.next() {
Some(s) => match s.parse() {
Ok(f) => f,
Err(e) => {
return Err(ComplexParseError::Float(
ordered_float::ParseNotNanError::ParseFloatError(e),
))
}
},
None => return Err(ComplexParseError::LengthDismatch),
};
let average_capacitance = i.next().and_then(|s| match s.parse() {
Ok(f) => Some(f),
Err(_) => None,
});
let standard_deviation = i.next().and_then(|s| match s.parse() {
Ok(f) => Some(f),
Err(_) => None,
});
let number_of_nets = i.next().and_then(|s| match s.parse() {
Ok(f) => Some(f),
Err(_) => None,
});
if let Some(_) = i.next() {
return Err(ComplexParseError::LengthDismatch);
}
Ok(Self {
fanout,
length,
average_capacitance,
standard_deviation,
number_of_nets,
})
}
#[inline]
fn to_wrapper(&self) -> crate::ast::ComplexWrapper {
let mut buffer_f = ryu::Buffer::new();
let mut buffer_i = itoa::Buffer::new();
match (self.average_capacitance, self.standard_deviation, self.number_of_nets) {
(Some(average_capacitance), Some(standard_deviation), Some(number_of_nets)) => {
vec![vec![
ArcStr::from(buffer_i.format(self.fanout)),
ArcStr::from(buffer_f.format(self.length)),
ArcStr::from(buffer_f.format(average_capacitance)),
ArcStr::from(buffer_f.format(standard_deviation)),
ArcStr::from(buffer_i.format(number_of_nets)),
]]
}
_ => {
vec![vec![
ArcStr::from(buffer_i.format(self.fanout)),
ArcStr::from(buffer_f.format(self.length)),
]]
}
}
}
}
#[derive(Debug, Clone, Default)]
#[derive(liberty_macros::Group)]
#[mut_set_derive::item(
sort,
macro(derive(Debug, Clone,Default);)
)]
#[derive(serde::Serialize, serde::Deserialize)]
pub struct WireLoadSection {
#[id]
#[liberty(name)]
pub name: ArcStr,
#[liberty(comments)]
pub comments: GroupComments<Self>,
#[liberty(undefined)]
pub undefined: AttributeList,
#[liberty(complex)]
pub wire_load_from_area: (f64, f64, ArcStr),
}
impl GroupFn for WireLoadSection {}