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