Skip to main content

prjunnamed_netlist/
value.rs

1use std::{
2    borrow::Cow,
3    fmt::{Debug, Display},
4    ops::{Index, IndexMut},
5    hash::Hash,
6    slice::SliceIndex,
7};
8
9use crate::{Const, Design, Trit};
10
11/// A net is a driver in the design: a reference to a single position from
12/// the output of a [`Cell`].
13///
14/// Constant nets are represented as outputs of three singleton [`Cell::Const`] cells that are always present at fixed positions in the design.
15///
16/// [`Cell`]: crate::Cell
17#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
18pub struct Net {
19    pub(crate) index: u32,
20}
21
22impl Net {
23    pub const UNDEF: Net = Net { index: 2 };
24    pub const ZERO: Net = Net { index: 0 };
25    pub const ONE: Net = Net { index: 1 };
26
27    pub fn as_const(self) -> Option<Trit> {
28        if self == Self::UNDEF {
29            Some(Trit::Undef)
30        } else if self == Self::ZERO {
31            Some(Trit::Zero)
32        } else if self == Self::ONE {
33            Some(Trit::One)
34        } else {
35            None
36        }
37    }
38
39    pub(crate) fn from_cell_index(cell_index: usize) -> Net {
40        Net { index: cell_index as u32 }
41    }
42
43    pub(crate) fn as_cell_index(self) -> usize {
44        self.index as usize
45    }
46
47    pub fn is_const(self) -> bool {
48        self.as_const().is_some()
49    }
50
51    pub fn visit(self, mut f: impl FnMut(Net)) {
52        f(self)
53    }
54
55    pub fn visit_mut(&mut self, mut f: impl FnMut(&mut Net)) {
56        f(self)
57    }
58
59    pub fn repeat(self, count: usize) -> Value {
60        Value::from_iter(std::iter::repeat_n(self, count))
61    }
62}
63
64impl From<bool> for Net {
65    fn from(value: bool) -> Self {
66        match value {
67            false => Net::ZERO,
68            true => Net::ONE,
69        }
70    }
71}
72
73impl From<Trit> for Net {
74    fn from(value: Trit) -> Self {
75        match value {
76            Trit::Undef => Self::UNDEF,
77            Trit::Zero => Self::ZERO,
78            Trit::One => Self::ONE,
79        }
80    }
81}
82
83impl From<&Net> for Net {
84    fn from(net: &Net) -> Self {
85        *net
86    }
87}
88
89impl TryFrom<Value> for Net {
90    type Error = ();
91
92    fn try_from(value: Value) -> Result<Self, Self::Error> {
93        value.as_net().ok_or(())
94    }
95}
96
97impl Debug for Net {
98    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
99        match *self {
100            Net::ZERO => write!(f, "Net::ZERO"),
101            Net::ONE => write!(f, "Net::ONE"),
102            Net::UNDEF => write!(f, "Net::UNDEF"),
103            _ => {
104                write!(f, "Net::from_cell({cell_index})", cell_index = self.index)
105            }
106        }
107    }
108}
109
110impl Display for Net {
111    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
112        match *self {
113            Net::ZERO => write!(f, "0"),
114            Net::ONE => write!(f, "1"),
115            Net::UNDEF => write!(f, "X"),
116            _ => {
117                write!(f, "%_{cell_index}", cell_index = self.index)
118            }
119        }
120    }
121}
122
123#[derive(Clone)]
124enum ValueRepr {
125    None,
126    Some(Net),
127    Many(Vec<Net>),
128}
129
130impl ValueRepr {
131    fn as_slice(&self) -> &[Net] {
132        match self {
133            ValueRepr::None => &[],
134            ValueRepr::Some(net) => std::slice::from_ref(net),
135            ValueRepr::Many(nets) => nets.as_slice(),
136        }
137    }
138
139    fn as_slice_mut(&mut self) -> &mut [Net] {
140        match self {
141            ValueRepr::None => &mut [],
142            ValueRepr::Some(net) => std::slice::from_mut(net),
143            ValueRepr::Many(nets) => nets.as_mut_slice(),
144        }
145    }
146
147    fn push(&mut self, new_net: Net) {
148        match self {
149            ValueRepr::None => *self = ValueRepr::Some(new_net),
150            ValueRepr::Some(net) => *self = ValueRepr::Many(vec![*net, new_net]),
151            ValueRepr::Many(nets) => {
152                nets.push(new_net);
153            }
154        }
155    }
156}
157
158impl PartialEq for ValueRepr {
159    fn eq(&self, other: &Self) -> bool {
160        match (self, other) {
161            (ValueRepr::Some(lft), ValueRepr::Some(rgt)) => lft.eq(rgt),
162            _ => self.as_slice().eq(other.as_slice()),
163        }
164    }
165}
166
167impl Eq for ValueRepr {}
168
169impl PartialOrd for ValueRepr {
170    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
171        Some(self.cmp(other))
172    }
173}
174
175impl Ord for ValueRepr {
176    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
177        match (self, other) {
178            (ValueRepr::Some(lft), ValueRepr::Some(rgt)) => lft.cmp(rgt),
179            _ => self.as_slice().cmp(other.as_slice()),
180        }
181    }
182}
183
184impl Hash for ValueRepr {
185    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
186        self.as_slice().hash(state);
187    }
188}
189
190/// A value is a (possibly empty) sequence of [`Net`]s.
191#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
192pub struct Value(ValueRepr);
193
194impl Value {
195    /// Creates an empty value.
196    pub fn new() -> Self {
197        Value(ValueRepr::None)
198    }
199
200    /// Creates an all-`0` value of given width.
201    pub fn zero(width: usize) -> Self {
202        Net::ZERO.repeat(width)
203    }
204
205    /// Creates an all-`1` value of given width.
206    pub fn ones(width: usize) -> Self {
207        Net::ONE.repeat(width)
208    }
209
210    /// Creates an all-`X` value of given width.
211    pub fn undef(width: usize) -> Self {
212        Net::UNDEF.repeat(width)
213    }
214
215    /// Creates a reference to `count` outputs of cell at position `cell_index` in their natural order.
216    pub(crate) fn from_cell_range(cell_index: usize, count: usize) -> Value {
217        Value::from_iter((cell_index..(cell_index + count)).map(Net::from_cell_index))
218    }
219
220    pub fn len(&self) -> usize {
221        self.0.as_slice().len()
222    }
223
224    pub fn is_empty(&self) -> bool {
225        self.0.as_slice().is_empty()
226    }
227
228    pub fn iter(&self) -> impl DoubleEndedIterator<Item = Net> + ExactSizeIterator + '_ {
229        self.0.as_slice().iter().copied()
230    }
231
232    pub fn iter_mut(&mut self) -> impl DoubleEndedIterator<Item = &mut Net> + ExactSizeIterator + '_ {
233        self.0.as_slice_mut().iter_mut()
234    }
235
236    pub fn push(&mut self, new_net: impl Into<Net>) {
237        self.0.push(new_net.into())
238    }
239
240    pub fn is_undef(&self) -> bool {
241        self.iter().all(|net| net == Net::UNDEF)
242    }
243
244    pub fn is_zero(&self) -> bool {
245        self.iter().all(|net| net == Net::ZERO)
246    }
247
248    pub fn is_ones(&self) -> bool {
249        self.iter().all(|net| net == Net::ONE)
250    }
251
252    pub fn lsb(&self) -> Net {
253        self[0]
254    }
255
256    pub fn msb(&self) -> Net {
257        self[self.len() - 1]
258    }
259
260    pub fn has_undef(&self) -> bool {
261        self.iter().any(|net| net == Net::UNDEF)
262    }
263
264    pub fn as_const(&self) -> Option<Const> {
265        let nets = self.0.as_slice();
266        if nets.iter().all(|net| net.is_const()) {
267            Some(Const::from_iter(nets.iter().map(|net| net.as_const().unwrap())))
268        } else {
269            None
270        }
271    }
272
273    pub fn as_net(&self) -> Option<Net> {
274        if self.len() == 1 { Some(self[0]) } else { None }
275    }
276
277    pub fn unwrap_net(&self) -> Net {
278        self.as_net().unwrap()
279    }
280
281    pub fn concat<'a>(&self, other: impl Into<Cow<'a, Value>>) -> Self {
282        Value::from_iter(self.iter().chain(other.into().iter()))
283    }
284
285    pub fn repeat(&self, count: usize) -> Self {
286        Value::from_iter((0..count).flat_map(|_| self))
287    }
288
289    pub fn slice(&self, range: impl std::ops::RangeBounds<usize>) -> Value {
290        Value::from(&self[(range.start_bound().cloned(), range.end_bound().cloned())])
291    }
292
293    pub fn zext(&self, width: usize) -> Self {
294        assert!(width >= self.len());
295        self.concat(Value::zero(width - self.len()))
296    }
297
298    pub fn sext(&self, width: usize) -> Self {
299        assert!(!self.is_empty());
300        assert!(width >= self.len());
301        Value::from_iter(self.iter().chain(std::iter::repeat_n(self.msb(), width - self.len())))
302    }
303
304    fn shift_count(value: &Const, stride: u32) -> usize {
305        let stride = stride as usize;
306        let mut result: usize = 0;
307        for (index, trit) in value.iter().enumerate() {
308            if trit == Trit::One {
309                if index >= usize::BITS as usize {
310                    return usize::MAX;
311                } else {
312                    result |= 1 << index;
313                }
314            }
315        }
316        result.saturating_mul(stride)
317    }
318
319    pub fn shl<'a>(&self, other: impl Into<Cow<'a, Const>>, stride: u32) -> Value {
320        let other = other.into();
321        if other.has_undef() {
322            return Value::undef(self.len());
323        }
324        let shcnt = Self::shift_count(&other, stride);
325        if shcnt >= self.len() {
326            return Value::zero(self.len());
327        }
328        Value::zero(shcnt).concat(Value::from(&self[..self.len() - shcnt]))
329    }
330
331    pub fn ushr<'a>(&self, other: impl Into<Cow<'a, Const>>, stride: u32) -> Value {
332        let other = other.into();
333        if other.has_undef() {
334            return Value::undef(self.len());
335        }
336        let shcnt = Self::shift_count(&other, stride);
337        if shcnt >= self.len() {
338            return Value::zero(self.len());
339        }
340        Value::from(&self[shcnt..]).zext(self.len())
341    }
342
343    pub fn sshr<'a>(&self, other: impl Into<Cow<'a, Const>>, stride: u32) -> Value {
344        let other = other.into();
345        if other.has_undef() {
346            return Value::undef(self.len());
347        }
348        let shcnt = Self::shift_count(&other, stride);
349        if shcnt >= self.len() {
350            return Value::from(self.msb()).sext(self.len());
351        }
352        Value::from(&self[shcnt..]).sext(self.len())
353    }
354
355    pub fn xshr<'a>(&self, other: impl Into<Cow<'a, Const>>, stride: u32) -> Value {
356        let other = other.into();
357        if other.has_undef() {
358            return Value::undef(self.len());
359        }
360        let shcnt = Self::shift_count(&other, stride);
361        if shcnt >= self.len() {
362            return Value::undef(self.len());
363        }
364        Value::from(&self[shcnt..]).concat(Value::undef(shcnt))
365    }
366
367    pub fn visit(&self, mut f: impl FnMut(Net)) {
368        for net in self.iter() {
369            f(net)
370        }
371    }
372
373    pub fn visit_mut(&mut self, mut f: impl FnMut(&mut Net)) {
374        for net in self.iter_mut() {
375            f(net)
376        }
377    }
378}
379
380impl Default for Value {
381    fn default() -> Self {
382        Value::new()
383    }
384}
385
386impl Debug for Value {
387    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
388        write!(f, "Value::from_iter([")?;
389        for (index, net) in self.iter().enumerate() {
390            if index != 0 {
391                write!(f, ", ")?;
392            }
393            write!(f, "{net:?}")?;
394        }
395        write!(f, "])")?;
396        Ok(())
397    }
398}
399
400impl Display for Value {
401    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
402        if self.is_empty() {
403            write!(f, "[]")
404        } else if self.len() == 1 {
405            write!(f, "{}", self[0])
406        } else {
407            write!(f, "[")?;
408            for net in self.iter().rev() {
409                write!(f, " {net}")?;
410            }
411            write!(f, " ]")
412        }
413    }
414}
415
416impl<I: SliceIndex<[Net]>> Index<I> for Value {
417    type Output = I::Output;
418
419    fn index(&self, index: I) -> &Self::Output {
420        &self.0.as_slice()[index]
421    }
422}
423
424impl<I: SliceIndex<[Net]>> IndexMut<I> for Value {
425    fn index_mut(&mut self, index: I) -> &mut Self::Output {
426        &mut self.0.as_slice_mut()[index]
427    }
428}
429
430impl Extend<Net> for Value {
431    fn extend<T: IntoIterator<Item = Net>>(&mut self, iter: T) {
432        for net in iter {
433            self.push(net);
434        }
435    }
436}
437
438impl From<&Value> for Value {
439    fn from(value: &Value) -> Self {
440        value.clone()
441    }
442}
443
444impl From<Net> for Value {
445    fn from(net: Net) -> Self {
446        Value(ValueRepr::Some(net))
447    }
448}
449
450impl From<&Net> for Value {
451    fn from(net: &Net) -> Self {
452        Value::from(*net)
453    }
454}
455
456impl From<Trit> for Value {
457    fn from(trit: Trit) -> Self {
458        Value(ValueRepr::Some(trit.into()))
459    }
460}
461
462impl From<&[Net]> for Value {
463    fn from(nets: &[Net]) -> Self {
464        Value::from_iter(nets.iter().cloned())
465    }
466}
467
468impl From<Vec<Net>> for Value {
469    fn from(nets: Vec<Net>) -> Self {
470        Value::from(&nets[..])
471    }
472}
473
474impl From<&Const> for Value {
475    fn from(value: &Const) -> Self {
476        Value::from_iter(value.into_iter().map(Net::from))
477    }
478}
479
480impl From<Const> for Value {
481    fn from(value: Const) -> Self {
482        Value::from(&value)
483    }
484}
485
486impl From<Value> for Cow<'_, Value> {
487    fn from(value: Value) -> Self {
488        Cow::Owned(value)
489    }
490}
491
492impl From<Net> for Cow<'_, Value> {
493    fn from(value: Net) -> Self {
494        Cow::Owned(Value::from(value))
495    }
496}
497
498impl From<Trit> for Cow<'_, Value> {
499    fn from(value: Trit) -> Self {
500        Cow::Owned(Value::from(Net::from(value)))
501    }
502}
503
504impl From<&Const> for Cow<'_, Value> {
505    fn from(value: &Const) -> Self {
506        Cow::Owned(Value::from(value))
507    }
508}
509
510impl From<Const> for Cow<'_, Value> {
511    fn from(value: Const) -> Self {
512        Cow::Owned(Value::from(value))
513    }
514}
515
516impl<'a> From<&'a Value> for Cow<'a, Value> {
517    fn from(value: &'a Value) -> Self {
518        Cow::Borrowed(value)
519    }
520}
521
522impl FromIterator<Net> for Value {
523    fn from_iter<T: IntoIterator<Item = Net>>(iter: T) -> Self {
524        let mut iter = iter.into_iter();
525        match iter.size_hint() {
526            (_, Some(0 | 1)) => {
527                let mut value = match iter.next() {
528                    None => Value::new(),
529                    Some(net) => Value::from(net),
530                };
531                for net in iter {
532                    value.push(net);
533                }
534                value
535            }
536            _ => Value(ValueRepr::Many(iter.collect())),
537        }
538    }
539}
540
541impl<'a> IntoIterator for &'a Value {
542    type Item = Net;
543    type IntoIter = std::iter::Copied<std::slice::Iter<'a, Net>>;
544
545    fn into_iter(self) -> Self::IntoIter {
546        self.0.as_slice().iter().copied()
547    }
548}
549
550pub struct ValueIntoIter {
551    repr: ValueRepr,
552    index: usize,
553}
554
555impl Iterator for ValueIntoIter {
556    type Item = Net;
557
558    fn next(&mut self) -> Option<Self::Item> {
559        let item = self.repr.as_slice().get(self.index).cloned();
560        if item.is_some() {
561            self.index += 1;
562        }
563        item
564    }
565}
566
567impl IntoIterator for Value {
568    type Item = Net;
569    type IntoIter = ValueIntoIter;
570
571    fn into_iter(self) -> Self::IntoIter {
572        ValueIntoIter { repr: self.0, index: 0 }
573    }
574}
575
576/// A control net is a [`Net`] that can be negated.
577#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
578pub enum ControlNet {
579    Pos(Net),
580    Neg(Net),
581}
582
583impl ControlNet {
584    pub const UNDEF: ControlNet = ControlNet::Pos(Net::UNDEF);
585    pub const ZERO: ControlNet = ControlNet::Pos(Net::ZERO);
586    pub const ONE: ControlNet = ControlNet::Pos(Net::ONE);
587
588    pub fn from_net_invert(net: Net, invert: bool) -> Self {
589        match invert {
590            false => ControlNet::Pos(net),
591            true => ControlNet::Neg(net),
592        }
593    }
594
595    pub fn net(self) -> Net {
596        match self {
597            Self::Pos(net) => net,
598            Self::Neg(net) => net,
599        }
600    }
601
602    pub fn is_positive(self) -> bool {
603        matches!(self, Self::Pos(_))
604    }
605
606    pub fn is_negative(self) -> bool {
607        matches!(self, Self::Neg(_))
608    }
609
610    pub fn is_active(self) -> Option<bool> {
611        match self {
612            Self::Pos(net) if net == Net::ZERO => Some(false),
613            Self::Neg(net) if net == Net::ONE => Some(false),
614            Self::Pos(net) if net == Net::ONE => Some(true),
615            Self::Neg(net) if net == Net::ZERO => Some(true),
616            _ => None,
617        }
618    }
619
620    pub fn is_always(self, active: bool) -> bool {
621        self.is_active() == Some(active)
622    }
623
624    pub fn is_const(self) -> bool {
625        self.net().as_const().is_some()
626    }
627
628    pub fn canonicalize(self) -> Self {
629        match self {
630            Self::Neg(net) if net == Net::UNDEF => Self::Pos(net),
631            Self::Neg(net) if net == Net::ZERO => Self::Pos(Net::ONE),
632            Self::Neg(net) if net == Net::ONE => Self::Pos(Net::ZERO),
633            _ => self,
634        }
635    }
636
637    pub fn into_pos(self, design: &Design) -> Net {
638        match self {
639            ControlNet::Pos(net) => net,
640            ControlNet::Neg(net) => {
641                if let Some(trit) = net.as_const() {
642                    Net::from(!trit)
643                } else {
644                    design.add_not(net).unwrap_net()
645                }
646            }
647        }
648    }
649
650    pub fn into_neg(self, design: &Design) -> Net {
651        match self {
652            ControlNet::Pos(net) => {
653                if let Some(trit) = net.as_const() {
654                    Net::from(!trit)
655                } else {
656                    design.add_not(net).unwrap_net()
657                }
658            }
659            ControlNet::Neg(net) => net,
660        }
661    }
662
663    pub fn visit(self, f: impl FnMut(Net)) {
664        match self {
665            ControlNet::Pos(net) => net.visit(f),
666            ControlNet::Neg(net) => net.visit(f),
667        }
668    }
669
670    pub fn visit_mut(&mut self, f: impl FnMut(&mut Net)) {
671        match self {
672            ControlNet::Pos(net) => net.visit_mut(f),
673            ControlNet::Neg(net) => net.visit_mut(f),
674        }
675    }
676}
677
678impl std::ops::Not for ControlNet {
679    type Output = ControlNet;
680
681    fn not(self) -> Self::Output {
682        match self {
683            ControlNet::Pos(net) => ControlNet::Neg(net),
684            ControlNet::Neg(net) => ControlNet::Pos(net),
685        }
686        .canonicalize()
687    }
688}
689
690impl From<Net> for ControlNet {
691    fn from(net: Net) -> Self {
692        ControlNet::Pos(net)
693    }
694}
695
696impl Display for ControlNet {
697    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
698        match self {
699            ControlNet::Pos(net) => write!(f, "{net}"),
700            ControlNet::Neg(net) => write!(f, "!{net}"),
701        }
702    }
703}
704
705#[cfg(test)]
706mod test {
707    use crate::{Net, Trit, Value};
708
709    #[test]
710    fn test_net() {
711        assert_eq!(Net::from(Trit::Zero), Net::ZERO);
712        assert_eq!(Net::from(Trit::One), Net::ONE);
713        assert_eq!(Net::from(Trit::Undef), Net::UNDEF);
714        assert_eq!(Net::from_cell_index(3), Net { index: 3 });
715    }
716
717    #[test]
718    fn test_from_bool() {
719        assert_eq!(Net::from(false), Net::ZERO);
720        assert_eq!(Net::from(true), Net::ONE);
721    }
722
723    #[test]
724    fn test_from_trit() {
725        assert_eq!(Net::from(Trit::Zero), Net::ZERO);
726        assert_eq!(Net::from(Trit::One), Net::ONE);
727        assert_eq!(Net::from(Trit::Undef), Net::UNDEF);
728    }
729
730    #[test]
731    fn test_net_debug() {
732        assert_eq!(format!("{:?}", Net::ZERO), "Net::ZERO");
733        assert_eq!(format!("{:?}", Net::ONE), "Net::ONE");
734        assert_eq!(format!("{:?}", Net::UNDEF), "Net::UNDEF");
735        assert_eq!(format!("{:?}", Net::from_cell_index(3)), "Net::from_cell(3)");
736    }
737
738    #[test]
739    fn test_value() {
740        let v01 = Value::from_iter([Net::ONE, Net::ZERO]);
741        assert_eq!(v01.into_iter().collect::<Vec<_>>(), vec![Net::ONE, Net::ZERO]);
742    }
743}