1use std::collections::HashMap;
2use crate::error::{LibErrorContext, LibError};
3use crate::model::{LibAst, LibCell, LibGroup, LibLibrary, LibPin, LibPinDirection};
4
5pub trait FromLibGroup: Sized {
6 type Error: Sized;
7 fn from_group(group: LibGroup) -> Result<Self, Self::Error>;
8}
9
10impl LibLibrary {
11 pub fn from_ast(ast: LibAst) -> Result<Self, LibError> {
12 let group = LibGroup::from_ast(ast).context(|| "semantic root ast to group")?;
13 Self::from_group(group)
14 }
15}
16
17impl FromLibGroup for LibLibrary {
18 type Error = LibError;
19 fn from_group(group: LibGroup) -> Result<Self, LibError> {
20 let mut group = group;
21 let name = group.expect_name().context(|| "group name")?;
22 let (cell_groups, groups) = group.groups.into_iter().partition(|g| g.kind == "cell");
23
24 let mut cells = Vec::new();
26 for cell_group in cell_groups {
27 cells.push(LibCell::from_group(cell_group).context(|| "semantic cell")?);
28 }
29
30 Ok(Self {
31 name,
32 attrs: group.attrs,
33 groups,
34 cells,
35 })
36 }
37}
38
39impl FromLibGroup for LibCell {
40 type Error = LibError;
41 fn from_group(group: LibGroup) -> Result<Self, LibError> {
42 let mut group = group;
43 let name = group.expect_name().context(|| "cell name")?;
44 let err_context = |msg: &str| {
45 format!("{} in {} cell", msg, &name)
46 };
47
48 let (pin_groups, groups) = group.groups.into_iter().partition(|g| g.kind == "pin");
49
50 let mut pins = Vec::new();
52 for cell_group in pin_groups {
53 pins.push(LibPin::from_group(cell_group).context(|| err_context("semantic pin"))?);
54 }
55
56 Ok(Self {
57 name,
58 pins,
59 attrs: group.attrs,
60 groups,
61 })
62 }
63}
64
65impl FromLibGroup for LibPin {
66 type Error = LibError;
67
68 fn from_group(group: LibGroup) -> Result<Self, LibError> {
69 let mut group = group;
70 let name = group.expect_name().context(|| "pin name")?;
71 let err_context = |msg: &str| format!("{} in `{}` pin", msg, &name);
72
73 let get_bool_opt =
75 |key: &str| group.attr_bool_opt(key, || err_context(&format!("semantic `{}` attr", key)));
76 let get_float_opt =
77 |key: &str| group.attr_float_opt(key, || err_context(&format!("semantic `{}` attr", key)));
78 let get_string_opt =
79 |key: &str| group.attr_string_opt(key, || err_context(&format!("semantic `{}` attr", key))).map(|v| v.map(String::from));
80 let get_ident_opt =
81 |key: &str| group.attr_ident_opt(key, || err_context(&format!("semantic `{}` attr", key))).map(|v| v.map(String::from));
82 let get_expr_opt =
83 |key: &str| group.attr_expr_opt(key, &|| err_context(&format!("semantic `{}` attr", key)));
84
85
86 let alive_during_power_up = get_bool_opt("alive_during_power_up")?;
87 let always_on = get_bool_opt("always_on")?;
88
89 let antenna_diode_type = group.attr_parse_opt("antenna_diode_type", &|| err_context("semantic `antenna_diode_type` attr"))?;
90 let nextstate_type = group.attr_parse_opt("nextstate_type", &|| err_context("semantic `nextstate_type` attr"))?;
91
92 let antenna_diode_related_ground_pins = get_string_opt("antenna_diode_related_ground_pins")?;
93 let antenna_diode_related_power_pins = get_string_opt("antenna_diode_related_power_pins")?;
94 let bit_width = get_float_opt("bit_width")?.map(|v| v as usize);
95
96 let capacitance = get_float_opt("capacitance")?;
97 let fall_capacitance = get_float_opt("fall_capacitance")?;
98 let fanout_load = get_float_opt("fanout_load")?;
99 let drive_current = get_float_opt("drive_current")?;
100 let fall_current_slope_after_threshold = get_float_opt("fall_current_slope_after_threshold")?;
101 let fall_current_slope_before_threshold = get_float_opt("fall_current_slope_before_threshold")?;
102 let fall_time_after_threshold = get_float_opt("fall_time_after_threshold")?;
103 let fall_time_before_threshold = get_float_opt("fall_time_before_threshold")?;
104
105 let max_capacitance = get_float_opt("max_capacitance")?;
106 let min_capacitance = get_float_opt("min_capacitance")?;
107 let max_fanout = get_float_opt("max_fanout")?;
108 let min_fanout = get_float_opt("min_fanout")?;
109 let max_transition = get_float_opt("max_transition")?;
110 let min_transition = get_float_opt("min_transition")?;
111 let min_period = get_float_opt("min_period")?;
112 let min_pulse_width_high = get_float_opt("min_pulse_width_high")?;
113 let min_pulse_width_low = get_float_opt("min_pulse_width_low")?;
114 let max_input_delta_overdrive_high = get_float_opt("max_input_delta_overdrive_high")?;
115 let max_input_delta_underdrive_high = get_float_opt("max_input_delta_underdrive_high")?;
116
117 let clamp_0_function = get_string_opt("clamp_0_function")?;
118 let clamp_1_function = get_string_opt("clamp_1_function")?;
119 let clamp_latch_function = get_string_opt("clamp_latch_function")?;
120 let clamp_z_function = get_string_opt("clamp_z_function")?;
121 let illegal_clamp_condition = get_string_opt("illegal_clamp_condition")?;
122 let complementary_pin = get_string_opt("complementary_pin")?;
123
124 let clock = get_bool_opt("clock")?;
125 let clock_gate_clock_pin = get_bool_opt("clock_gate_clock_pin")?;
126 let clock_gate_enable_pin = get_bool_opt("clock_gate_enable_pin")?;
127 let clock_gate_test_pin = get_bool_opt("clock_gate_test_pin")?;
128 let clock_gate_obs_pin = get_bool_opt("clock_gate_obs_pin")?;
129 let clock_gate_out_pin = get_bool_opt("clock_gate_out_pin")?;
130 let clock_isolation_cell_clock_pin = get_bool_opt("clock_isolation_cell_clock_pin")?;
131
132 let direction = group.attr_parse_opt("direction", &|| err_context("semantic `direction` attr"))?.unwrap_or(LibPinDirection::Input);
133
134 let driver_type = group.attr_parse_opt("driver_type", &|| err_context("semantic `driver_type` attr"))?;
135
136 let output_signal_level = get_string_opt("output_signal_level")?;
137 let output_signal_level_high = get_float_opt("output_signal_level_high")?;
138 let output_signal_level_low = get_float_opt("output_signal_level_low")?;
139 let output_voltage = get_string_opt("output_voltage")?;
140 let input_signal_level = get_string_opt("input_signal_level")?;
141 let input_voltage = get_string_opt("input_voltage")?;
142
143 let has_builtin_pad = get_bool_opt("has_builtin_pad")?;
144 let hysteresis = get_bool_opt("hysteresis")?;
145 let is_pad = get_bool_opt("is_pad")?;
146 let is_unconnected = get_bool_opt("is_unconnected")?;
147 let multicell_pad_pin = get_bool_opt("multicell_pad_pin")?;
148 let inverted_output = get_bool_opt("inverted_output")?;
149
150 let connection_class = get_string_opt("connection_class")?;
151 let fault_model = get_string_opt("fault_model")?;
152 let dont_fault = group.attr_parse_opt("dont_fault", &|| err_context("semantic `dont_fault` attr"))?;
153 let internal_node = get_ident_opt("internal_node")?;
154 let input_map = get_string_opt("input_map")?;
155
156 let function = get_expr_opt("function")?;
157
158 let pin_func_type = group.attr_parse_opt("pin_func_type", &|| err_context("semantic `pin_func_type` attr"))?;
160 let primary_output = get_bool_opt("primary_output")?;
161 let pulling_current = get_float_opt("pulling_current")?;
162 let pulling_resistance = get_float_opt("pulling_resistance")?;
163 let restore_action = group.attr_parse_opt("restore_action", &|| err_context("semantic `restore_action` attr"))?;
164 let restore_edge_type = group.attr_parse_opt("restore_edge_type", &|| err_context("semantic `restore_edge_type` attr"))?;
165
166 let rise_capacitance = get_float_opt("rise_capacitance")?;
168 let rise_current_slope_after_threshold = get_float_opt("rise_current_slope_after_threshold")?;
169 let rise_current_slope_before_threshold = get_float_opt("rise_current_slope_before_threshold")?;
170 let rise_time_after_threshold = get_float_opt("rise_time_after_threshold")?;
171 let rise_time_before_threshold = get_float_opt("rise_time_before_threshold")?;
172
173 let save_action = group.attr_parse_opt("save_action", &|| err_context("semantic `save_action` attr"))?;
174 let signal_type = group.attr_parse_opt("signal_type", &|| err_context("semantic `signal_type` attr"))?;
175 let slew_control = group.attr_parse_opt("slew_control", &|| err_context("semantic `slew_control` attr"))?;
176
177 let state_function = get_expr_opt("state_function")?;
179 let test_output_only = get_bool_opt("test_output_only")?;
180 let three_state = get_expr_opt("three_state")?;
181 let x_function = get_expr_opt("x_function")?;
182
183 let fall_capacitance_range = group.attr_floats_opt("fall_capacitance_range", &|| err_context("semantic `fall_capacitance_range` attr"))?;
184 let rise_capacitance_range = group.attr_floats_opt("rise_capacitance_range", &|| err_context("semantic `rise_capacitance_range` attr"))?;
185
186 Ok(Self {
187 name,
188
189 alive_during_power_up,
190 always_on,
191
192 antenna_diode_type,
193 antenna_diode_related_ground_pins,
194 antenna_diode_related_power_pins,
195
196 bit_width,
197
198 capacitance,
199 fall_capacitance,
200 fanout_load,
201 drive_current,
202 fall_current_slope_after_threshold,
203 fall_current_slope_before_threshold,
204 fall_time_after_threshold,
205 fall_time_before_threshold,
206
207 max_capacitance,
208 min_capacitance,
209 max_fanout,
210 min_fanout,
211 max_transition,
212 min_transition,
213 min_period,
214 min_pulse_width_high,
215 min_pulse_width_low,
216 max_input_delta_overdrive_high,
217 max_input_delta_underdrive_high,
218
219 clamp_0_function,
220 clamp_1_function,
221 clamp_latch_function,
222 clamp_z_function,
223 illegal_clamp_condition,
224 complementary_pin,
225 nextstate_type,
226
227 clock,
228 clock_gate_clock_pin,
229 clock_gate_enable_pin,
230 clock_gate_test_pin,
231 clock_gate_obs_pin,
232 clock_gate_out_pin,
233 clock_isolation_cell_clock_pin,
234
235 direction,
236 driver_type,
237 output_signal_level,
238 output_signal_level_high,
239 output_signal_level_low,
240 output_voltage,
241 input_signal_level,
242 input_voltage,
243
244 has_builtin_pad,
245 hysteresis,
246 is_pad,
247 is_unconnected,
248 multicell_pad_pin,
249 inverted_output,
250
251 connection_class,
252 fault_model,
253 dont_fault,
254 internal_node,
255 input_map,
256
257 function,
258
259 pin_func_type,
260 primary_output,
261 pulling_current,
262 pulling_resistance,
263 restore_action,
264 restore_edge_type,
265 rise_capacitance,
266 rise_current_slope_after_threshold,
267 rise_current_slope_before_threshold,
268 rise_time_after_threshold,
269 rise_time_before_threshold,
270 save_action,
271 signal_type,
272 slew_control,
273 state_function,
274 test_output_only,
275 three_state,
276 x_function,
277
278 fall_capacitance_range,
279 rise_capacitance_range,
280
281 attrs: group.attrs,
282 groups: group.groups,
283 })
284 }
285}
286
287impl LibGroup {
288 pub fn from_ast(ast: LibAst) -> Result<Self, LibError> {
289 match ast {
290 LibAst::LibGroup { kind, params, items } => {
291 let mut attrs = HashMap::new();
292 let mut groups = Vec::new();
293
294 for item_ast in items {
295 if let LibAst::Attr { key, value } = item_ast {
296 attrs.insert(key, value);
297 } else {
298 groups.push(LibGroup::from_ast(item_ast)?);
299 }
300 }
301
302 Ok(Self {
303 kind,
304 params,
305 attrs,
306 groups
307 })
308 }
309 LibAst::Attr { key:_, value:_ } => Err(LibError::ExceptLibGroup),
310 }
311 }
312}
313
314#[cfg(test)]
315mod test {
316 use super::*;
317
318 #[test]
319 fn test_pin_into_group() {
320 let mut pin = LibPin::new("my_pin");
321 pin.groups.push(LibGroup::new("gtype", vec!["gname".to_string()]));
322 }
327
328 #[test]
329 fn test_pin_from_group() {
330 let mut group = LibGroup::new("pin", vec!["a".to_string()]);
331 group.groups.push(LibGroup::new("gtype", vec!["gname".to_string()]));
332 let pin = LibPin::from_group(group).unwrap();
333 assert_eq!(pin.name, "a");
334 assert_eq!(pin.groups.len(), 1);
335 }
336
337 #[test]
338 fn test_cell_into_group() {
339 let mut cell = LibCell::new("my_cell");
340 cell.groups.push(LibGroup::new("gtype", vec!["gname".to_string()]));
341 cell.pins.push(LibPin::new("a"));
342 cell.pins.push(LibPin::new("b"));
343 }
348
349 #[test]
350 fn test_cell_from_group() {
351 let mut group = LibGroup::new("cell", vec!["AND2".to_string()]);
352 group.groups.push(LibGroup::new("gtype", vec!["gname".to_string()]));
353 group.groups.push(LibGroup::new("pin", vec!["a".to_string()]));
354 group.groups.push(LibGroup::new("pin", vec!["b".to_string()]));
355 let cell = LibCell::from_group(group).unwrap();
356 assert_eq!(cell.name, "AND2");
357 assert_eq!(cell.groups.len(), 1);
358 assert_eq!(cell.pins.len(), 2);
359 }
360
361 #[test]
362 fn test_library_into_group() {
363 let mut lib = LibLibrary::new("my_lib");
364 lib.groups.push(LibGroup::new("gtype", vec!["gname".to_string()]));
365 lib.cells.push(LibCell::new("AND2"));
366 lib.cells.push(LibCell::new("NAND2"));
367 }
372
373 #[test]
374 fn test_lib_from_group() {
375 let mut group = LibGroup::new("library", vec!["mylib".to_string()]);
376 group.groups.push(LibGroup::new("gtype", vec!["gname".to_string()]));
377 let mut cell = LibGroup::new("cell", vec!["AND2".to_string()]);
378 cell.groups.push(LibGroup::new("pin", vec!["a".to_string()]));
379 cell.groups.push(LibGroup::new("pin", vec!["b".to_string()]));
380 group.groups.push(cell);
381 let lib = LibLibrary::from_group(group).unwrap();
382 assert_eq!(lib.name, "mylib");
383 assert_eq!(lib.groups.len(), 1);
384 assert_eq!(lib.cells.len(), 1);
385 let converted_cell = lib.cell("AND2").unwrap();
386 assert_eq!(converted_cell.name, "AND2");
387 assert_eq!(converted_cell.groups.len(), 0);
388 assert_eq!(converted_cell.pins.len(), 2);
389 }
390}