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 let num_fields = fields.len();
457 write!(f, "{{ ")?;
458 for (i, field) in fields.iter().enumerate() {
459 if i == num_fields - 1 {
460 write!(f, "{}", field)?;
461 } else {
462 write!(f, "{}, ", field)?;
463 }
464 }
465 write!(f, " }}")
466 }
467 Self::Array(tpe, idx) => {
468 write!(f, "{}[{}]", tpe, idx)
469 }
470 }
471 }
472}
473
474#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
475pub enum Type {
476 TypeGround(TypeGround),
477 ConstTypeGround(TypeGround),
478 TypeAggregate(Box<TypeAggregate>),
479 ConstTypeAggregate(Box<TypeAggregate>),
480}
481
482impl Display for Type {
483 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
484 match self {
485 Self::TypeGround(tg) => write!(f, "{}", tg),
486 Self::ConstTypeGround(tg) => write!(f, "{}", tg),
487 Self::TypeAggregate(ta) => write!(f, "{}", ta),
488 Self::ConstTypeAggregate(ta) => write!(f, "{}", ta),
489 }
490 }
491}
492
493#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
494pub enum ChirrtlMemoryReadUnderWrite {
495 #[default]
496 Undefined,
497 Old,
498 New
499}
500
501#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
502pub enum ChirrtlMemory {
503 SMem(Identifier, Type, Option<ChirrtlMemoryReadUnderWrite>, Info),
504 CMem(Identifier, Type, Info),
505}
506
507impl Display for ChirrtlMemory {
508 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
509 match self {
510 Self::SMem(name, tpe, ruw_opt, info) => {
511 if let Some(ruw) = ruw_opt {
512 write!(f, "smem {} : {}, {:?} {}", name, tpe, ruw, info)
513 } else {
514 write!(f, "smem {} : {} {}", name, tpe, info)
515 }
516 }
517 Self::CMem(name, tpe, info) => {
518 write!(f, "cmem {} : {} {}", name, tpe, info)
519 }
520 }
521 }
522}
523
524#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
525pub enum ChirrtlMemoryPort {
526 Write(Identifier, Identifier, Expr, Reference, Info),
527 Read (Identifier, Identifier, Expr, Reference, Info),
528 Infer(Identifier, Identifier, Expr, Reference, Info),
529}
530
531impl Display for ChirrtlMemoryPort {
532 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
533 match self {
534 ChirrtlMemoryPort::Write(port_name, mem_name, addr, clk, info) => {
535 write!(f, "write mport {} = {}[{}], {} {}", port_name, mem_name, addr, clk, info)
536 }
537 ChirrtlMemoryPort::Read(port_name, mem_name, addr, clk, info) => {
538 write!(f, "read mport {} = {}[{}], {} {}", port_name, mem_name, addr, clk, info)
539 }
540 ChirrtlMemoryPort::Infer(port_name, mem_name, addr, clk, info) => {
541 write!(f, "infer mport {} = {}[{}], {} {}", port_name, mem_name, addr, clk, info)
542 }
543 }
544 }
545}
546
547pub type Stmts = Vec<Box<Stmt>>;
548
549#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
550pub enum Stmt {
551 Skip(Info),
552 Wire(Identifier, Type, Info),
553 Reg(Identifier, Type, Expr, Info),
554 RegReset(Identifier, Type, Expr, Expr, Expr, Info),
555 ChirrtlMemory(ChirrtlMemory),
556 ChirrtlMemoryPort(ChirrtlMemoryPort),
557 Inst(Identifier, Identifier, Info),
558 Node(Identifier, Expr, Info),
559 Connect(Expr, Expr, Info),
560 Invalidate(Expr, Info),
561 When(Expr, Info, Stmts, Option<Stmts>),
562 Printf(Expr, Expr, String, Option<Exprs>, Info),
563 Assert(Expr, Expr, Expr, String, Info),
564}
573
574impl Stmt {
575 pub fn traverse(&self) {
576 match self {
577 Self::When(e, i, tstmts, fstmts_opt) => {
578 println!("When, {:?}, {:?}", e, i);
579 for tstmt in tstmts.iter() {
580 println!("{:?}", tstmt);
581 }
582 match fstmts_opt {
583 Some(fstmts) => {
584 println!("ELSE");
585 for fstmt in fstmts.iter() {
586 println!("{:?}", fstmt);
587 }
588 }
589 None => {
590 }
591 }
592 }
593 _ => {
594 println!("{:?}", self);
595 }
596 }
597 }
598}
599
600impl Display for Stmt {
601 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
602 match self {
603 Stmt::Skip(info) => write!(f, "skip {}", info),
604 Stmt::Wire(name, tpe, info) => write!(f, "wire {} : {} {}", name, tpe, info),
605 Stmt::Reg(name, tpe, clk, info) => write!(f, "reg {} : {}, {} {}", name, tpe, clk, info),
606 Stmt::RegReset(name, tpe, clk, rst, init, info) => write!(f, "regreset {} : {}, {}, {}, {} {}", name, tpe, clk, rst, init, info),
607 Stmt::ChirrtlMemory(cm) => write!(f, "{}", cm),
608 Stmt::ChirrtlMemoryPort(cmp) => write!(f, "{}", cmp),
609 Stmt::Inst(inst, module, info) => write!(f, "{} of {} {}", inst, module, info),
610 Stmt::Node(name, expr, info) => write!(f, "node {} = {} {}", name, expr, info),
611 Stmt::Connect(lhs, rhs, info) => write!(f, "connect {}, {} {}", lhs, rhs, info),
612 Stmt::Invalidate(reference, info) => write!(f, "invalidate {} {}", reference, info),
613 Stmt::Printf(clk, clk_val, msg, fields_opt, info) => {
614 if let Some(fields) = fields_opt {
615 write!(f, "printf({}, {}, {}, {}) : {}", clk, clk_val, msg, fmt_exprs(fields), info)
616 } else {
617 write!(f, "printf({}, {}, {}) : {}", clk, clk_val, msg, info)
618 }
619 }
620 Stmt::Assert(clk, cond, cond_val, msg, info) => {
621 write!(f, "assert({}, {}, {}, {}) : {}", clk, cond, cond_val, msg, info)
622 }
623 Stmt::When(cond, info, when_stmts, else_stmts_opt) => {
624 writeln!(f, "when {} : {}", cond, info)?;
627 for stmt in when_stmts.iter() {
628 writeln!(f, "{}{}", " ".repeat(2), stmt)?;
629 }
630 if let Some(else_stmts) = else_stmts_opt {
631 writeln!(f, "else :")?;
632 for stmt in else_stmts.iter() {
633 writeln!(f, "{}{}", " ".repeat(2), stmt)?;
634 }
635 }
636 Ok(())
637 }
638 }
639 }
640}
641
642#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
643pub enum Port {
644 Input(Identifier, Type, Info),
645 Output(Identifier, Type, Info),
646}
647
648impl Display for Port {
649 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
650 match self {
651 Self::Input(id, tpe, info) => {
652 write!(f, "input {} : {} {}", id, tpe, info)
653 }
654 Self::Output(id, tpe, info) => {
655 write!(f, "output {} : {} {}", id, tpe, info)
656 }
657 }
658 }
659}
660
661pub type Ports = Vec<Box<Port>>;
662
663#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
664pub struct Module {
665 pub name: Identifier,
666 pub ports: Ports,
667 pub stmts: Stmts,
668 pub info: Info,
669}
670
671impl Module {
672 pub fn new(name: Identifier, ports: Ports, stmts: Stmts, info: Info) -> Self {
673 Self { name, ports, stmts, info, }
674 }
675}
676
677#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
678pub struct DefName(Identifier);
679
680impl From<Identifier> for DefName {
681 fn from(value: Identifier) -> Self {
682 Self(value)
683 }
684}
685
686impl Display for DefName {
687 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
688 write!(f, "defname = {}", self.0)
689 }
690}
691
692pub type Parameters = Vec<Box<Parameter>>;
693
694#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
695pub enum Parameter {
696 IntParam(Identifier, Int),
697 FloatParam(Identifier, Float),
698 StringParam(Identifier, String),
699}
700
701impl Display for Parameter {
702 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
703 match self {
704 Self::IntParam(name, value) => write!(f, "parameter {} = {}", name, value),
705 Self::FloatParam(name, value) => write!(f, "parameter {} = {}", name, value),
706 Self::StringParam(name, value) => write!(f, "parameter {} = {}", name, value),
707 }
708 }
709}
710
711#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
712pub struct ExtModule {
713 pub name: Identifier,
714 pub ports: Ports,
715 pub defname: DefName,
716 pub params: Parameters,
717 pub info: Info,
718}
719
720impl ExtModule {
721 pub fn new(name: Identifier, ports: Ports, defname: DefName, params: Parameters, info: Info) -> Self {
722 Self { name, ports, defname, params, info }
723 }
724}
725
726#[allow(dead_code)]
727pub struct IntModule {
728 pub name: Identifier,
729 pub ports: Ports,
730 pub params: Parameters,
731 pub info: Info,
732}
733
734#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
735pub enum CircuitModule {
736 Module(Module),
737 ExtModule(ExtModule),
738}
740
741pub type CircuitModules = Vec<Box<CircuitModule>>;
742
743#[derive(Debug, Default, Clone, PartialEq, Eq, Hash)]
744pub struct Annotations(pub serde_json::Value);
745
746impl Annotations {
747 pub fn from_str(input: String) -> Self {
748 let input = "[".to_owned() + &input + "]";
749 Self { 0: serde_json::from_str(&input).unwrap() }
750 }
751}
752
753#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
754pub struct Version(pub u32, pub u32, pub u32);
755
756impl Display for Version {
757 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
758 write!(f, "version {}.{}.{}", self.0, self.1, self.2)
759 }
760}
761
762#[derive(Debug, Clone, Eq, PartialEq, Hash)]
763pub struct Circuit {
764 pub version: Version,
765 pub name: Identifier,
766 pub annos: Annotations,
767 pub modules: CircuitModules,
768}
769
770impl Circuit {
771 pub fn new(version: Version, name: Identifier, annos: Annotations, modules: CircuitModules) -> Self {
772 Self { version, name, annos, modules }
773 }
774}