reda_lib/io/read/
semantic_cell.rs1use crate::error::{LibErrorContext, LibError};
2use crate::model::{LibCell, LibGroup, LibLeakagePower, LibPgPin, LibPin};
3use super::FromLibGroup;
4
5impl FromLibGroup for LibCell {
6 type Error = LibError;
7 fn from_group(group: LibGroup) -> Result<Self, LibError> {
8 let mut group = group;
9 let name = group.expect_name().context(|| "cell name")?;
10 let err_context = |msg: &str| {
11 format!("{} in {} cell", msg, &name)
12 };
13
14 let area = group.attr_float_opt("area", || err_context("semantic `area` attr"))?;
15 let drive_strength = group.attr_float_opt("drive_strength", || err_context("semantic `drive_strength` attr"))?.map(|f| f as usize);
16 let cell_leakage_power = group.attr_float_opt("cell_leakage_power", || err_context("semantic `cell_leakage_power` attr"))?;
17
18 let mut pins = vec![];
19 let mut pg_pins = vec![];
20 let mut leakage_powers = vec![];
21 let mut groups = vec![];
22 for group in group.groups {
23 match group.kind.as_str() {
24 "pin" => pins.push(LibPin::from_group(group).context(|| err_context("semantic pin"))?),
25 "pg_pin" => pg_pins.push(LibPgPin::from_group(group).context(|| err_context("semantic pg_pin"))?),
26 "leakage_power" => leakage_powers.push(LibLeakagePower::from_group(group).context(|| err_context("semantic leakage_power"))?),
27 _ => groups.push(group),
28 }
29 }
30
31 Ok(Self {
32 name,
33 area,
34 drive_strength,
35 cell_leakage_power,
36 pins,
37 pg_pins,
38 leakage_powers,
39 attrs: group.attrs,
40 groups,
41 })
42 }
43}
44
45impl FromLibGroup for LibPgPin {
46 type Error = LibError;
47
48 fn from_group(group: LibGroup) -> Result<Self, Self::Error> {
49 let mut group = group;
50 let name = group.expect_name().context(|| "cell name")?;
51 let err_context = |msg: &str| format!("{} in `{}` pg_pin", msg, &name);
52
53 Ok(Self {
54 name: name.clone(),
55 voltage_name: group.attr_literal("voltage_name", || err_context("semantic `voltage_name` attr"))?.to_string(),
56 pg_type: group.attr_parse("pg_type", &|| err_context("semantic `pg_type` attr"))?,
57 user_pg_type: group.attr_string_opt("user_pg_type", || err_context("semantic `user_pg_type` attr"))?.map(String::from),
58 physical_connection: group.attr_parse_opt("physical_connection", &|| err_context("semantic `physical_connection` attr"))?,
59
60 attrs: group.attrs,
61 groups: group.groups,
62 })
63 }
64}
65
66impl FromLibGroup for LibLeakagePower {
67 type Error = LibError;
68
69 fn from_group(group: LibGroup) -> Result<Self, Self::Error> {
70 let err_context = |msg: &str| format!("{} in leakage_power", msg);
71
72 Ok(Self {
73 when: group.attr_expr("when", &|| err_context("semantic `when` attr"))?,
74 value: group.attr_float("value", &|| err_context("semantic `value` attr"))?,
75 attrs: group.attrs,
76 groups: group.groups,
77 })
78 }
79}
80
81#[cfg(test)]
82mod test {
83 use super::*;
84
85 #[test]
86 fn test_pin_into_group() {
87 let mut pin = LibPin::new("my_pin");
88 pin.groups.push(LibGroup::new("gtype", vec!["gname".to_string()]));
89 }
94
95 #[test]
96 fn test_pin_from_group() {
97 let mut group = LibGroup::new("pin", vec!["a".to_string()]);
98 group.groups.push(LibGroup::new("gtype", vec!["gname".to_string()]));
99 let pin = LibPin::from_group(group).unwrap();
100 assert_eq!(pin.name, "a");
101 assert_eq!(pin.groups.len(), 1);
102 }
103
104 #[test]
105 fn test_cell_into_group() {
106 let mut cell = LibCell::new("my_cell");
107 cell.groups.push(LibGroup::new("gtype", vec!["gname".to_string()]));
108 cell.pins.push(LibPin::new("a"));
109 cell.pins.push(LibPin::new("b"));
110 }
115
116}