2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
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 #include "kernel/yosys.h"
26 char type
; // S=String, N=Number, A=Array, D=Dict
29 vector
<JsonNode
*> data_array
;
30 dict
<string
, JsonNode
*> data_dict
;
31 vector
<string
> data_dict_keys
;
33 JsonNode(std::istream
&f
)
43 log_error("Unexpected EOF in JSON file.\n");
45 if (ch
== ' ' || ch
== '\t' || ch
== '\r' || ch
== '\n')
57 log_error("Unexpected EOF in JSON string.\n");
66 log_error("Unexpected EOF in JSON string.\n");
75 if ('0' <= ch
&& ch
<= '9')
78 data_number
= ch
- '0';
91 if (ch
< '0' || '9' < ch
) {
96 data_number
= data_number
*10 + (ch
- '0');
115 if (ch
< '0' || '9' < ch
) {
135 log_error("Unexpected EOF in JSON file.\n");
137 if (ch
== ' ' || ch
== '\t' || ch
== '\r' || ch
== '\n' || ch
== ',')
144 data_array
.push_back(new JsonNode(f
));
159 log_error("Unexpected EOF in JSON file.\n");
161 if (ch
== ' ' || ch
== '\t' || ch
== '\r' || ch
== '\n' || ch
== ',')
175 log_error("Unexpected EOF in JSON file.\n");
177 if (ch
== ' ' || ch
== '\t' || ch
== '\r' || ch
== '\n' || ch
== ':')
184 JsonNode
*value
= new JsonNode(f
);
187 log_error("Unexpected non-string key in JSON dict.\n");
189 data_dict
[key
.data_string
] = value
;
190 data_dict_keys
.push_back(key
.data_string
);
196 log_error("Unexpected character in JSON file: '%c'\n", ch
);
202 for (auto it
: data_array
)
204 for (auto &it
: data_dict
)
209 void json_parse_attr_param(dict
<IdString
, Const
> &results
, JsonNode
*node
)
211 if (node
->type
!= 'D')
212 log_error("JSON attributes or parameters node is not a dictionary.\n");
214 for (auto it
: node
->data_dict
)
216 IdString key
= RTLIL::escape_id(it
.first
.c_str());
217 JsonNode
*value_node
= it
.second
;
220 if (value_node
->type
== 'S') {
221 string
&s
= value_node
->data_string
;
222 if (s
.find_first_not_of("01xz") == string::npos
)
223 value
= Const::from_string(s
);
227 if (value_node
->type
== 'N') {
228 value
= Const(value_node
->data_number
, 32);
230 if (value_node
->type
== 'A') {
231 log_error("JSON attribute or parameter value is an array.\n");
233 if (value_node
->type
== 'D') {
234 log_error("JSON attribute or parameter value is a dict.\n");
239 results
[key
] = value
;
243 void json_import(Design
*design
, string
&modname
, JsonNode
*node
)
245 log("Importing module %s from JSON tree.\n", modname
.c_str());
247 Module
*module
= new RTLIL::Module
;
248 module
->name
= RTLIL::escape_id(modname
.c_str());
250 if (design
->module(module
->name
))
251 log_error("Re-definition of module %s.\n", log_id(module
->name
));
255 if (node
->data_dict
.count("attributes"))
256 json_parse_attr_param(module
->attributes
, node
->data_dict
.at("attributes"));
258 dict
<int, SigBit
> signal_bits
;
260 if (node
->data_dict
.count("ports"))
262 JsonNode
*ports_node
= node
->data_dict
.at("ports");
264 if (ports_node
->type
!= 'D')
265 log_error("JSON ports node is not a dictionary.\n");
267 for (int port_id
= 1; port_id
<= GetSize(ports_node
->data_dict_keys
); port_id
++)
269 IdString port_name
= RTLIL::escape_id(ports_node
->data_dict_keys
[port_id
-1].c_str());
270 JsonNode
*port_node
= ports_node
->data_dict
.at(ports_node
->data_dict_keys
[port_id
-1]);
272 if (port_node
->type
!= 'D')
273 log_error("JSON port node '%s' is not a dictionary.\n", log_id(port_name
));
275 if (port_node
->data_dict
.count("direction") == 0)
276 log_error("JSON port node '%s' has no direction attribute.\n", log_id(port_name
));
278 if (port_node
->data_dict
.count("bits") == 0)
279 log_error("JSON port node '%s' has no bits attribute.\n", log_id(port_name
));
281 JsonNode
*port_direction_node
= port_node
->data_dict
.at("direction");
282 JsonNode
*port_bits_node
= port_node
->data_dict
.at("bits");
284 if (port_direction_node
->type
!= 'S')
285 log_error("JSON port node '%s' has non-string direction attribute.\n", log_id(port_name
));
287 if (port_bits_node
->type
!= 'A')
288 log_error("JSON port node '%s' has non-array bits attribute.\n", log_id(port_name
));
290 Wire
*port_wire
= module
->wire(port_name
);
292 if (port_wire
== nullptr)
293 port_wire
= module
->addWire(port_name
, GetSize(port_bits_node
->data_array
));
295 if (port_direction_node
->data_string
== "input") {
296 port_wire
->port_input
= true;
298 if (port_direction_node
->data_string
== "output") {
299 port_wire
->port_output
= true;
301 if (port_direction_node
->data_string
== "inout") {
302 port_wire
->port_input
= true;
303 port_wire
->port_output
= true;
305 log_error("JSON port node '%s' has invalid '%s' direction attribute.\n", log_id(port_name
), port_direction_node
->data_string
.c_str());
307 port_wire
->port_id
= port_id
;
309 for (int i
= 0; i
< GetSize(port_bits_node
->data_array
); i
++)
311 JsonNode
*bitval_node
= port_bits_node
->data_array
.at(i
);
312 SigBit
sigbit(port_wire
, i
);
314 if (bitval_node
->type
== 'S') {
315 if (bitval_node
->data_string
== "0")
316 module
->connect(sigbit
, State::S0
);
317 else if (bitval_node
->data_string
== "1")
318 module
->connect(sigbit
, State::S1
);
319 else if (bitval_node
->data_string
== "x")
320 module
->connect(sigbit
, State::Sx
);
321 else if (bitval_node
->data_string
== "z")
322 module
->connect(sigbit
, State::Sz
);
324 log_error("JSON port node '%s' has invalid '%s' bit string value on bit %d.\n",
325 log_id(port_name
), bitval_node
->data_string
.c_str(), i
);
327 if (bitval_node
->type
== 'N') {
328 int bitidx
= bitval_node
->data_number
;
329 if (signal_bits
.count(bitidx
)) {
330 if (port_wire
->port_output
) {
331 module
->connect(sigbit
, signal_bits
.at(bitidx
));
333 module
->connect(signal_bits
.at(bitidx
), sigbit
);
334 signal_bits
[bitidx
] = sigbit
;
337 signal_bits
[bitidx
] = sigbit
;
340 log_error("JSON port node '%s' has invalid bit value on bit %d.\n", log_id(port_name
), i
);
344 module
->fixup_ports();
347 if (node
->data_dict
.count("netnames"))
349 JsonNode
*netnames_node
= node
->data_dict
.at("netnames");
351 if (netnames_node
->type
!= 'D')
352 log_error("JSON netnames node is not a dictionary.\n");
354 for (auto &net
: netnames_node
->data_dict
)
356 IdString net_name
= RTLIL::escape_id(net
.first
.c_str());
357 JsonNode
*net_node
= net
.second
;
359 if (net_node
->type
!= 'D')
360 log_error("JSON netname node '%s' is not a dictionary.\n", log_id(net_name
));
362 if (net_node
->data_dict
.count("bits") == 0)
363 log_error("JSON netname node '%s' has no bits attribute.\n", log_id(net_name
));
365 JsonNode
*bits_node
= net_node
->data_dict
.at("bits");
367 if (bits_node
->type
!= 'A')
368 log_error("JSON netname node '%s' has non-array bits attribute.\n", log_id(net_name
));
370 Wire
*wire
= module
->wire(net_name
);
373 wire
= module
->addWire(net_name
, GetSize(bits_node
->data_array
));
375 for (int i
= 0; i
< GetSize(bits_node
->data_array
); i
++)
377 JsonNode
*bitval_node
= bits_node
->data_array
.at(i
);
378 SigBit
sigbit(wire
, i
);
380 if (bitval_node
->type
== 'S') {
381 if (bitval_node
->data_string
== "0")
382 module
->connect(sigbit
, State::S0
);
383 else if (bitval_node
->data_string
== "1")
384 module
->connect(sigbit
, State::S1
);
385 else if (bitval_node
->data_string
== "x")
386 module
->connect(sigbit
, State::Sx
);
387 else if (bitval_node
->data_string
== "z")
388 module
->connect(sigbit
, State::Sz
);
390 log_error("JSON netname node '%s' has invalid '%s' bit string value on bit %d.\n",
391 log_id(net_name
), bitval_node
->data_string
.c_str(), i
);
393 if (bitval_node
->type
== 'N') {
394 int bitidx
= bitval_node
->data_number
;
395 if (signal_bits
.count(bitidx
)) {
396 if (sigbit
!= signal_bits
.at(bitidx
))
397 module
->connect(sigbit
, signal_bits
.at(bitidx
));
399 signal_bits
[bitidx
] = sigbit
;
402 log_error("JSON netname node '%s' has invalid bit value on bit %d.\n", log_id(net_name
), i
);
405 if (net_node
->data_dict
.count("attributes"))
406 json_parse_attr_param(wire
->attributes
, net_node
->data_dict
.at("attributes"));
410 if (node
->data_dict
.count("cells"))
412 JsonNode
*cells_node
= node
->data_dict
.at("cells");
414 if (cells_node
->type
!= 'D')
415 log_error("JSON cells node is not a dictionary.\n");
417 for (auto &cell_node_it
: cells_node
->data_dict
)
419 IdString cell_name
= RTLIL::escape_id(cell_node_it
.first
.c_str());
420 JsonNode
*cell_node
= cell_node_it
.second
;
422 if (cell_node
->type
!= 'D')
423 log_error("JSON cells node '%s' is not a dictionary.\n", log_id(cell_name
));
425 if (cell_node
->data_dict
.count("type") == 0)
426 log_error("JSON cells node '%s' has no type attribute.\n", log_id(cell_name
));
428 JsonNode
*type_node
= cell_node
->data_dict
.at("type");
430 if (type_node
->type
!= 'S')
431 log_error("JSON cells node '%s' has a non-string type.\n", log_id(cell_name
));
433 IdString cell_type
= RTLIL::escape_id(type_node
->data_string
.c_str());
435 Cell
*cell
= module
->addCell(cell_name
, cell_type
);
437 if (cell_node
->data_dict
.count("connections") == 0)
438 log_error("JSON cells node '%s' has no connections attribute.\n", log_id(cell_name
));
440 JsonNode
*connections_node
= cell_node
->data_dict
.at("connections");
442 if (connections_node
->type
!= 'D')
443 log_error("JSON cells node '%s' has non-dictionary connections attribute.\n", log_id(cell_name
));
445 for (auto &conn_it
: connections_node
->data_dict
)
447 IdString conn_name
= RTLIL::escape_id(conn_it
.first
.c_str());
448 JsonNode
*conn_node
= conn_it
.second
;
450 if (conn_node
->type
!= 'A')
451 log_error("JSON cells node '%s' connection '%s' is not an array.\n", log_id(cell_name
), log_id(conn_name
));
455 for (int i
= 0; i
< GetSize(conn_node
->data_array
); i
++)
457 JsonNode
*bitval_node
= conn_node
->data_array
.at(i
);
459 if (bitval_node
->type
== 'S') {
460 if (bitval_node
->data_string
== "0")
461 sig
.append(State::S0
);
462 else if (bitval_node
->data_string
== "1")
463 sig
.append(State::S1
);
464 else if (bitval_node
->data_string
== "x")
465 sig
.append(State::Sx
);
466 else if (bitval_node
->data_string
== "z")
467 sig
.append(State::Sz
);
469 log_error("JSON cells node '%s' connection '%s' has invalid '%s' bit string value on bit %d.\n",
470 log_id(cell_name
), log_id(conn_name
), bitval_node
->data_string
.c_str(), i
);
472 if (bitval_node
->type
== 'N') {
473 int bitidx
= bitval_node
->data_number
;
474 if (signal_bits
.count(bitidx
) == 0)
475 signal_bits
[bitidx
] = module
->addWire(NEW_ID
);
476 sig
.append(signal_bits
.at(bitidx
));
478 log_error("JSON cells node '%s' connection '%s' has invalid bit value on bit %d.\n",
479 log_id(cell_name
), log_id(conn_name
), i
);
483 cell
->setPort(conn_name
, sig
);
486 if (cell_node
->data_dict
.count("attributes"))
487 json_parse_attr_param(cell
->attributes
, cell_node
->data_dict
.at("attributes"));
489 if (cell_node
->data_dict
.count("parameters"))
490 json_parse_attr_param(cell
->parameters
, cell_node
->data_dict
.at("parameters"));
495 struct JsonFrontend
: public Frontend
{
496 JsonFrontend() : Frontend("json", "read JSON file") { }
497 void help() YS_OVERRIDE
499 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
501 log(" read_json [filename]\n");
503 log("Load modules from a JSON file into the current design See \"help write_json\"\n");
504 log("for a description of the file format.\n");
507 void execute(std::istream
*&f
, std::string filename
, std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
509 log_header(design
, "Executing JSON frontend.\n");
512 for (argidx
= 1; argidx
< args
.size(); argidx
++) {
513 // std::string arg = args[argidx];
514 // if (arg == "-sop") {
520 extra_args(f
, filename
, args
, argidx
);
524 if (root
.type
!= 'D')
525 log_error("JSON root node is not a dictionary.\n");
527 if (root
.data_dict
.count("modules") != 0)
529 JsonNode
*modules
= root
.data_dict
.at("modules");
531 if (modules
->type
!= 'D')
532 log_error("JSON modules node is not a dictionary.\n");
534 for (auto &it
: modules
->data_dict
)
535 json_import(design
, it
.first
, it
.second
);