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 BitSel,
187}
188
189#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
190pub enum PrimOp1Expr2Int {
191 BitSelRange,
192}
193
194impl From<String> for PrimOp2Expr {
195 fn from(value: String) -> Self {
196 match value.as_str() {
197 "add" => { Self::Add },
198 "sub" => { Self::Sub },
199 "mul" => { Self::Mul },
200 "div" => { Self::Div },
201 "rem" => { Self::Rem },
202 "lt" => { Self::Lt },
203 "leq" => { Self::Leq },
204 "gt" => { Self::Gt },
205 "geq" => { Self::Geq },
206 "eq" => { Self::Eq },
207 "neq" => { Self::Neq },
208 "dshl" => { Self::Dshl },
209 "dshr" => { Self::Dshr },
210 "and" => { Self::And },
211 "or" => { Self::Or },
212 "xor" => { Self::Xor },
213 "cat" => { Self::Cat },
214 _ => {
215 panic!("Unrecognized operator {}", value);
216 }
217 }
218 }
219}
220
221impl Display for PrimOp2Expr {
222 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
223 let s = match self {
224 PrimOp2Expr::Add => "add",
225 PrimOp2Expr::Sub => "sub",
226 PrimOp2Expr::Mul => "mul",
227 PrimOp2Expr::Div => "div",
228 PrimOp2Expr::Rem => "rem",
229 PrimOp2Expr::Lt => "lt",
230 PrimOp2Expr::Leq => "leq",
231 PrimOp2Expr::Gt => "gt",
232 PrimOp2Expr::Geq => "geq",
233 PrimOp2Expr::Eq => "eq",
234 PrimOp2Expr::Neq => "neq",
235 PrimOp2Expr::Dshl => "dshl",
236 PrimOp2Expr::Dshr => "dshr",
237 PrimOp2Expr::And => "and",
238 PrimOp2Expr::Or => "or",
239 PrimOp2Expr::Xor => "xor",
240 PrimOp2Expr::Cat => "cat",
241 };
242 write!(f, "{s}")
243 }
244}
245
246impl From<String> for PrimOp1Expr {
247 fn from(value: String) -> Self {
248 match value.as_str() {
249 "asUInt" => { Self::AsUInt },
250 "asSInt" => { Self::AsSInt },
251 "asClock" => { Self::AsClock },
252 "asAsyncReset" => { Self::AsAsyncReset },
253 "cvt" => { Self::Cvt },
254 "neg" => { Self::Neg },
255 "not" => { Self::Not },
256 "andr" => { Self::Andr },
257 "orr" => { Self::Orr },
258 "xorr" => { Self::Xorr },
259 _ => {
260 panic!("Unrecognized operator {}", value);
261 }
262 }
263 }
264}
265
266impl std::fmt::Display for PrimOp1Expr {
267 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
268 let s = match self {
269 PrimOp1Expr::AsUInt => "asUInt",
270 PrimOp1Expr::AsSInt => "asSInt",
271 PrimOp1Expr::AsClock => "asClock",
272 PrimOp1Expr::AsAsyncReset => "asAsyncReset",
273 PrimOp1Expr::Cvt => "cvt",
274 PrimOp1Expr::Neg => "neg",
275 PrimOp1Expr::Not => "not",
276 PrimOp1Expr::Andr => "andr",
277 PrimOp1Expr::Orr => "orr",
278 PrimOp1Expr::Xorr => "xorr",
279 };
280 write!(f, "{s}")
281 }
282}
283
284impl From<String> for PrimOp1Expr1Int {
285 fn from(value: String) -> Self {
286 match value.as_str() {
287 "pad" => { Self::Pad },
288 "shl" => { Self::Shl },
289 "shr" => { Self::Shr },
290 "head" => { Self::Head },
291 "tail" => { Self::Tail },
292 _ => { Self::BitSel }
293 }
294 }
295}
296
297
298impl std::fmt::Display for PrimOp1Expr1Int {
299 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
300 let s = match self {
301 PrimOp1Expr1Int::Pad => "pad",
302 PrimOp1Expr1Int::Shl => "shl",
303 PrimOp1Expr1Int::Shr => "shr",
304 PrimOp1Expr1Int::Head => "head",
305 PrimOp1Expr1Int::Tail => "tail",
306 PrimOp1Expr1Int::BitSel => panic!("Display called for bitsel"),
307 };
308 write!(f, "{s}")
309 }
310}
311
312impl From<String> for PrimOp1Expr2Int {
313 fn from(value: String) -> Self {
314 assert!(value.contains("bit"));
315 Self::BitSelRange
316 }
317}
318
319impl std::fmt::Display for PrimOp1Expr2Int {
320 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
321 let s = match self {
322 PrimOp1Expr2Int::BitSelRange => "bits",
323 };
324 write!(f, "{s}")
325 }
326}
327
328pub type Exprs = Vec<Box<Expr>>;
329
330fn fmt_exprs(exprs: &Exprs) -> String {
331 let mut ret = "".to_string();
332 let len = exprs.len();
333 for (id, e) in exprs.iter().enumerate() {
334 ret.push_str(&format!("{}", e));
335 if id != len - 1 {
336 ret.push_str(", ");
337 }
338 }
339 return ret;
340}
341
342#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
343pub enum Expr {
344 UIntNoInit(Width),
345 UIntInit(Width, Int),
346 SIntNoInit(Width),
347 SIntInit(Width, Int),
348 Reference(Reference),
349 Mux(Box<Expr>, Box<Expr>, Box<Expr>),
350 ValidIf(Box<Expr>, Box<Expr>),
351 PrimOp2Expr(PrimOp2Expr, Box<Expr>, Box<Expr>),
352 PrimOp1Expr(PrimOp1Expr, Box<Expr>),
353 PrimOp1Expr1Int(PrimOp1Expr1Int, Box<Expr>, Int),
354 PrimOp1Expr2Int(PrimOp1Expr2Int, Box<Expr>, Int, Int),
355}
356
357impl Expr {
358 pub fn parse_radixint(s: &str) -> Result<Int, String> {
359 if let Some(num) = s.strip_prefix("0b") {
360 Int::from_str_radix(num, 2).map_err(|e| e.to_string())
361 } else if let Some(num) = s.strip_prefix("0o") {
362 Int::from_str_radix(num, 8).map_err(|e| e.to_string())
363 } else if let Some(num) = s.strip_prefix("0d") {
364 Int::from_str_radix(num, 10).map_err(|e| e.to_string())
365 } else if let Some(num) = s.strip_prefix("0h") {
366 Int::from_str_radix(num, 16).map_err(|e| e.to_string())
367 } else {
368 Err(format!("Invalid number format: {}", s))
369 }
370 }
371}
372
373impl Display for Expr {
374 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
375 match self {
376 Expr::UIntNoInit(w) => write!(f, "UInt<{}>()", w),
377 Expr::UIntInit(w, init) => write!(f, "UInt<{}>({:?})", w, init),
378 Expr::SIntNoInit(w) => write!(f, "SInt<{}>()", w),
379 Expr::SIntInit(w, init) => write!(f, "SInt<{}>({:?})", w, init),
380 Expr::Reference(r) => write!(f, "{}", r),
381 Expr::Mux(cond, te, fe) => write!(f, "mux({}, {}, {})", cond, te, fe),
382 Expr::ValidIf(cond, te) => write!(f, "validif({}, {})", cond, te),
383 Expr::PrimOp2Expr(op, a, b) => write!(f, "{}({}, {})", op, a, b),
384 Expr::PrimOp1Expr(op, a) => write!(f, "{}({})", op, a),
385 Expr::PrimOp1Expr1Int(PrimOp1Expr1Int::BitSel, a, b) => write!(f, "{}({})", a, b),
386 Expr::PrimOp1Expr1Int(op, a, b) => write!(f, "{}({}, {})", op, a, b),
387 Expr::PrimOp1Expr2Int(op, a, b, c) => write!(f, "{}({}, {}, {})", op, a, b, c),
388 }
389 }
390}
391
392#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
393pub enum TypeGround {
394 Clock,
395 Reset,
396 AsyncReset,
397 UInt(Option<Width>),
398 SInt(Option<Width>),
399}
403
404impl Display for TypeGround {
405 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
406 match self {
407 Self::Clock => { write!(f, "Clock") }
408 Self::Reset => { write!(f, "Reset") }
409 Self::AsyncReset => { write!(f, "AsyncReset") }
410 Self::UInt(w_opt) => {
411 if let Some(w) = w_opt {
412 write!(f, "UInt<{}>", w)
413 } else {
414 write!(f, "UInt")
415 }
416 }
417 Self::SInt(w_opt) => {
418 if let Some(w) = w_opt {
419 write!(f, "SInt<{}>", w)
420 } else {
421 write!(f, "SInt")
422 }
423 }
424 }
425 }
426}
427
428pub type Fields = Vec<Box<Field>>;
429
430#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
431pub enum Field {
432 Straight(Identifier, Box<Type>),
433 Flipped(Identifier, Box<Type>),
434}
435
436impl Display for Field {
437 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
438 match self {
439 Self::Straight(id, tpe) => {
440 write!(f, "{}: {}", id, tpe)
441 }
442 Self::Flipped(id, tpe) => {
443 write!(f, "flip {}: {}", id, tpe)
444 }
445 }
446 }
447}
448
449#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
450pub enum TypeAggregate {
451 Fields(Box<Fields>),
452 Array(Box<Type>, Int),
453}
454
455impl Display for TypeAggregate {
456 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
457 match self {
458 Self::Fields(fields) => {
459 write!(f, "{{ ")?;
460 for field in fields.iter() {
461 write!(f, "{}, ", field)?;
462 }
463 write!(f, " }}")
464 }
465 Self::Array(tpe, idx) => {
466 write!(f, "{}[{:?}]", tpe, idx)
467 }
468 }
469 }
470}
471
472#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
473pub enum Type {
474 TypeGround(TypeGround),
475 ConstTypeGround(TypeGround),
476 TypeAggregate(Box<TypeAggregate>),
477 ConstTypeAggregate(Box<TypeAggregate>),
478}
479
480impl Display for Type {
481 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
482 match self {
483 Self::TypeGround(tg) => write!(f, "{}", tg),
484 Self::ConstTypeGround(tg) => write!(f, "{}", tg),
485 Self::TypeAggregate(ta) => write!(f, "{}", ta),
486 Self::ConstTypeAggregate(ta) => write!(f, "{}", ta),
487 }
488 }
489}
490
491#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
492pub enum ChirrtlMemoryReadUnderWrite {
493 #[default]
494 Undefined,
495 Old,
496 New
497}
498
499#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
500pub enum ChirrtlMemory {
501 SMem(Identifier, Type, Option<ChirrtlMemoryReadUnderWrite>, Info),
502 CMem(Identifier, Type, Info),
503}
504
505impl Display for ChirrtlMemory {
506 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
507 match self {
508 Self::SMem(name, tpe, ruw_opt, info) => {
509 if let Some(ruw) = ruw_opt {
510 write!(f, "smem {} : {}, {:?} {}", name, tpe, ruw, info)
511 } else {
512 write!(f, "smem {} : {} {}", name, tpe, info)
513 }
514 }
515 Self::CMem(name, tpe, info) => {
516 write!(f, "cmem {} : {} {}", name, tpe, info)
517 }
518 }
519 }
520}
521
522#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
523pub enum ChirrtlMemoryPort {
524 Write(Identifier, Identifier, Expr, Reference, Info),
525 Read (Identifier, Identifier, Expr, Reference, Info),
526 Infer(Identifier, Identifier, Expr, Reference, Info),
527}
528
529impl Display for ChirrtlMemoryPort {
530 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
531 match self {
532 ChirrtlMemoryPort::Write(port_name, mem_name, addr, clk, info) => {
533 write!(f, "write mport {} = {}[{}], {} {}", port_name, mem_name, addr, clk, info)
534 }
535 ChirrtlMemoryPort::Read(port_name, mem_name, addr, clk, info) => {
536 write!(f, "read mport {} = {}[{}], {} {}", port_name, mem_name, addr, clk, info)
537 }
538 ChirrtlMemoryPort::Infer(port_name, mem_name, addr, clk, info) => {
539 write!(f, "infer mport {} = {}[{}], {} {}", port_name, mem_name, addr, clk, info)
540 }
541 }
542 }
543}
544
545pub type Stmts = Vec<Box<Stmt>>;
546
547#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
548pub enum Stmt {
549 Skip(Info),
550 Wire(Identifier, Type, Info),
551 Reg(Identifier, Type, Expr, Info),
552 RegReset(Identifier, Type, Expr, Expr, Expr, Info),
553 ChirrtlMemory(ChirrtlMemory),
554 ChirrtlMemoryPort(ChirrtlMemoryPort),
555 Inst(Identifier, Identifier, Info),
556 Node(Identifier, Expr, Info),
557 Connect(Expr, Expr, Info),
558 Invalidate(Expr, Info),
559 When(Expr, Info, Stmts, Option<Stmts>),
560 Printf(Expr, Expr, String, Option<Exprs>, Info),
561 Assert(Expr, Expr, Expr, String, Info),
562}
571
572impl Stmt {
573 pub fn traverse(&self) {
574 match self {
575 Self::When(e, i, tstmts, fstmts_opt) => {
576 println!("When, {:?}, {:?}", e, i);
577 for tstmt in tstmts.iter() {
578 println!("{:?}", tstmt);
579 }
580 match fstmts_opt {
581 Some(fstmts) => {
582 println!("ELSE");
583 for fstmt in fstmts.iter() {
584 println!("{:?}", fstmt);
585 }
586 }
587 None => {
588 }
589 }
590 }
591 _ => {
592 println!("{:?}", self);
593 }
594 }
595 }
596}
597
598impl Display for Stmt {
599 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
600 match self {
601 Stmt::Skip(info) => write!(f, "skip {}", info),
602 Stmt::Wire(name, tpe, info) => write!(f, "wire {} : {} {}", name, tpe, info),
603 Stmt::Reg(name, tpe, clk, info) => write!(f, "reg {} : {}, {} {}", name, tpe, clk, info),
604 Stmt::RegReset(name, tpe, clk, rst, init, info) => write!(f, "reg {} : {}, {}, {}, {} {}", name, tpe, clk, rst, init, info),
605 Stmt::ChirrtlMemory(cm) => write!(f, "{}", cm),
606 Stmt::ChirrtlMemoryPort(cmp) => write!(f, "{}", cmp),
607 Stmt::Inst(inst, module, info) => write!(f, "{} of {} {}", inst, module, info),
608 Stmt::Node(name, expr, info) => write!(f, "node {} = {} {}", name, expr, info),
609 Stmt::Connect(lhs, rhs, info) => write!(f, "connect {}, {} {}", lhs, rhs, info),
610 Stmt::Invalidate(reference, info) => write!(f, "invalidate {} {}", reference, info),
611 Stmt::Printf(clk, clk_val, msg, fields_opt, info) => {
612 if let Some(fields) = fields_opt {
613 write!(f, "printf({}, {}, {}, {}) : {}", clk, clk_val, msg, fmt_exprs(fields), info)
614 } else {
615 write!(f, "printf({}, {}, {}) : {}", clk, clk_val, msg, info)
616 }
617 }
618 Stmt::Assert(clk, cond, cond_val, msg, info) => {
619 write!(f, "assert({}, {}, {}, {}) : {}", clk, cond, cond_val, msg, info)
620 }
621 Stmt::When(cond, info, when_stmts, else_stmts_opt) => {
622 writeln!(f, "when {} : {}", cond, info)?;
625 for stmt in when_stmts.iter() {
626 writeln!(f, "{}{}", " ".repeat(2), stmt)?;
627 }
628 if let Some(else_stmts) = else_stmts_opt {
629 writeln!(f, "else :")?;
630 for stmt in else_stmts.iter() {
631 writeln!(f, "{}{}", " ".repeat(2), stmt)?;
632 }
633 }
634 Ok(())
635 }
636 }
637 }
638}
639
640#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
641pub enum Port {
642 Input(Identifier, Type, Info),
643 Output(Identifier, Type, Info),
644}
645
646impl Display for Port {
647 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
648 match self {
649 Self::Input(id, tpe, info) => {
650 write!(f, "input {} : {} {}", id, tpe, info)
651 }
652 Self::Output(id, tpe, info) => {
653 write!(f, "output {} : {} {}", id, tpe, info)
654 }
655 }
656 }
657}
658
659pub type Ports = Vec<Box<Port>>;
660
661#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
662pub struct Module {
663 pub name: Identifier,
664 pub ports: Ports,
665 pub stmts: Stmts,
666 pub info: Info,
667}
668
669impl Module {
670 pub fn new(name: Identifier, ports: Ports, stmts: Stmts, info: Info) -> Self {
671 Self { name, ports, stmts, info, }
672 }
673}
674
675#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
676pub struct DefName(Identifier);
677
678impl From<Identifier> for DefName {
679 fn from(value: Identifier) -> Self {
680 Self(value)
681 }
682}
683
684impl Display for DefName {
685 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
686 write!(f, "defname = {}", self.0)
687 }
688}
689
690pub type Parameters = Vec<Box<Parameter>>;
691
692#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
693pub enum Parameter {
694 IntParam(Identifier, Int),
695 FloatParam(Identifier, Float),
696 StringParam(Identifier, String),
697}
698
699impl Display for Parameter {
700 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
701 match self {
702 Self::IntParam(name, value) => write!(f, "parameter {} = {:?}", name, value),
703 Self::FloatParam(name, value) => write!(f, "parameter {} = {}", name, value),
704 Self::StringParam(name, value) => write!(f, "parameter {} = {}", name, value),
705 }
706 }
707}
708
709#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
710pub struct ExtModule {
711 pub name: Identifier,
712 pub ports: Ports,
713 pub defname: DefName,
714 pub params: Parameters,
715 pub info: Info,
716}
717
718impl ExtModule {
719 pub fn new(name: Identifier, ports: Ports, defname: DefName, params: Parameters, info: Info) -> Self {
720 Self { name, ports, defname, params, info }
721 }
722}
723
724#[allow(dead_code)]
725pub struct IntModule {
726 pub name: Identifier,
727 pub ports: Ports,
728 pub params: Parameters,
729 pub info: Info,
730}
731
732#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
733pub enum CircuitModule {
734 Module(Module),
735 ExtModule(ExtModule),
736}
738
739pub type CircuitModules = Vec<Box<CircuitModule>>;
740
741#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
742pub struct Annotations(pub serde_json::Value);
743
744impl Annotations {
745 pub fn from_str(input: String) -> Self {
746 let input = "[".to_owned() + &input + "]";
747 Self { 0: serde_json::from_str(&input).unwrap() }
748 }
749}
750
751#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
752pub struct Version(pub u32, pub u32, pub u32);
753
754impl Display for Version {
755 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
756 write!(f, "Version {}.{}.{}", self.0, self.1, self.2)
757 }
758}
759
760#[derive(Debug, Clone, Eq, PartialEq, Hash)]
761pub struct Circuit {
762 pub version: Version,
763 pub name: Identifier,
764 pub annos: Annotations,
765 pub modules: CircuitModules,
766}
767
768impl Circuit {
769 pub fn new(version: Version, name: Identifier, annos: Annotations, modules: CircuitModules) -> Self {
770 Self { version, name, annos, modules }
771 }
772}