ETISS 0.8.0
Extendable Translating Instruction Set Simulator (version 0.8.0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
VCD.cpp
Go to the documentation of this file.
1/*
2
3 @copyright
4
5 <pre>
6
7 Copyright 2018 Infineon Technologies AG
8
9 This file is part of ETISS tool, see <https://github.com/tum-ei-eda/etiss>.
10
11 The initial version of this software has been created with the funding support by the German Federal
12 Ministry of Education and Research (BMBF) in the project EffektiV under grant 01IS13022.
13
14 Redistribution and use in source and binary forms, with or without modification, are permitted
15 provided that the following conditions are met:
16
17 1. Redistributions of source code must retain the above copyright notice, this list of conditions and
18 the following disclaimer.
19
20 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
21 and the following disclaimer in the documentation and/or other materials provided with the distribution.
22
23 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse
24 or promote products derived from this software without specific prior written permission.
25
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
27 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
28 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
29 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 POSSIBILITY OF SUCH DAMAGE.
34
35 </pre>
36
37 @author Marc Greim <marc.greim@mytum.de>, Chair of Electronic Design Automation, TUM
38
39 @version 0.1
40
41*/
42
44
45namespace etiss
46{
47namespace interfaces
48{
49
51static std::string val2str(uint64_t val, unsigned width, uint64_t udef)
52{
53 if (width == 1)
54 {
55 return (udef & 1) ? "x" : ((val & 1) ? "1" : "0");
56 }
57 else
58 {
59 char *ret = new char[width + 3];
60 ret[0] = 'b';
61 ret[width + 1] = ' ';
62 ret[width + 2] = 0;
63 for (unsigned i = 1; i < width + 1; i++)
64 {
65 ret[width + 1 - i] = (udef & 1) ? 'x' : ((val & 1) ? '1' : '0');
66 val = val >> 1;
67 udef = udef >> 1;
68 }
69 std::string r(ret);
70 delete[] ret;
71 return r;
72 }
73}
74
78static std::string index2str(int index)
79{
80 std::string out;
81 while (true)
82 {
83 out += static_cast<char>(index % 94) + 33;
84 if (index < 94)
85 break;
86 index -= 94;
87 index /= 94;
88 }
89 return out;
90}
91
92VCD::VCD(const std::string &file, const std::string &comment) : dumpstarted_(false), lasttime_ps(0), file(file)
93{
94 out_.open(file);
95 valid_ = out_.is_open();
96
97 if (!valid_)
98 {
99 etiss::log(etiss::WARNING, "Failed to open file for VCD output: " + file);
100 }
101 else
102 {
103 out_ << "$date\n"
104 " \n"
105 "$end\n"
106 "$version\n"
107 " ETISS " ETISS_VERSION_FULL "\n"
108 "$end\n"
109 "$comment\n"
110 << comment
111 << "\n"
112 "$end\n"
113 "$timescale 1ps $end\n";
114 }
115
116 dumpvar = "$enddefinitions $end\n$dumpvars\n";
117}
118
119VCD::~VCD()
120{
121 close();
122}
123
124void VCD::close()
125{
126 if (!valid_)
127 return;
128 valid_ = false;
129 flush();
130 out_.close();
131}
132
133bool VCD::declare(void *variable, const std::string &name, unsigned width, uint64_t initialvalue, uint64_t undefined)
134{
135 if (!valid_)
136 return false;
137 if (name.size() == 0)
138 {
139 etiss::log(etiss::ERROR, "Cannot call etiss::interfaces::VCD::declare without a name.", *this);
140 return false;
141 }
142 if (dumpstarted_)
143 {
144 etiss::log(etiss::ERROR, "Cannot call etiss::interfaces::VCD::declare after dump started.", *this);
145 return false;
146 }
147 if (sigs_.size() >= (94 + 94 * 94 + 94 * 94 * 94 + 94 * 94 * 94 * 94))
148 {
149 etiss::log(etiss::ERROR, "etiss::interfaces::VCD::declare called for more than supported variables.", *this);
150 return false;
151 }
152 int checked_sig_size = static_cast<int>(sigs_.size());
153 sigs_.emplace_back();
154 Signal &sig = sigs_.back();
155
156 sig.valid = false;
157 sig.name = name;
158 sig.value = initialvalue;
159 sig.width = width;
160 sig.ident = index2str(checked_sig_size - 1);
161 sig.undefined = undefined;
162
163 // declare signal
164 {
165 // split on dots and double quotes to get the submodules and enter their scopes
166 std::list<std::string> vec_bd = etiss::split(name, [](const std::string &str, size_t from, size_t &seplen) {
167 size_t f1 = str.find(".", from);
168 size_t f2 = str.find("::", from);
169 seplen = f1 < f2 ? 1 : 2;
170 return f1 < f2 ? f1 : f2;
171 });
172 std::vector<std::string> vec;
173 vec.insert(vec.end(), vec_bd.begin(), vec_bd.end());
174 if (vec.size() == 0)
175 vec.push_back(name);
176 for (size_t i = 1; i < vec.size(); i++)
177 {
178 out_ << "$scope module " << vec[i - 1] << " $end\n";
179 }
180 out_ << "$var wire " << width << " " << sig.ident << " " << vec[vec.size() - 1] << " $end\n";
181 for (size_t i = 1; i < vec.size(); i++)
182 {
183 out_ << "$upscope $end\n";
184 }
185 }
186
187 dumpvar = dumpvar + val2str(initialvalue, width, undefined) + sig.ident + "\n";
188
189 ptr2index_.insert(std::make_pair(variable, (checked_sig_size - 1)));
190
191 out_.flush();
192
193 return true;
194}
195void VCD::update(uint64_t time_ps, void *variable, uint64_t value, uint64_t undefined)
196{
197 if (!valid_)
198 return;
199 if (time_ps < lasttime_ps)
200 {
201 etiss::log(etiss::ERROR, "etiss::interfaces::VCD::update called with decreased time value");
202 }
203
204 auto findex = ptr2index_.find(variable);
205 if (findex != ptr2index_.end())
206 {
207 if (time_ps > lasttime_ps)
208 {
209 flush();
210 lasttime_ps = time_ps;
211 }
212 int index = findex->second;
213 Signal &sig = sigs_[index];
214 sig.valid = true;
215 sig.value = value;
216 sig.undefined = undefined;
217 }
218 else
219 {
220 // not a declared vriable. ignore
221 }
222}
223void VCD::flush()
224{
225 if (!valid_)
226 return;
227 dumpstarted_ = true;
228 if (lasttime_ps == 0)
229 {
230 out_ << dumpvar;
231 out_ << "$end\n"; // terminate dumpvars
232 }
233 bool empty = true;
234 for (size_t i = 0; i < sigs_.size(); i++)
235 {
236 if (sigs_[i].valid)
237 {
238 empty = false;
239 break;
240 }
241 }
242 if (empty)
243 return;
244 out_ << "#" << lasttime_ps << "\n";
245 for (size_t i = 0; i < sigs_.size(); i++)
246 {
247 Signal &s = sigs_[i];
248 if (s.valid)
249 {
250 out_ << val2str(s.value, s.width, s.undefined) << s.ident << "\n";
251 s.valid = false;
252 }
253 }
254 // out_.flush();
255}
256
257} // namespace interfaces
258} // namespace etiss
__device__ __2f16 float bool s
static __inline__ uint64_t
Definition arm_cde.h:31
#define ETISS_VERSION_FULL
Definition config.h:67
static std::string index2str(int index)
generated an identifier for the given index
Definition VCD.cpp:78
static std::string val2str(uint64_t val, unsigned width, uint64_t udef)
TODO efficient implementation.
Definition VCD.cpp:51
Page Table Entry (PTE) defines the composition of Page Frame Number (PFN) and relavant flags.
Definition Benchmark.h:53
std::list< std::string > split(const std::string &str, std::function< size_t(const std::string &, size_t, size_t &)> findsplit)
Definition Misc.cpp:91
@ WARNING
Definition Misc.h:128
@ ERROR
Definition Misc.h:127
void log(Verbosity level, std::string msg)
write log message at the given level.
Definition Misc.cpp:125
#define false
Definition stdbool.h:17