1use std::{fmt, str::FromStr};
8
9use crate::error::Error;
10
11#[derive(Debug, Clone, PartialEq, Eq, Copy)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub enum Logic {
15 False,
17 True,
19 X,
21 Z,
23}
24
25impl Logic {
26 pub fn unwrap(self) -> bool {
28 match self {
29 Logic::True => true,
30 Logic::False => false,
31 _ => panic!("Logic is not truthy"),
32 }
33 }
34
35 pub fn expect(self, msg: &str) -> bool {
37 match self {
38 Logic::True => true,
39 Logic::False => false,
40 _ => panic!("{}", msg),
41 }
42 }
43
44 pub fn is_dont_care(&self) -> bool {
46 matches!(self, Logic::X)
47 }
48
49 pub fn as_str(&self) -> &str {
51 match self {
52 Logic::True => "1'b1",
53 Logic::False => "1'b0",
54 Logic::X => "1'bx",
55 Logic::Z => "1'bz",
56 }
57 }
58
59 pub fn from_bool(b: bool) -> Logic {
61 if b { Logic::True } else { Logic::False }
62 }
63}
64
65impl std::ops::BitAnd for Logic {
66 type Output = Self;
67
68 fn bitand(self, rhs: Self) -> Self::Output {
69 match (self, rhs) {
70 (Logic::False, _) | (_, Logic::False) => Logic::False,
71 (Logic::True, Logic::True) => Logic::True,
72 (Logic::True, Logic::Z) | (Logic::Z, Logic::True) => Logic::X,
73 (Logic::X, _) | (_, Logic::X) | (Logic::Z, Logic::Z) => Logic::X,
74 }
75 }
76}
77
78impl std::ops::BitOr for Logic {
79 type Output = Self;
80
81 fn bitor(self, rhs: Self) -> Self::Output {
82 match (self, rhs) {
83 (Logic::True, _) | (_, Logic::True) => Logic::True,
84 (Logic::False, Logic::False) => Logic::False,
85 _ => Logic::X,
86 }
87 }
88}
89
90impl std::ops::Not for Logic {
91 type Output = Self;
92
93 fn not(self) -> Self::Output {
94 match self {
95 Logic::False => Logic::True,
96 Logic::True => Logic::False,
97 _ => Logic::X,
98 }
99 }
100}
101
102impl fmt::Display for Logic {
103 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
104 match self {
105 Logic::True => write!(f, "1'b1"),
106 Logic::False => write!(f, "1'b0"),
107 Logic::X => write!(f, "1'bx"),
108 Logic::Z => write!(f, "1'bz"),
109 }
110 }
111}
112
113impl From<bool> for Logic {
114 fn from(value: bool) -> Self {
115 if value { Logic::True } else { Logic::False }
116 }
117}
118
119impl FromStr for Logic {
120 type Err = Error;
121
122 fn from_str(s: &str) -> Result<Self, Self::Err> {
123 match s {
124 "1'b1" | "1'h1" => Ok(Logic::True),
125 "1'b0" | "1'h0" => Ok(Logic::False),
126 "1'bx" | "1'hx" => Ok(Logic::X),
127 "1'bz" | "1'hz" => Ok(Logic::Z),
128 _ => Err(Error::ParseError(s.to_string())),
129 }
130 }
131}
132
133pub fn r#true() -> Logic {
135 Logic::True
136}
137
138pub fn r#false() -> Logic {
140 Logic::False
141}
142
143pub fn dont_care() -> Logic {
145 Logic::X
146}
147
148pub fn high_z() -> Logic {
150 Logic::Z
151}