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}