prjunnamed_pattern/
simple.rs

1use prjunnamed_netlist::{Cell, Const, Net, Trit, Value};
2
3use crate::{DesignDyn, NetOrValue, Pattern};
4
5pub struct PAny;
6
7impl PAny {
8    pub fn new() -> PAny {
9        PAny
10    }
11}
12
13impl<T: Clone> Pattern<T> for PAny {
14    type Capture = (T,);
15
16    #[inline]
17    fn execute(&self, _design: &dyn DesignDyn, target: &T) -> Option<Self::Capture> {
18        Some((target.clone(),))
19    }
20}
21
22pub struct PBind<P>(P);
23
24impl<P> PBind<P> {
25    pub fn new(pat: P) -> PBind<P> {
26        PBind(pat)
27    }
28}
29
30impl<T: Clone, P: Pattern<T>> Pattern<T> for PBind<P> {
31    type Capture = (T, P::Capture);
32
33    #[inline]
34    fn execute(&self, design: &dyn DesignDyn, target: &T) -> Option<Self::Capture> {
35        self.0.execute(design, target).and_then(|capture| Some((target.clone(), capture)))
36    }
37}
38
39pub struct PConst;
40
41impl PConst {
42    pub fn new() -> PConst {
43        PConst
44    }
45}
46
47impl Pattern<Net> for PConst {
48    type Capture = (Trit,);
49
50    #[inline]
51    fn execute(&self, _design: &dyn DesignDyn, target: &Net) -> Option<Self::Capture> {
52        Net::as_const(*target).map(|value| (value,))
53    }
54}
55
56impl Pattern<Value> for PConst {
57    type Capture = (Const,);
58
59    #[inline]
60    fn execute(&self, _design: &dyn DesignDyn, target: &Value) -> Option<Self::Capture> {
61        Value::as_const(&target).map(|value| (value,))
62    }
63}
64
65pub struct PZero;
66
67impl PZero {
68    pub fn new() -> PZero {
69        PZero
70    }
71}
72
73impl Pattern<u32> for PZero {
74    type Capture = ((),);
75
76    #[inline]
77    fn execute(&self, _design: &dyn DesignDyn, target: &u32) -> Option<Self::Capture> {
78        if *target == 0 {
79            Some(((),))
80        } else {
81            None
82        }
83    }
84}
85
86impl<T: NetOrValue> Pattern<T> for PZero {
87    type Capture = ((),);
88
89    #[inline]
90    fn execute(&self, _design: &dyn DesignDyn, target: &T) -> Option<Self::Capture> {
91        match target.as_const() {
92            Some(value) if value.iter().all(|net| net == Trit::Zero) => Some(((),)),
93            _ => None,
94        }
95    }
96}
97
98pub struct POnes;
99
100impl POnes {
101    pub fn new() -> POnes {
102        POnes
103    }
104}
105
106impl<T: NetOrValue> Pattern<T> for POnes {
107    type Capture = ((),);
108
109    #[inline]
110    fn execute(&self, _design: &dyn DesignDyn, target: &T) -> Option<Self::Capture> {
111        match target.as_const() {
112            Some(value) if value.is_empty() => None,
113            Some(value) if value.iter().all(|net| net == Trit::One) => Some(((),)),
114            _ => None,
115        }
116    }
117}
118
119pub struct PUndef;
120
121impl PUndef {
122    pub fn new() -> PUndef {
123        PUndef
124    }
125}
126
127impl<T: NetOrValue> Pattern<T> for PUndef {
128    type Capture = ((),);
129
130    #[inline]
131    fn execute(&self, _design: &dyn DesignDyn, target: &T) -> Option<Self::Capture> {
132        match target.as_const() {
133            Some(value) if value.is_empty() => None,
134            Some(value) if value.iter().all(|net| net == Trit::Undef) => Some(((),)),
135            _ => None,
136        }
137    }
138}
139
140pub struct PHasX;
141
142impl PHasX {
143    pub fn new() -> PHasX {
144        PHasX
145    }
146}
147
148impl<T: NetOrValue> Pattern<T> for PHasX {
149    type Capture = ((),);
150
151    #[inline]
152    fn execute(&self, _design: &dyn DesignDyn, target: &T) -> Option<Self::Capture> {
153        match target.as_const() {
154            Some(value) if value.has_undef() => Some(((),)),
155            _ => None,
156        }
157    }
158}
159
160pub struct PPow2;
161
162impl PPow2 {
163    pub fn new() -> PPow2 {
164        PPow2
165    }
166}
167
168impl<T: NetOrValue> Pattern<T> for PPow2 {
169    type Capture = (u32,);
170
171    #[inline]
172    fn execute(&self, _design: &dyn DesignDyn, target: &T) -> Option<Self::Capture> {
173        target.as_const().and_then(|value| value.as_power_of_two().map(|exp| (exp,)))
174    }
175}
176
177pub type POneHot = PPow2;
178
179pub struct PInput(&'static str);
180
181impl PInput {
182    pub fn new(name: &'static str) -> PInput {
183        PInput(name)
184    }
185}
186
187impl<T: NetOrValue> Pattern<T> for PInput {
188    type Capture = (T,);
189
190    #[inline]
191    fn execute(&self, design: &dyn DesignDyn, target: &T) -> Option<Self::Capture> {
192        if let Some(net) = target.iter().next() {
193            if let Ok((cell_ref, 0)) = design.find_cell(net) {
194                if let Cell::Input(name, _size) = &*cell_ref.get() {
195                    if target.as_value() == cell_ref.output() && name == self.0 {
196                        return Some((target.clone(),));
197                    }
198                }
199            }
200        }
201        None
202    }
203}
204
205pub struct PZExt<P>(P);
206
207impl<P> PZExt<P> {
208    pub fn new(pat: P) -> PZExt<P> {
209        PZExt(pat)
210    }
211}
212
213impl<P: Pattern<Value>> Pattern<Value> for PZExt<P> {
214    // The amount of extension bits can be found using: [PZExt@y [PAny@a]] => y.len() - a.len()
215    type Capture = (Value, P::Capture);
216
217    #[inline]
218    fn execute(&self, design: &dyn DesignDyn, target: &Value) -> Option<Self::Capture> {
219        let zext_count = target.iter().rev().take_while(|net| *net == Net::ZERO).count();
220        self.0.execute(design, &target.slice(..target.len() - zext_count)).map(|capture| (target.clone(), capture))
221    }
222}
223
224pub struct PSExt<P>(P);
225
226impl<P> PSExt<P> {
227    pub fn new(pat: P) -> PSExt<P> {
228        PSExt(pat)
229    }
230}
231
232impl<P: Pattern<Value>> Pattern<Value> for PSExt<P> {
233    // The amount of extension bits can be found using: [PZExt@y [PAny@a]] => y.len() - a.len()
234    type Capture = (Value, P::Capture);
235
236    #[inline]
237    fn execute(&self, design: &dyn DesignDyn, target: &Value) -> Option<Self::Capture> {
238        if target.is_empty() {
239            return None;
240        }
241        let sext_count = target.iter().rev().take_while(|net| *net == target.msb()).count() - 1;
242        self.0.execute(design, &target.slice(..target.len() - sext_count)).map(|capture| (target.clone(), capture))
243    }
244}