prjunnamed_generic/analysis/
level.rs

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