diff options
Diffstat (limited to 'frontends')
-rw-r--r-- | frontends/ast/ast.cc | 5 | ||||
-rw-r--r-- | frontends/ast/simplify.cc | 53 | ||||
-rw-r--r-- | frontends/rpc/rpc_frontend.cc | 2 | ||||
-rw-r--r-- | frontends/verilog/verilog_parser.y | 6 |
4 files changed, 56 insertions, 10 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc index 4cf329f75..9ddd538b5 100644 --- a/frontends/ast/ast.cc +++ b/frontends/ast/ast.cc @@ -1158,6 +1158,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump bool nolatches, bool nomeminit, bool nomem2reg, bool mem2reg, bool noblackbox, bool lib, bool nowb, bool noopt, bool icells, bool pwires, bool nooverwrite, bool overwrite, bool defer, bool autowire) { current_ast = ast; + current_ast_mod = nullptr; flag_dump_ast1 = dump_ast1; flag_dump_ast2 = dump_ast2; flag_no_dump_ptr = no_dump_ptr; @@ -1224,6 +1225,7 @@ void AST::process(RTLIL::Design *design, AstNode *ast, bool dump_ast1, bool dump } design->add(process_module(*it, defer)); + current_ast_mod = nullptr; } else if ((*it)->type == AST_PACKAGE) { // process enum/other declarations @@ -1568,6 +1570,9 @@ std::string AstModule::derive_common(RTLIL::Design *design, const dict<RTLIL::Id rewritten.reserve(GetSize(parameters)); AstNode *new_ast = ast->clone(); + if (!new_ast->attributes.count(ID::hdlname)) + new_ast->attributes[ID::hdlname] = AstNode::mkconst_str(stripped_name); + para_counter = 0; for (auto child : new_ast->children) { if (child->type != AST_PARAMETER) diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc index 2ebe2edbc..837c14ad7 100644 --- a/frontends/ast/simplify.cc +++ b/frontends/ast/simplify.cc @@ -64,6 +64,21 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg continue; } + bool got_len = false; + bool got_zlen = false; + int len_value = 0; + + while ('0' <= cformat && cformat <= '9') + { + if (!got_len && cformat == '0') + got_zlen = true; + + got_len = true; + len_value = 10*len_value + (cformat - '0'); + + cformat = sformat[++i]; + } + // Simplify the argument AstNode *node_arg = nullptr; @@ -74,6 +89,9 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg case 'S': case 'd': case 'D': + if (got_len) + goto unsupported_format; + /* fall through */ case 'x': case 'X': if (next_arg >= GetSize(children)) @@ -88,9 +106,12 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg case 'm': case 'M': + 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()); break; } @@ -104,19 +125,28 @@ std::string AstNode::process_format_str(const std::string &sformat, int next_arg case 'd': case 'D': - { - char tmp[128]; - snprintf(tmp, sizeof(tmp), "%d", node_arg->bitsAsConst().as_int()); - sout += tmp; - } + sout += stringf("%d", node_arg->bitsAsConst().as_int()); break; case 'x': case 'X': { - char tmp[128]; - snprintf(tmp, sizeof(tmp), "%x", node_arg->bitsAsConst().as_int()); - sout += tmp; + Const val = node_arg->bitsAsConst(); + + while (GetSize(val) % 4 != 0) + val.bits.push_back(State::S0); + + int len = GetSize(val) / 4; + for (int i = len; i < len_value; i++) + sout += got_zlen ? '0' : ' '; + + for (int i = len-1; i >= 0; i--) { + Const digit = val.extract(4*i, 4); + if (digit.is_fully_def()) + sout += stringf(cformat == 'x' ? "%x" : "%X", digit.as_int()); + else + sout += cformat == 'x' ? "x" : "X"; + } } break; @@ -1169,7 +1199,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, // annotate identifiers using scope resolution and create auto-wires as needed if (type == AST_IDENTIFIER) { if (current_scope.count(str) == 0) { - for (auto node : current_ast_mod->children) { + AstNode *current_scope_ast = (current_ast_mod == nullptr) ? current_ast : current_ast_mod; + for (auto node : current_scope_ast->children) { //log("looking at mod scope child %s\n", type2str(node->type).c_str()); switch (node->type) { case AST_PARAMETER: @@ -1203,7 +1234,9 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage, } } if (current_scope.count(str) == 0) { - if (flag_autowire || str == "\\$global_clock") { + if (current_ast_mod == nullptr) { + log_file_error(filename, location.first_line, "Identifier `%s' is implicitly declared outside of a module.\n", str.c_str()); + } else if (flag_autowire || str == "\\$global_clock") { AstNode *auto_wire = new AstNode(AST_AUTOWIRE); auto_wire->str = str; current_ast_mod->children.push_back(auto_wire); diff --git a/frontends/rpc/rpc_frontend.cc b/frontends/rpc/rpc_frontend.cc index a23f7548e..46ee6a733 100644 --- a/frontends/rpc/rpc_frontend.cc +++ b/frontends/rpc/rpc_frontend.cc @@ -217,6 +217,8 @@ struct RpcModule : RTLIL::Module { module.second->name = mangled_name; module.second->design = design; module.second->attributes.erase(ID::top); + if (!module.second->has_attribute(ID::hdlname)) + module.second->set_string_attribute(ID::hdlname, module.first.str()); design->modules_[mangled_name] = module.second; derived_design->modules_.erase(module.first); } diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y index 76373c2e4..4a5aba79e 100644 --- a/frontends/verilog/verilog_parser.y +++ b/frontends/verilog/verilog_parser.y @@ -1924,11 +1924,13 @@ always_events: always_event: TOK_POSEDGE expr { AstNode *node = new AstNode(AST_POSEDGE); + SET_AST_NODE_LOC(node, @1, @1); ast_stack.back()->children.push_back(node); node->children.push_back($2); } | TOK_NEGEDGE expr { AstNode *node = new AstNode(AST_NEGEDGE); + SET_AST_NODE_LOC(node, @1, @1); ast_stack.back()->children.push_back(node); node->children.push_back($2); } | @@ -2244,6 +2246,7 @@ behavioral_stmt: exitTypeScope(); if ($4 != NULL && $8 != NULL && *$4 != *$8) frontend_verilog_yyerror("Begin label (%s) and end label (%s) don't match.", $4->c_str()+1, $8->c_str()+1); + SET_AST_NODE_LOC(ast_stack.back(), @2, @8); delete $4; delete $8; ast_stack.pop_back(); @@ -2618,6 +2621,7 @@ basic_expr: bits->str = *$1; SET_AST_NODE_LOC(bits, @1, @1); AstNode *val = const2ast(*$2, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode); + SET_AST_NODE_LOC(val, @2, @2); if (val == NULL) log_error("Value conversion failed: `%s'\n", $2->c_str()); $$ = new AstNode(AST_TO_BITS, bits, val); @@ -2626,6 +2630,7 @@ basic_expr: } | integral_number { $$ = const2ast(*$1, case_type_stack.size() == 0 ? 0 : case_type_stack.back(), !lib_mode); + SET_AST_NODE_LOC($$, @1, @1); if ($$ == NULL) log_error("Value conversion failed: `%s'\n", $1->c_str()); delete $1; @@ -2644,6 +2649,7 @@ basic_expr: } | TOK_STRING { $$ = AstNode::mkconst_str(*$1); + SET_AST_NODE_LOC($$, @1, @1); delete $1; } | hierarchical_id attr { |