2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Aki "lethalbit" Van Ness <aki@yosyshq.com> <aki@lethalbit.net>
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 // MYAU - Metadata for Yosys-Assisted Utilities
22 #include "kernel/rtlil.h"
23 #include "kernel/register.h"
24 #include "kernel/sigtools.h"
25 #include "kernel/celltypes.h"
26 #include "kernel/cellaigs.h"
27 #include "kernel/log.h"
29 #include <unordered_map>
33 PRIVATE_NAMESPACE_BEGIN
41 std::unordered_map
<std::string
, std::vector
<Cell
*>> _cells
{};
43 // XXX(aki): this was pulled from the json backend, needs to be pulled
44 // out possibly into some sort of utilities file, or integrated into rtlil.h
46 string
get_string(string str
)
57 // XXX(aki): I know this is far from ideal but i'm out of spoons and cant focus so
58 // it'll have to do for now,
59 void coalesce_cells(Module
* mod
)
61 for (auto cell
: mod
->cells()) {
62 const auto cell_type
= get_string(RTLIL::unescape_id(cell
->type
));
64 if (_cells
.find(cell_type
) == _cells
.end())
65 _cells
.emplace(cell_type
, std::vector
<Cell
*>());
67 _cells
.at(cell_type
).push_back(cell
);
72 MetadataWriter(std::ostream
&f
, bool use_selection
) noexcept
: f
{f
}, _use_selection
{use_selection
} { }
74 void write_metadata(Design
*design
)
76 log_assert(design
!= nullptr);
81 f
<< stringf(" \"generator\": %s,\n", get_string(yosys_version_str
).c_str());
82 // XXX(aki): Replace this with a proper version info eventually:tm:
83 f
<< stringf(" \"version\": \"0.0.0\",\n");
84 f
<< stringf(" \"modules\": [\n");
87 for (auto mod
: _use_selection
? design
->selected_modules() : design
->modules()) {
101 void write_module(Module
* mod
)
103 log_assert(mod
!= nullptr);
107 f
<< stringf(" {\n");
108 f
<< stringf(" \"name\": %s,\n", get_string(RTLIL::unescape_id(mod
->name
)).c_str());
109 f
<< stringf(" \"cell_sorts\": [\n");
111 bool first_sort
{true};
112 for (auto& sort
: _cells
) {
116 write_cell_sort(sort
);
121 f
<< stringf(" ],\n");
122 f
<< stringf(" \"connections\": [\n");
124 f
<< stringf(" ]\n");
129 void write_cell_sort(std::pair
<const std::string
, std::vector
<Cell
*>>& sort
)
131 const auto port_cell
= sort
.second
.front();
133 f
<< stringf(" {\n");
134 f
<< stringf(" \"type\": %s,\n", sort
.first
.c_str());
135 f
<< stringf(" \"ports\": [\n");
137 bool first_port
{true};
138 for (auto con
: port_cell
->connections()) {
142 f
<< stringf(" {\n");
143 f
<< stringf(" \"name\": %s,\n", get_string(RTLIL::unescape_id(con
.first
)).c_str());
144 f
<< stringf(" \"direction\": \"");
145 if (port_cell
->input(con
.first
))
147 if (port_cell
->input(con
.first
))
149 f
<< stringf("\",\n");
150 if (con
.second
.size() == 1)
151 f
<< stringf(" \"range\": [0, 0]\n");
153 f
<< stringf(" \"range\": [%d, %d]\n", con
.second
.size(), 0);
159 f
<< stringf(" ],\n \"cells\": [\n");
160 bool first_cell
{true};
161 for (auto& cell
: sort
.second
) {
169 f
<< stringf(" ]\n");
173 void write_cell(Cell
* cell
)
175 log_assert(cell
!= nullptr);
177 f
<< stringf(" {\n");
178 f
<< stringf(" \"name\": %s,\n", get_string(RTLIL::unescape_id(cell
->name
)).c_str());
179 f
<< stringf(" \"attributes\": {\n");
180 f
<< stringf(" },\n");
181 f
<< stringf(" \"parameters\": {\n");
182 f
<< stringf(" },\n");
187 struct MetadataBackend
: public Backend
{
188 MetadataBackend() : Backend("metadata", "generate design metadata") { }
191 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
193 log(" metadata [options] [selection]\n");
195 log("Write a JSON metadata for the current design\n");
200 void execute(std::ostream
*&f
, std::string filename
, std::vector
<std::string
> args
, RTLIL::Design
*design
) override
203 extra_args(f
, filename
, args
, argidx
);
205 log_header(design
, "Executing metadata backend.\n");
207 MetadataWriter
metadata_writier(*f
, false);
208 metadata_writier
.write_metadata(design
);
214 struct MetadataPass
: public Pass
{
215 MetadataPass() : Pass("metadata", "write design metadata") { }
219 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
221 log(" metadata [options] [selection]\n");
223 log("Write a JSON metadata for the current design\n");
225 log(" -o <filename>\n");
226 log(" write to the specified file.\n");
228 log("See 'help write_metadata' for a description of the JSON format used.\n");
231 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) override
233 std::string filename
{};
236 for (argidx
= 1; argidx
< args
.size(); argidx
++)
238 if (args
[argidx
] == "-o" && argidx
+1 < args
.size()) {
239 filename
= args
[++argidx
];
244 extra_args(args
, argidx
, design
);
247 std::stringstream buf
;
249 if (!filename
.empty()) {
250 rewrite_filename(filename
);
251 std::ofstream
*ff
= new std::ofstream
;
252 ff
->open(filename
.c_str(), std::ofstream::trunc
);
255 log_error("Can't open file `%s' for writing: %s\n", filename
.c_str(), strerror(errno
));
263 MetadataWriter
metadata_writier(*f
, false);
264 metadata_writier
.write_metadata(design
);
266 if (!filename
.empty()) {
269 log("%s", buf
.str().c_str());
275 PRIVATE_NAMESPACE_END