1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//! <script>
//! IFRAME('https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html');
//! </script>
mod items;
pub use items::*;
use crate::{
ast::{AttributeList, GroupComments},
cell::Cell,
units, GroupSet,
};
use std::collections::HashMap;
use std::fmt::{Display, Write};
#[derive(Debug, Clone, derivative::Derivative)]
#[derivative(Default)]
#[derive(liberty_macros::Group)]
#[mut_set_derive::item(
macro(derive(Debug, Clone);
derive(derivative::Derivative);
derivative(Default);),
attr_filter(derivative;)
)]
pub struct Library {
#[id]
#[liberty(name)]
pub name: String,
#[liberty(comments)]
_comments: GroupComments<Self>,
#[liberty(undefined)]
_undefined: AttributeList,
/// Valid values are 1ps, 10ps, 100ps, and 1ns. The default is 1ns.
/// <a name ="reference_link" href="
/// https://zao111222333.github.io/liberty-db/2020.09/user_guide.html?field=null&bgn=42.25&end=42.30
/// ">Reference</a>
#[liberty(simple)]
pub time_unit: units::TimeUnit,
/// This attribute specifies the unit for all capacitance
/// values within the logic library, including
/// default capacitances, max_fanout capacitances,
/// pin capacitances, and wire capacitances.
/// <a name ="reference_link" href="
/// https://zao111222333.github.io/liberty-db/2020.09/user_guide.html?field=null&bgn=44.7&end=44.19
/// ">Reference</a>
#[liberty(complex(type = Option))]
pub capacitive_load_unit: Option<units::CapacitiveLoadUnit>,
/// Valid values are 1mV, 10mV, 100mV, and 1V. The default is 1V.
/// <a name ="reference_link" href="
/// https://zao111222333.github.io/liberty-db/2020.09/user_guide.html?field=null&bgn=43.2&end=43.9
/// ">Reference</a>
#[liberty(simple)]
pub voltage_unit: units::VoltageUnit,
/// The valid values are 1uA, 10uA, 100uA, 1mA, 10mA, 100mA, and 1A.
/// **No default exists for the `current_unit` attribute if the attribute is omitted.**
/// <a name ="reference_link" href="
/// https://zao111222333.github.io/liberty-db/2020.09/user_guide.html?field=null&bgn=43.12&end=43.24
/// ">Reference</a>
#[liberty(simple(type = Option))]
pub current_unit: Option<units::CurrentUnit>,
/// Valid unit values are 1ohm, 10ohm, 100ohm, and 1kohm.
/// **No default exists for `pulling_resistance_unit` if the attribute is omitted.**
/// <a name ="reference_link" href="
/// https://zao111222333.github.io/liberty-db/2020.09/user_guide.html?field=null&bgn=43.25&end=44.4
/// ">Reference</a>
#[liberty(simple(type = Option))]
pub pulling_resistance_unit: Option<units::PullingResistanceUnit>,
/// This attribute indicates the units of the power values
/// in the library. If this attribute is missing, the
/// leakage-power values are expressed without units.
/// Valid values are 1W, 100mW, 10mW, 1mW, 100nW, 10nW, 1nW, 100pW, 10pW, and 1pW.
/// <a name ="reference_link" href="
/// https://zao111222333.github.io/liberty-db/2020.09/user_guide.html?field=null&bgn=44.22&end=44.31
/// ">Reference</a>
#[liberty(simple(type = Option))]
pub leakage_power_unit: Option<units::LeakagePowerUnit>,
#[liberty(simple)]
#[derivative(Default(value = "80.0"))]
pub slew_upper_threshold_pct_rise: f64,
#[liberty(group(type = Set))]
pub cell: GroupSet<Cell>,
pub voltage_map: HashMap<String, f64>,
pub sensitization_map: HashMap<String, Sensitization>,
}
impl Display for Library {
/// ```
/// use liberty_db::library::Library;
/// use std::{
/// fs::{self, File},
/// io::{BufWriter, Write},
/// path::Path};
/// let library = Library::default();
/// let mut writer = BufWriter::new(File::create(Path::new("out.lib"))?);
/// write!(&mut writer, "{}", library)?;
/// ```
/// Format [Library] struct as `.lib` file
#[inline]
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
let ff = &mut crate::ast::CodeFormatter::new(f, " ");
<AttriComment as Format>::liberty(self.comment(), "", ff)?;
self.fmt_liberty("library", ff)
}
}
use crate::ast::parser;
use crate::ast::{AttriComment, Format, GroupAttri, ParserError};
impl Library {
// /// Format [Library] struct as `.lib` file
// #[inline]
// pub fn fmt<T: Write>(&self, w: &mut T) -> std::fmt::Result {
// let f = &mut crate::ast::CodeFormatter::new(w, " ");
// <AttriComment as Format>::liberty(self.comment(), "", f)?;
// self.fmt_liberty("library", f)
// }
/// Parse `.lib` file as a [Library] struct.
#[inline]
pub fn parse<'a>(i: &'a str) -> Result<Self, ParserError<'a>> {
let mut line_num = 1;
let input = match parser::comment_space_newline(i) {
Ok((input, n)) => {
line_num += n;
input
}
Err(e) => return Err(ParserError::NomError(line_num, e)),
};
let (input, key) = match parser::key::<nom::error::Error<&str>>(input) {
Ok(res) => res,
Err(e) => return Err(ParserError::NomError(line_num, e)),
};
if key == "library" {
match <Self as GroupAttri>::nom_parse(input, &mut line_num) {
Err(e) => return Err(ParserError::NomError(line_num, e)),
Ok((_, Err(e))) => return Err(ParserError::IdError(line_num, e)),
Ok((_, Ok(l))) => return Ok(l),
}
} else {
Err(ParserError::Other(line_num, format!("Need key=library, find={}", key)))
}
}
}