rust_hdl_core/
synth.rs

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}