liberty_db/library/
mod.rs

1//! <script>
2//! IFRAME('https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html');
3//! </script>
4
5mod items;
6mod test;
7use crate::{
8  Ctx,
9  ast::{
10    Attributes, BuilderScope, DefaultIndentation, GroupAttri, GroupComments, GroupFn,
11    LibertySet, ParseLoc, ParseScope, ParserError, ParsingBuilder, parser,
12  },
13  cell::{Cell, Model, ScaledCell},
14  common::char_config::CharConfig,
15  pin::BusType,
16  table::{CompactLutTemplate, DriverWaveform, PolyTemplate, TableTemple},
17  units,
18};
19use alloc::borrow::Cow;
20use core::fmt::{self, Write as _};
21pub use items::*;
22use std::path::Path;
23
24/// The first line of the library group statement names the library.
25///
26/// It is the first executable line in your library.
27/// <a name ="reference_link" href="
28/// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=20.24&end=20.26
29/// ">Reference</a>
30/// <script>
31/// IFRAME('https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html');
32/// </script>
33#[derive(Debug, Clone)]
34#[derive(liberty_macros::Group)]
35#[mut_set::derive::item]
36#[derive(serde::Serialize, serde::Deserialize)]
37#[serde(bound = "C::Library: serde::Serialize + serde::de::DeserializeOwned")]
38pub struct Library<C: 'static + Ctx> {
39  /// library name
40  #[id(borrow = [String])]
41  #[liberty(name)]
42  #[liberty(default = vec![String::from("undefined")])]
43  pub name: Vec<String>,
44  /// group comments
45  #[liberty(comments)]
46  comments: GroupComments,
47  #[liberty(extra_ctx)]
48  pub extra_ctx: C::Library,
49  /// group undefined attributes
50  #[liberty(attributes)]
51  pub attributes: Attributes,
52  /// Use this attribute to define new, temporary, or user-defined attributes
53  /// for use in symbol and technology libraries.
54  /// You can use either a space or a comma to separate the arguments.
55  /// The following example shows how to define a new string attribute called `bork`,
56  /// which is valid in a `pin`  group:
57  ///
58  /// ### Example
59  /// ``` liberty
60  /// define ("bork", "pin", "string") ;
61  /// ```
62  /// You give the new library attribute a value by using the simple attribute syntax:
63  /// ``` liberty
64  /// bork : "nimo" ;
65  /// ```
66  /// <a name ="reference_link" href="
67  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=36.5&end=36.21
68  /// ">Reference</a>
69  #[liberty(complex)]
70  pub define: LibertySet<Define>,
71  /// The `technology`  attribute statement specifies the technology
72  /// family being used in the library.
73  /// When you define the technology  attribute,
74  /// it must be the first attribute you use and it must be placed at the top of the listing.
75  /// <a name ="reference_link" href="
76  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=39.3&end=39.5
77  /// ">Reference</a>
78  #[liberty(complex)]
79  pub technology: Option<Technology>,
80  /// Use the `delay_model`  attribute to specify which delay model
81  /// to use in the delay calculations.
82  /// The `delay_model`  attribute must be the first attribute in the library
83  /// if a technology attribute is not present.
84  /// Otherwise, it should follow the technology attribute.
85  /// <a name ="reference_link" href="
86  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=24.3&end=24.6
87  /// ">Reference</a>
88  #[liberty(simple)]
89  pub delay_model: DelayModel,
90  #[liberty(simple)]
91  pub power_model: DelayModel,
92  /// You can use any format within the quotation marks to report the date
93  /// <a name ="reference_link" href="
94  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=23.5&end=23.5
95  /// ">Reference</a>
96  #[liberty(simple)]
97  pub date: String,
98  /// You use the `comment`  attribute to include copyright
99  /// or other product information in the library report. You can include only one comment line in a library
100  /// <a name ="reference_link" href="
101  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=22.10&end=22.11
102  /// ">Reference</a>
103  #[liberty(simple)]
104  pub comment: Option<String>,
105  /// The optional `revision`  attribute defines a revision number for your library.
106  /// <a name ="reference_link" href="
107  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=30.17&end=30.18
108  /// ">Reference</a>
109  #[liberty(simple)]
110  pub revision: Option<String>,
111  /// Used in TSMC PDK
112  #[liberty(simple)]
113  pub simulation: Option<bool>,
114  /// The `bus_naming_style` attribute defines the naming convention for buses in the library.
115  ///
116  /// *Syntax*
117  /// ```text
118  /// bus_naming_style : "string";
119  /// ```
120  /// Contains alphanumeric characters, braces, underscores, dashes, or
121  /// parentheses. Must contain one `%s` symbol and one `%d` symbol. The `%s` and `%d`
122  /// symbols can appear in any order with at least one nonnumeric character in
123  /// between.
124  ///
125  /// The colon character is not allowed in a `bus_naming_style` attribute value
126  /// because the colon is used to denote a range of bus members. You construct a
127  /// complete bused-pin name by using the name of the owning bus and the member
128  /// number. The owning bus name is substituted for the `%s`, and the member
129  /// number replaces the `%d`.
130  ///
131  /// If you do not define the `bus_naming_style` attribute, the default naming convention is
132  /// applied, as shown.
133  ///
134  /// *Example*
135  /// ```text
136  /// bus_naming_style : "%s[%d]" ;
137  /// ```
138  /// <a name ="reference_link" href="
139  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=21.14&end=21.30
140  /// ">Reference</a>
141  #[liberty(simple)]
142  pub bus_naming_style: Option<String>,
143  /// The `nom_process`  attribute defines process scaling,
144  /// one of the nominal operating conditions for a library.
145  ///
146  /// A floating-point number that represents the degree of process scaling in the cells of the library.
147  /// <a name ="reference_link" href="
148  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=28.3+28.10&end=28.4+28.11
149  /// ">Reference</a>
150  #[liberty(simple)]
151  pub nom_process: Option<f64>,
152  /// The `nom_temperature`  attribute defines the temperature (in centigrade),
153  /// one of the nominal operating conditions for a library.
154  ///
155  /// A floating-point number that represents the temperature of the cells in the library
156  /// <a name ="reference_link" href="
157  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=28.15&end=28.22
158  /// ">Reference</a>
159  #[liberty(simple)]
160  pub nom_temperature: Option<f64>,
161  /// The `nom_voltage`  attribute defines voltage, one of the nominal operating conditions for a library.
162  /// <a name ="reference_link" href="
163  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=28.26&end=28.27
164  /// ">Reference</a>
165  #[liberty(simple)]
166  pub nom_voltage: Option<f64>,
167  /// The `receiver_capacitance_rise_threshold_pct` attribute specifies the points that
168  /// separate the voltage rise segments in the multi-segment receiver capacitance model.
169  ///
170  /// Specify the points as percentage of the rail voltage between 0.0 and 100.0.
171  ///
172  /// Specify monotonically increasing values with the
173  /// `receiver_capacitance_rise_threshold_pct` attribute.
174  ///
175  /// ### Syntax
176  /// ``` text
177  /// receiver_capacitance_rise_threshold_pct ("float, float,...");
178  /// ```
179  /// ### Example
180  /// ``` text
181  /// receiver_capacitance_rise_threshold_pct ("0, 30, 50, 60, 70, 80, 100");
182  /// ```
183  /// In this example, six segments are defined and the first segment is from zero percent to 30
184  /// percent of the rail voltage.
185  /// <a name ="reference_link" href="
186  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=38.18&end=38.28
187  /// ">Reference</a>
188  #[liberty(complex)]
189  pub receiver_capacitance_rise_threshold_pct: Vec<f64>,
190  /// The `receiver_capacitance_fall_threshold_pct` attribute specifies the points that
191  /// separate the voltage fall segments in the multi-segment receiver capacitance model.
192  ///
193  /// Specify each point as a percentage of the rail voltage between 0.0 and 100.0.
194  ///
195  /// Specify monotonically decreasing values with the
196  /// `receiver_capacitance_fall_threshold_pct` attribute.
197  ///
198  /// ### Syntax
199  /// ``` text
200  /// receiver_capacitance_fall_threshold_pct ("float, float,...");
201  /// ```
202  /// ### Example
203  /// ``` text
204  /// receiver_capacitance_fall_threshold_pct ("100, 80, 70, 60, 50, 30, 0");
205  /// ```
206  /// In this example, six segments are defined and the first segment is from 100 percent to 80
207  /// percent of the rail voltage.
208  /// <a name ="reference_link" href="
209  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=38.6&end=38.16
210  /// ">Reference</a>
211  #[liberty(complex)]
212  pub receiver_capacitance_fall_threshold_pct: Vec<f64>,
213  /// If your library contains bused pins, you must define type groups and define the structural
214  /// constraints of each bus type in the library. The type group is defined at the library group
215  /// level, as shown here:
216  /// <a name ="reference_link" href="
217  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=91.7+136.10&end=91.9+136.25
218  /// ">Reference</a>
219  /// <script>
220  /// IFRAME('https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html');
221  /// </script>
222  /// ``` text
223  /// Example 17 Bused Pins
224  /// library (ExamBus) {
225  ///   type (bus4) { /* bus name */
226  ///     bit_width : 4 ; /* number of bused pins */
227  ///     ...
228  ///     ...
229  ///   }
230  ///   cell (bused cell) {
231  ///     ...
232  ///     bus (A) {
233  ///       ...
234  ///       bus_type : bus4 ; /* bus name */
235  ///       ...
236  ///     }
237  ///   }
238  /// }
239  /// ```
240  #[liberty(group)]
241  pub r#type: LibertySet<BusType<C>>,
242  /// The `power_supply` group captures all nominal information about voltage variation.
243  /// It is defined before the `operating_conditions` group and before the `cell` groups.
244  /// All the power supply names defined in the `power_supply` group exist in the
245  /// `operating_conditions` group. Define the `power_supply` group at the library level.
246  ///
247  /// Syntax
248  /// ```text
249  /// power_supply () {
250  ///   default_power_rail : string ;
251  ///   power_rail (string, float) ;
252  ///   power_rail (string, float) ;
253  ///   ...
254  /// }
255  /// ```
256  /// Example
257  /// ```text
258  /// power_supply () {
259  ///   default_power_rail : VDD0;
260  ///   power_rail (VDD1, 5.0) ;
261  ///   power_rail (VDD2, 3.3) ;
262  /// }
263  /// ```
264  /// <a name ="reference_link" href="
265  /// https://zao111222333.github.io/liberty-db/2020.09/user_guide.html?field=null&bgn=51.33+52.2&end=51.34+52.16
266  /// ">Reference</a>
267  #[liberty(group)]
268  pub power_supply: Option<PowerSupply<C>>,
269  /// Use this group to define operating conditions;
270  /// that is, `process`, `voltage`, and `temperature`.
271  /// You define an `operating_conditions`  group at the library-level, as shown here:
272  /// <a name ="reference_link" href="
273  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=72.3&end=72.4
274  /// ">Reference</a>
275  #[liberty(group)]
276  pub operating_conditions: LibertySet<OperatingConditions<C>>,
277  /// Default operating conditions for the library
278  /// <a name ="reference_link" href="
279  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=34.29+34.32&end=34.31+34.33
280  /// ">Reference</a>
281  #[liberty(simple)]
282  pub default_operating_conditions: Option<String>,
283  /// The optional `default_threshold_voltage_group`  attribute specifies a cell’s category based on its threshold voltage characteristics
284  /// <a name ="reference_link" href="
285  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=23.20&end=23.21
286  /// ">Reference</a>
287  #[liberty(simple)]
288  pub default_threshold_voltage_group: Option<String>,
289  /// Use this special attribute to define new, temporary, or user-defined groups
290  /// for use in technology libraries.
291  /// <a name ="reference_link" href="
292  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=37.24&end=37.25
293  /// ">Reference</a>
294  #[liberty(complex)]
295  pub define_group: LibertySet<DefineGroup>,
296  /// The `define_cell_area`  attribute defines the area resources a `cell` uses,
297  /// such as the number of pad slots.
298  /// <a name ="reference_link" href="
299  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=36.23&end=36.24
300  /// ">Reference</a>
301  #[liberty(complex)]
302  pub define_cell_area: LibertySet<DefineCellArea>,
303  /// ``` liberty
304  /// library_features (value_1, value_2, ..., value_n) ;
305  /// ```
306  /// <a name ="reference_link" href="
307  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=18.40&end=18.41
308  /// ">Reference</a>
309  #[liberty(complex)]
310  pub library_features: Vec<String>,
311  /// Used in TSMC library
312  #[liberty(simple)]
313  pub default_leakage_power_density: Option<f64>,
314  /// Default leakage power
315  /// <a name ="reference_link" href="
316  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=34.4&end=34.5
317  /// ">Reference</a>
318  #[liberty(simple)]
319  pub default_cell_leakage_power: Option<f64>,
320  /// Default connection class
321  /// <a name ="reference_link" href="
322  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=34.7&end=34.8
323  /// ">Reference</a>
324  #[liberty(simple)]
325  pub default_connection_class: Option<String>,
326  /// Fanout load of input pins
327  /// <a name ="reference_link" href="
328  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=34.10&end=34.11
329  /// ">Reference</a>
330  #[liberty(simple)]
331  pub default_fanout_load: Option<f64>,
332  /// Capacitance of inout pins
333  /// <a name ="reference_link" href="
334  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=34.13&end=34.14
335  /// ">Reference</a>
336  #[liberty(simple)]
337  pub default_inout_pin_cap: Option<f64>,
338  /// Capacitance of input pins
339  /// <a name ="reference_link" href="
340  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=34.16&end=34.17
341  /// ">Reference</a>
342  #[liberty(simple)]
343  pub default_input_pin_cap: Option<f64>,
344  /// Maximum capacitance of output pins
345  /// <a name ="reference_link" href="
346  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=34.19&end=34.21
347  /// ">Reference</a>
348  #[liberty(simple)]
349  pub default_max_capacitance: Option<f64>,
350  /// Maximum fanout of all output pins
351  /// <a name ="reference_link" href="
352  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=34.23&end=34.24
353  /// ">Reference</a>
354  #[liberty(simple)]
355  pub default_max_fanout: Option<f64>,
356  /// Maximum transition of output pins
357  /// <a name ="reference_link" href="
358  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=34.26&end=34.27
359  /// ">Reference</a>
360  #[liberty(simple)]
361  pub default_max_transition: Option<f64>,
362  /// Capacitance of output pins
363  /// <a name ="reference_link" href="
364  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=34.33&end=34.34
365  /// ">Reference</a>
366  #[liberty(simple)]
367  pub default_output_pin_cap: Option<f64>,
368  /// Wire load area
369  /// <a name ="reference_link" href="
370  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=34.37&end=34.37
371  /// ">Reference</a>
372  #[liberty(simple)]
373  pub default_wire_load_area: Option<f64>,
374  /// Wire load capacitance
375  /// <a name ="reference_link" href="
376  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=34.38&end=34.39
377  /// ">Reference</a>
378  #[liberty(simple)]
379  pub default_wire_load_capacitance: Option<f64>,
380  /// Wire load mode
381  /// <a name ="reference_link" href="
382  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=34.41&end=34.41
383  /// ">Reference</a>
384  #[liberty(simple)]
385  pub default_wire_load_mode: Option<String>,
386  /// Wire load resistance
387  /// <a name ="reference_link" href="
388  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=34.42&end=34.43
389  /// ">Reference</a>
390  #[liberty(simple)]
391  pub default_wire_load_resistance: Option<f64>,
392  /// Wire load selection
393  /// <a name ="reference_link" href="
394  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=34.45&end=34.45
395  /// ">Reference</a>
396  #[liberty(simple)]
397  pub default_wire_load_selection: Option<String>,
398  /// The `em_temp_degradation_factor` attribute specifies the electromigration exponential
399  /// degradation factor.
400  ///
401  /// ### Syntax:
402  /// `em_temp_degradation_factor : valuefloat ;`
403  ///
404  /// value:
405  /// A floating-point number in centigrade units consistent with other temperature specifications throughout the library.
406  ///
407  /// ### Example
408  /// `em_temp_degradation_factor : 40.0 ;`
409  /// <a name ="reference_link" href="
410  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=26.3&end=26.13
411  /// ">Reference</a>
412  #[liberty(simple)]
413  pub em_temp_degradation_factor: Option<f64>,
414  /// Valid values are 1ps, 10ps, 100ps, and 1ns. The default is 1ns.
415  /// <a name ="reference_link" href="
416  /// https://zao111222333.github.io/liberty-db/2020.09/user_guide.html?field=null&bgn=42.25&end=42.30
417  /// ">Reference</a>
418  #[liberty(simple)]
419  pub time_unit: units::TimeUnit,
420  /// This attribute specifies the unit for all capacitance
421  /// values within the logic library, including
422  /// default capacitances, `max_fanout` capacitances,
423  /// pin capacitances, and wire capacitances.
424  /// <a name ="reference_link" href="
425  /// https://zao111222333.github.io/liberty-db/2020.09/user_guide.html?field=null&bgn=44.7&end=44.19
426  /// ">Reference</a>
427  #[liberty(complex)]
428  pub capacitive_load_unit: Option<units::CapacitiveLoadUnit>,
429  /// Valid values are 1mV, 10mV, 100mV, and 1V. The default is 1V.
430  /// <a name ="reference_link" href="
431  /// https://zao111222333.github.io/liberty-db/2020.09/user_guide.html?field=null&bgn=43.2&end=43.9
432  /// ">Reference</a>
433  #[liberty(simple)]
434  pub voltage_unit: units::VoltageUnit,
435  /// The valid values are 1uA, 10uA, 100uA, 1mA, 10mA, 100mA, and 1A.
436  /// **No default exists for the `current_unit` attribute if the attribute is omitted.**
437  /// <a name ="reference_link" href="
438  /// https://zao111222333.github.io/liberty-db/2020.09/user_guide.html?field=null&bgn=43.12&end=43.24
439  /// ">Reference</a>
440  #[liberty(simple)]
441  pub current_unit: Option<units::CurrentUnit>,
442  /// Valid unit values are 1ohm, 10ohm, 100ohm, and 1kohm.
443  /// **No default exists for `pulling_resistance_unit` if the attribute is omitted.**
444  /// <a name ="reference_link" href="
445  /// https://zao111222333.github.io/liberty-db/2020.09/user_guide.html?field=null&bgn=43.25&end=44.4
446  /// ">Reference</a>
447  #[liberty(simple)]
448  pub pulling_resistance_unit: Option<units::PullingResistanceUnit>,
449  /// This attribute indicates the units of the power values
450  /// in the library. If this attribute is missing, the
451  /// leakage-power values are expressed without units.
452  ///
453  /// Valid values are 1W, 100mW, 10mW, 1mW, 100nW, 10nW, 1nW, 100pW, 10pW, and 1pW.
454  /// <a name ="reference_link" href="
455  /// https://zao111222333.github.io/liberty-db/2020.09/user_guide.html?field=null&bgn=44.22&end=44.31
456  /// ">Reference</a>
457  #[liberty(simple)]
458  pub leakage_power_unit: Option<units::LeakagePowerUnit>,
459  /// Use the `voltage_map`  attribute to associate a voltage name
460  /// with relative voltage values referenced by the cell-level `pg_pin`  groups
461  /// <a name ="reference_link" href="
462  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=39.15&end=39.16
463  /// ">Reference</a>
464  #[liberty(complex)]
465  #[liberty(after_build = VoltageMap::add2scope)]
466  pub voltage_map: LibertySet<VoltageMap>,
467  /// An `input_voltage`  group is defined in the library  group to designate
468  /// a set of input voltage ranges for your cells.
469  /// <a name ="reference_link" href="
470  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=61.32&end=61.33
471  /// ">Reference</a>
472  #[liberty(group)]
473  pub input_voltage: LibertySet<InputVoltage<C>>,
474  /// You define an `output_voltage` group in the `library` group to designate a set of output
475  /// voltage level ranges to drive output cells.
476  /// <a name ="reference_link" href="
477  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=75.22&end=75.23
478  /// ">Reference</a>
479  #[liberty(group)]
480  pub output_voltage: LibertySet<OutputVoltage<C>>,
481  /// Use the `slew_upper_threshold_pct_rise`  attribute to set the value of the upper threshold point
482  /// that is used to model the delay of a pin rising from 0 to 1.
483  /// You can specify this attribute at the pin-level to override the default.
484  ///
485  /// A floating-point number between 0.0 and 100.0 that specifies the upper threshold point
486  /// used to model the delay of a pin rising from 0 to 1. The default is 80.0.
487  /// <a name ="reference_link" href="
488  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=32.16+32.24&end=32.18+32.26
489  /// ">Reference</a>
490  #[liberty(simple)]
491  #[liberty(default = 80.0)]
492  pub slew_upper_threshold_pct_rise: f64,
493  /// Use the `slew_lower_threshold_pct_rise`  attribute to set the default lower threshold point
494  /// that is used to model the delay of a pin rising from 0 to 1.
495  /// You can specify this attribute at the pin-level to override the default.
496  ///
497  /// A floating-point number between 0.0 and 100.0 that specifies the lower threshold point
498  /// used to model the delay of a pin rising from 0 to 1. The default is 20.0
499  /// <a name ="reference_link" href="
500  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=31.20+31.28&end=31.22+31.29
501  /// ">Reference</a>
502  #[liberty(simple)]
503  #[liberty(default = 20.0)]
504  pub slew_lower_threshold_pct_rise: f64,
505  /// Use the `slew_derate_from_library`  attribute to specify how the transition times need to be derated to match the transition times between the characterization trip points
506  ///
507  /// A floating-point number between 0.0 and 1.0. The default is 1.0.
508  /// <a name ="reference_link" href="
509  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=30.25+31.3&end=30.26+31.4
510  /// ">Reference</a>
511  #[liberty(simple)]
512  #[liberty(default = 1.0)]
513  pub slew_derate_from_library: f64,
514  /// Use the `slew_lower_threshold_pct_fall`  attribute to set the default lower threshold point
515  /// that is used to model the delay of a pin falling from 1 to 0.
516  /// You can specify this attribute at the pin-level to override the default.
517  ///
518  /// A floating-point number between 0.0 and 100.0 that specifies the lower threshold point
519  /// used to model the delay of a pin falling from 1 to 0. The default is 20.0
520  /// <a name ="reference_link" href="
521  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=31.7+31.15&end=31.9+31.16
522  /// ">Reference</a>
523  #[liberty(simple)]
524  #[liberty(default = 20.0)]
525  pub slew_lower_threshold_pct_fall: f64,
526  /// Use the `slew_upper_threshold_pct_fall`  attribute to set the default upper threshold point
527  /// that is used to model the delay of a pin falling from 1 to 0.
528  /// You can specify this attribute at the pin-level to override the default.
529  ///
530  /// A floating-point number between 0.0 and 100.0 that specifies the upper threshold point
531  /// to model the delay of a pin falling from 1 to 0. The default is 80.0
532  /// <a name ="reference_link" href="
533  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=32.3+32.11&end=32.5+32.12
534  /// ">Reference</a>
535  #[liberty(simple)]
536  #[liberty(default = 80.0)]
537  pub slew_upper_threshold_pct_fall: f64,
538  /// Use the `input_threshold_pct_fall`  attribute to set the default threshold point
539  /// on an input pin signal falling from 1 to 0.
540  /// You can specify this attribute at the pin-level to override the default.
541  ///
542  /// A floating-point number between 0.0 and 100.0 that specifies the threshold point
543  /// of an input pin signal falling from 1 to 0. The default is 50.0.
544  /// <a name ="reference_link" href="
545  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=26.15+26.23&end=26.17+26.24
546  /// ">Reference</a>
547  #[liberty(simple)]
548  #[liberty(default = 50.0)]
549  pub input_threshold_pct_fall: f64,
550  /// Use the `input_threshold_pct_rise`  attribute to set the default threshold point
551  /// on an input pin signal rising from 0 to 1.
552  /// You can specify this attribute at the pin-level to override the default.
553  ///
554  /// A floating-point number between 0.0 and 100.0 that specifies the threshold point
555  /// of an input pin signal rising from 0 to 1. The default is 50.0.
556  /// <a name ="reference_link" href="
557  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=26.28+27.3&end=26.30+27.4
558  /// ">Reference</a>
559  #[liberty(simple)]
560  #[liberty(default = 50.0)]
561  pub input_threshold_pct_rise: f64,
562  /// Use the `output_threshold_pct_rise`  attribute to set the value
563  /// of the threshold point on an output pin signal rising from 0 to 1.
564  ///
565  /// A floating-point number between 0.0 and 100.0 that specifies the threshold point
566  /// of an output pin signal rising from 0 to 1.The default is 50.0
567  /// <a name ="reference_link" href="
568  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=29.17+29.24&end=29.18+29.25
569  /// ">Reference</a>
570  #[liberty(simple)]
571  #[liberty(default = 50.0)]
572  pub output_threshold_pct_rise: f64,
573  /// Use the `output_threshold_pct_fall`  attribute to set the value of the threshold point
574  /// on an output pin signal falling from 1 to 0.
575  ///
576  /// A floating-point number between 0.0 and 100.0 that specifies the threshold point
577  /// of an output pin signal falling from 1 to 0. The default is 50.0
578  /// <a name ="reference_link" href="
579  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=29.5+29.12&end=29.6+29.13
580  /// ">Reference</a>
581  #[liberty(simple)]
582  #[liberty(default = 50.0)]
583  pub output_threshold_pct_fall: f64,
584  /// You can define power factors only in libraries that use a CMOS technology. Power scaling
585  /// factors scale the power computation according to process, temperature, and voltage.
586  /// The power-scaling factors are listed below. In the following syntax, multiplier is a floatingpoint number:
587  ///
588  /// Specifies process derating factors for the `cell_leakage_power` attribute.
589  #[liberty(simple)]
590  pub k_process_cell_leakage_power: Option<f64>,
591  /// Specifies process derating factors for the `internal_power` attribute.
592  #[liberty(simple)]
593  pub k_process_internal_power: Option<f64>,
594  /// Specifies temperature derating factors for the `cell_leakage_power` attribute.
595  #[liberty(simple)]
596  pub k_temp_cell_leakage_power: Option<f64>,
597  /// Specifies temperature derating factors for the `internal_power` attribute.
598  #[liberty(simple)]
599  pub k_temp_internal_power: Option<f64>,
600  /// Specifies voltage derating factors for the `cell_leakage_power` attribute.
601  #[liberty(simple)]
602  pub k_volt_cell_leakage_power: Option<f64>,
603  /// Specifies voltage derating factors for the `internal_power` attribute.
604  #[liberty(simple)]
605  pub k_volt_internal_power: Option<f64>,
606  /// The `is_soi`  attribute specifies that the cell is a
607  /// silicon-on-insulator (SOI) cell.
608  /// The default is false, which means that the cell is a
609  /// bulk-CMOS cell.
610  ///
611  /// If the `is_soi`  attribute is specified at both the
612  /// library and cell levels,
613  /// the cell-level value overrides the library-level value
614  /// <a name ="reference_link" href="
615  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=114.25&end=114.28
616  /// ">Reference</a>
617  #[liberty(simple)]
618  pub is_soi: Option<bool>,
619  /// The `soft_error_rate_confidence`  attribute specifies the confidence level
620  /// at which the cell soft error rate is sampled in the library. The value range is from 0 to 1.
621  /// <a name ="reference_link" href="
622  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=32.30&end=32.31
623  /// ">Reference</a>
624  #[liberty(simple)]
625  pub soft_error_rate_confidence: Option<f64>,
626  /// The `char_config` group is a group of attributes including simple and complex attributes.
627  /// These attributes represent library characterization configuration, and specify the settings
628  /// to characterize the library. Use the `char_config` group syntax to apply an attribute value
629  /// to a specific characterization model. You can specify multiple complex attributes in the
630  /// `char_config` group. You can also specify a single complex attribute multiple times for
631  /// different characterization models.
632  /// You can also define the `char_config` group within the cell, pin, and timing groups.
633  /// However, when you specify the same attribute in multiple `char_config` groups at different
634  /// levels, such as at the `library`, `cell`, `pin`, and `timing` levels, the attribute specified at the lower
635  /// level gets priority over the ones specified at the higher levels. For example, the pin-level
636  /// `char_config` group attributes have higher priority over the library-level `char_config`
637  /// group attributes.
638  ///
639  /// ### Syntax
640  /// ``` text
641  /// library (library_name) {
642  ///   char_config() {
643  ///     /* characterization configuration attributes */
644  ///   }
645  ///   ...
646  ///   cell (cell_name) {
647  ///     char_config() {
648  ///       /* characterization configuration attributes */
649  ///     }
650  ///     ...
651  ///     pin(pin_name) {
652  ///       char_config() {
653  ///         /* characterization configuration attributes */
654  ///       }
655  ///       timing() {
656  ///         char_config() {
657  ///           /* characterization configuration attributes */
658  ///         }
659  ///       } /* end of timing */
660  ///       ...
661  ///     } /* end of pin */
662  ///     ...
663  ///   } /* end of cell */
664  ///   ...
665  /// }
666  /// ```
667  /// <a name ="reference_link" href="
668  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=43.30+44.2&end=43.31+44.37
669  /// ">Reference</a>
670  #[liberty(group)]
671  pub char_config: Option<CharConfig<C>>,
672  /// Use the `output_current_template`  group to describe a table template
673  /// for composite current source (CCS) modeling.
674  /// <a name ="reference_link" href="
675  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=74.15&end=74.16
676  /// ">Reference</a>
677  #[liberty(group)]
678  pub output_current_template: LibertySet<TableTemple<C>>,
679  /// In the composite current source (CCS) power library format, instantaneous
680  /// power data is specified as 1- to n- dimensional tables of current waveforms in the
681  /// `pg_current_template` group. This library-level group creates templates of common
682  /// information that power and ground current vectors use.
683  /// <a name ="reference_link" href="
684  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=82.22&end=82.25
685  /// ">Reference</a>
686  #[liberty(group)]
687  pub pg_current_template: LibertySet<TableTemple<C>>,
688  /// The `power_lut_template` group is defined within the `library` group, as shown here:
689  /// <a name ="reference_link" href="
690  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=83.34&end=83.35
691  /// ">Reference</a>
692  #[liberty(group)]
693  pub power_lut_template: LibertySet<TableTemple<C>>,
694  /// Use the `lu_table_template`  group to define templates of common information
695  /// to use in lookup tables. Define the `lu_table_template`  group at the library level
696  /// <a name ="reference_link" href="
697  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=65.5&end=65.6
698  /// ">Reference</a>
699  #[liberty(group)]
700  pub lu_table_template: LibertySet<TableTemple<C>>,
701  #[liberty(group)]
702  pub noise_lut_template: LibertySet<TableTemple<C>>,
703  #[liberty(group)]
704  pub iv_lut_template: LibertySet<TableTemple<C>>,
705  #[liberty(group)]
706  pub propagation_lut_template: LibertySet<TableTemple<C>>,
707  #[liberty(group)]
708  pub poly_template: LibertySet<PolyTemplate<C>>,
709  #[liberty(group)]
710  pub power_poly_template: LibertySet<PolyTemplate<C>>,
711  /// The `base_curves`  group is a library-level group that contains
712  /// the detailed description of normalized base curves.
713  ///
714  /// **Syntax**
715  /// ``` text
716  /// library (my_compact_ccs_lib) {
717  ///   …
718  ///   base_curves (base_curves_name) {
719  ///     …
720  ///   }
721  /// }
722  /// ```
723  /// **Example**
724  /// ``` text
725  /// library(my_lib) {
726  ///   …
727  ///   base_curves (ctbct1) {
728  ///     …
729  ///   }
730  /// }
731  /// ```
732  /// <a name ="reference_link" href="
733  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=39.32+40.2&end=39.33+40.15
734  /// ">Reference</a>
735  #[liberty(group)]
736  pub base_curves: LibertySet<BaseCurves<C>>,
737  /// The `compact_lut_template`  group is a lookup table template used for compact CCS timing and power modeling
738  /// <a name ="reference_link" href="
739  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=41.20&end=41.21
740  /// ">Reference</a>
741  #[liberty(group)]
742  pub compact_lut_template: LibertySet<CompactLutTemplate<C>>,
743  /// The library-level `normalized_driver_waveform`  group represents a collection
744  /// of driver waveforms under various input slew values.
745  /// The `index_1`  specifies the input slew and `index_2`  specifies the normalized voltage.
746  /// Note that the slew index in the `normalized_driver_waveform`  table is
747  /// based on the slew derate and slew trip points of the library (global values).
748  /// When applied on a pin or cell with different slew or slew derate,
749  /// the new slew should be interpreted from the waveform.
750  /// <a name ="reference_link" href="
751  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=70.28&end=70.33
752  /// ">Reference</a>
753  #[liberty(group)]
754  pub normalized_driver_waveform: LibertySet<DriverWaveform<C>>,
755  /// A `wire_load`  group is defined in a `library`  group, as follows.
756  /// <a name ="reference_link" href="
757  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=94.16&end=94.17
758  /// ">Reference</a>
759  #[liberty(group)]
760  pub wire_load: LibertySet<WireLoad<C>>,
761  /// A `wire_load_selection`  group is defined in a `library`  group, as follows.
762  /// <a name ="reference_link" href="
763  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=94.16&end=94.17
764  /// ">Reference</a>
765  #[liberty(group)]
766  pub wire_load_selection: LibertySet<WireLoadSection<C>>,
767  /// Wire load
768  /// <a name ="reference_link" href="
769  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=34.36&end=34.36
770  /// ">Reference</a>
771  #[liberty(simple)]
772  pub default_wire_load: Option<String>,
773  /// Used in TSMC library
774  /// valid: `match_footprint`?
775  #[liberty(simple)]
776  pub in_place_swap_mode: Option<String>,
777  /// You can define one or more `fpga_isd`  groups at the library level
778  /// to specify the drive current, I/O voltages, and slew rates for FPGA parts and cells
779  ///
780  /// When you specify more than one `fpga_isd`  group, you **must** also define
781  /// the library-level `default_fpga_isd`  attribute to specify which `fpga_isd`
782  /// group is the default
783  /// <a name ="reference_link" href="
784  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=63.22+63.25&end=63.23+63.27
785  /// ">Reference</a>
786  #[liberty(group)]
787  pub fpga_isd: LibertySet<FpgaIsd<C>>,
788  /// When you specify more than one `fpga_isd`  group, you **must** also define
789  /// the library-level `default_fpga_isd`  attribute to specify which `fpga_isd`
790  /// group is the default
791  /// <a name ="reference_link" href="
792  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=63.22+63.25&end=63.23+63.27
793  /// ">Reference</a>
794  #[liberty(simple)]
795  pub default_fpga_isd: Option<String>,
796  /// The `sensitization` group defined at the library level describes
797  /// the complete state patterns for a specific list of pins (defined by the `pin_names` attribute)
798  /// that are referenced and instantiated as stimuli in the timing arc.
799  ///
800  /// Vector attributes in the group define all possible pin states used as stimuli.
801  /// Actual stimulus waveforms can be described by a combination of these vectors.
802  /// Multiple sensitization groups are allowed in a library. Each `sensitization` group
803  /// can be referenced by multiple cells, and each cell can make reference to
804  /// multiple `sensitization`  groups.
805  ///
806  /// <a name ="reference_link" href="
807  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=null&bgn=88.10&end=88.16
808  /// ">Reference</a>
809  #[liberty(group)]
810  pub sensitization: LibertySet<Sensitization<C>>,
811  /// A model group can include all the attributes that are valid in a cell group, as well as the
812  /// two additional attributes described in this section. For information about the cell group
813  /// attributes, see Attributes and Values on page 99.
814  /// <a name ="reference_link" href="
815  /// https://zao111222333.github.io/liberty-db/2020.09/reference_manual.html?field=test&bgn=225.23&end=225.29
816  /// ">Reference</a>
817  #[liberty(group)]
818  pub model: LibertySet<Model<C>>,
819  #[liberty(group)]
820  pub cell: LibertySet<Cell<C>>,
821  #[liberty(group)]
822  pub scaled_cell: LibertySet<ScaledCell<C>>,
823}
824
825impl<C: 'static + Ctx> fmt::Display for Library<C> {
826  #[inline]
827  fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
828    self.fmt_lib::<DefaultIndentation>(f)
829  }
830}
831impl<C: 'static + Ctx> Library<C> {
832  const KEY: &'static str = "library";
833  #[inline]
834  pub fn write_lib_file<P: AsRef<Path>>(&self, filename: P) -> std::io::Result<()> {
835    use std::io::{BufWriter, Write as _};
836    if let Some(dir) = filename.as_ref().parent() {
837      _ = std::fs::create_dir_all(dir);
838    }
839    let file = std::fs::File::create(filename)?;
840    let mut writer = BufWriter::new(file);
841    write!(&mut writer, "{self}")?;
842    Ok(())
843  }
844  #[inline]
845  pub fn write_lib_file_gz<P: AsRef<Path>>(&self, filename: P) -> std::io::Result<()> {
846    use flate2::{Compression, write::GzEncoder};
847    use std::io::{BufWriter, Write as _};
848    if let Some(dir) = filename.as_ref().parent() {
849      _ = std::fs::create_dir_all(dir);
850    }
851    let file = std::fs::File::create(filename)?;
852    let buf = BufWriter::new(file);
853    let mut writer = GzEncoder::new(buf, Compression::default());
854    write!(&mut writer, "{self}")?;
855    let mut buf_finish = writer.finish()?;
856    buf_finish.flush()?;
857    buf_finish.get_mut().sync_all()?;
858    Ok(())
859  }
860  /// Parse `.lib` file as a [Library] struct.
861  #[inline]
862  pub fn parse_lib_file(filename: &Path) -> Result<Self, ParserError<'_>> {
863    use flate2::read::GzDecoder;
864    use std::io::{self, BufRead as _, BufReader, Read as _};
865
866    fn read_maybe_gz_file(filename: &Path) -> io::Result<Vec<u8>> {
867      let file = std::fs::File::open(filename)?;
868      let mut buf = BufReader::new(file);
869
870      // https://www.rfc-editor.org/rfc/rfc1952#page-5
871      let head = buf.fill_buf()?;
872      let is_gz = head.starts_with(&[0x1F, 0x8B]);
873
874      let mut bytes = Vec::new();
875      _ = if is_gz {
876        GzDecoder::new(buf).read_to_end(&mut bytes)?
877      } else {
878        buf.read_to_end(&mut bytes)?
879      };
880
881      Ok(bytes)
882    }
883    let bytes = read_maybe_gz_file(filename)
884      .map_err(|e| ParserError::IO(filename.to_path_buf(), e))?;
885    // UTF-8 or lossy
886    match String::from_utf8(bytes) {
887      Ok(s) => Self::parse_lib(&s, Some(filename)),
888      Err(e) => {
889        let s = String::from_utf8_lossy(e.as_bytes());
890        Self::parse_lib(&s, Some(filename))
891      }
892    }
893  }
894  /// Parse `.lib` string as a [Library] struct.
895  /// Specify `filename` for better error information.
896  #[expect(clippy::arithmetic_side_effects)]
897  #[inline]
898  pub fn parse_lib<'a>(
899    s: &str,
900    filename: Option<&'a Path>,
901  ) -> Result<Self, ParserError<'a>> {
902    let mut scope = ParseScope {
903      loc: ParseLoc { filename: filename.map(Cow::Borrowed), line_num: 0 },
904      ..Default::default()
905    };
906    let input1 = match parser::comment_space_newline(s) {
907      Ok((input1, n)) => {
908        scope.loc.line_num += n;
909        input1
910      }
911      Err(e) => return Err(ParserError::nom(scope.loc, e)),
912    };
913    let (input2, key) = match parser::key(input1) {
914      Ok(res) => res,
915      Err(e) => return Err(ParserError::nom(scope.loc, e)),
916    };
917    if key == Self::KEY {
918      let mut builder = LibraryBuilder::default();
919      match <Self as GroupAttri<C>>::nom_parse::<false>(
920        &mut builder,
921        input2,
922        Self::KEY,
923        &mut scope,
924      ) {
925        Err(e) => Err(ParserError::nom(scope.loc, e)),
926        Ok((_, Err(e))) => Err(ParserError::IdError(scope.loc, e)),
927        Ok((_, Ok(_))) => {
928          let mut builder_scope = BuilderScope::default();
929          Ok(ParsingBuilder::build(builder, &mut builder_scope))
930        }
931      }
932    } else {
933      Err(ParserError::Other(scope.loc, format!("Need key={}, find={key}", Self::KEY)))
934    }
935  }
936  #[inline]
937  pub fn fmt_lib<I: crate::ast::Indentation>(
938    &self,
939    f: &mut fmt::Formatter<'_>,
940  ) -> Result<(), fmt::Error> {
941    let ff = &mut crate::ast::CodeFormatter::<'_, fmt::Formatter<'_>, I>::new(f);
942    crate::ast::fmt_library_beginning(self.comments_this(), ff)?;
943    GroupAttri::fmt_liberty(self, Self::KEY, ff)?;
944    f.write_char('\n')
945  }
946  /// TODO: Parse `.json` file as a [Library] struct.
947  #[inline]
948  pub fn parse_json(_i: &str) -> Result<Self, ParserError<'_>> {
949    todo!()
950  }
951  /// TODO: Format [Library] to .json
952  #[inline]
953  pub fn fmt_json<I: crate::ast::Indentation>(
954    &self,
955    _f: &mut fmt::Formatter<'_>,
956  ) -> Result<(), fmt::Error> {
957    todo!()
958  }
959  /// TODO: Parse `.db` file as a [Library] struct.
960  #[inline]
961  pub fn parse_db(_i: &str) -> Result<Self, ParserError<'_>> {
962    todo!()
963  }
964  /// TODO: Format [Library] to .db
965  #[inline]
966  pub fn fmt_db(&self, _f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
967    todo!()
968  }
969}
970
971impl<C: 'static + Ctx> GroupFn<C> for Library<C> {
972  #[cfg_attr(not(feature = "lut_template"), expect(unused_variables))]
973  fn before_build(builder: &mut Self::Builder, scope: &mut BuilderScope<C>) {
974    #[cfg(feature = "lut_template")]
975    {
976      use alloc::sync::Arc;
977      let mut empty_scope = BuilderScope::<C>::default();
978      scope.lu_table_template = builder
979        .lu_table_template
980        .iter()
981        .map(|_lut| {
982          let lut =
983            <TableTemple<C> as ParsingBuilder<C>>::build(_lut.clone(), &mut empty_scope);
984          (lut.name.clone(), Arc::new(lut))
985        })
986        .collect();
987      scope.power_lut_template = builder
988        .power_lut_template
989        .iter()
990        .map(|_lut| {
991          let lut =
992            <TableTemple<C> as ParsingBuilder<C>>::build(_lut.clone(), &mut empty_scope);
993          (lut.name.clone(), Arc::new(lut))
994        })
995        .collect();
996      scope.current_template = builder
997        .output_current_template
998        .iter()
999        .chain(builder.pg_current_template.iter())
1000        .map(|_lut| {
1001          let lut =
1002            <TableTemple<C> as ParsingBuilder<C>>::build(_lut.clone(), &mut empty_scope);
1003          (lut.name.clone(), Arc::new(lut))
1004        })
1005        .collect();
1006      scope.compact_lut_template = builder
1007        .compact_lut_template
1008        .iter()
1009        .map(|_lut| {
1010          let lut = <CompactLutTemplate<C> as ParsingBuilder<C>>::build(
1011            _lut.clone(),
1012            &mut empty_scope,
1013          );
1014          (lut.name.clone(), Arc::new(lut))
1015        })
1016        .collect();
1017    }
1018  }
1019}