liberty_db/ccsn.rs
1//! <script>
2//! IFRAME('https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html');
3//! </script>
4
5use crate::{
6 Ctx,
7 ast::{
8 Attributes, BuilderScope, CodeFormatter, ComplexAttri, ComplexParseError,
9 GroupComments, GroupFn, Indentation, LibertySet, ParseScope,
10 },
11 expression::LogicBooleanExpression,
12 table::{
13 DcCurrent, TableLookUp, TableLookUpMultiSegment, Vector3DGrpup, Vector4DGrpup,
14 },
15};
16use core::fmt::{self, Write};
17
18/// Use the `ccsn_first_stage` group to specify CCS noise for the first stage of the channel-
19/// connected block (CCB).
20///
21/// A `ccsn_first_stage` or `ccsn_last_stage` group contains the following information:
22/// • A set of channel-connected block parameters: the `is_needed`, `is_inverting`,
23/// `stage_type`, `miller_cap_rise`, `miller_cap_fall`, and optional `related_ccb_node`
24/// attributes
25/// • The optional `when` and `mode` attributes for conditional data modeling
26/// • The optional `output_signal_level` or `input_signal_level` attribute to model CCS
27/// noise stages of channel-connected blocks with internal power supplies
28/// • A two-dimensional DC current table: `dc_current` group
29/// • Two timing tables for rising and falling transitions: `output_current_rise` group,
30/// `output_current_fall` group
31/// • Two noise tables for low and high propagated noise: `propagated_noise_low` group,
32/// `propagated_noise_high` group
33/// Note that if the `ccsn_first_stage` and `ccsn_last_stage` groups are defined inside pin-
34/// level groups, then the `ccsn_first_stage` group can only be defined in an input pin or an
35/// inout pin, and the `ccsn_last_stage` group can only be defined in an output pin or an inout
36/// pin.
37/// <a name ="reference_link" href="
38/// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=283.21&end=283.43
39/// ">Reference-Definition</a>
40/// <script>
41/// IFRAME('https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html');
42/// </script>
43#[derive(Debug, Clone)]
44#[derive(liberty_macros::Group)]
45#[mut_set::derive::item]
46#[derive(serde::Serialize, serde::Deserialize)]
47#[serde(bound = "C::Other: serde::Serialize + serde::de::DeserializeOwned")]
48pub struct CCSNStage<C: 'static + Ctx> {
49 /// group name
50 #[liberty(name)]
51 #[id(borrow = [String])]
52 pub name: Vec<String>,
53 /// group comments
54 #[liberty(comments)]
55 comments: GroupComments,
56 #[liberty(extra_ctx)]
57 pub extra_ctx: C::Other,
58 /// group undefined attributes
59 #[liberty(attributes)]
60 pub attributes: Attributes,
61 #[liberty(simple)]
62 pub load_cap_fall: Option<f64>,
63 #[liberty(simple)]
64 pub load_cap_rise: Option<f64>,
65 /// Use the `is_inverting` attribute to specify whether the channel-connecting block is inverting.
66 /// This attribute is mandatory if the `is_needed` attribute value is true.
67 /// If the channel-connecting block is inverting, set the attribute to true.
68 /// Otherwise, set the attribute to false.
69 /// This attribute is different from the timing sense of a timing arc,
70 /// which might consist of multiple channel-connecting blocks.
71 /// <a name ="reference_link" href="
72 /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=285.31&end=285.36
73 /// ">Reference-Definition</a>
74 #[liberty(simple)]
75 pub is_inverting: Option<bool>,
76 /// Use the `is_needed` attribute to specify
77 /// whether composite current source (CCS) noise modeling data is required.
78 /// <a name ="reference_link" href="
79 /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=286.5&end=286.6
80 /// ">Reference-Definition</a>
81 #[liberty(simple)]
82 pub is_needed: Option<bool>,
83 /// The `is_pass_gate` attribute is defined in a ccsn_*_stage group,
84 /// such as the `ccsn_first_stage` group,
85 /// to indicate that the ccsn_*_stage information is modeled as a pass gate.
86 /// The attribute is optional and the default is false.
87 /// <a name ="reference_link" href="
88 /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=286.17&end=286.19
89 /// ">Reference-Definition</a>
90 #[liberty(simple)]
91 pub is_pass_gate: Option<bool>,
92 /// Use the `miller_cap_fall` attribute to specify the Miller capacitance value for the channel-connecting block.
93 /// A floating-point number representing the Miller capacitance value. The value must be greater or equal to zero.
94 /// <a name ="reference_link" href="
95 /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=286.25&end=286.26
96 /// ">Reference-Definition</a>
97 #[liberty(simple)]
98 pub miller_cap_fall: Option<f64>,
99 /// Use the `miller_cap_rise` attribute to specify the Miller capacitance value for the channel-connecting block.
100 /// A floating-point number representing the Miller capacitance value. The value must be greater or equal to zero.
101 /// <a name ="reference_link" href="
102 /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=287.3&end=287.11
103 /// ">Reference-Definition</a>
104 #[liberty(simple)]
105 pub miller_cap_rise: Option<f64>,
106 /// The optional `related_ccb_node` attribute specifies the SPICE node
107 /// in the subcircuit netlist that is used for the `dc_current`
108 /// table characterization and waveform measurements.
109 /// <a name ="reference_link" href="
110 /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=287.15&end=287.17
111 /// ">Reference-Definition</a>
112 #[liberty(simple)]
113 #[id]
114 pub related_ccb_node: Option<String>,
115 /// Use the `stage_type` attribute to specify the stage type of the channel-connecting block output voltage.
116 ///
117 /// The valid values are `pull_up`,in which the output voltage of the channel-connecting block is always pulled up (rising);
118 /// `pull_down`, in which the output voltage of the channel-connecting block is always pulled down (falling);
119 /// and `both`, in which the output voltage of the channel-connecting block is pulled up or down.
120 /// <a name ="reference_link" href="
121 /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=287.27+288.2&end=287.36+288.5
122 /// ">Reference-Definition</a>
123 #[liberty(simple)]
124 pub stage_type: Option<StageType>,
125 #[liberty(simple)]
126 #[id]
127 pub when: Option<LogicBooleanExpression>,
128 /// The pin-based mode attribute is provided in the `ccsn_first_stage`
129 /// and `ccsn_last_stage` groups for conditional data modeling.
130 /// If the `mode` attribute is specified, `mode_name` and `mode_value` must be
131 /// predefined in the `mode_definition` group at the cell level.
132 /// <a name ="reference_link" href="
133 /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=287.23&end=287.25
134 /// ">Reference-Definition</a>
135 #[liberty(complex)]
136 pub mode: Option<[String; 2]>,
137 /// Use the `dc_current` group to specify the input and output voltage values
138 /// of a two-dimensional current table for a channel-connecting block.
139 ///
140 /// Use `index_1` to represent the input voltage
141 /// and `index_2` to represent the output voltage.
142 /// The `values` attribute of the group lists the relative
143 /// channel-connecting block DC current values in library units measured
144 /// at the channel-connecting block output node.
145 /// <a name ="reference_link" href="
146 /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=289.2+288.24&end=289.4+288.25
147 /// ">Reference-Definition</a>
148 #[liberty(group)]
149 #[liberty(after_build = DcCurrent::use_common_template)]
150 pub dc_current: Option<DcCurrent<C>>,
151 /// Use the `output_voltage_fall` group to specify vector groups that describe
152 /// three-dimensional `output_voltage` tables of the channel-connecting block
153 /// whose output node’s voltage values are falling.
154 ///
155 /// + The `index_1` attribute lists the `input_net_transition` (slew) values in library time units.
156 /// + The `index_2` attribute lists the `total_output_net_capacitance` (load) values in library capacitance units.
157 /// + The `index_3` attribute lists the sampling time values in library time units.
158 /// + The `values` attribute lists the voltage values, in library voltage units,
159 /// that are measured at the channel-connecting block output node.
160 /// <a name ="reference_link" href="
161 /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=289.6&end=289.26
162 /// ">Reference-Definition</a>
163 #[liberty(group)]
164 pub output_voltage_fall: Option<Vector3DGrpup<C>>,
165 /// Use the `output_voltage_rise` group to specify `vector` groups that describe
166 /// three-dimensional `output_voltage` tables of the channel-connecting block
167 /// whose output node’s voltage values are rising.
168 /// For details, see the `output_voltage_fall` group description.
169 ///
170 /// <a name ="reference_link" href="
171 /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=289.28&end=289.30
172 /// ">Reference-Definition</a>
173 #[liberty(group)]
174 pub output_voltage_rise: Option<Vector3DGrpup<C>>,
175 /// The `propagated_noise_low` group uses `vector` groups to specify the
176 /// three-dimensional `output_voltage` tables of the channel-connecting block
177 /// whose output node’s voltage values are falling.
178 /// Specify the following attributes in the `vector` group:
179 ///
180 /// + The `index_1` attribute lists the `input_noise_height` values in library voltage units.
181 /// + The `index_2` attribute lists the `input_noise_width` values in library time units.
182 /// + The `index_3` attribute lists the `total_output_net_capacitance` values in library capacitance units.
183 /// + The `index_4` attribute lists the sampling time values in library time units.
184 /// + The `values` attribute lists the voltage values, in library voltage units, that are measured at the channel-connecting block output node.
185 /// <a name ="reference_link" href="
186 /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=290.19&end=290.20
187 /// ">Reference-Definition</a>
188 #[liberty(group)]
189 pub propagated_noise_low: Option<Vector4DGrpup<C>>,
190 /// The `propagated_noise_high` group uses `vector` groups to specify the
191 /// three-dimensional `output_voltage` tables of the channel-connecting block
192 /// whose output node’s voltage values are rising.
193 /// Specify the following attributes in the `vector` group:
194 ///
195 /// + The `index_1` attribute lists the `input_noise_height` values in library voltage units.
196 /// + The `index_2` attribute lists the `input_noise_width` values in library time units.
197 /// + The `index_3` attribute lists the `total_output_net_capacitance` values in library capacitance units.
198 /// + The `index_4` attribute lists the sampling time values in library time units.
199 /// + The `values` attribute lists the voltage values, in library voltage units, that are measured at the channel-connecting block output node.
200 /// <a name ="reference_link" href="
201 /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=289.33&end=289.35
202 /// ">Reference-Definition</a>
203 #[liberty(group)]
204 pub propagated_noise_high: Option<Vector4DGrpup<C>>,
205}
206
207impl<C: 'static + Ctx> GroupFn<C> for CCSNStage<C> {
208 #[inline]
209 fn before_build(builder: &mut Self::Builder, _scope: &mut BuilderScope<C>) {
210 if let Some(miller_cap_fall) = builder.miller_cap_fall.as_mut()
211 && miller_cap_fall.is_sign_negative()
212 {
213 *miller_cap_fall = 0.0;
214 crate::warn!("miller_cap_fall is negative!");
215 }
216 if let Some(miller_cap_rise) = builder.miller_cap_rise.as_mut()
217 && miller_cap_rise.is_sign_negative()
218 {
219 *miller_cap_rise = 0.0;
220 crate::warn!("miller_cap_rise is negative!");
221 }
222 }
223}
224
225/// Use the `stage_type` attribute to specify the stage type of the channel-connecting block output voltage.
226///
227/// The valid values are `pull_up`,in which the output voltage of the channel-connecting block is always pulled up (rising);
228/// `pull_down`, in which the output voltage of the channel-connecting block is always pulled down (falling);
229/// and `both`, in which the output voltage of the channel-connecting block is pulled up or down.
230/// <a name ="reference_link" href="
231/// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=287.27+288.2&end=287.36+288.5
232/// ">Reference-Definition</a>
233#[derive(Debug, Clone, Copy)]
234#[derive(Hash, PartialEq, Eq)]
235#[derive(Ord, PartialOrd, Default)]
236#[derive(strum::EnumString, strum::EnumIter, strum::Display)]
237#[derive(serde::Serialize, serde::Deserialize)]
238pub enum StageType {
239 /// `pull_up`, in which the output voltage of the channel-connecting block is always pulled up (rising);
240 #[strum(serialize = "pull_up")]
241 PullUp,
242 /// in which the output voltage of the channel-connecting block is always pulled down (falling)
243 #[strum(serialize = "pull_down")]
244 PullDown,
245 /// both, in which the output voltage of the channel-connecting block is pulled up or down
246 #[strum(serialize = "both")]
247 #[default]
248 Both,
249}
250crate::ast::impl_self_builder!(StageType);
251crate::ast::impl_simple!(StageType);
252
253/// Use the `receiver_capacitance` group to specify capacitance values
254/// for composite current source (CCS) receiver modeling at the pin level.
255///
256/// Groups
257///
258/// For two-segment receiver capacitance model
259/// + `receiver_capacitance1_fall`
260/// + `receiver_capacitance1_rise`
261/// + `receiver_capacitance2_fall`
262/// + `receiver_capacitance2_rise`
263///
264/// For multisegment receiver capacitance model
265/// + `receiver_capacitance_fall`
266/// + `receiver_capacitance_rise`
267/// <a name ="reference_link" href="
268/// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=316.5&end=316.31
269/// ">Reference-Definition</a>
270/// <script>
271/// IFRAME('https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html');
272/// </script>
273#[derive(Debug, Clone)]
274#[derive(liberty_macros::Group)]
275#[mut_set::derive::item]
276#[derive(serde::Serialize, serde::Deserialize)]
277#[serde(bound = "C::Other: serde::Serialize + serde::de::DeserializeOwned")]
278pub struct ReceiverCapacitance<C: 'static + Ctx> {
279 /// group name
280 #[liberty(name)]
281 #[id]
282 pub name: Option<String>,
283 /// group comments
284 #[liberty(comments)]
285 comments: GroupComments,
286 #[liberty(extra_ctx)]
287 pub extra_ctx: C::Other,
288 /// group undefined attributes
289 #[liberty(attributes)]
290 pub attributes: Attributes,
291 #[liberty(simple)]
292 #[id]
293 pub when: Option<LogicBooleanExpression>,
294 #[liberty(group)]
295 #[liberty(after_build = TableLookUpMultiSegment::use_common_template)]
296 pub receiver_capacitance_fall: LibertySet<TableLookUpMultiSegment<C>>,
297 #[liberty(group)]
298 #[liberty(after_build = TableLookUpMultiSegment::use_common_template)]
299 pub receiver_capacitance_rise: LibertySet<TableLookUpMultiSegment<C>>,
300 /// In referenced CCS noise modeling, the `active_input_ccb` attribute lists the active or
301 /// switching `input_ccb` groups of the input pin that do not propagate the noise in the timing
302 /// arc or the receiver capacitance load.
303 /// You can also specify this attribute in the `receiver_capacitance` group of the input pin.
304 ///
305 /// ### Syntax
306 /// ``` text
307 /// active_input_ccb(input_ccb_name1[ , input_ccb_name2, ...]);
308 /// ```
309 /// ### Example
310 /// ``` text
311 /// active_input_ccb("A", "B");
312 /// ```
313 /// <a name ="reference_link" href="
314 /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=339.2&end=339.6
315 /// ">Reference-Instance</a>
316 #[liberty(complex)]
317 pub active_input_ccb: Vec<String>,
318 #[liberty(group)]
319 #[liberty(after_build = TableLookUp::use_common_template)]
320 pub receiver_capacitance1_fall: Option<TableLookUp<C>>,
321 #[liberty(group)]
322 #[liberty(after_build = TableLookUp::use_common_template)]
323 pub receiver_capacitance1_rise: Option<TableLookUp<C>>,
324 #[liberty(group)]
325 #[liberty(after_build = TableLookUp::use_common_template)]
326 pub receiver_capacitance2_fall: Option<TableLookUp<C>>,
327 #[liberty(group)]
328 #[liberty(after_build = TableLookUp::use_common_template)]
329 pub receiver_capacitance2_rise: Option<TableLookUp<C>>,
330}
331impl<C: 'static + Ctx> GroupFn<C> for ReceiverCapacitance<C> {}
332
333/// The `propagating_ccb` attribute lists all the channel-connected block noise groups that propagate
334/// the noise to the output pin in a particular timing arc.
335///
336/// In the list, the first name is the `input_ccb` group of the input pin (specified by the `related_pin` attribute in the timing group).
337/// The second name, **if present**, is for the `output_ccb` group of the output pin
338/// <a name ="reference_link" href="
339/// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=339.33+340.2&end=339.34+340.4
340/// ">Reference</a>
341#[derive(Debug, Clone)]
342#[derive(serde::Serialize, serde::Deserialize)]
343pub struct PropagatingCcb {
344 /// `input_ccb_name`
345 pub input_ccb_name: String,
346 /// `output_ccb_name`
347 pub output_ccb_name: Option<String>,
348}
349crate::ast::impl_self_builder!(PropagatingCcb);
350impl<C: 'static + Ctx> ComplexAttri<C> for PropagatingCcb {
351 #[inline]
352 fn parse<'a, I: Iterator<Item = &'a &'a str>>(
353 mut iter: I,
354 _scope: &mut ParseScope<'_>,
355 ) -> Result<Self, ComplexParseError> {
356 let input_ccb_name = match iter.next() {
357 Some(&s) => String::from(s),
358 None => return Err(ComplexParseError::LengthDismatch),
359 };
360 let output_ccb_name = iter.next().map(|&s| String::from(s));
361 if iter.next().is_some() {
362 return Err(ComplexParseError::LengthDismatch);
363 }
364 Ok(Self { input_ccb_name, output_ccb_name })
365 }
366 #[expect(clippy::or_fun_call)]
367 #[inline]
368 fn fmt_self<T: Write, I: Indentation>(
369 &self,
370 f: &mut CodeFormatter<'_, T, I>,
371 ) -> fmt::Result {
372 self
373 .output_ccb_name
374 .as_ref()
375 .map_or(write!(f, "{}", self.input_ccb_name), |output_ccb_name| {
376 write!(f, "{}, {}", self.input_ccb_name, output_ccb_name)
377 })
378 }
379}