yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
verilog_frontend.cc
Go to the documentation of this file.
1 /*
2  * yosys -- Yosys Open SYnthesis Suite
3  *
4  * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5  *
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.
9  *
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.
17  *
18  * ---
19  *
20  * The Verilog frontend.
21  *
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.
26  *
27  */
28 
29 #include "verilog_frontend.h"
30 #include "kernel/yosys.h"
31 #include "libs/sha1/sha1.h"
32 #include <stdarg.h>
33 
35 using namespace VERILOG_FRONTEND;
36 
37 // use the Verilog bison/flex parser to generate an AST and use AST::process() to convert it to RTLIL
38 
39 static std::vector<std::string> verilog_defaults;
40 static std::list<std::vector<std::string>> verilog_defaults_stack;
41 
42 struct VerilogFrontend : public Frontend {
43  VerilogFrontend() : Frontend("verilog", "read modules from verilog file") { }
44  virtual void help()
45  {
46  // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
47  log("\n");
48  log(" read_verilog [options] [filename]\n");
49  log("\n");
50  log("Load modules from a verilog file to the current design. A large subset of\n");
51  log("Verilog-2005 is supported.\n");
52  log("\n");
53  log(" -sv\n");
54  log(" enable support for SystemVerilog features. (only a small subset\n");
55  log(" of SystemVerilog is supported)\n");
56  log("\n");
57  log(" -dump_ast1\n");
58  log(" dump abstract syntax tree (before simplification)\n");
59  log("\n");
60  log(" -dump_ast2\n");
61  log(" dump abstract syntax tree (after simplification)\n");
62  log("\n");
63  log(" -dump_vlog\n");
64  log(" dump ast as verilog code (after simplification)\n");
65  log("\n");
66  log(" -yydebug\n");
67  log(" enable parser debug output\n");
68  log("\n");
69  log(" -nolatches\n");
70  log(" usually latches are synthesized into logic loops\n");
71  log(" this option prohibits this and sets the output to 'x'\n");
72  log(" in what would be the latches hold condition\n");
73  log("\n");
74  log(" this behavior can also be achieved by setting the\n");
75  log(" 'nolatches' attribute on the respective module or\n");
76  log(" always block.\n");
77  log("\n");
78  log(" -nomem2reg\n");
79  log(" under certain conditions memories are converted to registers\n");
80  log(" early during simplification to ensure correct handling of\n");
81  log(" complex corner cases. this option disables this behavior.\n");
82  log("\n");
83  log(" this can also be achieved by setting the 'nomem2reg'\n");
84  log(" attribute on the respective module or register.\n");
85  log("\n");
86  log(" -mem2reg\n");
87  log(" always convert memories to registers. this can also be\n");
88  log(" achieved by setting the 'mem2reg' attribute on the respective\n");
89  log(" module or register.\n");
90  log("\n");
91  log(" -ppdump\n");
92  log(" dump verilog code after pre-processor\n");
93  log("\n");
94  log(" -nopp\n");
95  log(" do not run the pre-processor\n");
96  log("\n");
97  log(" -lib\n");
98  log(" only create empty blackbox modules\n");
99  log("\n");
100  log(" -noopt\n");
101  log(" don't perform basic optimizations (such as const folding) in the\n");
102  log(" high-level front-end.\n");
103  log("\n");
104  log(" -icells\n");
105  log(" interpret cell types starting with '$' as internal cell types\n");
106  log("\n");
107  log(" -ignore_redef\n");
108  log(" ignore re-definitions of modules. (the default behavior is to\n");
109  log(" create an error message.)\n");
110  log("\n");
111  log(" -defer\n");
112  log(" only read the abstract syntax tree and defer actual compilation\n");
113  log(" to a later 'hierarchy' command. Useful in cases where the default\n");
114  log(" parameters of modules yield invalid or not synthesizable code.\n");
115  log("\n");
116  log(" -setattr <attribute_name>\n");
117  log(" set the specified attribute (to the value 1) on all loaded modules\n");
118  log("\n");
119  log(" -Dname[=definition]\n");
120  log(" define the preprocessor symbol 'name' and set its optional value\n");
121  log(" 'definition'\n");
122  log("\n");
123  log(" -Idir\n");
124  log(" add 'dir' to the directories which are used when searching include\n");
125  log(" files\n");
126  log("\n");
127  log("The command 'verilog_defaults' can be used to register default options for\n");
128  log("subsequent calls to 'read_verilog'.\n");
129  log("\n");
130  log("Note that the Verilog frontend does a pretty good job of processing valid\n");
131  log("verilog input, but has not very good error reporting. It generally is\n");
132  log("recommended to use a simulator (for example icarus verilog) for checking\n");
133  log("the syntax of the code, rather than to rely on read_verilog for that.\n");
134  log("\n");
135  }
136  virtual void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design)
137  {
138  bool flag_dump_ast1 = false;
139  bool flag_dump_ast2 = false;
140  bool flag_dump_vlog = false;
141  bool flag_nolatches = false;
142  bool flag_nomem2reg = false;
143  bool flag_mem2reg = false;
144  bool flag_ppdump = false;
145  bool flag_nopp = false;
146  bool flag_lib = false;
147  bool flag_noopt = false;
148  bool flag_icells = false;
149  bool flag_ignore_redef = false;
150  bool flag_defer = false;
151  std::map<std::string, std::string> defines_map;
152  std::list<std::string> include_dirs;
153  std::list<std::string> attributes;
154 
155  frontend_verilog_yydebug = false;
156  sv_mode = false;
157 
158  log_header("Executing Verilog-2005 frontend.\n");
159 
160  args.insert(args.begin()+1, verilog_defaults.begin(), verilog_defaults.end());
161 
162  size_t argidx;
163  for (argidx = 1; argidx < args.size(); argidx++) {
164  std::string arg = args[argidx];
165  if (arg == "-sv") {
166  sv_mode = true;
167  continue;
168  }
169  if (arg == "-dump_ast1") {
170  flag_dump_ast1 = true;
171  continue;
172  }
173  if (arg == "-dump_ast2") {
174  flag_dump_ast2 = true;
175  continue;
176  }
177  if (arg == "-dump_vlog") {
178  flag_dump_vlog = true;
179  continue;
180  }
181  if (arg == "-yydebug") {
183  continue;
184  }
185  if (arg == "-nolatches") {
186  flag_nolatches = true;
187  continue;
188  }
189  if (arg == "-nomem2reg") {
190  flag_nomem2reg = true;
191  continue;
192  }
193  if (arg == "-mem2reg") {
194  flag_mem2reg = true;
195  continue;
196  }
197  if (arg == "-ppdump") {
198  flag_ppdump = true;
199  continue;
200  }
201  if (arg == "-nopp") {
202  flag_nopp = true;
203  continue;
204  }
205  if (arg == "-lib") {
206  flag_lib = true;
207  continue;
208  }
209  if (arg == "-noopt") {
210  flag_noopt = true;
211  continue;
212  }
213  if (arg == "-icells") {
214  flag_icells = true;
215  continue;
216  }
217  if (arg == "-ignore_redef") {
218  flag_ignore_redef = true;
219  continue;
220  }
221  if (arg == "-defer") {
222  flag_defer = true;
223  continue;
224  }
225  if (arg == "-setattr" && argidx+1 < args.size()) {
226  attributes.push_back(RTLIL::escape_id(args[++argidx]));
227  continue;
228  }
229  if (arg == "-D" && argidx+1 < args.size()) {
230  std::string name = args[++argidx], value;
231  size_t equal = name.find('=', 2);
232  if (equal != std::string::npos) {
233  value = arg.substr(equal+1);
234  name = arg.substr(0, equal);
235  }
236  defines_map[name] = value;
237  continue;
238  }
239  if (arg.compare(0, 2, "-D") == 0) {
240  size_t equal = arg.find('=', 2);
241  std::string name = arg.substr(2, equal-2);
242  std::string value;
243  if (equal != std::string::npos)
244  value = arg.substr(equal+1);
245  defines_map[name] = value;
246  continue;
247  }
248  if (arg == "-I" && argidx+1 < args.size()) {
249  include_dirs.push_back(args[++argidx]);
250  continue;
251  }
252  if (arg.compare(0, 2, "-I") == 0) {
253  include_dirs.push_back(arg.substr(2));
254  continue;
255  }
256  break;
257  }
258  extra_args(f, filename, args, argidx);
259 
260  log("Parsing %s input from `%s' to AST representation.\n", sv_mode ? "SystemVerilog" : "Verilog", filename.c_str());
261 
262  AST::current_filename = filename;
265 
267  default_nettype_wire = true;
268 
269  lexin = f;
270  std::string code_after_preproc;
271 
272  if (!flag_nopp) {
273  code_after_preproc = frontend_verilog_preproc(*f, filename, defines_map, include_dirs);
274  if (flag_ppdump)
275  log("-- Verilog code after preprocessor --\n%s-- END OF DUMP --\n", code_after_preproc.c_str());
276  lexin = new std::istringstream(code_after_preproc);
277  }
278 
283 
284  for (auto &child : current_ast->children) {
285  if (child->type == AST::AST_MODULE)
286  for (auto &attr : attributes)
287  if (child->attributes.count(attr) == 0)
288  child->attributes[attr] = AST::AstNode::mkconst_int(1, false);
289  }
290 
291  AST::process(design, current_ast, flag_dump_ast1, flag_dump_ast2, flag_dump_vlog, flag_nolatches, flag_nomem2reg, flag_mem2reg, flag_lib, flag_noopt, flag_icells, flag_ignore_redef, flag_defer, default_nettype_wire);
292 
293  if (!flag_nopp)
294  delete lexin;
295 
296  delete current_ast;
297  current_ast = NULL;
298 
299  log("Successfully finished Verilog frontend.\n");
300  }
302 
303 struct VerilogDefaults : public Pass {
304  VerilogDefaults() : Pass("verilog_defaults", "set default options for read_verilog") { }
305  virtual void help()
306  {
307  // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
308  log("\n");
309  log(" verilog_defaults -add [options]\n");
310  log("\n");
311  log("Add the sepcified options to the list of default options to read_verilog.\n");
312  log("\n");
313  log("\n");
314  log(" verilog_defaults -clear");
315  log("\n");
316  log("Clear the list of verilog default options.\n");
317  log("\n");
318  log("\n");
319  log(" verilog_defaults -push");
320  log(" verilog_defaults -pop");
321  log("\n");
322  log("Push or pop the list of default options to a stack. Note that -push does\n");
323  log("not imply -clear.\n");
324  log("\n");
325  }
326  virtual void execute(std::vector<std::string> args, RTLIL::Design*)
327  {
328  if (args.size() == 0)
329  cmd_error(args, 1, "Missing argument.");
330 
331  if (args[1] == "-add") {
332  verilog_defaults.insert(verilog_defaults.end(), args.begin()+2, args.end());
333  return;
334  }
335 
336  if (args.size() != 2)
337  cmd_error(args, 2, "Extra argument.");
338 
339  if (args[1] == "-clear") {
340  verilog_defaults.clear();
341  return;
342  }
343 
344  if (args[1] == "-push") {
346  return;
347  }
348 
349  if (args[1] == "-pop") {
350  if (verilog_defaults_stack.empty()) {
351  verilog_defaults.clear();
352  } else {
354  verilog_defaults_stack.pop_back();
355  }
356  return;
357  }
358  }
360 
362 
363 // the yyerror function used by bison to report parser errors
364 void frontend_verilog_yyerror(char const *fmt, ...)
365 {
366  va_list ap;
367  char buffer[1024];
368  char *p = buffer;
369  p += snprintf(p, buffer + sizeof(buffer) - p, "Parser error in line %s:%d: ",
371  va_start(ap, fmt);
372  p += vsnprintf(p, buffer + sizeof(buffer) - p, fmt, ap);
373  va_end(ap);
374  p += snprintf(p, buffer + sizeof(buffer) - p, "\n");
375  YOSYS_NAMESPACE_PREFIX log_error("%s", buffer);
376  exit(1);
377 }
378 
bool flag_lib
Definition: ast.cc:56
virtual void execute(std::istream *&f, std::string filename, std::vector< std::string > args, RTLIL::Design *design)
static AstNode * mkconst_int(uint32_t v, bool is_signed, int width=32)
Definition: ast.cc:672
void log_header(const char *format,...)
Definition: log.cc:188
#define YOSYS_NAMESPACE_PREFIX
Definition: yosys.h:101
#define YOSYS_NAMESPACE_END
Definition: yosys.h:100
YOSYS_NAMESPACE_END void frontend_verilog_yyerror(char const *fmt,...)
std::string frontend_verilog_preproc(std::istream &f, std::string filename, const std::map< std::string, std::string > pre_defines_map, const std::list< std::string > include_dirs)
Definition: preproc.cc:212
void(* set_line_num)(int)
Definition: ast.cc:50
bool flag_dump_ast1
Definition: ast.cc:56
void log_error(const char *format,...)
Definition: log.cc:204
static std::vector< std::string > verilog_defaults
virtual void execute(std::vector< std::string > args, RTLIL::Design *)
static std::string escape_id(std::string str)
Definition: rtlil.h:251
virtual void help()
int frontend_verilog_yyget_lineno(void)
int(* get_line_num)()
Definition: ast.cc:51
YOSYS_NAMESPACE_END int frontend_verilog_yydebug
bool flag_dump_ast2
Definition: ast.cc:56
bool flag_noopt
Definition: ast.cc:56
int frontend_verilog_yyparse(void)
Definition: register.h:27
virtual void help()
std::string current_filename
Definition: ast.cc:49
#define NULL
#define YOSYS_NAMESPACE_BEGIN
Definition: yosys.h:99
void log(const char *format,...)
Definition: log.cc:180
void frontend_verilog_yyrestart(FILE *f)
std::vector< AstNode * > children
Definition: ast.h:149
bool flag_nolatches
Definition: ast.cc:56
bool flag_mem2reg
Definition: ast.cc:56
VerilogDefaults VerilogDefaults
void process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump_ast2, bool dump_vlog, bool nolatches, bool nomem2reg, bool mem2reg, bool lib, bool noopt, bool icells, bool ignore_redef, bool defer, bool autowire)
Definition: ast.cc:967
bool flag_icells
Definition: ast.cc:56
struct AST::AstNode * current_ast
int frontend_verilog_yylex_destroy(void)
static std::list< std::vector< std::string > > verilog_defaults_stack
bool flag_nomem2reg
Definition: ast.cc:56
std::istream * lexin
VerilogFrontend VerilogFrontend
bool flag_dump_vlog
Definition: ast.cc:56
void frontend_verilog_yyset_lineno(int)