Skip to main content

reda_lib/io/read/
semantic_cell.rs

1use crate::error::{LibErrorContext, LibError};
2use crate::model::{LibCell, LibFF, 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        let mut ff = None;
23
24        for group in group.groups {
25            match group.kind.as_str() {
26                "pin" => pins.push(LibPin::from_group(group).context(|| err_context("semantic pin"))?),
27                "pg_pin" => pg_pins.push(LibPgPin::from_group(group).context(|| err_context("semantic pg_pin"))?),
28                "leakage_power" => leakage_powers.push(LibLeakagePower::from_group(group).context(|| err_context("semantic leakage_power"))?),
29                "ff" => if ff.is_some() {
30                    Err(LibError::NotOnlyFF).context(|| err_context("semantic ff"))?;
31                } else {
32                    ff = Some(LibFF::from_group(group).context(|| err_context("semantic ff"))?)
33                },
34                _ => groups.push(group),
35            }
36        }
37
38        Ok(Self {
39            name,
40            area,
41            drive_strength,
42            cell_leakage_power,
43            pins,
44            pg_pins,
45            leakage_powers,
46            attrs: group.attrs,
47            groups,
48            ff,
49        })
50    }
51}
52
53impl FromLibGroup for LibPgPin {
54    type Error = LibError;
55
56    fn from_group(group: LibGroup) -> Result<Self, Self::Error> {
57        let mut group = group;
58        let name = group.expect_name().context(|| "cell name")?;
59        let err_context = |msg: &str| format!("{} in `{}` pg_pin", msg, &name);
60
61        Ok(Self {
62            name: name.clone(),
63            voltage_name: group.attr_lliteral("voltage_name", || err_context("semantic `voltage_name` attr"))?.to_string(),
64            pg_type: group.attr_parse("pg_type", &|| err_context("semantic `pg_type` attr"))?,
65            user_pg_type: group.attr_string_opt("user_pg_type", || err_context("semantic `user_pg_type` attr"))?.map(String::from),
66            physical_connection: group.attr_parse_opt("physical_connection", &|| err_context("semantic `physical_connection` attr"))?,
67
68            attrs: group.attrs,
69            groups: group.groups,
70        })
71    }
72}
73
74impl FromLibGroup for LibLeakagePower {
75    type Error = LibError;
76
77    fn from_group(group: LibGroup) -> Result<Self, Self::Error> {
78        let err_context = |msg: &str| format!("{} in leakage_power", msg);
79
80        Ok(Self {
81            when: group.attr_expr("when", &|| err_context("semantic `when` attr"))?,
82            value: group.attr_float("value", &|| err_context("semantic `value` attr"))?,
83            attrs: group.attrs,
84            groups: group.groups,
85        })
86    }
87}
88
89impl FromLibGroup for LibFF {
90    type Error = LibError;
91
92    fn from_group(group: LibGroup) -> Result<Self, Self::Error> {
93        let err_context = |msg: &str| format!("{} in ff", msg);
94        let next_state = group.attr_expr_opt("next_state", &|| err_context("semantic `next_state` attr"))?;
95        let clear = group.attr_expr_opt("clear", &|| err_context("semantic `clear` attr"))?;
96        let clocked_on = group.attr_expr_opt("clocked_on", &|| err_context("semantic `clocked_on` attr"))?;
97        let clocked_on_also = group.attr_expr_opt("clocked_on_also", &|| err_context("semantic `clocked_on_also` attr"))?;
98        let preset = group.attr_expr_opt("preset", &|| err_context("semantic `preset` attr"))?;
99        let clear_preset_var1 = group.attr_parse_opt("clear_preset_var1", &|| err_context("semantic `clear_preset_var1` attr"))?;
100        let clear_preset_var2 = group.attr_parse_opt("clear_preset_var2", &|| err_context("semantic `clear_preset_var2` attr"))?;
101
102        Ok(Self {
103            names: group.params,
104            next_state,
105            clocked_on,
106            clear,
107            clocked_on_also,
108            preset,
109            clear_preset_var1,
110            clear_preset_var2,
111
112            attrs: group.attrs,
113            groups: group.groups,
114        })
115    }
116}
117
118#[cfg(test)]
119mod test {
120    use super::*;
121
122    #[test]
123    fn test_pin_into_group() {
124        let mut pin = LibPin::new("my_pin");
125        pin.groups.push(LibGroup::new("gtype", vec!["gname".to_string()]));
126        // let group = pin.into_group();
127        // assert_eq!(group.type_, "pin");
128        // assert_eq!(group.name, "my_pin");
129        // assert_eq!(group.groups.len(), 1);
130    }
131
132    #[test]
133    fn test_pin_from_group() {
134        let mut group = LibGroup::new("pin", vec!["a".to_string()]);
135        group.groups.push(LibGroup::new("gtype", vec!["gname".to_string()]));
136        let pin = LibPin::from_group(group).unwrap();
137        assert_eq!(pin.name, "a");
138        assert_eq!(pin.groups.len(), 1);
139    }
140
141    #[test]
142    fn test_cell_into_group() {
143        let mut cell = LibCell::new("my_cell");
144        cell.groups.push(LibGroup::new("gtype", vec!["gname".to_string()]));
145        cell.pins.push(LibPin::new("a"));
146        cell.pins.push(LibPin::new("b"));
147        // let group = cell.into_group();
148        // assert_eq!(group.type_, "cell");
149        // assert_eq!(group.name, "my_cell");
150        // assert_eq!(group.groups.len(), 3);
151    }
152
153}