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