1use std::io;
2
3use crate::{
4 Command, Header, IdCode, ReferenceIndex, Scope, ScopeItem, ScopeType, SimulationCommand,
5 TimescaleUnit, Value, VecValue, Var, VarType,
6};
7
8pub struct Writer<W: io::Write> {
10 writer: W,
11 next_id_code: IdCode,
12 scope_depth: usize,
13}
14
15impl<W: io::Write> Writer<W> {
16 pub fn new(writer: W) -> Writer<W> {
23 Writer {
24 writer,
25 next_id_code: IdCode::FIRST,
26 scope_depth: 0,
27 }
28 }
29
30 pub fn header(&mut self, h: &Header) -> io::Result<()> {
32 if let Some(ref s) = h.date {
33 self.date(s)?;
34 }
35 if let Some(ref s) = h.version {
36 self.version(s)?;
37 }
38 if let Some(ref s) = h.comment {
39 self.comment(s)?;
40 }
41 if let Some((v, u)) = h.timescale {
42 self.timescale(v, u)?;
43 }
44 for i in &h.items {
45 match *i {
46 ScopeItem::Var(ref v) => self.var(v)?,
47 ScopeItem::Scope(ref s) => self.scope(s)?,
48 ScopeItem::Comment(ref c) => self.comment(c)?,
49 }
50 }
51 self.enddefinitions()
52 }
53
54 pub fn comment(&mut self, v: &str) -> io::Result<()> {
56 writeln!(self.writer, "$comment\n {}\n$end", v)
57 }
58
59 pub fn date(&mut self, v: &str) -> io::Result<()> {
61 writeln!(self.writer, "$date\n {}\n$end", v)
62 }
63
64 pub fn version(&mut self, v: &str) -> io::Result<()> {
66 writeln!(self.writer, "$version\n {}\n$end", v)
67 }
68
69 pub fn timescale(&mut self, ts: u32, unit: TimescaleUnit) -> io::Result<()> {
71 writeln!(self.writer, "$timescale {} {} $end", ts, unit)
72 }
73
74 pub fn scope_def(&mut self, t: ScopeType, i: &str) -> io::Result<()> {
76 self.scope_depth += 1;
77 writeln!(self.writer, "$scope {} {} $end", t, i)
78 }
79
80 pub fn add_module(&mut self, identifier: &str) -> io::Result<()> {
84 self.scope_def(ScopeType::Module, identifier)
85 }
86
87 pub fn upscope(&mut self) -> io::Result<()> {
89 debug_assert!(
90 self.scope_depth > 0,
91 "Generating invalid VCD: upscope without a matching scope"
92 );
93 self.scope_depth -= 1;
94 writeln!(self.writer, "$upscope $end")
95 }
96
97 pub fn scope(&mut self, s: &Scope) -> io::Result<()> {
100 self.scope_def(s.scope_type, &s.identifier[..])?;
101 for i in &s.children {
102 match *i {
103 ScopeItem::Var(ref v) => self.var(v)?,
104 ScopeItem::Scope(ref s) => self.scope(s)?,
105 ScopeItem::Comment(ref c) => self.comment(c)?,
106 }
107 }
108 self.upscope()
109 }
110
111 pub fn var_def(
113 &mut self,
114 var_type: VarType,
115 width: u32,
116 id: IdCode,
117 reference: &str,
118 index: Option<ReferenceIndex>,
119 ) -> io::Result<()> {
120 debug_assert!(
121 self.scope_depth > 0,
122 "Generating invalid VCD: variable must be in a scope"
123 );
124 if id >= self.next_id_code {
125 self.next_id_code = id.next();
126 }
127 match index {
128 Some(idx) => writeln!(
129 self.writer,
130 "$var {} {} {} {} {} $end",
131 var_type, width, id, reference, idx
132 ),
133 None => writeln!(
134 self.writer,
135 "$var {} {} {} {} $end",
136 var_type, width, id, reference
137 ),
138 }
139 }
140
141 pub fn add_var(
145 &mut self,
146 var_type: VarType,
147 width: u32,
148 reference: &str,
149 index: Option<ReferenceIndex>,
150 ) -> io::Result<IdCode> {
151 let id = self.next_id_code;
152 self.var_def(var_type, width, id, reference, index)?;
153 Ok(id)
154 }
155
156 pub fn add_wire(&mut self, width: u32, reference: &str) -> io::Result<IdCode> {
160 self.add_var(VarType::Wire, width, reference, None)
161 }
162
163 pub fn var(&mut self, v: &Var) -> io::Result<()> {
165 self.var_def(v.var_type, v.size, v.code, &v.reference[..], v.index)
166 }
167
168 pub fn enddefinitions(&mut self) -> io::Result<()> {
170 debug_assert!(
171 self.scope_depth == 0,
172 "Generating invalid VCD: {} scopes must be closed with $upscope before $enddefinitions",
173 self.scope_depth
174 );
175 writeln!(self.writer, "$enddefinitions $end")
176 }
177
178 pub fn timestamp(&mut self, ts: u64) -> io::Result<()> {
180 writeln!(self.writer, "#{}", ts)
181 }
182
183 pub fn change_scalar<V: Into<Value>>(&mut self, id: IdCode, v: V) -> io::Result<()> {
185 writeln!(self.writer, "{}{}", v.into(), id)
186 }
187
188 pub fn change_vector(&mut self, id: IdCode, v: &VecValue) -> io::Result<()> {
190 write!(self.writer, "b")?;
191 for i in v {
192 write!(self.writer, "{}", i)?
193 }
194 writeln!(self.writer, " {}", id)
195 }
196
197 pub fn change_real(&mut self, id: IdCode, v: f64) -> io::Result<()> {
199 writeln!(self.writer, "r{} {}", v, id)
200 }
201
202 pub fn change_string(&mut self, id: IdCode, v: &str) -> io::Result<()> {
204 writeln!(self.writer, "s{} {}", v, id)
205 }
206
207 pub fn begin(&mut self, c: SimulationCommand) -> io::Result<()> {
209 writeln!(self.writer, "${}", c)
210 }
211
212 pub fn end(&mut self) -> io::Result<()> {
214 writeln!(self.writer, "$end")
215 }
216
217 pub fn command(&mut self, c: &Command) -> io::Result<()> {
219 use Command::*;
220 match *c {
221 Comment(ref c) => self.comment(&c[..]),
222 Date(ref c) => self.date(&c[..]),
223 Version(ref c) => self.version(&c[..]),
224 Timescale(v, u) => self.timescale(v, u),
225 ScopeDef(t, ref i) => self.scope_def(t, &i[..]),
226 Upscope => self.upscope(),
227 VarDef(t, s, i, ref r, idx) => self.var_def(t, s, i, &r[..], idx),
228 Enddefinitions => self.enddefinitions(),
229 Timestamp(t) => self.timestamp(t),
230 ChangeScalar(i, v) => self.change_scalar(i, v),
231 ChangeVector(i, ref v) => self.change_vector(i, v),
232 ChangeReal(i, v) => self.change_real(i, v),
233 ChangeString(i, ref v) => self.change_string(i, v),
234 Begin(c) => self.begin(c),
235 End(_) => self.end(),
236 }
237 }
238}