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