1use std::fmt::Debug;
2
3use crate::ast::VerilogLiteral;
4use crate::bits::{Bit, Bits};
5use crate::clock::Clock;
6use crate::signed::Signed;
7use crate::type_descriptor::{TypeDescriptor, TypeKind};
8
9#[derive(Clone, PartialEq, Debug)]
10pub enum VCDValue {
11 Single(vcd::Value),
12 Vector(Vec<vcd::Value>),
13 String(String),
14 Composite(Vec<Box<VCDValue>>),
15}
16
17impl From<bool> for VCDValue {
18 fn from(x: bool) -> Self {
19 if x {
20 VCDValue::Single(vcd::Value::V1)
21 } else {
22 VCDValue::Single(vcd::Value::V0)
23 }
24 }
25}
26
27pub trait Synth: Default + Copy + PartialEq + Debug {
28 const BITS: usize;
29 fn descriptor() -> TypeDescriptor;
30 fn vcd(self) -> VCDValue;
31 fn verilog(self) -> VerilogLiteral;
32 fn bits(self) -> usize {
33 Self::BITS
34 }
35}
36
37impl<const N: usize> Synth for Bits<N> {
38 const BITS: usize = N;
39
40 fn descriptor() -> TypeDescriptor {
41 TypeDescriptor {
42 name: format!("Bits::<{}>", Self::BITS),
43 kind: TypeKind::Bits(Self::BITS),
44 }
45 }
46
47 fn vcd(self) -> VCDValue {
48 self.into()
49 }
50
51 fn verilog(self) -> VerilogLiteral {
52 self.into()
53 }
54}
55
56impl Synth for Bit {
57 const BITS: usize = 1;
58
59 fn descriptor() -> TypeDescriptor {
60 TypeDescriptor {
61 name: "Bit".to_string(),
62 kind: TypeKind::Bits(1),
63 }
64 }
65
66 fn vcd(self) -> VCDValue {
67 if self {
68 VCDValue::Single(vcd::Value::V1)
69 } else {
70 VCDValue::Single(vcd::Value::V0)
71 }
72 }
73
74 fn verilog(self) -> VerilogLiteral {
75 self.into()
76 }
77}
78
79impl Synth for Clock {
80 const BITS: usize = 1;
81
82 fn descriptor() -> TypeDescriptor {
83 TypeDescriptor {
84 name: "clock".to_string(),
85 kind: TypeKind::Bits(1),
86 }
87 }
88
89 fn vcd(self) -> VCDValue {
90 self.clk.into()
91 }
92
93 fn verilog(self) -> VerilogLiteral {
94 self.clk.into()
95 }
96}
97
98impl<const N: usize> Synth for Signed<N> {
99 const BITS: usize = N;
100 fn descriptor() -> TypeDescriptor {
101 TypeDescriptor {
102 name: format!("Signed::<{}>", Self::BITS),
103 kind: TypeKind::Signed(Self::BITS),
104 }
105 }
106 fn vcd(self) -> VCDValue {
107 self.inner().vcd()
108 }
109 fn verilog(self) -> VerilogLiteral {
110 self.inner().into()
111 }
112}