1use reda_lib_macro::model;
2use crate::{lib_enum, model::LibPin};
3
4use super::{LibExpr, LibPinDirection};
5
6#[model]
7#[derive(Debug, Clone, Default)]
8pub struct LibCell {
9 pub name: String,
10
11 pub area: Option<f64>,
12 pub drive_strength: Option<usize>,
13 pub cell_leakage_power: Option<f64>,
14 pub ff: Option<LibFF>,
15
16 pub leakage_powers: Vec<LibLeakagePower>,
17 pub pins: Vec<LibPin>,
18 pub pg_pins: Vec<LibPgPin>,
19}
20
21#[model]
22#[derive(Debug, Clone, Default)]
23pub struct LibPgPin {
24 pub name: String,
25 pub voltage_name: String,
26 pub pg_type: LibPgType,
27 pub user_pg_type: Option<String>,
28 pub physical_connection: Option<LibPhysicalConnection>,
29}
30
31#[model]
32#[derive(Debug, Clone, Default)]
33pub struct LibFF {
34 pub names: Vec<String>,
35 pub next_state: Option<LibExpr>,
36 pub clocked_on: Option<LibExpr>,
37 pub clear: Option<LibExpr>,
38 pub clocked_on_also: Option<LibExpr>,
39 pub preset: Option<LibExpr>,
40 pub clear_preset_var1: Option<LibClearPresetVar>,
41 pub clear_preset_var2: Option<LibClearPresetVar>,
42}
43
44lib_enum!(LibDontFault,
45 Sa0,
46 Sa1,
47 Sa01,
48);
49
50lib_enum!(LibFpgaCellType,
51 Sa0,
52 Sa1,
53 Sa01,
54);
55
56lib_enum!(LibClearPresetVar,
57 L, H, N, T, X
58);
59
60lib_enum!(LibPgType,
61 primary_power,
62 primary_ground,
63 backup_power,
64 backup_ground,
65 internal_power,
66 internal_ground,
67 pwell,
68 nwell,
69 deepnwell,
70 deeppwell
71);
72
73lib_enum!(LibPhysicalConnection,
74 device_layer,
75 routing_pin,
76);
77
78#[model]
79#[derive(Debug, Clone)]
80pub struct LibLeakagePower {
81 pub when: LibExpr,
82 pub value: f64,
83}
84
85impl LibCell {
86 pub fn new<S: Into<String>>(name: S) -> Self {
87 Self {
88 name: name.into(),
89 ..Default::default()
90 }
91 }
92
93 pub fn pin(&self, name: &str) -> Option<&LibPin> {
94 self.pins.iter().find(|p| p.name == name)
95 }
96
97 pub fn input_pins(&self) -> impl Iterator<Item = &LibPin> {
98 self.pins.iter()
99 .filter(|pin| {
100 pin.direction == LibPinDirection::Input
101 })
102 }
103
104 pub fn output_pins(&self) -> impl Iterator<Item = &LibPin> {
105 self.pins.iter()
106 .filter(|pin| {
107 pin.direction == LibPinDirection::Output
108 })
109 }
110
111 pub fn get_pin(&self, name: &str) -> Option<&LibPin> {
112 self.pins.iter()
113 .find(|pin| pin.name == name)
114 }
115
116 pub fn get_pg_pin(&self, name: &str) -> Option<&LibPgPin> {
117 self.pg_pins.iter()
118 .find(|pin| pin.name == name)
119 }
120}