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