From 14f32028ec878b8ba7324584631523f5b571b39f Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 27 Feb 2020 16:57:35 +0000 Subject: Parser changes to support typedef. --- frontends/verilog/verilog_frontend.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'frontends/verilog/verilog_frontend.cc') diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 42eabc02d..de05d29a7 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -47,6 +47,22 @@ static void error_on_dpi_function(AST::AstNode *node) error_on_dpi_function(child); } +static void add_package_types(std::map &user_types, std::vector &package_list) +{ + // prime the parser's user type lookup table with the package qualified names + // of typedefed names in the packages seen so far. + user_types.clear(); + for (const auto &pkg : package_list) { + log_assert(pkg->type==AST::AST_PACKAGE); + for (const auto &node: pkg->children) { + if (node->type == AST::AST_TYPEDEF) { + std::string s = pkg->str + "::" + node->str.substr(1); + user_types[s] = node; + } + } + } +} + struct VerilogFrontend : public Frontend { VerilogFrontend() : Frontend("verilog", "read modules from Verilog file") { } void help() YS_OVERRIDE @@ -468,6 +484,9 @@ struct VerilogFrontend : public Frontend { 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, 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); + // make latest package info available to next parser + add_package_types(pkg_user_types, design->verilog_packages); + if (!flag_nopp) delete lexin; -- cgit v1.2.3 From 0aaa36ca6d4a95771ef26a515b64031c4d43be11 Mon Sep 17 00:00:00 2001 From: Peter Date: Tue, 3 Mar 2020 19:30:54 +0000 Subject: Clear pkg_user_types if no packages following a 'design -reset-vlog'. --- frontends/verilog/verilog_frontend.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'frontends/verilog/verilog_frontend.cc') diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index de05d29a7..61db0a176 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -465,6 +465,10 @@ struct VerilogFrontend : public Frontend { log("-- Verilog code after preprocessor --\n%s-- END OF DUMP --\n", code_after_preproc.c_str()); lexin = new std::istringstream(code_after_preproc); } + if (design->verilog_packages.empty()) { + // might be because of a `design -reset-vlog` command + pkg_user_types.clear(); + } frontend_verilog_yyset_lineno(1); frontend_verilog_yyrestart(NULL); -- cgit v1.2.3 From c06eda25041cd567ac53da52d486dfd0daa8eaff Mon Sep 17 00:00:00 2001 From: Peter Crozier Date: Sun, 15 Mar 2020 19:01:46 +0000 Subject: Build pkg_user_types before parsing in case of changes in the design. --- frontends/verilog/verilog_frontend.cc | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'frontends/verilog/verilog_frontend.cc') diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 61db0a176..f2c1c227f 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -465,10 +465,9 @@ struct VerilogFrontend : public Frontend { log("-- Verilog code after preprocessor --\n%s-- END OF DUMP --\n", code_after_preproc.c_str()); lexin = new std::istringstream(code_after_preproc); } - if (design->verilog_packages.empty()) { - // might be because of a `design -reset-vlog` command - pkg_user_types.clear(); - } + + // make package typedefs available to parser + add_package_types(pkg_user_types, design->verilog_packages); frontend_verilog_yyset_lineno(1); frontend_verilog_yyrestart(NULL); @@ -488,8 +487,6 @@ struct VerilogFrontend : public Frontend { 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, 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); - // make latest package info available to next parser - add_package_types(pkg_user_types, design->verilog_packages); if (!flag_nopp) delete lexin; -- cgit v1.2.3 From ecc22f7fedfa639482dbc55a05709da85116a60f Mon Sep 17 00:00:00 2001 From: Peter Crozier Date: Mon, 23 Mar 2020 20:07:22 +0000 Subject: Support module/package/interface/block scope for typedef names. --- frontends/verilog/verilog_frontend.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'frontends/verilog/verilog_frontend.cc') diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index f2c1c227f..1c88d479b 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -51,7 +51,6 @@ static void add_package_types(std::map &user_types, { // prime the parser's user type lookup table with the package qualified names // of typedefed names in the packages seen so far. - user_types.clear(); for (const auto &pkg : package_list) { log_assert(pkg->type==AST::AST_PACKAGE); for (const auto &node: pkg->children) { @@ -61,6 +60,8 @@ static void add_package_types(std::map &user_types, } } } + user_type_stack.clear(); + user_type_stack.push_back(new UserTypeMap()); } struct VerilogFrontend : public Frontend { -- cgit v1.2.3 From 044ca9dde409e3c91542fe95513d6641110f8462 Mon Sep 17 00:00:00 2001 From: Rupert Swarbrick Date: Tue, 17 Mar 2020 09:34:31 +0000 Subject: 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. --- frontends/verilog/verilog_frontend.cc | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'frontends/verilog/verilog_frontend.cc') diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index f2c1c227f..a2334e654 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -27,6 +27,7 @@ */ #include "verilog_frontend.h" +#include "preproc.h" #include "kernel/yosys.h" #include "libs/sha1/sha1.h" #include @@ -253,7 +254,8 @@ struct VerilogFrontend : public Frontend { bool flag_defer = false; bool flag_noblackbox = false; bool flag_nowb = false; - std::map defines_map; + define_map_t defines_map; + std::list include_dirs; std::list 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(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(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; -- cgit v1.2.3