Skip to main content

spef_parser/spef_parser/
spef_data.rs

1use std::collections::HashMap;
2use std::fmt::Debug;
3
4/// spef line entry basic info and it's methods
5#[derive(Clone, Debug)]
6pub struct SpefEntryBasicInfo {
7    file_name: String,
8    line_no: usize,
9}
10
11impl SpefEntryBasicInfo {
12    pub fn new(file_name: &str, line_no: usize) -> SpefEntryBasicInfo {
13        SpefEntryBasicInfo { file_name: file_name.to_string(), line_no }
14    }
15
16    pub fn get_file_name(&self) -> &str {
17        &self.file_name
18    }
19
20    pub fn get_line_no(&self) -> usize {
21        self.line_no
22    }
23}
24
25#[derive(Clone, Debug)]
26pub enum SectionType {
27    HEADER,
28    PORTS,
29    NAMEMAP,
30    CONN,
31    CAP,
32    RES,
33    END,
34}
35
36#[derive(Clone, Debug)]
37pub struct SpefSectionEntry {
38    basic_info: SpefEntryBasicInfo,
39    section_type: SectionType,
40}
41
42impl SpefSectionEntry {
43    pub fn new(file_name: &str, line_no: usize, section_type: SectionType) -> SpefSectionEntry {
44        SpefSectionEntry { basic_info: SpefEntryBasicInfo::new(file_name, line_no), section_type }
45    }
46
47    pub fn get_basic_info(&self) -> &SpefEntryBasicInfo {
48        &self.basic_info
49    }
50
51    pub fn get_section_type(&self) -> &SectionType {
52        &self.section_type
53    }
54}
55
56#[derive(Clone, Debug)]
57pub struct SpefHeaderEntry {
58    basic_info: SpefEntryBasicInfo,
59    pub header_key: String,
60    pub header_value: String,
61}
62
63impl SpefHeaderEntry {
64    pub fn new(file_name: &str, line_no: usize, header_key: String, header_value: String) -> SpefHeaderEntry {
65        SpefHeaderEntry {
66            basic_info: SpefEntryBasicInfo::new(file_name, line_no),
67            header_key,
68            header_value,
69        }
70    }
71
72    pub fn get_basic_info(&self) -> &SpefEntryBasicInfo {
73        &self.basic_info
74    }
75
76    pub fn get_header_key(&self) -> &str {
77        &self.header_key
78    }
79
80    pub fn get_header_value(&self) -> &str {
81        &self.header_value
82    }
83}
84
85/// Store each line of NameMap section
86/// namemap entry example: *43353 us21\/_1057_
87/// index: 43353
88/// name: us21\/_1057_
89#[derive(Clone, Debug)]
90pub struct SpefNameMapEntry {
91    basic_info: SpefEntryBasicInfo,
92    pub index: usize,
93    pub name: String,
94}
95
96impl SpefNameMapEntry {
97    pub fn new(file_name: &str, line_no: usize, index: usize, name: &str) -> SpefNameMapEntry {
98        SpefNameMapEntry { basic_info: SpefEntryBasicInfo::new(file_name, line_no), index, name: name.to_string() }
99    }
100
101    pub fn get_basic_info(&self) -> &SpefEntryBasicInfo {
102        &self.basic_info
103    }
104}
105
106/// Store each line of Port section
107/// Port entry example: *37 I *C 633.84 0.242
108/// name: "37"
109/// direction: ConnectionType::INPUT
110/// coordinate: (633.84, 0.242)
111#[repr(C)]
112#[derive(Clone, Copy, Debug)]
113pub enum ConnectionDirection {
114    INPUT,
115    OUTPUT,
116    INOUT,
117    Internal,
118    UNITIALIZED,
119}
120
121#[derive(Clone, Debug)]
122pub struct SpefPortEntry {
123    basic_info: SpefEntryBasicInfo,
124    name: String,
125    direction: ConnectionDirection,
126    coordinate: (f64, f64),
127}
128
129impl SpefPortEntry {
130    pub fn new(
131        file_name: &str,
132        line_no: usize,
133        name: String,
134        direction: ConnectionDirection,
135        coordinate: (f64, f64),
136    ) -> SpefPortEntry {
137        SpefPortEntry { basic_info: SpefEntryBasicInfo::new(file_name, line_no), name, direction, coordinate }
138    }
139
140    pub fn get_basic_info(&self) -> &SpefEntryBasicInfo {
141        &self.basic_info
142    }
143
144    pub fn get_name(&self) -> String {
145        self.name.clone()
146    }
147
148    pub fn get_direction(&self) -> ConnectionDirection {
149        self.direction
150    }
151
152    pub fn get_coordinate(&self) -> (f64, f64) {
153        // let mut result = Vec::<f64>::new();
154        // result.push(self.coordinate.0);
155        // result.push(self.coordinate.1);
156        // result
157        self.coordinate
158    }
159}
160
161/// Store each line of Conn section
162/// Conn entry example: *I *33272:Q O *C 635.66 405.835 *L 0 *D sky130_fd_sc_hd__dfxtp_1
163/// name: "37"
164/// direction: ConnectionType::INPUT
165/// coordinate: (633.84, 0.242)
166/// driving_cell: "sky130_fd_sc_hd__dfxtp_1"
167#[repr(C)]
168#[derive(Clone, Copy, Debug)]
169pub enum ConnectionType {
170    INTERNAL,
171    EXTERNAL,
172    UNITIALIZED,
173}
174
175#[derive(Clone, Debug)]
176pub struct SpefConnEntry {
177    basic_info: SpefEntryBasicInfo,
178    pub conn_type: ConnectionType,
179    pub conn_direction: ConnectionDirection,
180    pub pin_port_name: String,
181    pub driving_cell: String,
182    pub load: f64,
183    pub layer: u32,
184
185    pub coordinate: (f64, f64),
186    pub ll_coordinate: (f64, f64),
187    pub ur_coordinate: (f64, f64),
188}
189
190impl SpefConnEntry {
191    pub fn new(file_name: &str, line_no: usize) -> SpefConnEntry {
192        SpefConnEntry {
193            basic_info: SpefEntryBasicInfo::new(file_name, line_no),
194            conn_type: ConnectionType::UNITIALIZED,
195            conn_direction: ConnectionDirection::UNITIALIZED,
196            pin_port_name: String::new(),
197            driving_cell: String::new(),
198            load: 0.0,
199            layer: 0,
200            coordinate: (-1.0, -1.0),
201            ll_coordinate: (-1.0, -1.0),
202            ur_coordinate: (-1.0, -1.0),
203        }
204    }
205
206    pub fn get_basic_info(&self) -> &SpefEntryBasicInfo {
207        &self.basic_info
208    }
209
210    pub fn get_pin_port_name(&self) -> &str {
211        &self.pin_port_name
212    }
213    pub fn set_pin_port_name(&mut self, pin_port_name: String) {
214        self.pin_port_name = pin_port_name;
215    }
216
217    pub fn get_conn_type(&self) -> ConnectionType {
218        self.conn_type
219    }
220
221    pub fn set_conn_type(&mut self, conn_type: ConnectionType) {
222        self.conn_type = conn_type;
223    }
224
225    pub fn get_conn_direction(&self) -> ConnectionDirection {
226        self.conn_direction
227    }
228    pub fn set_conn_direction(&mut self, conn_direction: ConnectionDirection) {
229        self.conn_direction = conn_direction;
230    }
231
232    pub fn get_xy_coordinate(&self) -> (f64, f64) {
233        self.coordinate
234    }
235    pub fn set_xy_coordinate(&mut self, coordinate: (f64, f64)) {
236        self.coordinate = coordinate;
237    }
238
239    pub fn get_ll_coordinate(&self) -> (f64, f64) {
240        self.ll_coordinate
241    }
242    pub fn get_ur_coordinate(&self) -> (f64, f64) {
243        self.ur_coordinate
244    }
245
246    pub fn set_ll_corr(&mut self, coordinate: (f64, f64)) {
247        self.ll_coordinate = coordinate;
248    }
249    pub fn set_ur_corr(&mut self, coordinate: (f64, f64)) {
250        self.ur_coordinate = coordinate;
251    }
252
253    pub fn set_layer(&mut self, layer: u32) {
254        self.layer = layer;
255    }
256    pub fn get_layer(&self) -> u32 {
257        self.layer
258    }
259
260    pub fn set_driving_cell(&mut self, driving_cell: String) {
261        self.driving_cell = driving_cell;
262    }
263    pub fn get_driving_cell(&self) -> String {
264        self.driving_cell.clone()
265    }
266    pub fn set_load(&mut self, load: f64) {
267        self.load = load;
268    }
269    pub fn get_load(&self) -> f64 {
270        self.load
271    }
272}
273
274#[derive(Clone, Debug, Default)]
275pub struct SpefResCap {
276    pub node1: String,
277    pub node2: String,
278    pub res_or_cap: f64,
279}
280
281/// Store everthing about a net
282/// Conn entry example: 3 *1:2 0.000520945
283/// name: "1:2"
284/// direction: ConnectionType::INPUT
285/// coordinate: (633.84, 0.242)
286/// driving_cell: "sky130_fd_sc_hd__dfxtp_1"
287
288#[derive(Clone, Debug, Default)]
289pub struct SpefNet {
290    pub name: String,
291    pub line_no: usize,
292    pub lcap: f64,
293    pub connection: Vec<SpefConnEntry>,
294    pub caps: Vec<SpefResCap>,
295    pub ress: Vec<SpefResCap>,
296}
297
298impl SpefNet {
299    pub fn new(line_no: usize, name: String, lcap: f64) -> SpefNet {
300        SpefNet { name, line_no, lcap, connection: Vec::new(), caps: Vec::new(), ress: Vec::new() }
301    }
302
303    pub fn add_connection(&mut self, conn: &SpefConnEntry) {
304        self.connection.push(conn.clone());
305    }
306
307    pub fn add_cap(&mut self, cap: (String, String, f64)) {
308        let cap_item = SpefResCap { node1: cap.0, node2: cap.1, res_or_cap: cap.2 };
309        self.caps.push(cap_item);
310    }
311
312    pub fn add_res(&mut self, res: (String, String, f64)) {
313        let res_item = SpefResCap { node1: res.0, node2: res.1, res_or_cap: res.2 };
314        self.ress.push(res_item);
315    }
316
317    pub fn get_net_name(&self) -> String {
318        self.name.clone()
319    }
320
321    pub fn get_lcap(&self) -> f64 {
322        self.lcap
323    }
324
325    pub fn get_conns(&self) -> &Vec<SpefConnEntry> {
326        &self.connection
327    }
328
329    pub fn get_caps(&self) -> &Vec<SpefResCap> {
330        &self.caps
331    }
332
333    pub fn get_ress(&self) -> &Vec<SpefResCap> {
334        &self.ress
335    }
336}
337
338#[derive(Clone, Debug)]
339/// Spef Exchange data structure with cpp
340pub struct SpefExchange {
341    pub file_name: String,
342    pub header: Vec<SpefHeaderEntry>,
343    pub index_to_name_map: HashMap<usize, String>,
344    pub name_to_index_map: HashMap<String, usize>,
345    pub ports: Vec<SpefPortEntry>,
346    pub nets: Vec<SpefNet>,
347}
348
349impl SpefExchange {
350    pub fn new(file_name: String) -> SpefExchange {
351        SpefExchange {
352            file_name,
353            header: Vec::new(),
354            index_to_name_map: HashMap::new(),
355            name_to_index_map: HashMap::new(),
356            ports: Vec::new(),
357            nets: Vec::new(),
358        }
359    }
360
361    pub fn add_header_entry(&mut self, header: SpefHeaderEntry) {
362        self.header.push(header);
363    }
364
365    pub fn get_header(&self) -> &Vec<SpefHeaderEntry> {
366        &self.header
367    }
368
369    pub fn add_name_map_entry(&mut self, name_map_entry: SpefNameMapEntry) {
370        let name_clone = name_map_entry.name.clone();
371        self.index_to_name_map.insert(name_map_entry.index, name_map_entry.name);
372        self.name_to_index_map.insert(name_clone, name_map_entry.index);
373    }
374
375    pub fn get_index_to_name_map(&self) -> &HashMap<usize, String> {
376        &self.index_to_name_map
377    }
378
379    pub fn get_name_to_index_map(&self) -> &HashMap<String, usize> {
380        &self.name_to_index_map
381    }
382
383    pub fn add_port_entry(&mut self, port_entry: SpefPortEntry) {
384        self.ports.push(port_entry);
385    }
386
387    pub fn get_ports(&self) -> &Vec<SpefPortEntry> {
388        &self.ports
389    }
390
391    pub fn add_net(&mut self, net: SpefNet) {
392        self.nets.push(net);
393    }
394
395    pub fn get_nets(&self) -> &Vec<SpefNet> {
396        &self.nets
397    }
398
399    pub fn get_file_name(&self) -> &str {
400        &self.file_name
401    }
402}
403
404#[derive(Clone, Debug)]
405pub enum SpefParserData {
406    SectionEntry(SpefSectionEntry),
407    HeaderEntry(SpefHeaderEntry),
408    NameMapEntry(SpefNameMapEntry),
409    PortEntry(SpefPortEntry),
410    ConnEntry(SpefConnEntry),
411    NetEntry(SpefNet),
412    Exchange(SpefExchange),
413    Unitialized,
414}