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 * The Verilog frontend.
22 * This frontend is using the AST frontend library (see frontends/ast/).
23 * Thus this frontend does not generate RTLIL code directly but creates an
24 * AST directly from the Verilog parse tree and then passes this AST to
25 * the AST frontend library.
29 #include "verilog_frontend.h"
30 #include "kernel/yosys.h"
31 #include "libs/sha1/sha1.h"
35 using namespace VERILOG_FRONTEND
;
37 // use the Verilog bison/flex parser to generate an AST and use AST::process() to convert it to RTLIL
39 static std::vector
<std::string
> verilog_defaults
;
40 static std::list
<std::vector
<std::string
>> verilog_defaults_stack
;
42 static void error_on_dpi_function(AST::AstNode
*node
)
44 if (node
->type
== AST::AST_DPI_FUNCTION
)
45 log_file_error(node
->filename
, node
->linenum
, "Found DPI function %s.\n", node
->str
.c_str());
46 for (auto child
: node
->children
)
47 error_on_dpi_function(child
);
50 struct VerilogFrontend
: public Frontend
{
51 VerilogFrontend() : Frontend("verilog", "read modules from Verilog file") { }
52 void help() YS_OVERRIDE
54 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
56 log(" read_verilog [options] [filename]\n");
58 log("Load modules from a Verilog file to the current design. A large subset of\n");
59 log("Verilog-2005 is supported.\n");
62 log(" enable support for SystemVerilog features. (only a small subset\n");
63 log(" of SystemVerilog is supported)\n");
66 log(" enable support for SystemVerilog assertions and some Yosys extensions\n");
67 log(" replace the implicit -D SYNTHESIS with -D FORMAL\n");
70 log(" ignore assert() statements\n");
73 log(" ignore assume() statements\n");
75 log(" -norestrict\n");
76 log(" ignore restrict() statements\n");
78 log(" -assume-asserts\n");
79 log(" treat all assert() statements like assume() statements\n");
81 log(" -assert-assumes\n");
82 log(" treat all assume() statements like assert() statements\n");
85 log(" alias for -dump_ast1 -dump_ast2 -dump_vlog1 -dump_vlog2 -yydebug\n");
88 log(" dump abstract syntax tree (before simplification)\n");
91 log(" dump abstract syntax tree (after simplification)\n");
93 log(" -no_dump_ptr\n");
94 log(" do not include hex memory addresses in dump (easier to diff dumps)\n");
96 log(" -dump_vlog1\n");
97 log(" dump ast as Verilog code (before simplification)\n");
99 log(" -dump_vlog2\n");
100 log(" dump ast as Verilog code (after simplification)\n");
102 log(" -dump_rtlil\n");
103 log(" dump generated RTLIL netlist\n");
106 log(" enable parser debug output\n");
108 log(" -nolatches\n");
109 log(" usually latches are synthesized into logic loops\n");
110 log(" this option prohibits this and sets the output to 'x'\n");
111 log(" in what would be the latches hold condition\n");
113 log(" this behavior can also be achieved by setting the\n");
114 log(" 'nolatches' attribute on the respective module or\n");
115 log(" always block.\n");
117 log(" -nomem2reg\n");
118 log(" under certain conditions memories are converted to registers\n");
119 log(" early during simplification to ensure correct handling of\n");
120 log(" complex corner cases. this option disables this behavior.\n");
122 log(" this can also be achieved by setting the 'nomem2reg'\n");
123 log(" attribute on the respective module or register.\n");
125 log(" This is potentially dangerous. Usually the front-end has good\n");
126 log(" reasons for converting an array to a list of registers.\n");
127 log(" Prohibiting this step will likely result in incorrect synthesis\n");
131 log(" always convert memories to registers. this can also be\n");
132 log(" achieved by setting the 'mem2reg' attribute on the respective\n");
133 log(" module or register.\n");
135 log(" -nomeminit\n");
136 log(" do not infer $meminit cells and instead convert initialized\n");
137 log(" memories to registers directly in the front-end.\n");
140 log(" dump Verilog code after pre-processor\n");
143 log(" do not run the pre-processor\n");
146 log(" disable DPI-C support\n");
148 log(" -noblackbox\n");
149 log(" do not automatically add a (* blackbox *) attribute to an\n");
150 log(" empty module.\n");
153 log(" only create empty blackbox modules. This implies -DBLACKBOX.\n");
154 log(" modules with the (* whitebox *) attribute will be preserved.\n");
155 log(" (* lib_whitebox *) will be treated like (* whitebox *).\n");
158 log(" delete (* whitebox *) and (* lib_whitebox *) attributes from\n");
159 log(" all modules.\n");
162 log(" parse and import specify blocks\n");
165 log(" don't perform basic optimizations (such as const folding) in the\n");
166 log(" high-level front-end.\n");
169 log(" interpret cell types starting with '$' as internal cell types\n");
172 log(" add a wire for each module parameter\n");
174 log(" -nooverwrite\n");
175 log(" ignore re-definitions of modules. (the default behavior is to\n");
176 log(" create an error message if the existing module is not a black box\n");
177 log(" module, and overwrite the existing module otherwise.)\n");
179 log(" -overwrite\n");
180 log(" overwrite existing modules with the same name\n");
183 log(" only read the abstract syntax tree and defer actual compilation\n");
184 log(" to a later 'hierarchy' command. Useful in cases where the default\n");
185 log(" parameters of modules yield invalid or not synthesizable code.\n");
187 log(" -noautowire\n");
188 log(" make the default of `default_nettype be \"none\" instead of \"wire\".\n");
190 log(" -setattr <attribute_name>\n");
191 log(" set the specified attribute (to the value 1) on all loaded modules\n");
193 log(" -Dname[=definition]\n");
194 log(" define the preprocessor symbol 'name' and set its optional value\n");
195 log(" 'definition'\n");
198 log(" add 'dir' to the directories which are used when searching include\n");
201 log("The command 'verilog_defaults' can be used to register default options for\n");
202 log("subsequent calls to 'read_verilog'.\n");
204 log("Note that the Verilog frontend does a pretty good job of processing valid\n");
205 log("verilog input, but has not very good error reporting. It generally is\n");
206 log("recommended to use a simulator (for example Icarus Verilog) for checking\n");
207 log("the syntax of the code, rather than to rely on read_verilog for that.\n");
209 log("Depending on if read_verilog is run in -formal mode, either the macro\n");
210 log("SYNTHESIS or FORMAL is defined automatically. In addition, read_verilog\n");
211 log("always defines the macro YOSYS.\n");
213 log("See the Yosys README file for a list of non-standard Verilog features\n");
214 log("supported by the Yosys Verilog front-end.\n");
217 void execute(std::istream
*&f
, std::string filename
, std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
219 bool flag_dump_ast1
= false;
220 bool flag_dump_ast2
= false;
221 bool flag_no_dump_ptr
= false;
222 bool flag_dump_vlog1
= false;
223 bool flag_dump_vlog2
= false;
224 bool flag_dump_rtlil
= false;
225 bool flag_nolatches
= false;
226 bool flag_nomeminit
= false;
227 bool flag_nomem2reg
= false;
228 bool flag_mem2reg
= false;
229 bool flag_ppdump
= false;
230 bool flag_nopp
= false;
231 bool flag_nodpi
= false;
232 bool flag_noopt
= false;
233 bool flag_icells
= false;
234 bool flag_pwires
= false;
235 bool flag_nooverwrite
= false;
236 bool flag_overwrite
= false;
237 bool flag_defer
= false;
238 bool flag_noblackbox
= false;
239 bool flag_nowb
= false;
240 std::map
<std::string
, std::string
> defines_map
;
241 std::list
<std::string
> include_dirs
;
242 std::list
<std::string
> attributes
;
244 frontend_verilog_yydebug
= false;
247 norestrict_mode
= false;
248 assume_asserts_mode
= false;
250 specify_mode
= false;
251 default_nettype_wire
= true;
253 args
.insert(args
.begin()+1, verilog_defaults
.begin(), verilog_defaults
.end());
256 for (argidx
= 1; argidx
< args
.size(); argidx
++) {
257 std::string arg
= args
[argidx
];
262 if (arg
== "-formal") {
266 if (arg
== "-noassert") {
267 noassert_mode
= true;
270 if (arg
== "-noassume") {
271 noassume_mode
= true;
274 if (arg
== "-norestrict") {
275 norestrict_mode
= true;
278 if (arg
== "-assume-asserts") {
279 assume_asserts_mode
= true;
282 if (arg
== "-assert-assumes") {
283 assert_assumes_mode
= true;
286 if (arg
== "-debug") {
287 flag_dump_ast1
= true;
288 flag_dump_ast2
= true;
289 flag_dump_vlog1
= true;
290 flag_dump_vlog2
= true;
291 frontend_verilog_yydebug
= true;
294 if (arg
== "-dump_ast1") {
295 flag_dump_ast1
= true;
298 if (arg
== "-dump_ast2") {
299 flag_dump_ast2
= true;
302 if (arg
== "-no_dump_ptr") {
303 flag_no_dump_ptr
= true;
306 if (arg
== "-dump_vlog1") {
307 flag_dump_vlog1
= true;
310 if (arg
== "-dump_vlog2") {
311 flag_dump_vlog2
= true;
314 if (arg
== "-dump_rtlil") {
315 flag_dump_rtlil
= true;
318 if (arg
== "-yydebug") {
319 frontend_verilog_yydebug
= true;
322 if (arg
== "-nolatches") {
323 flag_nolatches
= true;
326 if (arg
== "-nomeminit") {
327 flag_nomeminit
= true;
330 if (arg
== "-nomem2reg") {
331 flag_nomem2reg
= true;
334 if (arg
== "-mem2reg") {
338 if (arg
== "-ppdump") {
342 if (arg
== "-nopp") {
346 if (arg
== "-nodpi") {
350 if (arg
== "-noblackbox") {
351 flag_noblackbox
= true;
356 defines_map
["BLACKBOX"] = string();
359 if (arg
== "-nowb") {
363 if (arg
== "-specify") {
367 if (arg
== "-noopt") {
371 if (arg
== "-icells") {
375 if (arg
== "-pwires") {
379 if (arg
== "-ignore_redef" || arg
== "-nooverwrite") {
380 flag_nooverwrite
= true;
381 flag_overwrite
= false;
384 if (arg
== "-overwrite") {
385 flag_nooverwrite
= false;
386 flag_overwrite
= true;
389 if (arg
== "-defer") {
393 if (arg
== "-noautowire") {
394 default_nettype_wire
= false;
397 if (arg
== "-setattr" && argidx
+1 < args
.size()) {
398 attributes
.push_back(RTLIL::escape_id(args
[++argidx
]));
401 if (arg
== "-D" && argidx
+1 < args
.size()) {
402 std::string name
= args
[++argidx
], value
;
403 size_t equal
= name
.find('=');
404 if (equal
!= std::string::npos
) {
405 value
= name
.substr(equal
+1);
406 name
= name
.substr(0, equal
);
408 defines_map
[name
] = value
;
411 if (arg
.compare(0, 2, "-D") == 0) {
412 size_t equal
= arg
.find('=', 2);
413 std::string name
= arg
.substr(2, equal
-2);
415 if (equal
!= std::string::npos
)
416 value
= arg
.substr(equal
+1);
417 defines_map
[name
] = value
;
420 if (arg
== "-I" && argidx
+1 < args
.size()) {
421 include_dirs
.push_back(args
[++argidx
]);
424 if (arg
.compare(0, 2, "-I") == 0) {
425 include_dirs
.push_back(arg
.substr(2));
430 extra_args(f
, filename
, args
, argidx
);
432 log_header(design
, "Executing Verilog-2005 frontend: %s\n", filename
.c_str());
434 log("Parsing %s%s input from `%s' to AST representation.\n",
435 formal_mode
? "formal " : "", sv_mode
? "SystemVerilog" : "Verilog", filename
.c_str());
437 AST::current_filename
= filename
;
438 AST::set_line_num
= &frontend_verilog_yyset_lineno
;
439 AST::get_line_num
= &frontend_verilog_yyget_lineno
;
441 current_ast
= new AST::AstNode(AST::AST_DESIGN
);
444 std::string code_after_preproc
;
447 code_after_preproc
= frontend_verilog_preproc(*f
, filename
, defines_map
, design
->verilog_defines
, include_dirs
);
449 log("-- Verilog code after preprocessor --\n%s-- END OF DUMP --\n", code_after_preproc
.c_str());
450 lexin
= new std::istringstream(code_after_preproc
);
453 frontend_verilog_yyset_lineno(1);
454 frontend_verilog_yyrestart(NULL
);
455 frontend_verilog_yyparse();
456 frontend_verilog_yylex_destroy();
458 for (auto &child
: current_ast
->children
) {
459 if (child
->type
== AST::AST_MODULE
)
460 for (auto &attr
: attributes
)
461 if (child
->attributes
.count(attr
) == 0)
462 child
->attributes
[attr
] = AST::AstNode::mkconst_int(1, false);
466 error_on_dpi_function(current_ast
);
468 AST::process(design
, current_ast
, flag_dump_ast1
, flag_dump_ast2
, flag_no_dump_ptr
, flag_dump_vlog1
, flag_dump_vlog2
, flag_dump_rtlil
, flag_nolatches
,
469 flag_nomeminit
, flag_nomem2reg
, flag_mem2reg
, flag_noblackbox
, lib_mode
, flag_nowb
, flag_noopt
, flag_icells
, flag_pwires
, flag_nooverwrite
, flag_overwrite
, flag_defer
, default_nettype_wire
);
477 log("Successfully finished Verilog frontend.\n");
481 struct VerilogDefaults
: public Pass
{
482 VerilogDefaults() : Pass("verilog_defaults", "set default options for read_verilog") { }
483 void help() YS_OVERRIDE
485 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
487 log(" verilog_defaults -add [options]\n");
489 log("Add the specified options to the list of default options to read_verilog.\n");
492 log(" verilog_defaults -clear\n");
494 log("Clear the list of Verilog default options.\n");
497 log(" verilog_defaults -push\n");
498 log(" verilog_defaults -pop\n");
500 log("Push or pop the list of default options to a stack. Note that -push does\n");
501 log("not imply -clear.\n");
504 void execute(std::vector
<std::string
> args
, RTLIL::Design
*) YS_OVERRIDE
507 cmd_error(args
, 1, "Missing argument.");
509 if (args
[1] == "-add") {
510 verilog_defaults
.insert(verilog_defaults
.end(), args
.begin()+2, args
.end());
514 if (args
.size() != 2)
515 cmd_error(args
, 2, "Extra argument.");
517 if (args
[1] == "-clear") {
518 verilog_defaults
.clear();
522 if (args
[1] == "-push") {
523 verilog_defaults_stack
.push_back(verilog_defaults
);
527 if (args
[1] == "-pop") {
528 if (verilog_defaults_stack
.empty()) {
529 verilog_defaults
.clear();
531 verilog_defaults
.swap(verilog_defaults_stack
.back());
532 verilog_defaults_stack
.pop_back();
539 struct VerilogDefines
: public Pass
{
540 VerilogDefines() : Pass("verilog_defines", "define and undefine verilog defines") { }
541 void help() YS_OVERRIDE
543 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
545 log(" verilog_defines [options]\n");
547 log("Define and undefine verilog preprocessor macros.\n");
549 log(" -Dname[=definition]\n");
550 log(" define the preprocessor symbol 'name' and set its optional value\n");
551 log(" 'definition'\n");
553 log(" -Uname[=definition]\n");
554 log(" undefine the preprocessor symbol 'name'\n");
557 void execute(std::vector
<std::string
> args
, RTLIL::Design
*design
) YS_OVERRIDE
560 for (argidx
= 1; argidx
< args
.size(); argidx
++) {
561 std::string arg
= args
[argidx
];
562 if (arg
== "-D" && argidx
+1 < args
.size()) {
563 std::string name
= args
[++argidx
], value
;
564 size_t equal
= name
.find('=');
565 if (equal
!= std::string::npos
) {
566 value
= name
.substr(equal
+1);
567 name
= name
.substr(0, equal
);
569 design
->verilog_defines
[name
] = std::pair
<std::string
, bool>(value
, false);
572 if (arg
.compare(0, 2, "-D") == 0) {
573 size_t equal
= arg
.find('=', 2);
574 std::string name
= arg
.substr(2, equal
-2);
576 if (equal
!= std::string::npos
)
577 value
= arg
.substr(equal
+1);
578 design
->verilog_defines
[name
] = std::pair
<std::string
, bool>(value
, false);
581 if (arg
== "-U" && argidx
+1 < args
.size()) {
582 std::string name
= args
[++argidx
];
583 design
->verilog_defines
.erase(name
);
586 if (arg
.compare(0, 2, "-U") == 0) {
587 std::string name
= arg
.substr(2);
588 design
->verilog_defines
.erase(name
);
594 if (args
.size() != argidx
)
595 cmd_error(args
, argidx
, "Extra argument.");
601 // the yyerror function used by bison to report parser errors
602 void frontend_verilog_yyerror(char const *fmt
, ...)
608 p
+= vsnprintf(p
, buffer
+ sizeof(buffer
) - p
, fmt
, ap
);
610 p
+= snprintf(p
, buffer
+ sizeof(buffer
) - p
, "\n");
611 YOSYS_NAMESPACE_PREFIX
log_file_error(YOSYS_NAMESPACE_PREFIX
AST::current_filename
, frontend_verilog_yyget_lineno(),