1use std::fmt::{Display, Debug};
2use num_bigint::{BigInt, ParseBigIntError};
3use num_traits::{FromPrimitive, Num};
4use std::str::FromStr;
5
6#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
7pub struct Int(BigInt);
8
9impl Int {
10 pub fn to_u32(&self) -> u32 {
11 let (_, digits_u32) = self.0.to_u32_digits();
12 assert!(digits_u32.len() <= 1,
13 "to_u32 should only be called on small bigints that can be represented by a u32 len {}",
14 digits_u32.len());
15 *digits_u32.get(0).unwrap_or(&0)
16 }
17
18 pub fn from_str_radix(num: &str, radix: u32) -> Result<Self, ParseBigIntError> {
19 let bigint = BigInt::from_str_radix(num, radix)?;
20 Ok(Self {
21 0: bigint
22 })
23 }
24
25 pub fn from_str(num: &str) -> Result<Self, ParseBigIntError> {
26 let bigint = BigInt::from_str(num)?;
27 Ok(Self {
28 0: bigint
29 })
30 }
31}
32
33impl From<u32> for Int {
34 fn from(value: u32) -> Self {
35 Self {
36 0: BigInt::from_u32(value)
37 .expect(&format!("BigInt from_u32 {}", value))
38 }
39 }
40}
41
42impl Debug for Int {
43 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44 write!(f, "0h{}", self.0.to_str_radix(16).to_uppercase())
45 }
46}
47
48impl Display for Int {
49 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50 write!(f, "{}", self.0.to_string())
51 }
52}
53
54#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
55pub struct Info(pub String);
56
57impl Display for Info {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 write!(f, "@[{}]", self.0)
60 }
61}
62
63#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
64pub struct Width(pub u32);
65
66impl Display for Width {
67 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68 write!(f, "{}", self.0)
69 }
70}
71
72#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
73pub enum Identifier {
74 ID(Int),
75 Name(String),
76}
77
78impl Display for Identifier {
79 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80 match self {
81 Self::ID(x) => write!(f, "{:?}", x),
82 Self::Name(x) => write!(f, "{}", x)
83 }
84 }
85}
86
87#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
88pub struct Float {
89 pub integer: u32,
90 pub decimal: u32,
91}
92
93impl Float {
94 pub fn new(integer: u32, decimal: u32) -> Self {
95 Self { integer, decimal }
96 }
97}
98
99impl Display for Float {
100 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101 write!(f, "{}.{}", self.integer, self.decimal)
102 }
103}
104
105#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
106pub enum Reference {
107 Ref(Identifier),
108 RefDot(Box<Reference>, Identifier),
109 RefIdxInt(Box<Reference>, Int),
110 RefIdxExpr(Box<Reference>, Box<Expr>)
111}
112
113impl Display for Reference {
114 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
115 match self {
116 Self::Ref(name) => write!(f, "{}", name),
117 Self::RefDot(r, name) => write!(f, "{}.{}", r, name),
118 Self::RefIdxInt(r, int) => write!(f, "{}[{:?}]", r, int),
119 Self::RefIdxExpr(r, expr) => write!(f, "{}[{}]", r, expr),
120 }
121 }
122}
123
124impl Debug for Reference {
125 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
126 write!(f, "{}", self)
127 }
128}
129
130impl Reference {
131 pub fn root(&self) -> Identifier {
132 match self {
133 Self::Ref(name) => name.clone(),
134 Self::RefDot(parent, _) |
135 Self::RefIdxInt(parent, _) |
136 Self::RefIdxExpr(parent, _) => {
137 parent.root()
138 }
139 }
140 }
141}
142
143#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
144pub enum PrimOp2Expr {
145 Add,
146 Sub,
147 Mul,
148 Div,
149 Rem,
150 Lt,
151 Leq,
152 Gt,
153 Geq,
154 Eq,
155 Neq,
156 Dshl,
157 Dshr,
158 And,
159 Or,
160 Xor,
161 Cat,
162}
163
164#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
165pub enum PrimOp1Expr {
166 AsUInt,
167 AsSInt,
168 AsClock,
169 AsAsyncReset,
170 Cvt,
171 Neg,
172 Not,
173 Andr,
174 Orr,
175 Xorr,
176}
177
178
179#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
180pub enum PrimOp1Expr1Int {
181 Pad,
182 Shl,
183 Shr,
184 Head,
185 Tail,
186}
187
188#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
189pub enum PrimOp1Expr2Int {
190 BitSelRange,
191}
192
193impl From<String> for PrimOp2Expr {
194 fn from(value: String) -> Self {
195 match value.as_str() {
196 "add" => { Self::Add },
197 "sub" => { Self::Sub },
198 "mul" => { Self::Mul },
199 "div" => { Self::Div },
200 "rem" => { Self::Rem },
201 "lt" => { Self::Lt },
202 "leq" => { Self::Leq },
203 "gt" => { Self::Gt },
204 "geq" => { Self::Geq },
205 "eq" => { Self::Eq },
206 "neq" => { Self::Neq },
207 "dshl" => { Self::Dshl },
208 "dshr" => { Self::Dshr },
209 "and" => { Self::And },
210 "or" => { Self::Or },
211 "xor" => { Self::Xor },
212 "cat" => { Self::Cat },
213 _ => {
214 panic!("Unrecognized operator {}", value);
215 }
216 }
217 }
218}
219
220impl Display for PrimOp2Expr {
221 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
222 let s = match self {
223 PrimOp2Expr::Add => "add",
224 PrimOp2Expr::Sub => "sub",
225 PrimOp2Expr::Mul => "mul",
226 PrimOp2Expr::Div => "div",
227 PrimOp2Expr::Rem => "rem",
228 PrimOp2Expr::Lt => "lt",
229 PrimOp2Expr::Leq => "leq",
230 PrimOp2Expr::Gt => "gt",
231 PrimOp2Expr::Geq => "geq",
232 PrimOp2Expr::Eq => "eq",
233 PrimOp2Expr::Neq => "neq",
234 PrimOp2Expr::Dshl => "dshl",
235 PrimOp2Expr::Dshr => "dshr",
236 PrimOp2Expr::And => "and",
237 PrimOp2Expr::Or => "or",
238 PrimOp2Expr::Xor => "xor",
239 PrimOp2Expr::Cat => "cat",
240 };
241 write!(f, "{s}")
242 }
243}
244
245impl From<String> for PrimOp1Expr {
246 fn from(value: String) -> Self {
247 match value.as_str() {
248 "asUInt" => { Self::AsUInt },
249 "asSInt" => { Self::AsSInt },
250 "asClock" => { Self::AsClock },
251 "asAsyncReset" => { Self::AsAsyncReset },
252 "cvt" => { Self::Cvt },
253 "neg" => { Self::Neg },
254 "not" => { Self::Not },
255 "andr" => { Self::Andr },
256 "orr" => { Self::Orr },
257 "xorr" => { Self::Xorr },
258 _ => {
259 panic!("Unrecognized operator {}", value);
260 }
261 }
262 }
263}
264
265impl std::fmt::Display for PrimOp1Expr {
266 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
267 let s = match self {
268 PrimOp1Expr::AsUInt => "asUInt",
269 PrimOp1Expr::AsSInt => "asSInt",
270 PrimOp1Expr::AsClock => "asClock",
271 PrimOp1Expr::AsAsyncReset => "asAsyncReset",
272 PrimOp1Expr::Cvt => "cvt",
273 PrimOp1Expr::Neg => "neg",
274 PrimOp1Expr::Not => "not",
275 PrimOp1Expr::Andr => "andr",
276 PrimOp1Expr::Orr => "orr",
277 PrimOp1Expr::Xorr => "xorr",
278 };
279 write!(f, "{s}")
280 }
281}
282
283impl From<String> for PrimOp1Expr1Int {
284 fn from(value: String) -> Self {
285 match value.as_str() {
286 "pad" => { Self::Pad },
287 "shl" => { Self::Shl },
288 "shr" => { Self::Shr },
289 "head" => { Self::Head },
290 "tail" => { Self::Tail },
291 _ => { panic!("Unrecognized PrimOp1Expr1Int"); }
292 }
293 }
294}
295
296
297impl std::fmt::Display for PrimOp1Expr1Int {
298 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
299 let s = match self {
300 PrimOp1Expr1Int::Pad => "pad",
301 PrimOp1Expr1Int::Shl => "shl",
302 PrimOp1Expr1Int::Shr => "shr",
303 PrimOp1Expr1Int::Head => "head",
304 PrimOp1Expr1Int::Tail => "tail",
305 };
306 write!(f, "{s}")
307 }
308}
309
310impl From<String> for PrimOp1Expr2Int {
311 fn from(value: String) -> Self {
312 assert!(value.contains("bit"));
313 Self::BitSelRange
314 }
315}
316
317impl std::fmt::Display for PrimOp1Expr2Int {
318 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
319 let s = match self {
320 PrimOp1Expr2Int::BitSelRange => "bits",
321 };
322 write!(f, "{s}")
323 }
324}
325
326pub type Exprs = Vec<Box<Expr>>;
327
328fn fmt_exprs(exprs: &Exprs) -> String {
329 let mut ret = "".to_string();
330 let len = exprs.len();
331 for (id, e) in exprs.iter().enumerate() {
332 ret.push_str(&format!("{}", e));
333 if id != len - 1 {
334 ret.push_str(", ");
335 }
336 }
337 return ret;
338}
339
340#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
341pub enum Expr {
342 UIntNoInit(Width),
343 UIntInit(Width, Int),
344 SIntNoInit(Width),
345 SIntInit(Width, Int),
346 Reference(Reference),
347 Mux(Box<Expr>, Box<Expr>, Box<Expr>),
348 ValidIf(Box<Expr>, Box<Expr>),
349 PrimOp2Expr(PrimOp2Expr, Box<Expr>, Box<Expr>),
350 PrimOp1Expr(PrimOp1Expr, Box<Expr>),
351 PrimOp1Expr1Int(PrimOp1Expr1Int, Box<Expr>, Int),
352 PrimOp1Expr2Int(PrimOp1Expr2Int, Box<Expr>, Int, Int),
353}
354
355impl Expr {
356 pub fn parse_radixint(s: &str) -> Result<Int, String> {
357 if let Some(num) = s.strip_prefix("0b") {
358 Int::from_str_radix(num, 2).map_err(|e| e.to_string())
359 } else if let Some(num) = s.strip_prefix("0o") {
360 Int::from_str_radix(num, 8).map_err(|e| e.to_string())
361 } else if let Some(num) = s.strip_prefix("0d") {
362 Int::from_str_radix(num, 10).map_err(|e| e.to_string())
363 } else if let Some(num) = s.strip_prefix("0h") {
364 Int::from_str_radix(num, 16).map_err(|e| e.to_string())
365 } else {
366 Err(format!("Invalid number format: {}", s))
367 }
368 }
369}
370
371impl Display for Expr {
372 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
373 match self {
374 Expr::UIntNoInit(w) => write!(f, "UInt<{}>()", w),
375 Expr::UIntInit(w, init) => write!(f, "UInt<{}>({:?})", w, init),
376 Expr::SIntNoInit(w) => write!(f, "SInt<{}>()", w),
377 Expr::SIntInit(w, init) => write!(f, "SInt<{}>({:?})", w, init),
378 Expr::Reference(r) => write!(f, "{}", r),
379 Expr::Mux(cond, te, fe) => write!(f, "mux({}, {}, {})", cond, te, fe),
380 Expr::ValidIf(cond, te) => write!(f, "validif({}, {})", cond, te),
381 Expr::PrimOp2Expr(op, a, b) => write!(f, "{}({}, {})", op, a, b),
382 Expr::PrimOp1Expr(op, a) => write!(f, "{}({})", op, a),
383 Expr::PrimOp1Expr1Int(op, a, b) => write!(f, "{}({}, {})", op, a, b),
384 Expr::PrimOp1Expr2Int(op, a, b, c) => write!(f, "{}({}, {}, {})", op, a, b, c),
385 }
386 }
387}
388
389#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
390pub enum TypeGround {
391 Clock,
392 Reset,
393 AsyncReset,
394 UInt(Option<Width>),
395 SInt(Option<Width>),
396}
400
401impl Display for TypeGround {
402 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
403 match self {
404 Self::Clock => { write!(f, "Clock") }
405 Self::Reset => { write!(f, "Reset") }
406 Self::AsyncReset => { write!(f, "AsyncReset") }
407 Self::UInt(w_opt) => {
408 if let Some(w) = w_opt {
409 write!(f, "UInt<{}>", w)
410 } else {
411 write!(f, "UInt")
412 }
413 }
414 Self::SInt(w_opt) => {
415 if let Some(w) = w_opt {
416 write!(f, "SInt<{}>", w)
417 } else {
418 write!(f, "SInt")
419 }
420 }
421 }
422 }
423}
424
425pub type Fields = Vec<Box<Field>>;
426
427#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
428pub enum Field {
429 Straight(Identifier, Box<Type>),
430 Flipped(Identifier, Box<Type>),
431}
432
433impl Display for Field {
434 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
435 match self {
436 Self::Straight(id, tpe) => {
437 write!(f, "{}: {}", id, tpe)
438 }
439 Self::Flipped(id, tpe) => {
440 write!(f, "flip {}: {}", id, tpe)
441 }
442 }
443 }
444}
445
446#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
447pub enum TypeAggregate {
448 Fields(Box<Fields>),
449 Array(Box<Type>, Int),
450}
451
452impl Display for TypeAggregate {
453 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
454 match self {
455 Self::Fields(fields) => {
456 write!(f, "{{ ")?;
457 for field in fields.iter() {
458 write!(f, "{}, ", field)?;
459 }
460 write!(f, " }}")
461 }
462 Self::Array(tpe, idx) => {
463 write!(f, "{}[{:?}]", tpe, idx)
464 }
465 }
466 }
467}
468
469#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
470pub enum Type {
471 TypeGround(TypeGround),
472 ConstTypeGround(TypeGround),
473 TypeAggregate(Box<TypeAggregate>),
474 ConstTypeAggregate(Box<TypeAggregate>),
475}
476
477impl Display for Type {
478 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
479 match self {
480 Self::TypeGround(tg) => write!(f, "{}", tg),
481 Self::ConstTypeGround(tg) => write!(f, "{}", tg),
482 Self::TypeAggregate(ta) => write!(f, "{}", ta),
483 Self::ConstTypeAggregate(ta) => write!(f, "{}", ta),
484 }
485 }
486}
487
488#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
489pub enum ChirrtlMemoryReadUnderWrite {
490 #[default]
491 Undefined,
492 Old,
493 New
494}
495
496#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
497pub enum ChirrtlMemory {
498 SMem(Identifier, Type, Option<ChirrtlMemoryReadUnderWrite>, Info),
499 CMem(Identifier, Type, Info),
500}
501
502impl Display for ChirrtlMemory {
503 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
504 match self {
505 Self::SMem(name, tpe, ruw_opt, info) => {
506 if let Some(ruw) = ruw_opt {
507 write!(f, "smem {} : {}, {:?} {}", name, tpe, ruw, info)
508 } else {
509 write!(f, "smem {} : {} {}", name, tpe, info)
510 }
511 }
512 Self::CMem(name, tpe, info) => {
513 write!(f, "cmem {} : {} {}", name, tpe, info)
514 }
515 }
516 }
517}
518
519#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
520pub enum ChirrtlMemoryPort {
521 Write(Identifier, Identifier, Expr, Reference, Info),
522 Read (Identifier, Identifier, Expr, Reference, Info),
523 Infer(Identifier, Identifier, Expr, Reference, Info),
524}
525
526impl Display for ChirrtlMemoryPort {
527 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
528 match self {
529 ChirrtlMemoryPort::Write(port_name, mem_name, addr, clk, info) => {
530 write!(f, "write mport {} = {}[{}], {} {}", port_name, mem_name, addr, clk, info)
531 }
532 ChirrtlMemoryPort::Read(port_name, mem_name, addr, clk, info) => {
533 write!(f, "read mport {} = {}[{}], {} {}", port_name, mem_name, addr, clk, info)
534 }
535 ChirrtlMemoryPort::Infer(port_name, mem_name, addr, clk, info) => {
536 write!(f, "infer mport {} = {}[{}], {} {}", port_name, mem_name, addr, clk, info)
537 }
538 }
539 }
540}
541
542pub type Stmts = Vec<Box<Stmt>>;
543
544#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
545pub enum Stmt {
546 Skip(Info),
547 Wire(Identifier, Type, Info),
548 Reg(Identifier, Type, Expr, Info),
549 RegReset(Identifier, Type, Expr, Expr, Expr, Info),
550 ChirrtlMemory(ChirrtlMemory),
551 ChirrtlMemoryPort(ChirrtlMemoryPort),
552 Inst(Identifier, Identifier, Info),
553 Node(Identifier, Expr, Info),
554 Connect(Expr, Expr, Info),
555 Invalidate(Expr, Info),
556 When(Expr, Info, Stmts, Option<Stmts>),
557 Printf(Expr, Expr, String, Option<Exprs>, Info),
558 Assert(Expr, Expr, Expr, String, Info),
559}
568
569impl Stmt {
570 pub fn traverse(&self) {
571 match self {
572 Self::When(e, i, tstmts, fstmts_opt) => {
573 println!("When, {:?}, {:?}", e, i);
574 for tstmt in tstmts.iter() {
575 println!("{:?}", tstmt);
576 }
577 match fstmts_opt {
578 Some(fstmts) => {
579 println!("ELSE");
580 for fstmt in fstmts.iter() {
581 println!("{:?}", fstmt);
582 }
583 }
584 None => {
585 }
586 }
587 }
588 _ => {
589 println!("{:?}", self);
590 }
591 }
592 }
593}
594
595impl Display for Stmt {
596 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
597 match self {
598 Stmt::Skip(info) => write!(f, "skip {}", info),
599 Stmt::Wire(name, tpe, info) => write!(f, "wire {} : {} {}", name, tpe, info),
600 Stmt::Reg(name, tpe, clk, info) => write!(f, "reg {} : {}, {} {}", name, tpe, clk, info),
601 Stmt::RegReset(name, tpe, clk, rst, init, info) => write!(f, "reg {} : {}, {}, {}, {} {}", name, tpe, clk, rst, init, info),
602 Stmt::ChirrtlMemory(cm) => write!(f, "{}", cm),
603 Stmt::ChirrtlMemoryPort(cmp) => write!(f, "{}", cmp),
604 Stmt::Inst(inst, module, info) => write!(f, "{} of {} {}", inst, module, info),
605 Stmt::Node(name, expr, info) => write!(f, "node {} = {} {}", name, expr, info),
606 Stmt::Connect(lhs, rhs, info) => write!(f, "connect {}, {} {}", lhs, rhs, info),
607 Stmt::Invalidate(reference, info) => write!(f, "invalidate {} {}", reference, info),
608 Stmt::Printf(clk, clk_val, msg, fields_opt, info) => {
609 if let Some(fields) = fields_opt {
610 write!(f, "printf({}, {}, {}, {}) : {}", clk, clk_val, msg, fmt_exprs(fields), info)
611 } else {
612 write!(f, "printf({}, {}, {}) : {}", clk, clk_val, msg, info)
613 }
614 }
615 Stmt::Assert(clk, cond, cond_val, msg, info) => {
616 write!(f, "assert({}, {}, {}, {}) : {}", clk, cond, cond_val, msg, info)
617 }
618 Stmt::When(cond, info, when_stmts, else_stmts_opt) => {
619 writeln!(f, "when {} : {}", cond, info)?;
622 for stmt in when_stmts.iter() {
623 writeln!(f, "{}{}", " ".repeat(2), stmt)?;
624 }
625 if let Some(else_stmts) = else_stmts_opt {
626 writeln!(f, "else :")?;
627 for stmt in else_stmts.iter() {
628 writeln!(f, "{}{}", " ".repeat(2), stmt)?;
629 }
630 }
631 Ok(())
632 }
633 }
634 }
635}
636
637#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
638pub enum Port {
639 Input(Identifier, Type, Info),
640 Output(Identifier, Type, Info),
641}
642
643impl Display for Port {
644 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
645 match self {
646 Self::Input(id, tpe, info) => {
647 write!(f, "input {} : {} {}", id, tpe, info)
648 }
649 Self::Output(id, tpe, info) => {
650 write!(f, "output {} : {} {}", id, tpe, info)
651 }
652 }
653 }
654}
655
656pub type Ports = Vec<Box<Port>>;
657
658#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
659pub struct Module {
660 pub name: Identifier,
661 pub ports: Ports,
662 pub stmts: Stmts,
663 pub info: Info,
664}
665
666impl Module {
667 pub fn new(name: Identifier, ports: Ports, stmts: Stmts, info: Info) -> Self {
668 Self { name, ports, stmts, info, }
669 }
670}
671
672#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
673pub struct DefName(Identifier);
674
675impl From<Identifier> for DefName {
676 fn from(value: Identifier) -> Self {
677 Self(value)
678 }
679}
680
681impl Display for DefName {
682 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
683 write!(f, "defname = {}", self.0)
684 }
685}
686
687pub type Parameters = Vec<Box<Parameter>>;
688
689#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
690pub enum Parameter {
691 IntParam(Identifier, Int),
692 FloatParam(Identifier, Float),
693 StringParam(Identifier, String),
694}
695
696impl Display for Parameter {
697 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
698 match self {
699 Self::IntParam(name, value) => write!(f, "parameter {} = {:?}", name, value),
700 Self::FloatParam(name, value) => write!(f, "parameter {} = {}", name, value),
701 Self::StringParam(name, value) => write!(f, "parameter {} = {}", name, value),
702 }
703 }
704}
705
706#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
707pub struct ExtModule {
708 pub name: Identifier,
709 pub ports: Ports,
710 pub defname: DefName,
711 pub params: Parameters,
712 pub info: Info,
713}
714
715impl ExtModule {
716 pub fn new(name: Identifier, ports: Ports, defname: DefName, params: Parameters, info: Info) -> Self {
717 Self { name, ports, defname, params, info }
718 }
719}
720
721#[allow(dead_code)]
722pub struct IntModule {
723 pub name: Identifier,
724 pub ports: Ports,
725 pub params: Parameters,
726 pub info: Info,
727}
728
729#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
730pub enum CircuitModule {
731 Module(Module),
732 ExtModule(ExtModule),
733}
735
736pub type CircuitModules = Vec<Box<CircuitModule>>;
737
738#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
739pub struct Annotations(pub serde_json::Value);
740
741impl Annotations {
742 pub fn from_str(input: String) -> Self {
743 let input = "[".to_owned() + &input + "]";
744 Self { 0: serde_json::from_str(&input).unwrap() }
745 }
746}
747
748#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
749pub struct Version(pub u32, pub u32, pub u32);
750
751impl Display for Version {
752 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
753 write!(f, "Version {}.{}.{}", self.0, self.1, self.2)
754 }
755}
756
757#[derive(Debug, Clone, Eq, PartialEq, Hash)]
758pub struct Circuit {
759 pub version: Version,
760 pub name: Identifier,
761 pub annos: Annotations,
762 pub modules: CircuitModules,
763}
764
765impl Circuit {
766 pub fn new(version: Version, name: Identifier, annos: Annotations, modules: CircuitModules) -> Self {
767 Self { version, name, annos, modules }
768 }
769}