diff options
Diffstat (limited to 'frontends/verilog')
-rw-r--r-- | frontends/verilog/preproc.cc | 24 | ||||
-rw-r--r-- | frontends/verilog/verilog_lexer.l | 1 | ||||
-rw-r--r-- | frontends/verilog/verilog_parser.y | 31 |
3 files changed, 39 insertions, 17 deletions
diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc index ee742d485..00bdcee43 100644 --- a/frontends/verilog/preproc.cc +++ b/frontends/verilog/preproc.cc @@ -366,14 +366,31 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons ff.clear(); std::string fixed_fn = fn; ff.open(fixed_fn.c_str()); - if (ff.fail() && fn.size() > 0 && fn[0] != '/' && filename.find('/') != std::string::npos) { + + bool filename_path_sep_found; + bool fn_relative; +#ifdef _WIN32 + // Both forward and backslash are acceptable separators on Windows. + filename_path_sep_found = (filename.find_first_of("/\\") != std::string::npos); + // Easier just to invert the check for an absolute path (e.g. C:\ or C:/) + fn_relative = !(fn[1] == ':' && (fn[2] == '/' || fn[2] == '\\')); +#else + filename_path_sep_found = (filename.find('/') != std::string::npos); + fn_relative = (fn[0] != '/'); +#endif + + if (ff.fail() && fn.size() > 0 && fn_relative && filename_path_sep_found) { // 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 ff.clear(); +#ifdef _WIN32 + fixed_fn = filename.substr(0, filename.find_last_of("/\\")+1) + fn; +#else fixed_fn = filename.substr(0, filename.rfind('/')+1) + fn; +#endif ff.open(fixed_fn); } - if (ff.fail() && fn.size() > 0 && fn[0] != '/') { + if (ff.fail() && fn.size() > 0 && fn_relative) { // 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) { @@ -505,7 +522,7 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons if (try_expand_macro(defines_with_args, defines_map, tok)) continue; - + output_code.push_back(tok); } @@ -521,4 +538,3 @@ std::string frontend_verilog_preproc(std::istream &f, std::string filename, cons } YOSYS_NAMESPACE_END - diff --git a/frontends/verilog/verilog_lexer.l b/frontends/verilog/verilog_lexer.l index 07d85bed8..d6d00c371 100644 --- a/frontends/verilog/verilog_lexer.l +++ b/frontends/verilog/verilog_lexer.l @@ -170,6 +170,7 @@ YOSYS_NAMESPACE_END "endgenerate" { return TOK_ENDGENERATE; } "while" { return TOK_WHILE; } "repeat" { return TOK_REPEAT; } +"automatic" { return TOK_AUTOMATIC; } "unique" { SV_KEYWORD(TOK_UNIQUE); } "unique0" { SV_KEYWORD(TOK_UNIQUE); } diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index ec92f6628..9aa01c9f0 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -108,7 +108,7 @@ static void free_attr(std::map<std::string, AstNode*> *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_DPI_FUNCTION TOK_POSEDGE TOK_NEGEDGE TOK_OR +%token TOK_DPI_FUNCTION TOK_POSEDGE TOK_NEGEDGE TOK_OR TOK_AUTOMATIC %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 @@ -359,6 +359,7 @@ package_body_stmt: non_opt_delay: '#' TOK_ID { delete $2; } | '#' TOK_CONSTVAL { delete $2; } | + '#' TOK_REALVAL { delete $2; } | '#' '(' expr ')' { delete $3; } | '#' '(' expr ':' expr ':' expr ')' { delete $3; delete $5; delete $7; }; @@ -523,35 +524,35 @@ task_func_decl: } opt_dpi_function_args ';' { current_function_or_task = NULL; } | - attr TOK_TASK TOK_ID { + attr TOK_TASK opt_automatic TOK_ID { current_function_or_task = new AstNode(AST_TASK); - current_function_or_task->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); ast_stack.push_back(current_function_or_task); current_function_or_task_port_id = 1; - delete $3; + delete $4; } task_func_args_opt ';' task_func_body TOK_ENDTASK { current_function_or_task = NULL; ast_stack.pop_back(); } | - attr TOK_FUNCTION opt_signed range_or_signed_int TOK_ID { + attr TOK_FUNCTION opt_automatic opt_signed range_or_signed_int TOK_ID { current_function_or_task = new AstNode(AST_FUNCTION); - current_function_or_task->str = *$5; + current_function_or_task->str = *$6; 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 = *$5; - outreg->is_signed = $3; - if ($4 != NULL) { - outreg->children.push_back($4); - outreg->is_signed = $3 || $4->is_signed; - $4->is_signed = false; + outreg->str = *$6; + outreg->is_signed = $4; + if ($5 != NULL) { + outreg->children.push_back($5); + outreg->is_signed = $4 || $5->is_signed; + $5->is_signed = false; } current_function_or_task->children.push_back(outreg); current_function_or_task_port_id = 1; - delete $5; + delete $6; } task_func_args_opt ';' task_func_body TOK_ENDFUNCTION { current_function_or_task = NULL; ast_stack.pop_back(); @@ -578,6 +579,10 @@ dpi_function_args: dpi_function_arg | /* empty */; +opt_automatic: + TOK_AUTOMATIC | + /* empty */; + opt_signed: TOK_SIGNED { $$ = true; |