mirror of
https://github.com/YosysHQ/yosys
synced 2025-06-08 15:13:24 +00:00
Add support for SystemVerilog-style `define to Verilog frontend
This patch should support things like `define foo(a, b = 3, c) a+b+c `foo(1, ,2) which will evaluate to 1+3+2. It also spots mistakes like `foo(1) (the 3rd argument doesn't have a default value, so a call site is required to set it). Most of the patch is a simple parser for the format in preproc.cc, but I've also taken the opportunity to wrap up the "name -> definition" map in a type, rather than use multiple std::map's. Since this type needs to be visible to code that touches defines, I've pulled it (and the frontend_verilog_preproc declaration) out into a new file at frontends/verilog/preproc.h and included that where necessary. Finally, the patch adds a few tests in tests/various to check that we are parsing everything correctly.
This commit is contained in:
parent
4c38895fab
commit
044ca9dde4
11 changed files with 636 additions and 151 deletions
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
|
||||
#include "verilog_frontend.h"
|
||||
#include "preproc.h"
|
||||
#include "kernel/yosys.h"
|
||||
#include "libs/sha1/sha1.h"
|
||||
#include <stdarg.h>
|
||||
|
@ -253,7 +254,8 @@ struct VerilogFrontend : public Frontend {
|
|||
bool flag_defer = false;
|
||||
bool flag_noblackbox = false;
|
||||
bool flag_nowb = false;
|
||||
std::map<std::string, std::string> defines_map;
|
||||
define_map_t defines_map;
|
||||
|
||||
std::list<std::string> include_dirs;
|
||||
std::list<std::string> attributes;
|
||||
|
||||
|
@ -369,7 +371,7 @@ struct VerilogFrontend : public Frontend {
|
|||
}
|
||||
if (arg == "-lib") {
|
||||
lib_mode = true;
|
||||
defines_map["BLACKBOX"] = string();
|
||||
defines_map.add("BLACKBOX", "");
|
||||
continue;
|
||||
}
|
||||
if (arg == "-nowb") {
|
||||
|
@ -421,7 +423,7 @@ struct VerilogFrontend : public Frontend {
|
|||
value = name.substr(equal+1);
|
||||
name = name.substr(0, equal);
|
||||
}
|
||||
defines_map[name] = value;
|
||||
defines_map.add(name, value);
|
||||
continue;
|
||||
}
|
||||
if (arg.compare(0, 2, "-D") == 0) {
|
||||
|
@ -430,7 +432,7 @@ struct VerilogFrontend : public Frontend {
|
|||
std::string value;
|
||||
if (equal != std::string::npos)
|
||||
value = arg.substr(equal+1);
|
||||
defines_map[name] = value;
|
||||
defines_map.add(name, value);
|
||||
continue;
|
||||
}
|
||||
if (arg == "-I" && argidx+1 < args.size()) {
|
||||
|
@ -460,7 +462,7 @@ struct VerilogFrontend : public Frontend {
|
|||
std::string code_after_preproc;
|
||||
|
||||
if (!flag_nopp) {
|
||||
code_after_preproc = frontend_verilog_preproc(*f, filename, defines_map, design->verilog_defines, include_dirs);
|
||||
code_after_preproc = frontend_verilog_preproc(*f, filename, defines_map, *design->verilog_defines, include_dirs);
|
||||
if (flag_ppdump)
|
||||
log("-- Verilog code after preprocessor --\n%s-- END OF DUMP --\n", code_after_preproc.c_str());
|
||||
lexin = new std::istringstream(code_after_preproc);
|
||||
|
@ -592,7 +594,7 @@ struct VerilogDefines : public Pass {
|
|||
value = name.substr(equal+1);
|
||||
name = name.substr(0, equal);
|
||||
}
|
||||
design->verilog_defines[name] = std::pair<std::string, bool>(value, false);
|
||||
design->verilog_defines->add(name, value);
|
||||
continue;
|
||||
}
|
||||
if (arg.compare(0, 2, "-D") == 0) {
|
||||
|
@ -601,27 +603,25 @@ struct VerilogDefines : public Pass {
|
|||
std::string value;
|
||||
if (equal != std::string::npos)
|
||||
value = arg.substr(equal+1);
|
||||
design->verilog_defines[name] = std::pair<std::string, bool>(value, false);
|
||||
design->verilog_defines->add(name, value);
|
||||
continue;
|
||||
}
|
||||
if (arg == "-U" && argidx+1 < args.size()) {
|
||||
std::string name = args[++argidx];
|
||||
design->verilog_defines.erase(name);
|
||||
design->verilog_defines->erase(name);
|
||||
continue;
|
||||
}
|
||||
if (arg.compare(0, 2, "-U") == 0) {
|
||||
std::string name = arg.substr(2);
|
||||
design->verilog_defines.erase(name);
|
||||
design->verilog_defines->erase(name);
|
||||
continue;
|
||||
}
|
||||
if (arg == "-reset") {
|
||||
design->verilog_defines.clear();
|
||||
design->verilog_defines->clear();
|
||||
continue;
|
||||
}
|
||||
if (arg == "-list") {
|
||||
for (auto &it : design->verilog_defines) {
|
||||
log("`define %s%s %s\n", it.first.c_str(), it.second.second ? "()" : "", it.second.first.c_str());
|
||||
}
|
||||
design->verilog_defines->log();
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue