diff options
Diffstat (limited to 'frontends')
-rw-r--r-- | frontends/ast/simplify.cc | 25 | ||||
-rw-r--r-- | frontends/ilang/.gitignore | 4 | ||||
-rw-r--r-- | frontends/ilang/Makefile.inc | 19 | ||||
-rw-r--r-- | frontends/rpc/rpc_frontend.cc | 2 | ||||
-rw-r--r-- | frontends/rtlil/.gitignore | 4 | ||||
-rw-r--r-- | frontends/rtlil/Makefile.inc | 19 | ||||
-rw-r--r-- | frontends/rtlil/rtlil_frontend.cc (renamed from frontends/ilang/ilang_frontend.cc) | 61 | ||||
-rw-r--r-- | frontends/rtlil/rtlil_frontend.h (renamed from frontends/ilang/ilang_frontend.h) | 22 | ||||
-rw-r--r-- | frontends/rtlil/rtlil_lexer.l (renamed from frontends/ilang/ilang_lexer.l) | 24 | ||||
-rw-r--r-- | frontends/rtlil/rtlil_parser.y (renamed from frontends/ilang/ilang_parser.y) | 42 | ||||
-rw-r--r-- | frontends/verific/verific.cc | 255 |
11 files changed, 371 insertions, 106 deletions
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index b8e4f941c..0ba2ab6ac 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -110,6 +110,12 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg goto unsupported_format; break; + case 'l': + case 'L': + if (got_len) + goto unsupported_format; + break; + default: unsupported_format: log_file_error(filename, location.first_line, "System task `%s' called with invalid/unsupported format specifier.\n", str.c_str()); @@ -155,6 +161,11 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg sout += log_id(current_module->name); break; + case 'l': + case 'L': + sout += log_id(current_module->name); + break; + default: log_abort(); } @@ -1597,6 +1608,13 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, if (type == AST_IDENTIFIER) { if (current_scope.count(str) == 0) { AstNode *current_scope_ast = (current_ast_mod == nullptr) ? current_ast : current_ast_mod; + const std::string& mod_scope = current_scope_ast->str; + if (str[0] == '\\' && str.substr(0, mod_scope.size()) == mod_scope) { + std::string new_str = "\\" + str.substr(mod_scope.size() + 1); + if (current_scope.count(new_str)) { + str = new_str; + } + } for (auto node : current_scope_ast->children) { //log("looking at mod scope child %s\n", type2str(node->type).c_str()); switch (node->type) { @@ -3211,14 +3229,15 @@ skip_dynamic_range_lvalue_expansion:; if (wire_cache.count(child->str)) { wire = wire_cache.at(child->str); - if (wire->children.empty()) { + bool contains_value = wire->type == AST_LOCALPARAM; + if (wire->children.size() == contains_value) { for (auto c : child->children) wire->children.push_back(c->clone()); } else if (!child->children.empty()) { while (child->simplify(true, false, false, stage, -1, false, false)) { } - if (GetSize(child->children) == GetSize(wire->children)) { + if (GetSize(child->children) == GetSize(wire->children) - contains_value) { for (int i = 0; i < GetSize(child->children); i++) - if (*child->children.at(i) != *wire->children.at(i)) + if (*child->children.at(i) != *wire->children.at(i + contains_value)) goto tcall_incompatible_wires; } else { tcall_incompatible_wires: diff --git a/frontends/ilang/.gitignore b/frontends/ilang/.gitignore deleted file mode 100644 index f586b33c7..000000000 --- a/frontends/ilang/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -ilang_lexer.cc -ilang_parser.output -ilang_parser.tab.cc -ilang_parser.tab.hh diff --git a/frontends/ilang/Makefile.inc b/frontends/ilang/Makefile.inc deleted file mode 100644 index 6f1f0e8fc..000000000 --- a/frontends/ilang/Makefile.inc +++ /dev/null @@ -1,19 +0,0 @@ - -GENFILES += frontends/ilang/ilang_parser.tab.cc -GENFILES += frontends/ilang/ilang_parser.tab.hh -GENFILES += frontends/ilang/ilang_parser.output -GENFILES += frontends/ilang/ilang_lexer.cc - -frontends/ilang/ilang_parser.tab.cc: frontends/ilang/ilang_parser.y - $(Q) mkdir -p $(dir $@) - $(P) $(BISON) -o $@ -d -r all -b frontends/ilang/ilang_parser $< - -frontends/ilang/ilang_parser.tab.hh: frontends/ilang/ilang_parser.tab.cc - -frontends/ilang/ilang_lexer.cc: frontends/ilang/ilang_lexer.l - $(Q) mkdir -p $(dir $@) - $(P) flex -o frontends/ilang/ilang_lexer.cc $< - -OBJS += frontends/ilang/ilang_parser.tab.o frontends/ilang/ilang_lexer.o -OBJS += frontends/ilang/ilang_frontend.o - diff --git a/frontends/rpc/rpc_frontend.cc b/frontends/rpc/rpc_frontend.cc index 6d72cbff5..5a40001cb 100644 --- a/frontends/rpc/rpc_frontend.cc +++ b/frontends/rpc/rpc_frontend.cc @@ -378,7 +378,7 @@ struct RpcFrontend : public Pass { log(" -> {\"method\": \"derive\", \"module\": \"<module-name\">, \"parameters\": {\n"); log(" \"<param-name>\": {\"type\": \"[unsigned|signed|string|real]\",\n"); log(" \"value\": \"<param-value>\"}, ...}}\n"); - log(" <- {\"frontend\": \"[ilang|verilog|...]\",\"source\": \"<source>\"}}\n"); + log(" <- {\"frontend\": \"[rtlil|verilog|...]\",\"source\": \"<source>\"}}\n"); log(" <- {\"error\": \"<error-message>\"}\n"); log(" request for the module <module-name> to be derived for a specific set of\n"); log(" parameters. <param-name> starts with \\ for named parameters, and with $\n"); diff --git a/frontends/rtlil/.gitignore b/frontends/rtlil/.gitignore new file mode 100644 index 000000000..d4a322756 --- /dev/null +++ b/frontends/rtlil/.gitignore @@ -0,0 +1,4 @@ +rtlil_lexer.cc +rtlil_parser.output +rtlil_parser.tab.cc +rtlil_parser.tab.hh diff --git a/frontends/rtlil/Makefile.inc b/frontends/rtlil/Makefile.inc new file mode 100644 index 000000000..d0c0cfcf8 --- /dev/null +++ b/frontends/rtlil/Makefile.inc @@ -0,0 +1,19 @@ + +GENFILES += frontends/rtlil/rtlil_parser.tab.cc +GENFILES += frontends/rtlil/rtlil_parser.tab.hh +GENFILES += frontends/rtlil/rtlil_parser.output +GENFILES += frontends/rtlil/rtlil_lexer.cc + +frontends/rtlil/rtlil_parser.tab.cc: frontends/rtlil/rtlil_parser.y + $(Q) mkdir -p $(dir $@) + $(P) $(BISON) -o $@ -d -r all -b frontends/rtlil/rtlil_parser $< + +frontends/rtlil/rtlil_parser.tab.hh: frontends/rtlil/rtlil_parser.tab.cc + +frontends/rtlil/rtlil_lexer.cc: frontends/rtlil/rtlil_lexer.l + $(Q) mkdir -p $(dir $@) + $(P) flex -o frontends/rtlil/rtlil_lexer.cc $< + +OBJS += frontends/rtlil/rtlil_parser.tab.o frontends/rtlil/rtlil_lexer.o +OBJS += frontends/rtlil/rtlil_frontend.o + diff --git a/frontends/ilang/ilang_frontend.cc b/frontends/rtlil/rtlil_frontend.cc index 973e62f2c..00c34175e 100644 --- a/frontends/ilang/ilang_frontend.cc +++ b/frontends/rtlil/rtlil_frontend.cc @@ -18,30 +18,30 @@ * --- * * A very simple and straightforward frontend for the RTLIL text - * representation (as generated by the 'ilang' backend). + * representation. * */ -#include "ilang_frontend.h" +#include "rtlil_frontend.h" #include "kernel/register.h" #include "kernel/log.h" -void rtlil_frontend_ilang_yyerror(char const *s) +void rtlil_frontend_yyerror(char const *s) { - YOSYS_NAMESPACE_PREFIX log_error("Parser error in line %d: %s\n", rtlil_frontend_ilang_yyget_lineno(), s); + YOSYS_NAMESPACE_PREFIX log_error("Parser error in line %d: %s\n", rtlil_frontend_yyget_lineno(), s); } YOSYS_NAMESPACE_BEGIN -struct IlangFrontend : public Frontend { - IlangFrontend() : Frontend("ilang", "read modules from ilang file") { } +struct RTLILFrontend : public Frontend { + RTLILFrontend() : Frontend("rtlil", "read modules from RTLIL file") { } void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" read_ilang [filename]\n"); + log(" read_rtlil [filename]\n"); log("\n"); - log("Load modules from an ilang file to the current design. (ilang is a text\n"); + log("Load modules from an RTLIL file to the current design. (RTLIL is a text\n"); log("representation of a design in yosys's internal format.)\n"); log("\n"); log(" -nooverwrite\n"); @@ -58,27 +58,27 @@ struct IlangFrontend : public Frontend { } void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override { - ILANG_FRONTEND::flag_nooverwrite = false; - ILANG_FRONTEND::flag_overwrite = false; - ILANG_FRONTEND::flag_lib = false; + RTLIL_FRONTEND::flag_nooverwrite = false; + RTLIL_FRONTEND::flag_overwrite = false; + RTLIL_FRONTEND::flag_lib = false; - log_header(design, "Executing ILANG frontend.\n"); + log_header(design, "Executing RTLIL frontend.\n"); size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { std::string arg = args[argidx]; if (arg == "-nooverwrite") { - ILANG_FRONTEND::flag_nooverwrite = true; - ILANG_FRONTEND::flag_overwrite = false; + RTLIL_FRONTEND::flag_nooverwrite = true; + RTLIL_FRONTEND::flag_overwrite = false; continue; } if (arg == "-overwrite") { - ILANG_FRONTEND::flag_nooverwrite = false; - ILANG_FRONTEND::flag_overwrite = true; + RTLIL_FRONTEND::flag_nooverwrite = false; + RTLIL_FRONTEND::flag_overwrite = true; continue; } if (arg == "-lib") { - ILANG_FRONTEND::flag_lib = true; + RTLIL_FRONTEND::flag_lib = true; continue; } break; @@ -87,12 +87,27 @@ struct IlangFrontend : public Frontend { log("Input filename: %s\n", filename.c_str()); - ILANG_FRONTEND::lexin = f; - ILANG_FRONTEND::current_design = design; - rtlil_frontend_ilang_yydebug = false; - rtlil_frontend_ilang_yyrestart(NULL); - rtlil_frontend_ilang_yyparse(); - rtlil_frontend_ilang_yylex_destroy(); + RTLIL_FRONTEND::lexin = f; + RTLIL_FRONTEND::current_design = design; + rtlil_frontend_yydebug = false; + rtlil_frontend_yyrestart(NULL); + rtlil_frontend_yyparse(); + rtlil_frontend_yylex_destroy(); + } +} RTLILFrontend; + +struct IlangFrontend : public Frontend { + IlangFrontend() : Frontend("ilang", "(deprecated) alias of read_rtlil") { } + void help() override + { + // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| + log("\n"); + log("See `help read_rtlil`.\n"); + log("\n"); + } + void execute(std::istream *&f, std::string filename, std::vector<std::string> args, RTLIL::Design *design) override + { + RTLILFrontend.execute(f, filename, args, design); } } IlangFrontend; diff --git a/frontends/ilang/ilang_frontend.h b/frontends/rtlil/rtlil_frontend.h index f8a152841..a420778b0 100644 --- a/frontends/ilang/ilang_frontend.h +++ b/frontends/rtlil/rtlil_frontend.h @@ -18,18 +18,18 @@ * --- * * A very simple and straightforward frontend for the RTLIL text - * representation (as generated by the 'ilang' backend). + * representation. * */ -#ifndef ILANG_FRONTEND_H -#define ILANG_FRONTEND_H +#ifndef RTLIL_FRONTEND_H +#define RTLIL_FRONTEND_H #include "kernel/yosys.h" YOSYS_NAMESPACE_BEGIN -namespace ILANG_FRONTEND { +namespace RTLIL_FRONTEND { extern std::istream *lexin; extern RTLIL::Design *current_design; extern bool flag_nooverwrite; @@ -39,13 +39,13 @@ namespace ILANG_FRONTEND { YOSYS_NAMESPACE_END -extern int rtlil_frontend_ilang_yydebug; -int rtlil_frontend_ilang_yylex(void); -void rtlil_frontend_ilang_yyerror(char const *s); -void rtlil_frontend_ilang_yyrestart(FILE *f); -int rtlil_frontend_ilang_yyparse(void); -int rtlil_frontend_ilang_yylex_destroy(void); -int rtlil_frontend_ilang_yyget_lineno(void); +extern int rtlil_frontend_yydebug; +int rtlil_frontend_yylex(void); +void rtlil_frontend_yyerror(char const *s); +void rtlil_frontend_yyrestart(FILE *f); +int rtlil_frontend_yyparse(void); +int rtlil_frontend_yylex_destroy(void); +int rtlil_frontend_yyget_lineno(void); #endif diff --git a/frontends/ilang/ilang_lexer.l b/frontends/rtlil/rtlil_lexer.l index 3362ed641..295455f53 100644 --- a/frontends/ilang/ilang_lexer.l +++ b/frontends/rtlil/rtlil_lexer.l @@ -18,7 +18,7 @@ * --- * * A very simple and straightforward frontend for the RTLIL text - * representation (as generated by the 'ilang' backend). + * representation. * */ @@ -30,20 +30,20 @@ #endif #include <cstdlib> -#include "frontends/ilang/ilang_frontend.h" -#include "ilang_parser.tab.hh" +#include "frontends/rtlil/rtlil_frontend.h" +#include "rtlil_parser.tab.hh" USING_YOSYS_NAMESPACE #define YY_INPUT(buf,result,max_size) \ - result = readsome(*ILANG_FRONTEND::lexin, buf, max_size) + result = readsome(*RTLIL_FRONTEND::lexin, buf, max_size) %} %option yylineno %option noyywrap %option nounput -%option prefix="rtlil_frontend_ilang_yy" +%option prefix="rtlil_frontend_yy" %x STRING @@ -84,11 +84,11 @@ USING_YOSYS_NAMESPACE [a-z]+ { return TOK_INVALID; } -"\\"[^ \t\r\n]+ { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_ID; } -"$"[^ \t\r\n]+ { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_ID; } -"."[0-9]+ { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_ID; } +"\\"[^ \t\r\n]+ { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; } +"$"[^ \t\r\n]+ { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; } +"."[0-9]+ { rtlil_frontend_yylval.string = strdup(yytext); return TOK_ID; } -[0-9]+'[01xzm-]* { rtlil_frontend_ilang_yylval.string = strdup(yytext); return TOK_VALUE; } +[0-9]+'[01xzm-]* { rtlil_frontend_yylval.string = strdup(yytext); return TOK_VALUE; } -?[0-9]+ { char *end = nullptr; errno = 0; @@ -98,7 +98,7 @@ USING_YOSYS_NAMESPACE return TOK_INVALID; // literal out of range of long if (value < INT_MIN || value > INT_MAX) return TOK_INVALID; // literal out of range of int (relevant mostly for LP64 platforms) - rtlil_frontend_ilang_yylval.integer = value; + rtlil_frontend_yylval.integer = value; return TOK_INT; } @@ -131,7 +131,7 @@ USING_YOSYS_NAMESPACE yystr[j++] = yystr[i++]; } yystr[j] = 0; - rtlil_frontend_ilang_yylval.string = yystr; + rtlil_frontend_yylval.string = yystr; return TOK_STRING; } <STRING>. { yymore(); } @@ -145,6 +145,6 @@ USING_YOSYS_NAMESPACE %% // this is a hack to avoid the 'yyinput defined but not used' error msgs -void *rtlil_frontend_ilang_avoid_input_warnings() { +void *rtlil_frontend_avoid_input_warnings() { return (void*)&yyinput; } diff --git a/frontends/ilang/ilang_parser.y b/frontends/rtlil/rtlil_parser.y index 879ef4af9..646489196 100644 --- a/frontends/ilang/ilang_parser.y +++ b/frontends/rtlil/rtlil_parser.y @@ -18,15 +18,15 @@ * --- * * A very simple and straightforward frontend for the RTLIL text - * representation (as generated by the 'ilang' backend). + * representation. * */ %{ #include <list> -#include "frontends/ilang/ilang_frontend.h" +#include "frontends/rtlil/rtlil_frontend.h" YOSYS_NAMESPACE_BEGIN -namespace ILANG_FRONTEND { +namespace RTLIL_FRONTEND { std::istream *lexin; RTLIL::Design *current_design; RTLIL::Module *current_module; @@ -40,12 +40,12 @@ namespace ILANG_FRONTEND { bool flag_nooverwrite, flag_overwrite, flag_lib; bool delete_current_module; } -using namespace ILANG_FRONTEND; +using namespace RTLIL_FRONTEND; YOSYS_NAMESPACE_END USING_YOSYS_NAMESPACE %} -%define api.prefix {rtlil_frontend_ilang_yy} +%define api.prefix {rtlil_frontend_yy} /* The union is defined in the header, so we need to provide all the * includes it requires @@ -53,7 +53,7 @@ USING_YOSYS_NAMESPACE %code requires { #include <string> #include <vector> -#include "frontends/ilang/ilang_frontend.h" +#include "frontends/rtlil/rtlil_frontend.h" } %union { @@ -87,7 +87,7 @@ input: attrbuf.clear(); } design { if (attrbuf.size() != 0) - rtlil_frontend_ilang_yyerror("dangling attribute"); + rtlil_frontend_yyerror("dangling attribute"); }; EOL: @@ -111,7 +111,7 @@ module: log("Ignoring blackbox re-definition of module %s.\n", $2); delete_current_module = true; } else if (!flag_nooverwrite && !flag_overwrite && !existing_mod->get_bool_attribute(ID::blackbox)) { - rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of module %s.", $2).c_str()); + rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of module %s.", $2).c_str()); } else if (flag_nooverwrite) { log("Ignoring re-definition of module %s.\n", $2); delete_current_module = true; @@ -129,7 +129,7 @@ module: free($2); } module_body TOK_END { if (attrbuf.size() != 0) - rtlil_frontend_ilang_yyerror("dangling attribute"); + rtlil_frontend_yyerror("dangling attribute"); current_module->fixup_ports(); if (delete_current_module) delete current_module; @@ -172,12 +172,12 @@ autoidx_stmt: wire_stmt: TOK_WIRE { - current_wire = current_module->addWire("$__ilang_frontend_tmp__"); + current_wire = current_module->addWire("$__rtlil_frontend_tmp__"); current_wire->attributes = attrbuf; attrbuf.clear(); } wire_options TOK_ID EOL { if (current_module->wire($4) != nullptr) - rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of wire %s.", $4).c_str()); + rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of wire %s.", $4).c_str()); current_module->rename(current_wire, $4); free($4); }; @@ -187,7 +187,7 @@ wire_options: current_wire->width = $3; } | wire_options TOK_WIDTH TOK_INVALID { - rtlil_frontend_ilang_yyerror("ilang error: invalid wire width"); + rtlil_frontend_yyerror("RTLIL error: invalid wire width"); } | wire_options TOK_UPTO { current_wire->upto = true; @@ -222,7 +222,7 @@ memory_stmt: attrbuf.clear(); } memory_options TOK_ID EOL { if (current_module->memories.count($4) != 0) - rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of memory %s.", $4).c_str()); + rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of memory %s.", $4).c_str()); current_memory->name = $4; current_module->memories[$4] = current_memory; free($4); @@ -243,7 +243,7 @@ memory_options: cell_stmt: TOK_CELL TOK_ID TOK_ID EOL { if (current_module->cell($3) != nullptr) - rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell %s.", $3).c_str()); + rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of cell %s.", $3).c_str()); current_cell = current_module->addCell($3, $2); current_cell->attributes = attrbuf; attrbuf.clear(); @@ -271,7 +271,7 @@ cell_body: } | cell_body TOK_CONNECT TOK_ID sigspec EOL { if (current_cell->hasPort($3)) - rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of cell port %s.", $3).c_str()); + rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of cell port %s.", $3).c_str()); current_cell->setPort($3, *$4); delete $4; free($3); @@ -281,7 +281,7 @@ cell_body: proc_stmt: TOK_PROCESS TOK_ID EOL { if (current_module->processes.count($2) != 0) - rtlil_frontend_ilang_yyerror(stringf("ilang error: redefinition of process %s.", $2).c_str()); + rtlil_frontend_yyerror(stringf("RTLIL error: redefinition of process %s.", $2).c_str()); current_process = new RTLIL::Process; current_process->name = $2; current_process->attributes = attrbuf; @@ -342,7 +342,7 @@ case_body: assign_stmt: TOK_ASSIGN sigspec sigspec EOL { if (attrbuf.size() != 0) - rtlil_frontend_ilang_yyerror("dangling attribute"); + rtlil_frontend_yyerror("dangling attribute"); case_stack.back()->actions.push_back(RTLIL::SigSig(*$2, *$3)); delete $2; delete $3; @@ -438,19 +438,19 @@ sigspec: } | TOK_ID { if (current_module->wire($1) == nullptr) - rtlil_frontend_ilang_yyerror(stringf("ilang error: wire %s not found", $1).c_str()); + rtlil_frontend_yyerror(stringf("RTLIL error: wire %s not found", $1).c_str()); $$ = new RTLIL::SigSpec(current_module->wire($1)); free($1); } | sigspec '[' TOK_INT ']' { if ($3 >= $1->size() || $3 < 0) - rtlil_frontend_ilang_yyerror("bit index out of range"); + rtlil_frontend_yyerror("bit index out of range"); $$ = new RTLIL::SigSpec($1->extract($3)); delete $1; } | sigspec '[' TOK_INT ':' TOK_INT ']' { if ($3 >= $1->size() || $3 < 0 || $3 < $5) - rtlil_frontend_ilang_yyerror("invalid slice"); + rtlil_frontend_yyerror("invalid slice"); $$ = new RTLIL::SigSpec($1->extract($5, $3 - $5 + 1)); delete $1; } | @@ -477,7 +477,7 @@ sigspec_list: sigspec_list_reversed { conn_stmt: TOK_CONNECT sigspec sigspec EOL { if (attrbuf.size() != 0) - rtlil_frontend_ilang_yyerror("dangling attribute"); + rtlil_frontend_yyerror("dangling attribute"); current_module->connect(*$2, *$3); delete $2; delete $3; diff --git a/frontends/verific/verific.cc b/frontends/verific/verific.cc index 632dc51fd..40dca20ba 100644 --- a/frontends/verific/verific.cc +++ b/frontends/verific/verific.cc @@ -54,7 +54,7 @@ USING_YOSYS_NAMESPACE # error "Only Symbiotic EDA flavored Verific is supported. Please contact office@symbioticeda.com for commercial support for Yosys+Verific." #endif -#if SYMBIOTIC_VERIFIC_API_VERSION < 202006 +#if SYMBIOTIC_VERIFIC_API_VERSION < 20200702 # error "Please update your version of Symbiotic EDA flavored Verific." #endif @@ -199,12 +199,17 @@ void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &att attributes.emplace(stringf("\\enum_value_%s", p+2), RTLIL::escape_id(k)); } else if (nl->IsFromVhdl()) { - // Expect "<binary>" + // Expect "<binary>" or plain <binary> auto p = v; if (p) { - if (*p != '"') - p = nullptr; - else { + if (*p != '"') { + auto l = strlen(p); + auto q = (char*)malloc(l+1); + strncpy(q, p, l); + q[l] = '\0'; + for(char *ptr = q; *ptr; ++ptr )*ptr = tolower(*ptr); + attributes.emplace(stringf("\\enum_value_%s", q), RTLIL::escape_id(k)); + } else { auto *q = p+1; for (; *q != '"'; q++) if (*q != '0' && *q != '1') { @@ -213,16 +218,20 @@ void VerificImporter::import_attributes(dict<RTLIL::IdString, RTLIL::Const> &att } if (p && *(q+1) != '\0') p = nullptr; + + if (p != nullptr) + { + auto l = strlen(p); + auto q = (char*)malloc(l+1-2); + strncpy(q, p+1, l-2); + q[l-2] = '\0'; + attributes.emplace(stringf("\\enum_value_%s", q), RTLIL::escape_id(k)); + free(q); + } } } if (p == nullptr) - log_error("Expected TypeRange value '%s' to be of form \"<binary>\".\n", v); - auto l = strlen(p); - auto q = (char*)malloc(l+1-2); - strncpy(q, p+1, l-2); - q[l-2] = '\0'; - attributes.emplace(stringf("\\enum_value_%s", q), RTLIL::escape_id(k)); - free(q); + log_error("Expected TypeRange value '%s' to be of form \"<binary>\" or <binary>.\n", v); } } } @@ -2158,6 +2167,70 @@ struct VerificPass : public Pass { log(" Dump the Verific netlist as a verilog file.\n"); log("\n"); log("\n"); + log(" verific [-work <libname>] -pp [options] <filename> [<module>]..\n"); + log("\n"); + log("Pretty print design (or just module) to the specified file from the\n"); + log("specified library. (default library when -work is not present: \"work\")\n"); + log("\n"); + log("Pretty print options:\n"); + log("\n"); + log(" -verilog\n"); + log(" Save output for Verilog/SystemVerilog design modules (default).\n"); + log("\n"); + log(" -vhdl\n"); + log(" Save output for VHDL design units.\n"); + log("\n"); + log("\n"); + log(" verific -app <application>..\n"); + log("\n"); + log("Execute SEDA formal application on loaded Verilog files.\n"); + log("\n"); + log("Application options:\n"); + log("\n"); + log(" -blacklist <filename[:lineno]>\n"); + log(" Do not run application on modules from files that match the filename\n"); + log(" or filename and line number if provided in such format.\n"); + log(" Parameter can also contain comma separated list of file locations.\n"); + log("\n"); + log(" -blfile <file>\n"); + log(" Do not run application on locations specified in file, they can represent filename\n"); + log(" or filename and location in file.\n"); + log("\n"); + log("Applications:\n"); + log("\n"); +#ifdef YOSYS_ENABLE_VERIFIC + VerificFormalApplications vfa; + log("%s\n",vfa.GetHelp().c_str()); +#else + log(" WARNING: Applications only available in commercial build.\n"); + +#endif + log("\n"); + log("\n"); + log(" verific -template <name> <top_module>..\n"); + log("\n"); + log("Generate template for specified top module of loaded design.\n"); + log("\n"); + log("Template options:\n"); + log("\n"); + log(" -out\n"); + log(" Specifies output file for generated template, by default output is stdout\n"); + log("\n"); + log(" -chparam name value \n"); + log(" Generate template using this parameter value. Otherwise default parameter\n"); + log(" values will be used for templat generate functionality. This option\n"); + log(" can be specified multiple times to override multiple parameters.\n"); + log(" String values must be passed in double quotes (\").\n"); + log("\n"); + log("Templates:\n"); + log("\n"); +#ifdef YOSYS_ENABLE_VERIFIC + VerificTemplateGenerator vfg; + log("%s\n",vfg.GetHelp().c_str()); +#else + log(" WARNING: Templates only available in commercial build.\n"); + log("\n"); +#endif log("Use Symbiotic EDA Suite if you need Yosys+Verifc.\n"); log("https://www.symbioticeda.com/seda-suite\n"); log("\n"); @@ -2202,6 +2275,9 @@ struct VerificPass : public Pass { RuntimeFlags::SetVar("veri_preserve_assignments", 1); RuntimeFlags::SetVar("vhdl_preserve_assignments", 1); + RuntimeFlags::SetVar("veri_preserve_comments",1); + //RuntimeFlags::SetVar("vhdl_preserve_comments",1); + // Workaround for VIPER #13851 RuntimeFlags::SetVar("veri_create_name_for_unnamed_gen_block", 1); @@ -2399,6 +2475,161 @@ struct VerificPass : public Pass { goto check_error; } + if (argidx+1 < GetSize(args) && args[argidx] == "-app") + { + VerificFormalApplications vfa; + auto apps = vfa.GetApps(); + std::string app = args[++argidx]; + std::vector<std::string> blacklists; + if (apps.find(app) == apps.end()) + log_cmd_error("Application '%s' does not exist.\n", app.c_str()); + + for (argidx++; argidx < GetSize(args); argidx++) { + if (args[argidx] == "-blacklist" && argidx+1 < GetSize(args)) { + std::string line = args[++argidx]; + std::string p; + while (!(p = next_token(line, ",\t\r\n ")).empty()) + blacklists.push_back(p); + continue; + } + if (args[argidx] == "-blfile" && argidx+1 < GetSize(args)) { + std::string fn = args[++argidx]; + std::ifstream f(fn); + if (f.fail()) + log_cmd_error("Can't open blacklist file '%s'!\n", fn.c_str()); + + std::string line,p; + while (std::getline(f, line)) { + while (!(p = next_token(line, ",\t\r\n ")).empty()) + blacklists.push_back(p); + } + continue; + } + break; + } + if (argidx < GetSize(args)) + cmd_error(args, argidx, "unknown option/parameter"); + MapIter mi; + VeriModule *module ; + VeriLibrary *veri_lib = veri_file::GetLibrary(work.c_str(), 1); + log("Running formal application '%s'.\n", app.c_str()); + FOREACH_VERILOG_MODULE_IN_LIBRARY(veri_lib, mi, module) { + vfa.Run(module,apps[app],blacklists); + } + goto check_error; + } + + if (argidx < GetSize(args) && args[argidx] == "-pp") + { + const char* filename = nullptr; + const char* module = nullptr; + bool mode_vhdl = false; + for (argidx++; argidx < GetSize(args); argidx++) { + if (args[argidx] == "-vhdl") { + mode_vhdl = true; + continue; + } + if (args[argidx] == "-verilog") { + mode_vhdl = false; + continue; + } + + if (args[argidx].compare(0, 1, "-") == 0) { + cmd_error(args, argidx, "unknown option"); + goto check_error; + } + + if (!filename) { + filename = args[argidx].c_str(); + continue; + } + if (module) + log_cmd_error("Only one module can be specified.\n"); + module = args[argidx].c_str(); + } + + if (argidx < GetSize(args)) + cmd_error(args, argidx, "unknown option/parameter"); + + if (!filename) + log_cmd_error("Filname must be specified.\n"); + + if (mode_vhdl) + vhdl_file::PrettyPrint(filename, module, work.c_str()); + else + veri_file::PrettyPrint(filename, module, work.c_str()); + goto check_error; + } + + if (argidx < GetSize(args) && args[argidx] == "-template") + { + if (!(argidx < GetSize(args))) + cmd_error(args, argidx, "No template type specified.\n"); + + VerificTemplateGenerator vfg; + auto gens = vfg.GetGenerators(); + std::string app = args[++argidx]; + if (gens.find(app) == gens.end()) + log_cmd_error("Template generator '%s' does not exist.\n", app.c_str()); + TemplateGenerator *generator = gens[app]; + if (!(argidx < GetSize(args))) + cmd_error(args, argidx, "No top module specified.\n"); + + std::string module = args[++argidx]; + VeriLibrary* veri_lib = veri_file::GetLibrary(work.c_str(), 1); + VeriModule *veri_module = veri_lib ? veri_lib->GetModule(module.c_str(), 1) : nullptr; + if (!veri_module) { + log_error("Can't find module/unit '%s'.\n", module.c_str()); + } + + log("Template '%s' is running for module '%s'.\n", app.c_str(),module.c_str()); + + Map parameters(STRING_HASH); + const char *out_filename = nullptr; + + for (argidx++; argidx < GetSize(args); argidx++) { + if (generator->checkParams(args, argidx)) + continue; + if (args[argidx] == "-chparam" && argidx+2 < GetSize(args)) { + const std::string &key = args[++argidx]; + const std::string &value = args[++argidx]; + unsigned new_insertion = parameters.Insert(key.c_str(), value.c_str(), + 1 /* force_overwrite */); + if (!new_insertion) + log_warning_noprefix("-chparam %s already specified: overwriting.\n", key.c_str()); + continue; + } + + if (args[argidx] == "-out" && argidx+1 < GetSize(args)) { + out_filename = args[++argidx].c_str(); + continue; + } + + break; + } + if (argidx < GetSize(args)) + cmd_error(args, argidx, "unknown option/parameter"); + + const char *err = generator->validate(); + if (err) + cmd_error(args, argidx, err); + + std::string val = generator->generate(veri_module, ¶meters); + + FILE *of = stdout; + if (out_filename) { + of = fopen(out_filename, "w"); + if (of == nullptr) + log_error("Can't open '%s' for writing: %s\n", out_filename, strerror(errno)); + log("Writing output to '%s'\n",out_filename); + } + fprintf(of, "%s\n",val.c_str()); + fflush(of); + if (of!=stdout) + fclose(of); + goto check_error; + } + if (GetSize(args) > argidx && args[argidx] == "-import") { std::set<Netlist*> nl_todo, nl_done; |