From 007bdff55d69e6e29091c7beff19c36eeb7ed078 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 12 Feb 2014 23:29:54 +0100 Subject: Added support for functions returning integer --- frontends/verilog/parser.y | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 5b6bf58c2..8080729b0 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -106,7 +106,7 @@ static void free_attr(std::map *al) %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT -%type wire_type range non_opt_range expr basic_expr concat_list rvalue lvalue lvalue_concat_list +%type wire_type range non_opt_range range_or_integer expr basic_expr concat_list rvalue lvalue lvalue_concat_list %type opt_label tok_prim_wrapper hierarchical_id %type opt_signed %type attr @@ -360,6 +360,16 @@ range: $$ = NULL; }; +range_or_integer: + range { + $$ = $1; + } | + TOK_INTEGER { + $$ = new AstNode(AST_RANGE); + $$->children.push_back(AstNode::mkconst_int(31, true)); + $$->children.push_back(AstNode::mkconst_int(0, true)); + }; + module_body: module_body module_body_stmt | /* empty */; @@ -380,7 +390,7 @@ task_func_decl: current_function_or_task = NULL; ast_stack.pop_back(); } | - TOK_FUNCTION opt_signed range TOK_ID ';' { + TOK_FUNCTION opt_signed range_or_integer TOK_ID ';' { current_function_or_task = new AstNode(AST_FUNCTION); current_function_or_task->str = *$4; ast_stack.back()->children.push_back(current_function_or_task); -- cgit v1.2.3 From cd9e8741a71502c303c6f25d02bb2259a7dd7ff3 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Feb 2014 13:59:13 +0100 Subject: Implemented read_verilog -defer --- frontends/verilog/verilog_frontend.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index c70d6f305..d46dfa6e2 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -106,6 +106,11 @@ struct VerilogFrontend : public Frontend { log(" ignore re-definitions of modules. (the default behavior is to\n"); log(" create an error message.)\n"); log("\n"); + log(" -defer\n"); + log(" only read the abstract syntax tree and defer actual compilation\n"); + log(" to a later 'hierarchy' command. Useful in cases where the default\n"); + log(" parameters of modules yield invalid or not synthesizable code.\n"); + log("\n"); log(" -setattr \n"); log(" set the specified attribute (to the value 1) on all loaded modules\n"); log("\n"); @@ -135,6 +140,7 @@ struct VerilogFrontend : public Frontend { bool flag_noopt = false; bool flag_icells = false; bool flag_ignore_redef = false; + bool flag_defer = false; std::map defines_map; std::list include_dirs; std::list attributes; @@ -199,6 +205,10 @@ struct VerilogFrontend : public Frontend { flag_ignore_redef = true; continue; } + if (arg == "-defer") { + flag_defer = true; + continue; + } if (arg == "-setattr" && argidx+1 < args.size()) { attributes.push_back(RTLIL::escape_id(args[++argidx])); continue; @@ -264,7 +274,7 @@ struct VerilogFrontend : public Frontend { child->attributes[attr] = AST::AstNode::mkconst_int(1, false); } - 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); + 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); if (!flag_nopp) fclose(fp); -- cgit v1.2.3 From 7d7e068dd1c5e04cf0c2b9e18abade2b49fe677e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 16 Feb 2014 20:20:25 +0100 Subject: Added a warning note about error reporting to read_verilog help message --- frontends/verilog/verilog_frontend.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'frontends/verilog') diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index d46dfa6e2..477f26b45 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -125,6 +125,11 @@ struct VerilogFrontend : public Frontend { log("The command 'verilog_defaults' can be used to register default options for\n"); log("subsequent calls to 'read_verilog'.\n"); log("\n"); + log("Note that the Verilog frontend does a pretty good job of processing valid\n"); + log("verilog input, but has not very good error reporting. It generally is\n"); + log("recommended to use a simulator (for example icarus verilog) for checking\n"); + log("the syntax of the code, rather than to rely on read_verilog for that.\n"); + log("\n"); } virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) { -- cgit v1.2.3 From 02e6f2c5be8c5514cc8cdb7b3344f6170fb87af9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 17 Feb 2014 14:28:52 +0100 Subject: Added Verilog support for "`default_nettype none" --- frontends/verilog/lexer.l | 12 ++++++++++++ frontends/verilog/parser.y | 1 + frontends/verilog/preproc.cc | 1 - frontends/verilog/verilog_frontend.cc | 3 ++- frontends/verilog/verilog_frontend.h | 3 +++ 5 files changed, 18 insertions(+), 2 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 81167cf4e..79f44b4a6 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -81,6 +81,18 @@ namespace VERILOG_FRONTEND { "`timescale"[ \t]+[^ \t\r\n/]+[ \t]*"/"[ \t]*[^ \t\r\n]* /* ignore timescale directive */ +"`default_nettype"[ \t]+[^ \t\r\n/]+ { + char *p = yytext; + while (*p != 0 && *p != ' ' && *p != '\t') p++; + while (*p == ' ' || *p == '\t') p++; + if (!strcmp(p, "none")) + VERILOG_FRONTEND::default_nettype_wire = false; + else if (!strcmp(p, "wire")) + VERILOG_FRONTEND::default_nettype_wire = true; + else + frontend_verilog_yyerror("Unsupported default nettype: %s", p); +} + "`"[a-zA-Z_$][a-zA-Z0-9_$]* { frontend_verilog_yyerror("Unimplemented compiler directive or undefined macro %s.", yytext); } diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 8080729b0..4726f1aa3 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -53,6 +53,7 @@ namespace VERILOG_FRONTEND { struct AstNode *current_ast, *current_ast_mod; int current_function_or_task_port_id; std::vector case_type_stack; + bool default_nettype_wire; } static void append_attr(AstNode *ast, std::map *al) diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index db53e8c68..873ae3d51 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -373,7 +373,6 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m } if (tok == "`timescale") { - std::string name; skip_spaces(); while (!tok.empty() && tok != "\n") tok = next_token(true); diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 477f26b45..13c2676db 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -256,6 +256,7 @@ struct VerilogFrontend : public Frontend { AST::get_line_num = &frontend_verilog_yyget_lineno; current_ast = new AST::AstNode(AST::AST_DESIGN); + default_nettype_wire = true; FILE *fp = f; std::string code_after_preproc; @@ -279,7 +280,7 @@ struct VerilogFrontend : public Frontend { child->attributes[attr] = AST::AstNode::mkconst_int(1, false); } - 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); + 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); if (!flag_nopp) fclose(fp); diff --git a/frontends/verilog/verilog_frontend.h b/frontends/verilog/verilog_frontend.h index 8b4fae6e9..99b2164ef 100644 --- a/frontends/verilog/verilog_frontend.h +++ b/frontends/verilog/verilog_frontend.h @@ -42,6 +42,9 @@ namespace VERILOG_FRONTEND // this function converts a Verilog constant to an AST_CONSTANT node AST::AstNode *const2ast(std::string code, char case_type = 0); + + // state of `default_nettype + extern bool default_nettype_wire; } // the pre-processor -- cgit v1.2.3 From 9992026a8d4482abd8fbae8cb246a87cbbbde364 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 11 Mar 2014 14:06:57 +0100 Subject: Added support for `line compiler directive --- frontends/verilog/lexer.l | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'frontends/verilog') diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 79f44b4a6..e3e5e4ab2 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -75,6 +75,17 @@ namespace VERILOG_FRONTEND { ln_stack.pop_back(); } +"`line"[ \t]+[^ \t\r\n]+[ \t]+\"[^ \r\n]+\"[^\r\n]*\n { + char *p = yytext + 5; + while (*p == ' ' || *p == '\t') p++; + frontend_verilog_yyset_lineno(atoi(p)); + while (*p && *p != ' ' && *p != '\t') p++; + while (*p == ' ' || *p == '\t') p++; + char *q = *p ? p + 1 : p; + while (*q && *q != '"') q++; + current_filename = std::string(p).substr(1, q-p-1); +} + "`file_notfound "[^\n]* { log_error("Can't open include file `%s'!\n", yytext + 15); } -- cgit v1.2.3 From fad8558eb5ecbd62e2032a48c537bfecfad3dfc4 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 13 Mar 2014 12:48:10 +0100 Subject: Merged OSX fixes from Siesh1oo with some modifications --- frontends/verilog/verilog_frontend.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'frontends/verilog') diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 13c2676db..8e9efa173 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -27,6 +27,7 @@ */ #include "verilog_frontend.h" +#include "kernel/compatibility.h" #include "kernel/register.h" #include "kernel/log.h" #include "libs/sha1/sha1.h" -- cgit v1.2.3 From a1be4816d602548f4454242dc17f8a85ccaa91bd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Apr 2014 14:22:11 +0200 Subject: Replaced depricated %name-prefix= bison directive --- frontends/verilog/parser.y | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 4726f1aa3..ed9be692b 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -84,7 +84,7 @@ static void free_attr(std::map *al) %} -%name-prefix="frontend_verilog_yy" +%name-prefix "frontend_verilog_yy" %union { std::string *string; -- cgit v1.2.3 From 7188542155902bcf3880d482d472e91331f8a3ed Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 20 Apr 2014 14:28:23 +0200 Subject: Fixed clang -Wdeprecated-register warnings --- frontends/verilog/lexer.l | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'frontends/verilog') diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index e3e5e4ab2..226a26709 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -34,6 +34,11 @@ %{ +#ifdef __clang__ +// bison generates code using the 'register' storage class specifier +#pragma clang diagnostic ignored "-Wdeprecated-register" +#endif + #include "kernel/log.h" #include "verilog_frontend.h" #include "frontends/ast/ast.h" -- cgit v1.2.3 From f9c1cd5edba5acb4d9b9dd287c7265111cf22087 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 4 Jun 2014 09:10:50 +0200 Subject: Improved error message for options after front-end filename arguments --- frontends/verilog/verilog_frontend.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 8e9efa173..108214586 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -48,7 +48,7 @@ struct VerilogFrontend : public Frontend { { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| log("\n"); - log(" read_verilog [filename]\n"); + log(" read_verilog [options] [filename]\n"); log("\n"); log("Load modules from a verilog file to the current design. A large subset of\n"); log("Verilog-2005 is supported.\n"); -- cgit v1.2.3 From b5cd7a01793294a53d91a2cd3ee9bbca5b9a8c54 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 6 Jun 2014 17:40:04 +0200 Subject: added while and repeat support to verilog parser --- frontends/verilog/lexer.l | 2 ++ frontends/verilog/parser.y | 28 +++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 226a26709..5300d1b26 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -140,6 +140,8 @@ namespace VERILOG_FRONTEND { "default" { return TOK_DEFAULT; } "generate" { return TOK_GENERATE; } "endgenerate" { return TOK_ENDGENERATE; } +"while" { return TOK_WHILE; } +"repeat" { return TOK_REPEAT; } "assert"([ \t\r\n]+"property")? { return TOK_ASSERT; } diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index ed9be692b..a12dcf142 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -98,7 +98,7 @@ static void free_attr(std::map *al) %token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM %token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_REG %token TOK_INTEGER TOK_SIGNED TOK_ASSIGN TOK_ALWAYS TOK_INITIAL -%token TOK_BEGIN TOK_END TOK_IF TOK_ELSE TOK_FOR +%token TOK_BEGIN TOK_END TOK_IF TOK_ELSE TOK_FOR TOK_WHILE TOK_REPEAT %token TOK_POSEDGE TOK_NEGEDGE TOK_OR %token TOK_CASE TOK_CASEX TOK_CASEZ TOK_ENDCASE TOK_DEFAULT %token TOK_FUNCTION TOK_ENDFUNCTION TOK_TASK TOK_ENDTASK @@ -819,6 +819,32 @@ behavioral_stmt: ast_stack.pop_back(); ast_stack.pop_back(); } | + attr TOK_WHILE '(' expr ')' { + AstNode *node = new AstNode(AST_WHILE); + ast_stack.back()->children.push_back(node); + ast_stack.push_back(node); + append_attr(node, $1); + AstNode *block = new AstNode(AST_BLOCK); + ast_stack.back()->children.push_back($4); + ast_stack.back()->children.push_back(block); + ast_stack.push_back(block); + } behavioral_stmt { + ast_stack.pop_back(); + ast_stack.pop_back(); + } | + attr TOK_REPEAT '(' expr ')' { + AstNode *node = new AstNode(AST_REPEAT); + ast_stack.back()->children.push_back(node); + ast_stack.push_back(node); + append_attr(node, $1); + AstNode *block = new AstNode(AST_BLOCK); + ast_stack.back()->children.push_back($4); + ast_stack.back()->children.push_back(block); + ast_stack.push_back(block); + } behavioral_stmt { + ast_stack.pop_back(); + ast_stack.pop_back(); + } | attr TOK_IF '(' expr ')' { AstNode *node = new AstNode(AST_CASE); AstNode *block = new AstNode(AST_BLOCK); -- cgit v1.2.3 From 5281562d0e9468c584e6db6f30908e3155a76ad2 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 6 Jun 2014 23:05:01 +0200 Subject: made the generate..endgenrate keywords optional --- frontends/verilog/parser.y | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index a12dcf142..42a8f91c5 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -373,6 +373,8 @@ range_or_integer: module_body: module_body module_body_stmt | + /* the following line makes the generate..endgenrate keywords optional */ + module_body gen_stmt | /* empty */; module_body_stmt: @@ -1013,9 +1015,12 @@ single_arg: }; module_gen_body: - module_gen_body gen_stmt | + module_gen_body gen_stmt_or_module_body_stmt | /* empty */; +gen_stmt_or_module_body_stmt: + gen_stmt | module_body_stmt; + // this production creates the obligatory if-else shift/reduce conflict gen_stmt: TOK_FOR '(' { @@ -1054,15 +1059,14 @@ gen_stmt: if ($6 != NULL) delete $6; ast_stack.pop_back(); - } | - module_body_stmt; + }; gen_stmt_block: { AstNode *node = new AstNode(AST_GENBLOCK); ast_stack.back()->children.push_back(node); ast_stack.push_back(node); - } gen_stmt { + } gen_stmt_or_module_body_stmt { ast_stack.pop_back(); }; -- cgit v1.2.3 From e275e8eef9ae47670075bd73a671f3acd3c0ca52 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 7 Jun 2014 11:48:50 +0200 Subject: Add support for cell arrays --- frontends/verilog/parser.y | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'frontends/verilog') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 42a8f91c5..f422258c7 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -634,6 +634,13 @@ single_cell: astbuf2->str = *$1; delete $1; ast_stack.back()->children.push_back(astbuf2); + } '(' cell_port_list ')' | + TOK_ID non_opt_range { + astbuf2 = astbuf1->clone(); + if (astbuf2->type != AST_PRIMITIVE) + astbuf2->str = *$1; + delete $1; + ast_stack.back()->children.push_back(new AstNode(AST_CELLARRAY, $2, astbuf2)); } '(' cell_port_list ')'; prim_list: -- cgit v1.2.3 From 482d9208aa9dacb7afe21f08c882d4881581013a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 12 Jun 2014 11:54:20 +0200 Subject: Added read_verilog -sv options, added support for bit, logic, allways_ff, always_comb, and always_latch --- frontends/verilog/lexer.l | 17 ++++++++++++++++- frontends/verilog/parser.y | 10 ++++++++-- frontends/verilog/verilog_frontend.cc | 10 ++++++++++ frontends/verilog/verilog_frontend.h | 3 +++ 4 files changed, 37 insertions(+), 3 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 5300d1b26..8f4b49916 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -52,6 +52,14 @@ namespace VERILOG_FRONTEND { std::vector ln_stack; } +#define SV_KEYWORD(_tok) \ + if (sv_mode) return _tok; \ + log("Lexer warning: The SystemVerilog keyword `%s' (at %s:%d) is not "\ + "recognized unless read_verilog is called with -sv!\n", yytext, \ + AST::current_filename.c_str(), frontend_verilog_yyget_lineno()); \ + frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext); \ + return TOK_ID; + %} %option yylineno @@ -143,7 +151,14 @@ namespace VERILOG_FRONTEND { "while" { return TOK_WHILE; } "repeat" { return TOK_REPEAT; } -"assert"([ \t\r\n]+"property")? { return TOK_ASSERT; } +"always_comb" { SV_KEYWORD(TOK_ALWAYS); } +"always_ff" { SV_KEYWORD(TOK_ALWAYS); } +"always_latch" { SV_KEYWORD(TOK_ALWAYS); } + +"assert" { SV_KEYWORD(TOK_ASSERT); } +"property" { SV_KEYWORD(TOK_PROPERTY); } +"logic" { SV_KEYWORD(TOK_REG); } +"bit" { SV_KEYWORD(TOK_REG); } "input" { return TOK_INPUT; } "output" { return TOK_OUTPUT; } diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index f422258c7..cce8a8c40 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -54,6 +54,7 @@ namespace VERILOG_FRONTEND { int current_function_or_task_port_id; std::vector case_type_stack; bool default_nettype_wire; + bool sv_mode; } static void append_attr(AstNode *ast, std::map *al) @@ -105,7 +106,7 @@ static void free_attr(std::map *al) %token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR %token TOK_SYNOPSYS_FULL_CASE TOK_SYNOPSYS_PARALLEL_CASE %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED -%token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT +%token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT TOK_PROPERTY %type wire_type range non_opt_range range_or_integer expr basic_expr concat_list rvalue lvalue lvalue_concat_list %type opt_label tok_prim_wrapper hierarchical_id @@ -379,7 +380,7 @@ module_body: module_body_stmt: task_func_decl | param_decl | localparam_decl | defparam_decl | wire_decl | assign_stmt | cell_stmt | - always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert; + always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property; task_func_decl: TOK_TASK TOK_ID ';' { @@ -773,6 +774,11 @@ assert: ast_stack.back()->children.push_back(new AstNode(AST_ASSERT, $3)); }; +assert_property: + TOK_ASSERT TOK_PROPERTY '(' expr ')' ';' { + ast_stack.back()->children.push_back(new AstNode(AST_ASSERT, $4)); + }; + simple_behavioral_stmt: lvalue '=' expr { AstNode *node = new AstNode(AST_ASSIGN_EQ, $1, $3); diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 108214586..437fc3ec0 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -53,6 +53,10 @@ struct VerilogFrontend : public Frontend { log("Load modules from a verilog file to the current design. A large subset of\n"); log("Verilog-2005 is supported.\n"); log("\n"); + log(" -sv\n"); + log(" enable support for SystemVerilog features. (only a small subset\n"); + log(" of SystemVerilog is supported)\n"); + log("\n"); log(" -dump_ast1\n"); log(" dump abstract syntax tree (before simplification)\n"); log("\n"); @@ -150,7 +154,9 @@ struct VerilogFrontend : public Frontend { std::map defines_map; std::list include_dirs; std::list attributes; + frontend_verilog_yydebug = false; + sv_mode = false; log_header("Executing Verilog-2005 frontend.\n"); @@ -159,6 +165,10 @@ struct VerilogFrontend : public Frontend { size_t argidx; for (argidx = 1; argidx < args.size(); argidx++) { std::string arg = args[argidx]; + if (arg == "-sv") { + sv_mode = true; + continue; + } if (arg == "-dump_ast1") { flag_dump_ast1 = true; continue; diff --git a/frontends/verilog/verilog_frontend.h b/frontends/verilog/verilog_frontend.h index 99b2164ef..6d01a1532 100644 --- a/frontends/verilog/verilog_frontend.h +++ b/frontends/verilog/verilog_frontend.h @@ -45,6 +45,9 @@ namespace VERILOG_FRONTEND // state of `default_nettype extern bool default_nettype_wire; + + // running in SystemVerilog mode + extern bool sv_mode; } // the pre-processor -- cgit v1.2.3 From 7ef0da32cdcddb50de8ba8acf0c6421fe5732c55 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 13 Jun 2014 11:29:23 +0200 Subject: Added Verilog lexer and parser support for real values --- frontends/verilog/lexer.l | 10 ++++++++++ frontends/verilog/parser.y | 17 ++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 8f4b49916..ed304572b 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -179,6 +179,16 @@ namespace VERILOG_FRONTEND { return TOK_CONST; } +[0-9][0-9_]*\.[0-9][0-9_]*([eE][-+]?[0-9_]+)? { + frontend_verilog_yylval.string = new std::string(yytext); + return TOK_REAL; +} + +[0-9][0-9_]*[eE][-+]?[0-9_]+ { + frontend_verilog_yylval.string = new std::string(yytext); + return TOK_REAL; +} + \" { BEGIN(STRING); } \\. { yymore(); } \" { diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index cce8a8c40..e51712b3f 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -35,7 +35,7 @@ %{ #include -#include +#include #include "verilog_frontend.h" #include "kernel/log.h" @@ -94,7 +94,7 @@ static void free_attr(std::map *al) bool boolean; } -%token TOK_STRING TOK_ID TOK_CONST TOK_PRIMITIVE +%token TOK_STRING TOK_ID TOK_CONST TOK_REAL TOK_PRIMITIVE %token ATTR_BEGIN ATTR_END DEFATTR_BEGIN DEFATTR_END %token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM %token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_REG @@ -221,7 +221,7 @@ module: frontend_verilog_yyerror("Missing details for module port `%s'.", port_stubs.begin()->first.c_str()); ast_stack.pop_back(); - assert(ast_stack.size() == 0); + log_assert(ast_stack.size() == 0); }; module_para_opt: @@ -1133,6 +1133,17 @@ basic_expr: log_error("Value conversion failed: `%s'\n", $1->c_str()); delete $1; } | + TOK_REAL { + $$ = new AstNode(AST_REALVALUE); + char *p = strdup($1->c_str()), *q; + for (int i = 0, j = 0; !p[j]; j++) + if (p[j] != '_') + p[i++] = p[j], p[i] = 0; + $$->realvalue = strtod(p, &q); + log_assert(*q == 0); + delete $1; + free(p); + } | TOK_STRING { $$ = AstNode::mkconst_str(*$1); delete $1; -- cgit v1.2.3 From 9bd7d5c46856f25fd7befcdfe20198fd8eb59ccd Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 14 Jun 2014 12:00:47 +0200 Subject: Added handling of real-valued parameters/localparams --- frontends/verilog/lexer.l | 5 +++-- frontends/verilog/parser.y | 17 ++++++++++++----- 2 files changed, 15 insertions(+), 7 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index ed304572b..0839f5cf9 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -168,6 +168,7 @@ namespace VERILOG_FRONTEND { "integer" { return TOK_INTEGER; } "signed" { return TOK_SIGNED; } "genvar" { return TOK_GENVAR; } +"real" { return TOK_REAL; } [0-9]+ { frontend_verilog_yylval.string = new std::string(yytext); @@ -181,12 +182,12 @@ namespace VERILOG_FRONTEND { [0-9][0-9_]*\.[0-9][0-9_]*([eE][-+]?[0-9_]+)? { frontend_verilog_yylval.string = new std::string(yytext); - return TOK_REAL; + return TOK_REALVAL; } [0-9][0-9_]*[eE][-+]?[0-9_]+ { frontend_verilog_yylval.string = new std::string(yytext); - return TOK_REAL; + return TOK_REALVAL; } \" { BEGIN(STRING); } diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index e51712b3f..57defd56b 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -94,7 +94,7 @@ static void free_attr(std::map *al) bool boolean; } -%token TOK_STRING TOK_ID TOK_CONST TOK_REAL TOK_PRIMITIVE +%token TOK_STRING TOK_ID TOK_CONST TOK_REALVAL TOK_PRIMITIVE %token ATTR_BEGIN ATTR_END DEFATTR_BEGIN DEFATTR_END %token TOK_MODULE TOK_ENDMODULE TOK_PARAMETER TOK_LOCALPARAM TOK_DEFPARAM %token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_REG @@ -103,7 +103,7 @@ static void free_attr(std::map *al) %token TOK_POSEDGE TOK_NEGEDGE TOK_OR %token TOK_CASE TOK_CASEX TOK_CASEZ TOK_ENDCASE TOK_DEFAULT %token TOK_FUNCTION TOK_ENDFUNCTION TOK_TASK TOK_ENDTASK -%token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR +%token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR TOK_REAL %token TOK_SYNOPSYS_FULL_CASE TOK_SYNOPSYS_PARALLEL_CASE %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT TOK_PROPERTY @@ -438,6 +438,13 @@ param_integer: astbuf1->children.back()->children.push_back(AstNode::mkconst_int(0, true)); } | /* empty */; +param_real: + TOK_REAL { + if (astbuf1->children.size() != 1) + frontend_verilog_yyerror("Syntax error."); + astbuf1->children.push_back(new AstNode(AST_REALVALUE)); + } | /* empty */; + param_range: range { if ($1 != NULL) { @@ -451,7 +458,7 @@ param_decl: TOK_PARAMETER { astbuf1 = new AstNode(AST_PARAMETER); astbuf1->children.push_back(AstNode::mkconst_int(0, true)); - } param_signed param_integer param_range param_decl_list ';' { + } param_signed param_integer param_real param_range param_decl_list ';' { delete astbuf1; }; @@ -459,7 +466,7 @@ localparam_decl: TOK_LOCALPARAM { astbuf1 = new AstNode(AST_LOCALPARAM); astbuf1->children.push_back(AstNode::mkconst_int(0, true)); - } param_signed param_integer param_range param_decl_list ';' { + } param_signed param_integer param_real param_range param_decl_list ';' { delete astbuf1; }; @@ -1133,7 +1140,7 @@ basic_expr: log_error("Value conversion failed: `%s'\n", $1->c_str()); delete $1; } | - TOK_REAL { + TOK_REALVAL { $$ = new AstNode(AST_REALVALUE); char *p = strdup($1->c_str()), *q; for (int i = 0, j = 0; !p[j]; j++) -- cgit v1.2.3 From 7f57bc838517a5660beaf0645d7bb4cc6ed71ce9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 15 Jun 2014 08:48:17 +0200 Subject: Improved parsing of large integer constants --- frontends/verilog/const2ast.cc | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/const2ast.cc b/frontends/verilog/const2ast.cc index c95ce5dc4..8491a6b47 100644 --- a/frontends/verilog/const2ast.cc +++ b/frontends/verilog/const2ast.cc @@ -52,6 +52,8 @@ static int my_decimal_div_by_two(std::vector &digits) carry = digits[i] % 2; digits[i] /= 2; } + while (!digits.empty() && !digits.front()) + digits.erase(digits.begin()); return carry; } @@ -90,10 +92,15 @@ static void my_strtobin(std::vector &data, const char *str, int le if (base == 10) { data.clear(); - if (len_in_bits < 0) - len_in_bits = ceil(digits.size()/log10(2)); - for (int i = 0; i < len_in_bits; i++) - data.push_back(my_decimal_div_by_two(digits) ? RTLIL::S1 : RTLIL::S0); + if (len_in_bits < 0) { + while (!digits.empty()) + data.push_back(my_decimal_div_by_two(digits) ? RTLIL::S1 : RTLIL::S0); + while (data.size() < 32) + data.push_back(RTLIL::S0); + } else { + for (int i = 0; i < len_in_bits; i++) + data.push_back(my_decimal_div_by_two(digits) ? RTLIL::S1 : RTLIL::S0); + } return; } @@ -151,20 +158,24 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type) str = code.c_str(); char *endptr; - long intval = strtol(str, &endptr, 10); + long len_in_bits = strtol(str, &endptr, 10); + + // Simple base-10 integer + if (*endptr == 0) { + std::vector data; + my_strtobin(data, str, -1, 10, case_type); + if (data.back() == RTLIL::S1) + data.push_back(RTLIL::S0); + return AstNode::mkconst_bits(data, true); + } - // Simple 32 bit integer - if (*endptr == 0) - return AstNode::mkconst_int(intval, true); - // unsized constant if (str == endptr) - intval = -1; + len_in_bits = -1; // The "'s?[bodh]" syntax if (*endptr == '\'') { - int len_in_bits = intval; std::vector data; bool is_signed = false; if (*(endptr+1) == 's') { @@ -188,6 +199,12 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type) default: return NULL; } + if (len_in_bits < 0) { + if (is_signed && data.back() == RTLIL::S1) + data.push_back(RTLIL::S0); + while (data.size() < 32) + data.push_back(RTLIL::S0); + } return AstNode::mkconst_bits(data, is_signed); } -- cgit v1.2.3 From 0c4c79c4c6f8a433ef4b141b1523bccc261f8231 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 16 Jun 2014 15:02:40 +0200 Subject: Fixed parsing of TOK_INTEGER (implies TOK_SIGNED) --- frontends/verilog/parser.y | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 57defd56b..37c3232aa 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -108,7 +108,7 @@ static void free_attr(std::map *al) %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT TOK_PROPERTY -%type wire_type range non_opt_range range_or_integer expr basic_expr concat_list rvalue lvalue lvalue_concat_list +%type wire_type range non_opt_range range_or_signed_int expr basic_expr concat_list rvalue lvalue lvalue_concat_list %type opt_label tok_prim_wrapper hierarchical_id %type opt_signed %type attr @@ -322,6 +322,7 @@ wire_type_token: astbuf3->is_reg = true; astbuf3->range_left = 31; astbuf3->range_right = 0; + astbuf3->is_signed = true; } | TOK_GENVAR { astbuf3->type = AST_GENVAR; @@ -362,7 +363,7 @@ range: $$ = NULL; }; -range_or_integer: +range_or_signed_int: range { $$ = $1; } | @@ -370,6 +371,7 @@ range_or_integer: $$ = new AstNode(AST_RANGE); $$->children.push_back(AstNode::mkconst_int(31, true)); $$->children.push_back(AstNode::mkconst_int(0, true)); + $$->is_signed = true; }; module_body: @@ -394,16 +396,19 @@ task_func_decl: current_function_or_task = NULL; ast_stack.pop_back(); } | - TOK_FUNCTION opt_signed range_or_integer TOK_ID ';' { + TOK_FUNCTION opt_signed range_or_signed_int TOK_ID ';' { current_function_or_task = new AstNode(AST_FUNCTION); current_function_or_task->str = *$4; ast_stack.back()->children.push_back(current_function_or_task); ast_stack.push_back(current_function_or_task); AstNode *outreg = new AstNode(AST_WIRE); - if ($3 != NULL) - outreg->children.push_back($3); outreg->str = *$4; outreg->is_signed = $2; + if ($3 != NULL) { + outreg->children.push_back($3); + outreg->is_signed = $2 || $3->is_signed; + $3->is_signed = false; + } current_function_or_task->children.push_back(outreg); current_function_or_task_port_id = 1; delete $4; @@ -436,6 +441,7 @@ param_integer: astbuf1->children.push_back(new AstNode(AST_RANGE)); astbuf1->children.back()->children.push_back(AstNode::mkconst_int(31, true)); astbuf1->children.back()->children.push_back(AstNode::mkconst_int(0, true)); + astbuf1->is_signed = true; } | /* empty */; param_real: -- cgit v1.2.3 From ee8ad72fd950e1ee204e5c97155a50b8b1445dec Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 2 Jul 2014 06:27:04 +0200 Subject: fixed parsing of constant with comment between size and value --- frontends/verilog/parser.y | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'frontends/verilog') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 37c3232aa..ce7b99272 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -1140,6 +1140,13 @@ basic_expr: delete $1; delete $2; } | + TOK_CONST TOK_CONST { + $$ = const2ast(*$1 + *$2, case_type_stack.size() == 0 ? 0 : case_type_stack.back()); + if ($$ == NULL || (*$2)[0] != '\'') + log_error("Value conversion failed: `%s%s'\n", $1->c_str(), $2->c_str()); + delete $1; + delete $2; + } | TOK_CONST { $$ = const2ast(*$1, case_type_stack.size() == 0 ? 0 : case_type_stack.back()); if ($$ == NULL) -- cgit v1.2.3 From b17d6531c833f9064c5888c694aa24e8a395b72a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 24 Jul 2014 17:15:01 +0200 Subject: Added "make PRETTY=1" --- frontends/verilog/Makefile.inc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/Makefile.inc b/frontends/verilog/Makefile.inc index 5586b4cc2..49eb320ec 100644 --- a/frontends/verilog/Makefile.inc +++ b/frontends/verilog/Makefile.inc @@ -5,13 +5,13 @@ GENFILES += frontends/verilog/parser.output GENFILES += frontends/verilog/lexer.cc frontends/verilog/parser.tab.cc: frontends/verilog/parser.y - bison -d -r all -b frontends/verilog/parser frontends/verilog/parser.y - mv frontends/verilog/parser.tab.c frontends/verilog/parser.tab.cc + $(P) bison -d -r all -b frontends/verilog/parser frontends/verilog/parser.y + $(Q) mv frontends/verilog/parser.tab.c frontends/verilog/parser.tab.cc frontends/verilog/parser.tab.h: frontends/verilog/parser.tab.cc frontends/verilog/lexer.cc: frontends/verilog/lexer.l - flex -o frontends/verilog/lexer.cc frontends/verilog/lexer.l + $(P) flex -o frontends/verilog/lexer.cc frontends/verilog/lexer.l OBJS += frontends/verilog/parser.tab.o OBJS += frontends/verilog/lexer.o -- cgit v1.2.3 From 7bd2d1064f2eceddc3c93c121c4154a2f594a040 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 28 Jul 2014 11:08:55 +0200 Subject: Using log_assert() instead of assert() --- frontends/verilog/const2ast.cc | 3 +-- frontends/verilog/preproc.cc | 3 +-- frontends/verilog/verilog_frontend.cc | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/const2ast.cc b/frontends/verilog/const2ast.cc index 8491a6b47..446f5e50c 100644 --- a/frontends/verilog/const2ast.cc +++ b/frontends/verilog/const2ast.cc @@ -36,7 +36,6 @@ #include "verilog_frontend.h" #include "kernel/log.h" -#include #include #include @@ -47,7 +46,7 @@ static int my_decimal_div_by_two(std::vector &digits) { int carry = 0; for (size_t i = 0; i < digits.size(); i++) { - assert(digits[i] < 10); + log_assert(digits[i] < 10); digits[i] += carry * 10; carry = digits[i] % 2; digits[i] /= 2; diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 873ae3d51..67b2ffa7c 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -37,7 +37,6 @@ #include #include #include -#include static std::list output_code; static std::list input_buffer; @@ -65,7 +64,7 @@ static char next_char() if (input_buffer.empty()) return 0; - assert(input_buffer_charp <= input_buffer.front().size()); + log_assert(input_buffer_charp <= input_buffer.front().size()); if (input_buffer_charp == input_buffer.front().size()) { input_buffer_charp = 0; input_buffer.pop_front(); diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 437fc3ec0..cbc594e86 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -33,7 +33,6 @@ #include "libs/sha1/sha1.h" #include #include -#include using namespace VERILOG_FRONTEND; -- cgit v1.2.3 From e605af8a4937533b35068071e14f5bd92c2e5b4f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 29 Jul 2014 20:14:25 +0200 Subject: Fixed Verilog pre-processor for files with no trailing newline --- frontends/verilog/preproc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 67b2ffa7c..9ff68822e 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -198,7 +198,7 @@ static void input_file(FILE *f, std::string filename) buffer[rc] = 0; input_buffer.insert(it, buffer); } - input_buffer.insert(it, "`file_pop\n"); + input_buffer.insert(it, "\n`file_pop\n"); } std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::map pre_defines_map, const std::list include_dirs) -- cgit v1.2.3 From 7daad40ca408732786d46fee8b5485bf45595807 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 30 Jul 2014 20:18:48 +0200 Subject: Fixed counting verilog line numbers for "// synopsys translate_off" sections --- frontends/verilog/lexer.l | 6 +++--- frontends/verilog/preproc.cc | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 0839f5cf9..00deeb0b4 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -74,21 +74,21 @@ namespace VERILOG_FRONTEND { %% -"`file_push "[^\n]* { +"`file_push "[^\n]* { fn_stack.push_back(current_filename); ln_stack.push_back(frontend_verilog_yyget_lineno()); current_filename = yytext+11; frontend_verilog_yyset_lineno(0); } -"`file_pop"[^\n]*\n { +"`file_pop"[^\n]*\n { current_filename = fn_stack.back(); fn_stack.pop_back(); frontend_verilog_yyset_lineno(ln_stack.back()); ln_stack.pop_back(); } -"`line"[ \t]+[^ \t\r\n]+[ \t]+\"[^ \r\n]+\"[^\r\n]*\n { +"`line"[ \t]+[^ \t\r\n]+[ \t]+\"[^ \r\n]+\"[^\r\n]*\n { char *p = yytext + 5; while (*p == ' ' || *p == '\t') p++; frontend_verilog_yyset_lineno(atoi(p)); diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 9ff68822e..2cfa8ca76 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -300,7 +300,7 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m input_file(fp, fn); fclose(fp); } else - output_code.push_back("`file_notfound " + fn + "\n"); + output_code.push_back("`file_notfound " + fn); continue; } -- cgit v1.2.3 From 1cb25c05b37b0172dbc50e140fe20f25d973dd8a Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 31 Jul 2014 13:19:47 +0200 Subject: Moved some stuff to kernel/yosys.{h,cc}, using Yosys:: namespace --- frontends/verilog/const2ast.cc | 4 ++++ frontends/verilog/lexer.l | 3 +++ frontends/verilog/parser.y | 7 +++++-- frontends/verilog/preproc.cc | 4 ++++ frontends/verilog/verilog_frontend.cc | 3 +++ frontends/verilog/verilog_frontend.h | 6 +++++- 6 files changed, 24 insertions(+), 3 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/const2ast.cc b/frontends/verilog/const2ast.cc index 446f5e50c..a81e3010f 100644 --- a/frontends/verilog/const2ast.cc +++ b/frontends/verilog/const2ast.cc @@ -39,6 +39,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + using namespace AST; // divide an arbitrary length decimal number by two and return the rest @@ -210,3 +212,5 @@ AstNode *VERILOG_FRONTEND::const2ast(std::string code, char case_type) return NULL; } +YOSYS_NAMESPACE_END + diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index 00deeb0b4..fdb9bb02c 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -44,13 +44,16 @@ #include "frontends/ast/ast.h" #include "parser.tab.h" +USING_YOSYS_NAMESPACE using namespace AST; using namespace VERILOG_FRONTEND; +YOSYS_NAMESPACE_BEGIN namespace VERILOG_FRONTEND { std::vector fn_stack; std::vector ln_stack; } +YOSYS_NAMESPACE_END #define SV_KEYWORD(_tok) \ if (sv_mode) return _tok; \ diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index ce7b99272..c62e761e2 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -39,9 +39,11 @@ #include "verilog_frontend.h" #include "kernel/log.h" +USING_YOSYS_NAMESPACE using namespace AST; using namespace VERILOG_FRONTEND; +YOSYS_NAMESPACE_BEGIN namespace VERILOG_FRONTEND { int port_counter; std::map port_stubs; @@ -56,6 +58,7 @@ namespace VERILOG_FRONTEND { bool default_nettype_wire; bool sv_mode; } +YOSYS_NAMESPACE_END static void append_attr(AstNode *ast, std::map *al) { @@ -89,8 +92,8 @@ static void free_attr(std::map *al) %union { std::string *string; - struct AstNode *ast; - std::map *al; + struct YOSYS_NAMESPACE_PREFIX AST::AstNode *ast; + std::map *al; bool boolean; } diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 2cfa8ca76..8efd4d7c3 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -38,6 +38,8 @@ #include #include +YOSYS_NAMESPACE_BEGIN + static std::list output_code; static std::list input_buffer; static size_t input_buffer_charp; @@ -427,3 +429,5 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m return output; } +YOSYS_NAMESPACE_END + diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index cbc594e86..4466e1cb6 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -34,6 +34,7 @@ #include #include +YOSYS_NAMESPACE_BEGIN using namespace VERILOG_FRONTEND; // use the Verilog bison/flex parser to generate an AST and use AST::process() to convert it to RTLIL @@ -376,3 +377,5 @@ struct VerilogDefaults : public Pass { } } VerilogDefaults; +YOSYS_NAMESPACE_END + diff --git a/frontends/verilog/verilog_frontend.h b/frontends/verilog/verilog_frontend.h index 6d01a1532..dac5b3d02 100644 --- a/frontends/verilog/verilog_frontend.h +++ b/frontends/verilog/verilog_frontend.h @@ -29,12 +29,14 @@ #ifndef VERILOG_FRONTEND_H #define VERILOG_FRONTEND_H -#include "kernel/rtlil.h" +#include "kernel/yosys.h" #include "frontends/ast/ast.h" #include #include #include +YOSYS_NAMESPACE_BEGIN + namespace VERILOG_FRONTEND { // this variable is set to a new AST_DESIGN node and then filled with the AST by the bison parser @@ -53,6 +55,8 @@ namespace VERILOG_FRONTEND // the pre-processor std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::map pre_defines_map, const std::list include_dirs); +YOSYS_NAMESPACE_END + // the usual bison/flex stuff extern int frontend_verilog_yydebug; int frontend_verilog_yylex(void); -- cgit v1.2.3 From b5a3419ac2c6f367b90f062c4e2252029910cdb9 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 4 Aug 2014 15:19:24 +0200 Subject: Added support for non-standard "module mod_name(...);" syntax --- frontends/verilog/parser.y | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index c62e761e2..1e0168a5f 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -55,6 +55,7 @@ namespace VERILOG_FRONTEND { struct AstNode *current_ast, *current_ast_mod; int current_function_or_task_port_id; std::vector case_type_stack; + bool do_not_require_port_stubs; bool default_nettype_wire; bool sv_mode; } @@ -210,6 +211,7 @@ hierarchical_id: module: attr TOK_MODULE TOK_ID { + do_not_require_port_stubs = false; AstNode *mod = new AstNode(AST_MODULE); current_ast->children.push_back(mod); current_ast_mod = mod; @@ -244,7 +246,8 @@ single_module_para: }; module_args_opt: - '(' ')' | /* empty */ | '(' module_args optional_comma ')'; + '(' ')' | /* empty */ | '(' module_args optional_comma ')' | + '(' '.' '.' '.' ')' { do_not_require_port_stubs = true; }; module_args: module_arg | module_args ',' module_arg; @@ -582,6 +585,9 @@ wire_name: node->children.push_back($2); } if (current_function_or_task == NULL) { + if (do_not_require_port_stubs && (node->is_input || node->is_output) && port_stubs.count(*$1) == 0) { + port_stubs[*$1] = ++port_counter; + } if (port_stubs.count(*$1) != 0) { if (!node->is_input && !node->is_output) frontend_verilog_yyerror("Module port `%s' is neither input nor output.", $1->c_str()); -- cgit v1.2.3 From 91dd87e60b120119ee34a9961a7b5f33f340282e Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Tue, 5 Aug 2014 12:15:53 +0200 Subject: Improved scope resolution of local regs in Verilog+AST frontend --- frontends/verilog/parser.y | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 1e0168a5f..26e2ddc34 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -599,12 +599,11 @@ wire_name: if (node->is_input || node->is_output) frontend_verilog_yyerror("Module port `%s' is not declared in module header.", $1->c_str()); } - ast_stack.back()->children.push_back(node); } else { if (node->is_input || node->is_output) node->port_id = current_function_or_task_port_id++; - current_function_or_task->children.push_back(node); } + ast_stack.back()->children.push_back(node); delete $1; }; -- cgit v1.2.3 From d259abbda2b9d568228dc8d0bed2d0b0d88d7b4f Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 6 Aug 2014 15:43:46 +0200 Subject: Added AST_MULTIRANGE (arrays with more than 1 dimension) --- frontends/verilog/parser.y | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 26e2ddc34..95d7f3935 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -112,7 +112,8 @@ static void free_attr(std::map *al) %token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED %token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_ASSERT TOK_PROPERTY -%type wire_type range non_opt_range range_or_signed_int expr basic_expr concat_list rvalue lvalue lvalue_concat_list +%type range range_or_multirange non_opt_range non_opt_multirange range_or_signed_int +%type wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list %type opt_label tok_prim_wrapper hierarchical_id %type opt_signed %type attr @@ -361,6 +362,15 @@ non_opt_range: $$->children.push_back($2); }; +non_opt_multirange: + non_opt_range non_opt_range { + $$ = new AstNode(AST_MULTIRANGE, $1, $2); + } | + non_opt_multirange non_opt_range { + $$ = $1; + $$->children.push_back($2); + }; + range: non_opt_range { $$ = $1; @@ -369,6 +379,10 @@ range: $$ = NULL; }; +range_or_multirange: + range { $$ = $1; } | + non_opt_multirange { $$ = $1; }; + range_or_signed_int: range { $$ = $1; @@ -566,7 +580,7 @@ wire_name_and_opt_assign: }; wire_name: - TOK_ID range { + TOK_ID range_or_multirange { AstNode *node = astbuf1->clone(); node->str = *$1; append_attr_clone(node, albuf); @@ -1007,8 +1021,8 @@ rvalue: $$->str = *$1; delete $1; } | - hierarchical_id non_opt_range non_opt_range { - $$ = new AstNode(AST_IDENTIFIER, $2, $3); + hierarchical_id non_opt_multirange { + $$ = new AstNode(AST_IDENTIFIER, $2); $$->str = *$1; delete $1; }; -- cgit v1.2.3 From 2dc33337346ea53a654af3d80bdf056c7ccfa43c Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 7 Aug 2014 16:41:27 +0200 Subject: Also allow "module foobar(input foo, output bar, ...);" syntax --- frontends/verilog/parser.y | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 95d7f3935..f619d3c2b 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -247,8 +247,7 @@ single_module_para: }; module_args_opt: - '(' ')' | /* empty */ | '(' module_args optional_comma ')' | - '(' '.' '.' '.' ')' { do_not_require_port_stubs = true; }; + '(' ')' | /* empty */ | '(' module_args optional_comma ')'; module_args: module_arg | module_args ',' module_arg; @@ -297,7 +296,10 @@ module_arg: ast_stack.back()->children.push_back(node); append_attr(node, $1); delete $4; - } module_arg_opt_assignment; + } module_arg_opt_assignment | + '.' '.' '.' { + do_not_require_port_stubs = true; + }; wire_type: { -- cgit v1.2.3 From f53984795d38946ee71684d88883cafd9f58f603 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Wed, 13 Aug 2014 13:03:38 +0200 Subject: Added support for non-standard """ macro bodies --- frontends/verilog/preproc.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 8efd4d7c3..7935fbc34 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -131,6 +131,12 @@ static std::string next_token(bool pass_newline = false) token += ch; } } + if (token == "\"\"" && (ch = next_char()) != 0) { + if (ch == '"') + token += ch; + else + return_char(ch); + } } else if (ch == '/') { @@ -311,12 +317,17 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m std::map args; skip_spaces(); name = next_token(true); + bool here_doc_mode = false; int newline_count = 0; int state = 0; if (skip_spaces() != "") state = 3; while (!tok.empty()) { tok = next_token(); + if (tok == "\"\"\"") { + here_doc_mode = !here_doc_mode; + continue; + } if (state == 0 && tok == "(") { state = 1; skip_spaces(); @@ -332,7 +343,7 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m } else { if (state != 2) state = 3; - if (tok == "\n") { + if (tok == "\n" && !here_doc_mode) { return_char('\n'); break; } -- cgit v1.2.3 From 6d56172c0d16f80742c1c4588929d1805e3dd650 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 14 Aug 2014 22:26:30 +0200 Subject: Fixed line numbers when using here-doc macros --- frontends/verilog/preproc.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index 7935fbc34..ae139741a 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -343,10 +343,15 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m } else { if (state != 2) state = 3; - if (tok == "\n" && !here_doc_mode) { - return_char('\n'); - break; - } + if (tok == "\n") { + if (here_doc_mode) { + value += " "; + newline_count++; + } else { + return_char('\n'); + break; + } + } else if (tok == "\\") { char ch = next_char(); if (ch == '\n') { -- cgit v1.2.3 From 640d9fc551c546b511f8d64c0ccfc438937164a1 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Mon, 18 Aug 2014 14:29:30 +0200 Subject: Added "via_celltype" attribute on task/func --- frontends/verilog/parser.y | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index f619d3c2b..bf9b21bb6 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -407,33 +407,35 @@ module_body_stmt: always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property; task_func_decl: - TOK_TASK TOK_ID ';' { + attr TOK_TASK TOK_ID ';' { current_function_or_task = new AstNode(AST_TASK); - current_function_or_task->str = *$2; + current_function_or_task->str = *$3; + append_attr(current_function_or_task, $1); ast_stack.back()->children.push_back(current_function_or_task); ast_stack.push_back(current_function_or_task); current_function_or_task_port_id = 1; - delete $2; + delete $3; } task_func_body TOK_ENDTASK { current_function_or_task = NULL; ast_stack.pop_back(); } | - TOK_FUNCTION opt_signed range_or_signed_int TOK_ID ';' { + attr TOK_FUNCTION opt_signed range_or_signed_int TOK_ID ';' { current_function_or_task = new AstNode(AST_FUNCTION); - current_function_or_task->str = *$4; + current_function_or_task->str = *$5; + append_attr(current_function_or_task, $1); ast_stack.back()->children.push_back(current_function_or_task); ast_stack.push_back(current_function_or_task); AstNode *outreg = new AstNode(AST_WIRE); - outreg->str = *$4; - outreg->is_signed = $2; - if ($3 != NULL) { - outreg->children.push_back($3); - outreg->is_signed = $2 || $3->is_signed; - $3->is_signed = false; + outreg->str = *$5; + outreg->is_signed = $3; + if ($4 != NULL) { + outreg->children.push_back($4); + outreg->is_signed = $3 || $4->is_signed; + $4->is_signed = false; } current_function_or_task->children.push_back(outreg); current_function_or_task_port_id = 1; - delete $4; + delete $5; } task_func_body TOK_ENDFUNCTION { current_function_or_task = NULL; ast_stack.pop_back(); -- cgit v1.2.3 From 38addd4c67905e3d1514ba839f07d94058e42560 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 12:42:28 +0200 Subject: Added support for global tasks and functions --- frontends/verilog/parser.y | 30 +++++++++++++++++++----------- frontends/verilog/verilog_frontend.cc | 8 ++++---- 2 files changed, 23 insertions(+), 15 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index bf9b21bb6..acd904e55 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -137,14 +137,21 @@ static void free_attr(std::map *al) %% -input: - module input | - defattr input | - /* empty */ { - for (auto &it : default_attr_list) - delete it.second; - default_attr_list.clear(); - }; +input: { + ast_stack.push_back(current_ast); +} design { + ast_stack.pop_back(); + log_assert(SIZE(ast_stack) == 0); + for (auto &it : default_attr_list) + delete it.second; + default_attr_list.clear(); +}; + +design: + module design | + defattr design | + task_func_decl design | + /* empty */; attr: { @@ -214,9 +221,9 @@ module: attr TOK_MODULE TOK_ID { do_not_require_port_stubs = false; AstNode *mod = new AstNode(AST_MODULE); - current_ast->children.push_back(mod); - current_ast_mod = mod; + ast_stack.back()->children.push_back(mod); ast_stack.push_back(mod); + current_ast_mod = mod; port_stubs.clear(); port_counter = 0; mod->str = *$3; @@ -227,7 +234,8 @@ module: frontend_verilog_yyerror("Missing details for module port `%s'.", port_stubs.begin()->first.c_str()); ast_stack.pop_back(); - log_assert(ast_stack.size() == 0); + log_assert(ast_stack.size() == 1); + current_ast_mod = NULL; }; module_para_opt: diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 4466e1cb6..195789086 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -285,10 +285,10 @@ struct VerilogFrontend : public Frontend { frontend_verilog_yylex_destroy(); for (auto &child : current_ast->children) { - log_assert(child->type == AST::AST_MODULE); - for (auto &attr : attributes) - if (child->attributes.count(attr) == 0) - child->attributes[attr] = AST::AstNode::mkconst_int(1, false); + if (child->type == AST::AST_MODULE) + for (auto &attr : attributes) + if (child->attributes.count(attr) == 0) + child->attributes[attr] = AST::AstNode::mkconst_int(1, false); } 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); -- cgit v1.2.3 From 7bfc4ae12030648cd73686d3779c6d412a3c33c0 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 12:43:51 +0200 Subject: Added Verilog/AST support for DPI functions (dpi_call() still unimplemented) --- frontends/verilog/lexer.l | 22 ++++++++++++++++++++++ frontends/verilog/parser.y | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index fdb9bb02c..cf51aac82 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -74,6 +74,7 @@ YOSYS_NAMESPACE_END %x STRING %x SYNOPSYS_TRANSLATE_OFF %x SYNOPSYS_FLAGS +%x IMPORT_DPI %% @@ -274,6 +275,27 @@ supply1 { return TOK_SUPPLY1; } . /* ignore everything else */ "*/" { BEGIN(0); } +import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ { + BEGIN(IMPORT_DPI); + return TOK_DPI_FUNCTION; +} + +[(),] { + return *yytext; +} + +[a-zA-Z_$][a-zA-Z0-9_$]* { + frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext); + return TOK_ID; +} + +[ \t\r\n] /* ignore whitespaces */ + +";" { + BEGIN(0); + return *yytext; +} + "\\"[^ \t\r\n]+ { frontend_verilog_yylval.string = new std::string(yytext); return TOK_ID; diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index acd904e55..1d62bc3be 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -104,7 +104,7 @@ static void free_attr(std::map *al) %token TOK_INPUT TOK_OUTPUT TOK_INOUT TOK_WIRE TOK_REG %token TOK_INTEGER TOK_SIGNED TOK_ASSIGN TOK_ALWAYS TOK_INITIAL %token TOK_BEGIN TOK_END TOK_IF TOK_ELSE TOK_FOR TOK_WHILE TOK_REPEAT -%token TOK_POSEDGE TOK_NEGEDGE TOK_OR +%token TOK_DPI_FUNCTION TOK_POSEDGE TOK_NEGEDGE TOK_OR %token TOK_CASE TOK_CASEX TOK_CASEZ TOK_ENDCASE TOK_DEFAULT %token TOK_FUNCTION TOK_ENDFUNCTION TOK_TASK TOK_ENDTASK %token TOK_GENERATE TOK_ENDGENERATE TOK_GENVAR TOK_REAL @@ -415,6 +415,16 @@ module_body_stmt: always_stmt | TOK_GENERATE module_gen_body TOK_ENDGENERATE | defattr | assert_property; task_func_decl: + attr TOK_DPI_FUNCTION TOK_ID TOK_ID { + current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$3)); + current_function_or_task->str = *$4; + append_attr(current_function_or_task, $1); + ast_stack.back()->children.push_back(current_function_or_task); + delete $3; + delete $4; + } opt_dpi_function_args ';' { + current_function_or_task = NULL; + } | attr TOK_TASK TOK_ID ';' { current_function_or_task = new AstNode(AST_TASK); current_function_or_task->str = *$3; @@ -449,6 +459,27 @@ task_func_decl: ast_stack.pop_back(); }; +dpi_function_arg: + TOK_ID TOK_ID { + current_function_or_task->children.push_back(AstNode::mkconst_str(*$1)); + delete $1; + delete $2; + } | + TOK_ID { + current_function_or_task->children.push_back(AstNode::mkconst_str(*$1)); + delete $1; + }; + +opt_dpi_function_args: + '(' dpi_function_args ')' | + /* empty */; + +dpi_function_args: + dpi_function_args ',' dpi_function_arg | + dpi_function_args ',' | + dpi_function_arg | + /* empty */; + opt_signed: TOK_SIGNED { $$ = true; -- cgit v1.2.3 From 6c5cafcd8bf4d6b12b4d510480a0ccc1adee7212 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Thu, 21 Aug 2014 17:22:04 +0200 Subject: Added support for DPI function with different names in C and Verilog --- frontends/verilog/lexer.l | 8 ++++---- frontends/verilog/parser.y | 13 ++++++++++++- 2 files changed, 16 insertions(+), 5 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index cf51aac82..f79f81a9c 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -280,10 +280,6 @@ import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ { return TOK_DPI_FUNCTION; } -[(),] { - return *yytext; -} - [a-zA-Z_$][a-zA-Z0-9_$]* { frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext); return TOK_ID; @@ -296,6 +292,10 @@ import[ \t\r\n]+\"(DPI|DPI-C)\"[ \t\r\n]+function[ \t\r\n]+ { return *yytext; } +. { + return *yytext; +} + "\\"[^ \t\r\n]+ { frontend_verilog_yylval.string = new std::string(yytext); return TOK_ID; diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 1d62bc3be..22312c6d1 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -416,7 +416,7 @@ module_body_stmt: task_func_decl: attr TOK_DPI_FUNCTION TOK_ID TOK_ID { - current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$3)); + current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$3), AstNode::mkconst_str(*$4)); current_function_or_task->str = *$4; append_attr(current_function_or_task, $1); ast_stack.back()->children.push_back(current_function_or_task); @@ -425,6 +425,17 @@ task_func_decl: } opt_dpi_function_args ';' { current_function_or_task = NULL; } | + attr TOK_DPI_FUNCTION TOK_ID '=' TOK_ID TOK_ID { + current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$5), AstNode::mkconst_str(*$3)); + current_function_or_task->str = *$6; + append_attr(current_function_or_task, $1); + ast_stack.back()->children.push_back(current_function_or_task); + delete $3; + delete $5; + delete $6; + } opt_dpi_function_args ';' { + current_function_or_task = NULL; + } | attr TOK_TASK TOK_ID ';' { current_function_or_task = new AstNode(AST_TASK); current_function_or_task->str = *$3; -- cgit v1.2.3 From e218f0eacf7cbcfa0736cb2d66bba0010e8e6799 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Fri, 22 Aug 2014 14:30:29 +0200 Subject: Added support for non-standard : DPI syntax --- frontends/verilog/parser.y | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'frontends/verilog') diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 22312c6d1..3512538ca 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -436,6 +436,18 @@ task_func_decl: } opt_dpi_function_args ';' { current_function_or_task = NULL; } | + attr TOK_DPI_FUNCTION TOK_ID ':' TOK_ID '=' TOK_ID TOK_ID { + current_function_or_task = new AstNode(AST_DPI_FUNCTION, AstNode::mkconst_str(*$7), AstNode::mkconst_str(*$3 + ":" + RTLIL::unescape_id(*$5))); + current_function_or_task->str = *$8; + append_attr(current_function_or_task, $1); + ast_stack.back()->children.push_back(current_function_or_task); + delete $3; + delete $5; + delete $7; + delete $8; + } opt_dpi_function_args ';' { + current_function_or_task = NULL; + } | attr TOK_TASK TOK_ID ';' { current_function_or_task = new AstNode(AST_TASK); current_function_or_task->str = *$3; -- cgit v1.2.3 From 19cff41eb4261b20374058f16807a229af46f304 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 23 Aug 2014 15:03:55 +0200 Subject: Changed frontend-api from FILE to std::istream --- frontends/verilog/lexer.l | 3 +++ frontends/verilog/parser.y | 1 + frontends/verilog/preproc.cc | 31 ++++++++++++++++--------------- frontends/verilog/verilog_frontend.cc | 12 ++++++------ frontends/verilog/verilog_frontend.h | 5 ++++- 5 files changed, 30 insertions(+), 22 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/lexer.l b/frontends/verilog/lexer.l index f79f81a9c..c9302aba8 100644 --- a/frontends/verilog/lexer.l +++ b/frontends/verilog/lexer.l @@ -63,6 +63,9 @@ YOSYS_NAMESPACE_END frontend_verilog_yylval.string = new std::string(std::string("\\") + yytext); \ return TOK_ID; +#define YY_INPUT(buf,result,max_size) \ + result = lexin->readsome(buf, max_size); + %} %option yylineno diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y index 3512538ca..a9f69a49c 100644 --- a/frontends/verilog/parser.y +++ b/frontends/verilog/parser.y @@ -58,6 +58,7 @@ namespace VERILOG_FRONTEND { bool do_not_require_port_stubs; bool default_nettype_wire; bool sv_mode; + std::istream *lexin; } YOSYS_NAMESPACE_END diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index ae139741a..f83433219 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -193,7 +193,7 @@ static std::string next_token(bool pass_newline = false) return token; } -static void input_file(FILE *f, std::string filename) +static void input_file(std::istream &f, std::string filename) { char buffer[513]; int rc; @@ -202,14 +202,14 @@ static void input_file(FILE *f, std::string filename) auto it = input_buffer.begin(); input_buffer.insert(it, "`file_push " + filename + "\n"); - while ((rc = fread(buffer, 1, sizeof(buffer)-1, f)) > 0) { + while ((rc = f.readsome(buffer, sizeof(buffer)-1)) > 0) { buffer[rc] = 0; input_buffer.insert(it, buffer); } input_buffer.insert(it, "\n`file_pop\n"); } -std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::map pre_defines_map, const std::list include_dirs) +std::string frontend_verilog_preproc(std::istream &f, std::string filename, const std::map pre_defines_map, const std::list include_dirs) { std::set defines_with_args; std::map defines_map(pre_defines_map); @@ -288,27 +288,28 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m else fn = fn.substr(0, pos) + fn.substr(pos+1); } - FILE *fp = fopen(fn.c_str(), "r"); - if (fp == NULL && fn.size() > 0 && fn[0] != '/' && filename.find('/') != std::string::npos) { + std::ifstream ff; + ff.clear(); + ff.open(fn.c_str()); + if (ff.fail() && fn.size() > 0 && fn[0] != '/' && filename.find('/') != std::string::npos) { // if the include file was not found, it is not given with an absolute path, and the // currently read file is given with a path, then try again relative to its directory - std::string fn2 = filename.substr(0, filename.rfind('/')+1) + fn; - fp = fopen(fn2.c_str(), "r"); + ff.clear(); + ff.open(filename.substr(0, filename.rfind('/')+1) + fn); } - if (fp == NULL && fn.size() > 0 && fn[0] != '/') { + if (ff.fail() && fn.size() > 0 && fn[0] != '/') { // if the include file was not found and it is not given with an absolute path, then // search it in the include path for (auto incdir : include_dirs) { - std::string fn2 = incdir + '/' + fn; - fp = fopen(fn2.c_str(), "r"); - if (fp != NULL) break; + ff.clear(); + ff.open(incdir + '/' + fn); + if (!ff.fail()) break; } } - if (fp != NULL) { - input_file(fp, fn); - fclose(fp); - } else + if (ff.fail()) output_code.push_back("`file_notfound " + fn); + else + input_file(ff, fn); continue; } diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index 195789086..c63fbb08a 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -136,7 +136,7 @@ struct VerilogFrontend : public Frontend { log("the syntax of the code, rather than to rely on read_verilog for that.\n"); log("\n"); } - virtual void execute(FILE *&f, std::string filename, std::vector args, RTLIL::Design *design) + virtual void execute(std::istream *&f, std::string filename, std::vector args, RTLIL::Design *design) { bool flag_dump_ast1 = false; bool flag_dump_ast2 = false; @@ -269,18 +269,18 @@ struct VerilogFrontend : public Frontend { current_ast = new AST::AstNode(AST::AST_DESIGN); default_nettype_wire = true; - FILE *fp = f; + lexin = f; std::string code_after_preproc; if (!flag_nopp) { - code_after_preproc = frontend_verilog_preproc(f, filename, defines_map, include_dirs); + code_after_preproc = frontend_verilog_preproc(*f, filename, defines_map, include_dirs); if (flag_ppdump) log("-- Verilog code after preprocessor --\n%s-- END OF DUMP --\n", code_after_preproc.c_str()); - fp = fmemopen((void*)code_after_preproc.c_str(), code_after_preproc.size(), "r"); + lexin = new std::istringstream(code_after_preproc); } frontend_verilog_yyset_lineno(1); - frontend_verilog_yyrestart(fp); + frontend_verilog_yyrestart(NULL); frontend_verilog_yyparse(); frontend_verilog_yylex_destroy(); @@ -294,7 +294,7 @@ struct VerilogFrontend : public Frontend { 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); if (!flag_nopp) - fclose(fp); + delete lexin; delete current_ast; current_ast = NULL; diff --git a/frontends/verilog/verilog_frontend.h b/frontends/verilog/verilog_frontend.h index dac5b3d02..af6495f8f 100644 --- a/frontends/verilog/verilog_frontend.h +++ b/frontends/verilog/verilog_frontend.h @@ -50,10 +50,13 @@ namespace VERILOG_FRONTEND // running in SystemVerilog mode extern bool sv_mode; + + // lexer input stream + extern std::istream *lexin; } // the pre-processor -std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::map pre_defines_map, const std::list include_dirs); +std::string frontend_verilog_preproc(std::istream &f, std::string filename, const std::map pre_defines_map, const std::list include_dirs); YOSYS_NAMESPACE_END -- cgit v1.2.3 From 58367cd87a5d2bac1de81512f60939c080b3b9ef Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sat, 23 Aug 2014 15:14:58 +0200 Subject: Removed compatbility.{h,cc}: Not using open_memstream/fmemopen anymore --- frontends/verilog/verilog_frontend.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'frontends/verilog') diff --git a/frontends/verilog/verilog_frontend.cc b/frontends/verilog/verilog_frontend.cc index c63fbb08a..c6d4a0b79 100644 --- a/frontends/verilog/verilog_frontend.cc +++ b/frontends/verilog/verilog_frontend.cc @@ -27,11 +27,8 @@ */ #include "verilog_frontend.h" -#include "kernel/compatibility.h" -#include "kernel/register.h" -#include "kernel/log.h" +#include "kernel/yosys.h" #include "libs/sha1/sha1.h" -#include #include YOSYS_NAMESPACE_BEGIN -- cgit v1.2.3