spade_mir/
renaming.rs

1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4use spade_common::{id_tracker::ExprID, name::NameID};
5
6use crate::{Binding, Entity, MirInput, Register, ValueName};
7
8/// Mapping from verilog name back to the corresponding NameID
9#[derive(Serialize, Deserialize, Debug, Clone)]
10pub struct VerilogNameMap {
11    inner: HashMap<String, VerilogNameSource>,
12}
13
14impl Default for VerilogNameMap {
15    fn default() -> Self {
16        Self::new()
17    }
18}
19
20impl VerilogNameMap {
21    pub fn new() -> Self {
22        Self {
23            inner: HashMap::new(),
24        }
25    }
26
27    /// Insert the specified string into the name map. If the string contains
28    /// verilog escape characters (\\<name> ), those are removed
29    pub fn insert(&mut self, from: &str, to: VerilogNameSource) {
30        self.inner.insert(
31            from.trim_start_matches('\\')
32                .trim_end_matches(' ')
33                .to_string(),
34            to,
35        );
36    }
37
38    pub fn lookup_name(&self, name: &str) -> Option<&VerilogNameSource> {
39        self.inner.get(name)
40    }
41}
42
43#[derive(Serialize, Deserialize, Debug, Clone)]
44pub enum VerilogNameSource {
45    ForwardName(NameID),
46    BackwardName(NameID),
47    ForwardExpr(ExprID),
48    BackwardExpr(ExprID),
49}
50
51#[derive(Clone)]
52pub struct NameState {
53    /// Mapping between names and the amount of copies of that name we've seen so far
54    names: HashMap<String, u64>,
55    /// Mapping between ValueName and predictable name
56    name_map: HashMap<ValueName, ValueName>,
57}
58
59impl Default for NameState {
60    fn default() -> Self {
61        Self::new()
62    }
63}
64
65impl NameState {
66    pub fn new() -> NameState {
67        Self {
68            names: HashMap::new(),
69            name_map: HashMap::new(),
70        }
71    }
72
73    pub fn push(&mut self, name: &ValueName) {
74        let new_name = match name {
75            ValueName::Named(_, name_str, source) => {
76                let id = self
77                    .names
78                    .entry(name_str.clone())
79                    .and_modify(|v| *v += 1)
80                    .or_insert(0);
81
82                ValueName::Named(*id, name_str.clone(), source.clone())
83            }
84            v @ ValueName::Expr(_) => v.clone(),
85        };
86
87        self.name_map.insert(name.clone(), new_name);
88    }
89
90    pub fn get(&mut self, name: &ValueName) -> ValueName {
91        self.name_map
92            .get(name)
93            .cloned()
94            .unwrap_or_else(|| name.clone())
95    }
96}
97
98pub fn make_names_predictable(e: &mut Entity) -> NameState {
99    let mut state = NameState::new();
100
101    {
102        // Walk through all statements adding defined names to the state
103        let Entity {
104            name: _, // we should not translate the outer name
105            inputs,
106            output: _,
107            output_type: _,
108            statements,
109        } = e;
110
111        for input in inputs {
112            state.push(&input.val_name);
113        }
114
115        for stmt in statements {
116            match stmt {
117                crate::Statement::Binding(Binding {
118                    name,
119                    operator: _,
120                    operands: _,
121                    ty: _,
122                    loc: _,
123                }) => state.push(name),
124                crate::Statement::Register(Register {
125                    name,
126                    ty: _,
127                    clock: _,
128                    reset: _,
129                    initial: _,
130                    value: _,
131                    loc: _,
132                    traced: _,
133                }) => state.push(name),
134                crate::Statement::Constant(_, _, _) => {}
135                crate::Statement::Assert(_) => {}
136                crate::Statement::Set {
137                    target: _,
138                    value: _,
139                } => {}
140                crate::Statement::WalTrace { .. } => {}
141            }
142        }
143    }
144
145    {
146        // Walk through the whole structure again, replacing names by their predictable versions
147        let Entity {
148            name: _, // we should not translate the outer name
149            inputs,
150            output,
151            output_type: _,
152            statements,
153        } = e;
154
155        for MirInput {
156            name: _,
157            val_name: val,
158            ty: _,
159            no_mangle: _,
160        } in inputs.iter_mut()
161        {
162            *val = state.get(val)
163        }
164
165        *output = state.get(output);
166
167        for stmt in statements.iter_mut() {
168            match stmt {
169                crate::Statement::Binding(Binding {
170                    name,
171                    operator: _,
172                    operands,
173                    ty: _,
174                    loc: _,
175                }) => {
176                    *name = state.get(name);
177
178                    for op in operands {
179                        *op = state.get(op)
180                    }
181                }
182                crate::Statement::Register(Register {
183                    name,
184                    ty: _,
185                    clock,
186                    reset,
187                    initial: _,
188                    value,
189                    loc: _,
190                    traced,
191                }) => {
192                    *name = state.get(name);
193                    *clock = state.get(clock);
194                    reset.as_mut().map(|(trig, val)| {
195                        *trig = state.get(trig);
196                        *val = state.get(val);
197                    });
198                    *value = state.get(value);
199                    traced.as_mut().map(|traced| *traced = state.get(traced));
200                }
201                crate::Statement::Constant(_, _, _) => {}
202                crate::Statement::Assert(val) => val.inner = state.get(val),
203                crate::Statement::Set { target, value } => {
204                    target.inner = state.get(target);
205                    value.inner = state.get(value);
206                }
207                crate::Statement::WalTrace {
208                    name,
209                    val,
210                    suffix: _,
211                    ty: _,
212                } => {
213                    *name = state.get(name);
214                    *val = state.get(val);
215                }
216            }
217        }
218    }
219    state
220}