reda_lib/io/read/
semantic_cell.rs

1use 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        // let group = pin.into_group();
90        // assert_eq!(group.type_, "pin");
91        // assert_eq!(group.name, "my_pin");
92        // assert_eq!(group.groups.len(), 1);
93    }
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        // let group = cell.into_group();
111        // assert_eq!(group.type_, "cell");
112        // assert_eq!(group.name, "my_cell");
113        // assert_eq!(group.groups.len(), 3);
114    }
115
116}