prjunnamed_generic/analysis/
level.rs

1use std::{cell::RefCell, collections::HashMap};
2
3use prjunnamed_netlist::{Cell, Design, Net, RewriteRuleset, Value};
4
5#[derive(Default)]
6pub struct LevelAnalysis {
7    levels: RefCell<HashMap<Net, u32>>,
8}
9
10impl LevelAnalysis {
11    pub fn new() -> Self {
12        Default::default()
13    }
14
15    pub fn get(&self, net: Net) -> u32 {
16        self.levels.borrow().get(&net).copied().unwrap_or(0)
17    }
18}
19
20impl RewriteRuleset for LevelAnalysis {
21    fn cell_added(&self, design: &Design, cell: &Cell, output: &Value) {
22        let mut levels = self.levels.borrow_mut();
23        if let Cell::Not(input) = cell {
24            for (onet, inet) in output.iter().zip(input) {
25                let ilevel = levels.get(&inet).copied().unwrap_or(0);
26                levels.insert(onet, ilevel);
27            }
28        } else if !cell.has_state(design) {
29            let mut level = 0;
30            cell.visit(|net| {
31                if !net.is_const() {
32                    let l = levels.get(&net).copied().unwrap_or(0);
33                    level = level.max(l + 1);
34                }
35            });
36            for net in output {
37                levels.insert(net, level);
38            }
39        };
40    }
41
42    fn net_replaced(&self, _design: &Design, from: Net, to: Net) {
43        let mut levels = self.levels.borrow_mut();
44        if let Some(&level) = levels.get(&to) {
45            levels.insert(from, level);
46        }
47    }
48}